@colijnit/configurator 262.1.8 → 262.1.10

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 (46) hide show
  1. package/fesm2022/colijnit-configurator.mjs +2430 -789
  2. package/fesm2022/colijnit-configurator.mjs.map +1 -1
  3. package/index.d.ts +321 -81
  4. package/lib/components/answer-info-dialog/style/_theme.scss +3 -3
  5. package/lib/components/answers-slideout/style/_layout.scss +10 -10
  6. package/lib/components/configuration-preset/style/_layout.scss +1 -1
  7. package/lib/components/configuration-preset/style/_theme.scss +2 -2
  8. package/lib/components/configuration-preset-dialog/style/_theme.scss +7 -7
  9. package/lib/components/configurator-dialog/style/_theme.scss +5 -5
  10. package/lib/components/configurator-scene/style/_layout.scss +1 -0
  11. package/lib/components/element-buttons/style/_layout.scss +13 -12
  12. package/lib/components/element-buttons/style/_material-definition.scss +9 -0
  13. package/lib/components/element-buttons/style/_theme.scss +15 -7
  14. package/lib/components/element-toolbar/style/_layout.scss +30 -4
  15. package/lib/components/element-toolbar/style/_material-definition.scss +3 -1
  16. package/lib/components/element-toolbar/style/_theme.scss +13 -12
  17. package/lib/components/product-configurator/style/_layout.scss +18 -7
  18. package/lib/components/product-configurator/style/_theme.scss +3 -3
  19. package/lib/components/product-configurator-grouped-repeatable-options/style/_layout.scss +74 -0
  20. package/lib/components/product-configurator-grouped-repeatable-options/style/_material-definition.scss +12 -0
  21. package/lib/components/product-configurator-grouped-repeatable-options/style/_theme.scss +75 -0
  22. package/lib/components/product-configurator-grouped-repeatable-options/style/material.scss +3 -0
  23. package/lib/components/product-configurator-repeat-buttons/style/_layout.scss +24 -0
  24. package/lib/components/product-configurator-repeat-buttons/style/_material-definition.scss +3 -0
  25. package/lib/components/product-configurator-repeat-buttons/style/_theme.scss +24 -0
  26. package/lib/components/product-configurator-repeat-buttons/style/material.scss +3 -0
  27. package/lib/components/product-configurator-selector/style/_layout.scss +36 -3
  28. package/lib/components/product-configurator-selector/style/_theme.scss +41 -22
  29. package/lib/components/product-configurator-selector-child-article/style/_layout.scss +40 -0
  30. package/lib/components/product-configurator-selector-child-article/style/_material-definition.scss +3 -0
  31. package/lib/components/product-configurator-selector-child-article/style/_theme.scss +29 -0
  32. package/lib/components/product-configurator-selector-child-article/style/material.scss +3 -0
  33. package/lib/components/product-configurator-selector-option/style/_theme.scss +18 -1
  34. package/lib/components/product-configurator-selector-option-button/style/_theme.scss +5 -5
  35. package/lib/components/product-configurator-selector-option-checkbox/style/_theme.scss +9 -9
  36. package/lib/components/product-configurator-selector-option-dropdown/style/_theme.scss +2 -2
  37. package/lib/components/product-configurator-selector-option-tile/style/_layout.scss +1 -1
  38. package/lib/components/product-configurator-selector-option-tile/style/_theme.scss +52 -21
  39. package/lib/components/product-configurator-slideout/style/_layout.scss +38 -0
  40. package/lib/components/product-configurator-slideout/style/_material-definition.scss +3 -0
  41. package/lib/components/product-configurator-slideout/style/_theme.scss +30 -0
  42. package/lib/components/product-configurator-slideout/style/material.scss +3 -0
  43. package/lib/components/summary-line/style/_theme.scss +6 -6
  44. package/lib/style/_variables.scss +50 -40
  45. package/package.json +10 -10
  46. package/colijnit-configurator-262.1.7.tgz +0 -0
@@ -1,15 +1,16 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, EventEmitter, HostBinding, ViewEncapsulation, Component, Input, Output, HostListener, ViewChild, Directive, ElementRef, ViewChildren, TemplateRef, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
3
- import * as i5 from '@angular/common';
3
+ import * as i6$1 from '@angular/common';
4
4
  import { CommonModule, AsyncPipe } from '@angular/common';
5
5
  import { BehaviorSubject, Subject, combineLatest, debounceTime } from 'rxjs';
6
6
  import * as THREE from 'three';
7
7
  import { Color, WebGLRenderer, Box3, Vector3, Scene, PerspectiveCamera, MathUtils, AmbientLight, DirectionalLight, Group, Euler, Object3D, EventDispatcher, MeshBasicMaterial, Mesh, PlaneGeometry, DoubleSide, MeshStandardMaterial, CylinderGeometry, RingGeometry, Matrix4, Raycaster, BufferGeometry, Line, DataTexture, RGFormat, UnsignedByteType, LinearFilter, Shape, Vector2, SphereGeometry, SRGBColorSpace, PCFSoftShadowMap, ShadowMaterial, LightProbe, Texture as Texture$1, MeshPhongMaterial, NoToneMapping, TextureLoader, RGBAFormat, Quaternion, PointLight, BoxGeometry, BackSide, FrontSide, ShapeGeometry } from 'three';
8
+ import { Options } from '@colijnit/ioneconnector/build/model/options';
8
9
  import { HdecoPlacement } from '@colijnit/configuratorapi/build/enum/hdeco-placement.enum';
9
10
  import * as i6 from '@colijnit/utilities';
10
11
  import { ObjectUtils, MaterialUtils, DeviceUtils as DeviceUtils$1, DeviceTier as DeviceTier$1, TranslationModule, UtilitiesPipesModule } from '@colijnit/utilities';
11
12
  import { isNill } from '@colijnit/configuratorapi/build/utils/function/is-nill.function';
12
- import { VariationUtils, AssetUtils, FileUtils, ThreedUtils, DebugUtils, VariationHelper, SelectionUtils, Scene3DUtil } from '@colijnit/configuratorcore';
13
+ import { ImageUtils, VariationUtils, AssetUtils, FileUtils, ThreedUtils, DebugUtils, VariationHelper, SelectionUtils, Scene3DUtil } from '@colijnit/configuratorcore';
13
14
  import { UserRoleType } from '@colijnit/ioneconnector/build/enum/user-role-type.enum';
14
15
  import { MainApi } from '@colijnit/mainapi';
15
16
  import { TableName } from '@colijnit/mainapi/build/enum/table-name.enum';
@@ -18,9 +19,9 @@ import { BusinessObjectFactory } from '@colijnit/ioneconnector/build/service/bus
18
19
  import { Configurator } from '@colijnit/configuratorapi';
19
20
  import { NodeType } from '@colijnit/configuratorapi/build/enum/node-type.enum';
20
21
  import { Articles } from '@colijnit/articleapi/build/articles';
21
- import { Options } from '@colijnit/ioneconnector/build/model/options';
22
22
  import { Article } from '@colijnit/configuratorapi/build/model/article';
23
23
  import { Selection } from '@colijnit/configuratorapi/build/model/selection';
24
+ import { SelectorStructure } from '@colijnit/configuratorapi/build/model/selector-structure.bo';
24
25
  import { SelectorWithOptions } from '@colijnit/configuratorapi/build/model/selector-with-options';
25
26
  import { AnswerPrice } from '@colijnit/configuratorapi/build/model/answer-price';
26
27
  import { ArticleText } from '@colijnit/configuratorapi/build/model/article-text.bo';
@@ -42,19 +43,21 @@ import { XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerM
42
43
  import axios from 'axios';
43
44
  import { trigger, state, style, transition, animate } from '@angular/animations';
44
45
  import * as i4 from '@colijnit/corecomponents_v12';
45
- import { LoaderModule, IconModule, ButtonModule, InputTextModule, CardModule, PriceDisplayPipeModule, ImageModule, TooltipDirectiveModule } from '@colijnit/corecomponents_v12';
46
+ import { LoaderModule, IconModule, ButtonModule, InputTextModule, CardModule, PriceDisplayPipeModule, InputTextChipsModule, ImageModule, AppendPipeModule, TooltipDirectiveModule } from '@colijnit/corecomponents_v12';
46
47
  import * as i1 from '@angular/platform-browser';
47
48
  import { TemplatePortal } from '@angular/cdk/portal';
48
49
  import * as i2 from '@angular/cdk/overlay';
49
50
  import * as i7 from '@angular/cdk/clipboard';
50
51
  import { CdkCopyToClipboard } from '@angular/cdk/clipboard';
51
52
  import { ConfigurationDisplayOption } from '@colijnit/configuratorapi/build/enum/refcode/configuration-display-option.enum';
52
- import { SelectorStructure } from '@colijnit/configuratorapi/build/model/selector-structure.bo';
53
- import * as i6$1 from '@angular/forms';
53
+ import * as i6$2 from '@angular/forms';
54
54
  import { FormsModule } from '@angular/forms';
55
55
  import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';
56
56
  import { MatButtonModule } from '@angular/material/button';
57
57
  import { MatIconModule } from '@angular/material/icon';
58
+ import { fromEvent } from 'rxjs/internal/observable/fromEvent';
59
+ import { filter, delay, takeUntil } from 'rxjs/operators';
60
+ import { of } from 'rxjs/internal/observable/of';
58
61
 
59
62
  class ArParameters {
60
63
  depthOcclusion = false;
@@ -133,8 +136,11 @@ class SettingOptions {
133
136
  useExternalOpenSave = false;
134
137
  floorFadeStart = 2.0;
135
138
  floorFadeEnd = 6.0;
136
- maxVisibleTiles = 10;
137
- maxVisibleSmallTiles = 24;
139
+ limitStartView = false; // Only works for full config -> true to enable limited data on start
140
+ limitAmountOfTiles = false; // this enables the tile limits
141
+ amountOfGroupsToShow = 2; // this limits the level 1 stuff
142
+ maxVisibleTiles = 10; // this limits the amount of tiles shown on load
143
+ maxVisibleSmallTiles = 24; // this limits the amount of tiles shown on load
138
144
  groupedShowAllBtn = false;
139
145
  showSavePresetButton = false;
140
146
  showLoadPresetButton = false;
@@ -159,20 +165,10 @@ class SceneSettings {
159
165
  scenes;
160
166
  }
161
167
 
162
- class ConfiguratorSettings {
163
- url;
164
- schema;
165
- version;
166
- branch;
168
+ class ConfiguratorSettings extends Options {
167
169
  currency;
168
170
  currencySymbol = '€';
169
- username;
170
- password;
171
171
  session = undefined;
172
- useGroups = true;
173
- useRenders = false;
174
- useLoginEncryption = true;
175
- logoutWhenRefresh = true;
176
172
  useMatch = false;
177
173
  assetPath;
178
174
  threeDAssetPath;
@@ -181,10 +177,7 @@ class ConfiguratorSettings {
181
177
  additionalTranslationFile;
182
178
  apiUrl;
183
179
  client;
184
- timeoutInMs;
185
- languageCode;
186
180
  secondaryLogo;
187
- jwtEnabled;
188
181
  gtm;
189
182
  dracoPath = 'https?://cdn1.colijn-it.nl/draco/';
190
183
  mainUrl;
@@ -262,6 +255,12 @@ class ConfiguratorSettingsService {
262
255
  const ownOptions = Object.assign({}, this.settings.options);
263
256
  const ownRenderParameters = Object.assign({}, this.settings.renderParameters);
264
257
  const blenderSceneSettings = Object.assign({}, this.settings.blenderSceneSettings);
258
+ if (this.settings.url !== obj.url) { // other backend, clear some stuff
259
+ this.settings.password = undefined;
260
+ this.settings.dataSessionId = undefined;
261
+ this.settings.sessionId = undefined;
262
+ this.settings.getAccessTokenFunction = undefined;
263
+ }
265
264
  this.settings = Object.assign({}, this.settings, obj);
266
265
  if (obj.renderParameters) {
267
266
  this.settings.renderParameters = Object.assign({}, ownRenderParameters, obj.renderParameters);
@@ -435,6 +434,13 @@ class ConfiguratorEventService {
435
434
  renderImageChanged = new BehaviorSubject('');
436
435
  renderImageError = new BehaviorSubject('');
437
436
  startBuildFromPresetId = new Subject();
437
+ selectSelection = new Subject();
438
+ showAllConfigurationOptions = new Subject();
439
+ hideMainConfigurator = new Subject();
440
+ checkHiddenRepeatItem = new Subject();
441
+ checkForMarkedInputs = new Subject();
442
+ closeSlideOut = new Subject();
443
+ openSlideOut = new Subject();
438
444
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfiguratorEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
439
445
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfiguratorEventService, providedIn: 'root' });
440
446
  }
@@ -561,6 +567,19 @@ class RotationHelper {
561
567
  }
562
568
  }
563
569
 
570
+ class ConfiguratorErrorMessage {
571
+ message;
572
+ safeMessage;
573
+ description;
574
+ safeDescription;
575
+ constructor(message, description) {
576
+ this.message = message;
577
+ if (description) {
578
+ this.description = description;
579
+ }
580
+ }
581
+ }
582
+
564
583
  class ConfiguratorService {
565
584
  showLoader = new Subject();
566
585
  connectionReset = new Subject();
@@ -657,7 +676,15 @@ class ConfiguratorService {
657
676
  return this._configuratorApi.selectAnswerBySelection(selection, false, userInput);
658
677
  }
659
678
  navigateTo(chosenOption, showLoader = false) {
660
- return this._configuratorApi.navigateTo(chosenOption.opvTreeNodeHierarchy, showLoader);
679
+ return this._configuratorApi.navigateTo(chosenOption.nodeHierarchy, showLoader);
680
+ }
681
+ navigateToBySelNode(instanceId, chosenOption, showLoader = false) {
682
+ return this._configuratorApi.navigateToBySelNode(instanceId, chosenOption.selNodeHierarchy, showLoader);
683
+ }
684
+ nextCombNode(selection, showLoader = false) {
685
+ let params = {};
686
+ params.nodeId = selection.selNodeId;
687
+ return this._configuratorApi.nextCombNode(params, showLoader);
661
688
  }
662
689
  cancelAnswer(getAnswersAndQuestion = true) {
663
690
  return this._configuratorApi.cancelAnswer();
@@ -747,6 +774,9 @@ class ConfiguratorService {
747
774
  catch (e) {
748
775
  }
749
776
  }
777
+ repeatOption(params) {
778
+ return this._configuratorApi.repeatOption(params);
779
+ }
750
780
  _getPublicationCodeForRole(role) {
751
781
  if (this._publicationCodeForUserRole.has(role)) {
752
782
  return this._publicationCodeForUserRole.get(role);
@@ -766,19 +796,6 @@ function notNill(questionPublicationCode) {
766
796
  throw new Error('Function not implemented.');
767
797
  }
768
798
 
769
- class ConfiguratorErrorMessage {
770
- message;
771
- safeMessage;
772
- description;
773
- safeDescription;
774
- constructor(message, description) {
775
- this.message = message;
776
- if (description) {
777
- this.description = description;
778
- }
779
- }
780
- }
781
-
782
799
  class ConfiguratorConnectorService {
783
800
  _appEventService;
784
801
  _settingsService;
@@ -839,6 +856,17 @@ class ConfiguratorConnectorService {
839
856
  get instanceId() {
840
857
  return this._instanceId;
841
858
  }
859
+ /**
860
+ *
861
+ * This is for the nested article slide out for the full config template
862
+ *
863
+ * */
864
+ set activeSlideOutParentId(id) {
865
+ this._activeSlideOutParentId = id;
866
+ }
867
+ get activeSlideOutParentId() {
868
+ return this._activeSlideOutParentId;
869
+ }
842
870
  controllerInitialized = new BehaviorSubject(false);
843
871
  standAloneInstance = new BehaviorSubject(false);
844
872
  connectionReset = new Subject();
@@ -846,6 +874,7 @@ class ConfiguratorConnectorService {
846
874
  activeQuestion;
847
875
  activeAnswers = [];
848
876
  assetPath;
877
+ _activeSlideOutParentId;
849
878
  _selections = [];
850
879
  _currentSelections;
851
880
  _activeSelection;
@@ -857,6 +886,7 @@ class ConfiguratorConnectorService {
857
886
  _totalPrice;
858
887
  _imageCache = new Map();
859
888
  _exceptionQuestionChanged;
889
+ _exceptionIds = [];
860
890
  _shouldShowLoader;
861
891
  _connectorOptions = new Options();
862
892
  _subs = [];
@@ -993,17 +1023,24 @@ class ConfiguratorConnectorService {
993
1023
  copyInstanceAndLoseOriginalConfiguration(instanceId, result) {
994
1024
  return this._copyInstance(instanceId, false, result);
995
1025
  }
996
- async getQuestionAndAnswersAsync() {
1026
+ async getQuestionAndAnswersAsync(addedElement = false) {
997
1027
  const questionAndAnswers = await this._configuratorService.getQuestionAndAnswersAsync();
1028
+ // TODO Check exception handling.
998
1029
  // When using a full config template, we got some shit
999
1030
  // When we got a response with a question + answers, it means we got an option that got change by exceptions.
1000
1031
  // Save the option for exception, update the selectorStructor and make sure the costumer knows which choice needs to be checked
1001
1032
  if (questionAndAnswers.answers.length > 0 && this.article && this.article.showFullConfiguration) {
1002
- this._exceptionQuestionChanged = questionAndAnswers.question; // TODO we should change this
1033
+ if (!addedElement) {
1034
+ this._exceptionQuestionChanged = questionAndAnswers.question; // TODO we should change this
1035
+ }
1036
+ questionAndAnswers.answers.forEach(option => {
1037
+ if (option.node) {
1038
+ this._exceptionIds.push(option.node);
1039
+ }
1040
+ });
1003
1041
  await this.getSelectionsAsync();
1004
1042
  }
1005
1043
  questionAndAnswers.answers = questionAndAnswers.answers.filter(a => this._isAnswerPublished(a));
1006
- this._appEventService.answerCountReceived.next(questionAndAnswers.answers.length);
1007
1044
  if (questionAndAnswers.answers.length === 0) {
1008
1045
  this.emptyAnswersAndQuestion();
1009
1046
  }
@@ -1011,6 +1048,8 @@ class ConfiguratorConnectorService {
1011
1048
  this.activeQuestion = questionAndAnswers.question;
1012
1049
  this.activeAnswers = questionAndAnswers.answers;
1013
1050
  }
1051
+ // Emit it here so we can use it ea
1052
+ this._appEventService.answerCountReceived.next(questionAndAnswers.answers.length);
1014
1053
  this.handleAnswersReceived();
1015
1054
  return questionAndAnswers;
1016
1055
  }
@@ -1060,6 +1099,12 @@ class ConfiguratorConnectorService {
1060
1099
  navigateTo(choseValue, showLoader = false) {
1061
1100
  return this._configuratorService.navigateTo(choseValue, showLoader);
1062
1101
  }
1102
+ async navigateToBySelNode(instanceId, choseValue, showLoader = false) {
1103
+ return this._configuratorService.navigateToBySelNode(instanceId, choseValue, showLoader);
1104
+ }
1105
+ async nextCombNode(selection, showLoader = false) {
1106
+ return this._configuratorService.nextCombNode(selection, showLoader);
1107
+ }
1063
1108
  cancelAnswer(getAnswersAndQuestion = true) {
1064
1109
  return this._configuratorService.cancelAnswer();
1065
1110
  }
@@ -1219,8 +1264,13 @@ class ConfiguratorConnectorService {
1219
1264
  selectedOption.optionText = textAndImage.oText;
1220
1265
  selectedOption.optionText = textAndImage.oText;
1221
1266
  const image = textAndImage.oImage;
1222
- const imageData = await this._configuratorService.getImage(image.key, 4, true, TableName.InternalParam);
1223
- selectedOption.imageData = this._handleImageResponse(imageData);
1267
+ if (image.thumbnailBody) {
1268
+ selectedOption.imageData = ImageUtils.getDocBodyWithMimeTypeDefinition(image.fileName, image.thumbnailBody);
1269
+ }
1270
+ else {
1271
+ const imageData = await this._configuratorService.getImage(image.key, 4, true, TableName.InternalParam);
1272
+ selectedOption.imageData = this._handleImageResponse(imageData);
1273
+ }
1224
1274
  }
1225
1275
  }
1226
1276
  }
@@ -1256,6 +1306,66 @@ class ConfiguratorConnectorService {
1256
1306
  (selection.nodeType === NodeType.Answer && (((selection.answerPublicationCode & this._getPublicationCode()) > 0) ||
1257
1307
  isNill(selection.answerPublicationCode)))));
1258
1308
  }
1309
+ async repeatOption(optCycle, id, after = true) {
1310
+ const params = {};
1311
+ if (after !== undefined) {
1312
+ params.copyAfter = after ? 'T' : 'F';
1313
+ }
1314
+ params.optCycle = optCycle;
1315
+ const response = await this._configuratorService.repeatOption(params);
1316
+ if (response && response.validationResult && response.validationResult.success) {
1317
+ await this.getQuestionAndAnswersAsync(true);
1318
+ return true;
1319
+ }
1320
+ return false;
1321
+ }
1322
+ filterRemoveSelectionsByDeleteExceptions(options) {
1323
+ return options.filter(option => this._checkForRemovedByException(this.selectionWithAnswers, option.node));
1324
+ }
1325
+ markSelectionForUserInput(selectionNode) {
1326
+ this.selectionWithAnswers.forEach(parent => {
1327
+ let found = false;
1328
+ // Normal configurations
1329
+ parent.selectorOptions.forEach(child => {
1330
+ if (child.selector.selNodeId === selectionNode) {
1331
+ this.activeSlideOutParentId = child.selector.selNodeId;
1332
+ parent.markForUserInput = true;
1333
+ found = true;
1334
+ }
1335
+ });
1336
+ // Repeated articles are more nested
1337
+ parent.repeatedOptions.forEach(child => {
1338
+ if (child.selectorOptions && child.selectorOptions.length > 0) {
1339
+ child.selectorOptions.forEach(value => {
1340
+ if (value.selector.selNodeId === selectionNode) {
1341
+ this.activeSlideOutParentId = value.selector.selNodeId;
1342
+ parent.markForUserInput = true;
1343
+ found = true;
1344
+ }
1345
+ });
1346
+ }
1347
+ });
1348
+ // When someone clicks on a non repeating item, we got the selNodeId of the child and not the parent,
1349
+ // we need to loop extra for this to be sure.
1350
+ if (!found) {
1351
+ parent.selectorOptions.forEach(child => {
1352
+ if (child.selectorOptions && child.selectorOptions.length > 0) {
1353
+ child.selectorOptions.forEach(nested => {
1354
+ if (nested.selectorOptions && nested.selectorOptions.length > 0) {
1355
+ nested.selectorOptions.forEach(option => {
1356
+ if (option.selector.selNodeId === selectionNode) {
1357
+ this.activeSlideOutParentId = child.selector.selNodeId;
1358
+ parent.markForUserInput = true;
1359
+ }
1360
+ });
1361
+ }
1362
+ });
1363
+ }
1364
+ });
1365
+ }
1366
+ });
1367
+ this._appEventService.checkForMarkedInputs.next(true);
1368
+ }
1259
1369
  _prepareSelections(selections) {
1260
1370
  this._selections = selections.slice(0);
1261
1371
  this._prepareSelectionsToDisplay();
@@ -1398,6 +1508,17 @@ class ConfiguratorConnectorService {
1398
1508
  * Show full config stuff
1399
1509
  *
1400
1510
  * */
1511
+ async _getSelectorStructure(showLoader = true) {
1512
+ const response = await this._configuratorService.getSelectorStructure(showLoader);
1513
+ if (response && response.validationResult && response.validationResult.success) {
1514
+ if (response.resultObjects) {
1515
+ return this._boFactory.makeBOArrayFromRawBackendDataArray(SelectorStructure, response.resultObjects);
1516
+ }
1517
+ else {
1518
+ return this._boFactory.makeBOArrayFromRawBackendDataArray(SelectorStructure, response.resultObject['structures']);
1519
+ }
1520
+ }
1521
+ }
1401
1522
  async _createSelectorFullConfiguration(selections) {
1402
1523
  this._selections = selections.slice(0);
1403
1524
  this._prepareSelectionsToDisplay();
@@ -1409,42 +1530,97 @@ class ConfiguratorConnectorService {
1409
1530
  });
1410
1531
  }
1411
1532
  this._totalPrice = Math.round((totalPrice + Number.EPSILON) * 100) / 100;
1412
- let selectorStructureList = [];
1413
- const selectorStructure = await this._configuratorService.getSelectorStructure();
1414
- if (selectorStructure.validationResult.success) {
1415
- if (selectorStructure.resultObjects) {
1416
- selectorStructureList = selectorStructure.resultObjects;
1417
- }
1418
- else {
1419
- selectorStructureList = selectorStructure.resultObject['structures'];
1420
- }
1421
- }
1422
- const filteredList = selectorStructureList.filter(s => this._isStructurePublished(s));
1423
- struct = this._buildStructureThree(filteredList);
1533
+ // TODO exceptions needs to be checked/ reimplementent
1534
+ // if (this._exceptionQuestionChanged) {
1535
+ // struct = this._linkExceptionToOption(this._exceptionQuestionChanged, struct);
1536
+ // }
1537
+ const selectorStructure = await this._getSelectorStructure();
1538
+ struct = this._buildStructureThree(selectorStructure);
1539
+ this._markLastNodeWithChildren(struct);
1540
+ struct = this._buildRepeatedOptions(struct);
1541
+ struct = this._filterResultOnPublicationCodes(struct);
1424
1542
  this._markLastNodeWithChildren(struct);
1425
- if (this._exceptionQuestionChanged) {
1426
- struct = this._linkExceptionToOption(this._exceptionQuestionChanged, struct);
1543
+ if (this._exceptionIds.length > 0) {
1544
+ struct = this._markExceptions(this._exceptionIds, struct);
1545
+ this._exceptionIds = [];
1427
1546
  }
1428
1547
  this.selectionWithAnswers = struct;
1429
1548
  }
1549
+ _buildRepeatedOptions(items) {
1550
+ const seenByOptId = {};
1551
+ const toRemove = new Set();
1552
+ items.forEach(node => {
1553
+ const optId = node.selector.artNodeOptId;
1554
+ if (optId == null) {
1555
+ return;
1556
+ }
1557
+ if (seenByOptId[optId] == null) {
1558
+ seenByOptId[optId] = node;
1559
+ }
1560
+ else {
1561
+ seenByOptId[optId].repeatedOptions.push(node);
1562
+ toRemove.add(node);
1563
+ }
1564
+ });
1565
+ toRemove.forEach(node => {
1566
+ const index = items.indexOf(node);
1567
+ if (index !== -1) {
1568
+ items.splice(index, 1);
1569
+ }
1570
+ });
1571
+ return items;
1572
+ }
1430
1573
  _buildStructureThree(items) {
1431
1574
  const map = {};
1432
- const structuredList = [];
1575
+ const roots = [];
1433
1576
  items.forEach(item => {
1434
- const option = new SelectorWithOptions();
1435
- option.selector = item;
1436
- option.selectorOptions = [];
1437
- map[item.id] = option;
1577
+ const node = new SelectorWithOptions();
1578
+ node.selector = item;
1579
+ node.selectorOptions = [];
1580
+ node.repeatedOptions = [];
1581
+ map[item.id] = node;
1438
1582
  });
1583
+ const isInsideArticle = (item) => {
1584
+ let current = item;
1585
+ while (current.parentId) {
1586
+ const parent = map[current.parentId]?.selector;
1587
+ if (!parent) {
1588
+ break;
1589
+ }
1590
+ if (parent.nodeType === NodeType.Article) {
1591
+ return true;
1592
+ }
1593
+ current = parent;
1594
+ }
1595
+ return false;
1596
+ };
1597
+ const markAncestorsAsArticles = (item) => {
1598
+ let current = item;
1599
+ while (current.parentId) {
1600
+ const parentNode = map[current.parentId];
1601
+ if (!parentNode) {
1602
+ break;
1603
+ }
1604
+ parentNode.selectorOptionsAreArticles = true;
1605
+ current = parentNode.selector;
1606
+ }
1607
+ };
1439
1608
  items.forEach(item => {
1440
- if (map[item.parentId]) {
1441
- map[item.parentId].selectorOptions.push(map[item.id]);
1609
+ const parent = map[item.parentId];
1610
+ if (!parent) {
1611
+ roots.push(map[item.id]);
1612
+ return;
1613
+ }
1614
+ if (parent.selector.nodeType === NodeType.Article || (parent.selector.nodeType === NodeType.Question && parent.selector.showGrouped === false) || isInsideArticle(item)) {
1615
+ parent.selectorOptions.push(map[item.id]);
1616
+ parent.selectorOptionsAreArticles = true;
1617
+ markAncestorsAsArticles(item);
1442
1618
  }
1443
1619
  else {
1444
- structuredList.push(map[item.id]);
1620
+ parent.selectorOptions.push(map[item.id]);
1445
1621
  }
1446
1622
  });
1447
- return structuredList;
1623
+ return roots;
1448
1624
  }
1449
1625
  _markLastNodeWithChildren(nodes) {
1450
1626
  nodes.forEach(node => {
@@ -1577,13 +1753,70 @@ class ConfiguratorConnectorService {
1577
1753
  }
1578
1754
  }
1579
1755
  _linkExceptionToOption(exceptionQuestion, struct) {
1756
+ let exceptionCount = 0;
1580
1757
  struct.forEach(struct => {
1581
1758
  if (struct.selector.optId === exceptionQuestion.optionId) {
1582
1759
  struct.markForExceptionNotification = true;
1760
+ exceptionCount++;
1761
+ }
1762
+ });
1763
+ if (exceptionCount === 1) {
1764
+ this._exceptionQuestionChanged = undefined; // reset
1765
+ return struct;
1766
+ }
1767
+ }
1768
+ _filterResultOnPublicationCodes(list) {
1769
+ return list.filter(part => {
1770
+ if (!this._isStructurePublished(part.selector)) {
1771
+ return false;
1772
+ }
1773
+ if (part.selectorOptions && part.selectorOptions.length) {
1774
+ part.selectorOptions = this._filterResultOnPublicationCodes(part.selectorOptions);
1583
1775
  }
1776
+ if (part.repeatedOptions && part.repeatedOptions.length) {
1777
+ part.repeatedOptions = this._filterResultOnPublicationCodes(part.repeatedOptions);
1778
+ }
1779
+ return true;
1584
1780
  });
1585
- this._exceptionQuestionChanged = undefined; // reset
1586
- return struct;
1781
+ }
1782
+ _checkForRemovedByException(list, node) {
1783
+ for (const part of list) {
1784
+ if (part.selector.selNodeId === node) {
1785
+ return true;
1786
+ }
1787
+ if (part.selectorOptions && part.selectorOptions.length) {
1788
+ if (part.selectorOptions.length === 1) {
1789
+ if (part.selectorOptions[0].selector.opvId === 0 && part.selectorOptions[0].selector.selNodeId === node) {
1790
+ return false;
1791
+ }
1792
+ }
1793
+ const found = this._checkForRemovedByException(part.selectorOptions, node);
1794
+ if (found !== false) {
1795
+ return found;
1796
+ }
1797
+ }
1798
+ }
1799
+ return false;
1800
+ }
1801
+ _markExceptions(exceptionIds, structure) {
1802
+ if (structure && structure.length > 0) {
1803
+ for (const item of structure) {
1804
+ if (item.selectorOptions && item.selectorOptions.length > 0) {
1805
+ this._markExceptions(exceptionIds, item.selectorOptions);
1806
+ }
1807
+ if (item.repeatedOptions && item.repeatedOptions.length > 0) {
1808
+ this._markExceptions(exceptionIds, item.repeatedOptions);
1809
+ }
1810
+ if (item.selector && exceptionIds.includes(item.selector.selNodeId)) {
1811
+ item.markForExceptionNotification = true;
1812
+ }
1813
+ if (item.selectorOptions?.some(c => c.markForExceptionNotification) ||
1814
+ item.repeatedOptions?.some(c => c.markForExceptionNotification)) {
1815
+ item.markForExceptionNotification = true;
1816
+ }
1817
+ }
1818
+ }
1819
+ return structure;
1587
1820
  }
1588
1821
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfiguratorConnectorService, deps: [{ token: ConfiguratorEventService }, { token: ConfiguratorSettingsService }, { token: LoaderService }, { token: i6.UtilitiesConnectorService }], target: i0.ɵɵFactoryTarget.Injectable });
1589
1822
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfiguratorConnectorService, providedIn: 'root' });
@@ -1793,7 +2026,7 @@ class ThreedselectorService {
1793
2026
  c.children = connectors.concat(meshes);
1794
2027
  });
1795
2028
  return resolve(object);
1796
- });
2029
+ }).catch((e) => reject(e));
1797
2030
  }
1798
2031
  catch (e) {
1799
2032
  reject(e);
@@ -1808,6 +2041,10 @@ class ThreedselectorService {
1808
2041
  resolve(obj);
1809
2042
  }).catch(async (e) => {
1810
2043
  DebugUtils.log('downloadAssetsAndReturn: ' + e);
2044
+ // GLB failed, fall back to the legacy JSON model format. The XMLHttpRequest
2045
+ // handlers above settle the promise: onloadend parses the response, onerror rejects.
2046
+ oReq.open('GET', FileUtils.FixUrl(assetPath.replace('.glb.gz', '').replace('.glb', '')), true);
2047
+ oReq.send(null);
1811
2048
  });
1812
2049
  });
1813
2050
  }
@@ -2278,7 +2515,7 @@ class BuildFurnitureBaseService {
2278
2515
  this.prepareTheSelections(result.instanceId);
2279
2516
  }
2280
2517
  // TODO check if we need this function for Habufa
2281
- // protected handleIntegrationConnections(id: string, object: Item): void {
2518
+ // protected handleIntegrationConnections(selNodeId: string, object: Item): void {
2282
2519
  // const parts: FurniturePartIntegration[] = [];
2283
2520
  // const childParts: Object3D[] = object.configurable ? object.children : [object];
2284
2521
  // const len: number = childParts.length;
@@ -2338,12 +2575,12 @@ class BuildFurnitureBaseService {
2338
2575
  // connection.ConnectedParts = connectors;
2339
2576
  // parts.push(connection);
2340
2577
  // }
2341
- // this.upsertFurniture(id, {Parts: parts}, object);
2578
+ // this.upsertFurniture(selNodeId, {Parts: parts}, object);
2342
2579
  // }
2343
2580
  //
2344
- // protected upsertFurniture(id: string, object: any, item: Item): void {
2581
+ // protected upsertFurniture(selNodeId: string, object: any, item: Item): void {
2345
2582
  // if (this._integrationEnabled && !item.metadata.obsolete) {
2346
- // const idx: number = this._furnitureConfigurations.findIndex(f => f.Id === id);
2583
+ // const idx: number = this._furnitureConfigurations.findIndex(f => f.Id === selNodeId);
2347
2584
  // let furniture: FurnitureIntegration;
2348
2585
  // if (idx < 0) {
2349
2586
  // // empty entry for mrp code, re-use that one
@@ -2353,7 +2590,7 @@ class BuildFurnitureBaseService {
2353
2590
  // furniture = new FurnitureIntegration();
2354
2591
  // this._furnitureConfigurations.push(furniture);
2355
2592
  // }
2356
- // furniture.Id = id;
2593
+ // furniture.Id = selNodeId;
2357
2594
  // } else {
2358
2595
  // furniture = this._furnitureConfigurations[idx];
2359
2596
  // }
@@ -3288,7 +3525,7 @@ class LoadFurnitureBaseService {
3288
3525
  return obj;
3289
3526
  }, err => {
3290
3527
  DebugUtils.log('Error: ' + err);
3291
- return err;
3528
+ return Promise.reject(new ConfiguratorErrorMessage('THREED_MODEL_NOT_FOUND', String(err)));
3292
3529
  });
3293
3530
  // }
3294
3531
  }
@@ -3329,7 +3566,7 @@ class LoadFurnitureBaseService {
3329
3566
  return Promise.reject(configurationResultObject);
3330
3567
  }
3331
3568
  });
3332
- if (obj === null) {
3569
+ if (!obj) { // no model url, or the download failed and onlyThreeD is off
3333
3570
  if (this.settingsService.settings.options.onlyThreeD && this.needs3DModel(configurationResultObject.placement)) {
3334
3571
  configurationResultObject.resultType = ResultType.No3DModel;
3335
3572
  return Promise.reject(configurationResultObject);
@@ -3788,74 +4025,49 @@ Controls = function (camera, domElement) {
3788
4025
  const position = camera.position.clone();
3789
4026
  const target = this.target.clone();
3790
4027
  const group = new Group$1();
3791
- const targetTween = new Tween(target)
3792
- .to(endTarget, duration)
3793
- .easing(Easing.Quadratic.InOut)
3794
- .onUpdate(() => {
3795
- this.target = target;
3796
- this.update();
3797
- this.dispatchEvent(changeEvent);
3798
- })
3799
- .onComplete(() => {
3800
- this.update();
3801
- this.dispatchEvent(changeEvent);
3802
- group.remove(targetTween);
3803
- dispatchRemoveGroup(group);
3804
- })
3805
- .start();
3806
- const positionTween = new Tween(position)
3807
- .to(endPosition, duration)
3808
- .easing(Easing.Quadratic.In)
3809
- .onUpdate(() => {
3810
- this.camera.position.copy(position);
3811
- this.update();
3812
- this.dispatchEvent(changeEvent);
3813
- })
3814
- .onComplete(() => {
3815
- this.update();
3816
- this.dispatchEvent(changeEvent);
3817
- group.remove(positionTween);
3818
- dispatchRemoveGroup(group);
3819
- })
3820
- .start();
3821
- group.add(targetTween);
3822
- group.add(positionTween);
3823
- dispatchAddGroup(group);
3824
- // const targetTween = new TWEEN.Tween<any>(target)
3825
- // .to(endTarget, duration)
3826
- // .easing(TWEEN.Easing.Quadratic.InOut)
3827
- // .onUpdate(() => {
3828
- // this.target = target;
3829
- // this.update();
3830
- // this.dispatchEvent(changeEvent);
3831
- // });
3832
- // const positionTween = new TWEEN.Tween<any>(position)
3833
- // .to(endPosition, duration)
3834
- // .easing(TWEEN.Easing.Quadratic.In)
3835
- // .onUpdate(() => {
3836
- // this.camera.position.copy(position);
3837
- // this.update();
3838
- // this.dispatchEvent(changeEvent);
3839
- // });
3840
- // const targetPromise = new Promise<TWEEN.Tween<any>>(resolve => {
3841
- // targetTween
3842
- // .onComplete(() => {
3843
- // this.update();
3844
- // this.dispatchEvent(changeEvent);
3845
- // resolve(targetTween);
3846
- // })
3847
- // .start();
3848
- // });
3849
- // const positionPromise = new Promise<TWEEN.Tween<any>>(resolve => {
3850
- // positionTween
3851
- // .onComplete(() => {
3852
- // this.update();
3853
- // this.dispatchEvent(changeEvent);
3854
- // resolve(positionTween);
3855
- // })
3856
- // .start();
3857
- // });
3858
- // return Promise.all([targetPromise, positionPromise]);
4028
+ return new Promise((resolve) => {
4029
+ let completedCount = 0;
4030
+ const onTweenComplete = () => {
4031
+ completedCount++;
4032
+ if (completedCount === 2)
4033
+ resolve();
4034
+ };
4035
+ const targetTween = new Tween(target)
4036
+ .to(endTarget, duration)
4037
+ .easing(Easing.Quadratic.InOut)
4038
+ .onUpdate(() => {
4039
+ this.target = target;
4040
+ this.update();
4041
+ this.dispatchEvent(changeEvent);
4042
+ })
4043
+ .onComplete(() => {
4044
+ this.update();
4045
+ this.dispatchEvent(changeEvent);
4046
+ group.remove(targetTween);
4047
+ dispatchRemoveGroup(group);
4048
+ onTweenComplete();
4049
+ })
4050
+ .start();
4051
+ const positionTween = new Tween(position)
4052
+ .to(endPosition, duration)
4053
+ .easing(Easing.Quadratic.In)
4054
+ .onUpdate(() => {
4055
+ this.camera.position.copy(position);
4056
+ this.update();
4057
+ this.dispatchEvent(changeEvent);
4058
+ })
4059
+ .onComplete(() => {
4060
+ this.update();
4061
+ this.dispatchEvent(changeEvent);
4062
+ group.remove(positionTween);
4063
+ dispatchRemoveGroup(group);
4064
+ onTweenComplete();
4065
+ })
4066
+ .start();
4067
+ group.add(targetTween);
4068
+ group.add(positionTween);
4069
+ dispatchAddGroup(group);
4070
+ });
3859
4071
  };
3860
4072
  this.fixedCameraMovement = async function (endPosition, endTarget, endDuration) {
3861
4073
  if (!isFinite(endPosition.x) ||
@@ -6258,6 +6470,8 @@ class ConfiguratorSceneService {
6258
6470
  webGL2Available;
6259
6471
  domElement;
6260
6472
  floorTexturesLoaded = new BehaviorSubject(undefined);
6473
+ getFloorSizeFn;
6474
+ getCenterFloorFn;
6261
6475
  _needsRender;
6262
6476
  _arMode = false;
6263
6477
  _subs = [];
@@ -6317,6 +6531,8 @@ class ConfiguratorSceneService {
6317
6531
  this._handleAddTweenGroup(group);
6318
6532
  }), this._cameraService.removeTweenGroup.subscribe((group) => {
6319
6533
  this._handleRemoveTweenGroup(group);
6534
+ }), this._lightsService.renderPropsChanged.subscribe(() => {
6535
+ this.handlePropsChanged();
6320
6536
  }),
6321
6537
  // this._messageBusService.subscribe(MessageType.TakeScreenshot, async () => {
6322
6538
  // if (this._viewModeService.is3dViewActive() || this._viewModeService.isTopViewActive()) {
@@ -6345,7 +6561,6 @@ class ConfiguratorSceneService {
6345
6561
  }
6346
6562
  MaterialUtils.SetAssetPath(this._assetPath);
6347
6563
  }
6348
- this._lightsService.assetPath = this._assetPath;
6349
6564
  this._initLightService();
6350
6565
  if (this._configuratorSettingsService.settings.assetIndex) {
6351
6566
  this._indexJsonFile = this._configuratorSettingsService.settings.assetIndex;
@@ -6397,7 +6612,10 @@ class ConfiguratorSceneService {
6397
6612
  positionInSceneToScreen(pos) {
6398
6613
  return Scene3DUtil.Convert3DPointToScreenPoint(pos, this._cameraService.camera, this.domElement.clientWidth, this.domElement.clientHeight);
6399
6614
  }
6400
- rendererPropsChange() {
6615
+ handlePropsChanged() {
6616
+ if (!this.scene) {
6617
+ return;
6618
+ }
6401
6619
  this.scene.traverse((node) => {
6402
6620
  if (!node.isMesh) {
6403
6621
  return;
@@ -6440,7 +6658,10 @@ class ConfiguratorSceneService {
6440
6658
  this._postProcessingService.init(this.renderer, this.scene, this._cameraService.camera, this.domElement.clientWidth, this.domElement.clientHeight);
6441
6659
  }
6442
6660
  _initLightService() {
6661
+ this._lightsService.assetPath = this._assetPath;
6443
6662
  this._lightsService.init(this.scene, this.renderer);
6663
+ this._lightsService.getSizeFn = this.getFloorSizeFn;
6664
+ this._lightsService.getCenterFn = this.getCenterFloorFn;
6444
6665
  }
6445
6666
  _initPathTracer() {
6446
6667
  if (this._configuratorSettingsService.settings.options.pathTracer) {
@@ -6819,6 +7040,13 @@ class RenderApi {
6819
7040
  options.transparency = this._useTransparency(sceneSettings);
6820
7041
  options.objectOptions = objectOptions;
6821
7042
  options.objectRenderTransform = blenderVector;
7043
+ if (optionalRenderParameters && optionalRenderParameters.objectWidth && optionalRenderParameters.objectHeight) {
7044
+ options.width = optionalRenderParameters.objectWidth;
7045
+ options.height = optionalRenderParameters.objectHeight;
7046
+ }
7047
+ if (optionalRenderParameters && optionalRenderParameters.renderType) {
7048
+ options.renderType = optionalRenderParameters.renderType;
7049
+ }
6822
7050
  renderBaseObject.assetUrl = buildResult.assetUrl;
6823
7051
  renderBaseObject.cdnUrl = buildResult.cdnUrl;
6824
7052
  renderBaseObject.options = options;
@@ -7298,6 +7526,7 @@ var IconEnum;
7298
7526
  IconEnum["ArrowTurnRightRegular"] = "arrow_turn_right_regular";
7299
7527
  IconEnum["ArCircle"] = "ar_circle";
7300
7528
  IconEnum["BarsLightFull"] = "bars_light_full";
7529
+ IconEnum["BellSharpSolid"] = "bell_sharp_solid";
7301
7530
  IconEnum["Brush"] = "brush";
7302
7531
  IconEnum["CameraSolid"] = "camera_solid";
7303
7532
  IconEnum["CameraTopdown"] = "camera_topdown";
@@ -7306,6 +7535,7 @@ var IconEnum;
7306
7535
  IconEnum["Check"] = "check";
7307
7536
  IconEnum["CheckRegular"] = "check_regular";
7308
7537
  IconEnum["CheckSolid"] = "check_solid";
7538
+ IconEnum["ChevronLeftRegular"] = "chevron_left_regular";
7309
7539
  IconEnum["CircleCheck"] = "circle_check";
7310
7540
  IconEnum["CircleCheckRegular"] = "circle_check_regular";
7311
7541
  IconEnum["CircleInfo"] = "circle_info";
@@ -7415,6 +7645,7 @@ const IconSvg = {
7415
7645
  "arrow_turn_right_regular": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M377 369c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l87-87L88 248c-22.1 0-40 17.9-40 40l0 168c0 13.3-10.7 24-24 24s-24-10.7-24-24L0 288c0-48.6 39.4-88 88-88l342.1 0-87-87c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0L505 207c9.4 9.4 9.4 24.6 0 33.9L377 369z\"/></svg>",
7416
7646
  "ar_circle": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 50 50\"><path d=\"M25,11A14,14,0,1,1,11,25,14,14,0,0,1,25,11m0-1A15,15,0,1,0,40,25,15,15,0,0,0,25,10Z\" fill=\"#484f60\"/><path d=\"M23.23,30.1l-.85-2.2H18.53l-.85,2.2H15.5l4-10.2h2l4,10.2Zm-2.77-7.16-1.15,3h2.3Z\" fill=\"#484f60\"/><path d=\"M33.92,23.29c0,1.63-.58,2.69-1.74,3.16L34.5,30.1H32l-2-3.25H28.53V30.1H26.48V19.9H30a4.65,4.65,0,0,1,3,.8A3.29,3.29,0,0,1,33.92,23.29ZM31.45,24.5a1.64,1.64,0,0,0,.39-1.21,1.38,1.38,0,0,0-.4-1.13,2.35,2.35,0,0,0-1.38-.3H28.53v3H30A2,2,0,0,0,31.45,24.5Z\" fill=\"#484f60\"/></svg>",
7417
7647
  "bars_light_full": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><path d=\"M96 144C96 135.2 103.2 128 112 128L528 128C536.8 128 544 135.2 544 144C544 152.8 536.8 160 528 160L112 160C103.2 160 96 152.8 96 144zM96 320C96 311.2 103.2 304 112 304L528 304C536.8 304 544 311.2 544 320C544 328.8 536.8 336 528 336L112 336C103.2 336 96 328.8 96 320zM544 496C544 504.8 536.8 512 528 512L112 512C103.2 512 96 504.8 96 496C96 487.2 103.2 480 112 480L528 480C536.8 480 544 487.2 544 496z\"/></svg>",
7648
+ "bell_sharp_solid": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><path d=\"M352 64L288 64L288 99.2C215 114 160 178.6 160 256L160 352L80 480L560 480L480 352L480 256C480 178.6 425 114 352 99.2L352 64zM258 528C265.1 555.6 290.2 576 320 576C349.8 576 374.9 555.6 382 528L258 528z\"/></svg>",
7418
7649
  "brush": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 50 50\"><path d=\"M28.16,26a9.71,9.71,0,0,1-4-3.66A.88.88,0,0,0,22.92,22c-1.08.48-2.19.92-3.27,1.43-3.71,1.74-6,4.5-6.23,8.75-.17,2.75-.89,5.32-3.42,7.25,1.18,0,2.12,0,3.05,0,.73,0,1.46-.07,2.18-.12a10.82,10.82,0,0,0,4.86-3.38c1.31-1.61,3.14-3.58,3.95-5.49l-.08.38a22.78,22.78,0,0,1-3.09,5.74A11.79,11.79,0,0,1,18.13,39a22.35,22.35,0,0,0,4.29-1A8.2,8.2,0,0,0,28.06,32c.38-1.62.44-3.31.66-5A1,1,0,0,0,28.16,26Z\" fill=\"#484f60\"/><path d=\"M26.23,20.43l6.57-9.32a1.23,1.23,0,0,1,1.87-.18l4.94,4.7a1.24,1.24,0,0,1-.11,1.9l-9.15,6.78a1.25,1.25,0,0,1-1.58-.08L26.4,22.06A1.23,1.23,0,0,1,26.23,20.43Z\" fill=\"#484f60\"/></svg>",
7419
7650
  "camera_solid": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M149.1 64.8L138.7 96 64 96C28.7 96 0 124.7 0 160L0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-256c0-35.3-28.7-64-64-64l-74.7 0L362.9 64.8C356.4 45.2 338.1 32 317.4 32L194.6 32c-20.7 0-39 13.2-45.5 32.8zM256 192a96 96 0 1 1 0 192 96 96 0 1 1 0-192z\"/></svg>",
7420
7651
  "camera_topdown": "<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 600 600\" style=\"enable-background:new 0 0 600 600;\" ><g><path d=\"M198.4,473.9c-12.3,0-23.9-6.8-29.4-17.4c-2.4-4.6-3.7-9.8-3.7-15c0-6.7,2-13.1,5.9-18.6l57.5-82.1c3.7-5.2,9.7-8.4,16.1-8.4c4,0,7.9,1.2,11.2,3.5c8.8,6.2,11,18.4,4.8,27.3l-49.9,71.4h178.2l-50-71.4c-3.2-4.7-4.3-10.5-3-16c1.1-5,4-9.1,8.1-11.5c3.3-2.2,7.1-3.4,11-3.4c6.4,0,12.4,3.1,16.1,8.4l57.6,82.1c6.9,9.9,7.8,22.7,2.1,33.6c-5.6,10.8-16.7,17.4-28.7,17.4H198.4z M219.9,320.5c-32,0-58-26-58-58V58c0-32,26-58,58-58h160.2c32,0,58,26,58,58v204.6c0,32-26,58-58,58H219.9z M219.9,39.3c-10.3,0-18.7,8.4-18.7,18.7v204.6c0,10.3,8.4,18.7,18.7,18.7h160.2c10.3,0,18.7-8.4,18.7-18.7V58c0-10.3-8.4-18.7-18.7-18.7H219.9z\"/><path d=\"M300,600c-4,0-7.2-3.2-7.2-7.2v-85.3c0-4,3.2-7.2,7.2-7.2s7.2,3.2,7.2,7.2v85.3C307.2,596.8,304,600,300,600z\"/><path d=\"M179.7,591.6c-1.5,0-2.9-0.5-4.1-1.3c-1.6-1.1-2.6-2.8-3-4.6c-0.3-1.9,0.1-3.8,1.2-5.4l50.6-77c1.3-1.9,3.5-3,5.9-3c1.5,0,2.9,0.5,4.1,1.3c1.6,1.1,2.6,2.8,3,4.6c0.3,1.9-0.1,3.8-1.2,5.4l-50.6,77C184.2,590.5,182,591.6,179.7,591.6z\"/><path d=\"M420.3,591.6c-2.3,0-4.5-1.1-5.9-3l-50.6-77c-2.3-3.3-1.5-7.7,1.8-10c1.2-0.9,2.6-1.3,4.1-1.3c2.3,0,4.5,1.1,5.9,3l50.5,76.9l0,0.1c1.1,1.6,1.5,3.5,1.2,5.4c-0.3,1.9-1.4,3.5-3,4.6C423.2,591.2,421.8,591.6,420.3,591.6z\"/><path d=\"M375.9,65v38.7c0,1.5-1.2,2.8-2.8,2.8h-19.9c-1.5,0-2.8-1.2-2.8-2.8V65c0-1.5,1.2-2.8,2.8-2.8h19.9C374.6,62.2,375.9,63.5,375.9,65z\"/></g></svg>",
@@ -7423,6 +7654,7 @@ const IconSvg = {
7423
7654
  "check": "<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 50 50\" enable-background=\"new 0 0 50 50\" ><polygon fill=\"#29363E\" points=\"15,22.4 19.7,29.5 31.2,10 38.9,10 19.7,40 11.1,27.4 \"/></svg>",
7424
7655
  "check_regular": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><path d=\"M534 132.5C544.8 140.2 547.2 155.2 539.5 166L275.5 534C271.4 539.7 265 543.4 258 543.9C251 544.4 244 542 239 537L103 401C93.6 391.6 93.6 376.4 103 367.1C112.4 357.8 127.6 357.7 136.9 367.1L253 483L500.5 138C508.2 127.2 523.2 124.8 534 132.5z\"/></svg>",
7425
7656
  "check_solid": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><path d=\"M530.8 134.1C545.1 144.5 548.3 164.5 537.9 178.8L281.9 530.8C276.4 538.4 267.9 543.1 258.5 543.9C249.1 544.7 240 541.2 233.4 534.6L105.4 406.6C92.9 394.1 92.9 373.8 105.4 361.3C117.9 348.8 138.2 348.8 150.7 361.3L252.2 462.8L486.2 141.1C496.6 126.8 516.6 123.6 530.9 134z\"/></svg>",
7657
+ "chevron_left_regular": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><path d=\"M167.5 303C158.1 312.4 158.1 327.6 167.5 336.9L367.5 536.9C376.9 546.3 392.1 546.3 401.4 536.9C410.7 527.5 410.8 512.3 401.4 503L218.4 320L401.4 137C410.8 127.6 410.8 112.4 401.4 103.1C392 93.8 376.8 93.7 367.5 103.1L167.5 303z\"/></svg>",
7426
7658
  "circle_check": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M256 32a224 224 0 1 1 0 448 224 224 0 1 1 0-448zm0 480A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM363.3 203.3c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0L224 297.4l-52.7-52.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6l64 64c6.2 6.2 16.4 6.2 22.6 0l128-128z\"/></svg>",
7427
7659
  "circle_check_regular": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-111 111-47-47c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l64 64c9.4 9.4 24.6 9.4 33.9 0L369 209z\"/></svg>",
7428
7660
  "circle_info": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M256 32a224 224 0 1 1 0 448 224 224 0 1 1 0-448zm0 480A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM208 352c-8.8 0-16 7.2-16 16s7.2 16 16 16l96 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0 0-112c0-8.8-7.2-16-16-16l-40 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l24 0 0 96-32 0zm48-168a24 24 0 1 0 0-48 24 24 0 1 0 0 48z\"/></svg>",
@@ -7483,7 +7715,7 @@ const IconSvg = {
7483
7715
  "magnifying_glass_plus": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M208 32a176 176 0 1 1 0 352 176 176 0 1 1 0-352zm0 384c51.7 0 99-18.8 135.3-50L484.7 507.3c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6L366 343.3c31.2-36.4 50-83.7 50-135.3C416 93.1 322.9 0 208 0S0 93.1 0 208S93.1 416 208 416zM192 304c0 8.8 7.2 16 16 16s16-7.2 16-16l0-80 80 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-80 0 0-80c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 80-80 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l80 0 0 80z\"/></svg>",
7484
7716
  "measurements": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 50 50\"><path d=\"M17.8,39.17,11,32.37l21.2-21.2L39,18Zm-4.4-6.8,4.4,4.4L36.6,18l-4.4-4.4Z\" fill=\"#484f60\"/><rect x=\"28.54\" y=\"14.92\" width=\"4.53\" height=\"1.7\" transform=\"translate(20.17 -17.16) rotate(45)\" fill=\"#484f60\"/><rect x=\"13.34\" y=\"30.12\" width=\"4.53\" height=\"1.7\" transform=\"translate(26.47 -1.96) rotate(45)\" fill=\"#484f60\"/><rect x=\"25.84\" y=\"17.85\" width=\"5.66\" height=\"1.7\" transform=\"translate(21.62 -14.79) rotate(45)\" fill=\"#484f60\"/><rect x=\"23.47\" y=\"19.98\" width=\"4.53\" height=\"1.7\" transform=\"translate(22.27 -12.09) rotate(45)\" fill=\"#484f60\"/><rect x=\"20.77\" y=\"22.92\" width=\"5.66\" height=\"1.7\" transform=\"translate(23.72 -9.73) rotate(45)\" fill=\"#484f60\"/><rect x=\"18.4\" y=\"25.05\" width=\"4.53\" height=\"1.7\" transform=\"translate(24.37 -7.03) rotate(45)\" fill=\"#484f60\"/><rect x=\"15.7\" y=\"27.98\" width=\"5.66\" height=\"1.7\" transform=\"translate(25.82 -4.66) rotate(45)\" fill=\"#484f60\"/></svg>",
7485
7717
  "measurements_inside": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 30 30\"><g ><path d=\"m24.64,0h-3.43c-.59,0-1.07.48-1.07,1.07s.48,1.07,1.07,1.07h3.43c1.77,0,3.21,1.44,3.21,3.21v19.29c0,1.77-1.44,3.21-3.21,3.21h-3.43c-.59,0-1.07.48-1.07,1.07s.48,1.07,1.07,1.07h3.43c2.96,0,5.36-2.4,5.36-5.36V5.36c0-2.95-2.4-5.36-5.36-5.36Z\" fill=\"#484f60\" stroke-width=\"0\"/><path d=\"m0,26.25c0-.41.27-.75.6-.75h10.8c.33,0,.6.34.6.75s-.27.75-.6.75H.6c-.33,0-.6-.34-.6-.75Zm1.98-9.53c.23-.3.62-.3.85,0l2.58,3.22v-9.88l-2.58,3.22c-.23.3-.62.3-.85,0-.24-.29-.24-.77,0-1.06l3.6-4.5c.23-.3.62-.3.85,0l3.6,4.5c.24.29.24.77,0,1.06-.23.3-.61.3-.85,0l-2.58-3.22v9.88l2.58-3.22c.23-.3.61-.3.85,0,.24.29.24.77,0,1.06l-3.6,4.5c-.23.29-.61.29-.85,0l-3.6-4.5c-.24-.29-.24-.77,0-1.06h0ZM11.4,3c.33,0,.6.34.6.75s-.27.75-.6.75H.6c-.33,0-.6-.34-.6-.75s.27-.75.6-.75h10.8Z\" fill=\"#484f60\" stroke-width=\"0\"/></g></svg>",
7486
- "move-phone-ar": "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"363px\" height=\"222px\" viewBox=\"-0.5 -0.5 363 222\" content=\"&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-02-28T15:27:40.868Z&quot; agent=&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36&quot; etag=&quot;_ioPnVdQo6hh2aJpDZbs&quot; version=&quot;16.6.4&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;KlZxfvW3MfvAEXvIozvx&quot; name=&quot;Page-1&quot;&gt;7VjLcpswFP0aL+PRAxAsY8dNu2ibmaTTZolBwZpg5BHyK19fESTeCdhjp80k3hiOpCvpnHPFhRGeLnfXwl8tvvOQxiMEwt0IX40QggAS9Zch+xzxXA1EgoW6UwncsidqRmp0zUKa1jpKzmPJVnUw4ElCA1nDfCH4tt7tgcf1WVd+RFvAbeDHbfQ3C+UiR11ESvwrZdHCzAwdL29Z+qaz3km68EO+rUB4NsJTwbnMr5a7KY0z8gwv+bgvL7QWCxM0kUMGkOAyouDO+bVL0cx9YrPNzeMFzqNs/HitN6wXK/eGAcHXSUizIHCEJ9sFk/R25QdZ61ZprrCFXMa6WXDpS8YTdXvhAQU8sDie8pgLhSQ8UaMmqRT8sWDTVkh7K3p3Gyok3VUgvbVrypdUir3qolsxAGM7H7Q3iDUmGtqW0iHomI6LqnDIM7CvLRMVk5SsqgtN7AEke/0k0yS8zNxaslQjtarAAfTRsGbuNnkVXmzQJsVggsZK1U09Jbpo0jPccKZWUmpDnEIJLQ4ioB4l5WsRUD2w6uJGLMsCvbGkLyIqW7EUwf6+0m2VdUgPW7YLelfnuKD8Oa8NVxf5mkprFdoc7zZzcn5Yu1kAN3WzbOdIu8H+WC/Y7WR6kn49K+p1HdDq0bPKblnKp+s5VcRN5n7wGD0r/XMtY5Z54Hm46nKZRM9xod0pf8eJforzm+AxahzgGBVQxTkEtp1DrLMd3tDtp9/w+xDTnc6rSSXFgthPUxa8lGWgk+YcaRBd5X6UPfOyXya6HohAPrOuo9wxgcSxCLBdF2Ebv4PktQGom8BRm7DbJ+qhiWx77bgOedtEHlAHZCm5Gp5ORd3rz00E0K2eSTOnnWaoKIgqEnsdWeY2uD9djsF+ZgY+srqTqc3oqwr9J7ng1i3bpH+o9RvOJ8MeX4dWS17nYs9b6aBP23QoAZtKFBk/2DlnsspbemPAm+0H9IYLD3SCyW5Y8xQ8zxuXnuW8xrA/jdGRk01FhxrjxE44lfT4m2uhXcDsu/l98CP5c3/tWRcDqox3V8k37NNRNv6zrz7mxbWouL0xPs5kCPWGOrp2V7flN9i8e/klG8/+Ag==&lt;/diagram&gt;&lt;/mxfile&gt;\"><defs/><g><rect x=\"72.5\" y=\"45.75\" width=\"216.5\" height=\"129.5\" rx=\"19.43\" ry=\"19.43\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" transform=\"rotate(-90,180.75,110.5)\" pointer-events=\"all\"/><path d=\"M 148.75 11 L 148.75 16 Q 148.75 21 158.75 21 L 202.68 21 Q 212.68 21 212.72 16 L 212.75 11\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"stroke\"/><path d=\"M 175.75 197 L 185.75 197\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"stroke\"/><path d=\"M 180.75 73.25 L 216.25 90.3 L 216.25 130.7 L 180.75 147.75 L 145.25 130.7 L 145.25 90.3 Z\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"all\"/><path d=\"M 145.25 90.3 L 180.75 107.34 L 216.25 90.3 M 180.75 107.34 L 180.75 147.75\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"all\"/><path d=\"M 274.51 121.75 L 274.49 97.75 L 328.34 97.7 L 328.33 85.2 L 359.5 109.67 L 328.37 134.2 L 328.36 121.7 Z\" fill=\"#000000\" stroke=\"none\" pointer-events=\"all\"/><path d=\"M 215.25 153.5 L 225.25 153.5 L 225.25 143.5\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"none\"/><path d=\"M 145.25 153.75 L 135.25 153.5 L 135.25 143.5\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"none\"/><path d=\"M 216.25 67.5 L 226.25 67.5 L 226.25 77.5\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"none\"/><path d=\"M 135.25 77.5 L 135.25 67.5 L 145.25 67.5\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"none\"/><path d=\"M 86.5 98.3 L 86.5 122.3 L 32.65 122.3 L 32.65 134.8 L 1.5 110.3 L 32.65 85.8 L 32.65 98.3 Z\" fill=\"#000000\" stroke=\"none\" pointer-events=\"none\"/></g></svg>",
7718
+ "move-phone-ar": "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"363px\" height=\"222px\" viewBox=\"-0.5 -0.5 363 222\" content=\"&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-02-28T15:27:40.868Z&quot; agent=&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36&quot; etag=&quot;_ioPnVdQo6hh2aJpDZbs&quot; version=&quot;16.6.4&quot; type=&quot;device&quot;&gt;&lt;diagram selNodeId=&quot;KlZxfvW3MfvAEXvIozvx&quot; name=&quot;Page-1&quot;&gt;7VjLcpswFP0aL+PRAxAsY8dNu2ibmaTTZolBwZpg5BHyK19fESTeCdhjp80k3hiOpCvpnHPFhRGeLnfXwl8tvvOQxiMEwt0IX40QggAS9Zch+xzxXA1EgoW6UwncsidqRmp0zUKa1jpKzmPJVnUw4ElCA1nDfCH4tt7tgcf1WVd+RFvAbeDHbfQ3C+UiR11ESvwrZdHCzAwdL29Z+qaz3km68EO+rUB4NsJTwbnMr5a7KY0z8gwv+bgvL7QWCxM0kUMGkOAyouDO+bVL0cx9YrPNzeMFzqNs/HitN6wXK/eGAcHXSUizIHCEJ9sFk/R25QdZ61ZprrCFXMa6WXDpS8YTdXvhAQU8sDie8pgLhSQ8UaMmqRT8sWDTVkh7K3p3Gyok3VUgvbVrypdUir3qolsxAGM7H7Q3iDUmGtqW0iHomI6LqnDIM7CvLRMVk5SsqgtN7AEke/0k0yS8zNxaslQjtarAAfTRsGbuNnkVXmzQJsVggsZK1U09Jbpo0jPccKZWUmpDnEIJLQ4ioB4l5WsRUD2w6uJGLMsCvbGkLyIqW7EUwf6+0m2VdUgPW7YLelfnuKD8Oa8NVxf5mkprFdoc7zZzcn5Yu1kAN3WzbOdIu8H+WC/Y7WR6kn49K+p1HdDq0bPKblnKp+s5VcRN5n7wGD0r/XMtY5Z54Hm46nKZRM9xod0pf8eJforzm+AxahzgGBVQxTkEtp1DrLMd3tDtp9/w+xDTnc6rSSXFgthPUxa8lGWgk+YcaRBd5X6UPfOyXya6HohAPrOuo9wxgcSxCLBdF2Ebv4PktQGom8BRm7DbJ+qhiWx77bgOedtEHlAHZCm5Gp5ORd3rz00E0K2eSTOnnWaoKIgqEnsdWeY2uD9djsF+ZgY+srqTqc3oqwr9J7ng1i3bpH+o9RvOJ8MeX4dWS17nYs9b6aBP23QoAZtKFBk/2DlnsspbemPAm+0H9IYLD3SCyW5Y8xQ8zxuXnuW8xrA/jdGRk01FhxrjxE44lfT4m2uhXcDsu/l98CP5c3/tWRcDqox3V8k37NNRNv6zrz7mxbWouL0xPs5kCPWGOrp2V7flN9i8e/klG8/+Ag==&lt;/diagram&gt;&lt;/mxfile&gt;\"><defs/><g><rect x=\"72.5\" y=\"45.75\" width=\"216.5\" height=\"129.5\" rx=\"19.43\" ry=\"19.43\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" transform=\"rotate(-90,180.75,110.5)\" pointer-events=\"all\"/><path d=\"M 148.75 11 L 148.75 16 Q 148.75 21 158.75 21 L 202.68 21 Q 212.68 21 212.72 16 L 212.75 11\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"stroke\"/><path d=\"M 175.75 197 L 185.75 197\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"stroke\"/><path d=\"M 180.75 73.25 L 216.25 90.3 L 216.25 130.7 L 180.75 147.75 L 145.25 130.7 L 145.25 90.3 Z\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"all\"/><path d=\"M 145.25 90.3 L 180.75 107.34 L 216.25 90.3 M 180.75 107.34 L 180.75 147.75\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"all\"/><path d=\"M 274.51 121.75 L 274.49 97.75 L 328.34 97.7 L 328.33 85.2 L 359.5 109.67 L 328.37 134.2 L 328.36 121.7 Z\" fill=\"#000000\" stroke=\"none\" pointer-events=\"all\"/><path d=\"M 215.25 153.5 L 225.25 153.5 L 225.25 143.5\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"none\"/><path d=\"M 145.25 153.75 L 135.25 153.5 L 135.25 143.5\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"none\"/><path d=\"M 216.25 67.5 L 226.25 67.5 L 226.25 77.5\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"none\"/><path d=\"M 135.25 77.5 L 135.25 67.5 L 145.25 67.5\" fill=\"none\" stroke=\"rgb(0, 0, 0)\" stroke-width=\"5\" stroke-miterlimit=\"10\" pointer-events=\"none\"/><path d=\"M 86.5 98.3 L 86.5 122.3 L 32.65 122.3 L 32.65 134.8 L 1.5 110.3 L 32.65 85.8 L 32.65 98.3 Z\" fill=\"#000000\" stroke=\"none\" pointer-events=\"none\"/></g></svg>",
7487
7719
  "paint_roller_light": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M352 32c17.7 0 32 14.3 32 32l0 32c0 17.7-14.3 32-32 32L64 128c-17.7 0-32-14.3-32-32l0-32c0-17.7 14.3-32 32-32l288 0zm64 32c0-35.3-28.7-64-64-64L64 0C28.7 0 0 28.7 0 64L0 96c0 35.3 28.7 64 64 64l288 0c35.3 0 64-28.7 64-64l0-32zM240 352c8.8 0 16 7.2 16 16l0 96c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-96c0-8.8 7.2-16 16-16l32 0zm-32-32c-26.5 0-48 21.5-48 48l0 96c0 26.5 21.5 48 48 48l32 0c26.5 0 48-21.5 48-48l0-96c0-26.5-21.5-48-48-48l0-32c0-17.7 14.3-32 32-32l176 0c35.3 0 64-28.7 64-64l0-64c0-35.3-28.7-64-64-64l0 32c17.7 0 32 14.3 32 32l0 64c0 17.7-14.3 32-32 32l-176 0c-35.3 0-64 28.7-64 64l0 32z\"/></svg>",
7488
7720
  "pen-ruler": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M373.2 16.97C395.1-4.901 430.5-4.901 452.4 16.97L495 59.6C516.9 81.47 516.9 116.9 495 138.8L182.3 451.6C170.9 462.9 156.9 471.2 141.5 475.8L20.52 511.3C14.9 512.1 8.827 511.5 4.687 507.3C.5466 503.2-1.002 497.1 .6506 491.5L36.23 370.5C40.76 355.1 49.09 341.1 60.44 329.7L373.2 16.97zM429.8 39.6C420.4 30.22 405.2 30.22 395.8 39.6L341 94.4L417.6 170.1L472.4 116.2C481.8 106.8 481.8 91.6 472.4 82.23L429.8 39.6zM66.93 379.5L39.63 472.4L132.4 445.1C142.7 442 152.1 436.5 159.6 428.9L394.1 193.6L318.4 117L83.07 352.4C75.5 359.9 69.95 369.3 66.93 379.5V379.5zM173.3 27.31L244.1 98.18L221.5 120.8L189.7 88.97L155.3 123.3C149.1 129.6 138.9 129.6 132.7 123.3C126.4 117.1 126.4 106.9 132.7 100.7L167 66.34L150.6 49.94C138.1 37.44 117.9 37.44 105.4 49.94L49.94 105.4C37.44 117.9 37.44 138.1 49.94 150.6L120.8 221.5L98.18 244.1L27.31 173.3C2.32 148.3 2.32 107.7 27.31 82.75L82.75 27.31C107.7 2.32 148.3 2.32 173.3 27.31V27.31zM338.7 484.7L267.9 413.8L290.5 391.2L361.4 462.1C373.9 474.6 394.1 474.6 406.6 462.1L462.1 406.6C474.6 394.1 474.6 373.9 462.1 361.4L445.7 344.1L411.3 379.3C405.1 385.6 394.9 385.6 388.7 379.3C382.4 373.1 382.4 362.9 388.7 356.7L423 322.3L391.2 290.5L413.8 267.9L484.7 338.7C509.7 363.7 509.7 404.3 484.7 429.3L429.3 484.7C404.3 509.7 363.7 509.7 338.7 484.7V484.7z\"/></svg>",
7489
7721
  "pencil_light": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M395.8 39.6c9.4-9.4 24.6-9.4 33.9 0l42.6 42.6c9.4 9.4 9.4 24.6 0 33.9L417.6 171 341 94.4l54.8-54.8zM318.4 117L395 193.6 159.6 428.9c-7.6 7.6-16.9 13.1-27.2 16.1L39.6 472.4l27.3-92.8c3-10.3 8.6-19.6 16.1-27.2L318.4 117zM452.4 17c-21.9-21.9-57.3-21.9-79.2 0L60.4 329.7c-11.4 11.4-19.7 25.4-24.2 40.8L.7 491.5c-1.7 5.6-.1 11.7 4 15.8s10.2 5.7 15.8 4l121-35.6c15.4-4.5 29.4-12.9 40.8-24.2L495 138.8c21.9-21.9 21.9-57.3 0-79.2L452.4 17z\"/></svg>",
@@ -7593,7 +7825,7 @@ class ConfiguratorErrorDialogComponent {
7593
7825
  <button class="close-button" (click)="onClose()" [textContent]="'CLOSE' | localize:false | async"></button>
7594
7826
  </div>
7595
7827
  </div>
7596
- `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
7828
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
7597
7829
  }
7598
7830
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfiguratorErrorDialogComponent, decorators: [{
7599
7831
  type: Component,
@@ -7783,7 +8015,7 @@ class AnswersInfoDialogComponent {
7783
8015
  </div>
7784
8016
  </div>
7785
8017
  }
7786
- `, isInline: true, dependencies: [{ kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
8018
+ `, isInline: true, dependencies: [{ kind: "directive", type: i6$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
7787
8019
  }
7788
8020
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AnswersInfoDialogComponent, decorators: [{
7789
8021
  type: Component,
@@ -8064,7 +8296,7 @@ class AnswerCardComponent {
8064
8296
  }
8065
8297
 
8066
8298
  </co-card>
8067
- `, isInline: true, dependencies: [{ kind: "component", type: i4.CardComponent, selector: "co-card", inputs: ["imageData", "description", "price", "level", "isSelected", "isSmallModus", "hasMagnifierButton", "hasInfoButton"], outputs: ["contentClick", "infoButtonClick", "magnifierButtonClick"] }, { kind: "component", type: i4.InputTextComponent, selector: "co-input-text", inputs: ["useContent", "placeholder", "align", "type", "formatPipe", "min", "max", "pattern", "digitsOnly", "excludePlusMinus", "showClearButton", "keyDownWhiteList", "showPlaceholderOnFocus", "leftIcon", "rightIcon", "leftIconData", "rightIconData", "selectOnFocus", "emptyPlace", "firstDayOfWeek", "noStyle", "hideArrowButtons", "model"], outputs: ["leftIconClick", "leftIconMouseDown", "leftIconMouseUp", "rightIconClick", "rightIconMouseDown", "rightIconMouseUp", "clearIconClick", "isFocused"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: AnswersInfoDialogComponent, selector: "co-answer-info-dialog", inputs: ["answer", "structure", "fixedPosition"], outputs: ["nothingToShow"] }, { kind: "component", type: i4.ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
8299
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.CardComponent, selector: "co-card", inputs: ["imageData", "description", "price", "level", "isSelected", "isSmallModus", "hasMagnifierButton", "hasInfoButton"], outputs: ["contentClick", "infoButtonClick", "magnifierButtonClick"] }, { kind: "component", type: i4.InputTextComponent, selector: "co-input-text", inputs: ["useContent", "placeholder", "align", "type", "formatPipe", "min", "max", "pattern", "digitsOnly", "excludePlusMinus", "showClearButton", "keyDownWhiteList", "showPlaceholderOnFocus", "leftIcon", "rightIcon", "leftIconData", "rightIconData", "selectOnFocus", "emptyPlace", "firstDayOfWeek", "noStyle", "hideArrowButtons", "model"], outputs: ["leftIconClick", "leftIconMouseDown", "leftIconMouseUp", "rightIconClick", "rightIconMouseDown", "rightIconMouseUp", "clearIconClick", "isFocused"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: AnswersInfoDialogComponent, selector: "co-answer-info-dialog", inputs: ["answer", "structure", "fixedPosition"], outputs: ["nothingToShow"] }, { kind: "component", type: i4.ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
8068
8300
  }
8069
8301
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AnswerCardComponent, decorators: [{
8070
8302
  type: Component,
@@ -8790,19 +9022,6 @@ class AnswersSlideoutComponent {
8790
9022
  </div>
8791
9023
  }
8792
9024
  <ng-template #answerTemplate>
8793
- @if (searchExpanded) {
8794
- <div class="search-wrapper" [@showFilter]="searchExpanded">
8795
- <!-- TODO enable after Angular update -->
8796
- <!-- <co-input-text-chips-->
8797
- <!-- class="text-chips"-->
8798
- <!-- [value]="chipTexts"-->
8799
- <!-- [initFocus]="true"-->
8800
- <!-- extraIcon="cancel"-->
8801
- <!-- (valueChange)="onChipsValueChange($event)"-->
8802
- <!-- (extraIconClicked)="onChipsClose()"-->
8803
- <!-- ></co-input-text-chips>-->
8804
- </div>
8805
- }
8806
9025
  @if (showTitle) {
8807
9026
  <div class="title">
8808
9027
  <h3 [textContent]="(question?.commercialQuestion ? question?.commercialQuestion : question?.question) | localize:true | async"></h3>
@@ -8817,6 +9036,21 @@ class AnswersSlideoutComponent {
8817
9036
  <co-icon [iconData]="iconService.getIcon(icons.Cross)"></co-icon>
8818
9037
  </button>
8819
9038
  }
9039
+ @if (searchExpanded) {
9040
+ <div class="search-wrapper">
9041
+ <co-input-text-chips
9042
+ class="text-chips"
9043
+ [model]="chipTexts"
9044
+ [initFocus]="true"
9045
+ (modelChange)="onChipsValueChange($event)"
9046
+ (extraIconClicked)="onChipsClose()"
9047
+ ></co-input-text-chips>
9048
+ <co-button
9049
+ [iconData]="iconService.getIcon(icons.Cross)"
9050
+ (onClick)="searchExpanded = false"
9051
+ ></co-button>
9052
+ </div>
9053
+ }
8820
9054
  </div>
8821
9055
  }
8822
9056
  @if (question && question.optionLinkedText) {
@@ -8901,7 +9135,7 @@ class AnswersSlideoutComponent {
8901
9135
  }
8902
9136
  </div>
8903
9137
  </ng-template>
8904
- `, isInline: true, dependencies: [{ kind: "component", type: SlideoutComponent, selector: "co-slideout", inputs: ["show", "resizable"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: AnswerCardComponent, selector: "co-answer-card", inputs: ["model", "valutaSymbol", "showing", "isSelected", "isSmallModus", "freeInput"], outputs: ["freeInputChange", "inqNumberChange", "select", "selectWithInq", "magnifierClick", "answerInfoToggle"] }, { kind: "component", type: ImageZoomComponent, selector: "co-image-zoom", inputs: ["imageData", "show"], outputs: ["showChange"] }, { kind: "component", type: ColorFilterComponent, selector: "co-color-filter", inputs: ["color", "active"] }, { kind: "component", type: TagFilterComponent, selector: "co-tag-filter", inputs: ["tag", "active"] }, { kind: "directive", type: VisibilityObserverDirective, selector: "[visibilityObserver]", inputs: ["observerEnabled"], exportAs: ["intersection"] }, { kind: "directive", type: VisibilityObserverMasterDirective, selector: "[visibilityObserverMaster]" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.PriceDisplayPipe, name: "priceDisplay" }, { kind: "pipe", type: i6.AppendPipe, name: "append" }, { kind: "pipe", type: i6.PrependPipe, name: "prepend" }, { kind: "pipe", type: i6.StripHtmlPipe, name: "stripHtml" }], animations: [
9138
+ `, isInline: true, dependencies: [{ kind: "component", type: SlideoutComponent, selector: "co-slideout", inputs: ["show", "resizable"] }, { kind: "directive", type: i6$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: AnswerCardComponent, selector: "co-answer-card", inputs: ["model", "valutaSymbol", "showing", "isSelected", "isSmallModus", "freeInput"], outputs: ["freeInputChange", "inqNumberChange", "select", "selectWithInq", "magnifierClick", "answerInfoToggle"] }, { kind: "component", type: ImageZoomComponent, selector: "co-image-zoom", inputs: ["imageData", "show"], outputs: ["showChange"] }, { kind: "component", type: ColorFilterComponent, selector: "co-color-filter", inputs: ["color", "active"] }, { kind: "component", type: TagFilterComponent, selector: "co-tag-filter", inputs: ["tag", "active"] }, { kind: "directive", type: VisibilityObserverDirective, selector: "[visibilityObserver]", inputs: ["observerEnabled"], exportAs: ["intersection"] }, { kind: "directive", type: VisibilityObserverMasterDirective, selector: "[visibilityObserverMaster]" }, { kind: "component", type: i4.InputTextChipsComponent, selector: "co-input-text-chips", inputs: ["placeholder", "colorSeqName", "toggleModel", "toggleBoxLabel", "extraIcon"], outputs: ["extraIconClicked", "submit", "toggleModelChange"] }, { kind: "component", type: i4.ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.PriceDisplayPipe, name: "priceDisplay" }, { kind: "pipe", type: i6.AppendPipe, name: "append" }, { kind: "pipe", type: i6.PrependPipe, name: "prepend" }, { kind: "pipe", type: i6.StripHtmlPipe, name: "stripHtml" }], animations: [
8905
9139
  trigger('showFilter', [
8906
9140
  state('1', style({ transform: 'translateX(0%) scaleX(1)', opacity: 1 })),
8907
9141
  state('void', style({ transform: 'translateX(50%) scaleX(0)', opacity: 0 })),
@@ -8938,19 +9172,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
8938
9172
  </div>
8939
9173
  }
8940
9174
  <ng-template #answerTemplate>
8941
- @if (searchExpanded) {
8942
- <div class="search-wrapper" [@showFilter]="searchExpanded">
8943
- <!-- TODO enable after Angular update -->
8944
- <!-- <co-input-text-chips-->
8945
- <!-- class="text-chips"-->
8946
- <!-- [value]="chipTexts"-->
8947
- <!-- [initFocus]="true"-->
8948
- <!-- extraIcon="cancel"-->
8949
- <!-- (valueChange)="onChipsValueChange($event)"-->
8950
- <!-- (extraIconClicked)="onChipsClose()"-->
8951
- <!-- ></co-input-text-chips>-->
8952
- </div>
8953
- }
8954
9175
  @if (showTitle) {
8955
9176
  <div class="title">
8956
9177
  <h3 [textContent]="(question?.commercialQuestion ? question?.commercialQuestion : question?.question) | localize:true | async"></h3>
@@ -8965,6 +9186,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
8965
9186
  <co-icon [iconData]="iconService.getIcon(icons.Cross)"></co-icon>
8966
9187
  </button>
8967
9188
  }
9189
+ @if (searchExpanded) {
9190
+ <div class="search-wrapper">
9191
+ <co-input-text-chips
9192
+ class="text-chips"
9193
+ [model]="chipTexts"
9194
+ [initFocus]="true"
9195
+ (modelChange)="onChipsValueChange($event)"
9196
+ (extraIconClicked)="onChipsClose()"
9197
+ ></co-input-text-chips>
9198
+ <co-button
9199
+ [iconData]="iconService.getIcon(icons.Cross)"
9200
+ (onClick)="searchExpanded = false"
9201
+ ></co-button>
9202
+ </div>
9203
+ }
8968
9204
  </div>
8969
9205
  }
8970
9206
  @if (question && question.optionLinkedText) {
@@ -9259,7 +9495,7 @@ class CoSummaryLine {
9259
9495
  <ng-content></ng-content>
9260
9496
  </div>
9261
9497
  }
9262
- `, isInline: true, dependencies: [{ kind: "component", type: i4.ImageComponent, selector: "co-image", inputs: ["source", "placeHolder"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.PriceDisplayPipe, name: "priceDisplay" }], animations: [
9498
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.ImageComponent, selector: "co-image", inputs: ["source", "placeHolder"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.PriceDisplayPipe, name: "priceDisplay" }], animations: [
9263
9499
  trigger('showTheContent', [
9264
9500
  state('void', style({ height: 0, opacity: 0 })),
9265
9501
  state('*', style({ height: '*', opacity: 1 })),
@@ -9511,7 +9747,7 @@ class SelectionsSummaryLineComponent {
9511
9747
  }
9512
9748
  </co-summary-line>
9513
9749
  }
9514
- `, isInline: true, dependencies: [{ kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CoSummaryLine, selector: "co-summary-line", inputs: ["imageData", "title", "description", "price", "multilineData", "valutaSymbol", "isHighlighted", "isCollapsable", "canRepeat", "isDeletable", "showContent"], outputs: ["repeatClicked", "deleteClicked"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
9750
+ `, isInline: true, dependencies: [{ kind: "directive", type: i6$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CoSummaryLine, selector: "co-summary-line", inputs: ["imageData", "title", "description", "price", "multilineData", "valutaSymbol", "isHighlighted", "isCollapsable", "canRepeat", "isDeletable", "showContent"], outputs: ["repeatClicked", "deleteClicked"] }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
9515
9751
  }
9516
9752
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SelectionsSummaryLineComponent, decorators: [{
9517
9753
  type: Component,
@@ -9766,7 +10002,7 @@ class ConfigurationPresetDialogComponent {
9766
10002
  </div>
9767
10003
  </div>
9768
10004
  </ng-template>
9769
- `, isInline: true, dependencies: [{ kind: "component", type: i4.ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: i4.InputTextComponent, selector: "co-input-text", inputs: ["useContent", "placeholder", "align", "type", "formatPipe", "min", "max", "pattern", "digitsOnly", "excludePlusMinus", "showClearButton", "keyDownWhiteList", "showPlaceholderOnFocus", "leftIcon", "rightIcon", "leftIconData", "rightIconData", "selectOnFocus", "emptyPlace", "firstDayOfWeek", "noStyle", "hideArrowButtons", "model"], outputs: ["leftIconClick", "leftIconMouseDown", "leftIconMouseUp", "rightIconClick", "rightIconMouseDown", "rightIconMouseUp", "clearIconClick", "isFocused"] }, { kind: "directive", type: i7.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
10005
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: i4.InputTextComponent, selector: "co-input-text", inputs: ["useContent", "placeholder", "align", "type", "formatPipe", "min", "max", "pattern", "digitsOnly", "excludePlusMinus", "showClearButton", "keyDownWhiteList", "showPlaceholderOnFocus", "leftIcon", "rightIcon", "leftIconData", "rightIconData", "selectOnFocus", "emptyPlace", "firstDayOfWeek", "noStyle", "hideArrowButtons", "model"], outputs: ["leftIconClick", "leftIconMouseDown", "leftIconMouseUp", "rightIconClick", "rightIconMouseDown", "rightIconMouseUp", "clearIconClick", "isFocused"] }, { kind: "directive", type: i7.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
9770
10006
  }
9771
10007
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfigurationPresetDialogComponent, decorators: [{
9772
10008
  type: Component,
@@ -9920,7 +10156,7 @@ class ConfigurationPresetComponent {
9920
10156
  </div>
9921
10157
  <co-configuration-preset-dialog></co-configuration-preset-dialog>
9922
10158
  }
9923
- `, isInline: true, dependencies: [{ kind: "component", type: i4.ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: ConfigurationPresetDialogComponent, selector: "co-configuration-preset-dialog" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
10159
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: ConfigurationPresetDialogComponent, selector: "co-configuration-preset-dialog" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
9924
10160
  }
9925
10161
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfigurationPresetComponent, decorators: [{
9926
10162
  type: Component,
@@ -10068,7 +10304,7 @@ class SelectionsSummaryComponent {
10068
10304
  }
10069
10305
  </div>
10070
10306
  }
10071
- `, isInline: true, dependencies: [{ kind: "component", type: SelectionsSummaryLineComponent, selector: "co-selections-summary-line", inputs: ["selection", "valutaSymbol", "answersTemplate", "answerToShowFromSelectionText"], outputs: ["customizeButtonClicked", "summaryLineClick", "summaryLineRepeat", "summaryLineDelete"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: ConfigurationPresetComponent, selector: "co-configuration-preset" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i4.PriceDisplayPipe, name: "priceDisplay" }], encapsulation: i0.ViewEncapsulation.None });
10307
+ `, isInline: true, dependencies: [{ kind: "component", type: SelectionsSummaryLineComponent, selector: "co-selections-summary-line", inputs: ["selection", "valutaSymbol", "answersTemplate", "answerToShowFromSelectionText"], outputs: ["customizeButtonClicked", "summaryLineClick", "summaryLineRepeat", "summaryLineDelete"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: ConfigurationPresetComponent, selector: "co-configuration-preset" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i4.PriceDisplayPipe, name: "priceDisplay" }], encapsulation: i0.ViewEncapsulation.None });
10072
10308
  }
10073
10309
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SelectionsSummaryComponent, decorators: [{
10074
10310
  type: Component,
@@ -10278,7 +10514,7 @@ class LiteSelectorComponent {
10278
10514
  ></co-answers-slideout>
10279
10515
  }
10280
10516
  </ng-template>
10281
- `, isInline: true, dependencies: [{ kind: "component", type: AnswersSlideoutComponent, selector: "co-answers-slideout", inputs: ["question", "showTitle", "showFilter", "answers", "useSlideout", "customDimensions"], outputs: ["answerChosen"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SelectionsSummaryComponent, selector: "co-selections-summary", inputs: ["selections", "showLabel", "canClose", "answersTemplate", "answerToShowFromSelectionText", "customDimensions"], outputs: ["closeClick", "cancelAnswers", "selectSelection", "repeatSelection", "deleteSelection"] }], animations: [
10517
+ `, isInline: true, dependencies: [{ kind: "component", type: AnswersSlideoutComponent, selector: "co-answers-slideout", inputs: ["question", "showTitle", "showFilter", "answers", "useSlideout", "customDimensions"], outputs: ["answerChosen"] }, { kind: "directive", type: i6$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SelectionsSummaryComponent, selector: "co-selections-summary", inputs: ["selections", "showLabel", "canClose", "answersTemplate", "answerToShowFromSelectionText", "customDimensions"], outputs: ["closeClick", "cancelAnswers", "selectSelection", "repeatSelection", "deleteSelection"] }], animations: [
10282
10518
  trigger('showSelections', [
10283
10519
  state('void', style({ 'transform': 'translateX(100%)', opacity: 0 })),
10284
10520
  state('*', style({ 'transform': 'translateX(0%)', opacity: 1 })),
@@ -10361,17 +10597,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
10361
10597
  type: Output
10362
10598
  }] } });
10363
10599
 
10364
- class ProductConfiguratorService {
10365
- showChange = new EventEmitter();
10366
- answerChosen = new EventEmitter();
10367
- selectSelection = new EventEmitter();
10368
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
10369
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorService, providedIn: 'root' });
10370
- }
10371
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorService, decorators: [{
10372
- type: Injectable,
10373
- args: [{ providedIn: 'root' }]
10374
- }] });
10600
+ const trackBySelectionIdFn = (index, selection) => {
10601
+ return selection && selection.id ? `${selection.id}-${selection.selected}` : `__NEW__${index}`;
10602
+ };
10375
10603
 
10376
10604
  class ProductConfiguratorSelectorOptionTileComponent {
10377
10605
  configuratorConnectorService;
@@ -10382,94 +10610,152 @@ class ProductConfiguratorSelectorOptionTileComponent {
10382
10610
  }
10383
10611
  icons = IconEnum;
10384
10612
  option;
10385
- tileClass = 'small';
10613
+ tileClass;
10386
10614
  noLabel = false;
10615
+ markAsException = false;
10616
+ set showing(value) {
10617
+ if (value) {
10618
+ this._getThumbnailImage();
10619
+ }
10620
+ }
10387
10621
  selectionClicked = new EventEmitter();
10622
+ class = 'small';
10388
10623
  constructor(configuratorConnectorService, iconService, settingsService) {
10389
10624
  this.configuratorConnectorService = configuratorConnectorService;
10390
10625
  this.iconService = iconService;
10391
10626
  this.settingsService = settingsService;
10392
10627
  }
10628
+ ngOnInit() {
10629
+ if (this.tileClass) {
10630
+ this.class = this._getTileClass();
10631
+ }
10632
+ }
10393
10633
  changeSelection() {
10394
10634
  this.selectionClicked.emit();
10395
10635
  }
10636
+ _getTileClass() {
10637
+ if (this.tileClass === ConfigurationDisplayOption.TileLarge) {
10638
+ return 'large';
10639
+ }
10640
+ else if (this.tileClass === ConfigurationDisplayOption.TileRounded) {
10641
+ return 'rounded';
10642
+ }
10643
+ else if (this.tileClass === ConfigurationDisplayOption.SmallCircle) {
10644
+ return 'small-rounded';
10645
+ }
10646
+ else if (this.tileClass === ConfigurationDisplayOption.SmallSquare) {
10647
+ return 'small-square';
10648
+ }
10649
+ else if (this.tileClass === ConfigurationDisplayOption.HorizontalTiles) {
10650
+ return 'horizontal';
10651
+ }
10652
+ else if (this.tileClass === ConfigurationDisplayOption.OnPage) {
10653
+ return 'on-page';
10654
+ }
10655
+ else if (this.tileClass === ConfigurationDisplayOption.SlideOut) {
10656
+ return 'slide-out';
10657
+ }
10658
+ else {
10659
+ return 'small';
10660
+ }
10661
+ }
10662
+ async _getThumbnailImage() {
10663
+ await this.configuratorConnectorService.getImageForAnswer(this.option);
10664
+ }
10665
+ NodeType = NodeType;
10396
10666
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorOptionTileComponent, deps: [{ token: ConfiguratorConnectorService }, { token: IconCacheService }, { token: ConfiguratorSettingsService }], target: i0.ɵɵFactoryTarget.Component });
10397
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ProductConfiguratorSelectorOptionTileComponent, isStandalone: false, selector: "co-product-configurator-selector-option-tile", inputs: { option: "option", tileClass: "tileClass", noLabel: "noLabel" }, outputs: { selectionClicked: "selectionClicked" }, host: { properties: { "class.co-product-configurator-selector-option-tile": "this.showClass" } }, ngImport: i0, template: `
10398
- <!-- When selected show checkmark -->
10399
- <div
10400
- class="configurator-selector-option-tile-container configurator-selector-option-tile-container-{{this.tileClass}}"
10401
- (click)="changeSelection()" [class.active]="option.selected ==='F'">
10402
- @if (option.selected ==='F') {
10403
- <div class="product-configurator-selector-option-tile-checkmark">
10404
- <co-icon class="product-configurator-selector-option-tile-selected"
10405
- [iconData]="iconService.getIcon(icons.CheckSolid)">
10406
- </co-icon>
10407
- </div>
10408
- }
10409
- <!-- Image -->
10410
- <div class="product-configurator-selector-option-tile-image">
10411
- @if (option.imageData) {
10412
- <img [src]="option.imageData" [alt]="option.artNodeId">
10413
- }
10414
- @if (!option.imageData) {
10415
- <co-icon class="product-configurator-selector-option-button-no-image"
10416
- [iconData]="iconService.getIcon(icons.ImageSlashRegular)">
10417
- </co-icon>
10667
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ProductConfiguratorSelectorOptionTileComponent, isStandalone: false, selector: "co-product-configurator-selector-option-tile", inputs: { option: "option", tileClass: "tileClass", noLabel: "noLabel", markAsException: "markAsException", showing: "showing" }, outputs: { selectionClicked: "selectionClicked" }, host: { properties: { "class.co-product-configurator-selector-option-tile": "this.showClass" } }, ngImport: i0, template: `
10668
+ <!-- When selected show checkmark -->
10669
+ <div
10670
+ class="configurator-selector-option-tile-container configurator-selector-option-tile-container-{{this.class}}"
10671
+ (click)="changeSelection()" [class.active]="option.selected ==='F'">
10672
+ @if (option.selected === 'F') {
10673
+ @if (option.nodeType === NodeType.Article) {
10674
+ <div class="product-configurator-selector-option-tile-configurable" [class.exception]="markAsException">
10675
+ <co-icon class="product-configurator-selector-option-tile-selected"
10676
+ [iconData]="iconService.getIcon(icons.Brush)">
10677
+ </co-icon>
10678
+ </div>
10679
+ } @else {
10680
+ <div class="product-configurator-selector-option-tile-checkmark">
10681
+ <co-icon class="product-configurator-selector-option-tile-selected"
10682
+ [iconData]="iconService.getIcon(icons.CheckSolid)">
10683
+ </co-icon>
10684
+ </div>
10685
+ }
10418
10686
  }
10419
- </div>
10420
- <!-- Answer text -->
10687
+ <!-- Image -->
10688
+ <div class="product-configurator-selector-option-tile-image">
10689
+ @if (option.imageData) {
10690
+ <img [src]="option.imageData" [alt]="option.artNodeId">
10691
+ }
10692
+ @if (!option.imageData) {
10693
+ <co-icon class="product-configurator-selector-option-button-no-image"
10694
+ [iconData]="iconService.getIcon(icons.ImageSlashRegular)">
10695
+ </co-icon>
10696
+ }
10697
+ </div>
10698
+ <!-- Answer text -->
10421
10699
  @if (!noLabel) {
10422
- <div class="product-configurator-selector-option-tile-description">
10423
- @if (option.nodeText) {
10424
- <p [textContent]="option.nodeText | localize:true | async"></p>
10425
- }
10426
- @if (!option.nodeText) {
10427
- <p [textContent]="'Skip / Cancel' | localize:true | async"></p>
10428
- }
10429
- </div>
10700
+ <div class="product-configurator-selector-option-tile-description">
10701
+ @if (option.nodeText) {
10702
+ <p [textContent]="option.nodeText | localize:true | async"></p>
10703
+ }
10704
+ @if (!option.nodeText) {
10705
+ <p [textContent]="'Skip / Cancel' | localize:true | async"></p>
10706
+ }
10707
+ </div>
10430
10708
  }
10431
- </div>
10432
- `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
10709
+ </div>
10710
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
10433
10711
  }
10434
10712
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorOptionTileComponent, decorators: [{
10435
10713
  type: Component,
10436
10714
  args: [{
10437
10715
  selector: 'co-product-configurator-selector-option-tile',
10438
10716
  template: `
10439
- <!-- When selected show checkmark -->
10440
- <div
10441
- class="configurator-selector-option-tile-container configurator-selector-option-tile-container-{{this.tileClass}}"
10442
- (click)="changeSelection()" [class.active]="option.selected ==='F'">
10443
- @if (option.selected ==='F') {
10444
- <div class="product-configurator-selector-option-tile-checkmark">
10445
- <co-icon class="product-configurator-selector-option-tile-selected"
10446
- [iconData]="iconService.getIcon(icons.CheckSolid)">
10447
- </co-icon>
10448
- </div>
10449
- }
10450
- <!-- Image -->
10451
- <div class="product-configurator-selector-option-tile-image">
10452
- @if (option.imageData) {
10453
- <img [src]="option.imageData" [alt]="option.artNodeId">
10454
- }
10455
- @if (!option.imageData) {
10456
- <co-icon class="product-configurator-selector-option-button-no-image"
10457
- [iconData]="iconService.getIcon(icons.ImageSlashRegular)">
10458
- </co-icon>
10717
+ <!-- When selected show checkmark -->
10718
+ <div
10719
+ class="configurator-selector-option-tile-container configurator-selector-option-tile-container-{{this.class}}"
10720
+ (click)="changeSelection()" [class.active]="option.selected ==='F'">
10721
+ @if (option.selected === 'F') {
10722
+ @if (option.nodeType === NodeType.Article) {
10723
+ <div class="product-configurator-selector-option-tile-configurable" [class.exception]="markAsException">
10724
+ <co-icon class="product-configurator-selector-option-tile-selected"
10725
+ [iconData]="iconService.getIcon(icons.Brush)">
10726
+ </co-icon>
10727
+ </div>
10728
+ } @else {
10729
+ <div class="product-configurator-selector-option-tile-checkmark">
10730
+ <co-icon class="product-configurator-selector-option-tile-selected"
10731
+ [iconData]="iconService.getIcon(icons.CheckSolid)">
10732
+ </co-icon>
10733
+ </div>
10734
+ }
10459
10735
  }
10460
- </div>
10461
- <!-- Answer text -->
10736
+ <!-- Image -->
10737
+ <div class="product-configurator-selector-option-tile-image">
10738
+ @if (option.imageData) {
10739
+ <img [src]="option.imageData" [alt]="option.artNodeId">
10740
+ }
10741
+ @if (!option.imageData) {
10742
+ <co-icon class="product-configurator-selector-option-button-no-image"
10743
+ [iconData]="iconService.getIcon(icons.ImageSlashRegular)">
10744
+ </co-icon>
10745
+ }
10746
+ </div>
10747
+ <!-- Answer text -->
10462
10748
  @if (!noLabel) {
10463
- <div class="product-configurator-selector-option-tile-description">
10464
- @if (option.nodeText) {
10465
- <p [textContent]="option.nodeText | localize:true | async"></p>
10466
- }
10467
- @if (!option.nodeText) {
10468
- <p [textContent]="'Skip / Cancel' | localize:true | async"></p>
10469
- }
10470
- </div>
10749
+ <div class="product-configurator-selector-option-tile-description">
10750
+ @if (option.nodeText) {
10751
+ <p [textContent]="option.nodeText | localize:true | async"></p>
10752
+ }
10753
+ @if (!option.nodeText) {
10754
+ <p [textContent]="'Skip / Cancel' | localize:true | async"></p>
10755
+ }
10756
+ </div>
10471
10757
  }
10472
- </div>
10758
+ </div>
10473
10759
  `,
10474
10760
  encapsulation: ViewEncapsulation.None,
10475
10761
  standalone: false
@@ -10483,6 +10769,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
10483
10769
  type: Input
10484
10770
  }], noLabel: [{
10485
10771
  type: Input
10772
+ }], markAsException: [{
10773
+ type: Input
10774
+ }], showing: [{
10775
+ type: Input
10486
10776
  }], selectionClicked: [{
10487
10777
  type: Output
10488
10778
  }] } });
@@ -10532,7 +10822,7 @@ class ProductConfiguratorOptionCheckboxComponent {
10532
10822
  </div>
10533
10823
  </div>
10534
10824
 
10535
- `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
10825
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
10536
10826
  }
10537
10827
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorOptionCheckboxComponent, decorators: [{
10538
10828
  type: Component,
@@ -10616,7 +10906,7 @@ class ProductConfiguratorSelectorOptionButtonComponent {
10616
10906
  }
10617
10907
  </div>
10618
10908
  </div>
10619
- `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
10909
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
10620
10910
  }
10621
10911
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorOptionButtonComponent, decorators: [{
10622
10912
  type: Component,
@@ -10698,7 +10988,7 @@ class ProductConfiguratorSelectorOptionDropDownComponent {
10698
10988
  </co-icon>
10699
10989
  </div>
10700
10990
  </div>
10701
- `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
10991
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
10702
10992
  }
10703
10993
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorOptionDropDownComponent, decorators: [{
10704
10994
  type: Component,
@@ -10742,22 +11032,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
10742
11032
  class ProductConfiguratorSelectorOptionComponent {
10743
11033
  configuratorConnectorService;
10744
11034
  settingsService;
10745
- productConfiguratorService;
10746
- showClass() {
10747
- return true;
10748
- }
10749
- selection;
10750
- listOfChoices;
10751
- markAsException;
10752
- showGlobalAll = false;
10753
- groupedSubShow = true;
10754
- configurationDisplayOption = ConfigurationDisplayOption;
10755
- selectionClass = '';
10756
- showAllTiles = false;
10757
- maxVisibleTiles = 10;
10758
- maxVisibleSmallTiles = 7;
10759
- visibleAnswers = [];
10760
- remainingTilesCount = 0;
11035
+ _appEventService;
11036
+ trackBySelectionIdFn = trackBySelectionIdFn;
10761
11037
  smallTileOptions = [
10762
11038
  ConfigurationDisplayOption.TileSmall,
10763
11039
  ConfigurationDisplayOption.SmallCircle,
@@ -10767,13 +11043,33 @@ class ProductConfiguratorSelectorOptionComponent {
10767
11043
  ConfigurationDisplayOption.TileLarge,
10768
11044
  ConfigurationDisplayOption.TileRounded
10769
11045
  ];
10770
- constructor(configuratorConnectorService, settingsService, productConfiguratorService) {
11046
+ showClass() {
11047
+ return true;
11048
+ }
11049
+ selection;
11050
+ listOfChoices;
11051
+ markAsException;
11052
+ limitAmountOfTiles = false;
11053
+ maxVisibleTiles = 5;
11054
+ maxVisibleSmallTiles = 10;
11055
+ selectionClicked = new EventEmitter();
11056
+ configurationDisplayOption = ConfigurationDisplayOption;
11057
+ selectionClass = '';
11058
+ showAllTiles = false;
11059
+ remainingTilesCount = 0;
11060
+ amountOfTilesToShow = 0;
11061
+ showViewMoreButton = true;
11062
+ _subs = [];
11063
+ constructor(configuratorConnectorService, settingsService, _appEventService) {
10771
11064
  this.configuratorConnectorService = configuratorConnectorService;
10772
11065
  this.settingsService = settingsService;
10773
- this.productConfiguratorService = productConfiguratorService;
11066
+ this._appEventService = _appEventService;
11067
+ this._subs.push(this._appEventService.showAllConfigurationOptions.subscribe(show => {
11068
+ this._handleShowAll(show);
11069
+ }));
10774
11070
  }
10775
11071
  ngOnInit() {
10776
- if (this.selection && this.selection.displayOptionControl == null) {
11072
+ if (this.selection && this.selection.displayOptionControl === null || this.selection.displayOptionControl === undefined) {
10777
11073
  this.selection.displayOptionControl = ConfigurationDisplayOption.TileLarge;
10778
11074
  }
10779
11075
  if (this.markAsException) {
@@ -10782,160 +11078,126 @@ class ProductConfiguratorSelectorOptionComponent {
10782
11078
  else {
10783
11079
  this.selectionClass = 'selection-container-' + this.selection.displayOptionControl;
10784
11080
  }
10785
- if (this.selection && this.selection.opvTreeNodeHierarchy && this.selection.nodeType === NodeType.Question) {
10786
- // When the selection has a opvTreeNodeHierarchy and has nodeType OPT means we need to add a cancel/ skip option.
10787
- // This is different from the slide out comp/ selector.
10788
- // But we need to make a copy of it, if we do not do that, we are missing the right header...
10789
- const selectionCopy = Object.assign(new SelectorStructure(), this.selection);
10790
- this.configuratorConnectorService.getImageForAnswer(selectionCopy);
10791
- this.listOfChoices.push(selectionCopy);
10792
- }
10793
- if (this.showGlobalAll) {
10794
- this.showAllTiles = true;
10795
- }
11081
+ this.amountOfTilesToShow = this.listOfChoices.length; // Set the default amount to show.
11082
+ this.showViewMoreButton = !this.settingsService.settings.options.groupedShowAllBtn;
10796
11083
  this._calculateVisibleAnswers();
10797
11084
  }
10798
- ngOnChanges(changes) {
10799
- if (changes.showGlobalAll && !changes.showGlobalAll.firstChange) {
10800
- this.showAllTiles = !!changes.showGlobalAll.currentValue;
10801
- this._calculateVisibleAnswers();
10802
- }
10803
- if (changes.listOfChoices && !changes.listOfChoices.firstChange) {
10804
- this._calculateVisibleAnswers();
10805
- }
10806
- if (changes.selection && !changes.selection.firstChange) {
10807
- this._calculateVisibleAnswers();
10808
- }
11085
+ ngOnDestroy() {
11086
+ this._subs.forEach(s => s.unsubscribe());
10809
11087
  }
10810
- selectionClicked(answer) {
10811
- this.productConfiguratorService.selectSelection.emit(answer);
11088
+ handleSelectionClicked(answer) {
11089
+ this.selectionClicked.emit(answer);
10812
11090
  }
10813
11091
  showMore() {
10814
11092
  this.showAllTiles = true;
11093
+ this.amountOfTilesToShow = this.listOfChoices.length;
10815
11094
  this._calculateVisibleAnswers();
10816
11095
  }
10817
11096
  showLess() {
10818
11097
  this.showAllTiles = false;
10819
11098
  this._calculateVisibleAnswers();
10820
11099
  }
10821
- getTileClass() {
10822
- switch (this.selection.displayOptionControl) {
10823
- case this.configurationDisplayOption.TileLarge:
10824
- return 'large';
10825
- case this.configurationDisplayOption.TileRounded:
10826
- return 'rounded';
10827
- case this.configurationDisplayOption.SmallCircle:
10828
- return 'small-rounded';
10829
- case this.configurationDisplayOption.SmallSquare:
10830
- return 'small-square';
10831
- default:
10832
- return 'small';
10833
- }
10834
- }
10835
11100
  _calculateVisibleAnswers() {
10836
- if (this.largeTileOptions.includes(this.selection.displayOptionControl)) {
10837
- const configuredMaxVisibleTiles = this.settingsService?.settings?.options?.maxVisibleTiles;
10838
- if (configuredMaxVisibleTiles != null) {
10839
- this.maxVisibleTiles = configuredMaxVisibleTiles;
10840
- }
10841
- this.visibleAnswers = this.showAllTiles
10842
- ? this.listOfChoices
10843
- : this.listOfChoices.slice(0, this.maxVisibleTiles);
10844
- this.remainingTilesCount = Math.max(0, this.listOfChoices.length - this.maxVisibleTiles);
10845
- }
10846
- else if (this.smallTileOptions.includes(this.selection.displayOptionControl)) {
10847
- const configuredMaxVisibleTiles = this.settingsService?.settings?.options?.maxVisibleSmallTiles;
10848
- if (configuredMaxVisibleTiles != null) {
10849
- this.maxVisibleSmallTiles = configuredMaxVisibleTiles;
10850
- }
10851
- this.visibleAnswers = this.showAllTiles
10852
- ? this.listOfChoices
10853
- : this.listOfChoices.slice(0, this.maxVisibleSmallTiles);
10854
- this.remainingTilesCount = Math.max(0, this.listOfChoices.length - this.maxVisibleSmallTiles);
11101
+ if (this.limitAmountOfTiles && !this.showAllTiles) {
11102
+ if (this.largeTileOptions.includes(this.selection.displayOptionControl)) {
11103
+ this.amountOfTilesToShow = this.maxVisibleTiles;
11104
+ this.remainingTilesCount = Math.max(0, this.listOfChoices.length - this.maxVisibleTiles);
11105
+ }
11106
+ else if (this.smallTileOptions.includes(this.selection.displayOptionControl)) {
11107
+ this.amountOfTilesToShow = this.maxVisibleSmallTiles;
11108
+ this.remainingTilesCount = Math.max(0, this.listOfChoices.length - this.maxVisibleSmallTiles);
11109
+ }
11110
+ else {
11111
+ this.remainingTilesCount = 0;
11112
+ }
10855
11113
  }
10856
- else {
10857
- this.visibleAnswers = this.listOfChoices;
10858
- this.remainingTilesCount = 0;
10859
- }
10860
- }
10861
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorOptionComponent, deps: [{ token: ConfiguratorConnectorService }, { token: ConfiguratorSettingsService }, { token: ProductConfiguratorService }], target: i0.ɵɵFactoryTarget.Component });
10862
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ProductConfiguratorSelectorOptionComponent, isStandalone: false, selector: "co-product-configurator-selector-option", inputs: { selection: "selection", listOfChoices: "listOfChoices", markAsException: "markAsException", showGlobalAll: "showGlobalAll", groupedSubShow: "groupedSubShow" }, host: { properties: { "class.co-product-configurator-selector-option": "this.showClass" } }, usesOnChanges: true, ngImport: i0, template: `
10863
- <div class="selector-wrapper {{this.selectionClass}}">
10864
- @if (this.selection.displayOptionControl !== configurationDisplayOption.DropDown
10865
- && !this.largeTileOptions.includes(this.selection.displayOptionControl)
10866
- && !this.smallTileOptions.includes(this.selection.displayOptionControl)) {
10867
- @for (child of listOfChoices; track child.id) {
10868
- <div class="selector-option-wrapper" [class.active]="child.selected ==='F'">
10869
- @if (this.selection.displayOptionControl === configurationDisplayOption.Button) {
11114
+ }
11115
+ _handleShowAll(show) {
11116
+ this.limitAmountOfTiles = false;
11117
+ this.showAllTiles = true;
11118
+ this.amountOfTilesToShow = this.listOfChoices.length;
11119
+ this._calculateVisibleAnswers();
11120
+ }
11121
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorOptionComponent, deps: [{ token: ConfiguratorConnectorService }, { token: ConfiguratorSettingsService }, { token: ConfiguratorEventService }], target: i0.ɵɵFactoryTarget.Component });
11122
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ProductConfiguratorSelectorOptionComponent, isStandalone: false, selector: "co-product-configurator-selector-option", inputs: { selection: "selection", listOfChoices: "listOfChoices", markAsException: "markAsException", limitAmountOfTiles: "limitAmountOfTiles", maxVisibleTiles: "maxVisibleTiles", maxVisibleSmallTiles: "maxVisibleSmallTiles" }, outputs: { selectionClicked: "selectionClicked" }, host: { properties: { "class.co-product-configurator-selector-option": "this.showClass" } }, ngImport: i0, template: `
11123
+ <div class="selector-wrapper {{selectionClass}}" visibilityObserverMaster>
11124
+ @if (selection.displayOptionControl !== configurationDisplayOption.DropDown && !largeTileOptions.includes(selection.displayOptionControl) && !smallTileOptions.includes(selection.displayOptionControl)) {
11125
+ @for (child of listOfChoices; track trackBySelectionIdFn($index, child); ) {
11126
+ <div
11127
+ class="selector-option-wrapper"
11128
+ [class.active]="child.selected ==='F'"
11129
+ [class.exception]="child.selected ==='F' && markAsException">
11130
+ @if (selection.displayOptionControl === configurationDisplayOption.Button) {
10870
11131
  <co-product-configurator-selector-option-button
10871
11132
  [option]="child"
10872
- (selectionClicked)="selectionClicked(child)">
11133
+ (selectionClicked)="handleSelectionClicked(child)">
10873
11134
  </co-product-configurator-selector-option-button>
10874
11135
  }
10875
- @if (this.selection.displayOptionControl === configurationDisplayOption.ListOfValues) {
11136
+ @if (selection.displayOptionControl === configurationDisplayOption.ListOfValues) {
10876
11137
  <co-product-configurator-option-checkbox
10877
11138
  [option]="child"
10878
- (selectionClicked)="selectionClicked(child)">
11139
+ (selectionClicked)="handleSelectionClicked(child)">
10879
11140
  </co-product-configurator-option-checkbox>
10880
11141
  }
10881
- @if (this.selection.displayOptionControl === configurationDisplayOption.TileRounded) {
11142
+ @if (selection.displayOptionControl === configurationDisplayOption.TileRounded) {
10882
11143
  <co-product-configurator-selector-option-tile
10883
11144
  [option]="child"
10884
- [tileClass]="'rounded'"
10885
- (selectionClicked)="selectionClicked(child)">
11145
+ [tileClass]="selection.displayOptionControl"
11146
+ (selectionClicked)="handleSelectionClicked(child)">
10886
11147
  </co-product-configurator-selector-option-tile>
10887
11148
  }
10888
- @if (this.selection.displayOptionControl === configurationDisplayOption.HorizontalTiles) {
11149
+ @if (selection.displayOptionControl === configurationDisplayOption.HorizontalTiles) {
10889
11150
  <co-product-configurator-selector-option-tile
10890
11151
  [option]="child"
10891
- [tileClass]="'horizontal'"
10892
- (selectionClicked)="selectionClicked(child)">
11152
+ [tileClass]="selection.displayOptionControl"
11153
+ (selectionClicked)="handleSelectionClicked(child)">
10893
11154
  </co-product-configurator-selector-option-tile>
10894
11155
  }
10895
- @if (this.selection.displayOptionControl === configurationDisplayOption.OnPage) {
11156
+ @if (selection.displayOptionControl === configurationDisplayOption.OnPage) {
10896
11157
  <co-product-configurator-selector-option-tile
10897
- [option]="child"
10898
- [tileClass]="'on-page'"
10899
- (selectionClicked)="selectionClicked(child)">
11158
+ [option]="child"
11159
+ [tileClass]="selection.displayOptionControl"
11160
+ (selectionClicked)="handleSelectionClicked(child)">
10900
11161
  </co-product-configurator-selector-option-tile>
10901
11162
  }
10902
- @if (this.selection.displayOptionControl === configurationDisplayOption.SlideOut) {
11163
+ @if (selection.displayOptionControl === configurationDisplayOption.SlideOut) {
10903
11164
  <co-product-configurator-selector-option-tile
10904
- [option]="child"
10905
- [tileClass]="'slide-out'"
10906
- (selectionClicked)="selectionClicked(child)">
11165
+ [option]="child"
11166
+ [tileClass]="selection.displayOptionControl"
11167
+ (selectionClicked)="handleSelectionClicked(child)">
10907
11168
  </co-product-configurator-selector-option-tile>
10908
11169
  }
10909
11170
  </div>
10910
11171
  }
10911
11172
  }
10912
-
10913
- @if (
10914
- this.largeTileOptions.includes(this.selection.displayOptionControl)
10915
- || this.smallTileOptions.includes(this.selection.displayOptionControl)) {
10916
- @for (child of visibleAnswers; track child.id) {
10917
- <div class="selector-option-wrapper" [class.active]="child.selected ==='F'">
11173
+ @if (largeTileOptions.includes(selection.displayOptionControl) || smallTileOptions.includes(selection.displayOptionControl)) {
11174
+ @for (child of listOfChoices | slice:0:amountOfTilesToShow; track trackBySelectionIdFn($index, child)) {
11175
+ <div
11176
+ class="selector-option-wrapper"
11177
+ [class.active]="child.selected ==='F'"
11178
+ [class.exception]="child.selected ==='F' && markAsException">
10918
11179
  <co-product-configurator-selector-option-tile
11180
+ visibilityObserver
11181
+ #intersection="intersection"
11182
+ [observerEnabled]="true"
11183
+ [showing]="intersection.isIntersecting"
10919
11184
  [option]="child"
10920
- [noLabel]="this.selection.displayOptionControl === configurationDisplayOption.SmallCircle || this.selection.displayOptionControl === configurationDisplayOption.SmallSquare"
10921
- [tileClass]="getTileClass()"
10922
- (selectionClicked)="selectionClicked(child)"
11185
+ [markAsException]="markAsException"
11186
+ [noLabel]="selection.displayOptionControl === configurationDisplayOption.SmallCircle || selection.displayOptionControl === configurationDisplayOption.SmallSquare"
11187
+ [tileClass]="selection.displayOptionControl"
11188
+ (selectionClicked)="handleSelectionClicked(child)"
10923
11189
  ></co-product-configurator-selector-option-tile>
10924
11190
  </div>
10925
11191
  }
10926
11192
  }
10927
-
10928
- @if (this.selection.displayOptionControl === configurationDisplayOption.DropDown) {
11193
+ @if (selection.displayOptionControl === configurationDisplayOption.DropDown) {
10929
11194
  <co-product-configurator-selector-option-dropdown
10930
11195
  [options]="listOfChoices"
10931
- (selectionClicked)="selectionClicked($event)"
11196
+ (selectionClicked)="handleSelectionClicked($event)"
10932
11197
  ></co-product-configurator-selector-option-dropdown>
10933
11198
  }
10934
11199
  </div>
10935
-
10936
- @if (
10937
- (this.largeTileOptions.includes(this.selection.displayOptionControl) ||
10938
- this.smallTileOptions.includes(this.selection.displayOptionControl)) && groupedSubShow) {
11200
+ @if (showViewMoreButton && (largeTileOptions.includes(selection.displayOptionControl) || smallTileOptions.includes(selection.displayOptionControl))) {
10939
11201
  @if (!showAllTiles && remainingTilesCount > 0) {
10940
11202
  <div class="show-more-container">
10941
11203
  <span (click)="showMore()">
@@ -10951,96 +11213,91 @@ class ProductConfiguratorSelectorOptionComponent {
10951
11213
  </div>
10952
11214
  }
10953
11215
  }
10954
-
10955
- `, isInline: true, dependencies: [{ kind: "component", type: ProductConfiguratorSelectorOptionTileComponent, selector: "co-product-configurator-selector-option-tile", inputs: ["option", "tileClass", "noLabel"], outputs: ["selectionClicked"] }, { kind: "component", type: ProductConfiguratorOptionCheckboxComponent, selector: "co-product-configurator-option-checkbox", inputs: ["option"], outputs: ["selectionClicked"] }, { kind: "component", type: ProductConfiguratorSelectorOptionButtonComponent, selector: "co-product-configurator-selector-option-button", inputs: ["option"], outputs: ["selectionClicked"] }, { kind: "component", type: ProductConfiguratorSelectorOptionDropDownComponent, selector: "co-product-configurator-selector-option-dropdown", inputs: ["options", "tileClass"], outputs: ["selectionClicked"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], animations: [
10956
- trigger('showSelections', [
10957
- state('void', style({ 'transform': 'translateX(100%)', opacity: 0 })),
10958
- state('*', style({ 'transform': 'translateX(0%)', opacity: 1 })),
10959
- transition('void <=> *', animate(200))
10960
- ])
10961
- ], encapsulation: i0.ViewEncapsulation.None });
11216
+ `, isInline: true, dependencies: [{ kind: "component", type: ProductConfiguratorSelectorOptionTileComponent, selector: "co-product-configurator-selector-option-tile", inputs: ["option", "tileClass", "noLabel", "markAsException", "showing"], outputs: ["selectionClicked"] }, { kind: "component", type: ProductConfiguratorOptionCheckboxComponent, selector: "co-product-configurator-option-checkbox", inputs: ["option"], outputs: ["selectionClicked"] }, { kind: "component", type: ProductConfiguratorSelectorOptionButtonComponent, selector: "co-product-configurator-selector-option-button", inputs: ["option"], outputs: ["selectionClicked"] }, { kind: "component", type: ProductConfiguratorSelectorOptionDropDownComponent, selector: "co-product-configurator-selector-option-dropdown", inputs: ["options", "tileClass"], outputs: ["selectionClicked"] }, { kind: "directive", type: VisibilityObserverDirective, selector: "[visibilityObserver]", inputs: ["observerEnabled"], exportAs: ["intersection"] }, { kind: "directive", type: VisibilityObserverMasterDirective, selector: "[visibilityObserverMaster]" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6$1.SlicePipe, name: "slice" }], encapsulation: i0.ViewEncapsulation.None });
10962
11217
  }
10963
11218
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorOptionComponent, decorators: [{
10964
11219
  type: Component,
10965
11220
  args: [{
10966
11221
  selector: 'co-product-configurator-selector-option',
10967
11222
  template: `
10968
- <div class="selector-wrapper {{this.selectionClass}}">
10969
- @if (this.selection.displayOptionControl !== configurationDisplayOption.DropDown
10970
- && !this.largeTileOptions.includes(this.selection.displayOptionControl)
10971
- && !this.smallTileOptions.includes(this.selection.displayOptionControl)) {
10972
- @for (child of listOfChoices; track child.id) {
10973
- <div class="selector-option-wrapper" [class.active]="child.selected ==='F'">
10974
- @if (this.selection.displayOptionControl === configurationDisplayOption.Button) {
11223
+ <div class="selector-wrapper {{selectionClass}}" visibilityObserverMaster>
11224
+ @if (selection.displayOptionControl !== configurationDisplayOption.DropDown && !largeTileOptions.includes(selection.displayOptionControl) && !smallTileOptions.includes(selection.displayOptionControl)) {
11225
+ @for (child of listOfChoices; track trackBySelectionIdFn($index, child); ) {
11226
+ <div
11227
+ class="selector-option-wrapper"
11228
+ [class.active]="child.selected ==='F'"
11229
+ [class.exception]="child.selected ==='F' && markAsException">
11230
+ @if (selection.displayOptionControl === configurationDisplayOption.Button) {
10975
11231
  <co-product-configurator-selector-option-button
10976
11232
  [option]="child"
10977
- (selectionClicked)="selectionClicked(child)">
11233
+ (selectionClicked)="handleSelectionClicked(child)">
10978
11234
  </co-product-configurator-selector-option-button>
10979
11235
  }
10980
- @if (this.selection.displayOptionControl === configurationDisplayOption.ListOfValues) {
11236
+ @if (selection.displayOptionControl === configurationDisplayOption.ListOfValues) {
10981
11237
  <co-product-configurator-option-checkbox
10982
11238
  [option]="child"
10983
- (selectionClicked)="selectionClicked(child)">
11239
+ (selectionClicked)="handleSelectionClicked(child)">
10984
11240
  </co-product-configurator-option-checkbox>
10985
11241
  }
10986
- @if (this.selection.displayOptionControl === configurationDisplayOption.TileRounded) {
11242
+ @if (selection.displayOptionControl === configurationDisplayOption.TileRounded) {
10987
11243
  <co-product-configurator-selector-option-tile
10988
11244
  [option]="child"
10989
- [tileClass]="'rounded'"
10990
- (selectionClicked)="selectionClicked(child)">
11245
+ [tileClass]="selection.displayOptionControl"
11246
+ (selectionClicked)="handleSelectionClicked(child)">
10991
11247
  </co-product-configurator-selector-option-tile>
10992
11248
  }
10993
- @if (this.selection.displayOptionControl === configurationDisplayOption.HorizontalTiles) {
11249
+ @if (selection.displayOptionControl === configurationDisplayOption.HorizontalTiles) {
10994
11250
  <co-product-configurator-selector-option-tile
10995
11251
  [option]="child"
10996
- [tileClass]="'horizontal'"
10997
- (selectionClicked)="selectionClicked(child)">
11252
+ [tileClass]="selection.displayOptionControl"
11253
+ (selectionClicked)="handleSelectionClicked(child)">
10998
11254
  </co-product-configurator-selector-option-tile>
10999
11255
  }
11000
- @if (this.selection.displayOptionControl === configurationDisplayOption.OnPage) {
11256
+ @if (selection.displayOptionControl === configurationDisplayOption.OnPage) {
11001
11257
  <co-product-configurator-selector-option-tile
11002
- [option]="child"
11003
- [tileClass]="'on-page'"
11004
- (selectionClicked)="selectionClicked(child)">
11258
+ [option]="child"
11259
+ [tileClass]="selection.displayOptionControl"
11260
+ (selectionClicked)="handleSelectionClicked(child)">
11005
11261
  </co-product-configurator-selector-option-tile>
11006
11262
  }
11007
- @if (this.selection.displayOptionControl === configurationDisplayOption.SlideOut) {
11263
+ @if (selection.displayOptionControl === configurationDisplayOption.SlideOut) {
11008
11264
  <co-product-configurator-selector-option-tile
11009
- [option]="child"
11010
- [tileClass]="'slide-out'"
11011
- (selectionClicked)="selectionClicked(child)">
11265
+ [option]="child"
11266
+ [tileClass]="selection.displayOptionControl"
11267
+ (selectionClicked)="handleSelectionClicked(child)">
11012
11268
  </co-product-configurator-selector-option-tile>
11013
11269
  }
11014
11270
  </div>
11015
11271
  }
11016
11272
  }
11017
-
11018
- @if (
11019
- this.largeTileOptions.includes(this.selection.displayOptionControl)
11020
- || this.smallTileOptions.includes(this.selection.displayOptionControl)) {
11021
- @for (child of visibleAnswers; track child.id) {
11022
- <div class="selector-option-wrapper" [class.active]="child.selected ==='F'">
11273
+ @if (largeTileOptions.includes(selection.displayOptionControl) || smallTileOptions.includes(selection.displayOptionControl)) {
11274
+ @for (child of listOfChoices | slice:0:amountOfTilesToShow; track trackBySelectionIdFn($index, child)) {
11275
+ <div
11276
+ class="selector-option-wrapper"
11277
+ [class.active]="child.selected ==='F'"
11278
+ [class.exception]="child.selected ==='F' && markAsException">
11023
11279
  <co-product-configurator-selector-option-tile
11280
+ visibilityObserver
11281
+ #intersection="intersection"
11282
+ [observerEnabled]="true"
11283
+ [showing]="intersection.isIntersecting"
11024
11284
  [option]="child"
11025
- [noLabel]="this.selection.displayOptionControl === configurationDisplayOption.SmallCircle || this.selection.displayOptionControl === configurationDisplayOption.SmallSquare"
11026
- [tileClass]="getTileClass()"
11027
- (selectionClicked)="selectionClicked(child)"
11285
+ [markAsException]="markAsException"
11286
+ [noLabel]="selection.displayOptionControl === configurationDisplayOption.SmallCircle || selection.displayOptionControl === configurationDisplayOption.SmallSquare"
11287
+ [tileClass]="selection.displayOptionControl"
11288
+ (selectionClicked)="handleSelectionClicked(child)"
11028
11289
  ></co-product-configurator-selector-option-tile>
11029
11290
  </div>
11030
11291
  }
11031
11292
  }
11032
-
11033
- @if (this.selection.displayOptionControl === configurationDisplayOption.DropDown) {
11293
+ @if (selection.displayOptionControl === configurationDisplayOption.DropDown) {
11034
11294
  <co-product-configurator-selector-option-dropdown
11035
11295
  [options]="listOfChoices"
11036
- (selectionClicked)="selectionClicked($event)"
11296
+ (selectionClicked)="handleSelectionClicked($event)"
11037
11297
  ></co-product-configurator-selector-option-dropdown>
11038
11298
  }
11039
11299
  </div>
11040
-
11041
- @if (
11042
- (this.largeTileOptions.includes(this.selection.displayOptionControl) ||
11043
- this.smallTileOptions.includes(this.selection.displayOptionControl)) && groupedSubShow) {
11300
+ @if (showViewMoreButton && (largeTileOptions.includes(selection.displayOptionControl) || smallTileOptions.includes(selection.displayOptionControl))) {
11044
11301
  @if (!showAllTiles && remainingTilesCount > 0) {
11045
11302
  <div class="show-more-container">
11046
11303
  <span (click)="showMore()">
@@ -11056,19 +11313,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
11056
11313
  </div>
11057
11314
  }
11058
11315
  }
11059
-
11060
- `,
11316
+ `,
11061
11317
  encapsulation: ViewEncapsulation.None,
11062
- animations: [
11063
- trigger('showSelections', [
11064
- state('void', style({ 'transform': 'translateX(100%)', opacity: 0 })),
11065
- state('*', style({ 'transform': 'translateX(0%)', opacity: 1 })),
11066
- transition('void <=> *', animate(200))
11067
- ])
11068
- ],
11069
11318
  standalone: false
11070
11319
  }]
11071
- }], ctorParameters: () => [{ type: ConfiguratorConnectorService }, { type: ConfiguratorSettingsService }, { type: ProductConfiguratorService }], propDecorators: { showClass: [{
11320
+ }], ctorParameters: () => [{ type: ConfiguratorConnectorService }, { type: ConfiguratorSettingsService }, { type: ConfiguratorEventService }], propDecorators: { showClass: [{
11072
11321
  type: HostBinding,
11073
11322
  args: ['class.co-product-configurator-selector-option']
11074
11323
  }], selection: [{
@@ -11077,80 +11326,589 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
11077
11326
  type: Input
11078
11327
  }], markAsException: [{
11079
11328
  type: Input
11080
- }], showGlobalAll: [{
11329
+ }], limitAmountOfTiles: [{
11330
+ type: Input
11331
+ }], maxVisibleTiles: [{
11332
+ type: Input
11333
+ }], maxVisibleSmallTiles: [{
11334
+ type: Input
11335
+ }], selectionClicked: [{
11336
+ type: Output
11337
+ }] } });
11338
+
11339
+ class ProductConfiguratorRepeatButtonsComponent {
11340
+ iconCacheService;
11341
+ icons = IconEnum;
11342
+ showClass() {
11343
+ return true;
11344
+ }
11345
+ showRepeatButton = false;
11346
+ showDeleteButton = false;
11347
+ repeatClicked = new EventEmitter();
11348
+ deleteClicked = new EventEmitter();
11349
+ constructor(iconCacheService) {
11350
+ this.iconCacheService = iconCacheService;
11351
+ }
11352
+ handleRepeatClick() {
11353
+ this.repeatClicked.emit();
11354
+ }
11355
+ handleDeleteClick() {
11356
+ this.deleteClicked.emit();
11357
+ }
11358
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorRepeatButtonsComponent, deps: [{ token: IconCacheService }], target: i0.ɵɵFactoryTarget.Component });
11359
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ProductConfiguratorRepeatButtonsComponent, isStandalone: false, selector: "co-product-configurator-repeat-buttons", inputs: { showRepeatButton: "showRepeatButton", showDeleteButton: "showDeleteButton" }, outputs: { repeatClicked: "repeatClicked", deleteClicked: "deleteClicked" }, host: { properties: { "class.co-product-configurator-repeat-buttons": "this.showClass" } }, ngImport: i0, template: `
11360
+ @if (showRepeatButton || showDeleteButton) {
11361
+ <div class="button-container">
11362
+ @if (showRepeatButton) {
11363
+ <div class="repeat-button-container">
11364
+ <co-button
11365
+ [iconData]="iconCacheService.getIcon(icons.AddButton)"
11366
+ [label]="'ADD_ELEMENT' | localize:false | async"
11367
+ (onClick)="handleRepeatClick()"
11368
+ ></co-button>
11369
+ </div>
11370
+ }
11371
+
11372
+ @if (showDeleteButton) {
11373
+ <!-- <div class="delete-button-container">-->
11374
+ <!-- <co-button-->
11375
+ <!-- [iconData]="iconCacheService.getIcon(icons.DeleteButton)"-->
11376
+ <!-- (onClick)="handleDeleteClick()"-->
11377
+ <!-- ></co-button>-->
11378
+ <!-- </div>-->
11379
+ }
11380
+ </div>
11381
+ }
11382
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
11383
+ }
11384
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorRepeatButtonsComponent, decorators: [{
11385
+ type: Component,
11386
+ args: [{
11387
+ selector: 'co-product-configurator-repeat-buttons',
11388
+ template: `
11389
+ @if (showRepeatButton || showDeleteButton) {
11390
+ <div class="button-container">
11391
+ @if (showRepeatButton) {
11392
+ <div class="repeat-button-container">
11393
+ <co-button
11394
+ [iconData]="iconCacheService.getIcon(icons.AddButton)"
11395
+ [label]="'ADD_ELEMENT' | localize:false | async"
11396
+ (onClick)="handleRepeatClick()"
11397
+ ></co-button>
11398
+ </div>
11399
+ }
11400
+
11401
+ @if (showDeleteButton) {
11402
+ <!-- <div class="delete-button-container">-->
11403
+ <!-- <co-button-->
11404
+ <!-- [iconData]="iconCacheService.getIcon(icons.DeleteButton)"-->
11405
+ <!-- (onClick)="handleDeleteClick()"-->
11406
+ <!-- ></co-button>-->
11407
+ <!-- </div>-->
11408
+ }
11409
+ </div>
11410
+ }
11411
+ `,
11412
+ standalone: false,
11413
+ encapsulation: ViewEncapsulation.None
11414
+ }]
11415
+ }], ctorParameters: () => [{ type: IconCacheService }], propDecorators: { showClass: [{
11416
+ type: HostBinding,
11417
+ args: ['class.co-product-configurator-repeat-buttons']
11418
+ }], showRepeatButton: [{
11419
+ type: Input
11420
+ }], showDeleteButton: [{
11421
+ type: Input
11422
+ }], repeatClicked: [{
11423
+ type: Output
11424
+ }], deleteClicked: [{
11425
+ type: Output
11426
+ }] } });
11427
+
11428
+ class ProductConfiguratorSelectorChildArticleComponent {
11429
+ configuratorConnectorService;
11430
+ iconService;
11431
+ _appEventService;
11432
+ icons = IconEnum;
11433
+ showClass() {
11434
+ return true;
11435
+ }
11436
+ selection;
11437
+ listOfChoices;
11438
+ options;
11439
+ repeatedOptions;
11440
+ markAsException = false;
11441
+ selectionClick = new EventEmitter();
11442
+ constructor(configuratorConnectorService, iconService, _appEventService) {
11443
+ this.configuratorConnectorService = configuratorConnectorService;
11444
+ this.iconService = iconService;
11445
+ this._appEventService = _appEventService;
11446
+ }
11447
+ handleOpenChildOptions(selection) {
11448
+ // I have no clue anymore, but on this level could also be a skip cancel that does not need to open a slideout, but just navigateto
11449
+ // This only applies when opvid === 0 and only works for java backend
11450
+ if (selection.opvId === 0) {
11451
+ this.selectionClick.emit(selection);
11452
+ }
11453
+ else {
11454
+ let articleNoChildren = false;
11455
+ if (this.options && this.options.length > 0) {
11456
+ this.options.forEach(option => {
11457
+ if (option.selector.selNodeId === selection.selNodeId && option.selector.nodeType === NodeType.Article) {
11458
+ if (option.selectorOptions && option.selectorOptions.length === 0) {
11459
+ articleNoChildren = true;
11460
+ }
11461
+ }
11462
+ });
11463
+ }
11464
+ // Repeated check aswell
11465
+ if (this.repeatedOptions && this.repeatedOptions.length > 0) {
11466
+ this.repeatedOptions.forEach(option => {
11467
+ if (option.selectorOptions && option.selectorOptions.length > 0) {
11468
+ option.selectorOptions.forEach(child => {
11469
+ if (child.selector.selNodeId === selection.selNodeId && child.selector.nodeType === NodeType.Article) {
11470
+ if (child.selectorOptions && child.selectorOptions.length === 0) {
11471
+ articleNoChildren = true;
11472
+ }
11473
+ }
11474
+ });
11475
+ }
11476
+ });
11477
+ }
11478
+ if (selection.nodeType === NodeType.Article && !articleNoChildren) {
11479
+ const event = {
11480
+ open: true,
11481
+ selNodeId: selection.selNodeId,
11482
+ selection: this.selection,
11483
+ options: this.options,
11484
+ repeatedOptions: this.repeatedOptions,
11485
+ };
11486
+ this._appEventService.openSlideOut.next(event);
11487
+ }
11488
+ else {
11489
+ this.selectionClick.emit(selection);
11490
+ }
11491
+ }
11492
+ }
11493
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorChildArticleComponent, deps: [{ token: ConfiguratorConnectorService }, { token: IconCacheService }, { token: ConfiguratorEventService }], target: i0.ɵɵFactoryTarget.Component });
11494
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.18", type: ProductConfiguratorSelectorChildArticleComponent, isStandalone: false, selector: "co-product-configurator-selector-child-article", inputs: { selection: "selection", listOfChoices: "listOfChoices", options: "options", repeatedOptions: "repeatedOptions", markAsException: "markAsException" }, outputs: { selectionClick: "selectionClick" }, host: { properties: { "class.co-product-configurator-selector-child-article": "this.showClass" } }, ngImport: i0, template: `
11495
+ <div class="product-configurator-selector-child-article-container">
11496
+ <div class="product-configurator-selector-child-article-container-headers">
11497
+ <co-product-configurator-selector-option
11498
+ [selection]="selection"
11499
+ [listOfChoices]="listOfChoices"
11500
+ [markAsException]="markAsException"
11501
+ (selectionClicked)="handleOpenChildOptions($event)">
11502
+ </co-product-configurator-selector-option>
11503
+ </div>
11504
+ </div>
11505
+ `, isInline: true, dependencies: [{ kind: "component", type: ProductConfiguratorSelectorOptionComponent, selector: "co-product-configurator-selector-option", inputs: ["selection", "listOfChoices", "markAsException", "limitAmountOfTiles", "maxVisibleTiles", "maxVisibleSmallTiles"], outputs: ["selectionClicked"] }], encapsulation: i0.ViewEncapsulation.None });
11506
+ }
11507
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorChildArticleComponent, decorators: [{
11508
+ type: Component,
11509
+ args: [{
11510
+ selector: 'co-product-configurator-selector-child-article',
11511
+ template: `
11512
+ <div class="product-configurator-selector-child-article-container">
11513
+ <div class="product-configurator-selector-child-article-container-headers">
11514
+ <co-product-configurator-selector-option
11515
+ [selection]="selection"
11516
+ [listOfChoices]="listOfChoices"
11517
+ [markAsException]="markAsException"
11518
+ (selectionClicked)="handleOpenChildOptions($event)">
11519
+ </co-product-configurator-selector-option>
11520
+ </div>
11521
+ </div>
11522
+ `,
11523
+ standalone: false,
11524
+ encapsulation: ViewEncapsulation.None
11525
+ }]
11526
+ }], ctorParameters: () => [{ type: ConfiguratorConnectorService }, { type: IconCacheService }, { type: ConfiguratorEventService }], propDecorators: { showClass: [{
11527
+ type: HostBinding,
11528
+ args: ['class.co-product-configurator-selector-child-article']
11529
+ }], selection: [{
11530
+ type: Input
11531
+ }], listOfChoices: [{
11532
+ type: Input
11533
+ }], options: [{
11534
+ type: Input
11535
+ }], repeatedOptions: [{
11536
+ type: Input
11537
+ }], markAsException: [{
11538
+ type: Input
11539
+ }], selectionClick: [{
11540
+ type: Output
11541
+ }] } });
11542
+
11543
+ class ProductConfiguratorGroupedRepeatableOptionsComponent {
11544
+ configuratorConnectorService;
11545
+ iconCacheService;
11546
+ _appEventService;
11547
+ icons = IconEnum;
11548
+ showClass() {
11549
+ return true;
11550
+ }
11551
+ selection;
11552
+ listOfChoices;
11553
+ repeatedOptions;
11554
+ selectionIndex;
11555
+ options;
11556
+ selectionClick = new EventEmitter();
11557
+ newSelection;
11558
+ optionGroups = [];
11559
+ showAllElements = true;
11560
+ showRepeatedOption = true;
11561
+ _subs = [];
11562
+ constructor(configuratorConnectorService, iconCacheService, _appEventService) {
11563
+ this.configuratorConnectorService = configuratorConnectorService;
11564
+ this.iconCacheService = iconCacheService;
11565
+ this._appEventService = _appEventService;
11566
+ this._subs.push(this._appEventService.checkHiddenRepeatItem.subscribe(selection => {
11567
+ this._handleCheckRepeats(selection);
11568
+ }));
11569
+ }
11570
+ ngOnInit() {
11571
+ this.buildOptionGroups();
11572
+ setTimeout(() => {
11573
+ const el = this.newSelection?.nativeElement;
11574
+ const container = el?.closest('.product-configurator-details');
11575
+ if (el && container) {
11576
+ const offset = 400;
11577
+ const top = el.getBoundingClientRect().top - container.getBoundingClientRect().top + container.scrollTop - offset;
11578
+ container.scrollTo({ top, behavior: 'smooth' });
11579
+ }
11580
+ });
11581
+ }
11582
+ ngOnDestroy() {
11583
+ this._subs.forEach(s => s.unsubscribe());
11584
+ }
11585
+ hasSelectedItem(options) {
11586
+ return options.some(o => o.selected === 'F');
11587
+ }
11588
+ handleSwitchView(showAll) {
11589
+ this.showAllElements = showAll;
11590
+ this.optionGroups = [];
11591
+ this.buildOptionGroups();
11592
+ }
11593
+ handleSelectionClicked(selection, group) {
11594
+ let articleNoChildren = false;
11595
+ if (this.options && this.options.length > 0) {
11596
+ this.options.forEach(option => {
11597
+ if (option.selector.selNodeId === selection.selNodeId && option.selector.nodeType === NodeType.Article) {
11598
+ if (option.selectorOptions && option.selectorOptions.length === 0) {
11599
+ articleNoChildren = true;
11600
+ }
11601
+ }
11602
+ });
11603
+ }
11604
+ // Repeated check aswell
11605
+ if (this.repeatedOptions && this.repeatedOptions.length > 0) {
11606
+ this.repeatedOptions.forEach(option => {
11607
+ if (option.selectorOptions && option.selectorOptions.length > 0) {
11608
+ option.selectorOptions.forEach(child => {
11609
+ if (child.selector.selNodeId === selection.selNodeId && child.selector.nodeType === NodeType.Article) {
11610
+ if (child.selectorOptions && child.selectorOptions.length === 0) {
11611
+ articleNoChildren = true;
11612
+ }
11613
+ }
11614
+ });
11615
+ }
11616
+ });
11617
+ }
11618
+ if (selection.nodeType === NodeType.Article && !articleNoChildren) {
11619
+ this.handleOpenChildOptions(selection, group);
11620
+ }
11621
+ else {
11622
+ this.selectionClick.emit(selection);
11623
+ }
11624
+ }
11625
+ buildOptionGroups() {
11626
+ // Base choices get their own group using the parent selector
11627
+ if (this.listOfChoices?.length > 0) {
11628
+ this.optionGroups.push({
11629
+ selector: this.selection,
11630
+ options: [...this.listOfChoices]
11631
+ });
11632
+ }
11633
+ // Each repeatedOptions entry gets its own isolated group
11634
+ if (this.repeatedOptions?.length > 0) {
11635
+ this.repeatedOptions.forEach(repeat => {
11636
+ if (repeat.selectorOptions?.length > 0) {
11637
+ this.optionGroups.push({
11638
+ selector: repeat.selector,
11639
+ options: repeat.selectorOptions.map(o => o.selector)
11640
+ });
11641
+ }
11642
+ });
11643
+ }
11644
+ if (!this.showAllElements) {
11645
+ // filter out the not selected ones
11646
+ this.optionGroups.forEach(group => {
11647
+ if (group.options && group.options.length > 0) {
11648
+ group.options.forEach(choice => {
11649
+ if (choice.selected === 'F') {
11650
+ group.options = [choice];
11651
+ }
11652
+ });
11653
+ }
11654
+ });
11655
+ }
11656
+ // New addition, when there is only 1 group (the default one) and the selected value is 'skip/ cancel' they do not want to show the group.
11657
+ // Hide the group until the user clicks 'Add element', then show this option.
11658
+ if (this.optionGroups.length === 1) {
11659
+ if (this.optionGroups[0].options.length > 0) {
11660
+ this.optionGroups[0].options.forEach(option => {
11661
+ if (option.opvId === 0 && option.selected === 'F') {
11662
+ this.showRepeatedOption = false;
11663
+ }
11664
+ });
11665
+ }
11666
+ }
11667
+ }
11668
+ handleOpenChildOptions(selection, group) {
11669
+ if (selection.opvId === 0) {
11670
+ this.selectionClick.emit(selection);
11671
+ }
11672
+ else {
11673
+ const event = {
11674
+ open: true,
11675
+ selNodeId: selection.selNodeId,
11676
+ selection: this.selection,
11677
+ options: this.options,
11678
+ repeatedOptions: this.repeatedOptions
11679
+ };
11680
+ this._appEventService.openSlideOut.next(event);
11681
+ }
11682
+ }
11683
+ _handleCheckRepeats(selection) {
11684
+ if (this.selection.id === selection.id) {
11685
+ this.showRepeatedOption = true;
11686
+ }
11687
+ }
11688
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorGroupedRepeatableOptionsComponent, deps: [{ token: ConfiguratorConnectorService }, { token: IconCacheService }, { token: ConfiguratorEventService }], target: i0.ɵɵFactoryTarget.Component });
11689
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ProductConfiguratorGroupedRepeatableOptionsComponent, isStandalone: false, selector: "co-product-configurator-grouped-repeatable-options", inputs: { selection: "selection", listOfChoices: "listOfChoices", repeatedOptions: "repeatedOptions", selectionIndex: "selectionIndex", options: "options" }, outputs: { selectionClick: "selectionClick" }, host: { properties: { "class.co-product-configurator-grouped-repeatable-options": "this.showClass" } }, viewQueries: [{ propertyName: "newSelection", first: true, predicate: ["newSelection"], descendants: true }], ngImport: i0, template: `
11690
+ <div class="product-configurator-grouped-repeatable-options-container" [class.repeatable-options-hidden]="!showRepeatedOption">
11691
+ <div class="grouped-repeatable-display-tabs">
11692
+ <co-button
11693
+ class="left-button"
11694
+ [class.active-button]="showAllElements"
11695
+ [label]="'SHOW_ALL_ELEMENTS' | localize: false | async"
11696
+ (onClick)="handleSwitchView(true)"
11697
+ ></co-button>
11698
+ <co-button
11699
+ class="right-button"
11700
+ [class.active-button]="!showAllElements"
11701
+ [label]="'SHOW_ACTIVE_ELEMENTS' | localize: false | async"
11702
+ (onClick)="handleSwitchView(false)"
11703
+ ></co-button>
11704
+ </div>
11705
+ <div class="grouped-repeatable-display-body">
11706
+ @if (optionGroups && optionGroups.length > 1) {
11707
+ <div class="repeat-explainer">
11708
+ <div class="info-icon">
11709
+ <co-icon
11710
+ [iconData]="iconCacheService.getIcon(icons.InfoSolidFull)"
11711
+ ></co-icon>
11712
+ </div>
11713
+ @if (showAllElements) {
11714
+ <div class="info-text" [textContent]="'REPEAT_ELEMENTS_EXPLAINER' | localize: false | async">
11715
+ </div>
11716
+ }
11717
+ @if (!showAllElements) {
11718
+ <div class="info-text" [textContent]="'CHANGE_ELEMENTS_EXPLAINER' | localize: false | async">
11719
+ </div>
11720
+ }
11721
+ </div>
11722
+ }
11723
+ <div class="grouped-repeatable-items" [class.show-filtered]="!showAllElements">
11724
+ @for (group of optionGroups; track group.selector.id; let index = $index) {
11725
+ @if (!hasSelectedItem(group.options)) {
11726
+ <div #newSelection></div>
11727
+ }
11728
+ <div class="grouped-items-container">
11729
+ @if (optionGroups && optionGroups.length > 1 && showAllElements) {
11730
+ <div class="index-indicator">
11731
+ <div [textContent]="selectionIndex.toString() | append: '.' | append: (index + 1).toString()"></div>
11732
+ </div>
11733
+ }
11734
+ <div class="selector-options">
11735
+ <co-product-configurator-selector-option
11736
+ [class.co-product-configurator-selector-new-option]="!hasSelectedItem(group.options)"
11737
+ [selection]="group.selector"
11738
+ [listOfChoices]="group.options"
11739
+ (selectionClicked)="handleSelectionClicked($event, group)">
11740
+ </co-product-configurator-selector-option>
11741
+ </div>
11742
+ </div>
11743
+ }
11744
+ </div>
11745
+ </div>
11746
+ </div>
11747
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: ProductConfiguratorSelectorOptionComponent, selector: "co-product-configurator-selector-option", inputs: ["selection", "listOfChoices", "markAsException", "limitAmountOfTiles", "maxVisibleTiles", "maxVisibleSmallTiles"], outputs: ["selectionClicked"] }, { kind: "component", type: i4.ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AppendPipe, name: "append" }], encapsulation: i0.ViewEncapsulation.None });
11748
+ }
11749
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorGroupedRepeatableOptionsComponent, decorators: [{
11750
+ type: Component,
11751
+ args: [{
11752
+ selector: 'co-product-configurator-grouped-repeatable-options',
11753
+ template: `
11754
+ <div class="product-configurator-grouped-repeatable-options-container" [class.repeatable-options-hidden]="!showRepeatedOption">
11755
+ <div class="grouped-repeatable-display-tabs">
11756
+ <co-button
11757
+ class="left-button"
11758
+ [class.active-button]="showAllElements"
11759
+ [label]="'SHOW_ALL_ELEMENTS' | localize: false | async"
11760
+ (onClick)="handleSwitchView(true)"
11761
+ ></co-button>
11762
+ <co-button
11763
+ class="right-button"
11764
+ [class.active-button]="!showAllElements"
11765
+ [label]="'SHOW_ACTIVE_ELEMENTS' | localize: false | async"
11766
+ (onClick)="handleSwitchView(false)"
11767
+ ></co-button>
11768
+ </div>
11769
+ <div class="grouped-repeatable-display-body">
11770
+ @if (optionGroups && optionGroups.length > 1) {
11771
+ <div class="repeat-explainer">
11772
+ <div class="info-icon">
11773
+ <co-icon
11774
+ [iconData]="iconCacheService.getIcon(icons.InfoSolidFull)"
11775
+ ></co-icon>
11776
+ </div>
11777
+ @if (showAllElements) {
11778
+ <div class="info-text" [textContent]="'REPEAT_ELEMENTS_EXPLAINER' | localize: false | async">
11779
+ </div>
11780
+ }
11781
+ @if (!showAllElements) {
11782
+ <div class="info-text" [textContent]="'CHANGE_ELEMENTS_EXPLAINER' | localize: false | async">
11783
+ </div>
11784
+ }
11785
+ </div>
11786
+ }
11787
+ <div class="grouped-repeatable-items" [class.show-filtered]="!showAllElements">
11788
+ @for (group of optionGroups; track group.selector.id; let index = $index) {
11789
+ @if (!hasSelectedItem(group.options)) {
11790
+ <div #newSelection></div>
11791
+ }
11792
+ <div class="grouped-items-container">
11793
+ @if (optionGroups && optionGroups.length > 1 && showAllElements) {
11794
+ <div class="index-indicator">
11795
+ <div [textContent]="selectionIndex.toString() | append: '.' | append: (index + 1).toString()"></div>
11796
+ </div>
11797
+ }
11798
+ <div class="selector-options">
11799
+ <co-product-configurator-selector-option
11800
+ [class.co-product-configurator-selector-new-option]="!hasSelectedItem(group.options)"
11801
+ [selection]="group.selector"
11802
+ [listOfChoices]="group.options"
11803
+ (selectionClicked)="handleSelectionClicked($event, group)">
11804
+ </co-product-configurator-selector-option>
11805
+ </div>
11806
+ </div>
11807
+ }
11808
+ </div>
11809
+ </div>
11810
+ </div>
11811
+ `,
11812
+ standalone: false,
11813
+ encapsulation: ViewEncapsulation.None
11814
+ }]
11815
+ }], ctorParameters: () => [{ type: ConfiguratorConnectorService }, { type: IconCacheService }, { type: ConfiguratorEventService }], propDecorators: { showClass: [{
11816
+ type: HostBinding,
11817
+ args: ['class.co-product-configurator-grouped-repeatable-options']
11818
+ }], selection: [{
11819
+ type: Input
11820
+ }], listOfChoices: [{
11821
+ type: Input
11822
+ }], repeatedOptions: [{
11081
11823
  type: Input
11082
- }], groupedSubShow: [{
11824
+ }], selectionIndex: [{
11825
+ type: Input
11826
+ }], options: [{
11083
11827
  type: Input
11828
+ }], selectionClick: [{
11829
+ type: Output
11830
+ }], newSelection: [{
11831
+ type: ViewChild,
11832
+ args: ['newSelection']
11084
11833
  }] } });
11085
11834
 
11086
11835
  class ProductConfiguratorSelectorComponent {
11087
11836
  configuratorConnectorService;
11088
11837
  settingsService;
11089
11838
  iconService;
11090
- get hostClasses() {
11091
- const classes = [
11092
- 'co-product-configurator-selector',
11093
- `treelevel-${this.treeLevelIndex}`
11094
- ];
11095
- if (!this._shouldBeVisible()) {
11096
- classes.push('hidden-frontend');
11097
- }
11098
- return classes.join(' ');
11839
+ _appEventService;
11840
+ showClass() {
11841
+ return true;
11099
11842
  }
11100
11843
  icons = IconEnum;
11101
11844
  exceptionContainer;
11102
11845
  selection;
11103
11846
  options;
11847
+ repeatedOptions;
11104
11848
  lastNodeWithChildren;
11849
+ set markForUserInput(mark) {
11850
+ this._markForUserInput = mark;
11851
+ this._handleMarkInput(mark);
11852
+ }
11853
+ get markForUserInput() {
11854
+ return this._markForUserInput;
11855
+ }
11105
11856
  selectionIndex;
11106
11857
  treeLevelIndex = 1;
11107
- isActive = true;
11108
11858
  markAsException = false;
11109
- showAll = false;
11110
- suppressSubShowMore = false;
11111
- useGroupedParentVisibility = false;
11859
+ hasArticlesAsChildren = false;
11112
11860
  activate = new EventEmitter();
11113
- selectionClass = '';
11861
+ openSlideOutClick = new EventEmitter();
11114
11862
  listOfChoices = [];
11115
11863
  activeChildIndex = 0;
11116
- localShowAll = false;
11117
- get selectionIndexText() {
11118
- return this.selectionIndex + '. ';
11119
- }
11120
- get expandButtonText() {
11121
- if (this.getChildShowAll()) {
11122
- return 'VIEW_LESS';
11123
- }
11124
- return this.groupedRemainingTilesCount > 0
11125
- ? `SHOW_ALL`
11126
- : 'SHOW_ALL';
11127
- }
11128
- get suppressSubShowMoreForChildren() {
11129
- return this.suppressSubShowMore || this.isGroupedSection();
11130
- }
11131
- get groupedRemainingTilesCount() {
11132
- if (!this.isGroupedSection() || this.getChildShowAll()) {
11133
- return 0;
11134
- }
11135
- return this._countGroupedTilesToReveal(this.options);
11136
- }
11137
- get useGroupedVisibilityForChildren() {
11138
- return this.useGroupedParentVisibility || this.isGroupedSection();
11139
- }
11140
- constructor(configuratorConnectorService, settingsService, iconService) {
11864
+ showAnswerGrouped = true;
11865
+ limitStartView = false;
11866
+ limitAmountOfTiles = false;
11867
+ sliceAmount = 2;
11868
+ amountOfGroupsToShow = 2;
11869
+ maxVisibleTiles = 5;
11870
+ maxVisibleSmallTiles = 7;
11871
+ totalOptionCount = 0;
11872
+ selectableOption = true;
11873
+ callRepeatOption;
11874
+ activeSelection = 0;
11875
+ _markForUserInput;
11876
+ _subs = [];
11877
+ constructor(configuratorConnectorService, settingsService, iconService, _appEventService) {
11141
11878
  this.configuratorConnectorService = configuratorConnectorService;
11142
11879
  this.settingsService = settingsService;
11143
11880
  this.iconService = iconService;
11881
+ this._appEventService = _appEventService;
11882
+ this._subs.push(this._appEventService.checkForMarkedInputs.subscribe(check => {
11883
+ this.markForUserInput = check;
11884
+ this._handleMarkInput(check);
11885
+ }), this._appEventService.showAllConfigurationOptions.subscribe(show => {
11886
+ this.handleLimitedViewMode();
11887
+ }));
11144
11888
  }
11145
11889
  ngOnInit() {
11890
+ this.showAnswerGrouped = this.selection.showGrouped;
11146
11891
  if (this.selection && this.selection.displayOptionControl == null) {
11147
11892
  this.selection.displayOptionControl = ConfigurationDisplayOption.TileLarge;
11148
11893
  }
11149
- this.selectionClass = 'selection-container-' + this.selection.displayOptionControl;
11150
- if (this.lastNodeWithChildren) {
11894
+ // When the opvId === 0 it means that we got a skip/ cancel option and if there are no other options to choice from, we should hide this
11895
+ if (this.options.length === 1) {
11896
+ if (this.options[0].selector.opvId === 0 && this.options[0].selectorOptions.length === 0) {
11897
+ this.selectableOption = false;
11898
+ }
11899
+ }
11900
+ // This is filling the 'tile' data in case there are no nested articles
11901
+ if (this.lastNodeWithChildren) {
11902
+ for (const option of this.options) {
11903
+ if (option.selector) {
11904
+ this.listOfChoices.push(option.selector);
11905
+ }
11906
+ }
11907
+ }
11908
+ // This is the case when we DO have nested articles
11909
+ if (!this.lastNodeWithChildren && this.hasArticlesAsChildren) {
11151
11910
  for (const option of this.options) {
11152
11911
  if (option.selector) {
11153
- this.configuratorConnectorService.getImageForAnswer(option.selector);
11154
11912
  this.listOfChoices.push(option.selector);
11155
11913
  }
11156
11914
  }
@@ -11158,15 +11916,35 @@ class ProductConfiguratorSelectorComponent {
11158
11916
  if (this.markAsException) {
11159
11917
  this.showAndScroll();
11160
11918
  }
11161
- this._setActiveChildIndexFromSelection();
11919
+ this.handleLimitedViewMode();
11162
11920
  }
11163
- ngOnChanges(changes) {
11164
- if (changes.options && !changes.options.firstChange) {
11165
- this._setActiveChildIndexFromSelection();
11166
- }
11167
- if (changes.showAll && !changes.showAll.firstChange) {
11168
- this._setActiveChildIndexFromSelection();
11921
+ ngOnDestroy() {
11922
+ this._subs.forEach(s => s.unsubscribe());
11923
+ }
11924
+ handleLimitedViewMode() {
11925
+ this.limitStartView = this.settingsService.settings.options.limitStartView;
11926
+ this.limitAmountOfTiles = this.settingsService.settings.options.limitAmountOfTiles;
11927
+ this.sliceAmount = this.options.length;
11928
+ if (this.limitStartView && this.options && this.options.length) {
11929
+ // amountOfGroupsToShow -> top level group
11930
+ if (this.settingsService.settings.options.amountOfGroupsToShow && this.treeLevelIndex >= 1) {
11931
+ if (this.options.length >= this.amountOfGroupsToShow) {
11932
+ this.sliceAmount = this.settingsService.settings.options.amountOfGroupsToShow;
11933
+ }
11934
+ }
11935
+ this.totalOptionCount = this._countGroupedTilesToReveal(this.options);
11169
11936
  }
11937
+ this.maxVisibleTiles = this.settingsService.settings.options.maxVisibleTiles;
11938
+ this.maxVisibleSmallTiles = this.settingsService.settings.options.maxVisibleSmallTiles;
11939
+ }
11940
+ /*
11941
+ *
11942
+ * When using the full config template, there are two ways to changing.
11943
+ * NavigateTo -> used for showGrouped true options, jumps the tree to some other point
11944
+ *
11945
+ * */
11946
+ handleNavigateTo(selection) {
11947
+ this._appEventService.selectSelection.next(selection);
11170
11948
  }
11171
11949
  showAndScroll() {
11172
11950
  setTimeout(() => {
@@ -11177,59 +11955,96 @@ class ProductConfiguratorSelectorComponent {
11177
11955
  this.activate.emit();
11178
11956
  }
11179
11957
  onShowAllClick() {
11180
- this.localShowAll = !this.localShowAll;
11181
- }
11182
- getIsChildVisible(index) {
11183
- if (!this.useGroupedVisibilityForChildren) {
11184
- return true;
11185
- }
11186
- if (this.getChildShowAll()) {
11187
- return true;
11188
- }
11189
- return index === this.activeChildIndex;
11190
- }
11191
- isGroupedSection() {
11192
- return this.treeLevelIndex === 1
11193
- && !this.lastNodeWithChildren
11194
- && this.settingsService.settings.options.groupedShowAllBtn
11195
- && Array.isArray(this.options)
11196
- && this.options.length > 1;
11197
- }
11198
- shouldShowExpandButton() {
11199
- return this.isGroupedSection();
11200
- }
11201
- getChildShowAll() {
11202
- return this.showAll || this.localShowAll;
11203
- }
11204
- _shouldBeVisible() {
11205
- if (!this.useGroupedVisibilityForChildren) {
11206
- return true;
11207
- }
11208
- if (this.getChildShowAll()) {
11209
- return true;
11210
- }
11211
- return this.isActive;
11212
- }
11213
- _setActiveChildIndexFromSelection() {
11214
- if (!Array.isArray(this.options) || this.options.length === 0) {
11215
- this.activeChildIndex = 0;
11216
- return;
11217
- }
11218
- const selectedIndex = this.options.findIndex(option => this._hasSelectedOption(option));
11219
- this.activeChildIndex = selectedIndex >= 0 ? selectedIndex : 0;
11220
- }
11221
- _hasSelectedOption(option) {
11222
- if (!option) {
11223
- return false;
11224
- }
11225
- if (option.selector && option.selector.selected === 'F') {
11226
- return true;
11958
+ // just limit it to all options so we loop through it all
11959
+ this.amountOfGroupsToShow = this.options.length;
11960
+ // TODO discuss
11961
+ // This is an hacky solution but;
11962
+ // the setting to check if we should limit the amount to show is in a global settings service.
11963
+ // but this is more like a state of loading thing and not a setting that should always be checked.
11964
+ // When clicking show all, we will just change the value of the session.
11965
+ this.settingsService.settings.options.limitStartView = false;
11966
+ this.settingsService.settings.options.limitAmountOfTiles = false;
11967
+ this.handleLimitedViewMode();
11968
+ this._appEventService.showAllConfigurationOptions.next(true);
11969
+ }
11970
+ handleRepeatClicked() {
11971
+ // Some information
11972
+ // When we have a repeatable option with skip cancel selected, we do not show this by default
11973
+ // So when the user clicks on add element, show the skipcancel one so the user can make a selection.
11974
+ // else, just call repeatOption and continue
11975
+ this.callRepeatOption = true;
11976
+ this.configuratorConnectorService.selectionWithAnswers.forEach(parent => {
11977
+ if (parent.selector.id === this.selection.id) {
11978
+ // see if the selected value === a skipperdoodle
11979
+ if (parent.selectorOptions && parent.selectorOptions.length > 0 && parent.repeatedOptions && parent.repeatedOptions.length === 0) {
11980
+ parent.selectorOptions.forEach(child => {
11981
+ if (child.selector.selected === 'F' && child.selector.opvId === 0) {
11982
+ this.callRepeatOption = false;
11983
+ this._appEventService.checkHiddenRepeatItem.next(this.selection);
11984
+ }
11985
+ });
11986
+ }
11987
+ }
11988
+ });
11989
+ if (this.callRepeatOption) {
11990
+ this.configuratorConnectorService.repeatOption(this.selection.optCycle, this.selection.id);
11991
+ }
11992
+ }
11993
+ handleDeleteClicked() {
11994
+ const tempSelection = this.selection;
11995
+ const nodeHierarchy = tempSelection.nodeHierarchy + '[0]';
11996
+ tempSelection.nodeHierarchy = nodeHierarchy;
11997
+ this.handleNavigateTo(tempSelection);
11998
+ }
11999
+ handleOpenSlideOut(event) {
12000
+ this.activeSelection = event.selNodeId;
12001
+ this.configuratorConnectorService.activeSlideOutParentId = this.activeSelection;
12002
+ this._appEventService.openSlideOut.next(event);
12003
+ }
12004
+ _handleMarkInput(mark) {
12005
+ // needs to handle repeated options as well!
12006
+ if (this.options && this.options.length > 0) {
12007
+ this.options.forEach(option => {
12008
+ if (option.selector.selNodeId === this.configuratorConnectorService.activeSlideOutParentId) {
12009
+ if (mark) {
12010
+ const event = {
12011
+ open: true,
12012
+ selNodeId: this.configuratorConnectorService.activeSlideOutParentId,
12013
+ selection: this.selection,
12014
+ options: this.options,
12015
+ repeatedOptions: this.repeatedOptions,
12016
+ activeSelection: this.activeSelection,
12017
+ markForUserInput: this.markForUserInput
12018
+ };
12019
+ this.handleOpenSlideOut(event);
12020
+ }
12021
+ }
12022
+ });
11227
12023
  }
11228
- if (!Array.isArray(option.selectorOptions) || option.selectorOptions.length === 0) {
11229
- return false;
12024
+ if (this.repeatedOptions && this.repeatedOptions.length > 0) {
12025
+ this.repeatedOptions.forEach(child => {
12026
+ if (child.selectorOptions && child.selectorOptions.length > 0) {
12027
+ child.selectorOptions.forEach(value => {
12028
+ if (value.selector.selNodeId === this.configuratorConnectorService.activeSlideOutParentId) {
12029
+ if (mark) {
12030
+ const event = {
12031
+ open: true,
12032
+ selNodeId: this.configuratorConnectorService.activeSlideOutParentId,
12033
+ selection: this.selection,
12034
+ options: this.options,
12035
+ repeatedOptions: this.repeatedOptions,
12036
+ activeSelection: this.activeSelection,
12037
+ markForUserInput: this.markForUserInput
12038
+ };
12039
+ this.handleOpenSlideOut(event);
12040
+ }
12041
+ }
12042
+ });
12043
+ }
12044
+ });
11230
12045
  }
11231
- return option.selectorOptions.some(childOption => this._hasSelectedOption(childOption));
11232
12046
  }
12047
+ // TODO review functions below this
11233
12048
  _countRemainingTiles(options) {
11234
12049
  if (!Array.isArray(options) || options.length === 0) {
11235
12050
  return 0;
@@ -11296,9 +12111,13 @@ class ProductConfiguratorSelectorComponent {
11296
12111
  }
11297
12112
  return 0;
11298
12113
  }
11299
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorComponent, deps: [{ token: ConfiguratorConnectorService }, { token: ConfiguratorSettingsService }, { token: IconCacheService }], target: i0.ɵɵFactoryTarget.Component });
11300
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ProductConfiguratorSelectorComponent, isStandalone: false, selector: "co-product-configurator-selector", inputs: { selection: "selection", options: "options", lastNodeWithChildren: "lastNodeWithChildren", selectionIndex: "selectionIndex", treeLevelIndex: "treeLevelIndex", isActive: "isActive", markAsException: "markAsException", showAll: "showAll", suppressSubShowMore: "suppressSubShowMore", useGroupedParentVisibility: "useGroupedParentVisibility" }, outputs: { activate: "activate" }, host: { properties: { "class": "this.hostClasses" } }, viewQueries: [{ propertyName: "exceptionContainer", first: true, predicate: ["exceptionContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
11301
- <div class="selector-container">
12114
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorComponent, deps: [{ token: ConfiguratorConnectorService }, { token: ConfiguratorSettingsService }, { token: IconCacheService }, { token: ConfiguratorEventService }], target: i0.ɵɵFactoryTarget.Component });
12115
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ProductConfiguratorSelectorComponent, isStandalone: false, selector: "co-product-configurator-selector", inputs: { selection: "selection", options: "options", repeatedOptions: "repeatedOptions", lastNodeWithChildren: "lastNodeWithChildren", markForUserInput: "markForUserInput", selectionIndex: "selectionIndex", treeLevelIndex: "treeLevelIndex", markAsException: "markAsException", hasArticlesAsChildren: "hasArticlesAsChildren" }, outputs: { activate: "activate", openSlideOutClick: "openSlideOutClick" }, host: { properties: { "class.co-product-configurator-selector": "this.showClass" } }, viewQueries: [{ propertyName: "exceptionContainer", first: true, predicate: ["exceptionContainer"], descendants: true }], ngImport: i0, template: `
12116
+ <div
12117
+ class="selector-container tree-level-{{treeLevelIndex}}"
12118
+ [class.hide-from-selector]="!selectableOption"
12119
+ [class.mark-for-input]="markForUserInput"
12120
+ >
11302
12121
  <!--
11303
12122
  Based on the threeLevel and the length op options we got a couple of flavours
11304
12123
  treeLevel 1 -> article, should not be used here
@@ -11307,96 +12126,119 @@ class ProductConfiguratorSelectorComponent {
11307
12126
  treeLevel 4 -> more like bold text, should be for something like 'the fabric group'
11308
12127
  treeLevel 5 -> just text head
11309
12128
  -->
11310
-
12129
+
11311
12130
  <div class="selector-container-header">
11312
12131
  @if (selection.treeLevel === 2 && options.length > 0) {
11313
12132
  <h2 class="selector-option-header">
11314
- <span [textContent]="selectionIndexText"></span>
12133
+ <span [textContent]="selectionIndex.toString() | append: '. '"></span>
11315
12134
  <span [textContent]="selection.nodeText ? selection.nodeText : selection.optionText | localize:true | async"></span>
11316
12135
  </h2>
11317
12136
  }
11318
-
11319
12137
  @if (selection.treeLevel === 3 && options.length > 0) {
11320
- <h3
11321
- class="selector-option-sub-header"
11322
- [textContent]="selection.nodeText | localize:true | async" (click)="onSubHeaderClick()"></h3>
12138
+ <h3 class="selector-option-sub-header" [textContent]="selection.nodeText | localize:true | async" (click)="onSubHeaderClick()"></h3>
11323
12139
  }
11324
-
11325
12140
  @if (selection.treeLevel === 4 && options.length > 0) {
11326
- <p
11327
- class="selector-option-bold-text-header"
11328
- [textContent]="selection.nodeText | localize:true | async"></p>
12141
+ <p class="selector-option-bold-text-header" [textContent]="selection.nodeText ? selection.nodeText: selection.optionText | localize:true | async"></p>
11329
12142
  }
11330
-
11331
12143
  @if (selection.treeLevel === 5 && options.length > 0) {
11332
- <p
11333
- class="selector-option-text-header"
11334
- [textContent]="selection.nodeText | localize:true | async"></p>
12144
+ <p class="selector-option-text-header" [textContent]="selection.nodeText | localize:true | async"></p>
11335
12145
  }
11336
-
11337
-
11338
12146
  @if (markAsException) {
11339
12147
  <span class="exception-icon" #exceptionContainer [title]="'CONFIGURATION_EXCEPTION_INFO' | localize:false | async">
11340
12148
  <co-icon [iconData]="iconService.getIcon(icons.TriangleExclamation)"></co-icon>
11341
12149
  </span>
11342
12150
  }
12151
+ @if (selection.repeatOptActive || selection.canBeDeleted) {
12152
+ <co-product-configurator-repeat-buttons
12153
+ [showRepeatButton]="selection.repeatOptActive"
12154
+ [showDeleteButton]="selection.canBeDeleted"
12155
+ (repeatClicked)="handleRepeatClicked()"
12156
+ (deleteClicked)="handleDeleteClicked()"
12157
+ ></co-product-configurator-repeat-buttons>
12158
+ }
11343
12159
  </div>
11344
-
11345
- @if (lastNodeWithChildren) {
12160
+
12161
+ @if (selection.repeatOptActive && lastNodeWithChildren && !hasArticlesAsChildren) {
12162
+ <co-product-configurator-grouped-repeatable-options
12163
+ [selection]="selection"
12164
+ [listOfChoices]="listOfChoices"
12165
+ [options]="options"
12166
+ [repeatedOptions]="repeatedOptions"
12167
+ [selectionIndex]="selectionIndex"
12168
+ (selectionClick)="handleNavigateTo($event)"
12169
+ ></co-product-configurator-grouped-repeatable-options>
12170
+ } @else if (lastNodeWithChildren) {
12171
+ <!-- Show the tiles now -->
11346
12172
  <co-product-configurator-selector-option
11347
12173
  [selection]="selection"
11348
12174
  [listOfChoices]="listOfChoices"
11349
- [groupedSubShow]="!suppressSubShowMoreForChildren"
11350
12175
  [markAsException]="markAsException"
11351
- [showGlobalAll]="getChildShowAll()">
12176
+ [limitAmountOfTiles]="limitAmountOfTiles"
12177
+ [maxVisibleTiles]="maxVisibleTiles"
12178
+ [maxVisibleSmallTiles]="maxVisibleSmallTiles"
12179
+ (selectionClicked)="handleNavigateTo($event)">
11352
12180
  </co-product-configurator-selector-option>
11353
12181
  }
12182
+
12183
+ @if (!lastNodeWithChildren && hasArticlesAsChildren) {
12184
+ <!-- When we have articles, we show show the user a nested view -->
12185
+ @if (selection.repeatOptActive) {
12186
+ <co-product-configurator-grouped-repeatable-options
12187
+ [selection]="selection"
12188
+ [listOfChoices]="listOfChoices"
12189
+ [repeatedOptions]="repeatedOptions"
12190
+ [options]="options"
12191
+ [selectionIndex]="selectionIndex"
12192
+ (selectionClick)="handleNavigateTo($event)"
12193
+ ></co-product-configurator-grouped-repeatable-options>
12194
+ } @else {
12195
+ <co-product-configurator-selector-child-article
12196
+ [selection]="selection"
12197
+ [listOfChoices]="listOfChoices"
12198
+ [options]="options"
12199
+ [repeatedOptions]="repeatedOptions"
12200
+ [markAsException]="markAsException"
12201
+ (selectionClick)="handleNavigateTo($event)">
12202
+ </co-product-configurator-selector-child-article>
12203
+ }
12204
+ }
11354
12205
  </div>
11355
-
11356
- @if (!lastNodeWithChildren) {
11357
- @for (displaySelection of options; track displaySelection; let index = $index) {
12206
+ @if (!lastNodeWithChildren && !hasArticlesAsChildren) {
12207
+ @for (displaySelection of options | slice:0:sliceAmount; track displaySelection.selector; let index = $index) {
11358
12208
  <co-product-configurator-selector
11359
12209
  [selection]="displaySelection.selector"
11360
12210
  [options]="displaySelection.selectorOptions"
12211
+ [repeatedOptions]="displaySelection.repeatedOptions"
11361
12212
  [lastNodeWithChildren]="displaySelection.lastNodeWithChildren"
11362
12213
  [selectionIndex]="index + 1"
11363
12214
  [treeLevelIndex]="treeLevelIndex + 1"
11364
- [showAll]="getChildShowAll()"
11365
- [isActive]="getIsChildVisible(index)"
11366
- [suppressSubShowMore]="suppressSubShowMoreForChildren"
11367
- [useGroupedParentVisibility]="useGroupedVisibilityForChildren"
11368
12215
  [markAsException]="displaySelection.markForExceptionNotification"
12216
+ [hasArticlesAsChildren]="displaySelection.selectorOptionsAreArticles"
12217
+ [markForUserInput]="displaySelection.markForUserInput"
11369
12218
  (activate)="activeChildIndex = index">
11370
12219
  </co-product-configurator-selector>
11371
12220
  }
11372
12221
  }
11373
- @if (shouldShowExpandButton()) {
12222
+ @if (limitStartView && treeLevelIndex === 1 && !lastNodeWithChildren && !hasArticlesAsChildren) {
11374
12223
  <div class="show-more-container" (click)="onShowAllClick()">
11375
- <span class="show-all-button show-more-text-link"
11376
- [textContent]="expandButtonText | localize:false | async">
11377
- </span>
11378
-
11379
- @if (this.groupedRemainingTilesCount > 0) {
11380
- <span class="show-all-button show-more-text-link counter"
11381
- [textContent]="'(' + this.groupedRemainingTilesCount + ')'">
11382
- </span>
12224
+ <span class="show-all-button show-more-text-link" [textContent]="'SHOW_ALL' | localize:false | async"></span>
12225
+ @if (totalOptionCount > 0) {
12226
+ <span class="show-all-button show-more-text-link counter" [textContent]="'(' + totalOptionCount + ')'"></span>
11383
12227
  }
11384
12228
  </div>
11385
12229
  }
11386
- `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: ProductConfiguratorSelectorOptionComponent, selector: "co-product-configurator-selector-option", inputs: ["selection", "listOfChoices", "markAsException", "showGlobalAll", "groupedSubShow"] }, { kind: "component", type: ProductConfiguratorSelectorComponent, selector: "co-product-configurator-selector", inputs: ["selection", "options", "lastNodeWithChildren", "selectionIndex", "treeLevelIndex", "isActive", "markAsException", "showAll", "suppressSubShowMore", "useGroupedParentVisibility"], outputs: ["activate"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], animations: [
11387
- trigger('showSelections', [
11388
- state('void', style({ 'transform': 'translateX(100%)', opacity: 0 })),
11389
- state('*', style({ 'transform': 'translateX(0%)', opacity: 1 })),
11390
- transition('void <=> *', animate(200))
11391
- ])
11392
- ], encapsulation: i0.ViewEncapsulation.None });
12230
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: ProductConfiguratorSelectorOptionComponent, selector: "co-product-configurator-selector-option", inputs: ["selection", "listOfChoices", "markAsException", "limitAmountOfTiles", "maxVisibleTiles", "maxVisibleSmallTiles"], outputs: ["selectionClicked"] }, { kind: "component", type: ProductConfiguratorRepeatButtonsComponent, selector: "co-product-configurator-repeat-buttons", inputs: ["showRepeatButton", "showDeleteButton"], outputs: ["repeatClicked", "deleteClicked"] }, { kind: "component", type: ProductConfiguratorSelectorComponent, selector: "co-product-configurator-selector", inputs: ["selection", "options", "repeatedOptions", "lastNodeWithChildren", "markForUserInput", "selectionIndex", "treeLevelIndex", "markAsException", "hasArticlesAsChildren"], outputs: ["activate", "openSlideOutClick"] }, { kind: "component", type: ProductConfiguratorSelectorChildArticleComponent, selector: "co-product-configurator-selector-child-article", inputs: ["selection", "listOfChoices", "options", "repeatedOptions", "markAsException"], outputs: ["selectionClick"] }, { kind: "component", type: ProductConfiguratorGroupedRepeatableOptionsComponent, selector: "co-product-configurator-grouped-repeatable-options", inputs: ["selection", "listOfChoices", "repeatedOptions", "selectionIndex", "options"], outputs: ["selectionClick"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6$1.SlicePipe, name: "slice" }, { kind: "pipe", type: i4.AppendPipe, name: "append" }], encapsulation: i0.ViewEncapsulation.None });
11393
12231
  }
11394
12232
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorComponent, decorators: [{
11395
12233
  type: Component,
11396
12234
  args: [{
11397
12235
  selector: 'co-product-configurator-selector',
11398
12236
  template: `
11399
- <div class="selector-container">
12237
+ <div
12238
+ class="selector-container tree-level-{{treeLevelIndex}}"
12239
+ [class.hide-from-selector]="!selectableOption"
12240
+ [class.mark-for-input]="markForUserInput"
12241
+ >
11400
12242
  <!--
11401
12243
  Based on the threeLevel and the length op options we got a couple of flavours
11402
12244
  treeLevel 1 -> article, should not be used here
@@ -11405,96 +12247,114 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
11405
12247
  treeLevel 4 -> more like bold text, should be for something like 'the fabric group'
11406
12248
  treeLevel 5 -> just text head
11407
12249
  -->
11408
-
12250
+
11409
12251
  <div class="selector-container-header">
11410
12252
  @if (selection.treeLevel === 2 && options.length > 0) {
11411
12253
  <h2 class="selector-option-header">
11412
- <span [textContent]="selectionIndexText"></span>
12254
+ <span [textContent]="selectionIndex.toString() | append: '. '"></span>
11413
12255
  <span [textContent]="selection.nodeText ? selection.nodeText : selection.optionText | localize:true | async"></span>
11414
12256
  </h2>
11415
12257
  }
11416
-
11417
12258
  @if (selection.treeLevel === 3 && options.length > 0) {
11418
- <h3
11419
- class="selector-option-sub-header"
11420
- [textContent]="selection.nodeText | localize:true | async" (click)="onSubHeaderClick()"></h3>
12259
+ <h3 class="selector-option-sub-header" [textContent]="selection.nodeText | localize:true | async" (click)="onSubHeaderClick()"></h3>
11421
12260
  }
11422
-
11423
12261
  @if (selection.treeLevel === 4 && options.length > 0) {
11424
- <p
11425
- class="selector-option-bold-text-header"
11426
- [textContent]="selection.nodeText | localize:true | async"></p>
12262
+ <p class="selector-option-bold-text-header" [textContent]="selection.nodeText ? selection.nodeText: selection.optionText | localize:true | async"></p>
11427
12263
  }
11428
-
11429
12264
  @if (selection.treeLevel === 5 && options.length > 0) {
11430
- <p
11431
- class="selector-option-text-header"
11432
- [textContent]="selection.nodeText | localize:true | async"></p>
12265
+ <p class="selector-option-text-header" [textContent]="selection.nodeText | localize:true | async"></p>
11433
12266
  }
11434
-
11435
-
11436
12267
  @if (markAsException) {
11437
12268
  <span class="exception-icon" #exceptionContainer [title]="'CONFIGURATION_EXCEPTION_INFO' | localize:false | async">
11438
12269
  <co-icon [iconData]="iconService.getIcon(icons.TriangleExclamation)"></co-icon>
11439
12270
  </span>
11440
12271
  }
12272
+ @if (selection.repeatOptActive || selection.canBeDeleted) {
12273
+ <co-product-configurator-repeat-buttons
12274
+ [showRepeatButton]="selection.repeatOptActive"
12275
+ [showDeleteButton]="selection.canBeDeleted"
12276
+ (repeatClicked)="handleRepeatClicked()"
12277
+ (deleteClicked)="handleDeleteClicked()"
12278
+ ></co-product-configurator-repeat-buttons>
12279
+ }
11441
12280
  </div>
11442
-
11443
- @if (lastNodeWithChildren) {
12281
+
12282
+ @if (selection.repeatOptActive && lastNodeWithChildren && !hasArticlesAsChildren) {
12283
+ <co-product-configurator-grouped-repeatable-options
12284
+ [selection]="selection"
12285
+ [listOfChoices]="listOfChoices"
12286
+ [options]="options"
12287
+ [repeatedOptions]="repeatedOptions"
12288
+ [selectionIndex]="selectionIndex"
12289
+ (selectionClick)="handleNavigateTo($event)"
12290
+ ></co-product-configurator-grouped-repeatable-options>
12291
+ } @else if (lastNodeWithChildren) {
12292
+ <!-- Show the tiles now -->
11444
12293
  <co-product-configurator-selector-option
11445
12294
  [selection]="selection"
11446
12295
  [listOfChoices]="listOfChoices"
11447
- [groupedSubShow]="!suppressSubShowMoreForChildren"
11448
12296
  [markAsException]="markAsException"
11449
- [showGlobalAll]="getChildShowAll()">
12297
+ [limitAmountOfTiles]="limitAmountOfTiles"
12298
+ [maxVisibleTiles]="maxVisibleTiles"
12299
+ [maxVisibleSmallTiles]="maxVisibleSmallTiles"
12300
+ (selectionClicked)="handleNavigateTo($event)">
11450
12301
  </co-product-configurator-selector-option>
11451
12302
  }
12303
+
12304
+ @if (!lastNodeWithChildren && hasArticlesAsChildren) {
12305
+ <!-- When we have articles, we show show the user a nested view -->
12306
+ @if (selection.repeatOptActive) {
12307
+ <co-product-configurator-grouped-repeatable-options
12308
+ [selection]="selection"
12309
+ [listOfChoices]="listOfChoices"
12310
+ [repeatedOptions]="repeatedOptions"
12311
+ [options]="options"
12312
+ [selectionIndex]="selectionIndex"
12313
+ (selectionClick)="handleNavigateTo($event)"
12314
+ ></co-product-configurator-grouped-repeatable-options>
12315
+ } @else {
12316
+ <co-product-configurator-selector-child-article
12317
+ [selection]="selection"
12318
+ [listOfChoices]="listOfChoices"
12319
+ [options]="options"
12320
+ [repeatedOptions]="repeatedOptions"
12321
+ [markAsException]="markAsException"
12322
+ (selectionClick)="handleNavigateTo($event)">
12323
+ </co-product-configurator-selector-child-article>
12324
+ }
12325
+ }
11452
12326
  </div>
11453
-
11454
- @if (!lastNodeWithChildren) {
11455
- @for (displaySelection of options; track displaySelection; let index = $index) {
12327
+ @if (!lastNodeWithChildren && !hasArticlesAsChildren) {
12328
+ @for (displaySelection of options | slice:0:sliceAmount; track displaySelection.selector; let index = $index) {
11456
12329
  <co-product-configurator-selector
11457
12330
  [selection]="displaySelection.selector"
11458
12331
  [options]="displaySelection.selectorOptions"
12332
+ [repeatedOptions]="displaySelection.repeatedOptions"
11459
12333
  [lastNodeWithChildren]="displaySelection.lastNodeWithChildren"
11460
12334
  [selectionIndex]="index + 1"
11461
12335
  [treeLevelIndex]="treeLevelIndex + 1"
11462
- [showAll]="getChildShowAll()"
11463
- [isActive]="getIsChildVisible(index)"
11464
- [suppressSubShowMore]="suppressSubShowMoreForChildren"
11465
- [useGroupedParentVisibility]="useGroupedVisibilityForChildren"
11466
12336
  [markAsException]="displaySelection.markForExceptionNotification"
12337
+ [hasArticlesAsChildren]="displaySelection.selectorOptionsAreArticles"
12338
+ [markForUserInput]="displaySelection.markForUserInput"
11467
12339
  (activate)="activeChildIndex = index">
11468
12340
  </co-product-configurator-selector>
11469
12341
  }
11470
12342
  }
11471
- @if (shouldShowExpandButton()) {
12343
+ @if (limitStartView && treeLevelIndex === 1 && !lastNodeWithChildren && !hasArticlesAsChildren) {
11472
12344
  <div class="show-more-container" (click)="onShowAllClick()">
11473
- <span class="show-all-button show-more-text-link"
11474
- [textContent]="expandButtonText | localize:false | async">
11475
- </span>
11476
-
11477
- @if (this.groupedRemainingTilesCount > 0) {
11478
- <span class="show-all-button show-more-text-link counter"
11479
- [textContent]="'(' + this.groupedRemainingTilesCount + ')'">
11480
- </span>
12345
+ <span class="show-all-button show-more-text-link" [textContent]="'SHOW_ALL' | localize:false | async"></span>
12346
+ @if (totalOptionCount > 0) {
12347
+ <span class="show-all-button show-more-text-link counter" [textContent]="'(' + totalOptionCount + ')'"></span>
11481
12348
  }
11482
12349
  </div>
11483
12350
  }
11484
- `,
12351
+ `,
11485
12352
  encapsulation: ViewEncapsulation.None,
11486
- animations: [
11487
- trigger('showSelections', [
11488
- state('void', style({ 'transform': 'translateX(100%)', opacity: 0 })),
11489
- state('*', style({ 'transform': 'translateX(0%)', opacity: 1 })),
11490
- transition('void <=> *', animate(200))
11491
- ])
11492
- ],
11493
12353
  standalone: false
11494
12354
  }]
11495
- }], ctorParameters: () => [{ type: ConfiguratorConnectorService }, { type: ConfiguratorSettingsService }, { type: IconCacheService }], propDecorators: { hostClasses: [{
12355
+ }], ctorParameters: () => [{ type: ConfiguratorConnectorService }, { type: ConfiguratorSettingsService }, { type: IconCacheService }, { type: ConfiguratorEventService }], propDecorators: { showClass: [{
11496
12356
  type: HostBinding,
11497
- args: ['class']
12357
+ args: ['class.co-product-configurator-selector']
11498
12358
  }], exceptionContainer: [{
11499
12359
  type: ViewChild,
11500
12360
  args: ['exceptionContainer']
@@ -11502,47 +12362,288 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
11502
12362
  type: Input
11503
12363
  }], options: [{
11504
12364
  type: Input
12365
+ }], repeatedOptions: [{
12366
+ type: Input
11505
12367
  }], lastNodeWithChildren: [{
11506
12368
  type: Input
12369
+ }], markForUserInput: [{
12370
+ type: Input
11507
12371
  }], selectionIndex: [{
11508
12372
  type: Input
11509
12373
  }], treeLevelIndex: [{
11510
12374
  type: Input
11511
- }], isActive: [{
11512
- type: Input
11513
12375
  }], markAsException: [{
11514
12376
  type: Input
11515
- }], showAll: [{
11516
- type: Input
11517
- }], suppressSubShowMore: [{
11518
- type: Input
11519
- }], useGroupedParentVisibility: [{
12377
+ }], hasArticlesAsChildren: [{
11520
12378
  type: Input
11521
12379
  }], activate: [{
11522
12380
  type: Output
12381
+ }], openSlideOutClick: [{
12382
+ type: Output
12383
+ }] } });
12384
+
12385
+ class ProductConfiguratorChildArticleConfiguratorComponent {
12386
+ configuratorConnectorService;
12387
+ settingsService;
12388
+ iconService;
12389
+ showClass() {
12390
+ return true;
12391
+ }
12392
+ icons = IconEnum;
12393
+ selection;
12394
+ options;
12395
+ lastNodeWithChildren;
12396
+ selectionIndex;
12397
+ treeLevelIndex = 1;
12398
+ markAsException = false;
12399
+ hasArticlesAsChildren = false;
12400
+ listOfChoices = [];
12401
+ showAnswerGrouped = true;
12402
+ constructor(configuratorConnectorService, settingsService, iconService) {
12403
+ this.configuratorConnectorService = configuratorConnectorService;
12404
+ this.settingsService = settingsService;
12405
+ this.iconService = iconService;
12406
+ }
12407
+ ngOnInit() {
12408
+ this.showAnswerGrouped = this.selection.showGrouped;
12409
+ if (this.selection && this.selection.displayOptionControl == null) {
12410
+ this.selection.displayOptionControl = ConfigurationDisplayOption.TileLarge;
12411
+ }
12412
+ // This is filling the 'tile' data in case there are no nested articles
12413
+ if (this.lastNodeWithChildren) {
12414
+ for (const option of this.options) {
12415
+ if (option.selector) {
12416
+ this.listOfChoices.push(option.selector);
12417
+ }
12418
+ }
12419
+ }
12420
+ // This is the case when we DO have nested articles
12421
+ if (!this.lastNodeWithChildren && this.hasArticlesAsChildren) {
12422
+ for (const option of this.options) {
12423
+ if (option.selector) {
12424
+ this.listOfChoices.push(option.selector);
12425
+ }
12426
+ }
12427
+ }
12428
+ }
12429
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorChildArticleConfiguratorComponent, deps: [{ token: ConfiguratorConnectorService }, { token: ConfiguratorSettingsService }, { token: IconCacheService }], target: i0.ɵɵFactoryTarget.Component });
12430
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ProductConfiguratorChildArticleConfiguratorComponent, isStandalone: false, selector: "co-product-configurator-child-article-configurator", inputs: { selection: "selection", options: "options", lastNodeWithChildren: "lastNodeWithChildren", selectionIndex: "selectionIndex", treeLevelIndex: "treeLevelIndex", markAsException: "markAsException", hasArticlesAsChildren: "hasArticlesAsChildren" }, host: { properties: { "class.co-product-configurator-child-article-configurator": "this.showClass" } }, ngImport: i0, template: `
12431
+ <div class="selector-container">
12432
+ <div class="selector-container-header">
12433
+ <p class="selector-option-bold-text-header" [textContent]="selection.nodeText ? selection.nodeText: selection.optionText | localize:true | async"></p>
12434
+ </div>
12435
+ </div>
12436
+ @if (!lastNodeWithChildren) {
12437
+ @for (displaySelection of options; track displaySelection.selector; let index = $index) {
12438
+ <co-product-configurator-selector
12439
+ [selection]="displaySelection.selector"
12440
+ [options]="displaySelection.selectorOptions"
12441
+ [lastNodeWithChildren]="displaySelection.lastNodeWithChildren"
12442
+ [selectionIndex]="index + 1"
12443
+ [treeLevelIndex]="treeLevelIndex + 1"
12444
+ [markAsException]="displaySelection.markForExceptionNotification"
12445
+ [markForUserInput]="displaySelection.markForUserInput"
12446
+ [hasArticlesAsChildren]="displaySelection.selectorOptionsAreArticles">
12447
+ </co-product-configurator-selector>
12448
+ }
12449
+ }
12450
+ `, isInline: true, dependencies: [{ kind: "component", type: ProductConfiguratorSelectorComponent, selector: "co-product-configurator-selector", inputs: ["selection", "options", "repeatedOptions", "lastNodeWithChildren", "markForUserInput", "selectionIndex", "treeLevelIndex", "markAsException", "hasArticlesAsChildren"], outputs: ["activate", "openSlideOutClick"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }] });
12451
+ }
12452
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorChildArticleConfiguratorComponent, decorators: [{
12453
+ type: Component,
12454
+ args: [{
12455
+ selector: 'co-product-configurator-child-article-configurator',
12456
+ template: `
12457
+ <div class="selector-container">
12458
+ <div class="selector-container-header">
12459
+ <p class="selector-option-bold-text-header" [textContent]="selection.nodeText ? selection.nodeText: selection.optionText | localize:true | async"></p>
12460
+ </div>
12461
+ </div>
12462
+ @if (!lastNodeWithChildren) {
12463
+ @for (displaySelection of options; track displaySelection.selector; let index = $index) {
12464
+ <co-product-configurator-selector
12465
+ [selection]="displaySelection.selector"
12466
+ [options]="displaySelection.selectorOptions"
12467
+ [lastNodeWithChildren]="displaySelection.lastNodeWithChildren"
12468
+ [selectionIndex]="index + 1"
12469
+ [treeLevelIndex]="treeLevelIndex + 1"
12470
+ [markAsException]="displaySelection.markForExceptionNotification"
12471
+ [markForUserInput]="displaySelection.markForUserInput"
12472
+ [hasArticlesAsChildren]="displaySelection.selectorOptionsAreArticles">
12473
+ </co-product-configurator-selector>
12474
+ }
12475
+ }
12476
+ `,
12477
+ standalone: false
12478
+ }]
12479
+ }], ctorParameters: () => [{ type: ConfiguratorConnectorService }, { type: ConfiguratorSettingsService }, { type: IconCacheService }], propDecorators: { showClass: [{
12480
+ type: HostBinding,
12481
+ args: ['class.co-product-configurator-child-article-configurator']
12482
+ }], selection: [{
12483
+ type: Input
12484
+ }], options: [{
12485
+ type: Input
12486
+ }], lastNodeWithChildren: [{
12487
+ type: Input
12488
+ }], selectionIndex: [{
12489
+ type: Input
12490
+ }], treeLevelIndex: [{
12491
+ type: Input
12492
+ }], markAsException: [{
12493
+ type: Input
12494
+ }], hasArticlesAsChildren: [{
12495
+ type: Input
12496
+ }] } });
12497
+
12498
+ class ProductConfiguratorSlideoutComponent {
12499
+ configuratorConnectorService;
12500
+ iconService;
12501
+ _appEventService;
12502
+ icons = IconEnum;
12503
+ showClass() {
12504
+ return true;
12505
+ }
12506
+ displaySelection;
12507
+ displayOptions;
12508
+ selection;
12509
+ options;
12510
+ repeatedOptions;
12511
+ showSlideOut = false;
12512
+ activeSelection;
12513
+ _subs = [];
12514
+ constructor(configuratorConnectorService, iconService, _appEventService) {
12515
+ this.configuratorConnectorService = configuratorConnectorService;
12516
+ this.iconService = iconService;
12517
+ this._appEventService = _appEventService;
12518
+ this._subs.push(this._appEventService.openSlideOut.subscribe(event => {
12519
+ this._handleSlideOut(event);
12520
+ }));
12521
+ }
12522
+ ngOnDestroy() {
12523
+ this._subs.forEach(s => s.unsubscribe());
12524
+ }
12525
+ handleCloseClick() {
12526
+ this.showSlideOut = false;
12527
+ this.configuratorConnectorService.activeSlideOutParentId = undefined;
12528
+ this._appEventService.closeSlideOut.next();
12529
+ }
12530
+ _handleSlideOut(event) {
12531
+ this.showSlideOut = event.open;
12532
+ this.selection = event.selection;
12533
+ this.options = event.options;
12534
+ this.repeatedOptions = event.repeatedOptions;
12535
+ this.activeSelection = event.selNodeId;
12536
+ this.configuratorConnectorService.activeSlideOutParentId = event.selNodeId;
12537
+ this._handleRepeatOptions(this.showSlideOut, this.activeSelection);
12538
+ }
12539
+ _handleRepeatOptions(show, activeSelection) {
12540
+ let foundRepeats = false;
12541
+ if (activeSelection && show && this.repeatedOptions && this.repeatedOptions.length > 0) {
12542
+ this.repeatedOptions.forEach(parent => {
12543
+ if (parent && parent.selectorOptions.length > 0) {
12544
+ if (parent.selectorOptions && parent.selectorOptions.length > 0) {
12545
+ parent.selectorOptions.forEach(child => {
12546
+ if (child.selector.selNodeId === activeSelection) {
12547
+ this.displaySelection = parent.selector;
12548
+ this.displayOptions = parent.selectorOptions;
12549
+ foundRepeats = true;
12550
+ }
12551
+ });
12552
+ }
12553
+ }
12554
+ });
12555
+ }
12556
+ if (!foundRepeats) {
12557
+ this.displaySelection = this.selection;
12558
+ this.displayOptions = this.options;
12559
+ }
12560
+ }
12561
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSlideoutComponent, deps: [{ token: ConfiguratorConnectorService }, { token: IconCacheService }, { token: ConfiguratorEventService }], target: i0.ɵɵFactoryTarget.Component });
12562
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ProductConfiguratorSlideoutComponent, isStandalone: false, selector: "co-product-configurator-slideout", host: { properties: { "class.co-product-configurator-slideout": "this.showClass" } }, ngImport: i0, template: `
12563
+ @if (showSlideOut) {
12564
+ <div class="product-configurator-slideout-body" [class.show-slide-out]="showSlideOut">
12565
+ <div class="product-configurator-selector-slideout-header">
12566
+ <div class="product-configurator-selector-slideout-close" (click)="handleCloseClick()">
12567
+ <co-button
12568
+ [label]="'BACK_TO_MAIN_CONFIGURATION' | localize: false | async"
12569
+ [iconData]="iconService.getIcon(icons.ChevronLeftRegular)"
12570
+ ></co-button>
12571
+ </div>
12572
+ <div class="slideout-head" [textContent]="displaySelection.optionText"></div>
12573
+ </div>
12574
+ @if (displayOptions && displayOptions.length > 0) {
12575
+ @for (child of displayOptions; track child.selector.id) {
12576
+ @if (child.selector.selNodeId === activeSelection) {
12577
+ <div class="child-article-option-container">
12578
+ <co-product-configurator-child-article-configurator
12579
+ [selection]="child.selector"
12580
+ [options]="child.selectorOptions"
12581
+ [lastNodeWithChildren]="child.lastNodeWithChildren"
12582
+ [markAsException]="child.markForExceptionNotification"
12583
+ [hasArticlesAsChildren]="child.selectorOptionsAreArticles">
12584
+ </co-product-configurator-child-article-configurator>
12585
+ </div>
12586
+ }
12587
+ }
12588
+ }
12589
+ </div>
12590
+ }
12591
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "component", type: ProductConfiguratorChildArticleConfiguratorComponent, selector: "co-product-configurator-child-article-configurator", inputs: ["selection", "options", "lastNodeWithChildren", "selectionIndex", "treeLevelIndex", "markAsException", "hasArticlesAsChildren"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
12592
+ }
12593
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSlideoutComponent, decorators: [{
12594
+ type: Component,
12595
+ args: [{
12596
+ selector: 'co-product-configurator-slideout',
12597
+ template: `
12598
+ @if (showSlideOut) {
12599
+ <div class="product-configurator-slideout-body" [class.show-slide-out]="showSlideOut">
12600
+ <div class="product-configurator-selector-slideout-header">
12601
+ <div class="product-configurator-selector-slideout-close" (click)="handleCloseClick()">
12602
+ <co-button
12603
+ [label]="'BACK_TO_MAIN_CONFIGURATION' | localize: false | async"
12604
+ [iconData]="iconService.getIcon(icons.ChevronLeftRegular)"
12605
+ ></co-button>
12606
+ </div>
12607
+ <div class="slideout-head" [textContent]="displaySelection.optionText"></div>
12608
+ </div>
12609
+ @if (displayOptions && displayOptions.length > 0) {
12610
+ @for (child of displayOptions; track child.selector.id) {
12611
+ @if (child.selector.selNodeId === activeSelection) {
12612
+ <div class="child-article-option-container">
12613
+ <co-product-configurator-child-article-configurator
12614
+ [selection]="child.selector"
12615
+ [options]="child.selectorOptions"
12616
+ [lastNodeWithChildren]="child.lastNodeWithChildren"
12617
+ [markAsException]="child.markForExceptionNotification"
12618
+ [hasArticlesAsChildren]="child.selectorOptionsAreArticles">
12619
+ </co-product-configurator-child-article-configurator>
12620
+ </div>
12621
+ }
12622
+ }
12623
+ }
12624
+ </div>
12625
+ }
12626
+ `,
12627
+ standalone: false,
12628
+ encapsulation: ViewEncapsulation.None
12629
+ }]
12630
+ }], ctorParameters: () => [{ type: ConfiguratorConnectorService }, { type: IconCacheService }, { type: ConfiguratorEventService }], propDecorators: { showClass: [{
12631
+ type: HostBinding,
12632
+ args: ['class.co-product-configurator-slideout']
11523
12633
  }] } });
11524
12634
 
11525
12635
  class ProductConfiguratorComponent {
11526
12636
  configuratorConnectorService;
11527
12637
  buildFurnitureService;
11528
12638
  settingsService;
11529
- productConfiguratorService;
11530
12639
  iconService;
11531
12640
  _sanitizer;
11532
12641
  _configuringService;
11533
- _eventService;
12642
+ _appEventService;
11534
12643
  showClass() {
11535
12644
  return true;
11536
12645
  }
11537
12646
  icons = IconEnum;
11538
- // @Input()
11539
- // public set show(value: boolean) {
11540
- // this._show = value;
11541
- // }
11542
- //
11543
- // public get show(): boolean {
11544
- // return this._show;
11545
- // }
11546
12647
  showHeaderInformation = true;
11547
12648
  set showSelections(value) {
11548
12649
  this._showSelections = value;
@@ -11559,47 +12660,57 @@ class ProductConfiguratorComponent {
11559
12660
  article = new Article();
11560
12661
  selectionList = [];
11561
12662
  safeDescription;
12663
+ hideMainConfiguration = false;
11562
12664
  _showSelections = false;
11563
- _show = false;
11564
- _selectionSelected;
11565
12665
  _subs = [];
11566
- constructor(configuratorConnectorService, buildFurnitureService, settingsService, productConfiguratorService, iconService, _sanitizer, _configuringService, _eventService) {
12666
+ constructor(configuratorConnectorService, buildFurnitureService, settingsService, iconService, _sanitizer, _configuringService, _appEventService) {
11567
12667
  this.configuratorConnectorService = configuratorConnectorService;
11568
12668
  this.buildFurnitureService = buildFurnitureService;
11569
12669
  this.settingsService = settingsService;
11570
- this.productConfiguratorService = productConfiguratorService;
11571
12670
  this.iconService = iconService;
11572
12671
  this._sanitizer = _sanitizer;
11573
12672
  this._configuringService = _configuringService;
11574
- this._eventService = _eventService;
12673
+ this._appEventService = _appEventService;
11575
12674
  this._subs.push(this.settingsService.settingsLoaded.subscribe((loaded) => {
11576
12675
  if (loaded && this.settingsService.settings.currencySymbol) {
11577
12676
  this.valutaSymbol = this.settingsService.settings.currencySymbol;
11578
12677
  }
11579
- }), this.productConfiguratorService.selectSelection.subscribe((selection) => {
12678
+ }), this._appEventService.selectSelection.subscribe((selection) => {
11580
12679
  if (selection) {
11581
- this.onSelectionsSummarySelectSelection(selection);
12680
+ this.navigateToSelection(selection);
11582
12681
  }
11583
- }), this._eventService.articleReceived.subscribe((article) => {
12682
+ }), this._appEventService.articleReceived.subscribe((article) => {
11584
12683
  if (article) {
11585
12684
  this._handleArticleReceived(article);
11586
12685
  }
11587
- }), this._eventService.selectionWithAnswersChanged.subscribe((selections) => this._handleSelectionWithAnswersChanged(selections)));
12686
+ }), this._appEventService.selectionWithAnswersChanged.subscribe((selections) => this._handleSelectionWithAnswersChanged(selections)), this._appEventService.openSlideOut.subscribe(event => {
12687
+ if (event.open) {
12688
+ this.handleHideMainConfiguration(true);
12689
+ }
12690
+ }), this._appEventService.closeSlideOut.subscribe(() => {
12691
+ this.handleHideMainConfiguration(false);
12692
+ }));
11588
12693
  }
11589
12694
  ngOnDestroy() {
11590
12695
  this._subs.forEach(s => s.unsubscribe());
11591
12696
  }
11592
- async onSelectionsSummarySelectSelection(chosenOption) {
11593
- await this.configuratorConnectorService.navigateTo(chosenOption, true);
12697
+ async navigateToSelection(chosenOption) {
12698
+ await this.configuratorConnectorService.navigateToBySelNode(this._configuringService.buildResult.instanceId, chosenOption, true);
11594
12699
  await this.buildFurnitureService.currentActiveService.selectSelectionAsAnswer(chosenOption, this._configuringService.buildResult);
11595
12700
  }
11596
12701
  handleCloseClick() {
11597
- this.showChange.emit(false);
12702
+ // this.showChange.emit(false);
12703
+ }
12704
+ handleHideMainConfiguration(hide) {
12705
+ this.hideMainConfiguration = hide;
11598
12706
  }
11599
12707
  _handleSelectionWithAnswersChanged(selections) {
11600
12708
  if (selections && selections.length > 0) {
11601
12709
  this.selectionList = selections;
11602
12710
  }
12711
+ if (this.configuratorConnectorService.activeSlideOutParentId) {
12712
+ this.configuratorConnectorService.markSelectionForUserInput(this.configuratorConnectorService.activeSlideOutParentId);
12713
+ }
11603
12714
  }
11604
12715
  _handleArticleReceived(article) {
11605
12716
  if (!article) {
@@ -11617,102 +12728,114 @@ class ProductConfiguratorComponent {
11617
12728
  this.safeDescription = this._sanitizer.bypassSecurityTrustHtml(this.article.description);
11618
12729
  }
11619
12730
  }
11620
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorComponent, deps: [{ token: ConfiguratorConnectorService }, { token: SwitchBuildFurnitureService }, { token: ConfiguratorSettingsService }, { token: ProductConfiguratorService }, { token: IconCacheService }, { token: i1.DomSanitizer }, { token: ConfiguringService }, { token: ConfiguratorEventService }], target: i0.ɵɵFactoryTarget.Component });
12731
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorComponent, deps: [{ token: ConfiguratorConnectorService }, { token: SwitchBuildFurnitureService }, { token: ConfiguratorSettingsService }, { token: IconCacheService }, { token: i1.DomSanitizer }, { token: ConfiguringService }, { token: ConfiguratorEventService }], target: i0.ɵɵFactoryTarget.Component });
11621
12732
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ProductConfiguratorComponent, isStandalone: false, selector: "co-product-configurator", inputs: { showHeaderInformation: "showHeaderInformation", showSelections: "showSelections", showLabel: "showLabel", canClose: "canClose", customDimensions: "customDimensions" }, outputs: { showChange: "showChange", answerChosen: "answerChosen" }, host: { properties: { "class.co-product-configurator": "this.showClass" } }, ngImport: i0, template: `
11622
- <div class="product-configurator-container">
11623
- @if (showHeaderInformation) {
11624
- <div class="product-configurator-header">
11625
- <div class="product-configurator-head">
11626
- <h2 class="product-configurator-header-text" [textContent]="article.name"></h2>
11627
- <p class="product-configurator-text" [innerHTML]="safeDescription"></p>
11628
- </div>
11629
- <div class="product-configurator-header-actions">
11630
- <co-configuration-preset></co-configuration-preset>
11631
- @if (canClose) {
11632
- <div class="product-configurator-close" (click)="handleCloseClick()">
11633
- <co-icon [iconData]="iconService.getIcon(icons.XmarkLightFull)"></co-icon>
11634
- </div>
11635
- }
11636
- </div>
12733
+ <div class="product-configurator-container" [class.hide-main-configuration]="hideMainConfiguration">
12734
+ @if (showHeaderInformation) {
12735
+ <div class="product-configurator-header">
12736
+ <div class="product-configurator-head">
12737
+ <h2 class="product-configurator-header-text" [textContent]="article.name"></h2>
12738
+ <p class="product-configurator-text" [innerHTML]="safeDescription"></p>
11637
12739
  </div>
11638
- }
11639
- <div class="product-configurator-details" #scrollcontainer>
11640
- @for (displaySelection of configuratorConnectorService.selectionWithAnswers; track displaySelection; let index = $index) {
11641
- <co-product-configurator-selector
11642
- [selection]="displaySelection.selector"
11643
- [options]="displaySelection.selectorOptions"
11644
- [lastNodeWithChildren]="displaySelection.lastNodeWithChildren"
11645
- [markAsException]="displaySelection.markForExceptionNotification"
11646
- [selectionIndex]="index + 1">
11647
- </co-product-configurator-selector>
11648
- }
11649
- </div>
11650
- @if (configuratorConnectorService.totalPrice !== undefined) {
11651
- <div class="product-configurator-summary">
11652
- <div class="product-configurator-summary-price-container">
11653
- @if (settingsService.settings.options.showAsConfigured) {
11654
- <div class="sum">
11655
- <label [textContent]="'AS_CONFIGURED' | localize:false | async"></label><span class="total-price"></span>
11656
- <div class="price" [textContent]="configuratorConnectorService.totalPrice | priceDisplay"></div>
11657
- </div>
11658
- }
11659
- </div>
12740
+ <div class="product-configurator-header-actions">
12741
+ <co-configuration-preset></co-configuration-preset>
12742
+ @if (canClose) {
12743
+ <div class="product-configurator-close" (click)="handleCloseClick()">
12744
+ <co-icon [iconData]="iconService.getIcon(icons.XmarkLightFull)"></co-icon>
12745
+ </div>
12746
+ }
11660
12747
  </div>
12748
+ </div>
12749
+ }
12750
+ <div class="product-configurator-details" #scrollcontainer>
12751
+ @for (displaySelection of configuratorConnectorService.selectionWithAnswers; track displaySelection.selector; let index = $index) {
12752
+ <co-product-configurator-selector
12753
+ [selection]="displaySelection.selector"
12754
+ [options]="displaySelection.selectorOptions"
12755
+ [repeatedOptions]="displaySelection.repeatedOptions"
12756
+ [lastNodeWithChildren]="displaySelection.lastNodeWithChildren"
12757
+ [markAsException]="displaySelection.markForExceptionNotification"
12758
+ [hasArticlesAsChildren]="displaySelection.selectorOptionsAreArticles"
12759
+ [markForUserInput]="displaySelection.markForUserInput"
12760
+ [selectionIndex]="index + 1">
12761
+ </co-product-configurator-selector>
11661
12762
  }
11662
12763
  </div>
11663
- `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: ProductConfiguratorSelectorComponent, selector: "co-product-configurator-selector", inputs: ["selection", "options", "lastNodeWithChildren", "selectionIndex", "treeLevelIndex", "isActive", "markAsException", "showAll", "suppressSubShowMore", "useGroupedParentVisibility"], outputs: ["activate"] }, { kind: "component", type: ConfigurationPresetComponent, selector: "co-configuration-preset" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.PriceDisplayPipe, name: "priceDisplay" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
12764
+ @if (configuratorConnectorService.totalPrice !== undefined) {
12765
+ <div class="product-configurator-summary">
12766
+ <div class="product-configurator-summary-price-container">
12767
+ @if (settingsService.settings.options.showAsConfigured) {
12768
+ <div class="sum">
12769
+ <label [textContent]="'AS_CONFIGURED' | localize:false | async"></label><span class="total-price"></span>
12770
+ <div class="price" [textContent]="configuratorConnectorService.totalPrice | priceDisplay"></div>
12771
+ </div>
12772
+ }
12773
+ </div>
12774
+ </div>
12775
+ }
12776
+
12777
+ <co-product-configurator-slideout></co-product-configurator-slideout>
12778
+ </div>
12779
+
12780
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "component", type: ProductConfiguratorSelectorComponent, selector: "co-product-configurator-selector", inputs: ["selection", "options", "repeatedOptions", "lastNodeWithChildren", "markForUserInput", "selectionIndex", "treeLevelIndex", "markAsException", "hasArticlesAsChildren"], outputs: ["activate", "openSlideOutClick"] }, { kind: "component", type: ProductConfiguratorSlideoutComponent, selector: "co-product-configurator-slideout" }, { kind: "component", type: ConfigurationPresetComponent, selector: "co-configuration-preset" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.PriceDisplayPipe, name: "priceDisplay" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], encapsulation: i0.ViewEncapsulation.None });
11664
12781
  }
11665
12782
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorComponent, decorators: [{
11666
12783
  type: Component,
11667
12784
  args: [{
11668
12785
  selector: 'co-product-configurator',
11669
12786
  template: `
11670
- <div class="product-configurator-container">
11671
- @if (showHeaderInformation) {
11672
- <div class="product-configurator-header">
11673
- <div class="product-configurator-head">
11674
- <h2 class="product-configurator-header-text" [textContent]="article.name"></h2>
11675
- <p class="product-configurator-text" [innerHTML]="safeDescription"></p>
11676
- </div>
11677
- <div class="product-configurator-header-actions">
11678
- <co-configuration-preset></co-configuration-preset>
11679
- @if (canClose) {
11680
- <div class="product-configurator-close" (click)="handleCloseClick()">
11681
- <co-icon [iconData]="iconService.getIcon(icons.XmarkLightFull)"></co-icon>
11682
- </div>
11683
- }
11684
- </div>
12787
+ <div class="product-configurator-container" [class.hide-main-configuration]="hideMainConfiguration">
12788
+ @if (showHeaderInformation) {
12789
+ <div class="product-configurator-header">
12790
+ <div class="product-configurator-head">
12791
+ <h2 class="product-configurator-header-text" [textContent]="article.name"></h2>
12792
+ <p class="product-configurator-text" [innerHTML]="safeDescription"></p>
11685
12793
  </div>
11686
- }
11687
- <div class="product-configurator-details" #scrollcontainer>
11688
- @for (displaySelection of configuratorConnectorService.selectionWithAnswers; track displaySelection; let index = $index) {
11689
- <co-product-configurator-selector
11690
- [selection]="displaySelection.selector"
11691
- [options]="displaySelection.selectorOptions"
11692
- [lastNodeWithChildren]="displaySelection.lastNodeWithChildren"
11693
- [markAsException]="displaySelection.markForExceptionNotification"
11694
- [selectionIndex]="index + 1">
11695
- </co-product-configurator-selector>
11696
- }
11697
- </div>
11698
- @if (configuratorConnectorService.totalPrice !== undefined) {
11699
- <div class="product-configurator-summary">
11700
- <div class="product-configurator-summary-price-container">
11701
- @if (settingsService.settings.options.showAsConfigured) {
11702
- <div class="sum">
11703
- <label [textContent]="'AS_CONFIGURED' | localize:false | async"></label><span class="total-price"></span>
11704
- <div class="price" [textContent]="configuratorConnectorService.totalPrice | priceDisplay"></div>
11705
- </div>
11706
- }
11707
- </div>
12794
+ <div class="product-configurator-header-actions">
12795
+ <co-configuration-preset></co-configuration-preset>
12796
+ @if (canClose) {
12797
+ <div class="product-configurator-close" (click)="handleCloseClick()">
12798
+ <co-icon [iconData]="iconService.getIcon(icons.XmarkLightFull)"></co-icon>
12799
+ </div>
12800
+ }
11708
12801
  </div>
12802
+ </div>
12803
+ }
12804
+ <div class="product-configurator-details" #scrollcontainer>
12805
+ @for (displaySelection of configuratorConnectorService.selectionWithAnswers; track displaySelection.selector; let index = $index) {
12806
+ <co-product-configurator-selector
12807
+ [selection]="displaySelection.selector"
12808
+ [options]="displaySelection.selectorOptions"
12809
+ [repeatedOptions]="displaySelection.repeatedOptions"
12810
+ [lastNodeWithChildren]="displaySelection.lastNodeWithChildren"
12811
+ [markAsException]="displaySelection.markForExceptionNotification"
12812
+ [hasArticlesAsChildren]="displaySelection.selectorOptionsAreArticles"
12813
+ [markForUserInput]="displaySelection.markForUserInput"
12814
+ [selectionIndex]="index + 1">
12815
+ </co-product-configurator-selector>
11709
12816
  }
11710
12817
  </div>
11711
- `,
12818
+ @if (configuratorConnectorService.totalPrice !== undefined) {
12819
+ <div class="product-configurator-summary">
12820
+ <div class="product-configurator-summary-price-container">
12821
+ @if (settingsService.settings.options.showAsConfigured) {
12822
+ <div class="sum">
12823
+ <label [textContent]="'AS_CONFIGURED' | localize:false | async"></label><span class="total-price"></span>
12824
+ <div class="price" [textContent]="configuratorConnectorService.totalPrice | priceDisplay"></div>
12825
+ </div>
12826
+ }
12827
+ </div>
12828
+ </div>
12829
+ }
12830
+
12831
+ <co-product-configurator-slideout></co-product-configurator-slideout>
12832
+ </div>
12833
+
12834
+ `,
11712
12835
  encapsulation: ViewEncapsulation.None,
11713
12836
  standalone: false
11714
12837
  }]
11715
- }], ctorParameters: () => [{ type: ConfiguratorConnectorService }, { type: SwitchBuildFurnitureService }, { type: ConfiguratorSettingsService }, { type: ProductConfiguratorService }, { type: IconCacheService }, { type: i1.DomSanitizer }, { type: ConfiguringService }, { type: ConfiguratorEventService }], propDecorators: { showClass: [{
12838
+ }], ctorParameters: () => [{ type: ConfiguratorConnectorService }, { type: SwitchBuildFurnitureService }, { type: ConfiguratorSettingsService }, { type: IconCacheService }, { type: i1.DomSanitizer }, { type: ConfiguringService }, { type: ConfiguratorEventService }], propDecorators: { showClass: [{
11716
12839
  type: HostBinding,
11717
12840
  args: ['class.co-product-configurator']
11718
12841
  }], showHeaderInformation: [{
@@ -12301,7 +13424,7 @@ class ConfiguratorCameraSettingsComponent {
12301
13424
  <button (click)="exportSettings()" [textContent]="'EXPORT_SETTINGS' | localize:false | async"></button>
12302
13425
  </div>
12303
13426
  </div>
12304
- `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "directive", type: i6$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i6$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
13427
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "directive", type: i6$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i6$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
12305
13428
  }
12306
13429
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfiguratorCameraSettingsComponent, decorators: [{
12307
13430
  type: Component,
@@ -12502,7 +13625,7 @@ class ConfiguratorExportDialogComponent {
12502
13625
  </div>
12503
13626
  </div>
12504
13627
  </div>
12505
- `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
13628
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None });
12506
13629
  }
12507
13630
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfiguratorExportDialogComponent, decorators: [{
12508
13631
  type: Component,
@@ -12797,7 +13920,9 @@ class AnswersSlideoutModule {
12797
13920
  ColorFilterModule,
12798
13921
  TagFilterModule,
12799
13922
  DirectivesModule,
12800
- UtilitiesPipesModule], exports: [AnswersSlideoutComponent] });
13923
+ UtilitiesPipesModule,
13924
+ InputTextChipsModule,
13925
+ ButtonModule], exports: [AnswersSlideoutComponent] });
12801
13926
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AnswersSlideoutModule, imports: [SlideoutModule,
12802
13927
  TranslationModule,
12803
13928
  CommonModule,
@@ -12808,7 +13933,9 @@ class AnswersSlideoutModule {
12808
13933
  ColorFilterModule,
12809
13934
  TagFilterModule,
12810
13935
  DirectivesModule,
12811
- UtilitiesPipesModule] });
13936
+ UtilitiesPipesModule,
13937
+ InputTextChipsModule,
13938
+ ButtonModule] });
12812
13939
  }
12813
13940
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AnswersSlideoutModule, decorators: [{
12814
13941
  type: NgModule,
@@ -12824,7 +13951,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
12824
13951
  ColorFilterModule,
12825
13952
  TagFilterModule,
12826
13953
  DirectivesModule,
12827
- UtilitiesPipesModule
13954
+ UtilitiesPipesModule,
13955
+ InputTextChipsModule,
13956
+ ButtonModule
12828
13957
  ],
12829
13958
  declarations: [
12830
13959
  AnswersSlideoutComponent,
@@ -13100,13 +14229,15 @@ class ProductConfiguratorSelectorOptionModule {
13100
14229
  ProductConfiguratorSelectorOptionTileModule,
13101
14230
  ProductConfiguratorSelectorOptionCheckboxModule,
13102
14231
  ProductConfiguratorSelectorOptionButtonModule,
13103
- ProductConfiguratorSelectorOptionDropdownModule], exports: [ProductConfiguratorSelectorOptionComponent] });
14232
+ ProductConfiguratorSelectorOptionDropdownModule,
14233
+ DirectivesModule], exports: [ProductConfiguratorSelectorOptionComponent] });
13104
14234
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorOptionModule, imports: [TranslationModule,
13105
14235
  CommonModule,
13106
14236
  ProductConfiguratorSelectorOptionTileModule,
13107
14237
  ProductConfiguratorSelectorOptionCheckboxModule,
13108
14238
  ProductConfiguratorSelectorOptionButtonModule,
13109
- ProductConfiguratorSelectorOptionDropdownModule] });
14239
+ ProductConfiguratorSelectorOptionDropdownModule,
14240
+ DirectivesModule] });
13110
14241
  }
13111
14242
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorOptionModule, decorators: [{
13112
14243
  type: NgModule,
@@ -13117,23 +14248,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
13117
14248
  ProductConfiguratorSelectorOptionTileModule,
13118
14249
  ProductConfiguratorSelectorOptionCheckboxModule,
13119
14250
  ProductConfiguratorSelectorOptionButtonModule,
13120
- ProductConfiguratorSelectorOptionDropdownModule
14251
+ ProductConfiguratorSelectorOptionDropdownModule,
14252
+ DirectivesModule
13121
14253
  ],
13122
14254
  declarations: [ProductConfiguratorSelectorOptionComponent],
13123
14255
  exports: [ProductConfiguratorSelectorOptionComponent]
13124
14256
  }]
13125
14257
  }] });
13126
14258
 
14259
+ class ProductConfiguratorRepeatButtonsModule {
14260
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorRepeatButtonsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
14261
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorRepeatButtonsModule, declarations: [ProductConfiguratorRepeatButtonsComponent], imports: [ButtonModule,
14262
+ TranslationModule,
14263
+ AsyncPipe], exports: [ProductConfiguratorRepeatButtonsComponent] });
14264
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorRepeatButtonsModule, imports: [ButtonModule,
14265
+ TranslationModule] });
14266
+ }
14267
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorRepeatButtonsModule, decorators: [{
14268
+ type: NgModule,
14269
+ args: [{
14270
+ imports: [
14271
+ ButtonModule,
14272
+ TranslationModule,
14273
+ AsyncPipe
14274
+ ],
14275
+ schemas: [
14276
+ NO_ERRORS_SCHEMA
14277
+ ],
14278
+ declarations: [
14279
+ ProductConfiguratorRepeatButtonsComponent
14280
+ ],
14281
+ exports: [
14282
+ ProductConfiguratorRepeatButtonsComponent
14283
+ ]
14284
+ }]
14285
+ }] });
14286
+
13127
14287
  class ProductConfiguratorSelectorModule {
13128
14288
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
13129
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorModule, declarations: [ProductConfiguratorSelectorComponent], imports: [TranslationModule,
14289
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorModule, declarations: [ProductConfiguratorSelectorComponent,
14290
+ ProductConfiguratorSelectorChildArticleComponent,
14291
+ ProductConfiguratorChildArticleConfiguratorComponent,
14292
+ ProductConfiguratorSlideoutComponent,
14293
+ ProductConfiguratorGroupedRepeatableOptionsComponent], imports: [TranslationModule,
13130
14294
  CommonModule,
13131
14295
  IconModule,
13132
- ProductConfiguratorSelectorOptionModule], exports: [ProductConfiguratorSelectorComponent] });
14296
+ ProductConfiguratorSelectorOptionModule,
14297
+ AppendPipeModule,
14298
+ AnswerCardModule,
14299
+ DirectivesModule,
14300
+ ButtonModule,
14301
+ ProductConfiguratorRepeatButtonsModule], exports: [ProductConfiguratorSelectorComponent,
14302
+ ProductConfiguratorSelectorChildArticleComponent,
14303
+ ProductConfiguratorChildArticleConfiguratorComponent,
14304
+ ProductConfiguratorSlideoutComponent,
14305
+ ProductConfiguratorGroupedRepeatableOptionsComponent] });
13133
14306
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorModule, imports: [TranslationModule,
13134
14307
  CommonModule,
13135
14308
  IconModule,
13136
- ProductConfiguratorSelectorOptionModule] });
14309
+ ProductConfiguratorSelectorOptionModule,
14310
+ AppendPipeModule,
14311
+ AnswerCardModule,
14312
+ DirectivesModule,
14313
+ ButtonModule,
14314
+ ProductConfiguratorRepeatButtonsModule] });
13137
14315
  }
13138
14316
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ProductConfiguratorSelectorModule, decorators: [{
13139
14317
  type: NgModule,
@@ -13142,13 +14320,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
13142
14320
  TranslationModule,
13143
14321
  CommonModule,
13144
14322
  IconModule,
13145
- ProductConfiguratorSelectorOptionModule
14323
+ ProductConfiguratorSelectorOptionModule,
14324
+ AppendPipeModule,
14325
+ AnswerCardModule,
14326
+ DirectivesModule,
14327
+ ButtonModule,
14328
+ ProductConfiguratorRepeatButtonsModule
13146
14329
  ],
13147
14330
  declarations: [
13148
- ProductConfiguratorSelectorComponent
14331
+ ProductConfiguratorSelectorComponent,
14332
+ ProductConfiguratorSelectorChildArticleComponent,
14333
+ ProductConfiguratorChildArticleConfiguratorComponent,
14334
+ ProductConfiguratorSlideoutComponent,
14335
+ ProductConfiguratorGroupedRepeatableOptionsComponent
13149
14336
  ],
13150
14337
  exports: [
13151
- ProductConfiguratorSelectorComponent
14338
+ ProductConfiguratorSelectorComponent,
14339
+ ProductConfiguratorSelectorChildArticleComponent,
14340
+ ProductConfiguratorChildArticleConfiguratorComponent,
14341
+ ProductConfiguratorSlideoutComponent,
14342
+ ProductConfiguratorGroupedRepeatableOptionsComponent
13152
14343
  ]
13153
14344
  }]
13154
14345
  }] });
@@ -13268,7 +14459,7 @@ class ConfiguratorSceneLoaderComponent {
13268
14459
  {{ loaderProgress | number: '1.0-0' }}%
13269
14460
  </div>
13270
14461
  </div>
13271
- `, isInline: true, dependencies: [{ kind: "pipe", type: i5.DecimalPipe, name: "number" }], encapsulation: i0.ViewEncapsulation.None });
14462
+ `, isInline: true, dependencies: [{ kind: "pipe", type: i6$1.DecimalPipe, name: "number" }], encapsulation: i0.ViewEncapsulation.None });
13272
14463
  }
13273
14464
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfiguratorSceneLoaderComponent, decorators: [{
13274
14465
  type: Component,
@@ -13611,7 +14802,7 @@ class ElementToolbarComponent {
13611
14802
  }
13612
14803
  </div>
13613
14804
  }
13614
- `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], animations: [
14805
+ `, isInline: true, dependencies: [{ kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }], animations: [
13615
14806
  trigger('showHideEditMenu', [
13616
14807
  state('void', style({ 'height': '0', opacity: 0 })),
13617
14808
  state('*', style({ 'height': '*', opacity: 1 })),
@@ -13877,7 +15068,7 @@ class SceneOptionsComponent {
13877
15068
  </div>
13878
15069
  }
13879
15070
  </div>
13880
- `, isInline: true, dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], animations: [
15071
+ `, isInline: true, dependencies: [{ kind: "directive", type: i6$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i4.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.LocalizePipe, name: "localize" }], animations: [
13881
15072
  trigger('showHideChild', [
13882
15073
  state('true', style({ 'opacity': '1', 'visibility': 'visible' })),
13883
15074
  state('false', style({ 'opacity': '0', 'visibility': 'hidden' })),
@@ -14294,36 +15485,62 @@ class CustomObject3D extends THREE.Object3D {
14294
15485
  class SceneButtonUtils {
14295
15486
  static getAddButtons(item, selectedMesh) {
14296
15487
  const result = [];
14297
- let objectToTraverse = item;
15488
+ const usedKeys = new Set();
15489
+ let objectToTraverse;
14298
15490
  if (selectedMesh) {
14299
15491
  objectToTraverse = selectedMesh;
14300
15492
  }
15493
+ else {
15494
+ objectToTraverse = item;
15495
+ }
14301
15496
  objectToTraverse.traverse((child) => {
14302
15497
  const selection = ObjectUtils.GetSelectionFromSelectedObject(child);
14303
- if (selection) {
14304
- // @ts-ignore
14305
- if (selection.hdecoPositioning !== 'N') {
14306
- const len = selection.decoNode ? selection.decoNode.connectors.length : 0;
14307
- for (let i = 0; i < len; i++) {
14308
- if (selection.decoNode.connectors[i] === null) {
14309
- return;
14310
- }
14311
- const conObject = this._getConnectorObject(child, selection.decoNode.connectors[i].connector);
14312
- const conObjectParent = ObjectUtils.GetParentItem(conObject, CustomObject3D);
14313
- const existingButton = result.find((eab) => {
14314
- return conObjectParent && ((eab.connectorObject.connectedTo === conObjectParent.name) || (eab.connectorObject.name === conObject.name));
14315
- }); // only unique buttons
14316
- if (!existingButton) {
14317
- if (conObject && this._canShowAddButton(selection.decoNode.connectors[i], conObject)) {
14318
- result.push({
14319
- selection: selection,
14320
- connector: selection.decoNode.connectors[i],
14321
- child: child,
14322
- connectorObject: conObject
14323
- });
14324
- }
14325
- }
14326
- }
15498
+ if (!selection) {
15499
+ return;
15500
+ }
15501
+ if (selection.hdecoPositioning === 'N') {
15502
+ return;
15503
+ }
15504
+ let len;
15505
+ if (selection.decoNode && selection.decoNode.connectors) {
15506
+ len = selection.decoNode.connectors.length;
15507
+ }
15508
+ else {
15509
+ len = 0;
15510
+ }
15511
+ for (let i = 0; i < len; i++) {
15512
+ const connector = selection.decoNode.connectors[i];
15513
+ if (connector === null) {
15514
+ continue;
15515
+ }
15516
+ const conObject = this._getConnectorObject(child, connector.connector);
15517
+ if (!conObject || !this._canShowAddButton(connector, conObject)) {
15518
+ continue;
15519
+ }
15520
+ const conObjectParent = ObjectUtils.GetParentItem(conObject, CustomObject3D);
15521
+ let parentName;
15522
+ if (conObjectParent) {
15523
+ parentName = conObjectParent.name;
15524
+ }
15525
+ else {
15526
+ parentName = '';
15527
+ }
15528
+ let connectedTo;
15529
+ if (conObject.connectedTo) {
15530
+ connectedTo = conObject.connectedTo;
15531
+ }
15532
+ else {
15533
+ connectedTo = '';
15534
+ }
15535
+ const dedupeKey = conObject.name + '|' + parentName + '|' + connectedTo;
15536
+ if (!usedKeys.has(dedupeKey)) {
15537
+ usedKeys.add(dedupeKey);
15538
+ result.push({
15539
+ selection: selection,
15540
+ connector: connector,
15541
+ child: child,
15542
+ connectorObject: conObject
15543
+ });
14327
15544
  }
14328
15545
  }
14329
15546
  });
@@ -14895,6 +16112,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
14895
16112
  args: [{ providedIn: 'root' }]
14896
16113
  }], ctorParameters: () => [{ type: ConfiguratorSceneService }, { type: FontService }, { type: ConfiguratorItemService }] });
14897
16114
 
16115
+ var SceneEventState;
16116
+ (function (SceneEventState) {
16117
+ SceneEventState[SceneEventState["UNSELECTED"] = 0] = "UNSELECTED";
16118
+ SceneEventState[SceneEventState["SELECTED"] = 1] = "SELECTED";
16119
+ SceneEventState[SceneEventState["DRAGGING"] = 2] = "DRAGGING";
16120
+ SceneEventState[SceneEventState["ROTATING"] = 3] = "ROTATING";
16121
+ SceneEventState[SceneEventState["PANNING"] = 5] = "PANNING";
16122
+ SceneEventState[SceneEventState["DND"] = 6] = "DND";
16123
+ SceneEventState[SceneEventState["EXPLORE"] = 7] = "EXPLORE";
16124
+ SceneEventState[SceneEventState["DRAGGINGCONNECTOR"] = 8] = "DRAGGINGCONNECTOR";
16125
+ })(SceneEventState || (SceneEventState = {}));
16126
+
16127
+ class IntersectedObjects {
16128
+ parent;
16129
+ child;
16130
+ constructor(parent = undefined, child = undefined) {
16131
+ this.parent = parent;
16132
+ this.child = child;
16133
+ }
16134
+ }
16135
+
16136
+ class IntersectionService {
16137
+ _cameraService;
16138
+ constructor(_cameraService) {
16139
+ this._cameraService = _cameraService;
16140
+ }
16141
+ getIntersections(mouseVector, planeObjects, options) {
16142
+ const { filterByNormals = false, onlyVisible = false, recursive = true, linePrecision = 0.2, includeFloors = false, onlyConfigurableFloors = false } = options || {};
16143
+ if (!mouseVector || !planeObjects.length) {
16144
+ return [];
16145
+ }
16146
+ const camera = this._cameraService.camera;
16147
+ const direction = mouseVector.sub(camera.position).normalize();
16148
+ const rayCaster = new Raycaster(camera.position, direction);
16149
+ rayCaster.params.Line.threshold = linePrecision;
16150
+ try {
16151
+ let intersections = rayCaster.intersectObjects(planeObjects, recursive);
16152
+ if (onlyVisible && intersections.length > 0) {
16153
+ intersections = this.removeIf(intersections, (intersection) => {
16154
+ return !intersection.object.visible;
16155
+ });
16156
+ }
16157
+ return intersections;
16158
+ }
16159
+ catch (e) {
16160
+ return [];
16161
+ }
16162
+ }
16163
+ removeIf(array, func) {
16164
+ const tResult = [];
16165
+ array.forEach((element) => {
16166
+ if (!func(element)) {
16167
+ tResult.push(element);
16168
+ }
16169
+ });
16170
+ return tResult;
16171
+ }
16172
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: IntersectionService, deps: [{ token: ConfiguratorCameraService }], target: i0.ɵɵFactoryTarget.Injectable });
16173
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: IntersectionService, providedIn: 'root' });
16174
+ }
16175
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: IntersectionService, decorators: [{
16176
+ type: Injectable,
16177
+ args: [{ providedIn: 'root' }]
16178
+ }], ctorParameters: () => [{ type: ConfiguratorCameraService }] });
16179
+
14898
16180
  var TextureType;
14899
16181
  (function (TextureType) {
14900
16182
  TextureType[TextureType["Basic"] = 0] = "Basic";
@@ -15059,6 +16341,8 @@ class FloorPlaneService {
15059
16341
  this._settingsService = _settingsService;
15060
16342
  this._sceneService = _sceneService;
15061
16343
  this._sceneOptionsService = _sceneOptionsService;
16344
+ this._sceneService.getFloorSizeFn = () => this.getPlaneSize();
16345
+ this._sceneService.getCenterFloorFn = () => this.getCenterFloorPlane();
15062
16346
  this._subs.push(this._sceneService.floorTexturesLoaded.subscribe((textures) => {
15063
16347
  if (textures && textures.length > 0) {
15064
16348
  this.createFloorPlane(textures);
@@ -15108,6 +16392,9 @@ class FloorPlaneService {
15108
16392
  }
15109
16393
  }
15110
16394
  getDimensions(scale = 1) {
16395
+ if (!this._floorPlane) {
16396
+ return { x: { min: 0, max: 0 }, y: { min: 0, max: 0 } };
16397
+ }
15111
16398
  const box = new Box3().setFromObject(this._floorPlane);
15112
16399
  return {
15113
16400
  x: {
@@ -15286,6 +16573,252 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
15286
16573
  }]
15287
16574
  }], ctorParameters: () => [{ type: ConfiguratorSettingsService }, { type: ConfiguratorSceneService }, { type: SceneOptionsService }] });
15288
16575
 
16576
+ class SceneEventService {
16577
+ _sceneService;
16578
+ _cameraService;
16579
+ _connectorService;
16580
+ _intersectionService;
16581
+ _floorPlaneService;
16582
+ _itemService;
16583
+ _appEventService;
16584
+ intersectOffsetForWalls = 20;
16585
+ longTouchDuration = 600;
16586
+ rotateNoDrag = false;
16587
+ _element;
16588
+ _controls;
16589
+ _camera;
16590
+ _mousePosition = new Vector2();
16591
+ _oldMousePosition = new Vector2();
16592
+ _rotationStartPoint = null;
16593
+ _intersectedObject;
16594
+ _intersectedMesh;
16595
+ _mouseoverObject;
16596
+ _selectedObject;
16597
+ _prevSelectedObject;
16598
+ _defaultCursorStyle = 'pointer';
16599
+ _inDragOver = false;
16600
+ _mouseDown = false;
16601
+ _mouseMoved = false; // has mouse moved since down click
16602
+ _rotateMouseOver = false;
16603
+ _groupingMode = false;
16604
+ _state = SceneEventState.UNSELECTED;
16605
+ _intersectedWall;
16606
+ _intersectedFloor;
16607
+ _subs = [];
16608
+ _cameraMoveSub;
16609
+ _debouncedSaveState = new Subject();
16610
+ _touchStart;
16611
+ _touchEnd;
16612
+ _touchCancel;
16613
+ _touchMove;
16614
+ constructor(_sceneService, _cameraService, _connectorService, _intersectionService, _floorPlaneService, _itemService, _appEventService) {
16615
+ this._sceneService = _sceneService;
16616
+ this._cameraService = _cameraService;
16617
+ this._connectorService = _connectorService;
16618
+ this._intersectionService = _intersectionService;
16619
+ this._floorPlaneService = _floorPlaneService;
16620
+ this._itemService = _itemService;
16621
+ this._appEventService = _appEventService;
16622
+ }
16623
+ ngOnDestroy() {
16624
+ this._subs.forEach(s => s.unsubscribe());
16625
+ this._element = undefined;
16626
+ }
16627
+ init(element) {
16628
+ this._element = element;
16629
+ this._controls = this._cameraService.controls;
16630
+ this._camera = this._cameraService.camera;
16631
+ this._touchStart = fromEvent(element, 'touchstart');
16632
+ this._touchEnd = fromEvent(element, 'touchend');
16633
+ this._touchCancel = fromEvent(element, 'touchcancel');
16634
+ this._touchMove = fromEvent(element, 'touchmove');
16635
+ fromEvent(element, 'mousedown').pipe(filter((event) => event.button === 0)).subscribe(event => this._leftMouseDownEvent(event));
16636
+ fromEvent(element, 'mouseup').subscribe((event) => this._mouseUpEvent(event));
16637
+ fromEvent(element, 'mousemove').subscribe((event) => this._mouseMoveEvent(event));
16638
+ this._touchStart.subscribe((event) => this._touchStartEvent(event));
16639
+ this._touchEnd.subscribe((event) => this._touchEndEvent(event));
16640
+ this._touchCancel.subscribe((event) => this._touchEndEvent(event));
16641
+ this._touchMove.subscribe((event) => this._touchMoveEvent(event));
16642
+ this._subs.push(
16643
+ // this._itemGroupService.objectAdded.subscribe((object) => this.setSelectedObject(object)),
16644
+ );
16645
+ }
16646
+ setExploreMode(on = true) {
16647
+ // TODO Remove
16648
+ }
16649
+ setSelectedObject(object, mesh) {
16650
+ if (object) {
16651
+ const intersectedObjects = new IntersectedObjects(object, mesh);
16652
+ this._state = SceneEventState.SELECTED;
16653
+ this._appEventService.onObjectSelected.next(intersectedObjects);
16654
+ }
16655
+ this._markSceneToUpdate();
16656
+ }
16657
+ setUnselectedObject() {
16658
+ this._state = SceneEventState.UNSELECTED;
16659
+ this._appEventService.onObjectUnSelected.next(true);
16660
+ }
16661
+ _updateIntersections() {
16662
+ // get floorplan
16663
+ const floorPlane = this._floorPlaneService.floorPlane;
16664
+ // get object in the scene
16665
+ const item = this._itemService.sceneItems.values().next().value;
16666
+ const objectPlanes = [floorPlane, item];
16667
+ const intersects = this._getIntersections(this._mousePosition, objectPlanes, { onlyVisible: true, includeFloors: false });
16668
+ // object intersection is prioritized
16669
+ if (intersects.length > 1) {
16670
+ this._setIntersectedObject(intersects[0].object);
16671
+ }
16672
+ else if (intersects.length === 1 && intersects[0].object.name === floorPlane.name) {
16673
+ // just the floor, no object
16674
+ this._clearIntersectedObject();
16675
+ }
16676
+ else {
16677
+ this._clearIntersectedObject();
16678
+ }
16679
+ }
16680
+ _clearIntersectedObject() {
16681
+ this._intersectedMesh = null;
16682
+ this._intersectedObject = null;
16683
+ }
16684
+ _setMousePositionFromTouchEvent(event) {
16685
+ const canvas = this._element;
16686
+ this._mousePosition = RelativePositionUtils.GetClientTouchPosition(event, canvas);
16687
+ }
16688
+ _touchStartEvent(event) {
16689
+ if (this._isMouseEventAllowed(event)) {
16690
+ const longTouch = of(1)
16691
+ .pipe(delay(this.longTouchDuration))
16692
+ .pipe(takeUntil(this._touchStart))
16693
+ .pipe(takeUntil(this._touchEnd))
16694
+ .pipe(takeUntil(this._touchCancel));
16695
+ longTouch.subscribe(() => {
16696
+ this._updateIntersections();
16697
+ });
16698
+ this._mouseMoved = false;
16699
+ this._mouseDown = true;
16700
+ this._setMousePositionFromTouchEvent(event);
16701
+ switch (this._state) {
16702
+ case SceneEventState.SELECTED:
16703
+ if (!this._intersectedObject) {
16704
+ this.setUnselectedObject();
16705
+ }
16706
+ else {
16707
+ this.setSelectedObject(this._intersectedObject, this._intersectedMesh);
16708
+ }
16709
+ break;
16710
+ case SceneEventState.UNSELECTED:
16711
+ if (this._intersectedObject) {
16712
+ this.setSelectedObject(this._intersectedObject, this._intersectedMesh);
16713
+ }
16714
+ break;
16715
+ }
16716
+ }
16717
+ }
16718
+ async _touchEndEvent(event) {
16719
+ // TODO check if we still need this.
16720
+ }
16721
+ _touchMoveEvent(event) {
16722
+ if (this._isMouseEventAllowed(event)) {
16723
+ this._setMousePositionFromTouchEvent(event);
16724
+ this._mouseMoved = true;
16725
+ if (this._mouseMoved) {
16726
+ this._updateIntersections();
16727
+ }
16728
+ }
16729
+ }
16730
+ //
16731
+ // MOUSE EVENTS
16732
+ //
16733
+ // TODO Might be ok to remove
16734
+ async _mouseUpEvent(event) {
16735
+ // this._mouseDown = false;
16736
+ // switch (this._state) {
16737
+ // case SceneEventState.UNSELECTED:
16738
+ // break;
16739
+ // case SceneEventState.SELECTED:
16740
+ // break;
16741
+ // }
16742
+ }
16743
+ _mouseMoveEvent(event) {
16744
+ if (this._isMouseEventAllowed(event)) {
16745
+ const mousePos = event ? RelativePositionUtils.GetClientMousePosition(event) : this._mousePosition;
16746
+ let canvas;
16747
+ if (event) {
16748
+ event.preventDefault();
16749
+ canvas = event.currentTarget;
16750
+ }
16751
+ this._mousePosition.set(mousePos.x - (canvas ? canvas.offsetLeft : 0), mousePos.y - (canvas ? canvas.offsetTop : 0));
16752
+ if (this._oldMousePosition.x !== mousePos.x && this._oldMousePosition.y !== mousePos.y) {
16753
+ this._mouseMoved = true;
16754
+ }
16755
+ if (this._mouseMoved) {
16756
+ this._updateIntersections();
16757
+ }
16758
+ }
16759
+ }
16760
+ _leftMouseDownEvent(event) {
16761
+ if (this._isMouseEventAllowed(event)) {
16762
+ if (event) {
16763
+ event.preventDefault();
16764
+ }
16765
+ switch (this._state) {
16766
+ case SceneEventState.SELECTED:
16767
+ if (!this._intersectedObject) {
16768
+ this.setUnselectedObject();
16769
+ }
16770
+ else {
16771
+ this.setSelectedObject(this._intersectedObject, this._intersectedMesh);
16772
+ }
16773
+ break;
16774
+ case SceneEventState.UNSELECTED:
16775
+ if (this._intersectedObject) {
16776
+ this.setSelectedObject(this._intersectedObject, this._intersectedMesh);
16777
+ }
16778
+ break;
16779
+ }
16780
+ }
16781
+ }
16782
+ _getIntersections(mousePos, objects, options) {
16783
+ const mouseVector = this._mouseToVec3(mousePos);
16784
+ return this._intersectionService.getIntersections(mouseVector, objects, options);
16785
+ }
16786
+ _setIntersectedObject(mesh) {
16787
+ if (mesh && mesh.parent && mesh.parent.userData && mesh.parent.userData.rootObject) {
16788
+ this._intersectedMesh = mesh;
16789
+ }
16790
+ if (mesh && mesh.userData && mesh.userData.rootObject) {
16791
+ this._intersectedObject = mesh;
16792
+ }
16793
+ else if (mesh.parent) {
16794
+ this._setIntersectedObject(mesh.parent);
16795
+ }
16796
+ }
16797
+ _isMouseEventAllowed(event) {
16798
+ return event ? (event.target && event.target.nodeName === 'CANVAS') : true;
16799
+ }
16800
+ // Reverted changes from IONE-31399
16801
+ _mouseToVec3(vec2) {
16802
+ const rendererElement = this._element;
16803
+ const mPosition = new Vector2((vec2.x / rendererElement.clientWidth) * 2 - 1, -(vec2.y / rendererElement.clientHeight) * 2 + 1);
16804
+ const vector = new Vector3(mPosition.x, mPosition.y, 0.5);
16805
+ vector.unproject(this._camera);
16806
+ return vector;
16807
+ }
16808
+ _markSceneToUpdate() {
16809
+ this._sceneService.needsRender = true;
16810
+ }
16811
+ _setCursorStyle(style) {
16812
+ this._element.style.cursor = style;
16813
+ }
16814
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SceneEventService, deps: [{ token: ConfiguratorSceneService }, { token: ConfiguratorCameraService }, { token: ConfiguratorConnectorService }, { token: IntersectionService }, { token: FloorPlaneService }, { token: ConfiguratorItemService }, { token: ConfiguratorEventService }], target: i0.ɵɵFactoryTarget.Injectable });
16815
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SceneEventService, providedIn: 'root' });
16816
+ }
16817
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SceneEventService, decorators: [{
16818
+ type: Injectable,
16819
+ args: [{ providedIn: 'root' }]
16820
+ }], ctorParameters: () => [{ type: ConfiguratorSceneService }, { type: ConfiguratorCameraService }, { type: ConfiguratorConnectorService }, { type: IntersectionService }, { type: FloorPlaneService }, { type: ConfiguratorItemService }, { type: ConfiguratorEventService }] });
16821
+
15289
16822
  class ConfiguratorSceneComponent {
15290
16823
  _settingsService;
15291
16824
  _rotationService;
@@ -15297,6 +16830,8 @@ class ConfiguratorSceneComponent {
15297
16830
  _buildFurnitureService;
15298
16831
  _sceneOptionsService;
15299
16832
  _dimensionsService;
16833
+ _configuratorConnectorService;
16834
+ _sceneEventService;
15300
16835
  _floorService;
15301
16836
  canvasElement;
15302
16837
  elementToolbar;
@@ -15316,11 +16851,12 @@ class ConfiguratorSceneComponent {
15316
16851
  development = false;
15317
16852
  showDownloadDialog = false;
15318
16853
  showCameraSettingsDialog = false;
16854
+ showFullConfiguration = undefined;
15319
16855
  _subs = [];
15320
16856
  _firstBuild = true;
15321
16857
  _selectedElementObject;
15322
16858
  _buildResult;
15323
- constructor(_settingsService, _rotationService, _dynamicCameraService, _sceneService, _eventService, _cameraService, _itemService, _buildFurnitureService, _sceneOptionsService, _dimensionsService, _floorService // do not remove
16859
+ constructor(_settingsService, _rotationService, _dynamicCameraService, _sceneService, _eventService, _cameraService, _itemService, _buildFurnitureService, _sceneOptionsService, _dimensionsService, _configuratorConnectorService, _sceneEventService, _floorService // do not remove
15324
16860
  ) {
15325
16861
  this._settingsService = _settingsService;
15326
16862
  this._rotationService = _rotationService;
@@ -15332,6 +16868,8 @@ class ConfiguratorSceneComponent {
15332
16868
  this._buildFurnitureService = _buildFurnitureService;
15333
16869
  this._sceneOptionsService = _sceneOptionsService;
15334
16870
  this._dimensionsService = _dimensionsService;
16871
+ this._configuratorConnectorService = _configuratorConnectorService;
16872
+ this._sceneEventService = _sceneEventService;
15335
16873
  this._floorService = _floorService;
15336
16874
  this._subs.push(this._eventService.buildFinished.subscribe((result) => {
15337
16875
  if (!result || !result.object) {
@@ -15347,6 +16885,7 @@ class ConfiguratorSceneComponent {
15347
16885
  this._firstBuild = false;
15348
16886
  }
15349
16887
  this._eventService.addedToScene.next(this._buildResult);
16888
+ this._sceneService.handlePropsChanged();
15350
16889
  }), this._eventService.buildStarted.subscribe((started) => {
15351
16890
  if (started) {
15352
16891
  this.setSceneBuildLoader = started;
@@ -15357,7 +16896,11 @@ class ConfiguratorSceneComponent {
15357
16896
  this._loaderProcessUpdate(this.totalSteps);
15358
16897
  }
15359
16898
  }
15360
- }), this._settingsService.settingsLoaded.subscribe((loaded) => {
16899
+ }), this._eventService.articleReceived.subscribe((article) => {
16900
+ if (article) {
16901
+ this.showFullConfiguration = !!article.showFullConfiguration;
16902
+ }
16903
+ }), this._eventService.onObjectSelected.subscribe((intersected) => this._handleIntersectedObjects(intersected)), this._eventService.onObjectUnSelected.subscribe((unselect) => this._handleUnselectObject(unselect)), this._sceneService.onAfterRender.subscribe(() => this._handleRender()), this._settingsService.settingsLoaded.subscribe((loaded) => {
15361
16904
  if (loaded && this._settingsService.settings && this._settingsService.settings.options) {
15362
16905
  if (this._settingsService.settings.options.showDownloadButton) {
15363
16906
  this._createDownloadButton();
@@ -15376,10 +16919,12 @@ class ConfiguratorSceneComponent {
15376
16919
  }
15377
16920
  ngAfterViewInit() {
15378
16921
  this._sceneService.init(this.canvasElement.nativeElement);
16922
+ this._sceneEventService.init(this.canvasElement.nativeElement);
15379
16923
  }
15380
16924
  ngOnDestroy() {
15381
16925
  this._subs.forEach(sub => sub.unsubscribe());
15382
16926
  this.canvasElement = undefined;
16927
+ this.showFullConfiguration = undefined;
15383
16928
  }
15384
16929
  swapElement() {
15385
16930
  if (this._selectedElementObject) {
@@ -15488,6 +17033,19 @@ class ConfiguratorSceneComponent {
15488
17033
  this._buildFurnitureService.currentActiveService.selectSelection(selection, this._buildResult, connector.linkedRepeatables !== 'T', after, connector.connector);
15489
17034
  this._resetSelectedElement();
15490
17035
  }
17036
+ _handleFullConfigAddButtonClick(selection, connector, parent) {
17037
+ let after;
17038
+ if (connector.addAdjust === 2) {
17039
+ after = connector.connector.indexOf('_M_') > -1;
17040
+ }
17041
+ if (selection.repeatOptActive) {
17042
+ this._configuratorConnectorService.repeatOption(selection.optCycle, selection.id, after);
17043
+ }
17044
+ else {
17045
+ // when it's not repeatable, we need to short cut to the correct in the configuration, like the Element menu
17046
+ this._configuratorConnectorService.markSelectionForUserInput(selection.node);
17047
+ }
17048
+ }
15491
17049
  _resetSelectedElement() {
15492
17050
  this._selectedElementObject = undefined;
15493
17051
  this._resetElementPosition();
@@ -15584,7 +17142,90 @@ class ConfiguratorSceneComponent {
15584
17142
  _handleShowMeasurements() {
15585
17143
  this._dimensionsService.enabled = !this._dimensionsService.enabled;
15586
17144
  }
15587
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfiguratorSceneComponent, deps: [{ token: ConfiguratorSettingsService }, { token: ConfiguratorRotationService }, { token: ConfiguratorDynamicCameraService }, { token: ConfiguratorSceneService }, { token: ConfiguratorEventService }, { token: ConfiguratorCameraService }, { token: ConfiguratorItemService }, { token: SwitchBuildFurnitureService }, { token: SceneOptionsService }, { token: DimensionsService }, { token: FloorPlaneService }], target: i0.ɵɵFactoryTarget.Component });
17145
+ _handleUnselectObject(unselected) {
17146
+ if (unselected) {
17147
+ this.editAddButtons = [];
17148
+ this.showElementToolbar = false;
17149
+ this._sceneService.needsRender = true;
17150
+ }
17151
+ }
17152
+ _handleRender() {
17153
+ if (this.showElementToolbar) {
17154
+ this._repositionButtons();
17155
+ }
17156
+ }
17157
+ _handleIntersectedObjects(intersectedObjects) {
17158
+ this._selectedElementObject = intersectedObjects.child;
17159
+ if (this._selectedElementObject) {
17160
+ this._prepareAddButtons(intersectedObjects);
17161
+ this._prepareElementMenu(intersectedObjects);
17162
+ const shouldBeHidden = this._selectedElementObject.userData &&
17163
+ this._selectedElementObject.userData.selection &&
17164
+ this._selectedElementObject.userData.selection.question.indexOf('[hidden]') > -1;
17165
+ if (this._settingsService.settings.options.instantReplace) {
17166
+ if (shouldBeHidden) {
17167
+ // this._cancelElementReplace();
17168
+ }
17169
+ else {
17170
+ this.swapElement();
17171
+ }
17172
+ }
17173
+ this.showElementToolbar = true;
17174
+ this._sceneService.needsRender = true;
17175
+ this._repositionButtons();
17176
+ }
17177
+ }
17178
+ _prepareAddButtons(intersectedObjects) {
17179
+ this.editAddButtons = [];
17180
+ const buttonList = SceneButtonUtils.getAddButtons(intersectedObjects.parent, intersectedObjects.child);
17181
+ for (const customButtonItem of buttonList) {
17182
+ // We should check them here again to make sure we do not have dubs
17183
+ this.editAddButtons.push(new CustomButton('', () => {
17184
+ if (this.showFullConfiguration) {
17185
+ this._handleFullConfigAddButtonClick(customButtonItem.selection, customButtonItem.connector, customButtonItem.child);
17186
+ }
17187
+ else {
17188
+ this._handleAddButtonClick(customButtonItem.selection, customButtonItem.connector, customButtonItem.child);
17189
+ }
17190
+ }, customButtonItem.connectorObject));
17191
+ }
17192
+ }
17193
+ _prepareElementMenu(intersectedObjects) {
17194
+ this.editElementMenu = [];
17195
+ const selection = ObjectUtils.GetSelectionFromSelectedObject(intersectedObjects.child);
17196
+ if (this._settingsService.settings.options.showEditPencilConfigurator && selection) {
17197
+ let options = this._getOptionsFromSelection(selection);
17198
+ options = options.filter(o => {
17199
+ return o.nodeType === 'OPT' && this._configuratorConnectorService.isSelectionPublished(o);
17200
+ });
17201
+ if (this.showFullConfiguration) {
17202
+ // TODO discuss, this means that we remove selections that got removed by exceptions.
17203
+ // When we do not remove them, we see them, we can click on them, but the will be removed from the _getOptionsFromSelection data
17204
+ // Not sure if this is correct, maybe conflict between normale and full config.
17205
+ //options = this._configuratorConnectorService.filterRemoveSelectionsByDeleteExceptions(options);
17206
+ }
17207
+ const len = options.length;
17208
+ for (let i = 0; i < len; i++) {
17209
+ this.editElementMenu.push(new CustomButton(options[i].question, () => {
17210
+ if (this.showFullConfiguration) {
17211
+ // TODO we might need to redo this when we got in trouble again but option[i].node matches with selectorStructure.selNodeId
17212
+ // We shoul be able to mark this in the template.
17213
+ this._configuratorConnectorService.markSelectionForUserInput(selection.node);
17214
+ }
17215
+ else {
17216
+ this._buildFurnitureService.currentActiveService.selectSelection(options[i], this._buildResult);
17217
+ }
17218
+ if (!this._settingsService.settings.options.instantEditMenu) {
17219
+ this._resetSelectedElement();
17220
+ }
17221
+ }));
17222
+ }
17223
+ }
17224
+ }
17225
+ _getOptionsFromSelection(baseSelection) {
17226
+ return this._buildFurnitureService.currentActiveService.getOptionsFromSelection(baseSelection);
17227
+ }
17228
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ConfiguratorSceneComponent, deps: [{ token: ConfiguratorSettingsService }, { token: ConfiguratorRotationService }, { token: ConfiguratorDynamicCameraService }, { token: ConfiguratorSceneService }, { token: ConfiguratorEventService }, { token: ConfiguratorCameraService }, { token: ConfiguratorItemService }, { token: SwitchBuildFurnitureService }, { token: SceneOptionsService }, { token: DimensionsService }, { token: ConfiguratorConnectorService }, { token: SceneEventService }, { token: FloorPlaneService }], target: i0.ɵɵFactoryTarget.Component });
15588
17229
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ConfiguratorSceneComponent, isStandalone: false, selector: "co-configurator-scene", host: { properties: { "class.co-configurator-scene": "this.showClass" } }, viewQueries: [{ propertyName: "canvasElement", first: true, predicate: ["canvas"], descendants: true, read: ElementRef }, { propertyName: "elementToolbar", first: true, predicate: ElementToolbarComponent, descendants: true }], ngImport: i0, template: `
15589
17230
  @if (showSceneBuildLoader && setSceneBuildLoader) {
15590
17231
  <co-configurator-scene-loader
@@ -15675,7 +17316,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
15675
17316
  encapsulation: ViewEncapsulation.None,
15676
17317
  standalone: false
15677
17318
  }]
15678
- }], ctorParameters: () => [{ type: ConfiguratorSettingsService }, { type: ConfiguratorRotationService }, { type: ConfiguratorDynamicCameraService }, { type: ConfiguratorSceneService }, { type: ConfiguratorEventService }, { type: ConfiguratorCameraService }, { type: ConfiguratorItemService }, { type: SwitchBuildFurnitureService }, { type: SceneOptionsService }, { type: DimensionsService }, { type: FloorPlaneService }], propDecorators: { canvasElement: [{
17319
+ }], ctorParameters: () => [{ type: ConfiguratorSettingsService }, { type: ConfiguratorRotationService }, { type: ConfiguratorDynamicCameraService }, { type: ConfiguratorSceneService }, { type: ConfiguratorEventService }, { type: ConfiguratorCameraService }, { type: ConfiguratorItemService }, { type: SwitchBuildFurnitureService }, { type: SceneOptionsService }, { type: DimensionsService }, { type: ConfiguratorConnectorService }, { type: SceneEventService }, { type: FloorPlaneService }], propDecorators: { canvasElement: [{
15679
17320
  type: ViewChild,
15680
17321
  args: ['canvas', { read: ElementRef }]
15681
17322
  }], elementToolbar: [{
@@ -15723,5 +17364,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
15723
17364
  * Generated bundle index. Do not edit.
15724
17365
  */
15725
17366
 
15726
- export { AnswerCardComponent, AnswerCardModule, AnswersInfoDialogComponent, AnswersInfoDialogModule, AnswersSlideoutComponent, AnswersSlideoutModule, ArFeature, ArPositionIndicator, CoSummaryLine, CoSummaryLineModule, ColorFilterComponent, ColorFilterModule, ConfigurationPresetComponent, ConfigurationPresetModule, ConfigurationResultObject, ConfiguratorArService, ConfiguratorCameraService, ConfiguratorCameraSettingsComponent, ConfiguratorComponent, ConfiguratorConnectorService, ConfiguratorDialogModule, ConfiguratorErrorDialogComponent, ConfiguratorErrorMessage, ConfiguratorEventService, ConfiguratorExportDialogComponent, ConfiguratorLoaderComponent, ConfiguratorLoaderModule, ConfiguratorModule, ConfiguratorSceneComponent, ConfiguratorSceneLoaderComponent, ConfiguratorSceneLoaderModule, ConfiguratorSceneModule, ConfiguratorSceneService, ConfiguratorVrService, ConfiguratorXrService, ConfiguringService, Controls, ElementButtonsComponent, ElementButtonsModule, ElementToolbarComponent, ElementToolbarModule, ImageZoomComponent, ImageZoomModule, LiteSelectorComponent, LiteSelectorModule, ProductConfiguratorComponent, ProductConfiguratorModule, ProductConfiguratorOptionCheckboxComponent, ProductConfiguratorSelectorComponent, ProductConfiguratorSelectorModule, ProductConfiguratorSelectorOptionButtonComponent, ProductConfiguratorSelectorOptionButtonModule, ProductConfiguratorSelectorOptionCheckboxModule, ProductConfiguratorSelectorOptionComponent, ProductConfiguratorSelectorOptionDropDownComponent, ProductConfiguratorSelectorOptionDropdownModule, ProductConfiguratorSelectorOptionModule, ProductConfiguratorSelectorOptionTileComponent, ProductConfiguratorSelectorOptionTileModule, ProgressBarComponent, ProgressBarModule, Reticle, SceneOptionsComponent, SelectionsModule, SelectionsSummaryComponent, SelectionsSummaryLineComponent, SelectionsSummaryModule, TagFilterComponent, TagFilterModule, XrMode };
17367
+ export { AnswerCardComponent, AnswerCardModule, AnswersInfoDialogComponent, AnswersInfoDialogModule, AnswersSlideoutComponent, AnswersSlideoutModule, ArFeature, ArPositionIndicator, CoSummaryLine, CoSummaryLineModule, ColorFilterComponent, ColorFilterModule, ConfigurationPresetComponent, ConfigurationPresetModule, ConfigurationResultObject, ConfiguratorArService, ConfiguratorCameraService, ConfiguratorCameraSettingsComponent, ConfiguratorComponent, ConfiguratorConnectorService, ConfiguratorDialogModule, ConfiguratorErrorDialogComponent, ConfiguratorErrorMessage, ConfiguratorEventService, ConfiguratorExportDialogComponent, ConfiguratorLoaderComponent, ConfiguratorLoaderModule, ConfiguratorModule, ConfiguratorSceneComponent, ConfiguratorSceneLoaderComponent, ConfiguratorSceneLoaderModule, ConfiguratorSceneModule, ConfiguratorSceneService, ConfiguratorVrService, ConfiguratorXrService, ConfiguringService, Controls, ElementButtonsComponent, ElementButtonsModule, ElementToolbarComponent, ElementToolbarModule, ImageZoomComponent, ImageZoomModule, LiteSelectorComponent, LiteSelectorModule, ProductConfiguratorChildArticleConfiguratorComponent, ProductConfiguratorComponent, ProductConfiguratorGroupedRepeatableOptionsComponent, ProductConfiguratorModule, ProductConfiguratorOptionCheckboxComponent, ProductConfiguratorSelectorChildArticleComponent, ProductConfiguratorSelectorComponent, ProductConfiguratorSelectorModule, ProductConfiguratorSelectorOptionButtonComponent, ProductConfiguratorSelectorOptionButtonModule, ProductConfiguratorSelectorOptionCheckboxModule, ProductConfiguratorSelectorOptionComponent, ProductConfiguratorSelectorOptionDropDownComponent, ProductConfiguratorSelectorOptionDropdownModule, ProductConfiguratorSelectorOptionModule, ProductConfiguratorSelectorOptionTileComponent, ProductConfiguratorSelectorOptionTileModule, ProductConfiguratorSlideoutComponent, ProgressBarComponent, ProgressBarModule, Reticle, SceneOptionsComponent, SelectionsModule, SelectionsSummaryComponent, SelectionsSummaryLineComponent, SelectionsSummaryModule, TagFilterComponent, TagFilterModule, XrMode };
15727
17368
  //# sourceMappingURL=colijnit-configurator.mjs.map