@memberjunction/ng-explorer-core 6.1.0-edge.3 → 6.1.0-edge.5

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 (38) hide show
  1. package/dist/app-routing.module.d.ts.map +1 -1
  2. package/dist/app-routing.module.js +10 -0
  3. package/dist/app-routing.module.js.map +1 -1
  4. package/dist/generated/lazy-feature-config.d.ts.map +1 -1
  5. package/dist/generated/lazy-feature-config.js +9 -3
  6. package/dist/generated/lazy-feature-config.js.map +1 -1
  7. package/dist/lib/command-palette/command-palette.component.d.ts +13 -0
  8. package/dist/lib/command-palette/command-palette.component.d.ts.map +1 -1
  9. package/dist/lib/command-palette/command-palette.component.js +105 -41
  10. package/dist/lib/command-palette/command-palette.component.js.map +1 -1
  11. package/dist/lib/identity-claims/claim-redeem.component.d.ts +64 -0
  12. package/dist/lib/identity-claims/claim-redeem.component.d.ts.map +1 -0
  13. package/dist/lib/identity-claims/claim-redeem.component.js +276 -0
  14. package/dist/lib/identity-claims/claim-redeem.component.js.map +1 -0
  15. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  16. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +13 -12
  17. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  18. package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts +24 -0
  19. package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts.map +1 -0
  20. package/dist/lib/resource-wrappers/chat-deeplink-params.js +27 -0
  21. package/dist/lib/resource-wrappers/chat-deeplink-params.js.map +1 -0
  22. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +7 -0
  23. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  24. package/dist/lib/resource-wrappers/dashboard-resource.component.js +23 -0
  25. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  26. package/dist/lib/server-connectivity/server-connectivity-banner.component.d.ts +20 -8
  27. package/dist/lib/server-connectivity/server-connectivity-banner.component.d.ts.map +1 -1
  28. package/dist/lib/server-connectivity/server-connectivity-banner.component.js +25 -20
  29. package/dist/lib/server-connectivity/server-connectivity-banner.component.js.map +1 -1
  30. package/dist/lib/shell/shell.component.d.ts +23 -0
  31. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  32. package/dist/lib/shell/shell.component.js +316 -248
  33. package/dist/lib/shell/shell.component.js.map +1 -1
  34. package/dist/module.d.ts +59 -58
  35. package/dist/module.d.ts.map +1 -1
  36. package/dist/module.js +3 -0
  37. package/dist/module.js.map +1 -1
  38. package/package.json +52 -52
@@ -0,0 +1,276 @@
1
+ /**
2
+ * @fileoverview Identity Claim Redemption Page
3
+ *
4
+ * Landing page for the links in identity-claim emails
5
+ * (`${PORTAL_BASE_URL}/claims/redeem?id=<claimId>&token=<rawToken>`). When a recipient
6
+ * clicks through, this component:
7
+ * 1. Waits for the user's session to be restored (same posture as the OAuth callback —
8
+ * no AuthGuard; the component handles the not-yet-authenticated case itself)
9
+ * 2. Extracts the claim id and optional verification token from the query params
10
+ * 3. Calls the `RedeemIdentityClaim` GraphQL mutation, which runs the server engine's full
11
+ * gate (email match subject to verification rules, or timing-safe token match, atomic CAS)
12
+ * 4. Shows the outcome and offers navigation back into the app
13
+ *
14
+ * Like the OAuth callback, this is a deliberate exception to the NavigationService-only rule:
15
+ * it is registered directly in the routing module and reads its own query params.
16
+ *
17
+ * @module IdentityClaims
18
+ */
19
+ import { Component } from '@angular/core';
20
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
21
+ import * as i0 from "@angular/core";
22
+ import * as i1 from "@angular/router";
23
+ import * as i2 from "@memberjunction/ng-shared-generic";
24
+ import * as i3 from "@memberjunction/ng-ui-components";
25
+ function ClaimRedeemComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
26
+ i0.ɵɵelementStart(0, "div", 2);
27
+ i0.ɵɵelement(1, "mj-loading", 5);
28
+ i0.ɵɵelementEnd();
29
+ } if (rf & 2) {
30
+ const ctx_r0 = i0.ɵɵnextContext();
31
+ i0.ɵɵadvance();
32
+ i0.ɵɵproperty("text", i0.ɵɵinterpolate(ctx_r0.StatusMessage));
33
+ } }
34
+ function ClaimRedeemComponent_Conditional_3_Conditional_8_Template(rf, ctx) { if (rf & 1) {
35
+ const _r3 = i0.ɵɵgetCurrentView();
36
+ i0.ɵɵelementStart(0, "button", 13);
37
+ i0.ɵɵlistener("click", function ClaimRedeemComponent_Conditional_3_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onRetry()); });
38
+ i0.ɵɵelement(1, "i", 14);
39
+ i0.ɵɵtext(2, " Try Again ");
40
+ i0.ɵɵelementEnd();
41
+ } }
42
+ function ClaimRedeemComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
43
+ const _r2 = i0.ɵɵgetCurrentView();
44
+ i0.ɵɵelementStart(0, "div", 3)(1, "div", 6);
45
+ i0.ɵɵelement(2, "i", 7);
46
+ i0.ɵɵelementEnd();
47
+ i0.ɵɵelementStart(3, "h2");
48
+ i0.ɵɵtext(4);
49
+ i0.ɵɵelementEnd();
50
+ i0.ɵɵelementStart(5, "p", 8);
51
+ i0.ɵɵtext(6);
52
+ i0.ɵɵelementEnd();
53
+ i0.ɵɵelementStart(7, "div", 9);
54
+ i0.ɵɵconditionalCreate(8, ClaimRedeemComponent_Conditional_3_Conditional_8_Template, 3, 0, "button", 10);
55
+ i0.ɵɵelementStart(9, "button", 11);
56
+ i0.ɵɵlistener("click", function ClaimRedeemComponent_Conditional_3_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onGoToApp()); });
57
+ i0.ɵɵelement(10, "i", 12);
58
+ i0.ɵɵtext(11);
59
+ i0.ɵɵelementEnd()()();
60
+ } if (rf & 2) {
61
+ const ctx_r0 = i0.ɵɵnextContext();
62
+ i0.ɵɵadvance(4);
63
+ i0.ɵɵtextInterpolate(ctx_r0.NeedsSignIn ? "Sign In Required" : "Claim Not Redeemed");
64
+ i0.ɵɵadvance(2);
65
+ i0.ɵɵtextInterpolate(ctx_r0.ErrorMessage);
66
+ i0.ɵɵadvance(2);
67
+ i0.ɵɵconditional(!ctx_r0.NeedsSignIn ? 8 : -1);
68
+ i0.ɵɵadvance();
69
+ i0.ɵɵproperty("variant", ctx_r0.NeedsSignIn ? "primary" : "outline");
70
+ i0.ɵɵadvance(2);
71
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.NeedsSignIn ? "Go to Sign In" : "Open the App", " ");
72
+ } }
73
+ function ClaimRedeemComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
74
+ const _r4 = i0.ɵɵgetCurrentView();
75
+ i0.ɵɵelementStart(0, "div", 4)(1, "div", 15);
76
+ i0.ɵɵelement(2, "i", 16);
77
+ i0.ɵɵelementEnd();
78
+ i0.ɵɵelementStart(3, "h2");
79
+ i0.ɵɵtext(4, "Claim Redeemed");
80
+ i0.ɵɵelementEnd();
81
+ i0.ɵɵelementStart(5, "p");
82
+ i0.ɵɵtext(6);
83
+ i0.ɵɵelementEnd();
84
+ i0.ɵɵelementStart(7, "div", 9)(8, "button", 17);
85
+ i0.ɵɵlistener("click", function ClaimRedeemComponent_Conditional_4_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onGoToApp()); });
86
+ i0.ɵɵelement(9, "i", 18);
87
+ i0.ɵɵtext(10, " Open the App ");
88
+ i0.ɵɵelementEnd()()();
89
+ } if (rf & 2) {
90
+ const ctx_r0 = i0.ɵɵnextContext();
91
+ i0.ɵɵadvance(6);
92
+ i0.ɵɵtextInterpolate(ctx_r0.StatusMessage);
93
+ } }
94
+ /** Maximum time to wait for session restoration (30 seconds) */
95
+ const MAX_WAIT_TIME_MS = 30000;
96
+ /** Polling interval for checking provider readiness (500ms) */
97
+ const POLL_INTERVAL_MS = 500;
98
+ const REDEEM_MUTATION = `
99
+ mutation RedeemIdentityClaim($ClaimID: String!, $Token: String) {
100
+ RedeemIdentityClaim(ClaimID: $ClaimID, Token: $Token) {
101
+ Success
102
+ ErrorMessage
103
+ ClaimID
104
+ Data
105
+ }
106
+ }
107
+ `;
108
+ export class ClaimRedeemComponent extends BaseAngularComponent {
109
+ route;
110
+ router;
111
+ cdr;
112
+ /** Loading state while restoring the session / redeeming */
113
+ IsLoading = true;
114
+ /** Terminal error state */
115
+ HasError = false;
116
+ /** Error message to display */
117
+ ErrorMessage = '';
118
+ /** True when the wait for authentication timed out (user likely not signed in) */
119
+ NeedsSignIn = false;
120
+ /** Status message shown during processing */
121
+ StatusMessage = 'Restoring session...';
122
+ /** Timer for polling provider readiness */
123
+ pollTimer = null;
124
+ /** Flag to prevent double processing */
125
+ isProcessing = false;
126
+ constructor(route, router, cdr) {
127
+ super();
128
+ this.route = route;
129
+ this.router = router;
130
+ this.cdr = cdr;
131
+ }
132
+ async ngOnInit() {
133
+ await this.waitForProviderAndRedeem();
134
+ }
135
+ ngOnDestroy() {
136
+ if (this.pollTimer) {
137
+ clearInterval(this.pollTimer);
138
+ this.pollTimer = null;
139
+ }
140
+ }
141
+ /**
142
+ * Waits for the GraphQL provider to be initialized (indicating auth is complete),
143
+ * then redeems the claim from the query params.
144
+ */
145
+ async waitForProviderAndRedeem() {
146
+ const startTime = Date.now();
147
+ if (this.isProviderReady()) {
148
+ await this.safeRedeem();
149
+ return;
150
+ }
151
+ this.StatusMessage = 'Waiting for sign-in...';
152
+ this.cdr.detectChanges();
153
+ return new Promise((resolve) => {
154
+ this.pollTimer = setInterval(async () => {
155
+ const elapsed = Date.now() - startTime;
156
+ if (this.isProviderReady()) {
157
+ if (this.pollTimer) {
158
+ clearInterval(this.pollTimer);
159
+ this.pollTimer = null;
160
+ }
161
+ await this.safeRedeem();
162
+ resolve();
163
+ return;
164
+ }
165
+ if (elapsed >= MAX_WAIT_TIME_MS) {
166
+ if (this.pollTimer) {
167
+ clearInterval(this.pollTimer);
168
+ this.pollTimer = null;
169
+ }
170
+ this.NeedsSignIn = true;
171
+ this.showError('Please sign in first, then open the link from your email again — the claim will attach to your signed-in account.');
172
+ resolve();
173
+ return;
174
+ }
175
+ const secondsRemaining = Math.ceil((MAX_WAIT_TIME_MS - elapsed) / 1000);
176
+ this.StatusMessage = `Waiting for sign-in... (${secondsRemaining}s)`;
177
+ this.cdr.detectChanges();
178
+ }, POLL_INTERVAL_MS);
179
+ });
180
+ }
181
+ /** Checks if the GraphQL provider is initialized with a valid token */
182
+ isProviderReady() {
183
+ try {
184
+ const provider = this.ProviderToUse;
185
+ if (!provider) {
186
+ return false;
187
+ }
188
+ const configData = provider.ConfigData;
189
+ return Boolean(configData && configData.Token && configData.URL);
190
+ }
191
+ catch {
192
+ return false;
193
+ }
194
+ }
195
+ /** Redeems exactly once, converting any throw into the error state */
196
+ async safeRedeem() {
197
+ if (this.isProcessing) {
198
+ return;
199
+ }
200
+ this.isProcessing = true;
201
+ try {
202
+ await this.redeemClaim();
203
+ }
204
+ catch (error) {
205
+ console.error('[Claim Redeem] Error redeeming claim:', error);
206
+ this.showError(error instanceof Error ? error.message : String(error));
207
+ }
208
+ }
209
+ /** Reads the query params and calls the redemption mutation */
210
+ async redeemClaim() {
211
+ const params = this.route.snapshot.queryParams;
212
+ const claimId = params['id'];
213
+ const token = params['token'];
214
+ if (!claimId) {
215
+ this.showError('This link is missing its claim id. Please use the exact link from your email.');
216
+ return;
217
+ }
218
+ this.StatusMessage = 'Redeeming your claim...';
219
+ this.cdr.detectChanges();
220
+ const provider = this.ProviderToUse;
221
+ const result = (await provider.ExecuteGQL(REDEEM_MUTATION, {
222
+ ClaimID: claimId,
223
+ Token: token ?? null
224
+ }));
225
+ const outcome = result?.RedeemIdentityClaim;
226
+ if (outcome?.Success) {
227
+ this.IsLoading = false;
228
+ this.StatusMessage = 'Your claim has been redeemed and attached to your account.';
229
+ this.cdr.detectChanges();
230
+ }
231
+ else {
232
+ this.showError(outcome?.ErrorMessage || 'The claim could not be redeemed.');
233
+ }
234
+ }
235
+ /** Shows the terminal error state */
236
+ showError(message) {
237
+ this.IsLoading = false;
238
+ this.HasError = true;
239
+ this.ErrorMessage = message;
240
+ this.cdr.detectChanges();
241
+ }
242
+ /** Navigates into the app shell (which handles sign-in when needed) */
243
+ onGoToApp() {
244
+ this.router.navigateByUrl('/');
245
+ }
246
+ /** Retries redemption from scratch (fresh component state) */
247
+ onRetry() {
248
+ this.IsLoading = true;
249
+ this.HasError = false;
250
+ this.NeedsSignIn = false;
251
+ this.ErrorMessage = '';
252
+ this.isProcessing = false;
253
+ void this.waitForProviderAndRedeem();
254
+ }
255
+ static ɵfac = function ClaimRedeemComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ClaimRedeemComponent)(i0.ɵɵdirectiveInject(i1.ActivatedRoute), i0.ɵɵdirectiveInject(i1.Router), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
256
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClaimRedeemComponent, selectors: [["mj-claim-redeem"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 3, consts: [[1, "claim-redeem-container"], [1, "claim-redeem-card"], [1, "claim-status", "loading"], [1, "claim-status", "error"], [1, "claim-status", "success"], [3, "text"], [1, "icon-container", "error-icon"], [1, "fa-solid", "fa-circle-exclamation"], [1, "error-message"], [1, "button-group"], ["mjButton", "", "variant", "secondary"], ["mjButton", "", 3, "click", "variant"], [1, "fa-solid", "fa-arrow-right-to-bracket"], ["mjButton", "", "variant", "secondary", 3, "click"], [1, "fa-solid", "fa-rotate-right"], [1, "icon-container", "success-icon"], [1, "fa-solid", "fa-circle-check"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fa-solid", "fa-house"]], template: function ClaimRedeemComponent_Template(rf, ctx) { if (rf & 1) {
257
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1);
258
+ i0.ɵɵconditionalCreate(2, ClaimRedeemComponent_Conditional_2_Template, 2, 2, "div", 2);
259
+ i0.ɵɵconditionalCreate(3, ClaimRedeemComponent_Conditional_3_Template, 12, 5, "div", 3);
260
+ i0.ɵɵconditionalCreate(4, ClaimRedeemComponent_Conditional_4_Template, 11, 1, "div", 4);
261
+ i0.ɵɵelementEnd()();
262
+ } if (rf & 2) {
263
+ i0.ɵɵadvance(2);
264
+ i0.ɵɵconditional(ctx.IsLoading ? 2 : -1);
265
+ i0.ɵɵadvance();
266
+ i0.ɵɵconditional(ctx.HasError ? 3 : -1);
267
+ i0.ɵɵadvance();
268
+ i0.ɵɵconditional(!ctx.IsLoading && !ctx.HasError ? 4 : -1);
269
+ } }, dependencies: [i2.LoadingComponent, i3.MJButtonDirective], styles: [".claim-redeem-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n background: var(--mj-brand-primary);\n padding: 1rem;\n}\n\n.claim-redeem-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n padding: 3rem;\n border-radius: 1rem;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n text-align: center;\n max-width: 450px;\n width: 100%;\n}\n\n.claim-status[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.claim-status[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1.5rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.claim-status[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-muted);\n line-height: 1.6;\n}\n\n.icon-container[_ngcontent-%COMP%] {\n font-size: 3rem;\n}\n\n.success-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.error-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.error-message[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.button-group[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n margin-top: 0.5rem;\n flex-wrap: wrap;\n justify-content: center;\n}"] });
270
+ }
271
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClaimRedeemComponent, [{
272
+ type: Component,
273
+ args: [{ standalone: false, selector: 'mj-claim-redeem', template: "<div class=\"claim-redeem-container\">\n <div class=\"claim-redeem-card\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"claim-status loading\">\n <mj-loading text=\"{{ StatusMessage }}\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (HasError) {\n <div class=\"claim-status error\">\n <div class=\"icon-container error-icon\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n </div>\n <h2>{{ NeedsSignIn ? 'Sign In Required' : 'Claim Not Redeemed' }}</h2>\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n @if (!NeedsSignIn) {\n <button mjButton variant=\"secondary\" (click)=\"onRetry()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Try Again\n </button>\n }\n <button mjButton [variant]=\"NeedsSignIn ? 'primary' : 'outline'\" (click)=\"onGoToApp()\">\n <i class=\"fa-solid fa-arrow-right-to-bracket\"></i>\n {{ NeedsSignIn ? 'Go to Sign In' : 'Open the App' }}\n </button>\n </div>\n </div>\n }\n\n <!-- Success State -->\n @if (!IsLoading && !HasError) {\n <div class=\"claim-status success\">\n <div class=\"icon-container success-icon\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <h2>Claim Redeemed</h2>\n <p>{{ StatusMessage }}</p>\n <div class=\"button-group\">\n <button mjButton variant=\"primary\" (click)=\"onGoToApp()\">\n <i class=\"fa-solid fa-house\"></i>\n Open the App\n </button>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [".claim-redeem-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n background: var(--mj-brand-primary);\n padding: 1rem;\n}\n\n.claim-redeem-card {\n background: var(--mj-bg-surface);\n padding: 3rem;\n border-radius: 1rem;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n text-align: center;\n max-width: 450px;\n width: 100%;\n}\n\n.claim-status {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.claim-status h2 {\n margin: 0;\n font-size: 1.5rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.claim-status p {\n margin: 0;\n color: var(--mj-text-muted);\n line-height: 1.6;\n}\n\n.icon-container {\n font-size: 3rem;\n}\n\n.success-icon {\n color: var(--mj-status-success);\n}\n\n.error-icon {\n color: var(--mj-status-error);\n}\n\n.error-message {\n color: var(--mj-text-secondary);\n}\n\n.button-group {\n display: flex;\n gap: 0.75rem;\n margin-top: 0.5rem;\n flex-wrap: wrap;\n justify-content: center;\n}\n"] }]
274
+ }], () => [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: i0.ChangeDetectorRef }], null); })();
275
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClaimRedeemComponent, { className: "ClaimRedeemComponent", filePath: "src/lib/identity-claims/claim-redeem.component.ts", lineNumber: 56 }); })();
276
+ //# sourceMappingURL=claim-redeem.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claim-redeem.component.js","sourceRoot":"","sources":["../../../src/lib/identity-claims/claim-redeem.component.ts","../../../src/lib/identity-claims/claim-redeem.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Identity Claim Redemption Page\n *\n * Landing page for the links in identity-claim emails\n * (`${PORTAL_BASE_URL}/claims/redeem?id=<claimId>&token=<rawToken>`). When a recipient\n * clicks through, this component:\n * 1. Waits for the user's session to be restored (same posture as the OAuth callback —\n * no AuthGuard; the component handles the not-yet-authenticated case itself)\n * 2. Extracts the claim id and optional verification token from the query params\n * 3. Calls the `RedeemIdentityClaim` GraphQL mutation, which runs the server engine's full\n * gate (email match subject to verification rules, or timing-safe token match, atomic CAS)\n * 4. Shows the outcome and offers navigation back into the app\n *\n * Like the OAuth callback, this is a deliberate exception to the NavigationService-only rule:\n * it is registered directly in the routing module and reads its own query params.\n *\n * @module IdentityClaims\n */\n\nimport { Component, OnDestroy, OnInit, ChangeDetectorRef } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\ninterface RedeemIdentityClaimResponse {\n RedeemIdentityClaim?: {\n Success: boolean;\n ErrorMessage?: string;\n ClaimID?: string;\n Data?: string;\n };\n}\n\n/** Maximum time to wait for session restoration (30 seconds) */\nconst MAX_WAIT_TIME_MS = 30000;\n/** Polling interval for checking provider readiness (500ms) */\nconst POLL_INTERVAL_MS = 500;\n\nconst REDEEM_MUTATION = `\n mutation RedeemIdentityClaim($ClaimID: String!, $Token: String) {\n RedeemIdentityClaim(ClaimID: $ClaimID, Token: $Token) {\n Success\n ErrorMessage\n ClaimID\n Data\n }\n }\n`;\n\n@Component({\n standalone: false,\n selector: 'mj-claim-redeem',\n templateUrl: './claim-redeem.component.html',\n styleUrls: ['./claim-redeem.component.css']\n})\nexport class ClaimRedeemComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n /** Loading state while restoring the session / redeeming */\n public IsLoading = true;\n\n /** Terminal error state */\n public HasError = false;\n\n /** Error message to display */\n public ErrorMessage = '';\n\n /** True when the wait for authentication timed out (user likely not signed in) */\n public NeedsSignIn = false;\n\n /** Status message shown during processing */\n public StatusMessage = 'Restoring session...';\n\n /** Timer for polling provider readiness */\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n\n /** Flag to prevent double processing */\n private isProcessing = false;\n\n constructor(\n private route: ActivatedRoute,\n private router: Router,\n private cdr: ChangeDetectorRef\n ) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n await this.waitForProviderAndRedeem();\n }\n\n ngOnDestroy(): void {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /**\n * Waits for the GraphQL provider to be initialized (indicating auth is complete),\n * then redeems the claim from the query params.\n */\n private async waitForProviderAndRedeem(): Promise<void> {\n const startTime = Date.now();\n\n if (this.isProviderReady()) {\n await this.safeRedeem();\n return;\n }\n\n this.StatusMessage = 'Waiting for sign-in...';\n this.cdr.detectChanges();\n\n return new Promise<void>((resolve) => {\n this.pollTimer = setInterval(async () => {\n const elapsed = Date.now() - startTime;\n\n if (this.isProviderReady()) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n await this.safeRedeem();\n resolve();\n return;\n }\n\n if (elapsed >= MAX_WAIT_TIME_MS) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n this.NeedsSignIn = true;\n this.showError('Please sign in first, then open the link from your email again — the claim will attach to your signed-in account.');\n resolve();\n return;\n }\n\n const secondsRemaining = Math.ceil((MAX_WAIT_TIME_MS - elapsed) / 1000);\n this.StatusMessage = `Waiting for sign-in... (${secondsRemaining}s)`;\n this.cdr.detectChanges();\n }, POLL_INTERVAL_MS);\n });\n }\n\n /** Checks if the GraphQL provider is initialized with a valid token */\n private isProviderReady(): boolean {\n try {\n const provider = this.ProviderToUse as GraphQLDataProvider;\n if (!provider) {\n return false;\n }\n const configData = provider.ConfigData;\n return Boolean(configData && configData.Token && configData.URL);\n } catch {\n return false;\n }\n }\n\n /** Redeems exactly once, converting any throw into the error state */\n private async safeRedeem(): Promise<void> {\n if (this.isProcessing) {\n return;\n }\n this.isProcessing = true;\n\n try {\n await this.redeemClaim();\n } catch (error) {\n console.error('[Claim Redeem] Error redeeming claim:', error);\n this.showError(error instanceof Error ? error.message : String(error));\n }\n }\n\n /** Reads the query params and calls the redemption mutation */\n private async redeemClaim(): Promise<void> {\n const params = this.route.snapshot.queryParams;\n const claimId = params['id'] as string | undefined;\n const token = params['token'] as string | undefined;\n\n if (!claimId) {\n this.showError('This link is missing its claim id. Please use the exact link from your email.');\n return;\n }\n\n this.StatusMessage = 'Redeeming your claim...';\n this.cdr.detectChanges();\n\n const provider = this.ProviderToUse as GraphQLDataProvider;\n const result = (await provider.ExecuteGQL(REDEEM_MUTATION, {\n ClaimID: claimId,\n Token: token ?? null\n })) as RedeemIdentityClaimResponse;\n\n const outcome = result?.RedeemIdentityClaim;\n if (outcome?.Success) {\n this.IsLoading = false;\n this.StatusMessage = 'Your claim has been redeemed and attached to your account.';\n this.cdr.detectChanges();\n } else {\n this.showError(outcome?.ErrorMessage || 'The claim could not be redeemed.');\n }\n }\n\n /** Shows the terminal error state */\n private showError(message: string): void {\n this.IsLoading = false;\n this.HasError = true;\n this.ErrorMessage = message;\n this.cdr.detectChanges();\n }\n\n /** Navigates into the app shell (which handles sign-in when needed) */\n public onGoToApp(): void {\n this.router.navigateByUrl('/');\n }\n\n /** Retries redemption from scratch (fresh component state) */\n public onRetry(): void {\n this.IsLoading = true;\n this.HasError = false;\n this.NeedsSignIn = false;\n this.ErrorMessage = '';\n this.isProcessing = false;\n void this.waitForProviderAndRedeem();\n }\n}\n","<div class=\"claim-redeem-container\">\n <div class=\"claim-redeem-card\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"claim-status loading\">\n <mj-loading text=\"{{ StatusMessage }}\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (HasError) {\n <div class=\"claim-status error\">\n <div class=\"icon-container error-icon\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n </div>\n <h2>{{ NeedsSignIn ? 'Sign In Required' : 'Claim Not Redeemed' }}</h2>\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n @if (!NeedsSignIn) {\n <button mjButton variant=\"secondary\" (click)=\"onRetry()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Try Again\n </button>\n }\n <button mjButton [variant]=\"NeedsSignIn ? 'primary' : 'outline'\" (click)=\"onGoToApp()\">\n <i class=\"fa-solid fa-arrow-right-to-bracket\"></i>\n {{ NeedsSignIn ? 'Go to Sign In' : 'Open the App' }}\n </button>\n </div>\n </div>\n }\n\n <!-- Success State -->\n @if (!IsLoading && !HasError) {\n <div class=\"claim-status success\">\n <div class=\"icon-container success-icon\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <h2>Claim Redeemed</h2>\n <p>{{ StatusMessage }}</p>\n <div class=\"button-group\">\n <button mjButton variant=\"primary\" (click)=\"onGoToApp()\">\n <i class=\"fa-solid fa-house\"></i>\n Open the App\n </button>\n </div>\n </div>\n }\n </div>\n</div>\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"chat-conversations-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/chat-conversations-resource.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat-conversations-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/chat-conversations-resource.component.ts"],"names":[],"mappings":"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"}
@@ -5,10 +5,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { Component, ViewEncapsulation, ViewChild, HostListener } from '@angular/core';
8
- import { CompositeKey } from '@memberjunction/core';
9
8
  import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
10
9
  import { BaseResourceComponent } from '@memberjunction/ng-shared';
11
10
  import { MJEnvironmentEntityExtended, UserInfoEngine, ConversationEngine } from '@memberjunction/core-entities';
11
+ import { resolveDeepLinkParam } from './chat-deeplink-params.js';
12
12
  import { MentionAutocompleteService } from '@memberjunction/ng-conversations';
13
13
  import { AIEngineBase } from '@memberjunction/ai-engine-base';
14
14
  import { takeUntil } from 'rxjs';
@@ -333,10 +333,13 @@ let ChatConversationsResource = class ChatConversationsResource extends BaseReso
333
333
  // Check queryParams first (shell populates these from the URL for deep-linking)
334
334
  const qp = config['queryParams'];
335
335
  this.applyAgentParam(qp?.['agent'], qp?.['agentReq']);
336
- const conversationId = qp?.['conversationId'] || config.conversationId;
337
- const artifactId = qp?.['artifactId'] || config.artifactId;
338
- const versionNumber = qp?.['versionNumber'] ? parseInt(qp['versionNumber'], 10)
339
- : config.versionNumber ? config.versionNumber : null;
336
+ const search = typeof window !== 'undefined' ? window.location.search : '';
337
+ const conversationId = resolveDeepLinkParam('conversationId', search, qp, config.conversationId);
338
+ const artifactId = resolveDeepLinkParam('artifactId', search, qp, config.artifactId);
339
+ // Resolved the same URL-first way as artifactId above: pairing a URL artifact with the
340
+ // previous visit's version number would open the wrong version of the right artifact.
341
+ const rawVersion = resolveDeepLinkParam('versionNumber', search, qp, config.versionNumber != null ? String(config.versionNumber) : undefined);
342
+ const versionNumber = rawVersion ? parseInt(rawVersion, 10) : null;
340
343
  // Set pending artifact if provided
341
344
  if (artifactId) {
342
345
  this.pendingArtifactId = artifactId;
@@ -871,12 +874,10 @@ let ChatConversationsResource = class ChatConversationsResource extends BaseReso
871
874
  handleActionableCommand(command) {
872
875
  if (command.type === 'open:resource') {
873
876
  const resourceCommand = command;
874
- if (resourceCommand.resourceType === 'Record' && resourceCommand.entityName) {
875
- const compositeKey = new CompositeKey([{
876
- FieldName: 'ID',
877
- Value: resourceCommand.resourceId
878
- }]);
879
- this.navigationService.OpenEntityRecord(resourceCommand.entityName, compositeKey);
877
+ if (resourceCommand.resourceType === 'Record') {
878
+ // Record opens are emitted as openEntityRecord from mj-conversation-chat-area
879
+ // (composite-key aware). Handling them here too would open the record twice.
880
+ return;
880
881
  }
881
882
  else if (resourceCommand.resourceType === 'Report' || resourceCommand.resourceType === 'Dashboard') {
882
883
  // Reports and dashboards from agents are stored as conversation artifacts.
@@ -1033,5 +1034,5 @@ export { ChatConversationsResource };
1033
1034
  type: HostListener,
1034
1035
  args: ['document:click', ['$event']]
1035
1036
  }] }); })();
1036
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ChatConversationsResource, { className: "ChatConversationsResource", filePath: "src/lib/resource-wrappers/chat-conversations-resource.component.ts", lineNumber: 261 }); })();
1037
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ChatConversationsResource, { className: "ChatConversationsResource", filePath: "src/lib/resource-wrappers/chat-conversations-resource.component.ts", lineNumber: 262 }); })();
1037
1038
  //# sourceMappingURL=chat-conversations-resource.component.js.map