[FEAT] continue integration
This commit is contained in:
parent
091390e025
commit
dc7131843d
12
back/pom.xml
12
back/pom.xml
@ -25,12 +25,12 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>2.0.9</version>
|
||||
<version>2.1.0-alpha1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>2.16.1</version>
|
||||
<version>2.18.0-rc1</version>
|
||||
</dependency>
|
||||
<!--
|
||||
************************************************************
|
||||
@ -40,24 +40,24 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.10.1</version>
|
||||
<version>5.11.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.10.1</version>
|
||||
<version>5.11.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.revelc.code.formatter</groupId>
|
||||
<artifactId>formatter-maven-plugin</artifactId>
|
||||
<version>2.24.0</version>
|
||||
<version>2.24.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<version>3.5.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
|
@ -1,6 +1,11 @@
|
||||
package org.kar.karusic;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.ImageWriter;
|
||||
|
||||
import org.glassfish.grizzly.http.server.HttpServer;
|
||||
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
|
||||
@ -10,6 +15,7 @@ import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.kar.archidata.GlobalConfiguration;
|
||||
import org.kar.archidata.UpdateJwtPublicKey;
|
||||
import org.kar.archidata.api.DataResource;
|
||||
import org.kar.archidata.api.ProxyResource;
|
||||
import org.kar.archidata.catcher.GenericCatcher;
|
||||
import org.kar.archidata.filter.CORSFilter;
|
||||
import org.kar.archidata.filter.OptionFilter;
|
||||
@ -28,6 +34,7 @@ import org.kar.karusic.migration.Initialization;
|
||||
import org.kar.karusic.migration.Migration20231126;
|
||||
import org.kar.karusic.migration.Migration20240225;
|
||||
import org.kar.karusic.migration.Migration20240226;
|
||||
import org.kar.karusic.migration.Migration20240907;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -55,6 +62,7 @@ public class WebLauncher {
|
||||
migrationEngine.add(new Migration20231126());
|
||||
migrationEngine.add(new Migration20240225());
|
||||
migrationEngine.add(new Migration20240226());
|
||||
migrationEngine.add(new Migration20240907());
|
||||
WebLauncher.LOGGER.info("Migrate the DB [START]");
|
||||
migrationEngine.migrateWaitAdmin(GlobalConfiguration.dbConfig);
|
||||
WebLauncher.LOGGER.info("Migrate the DB [STOP]");
|
||||
@ -64,7 +72,7 @@ public class WebLauncher {
|
||||
WebLauncher.LOGGER.info("[START] application wake UP");
|
||||
final WebLauncher launcher = new WebLauncher();
|
||||
launcher.migrateDB();
|
||||
|
||||
|
||||
launcher.process();
|
||||
WebLauncher.LOGGER.info("end-configure the server & wait finish process:");
|
||||
Thread.currentThread().join();
|
||||
@ -73,7 +81,34 @@ public class WebLauncher {
|
||||
WebLauncher.LOGGER.info("STOP the REST server:");
|
||||
}
|
||||
|
||||
public void plop(final String aaa) {
|
||||
// List available Image Readers
|
||||
System.out.println("Available Image Readers:");
|
||||
final Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(aaa);
|
||||
while (readers.hasNext()) {
|
||||
final ImageReader reader = readers.next();
|
||||
System.out.println("Reader: " + reader.getOriginatingProvider().getDescription(null));
|
||||
System.out.println("Reader CN: " + reader.getOriginatingProvider().getPluginClassName());
|
||||
//ImageIO.deregisterServiceProvider(reader.getOriginatingProvider());
|
||||
}
|
||||
|
||||
// List available Image Writers
|
||||
System.out.println("\nAvailable Image Writers:");
|
||||
final Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(aaa);
|
||||
while (writers.hasNext()) {
|
||||
final ImageWriter writer = writers.next();
|
||||
System.out.println("Writer: " + writer.getOriginatingProvider().getDescription(null));
|
||||
System.out.println("Writer CN: " + writer.getOriginatingProvider().getPluginClassName());
|
||||
}
|
||||
}
|
||||
|
||||
public void process() throws InterruptedException {
|
||||
|
||||
ImageIO.scanForPlugins();
|
||||
plop("jpeg");
|
||||
plop("png");
|
||||
plop("webmp");
|
||||
plop("webp");
|
||||
// ===================================================================
|
||||
// Configure resources
|
||||
// ===================================================================
|
||||
@ -97,6 +132,7 @@ public class WebLauncher {
|
||||
rc.register(PlaylistResource.class);
|
||||
rc.register(TrackResource.class);
|
||||
rc.register(DataResource.class);
|
||||
rc.register(ProxyResource.class);
|
||||
|
||||
rc.register(HealthCheck.class);
|
||||
rc.register(Front.class);
|
||||
|
@ -3,6 +3,7 @@ package org.kar.karusic;
|
||||
import java.util.List;
|
||||
|
||||
import org.kar.archidata.api.DataResource;
|
||||
import org.kar.archidata.api.ProxyResource;
|
||||
import org.kar.archidata.externalRestApi.AnalyzeApi;
|
||||
import org.kar.archidata.externalRestApi.TsGenerateApi;
|
||||
import org.kar.archidata.tools.ConfigBaseVariable;
|
||||
@ -19,20 +20,20 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
public class WebLauncherLocal extends WebLauncher {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(WebLauncherLocal.class);
|
||||
|
||||
|
||||
private WebLauncherLocal() {}
|
||||
|
||||
|
||||
public static void generateObjects() throws Exception {
|
||||
LOGGER.info("Generate APIs");
|
||||
final List<Class<?>> listOfResources = List.of(AlbumResource.class, ArtistResource.class, Front.class,
|
||||
GenderResource.class, HealthCheck.class, PlaylistResource.class, UserResource.class,
|
||||
TrackResource.class, DataResource.class);
|
||||
TrackResource.class, DataResource.class, ProxyResource.class);
|
||||
final AnalyzeApi api = new AnalyzeApi();
|
||||
api.addAllApi(listOfResources);
|
||||
TsGenerateApi.generateApi(api, "../front2/src/back-api/");
|
||||
LOGGER.info("Generate APIs (DONE)");
|
||||
}
|
||||
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
generateObjects();
|
||||
final WebLauncherLocal launcher = new WebLauncherLocal();
|
||||
@ -41,7 +42,7 @@ public class WebLauncherLocal extends WebLauncher {
|
||||
Thread.currentThread().join();
|
||||
launcher.LOGGER.info("STOP the REST server:");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void process() throws InterruptedException {
|
||||
if (true) {
|
||||
|
@ -100,13 +100,18 @@ public class AlbumResource {
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||
@Operation(description = "Add a cover on a specific album")
|
||||
@AsyncType(Album.class)
|
||||
@TypeScriptProgress
|
||||
public void uploadCover(
|
||||
public Album uploadCover(
|
||||
@PathParam("id") final Long id,
|
||||
@FormDataParam("uri") final String uri,
|
||||
@FormDataParam("file") final InputStream fileInputStream,
|
||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
||||
DataTools.uploadCover(Album.class, id, fileInputStream, fileMetaData);
|
||||
if (uri != null) {
|
||||
DataTools.uploadCoverFromUri(Album.class, id, uri);
|
||||
} else {
|
||||
DataTools.uploadCover(Album.class, id, fileInputStream, fileMetaData);
|
||||
}
|
||||
return DataAccess.get(Album.class, id);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
|
@ -30,27 +30,27 @@ import jakarta.ws.rs.core.MediaType;
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public class ArtistResource {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ArtistResource.class);
|
||||
|
||||
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@RolesAllowed("USER")
|
||||
public static Artist get(@PathParam("id") final Long id) throws Exception {
|
||||
return DataAccess.get(Artist.class, id);
|
||||
}
|
||||
|
||||
|
||||
@GET
|
||||
@RolesAllowed("USER")
|
||||
public List<Artist> gets() throws Exception {
|
||||
return DataAccess.gets(Artist.class);
|
||||
}
|
||||
|
||||
|
||||
@POST
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Artist post(@AsyncType(Artist.class) final String jsonRequest) throws Exception {
|
||||
return DataAccess.insertWithJson(Artist.class, jsonRequest);
|
||||
}
|
||||
|
||||
|
||||
@PATCH
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
@ -60,27 +60,32 @@ public class ArtistResource {
|
||||
DataAccess.updateWithJson(Artist.class, id, jsonRequest);
|
||||
return DataAccess.get(Artist.class, id);
|
||||
}
|
||||
|
||||
|
||||
@DELETE
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
public void remove(@PathParam("id") final Long id) throws Exception {
|
||||
DataAccess.delete(Artist.class, id);
|
||||
}
|
||||
|
||||
|
||||
@POST
|
||||
@Path("{id}/cover")
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||
@AsyncType(Artist.class)
|
||||
@TypeScriptProgress
|
||||
public void uploadCover(
|
||||
public Artist uploadCover(
|
||||
@PathParam("id") final Long id,
|
||||
@FormDataParam("uri") final String uri,
|
||||
@FormDataParam("file") final InputStream fileInputStream,
|
||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
||||
DataTools.uploadCover(Artist.class, id, fileInputStream, fileMetaData);
|
||||
if (uri != null) {
|
||||
DataTools.uploadCoverFromUri(Artist.class, id, uri);
|
||||
} else {
|
||||
DataTools.uploadCover(Artist.class, id, fileInputStream, fileMetaData);
|
||||
}
|
||||
return DataAccess.get(Artist.class, id);
|
||||
}
|
||||
|
||||
|
||||
@DELETE
|
||||
@Path("{id}/cover/{coverId}")
|
||||
@RolesAllowed("ADMIN")
|
||||
|
@ -72,13 +72,18 @@ public class GenderResource {
|
||||
@Path("{id}/cover")
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||
@AsyncType(Gender.class)
|
||||
@TypeScriptProgress
|
||||
public void uploadCover(
|
||||
public Gender uploadCover(
|
||||
@PathParam("id") final Long id,
|
||||
@FormDataParam("uri") final String uri,
|
||||
@FormDataParam("file") final InputStream fileInputStream,
|
||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
||||
DataTools.uploadCover(Gender.class, id, fileInputStream, fileMetaData);
|
||||
if (uri != null) {
|
||||
DataTools.uploadCoverFromUri(Gender.class, id, uri);
|
||||
} else {
|
||||
DataTools.uploadCover(Gender.class, id, fileInputStream, fileMetaData);
|
||||
}
|
||||
return DataAccess.get(Gender.class, id);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
|
@ -41,27 +41,27 @@ import jakarta.ws.rs.core.Response;
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public class TrackResource {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TrackResource.class);
|
||||
|
||||
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@RolesAllowed("USER")
|
||||
public static Track get(@PathParam("id") final Long id) throws Exception {
|
||||
return DataAccess.get(Track.class, id);
|
||||
}
|
||||
|
||||
|
||||
@GET
|
||||
@RolesAllowed("USER")
|
||||
public List<Track> gets() throws Exception {
|
||||
return DataAccess.gets(Track.class);
|
||||
}
|
||||
|
||||
|
||||
@POST
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Track post(@AsyncType(Track.class) final String jsonRequest) throws Exception {
|
||||
return DataAccess.insertWithJson(Track.class, jsonRequest);
|
||||
}
|
||||
|
||||
|
||||
@PATCH
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
@ -71,14 +71,14 @@ public class TrackResource {
|
||||
DataAccess.updateWithJson(Track.class, id, jsonRequest);
|
||||
return DataAccess.get(Track.class, id);
|
||||
}
|
||||
|
||||
|
||||
@DELETE
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
public void remove(@PathParam("id") final Long id) throws Exception {
|
||||
DataAccess.delete(Track.class, id);
|
||||
}
|
||||
|
||||
|
||||
@POST
|
||||
@Path("{id}/artist/{artistId}")
|
||||
@RolesAllowed("ADMIN")
|
||||
@ -87,7 +87,7 @@ public class TrackResource {
|
||||
AddOnManyToMany.removeLink(Track.class, id, "artist", artistId);
|
||||
return DataAccess.get(Track.class, id);
|
||||
}
|
||||
|
||||
|
||||
@DELETE
|
||||
@Path("{id}/artist/{trackId}")
|
||||
@RolesAllowed("ADMIN")
|
||||
@ -96,20 +96,25 @@ public class TrackResource {
|
||||
AddOnManyToMany.removeLink(Track.class, id, "artist", artistId);
|
||||
return DataAccess.get(Track.class, id);
|
||||
}
|
||||
|
||||
|
||||
@POST
|
||||
@Path("{id}/cover")
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||
@AsyncType(Track.class)
|
||||
@TypeScriptProgress
|
||||
public void uploadCover(
|
||||
public Track uploadCover(
|
||||
@PathParam("id") final Long id,
|
||||
@FormDataParam("uri") final String uri,
|
||||
@FormDataParam("file") final InputStream fileInputStream,
|
||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData) throws Exception {
|
||||
DataTools.uploadCover(Track.class, id, fileInputStream, fileMetaData);
|
||||
if (uri != null) {
|
||||
DataTools.uploadCoverFromUri(Track.class, id, uri);
|
||||
} else {
|
||||
DataTools.uploadCover(Track.class, id, fileInputStream, fileMetaData);
|
||||
}
|
||||
return DataAccess.get(Track.class, id);
|
||||
}
|
||||
|
||||
|
||||
@DELETE
|
||||
@Path("{id}/cover/{coverId}")
|
||||
@RolesAllowed("ADMIN")
|
||||
@ -118,7 +123,7 @@ public class TrackResource {
|
||||
AddOnDataJson.removeLink(Track.class, id, "covers", coverId);
|
||||
return DataAccess.get(Track.class, id);
|
||||
}
|
||||
|
||||
|
||||
@POST
|
||||
@Path("upload/")
|
||||
@RolesAllowed("ADMIN")
|
||||
@ -146,7 +151,7 @@ public class TrackResource {
|
||||
album = DataTools.multipartCorrection(album);
|
||||
trackId = DataTools.multipartCorrection(trackId);
|
||||
title = DataTools.multipartCorrection(title);
|
||||
|
||||
|
||||
//public NodeSmall uploadFile(final FormDataMultiPart form) {
|
||||
LOGGER.info("Upload media file: " + fileMetaData);
|
||||
LOGGER.info(" > fileName: " + fileName);
|
||||
@ -165,13 +170,13 @@ public class TrackResource {
|
||||
build();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
final long tmpUID = DataTools.getTmpDataId();
|
||||
final String sha512 = DataTools.saveTemporaryFile(fileInputStream, tmpUID);
|
||||
Data data = DataTools.getWithSha512(sha512);
|
||||
if (data == null) {
|
||||
LOGGER.info("Need to add the data in the BDD ... ");
|
||||
|
||||
|
||||
try {
|
||||
data = DataTools.createNewData(tmpUID, fileName, sha512);
|
||||
} catch (final IOException ex) {
|
||||
@ -207,7 +212,7 @@ public class TrackResource {
|
||||
// return Response.notModified("TypeId does not exist ...").build();
|
||||
// }
|
||||
LOGGER.info(" ==> genderElem={}", genderElem);
|
||||
|
||||
|
||||
Artist artistElem = null;
|
||||
if (artist != null) {
|
||||
LOGGER.info(" Try to find Artist: '{}'", artist);
|
||||
@ -220,7 +225,7 @@ public class TrackResource {
|
||||
}
|
||||
}
|
||||
LOGGER.info(" ==> artistElem={}", artistElem);
|
||||
|
||||
|
||||
Album albumElem = null;
|
||||
if (album != null) {
|
||||
albumElem = DataAccess.getWhere(Album.class, new Condition(new QueryCondition("name", "=", album)));
|
||||
@ -231,9 +236,9 @@ public class TrackResource {
|
||||
}
|
||||
}
|
||||
LOGGER.info(" ==> " + album);
|
||||
|
||||
|
||||
LOGGER.info("add media");
|
||||
|
||||
|
||||
Track trackElem = new Track();
|
||||
trackElem.name = title;
|
||||
trackElem.track = trackId != null ? Long.parseLong(trackId) : null;
|
||||
@ -259,5 +264,5 @@ public class TrackResource {
|
||||
return Response.status(417).entity("Back-end error : " + ex.getMessage()).type("text/plain").build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,29 @@ services:
|
||||
start_period: 1m
|
||||
start_interval: 1m
|
||||
|
||||
kar_mongodb_service:
|
||||
image: mongo:latest
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: root
|
||||
MONGO_INITDB_ROOT_PASSWORD: base_db_password
|
||||
ports:
|
||||
- 27017:27017
|
||||
volumes:
|
||||
- ./dataMongo:/data/db
|
||||
|
||||
mongo_express_service:
|
||||
image: mongo-express
|
||||
restart: always
|
||||
ports:
|
||||
- 8081:8081
|
||||
links:
|
||||
- kar_mongodb_service:db
|
||||
environment:
|
||||
ME_CONFIG_MONGODB_ADMINUSERNAME: root
|
||||
ME_CONFIG_MONGODB_ADMINPASSWORD: base_db_password
|
||||
ME_CONFIG_MONGODB_URL: mongodb://root:base_db_password@db:27017/
|
||||
ME_CONFIG_BASICAUTH: false
|
||||
|
||||
kar_adminer_service:
|
||||
image: adminer:latest
|
||||
restart: always
|
||||
@ -25,7 +48,7 @@ services:
|
||||
condition: service_healthy
|
||||
links:
|
||||
- kar_db_service:db
|
||||
- kar_mongodb_service:dbm
|
||||
ports:
|
||||
- 4079:8080
|
||||
mem_limit: 50m
|
||||
|
||||
|
@ -41,6 +41,9 @@ importers:
|
||||
'@formiz/core':
|
||||
specifier: 2.3.1
|
||||
version: 2.3.1(react@18.3.1)
|
||||
'@formiz/validations':
|
||||
specifier: 2.0.1
|
||||
version: 2.0.1
|
||||
allotment:
|
||||
specifier: 1.20.2
|
||||
version: 1.20.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@ -71,6 +74,9 @@ importers:
|
||||
react-dom:
|
||||
specifier: 18.3.1
|
||||
version: 18.3.1(react@18.3.1)
|
||||
react-dropzone:
|
||||
specifier: 14.2.3
|
||||
version: 14.2.3(react@18.3.1)
|
||||
react-error-boundary:
|
||||
specifier: 4.0.13
|
||||
version: 4.0.13(react@18.3.1)
|
||||
@ -102,8 +108,8 @@ importers:
|
||||
specifier: 0.4.7
|
||||
version: 0.4.7(react@18.3.1)
|
||||
react-virtuoso:
|
||||
specifier: 4.10.1
|
||||
version: 4.10.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
specifier: 4.10.2
|
||||
version: 4.10.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
ts-pattern:
|
||||
specifier: 5.3.1
|
||||
version: 5.3.1
|
||||
@ -140,7 +146,7 @@ importers:
|
||||
version: 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(typescript@5.5.4)
|
||||
'@storybook/react-vite':
|
||||
specifier: 8.2.9
|
||||
version: 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.21.1)(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.1))
|
||||
version: 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.21.1)(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.2)(terser@5.31.1))
|
||||
'@storybook/theming':
|
||||
specifier: 8.2.9
|
||||
version: 8.2.9(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))
|
||||
@ -160,8 +166,8 @@ importers:
|
||||
specifier: 29.5.12
|
||||
version: 29.5.12
|
||||
'@types/node':
|
||||
specifier: 22.5.1
|
||||
version: 22.5.1
|
||||
specifier: 22.5.2
|
||||
version: 22.5.2
|
||||
'@types/react':
|
||||
specifier: 18.3.5
|
||||
version: 18.3.5
|
||||
@ -179,7 +185,7 @@ importers:
|
||||
version: 8.3.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
|
||||
'@vitejs/plugin-react':
|
||||
specifier: 4.3.1
|
||||
version: 4.3.1(vite@5.4.2(@types/node@22.5.1)(terser@5.31.1))
|
||||
version: 4.3.1(vite@5.4.2(@types/node@22.5.2)(terser@5.31.1))
|
||||
eslint:
|
||||
specifier: 9.9.1
|
||||
version: 9.9.1(jiti@1.21.6)
|
||||
@ -200,13 +206,13 @@ importers:
|
||||
version: 0.8.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
|
||||
jest:
|
||||
specifier: 29.7.0
|
||||
version: 29.7.0(@types/node@22.5.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4))
|
||||
version: 29.7.0(@types/node@22.5.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4))
|
||||
jest-environment-jsdom:
|
||||
specifier: 29.7.0
|
||||
version: 29.7.0
|
||||
knip:
|
||||
specifier: 5.27.5
|
||||
version: 5.27.5(@types/node@22.5.1)(typescript@5.5.4)
|
||||
specifier: 5.29.1
|
||||
version: 5.29.1(@types/node@22.5.2)(typescript@5.5.4)
|
||||
lint-staged:
|
||||
specifier: 15.2.9
|
||||
version: 15.2.9
|
||||
@ -227,16 +233,16 @@ importers:
|
||||
version: 8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7))
|
||||
ts-node:
|
||||
specifier: 10.9.2
|
||||
version: 10.9.2(@types/node@22.5.1)(typescript@5.5.4)
|
||||
version: 10.9.2(@types/node@22.5.2)(typescript@5.5.4)
|
||||
typescript:
|
||||
specifier: 5.5.4
|
||||
version: 5.5.4
|
||||
vite:
|
||||
specifier: 5.4.2
|
||||
version: 5.4.2(@types/node@22.5.1)(terser@5.31.1)
|
||||
version: 5.4.2(@types/node@22.5.2)(terser@5.31.1)
|
||||
vitest:
|
||||
specifier: 2.0.5
|
||||
version: 2.0.5(@types/node@22.5.1)(jsdom@20.0.3)(terser@5.31.1)
|
||||
version: 2.0.5(@types/node@22.5.2)(jsdom@20.0.3)(terser@5.31.1)
|
||||
|
||||
packages:
|
||||
|
||||
@ -1824,6 +1830,9 @@ packages:
|
||||
peerDependencies:
|
||||
react: '>=18'
|
||||
|
||||
'@formiz/validations@2.0.1':
|
||||
resolution: {integrity: sha512-NZGluw3iWt7zw3oTiOwnttg7DCgB1SR0AMWVpdTYsaXDS54HwukwteaUqxii/FeGNliuRLYxtawnhMwa8YIhyA==}
|
||||
|
||||
'@humanwhocodes/module-importer@1.0.1':
|
||||
resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
|
||||
engines: {node: '>=12.22'}
|
||||
@ -2419,8 +2428,8 @@ packages:
|
||||
'@types/node@18.19.39':
|
||||
resolution: {integrity: sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==}
|
||||
|
||||
'@types/node@22.5.1':
|
||||
resolution: {integrity: sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==}
|
||||
'@types/node@22.5.2':
|
||||
resolution: {integrity: sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==}
|
||||
|
||||
'@types/parse-json@4.0.2':
|
||||
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
|
||||
@ -2774,6 +2783,10 @@ packages:
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
attr-accept@2.2.2:
|
||||
resolution: {integrity: sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
available-typed-arrays@1.0.7:
|
||||
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -3676,6 +3689,10 @@ packages:
|
||||
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
|
||||
file-selector@0.6.0:
|
||||
resolution: {integrity: sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
fill-range@7.1.1:
|
||||
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
||||
engines: {node: '>=8'}
|
||||
@ -4455,8 +4472,8 @@ packages:
|
||||
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
knip@5.27.5:
|
||||
resolution: {integrity: sha512-YkhFv/udMNGf6YUPU6enbDH2iPi7jq5d3K6egS0A2Qqk3M7+CuSF44f1uwQZH9chCyi3JJoJNxqyB8B0m/guxw==}
|
||||
knip@5.29.1:
|
||||
resolution: {integrity: sha512-l8qFtRqNpCk8xf46VOwhBUva7LBwanoGPJ4KQNwVRl6hmEXStf1BJlfbYRZ+yQpbilbIV6LN+ztX6LaGtyd4TQ==}
|
||||
engines: {node: '>=18.6.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@ -4731,10 +4748,6 @@ packages:
|
||||
micromark@4.0.0:
|
||||
resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==}
|
||||
|
||||
micromatch@4.0.5:
|
||||
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
micromatch@4.0.7:
|
||||
resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==}
|
||||
engines: {node: '>=8.6'}
|
||||
@ -5242,6 +5255,12 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^18.3.1
|
||||
|
||||
react-dropzone@14.2.3:
|
||||
resolution: {integrity: sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==}
|
||||
engines: {node: '>= 10.13'}
|
||||
peerDependencies:
|
||||
react: '>= 16.8 || 18.0.0'
|
||||
|
||||
react-element-to-jsx-string@15.0.0:
|
||||
resolution: {integrity: sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==}
|
||||
peerDependencies:
|
||||
@ -5378,8 +5397,8 @@ packages:
|
||||
react: '*'
|
||||
react-dom: '*'
|
||||
|
||||
react-virtuoso@4.10.1:
|
||||
resolution: {integrity: sha512-vDBt9AarmCjPNshw3VxPXW355ZQKSO0p9vrAJ0pi04TB6aXk+qHWTu8NuaQ3ppcd/Ub1r5ryRA4fJ2QGuH0H0g==}
|
||||
react-virtuoso@4.10.2:
|
||||
resolution: {integrity: sha512-os6n9QKeKRF+8mnQR/vGy/xrFf6vXIzuaAVL54q5k2st2d5QIEwI+KDKaflMUmMvnDbPxf68bs+CF5bY3YI7qA==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
react: '>=16 || >=17 || >= 18'
|
||||
@ -8383,6 +8402,8 @@ snapshots:
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
'@formiz/validations@2.0.1': {}
|
||||
|
||||
'@humanwhocodes/module-importer@1.0.1': {}
|
||||
|
||||
'@humanwhocodes/retry@0.3.0': {}
|
||||
@ -8400,27 +8421,27 @@ snapshots:
|
||||
'@jest/console@29.7.0':
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
chalk: 4.1.2
|
||||
jest-message-util: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
slash: 3.0.0
|
||||
|
||||
'@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4))':
|
||||
'@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4))':
|
||||
dependencies:
|
||||
'@jest/console': 29.7.0
|
||||
'@jest/reporters': 29.7.0
|
||||
'@jest/test-result': 29.7.0
|
||||
'@jest/transform': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
ansi-escapes: 4.3.2
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.9.0
|
||||
exit: 0.1.2
|
||||
graceful-fs: 4.2.11
|
||||
jest-changed-files: 29.7.0
|
||||
jest-config: 29.7.0(@types/node@22.5.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4))
|
||||
jest-config: 29.7.0(@types/node@22.5.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4))
|
||||
jest-haste-map: 29.7.0
|
||||
jest-message-util: 29.7.0
|
||||
jest-regex-util: 29.6.3
|
||||
@ -8445,7 +8466,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@jest/fake-timers': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
jest-mock: 29.7.0
|
||||
|
||||
'@jest/expect-utils@29.7.0':
|
||||
@ -8463,7 +8484,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@sinonjs/fake-timers': 10.3.0
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
jest-message-util: 29.7.0
|
||||
jest-mock: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
@ -8485,7 +8506,7 @@ snapshots:
|
||||
'@jest/transform': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
chalk: 4.1.2
|
||||
collect-v8-coverage: 1.0.2
|
||||
exit: 0.1.2
|
||||
@ -8555,17 +8576,17 @@ snapshots:
|
||||
'@jest/schemas': 29.6.3
|
||||
'@types/istanbul-lib-coverage': 2.0.6
|
||||
'@types/istanbul-reports': 3.0.4
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
'@types/yargs': 17.0.32
|
||||
chalk: 4.1.2
|
||||
|
||||
'@joshwooding/vite-plugin-react-docgen-typescript@0.3.1(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.1))':
|
||||
'@joshwooding/vite-plugin-react-docgen-typescript@0.3.1(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.2)(terser@5.31.1))':
|
||||
dependencies:
|
||||
glob: 7.2.3
|
||||
glob-promise: 4.2.2(glob@7.2.3)
|
||||
magic-string: 0.27.0
|
||||
react-docgen-typescript: 2.2.2(typescript@5.5.4)
|
||||
vite: 5.4.2(@types/node@22.5.1)(terser@5.31.1)
|
||||
vite: 5.4.2(@types/node@22.5.2)(terser@5.31.1)
|
||||
optionalDependencies:
|
||||
typescript: 5.5.4
|
||||
|
||||
@ -8834,7 +8855,7 @@ snapshots:
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@storybook/builder-vite@8.2.9(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.1))':
|
||||
'@storybook/builder-vite@8.2.9(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.2)(terser@5.31.1))':
|
||||
dependencies:
|
||||
'@storybook/csf-plugin': 8.2.9(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))
|
||||
'@types/find-cache-dir': 3.2.1
|
||||
@ -8846,7 +8867,7 @@ snapshots:
|
||||
magic-string: 0.30.10
|
||||
storybook: 8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7))
|
||||
ts-dedent: 2.2.0
|
||||
vite: 5.4.2(@types/node@22.5.1)(terser@5.31.1)
|
||||
vite: 5.4.2(@types/node@22.5.2)(terser@5.31.1)
|
||||
optionalDependencies:
|
||||
typescript: 5.5.4
|
||||
transitivePeerDependencies:
|
||||
@ -8928,11 +8949,11 @@ snapshots:
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
storybook: 8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7))
|
||||
|
||||
'@storybook/react-vite@8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.21.1)(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.1))':
|
||||
'@storybook/react-vite@8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.21.1)(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.2)(terser@5.31.1))':
|
||||
dependencies:
|
||||
'@joshwooding/vite-plugin-react-docgen-typescript': 0.3.1(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.1))
|
||||
'@joshwooding/vite-plugin-react-docgen-typescript': 0.3.1(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.2)(terser@5.31.1))
|
||||
'@rollup/pluginutils': 5.1.0(rollup@4.21.1)
|
||||
'@storybook/builder-vite': 8.2.9(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.1))
|
||||
'@storybook/builder-vite': 8.2.9(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.2)(terser@5.31.1))
|
||||
'@storybook/react': 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(typescript@5.5.4)
|
||||
find-up: 5.0.0
|
||||
magic-string: 0.30.10
|
||||
@ -8942,7 +8963,7 @@ snapshots:
|
||||
resolve: 1.22.8
|
||||
storybook: 8.2.9(@babel/preset-env@7.24.7(@babel/core@7.24.7))
|
||||
tsconfig-paths: 4.2.0
|
||||
vite: 5.4.2(@types/node@22.5.1)(terser@5.31.1)
|
||||
vite: 5.4.2(@types/node@22.5.2)(terser@5.31.1)
|
||||
transitivePeerDependencies:
|
||||
- '@preact/preset-vite'
|
||||
- rollup
|
||||
@ -9068,15 +9089,15 @@ snapshots:
|
||||
'@types/body-parser@1.19.5':
|
||||
dependencies:
|
||||
'@types/connect': 3.4.38
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
|
||||
'@types/connect@3.4.38':
|
||||
dependencies:
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
|
||||
'@types/cross-spawn@6.0.6':
|
||||
dependencies:
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
|
||||
'@types/debug@4.1.12':
|
||||
dependencies:
|
||||
@ -9094,7 +9115,7 @@ snapshots:
|
||||
|
||||
'@types/express-serve-static-core@4.19.5':
|
||||
dependencies:
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
'@types/qs': 6.9.15
|
||||
'@types/range-parser': 1.2.7
|
||||
'@types/send': 0.17.4
|
||||
@ -9111,11 +9132,11 @@ snapshots:
|
||||
'@types/glob@7.2.0':
|
||||
dependencies:
|
||||
'@types/minimatch': 5.1.2
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
|
||||
'@types/graceful-fs@4.1.9':
|
||||
dependencies:
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
|
||||
'@types/hast@3.0.4':
|
||||
dependencies:
|
||||
@ -9142,7 +9163,7 @@ snapshots:
|
||||
|
||||
'@types/jsdom@20.0.1':
|
||||
dependencies:
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
'@types/tough-cookie': 4.0.5
|
||||
parse5: 7.1.2
|
||||
|
||||
@ -9172,7 +9193,7 @@ snapshots:
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
|
||||
'@types/node@22.5.1':
|
||||
'@types/node@22.5.2':
|
||||
dependencies:
|
||||
undici-types: 6.19.8
|
||||
|
||||
@ -9208,12 +9229,12 @@ snapshots:
|
||||
'@types/send@0.17.4':
|
||||
dependencies:
|
||||
'@types/mime': 1.3.5
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
|
||||
'@types/serve-static@1.15.7':
|
||||
dependencies:
|
||||
'@types/http-errors': 2.0.4
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
'@types/send': 0.17.4
|
||||
|
||||
'@types/stack-utils@2.0.3': {}
|
||||
@ -9232,7 +9253,7 @@ snapshots:
|
||||
|
||||
'@types/yauzl@2.10.3':
|
||||
dependencies:
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.3.0(@typescript-eslint/parser@8.3.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)':
|
||||
@ -9359,14 +9380,14 @@ snapshots:
|
||||
|
||||
'@ungap/structured-clone@1.2.0': {}
|
||||
|
||||
'@vitejs/plugin-react@4.3.1(vite@5.4.2(@types/node@22.5.1)(terser@5.31.1))':
|
||||
'@vitejs/plugin-react@4.3.1(vite@5.4.2(@types/node@22.5.2)(terser@5.31.1))':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.24.7)
|
||||
'@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.24.7)
|
||||
'@types/babel__core': 7.20.5
|
||||
react-refresh: 0.14.2
|
||||
vite: 5.4.2(@types/node@22.5.1)(terser@5.31.1)
|
||||
vite: 5.4.2(@types/node@22.5.2)(terser@5.31.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@ -9616,6 +9637,8 @@ snapshots:
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
attr-accept@2.2.2: {}
|
||||
|
||||
available-typed-arrays@1.0.7:
|
||||
dependencies:
|
||||
possible-typed-array-names: 1.0.0
|
||||
@ -10020,13 +10043,13 @@ snapshots:
|
||||
optionalDependencies:
|
||||
typescript: 5.5.4
|
||||
|
||||
create-jest@29.7.0(@types/node@22.5.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4)):
|
||||
create-jest@29.7.0(@types/node@22.5.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4)):
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
chalk: 4.1.2
|
||||
exit: 0.1.2
|
||||
graceful-fs: 4.2.11
|
||||
jest-config: 29.7.0(@types/node@22.5.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4))
|
||||
jest-config: 29.7.0(@types/node@22.5.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4))
|
||||
jest-util: 29.7.0
|
||||
prompts: 2.4.2
|
||||
transitivePeerDependencies:
|
||||
@ -10695,7 +10718,7 @@ snapshots:
|
||||
'@nodelib/fs.walk': 1.2.8
|
||||
glob-parent: 5.1.2
|
||||
merge2: 1.4.1
|
||||
micromatch: 4.0.5
|
||||
micromatch: 4.0.7
|
||||
|
||||
fast-json-stable-stringify@2.1.0: {}
|
||||
|
||||
@ -10725,6 +10748,10 @@ snapshots:
|
||||
dependencies:
|
||||
flat-cache: 4.0.1
|
||||
|
||||
file-selector@0.6.0:
|
||||
dependencies:
|
||||
tslib: 2.6.3
|
||||
|
||||
fill-range@7.1.1:
|
||||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
@ -11299,7 +11326,7 @@ snapshots:
|
||||
'@jest/expect': 29.7.0
|
||||
'@jest/test-result': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
chalk: 4.1.2
|
||||
co: 4.6.0
|
||||
dedent: 1.5.3(babel-plugin-macros@3.1.0)
|
||||
@ -11319,16 +11346,16 @@ snapshots:
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
|
||||
jest-cli@29.7.0(@types/node@22.5.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4)):
|
||||
jest-cli@29.7.0(@types/node@22.5.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4)):
|
||||
dependencies:
|
||||
'@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4))
|
||||
'@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4))
|
||||
'@jest/test-result': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
chalk: 4.1.2
|
||||
create-jest: 29.7.0(@types/node@22.5.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4))
|
||||
create-jest: 29.7.0(@types/node@22.5.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4))
|
||||
exit: 0.1.2
|
||||
import-local: 3.1.0
|
||||
jest-config: 29.7.0(@types/node@22.5.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4))
|
||||
jest-config: 29.7.0(@types/node@22.5.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4))
|
||||
jest-util: 29.7.0
|
||||
jest-validate: 29.7.0
|
||||
yargs: 17.7.2
|
||||
@ -11338,7 +11365,7 @@ snapshots:
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
jest-config@29.7.0(@types/node@22.5.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4)):
|
||||
jest-config@29.7.0(@types/node@22.5.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4)):
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@jest/test-sequencer': 29.7.0
|
||||
@ -11363,8 +11390,8 @@ snapshots:
|
||||
slash: 3.0.0
|
||||
strip-json-comments: 3.1.1
|
||||
optionalDependencies:
|
||||
'@types/node': 22.5.1
|
||||
ts-node: 10.9.2(@types/node@22.5.1)(typescript@5.5.4)
|
||||
'@types/node': 22.5.2
|
||||
ts-node: 10.9.2(@types/node@22.5.2)(typescript@5.5.4)
|
||||
transitivePeerDependencies:
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
@ -11394,7 +11421,7 @@ snapshots:
|
||||
'@jest/fake-timers': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/jsdom': 20.0.1
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
jest-mock: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
jsdom: 20.0.3
|
||||
@ -11408,7 +11435,7 @@ snapshots:
|
||||
'@jest/environment': 29.7.0
|
||||
'@jest/fake-timers': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
jest-mock: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
|
||||
@ -11418,7 +11445,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@types/graceful-fs': 4.1.9
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
anymatch: 3.1.3
|
||||
fb-watchman: 2.0.2
|
||||
graceful-fs: 4.2.11
|
||||
@ -11457,7 +11484,7 @@ snapshots:
|
||||
jest-mock@29.7.0:
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
jest-util: 29.7.0
|
||||
|
||||
jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
|
||||
@ -11492,7 +11519,7 @@ snapshots:
|
||||
'@jest/test-result': 29.7.0
|
||||
'@jest/transform': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
chalk: 4.1.2
|
||||
emittery: 0.13.1
|
||||
graceful-fs: 4.2.11
|
||||
@ -11520,7 +11547,7 @@ snapshots:
|
||||
'@jest/test-result': 29.7.0
|
||||
'@jest/transform': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
chalk: 4.1.2
|
||||
cjs-module-lexer: 1.3.1
|
||||
collect-v8-coverage: 1.0.2
|
||||
@ -11566,7 +11593,7 @@ snapshots:
|
||||
jest-util@29.7.0:
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.9.0
|
||||
graceful-fs: 4.2.11
|
||||
@ -11585,7 +11612,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@jest/test-result': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
ansi-escapes: 4.3.2
|
||||
chalk: 4.1.2
|
||||
emittery: 0.13.1
|
||||
@ -11594,17 +11621,17 @@ snapshots:
|
||||
|
||||
jest-worker@29.7.0:
|
||||
dependencies:
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
jest-util: 29.7.0
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 8.1.1
|
||||
|
||||
jest@29.7.0(@types/node@22.5.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4)):
|
||||
jest@29.7.0(@types/node@22.5.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4)):
|
||||
dependencies:
|
||||
'@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4))
|
||||
'@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4))
|
||||
'@jest/types': 29.6.3
|
||||
import-local: 3.1.0
|
||||
jest-cli: 29.7.0(@types/node@22.5.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4))
|
||||
jest-cli: 29.7.0(@types/node@22.5.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4))
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- babel-plugin-macros
|
||||
@ -11727,11 +11754,11 @@ snapshots:
|
||||
|
||||
kleur@3.0.3: {}
|
||||
|
||||
knip@5.27.5(@types/node@22.5.1)(typescript@5.5.4):
|
||||
knip@5.29.1(@types/node@22.5.2)(typescript@5.5.4):
|
||||
dependencies:
|
||||
'@nodelib/fs.walk': 1.2.8
|
||||
'@snyk/github-codeowners': 1.1.0
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
easy-table: 1.2.0
|
||||
enhanced-resolve: 5.17.1
|
||||
fast-glob: 3.3.2
|
||||
@ -12188,11 +12215,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
micromatch@4.0.5:
|
||||
dependencies:
|
||||
braces: 3.0.3
|
||||
picomatch: 2.3.1
|
||||
|
||||
micromatch@4.0.7:
|
||||
dependencies:
|
||||
braces: 3.0.3
|
||||
@ -12700,6 +12722,13 @@ snapshots:
|
||||
react: 18.3.1
|
||||
scheduler: 0.23.2
|
||||
|
||||
react-dropzone@14.2.3(react@18.3.1):
|
||||
dependencies:
|
||||
attr-accept: 2.2.2
|
||||
file-selector: 0.6.0
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
|
||||
react-element-to-jsx-string@15.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
'@base2/pretty-print-object': 1.0.1
|
||||
@ -12853,7 +12882,7 @@ snapshots:
|
||||
ts-easing: 0.2.0
|
||||
tslib: 2.6.3
|
||||
|
||||
react-virtuoso@4.10.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
react-virtuoso@4.10.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
@ -13514,14 +13543,14 @@ snapshots:
|
||||
|
||||
ts-easing@0.2.0: {}
|
||||
|
||||
ts-node@10.9.2(@types/node@22.5.1)(typescript@5.5.4):
|
||||
ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4):
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.11
|
||||
'@tsconfig/node12': 1.0.11
|
||||
'@tsconfig/node14': 1.0.3
|
||||
'@tsconfig/node16': 1.0.4
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
acorn: 8.12.0
|
||||
acorn-walk: 8.3.3
|
||||
arg: 4.1.3
|
||||
@ -13773,13 +13802,13 @@ snapshots:
|
||||
unist-util-stringify-position: 4.0.0
|
||||
vfile-message: 4.0.2
|
||||
|
||||
vite-node@2.0.5(@types/node@22.5.1)(terser@5.31.1):
|
||||
vite-node@2.0.5(@types/node@22.5.2)(terser@5.31.1):
|
||||
dependencies:
|
||||
cac: 6.7.14
|
||||
debug: 4.3.6
|
||||
pathe: 1.1.2
|
||||
tinyrainbow: 1.2.0
|
||||
vite: 5.4.2(@types/node@22.5.1)(terser@5.31.1)
|
||||
vite: 5.4.2(@types/node@22.5.2)(terser@5.31.1)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- less
|
||||
@ -13791,17 +13820,17 @@ snapshots:
|
||||
- supports-color
|
||||
- terser
|
||||
|
||||
vite@5.4.2(@types/node@22.5.1)(terser@5.31.1):
|
||||
vite@5.4.2(@types/node@22.5.2)(terser@5.31.1):
|
||||
dependencies:
|
||||
esbuild: 0.21.5
|
||||
postcss: 8.4.41
|
||||
rollup: 4.21.1
|
||||
optionalDependencies:
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
fsevents: 2.3.3
|
||||
terser: 5.31.1
|
||||
|
||||
vitest@2.0.5(@types/node@22.5.1)(jsdom@20.0.3)(terser@5.31.1):
|
||||
vitest@2.0.5(@types/node@22.5.2)(jsdom@20.0.3)(terser@5.31.1):
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.3.0
|
||||
'@vitest/expect': 2.0.5
|
||||
@ -13819,11 +13848,11 @@ snapshots:
|
||||
tinybench: 2.8.0
|
||||
tinypool: 1.0.0
|
||||
tinyrainbow: 1.2.0
|
||||
vite: 5.4.2(@types/node@22.5.1)(terser@5.31.1)
|
||||
vite-node: 2.0.5(@types/node@22.5.1)(terser@5.31.1)
|
||||
vite: 5.4.2(@types/node@22.5.2)(terser@5.31.1)
|
||||
vite-node: 2.0.5(@types/node@22.5.2)(terser@5.31.1)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/node': 22.5.1
|
||||
'@types/node': 22.5.2
|
||||
jsdom: 20.0.3
|
||||
transitivePeerDependencies:
|
||||
- less
|
||||
|
@ -231,6 +231,7 @@ export namespace AlbumResource {
|
||||
},
|
||||
data: {
|
||||
file: File,
|
||||
uri: string,
|
||||
},
|
||||
callbacks?: RESTCallbacks,
|
||||
}): Promise<Album> {
|
||||
|
@ -162,6 +162,7 @@ export namespace ArtistResource {
|
||||
},
|
||||
data: {
|
||||
file: File,
|
||||
uri: string,
|
||||
},
|
||||
callbacks?: RESTCallbacks,
|
||||
}): Promise<Artist> {
|
||||
|
@ -162,6 +162,7 @@ export namespace GenderResource {
|
||||
},
|
||||
data: {
|
||||
file: File,
|
||||
uri: string,
|
||||
},
|
||||
callbacks?: RESTCallbacks,
|
||||
}): Promise<Gender> {
|
||||
|
@ -8,5 +8,6 @@ export * from "./front"
|
||||
export * from "./gender-resource"
|
||||
export * from "./health-check"
|
||||
export * from "./playlist-resource"
|
||||
export * from "./proxy-resource"
|
||||
export * from "./track-resource"
|
||||
export * from "./user-resource"
|
||||
|
30
front2/src/back-api/api/proxy-resource.ts
Normal file
30
front2/src/back-api/api/proxy-resource.ts
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import {
|
||||
HTTPRequestModel,
|
||||
RESTConfig,
|
||||
RESTRequestJson,
|
||||
} from "../rest-tools";
|
||||
|
||||
export namespace ProxyResource {
|
||||
|
||||
export function getImageFromUrl({
|
||||
restConfig,
|
||||
queries,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
queries: {
|
||||
url?: string,
|
||||
},
|
||||
}): Promise<object> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/proxy/",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
},
|
||||
restConfig,
|
||||
queries,
|
||||
});
|
||||
};
|
||||
}
|
@ -204,6 +204,7 @@ export namespace TrackResource {
|
||||
},
|
||||
data: {
|
||||
file: File,
|
||||
uri: string,
|
||||
},
|
||||
callbacks?: RESTCallbacks,
|
||||
}): Promise<Track> {
|
||||
|
36
front2/src/back-api/model/integer.ts
Normal file
36
front2/src/back-api/model/integer.ts
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodInteger = zod.object({
|
||||
|
||||
});
|
||||
|
||||
export type Integer = zod.infer<typeof ZodInteger>;
|
||||
|
||||
export function isInteger(data: any): data is Integer {
|
||||
try {
|
||||
ZodInteger.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodInteger' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodIntegerWrite = zod.object({
|
||||
|
||||
});
|
||||
|
||||
export type IntegerWrite = zod.infer<typeof ZodIntegerWrite>;
|
||||
|
||||
export function isIntegerWrite(data: any): data is IntegerWrite {
|
||||
try {
|
||||
ZodIntegerWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodIntegerWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,62 +1,61 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from 'zod';
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {
|
||||
ZodGenericDataSoftDelete,
|
||||
ZodGenericDataSoftDeleteWrite,
|
||||
} from './generic-data-soft-delete';
|
||||
import { ZodLong } from './long';
|
||||
import { ZodUUID } from './uuid';
|
||||
import {ZodUUID} from "./uuid";
|
||||
import {ZodLong} from "./long";
|
||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
||||
|
||||
export const ZodTrack = ZodGenericDataSoftDelete.extend({
|
||||
name: zod.string().max(256).optional(),
|
||||
description: zod.string().optional(),
|
||||
/**
|
||||
* List of Id of the specific covers
|
||||
*/
|
||||
covers: zod.array(ZodUUID).optional(),
|
||||
genderId: ZodLong.optional(),
|
||||
albumId: ZodLong.optional(),
|
||||
track: ZodLong.optional(),
|
||||
dataId: ZodUUID.optional(),
|
||||
artists: zod.array(ZodLong),
|
||||
name: zod.string().max(256).optional(),
|
||||
description: zod.string().optional(),
|
||||
/**
|
||||
* List of Id of the specific covers
|
||||
*/
|
||||
covers: zod.array(ZodUUID).optional(),
|
||||
genderId: ZodLong.optional(),
|
||||
albumId: ZodLong.optional(),
|
||||
track: ZodLong.optional(),
|
||||
dataId: ZodUUID.optional(),
|
||||
artists: zod.array(ZodLong),
|
||||
|
||||
});
|
||||
|
||||
export type Track = zod.infer<typeof ZodTrack>;
|
||||
|
||||
export function isTrack(data: any): data is Track {
|
||||
try {
|
||||
ZodTrack.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodTrack' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
ZodTrack.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodTrack' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodTrackWrite = ZodGenericDataSoftDeleteWrite.extend({
|
||||
name: zod.string().max(256).nullable().optional(),
|
||||
description: zod.string().nullable().optional(),
|
||||
/**
|
||||
* List of Id of the specific covers
|
||||
*/
|
||||
covers: zod.array(ZodUUID).nullable().optional(),
|
||||
genderId: ZodLong.nullable().optional(),
|
||||
albumId: ZodLong.nullable().optional(),
|
||||
track: ZodLong.nullable().optional(),
|
||||
dataId: ZodUUID.nullable().optional(),
|
||||
artists: zod.array(ZodLong).optional(),
|
||||
name: zod.string().max(256).nullable().optional(),
|
||||
description: zod.string().nullable().optional(),
|
||||
/**
|
||||
* List of Id of the specific covers
|
||||
*/
|
||||
covers: zod.array(ZodUUID).nullable().optional(),
|
||||
genderId: ZodLong.nullable().optional(),
|
||||
albumId: ZodLong.nullable().optional(),
|
||||
track: ZodLong.nullable().optional(),
|
||||
dataId: ZodUUID.nullable().optional(),
|
||||
artists: zod.array(ZodLong).optional(),
|
||||
|
||||
});
|
||||
|
||||
export type TrackWrite = zod.infer<typeof ZodTrackWrite>;
|
||||
|
||||
export function isTrackWrite(data: any): data is TrackWrite {
|
||||
try {
|
||||
ZodTrackWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodTrackWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
ZodTrackWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodTrackWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
185
front2/src/components/form/FormCovers.tsx
Normal file
185
front2/src/components/form/FormCovers.tsx
Normal file
@ -0,0 +1,185 @@
|
||||
import {
|
||||
DragEventHandler,
|
||||
ReactNode,
|
||||
RefObject,
|
||||
forwardRef,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import {
|
||||
Box,
|
||||
BoxProps,
|
||||
Center,
|
||||
Icon,
|
||||
Image,
|
||||
Wrap,
|
||||
WrapItem,
|
||||
} from '@chakra-ui/react';
|
||||
import { relative } from 'path';
|
||||
import {
|
||||
MdCheckCircle,
|
||||
MdClear,
|
||||
MdHighlightOff,
|
||||
MdUploadFile,
|
||||
} from 'react-icons/md';
|
||||
|
||||
import { ProxyResource } from '@/back-api';
|
||||
import { FormGroup } from '@/components/form/FormGroup';
|
||||
import { UseFormidableReturn } from '@/components/form/Formidable';
|
||||
import { DataUrlAccess } from '@/utils/data-url-access';
|
||||
|
||||
export type DragNdropProps = {
|
||||
onFilesSelected?: (file: File[]) => void;
|
||||
onUriSelected?: (uri: string) => void;
|
||||
width?: string;
|
||||
height?: string;
|
||||
};
|
||||
|
||||
export const DragNdrop = ({
|
||||
onFilesSelected = () => {},
|
||||
onUriSelected = () => {},
|
||||
width = '100px',
|
||||
height = '100px',
|
||||
}: DragNdropProps) => {
|
||||
const handleFileChange = (event) => {
|
||||
const selectedFiles = event.target.files;
|
||||
if (selectedFiles && selectedFiles.length > 0) {
|
||||
const newFiles: File[] = Array.from(selectedFiles);
|
||||
onFilesSelected(newFiles);
|
||||
}
|
||||
};
|
||||
const handleDrop = (event: DragEvent) => {
|
||||
event.preventDefault();
|
||||
const droppedFiles = event.dataTransfer?.files;
|
||||
console.log('drop ...' + droppedFiles?.length);
|
||||
if (droppedFiles && droppedFiles?.length > 0) {
|
||||
const newFiles: File[] = Array.from(droppedFiles);
|
||||
onFilesSelected(newFiles);
|
||||
} else {
|
||||
console.log(`drop types: ${event.dataTransfer?.types}`);
|
||||
const listUri = event.dataTransfer?.getData('text/uri-list');
|
||||
console.log(`listUri: ${listUri}`);
|
||||
if (!listUri) {
|
||||
return;
|
||||
}
|
||||
onUriSelected(listUri);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
width={width}
|
||||
height={height}
|
||||
border="2px"
|
||||
borderRadius="5px"
|
||||
borderStyle="dashed"
|
||||
onDrop={handleDrop}
|
||||
onDragOver={(event) => event.preventDefault()}
|
||||
>
|
||||
<label htmlFor="browse">
|
||||
<Box paddingY="15%" height="100%" cursor="pointer">
|
||||
<Center>
|
||||
<MdUploadFile size="50%" />
|
||||
</Center>
|
||||
<Center>
|
||||
<input
|
||||
type="file"
|
||||
hidden
|
||||
id="browse"
|
||||
onChange={handleFileChange}
|
||||
//accept=".pdf,.docx,.pptx,.txt,.xlsx"
|
||||
multiple
|
||||
/>
|
||||
Browse files
|
||||
</Center>
|
||||
</Box>
|
||||
</label>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export type CenterIconProps = BoxProps & {
|
||||
icon: any;
|
||||
sizeIcon?: string;
|
||||
};
|
||||
|
||||
export const CenterIcon = ({
|
||||
icon: IconEl,
|
||||
sizeIcon = '15px',
|
||||
...rest
|
||||
}: CenterIconProps) => {
|
||||
return (
|
||||
<Box position="relative" w={sizeIcon} h={sizeIcon} flex="none" {...rest}>
|
||||
<Box
|
||||
as={IconEl}
|
||||
w={sizeIcon}
|
||||
h={sizeIcon}
|
||||
position="absolute"
|
||||
top="50%"
|
||||
left="50%"
|
||||
transform="translate(-50%, -50%)"
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export type FormCoversProps = {
|
||||
form: UseFormidableReturn;
|
||||
variableName: string;
|
||||
ref?: RefObject<any>;
|
||||
label?: string;
|
||||
isRequired?: boolean;
|
||||
onFilesSelected?: (files: File[]) => void;
|
||||
onUriSelected?: (uri: string) => void;
|
||||
onRemove?: (index: number) => void;
|
||||
};
|
||||
|
||||
export const FormCovers = ({
|
||||
form,
|
||||
variableName,
|
||||
ref,
|
||||
onFilesSelected = () => {},
|
||||
onUriSelected = () => {},
|
||||
onRemove = () => {},
|
||||
...rest
|
||||
}: FormCoversProps) => {
|
||||
const urls =
|
||||
DataUrlAccess.getListThumbnailUrl(form.values[variableName]) ?? [];
|
||||
return (
|
||||
<FormGroup
|
||||
isModify={form.isModify[variableName]}
|
||||
onRestore={() => form.restoreValue({ [variableName]: true })}
|
||||
{...rest}
|
||||
>
|
||||
<Wrap width="full">
|
||||
{urls.map((data, index) => (
|
||||
<WrapItem key={data}>
|
||||
<Box width="125px" height="125px" position="relative">
|
||||
<Box width="125px" height="125px" position="absolute">
|
||||
<CenterIcon
|
||||
icon={MdHighlightOff}
|
||||
width="125px"
|
||||
sizeIcon="100%"
|
||||
zIndex="+1"
|
||||
color="#00000020"
|
||||
_hover={{ color: 'red' }}
|
||||
onClick={() => onRemove && onRemove(index)}
|
||||
/>
|
||||
</Box>
|
||||
<Image loading="lazy" src={data} boxSize="full" />
|
||||
</Box>
|
||||
</WrapItem>
|
||||
))}
|
||||
<WrapItem key="data">
|
||||
<DragNdrop
|
||||
height="125px"
|
||||
width="125px"
|
||||
onFilesSelected={onFilesSelected}
|
||||
onUriSelected={onUriSelected}
|
||||
/>
|
||||
</WrapItem>
|
||||
</Wrap>
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
@ -22,6 +22,7 @@ import {
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
|
||||
import { Album, AlbumResource } from '@/back-api';
|
||||
import { FormCovers } from '@/components/form/FormCovers';
|
||||
import { FormGroup } from '@/components/form/FormGroup';
|
||||
import { FormInput } from '@/components/form/FormInput';
|
||||
import { FormTextarea } from '@/components/form/FormTextarea';
|
||||
@ -85,6 +86,66 @@ export const AlbumEditPopUp = ({}: AlbumEditPopUpProps) => {
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const onUriSelected = (uri: string) => {
|
||||
if (isNullOrUndefined(albumIdInt)) {
|
||||
return;
|
||||
}
|
||||
// no real need the wrapper must be able to set optional the uri our file ...
|
||||
const plop = new File([], 'emptyFile.txt', {
|
||||
type: 'text/plain',
|
||||
});
|
||||
store.update(
|
||||
AlbumResource.uploadCover({
|
||||
restConfig: session.getRestConfig(),
|
||||
data: {
|
||||
file: plop,
|
||||
uri: uri,
|
||||
},
|
||||
params: {
|
||||
id: albumIdInt,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const onFilesSelected = (files: File[]) => {
|
||||
files.forEach((element) => {
|
||||
console.log(`Select file: '${element.name}'`);
|
||||
});
|
||||
if (isNullOrUndefined(albumIdInt)) {
|
||||
return;
|
||||
}
|
||||
store.update(
|
||||
AlbumResource.uploadCover({
|
||||
restConfig: session.getRestConfig(),
|
||||
data: {
|
||||
file: files[0],
|
||||
uri: null,
|
||||
},
|
||||
params: {
|
||||
id: albumIdInt,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
const onRemoveCover = (index: number) => {
|
||||
if (isNullOrUndefined(dataAlbum?.covers)) {
|
||||
return;
|
||||
}
|
||||
if (isNullOrUndefined(albumIdInt)) {
|
||||
return;
|
||||
}
|
||||
store.update(
|
||||
AlbumResource.removeCover({
|
||||
restConfig: session.getRestConfig(),
|
||||
params: {
|
||||
id: albumIdInt,
|
||||
coverId: dataAlbum.covers[index],
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
return (
|
||||
<Modal
|
||||
initialFocusRef={initialRef}
|
||||
@ -151,6 +212,13 @@ export const AlbumEditPopUp = ({}: AlbumEditPopUpProps) => {
|
||||
variableName="publication"
|
||||
label="Publication"
|
||||
/>
|
||||
<FormCovers
|
||||
form={form}
|
||||
variableName="covers"
|
||||
onFilesSelected={onFilesSelected}
|
||||
onUriSelected={onUriSelected}
|
||||
onRemove={onRemoveCover}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</ModalBody>
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
|
||||
import { Artist, ArtistResource } from '@/back-api';
|
||||
import { FormCovers } from '@/components/form/FormCovers';
|
||||
import { FormGroup } from '@/components/form/FormGroup';
|
||||
import { FormInput } from '@/components/form/FormInput';
|
||||
import { FormTextarea } from '@/components/form/FormTextarea';
|
||||
@ -85,6 +86,65 @@ export const ArtistEditPopUp = ({}: ArtistEditPopUpProps) => {
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const onUriSelected = (uri: string) => {
|
||||
if (isNullOrUndefined(artistIdInt)) {
|
||||
return;
|
||||
}
|
||||
// no real need the wrapper must be able to set optional the uri our file ...
|
||||
const plop = new File([], 'emptyFile.txt', {
|
||||
type: 'text/plain',
|
||||
});
|
||||
store.update(
|
||||
ArtistResource.uploadCover({
|
||||
restConfig: session.getRestConfig(),
|
||||
data: {
|
||||
file: plop,
|
||||
uri: uri,
|
||||
},
|
||||
params: {
|
||||
id: artistIdInt,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
const onFilesSelected = (files: File[]) => {
|
||||
files.forEach((element) => {
|
||||
console.log(`Select file: '${element.name}'`);
|
||||
});
|
||||
if (isNullOrUndefined(artistIdInt)) {
|
||||
return;
|
||||
}
|
||||
store.update(
|
||||
ArtistResource.uploadCover({
|
||||
restConfig: session.getRestConfig(),
|
||||
data: {
|
||||
file: files[0],
|
||||
uri: null,
|
||||
},
|
||||
params: {
|
||||
id: artistIdInt,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
const onRemoveCover = (index: number) => {
|
||||
if (isNullOrUndefined(dataArtist?.covers)) {
|
||||
return;
|
||||
}
|
||||
if (isNullOrUndefined(artistIdInt)) {
|
||||
return;
|
||||
}
|
||||
store.update(
|
||||
ArtistResource.removeCover({
|
||||
restConfig: session.getRestConfig(),
|
||||
params: {
|
||||
id: artistIdInt,
|
||||
coverId: dataArtist.covers[index],
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
return (
|
||||
<Modal
|
||||
initialFocusRef={initialRef}
|
||||
@ -154,6 +214,13 @@ export const ArtistEditPopUp = ({}: ArtistEditPopUpProps) => {
|
||||
<FormInput form={form} variableName="surname" label="SurName" />
|
||||
<FormInput form={form} variableName="birth" label="Birth date" />
|
||||
<FormInput form={form} variableName="death" label="Death date" />
|
||||
<FormCovers
|
||||
form={form}
|
||||
variableName="covers"
|
||||
onFilesSelected={onFilesSelected}
|
||||
onUriSelected={onUriSelected}
|
||||
onRemove={onRemoveCover}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</ModalBody>
|
||||
|
245
front2/src/components/popup/GenderEditPopUp.tsx
Normal file
245
front2/src/components/popup/GenderEditPopUp.tsx
Normal file
@ -0,0 +1,245 @@
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Flex,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
Text,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
MdAdminPanelSettings,
|
||||
MdDeleteForever,
|
||||
MdEdit,
|
||||
MdWarning,
|
||||
} from 'react-icons/md';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
|
||||
import { Gender, GenderResource } from '@/back-api';
|
||||
import { FormCovers } from '@/components/form/FormCovers';
|
||||
import { FormGroup } from '@/components/form/FormGroup';
|
||||
import { FormInput } from '@/components/form/FormInput';
|
||||
import { FormTextarea } from '@/components/form/FormTextarea';
|
||||
import { useFormidable } from '@/components/form/Formidable';
|
||||
import { ConfirmPopUp } from '@/components/popup/ConfirmPopUp';
|
||||
import { useGenderService, useSpecificGender } from '@/service/Gender';
|
||||
import { useServiceContext } from '@/service/ServiceContext';
|
||||
import { useCountTracksOfAGender } from '@/service/Track';
|
||||
import { isNullOrUndefined } from '@/utils/validator';
|
||||
|
||||
export type GenderEditPopUpProps = {};
|
||||
|
||||
export const GenderEditPopUp = ({}: GenderEditPopUpProps) => {
|
||||
const { genderId } = useParams();
|
||||
const genderIdInt = isNullOrUndefined(genderId)
|
||||
? undefined
|
||||
: parseInt(genderId, 10);
|
||||
const { session } = useServiceContext();
|
||||
const { countTracksOnAGender } = useCountTracksOfAGender(genderIdInt);
|
||||
const { store } = useGenderService();
|
||||
const { dataGender } = useSpecificGender(genderIdInt);
|
||||
const [admin, setAdmin] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const disclosure = useDisclosure();
|
||||
const onClose = () => {
|
||||
navigate('../../', { relative: 'path' });
|
||||
};
|
||||
const onRemove = () => {
|
||||
if (isNullOrUndefined(genderIdInt)) {
|
||||
return;
|
||||
}
|
||||
store.remove(
|
||||
genderIdInt,
|
||||
GenderResource.remove({
|
||||
restConfig: session.getRestConfig(),
|
||||
params: {
|
||||
id: genderIdInt,
|
||||
},
|
||||
})
|
||||
);
|
||||
onClose();
|
||||
};
|
||||
const initialRef = useRef(null);
|
||||
const finalRef = useRef(null);
|
||||
const form = useFormidable<Gender>({
|
||||
initialValues: dataGender,
|
||||
});
|
||||
const onSave = async () => {
|
||||
if (isNullOrUndefined(genderIdInt)) {
|
||||
return;
|
||||
}
|
||||
const dataThatNeedToBeUpdated = form.getDeltaData({ omit: ['covers'] });
|
||||
console.log(`onSave = ${JSON.stringify(dataThatNeedToBeUpdated, null, 2)}`);
|
||||
store.update(
|
||||
GenderResource.patch({
|
||||
restConfig: session.getRestConfig(),
|
||||
data: dataThatNeedToBeUpdated,
|
||||
params: {
|
||||
id: genderIdInt,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
const onUriSelected = (uri: string) => {
|
||||
if (isNullOrUndefined(genderIdInt)) {
|
||||
return;
|
||||
}
|
||||
// no real need the wrapper must be able to set optional the uri our file ...
|
||||
const plop = new File([], 'emptyFile.txt', {
|
||||
type: 'text/plain',
|
||||
});
|
||||
store.update(
|
||||
GenderResource.uploadCover({
|
||||
restConfig: session.getRestConfig(),
|
||||
data: {
|
||||
file: plop,
|
||||
uri: uri,
|
||||
},
|
||||
params: {
|
||||
id: genderIdInt,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
const onFilesSelected = (files: File[]) => {
|
||||
files.forEach((element) => {
|
||||
console.log(`Select file: '${element.name}'`);
|
||||
});
|
||||
if (isNullOrUndefined(genderIdInt)) {
|
||||
return;
|
||||
}
|
||||
store.update(
|
||||
GenderResource.uploadCover({
|
||||
restConfig: session.getRestConfig(),
|
||||
data: {
|
||||
file: files[0],
|
||||
uri: null,
|
||||
},
|
||||
params: {
|
||||
id: genderIdInt,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
const onRemoveCover = (index: number) => {
|
||||
if (isNullOrUndefined(dataGender?.covers)) {
|
||||
return;
|
||||
}
|
||||
if (isNullOrUndefined(genderIdInt)) {
|
||||
return;
|
||||
}
|
||||
store.update(
|
||||
GenderResource.removeCover({
|
||||
restConfig: session.getRestConfig(),
|
||||
params: {
|
||||
id: genderIdInt,
|
||||
coverId: dataGender.covers[index],
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
return (
|
||||
<Modal
|
||||
initialFocusRef={initialRef}
|
||||
finalFocusRef={finalRef}
|
||||
closeOnOverlayClick={false}
|
||||
onClose={onClose}
|
||||
isOpen={true}
|
||||
>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>Edit Gender</ModalHeader>
|
||||
<ModalCloseButton ref={finalRef} />
|
||||
|
||||
<ModalBody pb={6} gap="0px" paddingLeft="18px">
|
||||
{admin && (
|
||||
<>
|
||||
<FormGroup isRequired label="Id">
|
||||
<Text>{dataGender?.id}</Text>
|
||||
</FormGroup>
|
||||
{countTracksOnAGender !== 0 && (
|
||||
<Flex paddingLeft="14px">
|
||||
<MdWarning color="red.600" />
|
||||
<Text paddingLeft="6px" color="red.600" fontWeight="bold">
|
||||
Can not remove gender {countTracksOnAGender} track(s) depend
|
||||
on it.
|
||||
</Text>
|
||||
</Flex>
|
||||
)}
|
||||
<FormGroup label="Action(s):">
|
||||
<Button
|
||||
onClick={disclosure.onOpen}
|
||||
marginRight="auto"
|
||||
variant="@danger"
|
||||
isDisabled={countTracksOnAGender !== 0}
|
||||
>
|
||||
<MdDeleteForever /> Remove gender
|
||||
</Button>
|
||||
</FormGroup>
|
||||
<ConfirmPopUp
|
||||
disclosure={disclosure}
|
||||
title="Remove gender"
|
||||
body={`Remove gender [${dataGender?.id}] ${dataGender?.name}`}
|
||||
confirmTitle="Remove"
|
||||
onConfirm={onRemove}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{!admin && (
|
||||
<>
|
||||
<FormInput
|
||||
form={form}
|
||||
variableName="name"
|
||||
isRequired
|
||||
label="Gender name"
|
||||
ref={initialRef}
|
||||
/>
|
||||
<FormTextarea
|
||||
form={form}
|
||||
variableName="description"
|
||||
label="Description"
|
||||
/>
|
||||
<FormCovers
|
||||
form={form}
|
||||
variableName="covers"
|
||||
onFilesSelected={onFilesSelected}
|
||||
onUriSelected={onUriSelected}
|
||||
onRemove={onRemoveCover}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button
|
||||
onClick={() => setAdmin((value) => !value)}
|
||||
marginRight="auto"
|
||||
>
|
||||
{admin ? (
|
||||
<>
|
||||
<MdEdit />
|
||||
Edit
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<MdAdminPanelSettings />
|
||||
Admin
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
{!admin && form.isFormModified && (
|
||||
<Button colorScheme="blue" mr={3} onClick={onSave}>
|
||||
Save
|
||||
</Button>
|
||||
)}
|
||||
<Button onClick={onClose}>Cancel</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
};
|
@ -45,7 +45,7 @@ const environment_local: Environment = {
|
||||
ssoSignUp: `${serverSSOAddress}/karso/signup/karusic-dev/`,
|
||||
ssoSignOut: `${serverSSOAddress}/karso/signout/karusic-dev/`,
|
||||
tokenStoredInPermanentStorage: false,
|
||||
replaceDataToRealServer: true,
|
||||
//replaceDataToRealServer: true,
|
||||
};
|
||||
|
||||
const environment_full_local: Environment = {
|
||||
|
@ -1,12 +1,14 @@
|
||||
import { Box, Flex, Text } from '@chakra-ui/react';
|
||||
import { Box, Button, Flex, Text } from '@chakra-ui/react';
|
||||
import { LuDisc3 } from 'react-icons/lu';
|
||||
import { MdEdit } from 'react-icons/md';
|
||||
import { Route, Routes, useNavigate, useParams } from 'react-router-dom';
|
||||
|
||||
import { Covers } from '@/components/Cover';
|
||||
import { EmptyEnd } from '@/components/EmptyEnd';
|
||||
import { PageLayout } from '@/components/Layout/PageLayout';
|
||||
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
||||
import { TopBar } from '@/components/TopBar/TopBar';
|
||||
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
|
||||
import { GenderEditPopUp } from '@/components/popup/GenderEditPopUp';
|
||||
import { TrackEditPopUp } from '@/components/popup/TrackEditPopUp';
|
||||
import { DisplayTrack } from '@/components/track/DisplayTrack';
|
||||
import { DisplayTrackFull } from '@/components/track/DisplayTrackFull';
|
||||
@ -54,7 +56,16 @@ export const GenderDetailPage = () => {
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<TopBar title="Gender detail" />
|
||||
<TopBar title="Gender detail">
|
||||
<Button
|
||||
{...BUTTON_TOP_BAR_PROPERTY}
|
||||
onClick={() =>
|
||||
navigate(`/gender/${genderId}/edit-gender/${genderId}`)
|
||||
}
|
||||
>
|
||||
<MdEdit />
|
||||
</Button>
|
||||
</TopBar>
|
||||
<PageLayout>
|
||||
<Flex
|
||||
direction="row"
|
||||
@ -106,7 +117,7 @@ export const GenderDetailPage = () => {
|
||||
{
|
||||
name: 'Edit',
|
||||
onClick: () => {
|
||||
navigate(`/gender/${genderId}/edit/${data.id}`);
|
||||
navigate(`/gender/${genderId}/edit-track/${data.id}`);
|
||||
},
|
||||
},
|
||||
{ name: 'Add Playlist', onClick: () => {} },
|
||||
@ -117,7 +128,8 @@ export const GenderDetailPage = () => {
|
||||
<EmptyEnd />
|
||||
</Flex>
|
||||
<Routes>
|
||||
<Route path="edit/:trackId" element={<TrackEditPopUp />} />
|
||||
<Route path="edit-track/:trackId" element={<TrackEditPopUp />} />
|
||||
<Route path="edit-gender/:genderId" element={<GenderEditPopUp />} />
|
||||
</Routes>
|
||||
</PageLayout>
|
||||
</>
|
||||
|
@ -6,7 +6,8 @@
|
||||
import { DependencyList, useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { RestErrorResponse } from '@/back-api';
|
||||
import { isArray, isNullOrUndefined } from '@/utils/validator';
|
||||
import { useToastAPIError } from '@/utils/toastHook';
|
||||
import { isNullOrUndefined } from '@/utils/validator';
|
||||
|
||||
export type DataStoreType<TYPE> = {
|
||||
isLoading: boolean;
|
||||
@ -33,6 +34,7 @@ export const useDataStore = <TYPE>(
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState<RestErrorResponse | undefined>(undefined);
|
||||
const [data, setData] = useState<TYPE[]>([]);
|
||||
const toastAPIError = useToastAPIError();
|
||||
|
||||
// on instantiation ==> call the request of the data...
|
||||
useEffect(() => {
|
||||
@ -49,6 +51,7 @@ export const useDataStore = <TYPE>(
|
||||
setIsLoading(false);
|
||||
})
|
||||
.catch((error: RestErrorResponse) => {
|
||||
toastAPIError(error);
|
||||
console.log(
|
||||
`[${restApiName}] catch error: ${JSON.stringify(error, null, 2)}`
|
||||
);
|
||||
@ -97,8 +100,8 @@ export const useDataStore = <TYPE>(
|
||||
filterData.push(responseData);
|
||||
setData(filterData);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(`catch an error: ... ${JSON.stringify(error, null, 2)}`);
|
||||
.catch((error: RestErrorResponse) => {
|
||||
toastAPIError(error);
|
||||
});
|
||||
},
|
||||
[data, setData]
|
||||
@ -114,6 +117,7 @@ export const useDataStore = <TYPE>(
|
||||
setData(filterData);
|
||||
})
|
||||
.catch((error) => {
|
||||
toastAPIError(error);
|
||||
console.log(
|
||||
`catch an error on delete: ... ${JSON.stringify(error, null, 2)}`
|
||||
);
|
||||
|
50
front2/src/utils/toastHook.ts
Normal file
50
front2/src/utils/toastHook.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { UseToastOptions, useToast } from '@chakra-ui/react';
|
||||
|
||||
import { RestErrorResponse } from '@/back-api';
|
||||
|
||||
export const toastDefaultConfig: UseToastOptions = {
|
||||
duration: 3000,
|
||||
isClosable: true,
|
||||
position: 'top-right',
|
||||
variant: 'solid',
|
||||
};
|
||||
|
||||
export const useToastError = () =>
|
||||
useToast({
|
||||
...toastDefaultConfig,
|
||||
status: 'error',
|
||||
duration: 5000,
|
||||
});
|
||||
|
||||
export const useToastWarning = () =>
|
||||
useToast({
|
||||
...toastDefaultConfig,
|
||||
status: 'warning',
|
||||
});
|
||||
|
||||
export const useToastSuccess = () =>
|
||||
useToast({
|
||||
...toastDefaultConfig,
|
||||
status: 'success',
|
||||
});
|
||||
|
||||
export const useToastInfo = () =>
|
||||
useToast({
|
||||
...toastDefaultConfig,
|
||||
status: 'info',
|
||||
});
|
||||
|
||||
export const useToastAPIError = () => {
|
||||
const toastError = useToastError();
|
||||
return useCallback(
|
||||
(error: RestErrorResponse) => {
|
||||
toastError({
|
||||
title: `[${error.status}] ${error.statusMessage}`,
|
||||
description: error.message,
|
||||
});
|
||||
},
|
||||
[toastError]
|
||||
);
|
||||
};
|
Loading…
Reference in New Issue
Block a user