@configuratorware/configurator-frontendgui 1.29.4 → 1.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/App/Modules/Creator/Components/Option/index.js +2 -2
- package/App/Modules/Creator/Components/OptionsList/index.js +54 -28
- package/App/Modules/Designer/Components/ImageColorPicker/ImageColorPicker.js +5 -6
- package/App/Modules/Designer/Components/ImageEditDialog/ImageThumbnail.js +1 -1
- package/App/Modules/Designer/Components/ImageEditDialog/index.js +3 -1
- package/App/Modules/Designer/Containers/ImageEditDialog.js +163 -113
- package/App/Modules/Designer/Utils/SvgFixers.js +59 -0
- package/App/Modules/Designer/Utils/Transformers.js +17 -10
- package/App/Reducers/ImageGallery/Selectors.js +6 -3
- package/App/Services/AnalyticsService.js +13 -64
- package/App/Services/ConfiguratorService.js +4 -2
- package/App/Services/DesignDataService.js +125 -138
- package/App/configuration.js +1 -1
- package/package.json +4 -4
- package/src/App/Modules/Creator/Components/Option/__snapshots__/index.test.js.snap +2 -2
- package/src/App/Modules/Creator/Components/Option/index.js +12 -2
- package/src/App/Modules/Creator/Components/OptionsList/index.js +46 -32
- package/src/App/Modules/Designer/Components/ImageColorPicker/ImageColorPicker.js +5 -6
- package/src/App/Modules/Designer/Components/ImageEditDialog/ImageThumbnail.js +1 -1
- package/src/App/Modules/Designer/Components/ImageEditDialog/index.js +3 -1
- package/src/App/Modules/Designer/Containers/ImageEditDialog.js +36 -12
- package/src/App/Modules/Designer/Utils/SvgFixers.js +36 -0
- package/src/App/Modules/Designer/Utils/Transformers.js +6 -3
- package/src/App/Modules/Designer/Utils/__tests__/Transformers.test.js +2 -2
- package/src/App/Reducers/ImageGallery/Selectors.js +5 -3
- package/src/App/Services/AnalyticsService.js +7 -20
- package/src/App/Services/ConfiguratorService.js +3 -2
- package/src/App/Services/DesignDataService.js +39 -24
- package/src/App/Services/__tests__/AnalyticsService.test.js +24 -37
- package/src/App/configuration.js +1 -1
package/App/configuration.js
CHANGED
|
@@ -31,7 +31,7 @@ var DEVELOPMENT_HOST_INT = 'http://int.configuratorware.local'; // eslint-disabl
|
|
|
31
31
|
var DEVELOPMENT_HOST_LOCAL = 'http://localhost:10030';
|
|
32
32
|
var hostsByNodeEnv = {
|
|
33
33
|
production: '',
|
|
34
|
-
development:
|
|
34
|
+
development: DEVELOPMENT_HOST_LOCAL,
|
|
35
35
|
test: ''
|
|
36
36
|
};
|
|
37
37
|
var resourceUrlsByNodeEnv = {
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@configuratorware/configurator-frontendgui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "./index.js",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@babel/polyfill": "^7.12.1",
|
|
9
|
-
"@configuratorware/scripts": "1.
|
|
9
|
+
"@configuratorware/scripts": "1.30.0",
|
|
10
10
|
"@hot-loader/react-dom": "^17.0.1",
|
|
11
11
|
"@material-ui/core": "^4.12.2",
|
|
12
12
|
"@material-ui/icons": "^4.11.2",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"react-router-dom": "^5.2.0",
|
|
40
40
|
"react-swipeable": "^5.5.1",
|
|
41
41
|
"react-zoom-pan-pinch": "^2.1.3",
|
|
42
|
-
"redhotmagma-graphics-editor": "1.
|
|
43
|
-
"redhotmagma-visualization": "1.
|
|
42
|
+
"redhotmagma-graphics-editor": "1.30.0",
|
|
43
|
+
"redhotmagma-visualization": "1.30.0",
|
|
44
44
|
"redux": "^4.1.0",
|
|
45
45
|
"redux-logger": "^3.0.6",
|
|
46
46
|
"redux-persist": "^5.10.0",
|
|
@@ -128,7 +128,7 @@ exports[`Option renders with Incompatibility link 1`] = `
|
|
|
128
128
|
>
|
|
129
129
|
<svg
|
|
130
130
|
aria-hidden="true"
|
|
131
|
-
class="MuiSvgIcon-root Option-materialIcon-50"
|
|
131
|
+
class="MuiSvgIcon-root Option-materialIcon-50 custom-css-rule-info-icon-option"
|
|
132
132
|
focusable="false"
|
|
133
133
|
viewBox="0 0 24 24"
|
|
134
134
|
>
|
|
@@ -397,7 +397,7 @@ exports[`Option renders with details 1`] = `
|
|
|
397
397
|
>
|
|
398
398
|
<svg
|
|
399
399
|
aria-hidden="true"
|
|
400
|
-
class="MuiSvgIcon-root Option-materialIcon-39"
|
|
400
|
+
class="MuiSvgIcon-root Option-materialIcon-39 custom-css-rule-info-icon-option"
|
|
401
401
|
focusable="false"
|
|
402
402
|
viewBox="0 0 24 24"
|
|
403
403
|
>
|
|
@@ -357,7 +357,12 @@ const Option = ({ children, render, ...props }) => {
|
|
|
357
357
|
{displayDetails && (
|
|
358
358
|
<div>
|
|
359
359
|
<a className={classes.iconWithText} onClick={onDetailsClicked}>
|
|
360
|
-
<InfoRoundedIcon
|
|
360
|
+
<InfoRoundedIcon
|
|
361
|
+
className={clsx(
|
|
362
|
+
classes.materialIcon,
|
|
363
|
+
customClassName('rule-info-icon-option')
|
|
364
|
+
)}
|
|
365
|
+
/>
|
|
361
366
|
<Typography variant={'body2'} className={classes.iconWithText}>
|
|
362
367
|
{translations.details}
|
|
363
368
|
</Typography>
|
|
@@ -368,7 +373,12 @@ const Option = ({ children, render, ...props }) => {
|
|
|
368
373
|
{resultStatus !== true && (
|
|
369
374
|
<div>
|
|
370
375
|
<a className={classes.iconWithText} onClick={onIncompatibilityClicked}>
|
|
371
|
-
<WarningRoundedIcon
|
|
376
|
+
<WarningRoundedIcon
|
|
377
|
+
className={clsx(
|
|
378
|
+
classes.materialIcon,
|
|
379
|
+
customClassName('rule-alert-icon-option')
|
|
380
|
+
)}
|
|
381
|
+
/>
|
|
372
382
|
<Typography variant={'body2'}>{translations.incompatibility}</Typography>
|
|
373
383
|
</a>
|
|
374
384
|
</div>
|
|
@@ -56,22 +56,24 @@ const useStyles = makeStyles(
|
|
|
56
56
|
}
|
|
57
57
|
);
|
|
58
58
|
|
|
59
|
-
const OptionsList = ({
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
59
|
+
const OptionsList = ({ render, ...props }) => {
|
|
60
|
+
const {
|
|
61
|
+
addCheckedOptionclassification,
|
|
62
|
+
children,
|
|
63
|
+
isLoading,
|
|
64
|
+
onClose,
|
|
65
|
+
onSelect,
|
|
66
|
+
onToggle,
|
|
67
|
+
optionclassification,
|
|
68
|
+
options,
|
|
69
|
+
show,
|
|
70
|
+
viewDetails,
|
|
71
|
+
viewStockInformation,
|
|
72
|
+
LoadingComponent,
|
|
73
|
+
OptionComponent,
|
|
74
|
+
isAdminMode,
|
|
75
|
+
} = props;
|
|
76
|
+
|
|
75
77
|
const classes = useStyles();
|
|
76
78
|
|
|
77
79
|
const createOptions = () => {
|
|
@@ -130,22 +132,33 @@ const OptionsList = ({
|
|
|
130
132
|
);
|
|
131
133
|
};
|
|
132
134
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
135
|
+
const renderOptionsList = () => {
|
|
136
|
+
return (
|
|
137
|
+
<CustomDialog
|
|
138
|
+
className={clsx(classes.dialogStyle, customClassName('options'))}
|
|
139
|
+
dialogTitle={optionclassification.title}
|
|
140
|
+
onCancel={onClose}
|
|
141
|
+
onClose={onClose}
|
|
142
|
+
open={show && !!optionclassification.identifier}
|
|
143
|
+
BackdropProps={{
|
|
144
|
+
classes: {
|
|
145
|
+
root: classes.backDrop,
|
|
146
|
+
},
|
|
147
|
+
}}
|
|
148
|
+
>
|
|
149
|
+
<DialogContent className={classes.contentStyle}>{renderOptions()}</DialogContent>
|
|
150
|
+
</CustomDialog>
|
|
151
|
+
);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const getRenderProps = () => ({
|
|
155
|
+
...props,
|
|
156
|
+
renderOptions,
|
|
157
|
+
createOptions,
|
|
158
|
+
renderOptionsList,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
return typeof render === 'function' ? render(getRenderProps()) : renderOptionsList();
|
|
149
162
|
};
|
|
150
163
|
|
|
151
164
|
OptionsList.defaultProps = {
|
|
@@ -178,6 +191,7 @@ OptionsList.propTypes = {
|
|
|
178
191
|
LoadingComponent: PropTypes.elementType,
|
|
179
192
|
OptionComponent: PropTypes.elementType,
|
|
180
193
|
isAdminMode: PropTypes.bool,
|
|
194
|
+
render: PropTypes.func,
|
|
181
195
|
};
|
|
182
196
|
|
|
183
197
|
export default OptionsList;
|
|
@@ -210,17 +210,16 @@ export class ImageColorPicker extends React.Component {
|
|
|
210
210
|
const { width: pw, height: ph } = container.getBoundingClientRect();
|
|
211
211
|
const { width: ow, height: oh } = img;
|
|
212
212
|
|
|
213
|
-
const pa = pw / ph;
|
|
214
213
|
const oa = ow / oh;
|
|
215
214
|
|
|
216
|
-
if (
|
|
217
|
-
const height =
|
|
218
|
-
const width =
|
|
215
|
+
if (oa <= 1) {
|
|
216
|
+
const height = ph;
|
|
217
|
+
const width = height * (ow / oh);
|
|
219
218
|
|
|
220
219
|
this.updateCanvasDimensionsAndContent(canvas, img, width, height);
|
|
221
220
|
} else {
|
|
222
|
-
const width =
|
|
223
|
-
const height =
|
|
221
|
+
const width = pw;
|
|
222
|
+
const height = width * (oh / ow);
|
|
224
223
|
|
|
225
224
|
this.updateCanvasDimensionsAndContent(canvas, img, width, height);
|
|
226
225
|
}
|
|
@@ -32,6 +32,7 @@ import ColorPicker from '../ImageColorPicker/ImageColorPicker';
|
|
|
32
32
|
import ImageThumbnail from './ImageThumbnail';
|
|
33
33
|
import colorizeIcon from './res/baseline_colorize_black_24dp.png';
|
|
34
34
|
import checkers from './res/checkers_tile.png';
|
|
35
|
+
import { isOriginalVector } from '../../Utils/Transformers';
|
|
35
36
|
|
|
36
37
|
const styles = theme => ({
|
|
37
38
|
dialogContent: {
|
|
@@ -499,7 +500,8 @@ class ImageEditDialog extends React.Component {
|
|
|
499
500
|
src={
|
|
500
501
|
[0, 2].includes(activeTabIndex) &&
|
|
501
502
|
!displayColorPreview &&
|
|
502
|
-
!image.gallery
|
|
503
|
+
!image.gallery &&
|
|
504
|
+
!isOriginalVector(image)
|
|
503
505
|
? originalImagePreview
|
|
504
506
|
: preview
|
|
505
507
|
}
|
|
@@ -51,7 +51,7 @@ import createSelector from 'Utils/Function/createSelector';
|
|
|
51
51
|
import { getConf } from 'App/configuration';
|
|
52
52
|
import { EventTypes } from 'App/Constant';
|
|
53
53
|
import { expandVectorizeColorsMap, getClosestColorFromMap } from '../Utils/ImageEditUtils';
|
|
54
|
-
import { getRasterURL } from '../Utils/Transformers';
|
|
54
|
+
import { getRasterURL, isOriginalVector } from '../Utils/Transformers';
|
|
55
55
|
|
|
56
56
|
const getOperationsFromState = state => {
|
|
57
57
|
const { clipping, clippingColor, vectorize, vectorizeThreshold, vectorizeColorsMap } = state;
|
|
@@ -197,12 +197,10 @@ export class ImageEditDialogContainer extends React.Component {
|
|
|
197
197
|
image.preview &&
|
|
198
198
|
image.preview.url &&
|
|
199
199
|
activeTabIndex === 2 &&
|
|
200
|
-
originalImagePreview === null
|
|
200
|
+
originalImagePreview === null &&
|
|
201
|
+
!isOriginalVector(image)
|
|
201
202
|
) {
|
|
202
|
-
|
|
203
|
-
this.setState({
|
|
204
|
-
originalImagePreview: image.gallery ? previewUrl : previewUrl.replace(/.svg$/, '.png'),
|
|
205
|
-
});
|
|
203
|
+
this.updateOriginalPreview();
|
|
206
204
|
}
|
|
207
205
|
|
|
208
206
|
if (operationsChanged) {
|
|
@@ -285,6 +283,24 @@ export class ImageEditDialogContainer extends React.Component {
|
|
|
285
283
|
}
|
|
286
284
|
}
|
|
287
285
|
|
|
286
|
+
updateOriginalPreview = async () => {
|
|
287
|
+
const { image } = this.props;
|
|
288
|
+
const previewUrl = `${getConf('network.host')}${image.preview.url}`;
|
|
289
|
+
const isSvg = previewUrl && /\.svg$/.test(previewUrl);
|
|
290
|
+
if (isSvg) {
|
|
291
|
+
const svgContent = await getSvgContent(previewUrl, true);
|
|
292
|
+
const preview = applySvgContentOperations(image.preview, null, svgContent);
|
|
293
|
+
|
|
294
|
+
this.setState({
|
|
295
|
+
originalImagePreview: preview,
|
|
296
|
+
});
|
|
297
|
+
} else {
|
|
298
|
+
this.setState({
|
|
299
|
+
originalImagePreview: previewUrl,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
|
|
288
304
|
setUpload = upload => {
|
|
289
305
|
this.setState({ upload });
|
|
290
306
|
};
|
|
@@ -471,25 +487,33 @@ export class ImageEditDialogContainer extends React.Component {
|
|
|
471
487
|
let preview = null;
|
|
472
488
|
let originalImagePreview = null;
|
|
473
489
|
|
|
490
|
+
let previewUrl = image?.preview?.url;
|
|
491
|
+
if (previewUrl && activeTabIndex === 1) {
|
|
492
|
+
previewUrl = getRasterURL(previewUrl);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
const isSvg = previewUrl && /\.svg$/.test(previewUrl);
|
|
496
|
+
|
|
474
497
|
if (image) {
|
|
475
|
-
const updateSVG =
|
|
476
|
-
activeTabIndex !== 1 &&
|
|
477
|
-
(image.displayColorPreview || image.gallery) &&
|
|
478
|
-
isEditableVectorImage(image.preview);
|
|
498
|
+
const updateSVG = isSvg;
|
|
479
499
|
|
|
480
500
|
if (updateSVG) {
|
|
481
501
|
if (!svgContent) {
|
|
482
502
|
svgContent = await getSvgContent(image.preview.url, false, forceFetch);
|
|
483
503
|
}
|
|
484
504
|
|
|
485
|
-
preview = applySvgContentOperations(
|
|
505
|
+
preview = applySvgContentOperations(
|
|
506
|
+
image.preview,
|
|
507
|
+
image.displayColorPreview ? image.operations : null,
|
|
508
|
+
svgContent
|
|
509
|
+
);
|
|
486
510
|
} else {
|
|
487
511
|
const forceUpdate = isImageInvalidatedByChange(this.lastImageUpdateData, image);
|
|
488
512
|
if (forceUpdate) {
|
|
489
513
|
this.previewVersion = Math.random();
|
|
490
514
|
}
|
|
491
515
|
preview =
|
|
492
|
-
|
|
516
|
+
getPreviewUrlFromImageData(previewUrl) +
|
|
493
517
|
(this.previewVersion ? `?${this.previewVersion}` : '');
|
|
494
518
|
originalImagePreview = preview;
|
|
495
519
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export const getMatchAt = (str, regexp, idx = 1, defaultValue = '') => {
|
|
2
|
+
const matches = ('' + str).match(regexp);
|
|
3
|
+
return (matches && matches[idx]) || defaultValue;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export const embeddedSvgImageToInlineSvgContent = svgStr =>
|
|
7
|
+
svgStr.replace(/<image([^>]+)xlink:href="data:image\/svg\+xml;base64,([^"]+)"[^>]*>/g, function(
|
|
8
|
+
_,
|
|
9
|
+
attributesStr,
|
|
10
|
+
base64Str
|
|
11
|
+
) {
|
|
12
|
+
const x = getMatchAt(attributesStr, /x="([^"]+)"/, 1, 0);
|
|
13
|
+
const y = getMatchAt(attributesStr, /y="([^"]+)"/, 1, 0);
|
|
14
|
+
const transform = getMatchAt(attributesStr, /transform="([^"]+)"/, 1, '');
|
|
15
|
+
const svgContent = atob(base64Str).replace(/(<\?xml[^>]+>)|(<!--[^>]+-->)/gi, '');
|
|
16
|
+
return `<g transform="${transform} translate(${x},${y})">${svgContent}</g>`;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export const alterObjectValues = (obj, fn) => {
|
|
20
|
+
Object.keys(obj).forEach(key => {
|
|
21
|
+
obj[key] = fn(obj[key], key);
|
|
22
|
+
});
|
|
23
|
+
return obj;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const alterArrayValues = (arr, fn) => {
|
|
27
|
+
arr.forEach((value, key) => {
|
|
28
|
+
arr[key] = fn(value, key);
|
|
29
|
+
});
|
|
30
|
+
return arr;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const prepareDesignDataSnapshots = svgArrMap =>
|
|
34
|
+
alterObjectValues(svgArrMap, arr => alterArrayValues(arr, embeddedSvgImageToInlineSvgContent));
|
|
35
|
+
|
|
36
|
+
export const preparePrintDesignData = svgMap => alterObjectValues(svgMap, embeddedSvgImageToInlineSvgContent);
|
|
@@ -19,6 +19,8 @@ export const fixSrcURL = src => {
|
|
|
19
19
|
|
|
20
20
|
export const getRasterURL = imageURL => ('' + imageURL).replace(/svg$/, 'png');
|
|
21
21
|
|
|
22
|
+
export const isOriginalVector = imageData => /svg|pdf|eps|ai/i.test(get(imageData, 'original.format', ''));
|
|
23
|
+
|
|
22
24
|
export const noCache = src => `${src}?${Math.random()}`;
|
|
23
25
|
|
|
24
26
|
export const prepareImageObjectData = rawObject => {
|
|
@@ -29,21 +31,22 @@ export const prepareImageObjectData = rawObject => {
|
|
|
29
31
|
src: fixSrcURL(rawObject.src),
|
|
30
32
|
};
|
|
31
33
|
|
|
32
|
-
data.transformImageSrc = async (url, {
|
|
34
|
+
data.transformImageSrc = async (url, { operations } = {}) => {
|
|
33
35
|
if (!isEditableVectorImage({ url })) {
|
|
34
36
|
return noCache(url);
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
const { displayColorPreview, gallery, isPlaceHolderImage } = image;
|
|
40
|
+
const originalVector = isOriginalVector(image);
|
|
38
41
|
|
|
39
|
-
if (!displayColorPreview && !gallery && !isPlaceHolderImage) {
|
|
42
|
+
if (!originalVector && !displayColorPreview && !gallery && !isPlaceHolderImage) {
|
|
40
43
|
return noCache(fixSrcURL(getRasterURL(get(image, 'preview.url', ''))));
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
const svgContent = await getSvgContent(url, true);
|
|
44
47
|
|
|
45
48
|
return applySvgContentOperations(
|
|
46
|
-
|
|
49
|
+
image.preview,
|
|
47
50
|
displayColorPreview || gallery ? (operations ? operations : image.operations) : null,
|
|
48
51
|
svgContent
|
|
49
52
|
);
|
|
@@ -94,7 +94,7 @@ describe('App/Modules/Designer/Utils/Transformers', () => {
|
|
|
94
94
|
expect(transformedSrc).toBe('base64encodedSVG');
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
-
it('transformImageSrc uses the
|
|
97
|
+
it('transformImageSrc uses the SVG image if color preview is disabled but the original format is SVG', async () => {
|
|
98
98
|
DesignDataHelpers.getSvgContent.mockResolvedValue('<svg></svg>');
|
|
99
99
|
DesignDataHelpers.applySvgContentOperations.mockReturnValue('base64encodedSVG');
|
|
100
100
|
const currentSrc = 'path/to/image.svg';
|
|
@@ -113,7 +113,7 @@ describe('App/Modules/Designer/Utils/Transformers', () => {
|
|
|
113
113
|
};
|
|
114
114
|
const preparedImageData = prepareImageObjectData(imageObjectData);
|
|
115
115
|
const transformedSrc = await preparedImageData.transformImageSrc(currentSrc);
|
|
116
|
-
expect(transformedSrc.
|
|
116
|
+
expect(transformedSrc).toBe('base64encodedSVG');
|
|
117
117
|
});
|
|
118
118
|
|
|
119
119
|
it('transformImageSrc applies the operations (vectorizeColorsMap) on gallery images', async () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import find from 'lodash/find';
|
|
3
|
+
import isString from 'lodash/isString';
|
|
3
4
|
import flatten from 'lodash/flatten';
|
|
4
5
|
import { getConf } from '../../configuration';
|
|
5
6
|
import { getConfiguration, getConfigurator } from '../Configurator/Selectors';
|
|
@@ -15,11 +16,12 @@ import {
|
|
|
15
16
|
import isEqual from 'lodash/isEqual';
|
|
16
17
|
|
|
17
18
|
export const getPreviewUrlFromImageData = (preview, options = {}) => {
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
const previewUrl = isString(preview) ? preview : preview.url;
|
|
20
|
+
if (/^data:image/.test(previewUrl)) {
|
|
21
|
+
return previewUrl;
|
|
20
22
|
}
|
|
21
23
|
const { host = getConf('network.host', '') } = options;
|
|
22
|
-
return `${host}${
|
|
24
|
+
return `${host}${previewUrl}`;
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
export const isEditableVectorImage = preview => {
|
|
@@ -356,34 +356,21 @@ export default class AnalyticsService {
|
|
|
356
356
|
|
|
357
357
|
EventTypes = EventTypes;
|
|
358
358
|
|
|
359
|
-
|
|
360
|
-
|
|
359
|
+
setDataLayer(dataLayer) {
|
|
360
|
+
this.dataLayer = dataLayer;
|
|
361
361
|
const loadIdentifier = Services.configurator.state.loadIdentifier;
|
|
362
362
|
loadIdentifier && this.triggerEvent(EventTypes.load_item, Services.configurator.state.loadIdentifier);
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
-
createMiddleware(dataLayer) {
|
|
366
|
-
return store => next => action => {
|
|
367
|
-
const result = next(action);
|
|
368
|
-
|
|
369
|
-
const actionsToTrack = this.getActionsToTrack();
|
|
370
|
-
if (!actionsToTrack[action.type]) {
|
|
371
|
-
return result;
|
|
372
|
-
}
|
|
373
|
-
const nextState = store.getState();
|
|
374
|
-
if (action.type) {
|
|
375
|
-
const data = actionsToTrack[action.type](action, nextState);
|
|
376
|
-
dataLayer.push(data);
|
|
377
|
-
}
|
|
378
|
-
return result;
|
|
379
|
-
};
|
|
380
|
-
}
|
|
381
|
-
|
|
382
365
|
getActionsToTrack() {
|
|
383
366
|
return actionsToTrack;
|
|
384
367
|
}
|
|
385
368
|
|
|
386
369
|
triggerEvent(type, data = {}) {
|
|
387
|
-
|
|
370
|
+
const actionsToTrack = this.getActionsToTrack();
|
|
371
|
+
if (type && actionsToTrack[type]) {
|
|
372
|
+
const gaData = actionsToTrack[type]({ type, data }, Services.store.state);
|
|
373
|
+
this.dataLayer && this.dataLayer.push(gaData);
|
|
374
|
+
}
|
|
388
375
|
}
|
|
389
376
|
}
|
|
@@ -44,6 +44,7 @@ import createMessageInterface, {
|
|
|
44
44
|
METHOD_ADD_TO_CART,
|
|
45
45
|
METHOD_CONFIGURATION_SAVED_REMOTELY,
|
|
46
46
|
} from '../Utils/createMessageInterface';
|
|
47
|
+
import { prepareDesignDataSnapshots, preparePrintDesignData } from '../Modules/Designer/Utils/SvgFixers';
|
|
47
48
|
|
|
48
49
|
const getSelectedAmountsBySizes = (item, selectedAmounts) => {
|
|
49
50
|
const itemGroupMap = (rootItem, fn) => {
|
|
@@ -363,10 +364,10 @@ export default class ConfiguratorService extends AbstractConfiguratorService {
|
|
|
363
364
|
const fontMapping = getFontMapping(Services.store.state);
|
|
364
365
|
|
|
365
366
|
const svgs = await Services.designData.getScreenshotsOfElements(fontMapping);
|
|
366
|
-
mediaData.designDataSnapshots = svgs;
|
|
367
|
+
mediaData.designDataSnapshots = prepareDesignDataSnapshots(svgs);
|
|
367
368
|
|
|
368
369
|
const fullSvgs = await Services.designData.getScreenshots(fontMapping);
|
|
369
|
-
mediaData.printDesignData = fullSvgs;
|
|
370
|
+
mediaData.printDesignData = preparePrintDesignData(fullSvgs);
|
|
370
371
|
const usedAreas = Object.keys(fullSvgs);
|
|
371
372
|
|
|
372
373
|
const { designArea } = Services.store.state;
|
|
@@ -373,16 +373,18 @@ export const makeOperationsCompatible = (operations, compatibilityInfo, colorPal
|
|
|
373
373
|
|
|
374
374
|
export const getSvgContent = (() => {
|
|
375
375
|
const svgContentMap = new Map();
|
|
376
|
-
return
|
|
376
|
+
return function getSvgContent(url, absolute = false, forceFetch = false) {
|
|
377
377
|
const absUrl = absolute ? url : `${getConf('network.host')}${url}`;
|
|
378
378
|
if (!forceFetch && svgContentMap.has(absUrl)) {
|
|
379
379
|
return svgContentMap.get(absUrl);
|
|
380
380
|
}
|
|
381
381
|
try {
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
382
|
+
const promise = (async function() {
|
|
383
|
+
const result = await axios.get(absUrl);
|
|
384
|
+
return initDefaultColor(result.data);
|
|
385
|
+
})();
|
|
386
|
+
svgContentMap.set(absUrl, promise);
|
|
387
|
+
return promise;
|
|
386
388
|
} catch (e) {
|
|
387
389
|
return '';
|
|
388
390
|
}
|
|
@@ -1042,12 +1044,18 @@ export default class DesignDataService {
|
|
|
1042
1044
|
);
|
|
1043
1045
|
|
|
1044
1046
|
const designArea = getSelectedDesignArea(state);
|
|
1045
|
-
const
|
|
1047
|
+
const nonVectorizedImages = getImagesByDesignArea(state, designArea.identifier).filter(
|
|
1048
|
+
obj => !get(obj, 'imageData.operations.vectorize')
|
|
1049
|
+
);
|
|
1046
1050
|
|
|
1047
1051
|
if (
|
|
1048
|
-
|
|
1052
|
+
nonVectorizedImages.length === 1 &&
|
|
1049
1053
|
((!currentVectorsRequired && newVectorsRequired) ||
|
|
1050
|
-
!isColorPreviewCompatible(
|
|
1054
|
+
!isColorPreviewCompatible(
|
|
1055
|
+
state,
|
|
1056
|
+
nonVectorizedImages[0].imageData,
|
|
1057
|
+
designProductionMethodIdentifier
|
|
1058
|
+
))
|
|
1051
1059
|
) {
|
|
1052
1060
|
await Services.store.dispatch(showSwitchToProductionMethodWithVectorization());
|
|
1053
1061
|
return true;
|
|
@@ -1083,7 +1091,7 @@ export default class DesignDataService {
|
|
|
1083
1091
|
}
|
|
1084
1092
|
|
|
1085
1093
|
return (
|
|
1086
|
-
!
|
|
1094
|
+
!get(obj, 'imageData.operations.vectorize') ||
|
|
1087
1095
|
!isColorPreviewCompatible(state, obj.imageData, designProductionMethodIdentifier)
|
|
1088
1096
|
);
|
|
1089
1097
|
})
|
|
@@ -1183,12 +1191,14 @@ export default class DesignDataService {
|
|
|
1183
1191
|
const state = Services.store.state;
|
|
1184
1192
|
const designArea = getSelectedDesignArea(state);
|
|
1185
1193
|
const canvas = this._getCanvas(designArea);
|
|
1186
|
-
const
|
|
1194
|
+
const firstNonVectorizedImage = getImagesByDesignArea(state, designArea.identifier).find(
|
|
1195
|
+
obj => !get(obj, 'imageData.operations.vectorize')
|
|
1196
|
+
);
|
|
1187
1197
|
const operations = {
|
|
1188
|
-
...
|
|
1198
|
+
...firstNonVectorizedImage.imageData.operations,
|
|
1189
1199
|
vectorize: true,
|
|
1190
1200
|
};
|
|
1191
|
-
const imageData =
|
|
1201
|
+
const imageData = firstNonVectorizedImage.imageData;
|
|
1192
1202
|
|
|
1193
1203
|
try {
|
|
1194
1204
|
//returing if placeHolderImage, from executing edit operations
|
|
@@ -1202,10 +1212,14 @@ export default class DesignDataService {
|
|
|
1202
1212
|
.find(obj => obj._imageData.identifier === imageData.identifier);
|
|
1203
1213
|
imageToSelect.selected = true;
|
|
1204
1214
|
|
|
1205
|
-
await Services.designer.openImageEditDialog(
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1215
|
+
await Services.designer.openImageEditDialog(
|
|
1216
|
+
firstNonVectorizedImage.imageData.identifier,
|
|
1217
|
+
canvas,
|
|
1218
|
+
{
|
|
1219
|
+
placeholderImageUpdate: false,
|
|
1220
|
+
submitOnExitClick: true,
|
|
1221
|
+
}
|
|
1222
|
+
);
|
|
1209
1223
|
} finally {
|
|
1210
1224
|
Services.ui.hide('globalLoader');
|
|
1211
1225
|
}
|
|
@@ -1875,8 +1889,8 @@ export default class DesignDataService {
|
|
|
1875
1889
|
|
|
1876
1890
|
const isBackendNeeded = createCopy || !isEqual(editData, currentEditData);
|
|
1877
1891
|
|
|
1878
|
-
isBackendNeeded
|
|
1879
|
-
|
|
1892
|
+
if (isBackendNeeded) {
|
|
1893
|
+
await Services.store.dispatch(
|
|
1880
1894
|
editImage(
|
|
1881
1895
|
{
|
|
1882
1896
|
...editData,
|
|
@@ -1890,12 +1904,13 @@ export default class DesignDataService {
|
|
|
1890
1904
|
},
|
|
1891
1905
|
{ immediateCommit }
|
|
1892
1906
|
)
|
|
1893
|
-
)
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1907
|
+
);
|
|
1908
|
+
const {
|
|
1909
|
+
imageGallery: { selectedImage },
|
|
1910
|
+
} = Services.store.state;
|
|
1911
|
+
preview = get(selectedImage, 'preview');
|
|
1912
|
+
imageIdentifier = get(selectedImage, 'identifier');
|
|
1913
|
+
}
|
|
1899
1914
|
}
|
|
1900
1915
|
}
|
|
1901
1916
|
|