Skip to content

Commit d52e6fb

Browse files
authored
Merge pull request #2707 from devtron-labs/feat/rb-table
feat: table in RB
2 parents bbb5c73 + 2b0294f commit d52e6fb

File tree

66 files changed

+3095
-2599
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+3095
-2599
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"homepage": "/dashboard",
66
"dependencies": {
7-
"@devtron-labs/devtron-fe-common-lib": "1.16.0-pre-5",
7+
"@devtron-labs/devtron-fe-common-lib": "1.16.0-pre-6",
88
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
99
"@rjsf/core": "^5.13.3",
1010
"@rjsf/utils": "^5.13.3",

src/Pages/GlobalConfigurations/ClustersAndEnvironments/ClusterComponent.tsx

Lines changed: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,17 @@ import {
2121
Button,
2222
ButtonComponentType,
2323
ComponentSizeType,
24+
Drawer,
2425
ErrorScreenNotAuthorized,
2526
FeatureTitleWithInfo,
27+
GenericEmptyState,
2628
Icon,
2729
Progressing,
2830
Reload,
2931
showError,
3032
sortCallback,
31-
URLS as CommonURLS,
33+
stopPropagation,
34+
URLS as COMMON_URLS,
3235
} from '@devtron-labs/devtron-fe-common-lib'
3336

3437
import { importComponentFromFELibrary } from '@Components/common'
@@ -42,9 +45,13 @@ import { getClusterList, getEnvironmentList } from './cluster.service'
4245
import { ClusterMetadataTypes, ClusterProps } from './cluster.type'
4346
import { getSelectParsedCategory } from './cluster.util'
4447
import { ClusterList } from './ClusterList'
48+
import EditClusterDrawerContent from './EditClusterDrawerContent'
4549

4650
const ManageCategories = importComponentFromFELibrary('ManageCategories', null, 'function')
4751
const ManageCategoryButton = importComponentFromFELibrary('ManageCategoryButton', null, 'function')
52+
const PodSpreadModal = importComponentFromFELibrary('PodSpreadModal', null, 'function')
53+
const HibernationRulesModal = importComponentFromFELibrary('HibernationRulesModal', null, 'function')
54+
const VirtualClusterForm = importComponentFromFELibrary('VirtualClusterForm', null, 'function')
4855

4956
const ClusterComponents = ({ isSuperAdmin }: ClusterProps) => {
5057
const [view, setView] = useState(ViewType.LOADING)
@@ -138,22 +145,15 @@ const ClusterComponents = ({ isSuperAdmin }: ClusterProps) => {
138145
clusterName={cluster.cluster_name}
139146
isVirtualCluster={cluster.isVirtualCluster}
140147
environments={cluster.environments}
141-
sshTunnelConfig={cluster.sshTunnelConfig}
142148
isProd={cluster.isProd}
143149
serverURL={cluster.server_url}
144-
prometheusURL={cluster.prometheus_url}
145-
prometheusAuth={cluster.prometheusAuth}
146-
proxyUrl={cluster.proxyUrl}
147-
insecureSkipTlsVerify={cluster.insecureSkipTlsVerify}
148-
installationId={cluster.installationId}
149150
category={cluster.category}
150-
toConnectWithSSHTunnel={cluster.toConnectWithSSHTunnel}
151151
clusterId={cluster.id}
152152
/>
153153
))}
154154

155155
{ManageCategories && (
156-
<Route path={CommonURLS.GLOBAL_CONFIG_MANAGE_CATEGORIES}>
156+
<Route path={COMMON_URLS.GLOBAL_CONFIG_MANAGE_CATEGORIES}>
157157
<ManageCategories />
158158
</Route>
159159
)}
@@ -162,6 +162,83 @@ const ClusterComponents = ({ isSuperAdmin }: ClusterProps) => {
162162
<CreateCluster handleReloadClusterList={initialize} />
163163
</Route>
164164

165+
<Route
166+
path={COMMON_URLS.GLOBAL_CONFIG_EDIT_CLUSTER}
167+
render={(props) => {
168+
const { clusterId } = props.match.params
169+
const cluster: ClusterMetadataTypes = clusters.find((c) => c.id === +clusterId)
170+
171+
if (!cluster || !cluster.isVirtualCluster) {
172+
return (
173+
<Drawer position="right" width="1000px" onClose={handleRedirectToClusterList}>
174+
<div className="h-100 bg__primary" onClick={stopPropagation}>
175+
{!cluster ? (
176+
<GenericEmptyState
177+
title="Cluster not found"
178+
subTitle="The cluster that you are looking is not available."
179+
/>
180+
) : (
181+
<EditClusterDrawerContent
182+
handleModalClose={handleRedirectToClusterList}
183+
sshTunnelConfig={cluster.sshTunnelConfig}
184+
clusterId={cluster.id}
185+
clusterName={cluster.cluster_name}
186+
serverURL={cluster.server_url}
187+
reload={initialize}
188+
prometheusURL={cluster.prometheus_url}
189+
proxyUrl={cluster.proxyUrl}
190+
toConnectWithSSHTunnel={cluster.toConnectWithSSHTunnel}
191+
isProd={cluster.isProd}
192+
installationId={cluster.installationId}
193+
category={cluster.category}
194+
insecureSkipTlsVerify={cluster.insecureSkipTlsVerify}
195+
/>
196+
)}
197+
</div>
198+
</Drawer>
199+
)
200+
}
201+
202+
return (
203+
<VirtualClusterForm
204+
id={+cluster.id}
205+
clusterName={cluster.cluster_name}
206+
handleModalClose={handleRedirectToClusterList}
207+
reload={initialize}
208+
category={cluster.category}
209+
/>
210+
)
211+
}}
212+
/>
213+
214+
{PodSpreadModal && (
215+
<Route
216+
path={`${URLS.GLOBAL_CONFIG_CLUSTER}/:clusterName/${URLS.POD_SPREAD}`}
217+
render={(props) => {
218+
const { clusterName } = props.match.params
219+
const foundCluster: ClusterMetadataTypes | { id?: number } =
220+
clusters.find((c) => c.cluster_name === clusterName) || {}
221+
const { id: clusterId } = foundCluster
222+
223+
return <PodSpreadModal clusterId={clusterId} handleClose={handleRedirectToClusterList} />
224+
}}
225+
/>
226+
)}
227+
228+
{HibernationRulesModal && (
229+
<Route
230+
path={`${URLS.GLOBAL_CONFIG_CLUSTER}/:clusterName/${URLS.HIBERNATION_RULES}`}
231+
render={(props) => {
232+
const { clusterName } = props.match.params
233+
const foundCluster: ClusterMetadataTypes | { id?: number } =
234+
clusters.find((c) => c.cluster_name === clusterName) || {}
235+
const { id: clusterId } = foundCluster
236+
237+
return <HibernationRulesModal clusterId={clusterId} handleClose={handleRedirectToClusterList} />
238+
}}
239+
/>
240+
)}
241+
165242
<Route
166243
path={`${URLS.GLOBAL_CONFIG_CLUSTER}/:clusterName${URLS.CREATE_ENVIRONMENT}`}
167244
render={(props) => {
Lines changed: 43 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,83 @@
1-
import { useRef, useState } from 'react'
1+
import { generatePath, useHistory } from 'react-router-dom'
22

33
import {
44
Button,
55
ButtonComponentType,
66
ButtonStyleType,
77
ButtonVariantType,
88
ComponentSizeType,
9-
Drawer,
109
getClassNameForStickyHeaderWithShadow,
1110
Icon,
12-
noop,
13-
showError,
11+
URLS as COMMON_URLS,
1412
useStickyEvent,
1513
} from '@devtron-labs/devtron-fe-common-lib'
1614

1715
import { importComponentFromFELibrary } from '@Components/common'
1816
import { URLS } from '@Config/routes'
1917

2018
import { List } from '../../../components/globalConfigurations/GlobalConfiguration'
21-
import { getCluster } from './cluster.service'
22-
import { ClusterListProps, EditClusterFormProps } from './cluster.type'
19+
import { ClusterListProps } from './cluster.type'
2320
import { renderNoEnvironmentTab } from './cluster.util'
2421
import { ClusterEnvironmentList } from './ClusterEnvironmentList'
25-
import ClusterForm from './ClusterForm'
2622

27-
const VirtualClusterForm = importComponentFromFELibrary('VirtualClusterForm', null, 'function')
28-
29-
const getSSHConfig: (
30-
...props
31-
) => Pick<EditClusterFormProps, 'sshUsername' | 'sshPassword' | 'sshAuthKey' | 'sshServerAddress'> =
32-
importComponentFromFELibrary('getSSHConfig', noop, 'function')
23+
const EditClusterPopup = importComponentFromFELibrary('EditClusterPopup', null, 'function')
3324

3425
export const ClusterList = ({
3526
isVirtualCluster,
3627
environments,
3728
reload,
3829
clusterName,
39-
sshTunnelConfig,
4030
isProd,
4131
serverURL,
42-
prometheusURL,
43-
proxyUrl,
44-
insecureSkipTlsVerify,
45-
installationId,
46-
toConnectWithSSHTunnel,
4732
clusterId,
4833
category,
4934
}: ClusterListProps) => {
50-
const [editMode, setEditMode] = useState(false)
51-
const [prometheusAuth, setPrometheusAuth] = useState(null)
52-
53-
const drawerRef = useRef(null)
35+
const history = useHistory()
5436

5537
const { stickyElementRef, isStuck: isHeaderStuck } = useStickyEvent({
5638
containerSelector: '.global-configuration__component-wrapper',
5739
identifier: `cluster-list__${clusterName}`,
5840
})
5941

6042
const handleEdit = async () => {
61-
try {
62-
const { result } = await getCluster(+clusterId)
63-
setPrometheusAuth(result.prometheusAuth)
64-
setEditMode(true)
65-
} catch (err) {
66-
showError(err)
67-
}
43+
history.push(generatePath(COMMON_URLS.GLOBAL_CONFIG_EDIT_CLUSTER, { clusterId }))
44+
}
45+
46+
const handleOpenPodSpreadModal = () => {
47+
history.push(`${URLS.GLOBAL_CONFIG_CLUSTER}/${clusterName}/${URLS.POD_SPREAD}`)
6848
}
6949

70-
const handleModalClose = () => {
71-
setEditMode(false)
50+
const handleOpenHibernationRulesModal = () => {
51+
history.push(`${URLS.GLOBAL_CONFIG_CLUSTER}/${clusterName}/${URLS.HIBERNATION_RULES}`)
52+
}
53+
54+
const renderEditButton = () => {
55+
if (!clusterName) {
56+
return null
57+
}
58+
59+
if (EditClusterPopup && !isVirtualCluster) {
60+
return (
61+
<EditClusterPopup
62+
handleOpenEditClusterModal={handleEdit}
63+
handleOpenPodSpreadModal={handleOpenPodSpreadModal}
64+
handleOpenHibernationRulesModal={handleOpenHibernationRulesModal}
65+
clusterId={clusterId}
66+
/>
67+
)
68+
}
69+
70+
return (
71+
<Button
72+
dataTestId={`edit_cluster_pencil-${clusterName}`}
73+
ariaLabel="Edit Cluster"
74+
icon={<Icon name="ic-pencil" color={null} />}
75+
size={ComponentSizeType.small}
76+
variant={ButtonVariantType.borderLess}
77+
style={ButtonStyleType.neutral}
78+
onClick={handleEdit}
79+
/>
80+
)
7281
}
7382

7483
const subTitle: string = isVirtualCluster ? 'Isolated cluster' : serverURL
@@ -110,16 +119,9 @@ export const ClusterList = ({
110119
<div className="dc__divider" />
111120
</div>
112121
</div>
113-
<Button
114-
dataTestId={`edit_cluster_pencil-${clusterName}`}
115-
ariaLabel="Edit Cluster"
116-
icon={<Icon name="ic-pencil" color={null} />}
117-
size={ComponentSizeType.small}
118-
variant={ButtonVariantType.borderLess}
119-
style={ButtonStyleType.neutral}
120-
onClick={handleEdit}
121-
/>
122+
{renderEditButton()}
122123
</List>
124+
123125
{!window._env_.K8S_CLIENT && Array.isArray(environments) && environments.length > 0 ? (
124126
<ClusterEnvironmentList
125127
clusterId={String(clusterId)}
@@ -131,37 +133,6 @@ export const ClusterList = ({
131133
) : (
132134
renderNoEnvironmentTab()
133135
)}
134-
{editMode &&
135-
(!isVirtualCluster ? (
136-
<Drawer position="right" width="1000px" onEscape={handleModalClose}>
137-
<div className="h-100 bg__primary" ref={drawerRef}>
138-
<ClusterForm
139-
{...getSSHConfig(sshTunnelConfig)}
140-
id={+clusterId}
141-
clusterName={clusterName}
142-
serverUrl={serverURL}
143-
reload={reload}
144-
prometheusUrl={prometheusURL}
145-
prometheusAuth={prometheusAuth}
146-
proxyUrl={proxyUrl}
147-
isConnectedViaSSHTunnel={toConnectWithSSHTunnel}
148-
hideEditModal={handleModalClose}
149-
isProd={isProd}
150-
isTlsConnection={!insecureSkipTlsVerify}
151-
installationId={installationId}
152-
category={category}
153-
/>
154-
</div>
155-
</Drawer>
156-
) : (
157-
<VirtualClusterForm
158-
id={+clusterId}
159-
clusterName={clusterName}
160-
handleModalClose={handleModalClose}
161-
reload={reload}
162-
category={category}
163-
/>
164-
))}
165136
</article>
166137
)
167138
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { APIResponseHandler, noop, useAsync } from '@devtron-labs/devtron-fe-common-lib'
2+
3+
import { importComponentFromFELibrary } from '@Components/common'
4+
import { URLS } from '@Config/routes'
5+
6+
import { getCluster } from './cluster.service'
7+
import { EditClusterDrawerContentProps, EditClusterFormProps } from './cluster.type'
8+
import ClusterForm from './ClusterForm'
9+
10+
const getSSHConfig: (
11+
...props
12+
) => Pick<EditClusterFormProps, 'sshUsername' | 'sshPassword' | 'sshAuthKey' | 'sshServerAddress'> =
13+
importComponentFromFELibrary('getSSHConfig', noop, 'function')
14+
15+
const EditClusterDrawerContent = ({
16+
handleModalClose,
17+
sshTunnelConfig,
18+
clusterId,
19+
clusterName,
20+
serverURL,
21+
reload,
22+
prometheusURL,
23+
proxyUrl,
24+
toConnectWithSSHTunnel,
25+
isProd,
26+
installationId,
27+
category,
28+
insecureSkipTlsVerify,
29+
}: EditClusterDrawerContentProps) => {
30+
const [isPrometheusAuthLoading, prometheusAuthResult, prometheusAuthError, reloadPrometheusAuth] = useAsync(
31+
() => getCluster(+clusterId),
32+
[clusterId],
33+
!!clusterId,
34+
)
35+
36+
return (
37+
<APIResponseHandler
38+
isLoading={isPrometheusAuthLoading}
39+
progressingProps={{
40+
pageLoader: true,
41+
}}
42+
error={prometheusAuthError?.code}
43+
errorScreenManagerProps={{
44+
redirectURL: URLS.GLOBAL_CONFIG_CLUSTER,
45+
reload: reloadPrometheusAuth,
46+
}}
47+
>
48+
{prometheusAuthResult?.result && (
49+
<ClusterForm
50+
{...getSSHConfig(sshTunnelConfig)}
51+
id={+clusterId}
52+
clusterName={clusterName}
53+
serverUrl={serverURL}
54+
reload={reload}
55+
prometheusUrl={prometheusURL}
56+
prometheusAuth={prometheusAuthResult.result.prometheusAuth}
57+
proxyUrl={proxyUrl}
58+
isConnectedViaSSHTunnel={toConnectWithSSHTunnel}
59+
hideEditModal={handleModalClose}
60+
isProd={isProd}
61+
isTlsConnection={!insecureSkipTlsVerify}
62+
installationId={installationId}
63+
category={category}
64+
/>
65+
)}
66+
</APIResponseHandler>
67+
)
68+
}
69+
70+
export default EditClusterDrawerContent

0 commit comments

Comments
 (0)