From 9674b88ff03aa74792370bc52fa64fb4e779d06b Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 10:54:30 +0530 Subject: [PATCH 01/24] Time off management. --- .../Pages/CreateCandidate.php | 1 - .../en/enums/request-date-from-period.php | 6 ++ .../src/Enums/RequestDateFromPeriod.php | 28 +++++++ .../Resources/AllocationResource.php | 15 +--- .../Pages/ListAllocations.php | 8 +- .../Management/Resources/TimeOffResource.php | 79 ++++++++++++++++--- .../TimeOffResource/Pages/CreateTimeOff.php | 55 +++++++++++++ .../TimeOffResource/Pages/EditTimeOff.php | 55 +++++++++++++ .../TimeOffResource/Pages/ListTimeOffs.php | 77 ++++++++++++++++++ 9 files changed, 298 insertions(+), 26 deletions(-) create mode 100644 plugins/webkul/time-off/resources/lang/en/enums/request-date-from-period.php create mode 100644 plugins/webkul/time-off/src/Enums/RequestDateFromPeriod.php diff --git a/plugins/webkul/recruitments/src/Filament/Clusters/Applications/Resources/CandidateResource/Pages/CreateCandidate.php b/plugins/webkul/recruitments/src/Filament/Clusters/Applications/Resources/CandidateResource/Pages/CreateCandidate.php index f7cc2315..0b03582e 100644 --- a/plugins/webkul/recruitments/src/Filament/Clusters/Applications/Resources/CandidateResource/Pages/CreateCandidate.php +++ b/plugins/webkul/recruitments/src/Filament/Clusters/Applications/Resources/CandidateResource/Pages/CreateCandidate.php @@ -6,7 +6,6 @@ use Filament\Resources\Pages\CreateRecord; use Illuminate\Support\Facades\Auth; use Webkul\Recruitment\Filament\Clusters\Applications\Resources\CandidateResource; -use Webkul\Recruitment\Filament\Clusters\Applications\Resources\CandidateResource; class CreateCandidate extends CreateRecord { diff --git a/plugins/webkul/time-off/resources/lang/en/enums/request-date-from-period.php b/plugins/webkul/time-off/resources/lang/en/enums/request-date-from-period.php new file mode 100644 index 00000000..50e7887d --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/enums/request-date-from-period.php @@ -0,0 +1,6 @@ + 'Morning', + 'afternoon' => 'Afternoon', +]; diff --git a/plugins/webkul/time-off/src/Enums/RequestDateFromPeriod.php b/plugins/webkul/time-off/src/Enums/RequestDateFromPeriod.php new file mode 100644 index 00000000..64dd06f6 --- /dev/null +++ b/plugins/webkul/time-off/src/Enums/RequestDateFromPeriod.php @@ -0,0 +1,28 @@ + __('time_off::enums/request-date-from-period.morning'), + self::AFTERNOON => __('time_off::enums/request-date-from-period.afternoon'), + }; + } + + public static function options(): array + { + return [ + self::MORNING->value => __('time_off::enums/request-date-from-period.morning'), + self::AFTERNOON->value => __('time_off::enums/request-date-from-period.afternoon'), + ]; + } +} diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php index 0489a61b..5b145626 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php @@ -119,12 +119,12 @@ public static function table(Table $table): Table ->sortable() ->searchable(), Tables\Columns\TextColumn::make('allocation_type') - ->formatStateUsing(fn ($state) => AllocationType::options()[$state]) + ->formatStateUsing(fn($state) => AllocationType::options()[$state]) ->label(__('Allocation Type')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('state') - ->formatStateUsing(fn ($state) => State::options()[$state]) + ->formatStateUsing(fn($state) => State::options()[$state]) ->label(__('Status')) ->badge() ->sortable() @@ -153,7 +153,7 @@ public static function table(Table $table): Table Tables\Actions\Action::make('approve') ->icon('heroicon-o-check-circle') ->color('success') - ->hidden(fn ($record) => $record->state === State::VALIDATE_TWO->value) + ->hidden(fn($record) => $record->state === State::VALIDATE_TWO->value) ->action(function ($record) { if ($record->state === State::VALIDATE_ONE->value) { $record->update(['state' => State::VALIDATE_TWO->value]); @@ -170,7 +170,7 @@ public static function table(Table $table): Table }), Tables\Actions\Action::make('refuse') ->icon('heroicon-o-x-circle') - ->hidden(fn ($record) => $record->state === State::REFUSE->value) + ->hidden(fn($record) => $record->state === State::REFUSE->value) ->color('danger') ->action(function ($record) { $record->update(['state' => State::REFUSE->value]); @@ -185,13 +185,6 @@ public static function table(Table $table): Table ]); } - public static function getRelations(): array - { - return [ - // - ]; - } - public static function getPages(): array { return [ diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ListAllocations.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ListAllocations.php index 0d41afdf..511e6057 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ListAllocations.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ListAllocations.php @@ -24,7 +24,7 @@ public function getPresetTableViews(): array ->icon('heroicon-o-user-circle') ->favorite() ->default() - ->modifyQueryUsing(fn (Builder $query) => $query->whereIn('state', [ + ->modifyQueryUsing(fn(Builder $query) => $query->whereIn('state', [ State::CONFIRM->value, State::VALIDATE_ONE->value, ])), @@ -32,7 +32,7 @@ public function getPresetTableViews(): array ->icon('heroicon-o-shield-check') ->favorite() ->default() - ->modifyQueryUsing(fn (Builder $query) => $query->whereIn('state', [ + ->modifyQueryUsing(fn(Builder $query) => $query->whereIn('state', [ State::CONFIRM->value, State::VALIDATE_TWO->value, ])), @@ -40,7 +40,7 @@ public function getPresetTableViews(): array ->icon('heroicon-o-check-badge') ->favorite() ->default() - ->modifyQueryUsing(fn (Builder $query) => $query->where('state', State::VALIDATE_TWO->value)), + ->modifyQueryUsing(fn(Builder $query) => $query->where('state', State::VALIDATE_TWO->value)), 'valid' => PresetView::make(__('Currently Valid')) ->icon('heroicon-o-check') ->default() @@ -80,7 +80,7 @@ public function getPresetTableViews(): array 'refused' => PresetView::make(__('Refused')) ->icon('heroicon-o-x-circle') ->default() - ->modifyQueryUsing(fn (Builder $query) => $query->where('state', State::REFUSE->value)), + ->modifyQueryUsing(fn(Builder $query) => $query->where('state', State::REFUSE->value)), ]; } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php index 8d1e0164..7feddeac 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php @@ -11,6 +11,8 @@ use Filament\Tables\Table; use Illuminate\Support\Carbon; use Webkul\Employee\Models\Employee; +use Webkul\TimeOff\Enums\RequestDateFromPeriod; +use Webkul\TimeOff\Enums\State; use Webkul\TimeOff\Filament\Clusters\Management; use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource\Pages; use Webkul\TimeOff\Models\Leave; @@ -79,16 +81,14 @@ public static function form(Form $form): Form Forms\Components\DatePicker::make('request_date_to') ->native(false) ->default(now()) - ->hidden(fn (Get $get) => $get('request_unit_half')) + ->hidden(fn(Get $get) => $get('request_unit_half')) ->required(), Forms\Components\Select::make('request_date_from_period') ->label('Period') - ->options([ - 'morning' => 'Morning', - 'afternoon' => 'Afternoon', - ]) + ->options(RequestDateFromPeriod::class) + ->default(RequestDateFromPeriod::MORNING->value) ->native(false) - ->visible(fn (Get $get) => $get('request_unit_half')) + ->visible(fn(Get $get) => $get('request_unit_half')) ->required(), ]), Forms\Components\Toggle::make('request_unit_half') @@ -100,13 +100,17 @@ public static function form(Form $form): Form ->inlineLabel() ->reactive() ->content(function ($state, Get $get): string { + if ($get('request_unit_half')) { + return '0.5 day'; + } + $startDate = Carbon::parse($get('request_date_from')); $endDate = $get('request_date_to') ? Carbon::parse($get('request_date_to')) : $startDate; - return $startDate->diffInDays($endDate) + 1 .' day(s)'; + return $startDate->diffInDays($endDate) + 1 . ' day(s)'; }), - Forms\Components\TextInput::make('private_name') - ->label('Private Name') + Forms\Components\Textarea::make('private_name') + ->label('Description') ->live(), Forms\Components\FileUpload::make('attachment') ->label('Attachment') @@ -129,13 +133,68 @@ public static function table(Table $table): Table { return $table ->columns([ - // + Tables\Columns\TextColumn::make('employee.name') + ->label(__('Employee Name')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('holidayStatus.name') + ->label(__('Time Off Type')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('private_name') + ->label(__('Description')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('date_from') + ->label(__('Date From')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('date_to') + ->label(__('Date To')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('duration_display') + ->label(__('Duration')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('state') + ->label(__('Status')) + ->formatStateUsing(fn($state) => State::options()[$state]) + ->sortable() + ->badge() + ->searchable(), ]) ->filters([ // ]) ->actions([ Tables\Actions\EditAction::make(), + Tables\Actions\Action::make('approve') + ->icon('heroicon-o-check-circle') + ->color('success') + ->hidden(fn($record) => $record->state === State::VALIDATE_TWO->value) + ->action(function ($record) { + if ($record->state === State::VALIDATE_ONE->value) { + $record->update(['state' => State::VALIDATE_TWO->value]); + } else { + $record->update(['state' => State::VALIDATE_TWO->value]); + } + }) + ->label(function ($record) { + if ($record->state === State::VALIDATE_ONE->value) { + return 'Validate'; + } else { + return 'Approve'; + } + }), + Tables\Actions\Action::make('refuse') + ->icon('heroicon-o-x-circle') + ->hidden(fn($record) => $record->state === State::REFUSE->value) + ->color('danger') + ->action(function ($record) { + $record->update(['state' => State::REFUSE->value]); + }) + ->label('Refuse'), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php index 32baadc2..9728e4e1 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php @@ -3,9 +3,64 @@ namespace Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource\Pages; use Filament\Resources\Pages\CreateRecord; +use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Auth; +use Webkul\Employee\Models\Employee; +use Webkul\TimeOff\Enums\State; use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; class CreateTimeOff extends CreateRecord { protected static string $resource = TimeOffResource::class; + + protected function mutateFormDataBeforeCreate(array $data): array + { + if (isset($data['employee_id'])) { + $employee = Employee::find($data['employee_id']); + + if ($employee->department) { + $data['department_id'] = $employee->department->id; + } else { + $data['department_id'] = null; + } + + if ($employee->calendar) { + $data['calendar_id'] = $employee->calendar->id; + $data['number_of_hours'] = $employee->calendar->hours_per_day; + } + + $user = $employee?->user; + + if ($user) { + $data['user_id'] = $user->id; + + $data['company_id'] = $user->default_company_id; + + $data['employee_company_id'] = $user->default_company_id; + } + } + + + if (isset($data['request_unit_half'])) { + $data['duration_display'] = '0.5 day'; + + $data['number_of_days'] = 0.5; + } else { + $startDate = Carbon::parse($data['request_date_from']); + $endDate = $data['request_date_to'] ? Carbon::parse($data['request_date_to']) : $startDate; + + $data['duration_display'] = $startDate->diffInDays($endDate) + 1 . ' day(s)'; + + $data['number_of_days'] = $startDate->diffInDays($endDate) + 1; + } + + $data['creator_id'] = Auth::user()->id; + + $data['state'] = State::CONFIRM->value; + + $data['date_from'] = $data['request_date_from']; + $data['date_to'] = $data['request_date_to']; + + return $data; + } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php index b105456a..1f3d42c8 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php @@ -4,6 +4,10 @@ use Filament\Actions; use Filament\Resources\Pages\EditRecord; +use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Auth; +use Webkul\Employee\Models\Employee; +use Webkul\TimeOff\Enums\State; use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; class EditTimeOff extends EditRecord @@ -16,4 +20,55 @@ protected function getHeaderActions(): array Actions\DeleteAction::make(), ]; } + + protected function mutateFormDataBeforeSave(array $data): array + { + if (isset($data['employee_id'])) { + $employee = Employee::find($data['employee_id']); + + if ($employee->department) { + $data['department_id'] = $employee->department->id; + } else { + $data['department_id'] = null; + } + + if ($employee->calendar) { + $data['calendar_id'] = $employee->calendar->id; + $data['number_of_hours'] = $employee->calendar->hours_per_day; + } + + $user = $employee?->user; + + if ($user) { + $data['user_id'] = $user->id; + + $data['company_id'] = $user->default_company_id; + + $data['employee_company_id'] = $user->default_company_id; + } + } + + + if (isset($data['request_unit_half'])) { + $data['duration_display'] = '0.5 day'; + + $data['number_of_days'] = 0.5; + } else { + $startDate = Carbon::parse($data['request_date_from']); + $endDate = $data['request_date_to'] ? Carbon::parse($data['request_date_to']) : $startDate; + + $data['duration_display'] = $startDate->diffInDays($endDate) + 1 . ' day(s)'; + + $data['number_of_days'] = $startDate->diffInDays($endDate) + 1; + } + + $data['creator_id'] = Auth::user()->id; + + $data['state'] = State::CONFIRM->value; + + $data['date_from'] = $data['request_date_from']; + $data['date_to'] = $data['request_date_to']; + + return $data; + } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ListTimeOffs.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ListTimeOffs.php index 41d531a0..94a27a27 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ListTimeOffs.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ListTimeOffs.php @@ -6,10 +6,87 @@ use Filament\Resources\Pages\ListRecords; use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; + + +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Support\Facades\Auth; +use Webkul\TableViews\Filament\Components\PresetView; +use Webkul\TableViews\Filament\Concerns\HasTableViews; +use Webkul\TimeOff\Enums\State; + class ListTimeOffs extends ListRecords { + use HasTableViews; + protected static string $resource = TimeOffResource::class; + public function getPresetTableViews(): array + { + return [ + 'waiting_for_me' => PresetView::make(__('Waiting For Me')) + ->icon('heroicon-o-user-circle') + ->favorite() + ->default() + ->modifyQueryUsing(fn(Builder $query) => $query->whereIn('state', [ + State::CONFIRM->value, + State::VALIDATE_ONE->value, + ])), + 'second_approval' => PresetView::make(__('Second Approval')) + ->icon('heroicon-o-shield-check') + ->favorite() + ->default() + ->modifyQueryUsing(fn(Builder $query) => $query->whereIn('state', [ + State::CONFIRM->value, + State::VALIDATE_TWO->value, + ])), + 'approved' => PresetView::make(__('Approved')) + ->icon('heroicon-o-check-badge') + ->favorite() + ->default() + ->modifyQueryUsing(fn(Builder $query) => $query->where('state', State::VALIDATE_TWO->value)), + 'valid' => PresetView::make(__('Currently Valid')) + ->icon('heroicon-o-check') + ->default() + ->modifyQueryUsing(function (Builder $query) { + $today = now()->format('Y-m-d'); + + return $query + ->where(function ($query) use ($today) { + $query + ->whereDate('date_from', '<=', $today) + ->whereDate('date_to', '>=', $today); + }); + }), + 'my_team' => PresetView::make(__('My Team')) + ->icon('heroicon-o-users') + ->default() + ->modifyQueryUsing(function (Builder $query) { + $currentUserId = Auth::user()->id; + + return $query->whereHas('employee', function ($query) use ($currentUserId) { + $query->where('leave_manager_id', '=', $currentUserId) + ->orWhere('user_id', '=', $currentUserId); + }); + }), + 'my_department' => PresetView::make(__('My Team')) + ->icon('heroicon-o-building-office') + ->default() + ->modifyQueryUsing(function (Builder $query) { + $currentUserId = Auth::user()->id; + + return $query->whereHas('employee', function ($query) use ($currentUserId) { + $query->whereHas('parent', function ($query) use ($currentUserId) { + $query->where('user_id', '=', $currentUserId); + }); + }); + }), + 'refused' => PresetView::make(__('Refused')) + ->icon('heroicon-o-x-circle') + ->default() + ->modifyQueryUsing(fn(Builder $query) => $query->where('state', State::REFUSE->value)), + ]; + } + protected function getHeaderActions(): array { return [ From ecc36bc3825dde479aed2361d0aae9d0551a7f6d Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 12:44:48 +0530 Subject: [PATCH 02/24] Add accrual plan seeder and public holiday resource; enhance calendar leaves model --- .../employees/src/Models/CalendarLeaves.php | 29 +++- .../database/seeders/AccrualPlanSeeder.php | 36 +++++ .../database/seeders/DatabaseSeeder.php | 1 + .../Resources/AccrualPlanResource.php | 19 ++- .../Resources/PublicHolidayResource.php | 127 ++++++++++++++++++ .../Pages/ListPublicHolidays.php | 19 +++ .../Management/Resources/TimeOffResource.php | 19 ++- .../src/Filament/Widgets/CalendarWidget.php | 90 ++++--------- 8 files changed, 269 insertions(+), 71 deletions(-) create mode 100644 plugins/webkul/time-off/database/seeders/AccrualPlanSeeder.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource/Pages/ListPublicHolidays.php diff --git a/plugins/webkul/employees/src/Models/CalendarLeaves.php b/plugins/webkul/employees/src/Models/CalendarLeaves.php index b7e731da..5a2e02b9 100644 --- a/plugins/webkul/employees/src/Models/CalendarLeaves.php +++ b/plugins/webkul/employees/src/Models/CalendarLeaves.php @@ -1,13 +1,40 @@ belongsTo(User::class); + } + + public function calendar() + { + return $this->belongsTo(Calendar::class); + } + + public function company() + { + return $this->belongsTo(Company::class); + } } diff --git a/plugins/webkul/time-off/database/seeders/AccrualPlanSeeder.php b/plugins/webkul/time-off/database/seeders/AccrualPlanSeeder.php new file mode 100644 index 00000000..1f43bfc4 --- /dev/null +++ b/plugins/webkul/time-off/database/seeders/AccrualPlanSeeder.php @@ -0,0 +1,36 @@ +delete(); + + $leaveAccrualPlans = [ + [ + 'company_id' => 1, + 'creator_id' => 1, + 'name' => 'Seniority Plan', + 'transition_mode' => 'immediately', + 'accrued_gain_time' => 'end', + 'carryover_date' => 'year_start', + 'carryover_month' => 'jan', + 'is_active' => true, + 'created_at' => now(), + 'updated_at' => now(), + ], + ]; + + DB::table('time_off_leave_accrual_plans')->insert($leaveAccrualPlans); + } +} diff --git a/plugins/webkul/time-off/database/seeders/DatabaseSeeder.php b/plugins/webkul/time-off/database/seeders/DatabaseSeeder.php index 1e9b2280..43b01c8c 100644 --- a/plugins/webkul/time-off/database/seeders/DatabaseSeeder.php +++ b/plugins/webkul/time-off/database/seeders/DatabaseSeeder.php @@ -15,6 +15,7 @@ class DatabaseSeeder extends Seeder public function run($parameters = []) { $this->call([ + AccrualPlanSeeder::class, LeaveTypeSeeder::class, ]); } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php index 1de44313..9e0e6fd9 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php @@ -4,6 +4,7 @@ use Filament\Forms; use Filament\Forms\Form; +use Filament\Forms\Get; use Filament\Infolists; use Filament\Infolists\Infolist; use Filament\Pages\SubNavigationPosition; @@ -69,9 +70,14 @@ public static function form(Form $form): Form ->label(__('Carry-Over Time')) ->options(CarryoverDate::class) ->default(CarryoverDate::OTHER->value) + ->live() ->required(), Forms\Components\Fieldset::make() ->label('Carry-Over Date') + ->live() + ->visible(function (Get $get) { + return $get('carryover_date') === CarryoverDate::OTHER->value; + }) ->schema([ Forms\Components\Select::make('carryover_day') ->hiddenLabel() @@ -85,6 +91,9 @@ public static function form(Form $form): Form ->default(CarryoverMonth::JAN->value) ->required(), ])->columns(2), + Forms\Components\Toggle::make('is_active') + ->inline(false) + ->label(__('Status')), ]), ])->columns(2), ]); @@ -99,7 +108,7 @@ public static function table(Table $table): Table ->label(__('Name')), Tables\Columns\TextColumn::make('leaveAccrualLevels') ->searchable() - ->formatStateUsing(fn ($record) => $record->leaveAccrualLevels?->count()) + ->formatStateUsing(fn($record) => $record->leaveAccrualLevels?->count()) ->label(__('Levels')), ]) ->filters([ @@ -137,22 +146,22 @@ public static function infolist(Infolist $infolist): Infolist Infolists\Components\TextEntry::make('accrued_gain_time') ->icon('heroicon-o-clock') ->placeholder('—') - ->formatStateUsing(fn ($state) => AccruedGainTime::options()[$state]) + ->formatStateUsing(fn($state) => AccruedGainTime::options()[$state]) ->label(__('Accrued Gain Time')), Infolists\Components\TextEntry::make('carryover_date') ->icon('heroicon-o-calendar') ->placeholder('—') - ->formatStateUsing(fn ($state) => CarryoverDate::options()[$state]) + ->formatStateUsing(fn($state) => CarryoverDate::options()[$state]) ->label(__('Carryover Time')), Infolists\Components\TextEntry::make('carryover_day') ->icon('heroicon-o-calendar') ->placeholder('—') - ->formatStateUsing(fn ($state) => CarryoverDay::options()[$state]) + ->formatStateUsing(fn($state) => CarryoverDay::options()[$state]) ->label(__('Carryover Day')), Infolists\Components\TextEntry::make('carryover_month') ->icon('heroicon-o-calendar') ->placeholder('—') - ->formatStateUsing(fn ($state) => CarryoverMonth::options()[$state]) + ->formatStateUsing(fn($state) => CarryoverMonth::options()[$state]) ->label(__('Carryover Month')), ]), ]) diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php new file mode 100644 index 00000000..5a66a397 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php @@ -0,0 +1,127 @@ +schema([ + Forms\Components\Section::make([ + Forms\Components\Group::make() + ->schema([ + Forms\Components\Hidden::make('time_type') + ->default('leave'), + Forms\Components\TextInput::make('name') + ->label('Name') + ->required() + ->placeholder('Enter the name of the public holiday'), + ])->columns(2), + + Forms\Components\Group::make() + ->schema([ + Forms\Components\DatePicker::make('date_from') + ->label('Date From') + ->native(false) + ->required(), + Forms\Components\DatePicker::make('date_to') + ->label('Date To') + ->required() + ->native(false), + ])->columns(2), + Forms\Components\Select::make('calendar') + ->searchable() + ->preload() + ->relationship('calendar', 'name'), + ]), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('name') + ->searchable() + ->sortable() + ->label('Name'), + Tables\Columns\TextColumn::make('date_from') + ->sortable() + ->label('Date From'), + Tables\Columns\TextColumn::make('date_to') + ->sortable() + ->label('Date To'), + Tables\Columns\TextColumn::make('calendar.name') + ->sortable() + ->label('Calendar'), + ]) + ->groups([ + Tables\Grouping\Group::make('date_from') + ->label(__('Date From')) + ->collapsible(), + Tables\Grouping\Group::make('date_to') + ->label(__('Date To')) + ->collapsible(), + ]) + ->actions([ + Tables\Actions\ViewAction::make(), + Tables\Actions\EditAction::make(), + Tables\Actions\DeleteAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function infolist(Infolist $infolist): Infolist + { + return $infolist + ->schema([ + Infolists\Components\ColorEntry::make('name') + ->placeholder('—') + ->label(__('Name')), + Infolists\Components\TextEntry::make('date_from') + ->placeholder('-') + ->icon('heroicon-o-calendar') + ->label(__('Date From')), + Infolists\Components\TextEntry::make('date_to') + ->date() + ->placeholder('-') + ->icon('heroicon-o-calendar') + ->label(__('Date To')), + Infolists\Components\TextEntry::make('calendar.name') + ->placeholder('-') + ->icon('heroicon-o-clock') + ->label(__('Working Hours')), + ]); + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListPublicHolidays::route('/'), + ]; + } +} diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource/Pages/ListPublicHolidays.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource/Pages/ListPublicHolidays.php new file mode 100644 index 00000000..d9b2cc60 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource/Pages/ListPublicHolidays.php @@ -0,0 +1,19 @@ +live(), ]), - ])->columns(2), + ]), ]); } @@ -164,6 +164,23 @@ public static function table(Table $table): Table ->badge() ->searchable(), ]) + ->groups([ + Tables\Grouping\Group::make('employee.name') + ->label(__('Employee Name')) + ->collapsible(), + Tables\Grouping\Group::make('holidayStatus.name') + ->label(__('Time Off Type')) + ->collapsible(), + Tables\Grouping\Group::make('state') + ->label(__('Status')) + ->collapsible(), + Tables\Grouping\Group::make('date_from') + ->label(__('Start Date')) + ->collapsible(), + Tables\Grouping\Group::make('date_to') + ->label(__('Start To')) + ->collapsible(), + ]) ->filters([ // ]) diff --git a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php index 036e222d..f9f7ac79 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php @@ -4,9 +4,11 @@ use Carbon\Carbon; use Filament\Forms; +use Filament\Forms\Form; use Illuminate\Database\Eloquent\Model; use Saade\FilamentFullCalendar\Actions; use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget; +use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; use Webkul\TimeOff\Models\Leave; class CalendarWidget extends FullCalendarWidget @@ -17,6 +19,7 @@ protected function headerActions(): array { return [ Actions\CreateAction::make() + ->form(fn(Form $form) => TimeOffResource::form($form)) ->mountUsing( function (Forms\Form $form, array $arguments) { $form->fill($arguments); @@ -51,7 +54,7 @@ public function getFormSchema(): array ]), Forms\Components\Placeholder::make('requested_days') ->label('Requested Days') - ->content(fn ($state): string => $state), + ->content(fn($state): string => $state), Forms\Components\Textarea::make('reason') ->label('Reason') ->placeholder('Write the reason for your time off') @@ -59,55 +62,26 @@ public function getFormSchema(): array ]; } - public function fetchEvents(array $info): array + public function fetchEvents(array $fetchInfo): array { - $today = Carbon::now(); - - // $events = Leave::all()->map(function ($leave) { - // return [ - // 'id' => $leave->id, - // 'title' => $leave->holidayStatus->name, - // 'start' => $leave->request_date_from, - // 'end' => $leave->request_date_to, - // 'allDay' => true, - // 'backgroundColor' => $this->getEventColor('paid'), - // 'borderColor' => $this->getEventColor('paid'), - // 'textColor' => '#ffffff', - // ]; - // }); - - return [ - [ - 'id' => 1, - 'title' => 'Vacation in Paris', - 'start' => $today->subDays(10)->toDateString(), - 'end' => $today->subDays(5)->toDateString(), - 'allDay' => true, - 'backgroundColor' => $this->getEventColor('paid'), - 'borderColor' => $this->getEventColor('paid'), - 'textColor' => '#ffffff', - ], - [ - 'id' => 2, - 'title' => 'Sick Leave', - 'start' => $today->toDateString(), - 'end' => $today->addDay()->toDateString(), - 'allDay' => true, - 'backgroundColor' => $this->getEventColor('sick'), - 'borderColor' => $this->getEventColor('sick'), - 'textColor' => '#ffffff', - ], - [ - 'id' => 3, - 'title' => 'Family Wedding', - 'start' => $today->addDays(5)->toDateString(), - 'end' => $today->addDays(7)->toDateString(), - 'allDay' => true, - 'backgroundColor' => $this->getEventColor('paid'), - 'borderColor' => $this->getEventColor('paid'), - 'textColor' => '#ffffff', - ], - ]; + return Leave::query() + ->where('request_date_from', '>=', $fetchInfo['start']) + ->where('request_date_to', '<=', $fetchInfo['end']) + ->with('holidayStatus') + ->get() + ->map(function (Leave $leave) { + return [ + 'id' => $leave->id, + 'title' => $leave->holidayStatus->name, + 'start' => $leave->request_date_from, + 'end' => $leave->request_date_to, + 'allDay' => true, + 'backgroundColor' => $leave->holidayStatus->color, + 'borderColor' => $leave->holidayStatus->color, + 'textColor' => '#ffffff', + ]; + }) + ->all(); } public function onDateSelect(string $start, ?string $end, bool $allDay, ?array $view, ?array $resource): void @@ -117,22 +91,10 @@ public function onDateSelect(string $start, ?string $end, bool $allDay, ?array $ $numberOfDays = $startDate->diffInDays($endDate) + 1; - $data = [ + $this->mountAction('create', [ 'start_date' => $startDate->toDateString(), 'end_date' => $endDate->toDateString(), - 'requested_days' => $numberOfDays.' Days', - ]; - - $this->mountAction('create', $data); - } - - protected function getEventColor(string $type): string - { - return match ($type) { - 'paid' => '#28a745', - 'unpaid' => '#dc3545', - 'sick' => '#ffc107', - default => '#6c757d', - }; + 'requested_days' => $numberOfDays . ' Days', + ]); } } From a8d094605d43cd653b1ae990ba13a1c2664de5c8 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 13:34:50 +0530 Subject: [PATCH 03/24] Add CRUD pages for MyTimeOff and MyAllocation resources; update dashboard navigation and event fetching logic --- .../Resources/AllocationResource.php | 10 +- .../Pages/CreateAllocation.php | 5 + .../Pages/EditAllocation.php | 11 +- .../Pages/ViewAllocation.php | 20 ++ .../Management/Resources/TimeOffResource.php | 1 + .../MyTime/Resources/MyAllocationResource.php | 195 ++++++++++++++++ .../Pages/CreateMyAllocation.php | 28 +++ .../Pages/EditMyAllocation.php | 36 +++ .../Pages/ListMyAllocations.php | 19 ++ .../MyTime/Resources/MyTimeOffResource.php | 208 ++++++++++++++++++ .../Pages/CreateMyTimeOff.php | 25 +++ .../MyTimeOffResource/Pages/EditMyTimeOff.php | 32 +++ .../Pages/ListMyTimeOffs.php | 19 ++ .../time-off/src/Filament/Pages/Dashboard.php | 4 +- .../src/Filament/Widgets/CalendarWidget.php | 19 +- 15 files changed, 617 insertions(+), 15 deletions(-) create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/CreateMyAllocation.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ListMyAllocations.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ListMyTimeOffs.php diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php index 5b145626..c0196659 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php @@ -37,8 +37,10 @@ public static function form(Form $form): Form State::VALIDATE_TWO->value, ]; - if ($record->state === State::REFUSE->value) { - $onlyStates[] = State::REFUSE->value; + if ($record) { + if ($record->state === State::REFUSE->value) { + $onlyStates[] = State::REFUSE->value; + } } return collect(State::options())->only($onlyStates)->toArray(); @@ -111,7 +113,7 @@ public static function table(Table $table): Table ->sortable() ->searchable(), Tables\Columns\TextColumn::make('holidayStatus.name') - ->label(__('Employee Name')) + ->label(__('Time Off Type')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('number_of_days') @@ -150,6 +152,7 @@ public static function table(Table $table): Table ->actions([ Tables\Actions\ActionGroup::make([ Tables\Actions\EditAction::make(), + Tables\Actions\DeleteAction::make(), Tables\Actions\Action::make('approve') ->icon('heroicon-o-check-circle') ->color('success') @@ -191,6 +194,7 @@ public static function getPages(): array 'index' => Pages\ListAllocations::route('/'), 'create' => Pages\CreateAllocation::route('/create'), 'edit' => Pages\EditAllocation::route('/{record}/edit'), + 'view' => Pages\ViewAllocation::route('/{record}'), ]; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/CreateAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/CreateAllocation.php index 6e2b3836..32aabab7 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/CreateAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/CreateAllocation.php @@ -8,4 +8,9 @@ class CreateAllocation extends CreateRecord { protected static string $resource = AllocationResource::class; + + protected function getRedirectUrl(): string + { + return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); + } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php index 62311aea..a070e776 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php @@ -12,13 +12,18 @@ class EditAllocation extends EditRecord { protected static string $resource = AllocationResource::class; + protected function getRedirectUrl(): string + { + return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); + } + protected function getHeaderActions(): array { return [ Action::make('approved') ->label('Approved') ->color('gray') - ->hidden(fn ($record) => $record->state !== State::CONFIRM->value) + ->hidden(fn($record) => $record->state !== State::CONFIRM->value) ->action(function ($record) { $record->update(['state' => State::VALIDATE_TWO->value]); @@ -27,7 +32,7 @@ protected function getHeaderActions(): array Action::make('refuse') ->label('Refuse') ->color('gray') - ->hidden(fn ($record) => $record->state === State::REFUSE->value) + ->hidden(fn($record) => $record->state === State::REFUSE->value) ->action(function ($record) { $record->update(['state' => State::REFUSE->value]); @@ -36,7 +41,7 @@ protected function getHeaderActions(): array Action::make('mark_as_ready_to_confirm') ->label('Mark as Ready to Confirm') ->color('gray') - ->visible(fn ($record) => $record->state === State::REFUSE->value) + ->visible(fn($record) => $record->state === State::REFUSE->value) ->action(function ($record) { $record->update(['state' => State::CONFIRM->value]); diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php new file mode 100644 index 00000000..271d55b6 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php @@ -0,0 +1,20 @@ +actions([ + Tables\Actions\DeleteAction::make(), Tables\Actions\EditAction::make(), Tables\Actions\Action::make('approve') ->icon('heroicon-o-check-circle') diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php new file mode 100644 index 00000000..44915986 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php @@ -0,0 +1,195 @@ +schema([ + Forms\Components\Grid::make() + ->schema([ + ProgressStepper::make('state') + ->hiddenLabel() + ->inline() + ->options(function ($record) { + $onlyStates = [ + State::CONFIRM->value, + State::VALIDATE_TWO->value, + ]; + + if ($record) { + if ($record->state === State::REFUSE->value) { + $onlyStates[] = State::REFUSE->value; + } + } + + return collect(State::options())->only($onlyStates)->toArray(); + }) + ->default(State::CONFIRM->value) + ->columnSpan('full') + ->disabled() + ->reactive() + ->live(), + ])->columns(2), + Forms\Components\Section::make() + ->schema([ + Forms\Components\Group::make() + ->schema([ + Forms\Components\TextInput::make('name') + ->label('Name') + ->placeholder('Time Off Type (From validity start to validity end/no limit)') + ->required(), + Forms\Components\Grid::make(1) + ->schema([ + Forms\Components\Select::make('holiday_status_id') + ->label('Time Off Type') + ->relationship('holidayStatus', 'name') + ->searchable() + ->preload() + ->required(), + ]), + Forms\Components\Radio::make('allocation_type') + ->label('Allocation Type') + ->options(AllocationType::class) + ->default(AllocationType::REGULAR->value) + ->required(), + Forms\Components\Fieldset::make('Validity Period') + ->schema([ + Forms\Components\DatePicker::make('date_from') + ->label('From') + ->native(false) + ->required() + ->default(now()), + Forms\Components\DatePicker::make('date_to') + ->label('To') + ->native(false) + ->placeholder('No limit'), + ]), + Forms\Components\TextInput::make('number_of_days') + ->label('Allocation') + ->numeric() + ->default(0) + ->required() + ->suffix('Number of Days'), + Forms\Components\RichEditor::make('notes') + ->label('Reason'), + ]), + ])->columns(2), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('holidayStatus.name') + ->label(__('Time Off Type')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('number_of_days') + ->label(__('Amount')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('allocation_type') + ->formatStateUsing(fn($state) => AllocationType::options()[$state]) + ->label(__('Allocation Type')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('state') + ->formatStateUsing(fn($state) => State::options()[$state]) + ->label(__('Status')) + ->badge() + ->sortable() + ->searchable(), + ]) + ->groups([ + Tables\Grouping\Group::make('employee.name') + ->label(__('Employee Name')) + ->collapsible(), + Tables\Grouping\Group::make('holidayStatus.name') + ->label(__('Time Off Type')) + ->collapsible(), + Tables\Grouping\Group::make('allocation_type') + ->label(__('Allocation Type')) + ->collapsible(), + Tables\Grouping\Group::make('state') + ->label(__('Status')) + ->collapsible(), + Tables\Grouping\Group::make('date_from') + ->label(__('Start Date')) + ->collapsible(), + ]) + ->actions([ + Tables\Actions\ActionGroup::make([ + Tables\Actions\EditAction::make(), + Tables\Actions\DeleteAction::make(), + Tables\Actions\Action::make('approve') + ->icon('heroicon-o-check-circle') + ->color('success') + ->hidden(fn($record) => $record->state === State::VALIDATE_TWO->value) + ->action(function ($record) { + if ($record->state === State::VALIDATE_ONE->value) { + $record->update(['state' => State::VALIDATE_TWO->value]); + } else { + $record->update(['state' => State::VALIDATE_TWO->value]); + } + }) + ->label(function ($record) { + if ($record->state === State::VALIDATE_ONE->value) { + return 'Validate'; + } else { + return 'Approve'; + } + }), + Tables\Actions\Action::make('refuse') + ->icon('heroicon-o-x-circle') + ->hidden(fn($record) => $record->state === State::REFUSE->value) + ->color('danger') + ->action(function ($record) { + $record->update(['state' => State::REFUSE->value]); + }) + ->label('Refuse'), + ]), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]) + ->modifyQueryUsing(function ($query) { + $query->where('employee_id', Auth::user()->employee->id); + }); + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListMyAllocations::route('/'), + 'create' => Pages\CreateMyAllocation::route('/create'), + 'edit' => Pages\EditMyAllocation::route('/{record}/edit'), + ]; + } +} diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/CreateMyAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/CreateMyAllocation.php new file mode 100644 index 00000000..b685c59a --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/CreateMyAllocation.php @@ -0,0 +1,28 @@ +getResource()::getUrl('view', ['record' => $this->getRecord()]); + } + + protected function mutateFormDataBeforeCreate(array $data): array + { + $user = Auth::user(); + + if ($user?->employee) { + $data['employee_id'] = $user->employee->id; + } + + return $data; + } +} diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php new file mode 100644 index 00000000..e7734867 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php @@ -0,0 +1,36 @@ +getResource()::getUrl('view', ['record' => $this->getRecord()]); + } + + protected function getHeaderActions(): array + { + return [ + Actions\DeleteAction::make(), + ]; + } + + protected function mutateFormDataBeforeSave(array $data): array + { + $user = Auth::user(); + + if ($user?->employee) { + $data['employee_id'] = $user->employee->id; + } + + return $data; + } +} diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ListMyAllocations.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ListMyAllocations.php new file mode 100644 index 00000000..95b9eae2 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ListMyAllocations.php @@ -0,0 +1,19 @@ +schema([ + Forms\Components\Section::make() + ->schema([ + Forms\Components\Group::make() + ->schema([ + Forms\Components\Select::make('holiday_status_id') + ->relationship('holidayStatus', 'name') + ->searchable() + ->preload() + ->live() + ->required(), + Forms\Components\Fieldset::make() + ->label(function (Get $get) { + if ($get('request_unit_half')) { + return 'Date'; + } else { + return 'Dates'; + } + }) + ->live() + ->schema([ + Forms\Components\DatePicker::make('request_date_from') + ->native(false) + ->default(now()) + ->required(), + Forms\Components\DatePicker::make('request_date_to') + ->native(false) + ->default(now()) + ->hidden(fn(Get $get) => $get('request_unit_half')) + ->required(), + Forms\Components\Select::make('request_date_from_period') + ->label('Period') + ->options(RequestDateFromPeriod::class) + ->default(RequestDateFromPeriod::MORNING->value) + ->native(false) + ->visible(fn(Get $get) => $get('request_unit_half')) + ->required(), + ]), + Forms\Components\Toggle::make('request_unit_half') + ->live() + ->label('Half Day'), + Forms\Components\Placeholder::make('requested_days') + ->label('Requested (Days/Hours)') + ->live() + ->inlineLabel() + ->reactive() + ->content(function ($state, Get $get): string { + if ($get('request_unit_half')) { + return '0.5 day'; + } + + $startDate = Carbon::parse($get('request_date_from')); + $endDate = $get('request_date_to') ? Carbon::parse($get('request_date_to')) : $startDate; + + return $startDate->diffInDays($endDate) + 1 . ' day(s)'; + }), + Forms\Components\Textarea::make('private_name') + ->label('Description') + ->live(), + Forms\Components\FileUpload::make('attachment') + ->label('Attachment') + ->visible(function (Get $get) { + $leaveType = LeaveType::find($get('holiday_status_id')); + + if ($leaveType) { + return $leaveType->support_document; + } + + return false; + }) + ->live(), + ]), + ]), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('employee.name') + ->label(__('Employee Name')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('holidayStatus.name') + ->label(__('Time Off Type')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('private_name') + ->label(__('Description')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('date_from') + ->label(__('Date From')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('date_to') + ->label(__('Date To')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('duration_display') + ->label(__('Duration')) + ->sortable() + ->searchable(), + Tables\Columns\TextColumn::make('state') + ->label(__('Status')) + ->formatStateUsing(fn($state) => State::options()[$state]) + ->sortable() + ->badge() + ->searchable(), + ]) + ->groups([ + Tables\Grouping\Group::make('employee.name') + ->label(__('Employee Name')) + ->collapsible(), + Tables\Grouping\Group::make('holidayStatus.name') + ->label(__('Time Off Type')) + ->collapsible(), + Tables\Grouping\Group::make('state') + ->label(__('Status')) + ->collapsible(), + Tables\Grouping\Group::make('date_from') + ->label(__('Start Date')) + ->collapsible(), + Tables\Grouping\Group::make('date_to') + ->label(__('Start To')) + ->collapsible(), + ]) + ->actions([ + Tables\Actions\EditAction::make(), + Tables\Actions\DeleteAction::make(), + Tables\Actions\Action::make('approve') + ->icon('heroicon-o-check-circle') + ->color('success') + ->hidden(fn($record) => $record->state === State::VALIDATE_TWO->value) + ->action(function ($record) { + if ($record->state === State::VALIDATE_ONE->value) { + $record->update(['state' => State::VALIDATE_TWO->value]); + } else { + $record->update(['state' => State::VALIDATE_TWO->value]); + } + }) + ->label(function ($record) { + if ($record->state === State::VALIDATE_ONE->value) { + return 'Validate'; + } else { + return 'Approve'; + } + }), + Tables\Actions\Action::make('refuse') + ->icon('heroicon-o-x-circle') + ->hidden(fn($record) => $record->state === State::REFUSE->value) + ->color('danger') + ->action(function ($record) { + $record->update(['state' => State::REFUSE->value]); + }) + ->label('Refuse'), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]) + ->modifyQueryUsing(function ($query) { + $query->where('employee_id', auth()->user()->employee->id); + }); + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListMyTimeOffs::route('/'), + 'create' => Pages\CreateMyTimeOff::route('/create'), + 'edit' => Pages\EditMyTimeOff::route('/{record}/edit'), + ]; + } +} diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php new file mode 100644 index 00000000..0b74f578 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php @@ -0,0 +1,25 @@ +employee) { + $data['employee_id'] = $user->employee->id; + $data['department_id'] = $user->employee->department->id; + } + + return $data; + } +} diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php new file mode 100644 index 00000000..ee7a98a6 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php @@ -0,0 +1,32 @@ +employee) { + $data['employee_id'] = $user->employee->id; + $data['department_id'] = $user->employee->department->id; + } + + return $data; + } +} diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ListMyTimeOffs.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ListMyTimeOffs.php new file mode 100644 index 00000000..baa621c1 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ListMyTimeOffs.php @@ -0,0 +1,19 @@ +where('user_id', $user->id) + ->orWhere('employee_id', $user->employee->id) ->where('request_date_from', '>=', $fetchInfo['start']) ->where('request_date_to', '<=', $fetchInfo['end']) ->with('holidayStatus') ->get() ->map(function (Leave $leave) { return [ - 'id' => $leave->id, - 'title' => $leave->holidayStatus->name, - 'start' => $leave->request_date_from, - 'end' => $leave->request_date_to, - 'allDay' => true, + 'id' => $leave->id, + 'title' => $leave->holidayStatus->name, + 'start' => $leave->request_date_from, + 'end' => $leave->request_date_to, + 'allDay' => true, 'backgroundColor' => $leave->holidayStatus->color, - 'borderColor' => $leave->holidayStatus->color, - 'textColor' => '#ffffff', + 'borderColor' => $leave->holidayStatus->color, + 'textColor' => '#ffffff', ]; }) ->all(); From 6c7e96dc3c24a0dfdf69f60fd8eb2a17961473fb Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 15:43:05 +0530 Subject: [PATCH 04/24] Add navigation sorting and new overview/dashboard pages for time off management --- .../src/Filament/Clusters/Configurations.php | 2 +- .../Resources/AccrualPlanResource.php | 2 + .../Resources/ActivityTypeResource.php | 2 + .../Resources/LeaveTypeResource.php | 2 + .../Resources/MandatoryDayResource.php | 2 + .../Resources/PublicHolidayResource.php | 2 + .../src/Filament/Clusters/Management.php | 2 + .../Resources/AllocationResource.php | 2 + .../Management/Resources/TimeOffResource.php | 2 + .../TimeOffResource/Pages/ListTimeOffs.php | 3 - .../MyTime/Resources/MyAllocationResource.php | 5 +- .../Pages/ViewMyAllocation.php | 20 ++++ .../MyTime/Resources/MyTimeOffResource.php | 4 +- .../Pages/CreateMyTimeOff.php | 55 +++++++++- .../MyTimeOffResource/Pages/EditMyTimeOff.php | 54 ++++++++- .../MyTimeOffResource/Pages/ViewMyTimeOff.php | 20 ++++ .../src/Filament/Clusters/Overview.php | 25 +++++ .../time-off/src/Filament/Pages/Dashboard.php | 10 ++ .../time-off/src/Filament/Pages/Overview.php | 33 ++++++ .../src/Filament/Widgets/MyTimeOffWidget.php | 61 +++++++++++ .../Widgets/OverviewCalendarWidget.php | 103 ++++++++++++++++++ 21 files changed, 398 insertions(+), 13 deletions(-) create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/Overview.php create mode 100644 plugins/webkul/time-off/src/Filament/Pages/Overview.php create mode 100644 plugins/webkul/time-off/src/Filament/Widgets/MyTimeOffWidget.php create mode 100644 plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php index a3eb6696..080aa17c 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php @@ -8,7 +8,7 @@ class Configurations extends Cluster { protected static ?string $navigationIcon = 'heroicon-o-squares-2x2'; - protected static ?int $navigationSort = 2; + protected static ?int $navigationSort = 4; public static function getSlug(): string { diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php index 9e0e6fd9..7fd19cda 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php @@ -32,6 +32,8 @@ class AccrualPlanResource extends Resource protected static ?string $cluster = Configurations::class; + protected static ?int $navigationSort = 2; + public static function getSubNavigationPosition(): SubNavigationPosition { if (str_contains(Route::currentRouteName(), 'index')) { diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/ActivityTypeResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/ActivityTypeResource.php index 9ba9817e..8a362e29 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/ActivityTypeResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/ActivityTypeResource.php @@ -14,6 +14,8 @@ class ActivityTypeResource extends BaseActivityTypeResource protected static ?string $cluster = Configurations::class; + protected static ?int $navigationSort = 5; + public static function getModelLabel(): string { return __('Activity Type'); diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/LeaveTypeResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/LeaveTypeResource.php index 6ba149a2..5a98b134 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/LeaveTypeResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/LeaveTypeResource.php @@ -28,6 +28,8 @@ class LeaveTypeResource extends Resource protected static ?string $cluster = Configurations::class; + protected static ?int $navigationSort = 1; + public static function getModelLabel(): string { return __('time_off::filament/clusters/configurations/resources/leave-type.title'); diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php index 6e08e464..fa04d983 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php @@ -22,6 +22,8 @@ class MandatoryDayResource extends Resource protected static ?string $cluster = Configurations::class; + protected static ?int $navigationSort = 4; + public static function getModelLabel(): string { return __('time_off::filament/clusters/configurations/resources/mandatory-days.title'); diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php index 5a66a397..c4f7876f 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php @@ -21,6 +21,8 @@ class PublicHolidayResource extends Resource protected static ?string $cluster = Configurations::class; + protected static ?int $navigationSort = 3; + protected static ?string $modelLabel = 'Public Holiday'; public static function form(Form $form): Form diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management.php b/plugins/webkul/time-off/src/Filament/Clusters/Management.php index 8ca69aee..7256ce5e 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management.php @@ -8,6 +8,8 @@ class Management extends Cluster { protected static ?string $navigationIcon = 'heroicon-o-shield-check'; + protected static ?int $navigationSort = 3; + public static function getSlug(): string { return 'time-off/management'; diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php index c0196659..ff5439b3 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php @@ -22,6 +22,8 @@ class AllocationResource extends Resource protected static ?string $cluster = Management::class; + protected static ?int $navigationSort = 2; + public static function form(Form $form): Form { return $form diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php index b5baddee..a18833b9 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php @@ -26,6 +26,8 @@ class TimeOffResource extends Resource protected static ?string $cluster = Management::class; + protected static ?int $navigationSort = 1; + protected static ?string $modelLabel = 'Time Off'; public static function form(Form $form): Form diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ListTimeOffs.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ListTimeOffs.php index 94a27a27..6637f7ce 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ListTimeOffs.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ListTimeOffs.php @@ -5,9 +5,6 @@ use Filament\Actions; use Filament\Resources\Pages\ListRecords; use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; - - - use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\Auth; use Webkul\TableViews\Filament\Components\PresetView; diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php index 44915986..95960373 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php @@ -187,9 +187,10 @@ public static function table(Table $table): Table public static function getPages(): array { return [ - 'index' => Pages\ListMyAllocations::route('/'), + 'index' => Pages\ListMyAllocations::route('/'), 'create' => Pages\CreateMyAllocation::route('/create'), - 'edit' => Pages\EditMyAllocation::route('/{record}/edit'), + 'edit' => Pages\EditMyAllocation::route('/{record}/edit'), + 'view' => Pages\ViewMyAllocation::route('/{record}'), ]; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php new file mode 100644 index 00000000..de342fa2 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php @@ -0,0 +1,20 @@ +modifyQueryUsing(function ($query) { - $query->where('employee_id', auth()->user()->employee->id); + $query->where('employee_id', Auth::user()->employee->id); }); } @@ -203,6 +204,7 @@ public static function getPages(): array 'index' => Pages\ListMyTimeOffs::route('/'), 'create' => Pages\CreateMyTimeOff::route('/create'), 'edit' => Pages\EditMyTimeOff::route('/{record}/edit'), + 'view' => Pages\ViewMyTimeOff::route('/{record}'), ]; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php index 0b74f578..b4dde541 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php @@ -5,21 +5,70 @@ use Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyTimeOffResource; use Filament\Actions; use Filament\Resources\Pages\CreateRecord; +use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; +use Webkul\Employee\Models\Employee; +use Webkul\TimeOff\Enums\State; class CreateMyTimeOff extends CreateRecord { protected static string $resource = MyTimeOffResource::class; + protected function getRedirectUrl(): string + { + return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); + } + protected function mutateFormDataBeforeCreate(array $data): array { $user = Auth::user(); - if ($user?->employee) { - $data['employee_id'] = $user->employee->id; - $data['department_id'] = $user->employee->department->id; + $employee = $user->employee; + + if ($employee) { + $data['employee_id'] = $employee->id; + $data['department_id'] = $employee->department->id; + } + + + if (isset($data['employee_id'])) { + if ($employee->calendar) { + $data['calendar_id'] = $employee->calendar->id; + $data['number_of_hours'] = $employee->calendar->hours_per_day; + } + + $user = $employee?->user; + + if ($user) { + $data['user_id'] = $user->id; + + $data['company_id'] = $user->default_company_id; + + $data['employee_company_id'] = $user->default_company_id; + } + } + + + if (isset($data['request_unit_half'])) { + $data['duration_display'] = '0.5 day'; + + $data['number_of_days'] = 0.5; + } else { + $startDate = Carbon::parse($data['request_date_from']); + $endDate = $data['request_date_to'] ? Carbon::parse($data['request_date_to']) : $startDate; + + $data['duration_display'] = $startDate->diffInDays($endDate) + 1 . ' day(s)'; + + $data['number_of_days'] = $startDate->diffInDays($endDate) + 1; } + $data['creator_id'] = Auth::user()->id; + + $data['state'] = State::CONFIRM->value; + + $data['date_from'] = $data['request_date_from']; + $data['date_to'] = $data['request_date_to']; + return $data; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php index ee7a98a6..8354a01a 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php @@ -5,7 +5,9 @@ use Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyTimeOffResource; use Filament\Actions; use Filament\Resources\Pages\EditRecord; +use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; +use Webkul\TimeOff\Enums\State; class EditMyTimeOff extends EditRecord { @@ -18,15 +20,61 @@ protected function getHeaderActions(): array ]; } + protected function getRedirectUrl(): string + { + return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); + } + protected function mutateFormDataBeforeSave(array $data): array { $user = Auth::user(); - if ($user?->employee) { - $data['employee_id'] = $user->employee->id; - $data['department_id'] = $user->employee->department->id; + $employee = $user->employee; + + if ($employee) { + $data['employee_id'] = $employee->id; + $data['department_id'] = $employee->department->id; + } + + + if (isset($data['employee_id'])) { + if ($employee->calendar) { + $data['calendar_id'] = $employee->calendar->id; + $data['number_of_hours'] = $employee->calendar->hours_per_day; + } + + $user = $employee?->user; + + if ($user) { + $data['user_id'] = $user->id; + + $data['company_id'] = $user->default_company_id; + + $data['employee_company_id'] = $user->default_company_id; + } + } + + + if (isset($data['request_unit_half'])) { + $data['duration_display'] = '0.5 day'; + + $data['number_of_days'] = 0.5; + } else { + $startDate = Carbon::parse($data['request_date_from']); + $endDate = $data['request_date_to'] ? Carbon::parse($data['request_date_to']) : $startDate; + + $data['duration_display'] = $startDate->diffInDays($endDate) + 1 . ' day(s)'; + + $data['number_of_days'] = $startDate->diffInDays($endDate) + 1; } + $data['creator_id'] = Auth::user()->id; + + $data['state'] = State::CONFIRM->value; + + $data['date_from'] = $data['request_date_from']; + $data['date_to'] = $data['request_date_to']; + return $data; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php new file mode 100644 index 00000000..42b71048 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php @@ -0,0 +1,20 @@ +employee->id; + $endOfYear = Carbon::now()->endOfYear(); + + $leaveTypes = LeaveType::all(); + + $stats = []; + + foreach ($leaveTypes as $leaveType) { + $availableDays = $this->calculateAvailableDays($employeeId, $leaveType->id, $endOfYear); + + $stats[] = Stat::make(__($leaveType->name), $availableDays['days']) + ->description("Valid until {$endOfYear}") + ->color(Color::hex($leaveType->color)); + } + + $pendingRequests = $this->calculatePendingRequests($employeeId); + + $stats[] = Stat::make(__('Pending Requests'), $pendingRequests) + ->description('Time Off Requests') + ->color('danger'); + + return $stats; + } + + protected function calculateAvailableDays($employeeId, $leaveTypeId, $endDate) + { + $allocation = LeaveAllocation::where('employee_id', $employeeId) + ->where('holiday_status_id', $leaveTypeId) + ->where('date_to', '<=', $endDate) + ->latest('created_at') + ->first(); + + return [ + 'days' => $allocation ? $allocation->number_of_days : 0 + ]; + } + + protected function calculatePendingRequests($employeeId) + { + return Leave::where('employee_id', $employeeId) + ->where('state', 'confirm') + ->count(); + } +} diff --git a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php new file mode 100644 index 00000000..a703d279 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php @@ -0,0 +1,103 @@ +form(fn(Form $form) => TimeOffResource::form($form)) + ->mountUsing( + function (Forms\Form $form, array $arguments) { + $form->fill($arguments); + } + ), + ]; + } + + public function getFormSchema(): array + { + return [ + Forms\Components\Select::make('time_off_type') + ->label('Time Off Type') + ->relationship('holidayStatus', 'name') + ->searchable() + ->preload() + ->required(), + Forms\Components\Grid::make() + ->schema([ + Forms\Components\DatePicker::make('start_date') + ->label('Start Date') + ->required() + ->native(false) + ->closeOnDateSelection() + ->live(), + Forms\Components\DatePicker::make('end_date') + ->label('End Date') + ->required() + ->native(false) + ->closeOnDateSelection() + ->live(), + ]), + Forms\Components\Placeholder::make('requested_days') + ->label('Requested Days') + ->content(fn($state): string => $state), + Forms\Components\Textarea::make('reason') + ->label('Reason') + ->placeholder('Write the reason for your time off') + ->rows(3), + ]; + } + + public function fetchEvents(array $fetchInfo): array + { + return Leave::query() + ->where('request_date_from', '>=', $fetchInfo['start']) + ->where('request_date_to', '<=', $fetchInfo['end']) + ->with('holidayStatus') + ->get() + ->map(function (Leave $leave) { + return [ + 'id' => $leave->id, + 'title' => $leave->holidayStatus->name, + 'start' => $leave->request_date_from, + 'end' => $leave->request_date_to, + 'allDay' => true, + 'backgroundColor' => $leave->holidayStatus->color, + 'borderColor' => $leave->holidayStatus->color, + 'textColor' => '#ffffff', + ]; + }) + ->all(); + } + + public function onDateSelect(string $start, ?string $end, bool $allDay, ?array $view, ?array $resource): void + { + $startDate = Carbon::parse($start); + $endDate = $end ? Carbon::parse($end) : $startDate; + + $numberOfDays = $startDate->diffInDays($endDate) + 1; + + $this->mountAction('create', [ + 'start_date' => $startDate->toDateString(), + 'end_date' => $endDate->toDateString(), + 'requested_days' => $numberOfDays . ' Days', + ]); + } +} From 581504b62bbcf08b25f15d704c5fa50273e8c6fd Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 15:53:01 +0530 Subject: [PATCH 05/24] Update navigation sorting and add reporting cluster with employee resource pages --- .../src/Filament/Clusters/Configurations.php | 2 +- .../time-off/src/Filament/Clusters/MyTime.php | 2 + .../MyTime/Resources/MyAllocationResource.php | 2 + .../MyTime/Resources/MyTimeOffResource.php | 2 + .../src/Filament/Clusters/Overview.php | 2 + .../src/Filament/Clusters/Reporting.php | 27 ++++++++ .../Resources/ByEmployeeResource.php | 63 +++++++++++++++++++ .../Pages/CreateByEmployee.php | 12 ++++ .../Pages/EditByEmployee.php | 19 ++++++ .../Pages/ListByEmployees.php | 19 ++++++ .../time-off/src/Filament/Pages/Overview.php | 3 +- 11 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/Reporting.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/CreateByEmployee.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/EditByEmployee.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/ListByEmployees.php diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php index 080aa17c..6df13076 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php @@ -8,7 +8,7 @@ class Configurations extends Cluster { protected static ?string $navigationIcon = 'heroicon-o-squares-2x2'; - protected static ?int $navigationSort = 4; + protected static ?int $navigationSort = 5; public static function getSlug(): string { diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime.php index a64e71ce..703ef402 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime.php @@ -8,6 +8,8 @@ class MyTime extends Cluster { protected static ?string $navigationIcon = 'heroicon-o-clock'; + protected static ?int $navigationSort = 1; + public static function getSlug(): string { return 'time-off/dashboard'; diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php index 95960373..15c5bb5a 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php @@ -23,6 +23,8 @@ class MyAllocationResource extends Resource protected static ?string $cluster = MyTime::class; + protected static ?int $navigationSort = 3; + protected static ?string $modelLabel = 'My Allocation'; public static function form(Form $form): Form diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php index f1b52f5c..8d5b42e2 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php @@ -25,6 +25,8 @@ class MyTimeOffResource extends Resource protected static ?string $modelLabel = 'My Time Off'; + protected static ?int $navigationSort = 2; + protected static ?string $cluster = MyTime::class; public static function form(Form $form): Form diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Overview.php b/plugins/webkul/time-off/src/Filament/Clusters/Overview.php index 6e06d365..402a43a1 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Overview.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Overview.php @@ -8,6 +8,8 @@ class Overview extends Cluster { protected static ?string $navigationIcon = 'heroicon-o-view-columns'; + protected static ?int $navigationSort = 2; + public static function getSlug(): string { return 'time-off/overview'; diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Reporting.php b/plugins/webkul/time-off/src/Filament/Clusters/Reporting.php new file mode 100644 index 00000000..9fd10eab --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/Reporting.php @@ -0,0 +1,27 @@ +schema([ + // + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + // + ]) + ->filters([ + // + ]) + ->actions([ + Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListByEmployees::route('/'), + 'create' => Pages\CreateByEmployee::route('/create'), + 'edit' => Pages\EditByEmployee::route('/{record}/edit'), + ]; + } +} diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/CreateByEmployee.php b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/CreateByEmployee.php new file mode 100644 index 00000000..40dc4c6f --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/CreateByEmployee.php @@ -0,0 +1,12 @@ + Date: Fri, 24 Jan 2025 16:48:43 +0530 Subject: [PATCH 06/24] Enhance CalendarWidget with improved modal actions and form handling for time off requests --- .../src/Filament/Widgets/CalendarWidget.php | 239 ++++++++++++++--- .../Widgets/OverviewCalendarWidget.php | 245 +++++++++++++++--- 2 files changed, 423 insertions(+), 61 deletions(-) diff --git a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php index 521b04d7..30c353fd 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php @@ -3,24 +3,153 @@ namespace Webkul\TimeOff\Filament\Widgets; use Carbon\Carbon; +use Filament\Actions\Action; use Filament\Forms; -use Filament\Forms\Form; +use Filament\Forms\Get; +use Filament\Infolists; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Auth; use Saade\FilamentFullCalendar\Actions; use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget; -use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; +use Webkul\TimeOff\Enums\RequestDateFromPeriod; +use Webkul\TimeOff\Enums\State; use Webkul\TimeOff\Models\Leave; class CalendarWidget extends FullCalendarWidget { public Model|string|null $model = Leave::class; + protected function modalActions(): array + { + return [ + Actions\EditAction::make() + ->action(function ($data, $record) { + $user = Auth::user(); + $employee = $user->employee; + + if ($employee) { + $data['employee_id'] = $employee->id; + } + + if ($employee->department) { + $data['department_id'] = $employee->department->id; + } else { + $data['department_id'] = null; + } + + if ($employee->calendar) { + $data['calendar_id'] = $employee->calendar->id; + $data['number_of_hours'] = $employee->calendar->hours_per_day; + } + + if ($user) { + $data['user_id'] = $user->id; + + $data['company_id'] = $user->default_company_id; + + $data['employee_company_id'] = $user->default_company_id; + } + + if ($data['request_unit_half']) { + $data['duration_display'] = '0.5 day'; + + $data['number_of_days'] = 0.5; + } else { + $startDate = Carbon::parse($data['request_date_from']); + $endDate = $data['request_date_to'] ? Carbon::parse($data['request_date_to']) : $startDate; + + $data['duration_display'] = $startDate->diffInDays($endDate) + 1 . ' day(s)'; + + $data['number_of_days'] = $startDate->diffInDays($endDate) + 1; + } + + $data['creator_id'] = Auth::user()->id; + + $data['state'] = State::CONFIRM->value; + + $data['date_from'] = $data['request_date_from'] ?? null; + $data['date_to'] = $data['request_date_to'] ?? null; + + $record->update($data); + }) + ->mountUsing( + function (Forms\Form $form, array $arguments, $livewire, $data) { + $leave = $livewire->record; + + $newData = [ + ...$leave->toArray(), + 'request_date_from' => $arguments['event']['start'] ?? $leave->request_date_from, + 'request_date_to' => $arguments['event']['end'] ?? $leave->request_date_to, + ]; + + $form->fill($newData); + } + ), + Actions\DeleteAction::make(), + ]; + } + + protected function viewAction(): Action + { + return Actions\ViewAction::make() + ->modalIcon('heroicon-o-lifebuoy') + ->modalDescription('View Time Off Request') + ->infolist($this->infolist()); + } + protected function headerActions(): array { return [ Actions\CreateAction::make() - ->form(fn(Form $form) => TimeOffResource::form($form)) + ->action(function ($data) { + $user = Auth::user(); + $employee = $user->employee; + + if ($employee) { + $data['employee_id'] = $employee->id; + } + + if ($employee->department) { + $data['department_id'] = $employee->department->id; + } else { + $data['department_id'] = null; + } + + if ($employee->calendar) { + $data['calendar_id'] = $employee->calendar->id; + $data['number_of_hours'] = $employee->calendar->hours_per_day; + } + + if ($user) { + $data['user_id'] = $user->id; + + $data['company_id'] = $user->default_company_id; + + $data['employee_company_id'] = $user->default_company_id; + } + + if ($data['request_unit_half']) { + $data['duration_display'] = '0.5 day'; + + $data['number_of_days'] = 0.5; + } else { + $startDate = Carbon::parse($data['request_date_from']); + $endDate = $data['request_date_to'] ? Carbon::parse($data['request_date_to']) : $startDate; + + $data['duration_display'] = $startDate->diffInDays($endDate) + 1 . ' day(s)'; + + $data['number_of_days'] = $startDate->diffInDays($endDate) + 1; + } + + $data['creator_id'] = Auth::user()->id; + + $data['state'] = State::CONFIRM->value; + + $data['date_from'] = $data['request_date_from']; + $data['date_to'] = $data['request_date_to']; + + Leave::create($data); + }) ->mountUsing( function (Forms\Form $form, array $arguments) { $form->fill($arguments); @@ -32,34 +161,89 @@ function (Forms\Form $form, array $arguments) { public function getFormSchema(): array { return [ - Forms\Components\Select::make('time_off_type') + Forms\Components\Select::make('holiday_status_id') ->label('Time Off Type') ->relationship('holidayStatus', 'name') ->searchable() ->preload() ->required(), - Forms\Components\Grid::make() + Forms\Components\Fieldset::make() + ->label(function (Get $get) { + if ($get('request_unit_half')) { + return 'Date'; + } else { + return 'Dates'; + } + }) + ->live() ->schema([ - Forms\Components\DatePicker::make('start_date') - ->label('Start Date') - ->required() + Forms\Components\DatePicker::make('request_date_from') ->native(false) - ->closeOnDateSelection() - ->live(), - Forms\Components\DatePicker::make('end_date') - ->label('End Date') - ->required() + ->default(now()) + ->required(), + Forms\Components\DatePicker::make('request_date_to') ->native(false) - ->closeOnDateSelection() - ->live(), + ->default(now()) + ->hidden(fn(Get $get) => $get('request_unit_half')) + ->required(), + Forms\Components\Select::make('request_date_from_period') + ->label('Period') + ->options(RequestDateFromPeriod::class) + ->default(RequestDateFromPeriod::MORNING->value) + ->native(false) + ->visible(fn(Get $get) => $get('request_unit_half')) + ->required(), ]), + Forms\Components\Toggle::make('request_unit_half') + ->live() + ->label('Half Day'), Forms\Components\Placeholder::make('requested_days') - ->label('Requested Days') - ->content(fn($state): string => $state), - Forms\Components\Textarea::make('reason') - ->label('Reason') - ->placeholder('Write the reason for your time off') - ->rows(3), + ->label('Requested (Days/Hours)') + ->live() + ->inlineLabel() + ->reactive() + ->content(function ($state, Get $get): string { + if ($get('request_unit_half')) { + return '0.5 day'; + } + + $startDate = Carbon::parse($get('request_date_from')); + $endDate = $get('request_date_to') ? Carbon::parse($get('request_date_to')) : $startDate; + + return $startDate->diffInDays($endDate) . ' day(s)'; + }), + Forms\Components\Textarea::make('private_name') + ->label('Description'), + ]; + } + + public function infolist(): array + { + return [ + Infolists\Components\TextEntry::make('holidayStatus.name') + ->label('Time Off Type') + ->icon('heroicon-o-clock'), + Infolists\Components\TextEntry::make('request_date_from') + ->label('Start Date') + ->date() + ->icon('heroicon-o-calendar-days'), + Infolists\Components\TextEntry::make('request_date_to') + ->label('End Date') + ->date() + ->icon('heroicon-o-calendar-days'), + Infolists\Components\TextEntry::make('number_of_days') + ->label('Duration') + ->formatStateUsing(fn($state) => $state . ' day(s)') + ->icon('heroicon-o-clock'), + Infolists\Components\TextEntry::make('private_name') + ->label('Description') + ->icon('heroicon-o-document-text') + ->placeholder('No description provided'), + Infolists\Components\TextEntry::make('state') + ->label('Status') + ->badge() + ->formatStateUsing(fn($state) => State::options()[$state]) + ->icon('heroicon-o-check-circle') ]; } @@ -77,12 +261,12 @@ public function fetchEvents(array $fetchInfo): array ->map(function (Leave $leave) { return [ 'id' => $leave->id, - 'title' => $leave->holidayStatus->name, + 'title' => $leave->holidayStatus?->name, 'start' => $leave->request_date_from, 'end' => $leave->request_date_to, 'allDay' => true, - 'backgroundColor' => $leave->holidayStatus->color, - 'borderColor' => $leave->holidayStatus->color, + 'backgroundColor' => $leave->holidayStatus?->color, + 'borderColor' => $leave->holidayStatus?->color, 'textColor' => '#ffffff', ]; }) @@ -94,12 +278,9 @@ public function onDateSelect(string $start, ?string $end, bool $allDay, ?array $ $startDate = Carbon::parse($start); $endDate = $end ? Carbon::parse($end) : $startDate; - $numberOfDays = $startDate->diffInDays($endDate) + 1; - $this->mountAction('create', [ - 'start_date' => $startDate->toDateString(), - 'end_date' => $endDate->toDateString(), - 'requested_days' => $numberOfDays . ' Days', + 'request_date_from' => $startDate->toDateString(), + 'request_date_to' => $endDate->toDateString(), ]); } } diff --git a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php index a703d279..67e36d2f 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php @@ -4,25 +4,152 @@ use Carbon\Carbon; use Filament\Forms; -use Filament\Forms\Form; use Illuminate\Database\Eloquent\Model; use Saade\FilamentFullCalendar\Actions; use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget; -use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; use Webkul\TimeOff\Models\Leave; -use Webkul\TableViews\Filament\Concerns\HasTableViews; +use Filament\Actions\Action; +use Filament\Forms\Get; +use Filament\Infolists; +use Illuminate\Support\Facades\Auth; +use Webkul\TimeOff\Enums\RequestDateFromPeriod; +use Webkul\TimeOff\Enums\State; class OverviewCalendarWidget extends FullCalendarWidget { - use HasTableViews; - public Model|string|null $model = Leave::class; + protected function modalActions(): array + { + return [ + Actions\EditAction::make() + ->action(function ($data, $record) { + $user = Auth::user(); + $employee = $user->employee; + + if ($employee) { + $data['employee_id'] = $employee->id; + } + + if ($employee->department) { + $data['department_id'] = $employee->department->id; + } else { + $data['department_id'] = null; + } + + if ($employee->calendar) { + $data['calendar_id'] = $employee->calendar->id; + $data['number_of_hours'] = $employee->calendar->hours_per_day; + } + + if ($user) { + $data['user_id'] = $user->id; + + $data['company_id'] = $user->default_company_id; + + $data['employee_company_id'] = $user->default_company_id; + } + + if ($data['request_unit_half']) { + $data['duration_display'] = '0.5 day'; + + $data['number_of_days'] = 0.5; + } else { + $startDate = Carbon::parse($data['request_date_from']); + $endDate = $data['request_date_to'] ? Carbon::parse($data['request_date_to']) : $startDate; + + $data['duration_display'] = $startDate->diffInDays($endDate) + 1 . ' day(s)'; + + $data['number_of_days'] = $startDate->diffInDays($endDate) + 1; + } + + $data['creator_id'] = Auth::user()->id; + + $data['state'] = State::CONFIRM->value; + + $data['date_from'] = $data['request_date_from'] ?? null; + $data['date_to'] = $data['request_date_to'] ?? null; + + $record->update($data); + }) + ->mountUsing( + function (Forms\Form $form, array $arguments, $livewire, $data) { + $leave = $livewire->record; + + $newData = [ + ...$leave->toArray(), + 'request_date_from' => $arguments['event']['start'] ?? $leave->request_date_from, + 'request_date_to' => $arguments['event']['end'] ?? $leave->request_date_to, + ]; + + $form->fill($newData); + } + ), + Actions\DeleteAction::make(), + ]; + } + + protected function viewAction(): Action + { + return Actions\ViewAction::make() + ->modalIcon('heroicon-o-lifebuoy') + ->modalDescription('View Time Off Request') + ->infolist($this->infolist()); + } + protected function headerActions(): array { return [ Actions\CreateAction::make() - ->form(fn(Form $form) => TimeOffResource::form($form)) + ->action(function ($data) { + $user = Auth::user(); + $employee = $user->employee; + + if ($employee) { + $data['employee_id'] = $employee->id; + } + + if ($employee->department) { + $data['department_id'] = $employee->department->id; + } else { + $data['department_id'] = null; + } + + if ($employee->calendar) { + $data['calendar_id'] = $employee->calendar->id; + $data['number_of_hours'] = $employee->calendar->hours_per_day; + } + + if ($user) { + $data['user_id'] = $user->id; + + $data['company_id'] = $user->default_company_id; + + $data['employee_company_id'] = $user->default_company_id; + } + + if ($data['request_unit_half']) { + $data['duration_display'] = '0.5 day'; + + $data['number_of_days'] = 0.5; + } else { + $startDate = Carbon::parse($data['request_date_from']); + $endDate = $data['request_date_to'] ? Carbon::parse($data['request_date_to']) : $startDate; + + $data['duration_display'] = $startDate->diffInDays($endDate) + 1 . ' day(s)'; + + $data['number_of_days'] = $startDate->diffInDays($endDate) + 1; + } + + $data['creator_id'] = Auth::user()->id; + + $data['state'] = State::CONFIRM->value; + + $data['date_from'] = $data['request_date_from']; + $data['date_to'] = $data['request_date_to']; + + Leave::create($data); + }) ->mountUsing( function (Forms\Form $form, array $arguments) { $form->fill($arguments); @@ -34,39 +161,96 @@ function (Forms\Form $form, array $arguments) { public function getFormSchema(): array { return [ - Forms\Components\Select::make('time_off_type') + Forms\Components\Select::make('holiday_status_id') ->label('Time Off Type') ->relationship('holidayStatus', 'name') ->searchable() ->preload() ->required(), - Forms\Components\Grid::make() + Forms\Components\Fieldset::make() + ->label(function (Get $get) { + if ($get('request_unit_half')) { + return 'Date'; + } else { + return 'Dates'; + } + }) + ->live() ->schema([ - Forms\Components\DatePicker::make('start_date') - ->label('Start Date') - ->required() + Forms\Components\DatePicker::make('request_date_from') ->native(false) - ->closeOnDateSelection() - ->live(), - Forms\Components\DatePicker::make('end_date') - ->label('End Date') - ->required() + ->default(now()) + ->required(), + Forms\Components\DatePicker::make('request_date_to') ->native(false) - ->closeOnDateSelection() - ->live(), + ->default(now()) + ->hidden(fn(Get $get) => $get('request_unit_half')) + ->required(), + Forms\Components\Select::make('request_date_from_period') + ->label('Period') + ->options(RequestDateFromPeriod::class) + ->default(RequestDateFromPeriod::MORNING->value) + ->native(false) + ->visible(fn(Get $get) => $get('request_unit_half')) + ->required(), ]), + Forms\Components\Toggle::make('request_unit_half') + ->live() + ->label('Half Day'), Forms\Components\Placeholder::make('requested_days') - ->label('Requested Days') - ->content(fn($state): string => $state), - Forms\Components\Textarea::make('reason') - ->label('Reason') - ->placeholder('Write the reason for your time off') - ->rows(3), + ->label('Requested (Days/Hours)') + ->live() + ->inlineLabel() + ->reactive() + ->content(function ($state, Get $get): string { + if ($get('request_unit_half')) { + return '0.5 day'; + } + + $startDate = Carbon::parse($get('request_date_from')); + $endDate = $get('request_date_to') ? Carbon::parse($get('request_date_to')) : $startDate; + + return $startDate->diffInDays($endDate) . ' day(s)'; + }), + Forms\Components\Textarea::make('private_name') + ->label('Description'), + ]; + } + + public function infolist(): array + { + return [ + Infolists\Components\TextEntry::make('holidayStatus.name') + ->label('Time Off Type') + ->icon('heroicon-o-clock'), + Infolists\Components\TextEntry::make('request_date_from') + ->label('Start Date') + ->date() + ->icon('heroicon-o-calendar-days'), + Infolists\Components\TextEntry::make('request_date_to') + ->label('End Date') + ->date() + ->icon('heroicon-o-calendar-days'), + Infolists\Components\TextEntry::make('number_of_days') + ->label('Duration') + ->formatStateUsing(fn($state) => $state . ' day(s)') + ->icon('heroicon-o-clock'), + Infolists\Components\TextEntry::make('private_name') + ->label('Description') + ->icon('heroicon-o-document-text') + ->placeholder('No description provided'), + Infolists\Components\TextEntry::make('state') + ->label('Status') + ->badge() + ->formatStateUsing(fn($state) => State::options()[$state]) + ->icon('heroicon-o-check-circle') ]; } public function fetchEvents(array $fetchInfo): array { + $user = Auth::user(); + return Leave::query() ->where('request_date_from', '>=', $fetchInfo['start']) ->where('request_date_to', '<=', $fetchInfo['end']) @@ -75,12 +259,12 @@ public function fetchEvents(array $fetchInfo): array ->map(function (Leave $leave) { return [ 'id' => $leave->id, - 'title' => $leave->holidayStatus->name, + 'title' => $leave->holidayStatus?->name, 'start' => $leave->request_date_from, 'end' => $leave->request_date_to, 'allDay' => true, - 'backgroundColor' => $leave->holidayStatus->color, - 'borderColor' => $leave->holidayStatus->color, + 'backgroundColor' => $leave->holidayStatus?->color, + 'borderColor' => $leave->holidayStatus?->color, 'textColor' => '#ffffff', ]; }) @@ -92,12 +276,9 @@ public function onDateSelect(string $start, ?string $end, bool $allDay, ?array $ $startDate = Carbon::parse($start); $endDate = $end ? Carbon::parse($end) : $startDate; - $numberOfDays = $startDate->diffInDays($endDate) + 1; - $this->mountAction('create', [ - 'start_date' => $startDate->toDateString(), - 'end_date' => $endDate->toDateString(), - 'requested_days' => $numberOfDays . ' Days', + 'request_date_from' => $startDate->toDateString(), + 'request_date_to' => $endDate->toDateString(), ]); } } From d44bdb83337074161470eaa89827e031f3d54cd0 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 17:03:31 +0530 Subject: [PATCH 07/24] Refactor ByEmployeeResource to utilize TimeOffResource for form and table definitions; update ListByEmployees to extend ListTimeOffs; streamline modal actions in CalendarWidget and OverviewCalendarWidget. --- .../Resources/ByEmployeeResource.php | 33 ++++--------------- .../Pages/ListByEmployees.php | 10 ++---- .../src/Filament/Widgets/CalendarWidget.php | 2 +- .../Widgets/OverviewCalendarWidget.php | 2 +- 4 files changed, 10 insertions(+), 37 deletions(-) diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php index b7ae1429..f241572d 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php @@ -6,8 +6,8 @@ use Webkul\TimeOff\Filament\Clusters\Reporting\Resources\ByEmployeeResource\Pages; use Filament\Forms\Form; use Filament\Resources\Resource; -use Filament\Tables; use Filament\Tables\Table; +use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; use Webkul\TimeOff\Models\Leave; class ByEmployeeResource extends Resource @@ -18,38 +18,17 @@ class ByEmployeeResource extends Resource protected static ?string $cluster = Reporting::class; + protected static ?string $modelLabel = 'By Employee'; + public static function form(Form $form): Form { - return $form - ->schema([ - // - ]); + return TimeOffResource::form($form); } public static function table(Table $table): Table { - return $table - ->columns([ - // - ]) - ->filters([ - // - ]) - ->actions([ - Tables\Actions\EditAction::make(), - ]) - ->bulkActions([ - Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DeleteBulkAction::make(), - ]), - ]); - } - - public static function getRelations(): array - { - return [ - // - ]; + return TimeOffResource::table($table) + ->defaultGroup('employee.name'); } public static function getPages(): array diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/ListByEmployees.php b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/ListByEmployees.php index 25a01d66..f10ef771 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/ListByEmployees.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/ListByEmployees.php @@ -5,15 +5,9 @@ use Webkul\TimeOff\Filament\Clusters\Reporting\Resources\ByEmployeeResource; use Filament\Actions; use Filament\Resources\Pages\ListRecords; +use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource\Pages\ListTimeOffs; -class ListByEmployees extends ListRecords +class ListByEmployees extends ListTimeOffs { protected static string $resource = ByEmployeeResource::class; - - protected function getHeaderActions(): array - { - return [ - Actions\CreateAction::make(), - ]; - } } diff --git a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php index 30c353fd..72028e1f 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php @@ -73,7 +73,7 @@ protected function modalActions(): array $record->update($data); }) ->mountUsing( - function (Forms\Form $form, array $arguments, $livewire, $data) { + function (Forms\Form $form, array $arguments, $livewire) { $leave = $livewire->record; $newData = [ diff --git a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php index 67e36d2f..a52ad0ef 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php @@ -73,7 +73,7 @@ protected function modalActions(): array $record->update($data); }) ->mountUsing( - function (Forms\Form $form, array $arguments, $livewire, $data) { + function (Forms\Form $form, array $arguments, $livewire) { $leave = $livewire->record; $newData = [ From ec6e8963e6841766ba8983cad3ccef435c518ece Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 17:29:24 +0530 Subject: [PATCH 08/24] Add ByType page and LeaveTypeWidget for time off analysis; update navigation icons in ByEmployeeResource and Overview --- .../Resources/ByEmployeeResource.php | 2 +- .../time-off/src/Filament/Pages/ByType.php | 30 +++++++ .../time-off/src/Filament/Pages/Overview.php | 1 + .../src/Filament/Widgets/LeaveTypeWidget.php | 88 +++++++++++++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 plugins/webkul/time-off/src/Filament/Pages/ByType.php create mode 100644 plugins/webkul/time-off/src/Filament/Widgets/LeaveTypeWidget.php diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php index f241572d..3f691c3f 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php @@ -14,7 +14,7 @@ class ByEmployeeResource extends Resource { protected static ?string $model = Leave::class; - protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; + protected static ?string $navigationIcon = 'heroicon-o-users'; protected static ?string $cluster = Reporting::class; diff --git a/plugins/webkul/time-off/src/Filament/Pages/ByType.php b/plugins/webkul/time-off/src/Filament/Pages/ByType.php new file mode 100644 index 00000000..e9378014 --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Pages/ByType.php @@ -0,0 +1,30 @@ +filters['selectedCompanies'] ?? null) { + $query->whereIn('company_id', $this->filters['selectedCompanies']); + } + + if ($this->filters['selectedDepartments'] ?? null) { + $query->whereIn('department_id', $this->filters['selectedDepartments']); + } + + if ($this->filters['startDate'] ?? null) { + $query->where('request_date_from', '>=', Carbon::parse($this->filters['startDate'])->startOfDay()); + } + + if ($this->filters['endDate'] ?? null) { + $query->where('request_date_to', '<=', Carbon::parse($this->filters['endDate'])->endOfDay()); + } + + $stats = $query->selectRaw(' + COUNT(*) as total, + SUM(CASE WHEN state = "draft" THEN 1 ELSE 0 END) as draft, + SUM(CASE WHEN state = "confirm" THEN 1 ELSE 0 END) as confirmed, + SUM(CASE WHEN state = "validate" THEN 1 ELSE 0 END) as validated, + SUM(CASE WHEN state = "refuse" THEN 1 ELSE 0 END) as refused, + SUM(CASE WHEN state = "cancel" THEN 1 ELSE 0 END) as cancelled + ')->first(); + + $data = match ($this->filters['status'] ?? 'all') { + 'draft' => ['Draft' => $stats->draft ?? 0], + 'confirmed' => ['Confirmed' => $stats->confirmed ?? 0], + 'validated' => ['Validated' => $stats->validated ?? 0], + 'refused' => ['Refused' => $stats->refused ?? 0], + 'cancelled' => ['Cancelled' => $stats->cancelled ?? 0], + default => [ + 'Draft' => $stats->draft ?? 0, + 'Confirmed' => $stats->confirmed ?? 0, + 'Validated' => $stats->validated ?? 0, + 'Refused' => $stats->refused ?? 0, + 'Cancelled' => $stats->cancelled ?? 0, + ], + }; + + return [ + 'datasets' => [ + [ + 'label' => __('time_off::filament/widgets/leave.overview.label'), + 'data' => array_values($data), + 'backgroundColor' => array_map(fn($key) => match ($key) { + 'Draft' => '#94a3b8', + 'Confirmed' => '#3b82f6', + 'Validated' => '#22c55e', + 'Refused' => '#ef4444', + 'Cancelled' => '#f97316', + }, array_keys($data)), + ], + ], + 'labels' => array_keys($data), + ]; + } + + protected function getType(): string + { + return 'bar'; + } +} From 2bce68b25ca8fb2606d0eb1062e6874669462ec6 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 18:36:56 +0530 Subject: [PATCH 09/24] Add language files and update navigation labels for time off management pages and widgets --- .../lang/en/filament/pages/by-type.php | 7 + .../lang/en/filament/pages/dashboard.php | 7 + .../lang/en/filament/pages/overview.php | 8 + .../en/filament/widgets/calendar-widget.php | 48 ++++ .../en/filament/widgets/leave-type-widget.php | 17 ++ .../filament/widgets/my-time-off-widget.php | 8 + .../widgets/overview-calendar-widget.php | 48 ++++ .../lang/en/traits/leave-accrual-plan.php | 126 +++++++++ .../time-off/src/Filament/Pages/ByType.php | 2 +- .../time-off/src/Filament/Pages/Dashboard.php | 2 +- .../time-off/src/Filament/Pages/Overview.php | 4 +- .../src/Filament/Widgets/CalendarWidget.php | 37 ++- .../src/Filament/Widgets/LeaveTypeWidget.php | 24 +- .../src/Filament/Widgets/MyTimeOffWidget.php | 4 +- .../Widgets/OverviewCalendarWidget.php | 37 ++- .../time-off/src/Traits/LeaveAccrualPlan.php | 260 ++++++++++++++---- 16 files changed, 533 insertions(+), 106 deletions(-) create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/pages/by-type.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/pages/dashboard.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/pages/overview.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/widgets/leave-type-widget.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/widgets/my-time-off-widget.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/widgets/overview-calendar-widget.php create mode 100644 plugins/webkul/time-off/resources/lang/en/traits/leave-accrual-plan.php diff --git a/plugins/webkul/time-off/resources/lang/en/filament/pages/by-type.php b/plugins/webkul/time-off/resources/lang/en/filament/pages/by-type.php new file mode 100644 index 00000000..b2a668c8 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/pages/by-type.php @@ -0,0 +1,7 @@ + [ + 'title' => 'By Type', + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/pages/dashboard.php b/plugins/webkul/time-off/resources/lang/en/filament/pages/dashboard.php new file mode 100644 index 00000000..df4c22cf --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/pages/dashboard.php @@ -0,0 +1,7 @@ + [ + 'title' => 'Dashboard', + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/pages/overview.php b/plugins/webkul/time-off/resources/lang/en/filament/pages/overview.php new file mode 100644 index 00000000..aebff635 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/pages/overview.php @@ -0,0 +1,8 @@ + [ + 'title' => 'Overview', + 'group' => 'Time Off', + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php b/plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php new file mode 100644 index 00000000..3a0b2528 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php @@ -0,0 +1,48 @@ + [ + 'edit' => [ + 'title' => 'Edit', + ], + + 'delete' => [ + 'title' => 'Delete', + ] + ], + + 'view-action' => [ + 'title' => 'View', + 'description' => 'View Time Off Request', + ], + + 'header-actions' => [ + 'create' => [ + 'title' => 'New Time Off', + 'description' => 'Create Time Off Request', + ] + ], + + 'form' => [ + 'fields' => [ + 'time-off-type' => 'Time Off Type', + 'request-date-from' => 'Request Date From', + 'request-date-to' => 'Request Date To', + 'period' => 'Period', + 'half-day' => 'Half Day', + 'requested-days' => 'Requested (Days/Hours)', + 'description' => 'Description', + ] + ], + 'infolist' => [ + 'entries' => [ + 'time-off-type' => 'Time Off Type', + 'request-date-from' => 'Request Date From', + 'request-date-to' => 'Request Date To', + 'description' => 'Description', + 'description-placeholder' => 'No description provided', + 'duration' => 'Duration', + 'status' => 'Status', + ] + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/widgets/leave-type-widget.php b/plugins/webkul/time-off/resources/lang/en/filament/widgets/leave-type-widget.php new file mode 100644 index 00000000..5ee0e41b --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/widgets/leave-type-widget.php @@ -0,0 +1,17 @@ + [ + 'title' => 'Time Off Analysis', + ], + + 'label' => 'Overview', + + 'types' => [ + 'draft' => 'Draft', + 'confirmed' => 'Confirmed', + 'validated' => 'Validated', + 'refused' => 'Refused', + 'cancelled' => 'Cancelled', + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/widgets/my-time-off-widget.php b/plugins/webkul/time-off/resources/lang/en/filament/widgets/my-time-off-widget.php new file mode 100644 index 00000000..a230745b --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/widgets/my-time-off-widget.php @@ -0,0 +1,8 @@ + [ + 'valid-until' => 'Valid until :date', + 'time-off-requests' => 'Time Off Requests', + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/widgets/overview-calendar-widget.php b/plugins/webkul/time-off/resources/lang/en/filament/widgets/overview-calendar-widget.php new file mode 100644 index 00000000..3a0b2528 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/widgets/overview-calendar-widget.php @@ -0,0 +1,48 @@ + [ + 'edit' => [ + 'title' => 'Edit', + ], + + 'delete' => [ + 'title' => 'Delete', + ] + ], + + 'view-action' => [ + 'title' => 'View', + 'description' => 'View Time Off Request', + ], + + 'header-actions' => [ + 'create' => [ + 'title' => 'New Time Off', + 'description' => 'Create Time Off Request', + ] + ], + + 'form' => [ + 'fields' => [ + 'time-off-type' => 'Time Off Type', + 'request-date-from' => 'Request Date From', + 'request-date-to' => 'Request Date To', + 'period' => 'Period', + 'half-day' => 'Half Day', + 'requested-days' => 'Requested (Days/Hours)', + 'description' => 'Description', + ] + ], + 'infolist' => [ + 'entries' => [ + 'time-off-type' => 'Time Off Type', + 'request-date-from' => 'Request Date From', + 'request-date-to' => 'Request Date To', + 'description' => 'Description', + 'description-placeholder' => 'No description provided', + 'duration' => 'Duration', + 'status' => 'Status', + ] + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/traits/leave-accrual-plan.php b/plugins/webkul/time-off/resources/lang/en/traits/leave-accrual-plan.php new file mode 100644 index 00000000..1899a055 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/traits/leave-accrual-plan.php @@ -0,0 +1,126 @@ + [ + 'fields' => [ + 'accrual-amount' => 'Accrual Amount', + 'accrual-value-type' => 'Accrual Value Type', + 'accrual-frequency' => 'Accrual Frequency', + 'accrual-day' => 'Accrual Day', + 'day-of-month' => 'Day of Month', + 'first-day-of-month' => 'First Day of Month', + 'second-day-of-month' => 'Second Day of Month', + 'first-period-month' => 'First Period Month', + 'first-period-day' => 'First Period Day', + 'second-period-month' => 'Second Period Month', + 'second-period-day' => 'Second Period Day', + 'first-period-year' => 'First Period Year', + 'cap-accrued-time' => 'Cap accrued time', + 'days' => 'Days', + 'start-count' => 'Start Count', + 'start-type' => 'Start Type', + 'action-with-unused-accruals' => 'Action with Unused Accruals', + 'milestone-cap' => 'Milestone Cap', + 'maximum-leave-yearly' => 'Maximum Leave Yearly', + 'accrual-validity' => 'Accrual Validity', + 'accrual-validity-count' => 'Accrual Validity Count', + 'accrual-validity-type' => 'Accrual Validity Type', + 'advanced-accrual-settings' => 'Advanced Accrual Settings', + 'after-allocation-start' => 'After Allocation Start Date', + ] + ], + + 'table' => [ + 'columns' => [ + 'accrual-amount' => 'Accrual Amount', + 'accrual-value-type' => 'Accrual Value Type', + 'frequency' => 'Frequency', + 'maximum-leave-days' => 'Maximum Leave Days', + ], + + 'groups' => [ + 'accrual-amount' => 'Accrual Amount', + 'accrual-value-type' => 'Accrual Value Type', + 'frequency' => 'Frequency', + 'maximum-leave-days' => 'Maximum Leave Days', + ], + + 'filters' => [ + 'accrual-frequency' => 'Accrual Frequency', + 'start-type' => 'Start Type', + 'cap-accrued-time' => 'Cap Accrued Time', + 'action-with-unused-accruals' => 'Action With Unused Accruals', + 'accrual-amount' => 'Accrual Amount', + 'accrual-frequency' => 'Accrual Frequency', + 'start-type' => 'Start Type', + 'created-at' => 'Created At', + 'updated-at' => 'Updated At', + ], + + 'header-actions' => [ + 'created' => [ + 'title' => 'New Leave Accrual Plan', + + 'notification' => [ + 'title' => 'Leave accrual plan created', + 'body' => 'The leave accrual plan has been created successfully.', + ], + ], + ], + + 'actions' => [ + 'edit' => [ + 'notification' => [ + 'title' => 'Leave accrual plan updated', + 'body' => 'The leave accrual plan has been updated successfully.', + ], + ], + + 'delete' => [ + 'notification' => [ + 'title' => 'Leave accrual plan deleted', + 'body' => 'The leave accrual plan has been deleted successfully.', + ], + ], + ], + + 'bulk-actions' => [ + + 'delete' => [ + 'notification' => [ + 'title' => 'Leave accrual plans deleted', + 'body' => 'The leave accrual plans has been deleted successfully.', + ], + ], + ], + ], + + 'infolist' => [ + 'entries' => [ + 'accrual-amount' => 'Accrual Amount', + 'accrual-value-type' => 'Accrual Value Type', + 'accrual-frequency' => 'Accrual Frequency', + 'accrual-day' => 'Accrual Day', + 'day-of-month' => 'Day of Month', + 'first-day-of-month' => 'First Day of Month', + 'second-day-of-month' => 'Second Day of Month', + 'first-period-month' => 'First Period Month', + 'first-period-day' => 'First Period Day', + 'second-period-month' => 'Second Period Month', + 'second-period-day' => 'Second Period Day', + 'first-period-year' => 'First Period Year', + 'cap-accrued-time' => 'Cap accrued time', + 'days' => 'Days', + 'start-count' => 'Start Count', + 'start-type' => 'Start Type', + 'action-with-unused-accruals' => 'Action with Unused Accruals', + 'milestone-cap' => 'Milestone Cap', + 'maximum-leave-yearly' => 'Maximum Leave Yearly', + 'accrual-validity' => 'Accrual Validity', + 'accrual-validity-count' => 'Accrual Validity Count', + 'accrual-validity-type' => 'Accrual Validity Type', + 'advanced-accrual-settings' => 'Advanced Accrual Settings', + 'after-allocation-start' => 'After Allocation Start Date', + ] + ], +]; diff --git a/plugins/webkul/time-off/src/Filament/Pages/ByType.php b/plugins/webkul/time-off/src/Filament/Pages/ByType.php index e9378014..2e7cc27d 100644 --- a/plugins/webkul/time-off/src/Filament/Pages/ByType.php +++ b/plugins/webkul/time-off/src/Filament/Pages/ByType.php @@ -18,7 +18,7 @@ class ByType extends BaseDashboard public static function getNavigationLabel(): string { - return __('By Type'); + return __('time_off::filament/pages/by-type.navigation.title'); } public function getWidgets(): array diff --git a/plugins/webkul/time-off/src/Filament/Pages/Dashboard.php b/plugins/webkul/time-off/src/Filament/Pages/Dashboard.php index 9e55d657..15058b5d 100644 --- a/plugins/webkul/time-off/src/Filament/Pages/Dashboard.php +++ b/plugins/webkul/time-off/src/Filament/Pages/Dashboard.php @@ -19,7 +19,7 @@ class Dashboard extends BaseDashboard public static function getNavigationLabel(): string { - return __('Dashboard'); + return __('time_off::filament/pages/dashboard.navigation.title'); } public function getWidgets(): array diff --git a/plugins/webkul/time-off/src/Filament/Pages/Overview.php b/plugins/webkul/time-off/src/Filament/Pages/Overview.php index 105a544d..0e1a605a 100644 --- a/plugins/webkul/time-off/src/Filament/Pages/Overview.php +++ b/plugins/webkul/time-off/src/Filament/Pages/Overview.php @@ -16,12 +16,12 @@ class Overview extends BaseDashboard public static function getNavigationLabel(): string { - return __('Overview'); + return __('time_off::filament/pages/overview.navigation.title'); } public static function getNavigationGroup(): ?string { - return __('Time Off'); + return __('time_off::filament/pages/overview.navigation.group'); } public function getWidgets(): array diff --git a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php index 72028e1f..eb775fec 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php @@ -23,6 +23,7 @@ protected function modalActions(): array { return [ Actions\EditAction::make() + ->label(__('time_off::filament/widgets/calendar-widget.modal-actions.edit.title')) ->action(function ($data, $record) { $user = Auth::user(); $employee = $user->employee; @@ -85,7 +86,8 @@ function (Forms\Form $form, array $arguments, $livewire) { $form->fill($newData); } ), - Actions\DeleteAction::make(), + Actions\DeleteAction::make() + ->label(__('time_off::filament/widgets/calendar-widget.modal-actions.delete.title')), ]; } @@ -93,7 +95,8 @@ protected function viewAction(): Action { return Actions\ViewAction::make() ->modalIcon('heroicon-o-lifebuoy') - ->modalDescription('View Time Off Request') + ->label(__('time_off::filament/widgets/calendar-widget.view-action.title')) + ->modalDescription(__('time_off::filament/widgets/calendar-widget.view-action.description')) ->infolist($this->infolist()); } @@ -101,6 +104,10 @@ protected function headerActions(): array { return [ Actions\CreateAction::make() + ->icon('heroicon-o-plus-circle') + ->modalIcon('heroicon-o-lifebuoy') + ->label(__('time_off::filament/widgets/calendar-widget.header-actions.create.title')) + ->modalDescription(__('time_off::filament/widgets/calendar-widget.header-actions.create.description')) ->action(function ($data) { $user = Auth::user(); $employee = $user->employee; @@ -162,7 +169,7 @@ public function getFormSchema(): array { return [ Forms\Components\Select::make('holiday_status_id') - ->label('Time Off Type') + ->label(__('time_off::filament/widgets/calendar-widget.form.fields.time-off-type')) ->relationship('holidayStatus', 'name') ->searchable() ->preload() @@ -179,15 +186,17 @@ public function getFormSchema(): array ->schema([ Forms\Components\DatePicker::make('request_date_from') ->native(false) + ->label(__('time_off::filament/widgets/calendar-widget.form.fields.request-date-from')) ->default(now()) ->required(), Forms\Components\DatePicker::make('request_date_to') ->native(false) + ->label(__('time_off::filament/widgets/calendar-widget.form.fields.request-date-to')) ->default(now()) ->hidden(fn(Get $get) => $get('request_unit_half')) ->required(), Forms\Components\Select::make('request_date_from_period') - ->label('Period') + ->label(__('time_off::filament/widgets/calendar-widget.form.fields.period')) ->options(RequestDateFromPeriod::class) ->default(RequestDateFromPeriod::MORNING->value) ->native(false) @@ -196,9 +205,9 @@ public function getFormSchema(): array ]), Forms\Components\Toggle::make('request_unit_half') ->live() - ->label('Half Day'), + ->label(__('time_off::filament/widgets/calendar-widget.form.fields.half-day')), Forms\Components\Placeholder::make('requested_days') - ->label('Requested (Days/Hours)') + ->label(__('time_off::filament/widgets/calendar-widget.form.fields.requested-days')) ->live() ->inlineLabel() ->reactive() @@ -213,7 +222,7 @@ public function getFormSchema(): array return $startDate->diffInDays($endDate) . ' day(s)'; }), Forms\Components\Textarea::make('private_name') - ->label('Description'), + ->label(__('time_off::filament/widgets/calendar-widget.form.fields.description')), ]; } @@ -221,26 +230,26 @@ public function infolist(): array { return [ Infolists\Components\TextEntry::make('holidayStatus.name') - ->label('Time Off Type') + ->label(__('time_off::filament/widgets/calendar-widget.infolist.entries.time-off-type')) ->icon('heroicon-o-clock'), Infolists\Components\TextEntry::make('request_date_from') - ->label('Start Date') + ->label(__('time_off::filament/widgets/calendar-widget.infolist.entries.request-date-from')) ->date() ->icon('heroicon-o-calendar-days'), Infolists\Components\TextEntry::make('request_date_to') - ->label('End Date') + ->label(__('time_off::filament/widgets/calendar-widget.infolist.entries.request-date-to')) ->date() ->icon('heroicon-o-calendar-days'), Infolists\Components\TextEntry::make('number_of_days') - ->label('Duration') + ->label(__('time_off::filament/widgets/calendar-widget.infolist.entries.duration')) ->formatStateUsing(fn($state) => $state . ' day(s)') ->icon('heroicon-o-clock'), Infolists\Components\TextEntry::make('private_name') - ->label('Description') + ->label(__('time_off::filament/widgets/calendar-widget.infolist.entries.description')) ->icon('heroicon-o-document-text') - ->placeholder('No description provided'), + ->placeholder(__('time_off::filament/widgets/calendar-widget.infolist.entries.description-placeholder')), Infolists\Components\TextEntry::make('state') - ->label('Status') + ->placeholder(__('time_off::filament/widgets/calendar-widget.infolist.entries.status')) ->badge() ->formatStateUsing(fn($state) => State::options()[$state]) ->icon('heroicon-o-check-circle') diff --git a/plugins/webkul/time-off/src/Filament/Widgets/LeaveTypeWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/LeaveTypeWidget.php index f9aaff5f..88b1f390 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/LeaveTypeWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/LeaveTypeWidget.php @@ -10,7 +10,7 @@ class LeaveTypeWidget extends ChartWidget { public function getHeading(): string|Htmlable|null { - return __('Time Off Analysis'); + return __('time_off::filament/widgets/leave-type-widget.heading.title'); } protected static ?int $sort = 2; @@ -55,25 +55,25 @@ protected function getData(): array 'refused' => ['Refused' => $stats->refused ?? 0], 'cancelled' => ['Cancelled' => $stats->cancelled ?? 0], default => [ - 'Draft' => $stats->draft ?? 0, - 'Confirmed' => $stats->confirmed ?? 0, - 'Validated' => $stats->validated ?? 0, - 'Refused' => $stats->refused ?? 0, - 'Cancelled' => $stats->cancelled ?? 0, + __('time_off::filament/widgets/leave-type-widget.types.draft') => $stats->draft ?? 0, + __('time_off::filament/widgets/leave-type-widget.types.confirmed') => $stats->confirmed ?? 0, + __('time_off::filament/widgets/leave-type-widget.types.validated') => $stats->validated ?? 0, + __('time_off::filament/widgets/leave-type-widget.types.refused') => $stats->refused ?? 0, + __('time_off::filament/widgets/leave-type-widget.types.cancelled') => $stats->cancelled ?? 0, ], }; return [ 'datasets' => [ [ - 'label' => __('time_off::filament/widgets/leave.overview.label'), + 'label' => __('time_off::filament/widgets/leave-type-widget.label'), 'data' => array_values($data), 'backgroundColor' => array_map(fn($key) => match ($key) { - 'Draft' => '#94a3b8', - 'Confirmed' => '#3b82f6', - 'Validated' => '#22c55e', - 'Refused' => '#ef4444', - 'Cancelled' => '#f97316', + __('time_off::filament/widgets/leave-type-widget.types.draft') => '#94a3b8', + __('time_off::filament/widgets/leave-type-widget.types.confirmed') => '#3b82f6', + __('time_off::filament/widgets/leave-type-widget.types.validated') => '#22c55e', + __('time_off::filament/widgets/leave-type-widget.types.refused') => '#ef4444', + __('time_off::filament/widgets/leave-type-widget.types.cancelled') => '#f97316', }, array_keys($data)), ], ], diff --git a/plugins/webkul/time-off/src/Filament/Widgets/MyTimeOffWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/MyTimeOffWidget.php index 88f93e02..13ba653d 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/MyTimeOffWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/MyTimeOffWidget.php @@ -26,14 +26,14 @@ protected function getStats(): array $availableDays = $this->calculateAvailableDays($employeeId, $leaveType->id, $endOfYear); $stats[] = Stat::make(__($leaveType->name), $availableDays['days']) - ->description("Valid until {$endOfYear}") + ->description(__('time_off::filament/widgets/my-time-off-widget.stats.valid-until', ['date' => $endOfYear->format('Y-m-d')])) ->color(Color::hex($leaveType->color)); } $pendingRequests = $this->calculatePendingRequests($employeeId); $stats[] = Stat::make(__('Pending Requests'), $pendingRequests) - ->description('Time Off Requests') + ->description(__('time_off::filament/widgets/my-time-off-widget.stats.time-off-requests')) ->color('danger'); return $stats; diff --git a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php index a52ad0ef..d69d8db5 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php @@ -23,6 +23,7 @@ protected function modalActions(): array { return [ Actions\EditAction::make() + ->label(__('time_off::filament/widgets/overview-calendar-widget.modal-actions.edit.title')) ->action(function ($data, $record) { $user = Auth::user(); $employee = $user->employee; @@ -85,7 +86,8 @@ function (Forms\Form $form, array $arguments, $livewire) { $form->fill($newData); } ), - Actions\DeleteAction::make(), + Actions\DeleteAction::make() + ->label(__('time_off::filament/widgets/overview-calendar-widget.modal-actions.delete.title')), ]; } @@ -93,7 +95,8 @@ protected function viewAction(): Action { return Actions\ViewAction::make() ->modalIcon('heroicon-o-lifebuoy') - ->modalDescription('View Time Off Request') + ->label(__('time_off::filament/widgets/overview-calendar-widget.view-action.title')) + ->modalDescription(__('time_off::filament/widgets/overview-calendar-widget.view-action.description')) ->infolist($this->infolist()); } @@ -101,6 +104,10 @@ protected function headerActions(): array { return [ Actions\CreateAction::make() + ->icon('heroicon-o-plus-circle') + ->modalIcon('heroicon-o-lifebuoy') + ->label(__('time_off::filament/widgets/overview-calendar-widget.header-actions.create.title')) + ->modalDescription(__('time_off::filament/widgets/overview-calendar-widget.header-actions.create.description')) ->action(function ($data) { $user = Auth::user(); $employee = $user->employee; @@ -162,7 +169,7 @@ public function getFormSchema(): array { return [ Forms\Components\Select::make('holiday_status_id') - ->label('Time Off Type') + ->label(__('time_off::filament/widgets/overview-calendar-widget.form.fields.time-off-type')) ->relationship('holidayStatus', 'name') ->searchable() ->preload() @@ -179,15 +186,17 @@ public function getFormSchema(): array ->schema([ Forms\Components\DatePicker::make('request_date_from') ->native(false) + ->label(__('time_off::filament/widgets/overview-calendar-widget.form.fields.request-date-from')) ->default(now()) ->required(), Forms\Components\DatePicker::make('request_date_to') ->native(false) + ->label(__('time_off::filament/widgets/overview-calendar-widget.form.fields.request-date-to')) ->default(now()) ->hidden(fn(Get $get) => $get('request_unit_half')) ->required(), Forms\Components\Select::make('request_date_from_period') - ->label('Period') + ->label(__('time_off::filament/widgets/overview-calendar-widget.form.fields.period')) ->options(RequestDateFromPeriod::class) ->default(RequestDateFromPeriod::MORNING->value) ->native(false) @@ -196,9 +205,9 @@ public function getFormSchema(): array ]), Forms\Components\Toggle::make('request_unit_half') ->live() - ->label('Half Day'), + ->label(__('time_off::filament/widgets/overview-calendar-widget.form.fields.half-day')), Forms\Components\Placeholder::make('requested_days') - ->label('Requested (Days/Hours)') + ->label(__('time_off::filament/widgets/overview-calendar-widget.form.fields.requested-days')) ->live() ->inlineLabel() ->reactive() @@ -213,7 +222,7 @@ public function getFormSchema(): array return $startDate->diffInDays($endDate) . ' day(s)'; }), Forms\Components\Textarea::make('private_name') - ->label('Description'), + ->label(__('time_off::filament/widgets/overview-calendar-widget.form.fields.description')), ]; } @@ -221,26 +230,26 @@ public function infolist(): array { return [ Infolists\Components\TextEntry::make('holidayStatus.name') - ->label('Time Off Type') + ->label(__('time_off::filament/widgets/overview-calendar-widget.infolist.entries.time-off-type')) ->icon('heroicon-o-clock'), Infolists\Components\TextEntry::make('request_date_from') - ->label('Start Date') + ->label(__('time_off::filament/widgets/overview-calendar-widget.infolist.entries.request-date-from')) ->date() ->icon('heroicon-o-calendar-days'), Infolists\Components\TextEntry::make('request_date_to') - ->label('End Date') + ->label(__('time_off::filament/widgets/overview-calendar-widget.infolist.entries.request-date-to')) ->date() ->icon('heroicon-o-calendar-days'), Infolists\Components\TextEntry::make('number_of_days') - ->label('Duration') + ->label(__('time_off::filament/widgets/overview-calendar-widget.infolist.entries.duration')) ->formatStateUsing(fn($state) => $state . ' day(s)') ->icon('heroicon-o-clock'), Infolists\Components\TextEntry::make('private_name') - ->label('Description') + ->label(__('time_off::filament/widgets/overview-calendar-widget.infolist.entries.description')) ->icon('heroicon-o-document-text') - ->placeholder('No description provided'), + ->placeholder(__('time_off::filament/widgets/overview-calendar-widget.infolist.entries.description-placeholder')), Infolists\Components\TextEntry::make('state') - ->label('Status') + ->placeholder(__('time_off::filament/widgets/overview-calendar-widget.infolist.entries.status')) ->badge() ->formatStateUsing(fn($state) => State::options()[$state]) ->icon('heroicon-o-check-circle') diff --git a/plugins/webkul/time-off/src/Traits/LeaveAccrualPlan.php b/plugins/webkul/time-off/src/Traits/LeaveAccrualPlan.php index 3aab6ab0..b3be996e 100644 --- a/plugins/webkul/time-off/src/Traits/LeaveAccrualPlan.php +++ b/plugins/webkul/time-off/src/Traits/LeaveAccrualPlan.php @@ -5,6 +5,9 @@ use Filament\Forms; use Filament\Forms\Form; use Filament\Forms\Get; +use Filament\Infolists\Infolist; +use Filament\Infolists; +use Filament\Notifications\Notification; use Filament\Tables; use Filament\Tables\Filters\QueryBuilder; use Filament\Tables\Filters\SelectFilter; @@ -25,73 +28,73 @@ public function form(Form $form): Form Forms\Components\Grid::make(2) ->schema([ Forms\Components\TextInput::make('added_value') - ->label('Accrual Amount') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.accrual-amount')) ->numeric() ->default(1) ->required() ->minValue(0) ->step(0.5), Forms\Components\Select::make('added_value_type') - ->label('Accrual Value Type') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.accrual-value-type')) ->options(Enums\AddedValueType::class) ->default(Enums\AddedValueType::DAYS->value) ->required(), ]), Forms\Components\Fieldset::make() - ->label('Accrual Frequency') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.accrual-frequency')) ->schema([ Forms\Components\Select::make('frequency') - ->label('') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.accrual-frequency')) ->options(Enums\Frequency::class) ->live() ->default(Enums\Frequency::WEEKLY->value) ->required() - ->afterStateUpdated(fn (Forms\Set $set) => $set('week_day', null)), + ->afterStateUpdated(fn(Forms\Set $set) => $set('week_day', null)), Forms\Components\Grid::make() ->schema([ Forms\Components\Group::make() ->schema([ Forms\Components\Select::make('week_day') - ->label('Accrual Day') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.accrual-day')) ->options(Week::class) ->default(Week::MONDAY->value) ->required(), ]) - ->visible(fn (Get $get) => $get('frequency') === Enums\Frequency::WEEKLY->value), + ->visible(fn(Get $get) => $get('frequency') === Enums\Frequency::WEEKLY->value), Forms\Components\Group::make() ->schema([ Forms\Components\Select::make('monthly_day') - ->label('Day of Month') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.day-of-month')) ->options(Enums\CarryoverDay::class) ->default(Enums\CarryoverDay::DAY_1->value) ->required(), ]) - ->visible(fn (Get $get) => $get('frequency') === Enums\Frequency::MONTHLY->value), + ->visible(fn(Get $get) => $get('frequency') === Enums\Frequency::MONTHLY->value), Forms\Components\Grid::make(2) ->schema([ Forms\Components\Select::make('first_day') - ->label('First Day of Month') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.first-day-of-month')) ->options(Enums\CarryoverDay::class) ->default(Enums\CarryoverDay::DAY_1->value) ->required(), Forms\Components\Select::make('second_day') - ->label('Second Day of Month') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.second-day-of-month')) ->options(Enums\CarryoverDay::class) ->default(Enums\CarryoverDay::DAY_15->value) ->required(), ]) - ->visible(fn (Get $get) => $get('frequency') === Enums\Frequency::BIMONTHLY->value), + ->visible(fn(Get $get) => $get('frequency') === Enums\Frequency::BIMONTHLY->value), Forms\Components\Grid::make(2) ->schema([ Forms\Components\Group::make() ->schema([ Forms\Components\Select::make('first_month') - ->label('First Period Month') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.first-period-month')) ->options(Enums\CarryoverMonth::class) ->default(Enums\CarryoverMonth::JAN->value) ->required(), Forms\Components\Select::make('first_day_biyearly') - ->label('First Period Day') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.first-period-day')) ->options(Enums\CarryoverDay::class) ->default(Enums\CarryoverDay::DAY_1->value) ->required(), @@ -99,102 +102,103 @@ public function form(Form $form): Form Forms\Components\Group::make() ->schema([ Forms\Components\Select::make('second_month') - ->label('Second Period Month') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.second-period-month')) ->options(Enums\CarryoverMonth::class) ->default(Enums\CarryoverMonth::JUL->value) ->required(), Forms\Components\Select::make('second_day_biyearly') - ->label('Second Period Day') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.second-period-day')) ->options(Enums\CarryoverDay::class) ->default(Enums\CarryoverDay::DAY_1->value) ->required(), ]), ]) - ->visible(fn (Get $get) => $get('frequency') === Enums\Frequency::BIYEARLY->value), + ->visible(fn(Get $get) => $get('frequency') === Enums\Frequency::BIYEARLY->value), Forms\Components\Grid::make(2) ->schema([ Forms\Components\Group::make() ->schema([ Forms\Components\Select::make('first_day_biyearly') - ->label('First Period Day') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.first-period-day')) ->options(Enums\CarryoverDay::class) ->default(Enums\CarryoverDay::DAY_1->value) ->required(), Forms\Components\Select::make('first_month') - ->label('First Period Year') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.first-period-year')) ->options(Enums\CarryoverMonth::class) ->default(Enums\CarryoverMonth::JAN->value) ->required(), ]), ]) - ->visible(fn (Get $get) => $get('frequency') === Enums\Frequency::YEARLY->value), + ->visible(fn(Get $get) => $get('frequency') === Enums\Frequency::YEARLY->value), ]), ]), - Forms\Components\Fieldset::make('Cap Accrued') + Forms\Components\Fieldset::make(__('time_off::traits/leave-accrual-plan.form.fields.cap-accrued-time')) ->schema([ Forms\Components\Toggle::make('cap_accrued_time') ->inline(false) ->live() ->default(false) - ->label('Cap accrued time'), + ->label(__('time_off::traits/leave-accrual-plan.form.fields.cap-accrued-time')), Forms\Components\TextInput::make('maximum_leave') - ->label('Days') - ->visible(fn (Get $get) => $get('cap_accrued_time') === true) + ->label(__('time_off::traits/leave-accrual-plan.form.fields.days')) + ->visible(fn(Get $get) => $get('cap_accrued_time') === true) ->numeric(), ])->columns(4), - Forms\Components\Fieldset::make('Start Accrual') + Forms\Components\Fieldset::make(__('time_off::traits/leave-accrual-plan.form.fields.start-count')) ->schema([ Forms\Components\TextInput::make('start_count') ->live() ->default(1) - ->label('Start Count'), + ->label(__('time_off::traits/leave-accrual-plan.form.fields.start-count')), Forms\Components\Select::make('start_type') - ->label('Start Type') + ->label(__('time_off::traits/leave-accrual-plan.form.fields.start-type')) ->options(Enums\StartType::class) ->default(Enums\StartType::YEARS->value) ->required() - ->helperText('After allocation start date'), + ->helperText(__('time_off::traits/leave-accrual-plan.form.fields.after-allocation-start')), ])->columns(2), - Forms\Components\Fieldset::make('Advanced Accrual Settings') + Forms\Components\Fieldset::make(__('time_off::traits/leave-accrual-plan.form.fields.advanced-accrual-settings')) ->schema([ Forms\Components\Radio::make('action_with_unused_accruals') ->options(Enums\CarryOverUnusedAccruals::class) ->live() ->required() - ->default(Enums\CarryOverUnusedAccruals::ALL_ACCRUED_TIME_CARRIED_OVER->value), + ->default(Enums\CarryOverUnusedAccruals::ALL_ACCRUED_TIME_CARRIED_OVER->value) + ->label(__('time_off::traits/leave-accrual-plan.form.fields.action-with-unused-accruals')), Forms\Components\Grid::make(2) ->schema([ Forms\Components\Toggle::make('cap_accrued_time_yearly') ->inline(false) ->live() - ->visible(fn (Get $get) => $get('action_with_unused_accruals') == Enums\CarryOverUnusedAccruals::ALL_ACCRUED_TIME_CARRIED_OVER->value) + ->visible(fn(Get $get) => $get('action_with_unused_accruals') == Enums\CarryOverUnusedAccruals::ALL_ACCRUED_TIME_CARRIED_OVER->value) ->default(false) - ->label('Milestone cap'), + ->label(__('time_off::traits/leave-accrual-plan.form.fields.milestone-cap')), Forms\Components\TextInput::make('maximum_leave_yearly') ->numeric() - ->visible(fn (Get $get) => $get('cap_accrued_time_yearly')) - ->label('Days'), + ->visible(fn(Get $get) => $get('cap_accrued_time_yearly')) + ->label(__('time_off::traits/leave-accrual-plan.form.fields.maximum-leave-yearly')), ]), Forms\Components\Grid::make(2) ->schema([ Forms\Components\Toggle::make('accrual_validity') ->inline(false) ->live() - ->visible(fn (Get $get) => $get('action_with_unused_accruals') == Enums\CarryOverUnusedAccruals::ALL_ACCRUED_TIME_CARRIED_OVER->value) + ->visible(fn(Get $get) => $get('action_with_unused_accruals') == Enums\CarryOverUnusedAccruals::ALL_ACCRUED_TIME_CARRIED_OVER->value) ->default(false) - ->label('Milestone cap'), + ->label(__('time_off::traits/leave-accrual-plan.form.fields.accrual-validity')), Forms\Components\TextInput::make('accrual_validity_count') ->numeric() - ->visible(fn (Get $get) => $get('accrual_validity')) - ->label('Days'), + ->visible(fn(Get $get) => $get('accrual_validity')) + ->label(__('time_off::traits/leave-accrual-plan.form.fields.accrual-validity-count')), Forms\Components\Select::make('accrual_validity_type') ->required() - ->visible(fn (Get $get) => $get('accrual_validity')) + ->visible(fn(Get $get) => $get('accrual_validity')) ->options(Enums\AccrualValidityType::class) - ->label('Days'), + ->label(__('time_off::traits/leave-accrual-plan.form.fields.accrual-validity-type')), ]), ]) - ->columns(1), + ->columns(2), ]), ]); } @@ -204,73 +208,209 @@ public function table(Table $table): Table return $table ->columns([ Tables\Columns\TextColumn::make('added_value') - ->label('Accrual Amount') + ->label(__('time_off::traits/leave-accrual-plan.table.columns.accrual-amount')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('added_value_type') - ->label('Accrual Value Type') + ->label(__('time_off::traits/leave-accrual-plan.table.columns.accrual-value-type')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('frequency') - ->label('Frequency') + ->label(__('time_off::traits/leave-accrual-plan.table.columns.frequency')) ->sortable(), Tables\Columns\TextColumn::make('maximum_leave') - ->label('Max Leave Days') + ->label(__('time_off::traits/leave-accrual-plan.table.columns.maximum-leave-days')) ->sortable() ->searchable(), ]) + ->groups([ + Tables\Grouping\Group::make('added_value') + ->label(__('time_off::traits/leave-accrual-plan.table.groups.accrual-amount')) + ->collapsible(), + Tables\Grouping\Group::make('added_value_type') + ->label(__('time_off::traits/leave-accrual-plan.table.groups.accrual-value-type')) + ->collapsible(), + Tables\Grouping\Group::make('frequency') + ->label(__('time_off::traits/leave-accrual-plan.table.groups.frequency')) + ->collapsible(), + Tables\Grouping\Group::make('maximum_leave') + ->label(__('time_off::traits/leave-accrual-plan.table.groups.maximum-leave-days')) + ->collapsible(), + ]) ->filters([ SelectFilter::make('frequency') ->options(\Webkul\TimeOff\Enums\Frequency::class) - ->label(__('Accrual Frequency')), + ->label(__('time_off::traits/leave-accrual-plan.table.filters.accrual-frequency')), SelectFilter::make('start_type') ->options(\Webkul\TimeOff\Enums\StartType::class) - ->label(__('Start Type')), + ->label(__('time_off::traits/leave-accrual-plan.table.filters.start-type')), Tables\Filters\Filter::make('cap_accrued_time') ->form([ Forms\Components\Toggle::make('cap_accrued_time') - ->label(__('Cap Accrued Time')), + ->label(__('time_off::traits/leave-accrual-plan.table.filters.cap-accrued-time')), ]) - ->query(fn ($query, $data) => $query->where('cap_accrued_time', $data['cap_accrued_time'])) - ->label(__('Cap Accrued Time')), + ->query(fn($query, $data) => $query->where('cap_accrued_time', $data['cap_accrued_time'])) + ->label(__('time_off::traits/leave-accrual-plan.table.filters.cap-accrued-time')), SelectFilter::make('action_with_unused_accruals') ->options(\Webkul\TimeOff\Enums\CarryOverUnusedAccruals::class) - ->label(__('Action with Unused Accruals')), + ->label(__('time_off::traits/leave-accrual-plan.table.filters.action-with-unused-accruals')), QueryBuilder::make() ->constraintPickerColumns(2) ->constraints([ Tables\Filters\QueryBuilder\Constraints\TextConstraint::make('added_value') - ->label(__('Accrual Amount')) + ->label(__('time_off::traits/leave-accrual-plan.table.filters.accrual-amount')) ->icon('heroicon-o-calculator'), Tables\Filters\QueryBuilder\Constraints\TextConstraint::make('frequency') - ->label(__('Accrual Frequency')) + ->label(__('time_off::traits/leave-accrual-plan.table.filters.accrual-frequency')) ->icon('heroicon-o-arrow-path-rounded-square'), Tables\Filters\QueryBuilder\Constraints\TextConstraint::make('start_type') - ->label(__('Start Type')) + ->label(__('time_off::traits/leave-accrual-plan.table.filters.start-type')) ->icon('heroicon-o-clock'), Tables\Filters\QueryBuilder\Constraints\DateConstraint::make('created_at') - ->label(__('Created At')) + ->label(__('time_off::traits/leave-accrual-plan.table.filters.created-at')) ->icon('heroicon-o-calendar'), Tables\Filters\QueryBuilder\Constraints\DateConstraint::make('updated_at') - ->label(__('Updated At')) + ->label(__('time_off::traits/leave-accrual-plan.table.filters.updated-at')) ->icon('heroicon-o-calendar'), ]), ]) ->headerActions([ Tables\Actions\CreateAction::make() + ->icon('heroicon-o-plus-circle') + ->label(__('time_off::traits/leave-accrual-plan.table.header-actions.created.title')) ->mutateFormDataUsing(function ($data) { $data['creator_id'] = Auth::user()?->id; $data['sort'] = LeaveAccrualLevel::max('sort') + 1; return $data; - }), + }) + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::traits/leave-accrual-plan.table.header-actions.created.notification.title')) + ->body(__('time_off::traits/leave-accrual-plan.table.header-actions.created.notification.body')) + ), ]) ->actions([ - Tables\Actions\EditAction::make(), - Tables\Actions\DeleteAction::make(), + Tables\Actions\ViewAction::make(), + Tables\Actions\EditAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::traits/leave-accrual-plan.table.actions.edit.notification.title')) + ->body(__('time_off::traits/leave-accrual-plan.table.actions.edit.notification.body')) + ), + Tables\Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::traits/leave-accrual-plan.table.actions.delete.notification.title')) + ->body(__('time_off::traits/leave-accrual-plan.table.actions.delete.notification.body')) + ), ]) ->bulkActions([ - Tables\Actions\DeleteBulkAction::make(), + Tables\Actions\DeleteBulkAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::traits/leave-accrual-plan.table.bulk-actions.delete.notification.title')) + ->body(__('time_off::traits/leave-accrual-plan.table.bulk-actions.delete.notification.body')) + ), + ]); + } + + public function infolist(Infolist $infolist): Infolist + { + return $infolist + ->schema([ + Infolists\Components\Grid::make(1) + ->schema([ + Infolists\Components\Grid::make(2) + ->schema([ + Infolists\Components\TextEntry::make('added_value') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.accrual-amount')) + ->icon('heroicon-o-currency-dollar'), + Infolists\Components\TextEntry::make('added_value_type') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.accrual-value-type')) + ->formatStateUsing(fn($state) => Enums\AddedValueType::options()[$state] ?? $state) + ->icon('heroicon-o-adjustments-horizontal'), + ]), + Infolists\Components\TextEntry::make('frequency') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.accrual-frequency')) + ->formatStateUsing(fn($state) => Enums\Frequency::options()[$state] ?? $state) + ->icon('heroicon-o-calendar'), + Infolists\Components\Group::make() + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.accrual-frequency')) + ->schema([ + Infolists\Components\TextEntry::make('week_day') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.accrual-day')) + ->visible(fn($record) => $record->frequency === Enums\Frequency::WEEKLY->value) + ->icon('heroicon-o-clock'), + Infolists\Components\TextEntry::make('monthly_day') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.day-of-month')) + ->visible(fn($record) => $record->frequency === Enums\Frequency::MONTHLY->value) + ->icon('heroicon-o-calendar-days'), + Infolists\Components\Grid::make(2) + ->schema([ + Infolists\Components\TextEntry::make('first_day') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.first-day-of-month')) + ->icon('heroicon-o-arrow-up-circle'), + Infolists\Components\TextEntry::make('second_day') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.second-day-of-month')) + ->icon('heroicon-o-arrow-down-circle'), + ]) + ->visible(fn($record) => $record->frequency === Enums\Frequency::BIMONTHLY->value), + Infolists\Components\Grid::make(2) + ->schema([ + Infolists\Components\TextEntry::make('first_month') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.first-period-month')) + ->icon('heroicon-o-arrow-up-on-square'), + Infolists\Components\TextEntry::make('second_month') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.second-period-month')) + ->icon('heroicon-o-arrow-down-on-square'), + ]) + ->visible(fn($record) => $record->frequency === Enums\Frequency::BIYEARLY->value), + ]), + Infolists\Components\IconEntry::make('cap_accrued_time') + ->boolean() + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.cap-accrued-time')) + ->icon(fn($state) => $state ? 'heroicon-o-check-circle' : 'heroicon-o-x-circle'), + Infolists\Components\TextEntry::make('maximum_leave') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.days')) + ->visible(fn($record) => $record->cap_accrued_time) + ->icon('heroicon-o-scale'), + Infolists\Components\Grid::make(2) + ->schema([ + Infolists\Components\TextEntry::make('start_count') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.start-count')) + ->icon('heroicon-o-play-circle'), + Infolists\Components\TextEntry::make('start_type') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.start-type')) + ->formatStateUsing(fn($state) => Enums\StartType::options()[$state] ?? $state) + ->icon('heroicon-o-adjustments-vertical'), + ]), + Infolists\Components\Group::make() + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.advanced-accrual-settings')) + ->schema([ + Infolists\Components\TextEntry::make('action_with_unused_accruals') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.action-with-unused-accruals')) + ->formatStateUsing(fn($state) => Enums\CarryOverUnusedAccruals::options()[$state] ?? $state) + ->icon('heroicon-o-receipt-refund'), + Infolists\Components\TextEntry::make('maximum_leave_yearly') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.maximum-leave-yearly')) + ->visible(fn($record) => $record->cap_accrued_time_yearly) + ->icon('heroicon-o-chart-pie'), + Infolists\Components\TextEntry::make('accrual_validity_count') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.accrual-validity-count')) + ->visible(fn($record) => $record->accrual_validity) + ->icon('heroicon-o-clock'), + Infolists\Components\TextEntry::make('accrual_validity_type') + ->label(__('time_off::traits/leave-accrual-plan.infolist.entries.accrual-validity-type')) + ->formatStateUsing(fn($state) => Enums\AccrualValidityType::options()[$state] ?? $state) + ->visible(fn($record) => $record->accrual_validity) + ->icon('heroicon-o-calendar-days'), + ]), + ]), ]); } } From fb4846c0f2d43fcd50c5d9ac6e8d1fa387283dec Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 18:50:49 +0530 Subject: [PATCH 10/24] Add language files for time off clusters and update navigation labels --- .../lang/en/filament/clusters/configuration.php | 8 ++++++++ .../resources/lang/en/filament/clusters/management.php | 9 +++++++++ .../resources/lang/en/filament/clusters/my-time.php | 8 ++++++++ .../resources/lang/en/filament/clusters/overview.php | 8 ++++++++ .../resources/lang/en/filament/clusters/reporting.php | 8 ++++++++ .../time-off/src/Filament/Clusters/Configurations.php | 4 ++-- .../webkul/time-off/src/Filament/Clusters/Management.php | 4 ++-- plugins/webkul/time-off/src/Filament/Clusters/MyTime.php | 4 ++-- .../webkul/time-off/src/Filament/Clusters/Overview.php | 4 ++-- .../webkul/time-off/src/Filament/Clusters/Reporting.php | 4 ++-- 10 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/configuration.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/management.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/overview.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting.php diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configuration.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configuration.php new file mode 100644 index 00000000..c7adb167 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configuration.php @@ -0,0 +1,8 @@ + [ + 'title' => 'Configuration', + 'group' => 'Time Off', + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/management.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management.php new file mode 100644 index 00000000..c17ecba5 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management.php @@ -0,0 +1,9 @@ + [ + 'title' => 'Management', + 'group' => 'Time Off', + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time.php new file mode 100644 index 00000000..3b436a80 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time.php @@ -0,0 +1,8 @@ + [ + 'title' => 'Time Off', + 'group' => 'Time Off', + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/overview.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/overview.php new file mode 100644 index 00000000..859e733c --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/overview.php @@ -0,0 +1,8 @@ + [ + 'title' => 'Overview', + 'group' => 'Time Off', + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting.php new file mode 100644 index 00000000..cdcf3309 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting.php @@ -0,0 +1,8 @@ + [ + 'title' => 'Reporting', + 'group' => 'Time Off', + ] +]; diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php index 6df13076..2c15e243 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations.php @@ -17,11 +17,11 @@ public static function getSlug(): string public static function getNavigationLabel(): string { - return __('Configuration'); + return __('time_off::filament/clusters/configuration.navigation.title'); } public static function getNavigationGroup(): string { - return __('Time Off'); + return __('time_off::filament/clusters/configuration.navigation.group'); } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management.php b/plugins/webkul/time-off/src/Filament/Clusters/Management.php index 7256ce5e..37cdecb1 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management.php @@ -17,11 +17,11 @@ public static function getSlug(): string public static function getNavigationLabel(): string { - return __('Management'); + return __('time_off::filament/clusters/management.navigation.title'); } public static function getNavigationGroup(): string { - return __('Time Off'); + return __('time_off::filament/clusters/management.navigation.group'); } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime.php index 703ef402..815a775d 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime.php @@ -17,11 +17,11 @@ public static function getSlug(): string public static function getNavigationLabel(): string { - return __('Time Off'); + return __('time_off::filament/clusters/my-time.navigation.title'); } public static function getNavigationGroup(): string { - return __('Time Off'); + return __('time_off::filament/clusters/my-time.navigation.group'); } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Overview.php b/plugins/webkul/time-off/src/Filament/Clusters/Overview.php index 402a43a1..16caa9d2 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Overview.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Overview.php @@ -17,11 +17,11 @@ public static function getSlug(): string public static function getNavigationLabel(): string { - return __('Overview'); + return __('time_off::filament/clusters/overview.navigation.title'); } public static function getNavigationGroup(): string { - return __('Time Off'); + return __('time_off::filament/clusters/overview.navigation.group'); } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Reporting.php b/plugins/webkul/time-off/src/Filament/Clusters/Reporting.php index 9fd10eab..29915f85 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Reporting.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Reporting.php @@ -17,11 +17,11 @@ public static function getSlug(): string public static function getNavigationLabel(): string { - return __('Reporting'); + return __('time_off::filament/clusters/reporting.navigation.title'); } public static function getNavigationGroup(): string { - return __('Time Off'); + return __('time_off::filament/clusters/reporting.navigation.group'); } } From 2704badc3f8d5ef693fbda515e326bbeee58b43b Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 19:41:46 +0530 Subject: [PATCH 11/24] Refactor Leave model to rename creator method to createdBy; update global search attributes in MandatoryDayResource and enhance ByEmployeeResource with new methods for navigation and global search results. Add language files for By Employees resource. --- .../Filament/Resources/DepartmentResource.php | 10 ++--- .../reporting/resources/by-employee.php | 17 +++++++++ .../by-employee/edit-by-employee.php | 12 ++++++ .../Resources/LeaveTypeResource.php | 34 ++++++++--------- .../Resources/MandatoryDayResource.php | 2 +- .../Resources/ByEmployeeResource.php | 37 +++++++++++++++++-- .../Pages/CreateByEmployee.php | 5 +++ .../Pages/EditByEmployee.php | 14 ++++++- .../time-off/src/Filament/Pages/Overview.php | 1 - plugins/webkul/time-off/src/Models/Leave.php | 2 +- 10 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting/resources/by-employee.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting/resources/by-employee/edit-by-employee.php diff --git a/plugins/webkul/employees/src/Filament/Resources/DepartmentResource.php b/plugins/webkul/employees/src/Filament/Resources/DepartmentResource.php index b615258d..a33c805a 100644 --- a/plugins/webkul/employees/src/Filament/Resources/DepartmentResource.php +++ b/plugins/webkul/employees/src/Filament/Resources/DepartmentResource.php @@ -87,7 +87,7 @@ public static function form(Form $form): Form Forms\Components\Select::make('company_id') ->label(__('employees::filament/resources/department.form.sections.general.fields.company')) ->relationship('company', 'name') - ->options(fn () => Company::pluck('name', 'id')) + ->options(fn() => Company::pluck('name', 'id')) ->searchable() ->placeholder(__('employees::filament/resources/department.form.sections.general.fields.company-placeholder')) ->nullable(), @@ -127,7 +127,7 @@ public static function table(Table $table): Table ->sortable() ->searchable(), ]) - ->visible(fn ($record) => filled($record?->manager?->name)), + ->visible(fn($record) => filled($record?->manager?->name)), Tables\Columns\Layout\Stack::make([ Tables\Columns\TextColumn::make('company.name') ->searchable() @@ -135,7 +135,7 @@ public static function table(Table $table): Table ->icon('heroicon-m-building-office-2') ->searchable(), ]) - ->visible(fn ($record) => filled($record?->company?->name)), + ->visible(fn($record) => filled($record?->company?->name)), ])->space(1), ])->space(4), ]) @@ -283,7 +283,7 @@ public static function infolist(Infolist $infolist): Infolist Infolists\Components\TextEntry::make('hierarchy') ->label('') ->html() - ->state(fn (Department $record): string => static::buildHierarchyTree($record)), + ->state(fn(Department $record): string => static::buildHierarchyTree($record)), ])->columnSpan('full'), ]) ->columns(2), @@ -368,7 +368,7 @@ protected static function formatDepartmentLine( $managerName = $department->manager?->name ? " · {$department->manager->name}" : ''; $style = $isActive - ? 'color: '.($department->color ?? '#1D4ED8').'; font-weight: bold;' + ? 'color: ' . ($department->color ?? '#1D4ED8') . '; font-weight: bold;' : ''; return sprintf( diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting/resources/by-employee.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting/resources/by-employee.php new file mode 100644 index 00000000..289b763e --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting/resources/by-employee.php @@ -0,0 +1,17 @@ + 'By Employees', + + 'navigation' => [ + 'title' => 'By Employees', + ], + + 'global-search' => [ + 'employee' => 'Employee', + 'department' => 'Department', + 'time-off-type' => 'Time Off Type', + 'request-date-from' => 'Request Date From', + 'request-date-to' => 'Request Date To', + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting/resources/by-employee/edit-by-employee.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting/resources/by-employee/edit-by-employee.php new file mode 100644 index 00000000..debfc2b2 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/reporting/resources/by-employee/edit-by-employee.php @@ -0,0 +1,12 @@ + [ + 'delete' => [ + 'notification' => [ + 'title' => 'Time Off deleted', + 'body' => 'The time off has been deleted successfully.', + ], + ] + ] +]; diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/LeaveTypeResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/LeaveTypeResource.php index 5a98b134..ff387c40 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/LeaveTypeResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/LeaveTypeResource.php @@ -40,7 +40,7 @@ public static function getGloballySearchableAttributes(): array return [ 'name', 'company.name', - 'creator.name', + 'createdBy.name', ]; } @@ -89,14 +89,14 @@ public static function form(Form $form): Form ->label(__('time_off::filament/clusters/configurations/resources/leave-type.form.sections.general.fields.employee-requests')) ->inline(false) ->live() - ->visible(fn (Get $get) => $get('requires_allocation') === Enums\RequiresAllocation::YES->value) + ->visible(fn(Get $get) => $get('requires_allocation') === Enums\RequiresAllocation::YES->value) ->default(Enums\EmployeeRequest::NO->value) ->options(Enums\EmployeeRequest::class), Forms\Components\Radio::make('allocation_validation_type') ->label(__('time_off::filament/clusters/configurations/resources/leave-type.form.sections.general.fields.approval')) ->inline(false) ->live() - ->visible(fn (Get $get) => $get('requires_allocation') === Enums\RequiresAllocation::YES->value) + ->visible(fn(Get $get) => $get('requires_allocation') === Enums\RequiresAllocation::YES->value) ->default(Enums\AllocationValidationType::HR->value) ->options(Enums\AllocationValidationType::class), ]), @@ -139,14 +139,14 @@ public static function form(Form $form): Form ->default(Enums\TimeType::LEAVE->value) ->label(__('time_off::filament/clusters/configurations/resources/leave-type.form.sections.configuration.fields.kind-of-time')), Forms\Components\Toggle::make('allows_negative') - ->visible(fn (Get $get) => $get('requires_allocation') === Enums\RequiresAllocation::YES->value) + ->visible(fn(Get $get) => $get('requires_allocation') === Enums\RequiresAllocation::YES->value) ->live() ->inline(false) ->label(__('time_off::filament/clusters/configurations/resources/leave-type.form.sections.configuration.fields.allow-negative-cap')), Forms\Components\TextInput::make('max_allowed_negative') ->numeric() ->default(0) - ->visible(fn (Get $get) => $get('requires_allocation') === Enums\RequiresAllocation::YES->value && $get('allows_negative') === true) + ->visible(fn(Get $get) => $get('requires_allocation') === Enums\RequiresAllocation::YES->value && $get('allows_negative') === true) ->label(__('time_off::filament/clusters/configurations/resources/leave-type.form.sections.configuration.fields.max-negative-cap')) ->step(1) ->live() @@ -182,20 +182,20 @@ public static function table(Table $table): Table Tables\Columns\TextColumn::make('requires_allocation') ->badge() ->label(__('time_off::filament/clusters/configurations/resources/leave-type.table.columns.requires-allocation')) - ->formatStateUsing(fn ($state) => RequiresAllocation::options()[$state]) + ->formatStateUsing(fn($state) => RequiresAllocation::options()[$state]) ->searchable() ->toggleable(isToggledHiddenByDefault: true) ->sortable(), Tables\Columns\TextColumn::make('allocation_validation_type') ->label(__('time_off::filament/clusters/configurations/resources/leave-type.table.columns.allocation-approval')) ->searchable() - ->formatStateUsing(fn ($state) => Enums\AllocationValidationType::options()[$state]) + ->formatStateUsing(fn($state) => Enums\AllocationValidationType::options()[$state]) ->sortable(), Tables\Columns\TextColumn::make('employee_requests') ->badge() ->toggleable(isToggledHiddenByDefault: true) ->label(__('time_off::filament/clusters/configurations/resources/leave-type.table.columns.employee-request')) - ->formatStateUsing(fn ($state) => Enums\EmployeeRequest::options()[$state]) + ->formatStateUsing(fn($state) => Enums\EmployeeRequest::options()[$state]) ->searchable() ->sortable(), Tables\Columns\ColorColumn::make('color') @@ -329,21 +329,21 @@ public static function infolist(Infolist $infolist): Infolist ->label(__('time_off::filament/clusters/configurations/resources/leave-type.infolist.sections.general.entries.requires-allocation')) ->icon('heroicon-o-calculator') ->placeholder('—') - ->formatStateUsing(fn ($state) => Enums\RequiresAllocation::options()[$state]) + ->formatStateUsing(fn($state) => Enums\RequiresAllocation::options()[$state]) ->badge(), Infolists\Components\TextEntry::make('employee_requests') ->label(__('time_off::filament/clusters/configurations/resources/leave-type.infolist.sections.general.entries.employee-requests')) ->icon('heroicon-o-user-group') ->placeholder('—') - ->formatStateUsing(fn ($state) => Enums\EmployeeRequest::options()[$state]) - ->visible(fn ($record) => $record->requires_allocation === Enums\RequiresAllocation::YES->value) + ->formatStateUsing(fn($state) => Enums\EmployeeRequest::options()[$state]) + ->visible(fn($record) => $record->requires_allocation === Enums\RequiresAllocation::YES->value) ->badge(), Infolists\Components\TextEntry::make('allocation_validation_type') ->label(__('time_off::filament/clusters/configurations/resources/leave-type.infolist.sections.general.entries.approval')) ->icon('heroicon-o-shield-check') ->placeholder('—') - ->formatStateUsing(fn ($state) => Enums\AllocationValidationType::options()[$state]) - ->visible(fn ($record) => $record->requires_allocation === Enums\RequiresAllocation::YES->value) + ->formatStateUsing(fn($state) => Enums\AllocationValidationType::options()[$state]) + ->visible(fn($record) => $record->requires_allocation === Enums\RequiresAllocation::YES->value) ->badge(), ]), ]), @@ -369,7 +369,7 @@ public static function infolist(Infolist $infolist): Infolist Infolists\Components\TextEntry::make('request_unit') ->label(__('time_off::filament/clusters/configurations/resources/leave-type.infolist.sections.configuration.entries.take-time-off-in')) ->icon('heroicon-o-clock') - ->formatStateUsing(fn ($state) => Enums\RequestUnit::options()[$state]) + ->formatStateUsing(fn($state) => Enums\RequestUnit::options()[$state]) ->placeholder('—') ->badge(), Infolists\Components\IconEntry::make('include_public_holidays_in_duration') @@ -388,17 +388,17 @@ public static function infolist(Infolist $infolist): Infolist ->label(__('time_off::filament/clusters/configurations/resources/leave-type.infolist.sections.configuration.entries.kind-of-time')) ->icon('heroicon-o-clock') ->placeholder('—') - ->formatStateUsing(fn ($state) => Enums\TimeType::options()[$state]) + ->formatStateUsing(fn($state) => Enums\TimeType::options()[$state]) ->badge(), Infolists\Components\IconEntry::make('allows_negative') ->boolean() - ->visible(fn ($record) => $record->requires_allocation === Enums\RequiresAllocation::YES->value) + ->visible(fn($record) => $record->requires_allocation === Enums\RequiresAllocation::YES->value) ->placeholder('—'), Infolists\Components\TextEntry::make('max_allowed_negative') ->label(__('time_off::filament/clusters/configurations/resources/leave-type.infolist.sections.configuration.entries.max-negative-cap')) ->icon('heroicon-o-arrow-trending-down') ->placeholder('—') - ->visible(fn ($record) => $record->requires_allocation === Enums\RequiresAllocation::YES->value && $record->allows_negative === true) + ->visible(fn($record) => $record->requires_allocation === Enums\RequiresAllocation::YES->value && $record->allows_negative === true) ->numeric(), ]), ])->columnSpan(1), diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php index fa04d983..6e292235 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php @@ -34,7 +34,7 @@ public static function getGloballySearchableAttributes(): array return [ 'name', 'company.name', - 'creator.name', + 'createdBy.name', ]; } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php index 3f691c3f..40e5b8a1 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource.php @@ -7,6 +7,7 @@ use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Model; use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; use Webkul\TimeOff\Models\Leave; @@ -18,7 +19,37 @@ class ByEmployeeResource extends Resource protected static ?string $cluster = Reporting::class; - protected static ?string $modelLabel = 'By Employee'; + public static function getModelLabel(): string + { + return __('time_off::filament/clusters/reporting/resources/by-employee.title'); + } + + public static function getNavigationLabel(): string + { + return __('time_off::filament/clusters/reporting/resources/by-employee.navigation.title'); + } + + public static function getGloballySearchableAttributes(): array + { + return [ + 'employee.name', + 'department.name', + 'holidayStatus.name', + 'request_date_from', + 'request_date_to' + ]; + } + + public static function getGlobalSearchResultDetails(Model $record): array + { + return [ + __('time_Off::filament/clusters/reporting/resources/by-employee.global-search.employee') => $record->name ?? '—', + __('time_Off::filament/clusters/reporting/resources/by-employee.global-search.department') => $record->manager?->name ?? '—', + __('time_Off::filament/clusters/reporting/resources/by-employee.global-search.time-off-type') => $record->company?->name ?? '—', + __('time_Off::filament/clusters/reporting/resources/by-employee.global-search.request-date-from') => $record->request_date_from ?? '—', + __('time_Off::filament/clusters/reporting/resources/by-employee.global-search.request-date-to') => $record->request_date_to ?? '—', + ]; + } public static function form(Form $form): Form { @@ -34,9 +65,9 @@ public static function table(Table $table): Table public static function getPages(): array { return [ - 'index' => Pages\ListByEmployees::route('/'), + 'index' => Pages\ListByEmployees::route('/'), 'create' => Pages\CreateByEmployee::route('/create'), - 'edit' => Pages\EditByEmployee::route('/{record}/edit'), + 'edit' => Pages\EditByEmployee::route('/{record}/edit'), ]; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/CreateByEmployee.php b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/CreateByEmployee.php index 40dc4c6f..1e2acc59 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/CreateByEmployee.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/CreateByEmployee.php @@ -9,4 +9,9 @@ class CreateByEmployee extends CreateRecord { protected static string $resource = ByEmployeeResource::class; + + protected function getRedirectUrl(): string + { + return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); + } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/EditByEmployee.php b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/EditByEmployee.php index a15d0440..f6e13a52 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/EditByEmployee.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Reporting/Resources/ByEmployeeResource/Pages/EditByEmployee.php @@ -4,16 +4,28 @@ use Webkul\TimeOff\Filament\Clusters\Reporting\Resources\ByEmployeeResource; use Filament\Actions; +use Filament\Notifications\Notification; use Filament\Resources\Pages\EditRecord; class EditByEmployee extends EditRecord { protected static string $resource = ByEmployeeResource::class; + protected function getRedirectUrl(): string + { + return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); + } + protected function getHeaderActions(): array { return [ - Actions\DeleteAction::make(), + Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/reporting/resources/by-employee/edit-by-employee.header-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/reporting/resources/by-employee/edit-by-employee.header-actions.delete.notification.body')) + ) ]; } } diff --git a/plugins/webkul/time-off/src/Filament/Pages/Overview.php b/plugins/webkul/time-off/src/Filament/Pages/Overview.php index 0e1a605a..06b73f97 100644 --- a/plugins/webkul/time-off/src/Filament/Pages/Overview.php +++ b/plugins/webkul/time-off/src/Filament/Pages/Overview.php @@ -3,7 +3,6 @@ namespace Webkul\TimeOff\Filament\Pages; use Filament\Pages\Dashboard as BaseDashboard; -use Webkul\TimeOff\Filament\Widgets\LeaveTypeWidget; use Webkul\TimeOff\Filament\Widgets\OverviewCalendarWidget; class Overview extends BaseDashboard diff --git a/plugins/webkul/time-off/src/Models/Leave.php b/plugins/webkul/time-off/src/Models/Leave.php index 5b1b82a8..413013da 100644 --- a/plugins/webkul/time-off/src/Models/Leave.php +++ b/plugins/webkul/time-off/src/Models/Leave.php @@ -98,7 +98,7 @@ public function secondApprover(): BelongsTo return $this->belongsTo(Employee::class, 'second_approver_id'); } - public function creator(): BelongsTo + public function createdBy(): BelongsTo { return $this->belongsTo(User::class, 'creator_id'); } From a54a4daadb2339ee9f12b28df5d134167e73f2ca Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 20:31:54 +0530 Subject: [PATCH 12/24] Add language files for My Time Off resource; implement success notifications for create, update, and delete actions in relevant pages. --- .../my-time/resources/my-allocation.php | 0 .../my-time/resources/my-time-off.php | 112 ++++++++++++ .../my-time-off/pages/create-time-off.php | 8 + .../my-time-off/pages/edit-time-off.php | 17 ++ .../my-time-off/pages/view-time-off.php | 12 ++ .../MyTime/Resources/MyTimeOffResource.php | 171 +++++++++++++++--- .../Pages/CreateMyTimeOff.php | 11 +- .../MyTimeOffResource/Pages/EditMyTimeOff.php | 28 ++- .../Pages/ListMyTimeOffs.php | 3 +- .../MyTimeOffResource/Pages/ViewMyTimeOff.php | 12 +- 10 files changed, 338 insertions(+), 36 deletions(-) create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/create-time-off.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/edit-time-off.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/view-time-off.php diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation.php new file mode 100644 index 00000000..e69de29b diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off.php new file mode 100644 index 00000000..5b02bc53 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off.php @@ -0,0 +1,112 @@ + 'Time off', + + 'model-label' => 'My Time off', + + 'navigation' => [ + 'title' => 'My Time off', + ], + + 'global-search' => [ + 'time-off-type' => 'Time off Type', + 'request-date-from' => 'Request Date From', + 'request-date-to' => 'Request Date To', + ], + + 'form' => [ + 'fields' => [ + 'time-off-type' => 'Time off Type', + 'date' => 'Date', + 'dates' => 'Dates', + 'request-date-from' => 'Request Date From', + 'request-date-to' => 'Request Date To', + 'description' => 'Description', + 'period' => 'Period', + 'half-day' => 'Half Day', + 'requested-days' => 'Requested (Days/Hours)', + 'description' => 'Description', + 'attachment' => 'Attachment', + 'day' => ':day day', + 'days' => ':days day(s)', + ], + ], + + 'table' => [ + 'columns' => [ + 'employee-name' => 'Employee', + 'time-off-type' => 'Time Off Type', + 'description' => 'Description', + 'date-from' => 'Date From', + 'date-to' => 'Date To', + 'duration' => 'Duration', + 'status' => 'Status', + ], + + 'groups' => [ + 'employee-name' => 'Employee', + 'time-off-type' => 'Time Off Type', + 'status' => 'Status', + 'start-date' => 'Start Date', + 'start-to' => 'End Date', + 'updated-at' => 'Updated At', + 'created-at' => 'Created At', + ], + + 'actions' => [ + 'approve' => [ + 'title' => [ + 'validate' => 'Validate', + 'approve' => 'Approve', + ], + 'notification' => [ + 'title' => 'Time Off approved', + 'body' => 'The time off has been approved successfully.', + ], + ], + + 'delete' => [ + 'notification' => [ + 'title' => 'Time Off deleted', + 'body' => 'The time off has been deleted successfully.', + ], + ], + + 'refused' => [ + 'title' => 'Refuse', + 'notification' => [ + 'title' => 'Time Off refused', + 'body' => 'The time off has been refused successfully.', + ], + ], + ], + + 'bulk-actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Time Offs deleted', + 'body' => 'The time offs has been deleted successfully.', + ], + ], + ], + ], + + 'infolist' => [ + 'entries' => [ + 'time-off-type' => 'Time off Type', + 'date' => 'Date', + 'dates' => 'Dates', + 'request-date-from' => 'Request Date From', + 'request-date-to' => 'Request Date To', + 'description' => 'Description', + 'period' => 'Period', + 'half-day' => 'Half Day', + 'requested-days' => 'Requested (Days/Hours)', + 'description' => 'Description', + 'attachment' => 'Attachment', + 'day' => ':day day', + 'days' => ':days day(s)', + ], + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/create-time-off.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/create-time-off.php new file mode 100644 index 00000000..5052737b --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/create-time-off.php @@ -0,0 +1,8 @@ + [ + 'title' => 'Time Off created', + 'body' => 'The time off has been created successfully.', + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/edit-time-off.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/edit-time-off.php new file mode 100644 index 00000000..116c11f2 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/edit-time-off.php @@ -0,0 +1,17 @@ + [ + 'title' => 'Time Off updated', + 'body' => 'The time off has been updated successfully.', + ], + + 'header-actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Time Off deleted', + 'body' => 'The time off has been deleted successfully.' + ] + ] + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/view-time-off.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/view-time-off.php new file mode 100644 index 00000000..c12b58db --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-time-off/pages/view-time-off.php @@ -0,0 +1,12 @@ + [ + 'delete' => [ + 'notification' => [ + 'title' => 'Time Off Deleted', + 'body' => 'The time off has been deleted successfully.', + ] + ] + ] +]; diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php index 8d5b42e2..3c41b72c 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php @@ -7,15 +7,19 @@ use Filament\Forms\Form; use Filament\Forms; use Filament\Forms\Get; +use Filament\Notifications\Notification; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; use Webkul\TimeOff\Enums\RequestDateFromPeriod; use Webkul\TimeOff\Enums\State; use Webkul\TimeOff\Models\Leave; use Webkul\TimeOff\Models\LeaveType; +use Filament\Infolists; +use Filament\Infolists\Infolist; class MyTimeOffResource extends Resource { @@ -29,6 +33,35 @@ class MyTimeOffResource extends Resource protected static ?string $cluster = MyTime::class; + public static function getModelLabel(): string + { + return __('time_off::filament/clusters/my-time/resources/my-time-off.model-label'); + } + + public static function getNavigationLabel(): string + { + return __('time_off::filament/clusters/my-time/resources/my-time-off.navigation.title'); + } + + public static function getGloballySearchableAttributes(): array + { + return [ + 'holidayStatus.name', + 'request_date_from', + 'request_date_to', + ]; + } + + public static function getGlobalSearchResultDetails(Model $record): array + { + return [ + __('time_off::filament/clusters/my-time/resources/my-time-off.global-search.time-off-type') => $record->holidayStatus?->name ?? '—', + __('time_off::filament/clusters/my-time/resources/my-time-off.global-search.request-date-from') => $record->request_date_from ?? '—', + __('time_off::filament/clusters/my-time/resources/my-time-off.global-search.request-date-to') => $record->request_date_to ?? '—', + ]; + } + + public static function form(Form $form): Form { return $form @@ -42,13 +75,14 @@ public static function form(Form $form): Form ->searchable() ->preload() ->live() + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.time-off-type')) ->required(), Forms\Components\Fieldset::make() ->label(function (Get $get) { if ($get('request_unit_half')) { - return 'Date'; + return __('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.date'); } else { - return 'Dates'; + return __('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.dates'); } }) ->live() @@ -56,43 +90,45 @@ public static function form(Form $form): Form Forms\Components\DatePicker::make('request_date_from') ->native(false) ->default(now()) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.request-date-from')) ->required(), Forms\Components\DatePicker::make('request_date_to') ->native(false) ->default(now()) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.request-date-to')) ->hidden(fn(Get $get) => $get('request_unit_half')) ->required(), Forms\Components\Select::make('request_date_from_period') - ->label('Period') ->options(RequestDateFromPeriod::class) ->default(RequestDateFromPeriod::MORNING->value) ->native(false) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.period')) ->visible(fn(Get $get) => $get('request_unit_half')) ->required(), ]), Forms\Components\Toggle::make('request_unit_half') ->live() - ->label('Half Day'), + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.half-day')), Forms\Components\Placeholder::make('requested_days') - ->label('Requested (Days/Hours)') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.requested-days')) ->live() ->inlineLabel() ->reactive() ->content(function ($state, Get $get): string { if ($get('request_unit_half')) { - return '0.5 day'; + return __('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.day', ['day' => '0.5']); } $startDate = Carbon::parse($get('request_date_from')); $endDate = $get('request_date_to') ? Carbon::parse($get('request_date_to')) : $startDate; - return $startDate->diffInDays($endDate) + 1 . ' day(s)'; + return __('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.days', ['days' => $startDate->diffInDays($endDate) + 1]); }), Forms\Components\Textarea::make('private_name') - ->label('Description') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.description')) ->live(), Forms\Components\FileUpload::make('attachment') - ->label('Attachment') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.form.fields.attachment')) ->visible(function (Get $get) { $leaveType = LeaveType::find($get('holiday_status_id')); @@ -113,31 +149,31 @@ public static function table(Table $table): Table return $table ->columns([ Tables\Columns\TextColumn::make('employee.name') - ->label(__('Employee Name')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.columns.employee-name')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('holidayStatus.name') - ->label(__('Time Off Type')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.columns.time-off-type')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('private_name') - ->label(__('Description')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.columns.description')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('date_from') - ->label(__('Date From')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.columns.date-from')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('date_to') - ->label(__('Date To')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.columns.date-to')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('duration_display') - ->label(__('Duration')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.columns.duration')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('state') - ->label(__('Status')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.columns.status')) ->formatStateUsing(fn($state) => State::options()[$state]) ->sortable() ->badge() @@ -146,23 +182,31 @@ public static function table(Table $table): Table ->groups([ Tables\Grouping\Group::make('employee.name') ->label(__('Employee Name')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.groups.employee-name')) ->collapsible(), Tables\Grouping\Group::make('holidayStatus.name') - ->label(__('Time Off Type')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.groups.time-off-type')) ->collapsible(), Tables\Grouping\Group::make('state') - ->label(__('Status')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.groups.status')) ->collapsible(), Tables\Grouping\Group::make('date_from') - ->label(__('Start Date')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.groups.start-date')) ->collapsible(), Tables\Grouping\Group::make('date_to') - ->label(__('Start To')) + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.groups.start-to')) ->collapsible(), ]) ->actions([ + Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make(), - Tables\Actions\DeleteAction::make(), + Tables\Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-time-off.table.actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-time-off.table.actions.delete.notification.body')) + ), Tables\Actions\Action::make('approve') ->icon('heroicon-o-check-circle') ->color('success') @@ -173,12 +217,18 @@ public static function table(Table $table): Table } else { $record->update(['state' => State::VALIDATE_TWO->value]); } + + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-time-off.table.actions.approve.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-time-off.table.actions.approve.notification.body')) + ->send(); }) ->label(function ($record) { if ($record->state === State::VALIDATE_ONE->value) { - return 'Validate'; + return __('time_off::filament/clusters/my-time/resources/my-time-off.table.actions.approve.title.validate'); } else { - return 'Approve'; + return __('time_off::filament/clusters/my-time/resources/my-time-off.table.actions.approve.title.approve'); } }), Tables\Actions\Action::make('refuse') @@ -187,12 +237,24 @@ public static function table(Table $table): Table ->color('danger') ->action(function ($record) { $record->update(['state' => State::REFUSE->value]); + + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-time-off.table.actions.refused.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-time-off.table.actions.refused.notification.body')) + ->send(); }) - ->label('Refuse'), + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.table.actions.refused.title')), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DeleteBulkAction::make(), + Tables\Actions\DeleteBulkAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-time-off.table.bulk-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-time-off.table.bulk-actions.delete.notification.body')) + ), ]), ]) ->modifyQueryUsing(function ($query) { @@ -209,4 +271,63 @@ public static function getPages(): array 'view' => Pages\ViewMyTimeOff::route('/{record}'), ]; } + + public static function infolist(Infolist $infolist): Infolist + { + return $infolist + ->schema([ + Infolists\Components\Section::make() + ->schema([ + Infolists\Components\Group::make() + ->schema([ + Infolists\Components\TextEntry::make('holidayStatus.name') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.time-off-type')) + ->icon('heroicon-o-calendar'), + + Infolists\Components\TextEntry::make('request_unit_half') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.half-day')) + ->formatStateUsing(fn($record) => $record->request_unit_half ? 'Yes' : 'No') + ->icon('heroicon-o-clock'), + + Infolists\Components\TextEntry::make('request_date_from') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.request-date-from')) + ->date() + ->icon('heroicon-o-calendar'), + + Infolists\Components\TextEntry::make('request_date_to') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.request-date-to')) + ->date() + ->hidden(fn($record) => $record->request_unit_half) + ->icon('heroicon-o-calendar'), + + Infolists\Components\TextEntry::make('request_date_from_period') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.period')) + ->visible(fn($record) => $record->request_unit_half) + ->icon('heroicon-o-sun'), + + Infolists\Components\TextEntry::make('private_name') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.description')) + ->icon('heroicon-o-document-text'), + + Infolists\Components\TextEntry::make('duration_display') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.requested-days')) + ->formatStateUsing(function ($record) { + if ($record->request_unit_half) { + return __('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.day', ['day' => '0.5']); + } + + $startDate = Carbon::parse($record->request_date_from); + $endDate = $record->request_date_to ? Carbon::parse($record->request_date_to) : $startDate; + + return __('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.days', ['days' => ($startDate->diffInDays($endDate) + 1)]); + }) + ->icon('heroicon-o-calendar-days'), + + Infolists\Components\ImageEntry::make('attachment') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.attachment')) + ->visible(fn($record) => $record->holidayStatus?->support_document) + ]) + ]) + ]); + } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php index b4dde541..cda67920 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php @@ -2,12 +2,11 @@ namespace Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyTimeOffResource\Pages; +use Filament\Notifications\Notification; use Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyTimeOffResource; -use Filament\Actions; use Filament\Resources\Pages\CreateRecord; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; -use Webkul\Employee\Models\Employee; use Webkul\TimeOff\Enums\State; class CreateMyTimeOff extends CreateRecord @@ -71,4 +70,12 @@ protected function mutateFormDataBeforeCreate(array $data): array return $data; } + + protected function getCreatedNotification(): Notification + { + return Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-time-off/pages/create-time-off.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-time-off/pages/create-time-off.notification.body')); + } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php index 8354a01a..2daa4962 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php @@ -4,6 +4,7 @@ use Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyTimeOffResource; use Filament\Actions; +use Filament\Notifications\Notification; use Filament\Resources\Pages\EditRecord; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; @@ -13,16 +14,31 @@ class EditMyTimeOff extends EditRecord { protected static string $resource = MyTimeOffResource::class; - protected function getHeaderActions(): array + protected function getRedirectUrl(): string { - return [ - Actions\DeleteAction::make(), - ]; + return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); } - protected function getRedirectUrl(): string + protected function getSavedNotification(): ?Notification { - return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); + return Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-time-off/pages/edit-time-off.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-time-off/pages/edit-time-off.notification.body')); + } + + protected function getHeaderActions(): array + { + return [ + Actions\ViewAction::make(), + Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-time-off/pages/edit-time-off.header-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-time-off/pages/edit-time-off.header-actions.delete.notification.body')) + ), + ]; } protected function mutateFormDataBeforeSave(array $data): array diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ListMyTimeOffs.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ListMyTimeOffs.php index baa621c1..fefe9957 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ListMyTimeOffs.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ListMyTimeOffs.php @@ -13,7 +13,8 @@ class ListMyTimeOffs extends ListRecords protected function getHeaderActions(): array { return [ - Actions\CreateAction::make(), + Actions\CreateAction::make() + ->icon('heroicon-o-plus-circle'), ]; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php index 42b71048..01307211 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php @@ -4,9 +4,11 @@ use Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyTimeOffResource; use Filament\Actions; +use Filament\Notifications\Notification; use Filament\Resources\Pages\ListRecords; +use Filament\Resources\Pages\ViewRecord; -class ViewMyTimeOff extends ListRecords +class ViewMyTimeOff extends ViewRecord { protected static string $resource = MyTimeOffResource::class; @@ -14,7 +16,13 @@ protected function getHeaderActions(): array { return [ Actions\EditAction::make(), - Actions\DeleteAction::make(), + Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-time-off/pages/view-time-off.header-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-time-off/pages/view-time-off.header-actions.delete.notification.body')) + ), ]; } } From 02edc24a2681eb9adc2d92bcdca31812a301de9e Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Fri, 24 Jan 2025 20:48:38 +0530 Subject: [PATCH 13/24] Add title methods to ByType and Overview pages for improved navigation labeling --- plugins/webkul/time-off/src/Filament/Pages/ByType.php | 5 +++++ plugins/webkul/time-off/src/Filament/Pages/Overview.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/plugins/webkul/time-off/src/Filament/Pages/ByType.php b/plugins/webkul/time-off/src/Filament/Pages/ByType.php index 2e7cc27d..ee14797f 100644 --- a/plugins/webkul/time-off/src/Filament/Pages/ByType.php +++ b/plugins/webkul/time-off/src/Filament/Pages/ByType.php @@ -16,6 +16,11 @@ class ByType extends BaseDashboard protected static ?string $cluster = Reporting::class; + public function getTitle(): string + { + return __('time_off::filament/pages/by-type.navigation.title'); + } + public static function getNavigationLabel(): string { return __('time_off::filament/pages/by-type.navigation.title'); diff --git a/plugins/webkul/time-off/src/Filament/Pages/Overview.php b/plugins/webkul/time-off/src/Filament/Pages/Overview.php index 06b73f97..b2bfa0a5 100644 --- a/plugins/webkul/time-off/src/Filament/Pages/Overview.php +++ b/plugins/webkul/time-off/src/Filament/Pages/Overview.php @@ -13,6 +13,11 @@ class Overview extends BaseDashboard protected static ?int $navigationSort = 2; + public function getTitle(): string + { + return __('time_off::filament/pages/overview.navigation.title'); + } + public static function getNavigationLabel(): string { return __('time_off::filament/pages/overview.navigation.title'); From 277721c473fcf3c35c3a80618931b62d3eb86294 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Mon, 27 Jan 2025 12:12:23 +0530 Subject: [PATCH 14/24] Add language files for notifications on create, update, and delete actions in time off and allocation resources --- .../management/resources/allocation.php | 120 ++++++++++++ .../allocation/pages/create-allocation.php | 8 + .../allocation/pages/edit-allocation.php | 41 ++++ .../allocation/pages/view-allocation.php | 12 ++ .../management/resources/time-off.php | 114 +++++++++++ .../time-off/pages/create-time-off.php | 8 + .../time-off/pages/edit-time-off.php | 17 ++ .../time-off/pages/view-time-off.php | 12 ++ .../my-time/resources/my-allocation.php | 118 +++++++++++ .../my-allocation/pages/create-allocation.php | 8 + .../my-allocation/pages/edit-allocation.php | 17 ++ .../my-allocation/pages/view-allocation.php | 12 ++ .../Resources/AllocationResource.php | 166 +++++++++++++--- .../Pages/CreateAllocation.php | 9 + .../Pages/EditAllocation.php | 41 +++- .../Pages/ViewAllocation.php | 9 +- .../Management/Resources/TimeOffResource.php | 183 ++++++++++++++---- .../TimeOffResource/Pages/CreateTimeOff.php | 9 + .../TimeOffResource/Pages/EditTimeOff.php | 23 ++- .../TimeOffResource/Pages/ViewTimeOff.php | 32 +++ .../MyTime/Resources/MyAllocationResource.php | 164 +++++++++++++--- .../Pages/CreateMyAllocation.php | 9 + .../Pages/EditMyAllocation.php | 18 +- .../Pages/ViewMyAllocation.php | 9 +- .../MyTime/Resources/MyTimeOffResource.php | 30 +-- .../MyTimeOffResource/Pages/ViewMyTimeOff.php | 1 - 26 files changed, 1075 insertions(+), 115 deletions(-) create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/create-allocation.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/edit-allocation.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/view-allocation.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/create-time-off.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/edit-time-off.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/view-time-off.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/create-allocation.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/edit-allocation.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/view-allocation.php create mode 100644 plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation.php new file mode 100644 index 00000000..b54dba68 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation.php @@ -0,0 +1,120 @@ + 'Allocation', + + 'model-label' => 'Allocation', + + 'navigation' => [ + 'title' => 'Allocation', + ], + + 'global-search' => [ + 'time-off-type' => 'Time off Type', + 'date-from' => 'Request Date From', + 'date-to' => 'Request Date To', + ], + + 'form' => [ + 'fields' => [ + 'name' => 'Name', + 'name-placeholder' => 'Time Off Type (From validity start to validity end/no limit)', + 'time-off-type' => 'Time Off Type', + 'employee-name' => 'Employee Name', + 'allocation-type' => 'Allocation Type', + 'validity-period' => 'Validity Period', + 'date-from' => 'Date From', + 'date-to' => 'Date To', + 'date-to-placeholder' => 'No Limit', + 'allocation' => 'Allocation', + 'allocation-suffix' => 'Number of Days', + 'reason' => 'Reason', + ], + ], + + 'table' => [ + 'columns' => [ + 'employee-name' => 'Employee', + 'time-off-type' => 'Time Off Type', + 'amount' => 'Amount', + 'allocation-type' => 'Allocation Type', + 'status' => 'Status', + ], + + 'groups' => [ + 'time-off-type' => 'Time Off Type', + 'employee-name' => 'Employee Name', + 'allocation-type' => 'Allocation Type', + 'status' => 'Status', + 'start-date' => 'Start Date', + ], + + 'actions' => [ + 'approve' => [ + 'title' => [ + 'validate' => 'Validate', + 'approve' => 'Approve', + ], + 'notification' => [ + 'title' => 'Allocation approved approved', + 'body' => 'The allocation approved has been approved successfully.', + ], + ], + + 'delete' => [ + 'notification' => [ + 'title' => 'Allocation deleted', + 'body' => 'The allocation has been deleted successfully.', + ], + ], + + 'refused' => [ + 'title' => 'Refuse', + 'notification' => [ + 'title' => 'Allocation refused', + 'body' => 'The allocation has been refused successfully.', + ], + ], + ], + + 'bulk-actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Allocations deleted', + 'body' => 'The allocations has been deleted successfully.', + ], + ], + ], + ], + + 'infolist' => [ + 'sections' => [ + 'allocation-details' => [ + 'title' => 'Allocation Details', + 'entries' => [ + 'name' => 'Name', + 'time-off-type' => 'Time Off Type', + 'allocation-type' => 'Allocation Type', + ], + ], + + 'validity-period' => [ + 'title' => 'Validity Period', + 'entries' => [ + 'date-from' => 'Date From', + 'date-to' => 'Date To', + 'reason' => 'Reason', + ] + ], + 'allocation-status' => [ + 'title' => 'Allocation Status', + 'entries' => [ + 'date-to-placeholder' => 'No Limit', + 'allocation' => 'Number of Day(s)', + 'allocation-value' => ':days number of days', + 'state' => 'State' + ], + ] + ], + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/create-allocation.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/create-allocation.php new file mode 100644 index 00000000..5052737b --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/create-allocation.php @@ -0,0 +1,8 @@ + [ + 'title' => 'Time Off created', + 'body' => 'The time off has been created successfully.', + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/edit-allocation.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/edit-allocation.php new file mode 100644 index 00000000..42c66db7 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/edit-allocation.php @@ -0,0 +1,41 @@ + [ + 'title' => 'Allocation updated', + 'body' => 'The allocation has been updated successfully.', + ], + + 'header-actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Allocation deleted', + 'body' => 'The allocation has been deleted successfully.' + ] + ], + 'approved' => [ + 'title' => 'Approved', + + 'notification' => [ + 'title' => 'Allocation approved', + 'body' => 'The allocation has been approved successfully.' + ] + ], + 'refuse' => [ + 'title' => 'Refuse', + + 'notification' => [ + 'title' => 'Allocation refused', + 'body' => 'The allocation has been refused successfully.' + ] + ], + 'mark-as-ready-to-confirm' => [ + 'title' => 'Mark as Ready to Confirm', + + 'notification' => [ + 'title' => 'Marked as ready to confirm', + 'body' => 'The allocation has been marked as ready to confirm successfully.' + ] + ] + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/view-allocation.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/view-allocation.php new file mode 100644 index 00000000..7677b182 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/allocation/pages/view-allocation.php @@ -0,0 +1,12 @@ + [ + 'delete' => [ + 'notification' => [ + 'title' => 'Allocation Deleted', + 'body' => 'The allocation has been deleted successfully.', + ] + ] + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off.php new file mode 100644 index 00000000..419fc3b1 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off.php @@ -0,0 +1,114 @@ + 'Time off', + + 'model-label' => 'Time off', + + 'navigation' => [ + 'title' => 'Time off', + ], + + 'global-search' => [ + 'time-off-type' => 'Time off Type', + 'request-date-from' => 'Request Date From', + 'request-date-to' => 'Request Date To', + ], + + 'form' => [ + 'fields' => [ + 'employee-name' => 'Employee Name', + 'department-name' => 'Department Name', + 'time-off-type' => 'Time off Type', + 'date' => 'Date', + 'dates' => 'Dates', + 'request-date-from' => 'Request Date From', + 'request-date-to' => 'Request Date To', + 'description' => 'Description', + 'period' => 'Period', + 'half-day' => 'Half Day', + 'requested-days' => 'Requested (Days/Hours)', + 'description' => 'Description', + 'attachment' => 'Attachment', + 'day' => ':day day', + 'days' => ':days day(s)', + ], + ], + + 'table' => [ + 'columns' => [ + 'employee-name' => 'Employee', + 'time-off-type' => 'Time Off Type', + 'description' => 'Description', + 'date-from' => 'Date From', + 'date-to' => 'Date To', + 'duration' => 'Duration', + 'status' => 'Status', + ], + + 'groups' => [ + 'employee-name' => 'Employee', + 'time-off-type' => 'Time Off Type', + 'status' => 'Status', + 'start-date' => 'Start Date', + 'start-to' => 'End Date', + 'updated-at' => 'Updated At', + 'created-at' => 'Created At', + ], + + 'actions' => [ + 'approve' => [ + 'title' => [ + 'validate' => 'Validate', + 'approve' => 'Approve', + ], + 'notification' => [ + 'title' => 'Time Off approved', + 'body' => 'The time off has been approved successfully.', + ], + ], + + 'delete' => [ + 'notification' => [ + 'title' => 'Time Off deleted', + 'body' => 'The time off has been deleted successfully.', + ], + ], + + 'refused' => [ + 'title' => 'Refuse', + 'notification' => [ + 'title' => 'Time Off refused', + 'body' => 'The time off has been refused successfully.', + ], + ], + ], + + 'bulk-actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Time Offs deleted', + 'body' => 'The time offs has been deleted successfully.', + ], + ], + ], + ], + + 'infolist' => [ + 'entries' => [ + 'time-off-type' => 'Time off Type', + 'date' => 'Date', + 'dates' => 'Dates', + 'request-date-from' => 'Request Date From', + 'request-date-to' => 'Request Date To', + 'description' => 'Description', + 'period' => 'Period', + 'half-day' => 'Half Day', + 'requested-days' => 'Requested (Days/Hours)', + 'description' => 'Description', + 'attachment' => 'Attachment', + 'day' => ':day day', + 'days' => ':days day(s)', + ], + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/create-time-off.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/create-time-off.php new file mode 100644 index 00000000..5052737b --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/create-time-off.php @@ -0,0 +1,8 @@ + [ + 'title' => 'Time Off created', + 'body' => 'The time off has been created successfully.', + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/edit-time-off.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/edit-time-off.php new file mode 100644 index 00000000..116c11f2 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/edit-time-off.php @@ -0,0 +1,17 @@ + [ + 'title' => 'Time Off updated', + 'body' => 'The time off has been updated successfully.', + ], + + 'header-actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Time Off deleted', + 'body' => 'The time off has been deleted successfully.' + ] + ] + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/view-time-off.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/view-time-off.php new file mode 100644 index 00000000..c12b58db --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/management/resources/time-off/pages/view-time-off.php @@ -0,0 +1,12 @@ + [ + 'delete' => [ + 'notification' => [ + 'title' => 'Time Off Deleted', + 'body' => 'The time off has been deleted successfully.', + ] + ] + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation.php index e69de29b..89796380 100644 --- a/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation.php +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation.php @@ -0,0 +1,118 @@ + 'My Allocation', + + 'model-label' => 'My Allocation', + + 'navigation' => [ + 'title' => 'My Allocation', + ], + + 'global-search' => [ + 'time-off-type' => 'Time off Type', + 'date-from' => 'Request Date From', + 'date-to' => 'Request Date To', + ], + + 'form' => [ + 'fields' => [ + 'name' => 'Name', + 'name-placeholder' => 'Time Off Type (From validity start to validity end/no limit)', + 'time-off-type' => 'Time Off Type', + 'allocation-type' => 'Allocation Type', + 'validity-period' => 'Validity Period', + 'date-from' => 'Date From', + 'date-to' => 'Date To', + 'date-to-placeholder' => 'No Limit', + 'allocation' => 'Allocation', + 'allocation-suffix' => 'Number of Days', + 'reason' => 'Reason', + ], + ], + + 'table' => [ + 'columns' => [ + 'time-off-type' => 'Time Off Type', + 'amount' => 'Amount', + 'allocation-type' => 'Allocation Type', + 'status' => 'Status', + ], + + 'groups' => [ + 'time-off-type' => 'Time Off Type', + 'employee-name' => 'Employee Name', + 'allocation-type' => 'Allocation Type', + 'status' => 'Status', + 'start-date' => 'Start Date', + ], + + 'actions' => [ + 'approve' => [ + 'title' => [ + 'validate' => 'Validate', + 'approve' => 'Approve', + ], + 'notification' => [ + 'title' => 'Allocation approved approved', + 'body' => 'The allocation approved has been approved successfully.', + ], + ], + + 'delete' => [ + 'notification' => [ + 'title' => 'Allocation deleted', + 'body' => 'The allocation has been deleted successfully.', + ], + ], + + 'refused' => [ + 'title' => 'Refuse', + 'notification' => [ + 'title' => 'Allocation refused', + 'body' => 'The allocation has been refused successfully.', + ], + ], + ], + + 'bulk-actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Allocations deleted', + 'body' => 'The allocations has been deleted successfully.', + ], + ], + ], + ], + + 'infolist' => [ + 'sections' => [ + 'allocation-details' => [ + 'title' => 'Allocation Details', + 'entries' => [ + 'name' => 'Name', + 'time-off-type' => 'Time Off Type', + 'allocation-type' => 'Allocation Type', + ], + ], + + 'validity-period' => [ + 'title' => 'Validity Period', + 'entries' => [ + 'date-from' => 'Date From', + 'date-to' => 'Date To', + 'reason' => 'Reason', + ] + ], + 'allocation-status' => [ + 'title' => 'Allocation Status', + 'entries' => [ + 'date-to-placeholder' => 'No Limit', + 'allocation' => 'Number of Day(s)', + 'allocation-value' => ':days number of days', + 'state' => 'State' + ], + ] + ], + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/create-allocation.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/create-allocation.php new file mode 100644 index 00000000..5052737b --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/create-allocation.php @@ -0,0 +1,8 @@ + [ + 'title' => 'Time Off created', + 'body' => 'The time off has been created successfully.', + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/edit-allocation.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/edit-allocation.php new file mode 100644 index 00000000..bfe2053e --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/edit-allocation.php @@ -0,0 +1,17 @@ + [ + 'title' => 'Allocation updated', + 'body' => 'The allocation has been updated successfully.', + ], + + 'header-actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Allocation deleted', + 'body' => 'The allocation has been deleted successfully.' + ] + ] + ] +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/view-allocation.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/view-allocation.php new file mode 100644 index 00000000..7677b182 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/my-time/resources/my-allocation/pages/view-allocation.php @@ -0,0 +1,12 @@ + [ + 'delete' => [ + 'notification' => [ + 'title' => 'Allocation Deleted', + 'body' => 'The allocation has been deleted successfully.', + ] + ] + ] +]; diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php index ff5439b3..12b9aef2 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource.php @@ -4,9 +4,13 @@ use Filament\Forms; use Filament\Forms\Form; +use Filament\Infolists\Infolist; +use Filament\Infolists; +use Filament\Notifications\Notification; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Model; use Webkul\Field\Filament\Forms\Components\ProgressStepper; use Webkul\TimeOff\Enums\AllocationType; use Webkul\TimeOff\Enums\State; @@ -24,6 +28,34 @@ class AllocationResource extends Resource protected static ?int $navigationSort = 2; + public static function getModelLabel(): string + { + return __('time_off::filament/clusters/management/resources/allocation.model-label'); + } + + public static function getNavigationLabel(): string + { + return __('time_off::filament/clusters/management/resources/allocation.navigation.title'); + } + + public static function getGloballySearchableAttributes(): array + { + return [ + 'holidayStatus.name', + 'date_from', + 'date_to', + ]; + } + + public static function getGlobalSearchResultDetails(Model $record): array + { + return [ + __('time_off::filament/clusters/management/resources/allocation.global-search.time-off-type') => $record->holidayStatus?->name ?? '—', + __('time_off::filament/clusters/management/resources/allocation.global-search.date-from') => $record->date_from ?? '—', + __('time_off::filament/clusters/management/resources/allocation.global-search.date-to') => $record->date_to ?? '—', + ]; + } + public static function form(Form $form): Form { return $form @@ -58,49 +90,49 @@ public static function form(Form $form): Form Forms\Components\Group::make() ->schema([ Forms\Components\TextInput::make('name') - ->label('Name') - ->placeholder('Time Off Type (From validity start to validity end/no limit)') + ->label(__('time_off::filament/clusters/management/resources/allocation.form.fields.name')) + ->placeholder(__('time_off::filament/clusters/management/resources/allocation.form.fields.name-placeholder')) ->required(), Forms\Components\Grid::make(2) ->schema([ Forms\Components\Select::make('holiday_status_id') - ->label('Time Off Type') + ->label(__('time_off::filament/clusters/management/resources/allocation.form.fields.time-off-type')) ->relationship('holidayStatus', 'name') ->searchable() ->preload() ->required(), Forms\Components\Select::make('employee_id') - ->label('Employee') + ->label(__('time_off::filament/clusters/management/resources/allocation.form.fields.employee-name')) ->relationship('employee', 'name') ->searchable() ->preload() ->required(), ]), Forms\Components\Radio::make('allocation_type') - ->label('Allocation Type') + ->label(__('time_off::filament/clusters/management/resources/allocation.form.fields.allocation-type')) ->options(AllocationType::class) ->default(AllocationType::REGULAR->value) ->required(), Forms\Components\Fieldset::make('Validity Period') ->schema([ Forms\Components\DatePicker::make('date_from') - ->label('From') + ->label(__('time_off::filament/clusters/management/resources/allocation.form.fields.date-from')) ->native(false) ->required() ->default(now()), Forms\Components\DatePicker::make('date_to') - ->label('To') + ->label(__('time_off::filament/clusters/management/resources/allocation.form.fields.date-to')) ->native(false) - ->placeholder('No limit'), + ->placeholder(__('time_off::filament/clusters/management/resources/allocation.form.fields.date-to-placeholder')), ]), Forms\Components\TextInput::make('number_of_days') - ->label('Allocation') + ->label(__('time_off::filament/clusters/management/resources/allocation.form.fields.allocation')) ->numeric() ->default(0) ->required() - ->suffix('Number of Days'), + ->suffix(__('time_off::filament/clusters/management/resources/allocation.form.fields.allocation-suffix')), Forms\Components\RichEditor::make('notes') - ->label('Reason'), + ->label(__('time_off::filament/clusters/management/resources/allocation.form.fields.reason')), ]), ])->columns(2), ]); @@ -111,50 +143,57 @@ public static function table(Table $table): Table return $table ->columns([ Tables\Columns\TextColumn::make('employee.name') - ->label(__('Employee Name')) + ->label(__('time_off::filament/clusters/management/resources/allocation.table.columns.employee-name')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('holidayStatus.name') - ->label(__('Time Off Type')) + ->label(__('time_off::filament/clusters/management/resources/allocation.table.columns.time-off-type')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('number_of_days') - ->label(__('Amount')) + ->label(__('time_off::filament/clusters/management/resources/allocation.table.columns.amount')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('allocation_type') ->formatStateUsing(fn($state) => AllocationType::options()[$state]) - ->label(__('Allocation Type')) + ->label(__('time_off::filament/clusters/management/resources/allocation.table.columns.allocation-type')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('state') ->formatStateUsing(fn($state) => State::options()[$state]) - ->label(__('Status')) + ->label(__('time_off::filament/clusters/management/resources/allocation.table.columns.status')) ->badge() ->sortable() ->searchable(), ]) ->groups([ Tables\Grouping\Group::make('employee.name') - ->label(__('Employee Name')) + ->label(__('time_off::filament/clusters/management/resources/allocation.table.groups.employee-name')) ->collapsible(), Tables\Grouping\Group::make('holidayStatus.name') - ->label(__('Time Off Type')) + ->label(__('time_off::filament/clusters/management/resources/allocation.table.groups.time-off-type')) ->collapsible(), Tables\Grouping\Group::make('allocation_type') - ->label(__('Allocation Type')) + ->label(__('time_off::filament/clusters/management/resources/allocation.table.groups.allocation-type')) ->collapsible(), Tables\Grouping\Group::make('state') - ->label(__('Status')) + ->label(__('time_off::filament/clusters/management/resources/allocation.table.groups.status')) ->collapsible(), Tables\Grouping\Group::make('date_from') - ->label(__('Start Date')) + ->label(__('time_off::filament/clusters/management/resources/allocation.table.groups.start-date')) ->collapsible(), ]) ->actions([ Tables\Actions\ActionGroup::make([ + Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make(), - Tables\Actions\DeleteAction::make(), + Tables\Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/allocation.table.actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/allocation.table.actions.delete.notification.body')) + ), Tables\Actions\Action::make('approve') ->icon('heroicon-o-check-circle') ->color('success') @@ -165,12 +204,18 @@ public static function table(Table $table): Table } else { $record->update(['state' => State::VALIDATE_TWO->value]); } + + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/allocation.table.actions.approve.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/allocation.table.actions.approve.notification.body')) + ->send(); }) ->label(function ($record) { if ($record->state === State::VALIDATE_ONE->value) { - return 'Validate'; + return __('time_off::filament/clusters/management/resources/allocation.table.actions.approve.title.validate'); } else { - return 'Approve'; + return __('time_off::filament/clusters/management/resources/allocation.table.actions.approve.title.approve'); } }), Tables\Actions\Action::make('refuse') @@ -179,17 +224,86 @@ public static function table(Table $table): Table ->color('danger') ->action(function ($record) { $record->update(['state' => State::REFUSE->value]); + + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/allocation.table.actions.refused.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/allocation.table.actions.refused.notification.body')) + ->send(); }) - ->label('Refuse'), + ->label(__('time_off::filament/clusters/management/resources/allocation.table.actions.refused.title')) ]), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DeleteBulkAction::make(), + Tables\Actions\DeleteBulkAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/allocation.table.bulk-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/allocation.table.bulk-actions.delete.notification.body')) + ), ]), ]); } + public static function infolist(Infolist $infolist): Infolist + { + return $infolist + ->schema([ + Infolists\Components\Grid::make(['default' => 3]) + ->schema([ + Infolists\Components\Group::make() + ->schema([ + Infolists\Components\Section::make(__('time_off::filament/clusters/management/resources/allocation.infolist.sections.allocation-details.title')) + ->schema([ + Infolists\Components\TextEntry::make('name') + ->icon('heroicon-o-calendar') + ->placeholder('—') + ->label(__('time_off::filament/clusters/management/resources/allocation.infolist.sections.allocation-details.entries.name')), + Infolists\Components\TextEntry::make('holidayStatus.name') + ->placeholder('—') + ->icon('heroicon-o-clock') + ->label(__('time_off::filament/clusters/management/resources/allocation.infolist.sections.allocation-details.entries.time-off-type')), + Infolists\Components\TextEntry::make('allocation_type') + ->placeholder('—') + ->icon('heroicon-o-queue-list') + ->formatStateUsing(fn($state) => AllocationType::options()[$state]) + ->label(__('time_off::filament/clusters/management/resources/allocation.infolist.sections.allocation-details.entries.allocation-type')), + ])->columns(2), + Infolists\Components\Section::make(__('time_off::filament/clusters/management/resources/allocation.infolist.sections.validity-period.title')) + ->schema([ + Infolists\Components\TextEntry::make('date_from') + ->label(__('time_off::filament/clusters/management/resources/allocation.infolist.sections.validity-period.entries.date-from')) + ->placeholder('—'), + Infolists\Components\TextEntry::make('date_to') + ->label(__('time_off::filament/clusters/management/resources/allocation.infolist.sections.validity-period.entries.date-to')) + ->placeholder('—'), + Infolists\Components\TextEntry::make('notes') + ->label(__('time_off::filament/clusters/management/resources/allocation.infolist.sections.validity-period.entries.reason')) + ->placeholder('—') + ->columnSpanFull(), + ]), + ])->columnSpan(2), + Infolists\Components\Group::make([ + Infolists\Components\Section::make(__('time_off::filament/clusters/management/resources/allocation.infolist.sections.allocation-status.title')) + ->schema([ + Infolists\Components\TextEntry::make('number_of_days') + ->label(__('time_off::filament/clusters/management/resources/allocation.infolist.sections.allocation-status.entries.allocation')) + ->placeholder('—') + ->icon('heroicon-o-calculator') + ->numeric(), + Infolists\Components\TextEntry::make('state') + ->placeholder('—') + ->icon('heroicon-o-flag') + ->formatStateUsing(fn($state) => State::options()[$state]) + ->label(__('time_off::filament/clusters/management/resources/allocation.infolist.sections.allocation-status.entries.state')), + ]), + ])->columnSpan(1), + ]), + ]); + } + public static function getPages(): array { return [ diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/CreateAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/CreateAllocation.php index 32aabab7..3334194d 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/CreateAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/CreateAllocation.php @@ -2,6 +2,7 @@ namespace Webkul\TimeOff\Filament\Clusters\Management\Resources\AllocationResource\Pages; +use Filament\Notifications\Notification; use Filament\Resources\Pages\CreateRecord; use Webkul\TimeOff\Filament\Clusters\Management\Resources\AllocationResource; @@ -13,4 +14,12 @@ protected function getRedirectUrl(): string { return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); } + + protected function getCreatedNotification(): Notification + { + return Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/allocation/pages/create-allocation.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/allocation/pages/create-allocation.notification.body')); + } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php index a070e776..f3849572 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php @@ -4,6 +4,7 @@ use Filament\Actions; use Filament\Actions\Action; +use Filament\Notifications\Notification; use Filament\Resources\Pages\EditRecord; use Webkul\TimeOff\Enums\State; use Webkul\TimeOff\Filament\Clusters\Management\Resources\AllocationResource; @@ -17,37 +18,69 @@ protected function getRedirectUrl(): string return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); } + protected function getSavedNotification(): ?Notification + { + return Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.notification.body')); + } + protected function getHeaderActions(): array { return [ Action::make('approved') - ->label('Approved') + ->label(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.approved.title')) ->color('gray') ->hidden(fn($record) => $record->state !== State::CONFIRM->value) ->action(function ($record) { $record->update(['state' => State::VALIDATE_TWO->value]); $this->refreshFormData(['state']); + + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.approved.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.approved.notification.body')) + ->send(); }), Action::make('refuse') - ->label('Refuse') + ->label(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.refuse.title')) ->color('gray') ->hidden(fn($record) => $record->state === State::REFUSE->value) ->action(function ($record) { $record->update(['state' => State::REFUSE->value]); $this->refreshFormData(['state']); + + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.refuse.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.refuse.notification.body')) + ->send(); }), Action::make('mark_as_ready_to_confirm') - ->label('Mark as Ready to Confirm') + ->label(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.mark-as-ready-to-confirm.title')) ->color('gray') ->visible(fn($record) => $record->state === State::REFUSE->value) ->action(function ($record) { $record->update(['state' => State::CONFIRM->value]); $this->refreshFormData(['state']); + + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.mark-as-ready-to-confirm.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.mark-as-ready-to-confirm.notification.body')) + ->send(); }), - Actions\DeleteAction::make(), + Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.delete.notification.body')) + ) ]; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php index 271d55b6..424eb78a 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php @@ -3,6 +3,7 @@ namespace Webkul\TimeOff\Filament\Clusters\Management\Resources\AllocationResource\Pages; use Filament\Actions; +use Filament\Notifications\Notification; use Filament\Resources\Pages\ViewRecord; use Webkul\TimeOff\Filament\Clusters\Management\Resources\AllocationResource; @@ -14,7 +15,13 @@ protected function getHeaderActions(): array { return [ Actions\EditAction::make(), - Actions\DeleteAction::make(), + Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/allocation/pages/view-allocation.header-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/allocation/pages/view-allocation.header-actions.delete.notification.body')) + ), ]; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php index a18833b9..37d5f7f2 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource.php @@ -6,9 +6,13 @@ use Filament\Forms\Form; use Filament\Forms\Get; use Filament\Forms\Set; +use Filament\Infolists\Infolist; +use Filament\Infolists; +use Filament\Notifications\Notification; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Carbon; use Webkul\Employee\Models\Employee; use Webkul\TimeOff\Enums\RequestDateFromPeriod; @@ -28,7 +32,34 @@ class TimeOffResource extends Resource protected static ?int $navigationSort = 1; - protected static ?string $modelLabel = 'Time Off'; + + public static function getModelLabel(): string + { + return __('time_off::filament/clusters/management/resources/time-off.model-label'); + } + + public static function getNavigationLabel(): string + { + return __('time_off::filament/clusters/management/resources/time-off.navigation.title'); + } + + public static function getGloballySearchableAttributes(): array + { + return [ + 'holidayStatus.name', + 'request_date_from', + 'request_date_to', + ]; + } + + public static function getGlobalSearchResultDetails(Model $record): array + { + return [ + __('time_off::filament/clusters/management/resources/time-off.global-search.time-off-type') => $record->holidayStatus?->name ?? '—', + __('time_off::filament/clusters/management/resources/time-off.global-search.request-date-from') => $record->request_date_from ?? '—', + __('time_off::filament/clusters/management/resources/time-off.global-search.request-date-to') => $record->request_date_to ?? '—', + ]; + } public static function form(Form $form): Form { @@ -54,39 +85,44 @@ public static function form(Form $form): Form } } }) + ->label(__('time_off::filament/clusters/management/resources/time-off.form.fields.employee-name')) ->required(), Forms\Components\Select::make('department_id') ->relationship('department', 'name') + ->label(__('time_off::filament/clusters/management/resources/time-off.form.fields.department-name')) ->searchable() ->preload() ->required(), Forms\Components\Select::make('holiday_status_id') ->relationship('holidayStatus', 'name') ->searchable() + ->label(__('time_off::filament/clusters/management/resources/time-off.form.fields.time-off-type')) ->preload() ->live() ->required(), Forms\Components\Fieldset::make() ->label(function (Get $get) { if ($get('request_unit_half')) { - return 'Date'; + return __('time_off::filament/clusters/management/resources/time-off.form.fields.date'); } else { - return 'Dates'; + return __('time_off::filament/clusters/management/resources/time-off.form.fields.dates'); } }) ->live() ->schema([ Forms\Components\DatePicker::make('request_date_from') ->native(false) + ->label(__('time_off::filament/clusters/management/resources/time-off.form.fields.request-date-from')) ->default(now()) ->required(), Forms\Components\DatePicker::make('request_date_to') ->native(false) ->default(now()) + ->label(__('time_off::filament/clusters/management/resources/time-off.form.fields.request-date-to')) ->hidden(fn(Get $get) => $get('request_unit_half')) ->required(), Forms\Components\Select::make('request_date_from_period') - ->label('Period') + ->label(__('time_off::filament/clusters/management/resources/time-off.form.fields.period')) ->options(RequestDateFromPeriod::class) ->default(RequestDateFromPeriod::MORNING->value) ->native(false) @@ -95,27 +131,28 @@ public static function form(Form $form): Form ]), Forms\Components\Toggle::make('request_unit_half') ->live() - ->label('Half Day'), + ->label(__('time_off::filament/clusters/management/resources/time-off.form.fields.half-day')), Forms\Components\Placeholder::make('requested_days') ->label('Requested (Days/Hours)') + ->label(__('time_off::filament/clusters/management/resources/time-off.form.fields.requested-days')) ->live() ->inlineLabel() ->reactive() ->content(function ($state, Get $get): string { if ($get('request_unit_half')) { - return '0.5 day'; + return __('time_off::filament/clusters/management/resources/time-off.form.fields.day', ['day' => '0.5']); } $startDate = Carbon::parse($get('request_date_from')); $endDate = $get('request_date_to') ? Carbon::parse($get('request_date_to')) : $startDate; - return $startDate->diffInDays($endDate) + 1 . ' day(s)'; + return __('time_off::filament/clusters/management/resources/time-off.form.fields.days', ['days' => $startDate->diffInDays($endDate) + 1]); }), Forms\Components\Textarea::make('private_name') - ->label('Description') + ->label(__('time_off::filament/clusters/management/resources/time-off.form.fields.description')) ->live(), Forms\Components\FileUpload::make('attachment') - ->label('Attachment') + ->label(__('time_off::filament/clusters/management/resources/time-off.form.fields.attachment')) ->visible(function (Get $get) { $leaveType = LeaveType::find($get('holiday_status_id')); @@ -136,31 +173,32 @@ public static function table(Table $table): Table return $table ->columns([ Tables\Columns\TextColumn::make('employee.name') - ->label(__('Employee Name')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.columns.employee-name')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('holidayStatus.name') - ->label(__('Time Off Type')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.columns.time-off-type')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('private_name') - ->label(__('Description')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.columns.description')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('date_from') - ->label(__('Date From')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.columns.date-from')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('date_to') - ->label(__('Date To')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.columns.date-to')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('duration_display') ->label(__('Duration')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.columns.duration')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('state') - ->label(__('Status')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.columns.status')) ->formatStateUsing(fn($state) => State::options()[$state]) ->sortable() ->badge() @@ -168,27 +206,31 @@ public static function table(Table $table): Table ]) ->groups([ Tables\Grouping\Group::make('employee.name') - ->label(__('Employee Name')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.groups.employee-name')) ->collapsible(), Tables\Grouping\Group::make('holidayStatus.name') - ->label(__('Time Off Type')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.groups.time-off-type')) ->collapsible(), Tables\Grouping\Group::make('state') - ->label(__('Status')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.groups.status')) ->collapsible(), Tables\Grouping\Group::make('date_from') - ->label(__('Start Date')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.groups.start-date')) ->collapsible(), Tables\Grouping\Group::make('date_to') - ->label(__('Start To')) + ->label(__('time_off::filament/clusters/management/resources/time-off.table.groups.start-to')) ->collapsible(), ]) - ->filters([ - // - ]) ->actions([ - Tables\Actions\DeleteAction::make(), + Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make(), + Tables\Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/time-off.table.actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/time-off.table.actions.delete.notification.body')) + ), Tables\Actions\Action::make('approve') ->icon('heroicon-o-check-circle') ->color('success') @@ -199,12 +241,18 @@ public static function table(Table $table): Table } else { $record->update(['state' => State::VALIDATE_TWO->value]); } + + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/time-off.table.actions.approve.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/time-off.table.actions.approve.notification.body')) + ->send(); }) ->label(function ($record) { if ($record->state === State::VALIDATE_ONE->value) { - return 'Validate'; + return __('time_off::filament/clusters/management/resources/time-off.table.actions.approve.title.validate'); } else { - return 'Approve'; + return __('time_off::filament/clusters/management/resources/time-off.table.actions.approve.title.approve'); } }), Tables\Actions\Action::make('refuse') @@ -213,29 +261,94 @@ public static function table(Table $table): Table ->color('danger') ->action(function ($record) { $record->update(['state' => State::REFUSE->value]); + + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/time-off.table.actions.refused.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/time-off.table.actions.refused.notification.body')) + ->send(); }) - ->label('Refuse'), + ->label(__('time_off::filament/clusters/management/resources/time-off.table.actions.refused.title')), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DeleteBulkAction::make(), + Tables\Actions\DeleteBulkAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/time-off.table.bulk-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/time-off.table.bulk-actions.delete.notification.body')) + ), ]), ]); } - public static function getRelations(): array - { - return [ - // - ]; - } - public static function getPages(): array { return [ 'index' => Pages\ListTimeOffs::route('/'), 'create' => Pages\CreateTimeOff::route('/create'), 'edit' => Pages\EditTimeOff::route('/{record}/edit'), + 'view' => Pages\ViewTimeOff::route('/{record}'), ]; } + + public static function infolist(Infolist $infolist): Infolist + { + return $infolist + ->schema([ + Infolists\Components\Section::make() + ->schema([ + Infolists\Components\Group::make() + ->schema([ + Infolists\Components\TextEntry::make('holidayStatus.name') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.time-off-type')) + ->icon('heroicon-o-calendar'), + + Infolists\Components\TextEntry::make('request_unit_half') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.half-day')) + ->formatStateUsing(fn($record) => $record->request_unit_half ? 'Yes' : 'No') + ->icon('heroicon-o-clock'), + + Infolists\Components\TextEntry::make('request_date_from') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.request-date-from')) + ->date() + ->icon('heroicon-o-calendar'), + + Infolists\Components\TextEntry::make('request_date_to') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.request-date-to')) + ->date() + ->hidden(fn($record) => $record->request_unit_half) + ->icon('heroicon-o-calendar'), + + Infolists\Components\TextEntry::make('request_date_from_period') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.period')) + ->visible(fn($record) => $record->request_unit_half) + ->icon('heroicon-o-sun'), + + Infolists\Components\TextEntry::make('private_name') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.description')) + ->icon('heroicon-o-document-text'), + + Infolists\Components\TextEntry::make('duration_display') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.requested-days')) + ->formatStateUsing(function ($record) { + if ($record->request_unit_half) { + return __('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.day', ['day' => '0.5']); + } + + $startDate = Carbon::parse($record->request_date_from); + $endDate = $record->request_date_to ? Carbon::parse($record->request_date_to) : $startDate; + + return __('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.days', ['days' => ($startDate->diffInDays($endDate) + 1)]); + }) + ->icon('heroicon-o-calendar-days'), + + Infolists\Components\ImageEntry::make('attachment') + ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.attachment')) + ->visible(fn($record) => $record->holidayStatus?->support_document) + ]) + ]) + ]); + } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php index 9728e4e1..b3e3d9e2 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php @@ -2,6 +2,7 @@ namespace Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource\Pages; +use Filament\Notifications\Notification; use Filament\Resources\Pages\CreateRecord; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; @@ -13,6 +14,14 @@ class CreateTimeOff extends CreateRecord { protected static string $resource = TimeOffResource::class; + protected function getCreatedNotification(): Notification + { + return Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/time-off/pages/create-time-off.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/time-off/pages/create-time-off.notification.body')); + } + protected function mutateFormDataBeforeCreate(array $data): array { if (isset($data['employee_id'])) { diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php index 1f3d42c8..494097ae 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php @@ -3,6 +3,7 @@ namespace Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource\Pages; use Filament\Actions; +use Filament\Notifications\Notification; use Filament\Resources\Pages\EditRecord; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; @@ -14,10 +15,30 @@ class EditTimeOff extends EditRecord { protected static string $resource = TimeOffResource::class; + protected function getRedirectUrl(): string + { + return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); + } + + protected function getSavedNotification(): ?Notification + { + return Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/time-off/pages/edit-time-off.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/time-off/pages/edit-time-off.notification.body')); + } + protected function getHeaderActions(): array { return [ - Actions\DeleteAction::make(), + Actions\ViewAction::make(), + Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/time-off/pages/edit-time-off.header-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/time-off/pages/edit-time-off.header-actions.delete.notification.body')) + ), ]; } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php new file mode 100644 index 00000000..06aa54ab --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php @@ -0,0 +1,32 @@ +successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/management/resources/time-off/pages/view-time-off.header-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/management/resources/time-off/pages/view-time-off.header-actions.delete.notification.body')) + ), + ]; + } +} diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php index 15c5bb5a..c714afb6 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource.php @@ -6,9 +6,13 @@ use Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyAllocationResource\Pages; use Filament\Forms\Form; use Filament\Forms; +use Filament\Infolists\Infolist; +use Filament\Infolists; +use Filament\Notifications\Notification; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Auth; use Webkul\Field\Filament\Forms\Components\ProgressStepper; use Webkul\TimeOff\Enums\AllocationType; @@ -27,6 +31,34 @@ class MyAllocationResource extends Resource protected static ?string $modelLabel = 'My Allocation'; + public static function getModelLabel(): string + { + return __('time_off::filament/clusters/my-time/resources/my-allocation.model-label'); + } + + public static function getNavigationLabel(): string + { + return __('time_off::filament/clusters/my-time/resources/my-allocation.navigation.title'); + } + + public static function getGloballySearchableAttributes(): array + { + return [ + 'holidayStatus.name', + 'date_from', + 'date_to', + ]; + } + + public static function getGlobalSearchResultDetails(Model $record): array + { + return [ + __('time_off::filament/clusters/my-time/resources/my-allocation.global-search.time-off-type') => $record->holidayStatus?->name ?? '—', + __('time_off::filament/clusters/my-time/resources/my-allocation.global-search.date-from') => $record->date_from ?? '—', + __('time_off::filament/clusters/my-time/resources/my-allocation.global-search.date-to') => $record->date_to ?? '—', + ]; + } + public static function form(Form $form): Form { return $form @@ -61,43 +93,43 @@ public static function form(Form $form): Form Forms\Components\Group::make() ->schema([ Forms\Components\TextInput::make('name') - ->label('Name') - ->placeholder('Time Off Type (From validity start to validity end/no limit)') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.form.fields.name')) + ->placeholder(__('time_off::filament/clusters/my-time/resources/my-allocation.form.fields.name-placeholder')) ->required(), Forms\Components\Grid::make(1) ->schema([ Forms\Components\Select::make('holiday_status_id') - ->label('Time Off Type') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.form.fields.time-off-type')) ->relationship('holidayStatus', 'name') ->searchable() ->preload() ->required(), ]), Forms\Components\Radio::make('allocation_type') - ->label('Allocation Type') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.form.fields.allocation-type')) ->options(AllocationType::class) ->default(AllocationType::REGULAR->value) ->required(), - Forms\Components\Fieldset::make('Validity Period') + Forms\Components\Fieldset::make(__('time_off::filament/clusters/my-time/resources/my-allocation.form.fields.validity-period')) ->schema([ Forms\Components\DatePicker::make('date_from') - ->label('From') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.form.fields.date-from')) ->native(false) ->required() ->default(now()), Forms\Components\DatePicker::make('date_to') - ->label('To') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.form.fields.date-to')) ->native(false) - ->placeholder('No limit'), + ->placeholder(__('time_off::filament/clusters/my-time/resources/my-allocation.form.fields.date-to-placeholder')), ]), Forms\Components\TextInput::make('number_of_days') - ->label('Allocation') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.form.fields.allocation')) ->numeric() ->default(0) ->required() - ->suffix('Number of Days'), + ->suffix(__('time_off::filament/clusters/my-time/resources/my-allocation.form.fields.allocation-suffix')), Forms\Components\RichEditor::make('notes') - ->label('Reason'), + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.form.fields.reason')), ]), ])->columns(2), ]); @@ -108,46 +140,53 @@ public static function table(Table $table): Table return $table ->columns([ Tables\Columns\TextColumn::make('holidayStatus.name') - ->label(__('Time Off Type')) + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.table.columns.time-off-type')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('number_of_days') - ->label(__('Amount')) + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.table.columns.amount')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('allocation_type') ->formatStateUsing(fn($state) => AllocationType::options()[$state]) - ->label(__('Allocation Type')) + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.table.columns.allocation-type')) ->sortable() ->searchable(), Tables\Columns\TextColumn::make('state') ->formatStateUsing(fn($state) => State::options()[$state]) - ->label(__('Status')) + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.table.columns.status')) ->badge() ->sortable() ->searchable(), ]) ->groups([ Tables\Grouping\Group::make('employee.name') - ->label(__('Employee Name')) + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.table.groups.employee-name')) ->collapsible(), Tables\Grouping\Group::make('holidayStatus.name') - ->label(__('Time Off Type')) + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.table.groups.time-off-type')) ->collapsible(), Tables\Grouping\Group::make('allocation_type') - ->label(__('Allocation Type')) + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.table.groups.allocation-type')) ->collapsible(), Tables\Grouping\Group::make('state') - ->label(__('Status')) + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.table.groups.status')) ->collapsible(), Tables\Grouping\Group::make('date_from') - ->label(__('Start Date')) + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.table.groups.start-date')) ->collapsible(), ]) ->actions([ Tables\Actions\ActionGroup::make([ + Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make(), - Tables\Actions\DeleteAction::make(), + Tables\Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-allocation.table.actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-allocation.table.actions.delete.notification.body')) + ), Tables\Actions\Action::make('approve') ->icon('heroicon-o-check-circle') ->color('success') @@ -158,12 +197,18 @@ public static function table(Table $table): Table } else { $record->update(['state' => State::VALIDATE_TWO->value]); } + + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-allocation.table.actions.approve.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-allocation.table.actions.approve.notification.body')) + ->send(); }) ->label(function ($record) { if ($record->state === State::VALIDATE_ONE->value) { - return 'Validate'; + return __('time_off::filament/clusters/my-time/resources/my-allocation.table.actions.approve.title.validate'); } else { - return 'Approve'; + return __('time_off::filament/clusters/my-time/resources/my-allocation.table.actions.approve.title.approve'); } }), Tables\Actions\Action::make('refuse') @@ -172,13 +217,25 @@ public static function table(Table $table): Table ->color('danger') ->action(function ($record) { $record->update(['state' => State::REFUSE->value]); + + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-allocation.table.actions.refused.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-allocation.table.actions.refused.notification.body')) + ->send(); }) - ->label('Refuse'), + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.table.actions.refused.title')) ]), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DeleteBulkAction::make(), + Tables\Actions\DeleteBulkAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-allocation.table.bulk-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-allocation.table.bulk-actions.delete.notification.body')) + ), ]), ]) ->modifyQueryUsing(function ($query) { @@ -186,6 +243,63 @@ public static function table(Table $table): Table }); } + public static function infolist(Infolist $infolist): Infolist + { + return $infolist + ->schema([ + Infolists\Components\Grid::make(['default' => 3]) + ->schema([ + Infolists\Components\Group::make() + ->schema([ + Infolists\Components\Section::make(__('time_off::filament/clusters/my-time/resources/my-allocation.infolist.sections.allocation-details.title')) + ->schema([ + Infolists\Components\TextEntry::make('name') + ->icon('heroicon-o-calendar') + ->placeholder('—') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.infolist.sections.allocation-details.entries.name')), + Infolists\Components\TextEntry::make('holidayStatus.name') + ->placeholder('—') + ->icon('heroicon-o-clock') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.infolist.sections.allocation-details.entries.time-off-type')), + Infolists\Components\TextEntry::make('allocation_type') + ->placeholder('—') + ->icon('heroicon-o-queue-list') + ->formatStateUsing(fn($state) => AllocationType::options()[$state]) + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.infolist.sections.allocation-details.entries.allocation-type')), + ])->columns(2), + Infolists\Components\Section::make(__('time_off::filament/clusters/my-time/resources/my-allocation.infolist.sections.validity-period.title')) + ->schema([ + Infolists\Components\TextEntry::make('date_from') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.infolist.sections.validity-period.entries.date-from')) + ->placeholder('—'), + Infolists\Components\TextEntry::make('date_to') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.infolist.sections.validity-period.entries.date-to')) + ->placeholder('—'), + Infolists\Components\TextEntry::make('notes') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.infolist.sections.validity-period.entries.reason')) + ->placeholder('—') + ->columnSpanFull(), + ]), + ])->columnSpan(2), + Infolists\Components\Group::make([ + Infolists\Components\Section::make(__('time_off::filament/clusters/my-time/resources/my-allocation.infolist.sections.allocation-status.title')) + ->schema([ + Infolists\Components\TextEntry::make('number_of_days') + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.infolist.sections.allocation-status.entries.allocation')) + ->placeholder('—') + ->icon('heroicon-o-calculator') + ->numeric(), + Infolists\Components\TextEntry::make('state') + ->placeholder('—') + ->icon('heroicon-o-flag') + ->formatStateUsing(fn($state) => State::options()[$state]) + ->label(__('time_off::filament/clusters/my-time/resources/my-allocation.infolist.sections.allocation-status.entries.state')), + ]), + ])->columnSpan(1), + ]), + ]); + } + public static function getPages(): array { return [ diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/CreateMyAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/CreateMyAllocation.php index b685c59a..b526ba70 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/CreateMyAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/CreateMyAllocation.php @@ -2,6 +2,7 @@ namespace Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyAllocationResource\Pages; +use Filament\Notifications\Notification; use Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyAllocationResource; use Filament\Resources\Pages\CreateRecord; use Illuminate\Support\Facades\Auth; @@ -15,6 +16,14 @@ protected function getRedirectUrl(): string return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); } + protected function getCreatedNotification(): Notification + { + return Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-allocation/pages/create-allocation.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-allocation/pages/create-allocation.notification.body')); + } + protected function mutateFormDataBeforeCreate(array $data): array { $user = Auth::user(); diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php index e7734867..d895df01 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php @@ -4,6 +4,7 @@ use Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyAllocationResource; use Filament\Actions; +use Filament\Notifications\Notification; use Filament\Resources\Pages\EditRecord; use Illuminate\Support\Facades\Auth; @@ -16,10 +17,25 @@ protected function getRedirectUrl(): string return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); } + protected function getSavedNotification(): ?Notification + { + return Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-allocation/pages/edit-allocation.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-allocation/pages/edit-allocation.notification.body')); + } + protected function getHeaderActions(): array { return [ - Actions\DeleteAction::make(), + Actions\ViewAction::make(), + Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-allocation/pages/edit-allocation.header-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-allocation/pages/edit-allocation.header-actions.delete.notification.body')) + ), ]; } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php index de342fa2..0bd0c04d 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php @@ -4,6 +4,7 @@ use Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyAllocationResource; use Filament\Actions; +use Filament\Notifications\Notification; use Filament\Resources\Pages\ViewRecord; class ViewMyAllocation extends ViewRecord @@ -14,7 +15,13 @@ protected function getHeaderActions(): array { return [ Actions\EditAction::make(), - Actions\DeleteAction::make(), + Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/my-time/resources/my-allocation/pages/view-allocation.header-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/my-time/resources/my-allocation/pages/view-allocation.header-actions.delete.notification.body')) + ), ]; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php index 3c41b72c..1d87af78 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource.php @@ -27,8 +27,6 @@ class MyTimeOffResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-lifebuoy'; - protected static ?string $modelLabel = 'My Time Off'; - protected static ?int $navigationSort = 2; protected static ?string $cluster = MyTime::class; @@ -61,7 +59,6 @@ public static function getGlobalSearchResultDetails(Model $record): array ]; } - public static function form(Form $form): Form { return $form @@ -281,50 +278,43 @@ public static function infolist(Infolist $infolist): Infolist Infolists\Components\Group::make() ->schema([ Infolists\Components\TextEntry::make('holidayStatus.name') - ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.time-off-type')) + ->label(__('time_off::filament/clusters/management/resources/time-off.infolist.entries.time-off-type')) ->icon('heroicon-o-calendar'), - Infolists\Components\TextEntry::make('request_unit_half') - ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.half-day')) + ->label(__('time_off::filament/clusters/management/resources/time-off.infolist.entries.half-day')) ->formatStateUsing(fn($record) => $record->request_unit_half ? 'Yes' : 'No') ->icon('heroicon-o-clock'), - Infolists\Components\TextEntry::make('request_date_from') - ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.request-date-from')) + ->label(__('time_off::filament/clusters/management/resources/time-off.infolist.entries.request-date-from')) ->date() ->icon('heroicon-o-calendar'), - Infolists\Components\TextEntry::make('request_date_to') - ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.request-date-to')) + ->label(__('time_off::filament/clusters/management/resources/time-off.infolist.entries.request-date-to')) ->date() ->hidden(fn($record) => $record->request_unit_half) ->icon('heroicon-o-calendar'), - Infolists\Components\TextEntry::make('request_date_from_period') - ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.period')) + ->label(__('time_off::filament/clusters/management/resources/time-off.infolist.entries.period')) ->visible(fn($record) => $record->request_unit_half) ->icon('heroicon-o-sun'), - Infolists\Components\TextEntry::make('private_name') - ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.description')) + ->label(__('time_off::filament/clusters/management/resources/time-off.infolist.entries.description')) ->icon('heroicon-o-document-text'), - Infolists\Components\TextEntry::make('duration_display') - ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.requested-days')) + ->label(__('time_off::filament/clusters/management/resources/time-off.infolist.entries.requested-days')) ->formatStateUsing(function ($record) { if ($record->request_unit_half) { - return __('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.day', ['day' => '0.5']); + return __('time_off::filament/clusters/management/resources/time-off.infolist.entries.day', ['day' => '0.5']); } $startDate = Carbon::parse($record->request_date_from); $endDate = $record->request_date_to ? Carbon::parse($record->request_date_to) : $startDate; - return __('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.days', ['days' => ($startDate->diffInDays($endDate) + 1)]); + return __('time_off::filament/clusters/management/resources/time-off.infolist.entries.days', ['days' => ($startDate->diffInDays($endDate) + 1)]); }) ->icon('heroicon-o-calendar-days'), - Infolists\Components\ImageEntry::make('attachment') - ->label(__('time_off::filament/clusters/my-time/resources/my-time-off.infolist.entries.attachment')) + ->label(__('time_off::filament/clusters/management/resources/time-off.infolist.entries.attachment')) ->visible(fn($record) => $record->holidayStatus?->support_document) ]) ]) diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php index 01307211..621291c9 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php @@ -5,7 +5,6 @@ use Webkul\TimeOff\Filament\Clusters\MyTime\Resources\MyTimeOffResource; use Filament\Actions; use Filament\Notifications\Notification; -use Filament\Resources\Pages\ListRecords; use Filament\Resources\Pages\ViewRecord; class ViewMyTimeOff extends ViewRecord From feac0f4e0560bb0850fe95c3f1f7458dc9d7011f Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Mon, 27 Jan 2025 12:12:38 +0530 Subject: [PATCH 15/24] Remove unused imports in ViewTimeOff page for cleaner code --- .../Resources/TimeOffResource/Pages/ViewTimeOff.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php index 06aa54ab..39ea6d8f 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php @@ -4,12 +4,7 @@ use Filament\Actions; use Filament\Notifications\Notification; -use Filament\Resources\Pages\EditRecord; use Filament\Resources\Pages\ViewRecord; -use Illuminate\Support\Carbon; -use Illuminate\Support\Facades\Auth; -use Webkul\Employee\Models\Employee; -use Webkul\TimeOff\Enums\State; use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; class ViewTimeOff extends ViewRecord From 7092ba5e6bd3acefa43c8c8f26a55bd13c4b30ae Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Mon, 27 Jan 2025 12:23:55 +0530 Subject: [PATCH 16/24] Add event title localization and fix duration calculation in CalendarWidget --- .../lang/en/filament/widgets/calendar-widget.php | 5 +++++ .../time-off/src/Filament/Widgets/CalendarWidget.php | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php b/plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php index 3a0b2528..03a20b80 100644 --- a/plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php +++ b/plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php @@ -34,6 +34,7 @@ 'description' => 'Description', ] ], + 'infolist' => [ 'entries' => [ 'time-off-type' => 'Time Off Type', @@ -44,5 +45,9 @@ 'duration' => 'Duration', 'status' => 'Status', ] + ], + + 'events' => [ + 'title' => ":name On :status: :days day(s)" ] ]; diff --git a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php index eb775fec..abb9fb7e 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php @@ -219,7 +219,7 @@ public function getFormSchema(): array $startDate = Carbon::parse($get('request_date_from')); $endDate = $get('request_date_to') ? Carbon::parse($get('request_date_to')) : $startDate; - return $startDate->diffInDays($endDate) . ' day(s)'; + return $startDate->diffInDays($endDate) + 1 . ' day(s)'; }), Forms\Components\Textarea::make('private_name') ->label(__('time_off::filament/widgets/calendar-widget.form.fields.description')), @@ -270,7 +270,11 @@ public function fetchEvents(array $fetchInfo): array ->map(function (Leave $leave) { return [ 'id' => $leave->id, - 'title' => $leave->holidayStatus?->name, + 'title' => __('time_off::filament/widgets/calendar-widget.events.title', [ + 'name' => $leave->user->name, + 'status' => $leave->holidayStatus->name, + 'days' => $leave->number_of_days, + ]), 'start' => $leave->request_date_from, 'end' => $leave->request_date_to, 'allDay' => true, From 0a75c80c1301565ef0fe4bea55892ef7399c0f93 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Mon, 27 Jan 2025 13:13:02 +0530 Subject: [PATCH 17/24] Refactor CalendarLeaves model to use creator_id instead of user_id; add language files for public holidays and enhance navigation and global search features. --- ...create_employees_calendar_leaves_table.php | 4 +- .../employees/src/Models/CalendarLeaves.php | 6 +- .../resources/mandatory-days.php | 12 ++ .../{ => pages}/list-mandatory-days.php | 0 .../resources/public-holiday.php | 91 +++++++++++++ .../pages/list-public-holiday.php | 16 +++ .../Resources/MandatoryDayResource.php | 19 ++- .../Pages/ListMandatoryDays.php | 6 +- .../Resources/PublicHolidayResource.php | 123 +++++++++++++++--- .../Pages/ListPublicHolidays.php | 20 ++- 10 files changed, 265 insertions(+), 32 deletions(-) rename plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days/{ => pages}/list-mandatory-days.php (100%) create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/public-holiday.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/public-holiday/pages/list-public-holiday.php diff --git a/plugins/webkul/employees/database/migrations/2024_12_11_100442_create_employees_calendar_leaves_table.php b/plugins/webkul/employees/database/migrations/2024_12_11_100442_create_employees_calendar_leaves_table.php index 0346f89f..2a5b5c47 100644 --- a/plugins/webkul/employees/database/migrations/2024_12_11_100442_create_employees_calendar_leaves_table.php +++ b/plugins/webkul/employees/database/migrations/2024_12_11_100442_create_employees_calendar_leaves_table.php @@ -21,11 +21,11 @@ public function up(): void $table->unsignedBigInteger('company_id')->nullable(); $table->unsignedBigInteger('calendar_id')->nullable(); - $table->unsignedBigInteger('user_id')->nullable(); + $table->unsignedBigInteger('creator_id')->nullable(); $table->foreign('company_id')->references('id')->on('companies')->onDelete('set null'); $table->foreign('calendar_id')->references('id')->on('employees_calendars')->onDelete('set null'); - $table->foreign('user_id')->references('id')->on('users')->onDelete('set null'); + $table->foreign('creator_id')->references('id')->on('users')->onDelete('set null'); $table->timestamps(); }); diff --git a/plugins/webkul/employees/src/Models/CalendarLeaves.php b/plugins/webkul/employees/src/Models/CalendarLeaves.php index 5a2e02b9..1a8add47 100644 --- a/plugins/webkul/employees/src/Models/CalendarLeaves.php +++ b/plugins/webkul/employees/src/Models/CalendarLeaves.php @@ -20,12 +20,12 @@ class CalendarLeaves extends Model 'date_to', 'company_id', 'calendar_id', - 'user_id', + 'creator_id', ]; - public function user() + public function createdBy() { - return $this->belongsTo(User::class); + return $this->belongsTo(User::class, 'creator_id'); } public function calendar() diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days.php index 639161d4..db293386 100644 --- a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days.php +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days.php @@ -3,6 +3,18 @@ return [ 'title' => 'Mandatory Days', + 'model-label' => 'Mandatory Day', + + 'navigation' => [ + 'title' => 'Mandatory Days', + ], + + 'global-search' => [ + 'name' => 'Name', + 'start-date' => 'Start Date', + 'end-date' => 'End Date', + ], + 'form' => [ 'fields' => [ 'name' => 'Name', diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days/list-mandatory-days.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days/pages/list-mandatory-days.php similarity index 100% rename from plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days/list-mandatory-days.php rename to plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days/pages/list-mandatory-days.php diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/public-holiday.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/public-holiday.php new file mode 100644 index 00000000..d7299fb5 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/public-holiday.php @@ -0,0 +1,91 @@ + 'Public Holidays', + + 'model-label' => 'Public holiday', + + 'navigation' => [ + 'title' => 'Public Holidays', + ], + + 'global-search' => [ + 'name' => 'Name', + 'date-from' => 'Start Date', + 'date-to' => 'End Date', + ], + + 'form' => [ + 'fields' => [ + 'name' => 'Name', + 'name-placeholder' => 'Enter the name of the public holiday', + 'date-from' => 'Start Date', + 'date-to' => 'End Date', + 'color' => 'Color', + 'calendar' => 'Calendar', + ], + ], + + 'table' => [ + 'columns' => [ + 'name' => 'Name', + 'company-name' => 'Company Name', + 'calendar' => 'Calendar', + 'created-by' => 'Created By', + 'date-from' => 'Start Date', + 'date-to' => 'End Date', + ], + + 'filters' => [ + 'name' => 'Name', + 'company-name' => 'Company Name', + 'created-by' => 'Created By', + 'date-from' => 'Start Date', + 'date-to' => 'End Date', + 'created-at' => 'Created At', + 'updated-at' => 'Updated At', + ], + + 'groups' => [ + 'name' => 'Name', + 'company-name' => 'Company Name', + 'created-by' => 'Created By', + 'date-from' => 'Start Date', + 'date-to' => 'End Date', + ], + + 'actions' => [ + 'edit' => [ + 'notification' => [ + 'title' => 'Public holiday updated', + 'body' => 'The public holiday has been restored successfully.', + ], + ], + + 'delete' => [ + 'notification' => [ + 'title' => 'Public holiday deleted', + 'body' => 'The public holiday has been deleted successfully.', + ], + ], + ], + + 'bulk-actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Public holidays deleted', + 'body' => 'The public holidays has been deleted successfully.', + ], + ], + ], + ], + + 'infolist' => [ + 'entries' => [ + 'name' => 'Name', + 'date-from' => 'Start Date', + 'date-to' => 'End Date', + 'color' => 'Color', + ], + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/public-holiday/pages/list-public-holiday.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/public-holiday/pages/list-public-holiday.php new file mode 100644 index 00000000..ae9f1d8b --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/public-holiday/pages/list-public-holiday.php @@ -0,0 +1,16 @@ + [ + 'create' => [ + 'title' => 'New Mandatory Day', + + 'notification' => [ + 'created' => [ + 'title' => 'Mandatory day created', + 'body' => 'The mandatory day has been created successfully.', + ], + ], + ], + ], +]; diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php index 6e292235..12ca990b 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource.php @@ -10,6 +10,7 @@ use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Model; use Webkul\TimeOff\Filament\Clusters\Configurations; use Webkul\TimeOff\Filament\Clusters\Configurations\Resources\MandatoryDayResource\Pages; use Webkul\TimeOff\Models\LeaveMandatoryDay; @@ -29,12 +30,26 @@ public static function getModelLabel(): string return __('time_off::filament/clusters/configurations/resources/mandatory-days.title'); } + public static function getNavigationLabel(): string + { + return __('time_off::filament/clusters/configurations/resources/mandatory-days.navigation.title'); + } + public static function getGloballySearchableAttributes(): array { return [ 'name', - 'company.name', - 'createdBy.name', + 'start_date', + 'end_date', + ]; + } + + public static function getGlobalSearchResultDetails(Model $record): array + { + return [ + __('time_off::filament/clusters/configurations/resources/mandatory-days.global-search.name') => $record->name ?? '—', + __('time_off::filament/clusters/configurations/resources/mandatory-days.global-search.start-date') => $record->start_date ?? '—', + __('time_off::filament/clusters/configurations/resources/mandatory-days.global-search.end-date') => $record->end_date ?? '—', ]; } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource/Pages/ListMandatoryDays.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource/Pages/ListMandatoryDays.php index befc6058..5763b388 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource/Pages/ListMandatoryDays.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/MandatoryDayResource/Pages/ListMandatoryDays.php @@ -16,13 +16,13 @@ protected function getHeaderActions(): array { return [ Actions\CreateAction::make() - ->label(__('time_off::filament/clusters/configurations/resources/mandatory-days/list-mandatory-days.header-actions.create.title')) + ->label(__('time_off::filament/clusters/configurations/resources/mandatory-days/pages/list-mandatory-days.header-actions.create.title')) ->icon('heroicon-o-plus-circle') ->successNotification( Notification::make() ->success() - ->title(__('time_off::filament/clusters/configurations/resources/mandatory-days/list-mandatory-days.header-actions.create.notification.created.title')) - ->body(__('time_off::filament/clusters/configurations/resources/mandatory-days/list-mandatory-days.header-actions.create.notification.created.body')) + ->title(__('time_off::filament/clusters/configurations/resources/mandatory-days/pages/list-mandatory-days.header-actions.create.notification.created.title')) + ->body(__('time_off::filament/clusters/configurations/resources/mandatory-days/pages/list-mandatory-days.header-actions.create.notification.created.body')) ) ->mutateFormDataUsing(function ($data) { $user = Auth::user(); diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php index c4f7876f..b003104f 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php @@ -8,9 +8,11 @@ use Filament\Forms; use Filament\Infolists\Infolist; use Filament\Infolists; +use Filament\Notifications\Notification; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Model; use Webkul\Employee\Models\CalendarLeaves; class PublicHolidayResource extends Resource @@ -25,6 +27,34 @@ class PublicHolidayResource extends Resource protected static ?string $modelLabel = 'Public Holiday'; + public static function getModelLabel(): string + { + return __('time_off::filament/clusters/configurations/resources/public-holiday.title'); + } + + public static function getNavigationLabel(): string + { + return __('time_off::filament/clusters/configurations/resources/public-holiday.navigation.title'); + } + + public static function getGloballySearchableAttributes(): array + { + return [ + 'name', + 'date_from', + 'date_to', + ]; + } + + public static function getGlobalSearchResultDetails(Model $record): array + { + return [ + __('time_off::filament/clusters/configurations/resources/public-holiday.global-search.name') => $record->name ?? '—', + __('time_off::filament/clusters/configurations/resources/public-holiday.global-search.date-from') => $record->date_from ?? '—', + __('time_off::filament/clusters/configurations/resources/public-holiday.global-search.date-to') => $record->date_to ?? '—', + ]; + } + public static function form(Form $form): Form { return $form @@ -35,24 +65,25 @@ public static function form(Form $form): Form Forms\Components\Hidden::make('time_type') ->default('leave'), Forms\Components\TextInput::make('name') - ->label('Name') + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.form.fields.name')) ->required() - ->placeholder('Enter the name of the public holiday'), + ->placeholder(__('time_off::filament/clusters/configurations/resources/public-holiday.form.fields.name-placeholder')), ])->columns(2), Forms\Components\Group::make() ->schema([ Forms\Components\DatePicker::make('date_from') - ->label('Date From') + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.form.fields.date-from')) ->native(false) ->required(), Forms\Components\DatePicker::make('date_to') - ->label('Date To') + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.form.fields.date-to')) ->required() ->native(false), ])->columns(2), Forms\Components\Select::make('calendar') ->searchable() + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.form.fields.calendar')) ->preload() ->relationship('calendar', 'name'), ]), @@ -66,33 +97,83 @@ public static function table(Table $table): Table Tables\Columns\TextColumn::make('name') ->searchable() ->sortable() - ->label('Name'), + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.columns.name')), Tables\Columns\TextColumn::make('date_from') ->sortable() - ->label('Date From'), + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.columns.date-from')), Tables\Columns\TextColumn::make('date_to') ->sortable() - ->label('Date To'), + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.columns.date-to')), Tables\Columns\TextColumn::make('calendar.name') ->sortable() - ->label('Calendar'), + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.columns.calendar')), ]) ->groups([ Tables\Grouping\Group::make('date_from') - ->label(__('Date From')) + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.groups.date-from')) ->collapsible(), Tables\Grouping\Group::make('date_to') - ->label(__('Date To')) + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.groups.date-to')) + ->collapsible(), + Tables\Grouping\Group::make('company.name') + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.groups.company-name')) ->collapsible(), ]) + ->filters([ + Tables\Filters\SelectFilter::make('company_id') + ->relationship('company', 'name') + ->searchable() + ->preload() + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.filters.company-name')), + Tables\Filters\SelectFilter::make('creator_id') + ->relationship('createdBy', 'name') + ->searchable() + ->preload() + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.filters.created-by')), + Tables\Filters\QueryBuilder::make() + ->constraintPickerColumns(2) + ->constraints([ + Tables\Filters\QueryBuilder\Constraints\TextConstraint::make('name') + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.filters.name')) + ->icon('heroicon-o-clock'), + Tables\Filters\QueryBuilder\Constraints\TextConstraint::make('date_from') + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.filters.date-from')) + ->icon('heroicon-o-calendar'), + Tables\Filters\QueryBuilder\Constraints\TextConstraint::make('date_to') + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.filters.date-to')) + ->icon('heroicon-o-calendar'), + Tables\Filters\QueryBuilder\Constraints\DateConstraint::make('created_at') + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.filters.created-at')), + Tables\Filters\QueryBuilder\Constraints\DateConstraint::make('updated_at') + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.table.filters.updated-at')), + ]), + ]) ->actions([ Tables\Actions\ViewAction::make(), - Tables\Actions\EditAction::make(), - Tables\Actions\DeleteAction::make(), + Tables\Actions\EditAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/configurations/resources/public-holiday.table.actions.edit.notification.title')) + ->body(__('time_off::filament/clusters/configurations/resources/public-holiday.table.actions.edit.notification.body')), + ), + Tables\Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/configurations/resources/public-holiday.table.actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/configurations/resources/public-holiday.table.actions.delete.notification.body')), + ), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DeleteBulkAction::make(), + Tables\Actions\DeleteBulkAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/configurations/resources/public-holiday.table.bulk-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/configurations/resources/public-holiday.table.bulk-actions.delete.notification.body')), + ), ]), ]); } @@ -101,22 +182,22 @@ public static function infolist(Infolist $infolist): Infolist { return $infolist ->schema([ - Infolists\Components\ColorEntry::make('name') + Infolists\Components\ColorEntry::make('color') ->placeholder('—') - ->label(__('Name')), + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.infolist.entries.color')), + Infolists\Components\TextEntry::make('name') + ->placeholder('-') + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.infolist.entries.name')), Infolists\Components\TextEntry::make('date_from') + ->date() ->placeholder('-') ->icon('heroicon-o-calendar') - ->label(__('Date From')), + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.infolist.entries.date-from')), Infolists\Components\TextEntry::make('date_to') ->date() ->placeholder('-') ->icon('heroicon-o-calendar') - ->label(__('Date To')), - Infolists\Components\TextEntry::make('calendar.name') - ->placeholder('-') - ->icon('heroicon-o-clock') - ->label(__('Working Hours')), + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday.infolist.entries.date-to')), ]); } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource/Pages/ListPublicHolidays.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource/Pages/ListPublicHolidays.php index d9b2cc60..fc6f0b64 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource/Pages/ListPublicHolidays.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource/Pages/ListPublicHolidays.php @@ -4,7 +4,9 @@ use Webkul\TimeOff\Filament\Clusters\Configurations\Resources\PublicHolidayResource; use Filament\Actions; +use Filament\Notifications\Notification; use Filament\Resources\Pages\ListRecords; +use Illuminate\Support\Facades\Auth; class ListPublicHolidays extends ListRecords { @@ -13,7 +15,23 @@ class ListPublicHolidays extends ListRecords protected function getHeaderActions(): array { return [ - Actions\CreateAction::make(), + Actions\CreateAction::make() + ->label(__('time_off::filament/clusters/configurations/resources/public-holiday/pages/list-public-holiday.header-actions.create.title')) + ->icon('heroicon-o-plus-circle') + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/configurations/resources/public-holiday/pages/list-public-holiday.header-actions.create.notification.created.title')) + ->body(__('time_off::filament/clusters/configurations/resources/public-holiday/pages/list-public-holiday.header-actions.create.notification.created.body')) + ) + ->mutateFormDataUsing(function ($data) { + $user = Auth::user(); + + $data['company_id'] = $user->default_company_id; + $data['creator_id'] = $user->id; + + return $data; + }), ]; } } From 4200af744df88e3434c85195f50b63593db36fe7 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Mon, 27 Jan 2025 13:43:16 +0530 Subject: [PATCH 18/24] Add language files for Accrual Plan management and enhance notifications for create, update, and delete actions --- .../configurations/resources/accrual-plan.php | 61 +++++++++++++++ .../pages/create-accrual-plan.php | 8 ++ .../accrual-plan/pages/edit-accrual-plan.php | 17 ++++ .../accrual-plan/pages/list-accrual-plan.php | 7 ++ .../accrual-plan/pages/manage-milestone.php | 7 ++ .../Resources/AccrualPlanResource.php | 78 ++++++++++++++----- .../Pages/CreateAccrualPlan.php | 14 ++++ .../Pages/EditAccrualPlan.php | 22 +++++- .../Pages/ListAccrualPlans.php | 4 +- .../Pages/ManageMilestone.php | 2 +- .../Pages/ViewAccrualPlan.php | 8 ++ .../Resources/ActivityTypeResource.php | 5 -- 12 files changed, 207 insertions(+), 26 deletions(-) create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/create-accrual-plan.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/edit-accrual-plan.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/list-accrual-plan.php create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/manage-milestone.php diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan.php new file mode 100644 index 00000000..0e6d3371 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan.php @@ -0,0 +1,61 @@ + 'Accrual Plan', + 'navigation' => [ + 'title' => 'Accrual Plan', + ], + + 'global-search' => [ + 'name' => 'Name', + 'time-off-type' => 'Time Off Type', + 'created-by' => 'Created By', + ], + + 'form' => [ + 'fields' => [ + 'name' => 'Title', + 'is-based-on-worked-time' => 'Is Based on Worked Time', + 'accrued-gain-time' => 'Accrued Gain Time', + 'carry-over-time' => 'Carry Over Time', + 'carry-over-date' => 'Carry Over Date', + 'status' => 'Status', + ], + ], + + 'table' => [ + 'columns' => [ + 'name' => 'Name', + 'levels' => 'Levels', + ], + + 'actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Accrual Plan deleted', + 'body' => 'The Accrual Plan has been deleted successfully.', + ], + ], + ], + + 'bulk-actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Accrual Plan deleted', + 'body' => 'The Accrual Plan has been deleted successfully.', + ], + ], + ], + ], + + 'infolist' => [ + 'entries' => [ + 'name' => 'Name', + 'is-based-on-worked-time' => 'Is Based on Worked Time', + 'accrued-gain-time' => 'Accrued Gain Time', + 'carry-over-time' => 'Carry Over Time', + 'carry-over-day' => 'Carry Over Day', + 'carry-over-month' => 'Carry Over Month', + ] + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/create-accrual-plan.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/create-accrual-plan.php new file mode 100644 index 00000000..51d4e6dd --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/create-accrual-plan.php @@ -0,0 +1,8 @@ + [ + 'title' => 'Accrual Plan Created', + 'body' => 'The accrual plan has been created successfully.', + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/edit-accrual-plan.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/edit-accrual-plan.php new file mode 100644 index 00000000..f7f7ebde --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/edit-accrual-plan.php @@ -0,0 +1,17 @@ + [ + 'title' => 'Accrual Type updated', + 'body' => 'The accrual Type has been updated successfully.', + ], + + 'header-actions' => [ + 'delete' => [ + 'notification' => [ + 'title' => 'Accrual Type deleted', + 'body' => 'The accrual type has been deleted successfully.', + ], + ], + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/list-accrual-plan.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/list-accrual-plan.php new file mode 100644 index 00000000..da673eb2 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/list-accrual-plan.php @@ -0,0 +1,7 @@ + [ + 'new-leave-type' => 'New Leave Type', + ], +]; diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/manage-milestone.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/manage-milestone.php new file mode 100644 index 00000000..dd690718 --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/manage-milestone.php @@ -0,0 +1,7 @@ + [ + 'label' => 'Manage Milestone', + ] +]; diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php index 7fd19cda..aa51dffc 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php @@ -7,6 +7,7 @@ use Filament\Forms\Get; use Filament\Infolists; use Filament\Infolists\Infolist; +use Filament\Notifications\Notification; use Filament\Pages\SubNavigationPosition; use Filament\Resources\Pages\Page; use Filament\Resources\RelationManagers\RelationGroup; @@ -14,6 +15,7 @@ use Filament\Support\Enums\MaxWidth; use Filament\Tables; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Route; use Webkul\TimeOff\Enums\AccruedGainTime; use Webkul\TimeOff\Enums\CarryoverDate; @@ -45,7 +47,33 @@ public static function getSubNavigationPosition(): SubNavigationPosition public static function getModelLabel(): string { - return __('Accrual Plan'); + return __('time_off::filament/clusters/configurations/resources/accrual-plan.title'); + } + + public static function getNavigationLabel(): string + { + return __('time_off::filament/clusters/configurations/resources/accrual-plan.navigation.title'); + } + + public static function getGloballySearchableAttributes(): array + { + return [ + 'name', + 'timeOffType.name', + 'company_id', + 'transition_mode' + ]; + } + + public static function getGlobalSearchResultDetails(Model $record): array + { + return [ + __('time_off::filament/clusters/configurations/resources/accrual-plan.global-search.name') => $record->name ?? '—', + __('time_off::filament/clusters/configurations/resources/accrual-plan.global-search.time-off-type') => $record?->timeOffType?->name ?? '—', + __('time_off::filament/clusters/configurations/resources/accrual-plan.global-search.company-name') => $record?->company?->name ?? '—', + __('time_off::filament/clusters/configurations/resources/accrual-plan.global-search.transition_mode') => $record?->transition_mode ?? '—', + + ]; } public static function form(Form $form): Form @@ -58,24 +86,28 @@ public static function form(Form $form): Form ->schema([ Forms\Components\TextInput::make('name') ->label(__('Name')) - ->required() - ->placeholder(__('Name')), + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.form.fields.name')) + ->required(), Forms\Components\Toggle::make('is_based_on_worked_time') ->inline(false) - ->label(__('Is Based On Worked Time')), + ->label(__('Is Based On Worked Time')) + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.form.fields.is-based-on-worked-time')), Forms\Components\Radio::make('accrued_gain_time') ->label(__('Accrued Gain Time')) + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.form.fields.accrued-gain-time')) ->options(AccruedGainTime::class) ->default(AccruedGainTime::END->value) ->required(), Forms\Components\Radio::make('carryover_date') ->label(__('Carry-Over Time')) + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.form.fields.carry-over-time')) ->options(CarryoverDate::class) ->default(CarryoverDate::OTHER->value) ->live() ->required(), Forms\Components\Fieldset::make() ->label('Carry-Over Date') + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.form.fields.carry-over-date')) ->live() ->visible(function (Get $get) { return $get('carryover_date') === CarryoverDate::OTHER->value; @@ -95,7 +127,8 @@ public static function form(Form $form): Form ])->columns(2), Forms\Components\Toggle::make('is_active') ->inline(false) - ->label(__('Status')), + ->label(__('Status')) + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.form.fields.status')) ]), ])->columns(2), ]); @@ -107,23 +140,30 @@ public static function table(Table $table): Table ->columns([ Tables\Columns\TextColumn::make('name') ->searchable() - ->label(__('Name')), + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.table.columns.name')), Tables\Columns\TextColumn::make('leaveAccrualLevels') ->searchable() ->formatStateUsing(fn($record) => $record->leaveAccrualLevels?->count()) - ->label(__('Levels')), - ]) - ->filters([ - // + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.table.columns.levels')), ]) ->actions([ Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make(), - Tables\Actions\DeleteAction::make(), + Tables\Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->title(__('time_off::filament/clusters/configurations/resources/accrual-plan.table.actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/configurations/resources/accrual-plan.table.actions.delete.notification.body')) + ), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DeleteBulkAction::make(), + Tables\Actions\DeleteBulkAction::make() + ->successNotification( + Notification::make() + ->title(__('time_off::filament/clusters/configurations/resources/accrual-plan.table.bulk-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/configurations/resources/accrual-plan.table.bulk-actions.delete.notification.body')) + ), ]), ]); } @@ -141,30 +181,32 @@ public static function infolist(Infolist $infolist): Infolist Infolists\Components\TextEntry::make('name') ->icon('heroicon-o-user') ->placeholder('—') - ->label(__('Name')), + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.infolist.entries.name')), Infolists\Components\IconEntry::make('is_based_on_worked_time') ->boolean() - ->label(__('Is Based On Worked Time')), + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.infolist.entries.is-based-on-worked-time')), Infolists\Components\TextEntry::make('accrued_gain_time') ->icon('heroicon-o-clock') ->placeholder('—') ->formatStateUsing(fn($state) => AccruedGainTime::options()[$state]) - ->label(__('Accrued Gain Time')), + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.infolist.entries.accrued-gain-time')), Infolists\Components\TextEntry::make('carryover_date') ->icon('heroicon-o-calendar') ->placeholder('—') ->formatStateUsing(fn($state) => CarryoverDate::options()[$state]) - ->label(__('Carryover Time')), + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.infolist.entries.carry-over-time')), Infolists\Components\TextEntry::make('carryover_day') ->icon('heroicon-o-calendar') ->placeholder('—') ->formatStateUsing(fn($state) => CarryoverDay::options()[$state]) - ->label(__('Carryover Day')), + ->label(__('Carryover Day')) + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.infolist.entries.carry-over-day')), Infolists\Components\TextEntry::make('carryover_month') ->icon('heroicon-o-calendar') ->placeholder('—') ->formatStateUsing(fn($state) => CarryoverMonth::options()[$state]) - ->label(__('Carryover Month')), + ->label(__('Carryover Month')) + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan.infolist.entries.carry-over-month')), ]), ]) ->columnSpan(2), diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/CreateAccrualPlan.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/CreateAccrualPlan.php index e4b9163c..d3b96d12 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/CreateAccrualPlan.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/CreateAccrualPlan.php @@ -2,6 +2,7 @@ namespace Webkul\TimeOff\Filament\Clusters\Configurations\Resources\AccrualPlanResource\Pages; +use Filament\Notifications\Notification; use Filament\Resources\Pages\CreateRecord; use Illuminate\Support\Facades\Auth; use Webkul\TimeOff\Filament\Clusters\Configurations\Resources\AccrualPlanResource; @@ -10,6 +11,19 @@ class CreateAccrualPlan extends CreateRecord { protected static string $resource = AccrualPlanResource::class; + protected function getRedirectUrl(): string + { + return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); + } + + protected function getCreatedNotification(): ?Notification + { + return Notification::make() + ->success() + ->title(__('time_off::filament/clusters/configurations/resources/accrual-plan/pages/create-accrual-plan.notification.title')) + ->body(__('time_off::filament/clusters/configurations/resources/accrual-plan/pages/create-accrual-plan.notification.body')); + } + protected function mutateFormDataBeforeCreate(array $data): array { $user = Auth::user(); diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/EditAccrualPlan.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/EditAccrualPlan.php index 5e434b1f..7f5d8c4c 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/EditAccrualPlan.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/EditAccrualPlan.php @@ -3,6 +3,7 @@ namespace Webkul\TimeOff\Filament\Clusters\Configurations\Resources\AccrualPlanResource\Pages; use Filament\Actions; +use Filament\Notifications\Notification; use Filament\Resources\Pages\EditRecord; use Illuminate\Support\Facades\Auth; use Webkul\TimeOff\Filament\Clusters\Configurations\Resources\AccrualPlanResource; @@ -11,11 +12,30 @@ class EditAccrualPlan extends EditRecord { protected static string $resource = AccrualPlanResource::class; + protected function getRedirectUrl(): string + { + return $this->getResource()::getUrl('view', ['record' => $this->getRecord()]); + } + + protected function getSavedNotification(): Notification + { + return Notification::make() + ->success() + ->title(__('time_off::filament/clusters/configurations/resources/accrual-plan/pages/edit-accrual-plan.notification.title')) + ->body(__('time_off::filament/clusters/configurations/resources/accrual-plan/pages/edit-accrual-plan.notification.body')); + } + protected function getHeaderActions(): array { return [ Actions\ViewAction::make(), - Actions\DeleteAction::make(), + Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/configurations/resources/accrual-plan/pages/edit-accrual-plan.header-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/configurations/resources/accrual-plan/pages/edit-accrual-plan.header-actions.delete.notification.body')) + ), ]; } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ListAccrualPlans.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ListAccrualPlans.php index 43f00ec6..3aa30037 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ListAccrualPlans.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ListAccrualPlans.php @@ -13,7 +13,9 @@ class ListAccrualPlans extends ListRecords protected function getHeaderActions(): array { return [ - Actions\CreateAction::make(), + Actions\CreateAction::make() + ->label(__('time_off::filament/clusters/configurations/resources/accrual-plan/pages/list-accrual-plan.header-actions.new-accrual-plan')) + ->icon('heroicon-o-plus-circle'), ]; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ManageMilestone.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ManageMilestone.php index 8ccdba0e..86d93c32 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ManageMilestone.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ManageMilestone.php @@ -18,6 +18,6 @@ class ManageMilestone extends ManageRelatedRecords public static function getNavigationLabel(): string { - return __('Manage Milestones'); + return __('time_off::filament/clusters/configurations/resources/accrual-plan/pages/manage-milestone.navigation.label'); } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ViewAccrualPlan.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ViewAccrualPlan.php index 7dfc6917..8c6b0b27 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ViewAccrualPlan.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource/Pages/ViewAccrualPlan.php @@ -3,6 +3,7 @@ namespace Webkul\TimeOff\Filament\Clusters\Configurations\Resources\AccrualPlanResource\Pages; use Filament\Actions; +use Filament\Notifications\Notification; use Filament\Resources\Pages\ViewRecord; use Webkul\TimeOff\Filament\Clusters\Configurations\Resources\AccrualPlanResource; @@ -14,6 +15,13 @@ protected function getHeaderActions(): array { return [ Actions\EditAction::make(), + Actions\DeleteAction::make() + ->successNotification( + Notification::make() + ->success() + ->title(__('time_off::filament/clusters/configurations/resources/leave-type/pages/view-leave-type.header-actions.delete.notification.title')) + ->body(__('time_off::filament/clusters/configurations/resources/leave-type/pages/view-leave-type.header-actions.delete.notification.body')) + ), ]; } } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/ActivityTypeResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/ActivityTypeResource.php index 8a362e29..2c268711 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/ActivityTypeResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/ActivityTypeResource.php @@ -16,11 +16,6 @@ class ActivityTypeResource extends BaseActivityTypeResource protected static ?int $navigationSort = 5; - public static function getModelLabel(): string - { - return __('Activity Type'); - } - public static function getPages(): array { return [ From 0e0141a003547f98810c33a7277c8f7e9aa20d50 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Mon, 27 Jan 2025 16:02:07 +0530 Subject: [PATCH 19/24] Add HolidayAction and localization for holiday management in CalendarWidget --- .../en/filament/actions/holiday-action.php | 11 ++ .../src/Filament/Actions/HolidayAction.php | 106 ++++++++++++++++++ .../src/Filament/Widgets/CalendarWidget.php | 2 + 3 files changed, 119 insertions(+) create mode 100644 plugins/webkul/time-off/resources/lang/en/filament/actions/holiday-action.php create mode 100644 plugins/webkul/time-off/src/Filament/Actions/HolidayAction.php diff --git a/plugins/webkul/time-off/resources/lang/en/filament/actions/holiday-action.php b/plugins/webkul/time-off/resources/lang/en/filament/actions/holiday-action.php new file mode 100644 index 00000000..f226dc0e --- /dev/null +++ b/plugins/webkul/time-off/resources/lang/en/filament/actions/holiday-action.php @@ -0,0 +1,11 @@ + 'Holidays', + 'form' => [ + 'placeholders' => [ + 'public-holiday' => 'Public Holidays', + 'mandatory-holiday' => 'Mandatory Holidays' + ] + ] +]; diff --git a/plugins/webkul/time-off/src/Filament/Actions/HolidayAction.php b/plugins/webkul/time-off/src/Filament/Actions/HolidayAction.php new file mode 100644 index 00000000..00e6c40e --- /dev/null +++ b/plugins/webkul/time-off/src/Filament/Actions/HolidayAction.php @@ -0,0 +1,106 @@ +hiddenLabel() + ->icon('heroicon-s-ellipsis-vertical') + ->modalWidth(MaxWidth::TwoExtraLarge) + ->slideOver() + ->form([ + Forms\Components\Placeholder::make('public_holiday') + ->label(__('time_off::filament/actions/holiday-action.form.placeholders.public-holiday')) + ->content(function () { + $publicHolidays = CalendarLeaves::with('company')->get(); + + if ($publicHolidays->isEmpty()) { + return new HtmlString('

No public holidays found.

'); + } + + $html = '
'; + + foreach ($publicHolidays as $holiday) { + $dateRange = $holiday->date_from === $holiday->date_to + ? $holiday->date_from + : "{$holiday->date_from} - {$holiday->date_to}"; + + $companyName = $holiday->calendar->company ? $holiday->calendar->company->name : 'N/A'; + + $html .= " +
+
+

{$holiday->name}

+

{$companyName}

+
+
+

{$dateRange}

+
+
+ "; + } + + $html .= '
'; + + return new HtmlString($html); + }), + + Forms\Components\Placeholder::make('mandatory_holiday') + ->label(__('time_off::filament/actions/holiday-action.form.placeholders.mandatory-holiday')) + ->content(function () { + $mandatoryHolidays = LeaveMandatoryDay::with('company', 'createdBy')->get(); + + if ($mandatoryHolidays->isEmpty()) { + return new HtmlString('

No mandatory holidays found.

'); + } + + $html = '
'; + + foreach ($mandatoryHolidays as $mandatoryHoliday) { + $dateRange = $mandatoryHoliday->start_date === $mandatoryHoliday->end_date + ? $mandatoryHoliday->start_date + : "{$mandatoryHoliday->start_date} - {$mandatoryHoliday->end_date}"; + + $companyName = $mandatoryHoliday->company?->name ?? 'N/A'; + + $html .= " +
+
+

{$mandatoryHoliday->name}

+

{$companyName}

+
+
+

{$dateRange}

+
+
+ "; + } + + $html .= '
'; + + return new HtmlString($html); + }), + ]) + ->modalIcon('heroicon-s-ellipsis-vertical') + ->label(__('time_off::filament/actions/holiday-action.title')) + ->modalSubmitAction(false) + ->modalCancelAction(false); + } +} diff --git a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php index abb9fb7e..7cfc58bc 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php @@ -13,6 +13,7 @@ use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget; use Webkul\TimeOff\Enums\RequestDateFromPeriod; use Webkul\TimeOff\Enums\State; +use Webkul\TimeOff\Filament\Actions\HolidayAction; use Webkul\TimeOff\Models\Leave; class CalendarWidget extends FullCalendarWidget @@ -103,6 +104,7 @@ protected function viewAction(): Action protected function headerActions(): array { return [ + HolidayAction::make(), Actions\CreateAction::make() ->icon('heroicon-o-plus-circle') ->modalIcon('heroicon-o-lifebuoy') From 55e939c166b7e44ec974072d07026777ff58b442 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Mon, 27 Jan 2025 16:08:33 +0530 Subject: [PATCH 20/24] Update localization for Accrual Plan and change navigation icon in AccrualPlanResource --- .../resources/accrual-plan/pages/list-accrual-plan.php | 2 +- .../Clusters/Configurations/Resources/AccrualPlanResource.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/list-accrual-plan.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/list-accrual-plan.php index da673eb2..fa2d52de 100644 --- a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/list-accrual-plan.php +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/accrual-plan/pages/list-accrual-plan.php @@ -2,6 +2,6 @@ return [ 'header-actions' => [ - 'new-leave-type' => 'New Leave Type', + 'new-accrual-plan' => 'New Accrual', ], ]; diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php index aa51dffc..1c9a45ff 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/AccrualPlanResource.php @@ -30,7 +30,7 @@ class AccrualPlanResource extends Resource { protected static ?string $model = LeaveAccrualPlan::class; - protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; + protected static ?string $navigationIcon = 'heroicon-o-paper-airplane'; protected static ?string $cluster = Configurations::class; @@ -241,7 +241,6 @@ public static function getPages(): array 'view' => Pages\ViewAccrualPlan::route('/{record}'), 'edit' => Pages\EditAccrualPlan::route('/{record}/edit'), 'milestones' => Pages\ManageMilestone::route('/{record}/milestones'), - // 'skills' => Pages\ManageSkill::route('/{record}/skills'), ]; } } From ac72f0807ed3bc0924f20a2065e6ae3716a4c4a4 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Mon, 27 Jan 2025 16:28:07 +0530 Subject: [PATCH 21/24] Add LeaveMandatoryDay seeder and enhance employee notifications in calendar widgets --- .../database/seeders/DatabaseSeeder.php | 1 + .../database/seeders/LeaveMandatoryDay.php | 45 +++++++++++++++++++ .../resources/mandatory-days.php | 2 +- .../en/filament/widgets/calendar-widget.php | 7 +++ .../widgets/overview-calendar-widget.php | 7 +++ .../Resources/PublicHolidayResource.php | 2 +- .../src/Filament/Widgets/CalendarWidget.php | 13 +++++- .../src/Filament/Widgets/MyTimeOffWidget.php | 2 +- .../Widgets/OverviewCalendarWidget.php | 13 +++++- 9 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 plugins/webkul/time-off/database/seeders/LeaveMandatoryDay.php diff --git a/plugins/webkul/time-off/database/seeders/DatabaseSeeder.php b/plugins/webkul/time-off/database/seeders/DatabaseSeeder.php index 43b01c8c..786a2985 100644 --- a/plugins/webkul/time-off/database/seeders/DatabaseSeeder.php +++ b/plugins/webkul/time-off/database/seeders/DatabaseSeeder.php @@ -17,6 +17,7 @@ public function run($parameters = []) $this->call([ AccrualPlanSeeder::class, LeaveTypeSeeder::class, + LeaveMandatoryDay::class, ]); } } diff --git a/plugins/webkul/time-off/database/seeders/LeaveMandatoryDay.php b/plugins/webkul/time-off/database/seeders/LeaveMandatoryDay.php new file mode 100644 index 00000000..46f3d31f --- /dev/null +++ b/plugins/webkul/time-off/database/seeders/LeaveMandatoryDay.php @@ -0,0 +1,45 @@ +delete(); + + $leaveMandatoryDays = [ + [ + 'company_id' => 1, + 'creator_id' => 1, + 'color' => '#FF0000', + 'name' => 'New Year', + 'start_date' => '2022-01-01', + 'end_date' => '2022-01-01', + 'created_at' => now(), + 'updated_at' => now(), + ], + + [ + 'company_id' => 1, + 'creator_id' => 1, + 'color' => '#FF0000', + 'name' => 'Christmas', + 'start_date' => '2022-12-25', + 'end_date' => '2022-12-25', + 'created_at' => now(), + 'updated_at' => now(), + ] + ]; + + DB::table('time_off_leave_mandatory_days')->insert($leaveMandatoryDays); + } +} diff --git a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days.php b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days.php index db293386..31d20eb5 100644 --- a/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days.php +++ b/plugins/webkul/time-off/resources/lang/en/filament/clusters/configurations/resources/mandatory-days.php @@ -6,7 +6,7 @@ 'model-label' => 'Mandatory Day', 'navigation' => [ - 'title' => 'Mandatory Days', + 'title' => 'Mandatory Holidays', ], 'global-search' => [ diff --git a/plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php b/plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php index 03a20b80..9f0f3606 100644 --- a/plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php +++ b/plugins/webkul/time-off/resources/lang/en/filament/widgets/calendar-widget.php @@ -20,6 +20,13 @@ 'create' => [ 'title' => 'New Time Off', 'description' => 'Create Time Off Request', + + 'employee-not-found' => [ + 'notification' => [ + 'title' => 'Employee Not Found', + 'body' => 'Please add an employee to your profile before creating a time off request.', + ] + ] ] ], diff --git a/plugins/webkul/time-off/resources/lang/en/filament/widgets/overview-calendar-widget.php b/plugins/webkul/time-off/resources/lang/en/filament/widgets/overview-calendar-widget.php index 3a0b2528..67d11939 100644 --- a/plugins/webkul/time-off/resources/lang/en/filament/widgets/overview-calendar-widget.php +++ b/plugins/webkul/time-off/resources/lang/en/filament/widgets/overview-calendar-widget.php @@ -20,6 +20,13 @@ 'create' => [ 'title' => 'New Time Off', 'description' => 'Create Time Off Request', + + 'employee-not-found' => [ + 'notification' => [ + 'title' => 'Employee Not Found', + 'body' => 'Please add an employee to your profile before creating a time off request.', + ] + ] ] ], diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php index b003104f..757d082d 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Configurations/Resources/PublicHolidayResource.php @@ -19,7 +19,7 @@ class PublicHolidayResource extends Resource { protected static ?string $model = CalendarLeaves::class; - protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; + protected static ?string $navigationIcon = 'heroicon-o-lifebuoy'; protected static ?string $cluster = Configurations::class; diff --git a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php index 7cfc58bc..849f879d 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php @@ -7,6 +7,7 @@ use Filament\Forms; use Filament\Forms\Get; use Filament\Infolists; +use Filament\Notifications\Notification; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Auth; use Saade\FilamentFullCalendar\Actions; @@ -116,9 +117,17 @@ protected function headerActions(): array if ($employee) { $data['employee_id'] = $employee->id; + } else { + Notification::make() + ->danger() + ->title(__('time_off::filament/widgets/calendar-widget.header-actions.create.employee-not-found.notification.title')) + ->body(__('time_off::filament/widgets/calendar-widget.header-actions.create.employee-not-found.notification.body')) + ->send(); + + return; } - if ($employee->department) { + if ($employee?->department) { $data['department_id'] = $employee->department->id; } else { $data['department_id'] = null; @@ -264,7 +273,7 @@ public function fetchEvents(array $fetchInfo): array return Leave::query() ->where('user_id', $user->id) - ->orWhere('employee_id', $user->employee->id) + ->orWhere('employee_id', $user?->employee?->id) ->where('request_date_from', '>=', $fetchInfo['start']) ->where('request_date_to', '<=', $fetchInfo['end']) ->with('holidayStatus') diff --git a/plugins/webkul/time-off/src/Filament/Widgets/MyTimeOffWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/MyTimeOffWidget.php index 13ba653d..b443bc47 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/MyTimeOffWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/MyTimeOffWidget.php @@ -15,7 +15,7 @@ class MyTimeOffWidget extends BaseWidget { protected function getStats(): array { - $employeeId = Auth::user()->employee->id; + $employeeId = Auth::user()?->employee?->id; $endOfYear = Carbon::now()->endOfYear(); $leaveTypes = LeaveType::all(); diff --git a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php index d69d8db5..d99202dd 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php @@ -11,6 +11,7 @@ use Filament\Actions\Action; use Filament\Forms\Get; use Filament\Infolists; +use Filament\Notifications\Notification; use Illuminate\Support\Facades\Auth; use Webkul\TimeOff\Enums\RequestDateFromPeriod; use Webkul\TimeOff\Enums\State; @@ -114,15 +115,23 @@ protected function headerActions(): array if ($employee) { $data['employee_id'] = $employee->id; + } else { + Notification::make() + ->danger() + ->title(__('time_off::filament/widgets/overview-calendar-widget.header-actions.create.employee-not-found.notification.title')) + ->body(__('time_off::filament/widgets/overview-calendar-widget.header-actions.create.employee-not-found.notification.body')) + ->send(); + + return; } - if ($employee->department) { + if ($employee?->department) { $data['department_id'] = $employee->department->id; } else { $data['department_id'] = null; } - if ($employee->calendar) { + if ($employee?->calendar) { $data['calendar_id'] = $employee->calendar->id; $data['number_of_hours'] = $employee->calendar->hours_per_day; } From 57ef701067885a81e5ecb0f5670d3be136624ed1 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Mon, 27 Jan 2025 17:01:28 +0530 Subject: [PATCH 22/24] Refactor department_id assignment to use null-safe operator for employee's department in multiple resources --- .../Pages/EditAllocation.php | 3 ++ .../Pages/ViewAllocation.php | 3 ++ .../TimeOffResource/Pages/CreateTimeOff.php | 2 +- .../TimeOffResource/Pages/EditTimeOff.php | 5 ++- .../TimeOffResource/Pages/ViewTimeOff.php | 3 ++ .../Pages/EditMyAllocation.php | 3 ++ .../Pages/ViewMyAllocation.php | 3 ++ .../Pages/CreateMyTimeOff.php | 2 +- .../MyTimeOffResource/Pages/EditMyTimeOff.php | 9 +++-- .../MyTimeOffResource/Pages/ViewMyTimeOff.php | 3 ++ .../src/Filament/Widgets/CalendarWidget.php | 4 +- .../Widgets/OverviewCalendarWidget.php | 4 +- plugins/webkul/time-off/src/Models/Leave.php | 31 ++++++++++++++- .../time-off/src/Models/LeaveAllocation.php | 38 ++++++++++++++++++- 14 files changed, 101 insertions(+), 12 deletions(-) diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php index f3849572..995fdbe6 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/EditAllocation.php @@ -8,6 +8,7 @@ use Filament\Resources\Pages\EditRecord; use Webkul\TimeOff\Enums\State; use Webkul\TimeOff\Filament\Clusters\Management\Resources\AllocationResource; +use Webkul\Chatter\Filament\Actions as ChatterActions; class EditAllocation extends EditRecord { @@ -29,6 +30,8 @@ protected function getSavedNotification(): ?Notification protected function getHeaderActions(): array { return [ + ChatterActions\ChatterAction::make() + ->setResource(static::$resource), Action::make('approved') ->label(__('time_off::filament/clusters/management/resources/allocation/pages/edit-allocation.header-actions.approved.title')) ->color('gray') diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php index 424eb78a..8bc0a28c 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/AllocationResource/Pages/ViewAllocation.php @@ -6,6 +6,7 @@ use Filament\Notifications\Notification; use Filament\Resources\Pages\ViewRecord; use Webkul\TimeOff\Filament\Clusters\Management\Resources\AllocationResource; +use Webkul\Chatter\Filament\Actions as ChatterActions; class ViewAllocation extends ViewRecord { @@ -14,6 +15,8 @@ class ViewAllocation extends ViewRecord protected function getHeaderActions(): array { return [ + ChatterActions\ChatterAction::make() + ->setResource(static::$resource), Actions\EditAction::make(), Actions\DeleteAction::make() ->successNotification( diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php index b3e3d9e2..2c66aebd 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/CreateTimeOff.php @@ -28,7 +28,7 @@ protected function mutateFormDataBeforeCreate(array $data): array $employee = Employee::find($data['employee_id']); if ($employee->department) { - $data['department_id'] = $employee->department->id; + $data['department_id'] = $employee->department?->id; } else { $data['department_id'] = null; } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php index 494097ae..a18da94d 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/EditTimeOff.php @@ -10,6 +10,7 @@ use Webkul\Employee\Models\Employee; use Webkul\TimeOff\Enums\State; use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; +use Webkul\Chatter\Filament\Actions as ChatterActions; class EditTimeOff extends EditRecord { @@ -31,6 +32,8 @@ protected function getSavedNotification(): ?Notification protected function getHeaderActions(): array { return [ + ChatterActions\ChatterAction::make() + ->setResource(static::$resource), Actions\ViewAction::make(), Actions\DeleteAction::make() ->successNotification( @@ -48,7 +51,7 @@ protected function mutateFormDataBeforeSave(array $data): array $employee = Employee::find($data['employee_id']); if ($employee->department) { - $data['department_id'] = $employee->department->id; + $data['department_id'] = $employee->department?->id; } else { $data['department_id'] = null; } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php index 39ea6d8f..b0423d2c 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/Management/Resources/TimeOffResource/Pages/ViewTimeOff.php @@ -6,6 +6,7 @@ use Filament\Notifications\Notification; use Filament\Resources\Pages\ViewRecord; use Webkul\TimeOff\Filament\Clusters\Management\Resources\TimeOffResource; +use Webkul\Chatter\Filament\Actions as ChatterActions; class ViewTimeOff extends ViewRecord { @@ -14,6 +15,8 @@ class ViewTimeOff extends ViewRecord protected function getHeaderActions(): array { return [ + ChatterActions\ChatterAction::make() + ->setResource(static::$resource), Actions\EditAction::make(), Actions\DeleteAction::make() ->successNotification( diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php index d895df01..71d44faf 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/EditMyAllocation.php @@ -7,6 +7,7 @@ use Filament\Notifications\Notification; use Filament\Resources\Pages\EditRecord; use Illuminate\Support\Facades\Auth; +use Webkul\Chatter\Filament\Actions as ChatterActions; class EditMyAllocation extends EditRecord { @@ -28,6 +29,8 @@ protected function getSavedNotification(): ?Notification protected function getHeaderActions(): array { return [ + ChatterActions\ChatterAction::make() + ->setResource(static::$resource), Actions\ViewAction::make(), Actions\DeleteAction::make() ->successNotification( diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php index 0bd0c04d..950bab7b 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyAllocationResource/Pages/ViewMyAllocation.php @@ -6,6 +6,7 @@ use Filament\Actions; use Filament\Notifications\Notification; use Filament\Resources\Pages\ViewRecord; +use Webkul\Chatter\Filament\Actions as ChatterActions; class ViewMyAllocation extends ViewRecord { @@ -14,6 +15,8 @@ class ViewMyAllocation extends ViewRecord protected function getHeaderActions(): array { return [ + ChatterActions\ChatterAction::make() + ->setResource(static::$resource), Actions\EditAction::make(), Actions\DeleteAction::make() ->successNotification( diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php index cda67920..b91924dc 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/CreateMyTimeOff.php @@ -26,7 +26,7 @@ protected function mutateFormDataBeforeCreate(array $data): array if ($employee) { $data['employee_id'] = $employee->id; - $data['department_id'] = $employee->department->id; + $data['department_id'] = $employee->department?->id; } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php index 2daa4962..a50edd5c 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/EditMyTimeOff.php @@ -9,6 +9,7 @@ use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; use Webkul\TimeOff\Enums\State; +use Webkul\Chatter\Filament\Actions as ChatterActions; class EditMyTimeOff extends EditRecord { @@ -30,6 +31,8 @@ protected function getSavedNotification(): ?Notification protected function getHeaderActions(): array { return [ + ChatterActions\ChatterAction::make() + ->setResource(static::$resource), Actions\ViewAction::make(), Actions\DeleteAction::make() ->successNotification( @@ -49,7 +52,7 @@ protected function mutateFormDataBeforeSave(array $data): array if ($employee) { $data['employee_id'] = $employee->id; - $data['department_id'] = $employee->department->id; + $data['department_id'] = $employee->department?->id; } @@ -77,7 +80,7 @@ protected function mutateFormDataBeforeSave(array $data): array $data['number_of_days'] = 0.5; } else { $startDate = Carbon::parse($data['request_date_from']); - $endDate = $data['request_date_to'] ? Carbon::parse($data['request_date_to']) : $startDate; + $endDate = isset($data['request_date_to']) ? Carbon::parse($data['request_date_to']) : $startDate; $data['duration_display'] = $startDate->diffInDays($endDate) + 1 . ' day(s)'; @@ -89,7 +92,7 @@ protected function mutateFormDataBeforeSave(array $data): array $data['state'] = State::CONFIRM->value; $data['date_from'] = $data['request_date_from']; - $data['date_to'] = $data['request_date_to']; + $data['date_to'] = isset($data['request_date_to']) ? $data['request_date_to'] : null; return $data; } diff --git a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php index 621291c9..d8ed10c0 100644 --- a/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php +++ b/plugins/webkul/time-off/src/Filament/Clusters/MyTime/Resources/MyTimeOffResource/Pages/ViewMyTimeOff.php @@ -6,6 +6,7 @@ use Filament\Actions; use Filament\Notifications\Notification; use Filament\Resources\Pages\ViewRecord; +use Webkul\Chatter\Filament\Actions as ChatterActions; class ViewMyTimeOff extends ViewRecord { @@ -14,6 +15,8 @@ class ViewMyTimeOff extends ViewRecord protected function getHeaderActions(): array { return [ + ChatterActions\ChatterAction::make() + ->setResource(static::$resource), Actions\EditAction::make(), Actions\DeleteAction::make() ->successNotification( diff --git a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php index 849f879d..f96af3c6 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php @@ -35,7 +35,7 @@ protected function modalActions(): array } if ($employee->department) { - $data['department_id'] = $employee->department->id; + $data['department_id'] = $employee->department?->id; } else { $data['department_id'] = null; } @@ -128,7 +128,7 @@ protected function headerActions(): array } if ($employee?->department) { - $data['department_id'] = $employee->department->id; + $data['department_id'] = $employee->department?->id; } else { $data['department_id'] = null; } diff --git a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php index d99202dd..e6f8e763 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php @@ -34,7 +34,7 @@ protected function modalActions(): array } if ($employee->department) { - $data['department_id'] = $employee->department->id; + $data['department_id'] = $employee->department?->id; } else { $data['department_id'] = null; } @@ -126,7 +126,7 @@ protected function headerActions(): array } if ($employee?->department) { - $data['department_id'] = $employee->department->id; + $data['department_id'] = $employee->department?->id; } else { $data['department_id'] = null; } diff --git a/plugins/webkul/time-off/src/Models/Leave.php b/plugins/webkul/time-off/src/Models/Leave.php index 413013da..456967ba 100644 --- a/plugins/webkul/time-off/src/Models/Leave.php +++ b/plugins/webkul/time-off/src/Models/Leave.php @@ -10,10 +10,12 @@ use Webkul\Employee\Models\Employee; use Webkul\Security\Models\User; use Webkul\Support\Models\Company; +use Webkul\Chatter\Traits\HasChatter; +use Webkul\Chatter\Traits\HasLogActivity; class Leave extends Model { - use HasFactory; + use HasChatter, HasFactory, HasLogActivity; protected $table = 'time_off_leaves'; @@ -48,6 +50,33 @@ class Leave extends Model 'request_hour_to', ]; + protected array $logAttributes = [ + 'user.name' => 'User', + 'manger.name' => 'Manager', + 'holidayStatus.name' => 'Holiday Status', + 'employee.name' => 'Employee', + 'employeeCompany.name' => 'Employee Company', + 'department.name' => 'Department', + 'calendar.name' => 'Calendar', + 'firstApprover.name' => 'First Approver', + 'lastApprover.name' => 'Last Approver', + 'private_name' => 'Description', + 'state' => 'State', + 'duration_display' => 'Duration Display', + 'request_date_from_period' => 'Request Date From Period', + 'request_date_from' => 'Request Date From', + 'request_date_to' => 'Request Date To', + 'notes' => 'Notes', + 'request_unit_half' => 'Request Unit Half', + 'request_unit_hours' => 'Request Unit Hours', + 'date_from' => 'Date From', + 'date_to' => 'Date To', + 'number_of_days' => 'Number Of Days', + 'number_of_hours' => 'Number Of Hours', + 'request_hour_from' => 'Request Hour From', + 'request_hour_to' => 'Request Hour To', + ]; + public function user(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); diff --git a/plugins/webkul/time-off/src/Models/LeaveAllocation.php b/plugins/webkul/time-off/src/Models/LeaveAllocation.php index 003906c2..727aa26c 100644 --- a/plugins/webkul/time-off/src/Models/LeaveAllocation.php +++ b/plugins/webkul/time-off/src/Models/LeaveAllocation.php @@ -4,6 +4,8 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Webkul\Chatter\Traits\HasChatter; +use Webkul\Chatter\Traits\HasLogActivity; use Webkul\Employee\Models\Department; use Webkul\Employee\Models\Employee; use Webkul\Security\Models\User; @@ -11,7 +13,7 @@ class LeaveAllocation extends Model { - use HasFactory; + use HasChatter, HasFactory, HasLogActivity; protected $table = 'time_off_leave_allocations'; @@ -43,6 +45,35 @@ class LeaveAllocation extends Model 'expiring_carryover_days', ]; + protected array $logAttributes = [ + 'holidayStatus.name' => 'Time Off Type', + 'employee.name' => 'Employee', + 'employeeCompany.name' => 'Employee Company', + 'approver.name' => 'Approver', + 'secondApprover.name' => 'Second Approver', + 'department.name' => 'Department', + 'accrualPlan.name' => 'Accrual Plan', + 'createdBy.name' => 'Created By', + 'name' => 'Name', + 'state' => 'State', + 'allocation_type' => 'Allocation Type', + 'date_from' => 'Date From', + 'date_to' => 'Date To', + 'last_executed_carryover_date' => 'Last Executed Carryover Date', + 'last_called' => 'Last Called', + 'actual_last_called' => 'Actual Last Called', + 'next_call' => 'Next Call', + 'carried_over_days_expiration_date' => 'Carried Over Days Expiration Date', + 'notes' => 'Notes', + 'already_accrued' => 'Already Accrued', + 'number_of_days' => 'Number Of Days', + 'number_of_hours_display' => 'Number Of Hours Display', + 'yearly_accrued_amount' => 'Yearly Accrued Amount', + 'expiring_carryover_days' => 'Expiring Carryover Days', + 'created_at' => 'Created At', + 'updated_at' => 'Updated At', + ]; + public function employee() { return $this->belongsTo(Employee::class); @@ -53,6 +84,11 @@ public function company() return $this->belongsTo(Company::class, 'employee_company_id'); } + public function employeeCompany() + { + return $this->belongsTo(Company::class, 'employee_company_id'); + } + public function manager() { return $this->belongsTo(Employee::class, 'manager_id'); From 163dce76c6351c5059caefcf42b4609e9270b237 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Mon, 27 Jan 2025 17:49:03 +0530 Subject: [PATCH 23/24] Enhance HolidayAction and CalendarWidget with updated icons and null-safe date handling; improve TimeOffPlugin configuration for multi-month view --- .../time-off/src/Filament/Actions/HolidayAction.php | 4 ++-- .../time-off/src/Filament/Widgets/CalendarWidget.php | 4 ++-- plugins/webkul/time-off/src/TimeOffPlugin.php | 8 ++++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/plugins/webkul/time-off/src/Filament/Actions/HolidayAction.php b/plugins/webkul/time-off/src/Filament/Actions/HolidayAction.php index 00e6c40e..7e913611 100644 --- a/plugins/webkul/time-off/src/Filament/Actions/HolidayAction.php +++ b/plugins/webkul/time-off/src/Filament/Actions/HolidayAction.php @@ -22,7 +22,7 @@ protected function setUp(): void $this ->hiddenLabel() - ->icon('heroicon-s-ellipsis-vertical') + ->icon('heroicon-o-lifebuoy') ->modalWidth(MaxWidth::TwoExtraLarge) ->slideOver() ->form([ @@ -98,7 +98,7 @@ protected function setUp(): void return new HtmlString($html); }), ]) - ->modalIcon('heroicon-s-ellipsis-vertical') + ->modalIcon('heroicon-o-lifebuoy') ->label(__('time_off::filament/actions/holiday-action.title')) ->modalSubmitAction(false) ->modalCancelAction(false); diff --git a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php index f96af3c6..19ec5203 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php @@ -71,7 +71,7 @@ protected function modalActions(): array $data['state'] = State::CONFIRM->value; $data['date_from'] = $data['request_date_from'] ?? null; - $data['date_to'] = $data['request_date_to'] ?? null; + $data['date_to'] = $data['request_date_to'] ?? null; $record->update($data); }) @@ -164,7 +164,7 @@ protected function headerActions(): array $data['state'] = State::CONFIRM->value; $data['date_from'] = $data['request_date_from']; - $data['date_to'] = $data['request_date_to']; + $data['date_to'] = isset($data['request_date_to']) ? $data['request_date_to'] : null; Leave::create($data); }) diff --git a/plugins/webkul/time-off/src/TimeOffPlugin.php b/plugins/webkul/time-off/src/TimeOffPlugin.php index edfec6e7..9770a7a9 100644 --- a/plugins/webkul/time-off/src/TimeOffPlugin.php +++ b/plugins/webkul/time-off/src/TimeOffPlugin.php @@ -30,7 +30,11 @@ public function register(Panel $panel): void ->plugin( FilamentFullCalendarPlugin::make() ->selectable() - ->editable() + ->editable(true) + ->plugins(['multiMonth']) + ->config([ + 'initialView' => 'multiMonthYear', + ]) ); } @@ -43,6 +47,6 @@ protected function getPluginBasePath($path = null): string { $reflector = new \ReflectionClass(get_class($this)); - return dirname($reflector->getFileName()).($path ?? ''); + return dirname($reflector->getFileName()) . ($path ?? ''); } } From d9950c0a7d2f1343905be1e924a0b0eb2096b7e5 Mon Sep 17 00:00:00 2001 From: Suraj Kashyap Date: Mon, 27 Jan 2025 18:47:16 +0530 Subject: [PATCH 24/24] Add multi-month view configuration to CalendarWidget and OverviewCalendarWidget --- .../time-off/src/Filament/Widgets/CalendarWidget.php | 9 ++++++++- .../src/Filament/Widgets/OverviewCalendarWidget.php | 7 +++++++ plugins/webkul/time-off/src/TimeOffPlugin.php | 3 --- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php index 19ec5203..34ac8075 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/CalendarWidget.php @@ -21,6 +21,13 @@ class CalendarWidget extends FullCalendarWidget { public Model|string|null $model = Leave::class; + public function config(): array + { + return [ + 'initialView' => 'multiMonthYear', + ]; + } + protected function modalActions(): array { return [ @@ -71,7 +78,7 @@ protected function modalActions(): array $data['state'] = State::CONFIRM->value; $data['date_from'] = $data['request_date_from'] ?? null; - $data['date_to'] = $data['request_date_to'] ?? null; + $data['date_to'] = $data['request_date_to'] ?? null; $record->update($data); }) diff --git a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php index e6f8e763..22ba2a38 100644 --- a/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php +++ b/plugins/webkul/time-off/src/Filament/Widgets/OverviewCalendarWidget.php @@ -20,6 +20,13 @@ class OverviewCalendarWidget extends FullCalendarWidget { public Model|string|null $model = Leave::class; + public function config(): array + { + return [ + 'initialView' => 'multiMonthYear', + ]; + } + protected function modalActions(): array { return [ diff --git a/plugins/webkul/time-off/src/TimeOffPlugin.php b/plugins/webkul/time-off/src/TimeOffPlugin.php index 9770a7a9..1341a418 100644 --- a/plugins/webkul/time-off/src/TimeOffPlugin.php +++ b/plugins/webkul/time-off/src/TimeOffPlugin.php @@ -32,9 +32,6 @@ public function register(Panel $panel): void ->selectable() ->editable(true) ->plugins(['multiMonth']) - ->config([ - 'initialView' => 'multiMonthYear', - ]) ); }