oip-common 0.1.1 → 0.1.3
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/oip-common.mjs +68 -32
- package/fesm2022/oip-common.mjs.map +1 -1
- package/index.d.ts +5 -2
- package/package.json +1 -1
- package/scripts/generate-api.mjs +0 -1
package/fesm2022/oip-common.mjs
CHANGED
|
@@ -29,7 +29,7 @@ import { PrimeNG } from 'primeng/config';
|
|
|
29
29
|
import * as i3 from 'primeng/selectbutton';
|
|
30
30
|
import { SelectButtonModule } from 'primeng/selectbutton';
|
|
31
31
|
import { OidcSecurityService, PublicEventsService, EventTypes, StsConfigHttpLoader } from 'angular-auth-oidc-client';
|
|
32
|
-
import { filter, map, switchMap, catchError } from 'rxjs/operators';
|
|
32
|
+
import { filter, map, distinctUntilChanged, switchMap, catchError } from 'rxjs/operators';
|
|
33
33
|
import { Tabs, TabList, Tab } from 'primeng/tabs';
|
|
34
34
|
import * as i2$2 from 'primeng/avatar';
|
|
35
35
|
import { AvatarModule } from 'primeng/avatar';
|
|
@@ -1475,6 +1475,10 @@ class KeycloakSecurityService extends OidcSecurityService {
|
|
|
1475
1475
|
* Stores the decoded access token payload.
|
|
1476
1476
|
*/
|
|
1477
1477
|
this.payload = new BehaviorSubject(null);
|
|
1478
|
+
/**
|
|
1479
|
+
* Stores user-specific data from the login response.
|
|
1480
|
+
*/
|
|
1481
|
+
this.currentUser = new BehaviorSubject(null);
|
|
1478
1482
|
this.publicEventsService
|
|
1479
1483
|
.registerForEvents()
|
|
1480
1484
|
.pipe(filter((event) => event.type === EventTypes.NewAuthenticationResult))
|
|
@@ -1483,14 +1487,17 @@ class KeycloakSecurityService extends OidcSecurityService {
|
|
|
1483
1487
|
});
|
|
1484
1488
|
}
|
|
1485
1489
|
getCurrentUser() {
|
|
1486
|
-
return this.
|
|
1490
|
+
return this.currentUser.getValue();
|
|
1491
|
+
}
|
|
1492
|
+
getCurrentUser$() {
|
|
1493
|
+
return this.currentUser.asObservable();
|
|
1487
1494
|
}
|
|
1488
1495
|
/**
|
|
1489
1496
|
* Returns the ID token for the sign-in.
|
|
1490
1497
|
* @returns A string with the id token.
|
|
1491
1498
|
*/
|
|
1492
1499
|
getAccessToken() {
|
|
1493
|
-
return
|
|
1500
|
+
return super.getAccessToken();
|
|
1494
1501
|
}
|
|
1495
1502
|
/**
|
|
1496
1503
|
* Indicates whether the current user has the 'admin' role.
|
|
@@ -1507,7 +1514,7 @@ class KeycloakSecurityService extends OidcSecurityService {
|
|
|
1507
1514
|
auth() {
|
|
1508
1515
|
super.checkAuth().subscribe((_response) => {
|
|
1509
1516
|
this.loginResponse.next(_response);
|
|
1510
|
-
this.
|
|
1517
|
+
this.currentUser.next(_response.userData);
|
|
1511
1518
|
this.getPayloadFromAccessToken().subscribe((_token) => {
|
|
1512
1519
|
this.payload.next(_token);
|
|
1513
1520
|
});
|
|
@@ -1528,6 +1535,7 @@ class KeycloakSecurityService extends OidcSecurityService {
|
|
|
1528
1535
|
ngOnDestroy() {
|
|
1529
1536
|
this.loginResponse.complete();
|
|
1530
1537
|
this.payload.complete();
|
|
1538
|
+
this.currentUser.complete();
|
|
1531
1539
|
}
|
|
1532
1540
|
/**
|
|
1533
1541
|
* Checks whether the current access token is expired based on the 'exp' claim.
|
|
@@ -1554,6 +1562,7 @@ class UserService {
|
|
|
1554
1562
|
constructor() {
|
|
1555
1563
|
this.securityService = inject(SecurityService);
|
|
1556
1564
|
this.baseDataService = inject(BaseDataService);
|
|
1565
|
+
this.requestedPhotoEmail = null;
|
|
1557
1566
|
/**
|
|
1558
1567
|
* Stores the user's photo as a data URL or binary blob, depending on how it's processed.
|
|
1559
1568
|
*/
|
|
@@ -1562,7 +1571,12 @@ class UserService {
|
|
|
1562
1571
|
* Indicates whether the user photo has finished loading.
|
|
1563
1572
|
*/
|
|
1564
1573
|
this.photoLoaded = false;
|
|
1565
|
-
this.
|
|
1574
|
+
this.securityService
|
|
1575
|
+
.getCurrentUser$()
|
|
1576
|
+
.pipe(map((user) => user?.email ?? null), filter((email) => !!email), distinctUntilChanged())
|
|
1577
|
+
.subscribe(() => {
|
|
1578
|
+
this.getUserPhoto();
|
|
1579
|
+
});
|
|
1566
1580
|
}
|
|
1567
1581
|
/**
|
|
1568
1582
|
* Returns a short label composed of the user's initials.
|
|
@@ -1570,23 +1584,34 @@ class UserService {
|
|
|
1570
1584
|
*/
|
|
1571
1585
|
get shortLabel() {
|
|
1572
1586
|
const data = this.securityService.getCurrentUser();
|
|
1573
|
-
|
|
1587
|
+
const givenNameInitial = data?.given_name?.trim()?.[0];
|
|
1588
|
+
const familyNameInitial = data?.family_name?.trim()?.[0];
|
|
1589
|
+
return `${givenNameInitial ?? ''}${familyNameInitial ?? ''}`.toUpperCase();
|
|
1574
1590
|
}
|
|
1575
1591
|
get userName() {
|
|
1576
1592
|
const data = this.securityService.getCurrentUser();
|
|
1577
|
-
return
|
|
1593
|
+
return [data?.given_name, data?.family_name].filter(Boolean).join(' ');
|
|
1578
1594
|
}
|
|
1579
1595
|
/**
|
|
1580
1596
|
* Initiates an HTTP request to fetch the user's photo based on their email,
|
|
1581
1597
|
* and updates the `photo` and `photoLoaded` properties accordingly.
|
|
1582
1598
|
*/
|
|
1583
1599
|
getUserPhoto() {
|
|
1584
|
-
const
|
|
1600
|
+
const email = this.securityService.getCurrentUser()?.email;
|
|
1601
|
+
if (!email) {
|
|
1602
|
+
return;
|
|
1603
|
+
}
|
|
1604
|
+
if (this.requestedPhotoEmail === email && (this.photoLoaded || this.photo)) {
|
|
1605
|
+
return;
|
|
1606
|
+
}
|
|
1607
|
+
this.requestedPhotoEmail = email;
|
|
1608
|
+
const url = this.baseDataService.buildUrl(`api/user-profile/get-user-photo?email=${email}`);
|
|
1585
1609
|
this.baseDataService.getBlob(url).then((data) => {
|
|
1586
1610
|
this.createImageFromBlob(data);
|
|
1587
1611
|
this.photoLoaded = true;
|
|
1588
1612
|
}, (error) => {
|
|
1589
1613
|
console.log(error);
|
|
1614
|
+
this.photoLoaded = false;
|
|
1590
1615
|
});
|
|
1591
1616
|
}
|
|
1592
1617
|
/**
|
|
@@ -1980,15 +2005,18 @@ class HttpClient {
|
|
|
1980
2005
|
this.layoutService = inject(LayoutService);
|
|
1981
2006
|
this.baseUrl = "";
|
|
1982
2007
|
this.securityData = null;
|
|
1983
|
-
this.securityWorker = (securityData) =>
|
|
1984
|
-
headers
|
|
2008
|
+
this.securityWorker = (securityData) => {
|
|
2009
|
+
const headers = {
|
|
1985
2010
|
"Accept-language": this.layoutService.language()
|
|
1986
2011
|
? this.layoutService.language()
|
|
1987
2012
|
: "en",
|
|
1988
2013
|
"X-Timezone": this.layoutService.timeZone(),
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
2014
|
+
};
|
|
2015
|
+
if (securityData) {
|
|
2016
|
+
headers.Authorization = `Bearer ${securityData}`;
|
|
2017
|
+
}
|
|
2018
|
+
return { headers };
|
|
2019
|
+
};
|
|
1992
2020
|
this.abortControllers = new Map();
|
|
1993
2021
|
this.customFetch = (...fetchParams) => fetch(...fetchParams);
|
|
1994
2022
|
this.baseApiParams = {
|
|
@@ -3120,7 +3148,8 @@ class MenuComponent {
|
|
|
3120
3148
|
];
|
|
3121
3149
|
}
|
|
3122
3150
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3123
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MenuComponent, isStandalone: true, selector: "app-menu", providers: [MenuApi], viewQueries: [{ propertyName: "menuItemCreateDialogComponent", first: true, predicate: MenuItemCreateDialogComponent, descendants: true }, { propertyName: "menuItemEditDialogComponent", first: true, predicate: MenuItemEditDialogComponent, descendants: true }, { propertyName: "contextMenu", first: true, predicate: ContextMenu, descendants: true }], ngImport: i0, template: `
|
|
3151
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MenuComponent, isStandalone: true, selector: "app-menu", providers: [MenuApi], viewQueries: [{ propertyName: "menuItemCreateDialogComponent", first: true, predicate: MenuItemCreateDialogComponent, descendants: true }, { propertyName: "menuItemEditDialogComponent", first: true, predicate: MenuItemEditDialogComponent, descendants: true }, { propertyName: "contextMenu", first: true, predicate: ContextMenu, descendants: true }], ngImport: i0, template: `
|
|
3152
|
+
<div #empty class="layout-sidebar" (contextmenu)="onContextMenu($event)">
|
|
3124
3153
|
<ul class="layout-menu">
|
|
3125
3154
|
@for (item of menuService.menu; track item; let i = $index) {
|
|
3126
3155
|
<ng-container>
|
|
@@ -3140,10 +3169,10 @@ class MenuComponent {
|
|
|
3140
3169
|
}
|
|
3141
3170
|
</ul>
|
|
3142
3171
|
</div>
|
|
3143
|
-
<p-contextMenu [target]="empty"
|
|
3144
|
-
@if (securityService.isAdmin) {
|
|
3145
|
-
<menu-item-create-dialog
|
|
3146
|
-
<menu-item-edit-dialog
|
|
3172
|
+
<p-contextMenu [target]="empty"/>
|
|
3173
|
+
@if (securityService.isAdmin()) {
|
|
3174
|
+
<menu-item-create-dialog/>
|
|
3175
|
+
<menu-item-edit-dialog/>
|
|
3147
3176
|
}`, isInline: true, dependencies: [{ kind: "component", type: MenuItemComponent, selector: "[app-menuitem]", inputs: ["item", "index", "root", "parentKey", "menuItemCreateDialogComponent", "menuItemEditDialogComponent", "contextMenu"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i1$4.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "component", type: MenuItemCreateDialogComponent, selector: "menu-item-create-dialog", inputs: ["visible"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: MenuItemEditDialogComponent, selector: "menu-item-edit-dialog", inputs: ["visible"], outputs: ["visibleChange"] }] }); }
|
|
3148
3177
|
}
|
|
3149
3178
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuComponent, decorators: [{
|
|
@@ -3162,7 +3191,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
3162
3191
|
providers: [MenuApi],
|
|
3163
3192
|
selector: 'app-menu',
|
|
3164
3193
|
standalone: true,
|
|
3165
|
-
template: `
|
|
3194
|
+
template: `
|
|
3195
|
+
<div #empty class="layout-sidebar" (contextmenu)="onContextMenu($event)">
|
|
3166
3196
|
<ul class="layout-menu">
|
|
3167
3197
|
@for (item of menuService.menu; track item; let i = $index) {
|
|
3168
3198
|
<ng-container>
|
|
@@ -3182,10 +3212,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
3182
3212
|
}
|
|
3183
3213
|
</ul>
|
|
3184
3214
|
</div>
|
|
3185
|
-
<p-contextMenu [target]="empty"
|
|
3186
|
-
@if (securityService.isAdmin) {
|
|
3187
|
-
<menu-item-create-dialog
|
|
3188
|
-
<menu-item-edit-dialog
|
|
3215
|
+
<p-contextMenu [target]="empty"/>
|
|
3216
|
+
@if (securityService.isAdmin()) {
|
|
3217
|
+
<menu-item-create-dialog/>
|
|
3218
|
+
<menu-item-edit-dialog/>
|
|
3189
3219
|
}`
|
|
3190
3220
|
}]
|
|
3191
3221
|
}], propDecorators: { menuItemCreateDialogComponent: [{
|
|
@@ -5917,17 +5947,10 @@ class NotificationService {
|
|
|
5917
5947
|
this.securityService = inject(SecurityService);
|
|
5918
5948
|
this.msgService = inject(MsgService);
|
|
5919
5949
|
this.frontendConfig = inject(OIP_FRONTEND_CONFIG);
|
|
5920
|
-
this.
|
|
5921
|
-
this.securityData = token;
|
|
5922
|
-
if (token) {
|
|
5923
|
-
this.connection.stop().then(() => {
|
|
5924
|
-
this.connection.start().then();
|
|
5925
|
-
});
|
|
5926
|
-
}
|
|
5927
|
-
});
|
|
5950
|
+
this.securityData = null;
|
|
5928
5951
|
this.connection = new signalR.HubConnectionBuilder()
|
|
5929
5952
|
.withUrl(this.resolveHubUrl(), {
|
|
5930
|
-
accessTokenFactory: () => this.securityData,
|
|
5953
|
+
accessTokenFactory: () => this.securityData ?? '',
|
|
5931
5954
|
skipNegotiation: true,
|
|
5932
5955
|
transport: signalR.HttpTransportType.WebSockets
|
|
5933
5956
|
})
|
|
@@ -5942,6 +5965,19 @@ class NotificationService {
|
|
|
5942
5965
|
};
|
|
5943
5966
|
this.msgService.add(opt);
|
|
5944
5967
|
});
|
|
5968
|
+
this.securityService.getAccessToken().subscribe((token) => {
|
|
5969
|
+
this.securityData = token;
|
|
5970
|
+
if (!token) {
|
|
5971
|
+
return;
|
|
5972
|
+
}
|
|
5973
|
+
if (this.connection.state === signalR.HubConnectionState.Disconnected) {
|
|
5974
|
+
this.connection.start().catch((error) => console.error('Failed to start notification connection', error));
|
|
5975
|
+
return;
|
|
5976
|
+
}
|
|
5977
|
+
this.connection.stop().then(() => {
|
|
5978
|
+
this.connection.start().catch((error) => console.error('Failed to restart notification connection', error));
|
|
5979
|
+
});
|
|
5980
|
+
});
|
|
5945
5981
|
}
|
|
5946
5982
|
resolveHubUrl() {
|
|
5947
5983
|
if (this.frontendConfig.notificationHubUrl) {
|