[FEAT] migrate to react/chakra-ui v3 (not working)
This commit is contained in:
parent
bee72ee8a3
commit
99795f601b
@ -20,7 +20,7 @@
|
||||
<dependency>
|
||||
<groupId>kangaroo-and-rabbit</groupId>
|
||||
<artifactId>archidata</artifactId>
|
||||
<version>0.21.1-SNAPSHOT</version>
|
||||
<version>0.23.4</version>
|
||||
</dependency>
|
||||
<!-- Loopback of logger JDK logging API to SLF4J -->
|
||||
<dependency>
|
||||
|
@ -33,6 +33,7 @@ import org.kar.karso.migration.Initialization;
|
||||
import org.kar.karso.migration.Migration20231015;
|
||||
import org.kar.karso.migration.Migration20231126;
|
||||
import org.kar.karso.migration.Migration20240515;
|
||||
import org.kar.karso.migration.Migration20250204;
|
||||
import org.kar.karso.model.Application;
|
||||
import org.kar.karso.model.ApplicationToken;
|
||||
import org.kar.karso.model.Right;
|
||||
@ -76,6 +77,7 @@ public class WebLauncher {
|
||||
migrationEngine.add(new Migration20231015());
|
||||
migrationEngine.add(new Migration20231126());
|
||||
migrationEngine.add(new Migration20240515());
|
||||
migrationEngine.add(new Migration20250204());
|
||||
WebLauncher.LOGGER.info("Migrate the DB [START]");
|
||||
migrationEngine.migrateWaitAdmin(new DbConfig());
|
||||
WebLauncher.LOGGER.info("Migrate the DB [STOP]");
|
||||
|
@ -6,6 +6,7 @@ import java.util.List;
|
||||
import org.kar.archidata.api.DataResource;
|
||||
import org.kar.archidata.externalRestApi.AnalyzeApi;
|
||||
import org.kar.archidata.externalRestApi.TsGenerateApi;
|
||||
import org.kar.archidata.model.token.JwtToken;
|
||||
import org.kar.archidata.tools.ConfigBaseVariable;
|
||||
import org.kar.karso.api.ApplicationResource;
|
||||
import org.kar.karso.api.ApplicationTokenResource;
|
||||
@ -30,6 +31,7 @@ public class WebLauncherLocal extends WebLauncher {
|
||||
SystemConfigResource.class);
|
||||
final AnalyzeApi api = new AnalyzeApi();
|
||||
api.addAllApi(listOfResources);
|
||||
api.addModel(JwtToken.class);
|
||||
TsGenerateApi.generateApi(api, "../front/src/back-api/");
|
||||
LOGGER.info("Generate APIs (DONE)");
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ public class Initialization extends MigrationSqlStep {
|
||||
|
||||
public static final List<Class<?>> CLASSES_BASE = List.of(Settings.class, UserAuth.class, Application.class,
|
||||
ApplicationToken.class, RightDescription.class, Right.class);
|
||||
|
||||
// created object
|
||||
private Application app = null;
|
||||
private UserAuth user = null;
|
||||
@ -45,7 +46,7 @@ public class Initialization extends MigrationSqlStep {
|
||||
//app.id = 1L;
|
||||
app.name = "karso";
|
||||
app.description = "Root SSO interface";
|
||||
app.redirect = "https://atria-soft/karso";
|
||||
app.redirect = "https://atria-soft.org/karso";
|
||||
app.redirectDev = "http://localhost:4003/karso";
|
||||
app.notification = "";
|
||||
app.ttl = 666;
|
||||
|
87
back/src/org/kar/karso/migration/Migration20250204.java
Normal file
87
back/src/org/kar/karso/migration/Migration20250204.java
Normal file
@ -0,0 +1,87 @@
|
||||
package org.kar.karso.migration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.kar.archidata.dataAccess.DBAccess;
|
||||
import org.kar.archidata.dataAccess.options.AccessDeletedItems;
|
||||
import org.kar.archidata.dataAccess.options.OverrideTableName;
|
||||
import org.kar.archidata.filter.PartRight;
|
||||
import org.kar.archidata.migration.MigrationSqlStep;
|
||||
import org.kar.karso.migration.model.OIDConversion;
|
||||
import org.kar.karso.model.Right;
|
||||
|
||||
public class Migration20250204 extends MigrationSqlStep {
|
||||
|
||||
public static final int KARSO_INITIALISATION_ID = 1;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "migration-2025-02-04: mograte native id as ObjectId";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateStep() {
|
||||
// update migration update (last one)
|
||||
addAction("""
|
||||
ALTER TABLE `user_link_application` ADD `_id` binary(12) AFTER `uuid`;
|
||||
""");
|
||||
addAction((final DBAccess da) -> {
|
||||
final List<OIDConversion> datas = da.gets(OIDConversion.class, new AccessDeletedItems(),
|
||||
new OverrideTableName("user_link_application"));
|
||||
for (final OIDConversion elem : datas) {
|
||||
elem._id = new ObjectId();
|
||||
}
|
||||
for (final OIDConversion elem : datas) {
|
||||
da.update(elem, elem.uuid, List.of("_id"), new OverrideTableName("user_link_application"));
|
||||
}
|
||||
});
|
||||
addAction("""
|
||||
ALTER TABLE `user_link_application`
|
||||
CHANGE `uuid` `uuid` binary(16);
|
||||
""");
|
||||
addAction("""
|
||||
ALTER TABLE `user_link_application` DROP PRIMARY KEY;
|
||||
""");
|
||||
addAction("""
|
||||
ALTER TABLE `user_link_application`
|
||||
CHANGE `_id` `_id` binary(12) NOT NULL;
|
||||
""");
|
||||
addAction("""
|
||||
ALTER TABLE `user_link_application`
|
||||
ADD PRIMARY KEY `_id` (`_id`);
|
||||
""");
|
||||
addAction("""
|
||||
ALTER TABLE `user_link_application`
|
||||
DROP `uuid`;
|
||||
""");
|
||||
addAction("""
|
||||
ALTER TABLE `user`
|
||||
DROP `admin`;
|
||||
""");
|
||||
addAction("""
|
||||
ALTER TABLE `user`
|
||||
DROP `removed`;
|
||||
""");
|
||||
addAction("""
|
||||
ALTER TABLE `user` ADD `blockedReason` varchar(512) AFTER `blocked`;
|
||||
""");
|
||||
addAction("""
|
||||
ALTER TABLE `right`
|
||||
DROP `value`;
|
||||
""");
|
||||
addAction("""
|
||||
ALTER TABLE `right` ADD `value` JSON NOT NULL AFTER `rightDescriptionId`;
|
||||
""");
|
||||
addAction((final DBAccess da) -> {
|
||||
final List<Right> datas = da.gets(Right.class, new AccessDeletedItems());
|
||||
for (final Right elem : datas) {
|
||||
elem.value = PartRight.READ_WRITE;
|
||||
}
|
||||
for (final Right elem : datas) {
|
||||
da.update(elem, elem.id, List.of("value"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
13
back/src/org/kar/karso/migration/model/OIDConversion.java
Normal file
13
back/src/org/kar/karso/migration/model/OIDConversion.java
Normal file
@ -0,0 +1,13 @@
|
||||
package org.kar.karso.migration.model;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
public class OIDConversion {
|
||||
@Id
|
||||
public UUID uuid = null;
|
||||
public ObjectId _id = null;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package org.kar.karso.model;
|
||||
|
||||
import org.kar.archidata.dataAccess.options.CheckJPA;
|
||||
import org.kar.archidata.checker.CheckJPA;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
|
@ -7,7 +7,7 @@ import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import org.kar.archidata.dataAccess.options.CheckJPA;
|
||||
import org.kar.archidata.checker.CheckJPA;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
|
@ -4,7 +4,7 @@ import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
import org.kar.archidata.annotation.DataIfNotExists;
|
||||
import org.kar.archidata.dataAccess.options.CheckJPA;
|
||||
import org.kar.archidata.checker.CheckJPA;
|
||||
import org.kar.archidata.model.User;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.kar.karso.model;
|
||||
|
||||
import org.kar.archidata.dataAccess.options.CheckJPA;
|
||||
import org.kar.archidata.checker.CheckJPA;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
|
@ -11,7 +11,7 @@ CREATE TABLE `application` (
|
||||
*/
|
||||
|
||||
import org.kar.archidata.annotation.DataIfNotExists;
|
||||
import org.kar.archidata.model.UUIDGenericDataSoftDelete;
|
||||
import org.kar.archidata.model.OIDGenericDataSoftDelete;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@ -22,7 +22,7 @@ import jakarta.persistence.Table;
|
||||
@Table(name = "user_link_application")
|
||||
@DataIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class UserLinkApplication extends UUIDGenericDataSoftDelete {
|
||||
public class UserLinkApplication extends OIDGenericDataSoftDelete {
|
||||
@Column(name = "object1id")
|
||||
public Long userId;
|
||||
@Column(name = "object2id")
|
||||
|
2
front/.env.production
Normal file
2
front/.env.production
Normal file
@ -0,0 +1,2 @@
|
||||
# URL for database connection
|
||||
VITE_API_BASE_URL=karso/api/
|
27
front/.storybook/main.ts
Normal file
27
front/.storybook/main.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import type { StorybookConfig } from '@storybook/react-vite';
|
||||
|
||||
const config: StorybookConfig = {
|
||||
framework: {
|
||||
name: '@storybook/react-vite',
|
||||
options: {},
|
||||
},
|
||||
|
||||
core: {
|
||||
disableTelemetry: true,
|
||||
builder: '@storybook/builder-vite',
|
||||
},
|
||||
|
||||
stories: ['../src/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'],
|
||||
|
||||
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
|
||||
|
||||
staticDirs: ['../public'],
|
||||
|
||||
typescript: {
|
||||
reactDocgen: false,
|
||||
},
|
||||
|
||||
docs: {},
|
||||
};
|
||||
|
||||
export default config;
|
16
front/.storybook/preview-head.html
Normal file
16
front/.storybook/preview-head.html
Normal file
@ -0,0 +1,16 @@
|
||||
<style>
|
||||
html {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.docs-story > :first-child {
|
||||
padding: 0;
|
||||
}
|
||||
.docs-story > * {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
#root #start-ui-storybook-wrapper {
|
||||
min-height: 100vh;
|
||||
}
|
||||
</style>
|
43
front/.storybook/preview.tsx
Normal file
43
front/.storybook/preview.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { ChakraProvider } from '@chakra-ui/react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
|
||||
import theme from '../src/theme';
|
||||
|
||||
// .storybook/preview.js
|
||||
export const parameters = {
|
||||
options: {
|
||||
storySort: {
|
||||
order: ['StyleGuide', 'Components', 'Fields', 'App Layout'],
|
||||
},
|
||||
},
|
||||
actions: {},
|
||||
layout: 'fullscreen',
|
||||
backgrounds: { disable: true, grid: { disable: true } },
|
||||
chakra: {
|
||||
theme,
|
||||
},
|
||||
};
|
||||
|
||||
const DocumentationWrapper = ({ children }) => {
|
||||
return (
|
||||
<Box id="start-ui-storybook-wrapper" p="4" pb="8" flex="1">
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export const decorators = [
|
||||
(Story, context) => (
|
||||
<ChakraProvider theme={theme}>
|
||||
{/* Using MemoryRouter to avoid route clashing with Storybook */}
|
||||
<MemoryRouter>
|
||||
<DocumentationWrapper>
|
||||
<Story {...context} />
|
||||
</DocumentationWrapper>
|
||||
</MemoryRouter>
|
||||
</ChakraProvider>
|
||||
),
|
||||
];
|
2
front/LICENSE
Normal file
2
front/LICENSE
Normal file
@ -0,0 +1,2 @@
|
||||
Proprietary
|
||||
@copyright Edouard Dupin 2024
|
6
front/app-build.json
Normal file
6
front/app-build.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"display": "2025-02-04",
|
||||
"version": "0.0.1-dev\n - 2025-02-04T20:48:08+01:00",
|
||||
"commit": "0.0.1-dev\n",
|
||||
"date": "2025-02-04T20:48:08+01:00"
|
||||
}
|
25
front/build.js
Normal file
25
front/build.js
Normal file
@ -0,0 +1,25 @@
|
||||
const dayjs = require('dayjs');
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
const generateAppBuild = () => {
|
||||
const getVersion = () => fs.readFileSync('version.txt', 'utf8');
|
||||
|
||||
const commit = process.env.VERCEL_GIT_COMMIT_SHA
|
||||
? process.env.VERCEL_GIT_COMMIT_SHA
|
||||
: getVersion();
|
||||
|
||||
const appBuildContent = {
|
||||
display: `${dayjs().format('YYYY-MM-DD')}`,
|
||||
version: `${commit} - ${dayjs().format()}`,
|
||||
commit,
|
||||
date: dayjs().format(),
|
||||
};
|
||||
|
||||
fs.writeFileSync(
|
||||
'./app-build.json',
|
||||
JSON.stringify(appBuildContent, null, 2)
|
||||
);
|
||||
};
|
||||
|
||||
generateAppBuild();
|
10888
front/config sample.ts
Normal file
10888
front/config sample.ts
Normal file
File diff suppressed because it is too large
Load Diff
0
front/doc/.keep
Normal file
0
front/doc/.keep
Normal file
13
front/index.html
Normal file
13
front/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>karso</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</head>
|
||||
<body style="width:100vw;height:100vh;min-width:100%;min-height:100%;">
|
||||
<div id="root" style="width:100%;height:100%;min-width:100%;min-height:100%;"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
18
front/knip.ts
Normal file
18
front/knip.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import type { KnipConfig } from 'knip';
|
||||
|
||||
const config: KnipConfig = {
|
||||
// Ignoring mostly shell binaries
|
||||
ignoreBinaries: ['export', 'sleep'],
|
||||
ignore: [
|
||||
// Related to tests
|
||||
'tests/**',
|
||||
'**.conf.js',
|
||||
'steps.d.ts',
|
||||
'steps_file.js',
|
||||
'env_ci/codecept.conf.js',
|
||||
// Generic components are useful.
|
||||
'src/components/**',
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
92
front/package.json
Normal file
92
front/package.json
Normal file
@ -0,0 +1,92 @@
|
||||
{
|
||||
"name": "karso",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"description": "KAR web SSO application",
|
||||
"author": {
|
||||
"name": "Edouard DUPIN",
|
||||
"email": "yui.heero@gmail.farm"
|
||||
},
|
||||
"license": "PROPRIETARY",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"scripts": {
|
||||
"update_packages": "ncu --target minor",
|
||||
"upgrade_packages": "ncu --upgrade ",
|
||||
"install_dependency": "pnpm install",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest watch",
|
||||
"build": "tsc && vite build",
|
||||
"static:build": "node build.js && pnpm build",
|
||||
"dev": "vite",
|
||||
"pretty": "prettier -w .",
|
||||
"lint": "pnpm tsc --noEmit",
|
||||
"storybook": "storybook dev -p 3001",
|
||||
"storybook:build": "storybook build && mv ./storybook-static ./public/storybook"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx,js,jsx,json}": "prettier --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"@trivago/prettier-plugin-sort-imports": "5.2.2",
|
||||
"@chakra-ui/cli": "3.3.1",
|
||||
"@chakra-ui/react": "3.3.1",
|
||||
"@emotion/react": "11.14.0",
|
||||
"allotment": "1.20.2",
|
||||
"css-mediaquery": "0.1.2",
|
||||
"dayjs": "1.11.13",
|
||||
"history": "5.3.0",
|
||||
"next-themes": "^0.4.4",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-error-boundary": "5.0.0",
|
||||
"react-icons": "5.4.0",
|
||||
"react-router-dom": "7.1.1",
|
||||
"react-select": "5.9.0",
|
||||
"react-use": "17.6.0",
|
||||
"zod": "3.24.1",
|
||||
"zustand": "5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@chakra-ui/styled-system": "^2.12.0",
|
||||
"@playwright/test": "1.49.1",
|
||||
"@storybook/addon-actions": "8.4.7",
|
||||
"@storybook/addon-essentials": "8.4.7",
|
||||
"@storybook/addon-links": "8.4.7",
|
||||
"@storybook/addon-mdx-gfm": "8.4.7",
|
||||
"@storybook/react": "8.4.7",
|
||||
"@storybook/react-vite": "8.4.7",
|
||||
"@storybook/theming": "8.4.7",
|
||||
"@testing-library/jest-dom": "6.6.3",
|
||||
"@testing-library/react": "16.1.0",
|
||||
"@testing-library/user-event": "14.5.2",
|
||||
"@trivago/prettier-plugin-sort-imports": "5.2.1",
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/node": "22.10.6",
|
||||
"@types/react": "18.3.8",
|
||||
"@types/react-dom": "18.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.20.0",
|
||||
"@typescript-eslint/parser": "8.20.0",
|
||||
"@vitejs/plugin-react": "4.3.4",
|
||||
"eslint": "9.18.0",
|
||||
"eslint-plugin-codeceptjs": "1.3.0",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-react": "7.37.4",
|
||||
"eslint-plugin-react-hooks": "5.1.0",
|
||||
"eslint-plugin-storybook": "0.11.2",
|
||||
"jest": "29.7.0",
|
||||
"jest-environment-jsdom": "29.7.0",
|
||||
"knip": "5.42.0",
|
||||
"lint-staged": "15.3.0",
|
||||
"npm-check-updates": "^17.1.13",
|
||||
"prettier": "3.4.2",
|
||||
"puppeteer": "24.0.0",
|
||||
"react-is": "19.0.0",
|
||||
"storybook": "8.4.7",
|
||||
"ts-node": "10.9.2",
|
||||
"typescript": "5.7.3",
|
||||
"vite": "6.0.7",
|
||||
"vitest": "2.1.8"
|
||||
}
|
||||
}
|
0
front/playwright-report/.keep
Normal file
0
front/playwright-report/.keep
Normal file
11296
front/pnpm-lock.yaml
generated
Normal file
11296
front/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
front/prettier.config.js
Normal file
16
front/prettier.config.js
Normal file
@ -0,0 +1,16 @@
|
||||
// Using a JS file, allowing us to add comments
|
||||
module.exports = {
|
||||
// This plugins line is mandatory for the plugin to work with pnpm.
|
||||
// https://github.com/trivago/prettier-plugin-sort-imports/blob/61d069711008c530f5a41ca4e254781abc5de358/README.md?plain=1#L89-L96
|
||||
plugins: ['@trivago/prettier-plugin-sort-imports'],
|
||||
endOfLine: 'lf',
|
||||
semi: true,
|
||||
singleQuote: true,
|
||||
tabWidth: 2,
|
||||
trailingComma: 'es5',
|
||||
arrowParens: 'always',
|
||||
importOrder: ['^react$', '^(?!^react$|^@/|^[./]).*', '^@/(.*)$', '^[./]'],
|
||||
importOrderSeparation: true,
|
||||
importOrderSortSpecifiers: true,
|
||||
importOrderParserPlugins: ['jsx', 'typescript'],
|
||||
};
|
BIN
front/public/favicon.ico
Normal file
BIN
front/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
18
front/src/App.tsx
Normal file
18
front/src/App.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { EnvDevelopment } from './components/EnvDevelopment/EnvDevelopment';
|
||||
|
||||
import { ErrorBoundary } from '@/errors/ErrorBoundary';
|
||||
import { AppRoutes } from '@/scene/AppRoutes';
|
||||
import { ServiceContextProvider } from '@/service/ServiceContext';
|
||||
|
||||
export const App = () => {
|
||||
return (
|
||||
<ServiceContextProvider>
|
||||
<EnvDevelopment />
|
||||
<ErrorBoundary>
|
||||
<AppRoutes />
|
||||
</ErrorBoundary>
|
||||
</ServiceContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
66
front/src/assets/images/avatar_generic.svg
Normal file
66
front/src/assets/images/avatar_generic.svg
Normal file
@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="499"
|
||||
height="498"
|
||||
viewBox="0 0 499 498"
|
||||
version="1.1"
|
||||
id="svg10"
|
||||
sodipodi:docname="avatar_generic.svg"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs14" />
|
||||
<sodipodi:namedview
|
||||
id="namedview12"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="3.5060241"
|
||||
inkscape:cx="344.97766"
|
||||
inkscape:cy="288.78866"
|
||||
inkscape:window-width="3838"
|
||||
inkscape:window-height="2118"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="20"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg10" />
|
||||
<rect
|
||||
style="fill:#4c83e5;fill-opacity:1;stroke:none;stroke-width:8.82841587;stroke-opacity:1"
|
||||
width="500"
|
||||
height="500"
|
||||
x="0"
|
||||
y="-1.9999847"
|
||||
id="rect2" />
|
||||
<path
|
||||
style="fill:#4e4e4d;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
|
||||
d="m 198.78572,292.40268 -11.97951,28.10434 -7.03868,-39.62542 -32.77188,20.51375 14.30166,-59.1095 -47.70972,20.8692 30.95257,-58.44261 -40.08325,-11.9709 50.99682,-31.08004 -30.32488,-33.92052 41.38608,6.88643 c 0,0 -27.42157,-58.130582 -26.08007,-58.130582 1.34149,0 54.85161,37.962212 54.85161,37.962212 l 6.10019,-52.959427 22.55992,46.026947 33.20732,-51.718401 8.75817,54.113371 53.78031,-55.134502 -14.88381,76.635492 112.00146,-17.67965 -84.26404,54.10353 65.61018,10.26713 -53.91421,37.51917 40.05564,55.00796 -51.48529,-23.57551 7.49544,56.99322 -27.79947,-24.64556 -3.80452,36.62241 -23.37869,-22.14564 -5.89389,23.82189 -20.64297,-29.48769 -15.46209,46.92367 -7.2608,-54.46889 -21.32424,51.07849 z"
|
||||
id="path3162"
|
||||
sodipodi:nodetypes="cccccccccccsccccccccccccccccccccccc" />
|
||||
<path
|
||||
style="fill:#fbd0a6;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 126.90172,351.92657 55.90379,145.23242 168.77912,0.48055 8.10502,-147.83696 -56.19339,-10.73582 -9.91368,3.09728 -8.25753,-48.27446 -8.77147,-41.82541 -73.97306,-0.86753 -4.65072,84.85557 z"
|
||||
id="path3467"
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 45.319305,524.24985 50.878125,-168.64351 91.02866,-21.85078 124.81002,189.43887 15.4976,-12.33208 -130.63444,-191.36234 -9.67318,14.25555 124.81002,189.43887"
|
||||
id="path275"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 443.88287,524.02559 393.00474,355.38208 301.97608,333.5313 177.16606,522.97017 161.66846,510.63809 292.3029,319.27575 301.97608,333.5313 177.16606,522.97017"
|
||||
id="path275-6"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
style="fill:#fbd0a6;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 187.52213,139.10279 14.34593,25.22547 9.57434,-32.06638 13.85516,33.79118 18.44245,-38.89028 4.92331,44.11511 20.28515,-38.50102 -2.21466,39.35905 31.27764,-28.90273 -5.47875,45.83312 23.27252,-10.25342 -8.67174,30.59353 c 24.86464,-33.77835 23.21015,12.27629 3.94365,35.3922 l -12.95127,26.98572 -12.80079,22.10524 -26.61623,18.28625 -53.44338,-20.79546 c -21.13665,-20.42844 -23.443,-25.48798 -31.95313,-51.61993 -19.36867,-32.18928 -17.20493,-59.66994 4.27858,-38.00437 l -2.30548,-27.96686 11.07502,10.22035 -14.60569,-33.15484 22.1057,18.70679 z"
|
||||
id="path9531"
|
||||
sodipodi:nodetypes="cccccccccccccccccccccccc" />
|
||||
</svg>
|
After Width: | Height: | Size: 4.0 KiB |
135
front/src/assets/images/ikon.svg
Normal file
135
front/src/assets/images/ikon.svg
Normal file
@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="256"
|
||||
height="256"
|
||||
viewBox="0 0 67.733333 67.733333"
|
||||
version="1.1"
|
||||
id="svg18"
|
||||
sodipodi:docname="ikon_red.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs2">
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
id="filter5338"
|
||||
x="-0.12319682"
|
||||
y="-0.081815216"
|
||||
width="1.2463936"
|
||||
height="1.1636304">
|
||||
<feFlood
|
||||
flood-opacity="1"
|
||||
flood-color="rgb(165,29,45)"
|
||||
result="flood"
|
||||
id="feFlood5328" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite5330" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="2.1"
|
||||
result="blur"
|
||||
id="feGaussianBlur5332" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset5334" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite5336" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter1159"
|
||||
x="-0.11802406"
|
||||
width="1.2360481"
|
||||
y="-0.078379973"
|
||||
height="1.1567599">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.0118255"
|
||||
id="feGaussianBlur1161" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.9195959"
|
||||
inkscape:cx="89.966711"
|
||||
inkscape:cy="177.91312"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-text-baseline="false"
|
||||
inkscape:window-width="3838"
|
||||
inkscape:window-height="2118"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="20"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:deskcolor="#d1d1d1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4504"
|
||||
originx="0"
|
||||
originy="0"
|
||||
spacingy="1"
|
||||
spacingx="1"
|
||||
units="px"
|
||||
visible="true" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-229.26668)"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="text821-7"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:84.55024719px;line-height:1.25;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#2b3137;fill-opacity:1;stroke:none;stroke-width:2.11405313;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
transform="matrix(0.8407653,0,0,0.83753055,-37.28971,3.4402954)"
|
||||
aria-label="K">
|
||||
<path
|
||||
id="path823-5"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:84.55024719px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;opacity:0.775;fill:#2b3137;fill-opacity:1;stroke-width:2.11405313;filter:url(#filter5338);stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="M 65.200545 279.95309 L 65.200545 341.55532 L 74.14964 341.55532 L 74.14964 321.02125 L 80.541851 314.17676 L 99.718483 341.55532 L 106.11069 336.07998 L 85.655619 308.7008 L 106.11069 286.7982 L 99.718483 279.95309 L 74.14964 307.33227 L 74.14964 279.95309 L 65.200545 279.95309 z M 69.586585 307.95792 C 71.270821 307.95521 72.163105 308.76519 72.164982 309.94037 C 72.166858 311.11555 71.276967 311.92813 69.592731 311.93085 C 67.946259 311.9335 67.061695 311.12357 67.059818 309.94839 C 67.057941 308.77322 67.940113 307.96057 69.586585 307.95792 z M 69.588429 309.10309 C 68.568824 309.10473 68.017826 309.4316 68.01865 309.94716 C 68.019473 310.46272 68.571283 310.78793 69.590887 310.78629 C 70.655808 310.78458 71.206973 310.45717 71.20615 309.94161 C 71.205327 309.42604 70.653349 309.10138 69.588429 309.10309 z M 70.651134 317.13779 C 71.466818 317.13648 72.177771 317.82535 72.179733 319.0536 C 72.180798 319.7208 71.940317 320.4034 71.472902 320.93487 L 70.70891 320.29194 C 71.010421 319.91995 71.221049 319.45722 71.220287 318.97956 C 71.219524 318.50191 71.038049 318.28194 70.788812 318.28234 C 70.441392 318.2829 70.351355 318.5789 70.155738 319.04928 L 69.884683 319.68666 C 69.681646 320.24045 69.259204 320.7412 68.541704 320.74236 C 67.726021 320.74367 67.075662 320.0017 67.073955 318.93267 C 67.072998 318.33371 67.298319 317.73449 67.720551 317.28649 L 68.424309 317.85414 C 68.175617 318.19572 68.032626 318.50667 68.033401 318.9919 C 68.033994 319.36341 68.192626 319.61369 68.479626 319.61323 C 68.774179 319.61276 68.886895 319.27856 69.059842 318.80063 L 69.315531 318.20151 C 69.556173 317.54909 69.956292 317.13891 70.651134 317.13779 z M 72.09983 325.98324 L 72.102289 327.23453 L 70.32845 328.18534 L 70.32968 328.76904 L 72.104747 328.76595 L 72.106591 329.88027 L 67.18213 329.88829 L 67.179057 328.13722 C 67.177386 327.09093 67.538843 326.22575 68.7095 326.22387 C 69.434552 326.2227 69.895571 326.57849 70.130538 327.10126 L 72.09983 325.98324 z M 68.711344 327.32338 C 68.227976 327.32416 68.061959 327.6353 68.062903 328.22668 L 68.064133 328.77274 L 69.445833 328.77027 L 69.445219 328.22422 C 69.444274 327.63284 69.194712 327.3226 68.711344 327.32338 z M 72.114581 335.0286 L 72.116425 336.2114 L 70.946159 336.5088 L 70.948618 338.00258 L 72.119499 338.30368 L 72.121342 339.44145 L 67.195038 337.91003 L 67.192579 336.57544 L 72.114581 335.0286 z M 70.078294 336.73771 L 69.625307 336.85248 C 69.134592 336.98216 68.560497 337.13471 68.039547 337.24921 L 68.039547 337.27945 C 68.560872 337.39992 69.13541 337.53513 69.626536 337.66323 L 70.079523 337.77614 L 70.078294 336.73771 z " />
|
||||
</g>
|
||||
<g
|
||||
id="text821"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:84.55024719px;line-height:1.25;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#2b3137;fill-opacity:1;stroke:none;stroke-width:2.11376619;stroke-opacity:1;filter:url(#filter1159)"
|
||||
transform="matrix(1.0347881,0,0,0.96638144,-54.239583,-37.041665)"
|
||||
aria-label="K" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.6 KiB |
130
front/src/assets/images/ikon_gray.svg
Normal file
130
front/src/assets/images/ikon_gray.svg
Normal file
@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="256"
|
||||
height="256"
|
||||
viewBox="0 0 67.733333 67.733333"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="ikon_gray.svg"
|
||||
inkscape:export-filename="/home/heero/dev/perso/appl_pro/NoKomment/plugin/chrome/ikon.png"
|
||||
inkscape:export-xdpi="7.1250005"
|
||||
inkscape:export-ydpi="7.1250005">
|
||||
<defs
|
||||
id="defs2">
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter5338">
|
||||
<feFlood
|
||||
flood-opacity="1"
|
||||
flood-color="rgb(255,255,255)"
|
||||
result="flood"
|
||||
id="feFlood5328" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite5330" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="2.1"
|
||||
result="blur"
|
||||
id="feGaussianBlur5332" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset5334" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite5336" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter1159"
|
||||
x="-0.11802406"
|
||||
width="1.2360481"
|
||||
y="-0.078379973"
|
||||
height="1.1567599">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.0118255"
|
||||
id="feGaussianBlur1161" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.8"
|
||||
inkscape:cx="60.215971"
|
||||
inkscape:cy="128.86947"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-text-baseline="false"
|
||||
inkscape:window-width="1918"
|
||||
inkscape:window-height="1038"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="20"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4504" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-229.26668)"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="text821-7"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:84.55024719px;line-height:1.25;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#2b3137;fill-opacity:1;stroke:none;stroke-width:2.11376619;stroke-opacity:1"
|
||||
transform="matrix(0.8407653,0,0,0.83753055,-37.28971,3.4402954)"
|
||||
aria-label="K">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path823-5"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:84.55024719px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;opacity:0.775;fill:#2b3137;fill-opacity:1;stroke-width:2.11376619;filter:url(#filter5338)"
|
||||
d="m 65.200546,279.9533 h 8.949095 v 27.37877 l 25.568842,-27.37877 6.392207,6.84469 -20.455071,21.90302 20.455071,27.37876 -6.392207,5.47576 -19.176632,-27.37877 -6.39221,6.84469 v 20.53408 h -8.949095 z" />
|
||||
</g>
|
||||
<g
|
||||
id="text821"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:84.55024719px;line-height:1.25;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#2b3137;fill-opacity:1;stroke:none;stroke-width:2.11376619;stroke-opacity:1;filter:url(#filter1159)"
|
||||
transform="matrix(1.0347881,0,0,0.96638144,-54.239583,-37.041665)"
|
||||
aria-label="K" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.1 KiB |
12
front/src/assets/images/load.svg
Normal file
12
front/src/assets/images/load.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg fill="#2b3137" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8c-.45-.83-.7-1.79-.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z">
|
||||
<animateTransform attributeType="xml"
|
||||
attributeName="transform"
|
||||
type="rotate"
|
||||
from="0 12 12"
|
||||
to="360 12 12"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"/>
|
||||
</path>
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
</svg>
|
After Width: | Height: | Size: 713 B |
312
front/src/back-api/api/application-resource.ts
Normal file
312
front/src/back-api/api/application-resource.ts
Normal file
@ -0,0 +1,312 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import {
|
||||
HTTPMimeType,
|
||||
HTTPRequestModel,
|
||||
RESTConfig,
|
||||
RESTRequestJson,
|
||||
RESTRequestVoid,
|
||||
} from "../rest-tools";
|
||||
|
||||
import { z as zod } from "zod"
|
||||
import {
|
||||
AddUserDataWrite,
|
||||
Application,
|
||||
ApplicationSmall,
|
||||
ApplicationWrite,
|
||||
ClientToken,
|
||||
Long,
|
||||
RightDescription,
|
||||
ZodApplication,
|
||||
ZodApplicationSmall,
|
||||
ZodLong,
|
||||
ZodRightDescription,
|
||||
isApplication,
|
||||
isClientToken,
|
||||
} from "../model";
|
||||
|
||||
export namespace ApplicationResource {
|
||||
|
||||
export function addUser({
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
data: AddUserDataWrite,
|
||||
}): Promise<void> {
|
||||
return RESTRequestVoid({
|
||||
restModel: {
|
||||
endPoint: "/application/{id}/users",
|
||||
requestType: HTTPRequestModel.POST,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
});
|
||||
};
|
||||
export function create({
|
||||
restConfig,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
data: ApplicationWrite,
|
||||
}): Promise<Application> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/application/",
|
||||
requestType: HTTPRequestModel.POST,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
data,
|
||||
}, isApplication);
|
||||
};
|
||||
export function get({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
}): Promise<Application> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/application/{id}",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
}, isApplication);
|
||||
};
|
||||
|
||||
export const ZodGetApplicationUsersTypeReturn = zod.array(ZodLong);
|
||||
export type GetApplicationUsersTypeReturn = zod.infer<typeof ZodGetApplicationUsersTypeReturn>;
|
||||
|
||||
export function isGetApplicationUsersTypeReturn(data: any): data is GetApplicationUsersTypeReturn {
|
||||
try {
|
||||
ZodGetApplicationUsersTypeReturn.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetApplicationUsersTypeReturn' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getApplicationUsers({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
}): Promise<GetApplicationUsersTypeReturn> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/application/{id}/users",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
}, isGetApplicationUsersTypeReturn);
|
||||
};
|
||||
|
||||
export const ZodGetApplicationsSmallTypeReturn = zod.array(ZodApplicationSmall);
|
||||
export type GetApplicationsSmallTypeReturn = zod.infer<typeof ZodGetApplicationsSmallTypeReturn>;
|
||||
|
||||
export function isGetApplicationsSmallTypeReturn(data: any): data is GetApplicationsSmallTypeReturn {
|
||||
try {
|
||||
ZodGetApplicationsSmallTypeReturn.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetApplicationsSmallTypeReturn' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getApplicationsSmall({
|
||||
restConfig,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
}): Promise<GetApplicationsSmallTypeReturn> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/application/small",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
}, isGetApplicationsSmallTypeReturn);
|
||||
};
|
||||
export function getClientToken({
|
||||
restConfig,
|
||||
queries,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
queries: {
|
||||
application?: string,
|
||||
},
|
||||
}): Promise<ClientToken> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/application/get_token",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
queries,
|
||||
}, isClientToken);
|
||||
};
|
||||
|
||||
export const ZodGetRightsDescriptionTypeReturn = zod.array(ZodRightDescription);
|
||||
export type GetRightsDescriptionTypeReturn = zod.infer<typeof ZodGetRightsDescriptionTypeReturn>;
|
||||
|
||||
export function isGetRightsDescriptionTypeReturn(data: any): data is GetRightsDescriptionTypeReturn {
|
||||
try {
|
||||
ZodGetRightsDescriptionTypeReturn.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetRightsDescriptionTypeReturn' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getRightsDescription({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
}): Promise<GetRightsDescriptionTypeReturn> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/application/{id}/rights",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
}, isGetRightsDescriptionTypeReturn);
|
||||
};
|
||||
|
||||
export const ZodGetsTypeReturn = zod.array(ZodApplication);
|
||||
export type GetsTypeReturn = zod.infer<typeof ZodGetsTypeReturn>;
|
||||
|
||||
export function isGetsTypeReturn(data: any): data is GetsTypeReturn {
|
||||
try {
|
||||
ZodGetsTypeReturn.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetsTypeReturn' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function gets({
|
||||
restConfig,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
}): Promise<GetsTypeReturn> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/application/",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
}, isGetsTypeReturn);
|
||||
};
|
||||
export function logOut({
|
||||
restConfig,
|
||||
queries,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
queries: {
|
||||
application?: string,
|
||||
},
|
||||
}): Promise<string> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/application/return",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
queries,
|
||||
});
|
||||
};
|
||||
export function patch({
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
data: ApplicationWrite,
|
||||
}): Promise<Application> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/application/{id}",
|
||||
requestType: HTTPRequestModel.PATCH,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}, isApplication);
|
||||
};
|
||||
export function remove({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
}): Promise<void> {
|
||||
return RESTRequestVoid({
|
||||
restModel: {
|
||||
endPoint: "/application/{id}",
|
||||
requestType: HTTPRequestModel.DELETE,
|
||||
contentType: HTTPMimeType.TEXT_PLAIN,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
});
|
||||
};
|
||||
export function removeUser({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
userId: Long,
|
||||
},
|
||||
}): Promise<void> {
|
||||
return RESTRequestVoid({
|
||||
restModel: {
|
||||
endPoint: "/application/{id}/users/${userId}",
|
||||
requestType: HTTPRequestModel.DELETE,
|
||||
contentType: HTTPMimeType.TEXT_PLAIN,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
});
|
||||
};
|
||||
}
|
100
front/src/back-api/api/application-token-resource.ts
Normal file
100
front/src/back-api/api/application-token-resource.ts
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import {
|
||||
HTTPMimeType,
|
||||
HTTPRequestModel,
|
||||
RESTConfig,
|
||||
RESTRequestJson,
|
||||
RESTRequestVoid,
|
||||
} from "../rest-tools";
|
||||
|
||||
import { z as zod } from "zod"
|
||||
import {
|
||||
ApplicationToken,
|
||||
CreateTokenRequestWrite,
|
||||
Integer,
|
||||
Long,
|
||||
ZodApplicationToken,
|
||||
isApplicationToken,
|
||||
} from "../model";
|
||||
|
||||
export namespace ApplicationTokenResource {
|
||||
|
||||
export function create({
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
applicationId: Long,
|
||||
},
|
||||
data: CreateTokenRequestWrite,
|
||||
}): Promise<ApplicationToken> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/application_token/{applicationId}/create",
|
||||
requestType: HTTPRequestModel.POST,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}, isApplicationToken);
|
||||
};
|
||||
|
||||
export const ZodGetsTypeReturn = zod.array(ZodApplicationToken);
|
||||
export type GetsTypeReturn = zod.infer<typeof ZodGetsTypeReturn>;
|
||||
|
||||
export function isGetsTypeReturn(data: any): data is GetsTypeReturn {
|
||||
try {
|
||||
ZodGetsTypeReturn.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetsTypeReturn' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function gets({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
applicationId: Long,
|
||||
},
|
||||
}): Promise<GetsTypeReturn> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/application_token/{applicationId}",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
}, isGetsTypeReturn);
|
||||
};
|
||||
export function remove({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
tokenId: Integer,
|
||||
applicationId: Long,
|
||||
},
|
||||
}): Promise<void> {
|
||||
return RESTRequestVoid({
|
||||
restModel: {
|
||||
endPoint: "/application_token/{applicationId}/{tokenId}",
|
||||
requestType: HTTPRequestModel.DELETE,
|
||||
contentType: HTTPMimeType.TEXT_PLAIN,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
});
|
||||
};
|
||||
}
|
128
front/src/back-api/api/data-resource.ts
Normal file
128
front/src/back-api/api/data-resource.ts
Normal file
@ -0,0 +1,128 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import {
|
||||
HTTPMimeType,
|
||||
HTTPRequestModel,
|
||||
RESTConfig,
|
||||
RESTRequestJson,
|
||||
RESTRequestVoid,
|
||||
} from "../rest-tools";
|
||||
|
||||
import {
|
||||
ObjectId,
|
||||
} from "../model";
|
||||
|
||||
export namespace DataResource {
|
||||
|
||||
/**
|
||||
* Get back some data from the data environment (with a beautiful name (permit download with basic name)
|
||||
*/
|
||||
export function retrieveDataFull({
|
||||
restConfig,
|
||||
queries,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
queries: {
|
||||
Authorization?: string,
|
||||
},
|
||||
params: {
|
||||
name: string,
|
||||
oid: ObjectId,
|
||||
},
|
||||
data: string,
|
||||
}): Promise<object> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/data/{oid}/{name}",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
queries,
|
||||
data,
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Get back some data from the data environment
|
||||
*/
|
||||
export function retrieveDataId({
|
||||
restConfig,
|
||||
queries,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
queries: {
|
||||
Authorization?: string,
|
||||
},
|
||||
params: {
|
||||
oid: ObjectId,
|
||||
},
|
||||
data: string,
|
||||
}): Promise<object> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/data/{oid}",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
queries,
|
||||
data,
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Get a thumbnail of from the data environment (if resize is possible)
|
||||
*/
|
||||
export function retrieveDataThumbnailId({
|
||||
restConfig,
|
||||
queries,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
queries: {
|
||||
Authorization?: string,
|
||||
},
|
||||
params: {
|
||||
oid: ObjectId,
|
||||
},
|
||||
data: string,
|
||||
}): Promise<object> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/data/thumbnail/{oid}",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
queries,
|
||||
data,
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Insert a new data in the data environment
|
||||
*/
|
||||
export function uploadFile({
|
||||
restConfig,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
data: {
|
||||
file: File,
|
||||
},
|
||||
}): Promise<void> {
|
||||
return RESTRequestVoid({
|
||||
restModel: {
|
||||
endPoint: "/data//upload/",
|
||||
requestType: HTTPRequestModel.POST,
|
||||
contentType: HTTPMimeType.MULTIPART,
|
||||
},
|
||||
restConfig,
|
||||
data,
|
||||
});
|
||||
};
|
||||
}
|
6
front/src/back-api/api/front.ts
Normal file
6
front/src/back-api/api/front.ts
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
export namespace Front {
|
||||
|
||||
}
|
11
front/src/back-api/api/index.ts
Normal file
11
front/src/back-api/api/index.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
export * from "./application-resource"
|
||||
export * from "./application-token-resource"
|
||||
export * from "./data-resource"
|
||||
export * from "./front"
|
||||
export * from "./public-key-resource"
|
||||
export * from "./right-resource"
|
||||
export * from "./system-config-resource"
|
||||
export * from "./user-resource"
|
46
front/src/back-api/api/public-key-resource.ts
Normal file
46
front/src/back-api/api/public-key-resource.ts
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import {
|
||||
HTTPMimeType,
|
||||
HTTPRequestModel,
|
||||
RESTConfig,
|
||||
RESTRequestJson,
|
||||
} from "../rest-tools";
|
||||
|
||||
import {
|
||||
PublicKey,
|
||||
isPublicKey,
|
||||
} from "../model";
|
||||
|
||||
export namespace PublicKeyResource {
|
||||
|
||||
export function getKey({
|
||||
restConfig,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
}): Promise<PublicKey> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/public_key/",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
}, isPublicKey);
|
||||
};
|
||||
export function getKeyPem({
|
||||
restConfig,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
}): Promise<string> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/public_key//pem",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
});
|
||||
};
|
||||
}
|
130
front/src/back-api/api/right-resource.ts
Normal file
130
front/src/back-api/api/right-resource.ts
Normal file
@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import {
|
||||
HTTPMimeType,
|
||||
HTTPRequestModel,
|
||||
RESTConfig,
|
||||
RESTRequestJson,
|
||||
RESTRequestVoid,
|
||||
} from "../rest-tools";
|
||||
|
||||
import { z as zod } from "zod"
|
||||
import {
|
||||
Long,
|
||||
Right,
|
||||
RightWrite,
|
||||
ZodRight,
|
||||
isRight,
|
||||
} from "../model";
|
||||
|
||||
export namespace RightResource {
|
||||
|
||||
export function get({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
}): Promise<Right> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/right/{id}",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
}, isRight);
|
||||
};
|
||||
|
||||
export const ZodGetsTypeReturn = zod.array(ZodRight);
|
||||
export type GetsTypeReturn = zod.infer<typeof ZodGetsTypeReturn>;
|
||||
|
||||
export function isGetsTypeReturn(data: any): data is GetsTypeReturn {
|
||||
try {
|
||||
ZodGetsTypeReturn.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetsTypeReturn' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function gets({
|
||||
restConfig,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
}): Promise<GetsTypeReturn> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/right/",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
}, isGetsTypeReturn);
|
||||
};
|
||||
export function patch({
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
data: RightWrite,
|
||||
}): Promise<Right> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/right/{id}",
|
||||
requestType: HTTPRequestModel.PATCH,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}, isRight);
|
||||
};
|
||||
export function post({
|
||||
restConfig,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
data: RightWrite,
|
||||
}): Promise<Right> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/right/",
|
||||
requestType: HTTPRequestModel.POST,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
data,
|
||||
}, isRight);
|
||||
};
|
||||
export function remove({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
}): Promise<void> {
|
||||
return RESTRequestVoid({
|
||||
restModel: {
|
||||
endPoint: "/right/{id}",
|
||||
requestType: HTTPRequestModel.DELETE,
|
||||
contentType: HTTPMimeType.TEXT_PLAIN,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
});
|
||||
};
|
||||
}
|
89
front/src/back-api/api/system-config-resource.ts
Normal file
89
front/src/back-api/api/system-config-resource.ts
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import {
|
||||
HTTPMimeType,
|
||||
HTTPRequestModel,
|
||||
RESTConfig,
|
||||
RESTRequestJson,
|
||||
RESTRequestVoid,
|
||||
} from "../rest-tools";
|
||||
|
||||
import { z as zod } from "zod"
|
||||
import {
|
||||
GetSignUpAvailable,
|
||||
isGetSignUpAvailable,
|
||||
} from "../model";
|
||||
|
||||
export namespace SystemConfigResource {
|
||||
|
||||
|
||||
export const ZodGetKeyTypeReturn = zod.record(zod.string(), zod.any());
|
||||
export type GetKeyTypeReturn = zod.infer<typeof ZodGetKeyTypeReturn>;
|
||||
|
||||
export function isGetKeyTypeReturn(data: any): data is GetKeyTypeReturn {
|
||||
try {
|
||||
ZodGetKeyTypeReturn.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetKeyTypeReturn' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getKey({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
key: string,
|
||||
},
|
||||
}): Promise<GetKeyTypeReturn> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/system_config/key/{key}",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
}, isGetKeyTypeReturn);
|
||||
};
|
||||
export function isSignUpAvailable({
|
||||
restConfig,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
}): Promise<GetSignUpAvailable> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/system_config/is_sign_up_availlable",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
}, isGetSignUpAvailable);
|
||||
};
|
||||
export function setKey({
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
key: string,
|
||||
},
|
||||
data: object,
|
||||
}): Promise<void> {
|
||||
return RESTRequestVoid({
|
||||
restModel: {
|
||||
endPoint: "/system_config/key/{key}",
|
||||
requestType: HTTPRequestModel.PATCH,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
});
|
||||
};
|
||||
}
|
324
front/src/back-api/api/user-resource.ts
Normal file
324
front/src/back-api/api/user-resource.ts
Normal file
@ -0,0 +1,324 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import {
|
||||
HTTPMimeType,
|
||||
HTTPRequestModel,
|
||||
RESTConfig,
|
||||
RESTRequestJson,
|
||||
RESTRequestVoid,
|
||||
} from "../rest-tools";
|
||||
|
||||
import { z as zod } from "zod"
|
||||
import {
|
||||
ChangePasswordWrite,
|
||||
DataGetTokenWrite,
|
||||
GetToken,
|
||||
Long,
|
||||
PartRight,
|
||||
UserAuth,
|
||||
UserAuthGet,
|
||||
UserCreateWrite,
|
||||
UserOut,
|
||||
ZodPartRight,
|
||||
ZodUserAuthGet,
|
||||
isGetToken,
|
||||
isUserAuth,
|
||||
isUserAuthGet,
|
||||
isUserOut,
|
||||
} from "../model";
|
||||
|
||||
export namespace UserResource {
|
||||
|
||||
export function changePassword({
|
||||
restConfig,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
data: ChangePasswordWrite,
|
||||
}): Promise<void> {
|
||||
return RESTRequestVoid({
|
||||
restModel: {
|
||||
endPoint: "/users/password",
|
||||
requestType: HTTPRequestModel.POST,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
data,
|
||||
});
|
||||
};
|
||||
export function create({
|
||||
restConfig,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
data: UserCreateWrite,
|
||||
}): Promise<UserAuthGet> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/users/",
|
||||
requestType: HTTPRequestModel.POST,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
data,
|
||||
}, isUserAuthGet);
|
||||
};
|
||||
export function get({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
}): Promise<UserAuthGet> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/users/{id}",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
}, isUserAuthGet);
|
||||
};
|
||||
|
||||
export const ZodGetApplicationRightTypeReturn = zod.record(zod.string(), ZodPartRight);
|
||||
export type GetApplicationRightTypeReturn = zod.infer<typeof ZodGetApplicationRightTypeReturn>;
|
||||
|
||||
export function isGetApplicationRightTypeReturn(data: any): data is GetApplicationRightTypeReturn {
|
||||
try {
|
||||
ZodGetApplicationRightTypeReturn.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetApplicationRightTypeReturn' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getApplicationRight({
|
||||
restConfig,
|
||||
params,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
applicationId: Long,
|
||||
userId: Long,
|
||||
},
|
||||
}): Promise<GetApplicationRightTypeReturn> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/users/{userId}/application/{applicationId}/rights",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
}, isGetApplicationRightTypeReturn);
|
||||
};
|
||||
export function getMe({
|
||||
restConfig,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
}): Promise<UserOut> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/users/me",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
}, isUserOut);
|
||||
};
|
||||
export function getToken({
|
||||
restConfig,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
data: DataGetTokenWrite,
|
||||
}): Promise<GetToken> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/users/get_token",
|
||||
requestType: HTTPRequestModel.POST,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
data,
|
||||
}, isGetToken);
|
||||
};
|
||||
|
||||
export const ZodGetsTypeReturn = zod.array(ZodUserAuthGet);
|
||||
export type GetsTypeReturn = zod.infer<typeof ZodGetsTypeReturn>;
|
||||
|
||||
export function isGetsTypeReturn(data: any): data is GetsTypeReturn {
|
||||
try {
|
||||
ZodGetsTypeReturn.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetsTypeReturn' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function gets({
|
||||
restConfig,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
}): Promise<GetsTypeReturn> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/users/",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
}, isGetsTypeReturn);
|
||||
};
|
||||
export function isEmailExist({
|
||||
restConfig,
|
||||
queries,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
queries: {
|
||||
email?: string,
|
||||
},
|
||||
}): Promise<boolean> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/users/is_email_exist",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
queries,
|
||||
});
|
||||
};
|
||||
export function isLoginExist({
|
||||
restConfig,
|
||||
queries,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
queries: {
|
||||
login?: string,
|
||||
},
|
||||
}): Promise<boolean> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/users/is_login_exist",
|
||||
requestType: HTTPRequestModel.GET,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
queries,
|
||||
});
|
||||
};
|
||||
export function linkApplication({
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
applicationId: Long,
|
||||
userId: Long,
|
||||
},
|
||||
data: boolean,
|
||||
}): Promise<UserAuth> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/users/{userId}/application/{applicationId}/link",
|
||||
requestType: HTTPRequestModel.POST,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}, isUserAuth);
|
||||
};
|
||||
|
||||
export const ZodPatchApplicationRightTypeReturn = zod.record(zod.string(), ZodPartRight);
|
||||
export type PatchApplicationRightTypeReturn = zod.infer<typeof ZodPatchApplicationRightTypeReturn>;
|
||||
|
||||
export function isPatchApplicationRightTypeReturn(data: any): data is PatchApplicationRightTypeReturn {
|
||||
try {
|
||||
ZodPatchApplicationRightTypeReturn.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodPatchApplicationRightTypeReturn' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function patchApplicationRight({
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
applicationId: Long,
|
||||
userId: Long,
|
||||
},
|
||||
data: {[key: string]: PartRight;},
|
||||
}): Promise<PatchApplicationRightTypeReturn> {
|
||||
return RESTRequestJson({
|
||||
restModel: {
|
||||
endPoint: "/users/{userId}/application/{applicationId}/rights",
|
||||
requestType: HTTPRequestModel.PATCH,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
accept: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}, isPatchApplicationRightTypeReturn);
|
||||
};
|
||||
export function setAdmin({
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
data: boolean,
|
||||
}): Promise<void> {
|
||||
return RESTRequestVoid({
|
||||
restModel: {
|
||||
endPoint: "/users/{id}/set_admin",
|
||||
requestType: HTTPRequestModel.POST,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
});
|
||||
};
|
||||
export function setBlocked({
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
}: {
|
||||
restConfig: RESTConfig,
|
||||
params: {
|
||||
id: Long,
|
||||
},
|
||||
data: boolean,
|
||||
}): Promise<void> {
|
||||
return RESTRequestVoid({
|
||||
restModel: {
|
||||
endPoint: "/users/{id}/set_blocked",
|
||||
requestType: HTTPRequestModel.POST,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
},
|
||||
restConfig,
|
||||
params,
|
||||
data,
|
||||
});
|
||||
};
|
||||
}
|
7
front/src/back-api/index.ts
Normal file
7
front/src/back-api/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
export * from "./model";
|
||||
export * from "./api";
|
||||
export * from "./rest-tools";
|
||||
|
39
front/src/back-api/model/add-user-data.ts
Normal file
39
front/src/back-api/model/add-user-data.ts
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodLong} from "./long";
|
||||
|
||||
export const ZodAddUserData = zod.object({
|
||||
userId: ZodLong.optional(),
|
||||
|
||||
});
|
||||
|
||||
export type AddUserData = zod.infer<typeof ZodAddUserData>;
|
||||
|
||||
export function isAddUserData(data: any): data is AddUserData {
|
||||
try {
|
||||
ZodAddUserData.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodAddUserData' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodAddUserDataWrite = zod.object({
|
||||
userId: ZodLong.nullable().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type AddUserDataWrite = zod.infer<typeof ZodAddUserDataWrite>;
|
||||
|
||||
export function isAddUserDataWrite(data: any): data is AddUserDataWrite {
|
||||
try {
|
||||
ZodAddUserDataWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodAddUserDataWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
45
front/src/back-api/model/application-small.ts
Normal file
45
front/src/back-api/model/application-small.ts
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodLong} from "./long";
|
||||
|
||||
export const ZodApplicationSmall = zod.object({
|
||||
id: ZodLong.optional(),
|
||||
name: zod.string().optional(),
|
||||
description: zod.string().optional(),
|
||||
redirect: zod.string().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type ApplicationSmall = zod.infer<typeof ZodApplicationSmall>;
|
||||
|
||||
export function isApplicationSmall(data: any): data is ApplicationSmall {
|
||||
try {
|
||||
ZodApplicationSmall.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodApplicationSmall' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodApplicationSmallWrite = zod.object({
|
||||
id: ZodLong.nullable().optional(),
|
||||
name: zod.string().nullable().optional(),
|
||||
description: zod.string().nullable().optional(),
|
||||
redirect: zod.string().nullable().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type ApplicationSmallWrite = zod.infer<typeof ZodApplicationSmallWrite>;
|
||||
|
||||
export function isApplicationSmallWrite(data: any): data is ApplicationSmallWrite {
|
||||
try {
|
||||
ZodApplicationSmallWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodApplicationSmallWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
33
front/src/back-api/model/application-token.ts
Normal file
33
front/src/back-api/model/application-token.ts
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodGenericToken, ZodGenericTokenWrite } from "./generic-token";
|
||||
|
||||
export const ZodApplicationToken = ZodGenericToken;
|
||||
|
||||
export type ApplicationToken = zod.infer<typeof ZodApplicationToken>;
|
||||
|
||||
export function isApplicationToken(data: any): data is ApplicationToken {
|
||||
try {
|
||||
ZodApplicationToken.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodApplicationToken' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodApplicationTokenWrite = ZodGenericTokenWrite;
|
||||
|
||||
export type ApplicationTokenWrite = zod.infer<typeof ZodApplicationTokenWrite>;
|
||||
|
||||
export function isApplicationTokenWrite(data: any): data is ApplicationTokenWrite {
|
||||
try {
|
||||
ZodApplicationTokenWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodApplicationTokenWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
64
front/src/back-api/model/application.ts
Normal file
64
front/src/back-api/model/application.ts
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodInteger} from "./integer";
|
||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
||||
|
||||
export const ZodApplication = ZodGenericDataSoftDelete.extend({
|
||||
name: zod.string().optional(),
|
||||
description: zod.string().optional(),
|
||||
redirect: zod.string(),
|
||||
redirectDev: zod.string().optional(),
|
||||
notification: zod.string().optional(),
|
||||
/**
|
||||
* Expiration time
|
||||
*/
|
||||
ttl: ZodInteger,
|
||||
/**
|
||||
* Right is manage with Karso
|
||||
*/
|
||||
manageRight: zod.boolean(),
|
||||
|
||||
});
|
||||
|
||||
export type Application = zod.infer<typeof ZodApplication>;
|
||||
|
||||
export function isApplication(data: any): data is Application {
|
||||
try {
|
||||
ZodApplication.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodApplication' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodApplicationWrite = ZodGenericDataSoftDeleteWrite.extend({
|
||||
name: zod.string().nullable().optional(),
|
||||
description: zod.string().nullable().optional(),
|
||||
redirect: zod.string().optional(),
|
||||
redirectDev: zod.string().nullable().optional(),
|
||||
notification: zod.string().nullable().optional(),
|
||||
/**
|
||||
* Expiration time
|
||||
*/
|
||||
ttl: ZodInteger.optional(),
|
||||
/**
|
||||
* Right is manage with Karso
|
||||
*/
|
||||
manageRight: zod.boolean().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type ApplicationWrite = zod.infer<typeof ZodApplicationWrite>;
|
||||
|
||||
export function isApplicationWrite(data: any): data is ApplicationWrite {
|
||||
try {
|
||||
ZodApplicationWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodApplicationWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
46
front/src/back-api/model/change-password.ts
Normal file
46
front/src/back-api/model/change-password.ts
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodChangePassword = zod.object({
|
||||
method: zod.string().min(2).max(2),
|
||||
login: zod.string().min(3).max(128),
|
||||
time: zod.string().min(20).max(64),
|
||||
password: zod.string().min(128).max(128),
|
||||
newPassword: zod.string().min(128).max(128),
|
||||
|
||||
});
|
||||
|
||||
export type ChangePassword = zod.infer<typeof ZodChangePassword>;
|
||||
|
||||
export function isChangePassword(data: any): data is ChangePassword {
|
||||
try {
|
||||
ZodChangePassword.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodChangePassword' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodChangePasswordWrite = zod.object({
|
||||
method: zod.string().min(2).max(2).optional(),
|
||||
login: zod.string().min(3).max(128).optional(),
|
||||
time: zod.string().min(20).max(64).optional(),
|
||||
password: zod.string().min(128).max(128).optional(),
|
||||
newPassword: zod.string().min(128).max(128).optional(),
|
||||
|
||||
});
|
||||
|
||||
export type ChangePasswordWrite = zod.infer<typeof ZodChangePasswordWrite>;
|
||||
|
||||
export function isChangePasswordWrite(data: any): data is ChangePasswordWrite {
|
||||
try {
|
||||
ZodChangePasswordWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodChangePasswordWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
40
front/src/back-api/model/client-token.ts
Normal file
40
front/src/back-api/model/client-token.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodClientToken = zod.object({
|
||||
url: zod.string().optional(),
|
||||
jwt: zod.string().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type ClientToken = zod.infer<typeof ZodClientToken>;
|
||||
|
||||
export function isClientToken(data: any): data is ClientToken {
|
||||
try {
|
||||
ZodClientToken.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodClientToken' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodClientTokenWrite = zod.object({
|
||||
url: zod.string().nullable().optional(),
|
||||
jwt: zod.string().nullable().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type ClientTokenWrite = zod.infer<typeof ZodClientTokenWrite>;
|
||||
|
||||
export function isClientTokenWrite(data: any): data is ClientTokenWrite {
|
||||
try {
|
||||
ZodClientTokenWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodClientTokenWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
41
front/src/back-api/model/create-token-request.ts
Normal file
41
front/src/back-api/model/create-token-request.ts
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodInteger} from "./integer";
|
||||
|
||||
export const ZodCreateTokenRequest = zod.object({
|
||||
name: zod.string().optional(),
|
||||
validity: ZodInteger.optional(),
|
||||
|
||||
});
|
||||
|
||||
export type CreateTokenRequest = zod.infer<typeof ZodCreateTokenRequest>;
|
||||
|
||||
export function isCreateTokenRequest(data: any): data is CreateTokenRequest {
|
||||
try {
|
||||
ZodCreateTokenRequest.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodCreateTokenRequest' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodCreateTokenRequestWrite = zod.object({
|
||||
name: zod.string().nullable().optional(),
|
||||
validity: ZodInteger.nullable().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type CreateTokenRequestWrite = zod.infer<typeof ZodCreateTokenRequestWrite>;
|
||||
|
||||
export function isCreateTokenRequestWrite(data: any): data is CreateTokenRequestWrite {
|
||||
try {
|
||||
ZodCreateTokenRequestWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodCreateTokenRequestWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
44
front/src/back-api/model/data-get-token.ts
Normal file
44
front/src/back-api/model/data-get-token.ts
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodDataGetToken = zod.object({
|
||||
login: zod.string().min(3).max(128),
|
||||
method: zod.string().min(2).max(2),
|
||||
time: zod.string().min(20).max(64),
|
||||
password: zod.string().min(128).max(128),
|
||||
|
||||
});
|
||||
|
||||
export type DataGetToken = zod.infer<typeof ZodDataGetToken>;
|
||||
|
||||
export function isDataGetToken(data: any): data is DataGetToken {
|
||||
try {
|
||||
ZodDataGetToken.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodDataGetToken' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodDataGetTokenWrite = zod.object({
|
||||
login: zod.string().min(3).max(128).optional(),
|
||||
method: zod.string().min(2).max(2).optional(),
|
||||
time: zod.string().min(20).max(64).optional(),
|
||||
password: zod.string().min(128).max(128).optional(),
|
||||
|
||||
});
|
||||
|
||||
export type DataGetTokenWrite = zod.infer<typeof ZodDataGetTokenWrite>;
|
||||
|
||||
export function isDataGetTokenWrite(data: any): data is DataGetTokenWrite {
|
||||
try {
|
||||
ZodDataGetTokenWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodDataGetTokenWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
39
front/src/back-api/model/generic-data-soft-delete.ts
Normal file
39
front/src/back-api/model/generic-data-soft-delete.ts
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodGenericData, ZodGenericDataWrite } from "./generic-data";
|
||||
|
||||
export const ZodGenericDataSoftDelete = ZodGenericData.extend({
|
||||
/**
|
||||
* Deleted state
|
||||
*/
|
||||
deleted: zod.boolean().readonly().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type GenericDataSoftDelete = zod.infer<typeof ZodGenericDataSoftDelete>;
|
||||
|
||||
export function isGenericDataSoftDelete(data: any): data is GenericDataSoftDelete {
|
||||
try {
|
||||
ZodGenericDataSoftDelete.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGenericDataSoftDelete' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodGenericDataSoftDeleteWrite = ZodGenericDataWrite;
|
||||
|
||||
export type GenericDataSoftDeleteWrite = zod.infer<typeof ZodGenericDataSoftDeleteWrite>;
|
||||
|
||||
export function isGenericDataSoftDeleteWrite(data: any): data is GenericDataSoftDeleteWrite {
|
||||
try {
|
||||
ZodGenericDataSoftDeleteWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGenericDataSoftDeleteWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
40
front/src/back-api/model/generic-data.ts
Normal file
40
front/src/back-api/model/generic-data.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodLong} from "./long";
|
||||
import {ZodGenericTiming, ZodGenericTimingWrite } from "./generic-timing";
|
||||
|
||||
export const ZodGenericData = ZodGenericTiming.extend({
|
||||
/**
|
||||
* Unique Id of the object
|
||||
*/
|
||||
id: ZodLong.readonly(),
|
||||
|
||||
});
|
||||
|
||||
export type GenericData = zod.infer<typeof ZodGenericData>;
|
||||
|
||||
export function isGenericData(data: any): data is GenericData {
|
||||
try {
|
||||
ZodGenericData.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGenericData' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodGenericDataWrite = ZodGenericTimingWrite;
|
||||
|
||||
export type GenericDataWrite = zod.infer<typeof ZodGenericDataWrite>;
|
||||
|
||||
export function isGenericDataWrite(data: any): data is GenericDataWrite {
|
||||
try {
|
||||
ZodGenericDataWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGenericDataWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
45
front/src/back-api/model/generic-timing.ts
Normal file
45
front/src/back-api/model/generic-timing.ts
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodIsoDate} from "./iso-date";
|
||||
|
||||
export const ZodGenericTiming = zod.object({
|
||||
/**
|
||||
* Create time of the object
|
||||
*/
|
||||
createdAt: ZodIsoDate.readonly().optional(),
|
||||
/**
|
||||
* When update the object
|
||||
*/
|
||||
updatedAt: ZodIsoDate.readonly().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type GenericTiming = zod.infer<typeof ZodGenericTiming>;
|
||||
|
||||
export function isGenericTiming(data: any): data is GenericTiming {
|
||||
try {
|
||||
ZodGenericTiming.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGenericTiming' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodGenericTimingWrite = zod.object({
|
||||
|
||||
});
|
||||
|
||||
export type GenericTimingWrite = zod.infer<typeof ZodGenericTimingWrite>;
|
||||
|
||||
export function isGenericTimingWrite(data: any): data is GenericTimingWrite {
|
||||
try {
|
||||
ZodGenericTimingWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGenericTimingWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
47
front/src/back-api/model/generic-token.ts
Normal file
47
front/src/back-api/model/generic-token.ts
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodLong} from "./long";
|
||||
import {ZodTimestamp} from "./timestamp";
|
||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
||||
|
||||
export const ZodGenericToken = ZodGenericDataSoftDelete.extend({
|
||||
parentId: ZodLong,
|
||||
name: zod.string(),
|
||||
endValidityTime: ZodTimestamp,
|
||||
token: zod.string(),
|
||||
|
||||
});
|
||||
|
||||
export type GenericToken = zod.infer<typeof ZodGenericToken>;
|
||||
|
||||
export function isGenericToken(data: any): data is GenericToken {
|
||||
try {
|
||||
ZodGenericToken.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGenericToken' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodGenericTokenWrite = ZodGenericDataSoftDeleteWrite.extend({
|
||||
parentId: ZodLong.optional(),
|
||||
name: zod.string().optional(),
|
||||
endValidityTime: ZodTimestamp.optional(),
|
||||
token: zod.string().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type GenericTokenWrite = zod.infer<typeof ZodGenericTokenWrite>;
|
||||
|
||||
export function isGenericTokenWrite(data: any): data is GenericTokenWrite {
|
||||
try {
|
||||
ZodGenericTokenWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGenericTokenWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
38
front/src/back-api/model/get-sign-up-available.ts
Normal file
38
front/src/back-api/model/get-sign-up-available.ts
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodGetSignUpAvailable = zod.object({
|
||||
signup: zod.boolean(),
|
||||
|
||||
});
|
||||
|
||||
export type GetSignUpAvailable = zod.infer<typeof ZodGetSignUpAvailable>;
|
||||
|
||||
export function isGetSignUpAvailable(data: any): data is GetSignUpAvailable {
|
||||
try {
|
||||
ZodGetSignUpAvailable.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetSignUpAvailable' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodGetSignUpAvailableWrite = zod.object({
|
||||
signup: zod.boolean(),
|
||||
|
||||
});
|
||||
|
||||
export type GetSignUpAvailableWrite = zod.infer<typeof ZodGetSignUpAvailableWrite>;
|
||||
|
||||
export function isGetSignUpAvailableWrite(data: any): data is GetSignUpAvailableWrite {
|
||||
try {
|
||||
ZodGetSignUpAvailableWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetSignUpAvailableWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
38
front/src/back-api/model/get-token.ts
Normal file
38
front/src/back-api/model/get-token.ts
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodGetToken = zod.object({
|
||||
jwt: zod.string(),
|
||||
|
||||
});
|
||||
|
||||
export type GetToken = zod.infer<typeof ZodGetToken>;
|
||||
|
||||
export function isGetToken(data: any): data is GetToken {
|
||||
try {
|
||||
ZodGetToken.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetToken' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodGetTokenWrite = zod.object({
|
||||
jwt: zod.string().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type GetTokenWrite = zod.infer<typeof ZodGetTokenWrite>;
|
||||
|
||||
export function isGetTokenWrite(data: any): data is GetTokenWrite {
|
||||
try {
|
||||
ZodGetTokenWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodGetTokenWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
36
front/src/back-api/model/index.ts
Normal file
36
front/src/back-api/model/index.ts
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
export * from "./add-user-data"
|
||||
export * from "./application"
|
||||
export * from "./application-small"
|
||||
export * from "./application-token"
|
||||
export * from "./change-password"
|
||||
export * from "./client-token"
|
||||
export * from "./create-token-request"
|
||||
export * from "./data-get-token"
|
||||
export * from "./generic-data"
|
||||
export * from "./generic-data-soft-delete"
|
||||
export * from "./generic-timing"
|
||||
export * from "./generic-token"
|
||||
export * from "./get-sign-up-available"
|
||||
export * from "./get-token"
|
||||
export * from "./integer"
|
||||
export * from "./iso-date"
|
||||
export * from "./jwt-header"
|
||||
export * from "./jwt-payload"
|
||||
export * from "./jwt-token"
|
||||
export * from "./long"
|
||||
export * from "./object-id"
|
||||
export * from "./part-right"
|
||||
export * from "./public-key"
|
||||
export * from "./rest-error-response"
|
||||
export * from "./right"
|
||||
export * from "./right-description"
|
||||
export * from "./timestamp"
|
||||
export * from "./user"
|
||||
export * from "./user-auth"
|
||||
export * from "./user-auth-get"
|
||||
export * from "./user-create"
|
||||
export * from "./user-out"
|
||||
export * from "./uuid"
|
8
front/src/back-api/model/integer.ts
Normal file
8
front/src/back-api/model/integer.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodInteger = zod.number().safe();
|
||||
export type Integer = zod.infer<typeof ZodInteger>;
|
8
front/src/back-api/model/iso-date.ts
Normal file
8
front/src/back-api/model/iso-date.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodIsoDate = zod.string().datetime({ precision: 3 });
|
||||
export type IsoDate = zod.infer<typeof ZodIsoDate>;
|
40
front/src/back-api/model/jwt-header.ts
Normal file
40
front/src/back-api/model/jwt-header.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodJwtHeader = zod.object({
|
||||
typ: zod.string().max(128),
|
||||
alg: zod.string().max(128),
|
||||
|
||||
});
|
||||
|
||||
export type JwtHeader = zod.infer<typeof ZodJwtHeader>;
|
||||
|
||||
export function isJwtHeader(data: any): data is JwtHeader {
|
||||
try {
|
||||
ZodJwtHeader.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodJwtHeader' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodJwtHeaderWrite = zod.object({
|
||||
typ: zod.string().max(128).optional(),
|
||||
alg: zod.string().max(128).optional(),
|
||||
|
||||
});
|
||||
|
||||
export type JwtHeaderWrite = zod.infer<typeof ZodJwtHeaderWrite>;
|
||||
|
||||
export function isJwtHeaderWrite(data: any): data is JwtHeaderWrite {
|
||||
try {
|
||||
ZodJwtHeaderWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodJwtHeaderWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
51
front/src/back-api/model/jwt-payload.ts
Normal file
51
front/src/back-api/model/jwt-payload.ts
Normal file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodLong} from "./long";
|
||||
|
||||
export const ZodJwtPayload = zod.object({
|
||||
sub: zod.string(),
|
||||
application: zod.string(),
|
||||
iss: zod.string(),
|
||||
right: zod.record(zod.string(), zod.record(zod.string(), ZodLong)),
|
||||
login: zod.string(),
|
||||
exp: ZodLong,
|
||||
iat: ZodLong,
|
||||
|
||||
});
|
||||
|
||||
export type JwtPayload = zod.infer<typeof ZodJwtPayload>;
|
||||
|
||||
export function isJwtPayload(data: any): data is JwtPayload {
|
||||
try {
|
||||
ZodJwtPayload.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodJwtPayload' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodJwtPayloadWrite = zod.object({
|
||||
sub: zod.string().optional(),
|
||||
application: zod.string().optional(),
|
||||
iss: zod.string().optional(),
|
||||
right: zod.record(zod.string(), zod.record(zod.string(), ZodLong)).optional(),
|
||||
login: zod.string().optional(),
|
||||
exp: ZodLong.optional(),
|
||||
iat: ZodLong.optional(),
|
||||
|
||||
});
|
||||
|
||||
export type JwtPayloadWrite = zod.infer<typeof ZodJwtPayloadWrite>;
|
||||
|
||||
export function isJwtPayloadWrite(data: any): data is JwtPayloadWrite {
|
||||
try {
|
||||
ZodJwtPayloadWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodJwtPayloadWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
44
front/src/back-api/model/jwt-token.ts
Normal file
44
front/src/back-api/model/jwt-token.ts
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodJwtHeader, ZodJwtHeaderWrite } from "./jwt-header";
|
||||
import {ZodJwtPayload, ZodJwtPayloadWrite } from "./jwt-payload";
|
||||
|
||||
export const ZodJwtToken = zod.object({
|
||||
header: ZodJwtHeader,
|
||||
payload: ZodJwtPayload,
|
||||
signature: zod.string(),
|
||||
|
||||
});
|
||||
|
||||
export type JwtToken = zod.infer<typeof ZodJwtToken>;
|
||||
|
||||
export function isJwtToken(data: any): data is JwtToken {
|
||||
try {
|
||||
ZodJwtToken.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodJwtToken' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodJwtTokenWrite = zod.object({
|
||||
header: ZodJwtHeader.optional(),
|
||||
payload: ZodJwtPayload.optional(),
|
||||
signature: zod.string().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type JwtTokenWrite = zod.infer<typeof ZodJwtTokenWrite>;
|
||||
|
||||
export function isJwtTokenWrite(data: any): data is JwtTokenWrite {
|
||||
try {
|
||||
ZodJwtTokenWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodJwtTokenWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
8
front/src/back-api/model/long.ts
Normal file
8
front/src/back-api/model/long.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodLong = zod.number();
|
||||
export type Long = zod.infer<typeof ZodLong>;
|
8
front/src/back-api/model/object-id.ts
Normal file
8
front/src/back-api/model/object-id.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodObjectId = zod.string().length(24, "Invalid ObjectId length").regex(/^[a-fA-F0-9]{24}$/, "Invalid ObjectId format");
|
||||
export type ObjectId = zod.infer<typeof ZodObjectId>;
|
24
front/src/back-api/model/part-right.ts
Normal file
24
front/src/back-api/model/part-right.ts
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export enum PartRight {
|
||||
READ = 1,
|
||||
NONE = 0,
|
||||
WRITE = 2,
|
||||
READ_WRITE = 3,
|
||||
};
|
||||
|
||||
export const ZodPartRight = zod.nativeEnum(PartRight);
|
||||
|
||||
export function isPartRight(data: any): data is PartRight {
|
||||
try {
|
||||
ZodPartRight.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodPartRight' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
38
front/src/back-api/model/public-key.ts
Normal file
38
front/src/back-api/model/public-key.ts
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodPublicKey = zod.object({
|
||||
key: zod.string().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type PublicKey = zod.infer<typeof ZodPublicKey>;
|
||||
|
||||
export function isPublicKey(data: any): data is PublicKey {
|
||||
try {
|
||||
ZodPublicKey.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodPublicKey' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodPublicKeyWrite = zod.object({
|
||||
key: zod.string().nullable().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type PublicKeyWrite = zod.infer<typeof ZodPublicKeyWrite>;
|
||||
|
||||
export function isPublicKeyWrite(data: any): data is PublicKeyWrite {
|
||||
try {
|
||||
ZodPublicKeyWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodPublicKeyWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
29
front/src/back-api/model/rest-error-response.ts
Normal file
29
front/src/back-api/model/rest-error-response.ts
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodObjectId} from "./object-id";
|
||||
import {ZodInteger} from "./integer";
|
||||
|
||||
export const ZodRestErrorResponse = zod.object({
|
||||
oid: ZodObjectId.optional(),
|
||||
name: zod.string(),
|
||||
message: zod.string(),
|
||||
time: zod.string(),
|
||||
status: ZodInteger,
|
||||
statusMessage: zod.string(),
|
||||
|
||||
});
|
||||
|
||||
export type RestErrorResponse = zod.infer<typeof ZodRestErrorResponse>;
|
||||
|
||||
export function isRestErrorResponse(data: any): data is RestErrorResponse {
|
||||
try {
|
||||
ZodRestErrorResponse.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodRestErrorResponse' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
70
front/src/back-api/model/right-description.ts
Normal file
70
front/src/back-api/model/right-description.ts
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodLong} from "./long";
|
||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
||||
|
||||
export const ZodRightDescription = ZodGenericDataSoftDelete.extend({
|
||||
/**
|
||||
* Application id that have the reference of the right
|
||||
*/
|
||||
applicationId: ZodLong,
|
||||
/**
|
||||
* Key of the property
|
||||
*/
|
||||
key: zod.string(),
|
||||
/**
|
||||
* Title of the right
|
||||
*/
|
||||
title: zod.string(),
|
||||
/**
|
||||
* Description of the right
|
||||
*/
|
||||
description: zod.string(),
|
||||
|
||||
});
|
||||
|
||||
export type RightDescription = zod.infer<typeof ZodRightDescription>;
|
||||
|
||||
export function isRightDescription(data: any): data is RightDescription {
|
||||
try {
|
||||
ZodRightDescription.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodRightDescription' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodRightDescriptionWrite = ZodGenericDataSoftDeleteWrite.extend({
|
||||
/**
|
||||
* Application id that have the reference of the right
|
||||
*/
|
||||
applicationId: ZodLong.optional(),
|
||||
/**
|
||||
* Key of the property
|
||||
*/
|
||||
key: zod.string().optional(),
|
||||
/**
|
||||
* Title of the right
|
||||
*/
|
||||
title: zod.string().optional(),
|
||||
/**
|
||||
* Description of the right
|
||||
*/
|
||||
description: zod.string().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type RightDescriptionWrite = zod.infer<typeof ZodRightDescriptionWrite>;
|
||||
|
||||
export function isRightDescriptionWrite(data: any): data is RightDescriptionWrite {
|
||||
try {
|
||||
ZodRightDescriptionWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodRightDescriptionWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
71
front/src/back-api/model/right.ts
Normal file
71
front/src/back-api/model/right.ts
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodLong} from "./long";
|
||||
import {ZodPartRight} from "./part-right";
|
||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
||||
|
||||
export const ZodRight = ZodGenericDataSoftDelete.extend({
|
||||
/**
|
||||
* application-ID that have the reference of the right
|
||||
*/
|
||||
applicationId: ZodLong,
|
||||
/**
|
||||
* user-ID
|
||||
*/
|
||||
userId: ZodLong,
|
||||
/**
|
||||
* rightDescription-ID of the right description
|
||||
*/
|
||||
rightDescriptionId: ZodLong,
|
||||
/**
|
||||
* Value of the right
|
||||
*/
|
||||
value: ZodPartRight,
|
||||
|
||||
});
|
||||
|
||||
export type Right = zod.infer<typeof ZodRight>;
|
||||
|
||||
export function isRight(data: any): data is Right {
|
||||
try {
|
||||
ZodRight.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodRight' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodRightWrite = ZodGenericDataSoftDeleteWrite.extend({
|
||||
/**
|
||||
* application-ID that have the reference of the right
|
||||
*/
|
||||
applicationId: ZodLong.optional(),
|
||||
/**
|
||||
* user-ID
|
||||
*/
|
||||
userId: ZodLong.optional(),
|
||||
/**
|
||||
* rightDescription-ID of the right description
|
||||
*/
|
||||
rightDescriptionId: ZodLong.optional(),
|
||||
/**
|
||||
* Value of the right
|
||||
*/
|
||||
value: ZodPartRight.optional(),
|
||||
|
||||
});
|
||||
|
||||
export type RightWrite = zod.infer<typeof ZodRightWrite>;
|
||||
|
||||
export function isRightWrite(data: any): data is RightWrite {
|
||||
try {
|
||||
ZodRightWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodRightWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
8
front/src/back-api/model/timestamp.ts
Normal file
8
front/src/back-api/model/timestamp.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodTimestamp = zod.string().datetime({ precision: 3 });
|
||||
export type Timestamp = zod.infer<typeof ZodTimestamp>;
|
41
front/src/back-api/model/user-auth-get.ts
Normal file
41
front/src/back-api/model/user-auth-get.ts
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodUser, ZodUserWrite } from "./user";
|
||||
|
||||
export const ZodUserAuthGet = ZodUser.extend({
|
||||
email: zod.string(),
|
||||
avatar: zod.boolean(),
|
||||
|
||||
});
|
||||
|
||||
export type UserAuthGet = zod.infer<typeof ZodUserAuthGet>;
|
||||
|
||||
export function isUserAuthGet(data: any): data is UserAuthGet {
|
||||
try {
|
||||
ZodUserAuthGet.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodUserAuthGet' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodUserAuthGetWrite = ZodUserWrite.extend({
|
||||
email: zod.string().optional(),
|
||||
avatar: zod.boolean().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type UserAuthGetWrite = zod.infer<typeof ZodUserAuthGetWrite>;
|
||||
|
||||
export function isUserAuthGetWrite(data: any): data is UserAuthGetWrite {
|
||||
try {
|
||||
ZodUserAuthGetWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodUserAuthGetWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
57
front/src/back-api/model/user-auth.ts
Normal file
57
front/src/back-api/model/user-auth.ts
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodTimestamp} from "./timestamp";
|
||||
import {ZodLong} from "./long";
|
||||
import {ZodUser, ZodUserWrite } from "./user";
|
||||
|
||||
export const ZodUserAuth = ZodUser.extend({
|
||||
password: zod.string().min(128).max(128).optional(),
|
||||
email: zod.string().min(5).max(128),
|
||||
emailValidate: ZodTimestamp.optional(),
|
||||
newEmail: zod.string().min(5).max(128).optional(),
|
||||
avatar: zod.boolean(),
|
||||
/**
|
||||
* List of accessible application (if not set the application is not available)
|
||||
*/
|
||||
applications: zod.array(ZodLong),
|
||||
|
||||
});
|
||||
|
||||
export type UserAuth = zod.infer<typeof ZodUserAuth>;
|
||||
|
||||
export function isUserAuth(data: any): data is UserAuth {
|
||||
try {
|
||||
ZodUserAuth.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodUserAuth' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodUserAuthWrite = ZodUserWrite.extend({
|
||||
password: zod.string().min(128).max(128).nullable().optional(),
|
||||
email: zod.string().min(5).max(128).optional(),
|
||||
emailValidate: ZodTimestamp.nullable().optional(),
|
||||
newEmail: zod.string().min(5).max(128).nullable().optional(),
|
||||
avatar: zod.boolean().optional(),
|
||||
/**
|
||||
* List of accessible application (if not set the application is not available)
|
||||
*/
|
||||
applications: zod.array(ZodLong).optional(),
|
||||
|
||||
});
|
||||
|
||||
export type UserAuthWrite = zod.infer<typeof ZodUserAuthWrite>;
|
||||
|
||||
export function isUserAuthWrite(data: any): data is UserAuthWrite {
|
||||
try {
|
||||
ZodUserAuthWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodUserAuthWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
42
front/src/back-api/model/user-create.ts
Normal file
42
front/src/back-api/model/user-create.ts
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodUserCreate = zod.object({
|
||||
login: zod.string().min(3).max(128),
|
||||
email: zod.string().min(5).max(128),
|
||||
password: zod.string().min(128).max(128),
|
||||
|
||||
});
|
||||
|
||||
export type UserCreate = zod.infer<typeof ZodUserCreate>;
|
||||
|
||||
export function isUserCreate(data: any): data is UserCreate {
|
||||
try {
|
||||
ZodUserCreate.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodUserCreate' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodUserCreateWrite = zod.object({
|
||||
login: zod.string().min(3).max(128).optional(),
|
||||
email: zod.string().min(5).max(128).optional(),
|
||||
password: zod.string().min(128).max(128).optional(),
|
||||
|
||||
});
|
||||
|
||||
export type UserCreateWrite = zod.infer<typeof ZodUserCreateWrite>;
|
||||
|
||||
export function isUserCreateWrite(data: any): data is UserCreateWrite {
|
||||
try {
|
||||
ZodUserCreateWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodUserCreateWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
41
front/src/back-api/model/user-out.ts
Normal file
41
front/src/back-api/model/user-out.ts
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodLong} from "./long";
|
||||
|
||||
export const ZodUserOut = zod.object({
|
||||
id: ZodLong,
|
||||
login: zod.string().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type UserOut = zod.infer<typeof ZodUserOut>;
|
||||
|
||||
export function isUserOut(data: any): data is UserOut {
|
||||
try {
|
||||
ZodUserOut.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodUserOut' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodUserOutWrite = zod.object({
|
||||
id: ZodLong,
|
||||
login: zod.string().nullable().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type UserOutWrite = zod.infer<typeof ZodUserOutWrite>;
|
||||
|
||||
export function isUserOutWrite(data: any): data is UserOutWrite {
|
||||
try {
|
||||
ZodUserOutWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodUserOutWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
55
front/src/back-api/model/user.ts
Normal file
55
front/src/back-api/model/user.ts
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
import {ZodTimestamp} from "./timestamp";
|
||||
import {ZodUUID} from "./uuid";
|
||||
import {ZodGenericDataSoftDelete, ZodGenericDataSoftDeleteWrite } from "./generic-data-soft-delete";
|
||||
|
||||
export const ZodUser = ZodGenericDataSoftDelete.extend({
|
||||
login: zod.string().min(3).max(128),
|
||||
lastConnection: ZodTimestamp.optional(),
|
||||
blocked: zod.boolean().optional(),
|
||||
blockedReason: zod.string().max(512).optional(),
|
||||
/**
|
||||
* List of Id of the specific covers
|
||||
*/
|
||||
covers: zod.array(ZodUUID).optional(),
|
||||
|
||||
});
|
||||
|
||||
export type User = zod.infer<typeof ZodUser>;
|
||||
|
||||
export function isUser(data: any): data is User {
|
||||
try {
|
||||
ZodUser.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodUser' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const ZodUserWrite = ZodGenericDataSoftDeleteWrite.extend({
|
||||
login: zod.string().min(3).max(128).optional(),
|
||||
lastConnection: ZodTimestamp.nullable().optional(),
|
||||
blocked: zod.boolean().nullable().optional(),
|
||||
blockedReason: zod.string().max(512).nullable().optional(),
|
||||
/**
|
||||
* List of Id of the specific covers
|
||||
*/
|
||||
covers: zod.array(ZodUUID).nullable().optional(),
|
||||
|
||||
});
|
||||
|
||||
export type UserWrite = zod.infer<typeof ZodUserWrite>;
|
||||
|
||||
export function isUserWrite(data: any): data is UserWrite {
|
||||
try {
|
||||
ZodUserWrite.parse(data);
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
console.log(`Fail to parse data type='ZodUserWrite' error=${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
8
front/src/back-api/model/uuid.ts
Normal file
8
front/src/back-api/model/uuid.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from "zod";
|
||||
|
||||
|
||||
export const ZodUUID = zod.string().uuid();
|
||||
export type UUID = zod.infer<typeof ZodUUID>;
|
454
front/src/back-api/rest-tools.ts
Normal file
454
front/src/back-api/rest-tools.ts
Normal file
@ -0,0 +1,454 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2024, Edouard DUPIN, all right reserved
|
||||
* @license MPL-2
|
||||
*/
|
||||
|
||||
import { RestErrorResponse, isRestErrorResponse } from "./model";
|
||||
|
||||
export enum HTTPRequestModel {
|
||||
ARCHIVE = "ARCHIVE",
|
||||
DELETE = "DELETE",
|
||||
HEAD = "HEAD",
|
||||
GET = "GET",
|
||||
OPTION = "OPTION",
|
||||
PATCH = "PATCH",
|
||||
POST = "POST",
|
||||
PUT = "PUT",
|
||||
RESTORE = "RESTORE",
|
||||
}
|
||||
export enum HTTPMimeType {
|
||||
ALL = "*/*",
|
||||
CSV = "text/csv",
|
||||
IMAGE = "image/*",
|
||||
IMAGE_JPEG = "image/jpeg",
|
||||
IMAGE_PNG = "image/png",
|
||||
JSON = "application/json",
|
||||
MULTIPART = "multipart/form-data",
|
||||
OCTET_STREAM = "application/octet-stream",
|
||||
TEXT_PLAIN = "text/plain",
|
||||
}
|
||||
|
||||
export interface RESTConfig {
|
||||
// base of the server: http(s)://my.server.org/plop/api/
|
||||
server: string;
|
||||
// Token to access of the data.
|
||||
token?: string;
|
||||
}
|
||||
|
||||
export interface RESTModel {
|
||||
// base of the local API request: "sheep/{id}".
|
||||
endPoint: string;
|
||||
// Type of the request.
|
||||
requestType?: HTTPRequestModel;
|
||||
// Input type requested.
|
||||
accept?: HTTPMimeType;
|
||||
// Content of the local data.
|
||||
contentType?: HTTPMimeType;
|
||||
// Mode of the TOKEN in URL or Header (?token:${tokenInUrl})
|
||||
tokenInUrl?: boolean;
|
||||
}
|
||||
|
||||
export interface ModelResponseHttp {
|
||||
status: number;
|
||||
data: any;
|
||||
}
|
||||
|
||||
function isNullOrUndefined(data: any): data is undefined | null {
|
||||
return data === undefined || data === null;
|
||||
}
|
||||
|
||||
// generic progression callback
|
||||
export type ProgressCallback = (count: number, total: number) => void;
|
||||
|
||||
export interface RESTAbort {
|
||||
abort?: () => boolean;
|
||||
}
|
||||
|
||||
// Rest generic callback have a basic model to upload and download advancement.
|
||||
export interface RESTCallbacks {
|
||||
progressUpload?: ProgressCallback;
|
||||
progressDownload?: ProgressCallback;
|
||||
abortHandle?: RESTAbort;
|
||||
}
|
||||
|
||||
export interface RESTRequestType {
|
||||
restModel: RESTModel;
|
||||
restConfig: RESTConfig;
|
||||
data?: any;
|
||||
params?: object;
|
||||
queries?: object;
|
||||
callbacks?: RESTCallbacks;
|
||||
}
|
||||
|
||||
function replaceAll(input, searchValue, replaceValue) {
|
||||
return input.split(searchValue).join(replaceValue);
|
||||
}
|
||||
|
||||
function removeTrailingSlashes(input: string): string {
|
||||
if (isNullOrUndefined(input)) {
|
||||
return "undefined";
|
||||
}
|
||||
return input.replace(/\/+$/, "");
|
||||
}
|
||||
function removeLeadingSlashes(input: string): string {
|
||||
if (isNullOrUndefined(input)) {
|
||||
return "";
|
||||
}
|
||||
return input.replace(/^\/+/, "");
|
||||
}
|
||||
|
||||
export function RESTUrl({
|
||||
restModel,
|
||||
restConfig,
|
||||
params,
|
||||
queries,
|
||||
}: RESTRequestType): string {
|
||||
// Create the URL PATH:
|
||||
let generateUrl = `${removeTrailingSlashes(
|
||||
restConfig.server
|
||||
)}/${removeLeadingSlashes(restModel.endPoint)}`;
|
||||
if (params !== undefined) {
|
||||
for (let key of Object.keys(params)) {
|
||||
generateUrl = replaceAll(generateUrl, `{${key}}`, `${params[key]}`);
|
||||
}
|
||||
}
|
||||
if (
|
||||
queries === undefined &&
|
||||
(restConfig.token === undefined || restModel.tokenInUrl !== true)
|
||||
) {
|
||||
return generateUrl;
|
||||
}
|
||||
const searchParams = new URLSearchParams();
|
||||
if (queries !== undefined) {
|
||||
for (let key of Object.keys(queries)) {
|
||||
const value = queries[key];
|
||||
if (Array.isArray(value)) {
|
||||
for (const element of value) {
|
||||
searchParams.append(`${key}`, `${element}`);
|
||||
}
|
||||
} else {
|
||||
searchParams.append(`${key}`, `${value}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (restConfig.token !== undefined && restModel.tokenInUrl === true) {
|
||||
searchParams.append("Authorization", `Bearer ${restConfig.token}`);
|
||||
}
|
||||
return generateUrl + "?" + searchParams.toString();
|
||||
}
|
||||
|
||||
export function fetchProgress(
|
||||
generateUrl: string,
|
||||
{
|
||||
method,
|
||||
headers,
|
||||
body,
|
||||
}: {
|
||||
method: HTTPRequestModel;
|
||||
headers: any;
|
||||
body: any;
|
||||
},
|
||||
{ progressUpload, progressDownload, abortHandle }: RESTCallbacks
|
||||
): Promise<Response> {
|
||||
const xhr: {
|
||||
io?: XMLHttpRequest;
|
||||
} = {
|
||||
io: new XMLHttpRequest(),
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
// Stream the upload progress
|
||||
if (progressUpload) {
|
||||
xhr.io?.upload.addEventListener("progress", (dataEvent) => {
|
||||
if (dataEvent.lengthComputable) {
|
||||
progressUpload(dataEvent.loaded, dataEvent.total);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Stream the download progress
|
||||
if (progressDownload) {
|
||||
xhr.io?.addEventListener("progress", (dataEvent) => {
|
||||
if (dataEvent.lengthComputable) {
|
||||
progressDownload(dataEvent.loaded, dataEvent.total);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (abortHandle) {
|
||||
abortHandle.abort = () => {
|
||||
if (xhr.io) {
|
||||
console.log(`Request abort on the XMLHttpRequest: ${generateUrl}`);
|
||||
xhr.io.abort();
|
||||
return true;
|
||||
}
|
||||
console.log(
|
||||
`Request abort (FAIL) on the XMLHttpRequest: ${generateUrl}`
|
||||
);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
// Check if we have an internal Fail:
|
||||
xhr.io?.addEventListener("error", () => {
|
||||
xhr.io = undefined;
|
||||
reject(new TypeError("Failed to fetch"));
|
||||
});
|
||||
|
||||
// Capture the end of the stream
|
||||
xhr.io?.addEventListener("loadend", () => {
|
||||
if (xhr.io?.readyState !== XMLHttpRequest.DONE) {
|
||||
return;
|
||||
}
|
||||
if (xhr.io?.status === 0) {
|
||||
//the stream has been aborted
|
||||
reject(new TypeError("Fetch has been aborted"));
|
||||
return;
|
||||
}
|
||||
// Stream is ended, transform in a generic response:
|
||||
const response = new Response(xhr.io.response, {
|
||||
status: xhr.io.status,
|
||||
statusText: xhr.io.statusText,
|
||||
});
|
||||
const headersArray = replaceAll(
|
||||
xhr.io.getAllResponseHeaders().trim(),
|
||||
"\r\n",
|
||||
"\n"
|
||||
).split("\n");
|
||||
headersArray.forEach(function (header) {
|
||||
const firstColonIndex = header.indexOf(":");
|
||||
if (firstColonIndex !== -1) {
|
||||
const key = header.substring(0, firstColonIndex).trim();
|
||||
const value = header.substring(firstColonIndex + 1).trim();
|
||||
response.headers.set(key, value);
|
||||
} else {
|
||||
response.headers.set(header, "");
|
||||
}
|
||||
});
|
||||
xhr.io = undefined;
|
||||
resolve(response);
|
||||
});
|
||||
xhr.io?.open(method, generateUrl, true);
|
||||
if (!isNullOrUndefined(headers)) {
|
||||
for (const [key, value] of Object.entries(headers)) {
|
||||
xhr.io?.setRequestHeader(key, value as string);
|
||||
}
|
||||
}
|
||||
xhr.io?.send(body);
|
||||
});
|
||||
}
|
||||
|
||||
export function RESTRequest({
|
||||
restModel,
|
||||
restConfig,
|
||||
data,
|
||||
params,
|
||||
queries,
|
||||
callbacks,
|
||||
}: RESTRequestType): Promise<ModelResponseHttp> {
|
||||
// Create the URL PATH:
|
||||
let generateUrl = RESTUrl({ restModel, restConfig, data, params, queries });
|
||||
let headers: any = {};
|
||||
if (restConfig.token !== undefined && restModel.tokenInUrl !== true) {
|
||||
headers["Authorization"] = `Bearer ${restConfig.token}`;
|
||||
}
|
||||
if (restModel.accept !== undefined) {
|
||||
headers["Accept"] = restModel.accept;
|
||||
}
|
||||
if (restModel.requestType !== HTTPRequestModel.GET &&
|
||||
restModel.requestType !== HTTPRequestModel.ARCHIVE &&
|
||||
restModel.requestType !== HTTPRequestModel.RESTORE
|
||||
) {
|
||||
// if Get we have not a content type, the body is empty
|
||||
if (restModel.contentType !== HTTPMimeType.MULTIPART &&
|
||||
restModel.contentType !== undefined
|
||||
) {
|
||||
// special case of multi-part ==> no content type otherwise the browser does not set the ";bundary=--****"
|
||||
headers["Content-Type"] = restModel.contentType;
|
||||
}
|
||||
}
|
||||
let body = data;
|
||||
if (restModel.contentType === HTTPMimeType.JSON) {
|
||||
body = JSON.stringify(data);
|
||||
} else if (restModel.contentType === HTTPMimeType.MULTIPART) {
|
||||
const formData = new FormData();
|
||||
for (const name in data) {
|
||||
formData.append(name, data[name]);
|
||||
}
|
||||
body = formData;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let action: undefined | Promise<Response> = undefined;
|
||||
if (
|
||||
isNullOrUndefined(callbacks) ||
|
||||
(isNullOrUndefined(callbacks.progressDownload) &&
|
||||
isNullOrUndefined(callbacks.progressUpload) &&
|
||||
isNullOrUndefined(callbacks.abortHandle))
|
||||
) {
|
||||
// No information needed: call the generic fetch interface
|
||||
action = fetch(generateUrl, {
|
||||
method: restModel.requestType,
|
||||
headers,
|
||||
body,
|
||||
});
|
||||
} else {
|
||||
// need progression information: call old fetch model (XMLHttpRequest) that permit to keep % upload and % download for HTTP1.x
|
||||
action = fetchProgress(
|
||||
generateUrl,
|
||||
{
|
||||
method: restModel.requestType ?? HTTPRequestModel.GET,
|
||||
headers,
|
||||
body,
|
||||
},
|
||||
callbacks
|
||||
);
|
||||
}
|
||||
action
|
||||
.then((response: Response) => {
|
||||
if (response.status >= 200 && response.status <= 299) {
|
||||
const contentType = response.headers.get("Content-Type");
|
||||
if (
|
||||
!isNullOrUndefined(restModel.accept) &&
|
||||
restModel.accept !== contentType
|
||||
) {
|
||||
reject({
|
||||
name: "Model accept type incompatible",
|
||||
time: Date().toString(),
|
||||
status: 901,
|
||||
message: `REST Content type are not compatible: ${restModel.accept} != ${contentType}`,
|
||||
statusMessage: "Fetch error",
|
||||
error: "rest-tools.ts Wrong type in the message return type",
|
||||
} as RestErrorResponse);
|
||||
} else if (contentType === HTTPMimeType.JSON) {
|
||||
response
|
||||
.json()
|
||||
.then((value: any) => {
|
||||
resolve({ status: response.status, data: value });
|
||||
})
|
||||
.catch((reason: Error) => {
|
||||
reject({
|
||||
name: "API serialization error",
|
||||
time: Date().toString(),
|
||||
status: 902,
|
||||
message: `REST parse json fail: ${reason}`,
|
||||
statusMessage: "Fetch parse error",
|
||||
error: "rest-tools.ts Wrong message model to parse",
|
||||
} as RestErrorResponse);
|
||||
});
|
||||
} else {
|
||||
resolve({ status: response.status, data: response.body });
|
||||
}
|
||||
} else {
|
||||
// the answer is not correct not a 2XX
|
||||
// clone the response to keep the raw data if case of error:
|
||||
response
|
||||
.clone()
|
||||
.json()
|
||||
.then((value: any) => {
|
||||
if (isRestErrorResponse(value)) {
|
||||
reject(value);
|
||||
} else {
|
||||
response
|
||||
.text()
|
||||
.then((dataError: string) => {
|
||||
reject({
|
||||
name: "API serialization error",
|
||||
time: Date().toString(),
|
||||
status: 903,
|
||||
message: `REST parse error json with wrong type fail. ${dataError}`,
|
||||
statusMessage: "Fetch parse error",
|
||||
error: "rest-tools.ts Wrong message model to parse",
|
||||
} as RestErrorResponse);
|
||||
})
|
||||
.catch((reason: any) => {
|
||||
reject({
|
||||
name: "API serialization error",
|
||||
time: Date().toString(),
|
||||
status: response.status,
|
||||
message: `unmanaged error model: ??? with error: ${reason}`,
|
||||
statusMessage: "Fetch ERROR parse error",
|
||||
error: "rest-tools.ts Wrong message model to parse",
|
||||
} as RestErrorResponse);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((reason: Error) => {
|
||||
response
|
||||
.text()
|
||||
.then((dataError: string) => {
|
||||
reject({
|
||||
name: "API serialization error",
|
||||
time: Date().toString(),
|
||||
status: response.status,
|
||||
message: `unmanaged error model: ${dataError} with error: ${reason}`,
|
||||
statusMessage: "Fetch ERROR TEXT parse error",
|
||||
error: "rest-tools.ts Wrong message model to parse",
|
||||
} as RestErrorResponse);
|
||||
})
|
||||
.catch((reason: any) => {
|
||||
reject({
|
||||
name: "API serialization error",
|
||||
time: Date().toString(),
|
||||
status: response.status,
|
||||
message: `unmanaged error model: ??? with error: ${reason}`,
|
||||
statusMessage: "Fetch ERROR TEXT FAIL",
|
||||
error: "rest-tools.ts Wrong message model to parse",
|
||||
} as RestErrorResponse);
|
||||
});
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
if (isRestErrorResponse(error)) {
|
||||
reject(error);
|
||||
} else {
|
||||
reject({
|
||||
name: "Request fail",
|
||||
time: Date(),
|
||||
status: 999,
|
||||
message: error,
|
||||
statusMessage: "Fetch catch error",
|
||||
error: "rest-tools.ts detect an error in the fetch request",
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function RESTRequestJson<TYPE>(
|
||||
request: RESTRequestType,
|
||||
checker?: (data: any) => data is TYPE
|
||||
): Promise<TYPE> {
|
||||
return new Promise((resolve, reject) => {
|
||||
RESTRequest(request)
|
||||
.then((value: ModelResponseHttp) => {
|
||||
if (isNullOrUndefined(checker)) {
|
||||
console.log(`Have no check of MODEL in API: ${RESTUrl(request)}`);
|
||||
resolve(value.data);
|
||||
} else if (checker === undefined || checker(value.data)) {
|
||||
resolve(value.data);
|
||||
} else {
|
||||
reject({
|
||||
name: "Model check fail",
|
||||
time: Date().toString(),
|
||||
status: 950,
|
||||
error: "REST Fail to verify the data",
|
||||
statusMessage: "API cast ERROR",
|
||||
message: "api.ts Check type as fail",
|
||||
} as RestErrorResponse);
|
||||
}
|
||||
})
|
||||
.catch((reason: RestErrorResponse) => {
|
||||
reject(reason);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function RESTRequestVoid(request: RESTRequestType): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
RESTRequest(request)
|
||||
.then((value: ModelResponseHttp) => {
|
||||
resolve();
|
||||
})
|
||||
.catch((reason: RestErrorResponse) => {
|
||||
reject(reason);
|
||||
});
|
||||
});
|
||||
}
|
99
front/src/components/Cover.tsx
Normal file
99
front/src/components/Cover.tsx
Normal file
@ -0,0 +1,99 @@
|
||||
import { ReactElement, useEffect, useState } from 'react';
|
||||
|
||||
import { Box, BoxProps, Flex, FlexProps } from '@chakra-ui/react';
|
||||
import { Image } from '@chakra-ui/react';
|
||||
|
||||
import { DataUrlAccess } from '@/utils/data-url-access';
|
||||
import { Icon } from './Icon';
|
||||
import { ObjectId } from '@/back-api';
|
||||
|
||||
export type CoversProps = Omit<BoxProps, "iconEmpty"> & {
|
||||
data?: ObjectId[];
|
||||
size?: BoxProps["width"];
|
||||
iconEmpty?: ReactElement;
|
||||
slideshow?: boolean;
|
||||
};
|
||||
|
||||
export const Covers = ({
|
||||
data,
|
||||
iconEmpty,
|
||||
size = '100px',
|
||||
slideshow = false,
|
||||
...rest
|
||||
}: CoversProps) => {
|
||||
const [currentImageIndex, setCurrentImageIndex] = useState(0);
|
||||
const [previousImageIndex, setPreviousImageIndex] = useState(0);
|
||||
const [topOpacity, setTopOpacity] = useState(0.0);
|
||||
|
||||
useEffect(() => {
|
||||
if (!slideshow) {
|
||||
return;
|
||||
}
|
||||
const interval = setInterval(() => {
|
||||
setPreviousImageIndex(currentImageIndex);
|
||||
setTopOpacity(0.0);
|
||||
setTimeout(() => {
|
||||
setCurrentImageIndex((prevIndex) => (prevIndex + 1) % (data?.length ?? 1));
|
||||
setTopOpacity(1.0);
|
||||
}, 1500);
|
||||
}, 3000);
|
||||
return () => clearInterval(interval);
|
||||
}, [slideshow, data]);
|
||||
|
||||
if (!data || data.length < 1) {
|
||||
if (iconEmpty) {
|
||||
return <Icon children={iconEmpty} sizeIcon={size} />;
|
||||
} else {
|
||||
return (
|
||||
<Box
|
||||
width={size}
|
||||
height={size}
|
||||
minHeight={size}
|
||||
minWidth={size}
|
||||
borderColor="blue"
|
||||
borderWidth="1px"
|
||||
margin="auto"
|
||||
{...rest}
|
||||
></Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
if (slideshow === false || data.length === 1) {
|
||||
const url = DataUrlAccess.getThumbnailUrl(data[0]);
|
||||
return <Image loading="lazy" src={url} maxWidth={size} boxSize={size} /*{...rest}*/ />;
|
||||
}
|
||||
const urlCurrent = DataUrlAccess.getThumbnailUrl(data[currentImageIndex]);
|
||||
const urlPrevious = DataUrlAccess.getThumbnailUrl(data[previousImageIndex]);
|
||||
return <Flex
|
||||
position="relative"
|
||||
// {...rest}
|
||||
maxWidth={size}
|
||||
width={size}
|
||||
height={size}
|
||||
overflow="hidden">
|
||||
<Image
|
||||
src={urlPrevious}
|
||||
loading="lazy"
|
||||
position="absolute"
|
||||
top="0"
|
||||
left="0"
|
||||
width="100%"
|
||||
height="100%"
|
||||
zIndex={1}
|
||||
boxSize={size}
|
||||
/>
|
||||
<Image
|
||||
src={urlCurrent}
|
||||
loading="lazy"
|
||||
position="absolute"
|
||||
top="0"
|
||||
left="0"
|
||||
width="100%"
|
||||
height="100%"
|
||||
boxSize={size}
|
||||
transition="opacity 0.5s ease-in-out"
|
||||
opacity={topOpacity}
|
||||
zIndex={2}
|
||||
/>
|
||||
</Flex>
|
||||
};
|
13
front/src/components/EmptyEnd.tsx
Normal file
13
front/src/components/EmptyEnd.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import { Box } from '@chakra-ui/react';
|
||||
|
||||
export const EmptyEnd = () => {
|
||||
return (
|
||||
<Box
|
||||
width="full"
|
||||
height="25%"
|
||||
minHeight="250px"
|
||||
// borderWidth="1px"
|
||||
// borderColor="red"
|
||||
></Box>
|
||||
);
|
||||
};
|
113
front/src/components/EnvDevelopment/EnvDevelopment.tsx
Normal file
113
front/src/components/EnvDevelopment/EnvDevelopment.tsx
Normal file
@ -0,0 +1,113 @@
|
||||
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
createListCollection,
|
||||
Dialog,
|
||||
Select,
|
||||
Span,
|
||||
Stack,
|
||||
Text,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
import { useSessionService } from '@/service/session';
|
||||
import { useLogin } from '@/scene/connection/useLogin';
|
||||
|
||||
export const USERS_COLLECTION = createListCollection({
|
||||
items: [
|
||||
{ label: "karadmin", value: "adminA@666" },
|
||||
{ label: "karuser", value: "userA@666" },
|
||||
{ label: "NO_USER", value: "" },
|
||||
],
|
||||
})
|
||||
|
||||
export const EnvDevelopment = () => {
|
||||
const dialog = useDisclosure();
|
||||
|
||||
const {clearToken} = useSessionService();
|
||||
const {connect, lastError} = useLogin();
|
||||
|
||||
const buildEnv =
|
||||
process.env.NODE_ENV === 'development'
|
||||
? 'Development'
|
||||
: import.meta.env.VITE_DEV_ENV_NAME;
|
||||
const envName: Array<string> = [];
|
||||
!!buildEnv && envName.push(buildEnv);
|
||||
|
||||
if (!envName.length) {
|
||||
return null;
|
||||
}
|
||||
const handleChange = (key: string, value: string) => {
|
||||
console.log(`SELECT: [${key}:${value}]`);
|
||||
if (key === 'NO_USER') {
|
||||
clearToken();
|
||||
} else {
|
||||
connect(key, value);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
as="button"
|
||||
zIndex="100000"
|
||||
position="fixed"
|
||||
top="0"
|
||||
insetStart="0"
|
||||
insetEnd="0"
|
||||
h="2px"
|
||||
bg="warning.400"
|
||||
cursor="pointer"
|
||||
data-test-id="devtools"
|
||||
onClick={dialog.onOpen}
|
||||
>
|
||||
<Text
|
||||
position="fixed"
|
||||
top="0"
|
||||
insetStart="4"
|
||||
bg="warning.400"
|
||||
color="warning.900"
|
||||
fontSize="0.6rem"
|
||||
fontWeight="bold"
|
||||
px="10px"
|
||||
marginLeft="25%"
|
||||
borderBottomStartRadius="sm"
|
||||
borderBottomEndRadius="sm"
|
||||
textTransform="uppercase"
|
||||
>
|
||||
{envName.join(' : ')}
|
||||
</Text>
|
||||
</Box >
|
||||
|
||||
<Dialog.Root open={dialog.open} onOpenChange={dialog.onClose}>
|
||||
<Dialog.Positioner>
|
||||
<Dialog.Backdrop/>
|
||||
<Dialog.Content>
|
||||
<Dialog.Header>Development tools</Dialog.Header>
|
||||
<Dialog.Body>
|
||||
<Stack>
|
||||
<Text>User <Span color="red" fontWeight="bold">{lastError}</Span></Text>
|
||||
<Select.Root collection={USERS_COLLECTION}>
|
||||
<Select.Trigger>
|
||||
<Select.ValueText placeholder="Select test user" />
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
{USERS_COLLECTION.items.map((value) => (
|
||||
<Select.Item item={value} key={value.value}onClick={()=>handleChange(value.label, value.value)} >
|
||||
{value.label}
|
||||
</Select.Item>
|
||||
))}
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</Stack>
|
||||
</Dialog.Body>
|
||||
<Dialog.Footer>
|
||||
<Button onClick={dialog.onClose}>Close</Button>
|
||||
</Dialog.Footer>
|
||||
</Dialog.Content>
|
||||
</Dialog.Positioner>
|
||||
</Dialog.Root>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
41
front/src/components/Icon.tsx
Normal file
41
front/src/components/Icon.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
FlexProps,
|
||||
} from '@chakra-ui/react';
|
||||
import { forwardRef, ReactNode } from 'react';
|
||||
|
||||
export type IconProps = FlexProps & {
|
||||
children: ReactNode;
|
||||
color?: string;
|
||||
sizeIcon?: FlexProps['width'];
|
||||
};
|
||||
|
||||
export const Icon = forwardRef<HTMLDivElement, IconProps>(
|
||||
({ children, color, sizeIcon = '1em', ...rest }, ref) => {
|
||||
return (
|
||||
<Flex flex="none"
|
||||
minWidth={sizeIcon}
|
||||
minHeight={sizeIcon}
|
||||
maxWidth={sizeIcon}
|
||||
maxHeight={sizeIcon}
|
||||
align="center"
|
||||
padding="1px"
|
||||
ref={ref}
|
||||
{...rest}>
|
||||
<Box
|
||||
marginX="auto"
|
||||
width="100%"
|
||||
minWidth="100%"
|
||||
height="100%"
|
||||
color={color}
|
||||
asChild
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Icon.displayName = 'Icon';
|
52
front/src/components/Layout/PageLayout.tsx
Normal file
52
front/src/components/Layout/PageLayout.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import React, { ReactNode, useEffect } from 'react';
|
||||
|
||||
import { Flex, Image } from '@chakra-ui/react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import ikon from '@/assets/images/ikon.svg';
|
||||
import { TOP_BAR_HEIGHT } from '@/components/TopBar/TopBar';
|
||||
|
||||
export type LayoutProps = React.PropsWithChildren<unknown> & {
|
||||
topBar?: ReactNode;
|
||||
};
|
||||
|
||||
export const PageLayout = ({ children }: LayoutProps) => {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
window.scrollTo(0, 0);
|
||||
}, [pathname]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
minH={`calc(100vh - ${TOP_BAR_HEIGHT})`}
|
||||
maxH={`calc(100vh - ${TOP_BAR_HEIGHT})`}
|
||||
position="absolute"
|
||||
top={TOP_BAR_HEIGHT}
|
||||
bottom={0}
|
||||
left={0}
|
||||
right={0}
|
||||
minWidth="300px"
|
||||
zIndex={0}
|
||||
>
|
||||
<Image src={ikon} boxSize="90vh" margin="auto" />
|
||||
</Flex>
|
||||
<Flex
|
||||
direction="column"
|
||||
overflowX="auto"
|
||||
overflowY="auto"
|
||||
minH={`calc(100vh - ${TOP_BAR_HEIGHT})`}
|
||||
maxH={`calc(100vh - ${TOP_BAR_HEIGHT})`}
|
||||
position="absolute"
|
||||
top={TOP_BAR_HEIGHT}
|
||||
bottom={0}
|
||||
left={0}
|
||||
right={0}
|
||||
minWidth="300px"
|
||||
>
|
||||
{children}
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
};
|
43
front/src/components/Layout/PageLayoutInfoCenter.tsx
Normal file
43
front/src/components/Layout/PageLayoutInfoCenter.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import React, { ReactNode, useEffect } from 'react';
|
||||
|
||||
import { Flex, FlexProps } from '@chakra-ui/react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { PageLayout } from '@/components/Layout/PageLayout';
|
||||
import { colors } from '@/theme/colors';
|
||||
import { useColorModeValue } from '@/components/ui/color-mode';
|
||||
|
||||
export type LayoutProps = FlexProps & {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export const PageLayoutInfoCenter = ({
|
||||
children,
|
||||
width = '25%',
|
||||
...rest
|
||||
}: LayoutProps) => {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
window.scrollTo(0, 0);
|
||||
}, [pathname]);
|
||||
|
||||
return (
|
||||
<PageLayout>
|
||||
<Flex
|
||||
direction="column"
|
||||
margin="auto"
|
||||
minWidth={width}
|
||||
border="back.900"
|
||||
borderWidth="1px"
|
||||
borderRadius="8px"
|
||||
padding="10px"
|
||||
boxShadow={'0px 0px 16px ' + colors.back[900]}
|
||||
backgroundColor={useColorModeValue('#FFFFFF', '#000000')}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</Flex>
|
||||
</PageLayout>
|
||||
);
|
||||
};
|
22
front/src/components/ParameterLayout/ParameterLayout.ts
Normal file
22
front/src/components/ParameterLayout/ParameterLayout.ts
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
export {
|
||||
ParameterLayoutContent as Content,
|
||||
type ParameterLayoutContentProps as ContentProps
|
||||
} from './ParameterLayoutContent';
|
||||
export {
|
||||
ParameterLayoutFooter as Footer,
|
||||
type ParameterLayoutFooterProps as FooterProps
|
||||
} from './ParameterLayoutFooter';
|
||||
export {
|
||||
ParameterLayoutHeader as Header,
|
||||
type ParameterLayoutHeaderProps as HeaderProps
|
||||
} from './ParameterLayoutHeader';
|
||||
export {
|
||||
ParameterLayoutHeaderBase as HeaderBase,
|
||||
type ParameterLayoutHeaderBaseProps as HeaderBaseProps
|
||||
} from './ParameterLayoutHeaderBase';
|
||||
export {
|
||||
ParameterLayoutRoot as Root,
|
||||
type ParameterLayoutRootProps as RootProps
|
||||
} from './ParameterLayoutRoot';
|
||||
|
@ -0,0 +1,19 @@
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
export type ParameterLayoutContentProps = {
|
||||
children?:ReactNode;
|
||||
}
|
||||
|
||||
export const ParameterLayoutContent = ({children}:ParameterLayoutContentProps) => {
|
||||
return <Flex
|
||||
direction="column"
|
||||
width="full"
|
||||
borderY="1px solid black"
|
||||
paddingY="15px"
|
||||
paddingX="25px"
|
||||
minHeight="10px"
|
||||
background="gray.700">
|
||||
{children}
|
||||
</Flex>
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
export type ParameterLayoutFooterProps = {
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export const ParameterLayoutFooter = ({children}:ParameterLayoutFooterProps) => {
|
||||
return <Flex
|
||||
width="full"
|
||||
paddingY="15px"
|
||||
paddingX="25px"
|
||||
minHeight="10px">
|
||||
{children}
|
||||
</Flex>
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
export type ParameterLayoutHeaderProps = {
|
||||
children?:ReactNode;
|
||||
}
|
||||
|
||||
export const ParameterLayoutHeader = ({children}:ParameterLayoutHeaderProps) => {
|
||||
return <Flex
|
||||
width="full"
|
||||
paddingY="15px"
|
||||
paddingX="25px"
|
||||
minHeight="10px"
|
||||
>
|
||||
{children}
|
||||
</Flex>
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
import { Flex, Text } from "@chakra-ui/react";
|
||||
import { ParameterLayoutHeader } from "./ParameterLayoutHeader";
|
||||
|
||||
export type ParameterLayoutHeaderBaseProps = {
|
||||
title:string;
|
||||
description?: string,
|
||||
}
|
||||
|
||||
export const ParameterLayoutHeaderBase = ({
|
||||
title,
|
||||
description,
|
||||
}:ParameterLayoutHeaderBaseProps) => {
|
||||
return <ParameterLayoutHeader>
|
||||
<Flex direction="column">
|
||||
<Text
|
||||
fontSize="25px"
|
||||
fontWeight="bold">
|
||||
{title}
|
||||
</Text>
|
||||
{description && <Text>{description}</Text>}
|
||||
</Flex>
|
||||
</ParameterLayoutHeader>
|
||||
}
|
16
front/src/components/ParameterLayout/ParameterLayoutRoot.tsx
Normal file
16
front/src/components/ParameterLayout/ParameterLayoutRoot.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
import { VStack } from '@chakra-ui/react';
|
||||
|
||||
export type ParameterLayoutRootProps = {
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export const ParameterLayoutRoot = ({children}:ParameterLayoutRootProps) => {
|
||||
return <VStack gap="0px" marginX="15%" marginY="20px" justify="center"
|
||||
//borderRadius="20px"
|
||||
borderRadius="0px"
|
||||
border="1px solid black"
|
||||
background="gray.500">
|
||||
{children}
|
||||
</VStack>
|
||||
}
|
1
front/src/components/ParameterLayout/index.ts
Normal file
1
front/src/components/ParameterLayout/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * as ParameterLayout from './ParameterLayout';
|
56
front/src/components/SearchInput.tsx
Normal file
56
front/src/components/SearchInput.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import {
|
||||
Group,
|
||||
Input,
|
||||
} from '@chakra-ui/react';
|
||||
import { MdSearch } from 'react-icons/md';
|
||||
|
||||
export type SearchInputProps = {
|
||||
onChange?: (data?: string) => void;
|
||||
onSubmit?: (data?: string) => void;
|
||||
};
|
||||
|
||||
export const SearchInput = ({
|
||||
onChange: onChangeValue,
|
||||
onSubmit: onSubmitValue,
|
||||
}: SearchInputProps) => {
|
||||
const [inputData, setInputData] = useState<string | undefined>(undefined);
|
||||
const [searchInputProperty, setSearchInputProperty] =
|
||||
useState<any>(undefined);
|
||||
function onFocusKeep(): void {
|
||||
setSearchInputProperty({
|
||||
width: '70%',
|
||||
maxWidth: '70%',
|
||||
});
|
||||
}
|
||||
function onFocusLost(): void {
|
||||
setSearchInputProperty({
|
||||
width: '250px',
|
||||
});
|
||||
}
|
||||
function onChange(event): void {
|
||||
const data =
|
||||
event.target.value.length === 0 ? undefined : event.target.value;
|
||||
setInputData(data);
|
||||
if (onChangeValue) {
|
||||
onChangeValue(data);
|
||||
}
|
||||
}
|
||||
function onSubmit(): void {
|
||||
if (onSubmitValue) {
|
||||
onSubmitValue(inputData);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Group maxWidth="200px" marginLeft="auto" {...searchInputProperty}>
|
||||
<MdSearch color="gray.300" />
|
||||
<Input
|
||||
onFocus={onFocusKeep}
|
||||
onBlur={() => setTimeout(() => onFocusLost(), 200)}
|
||||
onChange={onChange}
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
</Group>
|
||||
);
|
||||
};
|
228
front/src/components/TopBar/TopBar.tsx
Normal file
228
front/src/components/TopBar/TopBar.tsx
Normal file
@ -0,0 +1,228 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
HStack,
|
||||
IconButton,
|
||||
Text,
|
||||
useDisclosure,
|
||||
Button,
|
||||
ConditionalValue,
|
||||
Span,
|
||||
chakra,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
LuAlignJustify,
|
||||
LuArrowBigLeft,
|
||||
LuCircleUserRound,
|
||||
LuLogIn,
|
||||
LuLogOut,
|
||||
LuMoon,
|
||||
LuSettings,
|
||||
LuSun,
|
||||
} from 'react-icons/lu';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { useServiceContext } from '@/service/ServiceContext';
|
||||
import { colors } from '@/theme/colors';
|
||||
import { useSessionService } from '@/service/session';
|
||||
import { MdHelp, MdHome, MdKey, MdMore, MdOutlineDashboardCustomize, MdOutlineGroup, MdSettings, MdSupervisedUserCircle } from 'react-icons/md';
|
||||
import { MenuContent, MenuItem, MenuRoot, MenuTrigger } from '@/components/ui/menu';
|
||||
import { useColorMode, useColorModeValue } from '@/components/ui/color-mode';
|
||||
import {
|
||||
DrawerBody,
|
||||
DrawerContent,
|
||||
DrawerHeader,
|
||||
DrawerRoot,
|
||||
} from '@/components/ui/drawer';
|
||||
|
||||
export const TOP_BAR_HEIGHT = '50px';
|
||||
|
||||
export const BUTTON_TOP_BAR_PROPERTY = {
|
||||
variant: "ghost" as ConditionalValue<"ghost" | "outline" | "solid" | "subtle" | "surface" | "plain" | undefined>,
|
||||
//colorPalette: "brand",
|
||||
fontSize: '20px',
|
||||
textTransform: 'uppercase',
|
||||
height: TOP_BAR_HEIGHT,
|
||||
};
|
||||
|
||||
export type TopBarProps = {
|
||||
children?: ReactNode;
|
||||
title?: string;
|
||||
};
|
||||
|
||||
const ButtonMenuLeft = ({ dest, title, icon,
|
||||
onClickEnd = () => { }, }: {
|
||||
dest: string, title: string, icon: ReactNode
|
||||
onClickEnd?: () => void;
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
return <>
|
||||
<Button
|
||||
background="#00000000"
|
||||
borderRadius="0px"
|
||||
onClick={() => {
|
||||
navigate(dest);
|
||||
onClickEnd();
|
||||
}}
|
||||
width="full"
|
||||
{...BUTTON_TOP_BAR_PROPERTY}
|
||||
>
|
||||
<Box asChild style={{ width: "45px", height: "45px" }}>{icon}</Box>
|
||||
<Text paddingLeft="3px" fontWeight="bold" marginRight="auto">
|
||||
{title}
|
||||
</Text>
|
||||
</Button>
|
||||
<Box marginY="5" marginX="10" height="2px" background="brand.600" />
|
||||
</>
|
||||
}
|
||||
export const TopBar = ({ title, children }: TopBarProps) => {
|
||||
const { colorMode, toggleColorMode } = useColorMode();
|
||||
|
||||
const { session } = useServiceContext();
|
||||
const backColor = useColorModeValue('back.100', 'back.800');
|
||||
const drawerDisclose = useDisclosure();
|
||||
const onChangeTheme = () => {
|
||||
drawerDisclose.onOpen();
|
||||
};
|
||||
const navigate = useNavigate();
|
||||
// const onSignIn = (): void => {
|
||||
// clearToken();
|
||||
// requestSignIn();
|
||||
// };
|
||||
// const onSignUp = (): void => {
|
||||
// clearToken();
|
||||
// requestSignUp();
|
||||
// };
|
||||
// const onSignOut = (): void => {
|
||||
// clearToken();
|
||||
// requestSignOut();
|
||||
// };
|
||||
return (
|
||||
<Flex
|
||||
position="absolute"
|
||||
top={0}
|
||||
left={0}
|
||||
right={0}
|
||||
height={TOP_BAR_HEIGHT}
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
backgroundColor={backColor}
|
||||
gap="2"
|
||||
px="2"
|
||||
boxShadow={'0px 2px 4px ' + colors.back[900]}
|
||||
zIndex={200}
|
||||
>
|
||||
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={onChangeTheme}>
|
||||
<HStack>
|
||||
<LuAlignJustify />
|
||||
<Text paddingLeft="3px" fontWeight="bold">
|
||||
karso
|
||||
</Text>
|
||||
</HStack>
|
||||
</Button>
|
||||
{title && (
|
||||
<Text
|
||||
fontSize="20px"
|
||||
fontWeight="bold"
|
||||
textTransform="uppercase"
|
||||
marginRight="auto"
|
||||
userSelect="none"
|
||||
color="brand.500"
|
||||
>
|
||||
{title}
|
||||
</Text>
|
||||
)}
|
||||
{children}
|
||||
<Flex right="0">
|
||||
{!session?.token && (
|
||||
<>
|
||||
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={() => navigate('/login')}>
|
||||
<LuLogIn />
|
||||
<Text paddingLeft="3px" fontWeight="bold">
|
||||
Sign-in
|
||||
</Text>
|
||||
</Button>
|
||||
<Button
|
||||
{...BUTTON_TOP_BAR_PROPERTY}
|
||||
onClick={() => navigate('/singup')}
|
||||
disabled={true}
|
||||
>
|
||||
<MdMore />
|
||||
<Text paddingLeft="3px" fontWeight="bold">
|
||||
Sign-up
|
||||
</Text>
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{session?.token && (
|
||||
<MenuRoot>
|
||||
<MenuTrigger asChild>
|
||||
<IconButton
|
||||
//asChild
|
||||
{...BUTTON_TOP_BAR_PROPERTY}
|
||||
width={TOP_BAR_HEIGHT}
|
||||
><LuCircleUserRound/></IconButton>
|
||||
</MenuTrigger>
|
||||
<MenuContent>
|
||||
<MenuItem value="user" valueText="user" color={useColorModeValue('brand.800', 'brand.200')}>
|
||||
<MdSupervisedUserCircle />
|
||||
<Box flex="1">Sign in as {session?.login ?? 'Fail'}</Box>
|
||||
</MenuItem>
|
||||
<MenuItem value="Settings" valueText="Settings" onClick={() => navigate('/settings')}><LuSettings />Settings</MenuItem>
|
||||
<MenuItem value="Help" valueText="Help" onClick={() => navigate('/help')}><MdHelp /> Help</MenuItem>
|
||||
<MenuItem value="Sign-out" valueText="Sign-out" onClick={() => navigate('/signout')}>
|
||||
<LuLogOut /> Sign-out
|
||||
</MenuItem>
|
||||
{colorMode === 'light' ? (
|
||||
<MenuItem value="set-dark" valueText="set-dark" onClick={toggleColorMode}>
|
||||
<LuMoon /> Set dark mode
|
||||
</MenuItem>
|
||||
) : (
|
||||
<MenuItem value="set-light" valueText="set-light" onClick={toggleColorMode}>
|
||||
<LuSun /> Set light mode
|
||||
</MenuItem>
|
||||
)}
|
||||
</MenuContent>
|
||||
</MenuRoot>
|
||||
)}
|
||||
</Flex>
|
||||
<DrawerRoot
|
||||
placement="start"
|
||||
onOpenChange={drawerDisclose.onClose}
|
||||
open={drawerDisclose.open}
|
||||
data-testid="top-bar_drawer-root"
|
||||
>
|
||||
<DrawerContent
|
||||
data-testid="top-bar_drawer-content">
|
||||
<DrawerHeader
|
||||
paddingY="auto"
|
||||
as="button"
|
||||
onClick={drawerDisclose.onClose}
|
||||
boxShadow={'0px 2px 4px ' + colors.back[900]}
|
||||
backgroundColor={backColor}
|
||||
color={useColorModeValue('brand.900', 'brand.50')}
|
||||
textTransform="uppercase"
|
||||
>
|
||||
<HStack
|
||||
{...BUTTON_TOP_BAR_PROPERTY} cursor="pointer">
|
||||
<LuArrowBigLeft />
|
||||
<Span paddingLeft="3px">
|
||||
karso
|
||||
</Span>
|
||||
</HStack>
|
||||
</DrawerHeader>
|
||||
<DrawerBody paddingX="0px">
|
||||
<Box marginY="3" />
|
||||
<ButtonMenuLeft onClickEnd={drawerDisclose.onClose} dest="/" title="Home" icon={<MdHome />} />
|
||||
<ButtonMenuLeft onClickEnd={drawerDisclose.onClose} dest="/change-password" title="Change password" icon={<MdKey />} />
|
||||
<ButtonMenuLeft onClickEnd={drawerDisclose.onClose} dest="/admin-settings" title="Admin settings" icon={<MdSettings />} />
|
||||
<ButtonMenuLeft onClickEnd={drawerDisclose.onClose} dest="/manage-account" title="Manage account" icon={<MdOutlineGroup />} />
|
||||
<ButtonMenuLeft onClickEnd={drawerDisclose.onClose} dest="/manage-application" title="Manage application" icon={<MdOutlineDashboardCustomize />} />
|
||||
</DrawerBody>
|
||||
</DrawerContent>
|
||||
</DrawerRoot>
|
||||
</Flex >
|
||||
);
|
||||
};
|
46
front/src/components/contextMenu/ContextMenu.tsx
Normal file
46
front/src/components/contextMenu/ContextMenu.tsx
Normal file
@ -0,0 +1,46 @@
|
||||
import { ReactNode, useState } from 'react';
|
||||
|
||||
import { LuMenu } from 'react-icons/lu';
|
||||
import { MenuContent, MenuItem, MenuRoot, MenuTrigger } from '../ui/menu';
|
||||
import { Button } from '../ui/button';
|
||||
|
||||
|
||||
export type MenuElement = {
|
||||
icon?: ReactNode;
|
||||
name: string;
|
||||
onClick: () => void;
|
||||
};
|
||||
|
||||
export type ContextMenuProps = {
|
||||
elements?: MenuElement[];
|
||||
};
|
||||
|
||||
export const ContextMenu = ({ elements }: ContextMenuProps) => {
|
||||
if (!elements) {
|
||||
return <></>;
|
||||
}
|
||||
return (
|
||||
<MenuRoot
|
||||
data-testid="context-menu">
|
||||
<MenuTrigger asChild
|
||||
marginY="auto"
|
||||
marginRight="4px"
|
||||
data-testid="context-menu_trigger">
|
||||
{/* This is very stupid, we need to set as span to prevent a button in button... WTF */}
|
||||
<Button variant="ghost" color="brand.500">
|
||||
<LuMenu />
|
||||
</Button>
|
||||
</MenuTrigger>
|
||||
<MenuContent
|
||||
data-testid="context-menu_content">
|
||||
{elements?.map((data) => (
|
||||
<MenuItem key={data.name} value={data.name} onClick={data.onClick} height="65px" fontSize="25px"
|
||||
data-test-id="context-menu_item" >
|
||||
{data.icon}
|
||||
{data.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</MenuContent>
|
||||
</MenuRoot >
|
||||
);
|
||||
};
|
176
front/src/components/form/FormCovers.tsx
Normal file
176
front/src/components/form/FormCovers.tsx
Normal file
@ -0,0 +1,176 @@
|
||||
import {
|
||||
DragEventHandler,
|
||||
ReactNode,
|
||||
RefObject,
|
||||
} from 'react';
|
||||
|
||||
import {
|
||||
Box,
|
||||
BoxProps,
|
||||
Center,
|
||||
Flex,
|
||||
HStack,
|
||||
Image,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
MdHighlightOff,
|
||||
MdUploadFile,
|
||||
} from 'react-icons/md';
|
||||
|
||||
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 = (eventInput: any) => {
|
||||
const event = eventInput as 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 & {
|
||||
children: ReactNode;
|
||||
sizeIcon?: string;
|
||||
};
|
||||
|
||||
export const CenterIcon = ({
|
||||
children,
|
||||
sizeIcon = '15px',
|
||||
...rest
|
||||
}: CenterIconProps) => {
|
||||
return (
|
||||
<Box position="relative" w={sizeIcon} h={sizeIcon} flex="none" {...rest}>
|
||||
<Box
|
||||
w={sizeIcon}
|
||||
h={sizeIcon}
|
||||
position="absolute"
|
||||
top="50%"
|
||||
left="50%"
|
||||
transform="translate(-50%, -50%)"
|
||||
>{children}</Box>
|
||||
</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}
|
||||
>
|
||||
<HStack wrap="wrap" width="full">
|
||||
{urls.map((data, index) => (
|
||||
<Flex align="flex-start" key={data}>
|
||||
<Box width="125px" height="125px" position="relative">
|
||||
<Box width="125px" height="125px" position="absolute">
|
||||
<CenterIcon
|
||||
width="125px"
|
||||
sizeIcon="100%"
|
||||
zIndex="+1"
|
||||
color="#00000020"
|
||||
_hover={{ color: 'red' }}
|
||||
onClick={() => onRemove && onRemove(index)}
|
||||
><MdHighlightOff /></CenterIcon>
|
||||
</Box>
|
||||
<Image loading="lazy" src={data} boxSize="full" />
|
||||
</Box>
|
||||
</Flex>
|
||||
))}
|
||||
<Flex align="flex-start" key="data">
|
||||
<DragNdrop
|
||||
height="125px"
|
||||
width="125px"
|
||||
onFilesSelected={onFilesSelected}
|
||||
onUriSelected={onUriSelected}
|
||||
/>
|
||||
</Flex>
|
||||
</HStack>
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
67
front/src/components/form/FormGroup.tsx
Normal file
67
front/src/components/form/FormGroup.tsx
Normal file
@ -0,0 +1,67 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { Flex, Text } from '@chakra-ui/react';
|
||||
import { MdErrorOutline, MdHelpOutline, MdRefresh } from 'react-icons/md';
|
||||
|
||||
export type FormGroupProps = {
|
||||
error?: ReactNode;
|
||||
help?: ReactNode;
|
||||
label?: ReactNode;
|
||||
isModify?: boolean;
|
||||
onRestore?: () => void;
|
||||
isRequired?: boolean;
|
||||
children: ReactNode;
|
||||
enableModifyNotification?: boolean;
|
||||
enableReset?: boolean;
|
||||
};
|
||||
|
||||
export const FormGroup = ({
|
||||
children,
|
||||
error,
|
||||
help,
|
||||
label,
|
||||
isModify = false,
|
||||
isRequired = false,
|
||||
enableModifyNotification = false,
|
||||
enableReset = false,
|
||||
onRestore,
|
||||
}: FormGroupProps) => (
|
||||
<Flex
|
||||
borderLeftWidth="3px"
|
||||
borderLeftColor={error ? 'red' : enableModifyNotification && isModify ? 'blue' : '#00000000'}
|
||||
paddingLeft="7px"
|
||||
paddingY="4px"
|
||||
width="full"
|
||||
direction="column"
|
||||
>
|
||||
<Flex direction="row" width="full" gap="52px">
|
||||
{!!label && (
|
||||
<Text marginRight="auto" fontWeight="bold">
|
||||
{label}{' '}
|
||||
{isRequired && (
|
||||
<Text as="span" color="red.600">
|
||||
*
|
||||
</Text>
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
{!!onRestore && isModify && enableReset && (
|
||||
<MdRefresh size="15px" onClick={onRestore} cursor="pointer" />
|
||||
)}
|
||||
</Flex>
|
||||
{children}
|
||||
{!!help && (
|
||||
<Flex direction="row">
|
||||
<MdHelpOutline />
|
||||
<Text>{help}</Text>
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
{!!error && (
|
||||
<Flex direction="row">
|
||||
<MdErrorOutline />
|
||||
<Text>{error}</Text>
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
42
front/src/components/form/FormInput.tsx
Normal file
42
front/src/components/form/FormInput.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import { RefObject } from 'react';
|
||||
|
||||
import { Input } from '@chakra-ui/react';
|
||||
|
||||
import { FormGroup, FormGroupProps } from '@/components/form/FormGroup';
|
||||
import { UseFormidableReturn } from '@/components/form/Formidable';
|
||||
|
||||
export type FormInputProps = {
|
||||
form: UseFormidableReturn;
|
||||
variableName: string;
|
||||
ref?: RefObject<any>;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
isRequired?: boolean;
|
||||
} & Omit<FormGroupProps, 'children'>;
|
||||
|
||||
export const FormInput = ({
|
||||
form,
|
||||
variableName,
|
||||
ref,
|
||||
placeholder,
|
||||
...rest
|
||||
}: FormInputProps) => {
|
||||
return (
|
||||
<FormGroup
|
||||
enableModifyNotification={form.configuration.enableModifyNotification}
|
||||
enableReset={form.configuration.enableReset}
|
||||
isModify={form.isModify[variableName]}
|
||||
onRestore={() => form.restoreValue({ [variableName]: true })}
|
||||
{...rest}
|
||||
>
|
||||
<Input
|
||||
ref={ref}
|
||||
type="text"
|
||||
name={variableName}
|
||||
autoComplete={variableName}
|
||||
value={form.values[variableName]}
|
||||
onChange={(e) => form.setValues({ [variableName]: e.target.value })}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
54
front/src/components/form/FormNumber.tsx
Normal file
54
front/src/components/form/FormNumber.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import { RefObject } from 'react';
|
||||
|
||||
import { FormGroup } from '@/components/form/FormGroup';
|
||||
import { UseFormidableReturn } from '@/components/form/Formidable';
|
||||
import { NumberInputField, NumberInputProps, NumberInputRoot } from '../ui/number-input';
|
||||
|
||||
export type FormNumberProps = Pick<
|
||||
NumberInputProps,
|
||||
'step' | 'defaultValue' | 'min' | 'max'
|
||||
> & {
|
||||
form: UseFormidableReturn;
|
||||
variableName: string;
|
||||
ref?: RefObject<any>;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
isRequired?: boolean;
|
||||
};
|
||||
|
||||
export const FormNumber = ({
|
||||
form,
|
||||
variableName,
|
||||
ref,
|
||||
placeholder,
|
||||
step,
|
||||
min,
|
||||
max,
|
||||
defaultValue,
|
||||
...rest
|
||||
}: FormNumberProps) => {
|
||||
const onEvent = (value) => {
|
||||
form.setValues({ [variableName]: value.value });
|
||||
}
|
||||
return (
|
||||
<FormGroup
|
||||
enableModifyNotification={form.configuration.enableModifyNotification}
|
||||
enableReset={form.configuration.enableReset}
|
||||
isModify={form.isModify[variableName]}
|
||||
onRestore={() => form.restoreValue({ [variableName]: true })}
|
||||
{...rest}
|
||||
>
|
||||
<NumberInputRoot
|
||||
ref={ref}
|
||||
value={form.values[variableName]}
|
||||
onValueChange={onEvent}
|
||||
step={step}
|
||||
defaultValue={defaultValue}
|
||||
min={min}
|
||||
max={max}
|
||||
>
|
||||
<NumberInputField />
|
||||
</NumberInputRoot>
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
55
front/src/components/form/FormPassword.tsx
Normal file
55
front/src/components/form/FormPassword.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
import { RefObject, useState } from 'react';
|
||||
|
||||
import { chakra, Group, Input } from '@chakra-ui/react';
|
||||
|
||||
import { FormGroup, FormGroupProps } from '@/components/form/FormGroup';
|
||||
import { UseFormidableReturn } from '@/components/form/Formidable';
|
||||
import { Button } from '../ui/button';
|
||||
import { LuEye, LuEyeOff } from 'react-icons/lu';
|
||||
|
||||
export type FormInputProps = {
|
||||
form: UseFormidableReturn;
|
||||
variableName: string;
|
||||
ref?: RefObject<any>;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
isRequired?: boolean;
|
||||
} & Omit<FormGroupProps, 'children'>;
|
||||
|
||||
export const FormPassword = ({
|
||||
form,
|
||||
variableName,
|
||||
ref,
|
||||
placeholder,
|
||||
...rest
|
||||
}: FormInputProps) => {
|
||||
const [showPassword, setShowPassword] = useState<boolean>(false);
|
||||
function toggleVisible(): void {
|
||||
setShowPassword((value) => ! value)
|
||||
}
|
||||
|
||||
return (
|
||||
<FormGroup
|
||||
enableModifyNotification={form.configuration.enableModifyNotification}
|
||||
enableReset={form.configuration.enableReset}
|
||||
isModify={form.isModify[variableName]}
|
||||
onRestore={() => form.restoreValue({ [variableName]: true })}
|
||||
{...rest}
|
||||
>
|
||||
<chakra.div position="relative">
|
||||
<Input
|
||||
ref={ref}
|
||||
type={showPassword? "text" : "password"}
|
||||
name={variableName}
|
||||
autoComplete={variableName}
|
||||
value={form.values[variableName]}
|
||||
onChange={(e) => form.setValues({ [variableName]: e.target.value })}
|
||||
paddingRight="47px"
|
||||
/>
|
||||
<Button variant="ghost" onClick={toggleVisible} position="absolute" top="0" right="0" _hover={{bg:"#0000", shadow:"none", color:"black"}}>
|
||||
{showPassword? <LuEye/> : <LuEyeOff/>}
|
||||
</Button>
|
||||
</chakra.div>
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
119
front/src/components/form/FormSelect.stories.tsx
Normal file
119
front/src/components/form/FormSelect.stories.tsx
Normal file
@ -0,0 +1,119 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { Box } from '@chakra-ui/react';
|
||||
|
||||
import { FormSelect } from '@/components/form/FormSelect';
|
||||
import { useFormidable } from '@/components/form/Formidable';
|
||||
|
||||
export default {
|
||||
title: 'Components/FormSelect',
|
||||
};
|
||||
|
||||
type BasicFormData = {
|
||||
data?: number;
|
||||
};
|
||||
|
||||
export const Default = () => {
|
||||
const form = useFormidable<BasicFormData>({});
|
||||
return (
|
||||
<FormSelect
|
||||
label="Simple Title"
|
||||
form={form}
|
||||
variableName={'data'}
|
||||
keyInputValue="id"
|
||||
options={[{ id: 111 }, { id: 222 }, { id: 333 }, { id: 123 }]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const ChangeKeys = () => {
|
||||
const form = useFormidable<BasicFormData>({});
|
||||
return (
|
||||
<FormSelect
|
||||
label="Simple Title for (ChangeKeys)"
|
||||
form={form}
|
||||
variableName={'data'}
|
||||
keyInputKey="key"
|
||||
keyInputValue="plop"
|
||||
options={[
|
||||
{ key: 111, plop: 'first Item' },
|
||||
{ key: 222, plop: 'Second Item' },
|
||||
{ key: 333, plop: 'third item' },
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
export const ChangeName = () => {
|
||||
const form = useFormidable<BasicFormData>({});
|
||||
return (
|
||||
<FormSelect
|
||||
label="Simple Title for (ChangeName)"
|
||||
form={form}
|
||||
variableName={'data'}
|
||||
options={[
|
||||
{ id: 111, name: 'first Item' },
|
||||
{ id: 222, name: 'Second Item' },
|
||||
{ id: 333, name: 'third item' },
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
export const AddableItem = () => {
|
||||
const form = useFormidable<BasicFormData>({});
|
||||
const [data, setData] = useState([
|
||||
{ id: 111, name: 'first Item' },
|
||||
{ id: 222, name: 'Second Item' },
|
||||
{ id: 333, name: 'third item' },
|
||||
]);
|
||||
return (
|
||||
<FormSelect
|
||||
label="Simple Title for (ChangeName)"
|
||||
form={form}
|
||||
variableName={'data'}
|
||||
addNewItem={(data: string) => {
|
||||
return new Promise((resolve, _rejects) => {
|
||||
let upperId = 0;
|
||||
setData((previous) => {
|
||||
previous.forEach((element) => {
|
||||
if (element['id'] > upperId) {
|
||||
upperId = element['id'];
|
||||
}
|
||||
});
|
||||
upperId++;
|
||||
return [...previous, { id: upperId, name: data }];
|
||||
});
|
||||
resolve({ id: upperId, name: data });
|
||||
});
|
||||
}}
|
||||
options={data}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const DarkBackground = {
|
||||
render: () => {
|
||||
const form = useFormidable<BasicFormData>({});
|
||||
return (
|
||||
<Box p="4" color="white" bg="gray.800">
|
||||
<FormSelect
|
||||
label="Simple Title for (DarkBackground)"
|
||||
form={form}
|
||||
variableName={'data'}
|
||||
options={[
|
||||
{ id: 111, name: 'first Item' },
|
||||
{ id: 222, name: 'Second Item' },
|
||||
{ id: 333, name: 'third item' },
|
||||
]}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
},
|
||||
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story: 'some story **markdown**',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
72
front/src/components/form/FormSelect.tsx
Normal file
72
front/src/components/form/FormSelect.tsx
Normal file
@ -0,0 +1,72 @@
|
||||
import { RefObject } from 'react';
|
||||
|
||||
import { Text } from '@chakra-ui/react';
|
||||
|
||||
import { FormGroup } from '@/components/form/FormGroup';
|
||||
import { UseFormidableReturn } from '@/components/form/Formidable';
|
||||
import { SelectSingle } from '@/components/select/SelectSingle';
|
||||
|
||||
export type FormSelectProps = {
|
||||
// Generic Form input
|
||||
form: UseFormidableReturn;
|
||||
// Form: Name of the variable
|
||||
variableName: string;
|
||||
// Forward object reference
|
||||
ref?: RefObject<any>;
|
||||
// Form: Label of the input
|
||||
label?: string;
|
||||
// Form: Placeholder if nothing is selected
|
||||
placeholder?: string;
|
||||
// Form: Specify if the element is required or not
|
||||
isRequired?: boolean;
|
||||
// List of object options
|
||||
options: object[];
|
||||
// in the option specify the value Key
|
||||
keyInputKey?: string;
|
||||
// in the option specify the value field
|
||||
keyInputValue?: string;
|
||||
// Add capability to add an item (no key but only value)
|
||||
addNewItem?: (data: string) => Promise<any>;
|
||||
// if a suggestion exist at the auto compleat
|
||||
suggestion?: string;
|
||||
};
|
||||
|
||||
export const FormSelect = ({
|
||||
form,
|
||||
variableName,
|
||||
ref,
|
||||
placeholder,
|
||||
options,
|
||||
keyInputKey = 'id',
|
||||
keyInputValue = 'name',
|
||||
suggestion,
|
||||
addNewItem,
|
||||
...rest
|
||||
}: FormSelectProps) => {
|
||||
// if set add capability to add the search item
|
||||
const onCreate = !addNewItem
|
||||
? undefined
|
||||
: (data: string) => {
|
||||
addNewItem(data).then((data: object) => form.setValues({ [variableName]: data[keyInputKey] }));
|
||||
};
|
||||
return (
|
||||
<FormGroup
|
||||
enableModifyNotification={form.configuration.enableModifyNotification}
|
||||
enableReset={form.configuration.enableReset}
|
||||
isModify={form.isModify[variableName]}
|
||||
onRestore={() => form.restoreValue({ [variableName]: true })}
|
||||
{...rest}
|
||||
>
|
||||
<SelectSingle
|
||||
ref={ref}
|
||||
value={form.values[variableName]}
|
||||
options={options}
|
||||
onChange={(value) => form.setValues({ [variableName]: value })}
|
||||
keyKey={keyInputKey}
|
||||
keyValue={keyInputValue}
|
||||
onCreate={onCreate}
|
||||
suggestion={suggestion}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user