@arsedizioni/ars-utils 22.0.3 → 22.0.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.
- package/fesm2022/arsedizioni-ars-utils-ui.application.mjs +283 -6
- package/fesm2022/arsedizioni-ars-utils-ui.application.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.mjs +28 -3
- package/fesm2022/arsedizioni-ars-utils-ui.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils.mjs +0 -1
- package/fesm2022/arsedizioni-ars-utils.mjs.map +1 -1
- package/package.json +1 -1
- package/types/arsedizioni-ars-utils-clipper.ui.d.ts +1 -1
- package/types/arsedizioni-ars-utils-ui.application.d.ts +83 -4
- package/types/arsedizioni-ars-utils-ui.d.ts +26 -2
- package/types/arsedizioni-ars-utils.d.ts +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, inject, Renderer2, ElementRef, afterNextRender, Directive, output, ChangeDetectorRef, signal, ChangeDetectionStrategy, Component, Injectable, DestroyRef, viewChild, computed, Service, NgModule, effect, Input, Optional, Self, booleanAttribute, model } from '@angular/core';
|
|
2
|
+
import { input, inject, Renderer2, ElementRef, afterNextRender, Directive, output, ChangeDetectorRef, signal, ChangeDetectionStrategy, Component, Injectable, DestroyRef, viewChild, computed, Service, makeEnvironmentProviders, NgModule, effect, Input, Optional, Self, booleanAttribute, model, NgZone } from '@angular/core';
|
|
3
3
|
import * as i14 from '@angular/material/paginator';
|
|
4
4
|
import { MatPaginatorModule, MatPaginatorIntl } from '@angular/material/paginator';
|
|
5
5
|
import { DialogService, OtpInputComponent, PaginatorIntl, UIService } from '@arsedizioni/ars-utils/ui';
|
|
@@ -21,13 +21,13 @@ import { MatInputModule } from '@angular/material/input';
|
|
|
21
21
|
import * as i8 from '@angular/material/tooltip';
|
|
22
22
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
23
23
|
import * as i4$1 from '@arsedizioni/ars-utils/core';
|
|
24
|
-
import { EmailsValidatorDirective, SafeHtmlPipe, SystemUtils, ArsCoreModule, DateInterval, DateIntervalChangeDirective, TimeValidatorDirective, SearchFilterPipe, FileInfo, FileSizeValidatorDirective, SafeUrlPipe } from '@arsedizioni/ars-utils/core';
|
|
24
|
+
import { EmailsValidatorDirective, SafeHtmlPipe, SystemUtils, ArsCoreModule, DateInterval, DateIntervalChangeDirective, TimeValidatorDirective, SearchFilterPipe, FileInfo, FileSizeValidatorDirective, SafeUrlPipe, EnvironmentService } from '@arsedizioni/ars-utils/core';
|
|
25
25
|
import * as i1$1 from '@ngbracket/ngx-layout/flex';
|
|
26
26
|
import { FlexModule } from '@ngbracket/ngx-layout/flex';
|
|
27
27
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
28
28
|
import * as i9 from '@angular/material/tree';
|
|
29
29
|
import { MatTree, MatTreeModule } from '@angular/material/tree';
|
|
30
|
-
import { BehaviorSubject, Subject, auditTime, animationFrameScheduler } from 'rxjs';
|
|
30
|
+
import { BehaviorSubject, Subject, auditTime, animationFrameScheduler, filter } from 'rxjs';
|
|
31
31
|
import { FlexLayoutModule } from '@ngbracket/ngx-layout';
|
|
32
32
|
import * as i2 from '@ngbracket/ngx-layout/extended';
|
|
33
33
|
import { MatOptionModule } from '@angular/material/core';
|
|
@@ -49,6 +49,11 @@ import { MatChipsModule } from '@angular/material/chips';
|
|
|
49
49
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
50
50
|
import * as i4$2 from '@angular/material/tabs';
|
|
51
51
|
import { MatTabsModule } from '@angular/material/tabs';
|
|
52
|
+
import { MsalBroadcastService, MsalService, MSAL_INSTANCE, MSAL_GUARD_CONFIG, MSAL_INTERCEPTOR_CONFIG } from '@azure/msal-angular';
|
|
53
|
+
import { PublicClientApplication, BrowserCacheLocation, InteractionType, EventType } from '@azure/msal-browser';
|
|
54
|
+
import { broadcastResponseToMainFrame } from '@azure/msal-browser/redirect-bridge';
|
|
55
|
+
import * as i2$1 from '@angular/material/progress-bar';
|
|
56
|
+
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
52
57
|
|
|
53
58
|
class ResizeTableColumnDirective {
|
|
54
59
|
constructor() {
|
|
@@ -155,6 +160,12 @@ var PromptDialogType;
|
|
|
155
160
|
PromptDialogType[PromptDialogType["List"] = 5] = "List";
|
|
156
161
|
PromptDialogType[PromptDialogType["Time"] = 6] = "Time";
|
|
157
162
|
})(PromptDialogType || (PromptDialogType = {}));
|
|
163
|
+
var LoginOAuthType;
|
|
164
|
+
(function (LoginOAuthType) {
|
|
165
|
+
LoginOAuthType[LoginOAuthType["None"] = 0] = "None";
|
|
166
|
+
LoginOAuthType[LoginOAuthType["Microsoft"] = 1] = "Microsoft";
|
|
167
|
+
LoginOAuthType[LoginOAuthType["Google"] = 2] = "Google";
|
|
168
|
+
})(LoginOAuthType || (LoginOAuthType = {}));
|
|
158
169
|
|
|
159
170
|
/** Constants identifying each filter group slot and text filter channels. */
|
|
160
171
|
const Filters = {
|
|
@@ -1717,11 +1728,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
|
|
|
1717
1728
|
type: Service
|
|
1718
1729
|
}] });
|
|
1719
1730
|
|
|
1731
|
+
/**
|
|
1732
|
+
* Standalone providers for the ars-utils "application" UI layer.
|
|
1733
|
+
*
|
|
1734
|
+
* Single source of truth for the environment-level configuration of this entry point.
|
|
1735
|
+
* Use it in a standalone bootstrap instead of importing {@link ArsUIApplicationModule}:
|
|
1736
|
+
*
|
|
1737
|
+
* @example
|
|
1738
|
+
* bootstrapApplication(AppComponent, {
|
|
1739
|
+
* providers: [provideArsUIApplication()]
|
|
1740
|
+
* });
|
|
1741
|
+
*/
|
|
1742
|
+
function provideArsUIApplication() {
|
|
1743
|
+
return makeEnvironmentProviders([
|
|
1744
|
+
{ provide: MatPaginatorIntl, useClass: PaginatorIntl },
|
|
1745
|
+
]);
|
|
1746
|
+
}
|
|
1747
|
+
/**
|
|
1748
|
+
* @deprecated Prefer the standalone {@link provideArsUIApplication} provider together with
|
|
1749
|
+
* direct imports of the standalone components/directives. This module is kept as a thin,
|
|
1750
|
+
* backward-compatible shim so existing NgModule-based applications keep working unchanged.
|
|
1751
|
+
*/
|
|
1720
1752
|
class ArsUIApplicationModule {
|
|
1721
1753
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ArsUIApplicationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1722
1754
|
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.0", ngImport: i0, type: ArsUIApplicationModule, imports: [ResizeTableColumnDirective], exports: [ResizeTableColumnDirective] }); }
|
|
1723
1755
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ArsUIApplicationModule, providers: [
|
|
1724
|
-
|
|
1756
|
+
provideArsUIApplication(),
|
|
1725
1757
|
] }); }
|
|
1726
1758
|
}
|
|
1727
1759
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ArsUIApplicationModule, decorators: [{
|
|
@@ -1734,7 +1766,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
|
|
|
1734
1766
|
ResizeTableColumnDirective,
|
|
1735
1767
|
],
|
|
1736
1768
|
providers: [
|
|
1737
|
-
|
|
1769
|
+
provideArsUIApplication(),
|
|
1738
1770
|
]
|
|
1739
1771
|
}]
|
|
1740
1772
|
}] });
|
|
@@ -3335,6 +3367,251 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
|
|
|
3335
3367
|
MatButtonModule, MatTooltipModule, MatFormFieldModule, MatInputModule, FormsModule, FlexLayoutModule, SafeHtmlPipe], template: "<mat-tab-group class=\"taxonomy-picker-tabs\" style=\"height:100%\">\r\n <mat-tab style=\"overflow-x: hidden !important; height: 100%\">\r\n <ng-template mat-tab-label>\r\n Seleziona\r\n <mat-icon\r\n style=\"font-size:16px;height:16px;width:16px;margin-left:4px;vertical-align:middle;color:var(--mat-sys-primary)\"\r\n [matTooltip]=\"'Nessuna selezione = tutti gli argomenti inclusi;\\r\\nOgni elemento selezionato include sempre tutti i suoi sottoelementi'\"\r\n matTooltipPosition=\"above\">\r\n info\r\n </mat-icon>\r\n </ng-template>\r\n <div fxLayout=\"column\" fxFill style=\"overflow: hidden; height: 100%;\">\r\n <div fxFlex>\r\n <div fxLayout=\"row\" fxLayoutGap=\"10px\" fxLayoutAlign=\"start center\" fxFill>\r\n <div fxFlex fxHide.xs>\r\n <mat-form-field style=\"width:200px; padding: 8px 0px\" appearance=\"outline\"\r\n subscriptSizing=\"dynamic\">\r\n <mat-label>Cerca...</mat-label>\r\n <input type=\"text\" (keyup)=\"doFilter()\" matInput [ngModel]=\"filterText()\"\r\n (ngModelChange)=\"filterText.set($event)\"\r\n (keydown.enter)=\"$event.preventDefault(); $event.stopPropagation(); nextFiltered()\"\r\n (keydown.arrowDown)=\"$event.preventDefault(); $event.stopPropagation(); nextFiltered()\">\r\n @if (filterText()) {\r\n <button type=\"button\" type=\"button\" tabindex=\"-1\" matSuffix mat-icon-button\r\n aria-label=\"Clear\" (click)=\"clearFilter()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n }\r\n </mat-form-field>\r\n </div>\r\n @if (filteredItems().length > 0) {\r\n <div fxFlex=\"50px\" fxHide.xs fxLayoutAlign=\"end center\">\r\n <div class=\"small\">{{filterIndex() + 1}} / {{filteredItems().length}}</div>\r\n </div>\r\n <div fxFlex=\"48px\" fxHide.xs fxLayoutAlign=\"end center\">\r\n <button mat-icon-button (click)=\"nextFiltered()\">\r\n <mat-icon aria-label=\"Vai al prossimo\"\r\n matTooltip=\"Vai al prossimo\">arrow_downward</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n <div fxFlex=\"*\" fxLayoutAlign=\"end center\">\r\n <button mat-icon-button [matTooltip]=\"'Espandi tutto'\" (click)=\"expandAll()\">\r\n <mat-icon>unfold_more</mat-icon>\r\n </button>\r\n <button mat-icon-button [matTooltip]=\"'Comprimi tutto'\" (click)=\"collapseAll()\">\r\n <mat-icon>unfold_less</mat-icon>\r\n </button>\r\n <button mat-icon-button [matTooltip]=\"'Azzera selezione'\" [disabled]=\"!hasSelection()\"\r\n (click)=\"clearAll()\">\r\n <mat-icon>deselect</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <div fxFlex=\"*\" style=\"overflow-y: auto;\">\r\n <mat-tree [dataSource]=\"tree()\" [childrenAccessor]=\"treeChildrenAccessor\" class=\"tree\">\r\n <!-- Leaf node -->\r\n <mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodePadding [matTreeNodePaddingIndent]=\"20\"\r\n class=\"tree-node\" [class.tree-node-filtered]=\"filteredNode()?.id === node.id\"\r\n [class.tree-node-no-select]=\"!isSelectable(node)\"\r\n [attr.data-node-id]=\"node.id\">\r\n <button mat-icon-button disabled style=\"visibility: hidden\"></button>\r\n @if (isSelectable(node)) {\r\n <mat-checkbox [checked]=\"isSelected(node)\" [disabled]=\"disabled()\" (change)=\"toggleNode(node)\">\r\n <span class=\"small\">{{node.name}}</span>\r\n </mat-checkbox>\r\n } @else {\r\n <div class=\"tree-node-label-only\">\r\n <span class=\"small\">{{node.name}}</span>\r\n </div>\r\n }\r\n </mat-tree-node>\r\n <!-- Expandable node with children -->\r\n <mat-tree-node *matTreeNodeDef=\"let node; when: hasChild\" matTreeNodePadding\r\n [matTreeNodePaddingIndent]=\"20\" #treeNode=\"matTreeNode\" class=\"tree-node\"\r\n [class.tree-node-filtered]=\"filteredNode()?.id === node.id\"\r\n [class.tree-node-no-select]=\"!isSelectable(node)\"\r\n [attr.data-node-id]=\"node.id\">\r\n <button mat-icon-button matTreeNodeToggle>\r\n <mat-icon>{{treeNode.isExpanded ? 'expand_more' : 'chevron_right'}}</mat-icon>\r\n </button>\r\n @if (isSelectable(node)) {\r\n <mat-checkbox [checked]=\"isSelected(node)\" [indeterminate]=\"isIndeterminate(node)\"\r\n [disabled]=\"disabled()\" (change)=\"toggleNode(node)\">\r\n <span class=\"small\">{{node.name}}</span>\r\n </mat-checkbox>\r\n } @else {\r\n <div class=\"tree-node-label-only\">\r\n <span class=\"small\">{{node.name}}</span>\r\n </div>\r\n }\r\n </mat-tree-node>\r\n </mat-tree>\r\n </div>\r\n </div>\r\n </mat-tab>\r\n <mat-tab [label]=\"hasSelection() ? 'Selezionati (' + selectedVisibleCount() + ')' : 'Selezionati (tutti)'\"\r\n style=\"height: 100%;\">\r\n <div fxLayout=\"column\" fxFill style=\"overflow: hidden; height: 100%;\">\r\n <div fxFlex>\r\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\" fxLayoutGap=\"8px\" style=\"padding:12px\">\r\n @if (!hasSelection()) {\r\n <mat-icon>info</mat-icon>\r\n <span [innerHTML]=\"descriptionEmpty() | safeHtml\"></span>\r\n } @else {\r\n <div fxFlex=\"*\" fxLayoutAlign=\"end\">\r\n <button mat-button color=\"warn\" style=\"margin-left:auto\" (click)=\"clearAll()\">\r\n <mat-icon>deselect</mat-icon> Azzera tutto\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n <div fxFlex=\"*\" style=\"overflow-y: auto; padding-bottom: 12px;\">\r\n <mat-chip-set>\r\n @for (id of selection(); track id) {\r\n @let node = nodeById(id);\r\n @if (node && isChipVisible(id)) {\r\n <mat-chip (removed)=\"removeNode(node)\" style=\"max-width: 280px;\" [matTooltip]=\"node.name\">\r\n {{node.name}}\r\n @if (!disabled()) {\r\n <button matChipRemove matTooltip=\"Elimina\"><mat-icon>cancel</mat-icon></button>\r\n }\r\n </mat-chip>\r\n }\r\n }\r\n </mat-chip-set>\r\n </div>\r\n </div>\r\n </mat-tab>\r\n</mat-tab-group>", styles: [".tree-picker-tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;height:100%}.tree{padding:8px 0 16px;background-color:transparent!important}.tree-node{min-height:36px!important;padding-right:12px;margin-right:0}.tree-node .small-icon-button{width:2rem!important;height:2rem!important;padding:0!important;display:inline-flex!important;align-items:center;justify-content:center}.tree-node .small-icon-button .mat-mdc-button-touch-target{width:2rem!important;height:2rem!important}.tree-node:not(.tree-node-no-select):hover{cursor:pointer;background-color:var(--mat-menu-item-hover-state-layer-color, transparent);border-radius:24px}.tree-node-filtered ::ng-deep .mdc-label,.tree-node-filtered ::ng-deep .mat-mdc-checkbox label{font-weight:700;color:var(--ars-color-accent, #7894ae)!important}.tree-node-filtered .tree-node-label-only{font-weight:700;color:var(--ars-color-accent, #7894ae);opacity:1}.tree-node-activated ::ng-deep .mdc-label,.tree-node-activated ::ng-deep .mat-mdc-checkbox label{font-weight:700;color:var(--ars-color-secondary, #4a635f)!important}.tree-node-label-only{display:flex;flex-direction:column;justify-content:center;padding-left:30px;opacity:.7}\n"] }]
|
|
3336
3368
|
}], ctorParameters: () => [], propDecorators: { tree: [{ type: i0.Input, args: [{ isSignal: true, alias: "tree", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], descriptionEmpty: [{ type: i0.Input, args: [{ isSignal: true, alias: "descriptionEmpty", required: false }] }], maxDepth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDepth", required: false }] }], maxDepthOverrides: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDepthOverrides", required: false }] }], minDepth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDepth", required: false }] }], selectionCount: [{ type: i0.Output, args: ["selectionCount"] }], changed: [{ type: i0.Output, args: ["changed"] }], _treeRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatTree), { isSignal: true }] }] } });
|
|
3337
3369
|
|
|
3370
|
+
function MSALInstanceFactory(environment) {
|
|
3371
|
+
return new PublicClientApplication({
|
|
3372
|
+
auth: {
|
|
3373
|
+
clientId: "6b2c080f-6ab0-4511-a9df-0bce69db5833",
|
|
3374
|
+
authority: "https://login.microsoftonline.com/common",
|
|
3375
|
+
redirectUri: environment.appLoginRedirectUri,
|
|
3376
|
+
},
|
|
3377
|
+
cache: {
|
|
3378
|
+
cacheLocation: BrowserCacheLocation.LocalStorage
|
|
3379
|
+
}
|
|
3380
|
+
});
|
|
3381
|
+
}
|
|
3382
|
+
function MSALInterceptorConfigFactory(environment) {
|
|
3383
|
+
return {
|
|
3384
|
+
interactionType: InteractionType.Popup,
|
|
3385
|
+
protectedResourceMap: new Map([
|
|
3386
|
+
[environment.appServiceLoginUri, ["api://6b2c080f-6ab0-4511-a9df-0bce69db5833/AngularSPAAuthScope"]],
|
|
3387
|
+
["https://graph.microsoft.com/v2.0/me", ["user.read"]],
|
|
3388
|
+
])
|
|
3389
|
+
};
|
|
3390
|
+
}
|
|
3391
|
+
function MSALGuardConfigFactory() {
|
|
3392
|
+
return {
|
|
3393
|
+
interactionType: InteractionType.Popup,
|
|
3394
|
+
authRequest: {
|
|
3395
|
+
scopes: ["user.read"]
|
|
3396
|
+
}
|
|
3397
|
+
};
|
|
3398
|
+
}
|
|
3399
|
+
class LoginOAuthComponent {
|
|
3400
|
+
constructor() {
|
|
3401
|
+
this.destroyRef = inject(DestroyRef);
|
|
3402
|
+
this.msalBroadcastService = inject(MsalBroadcastService);
|
|
3403
|
+
this.msaLService = inject(MsalService);
|
|
3404
|
+
this.dialogService = inject(DialogService);
|
|
3405
|
+
this.ngZone = inject(NgZone);
|
|
3406
|
+
/** Emitted when OAuth authentication succeeds. */
|
|
3407
|
+
this.success = output();
|
|
3408
|
+
/** Whether to show the introductory info panel. */
|
|
3409
|
+
this.showInfo = input(true, /* @ts-ignore */
|
|
3410
|
+
...(ngDevMode ? [{ debugName: "showInfo" }] : /* istanbul ignore next */ []));
|
|
3411
|
+
/** Application name displayed in the info panel. */
|
|
3412
|
+
this.applicationName = input(/* @ts-ignore */
|
|
3413
|
+
...(ngDevMode ? [undefined, { debugName: "applicationName" }] : /* istanbul ignore next */ []));
|
|
3414
|
+
/** Whether to trigger `initialize()` automatically on mount. */
|
|
3415
|
+
this.autoInitialize = input(false, /* @ts-ignore */
|
|
3416
|
+
...(ngDevMode ? [{ debugName: "autoInitialize" }] : /* istanbul ignore next */ []));
|
|
3417
|
+
/** Whether the Microsoft login button is shown. */
|
|
3418
|
+
this.allowMicrosoft = input(true, /* @ts-ignore */
|
|
3419
|
+
...(ngDevMode ? [{ debugName: "allowMicrosoft" }] : /* istanbul ignore next */ []));
|
|
3420
|
+
/** Whether the Google login button is shown. */
|
|
3421
|
+
this.allowGoogle = input(true, /* @ts-ignore */
|
|
3422
|
+
...(ngDevMode ? [{ debugName: "allowGoogle" }] : /* istanbul ignore next */ []));
|
|
3423
|
+
this.oauthReady = signal(false, /* @ts-ignore */
|
|
3424
|
+
...(ngDevMode ? [{ debugName: "oauthReady" }] : /* istanbul ignore next */ []));
|
|
3425
|
+
this.oauthMicrosoftReady = signal(false, /* @ts-ignore */
|
|
3426
|
+
...(ngDevMode ? [{ debugName: "oauthMicrosoftReady" }] : /* istanbul ignore next */ []));
|
|
3427
|
+
this.oauthGoogleReady = signal(false, /* @ts-ignore */
|
|
3428
|
+
...(ngDevMode ? [{ debugName: "oauthGoogleReady" }] : /* istanbul ignore next */ []));
|
|
3429
|
+
this.msalBroadcastService.msalSubject$
|
|
3430
|
+
.pipe(filter((msg) => msg.eventType === EventType.LOGOUT_FAILURE ||
|
|
3431
|
+
msg.eventType === EventType.ACQUIRE_TOKEN_FAILURE), takeUntilDestroyed(this.destroyRef))
|
|
3432
|
+
.subscribe((r) => {
|
|
3433
|
+
if (r?.payload) {
|
|
3434
|
+
const error = r.payload;
|
|
3435
|
+
this.dialogService.error(error?.message ?? 'Errore di autenticazione Microsoft');
|
|
3436
|
+
}
|
|
3437
|
+
});
|
|
3438
|
+
afterNextRender(() => {
|
|
3439
|
+
if (this.autoInitialize()) {
|
|
3440
|
+
this.initialize();
|
|
3441
|
+
}
|
|
3442
|
+
});
|
|
3443
|
+
}
|
|
3444
|
+
/**
|
|
3445
|
+
* Initialize OAuth providers (Microsoft MSAL and Google GSI).
|
|
3446
|
+
* Safe to call multiple times — already-initialized providers are skipped.
|
|
3447
|
+
* Must be public so the host component can trigger it manually when `autoInitialize` is false.
|
|
3448
|
+
*/
|
|
3449
|
+
initialize() {
|
|
3450
|
+
if (this.oauthMicrosoftReady() && this.oauthGoogleReady()) {
|
|
3451
|
+
return; // Both already loaded
|
|
3452
|
+
}
|
|
3453
|
+
this.oauthReady.set(true);
|
|
3454
|
+
// Load MS stack only if not already initialized
|
|
3455
|
+
if (!this.oauthMicrosoftReady()) {
|
|
3456
|
+
this.msaLService.initialize()
|
|
3457
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
3458
|
+
.subscribe(() => {
|
|
3459
|
+
this.oauthMicrosoftReady.set(true);
|
|
3460
|
+
});
|
|
3461
|
+
}
|
|
3462
|
+
// Load Google script only if not already initialized
|
|
3463
|
+
if (!this.oauthGoogleReady()) {
|
|
3464
|
+
const DSLScript = document.createElement('script');
|
|
3465
|
+
DSLScript.src = 'https://accounts.google.com/gsi/client';
|
|
3466
|
+
DSLScript.type = 'text/javascript';
|
|
3467
|
+
document.body.appendChild(DSLScript);
|
|
3468
|
+
document.body.removeChild(DSLScript);
|
|
3469
|
+
// @ts-ignore
|
|
3470
|
+
window.onGoogleLibraryLoad = () => {
|
|
3471
|
+
// initialize google account
|
|
3472
|
+
// @ts-ignore
|
|
3473
|
+
google.accounts.id.initialize({
|
|
3474
|
+
client_id: '71204983077-ag31h3bgt2udcbfr9nn84r9rni2k3snp.apps.googleusercontent.com',
|
|
3475
|
+
cancel_on_tap_outside: true,
|
|
3476
|
+
auto_select: false,
|
|
3477
|
+
callback: (r) => {
|
|
3478
|
+
this.ngZone.run(() => {
|
|
3479
|
+
this.success.emit({ type: LoginOAuthType.Google, token: r.credential });
|
|
3480
|
+
});
|
|
3481
|
+
}
|
|
3482
|
+
});
|
|
3483
|
+
googleButtonWrapper = createFakeGoogleWrapper();
|
|
3484
|
+
this.oauthGoogleReady.set(true);
|
|
3485
|
+
};
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
/**
|
|
3489
|
+
* Trigger a Microsoft (MSAL) login popup and acquire an access token on success.
|
|
3490
|
+
*/
|
|
3491
|
+
loginMSAL() {
|
|
3492
|
+
// Clear any in-progress interaction flag that may have been left by a previous incomplete popup
|
|
3493
|
+
sessionStorage.removeItem('msal.interaction.status');
|
|
3494
|
+
this.msaLService.loginPopup()
|
|
3495
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
3496
|
+
.subscribe({
|
|
3497
|
+
next: (r) => {
|
|
3498
|
+
try {
|
|
3499
|
+
this.msaLService.instance.setActiveAccount(r.account);
|
|
3500
|
+
this.msaLService.acquireTokenSilent({
|
|
3501
|
+
scopes: [
|
|
3502
|
+
"api://6b2c080f-6ab0-4511-a9df-0bce69db5833/AngularSPAAuthScope"
|
|
3503
|
+
],
|
|
3504
|
+
account: r.account
|
|
3505
|
+
}).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
|
|
3506
|
+
next: (tokenResult) => {
|
|
3507
|
+
console.log("Token acquired!");
|
|
3508
|
+
this.success.emit({ type: LoginOAuthType.Microsoft, token: tokenResult.accessToken });
|
|
3509
|
+
},
|
|
3510
|
+
error: (error) => {
|
|
3511
|
+
this.dialogService.error(error.message);
|
|
3512
|
+
}
|
|
3513
|
+
});
|
|
3514
|
+
}
|
|
3515
|
+
catch (error) {
|
|
3516
|
+
this.dialogService.error(error.message);
|
|
3517
|
+
}
|
|
3518
|
+
},
|
|
3519
|
+
error: (error) => {
|
|
3520
|
+
this.dialogService.error(error.message);
|
|
3521
|
+
}
|
|
3522
|
+
});
|
|
3523
|
+
}
|
|
3524
|
+
/**
|
|
3525
|
+
* Trigger the hidden Google GSI button to open the Google sign-in flow.
|
|
3526
|
+
*/
|
|
3527
|
+
loginGoogle() {
|
|
3528
|
+
// Use wrapper click to prevent Illegal invocation exception
|
|
3529
|
+
googleButtonWrapper.click();
|
|
3530
|
+
}
|
|
3531
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: LoginOAuthComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3532
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: LoginOAuthComponent, isStandalone: true, selector: "login-oauth", inputs: { showInfo: { classPropertyName: "showInfo", publicName: "showInfo", isSignal: true, isRequired: false, transformFunction: null }, applicationName: { classPropertyName: "applicationName", publicName: "applicationName", isSignal: true, isRequired: false, transformFunction: null }, autoInitialize: { classPropertyName: "autoInitialize", publicName: "autoInitialize", isSignal: true, isRequired: false, transformFunction: null }, allowMicrosoft: { classPropertyName: "allowMicrosoft", publicName: "allowMicrosoft", isSignal: true, isRequired: false, transformFunction: null }, allowGoogle: { classPropertyName: "allowGoogle", publicName: "allowGoogle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { success: "success" }, providers: [
|
|
3533
|
+
{
|
|
3534
|
+
provide: MSAL_INSTANCE,
|
|
3535
|
+
deps: [EnvironmentService],
|
|
3536
|
+
useFactory: MSALInstanceFactory
|
|
3537
|
+
},
|
|
3538
|
+
{
|
|
3539
|
+
provide: MSAL_GUARD_CONFIG,
|
|
3540
|
+
useFactory: MSALGuardConfigFactory
|
|
3541
|
+
},
|
|
3542
|
+
{
|
|
3543
|
+
provide: MSAL_INTERCEPTOR_CONFIG,
|
|
3544
|
+
deps: [EnvironmentService],
|
|
3545
|
+
useFactory: MSALInterceptorConfigFactory
|
|
3546
|
+
},
|
|
3547
|
+
MsalService,
|
|
3548
|
+
MsalBroadcastService
|
|
3549
|
+
], ngImport: i0, template: "<div class=\"login-oauth\">\r\n @if(showInfo()) {\r\n <div class=\"message\">\r\n <p>Questa sezione consente di accedere al servizio utilizzando un provider OAuth2.</p>\r\n @if(applicationName()) {\r\n <p>La email utilizzata deve essere collegata ad un utente valido di {{applicationName()}} e dei servizi ad esso\r\n connessi.</p>\r\n }\r\n </div>\r\n }\r\n @if (allowMicrosoft()) {\r\n <div class=\"button\">\r\n <button mat-flat-button (click)=\"loginMSAL()\" aria-label=\"Effettua accesso\"\r\n [disabled]=\"!oauthMicrosoftReady()\" style=\"width: 100%;\">\r\n Accedi con Microsoft</button>\r\n </div>\r\n }\r\n @if (allowGoogle()) {\r\n <div class=\"button\">\r\n <button mat-flat-button (click)=\"loginGoogle()\" style=\"width: 100%;\"\r\n aria-label=\"Effettua accesso\" [disabled]=\"!oauthGoogleReady()\">\r\n Accedi con Google</button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".login-oauth{text-align:center}.login-oauth .button{padding:10px 0;width:100%}.login-oauth .message{padding:0 0 10px!important;font-size:small}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3550
|
+
}
|
|
3551
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: LoginOAuthComponent, decorators: [{
|
|
3552
|
+
type: Component,
|
|
3553
|
+
args: [{ selector: 'login-oauth', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
3554
|
+
{
|
|
3555
|
+
provide: MSAL_INSTANCE,
|
|
3556
|
+
deps: [EnvironmentService],
|
|
3557
|
+
useFactory: MSALInstanceFactory
|
|
3558
|
+
},
|
|
3559
|
+
{
|
|
3560
|
+
provide: MSAL_GUARD_CONFIG,
|
|
3561
|
+
useFactory: MSALGuardConfigFactory
|
|
3562
|
+
},
|
|
3563
|
+
{
|
|
3564
|
+
provide: MSAL_INTERCEPTOR_CONFIG,
|
|
3565
|
+
deps: [EnvironmentService],
|
|
3566
|
+
useFactory: MSALInterceptorConfigFactory
|
|
3567
|
+
},
|
|
3568
|
+
MsalService,
|
|
3569
|
+
MsalBroadcastService
|
|
3570
|
+
], imports: [
|
|
3571
|
+
MatButtonModule
|
|
3572
|
+
], template: "<div class=\"login-oauth\">\r\n @if(showInfo()) {\r\n <div class=\"message\">\r\n <p>Questa sezione consente di accedere al servizio utilizzando un provider OAuth2.</p>\r\n @if(applicationName()) {\r\n <p>La email utilizzata deve essere collegata ad un utente valido di {{applicationName()}} e dei servizi ad esso\r\n connessi.</p>\r\n }\r\n </div>\r\n }\r\n @if (allowMicrosoft()) {\r\n <div class=\"button\">\r\n <button mat-flat-button (click)=\"loginMSAL()\" aria-label=\"Effettua accesso\"\r\n [disabled]=\"!oauthMicrosoftReady()\" style=\"width: 100%;\">\r\n Accedi con Microsoft</button>\r\n </div>\r\n }\r\n @if (allowGoogle()) {\r\n <div class=\"button\">\r\n <button mat-flat-button (click)=\"loginGoogle()\" style=\"width: 100%;\"\r\n aria-label=\"Effettua accesso\" [disabled]=\"!oauthGoogleReady()\">\r\n Accedi con Google</button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".login-oauth{text-align:center}.login-oauth .button{padding:10px 0;width:100%}.login-oauth .message{padding:0 0 10px!important;font-size:small}\n"] }]
|
|
3573
|
+
}], ctorParameters: () => [], propDecorators: { success: [{ type: i0.Output, args: ["success"] }], showInfo: [{ type: i0.Input, args: [{ isSignal: true, alias: "showInfo", required: false }] }], applicationName: [{ type: i0.Input, args: [{ isSignal: true, alias: "applicationName", required: false }] }], autoInitialize: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoInitialize", required: false }] }], allowMicrosoft: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowMicrosoft", required: false }] }], allowGoogle: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowGoogle", required: false }] }] } });
|
|
3574
|
+
const createFakeGoogleWrapper = () => {
|
|
3575
|
+
const googleLoginWrapper = document.createElement("div");
|
|
3576
|
+
// Or you can simple hide it in CSS rule for custom-google-button
|
|
3577
|
+
googleLoginWrapper.style.display = "none";
|
|
3578
|
+
googleLoginWrapper.classList.add("custom-google-button");
|
|
3579
|
+
// Add the wrapper to body
|
|
3580
|
+
document.body.appendChild(googleLoginWrapper);
|
|
3581
|
+
// Use GSI javascript api to render the button inside our wrapper
|
|
3582
|
+
// You can ignore the properties because this button will not appear
|
|
3583
|
+
// @ts-ignore
|
|
3584
|
+
window.google.accounts.id.renderButton(googleLoginWrapper, {
|
|
3585
|
+
type: "icon",
|
|
3586
|
+
width: "200",
|
|
3587
|
+
});
|
|
3588
|
+
const googleLoginWrapperButton = googleLoginWrapper.querySelector("div[role=button]");
|
|
3589
|
+
return {
|
|
3590
|
+
click: () => {
|
|
3591
|
+
// @ts-ignore
|
|
3592
|
+
googleLoginWrapperButton.click();
|
|
3593
|
+
},
|
|
3594
|
+
};
|
|
3595
|
+
};
|
|
3596
|
+
var googleButtonWrapper;
|
|
3597
|
+
|
|
3598
|
+
class LoginOAuthOkMSComponent {
|
|
3599
|
+
constructor() {
|
|
3600
|
+
/** Message displayed while the popup is completing authentication. */
|
|
3601
|
+
this.message = input('Accesso in corso...', /* @ts-ignore */
|
|
3602
|
+
...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
3603
|
+
// MSAL v5 popup flow: parse the auth response from the URL and send
|
|
3604
|
+
// it back to the opener window via BroadcastChannel, then close the popup.
|
|
3605
|
+
broadcastResponseToMainFrame();
|
|
3606
|
+
}
|
|
3607
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: LoginOAuthOkMSComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3608
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.0", type: LoginOAuthOkMSComponent, isStandalone: true, selector: "app-login-oauth-ok-ms", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div fxLayout=\"column\" fxLayoutAlign=\"center center\" fxFill>\r\n <div class=\"login-auto fade-in\">\r\n <div class=\"message\">\r\n Autenticazione in corso...\r\n </div>\r\n <mat-progress-bar mode=\"indeterminate\" color=\"primary\"></mat-progress-bar>\r\n </div>\r\n</div>\r\n", styles: [".login-auto{padding:20px 0}.login-auto .message{font-size:large;font-weight:700;color:var(--ars-color-primary);max-width:300px;text-align:center;width:100%;padding:40px 0}\n"], dependencies: [{ kind: "ngmodule", type: FlexModule }, { kind: "directive", type: i1$1.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i1$1.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i1$1.FlexFillDirective, selector: "[fxFill], [fxFlexFill]" }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i2$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3609
|
+
}
|
|
3610
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: LoginOAuthOkMSComponent, decorators: [{
|
|
3611
|
+
type: Component,
|
|
3612
|
+
args: [{ selector: 'app-login-oauth-ok-ms', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FlexModule, MatProgressBarModule], template: "<div fxLayout=\"column\" fxLayoutAlign=\"center center\" fxFill>\r\n <div class=\"login-auto fade-in\">\r\n <div class=\"message\">\r\n Autenticazione in corso...\r\n </div>\r\n <mat-progress-bar mode=\"indeterminate\" color=\"primary\"></mat-progress-bar>\r\n </div>\r\n</div>\r\n", styles: [".login-auto{padding:20px 0}.login-auto .message{font-size:large;font-weight:700;color:var(--ars-color-primary);max-width:300px;text-align:center;width:100%;padding:40px 0}\n"] }]
|
|
3613
|
+
}], ctorParameters: () => [], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }] } });
|
|
3614
|
+
|
|
3338
3615
|
/*
|
|
3339
3616
|
* Public API Surface of ars-utils
|
|
3340
3617
|
*/
|
|
@@ -3343,5 +3620,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
|
|
|
3343
3620
|
* Generated bundle index. Do not edit.
|
|
3344
3621
|
*/
|
|
3345
3622
|
|
|
3346
|
-
export { ApplicationDialogService, ArsUIApplicationModule, ButtonSelectorComponent, ButtonToggleComponent, CalendarEmptyHeader, ChipsSelectorComponent, CurrentFilter, CurrentFilterChanged, CurrentFilterItem, FileInputComponent, FilePreviewComponent, FilterBarComponent, Filters, ItemNode, PromptDateDialogComponent, PromptDialogComponent, PromptDialogType, PromptOtpDialogComponent, PromptTimeDialogComponent, ResizeTableColumnDirective, SelectDialogComponent, SelectFileDialogComponent, SelectPictureDialogComponent, SelectTreeDialogComponent, SelectableItem, SelectableNode, SendToDialogComponent, TreeDataSource, TreePickerComponent };
|
|
3623
|
+
export { ApplicationDialogService, ArsUIApplicationModule, ButtonSelectorComponent, ButtonToggleComponent, CalendarEmptyHeader, ChipsSelectorComponent, CurrentFilter, CurrentFilterChanged, CurrentFilterItem, FileInputComponent, FilePreviewComponent, FilterBarComponent, Filters, ItemNode, LoginOAuthComponent, LoginOAuthOkMSComponent, LoginOAuthType, MSALGuardConfigFactory, MSALInstanceFactory, MSALInterceptorConfigFactory, PromptDateDialogComponent, PromptDialogComponent, PromptDialogType, PromptOtpDialogComponent, PromptTimeDialogComponent, ResizeTableColumnDirective, SelectDialogComponent, SelectFileDialogComponent, SelectPictureDialogComponent, SelectTreeDialogComponent, SelectableItem, SelectableNode, SendToDialogComponent, TreeDataSource, TreePickerComponent, provideArsUIApplication };
|
|
3347
3624
|
//# sourceMappingURL=arsedizioni-ars-utils-ui.application.mjs.map
|