@configuratorware/configurator-admingui 1.39.0 → 1.39.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.
Files changed (35) hide show
  1. package/Components/FormFragments/InputWithSource.js +14 -2
  2. package/Components/FormFragments/Select.js +5 -3
  3. package/Screens/Attribute/Containers/Edit.js +7 -0
  4. package/Screens/Attribute/Reducers/Reducer.js +4 -1
  5. package/Screens/Attribute/Translations.js +6 -2
  6. package/Screens/Client/Containers/Edit.js +4 -0
  7. package/Screens/Client/Reducers/Reducer.js +3 -0
  8. package/Screens/Client/Translations.js +1 -0
  9. package/Screens/CurrentClient/Containers/Edit.js +4 -0
  10. package/Screens/CurrentClient/Reducers/Reducer.js +3 -0
  11. package/Screens/DefaultClient/Containers/Edit.js +4 -0
  12. package/Screens/DefaultClient/Reducers/Reducer.js +3 -0
  13. package/Screens/Designer/SubScreens/Visualization/Containers/Edit/Edit.js +17 -10
  14. package/Screens/PriceTypes/Containers/Edit.js +36 -10
  15. package/Screens/PriceTypes/Reducers/Reducer.js +2 -2
  16. package/Screens/PriceTypes/Translations.js +14 -0
  17. package/package.json +3 -3
  18. package/scripts/cpPublic.js +32 -0
  19. package/src/Components/FormFragments/InputWithSource.js +3 -0
  20. package/src/Components/FormFragments/Select.js +10 -4
  21. package/src/Screens/Attribute/Containers/Edit.js +7 -0
  22. package/src/Screens/Attribute/Reducers/Reducer.js +1 -0
  23. package/src/Screens/Attribute/Translations.js +4 -0
  24. package/src/Screens/Client/Containers/Edit.js +7 -2
  25. package/src/Screens/Client/Reducers/Reducer.js +1 -0
  26. package/src/Screens/Client/Translations.js +5 -2
  27. package/src/Screens/CurrentClient/Containers/Edit.js +9 -4
  28. package/src/Screens/CurrentClient/Reducers/Reducer.js +1 -0
  29. package/src/Screens/DefaultClient/Containers/Edit.js +6 -1
  30. package/src/Screens/DefaultClient/Reducers/Reducer.js +1 -0
  31. package/src/Screens/Designer/SubScreens/Visualization/Containers/Edit/Edit.js +10 -3
  32. package/src/Screens/PriceTypes/Containers/Edit.js +32 -9
  33. package/src/Screens/PriceTypes/Reducers/Reducer.js +1 -1
  34. package/src/Screens/PriceTypes/Translations.js +14 -0
  35. package/scripts/cpFavicon.js +0 -28
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.sourceConfigPropType = exports.getInputItemKeyByConfig = exports.getInputItemParamsByConfig = exports.getInputValueByConfig = void 0;
6
+ exports.nullToValue = exports.valueToNull = exports.sourceConfigPropType = exports.getInputItemKeyByConfig = exports.getInputItemParamsByConfig = exports.getInputValueByConfig = void 0;
7
7
 
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
 
@@ -65,4 +65,16 @@ var sourceConfigPropType = _propTypes["default"].shape({
65
65
  value: _propTypes["default"].string.isRequired
66
66
  });
67
67
 
68
- exports.sourceConfigPropType = sourceConfigPropType;
68
+ exports.sourceConfigPropType = sourceConfigPropType;
69
+
70
+ var valueToNull = function valueToNull(value) {
71
+ return value === 'null' ? null : value;
72
+ };
73
+
74
+ exports.valueToNull = valueToNull;
75
+
76
+ var nullToValue = function nullToValue(value) {
77
+ return value === null ? 'null' : value;
78
+ };
79
+
80
+ exports.nullToValue = nullToValue;
@@ -22,7 +22,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "d
22
22
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
23
23
 
24
24
  var select = function select(props) {
25
- var value = (0, _InputWithSource.getInputValueByConfig)(props);
25
+ var value = (0, _InputWithSource.nullToValue)((0, _InputWithSource.getInputValueByConfig)(props));
26
26
  return /*#__PURE__*/_react["default"].createElement(_SelectField["default"], {
27
27
  style: {
28
28
  width: '100%'
@@ -35,7 +35,7 @@ var select = function select(props) {
35
35
  var selectedObj = (0, _find2["default"])(props.source, _defineProperty({}, key, event.target.value));
36
36
  props.onChange(props.name, selectedObj);
37
37
  } else {
38
- props.onChange(props.name, event.target.value);
38
+ props.onChange(props.name, (0, _InputWithSource.valueToNull)(event.target.value));
39
39
  }
40
40
  },
41
41
  onFocus: function onFocus() {
@@ -52,8 +52,10 @@ var select = function select(props) {
52
52
  value = _getInputItemParamsBy.value,
53
53
  text = _getInputItemParamsBy.text;
54
54
 
55
+ var _value = (0, _InputWithSource.nullToValue)(value);
56
+
55
57
  return /*#__PURE__*/_react["default"].createElement(_MenuItem["default"], {
56
- value: value,
58
+ value: _value,
57
59
  key: idx
58
60
  }, text);
59
61
  }));
@@ -7,6 +7,8 @@ exports["default"] = void 0;
7
7
 
8
8
  var _Actions = require("../Reducers/Actions");
9
9
 
10
+ var _i18n = require("../../../App/i18n");
11
+
10
12
  var _DefaultConnectedForm = _interopRequireDefault(require("../../../Components/DefaultConnectedForm"));
11
13
 
12
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
@@ -39,6 +41,11 @@ var formFields = [{
39
41
  label: 'Attribute data type',
40
42
  type: 'select',
41
43
  source: ['string', 'integer', 'number', 'boolean', 'text']
44
+ }, {
45
+ name: 'writeProtected',
46
+ label: (0, _i18n.t)('attribute.writeProtected'),
47
+ type: 'checkbox',
48
+ helperText: (0, _i18n.t)('attribute.writeProtectedInfo')
42
49
  }];
43
50
 
44
51
  var _default = (0, _DefaultConnectedForm["default"])(formFields, _Actions.ATTRIBUTE_REDUCER_NAME, _Actions.setFieldData, _Actions.postData);
@@ -31,7 +31,10 @@ var initialState = _objectSpread({}, (0, _Reducer.getDefaultEntityState)({
31
31
  presence: true
32
32
  }
33
33
  },
34
- texts: []
34
+ texts: [],
35
+ writeProtected: {
36
+ value: ''
37
+ }
35
38
  }, null, _Actions.ATTRIBUTE_DATA_KEY));
36
39
 
37
40
  var attributeData = (0, _FeatureReducers.createFeatureReducer)(_Actions.ATTRIBUTE_REDUCER_NAME, function () {
@@ -7,7 +7,9 @@ require("../../App/i18n").use({
7
7
  'Attribute data type': 'Attribute data type',
8
8
  Variants: 'Variants',
9
9
  attribute: {
10
- addButtonLabel: 'Add Attribute'
10
+ addButtonLabel: 'Add Attribute',
11
+ writeProtected: 'Write protected',
12
+ writeProtectedInfo: 'Attribute won’t be deleted by the importer'
11
13
  }
12
14
  },
13
15
  de: {
@@ -16,7 +18,9 @@ require("../../App/i18n").use({
16
18
  'Attribute data type': 'Attributdatentyp',
17
19
  Variants: 'Varianten',
18
20
  attribute: {
19
- addButtonLabel: 'Attribute hinzufügen'
21
+ addButtonLabel: 'Attribute hinzufügen',
22
+ writeProtected: 'Schreibgeschützt',
23
+ writeProtectedInfo: 'Das Attribut wird beim Import nicht gelöscht'
20
24
  }
21
25
  }
22
26
  }, true);
@@ -137,6 +137,10 @@ var formFields = [{
137
137
  label: 'BCC E-Mail(s) receiver for request offer',
138
138
  type: 'text',
139
139
  helperText: (0, _i18n.t)('emailHint')
140
+ }, {
141
+ name: 'sendOfferRequestMailToCustomer',
142
+ label: 'Send offer request email to customer',
143
+ type: 'checkbox'
140
144
  }, {
141
145
  type: _CallToActionField.CallToActionField,
142
146
  fields: [{
@@ -110,6 +110,9 @@ var initialState = _objectSpread({}, (0, _Reducer.getDefaultEntityState)({
110
110
  bccEmailAddresses: {
111
111
  value: ''
112
112
  },
113
+ sendOfferRequestMailToCustomer: {
114
+ value: ''
115
+ },
113
116
  callToAction: '',
114
117
  channels: {
115
118
  value: []
@@ -36,6 +36,7 @@ require("../../App/i18n").use({
36
36
  'E-Mail sender for request offer': 'Absender E-Mail für die Angebotsanfrage',
37
37
  'CC E-Mail(s) receiver for request offer': 'CC E-Mail(s) für die Angebotsanfrage',
38
38
  'BCC E-Mail(s) receiver for request offer': 'BCC E-Mail(s) für die Angebotsanfrage',
39
+ 'Send offer request email to customer': 'Angebotsanfrage per E-Mail an den Kunden senden',
39
40
  'Client logo': 'Kunden Logo',
40
41
  Texts: 'Texte',
41
42
  themeColorError: 'Bitte gib einen hexadezimalen Farbwert ein (z.B. #0000ff)',
@@ -100,6 +100,10 @@ var formFields = [{
100
100
  label: 'BCC E-Mail(s) receiver for request offer',
101
101
  type: 'text',
102
102
  helperText: (0, _i18n.t)('emailHint')
103
+ }, {
104
+ name: 'sendOfferRequestMailToCustomer',
105
+ label: 'Send offer request email to customer',
106
+ type: 'checkbox'
103
107
  }, {
104
108
  type: _CallToActionField.CallToActionField,
105
109
  fields: [{
@@ -83,6 +83,9 @@ var initialState = _objectSpread({}, (0, _Reducer.getDefaultEntityState)({
83
83
  bccEmailAddresses: {
84
84
  value: ''
85
85
  },
86
+ sendOfferRequestMailToCustomer: {
87
+ value: ''
88
+ },
86
89
  callToAction: 'addToCart',
87
90
  customCss: ''
88
91
  }, null, _Actions.DATA_KEY));
@@ -98,6 +98,10 @@ var formFields = [{
98
98
  label: 'BCC E-Mail(s) receiver for request offer',
99
99
  type: 'text',
100
100
  helperText: (0, _i18n.t)('emailHint')
101
+ }, {
102
+ name: 'sendOfferRequestMailToCustomer',
103
+ label: 'Send offer request email to customer',
104
+ type: 'checkbox'
101
105
  }, {
102
106
  name: 'callToAction',
103
107
  label: 'callToAction.callToAction',
@@ -96,6 +96,9 @@ var initialState = _objectSpread({}, (0, _Reducer.getDefaultEntityState)({
96
96
  presence: true
97
97
  }
98
98
  },
99
+ sendOfferRequestMailToCustomer: {
100
+ value: ''
101
+ },
99
102
  callToAction: 'addToCart',
100
103
  customCss: ''
101
104
  }, null, _Actions.DATA_KEY));
@@ -120,6 +120,8 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
120
120
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
121
121
 
122
122
  var styles = function styles(theme) {
123
+ var _visualizationRoot;
124
+
123
125
  var breakPoint = {
124
126
  max: "@media screen and (max-width:".concat(1144 + 2 * theme.spacing.unit, "px)")
125
127
  };
@@ -127,7 +129,9 @@ var styles = function styles(theme) {
127
129
  editorRoot: _defineProperty({
128
130
  display: 'flex',
129
131
  flexDirection: 'row',
130
- height: 'calc(100vh - 180px)',
132
+ '&.fullHeight': {
133
+ height: 'calc(100vh - 180px)'
134
+ },
131
135
  '& > $header': _defineProperty({
132
136
  display: 'none'
133
137
  }, breakPoint.max, {
@@ -206,13 +210,16 @@ var styles = function styles(theme) {
206
210
  advancedEditor: {
207
211
  maxWidth: 600
208
212
  },
209
- visualizationRoot: {
210
- '& > $leftSide': _defineProperty({
211
- width: '70%'
212
- }, breakPoint.max, {
213
- width: '100%'
214
- })
215
- },
213
+ visualizationRoot: (_visualizationRoot = {
214
+ display: 'flex',
215
+ flexDirection: 'row'
216
+ }, _defineProperty(_visualizationRoot, breakPoint.max, {
217
+ flexDirection: 'column'
218
+ }), _defineProperty(_visualizationRoot, '& > $leftSide', _defineProperty({
219
+ width: '70%'
220
+ }, breakPoint.max, {
221
+ width: '100%'
222
+ })), _visualizationRoot),
216
223
  visualizationContainer: {
217
224
  width: '100%',
218
225
  height: '39vw'
@@ -853,7 +860,7 @@ var VisualizationSettingsEdit = /*#__PURE__*/function (_Component) {
853
860
 
854
861
  if (isKindOf2D(mode)) {
855
862
  return /*#__PURE__*/_react["default"].createElement("div", {
856
- className: [classes.editorRoot, classes.visualizationRoot].join(' ')
863
+ className: classes.visualizationRoot
857
864
  }, /*#__PURE__*/_react["default"].createElement("div", {
858
865
  className: classes.leftSide
859
866
  }, /*#__PURE__*/_react["default"].createElement(_VisualizationContainer["default"], {
@@ -913,7 +920,7 @@ var VisualizationSettingsEdit = /*#__PURE__*/function (_Component) {
913
920
  }
914
921
 
915
922
  return /*#__PURE__*/_react["default"].createElement("div", {
916
- className: classes.editorRoot
923
+ className: "".concat(classes.editorRoot, " ").concat(isKindOf3D(mode) ? 'fullHeight' : '')
917
924
  }, loading && /*#__PURE__*/_react["default"].createElement(LoadingComponent, {
918
925
  fullSize: true
919
926
  }), isKindOf3D(mode) ? this.renderHeader3D(data) : this.renderHeader(), imageElement && /*#__PURE__*/_react["default"].createElement("div", {
@@ -7,7 +7,9 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports["default"] = void 0;
9
9
 
10
- var _Actions = _interopRequireWildcard(require("../Reducers/Actions"));
10
+ var _react = _interopRequireDefault(require("react"));
11
+
12
+ var _i18n = require("../../../App/i18n");
11
13
 
12
14
  var _DefaultConnectedForm = _interopRequireDefault(require("../../../Components/DefaultConnectedForm"));
13
15
 
@@ -15,14 +17,14 @@ var _LocalizedPriceTextField = require("../../../Components/LocalizedPriceTextFi
15
17
 
16
18
  var _LocalizedPriceValue = _interopRequireDefault(require("../../../Components/LocalizedPriceValue"));
17
19
 
18
- var _react = _interopRequireDefault(require("react"));
19
-
20
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
20
+ var _Actions = _interopRequireWildcard(require("../Reducers/Actions"));
21
21
 
22
22
  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); }
23
23
 
24
24
  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; }
25
25
 
26
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
27
+
26
28
  var setFieldData = _Actions["default"].setFieldData,
27
29
  postData = _Actions["default"].postData;
28
30
  var formFields = [{
@@ -42,9 +44,33 @@ var formFields = [{
42
44
  label: 'selectable By User',
43
45
  type: 'toggle'
44
46
  }, {
45
- name: 'imageDataDependent',
46
- label: 'image Data Dependent',
47
- type: 'toggle'
47
+ name: 'imageDependent',
48
+ label: 'imageDependent.label',
49
+ type: 'select',
50
+ sourceConfig: {
51
+ text: function text(_ref) {
52
+ var label = _ref.label;
53
+ return (0, _i18n.T)(label);
54
+ },
55
+ value: 'value'
56
+ },
57
+ source: [{
58
+ value: null,
59
+ label: 'imageDependent.no',
60
+ id: 'print'
61
+ }, {
62
+ value: 'image_data_dependent',
63
+ label: 'imageDependent.imageDataDependent',
64
+ id: 'image_data_dependent'
65
+ }, {
66
+ value: 'user_image_dependent',
67
+ label: 'imageDependent.userImageDependent',
68
+ id: 'user_image_dependent'
69
+ }, {
70
+ value: 'gallery_image_dependent',
71
+ label: 'imageDependent.galleryImageDependent',
72
+ id: 'gallery_image_dependent'
73
+ }]
48
74
  }, {
49
75
  name: 'texts',
50
76
  label: 'Title',
@@ -71,9 +97,9 @@ var formFields = [{
71
97
  },
72
98
  type: 'dynSource',
73
99
  sourceConfig: {
74
- text: function text(_ref) {
75
- var identifier = _ref.identifier,
76
- currency = _ref.currency;
100
+ text: function text(_ref2) {
101
+ var identifier = _ref2.identifier,
102
+ currency = _ref2.currency;
77
103
  return "".concat(identifier, " / ").concat(currency.symbol, " (").concat(currency.iso, ")");
78
104
  }
79
105
  },
@@ -34,8 +34,8 @@ var initialState = _objectSpread({}, (0, _Reducer.getDefaultEntityState)({
34
34
  selectableByUser: {
35
35
  value: true
36
36
  },
37
- imageDataDependent: {
38
- value: true
37
+ imageDependent: {
38
+ value: null
39
39
  },
40
40
  texts: [],
41
41
  prices: {
@@ -15,6 +15,13 @@ require("../../App/i18n").use({
15
15
  prices: {
16
16
  addButtonLabel: 'Add Price'
17
17
  }
18
+ },
19
+ imageDependent: {
20
+ label: 'Depending on the image data',
21
+ no: 'No',
22
+ imageDataDependent: 'Image data dependent (uploaded + images from image gallery)',
23
+ userImageDependent: 'Uploaded Image Data Dependent',
24
+ galleryImageDependent: 'Image gallery Data Dependent'
18
25
  }
19
26
  },
20
27
  de: {
@@ -31,6 +38,13 @@ require("../../App/i18n").use({
31
38
  prices: {
32
39
  addButtonLabel: 'Preis hinzufügen'
33
40
  }
41
+ },
42
+ imageDependent: {
43
+ label: 'Abhängig von den Bilddaten',
44
+ no: 'Nein',
45
+ imageDataDependent: 'Abhängig von Bilddaten (hochgeladene + Bildern aus der Bildergalerie)',
46
+ userImageDependent: 'Abhängig von hochgeladenen Bildern',
47
+ galleryImageDependent: 'Abhängig von Bildern aus der Bildergalerie'
34
48
  }
35
49
  }
36
50
  }, true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@configuratorware/configurator-admingui",
3
- "version": "1.39.0",
3
+ "version": "1.39.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.39.0",
32
+ "redhotmagma-visualization": "1.39.1",
33
33
  "redux": "^4.1.0",
34
34
  "redux-logger": "^3.0.6",
35
35
  "redux-persist": "^5.10.0",
@@ -58,7 +58,7 @@
58
58
  "url-loader": "^1.1.2"
59
59
  },
60
60
  "scripts": {
61
- "copy-public": "node ./scripts/cpFavicon.js",
61
+ "copy-public": "node ./scripts/cpPublic.js",
62
62
  "install": "npm run copy-public"
63
63
  },
64
64
  "readme": "# configurator-admingui\n\n## Setup for development\n1. Follow the \"preparation\", \"install\" and \"start development\" steps in frontend/README.md\n1. Open the core app in the browser: http://localhost:3000\n\n## Ready to build the artifacts\n- run `pnpm build` from project scope (does not build workspace dependencies automatically)\n- or run `pnpm build` from workspace root\n"
@@ -0,0 +1,32 @@
1
+ /* eslint no-console: 0 */
2
+
3
+ /**
4
+ * This script is made to copy the content of the public folder
5
+ * into the same destination in the client projects
6
+ *
7
+ * Runs only when installing this package as a dependency in client projects
8
+ *
9
+ * usage: node ./scripts/cpPublic.js
10
+ *
11
+ * @author boda@redhotmagma.de
12
+ */
13
+
14
+ const path = require('path');
15
+
16
+ const { cpDirDeep, testMatchers } = require('@configuratorware/scripts/utils/fileSystem');
17
+ const { isDependency } = require('@configuratorware/scripts/utils/process');
18
+
19
+ // keep existing files listed below
20
+ const test = testMatchers.keepIfExists(/favicon\.ico$/);
21
+
22
+ if (isDependency()) {
23
+ console.log(
24
+ '\x1b[37m\x1b[42m%s\x1b[0m',
25
+ 'Copying public content into the public directory of the client project'
26
+ );
27
+
28
+ const src = path.resolve(__dirname, '../public');
29
+ const dst = path.resolve(__dirname, '../../../../public');
30
+
31
+ cpDirDeep(src, dst, { testFn: test });
32
+ }
@@ -44,3 +44,6 @@ export const sourceConfigPropType = PropTypes.shape({
44
44
  text: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired,
45
45
  value: PropTypes.string.isRequired,
46
46
  });
47
+
48
+ export const valueToNull = value => (value === 'null' ? null : value);
49
+ export const nullToValue = value => (value === null ? 'null' : value);
@@ -4,10 +4,15 @@ import find from 'lodash/find';
4
4
  import SelectField from '../../UIComponents/SelectField';
5
5
  import MenuItem from '../../UIComponents/MenuItem';
6
6
 
7
- import { getInputValueByConfig, getInputItemParamsByConfig } from './InputWithSource';
7
+ import {
8
+ getInputValueByConfig,
9
+ getInputItemParamsByConfig,
10
+ valueToNull,
11
+ nullToValue,
12
+ } from './InputWithSource';
8
13
 
9
14
  const select = props => {
10
- const value = getInputValueByConfig(props);
15
+ const value = nullToValue(getInputValueByConfig(props));
11
16
  return (
12
17
  <SelectField
13
18
  style={{ width: '100%' }}
@@ -19,7 +24,7 @@ const select = props => {
19
24
  const selectedObj = find(props.source, { [key]: event.target.value });
20
25
  props.onChange(props.name, selectedObj);
21
26
  } else {
22
- props.onChange(props.name, event.target.value);
27
+ props.onChange(props.name, valueToNull(event.target.value));
23
28
  }
24
29
  }}
25
30
  onFocus={() => props.source.length === 0 && this.props.loadSource && this.props.loadSource()}
@@ -32,8 +37,9 @@ const select = props => {
32
37
  >
33
38
  {props.source.map((item, idx) => {
34
39
  const { value, text } = getInputItemParamsByConfig(item, props.sourceConfig);
40
+ const _value = nullToValue(value);
35
41
  return (
36
- <MenuItem value={value} key={idx}>
42
+ <MenuItem value={_value} key={idx}>
37
43
  {text}
38
44
  </MenuItem>
39
45
  );
@@ -6,6 +6,7 @@ import {
6
6
  ATTRIBUTE_LIST_KEY,
7
7
  ATTRIBUTE_LIST_URL,
8
8
  } from '../Reducers/Actions';
9
+ import { t } from '../../../App/i18n';
9
10
 
10
11
  const formFields = [
11
12
  {
@@ -39,6 +40,12 @@ const formFields = [
39
40
  type: 'select',
40
41
  source: ['string', 'integer', 'number', 'boolean', 'text'],
41
42
  },
43
+ {
44
+ name: 'writeProtected',
45
+ label: t('attribute.writeProtected'),
46
+ type: 'checkbox',
47
+ helperText: t('attribute.writeProtectedInfo'),
48
+ },
42
49
  ];
43
50
 
44
51
  import generateConnectedEdit from '../../../Components/DefaultConnectedForm';
@@ -9,6 +9,7 @@ const initialState = {
9
9
  identifier: { value: '', constraints: { identifier: true } },
10
10
  attributedatatype: { value: null, constraints: { presence: true } },
11
11
  texts: [],
12
+ writeProtected: { value: '' },
12
13
  },
13
14
  null,
14
15
  ATTRIBUTE_DATA_KEY
@@ -7,6 +7,8 @@ require('../../App/i18n').use(
7
7
  Variants: 'Variants',
8
8
  attribute: {
9
9
  addButtonLabel: 'Add Attribute',
10
+ writeProtected: 'Write protected',
11
+ writeProtectedInfo: 'Attribute won’t be deleted by the importer',
10
12
  },
11
13
  },
12
14
  de: {
@@ -16,6 +18,8 @@ require('../../App/i18n').use(
16
18
  Variants: 'Varianten',
17
19
  attribute: {
18
20
  addButtonLabel: 'Attribute hinzufügen',
21
+ writeProtected: 'Schreibgeschützt',
22
+ writeProtectedInfo: 'Das Attribut wird beim Import nicht gelöscht',
19
23
  },
20
24
  },
21
25
  },
@@ -54,7 +54,7 @@ const formFields = [
54
54
  accept: '.ttf',
55
55
  showFileName: true,
56
56
  deleteEnabled: true,
57
- warningMessage: T('clientFontMessage')
57
+ warningMessage: T('clientFontMessage'),
58
58
  },
59
59
  {
60
60
  name: 'logo',
@@ -127,6 +127,11 @@ const formFields = [
127
127
  type: 'text',
128
128
  helperText: t('emailHint'),
129
129
  },
130
+ {
131
+ name: 'sendOfferRequestMailToCustomer',
132
+ label: 'Send offer request email to customer',
133
+ type: 'checkbox',
134
+ },
130
135
  {
131
136
  type: CallToActionField,
132
137
  fields: [
@@ -136,7 +141,7 @@ const formFields = [
136
141
  type: 'select',
137
142
  },
138
143
  ],
139
- dynamicDefaultLabel: false
144
+ dynamicDefaultLabel: false,
140
145
  },
141
146
  {
142
147
  name: 'texts',
@@ -38,6 +38,7 @@ const initialState = {
38
38
  fromEmailAddress: { value: '' },
39
39
  ccEmailAddresses: { value: '' },
40
40
  bccEmailAddresses: { value: '' },
41
+ sendOfferRequestMailToCustomer: { value: '' },
41
42
  callToAction: '',
42
43
  channels: { value: [] },
43
44
  customCss: '',
@@ -16,7 +16,8 @@ require('../../App/i18n').use(
16
16
  headerInfo: 'Please check your changes in a generated pdf to make sure it looks as expected',
17
17
  footerInfo: 'Please check your changes in a generated pdf to make sure it looks as expected',
18
18
  emailHint: 'separate multiple addresses with a semicolon',
19
- clientFontMessage: 'For the font to be rendered correctly in the configuratorware frontend, make sure the filename does not contain any spaces and matches the fonts internal name.'
19
+ clientFontMessage:
20
+ 'For the font to be rendered correctly in the configuratorware frontend, make sure the filename does not contain any spaces and matches the fonts internal name.',
20
21
  },
21
22
  de: {
22
23
  clients: 'Klienten',
@@ -35,6 +36,7 @@ require('../../App/i18n').use(
35
36
  'E-Mail sender for request offer': 'Absender E-Mail für die Angebotsanfrage',
36
37
  'CC E-Mail(s) receiver for request offer': 'CC E-Mail(s) für die Angebotsanfrage',
37
38
  'BCC E-Mail(s) receiver for request offer': 'BCC E-Mail(s) für die Angebotsanfrage',
39
+ 'Send offer request email to customer': 'Angebotsanfrage per E-Mail an den Kunden senden',
38
40
  'Client logo': 'Kunden Logo',
39
41
  Texts: 'Texte',
40
42
  themeColorError: 'Bitte gib einen hexadezimalen Farbwert ein (z.B. #0000ff)',
@@ -47,7 +49,8 @@ require('../../App/i18n').use(
47
49
  headerInfo: 'Bitte überprüfe Deine Änderungen in einem generierten PDF',
48
50
  footerInfo: 'Bitte überprüfe Deine Änderungen in einem generierten PDF',
49
51
  emailHint: 'trenne mehrere Adressen mit einem Semikolon',
50
- clientFontMessage: 'Für eine korrekte Darstellung der Schrift im configuratorware Fronted darf der Dateiname keine Leerzeichen enthalten und muss dem internen Namen der Schriftart entsprechen.'
52
+ clientFontMessage:
53
+ 'Für eine korrekte Darstellung der Schrift im configuratorware Fronted darf der Dateiname keine Leerzeichen enthalten und muss dem internen Namen der Schriftart entsprechen.',
51
54
  },
52
55
  },
53
56
  true
@@ -2,7 +2,7 @@ import Actions, { REDUCER_NAME } from '../Reducers/Actions';
2
2
  import SimpleNestedData from '../../../Components/FormFragments/SimpleNestedData';
3
3
  import generateConnectedEdit from '../../../Components/DefaultConnectedForm';
4
4
  import { withLoadAction } from '../../../Components/withLoadAction';
5
- import {T, t } from '../../../App/i18n';
5
+ import { T, t } from '../../../App/i18n';
6
6
  import { CallToActionField } from '../../../Components/CallToActionField';
7
7
  import PdfMarkDownField from '../../Client/Components/PdfMarkdownField';
8
8
 
@@ -23,7 +23,7 @@ const formFields = [
23
23
  accept: '.ttf',
24
24
  showFileName: true,
25
25
  deleteEnabled: true,
26
- warningMessage: T('clientFontMessage')
26
+ warningMessage: T('clientFontMessage'),
27
27
  },
28
28
  {
29
29
  name: 'logo',
@@ -96,6 +96,11 @@ const formFields = [
96
96
  type: 'text',
97
97
  helperText: t('emailHint'),
98
98
  },
99
+ {
100
+ name: 'sendOfferRequestMailToCustomer',
101
+ label: 'Send offer request email to customer',
102
+ type: 'checkbox',
103
+ },
99
104
  {
100
105
  type: CallToActionField,
101
106
  fields: [
@@ -103,9 +108,9 @@ const formFields = [
103
108
  name: 'callToAction',
104
109
  label: 'callToAction.callToAction',
105
110
  type: 'select',
106
- }
111
+ },
107
112
  ],
108
- dynamicDefaultLabel: false
113
+ dynamicDefaultLabel: false,
109
114
  },
110
115
  {
111
116
  name: 'texts',
@@ -30,6 +30,7 @@ const initialState = {
30
30
  fromEmailAddress: { value: '' },
31
31
  ccEmailAddresses: { value: '' },
32
32
  bccEmailAddresses: { value: '' },
33
+ sendOfferRequestMailToCustomer: { value: '' },
33
34
  callToAction: 'addToCart',
34
35
  customCss: '',
35
36
  },
@@ -22,7 +22,7 @@ const formFields = [
22
22
  accept: '.ttf',
23
23
  showFileName: true,
24
24
  deleteEnabled: true,
25
- warningMessage: T('clientFontMessage')
25
+ warningMessage: T('clientFontMessage'),
26
26
  },
27
27
  {
28
28
  name: 'logo',
@@ -95,6 +95,11 @@ const formFields = [
95
95
  type: 'text',
96
96
  helperText: t('emailHint'),
97
97
  },
98
+ {
99
+ name: 'sendOfferRequestMailToCustomer',
100
+ label: 'Send offer request email to customer',
101
+ type: 'checkbox',
102
+ },
98
103
  {
99
104
  name: 'callToAction',
100
105
  label: 'callToAction.callToAction',
@@ -31,6 +31,7 @@ const initialState = {
31
31
  fromEmailAddress: { value: '', constraints: { presence: true } },
32
32
  ccEmailAddresses: { value: '', constraints: { presence: true } },
33
33
  bccEmailAddresses: { value: '', constraints: { presence: true } },
34
+ sendOfferRequestMailToCustomer: { value: '' },
34
35
  callToAction: 'addToCart',
35
36
  customCss: '',
36
37
  },
@@ -58,7 +58,9 @@ const styles = theme => {
58
58
  editorRoot: {
59
59
  display: 'flex',
60
60
  flexDirection: 'row',
61
- height: 'calc(100vh - 180px)',
61
+ '&.fullHeight': {
62
+ height: 'calc(100vh - 180px)',
63
+ },
62
64
  '& > $header': {
63
65
  display: 'none',
64
66
  [breakPoint.max]: {
@@ -146,6 +148,11 @@ const styles = theme => {
146
148
  maxWidth: 600,
147
149
  },
148
150
  visualizationRoot: {
151
+ display: 'flex',
152
+ flexDirection: 'row',
153
+ [breakPoint.max]: {
154
+ flexDirection: 'column',
155
+ },
149
156
  '& > $leftSide': {
150
157
  width: '70%',
151
158
  [breakPoint.max]: {
@@ -634,7 +641,7 @@ export class VisualizationSettingsEdit extends Component {
634
641
  const { three } = this;
635
642
  if (isKindOf2D(mode)) {
636
643
  return (
637
- <div className={[classes.editorRoot, classes.visualizationRoot].join(' ')}>
644
+ <div className={classes.visualizationRoot}>
638
645
  <div className={classes.leftSide}>
639
646
  <VisualizationContainer three={three} className={classes.visualizationContainer} />
640
647
  </div>
@@ -688,7 +695,7 @@ export class VisualizationSettingsEdit extends Component {
688
695
  }
689
696
 
690
697
  return (
691
- <div className={classes.editorRoot}>
698
+ <div className={`${classes.editorRoot} ${isKindOf3D(mode) ? 'fullHeight' : ''}`}>
692
699
  {loading && <LoadingComponent fullSize />}
693
700
 
694
701
  {isKindOf3D(mode) ? this.renderHeader3D(data) : this.renderHeader()}
@@ -1,3 +1,8 @@
1
+ import React from 'react';
2
+ import { T } from '../../../App/i18n';
3
+ import generateConnectedEdit from '../../../Components/DefaultConnectedForm';
4
+ import { LocalizedPriceTextField } from '../../../Components/LocalizedPriceTextField';
5
+ import LocalizedPriceValue from '../../../Components/LocalizedPriceValue';
1
6
  import Actions, { REDUCER_NAME } from '../Reducers/Actions';
2
7
  const { setFieldData, postData } = Actions;
3
8
 
@@ -23,9 +28,31 @@ const formFields = [
23
28
  type: 'toggle',
24
29
  },
25
30
  {
26
- name: 'imageDataDependent',
27
- label: 'image Data Dependent',
28
- type: 'toggle',
31
+ name: 'imageDependent',
32
+ label: 'imageDependent.label',
33
+ type: 'select',
34
+ sourceConfig: {
35
+ text: ({ label }) => T(label),
36
+ value: 'value',
37
+ },
38
+ source: [
39
+ { value: null, label: 'imageDependent.no', id: 'print' },
40
+ {
41
+ value: 'image_data_dependent',
42
+ label: 'imageDependent.imageDataDependent',
43
+ id: 'image_data_dependent',
44
+ },
45
+ {
46
+ value: 'user_image_dependent',
47
+ label: 'imageDependent.userImageDependent',
48
+ id: 'user_image_dependent',
49
+ },
50
+ {
51
+ value: 'gallery_image_dependent',
52
+ label: 'imageDependent.galleryImageDependent',
53
+ id: 'gallery_image_dependent',
54
+ },
55
+ ],
29
56
  },
30
57
  {
31
58
  name: 'texts',
@@ -75,13 +102,13 @@ const formFields = [
75
102
  name: 'price',
76
103
  label: 'price',
77
104
  type: LocalizedPriceTextField,
78
- renderValue: value => <LocalizedPriceValue data={value}/>,
105
+ renderValue: value => <LocalizedPriceValue data={value} />,
79
106
  },
80
107
  {
81
108
  name: 'priceNet',
82
109
  label: 'price Net',
83
110
  type: LocalizedPriceTextField,
84
- renderValue: value => <LocalizedPriceValue data={value}/>,
111
+ renderValue: value => <LocalizedPriceValue data={value} />,
85
112
  },
86
113
  ],
87
114
  },
@@ -89,8 +116,4 @@ const formFields = [
89
116
  },
90
117
  ];
91
118
 
92
- import generateConnectedEdit from '../../../Components/DefaultConnectedForm';
93
- import {LocalizedPriceTextField} from "../../../Components/LocalizedPriceTextField";
94
- import LocalizedPriceValue from "../../../Components/LocalizedPriceValue";
95
- import React from "react";
96
119
  export default generateConnectedEdit(formFields, REDUCER_NAME, setFieldData, postData);
@@ -10,7 +10,7 @@ const initialState = {
10
10
  itemAmountDependent: { value: true },
11
11
  bulkNameDependent: { value: true },
12
12
  selectableByUser: { value: true },
13
- imageDataDependent: { value: true },
13
+ imageDependent: { value: null },
14
14
  texts: [],
15
15
  prices: {
16
16
  value: [],
@@ -15,6 +15,13 @@ require('../../App/i18n').use(
15
15
  addButtonLabel: 'Add Price',
16
16
  },
17
17
  },
18
+ imageDependent: {
19
+ label: 'Depending on the image data',
20
+ no: 'No',
21
+ imageDataDependent: 'Image data dependent (uploaded + images from image gallery)',
22
+ userImageDependent: 'Uploaded Image Data Dependent',
23
+ galleryImageDependent: 'Image gallery Data Dependent',
24
+ },
18
25
  },
19
26
  de: {
20
27
  designer_global_calculation_types: 'Globale Kalkulationsposten',
@@ -31,6 +38,13 @@ require('../../App/i18n').use(
31
38
  addButtonLabel: 'Preis hinzufügen',
32
39
  },
33
40
  },
41
+ imageDependent: {
42
+ label: 'Abhängig von den Bilddaten',
43
+ no: 'Nein',
44
+ imageDataDependent: 'Abhängig von Bilddaten (hochgeladene + Bildern aus der Bildergalerie)',
45
+ userImageDependent: 'Abhängig von hochgeladenen Bildern',
46
+ galleryImageDependent: 'Abhängig von Bildern aus der Bildergalerie',
47
+ },
34
48
  },
35
49
  },
36
50
  true
@@ -1,28 +0,0 @@
1
- /* eslint no-console: 0 */
2
-
3
- /**
4
- * This script is made to copy the favicon from public folder
5
- * into the same destination in the client projects
6
- *
7
- * Runs only when installing this package as a dependency in client projects
8
- *
9
- * usage: node ./scripts/cpFavicon.js
10
- *
11
- */
12
-
13
- const path = require('path');
14
- const fs = require('fs');
15
- const { isDependency } = require('./utils/process');
16
-
17
- if (isDependency()) {
18
- const dir = path.resolve(__dirname, '../../../../public');
19
- if (!fs.existsSync(dir)) {
20
- fs.mkdirSync(dir);
21
- }
22
- const src = path.resolve(__dirname, '../public/favicon.ico');
23
- const dst = path.resolve(dir, 'favicon.ico');
24
- // copy it only if there is no favicon.ico (which can be already a custom one) in the target location
25
- if (!fs.existsSync(dst)) {
26
- fs.createReadStream(src).pipe(fs.createWriteStream(dst));
27
- }
28
- }