-
-
{nom}
-
-
+
+
Chef de file
+ {hasChefDeFile ? (
+
+
+
-
+
+
+
+
+
-
-
-
+
+
+
+ {perimeters ? perimeters.map(p => (
+ - {p}
+ )) : 'Aucune périmètre n’est défini'}
+
+
-
-
-
-
-
- {perimeters ? perimeters.map(p => (
- - {p}
- )) : 'Aucune périmètre n’est défini'}
-
-
+ ) : (
+
+
+
+ Aucun chef de file
+
+
+
+ )}
)
}
/* eslint-disable react/boolean-prop-naming */
ChefDeFile.propTypes = {
- _id: PropTypes.string.isRequired,
- nom: PropTypes.string.isRequired,
- email: PropTypes.string.isRequired,
- perimetre: PropTypes.string.isRequired,
- signataireCharte: PropTypes.bool.isRequired
+ hasChefDeFile: PropTypes.bool,
+ _id: PropTypes.string,
+ nom: PropTypes.string,
+ email: PropTypes.string,
+ perimetre: PropTypes.array,
+ signataireCharte: PropTypes.bool
}
/* eslint-enable react/boolean-prop-naming */
diff --git a/components/api-depot/client-item.js b/components/api-depot/client-item.js
index d4b6f5d..493eac4 100644
--- a/components/api-depot/client-item.js
+++ b/components/api-depot/client-item.js
@@ -22,6 +22,17 @@ const ClientItem = ({_id, nom, mandataire, chefDeFile, authorizationStrategy, ac
|
+
+
+
+
+ |
{
const [isCreateFormOpen, setIsCreateFormOpen] = useState(false)
const chefsDeFileOptions = useMemo(() =>
- chefsDeFile.sort((a, b) => a.nom > b.nom).map(m => ({label: m.nom, value: m._id}))
+ chefsDeFile.sort((a, b) => a.nom > b.nom).map(m => ({label: m.nom + ' (' + m.email + ')', value: m._id}))
, [chefsDeFile])
const handleCreationForm = (event, isOpen) => {
event.preventDefault()
setIsCreateFormOpen(isOpen)
+ onSelect('')
}
useEffect(() => {
@@ -112,7 +113,10 @@ const ChefDeFileForm = ({selectedChefDeFile, chefsDeFile, onSelect}) => {
}
ChefDeFileForm.propTypes = {
- selectedChefDeFile: PropTypes.string,
+ selectedChefDeFile: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.object,
+ ]),
chefsDeFile: PropTypes.array.isRequired,
onSelect: PropTypes.func.isRequired
}
diff --git a/components/api-depot/client/client-form/chef-de-file-perimeter.js b/components/api-depot/client/client-form/chef-de-file-perimeter.js
index 3cbaba1..c4372e9 100644
--- a/components/api-depot/client/client-form/chef-de-file-perimeter.js
+++ b/components/api-depot/client/client-form/chef-de-file-perimeter.js
@@ -13,7 +13,6 @@ const ChefDeFilePerimeter = ({perimeters, handlePerimeter}) => {
const handleChange = useCallback((perimeter, key, idx) => {
const {type, code} = perimeter
-
const cpy = [...perimeters]
cpy[idx] = {type, code, key}
diff --git a/components/api-depot/client/client-form/mandataire-form.js b/components/api-depot/client/client-form/mandataire-form.js
index e34918c..82b1aa2 100644
--- a/components/api-depot/client/client-form/mandataire-form.js
+++ b/components/api-depot/client/client-form/mandataire-form.js
@@ -14,7 +14,7 @@ const MandataireForm = ({selectedMandataire, mandataires, onSelect}) => {
const [isCreateFormOpen, setIsCreateFormOpen] = useState(false)
const mandatairesOptions = useMemo(() =>
- mandataires.sort((a, b) => a.nom > b.nom).map(m => ({label: m.nom, value: m._id}))
+ mandataires.sort((a, b) => a.nom > b.nom).map(m => ({label: m.nom + ' (' + m.email + ')', value: m._id}))
, [mandataires])
const handleCreationForm = (event, isOpen) => {
@@ -92,7 +92,10 @@ const MandataireForm = ({selectedMandataire, mandataires, onSelect}) => {
}
MandataireForm.propTypes = {
- selectedMandataire: PropTypes.string,
+ selectedMandataire: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.object,
+ ]),
mandataires: PropTypes.array.isRequired,
onSelect: PropTypes.func.isRequired
}
diff --git a/components/api-depot/client/client-form/perimeter.js b/components/api-depot/client/client-form/perimeter.js
index 3735ad9..60ca44c 100644
--- a/components/api-depot/client/client-form/perimeter.js
+++ b/components/api-depot/client/client-form/perimeter.js
@@ -1,6 +1,11 @@
+import {useEffect, useState} from 'react'
+import {uniqueId} from 'lodash'
import PropTypes from 'prop-types'
-import Input from '@codegouvfr/react-dsfr/Input'
+import epcis from '@etalab/decoupage-administratif/data/epci.json'
+import departements from '@etalab/decoupage-administratif/data/departements.json'
+import allCommunes from '@etalab/decoupage-administratif/data/communes.json'
+import AutocompleteInput from '@/components/autocomplete-input'
import SelectInput from '@/components/select-input'
const typeOptions = [
@@ -9,25 +14,47 @@ const typeOptions = [
{label: 'Commune', value: 'commune'}
]
-const Perimeter = ({type, code, handlePerimeter}) => (
-
-
- handlePerimeter({type: v, code})}
- />
-
-
- handlePerimeter({type, code: e.target.value})}
- />
+const Perimeter = ({type, code, handlePerimeter}) => {
+ const [perimetreOptions, setPerimetreOptions] = useState([])
+
+ useEffect(() => {
+ let options = []
+ if (type === 'epci') {
+ options = epcis.map(({code, nom}) => ({value: code, label: nom}))
+ } else if (type === 'departement') {
+ options = departements.map(({code, nom}) => ({value: code, label: nom}))
+ } else if (type === 'commune') {
+ options = allCommunes
+ .filter(c => ['commune-actuelle', 'arrondissement-municipal'].includes(c.type))
+ .map(({code, nom}) => ({value: code, label: nom}))
+ }
+
+ setPerimetreOptions(options)
+ }, [type])
+
+ return (
+
+
+ handlePerimeter({type: v, code})}
+ />
+
+
+
+ handlePerimeter({type, code: e.target.value})}
+ />
+
-
-)
+ )
+}
Perimeter.propTypes = {
type: PropTypes.string.isRequired,
diff --git a/components/api-depot/client/client-header.js b/components/api-depot/client/client-header.js
index 38ff8b3..a07528b 100644
--- a/components/api-depot/client/client-header.js
+++ b/components/api-depot/client/client-header.js
@@ -1,23 +1,16 @@
import PropTypes from 'prop-types'
-import ToggleSwitch from '@codegouvfr/react-dsfr/ToggleSwitch'
import MongoId from '@/components/mongo-id'
-const ClientHeader = ({id, nom, isActive, isDisabled, onUpdate}) => (
-
-
-
- {nom}
-
-
-
-
- onUpdate({active: checked})}
- />
+const ClientHeader = ({id, nom}) => (
+
@@ -26,9 +19,6 @@ const ClientHeader = ({id, nom, isActive, isDisabled, onUpdate}) => (
ClientHeader.propTypes = {
id: PropTypes.string.isRequired,
nom: PropTypes.string.isRequired,
- isActive: PropTypes.bool.isRequired,
- isDisabled: PropTypes.bool.isRequired,
- onUpdate: PropTypes.func.isRequired
}
export default ClientHeader
diff --git a/components/api-depot/client/client-options.js b/components/api-depot/client/client-options.js
deleted file mode 100644
index 0369246..0000000
--- a/components/api-depot/client/client-options.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import PropTypes from 'prop-types'
-
-import ToggleSwitch from '@codegouvfr/react-dsfr/ToggleSwitch'
-
-const ClientOptions = ({isModeRelax, isDisabled, onUpdate}) => (
-
- Options
-
- onUpdate({options: {relaxMode: checked}})}
- />
-
-
-)
-
-ClientOptions.propTypes = {
- isModeRelax: PropTypes.bool.isRequired,
- isDisabled: PropTypes.bool.isRequired,
- onUpdate: PropTypes.func.isRequired
-}
-
-export default ClientOptions
diff --git a/components/api-depot/clients-list.js b/components/api-depot/clients-list.js
index 7cb62e6..4e485e2 100644
--- a/components/api-depot/clients-list.js
+++ b/components/api-depot/clients-list.js
@@ -54,7 +54,8 @@ const ClientsList = ({isDemo}) => {
Stratégie d’autorisation |
Activé |
Mode relax |
- |
+ Editer |
+ Consulter |
diff --git a/components/api-depot/mandataire.js b/components/api-depot/mandataire.js
index 7ce875c..60aabf2 100644
--- a/components/api-depot/mandataire.js
+++ b/components/api-depot/mandataire.js
@@ -3,14 +3,15 @@ import PropTypes from 'prop-types'
import MongoId from '@/components/mongo-id'
const Mandataire = ({_id, nom, email}) => (
-
-
-
- {nom}
-
-
-
- {email}
+
diff --git a/components/autocomplete-input.js b/components/autocomplete-input.js
new file mode 100644
index 0000000..9d7e7d9
--- /dev/null
+++ b/components/autocomplete-input.js
@@ -0,0 +1,48 @@
+import PropTypes from 'prop-types'
+
+const AutocompleteInput = ({id, label, value, hint, options, isDisabled, onChange}) => (
+
+
+
+ onChange(event)}
+ />
+
+
+)
+
+AutocompleteInput.defaultProps = {
+ value: '',
+ hint: null,
+ isDisabled: false
+}
+
+AutocompleteInput.propTypes = {
+ id: PropTypes.string.isRequired,
+ label: PropTypes.string.isRequired,
+ value: PropTypes.string,
+ hint: PropTypes.string,
+ options: PropTypes.array.isRequired,
+ isDisabled: PropTypes.bool,
+ onChange: PropTypes.func.isRequired
+}
+
+export default AutocompleteInput
diff --git a/components/text-input.js b/components/text-input.js
new file mode 100644
index 0000000..f070301
--- /dev/null
+++ b/components/text-input.js
@@ -0,0 +1,36 @@
+import PropTypes from 'prop-types'
+
+const TextInput = ({label, value, hint, isDisabled, onChange}) => (
+
+
+
+ onChange(event)}
+ />
+
+
+)
+
+TextInput.defaultProps = {
+ value: '',
+ hint: null,
+ isDisabled: false
+}
+
+TextInput.propTypes = {
+ label: PropTypes.string.isRequired,
+ value: PropTypes.string,
+ hint: PropTypes.string,
+ isDisabled: PropTypes.bool,
+ onChange: PropTypes.func.isRequired
+}
+
+export default TextInput
diff --git a/layouts/main.js b/layouts/main.js
index f9d9874..4086110 100644
--- a/layouts/main.js
+++ b/layouts/main.js
@@ -15,7 +15,6 @@ const Layout = ({isAdmin, children}) => (
-
{children}
@@ -34,9 +33,7 @@ const Layout = ({isAdmin, children}) => (
href: '#'
}}
/>
-
-
+ `}
>
)
diff --git a/pages/api-depot/client/client-form.js b/pages/api-depot/client/client-form.js
index 27fe0d4..b5c1468 100644
--- a/pages/api-depot/client/client-form.js
+++ b/pages/api-depot/client/client-form.js
@@ -1,12 +1,11 @@
import {useCallback, useEffect, useState} from 'react'
import PropTypes from 'prop-types'
import Router from 'next/router'
-import Input from '@codegouvfr/react-dsfr/Input'
import Button from '@codegouvfr/react-dsfr/Button'
import Alert from '@codegouvfr/react-dsfr/Alert'
import ToggleSwitch from '@codegouvfr/react-dsfr/ToggleSwitch'
-import {createClient, createMandataire, createChefDeFile, getChefsDeFile, getClient, getMandataires} from '@/lib/api-depot'
+import {createClient, updateClient, createMandataire, createChefDeFile, getChefsDeFile, getClient, getMandataires} from '@/lib/api-depot'
import Main from '@/layouts/main'
@@ -14,6 +13,7 @@ import {useUser} from '@/hooks/user'
import Loader from '@/components/loader'
import SelectInput from '@/components/select-input'
+import TextInput from '@/components/text-input'
import MandataireForm from '@/components/api-depot/client/client-form/mandataire-form'
import ChefDeFileForm from '@/components/api-depot/client/client-form/chef-de-file-form'
@@ -37,7 +37,6 @@ const ClientForm = ({client, mandataires, chefsDeFile, isDemo}) => {
const handleSumit = useCallback(async event => {
event.preventDefault()
-
const body = {
nom,
options: {relaxMode: isModeRelax},
@@ -64,12 +63,19 @@ const ClientForm = ({client, mandataires, chefsDeFile, isDemo}) => {
}
}
- const {_id} = await createClient(body, isDemo)
- Router.push({pathname: '/api-depot/client', query: {clientId: _id, demo: isDemo ? 1 : 0}})
+ let clientId = client._id
+ if (clientId) {
+ await updateClient(clientId, body, isDemo)
+ } else {
+ const response = await createClient(body, isDemo)
+ clientId = response._id
+ }
+
+ Router.push({pathname: '/api-depot/client', query: {clientId, demo: isDemo ? 1 : 0}})
} catch (error) {
setSubmitError(error.message || '')
}
- }, [nom, isModeRelax, isActive, authorizationStrategy, mandataire, chefDeFile, isDemo])
+ }, [nom, client._id, isModeRelax, isActive, authorizationStrategy, mandataire, chefDeFile, isDemo])
useEffect(() => {
let isFormValid = nom && mandataire
@@ -87,10 +93,10 @@ const ClientForm = ({client, mandataires, chefsDeFile, isDemo}) => {
{isAdmin && (
)}
|