@admin-layout/gluestack-ui-mobile 9.0.4-alpha.28 → 9.0.4-alpha.39

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/lib/components/AuthWrapper.d.ts +4 -2
  3. package/lib/components/AuthWrapper.js +5 -5
  4. package/lib/components/AuthWrapper.js.map +1 -1
  5. package/lib/components/WithConfiguration.d.ts +18 -0
  6. package/lib/components/WithConfiguration.js +41 -0
  7. package/lib/components/WithConfiguration.js.map +1 -0
  8. package/lib/components/WithPermission.d.ts +31 -0
  9. package/lib/components/WithPermission.js +56 -0
  10. package/lib/components/WithPermission.js.map +1 -0
  11. package/lib/components/WithPolicy.d.ts +13 -0
  12. package/lib/components/WithPolicy.js +18 -0
  13. package/lib/components/WithPolicy.js.map +1 -0
  14. package/lib/components/index.d.ts +5 -0
  15. package/lib/components/index.js +5 -0
  16. package/lib/components/index.js.map +1 -1
  17. package/lib/components/usePermissionAutoFetch.d.ts +63 -0
  18. package/lib/components/usePermissionAutoFetch.js +23 -0
  19. package/lib/components/usePermissionAutoFetch.js.map +1 -0
  20. package/lib/components/useSetting.d.ts +25 -0
  21. package/lib/components/useSetting.js +93 -0
  22. package/lib/components/useSetting.js.map +1 -0
  23. package/lib/components/with-interactions-lifecycle-managed.d.ts +3 -3
  24. package/lib/components/with-interactions-lifecycle-managed.js +19 -9
  25. package/lib/components/with-interactions-lifecycle-managed.js.map +1 -1
  26. package/lib/utils/generateMobileNavigations.js +150 -13
  27. package/lib/utils/generateMobileNavigations.js.map +1 -1
  28. package/package.json +3 -3
  29. package/src/components/AuthWrapper.tsx +5 -4
  30. package/src/components/WithConfiguration.tsx +73 -0
  31. package/src/components/WithPermission.tsx +85 -0
  32. package/src/components/WithPolicy.tsx +32 -0
  33. package/src/components/index.ts +6 -1
  34. package/src/components/usePermissionAutoFetch.tsx +27 -0
  35. package/src/components/useSetting.tsx +144 -0
  36. package/src/components/with-interactions-lifecycle-managed.tsx +56 -14
  37. package/src/utils/generateMobileNavigations.ts +175 -20
@@ -0,0 +1,73 @@
1
+ import * as React from 'react';
2
+ import { Spinner, Box, Text, Heading } from '@gluestack-ui/themed';
3
+ import { IPermissionType, IPreDefinedPermissions, IVisibility } from '@adminide-stack/core';
4
+ import { useSetting, usePermissionAutoFetch } from '@adminide-stack/platform-client';
5
+ import { get } from 'lodash-es';
6
+ import { URI } from '@vscode-alt/monaco-editor/esm/vs/base/common/uri';
7
+
8
+ export interface IWithConfigurationProps {
9
+ children?: React.ReactElement;
10
+ configKey: string;
11
+ permissionKeys?: IPreDefinedPermissions[];
12
+ permissionTypes?: IPermissionType[];
13
+ resourceName?: string;
14
+ settingsUri?: URI;
15
+ }
16
+
17
+ export const WithConfiguration = (props: IWithConfigurationProps) => {
18
+ const { configKey, children, permissionKeys, resourceName, permissionTypes } = props;
19
+
20
+ const {
21
+ data,
22
+ loading: settingsLoading,
23
+ updateConfiguration: _,
24
+ } = useSetting({
25
+ configKey,
26
+ overrides: { resource: props.settingsUri },
27
+ });
28
+ const { data: permissions, loading: permissionLoading } = usePermissionAutoFetch();
29
+
30
+ const isPrivate = React.useMemo(
31
+ () => IVisibility.Private === data?.resolveConfiguration,
32
+ [data?.resolveConfiguration],
33
+ );
34
+
35
+ const hasPermission = React.useMemo(() => {
36
+ if (isPrivate && permissions && Array.isArray(permissionKeys)) {
37
+ return permissionKeys.some((key) => permissionTypes.includes(get(permissions?.resolveConfiguration, key)));
38
+ }
39
+ return false;
40
+ }, [isPrivate, permissions]);
41
+
42
+ const isLoading = React.useMemo(() => permissionLoading || settingsLoading, [permissionLoading, settingsLoading]);
43
+
44
+ if (isLoading) {
45
+ return <Spinner color={'#ff5a00'} />;
46
+ }
47
+
48
+ // if public or has permission
49
+ if (!isPrivate || hasPermission) {
50
+ return children;
51
+ }
52
+
53
+ if (!hasPermission) {
54
+ return (
55
+ <Box>
56
+ <Heading>Missing Permission</Heading>
57
+ <Text>{`You don't have the required permission to access ${resourceName || 'this resource'} `}</Text>
58
+ </Box>
59
+ );
60
+ }
61
+ return (
62
+ <Box>
63
+ <Heading>{`Private ${resourceName || 'Resource'}`}</Heading>
64
+ <Text>{`You are trying to access private ${resourceName || 'resource'}.`}</Text>
65
+ </Box>
66
+ );
67
+ };
68
+
69
+ WithConfiguration.defaultProps = {
70
+ permissionTypes: [IPermissionType.Allow],
71
+ };
72
+
73
+ export const WithConfigurationContainer = (props: IWithConfigurationProps) => <WithConfiguration {...props} />;
@@ -0,0 +1,85 @@
1
+ import * as React from 'react';
2
+ import { Spinner, Box, Text, Heading } from '@gluestack-ui/themed';
3
+ import { IPermissionType, IPreDefinedPermissions } from '@adminide-stack/core';
4
+ import { get } from 'lodash-es';
5
+ import { usePermissionAutoFetch } from './usePermissionAutoFetch';
6
+ import { isUserAuthenticated } from '@adminide-stack/user-auth0-client';
7
+
8
+ export enum WithPermissionBehaviour {
9
+ hide,
10
+ showUnAuthorized,
11
+ showAlternative,
12
+ }
13
+
14
+ export interface IWithPermissionProps {
15
+ children?: React.ReactElement;
16
+ permissionKeys: IPreDefinedPermissions[];
17
+ permissionTypes?: IPermissionType[];
18
+ behaviour?: WithPermissionBehaviour;
19
+ message?: string;
20
+ alternative?: React.ReactElement;
21
+ render?: React.FunctionComponent<{ hasPermission: boolean }>;
22
+ }
23
+
24
+ export const WithPermission = ({
25
+ permissionKeys,
26
+ children,
27
+ permissionTypes = [IPermissionType.Allow],
28
+ behaviour = WithPermissionBehaviour.hide,
29
+ message = "You don't have permission to access this resource, contact owner",
30
+ alternative,
31
+ render,
32
+ }: IWithPermissionProps) => {
33
+ const { data: permissions, loading: permissionLoading, refetch } = usePermissionAutoFetch();
34
+ const { authenticated } = isUserAuthenticated();
35
+
36
+ const hasPermission = React.useMemo(() => {
37
+ // const permissionData = {...permissions?.resolveConfiguration,account:{...permissions?.resolveConfiguration?.account,user:{...permissions?.resolveConfiguration?.account?.user,secure:authenticated ? 'Allow' : 'Deny'}}};
38
+ return permissionKeys.some((key) => permissionTypes.includes(get(permissions?.resolveConfiguration, key)));
39
+ }, [permissions, permissionTypes, permissionKeys]);
40
+
41
+ console.log('hasPermission', hasPermission);
42
+ console.log('permissionKeys', permissionKeys);
43
+ console.log('permissions', JSON.stringify(permissions));
44
+
45
+ if (permissionLoading) {
46
+ return <Spinner />;
47
+ }
48
+
49
+ if (typeof render === 'function') {
50
+ return render({ hasPermission });
51
+ }
52
+
53
+ if (hasPermission) {
54
+ return children;
55
+ }
56
+
57
+ if (behaviour === WithPermissionBehaviour.showAlternative) {
58
+ return alternative;
59
+ }
60
+ if (behaviour === WithPermissionBehaviour.showUnAuthorized) {
61
+ if (permissionLoading) {
62
+ return <Spinner />;
63
+ }
64
+ return (
65
+ <Box>
66
+ <Heading>Missing Permission</Heading>
67
+ <Text>{message}</Text>
68
+ </Box>
69
+ );
70
+ }
71
+ return null;
72
+ };
73
+
74
+ WithPermission.defaultProps = {
75
+ permissionTypes: [IPermissionType.Allow],
76
+ behaviour: WithPermissionBehaviour.hide,
77
+ message: "You don't have permission to access this resource, contact owner",
78
+ disabledProps: {
79
+ disabled: true,
80
+ },
81
+ };
82
+
83
+ export const WithPermissionContainer = React.memo((props: IWithPermissionProps) => <WithPermission {...props} />);
84
+ export default WithPermissionContainer;
85
+ // export const WithPermissionContainer = (props: IWithPermissionProps) => <WithPermission {...props} />;
@@ -0,0 +1,32 @@
1
+ import * as React from 'react';
2
+ import { ReactElement } from 'react';
3
+ import { Spinner } from '@gluestack-ui/themed';
4
+ import { logger } from '@cdm-logger/client';
5
+ import { useSetting } from '@adminide-stack/platform-client';
6
+
7
+ interface IProps {
8
+ policyKey: string;
9
+ Child: React.FC<{ value: unknown }>;
10
+ childProps?: Record<string, any>;
11
+ showLoading?: boolean;
12
+ skeletonProps?: Record<string, unknown>;
13
+ }
14
+
15
+ export const WithPolicy = (props: IProps): ReactElement => {
16
+ const { policyKey, showLoading, Child, skeletonProps = {}, childProps = {} } = props;
17
+ const {
18
+ data: policy,
19
+ loading,
20
+ error,
21
+ } = useSetting({
22
+ configKey: policyKey,
23
+ });
24
+ if (error) {
25
+ logger.error(error, `WithPolicy.name`);
26
+ }
27
+ if (showLoading && loading) {
28
+ return <Spinner color={'#ff5a00'} />;
29
+ }
30
+
31
+ return <Child {...childProps} value={policy?.resolveConfiguration} />;
32
+ };
@@ -7,4 +7,9 @@ export * from './ErrorBounday';
7
7
  export * from './NavigationComponent';
8
8
  export * from './ToastAlert';
9
9
  export * from './with-interactions-managed';
10
- export * from './AuthWrapper'
10
+ export * from './AuthWrapper';
11
+ export * from './WithPermission';
12
+ export * from './WithConfiguration';
13
+ export * from './WithPolicy';
14
+ export * from './usePermissionAutoFetch';
15
+ export * from './useSetting';
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { IResourceAuthority, IConfigFragmentName } from '@adminide-stack/core';
3
+ import { useGetTeamContextQuery } from '@adminide-stack/platform-client';
4
+ import { useSetting } from './useSetting';
5
+
6
+ interface userPermissionAutoFetchProps {
7
+ configKey?: string;
8
+ }
9
+ export const usePermissionAutoFetch = (options?: userPermissionAutoFetchProps) => {
10
+ const { data, loading } = useGetTeamContextQuery();
11
+ const teamData = React.useMemo(() => data?.getTeamContext, [data]);
12
+ // const teamData = data?.getTeamContext;
13
+
14
+ const { loading: settingLoading, ...remaining } = useSetting({
15
+ configKey: options?.configKey || '',
16
+ overrides: {
17
+ resource: teamData?.teamUri ?? null,
18
+ },
19
+ options: {
20
+ forceExist: false,
21
+ authority: IResourceAuthority.Defaultpermissions,
22
+ fragment: IConfigFragmentName.Roles,
23
+ },
24
+ });
25
+ console.log('---remaining', JSON.stringify(remaining?.data));
26
+ return { ...remaining, loading: loading || settingLoading };
27
+ };
@@ -0,0 +1,144 @@
1
+ import React from 'react';
2
+ import {
3
+ IResolveConfigurationQuery,
4
+ IResolveConfigurationQueryVariables,
5
+ IPreferencesInput,
6
+ IPreferencesOpenOptionsInput,
7
+ IUpdateConfigurationMutation,
8
+ IConfigurationOverridesInput,
9
+ ConfigurationTarget,
10
+ } from '@adminide-stack/core';
11
+ import { QueryResult } from '@apollo/client/react';
12
+ import { omitBy, isNil } from 'lodash-es';
13
+ import { ExecutionResult } from 'graphql';
14
+ import {
15
+ useResolveConfigurationQuery,
16
+ useOpenPreferencesSettingsQuery,
17
+ useUpdateConfigurationMutation,
18
+ } from '@adminide-stack/platform-client';
19
+
20
+ export interface ISettingsVariable {
21
+ overrides?: IConfigurationOverridesInput;
22
+ configKey: string;
23
+ options?: IPreferencesOpenOptionsInput;
24
+ skip?: boolean;
25
+ }
26
+
27
+ interface IResponse extends QueryResult<IResolveConfigurationQuery, IResolveConfigurationQueryVariables> {
28
+ preferencesInput?: IPreferencesInput;
29
+ updateConfiguration?: ({
30
+ updateKey,
31
+ value,
32
+ updateOverrides,
33
+ target,
34
+ }: {
35
+ updateKey?: string;
36
+ value: string | boolean | number;
37
+ updateOverrides?: IConfigurationOverridesInput;
38
+ target?: ConfigurationTarget;
39
+ }) => Promise<ExecutionResult<IUpdateConfigurationMutation>>;
40
+ }
41
+
42
+ /**
43
+ * Provides configuration for Organization and OrganizationResources. By default, it provides Organization configuration.
44
+ * If you need `resource` level configuration then, you need to provide resource URI in `overrides`.
45
+ * @param baseOptions
46
+ */
47
+ export const useSetting = (settingsVariable: ISettingsVariable): IResponse => {
48
+ const { overrides, configKey, options, skip = false } = settingsVariable;
49
+ const targetResource = overrides?.resource ?? null;
50
+ console.log('---targetResource', targetResource);
51
+ let prefLoaded = false;
52
+ const {
53
+ data: prefData,
54
+ error: prefError,
55
+ loading: perfLoading,
56
+ refetch: refetchPrefData,
57
+ } = useOpenPreferencesSettingsQuery({
58
+ variables: { resource: targetResource, options },
59
+ fetchPolicy: 'cache-and-network', // to make `{always: true}` to work
60
+ skip: prefLoaded,
61
+ });
62
+ React.useEffect(() => {
63
+ refetchPrefData({ resource: targetResource, options });
64
+ }, [targetResource]);
65
+ prefLoaded = perfLoading || skip;
66
+ console.log('---prefData', prefData);
67
+ const [updateConfigurationMutation] = useUpdateConfigurationMutation();
68
+ const modifiedOverrides = {
69
+ ...overrides,
70
+ resource: targetResource ? prefData?.openPreferencesSettings?.editableSettingsInput ?? null : null,
71
+ };
72
+ const defaultOverrides = omitBy(modifiedOverrides, isNil);
73
+ let {
74
+ data: settingsData,
75
+ error: settingError,
76
+ loading: settingLoading,
77
+ ...remaining
78
+ } = useResolveConfigurationQuery({
79
+ variables: {
80
+ input: prefData?.openPreferencesSettings ?? null,
81
+ key: configKey,
82
+ overrides: defaultOverrides,
83
+ },
84
+ fetchPolicy: 'cache-and-network', // to make `{always: true}` to work
85
+ skip: prefLoaded || !!prefError || !prefData?.openPreferencesSettings?.editableSettingsInput,
86
+ });
87
+
88
+ React.useEffect(() => {
89
+ remaining?.refetch({
90
+ input: prefData?.openPreferencesSettings ?? null,
91
+ key: configKey,
92
+ overrides: defaultOverrides,
93
+ });
94
+ }, [prefData]);
95
+
96
+ let loading = true;
97
+ if (!settingLoading && !prefLoaded) {
98
+ loading = false;
99
+ }
100
+ const error = settingError || prefError;
101
+ console.log('---error', error);
102
+ console.log('---settingError', settingError);
103
+ console.log('---prefError', prefError);
104
+ if (error) {
105
+ return {
106
+ error,
107
+ data: undefined,
108
+ loading: false,
109
+ ...remaining,
110
+ };
111
+ }
112
+ if (loading) {
113
+ return {
114
+ error,
115
+ data: undefined,
116
+ loading,
117
+ ...remaining,
118
+ };
119
+ }
120
+
121
+ const updateConfiguration = ({ value, updateKey, updateOverrides, target }) => {
122
+ return updateConfigurationMutation({
123
+ variables: {
124
+ key: updateKey || configKey,
125
+ value,
126
+ target,
127
+ overrides: updateOverrides || defaultOverrides,
128
+ input: prefData?.openPreferencesSettings,
129
+ },
130
+ });
131
+ };
132
+
133
+ console.log('--USESetting ', JSON.stringify(settingsData?.resolveConfiguration));
134
+ return {
135
+ data: settingsData,
136
+ loading,
137
+ error,
138
+ ...remaining,
139
+ preferencesInput: {
140
+ ...prefData?.openPreferencesSettings,
141
+ },
142
+ updateConfiguration,
143
+ } as any;
144
+ };
@@ -7,6 +7,8 @@ import { useAfterInteractions } from '../hooks/use-after-interactions';
7
7
  import { Box, Spinner, SafeAreaView, Center } from '@gluestack-ui/themed';
8
8
  import hoistNonReactStatics from 'hoist-non-react-statics';
9
9
  import { Platform } from 'react-native';
10
+ import { WithPermissionContainer } from './WithPermission';
11
+ import { isUserAuthenticated } from '@adminide-stack/user-auth0-client';
10
12
 
11
13
  const LoadingComponent = () => (
12
14
  // <SafeAreaView flex={1}>
@@ -16,12 +18,25 @@ const LoadingComponent = () => (
16
18
  // </SafeAreaView>
17
19
  );
18
20
 
21
+ const LifecycleComponent = ({ children }) => {
22
+ const { authenticated } = isUserAuthenticated();
23
+ if (authenticated) {
24
+ return (
25
+ <Lifecycle renderWhenPhase={LifecyclePhase.Restored} loadingRenderer={LoadingComponent}>
26
+ {children}
27
+ </Lifecycle>
28
+ );
29
+ } else {
30
+ return <>{children}</>;
31
+ }
32
+ };
33
+
19
34
  const IntractionComponent = ({ children, interationTime }) => {
20
35
  const { interactionsComplete, opacity, setInteractionsTimeOut } = useAfterInteractions();
21
36
  React.useEffect(() => {
22
37
  if (interationTime) setInteractionsTimeOut(interationTime);
23
38
  }, [interationTime]);
24
- console.log('interactionsComplete', interactionsComplete);
39
+ // console.log('interactionsComplete', interactionsComplete);
25
40
  return (
26
41
  <>
27
42
  {interactionsComplete ? (
@@ -46,13 +61,11 @@ const IntractionWithLifeCycleComponent = ({ children, interationTime }) => {
46
61
  React.useEffect(() => {
47
62
  if (interationTime) setInteractionsTimeOut(interationTime);
48
63
  }, [interationTime]);
49
- console.log('interactionsComplete', interactionsComplete);
64
+ // console.log('interactionsComplete', interactionsComplete);
50
65
  return (
51
66
  <>
52
67
  {interactionsComplete ? (
53
- <Lifecycle renderWhenPhase={LifecyclePhase.Restored} loadingRenderer={LoadingComponent}>
54
- {children}
55
- </Lifecycle>
68
+ <LifecycleComponent>{children}</LifecycleComponent>
56
69
  ) : (
57
70
  <Animated.View
58
71
  style={{
@@ -68,38 +81,67 @@ const IntractionWithLifeCycleComponent = ({ children, interationTime }) => {
68
81
  );
69
82
  };
70
83
 
71
- export function withInteractionsManaged(component: any, interationTime?: number) {
84
+ export function withInteractionsManaged(component: any, interationTime?: number, permissionKeys = null) {
72
85
  return (
73
86
  <>
74
87
  {Platform.OS === 'ios' ? (
75
- { component }
88
+ <>
89
+ {component}
90
+ {/* {permissionKeys ? (
91
+ <WithPermissionContainer permissionKeys={permissionKeys}>{component}</WithPermissionContainer>
92
+ ) : (
93
+ component
94
+ )} */}
95
+ </>
76
96
  ) : (
77
- <IntractionComponent interationTime={interationTime}>{component}</IntractionComponent>
97
+ <IntractionComponent interationTime={interationTime}>
98
+ {component}
99
+ {/* {permissionKeys ? (
100
+ <WithPermissionContainer permissionKeys={permissionKeys}>{component}</WithPermissionContainer>
101
+ ) : (
102
+ component
103
+ )} */}
104
+ </IntractionComponent>
78
105
  )}
79
106
  </>
80
107
  );
81
108
  }
82
109
 
83
- export function withLifeCycleInteractionsManaged(component: any, interationTime?: number) {
110
+ export function withLifeCycleInteractionsManaged(component: any, interationTime?: number, permissionKeys = null) {
84
111
  return (
85
112
  <>
86
113
  {Platform.OS === 'ios' ? (
87
- <Lifecycle renderWhenPhase={LifecyclePhase.Restored} loadingRenderer={LoadingComponent}>
114
+ <LifecycleComponent>
88
115
  {component}
89
- </Lifecycle>
116
+ {/* {permissionKeys ? (
117
+ <WithPermissionContainer permissionKeys={permissionKeys}>{component}</WithPermissionContainer>
118
+ ) : (
119
+ component
120
+ )} */}
121
+ </LifecycleComponent>
90
122
  ) : (
91
123
  <IntractionWithLifeCycleComponent interationTime={interationTime}>
92
124
  {component}
125
+ {/* {permissionKeys ? (
126
+ <WithPermissionContainer permissionKeys={permissionKeys}>{component}</WithPermissionContainer>
127
+ ) : (
128
+ component
129
+ )} */}
93
130
  </IntractionWithLifeCycleComponent>
94
131
  )}
95
132
  </>
96
133
  );
97
134
  }
98
135
 
99
- export function withLifeCycleManaged(component: any) {
136
+ export function withLifeCycleManaged(component: any, permissionKeys = null) {
100
137
  return (
101
- <Lifecycle renderWhenPhase={LifecyclePhase.Restored} loadingRenderer={LoadingComponent}>
138
+ <LifecycleComponent>
102
139
  {component}
103
- </Lifecycle>
140
+ {/* {permissionKeys ? (
141
+ <WithPermissionContainer permissionKeys={permissionKeys}>{component}</WithPermissionContainer>
142
+ ) : (
143
+ component
144
+ )} */}
145
+ </LifecycleComponent>
104
146
  );
105
147
  }