@memberjunction/ng-record-changes 5.27.1 → 5.28.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":"ng-record-changes.component.js","sourceRoot":"","sources":["../../src/lib/ng-record-changes.component.ts","../../src/lib/ng-record-changes.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, Input, OnInit, Output, ChangeDetectorRef, ChangeDetectionStrategy, ViewEncapsulation, NgZone } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { BaseEntity, CompositeKey, EntityFieldInfo, EntityFieldTSType, Metadata, RunView } from '@memberjunction/core';\nimport { MJRecordChangeEntity } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { diffChars, diffWords, Change } from 'diff';\n\n/** Lightweight shape for displaying a version label associated with this record */\ninterface RecordLabel {\n ID: string;\n Name: string;\n Description: string | null;\n Scope: string;\n Status: string;\n CreatedAt: Date;\n ItemCount: number;\n}\n\n/**\n * Event payload emitted when the user requests to restore a previous version.\n * The parent component is responsible for applying the old field values and saving.\n */\nexport interface RestoreVersionEvent {\n /** The ID of the MJ: Record Changes record being restored */\n VersionID: string;\n /** When the version was created */\n ChangedAt: Date;\n /** User who made the change */\n ChangedByUser: string;\n /** Map of field name to old/new values from this change */\n FieldChanges: Record<string, { OldValue: unknown; NewValue: unknown }>;\n}\n\n/** A single field change with type-aware rendering info */\nexport interface FieldChangeInfo {\n field: string;\n displayName: string;\n oldValue: string;\n newValue: string;\n fieldType: 'boolean' | 'date' | 'number' | 'text';\n diffHtml?: SafeHtml;\n}\n\n/** A single field in the restore preview, comparing version value vs current record value */\nexport interface RestoreFieldDiff {\n FieldName: string;\n DisplayName: string;\n VersionValue: string;\n CurrentValue: string;\n IsChanged: boolean;\n}\n\n/** A group of changes that share the same date */\nexport interface DateGroup {\n label: string;\n changes: MJRecordChangeEntity[];\n}\n\n@Component({\n standalone: false,\n selector: 'mj-record-changes',\n templateUrl: './ng-record-changes.component.html',\n styleUrls: ['./ng-record-changes.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None\n})\nexport class RecordChangesComponent implements OnInit {\n public IsLoading = false;\n public IsVisible = false;\n @Output() dialogClosed = new EventEmitter();\n @Input() record!: BaseEntity;\n\n /** Whether to show a \"Restore\" button on each historical version row. Default false. */\n @Input() AllowRestore = false;\n\n /**\n * Emitted when the user clicks Restore on a historical version.\n * The parent is responsible for loading old values into the record and saving.\n */\n @Output() RestoreRequested = new EventEmitter<RestoreVersionEvent>();\n\n viewData: MJRecordChangeEntity[] = [];\n filteredData: MJRecordChangeEntity[] = [];\n dateGroups: DateGroup[] = [];\n expandedItems: Set<string> = new Set();\n\n /** The change record being previewed for restore, or null if no preview is active */\n RestorePreview: MJRecordChangeEntity | null = null;\n\n /** Parsed field-level diff for the restore preview */\n RestorePreviewFields: RestoreFieldDiff[] = [];\n\n /** Whether the restore operation is in progress */\n IsRestoring = false;\n\n // Version label state\n RecordLabels: RecordLabel[] = [];\n IsLoadingLabels = false;\n ShowCreateWizard = false;\n\n // Filter properties\n searchTerm = '';\n selectedType = '';\n selectedSource = '';\n\n constructor(\n private cdr: ChangeDetectorRef,\n private ngZone: NgZone,\n private mjNotificationService: MJNotificationService,\n private sanitizer: DomSanitizer\n ) {}\n\n ngOnInit(): void {\n if (this.record) {\n this.IsLoading = true;\n this.IsVisible = true;\n this.cdr.markForCheck();\n this.LoadRecordChanges(this.record.PrimaryKey, '', this.record.EntityInfo.Name);\n this.LoadRecordLabels();\n }\n }\n\n /**\n * Reloads the record changes list from the database.\n * Called by the parent container after a save completes while the drawer is open.\n */\n public Refresh(): void {\n if (this.record) {\n this.IsLoading = true;\n this.cdr.markForCheck();\n this.LoadRecordChanges(this.record.PrimaryKey, '', this.record.EntityInfo.Name);\n }\n }\n\n public OnClose(): void {\n this.IsVisible = false;\n this.cdr.markForCheck();\n // Allow the slide-out animation to complete before emitting\n setTimeout(() => this.dialogClosed.emit(), 300);\n }\n\n public async LoadRecordChanges(pkey: CompositeKey, appName: string, entityName: string): Promise<void> {\n if (pkey && entityName) {\n const md = new Metadata();\n const changes = await md.GetRecordChanges<MJRecordChangeEntity>(entityName, pkey);\n this.ngZone.run(() => {\n if (changes) {\n this.viewData = changes.sort((a, b) => new Date(b.ChangedAt).getTime() - new Date(a.ChangedAt).getTime());\n this.filteredData = [...this.viewData];\n this.dateGroups = this.buildDateGroups(this.filteredData);\n this.IsLoading = false;\n } else {\n this.mjNotificationService.CreateSimpleNotification(`Error loading record changes for ${entityName} with primary key ${pkey.ToString()}.`, 'error');\n this.IsLoading = false;\n }\n this.cdr.markForCheck();\n });\n }\n }\n\n // ─── Filter & Search ────────────────────────────────────────────\n\n onSearchChange(): void {\n this.applyFilters();\n }\n\n onFilterChange(): void {\n this.applyFilters();\n }\n\n SetTypeFilter(type: string): void {\n this.selectedType = this.selectedType === type ? '' : type;\n this.applyFilters();\n }\n\n public ClearFilters(): void {\n this.searchTerm = '';\n this.selectedType = '';\n this.selectedSource = '';\n this.applyFilters();\n }\n\n private applyFilters(): void {\n let filtered = [...this.viewData];\n\n if (this.searchTerm.trim()) {\n const search = this.searchTerm.toLowerCase();\n filtered = filtered.filter(change =>\n change.ChangesDescription?.toLowerCase().includes(search) ||\n change.User?.toLowerCase().includes(search) ||\n change.Comments?.toLowerCase().includes(search)\n );\n }\n\n if (this.selectedType) {\n filtered = filtered.filter(change => change.Type === this.selectedType);\n }\n\n if (this.selectedSource) {\n filtered = filtered.filter(change => change.Source === this.selectedSource);\n }\n\n this.filteredData = filtered;\n this.dateGroups = this.buildDateGroups(this.filteredData);\n this.cdr.markForCheck();\n }\n\n // ─── Version Labels ─────────────────────────────────────────────\n\n public async LoadRecordLabels(): Promise<void> {\n if (!this.record) return;\n\n this.IsLoadingLabels = true;\n this.cdr.markForCheck();\n\n try {\n const entityId = this.record.EntityInfo.ID;\n const recordId = this.record.PrimaryKey.ToConcatenatedString();\n\n const rv = new RunView();\n const itemsResult = await rv.RunView<{ VersionLabelID: string }>({\n EntityName: 'MJ: Version Label Items',\n Fields: ['VersionLabelID'],\n ExtraFilter: `EntityID='${entityId}' AND RecordID='${recordId}'`,\n ResultType: 'simple'\n });\n\n if (!itemsResult.Success || itemsResult.Results.length === 0) {\n this.ngZone.run(() => {\n this.RecordLabels = [];\n this.IsLoadingLabels = false;\n this.cdr.markForCheck();\n });\n return;\n }\n\n const labelIds = [...new Set(itemsResult.Results.map(i => i.VersionLabelID))];\n const labelIdFilter = labelIds.map(id => `'${id}'`).join(',');\n\n const labelsResult = await rv.RunView<{\n ID: string; Name: string; Description: string | null;\n Scope: string; Status: string; ItemCount: number; __mj_CreatedAt: Date;\n }>({\n EntityName: 'MJ: Version Labels',\n Fields: ['ID', 'Name', 'Description', 'Scope', 'Status', 'ItemCount', '__mj_CreatedAt'],\n ExtraFilter: `ID IN (${labelIdFilter})`,\n OrderBy: '__mj_CreatedAt DESC',\n ResultType: 'simple'\n });\n\n if (labelsResult.Success) {\n this.RecordLabels = labelsResult.Results.map(l => ({\n ID: l.ID,\n Name: l.Name,\n Description: l.Description,\n Scope: l.Scope,\n Status: l.Status,\n CreatedAt: l.__mj_CreatedAt,\n ItemCount: l.ItemCount\n }));\n }\n } catch (error) {\n console.error('Error loading version labels for record:', error);\n this.RecordLabels = [];\n } finally {\n this.ngZone.run(() => {\n this.IsLoadingLabels = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n public OpenCreateWizard(): void {\n this.ShowCreateWizard = true;\n this.cdr.markForCheck();\n }\n\n public OnLabelCreated(event: { LabelCount: number; ItemCount: number }): void {\n this.ShowCreateWizard = false;\n this.cdr.markForCheck();\n this.LoadRecordLabels();\n this.mjNotificationService.CreateSimpleNotification(\n `Version label created with ${event.ItemCount} snapshot${event.ItemCount !== 1 ? 's' : ''}`,\n 'info', 2000\n );\n }\n\n public OnLabelCreateCancelled(): void {\n this.ShowCreateWizard = false;\n this.cdr.markForCheck();\n }\n\n public getLabelStatusClass(status: string): string {\n switch (status) {\n case 'Active': return 'label-status-active';\n case 'Archived': return 'label-status-archived';\n case 'Restored': return 'label-status-restored';\n default: return '';\n }\n }\n\n // ─── Timeline Interaction ───────────────────────────────────────\n\n toggleExpansion(changeId: string): void {\n if (this.expandedItems.has(changeId)) {\n this.expandedItems.delete(changeId);\n } else {\n this.expandedItems.add(changeId);\n }\n this.cdr.markForCheck();\n }\n\n onTimelineItemKeydown(event: KeyboardEvent, changeId: string): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.toggleExpansion(changeId);\n }\n }\n\n /**\n * Opens the inline restore preview panel for a given change record.\n * Computes a field-by-field diff between the version's old values and the current record.\n */\n OnRestoreVersion(change: MJRecordChangeEntity, event: MouseEvent): void {\n event.stopPropagation(); // Prevent card toggle\n\n this.RestorePreview = change;\n this.RestorePreviewFields = this.buildRestorePreviewFields(change);\n this.IsRestoring = false;\n this.cdr.markForCheck();\n }\n\n /** Closes the restore preview panel without applying changes. */\n CancelRestorePreview(): void {\n this.RestorePreview = null;\n this.RestorePreviewFields = [];\n this.cdr.markForCheck();\n }\n\n /**\n * Confirms the restore: emits a RestoreVersionEvent with the old field values\n * so the parent (record-form-container) can apply them and save.\n */\n ConfirmRestore(): void {\n if (!this.RestorePreview) return;\n\n const change = this.RestorePreview;\n const fieldChanges = this.parseFieldChanges(change);\n\n this.IsRestoring = true;\n this.cdr.markForCheck();\n\n this.RestoreRequested.emit({\n VersionID: change.ID,\n ChangedAt: change.ChangedAt,\n ChangedByUser: change.User || '',\n FieldChanges: fieldChanges\n });\n\n // The parent will handle the actual save; we close the preview on completion.\n // A brief delay allows the parent to process, then we reset.\n setTimeout(() => {\n this.RestorePreview = null;\n this.RestorePreviewFields = [];\n this.IsRestoring = false;\n this.cdr.markForCheck();\n }, 500);\n }\n\n /**\n * Builds the diff list comparing version old values vs the current record.\n */\n private buildRestorePreviewFields(change: MJRecordChangeEntity): RestoreFieldDiff[] {\n const changesJson = this.parseChangesJson(change);\n if (!changesJson) return [];\n\n const diffs: RestoreFieldDiff[] = [];\n for (const key of Object.keys(changesJson)) {\n const entry = changesJson[key];\n const fieldName = entry.field || key;\n const entityField = this.record.EntityInfo.Fields.find(\n (f: EntityFieldInfo) => f.Name.trim().toLowerCase() === fieldName.trim().toLowerCase()\n );\n\n const isDateField = entityField?.TSType === EntityFieldTSType.Date;\n const versionValue = this.formatChangeValue(entry.oldValue, isDateField);\n const currentValue = this.getCurrentFieldValue(fieldName, isDateField);\n\n diffs.push({\n FieldName: fieldName,\n DisplayName: entityField?.DisplayNameOrName || fieldName,\n VersionValue: versionValue,\n CurrentValue: currentValue,\n IsChanged: versionValue !== currentValue\n });\n }\n\n return diffs;\n }\n\n /** Gets the current value of a field from the live record, formatted for display. */\n private getCurrentFieldValue(fieldName: string, isDateField: boolean): string {\n const field = this.record.Fields.find(\n f => f.Name.trim().toLowerCase() === fieldName.trim().toLowerCase()\n );\n if (!field) return '';\n return this.formatChangeValue(field.Value, isDateField);\n }\n\n /** Parses ChangesJSON into a structured map, returning null on failure. */\n private parseChangesJson(change: MJRecordChangeEntity): Record<string, { field?: string; oldValue?: unknown; newValue?: unknown }> | null {\n try {\n return JSON.parse(change.ChangesJSON || '{}') as Record<string, { field?: string; oldValue?: unknown; newValue?: unknown }>;\n } catch {\n return null;\n }\n }\n\n /** Parses field changes into the RestoreVersionEvent format. */\n private parseFieldChanges(change: MJRecordChangeEntity): Record<string, { OldValue: unknown; NewValue: unknown }> {\n const fieldChanges: Record<string, { OldValue: unknown; NewValue: unknown }> = {};\n const changesJson = this.parseChangesJson(change);\n if (!changesJson) return fieldChanges;\n\n for (const key of Object.keys(changesJson)) {\n const entry = changesJson[key];\n const fieldName = entry.field || key;\n fieldChanges[fieldName] = {\n OldValue: entry.oldValue,\n NewValue: entry.newValue\n };\n }\n return fieldChanges;\n }\n\n // ─── Date Grouping ─────────────────────────────────────────────\n\n private buildDateGroups(changes: MJRecordChangeEntity[]): DateGroup[] {\n const groups = new Map<string, MJRecordChangeEntity[]>();\n\n for (const change of changes) {\n const label = this.formatDateGroupLabel(new Date(change.ChangedAt));\n if (!groups.has(label)) {\n groups.set(label, []);\n }\n groups.get(label)!.push(change);\n }\n\n return Array.from(groups.entries()).map(([label, items]) => ({ label, changes: items }));\n }\n\n private formatDateGroupLabel(date: Date): string {\n const now = new Date();\n const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const target = new Date(date.getFullYear(), date.getMonth(), date.getDate());\n const diffDays = Math.floor((today.getTime() - target.getTime()) / 86400000);\n\n const formatted = new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric', year: 'numeric' }).format(date);\n\n if (diffDays === 0) return `Today \\u2014 ${formatted}`;\n if (diffDays === 1) return `Yesterday \\u2014 ${formatted}`;\n return formatted;\n }\n\n // ─── Display Helpers ────────────────────────────────────────────\n\n getChangeTypeCardClass(type: string): string {\n switch (type) {\n case 'Create': return 'type-create';\n case 'Update': return 'type-update';\n case 'Delete': return 'type-delete';\n default: return 'type-update';\n }\n }\n\n getChangeTypeBadgeText(type: string): string {\n switch (type) {\n case 'Create': return 'Created';\n case 'Delete': return 'Deleted';\n default: return type;\n }\n }\n\n getSourceClass(source: string): string {\n return source === 'Internal' ? 'source-internal' : 'source-external';\n }\n\n getStatusClass(status: string): string {\n switch (status) {\n case 'Complete': return 'status-complete';\n case 'Pending': return 'status-pending';\n case 'Error': return 'status-error';\n default: return 'status-unknown';\n }\n }\n\n getTimelineItemLabel(change: MJRecordChangeEntity): string {\n return `${change.Type} by ${change.User || 'Unknown User'} on ${this.formatFullDateTime(change.ChangedAt)}`;\n }\n\n getUserInitials(user: string | null): string {\n if (!user) return '?';\n // Handle email addresses: take first char of local part + first char of domain\n if (user.includes('@')) {\n const local = user.split('@')[0];\n return local.substring(0, 2).toUpperCase();\n }\n // Handle names: first char of each word\n const parts = user.trim().split(/\\s+/);\n if (parts.length >= 2) {\n return (parts[0][0] + parts[1][0]).toUpperCase();\n }\n return user.substring(0, 2).toUpperCase();\n }\n\n getUserDisplayName(user: string | null): string {\n if (!user) return 'Unknown';\n if (user.includes('@')) return user.split('@')[0];\n return user;\n }\n\n getUniqueContributorCount(): number {\n const users = new Set(this.viewData.map(c => c.User).filter(Boolean));\n return users.size;\n }\n\n formatTime(date: Date): string {\n return new Intl.DateTimeFormat('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n hour12: true\n }).format(new Date(date));\n }\n\n formatRelativeTime(date: Date): string {\n const now = new Date();\n const diffMs = now.getTime() - new Date(date).getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMins / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins} min${diffMins > 1 ? 's' : ''} ago`;\n if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`;\n if (diffDays < 7) return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;\n\n return new Intl.DateTimeFormat('en-US', {\n month: 'short',\n day: 'numeric',\n year: diffDays > 365 ? 'numeric' : undefined\n }).format(new Date(date));\n }\n\n formatFullDateTime(date: Date): string {\n return new Intl.DateTimeFormat('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n hour12: true,\n timeZoneName: 'short'\n }).format(new Date(date));\n }\n\n // ─── Change Summary ─────────────────────────────────────────────\n\n getChangeSummary(change: MJRecordChangeEntity): string {\n if (change.Type === 'Create') return 'Record created';\n if (change.Type === 'Delete') return 'Record deleted';\n\n try {\n const changesJson = JSON.parse(change.ChangesJSON || '{}');\n const fieldNames = this.extractFieldDisplayNames(changesJson);\n if (fieldNames.length === 0) return 'No field changes detected';\n\n return this.buildFieldListSummary(fieldNames);\n } catch {\n return change.ChangesDescription || 'Changes made';\n }\n }\n\n getCreatedFieldCount(change: MJRecordChangeEntity): number {\n try {\n if (!change.FullRecordJSON) return 0;\n const record = JSON.parse(change.FullRecordJSON);\n return this.record.EntityInfo.Fields\n .filter((f: EntityFieldInfo) => record[f.Name] != null && record[f.Name] !== '')\n .length;\n } catch {\n return 0;\n }\n }\n\n private extractFieldDisplayNames(changesJson: Record<string, { field?: string }>): string[] {\n return Object.keys(changesJson).map(fieldKey => {\n const changeInfo = changesJson[fieldKey];\n const field = this.record.EntityInfo.Fields.find((f: EntityFieldInfo) =>\n f.Name.trim().toLowerCase() === changeInfo.field?.trim().toLowerCase()\n );\n return field?.DisplayNameOrName || changeInfo.field || fieldKey;\n });\n }\n\n private buildFieldListSummary(fieldNames: string[]): string {\n if (fieldNames.length === 1) return `${fieldNames[0]} changed`;\n if (fieldNames.length === 2) return `${fieldNames[0]} and ${fieldNames[1]} changed`;\n if (fieldNames.length <= 4) {\n const last = fieldNames[fieldNames.length - 1];\n return `${fieldNames.slice(0, -1).join(', ')}, and ${last} changed`;\n }\n const remaining = fieldNames.length - 3;\n return `${fieldNames.slice(0, 3).join(', ')}, and ${remaining} other field${remaining > 1 ? 's' : ''} changed`;\n }\n\n // ─── Field Changes (type-aware) ────────────────────────────────\n\n getFieldChanges(change: MJRecordChangeEntity): FieldChangeInfo[] {\n try {\n const changesJson = JSON.parse(change.ChangesJSON || '{}');\n return Object.keys(changesJson).map(fieldKey => this.buildFieldChangeInfo(changesJson[fieldKey]));\n } catch {\n return [];\n }\n }\n\n private buildFieldChangeInfo(changeInfo: { field?: string; oldValue?: unknown; newValue?: unknown }): FieldChangeInfo {\n const field = this.record.EntityInfo.Fields.find((f: EntityFieldInfo) =>\n f.Name.trim().toLowerCase() === changeInfo.field?.trim().toLowerCase()\n );\n\n const fieldType = this.classifyFieldType(field);\n const isDateField = fieldType === 'date';\n const formattedOld = this.formatChangeValue(changeInfo.oldValue, isDateField);\n const formattedNew = this.formatChangeValue(changeInfo.newValue, isDateField);\n\n let diffHtml: SafeHtml | undefined;\n if (fieldType === 'text' && formattedOld !== formattedNew) {\n diffHtml = this.generateDiffHtml(formattedOld, formattedNew);\n }\n\n return {\n field: changeInfo.field || '',\n displayName: field?.DisplayNameOrName || changeInfo.field || '',\n oldValue: formattedOld,\n newValue: formattedNew,\n fieldType,\n diffHtml\n };\n }\n\n private classifyFieldType(field: EntityFieldInfo | undefined): 'boolean' | 'date' | 'number' | 'text' {\n if (!field) return 'text';\n if (field.TSType === EntityFieldTSType.Boolean) return 'boolean';\n if (field.TSType === EntityFieldTSType.Date) return 'date';\n if (field.TSType === EntityFieldTSType.Number) return 'number';\n return 'text';\n }\n\n getCreatedFields(change: MJRecordChangeEntity): Array<{name: string, displayName: string, value: string}> {\n try {\n if (!change.FullRecordJSON) return [];\n\n const record = JSON.parse(change.FullRecordJSON);\n const fields = this.record.EntityInfo.Fields;\n\n return fields\n .filter((field: EntityFieldInfo) => record[field.Name] != null && record[field.Name] !== '')\n .map((field: EntityFieldInfo) => ({\n name: field.Name,\n displayName: field.DisplayNameOrName,\n value: this.formatChangeValue(record[field.Name], field.TSType === EntityFieldTSType.Date)\n }));\n } catch {\n return [];\n }\n }\n\n // ─── Value Formatting ───────────────────────────────────────────\n\n /**\n * Formats a change value for display. Handles corrupted date values (stored as empty objects)\n * and formats ISO date strings into a human-readable format.\n */\n private formatChangeValue(value: unknown, isDateField: boolean): string {\n if (value == null) return '';\n\n if (typeof value === 'object') {\n const keys = Object.keys(value as Record<string, unknown>);\n if (keys.length === 0) return '';\n return JSON.stringify(value);\n }\n\n if (isDateField && typeof value === 'string') {\n const date = new Date(value);\n if (!isNaN(date.getTime())) {\n return new Intl.DateTimeFormat('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n hour12: true\n }).format(date);\n }\n }\n\n return String(value);\n }\n\n // ─── Diff Generation (text fields only) ─────────────────────────\n\n private generateDiffHtml(oldValue: string, newValue: string): SafeHtml {\n if (!oldValue && !newValue) {\n return this.sanitizer.bypassSecurityTrustHtml('<span class=\"rc-diff-unchanged\">(no change)</span>');\n }\n\n if (!oldValue) {\n return this.sanitizer.bypassSecurityTrustHtml(`<span class=\"rc-diff-added\">${this.escapeHtml(newValue)}</span>`);\n }\n\n if (!newValue) {\n return this.sanitizer.bypassSecurityTrustHtml(`<span class=\"rc-diff-removed\">${this.escapeHtml(oldValue)}</span>`);\n }\n\n const useWordDiff = this.shouldUseWordDiff(oldValue, newValue);\n const diffs = useWordDiff ? diffWords(oldValue, newValue) : diffChars(oldValue, newValue);\n\n const html = diffs.map((part: Change) => {\n const escaped = this.escapeHtml(part.value);\n if (part.added) return `<span class=\"rc-diff-added\">${escaped}</span>`;\n if (part.removed) return `<span class=\"rc-diff-removed\">${escaped}</span>`;\n return `<span class=\"rc-diff-unchanged\">${escaped}</span>`;\n }).join('');\n\n return this.sanitizer.bypassSecurityTrustHtml(html);\n }\n\n private shouldUseWordDiff(oldValue: string, newValue: string): boolean {\n const hasMultipleWords = (text: string) => text.includes(' ') && text.split(' ').length > 3;\n const isLongText = (text: string) => text.length > 50;\n\n return (hasMultipleWords(oldValue) || hasMultipleWords(newValue)) &&\n (isLongText(oldValue) || isLongText(newValue));\n }\n\n private escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n}\n","<mj-slide-panel\n [Mode]=\"'slide'\"\n [Title]=\"'Record Changes History'\"\n [Visible]=\"IsVisible\"\n [Resizable]=\"true\"\n [MinWidthPx]=\"400\"\n [MaxWidthRatio]=\"0.6\"\n (Closed)=\"OnClose()\">\n\n @if (IsLoading) {\n <mj-loading text=\"Loading history...\" size=\"medium\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <div class=\"rc-container\">\n <!-- Version Labels Section -->\n <div class=\"rc-labels-section\">\n <div class=\"rc-labels-header\">\n <div class=\"rc-labels-title\">\n <i class=\"fa-solid fa-tags\" aria-hidden=\"true\"></i>\n <span>Version Labels</span>\n @if (RecordLabels.length > 0) {\n <span class=\"rc-labels-count\">{{ RecordLabels.length }}</span>\n }\n </div>\n <button class=\"rc-create-label-btn\" (click)=\"OpenCreateWizard()\" title=\"Create a version label for this record\">\n <i class=\"fa-solid fa-plus\"></i> Create Label\n </button>\n </div>\n @if (IsLoadingLabels) {\n <div class=\"rc-labels-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading labels...\n </div>\n } @else if (RecordLabels.length === 0) {\n <div class=\"rc-labels-empty\">\n No version labels for this record yet.\n </div>\n } @else {\n <div class=\"rc-labels-list\">\n @for (label of RecordLabels; track label.ID) {\n <div class=\"rc-label-chip\" [title]=\"label.Description || label.Name\">\n <i class=\"fa-solid fa-tag rc-label-chip-icon\"></i>\n <span class=\"rc-label-chip-name\">{{ label.Name }}</span>\n <span class=\"rc-label-chip-meta\">\n <span class=\"rc-label-chip-status\" [class]=\"getLabelStatusClass(label.Status)\">{{ label.Status }}</span>\n <span class=\"rc-label-chip-items\">{{ label.ItemCount }} item{{ label.ItemCount !== 1 ? 's' : '' }}</span>\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n @if (viewData.length === 0) {\n <!-- Empty state -->\n <div class=\"rc-empty-state\">\n <div class=\"rc-empty-state-icon\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n </div>\n <h3 class=\"rc-empty-state-title\">No Change History</h3>\n <p class=\"rc-empty-state-description\">\n This record doesn't have any tracked changes yet.\n Changes will appear here automatically as edits are made.\n </p>\n <div class=\"rc-empty-state-hint\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Record change tracking is managed at the entity level</span>\n </div>\n </div>\n } @else {\n <!-- Page Header -->\n <div class=\"rc-page-header\">\n <div>\n <h2 class=\"rc-page-title\">Change History</h2>\n <div class=\"rc-page-subtitle\">{{ record.EntityInfo.Name }}</div>\n </div>\n <div class=\"rc-header-meta\">\n <div class=\"rc-entity-badge\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n {{ record.EntityInfo.Name }}\n </div>\n <div class=\"rc-change-count\">{{ viewData.length }} change{{ viewData.length !== 1 ? 's' : '' }} &middot; {{ getUniqueContributorCount() }} contributor{{ getUniqueContributorCount() !== 1 ? 's' : '' }}</div>\n </div>\n </div>\n\n <!-- Filter Bar -->\n <div class=\"rc-filter-bar\">\n <div class=\"rc-search-wrap\">\n <i class=\"fa-solid fa-search\" aria-hidden=\"true\"></i>\n <input\n class=\"rc-search-box\"\n type=\"text\"\n placeholder=\"Search changes...\"\n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchChange()\"\n aria-label=\"Search record changes\"\n />\n </div>\n <button class=\"rc-filter-pill\" [class.active]=\"!selectedType\" (click)=\"SetTypeFilter('')\">\n <i class=\"fa-solid fa-layer-group\" aria-hidden=\"true\"></i> All\n </button>\n <button class=\"rc-filter-pill\" [class.active]=\"selectedType === 'Update'\" (click)=\"SetTypeFilter('Update')\">\n <i class=\"fa-solid fa-pen\" aria-hidden=\"true\"></i> Updates\n </button>\n <button class=\"rc-filter-pill\" [class.active]=\"selectedType === 'Create'\" (click)=\"SetTypeFilter('Create')\">\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i> Creates\n </button>\n <button class=\"rc-filter-pill\" [class.active]=\"selectedType === 'Delete'\" (click)=\"SetTypeFilter('Delete')\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i> Deletes\n </button>\n </div>\n\n @if (filteredData.length !== viewData.length) {\n <div class=\"rc-filter-results\">\n Showing {{ filteredData.length }} of {{ viewData.length }} changes\n <button class=\"rc-clear-filters-link\" (click)=\"ClearFilters()\">Clear filters</button>\n </div>\n }\n\n <!-- Timeline -->\n <div class=\"rc-timeline\" [attr.aria-label]=\"'Timeline of changes for ' + record.EntityInfo.Name + ' record'\">\n @if (filteredData.length === 0) {\n <div class=\"rc-no-results\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n <p>No changes match your current filters.</p>\n <button class=\"rc-clear-filters-btn\" (click)=\"ClearFilters()\">\n <i class=\"fa-solid fa-xmark\"></i> Clear Filters\n </button>\n </div>\n } @else {\n @for (group of dateGroups; track group.label) {\n <div class=\"rc-date-group\">\n <div class=\"rc-date-label\">{{ group.label }}</div>\n\n @for (change of group.changes; track change.ID) {\n <div\n class=\"rc-card\"\n [class]=\"getChangeTypeCardClass(change.Type)\"\n [class.expanded]=\"expandedItems.has(change.ID)\"\n [attr.tabindex]=\"0\"\n [attr.aria-expanded]=\"expandedItems.has(change.ID)\"\n [attr.aria-label]=\"getTimelineItemLabel(change)\"\n (keydown)=\"onTimelineItemKeydown($event, change.ID)\"\n >\n <!-- Card Header -->\n <div class=\"rc-card-header\" (click)=\"toggleExpansion(change.ID)\">\n <div class=\"rc-card-header-left\">\n <span class=\"rc-card-type-badge\">{{ getChangeTypeBadgeText(change.Type) }}</span>\n <span class=\"rc-card-summary\">{{ getChangeSummary(change) }}</span>\n </div>\n <div class=\"rc-card-meta\">\n <div class=\"rc-card-user\">\n <div class=\"rc-avatar\">{{ getUserInitials(change.User) }}</div>\n {{ getUserDisplayName(change.User) }}\n </div>\n <span class=\"rc-card-time\" [title]=\"formatFullDateTime(change.ChangedAt)\">{{ formatTime(change.ChangedAt) }}</span>\n <span class=\"rc-card-source\" [class]=\"getSourceClass(change.Source)\">{{ change.Source }}</span>\n <span class=\"rc-card-status\" [class]=\"getStatusClass(change.Status)\">{{ change.Status }}</span>\n <i class=\"fa-solid fa-chevron-down rc-card-chevron\" aria-hidden=\"true\"></i>\n </div>\n </div>\n\n <!-- Card Body (expanded) -->\n @if (expandedItems.has(change.ID)) {\n <div class=\"rc-card-body\">\n @if (change.Type === 'Create') {\n <!-- Created record fields -->\n @if (change.FullRecordJSON) {\n @for (field of getCreatedFields(change); track field.name) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ field.displayName }}</div>\n <div class=\"rc-field-values\">\n <span class=\"rc-val-new\">{{ field.value }}</span>\n </div>\n </div>\n }\n }\n } @else if (change.Type === 'Delete') {\n <div class=\"rc-deletion-note\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n This record was permanently removed from the system.\n </div>\n } @else {\n <!-- Update: type-aware field changes -->\n @for (fc of getFieldChanges(change); track fc.field) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ fc.displayName }}</div>\n <div class=\"rc-field-values\">\n @if (fc.fieldType === 'boolean') {\n <!-- Boolean: dot indicators -->\n <div class=\"rc-bool-change\">\n <span class=\"rc-bool-dot\" [class.on]=\"fc.oldValue === 'true' || fc.oldValue === '1'\" [class.off]=\"fc.oldValue !== 'true' && fc.oldValue !== '1'\"></span>\n <span class=\"rc-bool-label old\">{{ fc.oldValue === 'true' || fc.oldValue === '1' ? 'Yes' : 'No' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-bool-dot\" [class.on]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.off]=\"fc.newValue !== 'true' && fc.newValue !== '1'\"></span>\n <span class=\"rc-bool-label new\" [class.active]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.inactive]=\"fc.newValue !== 'true' && fc.newValue !== '1'\">{{ fc.newValue === 'true' || fc.newValue === '1' ? 'Yes' : 'No' }}</span>\n </div>\n } @else if (fc.fieldType === 'date' || fc.fieldType === 'number') {\n <!-- Atomic: old → new -->\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n } @else if (fc.diffHtml) {\n <!-- Text: word/char diff -->\n <div class=\"rc-text-diff\" [innerHTML]=\"fc.diffHtml\"></div>\n } @else {\n <!-- Fallback: old → new -->\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n }\n </div>\n </div>\n }\n }\n\n @if (change.Comments) {\n <div class=\"rc-comments\">\n <i class=\"fa-solid fa-comment\" aria-hidden=\"true\"></i>\n {{ change.Comments }}\n </div>\n }\n\n @if (change.ErrorLog) {\n <div class=\"rc-errors\">\n <i class=\"fa-solid fa-exclamation-triangle\" aria-hidden=\"true\"></i>\n <pre class=\"rc-error-log\">{{ change.ErrorLog }}</pre>\n </div>\n }\n\n @if (AllowRestore && change.Type === 'Update') {\n <div class=\"rc-restore-action\">\n <button class=\"rc-restore-btn\"\n (click)=\"OnRestoreVersion(change, $event)\"\n title=\"Restore field values from before this change\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restore Previous Values\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n\n <!-- ═══════════════════════════════════════════════════\n RESTORE PREVIEW PANEL (inline diff before applying)\n ═══════════════════════════════════════════════════ -->\n @if (RestorePreview) {\n <div class=\"rc-restore-preview-backdrop\" (click)=\"CancelRestorePreview()\">\n <div class=\"rc-restore-preview-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"rc-restore-preview-header\">\n <div class=\"rc-restore-preview-title\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restore Preview\n </div>\n <button class=\"rc-restore-preview-close\" (click)=\"CancelRestorePreview()\" title=\"Close preview\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <div class=\"rc-restore-preview-meta\">\n <span><strong>Version:</strong> {{ formatFullDateTime(RestorePreview.ChangedAt) }}</span>\n <span><strong>By:</strong> {{ getUserDisplayName(RestorePreview.User) }}</span>\n </div>\n\n @if (RestorePreviewFields.length === 0) {\n <div class=\"rc-restore-preview-empty\">\n <i class=\"fa-solid fa-circle-info\" aria-hidden=\"true\"></i>\n No field changes could be parsed from this version.\n </div>\n } @else {\n <table class=\"rc-restore-preview-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th>Current Value</th>\n <th>Restore To</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (diff of RestorePreviewFields; track diff.FieldName) {\n <tr [class.rc-diff-changed]=\"diff.IsChanged\" [class.rc-diff-unchanged]=\"!diff.IsChanged\">\n <td class=\"rc-restore-field-name\">{{ diff.DisplayName }}</td>\n <td class=\"rc-restore-current\">{{ diff.CurrentValue || '(empty)' }}</td>\n <td class=\"rc-restore-version\">{{ diff.VersionValue || '(empty)' }}</td>\n <td class=\"rc-restore-indicator\">\n @if (diff.IsChanged) {\n <i class=\"fa-solid fa-circle-exclamation\" title=\"Will be changed\"></i>\n } @else {\n <i class=\"fa-solid fa-check\" title=\"Already matches\"></i>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n }\n\n <div class=\"rc-restore-preview-actions\">\n <button class=\"rc-restore-confirm-btn\"\n [disabled]=\"IsRestoring || RestorePreviewFields.length === 0\"\n (click)=\"ConfirmRestore()\">\n @if (IsRestoring) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Restoring...\n } @else {\n <i class=\"fa-solid fa-rotate-left\" aria-hidden=\"true\"></i>\n Apply Restore\n }\n </button>\n <button class=\"rc-restore-cancel-btn\" (click)=\"CancelRestorePreview()\" [disabled]=\"IsRestoring\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n @if (ShowCreateWizard) {\n <div class=\"rc-wizard-overlay\" (click)=\"OnLabelCreateCancelled()\">\n <div class=\"rc-wizard-container\" (click)=\"$event.stopPropagation()\">\n <mj-label-create\n [PreselectedEntity]=\"record.EntityInfo\"\n [PreselectedRecordIds]=\"[record.PrimaryKey.KeyValuePairs[0].Value]\"\n (Created)=\"OnLabelCreated($event)\"\n (Cancel)=\"OnLabelCreateCancelled()\">\n </mj-label-create>\n </div>\n </div>\n }\n</mj-slide-panel>\n"]}
1
+ {"version":3,"file":"ng-record-changes.component.js","sourceRoot":"","sources":["../../src/lib/ng-record-changes.component.ts","../../src/lib/ng-record-changes.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n EventEmitter,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ChangeDetectorRef,\n ChangeDetectionStrategy,\n ViewEncapsulation,\n NgZone,\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { Subscription } from 'rxjs';\nimport {\n BaseEntity,\n BaseEntityEvent,\n CompositeKey,\n EntityFieldInfo,\n EntityFieldTSType,\n Metadata,\n RunView,\n} from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { MJRecordChangeEntity } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { diffChars, diffWords, Change } from 'diff';\nimport { RestoreCommitEvent } from './restore-preview-panel/restore-preview-panel.component';\n\n/** Lightweight shape for displaying a version label associated with this record */\ninterface RecordLabel {\n ID: string;\n Name: string;\n Description: string | null;\n Scope: string;\n Status: string;\n CreatedAt: Date;\n ItemCount: number;\n}\n\n/**\n * Event payload emitted when the user confirms a restore.\n *\n * The host component (typically `record-form-container`) is responsible for:\n * 1. Reloading the live record (concurrency safety),\n * 2. Calling `record.SetRestoreContext(SourceChangeID, Reason)`,\n * 3. Calling `record.Set(FieldName, Value)` for each entry in `FieldValues`,\n * 4. Calling `record.Save()`,\n * 5. Calling `record.ClearRestoreContext()` after the save returns.\n *\n * The provider will write a new RecordChange row with `Source='Restore'`,\n * `RestoredFromID = SourceChangeID`, and `RestoreReason = Reason` —\n * producing the auditable lineage chain.\n */\nexport interface RestoreVersionEvent {\n /** ID of the historical RecordChange row whose state is being restored. */\n SourceChangeID: string;\n /** When the historical change was made. */\n ChangedAt: Date;\n /** Display name / email of who made the historical change. */\n ChangedByUser: string;\n /** Optional user-entered reason for the restore. */\n Reason: string | null;\n /** Selected field values, ready to pass to BaseEntity.Set(). */\n FieldValues: Array<{ FieldName: string; Value: unknown }>;\n}\n\n/** A single field change with type-aware rendering info (timeline display only). */\nexport interface FieldChangeInfo {\n field: string;\n displayName: string;\n oldValue: string;\n newValue: string;\n fieldType: 'boolean' | 'date' | 'number' | 'text';\n diffHtml?: SafeHtml;\n}\n\n/** A group of changes that share the same date. */\nexport interface DateGroup {\n label: string;\n changes: MJRecordChangeEntity[];\n}\n\n/** A conditional filter pill (one per type/source actually present in loaded data). */\nexport interface FilterPill {\n /** Unique key for selection state ('Update', 'Create', 'Delete', 'Snapshot', 'Restore'). */\n Key: string;\n /** User-facing label (pluralized: 'Updates', 'Restored', etc.). */\n Label: string;\n /** Font Awesome icon class. */\n Icon: string;\n /** Number of changes of this kind in the loaded data. */\n Count: number;\n /** Selection style — neutral type pill or violet restore pill. */\n Variant: 'type' | 'restore';\n}\n\n/**\n * Slide-out timeline of all changes to a single record. Hosts the reusable\n * {@link RestorePreviewPanelComponent} for the actual restore confirmation\n * flow, and exposes a `RestoreRequested` event the host can act on to\n * persist the restore.\n *\n * @example\n * <mj-record-changes\n * [record]=\"myEntity\"\n * [AllowRestore]=\"true\"\n * (dialogClosed)=\"showHistory = false\"\n * (RestoreRequested)=\"onRestoreRequested($event)\">\n * </mj-record-changes>\n */\n@Component({\n standalone: false,\n selector: 'mj-record-changes',\n templateUrl: './ng-record-changes.component.html',\n styleUrls: ['./ng-record-changes.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class RecordChangesComponent implements OnInit, OnDestroy {\n public IsLoading = false;\n public IsVisible = false;\n @Output() dialogClosed = new EventEmitter();\n @Input() record!: BaseEntity;\n\n /** Whether to show a \"Restore\" button on each historical version row. Default false. */\n @Input() AllowRestore = false;\n\n /**\n * Emitted when the user confirms a restore in the preview panel.\n * The host is responsible for applying the snapshot to the record and\n * saving with `record.SetRestoreContext()` set first.\n */\n @Output() RestoreRequested = new EventEmitter<RestoreVersionEvent>();\n\n viewData: MJRecordChangeEntity[] = [];\n filteredData: MJRecordChangeEntity[] = [];\n dateGroups: DateGroup[] = [];\n expandedItems: Set<string> = new Set();\n\n /** The change record currently selected for restore preview, or null. */\n RestorePreviewChange: MJRecordChangeEntity | null = null;\n /** Visibility of the embedded restore preview slide-in. */\n RestorePreviewVisible = false;\n /** Whether the restore commit is in progress (between confirmation and host response). */\n IsRestoring = false;\n\n // Version label state\n RecordLabels: RecordLabel[] = [];\n IsLoadingLabels = false;\n ShowCreateWizard = false;\n\n // Filter properties\n searchTerm = '';\n /** Single selected type filter (legacy, kept for backwards compat). */\n selectedType = '';\n selectedSource = '';\n /** Map of Key → selected, used by the conditional chip system. */\n ChipSelections: Record<string, boolean> = {};\n /** Whether the overflow popover is open. */\n ShowFilterOverflow = false;\n /** Highlighted change ID for the lineage-jump indicator (transient). */\n HighlightedChangeID: string | null = null;\n\n /**\n * Conditional filter pills derived from loaded data. Always includes 'All'\n * implicitly. Other pills only render when at least one matching change\n * exists. Overflows into a popover when the count exceeds 2.\n */\n ConditionalPills: FilterPill[] = [];\n\n /** Threshold above which conditional chips collapse into the overflow popover. */\n private readonly OVERFLOW_THRESHOLD = 2;\n\n /**\n * Subscription to the record's BaseEntity event stream. We listen for\n * 'save' events and auto-refresh the timeline so the user immediately\n * sees the new RecordChange row produced by either a normal save or a\n * restore. Cleaned up in ngOnDestroy.\n */\n private _entitySaveSub: Subscription | null = null;\n\n constructor(\n private cdr: ChangeDetectorRef,\n private ngZone: NgZone,\n private mjNotificationService: MJNotificationService,\n private sanitizer: DomSanitizer,\n ) {}\n\n ngOnInit(): void {\n if (this.record) {\n this.IsLoading = true;\n this.IsVisible = true;\n this.cdr.markForCheck();\n this.LoadRecordChanges(this.record.PrimaryKey, '', this.record.EntityInfo.Name);\n this.LoadRecordLabels();\n this.subscribeToRecordSaves();\n }\n }\n\n ngOnDestroy(): void {\n this._entitySaveSub?.unsubscribe();\n this._entitySaveSub = null;\n }\n\n /**\n * Wires up an event handler on the live record so the timeline auto-\n * refreshes immediately after any save lands — including the one\n * produced by the restore flow. Without this the user sees their record\n * update in the form but the panel above still shows the pre-restore\n * change list, which is confusing.\n */\n private subscribeToRecordSaves(): void {\n if (!this.record) return;\n this._entitySaveSub?.unsubscribe();\n this._entitySaveSub = this.record.RegisterEventHandler((event: BaseEntityEvent) => {\n if (event?.type === 'save') {\n this.ngZone.run(() => this.Refresh());\n }\n });\n }\n\n /**\n * Reloads the record changes list from the database.\n * Called by the parent container after a save completes while the drawer is open.\n */\n public Refresh(): void {\n if (this.record) {\n this.IsLoading = true;\n this.cdr.markForCheck();\n this.LoadRecordChanges(this.record.PrimaryKey, '', this.record.EntityInfo.Name);\n }\n }\n\n public OnClose(): void {\n this.IsVisible = false;\n this.cdr.markForCheck();\n // Allow the slide-out animation to complete before emitting\n setTimeout(() => this.dialogClosed.emit(), 300);\n }\n\n public async LoadRecordChanges(pkey: CompositeKey, appName: string, entityName: string): Promise<void> {\n if (pkey && entityName) {\n const md = new Metadata();\n const changes = await md.GetRecordChanges<MJRecordChangeEntity>(entityName, pkey);\n this.ngZone.run(() => {\n if (changes) {\n this.viewData = changes.sort(\n (a, b) => new Date(b.ChangedAt).getTime() - new Date(a.ChangedAt).getTime(),\n );\n this.rebuildConditionalPills();\n this.applyFilters();\n this.IsLoading = false;\n } else {\n this.mjNotificationService.CreateSimpleNotification(\n `Error loading record changes for ${entityName} with primary key ${pkey.ToString()}.`,\n 'error',\n );\n this.IsLoading = false;\n }\n this.cdr.markForCheck();\n });\n }\n }\n\n // ─── Filter & Search ────────────────────────────────────────────\n\n onSearchChange(): void {\n this.applyFilters();\n }\n\n onFilterChange(): void {\n this.applyFilters();\n }\n\n /**\n * Toggles the \"All\" pill — clears every conditional selection.\n */\n public SelectAllPill(): void {\n for (const k of Object.keys(this.ChipSelections)) this.ChipSelections[k] = false;\n this.applyFilters();\n }\n\n /**\n * Toggles a conditional pill on/off.\n */\n public TogglePill(key: string): void {\n this.ChipSelections[key] = !this.ChipSelections[key];\n this.applyFilters();\n }\n\n /**\n * Returns true when no conditional pills are selected (i.e. \"All\" mode).\n */\n public get IsAllSelected(): boolean {\n return !Object.values(this.ChipSelections).some(v => v);\n }\n\n /**\n * Whether any conditional pills are actually visible at all.\n */\n public get HasConditionalPills(): boolean {\n return this.ConditionalPills.length > 0;\n }\n\n /**\n * True when the conditional chips should collapse into an overflow popover\n * because there are more than the threshold.\n */\n public get UseOverflowPopover(): boolean {\n return this.ConditionalPills.length > this.OVERFLOW_THRESHOLD;\n }\n\n /** Number of currently selected conditional pills (for the popover trigger label). */\n public get SelectedConditionalCount(): number {\n return Object.values(this.ChipSelections).filter(v => v).length;\n }\n\n public ToggleFilterOverflow(): void {\n this.ShowFilterOverflow = !this.ShowFilterOverflow;\n this.cdr.markForCheck();\n }\n\n public CloseFilterOverflow(): void {\n this.ShowFilterOverflow = false;\n this.cdr.markForCheck();\n }\n\n public ClearFilters(): void {\n this.searchTerm = '';\n for (const k of Object.keys(this.ChipSelections)) this.ChipSelections[k] = false;\n this.applyFilters();\n }\n\n /**\n * Builds the list of conditional pills from currently loaded data —\n * a pill only appears for change types/sources that actually exist.\n */\n private rebuildConditionalPills(): void {\n const counts: Record<string, number> = {};\n let restoreCount = 0;\n\n for (const c of this.viewData) {\n const type = c.Type ?? 'Update';\n counts[type] = (counts[type] ?? 0) + 1;\n if (this.isRestoreChange(c)) restoreCount++;\n }\n\n const pills: FilterPill[] = [];\n if ((counts['Update'] ?? 0) > 0) {\n pills.push({ Key: 'Update', Label: 'Updates', Icon: 'fa-pen', Count: counts['Update'], Variant: 'type' });\n }\n if ((counts['Create'] ?? 0) > 0) {\n pills.push({ Key: 'Create', Label: 'Creates', Icon: 'fa-plus', Count: counts['Create'], Variant: 'type' });\n }\n if ((counts['Delete'] ?? 0) > 0) {\n pills.push({ Key: 'Delete', Label: 'Deletes', Icon: 'fa-trash', Count: counts['Delete'], Variant: 'type' });\n }\n if ((counts['Snapshot'] ?? 0) > 0) {\n pills.push({ Key: 'Snapshot', Label: 'Snapshots', Icon: 'fa-camera', Count: counts['Snapshot'], Variant: 'type' });\n }\n if (restoreCount > 0) {\n pills.push({ Key: 'Restore', Label: 'Restored', Icon: 'fa-clock-rotate-left', Count: restoreCount, Variant: 'restore' });\n }\n\n // Initialize/prune selection state\n const validKeys = new Set(pills.map(p => p.Key));\n for (const k of Object.keys(this.ChipSelections)) {\n if (!validKeys.has(k)) delete this.ChipSelections[k];\n }\n for (const p of pills) {\n if (this.ChipSelections[p.Key] === undefined) this.ChipSelections[p.Key] = false;\n }\n\n this.ConditionalPills = pills;\n }\n\n private isRestoreChange(c: MJRecordChangeEntity): boolean {\n return c.Source === 'Restore' || (c as any).RestoredFromID != null;\n }\n\n private applyFilters(): void {\n let filtered = [...this.viewData];\n\n if (this.searchTerm.trim()) {\n const search = this.searchTerm.toLowerCase();\n filtered = filtered.filter(\n change =>\n change.ChangesDescription?.toLowerCase().includes(search) ||\n change.User?.toLowerCase().includes(search) ||\n change.Comments?.toLowerCase().includes(search),\n );\n }\n\n // Apply conditional pill filters — if any are selected, only show changes matching ANY of them (OR semantics).\n const selectedKeys = Object.keys(this.ChipSelections).filter(k => this.ChipSelections[k]);\n if (selectedKeys.length > 0) {\n filtered = filtered.filter(change => {\n for (const key of selectedKeys) {\n if (key === 'Restore') {\n if (this.isRestoreChange(change)) return true;\n } else {\n if (change.Type === key) return true;\n }\n }\n return false;\n });\n }\n\n this.filteredData = filtered;\n this.dateGroups = this.buildDateGroups(this.filteredData);\n this.cdr.markForCheck();\n }\n\n // ─── Version Labels ─────────────────────────────────────────────\n\n public async LoadRecordLabels(): Promise<void> {\n if (!this.record) return;\n\n this.IsLoadingLabels = true;\n this.cdr.markForCheck();\n\n try {\n const entityId = this.record.EntityInfo.ID;\n const recordId = this.record.PrimaryKey.ToConcatenatedString();\n\n const rv = new RunView();\n const itemsResult = await rv.RunView<{ VersionLabelID: string }>({\n EntityName: 'MJ: Version Label Items',\n Fields: ['VersionLabelID'],\n ExtraFilter: `EntityID='${entityId}' AND RecordID='${recordId}'`,\n ResultType: 'simple',\n });\n\n if (!itemsResult.Success || itemsResult.Results.length === 0) {\n this.ngZone.run(() => {\n this.RecordLabels = [];\n this.IsLoadingLabels = false;\n this.cdr.markForCheck();\n });\n return;\n }\n\n const labelIds = [...new Set(itemsResult.Results.map(i => i.VersionLabelID))];\n const labelIdFilter = labelIds.map(id => `'${id}'`).join(',');\n\n const labelsResult = await rv.RunView<{\n ID: string;\n Name: string;\n Description: string | null;\n Scope: string;\n Status: string;\n ItemCount: number;\n __mj_CreatedAt: Date;\n }>({\n EntityName: 'MJ: Version Labels',\n Fields: ['ID', 'Name', 'Description', 'Scope', 'Status', 'ItemCount', '__mj_CreatedAt'],\n ExtraFilter: `ID IN (${labelIdFilter})`,\n OrderBy: '__mj_CreatedAt DESC',\n ResultType: 'simple',\n });\n\n if (labelsResult.Success) {\n this.RecordLabels = labelsResult.Results.map(l => ({\n ID: l.ID,\n Name: l.Name,\n Description: l.Description,\n Scope: l.Scope,\n Status: l.Status,\n CreatedAt: l.__mj_CreatedAt,\n ItemCount: l.ItemCount,\n }));\n }\n } catch (error) {\n console.error('Error loading version labels for record:', error);\n this.RecordLabels = [];\n } finally {\n this.ngZone.run(() => {\n this.IsLoadingLabels = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n public OpenCreateWizard(): void {\n this.ShowCreateWizard = true;\n this.cdr.markForCheck();\n }\n\n public OnLabelCreated(event: { LabelCount: number; ItemCount: number }): void {\n this.ShowCreateWizard = false;\n this.cdr.markForCheck();\n this.LoadRecordLabels();\n this.mjNotificationService.CreateSimpleNotification(\n `Version label created with ${event.ItemCount} snapshot${event.ItemCount !== 1 ? 's' : ''}`,\n 'info',\n 2000,\n );\n }\n\n public OnLabelCreateCancelled(): void {\n this.ShowCreateWizard = false;\n this.cdr.markForCheck();\n }\n\n public getLabelStatusClass(status: string): string {\n switch (status) {\n case 'Active': return 'label-status-active';\n case 'Archived': return 'label-status-archived';\n case 'Restored': return 'label-status-restored';\n default: return '';\n }\n }\n\n // ─── Timeline Interaction ───────────────────────────────────────\n\n toggleExpansion(changeId: string): void {\n if (this.expandedItems.has(changeId)) {\n this.expandedItems.delete(changeId);\n } else {\n this.expandedItems.add(changeId);\n }\n this.cdr.markForCheck();\n }\n\n onTimelineItemKeydown(event: KeyboardEvent, changeId: string): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.toggleExpansion(changeId);\n }\n }\n\n /**\n * Opens the embedded restore preview panel for a given change record.\n * The panel computes a full-record diff (current vs the change's\n * FullRecordJSON snapshot) — this is the semantic-correctness fix:\n * we restore TO the state at that point in time, not just undo the\n * one delta the user clicked.\n */\n OnRestoreVersion(change: MJRecordChangeEntity, event: MouseEvent): void {\n event.stopPropagation();\n this.RestorePreviewChange = change;\n this.RestorePreviewVisible = true;\n this.cdr.markForCheck();\n }\n\n /**\n * Called when the user confirms the restore in the embedded panel.\n * Translates the panel's RestoreCommitEvent into the broader-shape\n * RestoreVersionEvent the host is wired to handle.\n */\n OnRestorePanelConfirmed(commit: RestoreCommitEvent): void {\n if (!this.RestorePreviewChange) return;\n\n const change = this.RestorePreviewChange;\n this.IsRestoring = true;\n this.cdr.markForCheck();\n\n this.RestoreRequested.emit({\n SourceChangeID: commit.SourceChangeID,\n ChangedAt: change.ChangedAt,\n ChangedByUser: change.User || '',\n Reason: commit.Reason,\n FieldValues: commit.FieldValues,\n });\n\n // Close the panel after a brief delay so the host has a moment to react.\n setTimeout(() => {\n this.RestorePreviewVisible = false;\n this.RestorePreviewChange = null;\n this.IsRestoring = false;\n this.cdr.markForCheck();\n }, 500);\n }\n\n /**\n * Called when the user dismisses the restore preview without confirming.\n */\n OnRestorePanelCancelled(): void {\n this.RestorePreviewVisible = false;\n this.RestorePreviewChange = null;\n this.cdr.markForCheck();\n }\n\n // ─── Lineage chip ───────────────────────────────────────────────\n\n /**\n * Returns the source change for a given restored row, if found in the\n * currently loaded changes. Returns null when the source isn't loaded\n * (e.g., it's been pruned from history) or when this row isn't a restore.\n */\n public getRestoredFromSourceChange(change: MJRecordChangeEntity): MJRecordChangeEntity | null {\n const sourceId = (change as any).RestoredFromID;\n if (!sourceId) return null;\n return this.viewData.find(c => UUIDsEqual(c.ID, sourceId)) ?? null;\n }\n\n /**\n * True when the row was produced by a restore operation (either the\n * `Source` is `'Restore'` OR `RestoredFromID` is populated).\n */\n public isRestoreRow(change: MJRecordChangeEntity): boolean {\n return this.isRestoreChange(change);\n }\n\n /**\n * True when this change is the most recent in the loaded history.\n * `viewData` is sorted DESC by `ChangedAt`, so the most recent is index 0.\n * Restoring to the most recent version is a no-op, so the timeline hides\n * the Restore button on this row.\n */\n public isMostRecentChange(change: MJRecordChangeEntity): boolean {\n return this.viewData.length > 0 && this.viewData[0] === change;\n }\n\n /**\n * Click handler for the lineage chip — scrolls/highlights the source\n * change row in the timeline. Auto-clears after a few seconds.\n */\n public JumpToSourceChange(sourceChange: MJRecordChangeEntity, event: MouseEvent): void {\n event.stopPropagation();\n this.HighlightedChangeID = sourceChange.ID;\n this.expandedItems.add(sourceChange.ID);\n this.cdr.markForCheck();\n\n // Auto-clear the highlight after 3s\n setTimeout(() => {\n if (this.HighlightedChangeID && UUIDsEqual(this.HighlightedChangeID, sourceChange.ID)) {\n this.HighlightedChangeID = null;\n this.cdr.markForCheck();\n }\n }, 3000);\n\n // Scroll into view\n setTimeout(() => {\n const el = document.querySelector(`[data-change-id=\"${sourceChange.ID}\"]`);\n el?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }, 50);\n }\n\n // ─── Date Grouping ─────────────────────────────────────────────\n\n private buildDateGroups(changes: MJRecordChangeEntity[]): DateGroup[] {\n const groups = new Map<string, MJRecordChangeEntity[]>();\n\n for (const change of changes) {\n const label = this.formatDateGroupLabel(new Date(change.ChangedAt));\n if (!groups.has(label)) {\n groups.set(label, []);\n }\n groups.get(label)!.push(change);\n }\n\n return Array.from(groups.entries()).map(([label, items]) => ({ label, changes: items }));\n }\n\n private formatDateGroupLabel(date: Date): string {\n const now = new Date();\n const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const target = new Date(date.getFullYear(), date.getMonth(), date.getDate());\n const diffDays = Math.floor((today.getTime() - target.getTime()) / 86400000);\n\n const formatted = new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric', year: 'numeric' }).format(date);\n\n if (diffDays === 0) return `Today \\u2014 ${formatted}`;\n if (diffDays === 1) return `Yesterday \\u2014 ${formatted}`;\n return formatted;\n }\n\n // ─── Display Helpers ────────────────────────────────────────────\n\n getChangeTypeCardClass(type: string): string {\n switch (type) {\n case 'Create': return 'type-create';\n case 'Update': return 'type-update';\n case 'Delete': return 'type-delete';\n case 'Snapshot': return 'type-snapshot';\n default: return 'type-update';\n }\n }\n\n getChangeTypeBadgeText(type: string): string {\n switch (type) {\n case 'Create': return 'Created';\n case 'Delete': return 'Deleted';\n case 'Snapshot': return 'Snapshot';\n default: return type;\n }\n }\n\n /**\n * Badge text for the row's primary type tag. For restore rows we override\n * the underlying `Type='Update'` and show \"Restore\" instead — matches the\n * mockup's intent of treating restore as a first-class operation in the\n * timeline rather than a flavor of update.\n */\n getEffectiveBadgeText(change: MJRecordChangeEntity): string {\n if (this.isRestoreRow(change)) return 'Restore';\n return this.getChangeTypeBadgeText(change.Type);\n }\n\n /**\n * Optional restore reason — pulled from the dynamic `RestoreReason`\n * column added by the lineage migration. Returns null when not present\n * or not a restore row.\n */\n getRestoreReason(change: MJRecordChangeEntity): string | null {\n if (!this.isRestoreRow(change)) return null;\n const reason = (change as unknown as { RestoreReason?: string | null }).RestoreReason;\n return reason && reason.trim().length > 0 ? reason : null;\n }\n\n getSourceClass(source: string): string {\n if (source === 'Restore') return 'source-restore';\n if (source === 'Internal') return 'source-internal';\n return 'source-external';\n }\n\n getStatusClass(status: string): string {\n switch (status) {\n case 'Complete': return 'status-complete';\n case 'Pending': return 'status-pending';\n case 'Error': return 'status-error';\n default: return 'status-unknown';\n }\n }\n\n getTimelineItemLabel(change: MJRecordChangeEntity): string {\n return `${change.Type} by ${change.User || 'Unknown User'} on ${this.formatFullDateTime(change.ChangedAt)}`;\n }\n\n getUserInitials(user: string | null): string {\n if (!user) return '?';\n if (user.includes('@')) {\n const local = user.split('@')[0];\n return local.substring(0, 2).toUpperCase();\n }\n const parts = user.trim().split(/\\s+/);\n if (parts.length >= 2) {\n return (parts[0][0] + parts[1][0]).toUpperCase();\n }\n return user.substring(0, 2).toUpperCase();\n }\n\n getUserDisplayName(user: string | null): string {\n if (!user) return 'Unknown';\n if (user.includes('@')) return user.split('@')[0];\n return user;\n }\n\n getUniqueContributorCount(): number {\n const users = new Set(this.viewData.map(c => c.User).filter(Boolean));\n return users.size;\n }\n\n formatTime(date: Date): string {\n return new Intl.DateTimeFormat('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n }).format(new Date(date));\n }\n\n formatRelativeTime(date: Date): string {\n const now = new Date();\n const diffMs = now.getTime() - new Date(date).getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMins / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins} min${diffMins > 1 ? 's' : ''} ago`;\n if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`;\n if (diffDays < 7) return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;\n\n return new Intl.DateTimeFormat('en-US', {\n month: 'short',\n day: 'numeric',\n year: diffDays > 365 ? 'numeric' : undefined,\n }).format(new Date(date));\n }\n\n formatFullDateTime(date: Date): string {\n return new Intl.DateTimeFormat('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n hour12: true,\n timeZoneName: 'short',\n }).format(new Date(date));\n }\n\n // ─── Change Summary ─────────────────────────────────────────────\n\n getChangeSummary(change: MJRecordChangeEntity): string {\n // Restore rows get a distinctive summary so the timeline reads like a\n // sentence — \"Restored to 5:56 PM version\" rather than yet another\n // \"Name and Description changed\". The lineage chip carries the full\n // source-version detail.\n if (this.isRestoreRow(change)) {\n const src = this.getRestoredFromSourceChange(change);\n if (src) return `Restored to ${this.formatTime(src.ChangedAt)} version`;\n return 'Restored from earlier version';\n }\n if (change.Type === 'Create') return 'Record created';\n if (change.Type === 'Delete') return 'Record deleted';\n if (change.Type === 'Snapshot') return change.ChangesDescription || 'Snapshot captured';\n\n try {\n const changesJson = JSON.parse(change.ChangesJSON || '{}');\n const fieldNames = this.extractFieldDisplayNames(changesJson);\n if (fieldNames.length === 0) return 'No field changes detected';\n\n return this.buildFieldListSummary(fieldNames);\n } catch {\n return change.ChangesDescription || 'Changes made';\n }\n }\n\n getCreatedFieldCount(change: MJRecordChangeEntity): number {\n try {\n if (!change.FullRecordJSON) return 0;\n const record = JSON.parse(change.FullRecordJSON);\n return this.record.EntityInfo.Fields.filter(\n (f: EntityFieldInfo) => record[f.Name] != null && record[f.Name] !== '',\n ).length;\n } catch {\n return 0;\n }\n }\n\n private extractFieldDisplayNames(changesJson: Record<string, { field?: string }>): string[] {\n return Object.keys(changesJson).map(fieldKey => {\n const changeInfo = changesJson[fieldKey];\n const field = this.record.EntityInfo.Fields.find(\n (f: EntityFieldInfo) => f.Name.trim().toLowerCase() === changeInfo.field?.trim().toLowerCase(),\n );\n return field?.DisplayNameOrName || changeInfo.field || fieldKey;\n });\n }\n\n private buildFieldListSummary(fieldNames: string[]): string {\n if (fieldNames.length === 1) return `${fieldNames[0]} changed`;\n if (fieldNames.length === 2) return `${fieldNames[0]} and ${fieldNames[1]} changed`;\n if (fieldNames.length <= 4) {\n const last = fieldNames[fieldNames.length - 1];\n return `${fieldNames.slice(0, -1).join(', ')}, and ${last} changed`;\n }\n const remaining = fieldNames.length - 3;\n return `${fieldNames.slice(0, 3).join(', ')}, and ${remaining} other field${remaining > 1 ? 's' : ''} changed`;\n }\n\n // ─── Field Changes (type-aware) ────────────────────────────────\n\n getFieldChanges(change: MJRecordChangeEntity): FieldChangeInfo[] {\n try {\n const changesJson = JSON.parse(change.ChangesJSON || '{}');\n return Object.keys(changesJson).map(fieldKey => this.buildFieldChangeInfo(changesJson[fieldKey]));\n } catch {\n return [];\n }\n }\n\n private buildFieldChangeInfo(changeInfo: { field?: string; oldValue?: unknown; newValue?: unknown }): FieldChangeInfo {\n const field = this.record.EntityInfo.Fields.find(\n (f: EntityFieldInfo) => f.Name.trim().toLowerCase() === changeInfo.field?.trim().toLowerCase(),\n );\n\n const fieldType = this.classifyFieldType(field);\n const isDateField = fieldType === 'date';\n const formattedOld = this.formatChangeValue(changeInfo.oldValue, isDateField);\n const formattedNew = this.formatChangeValue(changeInfo.newValue, isDateField);\n\n let diffHtml: SafeHtml | undefined;\n if (fieldType === 'text' && formattedOld !== formattedNew) {\n diffHtml = this.generateDiffHtml(formattedOld, formattedNew);\n }\n\n return {\n field: changeInfo.field || '',\n displayName: field?.DisplayNameOrName || changeInfo.field || '',\n oldValue: formattedOld,\n newValue: formattedNew,\n fieldType,\n diffHtml,\n };\n }\n\n private classifyFieldType(field: EntityFieldInfo | undefined): 'boolean' | 'date' | 'number' | 'text' {\n if (!field) return 'text';\n if (field.TSType === EntityFieldTSType.Boolean) return 'boolean';\n if (field.TSType === EntityFieldTSType.Date) return 'date';\n if (field.TSType === EntityFieldTSType.Number) return 'number';\n return 'text';\n }\n\n getCreatedFields(change: MJRecordChangeEntity): Array<{ name: string; displayName: string; value: string }> {\n try {\n if (!change.FullRecordJSON) return [];\n\n const record = JSON.parse(change.FullRecordJSON);\n const fields = this.record.EntityInfo.Fields;\n\n return fields\n .filter((field: EntityFieldInfo) => record[field.Name] != null && record[field.Name] !== '')\n .map((field: EntityFieldInfo) => ({\n name: field.Name,\n displayName: field.DisplayNameOrName,\n value: this.formatChangeValue(record[field.Name], field.TSType === EntityFieldTSType.Date),\n }));\n } catch {\n return [];\n }\n }\n\n // ─── Value Formatting ───────────────────────────────────────────\n\n private formatChangeValue(value: unknown, isDateField: boolean): string {\n if (value == null) return '';\n\n if (typeof value === 'object') {\n const keys = Object.keys(value as Record<string, unknown>);\n if (keys.length === 0) return '';\n return JSON.stringify(value);\n }\n\n if (isDateField && typeof value === 'string') {\n const date = new Date(value);\n if (!isNaN(date.getTime())) {\n return new Intl.DateTimeFormat('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n }).format(date);\n }\n }\n\n return String(value);\n }\n\n // ─── Diff Generation (text fields only) ─────────────────────────\n\n private generateDiffHtml(oldValue: string, newValue: string): SafeHtml {\n if (!oldValue && !newValue) {\n return this.sanitizer.bypassSecurityTrustHtml('<span class=\"rc-diff-unchanged\">(no change)</span>');\n }\n\n if (!oldValue) {\n return this.sanitizer.bypassSecurityTrustHtml(`<span class=\"rc-diff-added\">${this.escapeHtml(newValue)}</span>`);\n }\n\n if (!newValue) {\n return this.sanitizer.bypassSecurityTrustHtml(`<span class=\"rc-diff-removed\">${this.escapeHtml(oldValue)}</span>`);\n }\n\n const useWordDiff = this.shouldUseWordDiff(oldValue, newValue);\n const diffs = useWordDiff ? diffWords(oldValue, newValue) : diffChars(oldValue, newValue);\n\n const html = diffs\n .map((part: Change) => {\n const escaped = this.escapeHtml(part.value);\n if (part.added) return `<span class=\"rc-diff-added\">${escaped}</span>`;\n if (part.removed) return `<span class=\"rc-diff-removed\">${escaped}</span>`;\n return `<span class=\"rc-diff-unchanged\">${escaped}</span>`;\n })\n .join('');\n\n return this.sanitizer.bypassSecurityTrustHtml(html);\n }\n\n private shouldUseWordDiff(oldValue: string, newValue: string): boolean {\n const hasMultipleWords = (text: string) => text.includes(' ') && text.split(' ').length > 3;\n const isLongText = (text: string) => text.length > 50;\n\n return (hasMultipleWords(oldValue) || hasMultipleWords(newValue)) && (isLongText(oldValue) || isLongText(newValue));\n }\n\n private escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n}\n","<mj-slide-panel\n [Mode]=\"'slide'\"\n [Title]=\"'Record Changes History'\"\n [Visible]=\"IsVisible\"\n [Resizable]=\"true\"\n [MinWidthPx]=\"400\"\n [MaxWidthRatio]=\"0.6\"\n (Closed)=\"OnClose()\">\n\n @if (IsLoading) {\n <mj-loading text=\"Loading history...\" size=\"medium\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <div class=\"rc-container\">\n <!-- Version Labels Section -->\n <div class=\"rc-labels-section\">\n <div class=\"rc-labels-header\">\n <div class=\"rc-labels-title\">\n <i class=\"fa-solid fa-tags\" aria-hidden=\"true\"></i>\n <span>Version Labels</span>\n @if (RecordLabels.length > 0) {\n <span class=\"rc-labels-count\">{{ RecordLabels.length }}</span>\n }\n </div>\n <button class=\"rc-create-label-btn\" (click)=\"OpenCreateWizard()\" title=\"Create a version label for this record\">\n <i class=\"fa-solid fa-plus\"></i> Create Label\n </button>\n </div>\n @if (IsLoadingLabels) {\n <div class=\"rc-labels-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading labels...\n </div>\n } @else if (RecordLabels.length === 0) {\n <div class=\"rc-labels-empty\">\n No version labels for this record yet.\n </div>\n } @else {\n <div class=\"rc-labels-list\">\n @for (label of RecordLabels; track label.ID) {\n <div class=\"rc-label-chip\" [title]=\"label.Description || label.Name\">\n <i class=\"fa-solid fa-tag rc-label-chip-icon\"></i>\n <span class=\"rc-label-chip-name\">{{ label.Name }}</span>\n <span class=\"rc-label-chip-meta\">\n <span class=\"rc-label-chip-status\" [class]=\"getLabelStatusClass(label.Status)\">{{ label.Status }}</span>\n <span class=\"rc-label-chip-items\">{{ label.ItemCount }} item{{ label.ItemCount !== 1 ? 's' : '' }}</span>\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n @if (viewData.length === 0) {\n <!-- Empty state -->\n <div class=\"rc-empty-state\">\n <div class=\"rc-empty-state-icon\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n </div>\n <h3 class=\"rc-empty-state-title\">No Change History</h3>\n <p class=\"rc-empty-state-description\">\n This record doesn't have any tracked changes yet.\n Changes will appear here automatically as edits are made.\n </p>\n <div class=\"rc-empty-state-hint\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Record change tracking is managed at the entity level</span>\n </div>\n </div>\n } @else {\n <!-- Page Header -->\n <div class=\"rc-page-header\">\n <div>\n <h2 class=\"rc-page-title\">Change History</h2>\n <div class=\"rc-page-subtitle\">{{ record.EntityInfo.Name }}</div>\n </div>\n <div class=\"rc-header-meta\">\n <div class=\"rc-entity-badge\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n {{ record.EntityInfo.Name }}\n </div>\n <div class=\"rc-change-count\">{{ viewData.length }} change{{ viewData.length !== 1 ? 's' : '' }} &middot; {{ getUniqueContributorCount() }} contributor{{ getUniqueContributorCount() !== 1 ? 's' : '' }}</div>\n </div>\n </div>\n\n <!-- Filter Bar — chips render only for change types/sources actually present in loaded data.\n When more than 2 conditional chips would render, they collapse into a \"More filters\" popover. -->\n <div class=\"rc-filter-bar\">\n <div class=\"rc-search-wrap\">\n <i class=\"fa-solid fa-search\" aria-hidden=\"true\"></i>\n <input\n class=\"rc-search-box\"\n type=\"text\"\n placeholder=\"Search changes...\"\n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchChange()\"\n aria-label=\"Search record changes\"\n />\n </div>\n\n <button class=\"rc-filter-pill\" [class.active]=\"IsAllSelected\" (click)=\"SelectAllPill()\" type=\"button\">\n <i class=\"fa-solid fa-layer-group\" aria-hidden=\"true\"></i> All\n </button>\n\n @if (HasConditionalPills) {\n @if (!UseOverflowPopover) {\n <!-- 1-2 conditional pills: render inline -->\n @for (pill of ConditionalPills; track pill.Key) {\n <button class=\"rc-filter-pill\"\n [class.active]=\"ChipSelections[pill.Key]\"\n [class.rc-filter-pill-restore]=\"pill.Variant === 'restore'\"\n (click)=\"TogglePill(pill.Key)\"\n type=\"button\">\n <i class=\"fa-solid {{ pill.Icon }}\" aria-hidden=\"true\"></i>\n {{ pill.Label }}\n <span class=\"rc-filter-pill-count\">{{ pill.Count }}</span>\n </button>\n }\n } @else {\n <!-- 3+ conditional pills: overflow popover -->\n <div class=\"rc-filter-overflow-wrap\">\n <button class=\"rc-filter-pill rc-filter-pill-overflow\"\n [class.active]=\"SelectedConditionalCount > 0\"\n (click)=\"ToggleFilterOverflow()\"\n type=\"button\">\n <i class=\"fa-solid fa-sliders\" aria-hidden=\"true\"></i>\n More filters\n @if (SelectedConditionalCount > 0) {\n <span class=\"rc-filter-pill-count\">{{ SelectedConditionalCount }}</span>\n }\n <i class=\"fa-solid fa-chevron-down rc-filter-overflow-caret\" aria-hidden=\"true\"></i>\n </button>\n\n @if (ShowFilterOverflow) {\n <!-- Backdrop: clicks close the popover -->\n <div class=\"rc-filter-overflow-backdrop\" (click)=\"CloseFilterOverflow()\"></div>\n <div class=\"rc-filter-overflow-popover\" role=\"menu\">\n <div class=\"rc-filter-overflow-header\">Filter by</div>\n @for (pill of ConditionalPills; track pill.Key) {\n <label class=\"rc-filter-overflow-row\" [class.rc-filter-overflow-row-restore]=\"pill.Variant === 'restore'\">\n <input type=\"checkbox\"\n [checked]=\"ChipSelections[pill.Key]\"\n (change)=\"TogglePill(pill.Key)\" />\n <i class=\"fa-solid {{ pill.Icon }}\" aria-hidden=\"true\"></i>\n <span class=\"rc-filter-overflow-label\">{{ pill.Label }}</span>\n <span class=\"rc-filter-overflow-count\">{{ pill.Count }}</span>\n </label>\n }\n <div class=\"rc-filter-overflow-actions\">\n <button class=\"rc-filter-overflow-clear\" (click)=\"SelectAllPill(); CloseFilterOverflow()\" type=\"button\">\n Clear all\n </button>\n <button class=\"rc-filter-overflow-done\" (click)=\"CloseFilterOverflow()\" type=\"button\">\n Done\n </button>\n </div>\n </div>\n }\n </div>\n }\n }\n </div>\n\n @if (filteredData.length !== viewData.length) {\n <div class=\"rc-filter-results\">\n Showing {{ filteredData.length }} of {{ viewData.length }} changes\n <button class=\"rc-clear-filters-link\" (click)=\"ClearFilters()\">Clear filters</button>\n </div>\n }\n\n <!-- Timeline -->\n <div class=\"rc-timeline\" [attr.aria-label]=\"'Timeline of changes for ' + record.EntityInfo.Name + ' record'\">\n @if (filteredData.length === 0) {\n <div class=\"rc-no-results\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n <p>No changes match your current filters.</p>\n <button class=\"rc-clear-filters-btn\" (click)=\"ClearFilters()\">\n <i class=\"fa-solid fa-xmark\"></i> Clear Filters\n </button>\n </div>\n } @else {\n @for (group of dateGroups; track group.label) {\n <div class=\"rc-date-group\">\n <div class=\"rc-date-label\">{{ group.label }}</div>\n\n @for (change of group.changes; track change.ID) {\n <div\n class=\"rc-card\"\n [attr.data-change-id]=\"change.ID\"\n [class]=\"getChangeTypeCardClass(change.Type)\"\n [class.expanded]=\"expandedItems.has(change.ID)\"\n [class.rc-card-restore]=\"isRestoreRow(change)\"\n [class.rc-card-highlight]=\"HighlightedChangeID === change.ID\"\n [attr.tabindex]=\"0\"\n [attr.aria-expanded]=\"expandedItems.has(change.ID)\"\n [attr.aria-label]=\"getTimelineItemLabel(change)\"\n (keydown)=\"onTimelineItemKeydown($event, change.ID)\"\n >\n <!-- Card Header -->\n <div class=\"rc-card-header\" (click)=\"toggleExpansion(change.ID)\">\n <div class=\"rc-card-header-left\">\n <span class=\"rc-card-type-badge\"\n [class.rc-card-type-badge-restore]=\"isRestoreRow(change)\">{{ getEffectiveBadgeText(change) }}</span>\n <span class=\"rc-card-summary\">{{ getChangeSummary(change) }}</span>\n\n <!-- Lineage chip — visible when this row was produced by a restore -->\n @if (isRestoreRow(change)) {\n @if (getRestoredFromSourceChange(change); as srcChange) {\n <a class=\"rc-restored-chip\"\n (click)=\"JumpToSourceChange(srcChange, $event)\"\n [title]=\"'Jump to source version (' + formatFullDateTime(srcChange.ChangedAt) + ')'\">\n <i class=\"fa-solid fa-link\" aria-hidden=\"true\"></i>\n Restored from {{ formatTime(srcChange.ChangedAt) }} {{ srcChange.ChangedAt ? 'on ' + (srcChange.ChangedAt | date:'mediumDate') : '' }}\n @if (srcChange.User) {\n by {{ getUserDisplayName(srcChange.User) }}\n }\n </a>\n } @else {\n <span class=\"rc-restored-chip rc-restored-chip-orphan\"\n title=\"Source version was not loaded into this view\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restored from earlier version\n </span>\n }\n }\n </div>\n <div class=\"rc-card-meta\">\n <div class=\"rc-card-user\">\n <div class=\"rc-avatar\">{{ getUserInitials(change.User) }}</div>\n {{ getUserDisplayName(change.User) }}\n </div>\n <span class=\"rc-card-time\" [title]=\"formatFullDateTime(change.ChangedAt)\">{{ formatTime(change.ChangedAt) }}</span>\n <span class=\"rc-card-source\" [class]=\"getSourceClass(change.Source)\">{{ change.Source }}</span>\n <span class=\"rc-card-status\" [class]=\"getStatusClass(change.Status)\">{{ change.Status }}</span>\n <i class=\"fa-solid fa-chevron-down rc-card-chevron\" aria-hidden=\"true\"></i>\n </div>\n </div>\n\n <!-- Card Body (expanded) -->\n @if (expandedItems.has(change.ID)) {\n <div class=\"rc-card-body\">\n <!-- Restore reason (when present) — Notion/Linear-style\n blockquote: a thin violet left bar + italic text,\n with a tiny \"Reason\" prefix. No box, no header,\n no large vertical footprint. Reads as a\n justification note rather than a callout. -->\n @if (getRestoreReason(change); as reason) {\n <blockquote class=\"rc-restore-reason\">\n <span class=\"rc-restore-reason-label\">Reason</span>\n <span class=\"rc-restore-reason-text\">{{ reason }}</span>\n </blockquote>\n }\n\n @if (change.Type === 'Create') {\n @if (change.FullRecordJSON) {\n @for (field of getCreatedFields(change); track field.name) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ field.displayName }}</div>\n <div class=\"rc-field-values\">\n <span class=\"rc-val-new\">{{ field.value }}</span>\n </div>\n </div>\n }\n }\n } @else if (change.Type === 'Delete') {\n <div class=\"rc-deletion-note\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n This record was permanently removed from the system.\n </div>\n } @else {\n <!-- Update / Snapshot / Restore: type-aware field changes -->\n @for (fc of getFieldChanges(change); track fc.field) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ fc.displayName }}</div>\n <div class=\"rc-field-values\">\n @if (fc.fieldType === 'boolean') {\n <div class=\"rc-bool-change\">\n <span class=\"rc-bool-dot\" [class.on]=\"fc.oldValue === 'true' || fc.oldValue === '1'\" [class.off]=\"fc.oldValue !== 'true' && fc.oldValue !== '1'\"></span>\n <span class=\"rc-bool-label old\">{{ fc.oldValue === 'true' || fc.oldValue === '1' ? 'Yes' : 'No' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-bool-dot\" [class.on]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.off]=\"fc.newValue !== 'true' && fc.newValue !== '1'\"></span>\n <span class=\"rc-bool-label new\" [class.active]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.inactive]=\"fc.newValue !== 'true' && fc.newValue !== '1'\">{{ fc.newValue === 'true' || fc.newValue === '1' ? 'Yes' : 'No' }}</span>\n </div>\n } @else if (fc.fieldType === 'date' || fc.fieldType === 'number') {\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n } @else if (fc.diffHtml) {\n <div class=\"rc-text-diff\" [innerHTML]=\"fc.diffHtml\"></div>\n } @else {\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n }\n </div>\n </div>\n }\n }\n\n @if (change.Comments) {\n <div class=\"rc-comments\">\n <i class=\"fa-solid fa-comment\" aria-hidden=\"true\"></i>\n {{ change.Comments }}\n </div>\n }\n\n @if (change.ErrorLog) {\n <div class=\"rc-errors\">\n <i class=\"fa-solid fa-exclamation-triangle\" aria-hidden=\"true\"></i>\n <pre class=\"rc-error-log\">{{ change.ErrorLog }}</pre>\n </div>\n }\n\n <!-- Restore action: shown for Update, Create, and Snapshot rows.\n Hidden on Delete rows (handled via the Recycle Bin path)\n and on the most recent change (restoring to current state is a no-op). -->\n @if (AllowRestore && change.Type !== 'Delete' && !isMostRecentChange(change)) {\n <div class=\"rc-restore-action\">\n <button class=\"rc-restore-btn\"\n (click)=\"OnRestoreVersion(change, $event)\"\n title=\"Restore the entire record to its state at this version\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restore record to this version\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n\n <!-- Restore preview slide-in (reusable component) -->\n <mj-restore-preview-panel\n [Visible]=\"RestorePreviewVisible\"\n [Mode]=\"'live'\"\n [RecordChange]=\"RestorePreviewChange\"\n [LiveRecord]=\"record\"\n (RestoreConfirmed)=\"OnRestorePanelConfirmed($event)\"\n (RestoreCancelled)=\"OnRestorePanelCancelled()\">\n </mj-restore-preview-panel>\n\n @if (ShowCreateWizard) {\n <div class=\"rc-wizard-overlay\" (click)=\"OnLabelCreateCancelled()\">\n <div class=\"rc-wizard-container\" (click)=\"$event.stopPropagation()\">\n <mj-label-create\n [PreselectedEntity]=\"record.EntityInfo\"\n [PreselectedRecordIds]=\"[record.PrimaryKey.KeyValuePairs[0].Value]\"\n (Created)=\"OnLabelCreated($event)\"\n (Cancel)=\"OnLabelCreateCancelled()\">\n </mj-label-create>\n </div>\n </div>\n }\n</mj-slide-panel>\n"]}
@@ -1,12 +1,13 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import * as i1 from "./ng-record-changes.component";
3
- import * as i2 from "@angular/common";
4
- import * as i3 from "@angular/forms";
5
- import * as i4 from "@memberjunction/ng-shared-generic";
6
- import * as i5 from "@memberjunction/ng-versions";
3
+ import * as i2 from "./restore-preview-panel/restore-preview-panel.component";
4
+ import * as i3 from "@angular/common";
5
+ import * as i4 from "@angular/forms";
6
+ import * as i5 from "@memberjunction/ng-shared-generic";
7
+ import * as i6 from "@memberjunction/ng-versions";
7
8
  export declare class RecordChangesModule {
8
9
  static ɵfac: i0.ɵɵFactoryDeclaration<RecordChangesModule, never>;
9
- static ɵmod: i0.ɵɵNgModuleDeclaration<RecordChangesModule, [typeof i1.RecordChangesComponent], [typeof i2.CommonModule, typeof i3.FormsModule, typeof i4.SharedGenericModule, typeof i5.VersionsModule], [typeof i1.RecordChangesComponent]>;
10
+ static ɵmod: i0.ɵɵNgModuleDeclaration<RecordChangesModule, [typeof i1.RecordChangesComponent, typeof i2.RestorePreviewPanelComponent], [typeof i3.CommonModule, typeof i4.FormsModule, typeof i5.SharedGenericModule, typeof i6.VersionsModule], [typeof i1.RecordChangesComponent, typeof i2.RestorePreviewPanelComponent]>;
10
11
  static ɵinj: i0.ɵɵInjectorDeclaration<RecordChangesModule>;
11
12
  }
12
13
  //# sourceMappingURL=ng-record-changes.module.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ng-record-changes.module.d.ts","sourceRoot":"","sources":["../../src/lib/ng-record-changes.module.ts"],"names":[],"mappings":";;;;;;AAQA,qBAca,mBAAmB;yCAAnB,mBAAmB;0CAAnB,mBAAmB;0CAAnB,mBAAmB;CAAG"}
1
+ {"version":3,"file":"ng-record-changes.module.d.ts","sourceRoot":"","sources":["../../src/lib/ng-record-changes.module.ts"],"names":[],"mappings":";;;;;;;AASA,qBAgBa,mBAAmB;yCAAnB,mBAAmB;0CAAnB,mBAAmB;0CAAnB,mBAAmB;CAAG"}
@@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { FormsModule } from '@angular/forms';
4
4
  import { RecordChangesComponent } from './ng-record-changes.component';
5
+ import { RestorePreviewPanelComponent } from './restore-preview-panel/restore-preview-panel.component';
5
6
  import { SharedGenericModule } from '@memberjunction/ng-shared-generic';
6
7
  import { VersionsModule } from '@memberjunction/ng-versions';
7
8
  import * as i0 from "@angular/core";
@@ -17,7 +18,8 @@ export class RecordChangesModule {
17
18
  type: NgModule,
18
19
  args: [{
19
20
  declarations: [
20
- RecordChangesComponent
21
+ RecordChangesComponent,
22
+ RestorePreviewPanelComponent
21
23
  ],
22
24
  imports: [
23
25
  CommonModule,
@@ -26,12 +28,15 @@ export class RecordChangesModule {
26
28
  VersionsModule
27
29
  ],
28
30
  exports: [
29
- RecordChangesComponent
31
+ RecordChangesComponent,
32
+ RestorePreviewPanelComponent
30
33
  ]
31
34
  }]
32
35
  }], null, null); })();
33
- (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(RecordChangesModule, { declarations: [RecordChangesComponent], imports: [CommonModule,
36
+ (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(RecordChangesModule, { declarations: [RecordChangesComponent,
37
+ RestorePreviewPanelComponent], imports: [CommonModule,
34
38
  FormsModule,
35
39
  SharedGenericModule,
36
- VersionsModule], exports: [RecordChangesComponent] }); })();
40
+ VersionsModule], exports: [RecordChangesComponent,
41
+ RestorePreviewPanelComponent] }); })();
37
42
  //# sourceMappingURL=ng-record-changes.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ng-record-changes.module.js","sourceRoot":"","sources":["../../src/lib/ng-record-changes.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;;AAgB7D,MAAM,OAAO,mBAAmB;6GAAnB,mBAAmB;4DAAnB,mBAAmB;gEAT5B,YAAY;YACZ,WAAW;YACX,mBAAmB;YACnB,cAAc;;iFAML,mBAAmB;cAd/B,QAAQ;eAAC;gBACR,YAAY,EAAE;oBACZ,sBAAsB;iBACvB;gBACD,OAAO,EAAE;oBACP,YAAY;oBACZ,WAAW;oBACX,mBAAmB;oBACnB,cAAc;iBACf;gBACD,OAAO,EAAE;oBACP,sBAAsB;iBACvB;aACF;;wFACY,mBAAmB,mBAZ5B,sBAAsB,aAGtB,YAAY;QACZ,WAAW;QACX,mBAAmB;QACnB,cAAc,aAGd,sBAAsB","sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\n\nimport { RecordChangesComponent } from './ng-record-changes.component';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { VersionsModule } from '@memberjunction/ng-versions';\n\n@NgModule({\n declarations: [\n RecordChangesComponent\n ],\n imports: [\n CommonModule,\n FormsModule,\n SharedGenericModule,\n VersionsModule\n ],\n exports: [\n RecordChangesComponent\n ]\n})\nexport class RecordChangesModule {}\n"]}
1
+ {"version":3,"file":"ng-record-changes.module.js","sourceRoot":"","sources":["../../src/lib/ng-record-changes.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yDAAyD,CAAC;AACvG,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;;AAkB7D,MAAM,OAAO,mBAAmB;6GAAnB,mBAAmB;4DAAnB,mBAAmB;gEAV5B,YAAY;YACZ,WAAW;YACX,mBAAmB;YACnB,cAAc;;iFAOL,mBAAmB;cAhB/B,QAAQ;eAAC;gBACR,YAAY,EAAE;oBACZ,sBAAsB;oBACtB,4BAA4B;iBAC7B;gBACD,OAAO,EAAE;oBACP,YAAY;oBACZ,WAAW;oBACX,mBAAmB;oBACnB,cAAc;iBACf;gBACD,OAAO,EAAE;oBACP,sBAAsB;oBACtB,4BAA4B;iBAC7B;aACF;;wFACY,mBAAmB,mBAd5B,sBAAsB;QACtB,4BAA4B,aAG5B,YAAY;QACZ,WAAW;QACX,mBAAmB;QACnB,cAAc,aAGd,sBAAsB;QACtB,4BAA4B","sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\n\nimport { RecordChangesComponent } from './ng-record-changes.component';\nimport { RestorePreviewPanelComponent } from './restore-preview-panel/restore-preview-panel.component';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { VersionsModule } from '@memberjunction/ng-versions';\n\n@NgModule({\n declarations: [\n RecordChangesComponent,\n RestorePreviewPanelComponent\n ],\n imports: [\n CommonModule,\n FormsModule,\n SharedGenericModule,\n VersionsModule\n ],\n exports: [\n RecordChangesComponent,\n RestorePreviewPanelComponent\n ]\n})\nexport class RecordChangesModule {}\n"]}