@memberjunction/ng-explorer-settings 3.0.0 → 3.1.0

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.
@@ -578,5 +578,5 @@ export class ApplicationDialogComponent {
578
578
  type: HostListener,
579
579
  args: ['document:keydown.escape', ['$event']]
580
580
  }] }); })();
581
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ApplicationDialogComponent, { className: "ApplicationDialogComponent" }); })();
581
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ApplicationDialogComponent, { className: "ApplicationDialogComponent", filePath: "src/lib/application-management/application-dialog/application-dialog.component.ts", lineNumber: 33 }); })();
582
582
  //# sourceMappingURL=application-dialog.component.js.map
@@ -590,5 +590,5 @@ export { ApplicationManagementComponent };
590
590
  type: Component,
591
591
  args: [{ selector: 'mj-application-management', template: "<div class=\"application-management-container\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"refreshData()\" [disabled]=\"isLoading\">\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"isLoading\"></i>\n Refresh\n </button>\n <button class=\"mj-btn mj-btn-primary\" (click)=\"createNewApplication()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add Application\n </button>\n </div>\n\n <!-- Stats Cards -->\n <div class=\"mj-grid mj-grid-4\">\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-total\">\n <i class=\"fa-solid fa-grid-2\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.totalApplications }}</div>\n <div class=\"stat-label\">Total Applications</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-active\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.activeApplications }}</div>\n <div class=\"stat-label\">Active Applications</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-entities\">\n <i class=\"fa-solid fa-database\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.totalEntities }}</div>\n <div class=\"stat-label\">Total Entities</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-public\">\n <i class=\"fa-solid fa-globe\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.publicEntities }}</div>\n <div class=\"stat-label\">Public Entities</div>\n </div>\n </div>\n </div>\n\n <!-- Filters Section -->\n <div class=\"filters-section\">\n <div class=\"filters-row\">\n <!-- Search -->\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\"></i>\n <input \n type=\"text\" \n class=\"mj-search-input\" \n placeholder=\"Search applications by name or description...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.search\"\n />\n </div>\n \n <!-- Status Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\">Status</label>\n <div class=\"mj-filter-buttons\">\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'all'\"\n (click)=\"onStatusFilterChange('all')\"\n >\n All\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'active'\"\n (click)=\"onStatusFilterChange('active')\"\n >\n Active\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'inactive'\"\n (click)=\"onStatusFilterChange('inactive')\"\n >\n Inactive\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">Loading applications...</div>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button class=\"mj-btn mj-btn-primary\" (click)=\"loadInitialData()\">\n <i class=\"fa-solid fa-refresh\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Content Area -->\n @if (!isLoading && !error) {\n <div class=\"content-area\">\n <div class=\"applications-list\">\n @for (app of filteredApplications; track app.ID) {\n <div class=\"app-card\" [class.expanded]=\"isAppExpanded(app.ID)\">\n <div class=\"app-header\" (click)=\"toggleAppExpansion(app.ID)\">\n <div class=\"app-info\">\n <div class=\"app-icon-wrapper\">\n <i [class]=\"'fa-solid ' + getAppIcon(app)\"></i>\n </div>\n <div class=\"app-details\">\n <h3 class=\"app-name\">{{ app.Name }}</h3>\n <p class=\"app-description\">{{ app.Description || 'No description available' }}</p>\n </div>\n </div>\n \n <div class=\"app-meta\">\n <span class=\"status-badge\" [class]=\"getAppStatusClass(app)\">\n {{ getAppStatusLabel(app) }}\n </span>\n <div class=\"app-actions\" (click)=\"$event.stopPropagation()\">\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm\" (click)=\"editApplication(app)\" title=\"Edit\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm mj-btn-danger\" (click)=\"confirmDeleteApplication(app)\" title=\"Delete\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n <button class=\"expand-btn\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n </div>\n </div>\n \n @if (isAppExpanded(app.ID)) {\n <div class=\"app-content\">\n <div class=\"app-stats\">\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-database\"></i>\n <span class=\"stat-label\">Entities:</span>\n <span class=\"stat-value\">{{ getAppEntities(app.ID).length }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n <span class=\"stat-label\">Created:</span>\n <span class=\"stat-value\">{{ app.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-clock\"></i>\n <span class=\"stat-label\">Updated:</span>\n <span class=\"stat-value\">{{ app.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n </div>\n \n <div class=\"entities-section\">\n <h4 class=\"section-title\">\n <i class=\"fa-solid fa-database\"></i>\n Application Entities\n </h4>\n \n @if (getAppEntities(app.ID).length > 0) {\n <div class=\"entities-grid\">\n @for (appEntity of getAppEntities(app.ID); track appEntity.ID) {\n @if (getEntityInfo(appEntity.EntityID); as entity) {\n <div class=\"entity-item\">\n <div class=\"entity-name\">{{ entity.Name }}</div>\n <div class=\"entity-meta\">\n @if (appEntity.DefaultForNewUser) {\n <span class=\"entity-badge public\">Public</span>\n }\n <span class=\"entity-sequence\">Order: {{ appEntity.Sequence }}</span>\n </div>\n </div>\n }\n }\n </div>\n } @else {\n <p class=\"no-entities\">No entities configured for this application</p>\n }\n </div>\n </div>\n }\n </div>\n }\n \n @if (filteredApplications.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-grid-2 empty-icon\"></i>\n <p class=\"empty-text\">No applications found</p>\n <p class=\"empty-subtext\">Try adjusting your filters or create a new application</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Application Dialog -->\n <mj-application-dialog\n [visible]=\"showApplicationDialog\"\n [data]=\"applicationDialogData\"\n (result)=\"onApplicationDialogResult($event)\"\n ></mj-application-dialog>\n\n <!-- Delete Confirmation Dialog -->\n @if (showDeleteConfirm && selectedApp) {\n <div class=\"modal-backdrop\" (click)=\"showDeleteConfirm = false\">\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\">\n <i class=\"fa-solid fa-exclamation-triangle text-danger\"></i>\n Confirm Delete\n </h3>\n <button class=\"modal-close\" (click)=\"showDeleteConfirm = false\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Are you sure you want to delete the application <strong>{{ selectedApp.Name }}</strong>?</p>\n <p class=\"text-warning\">\n <i class=\"fa-solid fa-warning\"></i>\n This will remove all entity associations for this application.\n </p>\n </div>\n <div class=\"modal-footer\">\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"showDeleteConfirm = false\">\n <i class=\"fa-solid fa-times\"></i>\n Cancel\n </button>\n <button class=\"mj-btn mj-btn-danger\" (click)=\"deleteApplication()\" [disabled]=\"isLoading\">\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Deleting...\n } @else {\n <i class=\"fa-solid fa-trash\"></i>\n Delete Application\n }\n </button>\n </div>\n </div>\n </div>\n }\n</div>", styles: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.application-management-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n max-width: 1200px;\n margin: 0 auto;\n padding: 2rem;\n}\n\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n margin-bottom: 1.5rem;\n}\n@media (max-width: 768px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n.btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-primary i {\n font-size: 0.875rem;\n}\n.btn-primary:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n\n.btn-secondary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n}\n.btn-secondary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-secondary i {\n font-size: 0.875rem;\n}\n.btn-secondary:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n}\n\n.btn-danger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #f44336;\n color: white;\n}\n.btn-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-danger i {\n font-size: 0.875rem;\n}\n.btn-danger:hover {\n background-color: #d32f2f;\n}\n\n.stats-grid {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n margin-bottom: 2rem;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n margin-right: 10px;\n align-items: center;\n gap: 1rem;\n transition: all 0.3s ease;\n min-width: 0;\n}\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.stat-icon {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n}\n.stat-icon-total {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.stat-icon-active {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n.stat-icon-entities {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n.stat-icon-public {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n}\n\n.stat-content {\n flex: 1;\n}\n.stat-content .stat-value {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n}\n.stat-content .stat-label {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n.filters-section {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n margin-bottom: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filters-row {\n display: flex;\n gap: 1.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n.search-container {\n flex: 1;\n min-width: 250px;\n position: relative;\n}\n.search-container .search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n}\n.search-container .search-input {\n width: 100%;\n padding: 0.75rem 1rem 0.75rem 2.75rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n}\n.search-container .search-input:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n.filter-group .filter-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: #374151;\n}\n.filter-group .filter-buttons {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n.filter-group .filter-btn {\n padding: 0.5rem 1rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group .filter-btn:hover {\n color: #374151;\n}\n.filter-group .filter-btn.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.content-area {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n padding: 1.5rem;\n}\n\n.applications-list {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n max-height: calc(100vh - 450px);\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n\n.app-card {\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.3s ease;\n}\n.app-card:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n}\n.app-card.expanded {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n.app-card.expanded .expand-btn i {\n transform: rotate(180deg);\n}\n\n.app-header {\n padding: 1.5rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n background: #f9fafb;\n transition: background-color 0.2s;\n}\n.app-header:hover {\n background: #f3f4f6;\n}\n\n.app-info {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex: 1;\n}\n\n.app-icon-wrapper {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n background: rgba(33, 150, 243, 0.1);\n display: flex;\n align-items: center;\n justify-content: center;\n color: #2196f3;\n font-size: 1.25rem;\n}\n\n.app-details {\n flex: 1;\n}\n.app-details .app-name {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n}\n.app-details .app-description {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0;\n}\n\n.app-meta {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.status-badge {\n padding: 0.375rem 0.75rem;\n border-radius: 20px;\n font-size: 0.75rem;\n font-weight: 600;\n}\n.status-badge.status-active {\n background: rgba(76, 175, 80, 0.1);\n color: #388e3c;\n}\n.status-badge.status-inactive {\n background: rgba(244, 67, 54, 0.1);\n color: #d32f2f;\n}\n\n.app-actions {\n display: flex;\n gap: 0.5rem;\n}\n\n.action-btn {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.action-btn:hover {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.action-btn-danger:hover {\n color: #f44336;\n}\n\n.expand-btn {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s;\n}\n.expand-btn i {\n transition: transform 0.3s ease;\n}\n\n.app-content {\n padding: 1.5rem;\n background: white;\n border-top: 1px solid #e5e7eb;\n animation: slideDown 0.3s ease-out;\n}\n\n.app-stats {\n display: flex;\n gap: 2rem;\n margin-bottom: 1.5rem;\n flex-wrap: wrap;\n}\n.app-stats .stat-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n}\n.app-stats .stat-item i {\n color: #6b7280;\n}\n.app-stats .stat-item .stat-label {\n color: #6b7280;\n}\n.app-stats .stat-item .stat-value {\n color: #1f2937;\n font-weight: 500;\n}\n\n.entities-section {\n padding: 1rem;\n background: #f9fafb;\n border-radius: 8px;\n}\n.entities-section .section-title {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 1rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 1rem 0;\n}\n.entities-section .section-title i {\n color: #2196f3;\n}\n\n.entities-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: 0.75rem;\n}\n\n.entity-item {\n padding: 0.75rem;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n transition: all 0.2s;\n}\n.entity-item:hover {\n border-color: #2196f3;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\n}\n.entity-item .entity-name {\n font-size: 0.875rem;\n font-weight: 500;\n color: #1f2937;\n margin-bottom: 0.25rem;\n}\n.entity-item .entity-meta {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.75rem;\n color: #6b7280;\n}\n\n.entity-badge {\n padding: 0.125rem 0.5rem;\n border-radius: 12px;\n font-size: 0.625rem;\n font-weight: 600;\n}\n.entity-badge.public {\n background: rgba(255, 152, 0, 0.1);\n color: #f57c00;\n}\n\n.entity-sequence {\n font-size: 0.75rem;\n color: #9ca3af;\n}\n\n.no-entities {\n color: #6b7280;\n font-size: 0.875rem;\n text-align: center;\n padding: 1rem;\n margin: 0;\n}\n\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n.empty-state .empty-icon {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n}\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n}\n.empty-state .empty-subtext {\n color: #6b7280;\n margin: 0;\n}\n\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n.loading-spinner {\n position: relative;\n width: 60px;\n height: 60px;\n margin-bottom: 1rem;\n}\n.loading-spinner .spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n}\n.loading-spinner .spinner-ring:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner .spinner-ring:nth-child(2) {\n border-color: transparent #9c27b0 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner .spinner-ring:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n.error-container .error-icon {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n}\n.error-container .error-message {\n color: #374151;\n margin-bottom: 1.5rem;\n}\n.error-container .retry-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.error-container .retry-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.error-container .retry-button i {\n font-size: 0.875rem;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n.modal-dialog {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s ease;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid #e5e7eb;\n}\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0;\n}\n.modal-header .modal-close {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.modal-header .modal-close:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n.modal-body {\n padding: 1.5rem;\n}\n.modal-body p {\n margin: 0 0 1rem 0;\n color: #374151;\n}\n.modal-body p:last-child {\n margin-bottom: 0;\n}\n.modal-body .text-warning {\n color: #f57c00;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 800px;\n }\n}\n.text-danger {\n color: #f44336;\n}\n"] }]
592
592
  }], () => [], null); })();
593
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ApplicationManagementComponent, { className: "ApplicationManagementComponent" }); })();
593
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ApplicationManagementComponent, { className: "ApplicationManagementComponent", filePath: "src/lib/application-management/application-management.component.ts", lineNumber: 28 }); })();
594
594
  //# sourceMappingURL=application-management.component.js.map
@@ -650,5 +650,5 @@ export { EntityPermissionsComponent };
650
650
  type: Component,
651
651
  args: [{ selector: 'mj-entity-permissions', template: "<div class=\"entity-permissions-container\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <div class=\"mj-view-toggle\">\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"viewMode === 'list'\"\n (click)=\"setViewMode('list')\"\n title=\"List View\"\n >\n <i class=\"fa-solid fa-list\"></i>\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"viewMode === 'grid'\"\n (click)=\"setViewMode('grid')\"\n title=\"Grid View\"\n >\n <i class=\"fa-solid fa-th\"></i>\n </button>\n </div>\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"refreshData()\" [disabled]=\"isLoading\">\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"isLoading\"></i>\n Refresh\n </button>\n </div>\n\n <!-- Stats Cards -->\n <div class=\"mj-grid mj-grid-4\">\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-total\">\n <i class=\"fa-solid fa-database\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.totalEntities }}</div>\n <div class=\"stat-label\">Total Entities</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-public\">\n <i class=\"fa-solid fa-globe\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.publicEntities }}</div>\n <div class=\"stat-label\">Public Entities</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-restricted\">\n <i class=\"fa-solid fa-lock\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.restrictedEntities }}</div>\n <div class=\"stat-label\">Restricted Entities</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-permissions\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.totalPermissions }}</div>\n <div class=\"stat-label\">Total Permissions</div>\n </div>\n </div>\n </div>\n\n <!-- Filters Section -->\n <div class=\"filters-section\">\n <div class=\"filters-row\">\n <!-- Entity Search -->\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\"></i>\n <input \n type=\"text\" \n class=\"mj-search-input\" \n placeholder=\"Search entities by name or description...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.entitySearch\"\n />\n </div>\n \n <!-- Access Level Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\">Access Level</label>\n <div class=\"mj-filter-buttons\">\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'all'\"\n (click)=\"onAccessLevelChange('all')\"\n >\n All\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'public'\"\n (click)=\"onAccessLevelChange('public')\"\n >\n Public\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'restricted'\"\n (click)=\"onAccessLevelChange('restricted')\"\n >\n Restricted\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'custom'\"\n (click)=\"onAccessLevelChange('custom')\"\n >\n Custom\n </button>\n </div>\n </div>\n \n <!-- Role Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\">Filter by Role</label>\n <select class=\"mj-select\" (change)=\"onRoleFilterChange($event)\">\n <option value=\"\">All Roles</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">Loading entity permissions...</div>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button class=\"mj-btn mj-btn-primary\" (click)=\"loadInitialData()\">\n <i class=\"fa-solid fa-refresh\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Content Area -->\n @if (!isLoading && !error) {\n <div class=\"content-area\">\n @if (viewMode === 'list') {\n <!-- List View -->\n <div class=\"entities-list\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <div class=\"entity-card\" [class.expanded]=\"isEntityExpanded(ea.entity.ID)\">\n <div class=\"entity-header\" (click)=\"toggleEntityExpansion(ea.entity.ID)\">\n <div class=\"entity-info\">\n <div class=\"entity-icon-wrapper\">\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 class=\"access-badge\" [class]=\"getAccessLevelClass(ea)\">\n <i [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' : \n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' : \n 'fa-solid fa-key'\"></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <button \n type=\"button\"\n class=\"btn-edit\" \n (click)=\"editEntityPermissions(ea); $event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n title=\"Edit Permissions\"\n >\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button class=\"expand-btn\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n </div>\n </div>\n \n @if (isEntityExpanded(ea.entity.ID)) {\n <div class=\"entity-content\">\n @if (ea.permissions.length > 0) {\n <div class=\"permissions-grid\">\n <div class=\"permissions-header\">\n <span class=\"role-header\">Role</span>\n <span class=\"permission-header\">Create</span>\n <span class=\"permission-header\">Read</span>\n <span class=\"permission-header\">Update</span>\n <span class=\"permission-header\">Delete</span>\n </div>\n @for (roleId of ea.rolePermissions.keys(); track roleId) {\n <div class=\"permission-row\">\n <span class=\"role-name\">{{ getRoleName(roleId) }}</span>\n <span class=\"permission-cell\">\n <i [class]=\"hasPermission(ea, roleId, 'canCreate') ? \n 'fa-solid fa-check text-success' : \n 'fa-solid fa-times text-muted'\"></i>\n </span>\n <span class=\"permission-cell\">\n <i [class]=\"hasPermission(ea, roleId, 'canRead') ? \n 'fa-solid fa-check text-success' : \n 'fa-solid fa-times text-muted'\"></i>\n </span>\n <span class=\"permission-cell\">\n <i [class]=\"hasPermission(ea, roleId, 'canUpdate') ? \n 'fa-solid fa-check text-success' : \n 'fa-solid fa-times text-muted'\"></i>\n </span>\n <span class=\"permission-cell\">\n <i [class]=\"hasPermission(ea, roleId, 'canDelete') ? \n 'fa-solid fa-check text-success' : \n 'fa-solid fa-times text-muted'\"></i>\n </span>\n </div>\n }\n </div>\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\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <div class=\"entity-grid-card\" [class]=\"getAccessLevelClass(ea)\">\n <div class=\"grid-card-header\">\n <i class=\"fa-solid fa-table\"></i>\n <button \n type=\"button\"\n class=\"btn-edit\" \n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n >\n <i class=\"fa-solid fa-edit\"></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 class=\"access-label\">\n <i [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' : \n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' : \n 'fa-solid fa-key'\"></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n @if (ea.permissions.length > 0) {\n <span class=\"permission-count\">\n {{ ea.permissions.length }} permission{{ ea.permissions.length === 1 ? '' : 's' }}\n </span>\n }\n </div>\n </div>\n }\n </div>\n }\n \n @if (filteredEntityAccess.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-key empty-icon\"></i>\n <p class=\"empty-text\">No entities found</p>\n <p class=\"empty-subtext\">Try adjusting your filters to see more results</p>\n </div>\n }\n </div>\n }\n\n <!-- Permission Edit Dialog -->\n <mj-permission-dialog\n [visible]=\"showPermissionDialog\"\n [data]=\"permissionDialogData\"\n (result)=\"onPermissionDialogResult($event)\"\n ></mj-permission-dialog>\n</div>", styles: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.entity-permissions-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n max-width: 1400px;\n margin: 0 auto;\n padding: 2rem;\n}\n\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: space-between;\n margin-bottom: 1.5rem;\n}\n@media (max-width: 768px) {\n .action-buttons {\n flex-direction: column;\n }\n}\n\n.view-toggle {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n\n.view-btn {\n padding: 0.5rem 1rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.view-btn:hover {\n color: #374151;\n}\n.view-btn.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-primary i {\n font-size: 0.875rem;\n}\n.btn-primary:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n\n.btn-secondary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n}\n.btn-secondary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-secondary i {\n font-size: 0.875rem;\n}\n.btn-secondary:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n}\n\n.stats-grid {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n margin-bottom: 2rem;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n margin-right: 10px;\n align-items: center;\n gap: 1rem;\n transition: all 0.3s ease;\n min-width: 0;\n}\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.stat-icon {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n}\n.stat-icon-total {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.stat-icon-public {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n.stat-icon-restricted {\n background: rgba(244, 67, 54, 0.1);\n color: #f44336;\n}\n.stat-icon-permissions {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n\n.stat-content {\n flex: 1;\n}\n.stat-content .stat-value {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n}\n.stat-content .stat-label {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n.filters-section {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n margin-bottom: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filters-row {\n display: flex;\n gap: 1.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n.search-container {\n flex: 1;\n min-width: 250px;\n position: relative;\n}\n.search-container .search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n}\n.search-container .search-input {\n width: 100%;\n padding: 0.75rem 1rem 0.75rem 2.75rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n}\n.search-container .search-input:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n.filter-group .filter-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: #374151;\n}\n.filter-group .filter-buttons {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n.filter-group .filter-btn {\n padding: 0.5rem 1rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group .filter-btn:hover {\n color: #374151;\n}\n.filter-group .filter-btn.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.filter-group .filter-select {\n padding: 0.75rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n background: white;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group .filter-select:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.content-area {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n padding: 1.5rem;\n}\n\n.entities-list {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n max-height: calc(100vh - 450px);\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n\n.entity-card {\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.3s ease;\n}\n.entity-card:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n}\n.entity-card.expanded {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n.entity-card.expanded .expand-btn i {\n transform: rotate(180deg);\n}\n\n.entity-header {\n padding: 1.5rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n background: #f9fafb;\n transition: background-color 0.2s;\n}\n.entity-header:hover {\n background: #f3f4f6;\n}\n\n.entity-info {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex: 1;\n}\n\n.entity-icon-wrapper {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n background: rgba(33, 150, 243, 0.1);\n display: flex;\n align-items: center;\n justify-content: center;\n color: #2196f3;\n font-size: 1.25rem;\n}\n\n.entity-details {\n flex: 1;\n}\n.entity-details .entity-name {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n}\n.entity-details .entity-description {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0;\n}\n\n.entity-meta {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.access-badge {\n padding: 0.375rem 0.75rem;\n border-radius: 20px;\n font-size: 0.75rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.375rem;\n}\n.access-badge.access-public {\n background: rgba(76, 175, 80, 0.1);\n color: #388e3c;\n}\n.access-badge.access-restricted {\n background: rgba(244, 67, 54, 0.1);\n color: #d32f2f;\n}\n.access-badge.access-custom {\n background: rgba(156, 39, 176, 0.1);\n color: #7b1fa2;\n}\n\n.action-btn {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.action-btn:hover {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.expand-btn {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s;\n}\n.expand-btn i {\n transition: transform 0.3s ease;\n}\n\n.entity-content {\n padding: 1.5rem;\n background: white;\n border-top: 1px solid #e5e7eb;\n animation: slideDown 0.3s ease-out;\n}\n\n.permissions-grid {\n background: #f9fafb;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.permissions-header {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 1rem;\n padding: 1rem;\n background: #e5e7eb;\n font-weight: 600;\n color: #374151;\n font-size: 0.875rem;\n}\n\n.permission-row {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 1rem;\n padding: 1rem;\n border-bottom: 1px solid #e5e7eb;\n transition: background-color 0.2s;\n}\n.permission-row:hover {\n background: white;\n}\n.permission-row:last-child {\n border-bottom: none;\n}\n\n.role-header, .permission-header {\n text-align: left;\n}\n\n.role-name {\n font-weight: 500;\n color: #1f2937;\n}\n\n.permission-cell {\n text-align: center;\n}\n\n.text-success {\n color: #4caf50;\n}\n\n.text-muted {\n color: #d1d5db;\n}\n\n.no-permissions {\n color: #6b7280;\n font-size: 0.875rem;\n margin: 0;\n}\n\n.entities-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 1.5rem;\n}\n\n.entity-grid-card {\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n padding: 1.5rem;\n transition: all 0.3s ease;\n position: relative;\n}\n.entity-grid-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n.entity-grid-card.access-public {\n border-left: 4px solid #4caf50;\n}\n.entity-grid-card.access-restricted {\n border-left: 4px solid #f44336;\n}\n.entity-grid-card.access-custom {\n border-left: 4px solid #9c27b0;\n}\n\n.grid-card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 1rem;\n font-size: 1.5rem;\n color: #2196f3;\n}\n\n.edit-btn {\n padding: 0.375rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.edit-btn:hover {\n background: #f3f4f6;\n color: #2196f3;\n}\n\n.grid-card-title {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.5rem 0;\n}\n\n.grid-card-description {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0 0 1rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.grid-card-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.875rem;\n}\n\n.access-label {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n font-weight: 500;\n}\n\n.permission-count {\n color: #6b7280;\n}\n\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n.empty-state .empty-icon {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n}\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n}\n.empty-state .empty-subtext {\n color: #6b7280;\n margin: 0;\n}\n\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n.loading-spinner {\n position: relative;\n width: 60px;\n height: 60px;\n margin-bottom: 1rem;\n}\n.loading-spinner .spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n}\n.loading-spinner .spinner-ring:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner .spinner-ring:nth-child(2) {\n border-color: transparent #9c27b0 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner .spinner-ring:nth-child(3) {\n border-color: transparent transparent #4caf50 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n.error-container .error-icon {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n}\n.error-container .error-message {\n color: #374151;\n margin-bottom: 1.5rem;\n}\n.error-container .retry-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.error-container .retry-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.error-container .retry-button i {\n font-size: 0.875rem;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n.modal-dialog {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s ease;\n}\n.modal-dialog.modal-large {\n max-width: 800px;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid #e5e7eb;\n}\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0;\n}\n.modal-header .modal-close {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.modal-header .modal-close:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n.modal-body {\n padding: 1.5rem;\n max-height: 60vh;\n overflow-y: auto;\n}\n.modal-body .modal-description {\n color: #374151;\n margin: 0 0 1.5rem 0;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n}\n\n.permission-editor {\n padding: 2rem;\n background: #f3f4f6;\n border-radius: 8px;\n text-align: center;\n}\n.permission-editor .coming-soon {\n color: #6b7280;\n margin: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 800px;\n }\n}\n.btn-edit {\n width: 36px;\n height: 36px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n background: white;\n color: #666666;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n}\n.btn-edit:hover {\n background: #f8f9fa;\n border-color: #2196f3;\n color: #2196f3;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.2);\n}\n.btn-edit:active {\n transform: translateY(0);\n}\n"] }]
652
652
  }], () => [], null); })();
653
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityPermissionsComponent, { className: "EntityPermissionsComponent" }); })();
653
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityPermissionsComponent, { className: "EntityPermissionsComponent", filePath: "src/lib/entity-permissions/entity-permissions.component.ts", lineNumber: 48 }); })();
654
654
  //# sourceMappingURL=entity-permissions.component.js.map
@@ -458,5 +458,5 @@ export class PermissionDialogComponent {
458
458
  type: HostListener,
459
459
  args: ['document:keydown.escape', ['$event']]
460
460
  }] }); })();
461
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PermissionDialogComponent, { className: "PermissionDialogComponent" }); })();
461
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PermissionDialogComponent, { className: "PermissionDialogComponent", filePath: "src/lib/entity-permissions/permission-dialog/permission-dialog.component.ts", lineNumber: 32 }); })();
462
462
  //# sourceMappingURL=permission-dialog.component.js.map
@@ -323,5 +323,5 @@ export class RoleDialogComponent {
323
323
  type: HostListener,
324
324
  args: ['document:keydown.escape', ['$event']]
325
325
  }] }); })();
326
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RoleDialogComponent, { className: "RoleDialogComponent" }); })();
326
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RoleDialogComponent, { className: "RoleDialogComponent", filePath: "src/lib/role-management/role-dialog/role-dialog.component.ts", lineNumber: 24 }); })();
327
327
  //# sourceMappingURL=role-dialog.component.js.map
@@ -509,5 +509,5 @@ export { RoleManagementComponent };
509
509
  type: Component,
510
510
  args: [{ selector: 'mj-role-management', template: "<div class=\"role-management-container\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"refreshData()\" [disabled]=\"isLoading\">\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"isLoading\"></i>\n Refresh\n </button>\n <button class=\"mj-btn mj-btn-primary\" (click)=\"createNewRole()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add Role\n </button>\n </div>\n\n <!-- Stats Cards -->\n <div class=\"mj-grid mj-grid-4\">\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-total\">\n <i class=\"fa-solid fa-user-tag\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.totalRoles }}</div>\n <div class=\"stat-label\">Total Roles</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-system\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.systemRoles }}</div>\n <div class=\"stat-label\">System Roles</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-custom\">\n <i class=\"fa-solid fa-user-tag\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.customRoles }}</div>\n <div class=\"stat-label\">Custom Roles</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-active\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.activeRoles }}</div>\n <div class=\"stat-label\">Active Roles</div>\n </div>\n </div>\n </div>\n\n <!-- Filters Section -->\n <div class=\"filters-section\">\n <div class=\"filters-row\">\n <!-- Search -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input \n type=\"text\" \n class=\"search-input\" \n placeholder=\"Search roles by name or description...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.search\"\n />\n </div>\n \n <!-- Type Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">Type</label>\n <div class=\"filter-buttons\">\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.type === 'all'\"\n (click)=\"onTypeFilterChange('all')\"\n >\n All\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.type === 'system'\"\n (click)=\"onTypeFilterChange('system')\"\n >\n System\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.type === 'custom'\"\n (click)=\"onTypeFilterChange('custom')\"\n >\n Custom\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">Loading roles...</div>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button class=\"retry-button\" (click)=\"loadInitialData()\">\n <i class=\"fa-solid fa-refresh\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Content Area -->\n @if (!isLoading && !error) {\n <div class=\"content-area\">\n <div class=\"roles-list\">\n @for (role of filteredRoles; track role.ID) {\n <div class=\"role-card\" [class.expanded]=\"isRoleExpanded(role.ID)\">\n <div class=\"role-header\" (click)=\"toggleRoleExpansion(role.ID)\">\n <div class=\"role-info\">\n <div class=\"role-icon-wrapper\">\n <i [class]=\"'fa-solid ' + getRoleIcon(role)\"></i>\n </div>\n <div class=\"role-details\">\n <h3 class=\"role-name\">{{ role.Name }}</h3>\n <p class=\"role-description\">{{ role.Description || 'No description available' }}</p>\n </div>\n </div>\n \n <div class=\"role-meta\">\n <span class=\"role-type-badge\" [class]=\"getRoleTypeClass(role)\">\n {{ getRoleTypeLabel(role) }}\n </span>\n <div class=\"role-actions\" (click)=\"$event.stopPropagation()\">\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm\" (click)=\"editRole(role)\" title=\"Edit\" [disabled]=\"isSystemRole(role)\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm text-danger\" (click)=\"confirmDeleteRole(role)\" title=\"Delete\" [disabled]=\"isSystemRole(role)\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n <button class=\"expand-btn\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n </div>\n </div>\n \n @if (isRoleExpanded(role.ID)) {\n <div class=\"role-content\">\n <div class=\"role-stats\">\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-users\"></i>\n <span class=\"stat-label\">Users:</span>\n <span class=\"stat-value\">0</span><!-- UserCount would come from a join -->\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n <span class=\"stat-label\">Created:</span>\n <span class=\"stat-value\">{{ role.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-clock\"></i>\n <span class=\"stat-label\">Updated:</span>\n <span class=\"stat-value\">{{ role.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n </div>\n \n <div class=\"permissions-preview\">\n <h4 class=\"section-title\">\n <i class=\"fa-solid fa-key\"></i>\n Permissions Preview\n </h4>\n <p class=\"permissions-note\">Full permission management available in the Permissions tab</p>\n </div>\n </div>\n }\n </div>\n }\n \n @if (filteredRoles.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-user-tag empty-icon\"></i>\n <p class=\"empty-text\">No roles found</p>\n <p class=\"empty-subtext\">Try adjusting your filters or create a new role</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Role Create/Edit Dialog -->\n <mj-role-dialog \n [data]=\"roleDialogData\"\n [visible]=\"showRoleDialog\"\n (result)=\"onRoleDialogResult($event)\">\n </mj-role-dialog>\n\n <!-- Delete Confirmation Dialog -->\n @if (showDeleteConfirm && selectedRole) {\n <div class=\"modal-backdrop\" (click)=\"showDeleteConfirm = false\">\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\">\n <i class=\"fa-solid fa-exclamation-triangle text-danger\"></i>\n Confirm Delete\n </h3>\n <button class=\"modal-close\" (click)=\"showDeleteConfirm = false\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Are you sure you want to delete the role <strong>{{ selectedRole.Name }}</strong>?</p>\n <p class=\"text-warning\">\n <i class=\"fa-solid fa-warning\"></i>\n This will affect all users assigned to this role.\n </p>\n </div>\n <div class=\"modal-footer\">\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"showDeleteConfirm = false\">Cancel</button>\n <button class=\"mj-btn mj-btn-primary text-danger\" (click)=\"deleteRole()\">\n <i class=\"fa-solid fa-trash\"></i>\n Delete Role\n </button>\n </div>\n </div>\n </div>\n }\n</div>", styles: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.role-management-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.action-buttons {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 1rem 2rem;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n}\n@media (max-width: 768px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n padding: 1rem;\n }\n}\n\n.btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-primary i {\n font-size: 0.875rem;\n}\n.btn-primary:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n}\n\n.btn-secondary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n}\n.btn-secondary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-secondary i {\n font-size: 0.875rem;\n}\n.btn-secondary:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n}\n\n.btn-danger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #f44336;\n color: white;\n}\n.btn-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-danger i {\n font-size: 0.875rem;\n}\n.btn-danger:hover {\n background-color: #d32f2f;\n}\n\n.stats-grid {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n margin-bottom: 2rem;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n margin-right: 10px;\n align-items: center;\n gap: 1rem;\n transition: all 0.3s ease;\n min-width: 0;\n}\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.stat-icon {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n}\n.stat-icon-total {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.stat-icon-system {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n.stat-icon-custom {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n}\n.stat-icon-active {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n\n.stat-content {\n flex: 1;\n}\n.stat-content .stat-value {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n}\n.stat-content .stat-label {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n.filters-section {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n margin-bottom: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filters-row {\n display: flex;\n gap: 1.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n@media (max-width: 768px) {\n .filters-row {\n gap: 1rem;\n }\n}\n\n.search-container {\n flex: 1;\n min-width: 250px;\n position: relative;\n}\n.search-container .search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n}\n.search-container .search-input {\n width: 100%;\n padding: 0.75rem 1rem 0.75rem 2.75rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n}\n.search-container .search-input:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n.filter-group .filter-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: #374151;\n}\n.filter-group .filter-buttons {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n.filter-group .filter-btn {\n padding: 0.5rem 1rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group .filter-btn:hover {\n color: #374151;\n}\n.filter-group .filter-btn.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.content-area {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n padding: 1.5rem;\n}\n\n.roles-list {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n max-height: calc(100vh - 450px);\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n\n.role-card {\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.3s ease;\n}\n.role-card:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n}\n.role-card.expanded {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n.role-card.expanded .expand-btn i {\n transform: rotate(180deg);\n}\n\n.role-header {\n padding: 1.5rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n background: #f9fafb;\n transition: background-color 0.2s;\n}\n.role-header:hover {\n background: #f3f4f6;\n}\n\n.role-info {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex: 1;\n}\n\n.role-icon-wrapper {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n background: rgba(33, 150, 243, 0.1);\n display: flex;\n align-items: center;\n justify-content: center;\n color: #2196f3;\n font-size: 1.25rem;\n}\n\n.role-details {\n flex: 1;\n}\n.role-details .role-name {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n}\n.role-details .role-description {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0;\n}\n\n.role-meta {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.role-type-badge {\n padding: 0.375rem 0.75rem;\n border-radius: 20px;\n font-size: 0.75rem;\n font-weight: 600;\n}\n.role-type-badge.badge-system {\n background: rgba(156, 39, 176, 0.1);\n color: #7b1fa2;\n}\n.role-type-badge.badge-custom {\n background: rgba(255, 152, 0, 0.1);\n color: #f57c00;\n}\n\n.role-actions {\n display: flex;\n gap: 0.5rem;\n}\n\n.action-btn {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.action-btn:hover:not(:disabled) {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.action-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.action-btn-danger:hover:not(:disabled) {\n color: #f44336;\n}\n\n.expand-btn {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s;\n}\n.expand-btn i {\n transition: transform 0.3s ease;\n}\n\n.role-content {\n padding: 1.5rem;\n background: white;\n border-top: 1px solid #e5e7eb;\n animation: slideDown 0.3s ease-out;\n}\n\n.role-stats {\n display: flex;\n gap: 2rem;\n margin-bottom: 1.5rem;\n flex-wrap: wrap;\n}\n.role-stats .stat-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n}\n.role-stats .stat-item i {\n color: #6b7280;\n}\n.role-stats .stat-item .stat-label {\n color: #6b7280;\n}\n.role-stats .stat-item .stat-value {\n color: #1f2937;\n font-weight: 500;\n}\n\n.permissions-preview {\n padding: 1rem;\n background: #f9fafb;\n border-radius: 8px;\n}\n.permissions-preview .section-title {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 1rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.5rem 0;\n}\n.permissions-preview .section-title i {\n color: #2196f3;\n}\n.permissions-preview .permissions-note {\n color: #6b7280;\n font-size: 0.875rem;\n margin: 0;\n}\n\n.role-card[data-system=true] .role-icon-wrapper {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n.empty-state .empty-icon {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n}\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n}\n.empty-state .empty-subtext {\n color: #6b7280;\n margin: 0;\n}\n\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n.loading-spinner {\n position: relative;\n width: 60px;\n height: 60px;\n margin-bottom: 1rem;\n}\n.loading-spinner .spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n}\n.loading-spinner .spinner-ring:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner .spinner-ring:nth-child(2) {\n border-color: transparent #9c27b0 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner .spinner-ring:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n.error-container .error-icon {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n}\n.error-container .error-message {\n color: #374151;\n margin-bottom: 1.5rem;\n}\n.error-container .retry-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.error-container .retry-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.error-container .retry-button i {\n font-size: 0.875rem;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n.modal-dialog {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s ease;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid #e5e7eb;\n}\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0;\n}\n.modal-header .modal-close {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.modal-header .modal-close:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n.modal-body {\n padding: 1.5rem;\n}\n.modal-body p {\n margin: 0 0 1rem 0;\n color: #374151;\n}\n.modal-body p:last-child {\n margin-bottom: 0;\n}\n.modal-body .text-warning {\n color: #f57c00;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 500px;\n }\n}\n.text-danger {\n color: #f44336;\n}\n"] }]
511
511
  }], () => [], null); })();
512
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RoleManagementComponent, { className: "RoleManagementComponent" }); })();
512
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RoleManagementComponent, { className: "RoleManagementComponent", filePath: "src/lib/role-management/role-management.component.ts", lineNumber: 28 }); })();
513
513
  //# sourceMappingURL=role-management.component.js.map
@@ -476,5 +476,5 @@ export { SettingsComponent };
476
476
  }], () => [], { stateChange: [{
477
477
  type: Output
478
478
  }] }); })();
479
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SettingsComponent, { className: "SettingsComponent" }); })();
479
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SettingsComponent, { className: "SettingsComponent", filePath: "src/lib/settings/settings.component.ts", lineNumber: 28 }); })();
480
480
  //# sourceMappingURL=settings.component.js.map
@@ -69,5 +69,5 @@ export class SettingsCardComponent {
69
69
  }], toggle: [{
70
70
  type: Output
71
71
  }] }); })();
72
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SettingsCardComponent, { className: "SettingsCardComponent" }); })();
72
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SettingsCardComponent, { className: "SettingsCardComponent", filePath: "src/lib/shared/settings-card.component.ts", lineNumber: 122 }); })();
73
73
  //# sourceMappingURL=settings-card.component.js.map
@@ -942,5 +942,5 @@ export { SqlLoggingComponent };
942
942
  type: Component,
943
943
  args: [{ selector: 'mj-sql-logging', template: "<div class=\"sql-logging-container\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button class=\"btn-secondary\" (click)=\"loadActiveSessions()\" [disabled]=\"loading\">\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"loading\"></i>\n Refresh\n </button>\n @if (isOwner && configEnabled) {\n <button \n class=\"btn-primary\"\n [disabled]=\"loading || activeSessions.length >= (sqlLoggingConfig?.maxActiveSessions || 5)\"\n (click)=\"openStartSessionDialog()\"\n title=\"Start SQL logging session\"\n >\n <i class=\"fa-solid fa-play\"></i>\n Start New Session\n </button>\n }\n </div>\n\n <!-- Stats Cards -->\n @if (isOwner && configEnabled) {\n <div class=\"stats-grid\" style=\"display: flex\">\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-status\">\n <i class=\"fa-solid fa-power-off\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ configEnabled ? 'Enabled' : 'Disabled' }}</div>\n <div class=\"stat-label\">Status</div>\n </div>\n </div>\n \n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-active\">\n <i class=\"fa-solid fa-play-circle\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ activeSessions.length }}</div>\n <div class=\"stat-label\">Active Sessions</div>\n </div>\n </div>\n \n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-limit\">\n <i class=\"fa-solid fa-gauge-high\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ sqlLoggingConfig?.maxActiveSessions || 5 }}</div>\n <div class=\"stat-label\">Max Sessions</div>\n </div>\n </div>\n \n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-total\">\n <i class=\"fa-solid fa-database\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ getTotalStatementCount() }}</div>\n <div class=\"stat-label\">Total Statements</div>\n </div>\n </div>\n </div>\n }\n\n <!-- Loading State -->\n @if (loading && !activeSessions.length) {\n <div class=\"loading-container\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">Loading SQL logging configuration...</div>\n </div>\n }\n\n <!-- Content Area -->\n @if (!loading || activeSessions.length > 0) {\n <div class=\"content-area\">\n @if (!isOwner) {\n <!-- Not authorized -->\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-lock empty-icon\"></i>\n <p class=\"empty-text\">Access Denied</p>\n <p class=\"empty-subtext\">SQL logging requires Owner privileges. Please contact your system administrator for access.</p>\n <button \n class=\"btn-secondary\"\n (click)=\"refreshUserPermissions()\"\n style=\"margin-top: 1rem\"\n >\n <i class=\"fa-solid fa-sync\"></i>\n Refresh Permissions\n </button>\n </div>\n } @else if (!configEnabled) {\n <!-- Not enabled in config -->\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-exclamation-triangle empty-icon warning\"></i>\n <p class=\"empty-text\">SQL Logging Disabled</p>\n <p class=\"empty-subtext\">SQL logging is not enabled in the server configuration.</p>\n <div class=\"info-box\">\n <h4>To enable SQL logging:</h4>\n <ol>\n <li>Set <code>sqlLogging.enabled = true</code> in mj.config.cjs</li>\n <li>Restart the MJ API server</li>\n <li>Refresh this page</li>\n </ol>\n </div>\n </div>\n } @else if (activeSessions.length === 0) {\n <!-- No active sessions -->\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-file-code empty-icon\"></i>\n <p class=\"empty-text\">No Active Sessions</p>\n <p class=\"empty-subtext\">Start a new SQL logging session to begin capturing SQL statements.</p>\n <button \n class=\"btn-primary\"\n (click)=\"openStartSessionDialog()\"\n style=\"margin-top: 1rem\"\n >\n <i class=\"fa-solid fa-play\"></i>\n Start New Session\n </button>\n </div>\n } @else {\n <!-- Sessions layout -->\n <div class=\"sessions-layout\">\n <!-- Sessions panel -->\n <div class=\"sessions-panel\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">Active Sessions</h3>\n @if (activeSessions.length > 0) {\n <button \n class=\"btn-danger btn-small\"\n (click)=\"stopAllSessions()\"\n [disabled]=\"loading\"\n title=\"Stop all sessions\"\n >\n <i class=\"fa-solid fa-stop\"></i>\n Stop All\n </button>\n }\n </div>\n <div class=\"sessions-list\">\n @for (session of activeSessions; track session.id) {\n <div \n class=\"session-card\" \n [class.selected]=\"selectedSession?.id === session.id\"\n (click)=\"selectSession(session)\"\n >\n <div class=\"session-header\">\n <div class=\"session-info\">\n <h4 class=\"session-title\">{{ session.sessionName }}</h4>\n <div class=\"session-meta\">\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-clock\"></i>\n {{ getSessionDuration(session.startTime) }}\n </span>\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-database\"></i>\n {{ session.statementCount }} statements\n </span>\n </div>\n </div>\n <button \n class=\"action-btn action-btn-danger\"\n (click)=\"stopSession(session, $event)\"\n title=\"Stop session\"\n >\n <i class=\"fa-solid fa-stop\"></i>\n </button>\n </div>\n <div class=\"session-badges\">\n @if (session.filterByUserId) {\n <span class=\"badge badge-user\">\n <i class=\"fa-solid fa-user\"></i>\n User Filtered\n </span>\n }\n @if (session.options?.formatAsMigration) {\n <span class=\"badge badge-migration\">\n <i class=\"fa-solid fa-code-branch\"></i>\n Migration\n </span>\n }\n <span class=\"badge badge-type\">\n {{ session.options?.statementTypes || 'both' }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n \n <!-- Log viewer panel -->\n <div class=\"log-viewer-panel\">\n @if (selectedSession) {\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">{{ selectedSession.sessionName }}</h3>\n <div class=\"panel-actions\">\n <label class=\"checkbox-label\">\n <input \n type=\"checkbox\" \n [(ngModel)]=\"autoRefresh\"\n />\n Auto-refresh\n </label>\n <button \n class=\"action-btn\"\n (click)=\"loadSessionLog(selectedSession)\"\n title=\"Refresh log\"\n >\n <i class=\"fa-solid fa-sync\" [class.fa-spin]=\"loading\"></i>\n </button>\n </div>\n </div>\n <div class=\"log-content\">\n <mj-code-editor\n [value]=\"logContent\"\n [readonly]=\"true\"\n [disabled]=\"true\"\n [language]=\"'sql'\"\n [setup]=\"'basic'\"\n [lineWrapping]=\"true\"\n [highlightWhitespace]=\"false\"\n style=\"height: 100%;\"\n ></mj-code-editor>\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-arrow-left empty-icon\"></i>\n <p class=\"empty-text\">Select a Session</p>\n <p class=\"empty-subtext\">Choose a session from the list to view its SQL log.</p>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Start Session Dialog -->\n @if (showStartSessionDialog) {\n <div class=\"modal-backdrop\" (click)=\"showStartSessionDialog = false\">\n <div class=\"modal-dialog modal-large\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\">\n <i class=\"fa-solid fa-play\"></i>\n Start SQL Logging Session\n </h3>\n <button class=\"modal-close\" (click)=\"showStartSessionDialog = false\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"form-group\">\n <label class=\"form-label\">Session Name</label>\n <input \n type=\"text\"\n class=\"form-input\" \n [(ngModel)]=\"newSessionOptions.sessionName\"\n placeholder=\"Enter a descriptive name for this session\"\n />\n </div>\n \n <div class=\"form-group\">\n <label class=\"form-label\">File Name</label>\n <input \n type=\"text\"\n class=\"form-input\" \n [(ngModel)]=\"newSessionOptions.fileName\"\n placeholder=\"sql-log-2024-01-01.sql\"\n />\n <div class=\"form-hint\">The SQL log will be saved to this file</div>\n </div>\n \n <div class=\"form-group\">\n <label class=\"form-label\">Statement Types</label>\n <select\n class=\"form-select\"\n [(ngModel)]=\"newSessionOptions.statementTypes\"\n >\n @for (option of statementTypeOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.text }}</option>\n }\n </select>\n </div>\n \n <div class=\"form-checkboxes\">\n <label class=\"checkbox-label\">\n <input \n type=\"checkbox\" \n [(ngModel)]=\"newSessionOptions.filterToCurrentUser\"\n />\n Filter to my SQL statements only\n </label>\n \n <label class=\"checkbox-label\">\n <input \n type=\"checkbox\" \n [(ngModel)]=\"newSessionOptions.formatAsMigration\"\n />\n Format as migration file\n </label>\n \n <label class=\"checkbox-label\">\n <input \n type=\"checkbox\" \n [(ngModel)]=\"newSessionOptions.prettyPrint\"\n />\n Pretty print SQL statements\n </label>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button class=\"btn-secondary\" (click)=\"showStartSessionDialog = false\">\n Cancel\n </button>\n <button class=\"btn-primary\" (click)=\"startNewSession()\" [disabled]=\"loading\">\n <i class=\"fa-solid fa-play\"></i>\n Start Session\n </button>\n </div>\n </div>\n </div>\n }\n</div>", styles: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.sql-logging-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n max-width: 1400px;\n margin: 0 auto;\n padding: 2rem;\n}\n\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n margin-bottom: 1.5rem;\n}\n@media (max-width: 768px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n.btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-primary i {\n font-size: 0.875rem;\n}\n.btn-primary:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n\n.btn-secondary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n}\n.btn-secondary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-secondary i {\n font-size: 0.875rem;\n}\n.btn-secondary:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n}\n\n.btn-danger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #f44336;\n color: white;\n}\n.btn-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-danger i {\n font-size: 0.875rem;\n}\n.btn-danger:hover {\n background-color: #d32f2f;\n}\n.btn-danger.btn-small {\n padding: 0.375rem 0.75rem;\n font-size: 0.875rem;\n}\n\n.stats-grid {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n margin-bottom: 2rem;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n margin-right: 10px;\n align-items: center;\n gap: 1rem;\n transition: all 0.3s ease;\n min-width: 0;\n}\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.stat-icon {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n}\n.stat-icon-status {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n.stat-icon-active {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.stat-icon-limit {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n}\n.stat-icon-total {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n\n.stat-content {\n flex: 1;\n}\n.stat-content .stat-value {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n}\n.stat-content .stat-label {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n.content-area {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n padding: 1.5rem;\n min-height: 400px;\n}\n\n.sessions-layout {\n display: flex;\n gap: 1.5rem;\n height: calc(100vh - 450px);\n min-height: 400px;\n max-height: 600px;\n}\n@media (max-width: 1024px) {\n .sessions-layout {\n flex-direction: column;\n height: auto;\n max-height: none;\n }\n}\n\n.sessions-panel {\n flex: 0 0 400px;\n display: flex;\n flex-direction: column;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n overflow: hidden;\n}\n@media (max-width: 1024px) {\n .sessions-panel {\n flex: 1;\n max-height: 400px;\n }\n}\n\n.panel-header {\n padding: 1rem;\n background: #f9fafb;\n border-bottom: 1px solid #e5e7eb;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n.panel-header .panel-title {\n margin: 0;\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n}\n\n.panel-actions {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.sessions-list {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n padding: 0.75rem;\n}\n\n.session-card {\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n padding: 1rem;\n margin-bottom: 0.75rem;\n cursor: pointer;\n transition: all 0.2s;\n}\n.session-card:hover {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n.session-card.selected {\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.session-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.75rem;\n}\n\n.session-info {\n flex: 1;\n}\n.session-info .session-title {\n margin: 0 0 0.5rem 0;\n font-size: 0.95rem;\n font-weight: 600;\n color: #1f2937;\n}\n\n.session-meta {\n display: flex;\n gap: 1rem;\n font-size: 0.75rem;\n color: #6b7280;\n}\n.session-meta .meta-item {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.session-badges {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n}\n\n.badge {\n padding: 0.25rem 0.5rem;\n border-radius: 12px;\n font-size: 0.625rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n.badge-user {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.badge-migration {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n.badge-type {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n}\n\n.action-btn {\n padding: 0.375rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.action-btn:hover {\n background: #f3f4f6;\n color: #374151;\n}\n.action-btn-danger:hover {\n color: #f44336;\n}\n\n.log-viewer-panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.log-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n background: #1e1e1e;\n color: #d4d4d4;\n padding: 0;\n min-height: 300px;\n height: 100%;\n position: relative;\n}\n.log-content ::ng-deep .cm-editor {\n height: 100%;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n font-size: 0.875rem;\n}\n.log-content ::ng-deep .cm-scroller {\n font-family: inherit;\n}\n.log-content ::ng-deep .cm-content {\n background: #1e1e1e;\n color: #d4d4d4;\n}\n.log-content ::ng-deep .cm-gutters {\n background: #252526;\n color: #858585;\n border-right: 1px solid #464647;\n}\n.log-content ::ng-deep .cm-activeLineGutter {\n background: #2a2a2a;\n}\n.log-content ::ng-deep .cm-activeLine {\n background: rgba(255, 255, 255, 0.04);\n}\n\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n.empty-state .empty-icon {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n}\n.empty-state .empty-icon.warning {\n color: #ffc107;\n}\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n}\n.empty-state .empty-subtext {\n color: #6b7280;\n margin: 0;\n}\n\n.info-box {\n background: #f3f4f6;\n border-radius: 8px;\n padding: 1.5rem;\n margin-top: 2rem;\n text-align: left;\n max-width: 500px;\n margin-left: auto;\n margin-right: auto;\n}\n.info-box h4 {\n margin: 0 0 1rem 0;\n color: #1f2937;\n}\n.info-box ol {\n margin: 0;\n padding-left: 1.25rem;\n color: #374151;\n}\n.info-box ol li {\n margin-bottom: 0.5rem;\n}\n.info-box code {\n background: #e5e7eb;\n padding: 0.125rem 0.375rem;\n border-radius: 4px;\n font-size: 0.875rem;\n}\n\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n min-height: 400px;\n}\n\n.loading-spinner {\n position: relative;\n width: 60px;\n height: 60px;\n margin-bottom: 1rem;\n}\n.loading-spinner .spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n}\n.loading-spinner .spinner-ring:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner .spinner-ring:nth-child(2) {\n border-color: transparent #9c27b0 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner .spinner-ring:nth-child(3) {\n border-color: transparent transparent #4caf50 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n.modal-dialog {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s ease;\n}\n.modal-dialog.modal-large {\n max-width: 700px;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid #e5e7eb;\n}\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0;\n}\n.modal-header .modal-close {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.modal-header .modal-close:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n.modal-body {\n padding: 1.5rem;\n max-height: 60vh;\n overflow-y: auto;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n}\n\n.form-group {\n margin-bottom: 1.5rem;\n}\n\n.form-label {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: #374151;\n margin-bottom: 0.5rem;\n}\n\n.form-input {\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n}\n.form-input:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.form-select {\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n background: white;\n cursor: pointer;\n transition: all 0.2s;\n}\n.form-select:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.form-hint {\n font-size: 0.75rem;\n color: #6b7280;\n margin-top: 0.25rem;\n}\n\n.form-checkboxes {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.checkbox-label {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: #374151;\n font-size: 0.95rem;\n cursor: pointer;\n}\n.checkbox-label input[type=checkbox] {\n cursor: pointer;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n"] }]
944
944
  }], () => [{ type: i1.SharedService }], null); })();
945
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SqlLoggingComponent, { className: "SqlLoggingComponent" }); })();
945
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SqlLoggingComponent, { className: "SqlLoggingComponent", filePath: "src/lib/sql-logging/sql-logging.component.ts", lineNumber: 65 }); })();
946
946
  //# sourceMappingURL=sql-logging.component.js.map
@@ -548,5 +548,5 @@ export class UserAppConfigComponent {
548
548
  }], configSaved: [{
549
549
  type: Output
550
550
  }] }); })();
551
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserAppConfigComponent, { className: "UserAppConfigComponent" }); })();
551
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserAppConfigComponent, { className: "UserAppConfigComponent", filePath: "src/lib/user-app-config/user-app-config.component.ts", lineNumber: 30 }); })();
552
552
  //# sourceMappingURL=user-app-config.component.js.map
@@ -464,5 +464,5 @@ export class UserDialogComponent {
464
464
  type: HostListener,
465
465
  args: ['document:keydown.escape', ['$event']]
466
466
  }] }); })();
467
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserDialogComponent, { className: "UserDialogComponent" }); })();
467
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserDialogComponent, { className: "UserDialogComponent", filePath: "src/lib/user-management/user-dialog/user-dialog.component.ts", lineNumber: 25 }); })();
468
468
  //# sourceMappingURL=user-dialog.component.js.map
@@ -762,5 +762,5 @@ export { UserManagementComponent };
762
762
  type: Component,
763
763
  args: [{ selector: 'mj-user-management', template: "<div class=\"user-management-container\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"refreshData()\" [disabled]=\"isLoading\">\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"isLoading\"></i>\n Refresh\n </button>\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"exportUsers()\">\n <i class=\"fa-solid fa-download\"></i>\n Export\n </button>\n <button class=\"mj-btn mj-btn-primary\" (click)=\"createNewUser()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add User\n </button>\n </div>\n\n <!-- Stats Cards -->\n <div class=\"mj-grid mj-grid-4\">\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-total\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.totalUsers }}</div>\n <div class=\"stat-label\">Total Users</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-active\">\n <i class=\"fa-solid fa-user-check\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.activeUsers }}</div>\n <div class=\"stat-label\">Active Users</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-inactive\">\n <i class=\"fa-solid fa-user-xmark\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.inactiveUsers }}</div>\n <div class=\"stat-label\">Inactive Users</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-admin\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.adminUsers }}</div>\n <div class=\"stat-label\">Owners</div>\n </div>\n </div>\n </div>\n\n <!-- Filters Section -->\n <div class=\"filters-section\">\n <div class=\"filters-row\">\n <!-- Search -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input \n type=\"text\" \n class=\"search-input\" \n placeholder=\"Search users by name or email...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.search\"\n />\n </div>\n \n <!-- Status Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">Status</label>\n <div class=\"filter-buttons\">\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'all'\"\n (click)=\"onStatusFilterChange('all')\"\n >\n All\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'active'\"\n (click)=\"onStatusFilterChange('active')\"\n >\n Active\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'inactive'\"\n (click)=\"onStatusFilterChange('inactive')\"\n >\n Inactive\n </button>\n </div>\n </div>\n \n <!-- Role Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">Role</label>\n <select class=\"filter-select\" (change)=\"onRoleFilterChange($any($event.target).value)\">\n <option value=\"\">All Roles</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n \n <!-- View Toggle -->\n <div class=\"view-toggle\">\n <button \n class=\"mj-btn mj-btn-icon-only\"\n [class.mj-btn-primary]=\"viewMode === 'grid'\"\n [class.mj-btn-ghost]=\"viewMode !== 'grid'\"\n (click)=\"viewMode = 'grid'\"\n title=\"Grid View\"\n >\n <i class=\"fa-solid fa-table\"></i>\n </button>\n <button \n class=\"mj-btn mj-btn-icon-only\"\n [class.mj-btn-primary]=\"viewMode === 'cards'\"\n [class.mj-btn-ghost]=\"viewMode !== 'cards'\"\n (click)=\"viewMode = 'cards'\"\n title=\"Card View\"\n >\n <i class=\"fa-solid fa-th-large\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">Loading users...</div>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button class=\"retry-button\" (click)=\"loadInitialData()\">\n <i class=\"fa-solid fa-refresh\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Content Area -->\n @if (!isLoading && !error) {\n <div class=\"content-area\">\n <!-- Grid View -->\n @if (viewMode === 'grid') {\n <div class=\"users-table\">\n <table class=\"modern-table\">\n <thead>\n <tr>\n <th class=\"th-checkbox\">\n <input type=\"checkbox\" class=\"checkbox\" />\n </th>\n <th>User</th>\n <th>Email</th>\n <th>Type</th>\n <th>Status</th>\n <th>Last Updated</th>\n <th class=\"th-actions\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (user of filteredUsers; track user.ID) {\n <tr class=\"table-row\" (click)=\"selectUser(user)\">\n <td class=\"td-checkbox\" (click)=\"$event.stopPropagation()\">\n <input type=\"checkbox\" class=\"checkbox\" />\n </td>\n <td>\n <div class=\"user-cell\">\n <div class=\"user-avatar\">\n {{ getUserInitials(user) }}\n </div>\n <div class=\"user-info\">\n <div class=\"user-name\">{{ user.Name }}</div>\n <div class=\"user-fullname\">\n {{ user.FirstName }} {{ user.LastName }}\n </div>\n </div>\n </div>\n </td>\n <td>{{ user.Email }}</td>\n <td>\n <div class=\"user-type\">\n <i [class]=\"'fa-solid ' + getUserTypeIcon(user)\"></i>\n {{ user.Type }}\n </div>\n </td>\n <td>\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n </td>\n <td>\n <span class=\"last-login\">\n {{ user.__mj_UpdatedAt ? (user.__mj_UpdatedAt | date:'short') : 'Never' }}\n </span>\n </td>\n <td class=\"td-actions\" (click)=\"$event.stopPropagation()\">\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm\" (click)=\"editUser(user)\" title=\"Edit\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button \n class=\"mj-btn mj-btn-ghost mj-btn-sm\" \n (click)=\"toggleUserStatus(user)\"\n [title]=\"user.IsActive ? 'Deactivate' : 'Activate'\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\"></i>\n </button>\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm text-danger\" (click)=\"confirmDeleteUser(user)\" title=\"Delete\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n \n @if (filteredUsers.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-users-slash empty-icon\"></i>\n <p class=\"empty-text\">No users found</p>\n <p class=\"empty-subtext\">Try adjusting your filters or add a new user</p>\n </div>\n }\n </div>\n }\n\n <!-- Card View -->\n @if (viewMode === 'cards') {\n <div class=\"users-grid\">\n @for (user of filteredUsers; track user.ID) {\n <div class=\"user-card\" (click)=\"selectUser(user)\">\n <div class=\"card-header\">\n <div class=\"user-avatar-large\">\n {{ getUserInitials(user) }}\n </div>\n <div class=\"card-actions\">\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm\" (click)=\"editUser(user); $event.stopPropagation()\" title=\"Edit\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm text-danger\" (click)=\"confirmDeleteUser(user); $event.stopPropagation()\" title=\"Delete\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n \n <div class=\"card-body\">\n <h3 class=\"user-name\">{{ user.Name }}</h3>\n <p class=\"user-fullname\">{{ user.FirstName }} {{ user.LastName }}</p>\n <p class=\"user-email\">\n <i class=\"fa-solid fa-envelope\"></i>\n {{ user.Email }}\n </p>\n \n <div class=\"card-meta\">\n <div class=\"meta-item\">\n <i [class]=\"'fa-solid ' + getUserTypeIcon(user)\"></i>\n {{ user.Type }}\n </div>\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n </div>\n \n <div class=\"card-footer\">\n <div class=\"last-login\">\n <i class=\"fa-solid fa-clock\"></i>\n Last updated: {{ user.__mj_UpdatedAt ? (user.__mj_UpdatedAt | date:'short') : 'Never' }}\n </div>\n </div>\n </div>\n </div>\n }\n \n @if (filteredUsers.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-users-slash empty-icon\"></i>\n <p class=\"empty-text\">No users found</p>\n <p class=\"empty-subtext\">Try adjusting your filters or add a new user</p>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- User Create/Edit Dialog -->\n <mj-user-dialog \n [data]=\"userDialogData\"\n [visible]=\"showUserDialog\"\n (result)=\"onUserDialogResult($event)\">\n </mj-user-dialog>\n\n <!-- Delete Confirmation Dialog -->\n @if (showDeleteConfirm && selectedUser) {\n <div class=\"modal-backdrop\" (click)=\"showDeleteConfirm = false\">\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\">\n <i class=\"fa-solid fa-exclamation-triangle text-danger\"></i>\n Confirm Delete\n </h3>\n <button class=\"modal-close\" (click)=\"showDeleteConfirm = false\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Are you sure you want to delete user <strong>{{ selectedUser.Name }}</strong>?</p>\n <p class=\"text-muted\">This action cannot be undone.</p>\n </div>\n <div class=\"modal-footer\">\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"showDeleteConfirm = false\">Cancel</button>\n <button class=\"mj-btn mj-btn-primary text-danger\" (click)=\"deleteUser()\">\n <i class=\"fa-solid fa-trash\"></i>\n Delete User\n </button>\n </div>\n </div>\n </div>\n }\n</div>", styles: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.user-management-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.action-buttons {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 1rem 2rem;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n}\n@media (max-width: 768px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n padding: 1rem;\n }\n}\n\n.btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-primary i {\n font-size: 0.875rem;\n}\n.btn-primary:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n}\n\n.btn-secondary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n}\n.btn-secondary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-secondary i {\n font-size: 0.875rem;\n}\n.btn-secondary:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n}\n\n.btn-danger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #f44336;\n color: white;\n}\n.btn-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-danger i {\n font-size: 0.875rem;\n}\n.btn-danger:hover {\n background-color: #d32f2f;\n}\n\n.stats-grid {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n padding: 1rem 2rem;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n padding: 1rem;\n }\n}\n\n.stat-card {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n margin-right: 10px;\n align-items: center;\n gap: 1rem;\n transition: all 0.3s ease;\n min-width: 0;\n}\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.stat-icon {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n}\n.stat-icon-total {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.stat-icon-active {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n.stat-icon-inactive {\n background: rgba(244, 67, 54, 0.1);\n color: #f44336;\n}\n.stat-icon-admin {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n\n.stat-content {\n flex: 1;\n}\n.stat-content .stat-value {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n}\n.stat-content .stat-label {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n.filters-section {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n background: white;\n padding: 1.5rem 2rem;\n border-bottom: 1px solid #e0e0e0;\n}\n@media (max-width: 768px) {\n .filters-section {\n padding: 1rem;\n }\n}\n\n.filters-row {\n display: flex;\n gap: 1.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n@media (max-width: 768px) {\n .filters-row {\n gap: 1rem;\n }\n}\n\n.search-container {\n flex: 1;\n min-width: 250px;\n position: relative;\n}\n.search-container .search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n}\n.search-container .search-input {\n width: 100%;\n padding: 0.75rem 1rem 0.75rem 2.75rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n}\n.search-container .search-input:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n.filter-group .filter-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: #374151;\n}\n.filter-group .filter-buttons {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n.filter-group .filter-btn {\n padding: 0.5rem 1rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group .filter-btn:hover {\n color: #374151;\n}\n.filter-group .filter-btn.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.filter-group .filter-select {\n padding: 0.625rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n font-size: 0.875rem;\n color: #374151;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group .filter-select:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.view-toggle {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n.view-toggle .view-btn {\n padding: 0.5rem 0.75rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.view-toggle .view-btn:hover {\n color: #374151;\n}\n.view-toggle .view-btn.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.content-area {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n padding: 2rem;\n background: white;\n}\n@media (max-width: 768px) {\n .content-area {\n padding: 1rem;\n }\n}\n\n.users-table {\n width: 100%;\n overflow-x: auto;\n}\n\n.modern-table {\n width: 100%;\n border-collapse: collapse;\n}\n.modern-table thead {\n background: #f9fafb;\n border-bottom: 1px solid #e5e7eb;\n}\n.modern-table thead th {\n padding: 1rem;\n text-align: left;\n font-size: 0.875rem;\n font-weight: 600;\n color: #374151;\n white-space: nowrap;\n}\n.modern-table thead th.th-checkbox {\n width: 50px;\n}\n.modern-table thead th.th-actions {\n text-align: center;\n width: 150px;\n}\n.modern-table tbody tr {\n border-bottom: 1px solid #f3f4f6;\n transition: background-color 0.2s;\n cursor: pointer;\n}\n.modern-table tbody tr:hover {\n background-color: #f9fafb;\n}\n.modern-table tbody td {\n padding: 1rem;\n font-size: 0.875rem;\n color: #374151;\n}\n.modern-table tbody td.td-checkbox {\n width: 50px;\n}\n.modern-table tbody td.td-actions {\n text-align: center;\n}\n\n.checkbox {\n width: 18px;\n height: 18px;\n cursor: pointer;\n}\n\n.user-cell {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.user-avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 0.875rem;\n}\n\n.user-avatar-large {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 1.5rem;\n margin: 0 auto 1rem;\n}\n\n.user-info .user-name {\n font-weight: 600;\n color: #1f2937;\n}\n.user-info .user-fullname {\n font-size: 0.75rem;\n color: #6b7280;\n}\n\n.user-type {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n color: #4b5563;\n}\n.user-type i {\n font-size: 0.875rem;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.25rem 0.75rem;\n border-radius: 20px;\n font-size: 0.75rem;\n font-weight: 500;\n}\n.status-badge.status-active {\n background: rgba(76, 175, 80, 0.1);\n color: #388e3c;\n}\n.status-badge.status-inactive {\n background: rgba(244, 67, 54, 0.1);\n color: #d32f2f;\n}\n.status-badge i {\n font-size: 0.625rem;\n}\n\n.last-login {\n color: #6b7280;\n font-size: 0.875rem;\n}\n\n.action-btn {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.action-btn:hover {\n background: #f3f4f6;\n color: #2196f3;\n}\n.action-btn-danger:hover {\n color: #f44336;\n}\n\n.users-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 1.5rem;\n padding: 1.5rem;\n}\n@media (max-width: 768px) {\n .users-grid {\n grid-template-columns: 1fr;\n gap: 1rem;\n padding: 1rem;\n }\n}\n\n.user-card {\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n padding: 1.5rem;\n cursor: pointer;\n transition: all 0.3s ease;\n}\n.user-card:hover {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);\n transform: translateY(-2px);\n border-color: #2196f3;\n}\n\n.card-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 1rem;\n}\n\n.card-actions {\n display: flex;\n gap: 0.5rem;\n}\n\n.card-body {\n text-align: center;\n}\n.card-body .user-name {\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n}\n.card-body .user-fullname {\n color: #6b7280;\n margin: 0 0 0.75rem 0;\n}\n.card-body .user-email {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n color: #4b5563;\n font-size: 0.875rem;\n margin-bottom: 1rem;\n}\n.card-body .user-email i {\n color: #6b7280;\n}\n\n.card-meta {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 1rem;\n padding: 1rem 0;\n border-top: 1px solid #f3f4f6;\n border-bottom: 1px solid #f3f4f6;\n margin-bottom: 1rem;\n}\n.card-meta .meta-item {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n color: #4b5563;\n font-size: 0.875rem;\n}\n\n.card-footer .last-login {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n color: #6b7280;\n font-size: 0.75rem;\n}\n.card-footer .last-login i {\n font-size: 0.875rem;\n}\n\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n.empty-state .empty-icon {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n}\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n}\n.empty-state .empty-subtext {\n color: #6b7280;\n margin: 0;\n}\n\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n.loading-spinner {\n position: relative;\n width: 60px;\n height: 60px;\n margin-bottom: 1rem;\n}\n.loading-spinner .spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n}\n.loading-spinner .spinner-ring:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner .spinner-ring:nth-child(2) {\n border-color: transparent #4caf50 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner .spinner-ring:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n.error-container .error-icon {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n}\n.error-container .error-message {\n color: #374151;\n margin-bottom: 1.5rem;\n}\n.error-container .retry-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.error-container .retry-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.error-container .retry-button i {\n font-size: 0.875rem;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n.modal-dialog {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s ease;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid #e5e7eb;\n}\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0;\n}\n.modal-header .modal-close {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.modal-header .modal-close:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n.modal-body {\n padding: 1.5rem;\n}\n.modal-body p {\n margin: 0 0 1rem 0;\n color: #374151;\n}\n.modal-body p:last-child {\n margin-bottom: 0;\n}\n.modal-body .text-muted {\n color: #6b7280;\n font-size: 0.875rem;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n.text-danger {\n color: #f44336;\n}\n"] }]
764
764
  }], () => [], null); })();
765
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserManagementComponent, { className: "UserManagementComponent" }); })();
765
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserManagementComponent, { className: "UserManagementComponent", filePath: "src/lib/user-management/user-management.component.ts", lineNumber: 29 }); })();
766
766
  //# sourceMappingURL=user-management.component.js.map
@@ -690,5 +690,5 @@ export class UserProfileSettingsComponent {
690
690
  type: Component,
691
691
  args: [{ selector: 'mj-user-profile-settings', template: "<div class=\"user-profile-settings\">\n <div class=\"profile-header\">\n <h3>Avatar Settings</h3>\n <p class=\"description\">Customize your profile picture with an image, URL, or icon</p>\n </div>\n\n <!-- Error Message -->\n @if (errorMessage) {\n <div class=\"alert alert-error\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ errorMessage }}</span>\n <button class=\"close-btn\" (click)=\"errorMessage = ''\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n\n <!-- Success Message -->\n @if (showSuccessMessage) {\n <div class=\"alert alert-success\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>Avatar updated successfully!</span>\n </div>\n }\n\n <!-- Preview Section -->\n <div class=\"avatar-preview-section\">\n <div class=\"preview-label\">Preview</div>\n <div class=\"preview-container\">\n @if (previewUrl) {\n <img [src]=\"previewUrl\" alt=\"Avatar preview\" class=\"preview-image\" />\n } @else if (previewIconClass) {\n <div class=\"preview-icon-wrapper\">\n <i [class]=\"previewIconClass + ' preview-icon'\"></i>\n </div>\n } @else {\n <div class=\"preview-placeholder\">\n <i class=\"fa-solid fa-user\"></i>\n <span>No avatar selected</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tab-navigation\">\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'upload'\"\n (click)=\"selectTab('upload')\"\n >\n <i class=\"fa-solid fa-upload\"></i>\n <span>Upload</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'url'\"\n (click)=\"selectTab('url')\"\n >\n <i class=\"fa-solid fa-link\"></i>\n <span>URL</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'icon'\"\n (click)=\"selectTab('icon')\"\n >\n <i class=\"fa-solid fa-icons\"></i>\n <span>Icon</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'provider'\"\n (click)=\"selectTab('provider')\"\n >\n <i class=\"fa-brands fa-microsoft\"></i>\n <span>Sync</span>\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Upload Tab -->\n @if (selectedTab === 'upload') {\n <div class=\"upload-section\">\n <input\n type=\"file\"\n #fileInput\n accept=\"image/png,image/jpeg,image/jpg,image/gif,image/webp\"\n (change)=\"onFileSelected($event)\"\n style=\"display: none\"\n />\n\n <button class=\"upload-btn\" (click)=\"fileInput.click()\">\n <i class=\"fa-solid fa-upload\"></i>\n Choose Image\n </button>\n\n <div class=\"upload-info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Max 200KB \u2022 PNG, JPG, GIF, WEBP\n </div>\n\n @if (uploadedFileName) {\n <div class=\"selected-file\">\n <i class=\"fa-solid fa-file-image\"></i>\n <span>{{ uploadedFileName }}</span>\n <button class=\"remove-btn\" (click)=\"clearUpload()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n </div>\n }\n\n <!-- URL Tab -->\n @if (selectedTab === 'url') {\n <div class=\"url-section\">\n <label for=\"imageUrl\">Image URL</label>\n <input\n type=\"text\"\n id=\"imageUrl\"\n class=\"url-input\"\n placeholder=\"https://example.com/avatar.jpg\"\n [(ngModel)]=\"imageUrlInput\"\n (input)=\"onUrlChange()\"\n />\n <div class=\"url-info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Enter a URL to an image hosted online\n </div>\n </div>\n }\n\n <!-- Icon Tab -->\n @if (selectedTab === 'icon') {\n <div class=\"icon-section\">\n @for (category of iconCategories; track category.name) {\n <div class=\"icon-category\">\n <h4 class=\"category-title\">{{ category.name }}</h4>\n <div class=\"icon-grid\">\n @for (icon of category.icons; track icon) {\n <button\n class=\"icon-option\"\n [class.selected]=\"isIconSelected(icon)\"\n (click)=\"selectIcon(icon)\"\n [title]=\"icon\"\n >\n <i [class]=\"icon\"></i>\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Provider Sync Tab -->\n @if (selectedTab === 'provider') {\n <div class=\"provider-section\">\n <div class=\"provider-info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>Sync your avatar from your authentication provider account</p>\n </div>\n\n <button\n class=\"sync-btn\"\n (click)=\"syncFromProvider()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-brands fa-microsoft\"></i>\n @if (isSaving) {\n <span>Syncing...</span>\n } @else {\n <span>Sync from Microsoft Account</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <small>This will download your profile photo from Microsoft and save it to your profile</small>\n </div>\n\n <div style=\"border-top: 1px solid #ddd; width: 100%; max-width: 500px; margin: 1rem 0;\"></div>\n\n <button\n class=\"revert-btn\"\n (click)=\"revertToDefault()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-solid fa-rotate-left\"></i>\n @if (isSaving) {\n <span>Reverting...</span>\n } @else {\n <span>Revert to Default</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <small>Clears your avatar settings and restores the automatic sync from your auth provider</small>\n </div>\n </div>\n }\n </div>\n\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button\n class=\"btn btn-secondary\"\n (click)=\"cancel()\"\n [disabled]=\"isSaving\"\n >\n Cancel\n </button>\n <button\n class=\"btn btn-primary\"\n (click)=\"save()\"\n [disabled]=\"isSaving || selectedTab === 'provider'\"\n >\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Saving...</span>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n <span>Save Changes</span>\n }\n </button>\n </div>\n</div>\n", styles: [".user-profile-settings {\n max-width: 800px;\n margin: 0 auto;\n padding: 1.5rem;\n}\n\n.user-profile-settings .profile-header {\n margin-bottom: 1.5rem;\n}\n\n.user-profile-settings .profile-header h3 {\n margin: 0 0 0.5rem 0;\n font-size: 1.5rem;\n font-weight: 600;\n color: #1a1a1a;\n}\n\n.user-profile-settings .profile-header .description {\n margin: 0;\n color: #666;\n font-size: 0.9rem;\n}\n\n/* Alert Messages */\n.user-profile-settings .alert {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n border-radius: 6px;\n margin-bottom: 1rem;\n font-size: 0.9rem;\n}\n\n.user-profile-settings .alert i {\n flex-shrink: 0;\n}\n\n.user-profile-settings .alert span {\n flex: 1;\n}\n\n.user-profile-settings .alert .close-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n color: inherit;\n opacity: 0.7;\n transition: opacity 0.2s;\n}\n\n.user-profile-settings .alert .close-btn:hover {\n opacity: 1;\n}\n\n.user-profile-settings .alert.alert-error {\n background-color: #fee;\n border: 1px solid #fcc;\n color: #c33;\n}\n\n.user-profile-settings .alert.alert-success {\n background-color: #efe;\n border: 1px solid #cfc;\n color: #3c3;\n}\n\n/* Avatar Preview */\n.user-profile-settings .avatar-preview-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: #f8f9fa;\n border-radius: 8px;\n}\n\n.user-profile-settings .avatar-preview-section .preview-label {\n font-size: 0.85rem;\n font-weight: 600;\n color: #666;\n margin-bottom: 1rem;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container {\n width: 120px;\n height: 120px;\n border-radius: 50%;\n overflow: hidden;\n background: white;\n border: 3px solid #e0e0e0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-image {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-icon-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-icon-wrapper .preview-icon {\n font-size: 3.5rem;\n color: #666;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: #999;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-placeholder i {\n font-size: 2.5rem;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-placeholder span {\n font-size: 0.75rem;\n}\n\n/* Tab Navigation */\n.user-profile-settings .tab-navigation {\n display: flex;\n gap: 0.5rem;\n margin-bottom: 1.5rem;\n border-bottom: 2px solid #e0e0e0;\n}\n\n.user-profile-settings .tab-navigation .tab-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: none;\n border: none;\n border-bottom: 3px solid transparent;\n cursor: pointer;\n font-size: 0.9rem;\n font-weight: 500;\n color: #666;\n transition: all 0.2s;\n margin-bottom: -2px;\n}\n\n.user-profile-settings .tab-navigation .tab-btn i {\n font-size: 1rem;\n}\n\n.user-profile-settings .tab-navigation .tab-btn:hover {\n color: #333;\n background: #f8f9fa;\n}\n\n.user-profile-settings .tab-navigation .tab-btn.active {\n color: #007bff;\n border-bottom-color: #007bff;\n background: #f8f9fa;\n}\n\n/* Tab Content */\n.user-profile-settings .tab-content {\n min-height: 300px;\n padding: 1.5rem;\n background: #f8f9fa;\n border-radius: 8px;\n margin-bottom: 1.5rem;\n}\n\n/* Upload Section */\n.user-profile-settings .upload-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.user-profile-settings .upload-section .upload-btn {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: #007bff;\n color: white;\n border: none;\n border-radius: 6px;\n font-size: 0.95rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.user-profile-settings .upload-section .upload-btn:hover {\n background: #0056b3;\n}\n\n.user-profile-settings .upload-section .upload-btn i {\n font-size: 1rem;\n}\n\n.user-profile-settings .upload-section .upload-info {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: #666;\n font-size: 0.85rem;\n}\n\n.user-profile-settings .upload-section .upload-info i {\n color: #007bff;\n}\n\n.user-profile-settings .upload-section .selected-file {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: white;\n border: 1px solid #ddd;\n border-radius: 6px;\n width: 100%;\n max-width: 400px;\n}\n\n.user-profile-settings .upload-section .selected-file i {\n color: #007bff;\n font-size: 1.2rem;\n}\n\n.user-profile-settings .upload-section .selected-file span {\n flex: 1;\n font-size: 0.9rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.user-profile-settings .upload-section .selected-file .remove-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n color: #999;\n transition: color 0.2s;\n}\n\n.user-profile-settings .upload-section .selected-file .remove-btn:hover {\n color: #c33;\n}\n\n.user-profile-settings .upload-section .selected-file .remove-btn i {\n font-size: 1rem;\n color: inherit;\n}\n\n/* URL Section */\n.user-profile-settings .url-section {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.user-profile-settings .url-section label {\n font-weight: 600;\n color: #333;\n font-size: 0.9rem;\n}\n\n.user-profile-settings .url-section .url-input {\n padding: 0.75rem;\n border: 1px solid #ddd;\n border-radius: 6px;\n font-size: 0.95rem;\n transition: border-color 0.2s;\n}\n\n.user-profile-settings .url-section .url-input:focus {\n outline: none;\n border-color: #007bff;\n}\n\n.user-profile-settings .url-section .url-info {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: #666;\n font-size: 0.85rem;\n}\n\n.user-profile-settings .url-section .url-info i {\n color: #007bff;\n}\n\n/* Icon Section */\n.user-profile-settings .icon-section {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n max-height: 400px;\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n\n.user-profile-settings .icon-section .icon-category .category-title {\n font-size: 0.9rem;\n font-weight: 600;\n color: #333;\n margin: 0 0 0.75rem 0;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid #ddd;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));\n gap: 0.5rem;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.75rem;\n background: white;\n border: 2px solid #ddd;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option i {\n font-size: 1.5rem;\n color: #666;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option:hover {\n border-color: #007bff;\n background: #f0f8ff;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option:hover i {\n color: #007bff;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option.selected {\n border-color: #007bff;\n background: #007bff;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option.selected i {\n color: white;\n}\n\n/* Custom scrollbar */\n.user-profile-settings .icon-section::-webkit-scrollbar {\n width: 6px;\n}\n\n.user-profile-settings .icon-section::-webkit-scrollbar-track {\n background: #f1f1f1;\n border-radius: 3px;\n}\n\n.user-profile-settings .icon-section::-webkit-scrollbar-thumb {\n background: #ccc;\n border-radius: 3px;\n}\n\n.user-profile-settings .icon-section::-webkit-scrollbar-thumb:hover {\n background: #999;\n}\n\n/* Provider Section */\n.user-profile-settings .provider-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1.5rem;\n padding: 2rem 1rem;\n}\n\n.user-profile-settings .provider-section .provider-info {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n background: white;\n border: 1px solid #ddd;\n border-radius: 6px;\n width: 100%;\n max-width: 500px;\n}\n\n.user-profile-settings .provider-section .provider-info i {\n color: #007bff;\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.user-profile-settings .provider-section .provider-info p {\n margin: 0;\n color: #666;\n font-size: 0.9rem;\n}\n\n.user-profile-settings .provider-section .sync-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem 2rem;\n background: #0078d4;\n color: white;\n border: none;\n border-radius: 6px;\n font-size: 1rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.user-profile-settings .provider-section .sync-btn:hover:not(:disabled) {\n background: #005a9e;\n}\n\n.user-profile-settings .provider-section .sync-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.user-profile-settings .provider-section .sync-btn i {\n font-size: 1.2rem;\n}\n\n.user-profile-settings .provider-section .provider-note {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n color: #666;\n font-size: 0.85rem;\n max-width: 500px;\n text-align: center;\n}\n\n.user-profile-settings .provider-section .provider-note i {\n color: #ffc107;\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.user-profile-settings .provider-section .revert-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem;\n background: #6c757d;\n color: white;\n border: none;\n border-radius: 6px;\n font-size: 0.95rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.user-profile-settings .provider-section .revert-btn:hover:not(:disabled) {\n background: #5a6268;\n}\n\n.user-profile-settings .provider-section .revert-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.user-profile-settings .provider-section .revert-btn i {\n font-size: 1rem;\n}\n\n/* Action Buttons */\n.user-profile-settings .action-buttons {\n display: flex;\n gap: 1rem;\n justify-content: flex-end;\n padding-top: 1rem;\n border-top: 1px solid #e0e0e0;\n}\n\n.user-profile-settings .action-buttons .btn {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n border: none;\n border-radius: 6px;\n font-size: 0.95rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.user-profile-settings .action-buttons .btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.user-profile-settings .action-buttons .btn i {\n font-size: 0.9rem;\n}\n\n.user-profile-settings .action-buttons .btn i.fa-spin {\n animation: spin 1s linear infinite;\n}\n\n.user-profile-settings .action-buttons .btn.btn-secondary {\n background: #6c757d;\n color: white;\n}\n\n.user-profile-settings .action-buttons .btn.btn-secondary:hover:not(:disabled) {\n background: #5a6268;\n}\n\n.user-profile-settings .action-buttons .btn.btn-primary {\n background: #28a745;\n color: white;\n}\n\n.user-profile-settings .action-buttons .btn.btn-primary:hover:not(:disabled) {\n background: #218838;\n}\n\n@keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .user-profile-settings {\n padding: 1rem;\n }\n\n .user-profile-settings .tab-navigation .tab-btn {\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n font-size: 0.75rem;\n }\n\n .user-profile-settings .tab-navigation .tab-btn i {\n font-size: 1.2rem;\n }\n\n .user-profile-settings .tab-navigation .tab-btn span {\n font-size: 0.7rem;\n }\n\n .user-profile-settings .icon-section .icon-category .icon-grid {\n grid-template-columns: repeat(auto-fill, minmax(45px, 1fr));\n }\n\n .user-profile-settings .action-buttons {\n flex-direction: column-reverse;\n }\n\n .user-profile-settings .action-buttons .btn {\n width: 100%;\n justify-content: center;\n }\n}\n"] }]
692
692
  }], () => [{ type: i1.UserAvatarService }, { type: i2.SharedService }], null); })();
693
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserProfileSettingsComponent, { className: "UserProfileSettingsComponent" }); })();
693
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserProfileSettingsComponent, { className: "UserProfileSettingsComponent", filePath: "src/lib/user-profile-settings/user-profile-settings.component.ts", lineNumber: 20 }); })();
694
694
  //# sourceMappingURL=user-profile-settings.component.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-explorer-settings",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "MemberJunction: Reusable Angular components for the settings section of the MJ Explorer App",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -25,25 +25,25 @@
25
25
  "@angular/router": "18.2.14"
26
26
  },
27
27
  "dependencies": {
28
- "@memberjunction/core": "3.0.0",
29
- "@memberjunction/core-entities": "3.0.0",
30
- "@memberjunction/global": "3.0.0",
31
- "@memberjunction/graphql-dataprovider": "3.0.0",
32
- "@memberjunction/ng-base-application": "3.0.0",
33
- "@memberjunction/ng-base-forms": "3.0.0",
34
- "@memberjunction/ng-code-editor": "3.0.0",
35
- "@memberjunction/ng-compare-records": "3.0.0",
36
- "@memberjunction/ng-container-directives": "3.0.0",
37
- "@memberjunction/ng-entity-form-dialog": "3.0.0",
38
- "@memberjunction/ng-entity-permissions": "3.0.0",
39
- "@memberjunction/ng-join-grid": "3.0.0",
40
- "@memberjunction/ng-notifications": "3.0.0",
41
- "@memberjunction/ng-shared": "3.0.0",
42
- "@memberjunction/ng-shared-generic": "3.0.0",
43
- "@memberjunction/ng-simple-record-list": "3.0.0",
44
- "@memberjunction/ng-tabstrip": "3.0.0",
45
- "@memberjunction/ng-user-avatar": "3.0.0",
46
- "@memberjunction/ng-user-view-grid": "3.0.0",
28
+ "@memberjunction/core": "3.1.0",
29
+ "@memberjunction/core-entities": "3.1.0",
30
+ "@memberjunction/global": "3.1.0",
31
+ "@memberjunction/graphql-dataprovider": "3.1.0",
32
+ "@memberjunction/ng-base-application": "3.1.0",
33
+ "@memberjunction/ng-base-forms": "3.1.0",
34
+ "@memberjunction/ng-code-editor": "3.1.0",
35
+ "@memberjunction/ng-compare-records": "3.1.0",
36
+ "@memberjunction/ng-container-directives": "3.1.0",
37
+ "@memberjunction/ng-entity-form-dialog": "3.1.0",
38
+ "@memberjunction/ng-entity-permissions": "3.1.0",
39
+ "@memberjunction/ng-join-grid": "3.1.0",
40
+ "@memberjunction/ng-notifications": "3.1.0",
41
+ "@memberjunction/ng-shared": "3.1.0",
42
+ "@memberjunction/ng-shared-generic": "3.1.0",
43
+ "@memberjunction/ng-simple-record-list": "3.1.0",
44
+ "@memberjunction/ng-tabstrip": "3.1.0",
45
+ "@memberjunction/ng-user-avatar": "3.1.0",
46
+ "@memberjunction/ng-user-view-grid": "3.1.0",
47
47
  "@progress/kendo-angular-buttons": "16.2.0",
48
48
  "@progress/kendo-angular-dialog": "16.2.0",
49
49
  "@progress/kendo-angular-dropdowns": "16.2.0",
@@ -1,27 +0,0 @@
1
- import { TemplateRef } from '@angular/core';
2
- import * as i0 from "@angular/core";
3
- /**
4
- * A reusable settings card component providing consistent styling and layout
5
- * across all settings sections. Follows the modern AI dashboard design patterns.
6
- */
7
- export declare class SettingsCardComponent {
8
- /** Card title displayed in the header */
9
- title?: string;
10
- /** Card subtitle displayed below the title */
11
- subtitle?: string;
12
- /** Whether to use floating card style (higher elevation) */
13
- floating: boolean;
14
- /** Card size variant */
15
- size: 'sm' | 'md' | 'lg';
16
- /** Whether to remove padding from content area */
17
- noPadding: boolean;
18
- /** Template for custom header content */
19
- headerTemplate?: TemplateRef<any>;
20
- /** Template for header action buttons */
21
- actionTemplate?: TemplateRef<any>;
22
- /** Template for footer content */
23
- footerTemplate?: TemplateRef<any>;
24
- static ɵfac: i0.ɵɵFactoryDeclaration<SettingsCardComponent, never>;
25
- static ɵcmp: i0.ɵɵComponentDeclaration<SettingsCardComponent, "mj-settings-card", never, { "title": { "alias": "title"; "required": false; }; "subtitle": { "alias": "subtitle"; "required": false; }; "floating": { "alias": "floating"; "required": false; }; "size": { "alias": "size"; "required": false; }; "noPadding": { "alias": "noPadding"; "required": false; }; "headerTemplate": { "alias": "headerTemplate"; "required": false; }; "actionTemplate": { "alias": "actionTemplate"; "required": false; }; "footerTemplate": { "alias": "footerTemplate"; "required": false; }; }, {}, never, ["*"], true, never>;
26
- }
27
- //# sourceMappingURL=settings-card.component.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"settings-card.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shared/components/settings-card/settings-card.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,WAAW,EAAE,MAAM,eAAe,CAAC;;AAG9D;;;GAGG;AACH,qBA0Ca,qBAAqB;IAChC,yCAAyC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IAExB,8CAA8C;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,4DAA4D;IACnD,QAAQ,UAAS;IAE1B,wBAAwB;IACf,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAEzC,kDAAkD;IACzC,SAAS,UAAS;IAE3B,yCAAyC;IAChC,cAAc,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC;IAE3C,yCAAyC;IAChC,cAAc,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC;IAE3C,kCAAkC;IACzB,cAAc,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC;yCAvBhC,qBAAqB;2CAArB,qBAAqB;CAwBjC"}
@@ -1,170 +0,0 @@
1
- import { Component, Input } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import * as i0 from "@angular/core";
4
- import * as i1 from "@angular/common";
5
- const _c0 = ["*"];
6
- function SettingsCardComponent_Conditional_1_Conditional_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
7
- i0.ɵɵelementContainer(0);
8
- } }
9
- function SettingsCardComponent_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
10
- i0.ɵɵtemplate(0, SettingsCardComponent_Conditional_1_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 4);
11
- } if (rf & 2) {
12
- const ctx_r0 = i0.ɵɵnextContext(2);
13
- i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.headerTemplate);
14
- } }
15
- function SettingsCardComponent_Conditional_1_Conditional_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
16
- i0.ɵɵelementStart(0, "p", 7);
17
- i0.ɵɵtext(1);
18
- i0.ɵɵelementEnd();
19
- } if (rf & 2) {
20
- const ctx_r0 = i0.ɵɵnextContext(3);
21
- i0.ɵɵadvance();
22
- i0.ɵɵtextInterpolate(ctx_r0.subtitle);
23
- } }
24
- function SettingsCardComponent_Conditional_1_Conditional_2_Conditional_4_ng_container_1_Template(rf, ctx) { if (rf & 1) {
25
- i0.ɵɵelementContainer(0);
26
- } }
27
- function SettingsCardComponent_Conditional_1_Conditional_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
28
- i0.ɵɵelementStart(0, "div", 8);
29
- i0.ɵɵtemplate(1, SettingsCardComponent_Conditional_1_Conditional_2_Conditional_4_ng_container_1_Template, 1, 0, "ng-container", 4);
30
- i0.ɵɵelementEnd();
31
- } if (rf & 2) {
32
- const ctx_r0 = i0.ɵɵnextContext(3);
33
- i0.ɵɵadvance();
34
- i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.actionTemplate);
35
- } }
36
- function SettingsCardComponent_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
37
- i0.ɵɵelementStart(0, "div", 5)(1, "h3", 6);
38
- i0.ɵɵtext(2);
39
- i0.ɵɵelementEnd();
40
- i0.ɵɵtemplate(3, SettingsCardComponent_Conditional_1_Conditional_2_Conditional_3_Template, 2, 1, "p", 7);
41
- i0.ɵɵelementEnd();
42
- i0.ɵɵtemplate(4, SettingsCardComponent_Conditional_1_Conditional_2_Conditional_4_Template, 2, 1, "div", 8);
43
- } if (rf & 2) {
44
- const ctx_r0 = i0.ɵɵnextContext(2);
45
- i0.ɵɵadvance(2);
46
- i0.ɵɵtextInterpolate(ctx_r0.title);
47
- i0.ɵɵadvance();
48
- i0.ɵɵconditional(ctx_r0.subtitle ? 3 : -1);
49
- i0.ɵɵadvance();
50
- i0.ɵɵconditional(ctx_r0.actionTemplate ? 4 : -1);
51
- } }
52
- function SettingsCardComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
53
- i0.ɵɵelementStart(0, "div", 1);
54
- i0.ɵɵtemplate(1, SettingsCardComponent_Conditional_1_Conditional_1_Template, 1, 1, "ng-container")(2, SettingsCardComponent_Conditional_1_Conditional_2_Template, 5, 3);
55
- i0.ɵɵelementEnd();
56
- } if (rf & 2) {
57
- const ctx_r0 = i0.ɵɵnextContext();
58
- i0.ɵɵadvance();
59
- i0.ɵɵconditional(ctx_r0.headerTemplate ? 1 : 2);
60
- } }
61
- function SettingsCardComponent_Conditional_4_ng_container_1_Template(rf, ctx) { if (rf & 1) {
62
- i0.ɵɵelementContainer(0);
63
- } }
64
- function SettingsCardComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
65
- i0.ɵɵelementStart(0, "div", 3);
66
- i0.ɵɵtemplate(1, SettingsCardComponent_Conditional_4_ng_container_1_Template, 1, 0, "ng-container", 4);
67
- i0.ɵɵelementEnd();
68
- } if (rf & 2) {
69
- const ctx_r0 = i0.ɵɵnextContext();
70
- i0.ɵɵadvance();
71
- i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.footerTemplate);
72
- } }
73
- /**
74
- * A reusable settings card component providing consistent styling and layout
75
- * across all settings sections. Follows the modern AI dashboard design patterns.
76
- */
77
- export class SettingsCardComponent {
78
- /** Card title displayed in the header */
79
- title;
80
- /** Card subtitle displayed below the title */
81
- subtitle;
82
- /** Whether to use floating card style (higher elevation) */
83
- floating = false;
84
- /** Card size variant */
85
- size = 'md';
86
- /** Whether to remove padding from content area */
87
- noPadding = false;
88
- /** Template for custom header content */
89
- headerTemplate;
90
- /** Template for header action buttons */
91
- actionTemplate;
92
- /** Template for footer content */
93
- footerTemplate;
94
- static ɵfac = function SettingsCardComponent_Factory(t) { return new (t || SettingsCardComponent)(); };
95
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SettingsCardComponent, selectors: [["mj-settings-card"]], inputs: { title: "title", subtitle: "subtitle", floating: "floating", size: "size", noPadding: "noPadding", headerTemplate: "headerTemplate", actionTemplate: "actionTemplate", footerTemplate: "footerTemplate" }, standalone: true, features: [i0.ɵɵStandaloneFeature], ngContentSelectors: _c0, decls: 5, vars: 10, consts: [[1, "mj-card"], [1, "mj-card-header"], [1, "mj-card-body"], [1, "mj-card-footer"], [4, "ngTemplateOutlet"], [1, "header-content"], [1, "card-title"], [1, "card-subtitle"], [1, "mj-card-actions"]], template: function SettingsCardComponent_Template(rf, ctx) { if (rf & 1) {
96
- i0.ɵɵprojectionDef();
97
- i0.ɵɵelementStart(0, "div", 0);
98
- i0.ɵɵtemplate(1, SettingsCardComponent_Conditional_1_Template, 3, 1, "div", 1);
99
- i0.ɵɵelementStart(2, "div", 2);
100
- i0.ɵɵprojection(3);
101
- i0.ɵɵelementEnd();
102
- i0.ɵɵtemplate(4, SettingsCardComponent_Conditional_4_Template, 2, 1, "div", 3);
103
- i0.ɵɵelementEnd();
104
- } if (rf & 2) {
105
- i0.ɵɵclassProp("mj-card-floating", ctx.floating)("mj-card-sm", ctx.size === "sm")("mj-card-lg", ctx.size === "lg");
106
- i0.ɵɵadvance();
107
- i0.ɵɵconditional(ctx.title || ctx.headerTemplate ? 1 : -1);
108
- i0.ɵɵadvance();
109
- i0.ɵɵclassProp("no-padding", ctx.noPadding);
110
- i0.ɵɵadvance(2);
111
- i0.ɵɵconditional(ctx.footerTemplate ? 4 : -1);
112
- } }, dependencies: [CommonModule, i1.NgTemplateOutlet], styles: ["@keyframes _ngcontent-%COMP%_shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n[_nghost-%COMP%] {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n font-size: 14px;\n line-height: 1.4;\n color: #212121;\n}\n[_nghost-%COMP%] *[_ngcontent-%COMP%] {\n box-sizing: border-box;\n}\n\n.settings-card[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 20px;\n}\n.settings-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.settings-card-floating[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n padding: 20px;\n}\n.settings-card-floating[_ngcontent-%COMP%]:hover {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-2px);\n}\n\n.settings-card-sm[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 16px;\n}\n.settings-card-sm[_ngcontent-%COMP%]:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.settings-card-lg[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 24px;\n}\n.settings-card-lg[_ngcontent-%COMP%]:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.dashboard-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding: 24px 0 16px 0;\n}\n.dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 16px;\n}\n.dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%], .dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] h2[_ngcontent-%COMP%], .dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-weight: 600;\n color: #212121;\n font-size: 24px;\n line-height: 1.2;\n}\n.dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n.dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n.dashboard-header[_ngcontent-%COMP%] .header-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n}\n.section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .section-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n font-weight: 500;\n color: #212121;\n font-size: 16px;\n}\n.section-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.control-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #ffffff;\n color: #212121;\n border-color: #bdbdbd;\n}\n.control-btn[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.control-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f8f9fa;\n border-color: #2196f3;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #2196f3;\n color: #ffffff;\n border-color: #2196f3;\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #1976d2;\n border-color: #1976d2;\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.2);\n transform: translateY(-1px);\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%]:active {\n transform: translateY(0);\n}\n.control-btn.control-btn-danger[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #f44336;\n color: #ffffff;\n border-color: #f44336;\n}\n.control-btn.control-btn-danger[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-danger[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.control-btn.control-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #ea1c0d;\n border-color: #ea1c0d;\n box-shadow: 0 2px 8px rgba(244, 67, 54, 0.3);\n transform: translateY(-1px);\n}\n.control-btn.control-btn-ghost[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: transparent;\n color: #666666;\n border-color: transparent;\n}\n.control-btn.control-btn-ghost[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-ghost[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-ghost[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.control-btn.control-btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f8f9fa;\n color: #2196f3;\n}\n.control-btn.control-btn-sm[_ngcontent-%COMP%] {\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n}\n.control-btn.control-btn-sm[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n.control-btn.control-btn-lg[_ngcontent-%COMP%] {\n height: 44px;\n padding: 0 24px;\n font-size: 14px;\n}\n.control-btn.control-btn-lg[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: transparent;\n color: #666666;\n border-color: transparent;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f8f9fa;\n color: #2196f3;\n}\n.action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #2196f3;\n color: #ffffff;\n border-color: #2196f3;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #1976d2;\n border-color: #1976d2;\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.2);\n transform: translateY(-1px);\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%]:active {\n transform: translateY(0);\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #f44336;\n color: #ffffff;\n border-color: #f44336;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #ea1c0d;\n border-color: #ea1c0d;\n box-shadow: 0 2px 8px rgba(244, 67, 54, 0.3);\n transform: translateY(-1px);\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.info-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(33, 150, 243, 0.1);\n color: #1976d2;\n border: 1px solid rgba(33, 150, 243, 0.2);\n}\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(158, 158, 158, 0.1);\n color: #666666;\n border: 1px solid rgba(158, 158, 158, 0.2);\n}\n.status-badge.status-active[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(76, 175, 80, 0.1);\n color: #3d8b40;\n border: 1px solid rgba(76, 175, 80, 0.2);\n}\n.status-badge.status-migration[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(33, 150, 243, 0.1);\n color: #1976d2;\n border: 1px solid rgba(33, 150, 243, 0.2);\n}\n.status-badge.status-warning[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(255, 193, 7, 0.1);\n color: #6d5200;\n border: 1px solid rgba(255, 193, 7, 0.2);\n}\n.status-badge.status-error[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(244, 67, 54, 0.1);\n color: #ea1c0d;\n border: 1px solid rgba(244, 67, 54, 0.2);\n}\n\n.settings-nav[_ngcontent-%COMP%] {\n width: 220px;\n min-width: 220px;\n max-width: 220px;\n background: #ffffff;\n border-right: 1px solid #e0e0e0;\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow-y: auto;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n margin: 0 8px 4px 8px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 400;\n color: #666666;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n position: relative;\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%]::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 50%;\n transform: translateY(-50%);\n width: 3px;\n height: 0;\n background: #2196f3;\n border-radius: 0 2px 2px 0;\n transition: height all 0.15s ease;\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%]:hover {\n background: #f8f9fa;\n color: #2196f3;\n transform: translateX(2px);\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item.active[_ngcontent-%COMP%] {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n font-weight: 500;\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item.active[_ngcontent-%COMP%]::before {\n height: 24px;\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n width: 18px;\n text-align: center;\n}\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n.form-field[_ngcontent-%COMP%] .field-label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 4px;\n font-size: 12px;\n font-weight: 500;\n color: #212121;\n}\n.form-field[_ngcontent-%COMP%] .field-hint[_ngcontent-%COMP%] {\n margin-top: 4px;\n font-size: 11px;\n color: #9e9e9e;\n}\n.form-field[_ngcontent-%COMP%] .field-error[_ngcontent-%COMP%] {\n margin-top: 4px;\n font-size: 11px;\n color: #f44336;\n}\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%], .form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%], .form-field[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n width: 100%;\n height: 36px;\n padding: 0 8px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n background: #ffffff;\n color: #212121;\n transition: all 0.15s ease;\n outline: none;\n}\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder, .form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]::placeholder, .form-field[_ngcontent-%COMP%] select[_ngcontent-%COMP%]::placeholder {\n color: #9e9e9e;\n}\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:focus, .form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]:focus, .form-field[_ngcontent-%COMP%] select[_ngcontent-%COMP%]:focus {\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.2);\n}\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:disabled, .form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]:disabled, .form-field[_ngcontent-%COMP%] select[_ngcontent-%COMP%]:disabled {\n background: #f8f9fa;\n color: #bdbdbd;\n cursor: not-allowed;\n}\n\n.form-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n}\n.form-row[_ngcontent-%COMP%] .form-field[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.checkbox-field[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 16px;\n}\n.checkbox-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #212121;\n cursor: pointer;\n margin: 0;\n}\n\n.status-bar[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n padding: 16px;\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n margin-bottom: 16px;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] .status-label[_ngcontent-%COMP%] {\n color: #666666;\n font-weight: 500;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] .status-value[_ngcontent-%COMP%] {\n color: #212121;\n font-weight: 600;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] .status-value.text-success[_ngcontent-%COMP%] {\n color: #4caf50;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] .status-value.text-warning[_ngcontent-%COMP%] {\n color: #ffc107;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] .status-value.text-danger[_ngcontent-%COMP%] {\n color: #f44336;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n gap: 16px;\n padding: 48px;\n text-align: center;\n color: #666666;\n}\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n color: #9e9e9e;\n margin-bottom: 8px;\n}\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n color: #212121;\n}\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n max-width: 400px;\n line-height: 1.6;\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n gap: 16px;\n padding: 48px;\n}\n.loading-container[_ngcontent-%COMP%] .loading-spinner[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border: 3px solid #e0e0e0;\n border-top-color: #2196f3;\n border-radius: 50%;\n animation: _ngcontent-%COMP%_spin 1s linear infinite;\n}\n.loading-container[_ngcontent-%COMP%] .loading-text[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #666666;\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n to {\n transform: rotate(360deg);\n }\n}\n.text-success[_ngcontent-%COMP%] {\n color: #4caf50 !important;\n}\n\n.text-warning[_ngcontent-%COMP%] {\n color: #ffc107 !important;\n}\n\n.text-danger[_ngcontent-%COMP%] {\n color: #f44336 !important;\n}\n\n.text-info[_ngcontent-%COMP%] {\n color: #00bcd4 !important;\n}\n\n.text-muted[_ngcontent-%COMP%] {\n color: #9e9e9e !important;\n}\n\n.text-primary[_ngcontent-%COMP%] {\n color: #212121 !important;\n}\n\n.text-secondary[_ngcontent-%COMP%] {\n color: #666666 !important;\n}\n\n.mb-0[_ngcontent-%COMP%] {\n margin-bottom: 0 !important;\n}\n\n.mb-1[_ngcontent-%COMP%] {\n margin-bottom: 4px !important;\n}\n\n.mb-2[_ngcontent-%COMP%] {\n margin-bottom: 8px !important;\n}\n\n.mb-3[_ngcontent-%COMP%] {\n margin-bottom: 16px !important;\n}\n\n.mb-4[_ngcontent-%COMP%] {\n margin-bottom: 24px !important;\n}\n\n.mb-5[_ngcontent-%COMP%] {\n margin-bottom: 32px !important;\n}\n\n.mt-0[_ngcontent-%COMP%] {\n margin-top: 0 !important;\n}\n\n.mt-1[_ngcontent-%COMP%] {\n margin-top: 4px !important;\n}\n\n.mt-2[_ngcontent-%COMP%] {\n margin-top: 8px !important;\n}\n\n.mt-3[_ngcontent-%COMP%] {\n margin-top: 16px !important;\n}\n\n.mt-4[_ngcontent-%COMP%] {\n margin-top: 24px !important;\n}\n\n.mt-5[_ngcontent-%COMP%] {\n margin-top: 32px !important;\n}\n\n.d-flex[_ngcontent-%COMP%] {\n display: flex !important;\n}\n\n.d-block[_ngcontent-%COMP%] {\n display: block !important;\n}\n\n.d-inline-block[_ngcontent-%COMP%] {\n display: inline-block !important;\n}\n\n.d-none[_ngcontent-%COMP%] {\n display: none !important;\n}\n\n.flex-1[_ngcontent-%COMP%] {\n flex: 1 !important;\n}\n\n.flex-column[_ngcontent-%COMP%] {\n flex-direction: column !important;\n}\n\n.flex-row[_ngcontent-%COMP%] {\n flex-direction: row !important;\n}\n\n.align-center[_ngcontent-%COMP%] {\n align-items: center !important;\n}\n\n.justify-center[_ngcontent-%COMP%] {\n justify-content: center !important;\n}\n\n.justify-between[_ngcontent-%COMP%] {\n justify-content: space-between !important;\n}\n\n.stats-grid[_ngcontent-%COMP%] {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card[_ngcontent-%COMP%] {\n margin-right: 10px;\n}\n\n.role-card[_ngcontent-%COMP%] {\n margin-bottom: 5px;\n}\n\n@media (max-width: 768px) {\n .settings-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n .dashboard-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 16px;\n }\n .dashboard-header[_ngcontent-%COMP%] .header-controls[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: flex-start;\n }\n .form-row[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}\n[_nghost-%COMP%] {\n display: block;\n width: 100%;\n}\n\n.settings-card[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n.settings-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n.settings-card.settings-card-floating[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n}\n.settings-card.settings-card-floating[_ngcontent-%COMP%]:hover {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-2px);\n}\n.settings-card.settings-card-sm[_ngcontent-%COMP%] {\n padding: 16px;\n}\n.settings-card.settings-card-lg[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n padding: 24px 24px 16px 24px;\n margin: 0;\n}\n.card-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .card-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n font-weight: 500;\n color: #212121;\n font-size: 16px;\n}\n.card-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.card-header[_ngcontent-%COMP%] .header-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n.card-header[_ngcontent-%COMP%] .header-content[_ngcontent-%COMP%] .card-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #212121;\n line-height: 1.2;\n}\n.card-header[_ngcontent-%COMP%] .header-content[_ngcontent-%COMP%] .card-subtitle[_ngcontent-%COMP%] {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: #666666;\n line-height: 1.4;\n}\n.card-header[_ngcontent-%COMP%] .header-actions[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n gap: 8px;\n align-items: flex-start;\n}\n\n.card-content[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n padding: 0 24px 24px 24px;\n}\n.card-content.no-padding[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.card-footer[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 16px 24px 24px 24px;\n border-top: 1px solid #e0e0e0;\n background: #f8f9fa;\n border-radius: 0 0 8px 8px;\n}\n\n.settings-card-sm[_ngcontent-%COMP%] .card-header[_ngcontent-%COMP%] {\n padding: 16px 16px 8px 16px;\n}\n.settings-card-sm[_ngcontent-%COMP%] .card-header[_ngcontent-%COMP%] .card-title[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.settings-card-sm[_ngcontent-%COMP%] .card-header[_ngcontent-%COMP%] .card-subtitle[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n.settings-card-sm[_ngcontent-%COMP%] .card-content[_ngcontent-%COMP%] {\n padding: 0 16px 16px 16px;\n}\n.settings-card-sm[_ngcontent-%COMP%] .card-content.no-padding[_ngcontent-%COMP%] {\n padding: 0;\n}\n.settings-card-sm[_ngcontent-%COMP%] .card-footer[_ngcontent-%COMP%] {\n padding: 8px 16px 16px 16px;\n}\n\n.settings-card-lg[_ngcontent-%COMP%] .card-header[_ngcontent-%COMP%] {\n padding: 32px 32px 24px 32px;\n}\n.settings-card-lg[_ngcontent-%COMP%] .card-header[_ngcontent-%COMP%] .card-title[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n.settings-card-lg[_ngcontent-%COMP%] .card-content[_ngcontent-%COMP%] {\n padding: 0 32px 32px 32px;\n}\n.settings-card-lg[_ngcontent-%COMP%] .card-content.no-padding[_ngcontent-%COMP%] {\n padding: 0;\n}\n.settings-card-lg[_ngcontent-%COMP%] .card-footer[_ngcontent-%COMP%] {\n padding: 24px 32px 32px 32px;\n}"] });
113
- }
114
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SettingsCardComponent, [{
115
- type: Component,
116
- args: [{ selector: 'mj-settings-card', standalone: true, imports: [CommonModule], template: `
117
- <div class="mj-card"
118
- [class.mj-card-floating]="floating"
119
- [class.mj-card-sm]="size === 'sm'"
120
- [class.mj-card-lg]="size === 'lg'">
121
- @if (title || headerTemplate) {
122
- <div class="mj-card-header">
123
- @if (headerTemplate) {
124
- <ng-container *ngTemplateOutlet="headerTemplate"></ng-container>
125
- } @else {
126
- <div class="header-content">
127
- <h3 class="card-title">{{ title }}</h3>
128
- @if (subtitle) {
129
- <p class="card-subtitle">{{ subtitle }}</p>
130
- }
131
- </div>
132
- @if (actionTemplate) {
133
- <div class="mj-card-actions">
134
- <ng-container *ngTemplateOutlet="actionTemplate"></ng-container>
135
- </div>
136
- }
137
- }
138
- </div>
139
- }
140
-
141
- <div class="mj-card-body" [class.no-padding]="noPadding">
142
- <ng-content></ng-content>
143
- </div>
144
-
145
- @if (footerTemplate) {
146
- <div class="mj-card-footer">
147
- <ng-container *ngTemplateOutlet="footerTemplate"></ng-container>
148
- </div>
149
- }
150
- </div>
151
- `, styles: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n:host {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n font-size: 14px;\n line-height: 1.4;\n color: #212121;\n}\n:host * {\n box-sizing: border-box;\n}\n\n.settings-card {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 20px;\n}\n.settings-card:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.settings-card-floating {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n padding: 20px;\n}\n.settings-card-floating:hover {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-2px);\n}\n\n.settings-card-sm {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 16px;\n}\n.settings-card-sm:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.settings-card-lg {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 24px;\n}\n.settings-card-lg:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.dashboard-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding: 24px 0 16px 0;\n}\n.dashboard-header .header-info {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 16px;\n}\n.dashboard-header .header-info h1, .dashboard-header .header-info h2, .dashboard-header .header-info h3 {\n margin: 0;\n font-weight: 600;\n color: #212121;\n font-size: 24px;\n line-height: 1.2;\n}\n.dashboard-header .header-info h2 {\n font-size: 18px;\n}\n.dashboard-header .header-info h3 {\n font-size: 16px;\n}\n.dashboard-header .header-controls {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n}\n.section-header h3, .section-header h4 {\n margin: 0;\n font-weight: 500;\n color: #212121;\n font-size: 16px;\n}\n.section-header h4 {\n font-size: 14px;\n}\n\n.control-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #ffffff;\n color: #212121;\n border-color: #bdbdbd;\n}\n.control-btn:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn i {\n font-size: 14px;\n}\n.control-btn:hover:not(:disabled) {\n background: #f8f9fa;\n border-color: #2196f3;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n}\n.control-btn.control-btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #2196f3;\n color: #ffffff;\n border-color: #2196f3;\n}\n.control-btn.control-btn-primary:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-primary i {\n font-size: 14px;\n}\n.control-btn.control-btn-primary:hover:not(:disabled) {\n background: #1976d2;\n border-color: #1976d2;\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.2);\n transform: translateY(-1px);\n}\n.control-btn.control-btn-primary:active {\n transform: translateY(0);\n}\n.control-btn.control-btn-danger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #f44336;\n color: #ffffff;\n border-color: #f44336;\n}\n.control-btn.control-btn-danger:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-danger i {\n font-size: 14px;\n}\n.control-btn.control-btn-danger:hover:not(:disabled) {\n background: #ea1c0d;\n border-color: #ea1c0d;\n box-shadow: 0 2px 8px rgba(244, 67, 54, 0.3);\n transform: translateY(-1px);\n}\n.control-btn.control-btn-ghost {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: transparent;\n color: #666666;\n border-color: transparent;\n}\n.control-btn.control-btn-ghost:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-ghost:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-ghost i {\n font-size: 14px;\n}\n.control-btn.control-btn-ghost:hover:not(:disabled) {\n background: #f8f9fa;\n color: #2196f3;\n}\n.control-btn.control-btn-sm {\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n}\n.control-btn.control-btn-sm i {\n font-size: 12px;\n}\n.control-btn.control-btn-lg {\n height: 44px;\n padding: 0 24px;\n font-size: 14px;\n}\n.control-btn.control-btn-lg i {\n font-size: 16px;\n}\n\n.action-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: transparent;\n color: #666666;\n border-color: transparent;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn i {\n font-size: 14px;\n}\n.action-btn:hover:not(:disabled) {\n background: #f8f9fa;\n color: #2196f3;\n}\n.action-btn i {\n font-size: 12px;\n}\n.action-btn.action-btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #2196f3;\n color: #ffffff;\n border-color: #2196f3;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn.action-btn-primary:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn.action-btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn.action-btn-primary i {\n font-size: 14px;\n}\n.action-btn.action-btn-primary:hover:not(:disabled) {\n background: #1976d2;\n border-color: #1976d2;\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.2);\n transform: translateY(-1px);\n}\n.action-btn.action-btn-primary:active {\n transform: translateY(0);\n}\n.action-btn.action-btn-primary i {\n font-size: 12px;\n}\n.action-btn.action-btn-danger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #f44336;\n color: #ffffff;\n border-color: #f44336;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn.action-btn-danger:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn.action-btn-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn.action-btn-danger i {\n font-size: 14px;\n}\n.action-btn.action-btn-danger:hover:not(:disabled) {\n background: #ea1c0d;\n border-color: #ea1c0d;\n box-shadow: 0 2px 8px rgba(244, 67, 54, 0.3);\n transform: translateY(-1px);\n}\n.action-btn.action-btn-danger i {\n font-size: 12px;\n}\n\n.info-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(33, 150, 243, 0.1);\n color: #1976d2;\n border: 1px solid rgba(33, 150, 243, 0.2);\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(158, 158, 158, 0.1);\n color: #666666;\n border: 1px solid rgba(158, 158, 158, 0.2);\n}\n.status-badge.status-active {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(76, 175, 80, 0.1);\n color: #3d8b40;\n border: 1px solid rgba(76, 175, 80, 0.2);\n}\n.status-badge.status-migration {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(33, 150, 243, 0.1);\n color: #1976d2;\n border: 1px solid rgba(33, 150, 243, 0.2);\n}\n.status-badge.status-warning {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(255, 193, 7, 0.1);\n color: #6d5200;\n border: 1px solid rgba(255, 193, 7, 0.2);\n}\n.status-badge.status-error {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(244, 67, 54, 0.1);\n color: #ea1c0d;\n border: 1px solid rgba(244, 67, 54, 0.2);\n}\n\n.settings-nav {\n width: 220px;\n min-width: 220px;\n max-width: 220px;\n background: #ffffff;\n border-right: 1px solid #e0e0e0;\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow-y: auto;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n}\n.settings-nav .nav-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n margin: 0 8px 4px 8px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 400;\n color: #666666;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n position: relative;\n}\n.settings-nav .nav-item::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 50%;\n transform: translateY(-50%);\n width: 3px;\n height: 0;\n background: #2196f3;\n border-radius: 0 2px 2px 0;\n transition: height all 0.15s ease;\n}\n.settings-nav .nav-item:hover {\n background: #f8f9fa;\n color: #2196f3;\n transform: translateX(2px);\n}\n.settings-nav .nav-item.active {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n font-weight: 500;\n}\n.settings-nav .nav-item.active::before {\n height: 24px;\n}\n.settings-nav .nav-item i {\n font-size: 14px;\n width: 18px;\n text-align: center;\n}\n\n.form-field {\n margin-bottom: 16px;\n}\n.form-field .field-label {\n display: block;\n margin-bottom: 4px;\n font-size: 12px;\n font-weight: 500;\n color: #212121;\n}\n.form-field .field-hint {\n margin-top: 4px;\n font-size: 11px;\n color: #9e9e9e;\n}\n.form-field .field-error {\n margin-top: 4px;\n font-size: 11px;\n color: #f44336;\n}\n.form-field input, .form-field textarea, .form-field select {\n width: 100%;\n height: 36px;\n padding: 0 8px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n background: #ffffff;\n color: #212121;\n transition: all 0.15s ease;\n outline: none;\n}\n.form-field input::placeholder, .form-field textarea::placeholder, .form-field select::placeholder {\n color: #9e9e9e;\n}\n.form-field input:focus, .form-field textarea:focus, .form-field select:focus {\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.2);\n}\n.form-field input:disabled, .form-field textarea:disabled, .form-field select:disabled {\n background: #f8f9fa;\n color: #bdbdbd;\n cursor: not-allowed;\n}\n\n.form-row {\n display: flex;\n gap: 16px;\n}\n.form-row .form-field {\n flex: 1;\n}\n\n.checkbox-field {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 16px;\n}\n.checkbox-field label {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #212121;\n cursor: pointer;\n margin: 0;\n}\n\n.status-bar {\n display: flex;\n gap: 24px;\n padding: 16px;\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n margin-bottom: 16px;\n}\n.status-bar .status-item {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n}\n.status-bar .status-item .status-label {\n color: #666666;\n font-weight: 500;\n}\n.status-bar .status-item .status-value {\n color: #212121;\n font-weight: 600;\n}\n.status-bar .status-item .status-value.text-success {\n color: #4caf50;\n}\n.status-bar .status-item .status-value.text-warning {\n color: #ffc107;\n}\n.status-bar .status-item .status-value.text-danger {\n color: #f44336;\n}\n\n.empty-state {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n gap: 16px;\n padding: 48px;\n text-align: center;\n color: #666666;\n}\n.empty-state i {\n font-size: 48px;\n color: #9e9e9e;\n margin-bottom: 8px;\n}\n.empty-state h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n color: #212121;\n}\n.empty-state p {\n margin: 0;\n font-size: 14px;\n max-width: 400px;\n line-height: 1.6;\n}\n\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n gap: 16px;\n padding: 48px;\n}\n.loading-container .loading-spinner {\n width: 40px;\n height: 40px;\n border: 3px solid #e0e0e0;\n border-top-color: #2196f3;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n.loading-container .loading-text {\n font-size: 12px;\n color: #666666;\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n.text-success {\n color: #4caf50 !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\n.text-danger {\n color: #f44336 !important;\n}\n\n.text-info {\n color: #00bcd4 !important;\n}\n\n.text-muted {\n color: #9e9e9e !important;\n}\n\n.text-primary {\n color: #212121 !important;\n}\n\n.text-secondary {\n color: #666666 !important;\n}\n\n.mb-0 {\n margin-bottom: 0 !important;\n}\n\n.mb-1 {\n margin-bottom: 4px !important;\n}\n\n.mb-2 {\n margin-bottom: 8px !important;\n}\n\n.mb-3 {\n margin-bottom: 16px !important;\n}\n\n.mb-4 {\n margin-bottom: 24px !important;\n}\n\n.mb-5 {\n margin-bottom: 32px !important;\n}\n\n.mt-0 {\n margin-top: 0 !important;\n}\n\n.mt-1 {\n margin-top: 4px !important;\n}\n\n.mt-2 {\n margin-top: 8px !important;\n}\n\n.mt-3 {\n margin-top: 16px !important;\n}\n\n.mt-4 {\n margin-top: 24px !important;\n}\n\n.mt-5 {\n margin-top: 32px !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-none {\n display: none !important;\n}\n\n.flex-1 {\n flex: 1 !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.align-center {\n align-items: center !important;\n}\n\n.justify-center {\n justify-content: center !important;\n}\n\n.justify-between {\n justify-content: space-between !important;\n}\n\n.stats-grid {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card {\n margin-right: 10px;\n}\n\n.role-card {\n margin-bottom: 5px;\n}\n\n@media (max-width: 768px) {\n .settings-card {\n padding: 16px;\n }\n .dashboard-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 16px;\n }\n .dashboard-header .header-controls {\n width: 100%;\n justify-content: flex-start;\n }\n .form-row {\n flex-direction: column;\n }\n}\n:host {\n display: block;\n width: 100%;\n}\n\n.settings-card {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n.settings-card:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n.settings-card.settings-card-floating {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n}\n.settings-card.settings-card-floating:hover {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-2px);\n}\n.settings-card.settings-card-sm {\n padding: 16px;\n}\n.settings-card.settings-card-lg {\n padding: 24px;\n}\n\n.card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n padding: 24px 24px 16px 24px;\n margin: 0;\n}\n.card-header h3, .card-header h4 {\n margin: 0;\n font-weight: 500;\n color: #212121;\n font-size: 16px;\n}\n.card-header h4 {\n font-size: 14px;\n}\n.card-header .header-content {\n flex: 1;\n}\n.card-header .header-content .card-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #212121;\n line-height: 1.2;\n}\n.card-header .header-content .card-subtitle {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: #666666;\n line-height: 1.4;\n}\n.card-header .header-actions {\n flex-shrink: 0;\n display: flex;\n gap: 8px;\n align-items: flex-start;\n}\n\n.card-content {\n flex: 1;\n min-height: 0;\n padding: 0 24px 24px 24px;\n}\n.card-content.no-padding {\n padding: 0;\n}\n\n.card-footer {\n flex-shrink: 0;\n padding: 16px 24px 24px 24px;\n border-top: 1px solid #e0e0e0;\n background: #f8f9fa;\n border-radius: 0 0 8px 8px;\n}\n\n.settings-card-sm .card-header {\n padding: 16px 16px 8px 16px;\n}\n.settings-card-sm .card-header .card-title {\n font-size: 14px;\n}\n.settings-card-sm .card-header .card-subtitle {\n font-size: 11px;\n}\n.settings-card-sm .card-content {\n padding: 0 16px 16px 16px;\n}\n.settings-card-sm .card-content.no-padding {\n padding: 0;\n}\n.settings-card-sm .card-footer {\n padding: 8px 16px 16px 16px;\n}\n\n.settings-card-lg .card-header {\n padding: 32px 32px 24px 32px;\n}\n.settings-card-lg .card-header .card-title {\n font-size: 18px;\n}\n.settings-card-lg .card-content {\n padding: 0 32px 32px 32px;\n}\n.settings-card-lg .card-content.no-padding {\n padding: 0;\n}\n.settings-card-lg .card-footer {\n padding: 24px 32px 32px 32px;\n}\n"] }]
152
- }], null, { title: [{
153
- type: Input
154
- }], subtitle: [{
155
- type: Input
156
- }], floating: [{
157
- type: Input
158
- }], size: [{
159
- type: Input
160
- }], noPadding: [{
161
- type: Input
162
- }], headerTemplate: [{
163
- type: Input
164
- }], actionTemplate: [{
165
- type: Input
166
- }], footerTemplate: [{
167
- type: Input
168
- }] }); })();
169
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SettingsCardComponent, { className: "SettingsCardComponent" }); })();
170
- //# sourceMappingURL=settings-card.component.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"settings-card.component.js","sourceRoot":"","sources":["../../../../../src/lib/shared/components/settings-card/settings-card.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAe,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;;;;;IAkBnC,wBAAgE;;;IAAhE,oHAAiD;;;IAAlC,wDAAgC;;;IAK3C,4BAAyB;IAAA,YAAc;IAAA,iBAAI;;;IAAlB,cAAc;IAAd,qCAAc;;;IAKvC,wBAAgE;;;IADlE,8BAA6B;IAC3B,kIAAiD;IACnD,iBAAM;;;IADW,cAAgC;IAAhC,wDAAgC;;;IAPjD,AADF,8BAA4B,YACH;IAAA,YAAW;IAAA,iBAAK;IACvC,wGAAgB;IAGlB,iBAAM;IACN,0GAAsB;;;IALG,eAAW;IAAX,kCAAW;IAClC,cAEC;IAFD,0CAEC;IAEH,cAIC;IAJD,gDAIC;;;IAdL,8BAA4B;IAGxB,AAFF,kGAAsB,qEAEb;IAaX,iBAAM;;;IAfJ,cAcC;IAdD,+CAcC;;;IAUD,wBAAgE;;;IADlE,8BAA4B;IAC1B,sGAAiD;IACnD,iBAAM;;;IADW,cAAgC;IAAhC,wDAAgC;;AAvCzD;;;GAGG;AA2CH,MAAM,OAAO,qBAAqB;IAChC,yCAAyC;IAChC,KAAK,CAAU;IAExB,8CAA8C;IACrC,QAAQ,CAAU;IAE3B,4DAA4D;IACnD,QAAQ,GAAG,KAAK,CAAC;IAE1B,wBAAwB;IACf,IAAI,GAAuB,IAAI,CAAC;IAEzC,kDAAkD;IACzC,SAAS,GAAG,KAAK,CAAC;IAE3B,yCAAyC;IAChC,cAAc,CAAoB;IAE3C,yCAAyC;IAChC,cAAc,CAAoB;IAE3C,kCAAkC;IACzB,cAAc,CAAoB;+EAvBhC,qBAAqB;6DAArB,qBAAqB;;YArC9B,8BAGwC;YACtC,8EAA+B;YAoB/B,8BAAyD;YACvD,kBAAyB;YAC3B,iBAAM;YAEN,8EAAsB;YAKxB,iBAAM;;YA9BD,AADA,AADA,gDAAmC,iCACD,iCACA;YACrC,cAkBC;YAlBD,0DAkBC;YAEyB,cAA8B;YAA9B,2CAA8B;YAIxD,eAIC;YAJD,6CAIC;4BAlCK,YAAY;;iFAuCX,qBAAqB;cA1CjC,SAAS;2BACE,kBAAkB,cAChB,IAAI,WACP,CAAC,YAAY,CAAC,YACb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCT;gBAKQ,KAAK;kBAAb,KAAK;YAGG,QAAQ;kBAAhB,KAAK;YAGG,QAAQ;kBAAhB,KAAK;YAGG,IAAI;kBAAZ,KAAK;YAGG,SAAS;kBAAjB,KAAK;YAGG,cAAc;kBAAtB,KAAK;YAGG,cAAc;kBAAtB,KAAK;YAGG,cAAc;kBAAtB,KAAK;;kFAvBK,qBAAqB"}