-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: create app revamp and support for templates #2451
Merged
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
d833c25
feat: add form state for create app modal
eshankvaish fc50923
fix: overflow issue
eshankvaish 0b01f25
feat: add support for creation method
eshankvaish 4d3908f
feat: add tags and form validation
eshankvaish c027f1f
refactor: code clean up and component breakdown
eshankvaish 04a37f3
refactor: remove old create app modal file
eshankvaish e046391
refactor: common out the method for validation
eshankvaish d9664ec
feat: add clone app
eshankvaish 5d92eaf
fix: checks for job
eshankvaish 02c7c07
fix: width for project selector
eshankvaish d2e84de
fix: check for isJobView
eshankvaish bca23a2
fix: styling issues
eshankvaish c0aafee
feat: add feature flag for application templates
eshankvaish 5b9da07
feat: add section for code source and build config
eshankvaish 4a33084
fix: description margin
eshankvaish 94c6f94
feat: add material list
eshankvaish 5ce51de
feat: add build configuration
eshankvaish 7a5aad2
feat: integration for build config state
eshankvaish 34ee6c7
feat: hide templates based on flag
eshankvaish c453548
feat: sync state for git materials
eshankvaish 005ad20
fix: race condition for form state
eshankvaish cf41038
feat: add icons for create app modal
eshankvaish 1ad78da
feat: add handler for workflow config change
eshankvaish 79007d9
feat: add payload for creation method
eshankvaish e3f6129
fix: typing for MaterialList component
eshankvaish 165e644
refactor: code clean up
eshankvaish 32604fd
refactor: migrate the CreateAppModal to Pages/App
eshankvaish 56305f0
refactor: remove unused code
eshankvaish 764a3d3
Merge branch 'feature/application-template' of github.com:devtron-lab…
eshankvaish 5a5c3b8
feat: api integration
eshankvaish File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import AsyncSelect from 'react-select/async' | ||
import { multiSelectStyles } from '@devtron-labs/devtron-fe-common-lib' | ||
import { appListOptions, noOptionsMessage } from '@Components/AppSelector/AppSelectorUtil' | ||
import { Option } from '@Components/v2/common/ReactSelect.utils' | ||
import { ReactComponent as ICError } from '@Icons/ic-warning.svg' | ||
import { ReactComponent as ICInfoFilled } from '@Icons/ic-info-filled.svg' | ||
import { AppToCloneSelectorProps } from './types' | ||
|
||
const _multiSelectStyles = { | ||
...multiSelectStyles, | ||
control: (base, state) => ({ | ||
...multiSelectStyles.control(base, state), | ||
cursor: 'pointer', | ||
}), | ||
menu: (base, state) => ({ | ||
...multiSelectStyles.menu(base, state), | ||
marginTop: 'auto', | ||
}), | ||
menuList: (base) => ({ | ||
...base, | ||
position: 'relative', | ||
paddingBottom: '0px', | ||
maxHeight: '180px', | ||
}), | ||
} | ||
|
||
const AppToCloneSelector = ({ isJobView, error, handleCloneIdChange }: AppToCloneSelectorProps) => { | ||
const loadAppListOptions = (inputValue: string) => appListOptions(inputValue, isJobView) | ||
|
||
const onChange = (selectedClonedApp) => { | ||
handleCloneIdChange(selectedClonedApp.value) | ||
} | ||
|
||
return ( | ||
<> | ||
<div> | ||
<span | ||
className="form__label dc__required-field" | ||
data-testid={`Clone-${isJobView ? 'job' : 'app'}-option`} | ||
> | ||
Select an {isJobView ? 'job' : 'app'} to clone | ||
</span> | ||
<AsyncSelect | ||
classNamePrefix={`${isJobView ? 'job' : 'app'}-name-for-clone`} | ||
loadOptions={loadAppListOptions} | ||
noOptionsMessage={noOptionsMessage} | ||
onChange={onChange} | ||
styles={_multiSelectStyles} | ||
components={{ | ||
IndicatorSeparator: null, | ||
LoadingIndicator: null, | ||
Option, | ||
}} | ||
placeholder={`Select ${isJobView ? 'job' : 'app'}`} | ||
/> | ||
{error && ( | ||
<span className="form__error"> | ||
<ICError className="form__icon form__icon--error" /> | ||
{error} | ||
</span> | ||
)} | ||
</div> | ||
<div className="dc__info-container info-container--create-app eb-2 mb-16"> | ||
<ICInfoFilled /> | ||
<div className="flex column left"> | ||
<div> | ||
<div className="dc__info-title">Important: </div> | ||
{isJobView | ||
? 'Do not forget to modify git repositories and corresponding branches to be used for each Job Pipeline if required.' | ||
: 'Do not forget to modify git repositories, corresponding branches and container registries to be used for each CI Pipeline if required.'} | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
) | ||
} | ||
|
||
export default AppToCloneSelector |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import { CustomInput, ResizableTextarea, TagsContainer } from '@devtron-labs/devtron-fe-common-lib' | ||
import { ReactComponent as ICDevtronApp } from '@Icons/ic-devtron-app.svg' | ||
import { ReactComponent as ICCaretLeftSmall } from '@Icons/ic-caret-left-small.svg' | ||
import { ChangeEvent, useState } from 'react' | ||
import { importComponentFromFELibrary } from '@Components/common' | ||
import { APP_TYPE } from '@Config/constants' | ||
import { ReactComponent as ICError } from '@Icons/ic-warning.svg' | ||
import ProjectSelector from './ProjectSelector' | ||
import { | ||
ApplicationInfoFormProps, | ||
CreateAppFormStateActionType, | ||
CreateAppFormStateType, | ||
CreationMethodType, | ||
HandleFormStateChangeParamsType, | ||
ProjectSelectorProps, | ||
} from './types' | ||
import AppToCloneSelector from './AppToCloneSelector' | ||
|
||
const MandatoryTagsContainer = importComponentFromFELibrary('MandatoryTagsContainer', null, 'function') | ||
|
||
const ApplicationInfoForm = ({ | ||
formState, | ||
handleFormStateChange, | ||
isJobView, | ||
formErrorState, | ||
handleTagErrorChange, | ||
selectedCreationMethod, | ||
}: ApplicationInfoFormProps) => { | ||
const [isTagsAccordionExpanded, setIsTagsAccordionExpanded] = useState(false) | ||
|
||
const toggleIsTagsAccordionExpanded = () => { | ||
setIsTagsAccordionExpanded((prev) => !prev) | ||
} | ||
|
||
const handleInputChange = | ||
( | ||
action: Extract< | ||
HandleFormStateChangeParamsType['action'], | ||
CreateAppFormStateActionType.updateName | CreateAppFormStateActionType.updateDescription | ||
>, | ||
) => | ||
(event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => { | ||
handleFormStateChange({ action, value: event.target.value }) | ||
} | ||
|
||
const handleProjectIdChange: ProjectSelectorProps['handleProjectIdChange'] = (projectId) => { | ||
handleFormStateChange({ | ||
action: CreateAppFormStateActionType.updateProjectId, | ||
value: projectId, | ||
}) | ||
} | ||
|
||
const handleTagsUpdate = (tags: CreateAppFormStateType['tags']) => { | ||
handleFormStateChange({ | ||
action: CreateAppFormStateActionType.updateTags, | ||
value: tags, | ||
}) | ||
} | ||
|
||
const handleCloneIdChange = (cloneId) => { | ||
handleFormStateChange({ | ||
action: CreateAppFormStateActionType.updateCloneAppId, | ||
value: cloneId, | ||
}) | ||
} | ||
|
||
return ( | ||
<div className="flexbox-col dc__gap-16 p-20 br-8 border__secondary bg__primary"> | ||
<ICDevtronApp className="icon-dim-48 dc__no-shrink" /> | ||
<div className="flexbox dc__gap-8"> | ||
<ProjectSelector | ||
selectedProjectId={formState.projectId} | ||
handleProjectIdChange={handleProjectIdChange} | ||
error={formErrorState.projectId} | ||
/> | ||
<span className="pt-26 fs-20 lh-36 cn-7 dc__no-shrink">/</span> | ||
<CustomInput | ||
label={isJobView ? 'Job name' : 'Application name'} | ||
isRequiredField | ||
required | ||
rootClassName="h-36" | ||
name="name" | ||
onChange={handleInputChange(CreateAppFormStateActionType.updateName)} | ||
value={formState.name} | ||
placeholder="Enter name" | ||
inputWrapClassName="w-100" | ||
error={formErrorState.name} | ||
helperText={ | ||
!isJobView && 'Apps are NOT env specific and can be used to deploy to multiple environments.' | ||
} | ||
/> | ||
</div> | ||
<div> | ||
<span className="form__label">Description</span> | ||
<ResizableTextarea | ||
name="description" | ||
value={formState.description} | ||
onChange={handleInputChange(CreateAppFormStateActionType.updateDescription)} | ||
placeholder={isJobView ? 'Describe this job' : 'Write a description for this application'} | ||
className="w-100" | ||
/> | ||
{formErrorState.description ? ( | ||
<span className="form__error"> | ||
<ICError className="form__icon form__icon--error" /> | ||
{formErrorState.description} <br /> | ||
</span> | ||
) : null} | ||
</div> | ||
<div className="flexbox-col dc__gap-16"> | ||
<button | ||
className="dc__transparent p-0 flex left dc__gap-8 dc__w-fit-content" | ||
type="button" | ||
onClick={toggleIsTagsAccordionExpanded} | ||
> | ||
<ICCaretLeftSmall | ||
className={`scn-7 dc__no-shrink dc__transition--transform ${isTagsAccordionExpanded ? 'dc__flip-270' : 'dc__flip-180'}`} | ||
/> | ||
<span className="fs-13 fw-6 lh-20 cn-9">Add tags to {isJobView ? 'job' : 'application'}</span> | ||
</button> | ||
{isTagsAccordionExpanded && | ||
(MandatoryTagsContainer ? ( | ||
<MandatoryTagsContainer | ||
isCreateApp | ||
appType={isJobView ? APP_TYPE.JOB : APP_TYPE.DEVTRON_APPS} | ||
projectId={formState.projectId} | ||
tags={formState.tags} | ||
setTags={handleTagsUpdate} | ||
tagsError={formErrorState.tags} | ||
setTagErrors={handleTagErrorChange} | ||
/> | ||
) : ( | ||
<TagsContainer | ||
appType={isJobView ? APP_TYPE.JOB : APP_TYPE.DEVTRON_APPS} | ||
isCreateApp | ||
rows={formState.tags} | ||
setRows={handleTagsUpdate} | ||
tagsError={formErrorState.tags} | ||
setTagErrors={handleTagErrorChange} | ||
/> | ||
))} | ||
</div> | ||
{selectedCreationMethod === CreationMethodType.clone && ( | ||
<AppToCloneSelector | ||
error={formErrorState.cloneAppId} | ||
isJobView={isJobView} | ||
handleCloneIdChange={handleCloneIdChange} | ||
/> | ||
)} | ||
</div> | ||
) | ||
} | ||
|
||
export default ApplicationInfoForm |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is moved from CreateApp