-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Frontend - harmonise mutation through hooks
- Loading branch information
Showing
15 changed files
with
1,138 additions
and
1,146 deletions.
There are no files selected for viewing
436 changes: 218 additions & 218 deletions
436
frontend/src/pam/mission/actions/action-control-nav.test.tsx
Large diffs are not rendered by default.
Oops, something went wrong.
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
41 changes: 41 additions & 0 deletions
41
frontend/src/pam/mission/actions/use-add-update-action-control.tsx
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,41 @@ | ||
import { gql, MutationTuple, useMutation } from '@apollo/client' | ||
import { GET_MISSION_TIMELINE } from "../timeline/use-mission-timeline.tsx"; | ||
import { GET_ACTION_BY_ID } from "./use-action-by-id.tsx"; | ||
import { ActionControl } from "../../../types/action-types.ts"; | ||
import { useParams } from "react-router-dom"; | ||
|
||
export const MUTATION_ADD_OR_UPDATE_ACTION_CONTROL = gql` | ||
mutation AddOrUpdateControl($controlAction: ActionControlInput!) { | ||
addOrUpdateControl(controlAction: $controlAction) { | ||
id | ||
startDateTimeUtc | ||
endDateTimeUtc | ||
latitude | ||
longitude | ||
controlMethod | ||
observations | ||
vesselIdentifier | ||
vesselType | ||
vesselSize | ||
identityControlledPerson | ||
} | ||
} | ||
` | ||
|
||
|
||
const useAddOrUpdateControl = (): MutationTuple<ActionControl, Record<string, any>> => { | ||
const {missionId} = useParams() | ||
const mutation = useMutation( | ||
MUTATION_ADD_OR_UPDATE_ACTION_CONTROL, | ||
{ | ||
refetchQueries: [ | ||
{query: GET_MISSION_TIMELINE, variables: {missionId}}, | ||
GET_ACTION_BY_ID | ||
] | ||
} | ||
) | ||
|
||
return mutation | ||
} | ||
|
||
export default useAddOrUpdateControl |
24 changes: 24 additions & 0 deletions
24
frontend/src/pam/mission/actions/use-delete-action-control.tsx
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,24 @@ | ||
import { gql, MutationTuple, useMutation } from '@apollo/client' | ||
import { GET_MISSION_TIMELINE } from "../timeline/use-mission-timeline.tsx"; | ||
import { GET_ACTION_BY_ID } from "./use-action-by-id.tsx"; | ||
import { useParams } from "react-router-dom"; | ||
|
||
export const DELETE_ACTION_CONTROL = gql` | ||
mutation DeleteControl($id: String!) { | ||
deleteControl(id: $id) | ||
} | ||
` | ||
|
||
const useDeleteActionControl = (): MutationTuple<boolean, Record<string, any>> => { | ||
const {missionId} = useParams() | ||
const mutation = useMutation(DELETE_ACTION_CONTROL, { | ||
refetchQueries: [ | ||
{query: GET_MISSION_TIMELINE, variables: {missionId}}, | ||
GET_ACTION_BY_ID | ||
] | ||
}) | ||
|
||
return mutation | ||
} | ||
|
||
export default useDeleteActionControl |
266 changes: 128 additions & 138 deletions
266
frontend/src/pam/mission/controls/control-administrative-form.tsx
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 |
---|---|---|
@@ -1,170 +1,160 @@ | ||
import { Panel, Stack, Toggle } from 'rsuite' | ||
import { ControlAdministrative, ControlType } from '../../../types/control-types' | ||
import { Label, MultiRadio, OptionValue, Textarea, THEME } from '@mtes-mct/monitor-ui' | ||
import { useMutation } from '@apollo/client' | ||
import { DELETE_CONTROL_ADMINISTRATIVE, MUTATION_ADD_OR_UPDATE_CONTROL_ADMINISTRATIVE } from '../queries' | ||
import omit from 'lodash/omit' | ||
import { controlResultOptions } from './control-result' | ||
import { useParams } from 'react-router-dom' | ||
import ControlTitleCheckbox from './control-title-checkbox' | ||
import ControlInfraction from '../infractions/infraction-for-control' | ||
import { FC, useEffect, useState } from 'react' | ||
import { GET_MISSION_TIMELINE } from "../timeline/use-mission-timeline.tsx"; | ||
import { GET_ACTION_BY_ID } from "../actions/use-action-by-id.tsx"; | ||
import useDeleteControl from "./use-delete-control.tsx"; | ||
import useAddOrUpdateControl from "./use-add-update-control.tsx"; | ||
|
||
interface ControlAdministrativeFormProps { | ||
data?: ControlAdministrative | ||
shouldCompleteControl?: boolean | ||
unitShouldConfirm?: boolean | ||
data?: ControlAdministrative | ||
shouldCompleteControl?: boolean | ||
unitShouldConfirm?: boolean | ||
} | ||
|
||
const ControlAdministrativeForm: FC<ControlAdministrativeFormProps> = ({ | ||
data, | ||
shouldCompleteControl, | ||
unitShouldConfirm, | ||
data, | ||
shouldCompleteControl, | ||
unitShouldConfirm, | ||
}) => { | ||
const {missionId, actionId} = useParams() | ||
const {missionId, actionId} = useParams() | ||
|
||
const [observationsValue, setObservationsValue] = useState<string | undefined>(data?.observations) | ||
const [observationsValue, setObservationsValue] = useState<string | undefined>(data?.observations) | ||
|
||
const handleObservationsChange = (nextValue?: string) => { | ||
setObservationsValue(nextValue) | ||
} | ||
|
||
useEffect(() => { | ||
setObservationsValue(data?.observations) | ||
}, [data]) | ||
const handleObservationsChange = (nextValue?: string) => { | ||
setObservationsValue(nextValue) | ||
} | ||
|
||
const handleObservationsBlur = async () => { | ||
await onChange('observations', observationsValue) | ||
} | ||
useEffect(() => { | ||
setObservationsValue(data?.observations) | ||
}, [data]) | ||
|
||
const [mutate] = useMutation( | ||
MUTATION_ADD_OR_UPDATE_CONTROL_ADMINISTRATIVE, | ||
{ | ||
refetchQueries: [GET_MISSION_TIMELINE, GET_ACTION_BY_ID] | ||
const handleObservationsBlur = async () => { | ||
await onChange('observations', observationsValue) | ||
} | ||
) | ||
|
||
const [deleteControl] = useMutation(DELETE_CONTROL_ADMINISTRATIVE, { | ||
refetchQueries: [GET_MISSION_TIMELINE, GET_ACTION_BY_ID] | ||
}) | ||
const [mutateControl] = useAddOrUpdateControl({controlType: ControlType.ADMINISTRATIVE}) | ||
const [deleteControl] = useDeleteControl({controlType: ControlType.ADMINISTRATIVE}) | ||
|
||
const toggleControl = async (isChecked: boolean) => | ||
isChecked | ||
? onChange() | ||
: await deleteControl({ | ||
variables: { | ||
actionId | ||
} | ||
}) | ||
|
||
const toggleControl = async (isChecked: boolean) => | ||
isChecked | ||
? onChange() | ||
: await deleteControl({ | ||
variables: { | ||
actionId | ||
const onChange = async (field?: string, value?: any) => { | ||
let updatedData = { | ||
...omit(data, '__typename', 'infractions'), | ||
id: data?.id, | ||
missionId: missionId, | ||
actionControlId: actionId, | ||
amountOfControls: 1, | ||
unitShouldConfirm: unitShouldConfirm | ||
} | ||
}) | ||
|
||
const onChange = async (field?: string, value?: any) => { | ||
let updatedData = { | ||
...omit(data, '__typename', 'infractions'), | ||
id: data?.id, | ||
missionId: missionId, | ||
actionControlId: actionId, | ||
amountOfControls: 1, | ||
unitShouldConfirm: unitShouldConfirm | ||
} | ||
if (!!field && value !== undefined) { | ||
updatedData = { | ||
...updatedData, | ||
[field]: value | ||
} | ||
} | ||
|
||
if (!!field && value !== undefined) { | ||
updatedData = { | ||
...updatedData, | ||
[field]: value | ||
} | ||
await mutateControl({variables: {control: updatedData}}) | ||
} | ||
|
||
await mutate({variables: {control: updatedData}}) | ||
} | ||
|
||
return ( | ||
<Panel | ||
header={ | ||
<ControlTitleCheckbox | ||
controlType={ControlType.ADMINISTRATIVE} | ||
checked={!!data || shouldCompleteControl} | ||
shouldCompleteControl={!!shouldCompleteControl && !!!data} | ||
onChange={(isChecked: boolean) => toggleControl(isChecked)} | ||
/> | ||
} | ||
// collapsible | ||
// defaultExpanded={controlIsEnabled(data)} | ||
style={{backgroundColor: THEME.color.white, borderRadius: 0}} | ||
> | ||
<Stack direction="column" alignItems="flex-start" spacing="1rem" style={{width: '100%'}}> | ||
{unitShouldConfirm && ( | ||
<Stack.Item style={{width: '100%'}}> | ||
<Stack direction="row" alignItems="baseline" spacing={'0.5rem'}> | ||
<Stack.Item> | ||
{/* TODO add Toggle component to monitor-ui */} | ||
<Toggle | ||
checked={!!data?.unitHasConfirmed} | ||
size="sm" | ||
onChange={(checked: boolean) => onChange('unitHasConfirmed', checked)} | ||
return ( | ||
<Panel | ||
header={ | ||
<ControlTitleCheckbox | ||
controlType={ControlType.ADMINISTRATIVE} | ||
checked={!!data || shouldCompleteControl} | ||
shouldCompleteControl={!!shouldCompleteControl && !!!data} | ||
onChange={(isChecked: boolean) => toggleControl(isChecked)} | ||
/> | ||
</Stack.Item> | ||
<Stack.Item alignSelf="flex-end"> | ||
<Label style={{marginBottom: 0}}> | ||
<b>Contrôle confirmé par l’unité</b> | ||
</Label> | ||
</Stack.Item> | ||
} | ||
// collapsible | ||
// defaultExpanded={controlIsEnabled(data)} | ||
style={{backgroundColor: THEME.color.white, borderRadius: 0}} | ||
> | ||
<Stack direction="column" alignItems="flex-start" spacing="1rem" style={{width: '100%'}}> | ||
{unitShouldConfirm && ( | ||
<Stack.Item style={{width: '100%'}}> | ||
<Stack direction="row" alignItems="baseline" spacing={'0.5rem'}> | ||
<Stack.Item> | ||
{/* TODO add Toggle component to monitor-ui */} | ||
<Toggle | ||
checked={!!data?.unitHasConfirmed} | ||
size="sm" | ||
onChange={(checked: boolean) => onChange('unitHasConfirmed', checked)} | ||
/> | ||
</Stack.Item> | ||
<Stack.Item alignSelf="flex-end"> | ||
<Label style={{marginBottom: 0}}> | ||
<b>Contrôle confirmé par l’unité</b> | ||
</Label> | ||
</Stack.Item> | ||
</Stack> | ||
</Stack.Item> | ||
)} | ||
<Stack.Item style={{width: '100%'}}> | ||
<MultiRadio | ||
value={data?.compliantOperatingPermit} | ||
error="" | ||
isInline | ||
label="Permis de mise en exploitation (autorisation à pêcher) conforme" | ||
name="compliantOperatingPermit" | ||
onChange={(nextValue: OptionValue) => onChange('compliantOperatingPermit', nextValue)} | ||
options={controlResultOptions()} | ||
/> | ||
</Stack.Item> | ||
<Stack.Item style={{width: '100%'}}> | ||
<MultiRadio | ||
value={data?.upToDateNavigationPermit} | ||
error="" | ||
isInline | ||
label="Permis de navigation à jour" | ||
name="upToDateNavigationPermit" | ||
onChange={(nextValue: OptionValue) => onChange('upToDateNavigationPermit', nextValue)} | ||
options={controlResultOptions()} | ||
/> | ||
</Stack.Item> | ||
<Stack.Item style={{width: '100%'}}> | ||
<MultiRadio | ||
value={data?.compliantSecurityDocuments} | ||
error="" | ||
isInline | ||
label="Titres de sécurité conformes" | ||
name="compliantSecurityDocuments" | ||
onChange={(nextValue: OptionValue) => onChange('compliantSecurityDocuments', nextValue)} | ||
options={controlResultOptions()} | ||
/> | ||
</Stack.Item> | ||
<Stack.Item style={{width: '100%'}}> | ||
<Textarea | ||
name="observations" | ||
label="Observations (hors infraction) sur les pièces administratives" | ||
value={observationsValue} | ||
onChange={handleObservationsChange} | ||
onBlur={handleObservationsBlur} | ||
/> | ||
</Stack.Item> | ||
<Stack.Item style={{width: '100%'}}> | ||
<ControlInfraction | ||
controlId={data?.id} | ||
infractions={data?.infractions} | ||
controlType={ControlType.ADMINISTRATIVE} | ||
/> | ||
</Stack.Item> | ||
</Stack> | ||
</Stack.Item> | ||
)} | ||
<Stack.Item style={{width: '100%'}}> | ||
<MultiRadio | ||
value={data?.compliantOperatingPermit} | ||
error="" | ||
isInline | ||
label="Permis de mise en exploitation (autorisation à pêcher) conforme" | ||
name="compliantOperatingPermit" | ||
onChange={(nextValue: OptionValue) => onChange('compliantOperatingPermit', nextValue)} | ||
options={controlResultOptions()} | ||
/> | ||
</Stack.Item> | ||
<Stack.Item style={{width: '100%'}}> | ||
<MultiRadio | ||
value={data?.upToDateNavigationPermit} | ||
error="" | ||
isInline | ||
label="Permis de navigation à jour" | ||
name="upToDateNavigationPermit" | ||
onChange={(nextValue: OptionValue) => onChange('upToDateNavigationPermit', nextValue)} | ||
options={controlResultOptions()} | ||
/> | ||
</Stack.Item> | ||
<Stack.Item style={{width: '100%'}}> | ||
<MultiRadio | ||
value={data?.compliantSecurityDocuments} | ||
error="" | ||
isInline | ||
label="Titres de sécurité conformes" | ||
name="compliantSecurityDocuments" | ||
onChange={(nextValue: OptionValue) => onChange('compliantSecurityDocuments', nextValue)} | ||
options={controlResultOptions()} | ||
/> | ||
</Stack.Item> | ||
<Stack.Item style={{width: '100%'}}> | ||
<Textarea | ||
name="observations" | ||
label="Observations (hors infraction) sur les pièces administratives" | ||
value={observationsValue} | ||
onChange={handleObservationsChange} | ||
onBlur={handleObservationsBlur} | ||
/> | ||
</Stack.Item> | ||
<Stack.Item style={{width: '100%'}}> | ||
<ControlInfraction | ||
controlId={data?.id} | ||
infractions={data?.infractions} | ||
controlType={ControlType.ADMINISTRATIVE} | ||
/> | ||
</Stack.Item> | ||
</Stack> | ||
</Panel> | ||
) | ||
</Panel> | ||
) | ||
} | ||
|
||
export default ControlAdministrativeForm |
Oops, something went wrong.