@memberjunction/ng-dashboards 6.2.0-edge.2 → 6.2.0-edge.3

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 (69) hide show
  1. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts +12 -1
  2. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts.map +1 -1
  3. package/dist/ComponentStudio/components/form-override-dialog.component.js +128 -81
  4. package/dist/ComponentStudio/components/form-override-dialog.component.js.map +1 -1
  5. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +4 -0
  6. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  7. package/dist/DataExplorer/data-explorer-dashboard.component.js +47 -13
  8. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  9. package/dist/TelephonyOperations/telephony-operations-agent-context.d.ts +107 -0
  10. package/dist/TelephonyOperations/telephony-operations-agent-context.d.ts.map +1 -0
  11. package/dist/TelephonyOperations/telephony-operations-agent-context.js +216 -0
  12. package/dist/TelephonyOperations/telephony-operations-agent-context.js.map +1 -0
  13. package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts +57 -0
  14. package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts.map +1 -0
  15. package/dist/TelephonyOperations/telephony-operations-dashboard.component.js +805 -0
  16. package/dist/TelephonyOperations/telephony-operations-dashboard.component.js.map +1 -0
  17. package/dist/WorkQueue/components/work-queue-bindings.component.d.ts +37 -0
  18. package/dist/WorkQueue/components/work-queue-bindings.component.d.ts.map +1 -0
  19. package/dist/WorkQueue/components/work-queue-bindings.component.js +210 -0
  20. package/dist/WorkQueue/components/work-queue-bindings.component.js.map +1 -0
  21. package/dist/WorkQueue/components/work-queue-dead-letters.component.d.ts +70 -0
  22. package/dist/WorkQueue/components/work-queue-dead-letters.component.d.ts.map +1 -0
  23. package/dist/WorkQueue/components/work-queue-dead-letters.component.js +496 -0
  24. package/dist/WorkQueue/components/work-queue-dead-letters.component.js.map +1 -0
  25. package/dist/WorkQueue/components/work-queue-discard-dialog.component.d.ts +22 -0
  26. package/dist/WorkQueue/components/work-queue-discard-dialog.component.d.ts.map +1 -0
  27. package/dist/WorkQueue/components/work-queue-discard-dialog.component.js +99 -0
  28. package/dist/WorkQueue/components/work-queue-discard-dialog.component.js.map +1 -0
  29. package/dist/WorkQueue/components/work-queue-overview.component.d.ts +29 -0
  30. package/dist/WorkQueue/components/work-queue-overview.component.d.ts.map +1 -0
  31. package/dist/WorkQueue/components/work-queue-overview.component.js +278 -0
  32. package/dist/WorkQueue/components/work-queue-overview.component.js.map +1 -0
  33. package/dist/WorkQueue/components/work-queue-partitions.component.d.ts +59 -0
  34. package/dist/WorkQueue/components/work-queue-partitions.component.d.ts.map +1 -0
  35. package/dist/WorkQueue/components/work-queue-partitions.component.js +359 -0
  36. package/dist/WorkQueue/components/work-queue-partitions.component.js.map +1 -0
  37. package/dist/WorkQueue/services/work-queue-operator.service.d.ts +22 -0
  38. package/dist/WorkQueue/services/work-queue-operator.service.d.ts.map +1 -0
  39. package/dist/WorkQueue/services/work-queue-operator.service.js +44 -0
  40. package/dist/WorkQueue/services/work-queue-operator.service.js.map +1 -0
  41. package/dist/WorkQueue/work-queue-agent-context.d.ts +67 -0
  42. package/dist/WorkQueue/work-queue-agent-context.d.ts.map +1 -0
  43. package/dist/WorkQueue/work-queue-agent-context.js +119 -0
  44. package/dist/WorkQueue/work-queue-agent-context.js.map +1 -0
  45. package/dist/WorkQueue/work-queue-dashboard.component.d.ts +94 -0
  46. package/dist/WorkQueue/work-queue-dashboard.component.d.ts.map +1 -0
  47. package/dist/WorkQueue/work-queue-dashboard.component.js +545 -0
  48. package/dist/WorkQueue/work-queue-dashboard.component.js.map +1 -0
  49. package/dist/WorkQueue/work-queue-types.d.ts +40 -0
  50. package/dist/WorkQueue/work-queue-types.d.ts.map +1 -0
  51. package/dist/WorkQueue/work-queue-types.js +2 -0
  52. package/dist/WorkQueue/work-queue-types.js.map +1 -0
  53. package/dist/core-dashboards.module.d.ts +29 -28
  54. package/dist/core-dashboards.module.d.ts.map +1 -1
  55. package/dist/core-dashboards.module.js +7 -0
  56. package/dist/core-dashboards.module.js.map +1 -1
  57. package/dist/module.d.ts +14 -13
  58. package/dist/module.d.ts.map +1 -1
  59. package/dist/module.js +7 -0
  60. package/dist/module.js.map +1 -1
  61. package/dist/public-api.d.ts +4 -0
  62. package/dist/public-api.d.ts.map +1 -1
  63. package/dist/public-api.js +6 -0
  64. package/dist/public-api.js.map +1 -1
  65. package/dist/work-queue-dashboards.module.d.ts +23 -0
  66. package/dist/work-queue-dashboards.module.d.ts.map +1 -0
  67. package/dist/work-queue-dashboards.module.js +92 -0
  68. package/dist/work-queue-dashboards.module.js.map +1 -0
  69. package/package.json +72 -66
@@ -100,6 +100,16 @@ export declare class FormOverrideDialogComponent extends BaseAngularComponent im
100
100
  get availableRoles(): RoleInfo[];
101
101
  /** @deprecated Use {@link AvailableRoles}. */
102
102
  set availableRoles(value: RoleInfo[]);
103
+ /**
104
+ * Whether this user may show a form to a role or to everyone. Read once each time the dialog
105
+ * opens.
106
+ *
107
+ * Decides only what the dialog offers. The server-side entity subclass enforces the same rule
108
+ * on the save, so a dialog that offered it anyway would still have the write refused.
109
+ */
110
+ CanPublish: boolean;
111
+ /** The current audience in words, for a user who cannot change it. */
112
+ get ScopeLabel(): string;
103
113
  private readonly cd;
104
114
  ngOnInit(): void;
105
115
  /**
@@ -113,7 +123,8 @@ export declare class FormOverrideDialogComponent extends BaseAngularComponent im
113
123
  /**
114
124
  * Sync editable state from `@Input()`s. Called on first open AND on
115
125
  * every subsequent Visible: false → true transition so the dialog
116
- * doesn't show stale data from a previous invocation.
126
+ * doesn't show stale data from a previous invocation. An Initial* input
127
+ * left unset gives its default: Pending, Me only with no role, priority 0.
117
128
  */
118
129
  private resetFromInputs;
119
130
  OnNameInput(e: Event): void;
@@ -1 +1 @@
1
- {"version":3,"file":"form-override-dialog.component.d.ts","sourceRoot":"","sources":["../../../src/ComponentStudio/components/form-override-dialog.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"form-override-dialog.component.d.ts","sourceRoot":"","sources":["../../../src/ComponentStudio/components/form-override-dialog.component.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, inject, } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
4
+ import { UUIDsEqual } from '@memberjunction/global';
5
+ import { UserCanManageFormDefaults } from '@memberjunction/core-entities';
4
6
  import * as i0 from "@angular/core";
5
7
  const _forTrack0 = ($index, $item) => $item.ID;
6
8
  function FormOverrideDialogComponent_Conditional_0_Conditional_9_Template(rf, ctx) { if (rf & 1) {
@@ -9,33 +11,74 @@ function FormOverrideDialogComponent_Conditional_0_Conditional_9_Template(rf, ct
9
11
  function FormOverrideDialogComponent_Conditional_0_Conditional_10_Template(rf, ctx) { if (rf & 1) {
10
12
  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
13
  } }
12
- function FormOverrideDialogComponent_Conditional_0_Conditional_39_For_4_Template(rf, ctx) { if (rf & 1) {
13
- i0.ɵɵdomElementStart(0, "option", 28);
14
+ function FormOverrideDialogComponent_Conditional_0_Conditional_32_Template(rf, ctx) { if (rf & 1) {
15
+ i0.ɵɵdomElementStart(0, "p", 24);
14
16
  i0.ɵɵtext(1);
15
17
  i0.ɵɵdomElementEnd();
18
+ i0.ɵɵdomElementStart(2, "small", 13);
19
+ i0.ɵɵtext(3, " Showing a form to a role or to everyone needs the Manage Form Defaults authorization. ");
20
+ i0.ɵɵdomElementEnd();
16
21
  } if (rf & 2) {
17
- const r_r4 = ctx.$implicit;
18
- i0.ɵɵdomProperty("value", r_r4.ID);
22
+ const ctx_r1 = i0.ɵɵnextContext(2);
19
23
  i0.ɵɵadvance();
20
- i0.ɵɵtextInterpolate(r_r4.Name);
24
+ i0.ɵɵtextInterpolate(ctx_r1.ScopeLabel);
21
25
  } }
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);
26
+ function FormOverrideDialogComponent_Conditional_0_Conditional_33_Conditional_7_For_4_Template(rf, ctx) { if (rf & 1) {
27
+ i0.ɵɵdomElementStart(0, "option", 29);
28
+ i0.ɵɵtext(1);
29
+ i0.ɵɵdomElementEnd();
30
+ } if (rf & 2) {
31
+ const r_r5 = ctx.$implicit;
32
+ i0.ɵɵdomProperty("value", r_r5.ID);
33
+ i0.ɵɵadvance();
34
+ i0.ɵɵtextInterpolate(r_r5.Name);
35
+ } }
36
+ function FormOverrideDialogComponent_Conditional_0_Conditional_33_Conditional_7_Template(rf, ctx) { if (rf & 1) {
37
+ const _r4 = i0.ɵɵgetCurrentView();
38
+ i0.ɵɵdomElementStart(0, "select", 27);
39
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Conditional_33_Conditional_7_Template_select_change_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnRoleChanged($event)); });
40
+ i0.ɵɵdomElementStart(1, "option", 28);
27
41
  i0.ɵɵtext(2, "\u2014 pick a role \u2014");
28
42
  i0.ɵɵdomElementEnd();
29
- i0.ɵɵrepeaterCreate(3, FormOverrideDialogComponent_Conditional_0_Conditional_39_For_4_Template, 2, 2, "option", 28, _forTrack0);
43
+ i0.ɵɵrepeaterCreate(3, FormOverrideDialogComponent_Conditional_0_Conditional_33_Conditional_7_For_4_Template, 2, 2, "option", 29, _forTrack0);
30
44
  i0.ɵɵdomElementEnd();
31
45
  } if (rf & 2) {
32
- const ctx_r1 = i0.ɵɵnextContext(2);
46
+ const ctx_r1 = i0.ɵɵnextContext(3);
33
47
  i0.ɵɵdomProperty("value", ctx_r1.RoleID ?? "");
34
48
  i0.ɵɵadvance(3);
35
49
  i0.ɵɵrepeater(ctx_r1.availableRoles);
36
50
  } }
37
- function FormOverrideDialogComponent_Conditional_0_Conditional_65_Template(rf, ctx) { if (rf & 1) {
38
- i0.ɵɵdomElementStart(0, "div", 22);
51
+ function FormOverrideDialogComponent_Conditional_0_Conditional_33_Template(rf, ctx) { if (rf & 1) {
52
+ const _r3 = i0.ɵɵgetCurrentView();
53
+ i0.ɵɵdomElementStart(0, "div", 14)(1, "label", 18)(2, "input", 25);
54
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Conditional_33_Template_input_change_2_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnScopeChange("User")); });
55
+ i0.ɵɵdomElementEnd();
56
+ i0.ɵɵtext(3, " Me only (User) ");
57
+ i0.ɵɵdomElementEnd();
58
+ i0.ɵɵdomElementStart(4, "label", 18)(5, "input", 25);
59
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Conditional_33_Template_input_change_5_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnScopeChange("Role")); });
60
+ i0.ɵɵdomElementEnd();
61
+ i0.ɵɵtext(6, " A role ");
62
+ i0.ɵɵdomElementEnd();
63
+ i0.ɵɵconditionalCreate(7, FormOverrideDialogComponent_Conditional_0_Conditional_33_Conditional_7_Template, 5, 1, "select", 26);
64
+ i0.ɵɵdomElementStart(8, "label", 18)(9, "input", 25);
65
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Conditional_33_Template_input_change_9_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnScopeChange("Global")); });
66
+ i0.ɵɵdomElementEnd();
67
+ i0.ɵɵtext(10, " Everyone (Global) ");
68
+ i0.ɵɵdomElementEnd()();
69
+ } if (rf & 2) {
70
+ const ctx_r1 = i0.ɵɵnextContext(2);
71
+ i0.ɵɵadvance(2);
72
+ i0.ɵɵdomProperty("checked", ctx_r1.Scope === "User");
73
+ i0.ɵɵadvance(3);
74
+ i0.ɵɵdomProperty("checked", ctx_r1.Scope === "Role");
75
+ i0.ɵɵadvance(2);
76
+ i0.ɵɵconditional(ctx_r1.Scope === "Role" ? 7 : -1);
77
+ i0.ɵɵadvance(2);
78
+ i0.ɵɵdomProperty("checked", ctx_r1.Scope === "Global");
79
+ } }
80
+ function FormOverrideDialogComponent_Conditional_0_Conditional_56_Template(rf, ctx) { if (rf & 1) {
81
+ i0.ɵɵdomElementStart(0, "div", 20);
39
82
  i0.ɵɵtext(1);
40
83
  i0.ɵɵdomElementEnd();
41
84
  } if (rf & 2) {
@@ -87,59 +130,45 @@ function FormOverrideDialogComponent_Conditional_0_Template(rf, ctx) { if (rf &
87
130
  i0.ɵɵdomElementStart(29, "div", 8)(30, "label");
88
131
  i0.ɵɵtext(31, "Scope");
89
132
  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 ");
133
+ i0.ɵɵconditionalCreate(32, FormOverrideDialogComponent_Conditional_0_Conditional_32_Template, 4, 1)(33, FormOverrideDialogComponent_Conditional_0_Conditional_33_Template, 11, 4, "div", 14);
99
134
  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")); });
135
+ i0.ɵɵdomElementStart(34, "div", 15)(35, "div", 8)(36, "label");
136
+ i0.ɵɵtext(37, "Priority");
103
137
  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)); });
138
+ i0.ɵɵdomElementStart(38, "input", 16);
139
+ i0.ɵɵdomListener("input", function FormOverrideDialogComponent_Conditional_0_Template_input_input_38_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnPriorityInput($event)); });
111
140
  i0.ɵɵdomElementEnd()();
112
- i0.ɵɵdomElementStart(48, "div", 8)(49, "label");
113
- i0.ɵɵtext(50, "Status");
141
+ i0.ɵɵdomElementStart(39, "div", 8)(40, "label");
142
+ i0.ɵɵtext(41, "Status");
114
143
  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"); });
144
+ i0.ɵɵdomElementStart(42, "div", 17)(43, "label", 18)(44, "input", 19);
145
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Template_input_change_44_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Status = "Pending"); });
117
146
  i0.ɵɵdomElementEnd();
118
- i0.ɵɵtext(54, " Pending ");
119
- i0.ɵɵdomElementStart(55, "span", 13);
120
- i0.ɵɵtext(56, "(draft)");
147
+ i0.ɵɵtext(45, " Pending ");
148
+ i0.ɵɵdomElementStart(46, "span", 13);
149
+ i0.ɵɵtext(47, "(draft)");
121
150
  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"); });
151
+ i0.ɵɵdomElementStart(48, "label", 18)(49, "input", 19);
152
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Template_input_change_49_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Status = "Active"); });
124
153
  i0.ɵɵdomElementEnd();
125
- i0.ɵɵtext(59, " Active ");
126
- i0.ɵɵdomElementStart(60, "span", 13);
127
- i0.ɵɵtext(61, "(live)");
154
+ i0.ɵɵtext(50, " Active ");
155
+ i0.ɵɵdomElementStart(51, "span", 13);
156
+ i0.ɵɵtext(52, "(live)");
128
157
  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"); });
158
+ i0.ɵɵdomElementStart(53, "label", 18)(54, "input", 19);
159
+ i0.ɵɵdomListener("change", function FormOverrideDialogComponent_Conditional_0_Template_input_change_54_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Status = "Inactive"); });
131
160
  i0.ɵɵdomElementEnd();
132
- i0.ɵɵtext(64, " Inactive ");
161
+ i0.ɵɵtext(55, " Inactive ");
133
162
  i0.ɵɵdomElementEnd()()()();
134
- i0.ɵɵconditionalCreate(65, FormOverrideDialogComponent_Conditional_0_Conditional_65_Template, 2, 1, "div", 22);
163
+ i0.ɵɵconditionalCreate(56, FormOverrideDialogComponent_Conditional_0_Conditional_56_Template, 2, 1, "div", 20);
135
164
  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);
165
+ i0.ɵɵdomElementStart(57, "footer", 21)(58, "button", 22);
166
+ i0.ɵɵdomListener("click", function FormOverrideDialogComponent_Conditional_0_Template_button_click_58_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnConfirmClick()); });
167
+ i0.ɵɵtext(59);
139
168
  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);
169
+ i0.ɵɵdomElementStart(60, "button", 23);
170
+ i0.ɵɵdomListener("click", function FormOverrideDialogComponent_Conditional_0_Template_button_click_60_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnCancelClick()); });
171
+ i0.ɵɵtext(61);
143
172
  i0.ɵɵdomElementEnd()()()();
144
173
  } if (rf & 2) {
145
174
  const ctx_r1 = i0.ɵɵnextContext();
@@ -155,14 +184,8 @@ function FormOverrideDialogComponent_Conditional_0_Template(rf, ctx) { if (rf &
155
184
  i0.ɵɵdomProperty("value", ctx_r1.Notes ?? "");
156
185
  i0.ɵɵadvance(4);
157
186
  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");
187
+ i0.ɵɵadvance(6);
188
+ i0.ɵɵconditional(!ctx_r1.CanPublish ? 32 : 33);
166
189
  i0.ɵɵadvance(6);
167
190
  i0.ɵɵdomProperty("value", ctx_r1.Priority);
168
191
  i0.ɵɵadvance(6);
@@ -172,7 +195,7 @@ function FormOverrideDialogComponent_Conditional_0_Template(rf, ctx) { if (rf &
172
195
  i0.ɵɵadvance(5);
173
196
  i0.ɵɵdomProperty("checked", ctx_r1.Status === "Inactive");
174
197
  i0.ɵɵadvance(2);
175
- i0.ɵɵconditional(ctx_r1.validationError ? 65 : -1);
198
+ i0.ɵɵconditional(ctx_r1.validationError ? 56 : -1);
176
199
  i0.ɵɵadvance(3);
177
200
  i0.ɵɵtextInterpolate(ctx_r1.EditMode ? "Save changes" : "Create Override");
178
201
  i0.ɵɵadvance(2);
@@ -263,6 +286,24 @@ export class FormOverrideDialogComponent extends BaseAngularComponent {
263
286
  set availableRoles(value) {
264
287
  this.AvailableRoles = value;
265
288
  }
289
+ /**
290
+ * Whether this user may show a form to a role or to everyone. Read once each time the dialog
291
+ * opens.
292
+ *
293
+ * Decides only what the dialog offers. The server-side entity subclass enforces the same rule
294
+ * on the save, so a dialog that offered it anyway would still have the write refused.
295
+ */
296
+ CanPublish = false;
297
+ /** The current audience in words, for a user who cannot change it. */
298
+ get ScopeLabel() {
299
+ if (this.Scope === 'Global')
300
+ return 'Everyone';
301
+ if (this.Scope === 'Role') {
302
+ const role = this.availableRoles.find((r) => UUIDsEqual(r.ID, this.RoleID))?.Name;
303
+ return role ? `${role} role` : 'A role';
304
+ }
305
+ return 'Me only';
306
+ }
266
307
  cd = inject(ChangeDetectorRef);
267
308
  ngOnInit() {
268
309
  // Load roles eagerly — small list, used only when Scope='Role'.
@@ -288,24 +329,20 @@ export class FormOverrideDialogComponent extends BaseAngularComponent {
288
329
  /**
289
330
  * Sync editable state from `@Input()`s. Called on first open AND on
290
331
  * every subsequent Visible: false → true transition so the dialog
291
- * doesn't show stale data from a previous invocation.
332
+ * doesn't show stale data from a previous invocation. An Initial* input
333
+ * left unset gives its default: Pending, Me only with no role, priority 0.
292
334
  */
293
335
  resetFromInputs() {
294
336
  this.Name = (this.InitialName?.trim() || this.ComponentName || '').trim();
295
337
  this.Description = this.InitialDescription?.trim() || null;
296
338
  this.Notes = this.InitialNotes?.trim() || null;
297
339
  this.ValidationError = null;
298
- // Default Status to Pending — matches the new "create as draft,
299
- // activate later" workflow. Edit-mode callers will override via
300
- // InitialStatus.
301
- if (this.InitialStatus)
302
- this.Status = this.InitialStatus;
303
- if (this.InitialScope)
304
- this.Scope = this.InitialScope;
305
- if (this.InitialRoleID !== undefined)
306
- this.RoleID = this.InitialRoleID;
307
- if (this.InitialPriority !== undefined)
308
- this.Priority = this.InitialPriority;
340
+ this.Status = this.InitialStatus ?? 'Pending';
341
+ this.Scope = this.InitialScope ?? 'User';
342
+ this.RoleID = this.Scope === 'Role' ? (this.InitialRoleID ?? null) : null;
343
+ this.Priority = this.InitialPriority ?? 0;
344
+ const provider = this.ProviderToUse;
345
+ this.CanPublish = UserCanManageFormDefaults(provider?.CurrentUser, provider);
309
346
  this.cd.markForCheck();
310
347
  }
311
348
  OnNameInput(e) {
@@ -362,11 +399,11 @@ export class FormOverrideDialogComponent extends BaseAngularComponent {
362
399
  this.Dismissed.emit();
363
400
  }
364
401
  static ɵfac = /*@__PURE__*/ (() => { let ɵFormOverrideDialogComponent_BaseFactory; return function FormOverrideDialogComponent_Factory(__ngFactoryType__) { return (ɵFormOverrideDialogComponent_BaseFactory || (ɵFormOverrideDialogComponent_BaseFactory = i0.ɵɵgetInheritedFactory(FormOverrideDialogComponent)))(__ngFactoryType__ || FormOverrideDialogComponent); }; })();
365
- 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", confirmed: "confirmed", Dismissed: "Dismissed", 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) {
366
- i0.ɵɵconditionalCreate(0, FormOverrideDialogComponent_Conditional_0_Template, 71, 17, "div", 0);
402
+ 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", confirmed: "confirmed", Dismissed: "Dismissed", 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, "field-row"], ["type", "number", "min", "0", "step", "1", 3, "input", "value"], [1, "status-options"], [1, "radio"], ["type", "radio", "name", "status", 3, "change", "checked"], [1, "error"], [1, "modal-footer"], [1, "btn", "btn-primary", 3, "click"], [1, "btn", 3, "click"], [1, "scope-readonly"], ["type", "radio", "name", "scope", 3, "change", "checked"], [1, "role-picker", 3, "value"], [1, "role-picker", 3, "change", "value"], ["value", ""], [3, "value"]], template: function FormOverrideDialogComponent_Template(rf, ctx) { if (rf & 1) {
403
+ i0.ɵɵconditionalCreate(0, FormOverrideDialogComponent_Conditional_0_Template, 62, 14, "div", 0);
367
404
  } if (rf & 2) {
368
405
  i0.ɵɵconditional(ctx.Visible ? 0 : -1);
369
- } }, 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 });
406
+ } }, 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 .scope-readonly[_ngcontent-%COMP%] { margin: 0; font-size: 13px; }\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 });
370
407
  }
371
408
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FormOverrideDialogComponent, [{
372
409
  type: Component,
@@ -418,6 +455,15 @@ export class FormOverrideDialogComponent extends BaseAngularComponent {
418
455
 
419
456
  <div class="field">
420
457
  <label>Scope</label>
458
+ @if (!CanPublish) {
459
+ <!-- Choosing who else sees a form is a grant, not a default. Without it the
460
+ audience is shown, not offered, so there is no control that would fail. -->
461
+ <p class="scope-readonly">{{ ScopeLabel }}</p>
462
+ <small class="muted">
463
+ Showing a form to a role or to everyone needs the Manage Form Defaults
464
+ authorization.
465
+ </small>
466
+ } @else {
421
467
  <div class="scope-options">
422
468
  <label class="radio">
423
469
  <input type="radio" name="scope" [checked]="Scope === 'User'" (change)="OnScopeChange('User')" />
@@ -440,6 +486,7 @@ export class FormOverrideDialogComponent extends BaseAngularComponent {
440
486
  Everyone (Global)
441
487
  </label>
442
488
  </div>
489
+ }
443
490
  </div>
444
491
 
445
492
  <div class="field-row">
@@ -478,7 +525,7 @@ export class FormOverrideDialogComponent extends BaseAngularComponent {
478
525
  </div>
479
526
  </div>
480
527
  }
481
- `, 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 "] }]
528
+ `, 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 .scope-readonly { margin: 0; font-size: 13px; }\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 "] }]
482
529
  }], null, { Visible: [{
483
530
  type: Input
484
531
  }], ComponentName: [{
@@ -510,5 +557,5 @@ export class FormOverrideDialogComponent extends BaseAngularComponent {
510
557
  }], dismissed: [{
511
558
  type: Output
512
559
  }] }); })();
513
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FormOverrideDialogComponent, { className: "FormOverrideDialogComponent", filePath: "src/ComponentStudio/components/form-override-dialog.component.ts", lineNumber: 189 }); })();
560
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FormOverrideDialogComponent, { className: "FormOverrideDialogComponent", filePath: "src/ComponentStudio/components/form-override-dialog.component.ts", lineNumber: 202 }); })();
514
561
  //# sourceMappingURL=form-override-dialog.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"form-override-dialog.component.js","sourceRoot":"","sources":["../../../src/ComponentStudio/components/form-override-dialog.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n OnInit,\n OnChanges,\n SimpleChanges,\n inject,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { RoleInfo } from '@memberjunction/core';\n\n/**\n * Scope of an EntityFormOverride row. Mirrors the DB CHECK constraint\n * (see migrations/v5/V202605161430_*_Interactive_Forms.sql).\n */\nexport type OverrideScope = 'User' | 'Role' | 'Global';\n\n/**\n * Override row status. Active = runtime serves this; Pending = AI / user\n * draft awaiting activation; Inactive = historical, never served.\n */\nexport type OverrideStatus = 'Active' | 'Inactive' | 'Pending';\n\n/** Payload emitted by {@link FormOverrideDialogComponent} on confirm. */\nexport interface FormOverrideDialogResult {\n Name: string;\n Description: string | null;\n Notes: string | null;\n EntityName: string;\n Scope: OverrideScope;\n RoleID: string | null;\n Priority: number;\n Status: OverrideStatus;\n}\n\n/**\n * Modal shown after a form-role Component is saved. Lets the author create\n * an `EntityFormOverride` row pointing the just-saved Component at an\n * entity for User / Role / Global scope. Skip exits without persisting —\n * useful when authoring a Component that isn't ready to be activated.\n *\n * The dialog only collects intent. The dashboard wires the confirm event\n * to the write call (currently blocked on the EntityFormOverrideEntity\n * generated class; see Tasks 3 + 15).\n */\n@Component({\n standalone: true,\n imports: [CommonModule],\n selector: 'mj-form-override-dialog',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n@if (Visible) {\n<div class=\"modal-backdrop\" (click)=\"OnCancelClick()\">\n <div class=\"modal\" (click)=\"$event.stopPropagation()\">\n <header class=\"modal-header\">\n <h3>{{ EditMode ? 'Edit form details' : 'Activate this form' }}</h3>\n <button class=\"close-btn\" (click)=\"OnCancelClick()\" aria-label=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </header>\n <div class=\"modal-body\">\n <p class=\"hint\">\n @if (EditMode) {\n Update the override's name, description, scope, priority, or status.\n Component code is edited from the cockpit's main editor — this dialog\n covers the override-row metadata only.\n } @else {\n Create an Entity Form Override so MemberJunction renders this\n Component instead of the default form for matching users.\n Skip to keep the Component saved but inactive.\n }\n </p>\n\n <div class=\"field\">\n <label>Override Name</label>\n <input type=\"text\" [value]=\"Name\" (input)=\"OnNameInput($event)\" placeholder=\"e.g. Compact Application Form\" />\n </div>\n\n <div class=\"field\">\n <label>Description</label>\n <textarea [value]=\"Description ?? ''\" (input)=\"OnDescriptionInput($event)\" rows=\"2\"\n placeholder=\"Optional — what's special about this variant?\"></textarea>\n </div>\n\n <div class=\"field\">\n <label>Notes</label>\n <textarea [value]=\"Notes ?? ''\" (input)=\"OnNotesInput($event)\" rows=\"2\"\n placeholder=\"Optional — private notes about this version, e.g. why you forked, what changed.\"></textarea>\n </div>\n\n <div class=\"field\">\n <label>Entity</label>\n <input type=\"text\" [value]=\"EntityName\" disabled />\n <small class=\"muted\">Set in the Field Binding inspector.</small>\n </div>\n\n <div class=\"field\">\n <label>Scope</label>\n <div class=\"scope-options\">\n <label class=\"radio\">\n <input type=\"radio\" name=\"scope\" [checked]=\"Scope === 'User'\" (change)=\"OnScopeChange('User')\" />\n Me only (User)\n </label>\n <label class=\"radio\">\n <input type=\"radio\" name=\"scope\" [checked]=\"Scope === 'Role'\" (change)=\"OnScopeChange('Role')\" />\n A role\n </label>\n @if (Scope === 'Role') {\n <select [value]=\"RoleID ?? ''\" (change)=\"OnRoleChanged($event)\" class=\"role-picker\">\n <option value=\"\">— pick a role —</option>\n @for (r of availableRoles; track r.ID) {\n <option [value]=\"r.ID\">{{ r.Name }}</option>\n }\n </select>\n }\n <label class=\"radio\">\n <input type=\"radio\" name=\"scope\" [checked]=\"Scope === 'Global'\" (change)=\"OnScopeChange('Global')\" />\n Everyone (Global)\n </label>\n </div>\n </div>\n\n <div class=\"field-row\">\n <div class=\"field\">\n <label>Priority</label>\n <input type=\"number\" [value]=\"Priority\" (input)=\"OnPriorityInput($event)\" min=\"0\" step=\"1\" />\n </div>\n\n <div class=\"field\">\n <label>Status</label>\n <div class=\"status-options\">\n <label class=\"radio\">\n <input type=\"radio\" name=\"status\" [checked]=\"Status === 'Pending'\" (change)=\"Status = 'Pending'\" />\n Pending <span class=\"muted\">(draft)</span>\n </label>\n <label class=\"radio\">\n <input type=\"radio\" name=\"status\" [checked]=\"Status === 'Active'\" (change)=\"Status = 'Active'\" />\n Active <span class=\"muted\">(live)</span>\n </label>\n <label class=\"radio\">\n <input type=\"radio\" name=\"status\" [checked]=\"Status === 'Inactive'\" (change)=\"Status = 'Inactive'\" />\n Inactive\n </label>\n </div>\n </div>\n </div>\n\n @if (validationError) {\n <div class=\"error\">{{ validationError }}</div>\n }\n </div>\n <footer class=\"modal-footer\">\n <button class=\"btn btn-primary\" (click)=\"OnConfirmClick()\">{{ EditMode ? 'Save changes' : 'Create Override' }}</button>\n <button class=\"btn\" (click)=\"OnCancelClick()\">{{ EditMode ? 'Cancel' : 'Skip' }}</button>\n </footer>\n </div>\n</div>\n}\n`,\n 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 `],\n})\nexport class FormOverrideDialogComponent extends BaseAngularComponent implements OnInit, OnChanges {\n\n /**\n * Plain `@Input()`. Per-open re-sync of editable state happens in\n * `ngOnChanges` — that's the only Angular hook that fires AFTER all\n * inputs in a single change-detection cycle are bound. The earlier\n * setter-based approach fired BEFORE peer inputs (`InitialName`,\n * `InitialDescription`, etc.) were set, so the dialog rendered with\n * stale or empty pre-fill values.\n */\n @Input() Visible = false;\n\n @Input() ComponentName = '';\n @Input() EntityName = '';\n /** Pre-fill for the Description textarea (cockpit's input value). */\n @Input() InitialDescription: string | null = null;\n /** Pre-fill for the Name input (defaults to ComponentName). */\n @Input() InitialName: string | null = null;\n /** Pre-fill for the Notes textarea (when present in the cockpit). */\n @Input() InitialNotes: string | null = null;\n /** Pre-fill for the Status radio group. Default: 'Pending'. */\n @Input() InitialStatus: OverrideStatus | null = null;\n /** Pre-fill for the Scope radio group. Default: 'User'. */\n @Input() InitialScope: OverrideScope | null = null;\n /** Pre-fill for the Role select (when Scope='Role'). */\n @Input() InitialRoleID: string | null | undefined = undefined;\n /** Pre-fill for the Priority numeric input. Default: 0. */\n @Input() InitialPriority: number | undefined = undefined;\n /**\n * When true, render the dialog as \"Edit form details\" instead of\n * \"Activate this form\" — same fields, different framing. The\n * confirm button reads \"Save changes\" and the explanatory hint adapts.\n */\n @Input() EditMode = false;\n\n @Output() Confirmed = new EventEmitter<FormOverrideDialogResult>();\n\n /**\n * @deprecated Use {@link Confirmed}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (confirmed) keeps working. Must stay AFTER Confirmed: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() confirmed = this.Confirmed;\n @Output() Dismissed = new EventEmitter<void>();\n\n /**\n * @deprecated Use {@link Dismissed}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (dismissed) keeps working. Must stay AFTER Dismissed: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() dismissed = this.Dismissed;\n\n public Name = '';\n public Description: string | null = null;\n public Notes: string | null = null;\n public Scope: OverrideScope = 'User';\n public RoleID: string | null = null;\n public Priority = 0;\n public Status: OverrideStatus = 'Pending';\n public ValidationError: string | null = null;\n\n /** @deprecated Use {@link ValidationError}. */\n public get validationError(): string | null {\n return this.ValidationError;\n }\n /** @deprecated Use {@link ValidationError}. */\n public set validationError(value: string | null) {\n this.ValidationError = value;\n }\n\n public AvailableRoles: RoleInfo[] = [];\n\n /** @deprecated Use {@link AvailableRoles}. */\n public get availableRoles(): RoleInfo[] {\n return this.AvailableRoles;\n }\n /** @deprecated Use {@link AvailableRoles}. */\n public set availableRoles(value: RoleInfo[]) {\n this.AvailableRoles = value;\n }\n\n private readonly cd = inject(ChangeDetectorRef);\n\n ngOnInit(): void {\n // Load roles eagerly — small list, used only when Scope='Role'.\n const provider = this.ProviderToUse;\n this.AvailableRoles = provider?.Roles ?? [];\n }\n\n /**\n * Re-sync editable state every time `Visible` flips false→true, AFTER\n * Angular has bound all the peer `@Input()`s for the same change-\n * detection cycle. The previous setter-based approach fired BEFORE\n * sibling inputs (`InitialName`, etc.) had landed, leaving the dialog\n * pre-fill empty.\n */\n ngOnChanges(changes: SimpleChanges): void {\n const visChange = changes['Visible'];\n if (!visChange) return;\n const becameVisible = !visChange.previousValue && visChange.currentValue;\n if (becameVisible) {\n this.resetFromInputs();\n }\n }\n\n /**\n * Sync editable state from `@Input()`s. Called on first open AND on\n * every subsequent Visible: false → true transition so the dialog\n * doesn't show stale data from a previous invocation.\n */\n private resetFromInputs(): void {\n this.Name = (this.InitialName?.trim() || this.ComponentName || '').trim();\n this.Description = this.InitialDescription?.trim() || null;\n this.Notes = this.InitialNotes?.trim() || null;\n this.ValidationError = null;\n // Default Status to Pending — matches the new \"create as draft,\n // activate later\" workflow. Edit-mode callers will override via\n // InitialStatus.\n if (this.InitialStatus) this.Status = this.InitialStatus;\n if (this.InitialScope) this.Scope = this.InitialScope;\n if (this.InitialRoleID !== undefined) this.RoleID = this.InitialRoleID;\n if (this.InitialPriority !== undefined) this.Priority = this.InitialPriority;\n this.cd.markForCheck();\n }\n\n public OnNameInput(e: Event): void {\n this.Name = (e.target as HTMLInputElement).value;\n }\n\n public OnDescriptionInput(e: Event): void {\n const v = (e.target as HTMLTextAreaElement).value;\n this.Description = v.trim().length > 0 ? v : null;\n }\n\n public OnNotesInput(e: Event): void {\n const v = (e.target as HTMLTextAreaElement).value;\n this.Notes = v.trim().length > 0 ? v : null;\n }\n\n public OnScopeChange(scope: OverrideScope): void {\n this.Scope = scope;\n if (scope !== 'Role') {\n this.RoleID = null;\n }\n }\n\n public OnRoleChanged(e: Event): void {\n const v = (e.target as HTMLSelectElement).value;\n this.RoleID = v.length > 0 ? v : null;\n }\n\n public OnPriorityInput(e: Event): void {\n const parsed = parseInt((e.target as HTMLInputElement).value, 10);\n this.Priority = isNaN(parsed) ? 0 : parsed;\n }\n\n public OnConfirmClick(): void {\n if (!this.Name?.trim()) {\n this.ValidationError = 'Name is required.';\n return;\n }\n if (!this.EntityName) {\n this.ValidationError = 'No entity selected. Pick one in the Field Binding inspector before activating.';\n return;\n }\n if (this.Scope === 'Role' && !this.RoleID) {\n this.ValidationError = 'Pick a role when Scope = Role.';\n return;\n }\n this.ValidationError = null;\n this.Confirmed.emit({\n Name: this.Name.trim(),\n Description: this.Description,\n Notes: this.Notes,\n EntityName: this.EntityName,\n Scope: this.Scope,\n RoleID: this.RoleID,\n Priority: this.Priority,\n Status: this.Status,\n });\n }\n\n public OnCancelClick(): void {\n this.Dismissed.emit();\n }\n}\n"]}
1
+ {"version":3,"file":"form-override-dialog.component.js","sourceRoot":"","sources":["../../../src/ComponentStudio/components/form-override-dialog.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n OnInit,\n OnChanges,\n SimpleChanges,\n inject,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { RoleInfo } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { UserCanManageFormDefaults } from '@memberjunction/core-entities';\n\n/**\n * Scope of an EntityFormOverride row. Mirrors the DB CHECK constraint\n * (see migrations/v5/V202605161430_*_Interactive_Forms.sql).\n */\nexport type OverrideScope = 'User' | 'Role' | 'Global';\n\n/**\n * Override row status. Active = runtime serves this; Pending = AI / user\n * draft awaiting activation; Inactive = historical, never served.\n */\nexport type OverrideStatus = 'Active' | 'Inactive' | 'Pending';\n\n/** Payload emitted by {@link FormOverrideDialogComponent} on confirm. */\nexport interface FormOverrideDialogResult {\n Name: string;\n Description: string | null;\n Notes: string | null;\n EntityName: string;\n Scope: OverrideScope;\n RoleID: string | null;\n Priority: number;\n Status: OverrideStatus;\n}\n\n/**\n * Modal shown after a form-role Component is saved. Lets the author create\n * an `EntityFormOverride` row pointing the just-saved Component at an\n * entity for User / Role / Global scope. Skip exits without persisting —\n * useful when authoring a Component that isn't ready to be activated.\n *\n * The dialog only collects intent. The dashboard wires the confirm event\n * to the write call (currently blocked on the EntityFormOverrideEntity\n * generated class; see Tasks 3 + 15).\n */\n@Component({\n standalone: true,\n imports: [CommonModule],\n selector: 'mj-form-override-dialog',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n@if (Visible) {\n<div class=\"modal-backdrop\" (click)=\"OnCancelClick()\">\n <div class=\"modal\" (click)=\"$event.stopPropagation()\">\n <header class=\"modal-header\">\n <h3>{{ EditMode ? 'Edit form details' : 'Activate this form' }}</h3>\n <button class=\"close-btn\" (click)=\"OnCancelClick()\" aria-label=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </header>\n <div class=\"modal-body\">\n <p class=\"hint\">\n @if (EditMode) {\n Update the override's name, description, scope, priority, or status.\n Component code is edited from the cockpit's main editor — this dialog\n covers the override-row metadata only.\n } @else {\n Create an Entity Form Override so MemberJunction renders this\n Component instead of the default form for matching users.\n Skip to keep the Component saved but inactive.\n }\n </p>\n\n <div class=\"field\">\n <label>Override Name</label>\n <input type=\"text\" [value]=\"Name\" (input)=\"OnNameInput($event)\" placeholder=\"e.g. Compact Application Form\" />\n </div>\n\n <div class=\"field\">\n <label>Description</label>\n <textarea [value]=\"Description ?? ''\" (input)=\"OnDescriptionInput($event)\" rows=\"2\"\n placeholder=\"Optional — what's special about this variant?\"></textarea>\n </div>\n\n <div class=\"field\">\n <label>Notes</label>\n <textarea [value]=\"Notes ?? ''\" (input)=\"OnNotesInput($event)\" rows=\"2\"\n placeholder=\"Optional — private notes about this version, e.g. why you forked, what changed.\"></textarea>\n </div>\n\n <div class=\"field\">\n <label>Entity</label>\n <input type=\"text\" [value]=\"EntityName\" disabled />\n <small class=\"muted\">Set in the Field Binding inspector.</small>\n </div>\n\n <div class=\"field\">\n <label>Scope</label>\n @if (!CanPublish) {\n <!-- Choosing who else sees a form is a grant, not a default. Without it the\n audience is shown, not offered, so there is no control that would fail. -->\n <p class=\"scope-readonly\">{{ ScopeLabel }}</p>\n <small class=\"muted\">\n Showing a form to a role or to everyone needs the Manage Form Defaults\n authorization.\n </small>\n } @else {\n <div class=\"scope-options\">\n <label class=\"radio\">\n <input type=\"radio\" name=\"scope\" [checked]=\"Scope === 'User'\" (change)=\"OnScopeChange('User')\" />\n Me only (User)\n </label>\n <label class=\"radio\">\n <input type=\"radio\" name=\"scope\" [checked]=\"Scope === 'Role'\" (change)=\"OnScopeChange('Role')\" />\n A role\n </label>\n @if (Scope === 'Role') {\n <select [value]=\"RoleID ?? ''\" (change)=\"OnRoleChanged($event)\" class=\"role-picker\">\n <option value=\"\">— pick a role —</option>\n @for (r of availableRoles; track r.ID) {\n <option [value]=\"r.ID\">{{ r.Name }}</option>\n }\n </select>\n }\n <label class=\"radio\">\n <input type=\"radio\" name=\"scope\" [checked]=\"Scope === 'Global'\" (change)=\"OnScopeChange('Global')\" />\n Everyone (Global)\n </label>\n </div>\n }\n </div>\n\n <div class=\"field-row\">\n <div class=\"field\">\n <label>Priority</label>\n <input type=\"number\" [value]=\"Priority\" (input)=\"OnPriorityInput($event)\" min=\"0\" step=\"1\" />\n </div>\n\n <div class=\"field\">\n <label>Status</label>\n <div class=\"status-options\">\n <label class=\"radio\">\n <input type=\"radio\" name=\"status\" [checked]=\"Status === 'Pending'\" (change)=\"Status = 'Pending'\" />\n Pending <span class=\"muted\">(draft)</span>\n </label>\n <label class=\"radio\">\n <input type=\"radio\" name=\"status\" [checked]=\"Status === 'Active'\" (change)=\"Status = 'Active'\" />\n Active <span class=\"muted\">(live)</span>\n </label>\n <label class=\"radio\">\n <input type=\"radio\" name=\"status\" [checked]=\"Status === 'Inactive'\" (change)=\"Status = 'Inactive'\" />\n Inactive\n </label>\n </div>\n </div>\n </div>\n\n @if (validationError) {\n <div class=\"error\">{{ validationError }}</div>\n }\n </div>\n <footer class=\"modal-footer\">\n <button class=\"btn btn-primary\" (click)=\"OnConfirmClick()\">{{ EditMode ? 'Save changes' : 'Create Override' }}</button>\n <button class=\"btn\" (click)=\"OnCancelClick()\">{{ EditMode ? 'Cancel' : 'Skip' }}</button>\n </footer>\n </div>\n</div>\n}\n`,\n 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 .scope-readonly { margin: 0; font-size: 13px; }\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 `],\n})\nexport class FormOverrideDialogComponent extends BaseAngularComponent implements OnInit, OnChanges {\n\n /**\n * Plain `@Input()`. Per-open re-sync of editable state happens in\n * `ngOnChanges` — that's the only Angular hook that fires AFTER all\n * inputs in a single change-detection cycle are bound. The earlier\n * setter-based approach fired BEFORE peer inputs (`InitialName`,\n * `InitialDescription`, etc.) were set, so the dialog rendered with\n * stale or empty pre-fill values.\n */\n @Input() Visible = false;\n\n @Input() ComponentName = '';\n @Input() EntityName = '';\n /** Pre-fill for the Description textarea (cockpit's input value). */\n @Input() InitialDescription: string | null = null;\n /** Pre-fill for the Name input (defaults to ComponentName). */\n @Input() InitialName: string | null = null;\n /** Pre-fill for the Notes textarea (when present in the cockpit). */\n @Input() InitialNotes: string | null = null;\n /** Pre-fill for the Status radio group. Default: 'Pending'. */\n @Input() InitialStatus: OverrideStatus | null = null;\n /** Pre-fill for the Scope radio group. Default: 'User'. */\n @Input() InitialScope: OverrideScope | null = null;\n /** Pre-fill for the Role select (when Scope='Role'). */\n @Input() InitialRoleID: string | null | undefined = undefined;\n /** Pre-fill for the Priority numeric input. Default: 0. */\n @Input() InitialPriority: number | undefined = undefined;\n /**\n * When true, render the dialog as \"Edit form details\" instead of\n * \"Activate this form\" — same fields, different framing. The\n * confirm button reads \"Save changes\" and the explanatory hint adapts.\n */\n @Input() EditMode = false;\n\n @Output() Confirmed = new EventEmitter<FormOverrideDialogResult>();\n\n /**\n * @deprecated Use {@link Confirmed}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (confirmed) keeps working. Must stay AFTER Confirmed: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() confirmed = this.Confirmed;\n @Output() Dismissed = new EventEmitter<void>();\n\n /**\n * @deprecated Use {@link Dismissed}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (dismissed) keeps working. Must stay AFTER Dismissed: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() dismissed = this.Dismissed;\n\n public Name = '';\n public Description: string | null = null;\n public Notes: string | null = null;\n public Scope: OverrideScope = 'User';\n public RoleID: string | null = null;\n public Priority = 0;\n public Status: OverrideStatus = 'Pending';\n public ValidationError: string | null = null;\n\n /** @deprecated Use {@link ValidationError}. */\n public get validationError(): string | null {\n return this.ValidationError;\n }\n /** @deprecated Use {@link ValidationError}. */\n public set validationError(value: string | null) {\n this.ValidationError = value;\n }\n\n public AvailableRoles: RoleInfo[] = [];\n\n /** @deprecated Use {@link AvailableRoles}. */\n public get availableRoles(): RoleInfo[] {\n return this.AvailableRoles;\n }\n /** @deprecated Use {@link AvailableRoles}. */\n public set availableRoles(value: RoleInfo[]) {\n this.AvailableRoles = value;\n }\n\n /**\n * Whether this user may show a form to a role or to everyone. Read once each time the dialog\n * opens.\n *\n * Decides only what the dialog offers. The server-side entity subclass enforces the same rule\n * on the save, so a dialog that offered it anyway would still have the write refused.\n */\n public CanPublish = false;\n\n /** The current audience in words, for a user who cannot change it. */\n public get ScopeLabel(): string {\n if (this.Scope === 'Global') return 'Everyone';\n if (this.Scope === 'Role') {\n const role = this.availableRoles.find((r) => UUIDsEqual(r.ID, this.RoleID))?.Name;\n return role ? `${role} role` : 'A role';\n }\n return 'Me only';\n }\n\n private readonly cd = inject(ChangeDetectorRef);\n\n ngOnInit(): void {\n // Load roles eagerly — small list, used only when Scope='Role'.\n const provider = this.ProviderToUse;\n this.AvailableRoles = provider?.Roles ?? [];\n }\n\n /**\n * Re-sync editable state every time `Visible` flips false→true, AFTER\n * Angular has bound all the peer `@Input()`s for the same change-\n * detection cycle. The previous setter-based approach fired BEFORE\n * sibling inputs (`InitialName`, etc.) had landed, leaving the dialog\n * pre-fill empty.\n */\n ngOnChanges(changes: SimpleChanges): void {\n const visChange = changes['Visible'];\n if (!visChange) return;\n const becameVisible = !visChange.previousValue && visChange.currentValue;\n if (becameVisible) {\n this.resetFromInputs();\n }\n }\n\n /**\n * Sync editable state from `@Input()`s. Called on first open AND on\n * every subsequent Visible: false → true transition so the dialog\n * doesn't show stale data from a previous invocation. An Initial* input\n * left unset gives its default: Pending, Me only with no role, priority 0.\n */\n private resetFromInputs(): void {\n this.Name = (this.InitialName?.trim() || this.ComponentName || '').trim();\n this.Description = this.InitialDescription?.trim() || null;\n this.Notes = this.InitialNotes?.trim() || null;\n this.ValidationError = null;\n this.Status = this.InitialStatus ?? 'Pending';\n this.Scope = this.InitialScope ?? 'User';\n this.RoleID = this.Scope === 'Role' ? (this.InitialRoleID ?? null) : null;\n this.Priority = this.InitialPriority ?? 0;\n const provider = this.ProviderToUse;\n this.CanPublish = UserCanManageFormDefaults(provider?.CurrentUser, provider);\n this.cd.markForCheck();\n }\n\n public OnNameInput(e: Event): void {\n this.Name = (e.target as HTMLInputElement).value;\n }\n\n public OnDescriptionInput(e: Event): void {\n const v = (e.target as HTMLTextAreaElement).value;\n this.Description = v.trim().length > 0 ? v : null;\n }\n\n public OnNotesInput(e: Event): void {\n const v = (e.target as HTMLTextAreaElement).value;\n this.Notes = v.trim().length > 0 ? v : null;\n }\n\n public OnScopeChange(scope: OverrideScope): void {\n this.Scope = scope;\n if (scope !== 'Role') {\n this.RoleID = null;\n }\n }\n\n public OnRoleChanged(e: Event): void {\n const v = (e.target as HTMLSelectElement).value;\n this.RoleID = v.length > 0 ? v : null;\n }\n\n public OnPriorityInput(e: Event): void {\n const parsed = parseInt((e.target as HTMLInputElement).value, 10);\n this.Priority = isNaN(parsed) ? 0 : parsed;\n }\n\n public OnConfirmClick(): void {\n if (!this.Name?.trim()) {\n this.ValidationError = 'Name is required.';\n return;\n }\n if (!this.EntityName) {\n this.ValidationError = 'No entity selected. Pick one in the Field Binding inspector before activating.';\n return;\n }\n if (this.Scope === 'Role' && !this.RoleID) {\n this.ValidationError = 'Pick a role when Scope = Role.';\n return;\n }\n this.ValidationError = null;\n this.Confirmed.emit({\n Name: this.Name.trim(),\n Description: this.Description,\n Notes: this.Notes,\n EntityName: this.EntityName,\n Scope: this.Scope,\n RoleID: this.RoleID,\n Priority: this.Priority,\n Status: this.Status,\n });\n }\n\n public OnCancelClick(): void {\n this.Dismissed.emit();\n }\n}\n"]}
@@ -811,6 +811,10 @@ export declare class DataExplorerDashboardComponent extends BaseDashboard implem
811
811
  * Used both during init and for popstate handling.
812
812
  */
813
813
  private applyUrlState;
814
+ /** Whether `viewId` (absent = the default view) is the view currently selected. */
815
+ private isSelectedView;
816
+ /** Whether `recordKey` (concatenated or compact URL form) is the record shown in the detail panel. */
817
+ private isSelectedRecord;
814
818
  /**
815
819
  * Restore a saved view from the URL's viewId parameter.
816
820
  * Looks up the view by ID and sets it as selected; the workspace applies its grid state once