Skip to content

Commit

Permalink
Impl [Projects] Provide validation rules on labels
Browse files Browse the repository at this point in the history
  • Loading branch information
mavdryk committed Nov 9, 2023
1 parent 34a418f commit 5479b2f
Show file tree
Hide file tree
Showing 16 changed files with 107 additions and 216 deletions.
14 changes: 0 additions & 14 deletions src/actions/projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,10 @@ import {
FETCH_PROJECTS_BEGIN,
FETCH_PROJECTS_FAILURE,
FETCH_PROJECTS_SUCCESS,
REMOVE_NEW_PROJECT,
REMOVE_NEW_PROJECT_ERROR,
REMOVE_PROJECT_SUMMARY,
REMOVE_PROJECT_DATA,
REMOVE_PROJECTS,
SET_NEW_PROJECT_DESCRIPTION,
SET_NEW_PROJECT_LABELS,
SET_NEW_PROJECT_NAME,
SET_PROJECT_DATA,
SET_PROJECT_LABELS,
FETCH_PROJECTS_NAMES_BEGIN,
Expand Down Expand Up @@ -587,20 +583,10 @@ const projectsAction = {
type: FETCH_PROJECT_WORKFLOWS_SUCCESS,
payload: workflows
}),
removeNewProject: () => ({ type: REMOVE_NEW_PROJECT }),
removeNewProjectError: () => ({ type: REMOVE_NEW_PROJECT_ERROR }),
removeProjectData: () => ({ type: REMOVE_PROJECT_DATA }),
removeProjectSummary: () => ({ type: REMOVE_PROJECT_SUMMARY }),
removeProjects: () => ({ type: REMOVE_PROJECTS }),
setNewProjectDescription: description => ({
type: SET_NEW_PROJECT_DESCRIPTION,
payload: description
}),
setNewProjectLabels: (label, labels) => ({
type: SET_NEW_PROJECT_LABELS,
payload: { ...labels, ...label }
}),
setNewProjectName: name => ({ type: SET_NEW_PROJECT_NAME, payload: name }),
setProjectData: data => ({
type: SET_PROJECT_DATA,
payload: data
Expand Down
2 changes: 1 addition & 1 deletion src/components/Details/details.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export const generateArtifactsContent = (detailsType, selectedItem, projectName)
name: 'common.tag',
additionalRules: {
name: 'tagUniqueness',
label: 'Artifact tag should be unique',
label: 'Artifact tag must be unique',
pattern: isArtifactTagUnique(projectName, detailsType, selectedItem),
async: true
}
Expand Down
162 changes: 85 additions & 77 deletions src/components/ProjectsPage/CreateProjectDialog/CreateProjectDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,41 @@ under the Apache 2.0 license is conditioned upon your compliance with
such restriction.
*/
import React from 'react'
import { useSelector } from 'react-redux'
import PropTypes from 'prop-types'
import arrayMutators from 'final-form-arrays'
import { Form } from 'react-final-form'
import { useSelector } from 'react-redux'

import ErrorMessage from '../../../common/ErrorMessage/ErrorMessage'
import Input from '../../../common/Input/Input'
import Loader from '../../../common/Loader/Loader'
import ProjectLabels from '../../Project/ProjectLabels/ProjectLabels'
import { Button, PopUpDialog } from 'igz-controls/components'
import { Button, FormChipCell, FormInput, FormTextarea, PopUpDialog } from 'igz-controls/components'

import { getValidationRules } from 'igz-controls/utils/validation.util'
import { SECONDARY_BUTTON, TERTIARY_BUTTON } from 'igz-controls/constants'
import { createForm } from 'final-form'
import { getChipOptions } from '../../../utils/getChipOptions'
import { getValidationRules } from 'igz-controls/utils/validation.util'
import { setFieldState } from 'igz-controls/utils/form.util'

import './createProjectDialog.scss'

const CreateProjectDialog = ({
closeNewProjectPopUp,
handleCreateProject,
isNameValid,
removeNewProjectError,
setNameValid,
setNewProjectDescription,
setNewProjectLabels,
setNewProjectName
removeNewProjectError
}) => {
const projectStore = useSelector(store => store.projectStore)
const initialValues = {
name: '',
description: '',
labels: []
}
const formRef = React.useRef(
createForm({
initialValues,
mutators: { ...arrayMutators, setFieldState },
onSubmit: () => {}
})
)

return (
<PopUpDialog
Expand All @@ -51,79 +61,77 @@ const CreateProjectDialog = ({
closePopUp={closeNewProjectPopUp}
>
{projectStore.loading && <Loader />}
<form noValidate>
<div className="pop-up-dialog__form">
<Input
className="pop-up-dialog__form-input"
floatingLabel
invalid={!isNameValid}
invalidText="This field is invalid"
label="Name"
onChange={setNewProjectName}
required
setInvalid={value => setNameValid(value)}
type="text"
value={projectStore.newProject.name}
validationRules={getValidationRules('project.name')}
/>
<Input
className="pop-up-dialog__form-input"
floatingLabel
label="Description"
onChange={setNewProjectDescription}
type="text"
value={projectStore.newProject.description}
/>
<div>
<span>Labels:</span>
<ProjectLabels
addProjectLabel={setNewProjectLabels}
isEditMode
labels={projectStore.newProject.labels}
updateProjectLabel={setNewProjectLabels}
visibleChipsMaxLength="all"
/>
</div>
</div>
{projectStore.newProject.error && (
<ErrorMessage
closeError={() => {
if (projectStore.newProject.error) {
removeNewProjectError()
}
}}
message={projectStore.newProject.error}
/>
)}
<div className="pop-up-dialog__footer-container">
<Button
type="button"
disabled={projectStore.loading}
variant={TERTIARY_BUTTON}
label="Cancel"
className="pop-up-dialog__btn_cancel"
onClick={closeNewProjectPopUp}
/>
<Button
disabled={projectStore.loading || !isNameValid || !projectStore.newProject.name}
variant={SECONDARY_BUTTON}
label="Create"
onClick={handleCreateProject}
/>
</div>
</form>
<Form form={formRef.current} onSubmit={() => {}}>
{formState => {
return (
<>
<div className="form-row">
<FormInput
label="Name"
name="name"
required
validationRules={getValidationRules('project.name')}
/>
</div>
<div className="form-row">
<FormTextarea name="description" label="Description" maxLength={500} />
</div>
<div className="form-row">
<FormChipCell
chipOptions={getChipOptions('metrics')}
formState={formState}
initialValues={initialValues}
isEditable
label="Labels"
name="labels"
shortChips
visibleChipsMaxLength="2"
validationRules={{
key: getValidationRules('common.tag'),
value: getValidationRules('common.tag')
}}
/>
</div>
{projectStore.newProject.error && (
<div className="form-row">
<ErrorMessage
closeError={() => {
if (projectStore.newProject.error) {
removeNewProjectError()
}
}}
message={projectStore.newProject.error}
/>
</div>
)}
<div className="pop-up-dialog__footer-container">
<Button
type="button"
disabled={projectStore.loading}
variant={TERTIARY_BUTTON}
label="Cancel"
className="pop-up-dialog__btn_cancel"
onClick={closeNewProjectPopUp}
/>
<Button
disabled={projectStore.loading || !formState.values.name || formState.invalid}
variant={SECONDARY_BUTTON}
label="Create"
onClick={(event) => handleCreateProject(event, formState)}
/>
</div>
</>
)
}}
</Form>
</PopUpDialog>
)
}

CreateProjectDialog.propTypes = {
closeNewProjectPopUp: PropTypes.func.isRequired,
handleCreateProject: PropTypes.func.isRequired,
isNameValid: PropTypes.bool.isRequired,
removeNewProjectError: PropTypes.func.isRequired,
setNameValid: PropTypes.func.isRequired,
setNewProjectDescription: PropTypes.func.isRequired,
setNewProjectName: PropTypes.func.isRequired
removeNewProjectError: PropTypes.func.isRequired
}

export default CreateProjectDialog
Original file line number Diff line number Diff line change
@@ -1,27 +1,5 @@
.create-project-dialog {
.pop-up-dialog {
&__footer-container {
align-items: center;
}

&__form {
margin-bottom: 20px;
}

.input-wrapper {
margin-bottom: 10px;

&:last-child {
margin-bottom: 0;
}
}

.chips-wrapper {
flex-wrap: wrap;
}
}

.error-message {
max-width: 235px;
.error {
width: 100%;
}
}
37 changes: 10 additions & 27 deletions src/components/ProjectsPage/Projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,8 @@ const Projects = ({
fetchProjectsNames,
fetchProjectsSummary,
projectStore,
removeNewProject,
removeNewProjectError,
removeProjects,
setNewProjectDescription,
setNewProjectLabels,
setNewProjectName
removeProjects
}) => {
const [actionsMenu, setActionsMenu] = useState({})
const [confirmData, setConfirmData] = useState(null)
Expand All @@ -66,7 +62,6 @@ const Projects = ({
const [filterByName, setFilterByName] = useState('')
const [filterMatches, setFilterMatches] = useState([])
const [isDescendingOrder, setIsDescendingOrder] = useState(false)
const [isNameValid, setNameValid] = useState(true)
const [selectedProjectsState, setSelectedProjectsState] = useState('active')
const [sortProjectId, setSortProjectId] = useState('byName')
const [source] = useState(axios.CancelToken.source())
Expand Down Expand Up @@ -356,34 +351,27 @@ const Projects = ({
removeNewProjectError()
}

removeNewProject()
setNameValid(true)
setCreateProject(false)
}, [projectStore.newProject.error, removeNewProject, removeNewProjectError])
}, [projectStore.newProject.error, removeNewProjectError])

const handleCreateProject = e => {
const handleCreateProject = (e, formState) => {
e.preventDefault()

if (e.currentTarget.checkValidity()) {
if (projectStore.newProject.name.length === 0) {
setNameValid(false)
return false
} else if (isNameValid) {
setNameValid(true)
}

if (e.currentTarget.checkValidity() && formState.valid) {
createNewProject({
metadata: {
name: projectStore.newProject.name,
labels: projectStore.newProject.labels
name: formState.values.name,
labels: formState.values.labels?.reduce((acc, labelData) => {
acc[labelData.key] = labelData.value
return acc
}, {}) ?? {}
},
spec: {
description: projectStore.newProject.description
description: formState.values.description
}
}).then(result => {
if (result) {
setCreateProject(false)
removeNewProject()
refreshProjects()
fetchProjectsNames()
}
Expand All @@ -406,7 +394,6 @@ const Projects = ({
handleSelectSortOption={handleSelectSortOption}
handleSearchOnFocus={handleSearchOnFocus}
isDescendingOrder={isDescendingOrder}
isNameValid={isNameValid}
projectStore={projectStore}
refreshProjects={refreshProjects}
removeNewProjectError={removeNewProjectError}
Expand All @@ -415,10 +402,6 @@ const Projects = ({
setFilterByName={setFilterByName}
setFilterMatches={setFilterMatches}
setIsDescendingOrder={setIsDescendingOrder}
setNameValid={setNameValid}
setNewProjectDescription={setNewProjectDescription}
setNewProjectName={setNewProjectName}
setNewProjectLabels={setNewProjectLabels}
setSelectedProjectsState={setSelectedProjectsState}
sortProjectId={sortProjectId}
urlParams={urlParams}
Expand Down
Loading

0 comments on commit 5479b2f

Please sign in to comment.