diff --git a/front2/src/components/form/Formidable.tsx b/front2/src/components/form/Formidable.tsx index 965525a..eb77423 100644 --- a/front2/src/components/form/Formidable.tsx +++ b/front2/src/components/form/Formidable.tsx @@ -62,9 +62,7 @@ export const useFormidable = ({ }) => { const [values, setValues] = useState({ ...initialValues } as TYPE); const [initialData, setInitialData] = useState(initialValues); - const [valueChange, setValueChange] = useState<{ [key: string]: boolean }>( - {} - ); + const [isModify, setIsModify] = useState<{ [key: string]: boolean }>({}); const [isFormModified, setIsFormModified] = useState(false); useEffect(() => { setInitialData((previous) => { @@ -77,7 +75,7 @@ export const useFormidable = ({ //console.log(`FORMIDABLE: ==> update new values`); setValues({ ...initialValues }); const ret = getDifferences(initialValues, initialValues); - setValueChange(ret); + setIsModify(ret); setIsFormModified(hasAnyTrue(ret)); return initialValues; }); @@ -85,7 +83,7 @@ export const useFormidable = ({ initialValues, setInitialData, setValues, - setValueChange, + setIsModify, setIsFormModified, ]); const setValuesExternal = useCallback( @@ -94,7 +92,7 @@ export const useFormidable = ({ setValues((previous) => { const newValues = { ...previous, ...data }; const ret = getDifferences(initialData, newValues); - setValueChange(ret); + setIsModify(ret); setIsFormModified(hasAnyTrue(ret)); return newValues; }); @@ -124,21 +122,21 @@ export const useFormidable = ({ //console.log(`initialData data ${JSON.stringify(initialData, null, 2)}`); //console.log(`New data ${JSON.stringify(newValue, null, 2)}`); const ret = getDifferences(initialData, newValue); - setValueChange(ret); + setIsModify(ret); setIsFormModified(hasAnyTrue(ret)); return newValue; }); }, - [setValues, initialData, setIsFormModified, setValueChange] + [setValues, initialData, setIsFormModified, setIsModify] ); const getDeltaData = useCallback( ({ omit = [], only }: { omit?: string[]; only?: string[] }) => { const out = {}; - Object.keys(valueChange).forEach((key) => { + Object.keys(isModify).forEach((key) => { if (omit.includes(key) || (only && !only.includes(key))) { return; } - if (!valueChange[key]) { + if (!isModify[key]) { return; } const tmpValue = values[key]; @@ -150,11 +148,11 @@ export const useFormidable = ({ }); return out; }, - [valueChange, values] + [isModify, values] ); return { values, - valueChange, + isModify, isFormModified, setValues: setValuesExternal, getDeltaData, diff --git a/front2/src/components/popup/TrackEditPopUp.tsx b/front2/src/components/popup/TrackEditPopUp.tsx index 5e788cc..0f7351c 100644 --- a/front2/src/components/popup/TrackEditPopUp.tsx +++ b/front2/src/components/popup/TrackEditPopUp.tsx @@ -31,9 +31,9 @@ import { useNavigate, useParams } from 'react-router-dom'; import { Track, TrackResource } from '@/back-api'; import { FormGroup } from '@/components/form/FormGroup'; import { useFormidable } from '@/components/form/Formidable'; -import { SelectMultiple } from '@/components/form/SelectMultiple'; -import { SelectSingle } from '@/components/form/SelectSingle'; import { ConfirmPopUp } from '@/components/popup/ConfirmPopUp'; +import { SelectMultiple } from '@/components/select/SelectMultiple'; +import { SelectSingle } from '@/components/select/SelectSingle'; import { useOrderedAlbums } from '@/service/Album'; import { useOrderedArtists } from '@/service/Artist'; import { useOrderedGenders } from '@/service/Gender'; @@ -144,7 +144,7 @@ export const TrackEditPopUp = ({}: TrackEditPopUpProps) => { <> form.restoreValue({ name: true })} label="Title" > @@ -156,7 +156,7 @@ export const TrackEditPopUp = ({}: TrackEditPopUpProps) => { form.restoreValue({ description: true })} label="Description" > @@ -168,7 +168,7 @@ export const TrackEditPopUp = ({}: TrackEditPopUpProps) => { /> form.restoreValue({ genderId: true })} label="Gender" > @@ -180,7 +180,7 @@ export const TrackEditPopUp = ({}: TrackEditPopUpProps) => { /> form.restoreValue({ artists: true })} label="Artist(s)" > @@ -192,7 +192,7 @@ export const TrackEditPopUp = ({}: TrackEditPopUpProps) => { /> form.restoreValue({ albumId: true })} label="Album" > @@ -204,7 +204,7 @@ export const TrackEditPopUp = ({}: TrackEditPopUpProps) => { /> form.restoreValue({ track: true })} label="Track n°" > diff --git a/front2/src/components/form/FormSelectList.tsx b/front2/src/components/select/SelectList.tsx similarity index 80% rename from front2/src/components/form/FormSelectList.tsx rename to front2/src/components/select/SelectList.tsx index 379c548..7a65246 100644 --- a/front2/src/components/form/FormSelectList.tsx +++ b/front2/src/components/select/SelectList.tsx @@ -4,21 +4,21 @@ import { Box, Button, Flex, Text } from '@chakra-ui/react'; import { isNullOrUndefined } from '@/utils/validator'; -export type SelectMultipleValueDisplayType = { +export type SelectListModel = { id: any; name: any; - isSelected: boolean; + isSelected?: boolean; }; const optionToOptionDisplay = ( - data: SelectMultipleValueDisplayType[] | undefined, - selectedOptions: SelectMultipleValueDisplayType[], + data: SelectListModel[] | undefined, + selectedOptions: SelectListModel[], search?: string -): SelectMultipleValueDisplayType[] => { +): SelectListModel[] => { if (isNullOrUndefined(data)) { return []; } - const out: SelectMultipleValueDisplayType[] = []; + const out: SelectListModel[] = []; data.forEach((element) => { if (search) { if (!element.name.toLowerCase().includes(search.toLowerCase())) { @@ -34,18 +34,18 @@ const optionToOptionDisplay = ( return out; }; -export type FormSelectListProps = { - options?: SelectMultipleValueDisplayType[]; - selected: SelectMultipleValueDisplayType[]; - onSelectValue: (data: SelectMultipleValueDisplayType) => void; +export type SelectListProps = { + options?: SelectListModel[]; + selected: SelectListModel[]; + onSelectValue: (data: SelectListModel) => void; search?: string; }; -export const FormSelectList = ({ +export const SelectList = ({ options, selected, onSelectValue, search, -}: FormSelectListProps) => { +}: SelectListProps) => { const displayedValue = optionToOptionDisplay(options, selected, search); const scrollToRef = useRef(null); useEffect(() => { diff --git a/front2/src/components/form/SelectMultiple.tsx b/front2/src/components/select/SelectMultiple.tsx similarity index 72% rename from front2/src/components/form/SelectMultiple.tsx rename to front2/src/components/select/SelectMultiple.tsx index b38897a..79af68d 100644 --- a/front2/src/components/form/SelectMultiple.tsx +++ b/front2/src/components/select/SelectMultiple.tsx @@ -1,6 +1,7 @@ -import { useMemo, useState } from 'react'; +import { useMemo, useRef, useState } from 'react'; import { + Button, Flex, Input, InputGroup, @@ -12,12 +13,14 @@ import { Wrap, WrapItem, } from '@chakra-ui/react'; -import { MdSearch } from 'react-icons/md'; - import { - FormSelectList, - SelectMultipleValueDisplayType, -} from '@/components/form/FormSelectList'; + MdClose, + MdKeyboardArrowDown, + MdKeyboardArrowUp, + MdSearch, +} from 'react-icons/md'; + +import { SelectList, SelectListModel } from '@/components/select/SelectList'; import { isNullOrUndefined } from '@/utils/validator'; export type SelectMultipleProps = { @@ -41,14 +44,14 @@ export const SelectMultiple = ({ return { id: element[keyKey], name: element[keyValue], - isSelected: false, - } as SelectMultipleValueDisplayType; + } as SelectListModel; }); }, [options, keyKey, keyValue]); const [currentSearch, setCurrentSearch] = useState( undefined ); + const ref = useRef(null); const selectedOptions = useMemo(() => { if (isNullOrUndefined(values) || !transformedOption) { return []; @@ -58,7 +61,7 @@ export const SelectMultiple = ({ }); }, [values, transformedOption]); - const selectValue = (data: SelectMultipleValueDisplayType) => { + const selectValue = (data: SelectListModel) => { const newValues = values?.includes(data.id) ? values.filter((elem) => data.id !== elem) : [...(values ?? []), data.id]; @@ -74,13 +77,19 @@ export const SelectMultiple = ({ if (!options) { return ; } - function onChangeInput(value: string): void { + const onChangeInput = (value: string): void => { if (value === '') { setCurrentSearch(undefined); } else { setCurrentSearch(value); } - } + }; + const onOpenClose = () => { + if (!showList) { + ref?.current?.focus(); + return; + } + }; return ( @@ -102,19 +111,33 @@ export const SelectMultiple = ({ ))} )} - - - - + + onChangeInput(e.target.value)} //onSubmit={onSubmit} onFocus={() => setShowList(true)} onBlur={() => setTimeout(() => setShowList(false), 200)} + value={showList ? (currentSearch ?? '') : ''} + borderRadius="5px 0 0 5px" /> - + + {showList && ( - ( @@ -62,7 +45,7 @@ export const SelectSingle = ({ return transformedOption?.find((data) => data.id === value); }, [value, transformedOption]); - const selectValue = (data?: SelectMultipleValueDisplayType) => { + const selectValue = (data?: SelectListModel) => { const tmpData = data?.id == selectedOptions?.id ? undefined : data; setShowList(false); if (onChange) { @@ -80,13 +63,13 @@ export const SelectSingle = ({ } } const onRemoveItem = () => { - if (showList || !selectedOptions) { - ref?.current?.focus(); - return; + if (selectedOptions) { + if (onChange) { + onChange(undefined); + } } - console.log('Remove item ...'); - if (onChange) { - onChange(undefined); + if (!showList || selectedOptions) { + ref?.current?.focus(); } }; @@ -113,7 +96,6 @@ export const SelectSingle = ({ variant="outline" borderRadius="0 5px 5px 0" borderWidth="1px 1px 1px 0" - isDisabled={showList} > {selectedOptions ? ( @@ -125,7 +107,7 @@ export const SelectSingle = ({ {showList && ( -