diff --git a/client/src/definitions/datasets.ts b/client/src/definitions/datasets.ts index 85e03b81..23f0c8aa 100644 --- a/client/src/definitions/datasets.ts +++ b/client/src/definitions/datasets.ts @@ -47,8 +47,8 @@ export type DatasetFormInitial = Omit; export type DatasetFormData = Omit< Dataset, - "id" | "catalogRecord" | "headlines" -> & { organizationSiret: string }; + "id" | "catalogRecord" | "headlines" | "formats" +> & { organizationSiret: string; formats: Partial[] }; export type DatasetCreateData = Omit & { tagIds: string[]; diff --git a/client/src/lib/components/DatasetForm/DatasetForm.spec.ts b/client/src/lib/components/DatasetForm/DatasetForm.spec.ts index 0f301ac9..d58135c4 100644 --- a/client/src/lib/components/DatasetForm/DatasetForm.spec.ts +++ b/client/src/lib/components/DatasetForm/DatasetForm.spec.ts @@ -64,7 +64,7 @@ describe("Test the dataset form", () => { }); test('The "formats" field is present', async () => { - const { getAllByRole } = render(DatasetForm, { + const { getByLabelText } = render(DatasetForm, { catalog, formats: [ { @@ -73,8 +73,10 @@ describe("Test the dataset form", () => { }, ], }); - const checkboxes = getAllByRole("checkbox"); - expect(checkboxes.length).toBeGreaterThan(0); + const formatfield = getByLabelText("Format(s) des données", { + exact: false, + }); + expect(formatfield).toBeInTheDocument(); }); test('The "geographicalCoverage" field is present', async () => { @@ -103,26 +105,6 @@ describe("Test the dataset form", () => { expect(tags).toBeInTheDocument(); }); - test("At least one format is required", async () => { - const { getAllByRole } = render(DatasetForm, { - catalog, - formats: [ - { - id: 55, - name: "fichier tabulaire", - }, - ], - }); - const checkboxes = getAllByRole("checkbox", { checked: false }); - checkboxes.forEach((checkbox) => expect(checkbox).toBeRequired()); - await fireEvent.click(checkboxes[0]); - expect(checkboxes[0]).toBeChecked(); - checkboxes - .slice(1) - .forEach((checkbox) => expect(checkbox).not.toBeChecked()); - checkboxes.forEach((checkbox) => expect(checkbox).not.toBeRequired()); - }); - test('The "producerEmail" field is present', () => { const { getByLabelText } = render(DatasetForm, { catalog, formats: [] }); const producerEmail = getByLabelText( diff --git a/client/src/lib/components/DatasetForm/DatasetForm.svelte b/client/src/lib/components/DatasetForm/DatasetForm.svelte index 884ee9f9..62740abe 100644 --- a/client/src/lib/components/DatasetForm/DatasetForm.svelte +++ b/client/src/lib/components/DatasetForm/DatasetForm.svelte @@ -14,7 +14,6 @@ UPDATE_FREQUENCY_LABELS, } from "src/constants"; import { formatHTMLDate } from "$lib/util/format"; - import RequiredMarker from "../RequiredMarker/RequiredMarker.svelte"; import { account } from "src/lib/stores/auth"; import ContactEmailsField from "../ContactEmailsField/ContactEmailsField.svelte"; import GeographicalCoverageField from "./_GeographicalCoverageField.svelte"; @@ -30,6 +29,7 @@ import ExtraField from "./_ExtraField.svelte"; import Alert from "../Alert/Alert.svelte"; import type { DataFormat } from "src/definitions/dataformat"; + import FormatSelector from "./_FormatSelector.svelte"; export let submitLabel = "Publier la fiche de données"; export let loadingLabel = "Publication en cours..."; @@ -42,15 +42,18 @@ export let initial: DatasetFormInitial | null = null; - const dispatch = - createEventDispatcher<{ save: DatasetFormData; touched: boolean }>(); + const dispatch = createEventDispatcher<{ + save: DatasetFormData; + touched: boolean; + createDataFormat: string; + }>(); type DatasetFormValues = { organizationSiret: string; title: string; description: string; service: string; - dataFormats: boolean[]; + formats: Partial[]; producerEmail: string | null; contactEmails: string[]; geographicalCoverage: string; @@ -69,9 +72,7 @@ title: initial?.title || "", description: initial?.description || "", service: initial?.service || "", - dataFormats: formats.map( - ({ id }) => !!(initial?.formats || []).find((v) => v.id === id) - ), + formats: initial ? initial.formats : [], producerEmail: initial?.producerEmail || "", contactEmails: initial?.contactEmails || [$account?.email || ""], lastUpdatedAt: initial?.lastUpdatedAt @@ -92,9 +93,6 @@ publicationRestriction: initial?.publicationRestriction || "no_restriction", }; - // Handle this value manually. - const dataFormatsValue = initialValues.dataFormats; - const { form, errors, handleChange, handleSubmit, updateValidateField } = createForm({ initialValues, @@ -104,7 +102,15 @@ title: yup.string().required("Ce champ est requis"), description: yup.string().required("Ce champs est requis"), service: yup.string().required("Ce champs est requis"), - dataFormats: yup.array(yup.boolean()).length(dataFormatsValue.length), + formats: yup + .array() + .of( + yup.object().shape({ + name: yup.string(), + id: yup.string().nullable(), + }) + ) + .min(1, "Veuillez séléctionner au moins 1 format de donnée"), producerEmail: yup .string() .email("Ce champ doit contenir une adresse e-mail valide") @@ -135,10 +141,6 @@ extraFieldValues: yup.array().of(yup.string()), }), onSubmit: (values: DatasetFormValues) => { - const updatedFormats = values.dataFormats - .map((checked, index) => (checked ? formats[index] : null)) - .filter((item) => item) as DataFormat[]; - // Ensure "" becomes null. const producerEmail = values.producerEmail ? values.producerEmail @@ -167,7 +169,6 @@ const data: DatasetFormData = { ...values, - formats: updatedFormats, producerEmail, contactEmails, lastUpdatedAt, @@ -184,6 +185,7 @@ $: emailErrors = $errors.contactEmails as unknown as string[]; export const submitForm = (event: Event) => { + event.preventDefault(); handleSubmit(event); }; @@ -192,14 +194,8 @@ dispatch("touched", true); }; - const hasError = (error: string | string[]) => { - return typeof error === "string" && Boolean(error); - }; - - const handleDataformatChange = (event: Event, index: number) => { - const { checked } = event.target as HTMLInputElement; - dataFormatsValue[index] = checked; - updateValidateField("dataFormats", dataFormatsValue); + const handleDataFormatChanges = async (event: CustomEvent) => { + updateValidateField("formats", event.detail); dispatch("touched"); }; @@ -232,11 +228,16 @@ updateValidateField("extraFieldValues", v); dispatch("touched"); }; + + const handleAddDataFormat = (e: CustomEvent) => { + dispatch("createDataFormat", e.detail); + };

Informations générales

@@ -283,51 +284,13 @@

Sources et formats

-
- - Format(s) des données - - - Sélectionnez ici les différents formats de données qu'un réutilisateur - potentiel pourrait exploiter. - - -
- {#each formats as { id, name }, index} - {@const identifier = `dataformats-${id}`} -
- !checked)} - checked={dataFormatsValue[index]} - on:change={(event) => handleDataformatChange(event, index)} - /> - -
- {/each} -
- {#if hasError($errors.dataFormats)} -

- {$errors.dataFormats} -

- {/if} -
- + + import type { DataFormat } from "src/definitions/dataformat"; + import type { SelectOption } from "src/definitions/form"; + import { + transformDataFormatToSelectOption, + transoformSelectOptionToDataFormat, + } from "src/lib/transformers/form"; + import { createEventDispatcher } from "svelte"; + import Tag from "../Tag/Tag.svelte"; + import SearcheableComboBox from "../SearchableComboBox/SearcheableComboBox.svelte"; + + const dispatch = createEventDispatcher<{ + change: Partial[]; + }>(); + + export let formatOptions: DataFormat[]; + export let error: string; + + export let selectedFormatOptions: Partial[] = []; + + const handleSelectFormat = (e: CustomEvent>) => { + const selectedOption = transoformSelectOptionToDataFormat(e.detail); + + const itemAlreadyExists = + selectedFormatOptions.findIndex( + (item) => item.id == selectedOption.id + ) !== -1; + + if (!itemAlreadyExists) { + selectedFormatOptions = [...selectedFormatOptions, selectedOption]; + + dispatch("change", selectedFormatOptions); + } + }; + + const handleRemoveDataFormat = ( + e: CustomEvent<{ id: string; name: string }> + ) => { + const filtered = selectedFormatOptions.filter( + (item) => item.name !== e.detail.name + ); + + selectedFormatOptions = filtered; + + dispatch("change", selectedFormatOptions); + }; + + const handleAddItem = (e: CustomEvent) => { + selectedFormatOptions = [...selectedFormatOptions, { name: e.detail }]; + dispatch("change", selectedFormatOptions); + }; + + +
+ + +
+ {#each selectedFormatOptions as format, index} + {#if format.name} + + {/if} + {/each} +
+
+ + diff --git a/client/src/lib/components/SearchableComboBox/SearchableComboBox.spec.ts b/client/src/lib/components/SearchableComboBox/SearchableComboBox.spec.ts new file mode 100644 index 00000000..215f8680 --- /dev/null +++ b/client/src/lib/components/SearchableComboBox/SearchableComboBox.spec.ts @@ -0,0 +1,231 @@ +/** + * @jest-environment jsdom + */ +import "@testing-library/jest-dom"; +import { fireEvent, render } from "@testing-library/svelte"; +import type { SelectOption } from "src/definitions/form"; +import SearcheableComboBox from "./SearcheableComboBox.svelte"; + +const options: SelectOption[] = [ + { + label: "label-1", + value: 1, + }, + { + label: "label-2", + value: 2, + }, + { + label: "label-3", + value: 3, + }, +]; + +describe("Test the select component", () => { + test("should display a select input with 3 options", () => { + const props = { + options, + label: "My Nice Select", + name: "mySelect", + hintText: "my nice hint text", + }; + + const { getAllByRole } = render(SearcheableComboBox, { props }); + + expect(getAllByRole("listbox").length).toBe(1); + }); + + test("should display a select input with 3 options after start to type", async () => { + const props = { + options, + label: "My Nice Select", + name: "mySelect", + hintText: "my nice hint text", + }; + + const { getByRole, getAllByRole } = render(SearcheableComboBox, { props }); + + const combobox = getByRole("combobox"); + + await fireEvent.input(combobox, { + target: { + value: "label", + }, + }); + expect(getAllByRole("option").length).toBe(3); + }); + + test("should display a select input with 3 options after hitting alt + down arrow", async () => { + const props = { + options, + label: "My Nice Select", + name: "mySelect", + hintText: "my nice hint text", + }; + + const { getByRole, getAllByRole } = render(SearcheableComboBox, { props }); + + const combobox = getByRole("combobox"); + + await fireEvent.keyDown(combobox, { + key: "ArrowDown", + altKey: true, + }); + expect(getAllByRole("option").length).toBe(3); + }); + + test("should display a select input with 3 options after start typing and hitting down arrow key", async () => { + const props = { + options, + label: "My Nice Select", + name: "mySelect", + hintText: "my nice hint text", + }; + + const { getByRole, getAllByRole } = render(SearcheableComboBox, { props }); + + const combobox = getByRole("combobox"); + + await fireEvent.input(combobox, { + target: { + value: "label", + }, + }); + + await fireEvent.keyDown(combobox, { + key: "ArrowDown", + }); + expect(getAllByRole("option").length).toBe(3); + }); + + test("should display a select input with 3 options after start typing and hitting down arrow key", async () => { + const props = { + options, + label: "My Nice Select", + name: "mySelect", + hintText: "my nice hint text", + }; + + const { getByRole, queryByRole } = render(SearcheableComboBox, { props }); + + const combobox = getByRole("combobox"); + + await fireEvent.input(combobox, { + target: { + value: "label", + }, + }); + + await fireEvent.keyDown(combobox, { + key: "ArrowDown", + }); + + await fireEvent.keyDown(combobox, { + key: "Escape", + }); + expect(queryByRole("option")).toBe(null); + }); + + test("should select an option after hitting Enter", async () => { + const props = { + options, + label: "My Nice Select", + name: "mySelect", + hintText: "my nice hint text", + }; + + const { getByRole } = render(SearcheableComboBox, { props }); + + const combobox = getByRole("combobox"); + + await fireEvent.input(combobox, { + target: { + value: "lab", + }, + }); + + await fireEvent.keyDown(combobox, { + key: "ArrowDown", + }); + + await fireEvent.keyDown(combobox, { + key: "Enter", + }); + + expect(combobox).toHaveValue("label-1"); + }); + + test("should select the second option after hitting down arrow twice and Enter", async () => { + const props = { + options, + label: "My Nice Select", + name: "mySelect", + hintText: "my nice hint text", + }; + + const { getByRole } = render(SearcheableComboBox, { props }); + + const combobox = getByRole("combobox"); + + await fireEvent.input(combobox, { + target: { + value: "lab", + }, + }); + + await fireEvent.keyDown(combobox, { + key: "ArrowDown", + }); + + await fireEvent.keyDown(combobox, { + key: "ArrowDown", + }); + + await fireEvent.keyDown(combobox, { + key: "Enter", + }); + + expect(combobox).toHaveValue("label-2"); + }); + + test("should select the second option after hitting down arrow 3 times and Enter", async () => { + const props = { + options, + label: "My Nice Select", + name: "mySelect", + hintText: "my nice hint text", + }; + + const { getByRole } = render(SearcheableComboBox, { props }); + + const combobox = getByRole("combobox"); + + await fireEvent.input(combobox, { + target: { + value: "lab", + }, + }); + + await fireEvent.keyDown(combobox, { + key: "ArrowDown", + }); + + await fireEvent.keyDown(combobox, { + key: "ArrowDown", + }); + + await fireEvent.keyDown(combobox, { + key: "ArrowDown", + }); + + await fireEvent.keyDown(combobox, { + key: "ArrowDown", + }); + + await fireEvent.keyDown(combobox, { + key: "Enter", + }); + + expect(combobox).toHaveValue("label-1"); + }); +}); diff --git a/client/src/lib/components/SearchableComboBox/SearcheableComboBox.svelte b/client/src/lib/components/SearchableComboBox/SearcheableComboBox.svelte new file mode 100644 index 00000000..a31f44e8 --- /dev/null +++ b/client/src/lib/components/SearchableComboBox/SearcheableComboBox.svelte @@ -0,0 +1,388 @@ + + + + + diff --git a/client/src/lib/repositories/dataformat.ts b/client/src/lib/repositories/dataformat.ts index de13feea..869d0758 100644 --- a/client/src/lib/repositories/dataformat.ts +++ b/client/src/lib/repositories/dataformat.ts @@ -2,10 +2,12 @@ import type { DataFormat } from "src/definitions/dataformat"; import type { Fetch } from "src/definitions/fetch"; import { getApiUrl, getHeaders, makeApiRequestOrFail } from "../fetch"; -type GetDataFormats = (opts: { +type Options = { fetch: Fetch; apiToken: string; -}) => Promise; +}; + +type GetDataFormats = (opts: Options) => Promise; export const getDataFormats: GetDataFormats = async ({ fetch, apiToken }) => { const url = `${getApiUrl()}/dataformats/`; @@ -15,3 +17,24 @@ export const getDataFormats: GetDataFormats = async ({ fetch, apiToken }) => { const response = await makeApiRequestOrFail(fetch, request); return response.json(); }; + +export const postDataFormat = async ({ + fetch, + apiToken, + value, +}: Options & { value: string }): Promise => { + const body = JSON.stringify({ value }); + const url = `${getApiUrl()}/dataformats/`; + const request = new Request(url, { + method: "POST", + headers: new Headers([ + ["Content-Type", "application/json"], + ...getHeaders(apiToken), + ]), + body, + }); + + const response = await makeApiRequestOrFail(fetch, request); + + return (await response.json()) as DataFormat; +}; diff --git a/client/src/lib/transformers/form.ts b/client/src/lib/transformers/form.ts index 1fa54c7c..ebcb371f 100644 --- a/client/src/lib/transformers/form.ts +++ b/client/src/lib/transformers/form.ts @@ -1,3 +1,4 @@ +import type { DataFormat } from "src/definitions/dataformat"; import type { SelectOption } from "src/definitions/form"; import type { Tag } from "src/definitions/tag"; @@ -14,6 +15,7 @@ export const toSelectOptions = ( label: labelsMap[key], value: key, })); + return map as Array>; }; @@ -21,3 +23,17 @@ export const transformTagToSelectOption = (tag: Tag): SelectOption => ({ label: tag.name, value: `${tag.id}`, }); + +export const transformDataFormatToSelectOption = ( + dataformat: DataFormat +): SelectOption => ({ + label: dataformat.name, + value: dataformat.id, +}); + +export const transoformSelectOptionToDataFormat = ( + selectOption: SelectOption +): DataFormat => ({ + name: selectOption.label, + id: selectOption.value, +}); diff --git a/client/src/routes/(app)/contribuer/+page.svelte b/client/src/routes/(app)/contribuer/+page.svelte index 63e0385b..25f89884 100644 --- a/client/src/routes/(app)/contribuer/+page.svelte +++ b/client/src/routes/(app)/contribuer/+page.svelte @@ -3,13 +3,18 @@ import type { PageData } from "./$types"; import type { DatasetFormData } from "src/definitions/datasets"; import paths from "$lib/paths"; - import { apiToken as apiTokenStore } from "$lib/stores/auth"; + import { apiToken } from "$lib/stores/auth"; import DatasetForm from "$lib/components/DatasetForm/DatasetForm.svelte"; import { createDataset } from "$lib/repositories/datasets"; import { Maybe } from "$lib/util/maybe"; import DatasetFormLayout from "src/lib/components/DatasetFormLayout/DatasetFormLayout.svelte"; import ModalExitFormConfirmation from "src/lib/components/ModalExitFormConfirmation/ModalExitFormConfirmation.svelte"; import { hasHistory } from "src/lib/util/history"; + import { + getDataFormats, + postDataFormat, + } from "src/lib/repositories/dataformat"; + import type { DataFormat } from "src/definitions/dataformat"; let modalControlId = "confirm-stop-contributing-modal"; @@ -17,19 +22,41 @@ let formHasBeenTouched = false; + let freshDataFormat: DataFormat[]; + export let data: PageData; - $: ({ catalog, tags, licenses, filtersInfo, dataformats } = data); + $: ({ catalog, tags, licenses, filtersInfo, formats } = data); const onSave = async (event: CustomEvent) => { try { loading = true; const tagIds = event.detail.tags.map((item) => item.id); - const formatIds = event.detail.formats.map((item) => item.id); + + const mergedDataFormatsIds = event.detail.formats.reduce((prev, next) => { + if (!next.name) { + return prev; + } + + if (!next.id) { + const foundItemId = freshDataFormat.find( + (item) => item.name === next.name + )?.id; + + if (!foundItemId) { + return prev; + } + + return [...prev, foundItemId]; + } + + return [...prev, next.id]; + }, [] as number[]); + const dataset = await createDataset({ fetch, - apiToken: $apiTokenStore, - data: { ...event.detail, tagIds, formatIds }, + apiToken: $apiToken, + data: { ...event.detail, tagIds, formatIds: mergedDataFormatsIds }, }); if (Maybe.Some(dataset)) { @@ -47,6 +74,17 @@ await goto(paths.home); } }; + const handleCreateDataFormat = async (e: CustomEvent) => { + const dataformat = await postDataFormat({ + fetch, + apiToken: $apiToken, + value: e.detail, + }); + + freshDataFormat = [...freshDataFormat, dataformat]; + + formats = await getDataFormats({ fetch, apiToken: $apiToken }); + };
@@ -89,7 +127,7 @@ (formHasBeenTouched = true)} + on:createDataFormat={handleCreateDataFormat} /> {/if} diff --git a/client/src/routes/(app)/contribuer/+page.ts b/client/src/routes/(app)/contribuer/+page.ts index 0a36d640..7b761bdf 100644 --- a/client/src/routes/(app)/contribuer/+page.ts +++ b/client/src/routes/(app)/contribuer/+page.ts @@ -14,15 +14,13 @@ export const load: PageLoad = async ({ fetch }) => { const apiToken = get(apiTokenStore); const siret = Maybe.expect(get(account), "$account").organizationSiret; - const [catalog, tags, licenses, filtersInfo, dataformats] = await Promise.all( - [ - getCatalogBySiret({ fetch, apiToken, siret }), - getTags({ fetch, apiToken }), - getLicenses({ fetch, apiToken }), - getDatasetFiltersInfo({ fetch, apiToken }), - getDataFormats({ fetch, apiToken }), - ] - ); + const [catalog, tags, licenses, filtersInfo, formats] = await Promise.all([ + getCatalogBySiret({ fetch, apiToken, siret }), + getTags({ fetch, apiToken }), + getLicenses({ fetch, apiToken }), + getDatasetFiltersInfo({ fetch, apiToken }), + getDataFormats({ fetch, apiToken }), + ]); return { title: `Contribuer une fiche de jeu de données - ${SITE_TITLE}`, @@ -30,6 +28,6 @@ export const load: PageLoad = async ({ fetch }) => { tags, licenses, filtersInfo, - dataformats, + formats, }; }; diff --git a/client/src/routes/(app)/fiches/[id]/edit/+page.svelte b/client/src/routes/(app)/fiches/[id]/edit/+page.svelte index 321e1d0b..6c3987c4 100644 --- a/client/src/routes/(app)/fiches/[id]/edit/+page.svelte +++ b/client/src/routes/(app)/fiches/[id]/edit/+page.svelte @@ -3,16 +3,21 @@ import type { DatasetFormData } from "src/definitions/datasets"; import DatasetForm from "$lib/components/DatasetForm/DatasetForm.svelte"; import paths from "$lib/paths"; - import { isAdmin, apiToken as apiTokenStore } from "$lib/stores/auth"; + import { isAdmin, apiToken } from "$lib/stores/auth"; import { deleteDataset, updateDataset } from "$lib/repositories/datasets"; import { Maybe } from "$lib/util/maybe"; import DatasetFormLayout from "src/lib/components/DatasetFormLayout/DatasetFormLayout.svelte"; import ModalExitFormConfirmation from "src/lib/components/ModalExitFormConfirmation/ModalExitFormConfirmation.svelte"; import type { PageData } from "./$types"; + import { + getDataFormats, + postDataFormat, + } from "src/lib/repositories/dataformat"; + import type { DataFormat } from "src/definitions/dataformat"; export let data: PageData; - $: ({ catalog, dataset, tags, licenses, filtersInfo, dataformats } = data); + $: ({ catalog, tags, licenses, filtersInfo, formats, dataset } = data); let modalControlId = "stop-editing-form-modal"; @@ -20,22 +25,54 @@ let formHasbeenTouched = false; + let freshDataFormat: DataFormat[] = []; + + const handleCreateDataFormat = async (e: CustomEvent) => { + const dataFormat = await postDataFormat({ + fetch, + apiToken: $apiToken, + value: e.detail, + }); + + freshDataFormat = [...freshDataFormat, dataFormat]; + + formats = await getDataFormats({ fetch, apiToken: $apiToken }); + }; + const onSave = async (event: CustomEvent) => { if (!Maybe.Some(dataset)) { return; } const tagIds = event.detail.tags.map((item) => item.id); - const fromatIds = event.detail.formats.map((item) => item.id); + const mergedDataFormatsIds = event.detail.formats.reduce((prev, next) => { + if (!next.name) { + return prev; + } + + if (!next.id) { + const foundItemId = freshDataFormat.find( + (item) => item.name === next.name + )?.id; + + if (!foundItemId) { + return prev; + } + + return [...prev, foundItemId]; + } + + return [...prev, next.id]; + }, [] as number[]); try { loading = true; const updatedDataset = await updateDataset({ fetch, - apiToken: $apiTokenStore, + apiToken: $apiToken, id: dataset.id, - data: { ...event.detail, tagIds, formatIds: fromatIds }, + data: { ...event.detail, tagIds, formatIds: mergedDataFormatsIds }, }); if (Maybe.Some(updatedDataset)) { @@ -59,7 +96,7 @@ return; } - await deleteDataset({ fetch, apiToken: $apiTokenStore, id: dataset.id }); + await deleteDataset({ fetch, apiToken: $apiToken, id: dataset.id }); await goto(paths.home); }; @@ -71,7 +108,7 @@ }; -{#if Maybe.Some(catalog) && Maybe.Some(dataset) && Maybe.Some(tags) && Maybe.Some(licenses) && Maybe.Some(filtersInfo) && dataformats} +{#if Maybe.Some(catalog) && Maybe.Some(dataset) && Maybe.Some(tags) && Maybe.Some(licenses) && Maybe.Some(filtersInfo) && formats}
@@ -108,7 +145,7 @@ (formHasbeenTouched = true)} /> diff --git a/client/src/routes/(app)/fiches/[id]/edit/+page.ts b/client/src/routes/(app)/fiches/[id]/edit/+page.ts index c02e4bf8..a6e2efc8 100644 --- a/client/src/routes/(app)/fiches/[id]/edit/+page.ts +++ b/client/src/routes/(app)/fiches/[id]/edit/+page.ts @@ -17,20 +17,19 @@ export const load: PageLoad = async ({ fetch, params }) => { try { const dataset = await getDatasetByID({ fetch, apiToken, id: params.id }); - const [catalog, tags, licenses, filtersInfo, dataformats] = - await Promise.all([ - Maybe.map(dataset, (dataset) => - getCatalogBySiret({ - fetch, - apiToken, - siret: dataset.catalogRecord.organization.siret, - }) - ), - getTags({ fetch, apiToken }), - getLicenses({ fetch, apiToken }), - getDatasetFiltersInfo({ fetch, apiToken }), - getDataFormats({ fetch, apiToken }), - ]); + const [catalog, tags, licenses, filtersInfo, formats] = await Promise.all([ + Maybe.map(dataset, (dataset) => + getCatalogBySiret({ + fetch, + apiToken, + siret: dataset.catalogRecord.organization.siret, + }) + ), + getTags({ fetch, apiToken }), + getLicenses({ fetch, apiToken }), + getDatasetFiltersInfo({ fetch, apiToken }), + getDataFormats({ fetch, apiToken }), + ]); return { title: `Modifier la fiche de jeu de données - ${SITE_TITLE}`, @@ -39,7 +38,7 @@ export const load: PageLoad = async ({ fetch, params }) => { tags, licenses, filtersInfo, - dataformats, + formats, }; } catch (response) { if (response.status === 403) { diff --git a/client/src/tests/e2e/contribuer.spec.ts b/client/src/tests/e2e/contribuer.spec.ts index fdc51079..64ae1e94 100644 --- a/client/src/tests/e2e/contribuer.spec.ts +++ b/client/src/tests/e2e/contribuer.spec.ts @@ -54,8 +54,12 @@ test.describe("Basic form submission", () => { // "Sources et formats" section - const apiFormat = page.locator("label[for=dataformats-1]"); - await apiFormat.check(); + await page + .getByLabel( + "Format(s) des données * Sélectionnez ici les différents formats de données qu'un réutilisateur potentiel pourrait exploiter." + ) + .fill("d"); + await page.getByText("Base de données").click(); const technicalSource = page.locator("form [name=technicalSource]"); await technicalSource.fill(technicalSourceText); @@ -146,8 +150,8 @@ test.describe("Basic form submission", () => { expect(json.geographical_coverage).toBe("Europe continentale"); expect(json.formats).toStrictEqual([ { - id: 1, - name: "Fichier tabulaire (XLS, XLSX, CSV, ...)", + id: 4, + name: "Base de données", }, ]); expect(json.producer_email).toBe(producerEmailText);