@memberjunction/ng-explorer-settings 5.51.2 → 5.51.4
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.
- package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts +2 -0
- package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts.map +1 -1
- package/dist/lib/user-management/user-dialog/user-dialog.component.js +24 -3
- package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
- package/dist/lib/user-management/user-management.component.d.ts +5 -0
- package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
- package/dist/lib/user-management/user-management.component.js +54 -2
- package/dist/lib/user-management/user-management.component.js.map +1 -1
- package/package.json +20 -20
|
@@ -39,6 +39,8 @@ export declare class UserDialogComponent extends BaseAngularComponent implements
|
|
|
39
39
|
toggleRole(roleId: string): void;
|
|
40
40
|
onSubmit(): Promise<void>;
|
|
41
41
|
private updateUserRoles;
|
|
42
|
+
/** Names a role for a refusal message; falls back to the ID when the catalog has no match. */
|
|
43
|
+
private describeRole;
|
|
42
44
|
onCancel(): void;
|
|
43
45
|
private markFormGroupTouched;
|
|
44
46
|
static ɵfac: i0.ɵɵFactoryDeclaration<UserDialogComponent, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-dialog.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/user-management/user-dialog/user-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAsE,MAAM,eAAe,CAAC;AAExL,OAAO,EAAiD,SAAS,EAAc,MAAM,gBAAgB,CAAC;AAEtG,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"user-dialog.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/user-management/user-dialog/user-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAsE,MAAM,eAAe,CAAC;AAExL,OAAO,EAAiD,SAAS,EAAc,MAAM,gBAAgB,CAAC;AAEtG,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAG7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AACrE,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACxB,cAAc,EAAE,YAAY,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED,qBAOa,mBAAoB,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS,EAAE,SAAS;IAC1F,IAAI,EAAE,cAAc,GAAG,IAAI,CAAQ;IACnC,OAAO,UAAS;IACf,MAAM,iCAAwC;IAExD,OAAO,CAAC,EAAE,CAAuB;IACjC,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,KAAK,QAAQ,GAAiC;IAC9C,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,UAAS;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5B,eAAe,cAAqB;IACpC,iBAAiB,EAAE,gBAAgB,EAAE,CAAM;;IAelD,QAAQ,IAAI,IAAI;IAIhB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAmBzC,WAAW,IAAI,IAAI;IAInB,OAAO,CAAC,SAAS;IAejB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAM/B,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,IAAW,UAAU,IAAI,OAAO,CAE/B;YAEa,YAAY;YAkBZ,qBAAqB;IAqB5B,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAUhD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ1B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAwDxB,eAAe;IAyD7B,8FAA8F;IAC9F,OAAO,CAAC,YAAY;IAIb,QAAQ,IAAI,IAAI;IAIvB,OAAO,CAAC,oBAAoB;yCAvQjB,mBAAmB;2CAAnB,mBAAmB;CA6Q/B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Component, Input, Output, EventEmitter, inject, HostListener, ViewEncapsulation, ChangeDetectorRef, NgZone } from '@angular/core';
|
|
2
2
|
import { FormBuilder, Validators } from '@angular/forms';
|
|
3
3
|
import { RunView } from '@memberjunction/core';
|
|
4
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
4
5
|
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
5
6
|
import * as i0 from "@angular/core";
|
|
6
7
|
import * as i1 from "@angular/forms";
|
|
@@ -421,9 +422,18 @@ export class UserDialogComponent extends BaseAngularComponent {
|
|
|
421
422
|
}
|
|
422
423
|
// Batch all role deletes and adds into one transactional GraphQL call
|
|
423
424
|
const tg = await this.metadata.CreateTransactionGroup();
|
|
425
|
+
// Each Delete()/Save() only ENROLS the row in the group; the write is deferred to Submit().
|
|
426
|
+
// A false return therefore means the row was refused CLIENT-side and never enrolled — so
|
|
427
|
+
// submitting anyway writes a PARTIAL change, or an empty one whose Submit() returns true for
|
|
428
|
+
// having nothing to do, and either way the dialog closes reporting success. Same rule and
|
|
429
|
+
// same reason as `UserManagementComponent.executeBulkRoleAssign`, where the transaction-group
|
|
430
|
+
// semantics — and why the server-side #4282 guard is NOT what this catches — are set out in full.
|
|
431
|
+
const refusals = [];
|
|
424
432
|
for (const userRole of rolesToRemove) {
|
|
425
433
|
userRole.TransactionGroup = tg;
|
|
426
|
-
await userRole.Delete()
|
|
434
|
+
if (!await userRole.Delete()) {
|
|
435
|
+
refusals.push(`Remove ${this.describeRole(userRole.RoleID)}: ${userRole.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
436
|
+
}
|
|
427
437
|
}
|
|
428
438
|
for (const roleId of rolesToAdd) {
|
|
429
439
|
const userRole = await this.metadata.GetEntityObject('MJ: User Roles');
|
|
@@ -431,7 +441,14 @@ export class UserDialogComponent extends BaseAngularComponent {
|
|
|
431
441
|
userRole.UserID = userId;
|
|
432
442
|
userRole.RoleID = roleId;
|
|
433
443
|
userRole.TransactionGroup = tg;
|
|
434
|
-
await userRole.Save()
|
|
444
|
+
if (!await userRole.Save()) {
|
|
445
|
+
refusals.push(`Add ${this.describeRole(roleId)}: ${userRole.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (refusals.length > 0) {
|
|
449
|
+
// Nothing was written: the refused rows never enrolled, and the rest are still only queued
|
|
450
|
+
// because Submit() is not reached.
|
|
451
|
+
throw new Error(`Failed to update user roles — no role changes were made.\n${refusals.join('\n')}`);
|
|
435
452
|
}
|
|
436
453
|
if (!await tg.Submit()) {
|
|
437
454
|
throw new Error('Failed to update user roles — all changes have been rolled back');
|
|
@@ -442,6 +459,10 @@ export class UserDialogComponent extends BaseAngularComponent {
|
|
|
442
459
|
throw error;
|
|
443
460
|
}
|
|
444
461
|
}
|
|
462
|
+
/** Names a role for a refusal message; falls back to the ID when the catalog has no match. */
|
|
463
|
+
describeRole(roleId) {
|
|
464
|
+
return this.data?.availableRoles.find(r => UUIDsEqual(r.ID, roleId))?.Name ?? roleId;
|
|
465
|
+
}
|
|
445
466
|
onCancel() {
|
|
446
467
|
this.result.emit({ action: 'cancel' });
|
|
447
468
|
}
|
|
@@ -473,5 +494,5 @@ export class UserDialogComponent extends BaseAngularComponent {
|
|
|
473
494
|
type: HostListener,
|
|
474
495
|
args: ['document:keydown.escape', ['$event']]
|
|
475
496
|
}] }); })();
|
|
476
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserDialogComponent, { className: "UserDialogComponent", filePath: "src/lib/user-management/user-dialog/user-dialog.component.ts", lineNumber:
|
|
497
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserDialogComponent, { className: "UserDialogComponent", filePath: "src/lib/user-management/user-dialog/user-dialog.component.ts", lineNumber: 27 }); })();
|
|
477
498
|
//# sourceMappingURL=user-dialog.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-dialog.component.js","sourceRoot":"","sources":["../../../../src/lib/user-management/user-dialog/user-dialog.component.ts","../../../../src/lib/user-management/user-dialog/user-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, OnChanges, SimpleChanges, inject, HostListener, ViewEncapsulation, ChangeDetectorRef, NgZone } from '@angular/core';\n\nimport { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';\nimport { Metadata, RunView } from '@memberjunction/core';\nimport { MJUserEntity, MJRoleEntity, MJUserRoleEntity } from '@memberjunction/core-entities';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nexport interface UserDialogData {\n user?: MJUserEntity;\n mode: 'create' | 'edit';\n availableRoles: MJRoleEntity[];\n}\n\nexport interface UserDialogResult {\n action: 'save' | 'cancel';\n user?: MJUserEntity;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-user-dialog',\n encapsulation: ViewEncapsulation.None,\n templateUrl: './user-dialog.component.html',\n styleUrls: ['./user-dialog.component.css']\n})\nexport class UserDialogComponent extends BaseAngularComponent implements OnInit, OnDestroy, OnChanges {\n @Input() data: UserDialogData | null = null;\n @Input() visible = false;\n @Output() result = new EventEmitter<UserDialogResult>();\n\n private fb = inject(FormBuilder);\n private cdr = inject(ChangeDetectorRef);\n private ngZone = inject(NgZone);\n private get metadata() { return this.ProviderToUse; }\n public userForm: FormGroup;\n public isLoading = false;\n public error: string | null = null;\n public selectedRoleIds = new Set<string>();\n public existingUserRoles: MJUserRoleEntity[] = [];\n\n constructor() {\n super();\n this.userForm = this.fb.group({\n name: ['', [Validators.required, Validators.email]],\n firstName: [''],\n lastName: [''],\n email: ['', [Validators.required, Validators.email]],\n title: [''],\n type: ['User', Validators.required],\n isActive: [true]\n });\n }\n\n ngOnInit(): void {\n // Initial setup\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n // Always clear state when data changes to prevent persistence bugs\n if (changes['data']) {\n this.selectedRoleIds.clear();\n this.existingUserRoles = [];\n \n if (this.data?.user && this.isEditMode) {\n this.loadUserData();\n } else {\n this.resetForm();\n }\n }\n \n // Reset form when dialog becomes visible and not in edit mode\n if (changes['visible'] && this.visible && !this.isEditMode) {\n this.resetForm();\n }\n }\n\n ngOnDestroy(): void {\n // Cleanup if needed\n }\n\n private resetForm(): void {\n this.userForm.reset({\n name: '',\n firstName: '',\n lastName: '',\n email: '',\n title: '',\n type: 'User',\n isActive: true\n });\n this.selectedRoleIds.clear();\n this.error = null;\n }\n\n @HostListener('document:keydown.escape', ['$event'])\n onEscapeKey(event: Event): void {\n if (this.visible) {\n this.onCancel();\n }\n }\n\n public get windowTitle(): string {\n return this.isEditMode ? 'Edit User' : 'Create New User';\n }\n\n public get isEditMode(): boolean {\n return this.data?.mode === 'edit';\n }\n\n private async loadUserData(): Promise<void> {\n if (!this.data?.user) return;\n\n const user = this.data.user;\n this.userForm.patchValue({\n name: user.Name,\n firstName: user.FirstName,\n lastName: user.LastName,\n email: user.Email,\n title: user.Title,\n type: user.Type,\n isActive: user.IsActive\n });\n\n // Load existing user roles\n await this.loadExistingUserRoles(user.ID);\n }\n\n private async loadExistingUserRoles(userId: string): Promise<void> {\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJUserRoleEntity>({\n EntityName: 'MJ: User Roles',\n ExtraFilter: `UserID='${userId}'`,\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.existingUserRoles = result.Results;\n // Pre-select existing roles\n for (const userRole of this.existingUserRoles) {\n this.selectedRoleIds.add(userRole.RoleID);\n }\n }\n } catch (error) {\n console.warn('Failed to load existing user roles:', error);\n }\n }\n\n public onRoleToggle(roleId: string, event: Event): void {\n event.stopPropagation();\n const checkbox = event.target as HTMLInputElement;\n if (checkbox.checked) {\n this.selectedRoleIds.add(roleId);\n } else {\n this.selectedRoleIds.delete(roleId);\n }\n }\n\n public toggleRole(roleId: string): void {\n if (this.selectedRoleIds.has(roleId)) {\n this.selectedRoleIds.delete(roleId);\n } else {\n this.selectedRoleIds.add(roleId);\n }\n }\n\n public async onSubmit(): Promise<void> {\n if (this.userForm.invalid) {\n this.markFormGroupTouched(this.userForm);\n return;\n }\n\n this.isLoading = true;\n this.error = null;\n\n try {\n let user: MJUserEntity;\n\n if (this.isEditMode && this.data?.user) {\n // Edit existing user\n user = this.data.user;\n } else {\n // Create new user\n user = await this.metadata.GetEntityObject<MJUserEntity>('MJ: Users');\n user.NewRecord();\n }\n\n // Update user properties\n const formValue = this.userForm.value;\n user.Name = formValue.name;\n user.FirstName = formValue.firstName;\n user.LastName = formValue.lastName;\n user.Email = formValue.email;\n user.Title = formValue.title;\n user.Type = formValue.type;\n user.IsActive = formValue.isActive;\n\n // Save user\n const saveResult = await user.Save();\n if (!saveResult) {\n throw new Error(user.LatestResult?.Message || 'Failed to save user');\n }\n\n // Handle role assignments\n await this.updateUserRoles(user.ID);\n\n this.result.emit({ action: 'save', user });\n\n } catch (error: unknown) {\n console.error('Error saving user:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'An unexpected error occurred';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n private async updateUserRoles(userId: string): Promise<void> {\n try {\n // Get current role IDs from existing UserRole entities\n const existingRoleIds = new Set(this.existingUserRoles.map(ur => ur.RoleID));\n\n // Determine roles to add and remove\n const rolesToAdd = Array.from(this.selectedRoleIds).filter(roleId => !existingRoleIds.has(roleId));\n const rolesToRemove = this.existingUserRoles.filter(userRole => !this.selectedRoleIds.has(userRole.RoleID));\n\n if (rolesToAdd.length === 0 && rolesToRemove.length === 0) {\n return;\n }\n\n // Batch all role deletes and adds into one transactional GraphQL call\n const tg = await this.metadata.CreateTransactionGroup();\n\n for (const userRole of rolesToRemove) {\n userRole.TransactionGroup = tg;\n await userRole.Delete();\n }\n\n for (const roleId of rolesToAdd) {\n const userRole = await this.metadata.GetEntityObject<MJUserRoleEntity>('MJ: User Roles');\n userRole.NewRecord();\n userRole.UserID = userId;\n userRole.RoleID = roleId;\n userRole.TransactionGroup = tg;\n await userRole.Save();\n }\n\n if (!await tg.Submit()) {\n throw new Error('Failed to update user roles — all changes have been rolled back');\n }\n } catch (error) {\n console.error('Error updating user roles:', error);\n throw error;\n }\n }\n\n public onCancel(): void {\n this.result.emit({ action: 'cancel' });\n }\n\n private markFormGroupTouched(formGroup: FormGroup): void {\n Object.keys(formGroup.controls).forEach(key => {\n const control = formGroup.get(key);\n control?.markAsTouched();\n });\n }\n}","<!-- MD3 Modal Dialog -->\n@if (visible) {\n <div class=\"modal-backdrop\" (click)=\"onCancel()\">\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <!-- Modal Header with MJ Blue -->\n <div class=\"modal-header\">\n <div class=\"dialog-header\">\n <h2 class=\"dialog-title\">\n <i class=\"fa-solid fa-user\"></i>\n {{ isEditMode ? 'Edit User' : 'Create New User' }}\n </h2>\n <p class=\"dialog-subtitle\">\n {{ isEditMode ? 'Update user information and role assignments' : 'Add a new user to the system' }}\n </p>\n </div>\n <button type=\"button\" class=\"modal-close\" (click)=\"onCancel()\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Modal Body -->\n <div class=\"modal-body\">\n <form [formGroup]=\"userForm\" (ngSubmit)=\"onSubmit()\">\n @if (error) {\n <div class=\"content-section\">\n <mj-alert Variant=\"error\" [Message]=\"error\" />\n </div>\n }\n <!-- Basic Information Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-id-card\"></i>\n Basic Information\n </h3>\n <p class=\"section-description\">Enter the user's personal and contact details</p>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-field\">\n <label class=\"field-label required\" for=\"name\">Username/Email</label>\n <input\n id=\"name\"\n type=\"email\"\n class=\"field-input\"\n formControlName=\"name\"\n placeholder=\"john@company.com\"\n [class.error]=\"userForm.get('name')?.invalid && userForm.get('name')?.touched\"\n />\n @if (userForm.get('name')?.invalid && userForm.get('name')?.touched) {\n <div class=\"field-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n @if (userForm.get('name')?.errors?.['required']) {\n Username/Email is required\n }\n @if (userForm.get('name')?.errors?.['email']) {\n Please enter a valid email address\n }\n </div>\n }\n </div>\n <div class=\"form-row\">\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"firstName\">First Name</label>\n <input\n id=\"firstName\"\n type=\"text\"\n class=\"field-input\"\n formControlName=\"firstName\"\n placeholder=\"John\"\n />\n </div>\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"lastName\">Last Name</label>\n <input\n id=\"lastName\"\n type=\"text\"\n class=\"field-input\"\n formControlName=\"lastName\"\n placeholder=\"Doe\"\n />\n </div>\n </div>\n <div class=\"form-field\">\n <label class=\"field-label required\" for=\"email\">Email Address</label>\n <input\n id=\"email\"\n type=\"email\"\n class=\"field-input\"\n formControlName=\"email\"\n placeholder=\"john@company.com\"\n [class.error]=\"userForm.get('email')?.invalid && userForm.get('email')?.touched\"\n />\n @if (userForm.get('email')?.invalid && userForm.get('email')?.touched) {\n <div class=\"field-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n @if (userForm.get('email')?.errors?.['required']) {\n Email address is required\n }\n @if (userForm.get('email')?.errors?.['email']) {\n Please enter a valid email address\n }\n </div>\n }\n </div>\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"title\">Job Title</label>\n <input\n id=\"title\"\n type=\"text\"\n class=\"field-input\"\n formControlName=\"title\"\n placeholder=\"Software Engineer\"\n />\n </div>\n </div>\n </div>\n </div>\n <!-- User Settings Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-cog\"></i>\n User Settings\n </h3>\n <p class=\"section-description\">Configure user type and account status</p>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"type\">User Type</label>\n <select id=\"type\" class=\"field-select\" formControlName=\"type\">\n <option value=\"User\">Standard User</option>\n <option value=\"Owner\">System Owner</option>\n </select>\n </div>\n <div class=\"form-field\">\n <div class=\"checkbox-field\">\n <input\n id=\"isActive\"\n type=\"checkbox\"\n class=\"checkbox-input\"\n formControlName=\"isActive\"\n />\n <label class=\"checkbox-label\" for=\"isActive\">\n <div class=\"checkbox-indicator\"></div>\n <div>\n <strong>Active Account</strong>\n <div style=\"font-size: 12px; color: var(--md-on-surface-variant); margin-top: 2px;\">\n User can log in and access the system\n </div>\n </div>\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Role Assignment Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-user-tag\"></i>\n Role Assignment\n </h3>\n <p class=\"section-description\">Select the roles to assign to this user</p>\n </div>\n <div class=\"roles-grid\">\n @for (role of data?.availableRoles; track role.ID) {\n <div class=\"role-card\"\n [class.selected]=\"selectedRoleIds.has(role.ID)\"\n (click)=\"toggleRole(role.ID)\">\n <div class=\"role-content\">\n <div class=\"checkbox-field\">\n <input\n type=\"checkbox\"\n class=\"checkbox-input\"\n [id]=\"'role-' + role.ID\"\n [checked]=\"selectedRoleIds.has(role.ID)\"\n (change)=\"onRoleToggle(role.ID, $event)\"\n />\n <label class=\"checkbox-label\" [for]=\"'role-' + role.ID\">\n <div class=\"checkbox-indicator\"></div>\n </label>\n </div>\n <div class=\"role-info\">\n <h4 class=\"role-name\">{{ role.Name }}</h4>\n @if (role.Description) {\n <p class=\"role-description\">{{ role.Description }}</p>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Modal Footer -->\n <div class=\"modal-footer\">\n <button\n type=\"submit\"\n class=\"btn btn-primary\"\n [disabled]=\"userForm.invalid || isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Saving...\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n {{ isEditMode ? 'Update User' : 'Create User' }}\n }\n </button>\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"onCancel()\">\n <i class=\"fa-solid fa-times\"></i>\n Cancel\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"user-dialog.component.js","sourceRoot":"","sources":["../../../../src/lib/user-management/user-dialog/user-dialog.component.ts","../../../../src/lib/user-management/user-dialog/user-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, OnChanges, SimpleChanges, inject, HostListener, ViewEncapsulation, ChangeDetectorRef, NgZone } from '@angular/core';\n\nimport { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';\nimport { Metadata, RunView } from '@memberjunction/core';\nimport { MJUserEntity, MJRoleEntity, MJUserRoleEntity } from '@memberjunction/core-entities';\n\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nexport interface UserDialogData {\n user?: MJUserEntity;\n mode: 'create' | 'edit';\n availableRoles: MJRoleEntity[];\n}\n\nexport interface UserDialogResult {\n action: 'save' | 'cancel';\n user?: MJUserEntity;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-user-dialog',\n encapsulation: ViewEncapsulation.None,\n templateUrl: './user-dialog.component.html',\n styleUrls: ['./user-dialog.component.css']\n})\nexport class UserDialogComponent extends BaseAngularComponent implements OnInit, OnDestroy, OnChanges {\n @Input() data: UserDialogData | null = null;\n @Input() visible = false;\n @Output() result = new EventEmitter<UserDialogResult>();\n\n private fb = inject(FormBuilder);\n private cdr = inject(ChangeDetectorRef);\n private ngZone = inject(NgZone);\n private get metadata() { return this.ProviderToUse; }\n public userForm: FormGroup;\n public isLoading = false;\n public error: string | null = null;\n public selectedRoleIds = new Set<string>();\n public existingUserRoles: MJUserRoleEntity[] = [];\n\n constructor() {\n super();\n this.userForm = this.fb.group({\n name: ['', [Validators.required, Validators.email]],\n firstName: [''],\n lastName: [''],\n email: ['', [Validators.required, Validators.email]],\n title: [''],\n type: ['User', Validators.required],\n isActive: [true]\n });\n }\n\n ngOnInit(): void {\n // Initial setup\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n // Always clear state when data changes to prevent persistence bugs\n if (changes['data']) {\n this.selectedRoleIds.clear();\n this.existingUserRoles = [];\n \n if (this.data?.user && this.isEditMode) {\n this.loadUserData();\n } else {\n this.resetForm();\n }\n }\n \n // Reset form when dialog becomes visible and not in edit mode\n if (changes['visible'] && this.visible && !this.isEditMode) {\n this.resetForm();\n }\n }\n\n ngOnDestroy(): void {\n // Cleanup if needed\n }\n\n private resetForm(): void {\n this.userForm.reset({\n name: '',\n firstName: '',\n lastName: '',\n email: '',\n title: '',\n type: 'User',\n isActive: true\n });\n this.selectedRoleIds.clear();\n this.error = null;\n }\n\n @HostListener('document:keydown.escape', ['$event'])\n onEscapeKey(event: Event): void {\n if (this.visible) {\n this.onCancel();\n }\n }\n\n public get windowTitle(): string {\n return this.isEditMode ? 'Edit User' : 'Create New User';\n }\n\n public get isEditMode(): boolean {\n return this.data?.mode === 'edit';\n }\n\n private async loadUserData(): Promise<void> {\n if (!this.data?.user) return;\n\n const user = this.data.user;\n this.userForm.patchValue({\n name: user.Name,\n firstName: user.FirstName,\n lastName: user.LastName,\n email: user.Email,\n title: user.Title,\n type: user.Type,\n isActive: user.IsActive\n });\n\n // Load existing user roles\n await this.loadExistingUserRoles(user.ID);\n }\n\n private async loadExistingUserRoles(userId: string): Promise<void> {\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJUserRoleEntity>({\n EntityName: 'MJ: User Roles',\n ExtraFilter: `UserID='${userId}'`,\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.existingUserRoles = result.Results;\n // Pre-select existing roles\n for (const userRole of this.existingUserRoles) {\n this.selectedRoleIds.add(userRole.RoleID);\n }\n }\n } catch (error) {\n console.warn('Failed to load existing user roles:', error);\n }\n }\n\n public onRoleToggle(roleId: string, event: Event): void {\n event.stopPropagation();\n const checkbox = event.target as HTMLInputElement;\n if (checkbox.checked) {\n this.selectedRoleIds.add(roleId);\n } else {\n this.selectedRoleIds.delete(roleId);\n }\n }\n\n public toggleRole(roleId: string): void {\n if (this.selectedRoleIds.has(roleId)) {\n this.selectedRoleIds.delete(roleId);\n } else {\n this.selectedRoleIds.add(roleId);\n }\n }\n\n public async onSubmit(): Promise<void> {\n if (this.userForm.invalid) {\n this.markFormGroupTouched(this.userForm);\n return;\n }\n\n this.isLoading = true;\n this.error = null;\n\n try {\n let user: MJUserEntity;\n\n if (this.isEditMode && this.data?.user) {\n // Edit existing user\n user = this.data.user;\n } else {\n // Create new user\n user = await this.metadata.GetEntityObject<MJUserEntity>('MJ: Users');\n user.NewRecord();\n }\n\n // Update user properties\n const formValue = this.userForm.value;\n user.Name = formValue.name;\n user.FirstName = formValue.firstName;\n user.LastName = formValue.lastName;\n user.Email = formValue.email;\n user.Title = formValue.title;\n user.Type = formValue.type;\n user.IsActive = formValue.isActive;\n\n // Save user\n const saveResult = await user.Save();\n if (!saveResult) {\n throw new Error(user.LatestResult?.Message || 'Failed to save user');\n }\n\n // Handle role assignments\n await this.updateUserRoles(user.ID);\n\n this.result.emit({ action: 'save', user });\n\n } catch (error: unknown) {\n console.error('Error saving user:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'An unexpected error occurred';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n private async updateUserRoles(userId: string): Promise<void> {\n try {\n // Get current role IDs from existing UserRole entities\n const existingRoleIds = new Set(this.existingUserRoles.map(ur => ur.RoleID));\n\n // Determine roles to add and remove\n const rolesToAdd = Array.from(this.selectedRoleIds).filter(roleId => !existingRoleIds.has(roleId));\n const rolesToRemove = this.existingUserRoles.filter(userRole => !this.selectedRoleIds.has(userRole.RoleID));\n\n if (rolesToAdd.length === 0 && rolesToRemove.length === 0) {\n return;\n }\n\n // Batch all role deletes and adds into one transactional GraphQL call\n const tg = await this.metadata.CreateTransactionGroup();\n\n // Each Delete()/Save() only ENROLS the row in the group; the write is deferred to Submit().\n // A false return therefore means the row was refused CLIENT-side and never enrolled — so\n // submitting anyway writes a PARTIAL change, or an empty one whose Submit() returns true for\n // having nothing to do, and either way the dialog closes reporting success. Same rule and\n // same reason as `UserManagementComponent.executeBulkRoleAssign`, where the transaction-group\n // semantics — and why the server-side #4282 guard is NOT what this catches — are set out in full.\n const refusals: string[] = [];\n\n for (const userRole of rolesToRemove) {\n userRole.TransactionGroup = tg;\n if (!await userRole.Delete()) {\n refusals.push(`Remove ${this.describeRole(userRole.RoleID)}: ${userRole.LatestResult?.CompleteMessage ?? 'unknown error'}`);\n }\n }\n\n for (const roleId of rolesToAdd) {\n const userRole = await this.metadata.GetEntityObject<MJUserRoleEntity>('MJ: User Roles');\n userRole.NewRecord();\n userRole.UserID = userId;\n userRole.RoleID = roleId;\n userRole.TransactionGroup = tg;\n if (!await userRole.Save()) {\n refusals.push(`Add ${this.describeRole(roleId)}: ${userRole.LatestResult?.CompleteMessage ?? 'unknown error'}`);\n }\n }\n\n if (refusals.length > 0) {\n // Nothing was written: the refused rows never enrolled, and the rest are still only queued\n // because Submit() is not reached.\n throw new Error(`Failed to update user roles — no role changes were made.\\n${refusals.join('\\n')}`);\n }\n\n if (!await tg.Submit()) {\n throw new Error('Failed to update user roles — all changes have been rolled back');\n }\n } catch (error) {\n console.error('Error updating user roles:', error);\n throw error;\n }\n }\n\n /** Names a role for a refusal message; falls back to the ID when the catalog has no match. */\n private describeRole(roleId: string): string {\n return this.data?.availableRoles.find(r => UUIDsEqual(r.ID, roleId))?.Name ?? roleId;\n }\n\n public onCancel(): void {\n this.result.emit({ action: 'cancel' });\n }\n\n private markFormGroupTouched(formGroup: FormGroup): void {\n Object.keys(formGroup.controls).forEach(key => {\n const control = formGroup.get(key);\n control?.markAsTouched();\n });\n }\n}","<!-- MD3 Modal Dialog -->\n@if (visible) {\n <div class=\"modal-backdrop\" (click)=\"onCancel()\">\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <!-- Modal Header with MJ Blue -->\n <div class=\"modal-header\">\n <div class=\"dialog-header\">\n <h2 class=\"dialog-title\">\n <i class=\"fa-solid fa-user\"></i>\n {{ isEditMode ? 'Edit User' : 'Create New User' }}\n </h2>\n <p class=\"dialog-subtitle\">\n {{ isEditMode ? 'Update user information and role assignments' : 'Add a new user to the system' }}\n </p>\n </div>\n <button type=\"button\" class=\"modal-close\" (click)=\"onCancel()\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Modal Body -->\n <div class=\"modal-body\">\n <form [formGroup]=\"userForm\" (ngSubmit)=\"onSubmit()\">\n @if (error) {\n <div class=\"content-section\">\n <mj-alert Variant=\"error\" [Message]=\"error\" />\n </div>\n }\n <!-- Basic Information Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-id-card\"></i>\n Basic Information\n </h3>\n <p class=\"section-description\">Enter the user's personal and contact details</p>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-field\">\n <label class=\"field-label required\" for=\"name\">Username/Email</label>\n <input\n id=\"name\"\n type=\"email\"\n class=\"field-input\"\n formControlName=\"name\"\n placeholder=\"john@company.com\"\n [class.error]=\"userForm.get('name')?.invalid && userForm.get('name')?.touched\"\n />\n @if (userForm.get('name')?.invalid && userForm.get('name')?.touched) {\n <div class=\"field-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n @if (userForm.get('name')?.errors?.['required']) {\n Username/Email is required\n }\n @if (userForm.get('name')?.errors?.['email']) {\n Please enter a valid email address\n }\n </div>\n }\n </div>\n <div class=\"form-row\">\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"firstName\">First Name</label>\n <input\n id=\"firstName\"\n type=\"text\"\n class=\"field-input\"\n formControlName=\"firstName\"\n placeholder=\"John\"\n />\n </div>\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"lastName\">Last Name</label>\n <input\n id=\"lastName\"\n type=\"text\"\n class=\"field-input\"\n formControlName=\"lastName\"\n placeholder=\"Doe\"\n />\n </div>\n </div>\n <div class=\"form-field\">\n <label class=\"field-label required\" for=\"email\">Email Address</label>\n <input\n id=\"email\"\n type=\"email\"\n class=\"field-input\"\n formControlName=\"email\"\n placeholder=\"john@company.com\"\n [class.error]=\"userForm.get('email')?.invalid && userForm.get('email')?.touched\"\n />\n @if (userForm.get('email')?.invalid && userForm.get('email')?.touched) {\n <div class=\"field-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n @if (userForm.get('email')?.errors?.['required']) {\n Email address is required\n }\n @if (userForm.get('email')?.errors?.['email']) {\n Please enter a valid email address\n }\n </div>\n }\n </div>\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"title\">Job Title</label>\n <input\n id=\"title\"\n type=\"text\"\n class=\"field-input\"\n formControlName=\"title\"\n placeholder=\"Software Engineer\"\n />\n </div>\n </div>\n </div>\n </div>\n <!-- User Settings Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-cog\"></i>\n User Settings\n </h3>\n <p class=\"section-description\">Configure user type and account status</p>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"type\">User Type</label>\n <select id=\"type\" class=\"field-select\" formControlName=\"type\">\n <option value=\"User\">Standard User</option>\n <option value=\"Owner\">System Owner</option>\n </select>\n </div>\n <div class=\"form-field\">\n <div class=\"checkbox-field\">\n <input\n id=\"isActive\"\n type=\"checkbox\"\n class=\"checkbox-input\"\n formControlName=\"isActive\"\n />\n <label class=\"checkbox-label\" for=\"isActive\">\n <div class=\"checkbox-indicator\"></div>\n <div>\n <strong>Active Account</strong>\n <div style=\"font-size: 12px; color: var(--md-on-surface-variant); margin-top: 2px;\">\n User can log in and access the system\n </div>\n </div>\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Role Assignment Section -->\n <div class=\"content-section\">\n <div class=\"form-section\">\n <div class=\"section-header\">\n <h3 class=\"section-title\">\n <i class=\"fa-solid fa-user-tag\"></i>\n Role Assignment\n </h3>\n <p class=\"section-description\">Select the roles to assign to this user</p>\n </div>\n <div class=\"roles-grid\">\n @for (role of data?.availableRoles; track role.ID) {\n <div class=\"role-card\"\n [class.selected]=\"selectedRoleIds.has(role.ID)\"\n (click)=\"toggleRole(role.ID)\">\n <div class=\"role-content\">\n <div class=\"checkbox-field\">\n <input\n type=\"checkbox\"\n class=\"checkbox-input\"\n [id]=\"'role-' + role.ID\"\n [checked]=\"selectedRoleIds.has(role.ID)\"\n (change)=\"onRoleToggle(role.ID, $event)\"\n />\n <label class=\"checkbox-label\" [for]=\"'role-' + role.ID\">\n <div class=\"checkbox-indicator\"></div>\n </label>\n </div>\n <div class=\"role-info\">\n <h4 class=\"role-name\">{{ role.Name }}</h4>\n @if (role.Description) {\n <p class=\"role-description\">{{ role.Description }}</p>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Modal Footer -->\n <div class=\"modal-footer\">\n <button\n type=\"submit\"\n class=\"btn btn-primary\"\n [disabled]=\"userForm.invalid || isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Saving...\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n {{ isEditMode ? 'Update User' : 'Create User' }}\n }\n </button>\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"onCancel()\">\n <i class=\"fa-solid fa-times\"></i>\n Cancel\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n}\n"]}
|
|
@@ -148,6 +148,11 @@ export declare class UserManagementComponent extends BaseDashboard implements On
|
|
|
148
148
|
toggleUserExpansion(userId: string): void;
|
|
149
149
|
isUserExpanded(userId: string): boolean;
|
|
150
150
|
getUserRoles(userId: string): MJRoleEntity[];
|
|
151
|
+
/**
|
|
152
|
+
* Names a user for an error message. Falls back to the raw ID rather than to a placeholder so a
|
|
153
|
+
* refusal for a user who has dropped out of the loaded page is still traceable.
|
|
154
|
+
*/
|
|
155
|
+
private describeUser;
|
|
151
156
|
static ɵfac: i0.ɵɵFactoryDeclaration<UserManagementComponent, never>;
|
|
152
157
|
static ɵcmp: i0.ɵɵComponentDeclaration<UserManagementComponent, "mj-user-management", never, {}, {}, never, never, false, never>;
|
|
153
158
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-management.component.d.ts","sourceRoot":"","sources":["../../../src/lib/user-management/user-management.component.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"user-management.component.d.ts","sourceRoot":"","sources":["../../../src/lib/user-management/user-management.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -980,8 +980,21 @@ let UserManagementComponent = class UserManagementComponent extends BaseDashboar
|
|
|
980
980
|
async toggleUserStatus(user) {
|
|
981
981
|
try {
|
|
982
982
|
user.IsActive = !user.IsActive;
|
|
983
|
-
|
|
983
|
+
// BaseEntity.Save() returns false on a validation failure — it does NOT throw. Discarding
|
|
984
|
+
// the result meant the catch below never ran for a refused save: no revert, no message, and
|
|
985
|
+
// calculateStats() re-rendered the row as toggled, so the UI asserted success while nothing
|
|
986
|
+
// had been written. Reachable for every non-Owner admin since the #4260 privilege-elevation
|
|
987
|
+
// guard on MJ: Users, because deactivating a user is a write to another user's row.
|
|
988
|
+
// Mirrors deleteUser() above, which already checks its result this way.
|
|
989
|
+
if (!(await user.Save())) {
|
|
990
|
+
throw new Error(user.LatestResult?.Message || 'Failed to update user status');
|
|
991
|
+
}
|
|
984
992
|
this.ngZone.run(() => {
|
|
993
|
+
// Clear any banner left by a PREVIOUS refused toggle. Without this a non-Owner who is
|
|
994
|
+
// refused on one row, then succeeds on a row they may edit (their own), keeps reading the
|
|
995
|
+
// stale refusal. `loadInitialData()` is the only other place `error` is reset and this path
|
|
996
|
+
// does not call it.
|
|
997
|
+
this.error = null;
|
|
985
998
|
this.calculateStats();
|
|
986
999
|
this.cdr.markForCheck();
|
|
987
1000
|
});
|
|
@@ -990,6 +1003,7 @@ let UserManagementComponent = class UserManagementComponent extends BaseDashboar
|
|
|
990
1003
|
console.error('Error updating user status:', error);
|
|
991
1004
|
this.ngZone.run(() => {
|
|
992
1005
|
user.IsActive = !user.IsActive; // Revert on error
|
|
1006
|
+
this.error = error instanceof Error ? error.message : 'Failed to update user status';
|
|
993
1007
|
this.cdr.markForCheck();
|
|
994
1008
|
});
|
|
995
1009
|
}
|
|
@@ -1314,13 +1328,43 @@ let UserManagementComponent = class UserManagementComponent extends BaseDashboar
|
|
|
1314
1328
|
});
|
|
1315
1329
|
if (usersNeedingRole.length > 0) {
|
|
1316
1330
|
const tg = await this.metadata.CreateTransactionGroup();
|
|
1331
|
+
// Each Save() only ENROLS the row in the group — the write is deferred to Submit(). Inside
|
|
1332
|
+
// a TransactionGroup, Save() therefore reports ENROLMENT, not the write's outcome: the
|
|
1333
|
+
// provider queues the item locally and returns true with no round trip
|
|
1334
|
+
// (`GraphQLDataProvider.Save` — "part of a TG always return true").
|
|
1335
|
+
//
|
|
1336
|
+
// So the role-elevation guard is NOT what this check catches. `MJUserRoleEntityServer`
|
|
1337
|
+
// (issue #4282) lives in `@memberjunction/core-entities-server`, which no browser package
|
|
1338
|
+
// depends on, so it never registers here — it refuses on the server, during Submit().
|
|
1339
|
+
//
|
|
1340
|
+
// And today that refusal reaches the user NOWHERE. `ExecuteTransactionGroup` discards the
|
|
1341
|
+
// refused row's `Save()` return, so the row never enrols in the SERVER's group either; an
|
|
1342
|
+
// all-refused batch submits an empty group, whose `Submit()` returns true for having
|
|
1343
|
+
// nothing to do, and the screen closes with no message at all. Verified end to end against
|
|
1344
|
+
// a live server: a non-Owner assigning a role they do not hold is correctly refused (no row
|
|
1345
|
+
// is written) and is reported as success. Tracked as issue #4309 — fixing it belongs in the
|
|
1346
|
+
// resolver, which is the only layer that still knows which row was refused and why.
|
|
1347
|
+
//
|
|
1348
|
+
// What this check DOES catch is a CLIENT-side refusal — a CheckPermissions denial or a
|
|
1349
|
+
// field-rule failure — which really does return false here, leaving that row unenrolled.
|
|
1350
|
+
// Ignoring the return meant an all-refused batch left the group EMPTY, and an empty group's
|
|
1351
|
+
// Submit() returns true for having nothing to do, so the screen reported success having
|
|
1352
|
+
// assigned nothing. That is the failure this guards; keep it.
|
|
1353
|
+
const refusals = [];
|
|
1317
1354
|
for (const userId of usersNeedingRole) {
|
|
1318
1355
|
const userRole = await this.metadata.GetEntityObject('MJ: User Roles');
|
|
1319
1356
|
userRole.NewRecord();
|
|
1320
1357
|
userRole.UserID = userId;
|
|
1321
1358
|
userRole.RoleID = this.bulkRoleId;
|
|
1322
1359
|
userRole.TransactionGroup = tg;
|
|
1323
|
-
await userRole.Save()
|
|
1360
|
+
if (!await userRole.Save()) {
|
|
1361
|
+
refusals.push(`${this.describeUser(userId)}: ${userRole.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
if (refusals.length > 0) {
|
|
1365
|
+
// Nothing was written: the refused rows never enrolled, and the rest are still only
|
|
1366
|
+
// queued because Submit() is not reached.
|
|
1367
|
+
throw new Error(`Failed to assign roles — nothing was changed.\n${refusals.join('\n')}`);
|
|
1324
1368
|
}
|
|
1325
1369
|
if (!await tg.Submit()) {
|
|
1326
1370
|
throw new Error('Failed to assign roles — all changes have been rolled back');
|
|
@@ -1400,6 +1444,14 @@ let UserManagementComponent = class UserManagementComponent extends BaseDashboar
|
|
|
1400
1444
|
const roleIds = this.userRoleMap.get(userId) || [];
|
|
1401
1445
|
return this.roles.filter(role => roleIds.some(id => UUIDsEqual(id, role.ID)));
|
|
1402
1446
|
}
|
|
1447
|
+
/**
|
|
1448
|
+
* Names a user for an error message. Falls back to the raw ID rather than to a placeholder so a
|
|
1449
|
+
* refusal for a user who has dropped out of the loaded page is still traceable.
|
|
1450
|
+
*/
|
|
1451
|
+
describeUser(userId) {
|
|
1452
|
+
const user = this.users.find(u => UUIDsEqual(u.ID, userId));
|
|
1453
|
+
return user?.Email ?? user?.Name ?? userId;
|
|
1454
|
+
}
|
|
1403
1455
|
static ɵfac = function UserManagementComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || UserManagementComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone)); };
|
|
1404
1456
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserManagementComponent, selectors: [["mj-user-management"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 26, vars: 17, consts: [["AriaLabel", "Filter users", "Title", "Users", "Subtitle", "Manage user accounts, roles, and access"], ["meta", ""], ["Label", "users", 3, "Count", "Total"], ["toolbar", ""], ["Placeholder", "Search users by name or email...", 3, "ValueChange", "Value"], ["Label", "Filters", "Icon", "fa-solid fa-filter", 3, "ClearAllRequested", "ActiveCount", "ShowClearAll"], [3, "ValuesChange", "Reset", "Fields", "Values"], ["actions", ""], [3, "Clicked", "Loading"], ["mjButton", "", "variant", "secondary", "size", "sm", "aria-label", "Export users to file", 3, "click"], [1, "fa-solid", "fa-download"], [1, "mj-action-label"], ["mjButton", "", "variant", "primary", "size", "sm", "aria-label", "Add new user", 3, "click"], [1, "fa-solid", "fa-plus"], ["role", "toolbar", "aria-label", "Bulk actions", 1, "bulk-action-toolbar"], ["role", "status", "aria-live", "polite", "aria-busy", "true", 1, "loading-container"], ["role", "alert", "aria-live", "assertive", 1, "error-container"], ["role", "list", "aria-label", "Users list", 1, "users-list"], [3, "result", "data", "visible"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "delete-dialog-title", "aria-describedby", "delete-dialog-desc", 1, "modal-backdrop"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "bulk-action-dialog-title", "aria-describedby", "bulk-action-dialog-desc", 1, "modal-backdrop"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "bulk-role-dialog-title", "aria-describedby", "bulk-role-dialog-desc", 1, "modal-backdrop"], [1, "bulk-selection-info"], ["aria-hidden", "true", 1, "fa-solid", "fa-check-square"], ["mjButton", "", "variant", "flat", "size", "sm", "aria-label", "Clear selection", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-times"], [1, "bulk-action-buttons"], ["mjButton", "", "variant", "secondary", "size", "sm", "aria-label", "Enable selected users", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-on"], [1, "btn-text"], ["mjButton", "", "variant", "secondary", "size", "sm", "aria-label", "Disable selected users", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-off"], ["mjButton", "", "variant", "secondary", "size", "sm", "aria-label", "Assign role to selected users", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-user-tag"], ["mjButton", "", "variant", "danger", "size", "sm", "aria-label", "Delete selected users", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-trash"], ["text", "Loading users...", "size", "medium"], [1, "error-content"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-message"], ["aria-label", "Retry loading users", 1, "retry-button", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-refresh"], [1, "list-header"], [1, "select-all-label"], ["type", "checkbox", "aria-label", "Select all users", 1, "checkbox", 3, "change", "checked", "indeterminate"], [1, "select-all-text"], [1, "selection-count"], ["role", "listitem", 1, "user-card", 3, "expanded", "selected"], ["Icon", "fa-solid fa-users-slash", "Title", "No users found", "Message", "Try adjusting your filters or add a new user", "ActionIcon", "fa-solid fa-rotate-left", 3, "Variant", "ActionText"], ["role", "listitem", 1, "user-card"], ["role", "button", "tabindex", "0", 1, "user-header", 3, "click", "keydown.enter"], [1, "user-selection", 3, "click"], ["type", "checkbox", 1, "checkbox", 3, "change", "checked"], [1, "user-info"], ["aria-hidden", "true", 1, "user-avatar"], [1, "user-details"], [1, "user-name"], [1, "user-email"], [1, "user-meta"], [1, "status-badge"], ["aria-hidden", "true"], [1, "user-actions", "desktop-only", 3, "click"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Edit", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-edit"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click", "title"], ["mjButton", "", "variant", "danger", "size", "sm", "title", "Delete", 3, "click"], ["aria-label", "Toggle user details", 1, "expand-btn"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"], [1, "user-content"], [1, "mobile-actions-bar", 3, "click"], [1, "mobile-action-buttons"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click"], [1, "btn-label"], ["mjButton", "", "variant", "danger", "size", "sm", 3, "click"], [1, "user-stats"], [1, "stat-item"], [1, "stat-label"], [1, "stat-value"], ["aria-hidden", "true", 1, "fa-solid", "fa-id-card"], ["aria-hidden", "true", 1, "fa-solid", "fa-calendar"], ["aria-hidden", "true", 1, "fa-solid", "fa-clock"], [1, "roles-section"], [1, "section-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-user-shield"], [1, "roles-grid"], [1, "no-roles"], [1, "role-item"], ["aria-hidden", "true", 1, "fa-solid", "fa-shield"], ["Icon", "fa-solid fa-users-slash", "Title", "No users found", "Message", "Try adjusting your filters or add a new user", "ActionIcon", "fa-solid fa-rotate-left", 3, "Action", "Variant", "ActionText"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "delete-dialog-title", "aria-describedby", "delete-dialog-desc", 1, "modal-backdrop", 3, "click"], [1, "modal-dialog", 3, "click"], [1, "modal-header"], ["id", "delete-dialog-title", 1, "modal-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle", "text-danger"], ["aria-label", "Close dialog", 1, "modal-close", 3, "click"], ["id", "delete-dialog-desc", 1, "modal-body"], [1, "text-muted"], [1, "modal-footer"], ["mjButton", "", "variant", "danger", 3, "click"], ["mjButton", "", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "bulk-action-dialog-title", "aria-describedby", "bulk-action-dialog-desc", 1, "modal-backdrop", 3, "click"], ["id", "bulk-action-dialog-title", 1, "modal-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-on", "text-success"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-off", "text-warning"], ["id", "bulk-action-dialog-desc", 1, "modal-body"], ["mjButton", "", 3, "click", "variant", "disabled"], ["mjButton", "", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "bulk-role-dialog-title", "aria-describedby", "bulk-role-dialog-desc", 1, "modal-backdrop", 3, "click"], ["id", "bulk-role-dialog-title", 1, "modal-title"], ["id", "bulk-role-dialog-desc", 1, "modal-body"], [1, "form-field"], ["for", "bulk-role-select", 1, "field-label"], ["id", "bulk-role-select", "aria-label", "Select role to assign", 1, "field-select", 3, "ngModelChange", "ngModel"], ["value", ""], [3, "value"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"]], template: function UserManagementComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1405
1457
|
i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-management.component.js","sourceRoot":"","sources":["../../../src/lib/user-management/user-management.component.ts","../../../src/lib/user-management/user-management.component.html"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAwC,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAY,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEvE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGnE,OAAO,EACL,+BAA+B,EAC/B,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,GAEtB,MAAM,iCAAiC,CAAC;;;;;;;;;;IC2CnC,AADF,+BAA0E,cACvC;IAC/B,wBAA2D;IAC3D,4BAAM;IAAA,YAAmE;IAAA,iBAAO;IAChF,kCAAkG;IAAxD,4LAAS,uBAAgB,KAAC;IAClE,wBAAoD;IACpD,uBACF;IACF,AADE,iBAAS,EACL;IAEJ,AADF,+BAAiC,iBACyF;IAAzE,4LAAS,yBAAkB,QAAQ,CAAC,KAAC;IAClF,yBAAwD;IACxD,iCAAuB;IAAA,uBAAM;IAC/B,AAD+B,iBAAO,EAC7B;IACT,mCAA0H;IAA3E,6LAAS,yBAAkB,SAAS,CAAC,KAAC;IACnF,yBAAyD;IACzD,iCAAuB;IAAA,wBAAO;IAChC,AADgC,iBAAO,EAC9B;IACT,mCAAyH;IAA1E,6LAAS,2BAAoB,KAAC;IAC3E,yBAAuD;IACvD,iCAAuB;IAAA,4BAAW;IACpC,AADoC,iBAAO,EAClC;IACT,mCAAqH;IAAzE,6LAAS,yBAAkB,QAAQ,CAAC,KAAC;IAC/E,yBAAoD;IACpD,iCAAuB;IAAA,uBAAM;IAGnC,AADE,AADE,AAD+B,iBAAO,EAC7B,EACL,EACF;;;IAxBI,eAAmE;IAAnE,0GAAmE;;;IA+B3E,+BAAiF;IAC/E,iCAA+D;IACjE,iBAAM;;;;IAMJ,AADF,+BAAgE,cACnC;IACzB,wBAA8E;IAC9E,6BAAyB;IAAA,YAAW;IAAA,iBAAI;IACxC,kCAA0F;IAA7D,4LAAS,wBAAiB,KAAC;IACtD,wBAAsD;IACtD,2BACF;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;IANuB,eAAW;IAAX,kCAAW;;;IA0BhC,gCAA8B;IAAA,YAA4B;IAAA,iBAAO;;;IAAnC,cAA4B;IAA5B,4DAA4B;;;IAyJ9C,+BAAuB;IACrB,wBAAqD;IACrD,YACF;IAAA,iBAAM;;;IADJ,eACF;IADE,6CACF;;;IALJ,+BAAwB;IACtB,8IAKC;IACH,iBAAM;;;;IANJ,cAKC;IALD,cAAA,+BAAqB,CAKpB;;;IAGH,6BAAoB;IAAA,8CAA8B;IAAA,iBAAI;;;;IA5E1D,AAFF,+BAA0B,cAE2C;IAAnC,iLAAS,wBAAwB,KAAC;IAChE,gCAA0D;IACxD,wBAAsE;IACtE,YACF;IAAA,iBAAO;IAEL,AADF,+BAAmC,iBAKhC;IAFC,gQAAS,wBAAc,KAAC;IAGxB,wBAAmD;IACnD,gCAAwB;IAAA,oBAAI;IAC9B,AAD8B,iBAAO,EAC5B;IACT,mCAIC;IAFC,iQAAS,gCAAsB,KAAC;IAGhC,yBAAuG;IACvG,iCAAwB;IAAA,aAA0C;IACpE,AADoE,iBAAO,EAClE;IACT,mCAIC;IAFC,iQAAS,iCAAuB,KAAC;IAGjC,yBAAoD;IACpD,iCAAwB;IAAA,uBAAM;IAGpC,AADE,AADE,AADgC,iBAAO,EAC9B,EACL,EACF;IAIJ,AADF,gCAAwB,eACC;IACrB,yBAAuD;IACvD,iCAAyB;IAAA,sBAAK;IAAA,iBAAO;IACrC,iCAAyB;IACvB,yBAAwE;IACxE,aACF;IACF,AADE,iBAAO,EACH;IACN,gCAAuB;IACrB,yBAAsD;IACtD,iCAAyB;IAAA,2BAAU;IAAA,iBAAO;IAC1C,iCAAyB;IAAA,aAAwC;IACnE,AADmE,iBAAO,EACpE;IACN,gCAAuB;IACrB,yBAAuD;IACvD,iCAAyB;IAAA,yBAAQ;IAAA,iBAAO;IACxC,iCAAyB;IAAA,aAAwC;;IACnE,AADmE,iBAAO,EACpE;IACN,gCAAuB;IACrB,yBAAoD;IACpD,iCAAyB;IAAA,yBAAQ;IAAA,iBAAO;IACxC,iCAAyB;IAAA,aAAwC;;IAErE,AADE,AADmE,iBAAO,EACpE,EACF;IAIJ,AADF,gCAA2B,cACC;IACxB,yBAA0D;IAC1D,iCACF;IAAA,iBAAK;IAUH,AATF,gIAAwC,wGAS/B;IAIb,AADE,iBAAM,EACF;;;;IA9EyB,eAA8B;IAA9B,6CAA8B;IACpD,cAA2C;IAA3C,0DAA2C;IAC9C,cACF;IADE,yEACF;IAKI,eAAuC;;IAQvC,eAA6E;;IAE1E,cAA4E;IAA5E,oFAA4E;IACvD,eAA0C;IAA1C,6DAA0C;IAKlE,cAAyC;;IActC,gBAA6C;IAA7C,4DAA6C;IAChD,cACF;IADE,6CACF;IAKyB,eAAwC;IAAxC,mEAAwC;IAKxC,eAAwC;IAAxC,6EAAwC;IAKxC,eAAwC;IAAxC,6EAAwC;IAUnE,eAWC;IAXD,sEAWC;;;;IArJP,AAPF,+BAKC,cASE;IADC,AAJA,0NAAS,sCAA4B,KAAC,6NAIrB,sCAA4B,KAAC;IAG9C,+BAA+D;IAAnC,kKAAS,wBAAwB,KAAC;IAC5D,iCAME;IAFA,oOAAU,8CAAoC,KAAC;IAGnD,AAPE,iBAME,EACE;IAIJ,AADF,+BAAuB,cACuB;IAC1C,YACF;IAAA,iBAAM;IAEJ,AADF,+BAA0B,aACF;IAAA,YAAe;IAAA,iBAAK;IAC1C,8BAAsB;IAAA,aAAgB;IAE1C,AADE,AADwC,iBAAI,EACtC,EACF;IAIJ,AADF,gCAAuB,gBACqC;IACxD,yBAAsE;IACtE,aACF;IAAA,iBAAO;IACP,gCAA0E;IAAnC,mKAAS,wBAAwB,KAAC;IACvE,mCAKC;IAHC,8NAAS,wBAAc,KAAC;IAIxB,yBAAmD;IACrD,iBAAS;IACT,mCAKC;IAHC,8NAAS,gCAAsB,KAAC;IAIhC,yBAAuG;IACzG,iBAAS;IACT,mCAKC;IAHC,8NAAS,iCAAuB,KAAC;IAIjC,yBAAoD;IAExD,AADE,iBAAS,EACL;IACN,mCAA4D;IAC1D,yBAA2D;IAGjE,AADE,AADE,iBAAS,EACL,EACF;IAGN,mHAA+B;IAoFjC,iBAAM;;;;IA7JJ,AADA,6DAA0C,+CACA;IAQxC,cAA8C;;IAS1C,eAAmC;IAAnC,2DAAmC;;IASnC,eACF;IADE,gEACF;IAEwB,eAAe;IAAf,kCAAe;IACf,eAAgB;IAAhB,mCAAgB;IAMb,eAA8B;IAA9B,6CAA8B;IACpD,cAA2C;IAA3C,0DAA2C;IAC9C,cACF;IADE,yEACF;IAKI,eAAuC;;IASvC,eAAmD;IAAnD,oEAAmD;;IAEhD,cAA4E;IAA5E,oFAA4E;IAK/E,cAAyC;;IAajD,eAmFC;IAnFD,6DAmFC;;;;IAKH,0CAO0C;IAAxC,qNAAU,iCAA0B,KAAC;IAPvC,iBAO0C;;;IAFxC,AAJA,wEAAmD,4DAIC;;;;IAzLpD,AADF,AADF,AAFJ,+BAA4D,cAE/B,gBACS,gBAQ5B;IAFA,6LAAU,wBAAiB,KAAC;IAL9B,iBAOE;IACF,gCAA8B;IAAA,YAAuC;IACvE,AADuE,iBAAO,EACtE;IACR,0GAAoB;IAGtB,iBAAM;IAEN,4GAkKC;IAED,oHAAkC;IAUpC,iBAAM;;;IA1LE,eAAyB;IACzB,AADA,8CAAyB,yCACQ;IAIL,eAAuC;IAAvC,uEAAuC;IAEvE,cAEC;IAFD,8CAEC;IAGH,cAkKC;IAlKD,mCAkKC;IAED,eASC;IATD,4DASC;;;;IAcP,+BAOC;IALC,qNAA6B,KAAK,KAAC;IAMnC,+BAA6D;IAAnC,6JAAS,wBAAwB,KAAC;IAExD,AADF,+BAA0B,aACyB;IAC/C,wBAA+E;IAC/E,gCACF;IAAA,iBAAK;IACL,kCAIC;IAFC,wNAA6B,KAAK,KAAC;IAGnC,wBAAoD;IAExD,AADE,iBAAS,EACL;IAEJ,AADF,+BAAgD,QAC3C;IAAA,sDAAqC;IAAA,+BAAQ;IAAA,aAAuB;IAAA,iBAAS;IAAA,kBAAC;IAAA,iBAAI;IACrF,8BAAsB;IAAA,8CAA6B;IACrD,AADqD,iBAAI,EACnD;IAEJ,AADF,gCAA0B,kBACiC;IAAvB,8LAAS,mBAAY,KAAC;IACtD,yBAAoD;IACpD,8BACF;IAAA,iBAAS;IACT,mCAAqD;IAApC,yNAA6B,KAAK,KAAC;IAClD,yBACF;IAGN,AADE,AADE,AADE,iBAAS,EACL,EACF,EACF;;;IAbgD,gBAAuB;IAAvB,8CAAuB;;;IA8BnE,wBAA+E;;;IAE/E,yBAAqE;;;IAErE,yBAAsE;;;IAexE,6BAAsB;IAAA,6CAA6B;IAAA,iBAAI;;;IAUrD,yBAA8D;IAC9D,+BACF;;;IAEI,wBAAoD;;;IAEpD,wBAAwD;;;IAExD,wBAAyD;;;IADzD,AAFA,AAFF,sHAAmC,gGAEO,gGAEjC;IAGT,YACF;;;IARE,qGAMC;IACD,eACF;IADE,iEACF;;;;IApDR,gCAOC;IALC,0LAAS,yBAAkB,KAAC;IAM5B,+BAA6D;IAAnC,6JAAS,wBAAwB,KAAC;IAExD,AADF,+BAA0B,cAC8B;IAKlD,AAFA,AAFF,uGAAmC,kFAEO,kFAEjC;IAGT,YACF;IAAA,iBAAK;IACL,kCAIC;IAFC,6LAAS,yBAAkB,KAAC;IAG5B,wBAAoD;IAExD,AADE,iBAAS,EACL;IAEJ,AADF,iCAAqD,SAChD;IAAA,aAA4B;IAAA,iBAAI;IACnC,yGAAmC;IAGrC,iBAAM;IAEJ,AADF,gCAA0B,mBAKvB;IAFC,8LAAS,0BAAmB,KAAC;IAM3B,AAHF,gGAAiB,0EAGR;IAUX,iBAAS;IACT,oCAAqE;IAApD,8LAAS,yBAAkB,KAAC;IAC3C,yBACF;IAGN,AADE,AADE,AADE,iBAAS,EACL,EACF,EACF;;;IAhDE,eAMC;IAND,qGAMC;IACD,eACF;IADE,4DACF;IAUG,eAA4B;IAA5B,mDAA4B;IAC/B,cAEC;IAFD,8DAEC;IAIC,eAA8D;IAE9D,AAFA,mFAA8D,8BAExC;IAEtB,cAYC;IAZD,4CAYC;IAE2C,eAAsB;IAAtB,2CAAsB;;;IA4C9D,mCAA0B;IAAA,YAAe;IAAA,iBAAS;;;IAA1C,mCAAiB;IAAC,cAAe;IAAf,mCAAe;;;IAY3C,yBAA8D;IAC9D,8BACF;;;IACE,wBAAuD;IACvD,6BACF;;;;IAnDR,gCAOC;IALC,0LAAS,6BAAsB,KAAC;IAMhC,+BAA6D;IAAnC,6JAAS,wBAAwB,KAAC;IAExD,AADF,+BAA0B,cAC4B;IAClD,wBAAuD;IACvD,YACF;IAAA,iBAAK;IACL,kCAIC;IAFC,6LAAS,6BAAsB,KAAC;IAGhC,wBAAoD;IAExD,AADE,iBAAS,EACL;IAEJ,AADF,gCAAmD,QAC9C;IAAA,+DAA8C;IAAA,iBAAI;IAEnD,AADF,iCAAwB,kBAC4B;IAAA,qBAAI;IAAA,iBAAQ;IAC9D,oCAKC;IAFC,uTAAwB;IAGxB,oCAAiB;IAAA,iCAAgB;IAAA,iBAAS;IAC1C,gHAEC;IAGP,AADE,AADE,iBAAS,EACL,EACF;IAEJ,AADF,gCAA0B,mBAKvB;IAFC,8LAAS,8BAAuB,KAAC;IAM/B,AAHF,gGAAiB,0EAGR;IAIX,iBAAS;IACT,oCAAyE;IAAxD,8LAAS,6BAAsB,KAAC;IAC/C,yBACF;IAGN,AADE,AADE,AADE,iBAAS,EACL,EACF,EACF;;;IA9CE,eACF;IADE,kHACF;IAgBI,eAAwB;IAAxB,iDAAwB;IAIxB,eAEC;IAFD,2BAEC;IAQH,eAAqC;IAArC,iEAAqC;IAErC,cAMC;IAND,4CAMC;IAE+C,eAAsB;IAAtB,2CAAsB;;ADnb3E,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,aAAa;IA0DpC;IAAgC;IAxDpD,mBAAmB;IACZ,KAAK,GAAmB,EAAE,CAAC;IAC3B,aAAa,GAAmB,EAAE,CAAC;IACnC,KAAK,GAAmB,EAAE,CAAC;IAC3B,YAAY,GAAwB,IAAI,CAAC;IACzC,SAAS,GAAG,KAAK,CAAC;IAClB,KAAK,GAAkB,IAAI,CAAC;IAEnC,mCAAmC;IAC5B,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAE3C,eAAe;IACR,cAAc,GAAG,KAAK,CAAC;IACvB,cAAc,GAA0B,IAAI,CAAC;IAEpD,2BAA2B;IACpB,qBAAqB,GAAG,KAAK,CAAC;IAC9B,cAAc,GAA2C,IAAI,CAAC;IAC9D,kBAAkB,GAAG,KAAK,CAAC;IAC3B,UAAU,GAAW,EAAE,CAAC;IAE/B,QAAQ;IACD,KAAK,GAAc;QACxB,UAAU,EAAE,CAAC;QACb,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,CAAC;QAChB,UAAU,EAAE,CAAC,CAAE,wCAAwC;KACxD,CAAC;IAEF,UAAU;IACH,QAAQ,GAAG,IAAI,eAAe,CAAgB;QACnD,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,EAAE;QACR,MAAM,EAAE,EAAE;KACX,CAAC,CAAC;IAEH,WAAW;IACJ,gBAAgB,GAAG,KAAK,CAAC;IACzB,cAAc,GAAG,KAAK,CAAC;IACvB,iBAAiB,GAAG,KAAK,CAAC;IAEjC,yBAAyB;IACjB,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAE5C,oBAAoB;IACZ,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC,CAAC,sBAAsB;IAEzE,qBAAqB;IACd,UAAU,GAAG;QAClB,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,MAAM;QACjB,aAAa,EAAE,KAAK;KACrB,CAAC;IAEiB,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAClD,IAAY,QAAQ,KAAK,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IACrD,YAAoB,GAAsB,EAAU,MAAc;QAChE,KAAK,EAAE,CAAC;QADU,QAAG,GAAH,GAAG,CAAmB;QAAU,WAAM,GAAN,MAAM,CAAQ;IAElE,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,IAAkB;QAC7C,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IAES,aAAa;QACrB,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAES,QAAQ;QAChB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,mEAAmE;IACnE,kCAAkC;IAClC,EAAE;IACF,yDAAyD;IACzD,2EAA2E;IAC3E,0EAA0E;IAC1E,8EAA8E;IAC9E,8EAA8E;IAC9E,6EAA6E;IAC7E,4EAA4E;IAC5E,yEAAyE;IACzE,0EAA0E;IAC1E,yEAAyE;IACzE,6CAA6C;IAC7C,mEAAmE;IAEnE,qEAAqE;IAC7D,cAAc,GAAkB,MAAM,CAAC;IACvC,kBAAkB,GAAsB,KAAK,CAAC;IAEtD;;;;;OAKG;IACK,mBAAmB;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9F,MAAM,KAAK,GAAoC;YAC7C,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YACjC,iBAAiB,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM;YAC5C,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW;YACvC,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa;YAC3C,YAAY,EAAE,OAAO,CAAC,MAAM;YAC5B,YAAY,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;YAClC,cAAc,EAAE,UAAU,EAAE,IAAI,IAAI,IAAI;YACxC,UAAU,EAAE,OAAO,CAAC,MAAM;YAC1B,cAAc,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,IAAI;YAC7C,gBAAgB,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,IAAI,IAAI;YACjD,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;YACjF,iBAAiB,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;YACnF,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;YAC3E,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC;SAC7D,CAAC;QACF,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAAI,EAAE,+BAA+B,CAAC,KAAK,CAAC,CAAC,CAAC;IACvF,CAAC;IAED;;;;OAIG;IACK,wBAAwB;QAC9B,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,IAAI,EAAE;YAC/C;gBACE,IAAI,EAAE,wBAAwB;gBAC9B,WAAW,EAAE,sEAAsE;gBACnF,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE;gBAC1I,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE,CAAC,IAAI,CAAC,4BAA4B,CAAC,MAAM,CAAC;aAC9F;YACD;gBACE,IAAI,EAAE,mBAAmB;gBACzB,WAAW,EAAE,0KAA0K;gBACvL,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;gBACjG,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC;aACxF;YACD;gBACE,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE,sEAAsE;gBACnF,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE;gBAC7G,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;aAClF;YACD;gBACE,IAAI,EAAE,YAAY;gBAClB,WAAW,EAAE,gLAAgL;gBAC7L,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;gBACjG,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC;aACtF;YACD;gBACE,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,uGAAuG;gBACpH,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE;gBACpM,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC;aACrF;YACD;gBACE,IAAI,EAAE,sBAAsB;gBAC5B,WAAW,EAAE,iHAAiH;gBAC9H,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;gBACjG,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE,CAAC,IAAI,CAAC,8BAA8B,CAAC,MAAM,CAAC;aAChG;YACD;gBACE,IAAI,EAAE,iBAAiB;gBACvB,WAAW,EAAE,2EAA2E;gBACxF,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;gBACnD,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE;aACnD;YACD;gBACE,IAAI,EAAE,iBAAiB;gBACvB,WAAW,EAAE,6EAA6E;gBAC1F,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;gBACnD,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE;aAC9C;YACD;gBACE,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE,oDAAoD;gBACjE,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;gBACnD,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE;aAC7C;SACF,CAAC,CAAC;IACL,CAAC;IAEO,4BAA4B,CAAC,MAA+B;QAClE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,EAAE,CAAC;YACrC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,mBAAmB,MAAM,CAAC,MAAM,CAAC,4CAA4C,EAAE,CAAC;QACzH,CAAC;QACD,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAEO,sBAAsB,CAAC,MAA+B;QAC5D,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;YAChB,kDAAkD;YAClD,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAChC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QACD,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACrG,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAEO,gBAAgB,CAAC,MAA+B;QACtD,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,YAAY,CAAC,CAAC;QAC1C,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAE,CAAC;QAC1E,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAEO,oBAAoB,CAAC,MAA+B;QAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC/D,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ;SAC3F,CAAC,CAAC,CAAC,CAAC;QACL,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC1D,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;QAChF,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QACxB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAEO,mBAAmB,CAAC,MAA+B;QACzD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACpF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,uBAAuB,KAAK,gDAAgD,EAAE,CAAC;QACxH,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC;QACrC,MAAM,SAAS,GAAsB,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QACxE,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;QACpC,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QACxB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAEO,8BAA8B,CAAC,MAA+B;QACpE,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC/D,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ;SAC3F,CAAC,CAAC,CAAC,CAAC;QACL,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,mGAAmG;IAC3F,uBAAuB;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC;QAClC,IAAI,CAAC,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACzD,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACzC,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACzC,OAAO,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,cAAc,CAAC,IAAkB,EAAE,KAAoB;QAC7D,QAAQ,KAAK,EAAE,CAAC;YACd,KAAK,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YACtD,KAAK,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;YAC5D,KAAK,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YACpD,KAAK,MAAM,CAAC;YACZ,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;IAEO,sBAAsB;QAC5B,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAChC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YAC7B,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;QAC9F,CAAC;IACH,CAAC;IAEO,gBAAgB;QACtB,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,CAAC;QACjE,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAEQ,WAAW;QAClB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,CAAC,WAAW,EAAE,CAAC;IACtB,CAAC;IAEM,KAAK,CAAC,eAAe;QAC1B,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAElB,6DAA6D;YAC7D,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAClD,IAAI,CAAC,SAAS,EAAE;gBAChB,IAAI,CAAC,SAAS,EAAE;gBAChB,IAAI,CAAC,aAAa,EAAE;aACrB,CAAC,CAAC;YAEH,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YAEnB,0BAA0B;YAC1B,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;YAErC,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,EAAE,CAAC;QAEtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;YACjD,IAAI,CAAC,KAAK,GAAG,6CAA6C,CAAC;QAC7D,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;gBACxB,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;YAC5C,UAAU,EAAE,WAAW;YACvB,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9C,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAe;YAC5C,UAAU,EAAE,WAAW;YACvB,UAAU,EAAE,eAAe;YAC3B,OAAO,EAAE,UAAU;SACpB,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9C,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAmB;YAChD,UAAU,EAAE,gBAAgB;YAC5B,UAAU,EAAE,eAAe;SAC5B,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9C,CAAC;IAEO,oBAAoB,CAAC,SAA6B;QACxD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QAEzB,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAE/B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACnC,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,uBAAuB;QAC7B,IAAI,CAAC,QAAQ;aACV,IAAI,CACH,YAAY,CAAC,GAAG,CAAC,EACjB,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EACvE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB;aACA,SAAS,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,YAAY;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpC,IAAI,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAE/B,sBAAsB;QACtB,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YAC7B,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAChC,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAC7D,CAAC;QACJ,CAAC;QAED,oBAAoB;QACpB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;gBAChC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;gBACtD,OAAO,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC;QAED,sBAAsB;QACtB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACjD,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAChC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC9C,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC/C,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;gBACnD,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CACnD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC9B,wFAAwF;QACxF,IAAI,CAAC,uBAAuB,EAAE,CAAC;IACjC,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,KAAK,GAAG;YACX,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YAC7B,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM;YACtD,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM;YACzD,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,MAAM,CAAE,4BAA4B;SAC5F,CAAC;IACJ,CAAC;IAED,8BAA8B;IACvB,oBAAoB,CAAC,MAAqC;QAC/D,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAChC,CAAC;IAEM,YAAY,CAAC,OAA+B;QACjD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK;YACtB,GAAG,OAAO;SACX,CAAC,CAAC;QACH,6EAA6E;QAC7E,yEAAyE;QACzE,sCAAsC;QACtC,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAEM,UAAU,CAAC,IAAkB;QAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7B,CAAC;IAEM,aAAa;QAClB,IAAI,CAAC,cAAc,GAAG;YACpB,IAAI,EAAE,QAAQ;YACd,cAAc,EAAE,IAAI,CAAC,KAAK;SAC3B,CAAC;QACF,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7B,CAAC;IAEM,QAAQ,CAAC,IAAkB;QAChC,IAAI,CAAC,cAAc,GAAG;YACpB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,MAAM;YACZ,cAAc,EAAE,IAAI,CAAC,KAAK;SAC3B,CAAC;QACF,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7B,CAAC;IAEM,iBAAiB,CAAC,IAAkB;QACzC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAChC,CAAC;IAEM,KAAK,CAAC,UAAU;QACrB,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAE/B,IAAI,CAAC;YACH,6BAA6B;YAC7B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAe,WAAW,CAAC,CAAC;YAC5E,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YAEzD,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzC,IAAI,YAAY,EAAE,CAAC;oBACjB,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;oBAC/B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;oBACzB,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC/B,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,IAAI,uBAAuB,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;gBAC9E,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAC,IAAkB;QAC9C,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC/B,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACpD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,kBAAkB;gBAClD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEM,WAAW;QAChB,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,KAAK,GAAG,oBAAoB,CAAC;YAClC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,qBAAqB;YACrB,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YACrG,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAEpC,gBAAgB;YAChB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBAChC,MAAM,GAAG,GAAG;oBACV,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;oBAC/B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;oBACpC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;oBACnC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;oBAChC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;oBAC/B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU;oBACrC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE;oBAC7E,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE;iBAC9E,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9B,CAAC,CAAC,CAAC;YAEH,2BAA2B;YAC3B,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC,CAAC;YACzE,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAEzC,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;gBACtC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;gBAC/B,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,gBAAgB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAC5F,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC;gBACjC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBAChC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACb,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;YAC/C,IAAI,CAAC,KAAK,GAAG,wBAAwB,CAAC;QACxC,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,KAAa;QAC7B,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACvE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;QAC1C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEM,WAAW;QAChB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAEM,aAAa,CAAC,IAAkB;QACrC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CAAC;IAC/D,CAAC;IAEM,cAAc,CAAC,IAAkB;QACtC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,iBAAiB,CAAC;IAC7D,CAAC;IAEM,eAAe,CAAC,IAAkB;QACvC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,OAAO;gBACV,OAAO,kBAAkB,CAAC;YAC5B,KAAK,MAAM;gBACT,OAAO,SAAS,CAAC;YACnB;gBACE,OAAO,SAAS,CAAC;QACrB,CAAC;IACH,CAAC;IAEM,eAAe,CAAC,IAAkB;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC;IACnF,CAAC;IAEM,kBAAkB,CAAC,MAAwB;QAChD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAE3B,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7B,wCAAwC;YACxC,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;YAC7B,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED,IAAW,eAAe;QACxB,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAClG,OAAO,aAAa,GAAG,CAAC,IAAI,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;IACxE,CAAC;IAED,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;IACnC,CAAC;IAED,IAAW,gBAAgB;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpC,OAAO,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC;IACzD,CAAC;IAED,IAAW,iBAAiB;QAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpC,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK;YAAE,KAAK,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,IAAI,KAAK,EAAE;YAAE,KAAK,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAEM,YAAY;QACjB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK;YACtB,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QACH,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,6EAA6E;IAC7E,EAAE;IACF,0EAA0E;IAC1E,uEAAuE;IACvE,0EAA0E;IAC1E,sEAAsE;IACtE,aAAa;IAEb;;;OAGG;IACH,IAAW,YAAY;QACrB,OAAO;YACL;gBACE,GAAG,EAAE,QAAQ;gBACb,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,QAAQ;gBACf,WAAW,EAAE;oBACX,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;oBAC7B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;oBACnC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;iBACxC;aACF;YACD;gBACE,GAAG,EAAE,MAAM;gBACX,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,MAAM;gBACb,IAAI,EAAE,yBAAyB;gBAC/B,WAAW,EAAE,WAAW;gBACxB,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE;gBAClC,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE;oBAChC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;iBAC9D;aACF;SACF,CAAC;IACJ,CAAC;IAED,mEAAmE;IACnE,IAAW,YAAY;QACrB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAChF,CAAC;IAED,6EAA6E;IAC7E,IAAW,sBAAsB;QAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC9B,OAAO,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,mDAAmD;IAC5C,mBAAmB,CAAC,MAA+B;QACxD,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,GAAI,MAAM,CAAC,QAAQ,CAA6B,IAAI,KAAK,CAAC;QAC1E,CAAC;QACD,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,GAAI,MAAM,CAAC,MAAM,CAAY,IAAI,EAAE,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,0DAA0D;IACnD,sBAAsB;QAC3B,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC;IAED;sDACkD;IAClD,IAAW,cAAc;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,EAAE,IAAI,IAAI,CAAC,sBAAsB,GAAG,CAAC,CAAC;IAC9E,CAAC;IAED;;qEAEiE;IAC1D,wBAAwB;QAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAEM,eAAe;QACpB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,8BAA8B;YAC9B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3E,CAAC;aAAM,CAAC;YACN,4BAA4B;YAC5B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAEM,mBAAmB,CAAC,MAAc,EAAE,KAAa;QACtD,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAEM,cAAc,CAAC,MAAc;QAClC,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAEM,cAAc;QACnB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED,sBAAsB;IACf,iBAAiB,CAAC,MAAuC;QAC9D,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAC/B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC;QAC7B,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;IACpC,CAAC;IAEM,gBAAgB;QACrB,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;QACnC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,iBAAiB;QAC5B,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAEvD,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAEnF,QAAQ,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC5B,KAAK,QAAQ;oBACX,MAAM,IAAI,CAAC,iBAAiB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;oBAClD,MAAM;gBACR,KAAK,SAAS;oBACZ,MAAM,IAAI,CAAC,iBAAiB,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;oBACnD,MAAM;gBACR,KAAK,QAAQ;oBACX,MAAM,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;oBAC1C,MAAM;YACV,CAAC;YAED,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;YACnC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;YAC5C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC;gBAC3E,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,KAAqB,EAAE,QAAiB;QACtE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAE/B,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC9B,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,sBAAsB,EAAE,CAAC;QAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACzB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;YACvB,oEAAoE;YACpE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,QAAQ,GAAG,CAAC,QAAQ,CAAC;YAC5B,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,KAAqB;QACjD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAE/B,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAC9B,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,sBAAsB,EAAE,CAAC;QAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IAED,uBAAuB;IAChB,kBAAkB;QACvB,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAC/B,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,oBAAoB;QACzB,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;IACvB,CAAC;IAEM,KAAK,CAAC,qBAAqB;QAChC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAEnD,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAEzD,0DAA0D;YAC1D,MAAM,gBAAgB,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;gBACvD,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBACzD,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;YAEH,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,sBAAsB,EAAE,CAAC;gBACxD,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;oBACtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAmB,gBAAgB,CAAC,CAAC;oBACzF,QAAQ,CAAC,SAAS,EAAE,CAAC;oBACrB,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;oBACzB,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;oBAClC,QAAQ,CAAC,gBAAgB,GAAG,EAAE,CAAC;oBAC/B,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACxB,CAAC;gBAED,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;oBACvB,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;gBAChF,CAAC;YACH,CAAC;YAED,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;YAChC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC;gBACpF,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEM,oBAAoB;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC;QACjC,QAAQ,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5B,KAAK,QAAQ;gBACX,OAAO,mCAAmC,KAAK,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;YACjF,KAAK,SAAS;gBACZ,OAAO,oCAAoC,KAAK,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;YAClF,KAAK,QAAQ;gBACX,OAAO,mCAAmC,KAAK,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,iCAAiC,CAAC;YAC/G;gBACE,OAAO,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IAEM,kBAAkB;QACvB,QAAQ,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5B,KAAK,QAAQ;gBACX,OAAO,cAAc,CAAC;YACxB,KAAK,SAAS;gBACZ,OAAO,eAAe,CAAC;YACzB,KAAK,QAAQ;gBACX,OAAO,cAAc,CAAC;YACxB;gBACE,OAAO,gBAAgB,CAAC;QAC5B,CAAC;IACH,CAAC;IAEM,uBAAuB;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC;QACjC,QAAQ,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5B,KAAK,QAAQ;gBACX,OAAO,UAAU,KAAK,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACvD,KAAK,SAAS;gBACZ,OAAO,WAAW,KAAK,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACxD,KAAK,QAAQ;gBACX,OAAO,UAAU,KAAK,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACvD;gBACE,OAAO,SAAS,CAAC;QACrB,CAAC;IACH,CAAC;IAED,oBAAoB;IACb,mBAAmB,CAAC,MAAc;QACvC,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAEM,cAAc,CAAC,MAAc;QAClC,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,gCAAgC;IACzB,YAAY,CAAC,MAAc;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC;iHA79BU,uBAAuB;6DAAvB,uBAAuB;YC3BlC,AARF,kDAGqD,aAKzC;YACR,mCAIgB;YAClB,iBAAM;YAKJ,AAJF,8BAAa,wBAOwC;YAAjD,8HAAe,iBAAa,kBAAkB,CAAC,IAAC;YAClD,iBAAiB;YACjB,4CAKiD;YAA/C,uIAAqB,4BAAwB,IAAC;YAC9C,0CAIqC;YAAnC,AADA,iIAAgB,+BAA2B,IAAC,gGACnC,4BAAwB,IAAC;YAGxC,AADE,AADE,iBAAkB,EACA,EAChB;YAEJ,AADF,8BAAa,2BACwD;YAA1B,mHAAW,iBAAa,IAAC;YAAC,iBAAoB;YACvF,iCAAyG;YAA1D,oGAAS,iBAAa,IAAC;YACpE,yBAAoC;YAAC,iCAA8B;YAAA,uBAAM;YAC3E,AAD2E,iBAAO,EACzE;YACT,mCAAiG;YAApD,qGAAS,mBAAe,IAAC;YACpE,yBAAgC;YAAC,iCAA8B;YAAA,yBAAQ;YAG7E,AADE,AADE,AADyE,iBAAO,EACvE,EACL,EACkB;YAGxB,6FAAoB;YAgCpB,8CAAuB;YAErB,4FAAiB;YAOjB,4FAA2B;YAc3B,6FAA4B;YAoM9B,iBAAwB;YAGxB,2CAGwC;YAAtC,qHAAU,8BAA0B,IAAC;YACvC,iBAAiB;YAGjB,6FAAyC;YAyCzC,6FAA6B;YAgE7B,6FAA0B;;YAtZtB,eAA8B;YAC9B,AADA,gDAA8B,2BACR;YAUtB,eAA+B;YAA/B,iDAA+B;YAM/B,cAAsC;YACtC,AADA,wDAAsC,gDACK;YAGzC,cAAuB;YACvB,AADA,yCAAuB,4BACA;YAOR,eAAqB;YAArB,uCAAqB;YAW1C,eA6BC;YA7BD,4CA6BC;YAKC,eAIC;YAJD,yCAIC;YAGD,cAWC;YAXD,uDAWC;YAGD,cAmMC;YAnMD,wDAmMC;YAKD,cAAuB;YACvB,AADA,yCAAuB,+BACG;YAK5B,cAsCC;YAtCD,qEAsCC;YAGD,cA6DC;YA7DD,qDA6DC;YAGD,cA4DC;YA5DD,kDA4DC;;;ADzbU,uBAAuB;IADnC,aAAa,CAAC,aAAa,EAAE,gBAAgB,CAAC;GAClC,uBAAuB,CA89BnC;;iFA99BY,uBAAuB;cAPnC,SAAS;6BACI,KAAK,YACP,oBAAoB;;kFAKnB,uBAAuB","sourcesContent":["import { Component, OnDestroy, ChangeDetectorRef, NgZone } from '@angular/core';\nimport { Subject, BehaviorSubject } from 'rxjs';\nimport { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';\nimport { RunView, Metadata, CompositeKey } from '@memberjunction/core';\nimport { MJUserEntity, MJRoleEntity, MJUserRoleEntity, ResourceData } from '@memberjunction/core-entities';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { FilterFieldConfig } from '@memberjunction/ng-ui-components';\nimport { UserDialogData, UserDialogResult } from './user-dialog/user-dialog.component';\nimport {\n buildUserManagementAgentContext,\n isValidUserStatusFilter,\n resolveUserByIDOrName,\n resolveRoleByIDOrName,\n UserManagementAgentContextInput,\n} from './user-management-agent-context';\n\n/** Sortable user columns + direction the agent can request via SortUsers. */\ntype UserSortField = 'name' | 'email' | 'status' | 'type';\ntype UserSortDirection = 'asc' | 'desc';\n\ninterface UserStats {\n totalUsers: number;\n activeUsers: number;\n inactiveUsers: number;\n adminUsers: number;\n}\n\ninterface FilterOptions {\n status: 'all' | 'active' | 'inactive';\n role: string;\n search: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-user-management',\n templateUrl: './user-management.component.html',\n styleUrls: ['../shared/styles/_admin-patterns.css', './user-management.component.css']\n})\n@RegisterClass(BaseDashboard, 'UserManagement')\nexport class UserManagementComponent extends BaseDashboard implements OnDestroy {\n\n // State management\n public users: MJUserEntity[] = [];\n public filteredUsers: MJUserEntity[] = [];\n public roles: MJRoleEntity[] = [];\n public selectedUser: MJUserEntity | null = null;\n public isLoading = false;\n public error: string | null = null;\n\n // Selection state for bulk actions\n public selectedUserIds = new Set<string>();\n\n // Dialog state\n public showUserDialog = false;\n public userDialogData: UserDialogData | null = null;\n\n // Bulk action dialog state\n public showBulkActionConfirm = false;\n public bulkActionType: 'enable' | 'disable' | 'delete' | null = null;\n public showBulkRoleAssign = false;\n public bulkRoleId: string = '';\n \n // Stats\n public stats: UserStats = {\n totalUsers: 0,\n activeUsers: 0,\n inactiveUsers: 0,\n adminUsers: 0 // This will be based on roles, not Type\n };\n \n // Filters\n public filters$ = new BehaviorSubject<FilterOptions>({\n status: 'all',\n role: '',\n search: ''\n });\n \n // UI State\n public showCreateDialog = false;\n public showEditDialog = false;\n public showDeleteConfirm = false;\n\n // Mobile expansion state\n private expandedUserIds = new Set<string>();\n\n // User-Role mapping\n private userRoleMap = new Map<string, string[]>(); // userId -> roleIds[]\n \n // Grid configuration\n public gridConfig = {\n pageSize: 20,\n sortField: 'Name',\n sortDirection: 'asc'\n };\n \n protected override destroy$ = new Subject<void>();\n private get metadata() { return this.ProviderToUse; }\n constructor(private cdr: ChangeDetectorRef, private ngZone: NgZone) {\n super();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return \"User Management\"\n }\n\n protected initDashboard(): void {\n this.setupFilterSubscription();\n this.registerAgentClientTools();\n }\n\n protected loadData(): void {\n this.loadInitialData();\n }\n\n // ================================================================\n // AI Agent Context & Client Tools\n //\n // 🚨 SAFETY BOUNDARY — READ-ONLY / GOVERNANCE SURFACE 🚨\n // User Management is a security-sensitive admin surface. The agent context\n // and client tools registered here are strictly READ-ONLY / navigational:\n // status/role filters, free-text search, SELECTING a user (view), SORTING the\n // list, clearing filters, refreshing, CSV export of already-visible rows, and\n // navigating to a user's record for viewing. The mutating operations on this\n // component — create/edit/delete users, toggle status, bulk enable/disable/\n // delete, AND bulk role assignment (a role GRANT) — are DELIBERATELY NOT\n // exposed to the agent; they remain human-initiated. Context exposes only\n // counts, active filter selections, and on-screen display names/emails —\n // NEVER passwords, tokens, or other secrets.\n // ================================================================\n\n /** Active agent-requested sort (defaults to the grid's Name/asc). */\n private agentSortField: UserSortField = 'name';\n private agentSortDirection: UserSortDirection = 'asc';\n\n /**\n * Publish the current user-management state to the AI agent. Re-invoked on\n * every meaningful state change (data load, filter, selection, sort) so the\n * agent sees a fresh, read-only, NON-SENSITIVE snapshot. Shaped by the pure\n * {@link buildUserManagementAgentContext} helper (unit-tested in isolation).\n */\n private publishAgentContext(): void {\n const filters = this.filters$.value;\n const roleFilter = filters.role ? this.roles.find(r => UUIDsEqual(r.ID, filters.role)) : null;\n const input: UserManagementAgentContextInput = {\n TotalUserCount: this.users.length,\n FilteredUserCount: this.filteredUsers.length,\n ActiveUserCount: this.stats.activeUsers,\n InactiveUserCount: this.stats.inactiveUsers,\n StatusFilter: filters.status,\n RoleFilterId: filters.role || null,\n RoleFilterName: roleFilter?.Name ?? null,\n SearchText: filters.search,\n SelectedUserId: this.selectedUser?.ID ?? null,\n SelectedUserName: this.selectedUser?.Name ?? null,\n VisibleUserNames: this.filteredUsers.map(u => u.Name ?? '').filter(n => n !== ''),\n VisibleUserEmails: this.filteredUsers.map(u => u.Email ?? '').filter(e => e !== ''),\n AvailableRoleNames: this.roles.map(r => r.Name ?? '').filter(n => n !== ''),\n VisibleColumns: ['Name', 'Email', 'Type', 'Status', 'Roles'],\n };\n this.navigationService.SetAgentContext(this, buildUserManagementAgentContext(input));\n }\n\n /**\n * Register the read-only / navigational client tools the agent may invoke.\n * Every Handler is tolerant: validates input and returns\n * `{ Success: false, ErrorMessage }` rather than throwing.\n */\n private registerAgentClientTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'SwitchUserStatusFilter',\n Description: 'Filter the user list by status. Valid values: all, active, inactive.',\n ParameterSchema: { type: 'object', properties: { status: { type: 'string', enum: ['all', 'active', 'inactive'] } }, required: ['status'] },\n Handler: async (params: Record<string, unknown>) => this.handleSwitchStatusFilterTool(params),\n },\n {\n Name: 'FilterUsersByRole',\n Description: 'Filter the user list by role. Accepts a role name OR a role ID; pass an empty string to clear the role filter. Available role names are published in AvailableRoleNames.',\n ParameterSchema: { type: 'object', properties: { role: { type: 'string' } }, required: ['role'] },\n Handler: async (params: Record<string, unknown>) => this.handleFilterByRoleTool(params),\n },\n {\n Name: 'SearchUsers',\n Description: 'Free-text search across user name, email, first name, and last name.',\n ParameterSchema: { type: 'object', properties: { searchText: { type: 'string' } }, required: ['searchText'] },\n Handler: async (params: Record<string, unknown>) => this.handleSearchTool(params),\n },\n {\n Name: 'SelectUser',\n Description: 'Select a user for VIEWING by ID or name (exact ID → exact name/email → partial match). Read-only — does not edit the user. Updates SelectedUserId/SelectedUserName in context.',\n ParameterSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] },\n Handler: async (params: Record<string, unknown>) => this.handleSelectUserTool(params),\n },\n {\n Name: 'SortUsers',\n Description: 'Sort the visible user list. field: name | email | status | type. direction: asc | desc (default asc).',\n ParameterSchema: { type: 'object', properties: { field: { type: 'string', enum: ['name', 'email', 'status', 'type'] }, direction: { type: 'string', enum: ['asc', 'desc'] } }, required: ['field'] },\n Handler: async (params: Record<string, unknown>) => this.handleSortUsersTool(params),\n },\n {\n Name: 'NavigateToUserRecord',\n Description: 'Open the record for a user (by ID or name) in a tab for VIEWING. Read-only navigation — does not edit the user.',\n ParameterSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] },\n Handler: async (params: Record<string, unknown>) => this.handleNavigateToUserRecordTool(params),\n },\n {\n Name: 'ClearAllFilters',\n Description: 'Clear all user filters (status, role, and search) and show the full list.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => this.handleClearFiltersTool(),\n },\n {\n Name: 'RefreshUserList',\n Description: 'Reload the user list from the server. Read-only — does not mutate any data.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => this.handleRefreshTool(),\n },\n {\n Name: 'ExportUsers',\n Description: 'Export the currently filtered users as a CSV file.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => this.handleExportTool(),\n },\n ]);\n }\n\n private handleSwitchStatusFilterTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const status = params?.['status'];\n if (!isValidUserStatusFilter(status)) {\n return { Success: false, ErrorMessage: `Invalid status \"${String(status)}\". Expected one of: all, active, inactive.` };\n }\n this.onStatusFilterChange(status);\n this.publishAgentContext();\n return { Success: true };\n }\n\n private handleFilterByRoleTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const raw = String(params?.['role'] ?? '');\n if (!raw.trim()) {\n // Empty string explicitly clears the role filter.\n this.updateFilter({ role: '' });\n this.publishAgentContext();\n return { Success: true };\n }\n const resolved = resolveRoleByIDOrName(raw, this.roles.map(r => ({ ID: r.ID, Name: r.Name ?? '' })));\n if (!resolved.ok) {\n return { Success: false, ErrorMessage: resolved.error };\n }\n this.updateFilter({ role: resolved.match.ID });\n this.publishAgentContext();\n return { Success: true };\n }\n\n private handleSearchTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const searchText = params?.['searchText'];\n if (typeof searchText !== 'string') {\n return { Success: false, ErrorMessage: 'searchText must be a string.' };\n }\n this.updateFilter({ search: searchText });\n this.publishAgentContext();\n return { Success: true };\n }\n\n private handleSelectUserTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const raw = String(params?.['user'] ?? '');\n const resolved = resolveUserByIDOrName(raw, this.users.map(u => ({\n ID: u.ID, Name: u.Name ?? '', Email: u.Email, FirstName: u.FirstName, LastName: u.LastName,\n })));\n if (!resolved.ok) {\n return { Success: false, ErrorMessage: resolved.error };\n }\n const match = this.users.find(u => UUIDsEqual(u.ID, resolved.match.ID)) ?? null;\n this.selectedUser = match;\n this.cdr.markForCheck();\n this.publishAgentContext();\n return { Success: true };\n }\n\n private handleSortUsersTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const field = String(params?.['field'] ?? '');\n if (field !== 'name' && field !== 'email' && field !== 'status' && field !== 'type') {\n return { Success: false, ErrorMessage: `Invalid sort field \"${field}\". Expected one of: name, email, status, type.` };\n }\n const dirRaw = params?.['direction'];\n const direction: UserSortDirection = dirRaw === 'desc' ? 'desc' : 'asc';\n this.agentSortField = field;\n this.agentSortDirection = direction;\n this.applySortToVisibleUsers();\n this.cdr.markForCheck();\n this.publishAgentContext();\n return { Success: true };\n }\n\n private handleNavigateToUserRecordTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const raw = String(params?.['user'] ?? '');\n const resolved = resolveUserByIDOrName(raw, this.users.map(u => ({\n ID: u.ID, Name: u.Name ?? '', Email: u.Email, FirstName: u.FirstName, LastName: u.LastName,\n })));\n if (!resolved.ok) {\n return { Success: false, ErrorMessage: resolved.error };\n }\n this.navigationService.OpenEntityRecord('MJ: Users', CompositeKey.FromID(resolved.match.ID));\n return { Success: true };\n }\n\n /** Sort filteredUsers in place per the active agent-requested sort. Read-only display ordering. */\n private applySortToVisibleUsers(): void {\n const dir = this.agentSortDirection === 'desc' ? -1 : 1;\n const field = this.agentSortField;\n this.filteredUsers = [...this.filteredUsers].sort((a, b) => {\n const av = this.sortKeyForUser(a, field);\n const bv = this.sortKeyForUser(b, field);\n return av.localeCompare(bv) * dir;\n });\n }\n\n private sortKeyForUser(user: MJUserEntity, field: UserSortField): string {\n switch (field) {\n case 'email': return (user.Email ?? '').toLowerCase();\n case 'status': return user.IsActive ? 'active' : 'inactive';\n case 'type': return (user.Type ?? '').toLowerCase();\n case 'name':\n default: return (user.Name ?? '').toLowerCase();\n }\n }\n\n private handleClearFiltersTool(): { Success: boolean } {\n this.resetAllFiltersAndSearch();\n this.publishAgentContext();\n return { Success: true };\n }\n\n private async handleRefreshTool(): Promise<{ Success: boolean; ErrorMessage?: string }> {\n try {\n await this.loadInitialData();\n this.publishAgentContext();\n return { Success: true };\n } catch (e) {\n return { Success: false, ErrorMessage: e instanceof Error ? e.message : 'Refresh failed.' };\n }\n }\n\n private handleExportTool(): { Success: boolean; ErrorMessage?: string } {\n if (this.filteredUsers.length === 0) {\n return { Success: false, ErrorMessage: 'No users to export.' };\n }\n this.exportUsers();\n return { Success: true };\n }\n\n override ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n super.ngOnDestroy();\n }\n \n public async loadInitialData(): Promise<void> {\n try {\n this.isLoading = true;\n this.error = null;\n \n // Load users, roles, and user-role relationships in parallel\n const [users, roles, userRoles] = await Promise.all([\n this.loadUsers(),\n this.loadRoles(),\n this.loadUserRoles()\n ]);\n \n this.users = users;\n this.roles = roles;\n \n // Build user-role mapping\n this.buildUserRoleMapping(userRoles);\n \n this.calculateStats();\n this.applyFilters();\n \n } catch (error) {\n console.error('Error loading user data:', error);\n this.error = 'Failed to load user data. Please try again.';\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n this.publishAgentContext();\n });\n }\n }\n\n private async loadUsers(): Promise<MJUserEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ResultType: 'entity_object'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private async loadRoles(): Promise<MJRoleEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n ResultType: 'entity_object',\n OrderBy: 'Name ASC'\n });\n \n return result.Success ? result.Results : [];\n }\n\n private async loadUserRoles(): Promise<MJUserRoleEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJUserRoleEntity>({\n EntityName: 'MJ: User Roles',\n ResultType: 'entity_object'\n });\n \n return result.Success ? result.Results : [];\n }\n\n private buildUserRoleMapping(userRoles: MJUserRoleEntity[]): void {\n this.userRoleMap.clear();\n \n userRoles.forEach(userRole => {\n const userId = userRole.UserID;\n const roleId = userRole.RoleID;\n \n if (!this.userRoleMap.has(userId)) {\n this.userRoleMap.set(userId, []);\n }\n \n this.userRoleMap.get(userId)!.push(roleId);\n });\n }\n \n private setupFilterSubscription(): void {\n this.filters$\n .pipe(\n debounceTime(300),\n distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),\n takeUntil(this.destroy$)\n )\n .subscribe(() => {\n this.applyFilters();\n this.publishAgentContext();\n });\n }\n\n private applyFilters(): void {\n const filters = this.filters$.value;\n let filtered = [...this.users];\n\n // Apply status filter\n if (filters.status !== 'all') {\n filtered = filtered.filter(user => \n filters.status === 'active' ? user.IsActive : !user.IsActive\n );\n }\n \n // Apply role filter\n if (filters.role) {\n filtered = filtered.filter(user => {\n const userRoles = this.userRoleMap.get(user.ID) || [];\n return userRoles.includes(filters.role);\n });\n }\n \n // Apply search filter\n if (filters.search) {\n const searchLower = filters.search.toLowerCase();\n filtered = filtered.filter(user =>\n user.Name?.toLowerCase().includes(searchLower) ||\n user.Email?.toLowerCase().includes(searchLower) ||\n user.FirstName?.toLowerCase().includes(searchLower) ||\n user.LastName?.toLowerCase().includes(searchLower)\n );\n }\n \n this.filteredUsers = filtered;\n // Preserve any agent-requested sort across filter changes (read-only display ordering).\n this.applySortToVisibleUsers();\n }\n\n private calculateStats(): void {\n this.stats = {\n totalUsers: this.users.length,\n activeUsers: this.users.filter(u => u.IsActive).length,\n inactiveUsers: this.users.filter(u => !u.IsActive).length,\n adminUsers: this.users.filter(u => u.Type === 'Owner').length // Using Owner as admin type\n };\n }\n \n // Public methods for template\n public onStatusFilterChange(status: 'all' | 'active' | 'inactive'): void {\n this.updateFilter({ status });\n }\n\n public updateFilter(partial: Partial<FilterOptions>): void {\n this.filters$.next({\n ...this.filters$.value,\n ...partial\n });\n // Discrete changes (chips, popover dropdowns) apply immediately. Text search\n // still goes through the 300ms debounce in setupFilterSubscription so we\n // don't re-filter on every keystroke.\n if (!('search' in partial)) {\n this.applyFilters();\n this.cdr.markForCheck();\n }\n }\n \n public selectUser(user: MJUserEntity): void {\n this.selectedUser = user;\n this.showEditDialog = true;\n }\n \n public createNewUser(): void {\n this.userDialogData = {\n mode: 'create',\n availableRoles: this.roles\n };\n this.showUserDialog = true;\n }\n \n public editUser(user: MJUserEntity): void {\n this.userDialogData = {\n user: user,\n mode: 'edit',\n availableRoles: this.roles\n };\n this.showUserDialog = true;\n }\n \n public confirmDeleteUser(user: MJUserEntity): void {\n this.selectedUser = user;\n this.showDeleteConfirm = true;\n }\n \n public async deleteUser(): Promise<void> {\n if (!this.selectedUser) return;\n \n try {\n // Load user entity to delete\n const user = await this.metadata.GetEntityObject<MJUserEntity>('MJ: Users');\n const loadResult = await user.Load(this.selectedUser.ID);\n \n if (loadResult) {\n const deleteResult = await user.Delete();\n if (deleteResult) {\n this.showDeleteConfirm = false;\n this.selectedUser = null;\n await this.loadInitialData();\n } else {\n throw new Error(user.LatestResult?.Message || 'Failed to delete user');\n }\n } else {\n throw new Error('User not found or permission denied');\n }\n } catch (error: unknown) {\n console.error('Error deleting user:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Failed to delete user';\n this.cdr.markForCheck();\n });\n }\n }\n \n public async toggleUserStatus(user: MJUserEntity): Promise<void> {\n try {\n user.IsActive = !user.IsActive;\n await user.Save();\n this.ngZone.run(() => {\n this.calculateStats();\n this.cdr.markForCheck();\n });\n } catch (error) {\n console.error('Error updating user status:', error);\n this.ngZone.run(() => {\n user.IsActive = !user.IsActive; // Revert on error\n this.cdr.markForCheck();\n });\n }\n }\n \n public exportUsers(): void {\n if (this.filteredUsers.length === 0) {\n this.error = 'No users to export';\n return;\n }\n\n try {\n // Create CSV content\n const headers = ['Name', 'First Name', 'Last Name', 'Email', 'Type', 'Status', 'Created', 'Updated'];\n const csvRows = [headers.join(',')];\n\n // Add user data\n this.filteredUsers.forEach(user => {\n const row = [\n this.escapeCSV(user.Name || ''),\n this.escapeCSV(user.FirstName || ''),\n this.escapeCSV(user.LastName || ''),\n this.escapeCSV(user.Email || ''),\n this.escapeCSV(user.Type || ''),\n user.IsActive ? 'Active' : 'Inactive',\n user.__mj_CreatedAt ? new Date(user.__mj_CreatedAt).toLocaleDateString() : '',\n user.__mj_UpdatedAt ? new Date(user.__mj_UpdatedAt).toLocaleDateString() : ''\n ];\n csvRows.push(row.join(','));\n });\n\n // Create and download file\n const csvContent = csvRows.join('\\n');\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });\n const link = document.createElement('a');\n \n if (link.download !== undefined) {\n const url = URL.createObjectURL(blob);\n link.setAttribute('href', url);\n link.setAttribute('download', `users_export_${new Date().toISOString().split('T')[0]}.csv`);\n link.style.visibility = 'hidden';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n } catch (error) {\n console.error('Error exporting users:', error);\n this.error = 'Failed to export users';\n }\n }\n\n private escapeCSV(value: string): string {\n if (value.includes(',') || value.includes('\"') || value.includes('\\n')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n }\n \n public refreshData(): void {\n this.loadInitialData();\n }\n \n public getStatusIcon(user: MJUserEntity): string {\n return user.IsActive ? 'fa-check-circle' : 'fa-times-circle';\n }\n \n public getStatusClass(user: MJUserEntity): string {\n return user.IsActive ? 'status-active' : 'status-inactive';\n }\n \n public getUserTypeIcon(user: MJUserEntity): string {\n switch (user.Type) {\n case 'Owner':\n return 'fa-shield-halved';\n case 'User':\n return 'fa-user';\n default:\n return 'fa-user';\n }\n }\n \n public getUserInitials(user: MJUserEntity): string {\n const first = user.FirstName?.charAt(0) || '';\n const last = user.LastName?.charAt(0) || '';\n return (first + last).toUpperCase() || user.Name?.charAt(0).toUpperCase() || 'U';\n }\n\n public onUserDialogResult(result: UserDialogResult): void {\n this.showUserDialog = false;\n this.userDialogData = null;\n\n if (result.action === 'save') {\n // Refresh the user list to show changes\n this.loadInitialData();\n }\n }\n\n // Selection methods for bulk actions\n public get isAllSelected(): boolean {\n return this.filteredUsers.length > 0 &&\n this.filteredUsers.every(user => this.selectedUserIds.has(user.ID));\n }\n\n public get isIndeterminate(): boolean {\n const selectedCount = this.filteredUsers.filter(user => this.selectedUserIds.has(user.ID)).length;\n return selectedCount > 0 && selectedCount < this.filteredUsers.length;\n }\n\n public get hasSelection(): boolean {\n return this.selectedUserIds.size > 0;\n }\n\n public get selectedCount(): number {\n return this.selectedUserIds.size;\n }\n\n public get hasActiveFilters(): boolean {\n const filters = this.filters$.value;\n return filters.status !== 'all' || filters.role !== '';\n }\n\n public get activeFilterCount(): number {\n let count = 0;\n const filters = this.filters$.value;\n if (filters.status !== 'all') count++;\n if (filters.role !== '') count++;\n return count;\n }\n\n public clearFilters(): void {\n this.filters$.next({\n ...this.filters$.value,\n status: 'all',\n role: ''\n });\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n // -- Filter panel binding (mj-filter-panel inside the popover) -------------\n //\n // Only Role lives inside the popover — Status is exposed as visible chips\n // in the filter card alongside search (the standardized \"quick toggle\"\n // pattern used by Scheduling's exterior chrome). The popover badge counts\n // only popover-resident filters (Role), so Status changes don't ghost\n // the badge.\n\n /**\n * FilterFieldConfig[] describing the popover's Role field. Driven off\n * `roles[]` so the dropdown stays in sync as roles load.\n */\n public get filterFields(): FilterFieldConfig[] {\n return [\n {\n key: 'status',\n type: 'chips',\n label: 'Status',\n chipOptions: [\n { text: 'All', value: 'all' },\n { text: 'Active', value: 'active' },\n { text: 'Inactive', value: 'inactive' },\n ],\n },\n {\n key: 'role',\n type: 'dropdown',\n label: 'Role',\n icon: 'fa-solid fa-user-shield',\n placeholder: 'All Roles',\n filterable: this.roles.length > 10,\n options: [\n { text: 'All Roles', value: '' },\n ...this.roles.map(r => ({ text: r.Name ?? '', value: r.ID }))\n ]\n }\n ];\n }\n\n /** Current popover field values keyed by FilterFieldConfig.key. */\n public get filterValues(): Record<string, unknown> {\n return { status: this.filters$.value.status, role: this.filters$.value.role };\n }\n\n /** Total active filters (Status + Role) — drives the Filter button badge. */\n public get TotalActiveFilterCount(): number {\n const f = this.filters$.value;\n return (f.status !== 'all' ? 1 : 0) + (f.role !== '' ? 1 : 0);\n }\n\n /** Apply a value change from <mj-filter-panel>. */\n public onFilterPanelChange(values: Record<string, unknown>): void {\n const partial: Partial<FilterOptions> = {};\n if ('status' in values) {\n partial.status = (values['status'] as FilterOptions['status']) || 'all';\n }\n if ('role' in values) {\n partial.role = (values['role'] as string) ?? '';\n }\n this.updateFilter(partial);\n }\n\n /** Clear all filters (Status + Role); search persists. */\n public clearAllAppliedFilters(): void {\n this.updateFilter({ status: 'all', role: '' });\n }\n\n /** True when search and/or panel filters are narrowing the list — gates the\n * no-results empty-state \"Reset filters\" CTA. */\n public get IsListNarrowed(): boolean {\n return this.filters$.value.search !== '' || this.TotalActiveFilterCount > 0;\n }\n\n /** Reset everything narrowing the list (search + Status + Role) and refresh\n * immediately. Wired to the no-results empty-state CTA. Unlike\n * clearAllAppliedFilters(), this also clears the search box. */\n public resetAllFiltersAndSearch(): void {\n this.filters$.next({ status: 'all', role: '', search: '' });\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n public toggleSelectAll(): void {\n if (this.isAllSelected) {\n // Deselect all filtered users\n this.filteredUsers.forEach(user => this.selectedUserIds.delete(user.ID));\n } else {\n // Select all filtered users\n this.filteredUsers.forEach(user => this.selectedUserIds.add(user.ID));\n }\n }\n\n public toggleUserSelection(userId: string, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n if (this.selectedUserIds.has(userId)) {\n this.selectedUserIds.delete(userId);\n } else {\n this.selectedUserIds.add(userId);\n }\n }\n\n public isUserSelected(userId: string): boolean {\n return this.selectedUserIds.has(userId);\n }\n\n public clearSelection(): void {\n this.selectedUserIds.clear();\n }\n\n // Bulk action methods\n public confirmBulkAction(action: 'enable' | 'disable' | 'delete'): void {\n if (!this.hasSelection) return;\n this.bulkActionType = action;\n this.showBulkActionConfirm = true;\n }\n\n public cancelBulkAction(): void {\n this.showBulkActionConfirm = false;\n this.bulkActionType = null;\n }\n\n public async executeBulkAction(): Promise<void> {\n if (!this.bulkActionType || !this.hasSelection) return;\n\n try {\n this.isLoading = true;\n const selectedUsers = this.users.filter(user => this.selectedUserIds.has(user.ID));\n\n switch (this.bulkActionType) {\n case 'enable':\n await this.bulkSetUserStatus(selectedUsers, true);\n break;\n case 'disable':\n await this.bulkSetUserStatus(selectedUsers, false);\n break;\n case 'delete':\n await this.bulkDeleteUsers(selectedUsers);\n break;\n }\n\n this.clearSelection();\n this.showBulkActionConfirm = false;\n this.bulkActionType = null;\n await this.loadInitialData();\n } catch (error: unknown) {\n console.error('Bulk action failed:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Bulk action failed';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n private async bulkSetUserStatus(users: MJUserEntity[], isActive: boolean): Promise<void> {\n if (users.length === 0) return;\n\n const md = this.ProviderToUse;\n const tg = await md.CreateTransactionGroup();\n for (const user of users) {\n user.IsActive = isActive;\n user.TransactionGroup = tg;\n await user.Save();\n }\n if (!await tg.Submit()) {\n // Server rolled back — restore in-memory flags to their prior state\n for (const user of users) {\n user.IsActive = !isActive;\n }\n throw new Error('Failed to update users — all changes have been rolled back');\n }\n }\n\n private async bulkDeleteUsers(users: MJUserEntity[]): Promise<void> {\n if (users.length === 0) return;\n\n const md = this.ProviderToUse;\n const tg = await md.CreateTransactionGroup();\n for (const user of users) {\n user.TransactionGroup = tg;\n await user.Delete();\n }\n if (!await tg.Submit()) {\n throw new Error('Failed to delete users — all changes have been rolled back');\n }\n }\n\n // Bulk role assignment\n public openBulkRoleAssign(): void {\n if (!this.hasSelection) return;\n this.bulkRoleId = '';\n this.showBulkRoleAssign = true;\n }\n\n public cancelBulkRoleAssign(): void {\n this.showBulkRoleAssign = false;\n this.bulkRoleId = '';\n }\n\n public async executeBulkRoleAssign(): Promise<void> {\n if (!this.bulkRoleId || !this.hasSelection) return;\n\n try {\n this.isLoading = true;\n const selectedUserIds = Array.from(this.selectedUserIds);\n\n // Collect only the users that don't already have the role\n const usersNeedingRole = selectedUserIds.filter(userId => {\n const existingRoles = this.userRoleMap.get(userId) || [];\n return !existingRoles.includes(this.bulkRoleId);\n });\n\n if (usersNeedingRole.length > 0) {\n const tg = await this.metadata.CreateTransactionGroup();\n for (const userId of usersNeedingRole) {\n const userRole = await this.metadata.GetEntityObject<MJUserRoleEntity>('MJ: User Roles');\n userRole.NewRecord();\n userRole.UserID = userId;\n userRole.RoleID = this.bulkRoleId;\n userRole.TransactionGroup = tg;\n await userRole.Save();\n }\n\n if (!await tg.Submit()) {\n throw new Error('Failed to assign roles — all changes have been rolled back');\n }\n }\n\n this.clearSelection();\n this.showBulkRoleAssign = false;\n this.bulkRoleId = '';\n await this.loadInitialData();\n } catch (error: unknown) {\n console.error('Bulk role assignment failed:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Bulk role assignment failed';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n public getBulkActionMessage(): string {\n const count = this.selectedCount;\n switch (this.bulkActionType) {\n case 'enable':\n return `Are you sure you want to enable ${count} user${count > 1 ? 's' : ''}?`;\n case 'disable':\n return `Are you sure you want to disable ${count} user${count > 1 ? 's' : ''}?`;\n case 'delete':\n return `Are you sure you want to delete ${count} user${count > 1 ? 's' : ''}? This action cannot be undone.`;\n default:\n return '';\n }\n }\n\n public getBulkActionTitle(): string {\n switch (this.bulkActionType) {\n case 'enable':\n return 'Enable Users';\n case 'disable':\n return 'Disable Users';\n case 'delete':\n return 'Delete Users';\n default:\n return 'Confirm Action';\n }\n }\n\n public getBulkActionButtonText(): string {\n const count = this.selectedCount;\n switch (this.bulkActionType) {\n case 'enable':\n return `Enable ${count} User${count > 1 ? 's' : ''}`;\n case 'disable':\n return `Disable ${count} User${count > 1 ? 's' : ''}`;\n case 'delete':\n return `Delete ${count} User${count > 1 ? 's' : ''}`;\n default:\n return 'Confirm';\n }\n }\n\n // Expansion methods\n public toggleUserExpansion(userId: string): void {\n if (this.expandedUserIds.has(userId)) {\n this.expandedUserIds.delete(userId);\n } else {\n this.expandedUserIds.add(userId);\n }\n }\n\n public isUserExpanded(userId: string): boolean {\n return this.expandedUserIds.has(userId);\n }\n\n // Get roles for a specific user\n public getUserRoles(userId: string): MJRoleEntity[] {\n const roleIds = this.userRoleMap.get(userId) || [];\n return this.roles.filter(role => roleIds.some(id => UUIDsEqual(id, role.ID)));\n }\n}","<!--\n Interior chrome — <mj-page-header-interior> is the body-level sibling of\n <mj-page-header>. Same slot conventions ([toolbar] / [meta] / [actions]);\n different visual shape (single-row card). See Section 10 of\n explorer-chrome-conventions.\n-->\n<mj-page-header-interior\n AriaLabel=\"Filter users\"\n Title=\"Users\"\n Subtitle=\"Manage user accounts, roles, and access\">\n <!-- X-of-Y filtered count earns its meta spot per chrome conventions §2 —\n tells the user how the search/filter is narrowing the data, signal at\n any scale. Partition badges (active/inactive/owners) stay dropped —\n they 1:1 mirror the filter chips in [toolbar] below. -->\n <div meta>\n <mj-stat-badge\n [Count]=\"filteredUsers.length\"\n [Total]=\"users.length\"\n Label=\"users\">\n </mj-stat-badge>\n </div>\n <div toolbar>\n <!-- Concise-chrome control bar: search · Filter. Status + Role live behind\n the one Filter button; applied filters show as removable chips below\n the card. On mobile the popover docks as a bottom sheet. -->\n <mj-page-search\n Placeholder=\"Search users by name or email...\"\n [Value]=\"filters$.value.search\"\n (ValueChange)=\"updateFilter({ search: $event })\">\n </mj-page-search>\n <mj-filter-popover\n Label=\"Filters\"\n Icon=\"fa-solid fa-filter\"\n [ActiveCount]=\"TotalActiveFilterCount\"\n [ShowClearAll]=\"TotalActiveFilterCount > 0\"\n (ClearAllRequested)=\"clearAllAppliedFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterPanelChange($event)\"\n (Reset)=\"clearAllAppliedFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"isLoading\" (Clicked)=\"refreshData()\"></mj-refresh-button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"exportUsers()\" aria-label=\"Export users to file\">\n <i class=\"fa-solid fa-download\"></i> <span class=\"mj-action-label\">Export</span>\n </button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"createNewUser()\" aria-label=\"Add new user\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"mj-action-label\">Add User</span>\n </button>\n </div>\n</mj-page-header-interior>\n\n <!-- Bulk Action Toolbar — contextual band shown above the list when users are selected. -->\n @if (hasSelection) {\n <div class=\"bulk-action-toolbar\" role=\"toolbar\" aria-label=\"Bulk actions\">\n <div class=\"bulk-selection-info\">\n <i class=\"fa-solid fa-check-square\" aria-hidden=\"true\"></i>\n <span>{{ selectedCount }} user{{ selectedCount > 1 ? 's' : '' }} selected</span>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"clearSelection()\" aria-label=\"Clear selection\">\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n Clear\n </button>\n </div>\n <div class=\"bulk-action-buttons\">\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"confirmBulkAction('enable')\" aria-label=\"Enable selected users\">\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Enable</span>\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"confirmBulkAction('disable')\" aria-label=\"Disable selected users\">\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Disable</span>\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"openBulkRoleAssign()\" aria-label=\"Assign role to selected users\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Assign Role</span>\n </button>\n <button mjButton variant=\"danger\" size=\"sm\" (click)=\"confirmBulkAction('delete')\" aria-label=\"Delete selected users\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Delete</span>\n </button>\n </div>\n </div>\n }\n\n <!-- Scrollable Content Section — owned by <mj-page-body-interior>. -->\n <mj-page-body-interior>\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading users...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\" aria-live=\"assertive\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\" aria-hidden=\"true\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button class=\"retry-button\" (click)=\"loadInitialData()\" aria-label=\"Retry loading users\">\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Users List -->\n @if (!isLoading && !error) {\n <div class=\"users-list\" role=\"list\" aria-label=\"Users list\">\n <!-- List Header with Select All -->\n <div class=\"list-header\">\n <label class=\"select-all-label\">\n <input\n type=\"checkbox\"\n class=\"checkbox\"\n [checked]=\"isAllSelected\"\n [indeterminate]=\"isIndeterminate\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all users\"\n />\n <span class=\"select-all-text\">Select All ({{ filteredUsers.length }})</span>\n </label>\n @if (hasSelection) {\n <span class=\"selection-count\">{{ selectedCount }} selected</span>\n }\n </div>\n\n @for (user of filteredUsers; track user.ID) {\n <div\n class=\"user-card\"\n [class.expanded]=\"isUserExpanded(user.ID)\"\n [class.selected]=\"isUserSelected(user.ID)\"\n role=\"listitem\"\n >\n <!-- User Card Header - Always Visible -->\n <div\n class=\"user-header\"\n (click)=\"toggleUserExpansion(user.ID)\"\n role=\"button\"\n [attr.aria-expanded]=\"isUserExpanded(user.ID)\"\n tabindex=\"0\"\n (keydown.enter)=\"toggleUserExpansion(user.ID)\"\n >\n <!-- Selection Checkbox -->\n <div class=\"user-selection\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n class=\"checkbox\"\n [checked]=\"isUserSelected(user.ID)\"\n (change)=\"toggleUserSelection(user.ID, $event)\"\n [attr.aria-label]=\"'Select ' + user.Name\"\n />\n </div>\n\n <!-- User Info -->\n <div class=\"user-info\">\n <div class=\"user-avatar\" aria-hidden=\"true\">\n {{ getUserInitials(user) }}\n </div>\n <div class=\"user-details\">\n <h3 class=\"user-name\">{{ user.Name }}</h3>\n <p class=\"user-email\">{{ user.Email }}</p>\n </div>\n </div>\n\n <!-- User Meta -->\n <div class=\"user-meta\">\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n <div class=\"user-actions desktop-only\" (click)=\"$event.stopPropagation()\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editUser(user)\"\n [attr.aria-label]=\"'Edit ' + user.Name\"\n title=\"Edit\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"toggleUserStatus(user)\"\n [attr.aria-label]=\"(user.IsActive ? 'Deactivate ' : 'Activate ') + user.Name\"\n [title]=\"user.IsActive ? 'Deactivate' : 'Activate'\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteUser(user)\"\n [attr.aria-label]=\"'Delete ' + user.Name\"\n title=\"Delete\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button class=\"expand-btn\" aria-label=\"Toggle user details\">\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n <!-- User Card Content - Expanded -->\n @if (isUserExpanded(user.ID)) {\n <div class=\"user-content\">\n <!-- Mobile Actions Bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editUser(user)\"\n [attr.aria-label]=\"'Edit ' + user.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"toggleUserStatus(user)\"\n [attr.aria-label]=\"(user.IsActive ? 'Deactivate ' : 'Activate ') + user.Name\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">{{ user.IsActive ? 'Disable' : 'Enable' }}</span>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteUser(user)\"\n [attr.aria-label]=\"'Delete ' + user.Name\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Delete</span>\n </button>\n </div>\n </div>\n\n <!-- User Stats -->\n <div class=\"user-stats\">\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Type:</span>\n <span class=\"stat-value\">\n <i [class]=\"'fa-solid ' + getUserTypeIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.Type }}\n </span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-id-card\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Full Name:</span>\n <span class=\"stat-value\">{{ user.FirstName }} {{ user.LastName }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-calendar\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Created:</span>\n <span class=\"stat-value\">{{ user.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-clock\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Updated:</span>\n <span class=\"stat-value\">{{ user.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n </div>\n\n <!-- User Roles Section -->\n <div class=\"roles-section\">\n <h4 class=\"section-title\">\n <i class=\"fa-solid fa-user-shield\" aria-hidden=\"true\"></i>\n Assigned Roles\n </h4>\n @if (getUserRoles(user.ID).length > 0) {\n <div class=\"roles-grid\">\n @for (role of getUserRoles(user.ID); track role.ID) {\n <div class=\"role-item\">\n <i class=\"fa-solid fa-shield\" aria-hidden=\"true\"></i>\n {{ role.Name }}\n </div>\n }\n </div>\n } @else {\n <p class=\"no-roles\">No roles assigned to this user</p>\n }\n </div>\n </div>\n }\n </div>\n }\n\n @if (filteredUsers.length === 0) {\n <mj-empty-state\n [Variant]=\"IsListNarrowed ? 'no-results' : 'empty'\"\n Icon=\"fa-solid fa-users-slash\"\n Title=\"No users found\"\n Message=\"Try adjusting your filters or add a new user\"\n [ActionText]=\"IsListNarrowed ? 'Reset filters' : ''\"\n ActionIcon=\"fa-solid fa-rotate-left\"\n (Action)=\"resetAllFiltersAndSearch()\" />\n }\n </div>\n }\n </mj-page-body-interior>\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\n class=\"modal-backdrop\"\n (click)=\"showDeleteConfirm = false\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"delete-dialog-title\"\n aria-describedby=\"delete-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"delete-dialog-title\">\n <i class=\"fa-solid fa-exclamation-triangle text-danger\" aria-hidden=\"true\"></i>\n Confirm Delete\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"showDeleteConfirm = false\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"delete-dialog-desc\">\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 mjButton variant=\"danger\" (click)=\"deleteUser()\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n Delete User\n </button>\n <button mjButton (click)=\"showDeleteConfirm = false\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Bulk Action Confirmation Dialog -->\n @if (showBulkActionConfirm) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelBulkAction()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"bulk-action-dialog-title\"\n aria-describedby=\"bulk-action-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"bulk-action-dialog-title\">\n @if (bulkActionType === 'delete') {\n <i class=\"fa-solid fa-exclamation-triangle text-danger\" aria-hidden=\"true\"></i>\n } @else if (bulkActionType === 'enable') {\n <i class=\"fa-solid fa-toggle-on text-success\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-toggle-off text-warning\" aria-hidden=\"true\"></i>\n }\n {{ getBulkActionTitle() }}\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"cancelBulkAction()\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"bulk-action-dialog-desc\">\n <p>{{ getBulkActionMessage() }}</p>\n @if (bulkActionType === 'delete') {\n <p class=\"text-muted\">This action cannot be undone.</p>\n }\n </div>\n <div class=\"modal-footer\">\n <button mjButton\n [variant]=\"bulkActionType === 'delete' ? 'danger' : 'primary'\"\n (click)=\"executeBulkAction()\"\n [disabled]=\"isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Processing...\n } @else {\n @if (bulkActionType === 'delete') {\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n } @else if (bulkActionType === 'enable') {\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n }\n {{ getBulkActionButtonText() }}\n }\n </button>\n <button mjButton (click)=\"cancelBulkAction()\" [disabled]=\"isLoading\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Bulk Role Assignment Dialog -->\n @if (showBulkRoleAssign) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelBulkRoleAssign()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"bulk-role-dialog-title\"\n aria-describedby=\"bulk-role-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"bulk-role-dialog-title\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n Assign Role to {{ selectedCount }} User{{ selectedCount > 1 ? 's' : '' }}\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"cancelBulkRoleAssign()\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"bulk-role-dialog-desc\">\n <p>Select a role to assign to the selected users:</p>\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"bulk-role-select\">Role</label>\n <select\n id=\"bulk-role-select\"\n class=\"field-select\"\n [(ngModel)]=\"bulkRoleId\"\n aria-label=\"Select role to assign\"\n >\n <option value=\"\">Select a role...</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 class=\"modal-footer\">\n <button\n mjButton variant=\"primary\"\n (click)=\"executeBulkRoleAssign()\"\n [disabled]=\"!bulkRoleId || isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Assigning...\n } @else {\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n Assign Role\n }\n </button>\n <button mjButton (click)=\"cancelBulkRoleAssign()\" [disabled]=\"isLoading\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n"]}
|
|
1
|
+
{"version":3,"file":"user-management.component.js","sourceRoot":"","sources":["../../../src/lib/user-management/user-management.component.ts","../../../src/lib/user-management/user-management.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnDestroy, ChangeDetectorRef, NgZone } from '@angular/core';\nimport { Subject, BehaviorSubject } from 'rxjs';\nimport { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';\nimport { RunView, Metadata, CompositeKey } from '@memberjunction/core';\nimport { MJUserEntity, MJRoleEntity, MJUserRoleEntity, ResourceData } from '@memberjunction/core-entities';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { FilterFieldConfig } from '@memberjunction/ng-ui-components';\nimport { UserDialogData, UserDialogResult } from './user-dialog/user-dialog.component';\nimport {\n buildUserManagementAgentContext,\n isValidUserStatusFilter,\n resolveUserByIDOrName,\n resolveRoleByIDOrName,\n UserManagementAgentContextInput,\n} from './user-management-agent-context';\n\n/** Sortable user columns + direction the agent can request via SortUsers. */\ntype UserSortField = 'name' | 'email' | 'status' | 'type';\ntype UserSortDirection = 'asc' | 'desc';\n\ninterface UserStats {\n totalUsers: number;\n activeUsers: number;\n inactiveUsers: number;\n adminUsers: number;\n}\n\ninterface FilterOptions {\n status: 'all' | 'active' | 'inactive';\n role: string;\n search: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-user-management',\n templateUrl: './user-management.component.html',\n styleUrls: ['../shared/styles/_admin-patterns.css', './user-management.component.css']\n})\n@RegisterClass(BaseDashboard, 'UserManagement')\nexport class UserManagementComponent extends BaseDashboard implements OnDestroy {\n\n // State management\n public users: MJUserEntity[] = [];\n public filteredUsers: MJUserEntity[] = [];\n public roles: MJRoleEntity[] = [];\n public selectedUser: MJUserEntity | null = null;\n public isLoading = false;\n public error: string | null = null;\n\n // Selection state for bulk actions\n public selectedUserIds = new Set<string>();\n\n // Dialog state\n public showUserDialog = false;\n public userDialogData: UserDialogData | null = null;\n\n // Bulk action dialog state\n public showBulkActionConfirm = false;\n public bulkActionType: 'enable' | 'disable' | 'delete' | null = null;\n public showBulkRoleAssign = false;\n public bulkRoleId: string = '';\n \n // Stats\n public stats: UserStats = {\n totalUsers: 0,\n activeUsers: 0,\n inactiveUsers: 0,\n adminUsers: 0 // This will be based on roles, not Type\n };\n \n // Filters\n public filters$ = new BehaviorSubject<FilterOptions>({\n status: 'all',\n role: '',\n search: ''\n });\n \n // UI State\n public showCreateDialog = false;\n public showEditDialog = false;\n public showDeleteConfirm = false;\n\n // Mobile expansion state\n private expandedUserIds = new Set<string>();\n\n // User-Role mapping\n private userRoleMap = new Map<string, string[]>(); // userId -> roleIds[]\n \n // Grid configuration\n public gridConfig = {\n pageSize: 20,\n sortField: 'Name',\n sortDirection: 'asc'\n };\n \n protected override destroy$ = new Subject<void>();\n private get metadata() { return this.ProviderToUse; }\n constructor(private cdr: ChangeDetectorRef, private ngZone: NgZone) {\n super();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return \"User Management\"\n }\n\n protected initDashboard(): void {\n this.setupFilterSubscription();\n this.registerAgentClientTools();\n }\n\n protected loadData(): void {\n this.loadInitialData();\n }\n\n // ================================================================\n // AI Agent Context & Client Tools\n //\n // 🚨 SAFETY BOUNDARY — READ-ONLY / GOVERNANCE SURFACE 🚨\n // User Management is a security-sensitive admin surface. The agent context\n // and client tools registered here are strictly READ-ONLY / navigational:\n // status/role filters, free-text search, SELECTING a user (view), SORTING the\n // list, clearing filters, refreshing, CSV export of already-visible rows, and\n // navigating to a user's record for viewing. The mutating operations on this\n // component — create/edit/delete users, toggle status, bulk enable/disable/\n // delete, AND bulk role assignment (a role GRANT) — are DELIBERATELY NOT\n // exposed to the agent; they remain human-initiated. Context exposes only\n // counts, active filter selections, and on-screen display names/emails —\n // NEVER passwords, tokens, or other secrets.\n // ================================================================\n\n /** Active agent-requested sort (defaults to the grid's Name/asc). */\n private agentSortField: UserSortField = 'name';\n private agentSortDirection: UserSortDirection = 'asc';\n\n /**\n * Publish the current user-management state to the AI agent. Re-invoked on\n * every meaningful state change (data load, filter, selection, sort) so the\n * agent sees a fresh, read-only, NON-SENSITIVE snapshot. Shaped by the pure\n * {@link buildUserManagementAgentContext} helper (unit-tested in isolation).\n */\n private publishAgentContext(): void {\n const filters = this.filters$.value;\n const roleFilter = filters.role ? this.roles.find(r => UUIDsEqual(r.ID, filters.role)) : null;\n const input: UserManagementAgentContextInput = {\n TotalUserCount: this.users.length,\n FilteredUserCount: this.filteredUsers.length,\n ActiveUserCount: this.stats.activeUsers,\n InactiveUserCount: this.stats.inactiveUsers,\n StatusFilter: filters.status,\n RoleFilterId: filters.role || null,\n RoleFilterName: roleFilter?.Name ?? null,\n SearchText: filters.search,\n SelectedUserId: this.selectedUser?.ID ?? null,\n SelectedUserName: this.selectedUser?.Name ?? null,\n VisibleUserNames: this.filteredUsers.map(u => u.Name ?? '').filter(n => n !== ''),\n VisibleUserEmails: this.filteredUsers.map(u => u.Email ?? '').filter(e => e !== ''),\n AvailableRoleNames: this.roles.map(r => r.Name ?? '').filter(n => n !== ''),\n VisibleColumns: ['Name', 'Email', 'Type', 'Status', 'Roles'],\n };\n this.navigationService.SetAgentContext(this, buildUserManagementAgentContext(input));\n }\n\n /**\n * Register the read-only / navigational client tools the agent may invoke.\n * Every Handler is tolerant: validates input and returns\n * `{ Success: false, ErrorMessage }` rather than throwing.\n */\n private registerAgentClientTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'SwitchUserStatusFilter',\n Description: 'Filter the user list by status. Valid values: all, active, inactive.',\n ParameterSchema: { type: 'object', properties: { status: { type: 'string', enum: ['all', 'active', 'inactive'] } }, required: ['status'] },\n Handler: async (params: Record<string, unknown>) => this.handleSwitchStatusFilterTool(params),\n },\n {\n Name: 'FilterUsersByRole',\n Description: 'Filter the user list by role. Accepts a role name OR a role ID; pass an empty string to clear the role filter. Available role names are published in AvailableRoleNames.',\n ParameterSchema: { type: 'object', properties: { role: { type: 'string' } }, required: ['role'] },\n Handler: async (params: Record<string, unknown>) => this.handleFilterByRoleTool(params),\n },\n {\n Name: 'SearchUsers',\n Description: 'Free-text search across user name, email, first name, and last name.',\n ParameterSchema: { type: 'object', properties: { searchText: { type: 'string' } }, required: ['searchText'] },\n Handler: async (params: Record<string, unknown>) => this.handleSearchTool(params),\n },\n {\n Name: 'SelectUser',\n Description: 'Select a user for VIEWING by ID or name (exact ID → exact name/email → partial match). Read-only — does not edit the user. Updates SelectedUserId/SelectedUserName in context.',\n ParameterSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] },\n Handler: async (params: Record<string, unknown>) => this.handleSelectUserTool(params),\n },\n {\n Name: 'SortUsers',\n Description: 'Sort the visible user list. field: name | email | status | type. direction: asc | desc (default asc).',\n ParameterSchema: { type: 'object', properties: { field: { type: 'string', enum: ['name', 'email', 'status', 'type'] }, direction: { type: 'string', enum: ['asc', 'desc'] } }, required: ['field'] },\n Handler: async (params: Record<string, unknown>) => this.handleSortUsersTool(params),\n },\n {\n Name: 'NavigateToUserRecord',\n Description: 'Open the record for a user (by ID or name) in a tab for VIEWING. Read-only navigation — does not edit the user.',\n ParameterSchema: { type: 'object', properties: { user: { type: 'string' } }, required: ['user'] },\n Handler: async (params: Record<string, unknown>) => this.handleNavigateToUserRecordTool(params),\n },\n {\n Name: 'ClearAllFilters',\n Description: 'Clear all user filters (status, role, and search) and show the full list.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => this.handleClearFiltersTool(),\n },\n {\n Name: 'RefreshUserList',\n Description: 'Reload the user list from the server. Read-only — does not mutate any data.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => this.handleRefreshTool(),\n },\n {\n Name: 'ExportUsers',\n Description: 'Export the currently filtered users as a CSV file.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => this.handleExportTool(),\n },\n ]);\n }\n\n private handleSwitchStatusFilterTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const status = params?.['status'];\n if (!isValidUserStatusFilter(status)) {\n return { Success: false, ErrorMessage: `Invalid status \"${String(status)}\". Expected one of: all, active, inactive.` };\n }\n this.onStatusFilterChange(status);\n this.publishAgentContext();\n return { Success: true };\n }\n\n private handleFilterByRoleTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const raw = String(params?.['role'] ?? '');\n if (!raw.trim()) {\n // Empty string explicitly clears the role filter.\n this.updateFilter({ role: '' });\n this.publishAgentContext();\n return { Success: true };\n }\n const resolved = resolveRoleByIDOrName(raw, this.roles.map(r => ({ ID: r.ID, Name: r.Name ?? '' })));\n if (!resolved.ok) {\n return { Success: false, ErrorMessage: resolved.error };\n }\n this.updateFilter({ role: resolved.match.ID });\n this.publishAgentContext();\n return { Success: true };\n }\n\n private handleSearchTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const searchText = params?.['searchText'];\n if (typeof searchText !== 'string') {\n return { Success: false, ErrorMessage: 'searchText must be a string.' };\n }\n this.updateFilter({ search: searchText });\n this.publishAgentContext();\n return { Success: true };\n }\n\n private handleSelectUserTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const raw = String(params?.['user'] ?? '');\n const resolved = resolveUserByIDOrName(raw, this.users.map(u => ({\n ID: u.ID, Name: u.Name ?? '', Email: u.Email, FirstName: u.FirstName, LastName: u.LastName,\n })));\n if (!resolved.ok) {\n return { Success: false, ErrorMessage: resolved.error };\n }\n const match = this.users.find(u => UUIDsEqual(u.ID, resolved.match.ID)) ?? null;\n this.selectedUser = match;\n this.cdr.markForCheck();\n this.publishAgentContext();\n return { Success: true };\n }\n\n private handleSortUsersTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const field = String(params?.['field'] ?? '');\n if (field !== 'name' && field !== 'email' && field !== 'status' && field !== 'type') {\n return { Success: false, ErrorMessage: `Invalid sort field \"${field}\". Expected one of: name, email, status, type.` };\n }\n const dirRaw = params?.['direction'];\n const direction: UserSortDirection = dirRaw === 'desc' ? 'desc' : 'asc';\n this.agentSortField = field;\n this.agentSortDirection = direction;\n this.applySortToVisibleUsers();\n this.cdr.markForCheck();\n this.publishAgentContext();\n return { Success: true };\n }\n\n private handleNavigateToUserRecordTool(params: Record<string, unknown>): { Success: boolean; ErrorMessage?: string } {\n const raw = String(params?.['user'] ?? '');\n const resolved = resolveUserByIDOrName(raw, this.users.map(u => ({\n ID: u.ID, Name: u.Name ?? '', Email: u.Email, FirstName: u.FirstName, LastName: u.LastName,\n })));\n if (!resolved.ok) {\n return { Success: false, ErrorMessage: resolved.error };\n }\n this.navigationService.OpenEntityRecord('MJ: Users', CompositeKey.FromID(resolved.match.ID));\n return { Success: true };\n }\n\n /** Sort filteredUsers in place per the active agent-requested sort. Read-only display ordering. */\n private applySortToVisibleUsers(): void {\n const dir = this.agentSortDirection === 'desc' ? -1 : 1;\n const field = this.agentSortField;\n this.filteredUsers = [...this.filteredUsers].sort((a, b) => {\n const av = this.sortKeyForUser(a, field);\n const bv = this.sortKeyForUser(b, field);\n return av.localeCompare(bv) * dir;\n });\n }\n\n private sortKeyForUser(user: MJUserEntity, field: UserSortField): string {\n switch (field) {\n case 'email': return (user.Email ?? '').toLowerCase();\n case 'status': return user.IsActive ? 'active' : 'inactive';\n case 'type': return (user.Type ?? '').toLowerCase();\n case 'name':\n default: return (user.Name ?? '').toLowerCase();\n }\n }\n\n private handleClearFiltersTool(): { Success: boolean } {\n this.resetAllFiltersAndSearch();\n this.publishAgentContext();\n return { Success: true };\n }\n\n private async handleRefreshTool(): Promise<{ Success: boolean; ErrorMessage?: string }> {\n try {\n await this.loadInitialData();\n this.publishAgentContext();\n return { Success: true };\n } catch (e) {\n return { Success: false, ErrorMessage: e instanceof Error ? e.message : 'Refresh failed.' };\n }\n }\n\n private handleExportTool(): { Success: boolean; ErrorMessage?: string } {\n if (this.filteredUsers.length === 0) {\n return { Success: false, ErrorMessage: 'No users to export.' };\n }\n this.exportUsers();\n return { Success: true };\n }\n\n override ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n super.ngOnDestroy();\n }\n \n public async loadInitialData(): Promise<void> {\n try {\n this.isLoading = true;\n this.error = null;\n \n // Load users, roles, and user-role relationships in parallel\n const [users, roles, userRoles] = await Promise.all([\n this.loadUsers(),\n this.loadRoles(),\n this.loadUserRoles()\n ]);\n \n this.users = users;\n this.roles = roles;\n \n // Build user-role mapping\n this.buildUserRoleMapping(userRoles);\n \n this.calculateStats();\n this.applyFilters();\n \n } catch (error) {\n console.error('Error loading user data:', error);\n this.error = 'Failed to load user data. Please try again.';\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n this.publishAgentContext();\n });\n }\n }\n\n private async loadUsers(): Promise<MJUserEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ResultType: 'entity_object'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private async loadRoles(): Promise<MJRoleEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n ResultType: 'entity_object',\n OrderBy: 'Name ASC'\n });\n \n return result.Success ? result.Results : [];\n }\n\n private async loadUserRoles(): Promise<MJUserRoleEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJUserRoleEntity>({\n EntityName: 'MJ: User Roles',\n ResultType: 'entity_object'\n });\n \n return result.Success ? result.Results : [];\n }\n\n private buildUserRoleMapping(userRoles: MJUserRoleEntity[]): void {\n this.userRoleMap.clear();\n \n userRoles.forEach(userRole => {\n const userId = userRole.UserID;\n const roleId = userRole.RoleID;\n \n if (!this.userRoleMap.has(userId)) {\n this.userRoleMap.set(userId, []);\n }\n \n this.userRoleMap.get(userId)!.push(roleId);\n });\n }\n \n private setupFilterSubscription(): void {\n this.filters$\n .pipe(\n debounceTime(300),\n distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),\n takeUntil(this.destroy$)\n )\n .subscribe(() => {\n this.applyFilters();\n this.publishAgentContext();\n });\n }\n\n private applyFilters(): void {\n const filters = this.filters$.value;\n let filtered = [...this.users];\n\n // Apply status filter\n if (filters.status !== 'all') {\n filtered = filtered.filter(user => \n filters.status === 'active' ? user.IsActive : !user.IsActive\n );\n }\n \n // Apply role filter\n if (filters.role) {\n filtered = filtered.filter(user => {\n const userRoles = this.userRoleMap.get(user.ID) || [];\n return userRoles.includes(filters.role);\n });\n }\n \n // Apply search filter\n if (filters.search) {\n const searchLower = filters.search.toLowerCase();\n filtered = filtered.filter(user =>\n user.Name?.toLowerCase().includes(searchLower) ||\n user.Email?.toLowerCase().includes(searchLower) ||\n user.FirstName?.toLowerCase().includes(searchLower) ||\n user.LastName?.toLowerCase().includes(searchLower)\n );\n }\n \n this.filteredUsers = filtered;\n // Preserve any agent-requested sort across filter changes (read-only display ordering).\n this.applySortToVisibleUsers();\n }\n\n private calculateStats(): void {\n this.stats = {\n totalUsers: this.users.length,\n activeUsers: this.users.filter(u => u.IsActive).length,\n inactiveUsers: this.users.filter(u => !u.IsActive).length,\n adminUsers: this.users.filter(u => u.Type === 'Owner').length // Using Owner as admin type\n };\n }\n \n // Public methods for template\n public onStatusFilterChange(status: 'all' | 'active' | 'inactive'): void {\n this.updateFilter({ status });\n }\n\n public updateFilter(partial: Partial<FilterOptions>): void {\n this.filters$.next({\n ...this.filters$.value,\n ...partial\n });\n // Discrete changes (chips, popover dropdowns) apply immediately. Text search\n // still goes through the 300ms debounce in setupFilterSubscription so we\n // don't re-filter on every keystroke.\n if (!('search' in partial)) {\n this.applyFilters();\n this.cdr.markForCheck();\n }\n }\n \n public selectUser(user: MJUserEntity): void {\n this.selectedUser = user;\n this.showEditDialog = true;\n }\n \n public createNewUser(): void {\n this.userDialogData = {\n mode: 'create',\n availableRoles: this.roles\n };\n this.showUserDialog = true;\n }\n \n public editUser(user: MJUserEntity): void {\n this.userDialogData = {\n user: user,\n mode: 'edit',\n availableRoles: this.roles\n };\n this.showUserDialog = true;\n }\n \n public confirmDeleteUser(user: MJUserEntity): void {\n this.selectedUser = user;\n this.showDeleteConfirm = true;\n }\n \n public async deleteUser(): Promise<void> {\n if (!this.selectedUser) return;\n \n try {\n // Load user entity to delete\n const user = await this.metadata.GetEntityObject<MJUserEntity>('MJ: Users');\n const loadResult = await user.Load(this.selectedUser.ID);\n \n if (loadResult) {\n const deleteResult = await user.Delete();\n if (deleteResult) {\n this.showDeleteConfirm = false;\n this.selectedUser = null;\n await this.loadInitialData();\n } else {\n throw new Error(user.LatestResult?.Message || 'Failed to delete user');\n }\n } else {\n throw new Error('User not found or permission denied');\n }\n } catch (error: unknown) {\n console.error('Error deleting user:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Failed to delete user';\n this.cdr.markForCheck();\n });\n }\n }\n \n public async toggleUserStatus(user: MJUserEntity): Promise<void> {\n try {\n user.IsActive = !user.IsActive;\n // BaseEntity.Save() returns false on a validation failure — it does NOT throw. Discarding\n // the result meant the catch below never ran for a refused save: no revert, no message, and\n // calculateStats() re-rendered the row as toggled, so the UI asserted success while nothing\n // had been written. Reachable for every non-Owner admin since the #4260 privilege-elevation\n // guard on MJ: Users, because deactivating a user is a write to another user's row.\n // Mirrors deleteUser() above, which already checks its result this way.\n if (!(await user.Save())) {\n throw new Error(user.LatestResult?.Message || 'Failed to update user status');\n }\n this.ngZone.run(() => {\n // Clear any banner left by a PREVIOUS refused toggle. Without this a non-Owner who is\n // refused on one row, then succeeds on a row they may edit (their own), keeps reading the\n // stale refusal. `loadInitialData()` is the only other place `error` is reset and this path\n // does not call it.\n this.error = null;\n this.calculateStats();\n this.cdr.markForCheck();\n });\n } catch (error) {\n console.error('Error updating user status:', error);\n this.ngZone.run(() => {\n user.IsActive = !user.IsActive; // Revert on error\n this.error = error instanceof Error ? error.message : 'Failed to update user status';\n this.cdr.markForCheck();\n });\n }\n }\n \n public exportUsers(): void {\n if (this.filteredUsers.length === 0) {\n this.error = 'No users to export';\n return;\n }\n\n try {\n // Create CSV content\n const headers = ['Name', 'First Name', 'Last Name', 'Email', 'Type', 'Status', 'Created', 'Updated'];\n const csvRows = [headers.join(',')];\n\n // Add user data\n this.filteredUsers.forEach(user => {\n const row = [\n this.escapeCSV(user.Name || ''),\n this.escapeCSV(user.FirstName || ''),\n this.escapeCSV(user.LastName || ''),\n this.escapeCSV(user.Email || ''),\n this.escapeCSV(user.Type || ''),\n user.IsActive ? 'Active' : 'Inactive',\n user.__mj_CreatedAt ? new Date(user.__mj_CreatedAt).toLocaleDateString() : '',\n user.__mj_UpdatedAt ? new Date(user.__mj_UpdatedAt).toLocaleDateString() : ''\n ];\n csvRows.push(row.join(','));\n });\n\n // Create and download file\n const csvContent = csvRows.join('\\n');\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });\n const link = document.createElement('a');\n \n if (link.download !== undefined) {\n const url = URL.createObjectURL(blob);\n link.setAttribute('href', url);\n link.setAttribute('download', `users_export_${new Date().toISOString().split('T')[0]}.csv`);\n link.style.visibility = 'hidden';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n } catch (error) {\n console.error('Error exporting users:', error);\n this.error = 'Failed to export users';\n }\n }\n\n private escapeCSV(value: string): string {\n if (value.includes(',') || value.includes('\"') || value.includes('\\n')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n }\n \n public refreshData(): void {\n this.loadInitialData();\n }\n \n public getStatusIcon(user: MJUserEntity): string {\n return user.IsActive ? 'fa-check-circle' : 'fa-times-circle';\n }\n \n public getStatusClass(user: MJUserEntity): string {\n return user.IsActive ? 'status-active' : 'status-inactive';\n }\n \n public getUserTypeIcon(user: MJUserEntity): string {\n switch (user.Type) {\n case 'Owner':\n return 'fa-shield-halved';\n case 'User':\n return 'fa-user';\n default:\n return 'fa-user';\n }\n }\n \n public getUserInitials(user: MJUserEntity): string {\n const first = user.FirstName?.charAt(0) || '';\n const last = user.LastName?.charAt(0) || '';\n return (first + last).toUpperCase() || user.Name?.charAt(0).toUpperCase() || 'U';\n }\n\n public onUserDialogResult(result: UserDialogResult): void {\n this.showUserDialog = false;\n this.userDialogData = null;\n\n if (result.action === 'save') {\n // Refresh the user list to show changes\n this.loadInitialData();\n }\n }\n\n // Selection methods for bulk actions\n public get isAllSelected(): boolean {\n return this.filteredUsers.length > 0 &&\n this.filteredUsers.every(user => this.selectedUserIds.has(user.ID));\n }\n\n public get isIndeterminate(): boolean {\n const selectedCount = this.filteredUsers.filter(user => this.selectedUserIds.has(user.ID)).length;\n return selectedCount > 0 && selectedCount < this.filteredUsers.length;\n }\n\n public get hasSelection(): boolean {\n return this.selectedUserIds.size > 0;\n }\n\n public get selectedCount(): number {\n return this.selectedUserIds.size;\n }\n\n public get hasActiveFilters(): boolean {\n const filters = this.filters$.value;\n return filters.status !== 'all' || filters.role !== '';\n }\n\n public get activeFilterCount(): number {\n let count = 0;\n const filters = this.filters$.value;\n if (filters.status !== 'all') count++;\n if (filters.role !== '') count++;\n return count;\n }\n\n public clearFilters(): void {\n this.filters$.next({\n ...this.filters$.value,\n status: 'all',\n role: ''\n });\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n // -- Filter panel binding (mj-filter-panel inside the popover) -------------\n //\n // Only Role lives inside the popover — Status is exposed as visible chips\n // in the filter card alongside search (the standardized \"quick toggle\"\n // pattern used by Scheduling's exterior chrome). The popover badge counts\n // only popover-resident filters (Role), so Status changes don't ghost\n // the badge.\n\n /**\n * FilterFieldConfig[] describing the popover's Role field. Driven off\n * `roles[]` so the dropdown stays in sync as roles load.\n */\n public get filterFields(): FilterFieldConfig[] {\n return [\n {\n key: 'status',\n type: 'chips',\n label: 'Status',\n chipOptions: [\n { text: 'All', value: 'all' },\n { text: 'Active', value: 'active' },\n { text: 'Inactive', value: 'inactive' },\n ],\n },\n {\n key: 'role',\n type: 'dropdown',\n label: 'Role',\n icon: 'fa-solid fa-user-shield',\n placeholder: 'All Roles',\n filterable: this.roles.length > 10,\n options: [\n { text: 'All Roles', value: '' },\n ...this.roles.map(r => ({ text: r.Name ?? '', value: r.ID }))\n ]\n }\n ];\n }\n\n /** Current popover field values keyed by FilterFieldConfig.key. */\n public get filterValues(): Record<string, unknown> {\n return { status: this.filters$.value.status, role: this.filters$.value.role };\n }\n\n /** Total active filters (Status + Role) — drives the Filter button badge. */\n public get TotalActiveFilterCount(): number {\n const f = this.filters$.value;\n return (f.status !== 'all' ? 1 : 0) + (f.role !== '' ? 1 : 0);\n }\n\n /** Apply a value change from <mj-filter-panel>. */\n public onFilterPanelChange(values: Record<string, unknown>): void {\n const partial: Partial<FilterOptions> = {};\n if ('status' in values) {\n partial.status = (values['status'] as FilterOptions['status']) || 'all';\n }\n if ('role' in values) {\n partial.role = (values['role'] as string) ?? '';\n }\n this.updateFilter(partial);\n }\n\n /** Clear all filters (Status + Role); search persists. */\n public clearAllAppliedFilters(): void {\n this.updateFilter({ status: 'all', role: '' });\n }\n\n /** True when search and/or panel filters are narrowing the list — gates the\n * no-results empty-state \"Reset filters\" CTA. */\n public get IsListNarrowed(): boolean {\n return this.filters$.value.search !== '' || this.TotalActiveFilterCount > 0;\n }\n\n /** Reset everything narrowing the list (search + Status + Role) and refresh\n * immediately. Wired to the no-results empty-state CTA. Unlike\n * clearAllAppliedFilters(), this also clears the search box. */\n public resetAllFiltersAndSearch(): void {\n this.filters$.next({ status: 'all', role: '', search: '' });\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n public toggleSelectAll(): void {\n if (this.isAllSelected) {\n // Deselect all filtered users\n this.filteredUsers.forEach(user => this.selectedUserIds.delete(user.ID));\n } else {\n // Select all filtered users\n this.filteredUsers.forEach(user => this.selectedUserIds.add(user.ID));\n }\n }\n\n public toggleUserSelection(userId: string, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n if (this.selectedUserIds.has(userId)) {\n this.selectedUserIds.delete(userId);\n } else {\n this.selectedUserIds.add(userId);\n }\n }\n\n public isUserSelected(userId: string): boolean {\n return this.selectedUserIds.has(userId);\n }\n\n public clearSelection(): void {\n this.selectedUserIds.clear();\n }\n\n // Bulk action methods\n public confirmBulkAction(action: 'enable' | 'disable' | 'delete'): void {\n if (!this.hasSelection) return;\n this.bulkActionType = action;\n this.showBulkActionConfirm = true;\n }\n\n public cancelBulkAction(): void {\n this.showBulkActionConfirm = false;\n this.bulkActionType = null;\n }\n\n public async executeBulkAction(): Promise<void> {\n if (!this.bulkActionType || !this.hasSelection) return;\n\n try {\n this.isLoading = true;\n const selectedUsers = this.users.filter(user => this.selectedUserIds.has(user.ID));\n\n switch (this.bulkActionType) {\n case 'enable':\n await this.bulkSetUserStatus(selectedUsers, true);\n break;\n case 'disable':\n await this.bulkSetUserStatus(selectedUsers, false);\n break;\n case 'delete':\n await this.bulkDeleteUsers(selectedUsers);\n break;\n }\n\n this.clearSelection();\n this.showBulkActionConfirm = false;\n this.bulkActionType = null;\n await this.loadInitialData();\n } catch (error: unknown) {\n console.error('Bulk action failed:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Bulk action failed';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n private async bulkSetUserStatus(users: MJUserEntity[], isActive: boolean): Promise<void> {\n if (users.length === 0) return;\n\n const md = this.ProviderToUse;\n const tg = await md.CreateTransactionGroup();\n for (const user of users) {\n user.IsActive = isActive;\n user.TransactionGroup = tg;\n await user.Save();\n }\n if (!await tg.Submit()) {\n // Server rolled back — restore in-memory flags to their prior state\n for (const user of users) {\n user.IsActive = !isActive;\n }\n throw new Error('Failed to update users — all changes have been rolled back');\n }\n }\n\n private async bulkDeleteUsers(users: MJUserEntity[]): Promise<void> {\n if (users.length === 0) return;\n\n const md = this.ProviderToUse;\n const tg = await md.CreateTransactionGroup();\n for (const user of users) {\n user.TransactionGroup = tg;\n await user.Delete();\n }\n if (!await tg.Submit()) {\n throw new Error('Failed to delete users — all changes have been rolled back');\n }\n }\n\n // Bulk role assignment\n public openBulkRoleAssign(): void {\n if (!this.hasSelection) return;\n this.bulkRoleId = '';\n this.showBulkRoleAssign = true;\n }\n\n public cancelBulkRoleAssign(): void {\n this.showBulkRoleAssign = false;\n this.bulkRoleId = '';\n }\n\n public async executeBulkRoleAssign(): Promise<void> {\n if (!this.bulkRoleId || !this.hasSelection) return;\n\n try {\n this.isLoading = true;\n const selectedUserIds = Array.from(this.selectedUserIds);\n\n // Collect only the users that don't already have the role\n const usersNeedingRole = selectedUserIds.filter(userId => {\n const existingRoles = this.userRoleMap.get(userId) || [];\n return !existingRoles.includes(this.bulkRoleId);\n });\n\n if (usersNeedingRole.length > 0) {\n const tg = await this.metadata.CreateTransactionGroup();\n // Each Save() only ENROLS the row in the group — the write is deferred to Submit(). Inside\n // a TransactionGroup, Save() therefore reports ENROLMENT, not the write's outcome: the\n // provider queues the item locally and returns true with no round trip\n // (`GraphQLDataProvider.Save` — \"part of a TG always return true\").\n //\n // So the role-elevation guard is NOT what this check catches. `MJUserRoleEntityServer`\n // (issue #4282) lives in `@memberjunction/core-entities-server`, which no browser package\n // depends on, so it never registers here — it refuses on the server, during Submit().\n //\n // And today that refusal reaches the user NOWHERE. `ExecuteTransactionGroup` discards the\n // refused row's `Save()` return, so the row never enrols in the SERVER's group either; an\n // all-refused batch submits an empty group, whose `Submit()` returns true for having\n // nothing to do, and the screen closes with no message at all. Verified end to end against\n // a live server: a non-Owner assigning a role they do not hold is correctly refused (no row\n // is written) and is reported as success. Tracked as issue #4309 — fixing it belongs in the\n // resolver, which is the only layer that still knows which row was refused and why.\n //\n // What this check DOES catch is a CLIENT-side refusal — a CheckPermissions denial or a\n // field-rule failure — which really does return false here, leaving that row unenrolled.\n // Ignoring the return meant an all-refused batch left the group EMPTY, and an empty group's\n // Submit() returns true for having nothing to do, so the screen reported success having\n // assigned nothing. That is the failure this guards; keep it.\n const refusals: string[] = [];\n for (const userId of usersNeedingRole) {\n const userRole = await this.metadata.GetEntityObject<MJUserRoleEntity>('MJ: User Roles');\n userRole.NewRecord();\n userRole.UserID = userId;\n userRole.RoleID = this.bulkRoleId;\n userRole.TransactionGroup = tg;\n if (!await userRole.Save()) {\n refusals.push(`${this.describeUser(userId)}: ${userRole.LatestResult?.CompleteMessage ?? 'unknown error'}`);\n }\n }\n if (refusals.length > 0) {\n // Nothing was written: the refused rows never enrolled, and the rest are still only\n // queued because Submit() is not reached.\n throw new Error(`Failed to assign roles — nothing was changed.\\n${refusals.join('\\n')}`);\n }\n\n if (!await tg.Submit()) {\n throw new Error('Failed to assign roles — all changes have been rolled back');\n }\n }\n\n this.clearSelection();\n this.showBulkRoleAssign = false;\n this.bulkRoleId = '';\n await this.loadInitialData();\n } catch (error: unknown) {\n console.error('Bulk role assignment failed:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Bulk role assignment failed';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n public getBulkActionMessage(): string {\n const count = this.selectedCount;\n switch (this.bulkActionType) {\n case 'enable':\n return `Are you sure you want to enable ${count} user${count > 1 ? 's' : ''}?`;\n case 'disable':\n return `Are you sure you want to disable ${count} user${count > 1 ? 's' : ''}?`;\n case 'delete':\n return `Are you sure you want to delete ${count} user${count > 1 ? 's' : ''}? This action cannot be undone.`;\n default:\n return '';\n }\n }\n\n public getBulkActionTitle(): string {\n switch (this.bulkActionType) {\n case 'enable':\n return 'Enable Users';\n case 'disable':\n return 'Disable Users';\n case 'delete':\n return 'Delete Users';\n default:\n return 'Confirm Action';\n }\n }\n\n public getBulkActionButtonText(): string {\n const count = this.selectedCount;\n switch (this.bulkActionType) {\n case 'enable':\n return `Enable ${count} User${count > 1 ? 's' : ''}`;\n case 'disable':\n return `Disable ${count} User${count > 1 ? 's' : ''}`;\n case 'delete':\n return `Delete ${count} User${count > 1 ? 's' : ''}`;\n default:\n return 'Confirm';\n }\n }\n\n // Expansion methods\n public toggleUserExpansion(userId: string): void {\n if (this.expandedUserIds.has(userId)) {\n this.expandedUserIds.delete(userId);\n } else {\n this.expandedUserIds.add(userId);\n }\n }\n\n public isUserExpanded(userId: string): boolean {\n return this.expandedUserIds.has(userId);\n }\n\n // Get roles for a specific user\n public getUserRoles(userId: string): MJRoleEntity[] {\n const roleIds = this.userRoleMap.get(userId) || [];\n return this.roles.filter(role => roleIds.some(id => UUIDsEqual(id, role.ID)));\n }\n\n /**\n * Names a user for an error message. Falls back to the raw ID rather than to a placeholder so a\n * refusal for a user who has dropped out of the loaded page is still traceable.\n */\n private describeUser(userId: string): string {\n const user = this.users.find(u => UUIDsEqual(u.ID, userId));\n return user?.Email ?? user?.Name ?? userId;\n }\n}","<!--\n Interior chrome — <mj-page-header-interior> is the body-level sibling of\n <mj-page-header>. Same slot conventions ([toolbar] / [meta] / [actions]);\n different visual shape (single-row card). See Section 10 of\n explorer-chrome-conventions.\n-->\n<mj-page-header-interior\n AriaLabel=\"Filter users\"\n Title=\"Users\"\n Subtitle=\"Manage user accounts, roles, and access\">\n <!-- X-of-Y filtered count earns its meta spot per chrome conventions §2 —\n tells the user how the search/filter is narrowing the data, signal at\n any scale. Partition badges (active/inactive/owners) stay dropped —\n they 1:1 mirror the filter chips in [toolbar] below. -->\n <div meta>\n <mj-stat-badge\n [Count]=\"filteredUsers.length\"\n [Total]=\"users.length\"\n Label=\"users\">\n </mj-stat-badge>\n </div>\n <div toolbar>\n <!-- Concise-chrome control bar: search · Filter. Status + Role live behind\n the one Filter button; applied filters show as removable chips below\n the card. On mobile the popover docks as a bottom sheet. -->\n <mj-page-search\n Placeholder=\"Search users by name or email...\"\n [Value]=\"filters$.value.search\"\n (ValueChange)=\"updateFilter({ search: $event })\">\n </mj-page-search>\n <mj-filter-popover\n Label=\"Filters\"\n Icon=\"fa-solid fa-filter\"\n [ActiveCount]=\"TotalActiveFilterCount\"\n [ShowClearAll]=\"TotalActiveFilterCount > 0\"\n (ClearAllRequested)=\"clearAllAppliedFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterPanelChange($event)\"\n (Reset)=\"clearAllAppliedFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"isLoading\" (Clicked)=\"refreshData()\"></mj-refresh-button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"exportUsers()\" aria-label=\"Export users to file\">\n <i class=\"fa-solid fa-download\"></i> <span class=\"mj-action-label\">Export</span>\n </button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"createNewUser()\" aria-label=\"Add new user\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"mj-action-label\">Add User</span>\n </button>\n </div>\n</mj-page-header-interior>\n\n <!-- Bulk Action Toolbar — contextual band shown above the list when users are selected. -->\n @if (hasSelection) {\n <div class=\"bulk-action-toolbar\" role=\"toolbar\" aria-label=\"Bulk actions\">\n <div class=\"bulk-selection-info\">\n <i class=\"fa-solid fa-check-square\" aria-hidden=\"true\"></i>\n <span>{{ selectedCount }} user{{ selectedCount > 1 ? 's' : '' }} selected</span>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"clearSelection()\" aria-label=\"Clear selection\">\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n Clear\n </button>\n </div>\n <div class=\"bulk-action-buttons\">\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"confirmBulkAction('enable')\" aria-label=\"Enable selected users\">\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Enable</span>\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"confirmBulkAction('disable')\" aria-label=\"Disable selected users\">\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Disable</span>\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"openBulkRoleAssign()\" aria-label=\"Assign role to selected users\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Assign Role</span>\n </button>\n <button mjButton variant=\"danger\" size=\"sm\" (click)=\"confirmBulkAction('delete')\" aria-label=\"Delete selected users\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Delete</span>\n </button>\n </div>\n </div>\n }\n\n <!-- Scrollable Content Section — owned by <mj-page-body-interior>. -->\n <mj-page-body-interior>\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading users...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\" aria-live=\"assertive\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\" aria-hidden=\"true\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button class=\"retry-button\" (click)=\"loadInitialData()\" aria-label=\"Retry loading users\">\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Users List -->\n @if (!isLoading && !error) {\n <div class=\"users-list\" role=\"list\" aria-label=\"Users list\">\n <!-- List Header with Select All -->\n <div class=\"list-header\">\n <label class=\"select-all-label\">\n <input\n type=\"checkbox\"\n class=\"checkbox\"\n [checked]=\"isAllSelected\"\n [indeterminate]=\"isIndeterminate\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all users\"\n />\n <span class=\"select-all-text\">Select All ({{ filteredUsers.length }})</span>\n </label>\n @if (hasSelection) {\n <span class=\"selection-count\">{{ selectedCount }} selected</span>\n }\n </div>\n\n @for (user of filteredUsers; track user.ID) {\n <div\n class=\"user-card\"\n [class.expanded]=\"isUserExpanded(user.ID)\"\n [class.selected]=\"isUserSelected(user.ID)\"\n role=\"listitem\"\n >\n <!-- User Card Header - Always Visible -->\n <div\n class=\"user-header\"\n (click)=\"toggleUserExpansion(user.ID)\"\n role=\"button\"\n [attr.aria-expanded]=\"isUserExpanded(user.ID)\"\n tabindex=\"0\"\n (keydown.enter)=\"toggleUserExpansion(user.ID)\"\n >\n <!-- Selection Checkbox -->\n <div class=\"user-selection\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n class=\"checkbox\"\n [checked]=\"isUserSelected(user.ID)\"\n (change)=\"toggleUserSelection(user.ID, $event)\"\n [attr.aria-label]=\"'Select ' + user.Name\"\n />\n </div>\n\n <!-- User Info -->\n <div class=\"user-info\">\n <div class=\"user-avatar\" aria-hidden=\"true\">\n {{ getUserInitials(user) }}\n </div>\n <div class=\"user-details\">\n <h3 class=\"user-name\">{{ user.Name }}</h3>\n <p class=\"user-email\">{{ user.Email }}</p>\n </div>\n </div>\n\n <!-- User Meta -->\n <div class=\"user-meta\">\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n <div class=\"user-actions desktop-only\" (click)=\"$event.stopPropagation()\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editUser(user)\"\n [attr.aria-label]=\"'Edit ' + user.Name\"\n title=\"Edit\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"toggleUserStatus(user)\"\n [attr.aria-label]=\"(user.IsActive ? 'Deactivate ' : 'Activate ') + user.Name\"\n [title]=\"user.IsActive ? 'Deactivate' : 'Activate'\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteUser(user)\"\n [attr.aria-label]=\"'Delete ' + user.Name\"\n title=\"Delete\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button class=\"expand-btn\" aria-label=\"Toggle user details\">\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n <!-- User Card Content - Expanded -->\n @if (isUserExpanded(user.ID)) {\n <div class=\"user-content\">\n <!-- Mobile Actions Bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editUser(user)\"\n [attr.aria-label]=\"'Edit ' + user.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"toggleUserStatus(user)\"\n [attr.aria-label]=\"(user.IsActive ? 'Deactivate ' : 'Activate ') + user.Name\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">{{ user.IsActive ? 'Disable' : 'Enable' }}</span>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteUser(user)\"\n [attr.aria-label]=\"'Delete ' + user.Name\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Delete</span>\n </button>\n </div>\n </div>\n\n <!-- User Stats -->\n <div class=\"user-stats\">\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Type:</span>\n <span class=\"stat-value\">\n <i [class]=\"'fa-solid ' + getUserTypeIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.Type }}\n </span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-id-card\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Full Name:</span>\n <span class=\"stat-value\">{{ user.FirstName }} {{ user.LastName }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-calendar\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Created:</span>\n <span class=\"stat-value\">{{ user.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-clock\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Updated:</span>\n <span class=\"stat-value\">{{ user.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n </div>\n\n <!-- User Roles Section -->\n <div class=\"roles-section\">\n <h4 class=\"section-title\">\n <i class=\"fa-solid fa-user-shield\" aria-hidden=\"true\"></i>\n Assigned Roles\n </h4>\n @if (getUserRoles(user.ID).length > 0) {\n <div class=\"roles-grid\">\n @for (role of getUserRoles(user.ID); track role.ID) {\n <div class=\"role-item\">\n <i class=\"fa-solid fa-shield\" aria-hidden=\"true\"></i>\n {{ role.Name }}\n </div>\n }\n </div>\n } @else {\n <p class=\"no-roles\">No roles assigned to this user</p>\n }\n </div>\n </div>\n }\n </div>\n }\n\n @if (filteredUsers.length === 0) {\n <mj-empty-state\n [Variant]=\"IsListNarrowed ? 'no-results' : 'empty'\"\n Icon=\"fa-solid fa-users-slash\"\n Title=\"No users found\"\n Message=\"Try adjusting your filters or add a new user\"\n [ActionText]=\"IsListNarrowed ? 'Reset filters' : ''\"\n ActionIcon=\"fa-solid fa-rotate-left\"\n (Action)=\"resetAllFiltersAndSearch()\" />\n }\n </div>\n }\n </mj-page-body-interior>\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\n class=\"modal-backdrop\"\n (click)=\"showDeleteConfirm = false\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"delete-dialog-title\"\n aria-describedby=\"delete-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"delete-dialog-title\">\n <i class=\"fa-solid fa-exclamation-triangle text-danger\" aria-hidden=\"true\"></i>\n Confirm Delete\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"showDeleteConfirm = false\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"delete-dialog-desc\">\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 mjButton variant=\"danger\" (click)=\"deleteUser()\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n Delete User\n </button>\n <button mjButton (click)=\"showDeleteConfirm = false\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Bulk Action Confirmation Dialog -->\n @if (showBulkActionConfirm) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelBulkAction()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"bulk-action-dialog-title\"\n aria-describedby=\"bulk-action-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"bulk-action-dialog-title\">\n @if (bulkActionType === 'delete') {\n <i class=\"fa-solid fa-exclamation-triangle text-danger\" aria-hidden=\"true\"></i>\n } @else if (bulkActionType === 'enable') {\n <i class=\"fa-solid fa-toggle-on text-success\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-toggle-off text-warning\" aria-hidden=\"true\"></i>\n }\n {{ getBulkActionTitle() }}\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"cancelBulkAction()\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"bulk-action-dialog-desc\">\n <p>{{ getBulkActionMessage() }}</p>\n @if (bulkActionType === 'delete') {\n <p class=\"text-muted\">This action cannot be undone.</p>\n }\n </div>\n <div class=\"modal-footer\">\n <button mjButton\n [variant]=\"bulkActionType === 'delete' ? 'danger' : 'primary'\"\n (click)=\"executeBulkAction()\"\n [disabled]=\"isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Processing...\n } @else {\n @if (bulkActionType === 'delete') {\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n } @else if (bulkActionType === 'enable') {\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n }\n {{ getBulkActionButtonText() }}\n }\n </button>\n <button mjButton (click)=\"cancelBulkAction()\" [disabled]=\"isLoading\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Bulk Role Assignment Dialog -->\n @if (showBulkRoleAssign) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelBulkRoleAssign()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"bulk-role-dialog-title\"\n aria-describedby=\"bulk-role-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"bulk-role-dialog-title\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n Assign Role to {{ selectedCount }} User{{ selectedCount > 1 ? 's' : '' }}\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"cancelBulkRoleAssign()\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"bulk-role-dialog-desc\">\n <p>Select a role to assign to the selected users:</p>\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"bulk-role-select\">Role</label>\n <select\n id=\"bulk-role-select\"\n class=\"field-select\"\n [(ngModel)]=\"bulkRoleId\"\n aria-label=\"Select role to assign\"\n >\n <option value=\"\">Select a role...</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 class=\"modal-footer\">\n <button\n mjButton variant=\"primary\"\n (click)=\"executeBulkRoleAssign()\"\n [disabled]=\"!bulkRoleId || isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Assigning...\n } @else {\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n Assign Role\n }\n </button>\n <button mjButton (click)=\"cancelBulkRoleAssign()\" [disabled]=\"isLoading\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-explorer-settings",
|
|
3
|
-
"version": "5.51.
|
|
3
|
+
"version": "5.51.4",
|
|
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",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@angular/compiler": "21.1.3",
|
|
29
29
|
"@angular/compiler-cli": "21.1.3",
|
|
30
|
-
"@memberjunction/ng-test-utils": "5.51.
|
|
30
|
+
"@memberjunction/ng-test-utils": "5.51.4"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@angular/common": "21.1.3",
|
|
@@ -37,24 +37,24 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@angular/cdk": "21.1.3",
|
|
40
|
-
"@memberjunction/core": "5.51.
|
|
41
|
-
"@memberjunction/core-entities": "5.51.
|
|
42
|
-
"@memberjunction/global": "5.51.
|
|
43
|
-
"@memberjunction/graphql-dataprovider": "5.51.
|
|
44
|
-
"@memberjunction/ng-base-application": "5.51.
|
|
45
|
-
"@memberjunction/ng-base-forms": "5.51.
|
|
46
|
-
"@memberjunction/ng-base-types": "5.51.
|
|
47
|
-
"@memberjunction/ng-code-editor": "5.51.
|
|
48
|
-
"@memberjunction/ng-entity-form-dialog": "5.51.
|
|
49
|
-
"@memberjunction/ng-entity-permissions": "5.51.
|
|
50
|
-
"@memberjunction/ng-join-grid": "5.51.
|
|
51
|
-
"@memberjunction/ng-notifications": "5.51.
|
|
52
|
-
"@memberjunction/ng-shared": "5.51.
|
|
53
|
-
"@memberjunction/ng-shared-generic": "5.51.
|
|
54
|
-
"@memberjunction/ng-simple-record-list": "5.51.
|
|
55
|
-
"@memberjunction/ng-tabstrip": "5.51.
|
|
56
|
-
"@memberjunction/ng-ui-components": "5.51.
|
|
57
|
-
"@memberjunction/ng-user-avatar": "5.51.
|
|
40
|
+
"@memberjunction/core": "5.51.4",
|
|
41
|
+
"@memberjunction/core-entities": "5.51.4",
|
|
42
|
+
"@memberjunction/global": "5.51.4",
|
|
43
|
+
"@memberjunction/graphql-dataprovider": "5.51.4",
|
|
44
|
+
"@memberjunction/ng-base-application": "5.51.4",
|
|
45
|
+
"@memberjunction/ng-base-forms": "5.51.4",
|
|
46
|
+
"@memberjunction/ng-base-types": "5.51.4",
|
|
47
|
+
"@memberjunction/ng-code-editor": "5.51.4",
|
|
48
|
+
"@memberjunction/ng-entity-form-dialog": "5.51.4",
|
|
49
|
+
"@memberjunction/ng-entity-permissions": "5.51.4",
|
|
50
|
+
"@memberjunction/ng-join-grid": "5.51.4",
|
|
51
|
+
"@memberjunction/ng-notifications": "5.51.4",
|
|
52
|
+
"@memberjunction/ng-shared": "5.51.4",
|
|
53
|
+
"@memberjunction/ng-shared-generic": "5.51.4",
|
|
54
|
+
"@memberjunction/ng-simple-record-list": "5.51.4",
|
|
55
|
+
"@memberjunction/ng-tabstrip": "5.51.4",
|
|
56
|
+
"@memberjunction/ng-ui-components": "5.51.4",
|
|
57
|
+
"@memberjunction/ng-user-avatar": "5.51.4",
|
|
58
58
|
"rxjs": "~7.8.2",
|
|
59
59
|
"tslib": "^2.8.1"
|
|
60
60
|
},
|