@memberjunction/ng-list-management 5.35.0 → 5.37.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,367 @@
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, inject } from '@angular/core';
2
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
+ import { RunView } from '@memberjunction/core';
4
+ import { GraphQLListsClient } from '@memberjunction/graphql-dataprovider';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "@angular/forms";
7
+ import * as i2 from "@memberjunction/ng-ui-components";
8
+ import * as i3 from "@memberjunction/ng-shared-generic";
9
+ const _c0 = () => ["Pending", "Accepted", "Expired", "Revoked"];
10
+ const _forTrack0 = ($index, $item) => $item.ID;
11
+ function ListInvitationsComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
12
+ i0.ɵɵelement(0, "i", 10);
13
+ } }
14
+ function ListInvitationsComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
15
+ i0.ɵɵelement(0, "i", 11);
16
+ } }
17
+ function ListInvitationsComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
18
+ i0.ɵɵelementStart(0, "div", 12);
19
+ i0.ɵɵelement(1, "i", 18);
20
+ i0.ɵɵtext(2);
21
+ i0.ɵɵelementEnd();
22
+ } if (rf & 2) {
23
+ const ctx_r0 = i0.ɵɵnextContext();
24
+ i0.ɵɵadvance(2);
25
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.errorMessage, " ");
26
+ } }
27
+ function ListInvitationsComponent_For_19_Template(rf, ctx) { if (rf & 1) {
28
+ const _r2 = i0.ɵɵgetCurrentView();
29
+ i0.ɵɵelementStart(0, "button", 19);
30
+ i0.ɵɵlistener("click", function ListInvitationsComponent_For_19_Template_button_click_0_listener() { const s_r3 = i0.ɵɵrestoreView(_r2).$implicit; const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setTab(s_r3)); });
31
+ i0.ɵɵtext(1);
32
+ i0.ɵɵelementStart(2, "span", 20);
33
+ i0.ɵɵtext(3);
34
+ i0.ɵɵelementEnd()();
35
+ } if (rf & 2) {
36
+ const s_r3 = ctx.$implicit;
37
+ const ctx_r0 = i0.ɵɵnextContext();
38
+ i0.ɵɵclassProp("invitation-tab--active", ctx_r0.activeTab === s_r3);
39
+ i0.ɵɵadvance();
40
+ i0.ɵɵtextInterpolate1(" ", s_r3, " ");
41
+ i0.ɵɵadvance(2);
42
+ i0.ɵɵtextInterpolate(ctx_r0.countFor(s_r3));
43
+ } }
44
+ function ListInvitationsComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
45
+ i0.ɵɵelementStart(0, "div", 15);
46
+ i0.ɵɵelement(1, "mj-loading", 21);
47
+ i0.ɵɵelementEnd();
48
+ } }
49
+ function ListInvitationsComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
50
+ i0.ɵɵelementStart(0, "div", 16);
51
+ i0.ɵɵelement(1, "i", 22);
52
+ i0.ɵɵelementStart(2, "span");
53
+ i0.ɵɵtext(3);
54
+ i0.ɵɵelementEnd()();
55
+ } if (rf & 2) {
56
+ const ctx_r0 = i0.ɵɵnextContext();
57
+ i0.ɵɵadvance(3);
58
+ i0.ɵɵtextInterpolate1("No ", ctx_r0.activeTab.toLowerCase(), " invitations.");
59
+ } }
60
+ function ListInvitationsComponent_Conditional_22_For_14_Conditional_11_Template(rf, ctx) { if (rf & 1) {
61
+ const _r4 = i0.ɵɵgetCurrentView();
62
+ i0.ɵɵelementStart(0, "button", 26);
63
+ i0.ɵɵlistener("click", function ListInvitationsComponent_Conditional_22_For_14_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const inv_r5 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.Resend(inv_r5)); });
64
+ i0.ɵɵelement(1, "i", 11);
65
+ i0.ɵɵtext(2, " Resend ");
66
+ i0.ɵɵelementEnd();
67
+ i0.ɵɵelementStart(3, "button", 27);
68
+ i0.ɵɵlistener("click", function ListInvitationsComponent_Conditional_22_For_14_Conditional_11_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r4); const inv_r5 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.Revoke(inv_r5.ID)); });
69
+ i0.ɵɵelement(4, "i", 28);
70
+ i0.ɵɵtext(5, " Revoke ");
71
+ i0.ɵɵelementEnd();
72
+ } }
73
+ function ListInvitationsComponent_Conditional_22_For_14_Conditional_12_Template(rf, ctx) { if (rf & 1) {
74
+ const _r6 = i0.ɵɵgetCurrentView();
75
+ i0.ɵɵelementStart(0, "button", 29);
76
+ i0.ɵɵlistener("click", function ListInvitationsComponent_Conditional_22_For_14_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const inv_r5 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.Resend(inv_r5)); });
77
+ i0.ɵɵelement(1, "i", 30);
78
+ i0.ɵɵtext(2, " Re-send ");
79
+ i0.ɵɵelementEnd();
80
+ } }
81
+ function ListInvitationsComponent_Conditional_22_For_14_Template(rf, ctx) { if (rf & 1) {
82
+ i0.ɵɵelementStart(0, "tr")(1, "td");
83
+ i0.ɵɵtext(2);
84
+ i0.ɵɵelementEnd();
85
+ i0.ɵɵelementStart(3, "td")(4, "span", 23);
86
+ i0.ɵɵtext(5);
87
+ i0.ɵɵelementEnd()();
88
+ i0.ɵɵelementStart(6, "td");
89
+ i0.ɵɵtext(7);
90
+ i0.ɵɵelementEnd();
91
+ i0.ɵɵelementStart(8, "td");
92
+ i0.ɵɵtext(9);
93
+ i0.ɵɵelementEnd();
94
+ i0.ɵɵelementStart(10, "td", 24);
95
+ i0.ɵɵconditionalCreate(11, ListInvitationsComponent_Conditional_22_For_14_Conditional_11_Template, 6, 0)(12, ListInvitationsComponent_Conditional_22_For_14_Conditional_12_Template, 3, 0, "button", 25);
96
+ i0.ɵɵelementEnd()();
97
+ } if (rf & 2) {
98
+ const inv_r5 = ctx.$implicit;
99
+ const ctx_r0 = i0.ɵɵnextContext(2);
100
+ i0.ɵɵadvance(2);
101
+ i0.ɵɵtextInterpolate(inv_r5.Email);
102
+ i0.ɵɵadvance(2);
103
+ i0.ɵɵclassProp("role-chip--editor", inv_r5.Role === "Editor");
104
+ i0.ɵɵadvance();
105
+ i0.ɵɵtextInterpolate1(" ", inv_r5.Role, " ");
106
+ i0.ɵɵadvance(2);
107
+ i0.ɵɵtextInterpolate(inv_r5.CreatedAt.toLocaleDateString());
108
+ i0.ɵɵadvance(2);
109
+ i0.ɵɵtextInterpolate(ctx_r0.formatExpiry(inv_r5.ExpiresAt));
110
+ i0.ɵɵadvance(2);
111
+ i0.ɵɵconditional(ctx_r0.activeTab === "Pending" ? 11 : ctx_r0.activeTab === "Expired" ? 12 : -1);
112
+ } }
113
+ function ListInvitationsComponent_Conditional_22_Template(rf, ctx) { if (rf & 1) {
114
+ i0.ɵɵelementStart(0, "table", 17)(1, "thead")(2, "tr")(3, "th");
115
+ i0.ɵɵtext(4, "Email");
116
+ i0.ɵɵelementEnd();
117
+ i0.ɵɵelementStart(5, "th");
118
+ i0.ɵɵtext(6, "Role");
119
+ i0.ɵɵelementEnd();
120
+ i0.ɵɵelementStart(7, "th");
121
+ i0.ɵɵtext(8, "Sent");
122
+ i0.ɵɵelementEnd();
123
+ i0.ɵɵelementStart(9, "th");
124
+ i0.ɵɵtext(10, "Expiry");
125
+ i0.ɵɵelementEnd();
126
+ i0.ɵɵelement(11, "th");
127
+ i0.ɵɵelementEnd()();
128
+ i0.ɵɵelementStart(12, "tbody");
129
+ i0.ɵɵrepeaterCreate(13, ListInvitationsComponent_Conditional_22_For_14_Template, 13, 7, "tr", null, _forTrack0);
130
+ i0.ɵɵelementEnd()();
131
+ } if (rf & 2) {
132
+ const ctx_r0 = i0.ɵɵnextContext();
133
+ i0.ɵɵadvance(13);
134
+ i0.ɵɵrepeater(ctx_r0.visibleInvitations);
135
+ } }
136
+ export class ListInvitationsComponent extends BaseAngularComponent {
137
+ cdr = inject(ChangeDetectorRef);
138
+ get ListID() {
139
+ return this._listId;
140
+ }
141
+ set ListID(value) {
142
+ if (this._listId !== value) {
143
+ this._listId = value;
144
+ if (this.initialized && value)
145
+ void this.loadInvitations();
146
+ }
147
+ }
148
+ _listId = null;
149
+ /** Optional display name for the list — used in the empty-state copy. */
150
+ ListName = null;
151
+ activeTab = 'Pending';
152
+ invitations = [];
153
+ loading = false;
154
+ errorMessage = null;
155
+ submitting = false;
156
+ // Send-new-invitation form
157
+ newEmail = '';
158
+ newRole = 'Viewer';
159
+ newTtlHours = 168; // 7 days default
160
+ initialized = false;
161
+ async ngOnInit() {
162
+ this.initialized = true;
163
+ if (this._listId)
164
+ await this.loadInvitations();
165
+ }
166
+ setTab(tab) {
167
+ this.activeTab = tab;
168
+ this.cdr.markForCheck();
169
+ }
170
+ get visibleInvitations() {
171
+ // We hydrate Status="Pending" rows whose ExpiresAt is in the past as
172
+ // Expired on the client so users see them without waiting for a
173
+ // server-side flip. The server's Accept path also lazily marks them.
174
+ const now = Date.now();
175
+ const hydrated = this.invitations.map((inv) => inv.Status === 'Pending' && inv.ExpiresAt.getTime() < now
176
+ ? { ...inv, Status: 'Expired' }
177
+ : inv);
178
+ return hydrated.filter((i) => i.Status === this.activeTab);
179
+ }
180
+ countFor(status) {
181
+ const now = Date.now();
182
+ let count = 0;
183
+ for (const inv of this.invitations) {
184
+ const effective = inv.Status === 'Pending' && inv.ExpiresAt.getTime() < now ? 'Expired' : inv.Status;
185
+ if (effective === status)
186
+ count++;
187
+ }
188
+ return count;
189
+ }
190
+ formatExpiry(d) {
191
+ const diff = d.getTime() - Date.now();
192
+ if (diff < 0)
193
+ return `expired ${d.toLocaleDateString()}`;
194
+ const hours = Math.floor(diff / 3_600_000);
195
+ if (hours < 24)
196
+ return `expires in ${hours}h`;
197
+ const days = Math.floor(hours / 24);
198
+ return `expires in ${days}d`;
199
+ }
200
+ get canSend() {
201
+ return !!this._listId && this.newEmail.trim().length > 0 && this.newEmail.includes('@') && !this.submitting;
202
+ }
203
+ async SendInvitation() {
204
+ if (!this.canSend || !this._listId)
205
+ return;
206
+ this.submitting = true;
207
+ this.cdr.markForCheck();
208
+ try {
209
+ const provider = this.ProviderToUse;
210
+ const client = new GraphQLListsClient(provider);
211
+ const result = await client.Invite({
212
+ ListID: this._listId,
213
+ Email: this.newEmail.trim(),
214
+ Role: this.newRole,
215
+ TtlHours: this.newTtlHours,
216
+ });
217
+ if (result.Success) {
218
+ this.newEmail = '';
219
+ await this.loadInvitations();
220
+ }
221
+ else {
222
+ this.errorMessage = `Failed to send: ${result.Message}`;
223
+ }
224
+ }
225
+ catch (e) {
226
+ this.errorMessage = e instanceof Error ? e.message : String(e);
227
+ }
228
+ finally {
229
+ this.submitting = false;
230
+ this.cdr.markForCheck();
231
+ }
232
+ }
233
+ async Revoke(invitationId) {
234
+ const provider = this.ProviderToUse;
235
+ const client = new GraphQLListsClient(provider);
236
+ const result = await client.RevokeInvitation(invitationId);
237
+ if (result.Success) {
238
+ await this.loadInvitations();
239
+ }
240
+ else {
241
+ this.errorMessage = `Failed to revoke: ${result.Message}`;
242
+ this.cdr.markForCheck();
243
+ }
244
+ }
245
+ /**
246
+ * "Resend" = create a fresh invitation for the same email + role. The
247
+ * old one stays Pending until either accepted or expired; users see
248
+ * both in the Pending tab until one is consumed.
249
+ */
250
+ async Resend(inv) {
251
+ const provider = this.ProviderToUse;
252
+ const client = new GraphQLListsClient(provider);
253
+ if (!this._listId)
254
+ return;
255
+ const result = await client.Invite({
256
+ ListID: this._listId,
257
+ Email: inv.Email,
258
+ Role: inv.Role,
259
+ TtlHours: 168,
260
+ });
261
+ if (result.Success)
262
+ await this.loadInvitations();
263
+ else {
264
+ this.errorMessage = `Failed to resend: ${result.Message}`;
265
+ this.cdr.markForCheck();
266
+ }
267
+ }
268
+ async loadInvitations() {
269
+ if (!this._listId)
270
+ return;
271
+ this.loading = true;
272
+ this.errorMessage = null;
273
+ this.cdr.markForCheck();
274
+ try {
275
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
276
+ const result = await rv.RunView({
277
+ EntityName: 'MJ: List Invitations',
278
+ ExtraFilter: `ListID='${this._listId.replace(/'/g, "''")}'`,
279
+ OrderBy: '__mj_CreatedAt DESC',
280
+ ResultType: 'simple',
281
+ });
282
+ if (!result.Success) {
283
+ this.errorMessage = result.ErrorMessage ?? 'Failed to load invitations';
284
+ this.invitations = [];
285
+ return;
286
+ }
287
+ this.invitations = (result.Results ?? []).map((r) => ({
288
+ ID: String(r.ID),
289
+ Email: String(r.Email),
290
+ Role: r.Role,
291
+ Status: r.Status,
292
+ ExpiresAt: new Date(r.ExpiresAt),
293
+ CreatedAt: new Date(r.__mj_CreatedAt),
294
+ Token: String(r.Token),
295
+ }));
296
+ }
297
+ catch (e) {
298
+ this.errorMessage = e instanceof Error ? e.message : String(e);
299
+ this.invitations = [];
300
+ }
301
+ finally {
302
+ this.loading = false;
303
+ this.cdr.markForCheck();
304
+ }
305
+ }
306
+ static ɵfac = /*@__PURE__*/ (() => { let ɵListInvitationsComponent_BaseFactory; return function ListInvitationsComponent_Factory(__ngFactoryType__) { return (ɵListInvitationsComponent_BaseFactory || (ɵListInvitationsComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ListInvitationsComponent)))(__ngFactoryType__ || ListInvitationsComponent); }; })();
307
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ListInvitationsComponent, selectors: [["mj-list-invitations"]], inputs: { ListID: "ListID", ListName: "ListName" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 23, vars: 9, consts: [[1, "invitations"], [1, "invitation-send"], [1, "invitation-send__heading"], [1, "invitation-send__form", 3, "submit"], ["type", "email", "name", "newEmail", "placeholder", "recipient@example.com", "required", "", 1, "mj-input", "invitation-send__email", 3, "ngModelChange", "ngModel"], ["name", "newRole", 1, "mj-input", "mj-select", "invitation-send__role", 3, "ngModelChange", "ngModel"], ["value", "Viewer"], ["value", "Editor"], ["type", "number", "name", "newTtlHours", "title", "Hours until expiry", "min", "1", "max", "720", 1, "mj-input", "invitation-send__ttl", 3, "ngModelChange", "ngModel"], ["mjButton", "", "variant", "primary", "type", "submit", 3, "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-paper-plane"], [1, "invitation-error"], [1, "invitation-tabs"], [1, "invitation-tab", 3, "invitation-tab--active"], [1, "invitation-state"], [1, "invitation-state", "invitation-state--empty"], [1, "invitation-table"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "invitation-tab", 3, "click"], [1, "invitation-tab__count"], ["text", "Loading invitations...", "size", "medium"], [1, "fa-solid", "fa-envelope"], [1, "role-chip"], [1, "invitation-actions"], ["mjButton", "", "size", "sm", "variant", "outline"], ["mjButton", "", "size", "sm", "variant", "outline", "title", "Send a fresh invitation", 3, "click"], ["mjButton", "", "size", "sm", "variant", "danger", 3, "click"], [1, "fa-solid", "fa-xmark"], ["mjButton", "", "size", "sm", "variant", "outline", 3, "click"], [1, "fa-solid", "fa-rotate-right"]], template: function ListInvitationsComponent_Template(rf, ctx) { if (rf & 1) {
308
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
309
+ i0.ɵɵtext(3, "Send invitation");
310
+ i0.ɵɵelementEnd();
311
+ i0.ɵɵelementStart(4, "form", 3);
312
+ i0.ɵɵlistener("submit", function ListInvitationsComponent_Template_form_submit_4_listener($event) { $event.preventDefault(); return ctx.SendInvitation(); });
313
+ i0.ɵɵelementStart(5, "input", 4);
314
+ i0.ɵɵtwoWayListener("ngModelChange", function ListInvitationsComponent_Template_input_ngModelChange_5_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.newEmail, $event) || (ctx.newEmail = $event); return $event; });
315
+ i0.ɵɵelementEnd();
316
+ i0.ɵɵelementStart(6, "select", 5);
317
+ i0.ɵɵtwoWayListener("ngModelChange", function ListInvitationsComponent_Template_select_ngModelChange_6_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.newRole, $event) || (ctx.newRole = $event); return $event; });
318
+ i0.ɵɵelementStart(7, "option", 6);
319
+ i0.ɵɵtext(8, "Viewer");
320
+ i0.ɵɵelementEnd();
321
+ i0.ɵɵelementStart(9, "option", 7);
322
+ i0.ɵɵtext(10, "Editor");
323
+ i0.ɵɵelementEnd()();
324
+ i0.ɵɵelementStart(11, "input", 8);
325
+ i0.ɵɵtwoWayListener("ngModelChange", function ListInvitationsComponent_Template_input_ngModelChange_11_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.newTtlHours, $event) || (ctx.newTtlHours = $event); return $event; });
326
+ i0.ɵɵelementEnd();
327
+ i0.ɵɵelementStart(12, "button", 9);
328
+ i0.ɵɵconditionalCreate(13, ListInvitationsComponent_Conditional_13_Template, 1, 0, "i", 10)(14, ListInvitationsComponent_Conditional_14_Template, 1, 0, "i", 11);
329
+ i0.ɵɵtext(15);
330
+ i0.ɵɵelementEnd()()();
331
+ i0.ɵɵconditionalCreate(16, ListInvitationsComponent_Conditional_16_Template, 3, 1, "div", 12);
332
+ i0.ɵɵelementStart(17, "div", 13);
333
+ i0.ɵɵrepeaterCreate(18, ListInvitationsComponent_For_19_Template, 4, 4, "button", 14, i0.ɵɵrepeaterTrackByIdentity);
334
+ i0.ɵɵelementEnd();
335
+ i0.ɵɵconditionalCreate(20, ListInvitationsComponent_Conditional_20_Template, 2, 0, "div", 15)(21, ListInvitationsComponent_Conditional_21_Template, 4, 1, "div", 16)(22, ListInvitationsComponent_Conditional_22_Template, 15, 0, "table", 17);
336
+ i0.ɵɵelementEnd();
337
+ } if (rf & 2) {
338
+ i0.ɵɵadvance(5);
339
+ i0.ɵɵtwoWayProperty("ngModel", ctx.newEmail);
340
+ i0.ɵɵadvance();
341
+ i0.ɵɵtwoWayProperty("ngModel", ctx.newRole);
342
+ i0.ɵɵadvance(5);
343
+ i0.ɵɵtwoWayProperty("ngModel", ctx.newTtlHours);
344
+ i0.ɵɵadvance();
345
+ i0.ɵɵproperty("disabled", !ctx.canSend);
346
+ i0.ɵɵadvance();
347
+ i0.ɵɵconditional(ctx.submitting ? 13 : 14);
348
+ i0.ɵɵadvance(2);
349
+ i0.ɵɵtextInterpolate1(" ", ctx.submitting ? "Sending\u2026" : "Send", " ");
350
+ i0.ɵɵadvance();
351
+ i0.ɵɵconditional(ctx.errorMessage ? 16 : -1);
352
+ i0.ɵɵadvance(2);
353
+ i0.ɵɵrepeater(i0.ɵɵpureFunction0(8, _c0));
354
+ i0.ɵɵadvance(2);
355
+ i0.ɵɵconditional(ctx.loading ? 20 : ctx.visibleInvitations.length === 0 ? 21 : 22);
356
+ } }, dependencies: [i1.ɵNgNoValidate, i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.NumberValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgControlStatusGroup, i1.RequiredValidator, i1.MinValidator, i1.MaxValidator, i1.NgModel, i1.NgForm, i2.MJButtonDirective, i3.LoadingComponent], styles: [".invitations[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 14px;\n padding: 16px;\n}\n\n.invitation-send[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 12px 14px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.invitation-send__heading[_ngcontent-%COMP%] {\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n}\n\n.invitation-send__form[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 120px 110px auto;\n gap: 8px;\n align-items: center;\n}\n\n.invitation-error[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: var(--mj-status-error-bg);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 6px;\n color: var(--mj-status-error-text);\n font-size: 12.5px;\n}\n\n.invitation-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.invitation-tab[_ngcontent-%COMP%] {\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n padding: 8px 12px;\n cursor: pointer;\n font-size: 12.5px;\n color: var(--mj-text-secondary);\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.invitation-tab--active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.invitation-tab__count[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n padding: 1px 6px;\n border-radius: 999px;\n font-size: 10.5px;\n}\n\n.invitation-tab--active[_ngcontent-%COMP%] .invitation-tab__count[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.invitation-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 32px;\n color: var(--mj-text-secondary);\n gap: 6px;\n}\n\n.invitation-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 22px;\n color: var(--mj-text-muted);\n}\n\n.invitation-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.invitation-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n padding: 8px 10px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.invitation-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n}\n\n.invitation-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n justify-content: flex-end;\n white-space: nowrap;\n}\n\n.role-chip[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.role-chip--editor[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text);\n}"], changeDetection: 0 });
357
+ }
358
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ListInvitationsComponent, [{
359
+ type: Component,
360
+ args: [{ standalone: false, selector: 'mj-list-invitations', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"invitations\">\n <!-- Send new invitation -->\n <div class=\"invitation-send\">\n <div class=\"invitation-send__heading\">Send invitation</div>\n <form class=\"invitation-send__form\" (submit)=\"$event.preventDefault(); SendInvitation()\">\n <input\n class=\"mj-input invitation-send__email\"\n type=\"email\"\n [(ngModel)]=\"newEmail\"\n name=\"newEmail\"\n placeholder=\"recipient@example.com\"\n required />\n <select class=\"mj-input mj-select invitation-send__role\" [(ngModel)]=\"newRole\" name=\"newRole\">\n <option value=\"Viewer\">Viewer</option>\n <option value=\"Editor\">Editor</option>\n </select>\n <input\n class=\"mj-input invitation-send__ttl\"\n type=\"number\"\n [(ngModel)]=\"newTtlHours\"\n name=\"newTtlHours\"\n title=\"Hours until expiry\"\n min=\"1\"\n max=\"720\" />\n <button mjButton variant=\"primary\" type=\"submit\" [disabled]=\"!canSend\">\n @if (submitting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n }\n {{ submitting ? 'Sending\u2026' : 'Send' }}\n </button>\n </form>\n </div>\n\n @if (errorMessage) {\n <div class=\"invitation-error\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n {{ errorMessage }}\n </div>\n }\n\n <!-- Status tabs -->\n <div class=\"invitation-tabs\">\n @for (s of ['Pending', 'Accepted', 'Expired', 'Revoked']; track s) {\n <button\n class=\"invitation-tab\"\n [class.invitation-tab--active]=\"activeTab === s\"\n (click)=\"setTab($any(s))\">\n {{ s }}\n <span class=\"invitation-tab__count\">{{ countFor($any(s)) }}</span>\n </button>\n }\n </div>\n\n @if (loading) {\n <div class=\"invitation-state\">\n <mj-loading text=\"Loading invitations...\" size=\"medium\"></mj-loading>\n </div>\n } @else if (visibleInvitations.length === 0) {\n <div class=\"invitation-state invitation-state--empty\">\n <i class=\"fa-solid fa-envelope\"></i>\n <span>No {{ activeTab.toLowerCase() }} invitations.</span>\n </div>\n } @else {\n <table class=\"invitation-table\">\n <thead>\n <tr>\n <th>Email</th>\n <th>Role</th>\n <th>Sent</th>\n <th>Expiry</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (inv of visibleInvitations; track inv.ID) {\n <tr>\n <td>{{ inv.Email }}</td>\n <td>\n <span class=\"role-chip\" [class.role-chip--editor]=\"inv.Role === 'Editor'\">\n {{ inv.Role }}\n </span>\n </td>\n <td>{{ inv.CreatedAt.toLocaleDateString() }}</td>\n <td>{{ formatExpiry(inv.ExpiresAt) }}</td>\n <td class=\"invitation-actions\">\n @if (activeTab === 'Pending') {\n <button mjButton size=\"sm\" variant=\"outline\" (click)=\"Resend(inv)\" title=\"Send a fresh invitation\">\n <i class=\"fa-solid fa-paper-plane\"></i>\n Resend\n </button>\n <button mjButton size=\"sm\" variant=\"danger\" (click)=\"Revoke(inv.ID)\">\n <i class=\"fa-solid fa-xmark\"></i>\n Revoke\n </button>\n } @else if (activeTab === 'Expired') {\n <button mjButton size=\"sm\" variant=\"outline\" (click)=\"Resend(inv)\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Re-send\n </button>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n }\n</div>\n", styles: [".invitations {\n display: flex;\n flex-direction: column;\n gap: 14px;\n padding: 16px;\n}\n\n.invitation-send {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 12px 14px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.invitation-send__heading {\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n}\n\n.invitation-send__form {\n display: grid;\n grid-template-columns: 1fr 120px 110px auto;\n gap: 8px;\n align-items: center;\n}\n\n.invitation-error {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: var(--mj-status-error-bg);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 6px;\n color: var(--mj-status-error-text);\n font-size: 12.5px;\n}\n\n.invitation-tabs {\n display: flex;\n gap: 4px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.invitation-tab {\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n padding: 8px 12px;\n cursor: pointer;\n font-size: 12.5px;\n color: var(--mj-text-secondary);\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.invitation-tab--active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.invitation-tab__count {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n padding: 1px 6px;\n border-radius: 999px;\n font-size: 10.5px;\n}\n\n.invitation-tab--active .invitation-tab__count {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.invitation-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 32px;\n color: var(--mj-text-secondary);\n gap: 6px;\n}\n\n.invitation-state i {\n font-size: 22px;\n color: var(--mj-text-muted);\n}\n\n.invitation-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.invitation-table th {\n text-align: left;\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n padding: 8px 10px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.invitation-table td {\n padding: 10px;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n}\n\n.invitation-actions {\n display: flex;\n gap: 6px;\n justify-content: flex-end;\n white-space: nowrap;\n}\n\n.role-chip {\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.role-chip--editor {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text);\n}\n"] }]
361
+ }], null, { ListID: [{
362
+ type: Input
363
+ }], ListName: [{
364
+ type: Input
365
+ }] }); })();
366
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ListInvitationsComponent, { className: "ListInvitationsComponent", filePath: "src/lib/components/list-invitations/list-invitations.component.ts", lineNumber: 39 }); })();
367
+ //# sourceMappingURL=list-invitations.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-invitations.component.js","sourceRoot":"","sources":["../../../../src/lib/components/list-invitations/list-invitations.component.ts","../../../../src/lib/components/list-invitations/list-invitations.component.html"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, inject } from '@angular/core';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { RunView } from '@memberjunction/core';\nimport type { MJListInvitationEntity } from '@memberjunction/core-entities';\nimport { GraphQLDataProvider, GraphQLListsClient } from '@memberjunction/graphql-dataprovider';\n\n/**\n * Invitations management UI (mockup 16). For a single List:\n * - Pending / Accepted / Expired / Revoked tabs.\n * - Send new invitation form (email + role + TTL).\n * - Revoke / Resend actions on Pending invites.\n *\n * Reads invitations directly via `RunView` (cheaper than going through\n * GraphQL — the entity is already accessible). Mutations route through\n * `GraphQLListsClient` so the audit-log + notification side effects\n * fire server-side.\n */\n\ntype InvitationStatus = 'Pending' | 'Accepted' | 'Expired' | 'Revoked';\n\ninterface InvitationRow {\n ID: string;\n Email: string;\n Role: 'Editor' | 'Viewer';\n Status: InvitationStatus;\n ExpiresAt: Date;\n CreatedAt: Date;\n Token: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-list-invitations',\n templateUrl: './list-invitations.component.html',\n styleUrls: ['./list-invitations.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ListInvitationsComponent extends BaseAngularComponent implements OnInit {\n private readonly cdr = inject(ChangeDetectorRef);\n\n @Input()\n get ListID(): string | null {\n return this._listId;\n }\n set ListID(value: string | null) {\n if (this._listId !== value) {\n this._listId = value;\n if (this.initialized && value) void this.loadInvitations();\n }\n }\n private _listId: string | null = null;\n\n /** Optional display name for the list — used in the empty-state copy. */\n @Input() ListName: string | null = null;\n\n public activeTab: InvitationStatus = 'Pending';\n public invitations: InvitationRow[] = [];\n public loading = false;\n public errorMessage: string | null = null;\n public submitting = false;\n\n // Send-new-invitation form\n public newEmail = '';\n public newRole: 'Editor' | 'Viewer' = 'Viewer';\n public newTtlHours = 168; // 7 days default\n\n private initialized = false;\n\n async ngOnInit(): Promise<void> {\n this.initialized = true;\n if (this._listId) await this.loadInvitations();\n }\n\n public setTab(tab: InvitationStatus): void {\n this.activeTab = tab;\n this.cdr.markForCheck();\n }\n\n public get visibleInvitations(): InvitationRow[] {\n // We hydrate Status=\"Pending\" rows whose ExpiresAt is in the past as\n // Expired on the client so users see them without waiting for a\n // server-side flip. The server's Accept path also lazily marks them.\n const now = Date.now();\n const hydrated = this.invitations.map<InvitationRow>((inv) =>\n inv.Status === 'Pending' && inv.ExpiresAt.getTime() < now\n ? { ...inv, Status: 'Expired' }\n : inv,\n );\n return hydrated.filter((i) => i.Status === this.activeTab);\n }\n\n public countFor(status: InvitationStatus): number {\n const now = Date.now();\n let count = 0;\n for (const inv of this.invitations) {\n const effective: InvitationStatus =\n inv.Status === 'Pending' && inv.ExpiresAt.getTime() < now ? 'Expired' : inv.Status;\n if (effective === status) count++;\n }\n return count;\n }\n\n public formatExpiry(d: Date): string {\n const diff = d.getTime() - Date.now();\n if (diff < 0) return `expired ${d.toLocaleDateString()}`;\n const hours = Math.floor(diff / 3_600_000);\n if (hours < 24) return `expires in ${hours}h`;\n const days = Math.floor(hours / 24);\n return `expires in ${days}d`;\n }\n\n public get canSend(): boolean {\n return !!this._listId && this.newEmail.trim().length > 0 && this.newEmail.includes('@') && !this.submitting;\n }\n\n public async SendInvitation(): Promise<void> {\n if (!this.canSend || !this._listId) return;\n this.submitting = true;\n this.cdr.markForCheck();\n try {\n const provider = this.ProviderToUse as unknown as GraphQLDataProvider;\n const client = new GraphQLListsClient(provider);\n const result = await client.Invite({\n ListID: this._listId,\n Email: this.newEmail.trim(),\n Role: this.newRole,\n TtlHours: this.newTtlHours,\n });\n if (result.Success) {\n this.newEmail = '';\n await this.loadInvitations();\n } else {\n this.errorMessage = `Failed to send: ${result.Message}`;\n }\n } catch (e) {\n this.errorMessage = e instanceof Error ? e.message : String(e);\n } finally {\n this.submitting = false;\n this.cdr.markForCheck();\n }\n }\n\n public async Revoke(invitationId: string): Promise<void> {\n const provider = this.ProviderToUse as unknown as GraphQLDataProvider;\n const client = new GraphQLListsClient(provider);\n const result = await client.RevokeInvitation(invitationId);\n if (result.Success) {\n await this.loadInvitations();\n } else {\n this.errorMessage = `Failed to revoke: ${result.Message}`;\n this.cdr.markForCheck();\n }\n }\n\n /**\n * \"Resend\" = create a fresh invitation for the same email + role. The\n * old one stays Pending until either accepted or expired; users see\n * both in the Pending tab until one is consumed.\n */\n public async Resend(inv: InvitationRow): Promise<void> {\n const provider = this.ProviderToUse as unknown as GraphQLDataProvider;\n const client = new GraphQLListsClient(provider);\n if (!this._listId) return;\n const result = await client.Invite({\n ListID: this._listId,\n Email: inv.Email,\n Role: inv.Role,\n TtlHours: 168,\n });\n if (result.Success) await this.loadInvitations();\n else {\n this.errorMessage = `Failed to resend: ${result.Message}`;\n this.cdr.markForCheck();\n }\n }\n\n private async loadInvitations(): Promise<void> {\n if (!this._listId) return;\n this.loading = true;\n this.errorMessage = null;\n this.cdr.markForCheck();\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJListInvitationEntity>({\n EntityName: 'MJ: List Invitations',\n ExtraFilter: `ListID='${this._listId.replace(/'/g, \"''\")}'`,\n OrderBy: '__mj_CreatedAt DESC',\n ResultType: 'simple',\n });\n if (!result.Success) {\n this.errorMessage = result.ErrorMessage ?? 'Failed to load invitations';\n this.invitations = [];\n return;\n }\n this.invitations = (result.Results ?? []).map((r) => ({\n ID: String(r.ID),\n Email: String(r.Email),\n Role: r.Role as 'Editor' | 'Viewer',\n Status: r.Status as InvitationStatus,\n ExpiresAt: new Date(r.ExpiresAt as unknown as string),\n CreatedAt: new Date(r.__mj_CreatedAt as unknown as string),\n Token: String(r.Token),\n }));\n } catch (e) {\n this.errorMessage = e instanceof Error ? e.message : String(e);\n this.invitations = [];\n } finally {\n this.loading = false;\n this.cdr.markForCheck();\n }\n }\n}\n","<div class=\"invitations\">\n <!-- Send new invitation -->\n <div class=\"invitation-send\">\n <div class=\"invitation-send__heading\">Send invitation</div>\n <form class=\"invitation-send__form\" (submit)=\"$event.preventDefault(); SendInvitation()\">\n <input\n class=\"mj-input invitation-send__email\"\n type=\"email\"\n [(ngModel)]=\"newEmail\"\n name=\"newEmail\"\n placeholder=\"recipient@example.com\"\n required />\n <select class=\"mj-input mj-select invitation-send__role\" [(ngModel)]=\"newRole\" name=\"newRole\">\n <option value=\"Viewer\">Viewer</option>\n <option value=\"Editor\">Editor</option>\n </select>\n <input\n class=\"mj-input invitation-send__ttl\"\n type=\"number\"\n [(ngModel)]=\"newTtlHours\"\n name=\"newTtlHours\"\n title=\"Hours until expiry\"\n min=\"1\"\n max=\"720\" />\n <button mjButton variant=\"primary\" type=\"submit\" [disabled]=\"!canSend\">\n @if (submitting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n }\n {{ submitting ? 'Sending…' : 'Send' }}\n </button>\n </form>\n </div>\n\n @if (errorMessage) {\n <div class=\"invitation-error\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n {{ errorMessage }}\n </div>\n }\n\n <!-- Status tabs -->\n <div class=\"invitation-tabs\">\n @for (s of ['Pending', 'Accepted', 'Expired', 'Revoked']; track s) {\n <button\n class=\"invitation-tab\"\n [class.invitation-tab--active]=\"activeTab === s\"\n (click)=\"setTab($any(s))\">\n {{ s }}\n <span class=\"invitation-tab__count\">{{ countFor($any(s)) }}</span>\n </button>\n }\n </div>\n\n @if (loading) {\n <div class=\"invitation-state\">\n <mj-loading text=\"Loading invitations...\" size=\"medium\"></mj-loading>\n </div>\n } @else if (visibleInvitations.length === 0) {\n <div class=\"invitation-state invitation-state--empty\">\n <i class=\"fa-solid fa-envelope\"></i>\n <span>No {{ activeTab.toLowerCase() }} invitations.</span>\n </div>\n } @else {\n <table class=\"invitation-table\">\n <thead>\n <tr>\n <th>Email</th>\n <th>Role</th>\n <th>Sent</th>\n <th>Expiry</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (inv of visibleInvitations; track inv.ID) {\n <tr>\n <td>{{ inv.Email }}</td>\n <td>\n <span class=\"role-chip\" [class.role-chip--editor]=\"inv.Role === 'Editor'\">\n {{ inv.Role }}\n </span>\n </td>\n <td>{{ inv.CreatedAt.toLocaleDateString() }}</td>\n <td>{{ formatExpiry(inv.ExpiresAt) }}</td>\n <td class=\"invitation-actions\">\n @if (activeTab === 'Pending') {\n <button mjButton size=\"sm\" variant=\"outline\" (click)=\"Resend(inv)\" title=\"Send a fresh invitation\">\n <i class=\"fa-solid fa-paper-plane\"></i>\n Resend\n </button>\n <button mjButton size=\"sm\" variant=\"danger\" (click)=\"Revoke(inv.ID)\">\n <i class=\"fa-solid fa-xmark\"></i>\n Revoke\n </button>\n } @else if (activeTab === 'Expired') {\n <button mjButton size=\"sm\" variant=\"outline\" (click)=\"Resend(inv)\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Re-send\n </button>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n }\n</div>\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"list-management-dialog.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/list-management-dialog/list-management-dialog.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"list-management-dialog.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/list-management-dialog/list-management-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EACZ,MAAM,EACN,SAAS,EACT,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGrE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAE/E,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,cAAc,EAGf,MAAM,qCAAqC,CAAC;;AAE7C;;;;;;;;;;GAUG;AACH,qBAMa,6BAA8B,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IA4DhG,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,GAAG;IA5Db;;OAEG;IACM,MAAM,EAAG,0BAA0B,CAAC;IAE7C;;OAEG;IACH,IACI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAKzB;IACD,OAAO,CAAC,QAAQ,CAAS;IAEzB;;OAEG;IACO,QAAQ,qCAA4C;IAE9D;;OAEG;IACO,MAAM,qBAA4B;IAG5C,OAAO,UAAS;IAChB,MAAM,UAAS;IACf,UAAU,SAAM;IAChB,SAAS,EAAE,aAAa,CAAS;IACjC,UAAU,EAAE,cAAc,CAAU;IACpC,cAAc,UAAS;IAGvB,QAAQ,EAAE,iBAAiB,EAAE,CAAM;IACnC,aAAa,EAAE,iBAAiB,EAAE,CAAM;IACxC,UAAU,EAAE,oBAAoB,EAAE,CAAM;IAGxC,WAAW,SAAM;IACjB,kBAAkB,SAAM;IACxB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAGxC,OAAO,CAAC,kBAAkB,CAA8B;IACjD,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IACtC,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAC1C,iBAAiB,EAAE,YAAY,EAAE,CAAM;IAG9C,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,aAAa,CAAyB;gBAGpC,WAAW,EAAE,qBAAqB,EAClC,GAAG,EAAE,iBAAiB;IAIhC,QAAQ,IAAI,IAAI;IAIhB,WAAW,IAAI,IAAI;IAKnB;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAgBxB;IAED;;OAEG;IACH,IAAI,cAAc,IAAI,MAAM,CAS3B;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;OAEG;YACW,gBAAgB;IAK9B;;OAEG;IACH,OAAO,CAAC,UAAU;IAclB;;OAEG;YACW,QAAQ;IAyDtB;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAKjC;;OAEG;IACH,WAAW,IAAI,IAAI;IAKnB;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IAKtC;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAK3C;;OAEG;IACH,OAAO,CAAC,YAAY;IA2CpB;;OAEG;IACH,gBAAgB,CAAC,EAAE,EAAE,iBAAiB,GAAG,IAAI;IAoB7C;;OAEG;IACH,mBAAmB,CAAC,EAAE,EAAE,iBAAiB,GAAG,IAAI;IAqBhD;;OAEG;IACH,kBAAkB,CAAC,EAAE,EAAE,iBAAiB,GAAG,MAAM;IAMjD;;OAEG;IACH,iBAAiB,CAAC,EAAE,EAAE,iBAAiB,GAAG,MAAM;IAUhD;;OAEG;IACH,iBAAiB,CAAC,EAAE,EAAE,iBAAiB,GAAG,MAAM;IAMhD;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAO1B;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAOxB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAkDjC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA8DnC;;OAEG;IACH,QAAQ,IAAI,IAAI;IAYhB;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAe9B;;OAEG;IACH,aAAa,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO;IAK7C;;OAEG;IACH,gBAAgB,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO;yCAtjBrC,6BAA6B;2CAA7B,6BAA6B;CA2jBzC"}
@@ -832,12 +832,8 @@ export class ListManagementDialogComponent extends BaseAngularComponent {
832
832
  try {
833
833
  // Process additions
834
834
  if (this.addedToLists.size > 0) {
835
- console.log(`[ListManagementDialog] Processing additions:`);
836
- console.log(` - Lists to add to:`, [...this.addedToLists]);
837
- console.log(` - Record IDs:`, this.config.recordIds);
838
835
  const addResult = await this.listService.addRecordsToLists([...this.addedToLists], this.config.recordIds, true // Skip duplicates
839
836
  );
840
- console.log(`[ListManagementDialog] Add result:`, addResult);
841
837
  for (const listId of this.addedToLists) {
842
838
  const vm = this.allLists.find(l => UUIDsEqual(l.list.ID, listId));
843
839
  if (vm) {