Skip to content

Commit a541c8f

Browse files
committed
Merge branch 'main' into custom-input-v2
2 parents b29b1c4 + 7481202 commit a541c8f

File tree

10 files changed

+259
-102
lines changed

10 files changed

+259
-102
lines changed

src/components/app/details/appDetails/AppDetails.tsx

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
showError,
44
Progressing,
55
ConfirmationDialog,
6-
Host,
76
noop,
87
stopPropagation,
98
multiSelectStyles,
@@ -24,7 +23,7 @@ import {
2423
HELM_DEPLOYMENT_STATUS_TEXT,
2524
RESOURCES_NOT_FOUND,
2625
} from '../../../../config'
27-
import { NavigationArrow, useAppContext, useEventSource, FragmentHOC, ScanDetailsModal } from '../../../common'
26+
import { NavigationArrow, useAppContext, FragmentHOC, ScanDetailsModal } from '../../../common'
2827
import { CustomValueContainer, groupHeaderStyle, GroupHeading, Option } from './../../../v2/common/ReactSelect.utils'
2928
import {
3029
getAppConfigStatus,
@@ -139,8 +138,10 @@ export default function AppDetail({ filteredEnvIds }: { filteredEnvIds?: string
139138

140139
// Set the URL and push to navigation stack
141140
if (selectedEnvId) {
142-
const newUrl = getAppDetailsURL(params.appId, selectedEnvId)
143-
push(newUrl)
141+
if (String(selectedEnvId) !== String(params.envId)) {
142+
const newUrl = getAppDetailsURL(params.appId, selectedEnvId)
143+
push(newUrl)
144+
}
144145
} else {
145146
setEnvironmentId(null)
146147
}
@@ -224,7 +225,8 @@ export const Details: React.FC<DetailsType> = ({
224225
}) => {
225226
const params = useParams<{ appId: string; envId: string }>()
226227
const location = useLocation()
227-
const [streamData, setStreamData] = useState<AppStreamData>(null)
228+
// fixme: the state is not being set anywhere and just being drilled down
229+
const [streamData] = useState<AppStreamData>(null)
228230
const [detailedStatus, toggleDetailedStatus] = useState<boolean>(false)
229231
const [resourceTreeFetchTimeOut, setResourceTreeFetchTimeOut] = useState<boolean>(false)
230232
const [urlInfo, setUrlInfo] = useState<boolean>(false)
@@ -246,13 +248,15 @@ export const Details: React.FC<DetailsType> = ({
246248
})
247249
const [loadingDetails, setLoadingDetails] = useState(true)
248250
const [loadingResourceTree, setLoadingResourceTree] = useState(true)
251+
// State to track the loading state for the timeline data when the detailed status modal opens
252+
const [isInitialTimelineDataLoading, setIsInitialTimelineDataLoading] = useState(true)
249253
const [errorsList, setErrorsList] = useState<ErrorItem[]>([])
250254
const appDetailsRef = useRef(null)
251255
const appDetailsRequestRef = useRef(null)
252-
const deploymentModalShownRef = useRef(false)
253256
const { envId } = useParams<{ appId: string; envId?: string }>()
254257
const pollResourceTreeRef = useRef(true)
255258
const appDetailsAbortRef = useRef(null)
259+
const shouldFetchTimelineRef = useRef(false)
256260

257261
const [deploymentStatusDetailsBreakdownData, setDeploymentStatusDetailsBreakdownData] =
258262
useState<DeploymentStatusDetailsBreakdownDataType>({
@@ -267,26 +271,18 @@ export const Details: React.FC<DetailsType> = ({
267271
const interval = window._env_.DEVTRON_APP_DETAILS_POLLING_INTERVAL || 30000
268272
appDetailsRequestRef.current = appDetails?.deploymentAppDeleteRequest
269273

270-
const syncSSE = useEventSource(
271-
`${Host}/api/v1/applications/stream?name=${appDetails?.appName}-${appDetails?.environmentName}`,
272-
[params.appId, params.envId],
273-
appDetails &&
274-
!!appDetails.appName &&
275-
!!appDetails.environmentName &&
276-
appDetails.deploymentAppType !== DeploymentAppTypes.HELM,
277-
(event) => setStreamData(JSON.parse(event.data)),
278-
)
279-
280274
const aggregatedNodes: AggregatedNodes = useMemo(() => {
281275
return aggregateNodes(appDetails?.resourceTree?.nodes || [], appDetails?.resourceTree?.podMetadata || [])
282276
}, [appDetails])
283277

284278
useEffect(() => {
285-
if (location.search.includes(DEPLOYMENT_STATUS_QUERY_PARAM)) {
286-
deploymentModalShownRef.current = true
287-
} else {
288-
deploymentModalShownRef.current = false
279+
const isModalOpen = location.search.includes(DEPLOYMENT_STATUS_QUERY_PARAM)
280+
// Reset the loading state when the modal is closed
281+
if (shouldFetchTimelineRef.current && !isModalOpen) {
282+
setIsInitialTimelineDataLoading(true)
289283
}
284+
// The timeline should be fetched by default if the modal is open
285+
shouldFetchTimelineRef.current = isModalOpen
290286
}, [location.search])
291287

292288
const clearDeploymentStatusTimer = useCallback((): void => {
@@ -304,15 +300,6 @@ export const Details: React.FC<DetailsType> = ({
304300

305301
clearDeploymentStatusTimer()
306302

307-
if (
308-
processedDeploymentStatusDetailsData.deploymentStatus === DEPLOYMENT_STATUS.HEALTHY ||
309-
processedDeploymentStatusDetailsData.deploymentStatus === DEPLOYMENT_STATUS.TIMED_OUT ||
310-
processedDeploymentStatusDetailsData.deploymentStatus === DEPLOYMENT_STATUS.SUPERSEDED ||
311-
processedDeploymentStatusDetailsData.deploymentStatus === DEPLOYMENT_STATUS.SUCCEEDED
312-
) {
313-
deploymentModalShownRef.current = false
314-
}
315-
316303
if (processedDeploymentStatusDetailsData.deploymentStatus === DEPLOYMENT_STATUS.INPROGRESS) {
317304
deploymentStatusTimer = setTimeout(() => {
318305
getDeploymentDetailStepsData()
@@ -327,24 +314,29 @@ export const Details: React.FC<DetailsType> = ({
327314
processDeploymentStatusDetailsData,
328315
clearDeploymentStatusTimer,
329316
DEPLOYMENT_STATUS,
330-
deploymentModalShownRef,
331317
setDeploymentStatusDetailsBreakdownData,
332318
],
333319
)
334320

335321
const getDeploymentDetailStepsData = useCallback(
336322
(showTimeline?: boolean): void => {
323+
const shouldFetchTimeline = showTimeline ?? shouldFetchTimelineRef.current
324+
337325
// Deployments status details for Devtron apps
338-
getDeploymentStatusDetail(params.appId, params.envId, showTimeline ?? deploymentModalShownRef.current).then(
326+
getDeploymentStatusDetail(params.appId, params.envId, shouldFetchTimeline).then(
339327
(deploymentStatusDetailRes) => {
340328
processDeploymentStatusData(deploymentStatusDetailRes.result)
329+
// Update the loading status if the modal is open
330+
if (shouldFetchTimeline) {
331+
setIsInitialTimelineDataLoading(false)
332+
}
341333
},
342334
)
343335
},
344336
[
345337
params.appId,
346338
params.envId,
347-
deploymentModalShownRef.current,
339+
shouldFetchTimelineRef.current,
348340
getDeploymentStatusDetail,
349341
processDeploymentStatusData,
350342
],
@@ -437,7 +429,9 @@ export const Details: React.FC<DetailsType> = ({
437429
}
438430

439431
function _getDeploymentStatusDetail(deploymentAppType: DeploymentAppTypes) {
440-
getDeploymentStatusDetail(params.appId, params.envId, deploymentModalShownRef.current)
432+
const shouldFetchTimeline = shouldFetchTimelineRef.current
433+
434+
getDeploymentStatusDetail(params.appId, params.envId, shouldFetchTimeline)
441435
.then((deploymentStatusDetailRes) => {
442436
if (deploymentStatusDetailRes.result) {
443437
if (deploymentAppType === DeploymentAppTypes.HELM) {
@@ -456,6 +450,9 @@ export const Details: React.FC<DetailsType> = ({
456450
} else {
457451
processDeploymentStatusData(deploymentStatusDetailRes.result)
458452
}
453+
if (shouldFetchTimeline) {
454+
setIsInitialTimelineDataLoading(false)
455+
}
459456
}
460457
})
461458
.catch(noop)
@@ -687,6 +684,7 @@ export const Details: React.FC<DetailsType> = ({
687684
streamData={streamData}
688685
deploymentStatusDetailsBreakdownData={deploymentStatusDetailsBreakdownData}
689686
isVirtualEnvironment={isVirtualEnvRef.current}
687+
isLoading={isInitialTimelineDataLoading}
690688
/>
691689
)}
692690
{showScanDetailsModal && (

src/components/app/details/appDetails/DeploymentStatusBreakdown.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@ export default function DeploymentStatusDetailBreakdown({
4646
type={TIMELINE_STATUS.GIT_COMMIT}
4747
deploymentDetailedData={deploymentStatusDetailsBreakdownData}
4848
/>
49+
50+
<ErrorInfoStatusBar
51+
type={TIMELINE_STATUS.ARGOCD_SYNC}
52+
nonDeploymentError={deploymentStatusDetailsBreakdownData.nonDeploymentError}
53+
errorMessage={deploymentStatusDetailsBreakdownData.deploymentError}
54+
/>
55+
<DeploymentStatusDetailRow
56+
type={TIMELINE_STATUS.ARGOCD_SYNC}
57+
deploymentDetailedData={deploymentStatusDetailsBreakdownData}
58+
/>
59+
4960
<ErrorInfoStatusBar
5061
type={TIMELINE_STATUS.KUBECTL_APPLY}
5162
nonDeploymentError={deploymentStatusDetailsBreakdownData.nonDeploymentError}
@@ -55,6 +66,7 @@ export default function DeploymentStatusDetailBreakdown({
5566
type={TIMELINE_STATUS.KUBECTL_APPLY}
5667
deploymentDetailedData={deploymentStatusDetailsBreakdownData}
5768
/>
69+
5870
<DeploymentStatusDetailRow
5971
type={TIMELINE_STATUS.APP_HEALTH}
6072
hideVerticalConnector={true}

src/components/app/details/appDetails/DeploymentStatusCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ function DeploymentStatusCard({
8787

8888
const onClickLastDeploymentStatus = (e) => {
8989
if (!hideDetails) {
90-
refetchDeploymentStatus(true)
9190
showDeploymentDetailedStatus(e)
91+
refetchDeploymentStatus(true)
9292
}
9393
}
9494

src/components/app/details/appDetails/DeploymentStatusDetailModal.tsx

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,22 @@ import DeploymentStatusDetailBreakdown from './DeploymentStatusBreakdown'
44
import { DeploymentStatusDetailModalType } from './appDetails.type'
55
import { useHistory } from 'react-router-dom'
66
import './appDetails.scss'
7-
import { Drawer } from '@devtron-labs/devtron-fe-common-lib'
7+
import { Drawer, Progressing } from '@devtron-labs/devtron-fe-common-lib'
88

99
export default function DeploymentStatusDetailModal({
1010
appName,
1111
environmentName,
1212
streamData,
1313
deploymentStatusDetailsBreakdownData,
14-
isVirtualEnvironment
14+
isVirtualEnvironment,
15+
isLoading,
1516
}: DeploymentStatusDetailModalType) {
1617
const history = useHistory()
1718
const appStatusDetailRef = useRef<HTMLDivElement>(null)
1819

1920
const closeStatusModal = () => {
2021
history.replace({
21-
search: ''
22+
search: '',
2223
})
2324
}
2425

@@ -29,10 +30,7 @@ export default function DeploymentStatusDetailModal({
2930
}
3031
}
3132
const outsideClickHandler = (evt): void => {
32-
if (
33-
appStatusDetailRef.current &&
34-
!appStatusDetailRef.current.contains(evt.target)
35-
) {
33+
if (appStatusDetailRef.current && !appStatusDetailRef.current.contains(evt.target)) {
3634
closeStatusModal()
3735
}
3836
}
@@ -53,19 +51,35 @@ export default function DeploymentStatusDetailModal({
5351

5452
return (
5553
<Drawer position="right" width="1024px">
56-
<div className="deployment-status-breakdown-modal-container bcn-0" data-testid="deployment-status-drawer" ref={appStatusDetailRef}>
54+
<div
55+
className="deployment-status-breakdown-modal-container bcn-0"
56+
data-testid="deployment-status-drawer"
57+
ref={appStatusDetailRef}
58+
>
5759
<div className="dc__box-shadow pb-12 pt-12 bcn-0">
58-
<div className="title flex dc__content-space pl-20 pr-20 " data-testid="app-status-cross">
60+
<div
61+
className="title flex dc__content-space pl-20 pr-20 show-shimmer-loading"
62+
data-testid="app-status-cross"
63+
>
5964
<div>
60-
<div className="cn-9 fs-16 fw-6">
61-
Deployment status: {appName} / {environmentName}
65+
<div className="cn-9 fs-16 fw-6 flexbox flex-align-center">
66+
Deployment status:&nbsp;
67+
{appName ?? <span className="child child-shimmer-loading w-120 h-20 mt-0-imp" />}
68+
&nbsp;/&nbsp;
69+
{environmentName ?? (
70+
<span className="child child-shimmer-loading w-120 h-20 mt-0-imp" />
71+
)}
6272
</div>
6373
<div className="flexbox">
64-
<span
65-
className={`app-summary__status-name fs-13 fw-6 f-${deploymentStatusDetailsBreakdownData.deploymentStatus}`}
66-
>
67-
{deploymentStatusDetailsBreakdownData.deploymentStatusText}
68-
</span>
74+
{isLoading ? (
75+
<span className="child child-shimmer-loading w-120 h-20" />
76+
) : (
77+
<span
78+
className={`app-summary__status-name fs-13 fw-6 f-${deploymentStatusDetailsBreakdownData.deploymentStatus}`}
79+
>
80+
{deploymentStatusDetailsBreakdownData.deploymentStatusText}
81+
</span>
82+
)}
6983
</div>
7084
</div>
7185
<span className="cursor" onClick={closeStatusModal}>
@@ -74,11 +88,15 @@ export default function DeploymentStatusDetailModal({
7488
</div>
7589
</div>
7690
<div className="bcn-1 dc__overflow-scroll pb-20 deployment-status-breakdown">
77-
<DeploymentStatusDetailBreakdown
78-
deploymentStatusDetailsBreakdownData={deploymentStatusDetailsBreakdownData}
79-
streamData={streamData}
80-
isVirtualEnvironment={isVirtualEnvironment}
81-
/>
91+
{isLoading ? (
92+
<Progressing />
93+
) : (
94+
<DeploymentStatusDetailBreakdown
95+
deploymentStatusDetailsBreakdownData={deploymentStatusDetailsBreakdownData}
96+
streamData={streamData}
97+
isVirtualEnvironment={isVirtualEnvironment}
98+
/>
99+
)}
82100
</div>
83101
</div>
84102
</Drawer>

src/components/app/details/appDetails/DeploymentStatusDetailRow.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ export function DeploymentStatusDetailRow({
7777
<div className="">
7878
{deploymentDetailedData.deploymentStatusBreakdown[
7979
TIMELINE_STATUS.KUBECTL_APPLY
80-
].kubeList?.map((items) => (
81-
<div className="flex left lh-20 mb-8">
80+
].kubeList?.map((items, index) => (
81+
<div className="flex left lh-20 mb-8" key={`item-${index}`}>
8282
{renderIcon(items.icon)}
8383
<span className="ml-12">{items.message}</span>
8484
</div>
@@ -226,19 +226,20 @@ export function DeploymentStatusDetailRow({
226226
{((type === TIMELINE_STATUS.KUBECTL_APPLY && statusBreakDownType.kubeList?.length) ||
227227
(type === TIMELINE_STATUS.APP_HEALTH &&
228228
appHealthDropDownlist.includes(statusBreakDownType.icon)) ||
229-
(type === TIMELINE_STATUS.GIT_COMMIT && statusBreakDownType.icon === 'failed')) && (
230-
<DropDownIcon
231-
style={{ marginLeft: 'auto', ['--rotateBy' as any]: `${180 * Number(!collapsed)}deg` }}
232-
className="icon-dim-24 rotate pointer"
233-
onClick={toggleDropdown}
234-
data-testid="steps-deployment-history-dropdown"
235-
/>
236-
)}
229+
((type === TIMELINE_STATUS.GIT_COMMIT || type === TIMELINE_STATUS.ARGOCD_SYNC) && statusBreakDownType.icon === 'failed')) && (
230+
<DropDownIcon
231+
style={{ marginLeft: 'auto', ['--rotateBy' as any]: `${180 * Number(!collapsed)}deg` }}
232+
className="icon-dim-24 rotate pointer"
233+
onClick={toggleDropdown}
234+
data-testid="steps-deployment-history-dropdown"
235+
/>
236+
)}
237237
</div>
238238
{isHelmManifestPushFailed && renderErrorInfoBar()}
239239
</div>
240240

241241
{type === TIMELINE_STATUS.GIT_COMMIT && renderDetailedData()}
242+
{type === TIMELINE_STATUS.ARGOCD_SYNC && renderDetailedData()}
242243
{type === TIMELINE_STATUS.KUBECTL_APPLY && renderDetailedData()}
243244
{type === TIMELINE_STATUS.APP_HEALTH && renderDetailChart()}
244245
{!hideVerticalConnector && <div className="vertical-connector"></div>}

src/components/app/details/appDetails/appDetails.type.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export interface DeploymentStatusDetailsBreakdownDataType {
9292
deploymentStatusBreakdown: {
9393
DEPLOYMENT_INITIATED: DeploymentStatusDetailRow
9494
GIT_COMMIT?: DeploymentStatusDetailRow
95+
ARGOCD_SYNC?: DeploymentStatusDetailRow
9596
KUBECTL_APPLY?: DeploymentStatusDetailRow
9697
APP_HEALTH?: DeploymentStatusDetailRow
9798
HELM_PACKAGE_GENERATED?: DeploymentStatusDetailRow
@@ -110,6 +111,10 @@ export interface DeploymentStatusDetailModalType {
110111
deploymentStatusDetailsBreakdownData: DeploymentStatusDetailsBreakdownDataType
111112
streamData: AppStreamData
112113
isVirtualEnvironment: boolean
114+
/**
115+
* Loading state for the timeline data
116+
*/
117+
isLoading: boolean
113118
}
114119

115120
export interface ModuleConfigResponse extends ResponseType {

0 commit comments

Comments
 (0)