Skip to content

Commit 9ca6b78

Browse files
committed
Merge branch 'develop' of github.com:devtron-labs/dashboard into fix/rb-table
2 parents 0e74c97 + 7757538 commit 9ca6b78

File tree

113 files changed

+2896
-2552
lines changed

Some content is hidden

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

113 files changed

+2896
-2552
lines changed

.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,7 @@ FEATURE_DEFAULT_AUTHENTICATED_VIEW_ENABLE=false
6969
GATEKEEPER_URL=https://license.devtron.ai/dashboard
7070
FEATURE_AI_INTEGRATION_ENABLE=false
7171
LOGIN_PAGE_IMAGE=
72+
FEATURE_ASK_DEVTRON_EXPERT=false
7273
FEATURE_MANAGE_TRAFFIC_ENABLE=false
7374
FEATURE_REDFISH_NODE_ENABLE=false
75+
FEATURE_INFRA_PROVISION_INFO_BLOCK_HIDE=false

.eslintignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ src/components/app/details/appDetails/utils.tsx
8888
src/components/app/details/cIDetails/CIDetails.tsx
8989
src/components/app/details/cIDetails/cIDetails.util.tsx
9090
src/components/app/details/cdDetails/CDDetails.tsx
91-
src/components/app/details/cdDetails/service.ts
9291
src/components/app/details/cicdHistory/History.components.tsx
9392
src/components/app/details/main.tsx
9493
src/components/app/details/metrics/BenchmarkModal.tsx

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v20.11.0
1+
v22

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:20-alpine AS builder
1+
FROM node:22-alpine AS builder
22

33
WORKDIR /app
44

package.json

Lines changed: 6 additions & 7 deletions
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.15.0-pre-5",
7+
"@devtron-labs/devtron-fe-common-lib": "1.15.3-pre-3",
88
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
99
"@rjsf/core": "^5.13.3",
1010
"@rjsf/utils": "^5.13.3",
@@ -14,7 +14,6 @@
1414
"@sentry/tracing": "7.50.0",
1515
"@tippyjs/react": "4.2.6",
1616
"@typeform/embed-react": "2.20.0",
17-
"@vitejs/plugin-react": "4.3.1",
1817
"command-line-parser": "^0.2.10",
1918
"compute-histogram": "^0.9.11",
2019
"dayjs": "^1.11.8",
@@ -39,9 +38,6 @@
3938
"rxjs": "^7.5.4",
4039
"sockjs-client": "1.6.1",
4140
"tippy.js": "^6.3.7",
42-
"vite": "5.4.19",
43-
"vite-plugin-require-transform": "1.0.21",
44-
"vite-plugin-svgr": "^2.4.0",
4541
"xterm": "^4.19.0",
4642
"xterm-addon-fit": "^0.5.0",
4743
"xterm-addon-search": "^0.9.0",
@@ -87,6 +83,7 @@
8783
"@types/recompose": "^0.30.10",
8884
"@typescript-eslint/eslint-plugin": "8.3.0",
8985
"@typescript-eslint/parser": "8.3.0",
86+
"@vitejs/plugin-react": "4.5.2",
9087
"env-cmd": "10.1.0",
9188
"eslint": "^8.57.1",
9289
"eslint-config-airbnb": "^19.0.4",
@@ -115,9 +112,11 @@
115112
"ts-jest": "29.2.5",
116113
"ts-node": "10.9.2",
117114
"typescript": "5.5.4",
118-
"vite-plugin-compression2": "^1.3.3",
119-
"vite-plugin-image-optimizer": "^1.1.8",
115+
"vite": "6.3.5",
116+
"vite-plugin-compression2": "2.0.1",
120117
"vite-plugin-pwa": "^0.21.1",
118+
"vite-plugin-require-transform": "1.0.21",
119+
"vite-plugin-svgr": "^2.4.0",
121120
"vite-tsconfig-paths": "5.0.1"
122121
},
123122
"jest": {

src/Pages/App/CreateAppModal/AppClone/AppCloneList.tsx

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,17 @@ export const AppCloneList = ({ handleCloneAppClick, isJobView, handleCreationMet
4747
<div className="flexbox-col dc__gap-12 pt-20 px-20">
4848
<h2 className="m-0 fs-15 lh-1-5 fw-6 cn-9">Choose {isJobView ? 'a job' : 'an application'} to clone</h2>
4949

50-
<SearchBar
51-
dataTestId="template-list-search"
52-
initialSearchText={searchKey}
53-
size={ComponentSizeType.medium}
54-
handleEnter={handleSearch}
55-
inputProps={{
56-
placeholder: `Search ${isJobView ? 'job' : 'application'}`,
57-
}}
58-
/>
50+
{!!list.length && !listError && (
51+
<SearchBar
52+
dataTestId="template-list-search"
53+
initialSearchText={searchKey}
54+
size={ComponentSizeType.medium}
55+
handleEnter={handleSearch}
56+
inputProps={{
57+
placeholder: `Search ${isJobView ? 'job' : 'application'}`,
58+
}}
59+
/>
60+
)}
5961
</div>
6062
<div className="flex-grow-1 flexbox-col dc__gap-12 p-20 dc__overflow-auto">
6163
<GenericInfoCardListing
File renamed without changes.
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/*
2+
* Copyright (c) 2024. Devtron Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { useEffect, useState } from 'react'
18+
import { generatePath, Route, useHistory } from 'react-router-dom'
19+
20+
import {
21+
Button,
22+
ButtonComponentType,
23+
ComponentSizeType,
24+
ErrorScreenNotAuthorized,
25+
FeatureTitleWithInfo,
26+
Icon,
27+
Progressing,
28+
Reload,
29+
showError,
30+
sortCallback,
31+
URLS as CommonURLS,
32+
} from '@devtron-labs/devtron-fe-common-lib'
33+
34+
import { importComponentFromFELibrary } from '@Components/common'
35+
import { ViewType } from '@Config/constants'
36+
import { URLS } from '@Config/routes'
37+
import { ClusterEnvironmentDrawer } from '@Pages/GlobalConfigurations/ClustersAndEnvironments/ClusterEnvironmentDrawer'
38+
import CreateCluster from '@Pages/GlobalConfigurations/ClustersAndEnvironments/CreateCluster/CreateCluster.component'
39+
import { CreateClusterTypeEnum } from '@Pages/GlobalConfigurations/ClustersAndEnvironments/CreateCluster/types'
40+
41+
import { getClusterList, getEnvironmentList } from './cluster.service'
42+
import { ClusterMetadataTypes, ClusterProps } from './cluster.type'
43+
import { getSelectParsedCategory } from './cluster.util'
44+
import { ClusterList } from './ClusterList'
45+
46+
const ManageCategories = importComponentFromFELibrary('ManageCategories', null, 'function')
47+
const ManageCategoryButton = importComponentFromFELibrary('ManageCategoryButton', null, 'function')
48+
49+
const ClusterComponents = ({ isSuperAdmin }: ClusterProps) => {
50+
const [view, setView] = useState(ViewType.LOADING)
51+
const [clusters, setClusters] = useState<ClusterMetadataTypes[]>([])
52+
53+
const history = useHistory()
54+
55+
const initialize = () => {
56+
Promise.all([getClusterList(), window._env_.K8S_CLIENT ? { result: undefined } : getEnvironmentList()])
57+
.then(([clusterRes, envResponse]) => {
58+
const environments = envResponse.result || []
59+
const clusterEnvironmentMap = environments.reduce((agg, curr) => {
60+
const newAgg = { ...agg }
61+
newAgg[curr.cluster_id] = newAgg[curr.cluster_id] || []
62+
newAgg[curr.cluster_id].push(curr)
63+
return newAgg
64+
}, {})
65+
66+
let clustersList = clusterRes.result || []
67+
clustersList = clustersList.map((cluster) => ({
68+
...cluster,
69+
environments: clusterEnvironmentMap[cluster.id] || [],
70+
category: getSelectParsedCategory(cluster.category),
71+
}))
72+
73+
clustersList = clustersList.sort((a, b) => sortCallback('cluster_name', a, b))
74+
75+
setClusters(clustersList)
76+
setView(ViewType.FORM)
77+
})
78+
.catch((error) => {
79+
showError(error)
80+
setView(ViewType.ERROR)
81+
})
82+
}
83+
84+
const handleRedirectToClusterList = () => {
85+
history.push(URLS.GLOBAL_CONFIG_CLUSTER)
86+
}
87+
88+
useEffect(() => {
89+
if (isSuperAdmin) {
90+
initialize()
91+
}
92+
}, [isSuperAdmin])
93+
94+
if (!isSuperAdmin) {
95+
return (
96+
<div className="dc__align-reload-center">
97+
<ErrorScreenNotAuthorized />
98+
</div>
99+
)
100+
}
101+
102+
if (view === ViewType.LOADING) return <Progressing pageLoader />
103+
if (view === ViewType.ERROR) return <Reload className="dc__align-reload-center" />
104+
105+
const moduleBasedTitle = `Clusters${window._env_.K8S_CLIENT ? '' : ' and Environments'}`
106+
107+
return (
108+
<section className="global-configuration__component flex-1">
109+
<div data-testid="cluster_and_env_header" className="flexbox dc__content-space">
110+
<FeatureTitleWithInfo
111+
title={moduleBasedTitle}
112+
renderDescriptionContent={() => `Manage your organization’s ${moduleBasedTitle.toLowerCase()}.`}
113+
docLink="GLOBAL_CONFIG_CLUSTER"
114+
showInfoIconTippy
115+
additionalContainerClasses="mb-20"
116+
/>
117+
<div className="flexbox dc__gap-8">
118+
{ManageCategoryButton && <ManageCategoryButton />}
119+
<Button
120+
dataTestId="add_cluster_button"
121+
linkProps={{
122+
to: generatePath(URLS.GLOBAL_CONFIG_CREATE_CLUSTER, {
123+
type: CreateClusterTypeEnum.CONNECT_CLUSTER,
124+
}),
125+
}}
126+
component={ButtonComponentType.link}
127+
startIcon={<Icon name="ic-add" color="N700" />}
128+
size={ComponentSizeType.medium}
129+
text="New Cluster"
130+
/>
131+
</div>
132+
</div>
133+
134+
{clusters.map((cluster) => (
135+
<ClusterList
136+
reload={initialize}
137+
key={cluster.id || Math.random().toString(36).substr(2, 5)}
138+
clusterName={cluster.cluster_name}
139+
isVirtualCluster={cluster.isVirtualCluster}
140+
environments={cluster.environments}
141+
sshTunnelConfig={cluster.sshTunnelConfig}
142+
isProd={cluster.isProd}
143+
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}
149+
category={cluster.category}
150+
toConnectWithSSHTunnel={cluster.toConnectWithSSHTunnel}
151+
clusterId={cluster.id}
152+
/>
153+
))}
154+
155+
{ManageCategories && (
156+
<Route path={CommonURLS.GLOBAL_CONFIG_MANAGE_CATEGORIES}>
157+
<ManageCategories />
158+
</Route>
159+
)}
160+
161+
<Route path={URLS.GLOBAL_CONFIG_CREATE_CLUSTER}>
162+
<CreateCluster handleReloadClusterList={initialize} />
163+
</Route>
164+
165+
<Route
166+
path={`${URLS.GLOBAL_CONFIG_CLUSTER}/:clusterName${URLS.CREATE_ENVIRONMENT}`}
167+
render={(props) => {
168+
const { clusterName } = props.match.params
169+
const foundCluster: ClusterMetadataTypes | { isVirtualCluster?: boolean; id?: null } =
170+
clusters.find((c) => c.cluster_name === clusterName) || {}
171+
const { isVirtualCluster, id: clusterId } = foundCluster
172+
173+
return (
174+
<ClusterEnvironmentDrawer
175+
reload={initialize}
176+
clusterName={clusterName}
177+
id={null}
178+
environmentName={null}
179+
clusterId={clusterId}
180+
namespace={null}
181+
isProduction={null}
182+
description={null}
183+
hideClusterDrawer={handleRedirectToClusterList}
184+
isVirtual={isVirtualCluster}
185+
category={null}
186+
/>
187+
)
188+
}}
189+
/>
190+
</section>
191+
)
192+
}
193+
194+
export default ClusterComponents

0 commit comments

Comments
 (0)