import { ChangeDetectorRef, EventEmitter, OnInit } from '@angular/core'; import { BaseEntity } from '@memberjunction/core'; import { MJRecordChangeEntity } from '@memberjunction/core-entities'; import { BaseAngularComponent } from '@memberjunction/ng-base-types'; import * as i0 from "@angular/core"; /** * Mode controls how the preview is rendered and how the restore is interpreted. * * - `'live'`: target record exists; the preview shows a current-vs-restore * diff per field. Confirming applies the snapshot to the live record and * triggers an UPDATE. * - `'undelete'`: target record was hard-deleted. The preview shows the * snapshot fields that will be inserted; confirming triggers an INSERT. */ export type RestorePreviewMode = 'live' | 'undelete'; /** * One row in the restore preview table. * * Renders as a checkbox + field name + (current / restore) values. The * `IsChanged` flag drives the default-checked state and the row's visual * treatment. `IsMissingInSchema` and `IsFKMissing` surface drift warnings. */ export interface RestoreFieldRow { /** Raw field name (matches EntityField.Name). */ FieldName: string; /** Friendly label (EntityField.DisplayNameOrName). */ DisplayName: string; /** Formatted current value of the live record (empty in undelete mode). */ CurrentValue: string; /** Formatted snapshot value that would be applied. */ RestoreValue: string; /** Raw snapshot value (the value passed to BaseEntity.Set). */ RawRestoreValue: unknown; /** True when CurrentValue and RestoreValue differ. Drives default checked. */ IsChanged: boolean; /** User's selection — when true, this field will be applied on restore. */ Selected: boolean; /** True when the snapshot references a field that no longer exists on the entity. */ IsMissingInSchema: boolean; /** True when the field is a FK whose target row no longer exists (best-effort). */ IsFKMissing: boolean; /** True when the field is read-only / system / PK and cannot be restored. */ IsImmutable: boolean; } /** * Cancelable event fired immediately after the user clicks Restore but * before {@link RestorePreviewPanelComponent.RestoreConfirmed} emits. * * Consumers can set `cancel = true` (and optionally `cancelReason`) to abort * the restore — useful for custom approval workflows, audit logging hooks, * or for a consumer that wants to take over the actual save itself. */ export interface BeforeRestoreCommitEvent { /** Set to true to abort. RestoreConfirmed will not fire. */ cancel: boolean; /** Optional explanation surfaced by the consumer. */ cancelReason?: string; /** Selected field names (only fields the user kept checked). */ SelectedFieldNames: string[]; /** The full set of rows in the preview, including unselected. */ AllRows: RestoreFieldRow[]; /** ID of the source RecordChange row whose state is being restored. */ SourceChangeID: string; /** Optional reason text the user entered. */ Reason: string | null; /** The mode — 'live' (UPDATE) or 'undelete' (INSERT). */ Mode: RestorePreviewMode; } /** * Event payload emitted after the user has confirmed a restore. * * The host component is responsible for applying the snapshot to a * BaseEntity instance, calling {@link BaseEntity.SetRestoreContext}, and * invoking Save(). This component never touches the database directly so * it remains usable in any consumer context. */ export interface RestoreCommitEvent { /** ID of the source RecordChange row whose state is being restored. */ SourceChangeID: string; /** Optional user-entered reason; persisted to RecordChange.RestoreReason. */ Reason: string | null; /** Selected fields with their snapshot values, ready for BaseEntity.Set. */ FieldValues: Array<{ FieldName: string; Value: unknown; }>; /** The full preview rows (including unselected) for audit/logging. */ AllRows: RestoreFieldRow[]; /** Mode indicates UPDATE (live) vs INSERT (undelete). */ Mode: RestorePreviewMode; } /** * Reusable slide-in panel that previews a restore operation against a * historical {@link MJRecordChangeEntity} and lets the user confirm with * field-level granularity. * * This component is rendered by both: * - The Record Changes timeline (for restoring a live record from any past * change row) * - The Recycle Bin (for re-creating a hard-deleted record from its delete * snapshot) * * It does NOT perform the save itself — the host component receives a * {@link RestoreCommitEvent} with the selected field values and is * responsible for applying them to a BaseEntity, setting the restore * context, and calling Save(). This keeps the component purely * presentational and reusable in any context. * * ### Semantic correctness * * The preview compares the **full snapshot** captured in the source * change's `FullRecordJSON` to the current live record (or to nothing in * un-delete mode). It does NOT roll back a single delta — restoring `v2` * means "make the record look like it did at v2", not "undo v3's changes". * * @example Live restore from the timeline * * * * @example Un-delete from the Recycle Bin * * */ export declare class RestorePreviewPanelComponent extends BaseAngularComponent implements OnInit { private cdr; /** * Controls panel visibility. Setting to true opens the slide-in; * setting to false closes it. On every closed→open transition the * panel auto-resets its transient state (`IsRestoring`, `Reason`, * `ShowUnchanged`, row checks) so the host doesn't have to remember * to call `Reset()` after a restore completes. */ private _visible; set Visible(value: boolean); get Visible(): boolean; /** * Operating mode — `'live'` for restoring an existing record from a * snapshot, `'undelete'` for re-creating a hard-deleted record. */ Mode: RestorePreviewMode; /** * The historical RecordChange row whose state will be restored. Required. * The component reads `FullRecordJSON` from this entity to determine the * target state. The change's `Type` does not matter — `Create`, * `Update`, `Snapshot`, and `Delete` are all valid restore sources. */ private _recordChange; set RecordChange(value: MJRecordChangeEntity | null); get RecordChange(): MJRecordChangeEntity | null; /** * The current live record to diff against. Required in `'live'` mode, * ignored in `'undelete'` mode (since the live record no longer exists). */ private _liveRecord; set LiveRecord(value: BaseEntity | null); get LiveRecord(): BaseEntity | null; /** * The entity name. Required in `'undelete'` mode (since there's no live * record to read it from). In `'live'` mode it can be omitted and is * inferred from the LiveRecord. */ EntityName: string | null; /** * When true, the Restore button is disabled until the user enters a * non-empty reason. Useful for regulated environments where every * reversal needs justification. Default: false. */ RequireReason: boolean; /** * When true, hides the optional reason text area entirely. Default: false. */ HideReason: boolean; /** * Cancelable event fired when the user clicks Restore but before * {@link RestoreConfirmed} emits. Consumers can set `cancel = true` on * the event arg to abort the operation — useful for custom approval * workflows or for taking over the save themselves. */ BeforeRestoreCommit: EventEmitter; /** * Emitted after the user confirms the restore (and BeforeRestoreCommit * was not cancelled). The host is responsible for applying the field * values to a BaseEntity, calling SetRestoreContext, and invoking Save(). */ RestoreConfirmed: EventEmitter; /** * Emitted when the user cancels the preview without restoring. */ RestoreCancelled: EventEmitter; Rows: RestoreFieldRow[]; Reason: string; IsRestoring: boolean; ShowUnchanged: boolean; /** Number of rows where the current value differs from the snapshot. */ ChangedCount: number; /** Number of rows that are checked (will be applied on restore). */ SelectedCount: number; /** Number of rows the schema has dropped or renamed since the snapshot. */ DriftCount: number; private isInitialized; private resolvedEntityInfo; constructor(cdr: ChangeDetectorRef); ngOnInit(): void; /** * Toggles whether unchanged rows are visible in the table. When false * (default), only rows where current ≠ snapshot are shown. */ ToggleUnchanged(): void; /** * Toggles whether a single row is selected for restore. Updates the * SelectedCount in real time so the primary button label reflects it. */ ToggleRow(row: RestoreFieldRow): void; /** * Selects every row that can be selected (skips immutable / drifted). */ SelectAll(): void; /** * Deselects every row in the preview. */ DeselectAll(): void; /** * User clicked Restore — fire BeforeRestoreCommit (cancelable), then * RestoreConfirmed if not cancelled. */ ConfirmRestore(): void; /** * User cancelled the preview. Resets state and emits RestoreCancelled. */ Cancel(): void; /** * Resets internal state — useful after a save completes so the panel * can be reopened cleanly. Called by the host component when needed. */ Reset(): void; get IsRestoreDisabled(): boolean; get RestoreButtonLabel(): string; get HeaderTitle(): string; get VersionTimestamp(): Date | null; get VersionUser(): string; get UnchangedCount(): number; /** * Rebuilds the Rows array from the current RecordChange + LiveRecord. * Idempotent and cheap — safe to call from input setters. */ private rebuildRows; private buildRowFromSnapshot; private getCurrentFieldValue; private parseSnapshot; /** * Resolves the entity metadata. Prefers LiveRecord.EntityInfo (always * accurate). Falls back to looking up by EntityName. Memoized. */ private resolveEntityInfo; private formatValue; private recountSelected; formatTimestamp(date: Date | null): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } //# sourceMappingURL=restore-preview-panel.component.d.ts.map