[FEAT] migrate to react/chakra-ui v3 (not working)

This commit is contained in:
Edouard DUPIN 2025-02-02 19:33:28 +01:00
parent bee72ee8a3
commit 1a8a315afc
193 changed files with 33942 additions and 230 deletions

View File

@ -20,7 +20,7 @@
<dependency> <dependency>
<groupId>kangaroo-and-rabbit</groupId> <groupId>kangaroo-and-rabbit</groupId>
<artifactId>archidata</artifactId> <artifactId>archidata</artifactId>
<version>0.21.1-SNAPSHOT</version> <version>0.23.2</version>
</dependency> </dependency>
<!-- Loopback of logger JDK logging API to SLF4J --> <!-- Loopback of logger JDK logging API to SLF4J -->
<dependency> <dependency>

View File

@ -6,6 +6,7 @@ import java.util.List;
import org.kar.archidata.api.DataResource; import org.kar.archidata.api.DataResource;
import org.kar.archidata.externalRestApi.AnalyzeApi; import org.kar.archidata.externalRestApi.AnalyzeApi;
import org.kar.archidata.externalRestApi.TsGenerateApi; import org.kar.archidata.externalRestApi.TsGenerateApi;
import org.kar.archidata.model.token.JwtToken;
import org.kar.archidata.tools.ConfigBaseVariable; import org.kar.archidata.tools.ConfigBaseVariable;
import org.kar.karso.api.ApplicationResource; import org.kar.karso.api.ApplicationResource;
import org.kar.karso.api.ApplicationTokenResource; import org.kar.karso.api.ApplicationTokenResource;
@ -30,6 +31,7 @@ public class WebLauncherLocal extends WebLauncher {
SystemConfigResource.class); SystemConfigResource.class);
final AnalyzeApi api = new AnalyzeApi(); final AnalyzeApi api = new AnalyzeApi();
api.addAllApi(listOfResources); api.addAllApi(listOfResources);
api.addModel(JwtToken.class);
TsGenerateApi.generateApi(api, "../front/src/back-api/"); TsGenerateApi.generateApi(api, "../front/src/back-api/");
LOGGER.info("Generate APIs (DONE)"); LOGGER.info("Generate APIs (DONE)");
} }

View File

@ -6,6 +6,7 @@ import org.kar.archidata.dataAccess.DBAccess;
import org.kar.archidata.dataAccess.addOnSQL.AddOnManyToMany; import org.kar.archidata.dataAccess.addOnSQL.AddOnManyToMany;
import org.kar.archidata.filter.PartRight; import org.kar.archidata.filter.PartRight;
import org.kar.archidata.migration.MigrationSqlStep; import org.kar.archidata.migration.MigrationSqlStep;
import org.kar.archidata.model.token.JwtToken;
import org.kar.karso.api.UserResource; import org.kar.karso.api.UserResource;
import org.kar.karso.model.Application; import org.kar.karso.model.Application;
import org.kar.karso.model.ApplicationToken; import org.kar.karso.model.ApplicationToken;
@ -22,7 +23,7 @@ public class Initialization extends MigrationSqlStep {
public static final int KARSO_INITIALISATION_ID = 1; public static final int KARSO_INITIALISATION_ID = 1;
public static final List<Class<?>> CLASSES_BASE = List.of(Settings.class, UserAuth.class, Application.class, public static final List<Class<?>> CLASSES_BASE = List.of(Settings.class, UserAuth.class, Application.class,
ApplicationToken.class, RightDescription.class, Right.class); ApplicationToken.class, RightDescription.class, Right.class, JwtToken.class);
// created object // created object
private Application app = null; private Application app = null;
private UserAuth user = null; private UserAuth user = null;

View File

@ -1,6 +1,6 @@
package org.kar.karso.model; package org.kar.karso.model;
import org.kar.archidata.dataAccess.options.CheckJPA; import org.kar.archidata.checker.CheckJPA;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;

View File

@ -7,7 +7,7 @@ import java.time.ZoneOffset;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import org.kar.archidata.dataAccess.options.CheckJPA; import org.kar.archidata.checker.CheckJPA;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;

View File

@ -4,7 +4,7 @@ import java.sql.Timestamp;
import java.util.List; import java.util.List;
import org.kar.archidata.annotation.DataIfNotExists; 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 org.kar.archidata.model.User;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;

View File

@ -1,6 +1,6 @@
package org.kar.karso.model; package org.kar.karso.model;
import org.kar.archidata.dataAccess.options.CheckJPA; import org.kar.archidata.checker.CheckJPA;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;

2
front/.env.production Normal file
View File

@ -0,0 +1,2 @@
# URL for database connection
VITE_API_BASE_URL=karso/api/

27
front/.storybook/main.ts Normal file
View 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;

View 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>

View 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
View File

@ -0,0 +1,2 @@
Proprietary
@copyright Edouard Dupin 2024

6
front/app-build.json Normal file
View File

@ -0,0 +1,6 @@
{
"display": "2025-01-14",
"version": "0.0.1-dev\n - 2025-01-14T20:19:20+01:00",
"commit": "0.0.1-dev\n",
"date": "2025-01-14T20:19:20+01:00"
}

25
front/build.js Normal file
View 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

File diff suppressed because it is too large Load Diff

0
front/doc/.keep Normal file
View File

13
front/index.html Normal file
View 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
View 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;

94
front/package.json Normal file
View File

@ -0,0 +1,94 @@
{
"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": {
"@lukemorales/query-key-factory": "1.3.4",
"@tanstack/react-query": "^5.65.1",
"@tanstack/react-query-devtools": "^5.65.1",
"@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"
}
}

View File

11315
front/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

16
front/prettier.config.js Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

119
front/src/App.tsx Normal file
View File

@ -0,0 +1,119 @@
import { useState } from 'react';
import {
Box,
Button,
ChakraProvider,
Dialog,
Select,
Stack,
Text,
useDisclosure,
} from '@chakra-ui/react';
import { environment } from '@/environment';
import { App as SpaApp } from '@/scene/App';
import { USERS, USERS_COLLECTION } from '@/service/session';
import { hashLocalData } from '@/utils/sso';
import { Toaster } from './components/ui/toaster';
import { systemTheme } from './theme/theme';
const AppEnvHint = () => {
const dialog = useDisclosure();
const [selectUserTest, setSelectUserTest] = useState<string>('NO_USER');
//const setUser = useRightsStore((store) => store.setUser);
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 = (selectedOption) => {
console.log(`SELECT: [${selectedOption.target.value}]`);
setSelectUserTest(selectedOption.target.value);
};
const onClose = () => {
dialog.onClose();
if (selectUserTest == 'NO_USER') {
window.location.href = `/${environment.applName}/sso/${hashLocalData()}/false/__LOGOUT__`;
} else {
window.location.href = `/${environment.applName}/sso/${hashLocalData()}/true/${USERS[selectUserTest]}`;
}
};
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.Content>
<Dialog.Header>Outils développeurs</Dialog.Header>
<Dialog.Body>
<Stack>
<Text>User</Text>
<Select.Root onChange={handleChange} 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}>
{value.label}
</Select.Item>
))}
</Select.Content>
</Select.Root>
</Stack>
</Dialog.Body>
<Dialog.Footer>
<Button onClick={onClose}>Close</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>
</>
);
};
const App = () => {
return (
<ChakraProvider value={systemTheme}>
<AppEnvHint />
<SpaApp />
<Toaster />
</ChakraProvider>
);
};
export default App;

View 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

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M24 44q-4.15 0-7.8-1.575-3.65-1.575-6.35-4.275-2.7-2.7-4.275-6.35Q4 28.15 4 24t1.575-7.8Q7.15 12.55 9.85 9.85q2.7-2.7 6.35-4.275Q19.85 4 24 4t7.8 1.575q3.65 1.575 6.35 4.275 2.7 2.7 4.275 6.35Q44 19.85 44 24t-1.575 7.8q-1.575 3.65-4.275 6.35-2.7 2.7-6.35 4.275Q28.15 44 24 44Zm0-3q7.1 0 12.05-4.95Q41 31.1 41 24q0-3.05-1.05-5.85T37 13.05L13.05 37q2.25 1.95 5.075 2.975Q20.95 41 24 41Zm-12.95-6.05 23.9-23.9q-2.3-1.95-5.1-3T24 7q-7.1 0-12.05 4.95Q7 16.9 7 24q0 3.05 1.1 5.875t2.95 5.075Z"/></svg>

After

Width:  |  Height:  |  Size: 567 B

View File

@ -0,0 +1,59 @@
<?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"
version="1.1"
id="svg2"
width="1600"
height="1600"
viewBox="0 0 1600 1600"
sodipodi:docname="comments.svg"
inkscape:version="0.92.2 2405546, 2018-03-11">
<metadata
id="metadata8">
<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>
<defs
id="defs6" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1598"
inkscape:window-height="858"
id="namedview4"
showgrid="false"
inkscape:zoom="0.417193"
inkscape:cx="564.95647"
inkscape:cy="689.55475"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<path
style="fill:#ffffff;fill-opacity:1"
d="M 1450,1300 H 970.49559 L 800,1470 629.50441,1300 H 150 V 300 H 1450 Z M 1350,400 H 250 v 800 H 670.50581 L 800,1329 929.49419,1200 H 1350 Z M 450,950 h 500 v 100 H 450 Z m 0,-200 h 700 V 850 H 450 Z M 1036,650 H 450 V 550 h 586 z"
id="path4520"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccccccccccccccccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M25.5 19.5V6H42v13.5ZM6 25.5V6h16.5v19.5ZM25.5 42V22.5H42V42ZM6 42V28.5h16.5V42Zm3-19.5h10.5V9H9ZM28.5 39H39V25.5H28.5Zm0-22.5H39V9H28.5ZM9 39h10.5v-7.5H9Zm10.5-16.5Zm9-6Zm0 9Zm-9 6Z"/></svg>

After

Width:  |  Height:  |  Size: 263 B

View File

@ -0,0 +1,63 @@
<?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"
version="1.1"
id="svg2"
width="128"
height="128"
viewBox="0 0 128 128"
sodipodi:docname="erase.svg"
inkscape:version="0.92.2 2405546, 2018-03-11">
<metadata
id="metadata8">
<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>
<defs
id="defs6" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1598"
inkscape:window-height="858"
id="namedview4"
showgrid="false"
inkscape:zoom="1.0091185"
inkscape:cx="-283.45157"
inkscape:cy="33.728592"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:9.22393036;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 78.057715,6.7629418 74.781278,10.009583 7.1140977,77.061429 41.377799,111.63957 l 24.704188,0.002 58.479833,-57.94805 z M 50.017286,47.533394 83.536922,81.36064 62.286619,102.4177 45.22373,102.41662 20.158146,77.121007 Z"
id="rect1639"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:6.53187132;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 0.12387033,120.4439 H 66.02296"
id="path1656"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg1543"
sodipodi:docname="group.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, 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="defs1547" />
<sodipodi:namedview
id="namedview1545"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="21.395833"
inkscape:cx="24"
inkscape:cy="24"
inkscape:window-width="3838"
inkscape:window-height="2118"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg1543" />
<path
d="M1.9 40v-4.7q0-1.75.9-3.175Q3.7 30.7 5.3 30q3.65-1.6 6.575-2.3Q14.8 27 17.9 27q3.1 0 6 .7t6.55 2.3q1.6.7 2.525 2.125.925 1.425.925 3.175V40Zm35 0v-4.7q0-3.15-1.6-5.175t-4.2-3.275q3.45.4 6.5 1.175t4.95 1.775q1.65.95 2.6 2.35.95 1.4.95 3.15V40Zm-19-16.05q-3.3 0-5.4-2.1-2.1-2.1-2.1-5.4 0-3.3 2.1-5.4 2.1-2.1 5.4-2.1 3.3 0 5.4 2.1 2.1 2.1 2.1 5.4 0 3.3-2.1 5.4-2.1 2.1-5.4 2.1Zm18-7.5q0 3.3-2.1 5.4-2.1 2.1-5.4 2.1-.55 0-1.225-.075T25.95 23.6q1.2-1.25 1.825-3.075.625-1.825.625-4.075t-.625-3.975Q27.15 10.75 25.95 9.3q.55-.15 1.225-.25t1.225-.1q3.3 0 5.4 2.1 2.1 2.1 2.1 5.4ZM4.9 37h26v-1.7q0-.8-.475-1.55T29.25 32.7q-3.6-1.6-6.05-2.15-2.45-.55-5.3-.55-2.85 0-5.325.55T6.5 32.7q-.7.3-1.15 1.05-.45.75-.45 1.55Zm13-16.05q1.95 0 3.225-1.275Q22.4 18.4 22.4 16.45q0-1.95-1.275-3.225Q19.85 11.95 17.9 11.95q-1.95 0-3.225 1.275Q13.4 14.5 13.4 16.45q0 1.95 1.275 3.225Q15.95 20.95 17.9 20.95Zm0 16.05Zm0-20.55Z"
id="path1541"
style="fill:#ffffff;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,4 @@
<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>
</svg>

After

Width:  |  Height:  |  Size: 303 B

View File

@ -0,0 +1,78 @@
<?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.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" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="52.480467"
inkscape:cy="138.73493"
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)">
<g
aria-label="K"
transform="scale(1.0347881,0.96638145)"
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:#000000;fill-opacity:1;stroke:none;stroke-width:2.11376619"
id="text821">
<path
d="m 12.784421,241.62303 h 8.949095 v 27.37877 l 25.568842,-27.37877 6.39221,6.84469 -20.455074,21.90302 20.455074,27.37876 -6.39221,5.47576 -19.176632,-27.37877 -6.39221,6.84469 0,20.53408 h -8.949095 z"
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;stroke-width:2.11376619;fill:#ff0000;fill-opacity:1"
id="path823"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View 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

View 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

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg4"
sodipodi:docname="lan.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, 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="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="16.822701"
inkscape:cx="12.691184"
inkscape:cy="39.737971"
inkscape:window-width="3838"
inkscape:window-height="2118"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<rect
style="fill:#000000;stroke:#ffffff;stroke-width:3;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
id="rect897"
width="12.08835"
height="10.642548"
x="17.961397"
y="5.4625888" />
<rect
style="fill:#000000;stroke:#ffffff;stroke-width:3;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
id="rect897-3"
width="12.08835"
height="10.642548"
x="7.428793"
y="32.038437" />
<rect
style="fill:#000000;stroke:#ffffff;stroke-width:3;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
id="rect897-6"
width="12.08835"
height="10.642548"
x="28.561865"
y="31.936249" />
<path
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="m 13.584028,32.01093 v -7.707304 h 20.889927 v 7.894963"
id="path990" />
<path
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="M 24.032132,23.799058 V 16.118716"
id="path992" />
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View 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

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg1004"
sodipodi:docname="person.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, 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="defs1008" />
<sodipodi:namedview
id="namedview1006"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="21.395833"
inkscape:cx="24"
inkscape:cy="24"
inkscape:window-width="3838"
inkscape:window-height="2118"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg1004" />
<path
d="M24 23.95q-3.3 0-5.4-2.1-2.1-2.1-2.1-5.4 0-3.3 2.1-5.4 2.1-2.1 5.4-2.1 3.3 0 5.4 2.1 2.1 2.1 2.1 5.4 0 3.3-2.1 5.4-2.1 2.1-5.4 2.1ZM8 40v-4.7q0-1.9.95-3.25T11.4 30q3.35-1.5 6.425-2.25Q20.9 27 24 27q3.1 0 6.15.775 3.05.775 6.4 2.225 1.55.7 2.5 2.05.95 1.35.95 3.25V40Zm3-3h26v-1.7q0-.8-.475-1.525-.475-.725-1.175-1.075-3.2-1.55-5.85-2.125Q26.85 30 24 30t-5.55.575q-2.7.575-5.85 2.125-.7.35-1.15 1.075Q11 34.5 11 35.3Zm13-16.05q1.95 0 3.225-1.275Q28.5 18.4 28.5 16.45q0-1.95-1.275-3.225Q25.95 11.95 24 11.95q-1.95 0-3.225 1.275Q19.5 14.5 19.5 16.45q0 1.95 1.275 3.225Q22.05 20.95 24 20.95Zm0-4.5ZM24 37Z"
id="path1002"
style="stroke:none;stroke-opacity:1;fill:#ffffff;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="m19.4 44-1-6.3q-.95-.35-2-.95t-1.85-1.25l-5.9 2.7L4 30l5.4-3.95q-.1-.45-.125-1.025Q9.25 24.45 9.25 24q0-.45.025-1.025T9.4 21.95L4 18l4.65-8.2 5.9 2.7q.8-.65 1.85-1.25t2-.9l1-6.35h9.2l1 6.3q.95.35 2.025.925Q32.7 11.8 33.45 12.5l5.9-2.7L44 18l-5.4 3.85q.1.5.125 1.075.025.575.025 1.075t-.025 1.05q-.025.55-.125 1.05L44 30l-4.65 8.2-5.9-2.7q-.8.65-1.825 1.275-1.025.625-2.025.925l-1 6.3ZM24 30.5q2.7 0 4.6-1.9 1.9-1.9 1.9-4.6 0-2.7-1.9-4.6-1.9-1.9-4.6-1.9-2.7 0-4.6 1.9-1.9 1.9-1.9 4.6 0 2.7 1.9 4.6 1.9 1.9 4.6 1.9Zm0-3q-1.45 0-2.475-1.025Q20.5 25.45 20.5 24q0-1.45 1.025-2.475Q22.55 20.5 24 20.5q1.45 0 2.475 1.025Q27.5 22.55 27.5 24q0 1.45-1.025 2.475Q25.45 27.5 24 27.5Zm0-3.5Zm-2.2 17h4.4l.7-5.6q1.65-.4 3.125-1.25T32.7 32.1l5.3 2.3 2-3.6-4.7-3.45q.2-.85.325-1.675.125-.825.125-1.675 0-.85-.1-1.675-.1-.825-.35-1.675L40 17.2l-2-3.6-5.3 2.3q-1.15-1.3-2.6-2.175-1.45-.875-3.2-1.125L26.2 7h-4.4l-.7 5.6q-1.7.35-3.175 1.2-1.475.85-2.625 2.1L10 13.6l-2 3.6 4.7 3.45q-.2.85-.325 1.675-.125.825-.125 1.675 0 .85.125 1.675.125.825.325 1.675L8 30.8l2 3.6 5.3-2.3q1.2 1.2 2.675 2.05Q19.45 35 21.1 35.4Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -0,0 +1,75 @@
<?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"
version="1.1"
id="svg2"
width="128"
height="128"
viewBox="0 0 128 128"
sodipodi:docname="time.svg"
inkscape:version="0.92.2 2405546, 2018-03-11">
<metadata
id="metadata8">
<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>
<defs
id="defs6" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1598"
inkscape:window-height="858"
id="namedview4"
showgrid="false"
inkscape:zoom="4.036474"
inkscape:cx="-40.018401"
inkscape:cy="81.29527"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:9.1856041;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 47.770331,11.314001 h 32"
id="path818-3"
inkscape:connector-curvature="0" />
<ellipse
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:10.51563644;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
id="path816"
cx="64"
cy="73"
rx="44.742184"
ry="44.74218" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:9.88546944;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 64,41.806476 V 78"
id="path818"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:6.86596394;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 94.602591,23.156735 108.29726,34.650486"
id="path818-3-6"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,4 @@
<svg fill="#dd0000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z"/>
</svg>

After

Width:  |  Height:  |  Size: 246 B

View File

@ -0,0 +1,4 @@
<svg fill="#089314" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
</svg>

After

Width:  |  Height:  |  Size: 281 B

View 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,
});
};
}

View 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,
});
};
}

View 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,
});
};
}

View File

@ -0,0 +1,6 @@
/**
* Interface of the server (auto-generated code)
*/
export namespace Front {
}

View 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"

View 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,
});
};
}

View 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,
});
};
}

View 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,
});
};
}

View 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,
});
};
}

View File

@ -0,0 +1,7 @@
/**
* Interface of the server (auto-generated code)
*/
export * from "./model";
export * from "./api";
export * from "./rest-tools";

View 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;
}
}

View 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;
}
}

View File

@ -0,0 +1,37 @@
/**
* Interface of the server (auto-generated code)
*/
import { z as zod } from "zod";
import {ZodGenericToken, ZodGenericTokenWrite } from "./generic-token";
export const ZodApplicationToken = ZodGenericToken.extend({
});
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.extend({
});
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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View File

@ -0,0 +1,41 @@
/**
* 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.extend({
});
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;
}
}

View File

@ -0,0 +1,42 @@
/**
* 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.extend({
});
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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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"

View 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>;

View 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>;

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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>;

View 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>;

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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>;

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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>;

View 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);
});
});
}

View 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 icon={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>
};

View 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>
);
};

View File

@ -0,0 +1,41 @@
import {
Box,
Flex,
FlexProps,
} from '@chakra-ui/react';
import { forwardRef, ReactNode } from 'react';
export type IconProps = FlexProps & {
icon: ReactNode;
color?: string;
sizeIcon?: FlexProps['width'];
};
export const Icon = forwardRef<HTMLDivElement, IconProps>(
({ icon: IconEl, 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
>
{IconEl}
</Box>
</Flex>
);
}
);
Icon.displayName = 'Icon';

View 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 background 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={-1}
>
<Image src={background} boxSize="90%" margin="auto" opacity="30%" />
</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>
</>
);
};

View 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>
);
};

View 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>
);
};

View File

@ -0,0 +1,221 @@
import { ReactNode } from 'react';
import {
Box,
Flex,
HStack,
IconButton,
Text,
useDisclosure,
Button,
ConditionalValue,
Span,
} from '@chakra-ui/react';
import {
LuAlignJustify,
LuArrowBigLeft,
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 }: { dest: string, title: string, icon: ReactNode }) => {
const navigate = useNavigate();
return <>
<Button
background="#00000000"
borderRadius="0px"
onClick={() => navigate(dest)}
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 { clearToken } = useSessionService();
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('/sing-up')}
disabled={true}
>
<MdMore />
<Text paddingLeft="3px" fontWeight="bold">
Sign-up
</Text>
</Button>
</>
)}
{session?.token && (
<MenuRoot>
<MenuTrigger asChild>
<IconButton
asChild
aria-label="Options"
{...BUTTON_TOP_BAR_PROPERTY}
width={TOP_BAR_HEIGHT}
><MdSupervisedUserCircle /></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('/logout')}>
<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 dest="/" title="Home" icon={<MdHome />} />
<ButtonMenuLeft dest="/change-password" title="Change password" icon={<MdKey />} />
<ButtonMenuLeft dest="/admin-settings" title="Admin settings" icon={<MdSettings />} />
<ButtonMenuLeft dest="/manage-account" title="Manage account" icon={<MdOutlineGroup />} />
<ButtonMenuLeft dest="/manage-application" title="Manage application" icon={<MdOutlineDashboardCustomize />} />
</DrawerBody>
</DrawerContent>
</DrawerRoot>
</Flex >
);
};

View File

@ -0,0 +1,63 @@
import { Flex, Span, Text } from '@chakra-ui/react';
import { LuDisc3 } from 'react-icons/lu';
import { Album } from '@/back-api';
import { Covers } from '@/components/Cover';
import { useCountTracksWithAlbumId } from '@/service/Track';
import { BASE_WRAP_ICON_SIZE } from '@/constants/genericSpacing';
export type DisplayAlbumProps = {
dataAlbum?: Album;
};
export const DisplayAlbum = ({ dataAlbum }: DisplayAlbumProps) => {
const { countTracksOfAnAlbum } = useCountTracksWithAlbumId(dataAlbum?.id);
if (!dataAlbum) {
return (
<Flex direction="row" width="full" height="full">
Fail to retrieve Album Data.
</Flex>
);
}
return (
<Flex direction="row" width="full" height="full"
data-testid="display-album_flex">
<Covers
data={dataAlbum?.covers}
size={BASE_WRAP_ICON_SIZE}
flex={1}
iconEmpty={<LuDisc3 />}
/>
<Flex
direction="column"
width="150px"
//maxWidth="150px"
height="full"
paddingLeft="5px"
overflowX="hidden"
flex={1}
>
<Span
textAlign="left"
fontSize="20px"
fontWeight="bold"
userSelect="none"
marginRight="auto"
overflow="hidden"
// noOfLines={[1, 2]}
>
{dataAlbum?.name}
</Span>
<Span
textAlign="left"
fontSize="15px"
userSelect="none"
marginRight="auto"
overflow="hidden"
// noOfLines={1}
>
{countTracksOfAnAlbum} track{countTracksOfAnAlbum >= 1 && 's'}
</Span>
</Flex>
</Flex>
);
};

View File

@ -0,0 +1,11 @@
import { DisplayAlbum } from '@/components/album/DisplayAlbum';
import { useSpecificAlbum } from '@/service/Album';
export type DisplayAlbumIdProps = {
id: number;
};
export const DisplayAlbumId = ({ id }: DisplayAlbumIdProps) => {
const { dataAlbum } = useSpecificAlbum(id);
return <DisplayAlbum dataAlbum={dataAlbum}
data-testid="display-album-id" />;
};

View 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 >
);
};

View File

@ -0,0 +1,175 @@
import {
DragEventHandler,
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 & {
icon: any;
sizeIcon?: string;
};
export const CenterIcon = ({
icon: IconEl,
sizeIcon = '15px',
...rest
}: CenterIconProps) => {
return (
<Box position="relative" w={sizeIcon} h={sizeIcon} flex="none" {...rest}>
<Box
w={sizeIcon}
h={sizeIcon}
position="absolute"
top="50%"
left="50%"
transform="translate(-50%, -50%)"
>{IconEl}</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>
);
};

View File

@ -0,0 +1,63 @@
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;
};
export const FormGroup = ({
children,
error,
help,
label,
isModify = false,
isRequired = false,
onRestore,
}: FormGroupProps) => (
<Flex
borderLeftWidth="3px"
borderLeftColor={error ? 'red' : 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 && (
<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>
);

View File

@ -0,0 +1,39 @@
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
isModify={form.isModify[variableName]}
onRestore={() => form.restoreValue({ [variableName]: true })}
{...rest}
>
<Input
ref={ref}
type="text"
name={variableName}
value={form.values[variableName]}
onChange={(e) => form.setValues({ [variableName]: e.target.value })}
/>
</FormGroup>
);
};

Some files were not shown because too many files have changed in this diff Show More