@memberjunction/ng-record-clone 0.0.1-seed.1 → 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.
Files changed (55) hide show
  1. package/LICENSE +183 -0
  2. package/README.md +241 -3
  3. package/dist/lib/clone-lineage-chip.component.d.ts +50 -0
  4. package/dist/lib/clone-lineage-chip.component.d.ts.map +1 -0
  5. package/dist/lib/clone-lineage-chip.component.js +448 -0
  6. package/dist/lib/clone-lineage-chip.component.js.map +1 -0
  7. package/dist/lib/clone-plan-tree.component.d.ts +51 -0
  8. package/dist/lib/clone-plan-tree.component.d.ts.map +1 -0
  9. package/dist/lib/clone-plan-tree.component.js +634 -0
  10. package/dist/lib/clone-plan-tree.component.js.map +1 -0
  11. package/dist/lib/clone-progress.component.d.ts +12 -0
  12. package/dist/lib/clone-progress.component.d.ts.map +1 -0
  13. package/dist/lib/clone-progress.component.js +151 -0
  14. package/dist/lib/clone-progress.component.js.map +1 -0
  15. package/dist/lib/clone-result.component.d.ts +40 -0
  16. package/dist/lib/clone-result.component.d.ts.map +1 -0
  17. package/dist/lib/clone-result.component.js +357 -0
  18. package/dist/lib/clone-result.component.js.map +1 -0
  19. package/dist/lib/clone-review.component.d.ts +58 -0
  20. package/dist/lib/clone-review.component.d.ts.map +1 -0
  21. package/dist/lib/clone-review.component.js +581 -0
  22. package/dist/lib/clone-review.component.js.map +1 -0
  23. package/dist/lib/clone-scope-controls.component.d.ts +81 -0
  24. package/dist/lib/clone-scope-controls.component.d.ts.map +1 -0
  25. package/dist/lib/clone-scope-controls.component.js +394 -0
  26. package/dist/lib/clone-scope-controls.component.js.map +1 -0
  27. package/dist/lib/clone-values.component.d.ts +55 -0
  28. package/dist/lib/clone-values.component.d.ts.map +1 -0
  29. package/dist/lib/clone-values.component.js +493 -0
  30. package/dist/lib/clone-values.component.js.map +1 -0
  31. package/dist/lib/record-clone-panel.component.d.ts +247 -0
  32. package/dist/lib/record-clone-panel.component.d.ts.map +1 -0
  33. package/dist/lib/record-clone-panel.component.js +1252 -0
  34. package/dist/lib/record-clone-panel.component.js.map +1 -0
  35. package/dist/lib/record-clone-slide-in.component.d.ts +83 -0
  36. package/dist/lib/record-clone-slide-in.component.d.ts.map +1 -0
  37. package/dist/lib/record-clone-slide-in.component.js +206 -0
  38. package/dist/lib/record-clone-slide-in.component.js.map +1 -0
  39. package/dist/lib/record-clone-types.d.ts +89 -0
  40. package/dist/lib/record-clone-types.d.ts.map +1 -0
  41. package/dist/lib/record-clone-types.js +29 -0
  42. package/dist/lib/record-clone-types.js.map +1 -0
  43. package/dist/lib/record-clone.module.d.ts +16 -0
  44. package/dist/lib/record-clone.module.d.ts.map +1 -0
  45. package/dist/lib/record-clone.module.js +69 -0
  46. package/dist/lib/record-clone.module.js.map +1 -0
  47. package/dist/lib/record-clone.service.d.ts +42 -0
  48. package/dist/lib/record-clone.service.d.ts.map +1 -0
  49. package/dist/lib/record-clone.service.js +123 -0
  50. package/dist/lib/record-clone.service.js.map +1 -0
  51. package/dist/public-api.d.ts +16 -0
  52. package/dist/public-api.d.ts.map +1 -0
  53. package/dist/public-api.js +16 -0
  54. package/dist/public-api.js.map +1 -0
  55. package/package.json +47 -5
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clone-scope-controls.component.js","sourceRoot":"","sources":["../../src/lib/clone-scope-controls.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Scope step controls for the record clone wizard.\n *\n * Implements §12.3 of the record cloning plan with the scope rules from the review:\n * everyone sees the preset picker and a summary of what the clone will copy, taken from the\n * entity's `Configuration.Clone`. Only a holder of `Clone Records: Override Scope` gets the\n * developer overrides (depth, record cap, soft links, subtypes, hierarchy). The summary says\n * whether Entity Actions run; changing that is not offered here (a caller holding\n * `Clone Records: Fire Hooks` can set `EntityActions` on the request). The server applies the same rules.\n */\n\nimport {\n Component,\n ChangeDetectionStrategy,\n Input,\n Output,\n EventEmitter,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { MJSwitchComponent } from '@memberjunction/ng-ui-components';\nimport type { RecordClonePlanOptions } from '@memberjunction/core-entities';\n\n/** The scope values the summary shows and the overrides edit. */\nexport interface CloneScopeValues {\n MaxDepth: number;\n MaxRecords: number;\n Subtypes: 'include' | 'exclude';\n Hierarchy: 'subtree' | 'node';\n SoftLinks: 'skip' | 'include';\n EntityActions: 'suppress' | 'fire';\n}\n\ninterface ScopeFact {\n Key: keyof CloneScopeValues;\n Text: string;\n}\n\n@Component({\n standalone: true,\n selector: 'mj-clone-scope-controls',\n template: `\n <div class=\"scope-controls-container\">\n @if (Presets && Presets.length > 0) {\n <div class=\"control-group\">\n <label class=\"control-label\" for=\"preset-select\">Cloning Preset</label>\n <select\n id=\"preset-select\"\n class=\"mj-select\"\n [ngModel]=\"SelectedPreset ?? ''\"\n (ngModelChange)=\"OnPresetChange($event)\">\n <option value=\"\">Default (Custom)</option>\n @for (preset of Presets; track preset) {\n <option [value]=\"preset\" [title]=\"PresetLabels[preset]?.Description ?? ''\">{{ PresetLabels[preset]?.Label ?? preset }}</option>\n }\n </select>\n </div>\n }\n\n <div class=\"scope-summary\">\n <div class=\"summary-top\">\n <span class=\"summary-title\">What will be copied</span>\n <span class=\"summary-source\">{{ SourceText }}</span>\n </div>\n <div class=\"facts\">\n @for (fact of Facts; track fact.Key) {\n <span class=\"fact\" [class.changed]=\"IsChanged(fact.Key)\">{{ fact.Text }}</span>\n }\n </div>\n </div>\n\n @if (CanOverrideScope) {\n <details class=\"dev-overrides\" [open]=\"ChangedKeys.length > 0\">\n <summary>\n <span><i class=\"fa-solid fa-code\"></i>&nbsp; Developer overrides</span>\n <span class=\"dev-count\">{{ ChangedKeys.length > 0 ? ChangedKeys.length + ' active' : 'none' }}</span>\n </summary>\n <div class=\"dev-body\">\n <p class=\"dev-warning\">\n These change what the engine copies for this one clone and are saved on the clone log.\n </p>\n\n @if (CanOverrideScope) {\n <div class=\"field-row\">\n <label for=\"max-depth-input\">Max depth</label>\n <input id=\"max-depth-input\" type=\"number\" min=\"1\" max=\"10\" class=\"mj-input num-input\"\n [ngModel]=\"MaxDepth\" (ngModelChange)=\"OnMaxDepthChange($event)\" />\n </div>\n <div class=\"field-row\">\n <label for=\"max-records-input\">Max records</label>\n <input id=\"max-records-input\" type=\"number\" min=\"1\" max=\"5000\" class=\"mj-input num-input\"\n [ngModel]=\"MaxRecords\" (ngModelChange)=\"OnMaxRecordsChange($event)\" />\n </div>\n <div class=\"field-row\">\n <span class=\"toggle-label\" [id]=\"IdPrefix + '-softlinks'\" (click)=\"OnSoftLinksToggle(SoftLinks !== 'include')\">Include soft links</span>\n <mj-switch [AriaLabelledBy]=\"IdPrefix + '-softlinks'\" [ngModel]=\"SoftLinks === 'include'\" (ngModelChange)=\"OnSoftLinksToggle($event)\"></mj-switch>\n <span class=\"field-hint\">Tags, attachments, notes and other EntityID/RecordID rows</span>\n </div>\n <div class=\"field-row\">\n <span class=\"toggle-label\" [id]=\"IdPrefix + '-subtypes'\" (click)=\"OnSubtypesToggle(Subtypes !== 'include')\">Include IS-A subtypes</span>\n <mj-switch [AriaLabelledBy]=\"IdPrefix + '-subtypes'\" [ngModel]=\"Subtypes === 'include'\" (ngModelChange)=\"OnSubtypesToggle($event)\"></mj-switch>\n </div>\n <div class=\"field-row\">\n <span class=\"toggle-label\" [id]=\"IdPrefix + '-hierarchy'\" (click)=\"OnHierarchyToggle(Hierarchy !== 'subtree')\">Copy the whole hierarchy subtree</span>\n <mj-switch [AriaLabelledBy]=\"IdPrefix + '-hierarchy'\" [ngModel]=\"Hierarchy === 'subtree'\" (ngModelChange)=\"OnHierarchyToggle($event)\"></mj-switch>\n </div>\n }\n\n <div class=\"dev-actions\">\n <span>{{ DefaultsText }}</span>\n <button type=\"button\" class=\"link-btn\" [disabled]=\"ChangedKeys.length === 0\" (click)=\"OnResetToDefaults()\">\n Reset to entity defaults\n </button>\n </div>\n </div>\n </details>\n }\n </div>\n `,\n styles: [`\n .scope-controls-container {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-4);\n padding: var(--mj-space-2) 0;\n }\n\n .control-group {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n }\n\n .control-label {\n font-size: var(--mj-text-xs);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-select, .mj-input {\n padding: var(--mj-space-1-5) var(--mj-space-2-5);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: var(--mj-text-sm);\n outline: none;\n }\n\n .mj-select:focus, .mj-input:focus {\n border-color: var(--mj-brand-primary);\n }\n\n .scope-summary {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n padding: var(--mj-space-3);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-card);\n }\n\n .summary-top {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n align-items: baseline;\n gap: var(--mj-space-2);\n }\n\n .summary-title {\n font-size: var(--mj-text-sm);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .summary-source {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n }\n\n .facts {\n display: flex;\n flex-wrap: wrap;\n gap: var(--mj-space-1-5);\n }\n\n .fact {\n font-size: var(--mj-text-xs);\n padding: 3px var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n }\n\n .fact.changed {\n border-color: var(--mj-status-warning-border);\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n font-weight: 600;\n }\n\n .dev-overrides {\n border: 1px solid var(--mj-status-warning-border);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n }\n\n .dev-overrides summary {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: var(--mj-space-2);\n padding: var(--mj-space-2-5) var(--mj-space-3);\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n font-weight: 600;\n font-size: var(--mj-text-sm);\n cursor: pointer;\n list-style: none;\n }\n\n .dev-overrides summary::-webkit-details-marker {\n display: none;\n }\n\n .dev-overrides summary:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n }\n\n .dev-count {\n font-weight: 500;\n font-size: var(--mj-text-xs);\n }\n\n .dev-body {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-3);\n padding: var(--mj-space-3);\n background: var(--mj-bg-surface);\n }\n\n .dev-warning {\n margin: 0;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n }\n\n .field-row {\n display: grid;\n grid-template-columns: 1fr auto;\n align-items: center;\n gap: var(--mj-space-1) var(--mj-space-3);\n }\n\n .field-row label, .toggle-label {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n cursor: pointer;\n user-select: none;\n }\n\n .field-hint {\n grid-column: 1 / -1;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n }\n\n .num-input {\n width: 96px;\n font-variant-numeric: tabular-nums;\n }\n\n .dev-actions {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n align-items: center;\n gap: var(--mj-space-2);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n }\n\n .link-btn {\n border: 0;\n background: none;\n padding: 0;\n color: var(--mj-brand-primary);\n font: inherit;\n cursor: pointer;\n }\n\n .link-btn:disabled {\n color: var(--mj-text-muted);\n cursor: default;\n }\n `],\n imports: [CommonModule, FormsModule, MJSwitchComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CloneScopeControlsComponent {\n /** Preset keys from the entity's `Clone.Presets`. */\n @Input() Presets: string[] = [];\n /** Label and description to show for each preset key; a key with none is shown as-is. */\n @Input() PresetLabels: Record<string, { Label: string; Description?: string }> = {};\n /** The preset currently applied, if any. */\n @Input() SelectedPreset?: string;\n\n /** Effective depth the plan uses. */\n @Input() MaxDepth = 3;\n /** Effective cap on records the clone may create. */\n @Input() MaxRecords = 500;\n /** Whether IS-A subtype rows are cloned with their parent. */\n @Input() Subtypes: 'include' | 'exclude' = 'include';\n /** For self-referencing hierarchies: copy the whole subtree, or only this node. */\n @Input() Hierarchy: 'subtree' | 'node' = 'subtree';\n /** Whether polymorphic EntityID/RecordID rows (tags, attachments, notes) are cloned. */\n @Input() SoftLinks: 'skip' | 'include' = 'skip';\n /** Whether Entity Actions run during the clone's saves. */\n @Input() EntityActions: 'suppress' | 'fire' = 'fire';\n\n /** The entity's configured scope; the summary highlights where the effective values differ. Null = same as effective. */\n @Input() ConfiguredScope: CloneScopeValues | null = null;\n /** Entity being cloned, for the summary's source line. */\n @Input() EntityName = '';\n\n /** Show the depth, cap and scope toggles. True only for holders of `Clone Records: Override Scope`. */\n @Input() CanOverrideScope = false;\n private static nextId = 0;\n /** Prefix for this instance's element ids, so the switches' labels stay unique on a page with two panels. */\n public readonly IdPrefix = `mj-clone-scope-${++CloneScopeControlsComponent.nextId}`;\n\n /** Fires with the full option set whenever any control changes. */\n @Output() ScopeChanged = new EventEmitter<RecordClonePlanOptions>();\n /** Fires when the user asks to drop every override and use the entity's configured scope. */\n @Output() ResetToDefaults = new EventEmitter<void>();\n\n public get Current(): CloneScopeValues {\n return {\n MaxDepth: this.MaxDepth,\n MaxRecords: this.MaxRecords,\n Subtypes: this.Subtypes,\n Hierarchy: this.Hierarchy,\n SoftLinks: this.SoftLinks,\n EntityActions: this.EntityActions,\n };\n }\n\n /** Scope values that differ from the entity's configuration. */\n public get ChangedKeys(): Array<keyof CloneScopeValues> {\n const configured = this.ConfiguredScope;\n if (!configured) return [];\n const current = this.Current;\n return (Object.keys(current) as Array<keyof CloneScopeValues>).filter((k) => current[k] !== configured[k]);\n }\n\n public IsChanged(key: keyof CloneScopeValues): boolean {\n return this.ChangedKeys.includes(key);\n }\n\n public get Facts(): ScopeFact[] {\n return [\n { Key: 'MaxDepth', Text: `Depth ${this.MaxDepth}` },\n { Key: 'MaxRecords', Text: `Up to ${this.MaxRecords} records` },\n { Key: 'SoftLinks', Text: this.SoftLinks === 'include' ? 'Soft links included' : 'Soft links off' },\n { Key: 'Subtypes', Text: this.Subtypes === 'include' ? 'Subtypes included' : 'Subtypes excluded' },\n { Key: 'Hierarchy', Text: this.Hierarchy === 'subtree' ? 'Hierarchy subtree' : 'This node only' },\n { Key: 'EntityActions', Text: this.EntityActions === 'fire' ? 'Entity actions fire' : 'Entity actions suppressed' },\n ];\n }\n\n public get SourceText(): string {\n const entity = this.EntityName ? `the ${this.EntityName} clone configuration` : 'the entity clone configuration';\n const n = this.ChangedKeys.length;\n return n === 0 ? `Set by ${entity}` : `${entity.charAt(0).toUpperCase()}${entity.slice(1)}, with ${n} override${n === 1 ? '' : 's'}`;\n }\n\n public get DefaultsText(): string {\n const c = this.ConfiguredScope;\n if (!c) return '';\n return `Entity defaults: depth ${c.MaxDepth} · ${c.MaxRecords} records · soft links ${c.SoftLinks === 'include' ? 'on' : 'off'}`;\n }\n\n public OnPresetChange(preset: string): void {\n this.SelectedPreset = preset || undefined;\n this.EmitScopeChanged();\n }\n\n public OnMaxDepthChange(depth: number | string): void {\n const parsed = typeof depth === 'string' ? parseInt(depth, 10) : depth;\n if (!Number.isFinite(parsed) || parsed < 1) return;\n this.MaxDepth = parsed;\n this.EmitScopeChanged();\n }\n\n public OnMaxRecordsChange(records: number | string): void {\n const parsed = typeof records === 'string' ? parseInt(records, 10) : records;\n if (!Number.isFinite(parsed) || parsed < 1) return;\n this.MaxRecords = parsed;\n this.EmitScopeChanged();\n }\n\n public OnSubtypesToggle(checked: boolean): void {\n this.Subtypes = checked ? 'include' : 'exclude';\n this.EmitScopeChanged();\n }\n\n public OnHierarchyToggle(checked: boolean): void {\n this.Hierarchy = checked ? 'subtree' : 'node';\n this.EmitScopeChanged();\n }\n\n public OnSoftLinksToggle(checked: boolean): void {\n this.SoftLinks = checked ? 'include' : 'skip';\n this.EmitScopeChanged();\n }\n\n public OnResetToDefaults(): void {\n this.ResetToDefaults.emit();\n }\n\n public EmitScopeChanged(): void {\n this.ScopeChanged.emit({ Preset: this.SelectedPreset, ...this.Current });\n }\n}\n"]}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @fileoverview Values configuration component for cloned records.
3
+ *
4
+ * Implements §12.3 & §12.4 of the Record Cloning architectural blueprint. Captures
5
+ * the root cloned record's name (prefilled via the naming strategy), prompts for
6
+ * required or configured field values, displays retarget pickers for foreign keys,
7
+ * and records an optional clone justification reason.
8
+ */
9
+ import { EventEmitter, OnInit, OnChanges } from '@angular/core';
10
+ import type { ClonePromptFieldItem, CloneRetargetFieldItem } from './record-clone-types';
11
+ import * as i0 from "@angular/core";
12
+ export declare class CloneValuesComponent implements OnInit, OnChanges {
13
+ /** Entity being cloned; used in labels. */
14
+ EntityName: string;
15
+ /** Name the clone will get. Pre-filled from the naming strategy; editable. */
16
+ RootName: string;
17
+ /** Why the suggested name was chosen (e.g. the source name already exists). */
18
+ NamingStrategyReason?: string;
19
+ /** The configuration sets the name (a rule or reset), so it's shown but can't be typed over. */
20
+ RootNameReadOnly: boolean;
21
+ /** Fields the entity's `Clone.Fields.PromptFor` requires the user to fill. */
22
+ PromptedFields: ClonePromptFieldItem[];
23
+ /** Current values for the prompted fields, keyed by field name. */
24
+ PromptedValues: Record<string, string | number | boolean | null>;
25
+ /** Foreign keys from `Clone.UI.RetargetFields` the user may point at a different record. */
26
+ RetargetFields: CloneRetargetFieldItem[];
27
+ /** Free-text reason stored on the clone log. */
28
+ Reason: string;
29
+ HasUserEditedRootName: boolean;
30
+ /** Fires as the user edits the clone's name. */
31
+ RootNameChange: EventEmitter<string>;
32
+ /** Fires with the full value map whenever a prompted field changes. */
33
+ PromptedValuesChange: EventEmitter<Record<string, string | number | boolean | null>>;
34
+ /** Fires when a retarget picker changes. */
35
+ RetargetFieldsChange: EventEmitter<CloneRetargetFieldItem[]>;
36
+ /** Fires as the user edits the reason. */
37
+ ReasonChange: EventEmitter<string>;
38
+ /** Fires when the step becomes valid or invalid (every required prompted field filled). */
39
+ ValidityChange: EventEmitter<boolean>;
40
+ ngOnInit(): void;
41
+ ngOnChanges(): void;
42
+ OnRootNameInput(event: Event): void;
43
+ OnRootNameChange(name: string): void;
44
+ OnTextFieldInput(fieldName: string, event: Event): void;
45
+ OnNumberFieldInput(fieldName: string, event: Event): void;
46
+ OnFieldChange(fieldName: string, value: string | number | boolean | null): void;
47
+ OnRetargetInput(item: CloneRetargetFieldItem, event: Event): void;
48
+ OnRetargetFieldChange(item: CloneRetargetFieldItem, newValue: string): void;
49
+ OnReasonInput(event: Event): void;
50
+ OnReasonChange(reason: string): void;
51
+ CheckValidity(): void;
52
+ static ɵfac: i0.ɵɵFactoryDeclaration<CloneValuesComponent, never>;
53
+ static ɵcmp: i0.ɵɵComponentDeclaration<CloneValuesComponent, "mj-clone-values", never, { "EntityName": { "alias": "EntityName"; "required": false; }; "RootName": { "alias": "RootName"; "required": false; }; "NamingStrategyReason": { "alias": "NamingStrategyReason"; "required": false; }; "RootNameReadOnly": { "alias": "RootNameReadOnly"; "required": false; }; "PromptedFields": { "alias": "PromptedFields"; "required": false; }; "PromptedValues": { "alias": "PromptedValues"; "required": false; }; "RetargetFields": { "alias": "RetargetFields"; "required": false; }; "Reason": { "alias": "Reason"; "required": false; }; }, { "RootNameChange": "RootNameChange"; "PromptedValuesChange": "PromptedValuesChange"; "RetargetFieldsChange": "RetargetFieldsChange"; "ReasonChange": "ReasonChange"; "ValidityChange": "ValidityChange"; }, never, never, true, never>;
54
+ }
55
+ //# sourceMappingURL=clone-values.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clone-values.component.d.ts","sourceRoot":"","sources":["../../src/lib/clone-values.component.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAKH,YAAY,EACZ,MAAM,EACN,SAAS,EACZ,MAAM,eAAe,CAAC;AAIvB,OAAO,KAAK,EACR,oBAAoB,EACpB,sBAAsB,EACzB,MAAM,sBAAsB,CAAC;;AAE9B,qBAoRa,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAC1D,2CAA2C;IAClC,UAAU,SAAY;IAC/B,8EAA8E;IACrE,QAAQ,SAAM;IACvB,+EAA+E;IACtE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,gGAAgG;IACvF,gBAAgB,UAAS;IAClC,8EAA8E;IACrE,cAAc,EAAE,oBAAoB,EAAE,CAAM;IACrD,mEAAmE;IAC1D,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAM;IAC/E,4FAA4F;IACnF,cAAc,EAAE,sBAAsB,EAAE,CAAM;IACvD,gDAAgD;IACvC,MAAM,SAAM;IAEd,qBAAqB,UAAS;IAErC,gDAAgD;IACtC,cAAc,uBAA8B;IACtD,uEAAuE;IAC7D,oBAAoB,iEAAwE;IACtG,4CAA4C;IAClC,oBAAoB,yCAAgD;IAC9E,0CAA0C;IAChC,YAAY,uBAA8B;IACpD,2FAA2F;IACjF,cAAc,wBAA+B;IAEhD,QAAQ,IAAI,IAAI;IAIhB,WAAW,IAAI,IAAI;IAInB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAMnC,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAMpC,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAKvD,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAMzD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI;IAkB/E,eAAe,CAAC,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAKjE,qBAAqB,CAAC,IAAI,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAM3E,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAKjC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKpC,aAAa,IAAI,IAAI;yCArGnB,oBAAoB;2CAApB,oBAAoB;CAwHhC"}
@@ -0,0 +1,493 @@
1
+ /**
2
+ * @fileoverview Values configuration component for cloned records.
3
+ *
4
+ * Implements §12.3 & §12.4 of the Record Cloning architectural blueprint. Captures
5
+ * the root cloned record's name (prefilled via the naming strategy), prompts for
6
+ * required or configured field values, displays retarget pickers for foreign keys,
7
+ * and records an optional clone justification reason.
8
+ */
9
+ import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter, } from '@angular/core';
10
+ import { CommonModule } from '@angular/common';
11
+ import { FormsModule } from '@angular/forms';
12
+ import { MJSwitchComponent } from '@memberjunction/ng-ui-components';
13
+ import * as i0 from "@angular/core";
14
+ import * as i1 from "@angular/forms";
15
+ const _forTrack0 = ($index, $item) => $item.FieldName;
16
+ function CloneValuesComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
17
+ i0.ɵɵelementStart(0, "span", 5);
18
+ i0.ɵɵelement(1, "i", 12);
19
+ i0.ɵɵtext(2);
20
+ i0.ɵɵelementEnd();
21
+ } if (rf & 2) {
22
+ const ctx_r0 = i0.ɵɵnextContext();
23
+ i0.ɵɵadvance(2);
24
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.NamingStrategyReason, " ");
25
+ } }
26
+ function CloneValuesComponent_Conditional_8_For_7_Conditional_3_Template(rf, ctx) { if (rf & 1) {
27
+ i0.ɵɵelementStart(0, "span", 3);
28
+ i0.ɵɵtext(1, "*");
29
+ i0.ɵɵelementEnd();
30
+ } }
31
+ function CloneValuesComponent_Conditional_8_For_7_Case_4_Template(rf, ctx) { if (rf & 1) {
32
+ const _r2 = i0.ɵɵgetCurrentView();
33
+ i0.ɵɵelementStart(0, "div", 18)(1, "mj-switch", 22);
34
+ i0.ɵɵlistener("ngModelChange", function CloneValuesComponent_Conditional_8_For_7_Case_4_Template_mj_switch_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r2); const field_r3 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnFieldChange(field_r3.FieldName, $event)); });
35
+ i0.ɵɵelementEnd();
36
+ i0.ɵɵelementStart(2, "span", 23);
37
+ i0.ɵɵtext(3);
38
+ i0.ɵɵelementEnd()();
39
+ } if (rf & 2) {
40
+ const field_r3 = i0.ɵɵnextContext().$implicit;
41
+ const ctx_r0 = i0.ɵɵnextContext(2);
42
+ i0.ɵɵadvance();
43
+ i0.ɵɵproperty("InputId", "field-" + field_r3.FieldName)("ngModel", !!ctx_r0.PromptedValues[field_r3.FieldName]);
44
+ i0.ɵɵadvance(2);
45
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.PromptedValues[field_r3.FieldName] ? "Yes / Enabled" : "No / Disabled", " ");
46
+ } }
47
+ function CloneValuesComponent_Conditional_8_For_7_Case_5_Template(rf, ctx) { if (rf & 1) {
48
+ const _r4 = i0.ɵɵgetCurrentView();
49
+ i0.ɵɵelementStart(0, "input", 24);
50
+ i0.ɵɵlistener("input", function CloneValuesComponent_Conditional_8_For_7_Case_5_Template_input_input_0_listener($event) { i0.ɵɵrestoreView(_r4); const field_r3 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnNumberFieldInput(field_r3.FieldName, $event)); });
51
+ i0.ɵɵelementEnd();
52
+ } if (rf & 2) {
53
+ const field_r3 = i0.ɵɵnextContext().$implicit;
54
+ const ctx_r0 = i0.ɵɵnextContext(2);
55
+ i0.ɵɵproperty("id", "field-" + field_r3.FieldName)("value", ctx_r0.PromptedValues[field_r3.FieldName] ?? "");
56
+ } }
57
+ function CloneValuesComponent_Conditional_8_For_7_Case_6_Template(rf, ctx) { if (rf & 1) {
58
+ const _r5 = i0.ɵɵgetCurrentView();
59
+ i0.ɵɵelementStart(0, "input", 25);
60
+ i0.ɵɵlistener("input", function CloneValuesComponent_Conditional_8_For_7_Case_6_Template_input_input_0_listener($event) { i0.ɵɵrestoreView(_r5); const field_r3 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnTextFieldInput(field_r3.FieldName, $event)); });
61
+ i0.ɵɵelementEnd();
62
+ } if (rf & 2) {
63
+ const field_r3 = i0.ɵɵnextContext().$implicit;
64
+ const ctx_r0 = i0.ɵɵnextContext(2);
65
+ i0.ɵɵproperty("id", "field-" + field_r3.FieldName)("value", ctx_r0.PromptedValues[field_r3.FieldName] ?? "");
66
+ } }
67
+ function CloneValuesComponent_Conditional_8_For_7_Case_7_Template(rf, ctx) { if (rf & 1) {
68
+ const _r6 = i0.ɵɵgetCurrentView();
69
+ i0.ɵɵelementStart(0, "input", 26);
70
+ i0.ɵɵlistener("input", function CloneValuesComponent_Conditional_8_For_7_Case_7_Template_input_input_0_listener($event) { i0.ɵɵrestoreView(_r6); const field_r3 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnTextFieldInput(field_r3.FieldName, $event)); });
71
+ i0.ɵɵelementEnd();
72
+ } if (rf & 2) {
73
+ const field_r3 = i0.ɵɵnextContext().$implicit;
74
+ const ctx_r0 = i0.ɵɵnextContext(2);
75
+ i0.ɵɵproperty("id", "field-" + field_r3.FieldName)("value", ctx_r0.PromptedValues[field_r3.FieldName] ?? "");
76
+ } }
77
+ function CloneValuesComponent_Conditional_8_For_7_Conditional_8_Template(rf, ctx) { if (rf & 1) {
78
+ i0.ɵɵelementStart(0, "span", 11);
79
+ i0.ɵɵtext(1);
80
+ i0.ɵɵelementEnd();
81
+ } if (rf & 2) {
82
+ const field_r3 = i0.ɵɵnextContext().$implicit;
83
+ i0.ɵɵadvance();
84
+ i0.ɵɵtextInterpolate(field_r3.Description);
85
+ } }
86
+ function CloneValuesComponent_Conditional_8_For_7_Template(rf, ctx) { if (rf & 1) {
87
+ i0.ɵɵelementStart(0, "div", 16)(1, "label", 17);
88
+ i0.ɵɵtext(2);
89
+ i0.ɵɵconditionalCreate(3, CloneValuesComponent_Conditional_8_For_7_Conditional_3_Template, 2, 0, "span", 3);
90
+ i0.ɵɵelementEnd();
91
+ i0.ɵɵconditionalCreate(4, CloneValuesComponent_Conditional_8_For_7_Case_4_Template, 4, 3, "div", 18)(5, CloneValuesComponent_Conditional_8_For_7_Case_5_Template, 1, 2, "input", 19)(6, CloneValuesComponent_Conditional_8_For_7_Case_6_Template, 1, 2, "input", 20)(7, CloneValuesComponent_Conditional_8_For_7_Case_7_Template, 1, 2, "input", 21);
92
+ i0.ɵɵconditionalCreate(8, CloneValuesComponent_Conditional_8_For_7_Conditional_8_Template, 2, 1, "span", 11);
93
+ i0.ɵɵelementEnd();
94
+ } if (rf & 2) {
95
+ let tmp_14_0;
96
+ const field_r3 = ctx.$implicit;
97
+ i0.ɵɵadvance();
98
+ i0.ɵɵproperty("for", "field-" + field_r3.FieldName);
99
+ i0.ɵɵadvance();
100
+ i0.ɵɵtextInterpolate1(" ", field_r3.DisplayName || field_r3.FieldName, " ");
101
+ i0.ɵɵadvance();
102
+ i0.ɵɵconditional(field_r3.IsRequired ? 3 : -1);
103
+ i0.ɵɵadvance();
104
+ i0.ɵɵconditional((tmp_14_0 = field_r3.Type.toLowerCase()) === "boolean" ? 4 : tmp_14_0 === "number" ? 5 : tmp_14_0 === "date" ? 6 : 7);
105
+ i0.ɵɵadvance(4);
106
+ i0.ɵɵconditional(field_r3.Description ? 8 : -1);
107
+ } }
108
+ function CloneValuesComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
109
+ i0.ɵɵelementStart(0, "div", 6)(1, "h4", 13);
110
+ i0.ɵɵtext(2, "Required & Prompted Fields");
111
+ i0.ɵɵelementEnd();
112
+ i0.ɵɵelementStart(3, "p", 14);
113
+ i0.ɵɵtext(4, " Provide or verify the following fields for the cloned record: ");
114
+ i0.ɵɵelementEnd();
115
+ i0.ɵɵelementStart(5, "div", 15);
116
+ i0.ɵɵrepeaterCreate(6, CloneValuesComponent_Conditional_8_For_7_Template, 9, 5, "div", 16, _forTrack0);
117
+ i0.ɵɵelementEnd()();
118
+ } if (rf & 2) {
119
+ const ctx_r0 = i0.ɵɵnextContext();
120
+ i0.ɵɵadvance(6);
121
+ i0.ɵɵrepeater(ctx_r0.PromptedFields);
122
+ } }
123
+ function CloneValuesComponent_Conditional_9_For_7_Conditional_7_Template(rf, ctx) { if (rf & 1) {
124
+ i0.ɵɵelementStart(0, "span", 11);
125
+ i0.ɵɵtext(1);
126
+ i0.ɵɵelementEnd();
127
+ } if (rf & 2) {
128
+ const item_r8 = i0.ɵɵnextContext().$implicit;
129
+ i0.ɵɵadvance();
130
+ i0.ɵɵtextInterpolate1(" Current: ", item_r8.CurrentDisplayName, " ");
131
+ } }
132
+ function CloneValuesComponent_Conditional_9_For_7_Template(rf, ctx) { if (rf & 1) {
133
+ const _r7 = i0.ɵɵgetCurrentView();
134
+ i0.ɵɵelementStart(0, "div", 28)(1, "label", 17);
135
+ i0.ɵɵtext(2);
136
+ i0.ɵɵelementStart(3, "span", 29);
137
+ i0.ɵɵtext(4);
138
+ i0.ɵɵelementEnd()();
139
+ i0.ɵɵelementStart(5, "div", 30)(6, "input", 31);
140
+ i0.ɵɵlistener("input", function CloneValuesComponent_Conditional_9_For_7_Template_input_input_6_listener($event) { const item_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnRetargetInput(item_r8, $event)); });
141
+ i0.ɵɵelementEnd()();
142
+ i0.ɵɵconditionalCreate(7, CloneValuesComponent_Conditional_9_For_7_Conditional_7_Template, 2, 1, "span", 11);
143
+ i0.ɵɵelementEnd();
144
+ } if (rf & 2) {
145
+ const item_r8 = ctx.$implicit;
146
+ i0.ɵɵadvance();
147
+ i0.ɵɵproperty("for", "retarget-" + item_r8.FieldName);
148
+ i0.ɵɵadvance();
149
+ i0.ɵɵtextInterpolate1(" ", item_r8.DisplayName || item_r8.FieldName, " ");
150
+ i0.ɵɵadvance(2);
151
+ i0.ɵɵtextInterpolate1("(", item_r8.RelatedEntity, ")");
152
+ i0.ɵɵadvance(2);
153
+ i0.ɵɵproperty("id", "retarget-" + item_r8.FieldName)("value", item_r8.NewValue || item_r8.CurrentValue || "");
154
+ i0.ɵɵadvance();
155
+ i0.ɵɵconditional(item_r8.CurrentDisplayName ? 7 : -1);
156
+ } }
157
+ function CloneValuesComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
158
+ i0.ɵɵelementStart(0, "div", 6)(1, "h4", 13);
159
+ i0.ɵɵtext(2, "Retarget Relationships");
160
+ i0.ɵɵelementEnd();
161
+ i0.ɵɵelementStart(3, "p", 14);
162
+ i0.ɵɵtext(4, " Redirect parent or foreign key references for the cloned record: ");
163
+ i0.ɵɵelementEnd();
164
+ i0.ɵɵelementStart(5, "div", 27);
165
+ i0.ɵɵrepeaterCreate(6, CloneValuesComponent_Conditional_9_For_7_Template, 8, 6, "div", 28, _forTrack0);
166
+ i0.ɵɵelementEnd()();
167
+ } if (rf & 2) {
168
+ const ctx_r0 = i0.ɵɵnextContext();
169
+ i0.ɵɵadvance(6);
170
+ i0.ɵɵrepeater(ctx_r0.RetargetFields);
171
+ } }
172
+ export class CloneValuesComponent {
173
+ /** Entity being cloned; used in labels. */
174
+ EntityName = 'Record';
175
+ /** Name the clone will get. Pre-filled from the naming strategy; editable. */
176
+ RootName = '';
177
+ /** Why the suggested name was chosen (e.g. the source name already exists). */
178
+ NamingStrategyReason;
179
+ /** The configuration sets the name (a rule or reset), so it's shown but can't be typed over. */
180
+ RootNameReadOnly = false;
181
+ /** Fields the entity's `Clone.Fields.PromptFor` requires the user to fill. */
182
+ PromptedFields = [];
183
+ /** Current values for the prompted fields, keyed by field name. */
184
+ PromptedValues = {};
185
+ /** Foreign keys from `Clone.UI.RetargetFields` the user may point at a different record. */
186
+ RetargetFields = [];
187
+ /** Free-text reason stored on the clone log. */
188
+ Reason = '';
189
+ HasUserEditedRootName = false;
190
+ /** Fires as the user edits the clone's name. */
191
+ RootNameChange = new EventEmitter();
192
+ /** Fires with the full value map whenever a prompted field changes. */
193
+ PromptedValuesChange = new EventEmitter();
194
+ /** Fires when a retarget picker changes. */
195
+ RetargetFieldsChange = new EventEmitter();
196
+ /** Fires as the user edits the reason. */
197
+ ReasonChange = new EventEmitter();
198
+ /** Fires when the step becomes valid or invalid (every required prompted field filled). */
199
+ ValidityChange = new EventEmitter();
200
+ ngOnInit() {
201
+ this.CheckValidity();
202
+ }
203
+ ngOnChanges() {
204
+ this.CheckValidity();
205
+ }
206
+ OnRootNameInput(event) {
207
+ const input = event.target;
208
+ this.HasUserEditedRootName = true;
209
+ this.OnRootNameChange(input.value);
210
+ }
211
+ OnRootNameChange(name) {
212
+ this.RootName = name;
213
+ this.RootNameChange.emit(name);
214
+ this.CheckValidity();
215
+ }
216
+ OnTextFieldInput(fieldName, event) {
217
+ const input = event.target;
218
+ this.OnFieldChange(fieldName, input.value);
219
+ }
220
+ OnNumberFieldInput(fieldName, event) {
221
+ const input = event.target;
222
+ const val = input.value === '' ? null : parseFloat(input.value);
223
+ this.OnFieldChange(fieldName, val);
224
+ }
225
+ OnFieldChange(fieldName, value) {
226
+ this.PromptedValues = {
227
+ ...this.PromptedValues,
228
+ [fieldName]: value,
229
+ };
230
+ this.PromptedValuesChange.emit(this.PromptedValues);
231
+ // Mirror a naming field into the name box for display only. RootNameChange means the user
232
+ // typed a name (the host then sends it as an override); the host mirrors prompted values itself.
233
+ if (!this.HasUserEditedRootName && (fieldName.toLowerCase() === 'name' || fieldName.toLowerCase() === 'email')) {
234
+ if (typeof value === 'string' && value.trim().length > 0) {
235
+ this.RootName = value;
236
+ }
237
+ }
238
+ this.CheckValidity();
239
+ }
240
+ OnRetargetInput(item, event) {
241
+ const input = event.target;
242
+ this.OnRetargetFieldChange(item, input.value);
243
+ }
244
+ OnRetargetFieldChange(item, newValue) {
245
+ item.NewValue = newValue;
246
+ this.RetargetFieldsChange.emit([...this.RetargetFields]);
247
+ this.CheckValidity();
248
+ }
249
+ OnReasonInput(event) {
250
+ const textarea = event.target;
251
+ this.OnReasonChange(textarea.value);
252
+ }
253
+ OnReasonChange(reason) {
254
+ this.Reason = reason;
255
+ this.ReasonChange.emit(reason);
256
+ }
257
+ CheckValidity() {
258
+ const isRootNameValid = this.RootName.trim().length > 0;
259
+ let arePromptedFieldsValid = true;
260
+ if (this.PromptedFields && this.PromptedFields.length > 0) {
261
+ for (const field of this.PromptedFields) {
262
+ if (field.IsRequired) {
263
+ const val = this.PromptedValues[field.FieldName];
264
+ if (val === null || val === undefined || (typeof val === 'string' && val.trim().length === 0)) {
265
+ arePromptedFieldsValid = false;
266
+ break;
267
+ }
268
+ }
269
+ }
270
+ }
271
+ const isValid = isRootNameValid && arePromptedFieldsValid;
272
+ this.ValidityChange.emit(isValid);
273
+ }
274
+ static ɵfac = function CloneValuesComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CloneValuesComponent)(); };
275
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CloneValuesComponent, selectors: [["mj-clone-values"]], inputs: { EntityName: "EntityName", RootName: "RootName", NamingStrategyReason: "NamingStrategyReason", RootNameReadOnly: "RootNameReadOnly", PromptedFields: "PromptedFields", PromptedValues: "PromptedValues", RetargetFields: "RetargetFields", Reason: "Reason" }, outputs: { RootNameChange: "RootNameChange", PromptedValuesChange: "PromptedValuesChange", RetargetFieldsChange: "RetargetFieldsChange", ReasonChange: "ReasonChange", ValidityChange: "ValidityChange" }, features: [i0.ɵɵNgOnChangesFeature], decls: 19, vars: 8, consts: [[1, "clone-values-container"], [1, "control-group"], ["for", "root-name-input", 1, "control-label"], [1, "required-asterisk"], ["id", "root-name-input", "type", "text", "placeholder", "Enter record name...", 1, "mj-input", "root-name-input", 3, "input", "value", "readOnly"], [1, "control-hint", "naming-hint"], [1, "section-group"], [1, "control-group", "reason-group"], ["for", "clone-reason-input", 1, "control-label"], [1, "optional-label"], ["id", "clone-reason-input", "rows", "2", "placeholder", "Briefly describe the business reason or project context for this clone...", 1, "mj-textarea", 3, "input", "value"], [1, "control-hint"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "section-title"], [1, "section-description"], [1, "fields-grid"], [1, "control-group", "field-item"], [1, "control-label", 3, "for"], [1, "switch-field-row"], ["type", "number", 1, "mj-input", 3, "id", "value"], ["type", "date", 1, "mj-input", 3, "id", "value"], ["type", "text", 1, "mj-input", 3, "id", "value"], [3, "ngModelChange", "InputId", "ngModel"], [1, "switch-field-label"], ["type", "number", 1, "mj-input", 3, "input", "id", "value"], ["type", "date", 1, "mj-input", 3, "input", "id", "value"], ["type", "text", 1, "mj-input", 3, "input", "id", "value"], [1, "retarget-grid"], [1, "control-group", "retarget-item"], [1, "related-entity-tag"], [1, "retarget-input-wrapper"], ["type", "text", "placeholder", "Target record ID or key...", 1, "mj-input", 3, "input", "id", "value"]], template: function CloneValuesComponent_Template(rf, ctx) { if (rf & 1) {
276
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "label", 2);
277
+ i0.ɵɵtext(3);
278
+ i0.ɵɵelementStart(4, "span", 3);
279
+ i0.ɵɵtext(5, "*");
280
+ i0.ɵɵelementEnd()();
281
+ i0.ɵɵelementStart(6, "input", 4);
282
+ i0.ɵɵlistener("input", function CloneValuesComponent_Template_input_input_6_listener($event) { return ctx.OnRootNameInput($event); });
283
+ i0.ɵɵelementEnd();
284
+ i0.ɵɵconditionalCreate(7, CloneValuesComponent_Conditional_7_Template, 3, 1, "span", 5);
285
+ i0.ɵɵelementEnd();
286
+ i0.ɵɵconditionalCreate(8, CloneValuesComponent_Conditional_8_Template, 8, 0, "div", 6);
287
+ i0.ɵɵconditionalCreate(9, CloneValuesComponent_Conditional_9_Template, 8, 0, "div", 6);
288
+ i0.ɵɵelementStart(10, "div", 7)(11, "label", 8);
289
+ i0.ɵɵtext(12, " Reason for Cloning ");
290
+ i0.ɵɵelementStart(13, "span", 9);
291
+ i0.ɵɵtext(14, "(Optional)");
292
+ i0.ɵɵelementEnd()();
293
+ i0.ɵɵelementStart(15, "textarea", 10);
294
+ i0.ɵɵlistener("input", function CloneValuesComponent_Template_textarea_input_15_listener($event) { return ctx.OnReasonInput($event); });
295
+ i0.ɵɵtext(16, " ");
296
+ i0.ɵɵelementEnd();
297
+ i0.ɵɵelementStart(17, "span", 11);
298
+ i0.ɵɵtext(18, "Recorded in the clone audit log for traceability.");
299
+ i0.ɵɵelementEnd()()();
300
+ } if (rf & 2) {
301
+ i0.ɵɵadvance(3);
302
+ i0.ɵɵtextInterpolate1(" Name for Cloned ", ctx.EntityName, " ");
303
+ i0.ɵɵadvance(3);
304
+ i0.ɵɵproperty("value", ctx.RootName)("readOnly", ctx.RootNameReadOnly);
305
+ i0.ɵɵattribute("aria-readonly", ctx.RootNameReadOnly || null);
306
+ i0.ɵɵadvance();
307
+ i0.ɵɵconditional(ctx.NamingStrategyReason ? 7 : -1);
308
+ i0.ɵɵadvance();
309
+ i0.ɵɵconditional(ctx.PromptedFields && ctx.PromptedFields.length > 0 ? 8 : -1);
310
+ i0.ɵɵadvance();
311
+ i0.ɵɵconditional(ctx.RetargetFields && ctx.RetargetFields.length > 0 ? 9 : -1);
312
+ i0.ɵɵadvance(6);
313
+ i0.ɵɵproperty("value", ctx.Reason);
314
+ } }, dependencies: [CommonModule,
315
+ FormsModule, i1.NgControlStatus, i1.NgModel, MJSwitchComponent], styles: [".clone-values-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-5);\n padding: var(--mj-space-1) 0;\n }\n\n .control-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n }\n\n .control-label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .required-asterisk[_ngcontent-%COMP%] {\n color: var(--mj-status-error-text);\n font-weight: 700;\n }\n\n .optional-label[_ngcontent-%COMP%] {\n font-weight: 400;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-xs);\n }\n\n .control-hint[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n }\n\n .naming-hint[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n color: var(--mj-brand-primary);\n margin-top: 2px;\n }\n\n .mj-input[_ngcontent-%COMP%], .mj-textarea[_ngcontent-%COMP%] {\n padding: var(--mj-space-1-5) var(--mj-space-2-5);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: var(--mj-text-sm);\n outline: none;\n transition: border-color 0.15s ease-in-out;\n font-family: inherit;\n }\n\n .mj-input[_ngcontent-%COMP%]:focus, .mj-textarea[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n }\n\n .root-name-input[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: 500;\n }\n\n .section-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n padding: var(--mj-space-3);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n }\n\n .section-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-sm);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .section-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n }\n\n .fields-grid[_ngcontent-%COMP%], .retarget-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--mj-space-3);\n margin-top: var(--mj-space-1);\n }\n\n @media (max-width: 640px) {\n .fields-grid[_ngcontent-%COMP%], .retarget-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n }\n\n .switch-field-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: 4px 0;\n }\n\n .switch-field-label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n }\n\n .related-entity-tag[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 400;\n color: var(--mj-text-muted);\n }\n\n .mj-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 52px;\n }"], changeDetection: 0 });
316
+ }
317
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CloneValuesComponent, [{
318
+ type: Component,
319
+ args: [{ standalone: true, selector: 'mj-clone-values', template: `
320
+ <div class="clone-values-container">
321
+ <!-- Root Record Name -->
322
+ <div class="control-group">
323
+ <label class="control-label" for="root-name-input">
324
+ Name for Cloned {{EntityName}} <span class="required-asterisk">*</span>
325
+ </label>
326
+ <input
327
+ id="root-name-input"
328
+ type="text"
329
+ class="mj-input root-name-input"
330
+ placeholder="Enter record name..."
331
+ [value]="RootName"
332
+ [readOnly]="RootNameReadOnly"
333
+ [attr.aria-readonly]="RootNameReadOnly || null"
334
+ (input)="OnRootNameInput($event)" />
335
+ @if (NamingStrategyReason) {
336
+ <span class="control-hint naming-hint">
337
+ <i class="fa-solid fa-wand-magic-sparkles"></i>
338
+ {{NamingStrategyReason}}
339
+ </span>
340
+ }
341
+ </div>
342
+
343
+ <!-- Prompted Fields -->
344
+ @if (PromptedFields && PromptedFields.length > 0) {
345
+ <div class="section-group">
346
+ <h4 class="section-title">Required & Prompted Fields</h4>
347
+ <p class="section-description">
348
+ Provide or verify the following fields for the cloned record:
349
+ </p>
350
+
351
+ <div class="fields-grid">
352
+ @for (field of PromptedFields; track field.FieldName) {
353
+ <div class="control-group field-item">
354
+ <label class="control-label" [for]="'field-' + field.FieldName">
355
+ {{field.DisplayName || field.FieldName}}
356
+ @if (field.IsRequired) {
357
+ <span class="required-asterisk">*</span>
358
+ }
359
+ </label>
360
+
361
+ @switch (field.Type.toLowerCase()) {
362
+ @case ('boolean') {
363
+ <div class="switch-field-row">
364
+ <mj-switch
365
+ [InputId]="'field-' + field.FieldName"
366
+ [ngModel]="!!PromptedValues[field.FieldName]"
367
+ (ngModelChange)="OnFieldChange(field.FieldName, $event)">
368
+ </mj-switch>
369
+ <span class="switch-field-label">
370
+ {{PromptedValues[field.FieldName] ? 'Yes / Enabled' : 'No / Disabled'}}
371
+ </span>
372
+ </div>
373
+ }
374
+ @case ('number') {
375
+ <input
376
+ [id]="'field-' + field.FieldName"
377
+ type="number"
378
+ class="mj-input"
379
+ [value]="PromptedValues[field.FieldName] ?? ''"
380
+ (input)="OnNumberFieldInput(field.FieldName, $event)" />
381
+ }
382
+ @case ('date') {
383
+ <input
384
+ [id]="'field-' + field.FieldName"
385
+ type="date"
386
+ class="mj-input"
387
+ [value]="PromptedValues[field.FieldName] ?? ''"
388
+ (input)="OnTextFieldInput(field.FieldName, $event)" />
389
+ }
390
+ @default {
391
+ <input
392
+ [id]="'field-' + field.FieldName"
393
+ type="text"
394
+ class="mj-input"
395
+ [value]="PromptedValues[field.FieldName] ?? ''"
396
+ (input)="OnTextFieldInput(field.FieldName, $event)" />
397
+ }
398
+ }
399
+
400
+ @if (field.Description) {
401
+ <span class="control-hint">{{field.Description}}</span>
402
+ }
403
+ </div>
404
+ }
405
+ </div>
406
+ </div>
407
+ }
408
+
409
+ <!-- Retarget Foreign Keys -->
410
+ @if (RetargetFields && RetargetFields.length > 0) {
411
+ <div class="section-group">
412
+ <h4 class="section-title">Retarget Relationships</h4>
413
+ <p class="section-description">
414
+ Redirect parent or foreign key references for the cloned record:
415
+ </p>
416
+
417
+ <div class="retarget-grid">
418
+ @for (item of RetargetFields; track item.FieldName) {
419
+ <div class="control-group retarget-item">
420
+ <label class="control-label" [for]="'retarget-' + item.FieldName">
421
+ {{item.DisplayName || item.FieldName}}
422
+ <span class="related-entity-tag">({{item.RelatedEntity}})</span>
423
+ </label>
424
+ <div class="retarget-input-wrapper">
425
+ <input
426
+ [id]="'retarget-' + item.FieldName"
427
+ type="text"
428
+ class="mj-input"
429
+ placeholder="Target record ID or key..."
430
+ [value]="item.NewValue || item.CurrentValue || ''"
431
+ (input)="OnRetargetInput(item, $event)" />
432
+ </div>
433
+ @if (item.CurrentDisplayName) {
434
+ <span class="control-hint">
435
+ Current: {{item.CurrentDisplayName}}
436
+ </span>
437
+ }
438
+ </div>
439
+ }
440
+ </div>
441
+ </div>
442
+ }
443
+
444
+ <!-- Clone Reason -->
445
+ <div class="control-group reason-group">
446
+ <label class="control-label" for="clone-reason-input">
447
+ Reason for Cloning <span class="optional-label">(Optional)</span>
448
+ </label>
449
+ <textarea
450
+ id="clone-reason-input"
451
+ rows="2"
452
+ class="mj-textarea"
453
+ placeholder="Briefly describe the business reason or project context for this clone..."
454
+ [value]="Reason"
455
+ (input)="OnReasonInput($event)">
456
+ </textarea>
457
+ <span class="control-hint">Recorded in the clone audit log for traceability.</span>
458
+ </div>
459
+ </div>
460
+ `, imports: [
461
+ CommonModule,
462
+ FormsModule,
463
+ MJSwitchComponent,
464
+ ], changeDetection: ChangeDetectionStrategy.OnPush, styles: ["\n .clone-values-container {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-5);\n padding: var(--mj-space-1) 0;\n }\n\n .control-group {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n }\n\n .control-label {\n font-size: var(--mj-text-xs);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .required-asterisk {\n color: var(--mj-status-error-text);\n font-weight: 700;\n }\n\n .optional-label {\n font-weight: 400;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-xs);\n }\n\n .control-hint {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n }\n\n .naming-hint {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n color: var(--mj-brand-primary);\n margin-top: 2px;\n }\n\n .mj-input, .mj-textarea {\n padding: var(--mj-space-1-5) var(--mj-space-2-5);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: var(--mj-text-sm);\n outline: none;\n transition: border-color 0.15s ease-in-out;\n font-family: inherit;\n }\n\n .mj-input:focus, .mj-textarea:focus {\n border-color: var(--mj-brand-primary);\n }\n\n .root-name-input {\n font-size: var(--mj-text-sm);\n font-weight: 500;\n }\n\n .section-group {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n padding: var(--mj-space-3);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n }\n\n .section-title {\n margin: 0;\n font-size: var(--mj-text-sm);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .section-description {\n margin: 0;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n }\n\n .fields-grid, .retarget-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--mj-space-3);\n margin-top: var(--mj-space-1);\n }\n\n @media (max-width: 640px) {\n .fields-grid, .retarget-grid {\n grid-template-columns: 1fr;\n }\n }\n\n .switch-field-row {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: 4px 0;\n }\n\n .switch-field-label {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n }\n\n .related-entity-tag {\n font-size: 11px;\n font-weight: 400;\n color: var(--mj-text-muted);\n }\n\n .mj-textarea {\n resize: vertical;\n min-height: 52px;\n }\n "] }]
465
+ }], null, { EntityName: [{
466
+ type: Input
467
+ }], RootName: [{
468
+ type: Input
469
+ }], NamingStrategyReason: [{
470
+ type: Input
471
+ }], RootNameReadOnly: [{
472
+ type: Input
473
+ }], PromptedFields: [{
474
+ type: Input
475
+ }], PromptedValues: [{
476
+ type: Input
477
+ }], RetargetFields: [{
478
+ type: Input
479
+ }], Reason: [{
480
+ type: Input
481
+ }], RootNameChange: [{
482
+ type: Output
483
+ }], PromptedValuesChange: [{
484
+ type: Output
485
+ }], RetargetFieldsChange: [{
486
+ type: Output
487
+ }], ReasonChange: [{
488
+ type: Output
489
+ }], ValidityChange: [{
490
+ type: Output
491
+ }] }); })();
492
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CloneValuesComponent, { className: "CloneValuesComponent", filePath: "src/lib/clone-values.component.ts", lineNumber: 303 }); })();
493
+ //# sourceMappingURL=clone-values.component.js.map