@memberjunction/ng-export-service 6.2.0-edge.6 → 6.2.0-edge.7
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.
- package/dist/lib/module.d.ts +2 -1
- package/dist/lib/module.d.ts.map +1 -1
- package/dist/lib/module.js +10 -4
- package/dist/lib/module.js.map +1 -1
- package/dist/lib/office-connect-panel.component.d.ts +87 -0
- package/dist/lib/office-connect-panel.component.d.ts.map +1 -0
- package/dist/lib/office-connect-panel.component.js +454 -0
- package/dist/lib/office-connect-panel.component.js.map +1 -0
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +8 -3
package/dist/lib/module.d.ts
CHANGED
|
@@ -2,9 +2,10 @@ import * as i0 from "@angular/core";
|
|
|
2
2
|
import * as i1 from "./export-dialog.component";
|
|
3
3
|
import * as i2 from "@angular/common";
|
|
4
4
|
import * as i3 from "@angular/forms";
|
|
5
|
+
import * as i4 from "./office-connect-panel.component";
|
|
5
6
|
export declare class ExportServiceModule {
|
|
6
7
|
static ɵfac: i0.ɵɵFactoryDeclaration<ExportServiceModule, never>;
|
|
7
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<ExportServiceModule, [typeof i1.ExportDialogComponent], [typeof i2.CommonModule, typeof i3.FormsModule], [typeof i1.ExportDialogComponent]>;
|
|
8
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<ExportServiceModule, [typeof i1.ExportDialogComponent], [typeof i2.CommonModule, typeof i3.FormsModule, typeof i4.OfficeConnectPanelComponent], [typeof i1.ExportDialogComponent, typeof i4.OfficeConnectPanelComponent]>;
|
|
8
9
|
static ɵinj: i0.ɵɵInjectorDeclaration<ExportServiceModule>;
|
|
9
10
|
}
|
|
10
11
|
//# sourceMappingURL=module.d.ts.map
|
package/dist/lib/module.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/lib/module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/lib/module.ts"],"names":[],"mappings":";;;;;AAQA,qBAiBa,mBAAmB;yCAAnB,mBAAmB;0CAAnB,mBAAmB;0CAAnB,mBAAmB;CAAI"}
|
package/dist/lib/module.js
CHANGED
|
@@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common';
|
|
|
3
3
|
import { FormsModule } from '@angular/forms';
|
|
4
4
|
import { ExportDialogComponent } from './export-dialog.component';
|
|
5
5
|
import { ExportService } from './export.service';
|
|
6
|
+
import { OfficeConnectPanelComponent } from './office-connect-panel.component';
|
|
6
7
|
import * as i0 from "@angular/core";
|
|
7
8
|
export class ExportServiceModule {
|
|
8
9
|
static ɵfac = function ExportServiceModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ExportServiceModule)(); };
|
|
@@ -10,7 +11,8 @@ export class ExportServiceModule {
|
|
|
10
11
|
static ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ providers: [
|
|
11
12
|
ExportService
|
|
12
13
|
], imports: [CommonModule,
|
|
13
|
-
FormsModule
|
|
14
|
+
FormsModule,
|
|
15
|
+
OfficeConnectPanelComponent] });
|
|
14
16
|
}
|
|
15
17
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ExportServiceModule, [{
|
|
16
18
|
type: NgModule,
|
|
@@ -20,10 +22,12 @@ export class ExportServiceModule {
|
|
|
20
22
|
],
|
|
21
23
|
imports: [
|
|
22
24
|
CommonModule,
|
|
23
|
-
FormsModule
|
|
25
|
+
FormsModule,
|
|
26
|
+
OfficeConnectPanelComponent
|
|
24
27
|
],
|
|
25
28
|
exports: [
|
|
26
|
-
ExportDialogComponent
|
|
29
|
+
ExportDialogComponent,
|
|
30
|
+
OfficeConnectPanelComponent
|
|
27
31
|
],
|
|
28
32
|
providers: [
|
|
29
33
|
ExportService
|
|
@@ -31,5 +35,7 @@ export class ExportServiceModule {
|
|
|
31
35
|
}]
|
|
32
36
|
}], null, null); })();
|
|
33
37
|
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(ExportServiceModule, { declarations: [ExportDialogComponent], imports: [CommonModule,
|
|
34
|
-
FormsModule
|
|
38
|
+
FormsModule,
|
|
39
|
+
OfficeConnectPanelComponent], exports: [ExportDialogComponent,
|
|
40
|
+
OfficeConnectPanelComponent] }); })();
|
|
35
41
|
//# sourceMappingURL=module.js.map
|
package/dist/lib/module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/lib/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;;
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/lib/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;;AAmB/E,MAAM,OAAO,mBAAmB;6GAAnB,mBAAmB;4DAAnB,mBAAmB;iEAJnB;YACT,aAAa;SACd,YAVC,YAAY;YACZ,WAAW;YACX,2BAA2B;;iFAUlB,mBAAmB;cAjB/B,QAAQ;eAAC;gBACR,YAAY,EAAE;oBACZ,qBAAqB;iBACtB;gBACD,OAAO,EAAE;oBACP,YAAY;oBACZ,WAAW;oBACX,2BAA2B;iBAC5B;gBACD,OAAO,EAAE;oBACP,qBAAqB;oBACrB,2BAA2B;iBAC5B;gBACD,SAAS,EAAE;oBACT,aAAa;iBACd;aACF;;wFACY,mBAAmB,mBAf5B,qBAAqB,aAGrB,YAAY;QACZ,WAAW;QACX,2BAA2B,aAG3B,qBAAqB;QACrB,2BAA2B","sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\n\nimport { ExportDialogComponent } from './export-dialog.component';\nimport { ExportService } from './export.service';\nimport { OfficeConnectPanelComponent } from './office-connect-panel.component';\n\n@NgModule({\n declarations: [\n ExportDialogComponent\n ],\n imports: [\n CommonModule,\n FormsModule,\n OfficeConnectPanelComponent\n ],\n exports: [\n ExportDialogComponent,\n OfficeConnectPanelComponent\n ],\n providers: [\n ExportService\n ]\n})\nexport class ExportServiceModule { }\n"]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Generic, router-free Excel add-in sign-in & consent panel (`<mj-office-connect-panel>`).
|
|
3
|
+
*
|
|
4
|
+
* Lives in `@memberjunction/ng-export-service` (`packages/Angular/Generic/export-service`, `"mjUILayer": "widgets"`)
|
|
5
|
+
* so ANY Angular application built on MemberJunction's Generic layer — MJ Explorer or a custom Angular host —
|
|
6
|
+
* can serve the standalone `/office/connect` endpoint without depending on `@memberjunction/ng-explorer-core`,
|
|
7
|
+
* `@angular/router`, or a specific authentication library.
|
|
8
|
+
*
|
|
9
|
+
* Host apps pass `[QueryParams]` (`pk` and `state` from the URL) and handle `(SignInRequested)` by invoking
|
|
10
|
+
* their authentication provider's login flow.
|
|
11
|
+
*/
|
|
12
|
+
import { EventEmitter, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
|
|
13
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
14
|
+
import { OfficeConnectQueryParams } from '@memberjunction/excel-addin';
|
|
15
|
+
import * as i0 from "@angular/core";
|
|
16
|
+
/** Stage in the `/office/connect` consent & key-handoff lifecycle. */
|
|
17
|
+
export type OfficeConnectStage = 'waiting' | 'sign-in' | 'bad-request' | 'not-enabled' | 'consent' | 'connecting' | 'leaving' | 'cancelled' | 'error';
|
|
18
|
+
export declare class OfficeConnectPanelComponent extends BaseAngularComponent implements OnInit, OnChanges, OnDestroy {
|
|
19
|
+
private cdr;
|
|
20
|
+
/**
|
|
21
|
+
* Query parameters from the `/office/connect` URL (`pk` and `state`).
|
|
22
|
+
* If omitted (`null`), falls back to reading `window.location.search` in browser environments.
|
|
23
|
+
*/
|
|
24
|
+
QueryParams: OfficeConnectQueryParams | null;
|
|
25
|
+
/**
|
|
26
|
+
* Optional explicit GraphQL endpoint URL to embed in the sealed connection payload.
|
|
27
|
+
* Defaults to the active `GraphQLDataProvider`'s `ConfigData.URL`.
|
|
28
|
+
*/
|
|
29
|
+
GraphQLUrl: string | null;
|
|
30
|
+
/** Emitted when the user clicks **Sign in** so the host application can trigger its auth login. */
|
|
31
|
+
SignInRequested: EventEmitter<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Emitted with the destination `ConnectedPageUrl#...` when observed; otherwise the panel navigates
|
|
34
|
+
* via `window.location.replace(url)`.
|
|
35
|
+
*/
|
|
36
|
+
NavigateToUrl: EventEmitter<string>;
|
|
37
|
+
Stage: OfficeConnectStage;
|
|
38
|
+
StatusMessage: string;
|
|
39
|
+
ErrorMessage: string;
|
|
40
|
+
/** True once the wait has run long enough that the person may simply not be signed in. */
|
|
41
|
+
CanSignIn: boolean;
|
|
42
|
+
UserName: string;
|
|
43
|
+
UserEmail: string;
|
|
44
|
+
ServerName: string;
|
|
45
|
+
KeyLifetimeDays: number;
|
|
46
|
+
private request;
|
|
47
|
+
private status;
|
|
48
|
+
private pollTimer;
|
|
49
|
+
private initialized;
|
|
50
|
+
private started;
|
|
51
|
+
ngOnInit(): void;
|
|
52
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
53
|
+
ngOnDestroy(): void;
|
|
54
|
+
/** Asks the host application to start its sign-in flow. */
|
|
55
|
+
OnSignIn(): void;
|
|
56
|
+
/** Allows the host application to surface a sign-in startup failure inside the panel. */
|
|
57
|
+
ShowSignInError(message: string): void;
|
|
58
|
+
/** Mints the connection key, seals it to the pane's public key, and returns to the add-in page. */
|
|
59
|
+
OnConnect(): Promise<void>;
|
|
60
|
+
/** Tells the add-in the person declined, or says the window can be closed. */
|
|
61
|
+
OnCancel(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Leaves the page for the add-in's `connected.html`. Emits {@link NavigateToUrl} if observed by a
|
|
64
|
+
* parent component or test; otherwise calls `window.location.replace(url)`. Protected so subclasses
|
|
65
|
+
* in tests can also override directly.
|
|
66
|
+
*/
|
|
67
|
+
protected LeaveFor(url: string): void;
|
|
68
|
+
private evaluateRequestAndStart;
|
|
69
|
+
private readWindowQueryParams;
|
|
70
|
+
private waitForSession;
|
|
71
|
+
private checkSession;
|
|
72
|
+
private stopPolling;
|
|
73
|
+
/** The GraphQL provider has a token, endpoint, and hydrated CurrentUser once the session is restored. */
|
|
74
|
+
private isProviderReady;
|
|
75
|
+
private resolveGraphQLUrl;
|
|
76
|
+
/** Reads the add-in status fresh (not the grids' cached answer) and shows the consent card. */
|
|
77
|
+
private loadStatus;
|
|
78
|
+
private applyStatus;
|
|
79
|
+
private createConnection;
|
|
80
|
+
private handOff;
|
|
81
|
+
private leave;
|
|
82
|
+
private setStage;
|
|
83
|
+
private showError;
|
|
84
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<OfficeConnectPanelComponent, never>;
|
|
85
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<OfficeConnectPanelComponent, "mj-office-connect-panel", never, { "QueryParams": { "alias": "QueryParams"; "required": false; }; "GraphQLUrl": { "alias": "GraphQLUrl"; "required": false; }; }, { "SignInRequested": "SignInRequested"; "NavigateToUrl": "NavigateToUrl"; }, never, never, true, never>;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=office-connect-panel.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"office-connect-panel.component.d.ts","sourceRoot":"","sources":["../../src/lib/office-connect-panel.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAGH,YAAY,EAEZ,SAAS,EACT,SAAS,EACT,MAAM,EAEN,aAAa,EAEhB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGrE,OAAO,EASH,wBAAwB,EAM3B,MAAM,6BAA6B,CAAC;;AAErC,sEAAsE;AACtE,MAAM,MAAM,kBAAkB,GACxB,SAAS,GACT,SAAS,GACT,aAAa,GACb,aAAa,GACb,SAAS,GACT,YAAY,GACZ,SAAS,GACT,WAAW,GACX,OAAO,CAAC;AAgBd,qBAOa,2BAA4B,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS,EAAE,SAAS;IACzG,OAAO,CAAC,GAAG,CAA6B;IAExC;;;OAGG;IACM,WAAW,EAAE,wBAAwB,GAAG,IAAI,CAAQ;IAE7D;;;OAGG;IACM,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE1C,mGAAmG;IACzF,eAAe,qBAA4B;IAErD;;;OAGG;IACO,aAAa,uBAA8B;IAE9C,KAAK,EAAE,kBAAkB,CAAa;IACtC,aAAa,SAA+B;IAC5C,YAAY,SAAM;IACzB,0FAA0F;IACnF,SAAS,UAAS;IAClB,QAAQ,SAAM;IACd,SAAS,SAAM;IACf,UAAU,SAAM;IAChB,eAAe,SAAK;IAE3B,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,SAAS,CAA+C;IAChE,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAS;IAExB,QAAQ,IAAI,IAAI;IAKhB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAMzC,WAAW,IAAI,IAAI;IAInB,2DAA2D;IACpD,QAAQ,IAAI,IAAI;IAIvB,yFAAyF;IAClF,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI7C,mGAAmG;IACtF,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBvC,8EAA8E;IACvE,QAAQ,IAAI,IAAI;IASvB;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQrC,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,WAAW;IAOnB,yGAAyG;IACzG,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,iBAAiB;IAIzB,+FAA+F;YACjF,UAAU;IAoBxB,OAAO,CAAC,WAAW;YAcL,gBAAgB;YAShB,OAAO;IA2BrB,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,SAAS;yCAnQR,2BAA2B;2CAA3B,2BAA2B;CAuQvC"}
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Generic, router-free Excel add-in sign-in & consent panel (`<mj-office-connect-panel>`).
|
|
3
|
+
*
|
|
4
|
+
* Lives in `@memberjunction/ng-export-service` (`packages/Angular/Generic/export-service`, `"mjUILayer": "widgets"`)
|
|
5
|
+
* so ANY Angular application built on MemberJunction's Generic layer — MJ Explorer or a custom Angular host —
|
|
6
|
+
* can serve the standalone `/office/connect` endpoint without depending on `@memberjunction/ng-explorer-core`,
|
|
7
|
+
* `@angular/router`, or a specific authentication library.
|
|
8
|
+
*
|
|
9
|
+
* Host apps pass `[QueryParams]` (`pk` and `state` from the URL) and handle `(SignInRequested)` by invoking
|
|
10
|
+
* their authentication provider's login flow.
|
|
11
|
+
*/
|
|
12
|
+
import { ChangeDetectorRef, Component, EventEmitter, Input, Output, inject, } from '@angular/core';
|
|
13
|
+
import { LogError } from '@memberjunction/core';
|
|
14
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
15
|
+
import { SharedGenericModule } from '@memberjunction/ng-shared-generic';
|
|
16
|
+
import { MJButtonDirective } from '@memberjunction/ng-ui-components';
|
|
17
|
+
import { BuildOfficeHandoffUrl, DisplayNameForUser, EXCEL_HANDOFF_VERSION, ExcelAddinCreateConnectionOperation, ExcelAddinGetStatusOperation, ReadOfficeConnectRequest, SealConnectionPayload, } from '@memberjunction/excel-addin';
|
|
18
|
+
import * as i0 from "@angular/core";
|
|
19
|
+
import * as i1 from "@memberjunction/ng-shared-generic";
|
|
20
|
+
function OfficeConnectPanelComponent_Case_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
21
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
22
|
+
i0.ɵɵelementStart(0, "p", 4);
|
|
23
|
+
i0.ɵɵtext(1, "Not signed in to MemberJunction in this window?");
|
|
24
|
+
i0.ɵɵelementEnd();
|
|
25
|
+
i0.ɵɵelementStart(2, "div", 5)(3, "button", 6);
|
|
26
|
+
i0.ɵɵlistener("click", function OfficeConnectPanelComponent_Case_2_Conditional_2_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnSignIn()); });
|
|
27
|
+
i0.ɵɵelement(4, "i", 7);
|
|
28
|
+
i0.ɵɵtext(5, " Sign in ");
|
|
29
|
+
i0.ɵɵelementEnd()();
|
|
30
|
+
} }
|
|
31
|
+
function OfficeConnectPanelComponent_Case_2_Template(rf, ctx) { if (rf & 1) {
|
|
32
|
+
i0.ɵɵelementStart(0, "div", 2);
|
|
33
|
+
i0.ɵɵelement(1, "mj-loading", 3);
|
|
34
|
+
i0.ɵɵconditionalCreate(2, OfficeConnectPanelComponent_Case_2_Conditional_2_Template, 6, 0);
|
|
35
|
+
i0.ɵɵelementEnd();
|
|
36
|
+
} if (rf & 2) {
|
|
37
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
38
|
+
i0.ɵɵadvance();
|
|
39
|
+
i0.ɵɵproperty("text", ctx_r1.StatusMessage);
|
|
40
|
+
i0.ɵɵadvance();
|
|
41
|
+
i0.ɵɵconditional(ctx_r1.CanSignIn ? 2 : -1);
|
|
42
|
+
} }
|
|
43
|
+
function OfficeConnectPanelComponent_Case_3_Template(rf, ctx) { if (rf & 1) {
|
|
44
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
45
|
+
i0.ɵɵelementStart(0, "div", 2)(1, "div", 8);
|
|
46
|
+
i0.ɵɵelement(2, "i", 9);
|
|
47
|
+
i0.ɵɵelementEnd();
|
|
48
|
+
i0.ɵɵelementStart(3, "h2");
|
|
49
|
+
i0.ɵɵtext(4, "Sign in to connect Excel");
|
|
50
|
+
i0.ɵɵelementEnd();
|
|
51
|
+
i0.ɵɵelementStart(5, "p");
|
|
52
|
+
i0.ɵɵtext(6, "Sign in to MemberJunction with the account whose views and queries Excel should load.");
|
|
53
|
+
i0.ɵɵelementEnd();
|
|
54
|
+
i0.ɵɵelementStart(7, "div", 5)(8, "button", 10);
|
|
55
|
+
i0.ɵɵlistener("click", function OfficeConnectPanelComponent_Case_3_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSignIn()); });
|
|
56
|
+
i0.ɵɵelement(9, "i", 7);
|
|
57
|
+
i0.ɵɵtext(10, " Sign in ");
|
|
58
|
+
i0.ɵɵelementEnd()()();
|
|
59
|
+
} }
|
|
60
|
+
function OfficeConnectPanelComponent_Case_4_Template(rf, ctx) { if (rf & 1) {
|
|
61
|
+
i0.ɵɵelementStart(0, "div", 2)(1, "div", 11);
|
|
62
|
+
i0.ɵɵelement(2, "i", 12);
|
|
63
|
+
i0.ɵɵelementEnd();
|
|
64
|
+
i0.ɵɵelementStart(3, "h2");
|
|
65
|
+
i0.ɵɵtext(4, "This link can't connect Excel");
|
|
66
|
+
i0.ɵɵelementEnd();
|
|
67
|
+
i0.ɵɵelementStart(5, "p");
|
|
68
|
+
i0.ɵɵtext(6, "Open this page from the MemberJunction add-in in Excel by choosing ");
|
|
69
|
+
i0.ɵɵelementStart(7, "strong");
|
|
70
|
+
i0.ɵɵtext(8, "Sign in");
|
|
71
|
+
i0.ɵɵelementEnd();
|
|
72
|
+
i0.ɵɵtext(9, " there. You can close this window.");
|
|
73
|
+
i0.ɵɵelementEnd()();
|
|
74
|
+
} }
|
|
75
|
+
function OfficeConnectPanelComponent_Case_5_Template(rf, ctx) { if (rf & 1) {
|
|
76
|
+
i0.ɵɵelementStart(0, "div", 2)(1, "div", 13);
|
|
77
|
+
i0.ɵɵelement(2, "i", 9);
|
|
78
|
+
i0.ɵɵelementEnd();
|
|
79
|
+
i0.ɵɵelementStart(3, "h2");
|
|
80
|
+
i0.ɵɵtext(4, "Excel isn't turned on");
|
|
81
|
+
i0.ɵɵelementEnd();
|
|
82
|
+
i0.ɵɵelementStart(5, "p");
|
|
83
|
+
i0.ɵɵtext(6);
|
|
84
|
+
i0.ɵɵelementEnd()();
|
|
85
|
+
} if (rf & 2) {
|
|
86
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
87
|
+
i0.ɵɵadvance(6);
|
|
88
|
+
i0.ɵɵtextInterpolate1("", ctx_r1.ServerName || "This MemberJunction server", " doesn't have the Excel add-in turned on. Ask an administrator to turn it on, then sign in again from Excel. You can close this window.");
|
|
89
|
+
} }
|
|
90
|
+
function OfficeConnectPanelComponent_Case_6_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
91
|
+
i0.ɵɵelementStart(0, "span", 16);
|
|
92
|
+
i0.ɵɵtext(1);
|
|
93
|
+
i0.ɵɵelementEnd();
|
|
94
|
+
} if (rf & 2) {
|
|
95
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
96
|
+
i0.ɵɵadvance();
|
|
97
|
+
i0.ɵɵtextInterpolate(ctx_r1.UserEmail);
|
|
98
|
+
} }
|
|
99
|
+
function OfficeConnectPanelComponent_Case_6_Template(rf, ctx) { if (rf & 1) {
|
|
100
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
101
|
+
i0.ɵɵelementStart(0, "div", 2)(1, "div", 8);
|
|
102
|
+
i0.ɵɵelement(2, "i", 9);
|
|
103
|
+
i0.ɵɵelementEnd();
|
|
104
|
+
i0.ɵɵelementStart(3, "h2");
|
|
105
|
+
i0.ɵɵtext(4);
|
|
106
|
+
i0.ɵɵelementEnd();
|
|
107
|
+
i0.ɵɵelementStart(5, "div", 14)(6, "span", 15);
|
|
108
|
+
i0.ɵɵtext(7);
|
|
109
|
+
i0.ɵɵelementEnd();
|
|
110
|
+
i0.ɵɵconditionalCreate(8, OfficeConnectPanelComponent_Case_6_Conditional_8_Template, 2, 1, "span", 16);
|
|
111
|
+
i0.ɵɵelementEnd();
|
|
112
|
+
i0.ɵɵelementStart(9, "ul", 17)(10, "li");
|
|
113
|
+
i0.ɵɵtext(11, "Excel can run the saved views and queries you can already open in MemberJunction, as you.");
|
|
114
|
+
i0.ɵɵelementEnd();
|
|
115
|
+
i0.ɵɵelementStart(12, "li");
|
|
116
|
+
i0.ɵɵtext(13, "It can only read data. It can't change or delete anything.");
|
|
117
|
+
i0.ɵɵelementEnd();
|
|
118
|
+
i0.ɵɵelementStart(14, "li");
|
|
119
|
+
i0.ɵɵtext(15);
|
|
120
|
+
i0.ɵɵelementEnd()();
|
|
121
|
+
i0.ɵɵelementStart(16, "div", 5)(17, "button", 10);
|
|
122
|
+
i0.ɵɵlistener("click", function OfficeConnectPanelComponent_Case_6_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnConnect()); });
|
|
123
|
+
i0.ɵɵelement(18, "i", 18);
|
|
124
|
+
i0.ɵɵtext(19, " Connect Excel ");
|
|
125
|
+
i0.ɵɵelementEnd();
|
|
126
|
+
i0.ɵɵelementStart(20, "button", 6);
|
|
127
|
+
i0.ɵɵlistener("click", function OfficeConnectPanelComponent_Case_6_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnCancel()); });
|
|
128
|
+
i0.ɵɵtext(21, "Cancel");
|
|
129
|
+
i0.ɵɵelementEnd()()();
|
|
130
|
+
} if (rf & 2) {
|
|
131
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
132
|
+
i0.ɵɵadvance(4);
|
|
133
|
+
i0.ɵɵtextInterpolate1("Connect Excel to ", ctx_r1.ServerName || "MemberJunction");
|
|
134
|
+
i0.ɵɵadvance(3);
|
|
135
|
+
i0.ɵɵtextInterpolate(ctx_r1.UserName);
|
|
136
|
+
i0.ɵɵadvance();
|
|
137
|
+
i0.ɵɵconditional(ctx_r1.UserEmail && ctx_r1.UserEmail !== ctx_r1.UserName ? 8 : -1);
|
|
138
|
+
i0.ɵɵadvance(7);
|
|
139
|
+
i0.ɵɵtextInterpolate2("The connection lasts ", ctx_r1.KeyLifetimeDays, " ", ctx_r1.KeyLifetimeDays === 1 ? "day" : "days", ". You can disconnect it sooner on the API Keys page.");
|
|
140
|
+
} }
|
|
141
|
+
function OfficeConnectPanelComponent_Case_7_Template(rf, ctx) { if (rf & 1) {
|
|
142
|
+
i0.ɵɵelementStart(0, "div", 2);
|
|
143
|
+
i0.ɵɵelement(1, "mj-loading", 3);
|
|
144
|
+
i0.ɵɵelementEnd();
|
|
145
|
+
} if (rf & 2) {
|
|
146
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
147
|
+
i0.ɵɵadvance();
|
|
148
|
+
i0.ɵɵproperty("text", ctx_r1.StatusMessage);
|
|
149
|
+
} }
|
|
150
|
+
function OfficeConnectPanelComponent_Case_8_Template(rf, ctx) { if (rf & 1) {
|
|
151
|
+
i0.ɵɵelementStart(0, "div", 2);
|
|
152
|
+
i0.ɵɵelement(1, "mj-loading", 3);
|
|
153
|
+
i0.ɵɵelementEnd();
|
|
154
|
+
} if (rf & 2) {
|
|
155
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
156
|
+
i0.ɵɵadvance();
|
|
157
|
+
i0.ɵɵproperty("text", ctx_r1.StatusMessage);
|
|
158
|
+
} }
|
|
159
|
+
function OfficeConnectPanelComponent_Case_9_Template(rf, ctx) { if (rf & 1) {
|
|
160
|
+
i0.ɵɵelementStart(0, "div", 2)(1, "div", 13);
|
|
161
|
+
i0.ɵɵelement(2, "i", 19);
|
|
162
|
+
i0.ɵɵelementEnd();
|
|
163
|
+
i0.ɵɵelementStart(3, "h2");
|
|
164
|
+
i0.ɵɵtext(4, "Excel wasn't connected");
|
|
165
|
+
i0.ɵɵelementEnd();
|
|
166
|
+
i0.ɵɵelementStart(5, "p");
|
|
167
|
+
i0.ɵɵtext(6, "You can close this window.");
|
|
168
|
+
i0.ɵɵelementEnd()();
|
|
169
|
+
} }
|
|
170
|
+
function OfficeConnectPanelComponent_Case_10_Template(rf, ctx) { if (rf & 1) {
|
|
171
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
172
|
+
i0.ɵɵelementStart(0, "div", 2)(1, "div", 11);
|
|
173
|
+
i0.ɵɵelement(2, "i", 12);
|
|
174
|
+
i0.ɵɵelementEnd();
|
|
175
|
+
i0.ɵɵelementStart(3, "h2");
|
|
176
|
+
i0.ɵɵtext(4, "Excel wasn't connected");
|
|
177
|
+
i0.ɵɵelementEnd();
|
|
178
|
+
i0.ɵɵelementStart(5, "p", 20);
|
|
179
|
+
i0.ɵɵtext(6);
|
|
180
|
+
i0.ɵɵelementEnd();
|
|
181
|
+
i0.ɵɵelementStart(7, "div", 5)(8, "button", 6);
|
|
182
|
+
i0.ɵɵlistener("click", function OfficeConnectPanelComponent_Case_10_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnCancel()); });
|
|
183
|
+
i0.ɵɵtext(9, "Cancel");
|
|
184
|
+
i0.ɵɵelementEnd()()();
|
|
185
|
+
} if (rf & 2) {
|
|
186
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
187
|
+
i0.ɵɵadvance(6);
|
|
188
|
+
i0.ɵɵtextInterpolate(ctx_r1.ErrorMessage);
|
|
189
|
+
} }
|
|
190
|
+
/** How long to wait for the session before giving up and asking the person to sign in. */
|
|
191
|
+
const MAX_WAIT_TIME_MS = 30000;
|
|
192
|
+
/** How long to wait before offering a sign-in button beside the wait spinner. */
|
|
193
|
+
const SIGN_IN_OFFER_MS = 4000;
|
|
194
|
+
const POLL_INTERVAL_MS = 500;
|
|
195
|
+
export class OfficeConnectPanelComponent extends BaseAngularComponent {
|
|
196
|
+
cdr = inject(ChangeDetectorRef);
|
|
197
|
+
/**
|
|
198
|
+
* Query parameters from the `/office/connect` URL (`pk` and `state`).
|
|
199
|
+
* If omitted (`null`), falls back to reading `window.location.search` in browser environments.
|
|
200
|
+
*/
|
|
201
|
+
QueryParams = null;
|
|
202
|
+
/**
|
|
203
|
+
* Optional explicit GraphQL endpoint URL to embed in the sealed connection payload.
|
|
204
|
+
* Defaults to the active `GraphQLDataProvider`'s `ConfigData.URL`.
|
|
205
|
+
*/
|
|
206
|
+
GraphQLUrl = null;
|
|
207
|
+
/** Emitted when the user clicks **Sign in** so the host application can trigger its auth login. */
|
|
208
|
+
SignInRequested = new EventEmitter();
|
|
209
|
+
/**
|
|
210
|
+
* Emitted with the destination `ConnectedPageUrl#...` when observed; otherwise the panel navigates
|
|
211
|
+
* via `window.location.replace(url)`.
|
|
212
|
+
*/
|
|
213
|
+
NavigateToUrl = new EventEmitter();
|
|
214
|
+
Stage = 'waiting';
|
|
215
|
+
StatusMessage = 'Restoring your session...';
|
|
216
|
+
ErrorMessage = '';
|
|
217
|
+
/** True once the wait has run long enough that the person may simply not be signed in. */
|
|
218
|
+
CanSignIn = false;
|
|
219
|
+
UserName = '';
|
|
220
|
+
UserEmail = '';
|
|
221
|
+
ServerName = '';
|
|
222
|
+
KeyLifetimeDays = 0;
|
|
223
|
+
request = null;
|
|
224
|
+
status = null;
|
|
225
|
+
pollTimer = null;
|
|
226
|
+
initialized = false;
|
|
227
|
+
started = false;
|
|
228
|
+
ngOnInit() {
|
|
229
|
+
this.initialized = true;
|
|
230
|
+
this.evaluateRequestAndStart();
|
|
231
|
+
}
|
|
232
|
+
ngOnChanges(changes) {
|
|
233
|
+
if (this.initialized && 'QueryParams' in changes && !this.started) {
|
|
234
|
+
this.evaluateRequestAndStart();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
ngOnDestroy() {
|
|
238
|
+
this.stopPolling();
|
|
239
|
+
}
|
|
240
|
+
/** Asks the host application to start its sign-in flow. */
|
|
241
|
+
OnSignIn() {
|
|
242
|
+
this.SignInRequested.emit();
|
|
243
|
+
}
|
|
244
|
+
/** Allows the host application to surface a sign-in startup failure inside the panel. */
|
|
245
|
+
ShowSignInError(message) {
|
|
246
|
+
this.showError(message);
|
|
247
|
+
}
|
|
248
|
+
/** Mints the connection key, seals it to the pane's public key, and returns to the add-in page. */
|
|
249
|
+
async OnConnect() {
|
|
250
|
+
if (this.Stage !== 'consent' || !this.request || !this.status) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
this.setStage('connecting', 'Connecting Excel...');
|
|
254
|
+
try {
|
|
255
|
+
const connection = await this.createConnection();
|
|
256
|
+
if (connection) {
|
|
257
|
+
await this.handOff(connection, this.request, this.status);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
catch (e) {
|
|
261
|
+
const detail = e instanceof Error ? e.message : String(e);
|
|
262
|
+
LogError(`Excel connect failed: ${detail}`);
|
|
263
|
+
this.showError(`Excel couldn't be connected: ${detail}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/** Tells the add-in the person declined, or says the window can be closed. */
|
|
267
|
+
OnCancel() {
|
|
268
|
+
const url = this.status?.Enabled ? BuildOfficeHandoffUrl(this.status.ConnectedPageUrl, 'cancelled') : null;
|
|
269
|
+
if (url) {
|
|
270
|
+
this.leave(url);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
this.setStage('cancelled');
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Leaves the page for the add-in's `connected.html`. Emits {@link NavigateToUrl} if observed by a
|
|
278
|
+
* parent component or test; otherwise calls `window.location.replace(url)`. Protected so subclasses
|
|
279
|
+
* in tests can also override directly.
|
|
280
|
+
*/
|
|
281
|
+
LeaveFor(url) {
|
|
282
|
+
if (this.NavigateToUrl.observed) {
|
|
283
|
+
this.NavigateToUrl.emit(url);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
window.location.replace(url);
|
|
287
|
+
}
|
|
288
|
+
evaluateRequestAndStart() {
|
|
289
|
+
this.stopPolling();
|
|
290
|
+
const params = this.QueryParams ?? this.readWindowQueryParams();
|
|
291
|
+
this.request = ReadOfficeConnectRequest(params);
|
|
292
|
+
if (!this.request) {
|
|
293
|
+
this.setStage('bad-request');
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
this.Stage = 'waiting';
|
|
297
|
+
this.StatusMessage = 'Restoring your session...';
|
|
298
|
+
this.waitForSession();
|
|
299
|
+
}
|
|
300
|
+
readWindowQueryParams() {
|
|
301
|
+
if (typeof window === 'undefined' || !window.location?.search) {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
const search = new URLSearchParams(window.location.search);
|
|
305
|
+
return {
|
|
306
|
+
pk: search.get('pk'),
|
|
307
|
+
state: search.get('state'),
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
waitForSession() {
|
|
311
|
+
if (this.isProviderReady()) {
|
|
312
|
+
void this.loadStatus();
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
const startedAt = Date.now();
|
|
316
|
+
this.pollTimer = setInterval(() => this.checkSession(startedAt), POLL_INTERVAL_MS);
|
|
317
|
+
}
|
|
318
|
+
checkSession(startedAt) {
|
|
319
|
+
const elapsed = Date.now() - startedAt;
|
|
320
|
+
if (this.isProviderReady()) {
|
|
321
|
+
this.stopPolling();
|
|
322
|
+
void this.loadStatus();
|
|
323
|
+
}
|
|
324
|
+
else if (elapsed >= MAX_WAIT_TIME_MS) {
|
|
325
|
+
this.stopPolling();
|
|
326
|
+
this.setStage('sign-in');
|
|
327
|
+
}
|
|
328
|
+
else if (elapsed >= SIGN_IN_OFFER_MS && !this.CanSignIn) {
|
|
329
|
+
this.CanSignIn = true;
|
|
330
|
+
this.cdr.detectChanges();
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
stopPolling() {
|
|
334
|
+
if (this.pollTimer) {
|
|
335
|
+
clearInterval(this.pollTimer);
|
|
336
|
+
this.pollTimer = null;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
/** The GraphQL provider has a token, endpoint, and hydrated CurrentUser once the session is restored. */
|
|
340
|
+
isProviderReady() {
|
|
341
|
+
try {
|
|
342
|
+
const provider = this.ProviderToUse;
|
|
343
|
+
const url = this.resolveGraphQLUrl(provider);
|
|
344
|
+
return Boolean(provider?.ConfigData?.Token && url && provider?.CurrentUser);
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
resolveGraphQLUrl(provider) {
|
|
351
|
+
return (this.GraphQLUrl?.trim() || provider?.ConfigData?.URL || '').trim();
|
|
352
|
+
}
|
|
353
|
+
/** Reads the add-in status fresh (not the grids' cached answer) and shows the consent card. */
|
|
354
|
+
async loadStatus() {
|
|
355
|
+
if (this.started) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
this.started = true;
|
|
359
|
+
this.setStage('waiting', 'Checking Excel is turned on...');
|
|
360
|
+
try {
|
|
361
|
+
const result = await new ExcelAddinGetStatusOperation().Execute({}, { provider: this.ProviderToUse });
|
|
362
|
+
if (!result.Success || !result.Output) {
|
|
363
|
+
this.showError(result.ErrorMessage || 'MemberJunction could not say whether Excel is turned on.');
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
this.applyStatus(result.Output);
|
|
367
|
+
}
|
|
368
|
+
catch (e) {
|
|
369
|
+
const detail = e instanceof Error ? e.message : String(e);
|
|
370
|
+
LogError(`Excel add-in status check failed: ${detail}`);
|
|
371
|
+
this.showError(`MemberJunction could not say whether Excel is turned on: ${detail}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
applyStatus(status) {
|
|
375
|
+
this.status = status;
|
|
376
|
+
this.ServerName = status.ServerName;
|
|
377
|
+
this.KeyLifetimeDays = status.KeyLifetimeDays;
|
|
378
|
+
if (!status.Enabled) {
|
|
379
|
+
this.setStage('not-enabled');
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const user = this.ProviderToUse.CurrentUser;
|
|
383
|
+
this.UserName = DisplayNameForUser(user);
|
|
384
|
+
this.UserEmail = user?.Email ?? '';
|
|
385
|
+
this.setStage('consent');
|
|
386
|
+
}
|
|
387
|
+
async createConnection() {
|
|
388
|
+
const result = await new ExcelAddinCreateConnectionOperation().Execute({}, { provider: this.ProviderToUse });
|
|
389
|
+
if (!result.Success || !result.Output) {
|
|
390
|
+
this.showError(result.ErrorMessage || 'Excel couldn\'t be connected.');
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
return result.Output;
|
|
394
|
+
}
|
|
395
|
+
async handOff(connection, request, status) {
|
|
396
|
+
const provider = this.ProviderToUse;
|
|
397
|
+
const payload = {
|
|
398
|
+
Version: EXCEL_HANDOFF_VERSION,
|
|
399
|
+
State: request.State,
|
|
400
|
+
APIKey: connection.APIKey,
|
|
401
|
+
GraphQLUrl: this.resolveGraphQLUrl(provider),
|
|
402
|
+
UserName: this.UserName,
|
|
403
|
+
UserEmail: this.UserEmail,
|
|
404
|
+
ExpiresAt: connection.ExpiresAt || null,
|
|
405
|
+
};
|
|
406
|
+
const sealed = await SealConnectionPayload(request.PublicKey, payload);
|
|
407
|
+
const outcome = { Sealed: sealed };
|
|
408
|
+
const url = BuildOfficeHandoffUrl(status.ConnectedPageUrl, outcome);
|
|
409
|
+
if (!url) {
|
|
410
|
+
this.showError('This MemberJunction server reports an add-in address that isn\'t a web address. Ask an administrator to check the Excel add-in settings.');
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
this.leave(url);
|
|
414
|
+
}
|
|
415
|
+
leave(url) {
|
|
416
|
+
this.setStage('leaving', 'Returning to Excel...');
|
|
417
|
+
this.LeaveFor(url);
|
|
418
|
+
}
|
|
419
|
+
setStage(stage, statusMessage) {
|
|
420
|
+
this.Stage = stage;
|
|
421
|
+
if (statusMessage) {
|
|
422
|
+
this.StatusMessage = statusMessage;
|
|
423
|
+
}
|
|
424
|
+
this.cdr.detectChanges();
|
|
425
|
+
}
|
|
426
|
+
showError(message) {
|
|
427
|
+
this.ErrorMessage = message;
|
|
428
|
+
this.setStage('error');
|
|
429
|
+
}
|
|
430
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵOfficeConnectPanelComponent_BaseFactory; return function OfficeConnectPanelComponent_Factory(__ngFactoryType__) { return (ɵOfficeConnectPanelComponent_BaseFactory || (ɵOfficeConnectPanelComponent_BaseFactory = i0.ɵɵgetInheritedFactory(OfficeConnectPanelComponent)))(__ngFactoryType__ || OfficeConnectPanelComponent); }; })();
|
|
431
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: OfficeConnectPanelComponent, selectors: [["mj-office-connect-panel"]], inputs: { QueryParams: "QueryParams", GraphQLUrl: "GraphQLUrl" }, outputs: { SignInRequested: "SignInRequested", NavigateToUrl: "NavigateToUrl" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 11, vars: 1, consts: [[1, "office-connect-container"], [1, "office-connect-card"], [1, "office-connect-status"], [3, "text"], [1, "office-connect-hint"], [1, "button-group"], ["mjButton", "", "variant", "secondary", 3, "click"], [1, "fa-solid", "fa-arrow-right-to-bracket"], [1, "icon-container", "brand-icon"], [1, "fa-solid", "fa-table-cells"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "icon-container", "error-icon"], [1, "fa-solid", "fa-circle-exclamation"], [1, "icon-container", "muted-icon"], [1, "office-connect-user"], [1, "office-connect-user-name"], [1, "office-connect-user-email"], [1, "office-connect-terms"], [1, "fa-solid", "fa-link"], [1, "fa-solid", "fa-circle-xmark"], [1, "error-message"]], template: function OfficeConnectPanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
432
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1);
|
|
433
|
+
i0.ɵɵconditionalCreate(2, OfficeConnectPanelComponent_Case_2_Template, 3, 2, "div", 2)(3, OfficeConnectPanelComponent_Case_3_Template, 11, 0, "div", 2)(4, OfficeConnectPanelComponent_Case_4_Template, 10, 0, "div", 2)(5, OfficeConnectPanelComponent_Case_5_Template, 7, 1, "div", 2)(6, OfficeConnectPanelComponent_Case_6_Template, 22, 5, "div", 2)(7, OfficeConnectPanelComponent_Case_7_Template, 2, 1, "div", 2)(8, OfficeConnectPanelComponent_Case_8_Template, 2, 1, "div", 2)(9, OfficeConnectPanelComponent_Case_9_Template, 7, 0, "div", 2)(10, OfficeConnectPanelComponent_Case_10_Template, 10, 1, "div", 2);
|
|
434
|
+
i0.ɵɵelementEnd()();
|
|
435
|
+
} if (rf & 2) {
|
|
436
|
+
let tmp_0_0;
|
|
437
|
+
i0.ɵɵadvance(2);
|
|
438
|
+
i0.ɵɵconditional((tmp_0_0 = ctx.Stage) === "waiting" ? 2 : tmp_0_0 === "sign-in" ? 3 : tmp_0_0 === "bad-request" ? 4 : tmp_0_0 === "not-enabled" ? 5 : tmp_0_0 === "consent" ? 6 : tmp_0_0 === "connecting" ? 7 : tmp_0_0 === "leaving" ? 8 : tmp_0_0 === "cancelled" ? 9 : tmp_0_0 === "error" ? 10 : -1);
|
|
439
|
+
} }, dependencies: [SharedGenericModule, i1.LoadingComponent, MJButtonDirective], styles: [".office-connect-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n background: var(--mj-bg-page);\n padding: var(--mj-space-4);\n}\n\n.office-connect-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n padding: var(--mj-space-8);\n border-radius: var(--mj-radius-xl);\n box-shadow: var(--mj-shadow-xl);\n text-align: center;\n max-width: 460px;\n width: 100%;\n}\n\n.office-connect-status[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--mj-space-4);\n}\n\n.office-connect-status[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.office-connect-status[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-muted);\n line-height: 1.6;\n}\n\n.office-connect-hint[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n\n.icon-container[_ngcontent-%COMP%] {\n font-size: 2.75rem;\n}\n\n.brand-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.muted-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\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.office-connect-user[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n}\n\n.office-connect-user-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.office-connect-user-email[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n color: var(--mj-text-secondary);\n}\n\n.office-connect-terms[_ngcontent-%COMP%] {\n margin: 0;\n padding: var(--mj-space-4) var(--mj-space-4) var(--mj-space-4) var(--mj-space-8);\n text-align: left;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n}\n\n.office-connect-terms[_ngcontent-%COMP%] li[_ngcontent-%COMP%] + li[_ngcontent-%COMP%] {\n margin-top: var(--mj-space-2);\n}\n\n.button-group[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-3);\n margin-top: var(--mj-space-2);\n flex-wrap: wrap;\n justify-content: center;\n}"] });
|
|
440
|
+
}
|
|
441
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(OfficeConnectPanelComponent, [{
|
|
442
|
+
type: Component,
|
|
443
|
+
args: [{ standalone: true, selector: 'mj-office-connect-panel', imports: [SharedGenericModule, MJButtonDirective], template: "<div class=\"office-connect-container\">\n <div class=\"office-connect-card\">\n @switch (Stage) {\n @case ('waiting') {\n <div class=\"office-connect-status\">\n <mj-loading [text]=\"StatusMessage\"></mj-loading>\n @if (CanSignIn) {\n <p class=\"office-connect-hint\">Not signed in to MemberJunction in this window?</p>\n <div class=\"button-group\">\n <button mjButton variant=\"secondary\" (click)=\"OnSignIn()\">\n <i class=\"fa-solid fa-arrow-right-to-bracket\"></i>\n Sign in\n </button>\n </div>\n }\n </div>\n }\n\n @case ('sign-in') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container brand-icon\"><i class=\"fa-solid fa-table-cells\"></i></div>\n <h2>Sign in to connect Excel</h2>\n <p>Sign in to MemberJunction with the account whose views and queries Excel should load.</p>\n <div class=\"button-group\">\n <button mjButton variant=\"primary\" (click)=\"OnSignIn()\">\n <i class=\"fa-solid fa-arrow-right-to-bracket\"></i>\n Sign in\n </button>\n </div>\n </div>\n }\n\n @case ('bad-request') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container error-icon\"><i class=\"fa-solid fa-circle-exclamation\"></i></div>\n <h2>This link can't connect Excel</h2>\n <p>Open this page from the MemberJunction add-in in Excel by choosing <strong>Sign in</strong> there. You can close this window.</p>\n </div>\n }\n\n @case ('not-enabled') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container muted-icon\"><i class=\"fa-solid fa-table-cells\"></i></div>\n <h2>Excel isn't turned on</h2>\n <p>{{ ServerName || 'This MemberJunction server' }} doesn't have the Excel add-in turned on. Ask an administrator to turn it on, then sign in again from Excel. You can close this window.</p>\n </div>\n }\n\n @case ('consent') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container brand-icon\"><i class=\"fa-solid fa-table-cells\"></i></div>\n <h2>Connect Excel to {{ ServerName || 'MemberJunction' }}</h2>\n <div class=\"office-connect-user\">\n <span class=\"office-connect-user-name\">{{ UserName }}</span>\n @if (UserEmail && UserEmail !== UserName) {\n <span class=\"office-connect-user-email\">{{ UserEmail }}</span>\n }\n </div>\n <ul class=\"office-connect-terms\">\n <li>Excel can run the saved views and queries you can already open in MemberJunction, as you.</li>\n <li>It can only read data. It can't change or delete anything.</li>\n <li>The connection lasts {{ KeyLifetimeDays }} {{ KeyLifetimeDays === 1 ? 'day' : 'days' }}. You can disconnect it sooner on the API Keys page.</li>\n </ul>\n <div class=\"button-group\">\n <button mjButton variant=\"primary\" (click)=\"OnConnect()\">\n <i class=\"fa-solid fa-link\"></i>\n Connect Excel\n </button>\n <button mjButton variant=\"secondary\" (click)=\"OnCancel()\">Cancel</button>\n </div>\n </div>\n }\n\n @case ('connecting') {\n <div class=\"office-connect-status\">\n <mj-loading [text]=\"StatusMessage\"></mj-loading>\n </div>\n }\n\n @case ('leaving') {\n <div class=\"office-connect-status\">\n <mj-loading [text]=\"StatusMessage\"></mj-loading>\n </div>\n }\n\n @case ('cancelled') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container muted-icon\"><i class=\"fa-solid fa-circle-xmark\"></i></div>\n <h2>Excel wasn't connected</h2>\n <p>You can close this window.</p>\n </div>\n }\n\n @case ('error') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container error-icon\"><i class=\"fa-solid fa-circle-exclamation\"></i></div>\n <h2>Excel wasn't connected</h2>\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n <button mjButton variant=\"secondary\" (click)=\"OnCancel()\">Cancel</button>\n </div>\n </div>\n }\n }\n </div>\n</div>\n", styles: [".office-connect-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n background: var(--mj-bg-page);\n padding: var(--mj-space-4);\n}\n\n.office-connect-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n padding: var(--mj-space-8);\n border-radius: var(--mj-radius-xl);\n box-shadow: var(--mj-shadow-xl);\n text-align: center;\n max-width: 460px;\n width: 100%;\n}\n\n.office-connect-status {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--mj-space-4);\n}\n\n.office-connect-status h2 {\n margin: 0;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.office-connect-status p {\n margin: 0;\n color: var(--mj-text-muted);\n line-height: 1.6;\n}\n\n.office-connect-hint {\n font-size: 0.875rem;\n}\n\n.icon-container {\n font-size: 2.75rem;\n}\n\n.brand-icon {\n color: var(--mj-brand-primary);\n}\n\n.muted-icon {\n color: var(--mj-text-muted);\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.office-connect-user {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n}\n\n.office-connect-user-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.office-connect-user-email {\n font-size: 0.875rem;\n color: var(--mj-text-secondary);\n}\n\n.office-connect-terms {\n margin: 0;\n padding: var(--mj-space-4) var(--mj-space-4) var(--mj-space-4) var(--mj-space-8);\n text-align: left;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n}\n\n.office-connect-terms li + li {\n margin-top: var(--mj-space-2);\n}\n\n.button-group {\n display: flex;\n gap: var(--mj-space-3);\n margin-top: var(--mj-space-2);\n flex-wrap: wrap;\n justify-content: center;\n}\n"] }]
|
|
444
|
+
}], null, { QueryParams: [{
|
|
445
|
+
type: Input
|
|
446
|
+
}], GraphQLUrl: [{
|
|
447
|
+
type: Input
|
|
448
|
+
}], SignInRequested: [{
|
|
449
|
+
type: Output
|
|
450
|
+
}], NavigateToUrl: [{
|
|
451
|
+
type: Output
|
|
452
|
+
}] }); })();
|
|
453
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(OfficeConnectPanelComponent, { className: "OfficeConnectPanelComponent", filePath: "src/lib/office-connect-panel.component.ts", lineNumber: 78 }); })();
|
|
454
|
+
//# sourceMappingURL=office-connect-panel.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"office-connect-panel.component.js","sourceRoot":"","sources":["../../src/lib/office-connect-panel.component.ts","../../src/lib/office-connect-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Generic, router-free Excel add-in sign-in & consent panel (`<mj-office-connect-panel>`).\n *\n * Lives in `@memberjunction/ng-export-service` (`packages/Angular/Generic/export-service`, `\"mjUILayer\": \"widgets\"`)\n * so ANY Angular application built on MemberJunction's Generic layer — MJ Explorer or a custom Angular host —\n * can serve the standalone `/office/connect` endpoint without depending on `@memberjunction/ng-explorer-core`,\n * `@angular/router`, or a specific authentication library.\n *\n * Host apps pass `[QueryParams]` (`pk` and `state` from the URL) and handle `(SignInRequested)` by invoking\n * their authentication provider's login flow.\n */\nimport {\n ChangeDetectorRef,\n Component,\n EventEmitter,\n Input,\n OnChanges,\n OnDestroy,\n OnInit,\n Output,\n SimpleChanges,\n inject,\n} from '@angular/core';\nimport { LogError } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { MJButtonDirective } from '@memberjunction/ng-ui-components';\nimport {\n BuildOfficeHandoffUrl,\n DisplayNameForUser,\n EXCEL_HANDOFF_VERSION,\n ExcelAddinCreateConnectionOperation,\n ExcelAddinCreateConnectionOutput,\n ExcelAddinGetStatusOperation,\n ExcelAddinStatusOutput,\n ExcelConnectionPayload,\n OfficeConnectQueryParams,\n OfficeConnectRequest,\n OfficeConnectUser,\n OfficeHandoffOutcome,\n ReadOfficeConnectRequest,\n SealConnectionPayload,\n} from '@memberjunction/excel-addin';\n\n/** Stage in the `/office/connect` consent & key-handoff lifecycle. */\nexport type OfficeConnectStage =\n | 'waiting'\n | 'sign-in'\n | 'bad-request'\n | 'not-enabled'\n | 'consent'\n | 'connecting'\n | 'leaving'\n | 'cancelled'\n | 'error';\n\ninterface AuthenticatedProviderView {\n ConfigData?: {\n Token?: string;\n URL?: string;\n };\n CurrentUser?: OfficeConnectUser | null;\n}\n\n/** How long to wait for the session before giving up and asking the person to sign in. */\nconst MAX_WAIT_TIME_MS = 30000;\n/** How long to wait before offering a sign-in button beside the wait spinner. */\nconst SIGN_IN_OFFER_MS = 4000;\nconst POLL_INTERVAL_MS = 500;\n\n@Component({\n standalone: true,\n selector: 'mj-office-connect-panel',\n imports: [SharedGenericModule, MJButtonDirective],\n templateUrl: './office-connect-panel.component.html',\n styleUrls: ['./office-connect-panel.component.css'],\n})\nexport class OfficeConnectPanelComponent extends BaseAngularComponent implements OnInit, OnChanges, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n /**\n * Query parameters from the `/office/connect` URL (`pk` and `state`).\n * If omitted (`null`), falls back to reading `window.location.search` in browser environments.\n */\n @Input() QueryParams: OfficeConnectQueryParams | null = null;\n\n /**\n * Optional explicit GraphQL endpoint URL to embed in the sealed connection payload.\n * Defaults to the active `GraphQLDataProvider`'s `ConfigData.URL`.\n */\n @Input() GraphQLUrl: string | null = null;\n\n /** Emitted when the user clicks **Sign in** so the host application can trigger its auth login. */\n @Output() SignInRequested = new EventEmitter<void>();\n\n /**\n * Emitted with the destination `ConnectedPageUrl#...` when observed; otherwise the panel navigates\n * via `window.location.replace(url)`.\n */\n @Output() NavigateToUrl = new EventEmitter<string>();\n\n public Stage: OfficeConnectStage = 'waiting';\n public StatusMessage = 'Restoring your session...';\n public ErrorMessage = '';\n /** True once the wait has run long enough that the person may simply not be signed in. */\n public CanSignIn = false;\n public UserName = '';\n public UserEmail = '';\n public ServerName = '';\n public KeyLifetimeDays = 0;\n\n private request: OfficeConnectRequest | null = null;\n private status: ExcelAddinStatusOutput | null = null;\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n private initialized = false;\n private started = false;\n\n ngOnInit(): void {\n this.initialized = true;\n this.evaluateRequestAndStart();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (this.initialized && 'QueryParams' in changes && !this.started) {\n this.evaluateRequestAndStart();\n }\n }\n\n ngOnDestroy(): void {\n this.stopPolling();\n }\n\n /** Asks the host application to start its sign-in flow. */\n public OnSignIn(): void {\n this.SignInRequested.emit();\n }\n\n /** Allows the host application to surface a sign-in startup failure inside the panel. */\n public ShowSignInError(message: string): void {\n this.showError(message);\n }\n\n /** Mints the connection key, seals it to the pane's public key, and returns to the add-in page. */\n public async OnConnect(): Promise<void> {\n if (this.Stage !== 'consent' || !this.request || !this.status) {\n return;\n }\n this.setStage('connecting', 'Connecting Excel...');\n try {\n const connection = await this.createConnection();\n if (connection) {\n await this.handOff(connection, this.request, this.status);\n }\n } catch (e) {\n const detail = e instanceof Error ? e.message : String(e);\n LogError(`Excel connect failed: ${detail}`);\n this.showError(`Excel couldn't be connected: ${detail}`);\n }\n }\n\n /** Tells the add-in the person declined, or says the window can be closed. */\n public OnCancel(): void {\n const url = this.status?.Enabled ? BuildOfficeHandoffUrl(this.status.ConnectedPageUrl, 'cancelled') : null;\n if (url) {\n this.leave(url);\n } else {\n this.setStage('cancelled');\n }\n }\n\n /**\n * Leaves the page for the add-in's `connected.html`. Emits {@link NavigateToUrl} if observed by a\n * parent component or test; otherwise calls `window.location.replace(url)`. Protected so subclasses\n * in tests can also override directly.\n */\n protected LeaveFor(url: string): void {\n if (this.NavigateToUrl.observed) {\n this.NavigateToUrl.emit(url);\n return;\n }\n window.location.replace(url);\n }\n\n private evaluateRequestAndStart(): void {\n this.stopPolling();\n const params = this.QueryParams ?? this.readWindowQueryParams();\n this.request = ReadOfficeConnectRequest(params);\n if (!this.request) {\n this.setStage('bad-request');\n return;\n }\n this.Stage = 'waiting';\n this.StatusMessage = 'Restoring your session...';\n this.waitForSession();\n }\n\n private readWindowQueryParams(): OfficeConnectQueryParams | null {\n if (typeof window === 'undefined' || !window.location?.search) {\n return null;\n }\n const search = new URLSearchParams(window.location.search);\n return {\n pk: search.get('pk'),\n state: search.get('state'),\n };\n }\n\n private waitForSession(): void {\n if (this.isProviderReady()) {\n void this.loadStatus();\n return;\n }\n const startedAt = Date.now();\n this.pollTimer = setInterval(() => this.checkSession(startedAt), POLL_INTERVAL_MS);\n }\n\n private checkSession(startedAt: number): void {\n const elapsed = Date.now() - startedAt;\n if (this.isProviderReady()) {\n this.stopPolling();\n void this.loadStatus();\n } else if (elapsed >= MAX_WAIT_TIME_MS) {\n this.stopPolling();\n this.setStage('sign-in');\n } else if (elapsed >= SIGN_IN_OFFER_MS && !this.CanSignIn) {\n this.CanSignIn = true;\n this.cdr.detectChanges();\n }\n }\n\n private stopPolling(): void {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /** The GraphQL provider has a token, endpoint, and hydrated CurrentUser once the session is restored. */\n private isProviderReady(): boolean {\n try {\n const provider = this.ProviderToUse as AuthenticatedProviderView;\n const url = this.resolveGraphQLUrl(provider);\n return Boolean(provider?.ConfigData?.Token && url && provider?.CurrentUser);\n } catch {\n return false;\n }\n }\n\n private resolveGraphQLUrl(provider: AuthenticatedProviderView): string {\n return (this.GraphQLUrl?.trim() || provider?.ConfigData?.URL || '').trim();\n }\n\n /** Reads the add-in status fresh (not the grids' cached answer) and shows the consent card. */\n private async loadStatus(): Promise<void> {\n if (this.started) {\n return;\n }\n this.started = true;\n this.setStage('waiting', 'Checking Excel is turned on...');\n try {\n const result = await new ExcelAddinGetStatusOperation().Execute({}, { provider: this.ProviderToUse });\n if (!result.Success || !result.Output) {\n this.showError(result.ErrorMessage || 'MemberJunction could not say whether Excel is turned on.');\n return;\n }\n this.applyStatus(result.Output);\n } catch (e) {\n const detail = e instanceof Error ? e.message : String(e);\n LogError(`Excel add-in status check failed: ${detail}`);\n this.showError(`MemberJunction could not say whether Excel is turned on: ${detail}`);\n }\n }\n\n private applyStatus(status: ExcelAddinStatusOutput): void {\n this.status = status;\n this.ServerName = status.ServerName;\n this.KeyLifetimeDays = status.KeyLifetimeDays;\n if (!status.Enabled) {\n this.setStage('not-enabled');\n return;\n }\n const user = this.ProviderToUse.CurrentUser;\n this.UserName = DisplayNameForUser(user);\n this.UserEmail = user?.Email ?? '';\n this.setStage('consent');\n }\n\n private async createConnection(): Promise<ExcelAddinCreateConnectionOutput | null> {\n const result = await new ExcelAddinCreateConnectionOperation().Execute({}, { provider: this.ProviderToUse });\n if (!result.Success || !result.Output) {\n this.showError(result.ErrorMessage || 'Excel couldn\\'t be connected.');\n return null;\n }\n return result.Output;\n }\n\n private async handOff(\n connection: ExcelAddinCreateConnectionOutput,\n request: OfficeConnectRequest,\n status: ExcelAddinStatusOutput,\n ): Promise<void> {\n const provider = this.ProviderToUse as AuthenticatedProviderView;\n const payload: ExcelConnectionPayload = {\n Version: EXCEL_HANDOFF_VERSION,\n State: request.State,\n APIKey: connection.APIKey,\n GraphQLUrl: this.resolveGraphQLUrl(provider),\n UserName: this.UserName,\n UserEmail: this.UserEmail,\n ExpiresAt: connection.ExpiresAt || null,\n };\n const sealed = await SealConnectionPayload(request.PublicKey, payload);\n const outcome: OfficeHandoffOutcome = { Sealed: sealed };\n const url = BuildOfficeHandoffUrl(status.ConnectedPageUrl, outcome);\n if (!url) {\n this.showError(\n 'This MemberJunction server reports an add-in address that isn\\'t a web address. Ask an administrator to check the Excel add-in settings.',\n );\n return;\n }\n this.leave(url);\n }\n\n private leave(url: string): void {\n this.setStage('leaving', 'Returning to Excel...');\n this.LeaveFor(url);\n }\n\n private setStage(stage: OfficeConnectStage, statusMessage?: string): void {\n this.Stage = stage;\n if (statusMessage) {\n this.StatusMessage = statusMessage;\n }\n this.cdr.detectChanges();\n }\n\n private showError(message: string): void {\n this.ErrorMessage = message;\n this.setStage('error');\n }\n}\n","<div class=\"office-connect-container\">\n <div class=\"office-connect-card\">\n @switch (Stage) {\n @case ('waiting') {\n <div class=\"office-connect-status\">\n <mj-loading [text]=\"StatusMessage\"></mj-loading>\n @if (CanSignIn) {\n <p class=\"office-connect-hint\">Not signed in to MemberJunction in this window?</p>\n <div class=\"button-group\">\n <button mjButton variant=\"secondary\" (click)=\"OnSignIn()\">\n <i class=\"fa-solid fa-arrow-right-to-bracket\"></i>\n Sign in\n </button>\n </div>\n }\n </div>\n }\n\n @case ('sign-in') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container brand-icon\"><i class=\"fa-solid fa-table-cells\"></i></div>\n <h2>Sign in to connect Excel</h2>\n <p>Sign in to MemberJunction with the account whose views and queries Excel should load.</p>\n <div class=\"button-group\">\n <button mjButton variant=\"primary\" (click)=\"OnSignIn()\">\n <i class=\"fa-solid fa-arrow-right-to-bracket\"></i>\n Sign in\n </button>\n </div>\n </div>\n }\n\n @case ('bad-request') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container error-icon\"><i class=\"fa-solid fa-circle-exclamation\"></i></div>\n <h2>This link can't connect Excel</h2>\n <p>Open this page from the MemberJunction add-in in Excel by choosing <strong>Sign in</strong> there. You can close this window.</p>\n </div>\n }\n\n @case ('not-enabled') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container muted-icon\"><i class=\"fa-solid fa-table-cells\"></i></div>\n <h2>Excel isn't turned on</h2>\n <p>{{ ServerName || 'This MemberJunction server' }} doesn't have the Excel add-in turned on. Ask an administrator to turn it on, then sign in again from Excel. You can close this window.</p>\n </div>\n }\n\n @case ('consent') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container brand-icon\"><i class=\"fa-solid fa-table-cells\"></i></div>\n <h2>Connect Excel to {{ ServerName || 'MemberJunction' }}</h2>\n <div class=\"office-connect-user\">\n <span class=\"office-connect-user-name\">{{ UserName }}</span>\n @if (UserEmail && UserEmail !== UserName) {\n <span class=\"office-connect-user-email\">{{ UserEmail }}</span>\n }\n </div>\n <ul class=\"office-connect-terms\">\n <li>Excel can run the saved views and queries you can already open in MemberJunction, as you.</li>\n <li>It can only read data. It can't change or delete anything.</li>\n <li>The connection lasts {{ KeyLifetimeDays }} {{ KeyLifetimeDays === 1 ? 'day' : 'days' }}. You can disconnect it sooner on the API Keys page.</li>\n </ul>\n <div class=\"button-group\">\n <button mjButton variant=\"primary\" (click)=\"OnConnect()\">\n <i class=\"fa-solid fa-link\"></i>\n Connect Excel\n </button>\n <button mjButton variant=\"secondary\" (click)=\"OnCancel()\">Cancel</button>\n </div>\n </div>\n }\n\n @case ('connecting') {\n <div class=\"office-connect-status\">\n <mj-loading [text]=\"StatusMessage\"></mj-loading>\n </div>\n }\n\n @case ('leaving') {\n <div class=\"office-connect-status\">\n <mj-loading [text]=\"StatusMessage\"></mj-loading>\n </div>\n }\n\n @case ('cancelled') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container muted-icon\"><i class=\"fa-solid fa-circle-xmark\"></i></div>\n <h2>Excel wasn't connected</h2>\n <p>You can close this window.</p>\n </div>\n }\n\n @case ('error') {\n <div class=\"office-connect-status\">\n <div class=\"icon-container error-icon\"><i class=\"fa-solid fa-circle-exclamation\"></i></div>\n <h2>Excel wasn't connected</h2>\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n <button mjButton variant=\"secondary\" (click)=\"OnCancel()\">Cancel</button>\n </div>\n </div>\n }\n }\n </div>\n</div>\n"]}
|
package/dist/public-api.d.ts
CHANGED
package/dist/public-api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAKA,cAAc,cAAc,CAAC;AAG7B,cAAc,sBAAsB,CAAC;AAGrC,cAAc,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAKA,cAAc,cAAc,CAAC;AAG7B,cAAc,sBAAsB,CAAC;AAGrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sCAAsC,CAAC"}
|
package/dist/public-api.js
CHANGED
|
@@ -7,5 +7,7 @@ export * from './lib/module';
|
|
|
7
7
|
export * from './lib/export.service';
|
|
8
8
|
// Components
|
|
9
9
|
export * from './lib/export-dialog.component';
|
|
10
|
+
export * from './lib/office-connect-panel.component';
|
|
10
11
|
// NOTE: For export types (ExportFormat, ExportOptions, etc.), import directly from @memberjunction/export-engine
|
|
12
|
+
// NOTE: For Office/Excel handoff helpers (OFFICE_CONNECT_ROUTE_PATH, BuildOfficeSignInOptions, etc.), import directly from @memberjunction/excel-addin
|
|
11
13
|
//# sourceMappingURL=public-api.js.map
|
package/dist/public-api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,cAAc,cAAc,CAAC;AAE7B,UAAU;AACV,cAAc,sBAAsB,CAAC;AAErC,aAAa;AACb,cAAc,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,cAAc,cAAc,CAAC;AAE7B,UAAU;AACV,cAAc,sBAAsB,CAAC;AAErC,aAAa;AACb,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sCAAsC,CAAC;AAErD,iHAAiH;AACjH,uJAAuJ","sourcesContent":["/*\n * Public API Surface for @memberjunction/ng-export-service\n */\n\n// Module\nexport * from './lib/module';\n\n// Service\nexport * from './lib/export.service';\n\n// Components\nexport * from './lib/export-dialog.component';\nexport * from './lib/office-connect-panel.component';\n\n// NOTE: For export types (ExportFormat, ExportOptions, etc.), import directly from @memberjunction/export-engine\n// NOTE: For Office/Excel handoff helpers (OFFICE_CONNECT_ROUTE_PATH, BuildOfficeSignInOptions, etc.), import directly from @memberjunction/excel-addin\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-export-service",
|
|
3
|
-
"version": "6.2.0-edge.
|
|
3
|
+
"version": "6.2.0-edge.7",
|
|
4
4
|
"description": "MemberJunction: Angular export service and dialog for exporting data to Excel, CSV, and JSON",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@angular/compiler": "21.2.22",
|
|
22
22
|
"@angular/compiler-cli": "21.2.22",
|
|
23
|
-
"@memberjunction/ng-test-utils": "6.2.0-edge.
|
|
23
|
+
"@memberjunction/ng-test-utils": "6.2.0-edge.7",
|
|
24
24
|
"vitest": "^4.0.18"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
@@ -30,7 +30,12 @@
|
|
|
30
30
|
"@angular/cdk": "^21.2.14"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@memberjunction/
|
|
33
|
+
"@memberjunction/core": "6.2.0-edge.7",
|
|
34
|
+
"@memberjunction/excel-addin": "6.2.0-edge.7",
|
|
35
|
+
"@memberjunction/export-engine": "6.2.0-edge.7",
|
|
36
|
+
"@memberjunction/ng-base-types": "6.2.0-edge.7",
|
|
37
|
+
"@memberjunction/ng-shared-generic": "6.2.0-edge.7",
|
|
38
|
+
"@memberjunction/ng-ui-components": "6.2.0-edge.7",
|
|
34
39
|
"tslib": "^2.8.1"
|
|
35
40
|
},
|
|
36
41
|
"sideEffects": false,
|