Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions frontend/common/services/useReleasePipelines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ export const releasePipelinesService = service
url: `projects/${query.projectId}/release-pipelines/${query.pipelineId}/add-feature/`,
}),
}),
cloneReleasePipeline: builder.mutation<
Comment thread
tiagoapolo marked this conversation as resolved.
Res['releasePipeline'],
Req['cloneReleasePipeline']
>({
invalidatesTags: [{ id: 'LIST', type: 'ReleasePipelines' }],
query: (query: Req['cloneReleasePipeline']) => ({
body: {
name: query.name,
},
method: 'POST',
url: `projects/${query.projectId}/release-pipelines/${query.pipelineId}/clone/`,
}),
}),
createReleasePipeline: builder.mutation<
Res['releasePipeline'],
Req['createReleasePipeline']
Expand Down Expand Up @@ -168,6 +181,7 @@ export async function removeFeatureFromReleasePipeline(

export const {
useAddFeatureToReleasePipelineMutation,
useCloneReleasePipelineMutation,
useCreateReleasePipelineMutation,
useDeleteReleasePipelineMutation,
useGetReleasePipelineQuery,
Expand Down
5 changes: 5 additions & 0 deletions frontend/common/types/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -741,5 +741,10 @@ export type Req = {
pipelineId: number
featureId: number
}
cloneReleasePipeline: {
projectId: number
pipelineId: number
name: string
}
// END OF TYPES
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { useEffect, useState } from 'react'
import { useCloneReleasePipelineMutation } from 'common/services/useReleasePipelines'
import Utils from 'common/utils/utils'
import Button from 'components/base/forms/Button'
import InputGroup from 'components/base/forms/InputGroup'

type CloneReleasePipelineModalProps = {
projectId: number
pipelineId: number
}

const CloneReleasePipelineModal = ({
pipelineId,
projectId,
}: CloneReleasePipelineModalProps) => {
const [name, setName] = useState<string>('')

const [
cloneReleasePipeline,
{
error: cloneReleasePipelineError,
isError: isCloningError,
isLoading: isCloning,
isSuccess: isCloningSuccess,
},
] = useCloneReleasePipelineMutation()

useEffect(() => {
if (isCloningSuccess) {
closeModal2()
toast('Release pipeline cloned successfully')
return
}

if (isCloningError) {
toast(
cloneReleasePipelineError?.data?.detail ??
'Error cloning release pipeline',
'danger',
)
return
}
}, [isCloningSuccess, isCloningError, cloneReleasePipelineError])

return (
<div className='p-4'>
<InputGroup
title='New Release Pipeline Name'
inputProps={{
className: 'full-width',
error: !name,
name: 'name',
}}
value={name}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setName(Utils.safeParseEventValue(event))
}}
isValid={name && name.length}
type='text'
name='name'
id='name'
placeholder='E.g. Beta Release'
/>
<div className='text-right mt-4'>
<Button
theme='secondary'
className='mr-2'
onClick={() => closeModal2()}
>
Cancel
</Button>
<Button
onClick={() => cloneReleasePipeline({ name, pipelineId, projectId })}
disabled={isCloning || !name}
>
Clone
</Button>
</div>
</div>
)
}

export type { CloneReleasePipelineModalProps }
export default CloneReleasePipelineModal
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import PanelSearch from 'components/PanelSearch'
import Tag from 'components/tags/Tag'
import { useEffect } from 'react'
import ChangeReleasePipelineStatusModal from './ChangeReleasePipelineStatusModal'
import CloneReleasePipelineModal from './CloneReleasePipelineModal'

const NoReleasePipelines = ({ projectId }: { projectId: number }) => {
const history = useHistory()
Expand Down Expand Up @@ -87,7 +88,12 @@ const ReleasePipelinesList = ({
'danger',
)
}
}, [isDeletingSuccess, isDeletingError, deleteReleasePipelineError])

}, [
isDeletingSuccess,
isDeletingError,
deleteReleasePipelineError,
])

const openChangeReleasePipelineStatusModal = (
projectId: number,
Expand Down Expand Up @@ -208,6 +214,18 @@ const ReleasePipelinesList = ({
? 'Cannot unpublish a release pipeline with in-flight features'
: undefined,
},
{
icon: 'copy' as IconName,
label: 'Clone',
onClick: () =>
openModal2(
'Clone Release Pipeline',
<CloneReleasePipelineModal
pipelineId={id}
projectId={Number(projectId)}
/>,
),
},
{
disabled: isDeleting || isPublished,
icon: 'trash-2',
Expand Down
Loading