kitchen-simulator 5.0.0-test.6 → 5.0.0-test.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kitchen-simulator",
3
- "version": "5.0.0-test.6",
3
+ "version": "5.0.0-test.7",
4
4
  "description": "It is a kitchen simulator.",
5
5
  "type": "module",
6
6
 
@@ -16,7 +16,17 @@
16
16
  },
17
17
 
18
18
  "files": [
19
- "src",
19
+ "src/*.js",
20
+ "src/*.jsx",
21
+ "src/catalog",
22
+ "src/components",
23
+ "src/utils",
24
+ "src/actions",
25
+ "src/reducers",
26
+ "src/class",
27
+ "src/plugins",
28
+ "src/shared-style",
29
+ "src/translator",
20
30
  "README.md",
21
31
  "LICENSE"
22
32
  ],
@@ -6,17 +6,16 @@ import { Map } from 'immutable';
6
6
  import PropTypes from 'prop-types';
7
7
  import React, { PureComponent } from 'react';
8
8
  import { FaPlayCircle } from 'react-icons/fa';
9
- import * as testJsonData from '../../../../../../../../../test_projects/*.json';
10
- import * as door_closet from '../../../../demo/src/catalog/holes/door-closet/planner-element';
11
- import * as door_exterior from '../../../../demo/src/catalog/holes/door-exterior/planner-element';
12
- import * as door_interior from '../../../../demo/src/catalog/holes/door-interior/planner-element';
13
- import * as door_sliding from '../../../../demo/src/catalog/holes/door-sliding/planner-element';
14
- import * as door_framed from '../../../../demo/src/catalog/holes/doorway-framed/planner-element';
15
- import * as door_frameless from '../../../../demo/src/catalog/holes/doorway-frameless/planner-element';
16
- import * as window_clear from '../../../../demo/src/catalog/holes/window-clear/planner-element';
17
- import * as window_cross from '../../../../demo/src/catalog/holes/window-cross/planner-element';
18
- import * as window_double_hung from '../../../../demo/src/catalog/holes/window-double-hung/planner-element';
19
- import * as window_vertical from '../../../../demo/src/catalog/holes/window-vertical/planner-element';
9
+ import * as door_closet from '../../../catalog/holes/door-closet/planner-element';
10
+ import * as door_exterior from '../../../catalog/holes/door-exterior/planner-element';
11
+ import * as door_interior from '../../../catalog/holes/door-interior/planner-element';
12
+ import * as door_sliding from '../../../catalog/holes/door-sliding/planner-element';
13
+ import * as door_framed from '../../../catalog/holes/doorway-framed/planner-element';
14
+ import * as door_frameless from '../../../catalog/holes/doorway-frameless/planner-element';
15
+ import * as window_clear from '../../../catalog/holes/window-clear/planner-element';
16
+ import * as window_cross from '../../../catalog/holes/window-cross/planner-element';
17
+ import * as window_double_hung from '../../../catalog/holes/window-double-hung/planner-element';
18
+ import * as window_vertical from '../../../catalog/holes/window-vertical/planner-element';
20
19
  import { formatNumber, toFixedFloat } from '../../../utils/math';
21
20
  import FormNumberInput from '../../style/form-number-input';
22
21
  import PlgItem from '../plugin-item.jsx';
@@ -3885,32 +3884,6 @@ export default class Toolbar extends PureComponent {
3885
3884
  }
3886
3885
  };
3887
3886
 
3888
- let testData = [];
3889
- if (process.env.MODE === 'staging') {
3890
- for (let testJson in testJsonData) {
3891
- testData.push(
3892
- <S.testJsonItemWrapper
3893
- onClick={() => {
3894
- if (
3895
- window.confirm(
3896
- `Do you really load ${testJson}.json for KC test?`
3897
- )
3898
- ) {
3899
- this.context.projectActions.loadProject(
3900
- JSON.parse(testJsonData[testJson].project_data),
3901
- this.props.categoryData
3902
- );
3903
- this.setState({ addingJson: false });
3904
- this.props.setToolbar('');
3905
- }
3906
- }}
3907
- >
3908
- {testJson}
3909
- </S.testJsonItemWrapper>
3910
- );
3911
- }
3912
- }
3913
-
3914
3887
  const isShowMoldingMenuItem = (subCabinetCategory, item) => {
3915
3888
  if (subCabinetCategory.name === TOE_KICK_MOLDING) {
3916
3889
  const items = this.state.elements.items?.toArray() ?? [];
@@ -3997,25 +3970,6 @@ export default class Toolbar extends PureComponent {
3997
3970
  );
3998
3971
  })}
3999
3972
  </S.SubCategoryItemWrapper>
4000
- {process.env.MODE === 'staging' &&
4001
- !!Object.keys(testJsonData).length && (
4002
- <S.SubCategoryItemWrapper
4003
- onClick={() =>
4004
- this.setState({
4005
- addingJson: !this.state.addingJson,
4006
- selectedRoomElement: ''
4007
- })
4008
- }
4009
- >
4010
- <S.SubCategoryItem>
4011
- <S.SubCategoryItemLabel
4012
- style={{ marginLeft: 15, color: TEXT_COLOR_NEUTRAL_0 }}
4013
- >
4014
- Test JSONs
4015
- </S.SubCategoryItemLabel>
4016
- </S.SubCategoryItem>
4017
- </S.SubCategoryItemWrapper>
4018
- )}
4019
3973
  </S.SubToolbarWrapper>
4020
3974
  {selectedRoomElement && (
4021
3975
  <S.SubToolbarWrapper
@@ -4065,20 +4019,6 @@ export default class Toolbar extends PureComponent {
4065
4019
  })}
4066
4020
  </S.SubToolbarWrapper>
4067
4021
  )}
4068
- {process.env.MODE === 'staging' &&
4069
- !!Object.keys(testJsonData).length &&
4070
- this.state.addingJson && (
4071
- <S.SubToolbarWrapper
4072
- id="test_json_datas"
4073
- style={{
4074
- alignItems: 'flex-start',
4075
- marginLeft: 20,
4076
- minWidth: 250
4077
- }}
4078
- >
4079
- {testData}
4080
- </S.SubToolbarWrapper>
4081
- )}
4082
4022
  </div>
4083
4023
  )
4084
4024
  },
@@ -1,49 +1,46 @@
1
1
  import * as Three from 'three';
2
+ import { Color, Group } from 'three';
2
3
  import createGrid from './grid-creator';
3
4
  import { disposeObject } from './three-memory-cleaner';
4
- import { Color, Group } from 'three';
5
- import { isUndefined } from 'util';
6
5
  import {
7
- MODE_DRAWING_ITEM_3D,
8
- EPSILON,
9
- DISTANCE_EPSILON,
10
- OBJTYPE_MESH,
11
- ARROW_TEXT_FORECOLOR,
12
- ARROW_TEXT_BACKCOLOR,
13
- ARROW_TEXT_FONTFACE,
14
- UNIT_CENTIMETER,
15
- SHADE_DARK_PURPLE_COLOR,
16
- MODE_DRAGGING_ITEM_3D,
17
- MODE_ROTATING_ITEM_3D,
18
6
  ANIMATE_STEP_MAX,
19
7
  ANIMATE_STEP_MIN,
20
- ANIMATE_OBJECT_OPEN_DOOR_ROTATION_UNIT,
21
- TOP_MOLDING_LOCATION,
22
- MIDDLE_MOLDING_LOCATION,
23
- BOTTOM_MOLDING_LOCATION,
8
+ ARRAY_3D_MODES,
9
+ ARROW_TEXT_BACKCOLOR,
10
+ ARROW_TEXT_FONTFACE,
11
+ ARROW_TEXT_FORECOLOR,
24
12
  BASE_CABINET_LAYOUTPOS,
25
- TALL_CABINET_LAYOUTPOS,
26
- WALL_CABINET_LAYOUTPOS,
13
+ BOTTOM_MOLDING_LOCATION,
27
14
  DECIMAL_PLACES_2,
28
15
  DIFFERENT_VALUES_PATH_LENGTH,
16
+ DISTANCE_EPSILON,
17
+ EPSILON,
18
+ MIDDLE_MOLDING_LOCATION,
19
+ MODE_DRAGGING_ITEM_3D,
20
+ MODE_DRAWING_ITEM_3D,
21
+ MODE_IDLE,
29
22
  MODE_IDLE_3D,
30
- ARRAY_3D_MODES,
31
- MODE_IDLE
23
+ MODE_ROTATING_ITEM_3D,
24
+ OBJTYPE_MESH,
25
+ SHADE_DARK_PURPLE_COLOR,
26
+ TOP_MOLDING_LOCATION,
27
+ UNIT_CENTIMETER,
28
+ WALL_CABINET_LAYOUTPOS
32
29
  } from '../../constants';
33
- import { IDBroker, GeometryUtils, MoldingUtils } from '../../utils/export';
30
+ import { GeometryUtils, IDBroker, MoldingUtils } from '../../utils/export';
34
31
  import convert from 'convert-units';
35
32
  import { verticesDistance } from '../../utils/geometry';
36
- import * as GeomUtils from '../../../demo/src/catalog/utils/geom-utils';
37
- import { loadTexture } from '../../../demo/src/catalog/utils/item-loader';
38
33
  import { returnReplaceableDeepSearchType } from '../viewer2d/utils';
39
34
  import {
40
- replaceMeshesWithLineSegments,
35
+ animateDoor,
41
36
  isElevationView,
42
37
  isEmpty,
43
- animateDoor,
38
+ replaceMeshesWithLineSegments,
44
39
  translateDrawer
45
40
  } from '../../../src/utils/helper';
46
41
  import { formatNumber } from '../../utils/math';
42
+ import * as GeomUtils from '../../../src/catalog/utils/geom-utils.js';
43
+ import { loadTexture } from '../../../src/catalog/utils/item-loader.jsx';
47
44
 
48
45
  let transformBox;
49
46
  export var fVLine = [];
@@ -5,32 +5,31 @@ import PropTypes from 'prop-types';
5
5
  import ReactDOM from 'react-dom';
6
6
  import * as Three from 'three';
7
7
  import {
8
+ checkCabinetOverlap,
9
+ createBacksplash,
10
+ deleteSpecifiedMeshObjects,
11
+ fVLine,
12
+ getDistances,
8
13
  parseData,
9
14
  updateScene,
10
- visibleTransformBox,
11
- getDistances,
12
- fVLine,
13
- deleteSpecifiedMeshObjects,
14
- createBacksplash,
15
- checkCabinetOverlap
15
+ visibleTransformBox
16
16
  } from './scene-creator';
17
- import { disposeScene } from './three-memory-cleaner';
18
- import { disposeObject } from './three-memory-cleaner';
17
+ import { disposeObject, disposeScene } from './three-memory-cleaner';
19
18
  import diff from 'immutablediff';
20
19
  import * as SharedStyle from '../../shared-style';
21
20
  import {
22
- MODE_DRAWING_ITEM_3D,
23
- MODE_IDLE_3D,
21
+ BASE_CABINET_LAYOUTPOS,
24
22
  MODE_3D_VIEW,
25
- UNIT_CENTIMETER,
23
+ MODE_DRAGGING_ITEM_3D,
26
24
  MODE_DRAWING_HOLE_3D,
27
- SECONDARY_PURPLE_COLOR,
25
+ MODE_DRAWING_ITEM_3D,
28
26
  MODE_ELEVATION_VIEW,
29
- MODE_DRAGGING_ITEM_3D,
27
+ MODE_IDLE_3D,
30
28
  MODE_ROTATING_ITEM_3D,
31
- WALL_CABINET_LAYOUTPOS,
32
- BASE_CABINET_LAYOUTPOS,
33
- TALL_CABINET_LAYOUTPOS
29
+ SECONDARY_PURPLE_COLOR,
30
+ TALL_CABINET_LAYOUTPOS,
31
+ UNIT_CENTIMETER,
32
+ WALL_CABINET_LAYOUTPOS
34
33
  } from '../../constants';
35
34
 
36
35
  import { isUndefined } from 'util';
@@ -40,13 +39,14 @@ import { GeometryUtils } from '../../utils/export';
40
39
  import { handleCamRect, isElevationView, isEmpty } from '../../utils/helper';
41
40
  import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';
42
41
  import CameraControls from 'camera-controls';
43
- CameraControls.install({ THREE: Three });
44
42
  import { returnReplaceableDeepSearchType } from '../viewer2d/utils';
45
43
  import {
46
44
  getAllMeshes,
47
45
  vectorIntersectWithMesh
48
46
  } from '../../utils/objects-utils';
49
47
 
48
+ CameraControls.install({ THREE: Three });
49
+
50
50
  export default class Scene3DViewer extends React.Component {
51
51
  constructor(props) {
52
52
  super(props);
@@ -2978,7 +2978,7 @@ export default class Scene3DViewer extends React.Component {
2978
2978
  line = line.children[0].children[0];
2979
2979
  // index(faces) of the line
2980
2980
  const indexAttribute = line.geometry.getIndex();
2981
- const firstFaceIndices = undefined;
2981
+ let firstFaceIndices = undefined;
2982
2982
  if (indexAttribute && indexAttribute.length > 0) {
2983
2983
  firstFaceIndices = [
2984
2984
  indexAttribute.getX(0),
@@ -1,38 +0,0 @@
1
- import axios from 'axios';
2
- import { useQuery } from 'react-query';
3
- import ls from 'localstorage-slim';
4
- import { LOCAL_STORAGE_TOKEN_VALUE } from '../../src/constants';
5
-
6
- const fetchCart = async () => {
7
- const accessToken = ls.get(LOCAL_STORAGE_TOKEN_VALUE);
8
- const visualizerName = sessionStorage.getItem('visualizerName');
9
-
10
- const response = await axios.post(
11
- `${process.env.API_URL}/api/project/checkCart`,
12
- {
13
- client_name: visualizerName,
14
- user_token: accessToken
15
- }
16
- );
17
-
18
- return response.data;
19
- };
20
-
21
- export const useCheckCart = ({ enabled = true }) =>
22
- useQuery({
23
- queryKey: ['cart'],
24
- queryFn: fetchCart,
25
- initialData: {
26
- is_empty: true
27
- },
28
- enabled,
29
- retry: 1,
30
- refetchOnWindowFocus: false,
31
- refetchOnWindowBlur: false,
32
- onSuccess: data => {
33
- console.log(`[useCheckCart] Fetched cart check data`, data);
34
- },
35
- onError: error => {
36
- console.log(`[useCheckCart] Failed to fetch cart check`, error);
37
- }
38
- });
@@ -1,59 +0,0 @@
1
- import axios from 'axios';
2
- import { useQuery } from 'react-query';
3
- import ls from 'localstorage-slim';
4
- import {
5
- LOCAL_STORAGE_TOKEN_VALUE,
6
- LOCAL_STORAGE_CUSTOMER_INFO
7
- } from '../../src/constants';
8
-
9
- function formatPrice(value) {
10
- const num = parseFloat((value || '').replace(/,/g, ''));
11
- return isNaN(num) ? 0 : parseFloat(num.toFixed(2));
12
- }
13
-
14
- const fetchPricesBySku = async (ids, accessToken) => {
15
- const customer = ls.get(LOCAL_STORAGE_CUSTOMER_INFO);
16
-
17
- const visualizerName = sessionStorage.getItem('visualizerName');
18
-
19
- const response = await axios.post(
20
- `${process.env.API_URL}/api/pricing/getPrices`,
21
- {
22
- client_name: visualizerName,
23
- customer_email: customer?.email || '',
24
- skus: ids,
25
- token: accessToken
26
- }
27
- );
28
-
29
- return {
30
- discount_type: response.data.discount_type || '',
31
- prices: response.data.prices.map(priceProduct => ({
32
- ...priceProduct,
33
- sku: priceProduct.internal_sku,
34
- regular_price: formatPrice(priceProduct.price),
35
- discounted_price: formatPrice(priceProduct.discounted_price)
36
- }))
37
- };
38
- };
39
-
40
- export const useGetPricesBySku = ids => {
41
- const accessToken = ls.get(LOCAL_STORAGE_TOKEN_VALUE);
42
-
43
- return useQuery({
44
- queryKey: ['prices', ids, accessToken],
45
- queryFn: () => fetchPricesBySku(ids, accessToken),
46
- enabled: Array.isArray(ids) && ids.length > 0,
47
- initialData: {
48
- discount_type: '',
49
- prices: []
50
- },
51
- retry: 1,
52
- onSuccess: data => {
53
- ls.set('DISCOUNT_TYPE', data.discount_type);
54
- },
55
- onError: error => {
56
- console.log(`[useGetPricesBySku] Failed to fetch prices`, error);
57
- }
58
- });
59
- };
@@ -1,181 +0,0 @@
1
- // hooks/useValidateToken.js
2
- import axios from 'axios';
3
- import { useQuery } from 'react-query';
4
- import ls from 'localstorage-slim';
5
- import {
6
- LOCAL_STORAGE_TOKEN_VALUE,
7
- LOCAL_STORAGE_CUSTOMER_INFO,
8
- LOCAL_STORAGE_ORIGINAL_TOKEN
9
- } from '../../src/constants';
10
- import {
11
- ENCODED_QUERY_PARAM_TOKEN,
12
- QUERY_PARAM_TOKEN
13
- } from '../../demo/src/CrossSignOn';
14
-
15
- const LOG_PREFIX = `[Cross Sign On]`;
16
-
17
- function persistAccessToken(accessToken) {
18
- const url = new URL(window.location.href);
19
- const token = url.searchParams.get(QUERY_PARAM_TOKEN);
20
- const encodedToken = url.searchParams.get(ENCODED_QUERY_PARAM_TOKEN);
21
-
22
- if (!accessToken) return;
23
-
24
- if (!token && !encodedToken) {
25
- return;
26
- }
27
-
28
- if (token) {
29
- url.searchParams.set(QUERY_PARAM_TOKEN, accessToken);
30
- }
31
-
32
- if (encodedToken) {
33
- url.searchParams.set(ENCODED_QUERY_PARAM_TOKEN, accessToken);
34
- }
35
-
36
- console.log(`${LOG_PREFIX} Persisting access token`);
37
- ls.set(LOCAL_STORAGE_TOKEN_VALUE, accessToken);
38
-
39
- if (window.location.href !== url.toString()) {
40
- window.history.replaceState({}, document.title, url.toString());
41
- }
42
- }
43
-
44
- function persistCustomerInfo(customerInfo) {
45
- if (!customerInfo) return;
46
-
47
- console.log(`${LOG_PREFIX} Persisting customer info`);
48
- ls.set(LOCAL_STORAGE_CUSTOMER_INFO, customerInfo);
49
- }
50
-
51
- async function refreshToken(currentToken) {
52
- const visualizerName = sessionStorage.getItem('visualizerName');
53
-
54
- try {
55
- const { data: refreshData } = await axios.post(
56
- `${process.env.API_URL}/api/token/refresh`,
57
- {
58
- client_name: visualizerName,
59
- token: currentToken
60
- }
61
- );
62
-
63
- if (
64
- refreshData &&
65
- refreshData.status === 'success' &&
66
- refreshData.accessToken
67
- ) {
68
- return {
69
- refreshed: true,
70
- token: refreshData.accessToken,
71
- raw: refreshData
72
- };
73
- }
74
-
75
- console.error(`${LOG_PREFIX} Token refresh failed`, refreshData?.message);
76
- throw new Error(refreshData?.message || 'Token refresh failed');
77
- } catch (err) {
78
- console.error(`${LOG_PREFIX} Error refreshing token`, err);
79
- throw err;
80
- }
81
- }
82
-
83
- /**
84
- * Normalizes validate/refresh results so consumers have a predictable shape.
85
- * Returns:
86
- * {
87
- * token: string | null,
88
- * customer: { email, firstName, lastName, tier } | null,
89
- * source: 'validated' | 'refreshed' | 'object' | 'unknown' | 'none'
90
- * }
91
- */
92
- async function fetchValidateToken(accessToken) {
93
- const visualizerName = sessionStorage.getItem('visualizerName');
94
- // Case: string token flow
95
- if (typeof accessToken === 'string' && accessToken) {
96
- try {
97
- const { data } = await axios.post(
98
- `${process.env.API_URL}/api/token/validate`,
99
- {
100
- client_name: visualizerName,
101
- token: accessToken
102
- }
103
- );
104
-
105
- if (data && data.status !== 'error' && data.email) {
106
- const customer = {
107
- email: data.email,
108
- firstName: data.firstName,
109
- lastName: data.lastName,
110
- tier: data.tier
111
- };
112
- ls.set(LOCAL_STORAGE_ORIGINAL_TOKEN, accessToken);
113
- persistAccessToken(accessToken);
114
- persistCustomerInfo(customer);
115
-
116
- return {
117
- token: accessToken,
118
- customer,
119
- source: 'validated'
120
- };
121
- }
122
-
123
- // If API returns an error status, try refresh
124
- if (
125
- data?.status === 'error' &&
126
- data.message.toLowerCase().includes('expired')
127
- ) {
128
- console.log(`${LOG_PREFIX} Token validation failed`, data.message);
129
- const refreshed = await refreshToken(accessToken);
130
-
131
- if (refreshed.token && typeof refreshed.token === 'string') {
132
- ls.set(LOCAL_STORAGE_ORIGINAL_TOKEN, refreshed.token);
133
- persistAccessToken(refreshed.token);
134
-
135
- window.dispatchEvent(
136
- new CustomEvent('token-changed', { detail: refreshed.token })
137
- );
138
- }
139
-
140
- return {
141
- token: refreshed.token,
142
- customer: null, // customer not returned by refresh; will be filled by next authenticated fetch
143
- source: 'refreshed'
144
- };
145
- }
146
-
147
- // If no email but not an explicit error, just return token
148
- return {
149
- token: accessToken,
150
- customer: null,
151
- source: 'validated'
152
- };
153
- } catch (e) {
154
- console.log(`${LOG_PREFIX} Failed fetching customer info`, e);
155
- const refreshed = await refreshToken(accessToken);
156
- return {
157
- token: refreshed.token ? refreshed.token : accessToken,
158
- customer: null,
159
- source: 'refreshed'
160
- };
161
- }
162
- }
163
-
164
- // No token
165
- return { token: null, customer: null, source: 'unknown' };
166
- }
167
-
168
- export const useValidateToken = accessToken => {
169
- return useQuery({
170
- queryKey: [
171
- 'validate-token',
172
- typeof accessToken === 'object' ? accessToken?.token : accessToken
173
- ],
174
- queryFn: () => fetchValidateToken(accessToken),
175
- retry: 1,
176
- onError: error => {
177
- console.error(`[useValidateToken] Validation failed`, error);
178
- },
179
- initialData: { token: null, customer: null, source: 'none' }
180
- });
181
- };
@@ -1,7 +0,0 @@
1
- import * as TabsStyle from './tabs.css';
2
-
3
- export { TabsStyle };
4
-
5
- export default {
6
- TabsStyle
7
- };
@@ -1,40 +0,0 @@
1
- .react-tabs__tab-list {
2
- border-bottom: 1px solid #aaa;
3
- margin: 0 0 10px;
4
- padding: 0;
5
- }
6
-
7
- .react-tabs__tab {
8
- display: inline-block;
9
- border: 1px solid transparent;
10
- border-bottom: none;
11
- bottom: -1px;
12
- position: relative;
13
- list-style: none;
14
- padding: 6px 12px;
15
- cursor: pointer;
16
- }
17
-
18
- .react-tabs__tab--selected,
19
- .react-tabs__tab:focus {
20
- border-color: #aaa;
21
- color: #1ca6fc;
22
- outline: none;
23
- }
24
-
25
- .react-tabs__tab-panel {
26
- display: none;
27
- }
28
-
29
- .react-tabs__tab-panel--selected {
30
- display: block;
31
- }
32
-
33
- @keyframes spin {
34
- from {
35
- transform: rotate(0deg);
36
- }
37
- to {
38
- transform: rotate(360deg);
39
- }
40
- }