Skip to content

Commit 93f3afb

Browse files
authored
Merge pull request #620 from devtron-labs/feat/ci-node-delete
feat: CI Node add & delete button
2 parents 886f724 + 46f3342 commit 93f3afb

File tree

12 files changed

+243
-3
lines changed

12 files changed

+243
-3
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devtron-labs/devtron-fe-common-lib",
3-
"version": "1.9.3",
3+
"version": "1.9.4",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",

src/Assets/IconV2/ic-add.svg

Lines changed: 19 additions & 0 deletions
Loading

src/Assets/IconV2/ic-delete.svg

Lines changed: 19 additions & 0 deletions
Loading
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
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 { useState } from 'react'
18+
import { ERROR_STATUS_CODE } from '@Common/Constants'
19+
import { Button, ButtonStyleType, ButtonVariantType, DeleteConfirmationModal, Icon } from '@Shared/Components'
20+
import { ComponentSizeType, DeleteComponentsName } from '@Shared/constants'
21+
import { ToastManager, ToastVariantType } from '@Shared/index'
22+
import { deleteWorkflow, savePipeline } from './utils'
23+
import { DeleteCINodeButtonProps } from './types'
24+
import { preventDefault, showError, stopPropagation } from '..'
25+
26+
export const DeleteCINodeButton = ({
27+
testId,
28+
showIconOnly = true,
29+
disabled = false,
30+
title,
31+
isJobView,
32+
deletePayloadConfig,
33+
onDelete,
34+
getWorkflows,
35+
}: DeleteCINodeButtonProps) => {
36+
const [showDeleteModal, setShowDeleteModal] = useState<boolean>(false)
37+
38+
const closeCIDeleteModal = (): void => {
39+
setShowDeleteModal(false)
40+
}
41+
42+
const onClickDeleteShowModal = (e) => {
43+
stopPropagation(e)
44+
preventDefault(e)
45+
setShowDeleteModal(true)
46+
}
47+
48+
const onDeleteWorkflow = async () => {
49+
try {
50+
const response = await deleteWorkflow(
51+
String(deletePayloadConfig.appId),
52+
Number(deletePayloadConfig.appWorkflowId),
53+
)
54+
if (response.errors) {
55+
const { errors } = response
56+
const { userMessage } = errors[0]
57+
ToastManager.showToast({
58+
variant: ToastVariantType.error,
59+
description: userMessage,
60+
})
61+
return
62+
}
63+
64+
if (response.status.toLowerCase() === 'ok') {
65+
ToastManager.showToast({
66+
variant: ToastVariantType.success,
67+
description: 'Workflow Deleted',
68+
})
69+
getWorkflows()
70+
}
71+
} catch (error) {
72+
showError(error)
73+
}
74+
}
75+
76+
const onClickDelete = async () => {
77+
const deletePayload = {
78+
action: 2, // To delete the pipeline
79+
appId: Number(deletePayloadConfig.appId),
80+
appWorkflowId: Number(deletePayloadConfig.appWorkflowId),
81+
ciPipeline: {
82+
id: Number(deletePayloadConfig.pipelineId),
83+
name: deletePayloadConfig.pipelineName,
84+
},
85+
}
86+
await savePipeline(deletePayload)
87+
if (typeof onDelete === 'function') {
88+
onDelete()
89+
}
90+
await onDeleteWorkflow()
91+
}
92+
93+
const renderDeleteButton = () =>
94+
showIconOnly ? (
95+
<Button
96+
ariaLabel="Delete pipeline"
97+
variant={ButtonVariantType.borderLess}
98+
dataTestId={testId}
99+
size={ComponentSizeType.xxs_small_icon}
100+
showAriaLabelInTippy
101+
onClick={onClickDeleteShowModal}
102+
style={ButtonStyleType.negativeGrey}
103+
icon={<Icon name="ic-delete" color={null} strokeWidth={1} size={12} />}
104+
disabled={disabled}
105+
showTooltip
106+
tooltipProps={{
107+
placement: 'right',
108+
content: 'Delete Pipeline',
109+
}}
110+
/>
111+
) : (
112+
<Button
113+
dataTestId={testId}
114+
disabled={disabled}
115+
onClick={onClickDeleteShowModal}
116+
text="Delete Pipeline"
117+
style={ButtonStyleType.negative}
118+
/>
119+
)
120+
121+
const renderDeleteCIModal = () =>
122+
showDeleteModal && (
123+
<DeleteConfirmationModal
124+
title={title}
125+
component={isJobView ? DeleteComponentsName.Job : DeleteComponentsName.BuildPipeline}
126+
subtitle={`Are you sure you want to delete this pipeline from '${title}' ?`}
127+
closeConfirmationModal={closeCIDeleteModal}
128+
onDelete={onClickDelete}
129+
errorCodeToShowCannotDeleteDialog={ERROR_STATUS_CODE.BAD_REQUEST}
130+
renderCannotDeleteConfirmationSubTitle="Please delete deployment pipelines for this workflow first and try again."
131+
successToastMessage="Pipeline Deleted Successfully"
132+
/>
133+
)
134+
135+
return (
136+
<>
137+
{renderDeleteButton()}
138+
{renderDeleteCIModal()}
139+
</>
140+
)
141+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './DeleteCINodeButton'
2+
export * from './utils'
3+
export * from './types'
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
interface DeletePayloadConfig {
2+
appId: string
3+
appWorkflowId: number
4+
pipelineId: number
5+
pipelineName: string
6+
}
7+
8+
export interface DeleteCINodeButtonProps {
9+
testId: string
10+
title: string
11+
showIconOnly?: boolean
12+
disabled?: boolean
13+
isJobView?: boolean
14+
deletePayloadConfig: DeletePayloadConfig
15+
onDelete?: () => void
16+
getWorkflows: () => void
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Routes } from '@Shared/constants'
2+
import { post, trash } from '..'
3+
4+
export function savePipeline(request, isRegexMaterial = false): Promise<any> {
5+
let url
6+
if (isRegexMaterial) {
7+
url = `${Routes.CI_PIPELINE_PATCH}/regex`
8+
} else {
9+
url = `${Routes.CI_PIPELINE_PATCH}`
10+
}
11+
return post(url, request)
12+
}
13+
14+
export function deleteWorkflow(appId: string, workflowId: number) {
15+
const URL = `${Routes.WORKFLOW}/${appId}/${workflowId}`
16+
return trash(URL)
17+
}

src/Common/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@ export * from './SegmentedBarChart'
6666
export * from './CodeEditor/types'
6767
export * from './Tooltip'
6868
export * from './SegmentedControl'
69+
export * from './DeleteCINodeButton'

src/Shared/Components/Button/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { ProgressingProps } from '@Common/Types'
1919
import { ButtonProps } from './types'
2020

2121
export const BUTTON_SIZE_TO_CLASS_NAME_MAP: Record<ButtonProps['size'], string> = {
22+
[ComponentSizeType.xxs_small_icon]: `${COMPONENT_SIZE_TYPE_TO_FONT_AND_BLOCK_PADDING_MAP[ComponentSizeType.xxs]} px-9 fw-6 dc__gap-6 mw-48`,
2223
[ComponentSizeType.xxs]: `${COMPONENT_SIZE_TYPE_TO_FONT_AND_BLOCK_PADDING_MAP[ComponentSizeType.xxs]} px-9 fw-6 dc__gap-6 mw-48`,
2324
[ComponentSizeType.xs]: `${COMPONENT_SIZE_TYPE_TO_FONT_AND_BLOCK_PADDING_MAP[ComponentSizeType.xs]} px-9 fw-6 dc__gap-6 mw-48`,
2425
[ComponentSizeType.small]: `${COMPONENT_SIZE_TYPE_TO_FONT_AND_BLOCK_PADDING_MAP[ComponentSizeType.small]} px-9 fw-6 dc__gap-8 mw-48`,
@@ -28,6 +29,7 @@ export const BUTTON_SIZE_TO_CLASS_NAME_MAP: Record<ButtonProps['size'], string>
2829
} as const
2930

3031
export const ICON_BUTTON_SIZE_TO_CLASS_NAME_MAP: Record<ButtonProps['size'], string> = {
32+
[ComponentSizeType.xxs_small_icon]: 'p-4',
3133
[ComponentSizeType.xxs]: 'p-1',
3234
[ComponentSizeType.xs]: 'p-3',
3335
[ComponentSizeType.small]: 'p-5',
@@ -37,6 +39,7 @@ export const ICON_BUTTON_SIZE_TO_CLASS_NAME_MAP: Record<ButtonProps['size'], str
3739
} as const
3840

3941
export const BUTTON_SIZE_TO_ICON_SIZE_MAP: Record<ButtonProps['size'], ProgressingProps['size']> = {
42+
[ComponentSizeType.xxs_small_icon]: 12,
4043
[ComponentSizeType.xxs]: 14,
4144
[ComponentSizeType.xs]: 14,
4245
[ComponentSizeType.small]: 16,
@@ -46,6 +49,7 @@ export const BUTTON_SIZE_TO_ICON_SIZE_MAP: Record<ButtonProps['size'], Progressi
4649
} as const
4750

4851
export const ICON_BUTTON_SIZE_TO_ICON_SIZE_MAP: Record<ButtonProps['size'], ProgressingProps['size']> = {
52+
[ComponentSizeType.xxs_small_icon]: 12,
4953
[ComponentSizeType.xxs]: 16,
5054
[ComponentSizeType.xs]: 16,
5155
[ComponentSizeType.small]: 16,

src/Shared/Components/Icon/Icon.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// NOTE: This file is auto-generated. Do not edit directly. Run the script `npm run generate-icon` to update.
22

33
import { ReactComponent as ICAborted } from '@IconsV2/ic-aborted.svg'
4+
import { ReactComponent as ICAdd } from '@IconsV2/ic-add.svg'
45
import { ReactComponent as ICAppGroup } from '@IconsV2/ic-app-group.svg'
56
import { ReactComponent as ICArrowRight } from '@IconsV2/ic-arrow-right.svg'
67
import { ReactComponent as ICAzure } from '@IconsV2/ic-azure.svg'
@@ -18,6 +19,7 @@ import { ReactComponent as ICCode } from '@IconsV2/ic-code.svg'
1819
import { ReactComponent as ICContainer } from '@IconsV2/ic-container.svg'
1920
import { ReactComponent as ICCrown } from '@IconsV2/ic-crown.svg'
2021
import { ReactComponent as ICCube } from '@IconsV2/ic-cube.svg'
22+
import { ReactComponent as ICDelete } from '@IconsV2/ic-delete.svg'
2123
import { ReactComponent as ICDockerhub } from '@IconsV2/ic-dockerhub.svg'
2224
import { ReactComponent as ICEcr } from '@IconsV2/ic-ecr.svg'
2325
import { ReactComponent as ICEnv } from '@IconsV2/ic-env.svg'
@@ -72,6 +74,7 @@ import { IconBaseProps } from './types'
7274

7375
export const iconMap = {
7476
'ic-aborted': ICAborted,
77+
'ic-add': ICAdd,
7578
'ic-app-group': ICAppGroup,
7679
'ic-arrow-right': ICArrowRight,
7780
'ic-azure': ICAzure,
@@ -89,6 +92,7 @@ export const iconMap = {
8992
'ic-container': ICContainer,
9093
'ic-crown': ICCrown,
9194
'ic-cube': ICCube,
95+
'ic-delete': ICDelete,
9296
'ic-dockerhub': ICDockerhub,
9397
'ic-ecr': ICEcr,
9498
'ic-env': ICEnv,

src/Shared/constants.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ export const ANSI_UP_REGEX = /\x1B\[.*?m/g
424424
* Size variants for components
425425
*/
426426
export enum ComponentSizeType {
427+
xxs_small_icon = 'xxs-small-icon',
427428
xxs = 'xxs',
428429
xs = 'xs',
429430
small = 'small',
@@ -433,6 +434,7 @@ export enum ComponentSizeType {
433434
}
434435

435436
export const COMPONENT_SIZE_TYPE_TO_FONT_AND_BLOCK_PADDING_MAP: Record<ComponentSizeType, string> = {
437+
[ComponentSizeType.xxs_small_icon]: 'py-1 fs-12 lh-20',
436438
[ComponentSizeType.xxs]: 'py-1 fs-12 lh-20',
437439
[ComponentSizeType.xs]: 'py-1 fs-12 lh-20',
438440
[ComponentSizeType.small]: 'py-3 fs-12 lh-20',
@@ -442,6 +444,7 @@ export const COMPONENT_SIZE_TYPE_TO_FONT_AND_BLOCK_PADDING_MAP: Record<Component
442444
} as const
443445

444446
export const COMPONENT_SIZE_TYPE_TO_INLINE_PADDING_MAP: Record<ComponentSizeType, string> = {
447+
[ComponentSizeType.xxs_small_icon]: 'px-4',
445448
[ComponentSizeType.xxs]: 'px-5',
446449
[ComponentSizeType.xs]: 'px-5',
447450
[ComponentSizeType.small]: 'px-5',
@@ -451,6 +454,7 @@ export const COMPONENT_SIZE_TYPE_TO_INLINE_PADDING_MAP: Record<ComponentSizeType
451454
} as const
452455

453456
export const COMPONENT_SIZE_TYPE_TO_ICON_SIZE_MAP: Record<ComponentSizeType, number> = {
457+
[ComponentSizeType.xxs_small_icon]: 12,
454458
[ComponentSizeType.xxs]: 14,
455459
[ComponentSizeType.xs]: 14,
456460
[ComponentSizeType.small]: 16,
@@ -515,3 +519,14 @@ export const DC_DELETE_SUBTITLES = {
515519
DELETE_ENVIRONMENT_SUBTITLE: 'Are you sure you want to delete this environment?',
516520
DELETE_CLUSTER_SUBTITLES: 'Are you sure you want to delete this cluster?',
517521
}
522+
523+
export const enum DeleteComponentsName {
524+
Cluster = 'cluster',
525+
Job = 'job pipeline',
526+
BuildPipeline = 'build pipeline',
527+
}
528+
529+
export const Routes = {
530+
CI_PIPELINE_PATCH: 'app/ci-pipeline/patch',
531+
WORKFLOW: 'app/app-wf',
532+
}

0 commit comments

Comments
 (0)