@abidibo/react-cam-roi 0.0.11 → 0.0.13

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 (35) hide show
  1. package/README.md +36 -10
  2. package/dist/Components/Button/Button.module.css +4 -2
  3. package/dist/Components/EnumField/index.d.ts +4 -4
  4. package/dist/Components/RoiEditor/Canvas.js +3 -3
  5. package/dist/Components/RoiEditor/Header.d.ts +2 -0
  6. package/dist/Components/RoiEditor/Header.js +22 -0
  7. package/dist/Components/RoiEditor/Header.module.css +32 -0
  8. package/dist/Components/RoiEditor/Hooks.js +25 -24
  9. package/dist/Components/RoiEditor/ParametersModalForm/index.d.ts +8 -2
  10. package/dist/Components/RoiEditor/ParametersModalForm/index.js +28 -19
  11. package/dist/Components/RoiEditor/Polygon.d.ts +4 -4
  12. package/dist/Components/RoiEditor/Polygon.js +5 -4
  13. package/dist/Components/RoiEditor/Polyline.d.ts +4 -4
  14. package/dist/Components/RoiEditor/Polyline.js +5 -4
  15. package/dist/Components/RoiEditor/Rectangle.d.ts +3 -3
  16. package/dist/Components/RoiEditor/Rectangle.js +5 -4
  17. package/dist/Components/RoiEditor/RoisInfo.d.ts +2 -0
  18. package/dist/Components/RoiEditor/RoisInfo.js +43 -0
  19. package/dist/Components/RoiEditor/ShapesList.js +51 -21
  20. package/dist/Components/RoiEditor/ShapesList.module.css +32 -1
  21. package/dist/Components/RoiEditor/Toolbar.js +5 -13
  22. package/dist/Components/RoiEditor/Toolbar.module.css +0 -12
  23. package/dist/Components/RoiEditor/Types.d.ts +4 -0
  24. package/dist/Components/RoiEditor/Utils.js +27 -20
  25. package/dist/Components/RoiEditor/index.d.ts +1 -1
  26. package/dist/Components/RoiEditor/index.js +7 -3
  27. package/dist/Components/RoleField.d.ts +7 -0
  28. package/dist/Components/RoleField.js +35 -0
  29. package/dist/Providers/EditorProvider.d.ts +2 -2
  30. package/dist/Providers/EditorProvider.js +2 -2
  31. package/dist/Providers/UiProvider.d.ts +12 -1
  32. package/dist/Providers/UiProvider.js +13 -1
  33. package/dist/Utils/index.d.ts +2 -0
  34. package/dist/Utils/index.js +12 -0
  35. package/package.json +2 -2
package/README.md CHANGED
@@ -52,7 +52,7 @@ The `RoiEditor` props and the `Output` interface used both in import and export:
52
52
  ``` ts
53
53
  export type RoiEditorProps = {
54
54
  // id of this editor instance, should be unique
55
- id: string
55
+ editorId: string
56
56
  // the url of the image we want to annotate
57
57
  imageUrl: string
58
58
  // configuration object
@@ -103,6 +103,8 @@ export interface OutputParameter {
103
103
  export interface OutputRoi {
104
104
  parameters: OutputParameter[]
105
105
  type: ShapeType
106
+ name: string
107
+ role: string
106
108
  shape: OutputShapeRect | OutputShapePolyline | OutputShapePolygon
107
109
  }
108
110
  export interface Output {
@@ -165,7 +167,7 @@ export type ConfigurationParameter = {
165
167
 
166
168
  // Configuration of ROIs
167
169
  export type RoiConfiguration = {
168
- role: string // for our use case
170
+ role: string // let's say the category of the roi
169
171
  type: Omit<ShapeType, 'pointer'> // shape type
170
172
  multiplicity: { // how many ROIs of this type can be drawn
171
173
  operator: OperatorEnum
@@ -210,7 +212,7 @@ export const configuration: Configuration = {
210
212
  ],
211
213
  rois: [
212
214
  {
213
- role: 'invasion_area', // analytics role, do not show in interface
215
+ role: 'invasion_area', // analytics role
214
216
  type: ToolEnum.Polygon,
215
217
  multiplicity: {
216
218
  // how many rois of this type can/should be created
@@ -255,7 +257,7 @@ import { UiProvider, RoiEditor } from 'react-cam-roi'
255
257
 
256
258
  const MyView: React.FC = () => {
257
259
  return (
258
- <UiProvider themeMode={'dark'} IconButton={IconButton} primaryColor={'#1976d2'} enableLogs>
260
+ <UiProvider themeMode={'dark'} IconButton={IconButton} primaryColor={'#1976d2'} primaryFgColor={'#fff'} enableLogs>
259
261
  <RoiEditor imageUrl={'whatever'} />
260
262
  </UiProvider>
261
263
  )
@@ -272,6 +274,7 @@ type UiContextType = {
272
274
  enableLogs: boolean // enable console logs
273
275
  themeMode: 'light' | 'dark' // themeMode for internal components
274
276
  primaryColor: string // primary color for internal components
277
+ primaryFgColor: string // text color above primary bg for internal components
275
278
  Typography: React.FC<TypographyProps> // component used to surround text
276
279
  Modal: React.FC<ModalProps> // modal dialog component (it displays metadata forms)
277
280
  IconButton: React.FC<IconButtonProps> // wrapper for icon buttons
@@ -297,16 +300,27 @@ type UiContextType = {
297
300
  mainParametersMetadata: string
298
301
  missingRequiredValuesInMainParameters: string
299
302
  missingRequiredValuesInShapeParameters: string // with {id} placeholder
303
+ mainParametersMetadata: strings
304
+ roiMultiplicityEqRule: string // with {role}, {type} and {threshold} placeholder
305
+ roiMultiplicityGtRule: string // with {role}, {type} and {threshold} placeholder
306
+ roiMultiplicityGteRule: string // with {role}, {type} and {threshold} placeholder
307
+ roiMultiplicityLtRule: string // with {role}, {type} and {threshold} placeholder
308
+ roiMultiplicityLteRule: string // with {role}, {type} and {threshold} placeholder
309
+ roiMultiplicityNoRule: string // with {role}, {type}
310
+ name: string
300
311
  polygon: string
301
312
  polygonHelpText: string
302
313
  polyline: string
303
314
  polylineHelpText: string
304
- rect: string
305
- rectHelpText: string
306
315
  pointer: string
307
316
  pointerHelpText: string
317
+ rect: string
318
+ rectHelpText: string
308
319
  requiredField: string
320
+ roisToBeDrawn: string
321
+ role: string
309
322
  save: string
323
+ shapeParametersMetadata: string
310
324
  shapesOfTypeShouldBeEqualToThreshold: string // with {type} and {threshold} placeholders
311
325
  shapesOfTypeShouldBeGreaterThanThreshold: string // with {type} and {threshold} placeholders
312
326
  shapesOfTypeShouldBeGreaterThanOrEqualToThreshold: string // with {type} and {threshold} placeholders
@@ -650,11 +664,17 @@ There are components that cannot be overridden. But still you can use classes to
650
664
  - `react-cam-roi-editor-wrapper-light`
651
665
  - `react-cam-roi-editor-wrapper-dark`
652
666
 
653
- #### Toolbar
667
+ #### Header
668
+
669
+ - `react-cam-roi-header`
670
+ - `react-cam-roi-header-light`
671
+ - `react-cam-roi-header-dark`
654
672
 
655
- - `react-cam-roi-toolbar-info`
656
- - `react-cam-roi-toolbar-info-light`
657
- - `react-cam-roi-toolbar-info-dark`
673
+ - `react-cam-roi-header-info`
674
+ - `react-cam-roi-header-info-light`
675
+ - `react-cam-roi-header-info-dark`
676
+
677
+ #### Toolbar
658
678
 
659
679
  - `react-cam-roi-toolbar`
660
680
  - `react-cam-roi-toolbar-light`
@@ -675,6 +695,12 @@ There are components that cannot be overridden. But still you can use classes to
675
695
  - `react-cam-roi-shapes-table`
676
696
  - `react-cam-roi-shapes-table-light`
677
697
  - `react-cam-roi-shapes-table-dark`
698
+ - `react-cam-roi-shapes-row-selected-light`
699
+ - `react-cam-roi-shapes-row-selected-dark`
700
+ - `react-cam-roi-shapes-row-even-light`
701
+ - `react-cam-roi-shapes-row-even-dark`
702
+ - `react-cam-roi-shapes-row-odd-light`
703
+ - `react-cam-roi-shapes-row-odd-dark`
678
704
 
679
705
  #### Colorpicker button
680
706
 
@@ -1,18 +1,20 @@
1
1
  .button {
2
+ align-items: center;
2
3
  border: none;
3
4
  border-radius: 4px;
4
5
  color: black;
5
6
  padding: .5rem 1rem;
6
7
  text-align: center;
7
8
  text-decoration: none;
8
- display: inline-block;
9
+ display: flex;
9
10
  font-size: 16px;
11
+ gap: .5rem;
10
12
  margin: 4px 2px;
11
13
  cursor: pointer;
12
14
  }
13
15
 
14
16
  .button-light {
15
- background-color: #d7d7d7;
17
+ background-color: #c7c7c7;
16
18
  color: black;
17
19
  }
18
20
 
@@ -1,10 +1,10 @@
1
1
  import { FieldProps } from '../../Types';
2
- export type EnumOption = {
3
- value: string | number;
2
+ export type EnumOption<T> = {
3
+ value: T;
4
4
  label: string;
5
5
  };
6
- declare const EnumField: ({ onChange, value, label, helperText, error, options, disabled, required, multiple }: Omit<FieldProps<string | number | (string | number)[]>, "readOnly"> & {
7
- options: EnumOption[];
6
+ declare const EnumField: <T extends string | number>({ onChange, value, label, helperText, error, options, disabled, required, multiple }: Omit<FieldProps<T | T[]>, "readOnly"> & {
7
+ options: EnumOption<T>[];
8
8
  multiple?: boolean;
9
9
  }) => import("react/jsx-runtime").JSX.Element;
10
10
  export default EnumField;
@@ -5,7 +5,7 @@ import { useEditorContext } from '../../Providers/EditorProvider';
5
5
  import { UiContext } from '../../Providers/UiProvider';
6
6
  import { initCanvasData, useDispatcherEvents, useTool } from './Hooks';
7
7
  const Canvas = ({ canvasSize, initialData }) => {
8
- const { metadata, setMetadata, addShapes, id } = useEditorContext();
8
+ const { metadata, setMetadata, addShapes, editorId } = useEditorContext();
9
9
  const { enableLogs } = useContext(UiContext);
10
10
  const [initialized, setInitialized] = useState(false);
11
11
  const canvasRef = useRef(null);
@@ -13,7 +13,7 @@ const Canvas = ({ canvasSize, initialData }) => {
13
13
  useDispatcherEvents(canvasRef.current);
14
14
  useEffect(() => {
15
15
  if (canvasSize.width !== 0 && canvasSize.height !== 0 && !initialized) {
16
- canvasRef.current = new fabric.Canvas('react-cam-roi-canvas');
16
+ canvasRef.current = new fabric.Canvas(`react-cam-roi-canvas-${editorId}`);
17
17
  canvasRef.current.setDimensions({ width: canvasSize.width, height: canvasSize.height });
18
18
  initCanvasData(canvasRef, addShapes, metadata, setMetadata, initialData, enableLogs);
19
19
  setInitialized(true);
@@ -23,6 +23,6 @@ const Canvas = ({ canvasSize, initialData }) => {
23
23
  (_a = canvasRef.current) === null || _a === void 0 ? void 0 : _a.dispose();
24
24
  };
25
25
  }, [canvasSize.width, canvasSize.height]); // eslint-disable-line
26
- return (_jsx("canvas", { id: `react-cam-roi-canvas-${id}`, style: { width: `${canvasSize.width}px`, height: `${canvasSize.height}px` } }));
26
+ return (_jsx("canvas", { id: `react-cam-roi-canvas-${editorId}`, style: { width: `${canvasSize.width}px`, height: `${canvasSize.height}px` } }));
27
27
  };
28
28
  export default Canvas;
@@ -0,0 +1,2 @@
1
+ declare const Header: () => import("react/jsx-runtime").JSX.Element;
2
+ export default Header;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useContext, useState } from 'react';
3
+ import { useEditorContext } from '../../Providers/EditorProvider';
4
+ import { UiContext } from '../../Providers/UiProvider';
5
+ import { css } from '../../Utils';
6
+ import styles from './Header.module.css';
7
+ import ParametersModalForm from './ParametersModalForm';
8
+ import { enableMainMetadata } from './Utils';
9
+ import RoisInfo from './RoisInfo';
10
+ const Header = () => {
11
+ var _a;
12
+ const { themeMode, Typography, Button, strings, SaveIcon, primaryFgColor, AnnotateIcon } = useContext(UiContext);
13
+ const { configuration, onSubmit, metadata, setMetadata } = useEditorContext();
14
+ const [form, setForm] = useState({ isOpen: false });
15
+ const iconColor = themeMode === 'light' ? 'black' : 'white';
16
+ const handleSubmitMetadata = (data) => {
17
+ setMetadata(Object.assign(Object.assign({}, metadata), { parameters: data }));
18
+ setForm({ isOpen: false });
19
+ };
20
+ return (_jsxs("div", { className: css('header', styles, themeMode), children: [_jsxs("div", { className: css('header-info', styles, themeMode), children: [((_a = configuration.options) === null || _a === void 0 ? void 0 : _a.description) && _jsx(Typography, { children: configuration.options.description }), _jsx(RoisInfo, {})] }), _jsxs("div", { className: styles.headerButtons, children: [enableMainMetadata(configuration) && (_jsxs(Button, { onClick: () => setForm({ isOpen: true }), children: [_jsx(AnnotateIcon, { color: iconColor }), " ", strings.mainParametersMetadata] })), _jsxs(Button, { primary: true, onClick: onSubmit, children: [_jsx(SaveIcon, { color: primaryFgColor }), " ", strings.save] })] }), form.isOpen && (_jsx(ParametersModalForm, { parameters: configuration.parameters, data: metadata.parameters, title: strings.mainParametersMetadata, onClose: () => setForm({ isOpen: false }), onSubmit: handleSubmitMetadata }))] }));
21
+ };
22
+ export default Header;
@@ -0,0 +1,32 @@
1
+ .header {
2
+ align-items: flex-start;
3
+ display: flex;
4
+ justify-content: space-between;
5
+ padding: .5rem;
6
+ }
7
+
8
+ .header-light {
9
+ background-color: #ddd;;
10
+ }
11
+
12
+ .header-dark {
13
+ background-color: #222;
14
+ }
15
+
16
+ .header-info {
17
+ padding: .5rem;
18
+ }
19
+ .header-info-light {
20
+ background-color: #ddd;;
21
+ color: #000;
22
+ }
23
+ .header-info-dark {
24
+ background-color: #222;
25
+ color: #fff;
26
+ }
27
+
28
+ .headerButtons {
29
+ display: flex;
30
+ align-items: center;
31
+ gap: .5rem
32
+ }
@@ -108,7 +108,7 @@ export const initCanvasData = (canvasRef, addShapes, metadata, setMetadata, init
108
108
  (_c = canvasRef.current) === null || _c === void 0 ? void 0 : _c.add(shape);
109
109
  break;
110
110
  }
111
- m.push({ id, parameters: r.parameters });
111
+ m.push({ id, parameters: r.parameters, name: r.name, role: r.role });
112
112
  s.push({ id, type: r.type, shape });
113
113
  });
114
114
  addShapes(s);
@@ -116,7 +116,7 @@ export const initCanvasData = (canvasRef, addShapes, metadata, setMetadata, init
116
116
  }
117
117
  };
118
118
  export const useTool = (canvas) => {
119
- const { configuration, activeTool, activeColor, shapes, addShape } = useEditorContext();
119
+ const { editorId, configuration, activeTool, activeColor, shapes, addShape } = useEditorContext();
120
120
  const { notify, strings } = useContext(UiContext);
121
121
  const [isDrawing, setIsDrawing] = useState(false);
122
122
  const [shape, setShape] = useState(null);
@@ -128,12 +128,12 @@ export const useTool = (canvas) => {
128
128
  // Handler for object selected event to update style settings
129
129
  const handleObjectSelected = useCallback((event) => {
130
130
  var _a;
131
- Dispatcher.emit('canvas:shapeSelected', (_a = event.selected) !== null && _a !== void 0 ? _a : null);
132
- }, []);
131
+ Dispatcher.emit(`canvas:${editorId}:shapeSelected`, (_a = event.selected) !== null && _a !== void 0 ? _a : null);
132
+ }, [editorId]);
133
133
  // Handler for selection cleared event to reset selected shapes state
134
134
  const handleSelectionCleared = useCallback(() => {
135
- Dispatcher.emit('canvas:shapeSelected', null);
136
- }, []);
135
+ Dispatcher.emit(`canvas:${editorId}:shapeSelected`, null);
136
+ }, [editorId]);
137
137
  useEffect(() => {
138
138
  if (!canvas) {
139
139
  return;
@@ -150,7 +150,7 @@ export const useTool = (canvas) => {
150
150
  // disable selection
151
151
  canvas.selection = false;
152
152
  canvas.discardActiveObject();
153
- Dispatcher.emit('canvas:shapeSelected', null);
153
+ Dispatcher.emit(`canvas:${editorId}:shapeSelected`, null);
154
154
  canvas.renderAll();
155
155
  }
156
156
  const handleMouseDown = (event) => {
@@ -192,7 +192,7 @@ export const useTool = (canvas) => {
192
192
  const handleMouseUp = () => {
193
193
  switch (activeTool) {
194
194
  case "rect" /* ToolEnum.Rectangle */:
195
- handleMouseUpRect(canvas, setIsDrawing, shape, setShape, addShape);
195
+ handleMouseUpRect(editorId, canvas, setIsDrawing, shape, setShape);
196
196
  break;
197
197
  default:
198
198
  break;
@@ -201,10 +201,10 @@ export const useTool = (canvas) => {
201
201
  const handleDoubleClick = () => {
202
202
  switch (activeTool) {
203
203
  case "polygon" /* ToolEnum.Polygon */:
204
- handleDoubleClickPolygon(canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines, addShape);
204
+ handleDoubleClickPolygon(editorId, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines);
205
205
  break;
206
206
  case "polyline" /* ToolEnum.Polyline */:
207
- handleDoubleClickPolyline(canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines, addShape);
207
+ handleDoubleClickPolyline(editorId, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines);
208
208
  break;
209
209
  default:
210
210
  break;
@@ -244,10 +244,11 @@ export const useTool = (canvas) => {
244
244
  notify,
245
245
  strings,
246
246
  shapes,
247
+ editorId,
247
248
  ]);
248
249
  };
249
250
  export const useDispatcherEvents = (canvas) => {
250
- const { configuration, shapes, addShape, setActiveTool } = useEditorContext();
251
+ const { configuration, shapes, addShape, setActiveTool, editorId } = useEditorContext();
251
252
  const { notify, strings } = useContext(UiContext);
252
253
  useEffect(() => {
253
254
  const removeShape = (_, id) => {
@@ -263,23 +264,23 @@ export const useDispatcherEvents = (canvas) => {
263
264
  case "polygon" /* ToolEnum.Polygon */:
264
265
  if (!canDrawShape(configuration, "polygon" /* ToolEnum.Polygon */, shapes, notify, strings.cannotDrawMorePolygons))
265
266
  return;
266
- copy = copyPolygon(canvas, obj, addShape);
267
+ copy = copyPolygon(editorId, canvas, obj);
267
268
  // @ts-expect-error id exists but his stupid ts does not know
268
- Dispatcher.emit('canvas:selectShape', copy.id);
269
+ Dispatcher.emit(`canvas:${editorId}:selectShape`, copy.id);
269
270
  break;
270
271
  case "polyline" /* ToolEnum.Polyline */:
271
272
  if (!canDrawShape(configuration, "polyline" /* ToolEnum.Polyline */, shapes, notify, strings.cannotDrawMorePolylines))
272
273
  return;
273
- copy = copyPolyline(canvas, obj, addShape);
274
+ copy = copyPolyline(editorId, canvas, obj);
274
275
  // @ts-expect-error id exists but his stupid ts does not know
275
- Dispatcher.emit('canvas:selectShape', copy.id);
276
+ Dispatcher.emit(`canvas:${editorId}:selectShape`, copy.id);
276
277
  break;
277
278
  case "rect" /* ToolEnum.Rectangle */:
278
279
  if (!canDrawShape(configuration, "rect" /* ToolEnum.Rectangle */, shapes, notify, strings.cannotDrawMoreRectangles))
279
280
  return;
280
- copy = copyRectangle(canvas, obj, addShape);
281
+ copy = copyRectangle(editorId, canvas, obj);
281
282
  // @ts-expect-error id exists but his stupid ts does not know
282
- Dispatcher.emit('canvas:selectShape', copy.id);
283
+ Dispatcher.emit(`canvas:${editorId}:selectShape`, copy.id);
283
284
  break;
284
285
  default:
285
286
  break;
@@ -294,15 +295,15 @@ export const useDispatcherEvents = (canvas) => {
294
295
  setActiveTool("pointer" /* ToolEnum.Pointer */);
295
296
  }
296
297
  };
297
- Dispatcher.register('canvas:removeShape', removeShape);
298
- Dispatcher.register('canvas:copyShape', copyShape);
299
- Dispatcher.register('canvas:selectShape', selectShape);
298
+ Dispatcher.register(`canvas:${editorId}:removeShape`, removeShape);
299
+ Dispatcher.register(`canvas:${editorId}:copyShape`, copyShape);
300
+ Dispatcher.register(`canvas:${editorId}:selectShape`, selectShape);
300
301
  return () => {
301
- Dispatcher.unregister('canvas:removeShape', removeShape);
302
- Dispatcher.unregister('canvas:copyShape', copyShape);
303
- Dispatcher.unregister('canvas:selectShape', selectShape);
302
+ Dispatcher.unregister(`canvas:${editorId}:removeShape`, removeShape);
303
+ Dispatcher.unregister(`canvas:${editorId}:copyShape`, copyShape);
304
+ Dispatcher.unregister(`canvas:${editorId}:selectShape`, selectShape);
304
305
  };
305
- }, [setActiveTool, canvas, addShape, configuration, shapes, notify, strings]);
306
+ }, [setActiveTool, canvas, addShape, configuration, shapes, notify, strings, editorId]);
306
307
  };
307
308
  export const useParametersForm = (parameters) => {
308
309
  const [errors, setErrors] = useState({});
@@ -1,10 +1,16 @@
1
- import { ConfigurationParameter, OutputParameter } from '../Types';
1
+ import { ConfigurationParameter, OutputParameter, ShapeType } from '../Types';
2
2
  export type ParametersModalFormProps = {
3
3
  onClose: () => void;
4
4
  title: string;
5
5
  parameters: ConfigurationParameter[];
6
6
  data: OutputParameter[];
7
- onSubmit: (data: OutputParameter[]) => void;
7
+ onSubmit: (data: OutputParameter[], properties?: {
8
+ name: string;
9
+ role: string;
10
+ }) => void;
11
+ shapeType?: ShapeType;
12
+ shapeName?: string;
13
+ shapeRole?: string;
8
14
  };
9
15
  declare const ParametersModalForm: React.FC<ParametersModalFormProps>;
10
16
  export default ParametersModalForm;
@@ -1,31 +1,40 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useContext } from 'react';
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useContext, useState } from 'react';
3
3
  import { UiContext } from '../../../Providers/UiProvider';
4
4
  import { css } from '../../../Utils';
5
+ import RoleField from '../../RoleField';
5
6
  import { useParametersForm } from '../Hooks';
6
7
  import ParameterField from '../ParameterField';
7
- import styles from './ParametersModalForm.module.css';
8
8
  import { validateParametersForm } from '../Utils';
9
- const ParametersModalForm = ({ title, onClose, parameters, data, onSubmit }) => {
10
- const { Modal } = useContext(UiContext);
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 : '');
11
14
  const { fields, setField, errors, setErrors } = useParametersForm(data);
12
15
  const handleSubmit = () => {
13
16
  if (validateParametersForm(parameters, fields, setErrors)) {
14
- onSubmit([...parameters.map((p) => ({ codename: p.codename, value: fields[p.codename] }))]);
17
+ const data = [...parameters.map((p) => ({ codename: p.codename, value: fields[p.codename] }))];
18
+ if (shapeType) {
19
+ onSubmit(data, { name, role });
20
+ }
21
+ else {
22
+ onSubmit(data);
23
+ }
15
24
  }
16
25
  };
17
- return (_jsx(Modal, { onClose: onClose, title: title, isOpen: true, maxWidth: "sm", onSubmit: handleSubmit, children: _jsx("div", { className: css('form', styles, null), children: parameters.map((parameter) => {
18
- switch (parameter.type) {
19
- case 'string':
20
- return (_jsx(ParameterField, { value: String(fields[parameter.codename]), onChange: setField(parameter.codename), parameter: parameter, errors: errors }, parameter.codename));
21
- case 'int':
22
- case 'float':
23
- return (_jsx(ParameterField, { value: fields[parameter.codename], onChange: setField(parameter.codename), parameter: parameter, errors: errors }, parameter.codename));
24
- case 'bool':
25
- return (_jsx(ParameterField, { value: fields[parameter.codename], onChange: setField(parameter.codename), parameter: parameter, errors: errors }, parameter.codename));
26
- default:
27
- return null;
28
- }
29
- }) }) }));
26
+ 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) => {
27
+ switch (parameter.type) {
28
+ case 'string':
29
+ return (_jsx(ParameterField, { value: String(fields[parameter.codename]), onChange: setField(parameter.codename), parameter: parameter, errors: errors }, parameter.codename));
30
+ case 'int':
31
+ case 'float':
32
+ return (_jsx(ParameterField, { value: fields[parameter.codename], onChange: setField(parameter.codename), parameter: parameter, errors: errors }, parameter.codename));
33
+ case 'bool':
34
+ return (_jsx(ParameterField, { value: fields[parameter.codename], onChange: setField(parameter.codename), parameter: parameter, errors: errors }, parameter.codename));
35
+ default:
36
+ return null;
37
+ }
38
+ })] }) }));
30
39
  };
31
40
  export default ParametersModalForm;
@@ -1,5 +1,5 @@
1
1
  import * as fabric from 'fabric';
2
- import { FabricEvent, IAddShape } from './Types';
2
+ import { FabricEvent } from './Types';
3
3
  export declare const handleMouseDownPolygon: (event: FabricEvent, canvas: fabric.Canvas, activeColor: string, setIsDrawing: (v: boolean) => void, points: {
4
4
  x: number;
5
5
  y: number;
@@ -8,11 +8,11 @@ export declare const handleMouseDownPolygon: (event: FabricEvent, canvas: fabric
8
8
  y: number;
9
9
  }[]) => void, lines: fabric.Line[], setLines: (v: fabric.Line[]) => void) => void;
10
10
  export declare const handleMouseMovePolygon: (event: FabricEvent, canvas: fabric.Canvas, isDrawing: boolean, lines: fabric.Line[]) => void;
11
- export declare const handleDoubleClickPolygon: (canvas: fabric.Canvas, activeColor: string, setIsDrawing: (v: boolean) => void, points: {
11
+ export declare const handleDoubleClickPolygon: (editorId: string, canvas: fabric.Canvas, activeColor: string, setIsDrawing: (v: boolean) => void, points: {
12
12
  x: number;
13
13
  y: number;
14
14
  }[], setPoints: (v: {
15
15
  x: number;
16
16
  y: number;
17
- }[]) => void, lines: fabric.Line[], setLines: (v: fabric.Line[]) => void, addShape: IAddShape) => void;
18
- export declare const copyPolygon: (canvas: fabric.Canvas, polygon: fabric.Polygon, addShape: IAddShape) => fabric.Polygon;
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;
@@ -1,5 +1,6 @@
1
1
  import * as fabric from 'fabric';
2
2
  import { v4 as uuidv4 } from 'uuid';
3
+ import Dispatcher from '../../Utils/Dispatcher';
3
4
  const addPoint = (event, canvas, color, points, setPoints, lines, setLines) => {
4
5
  const pointer = canvas.getScenePoint(event.e);
5
6
  const newPoint = { x: pointer.x, y: pointer.y };
@@ -33,7 +34,7 @@ export const handleMouseMovePolygon = (event, canvas, isDrawing, lines) => {
33
34
  canvas.renderAll();
34
35
  }
35
36
  };
36
- export const handleDoubleClickPolygon = (canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines, addShape) => {
37
+ export const handleDoubleClickPolygon = (editorId, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines) => {
37
38
  if (points.length > 2) {
38
39
  const id = uuidv4();
39
40
  const polygon = new fabric.Polygon(points, {
@@ -47,7 +48,7 @@ export const handleDoubleClickPolygon = (canvas, activeColor, setIsDrawing, poin
47
48
  id,
48
49
  });
49
50
  canvas.add(polygon);
50
- addShape(polygon.id, "polygon" /* ToolEnum.Polygon */, polygon);
51
+ Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polygon" /* ToolEnum.Polygon */, shape: polygon });
51
52
  setPoints([]);
52
53
  for (const line of lines) {
53
54
  canvas.remove(line); // Remove temporary lines
@@ -56,7 +57,7 @@ export const handleDoubleClickPolygon = (canvas, activeColor, setIsDrawing, poin
56
57
  setIsDrawing(false);
57
58
  }
58
59
  };
59
- export const copyPolygon = (canvas, polygon, addShape) => {
60
+ export const copyPolygon = (editorId, canvas, polygon) => {
60
61
  const id = uuidv4();
61
62
  const copy = new fabric.Polygon(polygon.points, {
62
63
  top: polygon.top + 10,
@@ -71,6 +72,6 @@ export const copyPolygon = (canvas, polygon, addShape) => {
71
72
  id,
72
73
  });
73
74
  canvas.add(copy);
74
- addShape(id, "polygon" /* ToolEnum.Polygon */, copy);
75
+ Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polygon" /* ToolEnum.Polygon */, shape: copy });
75
76
  return copy;
76
77
  };
@@ -1,5 +1,5 @@
1
1
  import * as fabric from 'fabric';
2
- import { FabricEvent, IAddShape, ShapeType } from './Types';
2
+ import { FabricEvent } from './Types';
3
3
  export declare const handleMouseDownPolyline: (event: FabricEvent, canvas: fabric.Canvas, activeColor: string, setIsDrawing: (v: boolean) => void, points: {
4
4
  x: number;
5
5
  y: number;
@@ -8,14 +8,14 @@ export declare const handleMouseDownPolyline: (event: FabricEvent, canvas: fabri
8
8
  y: number;
9
9
  }[]) => void, lines: fabric.Line[], setLines: (v: fabric.Line[]) => void) => void;
10
10
  export declare const handleMouseMovePolyline: (event: FabricEvent, canvas: fabric.Canvas, isDrawing: boolean, lines: fabric.Line[]) => void;
11
- export declare const handleDoubleClickPolyline: (canvas: fabric.Canvas, activeColor: string, setIsDrawing: (v: boolean) => void, points: {
11
+ export declare const handleDoubleClickPolyline: (editorId: string, canvas: fabric.Canvas, activeColor: string, setIsDrawing: (v: boolean) => void, points: {
12
12
  x: number;
13
13
  y: number;
14
14
  }[], setPoints: (v: {
15
15
  x: number;
16
16
  y: number;
17
- }[]) => void, lines: fabric.Line[], setLines: (v: fabric.Line[]) => void, addShape: (id: string, type: ShapeType, shape: fabric.Polyline) => void) => void;
18
- export declare const copyPolyline: (canvas: fabric.Canvas, polyline: fabric.Polyline, addShape: IAddShape) => fabric.Polyline<{
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
19
  top: number;
20
20
  left: number;
21
21
  fill: string;
@@ -1,5 +1,6 @@
1
1
  import * as fabric from 'fabric';
2
2
  import { v4 as uuidv4 } from 'uuid';
3
+ import Dispatcher from '../../Utils/Dispatcher';
3
4
  const addPoint = (event, canvas, color, points, setPoints, lines, setLines) => {
4
5
  const pointer = canvas.getScenePoint(event.e);
5
6
  const newPoint = { x: pointer.x, y: pointer.y };
@@ -33,7 +34,7 @@ export const handleMouseMovePolyline = (event, canvas, isDrawing, lines) => {
33
34
  canvas.renderAll();
34
35
  }
35
36
  };
36
- export const handleDoubleClickPolyline = (canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines, addShape) => {
37
+ export const handleDoubleClickPolyline = (editorId, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines) => {
37
38
  if (points.length > 2) {
38
39
  const id = uuidv4();
39
40
  const polyline = new fabric.Polyline(points, {
@@ -46,7 +47,7 @@ export const handleDoubleClickPolyline = (canvas, activeColor, setIsDrawing, poi
46
47
  id,
47
48
  });
48
49
  canvas.add(polyline);
49
- addShape(id, "polyline" /* ToolEnum.Polyline */, polyline);
50
+ Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polyline" /* ToolEnum.Polyline */, shape: polyline });
50
51
  setPoints([]);
51
52
  for (const line of lines) {
52
53
  canvas.remove(line); // Remove temporary lines
@@ -55,7 +56,7 @@ export const handleDoubleClickPolyline = (canvas, activeColor, setIsDrawing, poi
55
56
  setIsDrawing(false);
56
57
  }
57
58
  };
58
- export const copyPolyline = (canvas, polyline, addShape) => {
59
+ export const copyPolyline = (editorId, canvas, polyline) => {
59
60
  const id = uuidv4();
60
61
  const copy = new fabric.Polyline(polyline.points, {
61
62
  top: polyline.top + 10,
@@ -69,6 +70,6 @@ export const copyPolyline = (canvas, polyline, addShape) => {
69
70
  id,
70
71
  });
71
72
  canvas.add(copy);
72
- addShape(id, "polyline" /* ToolEnum.Polyline */, copy);
73
+ Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polyline" /* ToolEnum.Polyline */, shape: copy });
73
74
  return copy;
74
75
  };
@@ -1,9 +1,9 @@
1
1
  import * as fabric from 'fabric';
2
- import { FabricEvent, IAddShape, Shape, ShapeType } from './Types';
2
+ import { FabricEvent, Shape } from './Types';
3
3
  export declare const handleMouseDownRect: (event: FabricEvent, canvas: fabric.Canvas, activeColor: string, setOriginX: (v: number) => void, setOriginY: (v: number) => void, setShape: (v: Shape) => void, setIsDrawing: (v: boolean) => void) => void;
4
4
  export declare const handleMouseMoveRect: (event: FabricEvent, canvas: fabric.Canvas, originX: number, originY: number, shape: Shape, isDrawing: boolean) => void;
5
- export declare const handleMouseUpRect: (canvas: fabric.Canvas, setIsDrawing: (v: boolean) => void, shape: Shape, setShape: (v: Shape | null) => void, addShape: (id: string, type: ShapeType, shape: Shape) => void) => void;
6
- export declare const copyRectangle: (canvas: fabric.Canvas, rectangle: fabric.Rect, addShape: IAddShape) => fabric.Rect<{
5
+ export declare const handleMouseUpRect: (editorId: string, canvas: fabric.Canvas, setIsDrawing: (v: boolean) => void, shape: Shape, setShape: (v: Shape | null) => void) => void;
6
+ export declare const copyRectangle: (editorId: string, canvas: fabric.Canvas, rectangle: fabric.Rect) => fabric.Rect<{
7
7
  left: number;
8
8
  top: number;
9
9
  originX: "left";
@@ -1,5 +1,6 @@
1
1
  import * as fabric from 'fabric';
2
2
  import { v4 as uuidv4 } from 'uuid';
3
+ import Dispatcher from '../../Utils/Dispatcher';
3
4
  export const handleMouseDownRect = (event, canvas, activeColor, setOriginX, setOriginY, setShape, setIsDrawing) => {
4
5
  const pointer = canvas.getScenePoint(event.e);
5
6
  setOriginX(pointer.x);
@@ -41,14 +42,14 @@ export const handleMouseMoveRect = (event, canvas, originX, originY, shape, isDr
41
42
  canvas.renderAll();
42
43
  }
43
44
  };
44
- export const handleMouseUpRect = (canvas, setIsDrawing, shape, setShape, addShape) => {
45
+ export const handleMouseUpRect = (editorId, canvas, setIsDrawing, shape, setShape) => {
45
46
  setIsDrawing(false);
46
47
  shape.setCoords();
47
- addShape(shape.id, "rect" /* ToolEnum.Rectangle */, shape);
48
+ Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id: shape.id, type: "rect" /* ToolEnum.Rectangle */, shape });
48
49
  setShape(null);
49
50
  canvas.defaultCursor = 'default';
50
51
  };
51
- export const copyRectangle = (canvas, rectangle, addShape) => {
52
+ export const copyRectangle = (editorId, canvas, rectangle) => {
52
53
  const id = uuidv4();
53
54
  const copy = new fabric.Rect({
54
55
  left: rectangle.left + 10,
@@ -67,6 +68,6 @@ export const copyRectangle = (canvas, rectangle, addShape) => {
67
68
  id,
68
69
  });
69
70
  canvas.add(copy);
70
- addShape(id, "rect" /* ToolEnum.Rectangle */, copy);
71
+ Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "rect" /* ToolEnum.Rectangle */, shape: copy });
71
72
  return copy;
72
73
  };
@@ -0,0 +1,2 @@
1
+ declare const RoisInfo: () => import("react/jsx-runtime").JSX.Element | null;
2
+ export default RoisInfo;