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,28 +77,44 @@ const useNewPipelineModal = () => {
validateOnChange validateOnChange
validateOnBlur validateOnBlur
onSubmit={handleCreatePipeline}> onSubmit={handleCreatePipeline}>
<FormikForm> {formik => {
<Layout.Vertical spacing="small"> return (
<Layout.Vertical spacing="small"> <FormikForm>
<FormInput.Text <Layout.Vertical spacing="small">
name="name" <Layout.Vertical spacing="small">
label={getString('name')} <FormInput.Text
placeholder={getString('pipelines.enterPipelineName')} name="name"
inputGroup={{ autoFocus: true }} label={getString('name')}
/> placeholder={getString('pipelines.enterPipelineName')}
<FormInput.Text name="branch" label={getString('pipelines.basedOn')} /> inputGroup={{ autoFocus: true }}
<FormInput.Text onChange={event => {
name="yamlPath" const input = (event.target as HTMLInputElement)?.value
label={getString('pipelines.yamlPath')} formik?.setFieldValue('name', input)
placeholder={getString('pipelines.enterYAMLPath')} if (input) {
/> // Keeping minimal validation for now, this could be much more exhaustive
</Layout.Vertical> const path = input.trim().replace(/\s/g, '')
<Layout.Horizontal spacing="medium" width="100%"> formik?.setFieldValue(
<Button variation={ButtonVariation.PRIMARY} text={getString('create')} type="submit" /> 'yamlPath',
<Button variation={ButtonVariation.SECONDARY} text={getString('cancel')} onClick={onClose} /> DEFAULT_YAML_PATH_PREFIX.concat(path).concat(DEFAULT_YAML_PATH_SUFFIX)
</Layout.Horizontal> )
</Layout.Vertical> }
</FormikForm> }}
/>
<FormInput.Text name="branch" label={getString('pipelines.basedOn')} />
<FormInput.Text
name="yamlPath"
label={getString('pipelines.yamlPath')}
placeholder={getString('pipelines.enterYAMLPath')}
/>
</Layout.Vertical>
<Layout.Horizontal spacing="medium" width="100%">
<Button variation={ButtonVariation.PRIMARY} text={getString('create')} type="submit" />
<Button variation={ButtonVariation.SECONDARY} text={getString('cancel')} onClick={onClose} />
</Layout.Horizontal>
</Layout.Vertical>
</FormikForm>
)
}}
</Formik> </Formik>
</Dialog> </Dialog>
) )