diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php index 1dcaf75d..f24f3a36 100644 --- a/app/Http/Middleware/EncryptCookies.php +++ b/app/Http/Middleware/EncryptCookies.php @@ -12,6 +12,7 @@ class EncryptCookies extends Middleware * @var array */ protected $except = [ - 'in_app' + 'in_app', + 'customers_view', ]; } diff --git a/app/Misc/Helper.php b/app/Misc/Helper.php index d1bc158a..013aa1aa 100644 --- a/app/Misc/Helper.php +++ b/app/Misc/Helper.php @@ -1794,6 +1794,18 @@ class Helper return (int)$request->cookie('in_app'); } + /** + * Customers list view mode: cards (default) or table. + * The cookie is set from JS (see setCustomersView() in main.js). + */ + public static function getCustomersView($request = null) + { + if (!$request) { + $request = app('request'); + } + return $request->cookie('customers_view') == 'table' ? 'table' : 'cards'; + } + /** * Get identifier for queue:work */ diff --git a/public/css/style.css b/public/css/style.css index 7d5cd3a8..336c18c9 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -3677,6 +3677,75 @@ ul.sidebar-block-list { .customers-pager a:hover { color: #333; } +/* Customers list: table view */ +.customers-view-switch { + color: #93a1af; + cursor: pointer; + margin-left: 6px; + font-size: 13px; + top: 2px; +} +.customers-view-switch:hover { + color: #333; +} +.customers-table { + background-color: #fff; + /* Fixed layout: long values can not stretch the table, they are truncated. */ + table-layout: fixed; + width: 100%; +} +.customers-table-col-name { + width: 34%; +} +.customers-table-col-email { + width: 30%; +} +.customers-table-col-phone { + width: 16%; +} +.customers-table-col-company { + width: 20%; +} +.customers-table > thead > tr > th, +.customers-table > tbody > tr > td { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.customers-table > thead > tr > th { + color: #93a1af; + font-weight: normal; + border-bottom-width: 1px; +} +.customers-table > tbody > tr > td { + vertical-align: middle; +} +.customers-table-name > a { + color: #2a3b47; + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.customers-table-photo { + width: 28px; + height: 28px; + margin-right: 6px; + border-radius: 50%; + object-fit: cover; +} +@media (max-width:582px) { + .customers-table > thead > tr > th:nth-child(n+3), + .customers-table > tbody > tr > td:nth-child(n+3) { + display: none; + } + .customers-table-col-name { + width: 55%; + } + .customers-table-col-email { + width: 45%; + } +} /*.customers-pager a:hover, .customers-pager a:active .customers-pager a:focus, { @@ -4195,6 +4264,16 @@ a.help-icon:hover { .text-larger { font-size: 16.8px; } +.text-link, +.text-link:focus { + color: #0078D7!important; + text-decoration: none!important; + cursor: pointer; +} +.text-link:hover { + color: #000!important; + text-decoration: none!important; +} #loader-main { position: fixed; display: none; diff --git a/public/js/main.js b/public/js/main.js index 13800598..893bc07f 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -2955,6 +2955,7 @@ function searchInit() starConversationInit(); customersPagination(); + customersViewSwitchInit(); $(".sidebar-menu .menu-link a").filter('[data-filter]').click(function(e){ var trigger = $(this); @@ -3136,6 +3137,44 @@ function conversationPagination() }); } +// Customers list view: cards (default) or table. +// The choice is stored in the "customers_view" cookie and used by the server +// when rendering the list (Helper::getCustomersView()). +function setCustomersView(view) +{ + view = (view == 'table') ? 'table' : 'cards'; + + // SameSite=Lax and no Secure flag, so the cookie works on HTTP installations too. + setCookie('customers_view', view, {samesite: 'Lax'}); + updateCustomersViewSwitch(view); + loadCustomers(); +} + +function updateCustomersViewSwitch(view) +{ + $('.customers-view-switch').each(function() { + var button = $(this); + var is_table = (view == 'table'); + var title = is_table ? button.attr('data-title-cards') : button.attr('data-title-table'); + + // Icon shows the view the user will switch to. + button.toggleClass('glyphicon-th-large', is_table) + .toggleClass('glyphicon-th-list', !is_table) + .attr('title', title) + .attr('data-original-title', title); + }); +} + +function customersViewSwitchInit() +{ + $('.customers-view-switch').click(function(e) { + setCustomersView(getCookie('customers_view') == 'table' ? 'cards' : 'table'); + // The switch is inside the tab link. + e.preventDefault(); + e.stopPropagation(); + }); +} + function customersPagination() { $(".table-customers .pager-nav").click(function(e){ diff --git a/resources/views/conversations/search.blade.php b/resources/views/conversations/search.blade.php index f8a73c02..99fb9076 100644 --- a/resources/views/conversations/search.blade.php +++ b/resources/views/conversations/search.blade.php @@ -157,7 +157,7 @@ @if (Eventy::filter('search.is_tab_visible', true, App\Conversation::SEARCH_MODE_CONV))
  • {{ __('Conversations') }} ({{ $conversations->total() }})@action('search.conversations_tab_append', $filters, $conversations->total())
  • @endif -
  • {{ __('Customers') }} ({{ $customers->total() }})
  • +
  • {{ __('Customers') }} ({{ $customers->total() }})@if ($mode == App\Conversation::SEARCH_MODE_CUSTOMERS) @endif
  • @if ($mode == App\Conversation::SEARCH_MODE_CONV) @include('conversations/conversations_table', ['mailbox' => $search_mailbox, 'params' => ['target_blank' => false, 'show_mailbox' => (count(Auth::user()->mailboxesCanView(true)) > 1)]]) diff --git a/resources/views/customers/partials/customers_table.blade.php b/resources/views/customers/partials/customers_table.blade.php index f3d9db1b..027a34b5 100644 --- a/resources/views/customers/partials/customers_table.blade.php +++ b/resources/views/customers/partials/customers_table.blade.php @@ -1,15 +1,40 @@ @if (count($customers))
    - + @if (\Helper::getCustomersView() == 'table') + + + + + + + + + + + @foreach ($customers as $customer) + + + + + + + @endforeach + +
    {{ __('Name') }}{{ __('Phone') }}{{ __('Company') }}
    + {{ $customer->first_name }} {{ $customer->last_name }} + {{ $customer->getMainEmail() }}{{ $customer->getMainPhoneNumber() }}{{ $customer->company }}
    + @else + + @endif
    @if ($customers->lastPage() > 1)