@wolkabout/commons 0.0.50 → 0.0.52

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.
@@ -66,7 +66,7 @@ import * as i32 from '@angular/cdk/drag-drop';
66
66
  import { DragDropModule } from '@angular/cdk/drag-drop';
67
67
  import * as i0 from '@angular/core';
68
68
  import { NgModule, InjectionToken, inject, Injectable, DOCUMENT, Inject, Input, Directive, forwardRef, HostListener, TemplateRef, PLATFORM_ID, Pipe, ViewChild, ContentChild, Optional, Self, Component, input, computed, untracked, signal, viewChild, afterNextRender, effect, output, afterRenderEffect, contentChild } from '@angular/core';
69
- import { BehaviorSubject, catchError, of, switchMap, EMPTY, tap, filter, map, combineLatestWith, forkJoin, from, distinctUntilChanged, shareReplay, merge, Subject, takeUntil, combineLatest, take, first } from 'rxjs';
69
+ import { BehaviorSubject, catchError, of, switchMap, EMPTY, tap, filter, map, combineLatestWith, take, from, concatMap, first, forkJoin, distinctUntilChanged, shareReplay, merge, Subject, takeUntil, combineLatest } from 'rxjs';
70
70
  import { jwtDecode } from 'jwt-decode';
71
71
  import { loadRemoteModule } from '@angular-architects/native-federation';
72
72
  import * as i1$3 from '@angular/platform-browser';
@@ -267,7 +267,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
267
267
  }] });
268
268
 
269
269
  function isContextAccessible(authority, isMainContext) {
270
- return authority.mainContext === isMainContext;
270
+ return !isMainContext || authority.contextId === 1;
271
271
  }
272
272
 
273
273
  var DataType;
@@ -460,38 +460,78 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
460
460
  }]
461
461
  }] });
462
462
 
463
- const createGlobalPermissionsGuard = (fallbackRoute) => {
464
- let checkedRoutes = [];
465
- const permissionsGuard = (permissions) => (route) => {
466
- const router = inject(Router);
467
- const permissionService = inject(PermissionsService);
468
- const permissionsToCheck = Array.isArray(permissions) ? permissions : [permissions];
469
- return permissionService.hasAnyPermission(permissionsToCheck).pipe(map((hasPermissions) => {
470
- if (hasPermissions) {
471
- checkedRoutes = [];
472
- return true;
473
- }
474
- const currentPath = route.routeConfig?.path;
475
- if (!currentPath) {
476
- checkedRoutes = [];
477
- return router.createUrlTree(fallbackRoute);
463
+ /**
464
+ * Returns 'true' if the route is accessible,
465
+ * Returns the first available route if the requested route is NOT accessible
466
+ *
467
+ * Define "requiredPermissions" in the route data section.
468
+ * The permissions are checked globally, and the result will match if ANY permission is present.
469
+ */
470
+ const globalPermissionGuard = (route) => {
471
+ const router = inject(Router);
472
+ const permissionService = inject(PermissionsService);
473
+ return isAccessible(permissionService, route.data['requiredPermissions'] ?? []).pipe(take(1), switchMap((accessible) => {
474
+ if (accessible) {
475
+ return of(true);
476
+ }
477
+ else {
478
+ return findFirstAvailableRoute(route, permissionService).pipe(map((firstAvailableRoute) => {
479
+ return firstAvailableRoute ? router.createUrlTree(firstAvailableRoute) : false;
480
+ }));
481
+ }
482
+ }));
483
+ };
484
+ /**
485
+ * Checks the requiredPermissions data property of the route is present and checks the access through the permission service.
486
+ * The route is accessible if the user has ANY of the required permissions.
487
+ */
488
+ function isAccessible(permissionService, requiredPermissions) {
489
+ if (requiredPermissions.length === 0) {
490
+ return of(true);
491
+ }
492
+ return permissionService.hasAnyPermission(requiredPermissions);
493
+ }
494
+ /**
495
+ * If any of the sibling routes is accessible, returns the first defined sibling.
496
+ * If no sibling route is accessible, checks the parent route and its sibling accessibility.
497
+ * This repeats until an accessible route is found, or every route was tested.
498
+ * If no accessible route is found, returns null;
499
+ */
500
+ function findFirstAvailableRoute(currentRoute, permissionService) {
501
+ function inspectChildren(route, excludedRoute) {
502
+ const children = (route.routeConfig?.children ?? []).filter(child => child.path && child.path !== '**' && child !== excludedRoute);
503
+ if (children.length === 0) {
504
+ return of(null);
505
+ }
506
+ const parentPath = getFullPath(route);
507
+ return from(children).pipe(concatMap(child => isAccessible(permissionService, child.data ? child.data['requiredPermissions'] : []).pipe(take(1), map(accessible => accessible ? [...parentPath, child.path] : null))), first(result => result !== null, null));
508
+ }
509
+ /**
510
+ * Inspects the route for the available routes. The excludedRoute is the one we traversed from.
511
+ * If an accessible child is found, the child will be selected.
512
+ * If no accessible children are found, the parent will be inspected, and process continues...
513
+ */
514
+ function inspectNode(route, excludedRoute) {
515
+ return inspectChildren(route, excludedRoute).pipe(switchMap(result => {
516
+ if (result !== null) {
517
+ return of(result);
478
518
  }
479
- checkedRoutes.push(currentPath);
480
- const siblings = route.parent?.routeConfig?.children?.filter((route) => !!route.path && route.path !== '**' && !checkedRoutes.includes(route.path)) ?? [];
481
- const parentUrl = route.parent?.pathFromRoot
482
- .flatMap((route) => route.url)
483
- .map((url) => url.path)
484
- .filter(Boolean) ?? [];
485
- const nextRoute = siblings[0];
486
- if (nextRoute) {
487
- return router.createUrlTree([...parentUrl, nextRoute.path]);
519
+ if (!route.parent) {
520
+ return of(null);
488
521
  }
489
- checkedRoutes = [];
490
- return router.createUrlTree(fallbackRoute);
522
+ return inspectNode(route.parent, route.routeConfig);
491
523
  }));
492
- };
493
- return permissionsGuard;
494
- };
524
+ }
525
+ if (!currentRoute.parent) {
526
+ return of(null);
527
+ }
528
+ return inspectNode(currentRoute.parent, currentRoute.routeConfig);
529
+ }
530
+ function getFullPath(snapshot) {
531
+ return snapshot.pathFromRoot
532
+ .flatMap(route => route.url.map(segment => segment.path))
533
+ .filter(segment => segment.length > 0);
534
+ }
495
535
 
496
536
  class AssetManager {
497
537
  /**
@@ -7032,5 +7072,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
7032
7072
  * Generated bundle index. Do not edit.
7033
7073
  */
7034
7074
 
7035
- export { AUTHENTICATION_CLIENT, AssetManager, AuthenticationService, AutocompleteChipsComponent, AutocompleteComponent, BasicTimeSeriesGraphComponent, COLORS, CUSTOM_PERIOD, CardLabeledValueComponent, ConfirmationDialogComponent, DEFAULT_LOCALE, DEFAULT_TIMEZONES, DEFAULT_TIME_ZONE, DataType, DateRangeInputComponent, DateTimeFormFieldComponent, DragDropFileUploadComponent, DurationPipe, FeatureRegistry, GoogleMapComponent, ImageDisplayComponent, ImagePreviewComponent, LAST_ACTIVE_TAB_KEY, LOCALES, LabeledValueComponent, LoadedIconComponent, LoadingIndicatorDirective, LocalSortTableComponent, Locale, LocalizedNumberPipe, LocalizedNumericInputDirective, MILLISECONDS_IN_DAY, MapsLoaderService, MasterDetailsViewComponent, MessageTooltipDirective, MissingTranslationHelper, NestedListDataControl, NestedListDataSource, NestedListViewComponent, NgTemplateContentDirective, NotificationService, OverflowClassDirective, PdfViewerComponent, PeriodErrorStateMatcher, PermissionsService, RELATIVE_TIME_PERIODS, RelativeTimePeriod, RequiresAllGlobalOrAssetPermissionsDirective, RequiresAllPermissionDirective, RequiresGlobalOrAsserPermissionDirective, RequiresPermissionDirective, ScrollIntoViewDirective, SharedModule, SimpleDatePipe, SimpleDateTimePipe, SimpleTimePipe, SortPipe, StandardListDataControl, StandardListDataSource, StandardListViewComponent, TIMEZONES, TabulatedChipViewComponent, TabulatedViewComponent, TenantPropertiesService, ThemeService, TreeComponent, TreeNodeComponent, USERS_TIME_ZONE, ValueDisplayComponent, ValueInputBooleanComponent, ValueInputColorComponent, ValueInputComponent, ValueInputDateComponent, ValueInputDurationComponent, ValueInputEnumComponent, ValueInputHexadecimalComponent, ValueInputLinkComponent, ValueInputLocationComponent, ValueInputNumericComponent, ValueInputStringComponent, ValueInputVectorComponent, angularComponents, arrayToObject, chartThemeDark, chartThemeLight, createGlobalPermissionsGuard, daysAway, determineMagnitude, determineMinMaxValues, endOfPeriod, equalsByValue, fileSizeValidator, flatMap, flatten, format, formatDuration, generateRandomString, groupBy, hoursAway, isContextAccessible, lookUpPathPart, lookUpQueryParam, parseDateRangeInputPeriod, parseTimeInput, saveFile, scale, shared, startOfMonth, startOfPeriod, startOfTheDay, startOfWeek, startOfYear, toDate, toEndOfMonth, toEndOfYear, toJsDate, toOffset, toStartOfMonth, toStartOfTheDay, toStartOfWeek, toStartOfYear, toTime, uniqueBy, uniqueFrom, validateAssetName, validateTypeAssetName };
7075
+ export { AUTHENTICATION_CLIENT, AssetManager, AuthenticationService, AutocompleteChipsComponent, AutocompleteComponent, BasicTimeSeriesGraphComponent, COLORS, CUSTOM_PERIOD, CardLabeledValueComponent, ConfirmationDialogComponent, DEFAULT_LOCALE, DEFAULT_TIMEZONES, DEFAULT_TIME_ZONE, DataType, DateRangeInputComponent, DateTimeFormFieldComponent, DragDropFileUploadComponent, DurationPipe, FeatureRegistry, GoogleMapComponent, ImageDisplayComponent, ImagePreviewComponent, LAST_ACTIVE_TAB_KEY, LOCALES, LabeledValueComponent, LoadedIconComponent, LoadingIndicatorDirective, LocalSortTableComponent, Locale, LocalizedNumberPipe, LocalizedNumericInputDirective, MILLISECONDS_IN_DAY, MapsLoaderService, MasterDetailsViewComponent, MessageTooltipDirective, MissingTranslationHelper, NestedListDataControl, NestedListDataSource, NestedListViewComponent, NgTemplateContentDirective, NotificationService, OverflowClassDirective, PdfViewerComponent, PeriodErrorStateMatcher, PermissionsService, RELATIVE_TIME_PERIODS, RelativeTimePeriod, RequiresAllGlobalOrAssetPermissionsDirective, RequiresAllPermissionDirective, RequiresGlobalOrAsserPermissionDirective, RequiresPermissionDirective, ScrollIntoViewDirective, SharedModule, SimpleDatePipe, SimpleDateTimePipe, SimpleTimePipe, SortPipe, StandardListDataControl, StandardListDataSource, StandardListViewComponent, TIMEZONES, TabulatedChipViewComponent, TabulatedViewComponent, TenantPropertiesService, ThemeService, TreeComponent, TreeNodeComponent, USERS_TIME_ZONE, ValueDisplayComponent, ValueInputBooleanComponent, ValueInputColorComponent, ValueInputComponent, ValueInputDateComponent, ValueInputDurationComponent, ValueInputEnumComponent, ValueInputHexadecimalComponent, ValueInputLinkComponent, ValueInputLocationComponent, ValueInputNumericComponent, ValueInputStringComponent, ValueInputVectorComponent, angularComponents, arrayToObject, chartThemeDark, chartThemeLight, daysAway, determineMagnitude, determineMinMaxValues, endOfPeriod, equalsByValue, fileSizeValidator, flatMap, flatten, format, formatDuration, generateRandomString, globalPermissionGuard, groupBy, hoursAway, isContextAccessible, lookUpPathPart, lookUpQueryParam, parseDateRangeInputPeriod, parseTimeInput, saveFile, scale, shared, startOfMonth, startOfPeriod, startOfTheDay, startOfWeek, startOfYear, toDate, toEndOfMonth, toEndOfYear, toJsDate, toOffset, toStartOfMonth, toStartOfTheDay, toStartOfWeek, toStartOfYear, toTime, uniqueBy, uniqueFrom, validateAssetName, validateTypeAssetName };
7036
7076
  //# sourceMappingURL=wolkabout-commons.mjs.map