@configuratorware/configurator-admingui 1.37.3 → 1.38.0
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/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/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
package/App/Data.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.getErrorsFromValidatedDataObject = exports.validateDataObject = exports.DataValidator = exports["default"] = exports.whiteSpacePattern = void 0;
|
|
6
|
+
exports.getErrorsFromValidatedDataObject = exports.validateDataObject = exports.DataValidator = exports["default"] = exports.identifierPattern = exports.whiteSpacePattern = void 0;
|
|
7
7
|
|
|
8
8
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
9
9
|
|
|
@@ -29,6 +29,8 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
29
29
|
|
|
30
30
|
var whiteSpacePattern = /^[\S]+$/;
|
|
31
31
|
exports.whiteSpacePattern = whiteSpacePattern;
|
|
32
|
+
var identifierPattern = /^[A-za-z0-9_.-]+$/;
|
|
33
|
+
exports.identifierPattern = identifierPattern;
|
|
32
34
|
|
|
33
35
|
_validate.validate.validators.nonEmptyArray = function (value, options) {
|
|
34
36
|
if (options && options === true && (0, _isArray["default"])(value) && value.length !== 0) {
|
|
@@ -55,9 +57,7 @@ _validate.validate.validators.numericOrEmpty = function (value, options) {
|
|
|
55
57
|
};
|
|
56
58
|
|
|
57
59
|
_validate.validate.validators.identifier = function (value, options) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (options && options === true && typeof value === 'string' && value.match(pattern) && value.match(pattern)[0] === value) {
|
|
60
|
+
if (options && options === true && typeof value === 'string' && value.match(identifierPattern) && value.match(identifierPattern)[0] === value) {
|
|
61
61
|
return null;
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -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.0",
|
|
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.0",
|
|
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
|
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { connect } from "react-redux";
|
|
3
|
+
import { t } from '../../../App/i18n';
|
|
4
|
+
import Dialog from '../../../UIComponents/Dialog';
|
|
5
|
+
import FlatButton from '../../../UIComponents/FlatButton';
|
|
6
|
+
import TextField from '../../../UIComponents/TextField';
|
|
7
|
+
import IconButton from '../../../UIComponents/IconButton';
|
|
8
|
+
import Tooltip from '../../../UIComponents/Tooltip';
|
|
9
|
+
import CopyIcon from '@material-ui/icons/FileCopy';
|
|
10
|
+
import Actions from '../Reducers/Actions';
|
|
11
|
+
import IntlInputHoc from "../../../Components/FormFragments/IntlInput";
|
|
12
|
+
import { InputSwitch } from "../../../Components/Form";
|
|
13
|
+
import {identifierPattern} from "../../../App/Data";
|
|
14
|
+
import { showErrorMessage } from "../../../App/Reducers/Frame/Actions";
|
|
15
|
+
|
|
16
|
+
const IntlInput = IntlInputHoc(InputSwitch);
|
|
17
|
+
|
|
18
|
+
const CopyCreatorItemDialog = ({ data, selected, copyCreatorItem, clearSelection, reloadList, showErrorMessage }) => {
|
|
19
|
+
|
|
20
|
+
const [showEditor, setShowEditor] = useState(false);
|
|
21
|
+
const [identifier, setIdentifier] = useState('');
|
|
22
|
+
const [identifierError, setIdentifierError] = useState(null);
|
|
23
|
+
const [titles, setTitles] = useState([]);
|
|
24
|
+
const hasSelection = selected && selected.length === 1;
|
|
25
|
+
let hasOnlyCreatorItemsSelected = hasSelection;
|
|
26
|
+
if (hasSelection) {
|
|
27
|
+
selected.map(selectedIndex => hasOnlyCreatorItemsSelected = data[selectedIndex].configurationMode === 'creator');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const onTitleChange = (name, values) => {
|
|
31
|
+
setTitles(values);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const onIdentifierChange = (name, identifier) => {
|
|
35
|
+
setIdentifier(identifier);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const validateIdentifier = () => {
|
|
39
|
+
const isSameIdentifier = identifier === data[selected[0]].identifier;
|
|
40
|
+
if ( identifier.match(identifierPattern) &&
|
|
41
|
+
identifier.match(identifierPattern)[0] === identifier &&
|
|
42
|
+
!isSameIdentifier
|
|
43
|
+
) {
|
|
44
|
+
setIdentifierError(null);
|
|
45
|
+
} else {
|
|
46
|
+
setIdentifierError(t('customValidators.identifier'));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const onSave = async () => {
|
|
51
|
+
const saveResult = await copyCreatorItem(data[selected[0]].id, identifier, titles);
|
|
52
|
+
if (saveResult.error) {
|
|
53
|
+
showErrorMessage(t('entity.saveError'))
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
clearSelection();
|
|
57
|
+
reloadList();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!hasOnlyCreatorItemsSelected) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<>
|
|
67
|
+
<Tooltip title={t('item.copyCreatorItemDialogTitle')}>
|
|
68
|
+
<IconButton color={hasSelection ? 'primary' : ''}
|
|
69
|
+
onClick={() => setShowEditor(true)}
|
|
70
|
+
>
|
|
71
|
+
<CopyIcon />
|
|
72
|
+
</IconButton>
|
|
73
|
+
</Tooltip>
|
|
74
|
+
<Dialog
|
|
75
|
+
title={t('item.copyCreatorItemDialogTitle')}
|
|
76
|
+
actions={
|
|
77
|
+
<React.Fragment>
|
|
78
|
+
<FlatButton
|
|
79
|
+
label={t('cancel')}
|
|
80
|
+
onClick={() => setShowEditor(false)}
|
|
81
|
+
/>
|
|
82
|
+
<FlatButton
|
|
83
|
+
label={t('duplicate')}
|
|
84
|
+
primary={true}
|
|
85
|
+
onClick={onSave}
|
|
86
|
+
disabled={identifier === '' || identifierError !== null}
|
|
87
|
+
/>
|
|
88
|
+
</React.Fragment>
|
|
89
|
+
}
|
|
90
|
+
open={showEditor && hasOnlyCreatorItemsSelected}
|
|
91
|
+
>
|
|
92
|
+
<div style={{ display: 'flex', mindWidth: '620px', flexDirection: 'column' }}>
|
|
93
|
+
<TextField
|
|
94
|
+
label={t('item.copyItemIdentifier')}
|
|
95
|
+
onChange={(evt) => {
|
|
96
|
+
onIdentifierChange(name, evt.target.value);
|
|
97
|
+
}}
|
|
98
|
+
onBlur={validateIdentifier}
|
|
99
|
+
style={{ width: '100%' }}
|
|
100
|
+
error={identifierError !== null}
|
|
101
|
+
helperText={identifierError}
|
|
102
|
+
value={identifier}
|
|
103
|
+
type={'text'}
|
|
104
|
+
/>
|
|
105
|
+
<IntlInput
|
|
106
|
+
intl={{
|
|
107
|
+
name: 'title',
|
|
108
|
+
type: 'text',
|
|
109
|
+
}}
|
|
110
|
+
label={t('item.copyItemTitle')}
|
|
111
|
+
onChange={onTitleChange}
|
|
112
|
+
style={{ width: 200 }}
|
|
113
|
+
value={titles}
|
|
114
|
+
/>
|
|
115
|
+
</div>
|
|
116
|
+
</Dialog>
|
|
117
|
+
</>
|
|
118
|
+
)
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const mapDispatchToProps = (dispatch) => ({
|
|
122
|
+
copyCreatorItem: async (sourceItemId, newItemIdentifier, itemTexts) =>
|
|
123
|
+
await dispatch(Actions.copyCreatorItem(sourceItemId, newItemIdentifier, itemTexts)),
|
|
124
|
+
showErrorMessage: (errorMessage) => dispatch(showErrorMessage(errorMessage))
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
export default connect(
|
|
128
|
+
() => null,
|
|
129
|
+
mapDispatchToProps
|
|
130
|
+
)((CopyCreatorItemDialog));
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import Actions, { ITEM_LIST_KEY, ITEM_REDUCER_NAME } from '../Reducers/Actions';
|
|
3
3
|
import { T } from '../../../App/i18n';
|
|
4
|
+
import generateConnectedList from '../../../Components/DefaultConnectedList';
|
|
5
|
+
import ListItemStatusEditor from '../Components/ListItemStatusEditor';
|
|
6
|
+
import CopyCreatorItemDialog from "../Components/CopyCreatorItemDialog";
|
|
4
7
|
|
|
5
8
|
const columns = [
|
|
6
9
|
{
|
|
@@ -52,9 +55,6 @@ const listParams = {
|
|
|
52
55
|
orderdir: 'asc',
|
|
53
56
|
};
|
|
54
57
|
|
|
55
|
-
import generateConnectedList from '../../../Components/DefaultConnectedList';
|
|
56
|
-
import ListItemStatusEditor from '../Components/ListItemStatusEditor';
|
|
57
|
-
|
|
58
58
|
export const ConnectedItemList = generateConnectedList(
|
|
59
59
|
columns,
|
|
60
60
|
listParams,
|
|
@@ -74,7 +74,11 @@ const ItemList = ({ listProps, ...props }) => (
|
|
|
74
74
|
<ConnectedItemList
|
|
75
75
|
{...props}
|
|
76
76
|
listProps={{
|
|
77
|
-
renderAction: props =>
|
|
77
|
+
renderAction: props =>
|
|
78
|
+
<>
|
|
79
|
+
<ListItemStatusEditor {...props} />
|
|
80
|
+
<CopyCreatorItemDialog {...props} />
|
|
81
|
+
</>,
|
|
78
82
|
...listProps,
|
|
79
83
|
}}
|
|
80
84
|
/>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const ITEM_LIST_KEY = 'items';
|
|
2
2
|
export const ITEM_LIST_URL = 'items';
|
|
3
|
+
export const ITEM_COPY_URL = (id) => `items/${id}/duplicate`;
|
|
3
4
|
export const ITEM_STATUS_URL = 'items/status';
|
|
4
5
|
export const ITEM_DATA_KEY = 'item';
|
|
5
6
|
export const ITEM_REDUCER_NAME = 'itemData';
|
|
@@ -43,6 +44,13 @@ const setItemStatusForMultipleItems = (selectedItems, itemStatus) => (dispatch,
|
|
|
43
44
|
}))
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
const copyCreatorItem = (sourceItemId, newItemIdentifier, itemTexts) => (dispatch, getState) => {
|
|
48
|
+
return dispatch(apiActions.postData(ITEM_COPY_URL(sourceItemId), {
|
|
49
|
+
"identifier": newItemIdentifier,
|
|
50
|
+
itemTexts
|
|
51
|
+
}))
|
|
52
|
+
};
|
|
53
|
+
|
|
46
54
|
const setFieldData = (field, value) => (dispatch, getState) => {
|
|
47
55
|
const entityState = getState()[ITEM_REDUCER_NAME];
|
|
48
56
|
let configurationMode = entityState.data.configurationMode.value;
|
|
@@ -69,5 +77,6 @@ export default {
|
|
|
69
77
|
...actions,
|
|
70
78
|
setFieldData,
|
|
71
79
|
setItemStatusForMultipleItems,
|
|
72
|
-
loadItemStatus
|
|
80
|
+
loadItemStatus,
|
|
81
|
+
copyCreatorItem
|
|
73
82
|
};
|
|
@@ -18,7 +18,7 @@ require('../../App/i18n').use(
|
|
|
18
18
|
editDialogTitle: 'Edit selected entries',
|
|
19
19
|
editDialogHint:
|
|
20
20
|
'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.',
|
|
21
|
-
|
|
21
|
+
ItemClassifications: 'Product categories',
|
|
22
22
|
visualizationData: {
|
|
23
23
|
'2d': "2D",
|
|
24
24
|
'3d': "3D",
|
|
@@ -60,6 +60,9 @@ require('../../App/i18n').use(
|
|
|
60
60
|
dialogTitle: 'Edit core data',
|
|
61
61
|
},
|
|
62
62
|
},
|
|
63
|
+
copyCreatorItemDialogTitle: 'Copy selected product',
|
|
64
|
+
copyItemIdentifier: 'New identifier',
|
|
65
|
+
copyItemTitle: 'New title',
|
|
63
66
|
},
|
|
64
67
|
configuratorQuickView: {
|
|
65
68
|
buttonText: 'Preview',
|
|
@@ -98,9 +101,10 @@ require('../../App/i18n').use(
|
|
|
98
101
|
cancel: 'Abbrechen',
|
|
99
102
|
save: 'Speichern',
|
|
100
103
|
editDialogTitle: 'Gewählte Einträge bearbeiten',
|
|
104
|
+
duplicate: 'Duplizieren',
|
|
101
105
|
editDialogHint:
|
|
102
106
|
'Nutze die Checkboxen in der Liste und klicke dann dieses Icon,</br>um den Status für einen oder mehrere Einträge zu setzen.',
|
|
103
|
-
|
|
107
|
+
ItemClassifications: 'Produktkategorien',
|
|
104
108
|
visualizationData: {
|
|
105
109
|
'2d': "2D",
|
|
106
110
|
'3d': "3D",
|
|
@@ -123,6 +127,9 @@ require('../../App/i18n').use(
|
|
|
123
127
|
searchOrAddAttributeValue: 'Suche einen Attributwert oder lege einen neuen mit dem + an',
|
|
124
128
|
},
|
|
125
129
|
headline: 'Dieses Produkt ist folgendermaßen definiert:',
|
|
130
|
+
copyCreatorItemDialogTitle: 'Gewähltes Produkt kopieren',
|
|
131
|
+
copyItemIdentifier: 'Neuer Identifier',
|
|
132
|
+
copyItemTitle: 'Neuer Titel',
|
|
126
133
|
editorPopup: {
|
|
127
134
|
attribute: {
|
|
128
135
|
dialogTitle: 'Attribut hinzufügen',
|
|
@@ -4,12 +4,16 @@ export const ITEMCLASSIFICATION_REDUCER_NAME = 'itemclassificationData';
|
|
|
4
4
|
export const ITEMCLASSIFICATIONS_URL = 'itemclassifications';
|
|
5
5
|
|
|
6
6
|
import { generateDefaultActions } from '../../../App/Reducers/Entity/Actions';
|
|
7
|
+
import { customDispatchHandler } from '../../Item/DataStructures/Attributes/Actions';
|
|
7
8
|
|
|
8
9
|
const actions = generateDefaultActions(
|
|
9
10
|
ITEMCLASSIFICATION_LIST_KEY,
|
|
10
11
|
ITEMCLASSIFICATION_DATA_KEY,
|
|
11
12
|
ITEMCLASSIFICATION_REDUCER_NAME,
|
|
12
|
-
ITEMCLASSIFICATIONS_URL
|
|
13
|
+
ITEMCLASSIFICATIONS_URL,
|
|
14
|
+
{
|
|
15
|
+
customDispatchHandler,
|
|
16
|
+
}
|
|
13
17
|
);
|
|
14
18
|
|
|
15
19
|
export const { hideDetails, loadEntity, postData } = actions;
|