Skip to content

Commit b2c3e06

Browse files
authored
Merge branch 'main' into feat/catalog-framework
2 parents ece00a8 + d3f51c4 commit b2c3e06

File tree

8 files changed

+137
-59
lines changed

8 files changed

+137
-59
lines changed

src/components/app/details/appDetails/appDetails.scss

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,6 @@ table.pod__table td:last-child {
246246
}
247247

248248
.no-pod {
249-
display: flex;
250-
align-items: center;
251-
justify-content: center;
252249
width: 100%;
253250
height: 100%;
254251
flex-direction: column;

src/components/app/details/cIDetails/CIDetails.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import React, { useState, useEffect, useMemo } from 'react'
22
import { showError, Progressing, Reload, GenericEmptyState, useAsync } from '@devtron-labs/devtron-fe-common-lib'
3-
import { getCIHistoricalStatus, getTriggerHistory, getArtifact, getTagDetails, getArtifactForJobCi, getCIPipelines } from '../../service'
3+
import {
4+
getCIPipelines,
5+
getCIHistoricalStatus,
6+
getTriggerHistory,
7+
getArtifact,
8+
getTagDetails,
9+
getArtifactForJobCi,
10+
} from '../../service'
411
import { useScrollable, useInterval, mapByKey, asyncWrap } from '../../../common'
512
import { URLS, ModuleNameMap } from '../../../../config'
613
import { NavLink, Switch, Route, Redirect } from 'react-router-dom'
@@ -28,7 +35,7 @@ import { PipelineType } from '../triggerView/types'
2835
const terminalStatus = new Set(['succeeded', 'failed', 'error', 'cancelled', 'nottriggered', 'notbuilt'])
2936
let statusSet = new Set(['starting', 'running', 'pending'])
3037

31-
export default function CIDetails({ isJobView, filteredEnvIds }: { isJobView?: boolean, filteredEnvIds?: string }) {
38+
export default function CIDetails({ isJobView, filteredEnvIds }: { isJobView?: boolean; filteredEnvIds?: string }) {
3239
const { appId, pipelineId, buildId } = useParams<{
3340
appId: string
3441
pipelineId: string
@@ -164,7 +171,7 @@ export default function CIDetails({ isJobView, filteredEnvIds }: { isJobView?: b
164171
replace(generatePath(path, { appId, pipelineId: pipelines[0].id }))
165172
}
166173
const pipelineOptions: CICDSidebarFilterOptionType[] = (pipelines || []).map((item) => {
167-
return { value: `${item.id}`, label: item.name, pipelineId: item.id, pipelineType: item.pipelineType}
174+
return { value: `${item.id}`, label: item.name, pipelineId: item.id, pipelineType: item.pipelineType }
168175
})
169176
const pipelinesMap = mapByKey(pipelines, 'id')
170177
const pipeline = pipelinesMap.get(+pipelineId)
@@ -379,6 +386,7 @@ export const Details = ({
379386
artifact={triggerDetails.artifact}
380387
environmentName={triggerDetails.environmentName}
381388
isJobView={isJobView}
389+
workerPodName={triggerDetails.name}
382390
/>
383391
<ul className="tab-list dc__border-bottom pl-20 pr-20">
384392
<li className="tab-list__tab">

src/components/app/details/cicdHistory/Constants.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,9 @@ export const HISTORY_LABEL = {
1919
APPLICATION: 'Application',
2020
ENVIRONMENT: 'Environment',
2121
PIPELINE: 'Pipeline',
22-
}
22+
}
23+
24+
export const WORKER_POD_BASE_URL = '/resource-browser/1/devtron-ci/pod/k8sEmptyGroup'
25+
26+
export const TIMEOUT_VALUE = '1' // in hours
27+

src/components/app/details/cicdHistory/History.components.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export const GitChanges = ({
120120
<div className="flex column left w-100 ">
121121
{ciMaterials?.map((ciMaterial, index) => {
122122
const gitTrigger = gitTriggers[ciMaterial.id]
123-
return gitTrigger && (gitTrigger.Commit || gitTrigger.WebhookData?.Data) ? (
123+
return gitTrigger && (gitTrigger.Commit || gitTrigger.WebhookData?.data) ? (
124124
<div
125125
key={`mat-${gitTrigger?.Commit}-${index}`}
126126
className="bcn-0 pt-12 br-4 en-2 bw-1 pb-12 mt-16 ml-16"

src/components/app/details/cicdHistory/TriggerDetails.tsx

Lines changed: 88 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ import {
2323
TriggerDetailsType,
2424
WorkerStatusType,
2525
} from '../cicdHistory/types'
26-
import { Link } from 'react-router-dom'
26+
import { Link, NavLink } from 'react-router-dom'
2727
import { cancelCiTrigger, cancelPrePostCdTrigger, extractImage } from '../../service'
2828
import { DEFAULT_ENV } from '../triggerView/Constants'
29+
import { TIMEOUT_VALUE, WORKER_POD_BASE_URL } from './Constants'
2930

3031
const TriggerDetailsStatusIcon = React.memo(({ status }: TriggerDetailsStatusIconType): JSX.Element => {
3132
return (
@@ -61,6 +62,7 @@ export const TriggerDetails = React.memo(
6162
artifact,
6263
environmentName,
6364
isJobView,
65+
workerPodName,
6466
}: TriggerDetailsType): JSX.Element => {
6567
return (
6668
<div className="trigger-details">
@@ -88,6 +90,7 @@ export const TriggerDetails = React.memo(
8890
stage={stage}
8991
type={type}
9092
isJobView={isJobView}
93+
workerPodName={workerPodName}
9194
/>
9295
</div>
9396
</div>
@@ -98,7 +101,10 @@ export const TriggerDetails = React.memo(
98101
const Finished = React.memo(({ status, finishedOn, artifact, type }: FinishedType): JSX.Element => {
99102
return (
100103
<div className="flex column left dc__min-width-fit-content">
101-
<div className={`${status} fs-14 fw-6 ${TERMINAL_STATUS_COLOR_CLASS_MAP[status.toLowerCase()] || 'cn-5'}`} data-testid="deployment-status-text">
104+
<div
105+
className={`${status} fs-14 fw-6 ${TERMINAL_STATUS_COLOR_CLASS_MAP[status.toLowerCase()] || 'cn-5'}`}
106+
data-testid="deployment-status-text"
107+
>
102108
{status && status.toLowerCase() === 'cancelled' ? 'ABORTED' : status}
103109
</div>
104110
<div className="flex left">
@@ -121,39 +127,54 @@ const Finished = React.memo(({ status, finishedOn, artifact, type }: FinishedTyp
121127
)
122128
})
123129

124-
const WorkerStatus = React.memo(({ message, podStatus, stage }: WorkerStatusType): JSX.Element | null => {
125-
if (!message && !podStatus) return null
126-
return (
127-
<>
128-
<span style={{ height: '80%', borderRight: '1px solid var(--N100)', margin: '0 16px' }} />
129-
<div className="flex left column">
130-
<div className="flex left fs-14">
131-
<div className="mr-10">{stage === 'DEPLOY' ? 'Message' : 'Worker'}</div>
132-
{podStatus && (
133-
<div className="fw-6" style={{ color: colorMap[podStatus.toLowerCase()] }}>
134-
{podStatus}
135-
</div>
130+
const WorkerStatus = React.memo(
131+
({ message, podStatus, stage, workerPodName, finishedOn }: WorkerStatusType): JSX.Element | null => {
132+
if (!message && !podStatus) return null
133+
// check if finishedOn time is timed out or not
134+
const isTimedOut = moment(finishedOn).isBefore(moment().subtract(TIMEOUT_VALUE, 'hours'))
135+
// finishedOn is 0001-01-01T00:00:00Z when the worker is still running
136+
const showLink = finishedOn === ZERO_TIME_STRING || !isTimedOut
137+
138+
return (
139+
<>
140+
<span style={{ height: '80%', borderRight: '1px solid var(--N100)', margin: '0 16px' }} />
141+
<div className="flex left column">
142+
<div className="flex left fs-14">
143+
{stage === 'DEPLOY' ? (
144+
<div className="mr-10">Message</div>
145+
) : showLink ? (
146+
<NavLink to={`${WORKER_POD_BASE_URL}/${workerPodName}/logs`} className="anchor">
147+
<div className="mr-10">Worker</div>
148+
</NavLink>
149+
) : (
150+
<div className="mr-10">Worker</div>
151+
)}
152+
{podStatus && (
153+
<div className="fw-6" style={{ color: colorMap[podStatus.toLowerCase()] }}>
154+
{podStatus}
155+
</div>
156+
)}
157+
</div>
158+
{message && (
159+
<Tippy
160+
theme={TippyTheme.black}
161+
className="default-tt"
162+
arrow={false}
163+
placement="bottom-start"
164+
animation="shift-toward-subtle"
165+
content={message}
166+
>
167+
<div className="fs-12 cn-7 dc__ellipsis-right__2nd-line">{message}</div>
168+
</Tippy>
136169
)}
137170
</div>
138-
{message && (
139-
<Tippy
140-
theme={TippyTheme.black}
141-
className="default-tt"
142-
arrow={false}
143-
placement="bottom-start"
144-
animation="shift-toward-subtle"
145-
content={message}
146-
>
147-
<div className="fs-12 cn-7 dc__ellipsis-right__2nd-line">{message}</div>
148-
</Tippy>
149-
)}
150-
</div>
151-
</>
152-
)
153-
})
171+
</>
172+
)
173+
},
174+
)
154175

155176
const ProgressingStatus = React.memo(
156-
({ status, message, podStatus, stage, type }: ProgressingStatusType): JSX.Element => {
177+
({ status, message, podStatus, stage, type, finishedOn, workerPodName }: ProgressingStatusType): JSX.Element => {
157178
const [aborting, setAborting] = useState(false)
158179
const [abortConfirmation, setAbortConfiguration] = useState(false)
159180
const { buildId, triggerId, pipelineId } = useParams<{
@@ -187,9 +208,7 @@ const ProgressingStatus = React.memo(
187208
<>
188209
<div className="flex left mb-24">
189210
<div className="dc__min-width-fit-content">
190-
<div className={`${status} fs-14 fw-6 flex left inprogress-status-color`}>
191-
In progress
192-
</div>
211+
<div className={`${status} fs-14 fw-6 flex left inprogress-status-color`}>In progress</div>
193212
</div>
194213

195214
{abort && (
@@ -200,7 +219,13 @@ const ProgressingStatus = React.memo(
200219
Abort
201220
</button>
202221
)}
203-
<WorkerStatus message={message} podStatus={podStatus} stage={stage} />
222+
<WorkerStatus
223+
message={message}
224+
podStatus={podStatus}
225+
stage={stage}
226+
finishedOn={finishedOn}
227+
workerPodName={workerPodName}
228+
/>
204229
</div>
205230
{abortConfirmation && (
206231
<ConfirmationDialog>
@@ -233,16 +258,40 @@ const ProgressingStatus = React.memo(
233258
)
234259

235260
const CurrentStatus = React.memo(
236-
({ status, finishedOn, artifact, message, podStatus, stage, type, isJobView }: CurrentStatusType): JSX.Element => {
261+
({
262+
status,
263+
finishedOn,
264+
artifact,
265+
message,
266+
podStatus,
267+
stage,
268+
type,
269+
isJobView,
270+
workerPodName,
271+
}: CurrentStatusType): JSX.Element => {
237272
if (PROGRESSING_STATUS[status.toLowerCase()]) {
238273
return (
239-
<ProgressingStatus status={status} message={message} podStatus={podStatus} stage={stage} type={type} />
274+
<ProgressingStatus
275+
status={status}
276+
message={message}
277+
podStatus={podStatus}
278+
stage={stage}
279+
type={type}
280+
finishedOn={finishedOn}
281+
workerPodName={workerPodName}
282+
/>
240283
)
241284
} else {
242285
return (
243-
<div className={`flex left ${ isJobView ? "mb-24" : ""}`}>
286+
<div className={`flex left ${isJobView ? 'mb-24' : ''}`}>
244287
<Finished status={status} finishedOn={finishedOn} artifact={artifact} type={type} />
245-
<WorkerStatus message={message} podStatus={podStatus} stage={stage} />
288+
<WorkerStatus
289+
message={message}
290+
podStatus={podStatus}
291+
stage={stage}
292+
finishedOn={finishedOn}
293+
workerPodName={workerPodName}
294+
/>
246295
</div>
247296
)
248297
}

src/components/app/details/cicdHistory/types.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export interface CIListItemType {
108108
hideImageTaggingHardDelete?: boolean
109109
appliedFilters?: FilterConditionsListType[]
110110
appliedFiltersTimestamp?: string
111-
isSuperAdmin?:boolean
111+
isSuperAdmin?: boolean
112112
}
113113

114114
export interface ImageComment {
@@ -146,7 +146,7 @@ export interface GitChangesType {
146146
ciPipelineId?: number
147147
appReleaseTagNames?: string[]
148148
tagsEditable?: boolean
149-
hideImageTaggingHardDelete?: boolean,
149+
hideImageTaggingHardDelete?: boolean
150150
appliedFilters?: FilterConditionsListType[]
151151
appliedFiltersTimestamp?: string
152152
}
@@ -206,6 +206,7 @@ export interface TriggerDetailsType {
206206
artifact?: string
207207
environmentName?: string
208208
isJobView?: boolean
209+
workerPodName?: string
209210
}
210211

211212
export interface TriggerDetailsStatusIconType {
@@ -222,13 +223,17 @@ export interface WorkerStatusType {
222223
message: string
223224
podStatus: string
224225
stage: DeploymentStageType
226+
finishedOn?: string
227+
workerPodName?: string
225228
}
226229
export interface ProgressingStatusType {
227230
status: string
228231
message: string
229232
podStatus: string
230233
stage: DeploymentStageType
231234
type: HistoryComponentType
235+
finishedOn?: string
236+
workerPodName?: string
232237
}
233238

234239
export interface CurrentStatusType {
@@ -240,6 +245,7 @@ export interface CurrentStatusType {
240245
stage: DeploymentStageType
241246
type: HistoryComponentType
242247
isJobView?: boolean
248+
workerPodName?: string
243249
}
244250

245251
export interface StartDetailsType {

src/components/v2/appDetails/k8Resource/nodeDetail/NodeDetail.component.tsx

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ function NodeDetailComponent({
7474
const selectedContainerValue = isResourceBrowserView ? selectedResource?.name : podMetaData?.name
7575
const _selectedContainer = selectedContainer.get(selectedContainerValue) || containers?.[0]?.name || ''
7676
const [selectedContainerName, setSelectedContainerName] = useState(_selectedContainer)
77+
const [hideDeleteButton, setHideDeleteButton] = useState(false)
78+
7779
useEffect(() => toggleManagedFields(isManagedFields), [selectedTabName])
7880
useEffect(() => {
7981
if (location.pathname.endsWith('/terminal') && params.nodeType === Nodes.Pod.toLowerCase()) {
@@ -102,12 +104,17 @@ function NodeDetailComponent({
102104

103105
const getContainersFromManifest = async () => {
104106
try {
107+
const nullCaseName = isResourceBrowserView && params.nodeType === 'pod' ? params.node : ''
105108
const { result } = await getManifestResource(
106109
appDetails,
107-
params.podName,
110+
params.node,
108111
params.nodeType,
109112
isResourceBrowserView,
110-
selectedResource,
113+
{
114+
...selectedResource,
115+
name: selectedResource.name ? selectedResource.name : nullCaseName,
116+
namespace: selectedResource.namespace ? selectedResource.namespace : params.namespace,
117+
},
111118
)
112119
const _resourceContainers = []
113120
if (result?.manifest?.spec) {
@@ -130,7 +137,6 @@ function NodeDetailComponent({
130137
})),
131138
)
132139
}
133-
134140
}
135141

136142
if (result?.ephemeralContainers) {
@@ -153,8 +159,14 @@ function NodeDetailComponent({
153159
setResourceDeleted(false)
154160
}
155161
} catch (err) {
162+
// when resource is deleted
156163
if (Array.isArray(err['errors']) && err['errors'].some((_err) => _err.code === '404')) {
157164
setResourceDeleted(true)
165+
setHideDeleteButton(true)
166+
// when user is not authorized to view resource
167+
} else if (err['code'] === 403) {
168+
setHideDeleteButton(true)
169+
showError(err)
158170
} else {
159171
showError(err)
160172

@@ -321,12 +333,13 @@ function NodeDetailComponent({
321333
</>
322334
)}
323335
</div>
324-
{isResourceBrowserView && (
325-
<span className="flex left fw-6 cr-5 ml-16 fs-12 cursor" onClick={toggleDeleteDialog}>
326-
<DeleteIcon className="icon-dim-16 mr-5 scr-5" />
327-
{CLUSTER_NODE_ACTIONS_LABELS.delete}
328-
</span>
329-
)}
336+
{isResourceBrowserView &&
337+
!hideDeleteButton && ( // hide delete button if resource is deleted or user is not authorized
338+
<span className="flex left fw-6 cr-5 ml-16 fs-12 cursor" onClick={toggleDeleteDialog}>
339+
<DeleteIcon className="icon-dim-16 mr-5 scr-5" />
340+
{CLUSTER_NODE_ACTIONS_LABELS.delete}
341+
</span>
342+
)}
330343
</div>
331344
{renderPodTerminal()}
332345

src/components/v2/appDetails/k8Resource/nodeDetail/NodeDetailTabs/Terminal.component.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ function TerminalComponent({
239239

240240
if (isDeleted || !selectedContainerName.length) {
241241
return (
242-
<div>
242+
showTerminal && <div>
243243
<MessageUI
244244
msg="This resource no longer exists"
245245
size={32}

0 commit comments

Comments
 (0)