@memberjunction/ng-record-clone 0.0.0 → 6.2.0-edge.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +183 -0
- package/README.md +225 -28
- package/dist/lib/clone-lineage-chip.component.d.ts +50 -0
- package/dist/lib/clone-lineage-chip.component.d.ts.map +1 -0
- package/dist/lib/clone-lineage-chip.component.js +448 -0
- package/dist/lib/clone-lineage-chip.component.js.map +1 -0
- package/dist/lib/clone-plan-tree.component.d.ts +51 -0
- package/dist/lib/clone-plan-tree.component.d.ts.map +1 -0
- package/dist/lib/clone-plan-tree.component.js +634 -0
- package/dist/lib/clone-plan-tree.component.js.map +1 -0
- package/dist/lib/clone-progress.component.d.ts +12 -0
- package/dist/lib/clone-progress.component.d.ts.map +1 -0
- package/dist/lib/clone-progress.component.js +151 -0
- package/dist/lib/clone-progress.component.js.map +1 -0
- package/dist/lib/clone-result.component.d.ts +40 -0
- package/dist/lib/clone-result.component.d.ts.map +1 -0
- package/dist/lib/clone-result.component.js +357 -0
- package/dist/lib/clone-result.component.js.map +1 -0
- package/dist/lib/clone-review.component.d.ts +58 -0
- package/dist/lib/clone-review.component.d.ts.map +1 -0
- package/dist/lib/clone-review.component.js +581 -0
- package/dist/lib/clone-review.component.js.map +1 -0
- package/dist/lib/clone-scope-controls.component.d.ts +81 -0
- package/dist/lib/clone-scope-controls.component.d.ts.map +1 -0
- package/dist/lib/clone-scope-controls.component.js +394 -0
- package/dist/lib/clone-scope-controls.component.js.map +1 -0
- package/dist/lib/clone-values.component.d.ts +55 -0
- package/dist/lib/clone-values.component.d.ts.map +1 -0
- package/dist/lib/clone-values.component.js +493 -0
- package/dist/lib/clone-values.component.js.map +1 -0
- package/dist/lib/record-clone-panel.component.d.ts +247 -0
- package/dist/lib/record-clone-panel.component.d.ts.map +1 -0
- package/dist/lib/record-clone-panel.component.js +1252 -0
- package/dist/lib/record-clone-panel.component.js.map +1 -0
- package/dist/lib/record-clone-slide-in.component.d.ts +83 -0
- package/dist/lib/record-clone-slide-in.component.d.ts.map +1 -0
- package/dist/lib/record-clone-slide-in.component.js +206 -0
- package/dist/lib/record-clone-slide-in.component.js.map +1 -0
- package/dist/lib/record-clone-types.d.ts +89 -0
- package/dist/lib/record-clone-types.d.ts.map +1 -0
- package/dist/lib/record-clone-types.js +29 -0
- package/dist/lib/record-clone-types.js.map +1 -0
- package/dist/lib/record-clone.module.d.ts +16 -0
- package/dist/lib/record-clone.module.d.ts.map +1 -0
- package/dist/lib/record-clone.module.js +69 -0
- package/dist/lib/record-clone.module.js.map +1 -0
- package/dist/lib/record-clone.service.d.ts +42 -0
- package/dist/lib/record-clone.service.d.ts.map +1 -0
- package/dist/lib/record-clone.service.js +123 -0
- package/dist/lib/record-clone.service.js.map +1 -0
- package/dist/public-api.d.ts +16 -0
- package/dist/public-api.d.ts.map +1 -0
- package/dist/public-api.js +16 -0
- package/dist/public-api.js.map +1 -0
- package/package.json +49 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-clone-panel.component.js","sourceRoot":"","sources":["../../src/lib/record-clone-panel.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Embeddable record clone panel.\n *\n * Implements §12.2 and §12.3 of the record cloning plan. Hosts the full clone wizard\n * (loading, scope, values, review, executing, done, failed, not cloneable) inline, with no\n * overlay of its own, so it can sit in a slide-in, a dialog, a dashboard or a test harness.\n * {@link RecordCloneSlideInComponent} wraps it in MJ's generic slide panel.\n *\n * The panel never navigates. It reports what happened through outputs and the host decides:\n * `NavigateToRecord` carries the record to open, `CloseRequested` asks the host to dismiss it.\n */\n\nimport {\n Component,\n ChangeDetectionStrategy,\n Input,\n Output,\n EventEmitter,\n ChangeDetectorRef,\n inject,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { BaseEntity, BaseEntityEvent, CompositeKey } from '@memberjunction/core';\nimport { MJGlobal, MJEventType, type FieldRuleSet } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { NormalizeClonePresets, type CloneRequestOptions } from '@memberjunction/record-cloning-base';\nimport type {\n RecordCloneKey,\n RecordCloneDescribeOutput,\n RecordClonePlanDetails,\n RecordClonePlanOptions,\n RecordClonePlanNode,\n RecordCloneExecuteOutput,\n} from '@memberjunction/core-entities';\nimport {\n MJButtonDirective,\n MJTabNavComponent,\n TabConfig,\n} from '@memberjunction/ng-ui-components';\n\nimport { RecordCloneService } from './record-clone.service';\nimport { CloneScopeControlsComponent } from './clone-scope-controls.component';\nimport { ClonePlanTreeComponent } from './clone-plan-tree.component';\nimport { CloneValuesComponent } from './clone-values.component';\nimport { CloneReviewComponent } from './clone-review.component';\nimport { CloneProgressComponent } from './clone-progress.component';\nimport { CloneResultComponent } from './clone-result.component';\n\nimport type {\n RecordClonePanelState,\n RecordCloneStep,\n CloneCompletedEvent,\n CloneFailedEvent,\n CloneNavigationEvent,\n CloneProgressUpdate,\n ClonePromptFieldItem,\n CloneRetargetFieldItem,\n CloneEdgePolicyChange,\n} from './record-clone-types';\nimport type { CloneScopeValues } from './clone-scope-controls.component';\nimport {\n EntityToRecordCloneKey,\n CompositeKeyToRecordCloneKey,\n} from './record-clone-types';\n\n/** Plan options the scope step edits. */\ntype ScopeOptionKey = 'MaxDepth' | 'MaxRecords' | 'Subtypes' | 'Hierarchy' | 'SoftLinks' | 'EntityActions';\nconst SCOPE_OPTION_KEYS: readonly ScopeOptionKey[] = ['MaxDepth', 'MaxRecords', 'Subtypes', 'Hierarchy', 'SoftLinks', 'EntityActions'];\n\n/**\n * Embeddable clone wizard for one source record.\n *\n * Give it a source with either {@link Record} or {@link EntityName} plus {@link RecordKey}.\n * With {@link AutoStart} on (the default) it describes the record and computes the first plan\n * as soon as it has a source; otherwise call {@link Start}.\n *\n * @example\n * ```html\n * <mj-record-clone-panel\n * [Record]=\"record\"\n * (CloneCompleted)=\"OnCloned($event)\"\n * (NavigateToRecord)=\"OpenRecord($event)\"\n * (CloseRequested)=\"HidePanel()\">\n * </mj-record-clone-panel>\n * ```\n */\n@Component({\n standalone: true,\n selector: 'mj-record-clone-panel',\n template: `\n <div class=\"clone-panel-content\">\n <!-- Wizard Navigation Tabs (visible during authoring steps) -->\n @if (ShowWizardTabs) {\n <div class=\"panel-tabs-wrapper\">\n <mj-tab-nav\n [Tabs]=\"WizardTabs\"\n [ActiveKey]=\"CurrentStep\"\n (TabChange)=\"OnStepChange($event)\">\n </mj-tab-nav>\n </div>\n }\n\n <!-- Step Body -->\n <div class=\"panel-body\">\n <!-- Loading State -->\n @if (CurrentState === 'loading') {\n <div class=\"panel-state-center\">\n <mj-loading [Text]=\"LoadingMessage\" Size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Not Cloneable State -->\n @if (CurrentState === 'not_cloneable') {\n <div class=\"panel-state-center not-cloneable-card\">\n <i class=\"fa-solid fa-ban not-cloneable-icon\"></i>\n <h3 class=\"state-title\">Record Cannot Be Cloned</h3>\n <p class=\"state-description\">{{NotCloneableReason}}</p>\n <button\n type=\"button\"\n mjButton\n variant=\"outline\"\n (click)=\"OnClose()\">\n Close\n </button>\n </div>\n }\n\n <!-- Scope Step -->\n <!-- Wizard steps only while the wizard is active: after Execute the result (or failure) replaces them. -->\n @if (ShowWizardTabs && (CurrentState === 'scope' || CurrentStep === 'scope')) {\n <div class=\"step-container\" [class.step-hidden]=\"CurrentStep !== 'scope'\">\n <mj-clone-scope-controls\n [Presets]=\"AvailablePresets\"\n [PresetLabels]=\"PresetLabels\"\n [SelectedPreset]=\"SelectedPreset\"\n [MaxDepth]=\"DisplayedScope.MaxDepth\"\n [Subtypes]=\"DisplayedScope.Subtypes\"\n [Hierarchy]=\"DisplayedScope.Hierarchy\"\n [SoftLinks]=\"DisplayedScope.SoftLinks\"\n [EntityActions]=\"DisplayedScope.EntityActions\"\n [MaxRecords]=\"DisplayedScope.MaxRecords\"\n [ConfiguredScope]=\"ConfiguredScope\"\n [EntityName]=\"EffectiveEntityName\"\n [CanOverrideScope]=\"CanOverrideScope\"\n (ScopeChanged)=\"OnScopeOptionsChanged($event)\"\n (ResetToDefaults)=\"OnResetScopeToDefaults()\">\n </mj-clone-scope-controls>\n\n <div class=\"tree-section\">\n <h4 class=\"section-heading\">Planned Record Graph</h4>\n <mj-clone-plan-tree\n [Plan]=\"ActivePlan\"\n [AllowNarrowing]=\"CanNarrowScope\"\n [AllowWidening]=\"CanOverrideScope\"\n (NodeSelected)=\"OnNodeSelected($event)\"\n (EdgePolicyChanged)=\"OnEdgePolicyChanged($event)\">\n </mj-clone-plan-tree>\n @if (EdgeOverrides.length > 0) {\n <div class=\"branch-overrides\">\n @for (o of EdgeOverrides; track o.RelationshipID) {\n <span class=\"branch-override\">\n {{ o.Policy === 'Skip' ? 'Skipping' : 'Copying' }} {{ o.RelatedEntityName || 'a relationship' }}\n <button type=\"button\" class=\"undo-btn\" (click)=\"OnUndoEdgeOverride(o.RelationshipID)\"\n [attr.aria-label]=\"'Undo: ' + (o.Policy === 'Skip' ? 'copy ' : 'skip ') + (o.RelatedEntityName || 'this relationship') + ' again'\">Undo</button>\n </span>\n }\n </div>\n }\n @if (CanNarrowScope) {\n <p class=\"tree-hint\">Click Deep on a branch to skip all of its rows.{{ CanOverrideScope ? ' Click Skip to copy a branch the configuration leaves out.' : '' }}</p>\n }\n </div>\n\n <div class=\"step-footer\">\n <div></div>\n <button\n type=\"button\"\n mjButton\n variant=\"primary\"\n [disabled]=\"!ActivePlan\"\n (click)=\"GoToStep('values')\">\n Next: Values & Retarget\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n </div>\n }\n\n <!-- Values Step -->\n @if (ShowWizardTabs && (CurrentState === 'values' || CurrentStep === 'values')) {\n <div class=\"step-container\" [class.step-hidden]=\"CurrentStep !== 'values'\">\n <mj-clone-values\n [EntityName]=\"EffectiveEntityName\"\n [RootName]=\"RootRecordName\"\n [RootNameReadOnly]=\"RootNameReadOnly\"\n [NamingStrategyReason]=\"NamingStrategyReason\"\n [PromptedFields]=\"PromptedFields\"\n [PromptedValues]=\"PromptedValues\"\n [RetargetFields]=\"RetargetFields\"\n [Reason]=\"CloneReason\"\n (RootNameChange)=\"OnRootNameChange($event)\"\n (PromptedValuesChange)=\"OnPromptedValuesChange($event)\"\n (RetargetFieldsChange)=\"OnRetargetFieldsChange($event)\"\n (ReasonChange)=\"OnReasonChange($event)\"\n (ValidityChange)=\"OnValuesValidityChange($event)\">\n </mj-clone-values>\n\n <div class=\"step-footer\">\n <button\n type=\"button\"\n mjButton\n variant=\"outline\"\n (click)=\"GoToStep('scope')\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back to Scope\n </button>\n <button\n type=\"button\"\n mjButton\n variant=\"primary\"\n [disabled]=\"!IsValuesValid\"\n (click)=\"GoToStep('review')\">\n Next: Review & Execute\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n </div>\n </div>\n }\n\n <!-- Review Step -->\n @if ((ShowWizardTabs || CurrentState === 'executing') && (CurrentState === 'review' || CurrentStep === 'review')) {\n <div class=\"step-container\" [class.step-hidden]=\"CurrentStep !== 'review'\">\n @if (PlanChangedNotice) {\n <div class=\"plan-changed-notice\" role=\"status\">\n <i class=\"fa-solid fa-rotate\"></i>\n <span>{{ PlanChangedNotice }}</span>\n </div>\n }\n <mj-clone-review\n [Plan]=\"ActivePlan\"\n [RootName]=\"RootRecordName\"\n [Reason]=\"CloneReason\"\n [IsExecuting]=\"CurrentState === 'executing'\"\n [IsPlanning]=\"IsReplanning\"\n (Confirm)=\"ExecuteClone()\"\n (Cancel)=\"OnClose()\"\n (NodeClicked)=\"OnReviewNodeClicked($event)\">\n </mj-clone-review>\n\n @if (CurrentState !== 'executing') {\n <div class=\"step-footer\">\n <button\n type=\"button\"\n mjButton\n variant=\"outline\"\n (click)=\"GoToStep('values')\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back to Values\n </button>\n </div>\n }\n </div>\n }\n\n <!-- Executing State -->\n @if (CurrentState === 'executing') {\n <div class=\"step-container\">\n <mj-clone-progress\n [Progress]=\"ExecutionProgress\">\n </mj-clone-progress>\n </div>\n }\n\n <!-- Done State -->\n @if (CurrentState === 'done') {\n <div class=\"step-container\">\n <mj-clone-result\n [Result]=\"ExecutionResult\"\n [EntityName]=\"EffectiveEntityName\"\n [TargetKey]=\"TargetRecordKey\"\n [RootRecordName]=\"RootRecordName\"\n (CloneAnother)=\"Reset()\"\n (Close)=\"OnClose()\"\n (NavigateToRecord)=\"OnNavigateToRecord($event)\">\n </mj-clone-result>\n </div>\n }\n\n <!-- Failed State -->\n @if (CurrentState === 'failed') {\n <div class=\"panel-state-center failed-card\">\n <i class=\"fa-solid fa-circle-exclamation failed-icon\"></i>\n <h3 class=\"state-title failed-text\">Execution Error</h3>\n <p class=\"state-description\">{{ExecutionErrorMessage}}</p>\n <div class=\"state-actions\">\n <button\n type=\"button\"\n mjButton\n variant=\"primary\"\n (click)=\"BackToReview()\">\n Back to Review\n </button>\n <button\n type=\"button\"\n mjButton\n variant=\"outline\"\n (click)=\"OnClose()\">\n Close\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n `,\n styles: [`\n .plan-changed-notice {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n margin-bottom: var(--mj-space-3);\n padding: var(--mj-space-2) var(--mj-space-3);\n border: 1px solid var(--mj-status-warning-border);\n border-radius: var(--mj-radius-md);\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n }\n .clone-panel-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface);\n }\n\n .panel-tabs-wrapper {\n padding: var(--mj-space-2) var(--mj-space-4);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .panel-body {\n flex: 1;\n overflow-y: auto;\n padding: var(--mj-space-4);\n display: flex;\n flex-direction: column;\n }\n\n .step-container {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-4);\n }\n\n .step-hidden {\n display: none !important;\n }\n\n .tree-section {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1-5);\n margin-top: var(--mj-space-1);\n }\n\n .branch-overrides {\n display: flex;\n flex-wrap: wrap;\n gap: var(--mj-space-2);\n }\n\n .branch-override {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: 2px 4px 2px var(--mj-space-2-5);\n border: 1px solid var(--mj-status-warning-border);\n border-radius: var(--mj-radius-full);\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n font-size: var(--mj-text-xs);\n }\n\n .undo-btn {\n border: 0;\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-family: inherit;\n font-size: var(--mj-text-xs);\n padding: 1px var(--mj-space-2);\n cursor: pointer;\n }\n\n .undo-btn:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n }\n\n .tree-hint {\n margin: 0;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n }\n\n .section-heading {\n margin: 0;\n font-size: var(--mj-text-sm);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .step-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding-top: var(--mj-space-4);\n border-top: 1px solid var(--mj-border-default);\n margin-top: var(--mj-space-4);\n }\n\n .panel-state-center {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--mj-space-12) var(--mj-space-6);\n gap: var(--mj-space-3);\n }\n\n .not-cloneable-icon {\n font-size: 36px;\n color: var(--mj-status-warning-text);\n }\n\n .failed-icon {\n font-size: 36px;\n color: var(--mj-status-error-text);\n }\n\n .state-title {\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .failed-text {\n color: var(--mj-status-error-text);\n }\n\n .state-description {\n margin: 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n max-width: 400px;\n }\n\n .state-actions {\n display: flex;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n }\n `],\n imports: [\n CommonModule,\n SharedGenericModule,\n MJButtonDirective,\n MJTabNavComponent,\n CloneScopeControlsComponent,\n ClonePlanTreeComponent,\n CloneValuesComponent,\n CloneReviewComponent,\n CloneProgressComponent,\n CloneResultComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class RecordClonePanelComponent extends BaseAngularComponent {\n private cloneService = inject(RecordCloneService);\n private cdr = inject(ChangeDetectorRef);\n\n // ── Inputs ───────────────────────────────────────────────────────────\n\n /**\n * The record to clone. Takes precedence for the key when {@link RecordKey} is not set,\n * and supplies the entity name when {@link EntityName} is not set.\n */\n @Input()\n set Record(value: BaseEntity | null) {\n this._record = value;\n this.queueAutoStart();\n }\n get Record(): BaseEntity | null {\n return this._record;\n }\n private _record: BaseEntity | null = null;\n\n /** Entity of the source record, e.g. `'MJ: Users'`. Needed when {@link Record} is not set. */\n @Input()\n set EntityName(value: string | undefined) {\n this._entityName = value;\n this.queueAutoStart();\n }\n get EntityName(): string | undefined {\n return this._entityName;\n }\n private _entityName?: string;\n\n /**\n * Key of the source record: a {@link RecordCloneKey}, or a record-id string in the\n * compact URL-segment form (`'<value>'` for a single-column key, `'F1|V1||F2|V2'` for a\n * composite one), parsed with `CompositeKey.FromURLSegment` against the entity's metadata.\n */\n @Input()\n set RecordKey(value: RecordCloneKey | string | undefined) {\n this._recordKey = value;\n this.queueAutoStart();\n }\n get RecordKey(): RecordCloneKey | string | undefined {\n return this._recordKey;\n }\n private _recordKey?: RecordCloneKey | string;\n\n /** Start describing and planning as soon as a source is set. Default true. */\n @Input() AutoStart = true;\n\n /** Show the Scope / Values / Review step tabs. Default true. */\n @Input() ShowStepTabs = true;\n\n // ── Outputs ──────────────────────────────────────────────────────────\n\n /** Fires whenever {@link CurrentState} changes. */\n @Output() StateChange = new EventEmitter<RecordClonePanelState>();\n\n /** Fires whenever the active wizard step changes. */\n @Output() StepChange = new EventEmitter<RecordCloneStep>();\n\n /** Fires after every successful plan computation with the fresh plan. */\n @Output() PlanChanged = new EventEmitter<RecordClonePlanDetails>();\n\n /** Fires once the clone commits. The panel also raises one `remote-invalidate` event per written entity so open views refresh. */\n @Output() CloneCompleted = new EventEmitter<CloneCompletedEvent>();\n\n /** Fires when describe, plan or execute fails, with the message the panel shows. */\n @Output() CloneFailed = new EventEmitter<CloneFailedEvent>();\n\n /** Asks the host to open a record (the new clone, or a record linked from the result). The panel never routes itself. */\n @Output() NavigateToRecord = new EventEmitter<CloneNavigationEvent>();\n\n /** Asks the host to dismiss the panel (Close, Cancel, or after a navigation request). */\n @Output() CloseRequested = new EventEmitter<void>();\n\n // ── Public state (read by the template and by hosts) ─────────────────\n\n /** Current wizard state. Setting it emits {@link StateChange}. */\n public get CurrentState(): RecordClonePanelState {\n return this._currentState;\n }\n public set CurrentState(value: RecordClonePanelState) {\n if (value === this._currentState) return;\n this._currentState = value;\n this.StateChange.emit(value);\n }\n private _currentState: RecordClonePanelState = 'loading';\n\n /** Active authoring step. Setting it emits {@link StepChange}. */\n public get CurrentStep(): RecordCloneStep {\n return this._currentStep;\n }\n public set CurrentStep(value: RecordCloneStep) {\n if (value === this._currentStep) return;\n this._currentStep = value;\n this.StepChange.emit(value);\n }\n private _currentStep: RecordCloneStep = 'scope';\n\n /** True while the panel is describing, planning for the first time, or executing. Hosts use it to block closing. */\n public get IsBusy(): boolean {\n return this.CurrentState === 'loading' || this.CurrentState === 'executing';\n }\n\n public LoadingMessage = 'Analyzing record and dependencies...';\n public NotCloneableReason = 'This entity or record type does not permit cloning.';\n public ExecutionErrorMessage = '';\n\n /** Describe answer for the source entity, once loaded. */\n public DescribeDetails: RecordCloneDescribeOutput | null = null;\n /** Latest plan computed by the server. */\n public ActivePlan: RecordClonePlanDetails | null = null;\n /** Result of the last execute call. */\n public ExecutionResult: RecordCloneExecuteOutput | null = null;\n public ExecutionProgress: CloneProgressUpdate | null = null;\n\n /**\n * Plan options sent with every plan and execute request. Holds only what the user changed (plus\n * the preset and entered values); everything else comes from the entity's clone configuration.\n */\n public ScopeOptions: RecordClonePlanOptions = {};\n public AvailablePresets: string[] = [];\n /** How each preset is shown in the picker, from the entity's clone configuration. */\n public PresetLabels: Record<string, { Label: string; Description?: string }> = {};\n public SelectedPreset?: string;\n\n /**\n * Whether the developer scope overrides are offered: `RecordClone.Describe` reports whether the\n * user holds `Clone Records: Override Scope`. The server applies the same rule to every request.\n */\n public CanOverrideScope = false;\n\n /** Branch policies the user changed in the plan tree, sent with every plan and execute. */\n public EdgeOverrides: CloneEdgePolicyChange[] = [];\n\n /** Whether the user may skip branches: the entity's UserEditable allows scope changes, or they hold Override Scope. */\n public get CanNarrowScope(): boolean {\n const editable = this.DescribeDetails?.UserEditable ?? 'all';\n return editable === 'scope' || editable === 'all' || this.CanOverrideScope;\n }\n\n /** The entity's configured scope (its `Configuration.Clone`, else the engine defaults), for the summary. */\n public get ConfiguredScope(): CloneScopeValues {\n const entityCfg = this.ProviderToUse?.EntityByName(this.EffectiveEntityName)?.CloneConfig;\n const presetOptions = RecordClonePanelComponent.presetOptions(entityCfg?.Presets, this.SelectedPreset);\n const cfg = { ...(entityCfg ?? {}), ...presetOptions } as typeof entityCfg;\n const builtIn = RecordClonePanelComponent.builtInScope();\n return {\n MaxDepth: cfg?.MaxDepth ?? builtIn.MaxDepth,\n MaxRecords: cfg?.MaxRecords ?? builtIn.MaxRecords,\n Subtypes: cfg?.Subtypes ?? builtIn.Subtypes,\n Hierarchy: cfg?.Hierarchy ?? builtIn.Hierarchy,\n SoftLinks: cfg?.SoftLinks ?? builtIn.SoftLinks,\n EntityActions: cfg?.Hooks?.EntityActions ?? builtIn.EntityActions,\n };\n }\n\n public RootRecordName = '';\n public NamingStrategyReason?: string;\n public PromptedFields: ClonePromptFieldItem[] = [];\n public PromptedValues: Record<string, string | number | boolean | null> = {};\n public RetargetFields: CloneRetargetFieldItem[] = [];\n public CloneReason = '';\n public IsValuesValid = true;\n public HasUserEditedRootName = false;\n\n public WizardTabs: TabConfig[] = [\n { key: 'scope', label: '1. Scope & Graph', icon: 'fa-solid fa-diagram-project' },\n { key: 'values', label: '2. Values & Retarget', icon: 'fa-solid fa-pen-to-square' },\n { key: 'review', label: '3. Review & Execute', icon: 'fa-solid fa-clipboard-check' },\n ];\n\n /** The promise of the most recent {@link Start}; tests and hosts can await it. */\n public InitializationPromise?: Promise<void>;\n\n /** Entity name the panel is cloning, from {@link EntityName} or {@link Record}. */\n public get EffectiveEntityName(): string {\n return this.EntityName || this.Record?.EntityInfo?.Name || 'Record';\n }\n\n /** Source key resolved against the entity's primary key columns. */\n public get EffectiveRecordKey(): RecordCloneKey | undefined {\n if (this.RecordKey) {\n if (typeof this.RecordKey !== 'string') return this.RecordKey;\n const entityInfo = this.ProviderToUse?.EntityByName(this.EffectiveEntityName);\n return CompositeKeyToRecordCloneKey(CompositeKey.FromURLSegment(entityInfo, this.RecordKey));\n }\n if (this.Record) {\n return EntityToRecordCloneKey(this.Record);\n }\n return undefined;\n }\n\n /** Default title for hosts that show one, e.g. `Clone MJ: Users`. */\n public get PanelTitle(): string {\n return `Clone ${this.EffectiveEntityName}`;\n }\n\n public get ShowWizardTabs(): boolean {\n return (\n this.ShowStepTabs &&\n (this.CurrentState === 'scope' ||\n this.CurrentState === 'values' ||\n this.CurrentState === 'review' ||\n this.CurrentState === 'plan_changed')\n );\n }\n\n // ── Public methods ───────────────────────────────────────────────────\n\n /**\n * Describes the source, computes the first plan and lands on the Scope step.\n * Safe to call again; each call starts the wizard over.\n */\n public Start(): Promise<void> {\n this.InitializationPromise = this.initialize();\n return this.InitializationPromise;\n }\n\n /** Clears the values entered so far and starts over (used by \"Clone another\"). */\n public Reset(): Promise<void> {\n // Values folded into the options on the way to Review belong to the previous run.\n this.ScopeOptions = {};\n this.EdgeOverrides = [];\n this.SelectedPreset = undefined;\n this.ActivePlan = null;\n this.ExecutionResult = null;\n this.ExecutionProgress = null;\n this.PlanChangedNotice = null;\n this.PromptedValues = {};\n this.PromptedFields = [];\n this.RetargetFields = [];\n this.CloneReason = '';\n this.RootRecordName = '';\n this.HasUserEditedRootName = false;\n return this.Start();\n }\n\n /** True while a re-plan is in flight; Review disables Confirm so the user only confirms a plan they have seen. */\n public IsReplanning = false;\n private replanRequestId = 0;\n\n /**\n * Re-runs the plan with the current {@link ScopeOptions}, e.g. after a host changes them. When\n * several re-plans overlap, only the latest request's answer is kept.\n */\n public async Replan(): Promise<void> {\n const requestId = ++this.replanRequestId;\n this.IsReplanning = true;\n this.cdr.markForCheck();\n try {\n const planOutput = await this.cloneService.PlanClone(\n {\n EntityName: this.EffectiveEntityName,\n SourceRecordKey: this.EffectiveRecordKey,\n Options: this.ScopeOptions,\n EdgeOverrides: this.wireEdgeOverrides(),\n ExpectedPlanHash: this.ActivePlan?.Hash,\n },\n this.ProviderToUse\n );\n if (requestId !== this.replanRequestId) return; // a newer re-plan superseded this one\n\n this.ActivePlan = planOutput.Plan;\n if (planOutput.Plan) {\n // The name the server will apply can move with the plan (a rule derives it from a\n // prompted value, a rename avoids a newly taken one); follow it unless the user typed one.\n if (this.RootNameReadOnly || !this.HasUserEditedRootName) {\n const change = this.rootNameChange();\n if (change) {\n this.RootRecordName = String(change.NewValue);\n // The note under the name says how it was made, which can change too (a rule instead of a suffix).\n this.NamingStrategyReason = change.Reason || this.NamingStrategyReason;\n }\n }\n this.PlanChanged.emit(planOutput.Plan);\n }\n } catch (err) {\n // A superseded request's failure says nothing about the plan on screen.\n if (requestId === this.replanRequestId) throw err;\n } finally {\n if (requestId === this.replanRequestId) this.IsReplanning = false;\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Moves to a wizard step. Review is refused while prompted values are invalid; entering\n * Review folds the entered values into the options and re-plans so the diff is current.\n */\n public GoToStep(step: RecordCloneStep): void {\n if (step === 'review' && !this.IsValuesValid) {\n return;\n }\n\n this.CurrentStep = step;\n this.CurrentState = step;\n this.PlanChangedNotice = null;\n this.cdr.markForCheck();\n\n if (step === 'review') {\n // Re-plan whenever the values differ from the ones the shown plan was built with,\n // including a value the user cleared or a retarget set back to the original.\n const next = this.buildOptionsWithValues();\n if (this.planValuesKey(next) !== this.planValuesKey(this.ScopeOptions)) {\n this.ScopeOptions = next;\n void this.replanOrFail();\n }\n }\n }\n\n /** Executes the reviewed plan. The server refuses with `PLAN_CHANGED` if the plan hash moved. */\n public async ExecuteClone(): Promise<void> {\n // Also refuse re-entry: the button is disabled only by binding, so a second call before\n // change detection (a host, a key repeat) would start a second clone.\n if (!this.ActivePlan || this.ActivePlan.Blocked || this.IsReplanning || this.CurrentState === 'executing') return;\n\n this.PlanChangedNotice = null;\n this.CurrentState = 'executing';\n // One transaction on the server, with no per-row progress channel: an indeterminate state with the row count.\n const rows = this.ActivePlan.Counts.Create;\n this.ExecutionProgress = {\n Message: `Creating ${rows} record${rows === 1 ? '' : 's'} in one transaction...`,\n Total: rows,\n };\n this.cdr.markForCheck();\n\n try {\n const result = await this.cloneService.ExecuteClone(\n {\n EntityName: this.EffectiveEntityName,\n SourceRecordKey: this.EffectiveRecordKey,\n ExpectedPlanHash: this.ActivePlan.Hash,\n Options: this.buildOptionsWithValues(),\n EdgeOverrides: this.wireEdgeOverrides(),\n },\n this.ProviderToUse\n );\n\n this.ExecutionResult = result;\n\n if (result.Success) {\n this.CurrentState = 'done';\n const completed: CloneCompletedEvent = {\n EntityName: this.EffectiveEntityName,\n TargetKey: this.TargetRecordKey || '',\n CloneLogID: result.CloneLogID,\n CreatedRecordsCount: result.Created?.length || result.Counts?.Create || 1,\n Result: result,\n };\n this.raiseRecordCreatedEvent(completed);\n this.CloneCompleted.emit(completed);\n } else if (result.ResultCode === 'PLAN_CHANGED') {\n // The records changed since review: show the fresh plan and ask for a new confirmation.\n this.PlanChangedNotice = 'The records changed since you reviewed this plan. Review the updated plan and confirm again.';\n this.CurrentStep = 'review';\n this.CurrentState = 'plan_changed';\n if (result.Plan) {\n this.ActivePlan = result.Plan;\n this.PlanChanged.emit(result.Plan);\n } else {\n await this.replanOrFail();\n }\n } else {\n this.fail(result.ErrorMessage || 'Clone execution failed.', result.ResultCode);\n }\n } catch (err) {\n this.fail(err instanceof Error ? err.message : String(err));\n } finally {\n this.cdr.markForCheck();\n }\n }\n\n /** Shown on Review after an Execute found the plan out of date. Cleared by the next Execute or step change. */\n public PlanChangedNotice: string | null = null;\n\n /** From the Failed state: back to Review with a fresh plan, since the old one may be why it failed. */\n public BackToReview(): void {\n this.PlanChangedNotice = null;\n this.CurrentStep = 'review';\n this.CurrentState = 'review';\n this.ScopeOptions = this.buildOptionsWithValues();\n this.cdr.markForCheck();\n void this.replanOrFail();\n }\n\n /** Key of the root clone once execution succeeded, as a record-id string. */\n public get TargetRecordKey(): string | null {\n return this.ExecutionResult?.Roots?.[0]?.TargetKey || null;\n }\n\n // ── Template handlers ────────────────────────────────────────────────\n\n /** Scope values the controls show: the server's effective options once a plan exists. */\n public get DisplayedScope(): Required<Pick<RecordClonePlanOptions, ScopeOptionKey>> {\n return { ...RecordClonePanelComponent.builtInScope(), ...(this.ActivePlan?.EffectiveOptions ?? {}) };\n }\n\n /**\n * Keeps only the scope values the user changed from what is displayed, so the entity's\n * configured defaults (and a preset's options) are not overwritten by values nobody chose.\n * Picking a preset clears earlier scope changes so the preset's options apply.\n */\n public OnScopeOptionsChanged(options: RecordClonePlanOptions): void {\n const next: RecordClonePlanOptions = this.scopeWithCurrentValues();\n if (options.Preset !== this.SelectedPreset) {\n for (const k of SCOPE_OPTION_KEYS) delete next[k];\n next.Preset = options.Preset;\n } else {\n const shown = this.DisplayedScope;\n for (const k of SCOPE_OPTION_KEYS) {\n if (options[k] !== undefined && options[k] !== shown[k]) {\n (next as Record<ScopeOptionKey, unknown>)[k] = options[k];\n }\n }\n }\n this.ScopeOptions = next;\n this.SelectedPreset = options.Preset;\n void this.replanOrFail();\n }\n\n /**\n * A branch was switched in the plan tree. Switching a branch the user already changed drops that\n * override (back to the configured policy); otherwise the change is remembered. Then re-plan.\n */\n public OnEdgePolicyChanged(change: CloneEdgePolicyChange): void {\n const others = this.EdgeOverrides.filter((o) => o.RelationshipID !== change.RelationshipID);\n const hadOverride = others.length !== this.EdgeOverrides.length;\n this.EdgeOverrides = hadOverride ? others : [...others, change];\n void this.replanOrFail();\n }\n\n /** Drops one branch override so that relationship follows its configured policy again. */\n public OnUndoEdgeOverride(relationshipID: string): void {\n this.EdgeOverrides = this.EdgeOverrides.filter((o) => o.RelationshipID !== relationshipID);\n void this.replanOrFail();\n }\n\n /** Drops every scope and branch override so the entity's configured scope applies again. */\n public OnResetScopeToDefaults(): void {\n const next: RecordClonePlanOptions = this.scopeWithCurrentValues();\n for (const k of SCOPE_OPTION_KEYS) delete next[k];\n this.ScopeOptions = next;\n this.EdgeOverrides = [];\n void this.replanOrFail();\n }\n\n public OnStepChange(stepKey: string): void {\n this.GoToStep(stepKey as RecordCloneStep);\n }\n\n public OnRootNameChange(name: string): void {\n this.RootRecordName = name;\n this.HasUserEditedRootName = true;\n }\n\n /**\n * Keeps the root name in step with a prompted value while the user has not typed a name.\n * Which prompted field drives it comes from the entity's `Clone.Naming.Fields` (for MJ: Users\n * that is Email), falling back to the entity's name field.\n */\n public OnPromptedValuesChange(values: Record<string, string | number | boolean | null>): void {\n this.PromptedValues = values;\n if (this.HasUserEditedRootName) return;\n\n const drivingField = this.namingDrivenFields().find((f) => {\n const v = values[f];\n return typeof v === 'string' && v.trim().length > 0;\n });\n if (drivingField) {\n this.RootRecordName = values[drivingField] as string;\n }\n }\n\n public OnRetargetFieldsChange(fields: CloneRetargetFieldItem[]): void {\n this.RetargetFields = fields;\n }\n\n public OnReasonChange(reason: string): void {\n this.CloneReason = reason;\n }\n\n public OnValuesValidityChange(isValid: boolean): void {\n this.IsValuesValid = isValid;\n this.cdr.markForCheck();\n }\n\n public OnNodeSelected(_node: RecordClonePlanNode): void {\n // Reserved for a node detail pane.\n }\n\n public OnReviewNodeClicked(_nodeKey: string): void {\n this.GoToStep('scope');\n }\n\n public OnNavigateToRecord(event: CloneNavigationEvent): void {\n this.NavigateToRecord.emit(event);\n this.CloseRequested.emit();\n }\n\n public OnClose(): void {\n this.CloseRequested.emit();\n }\n\n // ── Internals ────────────────────────────────────────────────────────\n\n /** Label and description of each preset, by key, read the way the engine reads `Clone.Presets`. */\n private static presetLabels(presets: unknown): Record<string, { Label: string; Description?: string }> {\n return Object.fromEntries(NormalizeClonePresets(presets).map((p) => [p.Key, { Label: p.Label, Description: p.Description }]));\n }\n\n /** Options of the named preset, read the way the engine reads `Clone.Presets`. */\n private static presetOptions(presets: unknown, key: string | undefined): Partial<CloneRequestOptions> {\n if (!key) return {};\n return NormalizeClonePresets(presets).find((p) => p.Key === key)?.Options ?? {};\n }\n\n /** Branch overrides in the shape the operation accepts (labels stripped), or undefined when there are none. */\n private wireEdgeOverrides(): Array<{ RelationshipID: string; Policy: 'Deep' | 'Reference' | 'Skip' }> | undefined {\n return this.EdgeOverrides.length > 0 ? this.EdgeOverrides.map(({ RelationshipID, Policy }) => ({ RelationshipID, Policy })) : undefined;\n }\n\n /** What the controls show before the first plan arrives; the server's effective options replace it. */\n private static builtInScope(): Required<Pick<RecordClonePlanOptions, ScopeOptionKey>> {\n return {\n MaxDepth: 3,\n MaxRecords: 500,\n Subtypes: 'include',\n Hierarchy: 'subtree',\n SoftLinks: 'skip',\n EntityActions: 'fire',\n };\n }\n\n /** Re-plan from a UI event; a failure moves the wizard to Failed instead of leaving a stale plan up. */\n private async replanOrFail(): Promise<void> {\n try {\n await this.Replan();\n } catch (err) {\n this.fail(err instanceof Error ? err.message : String(err));\n this.cdr.markForCheck();\n }\n }\n\n private autoStartQueued = false;\n\n /** Coalesces the Record / EntityName / RecordKey setters into one start per change batch. */\n private queueAutoStart(): void {\n if (!this.AutoStart || this.autoStartQueued) return;\n this.autoStartQueued = true;\n queueMicrotask(() => {\n this.autoStartQueued = false;\n if (this.AutoStart && this.EffectiveRecordKey) {\n void this.Start();\n }\n });\n }\n\n private async initialize(): Promise<void> {\n this.HasUserEditedRootName = false;\n this.CurrentState = 'loading';\n this.CurrentStep = 'scope';\n this.LoadingMessage = 'Inspecting entity cloning policy...';\n this.cdr.markForCheck();\n\n try {\n const describe = await this.cloneService.DescribeRecord(\n {\n EntityName: this.EffectiveEntityName,\n Key: this.EffectiveRecordKey,\n },\n this.ProviderToUse\n );\n this.DescribeDetails = describe;\n\n if (!describe.CanClone) {\n this.CurrentState = 'not_cloneable';\n this.NotCloneableReason = describe.Reason || 'Cloning is disabled for this entity.';\n this.cdr.markForCheck();\n return;\n }\n\n this.AvailablePresets = describe.Presets || [];\n this.PresetLabels = RecordClonePanelComponent.presetLabels(this.ProviderToUse?.EntityByName(this.EffectiveEntityName)?.CloneConfig?.Presets);\n this.CanOverrideScope = describe.CanOverrideScope === true;\n\n this.LoadingMessage = 'Computing dependency graph and plan...';\n this.cdr.markForCheck();\n\n await this.Replan();\n this.setupInitialValues();\n\n this.CurrentState = 'scope';\n this.cdr.markForCheck();\n } catch (err) {\n this.fail(err instanceof Error ? err.message : String(err));\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Whether the configuration, not the user, decides the root's name: a rule derives it (a user's\n * Name from the prompted Email), a reset stamps it, or UserEditable doesn't allow field edits.\n * The server ignores a typed name then, so the box is read-only.\n */\n public get RootNameReadOnly(): boolean {\n const entInfo = this.ProviderToUse?.EntityByName(this.EffectiveEntityName);\n const cfg = entInfo?.CloneConfig;\n const nameField = (entInfo?.NameField?.Name ?? 'Name').toLowerCase();\n const ruleTargets: Array<{ TargetField?: string; Field?: string }> = (cfg?.Fields?.Rules as FieldRuleSet | undefined)?.Rules ?? [];\n const governed = ruleTargets.some((r) => (r.TargetField || r.Field || '').toLowerCase() === nameField)\n || Object.keys(cfg?.Fields?.Reset ?? {}).some((k) => k.toLowerCase() === nameField);\n const editable = cfg?.UserEditable ?? 'all';\n return governed || editable === 'none' || editable === 'scope';\n }\n\n /** The last change on the root's name field in the current plan: the value the server applies. */\n private rootNameChange(): RecordClonePlanDetails['Nodes'][number]['FieldChanges'][number] | undefined {\n const rootNode = this.ActivePlan?.Nodes.find((n) => n.Depth === 0 || n.ParentKey === null);\n if (!rootNode) return undefined;\n const nameField = (this.ProviderToUse?.EntityByName(this.EffectiveEntityName)?.NameField?.Name ?? 'Name').toLowerCase();\n return [...rootNode.FieldChanges].reverse().find((fc) => fc.Field.toLowerCase() === nameField);\n }\n\n private setupInitialValues(): void {\n if (!this.ActivePlan) return;\n\n const rootNode = this.ActivePlan.Nodes.find((n) => n.Depth === 0 || n.ParentKey === null);\n if (rootNode) {\n // The value the server will apply is the last change on the name field (its rename, when\n // the naming strategy made one), not the first, which is the plain copy of the source.\n const nameChange = this.rootNameChange();\n if (nameChange) {\n this.RootRecordName = String(nameChange.NewValue);\n this.NamingStrategyReason = nameChange.Reason || 'Suggested by naming strategy';\n } else {\n this.RootRecordName = rootNode.DisplayName ? `${rootNode.DisplayName} (Copy)` : 'Cloned Record';\n }\n }\n\n const entInfo = this.ProviderToUse?.EntityByName(this.EffectiveEntityName);\n const cloneCfg = entInfo?.CloneConfig;\n\n const promptFor = cloneCfg?.Fields?.PromptFor;\n if (Array.isArray(promptFor) && promptFor.length > 0) {\n this.PromptedFields = promptFor.map((fName: string): ClonePromptFieldItem => {\n const fieldInfo = entInfo?.Fields.find((f) => f.Name === fName);\n const fc = rootNode?.FieldChanges.find((c) => c.Field === fName);\n // Pre-fill only a value the engine proposed. The source row's own value is exactly\n // what a prompted field (a unique Email, say) must not keep, so it is never offered.\n const proposed = fc && fc.NewValue !== fc.OldValue ? fc.NewValue : null;\n return {\n FieldName: fName,\n DisplayName: fieldInfo?.DisplayName || fName,\n Type: fieldInfo?.Type || 'string',\n // The plan blocks without every PromptFor value (the copy can't reuse the source's).\n IsRequired: true,\n Description: fieldInfo?.Description,\n DefaultValue: (proposed ?? null) as string | number | boolean | null,\n };\n });\n\n for (const pf of this.PromptedFields) {\n if (this.PromptedValues[pf.FieldName] === undefined && pf.DefaultValue !== null && pf.DefaultValue !== undefined) {\n this.PromptedValues[pf.FieldName] = pf.DefaultValue;\n }\n }\n }\n\n const retargetFieldNames = cloneCfg?.UI?.RetargetFields;\n if (Array.isArray(retargetFieldNames) && retargetFieldNames.length > 0) {\n this.RetargetFields = retargetFieldNames\n .map((fName: string): CloneRetargetFieldItem | null => {\n const fieldInfo = entInfo?.Fields.find((f) => f.Name === fName);\n if (!fieldInfo) return null;\n const fc = rootNode?.FieldChanges.find((c) => c.Field === fName);\n const currentVal = (fc?.OldValue ?? null) as string | null;\n return {\n FieldName: fName,\n DisplayName: fieldInfo.DisplayName || fName,\n RelatedEntity: fieldInfo.RelatedEntity || '',\n CurrentValue: currentVal,\n NewValue: currentVal,\n };\n })\n .filter((item): item is CloneRetargetFieldItem => item !== null);\n }\n }\n\n /** Prompted fields whose value names the clone: `Clone.Naming.Fields` that are prompted, else the name field. */\n private namingDrivenFields(): string[] {\n const entInfo = this.ProviderToUse?.EntityByName(this.EffectiveEntityName);\n const prompted = new Set(this.PromptedFields.map((f) => f.FieldName.toLowerCase()));\n const configured = (entInfo?.CloneConfig?.Naming?.Fields ?? []).filter((f) => prompted.has(f.toLowerCase()));\n if (configured.length > 0) return configured;\n const nameField = entInfo?.NameField?.Name;\n return nameField && prompted.has(nameField.toLowerCase()) ? [nameField] : [];\n }\n\n /** Current options plus the root name, prompted values and reason the user entered. */\n /** Retarget pickers the user pointed at a different record, in the `Options.Retarget` shape. */\n private retargets(): NonNullable<RecordClonePlanOptions['Retarget']> {\n return this.RetargetFields\n .filter((r) => r.NewValue && r.NewValue !== r.CurrentValue)\n .map((r) => ({ EntityName: this.EffectiveEntityName, Field: r.FieldName, Value: r.NewValue as string }));\n }\n\n /**\n * The scope options plus the Values step's current values, leaving out the ones that are empty:\n * a Scope-step re-plan then carries no stale name or retarget, and nothing the user hasn't set.\n */\n private scopeWithCurrentValues(): RecordClonePlanOptions {\n const next = this.buildOptionsWithValues();\n if (Object.keys(next.FieldOverrides ?? {}).length === 0) delete next.FieldOverrides;\n if (Object.keys(next.PromptedValues ?? {}).length === 0) delete next.PromptedValues;\n if (!next.Reason) delete next.Reason;\n return next;\n }\n\n private buildOptionsWithValues(): RecordClonePlanOptions {\n const entInfo = this.ProviderToUse?.EntityByName(this.EffectiveEntityName);\n const nameField = entInfo?.NameField?.Name || 'Name';\n const retarget = this.retargets();\n // Values come from the current Values step every time, never from an earlier request's\n // options: a retarget set back, or a typed name that was cleared, must not linger.\n const { FieldOverrides: _fields, PromptedValues: _prompts, Retarget: _retarget, Reason: _reason, ...scope } = this.ScopeOptions;\n return {\n ...scope,\n // Only a name the user typed overrides the server's naming, which avoids names already taken.\n FieldOverrides: this.HasUserEditedRootName && this.RootRecordName.trim() ? { [nameField]: this.RootRecordName } : {},\n ...(retarget.length > 0 ? { Retarget: retarget } : {}),\n PromptedValues: { ...this.PromptedValues },\n Reason: this.CloneReason,\n };\n }\n\n /** The parts of the options that the Values step sets and that change the plan. */\n private planValuesKey(options: RecordClonePlanOptions): string {\n return JSON.stringify([options.FieldOverrides ?? {}, options.PromptedValues ?? {}, options.Retarget ?? []]);\n }\n\n private fail(message: string, resultCode?: string): void {\n this.CurrentState = 'failed';\n this.ExecutionErrorMessage = message;\n this.CloneFailed.emit({ EntityName: this.EffectiveEntityName, Message: message, ResultCode: resultCode });\n }\n\n /**\n * The clone's rows were saved on the server, so no client-side BaseEntity raised a save.\n * Announce each written entity the way the provider announces a server-side write\n * (`remote-invalidate`, no `baseEntity`), so cached engines and open views reload it.\n */\n private raiseRecordCreatedEvent(completed: CloneCompletedEvent): void {\n const written = new Set<string>([completed.EntityName, ...(completed.Result?.Created ?? []).map((c) => c.EntityName)]);\n const timestamp = new Date().toISOString();\n for (const entityName of written) {\n const args: BaseEntityEvent = {\n type: 'remote-invalidate',\n entityName,\n baseEntity: null,\n provider: this.ProviderToUse,\n payload: { primaryKeyValues: null, action: 'save', sourceServerId: '', timestamp },\n };\n MJGlobal.Instance.RaiseEvent({ component: this, event: MJEventType.ComponentEvent, eventCode: BaseEntity.BaseEventCode, args });\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Slide-in wrapper for the record clone panel.
|
|
3
|
+
*
|
|
4
|
+
* Puts {@link RecordClonePanelComponent} inside MJ's generic `<mj-slide-panel>` so any host
|
|
5
|
+
* (the base-forms record toolbar, a grid, a dashboard) gets the standard right-hand slide-in
|
|
6
|
+
* with one element. Everything the panel reports is re-emitted unchanged; the wrapper only
|
|
7
|
+
* adds open/close handling.
|
|
8
|
+
*/
|
|
9
|
+
import { EventEmitter } from '@angular/core';
|
|
10
|
+
import type { BaseEntity } from '@memberjunction/core';
|
|
11
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
12
|
+
import type { RecordCloneKey, RecordClonePlanDetails } from '@memberjunction/core-entities';
|
|
13
|
+
import { RecordClonePanelComponent } from './record-clone-panel.component';
|
|
14
|
+
import type { CloneCompletedEvent, CloneFailedEvent, CloneNavigationEvent, RecordClonePanelState, RecordCloneStep } from './record-clone-types';
|
|
15
|
+
import * as i0 from "@angular/core";
|
|
16
|
+
/**
|
|
17
|
+
* The clone wizard in a right-hand slide-in.
|
|
18
|
+
*
|
|
19
|
+
* Bind {@link Visible} two-way. The inner panel is created on first open and restarted on
|
|
20
|
+
* every later open, so each open plans against the record's current state. Closing is refused
|
|
21
|
+
* while a clone is executing.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```html
|
|
25
|
+
* <mj-record-clone-slide-in
|
|
26
|
+
* [(Visible)]="ShowClone"
|
|
27
|
+
* [Record]="record"
|
|
28
|
+
* [Provider]="provider"
|
|
29
|
+
* (CloneCompleted)="OnCloned($event)"
|
|
30
|
+
* (NavigateToRecord)="OpenRecord($event)">
|
|
31
|
+
* </mj-record-clone-slide-in>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class RecordCloneSlideInComponent extends BaseAngularComponent {
|
|
35
|
+
private cdr;
|
|
36
|
+
/** The embedded panel, once the slide-in has been opened. */
|
|
37
|
+
Panel?: RecordClonePanelComponent;
|
|
38
|
+
/** Whether the slide-in is open. Opening (re)starts the wizard. Bind two-way with `[(Visible)]`. */
|
|
39
|
+
set Visible(value: boolean);
|
|
40
|
+
get Visible(): boolean;
|
|
41
|
+
private _visible;
|
|
42
|
+
/** The record to clone. See {@link RecordClonePanelComponent.Record}. */
|
|
43
|
+
Record: BaseEntity | null;
|
|
44
|
+
/** Entity of the source record when {@link Record} is not set. */
|
|
45
|
+
EntityName?: string;
|
|
46
|
+
/** Key of the source record when {@link Record} is not set. See {@link RecordClonePanelComponent.RecordKey}. */
|
|
47
|
+
RecordKey?: RecordCloneKey | string;
|
|
48
|
+
/** Header text. Defaults to `Clone <entity name>`. */
|
|
49
|
+
Title: string;
|
|
50
|
+
/** Initial width in pixels. Default 720, wide enough for the plan tree and the review diff. */
|
|
51
|
+
WidthPx: number;
|
|
52
|
+
/** Show the Scope / Values / Review step tabs. Default true. */
|
|
53
|
+
ShowStepTabs: boolean;
|
|
54
|
+
/** Fires with the new value when the slide-in opens or closes itself. */
|
|
55
|
+
VisibleChange: EventEmitter<boolean>;
|
|
56
|
+
/** Fires after the slide-in closes, whatever closed it. */
|
|
57
|
+
Closed: EventEmitter<void>;
|
|
58
|
+
/** See {@link RecordClonePanelComponent.StateChange}. */
|
|
59
|
+
StateChange: EventEmitter<RecordClonePanelState>;
|
|
60
|
+
/** See {@link RecordClonePanelComponent.StepChange}. */
|
|
61
|
+
StepChange: EventEmitter<RecordCloneStep>;
|
|
62
|
+
/** See {@link RecordClonePanelComponent.PlanChanged}. */
|
|
63
|
+
PlanChanged: EventEmitter<RecordClonePlanDetails>;
|
|
64
|
+
/** See {@link RecordClonePanelComponent.CloneCompleted}. */
|
|
65
|
+
CloneCompleted: EventEmitter<CloneCompletedEvent>;
|
|
66
|
+
/** See {@link RecordClonePanelComponent.CloneFailed}. */
|
|
67
|
+
CloneFailed: EventEmitter<CloneFailedEvent>;
|
|
68
|
+
/** See {@link RecordClonePanelComponent.NavigateToRecord}. The slide-in closes after emitting it. */
|
|
69
|
+
NavigateToRecord: EventEmitter<CloneNavigationEvent>;
|
|
70
|
+
/** True once the slide-in has opened at least once; the panel is created lazily. */
|
|
71
|
+
HasOpened: boolean;
|
|
72
|
+
get DefaultTitle(): string;
|
|
73
|
+
/** Passed to `mj-slide-panel`: refuses X, Escape and backdrop closes while a clone is running. */
|
|
74
|
+
readonly CanCloseGuard: () => boolean;
|
|
75
|
+
/** Opens the slide-in and restarts the wizard. */
|
|
76
|
+
Open(): void;
|
|
77
|
+
/** Closes the slide-in unless a clone is executing. */
|
|
78
|
+
Close(): void;
|
|
79
|
+
private onOpened;
|
|
80
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RecordCloneSlideInComponent, never>;
|
|
81
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RecordCloneSlideInComponent, "mj-record-clone-slide-in", never, { "Visible": { "alias": "Visible"; "required": false; }; "Record": { "alias": "Record"; "required": false; }; "EntityName": { "alias": "EntityName"; "required": false; }; "RecordKey": { "alias": "RecordKey"; "required": false; }; "Title": { "alias": "Title"; "required": false; }; "WidthPx": { "alias": "WidthPx"; "required": false; }; "ShowStepTabs": { "alias": "ShowStepTabs"; "required": false; }; }, { "VisibleChange": "VisibleChange"; "Closed": "Closed"; "StateChange": "StateChange"; "StepChange": "StepChange"; "PlanChanged": "PlanChanged"; "CloneCompleted": "CloneCompleted"; "CloneFailed": "CloneFailed"; "NavigateToRecord": "NavigateToRecord"; }, never, never, true, never>;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=record-clone-slide-in.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-clone-slide-in.component.d.ts","sourceRoot":"","sources":["../../src/lib/record-clone-slide-in.component.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAKH,YAAY,EAIf,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAG5F,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,KAAK,EACR,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EAClB,MAAM,sBAAsB,CAAC;;AAE9B;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAqCa,2BAA4B,SAAQ,oBAAoB;IACjE,OAAO,CAAC,GAAG,CAA6B;IAExC,6DAA6D;IAChB,KAAK,CAAC,EAAE,yBAAyB,CAAC;IAI/E,oGAAoG;IACpG,IACI,OAAO,CAAC,KAAK,EAAE,OAAO,EAMzB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,OAAO,CAAC,QAAQ,CAAS;IAEzB,yEAAyE;IAChE,MAAM,EAAE,UAAU,GAAG,IAAI,CAAQ;IAE1C,kEAAkE;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B,gHAAgH;IACvG,SAAS,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC;IAE7C,sDAAsD;IAC7C,KAAK,SAAM;IAEpB,+FAA+F;IACtF,OAAO,SAAO;IAEvB,gEAAgE;IACvD,YAAY,UAAQ;IAI7B,yEAAyE;IAC/D,aAAa,wBAA+B;IACtD,2DAA2D;IACjD,MAAM,qBAA4B;IAC5C,yDAAyD;IAC/C,WAAW,sCAA6C;IAClE,wDAAwD;IAC9C,UAAU,gCAAuC;IAC3D,yDAAyD;IAC/C,WAAW,uCAA8C;IACnE,4DAA4D;IAClD,cAAc,oCAA2C;IACnE,yDAAyD;IAC/C,WAAW,iCAAwC;IAC7D,qGAAqG;IAC3F,gBAAgB,qCAA4C;IAItE,oFAAoF;IAC7E,SAAS,UAAS;IAEzB,IAAW,YAAY,IAAI,MAAM,CAGhC;IAED,kGAAkG;IAClG,SAAgB,aAAa,QAAO,OAAO,CAA6C;IAIxF,kDAAkD;IAC3C,IAAI,IAAI,IAAI;IAOnB,uDAAuD;IAChD,KAAK,IAAI,IAAI;IAQpB,OAAO,CAAC,QAAQ;yCA3FP,2BAA2B;2CAA3B,2BAA2B;CAsGvC"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Slide-in wrapper for the record clone panel.
|
|
3
|
+
*
|
|
4
|
+
* Puts {@link RecordClonePanelComponent} inside MJ's generic `<mj-slide-panel>` so any host
|
|
5
|
+
* (the base-forms record toolbar, a grid, a dashboard) gets the standard right-hand slide-in
|
|
6
|
+
* with one element. Everything the panel reports is re-emitted unchanged; the wrapper only
|
|
7
|
+
* adds open/close handling.
|
|
8
|
+
*/
|
|
9
|
+
import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter, ViewChild, ChangeDetectorRef, inject, } from '@angular/core';
|
|
10
|
+
import { CommonModule } from '@angular/common';
|
|
11
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
12
|
+
import { MjSlidePanelComponent } from '@memberjunction/ng-ui-components';
|
|
13
|
+
import { RecordClonePanelComponent } from './record-clone-panel.component';
|
|
14
|
+
import * as i0 from "@angular/core";
|
|
15
|
+
function RecordCloneSlideInComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
16
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
17
|
+
i0.ɵɵelementStart(0, "mj-record-clone-panel", 2);
|
|
18
|
+
i0.ɵɵlistener("StateChange", function RecordCloneSlideInComponent_Conditional_1_Template_mj_record_clone_panel_StateChange_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.StateChange.emit($event)); })("StepChange", function RecordCloneSlideInComponent_Conditional_1_Template_mj_record_clone_panel_StepChange_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.StepChange.emit($event)); })("PlanChanged", function RecordCloneSlideInComponent_Conditional_1_Template_mj_record_clone_panel_PlanChanged_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.PlanChanged.emit($event)); })("CloneCompleted", function RecordCloneSlideInComponent_Conditional_1_Template_mj_record_clone_panel_CloneCompleted_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloneCompleted.emit($event)); })("CloneFailed", function RecordCloneSlideInComponent_Conditional_1_Template_mj_record_clone_panel_CloneFailed_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloneFailed.emit($event)); })("NavigateToRecord", function RecordCloneSlideInComponent_Conditional_1_Template_mj_record_clone_panel_NavigateToRecord_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.NavigateToRecord.emit($event)); })("CloseRequested", function RecordCloneSlideInComponent_Conditional_1_Template_mj_record_clone_panel_CloseRequested_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Close()); });
|
|
19
|
+
i0.ɵɵelementEnd();
|
|
20
|
+
} if (rf & 2) {
|
|
21
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
22
|
+
i0.ɵɵproperty("Provider", ctx_r1.Provider)("Record", ctx_r1.Record)("EntityName", ctx_r1.EntityName)("RecordKey", ctx_r1.RecordKey)("AutoStart", false)("ShowStepTabs", ctx_r1.ShowStepTabs);
|
|
23
|
+
} }
|
|
24
|
+
/**
|
|
25
|
+
* The clone wizard in a right-hand slide-in.
|
|
26
|
+
*
|
|
27
|
+
* Bind {@link Visible} two-way. The inner panel is created on first open and restarted on
|
|
28
|
+
* every later open, so each open plans against the record's current state. Closing is refused
|
|
29
|
+
* while a clone is executing.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```html
|
|
33
|
+
* <mj-record-clone-slide-in
|
|
34
|
+
* [(Visible)]="ShowClone"
|
|
35
|
+
* [Record]="record"
|
|
36
|
+
* [Provider]="provider"
|
|
37
|
+
* (CloneCompleted)="OnCloned($event)"
|
|
38
|
+
* (NavigateToRecord)="OpenRecord($event)">
|
|
39
|
+
* </mj-record-clone-slide-in>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export class RecordCloneSlideInComponent extends BaseAngularComponent {
|
|
43
|
+
cdr = inject(ChangeDetectorRef);
|
|
44
|
+
/** The embedded panel, once the slide-in has been opened. */
|
|
45
|
+
Panel;
|
|
46
|
+
// ── Inputs ───────────────────────────────────────────────────────────
|
|
47
|
+
/** Whether the slide-in is open. Opening (re)starts the wizard. Bind two-way with `[(Visible)]`. */
|
|
48
|
+
set Visible(value) {
|
|
49
|
+
const opening = value && !this._visible;
|
|
50
|
+
this._visible = value;
|
|
51
|
+
if (opening) {
|
|
52
|
+
this.onOpened();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
get Visible() {
|
|
56
|
+
return this._visible;
|
|
57
|
+
}
|
|
58
|
+
_visible = false;
|
|
59
|
+
/** The record to clone. See {@link RecordClonePanelComponent.Record}. */
|
|
60
|
+
Record = null;
|
|
61
|
+
/** Entity of the source record when {@link Record} is not set. */
|
|
62
|
+
EntityName;
|
|
63
|
+
/** Key of the source record when {@link Record} is not set. See {@link RecordClonePanelComponent.RecordKey}. */
|
|
64
|
+
RecordKey;
|
|
65
|
+
/** Header text. Defaults to `Clone <entity name>`. */
|
|
66
|
+
Title = '';
|
|
67
|
+
/** Initial width in pixels. Default 720, wide enough for the plan tree and the review diff. */
|
|
68
|
+
WidthPx = 720;
|
|
69
|
+
/** Show the Scope / Values / Review step tabs. Default true. */
|
|
70
|
+
ShowStepTabs = true;
|
|
71
|
+
// ── Outputs (re-emitted from the panel) ──────────────────────────────
|
|
72
|
+
/** Fires with the new value when the slide-in opens or closes itself. */
|
|
73
|
+
VisibleChange = new EventEmitter();
|
|
74
|
+
/** Fires after the slide-in closes, whatever closed it. */
|
|
75
|
+
Closed = new EventEmitter();
|
|
76
|
+
/** See {@link RecordClonePanelComponent.StateChange}. */
|
|
77
|
+
StateChange = new EventEmitter();
|
|
78
|
+
/** See {@link RecordClonePanelComponent.StepChange}. */
|
|
79
|
+
StepChange = new EventEmitter();
|
|
80
|
+
/** See {@link RecordClonePanelComponent.PlanChanged}. */
|
|
81
|
+
PlanChanged = new EventEmitter();
|
|
82
|
+
/** See {@link RecordClonePanelComponent.CloneCompleted}. */
|
|
83
|
+
CloneCompleted = new EventEmitter();
|
|
84
|
+
/** See {@link RecordClonePanelComponent.CloneFailed}. */
|
|
85
|
+
CloneFailed = new EventEmitter();
|
|
86
|
+
/** See {@link RecordClonePanelComponent.NavigateToRecord}. The slide-in closes after emitting it. */
|
|
87
|
+
NavigateToRecord = new EventEmitter();
|
|
88
|
+
// ── State ────────────────────────────────────────────────────────────
|
|
89
|
+
/** True once the slide-in has opened at least once; the panel is created lazily. */
|
|
90
|
+
HasOpened = false;
|
|
91
|
+
get DefaultTitle() {
|
|
92
|
+
const name = this.EntityName || this.Record?.EntityInfo?.Name;
|
|
93
|
+
return name ? `Clone ${name}` : 'Clone record';
|
|
94
|
+
}
|
|
95
|
+
/** Passed to `mj-slide-panel`: refuses X, Escape and backdrop closes while a clone is running. */
|
|
96
|
+
CanCloseGuard = () => this.Panel?.CurrentState !== 'executing';
|
|
97
|
+
// ── Methods ──────────────────────────────────────────────────────────
|
|
98
|
+
/** Opens the slide-in and restarts the wizard. */
|
|
99
|
+
Open() {
|
|
100
|
+
if (this._visible)
|
|
101
|
+
return;
|
|
102
|
+
this.Visible = true;
|
|
103
|
+
this.VisibleChange.emit(true);
|
|
104
|
+
this.cdr.markForCheck();
|
|
105
|
+
}
|
|
106
|
+
/** Closes the slide-in unless a clone is executing. */
|
|
107
|
+
Close() {
|
|
108
|
+
if (!this._visible || !this.CanCloseGuard())
|
|
109
|
+
return;
|
|
110
|
+
this._visible = false;
|
|
111
|
+
this.VisibleChange.emit(false);
|
|
112
|
+
this.Closed.emit();
|
|
113
|
+
this.cdr.markForCheck();
|
|
114
|
+
}
|
|
115
|
+
onOpened() {
|
|
116
|
+
if (!this.HasOpened) {
|
|
117
|
+
this.HasOpened = true;
|
|
118
|
+
this.cdr.markForCheck();
|
|
119
|
+
}
|
|
120
|
+
// The panel exists after this change-detection pass; start it once it does.
|
|
121
|
+
queueMicrotask(() => {
|
|
122
|
+
this.cdr.detectChanges();
|
|
123
|
+
void this.Panel?.Reset();
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵRecordCloneSlideInComponent_BaseFactory; return function RecordCloneSlideInComponent_Factory(__ngFactoryType__) { return (ɵRecordCloneSlideInComponent_BaseFactory || (ɵRecordCloneSlideInComponent_BaseFactory = i0.ɵɵgetInheritedFactory(RecordCloneSlideInComponent)))(__ngFactoryType__ || RecordCloneSlideInComponent); }; })();
|
|
127
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RecordCloneSlideInComponent, selectors: [["mj-record-clone-slide-in"]], viewQuery: function RecordCloneSlideInComponent_Query(rf, ctx) { if (rf & 1) {
|
|
128
|
+
i0.ɵɵviewQuery(RecordClonePanelComponent, 5);
|
|
129
|
+
} if (rf & 2) {
|
|
130
|
+
let _t;
|
|
131
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.Panel = _t.first);
|
|
132
|
+
} }, inputs: { Visible: "Visible", Record: "Record", EntityName: "EntityName", RecordKey: "RecordKey", Title: "Title", WidthPx: "WidthPx", ShowStepTabs: "ShowStepTabs" }, outputs: { VisibleChange: "VisibleChange", Closed: "Closed", StateChange: "StateChange", StepChange: "StepChange", PlanChanged: "PlanChanged", CloneCompleted: "CloneCompleted", CloneFailed: "CloneFailed", NavigateToRecord: "NavigateToRecord" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 5, consts: [[3, "Closed", "Visible", "Title", "WidthPx", "CanClose"], [3, "Provider", "Record", "EntityName", "RecordKey", "AutoStart", "ShowStepTabs"], [3, "StateChange", "StepChange", "PlanChanged", "CloneCompleted", "CloneFailed", "NavigateToRecord", "CloseRequested", "Provider", "Record", "EntityName", "RecordKey", "AutoStart", "ShowStepTabs"]], template: function RecordCloneSlideInComponent_Template(rf, ctx) { if (rf & 1) {
|
|
133
|
+
i0.ɵɵelementStart(0, "mj-slide-panel", 0);
|
|
134
|
+
i0.ɵɵlistener("Closed", function RecordCloneSlideInComponent_Template_mj_slide_panel_Closed_0_listener() { return ctx.Close(); });
|
|
135
|
+
i0.ɵɵconditionalCreate(1, RecordCloneSlideInComponent_Conditional_1_Template, 1, 6, "mj-record-clone-panel", 1);
|
|
136
|
+
i0.ɵɵelementEnd();
|
|
137
|
+
} if (rf & 2) {
|
|
138
|
+
i0.ɵɵproperty("Visible", ctx.Visible)("Title", ctx.Title || ctx.DefaultTitle)("WidthPx", ctx.WidthPx)("CanClose", ctx.CanCloseGuard);
|
|
139
|
+
i0.ɵɵadvance();
|
|
140
|
+
i0.ɵɵconditional(ctx.HasOpened ? 1 : -1);
|
|
141
|
+
} }, dependencies: [CommonModule, MjSlidePanelComponent, RecordClonePanelComponent], styles: ["[_nghost-%COMP%] {\n display: contents;\n }"], changeDetection: 0 });
|
|
142
|
+
}
|
|
143
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RecordCloneSlideInComponent, [{
|
|
144
|
+
type: Component,
|
|
145
|
+
args: [{ standalone: true, selector: 'mj-record-clone-slide-in', template: `
|
|
146
|
+
<mj-slide-panel
|
|
147
|
+
[Visible]="Visible"
|
|
148
|
+
[Title]="Title || DefaultTitle"
|
|
149
|
+
[WidthPx]="WidthPx"
|
|
150
|
+
[CanClose]="CanCloseGuard"
|
|
151
|
+
(Closed)="Close()">
|
|
152
|
+
@if (HasOpened) {
|
|
153
|
+
<mj-record-clone-panel
|
|
154
|
+
[Provider]="Provider"
|
|
155
|
+
[Record]="Record"
|
|
156
|
+
[EntityName]="EntityName"
|
|
157
|
+
[RecordKey]="RecordKey"
|
|
158
|
+
[AutoStart]="false"
|
|
159
|
+
[ShowStepTabs]="ShowStepTabs"
|
|
160
|
+
(StateChange)="StateChange.emit($event)"
|
|
161
|
+
(StepChange)="StepChange.emit($event)"
|
|
162
|
+
(PlanChanged)="PlanChanged.emit($event)"
|
|
163
|
+
(CloneCompleted)="CloneCompleted.emit($event)"
|
|
164
|
+
(CloneFailed)="CloneFailed.emit($event)"
|
|
165
|
+
(NavigateToRecord)="NavigateToRecord.emit($event)"
|
|
166
|
+
(CloseRequested)="Close()">
|
|
167
|
+
</mj-record-clone-panel>
|
|
168
|
+
}
|
|
169
|
+
</mj-slide-panel>
|
|
170
|
+
`, imports: [CommonModule, MjSlidePanelComponent, RecordClonePanelComponent], changeDetection: ChangeDetectionStrategy.OnPush, styles: ["\n :host {\n display: contents;\n }\n "] }]
|
|
171
|
+
}], null, { Panel: [{
|
|
172
|
+
type: ViewChild,
|
|
173
|
+
args: [RecordClonePanelComponent]
|
|
174
|
+
}], Visible: [{
|
|
175
|
+
type: Input
|
|
176
|
+
}], Record: [{
|
|
177
|
+
type: Input
|
|
178
|
+
}], EntityName: [{
|
|
179
|
+
type: Input
|
|
180
|
+
}], RecordKey: [{
|
|
181
|
+
type: Input
|
|
182
|
+
}], Title: [{
|
|
183
|
+
type: Input
|
|
184
|
+
}], WidthPx: [{
|
|
185
|
+
type: Input
|
|
186
|
+
}], ShowStepTabs: [{
|
|
187
|
+
type: Input
|
|
188
|
+
}], VisibleChange: [{
|
|
189
|
+
type: Output
|
|
190
|
+
}], Closed: [{
|
|
191
|
+
type: Output
|
|
192
|
+
}], StateChange: [{
|
|
193
|
+
type: Output
|
|
194
|
+
}], StepChange: [{
|
|
195
|
+
type: Output
|
|
196
|
+
}], PlanChanged: [{
|
|
197
|
+
type: Output
|
|
198
|
+
}], CloneCompleted: [{
|
|
199
|
+
type: Output
|
|
200
|
+
}], CloneFailed: [{
|
|
201
|
+
type: Output
|
|
202
|
+
}], NavigateToRecord: [{
|
|
203
|
+
type: Output
|
|
204
|
+
}] }); })();
|
|
205
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RecordCloneSlideInComponent, { className: "RecordCloneSlideInComponent", filePath: "src/lib/record-clone-slide-in.component.ts", lineNumber: 90 }); })();
|
|
206
|
+
//# sourceMappingURL=record-clone-slide-in.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-clone-slide-in.component.js","sourceRoot":"","sources":["../../src/lib/record-clone-slide-in.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Slide-in wrapper for the record clone panel.\n *\n * Puts {@link RecordClonePanelComponent} inside MJ's generic `<mj-slide-panel>` so any host\n * (the base-forms record toolbar, a grid, a dashboard) gets the standard right-hand slide-in\n * with one element. Everything the panel reports is re-emitted unchanged; the wrapper only\n * adds open/close handling.\n */\n\nimport {\n Component,\n ChangeDetectionStrategy,\n Input,\n Output,\n EventEmitter,\n ViewChild,\n ChangeDetectorRef,\n inject,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport type { BaseEntity } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport type { RecordCloneKey, RecordClonePlanDetails } from '@memberjunction/core-entities';\nimport { MjSlidePanelComponent } from '@memberjunction/ng-ui-components';\n\nimport { RecordClonePanelComponent } from './record-clone-panel.component';\nimport type {\n CloneCompletedEvent,\n CloneFailedEvent,\n CloneNavigationEvent,\n RecordClonePanelState,\n RecordCloneStep,\n} from './record-clone-types';\n\n/**\n * The clone wizard in a right-hand slide-in.\n *\n * Bind {@link Visible} two-way. The inner panel is created on first open and restarted on\n * every later open, so each open plans against the record's current state. Closing is refused\n * while a clone is executing.\n *\n * @example\n * ```html\n * <mj-record-clone-slide-in\n * [(Visible)]=\"ShowClone\"\n * [Record]=\"record\"\n * [Provider]=\"provider\"\n * (CloneCompleted)=\"OnCloned($event)\"\n * (NavigateToRecord)=\"OpenRecord($event)\">\n * </mj-record-clone-slide-in>\n * ```\n */\n@Component({\n standalone: true,\n selector: 'mj-record-clone-slide-in',\n template: `\n <mj-slide-panel\n [Visible]=\"Visible\"\n [Title]=\"Title || DefaultTitle\"\n [WidthPx]=\"WidthPx\"\n [CanClose]=\"CanCloseGuard\"\n (Closed)=\"Close()\">\n @if (HasOpened) {\n <mj-record-clone-panel\n [Provider]=\"Provider\"\n [Record]=\"Record\"\n [EntityName]=\"EntityName\"\n [RecordKey]=\"RecordKey\"\n [AutoStart]=\"false\"\n [ShowStepTabs]=\"ShowStepTabs\"\n (StateChange)=\"StateChange.emit($event)\"\n (StepChange)=\"StepChange.emit($event)\"\n (PlanChanged)=\"PlanChanged.emit($event)\"\n (CloneCompleted)=\"CloneCompleted.emit($event)\"\n (CloneFailed)=\"CloneFailed.emit($event)\"\n (NavigateToRecord)=\"NavigateToRecord.emit($event)\"\n (CloseRequested)=\"Close()\">\n </mj-record-clone-panel>\n }\n </mj-slide-panel>\n `,\n styles: [`\n :host {\n display: contents;\n }\n `],\n imports: [CommonModule, MjSlidePanelComponent, RecordClonePanelComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class RecordCloneSlideInComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n /** The embedded panel, once the slide-in has been opened. */\n @ViewChild(RecordClonePanelComponent) public Panel?: RecordClonePanelComponent;\n\n // ── Inputs ───────────────────────────────────────────────────────────\n\n /** Whether the slide-in is open. Opening (re)starts the wizard. Bind two-way with `[(Visible)]`. */\n @Input()\n set Visible(value: boolean) {\n const opening = value && !this._visible;\n this._visible = value;\n if (opening) {\n this.onOpened();\n }\n }\n get Visible(): boolean {\n return this._visible;\n }\n private _visible = false;\n\n /** The record to clone. See {@link RecordClonePanelComponent.Record}. */\n @Input() Record: BaseEntity | null = null;\n\n /** Entity of the source record when {@link Record} is not set. */\n @Input() EntityName?: string;\n\n /** Key of the source record when {@link Record} is not set. See {@link RecordClonePanelComponent.RecordKey}. */\n @Input() RecordKey?: RecordCloneKey | string;\n\n /** Header text. Defaults to `Clone <entity name>`. */\n @Input() Title = '';\n\n /** Initial width in pixels. Default 720, wide enough for the plan tree and the review diff. */\n @Input() WidthPx = 720;\n\n /** Show the Scope / Values / Review step tabs. Default true. */\n @Input() ShowStepTabs = true;\n\n // ── Outputs (re-emitted from the panel) ──────────────────────────────\n\n /** Fires with the new value when the slide-in opens or closes itself. */\n @Output() VisibleChange = new EventEmitter<boolean>();\n /** Fires after the slide-in closes, whatever closed it. */\n @Output() Closed = new EventEmitter<void>();\n /** See {@link RecordClonePanelComponent.StateChange}. */\n @Output() StateChange = new EventEmitter<RecordClonePanelState>();\n /** See {@link RecordClonePanelComponent.StepChange}. */\n @Output() StepChange = new EventEmitter<RecordCloneStep>();\n /** See {@link RecordClonePanelComponent.PlanChanged}. */\n @Output() PlanChanged = new EventEmitter<RecordClonePlanDetails>();\n /** See {@link RecordClonePanelComponent.CloneCompleted}. */\n @Output() CloneCompleted = new EventEmitter<CloneCompletedEvent>();\n /** See {@link RecordClonePanelComponent.CloneFailed}. */\n @Output() CloneFailed = new EventEmitter<CloneFailedEvent>();\n /** See {@link RecordClonePanelComponent.NavigateToRecord}. The slide-in closes after emitting it. */\n @Output() NavigateToRecord = new EventEmitter<CloneNavigationEvent>();\n\n // ── State ────────────────────────────────────────────────────────────\n\n /** True once the slide-in has opened at least once; the panel is created lazily. */\n public HasOpened = false;\n\n public get DefaultTitle(): string {\n const name = this.EntityName || this.Record?.EntityInfo?.Name;\n return name ? `Clone ${name}` : 'Clone record';\n }\n\n /** Passed to `mj-slide-panel`: refuses X, Escape and backdrop closes while a clone is running. */\n public readonly CanCloseGuard = (): boolean => this.Panel?.CurrentState !== 'executing';\n\n // ── Methods ──────────────────────────────────────────────────────────\n\n /** Opens the slide-in and restarts the wizard. */\n public Open(): void {\n if (this._visible) return;\n this.Visible = true;\n this.VisibleChange.emit(true);\n this.cdr.markForCheck();\n }\n\n /** Closes the slide-in unless a clone is executing. */\n public Close(): void {\n if (!this._visible || !this.CanCloseGuard()) return;\n this._visible = false;\n this.VisibleChange.emit(false);\n this.Closed.emit();\n this.cdr.markForCheck();\n }\n\n private onOpened(): void {\n if (!this.HasOpened) {\n this.HasOpened = true;\n this.cdr.markForCheck();\n }\n // The panel exists after this change-detection pass; start it once it does.\n queueMicrotask(() => {\n this.cdr.detectChanges();\n void this.Panel?.Reset();\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Type definitions for the record cloning Angular UI layer.
|
|
3
|
+
*/
|
|
4
|
+
import type { BaseEntity, CompositeKey } from '@memberjunction/core';
|
|
5
|
+
import type { RecordCloneKey, RecordClonePlanNode, RecordClonePlanEdge, RecordCloneExecuteOutput } from '@memberjunction/core-entities';
|
|
6
|
+
/** Active step in the clone wizard. */
|
|
7
|
+
export type RecordCloneStep = 'scope' | 'values' | 'review';
|
|
8
|
+
/** State of the clone wizard. */
|
|
9
|
+
export type RecordClonePanelState = 'loading' | 'scope' | 'values' | 'review' | 'executing' | 'done' | 'blocked' | 'plan_changed' | 'failed' | 'not_cloneable';
|
|
10
|
+
/** Emitted when record cloning completes successfully. */
|
|
11
|
+
export interface CloneCompletedEvent {
|
|
12
|
+
EntityName: string;
|
|
13
|
+
TargetKey: string;
|
|
14
|
+
CloneLogID: string | null;
|
|
15
|
+
CreatedRecordsCount: number;
|
|
16
|
+
Result?: RecordCloneExecuteOutput;
|
|
17
|
+
}
|
|
18
|
+
/** A branch policy the user changed in the plan tree; sent to the planner as an edge override. */
|
|
19
|
+
export interface CloneEdgePolicyChange {
|
|
20
|
+
RelationshipID: string;
|
|
21
|
+
Policy: 'Deep' | 'Reference' | 'Skip';
|
|
22
|
+
/** Related entity of the branch, for labels such as the "Skipped branches" list. Not sent to the server. */
|
|
23
|
+
RelatedEntityName?: string;
|
|
24
|
+
}
|
|
25
|
+
/** Emitted when describe, plan or execute fails. */
|
|
26
|
+
export interface CloneFailedEvent {
|
|
27
|
+
EntityName: string;
|
|
28
|
+
/** The message the panel shows; names the failing node when the server reports one. */
|
|
29
|
+
Message: string;
|
|
30
|
+
/** Server result code, e.g. `PLAN_CHANGED`, `FORBIDDEN`, `EXECUTION_ERROR`, when there is one. */
|
|
31
|
+
ResultCode?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Asks the host to open a record. The clone widgets never navigate themselves; a host maps
|
|
35
|
+
* this onto its own navigation (base-forms turns it into a `FormNavigationEvent`).
|
|
36
|
+
*/
|
|
37
|
+
export interface CloneNavigationEvent {
|
|
38
|
+
Kind: 'record';
|
|
39
|
+
EntityName: string;
|
|
40
|
+
/** Record-id string in compact URL-segment form; parse with `CompositeKey.FromURLSegment`. */
|
|
41
|
+
RecordKey: string;
|
|
42
|
+
}
|
|
43
|
+
/** View model representing a node in the visual clone plan tree. */
|
|
44
|
+
export interface CloneTreeNodeViewModel {
|
|
45
|
+
Node: RecordClonePlanNode;
|
|
46
|
+
ParentEdge: RecordClonePlanEdge | null;
|
|
47
|
+
Children: CloneTreeNodeViewModel[];
|
|
48
|
+
Expanded: boolean;
|
|
49
|
+
Level: number;
|
|
50
|
+
}
|
|
51
|
+
/** Field prompt item required for the clone values step. */
|
|
52
|
+
export interface ClonePromptFieldItem {
|
|
53
|
+
FieldName: string;
|
|
54
|
+
DisplayName: string;
|
|
55
|
+
Type: string;
|
|
56
|
+
DefaultValue?: string | number | boolean | null;
|
|
57
|
+
IsRequired: boolean;
|
|
58
|
+
Description?: string;
|
|
59
|
+
}
|
|
60
|
+
/** Foreign key retarget item configured under UI.RetargetFields. */
|
|
61
|
+
export interface CloneRetargetFieldItem {
|
|
62
|
+
FieldName: string;
|
|
63
|
+
DisplayName: string;
|
|
64
|
+
RelatedEntity: string;
|
|
65
|
+
CurrentValue: string | null;
|
|
66
|
+
NewValue: string | null;
|
|
67
|
+
CurrentDisplayName?: string;
|
|
68
|
+
}
|
|
69
|
+
/** Progress update payload during long-running clone execution. */
|
|
70
|
+
export interface CloneProgressUpdate {
|
|
71
|
+
Percent?: number;
|
|
72
|
+
PercentComplete?: number;
|
|
73
|
+
Processed?: number;
|
|
74
|
+
CompletedRecords?: number;
|
|
75
|
+
Total?: number;
|
|
76
|
+
TotalRecords?: number;
|
|
77
|
+
Message?: string;
|
|
78
|
+
Phase?: string;
|
|
79
|
+
CurrentNodeKey?: string;
|
|
80
|
+
CurrentEntityName?: string;
|
|
81
|
+
CloneLogID?: string;
|
|
82
|
+
}
|
|
83
|
+
/** Converts a CompositeKey (any number of primary key columns) to the wire-level RecordCloneKey. */
|
|
84
|
+
export declare function CompositeKeyToRecordCloneKey(key: CompositeKey): RecordCloneKey;
|
|
85
|
+
/** Helper to extract a RecordCloneKey from an active BaseEntity record */
|
|
86
|
+
export declare function EntityToRecordCloneKey(record: BaseEntity): RecordCloneKey;
|
|
87
|
+
/** Convert a RecordCloneKey to a pipe-delimited string representation */
|
|
88
|
+
export declare function RecordCloneKeyToString(key?: RecordCloneKey | null): string;
|
|
89
|
+
//# sourceMappingURL=record-clone-types.d.ts.map
|