@abidibo/react-cam-roi 0.2.3 → 0.2.4

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 (94) hide show
  1. package/README.md +0 -2
  2. package/dist/index.cjs.css +2 -0
  3. package/dist/index.cjs.css.map +1 -0
  4. package/dist/index.cjs.js +1582 -0
  5. package/dist/index.cjs.js.map +1 -0
  6. package/dist/index.esm.css +2 -0
  7. package/dist/index.esm.css.map +1 -0
  8. package/dist/index.esm.js +1576 -0
  9. package/dist/index.esm.js.map +1 -0
  10. package/package.json +17 -6
  11. package/dist/Components/BoolField/index.js +0 -13
  12. package/dist/Components/Button/index.js +0 -15
  13. package/dist/Components/EnumField/index.js +0 -16
  14. package/dist/Components/IconButton/index.js +0 -10
  15. package/dist/Components/Loader/index.js +0 -9
  16. package/dist/Components/Modal/index.js +0 -16
  17. package/dist/Components/NumberField/index.js +0 -13
  18. package/dist/Components/RoiEditor/Canvas.js +0 -30
  19. package/dist/Components/RoiEditor/ColorPicker.js +0 -12
  20. package/dist/Components/RoiEditor/Header.js +0 -14
  21. package/dist/Components/RoiEditor/Hooks.js +0 -328
  22. package/dist/Components/RoiEditor/ParameterField.js +0 -27
  23. package/dist/Components/RoiEditor/ParametersModalForm/index.js +0 -42
  24. package/dist/Components/RoiEditor/Polygon.js +0 -77
  25. package/dist/Components/RoiEditor/Polyline.js +0 -75
  26. package/dist/Components/RoiEditor/Rectangle.js +0 -73
  27. package/dist/Components/RoiEditor/RoisInfo.js +0 -43
  28. package/dist/Components/RoiEditor/ShapesList.js +0 -77
  29. package/dist/Components/RoiEditor/Toolbar.js +0 -27
  30. package/dist/Components/RoiEditor/TopBar.js +0 -21
  31. package/dist/Components/RoiEditor/Types.js +0 -23
  32. package/dist/Components/RoiEditor/Utils.js +0 -161
  33. package/dist/Components/RoiEditor/index.js +0 -99
  34. package/dist/Components/RoleField.js +0 -49
  35. package/dist/Components/TextField/index.js +0 -13
  36. package/dist/Components/Typography/index.js +0 -6
  37. package/dist/Icons/AnnotateIcon.js +0 -5
  38. package/dist/Icons/CloseIcon.js +0 -5
  39. package/dist/Icons/CopyIcon.js +0 -5
  40. package/dist/Icons/DeleteIcon.js +0 -5
  41. package/dist/Icons/EditIcon.js +0 -5
  42. package/dist/Icons/PointerIcon.js +0 -5
  43. package/dist/Icons/PolygonIcon.js +0 -5
  44. package/dist/Icons/PolylineIcon.js +0 -5
  45. package/dist/Icons/RectangleIcon.js +0 -5
  46. package/dist/Icons/SaveIcon.js +0 -5
  47. package/dist/Providers/EditorProvider.js +0 -29
  48. package/dist/Providers/UiProvider.js +0 -104
  49. package/dist/Types.js +0 -1
  50. package/dist/Utils/Dispatcher.js +0 -65
  51. package/dist/Utils/index.js +0 -16
  52. package/dist/index.js +0 -4
  53. /package/dist/{Components → types/Components}/BoolField/index.d.ts +0 -0
  54. /package/dist/{Components → types/Components}/Button/index.d.ts +0 -0
  55. /package/dist/{Components → types/Components}/EnumField/index.d.ts +0 -0
  56. /package/dist/{Components → types/Components}/IconButton/index.d.ts +0 -0
  57. /package/dist/{Components → types/Components}/Loader/index.d.ts +0 -0
  58. /package/dist/{Components → types/Components}/Modal/index.d.ts +0 -0
  59. /package/dist/{Components → types/Components}/NumberField/index.d.ts +0 -0
  60. /package/dist/{Components → types/Components}/RoiEditor/Canvas.d.ts +0 -0
  61. /package/dist/{Components → types/Components}/RoiEditor/ColorPicker.d.ts +0 -0
  62. /package/dist/{Components → types/Components}/RoiEditor/Header.d.ts +0 -0
  63. /package/dist/{Components → types/Components}/RoiEditor/Hooks.d.ts +0 -0
  64. /package/dist/{Components → types/Components}/RoiEditor/ParameterField.d.ts +0 -0
  65. /package/dist/{Components → types/Components}/RoiEditor/ParametersModalForm/index.d.ts +0 -0
  66. /package/dist/{Components → types/Components}/RoiEditor/Polygon.d.ts +0 -0
  67. /package/dist/{Components → types/Components}/RoiEditor/Polyline.d.ts +0 -0
  68. /package/dist/{Components → types/Components}/RoiEditor/Rectangle.d.ts +0 -0
  69. /package/dist/{Components → types/Components}/RoiEditor/RoisInfo.d.ts +0 -0
  70. /package/dist/{Components → types/Components}/RoiEditor/ShapesList.d.ts +0 -0
  71. /package/dist/{Components → types/Components}/RoiEditor/Toolbar.d.ts +0 -0
  72. /package/dist/{Components → types/Components}/RoiEditor/TopBar.d.ts +0 -0
  73. /package/dist/{Components → types/Components}/RoiEditor/Types.d.ts +0 -0
  74. /package/dist/{Components → types/Components}/RoiEditor/Utils.d.ts +0 -0
  75. /package/dist/{Components → types/Components}/RoiEditor/index.d.ts +0 -0
  76. /package/dist/{Components → types/Components}/RoleField.d.ts +0 -0
  77. /package/dist/{Components → types/Components}/TextField/index.d.ts +0 -0
  78. /package/dist/{Components → types/Components}/Typography/index.d.ts +0 -0
  79. /package/dist/{Icons → types/Icons}/AnnotateIcon.d.ts +0 -0
  80. /package/dist/{Icons → types/Icons}/CloseIcon.d.ts +0 -0
  81. /package/dist/{Icons → types/Icons}/CopyIcon.d.ts +0 -0
  82. /package/dist/{Icons → types/Icons}/DeleteIcon.d.ts +0 -0
  83. /package/dist/{Icons → types/Icons}/EditIcon.d.ts +0 -0
  84. /package/dist/{Icons → types/Icons}/PointerIcon.d.ts +0 -0
  85. /package/dist/{Icons → types/Icons}/PolygonIcon.d.ts +0 -0
  86. /package/dist/{Icons → types/Icons}/PolylineIcon.d.ts +0 -0
  87. /package/dist/{Icons → types/Icons}/RectangleIcon.d.ts +0 -0
  88. /package/dist/{Icons → types/Icons}/SaveIcon.d.ts +0 -0
  89. /package/dist/{Providers → types/Providers}/EditorProvider.d.ts +0 -0
  90. /package/dist/{Providers → types/Providers}/UiProvider.d.ts +0 -0
  91. /package/dist/{Types.d.ts → types/Types.d.ts} +0 -0
  92. /package/dist/{Utils → types/Utils}/Dispatcher.d.ts +0 -0
  93. /package/dist/{Utils → types/Utils}/index.d.ts +0 -0
  94. /package/dist/{index.d.ts → types/index.d.ts} +0 -0
@@ -1,77 +0,0 @@
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
- };
@@ -1,75 +0,0 @@
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 newPolylinePoints = [...points, newPoint];
8
- setPoints(newPolylinePoints);
9
- if (newPolylinePoints.length > 0) {
10
- const line = new fabric.Line([
11
- newPolylinePoints[newPolylinePoints.length - 1].x,
12
- newPolylinePoints[newPolylinePoints.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 handleMouseDownPolyline = (event, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines) => {
27
- setIsDrawing(true);
28
- addPoint(event, canvas, activeColor, points, setPoints, lines, setLines);
29
- };
30
- export const handleMouseMovePolyline = (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 handleDoubleClickPolyline = (editorId, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines) => {
38
- if (points.length > 2) {
39
- const id = uuidv4();
40
- const polyline = new fabric.Polyline(points, {
41
- fill: 'transparent',
42
- stroke: activeColor,
43
- strokeWidth: 2,
44
- selectable: false,
45
- hasControls: true,
46
- lockRotation: false,
47
- id,
48
- });
49
- canvas.add(polyline);
50
- Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polyline" /* ToolEnum.Polyline */, shape: polyline });
51
- setPoints([]);
52
- for (const line of lines) {
53
- canvas.remove(line); // Remove temporary lines
54
- }
55
- setLines([]);
56
- setIsDrawing(false);
57
- }
58
- };
59
- export const copyPolyline = (editorId, canvas, polyline) => {
60
- const id = uuidv4();
61
- const copy = new fabric.Polyline(polyline.points, {
62
- top: polyline.top + 10,
63
- left: polyline.left + 10,
64
- fill: 'transparent',
65
- stroke: polyline.stroke,
66
- strokeWidth: polyline.strokeWidth,
67
- selectable: false,
68
- hasControls: true,
69
- hoverCursor: 'default',
70
- id,
71
- });
72
- canvas.add(copy);
73
- Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polyline" /* ToolEnum.Polyline */, shape: copy });
74
- return copy;
75
- };
@@ -1,73 +0,0 @@
1
- import * as fabric from 'fabric';
2
- import { v4 as uuidv4 } from 'uuid';
3
- import Dispatcher from '../../Utils/Dispatcher';
4
- export const handleMouseDownRect = (event, canvas, activeColor, setOriginX, setOriginY, setShape, setIsDrawing) => {
5
- const pointer = canvas.getScenePoint(event.e);
6
- setOriginX(pointer.x);
7
- setOriginY(pointer.y);
8
- const id = uuidv4();
9
- const newRectangle = new fabric.Rect({
10
- left: pointer.x,
11
- top: pointer.y,
12
- originX: 'left',
13
- originY: 'top',
14
- width: 0,
15
- height: 0,
16
- fill: 'transparent',
17
- stroke: activeColor,
18
- strokeWidth: 2,
19
- strokeUniform: true,
20
- selectable: false,
21
- hasControls: true,
22
- hoverCursor: 'default',
23
- id,
24
- });
25
- canvas.add(newRectangle);
26
- setShape(newRectangle);
27
- setIsDrawing(true);
28
- };
29
- export const handleMouseMoveRect = (event, canvas, originX, originY, shape, isDrawing) => {
30
- if (isDrawing && shape) {
31
- const pointer = canvas.getScenePoint(event.e);
32
- shape.set({
33
- width: Math.abs(originX - pointer.x),
34
- height: Math.abs(originY - pointer.y),
35
- });
36
- if (originX > pointer.x) {
37
- shape.set({ left: pointer.x });
38
- }
39
- if (originY > pointer.y) {
40
- shape.set({ top: pointer.y });
41
- }
42
- canvas.renderAll();
43
- }
44
- };
45
- export const handleMouseUpRect = (editorId, canvas, setIsDrawing, shape, setShape) => {
46
- setIsDrawing(false);
47
- shape.setCoords();
48
- Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id: shape.id, type: "rect" /* ToolEnum.Rectangle */, shape });
49
- setShape(null);
50
- canvas.defaultCursor = 'default';
51
- };
52
- export const copyRectangle = (editorId, canvas, rectangle) => {
53
- const id = uuidv4();
54
- const copy = new fabric.Rect({
55
- left: rectangle.left + 10,
56
- top: rectangle.top + 10,
57
- originX: 'left',
58
- originY: 'top',
59
- width: rectangle.width,
60
- height: rectangle.height,
61
- fill: 'transparent',
62
- stroke: rectangle.stroke,
63
- strokeWidth: rectangle.strokeWidth,
64
- strokeUniform: true,
65
- selectable: false,
66
- hasControls: true,
67
- hoverCursor: 'default',
68
- id,
69
- });
70
- canvas.add(copy);
71
- Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "rect" /* ToolEnum.Rectangle */, shape: copy });
72
- return copy;
73
- };
@@ -1,43 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { useContext } from 'react';
3
- import { useEditorContext } from '../../Providers/EditorProvider';
4
- import { UiContext } from '../../Providers/UiProvider';
5
- import { formatString } from '../../Utils';
6
- import { OperatorEnum } from './Types';
7
- const RoisInfo = () => {
8
- var _a;
9
- const { strings, Typography } = useContext(UiContext);
10
- const { configuration } = useEditorContext();
11
- if (!((_a = configuration.rois) === null || _a === void 0 ? void 0 : _a.length))
12
- return null;
13
- return (_jsxs("div", { children: [_jsxs(Typography, { component: "div", children: [strings.roisToBeDrawn, ":"] }), _jsx("ul", { children: configuration.rois.map((r) => {
14
- var _a, _b;
15
- let rule;
16
- const data = {
17
- role: r.label,
18
- type: r.type,
19
- threshold: (_a = r.multiplicity) === null || _a === void 0 ? void 0 : _a.threshold,
20
- };
21
- switch ((_b = r.multiplicity) === null || _b === void 0 ? void 0 : _b.operator) {
22
- case OperatorEnum.Eq:
23
- rule = formatString(strings.roiMultiplicityEqRule, data);
24
- break;
25
- case OperatorEnum.Lt:
26
- rule = formatString(strings.roiMultiplicityLtRule, data);
27
- break;
28
- case OperatorEnum.Lte:
29
- rule = formatString(strings.roiMultiplicityLteRule, data);
30
- break;
31
- case OperatorEnum.Gt:
32
- rule = formatString(strings.roiMultiplicityGtRule, data);
33
- break;
34
- case OperatorEnum.Gte:
35
- rule = formatString(strings.roiMultiplicityGteRule, data);
36
- break;
37
- default:
38
- rule = formatString(strings.roiMultiplicityNoRule, data);
39
- }
40
- return (_jsx("li", { children: _jsx(Typography, { children: rule }) }, r.role));
41
- }) })] }));
42
- };
43
- export default RoisInfo;
@@ -1,77 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useContext, useEffect, useState } from 'react';
3
- import { useEditorContext } from '../../Providers/EditorProvider';
4
- import { UiContext } from '../../Providers/UiProvider';
5
- import { css } from '../../Utils';
6
- import Dispatcher from '../../Utils/Dispatcher';
7
- import ParametersModalForm from './ParametersModalForm';
8
- import styles from './ShapesList.module.css';
9
- const ShapesList = () => {
10
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
11
- const { strings, Typography, IconButton, DeleteIcon, AnnotateIcon, CopyIcon, themeMode } = useContext(UiContext);
12
- const { shapes, removeShape, configuration, metadata, setMetadata, addShape, editorId } = useEditorContext();
13
- const [selected, setSelected] = useState([]);
14
- const [form, setForm] = useState({
15
- isOpen: false,
16
- shapeId: '',
17
- type: null,
18
- shape: null,
19
- });
20
- // open metadata form immediately after drawing the shape
21
- useEffect(() => {
22
- const openForm = (_, { id, type, shape }) => {
23
- setForm({ isOpen: true, shapeId: id, type, shape });
24
- };
25
- Dispatcher.register(`canvas:${editorId}:shapeAdded`, openForm);
26
- return () => {
27
- Dispatcher.unregister(`canvas:${editorId}:shapeAdded`, openForm);
28
- };
29
- }, [editorId]);
30
- useEffect(() => {
31
- const setSelectedShapes = (_, event) => { var _a; return setSelected((_a = event === null || event === void 0 ? void 0 : event.map((s) => s.id)) !== null && _a !== void 0 ? _a : []); };
32
- Dispatcher.register(`canvas:${editorId}:shapeSelected`, setSelectedShapes);
33
- return () => {
34
- Dispatcher.unregister(`canvas:${editorId}:shapeSelected`, setSelectedShapes);
35
- };
36
- }, [shapes, editorId]);
37
- const handleCopyShape = (id) => (evt) => {
38
- evt.stopPropagation();
39
- Dispatcher.emit(`canvas:${editorId}:copyShape`, id);
40
- };
41
- const handleRemoveShape = (id) => () => {
42
- Dispatcher.emit(`canvas:${editorId}:removeShape`, id);
43
- removeShape(id);
44
- };
45
- const handleSelectShape = (id) => () => {
46
- Dispatcher.emit(`canvas:${editorId}:selectShape`, id);
47
- };
48
- const handleEditShapeMetadata = (id) => () => {
49
- setForm({ isOpen: true, shapeId: id, type: null, shape: null });
50
- };
51
- const handleSubmitMetadata = (shapeId) => (data, properties) => {
52
- // if in creation mode, add the shape
53
- if (form.type !== null) {
54
- addShape(shapeId, form.type, form.shape);
55
- }
56
- setMetadata(Object.assign(Object.assign({}, metadata), { rois: [...metadata.rois.filter((r) => r.id !== shapeId), Object.assign({ id: shapeId, parameters: data }, properties)] }));
57
- setForm({ isOpen: false, shapeId: '', type: null, shape: null });
58
- };
59
- const handleCloseMetadataForm = () => {
60
- // if in creation mode do not add shape and delete shape from canvas
61
- if (form.type !== null) {
62
- Dispatcher.emit(`canvas:${editorId}:removeShape`, form.shapeId);
63
- }
64
- setForm({ isOpen: false, shapeId: '', type: null, shape: null });
65
- };
66
- const iconColor = themeMode === 'light' ? 'black' : 'white';
67
- return (_jsxs(_Fragment, { children: [_jsxs("table", { className: css('shapes-table', styles, themeMode), children: [Object.keys(shapes).length > 0 && (_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: _jsx(Typography, { style: { fontWeight: 'bold' }, children: strings.name }) }), _jsx("th", { children: _jsx(Typography, { style: { fontWeight: 'bold' }, children: strings.role }) }), _jsx("th", { children: _jsx(Typography, { style: { fontWeight: 'bold' }, children: strings.type }) }), _jsx("th", {})] }) })), _jsx("tbody", { children: Object.keys(shapes).map((id, idx) => {
68
- var _a;
69
- const m = metadata.rois.find((roi) => roi.id === id);
70
- return (_jsxs("tr", { onClick: handleSelectShape(id), className: selected.indexOf(id) > -1
71
- ? css('shapes-row-selected', styles, themeMode)
72
- : idx % 2 === 0
73
- ? css('shapes-row-even', styles, themeMode)
74
- : css('shapes-row-odd', styles, themeMode), children: [_jsx("td", { children: _jsxs("div", { className: styles.shapesTableName, children: [_jsx("div", { className: styles.shapesTableColor, style: { backgroundColor: shapes[id].shape.stroke } }), _jsx(Typography, { children: m === null || m === void 0 ? void 0 : m.name })] }) }), _jsx("td", { children: _jsx(Typography, { children: (_a = configuration.rois.find(r => r.role === (m === null || m === void 0 ? void 0 : m.role))) === null || _a === void 0 ? void 0 : _a.label }) }), _jsx("td", { children: _jsx(Typography, { children: strings[shapes[id].type] }) }), _jsxs("td", { children: [_jsx(IconButton, { onClick: handleCopyShape(id), children: _jsx(CopyIcon, { color: iconColor }) }), _jsx(IconButton, { onClick: handleEditShapeMetadata(id), children: _jsx(AnnotateIcon, { color: iconColor }) }), _jsx(IconButton, { onClick: handleRemoveShape(id), children: _jsx(DeleteIcon, { color: iconColor }) })] })] }, id));
75
- }) })] }), form.isOpen && (_jsx(ParametersModalForm, { shapeType: form.type || shapes[form.shapeId].type, shapeName: (_b = (_a = metadata.rois.find((roi) => roi.id === form.shapeId)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : '', shapeRole: (_d = (_c = metadata.rois.find((roi) => roi.id === form.shapeId)) === null || _c === void 0 ? void 0 : _c.role) !== null && _d !== void 0 ? _d : '', shapeId: form.shapeId, parameters: (_f = (_e = configuration.rois.find((roi) => roi.type === (form.type || shapes[form.shapeId].type))) === null || _e === void 0 ? void 0 : _e.parameters) !== null && _f !== void 0 ? _f : [], data: (_k = (_h = (_g = metadata.rois.find((roi) => roi.id === form.shapeId)) === null || _g === void 0 ? void 0 : _g.parameters) !== null && _h !== void 0 ? _h : (_j = configuration.rois.find((roi) => roi.type === (form.type || shapes[form.shapeId].type))) === null || _j === void 0 ? void 0 : _j.parameters) !== null && _k !== void 0 ? _k : [], title: strings.shapeParametersMetadata, onClose: handleCloseMetadataForm, onSubmit: handleSubmitMetadata(form.shapeId) }))] }));
76
- };
77
- export default ShapesList;
@@ -1,27 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useContext } from 'react';
3
- import PointerIcon from '../../Icons/PointerIcon';
4
- import PolygonIcon from '../../Icons/PolygonIcon';
5
- import PolylineIcon from '../../Icons/PolylineIcon';
6
- import RectangleIcon from '../../Icons/RectangleIcon';
7
- import { useEditorContext } from '../../Providers/EditorProvider';
8
- import { UiContext } from '../../Providers/UiProvider';
9
- import { css } from '../../Utils';
10
- import ColorPicker from './ColorPicker';
11
- import styles from './Toolbar.module.css';
12
- import { canDrawShape, enableRois } from './Utils';
13
- const Toolbar = () => {
14
- var _a;
15
- const { IconButton, themeMode, primaryColor, Typography, strings } = useContext(UiContext);
16
- const { activeTool, setActiveTool, configuration, shapes } = useEditorContext();
17
- const iconColor = (tool) => (tool === activeTool ? primaryColor : themeMode === 'light' ? 'black' : 'white');
18
- const setTool = (tool) => () => setActiveTool(tool);
19
- const hideForbiddenTools = (_a = configuration.options) === null || _a === void 0 ? void 0 : _a.hideForbiddenTools;
20
- const polylineEnabled = configuration.rois.find((r) => r.type === "polyline" /* ToolEnum.Polyline */) &&
21
- canDrawShape(configuration, "polyline" /* ToolEnum.Polyline */, shapes);
22
- const polygonEnabled = configuration.rois.find((r) => r.type === "polygon" /* ToolEnum.Polygon */) && canDrawShape(configuration, "polygon" /* ToolEnum.Polygon */, shapes);
23
- const rectangleEnabled = configuration.rois.find((r) => r.type === "rect" /* ToolEnum.Rectangle */) &&
24
- canDrawShape(configuration, "rect" /* ToolEnum.Rectangle */, shapes);
25
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: css('toolbar', styles, themeMode), children: enableRois(configuration) && (_jsxs(_Fragment, { children: [_jsx(IconButton, { onClick: setTool("pointer" /* ToolEnum.Pointer */), children: _jsx(PointerIcon, { color: iconColor("pointer" /* ToolEnum.Pointer */) }) }), (!hideForbiddenTools || polylineEnabled) && (_jsx(IconButton, { onClick: setTool("polyline" /* ToolEnum.Polyline */), disabled: !polylineEnabled, children: _jsx(PolylineIcon, { color: iconColor("polyline" /* ToolEnum.Polyline */) }) })), (!hideForbiddenTools || polygonEnabled) && (_jsx(IconButton, { onClick: setTool("polygon" /* ToolEnum.Polygon */), disabled: !polygonEnabled, children: _jsx(PolygonIcon, { color: iconColor("polygon" /* ToolEnum.Polygon */) }) })), (!hideForbiddenTools || rectangleEnabled) && (_jsx(IconButton, { onClick: setTool("rect" /* ToolEnum.Rectangle */), disabled: !rectangleEnabled, children: _jsx(RectangleIcon, { color: iconColor("rect" /* ToolEnum.Rectangle */) }) })), _jsx(ColorPicker, { style: { marginLeft: 'auto', marginRight: '.5rem' } })] })) }), enableRois(configuration) && (_jsx("div", { className: css('toolbar-helper', styles, themeMode), children: _jsxs(Typography, { children: [strings[activeTool], ": ", strings[`${activeTool}HelpText`]] }) }))] }));
26
- };
27
- export default Toolbar;
@@ -1,21 +0,0 @@
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 { enableMainMetadata } from './Utils';
7
- import SaveIcon from '../../Icons/SaveIcon';
8
- import ParametersModalForm from './ParametersModalForm';
9
- import styles from './TopBar.module.css';
10
- const TopBar = () => {
11
- const { themeMode, AnnotateIcon, Button, primaryFgColor, strings } = useContext(UiContext);
12
- const { configuration, onSubmit, metadata, setMetadata } = useEditorContext();
13
- const [form, setForm] = useState({ isOpen: false });
14
- const iconColor = themeMode === 'light' ? 'black' : 'white';
15
- const handleSubmitMetadata = (data) => {
16
- setMetadata(Object.assign(Object.assign({}, metadata), { parameters: data }));
17
- setForm({ isOpen: false });
18
- };
19
- return (_jsxs("div", { className: css('top-bar', styles, themeMode), 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 }))] }));
20
- };
21
- export default TopBar;
@@ -1,23 +0,0 @@
1
- export var DataTypeEnum;
2
- (function (DataTypeEnum) {
3
- DataTypeEnum["Integer"] = "int";
4
- DataTypeEnum["Float"] = "float";
5
- DataTypeEnum["String"] = "string";
6
- DataTypeEnum["Boolean"] = "bool";
7
- })(DataTypeEnum || (DataTypeEnum = {}));
8
- export var OperatorEnum;
9
- (function (OperatorEnum) {
10
- OperatorEnum["Lt"] = "lt";
11
- OperatorEnum["Lte"] = "lte";
12
- OperatorEnum["Gt"] = "gt";
13
- OperatorEnum["Gte"] = "gte";
14
- OperatorEnum["Eq"] = "eq";
15
- })(OperatorEnum || (OperatorEnum = {}));
16
- export var UpdateEventType;
17
- (function (UpdateEventType) {
18
- UpdateEventType["AddRoi"] = "AddRoi";
19
- UpdateEventType["RemoveRoi"] = "RemoveRoi";
20
- UpdateEventType["UpdateRoi"] = "UpdateRoi";
21
- UpdateEventType["UpdateRoiParameters"] = "UpdateRoiParameters";
22
- UpdateEventType["UpdateMainParameters"] = "UpdateMainParameters";
23
- })(UpdateEventType || (UpdateEventType = {}));
@@ -1,161 +0,0 @@
1
- import { abs2Perc, formatString } from '../../Utils';
2
- import { OperatorEnum, } from './Types';
3
- export const notify = {
4
- info: (message) => alert(`Info: ${message}`),
5
- warn: (message) => alert(`Warning: ${message}`),
6
- error: (message) => alert(`Error: ${message}`),
7
- success: (message) => alert(`Success: ${message}`),
8
- };
9
- export const enableRois = (configuration) => {
10
- return configuration.rois.length > 0;
11
- };
12
- export const enableMainMetadata = (configuration) => {
13
- return configuration.parameters.length > 0;
14
- };
15
- export const canDrawShape = (configuration, shapeType, shapes, notify, message) => {
16
- const rules = configuration.rois.filter((roi) => roi.type === shapeType);
17
- let currentShapeCount = Object.values(shapes).filter((s) => s.type === shapeType).length;
18
- for (let i = 0; i < rules.length; i++) {
19
- const rule = rules[i];
20
- if (rule.multiplicity) {
21
- switch (rule.multiplicity.operator) {
22
- case OperatorEnum.Eq:
23
- case OperatorEnum.Lte:
24
- if (currentShapeCount < rule.multiplicity.threshold) {
25
- return true;
26
- }
27
- currentShapeCount -= rule.multiplicity.threshold;
28
- break;
29
- case OperatorEnum.Lt:
30
- if (currentShapeCount < rule.multiplicity.threshold - 1) {
31
- return true;
32
- }
33
- currentShapeCount -= rule.multiplicity.threshold;
34
- break;
35
- default:
36
- return true;
37
- }
38
- }
39
- }
40
- if (notify) {
41
- notify.warn(message || '');
42
- }
43
- return false;
44
- };
45
- export const validateParametersForm = (parameters, fields, setErrors) => {
46
- const err = {};
47
- parameters.forEach((p) => {
48
- if (p.required && isEmpty(fields[p.codename])) {
49
- err[p.codename] = 'requiredField';
50
- }
51
- });
52
- if (Object.keys(err).length > 0) {
53
- setErrors(err);
54
- return false;
55
- }
56
- return true;
57
- };
58
- const isEmpty = (v) => {
59
- if (typeof v === 'string') {
60
- return v.length === 0;
61
- }
62
- if (Array.isArray(v)) {
63
- return v.length === 0;
64
- }
65
- return v === null || v === undefined;
66
- };
67
- export const validate = (configuration, shapes, metadata, strings) => {
68
- const errors = [];
69
- // check main parameters
70
- if (configuration.parameters.length) {
71
- if (metadata.parameters.find((p) => { var _a; return ((_a = configuration.parameters.find((p2) => p2.codename === p.codename)) === null || _a === void 0 ? void 0 : _a.required) && isEmpty(p.value); })) {
72
- errors.push(strings.missingRequiredValuesInMainParameters);
73
- }
74
- }
75
- // check rois number
76
- configuration.rois.forEach((roi) => {
77
- // check multiplicity
78
- if (roi.multiplicity) {
79
- switch (roi.multiplicity.operator) {
80
- case OperatorEnum.Eq:
81
- if ((metadata.rois || []).filter((m) => m.role === roi.role).length !== roi.multiplicity.threshold) {
82
- errors.push(formatString(strings.shapesOfRoleShouldBeEqualToThreshold, {
83
- role: String(roi.role),
84
- threshold: roi.multiplicity.threshold,
85
- }));
86
- }
87
- break;
88
- case OperatorEnum.Lt:
89
- if ((metadata.rois || []).filter((m) => m.role === roi.role).length >= roi.multiplicity.threshold) {
90
- errors.push(formatString(strings.shapesOfRoleShouldBeLessThanThreshold, {
91
- role: String(roi.role),
92
- threshold: roi.multiplicity.threshold,
93
- }));
94
- }
95
- break;
96
- case OperatorEnum.Lte:
97
- if ((metadata.rois || []).filter((m) => m.role === roi.role).length > roi.multiplicity.threshold) {
98
- errors.push(formatString(strings.shapesOfRoleShouldBeLessThanOrEqualToThreshold, {
99
- role: String(roi.role),
100
- threshold: roi.multiplicity.threshold,
101
- }));
102
- }
103
- break;
104
- case OperatorEnum.Gt:
105
- if ((metadata.rois || []).filter((m) => m.role === roi.role).length <= roi.multiplicity.threshold) {
106
- errors.push(formatString(strings.shapesOfRoleShouldBeGreaterThanThreshold, {
107
- role: String(roi.role),
108
- threshold: roi.multiplicity.threshold,
109
- }));
110
- }
111
- break;
112
- case OperatorEnum.Gte:
113
- if ((metadata.rois || []).filter((m) => m.role === roi.role).length < roi.multiplicity.threshold) {
114
- errors.push(formatString(strings.shapesOfRoleShouldBeGreaterThanOrEqualToThreshold, {
115
- role: String(roi.role),
116
- threshold: roi.multiplicity.threshold,
117
- }));
118
- }
119
- }
120
- }
121
- });
122
- // check rois metadata
123
- Object.keys(shapes).forEach((shapeId) => {
124
- var _a, _b;
125
- const type = shapes[shapeId].type;
126
- const confParameters = (_b = (_a = configuration.rois.find((r) => r.type === type)) === null || _a === void 0 ? void 0 : _a.parameters) !== null && _b !== void 0 ? _b : [];
127
- confParameters.forEach((p) => {
128
- var _a, _b;
129
- if (p.required &&
130
- isEmpty((_b = (_a = metadata.rois.find((r) => r.id === shapeId)) === null || _a === void 0 ? void 0 : _a.parameters.find((p) => p.codename === p.codename)) === null || _b === void 0 ? void 0 : _b.value)) {
131
- errors.push(strings.missingRequiredValuesInShapeParameters.replace('{id}', shapeId));
132
- }
133
- });
134
- });
135
- return [errors.length === 0, errors];
136
- };
137
- export const fabricShapeToOutputShape = (shape, type, imageSize) => {
138
- switch (type) {
139
- case "rect" /* ToolEnum.Rectangle */:
140
- return {
141
- top: abs2Perc(shape.top, imageSize.height),
142
- left: abs2Perc(shape.left, imageSize.width),
143
- width: abs2Perc(shape.width, imageSize.width),
144
- height: abs2Perc(shape.height, imageSize.height),
145
- color: shape.stroke,
146
- };
147
- case "polygon" /* ToolEnum.Polygon */:
148
- case "polyline" /* ToolEnum.Polyline */:
149
- return {
150
- points: shape
151
- .get('points')
152
- .map(({ x, y }) => ({
153
- x: abs2Perc(x, imageSize.width),
154
- y: abs2Perc(y, imageSize.height),
155
- })),
156
- top: abs2Perc(shape.top, imageSize.height),
157
- left: abs2Perc(shape.left, imageSize.width),
158
- color: shape.stroke,
159
- };
160
- }
161
- };