diff --git a/app-modules/analytics/src/Filament/Resources/AnalyticsResourceCategoryResource.php b/app-modules/analytics/src/Filament/Resources/AnalyticsResourceCategoryResource.php index 403d91b9b1..c56dc38db6 100644 --- a/app-modules/analytics/src/Filament/Resources/AnalyticsResourceCategoryResource.php +++ b/app-modules/analytics/src/Filament/Resources/AnalyticsResourceCategoryResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\Analytics\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\AnalyticsResources; use AdvisingApp\Analytics\Models\AnalyticsResourceCategory; use AdvisingApp\Analytics\Filament\Resources\AnalyticsResourceCategoryResource\Pages\EditAnalyticsResourceCategory; use AdvisingApp\Analytics\Filament\Resources\AnalyticsResourceCategoryResource\Pages\ViewAnalyticsResourceCategory; @@ -47,11 +48,9 @@ class AnalyticsResourceCategoryResource extends Resource { protected static ?string $model = AnalyticsResourceCategory::class; - protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; + protected static ?int $navigationSort = 30; - protected static ?string $navigationGroup = 'Product Settings'; - - protected static ?int $navigationSort = 20; + protected static ?string $cluster = AnalyticsResources::class; public static function getPages(): array { diff --git a/app-modules/analytics/src/Filament/Resources/AnalyticsResourceResource.php b/app-modules/analytics/src/Filament/Resources/AnalyticsResourceResource.php index f9b48f5546..09853bc320 100644 --- a/app-modules/analytics/src/Filament/Resources/AnalyticsResourceResource.php +++ b/app-modules/analytics/src/Filament/Resources/AnalyticsResourceResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\Analytics\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\AnalyticsResources; use AdvisingApp\Analytics\Models\AnalyticsResource; use AdvisingApp\Analytics\Filament\Resources\AnalyticsResourceResource\Pages\EditAnalyticsResource; use AdvisingApp\Analytics\Filament\Resources\AnalyticsResourceResource\Pages\ListAnalyticsResources; @@ -46,13 +47,9 @@ class AnalyticsResourceResource extends Resource { protected static ?string $model = AnalyticsResource::class; - protected static ?string $navigationIcon = 'heroicon-o-arrow-trending-up'; + protected static ?int $navigationSort = 10; - protected static ?string $navigationGroup = 'Data and Analytics'; - - protected static ?int $navigationSort = 1; - - protected static ?string $navigationLabel = 'Analytics Portal'; + protected static ?string $cluster = AnalyticsResources::class; public static function getPages(): array { diff --git a/app-modules/analytics/src/Filament/Resources/AnalyticsResourceSourceResource.php b/app-modules/analytics/src/Filament/Resources/AnalyticsResourceSourceResource.php index 89274b7902..b5d235b44a 100644 --- a/app-modules/analytics/src/Filament/Resources/AnalyticsResourceSourceResource.php +++ b/app-modules/analytics/src/Filament/Resources/AnalyticsResourceSourceResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\Analytics\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\AnalyticsResources; use AdvisingApp\Analytics\Models\AnalyticsResourceSource; use AdvisingApp\Analytics\Filament\Resources\AnalyticsResourceSourceResource\Pages\EditAnalyticsResourceSource; use AdvisingApp\Analytics\Filament\Resources\AnalyticsResourceSourceResource\Pages\ViewAnalyticsResourceSource; @@ -47,11 +48,9 @@ class AnalyticsResourceSourceResource extends Resource { protected static ?string $model = AnalyticsResourceSource::class; - protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; + protected static ?int $navigationSort = 20; - protected static ?string $navigationGroup = 'Product Settings'; - - protected static ?int $navigationSort = 19; + protected static ?string $cluster = AnalyticsResources::class; public static function getPages(): array { diff --git a/app-modules/application/src/Filament/Resources/ApplicationSubmissionStateResource.php b/app-modules/application/src/Filament/Resources/ApplicationSubmissionStateResource.php index 2a0563ac3b..95f0e2fb62 100644 --- a/app-modules/application/src/Filament/Resources/ApplicationSubmissionStateResource.php +++ b/app-modules/application/src/Filament/Resources/ApplicationSubmissionStateResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\Application\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\OnlineAdmissions; use AdvisingApp\Application\Models\ApplicationSubmissionState; use AdvisingApp\Application\Filament\Resources\ApplicationSubmissionStateResource\Pages\EditApplicationSubmissionState; use AdvisingApp\Application\Filament\Resources\ApplicationSubmissionStateResource\Pages\ViewApplicationSubmissionState; @@ -49,14 +50,12 @@ class ApplicationSubmissionStateResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; - protected static ?string $navigationParentItem = 'Online Admissions'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Application States'; protected static ?int $navigationSort = 1; + protected static ?string $cluster = OnlineAdmissions::class; + public static function getPages(): array { return [ diff --git a/app-modules/assistant/src/Filament/Pages/AssistantConfiguration.php b/app-modules/assistant/src/Filament/Pages/AssistantConfiguration.php deleted file mode 100644 index 0eb6c9e1a3..0000000000 --- a/app-modules/assistant/src/Filament/Pages/AssistantConfiguration.php +++ /dev/null @@ -1,118 +0,0 @@ - - - Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. - - Advising App™ is licensed under the Elastic License 2.0. For more details, - see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. - - Notice: - - - You may not provide the software to third parties as a hosted or managed - service, where the service provides users with access to any substantial set of - the features or functionality of the software. - - You may not move, change, disable, or circumvent the license key functionality - in the software, and you may not remove or obscure any functionality in the - software that is protected by the license key. - - You may not alter, remove, or obscure any licensing, copyright, or other notices - of the licensor in the software. Any use of the licensor’s trademarks is subject - to applicable law. - - Canyon GBS LLC respects the intellectual property rights of others and expects the - same in return. Canyon GBS™ and Advising App™ are registered trademarks of - Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks - vigorously. - - The software solution, including services, infrastructure, and code, is offered as a - Software as a Service (SaaS) by Canyon GBS LLC. - - Use of this software implies agreement to the license terms and conditions as stated - in the Elastic License 2.0. - - For more information or inquiries please visit our website at - https://www.canyongbs.com or contact us via email at legal@canyongbs.com. - - -*/ - -namespace AdvisingApp\Assistant\Filament\Pages; - -use Filament\Pages\Page; -use Filament\Navigation\NavigationItem; -use AdvisingApp\Consent\Filament\Resources\ConsentAgreementResource\Pages\ListConsentAgreements; - -class AssistantConfiguration extends Page -{ - protected static string $view = 'assistant::filament.pages.assistant-configuration'; - - protected static ?string $navigationIcon = 'heroicon-o-shield-exclamation'; - - protected static ?string $navigationParentItem = 'Product Integrations'; - - protected static ?string $navigationLabel = 'AI Settings'; - - protected static ?int $navigationSort = 10; - - protected static ?string $modelLabel = 'Artificial Intelligence'; - - protected static ?string $pluralModelLabel = 'Artificial Intelligence'; - - protected static ?string $title = 'Artificial Intelligence'; - - public function getBreadcrumbs(): array - { - return [ - $this::getUrl() => 'Artificial Intelligence', - ]; - } - - public static function shouldRegisterNavigation(): bool - { - return collect((new AssistantConfiguration())->getSubNavigation()) - ->filter(function (NavigationItem $item) { - return $item->isVisible(); - })->isNotEmpty(); - } - - public function mount(): void - { - /** @var NavigationItem $firstNavItem */ - $firstNavItem = collect($this->getSubNavigation())->first(function (NavigationItem $item) { - return $item->isVisible(); - }); - - if (is_null($firstNavItem)) { - abort(403); - } - - redirect($firstNavItem->getUrl()); - } - - public static function getNavigationItems(): array - { - $item = parent::getNavigationItems()[0]; - - $item->isActiveWhen(function (): bool { - $subItems = (new AssistantConfiguration())->getSubNavigation(); - - foreach ($subItems as $subItem) { - if (str(request()->fullUrl())->contains(str($subItem->getUrl())->after('/'))) { - return true; - } - } - - return request()->routeIs(static::getRouteName()); - }); - - return [$item]; - } - - public function getSubNavigation(): array - { - return $this->generateNavigationItems( - [ - ListConsentAgreements::class, - ManageAiSettings::class, - ] - ); - } -} diff --git a/app-modules/assistant/src/Filament/Pages/ManageAiSettings.php b/app-modules/assistant/src/Filament/Pages/ManageAiSettings.php index f450b00231..bf14dd22bf 100644 --- a/app-modules/assistant/src/Filament/Pages/ManageAiSettings.php +++ b/app-modules/assistant/src/Filament/Pages/ManageAiSettings.php @@ -42,6 +42,7 @@ use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use AdvisingApp\Authorization\Enums\LicenseType; +use App\Filament\Clusters\ArtificialIntelligence; use AdvisingApp\IntegrationAI\Settings\AISettings; class ManageAiSettings extends SettingsPage @@ -50,12 +51,9 @@ class ManageAiSettings extends SettingsPage protected static ?string $title = 'Manage AI Settings'; - protected static ?string $navigationGroup = 'Product Administration'; + protected static ?string $cluster = ArtificialIntelligence::class; - // We don't want to register the navigation as we will be using the navigation item in a different page. - public static function registerNavigationItems(): void {} - - public static function shouldRegisterNavigation(): bool + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -67,26 +65,6 @@ public static function shouldRegisterNavigation(): bool return $user->can(['assistant.access_ai_settings']); } - public function mount(): void - { - /** @var User $user */ - $user = auth()->user(); - - abort_unless($user->hasLicense(LicenseType::ConversationalAi), 403); - - abort_unless($user->can(['assistant.access_ai_settings']), 403); - - parent::mount(); - } - - public function getBreadcrumbs(): array - { - return [ - AssistantConfiguration::getUrl() => 'Artificial Intelligence', - $this::getUrl() => 'Manage AI Settings', - ]; - } - public function form(Form $form): Form { return $form @@ -113,9 +91,4 @@ public function form(Form $form): Form ->columnSpan('1/2'), ]); } - - public function getSubNavigation(): array - { - return (new AssistantConfiguration())->getSubNavigation(); - } } diff --git a/app-modules/assistant/src/Filament/Pages/PersonalAssistant.php b/app-modules/assistant/src/Filament/Pages/PersonalAssistant.php index 013ae37fb6..697e05c007 100644 --- a/app-modules/assistant/src/Filament/Pages/PersonalAssistant.php +++ b/app-modules/assistant/src/Filament/Pages/PersonalAssistant.php @@ -104,7 +104,7 @@ class PersonalAssistant extends Page public bool $loading = true; - public static function shouldRegisterNavigation(): bool + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -118,10 +118,6 @@ public static function shouldRegisterNavigation(): bool public function mount(): void { - abort_unless(auth()->user()->hasLicense(LicenseType::ConversationalAi), 403); - - $this->authorize('assistant.access'); - $this->consentAgreement = ConsentAgreement::where('type', ConsentAgreementType::AzureOpenAI)->first(); /** @var AssistantChat $chat */ diff --git a/app-modules/assistant/src/Filament/Pages/PromptLibrary.php b/app-modules/assistant/src/Filament/Pages/PromptLibrary.php index 259cf65a54..b2630ac6e6 100644 --- a/app-modules/assistant/src/Filament/Pages/PromptLibrary.php +++ b/app-modules/assistant/src/Filament/Pages/PromptLibrary.php @@ -50,7 +50,7 @@ class PromptLibrary extends Page protected static ?int $navigationSort = 10; - public static function shouldRegisterNavigation(): bool + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -61,9 +61,4 @@ public static function shouldRegisterNavigation(): bool return $user->can('assistant.access'); } - - public function mount(): void - { - abort_unless(auth()->user()->hasLicense(LicenseType::ConversationalAi), 403); - } } diff --git a/app-modules/assistant/src/Filament/Resources/AssistantChatMessageLogResource.php b/app-modules/assistant/src/Filament/Resources/AssistantChatMessageLogResource.php index d8c4b67d56..7d76b72bfd 100644 --- a/app-modules/assistant/src/Filament/Resources/AssistantChatMessageLogResource.php +++ b/app-modules/assistant/src/Filament/Resources/AssistantChatMessageLogResource.php @@ -42,6 +42,7 @@ use App\Infolists\Components\CodeEntry; use Filament\Tables\Actions\ViewAction; use Filament\Tables\Columns\TextColumn; +use App\Filament\Clusters\UsageAuditing; use Filament\Tables\Actions\DeleteAction; use Filament\Tables\Filters\SelectFilter; use Filament\Infolists\Components\TextEntry; @@ -58,16 +59,14 @@ class AssistantChatMessageLogResource extends Resource protected static ?string $navigationLabel = 'Personal Assistant'; - protected static ?string $navigationParentItem = 'Usage Auditing'; - - protected static ?string $navigationGroup = 'Reporting'; - protected static ?int $navigationSort = 30; protected static ?string $modelLabel = 'Personal Assistant'; protected static ?string $pluralLabel = 'Personal Assistant'; + protected static ?string $cluster = UsageAuditing::class; + public static function infolist(Infolist $infolist): Infolist { return $infolist diff --git a/app-modules/assistant/tests/Feature/Filament/Pages/AssistantConfigurationPageTest.php b/app-modules/assistant/tests/Feature/Filament/Pages/AssistantConfigurationPageTest.php deleted file mode 100644 index 842a9e4ee0..0000000000 --- a/app-modules/assistant/tests/Feature/Filament/Pages/AssistantConfigurationPageTest.php +++ /dev/null @@ -1,86 +0,0 @@ - - - Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. - - Advising App™ is licensed under the Elastic License 2.0. For more details, - see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. - - Notice: - - - You may not provide the software to third parties as a hosted or managed - service, where the service provides users with access to any substantial set of - the features or functionality of the software. - - You may not move, change, disable, or circumvent the license key functionality - in the software, and you may not remove or obscure any functionality in the - software that is protected by the license key. - - You may not alter, remove, or obscure any licensing, copyright, or other notices - of the licensor in the software. Any use of the licensor’s trademarks is subject - to applicable law. - - Canyon GBS LLC respects the intellectual property rights of others and expects the - same in return. Canyon GBS™ and Advising App™ are registered trademarks of - Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks - vigorously. - - The software solution, including services, infrastructure, and code, is offered as a - Software as a Service (SaaS) by Canyon GBS LLC. - - Use of this software implies agreement to the license terms and conditions as stated - in the Elastic License 2.0. - - For more information or inquiries please visit our website at - https://www.canyongbs.com or contact us via email at legal@canyongbs.com. - - -*/ - -use App\Models\User; - -use function Pest\Laravel\actingAs; - -use AdvisingApp\Authorization\Enums\LicenseType; -use AdvisingApp\Assistant\Filament\Pages\ManageAiSettings; -use AdvisingApp\Assistant\Filament\Pages\AssistantConfiguration; -use AdvisingApp\Consent\Filament\Resources\ConsentAgreementResource\Pages\ListConsentAgreements; - -it('does not load if you do not have any permissions to access', function () { - $user = User::factory()->licensed(LicenseType::ConversationalAi)->create(); - - actingAs($user); - - Livewire::test(AssistantConfiguration::class) - ->assertStatus(403); -}); - -it('redirects if you have the correct access to consent agreements', function () { - $user = User::factory()->licensed(LicenseType::ConversationalAi)->create(); - - $user->givePermissionTo(['consent_agreement.view-any', 'consent_agreement.*.view', 'consent_agreement.*.update']); - - actingAs($user); - - Livewire::test(AssistantConfiguration::class) - ->assertRedirect(ListConsentAgreements::getUrl()); -}); - -it('redirects if you have the correct access to ai settings', function () { - $user = User::factory()->licensed(LicenseType::ConversationalAi)->create(); - - $user->givePermissionTo(['assistant.access_ai_settings']); - - actingAs($user); - - Livewire::test(AssistantConfiguration::class) - ->assertRedirect(ManageAiSettings::getUrl()); -}); - -it('redirects if you have access for both ai settings and consent agreements', function () { - $user = User::factory()->licensed(LicenseType::ConversationalAi)->create(); - - $user->givePermissionTo(['consent_agreement.view-any', 'consent_agreement.*.view', 'consent_agreement.*.update', 'assistant.access_ai_settings']); - - actingAs($user); - - Livewire::test(AssistantConfiguration::class) - ->assertRedirect(ListConsentAgreements::getUrl()); -}); diff --git a/app-modules/audit/src/Filament/Pages/ManageAuditSettings.php b/app-modules/audit/src/Filament/Pages/ManageAuditSettings.php index 8b34cc1f6b..a3cad63805 100644 --- a/app-modules/audit/src/Filament/Pages/ManageAuditSettings.php +++ b/app-modules/audit/src/Filament/Pages/ManageAuditSettings.php @@ -41,6 +41,7 @@ use Filament\Pages\SettingsPage; use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\GlobalSettings; use AdvisingApp\Audit\Settings\AuditSettings; use AdvisingApp\Audit\Actions\Finders\AuditableModels; @@ -50,17 +51,15 @@ class ManageAuditSettings extends SettingsPage protected static ?string $navigationLabel = 'Auditing'; - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?string $navigationParentItem = 'Global Settings'; - protected static ?int $navigationSort = 20; protected static string $settings = AuditSettings::class; protected static ?string $title = 'Auditing'; - public static function shouldRegisterNavigation(): bool + protected static ?string $cluster = GlobalSettings::class; + + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -68,13 +67,6 @@ public static function shouldRegisterNavigation(): bool return $user->can('audit.view_audit_settings'); } - public function mount(): void - { - $this->authorize('audit.view_audit_settings'); - - parent::mount(); - } - public function form(Form $form): Form { return $form diff --git a/app-modules/audit/src/Filament/Resources/AuditResource.php b/app-modules/audit/src/Filament/Resources/AuditResource.php index 86e6c814bc..e22ab03f13 100644 --- a/app-modules/audit/src/Filament/Resources/AuditResource.php +++ b/app-modules/audit/src/Filament/Resources/AuditResource.php @@ -38,6 +38,7 @@ use Filament\Resources\Resource; use AdvisingApp\Audit\Models\Audit; +use App\Filament\Clusters\UsageAuditing; use AdvisingApp\Audit\Filament\Resources\AuditResource\Pages; class AuditResource extends Resource @@ -48,12 +49,10 @@ class AuditResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-shield-check'; - protected static ?string $navigationParentItem = 'Usage Auditing'; - - protected static ?string $navigationGroup = 'Reporting'; - protected static ?int $navigationSort = 40; + protected static ?string $cluster = UsageAuditing::class; + public static function getPages(): array { return [ diff --git a/app-modules/campaign/src/Filament/Pages/ManageCampaignSettings.php b/app-modules/campaign/src/Filament/Pages/ManageCampaignSettings.php index 80da9539db..fd69dc52c8 100644 --- a/app-modules/campaign/src/Filament/Pages/ManageCampaignSettings.php +++ b/app-modules/campaign/src/Filament/Pages/ManageCampaignSettings.php @@ -38,7 +38,6 @@ use Filament\Forms\Form; use Filament\Pages\SettingsPage; -use App\Filament\Pages\EmailConfiguration; use AdvisingApp\Campaign\Settings\CampaignSettings; use Tapp\FilamentTimezoneField\Forms\Components\TimezoneSelect; @@ -72,9 +71,4 @@ public function form(Form $form): Form ->placeholder(fn (TimezoneSelect $component): string => $component->getOptions()[config('app.timezone')]), ]); } - - public function getSubNavigation(): array - { - return (new EmailConfiguration())->getSubNavigation(); - } } diff --git a/app-modules/consent/src/Filament/Resources/ConsentAgreementResource.php b/app-modules/consent/src/Filament/Resources/ConsentAgreementResource.php index c6691dfb6f..37af75e678 100644 --- a/app-modules/consent/src/Filament/Resources/ConsentAgreementResource.php +++ b/app-modules/consent/src/Filament/Resources/ConsentAgreementResource.php @@ -38,13 +38,16 @@ use Filament\Resources\Resource; use AdvisingApp\Consent\Models\ConsentAgreement; +use App\Filament\Clusters\ArtificialIntelligence; use AdvisingApp\Consent\Filament\Resources\ConsentAgreementResource\Pages; class ConsentAgreementResource extends Resource { protected static ?string $model = ConsentAgreement::class; - protected static bool $shouldRegisterNavigation = false; + protected static ?string $cluster = ArtificialIntelligence::class; + + protected static ?string $navigationLabel = 'User Agreement'; public static function getRelations(): array { diff --git a/app-modules/consent/src/Filament/Resources/ConsentAgreementResource/Pages/ListConsentAgreements.php b/app-modules/consent/src/Filament/Resources/ConsentAgreementResource/Pages/ListConsentAgreements.php index 9b9b244fde..0ffce5ad3c 100644 --- a/app-modules/consent/src/Filament/Resources/ConsentAgreementResource/Pages/ListConsentAgreements.php +++ b/app-modules/consent/src/Filament/Resources/ConsentAgreementResource/Pages/ListConsentAgreements.php @@ -36,7 +36,6 @@ namespace AdvisingApp\Consent\Filament\Resources\ConsentAgreementResource\Pages; -use App\Models\User; use Filament\Forms\Form; use Filament\Tables\Table; use App\Filament\Columns\IdColumn; @@ -47,33 +46,14 @@ use Filament\Tables\Columns\TextColumn; use Filament\Forms\Components\TextInput; use Filament\Resources\Pages\ListRecords; -use AdvisingApp\Assistant\Filament\Pages\AssistantConfiguration; use AdvisingApp\Consent\Filament\Resources\ConsentAgreementResource; class ListConsentAgreements extends ListRecords { protected static string $resource = ConsentAgreementResource::class; - protected static ?string $navigationLabel = 'User Agreement'; - protected static ?string $title = 'User Agreement'; - public function getBreadcrumbs(): array - { - return [ - AssistantConfiguration::getUrl() => 'Artificial Intelligence', - $this::getUrl() => 'User Agreement', - ]; - } - - public static function shouldRegisterNavigation(array $parameters = []): bool - { - /** @var User $user */ - $user = auth()->user(); - - return $user->can(['consent_agreement.view-any', 'consent_agreement.*.view', 'consent_agreement.*.update']); - } - public function form(Form $form): Form { return $form @@ -129,11 +109,6 @@ public function table(Table $table): Table ->bulkActions([]); } - public function getSubNavigation(): array - { - return (new AssistantConfiguration())->getSubNavigation(); - } - protected function getHeaderActions(): array { return []; diff --git a/app-modules/engagement/src/Filament/Pages/MessageCenter.php b/app-modules/engagement/src/Filament/Pages/MessageCenter.php index 562f3d4cfb..f444423aea 100644 --- a/app-modules/engagement/src/Filament/Pages/MessageCenter.php +++ b/app-modules/engagement/src/Filament/Pages/MessageCenter.php @@ -117,11 +117,15 @@ class MessageCenter extends Page public int $inboxPerPage = 10; - public static function shouldRegisterNavigation(): bool + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); + if (! $user->can('viewAny', Engagement::class)) { + return false; + } + return $user->can('engagement.view_message_center'); } @@ -133,9 +137,6 @@ public function mount(): void $this->user = $user; $this->timelineRecords = collect(); - - $this->authorize('viewAny', Engagement::class); - $this->authorize('engagement.view_message_center'); } public function updated($property): void diff --git a/app-modules/engagement/src/Filament/Resources/EmailTemplateResource.php b/app-modules/engagement/src/Filament/Resources/EmailTemplateResource.php index 2e5c05a3af..10b2226522 100644 --- a/app-modules/engagement/src/Filament/Resources/EmailTemplateResource.php +++ b/app-modules/engagement/src/Filament/Resources/EmailTemplateResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\Engagement\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\GlobalSettings; use AdvisingApp\Engagement\Models\EmailTemplate; use AdvisingApp\Engagement\Filament\Resources\EmailTemplateResource\Pages\EditEmailTemplate; use AdvisingApp\Engagement\Filament\Resources\EmailTemplateResource\Pages\ListEmailTemplates; @@ -46,13 +47,13 @@ class EmailTemplateResource extends Resource { protected static ?string $model = EmailTemplate::class; - protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; + protected static ?string $navigationIcon = 'heroicon-o-envelope'; - protected static ?string $navigationGroup = 'Product Administration'; + protected static ?string $navigationGroup = 'Communication'; protected static ?int $navigationSort = 120; - protected static bool $shouldRegisterNavigation = false; + protected static ?string $cluster = GlobalSettings::class; public static function getPages(): array { diff --git a/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/CreateEmailTemplate.php b/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/CreateEmailTemplate.php index 55c56e9b2a..6c777cc95c 100644 --- a/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/CreateEmailTemplate.php +++ b/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/CreateEmailTemplate.php @@ -41,7 +41,6 @@ use FilamentTiptapEditor\TiptapEditor; use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; -use App\Filament\Pages\EmailConfiguration; use Filament\Resources\Pages\CreateRecord; use FilamentTiptapEditor\Enums\TiptapOutput; use AdvisingApp\Engagement\Filament\Resources\EmailTemplateResource; @@ -50,14 +49,6 @@ class CreateEmailTemplate extends CreateRecord { protected static string $resource = EmailTemplateResource::class; - public function getBreadcrumbs(): array - { - return [ - ...(new EmailConfiguration())->getBreadcrumbs(), - ...parent::getBreadcrumbs(), - ]; - } - public function form(Form $form): Form { return $form diff --git a/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/EditEmailTemplate.php b/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/EditEmailTemplate.php index 1b14a4f8ce..53c49e868c 100644 --- a/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/EditEmailTemplate.php +++ b/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/EditEmailTemplate.php @@ -42,7 +42,6 @@ use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use Filament\Resources\Pages\EditRecord; -use App\Filament\Pages\EmailConfiguration; use FilamentTiptapEditor\Enums\TiptapOutput; use AdvisingApp\Engagement\Filament\Resources\EmailTemplateResource; @@ -50,14 +49,6 @@ class EditEmailTemplate extends EditRecord { protected static string $resource = EmailTemplateResource::class; - public function getBreadcrumbs(): array - { - return [ - ...(new EmailConfiguration())->getBreadcrumbs(), - ...parent::getBreadcrumbs(), - ]; - } - public function form(Form $form): Form { return $form diff --git a/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/ListEmailTemplates.php b/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/ListEmailTemplates.php index a37cdf4f67..610e1391fb 100644 --- a/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/ListEmailTemplates.php +++ b/app-modules/engagement/src/Filament/Resources/EmailTemplateResource/Pages/ListEmailTemplates.php @@ -36,42 +36,19 @@ namespace AdvisingApp\Engagement\Filament\Resources\EmailTemplateResource\Pages; -use App\Models\User; use Filament\Tables\Table; use Filament\Actions\CreateAction; use Filament\Tables\Actions\EditAction; use Filament\Resources\Pages\ListRecords; -use App\Filament\Pages\EmailConfiguration; use Filament\Tables\Actions\BulkActionGroup; use Filament\Tables\Actions\DeleteBulkAction; use App\Filament\Columns\OpenSearch\TextColumn; -use AdvisingApp\Engagement\Models\EmailTemplate; use AdvisingApp\Engagement\Filament\Resources\EmailTemplateResource; class ListEmailTemplates extends ListRecords { protected static string $resource = EmailTemplateResource::class; - protected static ?string $navigationIcon = 'heroicon-o-envelope'; - - protected static ?string $navigationLabel = 'Email Templates'; - - public static function shouldRegisterNavigation(array $parameters = []): bool - { - /** @var User $user */ - $user = auth()->user(); - - return $user->can('viewAny', EmailTemplate::class); - } - - public function getBreadcrumbs(): array - { - return [ - ...(new EmailConfiguration())->getBreadcrumbs(), - ...parent::getBreadcrumbs(), - ]; - } - public function table(Table $table): Table { return $table @@ -91,11 +68,6 @@ public function table(Table $table): Table ]); } - public function getSubNavigation(): array - { - return (new EmailConfiguration())->getSubNavigation(); - } - protected function getHeaderActions(): array { return [ diff --git a/app-modules/engagement/src/Filament/Resources/SmsTemplateResource.php b/app-modules/engagement/src/Filament/Resources/SmsTemplateResource.php index b8f0e22a12..91ad297945 100644 --- a/app-modules/engagement/src/Filament/Resources/SmsTemplateResource.php +++ b/app-modules/engagement/src/Filament/Resources/SmsTemplateResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\Engagement\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\GlobalSettings; use AdvisingApp\Engagement\Models\SmsTemplate; use AdvisingApp\Engagement\Filament\Resources\SmsTemplateResource\Pages\EditSmsTemplate; use AdvisingApp\Engagement\Filament\Resources\SmsTemplateResource\Pages\ListSmsTemplates; @@ -46,9 +47,9 @@ class SmsTemplateResource extends Resource { protected static ?string $model = SmsTemplate::class; - protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; + protected static ?string $navigationIcon = 'heroicon-o-device-phone-mobile'; - protected static ?string $navigationGroup = 'Product Administration'; + protected static ?string $navigationGroup = 'Communication'; protected static ?string $navigationLabel = 'Text Message Templates'; @@ -56,7 +57,7 @@ class SmsTemplateResource extends Resource protected static ?int $navigationSort = 130; - protected static bool $shouldRegisterNavigation = false; + protected static ?string $cluster = GlobalSettings::class; public static function getPages(): array { diff --git a/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/CreateSmsTemplate.php b/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/CreateSmsTemplate.php index 53dc39b180..ec1eaf4959 100644 --- a/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/CreateSmsTemplate.php +++ b/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/CreateSmsTemplate.php @@ -41,7 +41,6 @@ use FilamentTiptapEditor\TiptapEditor; use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; -use App\Filament\Pages\EmailConfiguration; use Filament\Resources\Pages\CreateRecord; use FilamentTiptapEditor\Enums\TiptapOutput; use AdvisingApp\Engagement\Filament\Resources\SmsTemplateResource; @@ -50,14 +49,6 @@ class CreateSmsTemplate extends CreateRecord { protected static string $resource = SmsTemplateResource::class; - public function getBreadcrumbs(): array - { - return [ - ...(new EmailConfiguration())->getBreadcrumbs(), - ...parent::getBreadcrumbs(), - ]; - } - public function form(Form $form): Form { return $form diff --git a/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/EditSmsTemplate.php b/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/EditSmsTemplate.php index 8e625873fd..72bd7ffc84 100644 --- a/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/EditSmsTemplate.php +++ b/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/EditSmsTemplate.php @@ -42,7 +42,6 @@ use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use Filament\Resources\Pages\EditRecord; -use App\Filament\Pages\EmailConfiguration; use FilamentTiptapEditor\Enums\TiptapOutput; use AdvisingApp\Engagement\Filament\Resources\SmsTemplateResource; @@ -50,14 +49,6 @@ class EditSmsTemplate extends EditRecord { protected static string $resource = SmsTemplateResource::class; - public function getBreadcrumbs(): array - { - return [ - ...(new EmailConfiguration())->getBreadcrumbs(), - ...parent::getBreadcrumbs(), - ]; - } - public function form(Form $form): Form { return $form diff --git a/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/ListSmsTemplates.php b/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/ListSmsTemplates.php index 21eecf22ba..7a223d1427 100644 --- a/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/ListSmsTemplates.php +++ b/app-modules/engagement/src/Filament/Resources/SmsTemplateResource/Pages/ListSmsTemplates.php @@ -36,42 +36,19 @@ namespace AdvisingApp\Engagement\Filament\Resources\SmsTemplateResource\Pages; -use App\Models\User; use Filament\Tables\Table; use Filament\Actions\CreateAction; use Filament\Tables\Actions\EditAction; use Filament\Tables\Columns\TextColumn; use Filament\Resources\Pages\ListRecords; -use App\Filament\Pages\EmailConfiguration; use Filament\Tables\Actions\BulkActionGroup; use Filament\Tables\Actions\DeleteBulkAction; -use AdvisingApp\Engagement\Models\SmsTemplate; use AdvisingApp\Engagement\Filament\Resources\SmsTemplateResource; class ListSmsTemplates extends ListRecords { protected static string $resource = SmsTemplateResource::class; - protected static ?string $navigationIcon = 'heroicon-o-chat-bubble-oval-left-ellipsis'; - - protected static ?string $navigationLabel = 'Text Message Templates'; - - public static function shouldRegisterNavigation(array $parameters = []): bool - { - /** @var User $user */ - $user = auth()->user(); - - return $user->can('viewAny', SmsTemplate::class); - } - - public function getBreadcrumbs(): array - { - return [ - ...(new EmailConfiguration())->getBreadcrumbs(), - ...parent::getBreadcrumbs(), - ]; - } - public function table(Table $table): Table { return $table @@ -91,11 +68,6 @@ public function table(Table $table): Table ]); } - public function getSubNavigation(): array - { - return (new EmailConfiguration())->getSubNavigation(); - } - protected function getHeaderActions(): array { return [ diff --git a/app-modules/in-app-communication/src/Filament/Pages/UserChat.php b/app-modules/in-app-communication/src/Filament/Pages/UserChat.php index 4ce8db1a6e..043bf68391 100644 --- a/app-modules/in-app-communication/src/Filament/Pages/UserChat.php +++ b/app-modules/in-app-communication/src/Filament/Pages/UserChat.php @@ -82,7 +82,7 @@ class UserChat extends Page implements HasForms, HasActions protected static ?string $title = 'Realtime Chat'; - public static function shouldRegisterNavigation(): bool + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -92,9 +92,6 @@ public static function shouldRegisterNavigation(): bool public function mount() { - $this->authorize(Feature::RealtimeChat->getGateName()); - $this->authorize('in-app-communication.realtime-chat.access'); - /** @var User $user */ $user = auth()->user(); diff --git a/app-modules/integration-aws-ses-event-handling/src/Filament/Pages/ManageAmazonSesSettings.php b/app-modules/integration-aws-ses-event-handling/src/Filament/Pages/ManageAmazonSesSettings.php index 540852448a..9f36cebea7 100644 --- a/app-modules/integration-aws-ses-event-handling/src/Filament/Pages/ManageAmazonSesSettings.php +++ b/app-modules/integration-aws-ses-event-handling/src/Filament/Pages/ManageAmazonSesSettings.php @@ -41,6 +41,7 @@ use Filament\Pages\SettingsPage; use Filament\Forms\Components\Section; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\ProductIntegrations; use AdvisingApp\IntegrationAwsSesEventHandling\Settings\SesSettings; class ManageAmazonSesSettings extends SettingsPage @@ -53,13 +54,11 @@ class ManageAmazonSesSettings extends SettingsPage protected static ?string $navigationLabel = 'Amazon SES'; - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?string $navigationParentItem = 'Product Integrations'; - protected static ?int $navigationSort = 50; - public static function shouldRegisterNavigation(): bool + protected static ?string $cluster = ProductIntegrations::class; + + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -67,13 +66,6 @@ public static function shouldRegisterNavigation(): bool return $user->can('integration-aws-ses-event-handling.view_ses_settings'); } - public function mount(): void - { - $this->authorize('integration-aws-ses-event-handling.view_ses_settings'); - - parent::mount(); - } - public function form(Form $form): Form { return $form diff --git a/app-modules/integration-google-analytics/src/Filament/Pages/ManageGoogleAnalyticsSettings.php b/app-modules/integration-google-analytics/src/Filament/Pages/ManageGoogleAnalyticsSettings.php index 1298aee632..5b96871e97 100644 --- a/app-modules/integration-google-analytics/src/Filament/Pages/ManageGoogleAnalyticsSettings.php +++ b/app-modules/integration-google-analytics/src/Filament/Pages/ManageGoogleAnalyticsSettings.php @@ -42,6 +42,7 @@ use Filament\Pages\SettingsPage; use Filament\Forms\Components\Toggle; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\ProductIntegrations; use AdvisingApp\IntegrationGoogleAnalytics\Settings\GoogleAnalyticsSettings; class ManageGoogleAnalyticsSettings extends SettingsPage @@ -54,13 +55,11 @@ class ManageGoogleAnalyticsSettings extends SettingsPage protected static ?string $navigationLabel = 'Google Analytics'; - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?string $navigationParentItem = 'Product Integrations'; - protected static ?int $navigationSort = 10; - public static function shouldRegisterNavigation(): bool + protected static ?string $cluster = ProductIntegrations::class; + + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -68,13 +67,6 @@ public static function shouldRegisterNavigation(): bool return $user->can('integration-google-analytics.view_google_analytics_settings'); } - public function mount(): void - { - $this->authorize('integration-google-analytics.view_google_analytics_settings'); - - parent::mount(); - } - public function form(Form $form): Form { return $form diff --git a/app-modules/integration-google-recaptcha/src/Filament/Pages/ManageGoogleRecaptchaSettings.php b/app-modules/integration-google-recaptcha/src/Filament/Pages/ManageGoogleRecaptchaSettings.php index a5965d4e0e..663e14bc99 100644 --- a/app-modules/integration-google-recaptcha/src/Filament/Pages/ManageGoogleRecaptchaSettings.php +++ b/app-modules/integration-google-recaptcha/src/Filament/Pages/ManageGoogleRecaptchaSettings.php @@ -42,6 +42,7 @@ use Filament\Pages\SettingsPage; use Filament\Forms\Components\Toggle; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\ProductIntegrations; use AdvisingApp\IntegrationGoogleRecaptcha\Settings\GoogleRecaptchaSettings; class ManageGoogleRecaptchaSettings extends SettingsPage @@ -54,13 +55,11 @@ class ManageGoogleRecaptchaSettings extends SettingsPage protected static ?string $navigationLabel = 'Google ReCAPTCHA'; - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?string $navigationParentItem = 'Product Integrations'; - protected static ?int $navigationSort = 20; - public static function shouldRegisterNavigation(): bool + protected static ?string $cluster = ProductIntegrations::class; + + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -68,13 +67,6 @@ public static function shouldRegisterNavigation(): bool return $user->can('integration-google-recaptcha.view_google_recaptcha_settings'); } - public function mount(): void - { - $this->authorize('integration-google-recaptcha.view_google_recaptcha_settings'); - - parent::mount(); - } - public function form(Form $form): Form { return $form diff --git a/app-modules/integration-microsoft-clarity/src/Filament/Pages/ManageMicrosoftClaritySettings.php b/app-modules/integration-microsoft-clarity/src/Filament/Pages/ManageMicrosoftClaritySettings.php index 0b593e4234..421a4eac7a 100644 --- a/app-modules/integration-microsoft-clarity/src/Filament/Pages/ManageMicrosoftClaritySettings.php +++ b/app-modules/integration-microsoft-clarity/src/Filament/Pages/ManageMicrosoftClaritySettings.php @@ -42,6 +42,7 @@ use Filament\Pages\SettingsPage; use Filament\Forms\Components\Toggle; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\ProductIntegrations; use AdvisingApp\IntegrationMicrosoftClarity\Settings\MicrosoftClaritySettings; class ManageMicrosoftClaritySettings extends SettingsPage @@ -54,13 +55,11 @@ class ManageMicrosoftClaritySettings extends SettingsPage protected static ?string $navigationLabel = 'Microsoft Clarity'; - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?string $navigationParentItem = 'Product Integrations'; - protected static ?int $navigationSort = 30; - public static function shouldRegisterNavigation(): bool + protected static ?string $cluster = ProductIntegrations::class; + + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -68,13 +67,6 @@ public static function shouldRegisterNavigation(): bool return $user->can('integration-microsoft-clarity.view_microsoft_clarity_settings'); } - public function mount(): void - { - $this->authorize('integration-microsoft-clarity.view_microsoft_clarity_settings'); - - parent::mount(); - } - public function form(Form $form): Form { return $form diff --git a/app-modules/integration-twilio/src/Filament/Pages/ManageTwilioSettings.php b/app-modules/integration-twilio/src/Filament/Pages/ManageTwilioSettings.php index 7a7b79680d..fc6ac1fd4e 100644 --- a/app-modules/integration-twilio/src/Filament/Pages/ManageTwilioSettings.php +++ b/app-modules/integration-twilio/src/Filament/Pages/ManageTwilioSettings.php @@ -43,6 +43,7 @@ use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Section; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\ProductIntegrations; use AdvisingApp\IntegrationTwilio\Settings\TwilioSettings; class ManageTwilioSettings extends SettingsPage @@ -55,13 +56,11 @@ class ManageTwilioSettings extends SettingsPage protected static ?string $navigationLabel = 'Twilio'; - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?string $navigationParentItem = 'Product Integrations'; - protected static ?int $navigationSort = 40; - public static function shouldRegisterNavigation(): bool + protected static ?string $cluster = ProductIntegrations::class; + + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -69,13 +68,6 @@ public static function shouldRegisterNavigation(): bool return $user->can('integration-twilio.view_twilio_settings'); } - public function mount(): void - { - $this->authorize('integration-twilio.view_twilio_settings'); - - parent::mount(); - } - public function form(Form $form): Form { return $form diff --git a/app-modules/interaction/src/Filament/Resources/InteractionCampaignResource.php b/app-modules/interaction/src/Filament/Resources/InteractionCampaignResource.php index 883a2fb1ff..a1f242f359 100644 --- a/app-modules/interaction/src/Filament/Resources/InteractionCampaignResource.php +++ b/app-modules/interaction/src/Filament/Resources/InteractionCampaignResource.php @@ -39,6 +39,7 @@ use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\InteractionManagement; use AdvisingApp\Interaction\Models\InteractionCampaign; use AdvisingApp\Interaction\Filament\Resources\InteractionCampaignResource\Pages\EditInteractionCampaign; use AdvisingApp\Interaction\Filament\Resources\InteractionCampaignResource\Pages\ListInteractionCampaigns; @@ -50,14 +51,12 @@ class InteractionCampaignResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-megaphone'; - protected static ?string $navigationParentItem = 'Interaction Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Campaigns'; protected static ?int $navigationSort = 1; + protected static ?string $cluster = InteractionManagement::class; + public static function form(Form $form): Form { return $form diff --git a/app-modules/interaction/src/Filament/Resources/InteractionDriverResource.php b/app-modules/interaction/src/Filament/Resources/InteractionDriverResource.php index 71bac3244b..8abe729db2 100644 --- a/app-modules/interaction/src/Filament/Resources/InteractionDriverResource.php +++ b/app-modules/interaction/src/Filament/Resources/InteractionDriverResource.php @@ -39,6 +39,7 @@ use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\InteractionManagement; use AdvisingApp\Interaction\Models\InteractionDriver; use AdvisingApp\Interaction\Filament\Resources\InteractionDriverResource\Pages\EditInteractionDriver; use AdvisingApp\Interaction\Filament\Resources\InteractionDriverResource\Pages\ListInteractionDrivers; @@ -50,14 +51,12 @@ class InteractionDriverResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-cursor-arrow-ripple'; - protected static ?string $navigationParentItem = 'Interaction Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Drivers'; protected static ?int $navigationSort = 2; + protected static ?string $cluster = InteractionManagement::class; + public static function form(Form $form): Form { return $form diff --git a/app-modules/interaction/src/Filament/Resources/InteractionOutcomeResource.php b/app-modules/interaction/src/Filament/Resources/InteractionOutcomeResource.php index 3d784a8836..95e59ffd34 100644 --- a/app-modules/interaction/src/Filament/Resources/InteractionOutcomeResource.php +++ b/app-modules/interaction/src/Filament/Resources/InteractionOutcomeResource.php @@ -39,6 +39,7 @@ use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\InteractionManagement; use AdvisingApp\Interaction\Models\InteractionOutcome; use AdvisingApp\Interaction\Filament\Resources\InteractionOutcomeResource\Pages\EditInteractionOutcome; use AdvisingApp\Interaction\Filament\Resources\InteractionOutcomeResource\Pages\ListInteractionOutcomes; @@ -50,14 +51,12 @@ class InteractionOutcomeResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-map'; - protected static ?string $navigationParentItem = 'Interaction Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Outcomes'; protected static ?int $navigationSort = 3; + protected static ?string $cluster = InteractionManagement::class; + public static function form(Form $form): Form { return $form diff --git a/app-modules/interaction/src/Filament/Resources/InteractionRelationResource.php b/app-modules/interaction/src/Filament/Resources/InteractionRelationResource.php index 9bf6dc1e81..8c25443d79 100644 --- a/app-modules/interaction/src/Filament/Resources/InteractionRelationResource.php +++ b/app-modules/interaction/src/Filament/Resources/InteractionRelationResource.php @@ -39,6 +39,7 @@ use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\InteractionManagement; use AdvisingApp\Interaction\Models\InteractionRelation; use AdvisingApp\Interaction\Filament\Resources\InteractionRelationResource\Pages\EditInteractionRelation; use AdvisingApp\Interaction\Filament\Resources\InteractionRelationResource\Pages\ListInteractionRelations; @@ -50,14 +51,12 @@ class InteractionRelationResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-arrows-right-left'; - protected static ?string $navigationParentItem = 'Interaction Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Relations'; protected static ?int $navigationSort = 4; + protected static ?string $cluster = InteractionManagement::class; + public static function form(Form $form): Form { return $form diff --git a/app-modules/interaction/src/Filament/Resources/InteractionStatusResource.php b/app-modules/interaction/src/Filament/Resources/InteractionStatusResource.php index 757ef5a190..51065c842e 100644 --- a/app-modules/interaction/src/Filament/Resources/InteractionStatusResource.php +++ b/app-modules/interaction/src/Filament/Resources/InteractionStatusResource.php @@ -40,6 +40,7 @@ use Filament\Resources\Resource; use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\InteractionManagement; use AdvisingApp\Interaction\Models\InteractionStatus; use AdvisingApp\Interaction\Enums\InteractionStatusColorOptions; use AdvisingApp\Interaction\Filament\Resources\InteractionStatusResource\Pages\EditInteractionStatus; @@ -52,14 +53,12 @@ class InteractionStatusResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-tag'; - protected static ?string $navigationParentItem = 'Interaction Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Statuses'; protected static ?int $navigationSort = 5; + protected static ?string $cluster = InteractionManagement::class; + public static function form(Form $form): Form { return $form diff --git a/app-modules/interaction/src/Filament/Resources/InteractionTypeResource.php b/app-modules/interaction/src/Filament/Resources/InteractionTypeResource.php index 4bbf7fa4a8..33cb9b1c11 100644 --- a/app-modules/interaction/src/Filament/Resources/InteractionTypeResource.php +++ b/app-modules/interaction/src/Filament/Resources/InteractionTypeResource.php @@ -39,6 +39,7 @@ use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\InteractionManagement; use AdvisingApp\Interaction\Models\InteractionType; use AdvisingApp\Interaction\Filament\Resources\InteractionTypeResource\Pages\EditInteractionType; use AdvisingApp\Interaction\Filament\Resources\InteractionTypeResource\Pages\ListInteractionTypes; @@ -50,14 +51,12 @@ class InteractionTypeResource extends Resource protected static ?string $navigationIcon = 'heroicon-m-rectangle-stack'; - protected static ?string $navigationParentItem = 'Interaction Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Types'; protected static ?int $navigationSort = 6; + protected static ?string $cluster = InteractionManagement::class; + public static function form(Form $form): Form { return $form diff --git a/app-modules/inventory-management/src/Filament/Resources/AssetLocationResource.php b/app-modules/inventory-management/src/Filament/Resources/AssetLocationResource.php index adc0a611a5..05a57b0a64 100644 --- a/app-modules/inventory-management/src/Filament/Resources/AssetLocationResource.php +++ b/app-modules/inventory-management/src/Filament/Resources/AssetLocationResource.php @@ -39,6 +39,7 @@ use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\AssetManagement; use AdvisingApp\InventoryManagement\Models\AssetLocation; use AdvisingApp\InventoryManagement\Filament\Resources\AssetLocationResource\Pages\ViewAssetLocation; use AdvisingApp\InventoryManagement\Filament\Resources\AssetLocationResource\Pages\ListAssetLocations; @@ -50,14 +51,12 @@ class AssetLocationResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-map-pin'; - protected static ?string $navigationParentItem = 'Asset Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Locations'; protected static ?int $navigationSort = 1; + protected static ?string $cluster = AssetManagement::class; + public static function form(Form $form): Form { return $form diff --git a/app-modules/inventory-management/src/Filament/Resources/AssetResource.php b/app-modules/inventory-management/src/Filament/Resources/AssetResource.php index d5337bb3b3..8bd47e5141 100644 --- a/app-modules/inventory-management/src/Filament/Resources/AssetResource.php +++ b/app-modules/inventory-management/src/Filament/Resources/AssetResource.php @@ -44,6 +44,7 @@ use Filament\Forms\Components\TextInput; use Filament\Forms\Components\DatePicker; use Illuminate\Contracts\Support\Htmlable; +use App\Filament\Clusters\ServiceManagement; use AdvisingApp\InventoryManagement\Models\Asset; use AdvisingApp\InventoryManagement\Models\AssetType; use AdvisingApp\InventoryManagement\Models\AssetStatus; @@ -62,13 +63,11 @@ class AssetResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-archive-box'; - protected static ?string $navigationGroup = 'Service Management'; - - protected static ?int $navigationSort = 30; + protected static ?int $navigationSort = 20; protected static ?string $breadcrumb = 'Asset Management'; - protected static bool $shouldRegisterNavigation = false; + protected static ?string $cluster = ServiceManagement::class; public function getTitle(): string | Htmlable { diff --git a/app-modules/inventory-management/src/Filament/Resources/AssetResource/Pages/ManageAssetMaintenanceActivity.php b/app-modules/inventory-management/src/Filament/Resources/AssetResource/Pages/ManageAssetMaintenanceActivity.php index 3743b5eb43..8c691205e9 100644 --- a/app-modules/inventory-management/src/Filament/Resources/AssetResource/Pages/ManageAssetMaintenanceActivity.php +++ b/app-modules/inventory-management/src/Filament/Resources/AssetResource/Pages/ManageAssetMaintenanceActivity.php @@ -60,9 +60,9 @@ public function getTitle(): string | Htmlable return 'Manage Asset Maintenance Activity'; } - public static function canAccess(?Model $record = null): bool + public static function canAccess(array $arguments = []): bool { - return (bool) count(static::managers($record)); + return (bool) count(static::managers($arguments['record'] ?? null)); } public function getRelationManagers(): array @@ -70,12 +70,12 @@ public function getRelationManagers(): array return static::managers($this->getRecord()); } - private static function managers(Model $record): array + private static function managers(?Model $record = null): array { return collect([ MaintenanceActivitiesRelationManager::class, ]) - ->reject(fn ($relationManager) => ! $relationManager::canViewForRecord($record, static::class)) + ->reject(fn ($relationManager) => $record && (! $relationManager::canViewForRecord($record, static::class))) ->toArray(); } } diff --git a/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource.php b/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource.php index 27fb478ec5..194a98ba73 100644 --- a/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource.php +++ b/app-modules/inventory-management/src/Filament/Resources/AssetStatusResource.php @@ -39,6 +39,7 @@ use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\AssetManagement; use AdvisingApp\InventoryManagement\Models\AssetStatus; use AdvisingApp\InventoryManagement\Filament\Resources\AssetStatusResource\Pages\ViewAssetStatus; use AdvisingApp\InventoryManagement\Filament\Resources\AssetStatusResource\Pages\CreateAssetStatus; @@ -50,14 +51,12 @@ class AssetStatusResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-tag'; - protected static ?string $navigationParentItem = 'Asset Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Statuses'; protected static ?int $navigationSort = 2; + protected static ?string $cluster = AssetManagement::class; + public static function form(Form $form): Form { return $form diff --git a/app-modules/inventory-management/src/Filament/Resources/AssetTypeResource.php b/app-modules/inventory-management/src/Filament/Resources/AssetTypeResource.php index e8f40207aa..95b892e9b3 100644 --- a/app-modules/inventory-management/src/Filament/Resources/AssetTypeResource.php +++ b/app-modules/inventory-management/src/Filament/Resources/AssetTypeResource.php @@ -39,6 +39,7 @@ use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\AssetManagement; use AdvisingApp\InventoryManagement\Models\AssetType; use AdvisingApp\InventoryManagement\Filament\Resources\AssetTypeResource\Pages\ViewAssetType; use AdvisingApp\InventoryManagement\Filament\Resources\AssetTypeResource\Pages\ListAssetTypes; @@ -50,14 +51,12 @@ class AssetTypeResource extends Resource protected static ?string $navigationIcon = 'heroicon-m-rectangle-stack'; - protected static ?string $navigationParentItem = 'Asset Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Types'; protected static ?int $navigationSort = 3; + protected static ?string $cluster = AssetManagement::class; + public static function form(Form $form): Form { return $form diff --git a/app-modules/inventory-management/src/Policies/AssetCheckInPolicy.php b/app-modules/inventory-management/src/Policies/AssetCheckInPolicy.php index 9e57d18e83..630cfa035c 100644 --- a/app-modules/inventory-management/src/Policies/AssetCheckInPolicy.php +++ b/app-modules/inventory-management/src/Policies/AssetCheckInPolicy.php @@ -36,12 +36,32 @@ namespace AdvisingApp\InventoryManagement\Policies; +use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\InventoryManagement\Models\AssetCheckIn; class AssetCheckInPolicy { + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } + public function viewAny(Authenticatable $authenticatable): Response { return $authenticatable->canOrElse( @@ -97,4 +117,9 @@ public function forceDelete(Authenticatable $authenticatable, AssetCheckIn $asse denyResponse: 'You do not have permission to permanently delete this asset check in.' ); } + + protected function requiredFeatures(): array + { + return [Feature::ServiceManagement]; + } } diff --git a/app-modules/inventory-management/src/Policies/AssetCheckOutPolicy.php b/app-modules/inventory-management/src/Policies/AssetCheckOutPolicy.php index cd227de8ca..3dfba4a620 100644 --- a/app-modules/inventory-management/src/Policies/AssetCheckOutPolicy.php +++ b/app-modules/inventory-management/src/Policies/AssetCheckOutPolicy.php @@ -36,12 +36,32 @@ namespace AdvisingApp\InventoryManagement\Policies; +use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\InventoryManagement\Models\AssetCheckOut; class AssetCheckOutPolicy { + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } + public function viewAny(Authenticatable $authenticatable): Response { return $authenticatable->canOrElse( @@ -97,4 +117,9 @@ public function forceDelete(Authenticatable $authenticatable, AssetCheckOut $ass denyResponse: 'You do not have permission to permanently delete this asset check out.' ); } + + protected function requiredFeatures(): array + { + return [Feature::ServiceManagement]; + } } diff --git a/app-modules/inventory-management/src/Policies/AssetLocationPolicy.php b/app-modules/inventory-management/src/Policies/AssetLocationPolicy.php index f6500dc256..40c019d5c5 100644 --- a/app-modules/inventory-management/src/Policies/AssetLocationPolicy.php +++ b/app-modules/inventory-management/src/Policies/AssetLocationPolicy.php @@ -36,12 +36,32 @@ namespace AdvisingApp\InventoryManagement\Policies; +use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\InventoryManagement\Models\AssetLocation; class AssetLocationPolicy { + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } + public function viewAny(Authenticatable $authenticatable): Response { return $authenticatable->canOrElse( @@ -97,4 +117,9 @@ public function forceDelete(Authenticatable $authenticatable, AssetLocation $ass denyResponse: 'You do not have permission to permanently delete this asset location.' ); } + + protected function requiredFeatures(): array + { + return [Feature::ServiceManagement]; + } } diff --git a/app-modules/inventory-management/src/Policies/AssetPolicy.php b/app-modules/inventory-management/src/Policies/AssetPolicy.php index ec0b8e5140..72a7a01686 100644 --- a/app-modules/inventory-management/src/Policies/AssetPolicy.php +++ b/app-modules/inventory-management/src/Policies/AssetPolicy.php @@ -36,12 +36,32 @@ namespace AdvisingApp\InventoryManagement\Policies; +use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\InventoryManagement\Models\Asset; class AssetPolicy { + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } + public function viewAny(Authenticatable $authenticatable): Response { return $authenticatable->canOrElse( @@ -97,4 +117,9 @@ public function forceDelete(Authenticatable $authenticatable, Asset $asset): Res denyResponse: 'You do not have permission to permanently delete this asset.' ); } + + protected function requiredFeatures(): array + { + return [Feature::ServiceManagement]; + } } diff --git a/app-modules/inventory-management/src/Policies/AssetStatusPolicy.php b/app-modules/inventory-management/src/Policies/AssetStatusPolicy.php index 1e973501b9..1132aef85a 100644 --- a/app-modules/inventory-management/src/Policies/AssetStatusPolicy.php +++ b/app-modules/inventory-management/src/Policies/AssetStatusPolicy.php @@ -36,12 +36,32 @@ namespace AdvisingApp\InventoryManagement\Policies; +use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\InventoryManagement\Models\AssetStatus; class AssetStatusPolicy { + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } + public function viewAny(Authenticatable $authenticatable): Response { return $authenticatable->canOrElse( @@ -97,4 +117,9 @@ public function forceDelete(Authenticatable $authenticatable, AssetStatus $asset denyResponse: 'You do not have permission to permanently delete this asset status.' ); } + + protected function requiredFeatures(): array + { + return [Feature::ServiceManagement]; + } } diff --git a/app-modules/inventory-management/src/Policies/AssetTypePolicy.php b/app-modules/inventory-management/src/Policies/AssetTypePolicy.php index 952f9140ad..0e9e3211d7 100644 --- a/app-modules/inventory-management/src/Policies/AssetTypePolicy.php +++ b/app-modules/inventory-management/src/Policies/AssetTypePolicy.php @@ -36,12 +36,32 @@ namespace AdvisingApp\InventoryManagement\Policies; +use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\InventoryManagement\Models\AssetType; class AssetTypePolicy { + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } + public function viewAny(Authenticatable $authenticatable): Response { return $authenticatable->canOrElse( @@ -97,4 +117,9 @@ public function forceDelete(Authenticatable $authenticatable, AssetType $assetTy denyResponse: 'You do not have permission to permanently delete this asset type.' ); } + + protected function requiredFeatures(): array + { + return [Feature::ServiceManagement]; + } } diff --git a/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseCategoryResource.php b/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseCategoryResource.php index c49b5c77bf..47f32558ff 100644 --- a/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseCategoryResource.php +++ b/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseCategoryResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\KnowledgeBase\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\KnowledgeManagement; use AdvisingApp\KnowledgeBase\Models\KnowledgeBaseCategory; use AdvisingApp\KnowledgeBase\Filament\Resources\KnowledgeBaseCategoryResource\Pages\EditKnowledgeBaseCategory; use AdvisingApp\KnowledgeBase\Filament\Resources\KnowledgeBaseCategoryResource\Pages\ViewKnowledgeBaseCategory; @@ -49,14 +50,12 @@ class KnowledgeBaseCategoryResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; - protected static ?string $navigationParentItem = 'Knowledge Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Categories'; protected static ?int $navigationSort = 1; + protected static ?string $cluster = KnowledgeManagement::class; + public static function getPages(): array { return [ diff --git a/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseQualityResource.php b/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseQualityResource.php index 73d203d1b3..05e6c29073 100644 --- a/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseQualityResource.php +++ b/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseQualityResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\KnowledgeBase\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\KnowledgeManagement; use AdvisingApp\KnowledgeBase\Models\KnowledgeBaseQuality; use AdvisingApp\KnowledgeBase\Filament\Resources\KnowledgeBaseQualityResource\Pages\EditKnowledgeBaseQuality; use AdvisingApp\KnowledgeBase\Filament\Resources\KnowledgeBaseQualityResource\Pages\ViewKnowledgeBaseQuality; @@ -49,14 +50,12 @@ class KnowledgeBaseQualityResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; - protected static ?string $navigationParentItem = 'Knowledge Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Qualities'; protected static ?int $navigationSort = 2; + protected static ?string $cluster = KnowledgeManagement::class; + public static function getPages(): array { return [ diff --git a/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseStatusResource.php b/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseStatusResource.php index 427d981b7e..26ce4448ac 100644 --- a/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseStatusResource.php +++ b/app-modules/knowledge-base/src/Filament/Resources/KnowledgeBaseStatusResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\KnowledgeBase\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\KnowledgeManagement; use AdvisingApp\KnowledgeBase\Models\KnowledgeBaseStatus; use AdvisingApp\KnowledgeBase\Filament\Resources\KnowledgeBaseStatusResource\Pages\EditKnowledgeBaseStatus; use AdvisingApp\KnowledgeBase\Filament\Resources\KnowledgeBaseStatusResource\Pages\ViewKnowledgeBaseStatus; @@ -49,14 +50,12 @@ class KnowledgeBaseStatusResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-tag'; - protected static ?string $navigationParentItem = 'Knowledge Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Statuses'; protected static ?int $navigationSort = 3; + protected static ?string $cluster = KnowledgeManagement::class; + public static function getPages(): array { return [ diff --git a/app-modules/portal/src/Filament/Pages/ManagePortalSettings.php b/app-modules/portal/src/Filament/Pages/ManagePortalSettings.php index d6283ac2fe..2d3ab0ce63 100644 --- a/app-modules/portal/src/Filament/Pages/ManagePortalSettings.php +++ b/app-modules/portal/src/Filament/Pages/ManagePortalSettings.php @@ -45,6 +45,7 @@ use App\Filament\Fields\TiptapEditor; use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Section; +use App\Filament\Clusters\GlobalSettings; use Filament\Forms\Components\ColorPicker; use FilamentTiptapEditor\Enums\TiptapOutput; use AdvisingApp\Portal\Settings\PortalSettings; @@ -56,17 +57,15 @@ class ManagePortalSettings extends SettingsPage protected static ?string $navigationLabel = 'Portals'; - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?string $navigationParentItem = 'Global Settings'; - protected static ?int $navigationSort = 60; protected static string $settings = PortalSettings::class; protected static ?string $title = 'Portals'; - public static function shouldRegisterNavigation(): bool + protected static ?string $cluster = GlobalSettings::class; + + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -74,13 +73,6 @@ public static function shouldRegisterNavigation(): bool return $user->can('portal.view_portal_settings'); } - public function mount(): void - { - $this->authorize('portal.view_portal_settings'); - - parent::mount(); - } - public function form(Form $form): Form { return $form diff --git a/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectEngagement.php b/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectEngagement.php index 26f40323d0..577416bac3 100644 --- a/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectEngagement.php +++ b/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectEngagement.php @@ -61,9 +61,9 @@ public function getTitle(): string | Htmlable return 'Manage Prospect Email and Texts'; } - public static function canAccess(?Model $record = null): bool + public static function canAccess(array $arguments = []): bool { - return (bool) count(static::managers($record)); + return (bool) count(static::managers($arguments['record'] ?? null)); } public function getRelationManagers(): array @@ -71,13 +71,13 @@ public function getRelationManagers(): array return static::managers($this->getRecord()); } - private static function managers(Model $record): array + private static function managers(?Model $record = null): array { return collect([ EngagementsRelationManager::class, EngagementResponsesRelationManager::class, ]) - ->reject(fn ($relationManager) => ! $relationManager::canViewForRecord($record, static::class)) + ->reject(fn ($relationManager) => $record && (! $relationManager::canViewForRecord($record, static::class))) ->toArray(); } } diff --git a/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectFiles.php b/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectFiles.php index a18236efbf..f372315397 100644 --- a/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectFiles.php +++ b/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectFiles.php @@ -54,9 +54,9 @@ class ManageProspectFiles extends ManageRelatedRecords protected static ?string $navigationIcon = 'heroicon-o-folder'; - public static function canAccess(?Model $record = null): bool + public static function canAccess(array $arguments = []): bool { - return (bool) count(static::managers($record)); + return (bool) count(static::managers($arguments['record'] ?? null)); } public function getRelationManagers(): array @@ -64,12 +64,12 @@ public function getRelationManagers(): array return static::managers($this->getRecord()); } - private static function managers(Model $record): array + private static function managers(?Model $record = null): array { return collect([ EngagementFilesRelationManager::class, ]) - ->reject(fn ($relationManager) => ! $relationManager::canViewForRecord($record, static::class)) + ->reject(fn ($relationManager) => $record && (! $relationManager::canViewForRecord($record, static::class))) ->toArray(); } } diff --git a/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectServiceRequests.php b/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectServiceRequests.php index d1f93355ac..3af94f8f30 100644 --- a/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectServiceRequests.php +++ b/app-modules/prospect/src/Filament/Resources/ProspectResource/Pages/ManageProspectServiceRequests.php @@ -61,9 +61,9 @@ public function getTitle(): string | Htmlable return 'Manage Prospect Service Requests'; } - public static function canAccess(?Model $record = null): bool + public static function canAccess(array $arguments = []): bool { - return (bool) count(static::managers($record)); + return (bool) count(static::managers($arguments['record'] ?? null)); } public function getRelationManagers(): array @@ -71,12 +71,12 @@ public function getRelationManagers(): array return static::managers($this->getRecord()); } - private static function managers(Model $record): array + private static function managers(?Model $record = null): array { return collect([ ServiceRequestsRelationManager::class, ]) - ->reject(fn ($relationManager) => ! $relationManager::canViewForRecord($record, static::class)) + ->reject(fn ($relationManager) => $record && (! $relationManager::canViewForRecord($record, static::class))) ->toArray(); } } diff --git a/app-modules/prospect/src/Filament/Resources/ProspectSourceResource.php b/app-modules/prospect/src/Filament/Resources/ProspectSourceResource.php index ba7a550de9..b6204ba7ef 100644 --- a/app-modules/prospect/src/Filament/Resources/ProspectSourceResource.php +++ b/app-modules/prospect/src/Filament/Resources/ProspectSourceResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\Prospect\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\RecruitmentCrm; use AdvisingApp\Prospect\Models\ProspectSource; use AdvisingApp\Prospect\Filament\Resources\ProspectSourceResource\Pages; @@ -46,18 +47,15 @@ class ProspectSourceResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-viewfinder-circle'; - protected static ?string $navigationParentItem = 'Recruitment CRM'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Sources'; protected static ?int $navigationSort = 2; + protected static ?string $cluster = RecruitmentCrm::class; + public static function getRelations(): array { - return [ - ]; + return []; } public static function getPages(): array diff --git a/app-modules/prospect/src/Filament/Resources/ProspectStatusResource.php b/app-modules/prospect/src/Filament/Resources/ProspectStatusResource.php index d1f1d02ba3..a2ee89de0e 100644 --- a/app-modules/prospect/src/Filament/Resources/ProspectStatusResource.php +++ b/app-modules/prospect/src/Filament/Resources/ProspectStatusResource.php @@ -38,6 +38,7 @@ use Filament\Forms\Form; use Filament\Resources\Resource; +use App\Filament\Clusters\RecruitmentCrm; use AdvisingApp\Prospect\Models\ProspectStatus; use AdvisingApp\Prospect\Filament\Resources\ProspectStatusResource\Pages; @@ -47,14 +48,12 @@ class ProspectStatusResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-tag'; - protected static ?string $navigationParentItem = 'Recruitment CRM'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Statuses'; protected static ?int $navigationSort = 1; + protected static ?string $cluster = RecruitmentCrm::class; + public static function form(Form $form): Form { return $form diff --git a/app-modules/service-management/src/Filament/Resources/ServiceRequestPriorityResource.php b/app-modules/service-management/src/Filament/Resources/ServiceRequestPriorityResource.php index e9d2c9f14a..14a87b105b 100644 --- a/app-modules/service-management/src/Filament/Resources/ServiceRequestPriorityResource.php +++ b/app-modules/service-management/src/Filament/Resources/ServiceRequestPriorityResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\ServiceManagement\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\ServiceManagementAdministration; use AdvisingApp\ServiceManagement\Models\ServiceRequestPriority; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestPriorityResource\Pages\EditServiceRequestPriority; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestPriorityResource\Pages\ViewServiceRequestPriority; @@ -49,14 +50,12 @@ class ServiceRequestPriorityResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-arrows-up-down'; - protected static ?string $navigationParentItem = 'Service Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Priorities'; protected static ?int $navigationSort = 1; + protected static ?string $cluster = ServiceManagementAdministration::class; + public static function getPages(): array { return [ diff --git a/app-modules/service-management/src/Filament/Resources/ServiceRequestResource.php b/app-modules/service-management/src/Filament/Resources/ServiceRequestResource.php index 8cd9130fc8..b0fb25fa47 100644 --- a/app-modules/service-management/src/Filament/Resources/ServiceRequestResource.php +++ b/app-modules/service-management/src/Filament/Resources/ServiceRequestResource.php @@ -38,6 +38,7 @@ use Filament\Resources\Resource; use Filament\Resources\Pages\Page; +use App\Filament\Clusters\ServiceManagement; use AdvisingApp\ServiceManagement\Models\ServiceRequest; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestResource\Pages\EditServiceRequest; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestResource\Pages\ViewServiceRequest; @@ -54,15 +55,9 @@ class ServiceRequestResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-briefcase'; - protected static ?string $navigationGroup = 'Premium Features'; + protected static ?int $navigationSort = 10; - protected static ?int $navigationSort = 30; - - protected static ?string $navigationLabel = 'Service Management'; - - protected static ?string $modelLabel = 'Service Request'; - - protected static ?string $breadcrumb = 'Service Management'; + protected static ?string $cluster = ServiceManagement::class; public static function getRecordSubNavigation(Page $page): array { diff --git a/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestAssignment.php b/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestAssignment.php index 0d01fd5d62..b88cef4df1 100644 --- a/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestAssignment.php +++ b/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestAssignment.php @@ -55,9 +55,9 @@ class ManageServiceRequestAssignment extends ManageRelatedRecords protected static ?string $navigationIcon = 'heroicon-o-users'; - public static function canAccess(?Model $record = null): bool + public static function canAccess(array $arguments = []): bool { - return (bool) count(static::managers($record)); + return (bool) count(static::managers($arguments['record'] ?? null)); } public function getRelationManagers(): array @@ -65,13 +65,13 @@ public function getRelationManagers(): array return static::managers($this->getRecord()); } - private static function managers(Model $record): array + private static function managers(?Model $record = null): array { return collect([ AssignedToRelationManager::class, CreatedByRelationManager::class, ]) - ->reject(fn ($relationManager) => ! $relationManager::canViewForRecord($record, static::class)) + ->reject(fn ($relationManager) => $record && (! $relationManager::canViewForRecord($record, static::class))) ->toArray(); } } diff --git a/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestInteraction.php b/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestInteraction.php index 4f7316ba92..b213cad230 100644 --- a/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestInteraction.php +++ b/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestInteraction.php @@ -54,9 +54,9 @@ class ManageServiceRequestInteraction extends ManageRelatedRecords protected static ?string $navigationIcon = 'heroicon-o-arrow-path-rounded-square'; - public static function canAccess(?Model $record = null): bool + public static function canAccess(array $arguments = []): bool { - return (bool) count(static::managers($record)); + return (bool) count(static::managers($arguments['record'] ?? null)); } public function getRelationManagers(): array @@ -64,12 +64,12 @@ public function getRelationManagers(): array return static::managers($this->getRecord()); } - private static function managers(Model $record): array + private static function managers(?Model $record = null): array { return collect([ InteractionsRelationManager::class, ]) - ->reject(fn ($relationManager) => ! $relationManager::canViewForRecord($record, static::class)) + ->reject(fn ($relationManager) => $record && (! $relationManager::canViewForRecord($record, static::class))) ->toArray(); } } diff --git a/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestUpdate.php b/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestUpdate.php index 8668e87b74..df921619a1 100644 --- a/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestUpdate.php +++ b/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/Pages/ManageServiceRequestUpdate.php @@ -54,9 +54,9 @@ class ManageServiceRequestUpdate extends ManageRelatedRecords protected static ?string $navigationIcon = 'heroicon-o-adjustments-vertical'; - public static function canAccess(?Model $record = null): bool + public static function canAccess(array $arguments = []): bool { - return (bool) count(static::managers($record)); + return (bool) count(static::managers($arguments['record'] ?? null)); } public function getRelationManagers(): array @@ -64,12 +64,12 @@ public function getRelationManagers(): array return static::managers($this->getRecord()); } - private static function managers(Model $record): array + private static function managers(?Model $record = null): array { return collect([ ServiceRequestUpdatesRelationManager::class, ]) - ->reject(fn ($relationManager) => ! $relationManager::canViewForRecord($record, static::class)) + ->reject(fn ($relationManager) => $record && (! $relationManager::canViewForRecord($record, static::class))) ->toArray(); } } diff --git a/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource.php b/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource.php index f6f03de6b9..89d717150f 100644 --- a/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource.php +++ b/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\ServiceManagement\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\ServiceManagementAdministration; use AdvisingApp\ServiceManagement\Models\ServiceRequestStatus; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource\Pages\EditServiceRequestStatus; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource\Pages\ViewServiceRequestStatus; @@ -49,14 +50,12 @@ class ServiceRequestStatusResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-tag'; - protected static ?string $navigationParentItem = 'Service Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Statuses'; protected static ?int $navigationSort = 2; + protected static ?string $cluster = ServiceManagementAdministration::class; + public static function getPages(): array { return [ diff --git a/app-modules/service-management/src/Filament/Resources/ServiceRequestTypeResource.php b/app-modules/service-management/src/Filament/Resources/ServiceRequestTypeResource.php index 1074c10cc9..e108c8b151 100644 --- a/app-modules/service-management/src/Filament/Resources/ServiceRequestTypeResource.php +++ b/app-modules/service-management/src/Filament/Resources/ServiceRequestTypeResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\ServiceManagement\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\ServiceManagementAdministration; use AdvisingApp\ServiceManagement\Models\ServiceRequestType; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestTypeResource\Pages\EditServiceRequestType; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestTypeResource\Pages\ViewServiceRequestType; @@ -49,14 +50,12 @@ class ServiceRequestTypeResource extends Resource protected static ?string $navigationIcon = 'heroicon-m-rectangle-stack'; - protected static ?string $navigationParentItem = 'Service Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Types'; protected static ?int $navigationSort = 3; + protected static ?string $cluster = ServiceManagementAdministration::class; + public static function getPages(): array { return [ diff --git a/app-modules/service-management/src/Policies/ServiceRequestAssignmentPolicy.php b/app-modules/service-management/src/Policies/ServiceRequestAssignmentPolicy.php index 6258416bc3..6c52cf9cff 100644 --- a/app-modules/service-management/src/Policies/ServiceRequestAssignmentPolicy.php +++ b/app-modules/service-management/src/Policies/ServiceRequestAssignmentPolicy.php @@ -39,13 +39,28 @@ use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; -use App\Concerns\FeatureAccessEnforcedPolicyBefore; -use App\Policies\Contracts\FeatureAccessEnforcedPolicy; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestAssignment; -class ServiceRequestAssignmentPolicy implements FeatureAccessEnforcedPolicy +class ServiceRequestAssignmentPolicy { - use FeatureAccessEnforcedPolicyBefore; + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } public function viewAny(Authenticatable $authenticatable): Response { diff --git a/app-modules/service-management/src/Policies/ServiceRequestHistoryPolicy.php b/app-modules/service-management/src/Policies/ServiceRequestHistoryPolicy.php index d99a96a347..dbbbafbff9 100644 --- a/app-modules/service-management/src/Policies/ServiceRequestHistoryPolicy.php +++ b/app-modules/service-management/src/Policies/ServiceRequestHistoryPolicy.php @@ -39,13 +39,28 @@ use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; -use App\Concerns\FeatureAccessEnforcedPolicyBefore; -use App\Policies\Contracts\FeatureAccessEnforcedPolicy; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestHistory; -class ServiceRequestHistoryPolicy implements FeatureAccessEnforcedPolicy +class ServiceRequestHistoryPolicy { - use FeatureAccessEnforcedPolicyBefore; + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } public function viewAny(Authenticatable $authenticatable): Response { diff --git a/app-modules/service-management/src/Policies/ServiceRequestPolicy.php b/app-modules/service-management/src/Policies/ServiceRequestPolicy.php index 764e157912..b634395311 100644 --- a/app-modules/service-management/src/Policies/ServiceRequestPolicy.php +++ b/app-modules/service-management/src/Policies/ServiceRequestPolicy.php @@ -39,13 +39,28 @@ use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; -use App\Concerns\FeatureAccessEnforcedPolicyBefore; -use App\Policies\Contracts\FeatureAccessEnforcedPolicy; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequest; -class ServiceRequestPolicy implements FeatureAccessEnforcedPolicy +class ServiceRequestPolicy { - use FeatureAccessEnforcedPolicyBefore; + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } public function viewAny(Authenticatable $authenticatable): Response { diff --git a/app-modules/service-management/src/Policies/ServiceRequestPriorityPolicy.php b/app-modules/service-management/src/Policies/ServiceRequestPriorityPolicy.php index 84ced8a002..451e1efae1 100644 --- a/app-modules/service-management/src/Policies/ServiceRequestPriorityPolicy.php +++ b/app-modules/service-management/src/Policies/ServiceRequestPriorityPolicy.php @@ -39,13 +39,28 @@ use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; -use App\Concerns\FeatureAccessEnforcedPolicyBefore; -use App\Policies\Contracts\FeatureAccessEnforcedPolicy; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestPriority; -class ServiceRequestPriorityPolicy implements FeatureAccessEnforcedPolicy +class ServiceRequestPriorityPolicy { - use FeatureAccessEnforcedPolicyBefore; + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } public function viewAny(Authenticatable $authenticatable): Response { diff --git a/app-modules/service-management/src/Policies/ServiceRequestStatusPolicy.php b/app-modules/service-management/src/Policies/ServiceRequestStatusPolicy.php index fde684d696..903015cb96 100644 --- a/app-modules/service-management/src/Policies/ServiceRequestStatusPolicy.php +++ b/app-modules/service-management/src/Policies/ServiceRequestStatusPolicy.php @@ -39,13 +39,28 @@ use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; -use App\Concerns\FeatureAccessEnforcedPolicyBefore; -use App\Policies\Contracts\FeatureAccessEnforcedPolicy; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestStatus; -class ServiceRequestStatusPolicy implements FeatureAccessEnforcedPolicy +class ServiceRequestStatusPolicy { - use FeatureAccessEnforcedPolicyBefore; + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } public function viewAny(Authenticatable $authenticatable): Response { diff --git a/app-modules/service-management/src/Policies/ServiceRequestTypePolicy.php b/app-modules/service-management/src/Policies/ServiceRequestTypePolicy.php index 349df3a9f5..25261fd89e 100644 --- a/app-modules/service-management/src/Policies/ServiceRequestTypePolicy.php +++ b/app-modules/service-management/src/Policies/ServiceRequestTypePolicy.php @@ -39,13 +39,28 @@ use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; -use App\Concerns\FeatureAccessEnforcedPolicyBefore; -use App\Policies\Contracts\FeatureAccessEnforcedPolicy; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestType; -class ServiceRequestTypePolicy implements FeatureAccessEnforcedPolicy +class ServiceRequestTypePolicy { - use FeatureAccessEnforcedPolicyBefore; + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } public function viewAny(Authenticatable $authenticatable): Response { diff --git a/app-modules/service-management/src/Policies/ServiceRequestUpdatePolicy.php b/app-modules/service-management/src/Policies/ServiceRequestUpdatePolicy.php index b6fd91298e..173463fc5e 100644 --- a/app-modules/service-management/src/Policies/ServiceRequestUpdatePolicy.php +++ b/app-modules/service-management/src/Policies/ServiceRequestUpdatePolicy.php @@ -39,13 +39,28 @@ use App\Enums\Feature; use App\Models\Authenticatable; use Illuminate\Auth\Access\Response; -use App\Concerns\FeatureAccessEnforcedPolicyBefore; -use App\Policies\Contracts\FeatureAccessEnforcedPolicy; +use Illuminate\Support\Facades\Gate; +use App\Support\FeatureAccessResponse; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestUpdate; -class ServiceRequestUpdatePolicy implements FeatureAccessEnforcedPolicy +class ServiceRequestUpdatePolicy { - use FeatureAccessEnforcedPolicyBefore; + public function before(Authenticatable $authenticatable): ?Response + { + if (! $authenticatable->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()])) { + return Response::deny('You are not licensed for the Retention or Recruitment CRM.'); + } + + if (! Gate::check( + collect($this->requiredFeatures())->map(fn (Feature $feature) => $feature->getGateName()) + )) { + return FeatureAccessResponse::deny(); + } + + return null; + } public function viewAny(Authenticatable $authenticatable): Response { diff --git a/app-modules/service-management/tests/ServiceRequest/ListServiceRequestsTest.php b/app-modules/service-management/tests/ServiceRequest/ListServiceRequestsTest.php index 97086c9b0a..fc2b78a1ee 100644 --- a/app-modules/service-management/tests/ServiceRequest/ListServiceRequestsTest.php +++ b/app-modules/service-management/tests/ServiceRequest/ListServiceRequestsTest.php @@ -43,6 +43,8 @@ use function Pest\Laravel\actingAs; use function Pest\Livewire\livewire; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequest; use AdvisingApp\ServiceManagement\Models\ServiceRequestAssignment; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestResource; @@ -106,7 +108,7 @@ // Permission Tests test('ListServiceRequests is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); actingAs($user) ->get( @@ -128,7 +130,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request.view-any'); diff --git a/app-modules/service-management/tests/ServiceRequestPriority/CreateServiceRequestPriorityTest.php b/app-modules/service-management/tests/ServiceRequestPriority/CreateServiceRequestPriorityTest.php index 1cb8248d32..bd0398aaba 100644 --- a/app-modules/service-management/tests/ServiceRequestPriority/CreateServiceRequestPriorityTest.php +++ b/app-modules/service-management/tests/ServiceRequestPriority/CreateServiceRequestPriorityTest.php @@ -42,10 +42,14 @@ use function Pest\Laravel\actingAs; use function Pest\Livewire\livewire; + +use AdvisingApp\Prospect\Models\Prospect; + use function PHPUnit\Framework\assertCount; use function PHPUnit\Framework\assertEmpty; use function Pest\Laravel\assertDatabaseHas; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestPriority; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestPriorityResource; use AdvisingApp\ServiceManagement\Tests\RequestFactories\CreateServiceRequestPriorityRequestFactory; @@ -91,7 +95,7 @@ // Permission Tests test('CreateServiceRequestPriority is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); actingAs($user) ->get( @@ -128,7 +132,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_priority.view-any'); $user->givePermissionTo('service_request_priority.create'); diff --git a/app-modules/service-management/tests/ServiceRequestPriority/EditServiceRequestPriorityTest.php b/app-modules/service-management/tests/ServiceRequestPriority/EditServiceRequestPriorityTest.php index c37fb7acdf..7f7599109c 100644 --- a/app-modules/service-management/tests/ServiceRequestPriority/EditServiceRequestPriorityTest.php +++ b/app-modules/service-management/tests/ServiceRequestPriority/EditServiceRequestPriorityTest.php @@ -42,9 +42,13 @@ use function Pest\Laravel\actingAs; use function Pest\Livewire\livewire; + +use AdvisingApp\Prospect\Models\Prospect; + use function Pest\Laravel\assertDatabaseHas; use function PHPUnit\Framework\assertEquals; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestPriority; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestPriorityResource; use AdvisingApp\ServiceManagement\Tests\RequestFactories\EditServiceRequestPriorityRequestFactory; @@ -102,7 +106,7 @@ // Permission Tests test('EditServiceRequestPriority is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $serviceRequestPriority = ServiceRequestPriority::factory()->create(); @@ -147,7 +151,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_priority.view-any'); $user->givePermissionTo('service_request_priority.*.update'); diff --git a/app-modules/service-management/tests/ServiceRequestPriority/ListServiceRequestPrioritiesTest.php b/app-modules/service-management/tests/ServiceRequestPriority/ListServiceRequestPrioritiesTest.php index e2109153ac..3865195d1d 100644 --- a/app-modules/service-management/tests/ServiceRequestPriority/ListServiceRequestPrioritiesTest.php +++ b/app-modules/service-management/tests/ServiceRequestPriority/ListServiceRequestPrioritiesTest.php @@ -43,6 +43,8 @@ use function Pest\Laravel\actingAs; use function Pest\Livewire\livewire; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequest; use AdvisingApp\ServiceManagement\Models\ServiceRequestPriority; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestPriorityResource; @@ -89,7 +91,7 @@ // Permission Tests test('ListServiceRequestPriorities is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); actingAs($user) ->get( @@ -111,7 +113,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_priority.view-any'); diff --git a/app-modules/service-management/tests/ServiceRequestPriority/ViewServiceRequestPriorityTest.php b/app-modules/service-management/tests/ServiceRequestPriority/ViewServiceRequestPriorityTest.php index baac133a50..788d6bfcb7 100644 --- a/app-modules/service-management/tests/ServiceRequestPriority/ViewServiceRequestPriorityTest.php +++ b/app-modules/service-management/tests/ServiceRequestPriority/ViewServiceRequestPriorityTest.php @@ -42,6 +42,8 @@ use function Pest\Laravel\actingAs; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestPriority; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestPriorityResource; @@ -68,7 +70,7 @@ // Permission Tests test('ViewServiceRequestPriority is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $prospectSource = ServiceRequestPriority::factory()->create(); @@ -97,7 +99,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_priority.view-any'); $user->givePermissionTo('service_request_priority.*.view'); diff --git a/app-modules/service-management/tests/ServiceRequestStatus/CreateServiceRequestStatusTest.php b/app-modules/service-management/tests/ServiceRequestStatus/CreateServiceRequestStatusTest.php index 878ed4e937..044d52dd9e 100644 --- a/app-modules/service-management/tests/ServiceRequestStatus/CreateServiceRequestStatusTest.php +++ b/app-modules/service-management/tests/ServiceRequestStatus/CreateServiceRequestStatusTest.php @@ -44,11 +44,13 @@ use function Pest\Livewire\livewire; use Illuminate\Validation\Rules\Enum; +use AdvisingApp\Prospect\Models\Prospect; use function PHPUnit\Framework\assertCount; use function PHPUnit\Framework\assertEmpty; use function Pest\Laravel\assertDatabaseHas; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestStatus; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource; use AdvisingApp\ServiceManagement\Tests\RequestFactories\CreateServiceRequestStatusRequestFactory; @@ -94,7 +96,7 @@ // Permission Tests test('CreateServiceRequestStatus is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); actingAs($user) ->get( @@ -131,7 +133,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_status.view-any'); $user->givePermissionTo('service_request_status.create'); diff --git a/app-modules/service-management/tests/ServiceRequestStatus/EditServiceRequestStatusTest.php b/app-modules/service-management/tests/ServiceRequestStatus/EditServiceRequestStatusTest.php index 7ce9c2d13c..396e1aef3c 100644 --- a/app-modules/service-management/tests/ServiceRequestStatus/EditServiceRequestStatusTest.php +++ b/app-modules/service-management/tests/ServiceRequestStatus/EditServiceRequestStatusTest.php @@ -44,10 +44,12 @@ use function Pest\Livewire\livewire; use Illuminate\Validation\Rules\Enum; +use AdvisingApp\Prospect\Models\Prospect; use function Pest\Laravel\assertDatabaseHas; use function PHPUnit\Framework\assertEquals; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestStatus; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource; use AdvisingApp\ServiceManagement\Tests\RequestFactories\EditServiceRequestStatusRequestFactory; @@ -113,7 +115,7 @@ // Permission Tests test('EditServiceRequestStatus is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $serviceRequestStatus = ServiceRequestStatus::factory()->create(); @@ -158,7 +160,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_status.view-any'); $user->givePermissionTo('service_request_status.*.update'); diff --git a/app-modules/service-management/tests/ServiceRequestStatus/ListServiceRequestStatusesTest.php b/app-modules/service-management/tests/ServiceRequestStatus/ListServiceRequestStatusesTest.php index f9cc3b7937..6fe54f5e72 100644 --- a/app-modules/service-management/tests/ServiceRequestStatus/ListServiceRequestStatusesTest.php +++ b/app-modules/service-management/tests/ServiceRequestStatus/ListServiceRequestStatusesTest.php @@ -43,6 +43,8 @@ use function Pest\Laravel\actingAs; use function Pest\Livewire\livewire; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequest; use AdvisingApp\ServiceManagement\Models\ServiceRequestStatus; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource; @@ -94,7 +96,7 @@ // Permission Tests test('ListServiceRequestStatuses is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); actingAs($user) ->get( @@ -116,7 +118,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_status.view-any'); diff --git a/app-modules/service-management/tests/ServiceRequestStatus/ViewServiceRequestStatusTest.php b/app-modules/service-management/tests/ServiceRequestStatus/ViewServiceRequestStatusTest.php index 8562847e6a..f9fd4dc6ad 100644 --- a/app-modules/service-management/tests/ServiceRequestStatus/ViewServiceRequestStatusTest.php +++ b/app-modules/service-management/tests/ServiceRequestStatus/ViewServiceRequestStatusTest.php @@ -42,6 +42,8 @@ use function Pest\Laravel\actingAs; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestStatus; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource; @@ -68,7 +70,7 @@ // Permission Tests test('ViewServiceRequestStatus is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $prospectSource = ServiceRequestStatus::factory()->create(); @@ -97,7 +99,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_status.view-any'); $user->givePermissionTo('service_request_status.*.view'); diff --git a/app-modules/service-management/tests/ServiceRequestType/CreateServiceRequestTypeTest.php b/app-modules/service-management/tests/ServiceRequestType/CreateServiceRequestTypeTest.php index 6e2aa777a0..41664000c4 100644 --- a/app-modules/service-management/tests/ServiceRequestType/CreateServiceRequestTypeTest.php +++ b/app-modules/service-management/tests/ServiceRequestType/CreateServiceRequestTypeTest.php @@ -42,10 +42,14 @@ use function Pest\Laravel\actingAs; use function Pest\Livewire\livewire; + +use AdvisingApp\Prospect\Models\Prospect; + use function PHPUnit\Framework\assertCount; use function PHPUnit\Framework\assertEmpty; use function Pest\Laravel\assertDatabaseHas; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestType; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestTypeResource; use AdvisingApp\ServiceManagement\Tests\RequestFactories\CreateServiceRequestTypeRequestFactory; @@ -89,7 +93,7 @@ // Permission Tests test('CreateServiceRequestType is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); actingAs($user) ->get( @@ -126,7 +130,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_type.view-any'); $user->givePermissionTo('service_request_type.create'); diff --git a/app-modules/service-management/tests/ServiceRequestType/EditServiceRequestTypeTest.php b/app-modules/service-management/tests/ServiceRequestType/EditServiceRequestTypeTest.php index bb345f823c..9f2d017e99 100644 --- a/app-modules/service-management/tests/ServiceRequestType/EditServiceRequestTypeTest.php +++ b/app-modules/service-management/tests/ServiceRequestType/EditServiceRequestTypeTest.php @@ -42,9 +42,13 @@ use function Pest\Laravel\actingAs; use function Pest\Livewire\livewire; + +use AdvisingApp\Prospect\Models\Prospect; + use function Pest\Laravel\assertDatabaseHas; use function PHPUnit\Framework\assertEquals; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestType; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestTypeResource; use AdvisingApp\ServiceManagement\Tests\RequestFactories\EditServiceRequestTypeRequestFactory; @@ -102,7 +106,7 @@ // Permission Tests test('EditServiceRequestType is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $serviceRequestType = ServiceRequestType::factory()->create(); @@ -147,7 +151,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_type.view-any'); $user->givePermissionTo('service_request_type.*.update'); diff --git a/app-modules/service-management/tests/ServiceRequestType/ListServiceRequestTypeTest.php b/app-modules/service-management/tests/ServiceRequestType/ListServiceRequestTypeTest.php index 6d74c49fa1..793b0c60a4 100644 --- a/app-modules/service-management/tests/ServiceRequestType/ListServiceRequestTypeTest.php +++ b/app-modules/service-management/tests/ServiceRequestType/ListServiceRequestTypeTest.php @@ -43,6 +43,8 @@ use function Pest\Laravel\actingAs; use function Pest\Livewire\livewire; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequest; use AdvisingApp\ServiceManagement\Models\ServiceRequestType; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestTypeResource; @@ -84,7 +86,7 @@ // Permission Tests test('ListServiceRequestTypes is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); actingAs($user) ->get( @@ -106,7 +108,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_type.view-any'); diff --git a/app-modules/service-management/tests/ServiceRequestType/ViewServiceRequestTypeTest.php b/app-modules/service-management/tests/ServiceRequestType/ViewServiceRequestTypeTest.php index 7abeb18d92..408f206bf5 100644 --- a/app-modules/service-management/tests/ServiceRequestType/ViewServiceRequestTypeTest.php +++ b/app-modules/service-management/tests/ServiceRequestType/ViewServiceRequestTypeTest.php @@ -42,6 +42,8 @@ use function Pest\Laravel\actingAs; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequestType; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestTypeResource; @@ -66,7 +68,7 @@ // Permission Tests test('ViewServiceRequestType is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $serviceRequestType = ServiceRequestType::factory()->create(); @@ -95,7 +97,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_type.view-any'); $user->givePermissionTo('service_request_type.*.view'); diff --git a/app-modules/service-management/tests/ServiceRequestUpdate/ListServiceRequestUpdatesTest.php b/app-modules/service-management/tests/ServiceRequestUpdate/ListServiceRequestUpdatesTest.php index f5328d0b60..cce61e4b9c 100644 --- a/app-modules/service-management/tests/ServiceRequestUpdate/ListServiceRequestUpdatesTest.php +++ b/app-modules/service-management/tests/ServiceRequestUpdate/ListServiceRequestUpdatesTest.php @@ -44,6 +44,8 @@ use function Pest\Laravel\actingAs; use function Pest\Livewire\livewire; +use AdvisingApp\Prospect\Models\Prospect; +use AdvisingApp\StudentDataModel\Models\Student; use AdvisingApp\ServiceManagement\Models\ServiceRequest; use AdvisingApp\ServiceManagement\Models\ServiceRequestUpdate; use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestUpdateResource; @@ -107,7 +109,7 @@ // Permission Tests test('ListServiceRequestUpdates is gated with proper access control', function () { - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); actingAs($user) ->get( @@ -129,7 +131,7 @@ $settings->save(); - $user = User::factory()->create(); + $user = User::factory()->licensed([Student::getLicenseType(), Prospect::getLicenseType()])->create(); $user->givePermissionTo('service_request_update.view-any'); diff --git a/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentEngagement.php b/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentEngagement.php index 65cbbd5352..9b8f430e0f 100644 --- a/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentEngagement.php +++ b/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentEngagement.php @@ -61,9 +61,9 @@ public function getTitle(): string | Htmlable return 'Manage Student Email and Texts'; } - public static function canAccess(?Model $record = null): bool + public static function canAccess(array $arguments = []): bool { - return (bool) count(static::managers($record)); + return (bool) count(static::managers($arguments['record'] ?? null)); } public function getRelationManagers(): array @@ -71,13 +71,13 @@ public function getRelationManagers(): array return static::managers($this->getRecord()); } - private static function managers(Model $record): array + private static function managers(?Model $record = null): array { return collect([ EngagementsRelationManager::class, EngagementResponsesRelationManager::class, ]) - ->reject(fn ($relationManager) => ! $relationManager::canViewForRecord($record, static::class)) + ->reject(fn ($relationManager) => $record && (! $relationManager::canViewForRecord($record, static::class))) ->toArray(); } } diff --git a/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentFiles.php b/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentFiles.php index 403fa1ff53..d9b02a3694 100644 --- a/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentFiles.php +++ b/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentFiles.php @@ -54,9 +54,9 @@ class ManageStudentFiles extends ManageRelatedRecords protected static ?string $navigationIcon = 'heroicon-o-folder'; - public static function canAccess(?Model $record = null): bool + public static function canAccess(array $arguments = []): bool { - return (bool) count(static::managers($record)); + return (bool) count(static::managers($arguments['record'] ?? null)); } public function getRelationManagers(): array @@ -64,12 +64,12 @@ public function getRelationManagers(): array return static::managers($this->getRecord()); } - private static function managers(Model $record): array + private static function managers(?Model $record = null): array { return collect([ EngagementFilesRelationManager::class, ]) - ->reject(fn ($relationManager) => ! $relationManager::canViewForRecord($record, static::class)) + ->reject(fn ($relationManager) => $record && (! $relationManager::canViewForRecord($record, static::class))) ->toArray(); } } diff --git a/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentInformation.php b/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentInformation.php index 2de3a4945c..71dc2a7299 100644 --- a/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentInformation.php +++ b/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentInformation.php @@ -56,9 +56,9 @@ class ManageStudentInformation extends ManageRelatedRecords protected static ?string $navigationIcon = 'heroicon-o-information-circle'; - public static function canAccess(?Model $record = null): bool + public static function canAccess(array $arguments = []): bool { - return (bool) count(static::managers($record)); + return (bool) count(static::managers($arguments['record'] ?? null)); } public function getRelationManagers(): array @@ -66,14 +66,14 @@ public function getRelationManagers(): array return static::managers($this->getRecord()); } - private static function managers(Model $record): array + private static function managers(?Model $record = null): array { return collect([ ProgramsRelationManager::class, EnrollmentsRelationManager::class, PerformanceRelationManager::class, ]) - ->reject(fn ($relationManager) => ! $relationManager::canViewForRecord($record, static::class)) + ->reject(fn ($relationManager) => $record && (! $relationManager::canViewForRecord($record, static::class))) ->toArray(); } } diff --git a/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentServiceRequests.php b/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentServiceRequests.php index c057e562d9..cf0037bc0d 100644 --- a/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentServiceRequests.php +++ b/app-modules/student-data-model/src/Filament/Resources/StudentResource/Pages/ManageStudentServiceRequests.php @@ -61,9 +61,9 @@ public function getTitle(): string | Htmlable return 'Manage Student Service Requests'; } - public static function canAccess(?Model $record = null): bool + public static function canAccess(array $arguments = []): bool { - return (bool) count(static::managers($record)); + return (bool) count(static::managers($arguments['record'] ?? null)); } public function getRelationManagers(): array @@ -71,12 +71,12 @@ public function getRelationManagers(): array return static::managers($this->getRecord()); } - private static function managers(Model $record): array + private static function managers(?Model $record = null): array { return collect([ ServiceRequestsRelationManager::class, ]) - ->reject(fn ($relationManager) => ! $relationManager::canViewForRecord($record, static::class)) + ->reject(fn ($relationManager) => $record && (! $relationManager::canViewForRecord($record, static::class))) ->toArray(); } } diff --git a/app-modules/theme/src/Filament/Pages/ManageBrandConfigurationSettings.php b/app-modules/theme/src/Filament/Pages/ManageBrandConfigurationSettings.php index 43fa51e379..651ac73623 100644 --- a/app-modules/theme/src/Filament/Pages/ManageBrandConfigurationSettings.php +++ b/app-modules/theme/src/Filament/Pages/ManageBrandConfigurationSettings.php @@ -44,6 +44,7 @@ use Filament\Pages\SettingsPage; use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Section; +use App\Filament\Clusters\GlobalSettings; use AdvisingApp\Theme\Settings\ThemeSettings; use Filament\Forms\Components\SpatieMediaLibraryFileUpload; @@ -53,17 +54,15 @@ class ManageBrandConfigurationSettings extends SettingsPage protected static ?string $navigationLabel = 'Branding'; - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?string $navigationParentItem = 'Global Settings'; - protected static ?int $navigationSort = 30; protected static string $settings = ThemeSettings::class; protected static ?string $title = 'Branding'; - public static function shouldRegisterNavigation(): bool + protected static ?string $cluster = GlobalSettings::class; + + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); @@ -71,13 +70,6 @@ public static function shouldRegisterNavigation(): bool return $user->can('theme.view_theme_settings'); } - public function mount(): void - { - $this->authorize('theme.view_theme_settings'); - - parent::mount(); - } - public function form(Form $form): Form { return $form diff --git a/app-modules/timeline/src/Filament/Pages/TimelinePage.php b/app-modules/timeline/src/Filament/Pages/TimelinePage.php index e678f7bd3c..7851570c34 100644 --- a/app-modules/timeline/src/Filament/Pages/TimelinePage.php +++ b/app-modules/timeline/src/Filament/Pages/TimelinePage.php @@ -39,9 +39,7 @@ use Filament\Actions\ViewAction; use Filament\Resources\Pages\Page; use Illuminate\Database\Eloquent\Model; -use AdvisingApp\Timeline\Models\Timeline; use App\Actions\GetRecordFromMorphAndKey; -use Symfony\Component\HttpFoundation\Response; use AdvisingApp\Timeline\Actions\SyncTimelineData; use Filament\Resources\Pages\Concerns\InteractsWithRecord; use AdvisingApp\Timeline\Filament\Pages\Concerns\LoadsTimelineRecords; @@ -69,8 +67,6 @@ public function mount($record): void { $this->recordModel = $this->record = $this->resolveRecord($record); - $this->authorizeAccess(); - $this->timelineRecords = collect(); resolve(SyncTimelineData::class)->now($this->recordModel, $this->modelsToTimeline); @@ -92,38 +88,22 @@ public function viewAction(): ViewAction ->modalViewAction($this->currentRecordToView); } - /** - * @return array - */ - public function getSubNavigationParameters(): array - { - return [ - 'record' => $this->getRecord(), - ]; - } - - public function getSubNavigation(): array - { - return static::getResource()::getRecordSubNavigation($this); - } - - public static function shouldRegisterNavigation(array $parameters = []): bool + public static function canAccess(array $parameters = []): bool { if (auth()->user()->cannot('timeline.access')) { return false; } - return parent::shouldRegisterNavigation($parameters) && static::getResource()::canView($parameters['record']); - } + if (! parent::canAccess($parameters)) { + return false; + } - protected function authorizeAccess(): void - { - static::authorizeResourceAccess(); + $record = $parameters['record'] ?? null; - abort_unless(auth()->user()->can('timeline.access'), Response::HTTP_FORBIDDEN); + if (! $record) { + return false; + } - // TODO We also need to check access for the other entities that are going to be included in the timeline - // We probably just need to establish that the user can view any of a model, but might need to be more specific - abort_unless(static::getResource()::canView($this->getRecord()), Response::HTTP_FORBIDDEN); + return static::getResource()::canView($record); } } diff --git a/app-modules/webhook/src/Filament/Resources/InboundWebhookResource.php b/app-modules/webhook/src/Filament/Resources/InboundWebhookResource.php index 0de5a6b4b3..4d37b07a12 100644 --- a/app-modules/webhook/src/Filament/Resources/InboundWebhookResource.php +++ b/app-modules/webhook/src/Filament/Resources/InboundWebhookResource.php @@ -37,6 +37,7 @@ namespace AdvisingApp\Webhook\Filament\Resources; use Filament\Resources\Resource; +use App\Filament\Clusters\GlobalSettings; use AdvisingApp\Webhook\Models\InboundWebhook; use AdvisingApp\Webhook\Filament\Resources\InboundWebhookResource\Pages\ViewInboundWebhook; use AdvisingApp\Webhook\Filament\Resources\InboundWebhookResource\Pages\ListInboundWebhooks; @@ -47,12 +48,10 @@ class InboundWebhookResource extends Resource protected static ?string $navigationIcon = 'heroicon-o-signal'; - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?string $navigationParentItem = 'Global Settings'; - protected static ?int $navigationSort = 40; + protected static ?string $cluster = GlobalSettings::class; + public static function getPages(): array { return [ diff --git a/app/Filament/Clusters/AnalyticsResources.php b/app/Filament/Clusters/AnalyticsResources.php new file mode 100644 index 0000000000..f6196acf6e --- /dev/null +++ b/app/Filament/Clusters/AnalyticsResources.php @@ -0,0 +1,48 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace App\Filament\Clusters; + +use Filament\Clusters\Cluster; + +class AnalyticsResources extends Cluster +{ + protected static ?string $navigationIcon = 'heroicon-o-arrow-trending-up'; + + protected static ?string $navigationGroup = 'Engagement Features'; + + protected static ?int $navigationSort = 60; +} diff --git a/app/Filament/Pages/ArtificialIntelligence.php b/app/Filament/Clusters/ArtificialIntelligence.php similarity index 84% rename from app/Filament/Pages/ArtificialIntelligence.php rename to app/Filament/Clusters/ArtificialIntelligence.php index 33e3a07274..a076dca671 100644 --- a/app/Filament/Pages/ArtificialIntelligence.php +++ b/app/Filament/Clusters/ArtificialIntelligence.php @@ -34,16 +34,12 @@ */ -namespace App\Filament\Pages; +namespace App\Filament\Clusters; -use Filament\Pages\Page; -use App\Filament\Pages\Concerns\HasChildNavigationItemsOnly; -use AdvisingApp\Assistant\Filament\Pages\AssistantConfiguration; +use Filament\Clusters\Cluster; -class ArtificialIntelligence extends Page +class ArtificialIntelligence extends Cluster { - use HasChildNavigationItemsOnly; - protected static ?string $navigationIcon = 'heroicon-o-document-text'; protected static ?string $navigationGroup = 'Product Administration'; @@ -51,8 +47,4 @@ class ArtificialIntelligence extends Page protected static ?int $navigationSort = 3; protected static ?string $title = 'Artificial Intelligence'; - - protected static array $children = [ - AssistantConfiguration::class, - ]; } diff --git a/app/Filament/Pages/AssetManagement.php b/app/Filament/Clusters/AssetManagement.php similarity index 72% rename from app/Filament/Pages/AssetManagement.php rename to app/Filament/Clusters/AssetManagement.php index 6e331dfb0f..8afb7f35f7 100644 --- a/app/Filament/Pages/AssetManagement.php +++ b/app/Filament/Clusters/AssetManagement.php @@ -34,31 +34,15 @@ */ -namespace App\Filament\Pages; +namespace App\Filament\Clusters; -use Filament\Pages\Page; -use App\Filament\Pages\Concerns\HasChildNavigationItemsOnly; -use AdvisingApp\InventoryManagement\Filament\Resources\AssetTypeResource; -use AdvisingApp\InventoryManagement\Filament\Resources\AssetStatusResource; -use AdvisingApp\InventoryManagement\Filament\Resources\AssetLocationResource; +use Filament\Clusters\Cluster; -class AssetManagement extends Page +class AssetManagement extends Cluster { - use HasChildNavigationItemsOnly; - protected static ?string $navigationIcon = 'heroicon-o-document-text'; protected static ?string $navigationGroup = 'Product Administration'; protected static ?int $navigationSort = 5; - - protected static ?string $title = 'Asset Management'; - - protected static ?string $breadcrumb = 'Asset Management'; - - protected static array $children = [ - AssetLocationResource::class, - AssetStatusResource::class, - AssetTypeResource::class, - ]; } diff --git a/resources/views/filament/pages/email-configuration.blade.php b/app/Filament/Clusters/GlobalSettings.php similarity index 83% rename from resources/views/filament/pages/email-configuration.blade.php rename to app/Filament/Clusters/GlobalSettings.php index 6381921999..f675513b9b 100644 --- a/resources/views/filament/pages/email-configuration.blade.php +++ b/app/Filament/Clusters/GlobalSettings.php @@ -1,4 +1,6 @@ -{{-- + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. @@ -30,7 +32,17 @@ https://www.canyongbs.com or contact us via email at legal@canyongbs.com. ---}} - +*/ + +namespace App\Filament\Clusters; + +use Filament\Clusters\Cluster; + +class GlobalSettings extends Cluster +{ + protected static ?string $navigationIcon = 'heroicon-o-document-text'; + + protected static ?string $navigationGroup = 'Product Administration'; - + protected static ?int $navigationSort = 1; +} diff --git a/app/Filament/Pages/InteractionManagement.php b/app/Filament/Clusters/InteractionManagement.php similarity index 87% rename from app/Filament/Pages/InteractionManagement.php rename to app/Filament/Clusters/InteractionManagement.php index 64e08517e3..43f84be920 100644 --- a/app/Filament/Pages/InteractionManagement.php +++ b/app/Filament/Clusters/InteractionManagement.php @@ -34,10 +34,9 @@ */ -namespace App\Filament\Pages; +namespace App\Filament\Clusters; -use Filament\Pages\Page; -use App\Filament\Pages\Concerns\HasChildNavigationItemsOnly; +use Filament\Clusters\Cluster; use AdvisingApp\Interaction\Filament\Resources\InteractionTypeResource; use AdvisingApp\Interaction\Filament\Resources\InteractionDriverResource; use AdvisingApp\Interaction\Filament\Resources\InteractionStatusResource; @@ -45,21 +44,15 @@ use AdvisingApp\Interaction\Filament\Resources\InteractionCampaignResource; use AdvisingApp\Interaction\Filament\Resources\InteractionRelationResource; -class InteractionManagement extends Page +class InteractionManagement extends Cluster { - use HasChildNavigationItemsOnly; - protected static ?string $navigationIcon = 'heroicon-o-document-text'; protected static ?string $navigationGroup = 'Product Administration'; protected static ?int $navigationSort = 8; - protected static ?string $title = 'Interaction Management'; - - protected static ?string $breadcrumb = 'Interaction Management'; - - protected static array $children = [ + protected array $children = [ InteractionCampaignResource::class, InteractionDriverResource::class, InteractionOutcomeResource::class, diff --git a/app/Filament/Pages/KnowledgeManagement.php b/app/Filament/Clusters/KnowledgeManagement.php similarity index 70% rename from app/Filament/Pages/KnowledgeManagement.php rename to app/Filament/Clusters/KnowledgeManagement.php index d23a290531..52118bf81a 100644 --- a/app/Filament/Pages/KnowledgeManagement.php +++ b/app/Filament/Clusters/KnowledgeManagement.php @@ -34,31 +34,15 @@ */ -namespace App\Filament\Pages; +namespace App\Filament\Clusters; -use Filament\Pages\Page; -use App\Filament\Pages\Concerns\HasChildNavigationItemsOnly; -use AdvisingApp\KnowledgeBase\Filament\Resources\KnowledgeBaseStatusResource; -use AdvisingApp\KnowledgeBase\Filament\Resources\KnowledgeBaseQualityResource; -use AdvisingApp\KnowledgeBase\Filament\Resources\KnowledgeBaseCategoryResource; +use Filament\Clusters\Cluster; -class KnowledgeManagement extends Page +class KnowledgeManagement extends Cluster { - use HasChildNavigationItemsOnly; - protected static ?string $navigationIcon = 'heroicon-o-document-text'; protected static ?string $navigationGroup = 'Product Administration'; protected static ?int $navigationSort = 7; - - protected static ?string $title = 'Knowledge Management'; - - protected static ?string $breadcrumb = 'Knowledge Management'; - - protected static array $children = [ - KnowledgeBaseCategoryResource::class, - KnowledgeBaseQualityResource::class, - KnowledgeBaseStatusResource::class, - ]; } diff --git a/app/Filament/Pages/OnlineAdmissions.php b/app/Filament/Clusters/OnlineAdmissions.php similarity index 78% rename from app/Filament/Pages/OnlineAdmissions.php rename to app/Filament/Clusters/OnlineAdmissions.php index 8d930449c1..1996623d08 100644 --- a/app/Filament/Pages/OnlineAdmissions.php +++ b/app/Filament/Clusters/OnlineAdmissions.php @@ -34,27 +34,15 @@ */ -namespace App\Filament\Pages; +namespace App\Filament\Clusters; -use Filament\Pages\Page; -use App\Filament\Pages\Concerns\HasChildNavigationItemsOnly; -use AdvisingApp\Application\Filament\Resources\ApplicationSubmissionStateResource; +use Filament\Clusters\Cluster; -class OnlineAdmissions extends Page +class OnlineAdmissions extends Cluster { - use HasChildNavigationItemsOnly; - protected static ?string $navigationIcon = 'heroicon-o-document-text'; protected static ?string $navigationGroup = 'Product Administration'; protected static ?int $navigationSort = 10; - - protected static ?string $title = 'Online Admissions'; - - protected static ?string $breadcrumb = 'Online Admissions'; - - protected static array $children = [ - ApplicationSubmissionStateResource::class, - ]; } diff --git a/app/Filament/Clusters/ProductIntegrations.php b/app/Filament/Clusters/ProductIntegrations.php new file mode 100644 index 0000000000..8419e1ed87 --- /dev/null +++ b/app/Filament/Clusters/ProductIntegrations.php @@ -0,0 +1,48 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace App\Filament\Clusters; + +use Filament\Clusters\Cluster; + +class ProductIntegrations extends Cluster +{ + protected static ?string $navigationIcon = 'heroicon-o-document-text'; + + protected static ?string $navigationGroup = 'Product Administration'; + + protected static ?int $navigationSort = 2; +} diff --git a/app/Filament/Pages/ProfileManagement.php b/app/Filament/Clusters/ProfileManagement.php similarity index 80% rename from app/Filament/Pages/ProfileManagement.php rename to app/Filament/Clusters/ProfileManagement.php index d2bcc5ea26..2e66bb2669 100644 --- a/app/Filament/Pages/ProfileManagement.php +++ b/app/Filament/Clusters/ProfileManagement.php @@ -34,27 +34,15 @@ */ -namespace App\Filament\Pages; +namespace App\Filament\Clusters; -use Filament\Pages\Page; -use App\Filament\Resources\PronounsResource; -use App\Filament\Pages\Concerns\HasChildNavigationItemsOnly; +use Filament\Clusters\Cluster; -class ProfileManagement extends Page +class ProfileManagement extends Cluster { - use HasChildNavigationItemsOnly; - protected static ?string $navigationIcon = 'heroicon-o-document-text'; protected static ?string $navigationGroup = 'Product Administration'; protected static ?int $navigationSort = 9; - - protected static ?string $title = 'Profile Management'; - - protected static ?string $breadcrumb = 'Profile Management'; - - protected static array $children = [ - PronounsResource::class, - ]; } diff --git a/app/Filament/Pages/RecruitmentCrm.php b/app/Filament/Clusters/RecruitmentCrm.php similarity index 75% rename from app/Filament/Pages/RecruitmentCrm.php rename to app/Filament/Clusters/RecruitmentCrm.php index 8f9a14b5e4..233104a2d5 100644 --- a/app/Filament/Pages/RecruitmentCrm.php +++ b/app/Filament/Clusters/RecruitmentCrm.php @@ -34,29 +34,15 @@ */ -namespace App\Filament\Pages; +namespace App\Filament\Clusters; -use Filament\Pages\Page; -use App\Filament\Pages\Concerns\HasChildNavigationItemsOnly; -use AdvisingApp\Prospect\Filament\Resources\ProspectSourceResource; -use AdvisingApp\Prospect\Filament\Resources\ProspectStatusResource; +use Filament\Clusters\Cluster; -class RecruitmentCrm extends Page +class RecruitmentCrm extends Cluster { - use HasChildNavigationItemsOnly; - protected static ?string $navigationIcon = 'heroicon-o-document-text'; protected static ?string $navigationGroup = 'Product Administration'; protected static ?int $navigationSort = 4; - - protected static ?string $title = 'Recruitment CRM'; - - protected static ?string $breadcrumb = 'Recruitment CRM'; - - protected static array $children = [ - ProspectStatusResource::class, - ProspectSourceResource::class, - ]; } diff --git a/app-modules/assistant/resources/views/filament/pages/assistant-configuration.blade.php b/app/Filament/Clusters/ServiceManagement.php similarity index 83% rename from app-modules/assistant/resources/views/filament/pages/assistant-configuration.blade.php rename to app/Filament/Clusters/ServiceManagement.php index 6381921999..c1adadb421 100644 --- a/app-modules/assistant/resources/views/filament/pages/assistant-configuration.blade.php +++ b/app/Filament/Clusters/ServiceManagement.php @@ -1,4 +1,6 @@ -{{-- + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. @@ -30,7 +32,17 @@ https://www.canyongbs.com or contact us via email at legal@canyongbs.com. ---}} - +*/ + +namespace App\Filament\Clusters; + +use Filament\Clusters\Cluster; + +class ServiceManagement extends Cluster +{ + protected static ?string $navigationIcon = 'heroicon-o-briefcase'; + + protected static ?string $navigationGroup = 'Premium Features'; - + protected static ?int $navigationSort = 30; +} diff --git a/app/Filament/Pages/ServiceManagement.php b/app/Filament/Clusters/ServiceManagementAdministration.php similarity index 73% rename from app/Filament/Pages/ServiceManagement.php rename to app/Filament/Clusters/ServiceManagementAdministration.php index cea286c328..903ddf7705 100644 --- a/app/Filament/Pages/ServiceManagement.php +++ b/app/Filament/Clusters/ServiceManagementAdministration.php @@ -34,18 +34,12 @@ */ -namespace App\Filament\Pages; +namespace App\Filament\Clusters; -use Filament\Pages\Page; -use App\Filament\Pages\Concerns\HasChildNavigationItemsOnly; -use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestTypeResource; -use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource; -use AdvisingApp\ServiceManagement\Filament\Resources\ServiceRequestPriorityResource; +use Filament\Clusters\Cluster; -class ServiceManagement extends Page +class ServiceManagementAdministration extends Cluster { - use HasChildNavigationItemsOnly; - protected static ?string $navigationIcon = 'heroicon-o-document-text'; protected static ?string $navigationGroup = 'Product Administration'; @@ -53,12 +47,4 @@ class ServiceManagement extends Page protected static ?int $navigationSort = 6; protected static ?string $title = 'Service Management'; - - protected static ?string $breadcrumb = 'Service Management'; - - protected static array $children = [ - ServiceRequestPriorityResource::class, - ServiceRequestStatusResource::class, - ServiceRequestTypeResource::class, - ]; } diff --git a/app/Filament/Pages/UsageAuditing.php b/app/Filament/Clusters/UsageAuditing.php similarity index 78% rename from app/Filament/Pages/UsageAuditing.php rename to app/Filament/Clusters/UsageAuditing.php index 2481c1b805..fba22c5aae 100644 --- a/app/Filament/Pages/UsageAuditing.php +++ b/app/Filament/Clusters/UsageAuditing.php @@ -34,27 +34,15 @@ */ -namespace App\Filament\Pages; +namespace App\Filament\Clusters; -use Filament\Pages\Page; -use AdvisingApp\Audit\Filament\Resources\AuditResource; -use App\Filament\Pages\Concerns\HasChildNavigationItemsOnly; -use AdvisingApp\Assistant\Filament\Resources\AssistantChatMessageLogResource; +use Filament\Clusters\Cluster; -class UsageAuditing extends Page +class UsageAuditing extends Cluster { - use HasChildNavigationItemsOnly; - protected static ?string $navigationIcon = 'heroicon-o-document-text'; protected static ?string $navigationGroup = 'Reporting'; protected static ?int $navigationSort = 30; - - protected static ?string $title = 'Usage Auditing'; - - protected static array $children = [ - AssistantChatMessageLogResource::class, - AuditResource::class, - ]; } diff --git a/app/Filament/Pages/GlobalSettings.php b/app/Filament/Pages/ChangeManagement.php similarity index 67% rename from app/Filament/Pages/GlobalSettings.php rename to app/Filament/Pages/ChangeManagement.php index 64ebd84080..b646e75b9b 100644 --- a/app/Filament/Pages/GlobalSettings.php +++ b/app/Filament/Pages/ChangeManagement.php @@ -36,31 +36,33 @@ namespace App\Filament\Pages; +use App\Enums\Feature; use Filament\Pages\Page; -use AdvisingApp\Audit\Filament\Pages\ManageAuditSettings; -use AdvisingApp\Portal\Filament\Pages\ManagePortalSettings; -use App\Filament\Pages\Concerns\HasChildNavigationItemsOnly; -use AdvisingApp\Webhook\Filament\Resources\InboundWebhookResource; -use AdvisingApp\Theme\Filament\Pages\ManageBrandConfigurationSettings; +use App\Models\Authenticatable; +use Illuminate\Support\Facades\Gate; +use AdvisingApp\Prospect\Models\Prospect; +use App\Filament\Clusters\ServiceManagement; +use AdvisingApp\StudentDataModel\Models\Student; -class GlobalSettings extends Page +class ChangeManagement extends Page { - use HasChildNavigationItemsOnly; - protected static ?string $navigationIcon = 'heroicon-o-document-text'; - protected static ?string $navigationGroup = 'Product Administration'; + protected static ?int $navigationSort = 30; + + protected static string $view = 'filament.pages.coming-soon'; + + protected static ?string $cluster = ServiceManagement::class; - protected static ?int $navigationSort = 1; + public static function canAccess(): bool + { + if (! Gate::check(Feature::ServiceManagement->getGateName())) { + return false; + } - protected static ?string $title = 'Global Settings'; + /** @var Authenticatable $user */ + $user = auth()->user(); - protected static array $children = [ - ManageLicenseSettings::class, - ManageAuditSettings::class, - ManageBrandConfigurationSettings::class, - InboundWebhookResource::class, - EmailConfiguration::class, - ManagePortalSettings::class, - ]; + return $user->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()]); + } } diff --git a/app/Filament/Pages/Concerns/HasChildNavigationItemsOnly.php b/app/Filament/Pages/Concerns/HasChildNavigationItemsOnly.php deleted file mode 100644 index 412936e579..0000000000 --- a/app/Filament/Pages/Concerns/HasChildNavigationItemsOnly.php +++ /dev/null @@ -1,82 +0,0 @@ - - - Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. - - Advising App™ is licensed under the Elastic License 2.0. For more details, - see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. - - Notice: - - - You may not provide the software to third parties as a hosted or managed - service, where the service provides users with access to any substantial set of - the features or functionality of the software. - - You may not move, change, disable, or circumvent the license key functionality - in the software, and you may not remove or obscure any functionality in the - software that is protected by the license key. - - You may not alter, remove, or obscure any licensing, copyright, or other notices - of the licensor in the software. Any use of the licensor’s trademarks is subject - to applicable law. - - Canyon GBS LLC respects the intellectual property rights of others and expects the - same in return. Canyon GBS™ and Advising App™ are registered trademarks of - Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks - vigorously. - - The software solution, including services, infrastructure, and code, is offered as a - Software as a Service (SaaS) by Canyon GBS LLC. - - Use of this software implies agreement to the license terms and conditions as stated - in the Elastic License 2.0. - - For more information or inquiries please visit our website at - https://www.canyongbs.com or contact us via email at legal@canyongbs.com. - - -*/ - -namespace App\Filament\Pages\Concerns; - -use Filament\Pages\Page; -use Filament\Resources\Resource; -use Illuminate\Routing\Redirector; - -trait HasChildNavigationItemsOnly -{ - public static function shouldRegisterNavigation(): bool - { - foreach (static::$children as $child) { - if (static::canAccessChildPage($child)) { - return true; - } - } - - return false; - } - - public function mount(): Redirector - { - foreach (static::$children as $child) { - if (static::canAccessChildPage($child)) { - return redirect($child::getUrl()); - } - } - - abort(403); - } - - /** - * @param class-string $child - */ - protected static function canAccessChildPage(string $child): bool - { - if (! $child::shouldRegisterNavigation()) { - return false; - } - - if (! is_subclass_of($child, Resource::class)) { - return true; - } - - return $child::canViewAny(); - } -} diff --git a/app/Filament/Pages/EmailConfiguration.php b/app/Filament/Pages/EmailConfiguration.php deleted file mode 100644 index 4e62453cd5..0000000000 --- a/app/Filament/Pages/EmailConfiguration.php +++ /dev/null @@ -1,126 +0,0 @@ - - - Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. - - Advising App™ is licensed under the Elastic License 2.0. For more details, - see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. - - Notice: - - - You may not provide the software to third parties as a hosted or managed - service, where the service provides users with access to any substantial set of - the features or functionality of the software. - - You may not move, change, disable, or circumvent the license key functionality - in the software, and you may not remove or obscure any functionality in the - software that is protected by the license key. - - You may not alter, remove, or obscure any licensing, copyright, or other notices - of the licensor in the software. Any use of the licensor’s trademarks is subject - to applicable law. - - Canyon GBS LLC respects the intellectual property rights of others and expects the - same in return. Canyon GBS™ and Advising App™ are registered trademarks of - Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks - vigorously. - - The software solution, including services, infrastructure, and code, is offered as a - Software as a Service (SaaS) by Canyon GBS LLC. - - Use of this software implies agreement to the license terms and conditions as stated - in the Elastic License 2.0. - - For more information or inquiries please visit our website at - https://www.canyongbs.com or contact us via email at legal@canyongbs.com. - - -*/ - -namespace App\Filament\Pages; - -use App\Models\User; -use Filament\Pages\Page; -use Filament\Navigation\NavigationItem; -use Symfony\Component\HttpFoundation\Response; -use AdvisingApp\Campaign\Filament\Pages\ManageCampaignSettings; -use App\Filament\Resources\NotificationSettingResource\Pages\ListNotificationSettings; -use AdvisingApp\Engagement\Filament\Resources\SmsTemplateResource\Pages\ListSmsTemplates; -use AdvisingApp\Engagement\Filament\Resources\EmailTemplateResource\Pages\ListEmailTemplates; - -class EmailConfiguration extends Page -{ - protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; - - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?string $navigationParentItem = 'Global Settings'; - - protected static ?int $navigationSort = 50; - - protected static ?string $title = 'Communication'; - - protected static string $view = 'filament.pages.email-configuration'; - - public function getBreadcrumbs(): array - { - return [ - $this::getUrl() => 'Email Configuration', - ]; - } - - public static function shouldRegisterNavigation(): bool - { - /** @var NavigationItem $firstNavItem */ - $firstNavItem = collect((new EmailConfiguration())->getSubNavigation()) - ->first(function (NavigationItem $item) { - return $item->isVisible(); - }); - - return ! is_null($firstNavItem); - } - - public function mount(): void - { - /** @var NavigationItem $firstNavItem */ - $firstNavItem = collect($this->getSubNavigation()) - ->first(function (NavigationItem $item) { - return $item->isVisible(); - }); - - abort_if(is_null($firstNavItem), Response::HTTP_FORBIDDEN); - - redirect($firstNavItem->getUrl()); - } - - public static function getNavigationItems(): array - { - $item = parent::getNavigationItems()[0]; - - $item->isActiveWhen(function (): bool { - $subItems = (new EmailConfiguration())->getSubNavigation(); - - foreach ($subItems as $subItem) { - if (str(request()->fullUrl())->contains(str($subItem->getUrl())->after('/'))) { - return true; - } - } - - return request()->routeIs(static::getRouteName()); - }); - - return [$item]; - } - - public function getSubNavigation(): array - { - /** @var User $user */ - $user = auth()->user(); - - return [ - ...$this->generateNavigationItems([ - ListNotificationSettings::class, - ListEmailTemplates::class, - ListSmsTemplates::class, - ]), - ...($user->can('campaign.view_campaign_settings') ? ManageCampaignSettings::getNavigationItems() : []), - ]; - } -} diff --git a/app/Filament/Pages/ManageLicenseSettings.php b/app/Filament/Pages/ManageLicenseSettings.php index 949b319c7b..b2625890f0 100644 --- a/app/Filament/Pages/ManageLicenseSettings.php +++ b/app/Filament/Pages/ManageLicenseSettings.php @@ -42,6 +42,7 @@ use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Section; use Filament\Forms\Components\TextInput; +use App\Filament\Clusters\GlobalSettings; use Filament\Forms\Components\DatePicker; use App\DataTransferObjects\LicenseManagement\LicenseData; @@ -51,14 +52,12 @@ class ManageLicenseSettings extends SettingsPage protected static ?string $navigationLabel = 'Subscription'; - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?string $navigationParentItem = 'Global Settings'; - protected static ?int $navigationSort = 10; protected static string $settings = LicenseSettings::class; + protected static ?string $cluster = GlobalSettings::class; + public function form(Form $form): Form { return $form diff --git a/app/Filament/Pages/ProductHealth.php b/app/Filament/Pages/ProductHealth.php index a7a72b88d8..e19a1f8066 100644 --- a/app/Filament/Pages/ProductHealth.php +++ b/app/Filament/Pages/ProductHealth.php @@ -80,16 +80,11 @@ public static function getNavigationBadgeColor(): string | array | null return 'danger'; } - public static function shouldRegisterNavigation(): bool + public static function canAccess(): bool { /** @var User $user */ $user = auth()->user(); return $user->can('authorization.view_product_health_dashboard'); } - - public function mount(): void - { - $this->authorize('authorization.view_product_health_dashboard'); - } } diff --git a/app/Filament/Pages/ProductIntegrations.php b/app/Filament/Pages/ProductIntegrations.php deleted file mode 100644 index c17654ea8d..0000000000 --- a/app/Filament/Pages/ProductIntegrations.php +++ /dev/null @@ -1,66 +0,0 @@ - - - Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. - - Advising App™ is licensed under the Elastic License 2.0. For more details, - see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. - - Notice: - - - You may not provide the software to third parties as a hosted or managed - service, where the service provides users with access to any substantial set of - the features or functionality of the software. - - You may not move, change, disable, or circumvent the license key functionality - in the software, and you may not remove or obscure any functionality in the - software that is protected by the license key. - - You may not alter, remove, or obscure any licensing, copyright, or other notices - of the licensor in the software. Any use of the licensor’s trademarks is subject - to applicable law. - - Canyon GBS LLC respects the intellectual property rights of others and expects the - same in return. Canyon GBS™ and Advising App™ are registered trademarks of - Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks - vigorously. - - The software solution, including services, infrastructure, and code, is offered as a - Software as a Service (SaaS) by Canyon GBS LLC. - - Use of this software implies agreement to the license terms and conditions as stated - in the Elastic License 2.0. - - For more information or inquiries please visit our website at - https://www.canyongbs.com or contact us via email at legal@canyongbs.com. - - -*/ - -namespace App\Filament\Pages; - -use Filament\Pages\Page; -use App\Filament\Pages\Concerns\HasChildNavigationItemsOnly; -use AdvisingApp\IntegrationTwilio\Filament\Pages\ManageTwilioSettings; -use AdvisingApp\IntegrationAwsSesEventHandling\Filament\Pages\ManageAmazonSesSettings; -use AdvisingApp\IntegrationGoogleAnalytics\Filament\Pages\ManageGoogleAnalyticsSettings; -use AdvisingApp\IntegrationGoogleRecaptcha\Filament\Pages\ManageGoogleRecaptchaSettings; -use AdvisingApp\IntegrationMicrosoftClarity\Filament\Pages\ManageMicrosoftClaritySettings; - -class ProductIntegrations extends Page -{ - use HasChildNavigationItemsOnly; - - protected static ?string $navigationIcon = 'heroicon-o-document-text'; - - protected static ?string $navigationGroup = 'Product Administration'; - - protected static ?int $navigationSort = 2; - - protected static ?string $title = 'Product Integrations'; - - protected static array $children = [ - ManageGoogleAnalyticsSettings::class, - ManageGoogleRecaptchaSettings::class, - ManageMicrosoftClaritySettings::class, - ManageTwilioSettings::class, - ManageAmazonSesSettings::class, - ]; -} diff --git a/app/Filament/Pages/SLAs.php b/app/Filament/Pages/SLAs.php new file mode 100644 index 0000000000..7340510cbf --- /dev/null +++ b/app/Filament/Pages/SLAs.php @@ -0,0 +1,70 @@ + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace App\Filament\Pages; + +use App\Enums\Feature; +use Filament\Pages\Page; +use App\Models\Authenticatable; +use Illuminate\Support\Facades\Gate; +use AdvisingApp\Prospect\Models\Prospect; +use App\Filament\Clusters\ServiceManagement; +use AdvisingApp\StudentDataModel\Models\Student; + +class SLAs extends Page +{ + protected static ?string $navigationIcon = 'heroicon-o-document-text'; + + protected static ?int $navigationSort = 40; + + protected static string $view = 'filament.pages.coming-soon'; + + protected static ?string $title = 'SLAs'; + + protected static ?string $cluster = ServiceManagement::class; + + public static function canAccess(): bool + { + if (! Gate::check(Feature::ServiceManagement->getGateName())) { + return false; + } + + /** @var Authenticatable $user */ + $user = auth()->user(); + + return $user->hasAnyLicense([Student::getLicenseType(), Prospect::getLicenseType()]); + } +} diff --git a/app/Filament/Resources/NotificationSettingResource.php b/app/Filament/Resources/NotificationSettingResource.php index e95ae9dae6..bac855f7a8 100644 --- a/app/Filament/Resources/NotificationSettingResource.php +++ b/app/Filament/Resources/NotificationSettingResource.php @@ -38,6 +38,7 @@ use Filament\Resources\Resource; use App\Models\NotificationSetting; +use App\Filament\Clusters\GlobalSettings; use App\Filament\Resources\NotificationSettingResource\Pages\EditNotificationSetting; use App\Filament\Resources\NotificationSettingResource\Pages\ListNotificationSettings; use App\Filament\Resources\NotificationSettingResource\Pages\CreateNotificationSetting; @@ -46,13 +47,13 @@ class NotificationSettingResource extends Resource { protected static ?string $model = NotificationSetting::class; - protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; + protected static ?string $navigationIcon = 'heroicon-o-bell'; - protected static ?string $navigationGroup = 'Product Administration'; + protected static ?string $navigationGroup = 'Communication'; protected static ?int $navigationSort = 110; - protected static bool $shouldRegisterNavigation = false; + protected static ?string $cluster = GlobalSettings::class; public static function getRelations(): array { diff --git a/app/Filament/Resources/NotificationSettingResource/Pages/CreateNotificationSetting.php b/app/Filament/Resources/NotificationSettingResource/Pages/CreateNotificationSetting.php index db1e1592e0..40ad8b1616 100644 --- a/app/Filament/Resources/NotificationSettingResource/Pages/CreateNotificationSetting.php +++ b/app/Filament/Resources/NotificationSettingResource/Pages/CreateNotificationSetting.php @@ -40,7 +40,6 @@ use App\Filament\Fields\ColorSelect; use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; -use App\Filament\Pages\EmailConfiguration; use Filament\Resources\Pages\CreateRecord; use App\Filament\Resources\NotificationSettingResource; use Filament\Forms\Components\SpatieMediaLibraryFileUpload; @@ -49,14 +48,6 @@ class CreateNotificationSetting extends CreateRecord { protected static string $resource = NotificationSettingResource::class; - public function getBreadcrumbs(): array - { - return [ - ...(new EmailConfiguration())->getBreadcrumbs(), - ...parent::getBreadcrumbs(), - ]; - } - public function form(Form $form): Form { return $form diff --git a/app/Filament/Resources/NotificationSettingResource/Pages/EditNotificationSetting.php b/app/Filament/Resources/NotificationSettingResource/Pages/EditNotificationSetting.php index e3f36a2e49..5dab50ca02 100644 --- a/app/Filament/Resources/NotificationSettingResource/Pages/EditNotificationSetting.php +++ b/app/Filament/Resources/NotificationSettingResource/Pages/EditNotificationSetting.php @@ -42,7 +42,6 @@ use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use Filament\Resources\Pages\EditRecord; -use App\Filament\Pages\EmailConfiguration; use App\Filament\Resources\NotificationSettingResource; use Filament\Forms\Components\SpatieMediaLibraryFileUpload; @@ -50,14 +49,6 @@ class EditNotificationSetting extends EditRecord { protected static string $resource = NotificationSettingResource::class; - public function getBreadcrumbs(): array - { - return [ - ...(new EmailConfiguration())->getBreadcrumbs(), - ...parent::getBreadcrumbs(), - ]; - } - public function form(Form $form): Form { return $form diff --git a/app/Filament/Resources/NotificationSettingResource/Pages/ListNotificationSettings.php b/app/Filament/Resources/NotificationSettingResource/Pages/ListNotificationSettings.php index 72795f76b7..598cb044c4 100644 --- a/app/Filament/Resources/NotificationSettingResource/Pages/ListNotificationSettings.php +++ b/app/Filament/Resources/NotificationSettingResource/Pages/ListNotificationSettings.php @@ -36,13 +36,10 @@ namespace App\Filament\Resources\NotificationSettingResource\Pages; -use App\Models\User; use Filament\Tables\Table; use Filament\Actions\CreateAction; -use App\Models\NotificationSetting; use Filament\Tables\Actions\EditAction; use Filament\Resources\Pages\ListRecords; -use App\Filament\Pages\EmailConfiguration; use Filament\Tables\Actions\BulkActionGroup; use Filament\Tables\Actions\DeleteBulkAction; use App\Filament\Columns\OpenSearch\TextColumn; @@ -52,28 +49,6 @@ class ListNotificationSettings extends ListRecords { protected static string $resource = NotificationSettingResource::class; - protected static ?string $navigationLabel = 'Notification Settings'; - - protected static ?string $title = 'Notification Settings'; - - protected static ?string $navigationIcon = 'heroicon-o-bell'; - - public static function shouldRegisterNavigation(array $parameters = []): bool - { - /** @var User $user */ - $user = auth()->user(); - - return $user->can('viewAny', NotificationSetting::class); - } - - public function getBreadcrumbs(): array - { - return [ - ...(new EmailConfiguration())->getBreadcrumbs(), - ...parent::getBreadcrumbs(), - ]; - } - public function table(Table $table): Table { return $table @@ -93,11 +68,6 @@ public function table(Table $table): Table ]); } - public function getSubNavigation(): array - { - return (new EmailConfiguration())->getSubNavigation(); - } - protected function getHeaderActions(): array { return [ diff --git a/app/Filament/Resources/PronounsResource.php b/app/Filament/Resources/PronounsResource.php index 260a03d571..a9e6d75e8b 100644 --- a/app/Filament/Resources/PronounsResource.php +++ b/app/Filament/Resources/PronounsResource.php @@ -44,6 +44,7 @@ use Filament\Tables\Columns\TextColumn; use Filament\Forms\Components\TextInput; use Filament\Tables\Actions\DeleteAction; +use App\Filament\Clusters\ProfileManagement; use Filament\Tables\Actions\BulkActionGroup; use Filament\Tables\Actions\DeleteBulkAction; use App\Filament\Resources\PronounsResource\Pages\ManagePronouns; @@ -56,14 +57,12 @@ class PronounsResource extends Resource protected static ?string $label = 'User Profile Pronoun'; - protected static ?string $navigationParentItem = 'Profile Management'; - - protected static ?string $navigationGroup = 'Product Administration'; - protected static ?string $navigationLabel = 'Personal Pronouns'; protected static ?int $navigationSort = 1; + protected static ?string $cluster = ProfileManagement::class; + public static function form(Form $form): Form { return $form diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 27bdf9c642..e7799eb9b4 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -92,6 +92,7 @@ public function panel(Panel $panel): Panel ->favicon(asset('/images/default-favicon.png')) ->readOnlyRelationManagersOnResourceViewPagesByDefault(false) ->maxContentWidth('full') + ->discoverClusters(in: app_path('Filament/Clusters'), for: 'App\\Filament\\Clusters') ->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources') ->resources([]) ->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages') @@ -131,11 +132,6 @@ public function panel(Panel $panel): Panel ->label('Users and Permissions'), NavigationGroup::make() ->label('Product Administration'), - NavigationGroup::make() - ->label('Integrations'), - NavigationGroup::make() - ->label('Product Settings') - ->collapsed(), ]) ->plugins([ FilamentSpatieLaravelHealthPlugin::make() @@ -145,7 +141,11 @@ public function panel(Panel $panel): Panel ->userMenuItems([ 'profile' => MenuItem::make() ->url(fn () => EditProfile::getUrl()), - ]); + ]) + ->renderHook( + 'panels::scripts.before', + fn () => view('filament.scripts.scroll-sidebar-to-active-menu-item'), + ); } public function boot(): void {} diff --git a/composer.lock b/composer.lock index 938786121b..955c187e10 100644 --- a/composer.lock +++ b/composer.lock @@ -8,43 +8,36 @@ "packages": [ { "name": "amphp/amp", - "version": "v2.6.2", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", - "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb" + "reference": "aaf0ec1d5a2c20b523258995a10e80c1fb765871" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", - "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", + "url": "https://api.github.com/repos/amphp/amp/zipball/aaf0ec1d5a2c20b523258995a10e80c1fb765871", + "reference": "aaf0ec1d5a2c20b523258995a10e80c1fb765871", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" }, "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1", - "ext-json": "*", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^7 | ^8 | ^9", - "psalm/phar": "^3.11@dev", - "react/promise": "^2" + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "^4.13" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, "autoload": { "files": [ - "lib/functions.php", - "lib/Internal/functions.php" + "src/functions.php", + "src/Future/functions.php", + "src/Internal/functions.php" ], "psr-4": { - "Amp\\": "lib" + "Amp\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -52,10 +45,6 @@ "MIT" ], "authors": [ - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" - }, { "name": "Aaron Piotrowski", "email": "aaron@trowski.com" @@ -67,6 +56,10 @@ { "name": "Niklas Keller", "email": "me@kelunik.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" } ], "description": "A non-blocking concurrency framework for PHP applications.", @@ -83,9 +76,8 @@ "promise" ], "support": { - "irc": "irc://irc.freenode.org/amphp", "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v2.6.2" + "source": "https://github.com/amphp/amp/tree/v3.0.0" }, "funding": [ { @@ -93,46 +85,45 @@ "type": "github" } ], - "time": "2022-02-20T17:52:18+00:00" + "time": "2022-12-18T16:52:44+00:00" }, { "name": "amphp/byte-stream", - "version": "v1.8.1", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/amphp/byte-stream.git", - "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd" + "reference": "0a4b0e80dad92c75e6131f8ad253919211540338" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd", - "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/0a4b0e80dad92c75e6131f8ad253919211540338", + "reference": "0a4b0e80dad92c75e6131f8ad253919211540338", "shasum": "" }, "require": { - "amphp/amp": "^2", - "php": ">=7.1" + "amphp/amp": "^3", + "amphp/parser": "^1.1", + "amphp/pipeline": "^1", + "amphp/serialization": "^1", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2.3" }, "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1.4", - "friendsofphp/php-cs-fixer": "^2.3", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^6 || ^7 || ^8", - "psalm/phar": "^3.11.4" + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, "autoload": { "files": [ - "lib/functions.php" + "src/functions.php", + "src/Internal/functions.php" ], "psr-4": { - "Amp\\ByteStream\\": "lib" + "Amp\\ByteStream\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -150,7 +141,7 @@ } ], "description": "A stream abstraction to make working with non-blocking I/O simple.", - "homepage": "http://amphp.org/byte-stream", + "homepage": "https://amphp.org/byte-stream", "keywords": [ "amp", "amphp", @@ -160,9 +151,8 @@ "stream" ], "support": { - "irc": "irc://irc.freenode.org/amphp", "issues": "https://github.com/amphp/byte-stream/issues", - "source": "https://github.com/amphp/byte-stream/tree/v1.8.1" + "source": "https://github.com/amphp/byte-stream/tree/v2.1.0" }, "funding": [ { @@ -170,45 +160,39 @@ "type": "github" } ], - "time": "2021-03-30T17:13:30+00:00" + "time": "2023-11-19T14:34:16+00:00" }, { - "name": "amphp/parallel", - "version": "v1.4.3", + "name": "amphp/cache", + "version": "v2.0.0", "source": { "type": "git", - "url": "https://github.com/amphp/parallel.git", - "reference": "3aac213ba7858566fd83d38ccb85b91b2d652cb0" + "url": "https://github.com/amphp/cache.git", + "reference": "218bb3888d380eb9dd926cd06f803573c84391d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/parallel/zipball/3aac213ba7858566fd83d38ccb85b91b2d652cb0", - "reference": "3aac213ba7858566fd83d38ccb85b91b2d652cb0", + "url": "https://api.github.com/repos/amphp/cache/zipball/218bb3888d380eb9dd926cd06f803573c84391d3", + "reference": "218bb3888d380eb9dd926cd06f803573c84391d3", "shasum": "" }, "require": { - "amphp/amp": "^2", - "amphp/byte-stream": "^1.6.1", - "amphp/parser": "^1", - "amphp/process": "^1", + "amphp/amp": "^3", "amphp/serialization": "^1", - "amphp/sync": "^1.0.1", - "php": ">=7.1" + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" }, "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1.1", - "phpunit/phpunit": "^8 || ^7" + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" }, "type": "library", "autoload": { - "files": [ - "lib/Context/functions.php", - "lib/Sync/functions.php", - "lib/Worker/functions.php" - ], "psr-4": { - "Amp\\Parallel\\": "lib" + "Amp\\Cache\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -216,27 +200,112 @@ "MIT" ], "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, { "name": "Aaron Piotrowski", "email": "aaron@trowski.com" }, { - "name": "Stephen Coakley", - "email": "me@stephencoakley.com" + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" } ], - "description": "Parallel processing component for Amp.", - "homepage": "https://github.com/amphp/parallel", + "description": "A fiber-aware cache API based on Amp and Revolt.", + "homepage": "https://amphp.org/cache", + "support": { + "issues": "https://github.com/amphp/cache/issues", + "source": "https://github.com/amphp/cache/tree/v2.0.0" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2023-01-09T21:04:12+00:00" + }, + { + "name": "amphp/dns", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/dns.git", + "reference": "c3b518f321f26e786554480de580f06b9f34d1cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/dns/zipball/c3b518f321f26e786554480de580f06b9f34d1cd", + "reference": "c3b518f321f26e786554480de580f06b9f34d1cd", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/cache": "^2", + "amphp/parser": "^1", + "amphp/windows-registry": "^1", + "daverandom/libdns": "^2.0.2", + "ext-filter": "*", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Dns\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Wright", + "email": "addr@daverandom.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "Async DNS resolution for Amp.", + "homepage": "https://github.com/amphp/dns", "keywords": [ + "amp", + "amphp", "async", - "asynchronous", - "concurrent", - "multi-processing", - "multi-threading" + "client", + "dns", + "resolve" ], "support": { - "issues": "https://github.com/amphp/parallel/issues", - "source": "https://github.com/amphp/parallel/tree/v1.4.3" + "issues": "https://github.com/amphp/dns/issues", + "source": "https://github.com/amphp/dns/tree/v2.1.0" }, "funding": [ { @@ -244,41 +313,50 @@ "type": "github" } ], - "time": "2023-03-23T08:04:23+00:00" + "time": "2023-11-18T15:49:57+00:00" }, { - "name": "amphp/parallel-functions", - "version": "v1.1.0", + "name": "amphp/parallel", + "version": "v2.2.6", "source": { "type": "git", - "url": "https://github.com/amphp/parallel-functions.git", - "reference": "04e92fcacfc921a56dfe12c23b3265e62593a7cb" + "url": "https://github.com/amphp/parallel.git", + "reference": "5aeaad20297507cc754859236720501b54306eba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/parallel-functions/zipball/04e92fcacfc921a56dfe12c23b3265e62593a7cb", - "reference": "04e92fcacfc921a56dfe12c23b3265e62593a7cb", + "url": "https://api.github.com/repos/amphp/parallel/zipball/5aeaad20297507cc754859236720501b54306eba", + "reference": "5aeaad20297507cc754859236720501b54306eba", "shasum": "" }, "require": { - "amphp/amp": "^2.0.3", - "amphp/parallel": "^1.4", - "amphp/serialization": "^1.0", - "laravel/serializable-closure": "^1.0", - "php": ">=7.4" + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/parser": "^1", + "amphp/pipeline": "^1", + "amphp/process": "^2", + "amphp/serialization": "^1", + "amphp/socket": "^2", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1" }, "require-dev": { - "amphp/php-cs-fixer-config": "v2.x-dev", - "amphp/phpunit-util": "^2.0", - "phpunit/phpunit": "^9.5.11" + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.18" }, "type": "library", "autoload": { "files": [ - "src/functions.php" + "src/Context/functions.php", + "src/Context/Internal/functions.php", + "src/Ipc/functions.php", + "src/Worker/functions.php" ], "psr-4": { - "Amp\\ParallelFunctions\\": "src" + "Amp\\Parallel\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -286,15 +364,31 @@ "MIT" ], "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, { "name": "Niklas Keller", "email": "me@kelunik.com" + }, + { + "name": "Stephen Coakley", + "email": "me@stephencoakley.com" } ], - "description": "Parallel processing made simple.", + "description": "Parallel processing component for Amp.", + "homepage": "https://github.com/amphp/parallel", + "keywords": [ + "async", + "asynchronous", + "concurrent", + "multi-processing", + "multi-threading" + ], "support": { - "issues": "https://github.com/amphp/parallel-functions/issues", - "source": "https://github.com/amphp/parallel-functions/tree/v1.1.0" + "issues": "https://github.com/amphp/parallel/issues", + "source": "https://github.com/amphp/parallel/tree/v2.2.6" }, "funding": [ { @@ -302,7 +396,7 @@ "type": "github" } ], - "time": "2022-02-03T19:32:41+00:00" + "time": "2024-01-07T18:12:13+00:00" }, { "name": "amphp/parser", @@ -366,37 +460,107 @@ ], "time": "2022-12-30T18:08:47+00:00" }, + { + "name": "amphp/pipeline", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/pipeline.git", + "reference": "8a0ecc281bb0932d6b4a786453aff18c55756e63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/pipeline/zipball/8a0ecc281bb0932d6b4a786453aff18c55756e63", + "reference": "8a0ecc281bb0932d6b4a786453aff18c55756e63", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "php": ">=8.1", + "revolt/event-loop": "^1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.18" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Pipeline\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Asynchronous iterators and operators.", + "homepage": "https://amphp.org/pipeline", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "iterator", + "non-blocking" + ], + "support": { + "issues": "https://github.com/amphp/pipeline/issues", + "source": "https://github.com/amphp/pipeline/tree/v1.1.0" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2023-12-23T04:34:28+00:00" + }, { "name": "amphp/process", - "version": "v1.1.4", + "version": "v2.0.1", "source": { "type": "git", "url": "https://github.com/amphp/process.git", - "reference": "76e9495fd6818b43a20167cb11d8a67f7744ee0f" + "reference": "a65d3bc1f36ef12d44df42a68f0f0643183f1052" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/process/zipball/76e9495fd6818b43a20167cb11d8a67f7744ee0f", - "reference": "76e9495fd6818b43a20167cb11d8a67f7744ee0f", + "url": "https://api.github.com/repos/amphp/process/zipball/a65d3bc1f36ef12d44df42a68f0f0643183f1052", + "reference": "a65d3bc1f36ef12d44df42a68f0f0643183f1052", "shasum": "" }, "require": { - "amphp/amp": "^2", - "amphp/byte-stream": "^1.4", - "php": ">=7" + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" }, "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1", - "phpunit/phpunit": "^6" + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" }, "type": "library", "autoload": { "files": [ - "lib/functions.php" + "src/functions.php" ], "psr-4": { - "Amp\\Process\\": "lib" + "Amp\\Process\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -417,11 +581,11 @@ "email": "me@kelunik.com" } ], - "description": "Asynchronous process manager.", - "homepage": "https://github.com/amphp/process", + "description": "A fiber-aware process manager based on Amp and Revolt.", + "homepage": "https://amphp.org/process", "support": { "issues": "https://github.com/amphp/process/issues", - "source": "https://github.com/amphp/process/tree/v1.1.4" + "source": "https://github.com/amphp/process/tree/v2.0.1" }, "funding": [ { @@ -429,7 +593,7 @@ "type": "github" } ], - "time": "2022-07-06T23:50:12+00:00" + "time": "2023-01-15T16:00:57+00:00" }, { "name": "amphp/serialization", @@ -489,34 +653,121 @@ }, "time": "2020-03-25T21:39:07+00:00" }, + { + "name": "amphp/socket", + "version": "v2.2.2", + "source": { + "type": "git", + "url": "https://github.com/amphp/socket.git", + "reference": "eb6c5e6baae5aebd9a209f50e81bff38c7efef97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/socket/zipball/eb6c5e6baae5aebd9a209f50e81bff38c7efef97", + "reference": "eb6c5e6baae5aebd9a209f50e81bff38c7efef97", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/dns": "^2", + "ext-openssl": "*", + "kelunik/certificate": "^1.1", + "league/uri": "^6.5 | ^7", + "league/uri-interfaces": "^2.3 | ^7", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "amphp/process": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php", + "src/Internal/functions.php", + "src/SocketAddress/functions.php" + ], + "psr-4": { + "Amp\\Socket\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@gmail.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Non-blocking socket connection / server implementations based on Amp and Revolt.", + "homepage": "https://github.com/amphp/socket", + "keywords": [ + "amp", + "async", + "encryption", + "non-blocking", + "sockets", + "tcp", + "tls" + ], + "support": { + "issues": "https://github.com/amphp/socket/issues", + "source": "https://github.com/amphp/socket/tree/v2.2.2" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2023-12-31T18:12:01+00:00" + }, { "name": "amphp/sync", - "version": "v1.4.2", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/amphp/sync.git", - "reference": "85ab06764f4f36d63b1356b466df6111cf4b89cf" + "reference": "50ddc7392cc8034b3e4798cef3cc90d3f4c0441c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/sync/zipball/85ab06764f4f36d63b1356b466df6111cf4b89cf", - "reference": "85ab06764f4f36d63b1356b466df6111cf4b89cf", + "url": "https://api.github.com/repos/amphp/sync/zipball/50ddc7392cc8034b3e4798cef3cc90d3f4c0441c", + "reference": "50ddc7392cc8034b3e4798cef3cc90d3f4c0441c", "shasum": "" }, "require": { - "amphp/amp": "^2.2", - "php": ">=7.1" + "amphp/amp": "^3", + "amphp/pipeline": "^1", + "amphp/serialization": "^1", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" }, "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1.1", - "phpunit/phpunit": "^9 || ^8 || ^7" + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" }, "type": "library", "autoload": { "files": [ - "src/functions.php", - "src/ConcurrentIterator/functions.php" + "src/functions.php" ], "psr-4": { "Amp\\Sync\\": "src" @@ -531,12 +782,16 @@ "name": "Aaron Piotrowski", "email": "aaron@trowski.com" }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, { "name": "Stephen Coakley", "email": "me@stephencoakley.com" } ], - "description": "Mutex, Semaphore, and other synchronization tools for Amp.", + "description": "Non-blocking synchronization primitives for PHP based on Amp and Revolt.", "homepage": "https://github.com/amphp/sync", "keywords": [ "async", @@ -547,7 +802,7 @@ ], "support": { "issues": "https://github.com/amphp/sync/issues", - "source": "https://github.com/amphp/sync/tree/v1.4.2" + "source": "https://github.com/amphp/sync/tree/v2.1.0" }, "funding": [ { @@ -555,7 +810,59 @@ "type": "github" } ], - "time": "2021-10-25T18:29:10+00:00" + "time": "2023-08-19T13:53:40+00:00" + }, + { + "name": "amphp/windows-registry", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/windows-registry.git", + "reference": "8248247a41af7f97b88e4716c0f8de39696ef111" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/windows-registry/zipball/8248247a41af7f97b88e4716c0f8de39696ef111", + "reference": "8248247a41af7f97b88e4716c0f8de39696ef111", + "shasum": "" + }, + "require": { + "amphp/byte-stream": "^2", + "amphp/process": "^2", + "php": ">=8.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\WindowsRegistry\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Windows Registry Reader.", + "support": { + "issues": "https://github.com/amphp/windows-registry/issues", + "source": "https://github.com/amphp/windows-registry/tree/v1.0.0" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2023-01-09T22:29:20+00:00" }, { "name": "awcodes/filament-tiptap-editor", @@ -755,16 +1062,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.295.6", + "version": "3.295.8", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "9b0b2daf46d5e6a4600575917cea0764e4dbb6b5" + "reference": "dc23d1d1e2e0413a3707d5dd90d8c43cb6c7521b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/9b0b2daf46d5e6a4600575917cea0764e4dbb6b5", - "reference": "9b0b2daf46d5e6a4600575917cea0764e4dbb6b5", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/dc23d1d1e2e0413a3707d5dd90d8c43cb6c7521b", + "reference": "dc23d1d1e2e0413a3707d5dd90d8c43cb6c7521b", "shasum": "" }, "require": { @@ -844,9 +1151,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.295.6" + "source": "https://github.com/aws/aws-sdk-php/tree/3.295.8" }, - "time": "2024-01-04T19:43:02+00:00" + "time": "2024-01-08T19:04:58+00:00" }, { "name": "barryvdh/laravel-debugbar", @@ -3253,6 +3560,50 @@ ], "time": "2023-10-27T15:01:19+00:00" }, + { + "name": "daverandom/libdns", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/DaveRandom/LibDNS.git", + "reference": "42c2d700d1178c9f9e78664793463f7f1aea248c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DaveRandom/LibDNS/zipball/42c2d700d1178c9f9e78664793463f7f1aea248c", + "reference": "42c2d700d1178c9f9e78664793463f7f1aea248c", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": ">=7.0" + }, + "suggest": { + "ext-intl": "Required for IDN support" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "LibDNS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "DNS protocol implementation written in pure PHP", + "keywords": [ + "dns" + ], + "support": { + "issues": "https://github.com/DaveRandom/LibDNS/issues", + "source": "https://github.com/DaveRandom/LibDNS/tree/v2.0.3" + }, + "time": "2022-09-20T18:15:38+00:00" + }, { "name": "dflydev/dot-access-data", "version": "v3.0.2", @@ -4141,7 +4492,7 @@ }, { "name": "filament/actions", - "version": "v3.1.35", + "version": "v3.1.42", "source": { "type": "git", "url": "https://github.com/filamentphp/actions.git", @@ -4192,16 +4543,16 @@ }, { "name": "filament/filament", - "version": "v3.1.35", + "version": "v3.1.42", "source": { "type": "git", "url": "https://github.com/filamentphp/panels.git", - "reference": "4c6f1e1efdd3be5582af249055b893a09123777e" + "reference": "a9da0c924682caa307f4e76e38ac9956ccb5ed4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/panels/zipball/4c6f1e1efdd3be5582af249055b893a09123777e", - "reference": "4c6f1e1efdd3be5582af249055b893a09123777e", + "url": "https://api.github.com/repos/filamentphp/panels/zipball/a9da0c924682caa307f4e76e38ac9956ccb5ed4a", + "reference": "a9da0c924682caa307f4e76e38ac9956ccb5ed4a", "shasum": "" }, "require": { @@ -4253,20 +4604,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-01-04T12:28:40+00:00" + "time": "2024-01-09T17:55:06+00:00" }, { "name": "filament/forms", - "version": "v3.1.35", + "version": "v3.1.42", "source": { "type": "git", "url": "https://github.com/filamentphp/forms.git", - "reference": "23526fc23555d55d3fb3b9965efeba2ac04d6bbf" + "reference": "3eb61456e21a76094b5f7051c50f4ef0fcf72182" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/forms/zipball/23526fc23555d55d3fb3b9965efeba2ac04d6bbf", - "reference": "23526fc23555d55d3fb3b9965efeba2ac04d6bbf", + "url": "https://api.github.com/repos/filamentphp/forms/zipball/3eb61456e21a76094b5f7051c50f4ef0fcf72182", + "reference": "3eb61456e21a76094b5f7051c50f4ef0fcf72182", "shasum": "" }, "require": { @@ -4309,20 +4660,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-01-04T12:28:34+00:00" + "time": "2024-01-09T11:54:23+00:00" }, { "name": "filament/infolists", - "version": "v3.1.35", + "version": "v3.1.42", "source": { "type": "git", "url": "https://github.com/filamentphp/infolists.git", - "reference": "5bc1bfb47d34efd0ee7b3cee43d18996f99d9999" + "reference": "2515985792f32c68984ad2ea6b974b7342829e29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/infolists/zipball/5bc1bfb47d34efd0ee7b3cee43d18996f99d9999", - "reference": "5bc1bfb47d34efd0ee7b3cee43d18996f99d9999", + "url": "https://api.github.com/repos/filamentphp/infolists/zipball/2515985792f32c68984ad2ea6b974b7342829e29", + "reference": "2515985792f32c68984ad2ea6b974b7342829e29", "shasum": "" }, "require": { @@ -4360,11 +4711,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-01-02T23:07:20+00:00" + "time": "2024-01-08T12:59:23+00:00" }, { "name": "filament/notifications", - "version": "v3.1.35", + "version": "v3.1.42", "source": { "type": "git", "url": "https://github.com/filamentphp/notifications.git", @@ -4416,16 +4767,16 @@ }, { "name": "filament/spatie-laravel-media-library-plugin", - "version": "v3.1.35", + "version": "v3.1.42", "source": { "type": "git", "url": "https://github.com/filamentphp/spatie-laravel-media-library-plugin.git", - "reference": "64337a634115ea27602e972389c555f2a2e3f3d3" + "reference": "025bcacceea9368742e3a53257ce222906ef7888" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/spatie-laravel-media-library-plugin/zipball/64337a634115ea27602e972389c555f2a2e3f3d3", - "reference": "64337a634115ea27602e972389c555f2a2e3f3d3", + "url": "https://api.github.com/repos/filamentphp/spatie-laravel-media-library-plugin/zipball/025bcacceea9368742e3a53257ce222906ef7888", + "reference": "025bcacceea9368742e3a53257ce222906ef7888", "shasum": "" }, "require": { @@ -4449,11 +4800,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-01-04T20:29:06+00:00" + "time": "2024-01-08T12:59:14+00:00" }, { "name": "filament/spatie-laravel-settings-plugin", - "version": "v3.1.35", + "version": "v3.1.42", "source": { "type": "git", "url": "https://github.com/filamentphp/spatie-laravel-settings-plugin.git", @@ -4500,16 +4851,16 @@ }, { "name": "filament/support", - "version": "v3.1.35", + "version": "v3.1.42", "source": { "type": "git", "url": "https://github.com/filamentphp/support.git", - "reference": "bb580e362e66ae8071d8386e13841c1dc1a252b4" + "reference": "332308fdd61b67c8d8e7864029d8f6a85b99d49a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/support/zipball/bb580e362e66ae8071d8386e13841c1dc1a252b4", - "reference": "bb580e362e66ae8071d8386e13841c1dc1a252b4", + "url": "https://api.github.com/repos/filamentphp/support/zipball/332308fdd61b67c8d8e7864029d8f6a85b99d49a", + "reference": "332308fdd61b67c8d8e7864029d8f6a85b99d49a", "shasum": "" }, "require": { @@ -4553,20 +4904,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-01-04T12:29:08+00:00" + "time": "2024-01-08T12:59:20+00:00" }, { "name": "filament/tables", - "version": "v3.1.35", + "version": "v3.1.42", "source": { "type": "git", "url": "https://github.com/filamentphp/tables.git", - "reference": "ba00ac1bf300756a4b240decf8c82d550ff2d024" + "reference": "9efcf3f0b8395b376bb8eace47f11ed0830f8c09" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/tables/zipball/ba00ac1bf300756a4b240decf8c82d550ff2d024", - "reference": "ba00ac1bf300756a4b240decf8c82d550ff2d024", + "url": "https://api.github.com/repos/filamentphp/tables/zipball/9efcf3f0b8395b376bb8eace47f11ed0830f8c09", + "reference": "9efcf3f0b8395b376bb8eace47f11ed0830f8c09", "shasum": "" }, "require": { @@ -4606,11 +4957,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-01-04T12:29:06+00:00" + "time": "2024-01-08T12:59:16+00:00" }, { "name": "filament/widgets", - "version": "v3.1.35", + "version": "v3.1.42", "source": { "type": "git", "url": "https://github.com/filamentphp/widgets.git", @@ -5224,16 +5575,16 @@ }, { "name": "google/apiclient-services", - "version": "v0.330.0", + "version": "v0.331.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "3216fd1b6ba33c5f6658c3581e9723ff21d9acb7" + "reference": "94d0bcc1827f6ea24274fe17ece0930ae2a8f51d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/3216fd1b6ba33c5f6658c3581e9723ff21d9acb7", - "reference": "3216fd1b6ba33c5f6658c3581e9723ff21d9acb7", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/94d0bcc1827f6ea24274fe17ece0930ae2a8f51d", + "reference": "94d0bcc1827f6ea24274fe17ece0930ae2a8f51d", "shasum": "" }, "require": { @@ -5262,9 +5613,9 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", - "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.330.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.331.0" }, - "time": "2023-12-24T01:02:15+00:00" + "time": "2024-01-05T01:04:19+00:00" }, { "name": "google/auth", @@ -6062,6 +6413,64 @@ }, "time": "2023-09-26T02:20:38+00:00" }, + { + "name": "kelunik/certificate", + "version": "v1.1.3", + "source": { + "type": "git", + "url": "https://github.com/kelunik/certificate.git", + "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kelunik/certificate/zipball/7e00d498c264d5eb4f78c69f41c8bd6719c0199e", + "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "php": ">=7.0" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^6 | 7 | ^8 | ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Kelunik\\Certificate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Access certificate details and transform between different formats.", + "keywords": [ + "DER", + "certificate", + "certificates", + "openssl", + "pem", + "x509" + ], + "support": { + "issues": "https://github.com/kelunik/certificate/issues", + "source": "https://github.com/kelunik/certificate/tree/v1.1.3" + }, + "time": "2023-02-03T21:26:53+00:00" + }, { "name": "kirschbaum-development/eloquent-power-joins", "version": "3.4.0", @@ -6252,16 +6661,16 @@ }, { "name": "laravel/framework", - "version": "v10.39.0", + "version": "v10.40.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "114926b07bfb5fbf2545c03aa2ce5c8c37be650c" + "reference": "7a9470071dac9579ebf29ad1b9d73e4b8eb586fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/114926b07bfb5fbf2545c03aa2ce5c8c37be650c", - "reference": "114926b07bfb5fbf2545c03aa2ce5c8c37be650c", + "url": "https://api.github.com/repos/laravel/framework/zipball/7a9470071dac9579ebf29ad1b9d73e4b8eb586fc", + "reference": "7a9470071dac9579ebf29ad1b9d73e4b8eb586fc", "shasum": "" }, "require": { @@ -6453,7 +6862,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2023-12-27T14:26:28+00:00" + "time": "2024-01-09T11:46:47+00:00" }, { "name": "laravel/prompts", @@ -11224,6 +11633,78 @@ ], "time": "2023-11-16T16:16:50+00:00" }, + { + "name": "revolt/event-loop", + "version": "v1.0.6", + "source": { + "type": "git", + "url": "https://github.com/revoltphp/event-loop.git", + "reference": "25de49af7223ba039f64da4ae9a28ec2d10d0254" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/25de49af7223ba039f64da4ae9a28ec2d10d0254", + "reference": "25de49af7223ba039f64da4ae9a28ec2d10d0254", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Revolt\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "ceesjank@gmail.com" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Rock-solid event loop for concurrent PHP applications.", + "keywords": [ + "async", + "asynchronous", + "concurrency", + "event", + "event-loop", + "non-blocking", + "scheduler" + ], + "support": { + "issues": "https://github.com/revoltphp/event-loop/issues", + "source": "https://github.com/revoltphp/event-loop/tree/v1.0.6" + }, + "time": "2023-11-30T05:34:44+00:00" + }, { "name": "ryangjchandler/blade-capture-directive", "version": "v0.3.0", @@ -12348,16 +12829,16 @@ }, { "name": "spatie/laravel-health", - "version": "1.23.8", + "version": "1.23.9", "source": { "type": "git", "url": "https://github.com/spatie/laravel-health.git", - "reference": "f0219fa7fa89c55ba65f387e792304732ca2a797" + "reference": "223e12d73b9b19ac89bcd58888a48855e3bfbb82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-health/zipball/f0219fa7fa89c55ba65f387e792304732ca2a797", - "reference": "f0219fa7fa89c55ba65f387e792304732ca2a797", + "url": "https://api.github.com/repos/spatie/laravel-health/zipball/223e12d73b9b19ac89bcd58888a48855e3bfbb82", + "reference": "223e12d73b9b19ac89bcd58888a48855e3bfbb82", "shasum": "" }, "require": { @@ -12376,10 +12857,10 @@ "symfony/process": "^5.4|^6.0" }, "require-dev": { + "larastan/larastan": "^1.0.3|^2.4", "laravel/horizon": "^5.9.10", "laravel/slack-notification-channel": "^2.4", "nunomaduro/collision": "^5.10|^6.2.1|^6.1", - "nunomaduro/larastan": "^1.0.3|^2.4", "orchestra/testbench": "^6.23|^7.6|^8.0", "pestphp/pest": "^1.21.3", "pestphp/pest-plugin-laravel": "^1.2", @@ -12428,7 +12909,7 @@ "spatie" ], "support": { - "source": "https://github.com/spatie/laravel-health/tree/1.23.8" + "source": "https://github.com/spatie/laravel-health/tree/1.23.9" }, "funding": [ { @@ -12436,7 +12917,7 @@ "type": "github" } ], - "time": "2023-12-05T17:30:53+00:00" + "time": "2024-01-07T22:51:50+00:00" }, { "name": "spatie/laravel-medialibrary", @@ -12777,22 +13258,21 @@ }, { "name": "spatie/php-structure-discoverer", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/spatie/php-structure-discoverer.git", - "reference": "3e532f0952d37bb10cddd544800eb659499cda3d" + "reference": "d2e4e6cba962ce2a058ea415a123dd84b37765ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/php-structure-discoverer/zipball/3e532f0952d37bb10cddd544800eb659499cda3d", - "reference": "3e532f0952d37bb10cddd544800eb659499cda3d", + "url": "https://api.github.com/repos/spatie/php-structure-discoverer/zipball/d2e4e6cba962ce2a058ea415a123dd84b37765ac", + "reference": "d2e4e6cba962ce2a058ea415a123dd84b37765ac", "shasum": "" }, "require": { - "amphp/amp": "^2.6.2", - "amphp/parallel": "^1.4.1", - "amphp/parallel-functions": "^1.1", + "amphp/amp": "^v3.0", + "amphp/parallel": "^2.2", "illuminate/collections": "^9.30|^10.0", "php": "^8.1", "spatie/laravel-package-tools": "^1.4.3", @@ -12846,7 +13326,7 @@ ], "support": { "issues": "https://github.com/spatie/php-structure-discoverer/issues", - "source": "https://github.com/spatie/php-structure-discoverer/tree/2.0.0" + "source": "https://github.com/spatie/php-structure-discoverer/tree/2.0.1" }, "funding": [ { @@ -12854,7 +13334,7 @@ "type": "github" } ], - "time": "2023-12-21T12:04:07+00:00" + "time": "2024-01-08T21:01:26+00:00" }, { "name": "spatie/regex", @@ -17414,16 +17894,16 @@ }, { "name": "larastan/larastan", - "version": "v2.8.0", + "version": "v2.8.1", "source": { "type": "git", "url": "https://github.com/larastan/larastan.git", - "reference": "d60c1a6d49fcbb54b78922a955a55820abdbe3c7" + "reference": "b7cc6a29c457a7d4f3de90466392ae9ad3e17022" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/larastan/larastan/zipball/d60c1a6d49fcbb54b78922a955a55820abdbe3c7", - "reference": "d60c1a6d49fcbb54b78922a955a55820abdbe3c7", + "url": "https://api.github.com/repos/larastan/larastan/zipball/b7cc6a29c457a7d4f3de90466392ae9ad3e17022", + "reference": "b7cc6a29c457a7d4f3de90466392ae9ad3e17022", "shasum": "" }, "require": { @@ -17491,7 +17971,7 @@ ], "support": { "issues": "https://github.com/larastan/larastan/issues", - "source": "https://github.com/larastan/larastan/tree/v2.8.0" + "source": "https://github.com/larastan/larastan/tree/v2.8.1" }, "funding": [ { @@ -17511,7 +17991,7 @@ "type": "patreon" } ], - "time": "2024-01-02T22:09:07+00:00" + "time": "2024-01-08T09:11:17+00:00" }, { "name": "laravel/sail", @@ -17996,26 +18476,26 @@ }, { "name": "pestphp/pest-plugin-arch", - "version": "v2.5.0", + "version": "v2.6.0", "source": { "type": "git", "url": "https://github.com/pestphp/pest-plugin-arch.git", - "reference": "8d850753f0192c3fa1ed6c6cac6f76b718d131db" + "reference": "0741696072b5db5989d63013a7b3e83358f4dfcf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/8d850753f0192c3fa1ed6c6cac6f76b718d131db", - "reference": "8d850753f0192c3fa1ed6c6cac6f76b718d131db", + "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/0741696072b5db5989d63013a7b3e83358f4dfcf", + "reference": "0741696072b5db5989d63013a7b3e83358f4dfcf", "shasum": "" }, "require": { - "nunomaduro/collision": "^7.10.0|^8.0.0", + "nunomaduro/collision": "^7.10.0|^8.0.1", "pestphp/pest-plugin": "^2.1.1", "php": "^8.1", - "ta-tikoma/phpunit-architecture-test": "^0.7.5" + "ta-tikoma/phpunit-architecture-test": "^0.8.0" }, "require-dev": { - "pestphp/pest": "^2.27.0", + "pestphp/pest": "^2.30.0", "pestphp/pest-dev-tools": "^2.16.0" }, "type": "library", @@ -18051,7 +18531,7 @@ "unit" ], "support": { - "source": "https://github.com/pestphp/pest-plugin-arch/tree/v2.5.0" + "source": "https://github.com/pestphp/pest-plugin-arch/tree/v2.6.0" }, "funding": [ { @@ -18063,7 +18543,7 @@ "type": "github" } ], - "time": "2023-12-05T19:01:10+00:00" + "time": "2024-01-05T11:06:22+00:00" }, { "name": "pestphp/pest-plugin-faker", @@ -18522,16 +19002,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.51", + "version": "1.10.55", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "5082fa72dc13944578806ca1196a385818d8b077" + "reference": "9a88f9d18ddf4cf54c922fbeac16c4cb164c5949" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/5082fa72dc13944578806ca1196a385818d8b077", - "reference": "5082fa72dc13944578806ca1196a385818d8b077", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9a88f9d18ddf4cf54c922fbeac16c4cb164c5949", + "reference": "9a88f9d18ddf4cf54c922fbeac16c4cb164c5949", "shasum": "" }, "require": { @@ -18580,7 +19060,7 @@ "type": "tidelift" } ], - "time": "2024-01-04T21:16:30+00:00" + "time": "2024-01-08T12:32:40+00:00" }, { "name": "phpunit/php-code-coverage", @@ -20831,28 +21311,28 @@ }, { "name": "ta-tikoma/phpunit-architecture-test", - "version": "0.7.6", + "version": "0.8.4", "source": { "type": "git", "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", - "reference": "a252cd9488fd62f3c8c6cafa303b1b96e9df24e0" + "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/a252cd9488fd62f3c8c6cafa303b1b96e9df24e0", - "reference": "a252cd9488fd62f3c8c6cafa303b1b96e9df24e0", + "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/89f0dea1cb0f0d5744d3ec1764a286af5e006636", + "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18.0", + "nikic/php-parser": "^4.18.0 || ^5.0.0", "php": "^8.1.0", "phpdocumentor/reflection-docblock": "^5.3.0", - "phpunit/phpunit": "^10.5.5", + "phpunit/phpunit": "^10.5.5 || ^11.0.0", "symfony/finder": "^6.4.0 || ^7.0.0" }, "require-dev": { "laravel/pint": "^1.13.7", - "phpstan/phpstan": "^1.10.50" + "phpstan/phpstan": "^1.10.52" }, "type": "library", "autoload": { @@ -20884,9 +21364,9 @@ ], "support": { "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", - "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.7.6" + "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.4" }, - "time": "2023-12-29T13:14:58+00:00" + "time": "2024-01-05T14:10:56+00:00" }, { "name": "theseer/tokenizer", diff --git a/resources/views/filament/scripts/scroll-sidebar-to-active-menu-item.blade.php b/resources/views/filament/scripts/scroll-sidebar-to-active-menu-item.blade.php new file mode 100644 index 0000000000..30953e46e2 --- /dev/null +++ b/resources/views/filament/scripts/scroll-sidebar-to-active-menu-item.blade.php @@ -0,0 +1,43 @@ +{{-- + + + Copyright © 2022-2023, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +--}} +