@wolkabout/commons 0.0.49 → 0.0.51

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 !isMainContext || authority.contextId === 1;
270
+ return authority.mainContext === isMainContext;
271
271
  }
272
272
 
273
273
  var DataType;
@@ -460,34 +460,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
460
460
  }]
461
461
  }] });
462
462
 
463
- const createGlobalPermissionsGuard = (availableRoutesGetter, fallbackRoute, parentRoutes) => {
464
- let checkedRoutes = [];
465
- const permissionsGuard = (permissions) => (route, state) => {
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 currentRoute = route.routeConfig?.path;
475
- if (!currentRoute) {
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
+ * Returns the fallback route if there are no routes accessible.
467
+ *
468
+ * Define "requiredPermissions" in the route data section.
469
+ * The permissions are checked globally, and the result will match if ANY permission is present.
470
+ */
471
+ const globalPermissionGuard = (route) => {
472
+ const router = inject(Router);
473
+ const permissionService = inject(PermissionsService);
474
+ return isAccessible(permissionService, route.data['requiredPermissions'] ?? []).pipe(take(1), switchMap((accessible) => {
475
+ if (accessible) {
476
+ return of(true);
477
+ }
478
+ else {
479
+ return findFirstAvailableRoute(route, permissionService).pipe(map((firstAvailableRoute) => {
480
+ return firstAvailableRoute ? router.createUrlTree(firstAvailableRoute) : false;
481
+ }));
482
+ }
483
+ }));
484
+ };
485
+ /**
486
+ * Checks the requiredPermissions data property of the route is present and checks the access through the permission service.
487
+ * The route is accessible if the user has ANY of the required permissions.
488
+ */
489
+ function isAccessible(permissionService, requiredPermissions) {
490
+ if (requiredPermissions.length === 0) {
491
+ return of(true);
492
+ }
493
+ return permissionService.hasAnyPermission(requiredPermissions);
494
+ }
495
+ /**
496
+ * If any of the sibling routes is accessible, returns the first defined sibling.
497
+ * If no sibling route is accessible, checks the parent route and its sibling accessibility.
498
+ * This repeats until an accessible route is found, or every route was tested.
499
+ * If no accessible route is found, returns null;
500
+ */
501
+ function findFirstAvailableRoute(currentRoute, permissionService) {
502
+ function inspectChildren(route, excludedRoute) {
503
+ const children = (route.routeConfig?.children ?? []).filter(child => child.path && child.path !== '**' && child !== excludedRoute);
504
+ if (children.length === 0) {
505
+ return of(null);
506
+ }
507
+ const parentPath = getFullPath(route);
508
+ 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));
509
+ }
510
+ /**
511
+ * Inspects the route for the available routes. The excludedRoute is the one we traversed from.
512
+ * If an accessible child is found, the child will be selected.
513
+ * If no accessible children are found, the parent will be inspected, and process continues...
514
+ */
515
+ function inspectNode(route, excludedRoute) {
516
+ return inspectChildren(route, excludedRoute).pipe(switchMap(result => {
517
+ if (result !== null) {
518
+ return of(result);
478
519
  }
479
- checkedRoutes.push(currentRoute);
480
- const availableRoutes = availableRoutesGetter()?.filter(route => route.path !== '**');
481
- const nextRoute = availableRoutes?.find((route) => route.path !== currentRoute && !checkedRoutes.includes(route.path));
482
- if (nextRoute) {
483
- return router.createUrlTree(parentRoutes ? [...parentRoutes, nextRoute.path] : [nextRoute.path]);
520
+ if (!route.parent) {
521
+ return of(null);
484
522
  }
485
- checkedRoutes = [];
486
- return router.createUrlTree(fallbackRoute);
523
+ return inspectNode(route.parent, route.routeConfig);
487
524
  }));
488
- };
489
- return permissionsGuard;
490
- };
525
+ }
526
+ if (!currentRoute.parent) {
527
+ return of(null);
528
+ }
529
+ return inspectNode(currentRoute.parent, currentRoute.routeConfig);
530
+ }
531
+ function getFullPath(snapshot) {
532
+ return snapshot.pathFromRoot
533
+ .flatMap(route => route.url.map(segment => segment.path))
534
+ .filter(segment => segment.length > 0);
535
+ }
491
536
 
492
537
  class AssetManager {
493
538
  /**
@@ -7028,5 +7073,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
7028
7073
  * Generated bundle index. Do not edit.
7029
7074
  */
7030
7075
 
7031
- 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 };
7076
+ 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 };
7032
7077
  //# sourceMappingURL=wolkabout-commons.mjs.map