From 9b6af8135dbbca58235188dab7067cec8086a466 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 16 May 2026 09:44:54 +0000 Subject: [PATCH] refactor: remove unused UI components and factories for cleanup - Deleted obsolete components (`Choices`, `Input`, `ListItem`, `Table`) and trait (`HasAttributeHelpers`) from the `App\View\Components` namespace. - Removed `ConnectedAppFactory` as it is no longer utilized in the current workflow. --- app/Actions/Fortify/CreateNewUser.php | 2 +- app/Actions/Fortify/ResetUserPassword.php | 2 +- app/Concerns/PasswordValidationRules.php | 2 +- app/Concerns/ProfileValidationRules.php | 5 +- app/Concerns/UI/HasAttributeHelpers.php | 75 --- app/Factories/ConnectedAppFactory.php | 33 -- app/Livewire/Settings/Profile.php | 11 +- app/Models/ConnectedApp.php | 13 + app/Models/ConnectionProtocol.php | 5 + app/Services/ConnectedAppService.php | 6 +- app/Services/ConnectionProviderService.php | 6 +- app/View/Components/Choices.php | 430 ------------------ app/View/Components/Input.php | 62 --- app/View/Components/ListItem.php | 83 ---- app/View/Components/Table.php | 267 ----------- phpstan.neon | 4 +- pint.json | 3 - .../dashboard/connected-apps/⚡all.blade.php | 5 +- .../dashboard/roles/⚡hr-permission.blade.php | 12 +- .../dashboard/roles/⚡manager.blade.php | 4 +- .../dashboard/users/⚡assignments.blade.php | 4 +- .../pages/connected-apps/⚡create.blade.php | 24 +- .../pages/connected-apps/⚡edit.blade.php | 24 +- 23 files changed, 70 insertions(+), 1012 deletions(-) delete mode 100644 app/Concerns/UI/HasAttributeHelpers.php delete mode 100644 app/Factories/ConnectedAppFactory.php delete mode 100644 app/View/Components/Choices.php delete mode 100644 app/View/Components/Input.php delete mode 100644 app/View/Components/ListItem.php delete mode 100644 app/View/Components/Table.php diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php index 94b76a3..6cab060 100644 --- a/app/Actions/Fortify/CreateNewUser.php +++ b/app/Actions/Fortify/CreateNewUser.php @@ -17,7 +17,7 @@ final class CreateNewUser implements CreatesNewUsers /** * Validate and create a newly registered user. * - * @param array $input + * @param array $input */ public function create(array $input): User { diff --git a/app/Actions/Fortify/ResetUserPassword.php b/app/Actions/Fortify/ResetUserPassword.php index e9af5c7..82d9f0f 100644 --- a/app/Actions/Fortify/ResetUserPassword.php +++ b/app/Actions/Fortify/ResetUserPassword.php @@ -16,7 +16,7 @@ final class ResetUserPassword implements ResetsUserPasswords /** * Validate and reset the user's forgotten password. * - * @param array $input + * @param array $input */ public function reset(User $user, array $input): void { diff --git a/app/Concerns/PasswordValidationRules.php b/app/Concerns/PasswordValidationRules.php index cfafcd8..4337571 100644 --- a/app/Concerns/PasswordValidationRules.php +++ b/app/Concerns/PasswordValidationRules.php @@ -12,7 +12,7 @@ trait PasswordValidationRules /** * Get the validation rules used to validate passwords. * - * @return array|string> + * @return array */ protected function passwordRules(): array { diff --git a/app/Concerns/ProfileValidationRules.php b/app/Concerns/ProfileValidationRules.php index 3b82428..4a0e583 100644 --- a/app/Concerns/ProfileValidationRules.php +++ b/app/Concerns/ProfileValidationRules.php @@ -7,13 +7,14 @@ use App\Models\User; use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Validation\Rule; +use Illuminate\Validation\Rules\Unique; trait ProfileValidationRules { /** * Get the validation rules used to validate user profiles. * - * @return array|string>> + * @return array> */ protected function profileRules(?int $userId = null): array { @@ -36,7 +37,7 @@ protected function nameRules(): array /** * Get the validation rules used to validate user emails. * - * @return array|string> + * @return array */ protected function emailRules(?int $userId = null): array { diff --git a/app/Concerns/UI/HasAttributeHelpers.php b/app/Concerns/UI/HasAttributeHelpers.php deleted file mode 100644 index 4959ce1..0000000 --- a/app/Concerns/UI/HasAttributeHelpers.php +++ /dev/null @@ -1,75 +0,0 @@ -attributes->has($attribute); - } - - /** - * Get the error field name. - * If the parent class has an error field name (passed via props or defined), it will be returned. - * Otherwise, the model name will be returned. - */ - public function errorFieldName(): ?string - { - return $this->errorField ?? $this->modelName(); - } - - /** - * This function will return the model name from the wire:model attribute. - * This is useful as we use this to bind wire:model props passed from high level - * components (ex: input) to the internal html components (ex: input tag). - */ - public function modelName(): ?string - { - return $this->attributes->whereStartsWith('wire:model')->first(); - } - - /** - * Check if the input is required. - */ - public function isRequired(): bool - { - return $this->attributes->has('required') && true === $this->attributes->get('required'); - } - - /** - * Check if the input is disabled. - */ - public function isDisabled(): bool - { - return $this->attributes->has('disabled') && true === $this->attributes->get('disabled'); - } - - /** - * Check if the input is readonly. - */ - public function isReadonly(): bool - { - return $this->attributes->has('readonly') && true === $this->attributes->get('readonly'); - } - - /** - * Check if the input is autofocus. - */ - public function isAutofocus(): bool - { - return $this->attributes->has('autofocus') && true === $this->attributes->get('autofocus'); - } -} diff --git a/app/Factories/ConnectedAppFactory.php b/app/Factories/ConnectedAppFactory.php deleted file mode 100644 index 7628ac7..0000000 --- a/app/Factories/ConnectedAppFactory.php +++ /dev/null @@ -1,33 +0,0 @@ - $data->name, - 'connection_provider_id' => $data->connectionProviderId, - 'connection_protocol_id' => $data->connectionProtocolId, - 'slug' => $data->slug, - 'connection_status_id' => $data->statusId, - ]; - - // Check if the staus is filled, if not select disconnected by default - if (null === $data->statusId) { - $status = ConnectionStatus::query() - ->where('name', '=', ConnectionStatusEnum::Disconnected->value) - ->pluck('id'); - $result['service_status_id'] = $status[0]; - } - - return $result; - } -} diff --git a/app/Livewire/Settings/Profile.php b/app/Livewire/Settings/Profile.php index 376d60a..3edd38b 100644 --- a/app/Livewire/Settings/Profile.php +++ b/app/Livewire/Settings/Profile.php @@ -70,13 +70,18 @@ public function resendVerificationNotification(): void #[Computed] public function hasUnverifiedEmail(): bool { - return Auth::user() instanceof MustVerifyEmail && ! Auth::user()->hasVerifiedEmail(); + /** @var \App\Models\User|MustVerifyEmail|null $user */ + $user = Auth::user(); + + return $user instanceof MustVerifyEmail && ! $user->hasVerifiedEmail(); } #[Computed] public function showDeleteUser(): bool { - return ! Auth::user() instanceof MustVerifyEmail - || (Auth::user() instanceof MustVerifyEmail && Auth::user()->hasVerifiedEmail()); + /** @var \App\Models\User|MustVerifyEmail|null $user */ + $user = Auth::user(); + + return ! $user instanceof MustVerifyEmail || $user->hasVerifiedEmail(); } } diff --git a/app/Models/ConnectedApp.php b/app/Models/ConnectedApp.php index 63cd36a..96ccfc3 100644 --- a/app/Models/ConnectedApp.php +++ b/app/Models/ConnectedApp.php @@ -10,6 +10,10 @@ use Spatie\Activitylog\Models\Concerns\LogsActivity; use Spatie\Activitylog\Support\LogOptions; +/** + * @property int $id + * @property string $name + */ #[Fillable([ 'name', 'slug', @@ -21,16 +25,25 @@ class ConnectedApp extends Model { use LogsActivity, SoftDeletes; + /** + * @return HasOne + */ public function protocol(): HasOne { return $this->hasOne(ConnectionProtocol::class, 'id', 'connection_protocol_id'); } + /** + * @return BelongsTo + */ public function provider(): BelongsTo { return $this->belongsTo(ConnectionProvider::class, 'connection_provider_id'); } + /** + * @return HasOne + */ public function status(): HasOne { return $this->hasOne(ConnectionStatus::class, 'id', 'connection_status_id'); diff --git a/app/Models/ConnectionProtocol.php b/app/Models/ConnectionProtocol.php index 2e40a36..20691bc 100644 --- a/app/Models/ConnectionProtocol.php +++ b/app/Models/ConnectionProtocol.php @@ -6,6 +6,11 @@ use Illuminate\Database\Eloquent\{Model, SoftDeletes}; +/** + * @property int $id + * @property string $name + * @property string $slug + */ final class ConnectionProtocol extends Model { use SoftDeletes; diff --git a/app/Services/ConnectedAppService.php b/app/Services/ConnectedAppService.php index 805bc0e..2e93255 100644 --- a/app/Services/ConnectedAppService.php +++ b/app/Services/ConnectedAppService.php @@ -31,7 +31,7 @@ public function create(ConnectAppRequest $data): void /** * @throws InvalidArgumentException when id is invalid - * @throws Throwable when an error occurs during the update. + * @throws Throwable when an error occurs during the update. */ public function update(int $id, ConnectAppRequest $data): void { @@ -47,7 +47,7 @@ function () use ($id, $data): void { } /** - * @throws Throwable when an error occurs during the deletion. + * @throws Throwable when an error occurs during the deletion. * @throws InvalidArgumentException when id is invalid */ public function delete(int $id): void @@ -77,7 +77,7 @@ public function getAll(): PaginatedDataCollection /** * @throws ModelNotFoundException when the connected app is not found. - * @throws InvalidArgumentException when id is invalid. + * @throws InvalidArgumentException when id is invalid. */ public function getConnectedApp(int $id): ConnectedAppData { diff --git a/app/Services/ConnectionProviderService.php b/app/Services/ConnectionProviderService.php index b643fc9..454957b 100644 --- a/app/Services/ConnectionProviderService.php +++ b/app/Services/ConnectionProviderService.php @@ -53,7 +53,7 @@ public function getAll(): PaginatedDataCollection /** * @throws InvalidArgumentException when id is invalid - * @throws Throwable when an error occurs during the update. + * @throws Throwable when an error occurs during the update. */ public function update(string $slug, StoreConnectionProviderRequestData $data): void { @@ -71,7 +71,7 @@ function () use ($slug, $data): void { * Delete the connection provider and associated connected apps. * * @throws ModelNotFoundException when the connection provider is not found. - * @throws Throwable when an error occurs during the deletion. + * @throws Throwable when an error occurs during the deletion. */ public function delete(string $slug): void { @@ -107,7 +107,7 @@ function () use ($slug): void { /** * @throws ModelNotFoundException when the connected app is not found. - * @throws InvalidArgumentException when id is invalid. + * @throws InvalidArgumentException when id is invalid. */ #[NoDiscard] public function getProvider(string $slug): ConnectionProviderData diff --git a/app/View/Components/Choices.php b/app/View/Components/Choices.php deleted file mode 100644 index fae0267..0000000 --- a/app/View/Components/Choices.php +++ /dev/null @@ -1,430 +0,0 @@ -uuid = 'component'.md5(serialize($this)).$id; - - if (($this->allowAll || $this->compact) && ($this->single || $this->searchable)) { - throw new Exception('`allow-all` and `compact` does not work combined with `single` or `searchable`.'); - } - } - - public function getOptionValue($option): mixed - { - $value = data_get($option, $this->optionValue); - - if ($this->valuesAsString) { - return "'$value'"; - } - - if ($this->escapeValues) { - $value = addslashes($value); - - return "'$value'"; - } - - return is_numeric($value) && ! str($value)->startsWith('0') ? $value : "'$value'"; - } - - public function render(): View|Closure|string - { - return <<<'HTML' -
-
-
- {{-- STANDARD LABEL --}} - @if($label && !$inline) - - {{ $label }} - - @if($attributes->get('required')) - * - @endif - - - @endif - - - - {{-- ERROR --}} - @if(!$omitError) - - @endif - - {{-- HINT --}} - @if($hint) -
{{ $hint }}
- @endif -
- - {{-- OPTIONS LIST --}} -
-
- - {{-- PROGRESS --}} - @if(!$noProgress) - - @endif - - {{-- SELECT ALL --}} - @if($allowAll) -
-
{{ $allowAllText }}
-
{{ $removeAllText }}
-
- @endif - - {{-- NO RESULTS --}} -
- {{ $noResultText }} -
- - @forelse($options as $option) -
- {{-- ITEM SLOT --}} - @if($item) - {{ $item($option) }} - @else - - @endif - - {{-- SELECTION SLOT --}} - @if($selection) - - @endif -
- @empty -
No results found.
- @endforelse -
-
-
-
- HTML; - } -} diff --git a/app/View/Components/Input.php b/app/View/Components/Input.php deleted file mode 100644 index c8b38c2..0000000 --- a/app/View/Components/Input.php +++ /dev/null @@ -1,62 +0,0 @@ -uuid = 'component'.md5(serialize($this)).$id; - } - - /** - * Get the view / contents that represent the component. - */ - public function render(): View|Closure|string - { - return <<<'BLADE' -
-
- @if($label) - - {{$label}} - @if($hasAttribute('required')) - * - @endif - - @endif - merge([ - 'type' => 'text', - 'class' => 'rounded-xl border border-gray-300 px-4 py-2' - ]) - }} - /> - -
-
- BLADE; - } -} diff --git a/app/View/Components/ListItem.php b/app/View/Components/ListItem.php deleted file mode 100644 index 0cd204e..0000000 --- a/app/View/Components/ListItem.php +++ /dev/null @@ -1,83 +0,0 @@ -uuid = 'component'.md5(serialize($this)).$id; - } - - public function render(): View|Closure|string - { - return <<<'HTML' -
-
class([ - "flex justify-start items-center gap-4 px-3 py-3", - "hover:bg-gray-200" => !$noHover, - "cursor-pointer" => $link - ]) - }} - > - - - - - - @if($actions) - @if($link && !Str::of($actions)->contains([':click', '@click' , 'href'])) - - @endif -
attributes->class(["flex items-center gap-3 mary-hideable"]) }}> - {{ $actions }} -
- - @if($link && !Str::of($actions)->contains([':click', '@click' , 'href'])) -
- @endif - @endif -
- -
- HTML; - } -} diff --git a/app/View/Components/Table.php b/app/View/Components/Table.php deleted file mode 100644 index 972120a..0000000 --- a/app/View/Components/Table.php +++ /dev/null @@ -1,267 +0,0 @@ -rowDecoration; - $cellDecoration = $this->cellDecoration; - $headers = $this->headers; - - // Remove closures from serialization - unset($this->rowDecoration, $this->cellDecoration, $this->headers); - - // Serialize a unique ID for component tracking - $this->uuid = 'table-'.md5(serialize($this)).$id; - - // Restore closures - $this->rowDecoration = $rowDecoration; - $this->cellDecoration = $cellDecoration; - $this->headers = $headers; - } - - // Check if header is hidden - public function isHidden(mixed $header): bool - { - return $header['hidden'] ?? false; - } - - // Format header contents - public function format(mixed $row, mixed $field, mixed $header): mixed - { - $format = $header['format'] ?? null; - - if (! $format) { - return $field; - } - - if (is_callable($format)) { - return $format($row, $field); - } - - if ('currency' === $format[0]) { - return ($format[2] ?? '').number_format((float) $field, ...mb_str_split($format[1])); - } - - if ('date' === $format[0] && $field) { - return Carbon::parse($field)->translatedFormat($format[1]); - } - - return $field; - } - - // Check if link should be shown in cell - public function hasLink(mixed $header): bool - { - return $this->link && empty($header['disableLink']); - } - - // Build row link - public function redirectLink(mixed $row): string - { - $link = $this->link; - - // Transform from `route()` pattern - $link = Str::of($link)->replace('%5B', '{')->replace('%5D', '}'); - - // Extract tokens like {id}, {city.name} ... - $tokens = Str::of($link)->matchAll('/\{(.*?)\}/'); - - // Replace tokens with actual row values - $tokens->each(function (string $token) use ($row, &$link): void { - $link = Str::of($link)->replace('{'.$token.'}', data_get($row, $token))->toString(); - }); - - return $link; - } - - public function rowClasses(mixed $row): ?string - { - $classes = []; - - foreach ($this->rowDecoration as $class => $condition) { - if ($condition($row)) { - $classes[] = $class; - } - } - - return Arr::join($classes, ' '); - } - - public function cellClasses(mixed $row, array $header): ?string - { - $classes = Str::of($header['class'] ?? '')->explode(' ')->all(); - - foreach ($this->cellDecoration[$header['key']] ?? [] as $class => $condition) { - if ($condition($row)) { - $classes[] = $class; - } - } - - return Arr::join($classes, ' '); - } - - public function render(): View|Closure|string - { - return <<<'HTML' -
-
- whereDoesntStartWith('wire:model') - ->class([ - 'w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400', - ]) - }} - > - $noHeaders - ])> - - @foreach($headers as $header) - @php - if($isHidden($header)) continue; - - # Scoped slot's name like `user.city` are compiled to `user___city` through `@scope / @endscope`. - # So we use current `$header` key to find that slot on context. - $temp_key = str_replace('.', '___', $header['key']) - @endphp - - - @endforeach - - @if($actions) - - @endif - - - - @isset($rows) - - @foreach($rows as $k => $row) - $k < $rows->count() - 1, - $rowClasses($row), - 'even:bg-gray-50 ' => $striped, - 'hover:bg-gray-50' => !$noHover, - 'cursor-pointer' => $attributes->has('@row-click') || $link - ]) - @if($attributes->has('@row-click')) - @click="$dispatch('row-click', {{ json_encode($row) }});" - @endif - > - @foreach($headers as $header) - @php - if($isHidden($header)) continue; - $temp_key = str_replace('.', '___', $header['key']) - @endphp - - @if(isset(${"cell_".$temp_key})) - - @else - - @endif - @endforeach - - @if($actions) - - @endif - - @endforeach - - @endisset - @isset ($footer) - attributes->get('class') ?? '' - ])> - {{ $footer }} - - @endisset -
- {{ isset(${"header_".$temp_key}) ? ${"header_".$temp_key}($header) : $header['label'] }} - - Actions -
$hasLink($header)])> - @if($hasLink($header)) - - @endif - - {{ ${"cell_".$temp_key}($row) }} - - @if($hasLink($header)) - - @endif - $hasLink($header)])> - @if($hasLink($header)) - - @endif - - {{ $format($row, data_get($row, $header['key']), $header) }} - - @if($hasLink($header)) - - @endif - - {{ $actions($row) }} -
- - @if(!$rows || count($rows) === 0) - @if($showEmptyText) -
- {{ $emptyText }} -
- @endif - @if($empty) -
- {{ $empty }} -
- @endif - @endif -
- - @if($withPagination && method_exists($rows, 'links')) -
- {{ $rows->links() }} -
- @endif -
- HTML; - } -} diff --git a/phpstan.neon b/phpstan.neon index 5732528..45e9617 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -19,5 +19,5 @@ parameters: # ignoreErrors: # - '#PHPDoc tag @var#' # -# excludePaths: -# - ./*/*/FileToBeExcluded.php + excludePaths: + - resources/views/flux/* diff --git a/pint.json b/pint.json index 84302a9..b74ef63 100644 --- a/pint.json +++ b/pint.json @@ -43,9 +43,6 @@ "ordered_interfaces": true, "ordered_traits": true, "php_unit_strict": true, - "phpdoc_align": { - "align": "vertical" - }, "phpdoc_separation": true, "return_type_declaration": { "space_before": "none" diff --git a/resources/views/components/dashboard/connected-apps/⚡all.blade.php b/resources/views/components/dashboard/connected-apps/⚡all.blade.php index 8a0a7d3..0a7d236 100644 --- a/resources/views/components/dashboard/connected-apps/⚡all.blade.php +++ b/resources/views/components/dashboard/connected-apps/⚡all.blade.php @@ -16,8 +16,11 @@ public function mount(): void { } + /**\ + * @return PaginatedDataCollection + */ #[Computed] - private function getConnectedApps() + public function getConnectedApps(): PaginatedDataCollection { $service = app(ConnectedAppService::class); return $service->getAll(); diff --git a/resources/views/components/dashboard/roles/⚡hr-permission.blade.php b/resources/views/components/dashboard/roles/⚡hr-permission.blade.php index 0f709f7..8fe8c2a 100644 --- a/resources/views/components/dashboard/roles/⚡hr-permission.blade.php +++ b/resources/views/components/dashboard/roles/⚡hr-permission.blade.php @@ -42,19 +42,19 @@ public function mount(): void - + @scope('cell_view', $row) - + @endscope @scope('cell_create', $row) - + @endscope @scope('cell_update', $row) - + @endscope @scope('cell_delete', $row) - + @endscope - + diff --git a/resources/views/components/dashboard/roles/⚡manager.blade.php b/resources/views/components/dashboard/roles/⚡manager.blade.php index b1af010..a5a91c8 100644 --- a/resources/views/components/dashboard/roles/⚡manager.blade.php +++ b/resources/views/components/dashboard/roles/⚡manager.blade.php @@ -80,7 +80,7 @@ public function mount(): void - + @scope('cell_users', $role) @php /** @var RoleData $role */ @endphp
@@ -107,6 +107,6 @@ public function mount(): void @scope('actions', $role) @endscope - +
diff --git a/resources/views/components/dashboard/users/⚡assignments.blade.php b/resources/views/components/dashboard/users/⚡assignments.blade.php index 9530bd2..52fd50d 100644 --- a/resources/views/components/dashboard/users/⚡assignments.blade.php +++ b/resources/views/components/dashboard/users/⚡assignments.blade.php @@ -98,7 +98,7 @@ public function mount(): void - + @scope('cell_name', $row) @endscope @@ -133,6 +133,6 @@ public function mount(): void @scope('actions', $row) @endscope - +
diff --git a/resources/views/pages/connected-apps/⚡create.blade.php b/resources/views/pages/connected-apps/⚡create.blade.php index 4e20277..b72c1ac 100644 --- a/resources/views/pages/connected-apps/⚡create.blade.php +++ b/resources/views/pages/connected-apps/⚡create.blade.php @@ -7,7 +7,7 @@ use App\Livewire\Forms\StoreConnectedAppFrom; use App\Models\{ConnectionProtocol, ConnectionProvider, ConnectionStatus}; use App\Services\{ConnectedAppService, ConnectionProtocolService, ConnectionProviderService, ConnectionStatusService}; -use Illuminate\Database\Eloquent\Collection; +use Illuminate\Support\Collection; use Livewire\Attributes\{Computed, Title}; use Livewire\Component; use Mary\Traits\Toast; @@ -60,12 +60,6 @@ public function connectionStatuses(): DataCollection }); } - public function searchProvider(string $name) - { - $providerService = app(ConnectionProviderService::class); - $this->providers = $providerService->search($name); - } - public function save(bool $goBack = true): void { $this->form->validate(); @@ -111,15 +105,13 @@ public function goBack(): void :options="$this->protocols" placeholder="Select" /> - getAll(); } - public function searchProvider(string $name): void - { - $providerService = app(ConnectionProviderService::class); - $this->providers = $providerService->search($name); - } - public function save(): void { $this->attempt( @@ -119,15 +113,13 @@ public function save(): void :options="$this->protocols" placeholder="Select" /> -