You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Appearance.php 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <?php
  2. namespace App\Filament\Company\Clusters\Settings\Pages;
  3. use App\Enums\Setting\Font;
  4. use App\Enums\Setting\PrimaryColor;
  5. use App\Enums\Setting\RecordsPerPage;
  6. use App\Enums\Setting\TableSortDirection;
  7. use App\Filament\Company\Clusters\Settings;
  8. use App\Models\Setting\Appearance as AppearanceModel;
  9. use Filament\Actions\Action;
  10. use Filament\Actions\ActionGroup;
  11. use Filament\Forms\Components\Component;
  12. use Filament\Forms\Components\Section;
  13. use Filament\Forms\Components\Select;
  14. use Filament\Forms\Form;
  15. use Filament\Notifications\Notification;
  16. use Filament\Pages\Concerns\InteractsWithFormActions;
  17. use Filament\Pages\Page;
  18. use Filament\Support\Enums\MaxWidth;
  19. use Filament\Support\Exceptions\Halt;
  20. use Illuminate\Auth\Access\AuthorizationException;
  21. use Illuminate\Contracts\Support\Htmlable;
  22. use Illuminate\Database\Eloquent\Model;
  23. use Livewire\Attributes\Locked;
  24. use function Filament\authorize;
  25. /**
  26. * @property Form $form
  27. */
  28. class Appearance extends Page
  29. {
  30. use InteractsWithFormActions;
  31. protected static ?string $title = 'Appearance';
  32. protected static string $view = 'filament.company.pages.setting.appearance';
  33. protected static ?string $cluster = Settings::class;
  34. public ?array $data = [];
  35. #[Locked]
  36. public ?AppearanceModel $record = null;
  37. public function getTitle(): string | Htmlable
  38. {
  39. return translate(static::$title);
  40. }
  41. public function getMaxContentWidth(): MaxWidth
  42. {
  43. return MaxWidth::ScreenTwoExtraLarge;
  44. }
  45. public static function getNavigationLabel(): string
  46. {
  47. return translate(static::$title);
  48. }
  49. public function mount(): void
  50. {
  51. $this->record = AppearanceModel::firstOrNew([
  52. 'company_id' => auth()->user()->currentCompany->id,
  53. ]);
  54. abort_unless(static::canView($this->record), 404);
  55. $this->fillForm();
  56. }
  57. public function fillForm(): void
  58. {
  59. $data = $this->record->attributesToArray();
  60. $this->form->fill($data);
  61. }
  62. public function save(): void
  63. {
  64. try {
  65. $data = $this->form->getState();
  66. $this->handleRecordUpdate($this->record, $data);
  67. } catch (Halt $exception) {
  68. return;
  69. }
  70. $this->getSavedNotification()->send();
  71. }
  72. protected function getSavedNotification(): Notification
  73. {
  74. return Notification::make()
  75. ->success()
  76. ->title(__('filament-panels::resources/pages/edit-record.notifications.saved.title'));
  77. }
  78. public function form(Form $form): Form
  79. {
  80. return $form
  81. ->schema([
  82. $this->getGeneralSection(),
  83. $this->getDataPresentationSection(),
  84. ])
  85. ->model($this->record)
  86. ->statePath('data')
  87. ->operation('edit');
  88. }
  89. protected function getGeneralSection(): Component
  90. {
  91. return Section::make('General')
  92. ->schema([
  93. Select::make('primary_color')
  94. ->allowHtml()
  95. ->softRequired()
  96. ->localizeLabel()
  97. ->options(
  98. collect(PrimaryColor::cases())
  99. ->sort(static fn ($a, $b) => $a->value <=> $b->value)
  100. ->mapWithKeys(static fn ($case) => [
  101. $case->value => "<span class='flex items-center gap-x-4'>
  102. <span class='rounded-full w-4 h-4' style='background:rgb(" . $case->getColor()[600] . ")'></span>
  103. <span>" . $case->getLabel() . '</span>
  104. </span>',
  105. ]),
  106. ),
  107. Select::make('font')
  108. ->allowHtml()
  109. ->softRequired()
  110. ->localizeLabel()
  111. ->options(
  112. collect(Font::cases())
  113. ->mapWithKeys(static fn ($case) => [
  114. $case->value => "<span style='font-family:{$case->getLabel()}'>{$case->getLabel()}</span>",
  115. ]),
  116. ),
  117. ])->columns();
  118. }
  119. protected function getDataPresentationSection(): Component
  120. {
  121. return Section::make('Data Presentation')
  122. ->schema([
  123. Select::make('table_sort_direction')
  124. ->softRequired()
  125. ->localizeLabel()
  126. ->options(TableSortDirection::class),
  127. Select::make('records_per_page')
  128. ->softRequired()
  129. ->localizeLabel()
  130. ->options(RecordsPerPage::class),
  131. ])->columns();
  132. }
  133. protected function handleRecordUpdate(AppearanceModel $record, array $data): AppearanceModel
  134. {
  135. $record->fill($data);
  136. $keysToWatch = [
  137. 'primary_color',
  138. 'font',
  139. ];
  140. if ($record->isDirty($keysToWatch)) {
  141. $this->dispatch('appearanceUpdated');
  142. }
  143. $record->save();
  144. return $record;
  145. }
  146. /**
  147. * @return array<Action | ActionGroup>
  148. */
  149. protected function getFormActions(): array
  150. {
  151. return [
  152. $this->getSaveFormAction(),
  153. ];
  154. }
  155. protected function getSaveFormAction(): Action
  156. {
  157. return Action::make('save')
  158. ->label(__('filament-panels::resources/pages/edit-record.form.actions.save.label'))
  159. ->submit('save')
  160. ->keyBindings(['mod+s']);
  161. }
  162. public static function canView(Model $record): bool
  163. {
  164. try {
  165. return authorize('update', $record)->allowed();
  166. } catch (AuthorizationException $exception) {
  167. return $exception->toResponse()->allowed();
  168. }
  169. }
  170. }