mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 20:52:56 +01:00
Working on history sidebar
This commit is contained in:
parent
a2f7d32e57
commit
db0c305b4f
@ -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)){
|
||||
|
@ -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 [];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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');
|
||||
|
117
app/Libraries/HistoryUtils.php
Normal file
117
app/Libraries/HistoryUtils.php
Normal file
@ -0,0 +1,117 @@
|
||||
<?php namespace App\Libraries;
|
||||
|
||||
use Request;
|
||||
use stdClass;
|
||||
use Session;
|
||||
use App\Models\EntityModel;
|
||||
|
||||
class HistoryUtils
|
||||
{
|
||||
public static function trackViewed(EntityModel $entity)
|
||||
{
|
||||
if ($entity->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; $i<count($history); $i++) {
|
||||
$item = $history[$i];
|
||||
|
||||
if ($object->url == $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 = '<i class="fa fa-users" style="width:30px"></i>';
|
||||
if ($item->client_id) {
|
||||
$link = url('/clients/' . $item->client_id);
|
||||
$name = $item->client_name ;
|
||||
|
||||
$buttonLink = url('/invoices/create/' . $item->client_id);
|
||||
$button = '<a type="button" class="btn btn-primary btn-sm pull-right" style="margin-top:5px; margin-right:10px; text-indent:0px"
|
||||
href="' . $buttonLink . '">
|
||||
<i class="fa fa-plus-circle" style="width:20px" title="' . trans('texts.create_new') . '"></i>
|
||||
</a>';
|
||||
} else {
|
||||
$link = '#';
|
||||
$name = trans('texts.unassigned');
|
||||
$button = '';
|
||||
}
|
||||
|
||||
$str .= sprintf('<li>%s<a href="%s"><div>%s %s</div></a></li>', $button, $link, $icon, $name);
|
||||
$lastClientId = $item->client_id;
|
||||
}
|
||||
|
||||
if ($item->entityType == ENTITY_CLIENT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$icon = '<i class="fa fa-' . EntityModel::getIcon($item->entityType . 's') . '"></i>';
|
||||
$str .= sprintf('<li style="text-align:right; padding-right:20px;"><a href="%s">%s %s</a></li>', $item->url, $item->name, $icon);
|
||||
}
|
||||
|
||||
//dd($str);
|
||||
return $str;
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -151,7 +151,13 @@ class Task extends EntityModel
|
||||
{
|
||||
return "/tasks/{$this->public_id}/edit";
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return '#' . $this->public_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Task::created(function ($task) {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ class EventServiceProvider extends ServiceProvider {
|
||||
* @var array
|
||||
*/
|
||||
protected $listen = [
|
||||
|
||||
// Clients
|
||||
'App\Events\ClientWasCreated' => [
|
||||
'App\Listeners\ActivityListener@createdClient',
|
||||
|
@ -2089,6 +2089,8 @@ $LANG = array(
|
||||
|
||||
'toggle_navigation' => 'Toggle Navigation',
|
||||
'toggle_history' => 'Toggle History',
|
||||
'unassigned' => 'Unassigned',
|
||||
'task' => 'Task',
|
||||
|
||||
);
|
||||
|
||||
|
@ -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 @@
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div id="left-sidebar-wrapper">
|
||||
<ul class="sidebar-nav" style="padding-top:20px">
|
||||
<ul class="sidebar-nav">
|
||||
@foreach([
|
||||
'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',
|
||||
] as $option => $icon)
|
||||
<li style="border-bottom:solid 1px" class="{{ Request::is("{$option}*") ? 'active' : '' }}">
|
||||
'dashboard',
|
||||
'clients',
|
||||
'invoices',
|
||||
'payments',
|
||||
'recurring_invoices',
|
||||
'credits',
|
||||
'quotes',
|
||||
'tasks',
|
||||
'expenses',
|
||||
'vendors',
|
||||
'settings'
|
||||
] as $option)
|
||||
<li class="{{ Request::is("{$option}*") ? 'active' : '' }}">
|
||||
@if ($option != 'dashboard' && $option != 'settings')
|
||||
@if (Auth::user()->can('create', substr($option, 0, -1)))
|
||||
<a type="button" class="btn btn-primary btn-sm pull-right" style="margin-top:10px;margin-right:10px;text-indent:0px"
|
||||
href="{{ url("/{$option}/create") }}">
|
||||
<i class="fa fa-plus-circle" style="color:white;width:20px" title="{{ trans('texts.create_new') }}"></i>
|
||||
<i class="fa fa-plus-circle" style="width:20px" title="{{ trans('texts.create_new') }}"></i>
|
||||
</a>
|
||||
@endif
|
||||
@endif
|
||||
<a href="{{ url($option == 'recurring' ? 'recurring_invoice' : $option) }}"
|
||||
style="font-size:16px; padding-top:6px; padding-bottom:6px"
|
||||
class="{{ Request::is("{$option}*") ? 'active' : '' }}">
|
||||
<i class="fa fa-{{ $icon }}" style="width:46px; color:white; padding-right:10px"></i>
|
||||
<i class="fa fa-{{ \App\Models\EntityModel::getIcon($option) }}" style="width:46px; padding-right:10px"></i>
|
||||
{{ ($option == 'recurring_invoices') ? trans('texts.recurring') : trans("texts.{$option}") }}
|
||||
</a>
|
||||
</li>
|
||||
@ -736,7 +760,9 @@
|
||||
<!-- /#left-sidebar-wrapper -->
|
||||
|
||||
<div id="right-sidebar-wrapper">
|
||||
SIDEBAR
|
||||
<ul class="sidebar-nav">
|
||||
{!! \App\Libraries\HistoryUtils::renderHtml() !!}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Page Content -->
|
||||
|
Loading…
Reference in New Issue
Block a user