Andrew Wallo 1 vuosi sitten
vanhempi
commit
dc95d167b8

+ 126
- 2
app/Filament/Company/Pages/Concerns/HasDeferredFiltersForm.php Näytä tiedosto

@@ -2,10 +2,131 @@
2 2
 
3 3
 namespace App\Filament\Company\Pages\Concerns;
4 4
 
5
+use Filament\Actions\Action;
6
+use Filament\Forms\Components\DatePicker;
7
+use Filament\Forms\Form;
8
+use Illuminate\Support\Arr;
5 9
 use Illuminate\Support\Carbon;
6 10
 
7 11
 trait HasDeferredFiltersForm
8 12
 {
13
+    /**
14
+     * @var array<string, mixed> | null
15
+     */
16
+    public ?array $filters = null;
17
+
18
+    /**
19
+     * @var array<string, mixed> | null
20
+     */
21
+    public ?array $deferredFilters = null;
22
+
23
+    public function mountHasDeferredFiltersForm(): void
24
+    {
25
+        $this->initializeDefaultFilters();
26
+
27
+        $this->initializeFilters();
28
+    }
29
+
30
+    protected function initializeDefaultFilters(): void
31
+    {
32
+        //
33
+    }
34
+
35
+    public function initializeFilters(): void
36
+    {
37
+        if (! count($this->filters ?? [])) {
38
+            $this->filters = null;
39
+        }
40
+
41
+        $this->getFiltersForm()->fill($this->filters);
42
+    }
43
+
44
+    protected function getHasDeferredFiltersFormForms(): array
45
+    {
46
+        return [
47
+            'filtersForm' => $this->getFiltersForm(),
48
+        ];
49
+    }
50
+
51
+    public function filtersForm(Form $form): Form
52
+    {
53
+        return $form;
54
+    }
55
+
56
+    public function getFiltersForm(): Form
57
+    {
58
+        return $this->filtersForm($this->makeForm()
59
+            ->statePath('deferredFilters'));
60
+    }
61
+
62
+    public function updatedFilters(): void
63
+    {
64
+        $this->deferredFilters = $this->filters;
65
+
66
+        $this->handleFilterUpdates();
67
+    }
68
+
69
+    protected function isValidDate($date): bool
70
+    {
71
+        return strtotime($date) !== false;
72
+    }
73
+
74
+    protected function handleFilterUpdates(): void
75
+    {
76
+        //
77
+    }
78
+
79
+    public function applyFilters(): void
80
+    {
81
+        $this->filters = $this->deferredFilters;
82
+
83
+        $this->handleFilterUpdates();
84
+
85
+        $this->loadReportData();
86
+    }
87
+
88
+    public function applyFiltersAction(): Action
89
+    {
90
+        return Action::make('applyFilters')
91
+            ->label('Update Report')
92
+            ->action('applyFilters')
93
+            ->keyBindings(['mod+s'])
94
+            ->button();
95
+    }
96
+
97
+    public function getFilterState(string $name): mixed
98
+    {
99
+        return Arr::get($this->filters, $name);
100
+    }
101
+
102
+    public function setFilterState(string $name, mixed $value): void
103
+    {
104
+        Arr::set($this->filters, $name, $value);
105
+    }
106
+
107
+    public function getDeferredFilterState(string $name): mixed
108
+    {
109
+        return Arr::get($this->deferredFilters, $name);
110
+    }
111
+
112
+    public function setDeferredFilterState(string $name, mixed $value): void
113
+    {
114
+        Arr::set($this->deferredFilters, $name, $value);
115
+    }
116
+
117
+    protected function convertDatesToDateTimeString(array $filters): array
118
+    {
119
+        if (isset($filters['startDate'])) {
120
+            $filters['startDate'] = Carbon::parse($filters['startDate'])->startOfDay()->toDateTimeString();
121
+        }
122
+
123
+        if (isset($filters['endDate'])) {
124
+            $filters['endDate'] = Carbon::parse($filters['endDate'])->endOfDay()->toDateTimeString();
125
+        }
126
+
127
+        return $filters;
128
+    }
129
+
9 130
     protected function queryStringHasDeferredFiltersForm(): array
10 131
     {
11 132
         // Get the filter keys dynamically from the filters form
@@ -49,14 +170,17 @@ trait HasDeferredFiltersForm
49 170
     protected function excludeQueryStrings(): array
50 171
     {
51 172
         return [
52
-            'dateRange', // Example: dateRange should not have 'as' and 'keep'
173
+            'dateRange',
53 174
         ];
54 175
     }
55 176
 
56 177
     public function dehydrateHasDeferredFiltersForm(): void
57 178
     {
179
+        $flatFields = $this->getFiltersForm()->getFlatFields();
180
+
58 181
         foreach ($this->filters as $key => $value) {
59
-            if ($this->isDateFilter($value)) {
182
+            if (isset($flatFields[$key]) && $flatFields[$key] instanceof DatePicker) {
183
+                // TODO: Submit a PR to Filament to address DatePicker being dehydrated as a datetime string in filters
60 184
                 $this->filters[$key] = Carbon::parse($value)->toDateString();
61 185
             }
62 186
         }

+ 39
- 0
app/Filament/Company/Pages/Concerns/HasToggleTableColumnForm.php Näytä tiedosto

@@ -0,0 +1,39 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Pages\Concerns;
4
+
5
+use Filament\Actions\Action;
6
+use Filament\Forms\Form;
7
+use Filament\Support\Enums\ActionSize;
8
+use Filament\Support\Facades\FilamentIcon;
9
+
10
+trait HasToggleTableColumnForm
11
+{
12
+    protected function getHasToggleTableColumnFormForms(): array
13
+    {
14
+        return [
15
+            'toggleTableColumnForm' => $this->getToggleTableColumnForm(),
16
+        ];
17
+    }
18
+
19
+    public function getToggleTableColumnForm(): Form
20
+    {
21
+        return $this->toggleTableColumnForm($this->makeForm()
22
+            ->statePath('toggledTableColumns'));
23
+    }
24
+
25
+    public function toggleTableColumnForm(Form $form): Form
26
+    {
27
+        return $form;
28
+    }
29
+
30
+    public function toggleColumnsAction(): Action
31
+    {
32
+        return Action::make('toggleColumns')
33
+            ->label(__('filament-tables::table.actions.toggle_columns.label'))
34
+            ->iconButton()
35
+            ->size(ActionSize::Large)
36
+            ->icon(FilamentIcon::resolve('tables::actions.toggle-columns') ?? 'heroicon-m-view-columns')
37
+            ->color('gray');
38
+    }
39
+}

+ 43
- 0
app/Filament/Company/Pages/Dashboard.php Näytä tiedosto

@@ -0,0 +1,43 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Pages;
4
+
5
+use Filament\Forms\Components\DatePicker;
6
+use Filament\Forms\Components\Section;
7
+use Filament\Forms\Form;
8
+use Filament\Forms\Set;
9
+use Filament\Pages\Dashboard\Actions\FilterAction;
10
+use Filament\Pages\Dashboard\Concerns\HasFiltersAction;
11
+
12
+class Dashboard extends \Filament\Pages\Dashboard
13
+{
14
+    use HasFiltersAction;
15
+
16
+    //    public function filtersForm(Form $form): Form
17
+    //    {
18
+    //        return $form
19
+    //            ->schema([
20
+    //                Section::make()
21
+    //                    ->schema([
22
+    //                        DatePicker::make('startDate'),
23
+    //                        DatePicker::make('endDate'),
24
+    //                        // ...
25
+    //                    ])
26
+    //                    ->columns(3),
27
+    //            ]);
28
+    //    }
29
+
30
+    protected function getHeaderActions(): array
31
+    {
32
+        return [
33
+            FilterAction::make()
34
+                ->form([
35
+                    DatePicker::make('startDate')
36
+                        ->live()
37
+                        ->afterStateUpdated(fn (Set $set) => $set('endDate', now()->toDateTimeString())),
38
+                    DatePicker::make('endDate'),
39
+                    // ...
40
+                ]),
41
+        ];
42
+    }
43
+}

+ 3
- 130
app/Filament/Company/Pages/Reports/BaseReportPage.php Näytä tiedosto

@@ -5,6 +5,7 @@ namespace App\Filament\Company\Pages\Reports;
5 5
 use App\Contracts\ExportableReport;
6 6
 use App\DTO\ReportDTO;
7 7
 use App\Filament\Company\Pages\Concerns\HasDeferredFiltersForm;
8
+use App\Filament\Company\Pages\Concerns\HasToggleTableColumnForm;
8 9
 use App\Filament\Forms\Components\DateRangeSelect;
9 10
 use App\Models\Company;
10 11
 use App\Services\DateRangeService;
@@ -17,11 +18,8 @@ use Filament\Forms\Components\DatePicker;
17 18
 use Filament\Forms\Form;
18 19
 use Filament\Forms\Set;
19 20
 use Filament\Pages\Page;
20
-use Filament\Support\Enums\ActionSize;
21 21
 use Filament\Support\Enums\IconPosition;
22 22
 use Filament\Support\Enums\IconSize;
23
-use Filament\Support\Facades\FilamentIcon;
24
-use Illuminate\Support\Arr;
25 23
 use Illuminate\Support\Carbon;
26 24
 use Livewire\Attributes\Computed;
27 25
 use Livewire\Attributes\Session;
@@ -30,16 +28,7 @@ use Symfony\Component\HttpFoundation\StreamedResponse;
30 28
 abstract class BaseReportPage extends Page
31 29
 {
32 30
     use HasDeferredFiltersForm;
33
-
34
-    /**
35
-     * @var array<string, mixed> | null
36
-     */
37
-    public ?array $filters = null;
38
-
39
-    /**
40
-     * @var array<string, mixed> | null
41
-     */
42
-    public ?array $deferredFilters = null;
31
+    use HasToggleTableColumnForm;
43 32
 
44 33
     public string $fiscalYearStartDate;
45 34
 
@@ -71,114 +60,9 @@ abstract class BaseReportPage extends Page
71 60
 
72 61
         $this->loadDefaultDateRange();
73 62
 
74
-        $this->initializeDefaultFilters();
75
-
76
-        $this->initializeFilters();
77
-
78 63
         $this->loadDefaultTableColumnToggleState();
79 64
     }
80 65
 
81
-    protected function initializeDefaultFilters(): void
82
-    {
83
-        //
84
-    }
85
-
86
-    public function initializeFilters(): void
87
-    {
88
-        if (! count($this->filters ?? [])) {
89
-            $this->filters = null;
90
-        }
91
-
92
-        $this->getFiltersForm()->fill($this->filters);
93
-    }
94
-
95
-    protected function convertDatesToDateTimeString(array $filters): array
96
-    {
97
-        if (isset($filters['startDate'])) {
98
-            $filters['startDate'] = Carbon::parse($filters['startDate'])->startOfDay()->toDateTimeString();
99
-        }
100
-
101
-        if (isset($filters['endDate'])) {
102
-            $filters['endDate'] = Carbon::parse($filters['endDate'])->endOfDay()->toDateTimeString();
103
-        }
104
-
105
-        return $filters;
106
-    }
107
-
108
-    protected function getForms(): array
109
-    {
110
-        return [
111
-            'toggleTableColumnForm',
112
-            'filtersForm' => $this->getFiltersForm(),
113
-        ];
114
-    }
115
-
116
-    public function filtersForm(Form $form): Form
117
-    {
118
-        return $form;
119
-    }
120
-
121
-    public function getFiltersForm(): Form
122
-    {
123
-        return $this->filtersForm($this->makeForm()
124
-            ->statePath('deferredFilters'));
125
-    }
126
-
127
-    public function updatedFilters(): void
128
-    {
129
-        $this->deferredFilters = $this->filters;
130
-
131
-        $this->handleFilterUpdates();
132
-    }
133
-
134
-    protected function isValidDate($date): bool
135
-    {
136
-        return strtotime($date) !== false;
137
-    }
138
-
139
-    protected function handleFilterUpdates(): void
140
-    {
141
-        //
142
-    }
143
-
144
-    public function applyFilters(): void
145
-    {
146
-        $this->filters = $this->deferredFilters;
147
-
148
-        $this->handleFilterUpdates();
149
-
150
-        $this->loadReportData();
151
-    }
152
-
153
-    public function getFiltersApplyAction(): Action
154
-    {
155
-        return Action::make('applyFilters')
156
-            ->label('Update Report')
157
-            ->action('applyFilters')
158
-            ->keyBindings(['mod+s'])
159
-            ->button();
160
-    }
161
-
162
-    public function getFilterState(string $name): mixed
163
-    {
164
-        return Arr::get($this->filters, $name);
165
-    }
166
-
167
-    public function setFilterState(string $name, mixed $value): void
168
-    {
169
-        Arr::set($this->filters, $name, $value);
170
-    }
171
-
172
-    public function getDeferredFilterState(string $name): mixed
173
-    {
174
-        return Arr::get($this->deferredFilters, $name);
175
-    }
176
-
177
-    public function setDeferredFilterState(string $name, mixed $value): void
178
-    {
179
-        Arr::set($this->deferredFilters, $name, $value);
180
-    }
181
-
182 66
     protected function initializeProperties(): void
183 67
     {
184 68
         $this->company = auth()->user()->currentCompany;
@@ -275,21 +159,10 @@ abstract class BaseReportPage extends Page
275 159
         return Carbon::parse($this->getFilterState('endDate'))->endOfDay()->toDateTimeString();
276 160
     }
277 161
 
278
-    public function toggleColumnsAction(): Action
279
-    {
280
-        return Action::make('toggleColumns')
281
-            ->label(__('filament-tables::table.actions.toggle_columns.label'))
282
-            ->iconButton()
283
-            ->size(ActionSize::Large)
284
-            ->icon(FilamentIcon::resolve('tables::actions.toggle-columns') ?? 'heroicon-m-view-columns')
285
-            ->color('gray');
286
-    }
287
-
288 162
     public function toggleTableColumnForm(Form $form): Form
289 163
     {
290 164
         return $form
291
-            ->schema($this->getTableColumnToggleFormSchema())
292
-            ->statePath('toggledTableColumns');
165
+            ->schema($this->getTableColumnToggleFormSchema());
293 166
     }
294 167
 
295 168
     protected function hasToggleableColumns(): bool

+ 8
- 4
app/Listeners/ConfigureCompanyDefault.php Näytä tiedosto

@@ -71,17 +71,21 @@ class ConfigureCompanyDefault
71 71
         Tab::configureUsing(static function (Tab $tab) {
72 72
             $label = $tab->getLabel();
73 73
 
74
-            $translatedLabel = translate($label);
74
+            if ($label) {
75
+                $translatedLabel = translate($label);
75 76
 
76
-            $tab->label(ucwords($translatedLabel));
77
+                $tab->label(ucwords($translatedLabel));
78
+            }
77 79
         }, isImportant: true);
78 80
 
79 81
         Section::configureUsing(static function (Section $section): void {
80 82
             $heading = $section->getHeading();
81 83
 
82
-            $translatedHeading = translate($heading);
84
+            if ($heading) {
85
+                $translatedHeading = translate($heading);
83 86
 
84
-            $section->heading(ucfirst($translatedHeading));
87
+                $section->heading(ucfirst($translatedHeading));
88
+            }
85 89
         }, isImportant: true);
86 90
 
87 91
         ResourcesTab::configureUsing(static function (ResourcesTab $tab): void {

+ 1
- 4
app/Providers/FilamentCompaniesServiceProvider.php Näytä tiedosto

@@ -42,7 +42,6 @@ use Filament\Http\Middleware\DisableBladeIconComponents;
42 42
 use Filament\Http\Middleware\DispatchServingFilamentEvent;
43 43
 use Filament\Navigation\NavigationBuilder;
44 44
 use Filament\Navigation\NavigationGroup;
45
-use Filament\Pages;
46 45
 use Filament\Pages\Dashboard;
47 46
 use Filament\Panel;
48 47
 use Filament\PanelProvider;
@@ -148,9 +147,7 @@ class FilamentCompaniesServiceProvider extends PanelProvider
148 147
             ->discoverResources(in: app_path('Filament/Company/Resources'), for: 'App\\Filament\\Company\\Resources')
149 148
             ->discoverPages(in: app_path('Filament/Company/Pages'), for: 'App\\Filament\\Company\\Pages')
150 149
             ->discoverClusters(in: app_path('Filament/Company/Clusters'), for: 'App\\Filament\\Company\\Clusters')
151
-            ->pages([
152
-                Pages\Dashboard::class,
153
-            ])
150
+            ->pages([])
154 151
             ->authGuard('web')
155 152
             ->discoverWidgets(in: app_path('Filament/Company/Widgets'), for: 'App\\Filament\\Company\\Widgets')
156 153
             ->widgets([

+ 7
- 4
resources/views/filament/company/pages/reports/income-statement.blade.php Näytä tiedosto

@@ -2,9 +2,9 @@
2 2
     <x-filament::section>
3 3
         <div class="flex flex-col md:flex-row items-start md:items-center justify-between gap-4 md:gap-8">
4 4
             <!-- Form Container -->
5
-            <div class="flex-grow">
6
-                {{ $this->getFiltersForm() }}
7
-            </div>
5
+            @if(method_exists($this, 'filtersForm'))
6
+                {{ $this->filtersForm }}
7
+            @endif
8 8
 
9 9
             <!-- Grouping Button and Column Toggle -->
10 10
             <div class="flex flex-col md:flex-row items-start md:items-center gap-4 md:gap-8 flex-shrink-0">
@@ -14,7 +14,10 @@
14 14
                         :trigger-action="$this->toggleColumnsAction"
15 15
                     />
16 16
                 @endif
17
-                {{ $this->getFiltersApplyAction() }}
17
+            </div>
18
+
19
+            <div class="inline-flex items-center flex-shrink-0 min-w-[8.5rem] justify-end">
20
+                {{ $this->applyFiltersAction }}
18 21
             </div>
19 22
         </div>
20 23
     </x-filament::section>

Loading…
Peruuta
Tallenna