@memberjunction/ng-list-management 5.34.1 → 5.36.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 (63) hide show
  1. package/README.md +179 -85
  2. package/dist/lib/components/audience-source-picker/audience-source-picker.component.d.ts +74 -0
  3. package/dist/lib/components/audience-source-picker/audience-source-picker.component.d.ts.map +1 -0
  4. package/dist/lib/components/audience-source-picker/audience-source-picker.component.js +396 -0
  5. package/dist/lib/components/audience-source-picker/audience-source-picker.component.js.map +1 -0
  6. package/dist/lib/components/audience-source-summary/audience-source-summary.component.d.ts +34 -0
  7. package/dist/lib/components/audience-source-summary/audience-source-summary.component.d.ts.map +1 -0
  8. package/dist/lib/components/audience-source-summary/audience-source-summary.component.js +136 -0
  9. package/dist/lib/components/audience-source-summary/audience-source-summary.component.js.map +1 -0
  10. package/dist/lib/components/list-audit-log/list-audit-log.component.d.ts +55 -0
  11. package/dist/lib/components/list-audit-log/list-audit-log.component.d.ts.map +1 -0
  12. package/dist/lib/components/list-audit-log/list-audit-log.component.js +280 -0
  13. package/dist/lib/components/list-audit-log/list-audit-log.component.js.map +1 -0
  14. package/dist/lib/components/list-delta-confirm/list-delta-confirm.component.d.ts +64 -0
  15. package/dist/lib/components/list-delta-confirm/list-delta-confirm.component.d.ts.map +1 -0
  16. package/dist/lib/components/list-delta-confirm/list-delta-confirm.component.js +323 -0
  17. package/dist/lib/components/list-delta-confirm/list-delta-confirm.component.js.map +1 -0
  18. package/dist/lib/components/list-invitations/list-invitations.component.d.ts +60 -0
  19. package/dist/lib/components/list-invitations/list-invitations.component.d.ts.map +1 -0
  20. package/dist/lib/components/list-invitations/list-invitations.component.js +367 -0
  21. package/dist/lib/components/list-invitations/list-invitations.component.js.map +1 -0
  22. package/dist/lib/components/list-management-dialog/list-management-dialog.component.d.ts.map +1 -1
  23. package/dist/lib/components/list-management-dialog/list-management-dialog.component.js +0 -4
  24. package/dist/lib/components/list-management-dialog/list-management-dialog.component.js.map +1 -1
  25. package/dist/lib/components/list-share-dialog/list-share-dialog.component.d.ts +18 -1
  26. package/dist/lib/components/list-share-dialog/list-share-dialog.component.d.ts.map +1 -1
  27. package/dist/lib/components/list-share-dialog/list-share-dialog.component.js +115 -66
  28. package/dist/lib/components/list-share-dialog/list-share-dialog.component.js.map +1 -1
  29. package/dist/lib/components/list-stats/list-stats.component.d.ts +52 -0
  30. package/dist/lib/components/list-stats/list-stats.component.d.ts.map +1 -0
  31. package/dist/lib/components/list-stats/list-stats.component.js +283 -0
  32. package/dist/lib/components/list-stats/list-stats.component.js.map +1 -0
  33. package/dist/lib/components/save-view-as-list-dialog/save-view-as-list-dialog.component.d.ts +68 -0
  34. package/dist/lib/components/save-view-as-list-dialog/save-view-as-list-dialog.component.d.ts.map +1 -0
  35. package/dist/lib/components/save-view-as-list-dialog/save-view-as-list-dialog.component.js +316 -0
  36. package/dist/lib/components/save-view-as-list-dialog/save-view-as-list-dialog.component.js.map +1 -0
  37. package/dist/lib/components/shared-with-me/shared-with-me.component.d.ts +47 -0
  38. package/dist/lib/components/shared-with-me/shared-with-me.component.d.ts.map +1 -0
  39. package/dist/lib/components/shared-with-me/shared-with-me.component.js +231 -0
  40. package/dist/lib/components/shared-with-me/shared-with-me.component.js.map +1 -0
  41. package/dist/lib/components/tag-chips/tag-chips.component.d.ts +85 -0
  42. package/dist/lib/components/tag-chips/tag-chips.component.d.ts.map +1 -0
  43. package/dist/lib/components/tag-chips/tag-chips.component.js +392 -0
  44. package/dist/lib/components/tag-chips/tag-chips.component.js.map +1 -0
  45. package/dist/lib/models/list-sharing.models.d.ts +5 -0
  46. package/dist/lib/models/list-sharing.models.d.ts.map +1 -1
  47. package/dist/lib/models/list-sharing.models.js.map +1 -1
  48. package/dist/lib/module.d.ts +17 -8
  49. package/dist/lib/module.d.ts.map +1 -1
  50. package/dist/lib/module.js +51 -6
  51. package/dist/lib/module.js.map +1 -1
  52. package/dist/lib/services/list-management.service.d.ts.map +1 -1
  53. package/dist/lib/services/list-management.service.js +0 -9
  54. package/dist/lib/services/list-management.service.js.map +1 -1
  55. package/dist/lib/services/list-sharing.service.d.ts +8 -3
  56. package/dist/lib/services/list-sharing.service.d.ts.map +1 -1
  57. package/dist/lib/services/list-sharing.service.js +33 -15
  58. package/dist/lib/services/list-sharing.service.js.map +1 -1
  59. package/dist/public-api.d.ts +9 -0
  60. package/dist/public-api.d.ts.map +1 -1
  61. package/dist/public-api.js +9 -0
  62. package/dist/public-api.js.map +1 -1
  63. package/package.json +13 -11
@@ -0,0 +1,323 @@
1
+ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@memberjunction/ng-ui-components";
4
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_3_Template(rf, ctx) { if (rf & 1) {
5
+ i0.ɵɵtext(0, " Refreshing ");
6
+ i0.ɵɵelementStart(1, "strong");
7
+ i0.ɵɵtext(2);
8
+ i0.ɵɵelementEnd();
9
+ i0.ɵɵtext(3, " will reconcile against the source. Records that are no longer present in the source will be removed. ");
10
+ } if (rf & 2) {
11
+ const ctx_r1 = i0.ɵɵnextContext(2);
12
+ i0.ɵɵadvance(2);
13
+ i0.ɵɵtextInterpolate(ctx_r1.targetDisplayName);
14
+ } }
15
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_4_Template(rf, ctx) { if (rf & 1) {
16
+ i0.ɵɵtext(0, " You're about to apply this change to ");
17
+ i0.ɵɵelementStart(1, "strong");
18
+ i0.ɵɵtext(2);
19
+ i0.ɵɵelementEnd();
20
+ i0.ɵɵtext(3, ". ");
21
+ } if (rf & 2) {
22
+ const ctx_r1 = i0.ɵɵnextContext(2);
23
+ i0.ɵɵadvance(2);
24
+ i0.ɵɵtextInterpolate(ctx_r1.targetDisplayName);
25
+ } }
26
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_21_Template(rf, ctx) { if (rf & 1) {
27
+ i0.ɵɵelementStart(0, "div", 10);
28
+ i0.ɵɵelement(1, "i", 16);
29
+ i0.ɵɵelementStart(2, "span");
30
+ i0.ɵɵtext(3, "Safe operation \u2014 no records will be removed from the list.");
31
+ i0.ɵɵelementEnd()();
32
+ } }
33
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_22_Conditional_6_Template(rf, ctx) { if (rf & 1) {
34
+ i0.ɵɵtext(0, " These records are members today but are no longer matched by the source ");
35
+ i0.ɵɵelementStart(1, "em");
36
+ i0.ɵɵtext(2);
37
+ i0.ɵɵelementEnd();
38
+ i0.ɵɵtext(3, ". ");
39
+ } if (rf & 2) {
40
+ const ctx_r1 = i0.ɵɵnextContext(3);
41
+ i0.ɵɵadvance(2);
42
+ i0.ɵɵtextInterpolate1("\"", ctx_r1.SourceLabel, "\"");
43
+ } }
44
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_22_Conditional_7_Template(rf, ctx) { if (rf & 1) {
45
+ i0.ɵɵtext(0, " These records are members today but are no longer matched by the configured source. ");
46
+ } }
47
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_22_Template(rf, ctx) { if (rf & 1) {
48
+ const _r3 = i0.ɵɵgetCurrentView();
49
+ i0.ɵɵelementStart(0, "div", 11);
50
+ i0.ɵɵelement(1, "i", 17);
51
+ i0.ɵɵelementStart(2, "div", 18)(3, "div")(4, "strong");
52
+ i0.ɵɵtext(5);
53
+ i0.ɵɵelementEnd();
54
+ i0.ɵɵconditionalCreate(6, ListDeltaConfirmComponent_Conditional_0_Conditional_22_Conditional_6_Template, 4, 1)(7, ListDeltaConfirmComponent_Conditional_0_Conditional_22_Conditional_7_Template, 1, 0);
55
+ i0.ɵɵelementEnd();
56
+ i0.ɵɵelementStart(8, "label", 19)(9, "input", 20);
57
+ i0.ɵɵlistener("change", function ListDeltaConfirmComponent_Conditional_0_Conditional_22_Template_input_change_9_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnAcknowledgementToggle($event.target.checked)); });
58
+ i0.ɵɵelementEnd();
59
+ i0.ɵɵelementStart(10, "span");
60
+ i0.ɵɵtext(11);
61
+ i0.ɵɵelementEnd()()()();
62
+ } if (rf & 2) {
63
+ const ctx_r1 = i0.ɵɵnextContext(2);
64
+ i0.ɵɵadvance(5);
65
+ i0.ɵɵtextInterpolate1("", ctx_r1.Delta.Counts.Remove, " record(s) will be removed from this list.");
66
+ i0.ɵɵadvance();
67
+ i0.ɵɵconditional(ctx_r1.SourceLabel ? 6 : 7);
68
+ i0.ɵɵadvance(3);
69
+ i0.ɵɵproperty("checked", ctx_r1.dropAcknowledged);
70
+ i0.ɵɵadvance(2);
71
+ i0.ɵɵtextInterpolate1("I understand ", ctx_r1.Delta.Counts.Remove, " record(s) will be removed");
72
+ } }
73
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_23_For_4_Template(rf, ctx) { if (rf & 1) {
74
+ i0.ɵɵelementStart(0, "li", 23);
75
+ i0.ɵɵelement(1, "i", 24);
76
+ i0.ɵɵelementStart(2, "span", 25);
77
+ i0.ɵɵtext(3);
78
+ i0.ɵɵelementEnd()();
79
+ } if (rf & 2) {
80
+ const id_r4 = ctx.$implicit;
81
+ i0.ɵɵadvance(3);
82
+ i0.ɵɵtextInterpolate(id_r4);
83
+ } }
84
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_23_Template(rf, ctx) { if (rf & 1) {
85
+ i0.ɵɵelementStart(0, "div", 21);
86
+ i0.ɵɵtext(1);
87
+ i0.ɵɵelementEnd();
88
+ i0.ɵɵelementStart(2, "ul", 22);
89
+ i0.ɵɵrepeaterCreate(3, ListDeltaConfirmComponent_Conditional_0_Conditional_23_For_4_Template, 4, 1, "li", 23, i0.ɵɵrepeaterTrackByIdentity);
90
+ i0.ɵɵelementEnd();
91
+ } if (rf & 2) {
92
+ const ctx_r1 = i0.ɵɵnextContext(2);
93
+ i0.ɵɵadvance();
94
+ i0.ɵɵtextInterpolate2(" Preview \u2014 records being added (first ", ctx_r1.previewAdds.length, " of ", ctx_r1.Delta.Counts.Add, ") ");
95
+ i0.ɵɵadvance(2);
96
+ i0.ɵɵrepeater(ctx_r1.previewAdds);
97
+ } }
98
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_24_For_4_Template(rf, ctx) { if (rf & 1) {
99
+ i0.ɵɵelementStart(0, "li", 26);
100
+ i0.ɵɵelement(1, "i", 29);
101
+ i0.ɵɵelementStart(2, "span", 25);
102
+ i0.ɵɵtext(3);
103
+ i0.ɵɵelementEnd()();
104
+ } if (rf & 2) {
105
+ const id_r5 = ctx.$implicit;
106
+ i0.ɵɵadvance(3);
107
+ i0.ɵɵtextInterpolate(id_r5);
108
+ } }
109
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_24_Template(rf, ctx) { if (rf & 1) {
110
+ i0.ɵɵelementStart(0, "div", 21);
111
+ i0.ɵɵtext(1);
112
+ i0.ɵɵelementEnd();
113
+ i0.ɵɵelementStart(2, "ul", 22);
114
+ i0.ɵɵrepeaterCreate(3, ListDeltaConfirmComponent_Conditional_0_Conditional_24_For_4_Template, 4, 1, "li", 26, i0.ɵɵrepeaterTrackByIdentity);
115
+ i0.ɵɵelementEnd();
116
+ i0.ɵɵelementStart(5, "div", 27);
117
+ i0.ɵɵelement(6, "i", 28);
118
+ i0.ɵɵtext(7, " Removed records are logged in the audit log and can be re-added manually if needed. ");
119
+ i0.ɵɵelementEnd();
120
+ } if (rf & 2) {
121
+ const ctx_r1 = i0.ɵɵnextContext(2);
122
+ i0.ɵɵadvance();
123
+ i0.ɵɵtextInterpolate2(" Preview \u2014 records being removed (first ", ctx_r1.previewRemoves.length, " of ", ctx_r1.Delta.Counts.Remove, ") ");
124
+ i0.ɵɵadvance(2);
125
+ i0.ɵɵrepeater(ctx_r1.previewRemoves);
126
+ } }
127
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_32_Template(rf, ctx) { if (rf & 1) {
128
+ i0.ɵɵtext(0, " Confirm button unlocks after acknowledgement ");
129
+ } }
130
+ function ListDeltaConfirmComponent_Conditional_0_Conditional_33_Template(rf, ctx) { if (rf & 1) {
131
+ i0.ɵɵtext(0, " Delta token valid for 5 min ");
132
+ } }
133
+ function ListDeltaConfirmComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
134
+ const _r1 = i0.ɵɵgetCurrentView();
135
+ i0.ɵɵelementStart(0, "mj-dialog", 1);
136
+ i0.ɵɵlistener("Close", function ListDeltaConfirmComponent_Conditional_0_Template_mj_dialog_Close_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnCancel()); });
137
+ i0.ɵɵelementStart(1, "div", 2)(2, "div", 3);
138
+ i0.ɵɵconditionalCreate(3, ListDeltaConfirmComponent_Conditional_0_Conditional_3_Template, 4, 1)(4, ListDeltaConfirmComponent_Conditional_0_Conditional_4_Template, 4, 1);
139
+ i0.ɵɵelementEnd();
140
+ i0.ɵɵelementStart(5, "div", 4)(6, "div", 5)(7, "div", 6);
141
+ i0.ɵɵtext(8);
142
+ i0.ɵɵelementEnd();
143
+ i0.ɵɵelementStart(9, "div", 7);
144
+ i0.ɵɵtext(10, "To Add");
145
+ i0.ɵɵelementEnd()();
146
+ i0.ɵɵelementStart(11, "div", 8)(12, "div", 6);
147
+ i0.ɵɵtext(13);
148
+ i0.ɵɵelementEnd();
149
+ i0.ɵɵelementStart(14, "div", 7);
150
+ i0.ɵɵtext(15, "Unchanged");
151
+ i0.ɵɵelementEnd()();
152
+ i0.ɵɵelementStart(16, "div", 9)(17, "div", 6);
153
+ i0.ɵɵtext(18);
154
+ i0.ɵɵelementEnd();
155
+ i0.ɵɵelementStart(19, "div", 7);
156
+ i0.ɵɵtext(20, "To Remove");
157
+ i0.ɵɵelementEnd()()();
158
+ i0.ɵɵconditionalCreate(21, ListDeltaConfirmComponent_Conditional_0_Conditional_21_Template, 4, 0, "div", 10)(22, ListDeltaConfirmComponent_Conditional_0_Conditional_22_Template, 12, 4, "div", 11);
159
+ i0.ɵɵconditionalCreate(23, ListDeltaConfirmComponent_Conditional_0_Conditional_23_Template, 5, 2);
160
+ i0.ɵɵconditionalCreate(24, ListDeltaConfirmComponent_Conditional_0_Conditional_24_Template, 8, 2);
161
+ i0.ɵɵelementEnd();
162
+ i0.ɵɵelementStart(25, "mj-dialog-actions")(26, "button", 12);
163
+ i0.ɵɵlistener("click", function ListDeltaConfirmComponent_Conditional_0_Template_button_click_26_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnConfirm()); });
164
+ i0.ɵɵelement(27, "i", 13);
165
+ i0.ɵɵtext(28);
166
+ i0.ɵɵelementEnd();
167
+ i0.ɵɵelementStart(29, "button", 14);
168
+ i0.ɵɵlistener("click", function ListDeltaConfirmComponent_Conditional_0_Template_button_click_29_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnCancel()); });
169
+ i0.ɵɵtext(30, "Cancel");
170
+ i0.ɵɵelementEnd();
171
+ i0.ɵɵelementStart(31, "span", 15);
172
+ i0.ɵɵconditionalCreate(32, ListDeltaConfirmComponent_Conditional_0_Conditional_32_Template, 1, 0)(33, ListDeltaConfirmComponent_Conditional_0_Conditional_33_Template, 1, 0);
173
+ i0.ɵɵelementEnd()()();
174
+ } if (rf & 2) {
175
+ const ctx_r1 = i0.ɵɵnextContext();
176
+ i0.ɵɵproperty("Visible", true)("Width", 720)("Title", ctx_r1.hasDrops ? "Confirm List Update \u2014 Records Will Be Removed" : "Confirm List Update");
177
+ i0.ɵɵadvance();
178
+ i0.ɵɵclassProp("delta-confirm-body--danger", ctx_r1.hasDrops);
179
+ i0.ɵɵadvance(2);
180
+ i0.ɵɵconditional(ctx_r1.hasDrops ? 3 : 4);
181
+ i0.ɵɵadvance(5);
182
+ i0.ɵɵtextInterpolate1("+", ctx_r1.Delta.Counts.Add);
183
+ i0.ɵɵadvance(5);
184
+ i0.ɵɵtextInterpolate(ctx_r1.Delta.Counts.Unchanged);
185
+ i0.ɵɵadvance(3);
186
+ i0.ɵɵclassProp("delta-tile--remove", ctx_r1.hasDrops)("delta-tile--remove-empty", !ctx_r1.hasDrops);
187
+ i0.ɵɵadvance(2);
188
+ i0.ɵɵtextInterpolate2("", ctx_r1.hasDrops ? "\u2212" : "", "", ctx_r1.Delta.Counts.Remove);
189
+ i0.ɵɵadvance(3);
190
+ i0.ɵɵconditional(!ctx_r1.hasDrops ? 21 : 22);
191
+ i0.ɵɵadvance(2);
192
+ i0.ɵɵconditional(ctx_r1.previewAdds.length > 0 ? 23 : -1);
193
+ i0.ɵɵadvance();
194
+ i0.ɵɵconditional(ctx_r1.previewRemoves.length > 0 ? 24 : -1);
195
+ i0.ɵɵadvance(2);
196
+ i0.ɵɵproperty("variant", ctx_r1.hasDrops ? "danger" : "primary")("disabled", !ctx_r1.canConfirm);
197
+ i0.ɵɵadvance(2);
198
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.confirmButtonLabel, " ");
199
+ i0.ɵɵadvance(4);
200
+ i0.ɵɵconditional(ctx_r1.hasDrops && !ctx_r1.dropAcknowledged ? 32 : 33);
201
+ } }
202
+ /**
203
+ * Confirmation dialog for any list operation that produced a `ListDelta`
204
+ * preview. This is the **only** UI path that emits a valid `DeltaToken`
205
+ * onward to `applyListDelta` — every mutating list flow funnels through
206
+ * here.
207
+ *
208
+ * Two visual states:
209
+ *
210
+ * - **Safe** (`Delta.Counts.Remove === 0`): green confirmation banner; the
211
+ * primary button is enabled immediately.
212
+ * - **Drop-warning** (`Delta.Counts.Remove > 0`): red header + warning
213
+ * banner; the primary button stays disabled until the user checks the
214
+ * acknowledgement box. The server still rejects with `DROP_NOT_CONFIRMED`
215
+ * if `ConfirmDrops` is false — this UI gate is a convenience, not the
216
+ * source of truth.
217
+ */
218
+ export class ListDeltaConfirmComponent {
219
+ /**
220
+ * Whether the dialog is rendered. Bound via the same getter/setter
221
+ * pattern used by the sibling share dialog so consumers can drive
222
+ * visibility from a parent state machine.
223
+ */
224
+ get Visible() {
225
+ return this._visible;
226
+ }
227
+ set Visible(value) {
228
+ if (this._visible !== value) {
229
+ this._visible = value;
230
+ // Reset the acknowledgement when re-opening so a previous session's
231
+ // confirmation doesn't carry over to a new delta.
232
+ if (value)
233
+ this.dropAcknowledged = false;
234
+ }
235
+ }
236
+ _visible = false;
237
+ /** The delta to confirm. Required — the component renders nothing useful without it. */
238
+ Delta = null;
239
+ /**
240
+ * Human-readable name of the target list. Optional; the dialog falls
241
+ * back to "this list" if not provided.
242
+ */
243
+ TargetListName = null;
244
+ /**
245
+ * Optional descriptor of the source for display ("Q4 Donor View", etc.).
246
+ * Has no functional effect — purely for the warning copy.
247
+ */
248
+ SourceLabel = null;
249
+ /**
250
+ * How many preview records to render in the "first N of …" lists.
251
+ * Larger deltas could otherwise blow up the DOM.
252
+ */
253
+ PreviewLimit = 5;
254
+ /** Fires when the user confirms — payload is the validated delta token. */
255
+ Confirm = new EventEmitter();
256
+ /** Fires when the user cancels (close button, ESC, or Cancel button). */
257
+ Cancel = new EventEmitter();
258
+ /** Local UI state for the acknowledgement checkbox in drop-warning mode. */
259
+ dropAcknowledged = false;
260
+ get hasDrops() {
261
+ return (this.Delta?.Counts.Remove ?? 0) > 0;
262
+ }
263
+ get canConfirm() {
264
+ if (!this.Delta)
265
+ return false;
266
+ if (!this.hasDrops)
267
+ return true;
268
+ return this.dropAcknowledged;
269
+ }
270
+ get previewAdds() {
271
+ return this.Delta?.ToAdd.slice(0, this.PreviewLimit) ?? [];
272
+ }
273
+ get previewRemoves() {
274
+ return this.Delta?.ToRemove.slice(0, this.PreviewLimit) ?? [];
275
+ }
276
+ get confirmButtonLabel() {
277
+ if (!this.Delta)
278
+ return 'Confirm';
279
+ if (this.hasDrops)
280
+ return `Confirm Removal & Update`;
281
+ return `Confirm (Add ${this.Delta.Counts.Add})`;
282
+ }
283
+ get targetDisplayName() {
284
+ return this.TargetListName ?? 'this list';
285
+ }
286
+ OnConfirm() {
287
+ if (!this.canConfirm || !this.Delta)
288
+ return;
289
+ this.Confirm.emit(this.Delta.DeltaToken);
290
+ }
291
+ OnCancel() {
292
+ this.Cancel.emit();
293
+ }
294
+ OnAcknowledgementToggle(value) {
295
+ this.dropAcknowledged = value;
296
+ }
297
+ static ɵfac = function ListDeltaConfirmComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ListDeltaConfirmComponent)(); };
298
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ListDeltaConfirmComponent, selectors: [["mj-list-delta-confirm"]], inputs: { Visible: "Visible", Delta: "Delta", TargetListName: "TargetListName", SourceLabel: "SourceLabel", PreviewLimit: "PreviewLimit" }, outputs: { Confirm: "Confirm", Cancel: "Cancel" }, standalone: false, decls: 1, vars: 1, consts: [[3, "Visible", "Width", "Title"], [3, "Close", "Visible", "Width", "Title"], [1, "delta-confirm-body"], [1, "delta-confirm-intro"], [1, "delta-summary"], [1, "delta-tile", "delta-tile--add"], [1, "delta-tile__count"], [1, "delta-tile__label"], [1, "delta-tile", "delta-tile--keep"], [1, "delta-tile"], [1, "delta-banner", "delta-banner--safe"], [1, "delta-banner", "delta-banner--danger"], ["mjButton", "", 3, "click", "variant", "disabled"], [1, "fa-solid", "fa-check"], ["mjButton", "", "variant", "outline", 3, "click"], [1, "delta-token-hint"], [1, "fa-solid", "fa-circle-check"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "delta-banner__copy"], [1, "delta-banner__ack"], ["type", "checkbox", 3, "change", "checked"], [1, "delta-section-label"], [1, "delta-preview"], [1, "delta-preview__row", "delta-preview__row--add"], [1, "fa-solid", "fa-user-plus"], [1, "delta-preview__id"], [1, "delta-preview__row", "delta-preview__row--remove"], [1, "delta-footnote"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "fa-solid", "fa-user-minus"]], template: function ListDeltaConfirmComponent_Template(rf, ctx) { if (rf & 1) {
299
+ i0.ɵɵconditionalCreate(0, ListDeltaConfirmComponent_Conditional_0_Template, 34, 21, "mj-dialog", 0);
300
+ } if (rf & 2) {
301
+ i0.ɵɵconditional(ctx.Visible && ctx.Delta ? 0 : -1);
302
+ } }, dependencies: [i1.MJButtonDirective, i1.MJDialogComponent, i1.MJDialogActionsComponent], styles: ["[_nghost-%COMP%] {\n display: contents;\n}\n\n.delta-confirm-body[_ngcontent-%COMP%] {\n padding: 16px 20px 8px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n color: var(--mj-text-primary);\n font-size: 13px;\n line-height: 1.5;\n}\n\n.delta-confirm-body--danger[_ngcontent-%COMP%] {\n border-left: 3px solid var(--mj-status-error);\n padding-left: 17px;\n}\n\n.delta-confirm-intro[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.delta-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 10px;\n}\n\n.delta-tile[_ngcontent-%COMP%] {\n border-radius: 8px;\n padding: 12px 14px;\n text-align: center;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n}\n\n.delta-tile__count[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 600;\n line-height: 1.1;\n}\n\n.delta-tile__label[_ngcontent-%COMP%] {\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n.delta-tile--add[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n border-color: var(--mj-status-success-border);\n color: var(--mj-status-success-text);\n}\n\n.delta-tile--keep[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.delta-tile--remove[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n}\n\n.delta-tile--remove-empty[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n.delta-banner[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n padding: 10px 12px;\n border-radius: 8px;\n font-size: 12.5px;\n align-items: flex-start;\n}\n\n.delta-banner__copy[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.delta-banner--safe[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n border: 1px solid var(--mj-status-success-border);\n color: var(--mj-status-success-text);\n align-items: center;\n}\n\n.delta-banner--danger[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n border: 1px solid var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n}\n\n.delta-banner__ack[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12.5px;\n cursor: pointer;\n user-select: none;\n}\n\n.delta-banner__ack[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.delta-section-label[_ngcontent-%COMP%] {\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n margin-top: 6px;\n}\n\n.delta-preview[_ngcontent-%COMP%] {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n max-height: 180px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n padding: 6px 8px;\n}\n\n.delta-preview__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 6px;\n border-radius: 4px;\n font-size: 12.5px;\n}\n\n.delta-preview__row--add[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.delta-preview__row--remove[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.delta-preview__id[_ngcontent-%COMP%] {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 11.5px;\n color: var(--mj-text-secondary);\n}\n\n.delta-footnote[_ngcontent-%COMP%] {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.delta-token-hint[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 11px;\n color: var(--mj-text-muted);\n align-self: center;\n}"], changeDetection: 0 });
303
+ }
304
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ListDeltaConfirmComponent, [{
305
+ type: Component,
306
+ args: [{ standalone: false, selector: 'mj-list-delta-confirm', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (Visible && Delta) {\n <mj-dialog\n [Visible]=\"true\"\n [Width]=\"720\"\n [Title]=\"hasDrops ? 'Confirm List Update \u2014 Records Will Be Removed' : 'Confirm List Update'\"\n (Close)=\"OnCancel()\">\n <div class=\"delta-confirm-body\" [class.delta-confirm-body--danger]=\"hasDrops\">\n <div class=\"delta-confirm-intro\">\n @if (hasDrops) {\n Refreshing <strong>{{ targetDisplayName }}</strong> will reconcile against the source.\n Records that are no longer present in the source will be removed.\n } @else {\n You're about to apply this change to <strong>{{ targetDisplayName }}</strong>.\n }\n </div>\n\n <div class=\"delta-summary\">\n <div class=\"delta-tile delta-tile--add\">\n <div class=\"delta-tile__count\">+{{ Delta.Counts.Add }}</div>\n <div class=\"delta-tile__label\">To Add</div>\n </div>\n <div class=\"delta-tile delta-tile--keep\">\n <div class=\"delta-tile__count\">{{ Delta.Counts.Unchanged }}</div>\n <div class=\"delta-tile__label\">Unchanged</div>\n </div>\n <div class=\"delta-tile\"\n [class.delta-tile--remove]=\"hasDrops\"\n [class.delta-tile--remove-empty]=\"!hasDrops\">\n <div class=\"delta-tile__count\">{{ hasDrops ? '\u2212' : '' }}{{ Delta.Counts.Remove }}</div>\n <div class=\"delta-tile__label\">To Remove</div>\n </div>\n </div>\n\n @if (!hasDrops) {\n <div class=\"delta-banner delta-banner--safe\">\n <i class=\"fa-solid fa-circle-check\"></i>\n <span>Safe operation \u2014 no records will be removed from the list.</span>\n </div>\n } @else {\n <div class=\"delta-banner delta-banner--danger\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div class=\"delta-banner__copy\">\n <div>\n <strong>{{ Delta.Counts.Remove }} record(s) will be removed from this list.</strong>\n @if (SourceLabel) {\n These records are members today but are no longer matched by the source\n <em>\"{{ SourceLabel }}\"</em>.\n } @else {\n These records are members today but are no longer matched by the configured source.\n }\n </div>\n <label class=\"delta-banner__ack\">\n <input type=\"checkbox\"\n [checked]=\"dropAcknowledged\"\n (change)=\"OnAcknowledgementToggle($any($event.target).checked)\">\n <span>I understand {{ Delta.Counts.Remove }} record(s) will be removed</span>\n </label>\n </div>\n </div>\n }\n\n @if (previewAdds.length > 0) {\n <div class=\"delta-section-label\">\n Preview \u2014 records being added (first {{ previewAdds.length }} of {{ Delta.Counts.Add }})\n </div>\n <ul class=\"delta-preview\">\n @for (id of previewAdds; track id) {\n <li class=\"delta-preview__row delta-preview__row--add\">\n <i class=\"fa-solid fa-user-plus\"></i>\n <span class=\"delta-preview__id\">{{ id }}</span>\n </li>\n }\n </ul>\n }\n\n @if (previewRemoves.length > 0) {\n <div class=\"delta-section-label\">\n Preview \u2014 records being removed (first {{ previewRemoves.length }} of {{ Delta.Counts.Remove }})\n </div>\n <ul class=\"delta-preview\">\n @for (id of previewRemoves; track id) {\n <li class=\"delta-preview__row delta-preview__row--remove\">\n <i class=\"fa-solid fa-user-minus\"></i>\n <span class=\"delta-preview__id\">{{ id }}</span>\n </li>\n }\n </ul>\n <div class=\"delta-footnote\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Removed records are logged in the audit log and can be re-added manually if needed.\n </div>\n }\n </div>\n\n <mj-dialog-actions>\n <button mjButton\n [variant]=\"hasDrops ? 'danger' : 'primary'\"\n [disabled]=\"!canConfirm\"\n (click)=\"OnConfirm()\">\n <i class=\"fa-solid fa-check\"></i>\n {{ confirmButtonLabel }}\n </button>\n <button mjButton variant=\"outline\" (click)=\"OnCancel()\">Cancel</button>\n <span class=\"delta-token-hint\">\n @if (hasDrops && !dropAcknowledged) {\n Confirm button unlocks after acknowledgement\n } @else {\n Delta token valid for 5 min\n }\n </span>\n </mj-dialog-actions>\n </mj-dialog>\n}\n", styles: [":host {\n display: contents;\n}\n\n.delta-confirm-body {\n padding: 16px 20px 8px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n color: var(--mj-text-primary);\n font-size: 13px;\n line-height: 1.5;\n}\n\n.delta-confirm-body--danger {\n border-left: 3px solid var(--mj-status-error);\n padding-left: 17px;\n}\n\n.delta-confirm-intro {\n color: var(--mj-text-secondary);\n}\n\n.delta-summary {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 10px;\n}\n\n.delta-tile {\n border-radius: 8px;\n padding: 12px 14px;\n text-align: center;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n}\n\n.delta-tile__count {\n font-size: 22px;\n font-weight: 600;\n line-height: 1.1;\n}\n\n.delta-tile__label {\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n.delta-tile--add {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n border-color: var(--mj-status-success-border);\n color: var(--mj-status-success-text);\n}\n\n.delta-tile--keep {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.delta-tile--remove {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n}\n\n.delta-tile--remove-empty {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n.delta-banner {\n display: flex;\n gap: 10px;\n padding: 10px 12px;\n border-radius: 8px;\n font-size: 12.5px;\n align-items: flex-start;\n}\n\n.delta-banner__copy {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.delta-banner--safe {\n background: var(--mj-status-success-bg);\n border: 1px solid var(--mj-status-success-border);\n color: var(--mj-status-success-text);\n align-items: center;\n}\n\n.delta-banner--danger {\n background: var(--mj-status-error-bg);\n border: 1px solid var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n}\n\n.delta-banner__ack {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12.5px;\n cursor: pointer;\n user-select: none;\n}\n\n.delta-banner__ack input {\n cursor: pointer;\n}\n\n.delta-section-label {\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n margin-top: 6px;\n}\n\n.delta-preview {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n max-height: 180px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n padding: 6px 8px;\n}\n\n.delta-preview__row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 6px;\n border-radius: 4px;\n font-size: 12.5px;\n}\n\n.delta-preview__row--add i {\n color: var(--mj-status-success);\n}\n\n.delta-preview__row--remove i {\n color: var(--mj-status-error);\n}\n\n.delta-preview__id {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 11.5px;\n color: var(--mj-text-secondary);\n}\n\n.delta-footnote {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.delta-token-hint {\n margin-left: auto;\n font-size: 11px;\n color: var(--mj-text-muted);\n align-self: center;\n}\n"] }]
307
+ }], null, { Visible: [{
308
+ type: Input
309
+ }], Delta: [{
310
+ type: Input
311
+ }], TargetListName: [{
312
+ type: Input
313
+ }], SourceLabel: [{
314
+ type: Input
315
+ }], PreviewLimit: [{
316
+ type: Input
317
+ }], Confirm: [{
318
+ type: Output
319
+ }], Cancel: [{
320
+ type: Output
321
+ }] }); })();
322
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ListDeltaConfirmComponent, { className: "ListDeltaConfirmComponent", filePath: "src/lib/components/list-delta-confirm/list-delta-confirm.component.ts", lineNumber: 28 }); })();
323
+ //# sourceMappingURL=list-delta-confirm.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-delta-confirm.component.js","sourceRoot":"","sources":["../../../../src/lib/components/list-delta-confirm/list-delta-confirm.component.ts","../../../../src/lib/components/list-delta-confirm/list-delta-confirm.component.html"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';\n\nimport type { ListDelta } from '@memberjunction/lists-base';\n\n/**\n * Confirmation dialog for any list operation that produced a `ListDelta`\n * preview. This is the **only** UI path that emits a valid `DeltaToken`\n * onward to `applyListDelta` — every mutating list flow funnels through\n * here.\n *\n * Two visual states:\n *\n * - **Safe** (`Delta.Counts.Remove === 0`): green confirmation banner; the\n * primary button is enabled immediately.\n * - **Drop-warning** (`Delta.Counts.Remove > 0`): red header + warning\n * banner; the primary button stays disabled until the user checks the\n * acknowledgement box. The server still rejects with `DROP_NOT_CONFIRMED`\n * if `ConfirmDrops` is false — this UI gate is a convenience, not the\n * source of truth.\n */\n@Component({\n standalone: false,\n selector: 'mj-list-delta-confirm',\n templateUrl: './list-delta-confirm.component.html',\n styleUrls: ['./list-delta-confirm.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ListDeltaConfirmComponent {\n /**\n * Whether the dialog is rendered. Bound via the same getter/setter\n * pattern used by the sibling share dialog so consumers can drive\n * visibility from a parent state machine.\n */\n @Input()\n get Visible(): boolean {\n return this._visible;\n }\n set Visible(value: boolean) {\n if (this._visible !== value) {\n this._visible = value;\n // Reset the acknowledgement when re-opening so a previous session's\n // confirmation doesn't carry over to a new delta.\n if (value) this.dropAcknowledged = false;\n }\n }\n private _visible = false;\n\n /** The delta to confirm. Required — the component renders nothing useful without it. */\n @Input() Delta: ListDelta | null = null;\n\n /**\n * Human-readable name of the target list. Optional; the dialog falls\n * back to \"this list\" if not provided.\n */\n @Input() TargetListName: string | null = null;\n\n /**\n * Optional descriptor of the source for display (\"Q4 Donor View\", etc.).\n * Has no functional effect — purely for the warning copy.\n */\n @Input() SourceLabel: string | null = null;\n\n /**\n * How many preview records to render in the \"first N of …\" lists.\n * Larger deltas could otherwise blow up the DOM.\n */\n @Input() PreviewLimit = 5;\n\n /** Fires when the user confirms — payload is the validated delta token. */\n @Output() Confirm = new EventEmitter<string>();\n\n /** Fires when the user cancels (close button, ESC, or Cancel button). */\n @Output() Cancel = new EventEmitter<void>();\n\n /** Local UI state for the acknowledgement checkbox in drop-warning mode. */\n public dropAcknowledged = false;\n\n public get hasDrops(): boolean {\n return (this.Delta?.Counts.Remove ?? 0) > 0;\n }\n\n public get canConfirm(): boolean {\n if (!this.Delta) return false;\n if (!this.hasDrops) return true;\n return this.dropAcknowledged;\n }\n\n public get previewAdds(): string[] {\n return this.Delta?.ToAdd.slice(0, this.PreviewLimit) ?? [];\n }\n\n public get previewRemoves(): string[] {\n return this.Delta?.ToRemove.slice(0, this.PreviewLimit) ?? [];\n }\n\n public get confirmButtonLabel(): string {\n if (!this.Delta) return 'Confirm';\n if (this.hasDrops) return `Confirm Removal & Update`;\n return `Confirm (Add ${this.Delta.Counts.Add})`;\n }\n\n public get targetDisplayName(): string {\n return this.TargetListName ?? 'this list';\n }\n\n public OnConfirm(): void {\n if (!this.canConfirm || !this.Delta) return;\n this.Confirm.emit(this.Delta.DeltaToken);\n }\n\n public OnCancel(): void {\n this.Cancel.emit();\n }\n\n public OnAcknowledgementToggle(value: boolean): void {\n this.dropAcknowledged = value;\n }\n}\n","@if (Visible && Delta) {\n <mj-dialog\n [Visible]=\"true\"\n [Width]=\"720\"\n [Title]=\"hasDrops ? 'Confirm List Update — Records Will Be Removed' : 'Confirm List Update'\"\n (Close)=\"OnCancel()\">\n <div class=\"delta-confirm-body\" [class.delta-confirm-body--danger]=\"hasDrops\">\n <div class=\"delta-confirm-intro\">\n @if (hasDrops) {\n Refreshing <strong>{{ targetDisplayName }}</strong> will reconcile against the source.\n Records that are no longer present in the source will be removed.\n } @else {\n You're about to apply this change to <strong>{{ targetDisplayName }}</strong>.\n }\n </div>\n\n <div class=\"delta-summary\">\n <div class=\"delta-tile delta-tile--add\">\n <div class=\"delta-tile__count\">+{{ Delta.Counts.Add }}</div>\n <div class=\"delta-tile__label\">To Add</div>\n </div>\n <div class=\"delta-tile delta-tile--keep\">\n <div class=\"delta-tile__count\">{{ Delta.Counts.Unchanged }}</div>\n <div class=\"delta-tile__label\">Unchanged</div>\n </div>\n <div class=\"delta-tile\"\n [class.delta-tile--remove]=\"hasDrops\"\n [class.delta-tile--remove-empty]=\"!hasDrops\">\n <div class=\"delta-tile__count\">{{ hasDrops ? '−' : '' }}{{ Delta.Counts.Remove }}</div>\n <div class=\"delta-tile__label\">To Remove</div>\n </div>\n </div>\n\n @if (!hasDrops) {\n <div class=\"delta-banner delta-banner--safe\">\n <i class=\"fa-solid fa-circle-check\"></i>\n <span>Safe operation — no records will be removed from the list.</span>\n </div>\n } @else {\n <div class=\"delta-banner delta-banner--danger\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div class=\"delta-banner__copy\">\n <div>\n <strong>{{ Delta.Counts.Remove }} record(s) will be removed from this list.</strong>\n @if (SourceLabel) {\n These records are members today but are no longer matched by the source\n <em>\"{{ SourceLabel }}\"</em>.\n } @else {\n These records are members today but are no longer matched by the configured source.\n }\n </div>\n <label class=\"delta-banner__ack\">\n <input type=\"checkbox\"\n [checked]=\"dropAcknowledged\"\n (change)=\"OnAcknowledgementToggle($any($event.target).checked)\">\n <span>I understand {{ Delta.Counts.Remove }} record(s) will be removed</span>\n </label>\n </div>\n </div>\n }\n\n @if (previewAdds.length > 0) {\n <div class=\"delta-section-label\">\n Preview — records being added (first {{ previewAdds.length }} of {{ Delta.Counts.Add }})\n </div>\n <ul class=\"delta-preview\">\n @for (id of previewAdds; track id) {\n <li class=\"delta-preview__row delta-preview__row--add\">\n <i class=\"fa-solid fa-user-plus\"></i>\n <span class=\"delta-preview__id\">{{ id }}</span>\n </li>\n }\n </ul>\n }\n\n @if (previewRemoves.length > 0) {\n <div class=\"delta-section-label\">\n Preview — records being removed (first {{ previewRemoves.length }} of {{ Delta.Counts.Remove }})\n </div>\n <ul class=\"delta-preview\">\n @for (id of previewRemoves; track id) {\n <li class=\"delta-preview__row delta-preview__row--remove\">\n <i class=\"fa-solid fa-user-minus\"></i>\n <span class=\"delta-preview__id\">{{ id }}</span>\n </li>\n }\n </ul>\n <div class=\"delta-footnote\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Removed records are logged in the audit log and can be re-added manually if needed.\n </div>\n }\n </div>\n\n <mj-dialog-actions>\n <button mjButton\n [variant]=\"hasDrops ? 'danger' : 'primary'\"\n [disabled]=\"!canConfirm\"\n (click)=\"OnConfirm()\">\n <i class=\"fa-solid fa-check\"></i>\n {{ confirmButtonLabel }}\n </button>\n <button mjButton variant=\"outline\" (click)=\"OnCancel()\">Cancel</button>\n <span class=\"delta-token-hint\">\n @if (hasDrops && !dropAcknowledged) {\n Confirm button unlocks after acknowledgement\n } @else {\n Delta token valid for 5 min\n }\n </span>\n </mj-dialog-actions>\n </mj-dialog>\n}\n"]}
@@ -0,0 +1,60 @@
1
+ import { OnInit } from '@angular/core';
2
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Invitations management UI (mockup 16). For a single List:
6
+ * - Pending / Accepted / Expired / Revoked tabs.
7
+ * - Send new invitation form (email + role + TTL).
8
+ * - Revoke / Resend actions on Pending invites.
9
+ *
10
+ * Reads invitations directly via `RunView` (cheaper than going through
11
+ * GraphQL — the entity is already accessible). Mutations route through
12
+ * `GraphQLListsClient` so the audit-log + notification side effects
13
+ * fire server-side.
14
+ */
15
+ type InvitationStatus = 'Pending' | 'Accepted' | 'Expired' | 'Revoked';
16
+ interface InvitationRow {
17
+ ID: string;
18
+ Email: string;
19
+ Role: 'Editor' | 'Viewer';
20
+ Status: InvitationStatus;
21
+ ExpiresAt: Date;
22
+ CreatedAt: Date;
23
+ Token: string;
24
+ }
25
+ export declare class ListInvitationsComponent extends BaseAngularComponent implements OnInit {
26
+ private readonly cdr;
27
+ get ListID(): string | null;
28
+ set ListID(value: string | null);
29
+ private _listId;
30
+ /** Optional display name for the list — used in the empty-state copy. */
31
+ ListName: string | null;
32
+ activeTab: InvitationStatus;
33
+ invitations: InvitationRow[];
34
+ loading: boolean;
35
+ errorMessage: string | null;
36
+ submitting: boolean;
37
+ newEmail: string;
38
+ newRole: 'Editor' | 'Viewer';
39
+ newTtlHours: number;
40
+ private initialized;
41
+ ngOnInit(): Promise<void>;
42
+ setTab(tab: InvitationStatus): void;
43
+ get visibleInvitations(): InvitationRow[];
44
+ countFor(status: InvitationStatus): number;
45
+ formatExpiry(d: Date): string;
46
+ get canSend(): boolean;
47
+ SendInvitation(): Promise<void>;
48
+ Revoke(invitationId: string): Promise<void>;
49
+ /**
50
+ * "Resend" = create a fresh invitation for the same email + role. The
51
+ * old one stays Pending until either accepted or expired; users see
52
+ * both in the Pending tab until one is consumed.
53
+ */
54
+ Resend(inv: InvitationRow): Promise<void>;
55
+ private loadInvitations;
56
+ static ɵfac: i0.ɵɵFactoryDeclaration<ListInvitationsComponent, never>;
57
+ static ɵcmp: i0.ɵɵComponentDeclaration<ListInvitationsComponent, "mj-list-invitations", never, { "ListID": { "alias": "ListID"; "required": false; }; "ListName": { "alias": "ListName"; "required": false; }; }, {}, never, never, false, never>;
58
+ }
59
+ export {};
60
+ //# sourceMappingURL=list-invitations.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-invitations.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/list-invitations/list-invitations.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgE,MAAM,EAAU,MAAM,eAAe,CAAC;AAE7G,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AAKrE;;;;;;;;;;GAUG;AAEH,KAAK,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAEvE,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAOa,wBAAyB,SAAQ,oBAAqB,YAAW,MAAM;IAClF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA6B;IAEjD,IACI,MAAM,IAAI,MAAM,GAAG,IAAI,CAE1B;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAK9B;IACD,OAAO,CAAC,OAAO,CAAuB;IAEtC,yEAAyE;IAChE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEjC,SAAS,EAAE,gBAAgB,CAAa;IACxC,WAAW,EAAE,aAAa,EAAE,CAAM;IAClC,OAAO,UAAS;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IACnC,UAAU,UAAS;IAGnB,QAAQ,SAAM;IACd,OAAO,EAAE,QAAQ,GAAG,QAAQ,CAAY;IACxC,WAAW,SAAO;IAEzB,OAAO,CAAC,WAAW,CAAS;IAEtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAKxB,MAAM,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI;IAK1C,IAAW,kBAAkB,IAAI,aAAa,EAAE,CAW/C;IAEM,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM;IAW1C,YAAY,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM;IASpC,IAAW,OAAO,IAAI,OAAO,CAE5B;IAEY,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B/B,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxD;;;;OAIG;IACU,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;YAiBxC,eAAe;yCA3IlB,wBAAwB;2CAAxB,wBAAwB;CA8KpC"}