proje-react-panel 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +2 -0
- package/.idea/vcs.xml +0 -1
- package/.idea/watcherTasks.xml +4 -0
- package/dist/api/crudApi.d.ts +12 -4
- package/dist/components/ErrorBoundary.d.ts +16 -0
- package/dist/components/ErrorComponent.d.ts +4 -0
- package/dist/components/Form.d.ts +6 -0
- package/dist/components/FormField.d.ts +13 -0
- package/dist/components/Label.d.ts +8 -0
- package/dist/components/Panel.d.ts +3 -1
- package/dist/components/layout/Layout.d.ts +9 -2
- package/dist/components/layout/SideBar.d.ts +13 -2
- package/dist/components/list/List.d.ts +5 -5
- package/dist/components/screens/ControllerCreate.d.ts +5 -0
- package/dist/components/screens/ControllerDetails.d.ts +5 -0
- package/dist/components/screens/ControllerEdit.d.ts +5 -0
- package/dist/components/screens/ControllerList.d.ts +5 -0
- package/dist/components/screens/Login.d.ts +4 -0
- package/dist/decorators/Cell.d.ts +9 -0
- package/dist/decorators/Input.d.ts +13 -0
- package/dist/hooks/useScreens.d.ts +2 -0
- package/dist/index.cjs.js +1 -12
- package/dist/index.d.ts +6 -1
- package/dist/index.esm.js +1 -12
- package/dist/initPanel.d.ts +2 -0
- package/dist/initPanelOptions.d.ts +8 -0
- package/dist/screens/ControllerDetails.d.ts +2 -2
- package/dist/screens/ControllerEdit.d.ts +2 -2
- package/dist/screens/ControllerList.d.ts +2 -2
- package/dist/screens/Form.d.ts +2 -2
- package/dist/src/api/crudApi.d.ts +6 -0
- package/dist/src/components/Panel.d.ts +9 -0
- package/dist/src/components/layout/Layout.d.ts +11 -0
- package/dist/src/components/layout/SideBar.d.ts +10 -0
- package/dist/src/components/list/List.d.ts +10 -0
- package/dist/src/decorators/Crud.d.ts +6 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/screens/ControllerCreate.d.ts +5 -0
- package/dist/src/screens/ControllerDetails.d.ts +5 -0
- package/dist/src/screens/ControllerEdit.d.ts +5 -0
- package/dist/src/screens/ControllerList.d.ts +5 -0
- package/dist/src/screens/Form.d.ts +6 -0
- package/dist/src/store/store.d.ts +19 -0
- package/dist/src/types/Screen.d.ts +4 -0
- package/dist/src/types/ScreenCreatorData.d.ts +8 -0
- package/dist/src/utils/createScreens.d.ts +1 -0
- package/dist/src/utils/getFields.d.ts +2 -0
- package/dist/src/utils/getScreens.d.ts +2 -0
- package/dist/store/store.d.ts +19 -0
- package/dist/types/ScreenCreatorData.d.ts +9 -6
- package/dist/types/initPanelOptions.d.ts +8 -0
- package/dist/utils/crudScreens.d.ts +2 -0
- package/dist/utils/getFields.d.ts +1 -1
- package/dist/utils/getScreens.d.ts +2 -0
- package/package.json +14 -8
- package/src/api/crudApi.ts +30 -28
- package/src/components/ErrorBoundary.tsx +64 -0
- package/src/components/ErrorComponent.tsx +15 -0
- package/src/components/Form.tsx +70 -0
- package/src/components/FormField.tsx +60 -0
- package/src/components/Label.tsx +15 -0
- package/src/components/Panel.tsx +12 -7
- package/src/components/layout/Layout.tsx +16 -12
- package/src/components/layout/SideBar.tsx +38 -12
- package/src/components/list/List.tsx +73 -67
- package/src/components/screens/ControllerCreate.tsx +7 -0
- package/src/components/screens/ControllerDetails.tsx +40 -0
- package/src/components/screens/ControllerEdit.tsx +35 -0
- package/src/components/screens/ControllerList.tsx +44 -0
- package/src/components/screens/Login.tsx +64 -0
- package/src/decorators/Cell.ts +34 -0
- package/src/decorators/Input.ts +50 -0
- package/src/hooks/useScreens.tsx +37 -0
- package/src/index.ts +7 -2
- package/src/initPanel.ts +14 -0
- package/src/store/store.ts +18 -0
- package/src/styles/error-boundary.scss +89 -0
- package/src/styles/form.scss +38 -6
- package/src/styles/index.scss +22 -4
- package/src/styles/layout.scss +49 -0
- package/src/styles/list.scss +8 -6
- package/src/styles/login.scss +90 -0
- package/src/styles/sidebar.scss +17 -22
- package/src/types/ScreenCreatorData.ts +10 -7
- package/src/types/initPanelOptions.ts +8 -0
- package/src/utils/createScreens.ts +2 -2
- package/src/utils/getFields.ts +8 -9
- package/dist/utils/getScreenForRoutes.d.ts +0 -2
- package/dist/utils/storeData.d.ts +0 -4
- package/src/declerations/Cell.ts +0 -37
- package/src/screens/ControllerCreate.tsx +0 -13
- package/src/screens/ControllerDetails.tsx +0 -34
- package/src/screens/ControllerEdit.tsx +0 -31
- package/src/screens/ControllerList.tsx +0 -40
- package/src/screens/Form.tsx +0 -67
- package/src/utils/getScreenForRoutes.tsx +0 -44
- package/src/utils/storeData.ts +0 -7
- /package/dist/{declerations → decorators}/Crud.d.ts +0 -0
- /package/dist/{declerations → src/decorators}/Cell.d.ts +0 -0
- /package/src/{declerations → decorators}/Crud.ts +0 -0
package/src/styles/sidebar.scss
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
.sidebar {
|
2
2
|
position: relative;
|
3
|
-
background-color: #
|
3
|
+
background-color: #343a40;
|
4
4
|
height: 100vh;
|
5
5
|
transition: width 0.3s ease;
|
6
|
-
border-right: 1px solid #
|
7
|
-
|
6
|
+
border-right: 1px solid #454d55;
|
8
7
|
&.open {
|
9
8
|
width: 250px;
|
10
9
|
}
|
@@ -12,13 +11,6 @@
|
|
12
11
|
&.closed {
|
13
12
|
width: 60px;
|
14
13
|
|
15
|
-
.nav-links {
|
16
|
-
a {
|
17
|
-
span {
|
18
|
-
display: none;
|
19
|
-
}
|
20
|
-
}
|
21
|
-
}
|
22
14
|
}
|
23
15
|
|
24
16
|
.toggle-button {
|
@@ -28,8 +20,8 @@
|
|
28
20
|
width: 24px;
|
29
21
|
height: 24px;
|
30
22
|
border-radius: 50%;
|
31
|
-
background-color: #
|
32
|
-
border: 1px solid #
|
23
|
+
background-color: #495057;
|
24
|
+
border: 1px solid #6c757d;
|
33
25
|
display: flex;
|
34
26
|
align-items: center;
|
35
27
|
justify-content: center;
|
@@ -37,30 +29,33 @@
|
|
37
29
|
z-index: 10;
|
38
30
|
|
39
31
|
&:hover {
|
40
|
-
background-color: #
|
32
|
+
background-color: #6c757d;
|
41
33
|
}
|
42
34
|
}
|
43
35
|
|
44
36
|
.nav-links {
|
45
37
|
display: flex;
|
46
38
|
flex-direction: column;
|
47
|
-
padding: 2rem
|
39
|
+
padding: 2rem 0;
|
48
40
|
height: 100%;
|
41
|
+
overflow: hidden;
|
49
42
|
|
50
43
|
a {
|
51
|
-
padding: 0.75rem
|
44
|
+
padding: 0.75rem 0;
|
45
|
+
white-space: nowrap;
|
52
46
|
margin-bottom: 0.5rem;
|
53
|
-
color: #
|
47
|
+
color: #e9ecef;
|
54
48
|
text-decoration: none;
|
55
49
|
border-radius: 4px;
|
56
50
|
font-weight: 500;
|
57
|
-
|
58
|
-
|
59
|
-
background-color: rgba(0, 0, 0, 0.05);
|
51
|
+
&.active {
|
52
|
+
background-color: rgba(233, 236, 239, 0.2);
|
60
53
|
}
|
61
54
|
|
62
|
-
|
63
|
-
|
55
|
+
.nav-links-icon {
|
56
|
+
display: inline-block;
|
57
|
+
width: 60px;
|
58
|
+
text-align: center;
|
64
59
|
}
|
65
60
|
}
|
66
61
|
|
@@ -68,7 +63,7 @@
|
|
68
63
|
margin-top: auto;
|
69
64
|
|
70
65
|
a {
|
71
|
-
color: #
|
66
|
+
color: #adb5bd;
|
72
67
|
font-weight: 400;
|
73
68
|
}
|
74
69
|
}
|
@@ -1,9 +1,12 @@
|
|
1
|
-
import { CellOptions } from "../
|
2
|
-
import { CrudOptions } from "../
|
1
|
+
import { CellOptions } from "../decorators/Cell";
|
2
|
+
import { CrudOptions } from "../decorators/Crud";
|
3
|
+
import { InputOptions } from "../decorators/Input";
|
3
4
|
|
4
|
-
export
|
5
|
-
resolver: any
|
6
|
-
fields: string[]
|
7
|
-
cells: CellOptions
|
8
|
-
|
5
|
+
export interface ScreenCreatorData {
|
6
|
+
resolver: any;
|
7
|
+
fields: string[];
|
8
|
+
cells: CellOptions[];
|
9
|
+
inputs: InputOptions[];
|
10
|
+
crud?: CrudOptions;
|
11
|
+
path: string;
|
9
12
|
}
|
package/src/utils/getFields.ts
CHANGED
@@ -1,21 +1,20 @@
|
|
1
1
|
import { getMetadataStorage } from "class-validator";
|
2
|
-
import { getClassCrudData } from "../
|
2
|
+
import { getClassCrudData } from "../decorators/Crud";
|
3
3
|
import { classValidatorResolver } from "@hookform/resolvers/class-validator";
|
4
|
-
import { getCellFields } from "../
|
4
|
+
import { getCellFields } from "../decorators/Cell";
|
5
5
|
import { ScreenCreatorData } from "../types/ScreenCreatorData";
|
6
|
+
import { getInputFields } from "../decorators/Input";
|
6
7
|
|
7
|
-
export function getFields<T>(entityClass: T): ScreenCreatorData
|
8
|
+
export function getFields<T>(key: string, entityClass: T): ScreenCreatorData {
|
8
9
|
const metadataStorage = getMetadataStorage();
|
9
|
-
const targetMetadata = metadataStorage.getTargetValidationMetadatas(
|
10
|
-
entityClass as any,
|
11
|
-
"",
|
12
|
-
false, false,
|
13
|
-
);
|
10
|
+
const targetMetadata = metadataStorage.getTargetValidationMetadatas(entityClass as any, "", false, false);
|
14
11
|
const crud = getClassCrudData(entityClass);
|
15
12
|
return {
|
16
13
|
resolver: classValidatorResolver(entityClass as any),
|
17
14
|
fields: Array.from(new Set(targetMetadata.map((meta) => meta.propertyName))),
|
15
|
+
inputs: getInputFields(entityClass),
|
18
16
|
cells: getCellFields(entityClass),
|
19
|
-
crud: crud
|
17
|
+
crud: crud,
|
18
|
+
path: "/" + (crud?.controller ?? key),
|
20
19
|
};
|
21
20
|
}
|
package/src/declerations/Cell.ts
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
import 'reflect-metadata';
|
2
|
-
|
3
|
-
const CELL_KEY = Symbol('cell');
|
4
|
-
|
5
|
-
export interface CellOptions<T> {
|
6
|
-
name?: string;
|
7
|
-
title?: string;
|
8
|
-
type?: 'string' | 'number' | 'date';
|
9
|
-
placeHolder?: string;
|
10
|
-
linkTo?: (item: T) => string;
|
11
|
-
}
|
12
|
-
|
13
|
-
export function Cell<T>(options?: CellOptions<T>): PropertyDecorator {
|
14
|
-
return (target, propertyKey) => {
|
15
|
-
const existingCells: string[] = Reflect.getMetadata(CELL_KEY, target) || [];
|
16
|
-
Reflect.defineMetadata(CELL_KEY, [...existingCells, propertyKey.toString()], target);
|
17
|
-
|
18
|
-
if (options) {
|
19
|
-
const keyString = `${CELL_KEY.toString()}:${propertyKey.toString()}:options`;
|
20
|
-
Reflect.defineMetadata(keyString, options, target);
|
21
|
-
}
|
22
|
-
};
|
23
|
-
}
|
24
|
-
|
25
|
-
|
26
|
-
export function getCellFields<T>(entityClass: any): CellOptions<T> [] {
|
27
|
-
const prototype = entityClass.prototype;
|
28
|
-
const cellFields: string[] = Reflect.getMetadata(CELL_KEY, prototype) || [];
|
29
|
-
return cellFields.map((field) => {
|
30
|
-
const fields = (Reflect.getMetadata(`${CELL_KEY.toString()}:${field}:options`, prototype) || {});
|
31
|
-
return {
|
32
|
-
...fields,
|
33
|
-
name: fields?.name ?? field,
|
34
|
-
};
|
35
|
-
|
36
|
-
});
|
37
|
-
}
|
@@ -1,13 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { Screen } from '../types/Screen';
|
3
|
-
import { Layout } from '../components/layout/Layout';
|
4
|
-
import { Form } from './Form';
|
5
|
-
|
6
|
-
export function ControllerCreate({ screen }: { screen: Screen }) {
|
7
|
-
|
8
|
-
return (
|
9
|
-
<Layout>
|
10
|
-
<Form screen={screen} />
|
11
|
-
</Layout>
|
12
|
-
);
|
13
|
-
}
|
@@ -1,34 +0,0 @@
|
|
1
|
-
import { Layout } from '../components/layout/Layout';
|
2
|
-
import { useParams } from 'react-router';
|
3
|
-
import React, { useEffect, useState } from 'react';
|
4
|
-
import { CrudApi } from '../api/crudApi';
|
5
|
-
import { Screen } from '../types/Screen';
|
6
|
-
|
7
|
-
export function ControllerDetails({ screen }: { screen: Screen }) {
|
8
|
-
const { id } = useParams();
|
9
|
-
const [data, setData] = useState<any>(null);
|
10
|
-
const [error, setError] = useState(null);
|
11
|
-
|
12
|
-
useEffect(() => {
|
13
|
-
if (screen.controller && id) {
|
14
|
-
CrudApi.details(screen.controller, id)
|
15
|
-
.then((res) => {
|
16
|
-
setData(res.data);
|
17
|
-
})
|
18
|
-
.catch((e: any) => {
|
19
|
-
setError(e);
|
20
|
-
console.error(e);
|
21
|
-
});
|
22
|
-
}
|
23
|
-
}, [id, screen]);
|
24
|
-
|
25
|
-
return (
|
26
|
-
<Layout>
|
27
|
-
<p
|
28
|
-
dangerouslySetInnerHTML={{
|
29
|
-
__html: JSON.stringify(data, null, ' ' + '<br/>'),
|
30
|
-
}}
|
31
|
-
/>
|
32
|
-
</Layout>
|
33
|
-
);
|
34
|
-
}
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import { Layout } from '../components/layout/Layout';
|
2
|
-
import { Form } from './Form';
|
3
|
-
import React, { useEffect, useState } from 'react';
|
4
|
-
import { Screen } from '../types/Screen';
|
5
|
-
import { useParams } from 'react-router';
|
6
|
-
import { CrudApi } from '../api/crudApi';
|
7
|
-
|
8
|
-
export function ControllerEdit({ screen }: { screen: Screen }) {
|
9
|
-
const { id } = useParams();
|
10
|
-
const [data, setData] = useState<any>(null);
|
11
|
-
const [error, setError] = useState(null);
|
12
|
-
|
13
|
-
useEffect(() => {
|
14
|
-
if (screen.controller && id) {
|
15
|
-
CrudApi.details(screen.controller, id)
|
16
|
-
.then((res) => {
|
17
|
-
setData(res.data);
|
18
|
-
})
|
19
|
-
.catch((e: any) => {
|
20
|
-
setError(e);
|
21
|
-
console.error(e);
|
22
|
-
});
|
23
|
-
}
|
24
|
-
}, [id, screen]);
|
25
|
-
|
26
|
-
return (
|
27
|
-
<Layout>
|
28
|
-
<Form data={data} screen={screen} />
|
29
|
-
</Layout>
|
30
|
-
);
|
31
|
-
}
|
@@ -1,40 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { Layout } from '../components/layout/Layout';
|
3
|
-
import { Screen } from '../types/Screen';
|
4
|
-
import { useEffect, useState } from 'react';
|
5
|
-
import { CrudApi } from '../api/crudApi';
|
6
|
-
import { Link } from 'react-router';
|
7
|
-
import { List } from '../components/list/List';
|
8
|
-
|
9
|
-
import { StoreData } from "../utils/storeData";
|
10
|
-
|
11
|
-
export function ControllerList({ screen }: { screen: Screen }) {
|
12
|
-
const [page, setPage] = useState(0);
|
13
|
-
const [data, setData] = useState<any>(null);
|
14
|
-
const [error, setError] = useState(null);
|
15
|
-
|
16
|
-
useEffect(() => {
|
17
|
-
if (screen.controller) {
|
18
|
-
CrudApi.getList(screen.controller, page)
|
19
|
-
.then((res) => {
|
20
|
-
setData(res.data);
|
21
|
-
})
|
22
|
-
.catch((e: any) => {
|
23
|
-
setError(e);
|
24
|
-
console.error(e);
|
25
|
-
});
|
26
|
-
}
|
27
|
-
}, [page, screen.controller]);
|
28
|
-
|
29
|
-
return (
|
30
|
-
<Layout>
|
31
|
-
<Link to={'/maps/create'}>Create</Link>
|
32
|
-
{error ? <p>Error {error}</p> : null}
|
33
|
-
<List
|
34
|
-
screen={screen}
|
35
|
-
cells={StoreData.screens[screen.key].cells}
|
36
|
-
data={data}
|
37
|
-
/>
|
38
|
-
</Layout>
|
39
|
-
);
|
40
|
-
}
|
package/src/screens/Form.tsx
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
import React, { useEffect } from 'react';
|
2
|
-
import { Screen } from '../types/Screen';
|
3
|
-
import { FieldErrors, useForm } from 'react-hook-form';
|
4
|
-
import { useNavigate } from 'react-router';
|
5
|
-
import { CrudApi } from '../api/crudApi';
|
6
|
-
import { StoreData } from "../utils/storeData";
|
7
|
-
|
8
|
-
export function Form({ data, screen }: { data?: any; screen: Screen }) {
|
9
|
-
const {
|
10
|
-
register,
|
11
|
-
handleSubmit,
|
12
|
-
reset,
|
13
|
-
formState: { errors },
|
14
|
-
} = useForm<any>({
|
15
|
-
resolver: StoreData.screens[screen.controller].resolver,
|
16
|
-
defaultValues: data,
|
17
|
-
});
|
18
|
-
const navigate = useNavigate();
|
19
|
-
const fields = StoreData.screens[screen.controller].fields;
|
20
|
-
useEffect(() => {
|
21
|
-
reset(data);
|
22
|
-
}, [data, reset]);
|
23
|
-
return (
|
24
|
-
<div className="form-wrapper">
|
25
|
-
<form
|
26
|
-
onSubmit={handleSubmit((dataForm) => {
|
27
|
-
if (data) {
|
28
|
-
CrudApi.edit(screen.controller, dataForm).then(() => {
|
29
|
-
navigate('/' + screen.controller, {
|
30
|
-
replace: true,
|
31
|
-
});
|
32
|
-
});
|
33
|
-
} else {
|
34
|
-
CrudApi.create(screen.controller, dataForm).then(() => {
|
35
|
-
navigate('/' + screen.controller, {
|
36
|
-
replace: true,
|
37
|
-
});
|
38
|
-
});
|
39
|
-
}
|
40
|
-
})}
|
41
|
-
>
|
42
|
-
{fields.map((field) => (
|
43
|
-
<div className="form-field" key={field}>
|
44
|
-
<label htmlFor={field}>
|
45
|
-
{field.charAt(0).toUpperCase() + field.slice(1)}
|
46
|
-
</label>
|
47
|
-
<input
|
48
|
-
type="text"
|
49
|
-
{...register(field)}
|
50
|
-
placeholder={`Enter ${field}`}
|
51
|
-
id={field}
|
52
|
-
/>
|
53
|
-
{errors[field] && (
|
54
|
-
<span className="error-message">
|
55
|
-
{/*@ts-ignore*/}
|
56
|
-
{(errors[field] as FieldErrors)?.message}
|
57
|
-
</span>
|
58
|
-
)}
|
59
|
-
</div>
|
60
|
-
))}
|
61
|
-
<button type="submit" className="submit-button">
|
62
|
-
Submit
|
63
|
-
</button>
|
64
|
-
</form>
|
65
|
-
</div>
|
66
|
-
);
|
67
|
-
}
|
@@ -1,44 +0,0 @@
|
|
1
|
-
import { Route } from 'react-router';
|
2
|
-
import { ControllerCreate } from '../screens/ControllerCreate';
|
3
|
-
import { ControllerDetails } from '../screens/ControllerDetails';
|
4
|
-
import { ControllerEdit } from '../screens/ControllerEdit';
|
5
|
-
import { ControllerList } from '../screens/ControllerList';
|
6
|
-
import { Screen } from '../types/Screen';
|
7
|
-
import React from 'react';
|
8
|
-
import { StoreData } from "./storeData";
|
9
|
-
|
10
|
-
export function getScreenForRoutes() {
|
11
|
-
const screens = Object.entries(StoreData.screens);
|
12
|
-
return (
|
13
|
-
<>
|
14
|
-
{screens.map(([key, screenData]) => {
|
15
|
-
let routePath = `/${screenData.crud.controller}`;
|
16
|
-
const screen: Screen = {
|
17
|
-
key,
|
18
|
-
controller: screenData.crud.controller,
|
19
|
-
};
|
20
|
-
return (
|
21
|
-
<React.Fragment key={'index'}>
|
22
|
-
<Route
|
23
|
-
path={routePath + '/create'}
|
24
|
-
element={<ControllerCreate screen={screen} />}
|
25
|
-
/>
|
26
|
-
<Route
|
27
|
-
path={routePath + '/details/:id'}
|
28
|
-
element={<ControllerDetails screen={screen} />}
|
29
|
-
/>
|
30
|
-
<Route
|
31
|
-
path={routePath + '/edit/:id'}
|
32
|
-
element={<ControllerEdit screen={screen} />}
|
33
|
-
/>
|
34
|
-
<Route
|
35
|
-
path={routePath}
|
36
|
-
element={<ControllerList screen={screen} />}
|
37
|
-
/>
|
38
|
-
</React.Fragment>
|
39
|
-
);
|
40
|
-
})}
|
41
|
-
<Route path="*" element={<div>404 - Not Found</div>} />
|
42
|
-
</>
|
43
|
-
);
|
44
|
-
}
|
package/src/utils/storeData.ts
DELETED
File without changes
|
File without changes
|
File without changes
|