@memberjunction/ng-base-forms 5.4.1 → 5.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"base-form-component.d.ts","sourceRoot":"","sources":["../../src/lib/base-form-component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-form-component.d.ts","sourceRoot":"","sources":["../../src/lib/base-form-component.ts"],"names":[],"mappings":"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"}
@@ -146,10 +146,18 @@ export class BaseFormComponent extends BaseRecordComponent {
146
146
  // #region Edit Mode
147
147
  StartEditMode() {
148
148
  this.EditMode = true;
149
+ const entityName = this.getEntityName();
150
+ if (entityName) {
151
+ this.formStateService.setEditMode(entityName, true);
152
+ }
149
153
  }
150
154
  EndEditMode() {
151
155
  this.EditMode = false;
152
156
  this.clearValidationState();
157
+ const entityName = this.getEntityName();
158
+ if (entityName) {
159
+ this.formStateService.setEditMode(entityName, false);
160
+ }
153
161
  }
154
162
  handleHistoryDialog() {
155
163
  this.isHistoryDialogOpen = !this.isHistoryDialogOpen;
@@ -1 +1 @@
1
- {"version":3,"file":"base-form-component.js","sourceRoot":"","sources":["../../src/lib/base-form-component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AfterViewInit, OnInit, OnDestroy, Directive,\n ViewChildren, QueryList, ElementRef, ChangeDetectorRef,\n Output, EventEmitter, inject\n} from '@angular/core';\n\nimport { Subject, Subscription, debounceTime } from 'rxjs';\nimport {\n EntityInfo, ValidationResult, BaseEntity, EntityPermissionType,\n EntityRelationshipInfo, Metadata, RunViewParams, LogError,\n RecordDependency, BaseEntityEvent, CompositeKey, RunView, RunViewResult\n} from '@memberjunction/core';\nimport { MJEventType, MJGlobal, ValidationErrorInfo } from '@memberjunction/global';\nimport { FormEditingCompleteEvent, PendingRecordItem, BaseFormComponentEventCodes } from '@memberjunction/ng-base-types';\nimport { MJListEntity } from '@memberjunction/core-entities';\n\nimport { BaseRecordComponent } from './base-record-component';\nimport { BaseFormSectionInfo } from './base-form-section-info';\nimport { MjCollapsiblePanelComponent } from './panel/collapsible-panel.component';\nimport { FormNavigationEvent } from './types/navigation-events';\nimport {\n FormContext,\n FormNotificationEvent,\n RecordSavedEvent,\n RecordDeletedEvent,\n RecordSaveFailedEvent,\n RecordDeleteFailedEvent,\n ValidationFailedEvent\n} from './types/form-types';\nimport { FormStateService } from './form-state.service';\n\n/**\n * Abstract base class for all entity record forms in MemberJunction.\n *\n * Generated forms (via CodeGen) and custom forms extend this class.\n * It provides core form logic — section management, validation, pending records,\n * permissions, favorites, related entity helpers — with ZERO Explorer dependencies.\n *\n * Instead of calling Explorer services directly, events are emitted via @Output:\n * - **Navigate**: Form navigation requests (record links, new records, external links)\n * - **Notification**: User-facing notifications (save success, validation errors, etc.)\n * - **RecordSaved**: Emitted after a successful save\n * - **RecordDeleted**: Emitted after a successful delete\n *\n * The host application (e.g. SingleRecordComponent in Explorer) subscribes to\n * these events and maps them to its own services (NavigationService, SharedService, etc.).\n */\n@Directive()\nexport abstract class BaseFormComponent extends BaseRecordComponent implements AfterViewInit, OnInit, OnDestroy {\n public EditMode: boolean = false;\n public FavoriteInitDone: boolean = false;\n public isHistoryDialogOpen: boolean = false;\n public showDeleteDialog: boolean = false;\n public showCreateDialog: boolean = false;\n\n /**\n * Height of the top area when a splitter layout is used.\n * Referenced by CodeGen-generated templates for entities with \"top area\" sections.\n */\n public TopAreaHeight: string = '300px';\n\n /**\n * Called when the splitter layout changes (for entities with \"top area\" sections).\n * No-op in the generic version; override in host application if splitter resizing is needed.\n */\n public splitterLayoutChange(): void {\n // No-op — host application can override\n }\n\n private _pendingRecords: PendingRecordItem[] = [];\n\n // #region Injected Dependencies (no constructor params)\n\n protected elementRef = inject(ElementRef);\n public cdr = inject(ChangeDetectorRef);\n protected formStateService = inject(FormStateService);\n\n // #endregion\n\n // #region @Output Events\n\n /** Emitted when navigation is requested (record link, external link, email, new record, etc.) */\n @Output() Navigate = new EventEmitter<FormNavigationEvent>();\n\n /** Emitted when a user-facing notification should be shown */\n @Output() Notification = new EventEmitter<FormNotificationEvent>();\n\n /** Emitted after a record is saved successfully */\n @Output() RecordSaved = new EventEmitter<RecordSavedEvent>();\n\n /** Emitted after a record is deleted successfully */\n @Output() RecordDeleted = new EventEmitter<RecordDeletedEvent>();\n\n /** Emitted when a record save fails */\n @Output() RecordSaveFailed = new EventEmitter<RecordSaveFailedEvent>();\n\n /** Emitted when a record delete fails */\n @Output() RecordDeleteFailed = new EventEmitter<RecordDeleteFailedEvent>();\n\n /** Emitted when validation fails before save */\n @Output() ValidationFailed = new EventEmitter<ValidationFailedEvent>();\n\n // #endregion\n\n /** Subscription to form state changes */\n private formStateSubscription?: Subscription;\n\n @ViewChildren(MjCollapsiblePanelComponent) collapsiblePanels!: QueryList<MjCollapsiblePanelComponent>;\n\n async ngOnInit() {\n if (this.record) {\n if (!this.record.IsSaved) {\n this.StartEditMode();\n }\n const md = new Metadata();\n this._isFavorite = await md.GetRecordFavoriteStatus(md.CurrentUser.ID, this.record.EntityInfo.Name, this.record.PrimaryKey);\n this.FavoriteInitDone = true;\n\n // Initialize form state from User Settings\n const entityName = this.getEntityName();\n if (entityName) {\n await this.formStateService.initializeState(entityName);\n this.formStateSubscription = this.formStateService.getState$(entityName).subscribe(state => {\n this.showEmptyFields = state.showEmptyFields;\n this.cdr.markForCheck();\n });\n }\n }\n\n // Set up debounced filter subscription\n this.filterSubscription = this.filterSubject\n .pipe(debounceTime(100))\n .subscribe(searchTerm => {\n this.searchFilter = searchTerm;\n // After change detection propagates FormContext to panels and they update\n // their IsVisible state, expand any visible (matching) sections that are collapsed\n if (searchTerm) {\n Promise.resolve().then(() => this.expandMatchingSections());\n }\n });\n }\n\n ngAfterViewInit(): void {\n // Subclasses can override for post-view-init logic\n }\n\n ngOnDestroy(): void {\n if (this.filterSubscription) {\n this.filterSubscription.unsubscribe();\n }\n if (this.formStateSubscription) {\n this.formStateSubscription.unsubscribe();\n }\n }\n\n // #region Pending Records\n\n protected get PendingRecords(): PendingRecordItem[] {\n return this._pendingRecords;\n }\n\n protected PendingRecordsDirty(): boolean {\n this.PopulatePendingRecords();\n const pendingRecords = this.PendingRecords;\n if (pendingRecords && pendingRecords.length > 0) {\n for (const p of pendingRecords) {\n if (p.action === 'delete')\n return true;\n else if (p.entityObject.Dirty)\n return true;\n }\n }\n return false;\n }\n\n protected PopulatePendingRecords() {\n this._pendingRecords = [];\n this.RaiseEvent(BaseFormComponentEventCodes.EDITING_COMPLETE);\n const result = this.RaiseEvent(BaseFormComponentEventCodes.POPULATE_PENDING_RECORDS);\n if (result && result.pendingChanges) {\n for (const p of result.pendingChanges)\n this.PendingRecords.push(p);\n }\n }\n\n protected ValidatePendingRecords(): ValidationResult[] {\n const results: ValidationResult[] = [];\n for (let i = 0; i < this._pendingRecords.length; i++) {\n const pendingRecord = this._pendingRecords[i];\n results.push(pendingRecord.entityObject.Validate());\n }\n return results;\n }\n\n // #endregion\n\n // #region Edit Mode\n\n public StartEditMode(): void {\n this.EditMode = true;\n }\n\n public EndEditMode(): void {\n this.EditMode = false;\n this.clearValidationState();\n }\n\n public handleHistoryDialog(): void {\n this.isHistoryDialogOpen = !this.isHistoryDialogOpen;\n }\n\n // #endregion\n\n // #region Core Form Operations\n\n public Validate(): ValidationResult {\n const valResults = (<BaseEntity>this.record).Validate();\n const pendingValResults = this.ValidatePendingRecords();\n for (let i = 0; i < pendingValResults.length; i++) {\n const pendingValResult = pendingValResults[i];\n if (!pendingValResult.Success) {\n valResults.Success = false;\n valResults.Errors.push(...pendingValResult.Errors);\n }\n }\n return valResults;\n }\n\n protected RaiseEvent(eventCode: BaseFormComponentEventCodes) {\n const event = new FormEditingCompleteEvent();\n event.elementRef = this.elementRef;\n event.subEventCode = eventCode;\n\n MJGlobal.Instance.RaiseEvent({\n event: MJEventType.ComponentEvent,\n component: this,\n eventCode: BaseFormComponentEventCodes.BASE_CODE,\n args: event\n });\n\n return event;\n }\n\n public async SaveRecord(StopEditModeAfterSave: boolean): Promise<boolean> {\n try {\n try {\n (document.activeElement as HTMLElement).blur();\n this.RaiseEvent(BaseFormComponentEventCodes.EDITING_COMPLETE);\n } catch (_e) {\n // ignore blur errors\n }\n\n if (this.record) {\n this.PopulatePendingRecords();\n const valResults = this.Validate();\n if (valResults.Success) {\n const result = await this.InternalSaveRecord();\n if (result) {\n this._pendingRecords = [];\n this.clearValidationState();\n if (StopEditModeAfterSave)\n this.EndEditMode();\n\n this.Notification.emit({ Message: 'Record saved successfully', Type: 'success', Duration: 2500 });\n this.RecordSaved.emit({\n EntityName: this.record.EntityInfo.Name,\n RecordId: this.record.PrimaryKey.ToString(),\n Result: { Success: true }\n });\n return true;\n } else {\n const serverMsg = this.record.LatestResult?.Message || '';\n const errorMsg = serverMsg ? `Save failed: ${serverMsg}` : 'Error saving record';\n this.Notification.emit({ Message: errorMsg, Type: 'error', Duration: 5000 });\n this.RecordSaveFailed.emit({ EntityName: this.record.EntityInfo.Name, ErrorMessage: errorMsg });\n }\n } else {\n // Broadcast validation errors to all fields via FormContext\n this._showValidation = true;\n this._validationErrors = valResults.Errors;\n this.cdr.markForCheck();\n\n const errorMessages = valResults.Errors.map(x => x.Message);\n this.Notification.emit({\n Message: 'Validation Errors\\n' + errorMessages.join('\\n'),\n Type: 'warning',\n Duration: 5000\n });\n this.ValidationFailed.emit({ EntityName: this.record.EntityInfo.Name, Errors: errorMessages });\n }\n }\n\n LogError(\"Could not save record: Record not found\");\n return false;\n } catch (e) {\n const errorMsg = 'Error saving record: ' + e;\n this.Notification.emit({ Message: errorMsg, Type: 'error', Duration: 5000 });\n if (this.record) {\n this.RecordSaveFailed.emit({ EntityName: this.record.EntityInfo.Name, ErrorMessage: errorMsg });\n }\n return false;\n }\n }\n\n public CancelEdit() {\n if (this.record) {\n const r = <BaseEntity>this.record;\n if (r.Dirty || this.PendingRecordsDirty()) {\n // Revert is safe here — the toolbar's discard dialog already confirmed with the user\n r.Revert();\n\n const pendingRecords = this.PendingRecords;\n if (pendingRecords && pendingRecords.length > 0) {\n pendingRecords.forEach(p => {\n if (p.action === 'save')\n p.entityObject.Revert();\n });\n }\n this.RaiseEvent(BaseFormComponentEventCodes.REVERT_PENDING_CHANGES);\n }\n this.EndEditMode();\n }\n }\n\n protected async InternalSaveRecord(): Promise<boolean> {\n if (this.record) {\n if (this._pendingRecords.length > 0) {\n const md = new Metadata();\n const tg = await md.CreateTransactionGroup();\n this.record.TransactionGroup = tg;\n await this.record.Save();\n\n for (const x of this._pendingRecords) {\n x.entityObject.TransactionGroup = tg;\n if (x.action === 'save') {\n await x.entityObject.Save();\n } else {\n await x.entityObject.Delete();\n }\n }\n return await tg.Submit();\n } else {\n return await this.record.Save();\n }\n } else {\n return false;\n }\n }\n\n public async Wait(duration: number): Promise<void> {\n return new Promise<void>(resolve => setTimeout(resolve, duration));\n }\n\n // #endregion\n\n // #region Permissions\n\n private _userPermissions: { permission: EntityPermissionType; canDo: boolean }[] = [];\n\n public CheckUserPermission(type: EntityPermissionType): boolean {\n try {\n if (this.record) {\n const perm = this._userPermissions.find(x => x.permission === type);\n if (perm)\n return perm.canDo;\n else {\n const result = this.record.CheckPermissions(type, false);\n this._userPermissions.push({ permission: type, canDo: result });\n return result;\n }\n } else {\n return false;\n }\n } catch (e) {\n LogError(e);\n return false;\n }\n }\n\n public get UserCanEdit(): boolean {\n return this.CheckUserPermission(EntityPermissionType.Update);\n }\n\n public get UserCanRead(): boolean {\n return this.CheckUserPermission(EntityPermissionType.Read);\n }\n\n public get UserCanCreate(): boolean {\n return this.CheckUserPermission(EntityPermissionType.Create);\n }\n\n public get UserCanDelete(): boolean {\n return this.CheckUserPermission(EntityPermissionType.Delete);\n }\n\n // #endregion\n\n // #region Grid Edit Mode\n\n public GridEditMode(): \"None\" | \"Save\" | \"Queue\" {\n return this.EditMode ? \"Queue\" : \"None\";\n }\n\n // #endregion\n\n // #region Favorites\n\n private _isFavorite: boolean = false;\n\n public get IsFavorite(): boolean {\n return this._isFavorite;\n }\n\n public async RemoveFavorite(): Promise<void> {\n return this.SetFavoriteStatus(false);\n }\n\n public async MakeFavorite(): Promise<void> {\n return this.SetFavoriteStatus(true);\n }\n\n public async SetFavoriteStatus(isFavorite: boolean) {\n const md = new Metadata();\n await md.SetRecordFavoriteStatus(md.CurrentUser.ID, this.record.EntityInfo.Name, this.record.PrimaryKey, isFavorite);\n this._isFavorite = isFavorite;\n }\n\n // #endregion\n\n // #region Related Entity Helpers\n\n public BuildRelationshipViewParams(item: EntityRelationshipInfo): RunViewParams {\n return EntityInfo.BuildRelationshipViewParams(this.record, item);\n }\n\n public BuildRelationshipViewParamsByEntityName(relatedEntityName: string, relatedEntityJoinField?: string): RunViewParams {\n const eri = this.GetEntityRelationshipByRelatedEntityName(relatedEntityName, relatedEntityJoinField);\n if (eri)\n return this.BuildRelationshipViewParams(eri);\n else\n return {};\n }\n\n public GetEntityRelationshipByRelatedEntityName(relatedEntityName: string, relatedEntityJoinField?: string): EntityRelationshipInfo | undefined {\n if (this.record) {\n const r = <BaseEntity>this.record;\n const ret = r.EntityInfo.RelatedEntities.filter(x => x.RelatedEntity.trim().toLowerCase() === relatedEntityName.trim().toLowerCase());\n if (ret.length > 1 && relatedEntityJoinField) {\n const ret2 = ret.find(x => x.RelatedEntityJoinField.trim().toLowerCase() === relatedEntityJoinField.trim().toLowerCase());\n if (ret2)\n return ret2;\n } else if (ret.length === 1) {\n return ret[0];\n } else {\n return undefined;\n }\n }\n return undefined;\n }\n\n public NewRecordValues(relatedEntityName: string): Record<string, unknown> {\n const eri = this.GetEntityRelationshipByRelatedEntityName(relatedEntityName);\n if (eri)\n return this.NewRecordValuesByEntityRelationship(eri);\n else\n return {};\n }\n\n public NewRecordValuesByEntityRelationship(item: EntityRelationshipInfo): Record<string, unknown> {\n return EntityInfo.BuildRelationshipNewRecordValues(this.record, item);\n }\n\n public GetRelatedEntityTabDisplayName(relatedEntityName: string): string {\n if (this.record) {\n const eri = (<BaseEntity>this.record).EntityInfo.RelatedEntities.find(x => x.RelatedEntity === relatedEntityName);\n if (eri)\n return eri.DisplayName;\n }\n return relatedEntityName;\n }\n\n public get HasRelatedEntities(): boolean {\n if (this.record) {\n const relatedEntities = (<BaseEntity>this.record).EntityInfo.RelatedEntities;\n return relatedEntities && relatedEntities.length > 0;\n }\n return false;\n }\n\n // #endregion\n\n // #region Entity Info & Dependencies\n\n public get EntityInfo(): EntityInfo | undefined {\n try {\n const r = <BaseEntity>this.record;\n if (r)\n return r.EntityInfo;\n else\n return undefined;\n } catch (e) {\n LogError(e);\n return undefined;\n }\n }\n\n public async ShowDependencies() {\n const md = new Metadata();\n const dep = await md.GetRecordDependencies(this.record.EntityInfo.Name, this.record.PrimaryKey);\n console.log('Dependencies for: ' + this.record.EntityInfo.Name + ' ' + this.record.PrimaryKey.ToString());\n console.log(dep);\n }\n\n public ShowChanges(): void {\n if (this.record) {\n const changes = this.record.GetAll(false, true);\n const oldValues = this.record.GetAll(true, true);\n const message =\n 'Changes for: ' + this.record.EntityInfo.Name + ' ' + this.record.PrimaryKey.ToString() +\n '\\n\\n' + JSON.stringify(changes, null, 2) +\n '\\n\\nOld Values\\n\\n' + JSON.stringify(oldValues, null, 2);\n console.log(message);\n this.Notification.emit({ Message: message, Type: 'info', Duration: 30000 });\n }\n }\n\n public async GetListsCanAddTo(): Promise<MJListEntity[]> {\n if (!this.record) {\n LogError('Unable to fetch List records: Record not found');\n return [];\n }\n\n const rv = new RunView();\n const md = new Metadata();\n\n const rvResult: RunViewResult<MJListEntity> = await rv.RunView({\n EntityName: 'MJ: Lists',\n ExtraFilter: `UserID = '${md.CurrentUser.ID}' AND EntityID = '${this.record.EntityInfo.ID}'`,\n ResultType: 'entity_object'\n });\n\n if (!rvResult.Success) {\n LogError('Error running view to fetch lists', undefined, rvResult.ErrorMessage);\n return [];\n }\n\n return rvResult.Results;\n }\n\n public async GetRecordDependencies(): Promise<RecordDependency[]> {\n const md = new Metadata();\n const dependencies: RecordDependency[] = await md.GetRecordDependencies(this.record.EntityInfo.Name, this.record.PrimaryKey);\n return dependencies;\n }\n\n // #endregion\n\n // #region Collapsible Section Management\n\n protected sections: BaseFormSectionInfo[] = [];\n private sectionMap: Map<string, BaseFormSectionInfo> = new Map();\n\n public searchFilter: string = '';\n public showEmptyFields: boolean = false;\n\n /** Whether to show all validation errors on fields (set after save failure) */\n private _showValidation = false;\n /** Validation errors from the most recent failed save attempt */\n private _validationErrors: ValidationErrorInfo[] = [];\n\n public get formContext(): FormContext {\n return {\n sectionFilter: this.searchFilter,\n showEmptyFields: this.showEmptyFields,\n showValidation: this._showValidation,\n validationErrors: this._validationErrors\n };\n }\n\n /** Clears all validation display state (called on save success, cancel, end edit) */\n private clearValidationState(): void {\n this._showValidation = false;\n this._validationErrors = [];\n }\n\n private filterSubject = new Subject<string>();\n private filterSubscription?: Subscription;\n\n protected initSections(sections: (BaseFormSectionInfo | { sectionKey: string; sectionName: string; isExpanded: boolean; rowCount?: number; metadata?: unknown })[]): void {\n this.sections = sections.map(s =>\n s instanceof BaseFormSectionInfo\n ? s\n : new BaseFormSectionInfo(s.sectionKey, s.sectionName, s.isExpanded, s.rowCount, s.metadata)\n );\n this.sectionMap.clear();\n this.sections.forEach(section => {\n this.sectionMap.set(section.sectionKey, section);\n });\n }\n\n protected getSection(sectionKey: string): BaseFormSectionInfo | undefined {\n return this.sectionMap.get(sectionKey);\n }\n\n public IsSectionExpanded(sectionKey: string, defaultExpanded?: boolean): boolean {\n const entityName = this.getEntityName();\n if (entityName) {\n return this.formStateService.isSectionExpanded(entityName, sectionKey, defaultExpanded);\n }\n const section = this.sectionMap.get(sectionKey);\n return section ? section.isExpanded : (defaultExpanded !== undefined ? defaultExpanded : true);\n }\n\n public SetSectionExpanded(sectionKey: string, isExpanded: boolean): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.setSectionExpanded(entityName, sectionKey, isExpanded);\n }\n const section = this.sectionMap.get(sectionKey);\n if (section) {\n section.isExpanded = isExpanded;\n }\n }\n\n public GetSectionRowCount(sectionKey: string): number | undefined {\n const section = this.sectionMap.get(sectionKey);\n return section?.rowCount;\n }\n\n public SetSectionRowCount(sectionKey: string, rowCount: number): void {\n const section = this.sectionMap.get(sectionKey);\n if (section) {\n section.rowCount = rowCount;\n }\n }\n\n public GetSectionPanelHeight(sectionKey: string): number | undefined {\n const entityName = this.getEntityName();\n if (entityName) {\n return this.formStateService.getSectionPanelHeight(entityName, sectionKey);\n }\n return undefined;\n }\n\n public SetSectionPanelHeight(sectionKey: string, height: number): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.setSectionPanelHeight(entityName, sectionKey, height);\n }\n }\n\n public toggleSection(sectionKey: string): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.toggleSection(entityName, sectionKey);\n }\n const section = this.sectionMap.get(sectionKey);\n if (section) {\n section.isExpanded = !section.isExpanded;\n }\n }\n\n /**\n * Expand any sections that are visible (match the current filter) but currently collapsed.\n * Called after filter changes so the user can immediately see matching content.\n */\n private expandMatchingSections(): void {\n if (!this.collapsiblePanels) return;\n this.collapsiblePanels.forEach(panel => {\n if (panel.IsVisible && !panel.Expanded) {\n this.SetSectionExpanded(panel.SectionKey, true);\n }\n });\n }\n\n public expandAllSections(): void {\n const entityName = this.getEntityName();\n const sectionKeys = this.sections.map(s => s.sectionKey);\n if (entityName && sectionKeys.length > 0) {\n this.formStateService.expandAllSections(entityName, sectionKeys);\n }\n this.sections.forEach(section => {\n section.isExpanded = true;\n });\n }\n\n public collapseAllSections(): void {\n const entityName = this.getEntityName();\n const sectionKeys = this.sections.map(s => s.sectionKey);\n if (entityName && sectionKeys.length > 0) {\n this.formStateService.collapseAllSections(entityName, sectionKeys);\n }\n this.sections.forEach(section => {\n section.isExpanded = false;\n });\n }\n\n public getExpandedCount(): number {\n const entityName = this.getEntityName();\n const sectionKeys = this.sections.map(s => s.sectionKey);\n if (entityName && sectionKeys.length > 0) {\n return this.formStateService.getExpandedCount(entityName, sectionKeys);\n }\n return this.sections.filter(section => section.isExpanded).length;\n }\n\n public getVisibleSectionCount(): number {\n if (!this.collapsiblePanels || this.collapsiblePanels.length === 0) {\n return this.sections.length;\n }\n return this.collapsiblePanels.filter(panel => panel.IsVisible).length;\n }\n\n public getTotalSectionCount(): number {\n return this.sections.length;\n }\n\n public onFilterChange(searchTerm: string): void {\n this.filterSubject.next(searchTerm);\n }\n\n public getEntityName(): string {\n return this.record?.EntityInfo?.Name || '';\n }\n\n public getFormWidthMode(): 'centered' | 'full-width' {\n const entityName = this.getEntityName();\n if (entityName) {\n return this.formStateService.getWidthMode(entityName);\n }\n return 'centered';\n }\n\n public setFormWidthMode(widthMode: 'centered' | 'full-width'): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.setWidthMode(entityName, widthMode);\n }\n }\n\n public toggleFormWidthMode(): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.toggleWidthMode(entityName);\n }\n }\n\n // #endregion\n\n // #region Section Ordering\n\n public getSectionOrder(): string[] {\n const entityName = this.getEntityName();\n if (entityName) {\n const customOrder = this.formStateService.getSectionOrder(entityName);\n if (customOrder && customOrder.length > 0) {\n return customOrder;\n }\n }\n return this.sections.map(s => s.sectionKey);\n }\n\n public setSectionOrder(sectionOrder: string[]): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.setSectionOrder(entityName, sectionOrder);\n }\n }\n\n public resetSectionOrder(): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.resetSectionOrder(entityName);\n }\n }\n\n public hasCustomSectionOrder(): boolean {\n const entityName = this.getEntityName();\n if (entityName) {\n return this.formStateService.hasCustomSectionOrder(entityName);\n }\n return false;\n }\n\n public getSectionDisplayOrder(sectionKey: string): number {\n const order = this.getSectionOrder();\n const index = order.indexOf(sectionKey);\n return index >= 0 ? index : this.sections.length;\n }\n\n // #endregion\n\n // #region Form Container Event Handlers\n\n /**\n * Handles navigation events from the form container and related entity grids.\n * Relays the event upward via the Navigate @Output for the host application to handle.\n * Generated form templates bind this as: (Navigate)=\"OnFormNavigate($event)\"\n */\n public OnFormNavigate(event: FormNavigationEvent): void {\n this.Navigate.emit(event);\n }\n\n /**\n * Handles delete requests from the form container.\n * Emits RecordDeleted on success, RecordDeleteFailed on failure.\n * Generated form templates bind this as: (DeleteRequested)=\"OnDeleteRequested()\"\n */\n public async OnDeleteRequested(): Promise<void> {\n if (!this.record || !this.record.IsSaved) return;\n try {\n const result = await this.record.Delete();\n if (result) {\n this.Notification.emit({ Message: 'Record deleted successfully', Type: 'success', Duration: 2500 });\n this.RecordDeleted.emit({\n EntityName: this.record.EntityInfo.Name,\n RecordId: this.record.PrimaryKey.ToString()\n });\n } else {\n const errorMsg = 'Error deleting record';\n this.Notification.emit({ Message: errorMsg, Type: 'error', Duration: 5000 });\n this.RecordDeleteFailed.emit({ EntityName: this.record.EntityInfo.Name, ErrorMessage: errorMsg });\n }\n } catch (e) {\n const errorMsg = 'Error deleting record: ' + e;\n this.Notification.emit({ Message: errorMsg, Type: 'error', Duration: 5000 });\n this.RecordDeleteFailed.emit({ EntityName: this.record.EntityInfo.Name, ErrorMessage: errorMsg });\n }\n }\n\n /**\n * Handles favorite toggle from the form container.\n * Generated form templates bind this as: (FavoriteToggled)=\"OnFavoriteToggled()\"\n */\n public async OnFavoriteToggled(): Promise<void> {\n await this.SetFavoriteStatus(!this.IsFavorite);\n }\n\n /**\n * Handles history view requests from the form container.\n * Generated form templates bind this as: (HistoryRequested)=\"OnHistoryRequested()\"\n */\n public OnHistoryRequested(): void {\n this.handleHistoryDialog();\n }\n\n /**\n * Handles list management requests from the form container.\n * Generated form templates bind this as: (ListManagementRequested)=\"OnListManagementRequested()\"\n */\n public OnListManagementRequested(): void {\n // List management dialog is handled by the host application\n // Subclasses can override this to implement custom list management\n }\n\n // #endregion\n}\n"]}
1
+ {"version":3,"file":"base-form-component.js","sourceRoot":"","sources":["../../src/lib/base-form-component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AfterViewInit, OnInit, OnDestroy, Directive,\n ViewChildren, QueryList, ElementRef, ChangeDetectorRef,\n Output, EventEmitter, inject\n} from '@angular/core';\n\nimport { Subject, Subscription, debounceTime } from 'rxjs';\nimport {\n EntityInfo, ValidationResult, BaseEntity, EntityPermissionType,\n EntityRelationshipInfo, Metadata, RunViewParams, LogError,\n RecordDependency, BaseEntityEvent, CompositeKey, RunView, RunViewResult\n} from '@memberjunction/core';\nimport { MJEventType, MJGlobal, ValidationErrorInfo } from '@memberjunction/global';\nimport { FormEditingCompleteEvent, PendingRecordItem, BaseFormComponentEventCodes } from '@memberjunction/ng-base-types';\nimport { MJListEntity } from '@memberjunction/core-entities';\n\nimport { BaseRecordComponent } from './base-record-component';\nimport { BaseFormSectionInfo } from './base-form-section-info';\nimport { MjCollapsiblePanelComponent } from './panel/collapsible-panel.component';\nimport { FormNavigationEvent } from './types/navigation-events';\nimport {\n FormContext,\n FormNotificationEvent,\n RecordSavedEvent,\n RecordDeletedEvent,\n RecordSaveFailedEvent,\n RecordDeleteFailedEvent,\n ValidationFailedEvent\n} from './types/form-types';\nimport { FormStateService } from './form-state.service';\n\n/**\n * Abstract base class for all entity record forms in MemberJunction.\n *\n * Generated forms (via CodeGen) and custom forms extend this class.\n * It provides core form logic — section management, validation, pending records,\n * permissions, favorites, related entity helpers — with ZERO Explorer dependencies.\n *\n * Instead of calling Explorer services directly, events are emitted via @Output:\n * - **Navigate**: Form navigation requests (record links, new records, external links)\n * - **Notification**: User-facing notifications (save success, validation errors, etc.)\n * - **RecordSaved**: Emitted after a successful save\n * - **RecordDeleted**: Emitted after a successful delete\n *\n * The host application (e.g. SingleRecordComponent in Explorer) subscribes to\n * these events and maps them to its own services (NavigationService, SharedService, etc.).\n */\n@Directive()\nexport abstract class BaseFormComponent extends BaseRecordComponent implements AfterViewInit, OnInit, OnDestroy {\n public EditMode: boolean = false;\n public FavoriteInitDone: boolean = false;\n public isHistoryDialogOpen: boolean = false;\n public showDeleteDialog: boolean = false;\n public showCreateDialog: boolean = false;\n\n /**\n * Height of the top area when a splitter layout is used.\n * Referenced by CodeGen-generated templates for entities with \"top area\" sections.\n */\n public TopAreaHeight: string = '300px';\n\n /**\n * Called when the splitter layout changes (for entities with \"top area\" sections).\n * No-op in the generic version; override in host application if splitter resizing is needed.\n */\n public splitterLayoutChange(): void {\n // No-op — host application can override\n }\n\n private _pendingRecords: PendingRecordItem[] = [];\n\n // #region Injected Dependencies (no constructor params)\n\n protected elementRef = inject(ElementRef);\n public cdr = inject(ChangeDetectorRef);\n protected formStateService = inject(FormStateService);\n\n // #endregion\n\n // #region @Output Events\n\n /** Emitted when navigation is requested (record link, external link, email, new record, etc.) */\n @Output() Navigate = new EventEmitter<FormNavigationEvent>();\n\n /** Emitted when a user-facing notification should be shown */\n @Output() Notification = new EventEmitter<FormNotificationEvent>();\n\n /** Emitted after a record is saved successfully */\n @Output() RecordSaved = new EventEmitter<RecordSavedEvent>();\n\n /** Emitted after a record is deleted successfully */\n @Output() RecordDeleted = new EventEmitter<RecordDeletedEvent>();\n\n /** Emitted when a record save fails */\n @Output() RecordSaveFailed = new EventEmitter<RecordSaveFailedEvent>();\n\n /** Emitted when a record delete fails */\n @Output() RecordDeleteFailed = new EventEmitter<RecordDeleteFailedEvent>();\n\n /** Emitted when validation fails before save */\n @Output() ValidationFailed = new EventEmitter<ValidationFailedEvent>();\n\n // #endregion\n\n /** Subscription to form state changes */\n private formStateSubscription?: Subscription;\n\n @ViewChildren(MjCollapsiblePanelComponent) collapsiblePanels!: QueryList<MjCollapsiblePanelComponent>;\n\n async ngOnInit() {\n if (this.record) {\n if (!this.record.IsSaved) {\n this.StartEditMode();\n }\n const md = new Metadata();\n this._isFavorite = await md.GetRecordFavoriteStatus(md.CurrentUser.ID, this.record.EntityInfo.Name, this.record.PrimaryKey);\n this.FavoriteInitDone = true;\n\n // Initialize form state from User Settings\n const entityName = this.getEntityName();\n if (entityName) {\n await this.formStateService.initializeState(entityName);\n this.formStateSubscription = this.formStateService.getState$(entityName).subscribe(state => {\n this.showEmptyFields = state.showEmptyFields;\n this.cdr.markForCheck();\n });\n }\n }\n\n // Set up debounced filter subscription\n this.filterSubscription = this.filterSubject\n .pipe(debounceTime(100))\n .subscribe(searchTerm => {\n this.searchFilter = searchTerm;\n // After change detection propagates FormContext to panels and they update\n // their IsVisible state, expand any visible (matching) sections that are collapsed\n if (searchTerm) {\n Promise.resolve().then(() => this.expandMatchingSections());\n }\n });\n }\n\n ngAfterViewInit(): void {\n // Subclasses can override for post-view-init logic\n }\n\n ngOnDestroy(): void {\n if (this.filterSubscription) {\n this.filterSubscription.unsubscribe();\n }\n if (this.formStateSubscription) {\n this.formStateSubscription.unsubscribe();\n }\n }\n\n // #region Pending Records\n\n protected get PendingRecords(): PendingRecordItem[] {\n return this._pendingRecords;\n }\n\n protected PendingRecordsDirty(): boolean {\n this.PopulatePendingRecords();\n const pendingRecords = this.PendingRecords;\n if (pendingRecords && pendingRecords.length > 0) {\n for (const p of pendingRecords) {\n if (p.action === 'delete')\n return true;\n else if (p.entityObject.Dirty)\n return true;\n }\n }\n return false;\n }\n\n protected PopulatePendingRecords() {\n this._pendingRecords = [];\n this.RaiseEvent(BaseFormComponentEventCodes.EDITING_COMPLETE);\n const result = this.RaiseEvent(BaseFormComponentEventCodes.POPULATE_PENDING_RECORDS);\n if (result && result.pendingChanges) {\n for (const p of result.pendingChanges)\n this.PendingRecords.push(p);\n }\n }\n\n protected ValidatePendingRecords(): ValidationResult[] {\n const results: ValidationResult[] = [];\n for (let i = 0; i < this._pendingRecords.length; i++) {\n const pendingRecord = this._pendingRecords[i];\n results.push(pendingRecord.entityObject.Validate());\n }\n return results;\n }\n\n // #endregion\n\n // #region Edit Mode\n\n public StartEditMode(): void {\n this.EditMode = true;\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.setEditMode(entityName, true);\n }\n }\n\n public EndEditMode(): void {\n this.EditMode = false;\n this.clearValidationState();\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.setEditMode(entityName, false);\n }\n }\n\n public handleHistoryDialog(): void {\n this.isHistoryDialogOpen = !this.isHistoryDialogOpen;\n }\n\n // #endregion\n\n // #region Core Form Operations\n\n public Validate(): ValidationResult {\n const valResults = (<BaseEntity>this.record).Validate();\n const pendingValResults = this.ValidatePendingRecords();\n for (let i = 0; i < pendingValResults.length; i++) {\n const pendingValResult = pendingValResults[i];\n if (!pendingValResult.Success) {\n valResults.Success = false;\n valResults.Errors.push(...pendingValResult.Errors);\n }\n }\n return valResults;\n }\n\n protected RaiseEvent(eventCode: BaseFormComponentEventCodes) {\n const event = new FormEditingCompleteEvent();\n event.elementRef = this.elementRef;\n event.subEventCode = eventCode;\n\n MJGlobal.Instance.RaiseEvent({\n event: MJEventType.ComponentEvent,\n component: this,\n eventCode: BaseFormComponentEventCodes.BASE_CODE,\n args: event\n });\n\n return event;\n }\n\n public async SaveRecord(StopEditModeAfterSave: boolean): Promise<boolean> {\n try {\n try {\n (document.activeElement as HTMLElement).blur();\n this.RaiseEvent(BaseFormComponentEventCodes.EDITING_COMPLETE);\n } catch (_e) {\n // ignore blur errors\n }\n\n if (this.record) {\n this.PopulatePendingRecords();\n const valResults = this.Validate();\n if (valResults.Success) {\n const result = await this.InternalSaveRecord();\n if (result) {\n this._pendingRecords = [];\n this.clearValidationState();\n if (StopEditModeAfterSave)\n this.EndEditMode();\n\n this.Notification.emit({ Message: 'Record saved successfully', Type: 'success', Duration: 2500 });\n this.RecordSaved.emit({\n EntityName: this.record.EntityInfo.Name,\n RecordId: this.record.PrimaryKey.ToString(),\n Result: { Success: true }\n });\n return true;\n } else {\n const serverMsg = this.record.LatestResult?.Message || '';\n const errorMsg = serverMsg ? `Save failed: ${serverMsg}` : 'Error saving record';\n this.Notification.emit({ Message: errorMsg, Type: 'error', Duration: 5000 });\n this.RecordSaveFailed.emit({ EntityName: this.record.EntityInfo.Name, ErrorMessage: errorMsg });\n }\n } else {\n // Broadcast validation errors to all fields via FormContext\n this._showValidation = true;\n this._validationErrors = valResults.Errors;\n this.cdr.markForCheck();\n\n const errorMessages = valResults.Errors.map(x => x.Message);\n this.Notification.emit({\n Message: 'Validation Errors\\n' + errorMessages.join('\\n'),\n Type: 'warning',\n Duration: 5000\n });\n this.ValidationFailed.emit({ EntityName: this.record.EntityInfo.Name, Errors: errorMessages });\n }\n }\n\n LogError(\"Could not save record: Record not found\");\n return false;\n } catch (e) {\n const errorMsg = 'Error saving record: ' + e;\n this.Notification.emit({ Message: errorMsg, Type: 'error', Duration: 5000 });\n if (this.record) {\n this.RecordSaveFailed.emit({ EntityName: this.record.EntityInfo.Name, ErrorMessage: errorMsg });\n }\n return false;\n }\n }\n\n public CancelEdit() {\n if (this.record) {\n const r = <BaseEntity>this.record;\n if (r.Dirty || this.PendingRecordsDirty()) {\n // Revert is safe here — the toolbar's discard dialog already confirmed with the user\n r.Revert();\n\n const pendingRecords = this.PendingRecords;\n if (pendingRecords && pendingRecords.length > 0) {\n pendingRecords.forEach(p => {\n if (p.action === 'save')\n p.entityObject.Revert();\n });\n }\n this.RaiseEvent(BaseFormComponentEventCodes.REVERT_PENDING_CHANGES);\n }\n this.EndEditMode();\n }\n }\n\n protected async InternalSaveRecord(): Promise<boolean> {\n if (this.record) {\n if (this._pendingRecords.length > 0) {\n const md = new Metadata();\n const tg = await md.CreateTransactionGroup();\n this.record.TransactionGroup = tg;\n await this.record.Save();\n\n for (const x of this._pendingRecords) {\n x.entityObject.TransactionGroup = tg;\n if (x.action === 'save') {\n await x.entityObject.Save();\n } else {\n await x.entityObject.Delete();\n }\n }\n return await tg.Submit();\n } else {\n return await this.record.Save();\n }\n } else {\n return false;\n }\n }\n\n public async Wait(duration: number): Promise<void> {\n return new Promise<void>(resolve => setTimeout(resolve, duration));\n }\n\n // #endregion\n\n // #region Permissions\n\n private _userPermissions: { permission: EntityPermissionType; canDo: boolean }[] = [];\n\n public CheckUserPermission(type: EntityPermissionType): boolean {\n try {\n if (this.record) {\n const perm = this._userPermissions.find(x => x.permission === type);\n if (perm)\n return perm.canDo;\n else {\n const result = this.record.CheckPermissions(type, false);\n this._userPermissions.push({ permission: type, canDo: result });\n return result;\n }\n } else {\n return false;\n }\n } catch (e) {\n LogError(e);\n return false;\n }\n }\n\n public get UserCanEdit(): boolean {\n return this.CheckUserPermission(EntityPermissionType.Update);\n }\n\n public get UserCanRead(): boolean {\n return this.CheckUserPermission(EntityPermissionType.Read);\n }\n\n public get UserCanCreate(): boolean {\n return this.CheckUserPermission(EntityPermissionType.Create);\n }\n\n public get UserCanDelete(): boolean {\n return this.CheckUserPermission(EntityPermissionType.Delete);\n }\n\n // #endregion\n\n // #region Grid Edit Mode\n\n public GridEditMode(): \"None\" | \"Save\" | \"Queue\" {\n return this.EditMode ? \"Queue\" : \"None\";\n }\n\n // #endregion\n\n // #region Favorites\n\n private _isFavorite: boolean = false;\n\n public get IsFavorite(): boolean {\n return this._isFavorite;\n }\n\n public async RemoveFavorite(): Promise<void> {\n return this.SetFavoriteStatus(false);\n }\n\n public async MakeFavorite(): Promise<void> {\n return this.SetFavoriteStatus(true);\n }\n\n public async SetFavoriteStatus(isFavorite: boolean) {\n const md = new Metadata();\n await md.SetRecordFavoriteStatus(md.CurrentUser.ID, this.record.EntityInfo.Name, this.record.PrimaryKey, isFavorite);\n this._isFavorite = isFavorite;\n }\n\n // #endregion\n\n // #region Related Entity Helpers\n\n public BuildRelationshipViewParams(item: EntityRelationshipInfo): RunViewParams {\n return EntityInfo.BuildRelationshipViewParams(this.record, item);\n }\n\n public BuildRelationshipViewParamsByEntityName(relatedEntityName: string, relatedEntityJoinField?: string): RunViewParams {\n const eri = this.GetEntityRelationshipByRelatedEntityName(relatedEntityName, relatedEntityJoinField);\n if (eri)\n return this.BuildRelationshipViewParams(eri);\n else\n return {};\n }\n\n public GetEntityRelationshipByRelatedEntityName(relatedEntityName: string, relatedEntityJoinField?: string): EntityRelationshipInfo | undefined {\n if (this.record) {\n const r = <BaseEntity>this.record;\n const ret = r.EntityInfo.RelatedEntities.filter(x => x.RelatedEntity.trim().toLowerCase() === relatedEntityName.trim().toLowerCase());\n if (ret.length > 1 && relatedEntityJoinField) {\n const ret2 = ret.find(x => x.RelatedEntityJoinField.trim().toLowerCase() === relatedEntityJoinField.trim().toLowerCase());\n if (ret2)\n return ret2;\n } else if (ret.length === 1) {\n return ret[0];\n } else {\n return undefined;\n }\n }\n return undefined;\n }\n\n public NewRecordValues(relatedEntityName: string): Record<string, unknown> {\n const eri = this.GetEntityRelationshipByRelatedEntityName(relatedEntityName);\n if (eri)\n return this.NewRecordValuesByEntityRelationship(eri);\n else\n return {};\n }\n\n public NewRecordValuesByEntityRelationship(item: EntityRelationshipInfo): Record<string, unknown> {\n return EntityInfo.BuildRelationshipNewRecordValues(this.record, item);\n }\n\n public GetRelatedEntityTabDisplayName(relatedEntityName: string): string {\n if (this.record) {\n const eri = (<BaseEntity>this.record).EntityInfo.RelatedEntities.find(x => x.RelatedEntity === relatedEntityName);\n if (eri)\n return eri.DisplayName;\n }\n return relatedEntityName;\n }\n\n public get HasRelatedEntities(): boolean {\n if (this.record) {\n const relatedEntities = (<BaseEntity>this.record).EntityInfo.RelatedEntities;\n return relatedEntities && relatedEntities.length > 0;\n }\n return false;\n }\n\n // #endregion\n\n // #region Entity Info & Dependencies\n\n public get EntityInfo(): EntityInfo | undefined {\n try {\n const r = <BaseEntity>this.record;\n if (r)\n return r.EntityInfo;\n else\n return undefined;\n } catch (e) {\n LogError(e);\n return undefined;\n }\n }\n\n public async ShowDependencies() {\n const md = new Metadata();\n const dep = await md.GetRecordDependencies(this.record.EntityInfo.Name, this.record.PrimaryKey);\n console.log('Dependencies for: ' + this.record.EntityInfo.Name + ' ' + this.record.PrimaryKey.ToString());\n console.log(dep);\n }\n\n public ShowChanges(): void {\n if (this.record) {\n const changes = this.record.GetAll(false, true);\n const oldValues = this.record.GetAll(true, true);\n const message =\n 'Changes for: ' + this.record.EntityInfo.Name + ' ' + this.record.PrimaryKey.ToString() +\n '\\n\\n' + JSON.stringify(changes, null, 2) +\n '\\n\\nOld Values\\n\\n' + JSON.stringify(oldValues, null, 2);\n console.log(message);\n this.Notification.emit({ Message: message, Type: 'info', Duration: 30000 });\n }\n }\n\n public async GetListsCanAddTo(): Promise<MJListEntity[]> {\n if (!this.record) {\n LogError('Unable to fetch List records: Record not found');\n return [];\n }\n\n const rv = new RunView();\n const md = new Metadata();\n\n const rvResult: RunViewResult<MJListEntity> = await rv.RunView({\n EntityName: 'MJ: Lists',\n ExtraFilter: `UserID = '${md.CurrentUser.ID}' AND EntityID = '${this.record.EntityInfo.ID}'`,\n ResultType: 'entity_object'\n });\n\n if (!rvResult.Success) {\n LogError('Error running view to fetch lists', undefined, rvResult.ErrorMessage);\n return [];\n }\n\n return rvResult.Results;\n }\n\n public async GetRecordDependencies(): Promise<RecordDependency[]> {\n const md = new Metadata();\n const dependencies: RecordDependency[] = await md.GetRecordDependencies(this.record.EntityInfo.Name, this.record.PrimaryKey);\n return dependencies;\n }\n\n // #endregion\n\n // #region Collapsible Section Management\n\n protected sections: BaseFormSectionInfo[] = [];\n private sectionMap: Map<string, BaseFormSectionInfo> = new Map();\n\n public searchFilter: string = '';\n public showEmptyFields: boolean = false;\n\n /** Whether to show all validation errors on fields (set after save failure) */\n private _showValidation = false;\n /** Validation errors from the most recent failed save attempt */\n private _validationErrors: ValidationErrorInfo[] = [];\n\n public get formContext(): FormContext {\n return {\n sectionFilter: this.searchFilter,\n showEmptyFields: this.showEmptyFields,\n showValidation: this._showValidation,\n validationErrors: this._validationErrors\n };\n }\n\n /** Clears all validation display state (called on save success, cancel, end edit) */\n private clearValidationState(): void {\n this._showValidation = false;\n this._validationErrors = [];\n }\n\n private filterSubject = new Subject<string>();\n private filterSubscription?: Subscription;\n\n protected initSections(sections: (BaseFormSectionInfo | { sectionKey: string; sectionName: string; isExpanded: boolean; rowCount?: number; metadata?: unknown })[]): void {\n this.sections = sections.map(s =>\n s instanceof BaseFormSectionInfo\n ? s\n : new BaseFormSectionInfo(s.sectionKey, s.sectionName, s.isExpanded, s.rowCount, s.metadata)\n );\n this.sectionMap.clear();\n this.sections.forEach(section => {\n this.sectionMap.set(section.sectionKey, section);\n });\n }\n\n protected getSection(sectionKey: string): BaseFormSectionInfo | undefined {\n return this.sectionMap.get(sectionKey);\n }\n\n public IsSectionExpanded(sectionKey: string, defaultExpanded?: boolean): boolean {\n const entityName = this.getEntityName();\n if (entityName) {\n return this.formStateService.isSectionExpanded(entityName, sectionKey, defaultExpanded);\n }\n const section = this.sectionMap.get(sectionKey);\n return section ? section.isExpanded : (defaultExpanded !== undefined ? defaultExpanded : true);\n }\n\n public SetSectionExpanded(sectionKey: string, isExpanded: boolean): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.setSectionExpanded(entityName, sectionKey, isExpanded);\n }\n const section = this.sectionMap.get(sectionKey);\n if (section) {\n section.isExpanded = isExpanded;\n }\n }\n\n public GetSectionRowCount(sectionKey: string): number | undefined {\n const section = this.sectionMap.get(sectionKey);\n return section?.rowCount;\n }\n\n public SetSectionRowCount(sectionKey: string, rowCount: number): void {\n const section = this.sectionMap.get(sectionKey);\n if (section) {\n section.rowCount = rowCount;\n }\n }\n\n public GetSectionPanelHeight(sectionKey: string): number | undefined {\n const entityName = this.getEntityName();\n if (entityName) {\n return this.formStateService.getSectionPanelHeight(entityName, sectionKey);\n }\n return undefined;\n }\n\n public SetSectionPanelHeight(sectionKey: string, height: number): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.setSectionPanelHeight(entityName, sectionKey, height);\n }\n }\n\n public toggleSection(sectionKey: string): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.toggleSection(entityName, sectionKey);\n }\n const section = this.sectionMap.get(sectionKey);\n if (section) {\n section.isExpanded = !section.isExpanded;\n }\n }\n\n /**\n * Expand any sections that are visible (match the current filter) but currently collapsed.\n * Called after filter changes so the user can immediately see matching content.\n */\n private expandMatchingSections(): void {\n if (!this.collapsiblePanels) return;\n this.collapsiblePanels.forEach(panel => {\n if (panel.IsVisible && !panel.Expanded) {\n this.SetSectionExpanded(panel.SectionKey, true);\n }\n });\n }\n\n public expandAllSections(): void {\n const entityName = this.getEntityName();\n const sectionKeys = this.sections.map(s => s.sectionKey);\n if (entityName && sectionKeys.length > 0) {\n this.formStateService.expandAllSections(entityName, sectionKeys);\n }\n this.sections.forEach(section => {\n section.isExpanded = true;\n });\n }\n\n public collapseAllSections(): void {\n const entityName = this.getEntityName();\n const sectionKeys = this.sections.map(s => s.sectionKey);\n if (entityName && sectionKeys.length > 0) {\n this.formStateService.collapseAllSections(entityName, sectionKeys);\n }\n this.sections.forEach(section => {\n section.isExpanded = false;\n });\n }\n\n public getExpandedCount(): number {\n const entityName = this.getEntityName();\n const sectionKeys = this.sections.map(s => s.sectionKey);\n if (entityName && sectionKeys.length > 0) {\n return this.formStateService.getExpandedCount(entityName, sectionKeys);\n }\n return this.sections.filter(section => section.isExpanded).length;\n }\n\n public getVisibleSectionCount(): number {\n if (!this.collapsiblePanels || this.collapsiblePanels.length === 0) {\n return this.sections.length;\n }\n return this.collapsiblePanels.filter(panel => panel.IsVisible).length;\n }\n\n public getTotalSectionCount(): number {\n return this.sections.length;\n }\n\n public onFilterChange(searchTerm: string): void {\n this.filterSubject.next(searchTerm);\n }\n\n public getEntityName(): string {\n return this.record?.EntityInfo?.Name || '';\n }\n\n public getFormWidthMode(): 'centered' | 'full-width' {\n const entityName = this.getEntityName();\n if (entityName) {\n return this.formStateService.getWidthMode(entityName);\n }\n return 'centered';\n }\n\n public setFormWidthMode(widthMode: 'centered' | 'full-width'): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.setWidthMode(entityName, widthMode);\n }\n }\n\n public toggleFormWidthMode(): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.toggleWidthMode(entityName);\n }\n }\n\n // #endregion\n\n // #region Section Ordering\n\n public getSectionOrder(): string[] {\n const entityName = this.getEntityName();\n if (entityName) {\n const customOrder = this.formStateService.getSectionOrder(entityName);\n if (customOrder && customOrder.length > 0) {\n return customOrder;\n }\n }\n return this.sections.map(s => s.sectionKey);\n }\n\n public setSectionOrder(sectionOrder: string[]): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.setSectionOrder(entityName, sectionOrder);\n }\n }\n\n public resetSectionOrder(): void {\n const entityName = this.getEntityName();\n if (entityName) {\n this.formStateService.resetSectionOrder(entityName);\n }\n }\n\n public hasCustomSectionOrder(): boolean {\n const entityName = this.getEntityName();\n if (entityName) {\n return this.formStateService.hasCustomSectionOrder(entityName);\n }\n return false;\n }\n\n public getSectionDisplayOrder(sectionKey: string): number {\n const order = this.getSectionOrder();\n const index = order.indexOf(sectionKey);\n return index >= 0 ? index : this.sections.length;\n }\n\n // #endregion\n\n // #region Form Container Event Handlers\n\n /**\n * Handles navigation events from the form container and related entity grids.\n * Relays the event upward via the Navigate @Output for the host application to handle.\n * Generated form templates bind this as: (Navigate)=\"OnFormNavigate($event)\"\n */\n public OnFormNavigate(event: FormNavigationEvent): void {\n this.Navigate.emit(event);\n }\n\n /**\n * Handles delete requests from the form container.\n * Emits RecordDeleted on success, RecordDeleteFailed on failure.\n * Generated form templates bind this as: (DeleteRequested)=\"OnDeleteRequested()\"\n */\n public async OnDeleteRequested(): Promise<void> {\n if (!this.record || !this.record.IsSaved) return;\n try {\n const result = await this.record.Delete();\n if (result) {\n this.Notification.emit({ Message: 'Record deleted successfully', Type: 'success', Duration: 2500 });\n this.RecordDeleted.emit({\n EntityName: this.record.EntityInfo.Name,\n RecordId: this.record.PrimaryKey.ToString()\n });\n } else {\n const errorMsg = 'Error deleting record';\n this.Notification.emit({ Message: errorMsg, Type: 'error', Duration: 5000 });\n this.RecordDeleteFailed.emit({ EntityName: this.record.EntityInfo.Name, ErrorMessage: errorMsg });\n }\n } catch (e) {\n const errorMsg = 'Error deleting record: ' + e;\n this.Notification.emit({ Message: errorMsg, Type: 'error', Duration: 5000 });\n this.RecordDeleteFailed.emit({ EntityName: this.record.EntityInfo.Name, ErrorMessage: errorMsg });\n }\n }\n\n /**\n * Handles favorite toggle from the form container.\n * Generated form templates bind this as: (FavoriteToggled)=\"OnFavoriteToggled()\"\n */\n public async OnFavoriteToggled(): Promise<void> {\n await this.SetFavoriteStatus(!this.IsFavorite);\n }\n\n /**\n * Handles history view requests from the form container.\n * Generated form templates bind this as: (HistoryRequested)=\"OnHistoryRequested()\"\n */\n public OnHistoryRequested(): void {\n this.handleHistoryDialog();\n }\n\n /**\n * Handles list management requests from the form container.\n * Generated form templates bind this as: (ListManagementRequested)=\"OnListManagementRequested()\"\n */\n public OnListManagementRequested(): void {\n // List management dialog is handled by the host application\n // Subclasses can override this to implement custom list management\n }\n\n // #endregion\n}\n"]}
@@ -170,7 +170,7 @@ function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_3_Template
170
170
  function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_4_Case_0_Template(rf, ctx) { if (rf & 1) {
171
171
  const _r10 = i0.ɵɵgetCurrentView();
172
172
  i0.ɵɵelementStart(0, "input", 33);
173
- i0.ɵɵlistener("change", function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_4_Case_0_Template_input_change_0_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.OnInputChange($event)); });
173
+ i0.ɵɵlistener("input", function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_4_Case_0_Template_input_input_0_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.OnInputChange($event)); });
174
174
  i0.ɵɵelementEnd();
175
175
  } if (rf & 2) {
176
176
  const ctx_r0 = i0.ɵɵnextContext(4);
@@ -179,7 +179,7 @@ function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_4_Case_0_T
179
179
  function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_4_Case_1_Template(rf, ctx) { if (rf & 1) {
180
180
  const _r11 = i0.ɵɵgetCurrentView();
181
181
  i0.ɵɵelementStart(0, "textarea", 34);
182
- i0.ɵɵlistener("change", function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_4_Case_1_Template_textarea_change_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.OnInputChange($event)); });
182
+ i0.ɵɵlistener("input", function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_4_Case_1_Template_textarea_input_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.OnInputChange($event)); });
183
183
  i0.ɵɵelementEnd();
184
184
  } if (rf & 2) {
185
185
  const ctx_r0 = i0.ɵɵnextContext(4);
@@ -297,7 +297,7 @@ function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_4_Case_6_T
297
297
  } }
298
298
  function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_4_Case_7_Template(rf, ctx) { if (rf & 1) {
299
299
  const _r21 = i0.ɵɵgetCurrentView();
300
- i0.ɵɵelementStart(0, "input", 33);
300
+ i0.ɵɵelementStart(0, "input", 43);
301
301
  i0.ɵɵlistener("change", function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_4_Case_7_Template_input_change_0_listener($event) { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.OnInputChange($event)); });
302
302
  i0.ɵɵelementEnd();
303
303
  } if (rf & 2) {
@@ -312,8 +312,8 @@ function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_4_Template
312
312
  i0.ɵɵconditional((tmp_3_0 = ctx_r0.Type) === "textbox" ? 0 : tmp_3_0 === "textarea" ? 1 : tmp_3_0 === "number" ? 2 : tmp_3_0 === "datepicker" ? 3 : tmp_3_0 === "checkbox" ? 4 : tmp_3_0 === "select" ? 5 : tmp_3_0 === "autocomplete" ? 6 : 7);
313
313
  } }
314
314
  function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
315
- i0.ɵɵelementStart(0, "div", 43);
316
- i0.ɵɵelement(1, "i", 44);
315
+ i0.ɵɵelementStart(0, "div", 44);
316
+ i0.ɵɵelement(1, "i", 45);
317
317
  i0.ɵɵelementStart(2, "span");
318
318
  i0.ɵɵtext(3);
319
319
  i0.ɵɵelementEnd()();
@@ -324,7 +324,7 @@ function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_5_For_2_Te
324
324
  } }
325
325
  function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
326
326
  i0.ɵɵelementStart(0, "div", 17);
327
- i0.ɵɵrepeaterCreate(1, MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_5_For_2_Template, 4, 1, "div", 43, _forTrack1);
327
+ i0.ɵɵrepeaterCreate(1, MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_5_For_2_Template, 4, 1, "div", 44, _forTrack1);
328
328
  i0.ɵɵelementEnd();
329
329
  } if (rf & 2) {
330
330
  const ctx_r0 = i0.ɵɵnextContext(3);
@@ -332,8 +332,8 @@ function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_5_Template
332
332
  i0.ɵɵrepeater(ctx_r0.DisplayErrors);
333
333
  } }
334
334
  function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_6_For_2_Template(rf, ctx) { if (rf & 1) {
335
- i0.ɵɵelementStart(0, "div", 43);
336
- i0.ɵɵelement(1, "i", 45);
335
+ i0.ɵɵelementStart(0, "div", 44);
336
+ i0.ɵɵelement(1, "i", 46);
337
337
  i0.ɵɵelementStart(2, "span");
338
338
  i0.ɵɵtext(3);
339
339
  i0.ɵɵelementEnd()();
@@ -344,7 +344,7 @@ function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_6_For_2_Te
344
344
  } }
345
345
  function MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
346
346
  i0.ɵɵelementStart(0, "div", 18);
347
- i0.ɵɵrepeaterCreate(1, MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_6_For_2_Template, 4, 1, "div", 43, _forTrack1);
347
+ i0.ɵɵrepeaterCreate(1, MjFormFieldComponent_Conditional_0_Conditional_1_Conditional_6_For_2_Template, 4, 1, "div", 44, _forTrack1);
348
348
  i0.ɵɵelementEnd();
349
349
  } if (rf & 2) {
350
350
  const ctx_r0 = i0.ɵɵnextContext(3);
@@ -1150,7 +1150,7 @@ export class MjFormFieldComponent {
1150
1150
  return date.toISOString().split('T')[0];
1151
1151
  }
1152
1152
  static ɵfac = function MjFormFieldComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MjFormFieldComponent)(); };
1153
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MjFormFieldComponent, selectors: [["mj-form-field"]], inputs: { Record: "Record", EditMode: "EditMode", FieldName: "FieldName", Type: "Type", LinkType: "LinkType", ShowLabel: "ShowLabel", FormContext: "FormContext", _deprecatedRecord: [0, "record", "_deprecatedRecord"], _deprecatedFormContext: [0, "formContext", "_deprecatedFormContext"], HideWhenEmptyInReadOnlyMode: "HideWhenEmptyInReadOnlyMode", DisplayNameOverride: "DisplayNameOverride", PossibleValuesOverride: "PossibleValuesOverride" }, outputs: { ValueChange: "ValueChange", Navigate: "Navigate" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 1, vars: 1, consts: [[1, "mj-forms-field", 3, "mj-forms-field--readonly", "mj-forms-field--dirty"], [1, "mj-forms-field", "mj-forms-field--editing", 3, "mj-forms-field--dirty", "mj-forms-field--required-empty", "mj-forms-field--has-error", "mj-forms-field--has-warning"], [1, "mj-forms-field"], [1, "mj-forms-field-label", 3, "innerHTML"], [1, "mj-forms-field-control"], [1, "mj-forms-field-value"], ["title", "View related record", 1, "mj-forms-field-link", "mj-forms-field-link--fk", 3, "click"], ["title", "Send email", 1, "mj-forms-field-link", 3, "click"], [1, "fa-solid", "fa-envelope", "mj-forms-field-link-icon"], ["title", "Open link", 1, "mj-forms-field-link", 3, "click"], [1, "fa-solid", "fa-arrow-up-right-from-square", "mj-forms-field-link-icon"], ["title", "View related record", 1, "mj-forms-field-link", 3, "click"], [1, "mj-forms-field-value", "mj-forms-field-value--long"], [1, "mj-forms-field-checkbox"], ["type", "checkbox", "disabled", "", 3, "checked"], [1, "mj-forms-field", "mj-forms-field--editing"], [1, "mj-fk-search", 3, "mj-fk-search--matched"], [1, "mj-forms-field-validation", "mj-forms-field-validation--error"], [1, "mj-forms-field-validation", "mj-forms-field-validation--warning"], [1, "mj-fk-search"], ["type", "text", "placeholder", "Search...", 1, "mj-forms-field-input", 3, "input", "focus", "blur", "value"], ["title", "Clear", 1, "mj-fk-clear"], [1, "fa-solid", "fa-magnifying-glass", "mj-fk-search-icon"], [1, "mj-fk-dropdown", 3, "ngStyle", "mj-fk-dropdown--above"], ["title", "Clear", 1, "mj-fk-clear", 3, "mousedown"], [1, "fa-solid", "fa-xmark"], [1, "mj-fk-dropdown", 3, "ngStyle"], [1, "mj-fk-option"], [1, "mj-fk-option", 3, "mousedown"], ["type", "text", 1, "mj-forms-field-input", 3, "value"], [1, "mj-forms-field-input", "mj-forms-field-input--textarea", 3, "value"], ["type", "number", 1, "mj-forms-field-input", "mj-forms-field-input--number", 3, "value"], ["type", "date", 1, "mj-forms-field-input", "mj-forms-field-input--date", 3, "value"], ["type", "text", 1, "mj-forms-field-input", 3, "change", "value"], [1, "mj-forms-field-input", "mj-forms-field-input--textarea", 3, "change", "value"], ["type", "number", 1, "mj-forms-field-input", "mj-forms-field-input--number", 3, "change", "value"], ["type", "date", 1, "mj-forms-field-input", "mj-forms-field-input--date", 3, "change", "value"], ["type", "checkbox", 3, "change", "checked"], ["tabindex", "0", 1, "mj-custom-select-trigger", 3, "click", "blur"], [1, "mj-custom-select-value"], [1, "fa-solid", "fa-chevron-down", "mj-custom-select-chevron"], [1, "mj-fk-option", 3, "mj-fk-option--selected"], ["type", "text", "placeholder", "Type to search...", 1, "mj-forms-field-input", 3, "input", "focus", "blur", "value"], [1, "mj-forms-field-validation-item"], [1, "fa-solid", "fa-circle-exclamation"], [1, "fa-solid", "fa-triangle-exclamation"]], template: function MjFormFieldComponent_Template(rf, ctx) { if (rf & 1) {
1153
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MjFormFieldComponent, selectors: [["mj-form-field"]], inputs: { Record: "Record", EditMode: "EditMode", FieldName: "FieldName", Type: "Type", LinkType: "LinkType", ShowLabel: "ShowLabel", FormContext: "FormContext", _deprecatedRecord: [0, "record", "_deprecatedRecord"], _deprecatedFormContext: [0, "formContext", "_deprecatedFormContext"], HideWhenEmptyInReadOnlyMode: "HideWhenEmptyInReadOnlyMode", DisplayNameOverride: "DisplayNameOverride", PossibleValuesOverride: "PossibleValuesOverride" }, outputs: { ValueChange: "ValueChange", Navigate: "Navigate" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 1, vars: 1, consts: [[1, "mj-forms-field", 3, "mj-forms-field--readonly", "mj-forms-field--dirty"], [1, "mj-forms-field", "mj-forms-field--editing", 3, "mj-forms-field--dirty", "mj-forms-field--required-empty", "mj-forms-field--has-error", "mj-forms-field--has-warning"], [1, "mj-forms-field"], [1, "mj-forms-field-label", 3, "innerHTML"], [1, "mj-forms-field-control"], [1, "mj-forms-field-value"], ["title", "View related record", 1, "mj-forms-field-link", "mj-forms-field-link--fk", 3, "click"], ["title", "Send email", 1, "mj-forms-field-link", 3, "click"], [1, "fa-solid", "fa-envelope", "mj-forms-field-link-icon"], ["title", "Open link", 1, "mj-forms-field-link", 3, "click"], [1, "fa-solid", "fa-arrow-up-right-from-square", "mj-forms-field-link-icon"], ["title", "View related record", 1, "mj-forms-field-link", 3, "click"], [1, "mj-forms-field-value", "mj-forms-field-value--long"], [1, "mj-forms-field-checkbox"], ["type", "checkbox", "disabled", "", 3, "checked"], [1, "mj-forms-field", "mj-forms-field--editing"], [1, "mj-fk-search", 3, "mj-fk-search--matched"], [1, "mj-forms-field-validation", "mj-forms-field-validation--error"], [1, "mj-forms-field-validation", "mj-forms-field-validation--warning"], [1, "mj-fk-search"], ["type", "text", "placeholder", "Search...", 1, "mj-forms-field-input", 3, "input", "focus", "blur", "value"], ["title", "Clear", 1, "mj-fk-clear"], [1, "fa-solid", "fa-magnifying-glass", "mj-fk-search-icon"], [1, "mj-fk-dropdown", 3, "ngStyle", "mj-fk-dropdown--above"], ["title", "Clear", 1, "mj-fk-clear", 3, "mousedown"], [1, "fa-solid", "fa-xmark"], [1, "mj-fk-dropdown", 3, "ngStyle"], [1, "mj-fk-option"], [1, "mj-fk-option", 3, "mousedown"], ["type", "text", 1, "mj-forms-field-input", 3, "value"], [1, "mj-forms-field-input", "mj-forms-field-input--textarea", 3, "value"], ["type", "number", 1, "mj-forms-field-input", "mj-forms-field-input--number", 3, "value"], ["type", "date", 1, "mj-forms-field-input", "mj-forms-field-input--date", 3, "value"], ["type", "text", 1, "mj-forms-field-input", 3, "input", "value"], [1, "mj-forms-field-input", "mj-forms-field-input--textarea", 3, "input", "value"], ["type", "number", 1, "mj-forms-field-input", "mj-forms-field-input--number", 3, "change", "value"], ["type", "date", 1, "mj-forms-field-input", "mj-forms-field-input--date", 3, "change", "value"], ["type", "checkbox", 3, "change", "checked"], ["tabindex", "0", 1, "mj-custom-select-trigger", 3, "click", "blur"], [1, "mj-custom-select-value"], [1, "fa-solid", "fa-chevron-down", "mj-custom-select-chevron"], [1, "mj-fk-option", 3, "mj-fk-option--selected"], ["type", "text", "placeholder", "Type to search...", 1, "mj-forms-field-input", 3, "input", "focus", "blur", "value"], ["type", "text", 1, "mj-forms-field-input", 3, "change", "value"], [1, "mj-forms-field-validation-item"], [1, "fa-solid", "fa-circle-exclamation"], [1, "fa-solid", "fa-triangle-exclamation"]], template: function MjFormFieldComponent_Template(rf, ctx) { if (rf & 1) {
1154
1154
  i0.ɵɵconditionalCreate(0, MjFormFieldComponent_Conditional_0_Template, 2, 2);
1155
1155
  } if (rf & 2) {
1156
1156
  i0.ɵɵconditional(ctx.Record && (ctx.Record.IsSaved || !ctx.IsFieldReadOnly) ? 0 : -1);
@@ -1158,7 +1158,7 @@ export class MjFormFieldComponent {
1158
1158
  }
1159
1159
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MjFormFieldComponent, [{
1160
1160
  type: Component,
1161
- args: [{ standalone: false, selector: 'mj-form-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (Record && (Record.IsSaved || !IsFieldReadOnly)) {\n <!-- READ-ONLY MODE -->\n @if ((!EditMode || IsFieldReadOnly) && !ShouldHideField) {\n <div class=\"mj-forms-field\" [class.mj-forms-field--readonly]=\"EditMode && IsFieldReadOnly\" [class.mj-forms-field--dirty]=\"IsDirty\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- FK fields with a mapped name field: show the name as a hyperlink -->\n @if (IsFKWithNameField) {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link mj-forms-field-link--fk\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FKDisplayName }}\n </a>\n </span>\n }\n @else {\n @switch (LinkType) {\n @case ('Email') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnEmailLinkClick($event)\" title=\"Send email\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-envelope mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('URL') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnUrlLinkClick($event)\" title=\"Open link\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('Record') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @default {\n @if (Type === 'checkbox') {\n <span class=\"mj-forms-field-value\">\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\" [checked]=\"!!Value\" disabled>\n </div>\n </span>\n }\n @else if (IsLongText) {\n <span class=\"mj-forms-field-value mj-forms-field-value--long\">{{ FormatValue() }}</span>\n }\n @else {\n <span class=\"mj-forms-field-value\">{{ FormatValue() }}</span>\n }\n }\n }\n }\n </div>\n </div>\n }\n\n <!-- EDIT MODE -->\n @if (EditMode && !IsFieldReadOnly) {\n <div class=\"mj-forms-field mj-forms-field--editing\" [class.mj-forms-field--dirty]=\"IsDirty\" [class.mj-forms-field--required-empty]=\"IsRequiredEmpty\" [class.mj-forms-field--has-error]=\"ShowErrors\" [class.mj-forms-field--has-warning]=\"ShowWarnings\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- Foreign Key fields get custom search autocomplete -->\n @if (HasRelatedEntity) {\n <div class=\"mj-fk-search\" [class.mj-fk-search--matched]=\"FKIsMatched\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FKSearchText\"\n (input)=\"OnFKInput($event)\"\n (focus)=\"OnFKFocus($event)\"\n (blur)=\"OnFKBlur()\"\n placeholder=\"Search...\">\n @if (FKSearchText) {\n <button class=\"mj-fk-clear\" (mousedown)=\"OnFKClearClick($event)\" title=\"Clear\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n } @else {\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n }\n @if (ShowFKDropdown && FKSuggestions.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (suggestion of FKSuggestions; track suggestion.PrimaryKeyValue) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnFKSelectItem(suggestion, $event)\">\n {{ suggestion.DisplayName }}\n </div>\n }\n </div>\n }\n </div>\n }\n @else {\n @switch (Type) {\n @case ('textbox') {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (change)=\"OnInputChange($event)\">\n }\n @case ('textarea') {\n <textarea\n class=\"mj-forms-field-input mj-forms-field-input--textarea\"\n [value]=\"FormatValue()\"\n (change)=\"OnInputChange($event)\"></textarea>\n }\n @case ('number') {\n <input type=\"number\"\n class=\"mj-forms-field-input mj-forms-field-input--number\"\n [value]=\"Value\"\n (change)=\"OnNumberChange($event)\">\n }\n @case ('datepicker') {\n <input type=\"date\"\n class=\"mj-forms-field-input mj-forms-field-input--date\"\n [value]=\"DateInputValue\"\n (change)=\"OnDateChange($event)\">\n }\n @case ('checkbox') {\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\"\n [checked]=\"!!Value\"\n (change)=\"OnCheckboxChange($event)\">\n </div>\n }\n @case ('select') {\n <div class=\"mj-custom-select-trigger\"\n tabindex=\"0\"\n (click)=\"OnSelectTriggerClick($event)\"\n (blur)=\"OnSelectTriggerBlur()\">\n <span class=\"mj-custom-select-value\" [class.mj-custom-select-value--placeholder]=\"!FormatValue()\">\n {{ FormatValue() || '-- Select --' }}\n </span>\n <i class=\"fa-solid fa-chevron-down mj-custom-select-chevron\" [class.mj-custom-select-chevron--open]=\"ShowSelectDropdown\"></i>\n </div>\n @if (ShowSelectDropdown && PossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of PossibleValues; track option) {\n <div class=\"mj-fk-option\" [class.mj-fk-option--selected]=\"FormatValue() === option\" (mousedown)=\"OnSelectOptionClick(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n }\n @case ('autocomplete') {\n <div class=\"mj-fk-search\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (input)=\"OnValueListInput($event)\"\n (focus)=\"OnValueListFocus($event)\"\n (blur)=\"OnValueListBlur()\"\n placeholder=\"Type to search...\">\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n @if (ShowValueListDropdown && FilteredPossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of FilteredPossibleValues; track option) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnValueListSelect(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n </div>\n }\n @default {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (change)=\"OnInputChange($event)\">\n }\n }\n }\n </div>\n <!-- Inline validation messages -->\n @if (DisplayErrors.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--error\">\n @for (error of DisplayErrors; track error.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n <span>{{ error.Message }}</span>\n </div>\n }\n </div>\n }\n @if (DisplayWarnings.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--warning\">\n @for (warning of DisplayWarnings; track warning.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>{{ warning.Message }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n}\n", styles: ["/* ============================================\n FORM FIELD - Shared styles for read and edit\n ============================================ */\n:host {\n --mj-accent: #667eea;\n --mj-accent-light: rgba(102, 126, 234, 0.08);\n --mj-text-primary: #1f2937;\n --mj-text-secondary: #4b5563;\n --mj-text-muted: #9ca3af;\n --mj-border: #e5e7eb;\n --mj-error: #ef4444;\n --mj-warning: #f59e0b;\n --mj-card-bg: #ffffff;\n --mj-forms-field-label-width: 200px;\n --mj-forms-field-gap: 12px;\n --mj-transition: 200ms;\n\n display: contents;\n}\n\n.mj-forms-field {\n display: grid;\n grid-template-columns: var(--mj-forms-field-label-width) 1fr;\n gap: var(--mj-forms-field-gap);\n align-items: baseline;\n padding: 8px 0;\n transition: all var(--mj-transition) ease;\n}\n\n/* Subtle row hover in edit mode */\n.mj-forms-field--editing:hover {\n background: var(--mj-accent-light);\n border-radius: 6px;\n margin: 0 -8px;\n padding: 8px 8px;\n}\n\n/* ============================================\n LABEL\n ============================================ */\n.mj-forms-field-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n padding-top: 2px;\n word-break: break-word;\n}\n\n/* ============================================\n FIELD CONTROL WRAPPER (value + dirty dot)\n ============================================ */\n.mj-forms-field-control {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n}\n\n.mj-forms-field-control > * {\n flex: 1;\n min-width: 0;\n}\n\n/* ============================================\n DIRTY INDICATOR (solid amber dot after label)\n ============================================ */\n.mj-forms-field--dirty .mj-forms-field-label::after {\n content: '';\n display: inline-block;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--mj-warning);\n margin-left: 6px;\n vertical-align: middle;\n}\n\n/* ============================================\n REQUIRED FIELD - red underline when empty\n ============================================ */\n.mj-forms-field--required-empty .mj-forms-field-input {\n border-bottom-color: var(--mj-error);\n}\n\n.mj-forms-field--required-empty .mj-forms-field-input:focus {\n background: #fef2f2;\n border-bottom-color: var(--mj-error);\n}\n\n.mj-forms-field--required-empty .mj-custom-select-trigger {\n border-bottom-color: var(--mj-error);\n}\n\n.mj-forms-field--required-empty .mj-fk-search .mj-forms-field-input {\n border-bottom-color: var(--mj-error);\n}\n\n/* ============================================\n READ-ONLY VALUE\n ============================================ */\n.mj-forms-field-value {\n font-size: 14px;\n color: var(--mj-text-primary);\n min-height: 24px;\n display: flex;\n align-items: center;\n overflow-wrap: break-word;\n word-break: break-word;\n}\n\n.mj-forms-field-value--long {\n white-space: pre-line;\n max-height: 300px;\n overflow: auto;\n}\n\n/* Read-only fields in edit mode */\n.mj-forms-field--readonly {\n opacity: 0.7;\n}\n\n.mj-forms-field--readonly .mj-forms-field-value {\n color: var(--mj-text-secondary);\n}\n\n/* ============================================\n LINKS (FK, email, URL)\n ============================================ */\n.mj-forms-field-link {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-accent);\n cursor: pointer;\n font-weight: 500;\n transition: color var(--mj-transition);\n text-decoration: none;\n}\n\n.mj-forms-field-link:hover {\n color: #5a6fd6;\n}\n\n.mj-forms-field-link-icon {\n font-size: 11px;\n opacity: 0;\n transition: opacity var(--mj-transition);\n}\n\n.mj-forms-field-link:hover .mj-forms-field-link-icon {\n opacity: 1;\n}\n\n/* FK fields showing entity name instead of raw ID */\n.mj-forms-field-link--fk {\n font-size: 14px;\n font-weight: 400;\n}\n\n/* ============================================\n EDIT MODE INPUTS - Clean underline style\n ============================================ */\n.mj-forms-field-input {\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: transparent;\n border: none;\n border-bottom: 1.5px solid var(--mj-border);\n padding: 4px 0;\n width: 100%;\n outline: none;\n transition: border-color var(--mj-transition) ease,\n background var(--mj-transition) ease;\n}\n\n.mj-forms-field-input:focus {\n border-bottom-color: var(--mj-accent);\n background: var(--mj-accent-light);\n border-radius: 4px 4px 0 0;\n padding: 4px 6px;\n}\n\n.mj-forms-field-input::placeholder {\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n/* Textarea variant */\n.mj-forms-field-input--textarea {\n resize: vertical;\n min-height: 60px;\n border: 1.5px solid var(--mj-border);\n border-radius: 6px;\n padding: 8px 10px;\n background: white;\n font-family: inherit;\n}\n\n.mj-forms-field-input--textarea:focus {\n border-color: var(--mj-accent);\n box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);\n background: white;\n padding: 8px 10px;\n border-radius: 6px;\n}\n\n/* Number input - narrower */\n.mj-forms-field-input--number {\n max-width: 200px;\n}\n\n/* Date input - narrower */\n.mj-forms-field-input--date {\n max-width: 220px;\n}\n\n/* ============================================\n CHECKBOX (custom styled)\n ============================================ */\n.mj-forms-field-checkbox {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.mj-forms-field-checkbox input[type=\"checkbox\"] {\n appearance: none;\n width: 18px;\n height: 18px;\n border: 2px solid var(--mj-border);\n border-radius: 4px;\n cursor: pointer;\n position: relative;\n transition: all var(--mj-transition) ease;\n flex-shrink: 0;\n}\n\n.mj-forms-field-checkbox input[type=\"checkbox\"]:checked {\n background: var(--mj-accent);\n border-color: var(--mj-accent);\n}\n\n.mj-forms-field-checkbox input[type=\"checkbox\"]:checked::after {\n content: '';\n position: absolute;\n left: 5px;\n top: 1px;\n width: 5px;\n height: 9px;\n border: solid white;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n}\n\n.mj-forms-field-checkbox input[type=\"checkbox\"]:disabled {\n opacity: 0.5;\n cursor: default;\n}\n\n/* ============================================\n CUSTOM SELECT DROPDOWN (replaces native <select>)\n ============================================ */\n.mj-custom-select-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: transparent;\n border: none;\n border-bottom: 1.5px solid var(--mj-border);\n padding: 4px 0;\n width: 100%;\n cursor: pointer;\n outline: none;\n transition: border-color var(--mj-transition) ease,\n background var(--mj-transition) ease;\n}\n\n.mj-custom-select-trigger:focus {\n border-bottom-color: var(--mj-accent);\n background: var(--mj-accent-light);\n border-radius: 4px 4px 0 0;\n padding: 4px 6px;\n}\n\n.mj-custom-select-value {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mj-custom-select-value--placeholder {\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n.mj-custom-select-chevron {\n font-size: 11px;\n color: var(--mj-text-muted);\n transition: transform var(--mj-transition) ease;\n flex-shrink: 0;\n margin-left: 8px;\n}\n\n.mj-custom-select-chevron--open {\n transform: rotate(180deg);\n}\n\n/* ============================================\n FK SEARCH (custom autocomplete)\n ============================================ */\n.mj-fk-search {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n}\n\n.mj-fk-search .mj-forms-field-input {\n padding-right: 28px;\n}\n\n.mj-fk-search-icon {\n position: absolute;\n right: 4px;\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n}\n\n.mj-fk-clear {\n position: absolute;\n right: 2px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 11px;\n padding: 4px 6px;\n line-height: 1;\n border-radius: 3px;\n transition: all var(--mj-transition);\n}\n\n.mj-fk-clear:hover {\n color: var(--mj-error);\n background: rgba(239, 68, 68, 0.08);\n}\n\n/* Matched state: solid accent underline */\n.mj-fk-search--matched .mj-forms-field-input {\n border-bottom: 2px solid var(--mj-accent);\n}\n\n/* ============================================\n FLOATING DROPDOWN PANEL (position: fixed via ngStyle)\n ============================================ */\n.mj-fk-dropdown {\n background: var(--mj-card-bg);\n border: 1px solid var(--mj-border);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n max-height: 240px;\n overflow-y: auto;\n padding: 4px;\n animation: mj-dropdown-in 150ms ease;\n}\n\n.mj-fk-dropdown--above {\n animation: mj-dropdown-in-above 150ms ease;\n}\n\n.mj-fk-option {\n padding: 10px 14px;\n font-size: 14px;\n color: var(--mj-text-primary);\n cursor: pointer;\n transition: background var(--mj-transition);\n border-radius: 6px;\n}\n\n.mj-fk-option:hover {\n background: var(--mj-accent-light);\n}\n\n.mj-fk-option--selected {\n background: var(--mj-accent-light);\n font-weight: 600;\n color: var(--mj-accent);\n}\n\n.mj-fk-option--selected:hover {\n background: rgba(102, 126, 234, 0.15);\n}\n\n@keyframes mj-dropdown-in {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n@keyframes mj-dropdown-in-above {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* ============================================\n SEARCH HIGHLIGHTING\n ============================================ */\n.mj-forms-field-label :global(.mj-forms-search-highlight) {\n background-color: #fef08a;\n color: #854d0e;\n padding: 0;\n border-radius: 2px;\n font-weight: 700;\n box-shadow: 0 0 0 2px #fef08a;\n}\n\n/* ============================================\n VALIDATION ERROR STATE\n ============================================ */\n.mj-forms-field--has-error .mj-forms-field-input {\n border-bottom-color: var(--mj-error);\n border-bottom-width: 2px;\n}\n\n.mj-forms-field--has-error .mj-forms-field-input:focus {\n background: #fef2f2;\n border-bottom-color: var(--mj-error);\n}\n\n.mj-forms-field--has-error .mj-forms-field-input--textarea {\n border-color: var(--mj-error);\n}\n\n.mj-forms-field--has-error .mj-forms-field-input--textarea:focus {\n border-color: var(--mj-error);\n box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.08);\n}\n\n.mj-forms-field--has-error .mj-custom-select-trigger {\n border-bottom-color: var(--mj-error);\n border-bottom-width: 2px;\n}\n\n.mj-forms-field--has-error .mj-fk-search .mj-forms-field-input {\n border-bottom-color: var(--mj-error);\n border-bottom-width: 2px;\n}\n\n/* ============================================\n VALIDATION WARNING STATE\n ============================================ */\n.mj-forms-field--has-warning .mj-forms-field-input {\n border-bottom-color: var(--mj-warning);\n border-bottom-width: 2px;\n}\n\n.mj-forms-field--has-warning .mj-forms-field-input:focus {\n background: #fffbeb;\n border-bottom-color: var(--mj-warning);\n}\n\n.mj-forms-field--has-warning .mj-forms-field-input--textarea {\n border-color: var(--mj-warning);\n}\n\n.mj-forms-field--has-warning .mj-forms-field-input--textarea:focus {\n border-color: var(--mj-warning);\n box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.08);\n}\n\n.mj-forms-field--has-warning .mj-custom-select-trigger {\n border-bottom-color: var(--mj-warning);\n border-bottom-width: 2px;\n}\n\n.mj-forms-field--has-warning .mj-fk-search .mj-forms-field-input {\n border-bottom-color: var(--mj-warning);\n border-bottom-width: 2px;\n}\n\n/* ============================================\n VALIDATION MESSAGE AREA\n ============================================ */\n.mj-forms-field-validation {\n grid-column: 2;\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin-top: -2px;\n overflow: hidden;\n animation: mj-validation-slide-in 200ms ease-out;\n}\n\n.mj-forms-field-validation-item {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n font-size: 12px;\n line-height: 1.4;\n padding: 3px 0 1px;\n}\n\n.mj-forms-field-validation-item i {\n font-size: 11px;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Error message colors */\n.mj-forms-field-validation--error .mj-forms-field-validation-item {\n color: var(--mj-error);\n}\n\n.mj-forms-field-validation--error .mj-forms-field-validation-item i {\n color: var(--mj-error);\n}\n\n/* Warning message colors */\n.mj-forms-field-validation--warning .mj-forms-field-validation-item {\n color: #b45309;\n}\n\n.mj-forms-field-validation--warning .mj-forms-field-validation-item i {\n color: var(--mj-warning);\n}\n\n@keyframes mj-validation-slide-in {\n from {\n opacity: 0;\n max-height: 0;\n transform: translateY(-4px);\n }\n to {\n opacity: 1;\n max-height: 100px;\n transform: translateY(0);\n }\n}\n\n/* ============================================\n RESPONSIVE\n ============================================ */\n@media (max-width: 640px) {\n .mj-forms-field {\n grid-template-columns: 1fr;\n gap: 4px;\n }\n\n .mj-forms-field-label {\n font-size: 12px;\n }\n\n .mj-forms-field-validation {\n grid-column: 1;\n }\n}\n"] }]
1161
+ args: [{ standalone: false, selector: 'mj-form-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (Record && (Record.IsSaved || !IsFieldReadOnly)) {\n <!-- READ-ONLY MODE -->\n @if ((!EditMode || IsFieldReadOnly) && !ShouldHideField) {\n <div class=\"mj-forms-field\" [class.mj-forms-field--readonly]=\"EditMode && IsFieldReadOnly\" [class.mj-forms-field--dirty]=\"IsDirty\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- FK fields with a mapped name field: show the name as a hyperlink -->\n @if (IsFKWithNameField) {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link mj-forms-field-link--fk\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FKDisplayName }}\n </a>\n </span>\n }\n @else {\n @switch (LinkType) {\n @case ('Email') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnEmailLinkClick($event)\" title=\"Send email\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-envelope mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('URL') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnUrlLinkClick($event)\" title=\"Open link\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('Record') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @default {\n @if (Type === 'checkbox') {\n <span class=\"mj-forms-field-value\">\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\" [checked]=\"!!Value\" disabled>\n </div>\n </span>\n }\n @else if (IsLongText) {\n <span class=\"mj-forms-field-value mj-forms-field-value--long\">{{ FormatValue() }}</span>\n }\n @else {\n <span class=\"mj-forms-field-value\">{{ FormatValue() }}</span>\n }\n }\n }\n }\n </div>\n </div>\n }\n\n <!-- EDIT MODE -->\n @if (EditMode && !IsFieldReadOnly) {\n <div class=\"mj-forms-field mj-forms-field--editing\" [class.mj-forms-field--dirty]=\"IsDirty\" [class.mj-forms-field--required-empty]=\"IsRequiredEmpty\" [class.mj-forms-field--has-error]=\"ShowErrors\" [class.mj-forms-field--has-warning]=\"ShowWarnings\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- Foreign Key fields get custom search autocomplete -->\n @if (HasRelatedEntity) {\n <div class=\"mj-fk-search\" [class.mj-fk-search--matched]=\"FKIsMatched\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FKSearchText\"\n (input)=\"OnFKInput($event)\"\n (focus)=\"OnFKFocus($event)\"\n (blur)=\"OnFKBlur()\"\n placeholder=\"Search...\">\n @if (FKSearchText) {\n <button class=\"mj-fk-clear\" (mousedown)=\"OnFKClearClick($event)\" title=\"Clear\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n } @else {\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n }\n @if (ShowFKDropdown && FKSuggestions.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (suggestion of FKSuggestions; track suggestion.PrimaryKeyValue) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnFKSelectItem(suggestion, $event)\">\n {{ suggestion.DisplayName }}\n </div>\n }\n </div>\n }\n </div>\n }\n @else {\n @switch (Type) {\n @case ('textbox') {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (input)=\"OnInputChange($event)\">\n }\n @case ('textarea') {\n <textarea\n class=\"mj-forms-field-input mj-forms-field-input--textarea\"\n [value]=\"FormatValue()\"\n (input)=\"OnInputChange($event)\"></textarea>\n }\n @case ('number') {\n <input type=\"number\"\n class=\"mj-forms-field-input mj-forms-field-input--number\"\n [value]=\"Value\"\n (change)=\"OnNumberChange($event)\">\n }\n @case ('datepicker') {\n <input type=\"date\"\n class=\"mj-forms-field-input mj-forms-field-input--date\"\n [value]=\"DateInputValue\"\n (change)=\"OnDateChange($event)\">\n }\n @case ('checkbox') {\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\"\n [checked]=\"!!Value\"\n (change)=\"OnCheckboxChange($event)\">\n </div>\n }\n @case ('select') {\n <div class=\"mj-custom-select-trigger\"\n tabindex=\"0\"\n (click)=\"OnSelectTriggerClick($event)\"\n (blur)=\"OnSelectTriggerBlur()\">\n <span class=\"mj-custom-select-value\" [class.mj-custom-select-value--placeholder]=\"!FormatValue()\">\n {{ FormatValue() || '-- Select --' }}\n </span>\n <i class=\"fa-solid fa-chevron-down mj-custom-select-chevron\" [class.mj-custom-select-chevron--open]=\"ShowSelectDropdown\"></i>\n </div>\n @if (ShowSelectDropdown && PossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of PossibleValues; track option) {\n <div class=\"mj-fk-option\" [class.mj-fk-option--selected]=\"FormatValue() === option\" (mousedown)=\"OnSelectOptionClick(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n }\n @case ('autocomplete') {\n <div class=\"mj-fk-search\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (input)=\"OnValueListInput($event)\"\n (focus)=\"OnValueListFocus($event)\"\n (blur)=\"OnValueListBlur()\"\n placeholder=\"Type to search...\">\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n @if (ShowValueListDropdown && FilteredPossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of FilteredPossibleValues; track option) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnValueListSelect(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n </div>\n }\n @default {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (change)=\"OnInputChange($event)\">\n }\n }\n }\n </div>\n <!-- Inline validation messages -->\n @if (DisplayErrors.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--error\">\n @for (error of DisplayErrors; track error.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n <span>{{ error.Message }}</span>\n </div>\n }\n </div>\n }\n @if (DisplayWarnings.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--warning\">\n @for (warning of DisplayWarnings; track warning.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>{{ warning.Message }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n}\n", styles: ["/* ============================================\n FORM FIELD - Shared styles for read and edit\n ============================================ */\n:host {\n --mj-accent: #667eea;\n --mj-accent-light: rgba(102, 126, 234, 0.08);\n --mj-text-primary: #1f2937;\n --mj-text-secondary: #4b5563;\n --mj-text-muted: #9ca3af;\n --mj-border: #e5e7eb;\n --mj-error: #ef4444;\n --mj-warning: #f59e0b;\n --mj-card-bg: #ffffff;\n --mj-forms-field-label-width: 200px;\n --mj-forms-field-gap: 12px;\n --mj-transition: 200ms;\n\n display: contents;\n}\n\n.mj-forms-field {\n display: grid;\n grid-template-columns: var(--mj-forms-field-label-width) 1fr;\n gap: var(--mj-forms-field-gap);\n align-items: baseline;\n padding: 8px 0;\n transition: all var(--mj-transition) ease;\n}\n\n/* Subtle row hover in edit mode */\n.mj-forms-field--editing:hover {\n background: var(--mj-accent-light);\n border-radius: 6px;\n margin: 0 -8px;\n padding: 8px 8px;\n}\n\n/* ============================================\n LABEL\n ============================================ */\n.mj-forms-field-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n padding-top: 2px;\n word-break: break-word;\n}\n\n/* ============================================\n FIELD CONTROL WRAPPER (value + dirty dot)\n ============================================ */\n.mj-forms-field-control {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n}\n\n.mj-forms-field-control > * {\n flex: 1;\n min-width: 0;\n}\n\n/* ============================================\n DIRTY INDICATOR (solid amber dot after label)\n ============================================ */\n.mj-forms-field--dirty .mj-forms-field-label::after {\n content: '';\n display: inline-block;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--mj-warning);\n margin-left: 6px;\n vertical-align: middle;\n}\n\n/* ============================================\n REQUIRED FIELD - red underline when empty\n ============================================ */\n.mj-forms-field--required-empty .mj-forms-field-input {\n border-bottom-color: var(--mj-error);\n}\n\n.mj-forms-field--required-empty .mj-forms-field-input:focus {\n background: #fef2f2;\n border-bottom-color: var(--mj-error);\n}\n\n.mj-forms-field--required-empty .mj-custom-select-trigger {\n border-bottom-color: var(--mj-error);\n}\n\n.mj-forms-field--required-empty .mj-fk-search .mj-forms-field-input {\n border-bottom-color: var(--mj-error);\n}\n\n/* ============================================\n READ-ONLY VALUE\n ============================================ */\n.mj-forms-field-value {\n font-size: 14px;\n color: var(--mj-text-primary);\n min-height: 24px;\n display: flex;\n align-items: center;\n overflow-wrap: break-word;\n word-break: break-word;\n}\n\n.mj-forms-field-value--long {\n white-space: pre-line;\n max-height: 300px;\n overflow: auto;\n}\n\n/* Read-only fields in edit mode */\n.mj-forms-field--readonly {\n opacity: 0.7;\n}\n\n.mj-forms-field--readonly .mj-forms-field-value {\n color: var(--mj-text-secondary);\n}\n\n/* ============================================\n LINKS (FK, email, URL)\n ============================================ */\n.mj-forms-field-link {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-accent);\n cursor: pointer;\n font-weight: 500;\n transition: color var(--mj-transition);\n text-decoration: none;\n}\n\n.mj-forms-field-link:hover {\n color: #5a6fd6;\n}\n\n.mj-forms-field-link-icon {\n font-size: 11px;\n opacity: 0;\n transition: opacity var(--mj-transition);\n}\n\n.mj-forms-field-link:hover .mj-forms-field-link-icon {\n opacity: 1;\n}\n\n/* FK fields showing entity name instead of raw ID */\n.mj-forms-field-link--fk {\n font-size: 14px;\n font-weight: 400;\n}\n\n/* ============================================\n EDIT MODE INPUTS - Clean underline style\n ============================================ */\n.mj-forms-field-input {\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: transparent;\n border: none;\n border-bottom: 1.5px solid var(--mj-border);\n padding: 4px 0;\n width: 100%;\n outline: none;\n transition: border-color var(--mj-transition) ease,\n background var(--mj-transition) ease;\n}\n\n.mj-forms-field-input:focus {\n border-bottom-color: var(--mj-accent);\n background: var(--mj-accent-light);\n border-radius: 4px 4px 0 0;\n padding: 4px 6px;\n}\n\n.mj-forms-field-input::placeholder {\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n/* Textarea variant */\n.mj-forms-field-input--textarea {\n resize: vertical;\n min-height: 60px;\n border: 1.5px solid var(--mj-border);\n border-radius: 6px;\n padding: 8px 10px;\n background: white;\n font-family: inherit;\n}\n\n.mj-forms-field-input--textarea:focus {\n border-color: var(--mj-accent);\n box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);\n background: white;\n padding: 8px 10px;\n border-radius: 6px;\n}\n\n/* Number input - narrower */\n.mj-forms-field-input--number {\n max-width: 200px;\n}\n\n/* Date input - narrower */\n.mj-forms-field-input--date {\n max-width: 220px;\n}\n\n/* ============================================\n CHECKBOX (custom styled)\n ============================================ */\n.mj-forms-field-checkbox {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.mj-forms-field-checkbox input[type=\"checkbox\"] {\n appearance: none;\n width: 18px;\n height: 18px;\n border: 2px solid var(--mj-border);\n border-radius: 4px;\n cursor: pointer;\n position: relative;\n transition: all var(--mj-transition) ease;\n flex-shrink: 0;\n}\n\n.mj-forms-field-checkbox input[type=\"checkbox\"]:checked {\n background: var(--mj-accent);\n border-color: var(--mj-accent);\n}\n\n.mj-forms-field-checkbox input[type=\"checkbox\"]:checked::after {\n content: '';\n position: absolute;\n left: 5px;\n top: 1px;\n width: 5px;\n height: 9px;\n border: solid white;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n}\n\n.mj-forms-field-checkbox input[type=\"checkbox\"]:disabled {\n opacity: 0.5;\n cursor: default;\n}\n\n/* ============================================\n CUSTOM SELECT DROPDOWN (replaces native <select>)\n ============================================ */\n.mj-custom-select-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: transparent;\n border: none;\n border-bottom: 1.5px solid var(--mj-border);\n padding: 4px 0;\n width: 100%;\n cursor: pointer;\n outline: none;\n transition: border-color var(--mj-transition) ease,\n background var(--mj-transition) ease;\n}\n\n.mj-custom-select-trigger:focus {\n border-bottom-color: var(--mj-accent);\n background: var(--mj-accent-light);\n border-radius: 4px 4px 0 0;\n padding: 4px 6px;\n}\n\n.mj-custom-select-value {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mj-custom-select-value--placeholder {\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n.mj-custom-select-chevron {\n font-size: 11px;\n color: var(--mj-text-muted);\n transition: transform var(--mj-transition) ease;\n flex-shrink: 0;\n margin-left: 8px;\n}\n\n.mj-custom-select-chevron--open {\n transform: rotate(180deg);\n}\n\n/* ============================================\n FK SEARCH (custom autocomplete)\n ============================================ */\n.mj-fk-search {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n}\n\n.mj-fk-search .mj-forms-field-input {\n padding-right: 28px;\n}\n\n.mj-fk-search-icon {\n position: absolute;\n right: 4px;\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n}\n\n.mj-fk-clear {\n position: absolute;\n right: 2px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 11px;\n padding: 4px 6px;\n line-height: 1;\n border-radius: 3px;\n transition: all var(--mj-transition);\n}\n\n.mj-fk-clear:hover {\n color: var(--mj-error);\n background: rgba(239, 68, 68, 0.08);\n}\n\n/* Matched state: solid accent underline */\n.mj-fk-search--matched .mj-forms-field-input {\n border-bottom: 2px solid var(--mj-accent);\n}\n\n/* ============================================\n FLOATING DROPDOWN PANEL (position: fixed via ngStyle)\n ============================================ */\n.mj-fk-dropdown {\n background: var(--mj-card-bg);\n border: 1px solid var(--mj-border);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n max-height: 240px;\n overflow-y: auto;\n padding: 4px;\n animation: mj-dropdown-in 150ms ease;\n}\n\n.mj-fk-dropdown--above {\n animation: mj-dropdown-in-above 150ms ease;\n}\n\n.mj-fk-option {\n padding: 10px 14px;\n font-size: 14px;\n color: var(--mj-text-primary);\n cursor: pointer;\n transition: background var(--mj-transition);\n border-radius: 6px;\n}\n\n.mj-fk-option:hover {\n background: var(--mj-accent-light);\n}\n\n.mj-fk-option--selected {\n background: var(--mj-accent-light);\n font-weight: 600;\n color: var(--mj-accent);\n}\n\n.mj-fk-option--selected:hover {\n background: rgba(102, 126, 234, 0.15);\n}\n\n@keyframes mj-dropdown-in {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n@keyframes mj-dropdown-in-above {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* ============================================\n SEARCH HIGHLIGHTING\n ============================================ */\n.mj-forms-field-label :global(.mj-forms-search-highlight) {\n background-color: #fef08a;\n color: #854d0e;\n padding: 0;\n border-radius: 2px;\n font-weight: 700;\n box-shadow: 0 0 0 2px #fef08a;\n}\n\n/* ============================================\n VALIDATION ERROR STATE\n ============================================ */\n.mj-forms-field--has-error .mj-forms-field-input {\n border-bottom-color: var(--mj-error);\n border-bottom-width: 2px;\n}\n\n.mj-forms-field--has-error .mj-forms-field-input:focus {\n background: #fef2f2;\n border-bottom-color: var(--mj-error);\n}\n\n.mj-forms-field--has-error .mj-forms-field-input--textarea {\n border-color: var(--mj-error);\n}\n\n.mj-forms-field--has-error .mj-forms-field-input--textarea:focus {\n border-color: var(--mj-error);\n box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.08);\n}\n\n.mj-forms-field--has-error .mj-custom-select-trigger {\n border-bottom-color: var(--mj-error);\n border-bottom-width: 2px;\n}\n\n.mj-forms-field--has-error .mj-fk-search .mj-forms-field-input {\n border-bottom-color: var(--mj-error);\n border-bottom-width: 2px;\n}\n\n/* ============================================\n VALIDATION WARNING STATE\n ============================================ */\n.mj-forms-field--has-warning .mj-forms-field-input {\n border-bottom-color: var(--mj-warning);\n border-bottom-width: 2px;\n}\n\n.mj-forms-field--has-warning .mj-forms-field-input:focus {\n background: #fffbeb;\n border-bottom-color: var(--mj-warning);\n}\n\n.mj-forms-field--has-warning .mj-forms-field-input--textarea {\n border-color: var(--mj-warning);\n}\n\n.mj-forms-field--has-warning .mj-forms-field-input--textarea:focus {\n border-color: var(--mj-warning);\n box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.08);\n}\n\n.mj-forms-field--has-warning .mj-custom-select-trigger {\n border-bottom-color: var(--mj-warning);\n border-bottom-width: 2px;\n}\n\n.mj-forms-field--has-warning .mj-fk-search .mj-forms-field-input {\n border-bottom-color: var(--mj-warning);\n border-bottom-width: 2px;\n}\n\n/* ============================================\n VALIDATION MESSAGE AREA\n ============================================ */\n.mj-forms-field-validation {\n grid-column: 2;\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin-top: -2px;\n overflow: hidden;\n animation: mj-validation-slide-in 200ms ease-out;\n}\n\n.mj-forms-field-validation-item {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n font-size: 12px;\n line-height: 1.4;\n padding: 3px 0 1px;\n}\n\n.mj-forms-field-validation-item i {\n font-size: 11px;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Error message colors */\n.mj-forms-field-validation--error .mj-forms-field-validation-item {\n color: var(--mj-error);\n}\n\n.mj-forms-field-validation--error .mj-forms-field-validation-item i {\n color: var(--mj-error);\n}\n\n/* Warning message colors */\n.mj-forms-field-validation--warning .mj-forms-field-validation-item {\n color: #b45309;\n}\n\n.mj-forms-field-validation--warning .mj-forms-field-validation-item i {\n color: var(--mj-warning);\n}\n\n@keyframes mj-validation-slide-in {\n from {\n opacity: 0;\n max-height: 0;\n transform: translateY(-4px);\n }\n to {\n opacity: 1;\n max-height: 100px;\n transform: translateY(0);\n }\n}\n\n/* ============================================\n RESPONSIVE\n ============================================ */\n@media (max-width: 640px) {\n .mj-forms-field {\n grid-template-columns: 1fr;\n gap: 4px;\n }\n\n .mj-forms-field-label {\n font-size: 12px;\n }\n\n .mj-forms-field-validation {\n grid-column: 1;\n }\n}\n"] }]
1162
1162
  }], null, { Record: [{
1163
1163
  type: Input
1164
1164
  }], EditMode: [{
@@ -1 +1 @@
1
- {"version":3,"file":"form-field.component.js","sourceRoot":"","sources":["../../../src/lib/field/form-field.component.ts","../../../src/lib/field/form-field.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,EAAuC,MAAM,eAAe,CAAC;AAChK,OAAO,EAA+B,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;;;;;;ICI1G,2BAAiF;;;IAA7C,4EAAoC;;;;IAMpE,AADF,+BAAmC,WACsF;IAAhE,sNAAS,gCAAyB,KAAC;IACxF,YACF;IACF,AADE,iBAAI,EACC;;;IAFH,eACF;IADE,qDACF;;;;IAOI,AADF,+BAAmC,WACoD;IAAtD,6NAAS,+BAAwB,KAAC;IAC/D,YACA;IAAA,uBAA6D;IAEjE,AADE,iBAAI,EACC;;;IAHH,eACA;IADA,qDACA;;;;IAMF,AADF,+BAAmC,WACiD;IAAnD,6NAAS,6BAAsB,KAAC;IAC7D,YACA;IAAA,wBAA+E;IAEnF,AADE,iBAAI,EACC;;;IAHH,eACA;IADA,qDACA;;;;IAMF,AADF,+BAAmC,YAC8D;IAAhE,6NAAS,gCAAyB,KAAC;IAChE,YACA;IAAA,wBAA+E;IAEnF,AADE,iBAAI,EACC;;;IAHH,eACA;IADA,qDACA;;;IAOA,AADF,+BAAmC,cACI;IACnC,4BAAoD;IAExD,AADE,iBAAM,EACD;;;IAFoB,eAAmB;IAAnB,wCAAmB;;;IAK9C,gCAA8D;IAAA,YAAmB;IAAA,iBAAO;;;IAA1B,cAAmB;IAAnB,0CAAmB;;;IAGjF,+BAAmC;IAAA,YAAmB;IAAA,iBAAO;;;IAA1B,cAAmB;IAAnB,0CAAmB;;;IADxD,AAHA,AAPA,wIAA2B,mHAOJ,kHAGhB;;;IAVP,4EAYC;;;IAbH,AARA,AARA,AARA,0HAAiB,oGAQF,oGAQG,yFAQR;;;;IAzBZ,iDAAA,OAAO,mBAAP,KAAK,mBAAL,QAAQ,SAwCP;;;IAtDP,8BAAmI;IACjI,oHAAiB;IAGjB,8BAAoC;IASlC,AAPA,mHAAyB,kFAOlB;IA4CX,AADE,iBAAM,EACF;;;IAzDqF,AAA/D,qFAA8D,yCAAwC;IAChI,cAEC;IAFD,2CAEC;IAGC,eAiDC;IAjDD,kDAiDC;;;IASD,2BAAiF;;;IAA7C,4EAAoC;;;;IAclE,kCAA+E;IAAnD,iPAAa,6BAAsB,KAAC;IAC9D,wBAAiC;IACnC,iBAAS;;;IAET,wBAA8D;;;;IAK1D,+BAA2E;IAAjD,oRAAa,4CAAkC,KAAC;IACxE,YACF;IAAA,iBAAM;;;IADJ,cACF;IADE,0DACF;;;IAJJ,+BAAwG;IACtG,gJAIC;IACH,iBAAM;;;IANwD,yDAAyC;IAA3E,sDAAiC;IAC3D,cAIC;IAJD,mCAIC;;;;IApBL,AADF,+BAAsE,gBAO1C;IADxB,AADA,AADA,0NAAS,wBAAiB,KAAC,6MAClB,wBAAiB,KAAC,qMACnB,iBAAU,KAAC;IALrB,iBAM0B;IAKxB,AAJF,oIAAoB,yGAIX;IAGT,iIAAkD;IASpD,iBAAM;;;IAxBoB,2DAA2C;IAGjE,cAAsB;IAAtB,2CAAsB;IAKxB,cAMC;IAND,6CAMC;IACD,eAQC;IARD,mFAQC;;;;IAMC,iCAGmC;IAAjC,oOAAU,4BAAqB,KAAC;IAHlC,iBAGmC;;;IADjC,4CAAuB;;;;IAIzB,oCAGmC;IAAjC,uOAAU,4BAAqB,KAAC;IAAC,iBAAW;;;IAD5C,4CAAuB;;;;IAIzB,iCAGoC;IAAlC,oOAAU,6BAAsB,KAAC;IAHnC,iBAGoC;;;IADlC,oCAAe;;;;IAIjB,iCAGkC;IAAhC,oOAAU,2BAAoB,KAAC;IAHjC,iBAGkC;;;IADhC,6CAAwB;;;;IAKxB,AADF,+BAAqC,gBAGG;IAApC,oOAAU,+BAAwB,KAAC;IACvC,AAHE,iBAEsC,EAClC;;;IAFF,cAAmB;IAAnB,wCAAmB;;;;IAiBjB,+BAAsI;IAAlD,yRAAa,8CAAmC,KAAC;IACnI,YACF;IAAA,iBAAM;;;;IAFoB,6EAAyD;IACjF,cACF;IADE,2CACF;;;IAJJ,+BAAwG;IACtG,yKAIC;IACH,iBAAM;;;IANwD,yDAAyC;IAA3E,sDAAiC;IAC3D,cAIC;IAJD,oCAIC;;;;IAfL,+BAGiC;IAA/B,AADA,gOAAS,mCAA4B,KAAC,2MAC9B,4BAAqB,KAAC;IAC9B,gCAAkG;IAChG,YACF;IAAA,iBAAO;IACP,wBAA6H;IAC/H,iBAAM;IACN,wIAAuD;;;IALhB,cAA4D;IAA5D,4EAA4D;IAC/F,cACF;IADE,uEACF;IAC6D,cAA2D;IAA3D,2EAA2D;IAE1H,cAQC;IARD,wFAQC;;;;IAeO,+BAA0E;IAAhD,yRAAa,4CAAiC,KAAC;IACvE,YACF;IAAA,iBAAM;;;IADJ,cACF;IADE,2CACF;;;IAJJ,+BAAwG;IACtG,yKAIC;IACH,iBAAM;;;IANwD,yDAAyC;IAA3E,sDAAiC;IAC3D,cAIC;IAJD,4CAIC;;;;IAdL,AADF,+BAA0B,gBAOU;IADhC,AADA,AADA,kOAAS,+BAAwB,KAAC,qNACzB,+BAAwB,KAAC,6MAC1B,wBAAiB,KAAC;IAL5B,iBAMkC;IAClC,wBAA8D;IAC9D,wIAAkE;IASpE,iBAAM;;;IAfF,cAAuB;IAAvB,4CAAuB;IAMzB,eAQC;IARD,mGAQC;;;;IAIH,iCAGmC;IAAjC,oOAAU,4BAAqB,KAAC;IAHlC,iBAGmC;;;IADjC,4CAAuB;;;IAH3B,AArBA,AApBA,AAPA,AANA,AANA,AANA,AANA,4HAAmB,yGAMC,sGAMF,sGAMI,oGAMF,yFAOF,oGAoBM,sGAqBd;;;;IAzEZ,6CAAA,SAAS,mBAAT,UAAU,mBAAV,QAAQ,mBAAR,YAAY,mBAAZ,UAAU,mBAAV,QAAQ,mBAAR,cAAc,SA+Eb;;;IAOC,+BAA4C;IAC1C,wBAA8C;IAC9C,4BAAM;IAAA,YAAmB;IAC3B,AAD2B,iBAAO,EAC5B;;;IADE,eAAmB;IAAnB,uCAAmB;;;IAJ/B,+BAAwE;IACtE,kIAKC;IACH,iBAAM;;;IANJ,cAKC;IALD,mCAKC;;;IAMC,+BAA4C;IAC1C,wBAAgD;IAChD,4BAAM;IAAA,YAAqB;IAC7B,AAD6B,iBAAO,EAC9B;;;IADE,eAAqB;IAArB,yCAAqB;;;IAJjC,+BAA0E;IACxE,kIAKC;IACH,iBAAM;;;IANJ,cAKC;IALD,qCAKC;;;IAtIP,+BAAuP;IACrP,oHAAiB;IAGjB,8BAAoC;IA6BlC,AA3BA,mHAAwB,kFA2BjB;IAkFT,iBAAM;IAEN,mHAAgC;IAUhC,mHAAkC;IAUpC,iBAAM;;;IAzI8L,AAA/C,AAAzD,AAAxC,uDAAuC,0DAAyD,gDAA+C,oDAAmD;IACpP,cAEC;IAFD,2CAEC;IAGC,eA4GC;IA5GD,iDA4GC;IAGH,eASC;IATD,0DASC;IACD,cASC;IATD,4DASC;;;IAvML,oGAA0D;IA8D1D,qGAAoC;;;IA9DpC,kGA2DC;IAGD,cA2IC;IA3ID,qEA2IC;;AD7LH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAQH,MAAM,OAAO,oBAAoB;IACvB,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAExC,8CAA8C;IACrC,MAAM,CAAc;IAE7B,uCAAuC;IAC9B,QAAQ,GAAG,KAAK,CAAC;IAE1B,6DAA6D;IACpD,SAAS,GAAG,EAAE,CAAC;IAExB;;;;;;;OAOG;IACH,IACI,IAAI,CAAC,KAA6I;QACpJ,8DAA8D;QAC9D,QAAQ,KAAK,EAAE,CAAC;YACd,KAAK,cAAc;gBAAG,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;gBAAC,MAAM;YACnD,KAAK,gBAAgB;gBAAE,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;gBAAC,MAAM;YACpD;gBAAsB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;gBAAC,MAAM;QAClD,CAAC;IACH,CAAC;IACD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IACO,KAAK,GAAuG,SAAS,CAAC;IAE9H;;;;;;OAMG;IACM,QAAQ,GAAwC,MAAM,CAAC;IAEhE,sCAAsC;IAC7B,SAAS,GAAG,IAAI,CAAC;IAE1B,0DAA0D;IACjD,WAAW,CAAe;IAEnC,2DAA2D;IAE3D,uCAAuC;IACvC,IAAqB,iBAAiB,CAAC,KAAiB,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;IAElF,4CAA4C;IAC5C,IAA0B,sBAAsB,CAAC,KAA8B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC;IAE9G,6EAA6E;IACpE,2BAA2B,GAAG,IAAI,CAAC;IAE5C,4EAA4E;IACnE,mBAAmB,GAAG,EAAE,CAAC;IAElC,uDAAuD;IAC9C,sBAAsB,GAAoB,IAAI,CAAC;IAExD,2CAA2C;IACjC,WAAW,GAAG,IAAI,YAAY,EAA+D,CAAC;IAExG,uFAAuF;IAC7E,QAAQ,GAAG,IAAI,YAAY,EAAuB,CAAC;IAE7D,gCAAgC;IAEhC,kDAAkD;IAClD,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/E,CAAC;IAED,6CAA6C;IAC7C,IAAI,WAAW;QACb,IAAI,IAAI,CAAC,mBAAmB;YAAE,OAAO,IAAI,CAAC,mBAAmB,CAAC;QAE9D,mDAAmD;QACnD,IAAI,IAAI,CAAC,SAAS,KAAK,gBAAgB;YAAE,OAAO,SAAS,CAAC;QAC1D,IAAI,IAAI,CAAC,SAAS,KAAK,gBAAgB;YAAE,OAAO,SAAS,CAAC;QAE1D,oEAAoE;QACpE,8DAA8D;QAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC;QAC/D,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;YACtF,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,SAAS,CAAC,iBAAiB,CAAC;YACrC,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,EAAE,iBAAiB,IAAI,IAAI,CAAC,SAAS,CAAC;IAC7D,CAAC;IAED,oDAAoD;IACpD,IAAI,sBAAsB;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;QACvD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC;QAErC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QAC9D,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,mDAAmD,CAAC,CAAC;IAC9F,CAAC;IAED,0BAA0B;IAC1B,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,2EAA2E;IAC3E,IAAI,KAAK,CAAC,QAAiB;QACzB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,+DAA+D;IAC/D,IAAI,eAAe;QACjB,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,KAAK,CAAC;QAClC,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;IACjC,CAAC;IAED,4FAA4F;IAC5F,IAAI,OAAO;QACT,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QACvD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC;QACvE,OAAO,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC;IAC/B,CAAC;IAED,oDAAoD;IACpD,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,SAAS,EAAE,UAAU,KAAK,KAAK,CAAC;IAC9C,CAAC;IAED,wFAAwF;IACxF,IAAI,eAAe;QACjB,0EAA0E;QAC1E,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC;QACvB,OAAO,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,CAAC;IACzD,CAAC;IAED,8BAA8B;IAE9B,gEAAgE;IACxD,QAAQ,GAAG,KAAK,CAAC;IAEzB,wDAAwD;IAChD,YAAY,GAA0B,EAAE,CAAC;IAEjD,sEAAsE;IACtE,IAAI,WAAW;QACb,qEAAqE;QACrE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,YAAY,CAAC;QAC3B,CAAC;QACD,8EAA8E;QAC9E,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC;QACzD,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,iFAAiF;IACjF,IAAI,cAAc;QAChB,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,eAAe;YAAE,OAAO,KAAK,CAAC;QACzD,OAAO,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,KAAK,IAAI,CAAC,CAAC;IACtE,CAAC;IAED,+EAA+E;IAC/E,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IACjF,CAAC;IAED,+EAA+E;IAC/E,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IACrG,CAAC;IAED,+CAA+C;IAC/C,IAAI,aAAa;QACf,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IAC5D,CAAC;IAED,iDAAiD;IACjD,IAAI,eAAe;QACjB,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IAC5D,CAAC;IAED;;;;OAIG;IACK,kBAAkB;QACxB,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACtC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7E,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,oEAAoE;IACpE,IAAI,eAAe;QACjB,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,2BAA2B;YAAE,OAAO,KAAK,CAAC;QACpD,IAAI,IAAI,CAAC,WAAW,EAAE,eAAe;YAAE,OAAO,KAAK,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC;QACvB,OAAO,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,CAAC;IACzD,CAAC;IAED,+EAA+E;IAC/E,IAAI,cAAc;QAChB,IAAI,IAAI,CAAC,sBAAsB;YAAE,OAAO,IAAI,CAAC,sBAAsB,CAAC;QACpE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC;QACjD,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,4DAA4D;IAC5D,IAAI,gBAAgB;QAClB,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC;QACzC,OAAO,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACH,IAAI,aAAa;QACf,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO,IAAI,CAAC;QAExD,yDAAyD;QACzD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC;QAC/D,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC1C,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,KAAK,EAAE;gBAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACpD,CAAC;QAED,mDAAmD;QACnD,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC,eAAe,CAAC;QAC9B,CAAC;QAED,qDAAqD;QACrD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,CAAC,4BAA4B;IAC3C,CAAC;IAED;;;OAGG;IACH,IAAI,iBAAiB;QACnB,OAAO,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC;IAC7D,CAAC;IAED,qCAAqC;IAErC,4EAA4E;IACpE,eAAe,GAA8B,SAAS,CAAC;IAE/D,8EAA8E;IACtE,gBAAgB,GAAY,SAAS,CAAC;IAE9C,2CAA2C;IACnC,cAAc,GAAG,KAAK,CAAC;IAE/B;;;OAGG;IACK,kBAAkB;QACxB,IAAI,IAAI,CAAC,cAAc;YAAE,OAAO;QAEhC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;QAC3B,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,KAAK,EAAE;YAAE,OAAO;QAE9C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,SAAS,EAAE,aAAa,IAAI,CAAC,SAAS,EAAE,sBAAsB;YAAE,OAAO;QAE5E,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC;QAEhC,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,CAAC;gBAC3B,SAAS,EAAE,SAAS,CAAC,sBAAsB;gBAC3C,KAAK,EAAE,OAAO;aACf,CAAC,CAAC,CAAC;QAEJ,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC1B,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE,CAAC;aAChD,IAAI,CAAC,IAAI,CAAC,EAAE;YACX,IAAI,CAAC,eAAe,GAAG,IAAI,IAAI,IAAI,CAAC;YACpC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAC5B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC9B,CAAC,CAAC,CAAC;IACP,CAAC;IAED,+CAA+C;IAC/C,0DAA0D;IAC1D,+CAA+C;IAE/C,uDAAuD;IACvD,WAAW,GAAG,CAAC,CAAC;IAChB,YAAY,GAAG,CAAC,CAAC;IACjB,aAAa,GAAG,CAAC,CAAC;IAClB,SAAS,GAAG,KAAK,CAAC;IAElB,mDAAmD;IAC3C,cAAc,GAAwB,IAAI,CAAC;IAEnD,mDAAmD;IACnD,IAAI,qBAAqB;QACvB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO;gBACL,UAAU,EAAE,OAAO;gBACnB,QAAQ,EAAE,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI;gBACxD,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,IAAI,CAAC,YAAY,GAAG,IAAI;gBAChC,OAAO,EAAE,IAAI,CAAC,aAAa,GAAG,IAAI;gBAClC,SAAS,EAAE,OAAO;aACnB,CAAC;QACJ,CAAC;QACD,OAAO;YACL,UAAU,EAAE,OAAO;YACnB,KAAK,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI;YAC9B,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,IAAI,CAAC,YAAY,GAAG,IAAI;YAChC,OAAO,EAAE,IAAI,CAAC,aAAa,GAAG,IAAI;YAClC,SAAS,EAAE,OAAO;SACnB,CAAC;IACJ,CAAC;IAED,2EAA2E;IACnE,sBAAsB,CAAC,QAAqB;QAClD,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,EAAE,CAAC;QAC9C,MAAM,iBAAiB,GAAG,GAAG,CAAC;QAC9B,MAAM,GAAG,GAAG,CAAC,CAAC;QACd,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC;QAE5B,IAAI,UAAU,GAAG,iBAAiB,IAAI,UAAU,GAAG,UAAU,EAAE,CAAC;YAC9D,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC;QAC9B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC;IAClC,CAAC;IAED,2DAA2D;IACnD,mBAAmB;QACzB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,MAAM,QAAQ,GAAG,GAAG,EAAE;YACpB,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC,CAAC;QACF,MAAM,QAAQ,GAAG,GAAG,EAAE;YACpB,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC,CAAC;QAEF,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,iDAAiD;QACtG,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAE5C,IAAI,CAAC,cAAc,GAAG,GAAG,EAAE;YACzB,QAAQ,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;YACvD,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC,CAAC;IACJ,CAAC;IAED,qCAAqC;IAC7B,kBAAkB;QACxB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,+BAA+B;IACvB,iBAAiB;QACvB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;QACnC,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED,+CAA+C;IAC/C,0CAA0C;IAC1C,+CAA+C;IAE/C,qDAAqD;IACrD,aAAa,GAAmB,EAAE,CAAC;IAEnC,sFAAsF;IACtF,WAAW,GAAG,KAAK,CAAC;IAEpB,yCAAyC;IACzC,cAAc,GAAG,KAAK,CAAC;IAEvB,yFAAyF;IACjF,YAAY,GAAkB,IAAI,CAAC;IAE3C,mCAAmC;IAC3B,gBAAgB,GAAyC,IAAI,CAAC;IAEtE,6DAA6D;IACrD,cAAc,GAAuB,IAAI,CAAC;IAElD,oDAAoD;IACpD,IAAI,YAAY;QACd,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,YAAY,CAAC;QACzD,OAAO,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,2CAA2C;IAC3C,SAAS,CAAC,KAAY;QACpB,MAAM,KAAK,GAAG,KAAK,CAAC,MAA0B,CAAC;QAC/C,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QAEzB,kBAAkB;QAClB,IAAI,IAAI,CAAC,gBAAgB;YAAE,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC/D,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,GAAG,EAAE;YACtC,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;gBACxB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;gBAC5B,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC1B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;IAED,kDAAkD;IAClD,SAAS,CAAC,KAAiB;QACzB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAqB,CAAC;QAC1C,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;YACnC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,QAAQ;QACN,yDAAyD;QACzD,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAC5B,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,+DAA+D;YAC/D,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;gBACpD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAC3B,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;IAED,0CAA0C;IAC1C,cAAc,CAAC,UAAwB,EAAE,KAAiB;QACxD,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,WAAW,CAAC;QAC3C,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,eAAe,CAAC;QACxC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,8DAA8D;QAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC;QAC/D,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,sCAAsC;IACtC,cAAc,CAAC,KAAiB;QAC9B,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAElC,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC;QAC/D,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,mBAAmB,CAAC,KAAa;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,SAAS,EAAE,aAAa;YAAE,OAAO;QAEtC,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,aAAa,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,aAAa,CAAC,CAAC;QAChF,IAAI,CAAC,aAAa,EAAE,SAAS;YAAE,OAAO;QAEtC,MAAM,aAAa,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC;QACnD,MAAM,WAAW,GAAG,SAAS,CAAC,sBAAsB,IAAI,IAAI,CAAC;QAC7D,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAE/C,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAA0B;YACvD,UAAU,EAAE,SAAS,CAAC,aAAa;YACnC,WAAW,EAAE,IAAI,aAAa,YAAY,YAAY,IAAI;YAC1D,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,QAAQ;YACpB,MAAM,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC;SACrC,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC5C,eAAe,EAAE,CAAC,CAAC,WAAW,CAAC;gBAC/B,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;aAC5C,CAAC,CAAC,CAAC;YACJ,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACzD,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBACjD,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,CAAC;YACD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAC5B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,+CAA+C;IAC/C,oDAAoD;IACpD,+CAA+C;IAE/C,iDAAiD;IACjD,qBAAqB,GAAG,KAAK,CAAC;IAE9B,6CAA6C;IACrC,gBAAgB,GAAG,EAAE,CAAC;IAE9B,4DAA4D;IAC5D,IAAI,sBAAsB;QACxB,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO,IAAI,CAAC,cAAc,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC;QACnD,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,mDAAmD;IACnD,gBAAgB,CAAC,KAAY;QAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,MAA0B,CAAC;QAC/C,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACrD,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,6BAA6B;IAC7B,gBAAgB,CAAC,KAAiB;QAChC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAqB,CAAC;QAC1C,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,4BAA4B;IAC5B,eAAe;QACb,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;YACnC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;IAED,kDAAkD;IAClD,iBAAiB,CAAC,KAAa,EAAE,KAAiB;QAChD,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;QACnC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,+CAA+C;IAC/C,oDAAoD;IACpD,+CAA+C;IAE/C,oDAAoD;IACpD,kBAAkB,GAAG,KAAK,CAAC;IAE3B,wCAAwC;IACxC,oBAAoB,CAAC,KAAY;QAC/B,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;YAChC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,GAAG,KAAK,CAAC,aAA4B,CAAC;YAC9C,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;YAChC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QACjC,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,wCAAwC;IACxC,mBAAmB;QACjB,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;YAChC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;IAED,uDAAuD;IACvD,mBAAmB,CAAC,KAAa,EAAE,KAAiB;QAClD,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,+CAA+C;IAC/C,qBAAqB;IACrB,+CAA+C;IAE/C,gFAAgF;IAChF,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,SAAS,EAAE,MAAM,KAAK,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,iCAAiC;IACjC,WAAW;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC;QACvB,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,EAAE,CAAC;QACjD,IAAI,GAAG,YAAY,IAAI,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC,cAAc,EAAE,CAAC;QAC9B,CAAC;QACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,WAAW,CAAC,OAAsB;QAChC,IAAI,OAAO,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,qCAAqC;YACrC,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;gBACzB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;gBACxB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;gBAC5B,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;gBACjC,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;gBAClC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;gBAC5B,wCAAwC;gBACxC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACtB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;YACzB,CAAC;YACD,gDAAgD;YAChD,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC1C,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACtB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;YACzB,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,WAAW;QACT,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED,gCAAgC;IAEhC;;OAEG;IACH,iBAAiB,CAAC,KAAiB;QACjC,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;QAExB,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAC5C,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;QACvD,IAAI,CAAC,iBAAiB;YAAE,OAAO;QAE/B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,oFAAoF;QACpF,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC,sBAAsB,IAAI,IAAI,CAAC;QACvE,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,CAAC,IAAI,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAElF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,iBAAiB;YAC7B,UAAU,EAAE,SAAS;YACrB,YAAY,EAAE,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO;SAC7C,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,KAAiB;QAChC,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;QAExB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,IAAI,EAAE,OAAO;YACb,YAAY,EAAE,KAAK;SACpB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,KAAiB;QAC9B,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;QAExB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,IAAI,EAAE,eAAe;YACrB,GAAG,EAAE,GAAG;YACR,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,KAAY;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,MAA0B,CAAC;QAC/C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,KAAY;QACzB,MAAM,KAAK,GAAG,KAAK,CAAC,MAA0B,CAAC;QAC/C,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC;QAChC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,KAAY;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,MAA0B,CAAC;QAC/C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,KAAY;QAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,MAA0B,CAAC;QAC/C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,IAAI,cAAc;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC;QACvB,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,GAAG,YAAY,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/D,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAAE,OAAO,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;8GAlzBU,oBAAoB;6DAApB,oBAAoB;YChDjC,4EAAsD;;YAAtD,qFA4MC;;;iFD5JY,oBAAoB;cAPhC,SAAS;6BACI,KAAK,YACP,eAAe,mBACR,uBAAuB,CAAC,MAAM;;kBAQ9C,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAUL,KAAK;;kBAqBL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAKL,KAAK;mBAAC,QAAQ;;kBAGd,KAAK;mBAAC,aAAa;;kBAGnB,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,MAAM;;kBAGN,MAAM;;kFAtEI,oBAAoB","sourcesContent":["import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, inject, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';\nimport { BaseEntity, EntityFieldInfo, Metadata, CompositeKey, KeyValuePair, RunView } from '@memberjunction/core';\nimport { ValidationErrorInfo } from '@memberjunction/global';\nimport { FormContext } from '../types/form-types';\nimport { FormNavigationEvent } from '../types/navigation-events';\n\n/**\n * Represents a suggestion item for FK autocomplete search results.\n */\nexport interface FKSuggestion {\n PrimaryKeyValue: unknown;\n DisplayName: string;\n}\n\n/**\n * Modern form field component that renders entity fields in both read-only and edit modes.\n *\n * **Read mode**: Clean text display with optional hyperlinks (email, URL, record).\n * **Edit mode**: Native HTML inputs with custom-built select and autocomplete components.\n *\n * Uses:\n * - Native `<input>` for text, number, date\n * - Custom styled dropdown for value list selections\n * - Custom autocomplete with floating dropdown for foreign key search\n * - Custom-styled `<input type=\"checkbox\">` for booleans\n *\n * All navigation (clicking FK links, email links, URL links) is emitted as events.\n *\n * @example\n * ```html\n * <mj-form-field\n * [Record]=\"record\"\n * [EditMode]=\"editMode\"\n * FieldName=\"CustomerName\"\n * Type=\"textbox\"\n * [FormContext]=\"formContext\"\n * (Navigate)=\"onNavigate($event)\"\n * (ValueChange)=\"onValueChange($event)\">\n * </mj-form-field>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-form-field',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './form-field.component.html',\n styleUrls: ['./form-field.component.css']\n})\nexport class MjFormFieldComponent implements OnChanges, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n /** The entity record containing this field */\n @Input() Record!: BaseEntity;\n\n /** Whether the form is in edit mode */\n @Input() EditMode = false;\n\n /** The field code name (must match a field on the entity) */\n @Input() FieldName = '';\n\n /**\n * The control type to render in edit mode.\n * Determines which input component is used.\n *\n * Also accepts deprecated Kendo-style type names for backward compatibility:\n * - `'dropdownlist'` → `'select'`\n * - `'numerictextbox'` → `'number'`\n */\n @Input()\n set Type(value: 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' | 'dropdownlist' | 'numerictextbox') {\n // Normalize deprecated Kendo type names to modern equivalents\n switch (value) {\n case 'dropdownlist': this._type = 'select'; break;\n case 'numerictextbox': this._type = 'number'; break;\n default: this._type = value; break;\n }\n }\n get Type(): 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' {\n return this._type;\n }\n private _type: 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' = 'textbox';\n\n /**\n * Link type for read-only rendering.\n * - 'Email': renders as mailto link\n * - 'URL': renders as external hyperlink\n * - 'Record': renders as FK link to related entity record\n * - 'None': renders as plain text\n */\n @Input() LinkType: 'Email' | 'URL' | 'Record' | 'None' = 'None';\n\n /** Whether to show the field label */\n @Input() ShowLabel = true;\n\n /** Form-level context (search filter, showEmptyFields) */\n @Input() FormContext?: FormContext;\n\n // ---- Deprecated camelCase aliases (backward compat) ----\n\n /** @deprecated Use [Record] instead */\n @Input('record') set _deprecatedRecord(value: BaseEntity) { this.Record = value; }\n\n /** @deprecated Use [FormContext] instead */\n @Input('formContext') set _deprecatedFormContext(value: FormContext | undefined) { this.FormContext = value; }\n\n /** Whether to hide this field when empty in read-only mode. Default: true */\n @Input() HideWhenEmptyInReadOnlyMode = true;\n\n /** Override display name (defaults to entity field metadata DisplayName) */\n @Input() DisplayNameOverride = '';\n\n /** Override possible values for select/autocomplete */\n @Input() PossibleValuesOverride: string[] | null = null;\n\n /** Emitted when the field value changes */\n @Output() ValueChange = new EventEmitter<{ FieldName: string; OldValue: unknown; NewValue: unknown }>();\n\n /** Emitted when a navigation action is triggered (FK link click, email click, etc.) */\n @Output() Navigate = new EventEmitter<FormNavigationEvent>();\n\n // ---- Computed Properties ----\n\n /** Get EntityFieldInfo metadata for this field */\n get FieldInfo(): EntityFieldInfo | undefined {\n return this.Record?.EntityInfo?.Fields?.find(f => f.Name === this.FieldName);\n }\n\n /** Display name from metadata or override */\n get DisplayName(): string {\n if (this.DisplayNameOverride) return this.DisplayNameOverride;\n\n // Friendly labels for standard MJ timestamp fields\n if (this.FieldName === '__mj_CreatedAt') return 'Created';\n if (this.FieldName === '__mj_UpdatedAt') return 'Updated';\n\n // For FK fields that have a mapped name field, use the name field's\n // friendly label (e.g., show \"Parent\" instead of \"Parent ID\")\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n const nameField = this.Record?.EntityInfo?.Fields?.find(f => f.Name === nameFieldMap);\n if (nameField) {\n return nameField.DisplayNameOrName;\n }\n }\n\n return this.FieldInfo?.DisplayNameOrName ?? this.FieldName;\n }\n\n /** Display name with search highlighting applied */\n get HighlightedDisplayName(): string {\n const filter = this.FormContext?.sectionFilter?.trim();\n if (!filter) return this.DisplayName;\n\n const escaped = filter.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(escaped, 'gi');\n return this.DisplayName.replace(regex, '<mark class=\"mj-forms-search-highlight\">$&</mark>');\n }\n\n /** Current field value */\n get Value(): unknown {\n return this.Record?.Get(this.FieldName);\n }\n\n /** Set field value, mark touched, run validation, and emit change event */\n set Value(newValue: unknown) {\n if (!this.Record) return;\n const oldValue = this.Record.Get(this.FieldName);\n this.Record.Set(this.FieldName, newValue);\n this._touched = true;\n this.runFieldValidation();\n this.ValueChange.emit({ FieldName: this.FieldName, OldValue: oldValue, NewValue: newValue });\n }\n\n /** Whether this field is read-only based on entity metadata */\n get IsFieldReadOnly(): boolean {\n if (!this.FieldInfo) return false;\n return this.FieldInfo.ReadOnly;\n }\n\n /** Whether this field has been modified (dirty). Only shown for saved records (not new). */\n get IsDirty(): boolean {\n if (!this.Record || !this.Record.IsSaved) return false;\n const field = this.Record.Fields?.find(f => f.Name === this.FieldName);\n return field?.Dirty ?? false;\n }\n\n /** Whether this field is required (not nullable) */\n get IsRequired(): boolean {\n return this.FieldInfo?.AllowsNull === false;\n }\n\n /** Whether this is a required field that is currently empty (for validation styling) */\n get IsRequiredEmpty(): boolean {\n // Defer to the validation system when it has active errors for this field\n if (this.ShowErrors) return false;\n if (!this.IsRequired || !this.EditMode) return false;\n const val = this.Value;\n return val === null || val === undefined || val === '';\n }\n\n // ---- INLINE VALIDATION ----\n\n /** Whether the user has interacted with (changed) this field */\n private _touched = false;\n\n /** Locally computed validation errors for this field */\n private _fieldErrors: ValidationErrorInfo[] = [];\n\n /** Validation errors for this field from the best available source */\n get FieldErrors(): ValidationErrorInfo[] {\n // If touched, use fresh local validation (covers real-time feedback)\n if (this._touched) {\n return this._fieldErrors;\n }\n // Otherwise use form-level errors from save failure (covers untouched fields)\n const contextErrors = this.FormContext?.validationErrors;\n if (contextErrors && contextErrors.length > 0) {\n return contextErrors.filter(e => e.Source === this.FieldName);\n }\n return [];\n }\n\n /** Whether to show validation messages (touched OR form-level showValidation) */\n get ShowValidation(): boolean {\n if (!this.EditMode || this.IsFieldReadOnly) return false;\n return this._touched || (this.FormContext?.showValidation === true);\n }\n\n /** Whether this field has active error-level validation failures to display */\n get ShowErrors(): boolean {\n return this.ShowValidation && this.FieldErrors.some(e => e.Type === 'Failure');\n }\n\n /** Whether this field has active warning-level validation issues to display */\n get ShowWarnings(): boolean {\n return this.ShowValidation && !this.ShowErrors && this.FieldErrors.some(e => e.Type === 'Warning');\n }\n\n /** Error messages to render in the template */\n get DisplayErrors(): ValidationErrorInfo[] {\n if (!this.ShowValidation) return [];\n return this.FieldErrors.filter(e => e.Type === 'Failure');\n }\n\n /** Warning messages to render in the template */\n get DisplayWarnings(): ValidationErrorInfo[] {\n if (!this.ShowValidation) return [];\n return this.FieldErrors.filter(e => e.Type === 'Warning');\n }\n\n /**\n * Runs validation for this field using the full Record.Validate() method.\n * This captures both built-in field checks and custom Validate() overrides\n * (including cross-field rules). Results are filtered to this field only.\n */\n private runFieldValidation(): void {\n if (!this.Record || !this.EditMode) {\n this._fieldErrors = [];\n return;\n }\n try {\n const result = this.Record.Validate();\n this._fieldErrors = result.Errors.filter(e => e.Source === this.FieldName);\n } catch {\n this._fieldErrors = [];\n }\n this.cdr.markForCheck();\n }\n\n /** Whether this field should be hidden (empty in read-only mode) */\n get ShouldHideField(): boolean {\n if (this.EditMode) return false;\n if (!this.HideWhenEmptyInReadOnlyMode) return false;\n if (this.FormContext?.showEmptyFields) return false;\n const val = this.Value;\n return val === null || val === undefined || val === '';\n }\n\n /** Possible values for select/autocomplete from entity metadata or override */\n get PossibleValues(): string[] {\n if (this.PossibleValuesOverride) return this.PossibleValuesOverride;\n const values = this.FieldInfo?.EntityFieldValues;\n if (values && values.length > 0) {\n return values.map(v => v.Value);\n }\n return [];\n }\n\n /** Whether this field has a related entity (foreign key) */\n get HasRelatedEntity(): boolean {\n const re = this.FieldInfo?.RelatedEntity;\n return re != null && re.length > 0;\n }\n\n /**\n * For FK fields, returns the human-readable name to display instead of the raw ID.\n *\n * Resolution order:\n * 1. If `RelatedEntityNameFieldMap` exists, read the name from the joined field on the record (sync).\n * 2. Otherwise, fall back to an async `GetEntityRecordName` lookup (result cached in `_resolvedFKName`).\n */\n get FKDisplayName(): string | null {\n if (!this.Record || !this.HasRelatedEntity) return null;\n\n // Fast path: name field is joined into our record's view\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n const val = this.Record.Get(nameFieldMap);\n if (val != null && val !== '') return String(val);\n }\n\n // Async fallback: resolved via GetEntityRecordName\n if (this._resolvedFKName !== undefined) {\n return this._resolvedFKName;\n }\n\n // Kick off async resolution if not already in flight\n this.resolveFKNameAsync();\n return null; // will render once resolved\n }\n\n /**\n * Whether this FK field should display the related entity name\n * with a hyperlink instead of the raw ID value.\n */\n get IsFKWithNameField(): boolean {\n return this.HasRelatedEntity && this.FKDisplayName != null;\n }\n\n // ---- Async FK name resolution ----\n\n /** Cached result from GetEntityRecordName. undefined = not yet resolved. */\n private _resolvedFKName: string | null | undefined = undefined;\n\n /** Tracks which FK value we resolved so we can invalidate on record change */\n private _resolvedFKValue: unknown = undefined;\n\n /** Whether an async lookup is in flight */\n private _fkNameLoading = false;\n\n /**\n * Asynchronously resolves the display name for an FK field that lacks\n * a RelatedEntityNameFieldMap by calling Metadata.GetEntityRecordName.\n */\n private resolveFKNameAsync(): void {\n if (this._fkNameLoading) return;\n\n const fkValue = this.Value;\n if (fkValue == null || fkValue === '') return;\n\n const fieldInfo = this.FieldInfo;\n if (!fieldInfo?.RelatedEntity || !fieldInfo?.RelatedEntityFieldName) return;\n\n this._fkNameLoading = true;\n this._resolvedFKValue = fkValue;\n\n const pk = new CompositeKey([{\n FieldName: fieldInfo.RelatedEntityFieldName,\n Value: fkValue\n }]);\n\n const md = new Metadata();\n md.GetEntityRecordName(fieldInfo.RelatedEntity, pk)\n .then(name => {\n this._resolvedFKName = name || null;\n this._fkNameLoading = false;\n this.cdr.markForCheck();\n })\n .catch(() => {\n this._resolvedFKName = null;\n this._fkNameLoading = false;\n });\n }\n\n // ============================================\n // DROPDOWN POSITIONING (shared by FK, value list, select)\n // ============================================\n\n /** Calculated position for fixed-position dropdowns */\n DropdownTop = 0;\n DropdownLeft = 0;\n DropdownWidth = 0;\n OpenAbove = false;\n\n /** Cleanup function for scroll/resize listeners */\n private _scrollCleanup: (() => void) | null = null;\n\n /** Inline style for the fixed-position dropdown */\n get DropdownPositionStyle(): Record<string, string> {\n if (this.OpenAbove) {\n return {\n 'position': 'fixed',\n 'bottom': (window.innerHeight - this.DropdownTop) + 'px',\n 'top': 'auto',\n 'left': this.DropdownLeft + 'px',\n 'width': this.DropdownWidth + 'px',\n 'z-index': '10000'\n };\n }\n return {\n 'position': 'fixed',\n 'top': this.DropdownTop + 'px',\n 'bottom': 'auto',\n 'left': this.DropdownLeft + 'px',\n 'width': this.DropdownWidth + 'px',\n 'z-index': '10000'\n };\n }\n\n /** Calculate dropdown position relative to viewport from anchor element */\n private updateDropdownPosition(anchorEl: HTMLElement): void {\n const rect = anchorEl.getBoundingClientRect();\n const dropdownMaxHeight = 240;\n const gap = 4;\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n\n if (spaceBelow < dropdownMaxHeight && spaceAbove > spaceBelow) {\n this.OpenAbove = true;\n this.DropdownTop = rect.top - gap;\n } else {\n this.OpenAbove = false;\n this.DropdownTop = rect.bottom + gap;\n }\n this.DropdownLeft = rect.left;\n this.DropdownWidth = rect.width;\n }\n\n /** Start listening for scroll/resize to close dropdowns */\n private startScrollListener(): void {\n this.stopScrollListener();\n\n const onScroll = () => {\n this.closeAllDropdowns();\n this.cdr.markForCheck();\n };\n const onResize = () => {\n this.closeAllDropdowns();\n this.cdr.markForCheck();\n };\n\n document.addEventListener('scroll', onScroll, true); // capture phase catches all scrollable ancestors\n window.addEventListener('resize', onResize);\n\n this._scrollCleanup = () => {\n document.removeEventListener('scroll', onScroll, true);\n window.removeEventListener('resize', onResize);\n };\n }\n\n /** Remove scroll/resize listeners */\n private stopScrollListener(): void {\n if (this._scrollCleanup) {\n this._scrollCleanup();\n this._scrollCleanup = null;\n }\n }\n\n /** Close all dropdown types */\n private closeAllDropdowns(): void {\n this.ShowFKDropdown = false;\n this.ShowValueListDropdown = false;\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n }\n\n // ============================================\n // FK AUTOCOMPLETE (custom implementation)\n // ============================================\n\n /** Suggestions returned from the FK entity search */\n FKSuggestions: FKSuggestion[] = [];\n\n /** Whether the current FK value is a confirmed match (user selected from dropdown) */\n FKIsMatched = false;\n\n /** Whether the FK dropdown is visible */\n ShowFKDropdown = false;\n\n /** Text the user is currently typing in the FK search input. null = use display name. */\n private _fkInputText: string | null = null;\n\n /** Debounce timer for FK search */\n private _fkSearchTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Last known FK input element for position recalculation */\n private _lastFKInputEl: HTMLElement | null = null;\n\n /** The display text shown in the FK search input */\n get FKSearchText(): string {\n if (this._fkInputText !== null) return this._fkInputText;\n return this.FKDisplayName || '';\n }\n\n /** Handle typing in the FK search input */\n OnFKInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n this._fkInputText = input.value;\n this._lastFKInputEl = input;\n this.FKIsMatched = false;\n\n // Debounce search\n if (this._fkSearchTimeout) clearTimeout(this._fkSearchTimeout);\n this._fkSearchTimeout = setTimeout(() => {\n if (this._fkInputText && this._fkInputText.length >= 1) {\n this.searchRelatedEntity(this._fkInputText);\n } else {\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n }, 300);\n }\n\n /** Show dropdown on focus if suggestions exist */\n OnFKFocus(event: FocusEvent): void {\n const input = event.target as HTMLElement;\n this._lastFKInputEl = input;\n if (this.FKSuggestions.length > 0) {\n this.updateDropdownPosition(input);\n this.startScrollListener();\n this.ShowFKDropdown = true;\n this.cdr.markForCheck();\n }\n }\n\n /** Hide dropdown on blur, revert to matched name if user didn't select */\n OnFKBlur(): void {\n // Small delay so mousedown on dropdown items fires first\n setTimeout(() => {\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n // If user was typing but didn't select, revert to display name\n if (!this.FKIsMatched && this._fkInputText !== null) {\n this._fkInputText = null;\n }\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an item from the FK dropdown */\n OnFKSelectItem(suggestion: FKSuggestion, event: MouseEvent): void {\n event.preventDefault();\n this._fkInputText = suggestion.DisplayName;\n this.Value = suggestion.PrimaryKeyValue;\n this.FKIsMatched = true;\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n\n // Update virtual name field for visual consistency after save\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n this.Record.Set(nameFieldMap, suggestion.DisplayName);\n }\n this.cdr.markForCheck();\n }\n\n /** Clear FK value via the X button */\n OnFKClearClick(event: MouseEvent): void {\n event.preventDefault();\n this.Value = null;\n this._fkInputText = null;\n this.FKIsMatched = false;\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n this._resolvedFKName = undefined;\n this._resolvedFKValue = undefined;\n\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n this.Record.Set(nameFieldMap, '');\n }\n this.cdr.markForCheck();\n }\n\n /**\n * Perform a RunView search on the related entity's name field.\n */\n private async searchRelatedEntity(query: string): Promise<void> {\n const fieldInfo = this.FieldInfo;\n if (!fieldInfo?.RelatedEntity) return;\n\n const md = new Metadata();\n const relatedEntity = md.Entities.find(e => e.Name === fieldInfo.RelatedEntity);\n if (!relatedEntity?.NameField) return;\n\n const nameFieldName = relatedEntity.NameField.Name;\n const pkFieldName = fieldInfo.RelatedEntityFieldName || 'ID';\n const escapedQuery = query.replace(/'/g, \"''\");\n\n const rv = new RunView();\n const result = await rv.RunView<Record<string, unknown>>({\n EntityName: fieldInfo.RelatedEntity,\n ExtraFilter: `[${nameFieldName}] LIKE '%${escapedQuery}%'`,\n MaxRows: 20,\n ResultType: 'simple',\n Fields: [pkFieldName, nameFieldName]\n });\n\n if (result.Success) {\n this.FKSuggestions = result.Results.map(r => ({\n PrimaryKeyValue: r[pkFieldName],\n DisplayName: String(r[nameFieldName] || '')\n }));\n if (this.FKSuggestions.length > 0 && this._lastFKInputEl) {\n this.updateDropdownPosition(this._lastFKInputEl);\n this.startScrollListener();\n }\n this.ShowFKDropdown = this.FKSuggestions.length > 0;\n } else {\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n }\n this.cdr.markForCheck();\n }\n\n // ============================================\n // VALUE LIST AUTOCOMPLETE (for 'autocomplete' type)\n // ============================================\n\n /** Whether the value list dropdown is visible */\n ShowValueListDropdown = false;\n\n /** Current filter text for the value list */\n private _valueListFilter = '';\n\n /** Filtered possible values based on what the user typed */\n get FilteredPossibleValues(): string[] {\n if (!this._valueListFilter) return this.PossibleValues;\n const filter = this._valueListFilter.toLowerCase();\n return this.PossibleValues.filter(v => v.toLowerCase().includes(filter));\n }\n\n /** Handle typing in the value list autocomplete */\n OnValueListInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n this._valueListFilter = input.value;\n this.Value = input.value;\n this.updateDropdownPosition(input);\n if (!this._scrollCleanup) this.startScrollListener();\n this.ShowValueListDropdown = true;\n this.cdr.markForCheck();\n }\n\n /** Show dropdown on focus */\n OnValueListFocus(event: FocusEvent): void {\n const input = event.target as HTMLElement;\n this.updateDropdownPosition(input);\n this.startScrollListener();\n this.ShowValueListDropdown = true;\n this.cdr.markForCheck();\n }\n\n /** Hide dropdown on blur */\n OnValueListBlur(): void {\n setTimeout(() => {\n this.ShowValueListDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an item from the value list dropdown */\n OnValueListSelect(value: string, event: MouseEvent): void {\n event.preventDefault();\n this.Value = value;\n this._valueListFilter = '';\n this.ShowValueListDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n\n // ============================================\n // CUSTOM SELECT DROPDOWN (replaces native <select>)\n // ============================================\n\n /** Whether the custom select dropdown is visible */\n ShowSelectDropdown = false;\n\n /** Toggle the custom select dropdown */\n OnSelectTriggerClick(event: Event): void {\n event.preventDefault();\n if (this.ShowSelectDropdown) {\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n } else {\n const el = event.currentTarget as HTMLElement;\n this.updateDropdownPosition(el);\n this.startScrollListener();\n this.ShowSelectDropdown = true;\n }\n this.cdr.markForCheck();\n }\n\n /** Close the select dropdown on blur */\n OnSelectTriggerBlur(): void {\n setTimeout(() => {\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an option from the custom select dropdown */\n OnSelectOptionClick(value: string, event: MouseEvent): void {\n event.preventDefault();\n this.Value = value;\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n\n // ============================================\n // GENERAL PROPERTIES\n // ============================================\n\n /** Whether the field's varchar(max) - long text that gets markdown rendering */\n get IsLongText(): boolean {\n return this.FieldInfo?.Length === -1;\n }\n\n /** Format a value for display */\n FormatValue(): string {\n const val = this.Value;\n if (val === null || val === undefined) return '';\n if (val instanceof Date) {\n return val.toLocaleString();\n }\n return String(val);\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['FormContext'] || changes['EditMode'] || changes['Record']) {\n // Reset FK state when record changes\n if (changes['Record']) {\n this._fkInputText = null;\n this.FKIsMatched = false;\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this._resolvedFKName = undefined;\n this._resolvedFKValue = undefined;\n this._fkNameLoading = false;\n // Reset validation state for new record\n this._touched = false;\n this._fieldErrors = [];\n }\n // Reset validation state when exiting edit mode\n if (changes['EditMode'] && !this.EditMode) {\n this._touched = false;\n this._fieldErrors = [];\n }\n this.cdr.markForCheck();\n }\n }\n\n ngOnDestroy(): void {\n if (this._fkSearchTimeout) {\n clearTimeout(this._fkSearchTimeout);\n }\n this.stopScrollListener();\n }\n\n // ---- Navigation Handlers ----\n\n /**\n * Handle click on a record FK link in read-only mode.\n */\n OnRecordLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n if (!this.FieldInfo || !this.Record) return;\n const relatedEntityName = this.FieldInfo.RelatedEntity;\n if (!relatedEntityName) return;\n\n const fkValue = this.Value;\n if (!fkValue) return;\n\n // Build a CompositeKey for the FK target record using the related entity's PK field\n const relatedFieldName = this.FieldInfo.RelatedEntityFieldName || 'ID';\n const targetKey = new CompositeKey([new KeyValuePair(relatedFieldName, fkValue)]);\n\n this.Navigate.emit({\n Kind: 'record',\n EntityName: relatedEntityName,\n PrimaryKey: targetKey,\n OpenInNewTab: event.ctrlKey || event.metaKey\n });\n }\n\n /**\n * Handle click on an email link in read-only mode.\n */\n OnEmailLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n const email = this.FormatValue();\n if (!email) return;\n this.Navigate.emit({\n Kind: 'email',\n EmailAddress: email\n });\n }\n\n /**\n * Handle click on a URL link in read-only mode.\n */\n OnUrlLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n const url = this.FormatValue();\n if (!url) return;\n this.Navigate.emit({\n Kind: 'external-link',\n Url: url,\n OpenInNewTab: true\n });\n }\n\n /**\n * Handle value change from a native input.\n */\n OnInputChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.value;\n }\n\n /**\n * Handle value change from a number input.\n */\n OnNumberChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n const num = input.valueAsNumber;\n this.Value = isNaN(num) ? null : num;\n }\n\n /**\n * Handle value change from a date input.\n */\n OnDateChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.value ? new Date(input.value) : null;\n }\n\n /**\n * Handle value change from a checkbox.\n */\n OnCheckboxChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.checked;\n }\n\n /**\n * Get date value formatted for HTML date input.\n */\n get DateInputValue(): string {\n const val = this.Value;\n if (!val) return '';\n const date = val instanceof Date ? val : new Date(String(val));\n if (isNaN(date.getTime())) return '';\n return date.toISOString().split('T')[0];\n }\n}\n","@if (Record && (Record.IsSaved || !IsFieldReadOnly)) {\n <!-- READ-ONLY MODE -->\n @if ((!EditMode || IsFieldReadOnly) && !ShouldHideField) {\n <div class=\"mj-forms-field\" [class.mj-forms-field--readonly]=\"EditMode && IsFieldReadOnly\" [class.mj-forms-field--dirty]=\"IsDirty\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- FK fields with a mapped name field: show the name as a hyperlink -->\n @if (IsFKWithNameField) {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link mj-forms-field-link--fk\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FKDisplayName }}\n </a>\n </span>\n }\n @else {\n @switch (LinkType) {\n @case ('Email') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnEmailLinkClick($event)\" title=\"Send email\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-envelope mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('URL') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnUrlLinkClick($event)\" title=\"Open link\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('Record') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @default {\n @if (Type === 'checkbox') {\n <span class=\"mj-forms-field-value\">\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\" [checked]=\"!!Value\" disabled>\n </div>\n </span>\n }\n @else if (IsLongText) {\n <span class=\"mj-forms-field-value mj-forms-field-value--long\">{{ FormatValue() }}</span>\n }\n @else {\n <span class=\"mj-forms-field-value\">{{ FormatValue() }}</span>\n }\n }\n }\n }\n </div>\n </div>\n }\n\n <!-- EDIT MODE -->\n @if (EditMode && !IsFieldReadOnly) {\n <div class=\"mj-forms-field mj-forms-field--editing\" [class.mj-forms-field--dirty]=\"IsDirty\" [class.mj-forms-field--required-empty]=\"IsRequiredEmpty\" [class.mj-forms-field--has-error]=\"ShowErrors\" [class.mj-forms-field--has-warning]=\"ShowWarnings\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- Foreign Key fields get custom search autocomplete -->\n @if (HasRelatedEntity) {\n <div class=\"mj-fk-search\" [class.mj-fk-search--matched]=\"FKIsMatched\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FKSearchText\"\n (input)=\"OnFKInput($event)\"\n (focus)=\"OnFKFocus($event)\"\n (blur)=\"OnFKBlur()\"\n placeholder=\"Search...\">\n @if (FKSearchText) {\n <button class=\"mj-fk-clear\" (mousedown)=\"OnFKClearClick($event)\" title=\"Clear\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n } @else {\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n }\n @if (ShowFKDropdown && FKSuggestions.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (suggestion of FKSuggestions; track suggestion.PrimaryKeyValue) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnFKSelectItem(suggestion, $event)\">\n {{ suggestion.DisplayName }}\n </div>\n }\n </div>\n }\n </div>\n }\n @else {\n @switch (Type) {\n @case ('textbox') {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (change)=\"OnInputChange($event)\">\n }\n @case ('textarea') {\n <textarea\n class=\"mj-forms-field-input mj-forms-field-input--textarea\"\n [value]=\"FormatValue()\"\n (change)=\"OnInputChange($event)\"></textarea>\n }\n @case ('number') {\n <input type=\"number\"\n class=\"mj-forms-field-input mj-forms-field-input--number\"\n [value]=\"Value\"\n (change)=\"OnNumberChange($event)\">\n }\n @case ('datepicker') {\n <input type=\"date\"\n class=\"mj-forms-field-input mj-forms-field-input--date\"\n [value]=\"DateInputValue\"\n (change)=\"OnDateChange($event)\">\n }\n @case ('checkbox') {\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\"\n [checked]=\"!!Value\"\n (change)=\"OnCheckboxChange($event)\">\n </div>\n }\n @case ('select') {\n <div class=\"mj-custom-select-trigger\"\n tabindex=\"0\"\n (click)=\"OnSelectTriggerClick($event)\"\n (blur)=\"OnSelectTriggerBlur()\">\n <span class=\"mj-custom-select-value\" [class.mj-custom-select-value--placeholder]=\"!FormatValue()\">\n {{ FormatValue() || '-- Select --' }}\n </span>\n <i class=\"fa-solid fa-chevron-down mj-custom-select-chevron\" [class.mj-custom-select-chevron--open]=\"ShowSelectDropdown\"></i>\n </div>\n @if (ShowSelectDropdown && PossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of PossibleValues; track option) {\n <div class=\"mj-fk-option\" [class.mj-fk-option--selected]=\"FormatValue() === option\" (mousedown)=\"OnSelectOptionClick(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n }\n @case ('autocomplete') {\n <div class=\"mj-fk-search\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (input)=\"OnValueListInput($event)\"\n (focus)=\"OnValueListFocus($event)\"\n (blur)=\"OnValueListBlur()\"\n placeholder=\"Type to search...\">\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n @if (ShowValueListDropdown && FilteredPossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of FilteredPossibleValues; track option) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnValueListSelect(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n </div>\n }\n @default {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (change)=\"OnInputChange($event)\">\n }\n }\n }\n </div>\n <!-- Inline validation messages -->\n @if (DisplayErrors.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--error\">\n @for (error of DisplayErrors; track error.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n <span>{{ error.Message }}</span>\n </div>\n }\n </div>\n }\n @if (DisplayWarnings.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--warning\">\n @for (warning of DisplayWarnings; track warning.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>{{ warning.Message }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n}\n"]}
1
+ {"version":3,"file":"form-field.component.js","sourceRoot":"","sources":["../../../src/lib/field/form-field.component.ts","../../../src/lib/field/form-field.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, inject, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';\nimport { BaseEntity, EntityFieldInfo, Metadata, CompositeKey, KeyValuePair, RunView } from '@memberjunction/core';\nimport { ValidationErrorInfo } from '@memberjunction/global';\nimport { FormContext } from '../types/form-types';\nimport { FormNavigationEvent } from '../types/navigation-events';\n\n/**\n * Represents a suggestion item for FK autocomplete search results.\n */\nexport interface FKSuggestion {\n PrimaryKeyValue: unknown;\n DisplayName: string;\n}\n\n/**\n * Modern form field component that renders entity fields in both read-only and edit modes.\n *\n * **Read mode**: Clean text display with optional hyperlinks (email, URL, record).\n * **Edit mode**: Native HTML inputs with custom-built select and autocomplete components.\n *\n * Uses:\n * - Native `<input>` for text, number, date\n * - Custom styled dropdown for value list selections\n * - Custom autocomplete with floating dropdown for foreign key search\n * - Custom-styled `<input type=\"checkbox\">` for booleans\n *\n * All navigation (clicking FK links, email links, URL links) is emitted as events.\n *\n * @example\n * ```html\n * <mj-form-field\n * [Record]=\"record\"\n * [EditMode]=\"editMode\"\n * FieldName=\"CustomerName\"\n * Type=\"textbox\"\n * [FormContext]=\"formContext\"\n * (Navigate)=\"onNavigate($event)\"\n * (ValueChange)=\"onValueChange($event)\">\n * </mj-form-field>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-form-field',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './form-field.component.html',\n styleUrls: ['./form-field.component.css']\n})\nexport class MjFormFieldComponent implements OnChanges, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n /** The entity record containing this field */\n @Input() Record!: BaseEntity;\n\n /** Whether the form is in edit mode */\n @Input() EditMode = false;\n\n /** The field code name (must match a field on the entity) */\n @Input() FieldName = '';\n\n /**\n * The control type to render in edit mode.\n * Determines which input component is used.\n *\n * Also accepts deprecated Kendo-style type names for backward compatibility:\n * - `'dropdownlist'` → `'select'`\n * - `'numerictextbox'` → `'number'`\n */\n @Input()\n set Type(value: 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' | 'dropdownlist' | 'numerictextbox') {\n // Normalize deprecated Kendo type names to modern equivalents\n switch (value) {\n case 'dropdownlist': this._type = 'select'; break;\n case 'numerictextbox': this._type = 'number'; break;\n default: this._type = value; break;\n }\n }\n get Type(): 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' {\n return this._type;\n }\n private _type: 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' = 'textbox';\n\n /**\n * Link type for read-only rendering.\n * - 'Email': renders as mailto link\n * - 'URL': renders as external hyperlink\n * - 'Record': renders as FK link to related entity record\n * - 'None': renders as plain text\n */\n @Input() LinkType: 'Email' | 'URL' | 'Record' | 'None' = 'None';\n\n /** Whether to show the field label */\n @Input() ShowLabel = true;\n\n /** Form-level context (search filter, showEmptyFields) */\n @Input() FormContext?: FormContext;\n\n // ---- Deprecated camelCase aliases (backward compat) ----\n\n /** @deprecated Use [Record] instead */\n @Input('record') set _deprecatedRecord(value: BaseEntity) { this.Record = value; }\n\n /** @deprecated Use [FormContext] instead */\n @Input('formContext') set _deprecatedFormContext(value: FormContext | undefined) { this.FormContext = value; }\n\n /** Whether to hide this field when empty in read-only mode. Default: true */\n @Input() HideWhenEmptyInReadOnlyMode = true;\n\n /** Override display name (defaults to entity field metadata DisplayName) */\n @Input() DisplayNameOverride = '';\n\n /** Override possible values for select/autocomplete */\n @Input() PossibleValuesOverride: string[] | null = null;\n\n /** Emitted when the field value changes */\n @Output() ValueChange = new EventEmitter<{ FieldName: string; OldValue: unknown; NewValue: unknown }>();\n\n /** Emitted when a navigation action is triggered (FK link click, email click, etc.) */\n @Output() Navigate = new EventEmitter<FormNavigationEvent>();\n\n // ---- Computed Properties ----\n\n /** Get EntityFieldInfo metadata for this field */\n get FieldInfo(): EntityFieldInfo | undefined {\n return this.Record?.EntityInfo?.Fields?.find(f => f.Name === this.FieldName);\n }\n\n /** Display name from metadata or override */\n get DisplayName(): string {\n if (this.DisplayNameOverride) return this.DisplayNameOverride;\n\n // Friendly labels for standard MJ timestamp fields\n if (this.FieldName === '__mj_CreatedAt') return 'Created';\n if (this.FieldName === '__mj_UpdatedAt') return 'Updated';\n\n // For FK fields that have a mapped name field, use the name field's\n // friendly label (e.g., show \"Parent\" instead of \"Parent ID\")\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n const nameField = this.Record?.EntityInfo?.Fields?.find(f => f.Name === nameFieldMap);\n if (nameField) {\n return nameField.DisplayNameOrName;\n }\n }\n\n return this.FieldInfo?.DisplayNameOrName ?? this.FieldName;\n }\n\n /** Display name with search highlighting applied */\n get HighlightedDisplayName(): string {\n const filter = this.FormContext?.sectionFilter?.trim();\n if (!filter) return this.DisplayName;\n\n const escaped = filter.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(escaped, 'gi');\n return this.DisplayName.replace(regex, '<mark class=\"mj-forms-search-highlight\">$&</mark>');\n }\n\n /** Current field value */\n get Value(): unknown {\n return this.Record?.Get(this.FieldName);\n }\n\n /** Set field value, mark touched, run validation, and emit change event */\n set Value(newValue: unknown) {\n if (!this.Record) return;\n const oldValue = this.Record.Get(this.FieldName);\n this.Record.Set(this.FieldName, newValue);\n this._touched = true;\n this.runFieldValidation();\n this.ValueChange.emit({ FieldName: this.FieldName, OldValue: oldValue, NewValue: newValue });\n }\n\n /** Whether this field is read-only based on entity metadata */\n get IsFieldReadOnly(): boolean {\n if (!this.FieldInfo) return false;\n return this.FieldInfo.ReadOnly;\n }\n\n /** Whether this field has been modified (dirty). Only shown for saved records (not new). */\n get IsDirty(): boolean {\n if (!this.Record || !this.Record.IsSaved) return false;\n const field = this.Record.Fields?.find(f => f.Name === this.FieldName);\n return field?.Dirty ?? false;\n }\n\n /** Whether this field is required (not nullable) */\n get IsRequired(): boolean {\n return this.FieldInfo?.AllowsNull === false;\n }\n\n /** Whether this is a required field that is currently empty (for validation styling) */\n get IsRequiredEmpty(): boolean {\n // Defer to the validation system when it has active errors for this field\n if (this.ShowErrors) return false;\n if (!this.IsRequired || !this.EditMode) return false;\n const val = this.Value;\n return val === null || val === undefined || val === '';\n }\n\n // ---- INLINE VALIDATION ----\n\n /** Whether the user has interacted with (changed) this field */\n private _touched = false;\n\n /** Locally computed validation errors for this field */\n private _fieldErrors: ValidationErrorInfo[] = [];\n\n /** Validation errors for this field from the best available source */\n get FieldErrors(): ValidationErrorInfo[] {\n // If touched, use fresh local validation (covers real-time feedback)\n if (this._touched) {\n return this._fieldErrors;\n }\n // Otherwise use form-level errors from save failure (covers untouched fields)\n const contextErrors = this.FormContext?.validationErrors;\n if (contextErrors && contextErrors.length > 0) {\n return contextErrors.filter(e => e.Source === this.FieldName);\n }\n return [];\n }\n\n /** Whether to show validation messages (touched OR form-level showValidation) */\n get ShowValidation(): boolean {\n if (!this.EditMode || this.IsFieldReadOnly) return false;\n return this._touched || (this.FormContext?.showValidation === true);\n }\n\n /** Whether this field has active error-level validation failures to display */\n get ShowErrors(): boolean {\n return this.ShowValidation && this.FieldErrors.some(e => e.Type === 'Failure');\n }\n\n /** Whether this field has active warning-level validation issues to display */\n get ShowWarnings(): boolean {\n return this.ShowValidation && !this.ShowErrors && this.FieldErrors.some(e => e.Type === 'Warning');\n }\n\n /** Error messages to render in the template */\n get DisplayErrors(): ValidationErrorInfo[] {\n if (!this.ShowValidation) return [];\n return this.FieldErrors.filter(e => e.Type === 'Failure');\n }\n\n /** Warning messages to render in the template */\n get DisplayWarnings(): ValidationErrorInfo[] {\n if (!this.ShowValidation) return [];\n return this.FieldErrors.filter(e => e.Type === 'Warning');\n }\n\n /**\n * Runs validation for this field using the full Record.Validate() method.\n * This captures both built-in field checks and custom Validate() overrides\n * (including cross-field rules). Results are filtered to this field only.\n */\n private runFieldValidation(): void {\n if (!this.Record || !this.EditMode) {\n this._fieldErrors = [];\n return;\n }\n try {\n const result = this.Record.Validate();\n this._fieldErrors = result.Errors.filter(e => e.Source === this.FieldName);\n } catch {\n this._fieldErrors = [];\n }\n this.cdr.markForCheck();\n }\n\n /** Whether this field should be hidden (empty in read-only mode) */\n get ShouldHideField(): boolean {\n if (this.EditMode) return false;\n if (!this.HideWhenEmptyInReadOnlyMode) return false;\n if (this.FormContext?.showEmptyFields) return false;\n const val = this.Value;\n return val === null || val === undefined || val === '';\n }\n\n /** Possible values for select/autocomplete from entity metadata or override */\n get PossibleValues(): string[] {\n if (this.PossibleValuesOverride) return this.PossibleValuesOverride;\n const values = this.FieldInfo?.EntityFieldValues;\n if (values && values.length > 0) {\n return values.map(v => v.Value);\n }\n return [];\n }\n\n /** Whether this field has a related entity (foreign key) */\n get HasRelatedEntity(): boolean {\n const re = this.FieldInfo?.RelatedEntity;\n return re != null && re.length > 0;\n }\n\n /**\n * For FK fields, returns the human-readable name to display instead of the raw ID.\n *\n * Resolution order:\n * 1. If `RelatedEntityNameFieldMap` exists, read the name from the joined field on the record (sync).\n * 2. Otherwise, fall back to an async `GetEntityRecordName` lookup (result cached in `_resolvedFKName`).\n */\n get FKDisplayName(): string | null {\n if (!this.Record || !this.HasRelatedEntity) return null;\n\n // Fast path: name field is joined into our record's view\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n const val = this.Record.Get(nameFieldMap);\n if (val != null && val !== '') return String(val);\n }\n\n // Async fallback: resolved via GetEntityRecordName\n if (this._resolvedFKName !== undefined) {\n return this._resolvedFKName;\n }\n\n // Kick off async resolution if not already in flight\n this.resolveFKNameAsync();\n return null; // will render once resolved\n }\n\n /**\n * Whether this FK field should display the related entity name\n * with a hyperlink instead of the raw ID value.\n */\n get IsFKWithNameField(): boolean {\n return this.HasRelatedEntity && this.FKDisplayName != null;\n }\n\n // ---- Async FK name resolution ----\n\n /** Cached result from GetEntityRecordName. undefined = not yet resolved. */\n private _resolvedFKName: string | null | undefined = undefined;\n\n /** Tracks which FK value we resolved so we can invalidate on record change */\n private _resolvedFKValue: unknown = undefined;\n\n /** Whether an async lookup is in flight */\n private _fkNameLoading = false;\n\n /**\n * Asynchronously resolves the display name for an FK field that lacks\n * a RelatedEntityNameFieldMap by calling Metadata.GetEntityRecordName.\n */\n private resolveFKNameAsync(): void {\n if (this._fkNameLoading) return;\n\n const fkValue = this.Value;\n if (fkValue == null || fkValue === '') return;\n\n const fieldInfo = this.FieldInfo;\n if (!fieldInfo?.RelatedEntity || !fieldInfo?.RelatedEntityFieldName) return;\n\n this._fkNameLoading = true;\n this._resolvedFKValue = fkValue;\n\n const pk = new CompositeKey([{\n FieldName: fieldInfo.RelatedEntityFieldName,\n Value: fkValue\n }]);\n\n const md = new Metadata();\n md.GetEntityRecordName(fieldInfo.RelatedEntity, pk)\n .then(name => {\n this._resolvedFKName = name || null;\n this._fkNameLoading = false;\n this.cdr.markForCheck();\n })\n .catch(() => {\n this._resolvedFKName = null;\n this._fkNameLoading = false;\n });\n }\n\n // ============================================\n // DROPDOWN POSITIONING (shared by FK, value list, select)\n // ============================================\n\n /** Calculated position for fixed-position dropdowns */\n DropdownTop = 0;\n DropdownLeft = 0;\n DropdownWidth = 0;\n OpenAbove = false;\n\n /** Cleanup function for scroll/resize listeners */\n private _scrollCleanup: (() => void) | null = null;\n\n /** Inline style for the fixed-position dropdown */\n get DropdownPositionStyle(): Record<string, string> {\n if (this.OpenAbove) {\n return {\n 'position': 'fixed',\n 'bottom': (window.innerHeight - this.DropdownTop) + 'px',\n 'top': 'auto',\n 'left': this.DropdownLeft + 'px',\n 'width': this.DropdownWidth + 'px',\n 'z-index': '10000'\n };\n }\n return {\n 'position': 'fixed',\n 'top': this.DropdownTop + 'px',\n 'bottom': 'auto',\n 'left': this.DropdownLeft + 'px',\n 'width': this.DropdownWidth + 'px',\n 'z-index': '10000'\n };\n }\n\n /** Calculate dropdown position relative to viewport from anchor element */\n private updateDropdownPosition(anchorEl: HTMLElement): void {\n const rect = anchorEl.getBoundingClientRect();\n const dropdownMaxHeight = 240;\n const gap = 4;\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n\n if (spaceBelow < dropdownMaxHeight && spaceAbove > spaceBelow) {\n this.OpenAbove = true;\n this.DropdownTop = rect.top - gap;\n } else {\n this.OpenAbove = false;\n this.DropdownTop = rect.bottom + gap;\n }\n this.DropdownLeft = rect.left;\n this.DropdownWidth = rect.width;\n }\n\n /** Start listening for scroll/resize to close dropdowns */\n private startScrollListener(): void {\n this.stopScrollListener();\n\n const onScroll = () => {\n this.closeAllDropdowns();\n this.cdr.markForCheck();\n };\n const onResize = () => {\n this.closeAllDropdowns();\n this.cdr.markForCheck();\n };\n\n document.addEventListener('scroll', onScroll, true); // capture phase catches all scrollable ancestors\n window.addEventListener('resize', onResize);\n\n this._scrollCleanup = () => {\n document.removeEventListener('scroll', onScroll, true);\n window.removeEventListener('resize', onResize);\n };\n }\n\n /** Remove scroll/resize listeners */\n private stopScrollListener(): void {\n if (this._scrollCleanup) {\n this._scrollCleanup();\n this._scrollCleanup = null;\n }\n }\n\n /** Close all dropdown types */\n private closeAllDropdowns(): void {\n this.ShowFKDropdown = false;\n this.ShowValueListDropdown = false;\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n }\n\n // ============================================\n // FK AUTOCOMPLETE (custom implementation)\n // ============================================\n\n /** Suggestions returned from the FK entity search */\n FKSuggestions: FKSuggestion[] = [];\n\n /** Whether the current FK value is a confirmed match (user selected from dropdown) */\n FKIsMatched = false;\n\n /** Whether the FK dropdown is visible */\n ShowFKDropdown = false;\n\n /** Text the user is currently typing in the FK search input. null = use display name. */\n private _fkInputText: string | null = null;\n\n /** Debounce timer for FK search */\n private _fkSearchTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Last known FK input element for position recalculation */\n private _lastFKInputEl: HTMLElement | null = null;\n\n /** The display text shown in the FK search input */\n get FKSearchText(): string {\n if (this._fkInputText !== null) return this._fkInputText;\n return this.FKDisplayName || '';\n }\n\n /** Handle typing in the FK search input */\n OnFKInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n this._fkInputText = input.value;\n this._lastFKInputEl = input;\n this.FKIsMatched = false;\n\n // Debounce search\n if (this._fkSearchTimeout) clearTimeout(this._fkSearchTimeout);\n this._fkSearchTimeout = setTimeout(() => {\n if (this._fkInputText && this._fkInputText.length >= 1) {\n this.searchRelatedEntity(this._fkInputText);\n } else {\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n }, 300);\n }\n\n /** Show dropdown on focus if suggestions exist */\n OnFKFocus(event: FocusEvent): void {\n const input = event.target as HTMLElement;\n this._lastFKInputEl = input;\n if (this.FKSuggestions.length > 0) {\n this.updateDropdownPosition(input);\n this.startScrollListener();\n this.ShowFKDropdown = true;\n this.cdr.markForCheck();\n }\n }\n\n /** Hide dropdown on blur, revert to matched name if user didn't select */\n OnFKBlur(): void {\n // Small delay so mousedown on dropdown items fires first\n setTimeout(() => {\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n // If user was typing but didn't select, revert to display name\n if (!this.FKIsMatched && this._fkInputText !== null) {\n this._fkInputText = null;\n }\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an item from the FK dropdown */\n OnFKSelectItem(suggestion: FKSuggestion, event: MouseEvent): void {\n event.preventDefault();\n this._fkInputText = suggestion.DisplayName;\n this.Value = suggestion.PrimaryKeyValue;\n this.FKIsMatched = true;\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n\n // Update virtual name field for visual consistency after save\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n this.Record.Set(nameFieldMap, suggestion.DisplayName);\n }\n this.cdr.markForCheck();\n }\n\n /** Clear FK value via the X button */\n OnFKClearClick(event: MouseEvent): void {\n event.preventDefault();\n this.Value = null;\n this._fkInputText = null;\n this.FKIsMatched = false;\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n this._resolvedFKName = undefined;\n this._resolvedFKValue = undefined;\n\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n this.Record.Set(nameFieldMap, '');\n }\n this.cdr.markForCheck();\n }\n\n /**\n * Perform a RunView search on the related entity's name field.\n */\n private async searchRelatedEntity(query: string): Promise<void> {\n const fieldInfo = this.FieldInfo;\n if (!fieldInfo?.RelatedEntity) return;\n\n const md = new Metadata();\n const relatedEntity = md.Entities.find(e => e.Name === fieldInfo.RelatedEntity);\n if (!relatedEntity?.NameField) return;\n\n const nameFieldName = relatedEntity.NameField.Name;\n const pkFieldName = fieldInfo.RelatedEntityFieldName || 'ID';\n const escapedQuery = query.replace(/'/g, \"''\");\n\n const rv = new RunView();\n const result = await rv.RunView<Record<string, unknown>>({\n EntityName: fieldInfo.RelatedEntity,\n ExtraFilter: `[${nameFieldName}] LIKE '%${escapedQuery}%'`,\n MaxRows: 20,\n ResultType: 'simple',\n Fields: [pkFieldName, nameFieldName]\n });\n\n if (result.Success) {\n this.FKSuggestions = result.Results.map(r => ({\n PrimaryKeyValue: r[pkFieldName],\n DisplayName: String(r[nameFieldName] || '')\n }));\n if (this.FKSuggestions.length > 0 && this._lastFKInputEl) {\n this.updateDropdownPosition(this._lastFKInputEl);\n this.startScrollListener();\n }\n this.ShowFKDropdown = this.FKSuggestions.length > 0;\n } else {\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n }\n this.cdr.markForCheck();\n }\n\n // ============================================\n // VALUE LIST AUTOCOMPLETE (for 'autocomplete' type)\n // ============================================\n\n /** Whether the value list dropdown is visible */\n ShowValueListDropdown = false;\n\n /** Current filter text for the value list */\n private _valueListFilter = '';\n\n /** Filtered possible values based on what the user typed */\n get FilteredPossibleValues(): string[] {\n if (!this._valueListFilter) return this.PossibleValues;\n const filter = this._valueListFilter.toLowerCase();\n return this.PossibleValues.filter(v => v.toLowerCase().includes(filter));\n }\n\n /** Handle typing in the value list autocomplete */\n OnValueListInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n this._valueListFilter = input.value;\n this.Value = input.value;\n this.updateDropdownPosition(input);\n if (!this._scrollCleanup) this.startScrollListener();\n this.ShowValueListDropdown = true;\n this.cdr.markForCheck();\n }\n\n /** Show dropdown on focus */\n OnValueListFocus(event: FocusEvent): void {\n const input = event.target as HTMLElement;\n this.updateDropdownPosition(input);\n this.startScrollListener();\n this.ShowValueListDropdown = true;\n this.cdr.markForCheck();\n }\n\n /** Hide dropdown on blur */\n OnValueListBlur(): void {\n setTimeout(() => {\n this.ShowValueListDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an item from the value list dropdown */\n OnValueListSelect(value: string, event: MouseEvent): void {\n event.preventDefault();\n this.Value = value;\n this._valueListFilter = '';\n this.ShowValueListDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n\n // ============================================\n // CUSTOM SELECT DROPDOWN (replaces native <select>)\n // ============================================\n\n /** Whether the custom select dropdown is visible */\n ShowSelectDropdown = false;\n\n /** Toggle the custom select dropdown */\n OnSelectTriggerClick(event: Event): void {\n event.preventDefault();\n if (this.ShowSelectDropdown) {\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n } else {\n const el = event.currentTarget as HTMLElement;\n this.updateDropdownPosition(el);\n this.startScrollListener();\n this.ShowSelectDropdown = true;\n }\n this.cdr.markForCheck();\n }\n\n /** Close the select dropdown on blur */\n OnSelectTriggerBlur(): void {\n setTimeout(() => {\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an option from the custom select dropdown */\n OnSelectOptionClick(value: string, event: MouseEvent): void {\n event.preventDefault();\n this.Value = value;\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n\n // ============================================\n // GENERAL PROPERTIES\n // ============================================\n\n /** Whether the field's varchar(max) - long text that gets markdown rendering */\n get IsLongText(): boolean {\n return this.FieldInfo?.Length === -1;\n }\n\n /** Format a value for display */\n FormatValue(): string {\n const val = this.Value;\n if (val === null || val === undefined) return '';\n if (val instanceof Date) {\n return val.toLocaleString();\n }\n return String(val);\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['FormContext'] || changes['EditMode'] || changes['Record']) {\n // Reset FK state when record changes\n if (changes['Record']) {\n this._fkInputText = null;\n this.FKIsMatched = false;\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this._resolvedFKName = undefined;\n this._resolvedFKValue = undefined;\n this._fkNameLoading = false;\n // Reset validation state for new record\n this._touched = false;\n this._fieldErrors = [];\n }\n // Reset validation state when exiting edit mode\n if (changes['EditMode'] && !this.EditMode) {\n this._touched = false;\n this._fieldErrors = [];\n }\n this.cdr.markForCheck();\n }\n }\n\n ngOnDestroy(): void {\n if (this._fkSearchTimeout) {\n clearTimeout(this._fkSearchTimeout);\n }\n this.stopScrollListener();\n }\n\n // ---- Navigation Handlers ----\n\n /**\n * Handle click on a record FK link in read-only mode.\n */\n OnRecordLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n if (!this.FieldInfo || !this.Record) return;\n const relatedEntityName = this.FieldInfo.RelatedEntity;\n if (!relatedEntityName) return;\n\n const fkValue = this.Value;\n if (!fkValue) return;\n\n // Build a CompositeKey for the FK target record using the related entity's PK field\n const relatedFieldName = this.FieldInfo.RelatedEntityFieldName || 'ID';\n const targetKey = new CompositeKey([new KeyValuePair(relatedFieldName, fkValue)]);\n\n this.Navigate.emit({\n Kind: 'record',\n EntityName: relatedEntityName,\n PrimaryKey: targetKey,\n OpenInNewTab: event.ctrlKey || event.metaKey\n });\n }\n\n /**\n * Handle click on an email link in read-only mode.\n */\n OnEmailLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n const email = this.FormatValue();\n if (!email) return;\n this.Navigate.emit({\n Kind: 'email',\n EmailAddress: email\n });\n }\n\n /**\n * Handle click on a URL link in read-only mode.\n */\n OnUrlLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n const url = this.FormatValue();\n if (!url) return;\n this.Navigate.emit({\n Kind: 'external-link',\n Url: url,\n OpenInNewTab: true\n });\n }\n\n /**\n * Handle value change from a native input.\n */\n OnInputChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.value;\n }\n\n /**\n * Handle value change from a number input.\n */\n OnNumberChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n const num = input.valueAsNumber;\n this.Value = isNaN(num) ? null : num;\n }\n\n /**\n * Handle value change from a date input.\n */\n OnDateChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.value ? new Date(input.value) : null;\n }\n\n /**\n * Handle value change from a checkbox.\n */\n OnCheckboxChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.checked;\n }\n\n /**\n * Get date value formatted for HTML date input.\n */\n get DateInputValue(): string {\n const val = this.Value;\n if (!val) return '';\n const date = val instanceof Date ? val : new Date(String(val));\n if (isNaN(date.getTime())) return '';\n return date.toISOString().split('T')[0];\n }\n}\n","@if (Record && (Record.IsSaved || !IsFieldReadOnly)) {\n <!-- READ-ONLY MODE -->\n @if ((!EditMode || IsFieldReadOnly) && !ShouldHideField) {\n <div class=\"mj-forms-field\" [class.mj-forms-field--readonly]=\"EditMode && IsFieldReadOnly\" [class.mj-forms-field--dirty]=\"IsDirty\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- FK fields with a mapped name field: show the name as a hyperlink -->\n @if (IsFKWithNameField) {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link mj-forms-field-link--fk\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FKDisplayName }}\n </a>\n </span>\n }\n @else {\n @switch (LinkType) {\n @case ('Email') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnEmailLinkClick($event)\" title=\"Send email\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-envelope mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('URL') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnUrlLinkClick($event)\" title=\"Open link\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('Record') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @default {\n @if (Type === 'checkbox') {\n <span class=\"mj-forms-field-value\">\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\" [checked]=\"!!Value\" disabled>\n </div>\n </span>\n }\n @else if (IsLongText) {\n <span class=\"mj-forms-field-value mj-forms-field-value--long\">{{ FormatValue() }}</span>\n }\n @else {\n <span class=\"mj-forms-field-value\">{{ FormatValue() }}</span>\n }\n }\n }\n }\n </div>\n </div>\n }\n\n <!-- EDIT MODE -->\n @if (EditMode && !IsFieldReadOnly) {\n <div class=\"mj-forms-field mj-forms-field--editing\" [class.mj-forms-field--dirty]=\"IsDirty\" [class.mj-forms-field--required-empty]=\"IsRequiredEmpty\" [class.mj-forms-field--has-error]=\"ShowErrors\" [class.mj-forms-field--has-warning]=\"ShowWarnings\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- Foreign Key fields get custom search autocomplete -->\n @if (HasRelatedEntity) {\n <div class=\"mj-fk-search\" [class.mj-fk-search--matched]=\"FKIsMatched\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FKSearchText\"\n (input)=\"OnFKInput($event)\"\n (focus)=\"OnFKFocus($event)\"\n (blur)=\"OnFKBlur()\"\n placeholder=\"Search...\">\n @if (FKSearchText) {\n <button class=\"mj-fk-clear\" (mousedown)=\"OnFKClearClick($event)\" title=\"Clear\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n } @else {\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n }\n @if (ShowFKDropdown && FKSuggestions.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (suggestion of FKSuggestions; track suggestion.PrimaryKeyValue) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnFKSelectItem(suggestion, $event)\">\n {{ suggestion.DisplayName }}\n </div>\n }\n </div>\n }\n </div>\n }\n @else {\n @switch (Type) {\n @case ('textbox') {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (input)=\"OnInputChange($event)\">\n }\n @case ('textarea') {\n <textarea\n class=\"mj-forms-field-input mj-forms-field-input--textarea\"\n [value]=\"FormatValue()\"\n (input)=\"OnInputChange($event)\"></textarea>\n }\n @case ('number') {\n <input type=\"number\"\n class=\"mj-forms-field-input mj-forms-field-input--number\"\n [value]=\"Value\"\n (change)=\"OnNumberChange($event)\">\n }\n @case ('datepicker') {\n <input type=\"date\"\n class=\"mj-forms-field-input mj-forms-field-input--date\"\n [value]=\"DateInputValue\"\n (change)=\"OnDateChange($event)\">\n }\n @case ('checkbox') {\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\"\n [checked]=\"!!Value\"\n (change)=\"OnCheckboxChange($event)\">\n </div>\n }\n @case ('select') {\n <div class=\"mj-custom-select-trigger\"\n tabindex=\"0\"\n (click)=\"OnSelectTriggerClick($event)\"\n (blur)=\"OnSelectTriggerBlur()\">\n <span class=\"mj-custom-select-value\" [class.mj-custom-select-value--placeholder]=\"!FormatValue()\">\n {{ FormatValue() || '-- Select --' }}\n </span>\n <i class=\"fa-solid fa-chevron-down mj-custom-select-chevron\" [class.mj-custom-select-chevron--open]=\"ShowSelectDropdown\"></i>\n </div>\n @if (ShowSelectDropdown && PossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of PossibleValues; track option) {\n <div class=\"mj-fk-option\" [class.mj-fk-option--selected]=\"FormatValue() === option\" (mousedown)=\"OnSelectOptionClick(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n }\n @case ('autocomplete') {\n <div class=\"mj-fk-search\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (input)=\"OnValueListInput($event)\"\n (focus)=\"OnValueListFocus($event)\"\n (blur)=\"OnValueListBlur()\"\n placeholder=\"Type to search...\">\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n @if (ShowValueListDropdown && FilteredPossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of FilteredPossibleValues; track option) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnValueListSelect(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n </div>\n }\n @default {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (change)=\"OnInputChange($event)\">\n }\n }\n }\n </div>\n <!-- Inline validation messages -->\n @if (DisplayErrors.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--error\">\n @for (error of DisplayErrors; track error.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n <span>{{ error.Message }}</span>\n </div>\n }\n </div>\n }\n @if (DisplayWarnings.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--warning\">\n @for (warning of DisplayWarnings; track warning.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>{{ warning.Message }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n}\n"]}
@@ -13,6 +13,8 @@ export declare class FormStateService {
13
13
  private loadedEntities;
14
14
  /** Track loading promises to prevent duplicate loads */
15
15
  private loadingPromises;
16
+ /** Track which entities are currently in edit mode (saves suppressed) */
17
+ private editingEntities;
16
18
  private metadata;
17
19
  /**
18
20
  * Get the observable state for an entity.
@@ -144,6 +146,15 @@ export declare class FormStateService {
144
146
  * @returns True if custom order exists
145
147
  */
146
148
  hasCustomSectionOrder(entityName: string): boolean;
149
+ /**
150
+ * Set edit mode for an entity. While in edit mode, state changes update
151
+ * the in-memory BehaviorSubject (so the UI stays reactive) but skip
152
+ * database persistence. When edit mode ends, a single save is queued
153
+ * to persist the final layout state.
154
+ * @param entityName The entity name
155
+ * @param editing Whether the form is entering (true) or exiting (false) edit mode
156
+ */
157
+ setEditMode(entityName: string, editing: boolean): void;
147
158
  /**
148
159
  * Get the count of expanded sections.
149
160
  * @param entityName The entity name
@@ -169,6 +180,8 @@ export declare class FormStateService {
169
180
  private loadState;
170
181
  /**
171
182
  * Queue a debounced save using UserInfoEngine's centralized debounce.
183
+ * Skipped when the entity is in edit mode to avoid persisting transient
184
+ * layout changes made while editing a record.
172
185
  */
173
186
  private queueSave;
174
187
  static ɵfac: i0.ɵɵFactoryDeclaration<FormStateService, never>;
@@ -1 +1 @@
1
- {"version":3,"file":"form-state.service.d.ts","sourceRoot":"","sources":["../../src/lib/form-state.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"form-state.service.d.ts","sourceRoot":"","sources":["../../src/lib/form-state.service.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,8 @@ export class FormStateService {
17
17
  loadedEntities = new Set();
18
18
  /** Track loading promises to prevent duplicate loads */
19
19
  loadingPromises = new Map();
20
+ /** Track which entities are currently in edit mode (saves suppressed) */
21
+ editingEntities = new Set();
20
22
  metadata = new Metadata();
21
23
  /**
22
24
  * Get the observable state for an entity.
@@ -270,6 +272,24 @@ export class FormStateService {
270
272
  const order = this.getSectionOrder(entityName);
271
273
  return order !== undefined && order.length > 0;
272
274
  }
275
+ /**
276
+ * Set edit mode for an entity. While in edit mode, state changes update
277
+ * the in-memory BehaviorSubject (so the UI stays reactive) but skip
278
+ * database persistence. When edit mode ends, a single save is queued
279
+ * to persist the final layout state.
280
+ * @param entityName The entity name
281
+ * @param editing Whether the form is entering (true) or exiting (false) edit mode
282
+ */
283
+ setEditMode(entityName, editing) {
284
+ if (editing) {
285
+ this.editingEntities.add(entityName);
286
+ }
287
+ else {
288
+ this.editingEntities.delete(entityName);
289
+ // Persist the final state once on exit
290
+ this.queueSave(entityName);
291
+ }
292
+ }
273
293
  /**
274
294
  * Get the count of expanded sections.
275
295
  * @param entityName The entity name
@@ -352,8 +372,13 @@ export class FormStateService {
352
372
  }
353
373
  /**
354
374
  * Queue a debounced save using UserInfoEngine's centralized debounce.
375
+ * Skipped when the entity is in edit mode to avoid persisting transient
376
+ * layout changes made while editing a record.
355
377
  */
356
378
  queueSave(entityName) {
379
+ if (this.editingEntities.has(entityName)) {
380
+ return;
381
+ }
357
382
  const userId = this.metadata.CurrentUser?.ID;
358
383
  if (!userId) {
359
384
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"form-state.service.js","sourceRoot":"","sources":["../../src/lib/form-state.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { Metadata } from '@memberjunction/core';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { FormState, FormSectionState, DEFAULT_FORM_STATE, DEFAULT_SECTION_STATE } from './form-state.interface';\n\nconst SETTING_KEY_PREFIX = 'Form.State.';\n\n/**\n * Service for managing form state persistence per entity.\n * State is stored in the User Settings entity and shared reactively\n * across all form instances for the same entity.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class FormStateService {\n /** Cache of BehaviorSubjects per entity name */\n private stateCache = new Map<string, BehaviorSubject<FormState>>();\n\n /** Track which entities have been loaded from DB */\n private loadedEntities = new Set<string>();\n\n /** Track loading promises to prevent duplicate loads */\n private loadingPromises = new Map<string, Promise<void>>();\n\n private metadata = new Metadata();\n\n /**\n * Get the observable state for an entity.\n * Automatically loads from User Settings on first access.\n * @param entityName The entity name\n * @returns Observable of the form state\n */\n getState$(entityName: string): Observable<FormState> {\n return this.getOrCreateSubject(entityName).asObservable();\n }\n\n /**\n * Get the current state value for an entity.\n * @param entityName The entity name\n * @returns Current form state\n */\n getCurrentState(entityName: string): FormState {\n return this.getOrCreateSubject(entityName).value;\n }\n\n /**\n * Initialize state for an entity by loading from User Settings.\n * Call this when a form component initializes.\n * @param entityName The entity name\n */\n async initializeState(entityName: string): Promise<FormState> {\n // If already loaded, return current state\n if (this.loadedEntities.has(entityName)) {\n return this.getCurrentState(entityName);\n }\n\n // If currently loading, wait for that promise\n const existingPromise = this.loadingPromises.get(entityName);\n if (existingPromise) {\n await existingPromise;\n return this.getCurrentState(entityName);\n }\n\n // Start loading\n const loadPromise = this.loadState(entityName);\n this.loadingPromises.set(entityName, loadPromise);\n\n try {\n await loadPromise;\n this.loadedEntities.add(entityName);\n return this.getCurrentState(entityName);\n } finally {\n this.loadingPromises.delete(entityName);\n }\n }\n\n /**\n * Get section state, returning defaults if section doesn't exist yet.\n * @param entityName The entity name\n * @param sectionKey The section key\n * @returns Section state with defaults applied\n */\n getSectionState(entityName: string, sectionKey: string): FormSectionState {\n const state = this.getCurrentState(entityName);\n return state.sections[sectionKey] || { ...DEFAULT_SECTION_STATE };\n }\n\n /**\n * Check if a section is expanded.\n * @param entityName The entity name\n * @param sectionKey The section key\n * @param defaultExpanded Optional default value to use when no persisted state exists (defaults to DEFAULT_SECTION_STATE.isExpanded)\n * @returns True if expanded\n */\n isSectionExpanded(entityName: string, sectionKey: string, defaultExpanded?: boolean): boolean {\n const state = this.getCurrentState(entityName);\n const sectionState = state.sections[sectionKey];\n if (sectionState) {\n return sectionState.isExpanded;\n }\n // No persisted state - use provided default or fall back to DEFAULT_SECTION_STATE\n return defaultExpanded !== undefined ? defaultExpanded : DEFAULT_SECTION_STATE.isExpanded;\n }\n\n /**\n * Set section expanded state.\n * @param entityName The entity name\n * @param sectionKey The section key\n * @param isExpanded Whether the section is expanded\n */\n setSectionExpanded(entityName: string, sectionKey: string, isExpanded: boolean): void {\n this.updateSectionState(entityName, sectionKey, { isExpanded });\n }\n\n /**\n * Get the persisted panel height for a section.\n * @param entityName The entity name\n * @param sectionKey The section key\n * @returns Panel height in pixels, or undefined if no custom height is set\n */\n getSectionPanelHeight(entityName: string, sectionKey: string): number | undefined {\n const state = this.getCurrentState(entityName);\n return state.sections[sectionKey]?.panelHeight;\n }\n\n /**\n * Set the panel height for a section (persisted to User Settings).\n * @param entityName The entity name\n * @param sectionKey The section key\n * @param height Panel height in pixels\n */\n setSectionPanelHeight(entityName: string, sectionKey: string, height: number): void {\n this.updateSectionState(entityName, sectionKey, { panelHeight: height });\n }\n\n /**\n * Toggle section expanded state.\n * @param entityName The entity name\n * @param sectionKey The section key\n */\n toggleSection(entityName: string, sectionKey: string): void {\n const current = this.isSectionExpanded(entityName, sectionKey);\n this.setSectionExpanded(entityName, sectionKey, !current);\n }\n\n /**\n * Get form width mode.\n * @param entityName The entity name\n * @returns Width mode ('centered' or 'full-width')\n */\n getWidthMode(entityName: string): 'centered' | 'full-width' {\n return this.getCurrentState(entityName).widthMode;\n }\n\n /**\n * Set form width mode.\n * @param entityName The entity name\n * @param widthMode The width mode\n */\n setWidthMode(entityName: string, widthMode: 'centered' | 'full-width'): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const newState: FormState = {\n ...currentState,\n widthMode\n };\n subject.next(newState);\n this.queueSave(entityName);\n }\n\n /**\n * Toggle form width mode between centered and full-width.\n * @param entityName The entity name\n */\n toggleWidthMode(entityName: string): void {\n const current = this.getWidthMode(entityName);\n this.setWidthMode(entityName, current === 'centered' ? 'full-width' : 'centered');\n }\n\n /**\n * Get showEmptyFields preference for an entity.\n * @param entityName The entity name\n * @returns Whether to show empty fields\n */\n getShowEmptyFields(entityName: string): boolean {\n return this.getCurrentState(entityName).showEmptyFields;\n }\n\n /**\n * Set showEmptyFields preference for an entity.\n * @param entityName The entity name\n * @param show Whether to show empty fields\n */\n setShowEmptyFields(entityName: string, show: boolean): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const newState: FormState = {\n ...currentState,\n showEmptyFields: show\n };\n subject.next(newState);\n this.queueSave(entityName);\n }\n\n /**\n * Expand all sections for an entity.\n * @param entityName The entity name\n * @param sectionKeys Array of all section keys to expand\n */\n expandAllSections(entityName: string, sectionKeys: string[]): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const newSections = { ...currentState.sections };\n\n for (const key of sectionKeys) {\n newSections[key] = {\n ...DEFAULT_SECTION_STATE,\n ...newSections[key],\n isExpanded: true\n };\n }\n\n subject.next({ ...currentState, sections: newSections });\n this.queueSave(entityName);\n }\n\n /**\n * Collapse all sections for an entity.\n * @param entityName The entity name\n * @param sectionKeys Array of all section keys to collapse\n */\n collapseAllSections(entityName: string, sectionKeys: string[]): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const newSections = { ...currentState.sections };\n\n for (const key of sectionKeys) {\n newSections[key] = {\n ...DEFAULT_SECTION_STATE,\n ...newSections[key],\n isExpanded: false\n };\n }\n\n subject.next({ ...currentState, sections: newSections });\n this.queueSave(entityName);\n }\n\n /**\n * Reset state to defaults for an entity.\n * @param entityName The entity name\n */\n resetToDefaults(entityName: string): void {\n const subject = this.getOrCreateSubject(entityName);\n subject.next({ ...DEFAULT_FORM_STATE });\n this.queueSave(entityName);\n }\n\n /**\n * Get the custom section order for an entity.\n * @param entityName The entity name\n * @returns Array of section keys in user's preferred order, or undefined if using default order\n */\n getSectionOrder(entityName: string): string[] | undefined {\n return this.getCurrentState(entityName).sectionOrder;\n }\n\n /**\n * Set the custom section order for an entity.\n * @param entityName The entity name\n * @param sectionOrder Array of section keys in the desired order\n */\n setSectionOrder(entityName: string, sectionOrder: string[]): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const newState: FormState = {\n ...currentState,\n sectionOrder\n };\n subject.next(newState);\n this.queueSave(entityName);\n }\n\n /**\n * Reset the section order to default (removes custom ordering).\n * @param entityName The entity name\n */\n resetSectionOrder(entityName: string): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const { sectionOrder: _, ...stateWithoutOrder } = currentState;\n subject.next(stateWithoutOrder as FormState);\n this.queueSave(entityName);\n }\n\n /**\n * Check if a custom section order exists for an entity.\n * @param entityName The entity name\n * @returns True if custom order exists\n */\n hasCustomSectionOrder(entityName: string): boolean {\n const order = this.getSectionOrder(entityName);\n return order !== undefined && order.length > 0;\n }\n\n /**\n * Get the count of expanded sections.\n * @param entityName The entity name\n * @param sectionKeys Array of section keys to check\n * @returns Number of expanded sections\n */\n getExpandedCount(entityName: string, sectionKeys: string[]): number {\n const state = this.getCurrentState(entityName);\n return sectionKeys.filter(key => {\n const section = state.sections[key];\n return section ? section.isExpanded : DEFAULT_SECTION_STATE.isExpanded;\n }).length;\n }\n\n // -------------------- Private Methods --------------------\n\n /**\n * Get or create the BehaviorSubject for an entity.\n */\n private getOrCreateSubject(entityName: string): BehaviorSubject<FormState> {\n let subject = this.stateCache.get(entityName);\n if (!subject) {\n subject = new BehaviorSubject<FormState>({ ...DEFAULT_FORM_STATE });\n this.stateCache.set(entityName, subject);\n }\n return subject;\n }\n\n /**\n * Update a single section's state.\n */\n private updateSectionState(entityName: string, sectionKey: string, updates: Partial<FormSectionState>): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const currentSection = currentState.sections[sectionKey] || { ...DEFAULT_SECTION_STATE };\n\n const newState: FormState = {\n ...currentState,\n sections: {\n ...currentState.sections,\n [sectionKey]: {\n ...currentSection,\n ...updates\n }\n }\n };\n\n subject.next(newState);\n this.queueSave(entityName);\n }\n\n /**\n * Generate the User Settings key for an entity.\n */\n private getSettingKey(entityName: string): string {\n return `${SETTING_KEY_PREFIX}${entityName}`;\n }\n\n /**\n * Load state from User Settings using UserInfoEngine for cached access.\n */\n private async loadState(entityName: string): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) {\n return;\n }\n\n const settingKey = this.getSettingKey(entityName);\n const engine = UserInfoEngine.Instance;\n\n // Find setting from cached user settings\n const setting = engine.UserSettings.find(s => s.Setting === settingKey);\n\n const subject = this.getOrCreateSubject(entityName);\n\n if (setting?.Value) {\n const savedState = JSON.parse(setting.Value) as Partial<FormState>;\n // Merge with defaults to handle new properties\n subject.next({ ...DEFAULT_FORM_STATE, ...savedState });\n } else {\n // No saved state, use defaults\n subject.next({ ...DEFAULT_FORM_STATE });\n }\n } catch (error) {\n console.warn(`Failed to load form state for ${entityName}:`, error);\n // Keep default state on error\n }\n }\n\n /**\n * Queue a debounced save using UserInfoEngine's centralized debounce.\n */\n private queueSave(entityName: string): void {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) {\n return;\n }\n\n const settingKey = this.getSettingKey(entityName);\n const state = this.getCurrentState(entityName);\n UserInfoEngine.Instance.SetSettingDebounced(settingKey, JSON.stringify(state));\n }\n}\n"]}
1
+ {"version":3,"file":"form-state.service.js","sourceRoot":"","sources":["../../src/lib/form-state.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { Metadata } from '@memberjunction/core';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { FormState, FormSectionState, DEFAULT_FORM_STATE, DEFAULT_SECTION_STATE } from './form-state.interface';\n\nconst SETTING_KEY_PREFIX = 'Form.State.';\n\n/**\n * Service for managing form state persistence per entity.\n * State is stored in the User Settings entity and shared reactively\n * across all form instances for the same entity.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class FormStateService {\n /** Cache of BehaviorSubjects per entity name */\n private stateCache = new Map<string, BehaviorSubject<FormState>>();\n\n /** Track which entities have been loaded from DB */\n private loadedEntities = new Set<string>();\n\n /** Track loading promises to prevent duplicate loads */\n private loadingPromises = new Map<string, Promise<void>>();\n\n /** Track which entities are currently in edit mode (saves suppressed) */\n private editingEntities = new Set<string>();\n\n private metadata = new Metadata();\n\n /**\n * Get the observable state for an entity.\n * Automatically loads from User Settings on first access.\n * @param entityName The entity name\n * @returns Observable of the form state\n */\n getState$(entityName: string): Observable<FormState> {\n return this.getOrCreateSubject(entityName).asObservable();\n }\n\n /**\n * Get the current state value for an entity.\n * @param entityName The entity name\n * @returns Current form state\n */\n getCurrentState(entityName: string): FormState {\n return this.getOrCreateSubject(entityName).value;\n }\n\n /**\n * Initialize state for an entity by loading from User Settings.\n * Call this when a form component initializes.\n * @param entityName The entity name\n */\n async initializeState(entityName: string): Promise<FormState> {\n // If already loaded, return current state\n if (this.loadedEntities.has(entityName)) {\n return this.getCurrentState(entityName);\n }\n\n // If currently loading, wait for that promise\n const existingPromise = this.loadingPromises.get(entityName);\n if (existingPromise) {\n await existingPromise;\n return this.getCurrentState(entityName);\n }\n\n // Start loading\n const loadPromise = this.loadState(entityName);\n this.loadingPromises.set(entityName, loadPromise);\n\n try {\n await loadPromise;\n this.loadedEntities.add(entityName);\n return this.getCurrentState(entityName);\n } finally {\n this.loadingPromises.delete(entityName);\n }\n }\n\n /**\n * Get section state, returning defaults if section doesn't exist yet.\n * @param entityName The entity name\n * @param sectionKey The section key\n * @returns Section state with defaults applied\n */\n getSectionState(entityName: string, sectionKey: string): FormSectionState {\n const state = this.getCurrentState(entityName);\n return state.sections[sectionKey] || { ...DEFAULT_SECTION_STATE };\n }\n\n /**\n * Check if a section is expanded.\n * @param entityName The entity name\n * @param sectionKey The section key\n * @param defaultExpanded Optional default value to use when no persisted state exists (defaults to DEFAULT_SECTION_STATE.isExpanded)\n * @returns True if expanded\n */\n isSectionExpanded(entityName: string, sectionKey: string, defaultExpanded?: boolean): boolean {\n const state = this.getCurrentState(entityName);\n const sectionState = state.sections[sectionKey];\n if (sectionState) {\n return sectionState.isExpanded;\n }\n // No persisted state - use provided default or fall back to DEFAULT_SECTION_STATE\n return defaultExpanded !== undefined ? defaultExpanded : DEFAULT_SECTION_STATE.isExpanded;\n }\n\n /**\n * Set section expanded state.\n * @param entityName The entity name\n * @param sectionKey The section key\n * @param isExpanded Whether the section is expanded\n */\n setSectionExpanded(entityName: string, sectionKey: string, isExpanded: boolean): void {\n this.updateSectionState(entityName, sectionKey, { isExpanded });\n }\n\n /**\n * Get the persisted panel height for a section.\n * @param entityName The entity name\n * @param sectionKey The section key\n * @returns Panel height in pixels, or undefined if no custom height is set\n */\n getSectionPanelHeight(entityName: string, sectionKey: string): number | undefined {\n const state = this.getCurrentState(entityName);\n return state.sections[sectionKey]?.panelHeight;\n }\n\n /**\n * Set the panel height for a section (persisted to User Settings).\n * @param entityName The entity name\n * @param sectionKey The section key\n * @param height Panel height in pixels\n */\n setSectionPanelHeight(entityName: string, sectionKey: string, height: number): void {\n this.updateSectionState(entityName, sectionKey, { panelHeight: height });\n }\n\n /**\n * Toggle section expanded state.\n * @param entityName The entity name\n * @param sectionKey The section key\n */\n toggleSection(entityName: string, sectionKey: string): void {\n const current = this.isSectionExpanded(entityName, sectionKey);\n this.setSectionExpanded(entityName, sectionKey, !current);\n }\n\n /**\n * Get form width mode.\n * @param entityName The entity name\n * @returns Width mode ('centered' or 'full-width')\n */\n getWidthMode(entityName: string): 'centered' | 'full-width' {\n return this.getCurrentState(entityName).widthMode;\n }\n\n /**\n * Set form width mode.\n * @param entityName The entity name\n * @param widthMode The width mode\n */\n setWidthMode(entityName: string, widthMode: 'centered' | 'full-width'): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const newState: FormState = {\n ...currentState,\n widthMode\n };\n subject.next(newState);\n this.queueSave(entityName);\n }\n\n /**\n * Toggle form width mode between centered and full-width.\n * @param entityName The entity name\n */\n toggleWidthMode(entityName: string): void {\n const current = this.getWidthMode(entityName);\n this.setWidthMode(entityName, current === 'centered' ? 'full-width' : 'centered');\n }\n\n /**\n * Get showEmptyFields preference for an entity.\n * @param entityName The entity name\n * @returns Whether to show empty fields\n */\n getShowEmptyFields(entityName: string): boolean {\n return this.getCurrentState(entityName).showEmptyFields;\n }\n\n /**\n * Set showEmptyFields preference for an entity.\n * @param entityName The entity name\n * @param show Whether to show empty fields\n */\n setShowEmptyFields(entityName: string, show: boolean): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const newState: FormState = {\n ...currentState,\n showEmptyFields: show\n };\n subject.next(newState);\n this.queueSave(entityName);\n }\n\n /**\n * Expand all sections for an entity.\n * @param entityName The entity name\n * @param sectionKeys Array of all section keys to expand\n */\n expandAllSections(entityName: string, sectionKeys: string[]): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const newSections = { ...currentState.sections };\n\n for (const key of sectionKeys) {\n newSections[key] = {\n ...DEFAULT_SECTION_STATE,\n ...newSections[key],\n isExpanded: true\n };\n }\n\n subject.next({ ...currentState, sections: newSections });\n this.queueSave(entityName);\n }\n\n /**\n * Collapse all sections for an entity.\n * @param entityName The entity name\n * @param sectionKeys Array of all section keys to collapse\n */\n collapseAllSections(entityName: string, sectionKeys: string[]): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const newSections = { ...currentState.sections };\n\n for (const key of sectionKeys) {\n newSections[key] = {\n ...DEFAULT_SECTION_STATE,\n ...newSections[key],\n isExpanded: false\n };\n }\n\n subject.next({ ...currentState, sections: newSections });\n this.queueSave(entityName);\n }\n\n /**\n * Reset state to defaults for an entity.\n * @param entityName The entity name\n */\n resetToDefaults(entityName: string): void {\n const subject = this.getOrCreateSubject(entityName);\n subject.next({ ...DEFAULT_FORM_STATE });\n this.queueSave(entityName);\n }\n\n /**\n * Get the custom section order for an entity.\n * @param entityName The entity name\n * @returns Array of section keys in user's preferred order, or undefined if using default order\n */\n getSectionOrder(entityName: string): string[] | undefined {\n return this.getCurrentState(entityName).sectionOrder;\n }\n\n /**\n * Set the custom section order for an entity.\n * @param entityName The entity name\n * @param sectionOrder Array of section keys in the desired order\n */\n setSectionOrder(entityName: string, sectionOrder: string[]): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const newState: FormState = {\n ...currentState,\n sectionOrder\n };\n subject.next(newState);\n this.queueSave(entityName);\n }\n\n /**\n * Reset the section order to default (removes custom ordering).\n * @param entityName The entity name\n */\n resetSectionOrder(entityName: string): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const { sectionOrder: _, ...stateWithoutOrder } = currentState;\n subject.next(stateWithoutOrder as FormState);\n this.queueSave(entityName);\n }\n\n /**\n * Check if a custom section order exists for an entity.\n * @param entityName The entity name\n * @returns True if custom order exists\n */\n hasCustomSectionOrder(entityName: string): boolean {\n const order = this.getSectionOrder(entityName);\n return order !== undefined && order.length > 0;\n }\n\n /**\n * Set edit mode for an entity. While in edit mode, state changes update\n * the in-memory BehaviorSubject (so the UI stays reactive) but skip\n * database persistence. When edit mode ends, a single save is queued\n * to persist the final layout state.\n * @param entityName The entity name\n * @param editing Whether the form is entering (true) or exiting (false) edit mode\n */\n setEditMode(entityName: string, editing: boolean): void {\n if (editing) {\n this.editingEntities.add(entityName);\n } else {\n this.editingEntities.delete(entityName);\n // Persist the final state once on exit\n this.queueSave(entityName);\n }\n }\n\n /**\n * Get the count of expanded sections.\n * @param entityName The entity name\n * @param sectionKeys Array of section keys to check\n * @returns Number of expanded sections\n */\n getExpandedCount(entityName: string, sectionKeys: string[]): number {\n const state = this.getCurrentState(entityName);\n return sectionKeys.filter(key => {\n const section = state.sections[key];\n return section ? section.isExpanded : DEFAULT_SECTION_STATE.isExpanded;\n }).length;\n }\n\n // -------------------- Private Methods --------------------\n\n /**\n * Get or create the BehaviorSubject for an entity.\n */\n private getOrCreateSubject(entityName: string): BehaviorSubject<FormState> {\n let subject = this.stateCache.get(entityName);\n if (!subject) {\n subject = new BehaviorSubject<FormState>({ ...DEFAULT_FORM_STATE });\n this.stateCache.set(entityName, subject);\n }\n return subject;\n }\n\n /**\n * Update a single section's state.\n */\n private updateSectionState(entityName: string, sectionKey: string, updates: Partial<FormSectionState>): void {\n const subject = this.getOrCreateSubject(entityName);\n const currentState = subject.value;\n const currentSection = currentState.sections[sectionKey] || { ...DEFAULT_SECTION_STATE };\n\n const newState: FormState = {\n ...currentState,\n sections: {\n ...currentState.sections,\n [sectionKey]: {\n ...currentSection,\n ...updates\n }\n }\n };\n\n subject.next(newState);\n this.queueSave(entityName);\n }\n\n /**\n * Generate the User Settings key for an entity.\n */\n private getSettingKey(entityName: string): string {\n return `${SETTING_KEY_PREFIX}${entityName}`;\n }\n\n /**\n * Load state from User Settings using UserInfoEngine for cached access.\n */\n private async loadState(entityName: string): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) {\n return;\n }\n\n const settingKey = this.getSettingKey(entityName);\n const engine = UserInfoEngine.Instance;\n\n // Find setting from cached user settings\n const setting = engine.UserSettings.find(s => s.Setting === settingKey);\n\n const subject = this.getOrCreateSubject(entityName);\n\n if (setting?.Value) {\n const savedState = JSON.parse(setting.Value) as Partial<FormState>;\n // Merge with defaults to handle new properties\n subject.next({ ...DEFAULT_FORM_STATE, ...savedState });\n } else {\n // No saved state, use defaults\n subject.next({ ...DEFAULT_FORM_STATE });\n }\n } catch (error) {\n console.warn(`Failed to load form state for ${entityName}:`, error);\n // Keep default state on error\n }\n }\n\n /**\n * Queue a debounced save using UserInfoEngine's centralized debounce.\n * Skipped when the entity is in edit mode to avoid persisting transient\n * layout changes made while editing a record.\n */\n private queueSave(entityName: string): void {\n if (this.editingEntities.has(entityName)) {\n return;\n }\n\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) {\n return;\n }\n\n const settingKey = this.getSettingKey(entityName);\n const state = this.getCurrentState(entityName);\n UserInfoEngine.Instance.SetSettingDebounced(settingKey, JSON.stringify(state));\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-base-forms",
3
- "version": "5.4.1",
3
+ "version": "5.6.0",
4
4
  "description": "MemberJunction: Generic Angular form components for rendering and editing entity records. Provides configurable toolbar, modern form fields (PrimeNG unstyled), collapsible panels with IS-A inheritance support, and event-driven navigation. Zero Explorer dependencies - usable in any Angular application.",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -36,13 +36,13 @@
36
36
  "primeng": "21.1.1"
37
37
  },
38
38
  "dependencies": {
39
- "@memberjunction/core": "5.4.1",
40
- "@memberjunction/core-entities": "5.4.1",
41
- "@memberjunction/global": "5.4.1",
42
- "@memberjunction/ng-base-types": "5.4.1",
43
- "@memberjunction/ng-list-management": "5.4.1",
44
- "@memberjunction/ng-record-changes": "5.4.1",
45
- "@memberjunction/ng-entity-viewer": "5.4.1",
39
+ "@memberjunction/core": "5.6.0",
40
+ "@memberjunction/core-entities": "5.6.0",
41
+ "@memberjunction/global": "5.6.0",
42
+ "@memberjunction/ng-base-types": "5.6.0",
43
+ "@memberjunction/ng-list-management": "5.6.0",
44
+ "@memberjunction/ng-record-changes": "5.6.0",
45
+ "@memberjunction/ng-entity-viewer": "5.6.0",
46
46
  "rxjs": "^7.8.2",
47
47
  "tslib": "^2.8.1"
48
48
  },