@memberjunction/ng-explorer-settings 6.1.0-edge.4 → 6.1.0-edge.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/lib/application-management/application-dialog/application-dialog.component.js +2 -2
  2. package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
  3. package/dist/lib/application-management/application-management.component.js +4 -4
  4. package/dist/lib/application-management/application-management.component.js.map +1 -1
  5. package/dist/lib/entity-permissions/entity-permissions.component.js +3 -3
  6. package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
  7. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +1 -1
  8. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
  9. package/dist/lib/notification-preferences/notification-preferences.component.js +1 -1
  10. package/dist/lib/role-management/role-dialog/role-dialog.component.js +1 -1
  11. package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
  12. package/dist/lib/role-management/role-management.component.js +4 -4
  13. package/dist/lib/role-management/role-management.component.js.map +1 -1
  14. package/dist/lib/settings/settings.component.js +1 -1
  15. package/dist/lib/shared/settings-card.component.js +1 -1
  16. package/dist/lib/sql-logging/sql-logging.component.js +3 -3
  17. package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
  18. package/dist/lib/user-app-config/user-app-config-content.component.js +1 -1
  19. package/dist/lib/user-app-config/user-app-config.component.js +1 -1
  20. package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts +2 -0
  21. package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts.map +1 -1
  22. package/dist/lib/user-management/user-dialog/user-dialog.component.js +25 -4
  23. package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
  24. package/dist/lib/user-management/user-management.component.d.ts +5 -0
  25. package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
  26. package/dist/lib/user-management/user-management.component.js +61 -9
  27. package/dist/lib/user-management/user-management.component.js.map +1 -1
  28. package/dist/lib/user-profile-settings/user-profile-settings.component.js +1 -1
  29. package/package.json +26 -26
@@ -1 +1 @@
1
- {"version":3,"file":"entity-permissions.component.js","sourceRoot":"","sources":["../../../src/lib/entity-permissions/entity-permissions.component.ts","../../../src/lib/entity-permissions/entity-permissions.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnDestroy, ChangeDetectorRef, NgZone } from '@angular/core';\nimport { Subject, BehaviorSubject } from 'rxjs';\nimport { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';\nimport { RunView, Metadata } from '@memberjunction/core';\nimport {\n MJEntityPermissionEntity,\n MJEntityEntity,\n MJRoleEntity,\n ResourceData\n} from '@memberjunction/core-entities';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { FilterFieldConfig, ViewToggleOption } from '@memberjunction/ng-ui-components';\nimport { PermissionDialogData, PermissionDialogResult } from './permission-dialog/permission-dialog.component';\n\ninterface PermissionsStats {\n totalEntities: number;\n publicEntities: number;\n restrictedEntities: number;\n totalPermissions: number;\n}\n\ninterface FilterOptions {\n entitySearch: string;\n accessLevel: 'all' | 'public' | 'restricted' | 'custom';\n roleId: string | null;\n}\n\ninterface EntityAccess {\n entity: MJEntityEntity;\n isPublic: boolean;\n permissions: MJEntityPermissionEntity[];\n rolePermissions: Map<string, PermissionLevel>;\n}\n\ninterface PermissionLevel {\n canCreate: boolean;\n canRead: boolean;\n canUpdate: boolean;\n canDelete: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-entity-permissions',\n templateUrl: './entity-permissions.component.html',\n styleUrls: ['../shared/styles/_admin-patterns.css', './entity-permissions.component.css']\n})\n@RegisterClass(BaseDashboard, 'EntityPermissions')\nexport class EntityPermissionsComponent extends BaseDashboard implements OnDestroy {\n // State management\n public entityAccess: EntityAccess[] = [];\n public filteredEntityAccess: EntityAccess[] = [];\n public roles: MJRoleEntity[] = [];\n public isLoading = false;\n public error: string | null = null;\n \n // Permission dialog state\n public showPermissionDialog = false;\n public permissionDialogData: PermissionDialogData | null = null;\n \n // Stats\n public stats: PermissionsStats = {\n totalEntities: 0,\n publicEntities: 0,\n restrictedEntities: 0,\n totalPermissions: 0\n };\n \n // Filters\n public filters$ = new BehaviorSubject<FilterOptions>({\n entitySearch: '',\n accessLevel: 'all',\n roleId: null\n });\n \n // UI State\n public expandedEntityId: string | null = null;\n public viewMode: 'grid' | 'list' = 'list';\n\n /** Options for the <mj-view-toggle> in the interior chrome. Icon-only;\n title drives the tooltip + aria-label. */\n public readonly viewToggleOptions: ViewToggleOption[] = [\n { key: 'list', icon: 'fa-solid fa-list', title: 'List View' },\n { key: 'grid', icon: 'fa-solid fa-th', title: 'Grid View' }\n ];\n\n protected override destroy$ = new Subject<void>();\n private get metadata() { return this.ProviderToUse; }\n constructor(private cdr: ChangeDetectorRef, private ngZone: NgZone) {\n super();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return \"Permissions\"\n }\n\n protected initDashboard(): void {\n this.setupFilterSubscription();\n }\n\n protected loadData(): void {\n this.loadInitialData();\n }\n\n override ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n super.ngOnDestroy();\n }\n \n public async loadInitialData(): Promise<void> {\n try {\n this.isLoading = true;\n this.error = null;\n \n // Load all required data in parallel\n const [entities, permissions, roles] = await Promise.all([\n this.loadEntities(),\n this.loadEntityPermissions(),\n this.loadRoles()\n ]);\n \n // Process the data\n this.roles = roles;\n this.processEntityAccess(entities, permissions);\n this.calculateStats();\n this.applyFilters();\n \n } catch (error) {\n console.error('Error loading permissions data:', error);\n this.error = 'Failed to load permissions data. Please try again.';\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n private async loadEntities(): Promise<MJEntityEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJEntityEntity>({\n EntityName: 'MJ: Entities',\n ResultType: 'entity_object',\n OrderBy: 'Name ASC'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private async loadEntityPermissions(): Promise<MJEntityPermissionEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJEntityPermissionEntity>({\n EntityName: 'MJ: Entity Permissions',\n ResultType: 'entity_object',\n OrderBy: 'EntityID, RoleID'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private async loadRoles(): Promise<MJRoleEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n ResultType: 'entity_object',\n OrderBy: 'Name ASC'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private processEntityAccess(entities: MJEntityEntity[], permissions: MJEntityPermissionEntity[]): void {\n // Group permissions by entity\n const permissionsByEntity = new Map<string, MJEntityPermissionEntity[]>();\n \n for (const permission of permissions) {\n const entityId = permission.EntityID;\n if (!permissionsByEntity.has(entityId)) {\n permissionsByEntity.set(entityId, []);\n }\n permissionsByEntity.get(entityId)!.push(permission);\n }\n \n // Create EntityAccess objects\n this.entityAccess = entities.map(entity => {\n const entityPermissions = permissionsByEntity.get(entity.ID) || [];\n const rolePermissions = new Map<string, PermissionLevel>();\n \n // Process permissions by role\n for (const permission of entityPermissions) {\n if (permission.RoleID) {\n rolePermissions.set(permission.RoleID, {\n canCreate: permission.CanCreate || false,\n canRead: permission.CanRead || false,\n canUpdate: permission.CanUpdate || false,\n canDelete: permission.CanDelete || false\n });\n }\n }\n \n return {\n entity,\n isPublic: entity.AllowAllRowsAPI || false,\n permissions: entityPermissions,\n rolePermissions\n };\n });\n }\n \n private setupFilterSubscription(): void {\n this.filters$\n .pipe(\n debounceTime(300),\n distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),\n takeUntil(this.destroy$)\n )\n .subscribe(() => {\n this.applyFilters();\n });\n }\n \n private applyFilters(): void {\n const filters = this.filters$.value;\n let filtered = [...this.entityAccess];\n \n // Apply entity search\n if (filters.entitySearch) {\n const searchLower = filters.entitySearch.toLowerCase();\n filtered = filtered.filter(ea =>\n ea.entity.Name?.toLowerCase().includes(searchLower) ||\n ea.entity.Description?.toLowerCase().includes(searchLower)\n );\n }\n \n // Apply access level filter\n switch (filters.accessLevel) {\n case 'public':\n filtered = filtered.filter(ea => ea.isPublic);\n break;\n case 'restricted':\n filtered = filtered.filter(ea => !ea.isPublic && ea.permissions.length === 0);\n break;\n case 'custom':\n filtered = filtered.filter(ea => !ea.isPublic && ea.permissions.length > 0);\n break;\n }\n \n // Apply role filter\n if (filters.roleId) {\n filtered = filtered.filter(ea => \n ea.rolePermissions.has(filters.roleId!)\n );\n }\n \n this.filteredEntityAccess = filtered;\n }\n \n private calculateStats(): void {\n const publicEntities = this.entityAccess.filter(ea => ea.isPublic).length;\n const customPermissions = this.entityAccess.filter(ea => !ea.isPublic && ea.permissions.length > 0).length;\n const totalPermissions = this.entityAccess.reduce((sum, ea) => sum + ea.permissions.length, 0);\n \n this.stats = {\n totalEntities: this.entityAccess.length,\n publicEntities,\n restrictedEntities: this.entityAccess.length - publicEntities - customPermissions,\n totalPermissions\n };\n }\n \n // Public methods for template\n public onAccessLevelChange(level: 'all' | 'public' | 'restricted' | 'custom'): void {\n this.updateFilter({ accessLevel: level });\n }\n\n public updateFilter(partial: Partial<FilterOptions>): void {\n this.filters$.next({\n ...this.filters$.value,\n ...partial\n });\n // Discrete changes (chips, popover dropdowns) apply immediately. Text search\n // still goes through the 300ms debounce in setupFilterSubscription.\n if (!('entitySearch' in partial)) {\n this.applyFilters();\n this.cdr.markForCheck();\n }\n }\n\n // -- Filter panel binding (mj-filter-panel inside the one Filter popover) ---\n // Concise chrome: Access level + Role both live behind the single Filter\n // button; applied filters surface as removable chips below the card.\n\n public get filterFields(): FilterFieldConfig[] {\n return [\n {\n key: 'accessLevel',\n type: 'chips',\n label: 'Access level',\n chipOptions: [\n { text: 'All', value: 'all' },\n { text: 'Public', value: 'public' },\n { text: 'Restricted', value: 'restricted' },\n { text: 'Custom', value: 'custom' },\n ],\n },\n {\n key: 'roleId',\n type: 'dropdown',\n label: 'Role',\n icon: 'fa-solid fa-user-shield',\n placeholder: 'All Roles',\n filterable: this.roles.length > 10,\n options: [\n { text: 'All Roles', value: '' },\n ...this.roles.map(r => ({ text: r.Name ?? '', value: r.ID }))\n ]\n }\n ];\n }\n\n public get filterValues(): Record<string, unknown> {\n return { accessLevel: this.filters$.value.accessLevel, roleId: this.filters$.value.roleId ?? '' };\n }\n\n /** Total active filters (Access level + Role) — drives the Filter button badge. */\n public get TotalActiveFilterCount(): number {\n const f = this.filters$.value;\n return (f.accessLevel !== 'all' ? 1 : 0) + (f.roleId ? 1 : 0);\n }\n\n public onFilterPanelChange(values: Record<string, unknown>): void {\n const partial: Partial<FilterOptions> = {};\n if ('accessLevel' in values) {\n partial.accessLevel = (values['accessLevel'] as FilterOptions['accessLevel']) || 'all';\n }\n if ('roleId' in values) {\n partial.roleId = (values['roleId'] as string) || null;\n }\n this.updateFilter(partial);\n }\n\n /** Clear all filters (Access level + Role); search persists. */\n public clearAllAppliedFilters(): void {\n this.updateFilter({ accessLevel: 'all', roleId: null });\n }\n\n /** True when search and/or panel filters are narrowing the list — gates the\n * no-results empty-state \"Reset filters\" CTA. */\n public get IsListNarrowed(): boolean {\n return this.filters$.value.entitySearch !== '' || this.TotalActiveFilterCount > 0;\n }\n\n /** Reset everything narrowing the list (search + Access level + Role) and\n * refresh immediately. Wired to the no-results empty-state CTA. Unlike\n * clearAllAppliedFilters(), this also clears the search box. */\n public resetAllFiltersAndSearch(): void {\n this.filters$.next({ entitySearch: '', accessLevel: 'all', roleId: null });\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n /** Empty-state CTA handler: reset filters when the list is narrowed,\n * otherwise reload the data (the original \"Refresh\" affordance). */\n public onEmptyStateAction(): void {\n if (this.IsListNarrowed) {\n this.resetAllFiltersAndSearch();\n } else {\n this.refreshData();\n }\n }\n \n public toggleEntityExpansion(entityId: string): void {\n this.expandedEntityId = this.expandedEntityId === entityId ? null : entityId;\n }\n \n public isEntityExpanded(entityId: string): boolean {\n return this.expandedEntityId === entityId;\n }\n \n public editEntityPermissions(entityAccess: EntityAccess): void {\n console.log('Opening permission dialog for entity:', entityAccess.entity.Name);\n console.log('Entity permissions:', entityAccess.permissions);\n console.log('Available roles:', this.roles);\n \n this.permissionDialogData = {\n entity: entityAccess.entity,\n roles: this.roles,\n existingPermissions: entityAccess.permissions\n };\n this.showPermissionDialog = true;\n \n console.log('Dialog data set:', this.permissionDialogData);\n console.log('Dialog visible:', this.showPermissionDialog);\n }\n \n public onPermissionDialogResult(result: PermissionDialogResult): void {\n this.showPermissionDialog = false;\n this.permissionDialogData = null;\n\n if (result.action === 'save') {\n // Refresh the data after save\n this.loadInitialData();\n }\n }\n \n public async savePermissions(): Promise<void> {\n // This method is now handled by the dialog component\n // Keeping for backwards compatibility but not used\n console.warn('savePermissions method is deprecated - use PermissionDialogComponent instead');\n }\n \n public getAccessLevelClass(entityAccess: EntityAccess): string {\n if (entityAccess.isPublic) {\n return 'access-public';\n } else if (entityAccess.permissions.length === 0) {\n return 'access-restricted';\n } else {\n return 'access-custom';\n }\n }\n \n public getAccessLevelLabel(entityAccess: EntityAccess): string {\n if (entityAccess.isPublic) {\n return 'Public';\n } else if (entityAccess.permissions.length === 0) {\n return 'Restricted';\n } else {\n return 'Custom';\n }\n }\n \n public getRoleName(roleId: string): string {\n const role = this.roles.find(r => UUIDsEqual(r.ID, roleId));\n return role?.Name || 'Unknown Role';\n }\n \n public hasPermission(entityAccess: EntityAccess, roleId: string, permission: keyof PermissionLevel): boolean {\n const rolePermission = entityAccess.rolePermissions.get(roleId);\n return rolePermission ? rolePermission[permission] : false;\n }\n \n public refreshData(): void {\n this.loadInitialData();\n }\n \n public setViewMode(mode: 'grid' | 'list'): void {\n this.viewMode = mode;\n }\n}","<!--\n Interior chrome — see Section 10 of explorer-chrome-conventions.\n-->\n<mj-page-header-interior\n AriaLabel=\"Filter entity permissions\"\n Title=\"Entity Permissions\"\n Subtitle=\"Manage entity-level access for each role\">\n <!-- X-of-Y filtered count earns its meta spot per chrome conventions §2.\n Partition badges (public/restricted/custom) stay dropped — they mirror\n the Access Level filter chips in [toolbar]. -->\n <div meta>\n <mj-stat-badge\n [Count]=\"filteredEntityAccess.length\"\n [Total]=\"entityAccess.length\"\n Label=\"entities\">\n </mj-stat-badge>\n </div>\n <div toolbar>\n <!-- Concise-chrome control bar: search · Filter · view. Access level + Role\n live behind the one Filter button; applied filters show as removable\n chips below the card. On mobile the popover docks as a bottom sheet. -->\n <mj-page-search\n Placeholder=\"Search entities by name or description...\"\n [Value]=\"filters$.value.entitySearch\"\n (ValueChange)=\"updateFilter({ entitySearch: $event })\">\n </mj-page-search>\n <mj-filter-popover\n Label=\"Filters\"\n Icon=\"fa-solid fa-filter\"\n [ActiveCount]=\"TotalActiveFilterCount\"\n [ShowClearAll]=\"TotalActiveFilterCount > 0\"\n (ClearAllRequested)=\"clearAllAppliedFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterPanelChange($event)\"\n (Reset)=\"clearAllAppliedFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n <mj-view-toggle\n [Options]=\"viewToggleOptions\"\n [ActiveKey]=\"viewMode\"\n (KeyChange)=\"setViewMode($any($event))\">\n </mj-view-toggle>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"isLoading\" (Clicked)=\"refreshData()\"></mj-refresh-button>\n </div>\n</mj-page-header-interior>\n\n<!-- Scrollable Content Section — owned by <mj-page-body-interior>. -->\n<mj-page-body-interior>\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading entity permissions...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\" aria-live=\"assertive\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\" aria-hidden=\"true\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button\n mjButton variant=\"primary\"\n (click)=\"loadInitialData()\"\n aria-label=\"Retry loading entity permissions\"\n >\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n @if (!isLoading && !error) {\n @if (viewMode === 'list') {\n <!-- List View -->\n <div class=\"entities-list\" role=\"list\" aria-label=\"Entity permissions list\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <div\n class=\"entity-card\"\n [class.expanded]=\"isEntityExpanded(ea.entity.ID)\"\n role=\"listitem\"\n [attr.aria-expanded]=\"isEntityExpanded(ea.entity.ID)\"\n >\n <div\n class=\"entity-header\"\n (click)=\"toggleEntityExpansion(ea.entity.ID)\"\n (keydown.enter)=\"toggleEntityExpansion(ea.entity.ID)\"\n (keydown.space)=\"toggleEntityExpansion(ea.entity.ID); $event.preventDefault()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Expand permissions for ' + ea.entity.Name\"\n >\n <div class=\"entity-info\">\n <div class=\"entity-icon-wrapper\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-table\"></i>\n </div>\n <div class=\"entity-details\">\n <h3 class=\"entity-name\">{{ ea.entity.Name }}</h3>\n <p class=\"entity-description\">{{ ea.entity.Description || 'No description available' }}</p>\n </div>\n </div>\n\n <div class=\"entity-meta\">\n <span\n class=\"access-badge\"\n [class]=\"getAccessLevelClass(ea)\"\n [attr.aria-label]=\"'Access level: ' + getAccessLevelLabel(ea)\"\n >\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <div class=\"entity-actions\" (click)=\"$event.stopPropagation()\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button\n class=\"expand-btn\"\n [attr.aria-label]=\"(isEntityExpanded(ea.entity.ID) ? 'Collapse' : 'Expand') + ' permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n @if (isEntityExpanded(ea.entity.ID)) {\n <div class=\"entity-content\" role=\"region\" [attr.aria-label]=\"'Permissions for ' + ea.entity.Name\">\n <!-- Mobile-only actions bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"access-badge\" [class]=\"getAccessLevelClass(ea)\">\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n </div>\n </div>\n\n @if (ea.permissions.length > 0) {\n <table class=\"permissions-grid\" role=\"table\" aria-label=\"Role permissions\">\n <thead class=\"permissions-header\" role=\"rowgroup\">\n <tr role=\"row\">\n <th class=\"role-header\" scope=\"col\" role=\"columnheader\">Role</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Create</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Read</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Update</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Delete</th>\n </tr>\n </thead>\n <tbody role=\"rowgroup\">\n @for (roleId of ea.rolePermissions.keys(); track roleId) {\n <tr class=\"permission-row\" role=\"row\">\n <td class=\"role-name\" role=\"cell\">{{ getRoleName(roleId) }}</td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Create: ' + (hasPermission(ea, roleId, 'canCreate') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canCreate') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Read: ' + (hasPermission(ea, roleId, 'canRead') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canRead') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Update: ' + (hasPermission(ea, roleId, 'canUpdate') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canUpdate') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Delete: ' + (hasPermission(ea, roleId, 'canDelete') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canDelete') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <p class=\"no-permissions\">\n @if (ea.isPublic) {\n This entity is publicly accessible by all users.\n } @else {\n No specific role permissions configured. Access is restricted to system administrators.\n }\n </p>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <!-- Grid View -->\n <div class=\"entities-grid\" role=\"list\" aria-label=\"Entity permissions grid\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <article\n class=\"entity-grid-card\"\n [class]=\"getAccessLevelClass(ea)\"\n [attr.aria-label]=\"'Entity: ' + ea.entity.Name\"\n >\n <div class=\"grid-card-header\">\n <i class=\"fa-solid fa-table\" aria-hidden=\"true\"></i>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n title=\"Edit Permissions\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <h4 class=\"grid-card-title\">{{ ea.entity.Name }}</h4>\n <p class=\"grid-card-description\">{{ ea.entity.Description || 'No description' }}</p>\n <div class=\"grid-card-footer\">\n <span\n class=\"access-label\"\n [attr.aria-label]=\"'Access level: ' + getAccessLevelLabel(ea)\"\n >\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n @if (ea.permissions.length > 0) {\n <span\n class=\"permission-count\"\n [attr.aria-label]=\"ea.permissions.length + ' permission' + (ea.permissions.length === 1 ? '' : 's')\"\n >\n {{ ea.permissions.length }} permission{{ ea.permissions.length === 1 ? '' : 's' }}\n </span>\n }\n </div>\n </article>\n }\n </div>\n }\n\n @if (filteredEntityAccess.length === 0) {\n <mj-empty-state\n [Variant]=\"IsListNarrowed ? 'no-results' : 'empty'\"\n Icon=\"fa-solid fa-shield-halved\"\n Title=\"No Permissions Found\"\n Message=\"Try adjusting your filters or refresh the data.\"\n [ActionText]=\"IsListNarrowed ? 'Reset filters' : 'Refresh'\"\n [ActionIcon]=\"IsListNarrowed ? 'fa-solid fa-rotate-left' : 'fa-solid fa-arrows-rotate'\"\n (Action)=\"onEmptyStateAction()\" />\n }\n }\n </mj-page-body-interior>\n\n <!-- Permission Edit Dialog -->\n <mj-permission-dialog\n [visible]=\"showPermissionDialog\"\n [data]=\"permissionDialogData\"\n (result)=\"onPermissionDialogResult($event)\"\n ></mj-permission-dialog>\n\n"]}
1
+ {"version":3,"file":"entity-permissions.component.js","sourceRoot":"","sources":["../../../src/lib/entity-permissions/entity-permissions.component.ts","../../../src/lib/entity-permissions/entity-permissions.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnDestroy, ChangeDetectorRef, NgZone } from '@angular/core';\nimport { Subject, BehaviorSubject } from 'rxjs';\nimport { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';\nimport { RunView, Metadata } from '@memberjunction/core';\nimport {\n MJEntityPermissionEntity,\n MJEntityEntity,\n MJRoleEntity,\n ResourceData\n} from '@memberjunction/core-entities';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { FilterFieldConfig, ViewToggleOption } from '@memberjunction/ng-ui-components';\nimport { PermissionDialogData, PermissionDialogResult } from './permission-dialog/permission-dialog.component';\n\ninterface PermissionsStats {\n totalEntities: number;\n publicEntities: number;\n restrictedEntities: number;\n totalPermissions: number;\n}\n\ninterface FilterOptions {\n entitySearch: string;\n accessLevel: 'all' | 'public' | 'restricted' | 'custom';\n roleId: string | null;\n}\n\ninterface EntityAccess {\n entity: MJEntityEntity;\n isPublic: boolean;\n permissions: MJEntityPermissionEntity[];\n rolePermissions: Map<string, PermissionLevel>;\n}\n\ninterface PermissionLevel {\n canCreate: boolean;\n canRead: boolean;\n canUpdate: boolean;\n canDelete: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-entity-permissions',\n templateUrl: './entity-permissions.component.html',\n styleUrls: ['../shared/styles/_admin-patterns.css', './entity-permissions.component.css']\n})\n@RegisterClass(BaseDashboard, 'EntityPermissions')\nexport class EntityPermissionsComponent extends BaseDashboard implements OnDestroy {\n // State management\n public entityAccess: EntityAccess[] = [];\n public filteredEntityAccess: EntityAccess[] = [];\n public roles: MJRoleEntity[] = [];\n public isLoading = false;\n public error: string | null = null;\n \n // Permission dialog state\n public showPermissionDialog = false;\n public permissionDialogData: PermissionDialogData | null = null;\n \n // Stats\n public stats: PermissionsStats = {\n totalEntities: 0,\n publicEntities: 0,\n restrictedEntities: 0,\n totalPermissions: 0\n };\n \n // Filters\n public filters$ = new BehaviorSubject<FilterOptions>({\n entitySearch: '',\n accessLevel: 'all',\n roleId: null\n });\n \n // UI State\n public expandedEntityId: string | null = null;\n public viewMode: 'grid' | 'list' = 'list';\n\n /** Options for the <mj-view-toggle> in the interior chrome. Icon-only;\n title drives the tooltip + aria-label. */\n public readonly viewToggleOptions: ViewToggleOption[] = [\n { key: 'list', icon: 'fa-solid fa-list', title: 'List View' },\n { key: 'grid', icon: 'fa-solid fa-th', title: 'Grid View' }\n ];\n\n protected override destroy$ = new Subject<void>();\n private get metadata() { return this.ProviderToUse; }\n constructor(private cdr: ChangeDetectorRef, private ngZone: NgZone) {\n super();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return \"Permissions\"\n }\n\n protected initDashboard(): void {\n this.setupFilterSubscription();\n }\n\n protected loadData(): void {\n this.loadInitialData();\n }\n\n override ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n super.ngOnDestroy();\n }\n \n public async loadInitialData(): Promise<void> {\n try {\n this.isLoading = true;\n this.error = null;\n \n // Load all required data in parallel\n const [entities, permissions, roles] = await Promise.all([\n this.loadEntities(),\n this.loadEntityPermissions(),\n this.loadRoles()\n ]);\n \n // Process the data\n this.roles = roles;\n this.processEntityAccess(entities, permissions);\n this.calculateStats();\n this.applyFilters();\n \n } catch (error) {\n console.error('Error loading permissions data:', error);\n this.error = 'Failed to load permissions data. Please try again.';\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n private async loadEntities(): Promise<MJEntityEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJEntityEntity>({\n EntityName: 'MJ: Entities',\n ResultType: 'entity_object',\n OrderBy: 'Name ASC'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private async loadEntityPermissions(): Promise<MJEntityPermissionEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJEntityPermissionEntity>({\n EntityName: 'MJ: Entity Permissions',\n ResultType: 'entity_object',\n OrderBy: 'EntityID, RoleID'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private async loadRoles(): Promise<MJRoleEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n ResultType: 'entity_object',\n OrderBy: 'Name ASC'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private processEntityAccess(entities: MJEntityEntity[], permissions: MJEntityPermissionEntity[]): void {\n // Group permissions by entity\n const permissionsByEntity = new Map<string, MJEntityPermissionEntity[]>();\n \n for (const permission of permissions) {\n const entityId = permission.EntityID;\n if (!permissionsByEntity.has(entityId)) {\n permissionsByEntity.set(entityId, []);\n }\n permissionsByEntity.get(entityId)!.push(permission);\n }\n \n // Create EntityAccess objects\n this.entityAccess = entities.map(entity => {\n const entityPermissions = permissionsByEntity.get(entity.ID) || [];\n const rolePermissions = new Map<string, PermissionLevel>();\n \n // Process permissions by role\n for (const permission of entityPermissions) {\n if (permission.RoleID) {\n rolePermissions.set(permission.RoleID, {\n canCreate: permission.CanCreate || false,\n canRead: permission.CanRead || false,\n canUpdate: permission.CanUpdate || false,\n canDelete: permission.CanDelete || false\n });\n }\n }\n \n return {\n entity,\n isPublic: entity.AllowAllRowsAPI || false,\n permissions: entityPermissions,\n rolePermissions\n };\n });\n }\n \n private setupFilterSubscription(): void {\n this.filters$\n .pipe(\n debounceTime(300),\n distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),\n takeUntil(this.destroy$)\n )\n .subscribe(() => {\n this.applyFilters();\n });\n }\n \n private applyFilters(): void {\n const filters = this.filters$.value;\n let filtered = [...this.entityAccess];\n \n // Apply entity search\n if (filters.entitySearch) {\n const searchLower = filters.entitySearch.toLowerCase();\n filtered = filtered.filter(ea =>\n ea.entity.Name?.toLowerCase().includes(searchLower) ||\n ea.entity.Description?.toLowerCase().includes(searchLower)\n );\n }\n \n // Apply access level filter\n switch (filters.accessLevel) {\n case 'public':\n filtered = filtered.filter(ea => ea.isPublic);\n break;\n case 'restricted':\n filtered = filtered.filter(ea => !ea.isPublic && ea.permissions.length === 0);\n break;\n case 'custom':\n filtered = filtered.filter(ea => !ea.isPublic && ea.permissions.length > 0);\n break;\n }\n \n // Apply role filter\n if (filters.roleId) {\n filtered = filtered.filter(ea => \n ea.rolePermissions.has(filters.roleId!)\n );\n }\n \n this.filteredEntityAccess = filtered;\n }\n \n private calculateStats(): void {\n const publicEntities = this.entityAccess.filter(ea => ea.isPublic).length;\n const customPermissions = this.entityAccess.filter(ea => !ea.isPublic && ea.permissions.length > 0).length;\n const totalPermissions = this.entityAccess.reduce((sum, ea) => sum + ea.permissions.length, 0);\n \n this.stats = {\n totalEntities: this.entityAccess.length,\n publicEntities,\n restrictedEntities: this.entityAccess.length - publicEntities - customPermissions,\n totalPermissions\n };\n }\n \n // Public methods for template\n public onAccessLevelChange(level: 'all' | 'public' | 'restricted' | 'custom'): void {\n this.updateFilter({ accessLevel: level });\n }\n\n public updateFilter(partial: Partial<FilterOptions>): void {\n this.filters$.next({\n ...this.filters$.value,\n ...partial\n });\n // Discrete changes (chips, popover dropdowns) apply immediately. Text search\n // still goes through the 300ms debounce in setupFilterSubscription.\n if (!('entitySearch' in partial)) {\n this.applyFilters();\n this.cdr.markForCheck();\n }\n }\n\n // -- Filter panel binding (mj-filter-panel inside the one Filter popover) ---\n // Concise chrome: Access level + Role both live behind the single Filter\n // button; applied filters surface as removable chips below the card.\n\n public get filterFields(): FilterFieldConfig[] {\n return [\n {\n key: 'accessLevel',\n type: 'chips',\n label: 'Access level',\n chipOptions: [\n { text: 'All', value: 'all' },\n { text: 'Public', value: 'public' },\n { text: 'Restricted', value: 'restricted' },\n { text: 'Custom', value: 'custom' },\n ],\n },\n {\n key: 'roleId',\n type: 'dropdown',\n label: 'Role',\n icon: 'fa-solid fa-user-shield',\n placeholder: 'All Roles',\n filterable: this.roles.length > 10,\n options: [\n { text: 'All Roles', value: '' },\n ...this.roles.map(r => ({ text: r.Name ?? '', value: r.ID }))\n ]\n }\n ];\n }\n\n public get filterValues(): Record<string, unknown> {\n return { accessLevel: this.filters$.value.accessLevel, roleId: this.filters$.value.roleId ?? '' };\n }\n\n /** Total active filters (Access level + Role) — drives the Filter button badge. */\n public get TotalActiveFilterCount(): number {\n const f = this.filters$.value;\n return (f.accessLevel !== 'all' ? 1 : 0) + (f.roleId ? 1 : 0);\n }\n\n public onFilterPanelChange(values: Record<string, unknown>): void {\n const partial: Partial<FilterOptions> = {};\n if ('accessLevel' in values) {\n partial.accessLevel = (values['accessLevel'] as FilterOptions['accessLevel']) || 'all';\n }\n if ('roleId' in values) {\n partial.roleId = (values['roleId'] as string) || null;\n }\n this.updateFilter(partial);\n }\n\n /** Clear all filters (Access level + Role); search persists. */\n public clearAllAppliedFilters(): void {\n this.updateFilter({ accessLevel: 'all', roleId: null });\n }\n\n /** True when search and/or panel filters are narrowing the list — gates the\n * no-results empty-state \"Reset filters\" CTA. */\n public get IsListNarrowed(): boolean {\n return this.filters$.value.entitySearch !== '' || this.TotalActiveFilterCount > 0;\n }\n\n /** Reset everything narrowing the list (search + Access level + Role) and\n * refresh immediately. Wired to the no-results empty-state CTA. Unlike\n * clearAllAppliedFilters(), this also clears the search box. */\n public resetAllFiltersAndSearch(): void {\n this.filters$.next({ entitySearch: '', accessLevel: 'all', roleId: null });\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n /** Empty-state CTA handler: reset filters when the list is narrowed,\n * otherwise reload the data (the original \"Refresh\" affordance). */\n public onEmptyStateAction(): void {\n if (this.IsListNarrowed) {\n this.resetAllFiltersAndSearch();\n } else {\n this.refreshData();\n }\n }\n \n public toggleEntityExpansion(entityId: string): void {\n this.expandedEntityId = this.expandedEntityId === entityId ? null : entityId;\n }\n \n public isEntityExpanded(entityId: string): boolean {\n return this.expandedEntityId === entityId;\n }\n \n public editEntityPermissions(entityAccess: EntityAccess): void {\n console.log('Opening permission dialog for entity:', entityAccess.entity.Name);\n console.log('Entity permissions:', entityAccess.permissions);\n console.log('Available roles:', this.roles);\n \n this.permissionDialogData = {\n entity: entityAccess.entity,\n roles: this.roles,\n existingPermissions: entityAccess.permissions\n };\n this.showPermissionDialog = true;\n \n console.log('Dialog data set:', this.permissionDialogData);\n console.log('Dialog visible:', this.showPermissionDialog);\n }\n \n public onPermissionDialogResult(result: PermissionDialogResult): void {\n this.showPermissionDialog = false;\n this.permissionDialogData = null;\n\n if (result.action === 'save') {\n // Refresh the data after save\n this.loadInitialData();\n }\n }\n \n public async savePermissions(): Promise<void> {\n // This method is now handled by the dialog component\n // Keeping for backwards compatibility but not used\n console.warn('savePermissions method is deprecated - use PermissionDialogComponent instead');\n }\n \n public getAccessLevelClass(entityAccess: EntityAccess): string {\n if (entityAccess.isPublic) {\n return 'access-public';\n } else if (entityAccess.permissions.length === 0) {\n return 'access-restricted';\n } else {\n return 'access-custom';\n }\n }\n \n public getAccessLevelLabel(entityAccess: EntityAccess): string {\n if (entityAccess.isPublic) {\n return 'Public';\n } else if (entityAccess.permissions.length === 0) {\n return 'Restricted';\n } else {\n return 'Custom';\n }\n }\n \n public getRoleName(roleId: string): string {\n const role = this.roles.find(r => UUIDsEqual(r.ID, roleId));\n return role?.Name || 'Unknown Role';\n }\n \n public hasPermission(entityAccess: EntityAccess, roleId: string, permission: keyof PermissionLevel): boolean {\n const rolePermission = entityAccess.rolePermissions.get(roleId);\n return rolePermission ? rolePermission[permission] : false;\n }\n \n public refreshData(): void {\n this.loadInitialData();\n }\n \n public setViewMode(mode: 'grid' | 'list'): void {\n this.viewMode = mode;\n }\n}","<!--\n Interior chrome — see Section 10 of explorer-chrome-conventions.\n-->\n<mj-page-header-interior\n AriaLabel=\"Filter entity permissions\"\n Title=\"Entity Permissions\"\n Subtitle=\"Manage entity-level access for each role\">\n <!-- X-of-Y filtered count earns its meta spot per chrome conventions §2.\n Partition badges (public/restricted/custom) stay dropped — they mirror\n the Access Level filter chips in [toolbar]. -->\n <div meta>\n <mj-stat-badge\n [Count]=\"filteredEntityAccess.length\"\n [Total]=\"entityAccess.length\"\n Label=\"entities\">\n </mj-stat-badge>\n </div>\n <div toolbar>\n <!-- Concise-chrome control bar: search · Filter · view. Access level + Role\n live behind the one Filter button; applied filters show as removable\n chips below the card. On mobile the popover docks as a bottom sheet. -->\n <mj-page-search\n Placeholder=\"Search entities by name or description...\"\n [Value]=\"filters$.value.entitySearch\"\n (ValueChange)=\"updateFilter({ entitySearch: $event })\">\n </mj-page-search>\n <mj-filter-popover\n Label=\"Filters\"\n Icon=\"fa-solid fa-filter\"\n [ActiveCount]=\"TotalActiveFilterCount\"\n [ShowClearAll]=\"TotalActiveFilterCount > 0\"\n (ClearAllRequested)=\"clearAllAppliedFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterPanelChange($event)\"\n (Reset)=\"clearAllAppliedFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n <mj-view-toggle\n [Options]=\"viewToggleOptions\"\n [ActiveKey]=\"viewMode\"\n (KeyChange)=\"setViewMode($any($event))\">\n </mj-view-toggle>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"isLoading\" (Clicked)=\"refreshData()\"></mj-refresh-button>\n </div>\n</mj-page-header-interior>\n\n<!-- Scrollable Content Section — owned by <mj-page-body-interior>. -->\n<mj-page-body-interior>\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading entity permissions...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\" aria-live=\"assertive\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\" aria-hidden=\"true\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button\n mjButton variant=\"primary\"\n (click)=\"loadInitialData()\"\n aria-label=\"Retry loading entity permissions\"\n >\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n @if (!isLoading && !error) {\n @if (viewMode === 'list') {\n <!-- List View -->\n <div class=\"entities-list\" role=\"list\" aria-label=\"Entity permissions list\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <div\n class=\"entity-card\"\n [class.expanded]=\"isEntityExpanded(ea.entity.ID)\"\n role=\"listitem\"\n [attr.aria-expanded]=\"isEntityExpanded(ea.entity.ID)\"\n >\n <div\n class=\"entity-header\"\n (click)=\"toggleEntityExpansion(ea.entity.ID)\"\n (keydown.enter)=\"toggleEntityExpansion(ea.entity.ID)\"\n (keydown.space)=\"toggleEntityExpansion(ea.entity.ID); $event.preventDefault()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Expand permissions for ' + ea.entity.Name\"\n >\n <div class=\"entity-info\">\n <div class=\"entity-icon-wrapper\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-table\"></i>\n </div>\n <div class=\"entity-details\">\n <h3 class=\"entity-name\">{{ ea.entity.Name }}</h3>\n <p class=\"entity-description\">{{ ea.entity.Description || 'No description available' }}</p>\n </div>\n </div>\n\n <div class=\"entity-meta\">\n <span\n class=\"access-badge\"\n [class]=\"getAccessLevelClass(ea)\"\n [attr.aria-label]=\"'Access level: ' + getAccessLevelLabel(ea)\"\n >\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <div class=\"entity-actions\" (click)=\"$event.stopPropagation()\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button\n class=\"expand-btn\"\n [attr.aria-label]=\"(isEntityExpanded(ea.entity.ID) ? 'Collapse' : 'Expand') + ' permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n @if (isEntityExpanded(ea.entity.ID)) {\n <div class=\"entity-content\" role=\"region\" [attr.aria-label]=\"'Permissions for ' + ea.entity.Name\">\n <!-- Mobile-only actions bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"access-badge\" [class]=\"getAccessLevelClass(ea)\">\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n </div>\n </div>\n\n @if (ea.permissions.length > 0) {\n <table class=\"permissions-grid\" role=\"table\" aria-label=\"Role permissions\">\n <thead class=\"permissions-header\" role=\"rowgroup\">\n <tr role=\"row\">\n <th class=\"role-header\" scope=\"col\" role=\"columnheader\">Role</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Create</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Read</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Update</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Delete</th>\n </tr>\n </thead>\n <tbody role=\"rowgroup\">\n @for (roleId of ea.rolePermissions.keys(); track roleId) {\n <tr class=\"permission-row\" role=\"row\">\n <td class=\"role-name\" role=\"cell\">{{ getRoleName(roleId) }}</td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Create: ' + (hasPermission(ea, roleId, 'canCreate') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canCreate') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Read: ' + (hasPermission(ea, roleId, 'canRead') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canRead') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Update: ' + (hasPermission(ea, roleId, 'canUpdate') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canUpdate') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Delete: ' + (hasPermission(ea, roleId, 'canDelete') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canDelete') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <p class=\"no-permissions\">\n @if (ea.isPublic) {\n This entity is publicly accessible by all users.\n } @else {\n No specific role permissions configured. Access is restricted to system administrators.\n }\n </p>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <!-- Grid View -->\n <div class=\"entities-grid\" role=\"list\" aria-label=\"Entity permissions grid\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <article\n class=\"entity-grid-card\"\n [class]=\"getAccessLevelClass(ea)\"\n [attr.aria-label]=\"'Entity: ' + ea.entity.Name\"\n >\n <div class=\"grid-card-header\">\n <i class=\"fa-solid fa-table\" aria-hidden=\"true\"></i>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n title=\"Edit Permissions\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <h4 class=\"grid-card-title\">{{ ea.entity.Name }}</h4>\n <p class=\"grid-card-description\">{{ ea.entity.Description || 'No description' }}</p>\n <div class=\"grid-card-footer\">\n <span\n class=\"access-label\"\n [attr.aria-label]=\"'Access level: ' + getAccessLevelLabel(ea)\"\n >\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n @if (ea.permissions.length > 0) {\n <span\n class=\"permission-count\"\n [attr.aria-label]=\"ea.permissions.length + ' permission' + (ea.permissions.length === 1 ? '' : 's')\"\n >\n {{ ea.permissions.length }} permission{{ ea.permissions.length === 1 ? '' : 's' }}\n </span>\n }\n </div>\n </article>\n }\n </div>\n }\n\n @if (filteredEntityAccess.length === 0) {\n <mj-empty-state\n [Variant]=\"IsListNarrowed ? 'no-results' : 'empty'\"\n Icon=\"fa-solid fa-shield-halved\"\n Title=\"No Permissions Found\"\n Message=\"Try adjusting your filters or refresh the data.\"\n [ActionText]=\"IsListNarrowed ? 'Reset filters' : 'Refresh'\"\n [ActionIcon]=\"IsListNarrowed ? 'fa-solid fa-rotate-left' : 'fa-solid fa-arrows-rotate'\"\n (Action)=\"onEmptyStateAction()\" />\n }\n }\n </mj-page-body-interior>\n\n <!-- Permission Edit Dialog -->\n <mj-permission-dialog\n [visible]=\"showPermissionDialog\"\n [data]=\"permissionDialogData\"\n (result)=\"onPermissionDialogResult($event)\"\n ></mj-permission-dialog>\n\n"]}
@@ -151,7 +151,7 @@ function PermissionDialogComponent_Conditional_0_Template(rf, ctx) { if (rf & 1)
151
151
  i0.ɵɵelementStart(0, "div", 1);
152
152
  i0.ɵɵlistener("click", function PermissionDialogComponent_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onCancel()); });
153
153
  i0.ɵɵelementStart(1, "div", 2);
154
- i0.ɵɵlistener("click", function PermissionDialogComponent_Conditional_0_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView($event.stopPropagation()); });
154
+ i0.ɵɵlistener("click", function PermissionDialogComponent_Conditional_0_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
155
155
  i0.ɵɵelementStart(2, "div", 3)(3, "div", 4)(4, "h2", 5);
156
156
  i0.ɵɵelement(5, "i", 6);
157
157
  i0.ɵɵtext(6, " Edit Entity Permissions ");
@@ -1 +1 @@
1
- {"version":3,"file":"permission-dialog.component.js","sourceRoot":"","sources":["../../../../src/lib/entity-permissions/permission-dialog/permission-dialog.component.ts","../../../../src/lib/entity-permissions/permission-dialog/permission-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, OnChanges, SimpleChanges, inject, HostListener, ChangeDetectorRef, NgZone, ViewEncapsulation } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup } from '@angular/forms';\nimport { Metadata, RunView } from '@memberjunction/core';\nimport { MJEntityPermissionEntity, MJEntityEntity, MJRoleEntity } from '@memberjunction/core-entities';\nimport { UUIDsEqual } from '@memberjunction/global';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nexport interface PermissionDialogData {\n entity: MJEntityEntity;\n roles: MJRoleEntity[];\n existingPermissions: MJEntityPermissionEntity[];\n}\n\nexport interface PermissionDialogResult {\n action: 'save' | 'cancel';\n entity?: MJEntityEntity;\n}\n\ninterface RolePermissions {\n roleId: string;\n roleName: string;\n entityPermission: MJEntityPermissionEntity;\n isNew: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-permission-dialog',\n encapsulation: ViewEncapsulation.None,\n templateUrl: './permission-dialog.component.html',\n styleUrls: ['./permission-dialog.component.css']\n})\nexport class PermissionDialogComponent extends BaseAngularComponent implements OnInit, OnDestroy, OnChanges {\n @Input() data: PermissionDialogData | null = null;\n @Input() visible = false;\n @Output() result = new EventEmitter<PermissionDialogResult>();\n\n private fb = inject(FormBuilder);\n private cdr = inject(ChangeDetectorRef);\n private ngZone = inject(NgZone);\n private get metadata() { return this.ProviderToUse; }\n public permissionForm: FormGroup;\n public isLoading = false;\n public error: string | null = null;\n public rolePermissions: RolePermissions[] = [];\n public availableRoles: MJRoleEntity[] = [];\n\n constructor() {\n super();\n this.permissionForm = this.fb.group({});\n }\n\n ngOnInit(): void {\n // Initial setup\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n console.log('Permission dialog ngOnChanges called:', changes);\n \n if (changes['visible'] && this.visible) {\n this.resetDialog();\n // Load data when dialog becomes visible and we have data\n if (this.data) {\n console.log('Dialog became visible, loading permission data');\n this.loadPermissionData();\n }\n }\n \n if (changes['data'] && this.data && this.visible) {\n console.log('Data changed while dialog is visible, reloading permission data');\n this.loadPermissionData();\n }\n }\n\n ngOnDestroy(): void {\n // Cleanup if needed\n }\n\n private resetDialog(): void {\n this.error = null;\n this.isLoading = false;\n }\n\n @HostListener('document:keydown.escape', ['$event'])\n onEscapeKey(event: Event): void {\n if (this.visible) {\n this.onCancel();\n }\n }\n\n public get hasChanges(): boolean {\n return this.rolePermissions.some(rp => rp.isNew || rp.entityPermission.Dirty);\n }\n\n public hasEntityChanges(rolePermission: RolePermissions): boolean {\n return rolePermission.isNew || rolePermission.entityPermission.Dirty;\n }\n\n private loadPermissionData(): void {\n if (!this.data) return;\n\n console.log('Loading permission data for entity:', this.data.entity.Name);\n console.log('Existing permissions:', this.data.existingPermissions);\n console.log('Available roles:', this.data.roles);\n\n // Initialize role permissions from existing data\n this.rolePermissions = [];\n const existingRoleIds = new Set<string>();\n\n // Process existing permissions\n for (const permission of this.data.existingPermissions) {\n const role = this.data.roles.find(r => UUIDsEqual(r.ID, permission.RoleID));\n if (role) {\n console.log(`Processing permission for role ${role.Name}:`, {\n canCreate: permission.CanCreate,\n canRead: permission.CanRead,\n canUpdate: permission.CanUpdate,\n canDelete: permission.CanDelete\n });\n \n this.rolePermissions.push({\n roleId: role.ID,\n roleName: role.Name || '',\n entityPermission: permission,\n isNew: false\n });\n existingRoleIds.add(role.ID);\n }\n }\n\n console.log('Loaded role permissions:', this.rolePermissions);\n\n // Set available roles (those not already configured)\n this.availableRoles = this.data.roles.filter(role => !existingRoleIds.has(role.ID));\n \n console.log('Available roles for adding:', this.availableRoles.map(r => r.Name));\n \n // Trigger change detection to update the UI\n this.cdr.detectChanges();\n }\n\n public async addRolePermission(role: MJRoleEntity): Promise<void> {\n // Create new EntityPermission entity\n const entityPermission = await this.metadata.GetEntityObject<MJEntityPermissionEntity>('MJ: Entity Permissions');\n entityPermission.NewRecord();\n entityPermission.EntityID = this.data!.entity.ID;\n entityPermission.RoleID = role.ID;\n entityPermission.CanCreate = false;\n entityPermission.CanRead = true; // Default to read access\n entityPermission.CanUpdate = false;\n entityPermission.CanDelete = false;\n\n // Add new role permission\n this.rolePermissions.push({\n roleId: role.ID,\n roleName: role.Name || '',\n entityPermission: entityPermission,\n isNew: true\n });\n\n // Remove from available roles\n this.availableRoles = this.availableRoles.filter(r => !UUIDsEqual(r.ID, role.ID));\n this.cdr.detectChanges();\n }\n\n public removeRolePermission(rolePermission: RolePermissions): void {\n // Add back to available roles if not new\n if (!rolePermission.isNew) {\n const role = this.data?.roles.find(r => UUIDsEqual(r.ID, rolePermission.roleId));\n if (role) {\n this.availableRoles.push(role);\n this.availableRoles.sort((a, b) => (a.Name || '').localeCompare(b.Name || ''));\n }\n } else {\n // Add back to available roles\n const role = this.data?.roles.find(r => UUIDsEqual(r.ID, rolePermission.roleId));\n if (role) {\n this.availableRoles.push(role);\n this.availableRoles.sort((a, b) => (a.Name || '').localeCompare(b.Name || ''));\n }\n }\n\n // Remove from role permissions\n this.rolePermissions = this.rolePermissions.filter(rp => rp.roleId !== rolePermission.roleId);\n this.cdr.detectChanges();\n }\n\n public async onSubmit(): Promise<void> {\n if (!this.data || !this.hasChanges) return;\n\n this.isLoading = true;\n this.error = null;\n\n try {\n // Process each role permission\n for (const rolePermission of this.rolePermissions) {\n if (rolePermission.isNew || rolePermission.entityPermission.Dirty) {\n await this.saveRolePermission(rolePermission);\n }\n }\n\n this.result.emit({ action: 'save', entity: this.data.entity });\n\n } catch (error: unknown) {\n console.error('Error saving permissions:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'An unexpected error occurred while saving permissions';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n private async saveRolePermission(rolePermission: RolePermissions): Promise<void> {\n // Save the entity directly - it already has all the values bound\n const saveResult = await rolePermission.entityPermission.Save();\n if (!saveResult) {\n throw new Error(rolePermission.entityPermission.LatestResult?.Message || `Failed to save permissions for role ${rolePermission.roleName}`);\n }\n }\n\n public onCancel(): void {\n this.result.emit({ action: 'cancel' });\n }\n}","<!-- MD3 Modal Dialog -->\n@if (visible) {\n <div class=\"modal-backdrop\" (click)=\"onCancel()\">\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <!-- Modal Header -->\n <div class=\"modal-header\">\n <div class=\"dialog-header\">\n <h2 class=\"dialog-title\">\n <i class=\"fa-solid fa-key\"></i>\n Edit Entity Permissions\n </h2>\n <p class=\"dialog-subtitle\">\n Configure role-based permissions for {{ data?.entity?.Name }}\n </p>\n </div>\n <button type=\"button\" class=\"modal-close\" (click)=\"onCancel()\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Modal Body -->\n <div class=\"modal-body\">\n <form [formGroup]=\"permissionForm\" (ngSubmit)=\"onSubmit()\">\n @if (error) {\n <div class=\"content-section\">\n <mj-alert Variant=\"error\" [Message]=\"error\" />\n </div>\n }\n <!-- Entity Information Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-database\"></i>\n Entity Information\n </h3>\n <p class=\"section-description\">{{ data?.entity?.Description || 'Entity permissions configuration' }}</p>\n </div>\n <div class=\"entity-info-card\">\n <div class=\"entity-meta\">\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-table\"></i>\n <span class=\"meta-label\">Entity:</span>\n <span class=\"meta-value\">{{ data?.entity?.Name }}</span>\n </div>\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span class=\"meta-label\">Schema Name:</span>\n <span class=\"meta-value\">{{ data?.entity?.SchemaName || 'N/A' }}</span>\n </div>\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-key\"></i>\n <span class=\"meta-label\">Total Permissions:</span>\n <span class=\"meta-value\">{{ rolePermissions.length }}</span>\n </div>\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-clock\"></i>\n <span class=\"meta-label\">Last Updated:</span>\n <span class=\"meta-value\">{{ data?.entity?.__mj_UpdatedAt | date:'medium' }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Permissions Configuration Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-users-cog\"></i>\n Role Permissions\n </h3>\n <p class=\"section-description\">Configure CRUD permissions for each role</p>\n </div>\n <div class=\"permissions-table-container\">\n <table class=\"permissions-table\">\n <thead>\n <tr>\n <th class=\"role-column\">Role</th>\n <th class=\"permission-column\">\n <i class=\"fa-solid fa-plus\"></i>\n Create\n </th>\n <th class=\"permission-column\">\n <i class=\"fa-solid fa-eye\"></i>\n Read\n </th>\n <th class=\"permission-column\">\n <i class=\"fa-solid fa-edit\"></i>\n Update\n </th>\n <th class=\"permission-column\">\n <i class=\"fa-solid fa-trash\"></i>\n Delete\n </th>\n <th class=\"actions-column\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (rolePermission of rolePermissions; track rolePermission.roleId) {\n <tr class=\"permission-row\" [class.has-changes]=\"hasEntityChanges(rolePermission)\" [class.is-new]=\"rolePermission.isNew\">\n <td class=\"role-name\">\n <div class=\"role-info\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>{{ rolePermission.roleName }}</span>\n @if (rolePermission.isNew) {\n <span class=\"new-badge\">New</span>\n }\n @if (hasEntityChanges(rolePermission) && !rolePermission.isNew) {\n <span class=\"changed-badge\">Modified</span>\n }\n </div>\n </td>\n <td class=\"permission-cell\">\n <div class=\"permission-toggle\">\n <input\n type=\"checkbox\"\n [id]=\"'create-' + rolePermission.roleId\"\n [(ngModel)]=\"rolePermission.entityPermission.CanCreate\"\n [ngModelOptions]=\"{standalone: true}\"\n class=\"permission-checkbox\"\n />\n <label [for]=\"'create-' + rolePermission.roleId\" class=\"permission-label\">\n <div class=\"checkbox-indicator\"></div>\n </label>\n </div>\n </td>\n <td class=\"permission-cell\">\n <div class=\"permission-toggle\">\n <input\n type=\"checkbox\"\n [id]=\"'read-' + rolePermission.roleId\"\n [(ngModel)]=\"rolePermission.entityPermission.CanRead\"\n [ngModelOptions]=\"{standalone: true}\"\n class=\"permission-checkbox\"\n />\n <label [for]=\"'read-' + rolePermission.roleId\" class=\"permission-label\">\n <div class=\"checkbox-indicator\"></div>\n </label>\n </div>\n </td>\n <td class=\"permission-cell\">\n <div class=\"permission-toggle\">\n <input\n type=\"checkbox\"\n [id]=\"'update-' + rolePermission.roleId\"\n [(ngModel)]=\"rolePermission.entityPermission.CanUpdate\"\n [ngModelOptions]=\"{standalone: true}\"\n class=\"permission-checkbox\"\n />\n <label [for]=\"'update-' + rolePermission.roleId\" class=\"permission-label\">\n <div class=\"checkbox-indicator\"></div>\n </label>\n </div>\n </td>\n <td class=\"permission-cell\">\n <div class=\"permission-toggle\">\n <input\n type=\"checkbox\"\n [id]=\"'delete-' + rolePermission.roleId\"\n [(ngModel)]=\"rolePermission.entityPermission.CanDelete\"\n [ngModelOptions]=\"{standalone: true}\"\n class=\"permission-checkbox\"\n />\n <label [for]=\"'delete-' + rolePermission.roleId\" class=\"permission-label\">\n <div class=\"checkbox-indicator\"></div>\n </label>\n </div>\n </td>\n <td class=\"actions-cell\">\n <button\n type=\"button\"\n class=\"btn-icon btn-danger\"\n (click)=\"removeRolePermission(rolePermission)\"\n title=\"Remove permissions for this role\"\n attr.aria-label=\"Remove permissions for {{ rolePermission.roleName }}\"\n >\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (rolePermissions.length === 0) {\n <div class=\"empty-permissions\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <p>No role permissions configured</p>\n <p class=\"empty-subtext\">Add permissions for specific roles to control access to this entity</p>\n </div>\n }\n </div>\n <!-- Add Role Permissions -->\n <div class=\"add-role-section\">\n <div class=\"add-role-header\">\n <h4>Add Role Permissions</h4>\n <p>Select roles to configure permissions for this entity</p>\n </div>\n <div class=\"available-roles\">\n @for (role of availableRoles; track role.ID) {\n <button\n type=\"button\"\n class=\"role-chip\"\n (click)=\"addRolePermission(role)\"\n title=\"Add permissions for {{ role.Name }}\"\n attr.aria-label=\"Add permissions for {{ role.Name }}\"\n >\n <i class=\"fa-solid fa-plus\"></i>\n {{ role.Name }}\n </button>\n }\n @if (availableRoles.length === 0) {\n <p class=\"no-available-roles\">All roles have been configured</p>\n }\n </div>\n </div>\n </div>\n </div>\n <!-- Modal Footer -->\n <div class=\"modal-footer\">\n <div class=\"footer-info\">\n @if (hasChanges) {\n <span class=\"changes-indicator\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n You have unsaved changes\n </span>\n }\n </div>\n <div class=\"footer-actions\">\n <button\n type=\"submit\"\n class=\"btn btn-primary\"\n [disabled]=\"!hasChanges || isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Saving...\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n Save Permissions\n }\n </button>\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"onCancel()\">\n <i class=\"fa-solid fa-times\"></i>\n Cancel\n </button>\n </div>\n </div>\n </form>\n </div>\n </div>\n </div>\n}\n"]}
1
+ {"version":3,"file":"permission-dialog.component.js","sourceRoot":"","sources":["../../../../src/lib/entity-permissions/permission-dialog/permission-dialog.component.ts","../../../../src/lib/entity-permissions/permission-dialog/permission-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, OnChanges, SimpleChanges, inject, HostListener, ChangeDetectorRef, NgZone, ViewEncapsulation } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup } from '@angular/forms';\nimport { Metadata, RunView } from '@memberjunction/core';\nimport { MJEntityPermissionEntity, MJEntityEntity, MJRoleEntity } from '@memberjunction/core-entities';\nimport { UUIDsEqual } from '@memberjunction/global';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nexport interface PermissionDialogData {\n entity: MJEntityEntity;\n roles: MJRoleEntity[];\n existingPermissions: MJEntityPermissionEntity[];\n}\n\nexport interface PermissionDialogResult {\n action: 'save' | 'cancel';\n entity?: MJEntityEntity;\n}\n\ninterface RolePermissions {\n roleId: string;\n roleName: string;\n entityPermission: MJEntityPermissionEntity;\n isNew: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-permission-dialog',\n encapsulation: ViewEncapsulation.None,\n templateUrl: './permission-dialog.component.html',\n styleUrls: ['./permission-dialog.component.css']\n})\nexport class PermissionDialogComponent extends BaseAngularComponent implements OnInit, OnDestroy, OnChanges {\n @Input() data: PermissionDialogData | null = null;\n @Input() visible = false;\n @Output() result = new EventEmitter<PermissionDialogResult>();\n\n private fb = inject(FormBuilder);\n private cdr = inject(ChangeDetectorRef);\n private ngZone = inject(NgZone);\n private get metadata() { return this.ProviderToUse; }\n public permissionForm: FormGroup;\n public isLoading = false;\n public error: string | null = null;\n public rolePermissions: RolePermissions[] = [];\n public availableRoles: MJRoleEntity[] = [];\n\n constructor() {\n super();\n this.permissionForm = this.fb.group({});\n }\n\n ngOnInit(): void {\n // Initial setup\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n console.log('Permission dialog ngOnChanges called:', changes);\n \n if (changes['visible'] && this.visible) {\n this.resetDialog();\n // Load data when dialog becomes visible and we have data\n if (this.data) {\n console.log('Dialog became visible, loading permission data');\n this.loadPermissionData();\n }\n }\n \n if (changes['data'] && this.data && this.visible) {\n console.log('Data changed while dialog is visible, reloading permission data');\n this.loadPermissionData();\n }\n }\n\n ngOnDestroy(): void {\n // Cleanup if needed\n }\n\n private resetDialog(): void {\n this.error = null;\n this.isLoading = false;\n }\n\n @HostListener('document:keydown.escape', ['$event'])\n onEscapeKey(event: Event): void {\n if (this.visible) {\n this.onCancel();\n }\n }\n\n public get hasChanges(): boolean {\n return this.rolePermissions.some(rp => rp.isNew || rp.entityPermission.Dirty);\n }\n\n public hasEntityChanges(rolePermission: RolePermissions): boolean {\n return rolePermission.isNew || rolePermission.entityPermission.Dirty;\n }\n\n private loadPermissionData(): void {\n if (!this.data) return;\n\n console.log('Loading permission data for entity:', this.data.entity.Name);\n console.log('Existing permissions:', this.data.existingPermissions);\n console.log('Available roles:', this.data.roles);\n\n // Initialize role permissions from existing data\n this.rolePermissions = [];\n const existingRoleIds = new Set<string>();\n\n // Process existing permissions\n for (const permission of this.data.existingPermissions) {\n const role = this.data.roles.find(r => UUIDsEqual(r.ID, permission.RoleID));\n if (role) {\n console.log(`Processing permission for role ${role.Name}:`, {\n canCreate: permission.CanCreate,\n canRead: permission.CanRead,\n canUpdate: permission.CanUpdate,\n canDelete: permission.CanDelete\n });\n \n this.rolePermissions.push({\n roleId: role.ID,\n roleName: role.Name || '',\n entityPermission: permission,\n isNew: false\n });\n existingRoleIds.add(role.ID);\n }\n }\n\n console.log('Loaded role permissions:', this.rolePermissions);\n\n // Set available roles (those not already configured)\n this.availableRoles = this.data.roles.filter(role => !existingRoleIds.has(role.ID));\n \n console.log('Available roles for adding:', this.availableRoles.map(r => r.Name));\n \n // Trigger change detection to update the UI\n this.cdr.detectChanges();\n }\n\n public async addRolePermission(role: MJRoleEntity): Promise<void> {\n // Create new EntityPermission entity\n const entityPermission = await this.metadata.GetEntityObject<MJEntityPermissionEntity>('MJ: Entity Permissions');\n entityPermission.NewRecord();\n entityPermission.EntityID = this.data!.entity.ID;\n entityPermission.RoleID = role.ID;\n entityPermission.CanCreate = false;\n entityPermission.CanRead = true; // Default to read access\n entityPermission.CanUpdate = false;\n entityPermission.CanDelete = false;\n\n // Add new role permission\n this.rolePermissions.push({\n roleId: role.ID,\n roleName: role.Name || '',\n entityPermission: entityPermission,\n isNew: true\n });\n\n // Remove from available roles\n this.availableRoles = this.availableRoles.filter(r => !UUIDsEqual(r.ID, role.ID));\n this.cdr.detectChanges();\n }\n\n public removeRolePermission(rolePermission: RolePermissions): void {\n // Add back to available roles if not new\n if (!rolePermission.isNew) {\n const role = this.data?.roles.find(r => UUIDsEqual(r.ID, rolePermission.roleId));\n if (role) {\n this.availableRoles.push(role);\n this.availableRoles.sort((a, b) => (a.Name || '').localeCompare(b.Name || ''));\n }\n } else {\n // Add back to available roles\n const role = this.data?.roles.find(r => UUIDsEqual(r.ID, rolePermission.roleId));\n if (role) {\n this.availableRoles.push(role);\n this.availableRoles.sort((a, b) => (a.Name || '').localeCompare(b.Name || ''));\n }\n }\n\n // Remove from role permissions\n this.rolePermissions = this.rolePermissions.filter(rp => rp.roleId !== rolePermission.roleId);\n this.cdr.detectChanges();\n }\n\n public async onSubmit(): Promise<void> {\n if (!this.data || !this.hasChanges) return;\n\n this.isLoading = true;\n this.error = null;\n\n try {\n // Process each role permission\n for (const rolePermission of this.rolePermissions) {\n if (rolePermission.isNew || rolePermission.entityPermission.Dirty) {\n await this.saveRolePermission(rolePermission);\n }\n }\n\n this.result.emit({ action: 'save', entity: this.data.entity });\n\n } catch (error: unknown) {\n console.error('Error saving permissions:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'An unexpected error occurred while saving permissions';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n private async saveRolePermission(rolePermission: RolePermissions): Promise<void> {\n // Save the entity directly - it already has all the values bound\n const saveResult = await rolePermission.entityPermission.Save();\n if (!saveResult) {\n throw new Error(rolePermission.entityPermission.LatestResult?.Message || `Failed to save permissions for role ${rolePermission.roleName}`);\n }\n }\n\n public onCancel(): void {\n this.result.emit({ action: 'cancel' });\n }\n}","<!-- MD3 Modal Dialog -->\n@if (visible) {\n <div class=\"modal-backdrop\" (click)=\"onCancel()\">\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <!-- Modal Header -->\n <div class=\"modal-header\">\n <div class=\"dialog-header\">\n <h2 class=\"dialog-title\">\n <i class=\"fa-solid fa-key\"></i>\n Edit Entity Permissions\n </h2>\n <p class=\"dialog-subtitle\">\n Configure role-based permissions for {{ data?.entity?.Name }}\n </p>\n </div>\n <button type=\"button\" class=\"modal-close\" (click)=\"onCancel()\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Modal Body -->\n <div class=\"modal-body\">\n <form [formGroup]=\"permissionForm\" (ngSubmit)=\"onSubmit()\">\n @if (error) {\n <div class=\"content-section\">\n <mj-alert Variant=\"error\" [Message]=\"error\" />\n </div>\n }\n <!-- Entity Information Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-database\"></i>\n Entity Information\n </h3>\n <p class=\"section-description\">{{ data?.entity?.Description || 'Entity permissions configuration' }}</p>\n </div>\n <div class=\"entity-info-card\">\n <div class=\"entity-meta\">\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-table\"></i>\n <span class=\"meta-label\">Entity:</span>\n <span class=\"meta-value\">{{ data?.entity?.Name }}</span>\n </div>\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span class=\"meta-label\">Schema Name:</span>\n <span class=\"meta-value\">{{ data?.entity?.SchemaName || 'N/A' }}</span>\n </div>\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-key\"></i>\n <span class=\"meta-label\">Total Permissions:</span>\n <span class=\"meta-value\">{{ rolePermissions.length }}</span>\n </div>\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-clock\"></i>\n <span class=\"meta-label\">Last Updated:</span>\n <span class=\"meta-value\">{{ data?.entity?.__mj_UpdatedAt | date:'medium' }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Permissions Configuration Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-users-cog\"></i>\n Role Permissions\n </h3>\n <p class=\"section-description\">Configure CRUD permissions for each role</p>\n </div>\n <div class=\"permissions-table-container\">\n <table class=\"permissions-table\">\n <thead>\n <tr>\n <th class=\"role-column\">Role</th>\n <th class=\"permission-column\">\n <i class=\"fa-solid fa-plus\"></i>\n Create\n </th>\n <th class=\"permission-column\">\n <i class=\"fa-solid fa-eye\"></i>\n Read\n </th>\n <th class=\"permission-column\">\n <i class=\"fa-solid fa-edit\"></i>\n Update\n </th>\n <th class=\"permission-column\">\n <i class=\"fa-solid fa-trash\"></i>\n Delete\n </th>\n <th class=\"actions-column\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (rolePermission of rolePermissions; track rolePermission.roleId) {\n <tr class=\"permission-row\" [class.has-changes]=\"hasEntityChanges(rolePermission)\" [class.is-new]=\"rolePermission.isNew\">\n <td class=\"role-name\">\n <div class=\"role-info\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>{{ rolePermission.roleName }}</span>\n @if (rolePermission.isNew) {\n <span class=\"new-badge\">New</span>\n }\n @if (hasEntityChanges(rolePermission) && !rolePermission.isNew) {\n <span class=\"changed-badge\">Modified</span>\n }\n </div>\n </td>\n <td class=\"permission-cell\">\n <div class=\"permission-toggle\">\n <input\n type=\"checkbox\"\n [id]=\"'create-' + rolePermission.roleId\"\n [(ngModel)]=\"rolePermission.entityPermission.CanCreate\"\n [ngModelOptions]=\"{standalone: true}\"\n class=\"permission-checkbox\"\n />\n <label [for]=\"'create-' + rolePermission.roleId\" class=\"permission-label\">\n <div class=\"checkbox-indicator\"></div>\n </label>\n </div>\n </td>\n <td class=\"permission-cell\">\n <div class=\"permission-toggle\">\n <input\n type=\"checkbox\"\n [id]=\"'read-' + rolePermission.roleId\"\n [(ngModel)]=\"rolePermission.entityPermission.CanRead\"\n [ngModelOptions]=\"{standalone: true}\"\n class=\"permission-checkbox\"\n />\n <label [for]=\"'read-' + rolePermission.roleId\" class=\"permission-label\">\n <div class=\"checkbox-indicator\"></div>\n </label>\n </div>\n </td>\n <td class=\"permission-cell\">\n <div class=\"permission-toggle\">\n <input\n type=\"checkbox\"\n [id]=\"'update-' + rolePermission.roleId\"\n [(ngModel)]=\"rolePermission.entityPermission.CanUpdate\"\n [ngModelOptions]=\"{standalone: true}\"\n class=\"permission-checkbox\"\n />\n <label [for]=\"'update-' + rolePermission.roleId\" class=\"permission-label\">\n <div class=\"checkbox-indicator\"></div>\n </label>\n </div>\n </td>\n <td class=\"permission-cell\">\n <div class=\"permission-toggle\">\n <input\n type=\"checkbox\"\n [id]=\"'delete-' + rolePermission.roleId\"\n [(ngModel)]=\"rolePermission.entityPermission.CanDelete\"\n [ngModelOptions]=\"{standalone: true}\"\n class=\"permission-checkbox\"\n />\n <label [for]=\"'delete-' + rolePermission.roleId\" class=\"permission-label\">\n <div class=\"checkbox-indicator\"></div>\n </label>\n </div>\n </td>\n <td class=\"actions-cell\">\n <button\n type=\"button\"\n class=\"btn-icon btn-danger\"\n (click)=\"removeRolePermission(rolePermission)\"\n title=\"Remove permissions for this role\"\n attr.aria-label=\"Remove permissions for {{ rolePermission.roleName }}\"\n >\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (rolePermissions.length === 0) {\n <div class=\"empty-permissions\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <p>No role permissions configured</p>\n <p class=\"empty-subtext\">Add permissions for specific roles to control access to this entity</p>\n </div>\n }\n </div>\n <!-- Add Role Permissions -->\n <div class=\"add-role-section\">\n <div class=\"add-role-header\">\n <h4>Add Role Permissions</h4>\n <p>Select roles to configure permissions for this entity</p>\n </div>\n <div class=\"available-roles\">\n @for (role of availableRoles; track role.ID) {\n <button\n type=\"button\"\n class=\"role-chip\"\n (click)=\"addRolePermission(role)\"\n title=\"Add permissions for {{ role.Name }}\"\n attr.aria-label=\"Add permissions for {{ role.Name }}\"\n >\n <i class=\"fa-solid fa-plus\"></i>\n {{ role.Name }}\n </button>\n }\n @if (availableRoles.length === 0) {\n <p class=\"no-available-roles\">All roles have been configured</p>\n }\n </div>\n </div>\n </div>\n </div>\n <!-- Modal Footer -->\n <div class=\"modal-footer\">\n <div class=\"footer-info\">\n @if (hasChanges) {\n <span class=\"changes-indicator\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n You have unsaved changes\n </span>\n }\n </div>\n <div class=\"footer-actions\">\n <button\n type=\"submit\"\n class=\"btn btn-primary\"\n [disabled]=\"!hasChanges || isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Saving...\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n Save Permissions\n }\n </button>\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"onCancel()\">\n <i class=\"fa-solid fa-times\"></i>\n Cancel\n </button>\n </div>\n </div>\n </form>\n </div>\n </div>\n </div>\n}\n"]}
@@ -370,7 +370,7 @@ export class NotificationPreferencesComponent extends BaseAngularComponent {
370
370
  } if (rf & 2) {
371
371
  i0.ɵɵadvance();
372
372
  i0.ɵɵconditional(ctx.loading ? 1 : 2);
373
- } }, dependencies: [i2.CheckboxControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.LoadingComponent, i4.MJEmptyStateComponent, i4.MJAlertComponent], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n width: 100%;\n}\n\n\n\n\n\n.notification-preferences-container[_ngcontent-%COMP%] {\n padding: 1.5rem;\n max-width: 1200px;\n margin: 0 auto;\n background: var(--mj-bg-page);\n}\n\n\n\n\n\n.content[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n\n\n\n\n\n.notification-types-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n gap: 1.25rem;\n margin-bottom: 1.5rem;\n}\n\n\n\n\n\n.notification-type-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 12px;\n border-left: 4px solid var(--mj-border-strong);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.notification-type-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n border-color: var(--mj-brand-primary);\n}\n\n.notification-type-card.changed[_ngcontent-%COMP%] {\n border-left-color: var(--mj-brand-primary) !important;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.08);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n\n\n\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n gap: 1rem;\n padding: 1.25rem;\n border-bottom: 1px solid var(--mj-border-strong);\n align-items: flex-start;\n}\n\n.icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: transform 0.2s;\n}\n\n.notification-type-card[_ngcontent-%COMP%]:hover .icon-wrapper[_ngcontent-%COMP%] {\n transform: scale(1.05);\n}\n\n.icon-wrapper[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n}\n\n.header-text[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.header-text[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 0.375rem 0;\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.type-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n\n\n\n\n.card-body[_ngcontent-%COMP%] {\n padding: 1.25rem;\n}\n\n.preference-row[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n}\n\n.preference-row[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.delivery-label[_ngcontent-%COMP%] {\n display: block;\n font-weight: 600;\n margin-bottom: 0.75rem;\n font-size: 0.875rem;\n color: var(--mj-text-primary);\n letter-spacing: 0.01em;\n}\n\n\n\n\n\n.delivery-checkboxes[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 0.75rem 1rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n background: var(--mj-bg-page);\n min-height: 44px;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n margin: 0;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%]:disabled {\n cursor: not-allowed;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 1rem;\n transition: color 0.2s;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:hover:not(:has(input:disabled)) {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:hover:not(:has(input:disabled)) i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:has(input:checked) {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:has(input:checked) i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:has(input:disabled) {\n opacity: 0.5;\n cursor: not-allowed;\n background: var(--mj-bg-surface-sunken);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:focus-within {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n.info-message[_ngcontent-%COMP%] { margin-top: 0.75rem; }\n\n\n\n\n\n.metadata-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.625rem;\n align-items: center;\n font-size: 0.8125rem;\n color: var(--mj-text-muted);\n padding-top: 0.75rem;\n margin-top: 0.75rem;\n border-top: 1px solid var(--mj-border-strong);\n}\n\n.metadata-row[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.875rem;\n flex-shrink: 0;\n}\n\n.metadata-text[_ngcontent-%COMP%] {\n line-height: 1.4;\n}\n\n\n\n\n\n.actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.25rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n border: 1px solid var(--mj-border-strong);\n margin-top: 1.5rem;\n}\n\n\n\n\n\n.btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n border: none;\n border-radius: 9999px;\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.btn-primary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.btn-ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-text-muted);\n border: none;\n}\n\n.btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n}\n\n.btn-ghost[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.btn-danger[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-bg-surface);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.btn-danger[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-status-error);\n transform: scale(0.98);\n}\n\n.btn-sm[_ngcontent-%COMP%] {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n\n\n\n\n.badge-system[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: 9999px;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n border: 1px solid var(--mj-status-warning);\n}\n\n.badge-custom[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: 9999px;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border: 1px solid var(--mj-status-success);\n}\n\n\n\n\n\nbutton[_ngcontent-%COMP%]:focus-visible, \ninput[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n\n\n@media (max-width: 639px) {\n .notification-preferences-container[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 1rem;\n }\n\n .card-header[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .card-body[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .delivery-checkboxes[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .channel-checkbox[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .actions[_ngcontent-%COMP%] {\n flex-direction: column;\n padding: 1rem;\n }\n\n .actions[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}\n\n@media (min-width: 640px) and (max-width: 767px) {\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n@media (min-width: 768px) {\n .notification-preferences-container[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));\n }\n}\n\n@media (min-width: 1024px) {\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(450px, 1fr));\n gap: 1.5rem;\n }\n}"] });
373
+ } }, dependencies: [i2.CheckboxControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.LoadingComponent, i4.MJEmptyStateComponent, i4.MJAlertComponent], styles: ["\n\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n width: 100%;\n}\n\n\n\n\n.notification-preferences-container[_ngcontent-%COMP%] {\n padding: 1.5rem;\n max-width: 1200px;\n margin: 0 auto;\n background: var(--mj-bg-page);\n}\n\n\n\n\n.content[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n\n\n\n\n.notification-types-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n gap: 1.25rem;\n margin-bottom: 1.5rem;\n}\n\n\n\n\n.notification-type-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 12px;\n border-left: 4px solid var(--mj-border-strong);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.notification-type-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n border-color: var(--mj-brand-primary);\n}\n\n.notification-type-card.changed[_ngcontent-%COMP%] {\n border-left-color: var(--mj-brand-primary) !important;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.08);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n\n\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n gap: 1rem;\n padding: 1.25rem;\n border-bottom: 1px solid var(--mj-border-strong);\n align-items: flex-start;\n}\n\n.icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: transform 0.2s;\n}\n\n.notification-type-card[_ngcontent-%COMP%]:hover .icon-wrapper[_ngcontent-%COMP%] {\n transform: scale(1.05);\n}\n\n.icon-wrapper[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n}\n\n.header-text[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.header-text[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 0.375rem 0;\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.type-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n\n\n\n.card-body[_ngcontent-%COMP%] {\n padding: 1.25rem;\n}\n\n.preference-row[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n}\n\n.preference-row[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.delivery-label[_ngcontent-%COMP%] {\n display: block;\n font-weight: 600;\n margin-bottom: 0.75rem;\n font-size: 0.875rem;\n color: var(--mj-text-primary);\n letter-spacing: 0.01em;\n}\n\n\n\n\n.delivery-checkboxes[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 0.75rem 1rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n background: var(--mj-bg-page);\n min-height: 44px;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n margin: 0;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%]:disabled {\n cursor: not-allowed;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 1rem;\n transition: color 0.2s;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:hover:not(:has(input:disabled)) {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:hover:not(:has(input:disabled)) i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:has(input:checked) {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:has(input:checked) i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:has(input:disabled) {\n opacity: 0.5;\n cursor: not-allowed;\n background: var(--mj-bg-surface-sunken);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:focus-within {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n\n\n\n.info-message[_ngcontent-%COMP%] { margin-top: 0.75rem; }\n\n\n\n\n.metadata-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.625rem;\n align-items: center;\n font-size: 0.8125rem;\n color: var(--mj-text-muted);\n padding-top: 0.75rem;\n margin-top: 0.75rem;\n border-top: 1px solid var(--mj-border-strong);\n}\n\n.metadata-row[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.875rem;\n flex-shrink: 0;\n}\n\n.metadata-text[_ngcontent-%COMP%] {\n line-height: 1.4;\n}\n\n\n\n\n.actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.25rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n border: 1px solid var(--mj-border-strong);\n margin-top: 1.5rem;\n}\n\n\n\n\n.btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n border: none;\n border-radius: 9999px;\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.btn-primary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.btn-ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-text-muted);\n border: none;\n}\n\n.btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n}\n\n.btn-ghost[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.btn-danger[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-bg-surface);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.btn-danger[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-status-error);\n transform: scale(0.98);\n}\n\n.btn-sm[_ngcontent-%COMP%] {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n\n\n\n.badge-system[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: 9999px;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n border: 1px solid var(--mj-status-warning);\n}\n\n.badge-custom[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: 9999px;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border: 1px solid var(--mj-status-success);\n}\n\n\n\n\nbutton[_ngcontent-%COMP%]:focus-visible, \ninput[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n\n\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n\n@media (max-width: 639px) {\n .notification-preferences-container[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 1rem;\n }\n\n .card-header[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .card-body[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .delivery-checkboxes[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .channel-checkbox[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .actions[_ngcontent-%COMP%] {\n flex-direction: column;\n padding: 1rem;\n }\n\n .actions[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}\n\n@media (min-width: 640px) and (max-width: 767px) {\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n@media (min-width: 768px) {\n .notification-preferences-container[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));\n }\n}\n\n@media (min-width: 1024px) {\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(450px, 1fr));\n gap: 1.5rem;\n }\n}"] });
374
374
  }
375
375
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NotificationPreferencesComponent, [{
376
376
  type: Component,
@@ -82,7 +82,7 @@ function RoleDialogComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
82
82
  i0.ɵɵelementStart(0, "div", 1);
83
83
  i0.ɵɵlistener("click", function RoleDialogComponent_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onCancel()); });
84
84
  i0.ɵɵelementStart(1, "div", 2);
85
- i0.ɵɵlistener("click", function RoleDialogComponent_Conditional_0_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView($event.stopPropagation()); });
85
+ i0.ɵɵlistener("click", function RoleDialogComponent_Conditional_0_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
86
86
  i0.ɵɵelementStart(2, "div", 3)(3, "div", 4)(4, "h2", 5);
87
87
  i0.ɵɵelement(5, "i", 6);
88
88
  i0.ɵɵtext(6);
@@ -1 +1 @@
1
- {"version":3,"file":"role-dialog.component.js","sourceRoot":"","sources":["../../../../src/lib/role-management/role-dialog/role-dialog.component.ts","../../../../src/lib/role-management/role-dialog/role-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, OnChanges, SimpleChanges, inject, HostListener, ViewEncapsulation, ChangeDetectorRef, NgZone } from '@angular/core';\n\nimport { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';\nimport { Metadata } from '@memberjunction/core';\nimport { MJRoleEntity } from '@memberjunction/core-entities';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nexport interface RoleDialogData {\n role?: MJRoleEntity;\n mode: 'create' | 'edit';\n}\n\nexport interface RoleDialogResult {\n action: 'save' | 'cancel';\n role?: MJRoleEntity;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-role-dialog',\n encapsulation: ViewEncapsulation.None,\n templateUrl: './role-dialog.component.html',\n styleUrls: ['./role-dialog.component.css']\n})\nexport class RoleDialogComponent extends BaseAngularComponent implements OnInit, OnDestroy, OnChanges {\n @Input() data: RoleDialogData | null = null;\n @Input() visible = false;\n @Output() result = new EventEmitter<RoleDialogResult>();\n\n private fb = inject(FormBuilder);\n private cdr = inject(ChangeDetectorRef);\n private ngZone = inject(NgZone);\n private get metadata() { return this.ProviderToUse; }\n public roleForm: FormGroup;\n public isLoading = false;\n public error: string | null = null;\n\n constructor() {\n super();\n this.roleForm = this.fb.group({\n name: ['', [Validators.required, Validators.maxLength(50)]],\n description: [''],\n directoryId: ['']\n });\n }\n\n ngOnInit(): void {\n // Initial setup\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['data'] && this.data?.role && this.isEditMode) {\n this.loadRoleData();\n }\n \n // Reset form if switching to create mode or dialog becomes visible\n if (changes['visible'] && this.visible && !this.isEditMode) {\n this.resetForm();\n }\n }\n\n ngOnDestroy(): void {\n // Cleanup if needed\n }\n\n private resetForm(): void {\n this.roleForm.reset({\n name: '',\n description: '',\n directoryId: ''\n });\n this.error = null;\n }\n\n @HostListener('document:keydown.escape', ['$event'])\n onEscapeKey(event: Event): void {\n if (this.visible) {\n this.onCancel();\n }\n }\n\n public get windowTitle(): string {\n return this.isEditMode ? 'Edit Role' : 'Create New Role';\n }\n\n public get isEditMode(): boolean {\n return this.data?.mode === 'edit';\n }\n\n public get isSystemRole(): boolean {\n if (!this.data?.role) return false;\n const systemRoleNames = ['Administrator', 'User', 'Guest', 'Developer'];\n return systemRoleNames.includes(this.data.role.Name || '');\n }\n\n private loadRoleData(): void {\n if (!this.data?.role) return;\n\n const role = this.data.role;\n this.roleForm.patchValue({\n name: role.Name,\n description: role.Description,\n directoryId: role.DirectoryID\n });\n\n // Disable name editing for system roles\n if (this.isSystemRole) {\n this.roleForm.get('name')?.disable();\n }\n }\n\n public async onSubmit(): Promise<void> {\n if (this.roleForm.invalid) {\n this.markFormGroupTouched(this.roleForm);\n return;\n }\n\n this.isLoading = true;\n this.error = null;\n\n try {\n let role: MJRoleEntity;\n\n if (this.isEditMode && this.data?.role) {\n // Edit existing role\n role = this.data.role;\n } else {\n // Create new role\n role = await this.metadata.GetEntityObject<MJRoleEntity>('MJ: Roles');\n role.NewRecord();\n }\n\n // Update role properties\n const formValue = this.roleForm.value;\n \n // Only update name if not a system role\n if (!this.isSystemRole) {\n role.Name = formValue.name;\n }\n \n role.Description = formValue.description;\n role.DirectoryID = formValue.directoryId || null;\n\n // Save role\n const saveResult = await role.Save();\n if (!saveResult) {\n throw new Error(role.LatestResult?.Message || 'Failed to save role');\n }\n\n this.result.emit({ action: 'save', role });\n\n } catch (error: unknown) {\n console.error('Error saving role:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'An unexpected error occurred';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n public onCancel(): void {\n this.result.emit({ action: 'cancel' });\n }\n\n private markFormGroupTouched(formGroup: FormGroup): void {\n Object.keys(formGroup.controls).forEach(key => {\n const control = formGroup.get(key);\n control?.markAsTouched();\n });\n }\n}","<!-- MD3 Modal Dialog -->\n@if (visible) {\n <div class=\"modal-backdrop\" (click)=\"onCancel()\">\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <!-- Modal Header with MJ Blue -->\n <div class=\"modal-header\">\n <div class=\"dialog-header\">\n <h2 class=\"dialog-title\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n {{ isEditMode ? 'Edit Role' : 'Create New Role' }}\n </h2>\n <p class=\"dialog-subtitle\">\n {{ isEditMode ? 'Update role information and permissions' : 'Add a new role to the system' }}\n </p>\n </div>\n <button type=\"button\" class=\"modal-close\" (click)=\"onCancel()\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Modal Body -->\n <div class=\"modal-body\">\n <form [formGroup]=\"roleForm\" (ngSubmit)=\"onSubmit()\">\n @if (error) {\n <div class=\"content-section\">\n <mj-alert Variant=\"error\" [Message]=\"error\" />\n </div>\n }\n <!-- Basic Information Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n Role Information\n </h3>\n <p class=\"section-description\">Define the role's basic properties and purpose</p>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-field\">\n <label class=\"field-label required\" for=\"name\">Role Name</label>\n <input\n id=\"name\"\n type=\"text\"\n class=\"field-input\"\n formControlName=\"name\"\n placeholder=\"Sales Manager\"\n [class.error]=\"roleForm.get('name')?.invalid && roleForm.get('name')?.touched\"\n />\n @if (roleForm.get('name')?.invalid && roleForm.get('name')?.touched) {\n <div class=\"field-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n @if (roleForm.get('name')?.errors?.['required']) {\n Role name is required\n }\n @if (roleForm.get('name')?.errors?.['maxlength']) {\n Role name cannot exceed 50 characters\n }\n </div>\n }\n </div>\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"description\">Description</label>\n <textarea\n id=\"description\"\n class=\"field-textarea\"\n formControlName=\"description\"\n placeholder=\"Describe the role's purpose and responsibilities...\"\n rows=\"4\"\n ></textarea>\n <div class=\"field-hint\">\n Provide a clear description of what this role is for and what permissions it should have.\n </div>\n </div>\n @if (isEditMode) {\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"directoryId\">Directory ID</label>\n <input\n id=\"directoryId\"\n type=\"text\"\n class=\"field-input\"\n formControlName=\"directoryId\"\n placeholder=\"External directory identifier\"\n />\n <div class=\"field-hint\">\n External directory identifier for syncing with Active Directory or other systems.\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Role Type Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-cog\"></i>\n Role Type\n </h3>\n <p class=\"section-description\">System or custom role classification</p>\n </div>\n <div class=\"form-grid\">\n @if (isSystemRole) {\n <mj-alert Variant=\"warning\" Title=\"System Role\" Message=\"This is a system-defined role. Some properties may be limited for editing to maintain system integrity.\" />\n } @else {\n <mj-alert Variant=\"info\" Title=\"Custom Role\" Message=\"This is a custom role that can be fully configured and modified.\" />\n }\n </div>\n </div>\n </div>\n <!-- Permissions Preview Section -->\n @if (isEditMode) {\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-key\"></i>\n Permissions\n </h3>\n <p class=\"section-description\">Manage role permissions and access rights</p>\n </div>\n <div class=\"form-grid\">\n <mj-alert Variant=\"info\" Title=\"Permission Management\">\n Role permissions can be managed in the <strong>Permissions</strong> tab of the settings dashboard. Use that interface to configure specific access rights for this role.\n </mj-alert>\n </div>\n </div>\n </div>\n }\n <!-- Modal Footer -->\n <div class=\"modal-footer\">\n <button\n type=\"submit\"\n class=\"btn btn-primary\"\n [disabled]=\"roleForm.invalid || isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Saving...\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n {{ isEditMode ? 'Update Role' : 'Create Role' }}\n }\n </button>\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"onCancel()\">\n <i class=\"fa-solid fa-times\"></i>\n Cancel\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n}\n"]}
1
+ {"version":3,"file":"role-dialog.component.js","sourceRoot":"","sources":["../../../../src/lib/role-management/role-dialog/role-dialog.component.ts","../../../../src/lib/role-management/role-dialog/role-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, OnChanges, SimpleChanges, inject, HostListener, ViewEncapsulation, ChangeDetectorRef, NgZone } from '@angular/core';\n\nimport { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';\nimport { Metadata } from '@memberjunction/core';\nimport { MJRoleEntity } from '@memberjunction/core-entities';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nexport interface RoleDialogData {\n role?: MJRoleEntity;\n mode: 'create' | 'edit';\n}\n\nexport interface RoleDialogResult {\n action: 'save' | 'cancel';\n role?: MJRoleEntity;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-role-dialog',\n encapsulation: ViewEncapsulation.None,\n templateUrl: './role-dialog.component.html',\n styleUrls: ['./role-dialog.component.css']\n})\nexport class RoleDialogComponent extends BaseAngularComponent implements OnInit, OnDestroy, OnChanges {\n @Input() data: RoleDialogData | null = null;\n @Input() visible = false;\n @Output() result = new EventEmitter<RoleDialogResult>();\n\n private fb = inject(FormBuilder);\n private cdr = inject(ChangeDetectorRef);\n private ngZone = inject(NgZone);\n private get metadata() { return this.ProviderToUse; }\n public roleForm: FormGroup;\n public isLoading = false;\n public error: string | null = null;\n\n constructor() {\n super();\n this.roleForm = this.fb.group({\n name: ['', [Validators.required, Validators.maxLength(50)]],\n description: [''],\n directoryId: ['']\n });\n }\n\n ngOnInit(): void {\n // Initial setup\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['data'] && this.data?.role && this.isEditMode) {\n this.loadRoleData();\n }\n \n // Reset form if switching to create mode or dialog becomes visible\n if (changes['visible'] && this.visible && !this.isEditMode) {\n this.resetForm();\n }\n }\n\n ngOnDestroy(): void {\n // Cleanup if needed\n }\n\n private resetForm(): void {\n this.roleForm.reset({\n name: '',\n description: '',\n directoryId: ''\n });\n this.error = null;\n }\n\n @HostListener('document:keydown.escape', ['$event'])\n onEscapeKey(event: Event): void {\n if (this.visible) {\n this.onCancel();\n }\n }\n\n public get windowTitle(): string {\n return this.isEditMode ? 'Edit Role' : 'Create New Role';\n }\n\n public get isEditMode(): boolean {\n return this.data?.mode === 'edit';\n }\n\n public get isSystemRole(): boolean {\n if (!this.data?.role) return false;\n const systemRoleNames = ['Administrator', 'User', 'Guest', 'Developer'];\n return systemRoleNames.includes(this.data.role.Name || '');\n }\n\n private loadRoleData(): void {\n if (!this.data?.role) return;\n\n const role = this.data.role;\n this.roleForm.patchValue({\n name: role.Name,\n description: role.Description,\n directoryId: role.DirectoryID\n });\n\n // Disable name editing for system roles\n if (this.isSystemRole) {\n this.roleForm.get('name')?.disable();\n }\n }\n\n public async onSubmit(): Promise<void> {\n if (this.roleForm.invalid) {\n this.markFormGroupTouched(this.roleForm);\n return;\n }\n\n this.isLoading = true;\n this.error = null;\n\n try {\n let role: MJRoleEntity;\n\n if (this.isEditMode && this.data?.role) {\n // Edit existing role\n role = this.data.role;\n } else {\n // Create new role\n role = await this.metadata.GetEntityObject<MJRoleEntity>('MJ: Roles');\n role.NewRecord();\n }\n\n // Update role properties\n const formValue = this.roleForm.value;\n \n // Only update name if not a system role\n if (!this.isSystemRole) {\n role.Name = formValue.name;\n }\n \n role.Description = formValue.description;\n role.DirectoryID = formValue.directoryId || null;\n\n // Save role\n const saveResult = await role.Save();\n if (!saveResult) {\n throw new Error(role.LatestResult?.Message || 'Failed to save role');\n }\n\n this.result.emit({ action: 'save', role });\n\n } catch (error: unknown) {\n console.error('Error saving role:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'An unexpected error occurred';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n public onCancel(): void {\n this.result.emit({ action: 'cancel' });\n }\n\n private markFormGroupTouched(formGroup: FormGroup): void {\n Object.keys(formGroup.controls).forEach(key => {\n const control = formGroup.get(key);\n control?.markAsTouched();\n });\n }\n}","<!-- MD3 Modal Dialog -->\n@if (visible) {\n <div class=\"modal-backdrop\" (click)=\"onCancel()\">\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <!-- Modal Header with MJ Blue -->\n <div class=\"modal-header\">\n <div class=\"dialog-header\">\n <h2 class=\"dialog-title\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n {{ isEditMode ? 'Edit Role' : 'Create New Role' }}\n </h2>\n <p class=\"dialog-subtitle\">\n {{ isEditMode ? 'Update role information and permissions' : 'Add a new role to the system' }}\n </p>\n </div>\n <button type=\"button\" class=\"modal-close\" (click)=\"onCancel()\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Modal Body -->\n <div class=\"modal-body\">\n <form [formGroup]=\"roleForm\" (ngSubmit)=\"onSubmit()\">\n @if (error) {\n <div class=\"content-section\">\n <mj-alert Variant=\"error\" [Message]=\"error\" />\n </div>\n }\n <!-- Basic Information Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n Role Information\n </h3>\n <p class=\"section-description\">Define the role's basic properties and purpose</p>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-field\">\n <label class=\"field-label required\" for=\"name\">Role Name</label>\n <input\n id=\"name\"\n type=\"text\"\n class=\"field-input\"\n formControlName=\"name\"\n placeholder=\"Sales Manager\"\n [class.error]=\"roleForm.get('name')?.invalid && roleForm.get('name')?.touched\"\n />\n @if (roleForm.get('name')?.invalid && roleForm.get('name')?.touched) {\n <div class=\"field-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n @if (roleForm.get('name')?.errors?.['required']) {\n Role name is required\n }\n @if (roleForm.get('name')?.errors?.['maxlength']) {\n Role name cannot exceed 50 characters\n }\n </div>\n }\n </div>\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"description\">Description</label>\n <textarea\n id=\"description\"\n class=\"field-textarea\"\n formControlName=\"description\"\n placeholder=\"Describe the role's purpose and responsibilities...\"\n rows=\"4\"\n ></textarea>\n <div class=\"field-hint\">\n Provide a clear description of what this role is for and what permissions it should have.\n </div>\n </div>\n @if (isEditMode) {\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"directoryId\">Directory ID</label>\n <input\n id=\"directoryId\"\n type=\"text\"\n class=\"field-input\"\n formControlName=\"directoryId\"\n placeholder=\"External directory identifier\"\n />\n <div class=\"field-hint\">\n External directory identifier for syncing with Active Directory or other systems.\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Role Type Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-cog\"></i>\n Role Type\n </h3>\n <p class=\"section-description\">System or custom role classification</p>\n </div>\n <div class=\"form-grid\">\n @if (isSystemRole) {\n <mj-alert Variant=\"warning\" Title=\"System Role\" Message=\"This is a system-defined role. Some properties may be limited for editing to maintain system integrity.\" />\n } @else {\n <mj-alert Variant=\"info\" Title=\"Custom Role\" Message=\"This is a custom role that can be fully configured and modified.\" />\n }\n </div>\n </div>\n </div>\n <!-- Permissions Preview Section -->\n @if (isEditMode) {\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-key\"></i>\n Permissions\n </h3>\n <p class=\"section-description\">Manage role permissions and access rights</p>\n </div>\n <div class=\"form-grid\">\n <mj-alert Variant=\"info\" Title=\"Permission Management\">\n Role permissions can be managed in the <strong>Permissions</strong> tab of the settings dashboard. Use that interface to configure specific access rights for this role.\n </mj-alert>\n </div>\n </div>\n </div>\n }\n <!-- Modal Footer -->\n <div class=\"modal-footer\">\n <button\n type=\"submit\"\n class=\"btn btn-primary\"\n [disabled]=\"roleForm.invalid || isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Saving...\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n {{ isEditMode ? 'Update Role' : 'Create Role' }}\n }\n </button>\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"onCancel()\">\n <i class=\"fa-solid fa-times\"></i>\n Cancel\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n}\n"]}