@configuratorware/configurator-admingui 1.26.5 → 1.27.2

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 (44) hide show
  1. package/package.json +2 -2
  2. package/src/App/Data.js +9 -0
  3. package/src/App/Reducers/Common/OrderList/Actions.js +11 -3
  4. package/src/App/Reducers/Common/OrderList/Listener.js +2 -2
  5. package/src/App/Reducers/Common/OrderList/Reducer.js +22 -3
  6. package/src/App/Styles.scss +19 -1
  7. package/src/Components/DefaultConnectedScreen.js +3 -2
  8. package/src/Components/DefaultScreen.js +10 -2
  9. package/src/Components/Form.js +4 -0
  10. package/src/Components/FormFragments/HintText.js +14 -0
  11. package/src/Components/FormFragments/InputArray.js +42 -13
  12. package/src/Components/FormFragments/SimpleTable.js +18 -2
  13. package/src/Components/FormFragments/Styles.scss +4 -0
  14. package/src/Components/FormFragments/Text.js +1 -0
  15. package/src/Components/FormFragments/index.js +3 -0
  16. package/src/Components/List.js +1 -0
  17. package/src/Components/OrderList.js +15 -7
  18. package/src/Components/Pagination.js +8 -0
  19. package/src/Components/SplitContainer.js +25 -2
  20. package/src/Components/Styles.scss +2 -0
  21. package/src/Components/Translations.js +6 -0
  22. package/src/Screens/ColorPalettes/Components/DefaultColorSwitch.js +54 -0
  23. package/src/Screens/ColorPalettes/Containers/Edit.js +39 -21
  24. package/src/Screens/ColorPalettes/Translations.js +1 -0
  25. package/src/Screens/Creator/Reducers/ConfigurationActions.js +1 -1
  26. package/src/Screens/DesignProductionMethods/Containers/Edit.js +0 -5
  27. package/src/Screens/DesignProductionMethods/Reducers/DesignProductionMethodsReducer.js +0 -1
  28. package/src/Screens/Designer/SubScreens/DesignAreas/Containers/FormProductionMethods.js +339 -256
  29. package/src/Screens/Designer/SubScreens/DesignAreas/Reducers/Reducer.js +26 -3
  30. package/src/Screens/Designer/SubScreens/DesignAreas/Translations.js +16 -2
  31. package/src/Screens/Designer/__tests__/FormProductionMethods.test.js +0 -2
  32. package/src/Screens/Designer/__tests__/__snapshots__/FormProductionMethods.test.js.snap +167 -50
  33. package/src/Screens/DesignerGlobalItemPrices/Containers/Edit.js +34 -6
  34. package/src/Screens/DesignerGlobalItemPrices/Reducers/Actions.js +1 -1
  35. package/src/Screens/DesignerGlobalItemPrices/Screen.js +3 -1
  36. package/src/Screens/DesignerGlobalItemPrices/Translations.js +8 -0
  37. package/src/Screens/Font/Containers/List.js +14 -3
  38. package/src/Screens/Item/Containers/Styles.scss +3 -0
  39. package/src/Screens/OptionPools/Containers/Edit.js +20 -0
  40. package/src/Screens/OptionPools/Reducers/Reducer.js +3 -2
  41. package/src/Screens/Setting/Containers/Edit.js +6 -0
  42. package/src/Screens/Setting/Reducers/Reducer.js +1 -0
  43. package/src/Screens/Setting/Translations.js +4 -0
  44. package/src/Screens/ColorPalettes/Components/DefaultColorRadio.js +0 -35
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@configuratorware/configurator-admingui",
3
- "version": "1.26.5",
3
+ "version": "1.27.2",
4
4
  "license": "UNLICENSED",
5
5
  "private": false,
6
6
  "files": [
@@ -87,7 +87,7 @@
87
87
  "react-redux-i18n": "^1.9.3",
88
88
  "react-router": "^3.0.2",
89
89
  "react-sortable-hoc": "^1.3.1",
90
- "redhotmagma-visualization": "1.26.5",
90
+ "redhotmagma-visualization": "1.27.2",
91
91
  "redux": "^4.0.1",
92
92
  "redux-logger": "^3.0.6",
93
93
  "redux-persist": "^5.10.0",
package/src/App/Data.js CHANGED
@@ -18,6 +18,15 @@ validate.validators.emptyOrPositive = function(value, options) {
18
18
  return t('customValidators.numericality');
19
19
  };
20
20
 
21
+ validate.validators.numericOrEmpty = function (value, options) {
22
+ if (value === '' || value === null ) {
23
+ return null;
24
+ }
25
+ else {
26
+ return validate.validators.numericality(value, options);
27
+ }
28
+ }
29
+
21
30
  validate.validators.identifier = function(value, options) {
22
31
  const pattern = /^[A-za-z0-9_.-]+$/;
23
32
  if (
@@ -2,13 +2,15 @@ import { dispatchFetchData } from '../../Api/Helpers';
2
2
 
3
3
  export const COMPONENT_KEY = 'order_list';
4
4
  export const COMPONENT_KEY_SAVE = 'order_list_save';
5
+ export const ORDER_LIST_SET_DATA_FIELD = 'ORDER_LIST//setDataField'
5
6
  export const ORDER_LIST_SET_URL = 'ORDER_LIST//setUrl';
6
7
  export const ORDER_LIST_MOVE_ITEM = 'ORDER_LIST//moveItem';
7
8
  export const ORDER_LIST_SAVE_LIST = 'ORDER_LIST//saveList';
8
9
  export const ORDER_LIST_SET_STATUS = 'ORDER_LIST//setStatus';
9
10
 
10
- export const loadList = dispatch => (url, entity, orderSequenceNumber, filters = {}) => {
11
- dispatch(setUrl(url));
11
+ export const loadList = dispatch => (url, entity, orderSequenceNumber, filters = {}, dataField = null, postUrl = null) => {
12
+ dispatch(setUrl(url, postUrl));
13
+ dispatch(setDataField(dataField));
12
14
  return dispatchFetchData(dispatch)(COMPONENT_KEY, {
13
15
  url,
14
16
  params: { orderby: `${entity}.${orderSequenceNumber}`, filters: { ...filters } },
@@ -25,9 +27,15 @@ export const saveList = () => ({
25
27
  type: ORDER_LIST_SAVE_LIST,
26
28
  });
27
29
 
28
- export const setUrl = url => ({
30
+ export const setUrl = (url, postUrl) => ({
29
31
  type: ORDER_LIST_SET_URL,
30
32
  url,
33
+ postUrl
34
+ });
35
+
36
+ export const setDataField = dataField => ({
37
+ type: ORDER_LIST_SET_DATA_FIELD,
38
+ dataField,
31
39
  });
32
40
 
33
41
  export const setSaveStatus = (status, error = null) => ({
@@ -5,12 +5,12 @@ import { dispatchPostData, RECEIVE_DATA } from '../../Api/Helpers';
5
5
  export const orderListListener = {
6
6
  [ORDER_LIST_SAVE_LIST]: (action, dispatch, state) => {
7
7
  const { orderList } = state;
8
- const { list, url } = orderList;
8
+ const { list, url, postUrl } = orderList;
9
9
  const data = list.map(({ id }, idx) => ({
10
10
  id,
11
11
  sequencenumber: idx + 1,
12
12
  }));
13
- dispatchPostData(dispatch)(COMPONENT_KEY_SAVE, `${url}/savesequencenumbers`, data).then(res => {
13
+ dispatchPostData(dispatch)(COMPONENT_KEY_SAVE, postUrl || `${url}/savesequencenumbers`, data).then(res => {
14
14
  if (res.type === RECEIVE_DATA) {
15
15
  dispatch(setSaveStatus(true));
16
16
  } else {
@@ -1,6 +1,12 @@
1
1
  import { RECEIVE_DATA } from '../../Api/Helpers';
2
2
 
3
- import { COMPONENT_KEY, ORDER_LIST_MOVE_ITEM, ORDER_LIST_SET_URL, ORDER_LIST_SET_STATUS } from './Actions';
3
+ import {
4
+ COMPONENT_KEY,
5
+ ORDER_LIST_MOVE_ITEM,
6
+ ORDER_LIST_SET_URL,
7
+ ORDER_LIST_SET_STATUS,
8
+ ORDER_LIST_SET_DATA_FIELD
9
+ } from './Actions';
4
10
 
5
11
  import { arrayMove } from 'react-sortable-hoc';
6
12
  import { addReduxListener } from '../../../ReduxListener';
@@ -11,16 +17,20 @@ addReduxListener(orderListListener);
11
17
  const initialState = {
12
18
  list: null,
13
19
  url: null,
20
+ postUrl: null,
14
21
  saved: null,
22
+ dataField: null,
15
23
  };
16
24
 
17
25
  export const orderList = (state = initialState, action = {}) => {
18
26
  switch (action.type) {
19
27
  case RECEIVE_DATA: {
20
28
  if (action.key === COMPONENT_KEY) {
29
+ const { dataField } = state;
30
+ const list = (dataField && action.data && action.data[dataField]) ? action.data[dataField] : action.data.data;
21
31
  return {
22
32
  ...state,
23
- list: action.data.data,
33
+ list
24
34
  };
25
35
  }
26
36
  return state;
@@ -35,11 +45,20 @@ export const orderList = (state = initialState, action = {}) => {
35
45
  };
36
46
  }
37
47
 
48
+ case ORDER_LIST_SET_DATA_FIELD: {
49
+ const { dataField } = action;
50
+ return {
51
+ ...state,
52
+ dataField
53
+ };
54
+ }
55
+
38
56
  case ORDER_LIST_SET_URL: {
39
- const { url } = action;
57
+ const { url, postUrl } = action;
40
58
  return {
41
59
  ...state,
42
60
  url,
61
+ postUrl,
43
62
  list: null,
44
63
  saved: null,
45
64
  };
@@ -42,8 +42,16 @@ div + h2 {
42
42
  min-height: calc(100vh - 64px);
43
43
  position: relative;
44
44
  }
45
-
45
+ .hideSave {
46
+ .form-inner > .action-buttons {
47
+ display: none
48
+ }
49
+ }
50
+ .hint {
51
+ font-size: 15px
52
+ }
46
53
  .split-left {
54
+ overflow-x: auto;
47
55
  width: 50%;
48
56
  float: left;
49
57
  display: inline-block;
@@ -53,11 +61,21 @@ div + h2 {
53
61
  width: 50%;
54
62
  display: inline-block;
55
63
  padding-left: 0.6em;
64
+ padding-top: 40px;
65
+ position: relative;
66
+ .close-details {
67
+ position: absolute;
68
+ right: -10px;
69
+ top: -5px;
70
+ }
56
71
  }
57
72
  @media (max-width: 960px) {
58
73
  .split-left {
59
74
  display: none;
60
75
  }
76
+ .withDetails.hint {
77
+ display: none;
78
+ }
61
79
  .split-right {
62
80
  width: 100%;
63
81
  padding: 0;
@@ -53,10 +53,11 @@ export const generateConnectedSplitScreen = (
53
53
  reducerName,
54
54
  invalidateListAction,
55
55
  unsavedEntityAction,
56
- hideDetailsAction
56
+ hideDetailsAction,
57
+ hintText = null
57
58
  ) => {
58
59
  return connectDefault(
59
- generateDefaultScreen(title, ListComponent, EditComponent),
60
+ generateDefaultScreen(title, ListComponent, EditComponent, hintText),
60
61
  reducerName,
61
62
  invalidateListAction,
62
63
  unsavedEntityAction,
@@ -63,11 +63,13 @@ export default class DefaultScreen extends Component {
63
63
  ListComponent,
64
64
  EditComponent,
65
65
  ScreenComponent,
66
+ hintText,
66
67
  ...otherProps
67
68
  } = this.props;
68
69
  return (
69
70
  <ScreenComponent
70
71
  headlineText={title && T(title)}
72
+ hintText={hintText}
71
73
  showDetails={showDetails}
72
74
  listComponent={<ListComponent {...otherProps} />}
73
75
  detailsComponent={<EditComponent {...otherProps} />}
@@ -77,9 +79,15 @@ export default class DefaultScreen extends Component {
77
79
  }
78
80
  }
79
81
 
80
- export const generateDefaultScreen = (title, ListComponent, EditComponent) => {
82
+ export const generateDefaultScreen = (title, ListComponent, EditComponent, hintText = null) => {
81
83
  return props => (
82
- <DefaultScreen title={title} ListComponent={ListComponent} EditComponent={EditComponent} {...props} />
84
+ <DefaultScreen
85
+ title={title}
86
+ hintText={hintText}
87
+ ListComponent={ListComponent}
88
+ EditComponent={EditComponent}
89
+ {...props}
90
+ />
83
91
  );
84
92
  };
85
93
 
@@ -15,6 +15,7 @@ import File from './FormFragments/File';
15
15
  import SimpleTextEditor from './FormFragments/SimpleTextEditor';
16
16
  import MonacoEditor from './FormFragments/MonacoEditor';
17
17
  import InputGroup from './FormFragments/InputGroup';
18
+ import HintText from './FormFragments/HintText';
18
19
  import Label from './FormFragments/Label';
19
20
  import MarkDown from './FormFragments/MarkDown';
20
21
  import ValidatorCallbackProvider from './ValidatorCallbackProvider';
@@ -74,6 +75,8 @@ const getInputComponentByType = type => {
74
75
  return InputGroup;
75
76
  case 'markDown':
76
77
  return MarkDown;
78
+ case 'hinttext':
79
+ return HintText;
77
80
  default:
78
81
  return null;
79
82
  }
@@ -187,6 +190,7 @@ class ConfigurableForm extends Component {
187
190
  onChange: this.onChange,
188
191
  onAction: this.onAction,
189
192
  renderWrappedInput: this.renderWrappedInput,
193
+ helperText: input.helperText && T(input.helperText)
190
194
  };
191
195
 
192
196
  if (input.name) {
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import withStyles from '@material-ui/core/styles/withStyles';
3
+
4
+ export default withStyles(
5
+ () => ({
6
+ hint: {
7
+ fontSize: 15,
8
+ },
9
+ }),
10
+ { name: 'HintText' }
11
+ )(props => {
12
+ const { classes, renderHintText, value } = props;
13
+ return <span className={classes.hint}>{renderHintText(value)}</span>;
14
+ });
@@ -8,6 +8,7 @@ import Data from '../../App/Data';
8
8
  import nestedDataComponent from './NestedDataComponent';
9
9
  import { generateObjectPropertyStringComparator } from '../../App/Utils';
10
10
  import RaisedButton from '../../UIComponents/RaisedButton';
11
+ import Dialog from '../../UIComponents/Dialog';
11
12
  import Add from '../../UIComponents/icons/AddIcon';
12
13
  import { withValidatorCallbackContext } from '../ValidatorCallbackProvider';
13
14
 
@@ -20,6 +21,7 @@ class InputArray extends Component {
20
21
  this.state = {
21
22
  showEditor: false,
22
23
  selectedRow: false,
24
+ newItem: false,
23
25
  };
24
26
  }
25
27
 
@@ -117,7 +119,7 @@ class InputArray extends Component {
117
119
  onCancel = () => {
118
120
  const { schema } = this.props;
119
121
  schema.reset();
120
- this.setState({ selectedRow: false, showEditor: false });
122
+ this.setState({ selectedRow: false, showEditor: false, newItem: false });
121
123
  };
122
124
 
123
125
  onDelete = row => {
@@ -138,7 +140,7 @@ class InputArray extends Component {
138
140
  }
139
141
  const { schema } = this.props;
140
142
  schema.reset({ active: this });
141
- this.setState({ selectedRow: false, showEditor: true });
143
+ this.setState({ selectedRow: false, showEditor: true, newItem: !this.state.newItem });
142
144
  };
143
145
 
144
146
  isAddingDisabled() {
@@ -172,14 +174,21 @@ class InputArray extends Component {
172
174
  };
173
175
 
174
176
  render() {
175
- const { label, array, value, errors } = this.props;
177
+ const { label, array, value, errors, buttonsPosition = '', showPopup = false } = this.props;
176
178
  const { fields, disableDelete, disableEdit } = array;
179
+ const { newItem } = this.state;
177
180
  const columns = array.columns || fields;
178
181
  const selectedRows = this.state.selectedRow === false ? [] : [this.state.selectedRow];
179
182
 
180
183
  return (
181
184
  <div>
182
185
  {label && <div className="label">{label}</div>}
186
+ {buttonsPosition === 'top' && (
187
+ <div className="cancel-button">
188
+ {!showPopup && this.renderCancelButton()}
189
+ <div className="action-buttons">{this.renderAddButton()}</div>
190
+ </div>
191
+ )}
183
192
 
184
193
  {value.length > 0 && (
185
194
  <SimpleTable
@@ -192,17 +201,37 @@ class InputArray extends Component {
192
201
  />
193
202
  )}
194
203
 
195
- {this.state.showEditor && (
196
- <div>{fields.map((field, idx) => this.props.renderWrappedInput(field, idx))}</div>
197
- )}
198
-
199
- <div className="cancel-button">
200
- {this.renderCancelButton()}
201
- <div className="action-buttons">
202
- {this.renderAddButton()}
204
+ {this.state.showEditor &&
205
+ (showPopup ? (
206
+ <Dialog open={true}>
207
+ <div className="form">{fields.map((field, idx) => this.props.renderWrappedInput(field, idx))}</div>
208
+ <div className="overlay-actions">
209
+ {newItem && (
210
+ <RaisedButton
211
+ primary={true}
212
+ label={T('Save')}
213
+ onClick={() => {
214
+ this.addNewItem();
215
+ this.setState({ selectedRow: false, showEditor: false });
216
+ }}
217
+ />
218
+ )}
219
+ <RaisedButton
220
+ label={newItem ? T('Cancel') : T('Close')}
221
+ onClick={this.onCancel}
222
+ />
223
+ </div>
224
+ </Dialog>
225
+ ) : (
226
+ <div>{fields.map((field, idx) => this.props.renderWrappedInput(field, idx))}</div>
227
+ ))}
228
+
229
+ {buttonsPosition !== 'top' && (
230
+ <div className="cancel-button">
231
+ {!showPopup && this.renderCancelButton()}
232
+ <div className="action-buttons">{this.renderAddButton()}</div>
203
233
  </div>
204
- </div>
205
-
234
+ )}
206
235
  </div>
207
236
  );
208
237
  }
@@ -185,7 +185,16 @@ class SimpleTable extends Component {
185
185
  return (
186
186
  <TableRow key={index} style={style}>
187
187
  {columns.map((column, i) => (
188
- <TableRowColumn key={i} style={tableStyle.column}>
188
+ <TableRowColumn
189
+ key={i}
190
+ style={tableStyle.column}
191
+ onClick={e => {
192
+ if (column.disableSelection) {
193
+ e.preventDefault();
194
+ e.stopPropagation();
195
+ }
196
+ }}
197
+ >
189
198
  {column.renderValue
190
199
  ? column.renderValue(row[column.name], row)
191
200
  : row[column.name] !== null && row[column.name] !== undefined
@@ -193,7 +202,14 @@ class SimpleTable extends Component {
193
202
  : ''}
194
203
  </TableRowColumn>
195
204
  ))}
196
- <TableRowColumn key="actions" style={tableStyle.actionsColumn}>
205
+ <TableRowColumn
206
+ key="actions"
207
+ style={tableStyle.actionsColumn}
208
+ onClick={e => {
209
+ e.preventDefault();
210
+ e.stopPropagation();
211
+ }}
212
+ >
197
213
  {this.renderDeleteButton(index)}
198
214
  </TableRowColumn>
199
215
  </TableRow>
@@ -113,3 +113,7 @@
113
113
  .twoSideSelect-info {
114
114
  color: rgb(158, 158, 158);
115
115
  }
116
+
117
+ .overlay-actions {
118
+ text-align: right;
119
+ }
@@ -25,6 +25,7 @@ const text = props => (
25
25
  }}
26
26
  inputProps={props.inputProps}
27
27
  rows={props.rows || 1}
28
+ helperText={props.helperText}
28
29
  />
29
30
  );
30
31
 
@@ -24,6 +24,8 @@ import AutocompleteEntity from './AutocompleteEntity';
24
24
  export { AutocompleteEntity };
25
25
  import Value from './Value';
26
26
  export { Value };
27
+ import HintText from './HintText';
28
+ export { HintText };
27
29
 
28
30
  export default {
29
31
  Text,
@@ -39,4 +41,5 @@ export default {
39
41
  Chip,
40
42
  AutocompleteEntity,
41
43
  Value,
44
+ HintText,
42
45
  };
@@ -205,6 +205,7 @@ export default class List extends Component {
205
205
  onPaginationChange={this.onPaginationChange}
206
206
  rowsTotal={rowsTotal || data.length}
207
207
  colSpan={columns.length}
208
+ currentPage={this.props.listParams.offset / rowsPerPage}
208
209
  rowsPerPage={rowsPerPage}
209
210
  beforeElement={
210
211
  <div style={listStyle.groupButtons}>
@@ -17,7 +17,8 @@ import networkConfig from '../App/Config/network';
17
17
  const SortableItem = SortableElement(props => {
18
18
  return (
19
19
  <div>
20
- {props.number}. {props.translated_title} {props.identifier && props.identifier}
20
+ {props.number}. {props.translated_title ? props.translated_title : props.name}
21
+ {props.identifier && props.identifier}
21
22
  {props.thumbUrl && (
22
23
  <img
23
24
  className="sortlistThumb"
@@ -38,9 +39,10 @@ export class OrderList extends React.Component {
38
39
  showDialog: false,
39
40
  };
40
41
 
41
- componentWillReceiveProps(props) {
42
- if (props.saved) {
42
+ componentDidUpdate(prevProps) {
43
+ if (this.props.saved && this.props.saved !== prevProps.saved) {
43
44
  this.setState({ showDialog: false });
45
+ this.props.onListSaved && this.props.onListSaved();
44
46
  }
45
47
  }
46
48
 
@@ -52,7 +54,6 @@ export class OrderList extends React.Component {
52
54
 
53
55
  saveOrder = () => {
54
56
  this.props.saveList();
55
- this.setState({ showDialog: false });
56
57
  };
57
58
 
58
59
  openDialog = () => {
@@ -76,7 +77,14 @@ export class OrderList extends React.Component {
76
77
  }
77
78
 
78
79
  this.props
79
- .loadList(this.props.listUrl, this.props.entity, this.props.orderSequenceNumber, filters)
80
+ .loadList(
81
+ this.props.listUrl,
82
+ this.props.entity,
83
+ this.props.orderSequenceNumber,
84
+ filters,
85
+ this.props.listField,
86
+ this.props.saveListUrl
87
+ )
80
88
  .then(() => {
81
89
  this.setState({
82
90
  loading: false,
@@ -152,8 +160,8 @@ const mapStateToProps = ({ designerData, orderList }) => ({
152
160
  });
153
161
 
154
162
  const mapDispatchToProps = dispatch => ({
155
- loadList: (url, entity, orderSequenceNumber, filters) =>
156
- orderListActions.loadList(dispatch)(url, entity, orderSequenceNumber, filters),
163
+ loadList: (url, entity, orderSequenceNumber, filters, dataField, postUrl) =>
164
+ orderListActions.loadList(dispatch)(url, entity, orderSequenceNumber, filters, dataField, postUrl),
157
165
  moveItem: (oldIndex, newIndex) => dispatch(orderListActions.moveItem(oldIndex, newIndex)),
158
166
  saveList: () => dispatch(orderListActions.saveList()),
159
167
  });
@@ -18,6 +18,14 @@ export default class Pagination extends React.Component {
18
18
  };
19
19
  }
20
20
 
21
+ componentDidUpdate() {
22
+ if (this.state.currentPage !== this.props.currentPage) {
23
+ this.setState({ currentPage: this.props.currentPage });
24
+ } else if (this.state.rowsPerPage !== this.props.rowsPerPage) {
25
+ this.setState({ rowsPerPage: this.props.rowsPerPage });
26
+ }
27
+ }
28
+
21
29
  componentWillReceiveProps(props) {
22
30
  if (props.rowsTotal !== this.props.rowsTotal && props.rowsTotal !== 0) {
23
31
  const totalPages = Math.ceil(props.rowsTotal / this.state.rowsPerPage);
@@ -1,15 +1,38 @@
1
1
  import React from 'react';
2
+ import clsx from 'clsx';
2
3
  import { Headline } from './GeneralFragments';
4
+ import IconButton from '@material-ui/core/IconButton';
5
+ import Close from '../UIComponents/icons/CloseIcon';
6
+ import Tooltip from '../UIComponents/Tooltip';
7
+ import { T } from '../App/i18n';
3
8
 
4
9
  const SplitContainer = props => {
5
- const { showDetails, listComponent, detailsComponent, headlineText, className } = props;
10
+ const {
11
+ showDetails,
12
+ listComponent,
13
+ detailsComponent,
14
+ headlineText,
15
+ className,
16
+ hideDetailsAction,
17
+ hintText
18
+ } = props;
6
19
  return (
7
20
  <div className={'split-container ' + className}>
8
21
  <Headline text={headlineText} />
22
+ {hintText && <div className={clsx('hint', showDetails && 'withDetails')}>{hintText}</div>}
9
23
 
10
24
  <div className={showDetails ? 'split-left' : ''}>{listComponent}</div>
11
25
 
12
- {showDetails && <div className="split-right">{detailsComponent}</div>}
26
+ {showDetails && (
27
+ <div className="split-right">
28
+ <Tooltip title={T('detailView.close')}>
29
+ <IconButton onClick={() => hideDetailsAction()} className="close-details">
30
+ <Close />
31
+ </IconButton>
32
+ </Tooltip>
33
+ {detailsComponent}
34
+ </div>
35
+ )}
13
36
  </div>
14
37
  );
15
38
  };
@@ -48,6 +48,8 @@
48
48
 
49
49
  .form {
50
50
  text-align: center;
51
+ margin-top: 40px;
52
+
51
53
 
52
54
  .form-inner {
53
55
  margin: auto;
@@ -30,6 +30,9 @@ require('../App/i18n').use(
30
30
  deleteEntriesInfo: 'delete selected entries',
31
31
  deleteEntriesHint: 'Use the checkboxes to select one or more entries in the list<br>and then click this icon to delete them.',
32
32
  },
33
+ detailView: {
34
+ close: 'Close Editor',
35
+ },
33
36
  },
34
37
  de: {
35
38
  // LISTING AND EDITING
@@ -96,6 +99,9 @@ require('../App/i18n').use(
96
99
  deleteEntriesInfo: 'Gewählte Einträge löschen',
97
100
  deleteEntriesHint: 'Nutze die Checkboxen in der Liste und klicke dann dieses Icon,<br>um einen oder mehrere Einträge zu löschen.',
98
101
  },
102
+ detailView: {
103
+ close: 'Editor schließen',
104
+ },
99
105
  },
100
106
  },
101
107
  true
@@ -0,0 +1,54 @@
1
+ import React, { Component } from 'react';
2
+ import { connect } from 'react-redux';
3
+ import PropTypes from 'prop-types';
4
+ import get from 'lodash/get';
5
+ import Switch from '@material-ui/core/Switch';
6
+ import Actions, { COLORPALETTES_REDUCER_NAME } from '../Reducers/Actions';
7
+ import { withStyles } from '@material-ui/core/styles';
8
+
9
+ const styles = {
10
+ switchBase: {
11
+ height: 28,
12
+ },
13
+ };
14
+
15
+ export class DefaultColorSwitch extends Component {
16
+ static propTypes = {
17
+ color: PropTypes.object,
18
+ classes: PropTypes.object,
19
+ isDefaultColor: PropTypes.bool,
20
+ };
21
+
22
+ onToggle = e => {
23
+ this.props.setDefaultColor(this.props.isDefaultColor ? null : this.props.color);
24
+ };
25
+
26
+ render() {
27
+ const { classes } = this.props;
28
+ return (
29
+ <Switch
30
+ classes={{ switchBase: classes.switchBase }}
31
+ checked={this.props.isDefaultColor}
32
+ onClick={this.onToggle}
33
+ name="isDefaultColor"
34
+ color="primary"
35
+ />
36
+ );
37
+ }
38
+ }
39
+
40
+ const mapStateToProps = (state, ownProps) => {
41
+ const colorId = get(ownProps.color, 'id', null);
42
+ const defaultColorId = get(state, `${COLORPALETTES_REDUCER_NAME}.data.defaultColor.value.id`, null);
43
+
44
+ return {
45
+ isDefaultColor: colorId === defaultColorId,
46
+ };
47
+ };
48
+
49
+ const mapDispatchToProps = dispatch => ({
50
+ setDefaultColor: color => dispatch(Actions.setFieldData('defaultColor', color)),
51
+ });
52
+
53
+ export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(DefaultColorSwitch));
54
+