@configuratorware/configurator-admingui 1.31.0 → 1.31.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 (36) hide show
  1. package/App/Reducers/Api/Actions.js +1 -12
  2. package/App/Reducers/Api/Reducer.js +0 -6
  3. package/Components/DefaultForm.js +2 -3
  4. package/Screens/Client/Components/TextFields.js +163 -0
  5. package/Screens/Client/Containers/Edit.js +4 -15
  6. package/Screens/Client/Translations.js +1 -3
  7. package/Screens/Creator/Components/VisualizationAndMediaData/Components/ImageEditTools.js +28 -78
  8. package/Screens/Creator/Components/VisualizationAndMediaData/Translations.js +2 -4
  9. package/Screens/CurrentClient/Containers/Edit.js +4 -15
  10. package/Screens/CurrentClient/Reducers/Reducer.js +4 -1
  11. package/Screens/DefaultClient/Containers/Edit.js +4 -15
  12. package/Screens/DefaultClient/Reducers/Reducer.js +4 -1
  13. package/Screens/Group/Reducers/Actions.js +2 -4
  14. package/Screens/Item/Components/Variants/VariantsEditor.js +2 -4
  15. package/Screens/Item/Components/Variants/VariantsEditorPopup.js +0 -34
  16. package/Screens/Login/Reducers/Actions.js +5 -4
  17. package/package.json +2 -2
  18. package/src/App/Reducers/Api/Actions.js +0 -6
  19. package/src/App/Reducers/Api/Reducer.js +0 -7
  20. package/src/Components/DefaultForm.js +1 -2
  21. package/src/Components/TranslationFinder.js +0 -1
  22. package/src/Screens/Client/Components/TextFields.js +77 -0
  23. package/src/Screens/Client/Containers/Edit.js +2 -15
  24. package/src/Screens/Client/Translations.js +1 -3
  25. package/src/Screens/Creator/Components/VisualizationAndMediaData/Components/ImageEditTools.js +40 -65
  26. package/src/Screens/Creator/Components/VisualizationAndMediaData/Translations.js +0 -2
  27. package/src/Screens/Creator/Components/VisualizationAndMediaData/VisualizationAndMediaData.js +0 -1
  28. package/src/Screens/Creator/Components/VisualizationAndMediaData/VisualizationAndMediaData.test.js +0 -1
  29. package/src/Screens/CurrentClient/Containers/Edit.js +2 -15
  30. package/src/Screens/CurrentClient/Reducers/Reducer.js +1 -1
  31. package/src/Screens/DefaultClient/Containers/Edit.js +2 -15
  32. package/src/Screens/DefaultClient/Reducers/Reducer.js +1 -1
  33. package/src/Screens/Group/Reducers/Actions.js +1 -1
  34. package/src/Screens/Item/Components/Variants/VariantsEditor.js +2 -3
  35. package/src/Screens/Item/Components/Variants/VariantsEditorPopup.js +1 -11
  36. package/src/Screens/Login/Reducers/Actions.js +5 -1
@@ -23,18 +23,12 @@ var GroupEntryActions = _interopRequireWildcard(require("../../../GroupEntry/Red
23
23
 
24
24
  var _i18n = require("../../../../App/i18n");
25
25
 
26
- var _Actions3 = require("../../../../App/Reducers/Api/Actions");
27
-
28
26
  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); }
29
27
 
30
28
  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; }
31
29
 
32
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
33
31
 
34
- 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); } }
35
-
36
- 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); }); }; }
37
-
38
32
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
39
33
 
40
34
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
@@ -78,7 +72,6 @@ var VariantsEditorPopup = /*#__PURE__*/function (_React$Component) {
78
72
  open: showGroupEditor,
79
73
  scroll: 'paper'
80
74
  }, /*#__PURE__*/_react["default"].createElement(_Edit["default"], {
81
- customPostData: this.props.customPostData,
82
75
  onCancel: this.props.cancelGroup,
83
76
  closeAfterSave: true
84
77
  })), /*#__PURE__*/_react["default"].createElement(_Dialog["default"], {
@@ -113,33 +106,6 @@ var renderDispatchToProps = function renderDispatchToProps(dispatch) {
113
106
  cancelGroup: function cancelGroup() {
114
107
  dispatch(GroupActions.hideDetails(false));
115
108
  },
116
- customPostData: function () {
117
- var _customPostData = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
118
- return regeneratorRuntime.wrap(function _callee$(_context) {
119
- while (1) {
120
- switch (_context.prev = _context.next) {
121
- case 0:
122
- _context.next = 2;
123
- return dispatch(GroupActions.postData(true));
124
-
125
- case 2:
126
- // need to reset didInvalidate flag as it is set on save of group which is blocking to reloadList
127
- dispatch((0, _Actions3.resetDidInvalidate)(GroupActions.GROUPS_URL));
128
-
129
- case 3:
130
- case "end":
131
- return _context.stop();
132
- }
133
- }
134
- }, _callee);
135
- }));
136
-
137
- function customPostData() {
138
- return _customPostData.apply(this, arguments);
139
- }
140
-
141
- return customPostData;
142
- }(),
143
109
  cancelGroupEntry: function cancelGroupEntry() {
144
110
  dispatch(GroupEntryActions.hideDetails(false));
145
111
  }
@@ -88,10 +88,11 @@ var errorHandler = function errorHandler(dispatch) {
88
88
 
89
89
  var postLoginData = function postLoginData(username, password) {
90
90
  return function (dispatch) {
91
- return (0, _Helpers.dispatchPostData)(dispatch)(LOGIN_DATA_KEY, 'login_check', {
92
- username: username,
93
- password: password
94
- }).then(function (apiAction) {
91
+ var data = new _Api.ObjectFormData({
92
+ _username: username,
93
+ _password: password
94
+ });
95
+ return (0, _Helpers.dispatchPostData)(dispatch)(LOGIN_DATA_KEY, 'login_check', data).then(function (apiAction) {
95
96
  return dispatch((0, _Helpers.apiActionHandler)(apiAction, receiveHandler, errorHandler));
96
97
  });
97
98
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@configuratorware/configurator-admingui",
3
- "version": "1.31.0",
3
+ "version": "1.31.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.31.0",
32
+ "redhotmagma-visualization": "1.31.1",
33
33
  "redux": "^4.1.0",
34
34
  "redux-logger": "^3.0.6",
35
35
  "redux-persist": "^5.10.0",
@@ -10,18 +10,12 @@ export const POST_DATA = 'POST_DATA';
10
10
  export const DELETE_DATA = 'DELETE_DATA';
11
11
  export const CANCEL_REQUEST = 'CANCEL_REQUEST';
12
12
  export const EXPIRED_RESPONSE = 'EXPIRED_RESPONSE';
13
- export const RESET_DID_INVALIDATE = 'RESET_DID_INVALIDATE';
14
13
 
15
14
  export const invalidateSource = key => ({
16
15
  type: INVALIDATE_SOURCE,
17
16
  key,
18
17
  });
19
18
 
20
- export const resetDidInvalidate = key => ({
21
- type: RESET_DID_INVALIDATE,
22
- key,
23
- });
24
-
25
19
  export const requestData = (source, key) => ({
26
20
  type: REQUEST_DATA,
27
21
  source,
@@ -7,7 +7,6 @@ import {
7
7
  DELETE_DATA,
8
8
  CANCEL_REQUEST,
9
9
  EXPIRED_RESPONSE,
10
- RESET_DID_INVALIDATE,
11
10
  } from './Actions';
12
11
 
13
12
  const data = (
@@ -28,11 +27,6 @@ const data = (
28
27
  didInvalidate: true,
29
28
  data: null,
30
29
  };
31
- case RESET_DID_INVALIDATE:
32
- return {
33
- ...state,
34
- didInvalidate: false,
35
- };
36
30
  case REQUEST_DATA:
37
31
  return {
38
32
  ...state,
@@ -96,7 +90,6 @@ export const dataBySource = (state = {}, action) => {
96
90
  case DELETE_DATA:
97
91
  case CANCEL_REQUEST:
98
92
  case EXPIRED_RESPONSE:
99
- case RESET_DID_INVALIDATE:
100
93
  return {
101
94
  ...state,
102
95
  [action.key]: data(state[action.key], action),
@@ -13,11 +13,10 @@ export default class DefaultForm extends Component {
13
13
  onAction,
14
14
  config,
15
15
  closeAfterSave,
16
- customPostData
17
16
  } = this.props;
18
17
  const { actionButtons } = config;
19
18
 
20
- const onSubmit = customPostData ? customPostData : !closeAfterSave ? postData : () => postData(true);
19
+ const onSubmit = !closeAfterSave ? postData : () => postData(true);
21
20
 
22
21
  return entityState.isReady ? (
23
22
  <Form
@@ -20,7 +20,6 @@ let TranslationFinder = props => {
20
20
  const { language, data, property, fallback } = props;
21
21
  return <span>{get(find(data, { language }), property, fallback)}</span>;
22
22
  };
23
-
24
23
  const mapStateToProps = ({ i18n }) => ({
25
24
  language: i18n.locale.replace('-', '_'),
26
25
  });
@@ -0,0 +1,77 @@
1
+ import React, { Component } from 'react';
2
+ import find from 'lodash/find';
3
+ import TextField from '@material-ui/core/TextField/TextField';
4
+ import Typography from '@material-ui/core/Typography/Typography';
5
+ import { t } from '../../../App/i18n';
6
+
7
+ export default class TextFields extends Component {
8
+ onTextChange = textId => ({ target: { value: termsAndConditionsLink } }) => {
9
+ const { value: texts, name, onChange } = this.props;
10
+
11
+ const newTexts = texts.map(text => {
12
+ if (text.id !== textId) {
13
+ return text;
14
+ }
15
+
16
+ return {
17
+ ...text,
18
+ termsAndConditionsLink,
19
+ };
20
+ });
21
+
22
+ onChange(name, newTexts);
23
+ };
24
+
25
+ getGroupedTexts = () => {
26
+ const { value } = this.props;
27
+
28
+ const groupedTexts = [];
29
+
30
+ for (const text of value) {
31
+ let group = find(groupedTexts, { id: text.channel.id });
32
+
33
+ if (!group) {
34
+ group = {
35
+ id: text.channel.id,
36
+ identifier: text.channel.identifier,
37
+ texts: [],
38
+ };
39
+
40
+ groupedTexts.push(group);
41
+ }
42
+
43
+ group.texts.push({
44
+ id: text.id,
45
+ language: text.language,
46
+ termsAndConditionsLink: text.termsAndConditionsLink,
47
+ });
48
+ }
49
+
50
+ return groupedTexts;
51
+ };
52
+
53
+ render() {
54
+ const groupedTexts = this.getGroupedTexts();
55
+
56
+ return groupedTexts.length ? (
57
+ <div>
58
+ <Typography>{t('Texts')}</Typography>
59
+ {groupedTexts.map((group, groupIndex) => (
60
+ <React.Fragment key={groupIndex}>
61
+ <Typography variant="overline">{group.identifier}</Typography>
62
+ {group.texts.map((text, textIndex) => (
63
+ <TextField
64
+ key={textIndex}
65
+ label={`${t('termsAndConditionsLink')} ${text.language}`}
66
+ onChange={this.onTextChange(text.id)}
67
+ value={text.termsAndConditionsLink || ''}
68
+ fullWidth
69
+ margin="normal"
70
+ />
71
+ ))}
72
+ </React.Fragment>
73
+ ))}
74
+ </div>
75
+ ) : null;
76
+ }
77
+ }
@@ -1,6 +1,7 @@
1
1
  import Actions, { REDUCER_NAME } from '../Reducers/Actions';
2
2
  import SimpleNestedData from '../../../Components/FormFragments/SimpleNestedData';
3
3
  import generateConnectedEdit from '../../../Components/DefaultConnectedForm';
4
+ import TextFields from '../Components/TextFields';
4
5
  import ColorTextField from '../Components/ColorTextField';
5
6
  import { t } from '../../../App/i18n';
6
7
  import React from 'react';
@@ -138,22 +139,8 @@ const formFields = [
138
139
  dynamicDefaultLabel: false
139
140
  },
140
141
  {
142
+ type: TextFields,
141
143
  name: 'texts',
142
- label: 'termsAndConditionsLink',
143
- type: 'intl',
144
- intl: {
145
- name: 'termsAndConditionsLink',
146
- type: 'text',
147
- },
148
- },
149
- {
150
- name: 'texts',
151
- label: 'dataPrivacyLink',
152
- type: 'intl',
153
- intl: {
154
- name: 'dataPrivacyLink',
155
- type: 'text',
156
- },
157
144
  },
158
145
  {
159
146
  name: 'channels',
@@ -5,7 +5,6 @@ require('../../App/i18n').use(
5
5
  Users: 'Users',
6
6
  'Theme - Highlight color': 'Theme - Highlight color',
7
7
  termsAndConditionsLink: 'Terms and conditions link',
8
- dataPrivacyLink: 'Data privacy Link',
9
8
  themeColorError: 'Please enter a valid hex color (e.g. #0000ff)"',
10
9
  client: {
11
10
  addButtonLabel: 'Add Client',
@@ -22,8 +21,7 @@ require('../../App/i18n').use(
22
21
  Users: 'Benutzer',
23
22
  'Theme - Highlight color': 'Theme - Highlightfarbe',
24
23
  'Theme - Font': 'Theme - Font',
25
- termsAndConditionsLink: 'Link zu den Nutzungsbedingungen',
26
- dataPrivacyLink: 'Link zu den Datenschutzbestimmungen',
24
+ termsAndConditionsLink: 'Terms and conditions link',
27
25
  'Clientname / Shopname': 'Bezeichner/ Shopname',
28
26
  'E-mail (contact)': 'E-Mail (Kontakt)',
29
27
  'Street / no': 'Straße / Hausnummer',
@@ -7,10 +7,8 @@ import { t } from '../../../../../App/i18n';
7
7
  import ConfirmDelete from './ConfirmDelete';
8
8
  import Api from '../../../../../App/Api';
9
9
  import { networkError } from '../../../../../App/Reducers/Api/Actions';
10
- import { showErrorMessage, cancelErrorMessage } from '../../../../../App/Reducers/Frame/Actions';
11
10
  import { useDispatch } from 'react-redux';
12
11
  import { Tooltip } from '@material-ui/core';
13
- import FileDrop from 'react-file-drop';
14
12
 
15
13
  const ImageEditTools = withStyles({
16
14
  root: {
@@ -19,32 +17,18 @@ const ImageEditTools = withStyles({
19
17
  fileInput: {
20
18
  display: 'none',
21
19
  },
22
- fileDrop: {
23
- position: 'absolute',
24
- top: 0,
25
- left: '50%',
26
- width: 150,
27
- marginLeft: -75,
28
- height: 100,
29
- },
30
20
  })(({ classes, className, deleteEnabled, uploadUrl, removeUrl, onUpdate }) => {
31
21
  const fileInputRef = useRef(null);
32
22
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
33
23
  const dispatch = useDispatch();
34
24
 
35
25
  const uploadImage = async image => {
36
- const allowedFormats = ['image/jpeg', 'image/jpg', 'image/png'];
37
-
38
26
  if (!uploadUrl) {
39
27
  throw new Error('uploadUrl is not provided!');
40
28
  }
41
- if (allowedFormats.indexOf(image.type) === -1) {
42
- return dispatch(showErrorMessage(t('visualizationAndMediaData.unsupportedFileTypeError')));
43
- }
44
29
  try {
45
30
  const data = new FormData();
46
31
  data.append('file', image);
47
- dispatch(cancelErrorMessage());
48
32
  return await Api.request({ method: 'post', url: uploadUrl, data });
49
33
  } catch (e) {
50
34
  dispatch(networkError('image', 'image', e));
@@ -62,56 +46,47 @@ const ImageEditTools = withStyles({
62
46
  };
63
47
 
64
48
  return (
65
- <FileDrop
66
- className={classes.fileDrop}
67
- onDrop={async files => {
68
- await uploadImage(files[0]);
69
- onUpdate && onUpdate();
70
- }}
71
- multiple={false}
72
- >
73
- <div className={`${classes.root} ${className}`}>
74
- <input
75
- ref={fileInputRef}
76
- type="file"
77
- accept="image/jpeg, image/png"
78
- className={classes.fileInput}
79
- onChange={async evt => {
80
- if (evt.target.files.length) {
81
- await uploadImage(evt.target.files[0]);
82
- onUpdate && onUpdate();
83
- }
84
- }}
85
- />
86
- <label>
87
- <Tooltip title={t('visualizationAndMediaData.imageAddTooltip')}>
88
- <IconButton onClick={() => fileInputRef.current.click()}>
89
- <ImageSearchIcon />
90
- </IconButton>
91
- </Tooltip>
92
- </label>
93
- {deleteEnabled && (
94
- <Tooltip title={t('visualizationAndMediaData.imageDeleteTooltip')}>
95
- <IconButton onClick={() => setShowDeleteConfirm(true)}>
96
- <DeleteIcon />
97
- </IconButton>
98
- </Tooltip>
99
- )}
100
-
101
- <ConfirmDelete
102
- open={showDeleteConfirm}
103
- onCancel={() => setShowDeleteConfirm(false)}
104
- onConfirm={async () => {
105
- await removeImage();
106
- setShowDeleteConfirm(false);
49
+ <div className={`${classes.root} ${className}`}>
50
+ <input
51
+ ref={fileInputRef}
52
+ type="file"
53
+ accept="image/jpeg, image/png"
54
+ className={classes.fileInput}
55
+ onChange={async evt => {
56
+ if (evt.target.files.length) {
57
+ await uploadImage(evt.target.files[0]);
107
58
  onUpdate && onUpdate();
108
- }}
109
- title={t('visualizationAndMediaData.imageDeleteConfirm.title')}
110
- message={t('visualizationAndMediaData.imageDeleteConfirm.message')}
111
- />
112
- </div>
113
- </FileDrop>
59
+ }
60
+ }}
61
+ />
62
+ <label>
63
+ <Tooltip title={t('visualizationAndMediaData.imageAddTooltip')}>
64
+ <IconButton onClick={() => fileInputRef.current.click()}>
65
+ <ImageSearchIcon />
66
+ </IconButton>
67
+ </Tooltip>
68
+ </label>
69
+ {deleteEnabled && (
70
+ <Tooltip title={t('visualizationAndMediaData.imageDeleteTooltip')}>
71
+ <IconButton onClick={() => setShowDeleteConfirm(true)}>
72
+ <DeleteIcon />
73
+ </IconButton>
74
+ </Tooltip>
75
+ )}
76
+
77
+ <ConfirmDelete
78
+ open={showDeleteConfirm}
79
+ onCancel={() => setShowDeleteConfirm(false)}
80
+ onConfirm={async () => {
81
+ await removeImage();
82
+ setShowDeleteConfirm(false);
83
+ onUpdate && onUpdate();
84
+ }}
85
+ title={t('visualizationAndMediaData.imageDeleteConfirm.title')}
86
+ message={t('visualizationAndMediaData.imageDeleteConfirm.message')}
87
+ />
88
+ </div>
114
89
  );
115
90
  });
116
91
 
117
- export default ImageEditTools;
92
+ export default ImageEditTools;
@@ -44,7 +44,6 @@ require('../../../../App/i18n').use(
44
44
  title: 'Delete image',
45
45
  message: 'Do you really want to delete this image?',
46
46
  },
47
- unsupportedFileTypeError: 'Unsupported file format',
48
47
  },
49
48
  },
50
49
  de: {
@@ -93,7 +92,6 @@ require('../../../../App/i18n').use(
93
92
  title: 'Bild löschen',
94
93
  message: 'Möchtest du dieses Bild wirklich löschen?',
95
94
  },
96
- unsupportedFileTypeError: 'Nicht unterstütztes Dateiformat',
97
95
  },
98
96
  },
99
97
  },
@@ -70,7 +70,6 @@ const ImageTile = withStyles(theme => ({
70
70
  return (
71
71
  <div className={classes.imageTile}>
72
72
  {expectedSrc ? <PathStructure path={expectedSrc} /> : <Image src={src} />}
73
-
74
73
  {uploadUrl && removeUrl && (
75
74
  <ImageEditTools
76
75
  className={classes.imageEditTools}
@@ -3,7 +3,6 @@ import { act } from 'react-dom/test-utils';
3
3
  import { VisualizationAndMediaData } from './VisualizationAndMediaData';
4
4
  import { mount, render } from 'enzyme';
5
5
  import FormControl from '@material-ui/core/FormControl';
6
- jest.mock('react-file-drop', () => props => <div>{props.children}</div>);
7
6
 
8
7
  const mockDispatch = jest.fn();
9
8
  jest.mock('react-redux', () => ({
@@ -1,6 +1,7 @@
1
1
  import Actions, { REDUCER_NAME } from '../Reducers/Actions';
2
2
  import SimpleNestedData from '../../../Components/FormFragments/SimpleNestedData';
3
3
  import generateConnectedEdit from '../../../Components/DefaultConnectedForm';
4
+ import TextFields from '../../Client/Components/TextFields';
4
5
  import { withLoadAction } from '../../../Components/withLoadAction';
5
6
  import { t } from '../../../App/i18n';
6
7
  import { CallToActionField } from '../../../Components/CallToActionField';
@@ -107,22 +108,8 @@ const formFields = [
107
108
  dynamicDefaultLabel: false
108
109
  },
109
110
  {
111
+ type: TextFields,
110
112
  name: 'texts',
111
- label: 'termsAndConditionsLink',
112
- type: 'intl',
113
- intl: {
114
- name: 'termsAndConditionsLink',
115
- type: 'text',
116
- },
117
- },
118
- {
119
- name: 'texts',
120
- label: 'Title',
121
- type: 'dataPrivacyLink',
122
- intl: {
123
- name: 'dataPrivacyLink',
124
- type: 'text',
125
- },
126
113
  },
127
114
  {
128
115
  name: 'customCss',
@@ -7,7 +7,7 @@ const initialState = {
7
7
  ...getDefaultEntityState(
8
8
  {
9
9
  id: null,
10
- texts: { value: [] },
10
+ texts: { value: [], constraints: { presence: true } },
11
11
  theme: {
12
12
  value: {},
13
13
  schema: {
@@ -3,6 +3,7 @@ import generateConnectedEdit from '../../../Components/DefaultConnectedForm';
3
3
  import { withLoadAction } from '../../../Components/withLoadAction';
4
4
  import SimpleNestedData from '../../../Components/FormFragments/SimpleNestedData';
5
5
  import { t, T } from '../../../App/i18n';
6
+ import TextFields from '../../Client/Components/TextFields';
6
7
  import PdfMarkDownField from '../../Client/Components/PdfMarkdownField';
7
8
 
8
9
  const formFields = [
@@ -123,22 +124,8 @@ const formFields = [
123
124
  ],
124
125
  },
125
126
  {
127
+ type: TextFields,
126
128
  name: 'texts',
127
- label: 'termsAndConditionsLink',
128
- type: 'intl',
129
- intl: {
130
- name: 'termsAndConditionsLink',
131
- type: 'text',
132
- },
133
- },
134
- {
135
- name: 'texts',
136
- label: 'dataPrivacyLink',
137
- type: 'intl',
138
- intl: {
139
- name: 'dataPrivacyLink',
140
- type: 'text',
141
- },
142
129
  },
143
130
  {
144
131
  name: 'customCss',
@@ -12,7 +12,7 @@ const initialState = {
12
12
  theme: {
13
13
  value: {},
14
14
  schema: {
15
- highlightColor: { value: '' },
15
+ highlightColor: { value: '', constraints: { presence: true } },
16
16
  logo: { value: '' },
17
17
  font: { value: '' },
18
18
  },
@@ -7,6 +7,6 @@ import { generateDefaultActions } from '../../../App/Reducers/Entity/Actions';
7
7
 
8
8
  const actions = generateDefaultActions(LIST_KEY, DATA_KEY, REDUCER_NAME, GROUPS_URL);
9
9
 
10
- export const { hideDetails, loadEntity, postData } = actions;
10
+ export const { hideDetails, loadEntity } = actions;
11
11
 
12
12
  export default actions;
@@ -8,7 +8,6 @@ import TableHead from '@material-ui/core/TableHead';
8
8
  import TableRow from '@material-ui/core/TableRow';
9
9
  import Checkbox from '@material-ui/core/Checkbox/Checkbox';
10
10
  import TablePagination from '@material-ui/core/TablePagination';
11
- import uniq from 'lodash/uniq';
12
11
  import { addReduxListener, removeReduxListener } from '../../../../App/ReduxListener';
13
12
  import { t } from '../../../../App/i18n';
14
13
  import Actions, { ITEM_REDUCER_NAME } from '../../Reducers/Actions';
@@ -65,7 +64,7 @@ const getGroupsFromChildren = children => {
65
64
  }
66
65
  }
67
66
 
68
- return { groups, groupIdsInOrder: uniq(groupIdsInOrder) };
67
+ return { groups, groupIdsInOrder };
69
68
  };
70
69
 
71
70
  const prepareDataForRendering = children => {
@@ -223,7 +222,7 @@ class VariantsEditor extends Component {
223
222
 
224
223
  this.setState({
225
224
  groups,
226
- groupIdsInOrder: uniq(groupIdsInOrder),
225
+ groupIdsInOrder,
227
226
  });
228
227
  };
229
228
 
@@ -8,7 +8,6 @@ import * as GroupActions from '../../../Group/Reducers/Actions';
8
8
  import * as GroupEntryActions from '../../../GroupEntry/Reducers/Actions';
9
9
 
10
10
  import { T } from '../../../../App/i18n';
11
- import { resetDidInvalidate } from '../../../../App/Reducers/Api/Actions';
12
11
 
13
12
  export class VariantsEditorPopup extends React.Component {
14
13
  render() {
@@ -22,11 +21,7 @@ export class VariantsEditorPopup extends React.Component {
22
21
  open={showGroupEditor}
23
22
  scroll={'paper'}
24
23
  >
25
- <GroupEdit
26
- customPostData={this.props.customPostData}
27
- onCancel={this.props.cancelGroup}
28
- closeAfterSave
29
- />
24
+ <GroupEdit onCancel={this.props.cancelGroup} closeAfterSave />
30
25
  </Dialog>
31
26
 
32
27
  <Dialog
@@ -56,11 +51,6 @@ const renderDispatchToProps = dispatch => ({
56
51
  cancelGroup: () => {
57
52
  dispatch(GroupActions.hideDetails(false));
58
53
  },
59
- customPostData: async () => {
60
- await dispatch(GroupActions.postData(true));
61
- // need to reset didInvalidate flag as it is set on save of group which is blocking to reloadList
62
- dispatch(resetDidInvalidate(GroupActions.GROUPS_URL));
63
- },
64
54
  cancelGroupEntry: () => {
65
55
  dispatch(GroupEntryActions.hideDetails(false));
66
56
  },
@@ -49,7 +49,11 @@ const errorHandler = dispatch => error => {
49
49
  };
50
50
 
51
51
  export const postLoginData = (username, password) => dispatch => {
52
- return dispatchPostData(dispatch)(LOGIN_DATA_KEY, 'login_check', {username, password}).then(apiAction => {
52
+ const data = new ObjectFormData({
53
+ _username: username,
54
+ _password: password,
55
+ });
56
+ return dispatchPostData(dispatch)(LOGIN_DATA_KEY, 'login_check', data).then(apiAction => {
53
57
  return dispatch(apiActionHandler(apiAction, receiveHandler, errorHandler));
54
58
  });
55
59
  };