@configuratorware/configurator-frontendgui 1.34.2 → 1.35.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/App/Modules/Creator/Components/Option/index.js +42 -11
- package/App/Modules/Creator/Components/OptionsList/index.js +4 -1
- package/App/Modules/Creator/Components/ProductPart/index.js +19 -5
- package/App/Modules/Creator/Components/ProductPartsList/index.js +8 -4
- package/App/Modules/Creator/Containers/InvalidConfigurationNotice/index.js +6 -3
- package/App/Modules/Creator/Containers/OptionsList/index.js +5 -0
- package/App/Modules/Creator/Containers/ProductPartsList/index.js +8 -2
- package/App/Reducers/Configurator/Actions.js +80 -12
- package/App/Reducers/Configurator/Reducer.js +34 -1
- package/App/Services/ConfiguratorService.js +5 -0
- package/package.json +4 -4
- package/src/App/Modules/Creator/Components/Option/__snapshots__/index.test.js.snap +126 -67
- package/src/App/Modules/Creator/Components/Option/index.js +32 -3
- package/src/App/Modules/Creator/Components/Option/index.test.js +16 -0
- package/src/App/Modules/Creator/Components/OptionsList/index.js +3 -0
- package/src/App/Modules/Creator/Components/ProductPart/index.js +13 -5
- package/src/App/Modules/Creator/Components/ProductPartsList/index.js +4 -0
- package/src/App/Modules/Creator/Containers/InvalidConfigurationNotice/index.js +4 -1
- package/src/App/Modules/Creator/Containers/OptionsList/index.js +2 -0
- package/src/App/Modules/Creator/Containers/ProductPartsList/index.js +4 -1
- package/src/App/Reducers/Configurator/Actions.js +40 -0
- package/src/App/Reducers/Configurator/Reducer.js +31 -0
- package/src/App/Services/ConfiguratorService.js +4 -0
|
@@ -51,6 +51,7 @@ const ProductPartsList = ({
|
|
|
51
51
|
CallToActionComponent,
|
|
52
52
|
width,
|
|
53
53
|
optionListVisible,
|
|
54
|
+
onCloseSelectedPart,
|
|
54
55
|
}) => {
|
|
55
56
|
const classes = useStyles();
|
|
56
57
|
const [anchorRef, setAnchorRef] = useState(null);
|
|
@@ -72,6 +73,7 @@ const ProductPartsList = ({
|
|
|
72
73
|
selectedOption={selectedoptionclassification}
|
|
73
74
|
verticalMode={vertical}
|
|
74
75
|
optionListVisible={optionListVisible}
|
|
76
|
+
onCloseSelected={onCloseSelectedPart}
|
|
75
77
|
{...refProps}
|
|
76
78
|
/>
|
|
77
79
|
);
|
|
@@ -98,6 +100,7 @@ ProductPartsList.defaultProps = {
|
|
|
98
100
|
showStartHere: false,
|
|
99
101
|
vertical: true,
|
|
100
102
|
ProductPartComponent: ProductPart,
|
|
103
|
+
onCloseSelectedPart: () => {},
|
|
101
104
|
};
|
|
102
105
|
|
|
103
106
|
ProductPartsList.propTypes = {
|
|
@@ -111,6 +114,7 @@ ProductPartsList.propTypes = {
|
|
|
111
114
|
CallToActionComponent: PropTypes.elementType,
|
|
112
115
|
width: PropTypes.string,
|
|
113
116
|
optionListVisible: PropTypes.bool,
|
|
117
|
+
onCloseSelectedPart: PropTypes.func,
|
|
114
118
|
};
|
|
115
119
|
|
|
116
120
|
export default withWidth({ initialWidth: 'lg' })(ProductPartsList);
|
|
@@ -22,8 +22,11 @@ const getValidationErrors = configuratorState => {
|
|
|
22
22
|
return !optionclassifications
|
|
23
23
|
? []
|
|
24
24
|
: Object.entries(errors).map(([key, error]) => ({
|
|
25
|
-
title:
|
|
25
|
+
title:
|
|
26
|
+
optionclassifications.find(({ identifier }) => identifier === key)?.title ||
|
|
27
|
+
error.componentTitle,
|
|
26
28
|
errors: error.errors,
|
|
29
|
+
key,
|
|
27
30
|
}));
|
|
28
31
|
});
|
|
29
32
|
};
|
|
@@ -3,6 +3,7 @@ import { setStockInformationOption } from 'App/Reducers/Configurator/Actions';
|
|
|
3
3
|
import { setVisible } from 'App/Reducers/UI/Actions';
|
|
4
4
|
import OptionsList from '../../Components/OptionsList';
|
|
5
5
|
import { getConf } from '../../../../configuration';
|
|
6
|
+
import { Services } from 'App/ServiceLocator';
|
|
6
7
|
|
|
7
8
|
const mapStateToProps = ({ ui, configurator, api }) => {
|
|
8
9
|
const showDialog = !!ui.visibilityMap.incompatibility || !!ui.visibilityMap.optionDetails;
|
|
@@ -23,6 +24,7 @@ const mapDispatchToProps = dispatch => ({
|
|
|
23
24
|
dispatch(setVisible('stockInformation', true));
|
|
24
25
|
},
|
|
25
26
|
onClose: () => dispatch(setVisible('optionlist', false)),
|
|
27
|
+
setOptionInputText: (identifier, value) => Services.configurator.setOptionInputText(identifier, value),
|
|
26
28
|
});
|
|
27
29
|
|
|
28
30
|
export default containerConnect(mapStateToProps, mapDispatchToProps);
|
|
@@ -4,6 +4,7 @@ import { getConf } from 'App/configuration';
|
|
|
4
4
|
import { getComponent } from 'App/configuration';
|
|
5
5
|
import CallToAction from 'App/Shared/Components/CallToAction';
|
|
6
6
|
import memoize from 'Utils/Function/memoize';
|
|
7
|
+
import { applyOptionInputText } from '../../../../Reducers/Configurator/Actions';
|
|
7
8
|
|
|
8
9
|
const removeHiddenComponents = memoize(components =>
|
|
9
10
|
components.filter(({ hiddenInFrontend }) => !hiddenInFrontend)
|
|
@@ -24,6 +25,8 @@ const mapStateToProps = ({ configurator, device, ui }) => {
|
|
|
24
25
|
};
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
const mapDispatchToProps =
|
|
28
|
+
const mapDispatchToProps = dispatch => ({
|
|
29
|
+
onCloseSelectedPart: optionClassification => dispatch(applyOptionInputText(optionClassification)),
|
|
30
|
+
});
|
|
28
31
|
|
|
29
32
|
export default containerConnect(mapStateToProps, mapDispatchToProps);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as apiActions from '../Actions';
|
|
2
2
|
import { first, isObject, get, isArray, flatten } from 'lodash';
|
|
3
|
+
import find from 'lodash/find';
|
|
3
4
|
import uniq from 'lodash/uniq';
|
|
4
5
|
import { t } from 'Framework/i18n';
|
|
5
6
|
import Api from 'Framework/Api';
|
|
@@ -60,6 +61,8 @@ export const SET_CALCULATION_AUTO_RESOLVE_ENABLED = 'SET_CALCULATION_AUTO_RESOLV
|
|
|
60
61
|
export const SET_OPTIONCLASSIFICATION_CHECKED = 'SET_OPTIONCLASSIFICATION_CHECKED';
|
|
61
62
|
export const SET_CONFLICTING_SWITCHOPTION_DATA = 'SET_CONFLICTING_SWITCHOPTION_DATA';
|
|
62
63
|
export const SET_SELECTED_AMOUNT = 'SET_SELECTED_AMOUNT';
|
|
64
|
+
export const SET_OPTION_INPUT_TEXT = 'SET_OPTION_INPUT_TEXT';
|
|
65
|
+
export const RESET_OPTION_INPUT_TEXTS = 'RESET_OPTION_INPUT_TEXTS';
|
|
63
66
|
export const SWITCH_SELECTED_AMOUNT = 'SWITCH_SELECTED_AMOUNT';
|
|
64
67
|
export const SAVE_BULKNAMES = 'SAVE_BULKNAMES';
|
|
65
68
|
export const CLEAR_BULKNAMES = 'CLEAR_BULKNAMES';
|
|
@@ -731,6 +734,7 @@ export const selectOption = (
|
|
|
731
734
|
component: optionclassification.identifier,
|
|
732
735
|
option: option.identifier,
|
|
733
736
|
});
|
|
737
|
+
|
|
734
738
|
const switchOptionData = {
|
|
735
739
|
[optionclassification.identifier]: {
|
|
736
740
|
...option,
|
|
@@ -744,6 +748,32 @@ export const selectOption = (
|
|
|
744
748
|
return dispatch(switchOptions(configuration, switchOptionData, false, refreshOptionlist, true));
|
|
745
749
|
};
|
|
746
750
|
|
|
751
|
+
export const applyOptionInputText = optionClassification => (dispatch, getState) => {
|
|
752
|
+
const switchOptionData = { [optionClassification.identifier]: [] };
|
|
753
|
+
const { configuration, optionInputTexts } = getState().configurator;
|
|
754
|
+
if (!optionClassification.selectedoptions) {
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
for (let selectedOption of optionClassification.selectedoptions) {
|
|
758
|
+
const inputText = get(
|
|
759
|
+
find(optionInputTexts, ['optionIdentifier', selectedOption.identifier]),
|
|
760
|
+
'inputText',
|
|
761
|
+
null
|
|
762
|
+
);
|
|
763
|
+
if (inputText && inputText !== selectedOption.inputText) {
|
|
764
|
+
switchOptionData[optionClassification.identifier].push({
|
|
765
|
+
...selectedOption,
|
|
766
|
+
inputText: inputText,
|
|
767
|
+
check_results: null,
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
dispatch(resetOptionInputTexts());
|
|
772
|
+
if (switchOptionData[optionClassification.identifier].length > 0) {
|
|
773
|
+
return dispatch(switchOptions(configuration, switchOptionData, false, true, true));
|
|
774
|
+
}
|
|
775
|
+
};
|
|
776
|
+
|
|
747
777
|
export const selectMultipleOptions = optionsList => (dispatch, getState) => {
|
|
748
778
|
const configuration = getConfiguration(getConfigurator(getState()));
|
|
749
779
|
const switchOptionData = {};
|
|
@@ -870,3 +900,13 @@ export const setSelectedCalculation = (identifier, value) => ({
|
|
|
870
900
|
identifier,
|
|
871
901
|
value,
|
|
872
902
|
});
|
|
903
|
+
|
|
904
|
+
export const setOptionInputText = (identifier, value) => ({
|
|
905
|
+
type: SET_OPTION_INPUT_TEXT,
|
|
906
|
+
identifier,
|
|
907
|
+
value,
|
|
908
|
+
});
|
|
909
|
+
|
|
910
|
+
export const resetOptionInputTexts = () => ({
|
|
911
|
+
type: RESET_OPTION_INPUT_TEXTS,
|
|
912
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as actionTypes from './Actions';
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
|
+
import findIndex from 'lodash/findIndex';
|
|
4
5
|
import omit from 'lodash/omit';
|
|
5
6
|
import forEach from 'lodash/forEach';
|
|
6
7
|
import reduce from 'lodash/reduce';
|
|
@@ -34,6 +35,7 @@ const initialState = {
|
|
|
34
35
|
filteredOptionclassifications: [],
|
|
35
36
|
selectedVariantIdentifier: null,
|
|
36
37
|
selectedAmountsUpdated: false,
|
|
38
|
+
optionInputTexts: [],
|
|
37
39
|
};
|
|
38
40
|
|
|
39
41
|
export function configurationHandler(state, action) {
|
|
@@ -536,6 +538,35 @@ export function configurationModifierHandler(state, action) {
|
|
|
536
538
|
);
|
|
537
539
|
}
|
|
538
540
|
|
|
541
|
+
case actionTypes.SET_OPTION_INPUT_TEXT: {
|
|
542
|
+
const optionInputTexts = state.optionInputTexts;
|
|
543
|
+
const optionInputTextIndex = findIndex(optionInputTexts, ['optionIdentifier', action.identifier]);
|
|
544
|
+
if (optionInputTextIndex !== -1) {
|
|
545
|
+
optionInputTexts[optionInputTextIndex] = {
|
|
546
|
+
optionIdentifier: action.identifier,
|
|
547
|
+
inputText: action.value,
|
|
548
|
+
};
|
|
549
|
+
} else if (optionInputTextIndex === -1 && action.value) {
|
|
550
|
+
optionInputTexts.push({
|
|
551
|
+
optionIdentifier: action.identifier,
|
|
552
|
+
inputText: action.value,
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
return {
|
|
556
|
+
...state,
|
|
557
|
+
optionInputTexts,
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
case actionTypes.RESET_OPTION_INPUT_TEXTS: {
|
|
562
|
+
const optionInputTexts = [];
|
|
563
|
+
|
|
564
|
+
return {
|
|
565
|
+
...state,
|
|
566
|
+
optionInputTexts,
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
|
|
539
570
|
default:
|
|
540
571
|
return state;
|
|
541
572
|
}
|
|
@@ -724,6 +724,10 @@ export default class ConfiguratorService extends AbstractConfiguratorService {
|
|
|
724
724
|
return Services.store.dispatch(configuratorActions.setSelectedVariantIdentifier(identifier));
|
|
725
725
|
}
|
|
726
726
|
|
|
727
|
+
setOptionInputText(identifier, value) {
|
|
728
|
+
return Services.store.dispatch(configuratorActions.setOptionInputText(identifier, value));
|
|
729
|
+
}
|
|
730
|
+
|
|
727
731
|
/**
|
|
728
732
|
* A simple method for saving the configuration without any additional design data or screenshot
|
|
729
733
|
* @param {string} saveType
|