@iobroker/adapter-react-v5 6.0.3 → 6.0.5
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.
|
@@ -457,26 +457,25 @@ const styles = {
|
|
|
457
457
|
},
|
|
458
458
|
cellButtonsButton: {
|
|
459
459
|
display: 'inline-block',
|
|
460
|
-
opacity: 0.
|
|
460
|
+
opacity: 0.5,
|
|
461
461
|
width: SMALL_BUTTON_SIZE + 4,
|
|
462
462
|
height: SMALL_BUTTON_SIZE + 4,
|
|
463
463
|
'&:hover': {
|
|
464
464
|
opacity: 1,
|
|
465
465
|
},
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
marginTop: -2,
|
|
466
|
+
p: 0,
|
|
467
|
+
mt: '-2px',
|
|
469
468
|
},
|
|
470
469
|
cellButtonsEmptyButton: {
|
|
471
470
|
fontSize: 12,
|
|
472
471
|
},
|
|
473
472
|
cellButtonMinWidth: {
|
|
474
|
-
minWidth:
|
|
473
|
+
minWidth: 40,
|
|
475
474
|
},
|
|
476
475
|
cellButtonsButtonAlone: {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
476
|
+
ml: `${SMALL_BUTTON_SIZE + 20}px`,
|
|
477
|
+
pt: 0,
|
|
478
|
+
mt: '-2px',
|
|
480
479
|
},
|
|
481
480
|
cellButtonsButtonWithCustoms: (theme) => ({
|
|
482
481
|
color: theme.palette.mode === 'dark' ? theme.palette.primary.main : theme.palette.secondary.main,
|
|
@@ -596,6 +595,7 @@ const styles = {
|
|
|
596
595
|
},
|
|
597
596
|
aclText: {
|
|
598
597
|
fontSize: 13,
|
|
598
|
+
marginTop: 6,
|
|
599
599
|
},
|
|
600
600
|
rightsObject: {
|
|
601
601
|
color: '#55ff55',
|
|
@@ -1639,21 +1639,21 @@ function prepareSparkData(values, from) {
|
|
|
1639
1639
|
return v;
|
|
1640
1640
|
}
|
|
1641
1641
|
exports.ITEM_IMAGES = {
|
|
1642
|
-
state: react_1.default.createElement(IconState_1.default, { className: "itemIcon" }),
|
|
1643
|
-
channel: react_1.default.createElement(IconChannel_1.default, { className: "itemIcon" }),
|
|
1644
|
-
device: react_1.default.createElement(IconDevice_1.default, { className: "itemIcon" }),
|
|
1645
|
-
adapter: react_1.default.createElement(IconAdapter_1.default, { className: "itemIcon" }),
|
|
1646
|
-
meta: react_1.default.createElement(icons_material_1.Description, { className: "itemIcon" }),
|
|
1647
|
-
instance: react_1.default.createElement(IconInstance_1.default, { className: "itemIcon", style: { color: '#7da7ff' } }),
|
|
1648
|
-
enum: react_1.default.createElement(icons_material_1.ListAlt, { className: "itemIcon" }),
|
|
1649
|
-
chart: react_1.default.createElement(icons_material_1.ShowChart, { className: "itemIcon" }),
|
|
1650
|
-
config: react_1.default.createElement(icons_material_1.Settings, { className: "itemIcon" }),
|
|
1651
|
-
group: react_1.default.createElement(icons_material_1.SupervisedUserCircle, { className: "itemIcon" }),
|
|
1652
|
-
user: react_1.default.createElement(icons_material_1.PersonOutlined, { className: "itemIcon" }),
|
|
1653
|
-
host: react_1.default.createElement(icons_material_1.Router, { className: "itemIcon" }),
|
|
1654
|
-
schedule: react_1.default.createElement(icons_material_1.CalendarToday, { className: "itemIcon" }),
|
|
1655
|
-
script: react_1.default.createElement(icons_material_1.Code, { className: "itemIcon" }),
|
|
1656
|
-
folder: react_1.default.createElement(IconClosed_1.default, { className: "itemIcon itemIconFolder" }),
|
|
1642
|
+
state: react_1.default.createElement(IconState_1.default, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1643
|
+
channel: react_1.default.createElement(IconChannel_1.default, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1644
|
+
device: react_1.default.createElement(IconDevice_1.default, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1645
|
+
adapter: react_1.default.createElement(IconAdapter_1.default, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1646
|
+
meta: react_1.default.createElement(icons_material_1.Description, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1647
|
+
instance: react_1.default.createElement(IconInstance_1.default, { className: "itemIcon", style: { color: '#7da7ff', verticalAlign: 'middle' } }),
|
|
1648
|
+
enum: react_1.default.createElement(icons_material_1.ListAlt, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1649
|
+
chart: react_1.default.createElement(icons_material_1.ShowChart, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1650
|
+
config: react_1.default.createElement(icons_material_1.Settings, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1651
|
+
group: react_1.default.createElement(icons_material_1.SupervisedUserCircle, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1652
|
+
user: react_1.default.createElement(icons_material_1.PersonOutlined, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1653
|
+
host: react_1.default.createElement(icons_material_1.Router, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1654
|
+
schedule: react_1.default.createElement(icons_material_1.CalendarToday, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1655
|
+
script: react_1.default.createElement(icons_material_1.Code, { className: "itemIcon", style: { verticalAlign: 'middle' } }),
|
|
1656
|
+
folder: react_1.default.createElement(IconClosed_1.default, { className: "itemIcon itemIconFolder", style: { verticalAlign: 'middle' } }),
|
|
1657
1657
|
};
|
|
1658
1658
|
const SCREEN_WIDTHS = {
|
|
1659
1659
|
// extra-small: 0px
|
|
@@ -2557,10 +2557,12 @@ class ObjectBrowserClass extends react_1.Component {
|
|
|
2557
2557
|
this.lastSelectedItems = [...this.state.selected];
|
|
2558
2558
|
if (this.state.selected && this.state.selected.length) {
|
|
2559
2559
|
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectSelected`, JSON.stringify(this.lastSelectedItems));
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2560
|
+
if (this.lastSelectedItems.length === 1 && this.objects[this.lastSelectedItems[0]]) {
|
|
2561
|
+
const name = this.lastSelectedItems.length === 1
|
|
2562
|
+
? Utils_1.default.getObjectName(this.objects, this.lastSelectedItems[0], null, { language: this.props.lang })
|
|
2563
|
+
: '';
|
|
2564
|
+
this.props.onSelect && this.props.onSelect(this.lastSelectedItems, name, isDouble);
|
|
2565
|
+
}
|
|
2564
2566
|
}
|
|
2565
2567
|
else {
|
|
2566
2568
|
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectSelected`, '');
|
|
@@ -3622,8 +3624,9 @@ class ObjectBrowserClass extends react_1.Component {
|
|
|
3622
3624
|
var _b, _c, _d;
|
|
3623
3625
|
if (!item.data.obj) {
|
|
3624
3626
|
return this.props.onObjectDelete || this.props.objectEditOfAccessControl ? react_1.default.createElement("div", { style: styles.buttonDiv },
|
|
3625
|
-
this.state.filter.expertMode && this.props.objectEditOfAccessControl ? react_1.default.createElement(material_1.IconButton, { sx: Object.assign(Object.assign(Object.assign({}, styles.cellButtonsButton), styles.cellButtonsEmptyButton), styles.cellButtonMinWidth), onClick: () => this.setState({ modalEditOfAccess: true, modalEditOfAccessObjData: item.data }), size: "large" },
|
|
3626
|
-
|
|
3627
|
+
this.state.filter.expertMode && this.props.objectEditOfAccessControl ? react_1.default.createElement(material_1.IconButton, { sx: Object.assign(Object.assign(Object.assign({}, styles.cellButtonsButton), styles.cellButtonsEmptyButton), styles.cellButtonMinWidth), onClick: () => this.setState({ modalEditOfAccess: true, modalEditOfAccessObjData: item.data }), size: "large" },
|
|
3628
|
+
react_1.default.createElement("div", { style: { height: 15 } }, "---")) : null,
|
|
3629
|
+
this.props.onObjectDelete && item.children && item.children.length ? react_1.default.createElement(material_1.IconButton, { sx: Object.assign(Object.assign({}, styles.cellButtonsButton), styles.cellButtonsButtonAlone), size: "small", "aria-label": "delete", title: this.texts.deleteObject, onClick: () => {
|
|
3627
3630
|
var _b;
|
|
3628
3631
|
// calculate the number of children
|
|
3629
3632
|
const keys = Object.keys(this.objects);
|
|
@@ -3655,18 +3658,18 @@ class ObjectBrowserClass extends react_1.Component {
|
|
|
3655
3658
|
const showEdit = this.state.filter.expertMode || _a.isNonExpertId(item.data.id);
|
|
3656
3659
|
return [
|
|
3657
3660
|
this.state.filter.expertMode && this.props.objectEditOfAccessControl ? react_1.default.createElement(material_1.Tooltip, { key: "acl", title: item.data.aclTooltip, componentsProps: { popper: { sx: styles.tooltip } } },
|
|
3658
|
-
react_1.default.createElement(material_1.IconButton, {
|
|
3661
|
+
react_1.default.createElement(material_1.IconButton, { sx: Object.assign(Object.assign(Object.assign({}, styles.cellButtonsButton), styles.cellButtonMinWidth), { opacity: 1 }), onClick: () => this.setState({ modalEditOfAccess: true, modalEditOfAccessObjData: item.data }), size: "large" },
|
|
3659
3662
|
react_1.default.createElement("div", { style: styles.aclText }, Number.isNaN(Number(acl))
|
|
3660
3663
|
? Number(aclSystemConfig).toString(16)
|
|
3661
3664
|
: Number(acl).toString(16)))) :
|
|
3662
3665
|
react_1.default.createElement("div", { key: "aclEmpty", style: styles.cellButtonMinWidth }),
|
|
3663
|
-
showEdit ? react_1.default.createElement(material_1.IconButton, { key: "edit",
|
|
3666
|
+
showEdit ? react_1.default.createElement(material_1.IconButton, { key: "edit", sx: Object.assign(Object.assign({}, styles.cellButtonsButton), styles.cellButtonMinWidth), size: "small", "aria-label": "edit", title: this.texts.editObject, onClick: () => {
|
|
3664
3667
|
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectSelected`, id);
|
|
3665
3668
|
this.setState({ editObjectDialog: id, editObjectAlias: false });
|
|
3666
3669
|
} },
|
|
3667
3670
|
react_1.default.createElement(icons_material_1.Edit, { style: styles.cellButtonsButtonIcon })) :
|
|
3668
|
-
react_1.default.createElement("div",
|
|
3669
|
-
this.props.onObjectDelete && (((_b = item.children) === null || _b === void 0 ? void 0 : _b.length) || !((_c = item.data.obj.common) === null || _c === void 0 ? void 0 : _c.dontDelete)) ? react_1.default.createElement(material_1.IconButton, { key: "delete",
|
|
3671
|
+
react_1.default.createElement(material_1.Box, { component: "div", key: "editDisabled", sx: styles.cellButtonsButton }),
|
|
3672
|
+
this.props.onObjectDelete && (((_b = item.children) === null || _b === void 0 ? void 0 : _b.length) || !((_c = item.data.obj.common) === null || _c === void 0 ? void 0 : _c.dontDelete)) ? react_1.default.createElement(material_1.IconButton, { key: "delete", sx: styles.cellButtonsButton, size: "small", "aria-label": "delete", onClick: () => {
|
|
3670
3673
|
var _b, _c, _d;
|
|
3671
3674
|
const keys = Object.keys(this.objects);
|
|
3672
3675
|
keys.sort();
|
|
@@ -3687,7 +3690,7 @@ class ObjectBrowserClass extends react_1.Component {
|
|
|
3687
3690
|
this.info.hasSomeCustoms &&
|
|
3688
3691
|
item.data.obj.type === 'state' &&
|
|
3689
3692
|
// @ts-expect-error deprecated from js-controller 6
|
|
3690
|
-
((_d = item.data.obj.common) === null || _d === void 0 ? void 0 : _d.type) !== 'file' ? react_1.default.createElement(material_1.IconButton, {
|
|
3693
|
+
((_d = item.data.obj.common) === null || _d === void 0 ? void 0 : _d.type) !== 'file' ? react_1.default.createElement(material_1.IconButton, { sx: Object.assign(Object.assign({}, styles.cellButtonsButton), (item.data.hasCustoms
|
|
3691
3694
|
? this.styles.cellButtonsButtonWithCustoms
|
|
3692
3695
|
: styles.cellButtonsButtonWithoutCustoms)), key: "custom", size: "small", "aria-label": "config", title: this.texts.customConfig, onClick: () => {
|
|
3693
3696
|
var _b;
|
|
@@ -3755,7 +3758,6 @@ class ObjectBrowserClass extends react_1.Component {
|
|
|
3755
3758
|
var _b, _c;
|
|
3756
3759
|
const obj = this.objects[id];
|
|
3757
3760
|
const state = this.states[id];
|
|
3758
|
-
const classes = styles;
|
|
3759
3761
|
const { valFull, fileViewer } = formatValue({
|
|
3760
3762
|
state,
|
|
3761
3763
|
obj: obj,
|
|
@@ -3767,7 +3769,7 @@ class ObjectBrowserClass extends react_1.Component {
|
|
|
3767
3769
|
const valFullRx = [];
|
|
3768
3770
|
valFull === null || valFull === void 0 ? void 0 : valFull.forEach(_item => {
|
|
3769
3771
|
if (_item.t === this.texts.quality && state.q) {
|
|
3770
|
-
valFullRx.push(react_1.default.createElement("div", { style:
|
|
3772
|
+
valFullRx.push(react_1.default.createElement("div", { style: styles.cellValueTooltipBoth, key: _item.t },
|
|
3771
3773
|
_item.t,
|
|
3772
3774
|
":\u00A0",
|
|
3773
3775
|
_item.v));
|
|
@@ -3775,15 +3777,15 @@ class ObjectBrowserClass extends react_1.Component {
|
|
|
3775
3777
|
!_item.nbr && valFullRx.push(react_1.default.createElement("br", { key: `${_item.t}_br` }));
|
|
3776
3778
|
}
|
|
3777
3779
|
else {
|
|
3778
|
-
valFullRx.push(react_1.default.createElement("div", { style:
|
|
3780
|
+
valFullRx.push(react_1.default.createElement("div", { style: styles.cellValueTooltipTitle, key: _item.t },
|
|
3779
3781
|
_item.t,
|
|
3780
3782
|
":\u00A0"));
|
|
3781
|
-
valFullRx.push(react_1.default.createElement("div", { style:
|
|
3783
|
+
valFullRx.push(react_1.default.createElement("div", { style: styles.cellValueTooltipValue, key: `${_item.t}_v` }, _item.v));
|
|
3782
3784
|
!_item.nbr && valFullRx.push(react_1.default.createElement("br", { key: `${_item.t}_br` }));
|
|
3783
3785
|
}
|
|
3784
3786
|
});
|
|
3785
3787
|
if (fileViewer === 'image') {
|
|
3786
|
-
valFullRx.push(react_1.default.createElement("img", { style:
|
|
3788
|
+
valFullRx.push(react_1.default.createElement("img", { style: styles.cellValueTooltipImage, src: state.val, alt: id }));
|
|
3787
3789
|
}
|
|
3788
3790
|
else if (this.defaultHistory &&
|
|
3789
3791
|
((_c = (_b = this.objects[id]) === null || _b === void 0 ? void 0 : _b.common) === null || _c === void 0 ? void 0 : _c.custom) &&
|
|
@@ -5297,7 +5299,7 @@ class ObjectBrowserClass extends react_1.Component {
|
|
|
5297
5299
|
: typeof this.edit.val;
|
|
5298
5300
|
const role = this.objects[this.edit.id].common.role;
|
|
5299
5301
|
const ObjectBrowserValue = this.props.objectBrowserValue;
|
|
5300
|
-
return react_1.default.createElement(ObjectBrowserValue, { t: this.props.t, lang: this.props.lang, type: type, role: role || '', states: Utils_1.default.getStates(this.objects[this.edit.id]), themeType: this.props.themeType, expertMode: !!this.state.filter.expertMode, value: this.edit.val, socket: this.props.socket, object: this.objects[this.edit.id], defaultHistory: this.defaultHistory, dateFormat: this.props.dateFormat || this.systemConfig.common.dateFormat, isFloatComma: this.props.isFloatComma === undefined ? this.systemConfig.common.isFloatComma : this.props.isFloatComma, onClose: (res) => {
|
|
5302
|
+
return react_1.default.createElement(ObjectBrowserValue, { t: this.props.t, lang: this.props.lang, type: type, role: role || '', states: Utils_1.default.getStates(this.objects[this.edit.id]), themeType: this.props.themeType, theme: this.props.theme, expertMode: !!this.state.filter.expertMode, value: this.edit.val, socket: this.props.socket, object: this.objects[this.edit.id], defaultHistory: this.defaultHistory, dateFormat: this.props.dateFormat || this.systemConfig.common.dateFormat, isFloatComma: this.props.isFloatComma === undefined ? this.systemConfig.common.isFloatComma : this.props.isFloatComma, onClose: (res) => {
|
|
5301
5303
|
this.setState({ updateOpened: false });
|
|
5302
5304
|
res && this.onUpdate(res);
|
|
5303
5305
|
} });
|
|
@@ -10,7 +10,8 @@ interface TableResizeProps {
|
|
|
10
10
|
ready?: boolean;
|
|
11
11
|
stickyHeader?: boolean;
|
|
12
12
|
size?: 'small' | 'medium';
|
|
13
|
-
className
|
|
13
|
+
className?: string;
|
|
14
|
+
sx?: Record<string, any>;
|
|
14
15
|
style?: React.CSSProperties;
|
|
15
16
|
initialWidths?: (number | 'auto')[];
|
|
16
17
|
minWidths?: number[];
|
|
@@ -220,7 +220,7 @@ class TableResize extends react_1.Component {
|
|
|
220
220
|
return react_1.default.createElement(material_1.Skeleton, null);
|
|
221
221
|
}
|
|
222
222
|
const style = { gridTemplateColumns: this.resizerApplyWidths() };
|
|
223
|
-
return react_1.default.createElement(material_1.Table, { stickyHeader: this.props.stickyHeader, size: this.props.size || 'small', className: this.props.className, ref: this.resizerRefTable, style: (Object.assign(Object.assign({}, this.props.style ||
|
|
223
|
+
return react_1.default.createElement(material_1.Table, { stickyHeader: this.props.stickyHeader, size: this.props.size || 'small', className: this.props.className, sx: this.props.sx, ref: this.resizerRefTable, style: (Object.assign(Object.assign({}, (this.props.style || undefined)), style)) }, this.props.children);
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
exports.default = TableResize;
|
package/Components/Utils.js
CHANGED
|
@@ -116,7 +116,7 @@ class Utils {
|
|
|
116
116
|
text = text[0] + text.substring(1).toLowerCase();
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
|
-
else if (!isDesc && item.common) {
|
|
119
|
+
else if (!isDesc && (item === null || item === void 0 ? void 0 : item.common)) {
|
|
120
120
|
const textObj = item.common.name || item.common.desc;
|
|
121
121
|
if (textObj && typeof textObj === 'object') {
|
|
122
122
|
text = (options.language && textObj[options.language]) || textObj.en || textObj.de || textObj.ru || '';
|
|
@@ -1308,14 +1308,7 @@ class Utils {
|
|
|
1308
1308
|
text = `${dateObj.getFullYear()}-${mm}-${dd}`;
|
|
1309
1309
|
}
|
|
1310
1310
|
// time
|
|
1311
|
-
|
|
1312
|
-
text += ` ${v}`;
|
|
1313
|
-
v = dateObj.getMinutes().toString().toString();
|
|
1314
|
-
text += `:${v}`;
|
|
1315
|
-
v = dateObj.getSeconds().toString().padStart(2, '0');
|
|
1316
|
-
text += `:${v}`;
|
|
1317
|
-
v = dateObj.getMilliseconds().toString().padStart(3, '0');
|
|
1318
|
-
text += `.${v}`;
|
|
1311
|
+
text += ` ${dateObj.getHours().toString().padStart(2, '0')}:${dateObj.getMinutes().toString().padStart(2, '0')}:${dateObj.getSeconds().toString().padStart(2, '0')}.${dateObj.getMilliseconds().toString().padStart(3, '0')}`;
|
|
1319
1312
|
return text;
|
|
1320
1313
|
}
|
|
1321
1314
|
/*
|
package/README.md
CHANGED
|
@@ -759,7 +759,7 @@ The best practice is to replace `padding` with `p` and `margin` with `m`, so you
|
|
|
759
759
|
Before: `<Tooltip title={this.props.t('ra_Refresh tree')} classes={{ popper: styles.tooltip }}>`
|
|
760
760
|
|
|
761
761
|
After: `<Tooltip title={this.props.t('ra_Refresh tree')} componentsProps={{ popper: { sx: { pointerEvents: 'none' } } }}>`
|
|
762
|
-
Or: `<Tooltip title={this.props.t('ra_Refresh tree')}
|
|
762
|
+
Or: `<Tooltip title={this.props.t('ra_Refresh tree')} elr>`
|
|
763
763
|
|
|
764
764
|
Before. `<AccordionSummary classes={{ root: styles.rootStyle, content: styles.content }}>`
|
|
765
765
|
|
|
@@ -771,7 +771,10 @@ The best practice is to replace `padding` with `p` and `margin` with `m`, so you
|
|
|
771
771
|
-->
|
|
772
772
|
|
|
773
773
|
## Changelog
|
|
774
|
-
### 6.0.
|
|
774
|
+
### 6.0.5 (2024-06-24)
|
|
775
|
+
* (bluefox) Synchronised with admin
|
|
776
|
+
|
|
777
|
+
### 6.0.4 (2024-06-21)
|
|
775
778
|
* (bluefox) Removed the usage of `withStyles` in favor of `sx` and `style` properties (see [Migration from v5 to v6](#migration-from-v5-to-v6)
|
|
776
779
|
* (bluefox) (BREAKING) Higher version of `@mui/material` (5.15.20) is used
|
|
777
780
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iobroker/adapter-react-v5",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.5",
|
|
4
4
|
"description": "React classes to develop admin interfaces for ioBroker with react.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Denis Haev (bluefox)",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"@iobroker/js-controller-common-db": "^6.0.5",
|
|
36
36
|
"@mui/icons-material": "^5.15.20",
|
|
37
37
|
"@mui/material": "^5.15.20",
|
|
38
|
-
"@mui/x-date-pickers": "^7.7.
|
|
39
|
-
"@sentry/browser": "^8.
|
|
38
|
+
"@mui/x-date-pickers": "^7.7.1",
|
|
39
|
+
"@sentry/browser": "^8.11.0",
|
|
40
40
|
"react-color": "^2.19.3",
|
|
41
41
|
"react-colorful": "^5.6.1",
|
|
42
42
|
"react-cropper": "^2.3.3",
|