-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix #949
- Loading branch information
Showing
12 changed files
with
347 additions
and
13 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { expect, test } from '@playwright/test'; | ||
import { | ||
expectPageToHaveText, | ||
gotoNextPage, | ||
gotoPreviousPage, | ||
goToStory, | ||
} from './utils'; | ||
|
||
test.describe('Fillers', () => { | ||
test(`can fill data`, async ({ page }) => { | ||
await goToStory(page, 'behaviour-fillers--default#t100'); | ||
|
||
// First filling | ||
await page.getByLabel('Code postal').fill('34000'); | ||
await gotoNextPage(page); | ||
await expectPageToHaveText(page, 'Chargement'); | ||
await expect(page.getByLabel('Ville')).toHaveValue('Montpellier'); | ||
|
||
// Second filling | ||
await gotoPreviousPage(page); | ||
await page.getByLabel('Code postal').fill('31000'); | ||
await gotoNextPage(page); | ||
await expect(page.getByLabel('Ville')).toHaveValue('Toulouse'); | ||
}); | ||
}); |
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,11 @@ | ||
import { slottableComponent } from '../shared/HOC/slottableComponent'; | ||
|
||
/** | ||
* Displays a loader while fetching data to fill the form | ||
*/ | ||
export const FillerLoader = slottableComponent( | ||
'FillerLoader', | ||
function FillerLoader() { | ||
return <p>Chargement des données...</p>; | ||
} | ||
); |
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
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,31 @@ | ||
import source from './source.json'; | ||
import Orchestrator from '../../utils/orchestrator.jsx'; | ||
|
||
export default { | ||
title: 'Behaviour/Fillers', | ||
component: Orchestrator, | ||
}; | ||
|
||
export const Default = { | ||
args: { | ||
source: source, | ||
data: {}, | ||
mockFiller: (data) => { | ||
return new Promise((resolve) => { | ||
setTimeout( | ||
() => { | ||
if (data.CODE === '34000') { | ||
return resolve({ CITY: 'Montpellier' }); | ||
} else if (data.CODE === '31000') { | ||
return resolve({ CITY: 'Toulouse' }); | ||
} | ||
return resolve({}); | ||
}, | ||
window.location.hash.startsWith('#t') | ||
? parseInt(window.location.hash.replace('#t', ''), 10) | ||
: 1500 | ||
); | ||
}); | ||
}, | ||
}, | ||
}; |
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,77 @@ | ||
{ | ||
"$schema": "../../../../lunatic-schema.json", | ||
"maxPage": "2", | ||
"fillers": [ | ||
{ | ||
"endpoint": { | ||
"url": "https://inseefr.github.io/Lunatic/" | ||
}, | ||
"responses": [ | ||
{ | ||
"name": "CODE" | ||
} | ||
] | ||
} | ||
], | ||
"components": [ | ||
{ | ||
"id": "a", | ||
"page": "1", | ||
"componentType": "Input", | ||
"label": { | ||
"type": "TXT", | ||
"value": "Code postal" | ||
}, | ||
"response": { | ||
"name": "CODE" | ||
}, | ||
"declarations": [ | ||
{ | ||
"declarationType": "COMMENT", | ||
"position": "DETACHABLE", | ||
"id": "d_a", | ||
"label": { | ||
"value": "Ce code permettra de remplir la ville (34000 ou 31000)", | ||
"type": "TXT" | ||
} | ||
} | ||
] | ||
}, | ||
{ | ||
"id": "a", | ||
"page": "2", | ||
"componentType": "Input", | ||
"label": { | ||
"type": "TXT", | ||
"value": "Ville" | ||
}, | ||
"response": { | ||
"name": "CITY" | ||
} | ||
} | ||
], | ||
"variables": [ | ||
{ | ||
"variableType": "COLLECTED", | ||
"values": { | ||
"COLLECTED": null, | ||
"EDITED": null, | ||
"INPUTTED": null, | ||
"FORCED": null, | ||
"PREVIOUS": null | ||
}, | ||
"name": "CODE" | ||
}, | ||
{ | ||
"variableType": "COLLECTED", | ||
"values": { | ||
"COLLECTED": null, | ||
"EDITED": null, | ||
"INPUTTED": null, | ||
"FORCED": null, | ||
"PREVIOUS": null | ||
}, | ||
"name": "CITY" | ||
} | ||
] | ||
} |
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,123 @@ | ||
import type { FillerDefinition } from '../../type.source'; | ||
import type { LunaticVariablesStore } from '../commons/variables/lunatic-variables-store'; | ||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; | ||
import type { LunaticChangesHandler } from '../type'; | ||
|
||
type Args = { | ||
variables: LunaticVariablesStore; | ||
fillers: FillerDefinition[]; | ||
handleChanges: LunaticChangesHandler; | ||
fetchMock: | ||
| null | ||
| ((data: Record<string, unknown>) => Promise<Record<string, unknown>>); | ||
}; | ||
|
||
/** | ||
* Behaviour that fills variables from a server when some variables are collected | ||
* The filling happens when the user move forward in the form | ||
*/ | ||
export function useFillers({ | ||
variables, | ||
fillers, | ||
handleChanges, | ||
fetchMock, | ||
}: Args) { | ||
const watchedVariables = useMemo( | ||
() => buildWatchedVariableMap(fillers), | ||
[fillers] | ||
); | ||
const activeFillers = useRef(new Set<FillerDefinition>()); // List fillers that should be triggerred in the next navigation | ||
const [isFilling, setFilling] = useState<boolean>(false); | ||
|
||
// Listen for change on variables to detect if a filler need to be triggered on next page change | ||
useEffect(() => { | ||
const listener = ( | ||
e: CustomEvent<{ | ||
name: string; | ||
}> | ||
) => { | ||
if (watchedVariables.has(e.detail.name)) { | ||
activeFillers.current.add(watchedVariables.get(e.detail.name)!); | ||
} | ||
}; | ||
variables.on('change', listener); | ||
return () => { | ||
variables.off('change', listener); | ||
}; | ||
}, [variables, watchedVariables]); | ||
|
||
// Trigger fillers | ||
const triggerFillers = useCallback(async () => { | ||
if (activeFillers.current.size === 0) { | ||
return; | ||
} | ||
setFilling(true); | ||
Promise.all( | ||
Array.from(activeFillers.current).map((filler) => { | ||
const values = Object.fromEntries( | ||
filler.responses.map((r) => [r.name, variables.get(r.name)]) | ||
); | ||
return fetchFillerData(filler, values, fetchMock).then((data) => { | ||
handleChanges( | ||
Object.entries(data).map((d) => ({ | ||
name: d[0], | ||
value: d[1], | ||
})) | ||
); | ||
}); | ||
}) | ||
) | ||
.catch((e) => { | ||
console.error(e); | ||
alert(e); | ||
}) | ||
.finally(() => { | ||
setFilling(false); | ||
activeFillers.current.clear(); | ||
}); | ||
}, [activeFillers, variables, handleChanges]); | ||
|
||
return { | ||
triggerFillers, | ||
isFilling, | ||
}; | ||
} | ||
|
||
/** | ||
* Creates a map of FillerDefinition indexed by variable name (improves performance) | ||
*/ | ||
function buildWatchedVariableMap( | ||
definitions: FillerDefinition[] | ||
): Map<string, FillerDefinition> { | ||
const map = new Map<string, FillerDefinition>(); | ||
for (const definition of definitions) { | ||
for (const response of definition.responses) { | ||
map.set(response.name, definition); | ||
} | ||
} | ||
return map; | ||
} | ||
|
||
/** | ||
* Fetch new data from the server (use mock if it exists) | ||
*/ | ||
function fetchFillerData( | ||
filler: FillerDefinition, | ||
data: Record<string, unknown>, | ||
mock: | ||
| null | ||
| ((data: Record<string, unknown>) => Promise<Record<string, unknown>>) | ||
): Promise<Record<string, unknown>> { | ||
if (mock) { | ||
return mock(data); | ||
} | ||
|
||
return fetch(filler.endpoint.url, { | ||
method: 'POST', | ||
body: JSON.stringify(data), | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Accept: 'application/json', | ||
}, | ||
}).then((res) => res.json()); | ||
} |
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
Oops, something went wrong.