Skip to content

Commit 7218d58

Browse files
committed
feat: implement AppStatusBody component and integrate into AppStatusModal
1 parent dd454fe commit 7218d58

File tree

5 files changed

+112
-2
lines changed

5 files changed

+112
-2
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { ComponentProps, ReactNode, useMemo } from 'react'
2+
3+
import { Tooltip } from '@Common/Tooltip'
4+
5+
import { ShowMoreText } from '../ShowMoreText'
6+
import { AppStatus } from '../StatusComponent'
7+
import { APP_STATUS_CUSTOM_MESSAGES } from './constants'
8+
import { AppStatusModalProps } from './types'
9+
import { getAppStatusMessageFromAppDetails } from './utils'
10+
11+
const InfoCardItem = ({ heading, value, isLast = false }: { heading: string; value: ReactNode; isLast?: boolean }) => (
12+
<div
13+
className={`py-12 px-16 flexbox dc__align-items-center dc__gap-16 ${!isLast ? 'border__secondary--bottom' : ''}`}
14+
>
15+
<Tooltip content={heading}>
16+
<h3 className="cn-9 fs-13 fw-4 lh-1-5 dc__truncate">{heading}</h3>
17+
</Tooltip>
18+
19+
{typeof value === 'string' ? <ShowMoreText textClass="cn-9 fs-13 fw-4 lh-1-5" text={value} /> : value}
20+
</div>
21+
)
22+
23+
export const AppStatusBody = ({ appDetails, type }: Pick<AppStatusModalProps, 'appDetails' | 'type'>) => {
24+
const message = useMemo(() => getAppStatusMessageFromAppDetails(appDetails), [appDetails])
25+
const customMessage = APP_STATUS_CUSTOM_MESSAGES[appDetails.resourceTree?.status?.toUpperCase()]
26+
27+
const infoCardItems: (Omit<ComponentProps<typeof InfoCardItem>, 'isLast'> & { id: number })[] = [
28+
{
29+
id: 1,
30+
heading: type !== 'stack-manager' ? 'Application Status' : 'Status',
31+
value: <AppStatus status={appDetails.resourceTree?.status?.toUpperCase() || appDetails.appStatus} />,
32+
},
33+
message && {
34+
id: 2,
35+
heading: 'Message',
36+
value: message,
37+
},
38+
customMessage && {
39+
id: 3,
40+
heading: 'Message',
41+
value: customMessage,
42+
},
43+
]
44+
45+
return (
46+
<div className="flexbox-col dc__gap-16">
47+
{/* Info card */}
48+
<div className="flexbox-col br-8 border__primary bg__primary shadow__card--secondary">
49+
{infoCardItems.map((item, index) => (
50+
<InfoCardItem
51+
key={item.id}
52+
heading={item.heading}
53+
value={item.value}
54+
isLast={index === infoCardItems.length - 1}
55+
/>
56+
))}
57+
</div>
58+
</div>
59+
)
60+
}

src/Shared/Components/AppStatusModal/AppStatusModal.component.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import { ComponentSizeType } from '@Shared/constants'
33

44
import { Button, ButtonStyleType, ButtonVariantType } from '../Button'
55
import { Icon } from '../Icon'
6+
import { AppStatusBody } from './AppStatusBody'
67
import { AppStatusModalProps } from './types'
78

8-
const AppStatusModal = ({ title, handleClose }: AppStatusModalProps) => (
9+
const AppStatusModal = ({ title, handleClose, type, appDetails }: AppStatusModalProps) => (
910
<Drawer position="right" width="1024px" onClose={handleClose} onEscape={handleClose}>
1011
<div
1112
className="flexbox-col dc__content-space h-100 border__primary--left bg__modal--primary shadow__modal"
@@ -28,7 +29,9 @@ const AppStatusModal = ({ title, handleClose }: AppStatusModalProps) => (
2829
</div>
2930
</div>
3031

31-
<div className="flexbox-col flex-grow-1 dc__overflow-auto p-20 dc__gap-16" />
32+
<div className="flexbox-col flex-grow-1 dc__overflow-auto p-20 dc__gap-16">
33+
<AppStatusBody appDetails={appDetails} type={type} />
34+
</div>
3235
</div>
3336
</Drawer>
3437
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const APP_STATUS_CUSTOM_MESSAGES = {
2+
HIBERNATED: "This application's workloads are scaled down to 0 replicas",
3+
'PARTIALLY HIBERNATED': "Some of this application's workloads are scaled down to 0 replicas.",
4+
INTEGRATION_INSTALLING: 'The installation will complete when status for all the below resources become HEALTHY.',
5+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
import { ReactNode } from 'react'
22

3+
import { AppDetails } from '@Shared/types'
4+
35
export interface AppStatusModalProps {
46
title: ReactNode
57
handleClose: () => void
8+
type: 'devtron-app' | 'external-apps' | 'stack-manager' | 'release'
9+
/**
10+
* If not given
11+
*/
12+
handleShowConfigDriftModal?: () => void
13+
/**
14+
* If given would not poll for app details and resource tree, Polling for gitops timeline would still be done
15+
*/
16+
appDetails?: AppDetails
617
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { aggregateNodes } from '@Shared/Helpers'
2+
import { AppDetails } from '@Shared/types'
3+
4+
import { AggregatedNodes } from '../CICDHistory'
5+
6+
export const getAppStatusMessageFromAppDetails = (appDetails: AppDetails): string => {
7+
if (!appDetails?.resourceTree) {
8+
return ''
9+
}
10+
11+
const nodes: AggregatedNodes = aggregateNodes(
12+
appDetails.resourceTree.nodes || [],
13+
appDetails.resourceTree.podMetadata || [],
14+
)
15+
16+
const { conditions } = appDetails.resourceTree
17+
const rollout = nodes?.nodes?.Rollout?.entries()?.next()?.value?.[1]
18+
19+
if (Array.isArray(conditions) && conditions.length > 0 && conditions[0].message) {
20+
return conditions[0].message
21+
}
22+
23+
if (rollout?.health?.message) {
24+
return rollout.health.message
25+
}
26+
if (appDetails.FluxAppStatusDetail) {
27+
return appDetails.FluxAppStatusDetail.message
28+
}
29+
30+
return ''
31+
}

0 commit comments

Comments
 (0)