@abidibo/react-cam-roi 0.2.1 → 0.2.3

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 (100) hide show
  1. package/dist/Components/BoolField/BoolField.module.css +60 -0
  2. package/dist/Components/BoolField/index.d.ts +5 -0
  3. package/dist/Components/BoolField/index.js +13 -0
  4. package/dist/Components/Button/Button.module.css +29 -0
  5. package/dist/Components/Button/index.d.ts +8 -0
  6. package/dist/Components/Button/index.js +15 -0
  7. package/dist/Components/EnumField/EnumField.module.css +61 -0
  8. package/dist/Components/EnumField/index.d.ts +10 -0
  9. package/dist/Components/EnumField/index.js +16 -0
  10. package/dist/Components/IconButton/IconButton.module.css +20 -0
  11. package/dist/Components/IconButton/index.d.ts +7 -0
  12. package/dist/Components/IconButton/index.js +10 -0
  13. package/dist/Components/Loader/Loader.module.css +25 -0
  14. package/dist/Components/Loader/index.d.ts +1 -0
  15. package/dist/Components/Loader/index.js +9 -0
  16. package/dist/Components/Modal/Modal.module.css +92 -0
  17. package/dist/Components/Modal/index.d.ts +10 -0
  18. package/dist/Components/Modal/index.js +16 -0
  19. package/dist/Components/NumberField/NumberField.module.css +60 -0
  20. package/dist/Components/NumberField/index.d.ts +3 -0
  21. package/dist/Components/NumberField/index.js +13 -0
  22. package/dist/Components/RoiEditor/Canvas.d.ts +14 -0
  23. package/dist/Components/RoiEditor/Canvas.js +30 -0
  24. package/dist/Components/RoiEditor/ColorPicker.d.ts +5 -0
  25. package/dist/Components/RoiEditor/ColorPicker.js +12 -0
  26. package/dist/Components/RoiEditor/ColorPicker.module.css +17 -0
  27. package/dist/Components/RoiEditor/Header.d.ts +2 -0
  28. package/dist/Components/RoiEditor/Header.js +14 -0
  29. package/dist/Components/RoiEditor/Header.module.css +26 -0
  30. package/dist/Components/RoiEditor/Hooks.d.ts +38 -0
  31. package/dist/Components/RoiEditor/Hooks.js +328 -0
  32. package/dist/Components/RoiEditor/ParameterField.d.ts +9 -0
  33. package/dist/Components/RoiEditor/ParameterField.js +27 -0
  34. package/dist/Components/RoiEditor/ParametersModalForm/ParametersModalForm.module.css +5 -0
  35. package/dist/Components/RoiEditor/ParametersModalForm/index.d.ts +17 -0
  36. package/dist/Components/RoiEditor/ParametersModalForm/index.js +42 -0
  37. package/dist/Components/RoiEditor/Polygon.d.ts +18 -0
  38. package/dist/Components/RoiEditor/Polygon.js +77 -0
  39. package/dist/Components/RoiEditor/Polyline.d.ts +28 -0
  40. package/dist/Components/RoiEditor/Polyline.js +75 -0
  41. package/dist/Components/RoiEditor/Rectangle.d.ts +21 -0
  42. package/dist/Components/RoiEditor/Rectangle.js +73 -0
  43. package/dist/Components/RoiEditor/RoiEditor.module.css +5 -0
  44. package/dist/Components/RoiEditor/RoisInfo.d.ts +2 -0
  45. package/dist/Components/RoiEditor/RoisInfo.js +43 -0
  46. package/dist/Components/RoiEditor/ShapesList.d.ts +2 -0
  47. package/dist/Components/RoiEditor/ShapesList.js +77 -0
  48. package/dist/Components/RoiEditor/ShapesList.module.css +71 -0
  49. package/dist/Components/RoiEditor/Toolbar.d.ts +2 -0
  50. package/dist/Components/RoiEditor/Toolbar.js +27 -0
  51. package/dist/Components/RoiEditor/Toolbar.module.css +41 -0
  52. package/dist/Components/RoiEditor/TopBar.d.ts +2 -0
  53. package/dist/Components/RoiEditor/TopBar.js +21 -0
  54. package/dist/Components/RoiEditor/TopBar.module.css +7 -0
  55. package/dist/Components/RoiEditor/Types.d.ts +128 -0
  56. package/dist/Components/RoiEditor/Types.js +23 -0
  57. package/dist/Components/RoiEditor/Utils.d.ts +25 -0
  58. package/dist/Components/RoiEditor/Utils.js +161 -0
  59. package/dist/Components/RoiEditor/index.d.ts +12 -0
  60. package/dist/Components/RoiEditor/index.js +99 -0
  61. package/dist/Components/RoleField.d.ts +7 -0
  62. package/dist/Components/RoleField.js +49 -0
  63. package/dist/Components/TextField/TextField.module.css +61 -0
  64. package/dist/Components/TextField/index.d.ts +6 -0
  65. package/dist/Components/TextField/index.js +13 -0
  66. package/dist/Components/Typography/index.d.ts +9 -0
  67. package/dist/Components/Typography/index.js +6 -0
  68. package/dist/Icons/AnnotateIcon.d.ts +6 -0
  69. package/dist/Icons/AnnotateIcon.js +5 -0
  70. package/dist/Icons/CloseIcon.d.ts +6 -0
  71. package/dist/Icons/CloseIcon.js +5 -0
  72. package/dist/Icons/CopyIcon.d.ts +6 -0
  73. package/dist/Icons/CopyIcon.js +5 -0
  74. package/dist/Icons/DeleteIcon.d.ts +6 -0
  75. package/dist/Icons/DeleteIcon.js +5 -0
  76. package/dist/Icons/EditIcon.d.ts +6 -0
  77. package/dist/Icons/EditIcon.js +5 -0
  78. package/dist/Icons/PointerIcon.d.ts +6 -0
  79. package/dist/Icons/PointerIcon.js +5 -0
  80. package/dist/Icons/PolygonIcon.d.ts +6 -0
  81. package/dist/Icons/PolygonIcon.js +5 -0
  82. package/dist/Icons/PolylineIcon.d.ts +6 -0
  83. package/dist/Icons/PolylineIcon.js +5 -0
  84. package/dist/Icons/RectangleIcon.d.ts +6 -0
  85. package/dist/Icons/RectangleIcon.js +5 -0
  86. package/dist/Icons/SaveIcon.d.ts +6 -0
  87. package/dist/Icons/SaveIcon.js +5 -0
  88. package/dist/Providers/EditorProvider.d.ts +26 -0
  89. package/dist/Providers/EditorProvider.js +29 -0
  90. package/dist/Providers/UiProvider.d.ts +82 -0
  91. package/dist/Providers/UiProvider.js +104 -0
  92. package/dist/Types.d.ts +10 -0
  93. package/dist/Types.js +1 -0
  94. package/dist/Utils/Dispatcher.d.ts +16 -0
  95. package/dist/Utils/Dispatcher.js +65 -0
  96. package/dist/Utils/index.d.ts +6 -0
  97. package/dist/Utils/index.js +16 -0
  98. package/dist/index.d.ts +4 -0
  99. package/dist/index.js +4 -0
  100. package/package.json +1 -1
@@ -0,0 +1,38 @@
1
+ import * as fabric from 'fabric';
2
+ import { Metadata, Output, OutputParameter, Shape, ShapeType } from './Types';
3
+ export declare const useImageSize: (imageUrl: string) => {
4
+ imageSize: {
5
+ width: number;
6
+ height: number;
7
+ };
8
+ isReady: boolean;
9
+ };
10
+ export declare const useCanvasSize: (imageUrl: string) => {
11
+ imageSize: {
12
+ width: number;
13
+ height: number;
14
+ };
15
+ canvasSize: {
16
+ width: number;
17
+ height: number;
18
+ };
19
+ wrapperRef: import("react").RefObject<HTMLDivElement>;
20
+ isReady: boolean;
21
+ };
22
+ export declare const initCanvasData: (canvasRef: React.MutableRefObject<fabric.Canvas | null>, imageSize: {
23
+ width: number;
24
+ height: number;
25
+ }, addShapes: (shapes: {
26
+ id: string;
27
+ type: ShapeType;
28
+ shape: Shape;
29
+ }[]) => void, metadata: Metadata, setMetadata: (v: Metadata) => void, initialData?: Output, enableLogs?: boolean) => void;
30
+ export declare const useTool: (canvas: fabric.Canvas | null) => void;
31
+ export declare const useDispatcherEvents: (canvas: fabric.Canvas | null) => void;
32
+ export declare const useParametersForm: (parameters: OutputParameter[]) => {
33
+ fields: Record<string, unknown>;
34
+ setField: <T>(key: string) => (value: T) => void;
35
+ setFields: import("react").Dispatch<import("react").SetStateAction<Record<string, unknown>>>;
36
+ errors: Record<string, string>;
37
+ setErrors: import("react").Dispatch<import("react").SetStateAction<Record<string, string>>>;
38
+ };
@@ -0,0 +1,328 @@
1
+ import * as fabric from 'fabric';
2
+ import { useCallback, useContext, useEffect, useRef, useState } from 'react';
3
+ import { useEditorContext } from '../../Providers/EditorProvider';
4
+ import { UiContext } from '../../Providers/UiProvider';
5
+ import { log, perc2Abs } from '../../Utils';
6
+ import Dispatcher from '../../Utils/Dispatcher';
7
+ import { copyPolygon, handleDoubleClickPolygon, handleMouseDownPolygon, handleMouseMovePolygon } from './Polygon';
8
+ import { copyPolyline, handleDoubleClickPolyline, handleMouseDownPolyline, handleMouseMovePolyline } from './Polyline';
9
+ import { copyRectangle, handleMouseDownRect, handleMouseMoveRect, handleMouseUpRect } from './Rectangle';
10
+ import { canDrawShape } from './Utils';
11
+ export const useImageSize = (imageUrl) => {
12
+ const [imageSize, setImageSize] = useState({ width: 0, height: 0 });
13
+ useEffect(() => {
14
+ const image = new Image();
15
+ image.src = imageUrl;
16
+ image.onload = () => {
17
+ setImageSize({ width: image.width, height: image.height });
18
+ };
19
+ }, [imageUrl]);
20
+ return { imageSize, isReady: imageSize.width > 0 };
21
+ };
22
+ export const useCanvasSize = (imageUrl) => {
23
+ console.log('before wrapper ref');
24
+ const wrapperRef = useRef(null);
25
+ console.log('after wrapper ref');
26
+ const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 });
27
+ const { imageSize, isReady } = useImageSize(imageUrl);
28
+ useEffect(() => {
29
+ if (wrapperRef.current) {
30
+ const update = () => {
31
+ const availableWidth = wrapperRef.current.offsetWidth;
32
+ if (availableWidth < imageSize.width) {
33
+ setCanvasSize({
34
+ width: availableWidth,
35
+ height: availableWidth * (imageSize.height / imageSize.width),
36
+ });
37
+ }
38
+ else {
39
+ setCanvasSize({
40
+ width: imageSize.width,
41
+ height: imageSize.height,
42
+ });
43
+ }
44
+ };
45
+ if (imageSize.width > 0 && wrapperRef.current) {
46
+ update();
47
+ }
48
+ }
49
+ }, [imageSize, wrapperRef.current]); // eslint-disable-line
50
+ return { imageSize, canvasSize, wrapperRef, isReady };
51
+ };
52
+ export const initCanvasData = (canvasRef, imageSize, addShapes, metadata, setMetadata, initialData, enableLogs) => {
53
+ log('info', enableLogs !== null && enableLogs !== void 0 ? enableLogs : false, 'Loading initial shapes data', initialData, canvasRef.current);
54
+ if (initialData === null || initialData === void 0 ? void 0 : initialData.rois) {
55
+ const m = [];
56
+ const s = [];
57
+ initialData.rois.forEach((r) => {
58
+ var _a, _b, _c;
59
+ log('info', enableLogs !== null && enableLogs !== void 0 ? enableLogs : false, 'Loading initial shape', r);
60
+ const id = r.id;
61
+ let shape;
62
+ switch (r.type) {
63
+ case "rect" /* ToolEnum.Rectangle */:
64
+ shape = new fabric.Rect({
65
+ left: perc2Abs(r.shape.left, imageSize.width),
66
+ top: perc2Abs(r.shape.top, imageSize.height),
67
+ originX: 'left',
68
+ originY: 'top',
69
+ width: perc2Abs(r.shape.width, imageSize.width),
70
+ height: perc2Abs(r.shape.height, imageSize.height),
71
+ fill: 'transparent',
72
+ stroke: r.shape.color,
73
+ strokeWidth: 2,
74
+ strokeUniform: true,
75
+ selectable: false,
76
+ hasControls: true,
77
+ hoverCursor: 'default',
78
+ id,
79
+ });
80
+ (_a = canvasRef.current) === null || _a === void 0 ? void 0 : _a.add(shape);
81
+ break;
82
+ case "polygon" /* ToolEnum.Polygon */:
83
+ shape = new fabric.Polygon(r.shape.points.map(({ x, y }) => ({
84
+ x: perc2Abs(x, imageSize.width),
85
+ y: perc2Abs(y, imageSize.height),
86
+ })), {
87
+ top: perc2Abs(r.shape.top, imageSize.height),
88
+ left: perc2Abs(r.shape.left, imageSize.width),
89
+ fill: 'transparent',
90
+ stroke: r.shape.color,
91
+ strokeWidth: 2,
92
+ selectable: false,
93
+ hasControls: true,
94
+ hoverCursor: 'default',
95
+ // @ts-expect-error id is not included in types but the property is added and it works
96
+ id,
97
+ });
98
+ (_b = canvasRef.current) === null || _b === void 0 ? void 0 : _b.add(shape);
99
+ break;
100
+ case "polyline" /* ToolEnum.Polyline */:
101
+ shape = new fabric.Polyline(r.shape.points.map(({ x, y }) => ({
102
+ x: perc2Abs(x, imageSize.width),
103
+ y: perc2Abs(y, imageSize.height),
104
+ })), {
105
+ top: perc2Abs(r.shape.top, imageSize.height),
106
+ left: perc2Abs(r.shape.left, imageSize.width),
107
+ fill: 'transparent',
108
+ stroke: r.shape.color,
109
+ strokeWidth: 2,
110
+ selectable: false,
111
+ hasControls: true,
112
+ hoverCursor: 'default',
113
+ id,
114
+ });
115
+ (_c = canvasRef.current) === null || _c === void 0 ? void 0 : _c.add(shape);
116
+ break;
117
+ }
118
+ m.push({ id, parameters: r.parameters, name: r.name, role: r.role });
119
+ s.push({ id, type: r.type, shape });
120
+ });
121
+ addShapes(s);
122
+ setMetadata(Object.assign(Object.assign({}, metadata), { rois: m }));
123
+ }
124
+ };
125
+ export const useTool = (canvas) => {
126
+ const { editorId, configuration, activeTool, activeColor, shapes, addShape } = useEditorContext();
127
+ const { notify, strings } = useContext(UiContext);
128
+ const [isDrawing, setIsDrawing] = useState(false);
129
+ const [shape, setShape] = useState(null);
130
+ const [originX, setOriginX] = useState(0);
131
+ const [originY, setOriginY] = useState(0);
132
+ const [startPos] = useState({ x: 0, y: 0 });
133
+ const [points, setPoints] = useState([]);
134
+ const [lines, setLines] = useState([]);
135
+ // Handler for object selected event to update style settings
136
+ const handleObjectSelected = useCallback((event) => {
137
+ var _a;
138
+ Dispatcher.emit(`canvas:${editorId}:shapeSelected`, (_a = event.selected) !== null && _a !== void 0 ? _a : null);
139
+ }, [editorId]);
140
+ // Handler for selection cleared event to reset selected shapes state
141
+ const handleSelectionCleared = useCallback(() => {
142
+ Dispatcher.emit(`canvas:${editorId}:shapeSelected`, null);
143
+ }, [editorId]);
144
+ useEffect(() => {
145
+ if (!canvas) {
146
+ return;
147
+ }
148
+ if (activeTool === "pointer" /* ToolEnum.Pointer */) {
149
+ // enable selection
150
+ canvas.selection = true;
151
+ canvas.getObjects().forEach((object) => {
152
+ object.selectable = true;
153
+ });
154
+ canvas.renderAll();
155
+ }
156
+ else {
157
+ // disable selection
158
+ canvas.selection = false;
159
+ canvas.discardActiveObject();
160
+ Dispatcher.emit(`canvas:${editorId}:shapeSelected`, null);
161
+ canvas.renderAll();
162
+ }
163
+ const handleMouseDown = (event) => {
164
+ switch (activeTool) {
165
+ case "rect" /* ToolEnum.Rectangle */:
166
+ if (!canDrawShape(configuration, "rect" /* ToolEnum.Rectangle */, shapes, notify, strings.cannotDrawMoreRectangles))
167
+ return;
168
+ handleMouseDownRect(event, canvas, activeColor, setOriginX, setOriginY, setShape, setIsDrawing);
169
+ break;
170
+ case "polygon" /* ToolEnum.Polygon */:
171
+ if (!canDrawShape(configuration, "polygon" /* ToolEnum.Polygon */, shapes, notify, strings.cannotDrawMorePolygons))
172
+ return;
173
+ handleMouseDownPolygon(event, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines);
174
+ break;
175
+ case "polyline" /* ToolEnum.Polyline */:
176
+ if (!canDrawShape(configuration, "polyline" /* ToolEnum.Polyline */, shapes, notify, strings.cannotDrawMorePolylines))
177
+ return;
178
+ handleMouseDownPolyline(event, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines);
179
+ break;
180
+ default:
181
+ break;
182
+ }
183
+ };
184
+ const handleMouseMove = (event) => {
185
+ switch (activeTool) {
186
+ case "rect" /* ToolEnum.Rectangle */:
187
+ handleMouseMoveRect(event, canvas, originX, originY, shape, isDrawing);
188
+ break;
189
+ case "polygon" /* ToolEnum.Polygon */:
190
+ handleMouseMovePolygon(event, canvas, isDrawing, lines);
191
+ break;
192
+ case "polyline" /* ToolEnum.Polyline */:
193
+ handleMouseMovePolyline(event, canvas, isDrawing, lines);
194
+ break;
195
+ default:
196
+ break;
197
+ }
198
+ };
199
+ const handleMouseUp = () => {
200
+ switch (activeTool) {
201
+ case "rect" /* ToolEnum.Rectangle */:
202
+ handleMouseUpRect(editorId, canvas, setIsDrawing, shape, setShape);
203
+ break;
204
+ default:
205
+ break;
206
+ }
207
+ };
208
+ const handleDoubleClick = () => {
209
+ switch (activeTool) {
210
+ case "polygon" /* ToolEnum.Polygon */:
211
+ handleDoubleClickPolygon(editorId, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines);
212
+ break;
213
+ case "polyline" /* ToolEnum.Polyline */:
214
+ handleDoubleClickPolyline(editorId, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines);
215
+ break;
216
+ default:
217
+ break;
218
+ }
219
+ };
220
+ canvas.on('mouse:down', handleMouseDown);
221
+ canvas.on('mouse:move', handleMouseMove);
222
+ canvas.on('mouse:up', handleMouseUp);
223
+ canvas.on('mouse:dblclick', handleDoubleClick);
224
+ canvas.on('selection:created', handleObjectSelected);
225
+ canvas.on('selection:updated', handleObjectSelected);
226
+ canvas.on('selection:cleared', handleSelectionCleared);
227
+ return () => {
228
+ canvas.off('mouse:down', handleMouseDown);
229
+ canvas.off('mouse:move', handleMouseMove);
230
+ canvas.off('mouse:up', handleMouseUp);
231
+ canvas.off('mouse:dblclick', handleDoubleClick);
232
+ canvas.off('selection:created', handleObjectSelected);
233
+ canvas.off('selection:updated', handleObjectSelected);
234
+ canvas.off('selection:cleared', handleSelectionCleared);
235
+ };
236
+ }, [
237
+ activeTool,
238
+ activeColor,
239
+ isDrawing,
240
+ shape,
241
+ originX,
242
+ originY,
243
+ startPos,
244
+ lines,
245
+ points,
246
+ canvas,
247
+ addShape,
248
+ handleObjectSelected,
249
+ handleSelectionCleared,
250
+ configuration,
251
+ notify,
252
+ strings,
253
+ shapes,
254
+ editorId,
255
+ ]);
256
+ };
257
+ export const useDispatcherEvents = (canvas) => {
258
+ const { configuration, shapes, addShape, setActiveTool, editorId } = useEditorContext();
259
+ const { notify, strings } = useContext(UiContext);
260
+ useEffect(() => {
261
+ const removeShape = (_, id) => {
262
+ const obj = canvas === null || canvas === void 0 ? void 0 : canvas.getObjects().find((s) => s.id === id);
263
+ if (obj) {
264
+ canvas === null || canvas === void 0 ? void 0 : canvas.remove(obj);
265
+ }
266
+ };
267
+ const copyShape = (_, id) => {
268
+ const obj = canvas === null || canvas === void 0 ? void 0 : canvas.getObjects().find((s) => s.id === id);
269
+ let copy;
270
+ switch (obj === null || obj === void 0 ? void 0 : obj.type) {
271
+ case "polygon" /* ToolEnum.Polygon */:
272
+ if (!canDrawShape(configuration, "polygon" /* ToolEnum.Polygon */, shapes, notify, strings.cannotDrawMorePolygons))
273
+ return;
274
+ copy = copyPolygon(editorId, canvas, obj);
275
+ // @ts-expect-error id exists but his stupid ts does not know
276
+ Dispatcher.emit(`canvas:${editorId}:selectShape`, copy.id);
277
+ break;
278
+ case "polyline" /* ToolEnum.Polyline */:
279
+ if (!canDrawShape(configuration, "polyline" /* ToolEnum.Polyline */, shapes, notify, strings.cannotDrawMorePolylines))
280
+ return;
281
+ copy = copyPolyline(editorId, canvas, obj);
282
+ // @ts-expect-error id exists but his stupid ts does not know
283
+ Dispatcher.emit(`canvas:${editorId}:selectShape`, copy.id);
284
+ break;
285
+ case "rect" /* ToolEnum.Rectangle */:
286
+ if (!canDrawShape(configuration, "rect" /* ToolEnum.Rectangle */, shapes, notify, strings.cannotDrawMoreRectangles))
287
+ return;
288
+ copy = copyRectangle(editorId, canvas, obj);
289
+ // @ts-expect-error id exists but his stupid ts does not know
290
+ Dispatcher.emit(`canvas:${editorId}:selectShape`, copy.id);
291
+ break;
292
+ default:
293
+ break;
294
+ }
295
+ };
296
+ const selectShape = (_, id) => {
297
+ const obj = canvas === null || canvas === void 0 ? void 0 : canvas.getObjects().find((s) => s.id === id);
298
+ if (obj) {
299
+ canvas === null || canvas === void 0 ? void 0 : canvas.discardActiveObject();
300
+ canvas === null || canvas === void 0 ? void 0 : canvas.setActiveObject(obj);
301
+ canvas === null || canvas === void 0 ? void 0 : canvas.requestRenderAll();
302
+ setActiveTool("pointer" /* ToolEnum.Pointer */);
303
+ }
304
+ };
305
+ Dispatcher.register(`canvas:${editorId}:removeShape`, removeShape);
306
+ Dispatcher.register(`canvas:${editorId}:copyShape`, copyShape);
307
+ Dispatcher.register(`canvas:${editorId}:selectShape`, selectShape);
308
+ return () => {
309
+ Dispatcher.unregister(`canvas:${editorId}:removeShape`, removeShape);
310
+ Dispatcher.unregister(`canvas:${editorId}:copyShape`, copyShape);
311
+ Dispatcher.unregister(`canvas:${editorId}:selectShape`, selectShape);
312
+ };
313
+ }, [setActiveTool, canvas, addShape, configuration, shapes, notify, strings, editorId]);
314
+ };
315
+ export const useParametersForm = (parameters) => {
316
+ const [errors, setErrors] = useState({});
317
+ const [fields, setFields] = useState(parameters.reduce((acc, p) => (Object.assign(Object.assign({}, acc), { [p.codename]: p.value })), {}));
318
+ const setField = (key) => (value) => {
319
+ setFields(Object.assign(Object.assign({}, fields), { [key]: value }));
320
+ };
321
+ return {
322
+ fields,
323
+ setField,
324
+ setFields,
325
+ errors,
326
+ setErrors,
327
+ };
328
+ };
@@ -0,0 +1,9 @@
1
+ import { ConfigurationParameter } from './Types';
2
+ export type ParameterFieldProps<T> = {
3
+ value: T;
4
+ onChange: (value: T) => void;
5
+ parameter: ConfigurationParameter;
6
+ errors: Record<string, string>;
7
+ };
8
+ declare const ParameterField: <T>({ value, onChange, parameter, errors }: ParameterFieldProps<T>) => import("react/jsx-runtime").JSX.Element | null;
9
+ export default ParameterField;
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useContext } from 'react';
3
+ import { UiContext } from '../../Providers/UiProvider';
4
+ const ParameterField = ({ value, onChange, parameter, errors }) => {
5
+ var _a, _b;
6
+ const { TextField, NumberField, BoolField, EnumField, strings } = useContext(UiContext);
7
+ const props = {
8
+ required: parameter.required,
9
+ label: `${parameter.label}${parameter.unit ? ` (${parameter.unit})` : ''}`,
10
+ error: !!errors[parameter.codename],
11
+ helperText: errors[parameter.codename]
12
+ ? strings[errors[parameter.codename]]
13
+ : parameter.description,
14
+ };
15
+ switch (parameter.type) {
16
+ case 'string':
17
+ return ((_a = parameter.options) === null || _a === void 0 ? void 0 : _a.length) ? (_jsx(EnumField, Object.assign({ value: value, onChange: (v) => onChange(v), options: parameter.options, multiple: parameter.multiple }, props))) : (_jsx(TextField, Object.assign({ type: "text", value: value, onChange: (v) => onChange(v) }, props)));
18
+ case 'int':
19
+ case 'float':
20
+ return ((_b = parameter.options) === null || _b === void 0 ? void 0 : _b.length) ? (_jsx(EnumField, Object.assign({ value: value, onChange: (v) => onChange(v), options: parameter.options, multiple: parameter.multiple }, props))) : (_jsx(NumberField, Object.assign({ value: value, onChange: (v) => onChange(v) }, props)));
21
+ case 'bool':
22
+ return _jsx(BoolField, Object.assign({ value: value, onChange: (v) => onChange(v) }, props));
23
+ default:
24
+ return null;
25
+ }
26
+ };
27
+ export default ParameterField;
@@ -0,0 +1,5 @@
1
+ .form {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 1rem;
5
+ }
@@ -0,0 +1,17 @@
1
+ import { ConfigurationParameter, OutputParameter, ShapeType } from '../Types';
2
+ export type ParametersModalFormProps = {
3
+ onClose: () => void;
4
+ title: string;
5
+ parameters: ConfigurationParameter[];
6
+ data: OutputParameter[];
7
+ onSubmit: (data: OutputParameter[], properties?: {
8
+ name: string;
9
+ role: string;
10
+ }) => void;
11
+ shapeType?: ShapeType;
12
+ shapeName?: string;
13
+ shapeRole?: string;
14
+ shapeId?: string;
15
+ };
16
+ declare const ParametersModalForm: React.FC<ParametersModalFormProps>;
17
+ export default ParametersModalForm;
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useContext, useState } from 'react';
3
+ import { UiContext } from '../../../Providers/UiProvider';
4
+ import { css } from '../../../Utils';
5
+ import RoleField from '../../RoleField';
6
+ import { useParametersForm } from '../Hooks';
7
+ import ParameterField from '../ParameterField';
8
+ import { validateParametersForm } from '../Utils';
9
+ import styles from './ParametersModalForm.module.css';
10
+ const ParametersModalForm = ({ title, onClose, parameters, data, onSubmit, shapeType, shapeName, shapeRole, }) => {
11
+ const { Modal, TextField, strings } = useContext(UiContext);
12
+ const [name, setName] = useState(shapeName !== null && shapeName !== void 0 ? shapeName : '');
13
+ const [role, setRole] = useState(shapeRole !== null && shapeRole !== void 0 ? shapeRole : '');
14
+ const { fields, setField, errors, setErrors } = useParametersForm(data);
15
+ const handleSubmit = () => {
16
+ if (validateParametersForm(parameters, fields, setErrors)) {
17
+ const data = [
18
+ ...parameters.map((p) => ({ codename: p.codename, value: fields[p.codename] })),
19
+ ];
20
+ if (shapeType) {
21
+ onSubmit(data, { name, role });
22
+ }
23
+ else {
24
+ onSubmit(data);
25
+ }
26
+ }
27
+ };
28
+ return (_jsx(Modal, { onClose: onClose, title: title, isOpen: true, maxWidth: "sm", onSubmit: handleSubmit, children: _jsxs("div", { className: css('form', styles, null), children: [shapeType && (_jsxs(_Fragment, { children: [_jsx(TextField, { required: true, label: strings.name, type: "text", value: name, onChange: setName, error: !!errors.name, helperText: errors.name }), _jsx(RoleField, { required: true, value: role, onChange: setRole, error: !!errors.name, helperText: errors.name, shapeType: shapeType })] })), parameters.map((parameter) => {
29
+ switch (parameter.type) {
30
+ case 'string':
31
+ return (_jsx(ParameterField, { value: String(fields[parameter.codename]), onChange: setField(parameter.codename), parameter: parameter, errors: errors }, parameter.codename));
32
+ case 'int':
33
+ case 'float':
34
+ return (_jsx(ParameterField, { value: fields[parameter.codename], onChange: setField(parameter.codename), parameter: parameter, errors: errors }, parameter.codename));
35
+ case 'bool':
36
+ return (_jsx(ParameterField, { value: fields[parameter.codename], onChange: setField(parameter.codename), parameter: parameter, errors: errors }, parameter.codename));
37
+ default:
38
+ return null;
39
+ }
40
+ })] }) }));
41
+ };
42
+ export default ParametersModalForm;
@@ -0,0 +1,18 @@
1
+ import * as fabric from 'fabric';
2
+ import { FabricEvent } from './Types';
3
+ export declare const handleMouseDownPolygon: (event: FabricEvent, canvas: fabric.Canvas, activeColor: string, setIsDrawing: (v: boolean) => void, points: {
4
+ x: number;
5
+ y: number;
6
+ }[], setPoints: (v: {
7
+ x: number;
8
+ y: number;
9
+ }[]) => void, lines: fabric.Line[], setLines: (v: fabric.Line[]) => void) => void;
10
+ export declare const handleMouseMovePolygon: (event: FabricEvent, canvas: fabric.Canvas, isDrawing: boolean, lines: fabric.Line[]) => void;
11
+ export declare const handleDoubleClickPolygon: (editorId: string, canvas: fabric.Canvas, activeColor: string, setIsDrawing: (v: boolean) => void, points: {
12
+ x: number;
13
+ y: number;
14
+ }[], setPoints: (v: {
15
+ x: number;
16
+ y: number;
17
+ }[]) => void, lines: fabric.Line[], setLines: (v: fabric.Line[]) => void) => void;
18
+ export declare const copyPolygon: (editorId: string, canvas: fabric.Canvas, polygon: fabric.Polygon) => fabric.Polygon;
@@ -0,0 +1,77 @@
1
+ import * as fabric from 'fabric';
2
+ import { v4 as uuidv4 } from 'uuid';
3
+ import Dispatcher from '../../Utils/Dispatcher';
4
+ const addPoint = (event, canvas, color, points, setPoints, lines, setLines) => {
5
+ const pointer = canvas.getScenePoint(event.e);
6
+ const newPoint = { x: pointer.x, y: pointer.y };
7
+ const newPolygonPoints = [...points, newPoint];
8
+ setPoints(newPolygonPoints);
9
+ if (newPolygonPoints.length > 0) {
10
+ const line = new fabric.Line([
11
+ newPolygonPoints[newPolygonPoints.length - 1].x,
12
+ newPolygonPoints[newPolygonPoints.length - 1].y,
13
+ pointer.x,
14
+ pointer.y,
15
+ ], {
16
+ stroke: color,
17
+ strokeWidth: 2,
18
+ strokeUniform: true,
19
+ selectable: false,
20
+ hasControls: false,
21
+ });
22
+ canvas.add(line);
23
+ setLines([...lines, line]);
24
+ }
25
+ };
26
+ export const handleMouseDownPolygon = (event, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines) => {
27
+ setIsDrawing(true);
28
+ addPoint(event, canvas, activeColor, points, setPoints, lines, setLines);
29
+ };
30
+ export const handleMouseMovePolygon = (event, canvas, isDrawing, lines) => {
31
+ if (isDrawing && lines.length > 0) {
32
+ const pointer = canvas.getScenePoint(event.e);
33
+ lines[lines.length - 1].set({ x2: pointer.x, y2: pointer.y });
34
+ canvas.renderAll();
35
+ }
36
+ };
37
+ export const handleDoubleClickPolygon = (editorId, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines) => {
38
+ if (points.length > 2) {
39
+ const id = uuidv4();
40
+ const polygon = new fabric.Polygon(points, {
41
+ fill: 'transparent',
42
+ stroke: activeColor,
43
+ strokeWidth: 2,
44
+ selectable: false,
45
+ hasControls: true,
46
+ hoverCursor: 'default',
47
+ // @ts-expect-error id is not included in types but the property is added and it works
48
+ id,
49
+ });
50
+ canvas.add(polygon);
51
+ Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polygon" /* ToolEnum.Polygon */, shape: polygon });
52
+ setPoints([]);
53
+ for (const line of lines) {
54
+ canvas.remove(line); // Remove temporary lines
55
+ }
56
+ setLines([]);
57
+ setIsDrawing(false);
58
+ }
59
+ };
60
+ export const copyPolygon = (editorId, canvas, polygon) => {
61
+ const id = uuidv4();
62
+ const copy = new fabric.Polygon(polygon.points, {
63
+ top: polygon.top + 10,
64
+ left: polygon.left + 10,
65
+ fill: 'transparent',
66
+ stroke: polygon.stroke,
67
+ strokeWidth: polygon.strokeWidth,
68
+ selectable: false,
69
+ hasControls: true,
70
+ hoverCursor: 'default',
71
+ // @ts-expect-error id is not included in types but the property is added and it works
72
+ id,
73
+ });
74
+ canvas.add(copy);
75
+ Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polygon" /* ToolEnum.Polygon */, shape: copy });
76
+ return copy;
77
+ };
@@ -0,0 +1,28 @@
1
+ import * as fabric from 'fabric';
2
+ import { FabricEvent } from './Types';
3
+ export declare const handleMouseDownPolyline: (event: FabricEvent, canvas: fabric.Canvas, activeColor: string, setIsDrawing: (v: boolean) => void, points: {
4
+ x: number;
5
+ y: number;
6
+ }[], setPoints: (v: {
7
+ x: number;
8
+ y: number;
9
+ }[]) => void, lines: fabric.Line[], setLines: (v: fabric.Line[]) => void) => void;
10
+ export declare const handleMouseMovePolyline: (event: FabricEvent, canvas: fabric.Canvas, isDrawing: boolean, lines: fabric.Line[]) => void;
11
+ export declare const handleDoubleClickPolyline: (editorId: string, canvas: fabric.Canvas, activeColor: string, setIsDrawing: (v: boolean) => void, points: {
12
+ x: number;
13
+ y: number;
14
+ }[], setPoints: (v: {
15
+ x: number;
16
+ y: number;
17
+ }[]) => void, lines: fabric.Line[], setLines: (v: fabric.Line[]) => void) => void;
18
+ export declare const copyPolyline: (editorId: string, canvas: fabric.Canvas, polyline: fabric.Polyline) => fabric.Polyline<{
19
+ top: number;
20
+ left: number;
21
+ fill: string;
22
+ stroke: string | fabric.TFiller | null;
23
+ strokeWidth: number;
24
+ selectable: false;
25
+ hasControls: true;
26
+ hoverCursor: string;
27
+ id: string;
28
+ }, fabric.SerializedPolylineProps, fabric.ObjectEvents>;