@memberjunction/ng-dashboards 5.37.0 → 5.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +32 -0
  2. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +14 -0
  3. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  4. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +450 -292
  5. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  6. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +73 -1
  7. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
  8. package/dist/ComponentStudio/component-studio-dashboard.component.js +512 -127
  9. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  10. package/dist/ComponentStudio/component-studio-resource.component.d.ts +22 -0
  11. package/dist/ComponentStudio/component-studio-resource.component.d.ts.map +1 -0
  12. package/dist/ComponentStudio/component-studio-resource.component.js +55 -0
  13. package/dist/ComponentStudio/component-studio-resource.component.js.map +1 -0
  14. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +104 -45
  15. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -1
  16. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +234 -331
  17. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
  18. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.d.ts +54 -0
  19. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.d.ts.map +1 -0
  20. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.js +339 -0
  21. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.js.map +1 -0
  22. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.d.ts +65 -0
  23. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.d.ts.map +1 -0
  24. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.js +492 -0
  25. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.js.map +1 -0
  26. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.d.ts +88 -0
  27. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.d.ts.map +1 -0
  28. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.js +457 -0
  29. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.js.map +1 -0
  30. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts +106 -0
  31. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts.map +1 -0
  32. package/dist/ComponentStudio/components/form-override-dialog.component.js +478 -0
  33. package/dist/ComponentStudio/components/form-override-dialog.component.js.map +1 -0
  34. package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts +54 -0
  35. package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts.map +1 -1
  36. package/dist/ComponentStudio/components/workspace/component-preview.component.js +361 -50
  37. package/dist/ComponentStudio/components/workspace/component-preview.component.js.map +1 -1
  38. package/dist/ComponentStudio/components/workspace/editor-tabs.component.d.ts +10 -0
  39. package/dist/ComponentStudio/components/workspace/editor-tabs.component.d.ts.map +1 -1
  40. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +114 -45
  41. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
  42. package/dist/ComponentStudio/services/canvas-to-code.d.ts +32 -0
  43. package/dist/ComponentStudio/services/canvas-to-code.d.ts.map +1 -0
  44. package/dist/ComponentStudio/services/canvas-to-code.js +347 -0
  45. package/dist/ComponentStudio/services/canvas-to-code.js.map +1 -0
  46. package/dist/ComponentStudio/services/code-to-canvas.d.ts +32 -0
  47. package/dist/ComponentStudio/services/code-to-canvas.d.ts.map +1 -0
  48. package/dist/ComponentStudio/services/code-to-canvas.js +92 -0
  49. package/dist/ComponentStudio/services/code-to-canvas.js.map +1 -0
  50. package/dist/ComponentStudio/services/component-studio-state.service.d.ts +29 -0
  51. package/dist/ComponentStudio/services/component-studio-state.service.d.ts.map +1 -1
  52. package/dist/ComponentStudio/services/component-studio-state.service.js +76 -0
  53. package/dist/ComponentStudio/services/component-studio-state.service.js.map +1 -1
  54. package/dist/ComponentStudio/services/entity-form-override.service.d.ts +86 -0
  55. package/dist/ComponentStudio/services/entity-form-override.service.d.ts.map +1 -0
  56. package/dist/ComponentStudio/services/entity-form-override.service.js +246 -0
  57. package/dist/ComponentStudio/services/entity-form-override.service.js.map +1 -0
  58. package/dist/ComponentStudio/services/field-binding-scanner.d.ts +29 -0
  59. package/dist/ComponentStudio/services/field-binding-scanner.d.ts.map +1 -0
  60. package/dist/ComponentStudio/services/field-binding-scanner.js +110 -0
  61. package/dist/ComponentStudio/services/field-binding-scanner.js.map +1 -0
  62. package/dist/ComponentStudio/services/form-canvas-model.d.ts +56 -0
  63. package/dist/ComponentStudio/services/form-canvas-model.d.ts.map +1 -0
  64. package/dist/ComponentStudio/services/form-canvas-model.js +35 -0
  65. package/dist/ComponentStudio/services/form-canvas-model.js.map +1 -0
  66. package/dist/ComponentStudio/services/form-host-props-fixture.d.ts +10 -0
  67. package/dist/ComponentStudio/services/form-host-props-fixture.d.ts.map +1 -0
  68. package/dist/ComponentStudio/services/form-host-props-fixture.js +10 -0
  69. package/dist/ComponentStudio/services/form-host-props-fixture.js.map +1 -0
  70. package/dist/DataExplorer/data-explorer-dashboard.component.js +2 -2
  71. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  72. package/dist/FormBuilder/form-builder-resource.component.d.ts +964 -0
  73. package/dist/FormBuilder/form-builder-resource.component.d.ts.map +1 -0
  74. package/dist/FormBuilder/form-builder-resource.component.js +4487 -0
  75. package/dist/FormBuilder/form-builder-resource.component.js.map +1 -0
  76. package/dist/FormBuilder/form-builder-version-rail.helpers.d.ts +55 -0
  77. package/dist/FormBuilder/form-builder-version-rail.helpers.d.ts.map +1 -0
  78. package/dist/FormBuilder/form-builder-version-rail.helpers.js +73 -0
  79. package/dist/FormBuilder/form-builder-version-rail.helpers.js.map +1 -0
  80. package/dist/Home/home-application.d.ts +21 -1
  81. package/dist/Home/home-application.d.ts.map +1 -1
  82. package/dist/Home/home-application.js +60 -8
  83. package/dist/Home/home-application.js.map +1 -1
  84. package/dist/QueryBrowser/query-browser-resource.component.d.ts +14 -14
  85. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  86. package/dist/QueryBrowser/query-browser-resource.component.js +11 -10
  87. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  88. package/dist/component-studio-dashboards.module.d.ts +34 -22
  89. package/dist/component-studio-dashboards.module.d.ts.map +1 -1
  90. package/dist/component-studio-dashboards.module.js +65 -9
  91. package/dist/component-studio-dashboards.module.js.map +1 -1
  92. package/package.json +54 -53
@@ -0,0 +1,106 @@
1
+ import { EventEmitter, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
+ import { RoleInfo } from '@memberjunction/core';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Scope of an EntityFormOverride row. Mirrors the DB CHECK constraint
7
+ * (see migrations/v5/V202605161430_*_Interactive_Forms.sql).
8
+ */
9
+ export type OverrideScope = 'User' | 'Role' | 'Global';
10
+ /**
11
+ * Override row status. Active = runtime serves this; Pending = AI / user
12
+ * draft awaiting activation; Inactive = historical, never served.
13
+ */
14
+ export type OverrideStatus = 'Active' | 'Inactive' | 'Pending';
15
+ /** Payload emitted by {@link FormOverrideDialogComponent} on confirm. */
16
+ export interface FormOverrideDialogResult {
17
+ Name: string;
18
+ Description: string | null;
19
+ Notes: string | null;
20
+ EntityName: string;
21
+ Scope: OverrideScope;
22
+ RoleID: string | null;
23
+ Priority: number;
24
+ Status: OverrideStatus;
25
+ }
26
+ /**
27
+ * Modal shown after a form-role Component is saved. Lets the author create
28
+ * an `EntityFormOverride` row pointing the just-saved Component at an
29
+ * entity for User / Role / Global scope. Skip exits without persisting —
30
+ * useful when authoring a Component that isn't ready to be activated.
31
+ *
32
+ * The dialog only collects intent. The dashboard wires the confirm event
33
+ * to the write call (currently blocked on the EntityFormOverrideEntity
34
+ * generated class; see Tasks 3 + 15).
35
+ */
36
+ export declare class FormOverrideDialogComponent extends BaseAngularComponent implements OnInit, OnChanges {
37
+ /**
38
+ * Plain `@Input()`. Per-open re-sync of editable state happens in
39
+ * `ngOnChanges` — that's the only Angular hook that fires AFTER all
40
+ * inputs in a single change-detection cycle are bound. The earlier
41
+ * setter-based approach fired BEFORE peer inputs (`InitialName`,
42
+ * `InitialDescription`, etc.) were set, so the dialog rendered with
43
+ * stale or empty pre-fill values.
44
+ */
45
+ Visible: boolean;
46
+ ComponentName: string;
47
+ EntityName: string;
48
+ /** Pre-fill for the Description textarea (cockpit's input value). */
49
+ InitialDescription: string | null;
50
+ /** Pre-fill for the Name input (defaults to ComponentName). */
51
+ InitialName: string | null;
52
+ /** Pre-fill for the Notes textarea (when present in the cockpit). */
53
+ InitialNotes: string | null;
54
+ /** Pre-fill for the Status radio group. Default: 'Pending'. */
55
+ InitialStatus: OverrideStatus | null;
56
+ /** Pre-fill for the Scope radio group. Default: 'User'. */
57
+ InitialScope: OverrideScope | null;
58
+ /** Pre-fill for the Role select (when Scope='Role'). */
59
+ InitialRoleID: string | null | undefined;
60
+ /** Pre-fill for the Priority numeric input. Default: 0. */
61
+ InitialPriority: number | undefined;
62
+ /**
63
+ * When true, render the dialog as "Edit form details" instead of
64
+ * "Activate this form" — same fields, different framing. The
65
+ * confirm button reads "Save changes" and the explanatory hint adapts.
66
+ */
67
+ EditMode: boolean;
68
+ confirmed: EventEmitter<FormOverrideDialogResult>;
69
+ dismissed: EventEmitter<void>;
70
+ Name: string;
71
+ Description: string | null;
72
+ Notes: string | null;
73
+ Scope: OverrideScope;
74
+ RoleID: string | null;
75
+ Priority: number;
76
+ Status: OverrideStatus;
77
+ validationError: string | null;
78
+ availableRoles: RoleInfo[];
79
+ private readonly cd;
80
+ ngOnInit(): void;
81
+ /**
82
+ * Re-sync editable state every time `Visible` flips false→true, AFTER
83
+ * Angular has bound all the peer `@Input()`s for the same change-
84
+ * detection cycle. The previous setter-based approach fired BEFORE
85
+ * sibling inputs (`InitialName`, etc.) had landed, leaving the dialog
86
+ * pre-fill empty.
87
+ */
88
+ ngOnChanges(changes: SimpleChanges): void;
89
+ /**
90
+ * Sync editable state from `@Input()`s. Called on first open AND on
91
+ * every subsequent Visible: false → true transition so the dialog
92
+ * doesn't show stale data from a previous invocation.
93
+ */
94
+ private resetFromInputs;
95
+ OnNameInput(e: Event): void;
96
+ OnDescriptionInput(e: Event): void;
97
+ OnNotesInput(e: Event): void;
98
+ OnScopeChange(scope: OverrideScope): void;
99
+ OnRoleChanged(e: Event): void;
100
+ OnPriorityInput(e: Event): void;
101
+ OnConfirmClick(): void;
102
+ OnCancelClick(): void;
103
+ static ɵfac: i0.ɵɵFactoryDeclaration<FormOverrideDialogComponent, never>;
104
+ static ɵcmp: i0.ɵɵComponentDeclaration<FormOverrideDialogComponent, "mj-form-override-dialog", never, { "Visible": { "alias": "Visible"; "required": false; }; "ComponentName": { "alias": "ComponentName"; "required": false; }; "EntityName": { "alias": "EntityName"; "required": false; }; "InitialDescription": { "alias": "InitialDescription"; "required": false; }; "InitialName": { "alias": "InitialName"; "required": false; }; "InitialNotes": { "alias": "InitialNotes"; "required": false; }; "InitialStatus": { "alias": "InitialStatus"; "required": false; }; "InitialScope": { "alias": "InitialScope"; "required": false; }; "InitialRoleID": { "alias": "InitialRoleID"; "required": false; }; "InitialPriority": { "alias": "InitialPriority"; "required": false; }; "EditMode": { "alias": "EditMode"; "required": false; }; }, { "confirmed": "confirmed"; "dismissed": "dismissed"; }, never, never, true, never>;
105
+ }
106
+ //# sourceMappingURL=form-override-dialog.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-override-dialog.component.d.ts","sourceRoot":"","sources":["../../../src/ComponentStudio/components/form-override-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,YAAY,EAGZ,MAAM,EACN,SAAS,EACT,aAAa,EAEhB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;;AAEhD;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEvD;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAE/D,yEAAyE;AACzE,MAAM,WAAW,wBAAwB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,qBA0Ia,2BAA4B,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAE9F;;;;;;;OAOG;IACM,OAAO,UAAS;IAEhB,aAAa,SAAM;IACnB,UAAU,SAAM;IACzB,qEAAqE;IAC5D,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClD,+DAA+D;IACtD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC3C,qEAAqE;IAC5D,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5C,+DAA+D;IACtD,aAAa,EAAE,cAAc,GAAG,IAAI,CAAQ;IACrD,2DAA2D;IAClD,YAAY,EAAE,aAAa,GAAG,IAAI,CAAQ;IACnD,wDAAwD;IAC/C,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAa;IAC9D,2DAA2D;IAClD,eAAe,EAAE,MAAM,GAAG,SAAS,CAAa;IACzD;;;;OAIG;IACM,QAAQ,UAAS;IAEhB,SAAS,yCAAgD;IACzD,SAAS,qBAA4B;IAExC,IAAI,SAAM;IACV,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5B,KAAK,EAAE,aAAa,CAAU;IAC9B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC7B,QAAQ,SAAK;IACb,MAAM,EAAE,cAAc,CAAa;IACnC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEtC,cAAc,EAAE,QAAQ,EAAE,CAAM;IAEvC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAA6B;IAEhD,QAAQ,IAAI,IAAI;IAMhB;;;;;;OAMG;IACH,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IASzC;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAehB,WAAW,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;IAI3B,kBAAkB,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;IAKlC,YAAY,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;IAK5B,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAOzC,aAAa,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;IAK7B,eAAe,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;IAK/B,cAAc,IAAI,IAAI;IA0BtB,aAAa,IAAI,IAAI;yCAtJnB,2BAA2B;2CAA3B,2BAA2B;CAyJvC"}
@@ -0,0 +1,478 @@
1
+ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, inject, } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
4
+ import * as i0 from "@angular/core";
5
+ const _forTrack0 = ($index, $item) => $item.ID;
6
+ function FormOverrideDialogComponent_Conditional_0_Conditional_9_Template(rf, ctx) { if (rf & 1) {
7
+ i0.ɵɵtext(0, " Update the override's name, description, scope, priority, or status. Component code is edited from the cockpit's main editor \u2014 this dialog covers the override-row metadata only. ");
8
+ } }
9
+ function FormOverrideDialogComponent_Conditional_0_Conditional_10_Template(rf, ctx) { if (rf & 1) {
10
+ i0.ɵɵtext(0, " Create an Entity Form Override so MemberJunction renders this Component instead of the default form for matching users. Skip to keep the Component saved but inactive. ");
11
+ } }
12
+ function FormOverrideDialogComponent_Conditional_0_Conditional_39_For_4_Template(rf, ctx) { if (rf & 1) {
13
+ i0.ɵɵdomElementStart(0, "option", 28);
14
+ i0.ɵɵtext(1);
15
+ i0.ɵɵdomElementEnd();
16
+ } if (rf & 2) {
17
+ const r_r4 = ctx.$implicit;
18
+ i0.ɵɵdomProperty("value", r_r4.ID);
19
+ i0.ɵɵadvance();
20
+ i0.ɵɵtextInterpolate(r_r4.Name);
21
+ } }
22
+ function FormOverrideDialogComponent_Conditional_0_Conditional_39_Template(rf, ctx) { if (rf & 1) {
23
+ const _r3 = i0.ɵɵgetCurrentView();
24
+ i0.ɵɵdomElementStart(0, "select", 26);
25
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Conditional_39_Template_select_change_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnRoleChanged($event)); });
26
+ i0.ɵɵdomElementStart(1, "option", 27);
27
+ i0.ɵɵtext(2, "\u2014 pick a role \u2014");
28
+ i0.ɵɵdomElementEnd();
29
+ i0.ɵɵrepeaterCreate(3, FormOverrideDialogComponent_Conditional_0_Conditional_39_For_4_Template, 2, 2, "option", 28, _forTrack0);
30
+ i0.ɵɵdomElementEnd();
31
+ } if (rf & 2) {
32
+ const ctx_r1 = i0.ɵɵnextContext(2);
33
+ i0.ɵɵdomProperty("value", ctx_r1.RoleID ?? "");
34
+ i0.ɵɵadvance(3);
35
+ i0.ɵɵrepeater(ctx_r1.availableRoles);
36
+ } }
37
+ function FormOverrideDialogComponent_Conditional_0_Conditional_65_Template(rf, ctx) { if (rf & 1) {
38
+ i0.ɵɵdomElementStart(0, "div", 22);
39
+ i0.ɵɵtext(1);
40
+ i0.ɵɵdomElementEnd();
41
+ } if (rf & 2) {
42
+ const ctx_r1 = i0.ɵɵnextContext(2);
43
+ i0.ɵɵadvance();
44
+ i0.ɵɵtextInterpolate(ctx_r1.validationError);
45
+ } }
46
+ function FormOverrideDialogComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
47
+ const _r1 = i0.ɵɵgetCurrentView();
48
+ i0.ɵɵdomElementStart(0, "div", 1);
49
+ i0.ɵɵdomListener("click", function FormOverrideDialogComponent_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnCancelClick()); });
50
+ i0.ɵɵdomElementStart(1, "div", 2);
51
+ i0.ɵɵdomListener("click", function FormOverrideDialogComponent_Conditional_0_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView($event.stopPropagation()); });
52
+ i0.ɵɵdomElementStart(2, "header", 3)(3, "h3");
53
+ i0.ɵɵtext(4);
54
+ i0.ɵɵdomElementEnd();
55
+ i0.ɵɵdomElementStart(5, "button", 4);
56
+ i0.ɵɵdomListener("click", function FormOverrideDialogComponent_Conditional_0_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnCancelClick()); });
57
+ i0.ɵɵdomElement(6, "i", 5);
58
+ i0.ɵɵdomElementEnd()();
59
+ i0.ɵɵdomElementStart(7, "div", 6)(8, "p", 7);
60
+ i0.ɵɵconditionalCreate(9, FormOverrideDialogComponent_Conditional_0_Conditional_9_Template, 1, 0)(10, FormOverrideDialogComponent_Conditional_0_Conditional_10_Template, 1, 0);
61
+ i0.ɵɵdomElementEnd();
62
+ i0.ɵɵdomElementStart(11, "div", 8)(12, "label");
63
+ i0.ɵɵtext(13, "Override Name");
64
+ i0.ɵɵdomElementEnd();
65
+ i0.ɵɵdomElementStart(14, "input", 9);
66
+ i0.ɵɵdomListener("input", function FormOverrideDialogComponent_Conditional_0_Template_input_input_14_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnNameInput($event)); });
67
+ i0.ɵɵdomElementEnd()();
68
+ i0.ɵɵdomElementStart(15, "div", 8)(16, "label");
69
+ i0.ɵɵtext(17, "Description");
70
+ i0.ɵɵdomElementEnd();
71
+ i0.ɵɵdomElementStart(18, "textarea", 10);
72
+ i0.ɵɵdomListener("input", function FormOverrideDialogComponent_Conditional_0_Template_textarea_input_18_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDescriptionInput($event)); });
73
+ i0.ɵɵdomElementEnd()();
74
+ i0.ɵɵdomElementStart(19, "div", 8)(20, "label");
75
+ i0.ɵɵtext(21, "Notes");
76
+ i0.ɵɵdomElementEnd();
77
+ i0.ɵɵdomElementStart(22, "textarea", 11);
78
+ i0.ɵɵdomListener("input", function FormOverrideDialogComponent_Conditional_0_Template_textarea_input_22_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnNotesInput($event)); });
79
+ i0.ɵɵdomElementEnd()();
80
+ i0.ɵɵdomElementStart(23, "div", 8)(24, "label");
81
+ i0.ɵɵtext(25, "Entity");
82
+ i0.ɵɵdomElementEnd();
83
+ i0.ɵɵdomElement(26, "input", 12);
84
+ i0.ɵɵdomElementStart(27, "small", 13);
85
+ i0.ɵɵtext(28, "Set in the Field Binding inspector.");
86
+ i0.ɵɵdomElementEnd()();
87
+ i0.ɵɵdomElementStart(29, "div", 8)(30, "label");
88
+ i0.ɵɵtext(31, "Scope");
89
+ i0.ɵɵdomElementEnd();
90
+ i0.ɵɵdomElementStart(32, "div", 14)(33, "label", 15)(34, "input", 16);
91
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Template_input_change_34_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnScopeChange("User")); });
92
+ i0.ɵɵdomElementEnd();
93
+ i0.ɵɵtext(35, " Me only (User) ");
94
+ i0.ɵɵdomElementEnd();
95
+ i0.ɵɵdomElementStart(36, "label", 15)(37, "input", 16);
96
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Template_input_change_37_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnScopeChange("Role")); });
97
+ i0.ɵɵdomElementEnd();
98
+ i0.ɵɵtext(38, " A role ");
99
+ i0.ɵɵdomElementEnd();
100
+ i0.ɵɵconditionalCreate(39, FormOverrideDialogComponent_Conditional_0_Conditional_39_Template, 5, 1, "select", 17);
101
+ i0.ɵɵdomElementStart(40, "label", 15)(41, "input", 16);
102
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Template_input_change_41_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnScopeChange("Global")); });
103
+ i0.ɵɵdomElementEnd();
104
+ i0.ɵɵtext(42, " Everyone (Global) ");
105
+ i0.ɵɵdomElementEnd()()();
106
+ i0.ɵɵdomElementStart(43, "div", 18)(44, "div", 8)(45, "label");
107
+ i0.ɵɵtext(46, "Priority");
108
+ i0.ɵɵdomElementEnd();
109
+ i0.ɵɵdomElementStart(47, "input", 19);
110
+ i0.ɵɵdomListener("input", function FormOverrideDialogComponent_Conditional_0_Template_input_input_47_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnPriorityInput($event)); });
111
+ i0.ɵɵdomElementEnd()();
112
+ i0.ɵɵdomElementStart(48, "div", 8)(49, "label");
113
+ i0.ɵɵtext(50, "Status");
114
+ i0.ɵɵdomElementEnd();
115
+ i0.ɵɵdomElementStart(51, "div", 20)(52, "label", 15)(53, "input", 21);
116
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Template_input_change_53_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Status = "Pending"); });
117
+ i0.ɵɵdomElementEnd();
118
+ i0.ɵɵtext(54, " Pending ");
119
+ i0.ɵɵdomElementStart(55, "span", 13);
120
+ i0.ɵɵtext(56, "(draft)");
121
+ i0.ɵɵdomElementEnd()();
122
+ i0.ɵɵdomElementStart(57, "label", 15)(58, "input", 21);
123
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Template_input_change_58_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Status = "Active"); });
124
+ i0.ɵɵdomElementEnd();
125
+ i0.ɵɵtext(59, " Active ");
126
+ i0.ɵɵdomElementStart(60, "span", 13);
127
+ i0.ɵɵtext(61, "(live)");
128
+ i0.ɵɵdomElementEnd()();
129
+ i0.ɵɵdomElementStart(62, "label", 15)(63, "input", 21);
130
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Template_input_change_63_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Status = "Inactive"); });
131
+ i0.ɵɵdomElementEnd();
132
+ i0.ɵɵtext(64, " Inactive ");
133
+ i0.ɵɵdomElementEnd()()()();
134
+ i0.ɵɵconditionalCreate(65, FormOverrideDialogComponent_Conditional_0_Conditional_65_Template, 2, 1, "div", 22);
135
+ i0.ɵɵdomElementEnd();
136
+ i0.ɵɵdomElementStart(66, "footer", 23)(67, "button", 24);
137
+ i0.ɵɵdomListener("click", function FormOverrideDialogComponent_Conditional_0_Template_button_click_67_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnConfirmClick()); });
138
+ i0.ɵɵtext(68);
139
+ i0.ɵɵdomElementEnd();
140
+ i0.ɵɵdomElementStart(69, "button", 25);
141
+ i0.ɵɵdomListener("click", function FormOverrideDialogComponent_Conditional_0_Template_button_click_69_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnCancelClick()); });
142
+ i0.ɵɵtext(70);
143
+ i0.ɵɵdomElementEnd()()()();
144
+ } if (rf & 2) {
145
+ const ctx_r1 = i0.ɵɵnextContext();
146
+ i0.ɵɵadvance(4);
147
+ i0.ɵɵtextInterpolate(ctx_r1.EditMode ? "Edit form details" : "Activate this form");
148
+ i0.ɵɵadvance(5);
149
+ i0.ɵɵconditional(ctx_r1.EditMode ? 9 : 10);
150
+ i0.ɵɵadvance(5);
151
+ i0.ɵɵdomProperty("value", ctx_r1.Name);
152
+ i0.ɵɵadvance(4);
153
+ i0.ɵɵdomProperty("value", ctx_r1.Description ?? "");
154
+ i0.ɵɵadvance(4);
155
+ i0.ɵɵdomProperty("value", ctx_r1.Notes ?? "");
156
+ i0.ɵɵadvance(4);
157
+ i0.ɵɵdomProperty("value", ctx_r1.EntityName);
158
+ i0.ɵɵadvance(8);
159
+ i0.ɵɵdomProperty("checked", ctx_r1.Scope === "User");
160
+ i0.ɵɵadvance(3);
161
+ i0.ɵɵdomProperty("checked", ctx_r1.Scope === "Role");
162
+ i0.ɵɵadvance(2);
163
+ i0.ɵɵconditional(ctx_r1.Scope === "Role" ? 39 : -1);
164
+ i0.ɵɵadvance(2);
165
+ i0.ɵɵdomProperty("checked", ctx_r1.Scope === "Global");
166
+ i0.ɵɵadvance(6);
167
+ i0.ɵɵdomProperty("value", ctx_r1.Priority);
168
+ i0.ɵɵadvance(6);
169
+ i0.ɵɵdomProperty("checked", ctx_r1.Status === "Pending");
170
+ i0.ɵɵadvance(5);
171
+ i0.ɵɵdomProperty("checked", ctx_r1.Status === "Active");
172
+ i0.ɵɵadvance(5);
173
+ i0.ɵɵdomProperty("checked", ctx_r1.Status === "Inactive");
174
+ i0.ɵɵadvance(2);
175
+ i0.ɵɵconditional(ctx_r1.validationError ? 65 : -1);
176
+ i0.ɵɵadvance(3);
177
+ i0.ɵɵtextInterpolate(ctx_r1.EditMode ? "Save changes" : "Create Override");
178
+ i0.ɵɵadvance(2);
179
+ i0.ɵɵtextInterpolate(ctx_r1.EditMode ? "Cancel" : "Skip");
180
+ } }
181
+ /**
182
+ * Modal shown after a form-role Component is saved. Lets the author create
183
+ * an `EntityFormOverride` row pointing the just-saved Component at an
184
+ * entity for User / Role / Global scope. Skip exits without persisting —
185
+ * useful when authoring a Component that isn't ready to be activated.
186
+ *
187
+ * The dialog only collects intent. The dashboard wires the confirm event
188
+ * to the write call (currently blocked on the EntityFormOverrideEntity
189
+ * generated class; see Tasks 3 + 15).
190
+ */
191
+ export class FormOverrideDialogComponent extends BaseAngularComponent {
192
+ /**
193
+ * Plain `@Input()`. Per-open re-sync of editable state happens in
194
+ * `ngOnChanges` — that's the only Angular hook that fires AFTER all
195
+ * inputs in a single change-detection cycle are bound. The earlier
196
+ * setter-based approach fired BEFORE peer inputs (`InitialName`,
197
+ * `InitialDescription`, etc.) were set, so the dialog rendered with
198
+ * stale or empty pre-fill values.
199
+ */
200
+ Visible = false;
201
+ ComponentName = '';
202
+ EntityName = '';
203
+ /** Pre-fill for the Description textarea (cockpit's input value). */
204
+ InitialDescription = null;
205
+ /** Pre-fill for the Name input (defaults to ComponentName). */
206
+ InitialName = null;
207
+ /** Pre-fill for the Notes textarea (when present in the cockpit). */
208
+ InitialNotes = null;
209
+ /** Pre-fill for the Status radio group. Default: 'Pending'. */
210
+ InitialStatus = null;
211
+ /** Pre-fill for the Scope radio group. Default: 'User'. */
212
+ InitialScope = null;
213
+ /** Pre-fill for the Role select (when Scope='Role'). */
214
+ InitialRoleID = undefined;
215
+ /** Pre-fill for the Priority numeric input. Default: 0. */
216
+ InitialPriority = undefined;
217
+ /**
218
+ * When true, render the dialog as "Edit form details" instead of
219
+ * "Activate this form" — same fields, different framing. The
220
+ * confirm button reads "Save changes" and the explanatory hint adapts.
221
+ */
222
+ EditMode = false;
223
+ confirmed = new EventEmitter();
224
+ dismissed = new EventEmitter();
225
+ Name = '';
226
+ Description = null;
227
+ Notes = null;
228
+ Scope = 'User';
229
+ RoleID = null;
230
+ Priority = 0;
231
+ Status = 'Pending';
232
+ validationError = null;
233
+ availableRoles = [];
234
+ cd = inject(ChangeDetectorRef);
235
+ ngOnInit() {
236
+ // Load roles eagerly — small list, used only when Scope='Role'.
237
+ const provider = this.ProviderToUse;
238
+ this.availableRoles = provider?.Roles ?? [];
239
+ }
240
+ /**
241
+ * Re-sync editable state every time `Visible` flips false→true, AFTER
242
+ * Angular has bound all the peer `@Input()`s for the same change-
243
+ * detection cycle. The previous setter-based approach fired BEFORE
244
+ * sibling inputs (`InitialName`, etc.) had landed, leaving the dialog
245
+ * pre-fill empty.
246
+ */
247
+ ngOnChanges(changes) {
248
+ const visChange = changes['Visible'];
249
+ if (!visChange)
250
+ return;
251
+ const becameVisible = !visChange.previousValue && visChange.currentValue;
252
+ if (becameVisible) {
253
+ this.resetFromInputs();
254
+ }
255
+ }
256
+ /**
257
+ * Sync editable state from `@Input()`s. Called on first open AND on
258
+ * every subsequent Visible: false → true transition so the dialog
259
+ * doesn't show stale data from a previous invocation.
260
+ */
261
+ resetFromInputs() {
262
+ this.Name = (this.InitialName?.trim() || this.ComponentName || '').trim();
263
+ this.Description = this.InitialDescription?.trim() || null;
264
+ this.Notes = this.InitialNotes?.trim() || null;
265
+ this.validationError = null;
266
+ // Default Status to Pending — matches the new "create as draft,
267
+ // activate later" workflow. Edit-mode callers will override via
268
+ // InitialStatus.
269
+ if (this.InitialStatus)
270
+ this.Status = this.InitialStatus;
271
+ if (this.InitialScope)
272
+ this.Scope = this.InitialScope;
273
+ if (this.InitialRoleID !== undefined)
274
+ this.RoleID = this.InitialRoleID;
275
+ if (this.InitialPriority !== undefined)
276
+ this.Priority = this.InitialPriority;
277
+ this.cd.markForCheck();
278
+ }
279
+ OnNameInput(e) {
280
+ this.Name = e.target.value;
281
+ }
282
+ OnDescriptionInput(e) {
283
+ const v = e.target.value;
284
+ this.Description = v.trim().length > 0 ? v : null;
285
+ }
286
+ OnNotesInput(e) {
287
+ const v = e.target.value;
288
+ this.Notes = v.trim().length > 0 ? v : null;
289
+ }
290
+ OnScopeChange(scope) {
291
+ this.Scope = scope;
292
+ if (scope !== 'Role') {
293
+ this.RoleID = null;
294
+ }
295
+ }
296
+ OnRoleChanged(e) {
297
+ const v = e.target.value;
298
+ this.RoleID = v.length > 0 ? v : null;
299
+ }
300
+ OnPriorityInput(e) {
301
+ const parsed = parseInt(e.target.value, 10);
302
+ this.Priority = isNaN(parsed) ? 0 : parsed;
303
+ }
304
+ OnConfirmClick() {
305
+ if (!this.Name?.trim()) {
306
+ this.validationError = 'Name is required.';
307
+ return;
308
+ }
309
+ if (!this.EntityName) {
310
+ this.validationError = 'No entity selected. Pick one in the Field Binding inspector before activating.';
311
+ return;
312
+ }
313
+ if (this.Scope === 'Role' && !this.RoleID) {
314
+ this.validationError = 'Pick a role when Scope = Role.';
315
+ return;
316
+ }
317
+ this.validationError = null;
318
+ this.confirmed.emit({
319
+ Name: this.Name.trim(),
320
+ Description: this.Description,
321
+ Notes: this.Notes,
322
+ EntityName: this.EntityName,
323
+ Scope: this.Scope,
324
+ RoleID: this.RoleID,
325
+ Priority: this.Priority,
326
+ Status: this.Status,
327
+ });
328
+ }
329
+ OnCancelClick() {
330
+ this.dismissed.emit();
331
+ }
332
+ static ɵfac = /*@__PURE__*/ (() => { let ɵFormOverrideDialogComponent_BaseFactory; return function FormOverrideDialogComponent_Factory(__ngFactoryType__) { return (ɵFormOverrideDialogComponent_BaseFactory || (ɵFormOverrideDialogComponent_BaseFactory = i0.ɵɵgetInheritedFactory(FormOverrideDialogComponent)))(__ngFactoryType__ || FormOverrideDialogComponent); }; })();
333
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FormOverrideDialogComponent, selectors: [["mj-form-override-dialog"]], inputs: { Visible: "Visible", ComponentName: "ComponentName", EntityName: "EntityName", InitialDescription: "InitialDescription", InitialName: "InitialName", InitialNotes: "InitialNotes", InitialStatus: "InitialStatus", InitialScope: "InitialScope", InitialRoleID: "InitialRoleID", InitialPriority: "InitialPriority", EditMode: "EditMode" }, outputs: { confirmed: "confirmed", dismissed: "dismissed" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 1, vars: 1, consts: [[1, "modal-backdrop"], [1, "modal-backdrop", 3, "click"], [1, "modal", 3, "click"], [1, "modal-header"], ["aria-label", "Close", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "modal-body"], [1, "hint"], [1, "field"], ["type", "text", "placeholder", "e.g. Compact Application Form", 3, "input", "value"], ["rows", "2", "placeholder", "Optional \u2014 what's special about this variant?", 3, "input", "value"], ["rows", "2", "placeholder", "Optional \u2014 private notes about this version, e.g. why you forked, what changed.", 3, "input", "value"], ["type", "text", "disabled", "", 3, "value"], [1, "muted"], [1, "scope-options"], [1, "radio"], ["type", "radio", "name", "scope", 3, "change", "checked"], [1, "role-picker", 3, "value"], [1, "field-row"], ["type", "number", "min", "0", "step", "1", 3, "input", "value"], [1, "status-options"], ["type", "radio", "name", "status", 3, "change", "checked"], [1, "error"], [1, "modal-footer"], [1, "btn", "btn-primary", 3, "click"], [1, "btn", 3, "click"], [1, "role-picker", 3, "change", "value"], ["value", ""], [3, "value"]], template: function FormOverrideDialogComponent_Template(rf, ctx) { if (rf & 1) {
334
+ i0.ɵɵconditionalCreate(0, FormOverrideDialogComponent_Conditional_0_Template, 71, 17, "div", 0);
335
+ } if (rf & 2) {
336
+ i0.ɵɵconditional(ctx.Visible ? 0 : -1);
337
+ } }, dependencies: [CommonModule], styles: [".modal-backdrop[_ngcontent-%COMP%] { position: fixed; inset: 0; background: var(--mj-bg-overlay, rgba(0,0,0,0.5)); display: flex; align-items: center; justify-content: center; z-index: 1000; }\n .modal[_ngcontent-%COMP%] { background: var(--mj-bg-surface, #fff); border-radius: 8px; width: 520px; max-width: 90vw; max-height: 90vh; display: flex; flex-direction: column; box-shadow: 0 8px 32px rgba(0,0,0,0.12); }\n .modal-header[_ngcontent-%COMP%] { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--mj-border-default, #e0e0e0); }\n .modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { margin: 0; font-size: 16px; font-weight: 600; }\n .close-btn[_ngcontent-%COMP%] { background: transparent; border: 0; cursor: pointer; font-size: 16px; color: var(--mj-text-muted, #64748b); padding: 4px; }\n .modal-body[_ngcontent-%COMP%] { padding: 16px 20px; overflow-y: auto; }\n .modal-footer[_ngcontent-%COMP%] { display: flex; gap: 8px; padding: 12px 20px; border-top: 1px solid var(--mj-border-default, #e0e0e0); }\n .hint[_ngcontent-%COMP%] { margin: 0 0 16px; color: var(--mj-text-muted, #64748b); font-size: 13px; line-height: 1.5; }\n .field[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }\n .field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] { font-size: 11px; color: var(--mj-text-muted, #64748b); text-transform: uppercase; letter-spacing: 0.5px; }\n .field[_ngcontent-%COMP%] input[type=\"text\"][_ngcontent-%COMP%], .field[_ngcontent-%COMP%] input[type=\"number\"][_ngcontent-%COMP%], .field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%], .field[_ngcontent-%COMP%] select[_ngcontent-%COMP%] { padding: 8px 10px; border: 1px solid var(--mj-border-default, #e0e0e0); border-radius: 4px; font-size: 14px; background: var(--mj-bg-surface, #fff); color: var(--mj-text-primary, #111); font-family: inherit; }\n .field[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:disabled { background: var(--mj-bg-surface-sunken, #f1f5f9); color: var(--mj-text-muted, #64748b); }\n .field-row[_ngcontent-%COMP%] { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n .muted[_ngcontent-%COMP%] { font-size: 11px; color: var(--mj-text-muted, #64748b); }\n .scope-options[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 8px; }\n .status-options[_ngcontent-%COMP%] { display: flex; gap: 16px; padding-top: 6px; }\n .radio[_ngcontent-%COMP%] { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }\n .role-picker[_ngcontent-%COMP%] { margin-left: 24px; }\n .error[_ngcontent-%COMP%] { color: var(--mj-status-error-text, #b91c1c); background: var(--mj-status-error-bg, #fee2e2); padding: 8px 12px; border-radius: 4px; font-size: 13px; margin-top: 8px; }\n .btn[_ngcontent-%COMP%] { padding: 8px 16px; border: 1px solid var(--mj-border-default, #e0e0e0); border-radius: 4px; background: var(--mj-bg-surface, #fff); color: var(--mj-text-primary, #111); font-size: 14px; cursor: pointer; }\n .btn-primary[_ngcontent-%COMP%] { background: var(--mj-brand-primary, #5B4FE9); color: #fff; border-color: var(--mj-brand-primary, #5B4FE9); font-weight: 500; }"], changeDetection: 0 });
338
+ }
339
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FormOverrideDialogComponent, [{
340
+ type: Component,
341
+ args: [{ standalone: true, imports: [CommonModule], selector: 'mj-form-override-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: `
342
+ @if (Visible) {
343
+ <div class="modal-backdrop" (click)="OnCancelClick()">
344
+ <div class="modal" (click)="$event.stopPropagation()">
345
+ <header class="modal-header">
346
+ <h3>{{ EditMode ? 'Edit form details' : 'Activate this form' }}</h3>
347
+ <button class="close-btn" (click)="OnCancelClick()" aria-label="Close">
348
+ <i class="fa-solid fa-times"></i>
349
+ </button>
350
+ </header>
351
+ <div class="modal-body">
352
+ <p class="hint">
353
+ @if (EditMode) {
354
+ Update the override's name, description, scope, priority, or status.
355
+ Component code is edited from the cockpit's main editor — this dialog
356
+ covers the override-row metadata only.
357
+ } @else {
358
+ Create an Entity Form Override so MemberJunction renders this
359
+ Component instead of the default form for matching users.
360
+ Skip to keep the Component saved but inactive.
361
+ }
362
+ </p>
363
+
364
+ <div class="field">
365
+ <label>Override Name</label>
366
+ <input type="text" [value]="Name" (input)="OnNameInput($event)" placeholder="e.g. Compact Application Form" />
367
+ </div>
368
+
369
+ <div class="field">
370
+ <label>Description</label>
371
+ <textarea [value]="Description ?? ''" (input)="OnDescriptionInput($event)" rows="2"
372
+ placeholder="Optional — what's special about this variant?"></textarea>
373
+ </div>
374
+
375
+ <div class="field">
376
+ <label>Notes</label>
377
+ <textarea [value]="Notes ?? ''" (input)="OnNotesInput($event)" rows="2"
378
+ placeholder="Optional — private notes about this version, e.g. why you forked, what changed."></textarea>
379
+ </div>
380
+
381
+ <div class="field">
382
+ <label>Entity</label>
383
+ <input type="text" [value]="EntityName" disabled />
384
+ <small class="muted">Set in the Field Binding inspector.</small>
385
+ </div>
386
+
387
+ <div class="field">
388
+ <label>Scope</label>
389
+ <div class="scope-options">
390
+ <label class="radio">
391
+ <input type="radio" name="scope" [checked]="Scope === 'User'" (change)="OnScopeChange('User')" />
392
+ Me only (User)
393
+ </label>
394
+ <label class="radio">
395
+ <input type="radio" name="scope" [checked]="Scope === 'Role'" (change)="OnScopeChange('Role')" />
396
+ A role
397
+ </label>
398
+ @if (Scope === 'Role') {
399
+ <select [value]="RoleID ?? ''" (change)="OnRoleChanged($event)" class="role-picker">
400
+ <option value="">— pick a role —</option>
401
+ @for (r of availableRoles; track r.ID) {
402
+ <option [value]="r.ID">{{ r.Name }}</option>
403
+ }
404
+ </select>
405
+ }
406
+ <label class="radio">
407
+ <input type="radio" name="scope" [checked]="Scope === 'Global'" (change)="OnScopeChange('Global')" />
408
+ Everyone (Global)
409
+ </label>
410
+ </div>
411
+ </div>
412
+
413
+ <div class="field-row">
414
+ <div class="field">
415
+ <label>Priority</label>
416
+ <input type="number" [value]="Priority" (input)="OnPriorityInput($event)" min="0" step="1" />
417
+ </div>
418
+
419
+ <div class="field">
420
+ <label>Status</label>
421
+ <div class="status-options">
422
+ <label class="radio">
423
+ <input type="radio" name="status" [checked]="Status === 'Pending'" (change)="Status = 'Pending'" />
424
+ Pending <span class="muted">(draft)</span>
425
+ </label>
426
+ <label class="radio">
427
+ <input type="radio" name="status" [checked]="Status === 'Active'" (change)="Status = 'Active'" />
428
+ Active <span class="muted">(live)</span>
429
+ </label>
430
+ <label class="radio">
431
+ <input type="radio" name="status" [checked]="Status === 'Inactive'" (change)="Status = 'Inactive'" />
432
+ Inactive
433
+ </label>
434
+ </div>
435
+ </div>
436
+ </div>
437
+
438
+ @if (validationError) {
439
+ <div class="error">{{ validationError }}</div>
440
+ }
441
+ </div>
442
+ <footer class="modal-footer">
443
+ <button class="btn btn-primary" (click)="OnConfirmClick()">{{ EditMode ? 'Save changes' : 'Create Override' }}</button>
444
+ <button class="btn" (click)="OnCancelClick()">{{ EditMode ? 'Cancel' : 'Skip' }}</button>
445
+ </footer>
446
+ </div>
447
+ </div>
448
+ }
449
+ `, styles: ["\n .modal-backdrop { position: fixed; inset: 0; background: var(--mj-bg-overlay, rgba(0,0,0,0.5)); display: flex; align-items: center; justify-content: center; z-index: 1000; }\n .modal { background: var(--mj-bg-surface, #fff); border-radius: 8px; width: 520px; max-width: 90vw; max-height: 90vh; display: flex; flex-direction: column; box-shadow: 0 8px 32px rgba(0,0,0,0.12); }\n .modal-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--mj-border-default, #e0e0e0); }\n .modal-header h3 { margin: 0; font-size: 16px; font-weight: 600; }\n .close-btn { background: transparent; border: 0; cursor: pointer; font-size: 16px; color: var(--mj-text-muted, #64748b); padding: 4px; }\n .modal-body { padding: 16px 20px; overflow-y: auto; }\n .modal-footer { display: flex; gap: 8px; padding: 12px 20px; border-top: 1px solid var(--mj-border-default, #e0e0e0); }\n .hint { margin: 0 0 16px; color: var(--mj-text-muted, #64748b); font-size: 13px; line-height: 1.5; }\n .field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }\n .field label { font-size: 11px; color: var(--mj-text-muted, #64748b); text-transform: uppercase; letter-spacing: 0.5px; }\n .field input[type=\"text\"], .field input[type=\"number\"], .field textarea, .field select { padding: 8px 10px; border: 1px solid var(--mj-border-default, #e0e0e0); border-radius: 4px; font-size: 14px; background: var(--mj-bg-surface, #fff); color: var(--mj-text-primary, #111); font-family: inherit; }\n .field input:disabled { background: var(--mj-bg-surface-sunken, #f1f5f9); color: var(--mj-text-muted, #64748b); }\n .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n .muted { font-size: 11px; color: var(--mj-text-muted, #64748b); }\n .scope-options { display: flex; flex-direction: column; gap: 8px; }\n .status-options { display: flex; gap: 16px; padding-top: 6px; }\n .radio { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }\n .role-picker { margin-left: 24px; }\n .error { color: var(--mj-status-error-text, #b91c1c); background: var(--mj-status-error-bg, #fee2e2); padding: 8px 12px; border-radius: 4px; font-size: 13px; margin-top: 8px; }\n .btn { padding: 8px 16px; border: 1px solid var(--mj-border-default, #e0e0e0); border-radius: 4px; background: var(--mj-bg-surface, #fff); color: var(--mj-text-primary, #111); font-size: 14px; cursor: pointer; }\n .btn-primary { background: var(--mj-brand-primary, #5B4FE9); color: #fff; border-color: var(--mj-brand-primary, #5B4FE9); font-weight: 500; }\n "] }]
450
+ }], null, { Visible: [{
451
+ type: Input
452
+ }], ComponentName: [{
453
+ type: Input
454
+ }], EntityName: [{
455
+ type: Input
456
+ }], InitialDescription: [{
457
+ type: Input
458
+ }], InitialName: [{
459
+ type: Input
460
+ }], InitialNotes: [{
461
+ type: Input
462
+ }], InitialStatus: [{
463
+ type: Input
464
+ }], InitialScope: [{
465
+ type: Input
466
+ }], InitialRoleID: [{
467
+ type: Input
468
+ }], InitialPriority: [{
469
+ type: Input
470
+ }], EditMode: [{
471
+ type: Input
472
+ }], confirmed: [{
473
+ type: Output
474
+ }], dismissed: [{
475
+ type: Output
476
+ }] }); })();
477
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FormOverrideDialogComponent, { className: "FormOverrideDialogComponent", filePath: "src/ComponentStudio/components/form-override-dialog.component.ts", lineNumber: 189 }); })();
478
+ //# sourceMappingURL=form-override-dialog.component.js.map