kitchen-simulator 11.0.0-react-18 → 11.0.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/es/LiteKitchenConfigurator.js +42 -11
- package/es/LiteRenderer.js +2 -24
- package/es/actions/export.js +25 -12
- package/es/analytics/ga4.js +188 -0
- package/es/catalog/utils/item-loader.js +4 -4
- package/es/class/item.js +29 -7
- package/es/class/line.js +1 -3
- package/es/components/content.js +20 -5
- package/es/components/export.js +6 -4
- package/es/components/style/form-number-input.js +7 -5
- package/es/components/style/form-submit-button.js +25 -0
- package/es/components/viewer2d/group.js +6 -5
- package/es/components/viewer2d/item.js +9 -9
- package/es/components/viewer2d/line.js +18 -47
- package/es/components/viewer2d/rulerX.js +9 -8
- package/es/components/viewer2d/rulerY.js +9 -8
- package/es/components/viewer2d/scene.js +9 -9
- package/es/components/viewer2d/state.js +1 -1
- package/es/components/viewer2d/utils.js +0 -6
- package/es/components/viewer2d/viewer2d.js +35 -31
- package/es/components/viewer3d/ruler-utils/layer3D.js +2 -2
- package/es/components/viewer3d/scene-creator.js +40 -75
- package/es/components/viewer3d/viewer3d-first-person.js +13 -8
- package/es/components/viewer3d/viewer3d.js +19 -15
- package/es/devLiteRenderer.js +913 -0
- package/es/events/external/handleExternalEvent.js +1 -0
- package/es/events/external/handleExternalEvent.util.js +330 -347
- package/es/events/external/handlers.changeDoorStyle.js +5 -3
- package/es/events/external/handlers.loadProject.js +5 -3
- package/es/events/external/handlers.syncScene.js +1 -1
- package/es/mappings/external-events/mappers/ccdfMapper.js +14 -8
- package/es/shared/domain/cabinet-warning.js +15 -0
- package/es/utils/geometry.js +4 -7
- package/es/utils/helper.js +81 -22
- package/es/utils/skinPanelEngine.js +5 -9
- package/lib/LiteKitchenConfigurator.js +42 -11
- package/lib/LiteRenderer.js +3 -25
- package/lib/actions/export.js +35 -39
- package/lib/analytics/ga4.js +194 -0
- package/lib/catalog/utils/item-loader.js +3 -3
- package/lib/class/item.js +29 -7
- package/lib/class/line.js +1 -3
- package/lib/components/content.js +19 -4
- package/lib/components/export.js +6 -16
- package/lib/components/style/form-number-input.js +7 -5
- package/lib/components/style/form-submit-button.js +35 -0
- package/lib/components/viewer2d/group.js +6 -5
- package/lib/components/viewer2d/item.js +8 -8
- package/lib/components/viewer2d/line.js +18 -47
- package/lib/components/viewer2d/rulerX.js +9 -8
- package/lib/components/viewer2d/rulerY.js +9 -8
- package/lib/components/viewer2d/scene.js +9 -9
- package/lib/components/viewer2d/state.js +1 -1
- package/lib/components/viewer2d/utils.js +0 -7
- package/lib/components/viewer2d/viewer2d.js +33 -29
- package/lib/components/viewer3d/ruler-utils/layer3D.js +2 -2
- package/lib/components/viewer3d/scene-creator.js +39 -75
- package/lib/components/viewer3d/viewer3d-first-person.js +13 -8
- package/lib/components/viewer3d/viewer3d.js +19 -15
- package/lib/devLiteRenderer.js +917 -0
- package/lib/events/external/handleExternalEvent.js +1 -0
- package/lib/events/external/handleExternalEvent.util.js +330 -347
- package/lib/events/external/handlers.changeDoorStyle.js +5 -3
- package/lib/events/external/handlers.loadProject.js +5 -3
- package/lib/events/external/handlers.syncScene.js +1 -1
- package/lib/mappings/external-events/mappers/ccdfMapper.js +14 -8
- package/lib/shared/domain/cabinet-warning.js +20 -0
- package/lib/utils/geometry.js +4 -7
- package/lib/utils/helper.js +82 -24
- package/lib/utils/skinPanelEngine.js +4 -8
- package/package.json +21 -6
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
-
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
3
2
|
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
|
3
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
4
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
4
5
|
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
5
6
|
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
6
7
|
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
|
|
@@ -313,20 +314,41 @@ var LiteKitchenConfigurator = /*#__PURE__*/function (_Component) {
|
|
|
313
314
|
var el = document.getElementById('add_appliances_inactive');
|
|
314
315
|
if (el !== null && el !== void 0 && (_el$parentElement0 = el.parentElement) !== null && _el$parentElement0 !== void 0 && _el$parentElement0.parentElement) el.parentElement.parentElement.style.zIndex = 6;
|
|
315
316
|
}
|
|
317
|
+
}, {
|
|
318
|
+
key: "getChildContext",
|
|
319
|
+
value: function getChildContext() {
|
|
320
|
+
var _this2 = this;
|
|
321
|
+
return _objectSpread(_objectSpread({}, objectsMap(actions, function (actionNamespace) {
|
|
322
|
+
return _this2.props[actionNamespace];
|
|
323
|
+
})), {}, {
|
|
324
|
+
translator: this.props.translator,
|
|
325
|
+
catalog: this.props.catalog
|
|
326
|
+
});
|
|
327
|
+
}
|
|
316
328
|
}, {
|
|
317
329
|
key: "componentDidMount",
|
|
318
330
|
value: function componentDidMount() {
|
|
319
331
|
window.forRedo = [];
|
|
332
|
+
var store = this.context.store;
|
|
333
|
+
var _this$props = this.props,
|
|
334
|
+
stateExtractor = _this$props.stateExtractor,
|
|
335
|
+
plugins = _this$props.plugins;
|
|
336
|
+
|
|
337
|
+
// keep old behavior: run plugins once on mount
|
|
338
|
+
var newplugins = _toConsumableArray(plugins);
|
|
339
|
+
newplugins.forEach(function (newplugin) {
|
|
340
|
+
return newplugin(store, stateExtractor);
|
|
341
|
+
});
|
|
320
342
|
}
|
|
321
343
|
}, {
|
|
322
344
|
key: "componentDidUpdate",
|
|
323
345
|
value: function componentDidUpdate(prevProps) {
|
|
324
346
|
var _extractedState$getIn;
|
|
325
|
-
var _this$
|
|
326
|
-
externalEvent = _this$
|
|
327
|
-
extractedState = _this$
|
|
328
|
-
projectActions = _this$
|
|
329
|
-
catalog = _this$
|
|
347
|
+
var _this$props2 = this.props,
|
|
348
|
+
externalEvent = _this$props2.externalEvent,
|
|
349
|
+
extractedState = _this$props2.extractedState,
|
|
350
|
+
projectActions = _this$props2.projectActions,
|
|
351
|
+
catalog = _this$props2.catalog;
|
|
330
352
|
|
|
331
353
|
// same behavior: handle external event when it changes
|
|
332
354
|
if (prevProps.externalEvent !== externalEvent) {
|
|
@@ -385,11 +407,11 @@ var LiteKitchenConfigurator = /*#__PURE__*/function (_Component) {
|
|
|
385
407
|
}, {
|
|
386
408
|
key: "render",
|
|
387
409
|
value: function render() {
|
|
388
|
-
var _this$
|
|
389
|
-
width = _this$
|
|
390
|
-
height = _this$
|
|
391
|
-
extractedState = _this$
|
|
392
|
-
props = _objectWithoutProperties(_this$
|
|
410
|
+
var _this$props3 = this.props,
|
|
411
|
+
width = _this$props3.width,
|
|
412
|
+
height = _this$props3.height,
|
|
413
|
+
extractedState = _this$props3.extractedState,
|
|
414
|
+
props = _objectWithoutProperties(_this$props3, _excluded);
|
|
393
415
|
var _this$state = this.state,
|
|
394
416
|
savePopupVisible = _this$state.savePopupVisible,
|
|
395
417
|
quotePopupVisible = _this$state.quotePopupVisible,
|
|
@@ -455,6 +477,15 @@ LiteKitchenConfigurator.propTypes = {
|
|
|
455
477
|
// ✅ injected by connect
|
|
456
478
|
externalEvent: PropTypes.object
|
|
457
479
|
};
|
|
480
|
+
LiteKitchenConfigurator.contextTypes = {
|
|
481
|
+
store: PropTypes.object.isRequired
|
|
482
|
+
};
|
|
483
|
+
LiteKitchenConfigurator.childContextTypes = _objectSpread(_objectSpread({}, objectsMap(actions, function () {
|
|
484
|
+
return PropTypes.object;
|
|
485
|
+
})), {}, {
|
|
486
|
+
translator: PropTypes.object,
|
|
487
|
+
catalog: PropTypes.object
|
|
488
|
+
});
|
|
458
489
|
LiteKitchenConfigurator.defaultProps = {
|
|
459
490
|
translator: new Translator(),
|
|
460
491
|
catalog: new Catalog(),
|
package/es/LiteRenderer.js
CHANGED
|
@@ -11,7 +11,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
11
11
|
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
12
12
|
import PropTypes from 'prop-types';
|
|
13
13
|
import { Provider } from 'react-redux';
|
|
14
|
-
import { createStore
|
|
14
|
+
import { createStore } from 'redux';
|
|
15
15
|
import { Map } from 'immutable';
|
|
16
16
|
import * as Sentry from '@sentry/react';
|
|
17
17
|
import * as THREE from 'three';
|
|
@@ -20,14 +20,11 @@ import { State } from "./models";
|
|
|
20
20
|
import PlannerReducer from "./reducers/reducer";
|
|
21
21
|
import AppContext from "./AppContext";
|
|
22
22
|
import Catalog from "./catalog/catalog";
|
|
23
|
-
import actions from "./actions/export";
|
|
24
|
-
import Translator from "./translator/translator";
|
|
25
23
|
import * as Areas from "./catalog/areas/area/planner-element";
|
|
26
24
|
import * as Lines from "./catalog/lines/wall/planner-element";
|
|
27
25
|
import { buildHoleElements, registerDynamicHoles } from "./mappings/holesToCatalog";
|
|
28
26
|
import { ConsoleDebugger, Keyboard } from "./plugins/export";
|
|
29
27
|
import LiteKitchenConfigurator from "./LiteKitchenConfigurator";
|
|
30
|
-
import { objectsMap } from "./utils/objects-utils";
|
|
31
28
|
var isBrowser = typeof window !== 'undefined';
|
|
32
29
|
if (isBrowser) window.THREE = THREE;
|
|
33
30
|
|
|
@@ -277,26 +274,7 @@ export default function LiteRenderer(props) {
|
|
|
277
274
|
var _ref = configData || {},
|
|
278
275
|
logoImg = _ref.logoImg,
|
|
279
276
|
companyUrl = _ref.companyUrl;
|
|
280
|
-
|
|
281
|
-
// Build the context value with bound action creators + translator + catalog
|
|
282
|
-
var translatorRef = useRef(null);
|
|
283
|
-
if (!translatorRef.current) translatorRef.current = new Translator();
|
|
284
|
-
var contextValue = useMemo(function () {
|
|
285
|
-
var store = storeRef.current;
|
|
286
|
-
var boundActions = objectsMap(actions, function (actionNamespace) {
|
|
287
|
-
return bindActionCreators(actions[actionNamespace], store.dispatch);
|
|
288
|
-
});
|
|
289
|
-
return _objectSpread(_objectSpread({}, boundActions), {}, {
|
|
290
|
-
translator: translatorRef.current,
|
|
291
|
-
catalog: catalogRef.current
|
|
292
|
-
});
|
|
293
|
-
}, []);
|
|
294
|
-
|
|
295
|
-
// Update catalog in context when it changes
|
|
296
|
-
contextValue.catalog = catalogRef.current;
|
|
297
|
-
return /*#__PURE__*/React.createElement(AppContext.Provider, {
|
|
298
|
-
value: contextValue
|
|
299
|
-
}, /*#__PURE__*/React.createElement(Provider, {
|
|
277
|
+
return /*#__PURE__*/React.createElement(AppContext.Provider, null, /*#__PURE__*/React.createElement(Provider, {
|
|
300
278
|
store: storeRef.current
|
|
301
279
|
}, /*#__PURE__*/React.createElement(LiteKitchenConfigurator, _extends({
|
|
302
280
|
catalog: catalogRef.current,
|
package/es/actions/export.js
CHANGED
|
@@ -8,16 +8,29 @@ import * as verticesActions from "./vertices-actions";
|
|
|
8
8
|
import * as itemsActions from "./items-actions";
|
|
9
9
|
import * as areaActions from "./area-actions";
|
|
10
10
|
import * as groupsActions from "./groups-actions";
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
projectActions,
|
|
14
|
+
viewer2DActions,
|
|
15
|
+
viewer3DActions,
|
|
16
|
+
linesActions,
|
|
17
|
+
holesActions,
|
|
18
|
+
sceneActions,
|
|
19
|
+
verticesActions,
|
|
20
|
+
itemsActions,
|
|
21
|
+
areaActions,
|
|
22
|
+
groupsActions
|
|
23
|
+
};
|
|
24
|
+
|
|
12
25
|
export default {
|
|
13
|
-
projectActions
|
|
14
|
-
viewer2DActions
|
|
15
|
-
viewer3DActions
|
|
16
|
-
linesActions
|
|
17
|
-
holesActions
|
|
18
|
-
sceneActions
|
|
19
|
-
verticesActions
|
|
20
|
-
itemsActions
|
|
21
|
-
areaActions
|
|
22
|
-
groupsActions
|
|
23
|
-
};
|
|
26
|
+
projectActions,
|
|
27
|
+
viewer2DActions,
|
|
28
|
+
viewer3DActions,
|
|
29
|
+
linesActions,
|
|
30
|
+
holesActions,
|
|
31
|
+
sceneActions,
|
|
32
|
+
verticesActions,
|
|
33
|
+
itemsActions,
|
|
34
|
+
areaActions,
|
|
35
|
+
groupsActions
|
|
36
|
+
};
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
import ReactGA from 'react-ga4';
|
|
5
|
+
|
|
6
|
+
// ---------- Helpers ----------
|
|
7
|
+
function nowMs() {
|
|
8
|
+
return Date.now();
|
|
9
|
+
}
|
|
10
|
+
function getClientName() {
|
|
11
|
+
return sessionStorage.getItem('visualizerName');
|
|
12
|
+
}
|
|
13
|
+
function isDesktopUA() {
|
|
14
|
+
// Lightweight heuristic; GA4 also provides device.category. This flag can help ad-hoc filtering.
|
|
15
|
+
var ua = navigator.userAgent.toLowerCase();
|
|
16
|
+
var isMobile = /mobi|android|iphone|ipad|ipod|windows phone/.test(ua);
|
|
17
|
+
return !isMobile;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ---------- Keys for storage ----------
|
|
21
|
+
var SSN_KEYS = {
|
|
22
|
+
sessionStartMs: 'ga4_session_start_ms',
|
|
23
|
+
introChoiceMs: 'ga4_intro_choice_ms',
|
|
24
|
+
firstCabinetPlaced: 'ga4_first_cabinet_placed',
|
|
25
|
+
contextBooted: 'ga4_context_booted',
|
|
26
|
+
enteredCanvasSent: 'ga4_entered_canvas_sent'
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// ---------- Core GA wrapper ----------
|
|
30
|
+
export var GA = {
|
|
31
|
+
init: function init(_ref) {
|
|
32
|
+
var measurementId = _ref.measurementId;
|
|
33
|
+
ReactGA.initialize([{
|
|
34
|
+
trackingId: measurementId
|
|
35
|
+
}], {
|
|
36
|
+
testMode: false
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
resetSessionKeys: function resetSessionKeys() {
|
|
40
|
+
Object.values(SSN_KEYS).forEach(function (key) {
|
|
41
|
+
sessionStorage.removeItem(key);
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
/**
|
|
45
|
+
* Must be called ONCE per page load, *before* other events.
|
|
46
|
+
* Sets user properties (project_entry, cross_auth) and sends an initial page_view with client_name.
|
|
47
|
+
*/
|
|
48
|
+
bootSessionContext: function bootSessionContext(_ref2) {
|
|
49
|
+
var projectEntry = _ref2.projectEntry,
|
|
50
|
+
crossAuth = _ref2.crossAuth;
|
|
51
|
+
try {
|
|
52
|
+
var resolvedClient = getClientName();
|
|
53
|
+
|
|
54
|
+
// Persist session start for timing metrics (if not already set for this tab)
|
|
55
|
+
if (!sessionStorage.getItem(SSN_KEYS.sessionStartMs)) {
|
|
56
|
+
sessionStorage.setItem(SSN_KEYS.sessionStartMs, String(nowMs()));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Mark context as booted to avoid duplicate property sets on hot reloads
|
|
60
|
+
if (!sessionStorage.getItem(SSN_KEYS.contextBooted)) {
|
|
61
|
+
sessionStorage.setItem(SSN_KEYS.contextBooted, '1');
|
|
62
|
+
|
|
63
|
+
// Set GA4 user_properties (user-scoped dimensions)
|
|
64
|
+
ReactGA.gtag('set', 'user_properties', {
|
|
65
|
+
project_entry: projectEntry,
|
|
66
|
+
// user scope dimension
|
|
67
|
+
cross_auth: crossAuth // user scope dimension (boolean serialized)
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Send first page_view hit enriched with event-scoped client_name
|
|
72
|
+
ReactGA.send({
|
|
73
|
+
hitType: 'pageview',
|
|
74
|
+
page: window.location.pathname + window.location.search,
|
|
75
|
+
// @ts-expect-error react-ga4 passes along additional params into gtag
|
|
76
|
+
client_name: resolvedClient
|
|
77
|
+
});
|
|
78
|
+
} catch (e) {
|
|
79
|
+
// eslint-disable-next-line no-console
|
|
80
|
+
console.warn('GA.bootSessionContext error', e);
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
// Utility to derive cross_auth from URL (token or details query params)
|
|
84
|
+
deriveCrossAuthFromUrl: function deriveCrossAuthFromUrl(search) {
|
|
85
|
+
var sp = new URLSearchParams(search);
|
|
86
|
+
return sp.has('token') || sp.has('details');
|
|
87
|
+
},
|
|
88
|
+
// Utility to derive project entry (best-effort). You can also pass explicitly from router logic.
|
|
89
|
+
deriveProjectEntry: function deriveProjectEntry() {
|
|
90
|
+
var projectId = sessionStorage.getItem('projectId');
|
|
91
|
+
|
|
92
|
+
// If a project id exists, consider it "open_existing"; otherwise fallback to "new"
|
|
93
|
+
if (projectId) return 'open_existing';
|
|
94
|
+
return 'new';
|
|
95
|
+
},
|
|
96
|
+
// ---------- Event API ----------
|
|
97
|
+
events: {
|
|
98
|
+
/**
|
|
99
|
+
* intro_choice(option) — records the user's entry choice.
|
|
100
|
+
* Also stores a timestamp for later time_to_canvas calculation.
|
|
101
|
+
*/
|
|
102
|
+
introChoice: function introChoice(option, extra) {
|
|
103
|
+
var client_name = getClientName();
|
|
104
|
+
sessionStorage.setItem(SSN_KEYS.introChoiceMs, String(nowMs()));
|
|
105
|
+
ReactGA.event('intro_choice', _objectSpread({
|
|
106
|
+
client_name: client_name,
|
|
107
|
+
option: option
|
|
108
|
+
}, extra || {}));
|
|
109
|
+
},
|
|
110
|
+
/**
|
|
111
|
+
* entered_canvas(time_to_canvas) — compute (now - intro_choice)
|
|
112
|
+
*/
|
|
113
|
+
enteredCanvas: function enteredCanvas() {
|
|
114
|
+
// fire only once per tab/session
|
|
115
|
+
if (sessionStorage.getItem(SSN_KEYS.enteredCanvasSent)) return;
|
|
116
|
+
var client_name = getClientName();
|
|
117
|
+
var introMs = Number(sessionStorage.getItem(SSN_KEYS.introChoiceMs) || 0);
|
|
118
|
+
var timeSec = introMs ? Math.max(0, Math.round((Date.now() - introMs) / 1000)) : undefined;
|
|
119
|
+
ReactGA.event('entered_canvas', _objectSpread({
|
|
120
|
+
client_name: client_name
|
|
121
|
+
}, typeof timeSec === 'number' ? {
|
|
122
|
+
time_to_canvas: timeSec
|
|
123
|
+
} : {}));
|
|
124
|
+
sessionStorage.setItem(SSN_KEYS.enteredCanvasSent, '1'); // 👈 lock it
|
|
125
|
+
},
|
|
126
|
+
/**
|
|
127
|
+
* cabinet_placed(time_to_first_cabinet) — send only for the *first* cabinet of the session.
|
|
128
|
+
*/
|
|
129
|
+
cabinetPlaced: function cabinetPlaced() {
|
|
130
|
+
var already = sessionStorage.getItem(SSN_KEYS.firstCabinetPlaced);
|
|
131
|
+
var client_name = getClientName();
|
|
132
|
+
var params = {
|
|
133
|
+
client_name: client_name
|
|
134
|
+
};
|
|
135
|
+
if (!already) {
|
|
136
|
+
var startMs = Number(sessionStorage.getItem(SSN_KEYS.sessionStartMs) || 0);
|
|
137
|
+
var timeSec = startMs ? Math.max(0, Math.round((nowMs() - startMs) / 1000)) : undefined;
|
|
138
|
+
if (typeof timeSec === 'number') params.time_to_first_cabinet = timeSec; // custom metric (seconds)
|
|
139
|
+
sessionStorage.setItem(SSN_KEYS.firstCabinetPlaced, '1');
|
|
140
|
+
}
|
|
141
|
+
ReactGA.event('cabinet_placed', params);
|
|
142
|
+
},
|
|
143
|
+
/**
|
|
144
|
+
* door_changed(door_id)
|
|
145
|
+
*/
|
|
146
|
+
doorChanged: function doorChanged(door_id) {
|
|
147
|
+
var client_name = getClientName();
|
|
148
|
+
ReactGA.event('door_changed', {
|
|
149
|
+
client_name: client_name,
|
|
150
|
+
door_id: door_id
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
/**
|
|
154
|
+
* project_saved(project_id, save_method) — mark as conversion in GA UI.
|
|
155
|
+
*/
|
|
156
|
+
projectSaved: function projectSaved(project_id, save_method) {
|
|
157
|
+
var client_name = getClientName();
|
|
158
|
+
ReactGA.event('project_saved', {
|
|
159
|
+
client_name: client_name,
|
|
160
|
+
project_id: project_id,
|
|
161
|
+
save_method: save_method
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
/**
|
|
165
|
+
* assistance_requested(method, project_id) — mark as conversion in GA UI.
|
|
166
|
+
*/
|
|
167
|
+
assistanceRequested: function assistanceRequested(method, project_id) {
|
|
168
|
+
var client_name = getClientName();
|
|
169
|
+
ReactGA.event('assistance_requested', {
|
|
170
|
+
client_name: client_name,
|
|
171
|
+
method: method,
|
|
172
|
+
project_id: project_id
|
|
173
|
+
});
|
|
174
|
+
},
|
|
175
|
+
/**
|
|
176
|
+
* add_to_cart(project_id, sku_count, price_total) — mark as conversion in GA UI.
|
|
177
|
+
*/
|
|
178
|
+
addToCart: function addToCart(project_id, sku_count, price_total) {
|
|
179
|
+
var client_name = getClientName();
|
|
180
|
+
ReactGA.event('add_to_cart', {
|
|
181
|
+
client_name: client_name,
|
|
182
|
+
project_id: project_id,
|
|
183
|
+
sku_count: sku_count,
|
|
184
|
+
price_total: price_total
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
};
|
|
@@ -12,8 +12,8 @@ import { ARROW_COLOR, BASE_CABINET_LAYOUTPOS, OBJTYPE_GROUP, OBJTYPE_MESH, SHADE
|
|
|
12
12
|
import { Item } from "../../models";
|
|
13
13
|
import * as GeomUtils from "./geom-utils";
|
|
14
14
|
import { loadGLTF } from "./load-obj";
|
|
15
|
-
import { animateDoor,
|
|
16
|
-
import {
|
|
15
|
+
import { animateDoor, getCatalogCabinetSku, isEmpty, translateDrawer } from "../../utils/helper";
|
|
16
|
+
import { isWarningCabinet } from "../../shared/domain/cabinet-warning";
|
|
17
17
|
import { orderCabinetAssemblyKeys } from "../cabinet/cabinet-assembly-order";
|
|
18
18
|
var INITIAL_NORMAL_MAP = '';
|
|
19
19
|
|
|
@@ -124,7 +124,7 @@ export function render2DItem(element, layer, scene, sizeinfo, layoutpos, is_corn
|
|
|
124
124
|
var rowCount = 0; //parseInt((element.type.length / lineCount - 0.51).toFixed(), 10);
|
|
125
125
|
|
|
126
126
|
// Get SKU Alias
|
|
127
|
-
var objSKU =
|
|
127
|
+
var objSKU = getCatalogCabinetSku(element);
|
|
128
128
|
if (rowCount > 0) {
|
|
129
129
|
for (var _x = 0; _x < rowCount; _x++) {
|
|
130
130
|
splitStr.push(objSKU.slice(lineCount * _x, lineCount * (_x + 1)));
|
|
@@ -293,7 +293,7 @@ export function render2DItem(element, layer, scene, sizeinfo, layoutpos, is_corn
|
|
|
293
293
|
}), /*#__PURE__*/React.createElement("g", {
|
|
294
294
|
transform: "translate(".concat(padding_width, ",").concat(padding_depth, ")")
|
|
295
295
|
}, txtContent)), element.category === 'cabinet' && /*#__PURE__*/React.createElement("g", {
|
|
296
|
-
visibility:
|
|
296
|
+
visibility: isWarningCabinet(element) ? 'visible' : 'hidden'
|
|
297
297
|
}, warning_buttons)));
|
|
298
298
|
} else {
|
|
299
299
|
rendered = /*#__PURE__*/React.createElement("g", {
|
package/es/class/item.js
CHANGED
|
@@ -105,9 +105,16 @@ var Item = /*#__PURE__*/function () {
|
|
|
105
105
|
}
|
|
106
106
|
if (item.category === 'cabinet') {
|
|
107
107
|
if (isDuplication && refItem) {
|
|
108
|
+
var _refItem$ccdf, _refItem$get;
|
|
108
109
|
item = item.merge({
|
|
109
110
|
doorStyle: refItem.doorStyle
|
|
110
111
|
});
|
|
112
|
+
// When duplicating, preserve the instance-selected CCDF from the source cabinet.
|
|
113
|
+
var refCcdf = (_refItem$ccdf = refItem === null || refItem === void 0 ? void 0 : refItem.ccdf) !== null && _refItem$ccdf !== void 0 ? _refItem$ccdf : refItem === null || refItem === void 0 || (_refItem$get = refItem.get) === null || _refItem$get === void 0 ? void 0 : _refItem$get.call(refItem, 'ccdf');
|
|
114
|
+
refCcdf = toJSIfNeeded(refCcdf);
|
|
115
|
+
if (!isEmpty(refCcdf)) item = item.merge({
|
|
116
|
+
ccdf: refCcdf
|
|
117
|
+
});
|
|
111
118
|
} else {
|
|
112
119
|
var _layer$doorStyle, _temp, _ref, _temp$doorStyles$cds$, _temp2, _temp3, _state5;
|
|
113
120
|
var layer = state.getIn(['scene', 'layers', layerID]);
|
|
@@ -254,8 +261,7 @@ var Item = /*#__PURE__*/function () {
|
|
|
254
261
|
var doorFinishId = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
255
262
|
var layerID = state.getIn(['scene', 'selectedLayer']);
|
|
256
263
|
var layer = state.getIn(['scene', 'layers', layerID]);
|
|
257
|
-
|
|
258
|
-
if (!Array.isArray(ccdf_list) || !desiredDoorFinishId) return {
|
|
264
|
+
if (!Array.isArray(ccdf_list)) return {
|
|
259
265
|
updatedState: state
|
|
260
266
|
};
|
|
261
267
|
|
|
@@ -267,9 +273,27 @@ var Item = /*#__PURE__*/function () {
|
|
|
267
273
|
} else if (applyScope === DOORSTYLE_SCOPE_MULTIPLE) {
|
|
268
274
|
idSet = new Set(targetItemIDs);
|
|
269
275
|
}
|
|
276
|
+
|
|
277
|
+
// If host returns an empty ccdf_list, remove assets3d of persisted ccdf from affected instances.
|
|
278
|
+
// This keeps SYNC payload from sending stale `items[].ccdf`.
|
|
279
|
+
if (ccdf_list.length === 0) {
|
|
280
|
+
layer.items.forEach(function (it) {
|
|
281
|
+
var _idSet;
|
|
282
|
+
var should = applyScope === DOORSTYLE_SCOPE_ALL ? true : (_idSet = idSet) === null || _idSet === void 0 ? void 0 : _idSet.has(it.id);
|
|
283
|
+
if (!should) return;
|
|
284
|
+
state = state.deleteIn(['scene', 'layers', layerID, 'items', it.id, 'ccdf', 'assets3d']);
|
|
285
|
+
});
|
|
286
|
+
return {
|
|
287
|
+
updatedState: state
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
var desiredDoorFinishId = doorFinishId !== null && doorFinishId !== void 0 ? doorFinishId : this.__getDesiredDoorFinishId(layer);
|
|
291
|
+
if (!desiredDoorFinishId) return {
|
|
292
|
+
updatedState: state
|
|
293
|
+
};
|
|
270
294
|
layer.items.forEach(function (it) {
|
|
271
|
-
var
|
|
272
|
-
var should = applyScope === DOORSTYLE_SCOPE_ALL ? true : (
|
|
295
|
+
var _idSet2, _picked$door_finish_i;
|
|
296
|
+
var should = applyScope === DOORSTYLE_SCOPE_ALL ? true : (_idSet2 = idSet) === null || _idSet2 === void 0 ? void 0 : _idSet2.has(it.id);
|
|
273
297
|
if (!should) return;
|
|
274
298
|
|
|
275
299
|
// Join key: scene_cabinet_id (instance id).
|
|
@@ -567,9 +591,7 @@ var Item = /*#__PURE__*/function () {
|
|
|
567
591
|
break;
|
|
568
592
|
}
|
|
569
593
|
if (onInternalEvent && duplicatedElement) {
|
|
570
|
-
var
|
|
571
|
-
var catalog = (_state$get = state.get('catalog')) === null || _state$get === void 0 ? void 0 : _state$get.toJS();
|
|
572
|
-
var jsElement = updatePayloadOfInternalEvent(duplicatedElement, layer, catalog);
|
|
594
|
+
var jsElement = updatePayloadOfInternalEvent(duplicatedElement, layer);
|
|
573
595
|
onInternalEvent({
|
|
574
596
|
type: INTERNAL_EVENT_DRAW_ELEMENT,
|
|
575
597
|
value: jsElement
|
package/es/class/line.js
CHANGED
|
@@ -427,7 +427,6 @@ var Line = /*#__PURE__*/function () {
|
|
|
427
427
|
}, {
|
|
428
428
|
key: "beginDrawingLine",
|
|
429
429
|
value: function beginDrawingLine(state, layerID, x, y, onInternalEvent) {
|
|
430
|
-
var _state$get;
|
|
431
430
|
// if end drawing by created area
|
|
432
431
|
if (state.mode == MODE_IDLE) {
|
|
433
432
|
return {
|
|
@@ -481,8 +480,7 @@ var Line = /*#__PURE__*/function () {
|
|
|
481
480
|
drawingSupport: drawingSupport
|
|
482
481
|
});
|
|
483
482
|
var layer = state.getIn(['scene', 'layers', layerID]);
|
|
484
|
-
var
|
|
485
|
-
var payload = updatePayloadOfInternalEvent(line, layer, catalog);
|
|
483
|
+
var payload = updatePayloadOfInternalEvent(line, layer);
|
|
486
484
|
if (onInternalEvent) onInternalEvent({
|
|
487
485
|
type: INTERNAL_EVENT_START_DRAW_WALL,
|
|
488
486
|
value: payload
|
package/es/components/content.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import Viewer2D from "./viewer2d/viewer2d";
|
|
4
4
|
import Viewer3D from "./viewer3d/viewer3d";
|
|
@@ -20,11 +20,23 @@ export default function Content(_ref) {
|
|
|
20
20
|
var mode = state.get('mode');
|
|
21
21
|
|
|
22
22
|
// Internal Event for unselect_all
|
|
23
|
+
var prevSelectedCountRef = useRef(null);
|
|
23
24
|
useEffect(function () {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
var selectedCount = state.getIn(['scene', 'layers', 'layer-1', 'selected', 'vertices']).size + state.getIn(['scene', 'layers', 'layer-1', 'selected', 'lines']).size + state.getIn(['scene', 'layers', 'layer-1', 'selected', 'holes']).size + state.getIn(['scene', 'layers', 'layer-1', 'selected', 'areas']).size + state.getIn(['scene', 'layers', 'layer-1', 'selected', 'items']).size;
|
|
26
|
+
|
|
27
|
+
// Skip the initial mount/hydration; only emit when selection transitions from non-empty -> empty.
|
|
28
|
+
if (prevSelectedCountRef.current === null) {
|
|
29
|
+
prevSelectedCountRef.current = selectedCount;
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
var prevSelectedCount = prevSelectedCountRef.current;
|
|
33
|
+
prevSelectedCountRef.current = selectedCount;
|
|
34
|
+
if (prevSelectedCount > 0 && selectedCount < 1) {
|
|
35
|
+
onInternalEvent === null || onInternalEvent === void 0 || onInternalEvent({
|
|
36
|
+
type: constants.INTERNAL_EVENT_UNSELECT_ALL,
|
|
37
|
+
value: null
|
|
38
|
+
});
|
|
39
|
+
}
|
|
28
40
|
}, [state.getIn(['scene', 'layers', 'layer-1', 'selected'])]);
|
|
29
41
|
switch (mode) {
|
|
30
42
|
// this mode is when view elevation
|
|
@@ -131,4 +143,7 @@ Content.propTypes = {
|
|
|
131
143
|
height: PropTypes.number.isRequired,
|
|
132
144
|
replaceCabinet: PropTypes.func.isRequired,
|
|
133
145
|
onInternalEvent: PropTypes.func.isRequired
|
|
146
|
+
};
|
|
147
|
+
Content.contextTypes = {
|
|
148
|
+
projectActions: PropTypes.object.isRequired
|
|
134
149
|
};
|
package/es/components/export.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import Content from "./content";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
2
|
+
import Viewer2DComponents from "./viewer2d/export";
|
|
3
|
+
import StyleComponents from "./style/export";
|
|
4
|
+
|
|
5
|
+
export { Content, Viewer2DComponents, StyleComponents };
|
|
6
|
+
|
|
7
|
+
export default { Content, Viewer2DComponents, StyleComponents };
|
|
@@ -3,14 +3,12 @@ import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
|
3
3
|
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
|
|
4
4
|
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
|
|
5
5
|
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
6
|
-
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
7
6
|
import _taggedTemplateLiteral from "@babel/runtime/helpers/esm/taggedTemplateLiteral";
|
|
8
7
|
var _templateObject;
|
|
9
8
|
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
10
9
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
11
10
|
import React, { Component } from 'react';
|
|
12
11
|
import PropTypes from 'prop-types';
|
|
13
|
-
import AppContext from "../../AppContext";
|
|
14
12
|
import { KEYBOARD_BUTTON_CODE, TEXT_COLOR_NEUTRAL_0, SECONDARY_PURPLE_COLOR, DEFAULT_FONT_FAMILY } from "../../constants";
|
|
15
13
|
import styled from 'styled-components';
|
|
16
14
|
import { isValidNumber } from "../../utils/helper";
|
|
@@ -40,8 +38,8 @@ var FormNumberInput = /*#__PURE__*/function (_Component) {
|
|
|
40
38
|
}
|
|
41
39
|
}
|
|
42
40
|
}, {
|
|
43
|
-
key: "
|
|
44
|
-
value: function
|
|
41
|
+
key: "componentWillReceiveProps",
|
|
42
|
+
value: function componentWillReceiveProps(nextProps) {
|
|
45
43
|
if (this.props.value !== nextProps.value || this.props.focus !== nextProps.focus) {
|
|
46
44
|
this.setState({
|
|
47
45
|
showedValue: nextProps.value,
|
|
@@ -155,7 +153,6 @@ var FormNumberInput = /*#__PURE__*/function (_Component) {
|
|
|
155
153
|
}
|
|
156
154
|
}]);
|
|
157
155
|
}(Component);
|
|
158
|
-
_defineProperty(FormNumberInput, "contextType", AppContext);
|
|
159
156
|
export { FormNumberInput as default };
|
|
160
157
|
FormNumberInput.propTypes = {
|
|
161
158
|
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
@@ -170,6 +167,11 @@ FormNumberInput.propTypes = {
|
|
|
170
167
|
labelName: PropTypes.string,
|
|
171
168
|
isCeiling: PropTypes.string
|
|
172
169
|
};
|
|
170
|
+
FormNumberInput.contextTypes = {
|
|
171
|
+
translator: PropTypes.object.isRequired,
|
|
172
|
+
projectActions: PropTypes.object.isRequired,
|
|
173
|
+
linesActions: PropTypes.object.isRequired
|
|
174
|
+
};
|
|
173
175
|
FormNumberInput.defaultProps = {
|
|
174
176
|
value: 0,
|
|
175
177
|
style: {},
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
|
3
|
+
var _excluded = ["children"];
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import Button from "./button";
|
|
6
|
+
import * as SharedStyle from "../../shared-style";
|
|
7
|
+
var STYLE = {
|
|
8
|
+
borderColor: '#415375',
|
|
9
|
+
backgroundColor: '#415375',
|
|
10
|
+
color: SharedStyle.COLORS.white
|
|
11
|
+
};
|
|
12
|
+
var STYLE_HOVER = {
|
|
13
|
+
borderColor: '#1f3149',
|
|
14
|
+
backgroundColor: '#1f3149',
|
|
15
|
+
color: SharedStyle.COLORS.white
|
|
16
|
+
};
|
|
17
|
+
export default function FormSubmitButton(_ref) {
|
|
18
|
+
var children = _ref.children,
|
|
19
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
|
20
|
+
return /*#__PURE__*/React.createElement(Button, _extends({
|
|
21
|
+
type: "submit",
|
|
22
|
+
style: STYLE,
|
|
23
|
+
styleHover: STYLE_HOVER
|
|
24
|
+
}, rest), children);
|
|
25
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import AppContext from "../../AppContext";
|
|
4
3
|
import If from "../../utils/react-if";
|
|
5
4
|
import * as sharedStyles from "../../shared-style";
|
|
6
5
|
var cx = 0;
|
|
@@ -11,13 +10,12 @@ var STYLE_CIRCLE = {
|
|
|
11
10
|
stroke: sharedStyles.MATERIAL_COLORS[500].orange,
|
|
12
11
|
cursor: 'default'
|
|
13
12
|
};
|
|
14
|
-
export default function Group(_ref) {
|
|
13
|
+
export default function Group(_ref, _ref2) {
|
|
15
14
|
var layer = _ref.layer,
|
|
16
15
|
group = _ref.group,
|
|
17
16
|
scene = _ref.scene,
|
|
18
17
|
catalog = _ref.catalog;
|
|
19
|
-
var
|
|
20
|
-
translator = _useContext.translator;
|
|
18
|
+
var translator = _ref2.translator;
|
|
21
19
|
return /*#__PURE__*/React.createElement("g", {
|
|
22
20
|
"data-element-root": true,
|
|
23
21
|
"data-prototype": group.prototype,
|
|
@@ -49,4 +47,7 @@ Group.propTypes = {
|
|
|
49
47
|
layer: PropTypes.object.isRequired,
|
|
50
48
|
scene: PropTypes.object.isRequired,
|
|
51
49
|
catalog: PropTypes.object.isRequired
|
|
50
|
+
};
|
|
51
|
+
Group.contextTypes = {
|
|
52
|
+
translator: PropTypes.object.isRequired
|
|
52
53
|
};
|