@orchestrator-ui/orchestrator-ui-components 0.9.1 → 0.11.0
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/.turbo/turbo-build.log +5 -5
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +12 -11
- package/CHANGELOG.md +18 -0
- package/dist/index.d.ts +115 -43
- package/dist/index.js +5780 -5482
- package/package.json +2 -2
- package/src/components/WfoAuth/WfoAuth.tsx +35 -7
- package/src/components/WfoAuth/WfoIsAllowedToRender.tsx +17 -0
- package/src/components/WfoAuth/index.ts +1 -0
- package/src/components/WfoBadges/WfoFailedTasksBadge/WfoFailedTasksBadge.tsx +1 -3
- package/src/components/WfoBadges/WfoHeaderBadge/WfoHeaderBadge.tsx +1 -1
- package/src/components/WfoBadges/WfoSubscriptionSyncStatusBadge/WfoSubscriptionSyncStatusBadge.stories.tsx +27 -0
- package/src/components/WfoBadges/WfoSubscriptionSyncStatusBadge/WfoSubscriptionSyncStatusBadge.tsx +45 -0
- package/src/components/WfoBadges/WfoSubscriptionSyncStatusBadge/index.ts +1 -0
- package/src/components/WfoBadges/WfoWebsocketStatusBadge/WfoWebsocketStatusBadge.stories.tsx +13 -0
- package/src/components/WfoBadges/WfoWebsocketStatusBadge/WfoWebsocketStatusBadge.tsx +41 -0
- package/src/components/WfoBadges/WfoWebsocketStatusBadge/index.ts +1 -0
- package/src/components/WfoForms/formFields/CustomerField.tsx +4 -1
- package/src/components/WfoPageTemplate/WfoPageHeader/WfoPageHeader.tsx +47 -2
- package/src/components/WfoPageTemplate/WfoPageTemplate/WfoPageTemplate.tsx +4 -1
- package/src/components/WfoSubscription/WfoSubscription.tsx +25 -2
- package/src/contexts/ApiClientContext.tsx +2 -2
- package/src/contexts/OrchestratorConfigContext.tsx +1 -0
- package/src/contexts/PolicyContext.tsx +23 -0
- package/src/contexts/index.ts +2 -1
- package/src/hooks/DataFetchHooks.ts +2 -2
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useMutateProcess.ts +2 -2
- package/src/hooks/useOrchestratorTheme.ts +3 -1
- package/src/hooks/usePolicy.ts +15 -0
- package/src/hooks/useQueryWithFetch.ts +2 -2
- package/src/hooks/useQueryWithGraphql.ts +2 -2
- package/src/hooks/useShowToastMessage.ts +4 -26
- package/src/hooks/useSubscriptionActions.ts +2 -2
- package/src/hooks/useWfoSession.ts +28 -0
- package/src/icons/WfoSideMenu.stories.tsx +1 -1
- package/src/messages/en-GB.json +8 -2
- package/src/messages/nl-NL.json +8 -2
- package/src/rtk/api.ts +9 -3
- package/src/rtk/endpoints/index.ts +1 -0
- package/src/rtk/endpoints/settings.ts +3 -3
- package/src/rtk/endpoints/streamMessages.ts +128 -0
- package/src/theme/defaultOrchestratorTheme.ts +28 -1
- package/src/types/types.ts +6 -0
- package/src/utils/getToastMessage.spec.ts +28 -0
- package/src/utils/getToastMessage.ts +35 -0
- package/src/hooks/useSessionWithToken.ts +0 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orchestrator-ui/orchestrator-ui-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "jest",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"invariant": "^2.2.4",
|
|
22
22
|
"moment": "^2.29.4",
|
|
23
23
|
"moment-timezone": "^0.5.43",
|
|
24
|
-
"next-auth": "^4.
|
|
24
|
+
"next-auth": "^4.24.5",
|
|
25
25
|
"next-intl": "^3.4.1",
|
|
26
26
|
"next-query-params": "^5.0.0",
|
|
27
27
|
"object-hash": "^3.0.0",
|
|
@@ -1,22 +1,50 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
3
|
-
import { useSession } from 'next-auth/react';
|
|
1
|
+
import React, { ReactNode, useContext } from 'react';
|
|
4
2
|
|
|
5
3
|
import { WfoLoading } from '@/components';
|
|
6
4
|
import { OrchestratorConfigContext } from '@/contexts';
|
|
5
|
+
import { PolicyContextProvider } from '@/contexts/PolicyContext';
|
|
6
|
+
import { useWfoSession } from '@/hooks';
|
|
7
7
|
|
|
8
8
|
interface AuthProps {
|
|
9
|
-
children:
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
isAllowedHandler?: (routerPath: string, resource?: string) => boolean;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
/**
|
|
14
|
+
* The WfoAuth component exposes a function isAllowedHandler to apply policy checks.
|
|
15
|
+
* In components in this library a usePolicy hook is available that exposes a function isAllowed
|
|
16
|
+
* with 1 optional parameter "resource".
|
|
17
|
+
*
|
|
18
|
+
* For convenience there is also a WfoIsAllowedToRender component available. In both hook
|
|
19
|
+
* and component the current route is determined in the usePolicy hook and passed as
|
|
20
|
+
* first parameter in the isAllowedHandler function in this WfoAuth component.
|
|
21
|
+
*
|
|
22
|
+
* Example for usage in any component:
|
|
23
|
+
* const { isAllowed } = usePolicy();
|
|
24
|
+
* const isAllowedToDoOrSeeSomething: boolean = isAllowed('something')
|
|
25
|
+
*
|
|
26
|
+
* Example for implementing the isAllowed function:
|
|
27
|
+
* const isAllowed = (routerPath: string, resource?: string) => {
|
|
28
|
+
* // Your own rules to determine if something is allowed or not
|
|
29
|
+
* // The useWfoSession hook can be used to get the current user profile
|
|
30
|
+
* }
|
|
31
|
+
*/
|
|
32
|
+
export const WfoAuth = ({
|
|
33
|
+
children,
|
|
34
|
+
isAllowedHandler = () => true,
|
|
35
|
+
}: AuthProps) => {
|
|
13
36
|
const { authActive } = useContext(OrchestratorConfigContext);
|
|
14
|
-
const { status } =
|
|
37
|
+
const { status } = useWfoSession({
|
|
15
38
|
required: authActive,
|
|
16
39
|
});
|
|
17
40
|
|
|
18
41
|
if (status === 'loading') {
|
|
19
42
|
return <WfoLoading />;
|
|
20
43
|
}
|
|
21
|
-
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<PolicyContextProvider isAllowedHandler={isAllowedHandler}>
|
|
47
|
+
{children}
|
|
48
|
+
</PolicyContextProvider>
|
|
49
|
+
);
|
|
22
50
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React, { FC, ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
import { usePolicy } from '@/hooks';
|
|
4
|
+
|
|
5
|
+
export type WfoIsAllowedToRenderProps = {
|
|
6
|
+
resource?: string;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const WfoIsAllowedToRender: FC<WfoIsAllowedToRenderProps> = ({
|
|
11
|
+
resource,
|
|
12
|
+
children,
|
|
13
|
+
}) => {
|
|
14
|
+
const { isAllowed } = usePolicy();
|
|
15
|
+
|
|
16
|
+
return isAllowed(resource) ? <>{children}</> : null;
|
|
17
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { Meta } from '@storybook/react';
|
|
4
|
+
|
|
5
|
+
import { WfoSubscriptionSyncStatusBadge } from './WfoSubscriptionSyncStatusBadge';
|
|
6
|
+
|
|
7
|
+
const Story: Meta<typeof WfoSubscriptionSyncStatusBadge> = {
|
|
8
|
+
component: (args) => (
|
|
9
|
+
<div style={{ display: 'flex' }}>
|
|
10
|
+
<WfoSubscriptionSyncStatusBadge {...args} />
|
|
11
|
+
</div>
|
|
12
|
+
),
|
|
13
|
+
title: 'Badges/WfoSubscriptionSyncStatusBadge',
|
|
14
|
+
};
|
|
15
|
+
export default Story;
|
|
16
|
+
|
|
17
|
+
export const Primary = {
|
|
18
|
+
args: {
|
|
19
|
+
insync: true,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const Secondary = {
|
|
24
|
+
args: {
|
|
25
|
+
insync: false,
|
|
26
|
+
},
|
|
27
|
+
};
|
package/src/components/WfoBadges/WfoSubscriptionSyncStatusBadge/WfoSubscriptionSyncStatusBadge.tsx
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useTranslations } from 'next-intl';
|
|
4
|
+
|
|
5
|
+
import { useOrchestratorTheme } from '../../../hooks';
|
|
6
|
+
import { WfoBadge } from '../WfoBadge';
|
|
7
|
+
|
|
8
|
+
export type WfoSubscriptionSyncStatusBadgeProps = {
|
|
9
|
+
insync: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const WfoSubscriptionSyncStatusBadge: FC<
|
|
13
|
+
WfoSubscriptionSyncStatusBadgeProps
|
|
14
|
+
> = ({ insync }) => {
|
|
15
|
+
const { theme, toSecondaryColor } = useOrchestratorTheme();
|
|
16
|
+
|
|
17
|
+
const t = useTranslations('common');
|
|
18
|
+
|
|
19
|
+
const getBadgePropertiesFromStatus = (insync: boolean) => {
|
|
20
|
+
const { danger, dangerText, success, successText } = theme.colors;
|
|
21
|
+
|
|
22
|
+
if (insync) {
|
|
23
|
+
return {
|
|
24
|
+
badgeColor: toSecondaryColor(success),
|
|
25
|
+
textColor: successText,
|
|
26
|
+
insyncText: t('insyncTrue'),
|
|
27
|
+
};
|
|
28
|
+
} else {
|
|
29
|
+
return {
|
|
30
|
+
badgeColor: toSecondaryColor(danger),
|
|
31
|
+
textColor: dangerText,
|
|
32
|
+
insyncText: t('insyncFalse'),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const { badgeColor, textColor, insyncText } =
|
|
38
|
+
getBadgePropertiesFromStatus(insync);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<WfoBadge textColor={textColor} color={badgeColor}>
|
|
42
|
+
{insyncText}
|
|
43
|
+
</WfoBadge>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './WfoSubscriptionSyncStatusBadge';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Meta } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { WfoWebsocketStatusBadge } from './WfoWebsocketStatusBadge';
|
|
4
|
+
|
|
5
|
+
const Story: Meta<typeof WfoWebsocketStatusBadge> = {
|
|
6
|
+
component: WfoWebsocketStatusBadge,
|
|
7
|
+
title: 'Badges/WfoWebsocketStatusBadge',
|
|
8
|
+
};
|
|
9
|
+
export default Story;
|
|
10
|
+
|
|
11
|
+
export const Primary = {
|
|
12
|
+
args: {},
|
|
13
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { useTranslations } from 'next-intl';
|
|
4
|
+
|
|
5
|
+
import { EuiToolTip } from '@elastic/eui';
|
|
6
|
+
|
|
7
|
+
import { useOrchestratorTheme } from '@/hooks/useOrchestratorTheme';
|
|
8
|
+
import { WfoStatusDotIcon, WfoXCircleFill } from '@/icons';
|
|
9
|
+
import { useStreamMessagesQuery } from '@/rtk/endpoints/streamMessages';
|
|
10
|
+
|
|
11
|
+
import { WfoHeaderBadge } from '../WfoHeaderBadge';
|
|
12
|
+
|
|
13
|
+
export const WfoWebsocketStatusBadge = () => {
|
|
14
|
+
const t = useTranslations('main');
|
|
15
|
+
const { theme } = useOrchestratorTheme();
|
|
16
|
+
const { data: websocketConnected = false } = useStreamMessagesQuery();
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<EuiToolTip
|
|
20
|
+
position="bottom"
|
|
21
|
+
content={
|
|
22
|
+
websocketConnected
|
|
23
|
+
? t('websocketConnected')
|
|
24
|
+
: t('websocketDisconnected')
|
|
25
|
+
}
|
|
26
|
+
>
|
|
27
|
+
<WfoHeaderBadge
|
|
28
|
+
color={theme.colors.emptyShade}
|
|
29
|
+
textColor={theme.colors.shadow}
|
|
30
|
+
iconType={() =>
|
|
31
|
+
websocketConnected ? (
|
|
32
|
+
<WfoStatusDotIcon color={theme.colors.success} />
|
|
33
|
+
) : (
|
|
34
|
+
<WfoXCircleFill color={theme.colors.danger} />
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
style={{ paddingLeft: '8px' }}
|
|
38
|
+
/>
|
|
39
|
+
</EuiToolTip>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './WfoWebsocketStatusBadge';
|
|
@@ -35,7 +35,10 @@ function Customer({ ...props }: CustomerFieldProps) {
|
|
|
35
35
|
|
|
36
36
|
if (!isLoading && customers) {
|
|
37
37
|
customers?.map((customer) => {
|
|
38
|
-
uuidCustomerNameMap.set(
|
|
38
|
+
uuidCustomerNameMap.set(
|
|
39
|
+
customer.customerId,
|
|
40
|
+
`${customer.shortcode} - ${customer.fullname}`,
|
|
41
|
+
);
|
|
39
42
|
});
|
|
40
43
|
}
|
|
41
44
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React, { FC, ReactElement } from 'react';
|
|
2
2
|
|
|
3
|
+
import { useTranslations } from 'next-intl';
|
|
4
|
+
|
|
3
5
|
import {
|
|
4
6
|
EuiBadgeGroup,
|
|
5
7
|
EuiButtonIcon,
|
|
@@ -8,16 +10,19 @@ import {
|
|
|
8
10
|
EuiHeaderSection,
|
|
9
11
|
EuiHeaderSectionItem,
|
|
10
12
|
} from '@elastic/eui';
|
|
13
|
+
import type { EuiThemeColorMode } from '@elastic/eui';
|
|
11
14
|
|
|
12
15
|
import {
|
|
13
16
|
WfoEngineStatusBadge,
|
|
14
17
|
WfoEnvironmentBadge,
|
|
15
18
|
WfoFailedTasksBadge,
|
|
16
19
|
} from '@/components';
|
|
20
|
+
import { WfoWebsocketStatusBadge } from '@/components/WfoBadges/WfoWebsocketStatusBadge';
|
|
17
21
|
import { WfoAppLogo } from '@/components/WfoPageTemplate/WfoPageHeader/WfoAppLogo';
|
|
18
22
|
import { getWfoPageHeaderStyles } from '@/components/WfoPageTemplate/WfoPageHeader/styles';
|
|
19
23
|
import { useOrchestratorTheme, useWithOrchestratorTheme } from '@/hooks';
|
|
20
24
|
import { WfoLogoutIcon, WfoSideMenu } from '@/icons';
|
|
25
|
+
import { ColorModes } from '@/types';
|
|
21
26
|
|
|
22
27
|
export interface WfoPageHeaderProps {
|
|
23
28
|
// todo: should be part of theme!
|
|
@@ -25,15 +30,23 @@ export interface WfoPageHeaderProps {
|
|
|
25
30
|
getAppLogo: (navigationHeight: number) => ReactElement;
|
|
26
31
|
handleSideMenuClick: () => void;
|
|
27
32
|
handleLogoutClick: () => void;
|
|
33
|
+
onThemeSwitch: (theme: EuiThemeColorMode) => void;
|
|
28
34
|
}
|
|
29
35
|
|
|
36
|
+
const ENABLE_THEME_SWITCH =
|
|
37
|
+
process.env.NEXT_PUBLIC_USE_THEME_TOGGLE === 'true' || false;
|
|
38
|
+
const ENABLE_WEBSOCKET =
|
|
39
|
+
process.env.NEXT_PUBLIC_USE_WEBSOCKET === 'true' || false;
|
|
40
|
+
|
|
30
41
|
export const WfoPageHeader: FC<WfoPageHeaderProps> = ({
|
|
31
42
|
navigationHeight,
|
|
32
43
|
getAppLogo,
|
|
33
44
|
handleSideMenuClick,
|
|
34
45
|
handleLogoutClick,
|
|
46
|
+
onThemeSwitch,
|
|
35
47
|
}) => {
|
|
36
|
-
const
|
|
48
|
+
const t = useTranslations('main');
|
|
49
|
+
const { theme, multiplyByBaseUnit, colorMode } = useOrchestratorTheme();
|
|
37
50
|
const { getHeaderStyle, appNameStyle } = useWithOrchestratorTheme(
|
|
38
51
|
getWfoPageHeaderStyles,
|
|
39
52
|
);
|
|
@@ -63,11 +76,43 @@ export const WfoPageHeader: FC<WfoPageHeaderProps> = ({
|
|
|
63
76
|
|
|
64
77
|
<EuiHeaderSection>
|
|
65
78
|
<EuiHeaderSectionItem>
|
|
66
|
-
<EuiBadgeGroup css={{ marginRight: multiplyByBaseUnit(
|
|
79
|
+
<EuiBadgeGroup css={{ marginRight: multiplyByBaseUnit(1) }}>
|
|
67
80
|
<WfoEngineStatusBadge />
|
|
68
81
|
<WfoFailedTasksBadge />
|
|
82
|
+
{ENABLE_WEBSOCKET && <WfoWebsocketStatusBadge />}
|
|
69
83
|
</EuiBadgeGroup>
|
|
70
84
|
|
|
85
|
+
{ENABLE_THEME_SWITCH && (
|
|
86
|
+
<EuiButtonIcon
|
|
87
|
+
aria-label={t(
|
|
88
|
+
colorMode === ColorModes.LIGHT
|
|
89
|
+
? 'darkMode'
|
|
90
|
+
: 'lightMode',
|
|
91
|
+
)}
|
|
92
|
+
display="empty"
|
|
93
|
+
iconType={
|
|
94
|
+
colorMode === ColorModes.LIGHT ? 'moon' : 'sun'
|
|
95
|
+
}
|
|
96
|
+
css={{
|
|
97
|
+
width: '48px',
|
|
98
|
+
height: '48px',
|
|
99
|
+
color: 'white',
|
|
100
|
+
}}
|
|
101
|
+
title={t(
|
|
102
|
+
colorMode === ColorModes.LIGHT
|
|
103
|
+
? 'darkMode'
|
|
104
|
+
: 'lightMode',
|
|
105
|
+
)}
|
|
106
|
+
onClick={() =>
|
|
107
|
+
onThemeSwitch(
|
|
108
|
+
colorMode === ColorModes.LIGHT
|
|
109
|
+
? ColorModes.DARK
|
|
110
|
+
: ColorModes.LIGHT,
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
/>
|
|
114
|
+
)}
|
|
115
|
+
|
|
71
116
|
<EuiButtonIcon
|
|
72
117
|
aria-label="Logout"
|
|
73
118
|
display="empty"
|
|
@@ -3,6 +3,7 @@ import React, { FC, ReactElement, ReactNode, useState } from 'react';
|
|
|
3
3
|
import { signOut } from 'next-auth/react';
|
|
4
4
|
|
|
5
5
|
import { EuiPageTemplate } from '@elastic/eui';
|
|
6
|
+
import type { EuiThemeColorMode } from '@elastic/eui';
|
|
6
7
|
import { EuiSideNavItemType } from '@elastic/eui/src/components/side_nav/side_nav_types';
|
|
7
8
|
|
|
8
9
|
import { useOrchestratorTheme } from '../../../hooks/useOrchestratorTheme';
|
|
@@ -15,6 +16,7 @@ export interface WfoPageTemplateProps {
|
|
|
15
16
|
overrideMenuItems?: (
|
|
16
17
|
defaultMenuItems: EuiSideNavItemType<object>[],
|
|
17
18
|
) => EuiSideNavItemType<object>[];
|
|
19
|
+
onThemeSwitch: (theme: EuiThemeColorMode) => void;
|
|
18
20
|
children: ReactNode;
|
|
19
21
|
}
|
|
20
22
|
|
|
@@ -22,10 +24,10 @@ export const WfoPageTemplate: FC<WfoPageTemplateProps> = ({
|
|
|
22
24
|
children,
|
|
23
25
|
getAppLogo,
|
|
24
26
|
overrideMenuItems,
|
|
27
|
+
onThemeSwitch,
|
|
25
28
|
}) => {
|
|
26
29
|
const { theme, multiplyByBaseUnit } = useOrchestratorTheme();
|
|
27
30
|
const [isSideMenuVisible, setIsSideMenuVisible] = useState(true);
|
|
28
|
-
|
|
29
31
|
const navigationHeight = multiplyByBaseUnit(3);
|
|
30
32
|
|
|
31
33
|
return (
|
|
@@ -37,6 +39,7 @@ export const WfoPageTemplate: FC<WfoPageTemplateProps> = ({
|
|
|
37
39
|
setIsSideMenuVisible((prevState) => !prevState)
|
|
38
40
|
}
|
|
39
41
|
handleLogoutClick={signOut}
|
|
42
|
+
onThemeSwitch={onThemeSwitch}
|
|
40
43
|
/>
|
|
41
44
|
|
|
42
45
|
{/* Sidebar and content area */}
|
|
@@ -2,11 +2,18 @@ import React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { StringParam, useQueryParam, withDefault } from 'use-query-params';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
EuiBadgeGroup,
|
|
7
|
+
EuiFlexGroup,
|
|
8
|
+
EuiFlexItem,
|
|
9
|
+
EuiText,
|
|
10
|
+
} from '@elastic/eui';
|
|
6
11
|
|
|
7
12
|
import { GET_SUBSCRIPTION_DETAIL_GRAPHQL_QUERY } from '@/graphqlQueries';
|
|
8
|
-
import { useQueryWithGraphql } from '@/hooks';
|
|
13
|
+
import { useOrchestratorTheme, useQueryWithGraphql } from '@/hooks';
|
|
9
14
|
|
|
15
|
+
import { WfoSubscriptionStatusBadge } from '../WfoBadges';
|
|
16
|
+
import { WfoSubscriptionSyncStatusBadge } from '../WfoBadges/WfoSubscriptionSyncStatusBadge';
|
|
10
17
|
import { WfoError } from '../WfoError';
|
|
11
18
|
import { WfoFilterTabs } from '../WfoFilterTabs';
|
|
12
19
|
import { WfoLoading } from '../WfoLoading';
|
|
@@ -31,6 +38,8 @@ export const WfoSubscription = ({ subscriptionId }: WfoSubscriptionProps) => {
|
|
|
31
38
|
),
|
|
32
39
|
);
|
|
33
40
|
|
|
41
|
+
const { multiplyByBaseUnit } = useOrchestratorTheme();
|
|
42
|
+
|
|
34
43
|
const selectedTab = ((): SubscriptionDetailTab => {
|
|
35
44
|
return (
|
|
36
45
|
subscriptionDetailTabs.find(({ id }) => id === activeTab)?.id ||
|
|
@@ -68,6 +77,20 @@ export const WfoSubscription = ({ subscriptionId }: WfoSubscriptionProps) => {
|
|
|
68
77
|
<EuiText>
|
|
69
78
|
<h2>{subscriptionDetail.description}</h2>
|
|
70
79
|
</EuiText>
|
|
80
|
+
<EuiBadgeGroup
|
|
81
|
+
css={{ marginRight: multiplyByBaseUnit(1) }}
|
|
82
|
+
>
|
|
83
|
+
<EuiFlexItem grow={false}>
|
|
84
|
+
<WfoSubscriptionStatusBadge
|
|
85
|
+
status={subscriptionDetail.status}
|
|
86
|
+
/>
|
|
87
|
+
</EuiFlexItem>
|
|
88
|
+
<EuiFlexItem grow={false}>
|
|
89
|
+
<WfoSubscriptionSyncStatusBadge
|
|
90
|
+
insync={subscriptionDetail.insync}
|
|
91
|
+
/>
|
|
92
|
+
</EuiFlexItem>
|
|
93
|
+
</EuiBadgeGroup>
|
|
71
94
|
</EuiFlexItem>
|
|
72
95
|
<EuiFlexItem grow={false}>
|
|
73
96
|
<WfoSubscriptionActions
|
|
@@ -2,7 +2,7 @@ import React, { createContext, useContext } from 'react';
|
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
import { ApiClient, getApiClient } from '@/api';
|
|
5
|
-
import {
|
|
5
|
+
import { useWfoSession } from '@/hooks';
|
|
6
6
|
|
|
7
7
|
import { OrchestratorConfigContext } from './OrchestratorConfigContext';
|
|
8
8
|
|
|
@@ -22,7 +22,7 @@ export const ApiClientContextProvider = ({
|
|
|
22
22
|
children,
|
|
23
23
|
}: ApiClientContextProviderProps) => {
|
|
24
24
|
const { orchestratorApiBaseUrl } = useContext(OrchestratorConfigContext);
|
|
25
|
-
const { session } =
|
|
25
|
+
const { session } = useWfoSession();
|
|
26
26
|
const accessToken = session?.accessToken;
|
|
27
27
|
const apiClient = getApiClient(orchestratorApiBaseUrl, accessToken);
|
|
28
28
|
|
|
@@ -9,6 +9,7 @@ export const OrchestratorConfigContext = createContext<OrchestratorConfig>({
|
|
|
9
9
|
engineStatusEndpoint: '',
|
|
10
10
|
graphqlEndpointCore: '',
|
|
11
11
|
orchestratorApiBaseUrl: '',
|
|
12
|
+
orchestratorWebsocketUrl: '',
|
|
12
13
|
processStatusCountsEndpoint: '',
|
|
13
14
|
processesEndpoint: '',
|
|
14
15
|
subscriptionActionsEndpoint: '',
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React, { FC, ReactNode, createContext } from 'react';
|
|
2
|
+
|
|
3
|
+
export type Policy = {
|
|
4
|
+
isAllowedHandler: (routerPath: string, resource?: string) => boolean;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const PolicyContext = createContext<Policy>({
|
|
8
|
+
isAllowedHandler: () => true,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export type PolicyProviderProps = {
|
|
12
|
+
isAllowedHandler: (routerPath: string, resource?: string) => boolean;
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const PolicyContextProvider: FC<PolicyProviderProps> = ({
|
|
17
|
+
isAllowedHandler,
|
|
18
|
+
children,
|
|
19
|
+
}) => (
|
|
20
|
+
<PolicyContext.Provider value={{ isAllowedHandler }}>
|
|
21
|
+
{children}
|
|
22
|
+
</PolicyContext.Provider>
|
|
23
|
+
);
|
package/src/contexts/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { OrchestratorConfigContext } from '@/contexts';
|
|
|
5
5
|
import { GraphqlFilter, ProcessDetailResultRaw } from '@/types';
|
|
6
6
|
|
|
7
7
|
import { useQueryWithFetch } from './useQueryWithFetch';
|
|
8
|
-
import {
|
|
8
|
+
import { useWfoSession } from './useWfoSession';
|
|
9
9
|
|
|
10
10
|
export type CacheNames = { [key: string]: string };
|
|
11
11
|
|
|
@@ -48,7 +48,7 @@ export const useFilterQueryWithRest = <Type>(
|
|
|
48
48
|
filters?: GraphqlFilter<Type>[],
|
|
49
49
|
refetchInterval?: number,
|
|
50
50
|
) => {
|
|
51
|
-
const { session } =
|
|
51
|
+
const { session } = useWfoSession();
|
|
52
52
|
|
|
53
53
|
const fetchFromApi = async () => {
|
|
54
54
|
const response = await fetch(url, {
|
package/src/hooks/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './useQueryWithGraphql';
|
|
|
3
3
|
export * from './useMutateProcess';
|
|
4
4
|
export * from './useOrchestratorConfig';
|
|
5
5
|
export * from './useOrchestratorTheme';
|
|
6
|
+
export * from './usePolicy';
|
|
6
7
|
export * from './useProcessStatusCountsQuery';
|
|
7
8
|
export * from './DataFetchHooks';
|
|
8
9
|
export * from './useSubscriptionActions';
|
|
@@ -10,5 +11,5 @@ export * from './useDataDisplayParams';
|
|
|
10
11
|
export * from './useShowToastMessage';
|
|
11
12
|
export * from './useStoredTableConfig';
|
|
12
13
|
export * from './useWithOrchestratorTheme';
|
|
13
|
-
export * from './
|
|
14
|
+
export * from './useWfoSession';
|
|
14
15
|
export * from './useQueryWithFetch';
|
|
@@ -4,11 +4,11 @@ import { useMutation, useQueryClient } from 'react-query';
|
|
|
4
4
|
import { signOut } from 'next-auth/react';
|
|
5
5
|
|
|
6
6
|
import { OrchestratorConfigContext } from '@/contexts';
|
|
7
|
-
import {
|
|
7
|
+
import { useWfoSession } from '@/hooks/index';
|
|
8
8
|
|
|
9
9
|
export const useMutateProcess = () => {
|
|
10
10
|
const { processesEndpoint } = useContext(OrchestratorConfigContext);
|
|
11
|
-
const { session } =
|
|
11
|
+
const { session } = useWfoSession();
|
|
12
12
|
const queryClient = useQueryClient();
|
|
13
13
|
|
|
14
14
|
const genericRequestHeaders = {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { tint, useEuiTheme } from '@elastic/eui';
|
|
2
2
|
|
|
3
3
|
export const useOrchestratorTheme = () => {
|
|
4
|
-
const { euiTheme } = useEuiTheme();
|
|
4
|
+
const { euiTheme, colorMode } = useEuiTheme();
|
|
5
|
+
|
|
5
6
|
const baseUnit = euiTheme.base;
|
|
6
7
|
|
|
7
8
|
const multiplyByBaseUnit = (multiplier: number) => baseUnit * multiplier;
|
|
@@ -12,5 +13,6 @@ export const useOrchestratorTheme = () => {
|
|
|
12
13
|
theme: euiTheme,
|
|
13
14
|
multiplyByBaseUnit,
|
|
14
15
|
toSecondaryColor,
|
|
16
|
+
colorMode,
|
|
15
17
|
};
|
|
16
18
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useRouter } from 'next/router';
|
|
4
|
+
|
|
5
|
+
import { PolicyContext } from '@/contexts';
|
|
6
|
+
|
|
7
|
+
export const usePolicy = () => {
|
|
8
|
+
const { isAllowedHandler } = useContext(PolicyContext);
|
|
9
|
+
const router = useRouter();
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
isAllowed: (resource?: string) =>
|
|
13
|
+
isAllowedHandler(router.asPath, resource),
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -3,14 +3,14 @@ import { useQuery } from 'react-query';
|
|
|
3
3
|
import { Variables } from 'graphql-request/build/cjs/types';
|
|
4
4
|
import { signOut } from 'next-auth/react';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { useWfoSession } from './useWfoSession';
|
|
7
7
|
|
|
8
8
|
export const useQueryWithFetch = <T, V extends Variables>(
|
|
9
9
|
url: string,
|
|
10
10
|
queryVars: V,
|
|
11
11
|
queryKey: string,
|
|
12
12
|
) => {
|
|
13
|
-
const { session } =
|
|
13
|
+
const { session } = useWfoSession();
|
|
14
14
|
const requestHeaders = {
|
|
15
15
|
authorization: session ? `Bearer ${session.accessToken}` : '',
|
|
16
16
|
};
|
|
@@ -8,7 +8,7 @@ import { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
|
8
8
|
|
|
9
9
|
import { OrchestratorConfigContext } from '@/contexts';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { useWfoSession } from './useWfoSession';
|
|
12
12
|
|
|
13
13
|
export const useQueryWithGraphql = <U, V extends Variables>(
|
|
14
14
|
query: TypedDocumentNode<U, V>,
|
|
@@ -17,7 +17,7 @@ export const useQueryWithGraphql = <U, V extends Variables>(
|
|
|
17
17
|
options: UseQueryOptions<U> = {},
|
|
18
18
|
) => {
|
|
19
19
|
const { graphqlEndpointCore } = useContext(OrchestratorConfigContext);
|
|
20
|
-
const { session } =
|
|
20
|
+
const { session } = useWfoSession();
|
|
21
21
|
|
|
22
22
|
const graphQLClient = new GraphQLClient(graphqlEndpointCore);
|
|
23
23
|
|