@trackunit/react-core-hooks 1.12.50-alpha-c496ead6241.0 → 1.12.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.
- package/index.cjs.js +39 -64
- package/index.esm.js +41 -66
- package/package.json +4 -5
- package/src/navigation/useHasAccessTo.d.ts +20 -19
package/index.cjs.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var reactCoreContextsApi = require('@trackunit/react-core-contexts-api');
|
|
4
4
|
var react = require('react');
|
|
5
|
-
var esToolkit = require('es-toolkit');
|
|
6
5
|
var irisAppRuntimeCore = require('@trackunit/iris-app-runtime-core');
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -380,88 +379,64 @@ const useModalDialogContext = () => {
|
|
|
380
379
|
return modalDialogContext;
|
|
381
380
|
};
|
|
382
381
|
|
|
383
|
-
const isMultipleCriteriaOneOf = (options) =>
|
|
384
|
-
|
|
385
|
-
const resolveAccess = async (context, options) => {
|
|
386
|
-
if (isMultipleCriteriaOneOf(options) && isMultipleCriteriaRequireAll(options)) {
|
|
387
|
-
throw new Error("Multiple criteria are not allowed, use one of or require all - not both");
|
|
388
|
-
}
|
|
389
|
-
if (isMultipleCriteriaOneOf(options)) {
|
|
390
|
-
const results = await Promise.all(options.oneOf.map(option => context.hasAccessTo(option)));
|
|
391
|
-
return results.some(Boolean);
|
|
392
|
-
}
|
|
393
|
-
if (isMultipleCriteriaRequireAll(options)) {
|
|
394
|
-
const results = await Promise.all(options.requireAll.map(option => context.hasAccessTo(option)));
|
|
395
|
-
return results.every(Boolean);
|
|
396
|
-
}
|
|
397
|
-
return context.hasAccessTo(options);
|
|
382
|
+
const isMultipleCriteriaOneOf = (options) => {
|
|
383
|
+
return typeof options === "object" && "oneOf" in options;
|
|
398
384
|
};
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
hasAccess: undefined,
|
|
402
|
-
error: undefined,
|
|
403
|
-
};
|
|
404
|
-
const accessReducer = (_state, action) => {
|
|
405
|
-
switch (action.type) {
|
|
406
|
-
case "FETCH_START":
|
|
407
|
-
return INITIAL_STATE;
|
|
408
|
-
case "FETCH_SUCCESS":
|
|
409
|
-
return { status: "success", hasAccess: action.hasAccess, error: undefined };
|
|
410
|
-
case "FETCH_ERROR":
|
|
411
|
-
return { status: "error", hasAccess: undefined, error: action.error };
|
|
412
|
-
default:
|
|
413
|
-
throw new Error(`${action} is not a known action`);
|
|
414
|
-
}
|
|
385
|
+
const isMultipleCriteriaRequireAll = (options) => {
|
|
386
|
+
return typeof options === "object" && "requireAll" in options;
|
|
415
387
|
};
|
|
416
388
|
/**
|
|
417
|
-
*
|
|
418
|
-
*
|
|
389
|
+
* This is a hook to use the hasAccessTo in host.
|
|
390
|
+
* You can use this to ensure the page you link to is available for the user to see.
|
|
419
391
|
*
|
|
420
392
|
* @requires NavigationContext
|
|
421
393
|
* @example
|
|
422
394
|
* import { useHasAccessTo } from "@trackunit/react-core-hooks";
|
|
423
395
|
* useHasAccessTo({ assetId: assetInfo?.assetId, page: "movement" })
|
|
424
|
-
* @see
|
|
425
|
-
* @see
|
|
396
|
+
* @see (@link NavigationRuntimeApi)
|
|
397
|
+
* @see (@link HasAccessToOptions)
|
|
398
|
+
* @see (@link HasAccessToOptions.assetId)
|
|
399
|
+
* @see (@link HasAccessToOptions.page)
|
|
400
|
+
* @see (@link HasAccessToOptions.siteId)
|
|
401
|
+
* @see (@link NavigationRuntimeApi)
|
|
426
402
|
*/
|
|
427
403
|
const useHasAccessTo = (options) => {
|
|
428
404
|
const context = react.useContext(reactCoreContextsApi.NavigationContext);
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
if (!esToolkit.isEqual(stableOptions, options)) {
|
|
432
|
-
setStableOptions(options);
|
|
405
|
+
if (!context) {
|
|
406
|
+
throw new Error("useHasAccessTo must be used within an NavigationContext");
|
|
433
407
|
}
|
|
408
|
+
const [hasAccess, setHasAccess] = react.useState();
|
|
409
|
+
const [loading, setLoading] = react.useState(true);
|
|
410
|
+
const [error, setError] = react.useState();
|
|
434
411
|
react.useEffect(() => {
|
|
435
|
-
|
|
436
|
-
return;
|
|
437
|
-
let cancelled = false;
|
|
438
|
-
dispatch({ type: "FETCH_START" });
|
|
439
|
-
const checkAccess = async () => {
|
|
412
|
+
async function checkAccess() {
|
|
440
413
|
try {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
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);
|
|
444
428
|
}
|
|
445
429
|
}
|
|
446
430
|
catch (e) {
|
|
447
|
-
|
|
448
|
-
dispatch({ type: "FETCH_ERROR", error: new Error("Failed to check access", { cause: e }) });
|
|
449
|
-
}
|
|
431
|
+
setError(new Error("Failed to check access", { cause: e }));
|
|
450
432
|
}
|
|
451
|
-
|
|
433
|
+
finally {
|
|
434
|
+
setLoading(false);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
452
437
|
void checkAccess();
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
};
|
|
456
|
-
}, [context, stableOptions]);
|
|
457
|
-
if (!context) {
|
|
458
|
-
throw new Error("useHasAccessTo must be used within a NavigationContext");
|
|
459
|
-
}
|
|
460
|
-
return react.useMemo(() => ({
|
|
461
|
-
hasAccess: state.hasAccess,
|
|
462
|
-
loading: state.status === "loading",
|
|
463
|
-
error: state.error,
|
|
464
|
-
}), [state]);
|
|
438
|
+
}, [context, options]);
|
|
439
|
+
return react.useMemo(() => ({ hasAccess, loading, error }), [hasAccess, loading, error]);
|
|
465
440
|
};
|
|
466
441
|
|
|
467
442
|
/**
|
package/index.esm.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { AnalyticsContext, AssetSortingContext, ConfirmationDialogContext, EnvironmentContext, ErrorHandlingContext, ExportDataContext, FeatureFlagContext, FilterBarContext, TokenContext, ModalDialogContext, NavigationContext, OemBrandingContext, UserSubscriptionContext, TimeRangeContext, ToastContext, CurrentUserContext, CurrentUserPreferenceContext, WidgetConfigContext } from '@trackunit/react-core-contexts-api';
|
|
2
|
-
import { useContext, useMemo, useState, useCallback,
|
|
3
|
-
import { isEqual } from 'es-toolkit';
|
|
2
|
+
import { useContext, useMemo, useState, useCallback, useEffect, useRef } from 'react';
|
|
4
3
|
import { AssetRuntime, CustomerRuntime, EventRuntime, ParamsRuntime, SiteRuntime, WidgetConfigRuntime } from '@trackunit/iris-app-runtime-core';
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -378,88 +377,64 @@ const useModalDialogContext = () => {
|
|
|
378
377
|
return modalDialogContext;
|
|
379
378
|
};
|
|
380
379
|
|
|
381
|
-
const isMultipleCriteriaOneOf = (options) =>
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
if (isMultipleCriteriaOneOf(options)) {
|
|
388
|
-
const results = await Promise.all(options.oneOf.map(option => context.hasAccessTo(option)));
|
|
389
|
-
return results.some(Boolean);
|
|
390
|
-
}
|
|
391
|
-
if (isMultipleCriteriaRequireAll(options)) {
|
|
392
|
-
const results = await Promise.all(options.requireAll.map(option => context.hasAccessTo(option)));
|
|
393
|
-
return results.every(Boolean);
|
|
394
|
-
}
|
|
395
|
-
return context.hasAccessTo(options);
|
|
396
|
-
};
|
|
397
|
-
const INITIAL_STATE = {
|
|
398
|
-
status: "loading",
|
|
399
|
-
hasAccess: undefined,
|
|
400
|
-
error: undefined,
|
|
401
|
-
};
|
|
402
|
-
const accessReducer = (_state, action) => {
|
|
403
|
-
switch (action.type) {
|
|
404
|
-
case "FETCH_START":
|
|
405
|
-
return INITIAL_STATE;
|
|
406
|
-
case "FETCH_SUCCESS":
|
|
407
|
-
return { status: "success", hasAccess: action.hasAccess, error: undefined };
|
|
408
|
-
case "FETCH_ERROR":
|
|
409
|
-
return { status: "error", hasAccess: undefined, error: action.error };
|
|
410
|
-
default:
|
|
411
|
-
throw new Error(`${action} is not a known action`);
|
|
412
|
-
}
|
|
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;
|
|
413
385
|
};
|
|
414
386
|
/**
|
|
415
|
-
*
|
|
416
|
-
*
|
|
387
|
+
* This is a hook to use the hasAccessTo in host.
|
|
388
|
+
* You can use this to ensure the page you link to is available for the user to see.
|
|
417
389
|
*
|
|
418
390
|
* @requires NavigationContext
|
|
419
391
|
* @example
|
|
420
392
|
* import { useHasAccessTo } from "@trackunit/react-core-hooks";
|
|
421
393
|
* useHasAccessTo({ assetId: assetInfo?.assetId, page: "movement" })
|
|
422
|
-
* @see
|
|
423
|
-
* @see
|
|
394
|
+
* @see (@link NavigationRuntimeApi)
|
|
395
|
+
* @see (@link HasAccessToOptions)
|
|
396
|
+
* @see (@link HasAccessToOptions.assetId)
|
|
397
|
+
* @see (@link HasAccessToOptions.page)
|
|
398
|
+
* @see (@link HasAccessToOptions.siteId)
|
|
399
|
+
* @see (@link NavigationRuntimeApi)
|
|
424
400
|
*/
|
|
425
401
|
const useHasAccessTo = (options) => {
|
|
426
402
|
const context = useContext(NavigationContext);
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
if (!isEqual(stableOptions, options)) {
|
|
430
|
-
setStableOptions(options);
|
|
403
|
+
if (!context) {
|
|
404
|
+
throw new Error("useHasAccessTo must be used within an NavigationContext");
|
|
431
405
|
}
|
|
406
|
+
const [hasAccess, setHasAccess] = useState();
|
|
407
|
+
const [loading, setLoading] = useState(true);
|
|
408
|
+
const [error, setError] = useState();
|
|
432
409
|
useEffect(() => {
|
|
433
|
-
|
|
434
|
-
return;
|
|
435
|
-
let cancelled = false;
|
|
436
|
-
dispatch({ type: "FETCH_START" });
|
|
437
|
-
const checkAccess = async () => {
|
|
410
|
+
async function checkAccess() {
|
|
438
411
|
try {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
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);
|
|
442
426
|
}
|
|
443
427
|
}
|
|
444
428
|
catch (e) {
|
|
445
|
-
|
|
446
|
-
dispatch({ type: "FETCH_ERROR", error: new Error("Failed to check access", { cause: e }) });
|
|
447
|
-
}
|
|
429
|
+
setError(new Error("Failed to check access", { cause: e }));
|
|
448
430
|
}
|
|
449
|
-
|
|
431
|
+
finally {
|
|
432
|
+
setLoading(false);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
450
435
|
void checkAccess();
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
};
|
|
454
|
-
}, [context, stableOptions]);
|
|
455
|
-
if (!context) {
|
|
456
|
-
throw new Error("useHasAccessTo must be used within a NavigationContext");
|
|
457
|
-
}
|
|
458
|
-
return useMemo(() => ({
|
|
459
|
-
hasAccess: state.hasAccess,
|
|
460
|
-
loading: state.status === "loading",
|
|
461
|
-
error: state.error,
|
|
462
|
-
}), [state]);
|
|
436
|
+
}, [context, options]);
|
|
437
|
+
return useMemo(() => ({ hasAccess, loading, error }), [hasAccess, loading, error]);
|
|
463
438
|
};
|
|
464
439
|
|
|
465
440
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-core-hooks",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.51",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -8,10 +8,9 @@
|
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"react": "19.0.0",
|
|
11
|
-
"
|
|
12
|
-
"@trackunit/iris-app-runtime-core": "1.
|
|
13
|
-
"@trackunit/
|
|
14
|
-
"@trackunit/react-core-contexts-api": "1.13.45-alpha-c496ead6241.0"
|
|
11
|
+
"@trackunit/iris-app-runtime-core": "1.13.48",
|
|
12
|
+
"@trackunit/iris-app-runtime-core-api": "1.12.46",
|
|
13
|
+
"@trackunit/react-core-contexts-api": "1.13.46"
|
|
15
14
|
},
|
|
16
15
|
"module": "./index.esm.js",
|
|
17
16
|
"main": "./index.cjs.js",
|
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
import
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
type AccessOptions = HasAccessToOptions | MultipleCriteriaOneOf | MultipleCriteriaRequireAll;
|
|
9
|
-
type UseHasAccessToResult = {
|
|
10
|
-
readonly hasAccess: boolean | undefined;
|
|
11
|
-
readonly loading: boolean;
|
|
12
|
-
readonly error: Error | undefined;
|
|
13
|
-
};
|
|
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
|
+
}
|
|
14
8
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
9
|
+
* This is a hook to use the hasAccessTo in host.
|
|
10
|
+
* You can use this to ensure the page you link to is available for the user to see.
|
|
17
11
|
*
|
|
18
12
|
* @requires NavigationContext
|
|
19
13
|
* @example
|
|
20
14
|
* import { useHasAccessTo } from "@trackunit/react-core-hooks";
|
|
21
15
|
* useHasAccessTo({ assetId: assetInfo?.assetId, page: "movement" })
|
|
22
|
-
* @see
|
|
23
|
-
* @see
|
|
16
|
+
* @see (@link NavigationRuntimeApi)
|
|
17
|
+
* @see (@link HasAccessToOptions)
|
|
18
|
+
* @see (@link HasAccessToOptions.assetId)
|
|
19
|
+
* @see (@link HasAccessToOptions.page)
|
|
20
|
+
* @see (@link HasAccessToOptions.siteId)
|
|
21
|
+
* @see (@link NavigationRuntimeApi)
|
|
24
22
|
*/
|
|
25
|
-
export declare const useHasAccessTo: (options:
|
|
26
|
-
|
|
23
|
+
export declare const useHasAccessTo: (options: HasAccessToOptions | MultipleCriteriaOneOf | MultipleCriteriaRequireAll) => {
|
|
24
|
+
hasAccess: boolean | undefined;
|
|
25
|
+
loading: boolean;
|
|
26
|
+
error: Error | undefined;
|
|
27
|
+
};
|