fix some corner cases

This commit is contained in:
Vardan Bansal 2023-09-11 15:13:05 -07:00
parent 37bfe73da8
commit ed4faeb8d7
3 changed files with 82 additions and 60 deletions

View File

@ -126,7 +126,7 @@ const AddUpdatePipeline = (): JSX.Element => {
const { const {
data: pipelineYAMLFileContent, data: pipelineYAMLFileContent,
loading: resourceLoading, loading: fetchingPipelineYAMLFileContent,
refetch: fetchPipelineYAMLFileContent refetch: fetchPipelineYAMLFileContent
} = useGetResourceContent({ } = useGetResourceContent({
repoMetadata, repoMetadata,
@ -134,39 +134,38 @@ const AddUpdatePipeline = (): JSX.Element => {
resourcePath: pipelineData?.config_path || '' resourcePath: pipelineData?.config_path || ''
}) })
// check if file exists and has some content const originalPipelineYAMLFileContent = useMemo(
useEffect(() => { (): string => decodeGitContent((pipelineYAMLFileContent?.content as RepoFileContent)?.data),
if (!resourceLoading) { [pipelineYAMLFileContent?.content]
setIsExistingPipeline(!isEmpty(pipelineYAMLFileContent) && !isUndefined(pipelineYAMLFileContent.content)) )
}
}, [pipelineYAMLFileContent, resourceLoading])
// to load initial content on the editor // check if file already exists and has some content
useEffect(() => {
setIsExistingPipeline(!isEmpty(originalPipelineYAMLFileContent) && !isUndefined(originalPipelineYAMLFileContent))
}, [originalPipelineYAMLFileContent])
// load initial content on the editor
useEffect(() => { useEffect(() => {
if (isExistingPipeline) { if (isExistingPipeline) {
setPipelineAsYaml(decodeGitContent((pipelineYAMLFileContent?.content as RepoFileContent)?.data)) setPipelineAsYaml(originalPipelineYAMLFileContent)
} else { } else {
// load with starter pipeline
try { try {
setPipelineAsYaml(stringify(pipelineAsObj)) setPipelineAsYaml(stringify(pipelineAsObj))
} catch (ex) {} } catch (ex) {
// ignore exception
} }
}, [isExistingPipeline, pipelineYAMLFileContent]) }
}, [isExistingPipeline, originalPipelineYAMLFileContent, pipelineAsObj])
// find if editor content was modified // find if editor content was modified
useEffect(() => { useEffect(() => {
if (isExistingPipeline) { setIsDirty(originalPipelineYAMLFileContent !== pipelineAsYAML)
const originalContent = decodeGitContent((pipelineYAMLFileContent?.content as RepoFileContent)?.data) }, [originalPipelineYAMLFileContent, pipelineAsYAML])
setIsDirty(originalContent !== pipelineAsYAML)
} else {
setIsDirty(true)
}
}, [isExistingPipeline, pipelineAsYAML, pipelineYAMLFileContent])
// set initial CTA title
useEffect(() => { useEffect(() => {
if (isDirty) { setSelectedOption(isDirty ? pipelineSaveAndRunOption : pipelineRunOption)
// enable "Save" option if pipeline is edited
setSelectedOption(pipelineSaveOption)
}
}, [isDirty]) }, [isDirty])
const handleSaveAndRun = (option: PipelineSaveAndRunOption): void => { const handleSaveAndRun = (option: PipelineSaveAndRunOption): void => {
@ -191,6 +190,9 @@ const AddUpdatePipeline = (): JSX.Element => {
.then(() => { .then(() => {
fetchPipelineYAMLFileContent() fetchPipelineYAMLFileContent()
showSuccess(getString(isExistingPipeline ? 'pipelines.updated' : 'pipelines.created')) showSuccess(getString(isExistingPipeline ? 'pipelines.updated' : 'pipelines.created'))
if (option?.action === PipelineSaveAndRunAction.SAVE_AND_RUN && repoMetadata && pipeline) {
openRunPipelineModal({ repoMetadata, pipeline })
}
setSelectedOption(pipelineRunOption) setSelectedOption(pipelineRunOption)
}) })
.catch(error => { .catch(error => {
@ -225,17 +227,6 @@ const AddUpdatePipeline = (): JSX.Element => {
const renderCTA = useCallback(() => { const renderCTA = useCallback(() => {
switch (selectedOption?.action) { switch (selectedOption?.action) {
case PipelineSaveAndRunAction.SAVE:
return (
<Button
variation={ButtonVariation.PRIMARY}
text={getString('save')}
onClick={() => {
handleSaveAndRun(pipelineSaveOption)
}}
disabled={loading || !isDirty}
/>
)
case PipelineSaveAndRunAction.RUN: case PipelineSaveAndRunAction.RUN:
return ( return (
<Button <Button
@ -248,8 +239,18 @@ const AddUpdatePipeline = (): JSX.Element => {
}} }}
/> />
) )
case PipelineSaveAndRunAction.SAVE:
case PipelineSaveAndRunAction.SAVE_AND_RUN: case PipelineSaveAndRunAction.SAVE_AND_RUN:
return ( return isExistingPipeline ? (
<Button
variation={ButtonVariation.PRIMARY}
text={getString('save')}
onClick={() => {
handleSaveAndRun(pipelineSaveOption)
}}
disabled={loading || !isDirty}
/>
) : (
<SplitButton <SplitButton
text={selectedOption?.title} text={selectedOption?.title}
disabled={loading || !isDirty} disabled={loading || !isDirty}
@ -260,7 +261,8 @@ const AddUpdatePipeline = (): JSX.Element => {
position: PopoverPosition.BOTTOM_RIGHT, position: PopoverPosition.BOTTOM_RIGHT,
transitionDuration: 1000 transitionDuration: 1000
}} }}
intent="primary"> intent="primary"
onClick={() => handleSaveAndRun(selectedOption)}>
{pipelineSaveAndRunOptions.map(option => { {pipelineSaveAndRunOptions.map(option => {
return ( return (
<Menu.Item <Menu.Item
@ -271,7 +273,7 @@ const AddUpdatePipeline = (): JSX.Element => {
</Text> </Text>
} }
onClick={() => { onClick={() => {
handleSaveAndRun(option) setSelectedOption(option)
}} }}
/> />
) )
@ -281,7 +283,7 @@ const AddUpdatePipeline = (): JSX.Element => {
default: default:
return <></> return <></>
} }
}, [loading, fetchingPipeline, isDirty, repoMetadata, pipeline, selectedOption]) }, [loading, fetchingPipeline, isDirty, repoMetadata, pipeline, selectedOption, isExistingPipeline, pipelineAsYAML])
return ( return (
<> <>
@ -300,7 +302,7 @@ const AddUpdatePipeline = (): JSX.Element => {
content={<Layout.Horizontal flex={{ justifyContent: 'space-between' }}>{renderCTA()}</Layout.Horizontal>} content={<Layout.Horizontal flex={{ justifyContent: 'space-between' }}>{renderCTA()}</Layout.Horizontal>}
/> />
<PageBody> <PageBody>
<LoadingSpinner visible={fetchingPipeline} /> <LoadingSpinner visible={fetchingPipeline || fetchingPipelineYAMLFileContent} />
<Layout.Horizontal> <Layout.Horizontal>
<Container className={css.editorContainer}> <Container className={css.editorContainer}>
<MonacoSourceCodeEditor <MonacoSourceCodeEditor

View File

@ -2,3 +2,6 @@ export enum YamlVersion {
V0, V0,
V1 V1
} }
export const DEFAULT_YAML_PATH_PREFIX = '.harness/'
export const DEFAULT_YAML_PATH_SUFFIX = '.yaml'

View File

@ -8,6 +8,7 @@ import type { OpenapiCreatePipelineRequest, TypesPipeline, TypesRepository } fro
import { useStrings } from 'framework/strings' import { useStrings } from 'framework/strings'
import { useAppContext } from 'AppContext' import { useAppContext } from 'AppContext'
import { getErrorMessage } from 'utils/Utils' import { getErrorMessage } from 'utils/Utils'
import { DEFAULT_YAML_PATH_PREFIX, DEFAULT_YAML_PATH_SUFFIX } from './Constants'
interface FormData { interface FormData {
name: string name: string
@ -76,6 +77,8 @@ const useNewPipelineModal = () => {
validateOnChange validateOnChange
validateOnBlur validateOnBlur
onSubmit={handleCreatePipeline}> onSubmit={handleCreatePipeline}>
{formik => {
return (
<FormikForm> <FormikForm>
<Layout.Vertical spacing="small"> <Layout.Vertical spacing="small">
<Layout.Vertical spacing="small"> <Layout.Vertical spacing="small">
@ -84,6 +87,18 @@ const useNewPipelineModal = () => {
label={getString('name')} label={getString('name')}
placeholder={getString('pipelines.enterPipelineName')} placeholder={getString('pipelines.enterPipelineName')}
inputGroup={{ autoFocus: true }} inputGroup={{ autoFocus: true }}
onChange={event => {
const input = (event.target as HTMLInputElement)?.value
formik?.setFieldValue('name', input)
if (input) {
// Keeping minimal validation for now, this could be much more exhaustive
const path = input.trim().replace(/\s/g, '')
formik?.setFieldValue(
'yamlPath',
DEFAULT_YAML_PATH_PREFIX.concat(path).concat(DEFAULT_YAML_PATH_SUFFIX)
)
}
}}
/> />
<FormInput.Text name="branch" label={getString('pipelines.basedOn')} /> <FormInput.Text name="branch" label={getString('pipelines.basedOn')} />
<FormInput.Text <FormInput.Text
@ -98,6 +113,8 @@ const useNewPipelineModal = () => {
</Layout.Horizontal> </Layout.Horizontal>
</Layout.Vertical> </Layout.Vertical>
</FormikForm> </FormikForm>
)
}}
</Formik> </Formik>
</Dialog> </Dialog>
) )