[FEAT] ready gor update and suggestion
This commit is contained in:
parent
619e9aa4b8
commit
08eb0f878a
@ -71,17 +71,19 @@ export const AddableItem = () => {
|
||||
form={form}
|
||||
variableName={'data'}
|
||||
addNewItem={(data: string) => {
|
||||
let upperId = 0;
|
||||
setData((previous) => {
|
||||
previous.forEach((element) => {
|
||||
if (element['id'] > upperId) {
|
||||
upperId = element['id'];
|
||||
}
|
||||
return new Promise((resolve, _rejects) => {
|
||||
let upperId = 0;
|
||||
setData((previous) => {
|
||||
previous.forEach((element) => {
|
||||
if (element['id'] > upperId) {
|
||||
upperId = element['id'];
|
||||
}
|
||||
});
|
||||
upperId++;
|
||||
return [...previous, { id: upperId, name: data }];
|
||||
});
|
||||
upperId++;
|
||||
return [...previous, { id: upperId, name: data }];
|
||||
resolve({ id: upperId, name: data });
|
||||
});
|
||||
return upperId;
|
||||
}}
|
||||
options={data}
|
||||
/>
|
||||
|
@ -26,7 +26,9 @@ export type FormSelectProps = {
|
||||
// in the option specify the value field
|
||||
keyInputValue?: string;
|
||||
// Add capability to add an item (no key but only value)
|
||||
addNewItem?: (data: string) => number | string;
|
||||
addNewItem?: (data: string) => Promise<any>;
|
||||
// if a suggestion exist at the auto compleat
|
||||
suggestion?: string;
|
||||
};
|
||||
|
||||
export const FormSelect = ({
|
||||
@ -35,8 +37,9 @@ export const FormSelect = ({
|
||||
ref,
|
||||
placeholder,
|
||||
options,
|
||||
keyInputKey,
|
||||
keyInputKey = 'id',
|
||||
keyInputValue = 'name',
|
||||
suggestion,
|
||||
addNewItem,
|
||||
...rest
|
||||
}: FormSelectProps) => {
|
||||
@ -44,9 +47,8 @@ export const FormSelect = ({
|
||||
const onCreate = !addNewItem
|
||||
? undefined
|
||||
: (data: string) => {
|
||||
const ret = addNewItem(data);
|
||||
form.setValues({ [variableName]: ret });
|
||||
};
|
||||
addNewItem(data).then((data: object) => form.setValues({ [variableName]: data[keyInputKey] }));
|
||||
};
|
||||
return (
|
||||
<FormGroup
|
||||
isModify={form.isModify[variableName]}
|
||||
@ -61,6 +63,7 @@ export const FormSelect = ({
|
||||
keyKey={keyInputKey}
|
||||
keyValue={keyInputValue}
|
||||
onCreate={onCreate}
|
||||
suggestion={suggestion}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
|
@ -71,17 +71,19 @@ export const AddableItem = () => {
|
||||
form={form}
|
||||
variableName={'data'}
|
||||
addNewItem={(data: string) => {
|
||||
let upperId = 0;
|
||||
setData((previous) => {
|
||||
previous.forEach((element) => {
|
||||
if (element['id'] > upperId) {
|
||||
upperId = element['id'];
|
||||
}
|
||||
return new Promise((resolve, _rejects) => {
|
||||
let upperId = 0;
|
||||
setData((previous) => {
|
||||
previous.forEach((element) => {
|
||||
if (element['id'] > upperId) {
|
||||
upperId = element['id'];
|
||||
}
|
||||
});
|
||||
upperId++;
|
||||
return [...previous, { id: upperId, name: data }];
|
||||
});
|
||||
upperId++;
|
||||
return [...previous, { id: upperId, name: data }];
|
||||
resolve({ id: upperId, name: data });
|
||||
});
|
||||
return upperId;
|
||||
}}
|
||||
options={data}
|
||||
/>
|
||||
|
@ -24,7 +24,7 @@ export type FormSelectMultipleProps = {
|
||||
// in the option specify the value field
|
||||
keyInputValue?: string;
|
||||
// Add capability to add an item (no key but only value)
|
||||
addNewItem?: (data: string) => number | string;
|
||||
addNewItem?: (data: string) => Promise<any>;
|
||||
};
|
||||
|
||||
export const FormSelectMultiple = ({
|
||||
@ -33,7 +33,7 @@ export const FormSelectMultiple = ({
|
||||
ref,
|
||||
placeholder,
|
||||
options,
|
||||
keyInputKey,
|
||||
keyInputKey = 'id',
|
||||
keyInputValue = 'name',
|
||||
addNewItem,
|
||||
...rest
|
||||
@ -42,11 +42,8 @@ export const FormSelectMultiple = ({
|
||||
const onCreate = !addNewItem
|
||||
? undefined
|
||||
: (data: string) => {
|
||||
const ret = addNewItem(data);
|
||||
form.setValues({
|
||||
[variableName]: [...(form.values[variableName] ?? []), ret],
|
||||
});
|
||||
};
|
||||
addNewItem(data).then((data: object) => form.setValues({ [variableName]: [...(form.values[variableName] ?? []), data[keyInputKey]] }));
|
||||
};
|
||||
return (
|
||||
<FormGroup
|
||||
isModify={form.isModify[variableName]}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { RefObject, useMemo, useRef, useState } from 'react';
|
||||
import { RefObject, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import {
|
||||
Button,
|
||||
@ -11,7 +11,7 @@ import {
|
||||
Wrap,
|
||||
WrapItem,
|
||||
} from '@chakra-ui/react';
|
||||
import { MdKeyboardArrowDown, MdKeyboardArrowUp } from 'react-icons/md';
|
||||
import { MdEdit, MdKeyboardArrowDown, MdKeyboardArrowUp } from 'react-icons/md';
|
||||
|
||||
import { SelectList, SelectListModel } from '@/components/select/SelectList';
|
||||
import { isNullOrUndefined } from '@/utils/validator';
|
||||
@ -25,6 +25,8 @@ export type SelectMultipleProps = {
|
||||
ref?: RefObject<any>;
|
||||
// if set add capability to add the search item
|
||||
onCreate?: (data: string) => void;
|
||||
// if a suggestion exist at the auto compleat
|
||||
suggestion?: string;
|
||||
};
|
||||
|
||||
export const SelectMultiple = ({
|
||||
@ -34,6 +36,7 @@ export const SelectMultiple = ({
|
||||
ref,
|
||||
keyKey = 'id',
|
||||
keyValue = keyKey,
|
||||
suggestion,
|
||||
onCreate,
|
||||
}: SelectMultipleProps) => {
|
||||
const [showList, setShowList] = useState(false);
|
||||
@ -45,9 +48,18 @@ export const SelectMultiple = ({
|
||||
} as SelectListModel;
|
||||
});
|
||||
}, [options, keyKey, keyValue]);
|
||||
const [currentSearch, setCurrentSearch] = useState<string | undefined>(
|
||||
undefined
|
||||
const [hasSuggestion, setHasSuggestion] = useState<boolean>(
|
||||
onCreate && suggestion ? true : false
|
||||
);
|
||||
const [currentSearch, setCurrentSearch] = useState<string | undefined>(
|
||||
onCreate ? suggestion : undefined
|
||||
);
|
||||
useEffect(() => {
|
||||
if (suggestion) {
|
||||
setCurrentSearch(suggestion);
|
||||
setHasSuggestion(true);
|
||||
}
|
||||
}, [suggestion]);
|
||||
|
||||
const refFocus = ref ?? useRef<HTMLInputElement | null>(null);
|
||||
const selectedOptions = useMemo(() => {
|
||||
@ -76,6 +88,7 @@ export const SelectMultiple = ({
|
||||
return <Spinner />;
|
||||
}
|
||||
const onChangeInput = (value: string): void => {
|
||||
setHasSuggestion(false);
|
||||
if (value === '') {
|
||||
setCurrentSearch(undefined);
|
||||
} else {
|
||||
@ -91,9 +104,9 @@ export const SelectMultiple = ({
|
||||
const createNewItem = !onCreate
|
||||
? undefined
|
||||
: (data: string) => {
|
||||
onCreate(data);
|
||||
setCurrentSearch(undefined);
|
||||
};
|
||||
onCreate(data);
|
||||
setCurrentSearch(undefined);
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex direction="column" width="full" gap="0px">
|
||||
@ -124,7 +137,7 @@ export const SelectMultiple = ({
|
||||
//onSubmit={onSubmit}
|
||||
onFocus={() => setShowList(true)}
|
||||
onBlur={() => setTimeout(() => setShowList(false), 200)}
|
||||
value={showList ? (currentSearch ?? '') : ''}
|
||||
value={showList ? (currentSearch ?? '') : hasSuggestion ? `suggest: ${currentSearch}` : ''}
|
||||
borderRadius="5px 0 0 5px"
|
||||
/>
|
||||
<Button
|
||||
@ -135,6 +148,8 @@ export const SelectMultiple = ({
|
||||
>
|
||||
{showList ? (
|
||||
<MdKeyboardArrowUp color="gray.300" />
|
||||
) : hasSuggestion ? (
|
||||
<MdEdit color="gray.300" />
|
||||
) : (
|
||||
<MdKeyboardArrowDown color="gray.300" />
|
||||
)}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { RefObject, useMemo, useRef, useState } from 'react';
|
||||
import { RefObject, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import { Button, Flex, Input, Spinner } from '@chakra-ui/react';
|
||||
import {
|
||||
MdClose,
|
||||
MdEdit,
|
||||
MdKeyboardArrowDown,
|
||||
MdKeyboardArrowUp,
|
||||
} from 'react-icons/md';
|
||||
@ -19,6 +20,8 @@ export type SelectSingleProps = {
|
||||
ref?: RefObject<any>;
|
||||
// if set add capability to add the search item
|
||||
onCreate?: (data: string) => void;
|
||||
// if a suggestion exist at the auto compleat
|
||||
suggestion?: string;
|
||||
};
|
||||
|
||||
export const SelectSingle = ({
|
||||
@ -28,6 +31,7 @@ export const SelectSingle = ({
|
||||
ref,
|
||||
keyKey = 'id',
|
||||
keyValue = keyKey,
|
||||
suggestion,
|
||||
onCreate,
|
||||
}: SelectSingleProps) => {
|
||||
const [showList, setShowList] = useState(false);
|
||||
@ -39,9 +43,18 @@ export const SelectSingle = ({
|
||||
} as SelectListModel;
|
||||
});
|
||||
}, [options, keyKey, keyValue]);
|
||||
const [currentSearch, setCurrentSearch] = useState<string | undefined>(
|
||||
undefined
|
||||
const [hasSuggestion, setHasSuggestion] = useState<boolean>(
|
||||
onCreate && suggestion ? true : false
|
||||
);
|
||||
const [currentSearch, setCurrentSearch] = useState<string | undefined>(
|
||||
onCreate ? suggestion : undefined
|
||||
);
|
||||
useEffect(() => {
|
||||
if (suggestion) {
|
||||
setCurrentSearch(suggestion);
|
||||
setHasSuggestion(true);
|
||||
}
|
||||
}, [suggestion]);
|
||||
const refFocus = ref ?? useRef<HTMLInputElement | null>(null);
|
||||
const selectedOptions = useMemo(() => {
|
||||
if (isNullOrUndefined(value)) {
|
||||
@ -61,6 +74,7 @@ export const SelectSingle = ({
|
||||
return <Spinner />;
|
||||
}
|
||||
function onChangeInput(value: string): void {
|
||||
setHasSuggestion(false);
|
||||
if (value === '') {
|
||||
setCurrentSearch(undefined);
|
||||
} else {
|
||||
@ -68,6 +82,7 @@ export const SelectSingle = ({
|
||||
}
|
||||
}
|
||||
const onRemoveItem = () => {
|
||||
setHasSuggestion(false);
|
||||
if (selectedOptions) {
|
||||
if (onChange) {
|
||||
onChange(undefined);
|
||||
@ -81,9 +96,10 @@ export const SelectSingle = ({
|
||||
const createNewItem = !onCreate
|
||||
? undefined
|
||||
: (data: string) => {
|
||||
onCreate(data);
|
||||
setCurrentSearch(undefined);
|
||||
};
|
||||
onCreate(data);
|
||||
setCurrentSearch(undefined);
|
||||
setHasSuggestion(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex direction="column" width="full" gap="0px">
|
||||
@ -95,7 +111,7 @@ export const SelectSingle = ({
|
||||
onFocus={() => setShowList(true)}
|
||||
onBlur={() => setTimeout(() => setShowList(false), 200)}
|
||||
value={
|
||||
showList ? (currentSearch ?? '') : (selectedOptions?.name ?? '')
|
||||
showList ? (currentSearch ?? '') : (selectedOptions?.name ?? hasSuggestion ? `suggest: ${currentSearch}` : '')
|
||||
}
|
||||
backgroundColor={
|
||||
showList || !selectedOptions ? undefined : 'green.500'
|
||||
@ -112,6 +128,8 @@ export const SelectSingle = ({
|
||||
<MdClose color="gray.300" />
|
||||
) : showList ? (
|
||||
<MdKeyboardArrowUp color="gray.300" />
|
||||
) : hasSuggestion ? (
|
||||
<MdEdit color="gray.300" />
|
||||
) : (
|
||||
<MdKeyboardArrowDown color="gray.300" />
|
||||
)}
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { Album, AlbumResource, Artist, ArtistResource, Gender, GenderResource } from '@/back-api';
|
||||
import { useFormidable } from '@/components/form/Formidable';
|
||||
import { FormInput } from '@/components/form/FormInput';
|
||||
import { FormSelect } from '@/components/form/FormSelect';
|
||||
import { PageLayout } from '@/components/Layout/PageLayout';
|
||||
import { TopBar } from '@/components/TopBar/TopBar';
|
||||
import { useOrderedAlbums } from '@/service/Album';
|
||||
import { useOrderedArtists } from '@/service/Artist';
|
||||
import { useAlbumService, useOrderedAlbums } from '@/service/Album';
|
||||
import { useArtistService, useOrderedArtists } from '@/service/Artist';
|
||||
import { useGenderService, useOrderedGenders } from '@/service/Gender';
|
||||
import { useServiceContext } from '@/service/ServiceContext';
|
||||
import { isNullOrUndefined } from '@/utils/validator';
|
||||
import { Flex, Text, Input, Table, TableCaption, TableContainer, Tbody, Td, Tfoot, Th, Thead, Tr, Button } from '@chakra-ui/react';
|
||||
import { useState } from 'react';
|
||||
@ -72,6 +74,10 @@ export const AddPage = () => {
|
||||
const { dataGenders } = useOrderedGenders();
|
||||
const { dataArtist } = useOrderedArtists();
|
||||
const { dataAlbums } = useOrderedAlbums();
|
||||
const { store: storeGender } = useGenderService();
|
||||
const { store: storeArtist } = useArtistService();
|
||||
const { store: storeAlbum } = useAlbumService();
|
||||
const { session } = useServiceContext();
|
||||
|
||||
const updateNeedSend = () => {
|
||||
if (parsedElement.length === 0) {
|
||||
@ -270,7 +276,8 @@ export const AddPage = () => {
|
||||
// add it in the list.
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const [suggestedArtist, setSuggestedArtist] = useState<string | undefined>(undefined);
|
||||
const [suggestedAlbum, setSuggestedAlbum] = useState<string | undefined>(undefined);
|
||||
|
||||
const onChangeFile = (value: any): void => {
|
||||
clearData();
|
||||
@ -286,8 +293,6 @@ export const AddPage = () => {
|
||||
updateNeedSend();
|
||||
return;
|
||||
}
|
||||
// we verify with the first value to remove all unknown ...
|
||||
// clean different gender:
|
||||
|
||||
// clean different artist:
|
||||
for (let iii = 1; iii < parsedElementTmp.length; iii++) {
|
||||
@ -312,24 +317,36 @@ export const AddPage = () => {
|
||||
setParsedElement(parsedElementTmp);
|
||||
setParsedFailedElement(parsedFailedElementTmp);
|
||||
console.log(`check : ${JSON.stringify(parsedElementTmp[0])}`)
|
||||
|
||||
setGlobalArtist(parsedElementTmp[0].artist);
|
||||
// find artistId:
|
||||
console.log(`try find artist : ${parsedElementTmp[0].artist}`);
|
||||
let artistFound = false;
|
||||
dataArtist.forEach((data) => {
|
||||
if (data.name?.toLowerCase() === parsedElementTmp[0].artist?.toLowerCase()) {
|
||||
console.log(` find artist : ${data.id}`);
|
||||
form.setValues({ artistId: data.id });
|
||||
artistFound = true;
|
||||
}
|
||||
})
|
||||
if (!artistFound) {
|
||||
setSuggestedArtist(parsedElementTmp[0].artist);
|
||||
}
|
||||
|
||||
setGlobalAlbum(parsedElementTmp[0].album);
|
||||
// try to find album
|
||||
console.log(`try find album : ${parsedElementTmp[0].album}`);
|
||||
let albumFound = false;
|
||||
dataAlbums.forEach((data) => {
|
||||
if (data.name?.toLowerCase() === parsedElementTmp[0].album?.toLowerCase()) {
|
||||
console.log(` find album : ${data.id}`);
|
||||
form.setValues({ albumId: data.id });
|
||||
albumFound = true;
|
||||
}
|
||||
})
|
||||
|
||||
if (!albumFound) {
|
||||
setSuggestedAlbum(parsedElementTmp[0].album);
|
||||
}
|
||||
updateNeedSend();
|
||||
setArtistId(undefined);
|
||||
setAlbumId(undefined);
|
||||
@ -521,41 +538,33 @@ export const AddPage = () => {
|
||||
// });
|
||||
}
|
||||
|
||||
const eventPopUpAlbum = (event: string): void => {
|
||||
console.log(`GET event: ${event}`);
|
||||
// this.popInService.close('popin-new-album');
|
||||
}
|
||||
const eventPopUpArtist = (event: string): void => {
|
||||
console.log(`GET event: ${event}`);
|
||||
//this.popInService.close('popin-new-artist');
|
||||
}
|
||||
const eventPopUpType = (event: string): void => {
|
||||
console.log(`GET event: ${event}`);
|
||||
// this.popInService.close('popin-new-type');
|
||||
}
|
||||
const eventPopUpPlaylist = (event: string): void => {
|
||||
console.log(`GET event: ${event}`);
|
||||
// this.popInService.close('popin-new-playlist');
|
||||
}
|
||||
|
||||
const newAlbum = (): void => {
|
||||
console.log('Request new Album...');
|
||||
// this.popInService.open('popin-new-album');
|
||||
}
|
||||
const newArtist = (): void => {
|
||||
console.log('Request new Artist...');
|
||||
// this.popInService.open('popin-new-artist');
|
||||
}
|
||||
const newType = (): void => {
|
||||
console.log('Request new Type...');
|
||||
// this.popInService.open('popin-create-type');
|
||||
}
|
||||
const newPlaylist = () => {
|
||||
console.log('Request new Playlist...');
|
||||
// this.popInService.open('popin-new-playlist');
|
||||
}
|
||||
const form = useFormidable<FormInsertData>({});
|
||||
|
||||
const addNewGender = (data: string): Promise<Gender> => {
|
||||
return storeGender.update(GenderResource.post({
|
||||
restConfig: session.getRestConfig(),
|
||||
data: {
|
||||
name: data,
|
||||
},
|
||||
}));
|
||||
}
|
||||
const addNewArtist = (data: string): Promise<Artist> => {
|
||||
return storeArtist.update(ArtistResource.post({
|
||||
restConfig: session.getRestConfig(),
|
||||
data: {
|
||||
name: data,
|
||||
},
|
||||
}));
|
||||
}
|
||||
const addNewAlbum = (data: string): Promise<Album> => {
|
||||
return storeAlbum.update(AlbumResource.post({
|
||||
restConfig: session.getRestConfig(),
|
||||
data: {
|
||||
name: data,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TopBar title="Add new media" />
|
||||
@ -584,10 +593,9 @@ export const AddPage = () => {
|
||||
</Flex>
|
||||
{parsedElement && parsedElement.length !== 0 && (<>
|
||||
<Text fontSize="30px">Meta-data:</Text>
|
||||
<FormSelect label="Gender" form={form} variableName='genderId' options={dataGenders} keyInputValue='name' />
|
||||
<FormSelect label="Artist" form={form} variableName='artistId' options={dataArtist} keyInputValue='name' />
|
||||
<FormInput label="Album Title (TODO: fusion with next)" isRequired form={form} variableName='title' />
|
||||
<FormSelect label="Album" form={form} variableName='albumId' options={dataAlbums} keyInputValue='name' />
|
||||
<FormSelect label="Gender" form={form} variableName='genderId' options={dataGenders} keyInputValue='name' addNewItem={addNewGender} />
|
||||
<FormSelect label="Artist" form={form} variableName='artistId' options={dataArtist} keyInputValue='name' addNewItem={addNewArtist} suggestion={suggestedArtist} />
|
||||
<FormSelect label="Album" form={form} variableName='albumId' options={dataAlbums} keyInputValue='name' addNewItem={addNewAlbum} suggestion={suggestedAlbum} />
|
||||
<TableContainer>
|
||||
<Table variant='striped' colorScheme='teal' background="gray.700">
|
||||
<Thead>
|
||||
@ -605,13 +613,13 @@ export const AddPage = () => {
|
||||
placeholder="e?"
|
||||
value={data.trackId}
|
||||
onChange={e => onTrackId(data, e.target.value)}
|
||||
//[class.error]="data.trackIdDetected === true"
|
||||
backgroundColor={data.trackIdDetected === true ? "darkred" : undefined}
|
||||
/></Td>
|
||||
<Td><Input type="text"
|
||||
placeholder="Name of the Media"
|
||||
value={data.title}
|
||||
onChange={e => onTitle(data, e.target.value)}
|
||||
//[class.error]="data.title === ''"
|
||||
backgroundColor={data.title === '' ? "darkred" : undefined}
|
||||
/>
|
||||
{data.nameDetected === true &&
|
||||
<><br />
|
||||
|
@ -15,7 +15,7 @@ export type DataStoreType<TYPE> = {
|
||||
data: TYPE[];
|
||||
get: <MODEL>(value: MODEL, key?: string) => TYPE | undefined;
|
||||
gets: <MODEL>(value: MODEL[] | undefined, key?: string) => TYPE[];
|
||||
update: (request: Promise<TYPE>, key?: string) => void;
|
||||
update: (request: Promise<TYPE>, key?: string) => Promise<TYPE>;
|
||||
remove: (id: number | string, request: Promise<void>, key?: string) => void;
|
||||
};
|
||||
|
||||
@ -96,19 +96,23 @@ export const useDataStore = <TYPE>(
|
||||
);
|
||||
|
||||
const update = useCallback(
|
||||
(request: Promise<TYPE>, key?: string) => {
|
||||
(request: Promise<TYPE>, key?: string): Promise<TYPE> => {
|
||||
const keyValue = key ?? primaryKey;
|
||||
request
|
||||
.then((responseData: TYPE) => {
|
||||
const filterData = data.filter(
|
||||
(localData: TYPE) => localData[keyValue] !== responseData[keyValue]
|
||||
);
|
||||
filterData.push(responseData);
|
||||
setData(filterData);
|
||||
})
|
||||
.catch((error: RestErrorResponse) => {
|
||||
toastAPIError(error);
|
||||
});
|
||||
return new Promise((resolve, rejects) => {
|
||||
request
|
||||
.then((responseData: TYPE) => {
|
||||
const filterData = data.filter(
|
||||
(localData: TYPE) => localData[keyValue] !== responseData[keyValue]
|
||||
);
|
||||
filterData.push(responseData);
|
||||
setData(filterData);
|
||||
resolve(responseData);
|
||||
})
|
||||
.catch((error: RestErrorResponse) => {
|
||||
toastAPIError(error);
|
||||
rejects(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
[data, setData]
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user