From db0c305b4fb1e4f7055723deeec523840b259427 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 31 Aug 2016 22:10:41 +0300 Subject: [PATCH] Working on history sidebar --- app/Http/Controllers/ClientController.php | 2 - app/Http/Requests/EntityRequest.php | 7 +- app/Http/routes.php | 2 +- app/Libraries/HistoryUtils.php | 117 ++++++++++++++++++++++ app/Libraries/Utils.php | 2 + app/Models/EntityModel.php | 29 ++++++ app/Models/Expense.php | 5 +- app/Models/Invoice.php | 9 ++ app/Models/Task.php | 6 ++ app/Ninja/Presenters/EntityPresenter.php | 8 ++ app/Providers/EventServiceProvider.php | 1 + resources/lang/en/texts.php | 2 + resources/views/header.blade.php | 64 ++++++++---- 13 files changed, 227 insertions(+), 27 deletions(-) create mode 100644 app/Libraries/HistoryUtils.php diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index 79e309c76d0f..b964f49206a3 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -89,9 +89,7 @@ class ClientController extends BaseController public function show(ClientRequest $request) { $client = $request->entity(); - $user = Auth::user(); - Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT); $actionLinks = []; if($user->can('create', ENTITY_TASK)){ diff --git a/app/Http/Requests/EntityRequest.php b/app/Http/Requests/EntityRequest.php index 6bed19d44198..94dae7a443dd 100644 --- a/app/Http/Requests/EntityRequest.php +++ b/app/Http/Requests/EntityRequest.php @@ -2,6 +2,7 @@ use Input; use Utils; +use App\Libraries\HistoryUtils; class EntityRequest extends Request { @@ -52,7 +53,10 @@ class EntityRequest extends Request { public function authorize() { if ($this->entity()) { - return $this->user()->can('view', $this->entity()); + if ($this->user()->can('view', $this->entity())) { + HistoryUtils::trackViewed($this->entity()); + return true; + } } else { return $this->user()->can('create', $this->entityType); } @@ -62,4 +66,5 @@ class EntityRequest extends Request { { return []; } + } diff --git a/app/Http/routes.php b/app/Http/routes.php index 143d2d7f63e1..aeee6b1da9cd 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -355,7 +355,7 @@ if (!defined('CONTACT_EMAIL')) { define('ENV_DEVELOPMENT', 'local'); define('ENV_STAGING', 'staging'); - define('RECENTLY_VIEWED', 'RECENTLY_VIEWED'); + define('RECENTLY_VIEWED', 'recent_history'); define('ENTITY_CLIENT', 'client'); define('ENTITY_CONTACT', 'contact'); diff --git a/app/Libraries/HistoryUtils.php b/app/Libraries/HistoryUtils.php new file mode 100644 index 000000000000..6bad2156b3eb --- /dev/null +++ b/app/Libraries/HistoryUtils.php @@ -0,0 +1,117 @@ +isEntityType(ENTITY_CREDIT) || $entity->isEntityType(ENTITY_VENDOR)) { + return; + } + + $object = static::convertToObject($entity); + $history = Session::get(RECENTLY_VIEWED); + $data = []; + + // Add to the list and make sure to only show each item once + for ($i = 0; $iurl == $item->url) { + continue; + } + + array_push($data, $item); + + if (isset($counts[$item->accountId])) { + $counts[$item->accountId]++; + } else { + $counts[$item->accountId] = 1; + } + } + + array_unshift($data, $object); + + if (isset($counts[$entity->account_id]) && $counts[$entity->account_id] > RECENTLY_VIEWED_LIMIT) { + array_pop($data); + } + + //$data = []; + Session::put(RECENTLY_VIEWED, $data); + } + + private static function convertToObject($entity) + { + $object = new stdClass(); + $object->accountId = $entity->account_id; + $object->url = $entity->present()->url; + $object->entityType = $entity->subEntityType(); + $object->name = $entity->present()->titledName; + $object->timestamp = time(); + + if ($entity->isEntityType(ENTITY_CLIENT)) { + $object->client_id = $entity->public_id; + $object->client_name = $entity->getDisplayName(); + } elseif (method_exists($entity, 'client') && $entity->client) { + $object->client_id = $entity->client->public_id; + $object->client_name = $entity->client->getDisplayName(); + } else { + $object->client_id = 0; + $object->client_name = 0; + } + + return $object; + } + + public static function renderHtml() + { + $lastClientId = false; + $clientMap = []; + $str = ''; + + foreach (Session::get(RECENTLY_VIEWED) as $item) + { + if ($item->entityType == ENTITY_CLIENT && isset($clientMap[$item->client_id])) { + continue; + } + + $clientMap[$item->client_id] = true; + + if ($lastClientId === false || $item->client_id != $lastClientId) + { + $icon = ''; + if ($item->client_id) { + $link = url('/clients/' . $item->client_id); + $name = $item->client_name ; + + $buttonLink = url('/invoices/create/' . $item->client_id); + $button = ' + + '; + } else { + $link = '#'; + $name = trans('texts.unassigned'); + $button = ''; + } + + $str .= sprintf('
  • %s
    %s %s
  • ', $button, $link, $icon, $name); + $lastClientId = $item->client_id; + } + + if ($item->entityType == ENTITY_CLIENT) { + continue; + } + + $icon = ''; + $str .= sprintf('
  • %s %s
  • ', $item->url, $item->name, $icon); + } + + //dd($str); + return $str; + } +} diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index e5644e224c51..a382cca1f992 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -602,6 +602,7 @@ class Utils public static function trackViewed($name, $type, $url = false) { + /* if (!$url) { $url = Request::url(); } @@ -643,6 +644,7 @@ class Utils } Session::put(RECENTLY_VIEWED, $data); + */ } public static function processVariables($str) diff --git a/app/Models/EntityModel.php b/app/Models/EntityModel.php index 04d0a003df6f..4c0e88d9ac73 100644 --- a/app/Models/EntityModel.php +++ b/app/Models/EntityModel.php @@ -92,6 +92,16 @@ class EntityModel extends Eloquent return $this->public_id . ':' . $this->getEntityType(); } + public function subEntityType() + { + return $this->getEntityType(); + } + + public function isEntityType($type) + { + return $this->getEntityType() === $type; + } + /* public function getEntityType() { @@ -229,4 +239,23 @@ class EntityModel extends Eloquent } } + public static function getIcon($entityType) + { + $icons = [ + 'dashboard' => 'tachometer', + 'clients' => 'users', + 'invoices' => 'file-pdf-o', + 'payments' => 'credit-card', + 'recurring_invoices' => 'files-o', + 'credits' => 'credit-card', + 'quotes' => 'file-text-o', + 'tasks' => 'clock-o', + 'expenses' => 'file-image-o', + 'vendors' => 'building', + 'settings' => 'cog', + ]; + + return array_get($icons, $entityType); + } + } diff --git a/app/Models/Expense.php b/app/Models/Expense.php index 5348ee530ffb..f5cb229fea24 100644 --- a/app/Models/Expense.php +++ b/app/Models/Expense.php @@ -107,10 +107,7 @@ class Expense extends EntityModel */ public function getName() { - if($this->expense_number) - return $this->expense_number; - - return $this->public_id; + return $this->transaction_id ?: '#' . $this->public_id; } /** diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 02e63d020947..e353cc17280c 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -548,6 +548,15 @@ class Invoice extends EntityModel implements BalanceAffecting return $this->isType(INVOICE_TYPE_QUOTE) ? ENTITY_QUOTE : ENTITY_INVOICE; } + public function subEntityType() + { + if ($this->is_recurring) { + return ENTITY_RECURRING_INVOICE; + } else { + return $this->getEntityType(); + } + } + /** * @return bool */ diff --git a/app/Models/Task.php b/app/Models/Task.php index 11e952420141..f1a937594f55 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -151,9 +151,15 @@ class Task extends EntityModel { return "/tasks/{$this->public_id}/edit"; } + + public function getName() + { + return '#' . $this->public_id; + } } + Task::created(function ($task) { event(new TaskWasCreated($task)); }); diff --git a/app/Ninja/Presenters/EntityPresenter.php b/app/Ninja/Presenters/EntityPresenter.php index a37bf8b6c7b3..c30bb84cb07d 100644 --- a/app/Ninja/Presenters/EntityPresenter.php +++ b/app/Ninja/Presenters/EntityPresenter.php @@ -27,4 +27,12 @@ class EntityPresenter extends Presenter return link_to($link, $name)->toHtml(); } + + public function titledName() + { + $entity = $this->entity; + $entityType = $entity->getEntityType(); + + return sprintf('%s: %s', trans('texts.' . $entityType), $entity->getDisplayName()); + } } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 7bbbf92afde1..a383a3ad5e70 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -11,6 +11,7 @@ class EventServiceProvider extends ServiceProvider { * @var array */ protected $listen = [ + // Clients 'App\Events\ClientWasCreated' => [ 'App\Listeners\ActivityListener@createdClient', diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index ace29420206c..727cd11c2dfa 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -2089,6 +2089,8 @@ $LANG = array( 'toggle_navigation' => 'Toggle Navigation', 'toggle_history' => 'Toggle History', + 'unassigned' => 'Unassigned', + 'task' => 'Task', ); diff --git a/resources/views/header.blade.php b/resources/views/header.blade.php index d028d2f18a26..5247820988f5 100644 --- a/resources/views/header.blade.php +++ b/resources/views/header.blade.php @@ -64,7 +64,6 @@ #right-sidebar-wrapper { z-index: 1000; position: fixed; - top: 0px; right: 250px; width: 0px; height: 100%; @@ -104,20 +103,34 @@ /* Sidebar Styles */ .sidebar-nav { + padding-top: 16px; position: absolute; top: 0; width: 250px; margin: 0; - padding: 0; list-style: none; height: 100%; } + .sidebar-nav i.fa { + color: white; + } + .sidebar-nav li { + border-bottom:solid 1px; + } + + #left-sidebar-wrapper .sidebar-nav li { text-indent: 20px; line-height: 40px; } + #right-sidebar-wrapper .sidebar-nav li { + text-indent: 10px; + font-size: 16px; + line-height: 44px; + } + .sidebar-nav li > a { display: block; text-decoration: none; @@ -163,6 +176,17 @@ background: none; } + .sidebar-nav li div { + max-width:226px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .sidebar-nav li:hover div { + max-width:186px; + } + @media(min-width:768px) { #wrapper { padding-left: 250px; @@ -700,33 +724,33 @@