From 556a6b4b2c93c1755e3e1f61a00dc7a16af470c8 Mon Sep 17 00:00:00 2001 From: Guillaume Grossetie Date: Tue, 10 Dec 2024 17:10:11 +0100 Subject: [PATCH 1/5] =?UTF-8?q?resolves=20#1134=20inverse=20l'ordre=20des?= =?UTF-8?q?=20=C3=A9lements=20pour=20afficher=20le=20dernier=20=C3=A9l?= =?UTF-8?q?=C3=A9ment=20en=20premier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- front/src/components/Form.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/front/src/components/Form.jsx b/front/src/components/Form.jsx index 7f70937fd..84ccca160 100644 --- a/front/src/components/Form.jsx +++ b/front/src/components/Form.jsx @@ -98,9 +98,10 @@ function ArrayFieldTemplate (properties) { const removeItemTitle = properties.uiSchema['ui:remove-item-title'] ?? 'form.removeItem.title' const title = properties.uiSchema['ui:title'] const inlineRemoveButton = properties.schema?.items?.type === 'string' || !removeItemTitle + const items = properties.items return (
- {title && {(t) => + {title && {(t) => {t(title)}} } {properties.canAdd && ( @@ -116,8 +117,7 @@ function ArrayFieldTemplate (properties) { )} - {properties.items && - properties.items.map((element) => { + {items && items.toReversed().map((element) => { return (
Date: Sat, 14 Dec 2024 15:41:41 +0100 Subject: [PATCH 2/5] =?UTF-8?q?Utilise=20reverse=20avec=20une=20copie=20d'?= =?UTF-8?q?un=20tableau=20plut=C3=B4t=20que=20toReversed()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- front/src/components/Form.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/front/src/components/Form.jsx b/front/src/components/Form.jsx index 84ccca160..5f721b6bd 100644 --- a/front/src/components/Form.jsx +++ b/front/src/components/Form.jsx @@ -98,7 +98,7 @@ function ArrayFieldTemplate (properties) { const removeItemTitle = properties.uiSchema['ui:remove-item-title'] ?? 'form.removeItem.title' const title = properties.uiSchema['ui:title'] const inlineRemoveButton = properties.schema?.items?.type === 'string' || !removeItemTitle - const items = properties.items + const items = [...properties.items].reverse() return (
{title && {(t) => @@ -117,7 +117,7 @@ function ArrayFieldTemplate (properties) { )} - {items && items.toReversed().map((element) => { + {items && items.map((element) => { return (
Date: Mon, 16 Dec 2024 18:24:57 +0100 Subject: [PATCH 3/5] Formatting --- front/src/components/Form.jsx | 566 +++++++++++++++++++--------------- 1 file changed, 309 insertions(+), 257 deletions(-) diff --git a/front/src/components/Form.jsx b/front/src/components/Form.jsx index 5f721b6bd..0c432d689 100644 --- a/front/src/components/Form.jsx +++ b/front/src/components/Form.jsx @@ -1,241 +1,289 @@ -import clsx from 'clsx' -import PropTypes from 'prop-types' -import React, { Fragment, useCallback, useMemo, useState } from 'react' -import Form, { getDefaultRegistry } from '@rjsf/core' -import validator from '@rjsf/validator-ajv8' -import { set } from 'object-path-immutable' -import { Translation } from 'react-i18next' +import clsx from "clsx"; +import PropTypes from "prop-types"; +import React, { Fragment, useCallback, useMemo, useState } from "react"; +import Form, { getDefaultRegistry } from "@rjsf/core"; +import validator from "@rjsf/validator-ajv8"; +import { set } from "object-path-immutable"; +import { Translation } from "react-i18next"; // REMIND: use a custom SelectWidget to support "ui:emptyValue" // remove once fixed in https://github.com/rjsf-team/react-jsonschema-form/issues/1041 -import SelectWidget from './SelectWidget' -import isidoreKeywordSearch from './Write/metadata/isidoreKeyword' -import isidoreAuthorSearch from './Write/metadata/isidoreAuthor' +import SelectWidget from "./SelectWidget"; +import isidoreKeywordSearch from "./Write/metadata/isidoreKeyword"; +import isidoreAuthorSearch from "./Write/metadata/isidoreAuthor"; -import styles from './form.module.scss' -import Button from './Button' -import { Plus, Trash } from 'react-feather' -import IsidoreAuthorAPIAutocompleteField from './Write/metadata/isidoreAuthor' +import styles from "./form.module.scss"; +import Button from "./Button"; +import { Plus, Trash } from "react-feather"; +import IsidoreAuthorAPIAutocompleteField from "./Write/metadata/isidoreAuthor"; const { - templates: { BaseInputTemplate: DefaultBaseInputTemplate }, - widgets: { CheckboxesWidget } -} = getDefaultRegistry() + templates: { BaseInputTemplate: DefaultBaseInputTemplate }, + widgets: { CheckboxesWidget }, +} = getDefaultRegistry(); /** * @param {BaseInputTemplate} properties */ -function BaseInputTemplate (properties) { - const { placeholder } = properties - return ( - { - (t) => - } - ) +function BaseInputTemplate(properties) { + const { placeholder } = properties; + return ( + + {(t) => ( + + )} + + ); } /** * @param {SelectWidget} properties */ -function CustomSelectWidget (properties) { - const { options, title, placeholder } = properties - return (
- - { - (t) => { - if (title && opt.label in title) { - return { - label: t(title[opt.label]), - value: opt.value - } - } - return { - label: t(opt.label), - value: opt.value - } - }) - } - }}/> - } - -
) +function CustomSelectWidget(properties) { + const { options, title, placeholder } = properties; + return ( +
+ + {(t) => ( + { + if (title && opt.label in title) { + return { + label: t(title[opt.label]), + value: opt.value, + }; + } + return { + label: t(opt.label), + value: opt.value, + }; + }), + }, + }} + /> + )} + +
+ ); } /** * @param {WidgetProps} properties */ -function CustomCheckboxesWidget (properties) { - const { options, title } = properties - return ( - { - (t) => { - if (title && opt.label in title) { - return { - label: t(title[opt.label]), - value: opt.value - } - } - return { - label: t(opt.label), - value: opt.value - } - }) - } - }}/> - } - ) +function CustomCheckboxesWidget(properties) { + const { options, title } = properties; + return ( + + {(t) => ( + { + if (title && opt.label in title) { + return { + label: t(title[opt.label]), + value: opt.value, + }; + } + return { + label: t(opt.label), + value: opt.value, + }; + }), + }, + }} + /> + )} + + ); } /** * @param {ArrayFieldTemplateProps} properties */ -function ArrayFieldTemplate (properties) { - const addItemTitle = properties.uiSchema['ui:add-item-title'] ?? 'form.addItem.title' - const removeItemTitle = properties.uiSchema['ui:remove-item-title'] ?? 'form.removeItem.title' - const title = properties.uiSchema['ui:title'] - const inlineRemoveButton = properties.schema?.items?.type === 'string' || !removeItemTitle - const items = [...properties.items].reverse() - return ( -
- {title && {(t) => - {t(title)}} - } - {properties.canAdd && ( - - )} - {items && items.map((element) => { - return ( -
- {element.children} - {element.hasRemove && ( - - )} -
- ) - })} -
- ) +function ArrayFieldTemplate(properties) { + const addItemTitle = + properties.uiSchema["ui:add-item-title"] ?? "form.addItem.title"; + const removeItemTitle = + properties.uiSchema["ui:remove-item-title"] ?? "form.removeItem.title"; + const title = properties.uiSchema["ui:title"]; + const inlineRemoveButton = + properties.schema?.items?.type === "string" || !removeItemTitle; + const items = [...properties.items].reverse(); + return ( +
+ {title && ( + + {(t) => {t(title)}} + + )} + {properties.canAdd && ( + + )} + {items && + items.map((element) => { + return ( +
+ {element.children} + {element.hasRemove && ( + + )} +
+ ); + })} +
+ ); } -function FieldTemplate (properties) { - const { id, classNames, style, help, description, errors, children, displayLabel } = properties - const label = properties.schema.$id - ? properties.label[properties.schema.$id] - : properties.label - return ( -
- {displayLabel && } - {description} - {children} - {errors} - {help} -
- ) +function FieldTemplate(properties) { + const { + id, + classNames, + style, + help, + description, + errors, + children, + displayLabel, + } = properties; + const label = properties.schema.$id + ? properties.label[properties.schema.$id] + : properties.label; + return ( +
+ {displayLabel && ( + + )} + {description} + {children} + {errors} + {help} +
+ ); } /** * @param {ObjectFieldTemplateProps} properties */ -function ObjectFieldTemplate (properties) { - if (properties.uiSchema['ui:groups']) { - const groups = properties.uiSchema['ui:groups'] - const groupedElements = groups.map(({ fields, title }) => { - const elements = fields - .filter( - (field) => (properties.uiSchema[field] || {})['ui:widget'] !== 'hidden' - ) - .map((field) => { - const element = properties.properties.find((element) => element.name === field) +function ObjectFieldTemplate(properties) { + if (properties.uiSchema["ui:groups"]) { + const groups = properties.uiSchema["ui:groups"]; + const groupedElements = groups.map(({ fields, title }) => { + const elements = fields + .filter( + (field) => + (properties.uiSchema[field] || {})["ui:widget"] !== "hidden", + ) + .map((field) => { + const element = properties.properties.find( + (element) => element.name === field, + ); - if (!element) { - console.error('Field configuration not found for "%s" in \'ui:groups\' "%s" — part of %o', field, title || '', fields) - } + if (!element) { + console.error( + 'Field configuration not found for "%s" in \'ui:groups\' "%s" — part of %o', + field, + title || "", + fields, + ); + } - return [field, element] - }) + return [field, element]; + }); - if (elements && elements.length > 0) { - return ( -
- {title && - - { - (t) => <>{t(title)} - } - - } - {elements.map(([field, element]) => { - return ( - element - ? {element.content} - :

- Field {field} defined in ui:groups is not an - entry of data-schema.json[properties] object. -

- ) - })} -
- ) - } - }) + if (elements && elements.length > 0) { + return ( +
+ {title && ( + + {(t) => <>{t(title)}} + + )} + {elements.map(([field, element]) => { + return element ? ( + {element.content} + ) : ( +

+ Field {field} defined in ui:groups{" "} + is not an entry of data-schema.json[properties]{" "} + object. +

+ ); + })} +
+ ); + } + }); - return <>{groupedElements} - } + return <>{groupedElements}; + } - if (properties) { - const autocomplete = properties.uiSchema['ui:autocomplete'] - return ( - - {properties.description} - {autocomplete === 'IsidoreAuthorSearch' && } - {properties.properties.map((element) => ( - {element.content} - ))} - - ) - } + if (properties) { + const autocomplete = properties.uiSchema["ui:autocomplete"]; + return ( + + {properties.description} + {autocomplete === "IsidoreAuthorSearch" && ( + + )} + {properties.properties.map((element) => ( + {element.content} + ))} + + ); + } } const customFields = { - IsidoreKeywordSearch: isidoreKeywordSearch, - IsidoreAuthorSearch: isidoreAuthorSearch, -} + IsidoreKeywordSearch: isidoreKeywordSearch, + IsidoreAuthorSearch: isidoreAuthorSearch, +}; /** * @@ -246,70 +294,74 @@ const customFields = { * @return {Element} * @constructor */ -export default function SchemaForm ({ - formData: initialFormData, - schema, - uiSchema, - onChange = () => { - }, +export default function SchemaForm({ + formData: initialFormData, + schema, + uiSchema, + onChange = () => {}, }) { - const [formData, setFormData] = useState(initialFormData) - const [, setErrors] = useState({}) - const formContext = useMemo(() => ({ - partialUpdate: ({ id, value }) => { - const path = id.replace('root_', '').replace('_', '.') - setFormData((state) => { - const newFormData = set(state, path, value) - onChange(newFormData) - return newFormData - }) - }, - }), [onChange, setFormData]) - + const [formData, setFormData] = useState(initialFormData); + const [, setErrors] = useState({}); + const formContext = useMemo( + () => ({ + partialUpdate: ({ id, value }) => { + const path = id.replace("root_", "").replace("_", "."); + setFormData((state) => { + const newFormData = set(state, path, value); + onChange(newFormData); + return newFormData; + }); + }, + }), + [onChange, setFormData], + ); - const customWidgets = { - SelectWidget: CustomSelectWidget, - CheckboxesWidget: CustomCheckboxesWidget, - } + const customWidgets = { + SelectWidget: CustomSelectWidget, + CheckboxesWidget: CustomCheckboxesWidget, + }; - const customTemplates = { - ObjectFieldTemplate, - FieldTemplate, - BaseInputTemplate, - ArrayFieldTemplate - } + const customTemplates = { + ObjectFieldTemplate, + FieldTemplate, + BaseInputTemplate, + ArrayFieldTemplate, + }; - const handleUpdate = useCallback((event) => { - const formData = event.formData - setFormData(formData) - onChange(formData) - }, [setFormData, onChange]) + const handleUpdate = useCallback( + (event) => { + const formData = event.formData; + setFormData(formData); + onChange(formData); + }, + [setFormData, onChange], + ); - // noinspection JSValidateTypes - return ( -
- -
- ) + // noinspection JSValidateTypes + return ( +
+ +
+ ); } SchemaForm.propTypes = { - formData: PropTypes.object, - schema: PropTypes.object, - uiSchema: PropTypes.object, - basicMode: PropTypes.bool, - onChange: PropTypes.func -} + formData: PropTypes.object, + schema: PropTypes.object, + uiSchema: PropTypes.object, + basicMode: PropTypes.bool, + onChange: PropTypes.func, +}; From c11e0666c5df7e6076292c6c371ffb832b9ae49c Mon Sep 17 00:00:00 2001 From: Guillaume Grossetie Date: Mon, 16 Dec 2024 18:27:42 +0100 Subject: [PATCH 4/5] formatting --- front/src/components/Form.jsx | 246 +++++++++++++++++----------------- 1 file changed, 123 insertions(+), 123 deletions(-) diff --git a/front/src/components/Form.jsx b/front/src/components/Form.jsx index 2383cb472..a1bb000fd 100644 --- a/front/src/components/Form.jsx +++ b/front/src/components/Form.jsx @@ -1,21 +1,21 @@ -import clsx from "clsx"; -import PropTypes from "prop-types"; -import React, { Fragment, useCallback, useMemo, useState } from "react"; -import Form, { getDefaultRegistry } from "@rjsf/core"; -import validator from "@rjsf/validator-ajv8"; -import { set } from "object-path-immutable"; -import { Translation } from "react-i18next"; +import clsx from 'clsx' +import PropTypes from 'prop-types' +import React, { Fragment, useCallback, useMemo, useState } from 'react' +import Form, { getDefaultRegistry } from '@rjsf/core' +import validator from '@rjsf/validator-ajv8' +import { set } from 'object-path-immutable' +import { Translation } from 'react-i18next' // REMIND: use a custom SelectWidget to support "ui:emptyValue" // remove once fixed in https://github.com/rjsf-team/react-jsonschema-form/issues/1041 -import SelectWidget from "./SelectWidget"; -import isidoreKeywordSearch from "./Write/metadata/isidoreKeyword"; -import isidoreAuthorSearch from "./Write/metadata/isidoreAuthor"; +import SelectWidget from './SelectWidget' +import isidoreKeywordSearch from './Write/metadata/isidoreKeyword' +import isidoreAuthorSearch from './Write/metadata/isidoreAuthor' -import styles from "./form.module.scss"; -import Button from "./Button"; -import { Plus, Trash } from "react-feather"; -import IsidoreAuthorAPIAutocompleteField from "./Write/metadata/isidoreAuthor"; +import styles from './form.module.scss' +import Button from './Button' +import { Plus, Trash } from 'react-feather' +import IsidoreAuthorAPIAutocompleteField from './Write/metadata/isidoreAuthor' const { templates: { BaseInputTemplate: DefaultBaseInputTemplate }, @@ -110,102 +110,102 @@ function CustomCheckboxesWidget(properties) { * @param {ArrayFieldTemplateProps} properties */ function ArrayFieldTemplate(properties) { - const addItemTitle = - properties.uiSchema["ui:add-item-title"] ?? "form.addItem.title"; - const removeItemTitle = - properties.uiSchema["ui:remove-item-title"] ?? "form.removeItem.title"; - const title = properties.uiSchema["ui:title"]; - const inlineRemoveButton = - properties.schema?.items?.type === "string" || !removeItemTitle; - const items = [...properties.items].reverse(); - return ( -
- {title && ( - - {(t) => {t(title)}} - - )} - {properties.canAdd && ( - - )} - {items && - items.map((element) => { - return ( -
- {element.children} - {element.hasRemove && ( - - )} -
- ); - })} -
- ); + const addItemTitle = + properties.uiSchema['ui:add-item-title'] ?? 'form.addItem.title' + const removeItemTitle = + properties.uiSchema['ui:remove-item-title'] ?? 'form.removeItem.title' + const title = properties.uiSchema['ui:title'] + const inlineRemoveButton = + properties.schema?.items?.type === 'string' || !removeItemTitle + const items = [...properties.items].reverse() + return ( +
+ {title && ( + + {(t) => {t(title)}} + + )} + {properties.canAdd && ( + + )} + {items && + items.map((element) => { + return ( +
+ {element.children} + {element.hasRemove && ( + + )} +
+ ) + })} +
+ ) } function FieldTemplate(properties) { - const { - id, - classNames, - style, - help, - description, - errors, - children, - displayLabel, - } = properties; - const label = properties.schema.$id - ? properties.label[properties.schema.$id] - : properties.label; - return ( -
- {displayLabel && ( - - )} - {description} - {children} - {errors} - {help} -
- ); + const { + id, + classNames, + style, + help, + description, + errors, + children, + displayLabel, + } = properties + const label = properties.schema.$id + ? properties.label[properties.schema.$id] + : properties.label + return ( +
+ {displayLabel && ( + + )} + {description} + {children} + {errors} + {help} +
+ ) } /** @@ -218,11 +218,11 @@ function ObjectFieldTemplate(properties) { const elements = fields .filter( (field) => - (properties.uiSchema[field] || {})['ui:widget'] !== 'hidden' + (properties.uiSchema[field] || {})['ui:widget'] !== 'hidden', ) .map((field) => { const element = properties.properties.find( - (element) => element.name === field + (element) => element.name === field, ) if (!element) { @@ -230,12 +230,12 @@ function ObjectFieldTemplate(properties) { 'Field configuration not found for "%s" in \'ui:groups\' "%s" — part of %o', field, title || '', - fields + fields, ) } - return [field, element]; - }); + return [field, element] + }) if (elements && elements.length > 0) { return ( @@ -261,8 +261,8 @@ function ObjectFieldTemplate(properties) { } }) - return <>{groupedElements}; - } + return <>{groupedElements} + } if (properties) { const autocomplete = properties.uiSchema['ui:autocomplete'] @@ -281,9 +281,9 @@ function ObjectFieldTemplate(properties) { } const customFields = { - IsidoreKeywordSearch: isidoreKeywordSearch, - IsidoreAuthorSearch: isidoreAuthorSearch, -}; + IsidoreKeywordSearch: isidoreKeywordSearch, + IsidoreAuthorSearch: isidoreAuthorSearch, +} /** * @@ -313,13 +313,13 @@ export default function SchemaForm({ }) }, }), - [onChange, setFormData] + [onChange, setFormData], ) - const customWidgets = { - SelectWidget: CustomSelectWidget, - CheckboxesWidget: CustomCheckboxesWidget, - }; + const customWidgets = { + SelectWidget: CustomSelectWidget, + CheckboxesWidget: CustomCheckboxesWidget, + } const customTemplates = { ObjectFieldTemplate, @@ -334,7 +334,7 @@ export default function SchemaForm({ setFormData(formData) onChange(formData) }, - [setFormData, onChange] + [setFormData, onChange], ) // noinspection JSValidateTypes From 5fb7eeac3a2973ff5ab550c7c1a917a0ea4a828d Mon Sep 17 00:00:00 2001 From: Guillaume Grossetie Date: Mon, 16 Dec 2024 18:28:33 +0100 Subject: [PATCH 5/5] format --- front/src/components/Form.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/front/src/components/Form.jsx b/front/src/components/Form.jsx index a1bb000fd..de0db43d2 100644 --- a/front/src/components/Form.jsx +++ b/front/src/components/Form.jsx @@ -148,7 +148,7 @@ function ArrayFieldTemplate(properties) { className={clsx( element.className, 'can-add-remove', - element?.uiSchema?.['ui:className'], + element?.uiSchema?.['ui:className'] )} > {element.children} @@ -218,11 +218,11 @@ function ObjectFieldTemplate(properties) { const elements = fields .filter( (field) => - (properties.uiSchema[field] || {})['ui:widget'] !== 'hidden', + (properties.uiSchema[field] || {})['ui:widget'] !== 'hidden' ) .map((field) => { const element = properties.properties.find( - (element) => element.name === field, + (element) => element.name === field ) if (!element) { @@ -230,7 +230,7 @@ function ObjectFieldTemplate(properties) { 'Field configuration not found for "%s" in \'ui:groups\' "%s" — part of %o', field, title || '', - fields, + fields ) } @@ -313,7 +313,7 @@ export default function SchemaForm({ }) }, }), - [onChange, setFormData], + [onChange, setFormData] ) const customWidgets = { @@ -334,7 +334,7 @@ export default function SchemaForm({ setFormData(formData) onChange(formData) }, - [setFormData, onChange], + [setFormData, onChange] ) // noinspection JSValidateTypes