close #3214 Enhancement: Document list page add default tab feature
This commit is contained in:
parent
3f93f53a0b
commit
11e681ba32
|
|
@ -100,6 +100,20 @@ abstract class Controller extends BaseController
|
|||
|
||||
public function setActiveTabForDocuments(): void
|
||||
{
|
||||
// Added this method to set the active tab for documents
|
||||
if (! request()->has('list_records') && ! request()->has('search')) {
|
||||
$tab_pins = setting('favorites.tab.' . user()->id, []);
|
||||
$tab_pins = json_decode($tab_pins, true);
|
||||
|
||||
if (! empty($tab_pins) && ! empty($tab_pins[$this->type])) {
|
||||
$data = config('type.document.' . $this->type . '.route.params.' . $tab_pins[$this->type]);
|
||||
|
||||
if (! empty($data)) {
|
||||
request()->merge($data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (request()->get('list_records') == 'all') {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -567,10 +567,24 @@ abstract class Index extends Component
|
|||
|
||||
$status = $this->getSearchStringValue('status');
|
||||
|
||||
if ($status == 'draft') {
|
||||
$unpaid = str_replace('status:', '', config('type.document.' . $type . '.route.params.unpaid.search'));
|
||||
|
||||
if ($status == $unpaid) {
|
||||
return 'unpaid';
|
||||
}
|
||||
|
||||
$draft = str_replace('status:', '', config('type.document.' . $type . '.route.params.draft.search'));
|
||||
|
||||
if ($status == $draft) {
|
||||
return 'draft';
|
||||
}
|
||||
|
||||
$suffix = $this->getTabActiveFromSetting($type);
|
||||
|
||||
if (! empty($suffix)) {
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
return 'unpaid';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Tab;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Livewire\Component;
|
||||
|
||||
class Pin extends Component
|
||||
{
|
||||
public $id;
|
||||
|
||||
public $type;
|
||||
|
||||
public $tab;
|
||||
|
||||
public $pinned = false;
|
||||
|
||||
protected $listeners = [
|
||||
'addedPin' => 'render',
|
||||
'removedPin' => 'render',
|
||||
];
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
$this->pinned = false;
|
||||
|
||||
$pins = setting('favorites.tab.' . user()->id, []);
|
||||
|
||||
if (! empty($pins) && ! $this->pinned) {
|
||||
$pins = json_decode($pins, true);
|
||||
$type_pinned = $pins[$this->type] ?? null;
|
||||
|
||||
if (isset($pins[$this->type]) && $this->tab == $type_pinned) {
|
||||
$this->pinned = true;
|
||||
}
|
||||
}
|
||||
|
||||
return view('livewire.tab.pin');
|
||||
}
|
||||
|
||||
public function changeStatus($tab)
|
||||
{
|
||||
if ($this->pinned) {
|
||||
$this->removePin($tab);
|
||||
} else {
|
||||
$this->addPin($tab);
|
||||
}
|
||||
}
|
||||
|
||||
public function addPin($tab)
|
||||
{
|
||||
$pins = setting('favorites.tab.' . user()->id, []);
|
||||
|
||||
if (!empty($pins)) {
|
||||
$pins = json_decode($pins, true);
|
||||
}
|
||||
|
||||
$type_pinned = $pins[$this->type] ?? null;
|
||||
|
||||
if ($this->tab == $type_pinned) {
|
||||
return;
|
||||
}
|
||||
|
||||
$pins[$this->type] = $tab;
|
||||
|
||||
$this->pinned = true;
|
||||
|
||||
setting(['favorites.tab.' . user()->id => json_encode($pins)])->save();
|
||||
|
||||
$this->dispatch('addedPin');
|
||||
}
|
||||
|
||||
public function removePin($tab)
|
||||
{
|
||||
$pins = setting('favorites.tab.' . user()->id, []);
|
||||
|
||||
if (!empty($pins)) {
|
||||
$pins = json_decode($pins, true);
|
||||
}
|
||||
|
||||
foreach ($pins as $key => $pinned_id) {
|
||||
if ($pinned_id != $tab) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unset($pins[$key]);
|
||||
$this->pinned = false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
setting(['favorites.tab.' . user()->id => json_encode($pins)])->save();
|
||||
|
||||
$this->dispatch('removedPin');
|
||||
}
|
||||
}
|
||||
|
|
@ -214,6 +214,19 @@ trait ViewComponents
|
|||
return $script_key;
|
||||
}
|
||||
|
||||
public function getTabActiveFromSetting($type)
|
||||
{
|
||||
$tabs = setting('favorites.tab.' . user()->id, []);
|
||||
|
||||
if (empty($tabs)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tabs = json_decode($tabs, true);
|
||||
|
||||
return $tabs[$type] ?? false;
|
||||
}
|
||||
|
||||
protected function getTextPage($type, $textPage)
|
||||
{
|
||||
if (! empty($textPage)) {
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ return [
|
|||
'params' => [
|
||||
'unpaid' => ['search' => 'status:sent,viewed,partial'],
|
||||
'draft' => ['search' => 'status:draft'],
|
||||
'all' => ['list_records' => 'all'],
|
||||
],
|
||||
],
|
||||
'permission' => [
|
||||
|
|
@ -218,6 +219,7 @@ return [
|
|||
'params' => [
|
||||
'unpaid' => ['search' => 'status:received,partial'],
|
||||
'draft' => ['search' => 'status:draft'],
|
||||
'all' => ['list_records' => 'all'],
|
||||
],
|
||||
],
|
||||
'permission' => [
|
||||
|
|
|
|||
|
|
@ -316,6 +316,11 @@ return [
|
|||
'custom' => 'Custom',
|
||||
],
|
||||
|
||||
'pin_text' => [
|
||||
'pin_tab' => 'Pin default tab',
|
||||
'unpin_tab' => 'Unpin default tab',
|
||||
],
|
||||
|
||||
'empty' => [
|
||||
'documentation' => 'Check out the <a href=":url" target="_blank" class="text-green bg-no-repeat bg-0-2 bg-0-full hover:bg-full-2 bg-gradient-to-b from-transparent to-green transition-backgroundSize">documentation</a> for more details.',
|
||||
'items' => 'Items can be products or services. You can use items when creating invoices and bills to have the price, tax etc fields populated.',
|
||||
|
|
|
|||
|
|
@ -5,26 +5,59 @@
|
|||
|
||||
<x-index.container>
|
||||
@if (! $withoutTabs)
|
||||
<x-tabs active="{{ $tabActive }}">
|
||||
<x-tabs active="{{ $tabActive }}" id="tabs-{{ $type }}">
|
||||
<x-slot name="navs">
|
||||
@stack('document_nav_start')
|
||||
|
||||
@if ($tabActive == $type . '-unpaid')
|
||||
<x-tabs.nav id="{{ $type . '-unpaid' }}" name="{{ trans('documents.statuses.unpaid') }}" active />
|
||||
<x-tabs.nav-pin
|
||||
id="{{ $type . '-unpaid' }}"
|
||||
name="{{ trans('documents.statuses.unpaid') }}"
|
||||
type="{{ $type }}"
|
||||
tab="unpaid"
|
||||
/>
|
||||
@else
|
||||
<x-tabs.nav-link id="{{ $type . '-unpaid' }}" name="{{ trans('documents.statuses.unpaid') }}" href="{{ route($routeTabDocument) }}" />
|
||||
<x-tabs.nav-pin
|
||||
id="{{ $type . '-unpaid' }}"
|
||||
href="{{ route($routeTabDocument, $routeParamsTabUnpaid) }}"
|
||||
name="{{ trans('documents.statuses.unpaid') }}"
|
||||
type="{{ $type }}"
|
||||
tab="unpaid"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($tabActive == $type . '-draft')
|
||||
<x-tabs.nav id="{{ $type . '-draft' }}" name="{{ trans('documents.statuses.draft') }}" active />
|
||||
<x-tabs.nav-pin
|
||||
id="{{ $type . '-draft' }}"
|
||||
name="{{ trans('documents.statuses.draft') }}"
|
||||
type="{{ $type }}"
|
||||
tab="draft"
|
||||
/>
|
||||
@else
|
||||
<x-tabs.nav-link id="{{ $type . '-draft' }}" name="{{ trans('documents.statuses.draft') }}" href="{{ route($routeTabDocument, $routeParamsTabDraft) }}" />
|
||||
<x-tabs.nav-pin
|
||||
id="{{ $type . '-draft' }}"
|
||||
href="{{ route($routeTabDocument, $routeParamsTabDraft) }}"
|
||||
name="{{ trans('documents.statuses.draft') }}"
|
||||
type="{{ $type }}"
|
||||
tab="draft"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($tabActive == $type . '-all')
|
||||
<x-tabs.nav id="{{ $type . '-all' }}" name="{{ trans('general.all_type', ['type' => trans_choice($textTabDocument, 2)]) }}" active />
|
||||
<x-tabs.nav-pin
|
||||
id="{{ $type . '-all' }}"
|
||||
name="{{ trans('general.all_type', ['type' => trans_choice($textTabDocument, 2)]) }}"
|
||||
type="{{ $type }}"
|
||||
tab="all"
|
||||
/>
|
||||
@else
|
||||
<x-tabs.nav-link id="{{ $type . '-all' }}" name="{{ trans('general.all_type', ['type' => trans_choice($textTabDocument, 2)]) }}" href="{{ route($routeTabDocument, ['list_records' => 'all']) }}" />
|
||||
<x-tabs.nav-pin
|
||||
id="{{ $type . '-all' }}"
|
||||
href="{{ route($routeTabDocument, ['list_records' => 'all']) }}"
|
||||
name="{{ trans('general.all_type', ['type' => trans_choice($textTabDocument, 2)]) }}"
|
||||
type="{{ $type }}"
|
||||
tab="all"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@stack('document_nav_end')
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
@props(['id', 'name', 'href', 'active', 'type', 'tab'])
|
||||
|
||||
@if (empty($href))
|
||||
<x-tabs.nav :id="$id" :active="$active ?? false">
|
||||
<div class="flex items-center">
|
||||
{{ $name }}
|
||||
|
||||
<livewire:tab.pin :type="$type" :id="$id" :tab="$tab" :pinned="$active ?? false" />
|
||||
</div>
|
||||
</x-tabs.nav>
|
||||
@else
|
||||
<x-tabs.nav-link :id="$id" :href="$href" :active="$active ?? false">
|
||||
<div class="flex items-center">
|
||||
<a href="{{ $href }}">
|
||||
{{ $name }}
|
||||
</a>
|
||||
|
||||
<livewire:tab.pin :type="$type" :id="$id" :tab="$tab" :pinned="$active ?? false" />
|
||||
</div>
|
||||
</x-tabs.nav-link>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<button class="w-8 h-8 flex items-center justify-center px-2 py-2 rounded-xl text-purple text-sm font-medium leading-6"
|
||||
data-tooltip-target="{{ $id }}-pin"
|
||||
data-tooltip-placement="top"
|
||||
>
|
||||
<span
|
||||
id="{{ $pinned ? 'index-line-actions-unpin-tab-' . $id : 'index-line-actions-pin-tab-' . $id }}"
|
||||
@class([
|
||||
'text-sm transform rotate-45 transition-all',
|
||||
'material-icons-outlined hover:scale-125' => ($pinned) ? false : true,
|
||||
'material-icons' => (! $pinned) ? false : true,
|
||||
])
|
||||
wire:click="changeStatus('{{ $tab }}')"
|
||||
>push_pin
|
||||
</span>
|
||||
|
||||
@if ($pinned)
|
||||
<div
|
||||
id="{{ $id }}-pin"
|
||||
role="tooltip"
|
||||
class="inline-block absolute invisible z-20 py-1 px-2 text-sm font-medium text-gray-900 bg-white rounded-lg border border-gray-200 shadow-sm whitespace-nowrap opacity-0"
|
||||
>
|
||||
{{ trans('general.pin_text.unpin_tab') }}
|
||||
<div class="absolute w-2 h-2 before:absolute before:w-2 before:h-2 before:bg-white before:border-gray-200 before:transform before:rotate-45 before:border -bottom-1 before:border-t-0 before:border-l-0 border-gray-200" data-popper-top></div>
|
||||
</div>
|
||||
@else
|
||||
<div
|
||||
id="{{ $id }}-pin"
|
||||
role="tooltip"
|
||||
class=" inline-block absolute invisible z-20 py-1 px-2 text-sm font-medium text-gray-900 bg-white rounded-lg border border-gray-200 shadow-sm whitespace-nowrap opacity-0"
|
||||
>
|
||||
{{ trans('general.pin_text.pin_tab') }}
|
||||
<div class="absolute w-2 h-2 w-auto before:absolute before:w-2 before:h-2 before:bg-white before:border-gray-200 before:transform before:rotate-45 before:border -bottom-1 before:border-t-0 before:border-l-0 border-gray-200" data-popper-top></div>
|
||||
</div>
|
||||
@endif
|
||||
</button>
|
||||
Loading…
Reference in New Issue