schema([ Select::make('role') ->options(Role::class), TextInput::make('billable_rate') ->label('Billable rate (in Cents)') ->nullable() ->numeric(), ]); } public function table(Table $table): Table { /** @var Organization $organization */ $organization = $this->getOwnerRecord(); return $table ->recordTitleAttribute('name') ->columns([ Tables\Columns\TextColumn::make('name'), Tables\Columns\TextColumn::make('role'), TextColumn::make('billable_rate') ->money($organization->currency, divideBy: 100), ]) ->headerActions([ Tables\Actions\AttachAction::make() ->recordTitle(fn (User $record): string => "{$record->name} ({$record->email})") ->form(fn (AttachAction $action): array => [ $action->getRecordSelect(), Select::make('role') ->required() ->options(Role::class) ->rule([ 'required', 'string', Rule::enum(Role::class) ->except([Role::Owner, Role::Placeholder]), ]), ]) ->label('Add user') ->modalHeading('Add user') ->icon('heroicon-s-plus') ->using(function (User $record, array $data): void { /** @var Organization $organization */ $organization = $this->getOwnerRecord(); app(MemberService::class)->addMember($record, $organization, Role::from($data['role']), true); }), ]) ->actions([ Action::make('view') ->icon('heroicon-o-eye') ->color('gray') ->url(fn (User $record): string => UserResource::getUrl('view', [ 'record' => $record->getKey(), ])), Tables\Actions\EditAction::make() ->using(function (User $record, array $data): User { /** @var Organization $organization */ $organization = $this->getOwnerRecord(); /** @var Member $member */ $member = $record->getRelation('membership'); if ($data['billable_rate'] !== $member->billable_rate) { $member->billable_rate = $data['billable_rate']; app(BillableRateService::class)->updateTimeEntriesBillableRateForMember($member); } if ($data['role'] !== $member->role) { try { app(MemberService::class)->changeRole($member, $organization, Role::from($data['role']), true); } catch (ApiException $exception) { Notification::make() ->danger() ->title('Update failed') ->body($exception->getTranslatedMessage()) ->persistent() ->send(); } } $member->save(); return $record; }), Tables\Actions\DetachAction::make() ->using(function (User $record): void { /** @var Organization $organization */ $organization = $this->getOwnerRecord(); $member = Member::query() ->whereBelongsTo($record, 'user') ->whereBelongsTo($organization, 'organization') ->firstOrFail(); try { app(MemberService::class)->removeMember($member, $organization); } catch (ApiException $exception) { Notification::make() ->danger() ->title('Delete failed') ->body($exception->getTranslatedMessage()) ->persistent() ->send(); } }), ]) ->bulkActions([ ]); } }