proje-react-panel 1.0.17 → 1.1.0

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.
Files changed (113) hide show
  1. package/dist/components/Counter.d.ts +9 -0
  2. package/dist/components/DetailsPage.d.ts +7 -0
  3. package/dist/components/ErrorBoundary.d.ts +16 -0
  4. package/dist/components/ErrorComponent.d.ts +4 -0
  5. package/dist/components/LoadingScreen.d.ts +2 -0
  6. package/dist/components/Login.d.ts +13 -0
  7. package/dist/components/Panel.d.ts +1 -3
  8. package/dist/components/components/Checkbox.d.ts +3 -2
  9. package/dist/components/components/FormField.d.ts +5 -1
  10. package/dist/components/components/InnerForm.d.ts +8 -3
  11. package/dist/components/components/Label.d.ts +3 -2
  12. package/dist/components/components/Uploader.d.ts +8 -0
  13. package/dist/components/components/index.d.ts +1 -1
  14. package/dist/components/components/list/ListPage.d.ts +1 -1
  15. package/dist/components/form/Checkbox.d.ts +7 -0
  16. package/dist/components/form/FormField.d.ts +17 -0
  17. package/dist/components/form/FormPage.d.ts +6 -0
  18. package/dist/components/form/InnerForm.d.ts +10 -0
  19. package/dist/components/form/Label.d.ts +9 -0
  20. package/dist/components/form/Uploader.d.ts +8 -0
  21. package/dist/components/layout/Layout.d.ts +3 -4
  22. package/dist/components/layout/SideBar.d.ts +2 -3
  23. package/dist/components/list/CellField.d.ts +9 -0
  24. package/dist/components/list/Datagrid.d.ts +6 -8
  25. package/dist/components/list/FilterPopup.d.ts +7 -5
  26. package/dist/components/list/ListHeader.d.ts +11 -0
  27. package/dist/components/list/ListPage.d.ts +6 -0
  28. package/dist/components/pages/FormPage.d.ts +8 -2
  29. package/dist/decorators/details/Details.d.ts +11 -0
  30. package/dist/decorators/details/DetailsItem.d.ts +11 -0
  31. package/dist/decorators/details/getDetailsPageMeta.d.ts +8 -0
  32. package/dist/decorators/form/Form.d.ts +21 -5
  33. package/dist/decorators/form/Input.d.ts +7 -3
  34. package/dist/decorators/form/getFormPageMeta.d.ts +10 -0
  35. package/dist/decorators/list/Cell.d.ts +13 -1
  36. package/dist/decorators/list/List.d.ts +18 -1
  37. package/dist/decorators/list/cells/ImageCell.d.ts +9 -0
  38. package/dist/decorators/list/getListPageMeta.d.ts +8 -0
  39. package/dist/index.cjs.js +1 -1
  40. package/dist/index.d.ts +12 -17
  41. package/dist/index.esm.js +1 -1
  42. package/dist/initPanel.d.ts +1 -1
  43. package/dist/store/store.d.ts +0 -3
  44. package/dist/types/AnyClass.d.ts +2 -1
  45. package/dist/types/getDetailsData.d.ts +1 -0
  46. package/dist/types/initPanelOptions.d.ts +0 -1
  47. package/package.json +1 -1
  48. package/src/assets/icons/svg/check.svg +4 -0
  49. package/src/assets/icons/svg/cross.svg +4 -0
  50. package/src/components/DetailsPage.tsx +55 -0
  51. package/src/components/{components/ErrorComponent.tsx → ErrorComponent.tsx} +1 -1
  52. package/src/components/{pages/Login.tsx → Login.tsx} +2 -2
  53. package/src/components/Panel.tsx +4 -5
  54. package/src/components/form/Checkbox.tsx +21 -0
  55. package/src/components/{components → form}/FormField.tsx +30 -22
  56. package/src/components/form/FormPage.tsx +32 -0
  57. package/src/components/form/InnerForm.tsx +85 -0
  58. package/src/components/form/Label.tsx +21 -0
  59. package/src/components/form/Uploader.tsx +66 -0
  60. package/src/components/layout/Layout.tsx +29 -32
  61. package/src/components/layout/SideBar.tsx +4 -13
  62. package/src/components/list/CellField.tsx +63 -0
  63. package/src/components/list/Datagrid.tsx +106 -0
  64. package/src/components/{components/list → list}/FilterPopup.tsx +13 -9
  65. package/src/components/list/ListHeader.tsx +47 -0
  66. package/src/components/{components/list → list}/ListPage.tsx +20 -82
  67. package/src/decorators/details/Details.ts +31 -0
  68. package/src/decorators/details/DetailsItem.ts +40 -0
  69. package/src/decorators/details/getDetailsPageMeta.ts +15 -0
  70. package/src/decorators/form/Form.ts +37 -12
  71. package/src/decorators/form/Input.ts +11 -4
  72. package/src/decorators/form/getFormPageMeta.ts +21 -0
  73. package/src/decorators/list/Cell.ts +41 -1
  74. package/src/decorators/list/List.ts +30 -6
  75. package/src/decorators/list/cells/ImageCell.ts +17 -0
  76. package/src/decorators/list/getListPageMeta.ts +16 -0
  77. package/src/index.ts +32 -24
  78. package/src/initPanel.ts +1 -4
  79. package/src/store/store.ts +0 -5
  80. package/src/styles/components/checkbox.scss +42 -0
  81. package/src/styles/components/uploader.scss +86 -0
  82. package/src/styles/details.scss +62 -0
  83. package/src/styles/form.scss +9 -11
  84. package/src/styles/index.scss +26 -12
  85. package/src/styles/list.scss +3 -1
  86. package/src/types/AnyClass.ts +2 -1
  87. package/src/types/initPanelOptions.ts +1 -3
  88. package/src/components/components/Checkbox.tsx +0 -9
  89. package/src/components/components/ImageUploader.tsx +0 -301
  90. package/src/components/components/InnerForm.tsx +0 -74
  91. package/src/components/components/Label.tsx +0 -15
  92. package/src/components/components/index.ts +0 -8
  93. package/src/components/components/list/Datagrid.tsx +0 -127
  94. package/src/components/pages/ControllerDetails.tsx +0 -37
  95. package/src/components/pages/FormPage.tsx +0 -34
  96. package/src/decorators/Crud.ts +0 -20
  97. package/src/decorators/form/FormOptions.ts +0 -8
  98. package/src/decorators/form/getFormFields.ts +0 -13
  99. package/src/decorators/list/GetCellFields.ts +0 -13
  100. package/src/decorators/list/ImageCell.ts +0 -13
  101. package/src/decorators/list/ListData.ts +0 -7
  102. package/src/decorators/list/getListFields.ts +0 -10
  103. package/src/styles/image-uploader.scss +0 -94
  104. package/src/types/Screen.ts +0 -4
  105. package/src/types/ScreenCreatorData.ts +0 -14
  106. package/src/utils/createScreens.ts +0 -5
  107. package/src/utils/getFields.ts +0 -22
  108. /package/src/components/{components/Counter.tsx → Counter.tsx} +0 -0
  109. /package/src/components/{components/ErrorBoundary.tsx → ErrorBoundary.tsx} +0 -0
  110. /package/src/components/{components/LoadingScreen.tsx → LoadingScreen.tsx} +0 -0
  111. /package/src/components/{components/list → list}/EmptyList.tsx +0 -0
  112. /package/src/components/{components/list → list}/Pagination.tsx +0 -0
  113. /package/src/components/{components/list → list}/index.ts +0 -0
@@ -1,15 +0,0 @@
1
- import React from 'react';
2
-
3
- interface LabelProps {
4
- htmlFor: string;
5
- label?: string;
6
- fieldName: string;
7
- }
8
-
9
- export function Label({ htmlFor, label, fieldName }: LabelProps) {
10
- return (
11
- <label htmlFor={htmlFor}>
12
- {label ?? fieldName.charAt(0).toUpperCase() + fieldName.slice(1)}
13
- </label>
14
- );
15
- }
@@ -1,8 +0,0 @@
1
- export { InnerForm } from './InnerForm';
2
- export { FormField } from './FormField';
3
- export { LoadingScreen } from './LoadingScreen';
4
- export { Counter } from './Counter';
5
- export { ImageUploader } from './ImageUploader';
6
- export { ErrorComponent } from './ErrorComponent';
7
- export { Label } from './Label';
8
- export { ErrorBoundary } from './ErrorBoundary';
@@ -1,127 +0,0 @@
1
- import React from 'react';
2
- import { CellOptions } from '../../../decorators/list/Cell';
3
- import { Link } from 'react-router';
4
- import { useAppStore } from '../../../store/store';
5
- import { ImageCellOptions } from '../../../decorators/list/ImageCell';
6
- import { ListData } from '../../../decorators/list/ListData';
7
- import { EmptyList } from './EmptyList';
8
- import SearchIcon from '../../../assets/icons/svg/search.svg';
9
- import PencilIcon from '../../../assets/icons/svg/pencil.svg';
10
- import TrashIcon from '../../../assets/icons/svg/trash.svg';
11
-
12
- interface DatagridProps<T> {
13
- data: T[];
14
- listData: ListData<T>;
15
- onRemoveItem?: (item: T) => Promise<void>;
16
- }
17
-
18
- export function Datagrid<T>({ data, listData, onRemoveItem }: DatagridProps<T>) {
19
- const cells = listData.cells;
20
- const listGeneralCells =
21
- typeof listData.list?.cells === 'function'
22
- ? listData.list?.cells?.(data[0])
23
- : listData.list?.cells;
24
-
25
- return (
26
- <div className="datagrid">
27
- {!data || data.length === 0 ? (
28
- <EmptyList />
29
- ) : (
30
- <table className="datagrid-table">
31
- <thead>
32
- <tr>
33
- {cells.map(cellOptions => (
34
- <th key={cellOptions.name}>{cellOptions.title ?? cellOptions.name}</th>
35
- ))}
36
- {listGeneralCells?.details && <th>Details</th>}
37
- {listGeneralCells?.edit && <th>Edit</th>}
38
- {listGeneralCells?.delete && <th>Delete</th>}
39
- </tr>
40
- </thead>
41
- <tbody>
42
- {data.map((item, index) => (
43
- <tr key={index}>
44
- {cells.map(cellOptions => {
45
- // @ts-ignore
46
- const value = item[cellOptions.name];
47
- let render = value ?? '-'; // Default value if the field is undefined or null
48
-
49
- switch (cellOptions.type) {
50
- case 'date':
51
- if (value) {
52
- const date = new Date(value);
53
- render = `${date.getDate().toString().padStart(2, '0')}/${(
54
- date.getMonth() + 1
55
- )
56
- .toString()
57
- .padStart(
58
- 2,
59
- '0'
60
- )}/${date.getFullYear()} ${date.getHours().toString().padStart(2, '0')}:${date
61
- .getMinutes()
62
- .toString()
63
- .padStart(2, '0')}`;
64
- }
65
- break;
66
-
67
- case 'image': {
68
- const imageCellOptions = cellOptions as ImageCellOptions;
69
- render = (
70
- <img
71
- width={100}
72
- height={100}
73
- src={imageCellOptions.baseUrl + value}
74
- style={{ objectFit: 'contain' }}
75
- />
76
- );
77
- break;
78
- }
79
- case 'string':
80
- default:
81
- render = value ? value.toString() : (cellOptions?.placeHolder ?? '-'); // Handles string type or default fallback
82
- break;
83
- }
84
- /*
85
- if (cellOptions.linkTo) {
86
- render = <Link to={cellOptions.linkTo(item)}>{formattedValue}</Link>;
87
- }
88
- */
89
- return <td key={cellOptions.name}>{render}</td>;
90
- })}
91
- {listGeneralCells?.details && (
92
- <td>
93
- <Link to={listGeneralCells.details.path} className="util-cell-link">
94
- <SearchIcon className="icon icon-search" />
95
- <span className="util-cell-label">{listGeneralCells.details.label}</span>
96
- </Link>
97
- </td>
98
- )}
99
- {listGeneralCells?.edit && (
100
- <td>
101
- <Link to={listGeneralCells.edit.path} className="util-cell-link">
102
- <PencilIcon className="icon icon-pencil" />
103
- <span className="util-cell-label">{listGeneralCells.edit.label}</span>
104
- </Link>
105
- </td>
106
- )}
107
- {listGeneralCells?.delete && (
108
- <td>
109
- <a
110
- onClick={() => {
111
- onRemoveItem?.(item);
112
- }}
113
- className="util-cell-link"
114
- >
115
- <TrashIcon className="icon icon-trash" />
116
- <span className="util-cell-label">{listGeneralCells.delete.label}</span>
117
- </a>
118
- </td>
119
- )}
120
- </tr>
121
- ))}
122
- </tbody>
123
- </table>
124
- )}
125
- </div>
126
- );
127
- }
@@ -1,37 +0,0 @@
1
- import { useParams } from 'react-router';
2
- import React, { useEffect, useState } from 'react';
3
- import { Screen } from '../../types/Screen';
4
- import { ErrorComponent } from '../components/ErrorComponent';
5
-
6
- export function ControllerDetails({ screen }: { screen: Screen }) {
7
- const { id } = useParams();
8
- const [data, setData] = useState<any>(null);
9
- const [error, setError] = useState(null);
10
-
11
- useEffect(() => {
12
- if (screen.controller && id) {
13
- /*
14
- CrudApi.details({ ...fetchSettings, token }, screen.controller, id)
15
- .then(res => {
16
- setData(res);
17
- })
18
- .catch((e: any) => {
19
- setError(e);
20
- console.error(e);
21
- });
22
- */
23
- }
24
- }, [id, screen]);
25
-
26
- if (error) {
27
- return <ErrorComponent error={error} />;
28
- }
29
-
30
- return (
31
- <p
32
- dangerouslySetInnerHTML={{
33
- __html: JSON.stringify(data, null, ' ' + '<br/>'),
34
- }}
35
- />
36
- );
37
- }
@@ -1,34 +0,0 @@
1
- import React, { useMemo } from 'react';
2
- import { InnerForm } from '../components';
3
- import { AnyClass } from '../../types/AnyClass';
4
- import { getFormFields } from '../../decorators/form/getFormFields';
5
-
6
- export type GetDetailsDataFN<T> = (param: Record<string, string>) => Promise<T>;
7
- export type OnSubmitFN<T> = (data: T) => Promise<T>;
8
-
9
- export interface FormPageProps<T extends AnyClass> {
10
- model: T;
11
- getDetailsData?: GetDetailsDataFN<T>;
12
- redirect?: string;
13
- onSubmit: OnSubmitFN<T>;
14
- redirectBackOnSuccess?: boolean;
15
- }
16
-
17
- export function FormPage<T extends AnyClass>({
18
- model,
19
- getDetailsData,
20
- onSubmit,
21
- redirect,
22
- redirectBackOnSuccess = true,
23
- ...rest
24
- }: FormPageProps<T>) {
25
- const formOptions = useMemo(() => getFormFields(model), [model]);
26
- return (
27
- <InnerForm
28
- getDetailsData={getDetailsData}
29
- onSubmit={onSubmit}
30
- formOptions={formOptions}
31
- redirectBackOnSuccess={redirectBackOnSuccess}
32
- />
33
- );
34
- }
@@ -1,20 +0,0 @@
1
- import 'reflect-metadata';
2
-
3
- const CRUD_KEY = 'Crud'; // Changed from Symbol to string
4
-
5
- export interface CrudOptions {
6
- controller: string;
7
- }
8
-
9
- export function Crud(options?: CrudOptions): ClassDecorator {
10
- return (target: Function) => {
11
- if (options) {
12
- Reflect.defineMetadata(CRUD_KEY, options, target);
13
- }
14
- };
15
- }
16
-
17
-
18
- export function getClassCrudData(entityClass: any): CrudOptions | undefined {
19
- return Reflect.getMetadata(CRUD_KEY, entityClass);
20
- }
@@ -1,8 +0,0 @@
1
- import { FormConfiguration } from "./Form";
2
- import { InputOptions } from "./Input";
3
-
4
- export interface FormOptions {
5
- resolver: any; //TODO: type
6
- form?: FormConfiguration;
7
- inputs?: InputOptions[];
8
- }
@@ -1,13 +0,0 @@
1
- import { AnyClass } from "../../types/AnyClass";
2
- import { FormOptions } from "./FormOptions";
3
- import { getInputFields } from "./Input";
4
- import { getFormConfiguration } from "./Form";
5
- import { classValidatorResolver } from "@hookform/resolvers/class-validator";
6
-
7
- export function getFormFields<T extends AnyClass>(entityClass: T): FormOptions {
8
- return {
9
- resolver: classValidatorResolver(entityClass as any),
10
- form: getFormConfiguration(entityClass),
11
- inputs: getInputFields<T>(entityClass),
12
- };
13
- }
@@ -1,13 +0,0 @@
1
- import { CELL_KEY, CellOptions } from "./Cell";
2
-
3
- export function getCellFields(entityClass: any): CellOptions[] {
4
- const prototype = entityClass.prototype;
5
- const cellFields: string[] = Reflect.getMetadata(CELL_KEY, prototype) || [];
6
- return cellFields.map((field) => {
7
- const fields = Reflect.getMetadata(`${CELL_KEY.toString()}:${field}:options`, prototype) || {};
8
- return {
9
- ...fields,
10
- name: fields?.name ?? field,
11
- };
12
- });
13
- }
@@ -1,13 +0,0 @@
1
- import "reflect-metadata";
2
- import { Cell, CellOptions } from "./Cell";
3
-
4
- export interface ImageCellOptions extends CellOptions {
5
- baseUrl: string;
6
- }
7
-
8
- export function ImageCell(options?: ImageCellOptions): PropertyDecorator {
9
- return Cell({
10
- ...options,
11
- type: "image",
12
- });
13
- }
@@ -1,7 +0,0 @@
1
- import { ListOptions } from './List';
2
- import { CellOptions } from './Cell';
3
-
4
- export interface ListData<T> {
5
- list?: ListOptions<T>;
6
- cells: CellOptions[];
7
- }
@@ -1,10 +0,0 @@
1
- import { getClassListData } from './List';
2
- import { getCellFields } from './GetCellFields';
3
- import { ListData } from './ListData';
4
-
5
- export function getListFields<T>(entityClass: T): ListData<T> {
6
- return {
7
- list: getClassListData(entityClass),
8
- cells: getCellFields(entityClass),
9
- };
10
- }
@@ -1,94 +0,0 @@
1
- .multi-image {
2
-
3
- &.hover {
4
- .container {
5
- border: 2px solid rgb(160,160,160);
6
- background-color: rgb(250,250,250);
7
-
8
- .plus {
9
- background-color: rgb(240,240,240);
10
- }
11
- }
12
- }
13
-
14
- &.after {
15
- .container {
16
- button.trash {display:block;
17
- }
18
- }
19
- }
20
-
21
- .container {
22
- width: 100%;
23
- display: grid;
24
- grid-column-gap: 50px;
25
- grid-template-columns: 1fr 1fr 1fr;
26
- align-items: center;
27
- border: 2px dashed rgb(160,160,160);
28
- background-color: white;
29
- min-height: 200px;
30
- padding: 10px;
31
- position:relative;
32
-
33
- button.trash {
34
- display:none;
35
- position: absolute;
36
- z-index: 1000;
37
- right: 0;
38
- top: 0;
39
- background: none;
40
- border: none;
41
- cursor: pointer;
42
- color: rgb(50,50,50);
43
- }
44
-
45
- > div {
46
- text-align: center;
47
- }
48
-
49
- .image-container {
50
- border: 1px solid rgb(245,245,255);
51
- padding: 5px;
52
- background-color: white;
53
- position: relative;
54
-
55
- .image.removed {
56
- opacity: 0.3;
57
- }
58
-
59
- button {
60
- position: absolute;
61
- right: 0;
62
- top: 0;
63
- background: none;
64
- border: none;
65
- cursor: pointer;
66
-
67
- &.remove {
68
- color: red;
69
- }
70
- }
71
- }
72
-
73
- .plus {
74
- background-color: rgb(245,245,245);
75
- position: relative;
76
- height: 180px;
77
- width: 200px;
78
-
79
- span {
80
- display: block;
81
- position: absolute;
82
- top: 50%;
83
- left: 50%;
84
- transform: translate(-50%,-50%);
85
-
86
- > * {
87
- display: block;
88
- margin: 0 auto;
89
- text-align: center;
90
- }
91
- }
92
- }
93
- }
94
- }
@@ -1,4 +0,0 @@
1
- export interface Screen {
2
- key: string,
3
- controller: string,
4
- }
@@ -1,14 +0,0 @@
1
- import { CellOptions } from '../decorators/list/Cell';
2
- import { CrudOptions } from '../decorators/Crud';
3
- import { InputOptions } from '../decorators/form/Input';
4
- import { ListOptions } from '../decorators/list/List';
5
- //TODO: remove
6
- export interface ScreenCreatorData {
7
- resolver: any;
8
- fields: string[];
9
- inputs: InputOptions[];
10
- crud?: CrudOptions;
11
- path: string;
12
- list?: ListOptions<any>;
13
- cells: CellOptions[];
14
- }
@@ -1,5 +0,0 @@
1
- import { useAppStore } from "../store/store";
2
-
3
- export function createScreens(screens: Record<string, any>) {
4
- useAppStore.setState({ screens });
5
- }
@@ -1,22 +0,0 @@
1
- import { getMetadataStorage } from "class-validator";
2
- import { classValidatorResolver } from "@hookform/resolvers/class-validator";
3
- import { ScreenCreatorData } from "../types/ScreenCreatorData";
4
- import { getInputFields } from "../decorators/form/Input";
5
- import { getClassListData } from "../decorators/list/List";
6
- import { getCellFields } from "../decorators/list/GetCellFields";
7
- import { AnyClass } from "../types/AnyClass";
8
-
9
- export function getFields<T extends AnyClass>(key: string, entityClass: T): ScreenCreatorData {
10
- const metadataStorage = getMetadataStorage();
11
- const targetMetadata = metadataStorage.getTargetValidationMetadatas(entityClass as any, "", false, false);
12
- const listData = getClassListData(entityClass);
13
- return {
14
- resolver: classValidatorResolver(entityClass as any),
15
- cells: getCellFields(entityClass),
16
- list: listData,
17
- fields: Array.from(new Set(targetMetadata.map((meta) => meta.propertyName))),
18
- inputs: getInputFields<T>(entityClass),
19
- crud: { controller: "" },
20
- path: "/" + key,
21
- };
22
- }