@configuratorware/configurator-admingui 1.37.3 → 1.38.1
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.
- package/App/Data.js +4 -4
- package/Screens/Designer/SubScreens/Visualization/Components/AreaEditor.js +89 -67
- package/Screens/Designer/SubScreens/Visualization/Components/AreaEditorForm.js +203 -0
- package/Screens/Designer/SubScreens/Visualization/Containers/Edit/DataLinks.js +15 -11
- package/Screens/Designer/SubScreens/Visualization/Containers/Edit/Edit.js +66 -10
- package/Screens/Designer/SubScreens/Visualization/Screen.js +1 -1
- package/Screens/Item/Components/CopyCreatorItemDialog.js +246 -0
- package/Screens/Item/Containers/Edit.js +1 -1
- package/Screens/Item/Containers/List.js +3 -1
- package/Screens/Item/Reducers/Actions.js +18 -2
- package/Screens/Item/Translations.js +10 -3
- package/Screens/Itemclassification/Reducers/Actions.js +5 -1
- package/package.json +2 -2
- package/src/App/Data.js +4 -3
- package/src/Screens/Designer/SubScreens/Visualization/Components/AreaEditor.js +30 -5
- package/src/Screens/Designer/SubScreens/Visualization/Components/AreaEditorForm.js +139 -0
- package/src/Screens/Designer/SubScreens/Visualization/Containers/Edit/DataLinks.js +14 -8
- package/src/Screens/Designer/SubScreens/Visualization/Containers/Edit/Edit.js +68 -10
- package/src/Screens/Designer/SubScreens/Visualization/Screen.js +1 -1
- package/src/Screens/Item/Components/CopyCreatorItemDialog.js +130 -0
- package/src/Screens/Item/Containers/Edit.js +1 -1
- package/src/Screens/Item/Containers/List.js +8 -4
- package/src/Screens/Item/Reducers/Actions.js +10 -1
- package/src/Screens/Item/Translations.js +9 -2
- package/src/Screens/Itemclassification/Reducers/Actions.js +5 -1
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports["default"] = void 0;
|
|
9
|
+
|
|
10
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
+
|
|
12
|
+
var _reactRedux = require("react-redux");
|
|
13
|
+
|
|
14
|
+
var _i18n = require("../../../App/i18n");
|
|
15
|
+
|
|
16
|
+
var _Dialog = _interopRequireDefault(require("../../../UIComponents/Dialog"));
|
|
17
|
+
|
|
18
|
+
var _FlatButton = _interopRequireDefault(require("../../../UIComponents/FlatButton"));
|
|
19
|
+
|
|
20
|
+
var _TextField = _interopRequireDefault(require("../../../UIComponents/TextField"));
|
|
21
|
+
|
|
22
|
+
var _IconButton = _interopRequireDefault(require("../../../UIComponents/IconButton"));
|
|
23
|
+
|
|
24
|
+
var _Tooltip = _interopRequireDefault(require("../../../UIComponents/Tooltip"));
|
|
25
|
+
|
|
26
|
+
var _FileCopy = _interopRequireDefault(require("@material-ui/icons/FileCopy"));
|
|
27
|
+
|
|
28
|
+
var _Actions = _interopRequireDefault(require("../Reducers/Actions"));
|
|
29
|
+
|
|
30
|
+
var _IntlInput = _interopRequireDefault(require("../../../Components/FormFragments/IntlInput"));
|
|
31
|
+
|
|
32
|
+
var _Form = require("../../../Components/Form");
|
|
33
|
+
|
|
34
|
+
var _Data = require("../../../App/Data");
|
|
35
|
+
|
|
36
|
+
var _Actions2 = require("../../../App/Reducers/Frame/Actions");
|
|
37
|
+
|
|
38
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
39
|
+
|
|
40
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
41
|
+
|
|
42
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
43
|
+
|
|
44
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
45
|
+
|
|
46
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
47
|
+
|
|
48
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
49
|
+
|
|
50
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
51
|
+
|
|
52
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
53
|
+
|
|
54
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
55
|
+
|
|
56
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
57
|
+
|
|
58
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
59
|
+
|
|
60
|
+
var IntlInput = (0, _IntlInput["default"])(_Form.InputSwitch);
|
|
61
|
+
|
|
62
|
+
var CopyCreatorItemDialog = function CopyCreatorItemDialog(_ref) {
|
|
63
|
+
var data = _ref.data,
|
|
64
|
+
selected = _ref.selected,
|
|
65
|
+
copyCreatorItem = _ref.copyCreatorItem,
|
|
66
|
+
clearSelection = _ref.clearSelection,
|
|
67
|
+
reloadList = _ref.reloadList,
|
|
68
|
+
showErrorMessage = _ref.showErrorMessage;
|
|
69
|
+
|
|
70
|
+
var _useState = (0, _react.useState)(false),
|
|
71
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
72
|
+
showEditor = _useState2[0],
|
|
73
|
+
setShowEditor = _useState2[1];
|
|
74
|
+
|
|
75
|
+
var _useState3 = (0, _react.useState)(''),
|
|
76
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
77
|
+
identifier = _useState4[0],
|
|
78
|
+
setIdentifier = _useState4[1];
|
|
79
|
+
|
|
80
|
+
var _useState5 = (0, _react.useState)(null),
|
|
81
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
82
|
+
identifierError = _useState6[0],
|
|
83
|
+
setIdentifierError = _useState6[1];
|
|
84
|
+
|
|
85
|
+
var _useState7 = (0, _react.useState)([]),
|
|
86
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
87
|
+
titles = _useState8[0],
|
|
88
|
+
setTitles = _useState8[1];
|
|
89
|
+
|
|
90
|
+
var hasSelection = selected && selected.length === 1;
|
|
91
|
+
var hasOnlyCreatorItemsSelected = hasSelection;
|
|
92
|
+
|
|
93
|
+
if (hasSelection) {
|
|
94
|
+
selected.map(function (selectedIndex) {
|
|
95
|
+
return hasOnlyCreatorItemsSelected = data[selectedIndex].configurationMode === 'creator';
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
var onTitleChange = function onTitleChange(name, values) {
|
|
100
|
+
setTitles(values);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
var onIdentifierChange = function onIdentifierChange(name, identifier) {
|
|
104
|
+
setIdentifier(identifier);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
var validateIdentifier = function validateIdentifier() {
|
|
108
|
+
var isSameIdentifier = identifier === data[selected[0]].identifier;
|
|
109
|
+
|
|
110
|
+
if (identifier.match(_Data.identifierPattern) && identifier.match(_Data.identifierPattern)[0] === identifier && !isSameIdentifier) {
|
|
111
|
+
setIdentifierError(null);
|
|
112
|
+
} else {
|
|
113
|
+
setIdentifierError((0, _i18n.t)('customValidators.identifier'));
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
var onSave = /*#__PURE__*/function () {
|
|
118
|
+
var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
|
|
119
|
+
var saveResult;
|
|
120
|
+
return regeneratorRuntime.wrap(function _callee$(_context) {
|
|
121
|
+
while (1) {
|
|
122
|
+
switch (_context.prev = _context.next) {
|
|
123
|
+
case 0:
|
|
124
|
+
_context.next = 2;
|
|
125
|
+
return copyCreatorItem(data[selected[0]].id, identifier, titles);
|
|
126
|
+
|
|
127
|
+
case 2:
|
|
128
|
+
saveResult = _context.sent;
|
|
129
|
+
|
|
130
|
+
if (saveResult.error) {
|
|
131
|
+
showErrorMessage((0, _i18n.t)('entity.saveError'));
|
|
132
|
+
} else {
|
|
133
|
+
clearSelection();
|
|
134
|
+
reloadList();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
case 4:
|
|
138
|
+
case "end":
|
|
139
|
+
return _context.stop();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}, _callee);
|
|
143
|
+
}));
|
|
144
|
+
|
|
145
|
+
return function onSave() {
|
|
146
|
+
return _ref2.apply(this, arguments);
|
|
147
|
+
};
|
|
148
|
+
}();
|
|
149
|
+
|
|
150
|
+
if (!hasOnlyCreatorItemsSelected) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_Tooltip["default"], {
|
|
155
|
+
title: (0, _i18n.t)('item.copyCreatorItemDialogTitle')
|
|
156
|
+
}, /*#__PURE__*/_react["default"].createElement(_IconButton["default"], {
|
|
157
|
+
color: hasSelection ? 'primary' : '',
|
|
158
|
+
onClick: function onClick() {
|
|
159
|
+
return setShowEditor(true);
|
|
160
|
+
}
|
|
161
|
+
}, /*#__PURE__*/_react["default"].createElement(_FileCopy["default"], null))), /*#__PURE__*/_react["default"].createElement(_Dialog["default"], {
|
|
162
|
+
title: (0, _i18n.t)('item.copyCreatorItemDialogTitle'),
|
|
163
|
+
actions: /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_FlatButton["default"], {
|
|
164
|
+
label: (0, _i18n.t)('cancel'),
|
|
165
|
+
onClick: function onClick() {
|
|
166
|
+
return setShowEditor(false);
|
|
167
|
+
}
|
|
168
|
+
}), /*#__PURE__*/_react["default"].createElement(_FlatButton["default"], {
|
|
169
|
+
label: (0, _i18n.t)('duplicate'),
|
|
170
|
+
primary: true,
|
|
171
|
+
onClick: onSave,
|
|
172
|
+
disabled: identifier === '' || identifierError !== null
|
|
173
|
+
})),
|
|
174
|
+
open: showEditor && hasOnlyCreatorItemsSelected
|
|
175
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
176
|
+
style: {
|
|
177
|
+
display: 'flex',
|
|
178
|
+
mindWidth: '620px',
|
|
179
|
+
flexDirection: 'column'
|
|
180
|
+
}
|
|
181
|
+
}, /*#__PURE__*/_react["default"].createElement(_TextField["default"], {
|
|
182
|
+
label: (0, _i18n.t)('item.copyItemIdentifier'),
|
|
183
|
+
onChange: function onChange(evt) {
|
|
184
|
+
onIdentifierChange(name, evt.target.value);
|
|
185
|
+
},
|
|
186
|
+
onBlur: validateIdentifier,
|
|
187
|
+
style: {
|
|
188
|
+
width: '100%'
|
|
189
|
+
},
|
|
190
|
+
error: identifierError !== null,
|
|
191
|
+
helperText: identifierError,
|
|
192
|
+
value: identifier,
|
|
193
|
+
type: 'text'
|
|
194
|
+
}), /*#__PURE__*/_react["default"].createElement(IntlInput, {
|
|
195
|
+
intl: {
|
|
196
|
+
name: 'title',
|
|
197
|
+
type: 'text'
|
|
198
|
+
},
|
|
199
|
+
label: (0, _i18n.t)('item.copyItemTitle'),
|
|
200
|
+
onChange: onTitleChange,
|
|
201
|
+
style: {
|
|
202
|
+
width: 200
|
|
203
|
+
},
|
|
204
|
+
value: titles
|
|
205
|
+
}))));
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
|
|
209
|
+
return {
|
|
210
|
+
copyCreatorItem: function () {
|
|
211
|
+
var _copyCreatorItem = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(sourceItemId, newItemIdentifier, itemTexts) {
|
|
212
|
+
return regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
213
|
+
while (1) {
|
|
214
|
+
switch (_context2.prev = _context2.next) {
|
|
215
|
+
case 0:
|
|
216
|
+
_context2.next = 2;
|
|
217
|
+
return dispatch(_Actions["default"].copyCreatorItem(sourceItemId, newItemIdentifier, itemTexts));
|
|
218
|
+
|
|
219
|
+
case 2:
|
|
220
|
+
return _context2.abrupt("return", _context2.sent);
|
|
221
|
+
|
|
222
|
+
case 3:
|
|
223
|
+
case "end":
|
|
224
|
+
return _context2.stop();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}, _callee2);
|
|
228
|
+
}));
|
|
229
|
+
|
|
230
|
+
function copyCreatorItem(_x, _x2, _x3) {
|
|
231
|
+
return _copyCreatorItem.apply(this, arguments);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return copyCreatorItem;
|
|
235
|
+
}(),
|
|
236
|
+
showErrorMessage: function showErrorMessage(errorMessage) {
|
|
237
|
+
return dispatch((0, _Actions2.showErrorMessage)(errorMessage));
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
var _default = (0, _reactRedux.connect)(function () {
|
|
243
|
+
return null;
|
|
244
|
+
}, mapDispatchToProps)(CopyCreatorItemDialog);
|
|
245
|
+
|
|
246
|
+
exports["default"] = _default;
|
|
@@ -17,6 +17,8 @@ var _DefaultConnectedList = _interopRequireDefault(require("../../../Components/
|
|
|
17
17
|
|
|
18
18
|
var _ListItemStatusEditor = _interopRequireDefault(require("../Components/ListItemStatusEditor"));
|
|
19
19
|
|
|
20
|
+
var _CopyCreatorItemDialog = _interopRequireDefault(require("../Components/CopyCreatorItemDialog"));
|
|
21
|
+
|
|
20
22
|
var _excluded = ["listProps"];
|
|
21
23
|
|
|
22
24
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -108,7 +110,7 @@ var ItemList = function ItemList(_ref) {
|
|
|
108
110
|
return /*#__PURE__*/_react["default"].createElement(ConnectedItemList, _extends({}, props, {
|
|
109
111
|
listProps: _objectSpread({
|
|
110
112
|
renderAction: function renderAction(props) {
|
|
111
|
-
return /*#__PURE__*/_react["default"].createElement(_ListItemStatusEditor["default"], props);
|
|
113
|
+
return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_ListItemStatusEditor["default"], props), /*#__PURE__*/_react["default"].createElement(_CopyCreatorItemDialog["default"], props));
|
|
112
114
|
}
|
|
113
115
|
}, listProps)
|
|
114
116
|
}));
|
|
@@ -5,7 +5,7 @@ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "functi
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports["default"] = exports.ITEM_REDUCER_NAME = exports.ITEM_DATA_KEY = exports.ITEM_STATUS_URL = exports.ITEM_LIST_URL = exports.ITEM_LIST_KEY = void 0;
|
|
8
|
+
exports["default"] = exports.ITEM_REDUCER_NAME = exports.ITEM_DATA_KEY = exports.ITEM_STATUS_URL = exports.ITEM_COPY_URL = exports.ITEM_LIST_URL = exports.ITEM_LIST_KEY = void 0;
|
|
9
9
|
|
|
10
10
|
var apiActions = _interopRequireWildcard(require("../../../App/Reducers/Api/Actions"));
|
|
11
11
|
|
|
@@ -27,6 +27,12 @@ var ITEM_LIST_KEY = 'items';
|
|
|
27
27
|
exports.ITEM_LIST_KEY = ITEM_LIST_KEY;
|
|
28
28
|
var ITEM_LIST_URL = 'items';
|
|
29
29
|
exports.ITEM_LIST_URL = ITEM_LIST_URL;
|
|
30
|
+
|
|
31
|
+
var ITEM_COPY_URL = function ITEM_COPY_URL(id) {
|
|
32
|
+
return "items/".concat(id, "/duplicate");
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
exports.ITEM_COPY_URL = ITEM_COPY_URL;
|
|
30
36
|
var ITEM_STATUS_URL = 'items/status';
|
|
31
37
|
exports.ITEM_STATUS_URL = ITEM_STATUS_URL;
|
|
32
38
|
var ITEM_DATA_KEY = 'item';
|
|
@@ -73,6 +79,15 @@ var setItemStatusForMultipleItems = function setItemStatusForMultipleItems(selec
|
|
|
73
79
|
};
|
|
74
80
|
};
|
|
75
81
|
|
|
82
|
+
var copyCreatorItem = function copyCreatorItem(sourceItemId, newItemIdentifier, itemTexts) {
|
|
83
|
+
return function (dispatch, getState) {
|
|
84
|
+
return dispatch(apiActions.postData(ITEM_COPY_URL(sourceItemId), {
|
|
85
|
+
"identifier": newItemIdentifier,
|
|
86
|
+
itemTexts: itemTexts
|
|
87
|
+
}));
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
76
91
|
var setFieldData = function setFieldData(field, value) {
|
|
77
92
|
return function (dispatch, getState) {
|
|
78
93
|
var entityState = getState()[ITEM_REDUCER_NAME];
|
|
@@ -91,7 +106,8 @@ var setFieldData = function setFieldData(field, value) {
|
|
|
91
106
|
var _default = _objectSpread(_objectSpread({}, actions), {}, {
|
|
92
107
|
setFieldData: setFieldData,
|
|
93
108
|
setItemStatusForMultipleItems: setItemStatusForMultipleItems,
|
|
94
|
-
loadItemStatus: loadItemStatus
|
|
109
|
+
loadItemStatus: loadItemStatus,
|
|
110
|
+
copyCreatorItem: copyCreatorItem
|
|
95
111
|
});
|
|
96
112
|
|
|
97
113
|
exports["default"] = _default;
|
|
@@ -17,7 +17,7 @@ require("../../App/i18n").use({
|
|
|
17
17
|
save: 'Save',
|
|
18
18
|
editDialogTitle: 'Edit selected entries',
|
|
19
19
|
editDialogHint: 'Use the checkboxes to select one or more entries in the list</br>and then click this icon to set the item status for them.',
|
|
20
|
-
|
|
20
|
+
ItemClassifications: 'Product categories',
|
|
21
21
|
visualizationData: {
|
|
22
22
|
'2d': "2D",
|
|
23
23
|
'3d': "3D",
|
|
@@ -56,7 +56,10 @@ require("../../App/i18n").use({
|
|
|
56
56
|
coreData: {
|
|
57
57
|
dialogTitle: 'Edit core data'
|
|
58
58
|
}
|
|
59
|
-
}
|
|
59
|
+
},
|
|
60
|
+
copyCreatorItemDialogTitle: 'Copy selected product',
|
|
61
|
+
copyItemIdentifier: 'New identifier',
|
|
62
|
+
copyItemTitle: 'New title'
|
|
60
63
|
},
|
|
61
64
|
configuratorQuickView: {
|
|
62
65
|
buttonText: 'Preview'
|
|
@@ -93,8 +96,9 @@ require("../../App/i18n").use({
|
|
|
93
96
|
cancel: 'Abbrechen',
|
|
94
97
|
save: 'Speichern',
|
|
95
98
|
editDialogTitle: 'Gewählte Einträge bearbeiten',
|
|
99
|
+
duplicate: 'Duplizieren',
|
|
96
100
|
editDialogHint: 'Nutze die Checkboxen in der Liste und klicke dann dieses Icon,</br>um den Status für einen oder mehrere Einträge zu setzen.',
|
|
97
|
-
|
|
101
|
+
ItemClassifications: 'Produktkategorien',
|
|
98
102
|
visualizationData: {
|
|
99
103
|
'2d': "2D",
|
|
100
104
|
'3d': "3D",
|
|
@@ -117,6 +121,9 @@ require("../../App/i18n").use({
|
|
|
117
121
|
searchOrAddAttributeValue: 'Suche einen Attributwert oder lege einen neuen mit dem + an'
|
|
118
122
|
},
|
|
119
123
|
headline: 'Dieses Produkt ist folgendermaßen definiert:',
|
|
124
|
+
copyCreatorItemDialogTitle: 'Gewähltes Produkt kopieren',
|
|
125
|
+
copyItemIdentifier: 'Neuer Identifier',
|
|
126
|
+
copyItemTitle: 'Neuer Titel',
|
|
120
127
|
editorPopup: {
|
|
121
128
|
attribute: {
|
|
122
129
|
dialogTitle: 'Attribut hinzufügen'
|
|
@@ -7,6 +7,8 @@ exports["default"] = exports.postData = exports.loadEntity = exports.hideDetails
|
|
|
7
7
|
|
|
8
8
|
var _Actions = require("../../../App/Reducers/Entity/Actions");
|
|
9
9
|
|
|
10
|
+
var _Actions2 = require("../../Item/DataStructures/Attributes/Actions");
|
|
11
|
+
|
|
10
12
|
var ITEMCLASSIFICATION_LIST_KEY = 'itemclassifications';
|
|
11
13
|
exports.ITEMCLASSIFICATION_LIST_KEY = ITEMCLASSIFICATION_LIST_KEY;
|
|
12
14
|
var ITEMCLASSIFICATION_DATA_KEY = 'itemclassification';
|
|
@@ -15,7 +17,9 @@ var ITEMCLASSIFICATION_REDUCER_NAME = 'itemclassificationData';
|
|
|
15
17
|
exports.ITEMCLASSIFICATION_REDUCER_NAME = ITEMCLASSIFICATION_REDUCER_NAME;
|
|
16
18
|
var ITEMCLASSIFICATIONS_URL = 'itemclassifications';
|
|
17
19
|
exports.ITEMCLASSIFICATIONS_URL = ITEMCLASSIFICATIONS_URL;
|
|
18
|
-
var actions = (0, _Actions.generateDefaultActions)(ITEMCLASSIFICATION_LIST_KEY, ITEMCLASSIFICATION_DATA_KEY, ITEMCLASSIFICATION_REDUCER_NAME, ITEMCLASSIFICATIONS_URL
|
|
20
|
+
var actions = (0, _Actions.generateDefaultActions)(ITEMCLASSIFICATION_LIST_KEY, ITEMCLASSIFICATION_DATA_KEY, ITEMCLASSIFICATION_REDUCER_NAME, ITEMCLASSIFICATIONS_URL, {
|
|
21
|
+
customDispatchHandler: _Actions2.customDispatchHandler
|
|
22
|
+
});
|
|
19
23
|
var hideDetails = actions.hideDetails,
|
|
20
24
|
loadEntity = actions.loadEntity,
|
|
21
25
|
postData = actions.postData;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@configuratorware/configurator-admingui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.38.1",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"private": false,
|
|
6
6
|
"dependencies": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"react-redux-i18n": "^1.9.3",
|
|
30
30
|
"react-router": "^3.2.6",
|
|
31
31
|
"react-sortable-hoc": "^1.11.0",
|
|
32
|
-
"redhotmagma-visualization": "1.
|
|
32
|
+
"redhotmagma-visualization": "1.38.1",
|
|
33
33
|
"redux": "^4.1.0",
|
|
34
34
|
"redux-logger": "^3.0.6",
|
|
35
35
|
"redux-persist": "^5.10.0",
|
package/src/App/Data.js
CHANGED
|
@@ -5,6 +5,8 @@ import { t } from './i18n';
|
|
|
5
5
|
|
|
6
6
|
export const whiteSpacePattern = /^[\S]+$/;
|
|
7
7
|
|
|
8
|
+
export const identifierPattern = /^[A-za-z0-9_.-]+$/;
|
|
9
|
+
|
|
8
10
|
validate.validators.nonEmptyArray = function(value, options) {
|
|
9
11
|
if (options && options === true && isArray(value) && value.length !== 0) {
|
|
10
12
|
return null;
|
|
@@ -30,13 +32,12 @@ validate.validators.numericOrEmpty = function (value, options) {
|
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
validate.validators.identifier = function(value, options) {
|
|
33
|
-
const pattern = /^[A-za-z0-9_.-]+$/;
|
|
34
35
|
if (
|
|
35
36
|
options &&
|
|
36
37
|
options === true &&
|
|
37
38
|
typeof value === 'string' &&
|
|
38
|
-
value.match(
|
|
39
|
-
value.match(
|
|
39
|
+
value.match(identifierPattern) &&
|
|
40
|
+
value.match(identifierPattern)[0] === value
|
|
40
41
|
) {
|
|
41
42
|
return null;
|
|
42
43
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import debounce from 'lodash/debounce';
|
|
4
|
+
import isEqual from 'lodash/isEqual';
|
|
4
5
|
import {
|
|
5
6
|
createImageObject,
|
|
6
7
|
draw,
|
|
@@ -32,13 +33,34 @@ export class AreaEditor extends React.Component {
|
|
|
32
33
|
activeControl = null;
|
|
33
34
|
backgroundImage = null;
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
componentDidMount() {
|
|
37
|
+
this.setupAreaEditor();
|
|
38
|
+
window.addEventListener('resize', this.setupAreaEditor);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
componentDidUpdate(prevProps, prevState, snapshot) {
|
|
42
|
+
prevProps.areaData !== this.props.areaData && this.setupAreaEditor();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
onChangeDebounced = debounce(prevArea => {
|
|
46
|
+
const { area } = this;
|
|
47
|
+
const { onChange } = this.props;
|
|
48
|
+
onChange && !isEqual(area, prevArea) && onChange();
|
|
49
|
+
}, 1000);
|
|
50
|
+
|
|
51
|
+
setupAreaEditor = async () => {
|
|
36
52
|
const canvas = this.canvasRef.current;
|
|
37
53
|
this.ctx = canvas.getContext('2d');
|
|
54
|
+
const { width } = canvas.parentElement.getBoundingClientRect();
|
|
55
|
+
const { backgroundImageElement } = this.props;
|
|
56
|
+
|
|
57
|
+
// resize the canvas to fit the texture aspect ratio
|
|
58
|
+
const textureAspectRatio = backgroundImageElement.width / backgroundImageElement.height;
|
|
59
|
+
canvas.width = width;
|
|
60
|
+
canvas.height = width / textureAspectRatio;
|
|
38
61
|
|
|
39
62
|
this.area = await this.createScaledArea();
|
|
40
63
|
|
|
41
|
-
const { backgroundImageElement } = this.props;
|
|
42
64
|
if (backgroundImageElement) {
|
|
43
65
|
this.backgroundImage = fitSize(
|
|
44
66
|
createImageObject(backgroundImageElement),
|
|
@@ -59,19 +81,22 @@ export class AreaEditor extends React.Component {
|
|
|
59
81
|
|
|
60
82
|
this.onRedraw();
|
|
61
83
|
},
|
|
62
|
-
controlFactory: object => setDefaultControls(object),
|
|
84
|
+
controlFactory: object => setDefaultControls(object, 20, 0),
|
|
63
85
|
onUpdate: ({ getData }) => {
|
|
64
86
|
const { object } = getData();
|
|
87
|
+
const { area } = this;
|
|
65
88
|
this.area = object;
|
|
89
|
+
this.onChangeDebounced(area);
|
|
66
90
|
},
|
|
67
91
|
});
|
|
68
92
|
|
|
69
93
|
this._movableArea.init();
|
|
70
94
|
|
|
71
95
|
this.onUpdate();
|
|
72
|
-
}
|
|
96
|
+
};
|
|
73
97
|
|
|
74
98
|
componentWillUnmount() {
|
|
99
|
+
window.removeEventListener('resize', this.setupAreaEditor);
|
|
75
100
|
this._movableArea.dispose();
|
|
76
101
|
}
|
|
77
102
|
|
|
@@ -144,6 +169,6 @@ export class AreaEditor extends React.Component {
|
|
|
144
169
|
canvasRef = React.createRef();
|
|
145
170
|
|
|
146
171
|
render() {
|
|
147
|
-
return <canvas ref={this.canvasRef}
|
|
172
|
+
return <canvas ref={this.canvasRef} style={{ border: '1px solid #000', maxWidth: '100%' }} />;
|
|
148
173
|
}
|
|
149
174
|
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import get from 'lodash/get';
|
|
3
|
+
import debounce from 'lodash/debounce';
|
|
4
|
+
import TextField from '@material-ui/core/TextField';
|
|
5
|
+
import { withStyles } from '@material-ui/core/styles';
|
|
6
|
+
import { t } from '../../../../../App/i18n';
|
|
7
|
+
|
|
8
|
+
const toNumber = value => Number(value) || 0;
|
|
9
|
+
|
|
10
|
+
const toRad = deg => (Math.PI * deg) / 180;
|
|
11
|
+
|
|
12
|
+
const toDeg = rad => ((180 * rad) / Math.PI).toFixed(2);
|
|
13
|
+
|
|
14
|
+
const formatters = {
|
|
15
|
+
angle: v => toDeg(toNumber(v)),
|
|
16
|
+
number: v => toNumber(v).toFixed(2),
|
|
17
|
+
boolean: v => !!v,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function persistEvent(fn) {
|
|
21
|
+
return function(evt) {
|
|
22
|
+
evt.persist();
|
|
23
|
+
fn(evt);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const NumberInput = withStyles({
|
|
28
|
+
root: {
|
|
29
|
+
maxWidth: 100,
|
|
30
|
+
marginRight: 20,
|
|
31
|
+
},
|
|
32
|
+
})(({ classes, onChange, value, ...props }) => {
|
|
33
|
+
const [_value, _setValue] = useState(value);
|
|
34
|
+
const [focused, setFocused] = useState(false);
|
|
35
|
+
const onFocus = () => setFocused(true);
|
|
36
|
+
const onBlur = useMemo(
|
|
37
|
+
() => () => {
|
|
38
|
+
_setValue(value);
|
|
39
|
+
setFocused(false);
|
|
40
|
+
},
|
|
41
|
+
[value]
|
|
42
|
+
);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
!focused && _setValue(value);
|
|
45
|
+
}, [value, focused]);
|
|
46
|
+
const onChangeDebounced = useMemo(() => persistEvent(debounce(onChange, 50)), [onChange]);
|
|
47
|
+
return (
|
|
48
|
+
<TextField
|
|
49
|
+
type="number"
|
|
50
|
+
className={classes.root}
|
|
51
|
+
onChange={evt => {
|
|
52
|
+
_setValue(evt.target.value);
|
|
53
|
+
onChangeDebounced(evt);
|
|
54
|
+
}}
|
|
55
|
+
onFocus={onFocus}
|
|
56
|
+
onBlur={onBlur}
|
|
57
|
+
value={_value}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
export const AreaEditorForm = withStyles({
|
|
64
|
+
sectionTitle: {
|
|
65
|
+
fontSize: '1.2em',
|
|
66
|
+
marginTop: '1.2em',
|
|
67
|
+
marginBottom: '0.6em',
|
|
68
|
+
},
|
|
69
|
+
groupTitle: {
|
|
70
|
+
marginTop: '0.6em',
|
|
71
|
+
},
|
|
72
|
+
})(({ designAreaData, onChange, className, classes }) => {
|
|
73
|
+
const numberChangeHandler = evt => {
|
|
74
|
+
if (evt.target.value) {
|
|
75
|
+
onChange(evt.target.name, toNumber(evt.target.value));
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const angleChangeHandler = evt => {
|
|
80
|
+
if (evt.target.value) {
|
|
81
|
+
onChange(evt.target.name, toRad(toNumber(evt.target.value)));
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const format = (path, formatter = formatters.number) => formatter(toNumber(get(designAreaData, path)));
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<div className={className}>
|
|
89
|
+
<div>
|
|
90
|
+
<NumberInput
|
|
91
|
+
name={'position.angle'}
|
|
92
|
+
label={t('designer.advancedEditor.rotation')}
|
|
93
|
+
onChange={angleChangeHandler}
|
|
94
|
+
value={format('position.angle', formatters.angle)}
|
|
95
|
+
/>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<div>
|
|
99
|
+
<div className={classes.groupTitle}>{t('designer.advancedEditor.scaling')}</div>
|
|
100
|
+
<NumberInput
|
|
101
|
+
name={'position.width'}
|
|
102
|
+
label={t('designer.advancedEditor.width')}
|
|
103
|
+
onChange={numberChangeHandler}
|
|
104
|
+
value={format('position.width')}
|
|
105
|
+
inputProps={{
|
|
106
|
+
min: 1,
|
|
107
|
+
}}
|
|
108
|
+
/>
|
|
109
|
+
<NumberInput
|
|
110
|
+
name={'position.height'}
|
|
111
|
+
label={t('designer.advancedEditor.height')}
|
|
112
|
+
onChange={numberChangeHandler}
|
|
113
|
+
value={format('position.height')}
|
|
114
|
+
inputProps={{
|
|
115
|
+
min: 1,
|
|
116
|
+
}}
|
|
117
|
+
/>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
<div>
|
|
121
|
+
<div className={classes.groupTitle}>{t('designer.advancedEditor.positioning')}</div>
|
|
122
|
+
<NumberInput
|
|
123
|
+
name={'position.x'}
|
|
124
|
+
label={'x'}
|
|
125
|
+
onChange={numberChangeHandler}
|
|
126
|
+
value={format('position.x')}
|
|
127
|
+
/>
|
|
128
|
+
<NumberInput
|
|
129
|
+
name={'position.y'}
|
|
130
|
+
label={'y'}
|
|
131
|
+
onChange={numberChangeHandler}
|
|
132
|
+
value={format('position.y')}
|
|
133
|
+
/>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
export default AreaEditorForm;
|