[DEV] add checker

This commit is contained in:
Edouard DUPIN 2024-09-19 21:22:35 +02:00
parent 725cd54d92
commit e9af64405b
13 changed files with 425 additions and 215 deletions

View File

@ -20,7 +20,7 @@
<dependency>
<groupId>kangaroo-and-rabbit</groupId>
<artifactId>archidata</artifactId>
<version>0.14.2</version>
<version>0.14.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>

View File

@ -12,8 +12,10 @@ import org.kar.archidata.annotation.TypeScriptProgress;
import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.dataAccess.addOn.AddOnDataJson;
import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
import org.kar.archidata.dataAccess.options.CheckFunction;
import org.kar.archidata.tools.DataTools;
import org.kar.karusic.model.Album;
import org.kar.karusic.model.Album.AlbumChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -33,6 +35,7 @@ import jakarta.ws.rs.core.MediaType;
@Produces({ MediaType.APPLICATION_JSON })
public class AlbumResource {
private static final Logger LOGGER = LoggerFactory.getLogger(AlbumResource.class);
static final AlbumChecker CHECKER = new AlbumChecker();
@GET
@Path("{id}")
@ -53,8 +56,8 @@ public class AlbumResource {
@RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON)
@Operation(description = "Add an album (when all the data already exist)")
public Album post(@AsyncType(Album.class) final String jsonRequest) throws Exception {
return DataAccess.insertWithJson(Album.class, jsonRequest);
public Album post(final Album data) throws Exception {
return DataAccess.insert(data, new CheckFunction(CHECKER));
}
@PATCH
@ -63,7 +66,7 @@ public class AlbumResource {
@Consumes(MediaType.APPLICATION_JSON)
@Operation(description = "Update a specific album")
public Album patch(@PathParam("id") final Long id, @AsyncType(Album.class) final String jsonRequest) throws Exception {
DataAccess.updateWithJson(Album.class, id, jsonRequest);
DataAccess.updateWithJson(Album.class, id, jsonRequest, new CheckFunction(CHECKER));
return DataAccess.get(Album.class, id);
}

View File

@ -11,8 +11,10 @@ import org.kar.archidata.annotation.FormDataOptional;
import org.kar.archidata.annotation.TypeScriptProgress;
import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.dataAccess.addOn.AddOnDataJson;
import org.kar.archidata.dataAccess.options.CheckFunction;
import org.kar.archidata.tools.DataTools;
import org.kar.karusic.model.Artist;
import org.kar.karusic.model.Artist.ArtistChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -31,6 +33,7 @@ import jakarta.ws.rs.core.MediaType;
@Produces({ MediaType.APPLICATION_JSON })
public class ArtistResource {
private static final Logger LOGGER = LoggerFactory.getLogger(ArtistResource.class);
static final ArtistChecker CHECKER = new ArtistChecker();
@GET
@Path("{id}")
@ -48,8 +51,8 @@ public class ArtistResource {
@POST
@RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON)
public Artist post(@AsyncType(Artist.class) final String jsonRequest) throws Exception {
return DataAccess.insertWithJson(Artist.class, jsonRequest);
public Artist post(final Artist data) throws Exception {
return DataAccess.insert(data, new CheckFunction(CHECKER));
}
@PATCH
@ -57,7 +60,7 @@ public class ArtistResource {
@RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON)
public Artist patch(@PathParam("id") final Long id, @AsyncType(Artist.class) final String jsonRequest) throws Exception {
DataAccess.updateWithJson(Artist.class, id, jsonRequest);
DataAccess.updateWithJson(Artist.class, id, jsonRequest, new CheckFunction(CHECKER));
return DataAccess.get(Artist.class, id);
}

View File

@ -11,8 +11,10 @@ import org.kar.archidata.annotation.FormDataOptional;
import org.kar.archidata.annotation.TypeScriptProgress;
import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.dataAccess.addOn.AddOnDataJson;
import org.kar.archidata.dataAccess.options.CheckFunction;
import org.kar.archidata.tools.DataTools;
import org.kar.karusic.model.Gender;
import org.kar.karusic.model.Gender.GenderChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -31,6 +33,7 @@ import jakarta.ws.rs.core.MediaType;
@Produces({ MediaType.APPLICATION_JSON })
public class GenderResource {
private static final Logger LOGGER = LoggerFactory.getLogger(GenderResource.class);
static final GenderChecker CHECKER = new GenderChecker();
@GET
@Path("{id}")
@ -48,8 +51,8 @@ public class GenderResource {
@POST
@RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON)
public Gender post(@AsyncType(Gender.class) final String jsonRequest) throws Exception {
return DataAccess.insertWithJson(Gender.class, jsonRequest);
public Gender post(final Gender data) throws Exception {
return DataAccess.insert(data, new CheckFunction(CHECKER));
}
@PATCH
@ -57,7 +60,7 @@ public class GenderResource {
@RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON)
public Gender patch(@PathParam("id") final Long id, @AsyncType(Gender.class) final String jsonRequest) throws Exception {
DataAccess.updateWithJson(Gender.class, id, jsonRequest);
DataAccess.updateWithJson(Gender.class, id, jsonRequest, new CheckFunction(CHECKER));
return DataAccess.get(Gender.class, id);
}

View File

@ -10,8 +10,10 @@ import org.kar.archidata.annotation.AsyncType;
import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.dataAccess.addOn.AddOnDataJson;
import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
import org.kar.archidata.dataAccess.options.CheckFunction;
import org.kar.archidata.tools.DataTools;
import org.kar.karusic.model.Playlist;
import org.kar.karusic.model.Track.TrackChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -30,6 +32,7 @@ import jakarta.ws.rs.core.MediaType;
@Produces({ MediaType.APPLICATION_JSON })
public class PlaylistResource {
private static final Logger LOGGER = LoggerFactory.getLogger(PlaylistResource.class);
static final TrackChecker CHECKER = new TrackChecker();
@GET
@Path("{id}")
@ -47,8 +50,8 @@ public class PlaylistResource {
@POST
@RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON)
public Playlist post(@AsyncType(Playlist.class) final String jsonRequest) throws Exception {
return DataAccess.insertWithJson(Playlist.class, jsonRequest);
public Playlist post(final Playlist data) throws Exception {
return DataAccess.insert(data, new CheckFunction(CHECKER));
}
@PATCH
@ -56,7 +59,7 @@ public class PlaylistResource {
@RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON)
public Playlist patch(@PathParam("id") final Long id, @AsyncType(Playlist.class) final String jsonRequest) throws Exception {
DataAccess.updateWithJson(Playlist.class, id, jsonRequest);
DataAccess.updateWithJson(Playlist.class, id, jsonRequest, new CheckFunction(CHECKER));
return DataAccess.get(Playlist.class, id);
}

View File

@ -15,9 +15,11 @@ import org.kar.archidata.annotation.TypeScriptProgress;
import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.dataAccess.addOn.AddOnDataJson;
import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
import org.kar.archidata.dataAccess.options.CheckFunction;
import org.kar.archidata.model.Data;
import org.kar.archidata.tools.DataTools;
import org.kar.karusic.model.Track;
import org.kar.karusic.model.Track.TrackChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -37,6 +39,7 @@ import jakarta.ws.rs.core.Response;
@Produces({ MediaType.APPLICATION_JSON })
public class TrackResource {
private static final Logger LOGGER = LoggerFactory.getLogger(TrackResource.class);
static final TrackChecker CHECKER = new TrackChecker();
@GET
@Path("{id}")
@ -54,17 +57,16 @@ public class TrackResource {
@POST
@RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON)
public Track post(@AsyncType(Track.class) final String jsonRequest) throws Exception {
return DataAccess.insertWithJson(Track.class, jsonRequest);
public Track post(final Track data) throws Exception {
return DataAccess.insert(data, new CheckFunction(CHECKER));
}
@PATCH
@Path("{id}")
@RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON)
public Track patch(@PathParam("id") final Long id, @AsyncType(Track.class) final String jsonRequest)
throws Exception {
DataAccess.updateWithJson(Track.class, id, jsonRequest);
public Track patch(@PathParam("id") final Long id, @AsyncType(Track.class) final String jsonRequest) throws Exception {
DataAccess.updateWithJson(Track.class, id, jsonRequest, new CheckFunction(CHECKER));
return DataAccess.get(Track.class, id);
}
@ -87,8 +89,7 @@ public class TrackResource {
@DELETE
@Path("{id}/artist/{trackId}")
@RolesAllowed("ADMIN")
public Track removeTrack(@PathParam("id") final Long id, @PathParam("artistId") final Long artistId)
throws Exception {
public Track removeTrack(@PathParam("id") final Long id, @PathParam("artistId") final Long artistId) throws Exception {
AddOnManyToMany.removeLink(Track.class, id, "artist", artistId);
return DataAccess.get(Track.class, id);
}
@ -111,8 +112,7 @@ public class TrackResource {
@DELETE
@Path("{id}/cover/{coverId}")
@RolesAllowed("ADMIN")
public Track removeCover(@PathParam("id") final Long id, @PathParam("coverId") final UUID coverId)
throws Exception {
public Track removeCover(@PathParam("id") final Long id, @PathParam("coverId") final UUID coverId) throws Exception {
AddOnDataJson.removeLink(Track.class, id, "covers", coverId);
return DataAccess.get(Track.class, id);
}
@ -121,7 +121,6 @@ public class TrackResource {
@Path("upload/")
@RolesAllowed("ADMIN")
@Consumes({ MediaType.MULTIPART_FORM_DATA })
// Formatter:off
@AsyncType(Track.class)
@TypeScriptProgress
public Response uploadTrack( //
@ -133,7 +132,6 @@ public class TrackResource {
@FormDataParam("file") final InputStream fileInputStream, //
@FormDataParam("file") final FormDataContentDisposition fileMetaData //
) {
// Formatter:on
try {
// correct input string stream :
trackId = DataTools.multipartCorrection(trackId);
@ -190,7 +188,7 @@ public class TrackResource {
trackElem.artists = new ArrayList<>();
trackElem.artists.add(artistId != null ? Long.parseLong(artistId) : null);
}
trackElem = DataAccess.insert(trackElem);
trackElem = DataAccess.insert(trackElem, new CheckFunction(CHECKER));
/* Old mode of artist insertion (removed due to the slowlest request of getting value if (artistElem != null) { DataAccess.addLink(Track.class, trackElem.id, "artist", artistElem.id); } */
return Response.ok(trackElem).build();
} catch (final Exception ex) {

View File

@ -6,6 +6,7 @@ import java.util.UUID;
import org.kar.archidata.annotation.DataIfNotExists;
import org.kar.archidata.annotation.DataJson;
import org.kar.archidata.dataAccess.options.CheckJPA;
import org.kar.archidata.model.Data;
import org.kar.archidata.model.GenericDataSoftDelete;
@ -20,6 +21,12 @@ import jakarta.persistence.Table;
@DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Album extends GenericDataSoftDelete {
public static class AlbumChecker extends CheckJPA<Album> {
public AlbumChecker() {
super(Album.class);
}
}
@Column(length = 256)
public String name = null;
@Column(length = 0)

View File

@ -6,6 +6,7 @@ import java.util.UUID;
import org.kar.archidata.annotation.DataIfNotExists;
import org.kar.archidata.annotation.DataJson;
import org.kar.archidata.dataAccess.options.CheckJPA;
import org.kar.archidata.model.Data;
import org.kar.archidata.model.GenericDataSoftDelete;
@ -20,6 +21,12 @@ import jakarta.persistence.Table;
@DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Artist extends GenericDataSoftDelete {
public static class ArtistChecker extends CheckJPA<Artist> {
public ArtistChecker() {
super(Artist.class);
}
}
@Column(length = 256)
public String name = null;
@Column(length = 0)

View File

@ -17,6 +17,7 @@ import java.util.UUID;
import org.kar.archidata.annotation.DataIfNotExists;
import org.kar.archidata.annotation.DataJson;
import org.kar.archidata.dataAccess.options.CheckJPA;
import org.kar.archidata.model.Data;
import org.kar.archidata.model.GenericDataSoftDelete;
@ -31,6 +32,12 @@ import jakarta.persistence.Table;
@DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Gender extends GenericDataSoftDelete {
public static class GenderChecker extends CheckJPA<Gender> {
public GenderChecker() {
super(Gender.class);
}
}
@Column(length = 256)
public String name = null;
@Column(length = 0)

View File

@ -17,6 +17,7 @@ import java.util.UUID;
import org.kar.archidata.annotation.DataIfNotExists;
import org.kar.archidata.annotation.DataJson;
import org.kar.archidata.dataAccess.options.CheckJPA;
import org.kar.archidata.model.Data;
import org.kar.archidata.model.GenericDataSoftDelete;
@ -33,6 +34,12 @@ import jakarta.persistence.Table;
@DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Playlist extends GenericDataSoftDelete {
public static class PlaylistChecker extends CheckJPA<Playlist> {
public PlaylistChecker() {
super(Playlist.class);
}
}
@Column(length = 256)
public String name = null;
@Column(length = 0)

View File

@ -17,6 +17,7 @@ import java.util.UUID;
import org.kar.archidata.annotation.DataIfNotExists;
import org.kar.archidata.annotation.DataJson;
import org.kar.archidata.dataAccess.options.CheckJPA;
import org.kar.archidata.model.Data;
import org.kar.archidata.model.GenericDataSoftDelete;
@ -31,6 +32,13 @@ import jakarta.persistence.Table;
@DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Track extends GenericDataSoftDelete {
public static class TrackChecker extends CheckJPA<Track> {
public TrackChecker() {
super(Track.class);
}
}
@Column(length = 256)
public String name = null;
@Column(length = 0)

View File

@ -86,10 +86,9 @@ export const useFormidable = <TYPE extends object = object>({
setIsModify,
setIsFormModified,
]);
const reset = useCallback(() => {
const restoreValues = useCallback(() => {
setValues({ ...initialData });
},
[setValues, initialData]);
}, [setValues, initialData]);
const setValuesExternal = useCallback(
(data: object) => {
//console.log(`FORMIDABLE: setValuesExternal(${JSON.stringify(data)}) ==> keys=${Object.keys(data)}`);
@ -158,7 +157,7 @@ export const useFormidable = <TYPE extends object = object>({
getDeltaData,
isFormModified,
isModify,
reset,
restoreValues,
restoreValue,
setValues: setValuesExternal,
values,

View File

@ -1,26 +1,51 @@
import { Album, AlbumResource, Artist, ArtistResource, Gender, GenderResource, RestErrorResponse, Track, TrackResource } from '@/back-api';
import { useFormidable } from '@/components/form/Formidable';
import { useState } from 'react';
import {
Button,
Flex,
Input,
Table,
TableCaption,
TableContainer,
Tbody,
Td,
Text,
Tfoot,
Th,
Thead,
Tr,
} from '@chakra-ui/react';
import { LuTrash } from 'react-icons/lu';
import { MdCloudUpload, MdRemove } from 'react-icons/md';
import {
Album,
AlbumResource,
Artist,
ArtistResource,
Gender,
GenderResource,
RestErrorResponse,
Track,
TrackResource,
} from '@/back-api';
import { PageLayout } from '@/components/Layout/PageLayout';
import { TopBar } from '@/components/TopBar/TopBar';
import { FormInput } from '@/components/form/FormInput';
import { FormSelect } from '@/components/form/FormSelect';
import { PageLayout } from '@/components/Layout/PageLayout';
import { useFormidable } from '@/components/form/Formidable';
import { PopUpUploadProgress } from '@/components/popup/PopUpUploadProgress';
import { TopBar } from '@/components/TopBar/TopBar';
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';
import { LuTrash } from 'react-icons/lu';
import { MdCloudUpload, MdRemove } from 'react-icons/md';
export class ElementList {
constructor(
public id?: number,
public label?: string) {
public label?: string
) {
// nothing to do.
}
}
@ -33,7 +58,8 @@ export class FileParsedElement {
public title: string,
public artist?: string,
public album?: string,
public trackId?: number) {
public trackId?: number
) {
// nothing to do.
}
}
@ -41,7 +67,8 @@ export class FileFailParsedElement {
constructor(
public id: number,
public file: File,
public reason: string) {
public reason: string
) {
// nothing to do.
}
}
@ -50,18 +77,20 @@ type FormInsertData = {
genderId?: number;
artistId?: number;
titleAlbum?: string;
}
};
export const AddPage = () => {
const [parsedElement, setParsedElement] = useState<FileParsedElement[]>([]);
const [parsedFailedElement, setParsedFailedElement] = useState<FileFailParsedElement[] | undefined>(undefined);
const [parsedFailedElement, setParsedFailedElement] = useState<
FileFailParsedElement[] | undefined
>(undefined);
const [needSend, setNeedSend] = useState<boolean>(false);
// list of all files already registered in the bdd to compare with the current list of files.
const [listFileInBdd, setListFileInBdd] = useState<any[] | undefined>(undefined);
const [listFileInBdd, setListFileInBdd] = useState<any[] | undefined>(
undefined
);
const { dataGenders } = useOrderedGenders();
const { dataArtist } = useOrderedArtists();
@ -80,20 +109,21 @@ export const AddPage = () => {
}
let tmp = true;
for (let iii = 0; iii < parsedElement.length; iii++) {
if (isNullOrUndefined(parsedElement[iii].title) || parsedElement[iii].title === '') {
if (
isNullOrUndefined(parsedElement[iii].title) ||
parsedElement[iii].title === ''
) {
tmp = false;
}
}
setNeedSend(tmp);
}
};
const onTitle = (data: FileParsedElement, value: any): void => {
data.title = value;
setParsedElement([...parsedElement]);
updateNeedSend();
}
};
const removeElementFromList = (data: FileParsedElement, value: any): void => {
const parsedElementTmp = [...parsedElement];
@ -104,16 +134,22 @@ export const AddPage = () => {
}
}
setParsedElement(parsedElementTmp);
setParsedFailedElement((previous) => [...previous ?? [], new FileFailParsedElement(previous?.length ?? 0, data.file, 'Removed by user.')]);
setParsedFailedElement((previous) => [
...(previous ?? []),
new FileFailParsedElement(
previous?.length ?? 0,
data.file,
'Removed by user.'
),
]);
updateNeedSend();
}
};
const onTrackId = (data: FileParsedElement, value: any): void => {
data.trackId = value;
setParsedElement([...parsedElement]);
updateNeedSend();
}
};
const clearData = () => {
setParsedElement([]);
@ -122,7 +158,7 @@ export const AddPage = () => {
setSuggestedArtist(undefined);
setSuggestedAlbum(undefined);
}
};
const addFileWithMetaData = (file: File) => {
// parsedElement: FileParsedElement[] = [];
@ -131,7 +167,7 @@ export const AddPage = () => {
let trackIdNumber: number | undefined = undefined;
let title: string = '';
form.reset();
form.restoreValues();
console.log(`select file ${file.name}`);
let tmpName = file.name.replace(/[ \t]*-[ \t]*/g, '-');
@ -143,7 +179,7 @@ export const AddPage = () => {
artist = splitElement[0];
tmpName = tmpName.substring(artist.length + 1);
}
const splitElement2 = tmpName.split('\#');
const splitElement2 = tmpName.split('#');
if (splitElement2.length > 1) {
album = splitElement2[0];
tmpName = tmpName.substring(album.length + 1);
@ -167,9 +203,13 @@ export const AddPage = () => {
console.log(`==>${JSON.stringify(tmp)}`);
// add it in the list.
return tmp;
}
const [suggestedArtist, setSuggestedArtist] = useState<string | undefined>(undefined);
const [suggestedAlbum, setSuggestedAlbum] = useState<string | undefined>(undefined);
};
const [suggestedArtist, setSuggestedArtist] = useState<string | undefined>(
undefined
);
const [suggestedAlbum, setSuggestedAlbum] = useState<string | undefined>(
undefined
);
const onChangeFile = (value: any): void => {
clearData();
@ -188,38 +228,60 @@ export const AddPage = () => {
// clean different artist:
for (let iii = 1; iii < parsedElementTmp.length; iii++) {
console.log(`check artist [${iii + 1}/${parsedElementTmp.length}] '${parsedElementTmp[0].artist} !== ${parsedElementTmp[iii].artist}'`);
console.log(
`check artist [${iii + 1}/${parsedElementTmp.length}] '${parsedElementTmp[0].artist} !== ${parsedElementTmp[iii].artist}'`
);
if (parsedElementTmp[0].artist !== parsedElementTmp[iii].artist) {
parsedFailedElementTmp.push(new FileFailParsedElement(parsedFailedElementTmp.length, parsedElementTmp[iii].file, 'Remove from list due to wrong artist value'));
console.log(`Remove from list (!= artist) : [${iii + 1}/${parsedElementTmp.length}] '${parsedElementTmp[iii].file.name}'`);
parsedFailedElementTmp.push(
new FileFailParsedElement(
parsedFailedElementTmp.length,
parsedElementTmp[iii].file,
'Remove from list due to wrong artist value'
)
);
console.log(
`Remove from list (!= artist) : [${iii + 1}/${parsedElementTmp.length}] '${parsedElementTmp[iii].file.name}'`
);
parsedElementTmp.splice(iii, 1);
iii--;
}
}
// clean different album:
for (let iii = 1; iii < parsedElementTmp.length; iii++) {
console.log(`check album [${iii + 1}/${parsedElementTmp.length}] '${parsedElementTmp[0].album} !== ${parsedElementTmp[iii].album}'`);
console.log(
`check album [${iii + 1}/${parsedElementTmp.length}] '${parsedElementTmp[0].album} !== ${parsedElementTmp[iii].album}'`
);
if (parsedElementTmp[0].album !== parsedElementTmp[iii].album) {
parsedFailedElementTmp.push(new FileFailParsedElement(parsedFailedElementTmp.length, parsedElementTmp[iii].file, 'Remove from list due to wrong album value'));
console.log(`Remove from list (!= album) : [${iii + 1}/${parsedElementTmp.length}] '${parsedElementTmp[iii].file.name}'`);
parsedFailedElementTmp.push(
new FileFailParsedElement(
parsedFailedElementTmp.length,
parsedElementTmp[iii].file,
'Remove from list due to wrong album value'
)
);
console.log(
`Remove from list (!= album) : [${iii + 1}/${parsedElementTmp.length}] '${parsedElementTmp[iii].file.name}'`
);
parsedElementTmp.splice(iii, 1);
iii--;
}
}
setParsedElement(parsedElementTmp);
setParsedFailedElement(parsedFailedElementTmp);
console.log(`check : ${JSON.stringify(parsedElementTmp[0])}`)
console.log(`check : ${JSON.stringify(parsedElementTmp[0])}`);
// find artistId:
console.log(`try find artist : ${parsedElementTmp[0].artist}`);
let artistFound = false;
dataArtist.forEach((data) => {
if (data.name?.toLowerCase() === parsedElementTmp[0].artist?.toLowerCase()) {
if (
data.name?.toLowerCase() === parsedElementTmp[0].artist?.toLowerCase()
) {
console.log(` find artist : ${data.id}`);
form.setValues({ artistId: data.id });
artistFound = true;
}
})
});
if (!artistFound) {
console.log(` set Suggested artist : ${parsedElementTmp[0].artist}`);
setSuggestedArtist(parsedElementTmp[0].artist);
@ -230,18 +292,20 @@ export const AddPage = () => {
console.log(`try find album : ${parsedElementTmp[0].album}`);
let albumFound = false;
dataAlbums.forEach((data) => {
if (data.name?.toLowerCase() === parsedElementTmp[0].album?.toLowerCase()) {
if (
data.name?.toLowerCase() === parsedElementTmp[0].album?.toLowerCase()
) {
console.log(` find album : ${data.id}`);
form.setValues({ albumId: data.id });
albumFound = true;
}
})
});
if (!albumFound) {
console.log(` set Suggested album : ${parsedElementTmp[0].album}`);
setSuggestedAlbum(parsedElementTmp[0].album);
}
updateNeedSend();
}
};
const [indexUpload, setIndexUpload] = useState<number | undefined>(undefined);
const [listValues, setListValues] = useState<string[]>([]);
@ -254,35 +318,37 @@ export const AddPage = () => {
}
const uploadNext = (): void => {
setIndexUpload((previous) => (previous ?? -1 + 1));
setIndexUpload((previous) => previous ?? -1 + 1);
TrackResource.uploadTrack({
restConfig: session.getRestConfig(),
data: {
title: parsedElement[0].title,
file: parsedElement[0].file,
albumId: form.values['albumId'],
artistId: form.values['artistId'],
genderId: form.values['genderId'],
trackId: parsedElement[0].trackId,
}, callbacks: {
progressUpload: progressUpload
}
}).then((data: Track) => {
// TODO: add the element in the local base...
console.log(`element added: ${JSON.stringify(data, null, 2)}`);
}).catch((error: RestErrorResponse) => {
// TODO: manage error
console.log(`element error: ${JSON.stringify(error, null, 2)}`);
});
}
albumId: form.values['albumId'] ?? undefined,
artistId: form.values['artistId'] ?? undefined,
genderId: form.values['genderId'] ?? undefined,
trackId: parsedElement[0].trackId ?? undefined,
},
callbacks: {
progressUpload: progressUpload,
},
})
.then((data: Track) => {
// TODO: add the element in the local base...
console.log(`element added: ${JSON.stringify(data, null, 2)}`);
})
.catch((error: RestErrorResponse) => {
// TODO: manage error
console.log(`element error: ${JSON.stringify(error, null, 2)}`);
});
};
const sendFile = (): void => {
console.log(`Send file requested ... ${parsedElement.length}`);
setListValues(parsedElement.map((element) => element.file.name));
uploadNext();
}
};
function onUploadAbort(): void {
//throw new Error('Function not implemented.');
@ -293,30 +359,35 @@ export const AddPage = () => {
}
const addNewGender = (data: string): Promise<Gender> => {
return storeGender.update(GenderResource.post({
restConfig: session.getRestConfig(),
data: {
name: data,
},
}));
}
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,
},
}));
}
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 storeAlbum.update(
AlbumResource.post({
restConfig: session.getRestConfig(),
data: {
name: data,
},
})
);
};
return (
<>
@ -333,111 +404,205 @@ export const AddPage = () => {
<Flex>
<Text flex={1}>format:</Text>
<Text flex={4}>
The format of the media permit to automatic find meta-data:<br />
Artist~album#idTrack-my name of my media.webm<br />
<b>example:</b> Clarika~Moi En Mieux#22-des bulles.webm</Text>
The format of the media permit to automatic find meta-data:
<br />
Artist~album#idTrack-my name of my media.webm
<br />
<b>example:</b> Clarika~Moi En Mieux#22-des bulles.webm
</Text>
</Flex>
<Flex>
<Text flex={1}>Media:</Text>
<Input flex={4} type="file" placeholder="Select a media file"
accept=".webm" multiple onChange={onChangeFile} />
<Input
flex={4}
type="file"
placeholder="Select a media file"
accept=".webm"
multiple
onChange={onChangeFile}
/>
</Flex>
</Flex>
{parsedElement && parsedElement.length !== 0 && (<>
<Text fontSize="30px">Meta-data:</Text>
<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>
<Tr>
<Th>track ID</Th>
<Th width="full">Title</Th>
<Th>actions</Th>
</Tr>
</Thead>
<Tbody>
{parsedElement.map((data) => (
<Tr key={data.file.name}>
<Td><Input type="number"
pattern="[0-9]{0-4}"
placeholder="e?"
value={data.trackId}
onChange={e => onTrackId(data, e.target.value)}
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)}
backgroundColor={data.title === '' ? "darkred" : undefined}
/>
{data.nameDetected === true &&
<><br />
<Text as="span" color="@danger">
^^^This title already exist !!!
</Text>
</>
}</Td>
<Td><Button onClick={e => removeElementFromList(data, e.target)}>
<LuTrash /> Remove
</Button></Td>
</Tr>))}
</Tbody>
</Table>
<Flex marginY="15px">
<Button variant="@primary" onClick={sendFile} disabled={!needSend} marginLeft="auto" marginRight="30px">
<MdCloudUpload /> Upload
</Button>
</Flex>
</TableContainer>
</>)}
{listFileInBdd && (<>
<TableContainer>
<Table variant='striped' colorScheme='teal' background="gray.700">
<Thead>
<Tr>
<Th>track ID</Th>
<Th width="full">Title</Th>
<Th>actions</Th>
</Tr>
</Thead>
<Tbody>
{listFileInBdd.map((data) => (
{parsedElement && parsedElement.length !== 0 && (
<>
<Text fontSize="30px">Meta-data:</Text>
<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>
<Tr>
<Td><Text color={data.episodeDetected === true ? "red" : undefined}>{data.trackId}</Text></Td>
<Td><Text color={data.nameDetected === true ? "red" : undefined}>{data.title}</Text></Td>
<Td></Td>
</Tr>))}
</Tbody>
</Table>
</TableContainer>
</>)}
<Th>track ID</Th>
<Th width="full">Title</Th>
<Th>actions</Th>
</Tr>
</Thead>
<Tbody>
{parsedElement.map((data) => (
<Tr key={data.file.name}>
<Td>
<Input
type="number"
pattern="[0-9]{0-4}"
placeholder="e?"
value={data.trackId}
onChange={(e) => onTrackId(data, e.target.value)}
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)}
backgroundColor={
data.title === '' ? 'darkred' : undefined
}
/>
{data.nameDetected === true && (
<>
<br />
<Text as="span" color="@danger">
^^^This title already exist !!!
</Text>
</>
)}
</Td>
<Td>
<Button
onClick={(e) =>
removeElementFromList(data, e.target)
}
>
<LuTrash /> Remove
</Button>
</Td>
</Tr>
))}
</Tbody>
</Table>
<Flex marginY="15px">
<Button
variant="@primary"
onClick={sendFile}
disabled={!needSend}
marginLeft="auto"
marginRight="30px"
>
<MdCloudUpload /> Upload
</Button>
</Flex>
</TableContainer>
</>
)}
{parsedFailedElement && (<>
<Text fontSize="30px">Rejected:</Text>
<TableContainer>
<Table variant='striped' colorScheme='teal' background="gray.700">
<Thead>
<Tr>
<Th maxWidth='80%'>file</Th>
<Th>Reason</Th>
</Tr>
</Thead>
<Tbody>
{parsedFailedElement.map((data) => (
<Tr key={data.file.name}>
<Td>{data.file.name}</Td>
<Td>{data.reason}</Td>
</Tr>))}
</Tbody>
</Table>
</TableContainer>
</>)}
{listFileInBdd && (
<>
<TableContainer>
<Table
variant="striped"
colorScheme="teal"
background="gray.700"
>
<Thead>
<Tr>
<Th>track ID</Th>
<Th width="full">Title</Th>
<Th>actions</Th>
</Tr>
</Thead>
<Tbody>
{listFileInBdd.map((data) => (
<Tr>
<Td>
<Text
color={
data.episodeDetected === true ? 'red' : undefined
}
>
{data.trackId}
</Text>
</Td>
<Td>
<Text
color={
data.nameDetected === true ? 'red' : undefined
}
>
{data.title}
</Text>
</Td>
<Td></Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</>
)}
{parsedFailedElement && (
<>
<Text fontSize="30px">Rejected:</Text>
<TableContainer>
<Table
variant="striped"
colorScheme="teal"
background="gray.700"
>
<Thead>
<Tr>
<Th maxWidth="80%">file</Th>
<Th>Reason</Th>
</Tr>
</Thead>
<Tbody>
{parsedFailedElement.map((data) => (
<Tr key={data.file.name}>
<Td>{data.file.name}</Td>
<Td>{data.reason}</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</>
)}
</Flex>
{indexUpload !== undefined &&
{indexUpload !== undefined && (
<PopUpUploadProgress
title="Upload File(s)"
currentSize={currentPosition}
@ -445,10 +610,10 @@ export const AddPage = () => {
index={indexUpload}
elements={listValues}
onAbort={onUploadAbort}
onClose={OnUploadClose} />
}
</PageLayout >
onClose={OnUploadClose}
/>
)}
</PageLayout>
</>
);
};