@trackunit/react-core-hooks 1.9.12 → 1.9.13

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/index.cjs.js CHANGED
@@ -379,6 +379,12 @@ const useModalDialogContext = () => {
379
379
  return modalDialogContext;
380
380
  };
381
381
 
382
+ const isMultipleCriteriaOneOf = (options) => {
383
+ return typeof options === "object" && "oneOf" in options;
384
+ };
385
+ const isMultipleCriteriaRequireAll = (options) => {
386
+ return typeof options === "object" && "requireAll" in options;
387
+ };
382
388
  /**
383
389
  * This is a hook to use the hasAccessTo in host.
384
390
  * You can use this to ensure the page you link to is available for the user to see.
@@ -405,8 +411,21 @@ const useHasAccessTo = (options) => {
405
411
  react.useEffect(() => {
406
412
  async function checkAccess() {
407
413
  try {
408
- const doHaveAccess = await context?.hasAccessTo(options);
409
- setHasAccess(doHaveAccess);
414
+ if (isMultipleCriteriaOneOf(options) && isMultipleCriteriaRequireAll(options)) {
415
+ throw new Error("Multiple criteria are not allowed, use one of or require all - not both");
416
+ }
417
+ if (isMultipleCriteriaOneOf(options)) {
418
+ const doHaveAccess = await Promise.all(options.oneOf.map(option => context?.hasAccessTo(option)));
419
+ setHasAccess(doHaveAccess.some(access => access));
420
+ }
421
+ else if (isMultipleCriteriaRequireAll(options)) {
422
+ const doHaveAccess = await Promise.all(options.requireAll.map(option => context?.hasAccessTo(option)));
423
+ setHasAccess(doHaveAccess.every(access => access));
424
+ }
425
+ else {
426
+ const doHaveAccess = await context?.hasAccessTo(options);
427
+ setHasAccess(doHaveAccess);
428
+ }
410
429
  }
411
430
  catch (e) {
412
431
  setError(new Error("Failed to check access", { cause: e }));
@@ -860,6 +879,19 @@ const setGlobalLanguage = (language) => {
860
879
  }
861
880
  };
862
881
 
882
+ /**
883
+ * Hook that checks if the current user has a given permission.
884
+ *
885
+ * @param requiredPermission - The permission to check for typesafe string.
886
+ * @returns {HasAccess} - true if the user has the permission, false if not and null if we could not determine.
887
+ */
888
+ const useUserPermission = (requiredPermission) => {
889
+ const { permissions } = useCurrentUser();
890
+ return react.useMemo(() => {
891
+ return permissions?.includes(requiredPermission) ?? false;
892
+ }, [permissions, requiredPermission]);
893
+ };
894
+
863
895
  /**
864
896
  * This is a hook to use the WidgetConfigProvider.
865
897
  *
@@ -988,6 +1020,7 @@ exports.useSiteRuntime = useSiteRuntime;
988
1020
  exports.useTimeRange = useTimeRange;
989
1021
  exports.useToast = useToast;
990
1022
  exports.useToken = useToken;
1023
+ exports.useUserPermission = useUserPermission;
991
1024
  exports.useUserSubscription = useUserSubscription;
992
1025
  exports.useWidgetConfig = useWidgetConfig;
993
1026
  exports.useWidgetConfigAsync = useWidgetConfigAsync;
package/index.esm.js CHANGED
@@ -377,6 +377,12 @@ const useModalDialogContext = () => {
377
377
  return modalDialogContext;
378
378
  };
379
379
 
380
+ const isMultipleCriteriaOneOf = (options) => {
381
+ return typeof options === "object" && "oneOf" in options;
382
+ };
383
+ const isMultipleCriteriaRequireAll = (options) => {
384
+ return typeof options === "object" && "requireAll" in options;
385
+ };
380
386
  /**
381
387
  * This is a hook to use the hasAccessTo in host.
382
388
  * You can use this to ensure the page you link to is available for the user to see.
@@ -403,8 +409,21 @@ const useHasAccessTo = (options) => {
403
409
  useEffect(() => {
404
410
  async function checkAccess() {
405
411
  try {
406
- const doHaveAccess = await context?.hasAccessTo(options);
407
- setHasAccess(doHaveAccess);
412
+ if (isMultipleCriteriaOneOf(options) && isMultipleCriteriaRequireAll(options)) {
413
+ throw new Error("Multiple criteria are not allowed, use one of or require all - not both");
414
+ }
415
+ if (isMultipleCriteriaOneOf(options)) {
416
+ const doHaveAccess = await Promise.all(options.oneOf.map(option => context?.hasAccessTo(option)));
417
+ setHasAccess(doHaveAccess.some(access => access));
418
+ }
419
+ else if (isMultipleCriteriaRequireAll(options)) {
420
+ const doHaveAccess = await Promise.all(options.requireAll.map(option => context?.hasAccessTo(option)));
421
+ setHasAccess(doHaveAccess.every(access => access));
422
+ }
423
+ else {
424
+ const doHaveAccess = await context?.hasAccessTo(options);
425
+ setHasAccess(doHaveAccess);
426
+ }
408
427
  }
409
428
  catch (e) {
410
429
  setError(new Error("Failed to check access", { cause: e }));
@@ -858,6 +877,19 @@ const setGlobalLanguage = (language) => {
858
877
  }
859
878
  };
860
879
 
880
+ /**
881
+ * Hook that checks if the current user has a given permission.
882
+ *
883
+ * @param requiredPermission - The permission to check for typesafe string.
884
+ * @returns {HasAccess} - true if the user has the permission, false if not and null if we could not determine.
885
+ */
886
+ const useUserPermission = (requiredPermission) => {
887
+ const { permissions } = useCurrentUser();
888
+ return useMemo(() => {
889
+ return permissions?.includes(requiredPermission) ?? false;
890
+ }, [permissions, requiredPermission]);
891
+ };
892
+
861
893
  /**
862
894
  * This is a hook to use the WidgetConfigProvider.
863
895
  *
@@ -956,4 +988,4 @@ const useWidgetConfig = () => {
956
988
  return result;
957
989
  };
958
990
 
959
- export { fetchAssetBlobUrl, useAnalytics, useAssetRuntime, useAssetSorting, useConfirmationDialog, useCurrentUser, useCurrentUserLanguage, useCurrentUserSystemOfMeasurement, useCurrentUserTimeZonePreference, useCustomerRuntime, useEnvironment, useErrorHandler, useErrorHandlerOrNull, useEventRuntime, useExportDataContext, useFeatureBranchQueryString, useFeatureFlags, useFilterBarContext, useHasAccessTo, useImageUploader, useIrisAppId, useIrisAppImage, useIrisAppName, useModalDialogContext, useNavigateInHost, useOemBrandingContext, useSiteRuntime, useTimeRange, useToast, useToken, useUserSubscription, useWidgetConfig, useWidgetConfigAsync };
991
+ export { fetchAssetBlobUrl, useAnalytics, useAssetRuntime, useAssetSorting, useConfirmationDialog, useCurrentUser, useCurrentUserLanguage, useCurrentUserSystemOfMeasurement, useCurrentUserTimeZonePreference, useCustomerRuntime, useEnvironment, useErrorHandler, useErrorHandlerOrNull, useEventRuntime, useExportDataContext, useFeatureBranchQueryString, useFeatureFlags, useFilterBarContext, useHasAccessTo, useImageUploader, useIrisAppId, useIrisAppImage, useIrisAppName, useModalDialogContext, useNavigateInHost, useOemBrandingContext, useSiteRuntime, useTimeRange, useToast, useToken, useUserPermission, useUserSubscription, useWidgetConfig, useWidgetConfigAsync };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-core-hooks",
3
- "version": "1.9.12",
3
+ "version": "1.9.13",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -8,9 +8,9 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "react": "19.0.0",
11
- "@trackunit/iris-app-runtime-core": "1.10.12",
12
- "@trackunit/iris-app-runtime-core-api": "1.9.12",
13
- "@trackunit/react-core-contexts-api": "1.10.12"
11
+ "@trackunit/iris-app-runtime-core": "1.10.13",
12
+ "@trackunit/iris-app-runtime-core-api": "1.9.13",
13
+ "@trackunit/react-core-contexts-api": "1.10.13"
14
14
  },
15
15
  "module": "./index.esm.js",
16
16
  "main": "./index.cjs.js",
package/src/index.d.ts CHANGED
@@ -25,4 +25,5 @@ export * from "./token/useToken";
25
25
  export * from "./useFeatureBranchQueryString";
26
26
  export * from "./user/useCurrentUser";
27
27
  export * from "./user/useCurrentUserPreference";
28
+ export * from "./user/useUserPermission";
28
29
  export * from "./widgetConfig/useWidgetConfig";
@@ -1,4 +1,10 @@
1
1
  import { HasAccessToOptions } from "@trackunit/iris-app-runtime-core-api";
2
+ export interface MultipleCriteriaOneOf {
3
+ oneOf: Array<HasAccessToOptions>;
4
+ }
5
+ export interface MultipleCriteriaRequireAll {
6
+ requireAll: Array<HasAccessToOptions>;
7
+ }
2
8
  /**
3
9
  * This is a hook to use the hasAccessTo in host.
4
10
  * You can use this to ensure the page you link to is available for the user to see.
@@ -14,7 +20,7 @@ import { HasAccessToOptions } from "@trackunit/iris-app-runtime-core-api";
14
20
  * @see (@link HasAccessToOptions.siteId)
15
21
  * @see (@link NavigationRuntimeApi)
16
22
  */
17
- export declare const useHasAccessTo: (options: HasAccessToOptions) => {
23
+ export declare const useHasAccessTo: (options: HasAccessToOptions | MultipleCriteriaOneOf | MultipleCriteriaRequireAll) => {
18
24
  hasAccess: boolean | undefined;
19
25
  loading: boolean;
20
26
  error: Error | undefined;