architwin 1.6.0 → 1.6.2

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.
@@ -1,4 +1,5 @@
1
1
  import log from 'loglevel';
2
+ import i18n from './i18n';
2
3
  export let activeActionBtn;
3
4
  export function renderActionBar() {
4
5
  const element = document.createElement('div');
@@ -8,27 +9,35 @@ export function renderActionBar() {
8
9
  element.innerHTML = `
9
10
  <div class="at_sidebar_action_button_icon" style="border-bottom: dotted white 1px;">
10
11
  <span class="mdi mdi-chevron-double-right" id="at-close-action-bar-btn" data-cy="at-close-action-bar-btn" target-pane="at-object-list-pane"></span>
12
+ <div class="at_icon_tooltip">${i18n.t('Close')}</div>
11
13
  </div>
12
14
  <div class="at_sidebar_action_button_icon">
13
- <span class="mdi mdi-axis-arrow" id="at-translate-action-btn" data-cy="at-translate-action-bar-btn"></span>
15
+ <span class="mdi mdi-axis-arrow " id="at-translate-action-btn" data-cy="at-translate-action-bar-btn"></span>
16
+ <div class="at_icon_tooltip">${i18n.t('Translate')}</div>
14
17
  </div>
15
18
  <div class="at_sidebar_action_button_icon">
16
19
  <span class="mdi mdi-rotate-orbit" id="at-rotate-action-btn" data-cy="at-rotate-action-bar-btn"></span>
20
+ <div class="at_icon_tooltip">${i18n.t('Rotate')}</div>
17
21
  </div>
18
22
  <div class="at_sidebar_action_button_icon">
19
23
  <span class="mdi mdi-arrow-expand-all" id="at-scale-action-btn" data-cy="at-scale-action-bar-btn"></span>
24
+ <div class="at_icon_tooltip">${i18n.t('Scale')}</div>
20
25
  </div>
21
26
  <div class="at_sidebar_action_button_icon">
22
27
  <span class="mdi mdi-content-copy" id="at-copy-action-btn" data-cy="at-copy-action-bar-btn"></span>
28
+ <div class="at_icon_tooltip">${i18n.t('Copy')}</div>
23
29
  </div>
24
30
  <div class="at_sidebar_action_button_icon">
25
31
  <span class="mdi mdi-undo-variant" id="at-undo-action-btn" data-cy="at-undo-action-bar-btn"></span>
32
+ <div class="at_icon_tooltip">${i18n.t('Undo')}</div>
26
33
  </div>
27
34
  <div class="at_sidebar_action_button_icon">
28
35
  <span class="mdi mdi-redo-variant" id="at-redo-action-btn" data-cy="at-redo-action-bar-btn"></span>
36
+ <div class="at_icon_tooltip">${i18n.t('Redo')}</div>
29
37
  </div>
30
38
  <div class="at_sidebar_action_button_icon">
31
39
  <span class="mdi mdi-cancel" id="at-cancel-action-btn" data-cy="at-cancel-action-bar-btn"></span>
40
+ <div class="at_icon_tooltip">${i18n.t('Cancel')}</div>
32
41
  </div>
33
42
  `;
34
43
  return element;
@@ -1,7 +1,8 @@
1
1
  import { IShowcaseObject } from "../../../types";
2
2
  import { I3DObject } from "../../../types";
3
- export declare function renderObjectCard(payload: IShowcaseObject): HTMLDivElement;
4
- export declare function renderObjectRow(payload: IShowcaseObject): HTMLDivElement;
3
+ import { Scene } from "../../../../bundle/sdk";
4
+ export declare function renderObjectCard(payload: IShowcaseObject, objectComponent?: Scene.IComponent): HTMLDivElement;
5
+ export declare function renderObjectRow(payload: IShowcaseObject, objectComponent?: Scene.IComponent): HTMLDivElement;
5
6
  export declare function setActiveCard(cardId: string): Promise<void>;
6
7
  export declare function clearActiveCard(): void;
7
8
  export declare function renderLibraryCard(payload: I3DObject): HTMLDivElement;
@@ -14,7 +14,7 @@ import { Notyf } from 'notyf';
14
14
  import i18n from './i18n';
15
15
  let activeCard, activeLibraryCard;
16
16
  let _basePath = '../../../../architwin/static';
17
- export function renderObjectCard(payload) {
17
+ export function renderObjectCard(payload, objectComponent) {
18
18
  if (!payload) {
19
19
  console.error("Cannot render card without object payload data");
20
20
  return;
@@ -39,6 +39,11 @@ export function renderObjectCard(payload) {
39
39
  }
40
40
  thumbnail = `${_basePath}/defaulthumbnail.png`;
41
41
  }
42
+ let isObjectVisible = false;
43
+ if (objectComponent) {
44
+ // @ts-ignore
45
+ isObjectVisible = objectComponent.mesh.visible;
46
+ }
42
47
  element.innerHTML = `
43
48
  <img class="at_image at_object_image" src="${thumbnail}" alt="Property Image" id="at-card-image-${payload.id}" data-cy="at-card-image-${payload.id}" card-id="${payload.id}">
44
49
  <div class="at_card-body" id="at-object-card-body-${payload.id}" card-id="${payload.id}">
@@ -56,7 +61,7 @@ export function renderObjectCard(payload) {
56
61
  </div>
57
62
  <div>
58
63
  <div class="at_button_icon" style="display:inline-block">
59
- <span class="mdi mdi-eye-off at_model_visibility_btn" id="at-visibility-model-${payload.id}-btn" data-cy="at-visibility-model-${payload.id}-btn" card-id="${payload.id}"></span>
64
+ <span class="mdi ${isObjectVisible ? 'mdi-eye-off' : 'mdi-eye'} at_model_visibility_btn" id="at-visibility-model-${payload.id}-btn" data-cy="at-visibility-model-${payload.id}-btn" card-id="${payload.id}"></span>
60
65
  </div>
61
66
  <div class="at_button_icon" style="display:inline-block">
62
67
  <span class="mdi mdi-delete-outline at_model_delete_btn" id="at-delete-model-${payload.id}-btn" data-cy="at-delete-model-${payload.id}-btn" card-id="${payload.id}"></span>
@@ -66,7 +71,7 @@ export function renderObjectCard(payload) {
66
71
  `;
67
72
  return element;
68
73
  }
69
- export function renderObjectRow(payload) {
74
+ export function renderObjectRow(payload, objectComponent) {
70
75
  if (!payload) {
71
76
  console.error("Cannot render card without object payload data");
72
77
  return;
@@ -79,6 +84,11 @@ export function renderObjectRow(payload) {
79
84
  element.setAttribute('id', `at-card-${payload.id}`);
80
85
  let object_data = {};
81
86
  object_data = payload.object_data;
87
+ let isObjectVisible = false;
88
+ if (objectComponent) {
89
+ // @ts-ignore
90
+ isObjectVisible = objectComponent.mesh.visible;
91
+ }
82
92
  element.innerHTML = `
83
93
  <div class="at_card-body" id="at-card-row-body-${payload.id}" card-id="${payload.id}">
84
94
  ${payload.object_data.name ?
@@ -95,7 +105,7 @@ export function renderObjectRow(payload) {
95
105
  </div>
96
106
  <div>
97
107
  <div class="at_button_icon" style="display:inline-block">
98
- <span class="mdi mdi-eye-off at_model_visibility_btn" id="at-visibility-model-${payload.id}-btn" data-cy="at-visibility-model-${payload.id}-btn" card-id="${payload.id}"></span>
108
+ <span class="mdi ${isObjectVisible ? 'mdi-eye-off' : 'mdi-eye'} at_model_visibility_btn" id="at-visibility-model-${payload.id}-btn" data-cy="at-visibility-model-${payload.id}-btn" card-id="${payload.id}"></span>
99
109
  </div>
100
110
  <div class="at_button_icon" style="display:inline-block">
101
111
  <span class="mdi mdi-delete-outline at_model_delete_btn" id="at-delete-model-${payload.id}-btn" data-cy="at-delete-model-${payload.id}-btn" card-id="${payload.id}"></span>
@@ -64,7 +64,20 @@ i18n
64
64
  "PressEsc": "Press the Esc key or cancel button to cancel placement",
65
65
  "DeleteObject": "Delete Object",
66
66
  "ConfirmDeleteObject": "Are you sure you want to delete this object? This action cannot be reversed",
67
- "FloorMapNotAvailable": "The floor image for this floor is currently unavailable"
67
+ "FloorMapNotAvailable": "The floor image for this floor is currently unavailable",
68
+ "Tag": "Tag",
69
+ "Object": "Object",
70
+ "Minimap": "Minimap",
71
+ "Meeting": "Meeting",
72
+ "Screenshot": "Screenshot",
73
+ "Close": "Close",
74
+ "Translate": "Translate",
75
+ "Rotate": "Rotate",
76
+ "Scale": "Scale",
77
+ "Copy": "Copy",
78
+ "Undo": "Undo",
79
+ "Redo": "Redo",
80
+ "Confirm": "Confirm"
68
81
  }
69
82
  },
70
83
  ja: {
@@ -123,7 +136,20 @@ i18n
123
136
  "PressEsc": "キャンセルするにはESCキーもしくはキャンセルボタンを押してください",
124
137
  "DeleteObject": "オブジェクト削除",
125
138
  "ConfirmDeleteObject": "本当に削除してもよろしいですか?(この操作は取り消せません)",
126
- "FloorMapNotAvailable": "このフロアのフロア画像は現在利用できません"
139
+ "FloorMapNotAvailable": "このフロアのフロア画像は現在利用できません",
140
+ "Tag": "タグ",
141
+ "Object": "オブジェクト",
142
+ "Minimap": "ミニマップ",
143
+ "Meeting": "打ち合わせ",
144
+ "Screenshot": "スクリーンショット",
145
+ "Close": "閉じる",
146
+ "Translate": "変形",
147
+ "Rotate": "回転",
148
+ "Scale": "拡大",
149
+ "Copy": "複写",
150
+ "Undo": "やり直し",
151
+ "Redo": "もう一度",
152
+ "Confirm": "確認する"
127
153
  }
128
154
  }
129
155
  },
@@ -1,5 +1,7 @@
1
1
  import { _mpConfig } from "../../../architwin";
2
2
  import log from 'loglevel';
3
+ import i18n from "./i18n";
4
+ import { toggleActionBar } from "../../events";
3
5
  export let activeMenu;
4
6
  export let isObjectListEnabled = true;
5
7
  export function renderMenuBar(iFrame) {
@@ -23,21 +25,27 @@ export function renderMenuBar(iFrame) {
23
25
  menuBarElement.innerHTML = `
24
26
  <div class="at_sidebar_button_icon">
25
27
  <span class="mdi mdi-bullseye" id="at-expand-btn" data-cy="at-expand-btn" target-pane="at-tag-list-pane"></span>
28
+ <div class="at_icon_tooltip">${i18n.t('Tag')}</div>
26
29
  </div>
27
30
  <div class="at_sidebar_button_icon" style="display:${isObjectListEnabled ? 'block' : 'none'}">
28
31
  <span class="mdi mdi-cube-outline" id="at-object-list-btn" data-cy="at-object-list-btn" target-pane="at-object-list-pane"></span>
32
+ <div class="at_icon_tooltip">${i18n.t('Object')}</div>
29
33
  </div>
30
34
  <div class="at_sidebar_button_icon">
31
35
  <span class="mdi mdi-map" id="at-minimap-btn" data-cy="at-minimap-btn" target-pane="at-map"></span>
36
+ <div class="at_icon_tooltip">${i18n.t('Minimap')}</div>
32
37
  </div>
33
38
  <div class="at_sidebar_button_icon" style="display:${isMeetingEnabled ? 'block' : 'none'}">
34
39
  <span class="mdi mdi-message-video" id="at-videocall-btn" data-cy="at-videocall-btn" target-pane="at-video-call-pane"></span>
40
+ div class="at_icon_tooltip">${i18n.t('Meeting')}</div>
35
41
  </div>
36
42
  <div class="at_sidebar_button_icon">
37
43
  <span class="mdi mdi-monitor-screenshot" id="at-screenshot-btn" data-cy="at-screenshot-btn"></span>
44
+ <div class="at_icon_tooltip">${i18n.t('Screenshot')}</div>
38
45
  </div>
39
46
  <div class="at_sidebar_button_icon">
40
47
  <span class="mdi mdi-palette" id="at-theme-picker-btn" data-cy="at-theme-picker-btn" target-pane="at-theme-pane"></span>
48
+ <div class="at_icon_tooltip">${i18n.t('Theme')}</div>
41
49
  </div>
42
50
  `;
43
51
  return menuBarElement;
@@ -61,6 +69,8 @@ export function setActiveMenu(id) {
61
69
  // remove
62
70
  log.info("removing active...");
63
71
  parent.classList.remove('at_sidebar_button_icon_active');
72
+ // Close action bar
73
+ toggleActionBar('hide');
64
74
  }
65
75
  else {
66
76
  // activate
@@ -2,6 +2,7 @@ import { degreesToRadians, radiansToDegrees, useCapitalizeFirstLetter } from "..
2
2
  import { getSelectedObject } from "../../../architwin";
3
3
  import { Notyf } from 'notyf';
4
4
  import log from 'loglevel';
5
+ import i18n from "./i18n";
5
6
  let notyf = new Notyf({ position: { x: 'left', y: 'bottom' }, duration: 4500 });
6
7
  export let activeModelControlPane = false;
7
8
  export let modelControlPane;
@@ -20,7 +21,7 @@ export function renderModelControlPane(type = 'Translate') {
20
21
  <div class="at_flex at_flex_column">
21
22
  <div class="at_form_container">
22
23
  <div class="at_flex at_space_between">
23
- <span class="at_bolder at_text_base" id="at-transform-type-title">${type}</span>
24
+ <span class="at_bolder at_text_base" id="at-transform-type-title">${i18n.t(type)}</span>
24
25
  <span class="mdi mdi-close at_text_base" style="cursor:pointer" id="at-close-model-controls"></span>
25
26
  </div>
26
27
  <div class="at_number_field">
@@ -38,7 +39,7 @@ export function renderModelControlPane(type = 'Translate') {
38
39
  <input type="number" id="at-input-z" class="at_rounded_input"/>
39
40
  <span class="at_bolder at_model_unit">m</span>
40
41
  </div>
41
- <button class="at_button at_primary_azusa" id="at-confirm-transform">Confirm</button>
42
+ <button class="at_button at_primary_azusa" id="at-confirm-transform">${i18n.t('Confirm')}</button>
42
43
  </div>
43
44
  </div>
44
45
  `;
@@ -65,7 +66,7 @@ export function setTransformType(type) {
65
66
  if (validTransformTypes.includes(type)) {
66
67
  const transformTypeTitle = document.getElementById('at-transform-type-title');
67
68
  if (transformTypeTitle) {
68
- transformTypeTitle.textContent = useCapitalizeFirstLetter(type);
69
+ transformTypeTitle.textContent = i18n.t(useCapitalizeFirstLetter(type));
69
70
  transformType = type.toLowerCase();
70
71
  setModelInputUnit(type);
71
72
  return;
@@ -1,7 +1,8 @@
1
1
  import { IShowcaseObject } from "../../../types";
2
+ import { Scene } from "../../../../bundle/sdk";
2
3
  export declare function renderObjectListPane(cardList: Array<IShowcaseObject>): HTMLElement;
3
- export declare function renderObjectCards(cardList: Array<IShowcaseObject>): void;
4
+ export declare function renderObjectCards(cardList: Array<IShowcaseObject>, objectComponents?: Array<Scene.IComponent>): void;
4
5
  export declare function addObjectCard(objectCards: HTMLElement, payload: IShowcaseObject): void;
5
6
  export declare function removeObjectCard(elementId: string): void;
6
7
  export declare function updateObjectCard(objectCards: HTMLElement, payload: IShowcaseObject): void;
7
- export declare function renderObjectList(cardList: Array<IShowcaseObject>): void;
8
+ export declare function renderObjectList(cardList: Array<IShowcaseObject>, objectComponents?: Array<Scene.IComponent>): void;
@@ -52,14 +52,22 @@ export function renderObjectListPane(cardList) {
52
52
  `;
53
53
  return element;
54
54
  }
55
- export function renderObjectCards(cardList) {
56
- console.log("renderObjectCards()");
55
+ export function renderObjectCards(cardList, objectComponents) {
56
+ console.log("renderObjectCards(): ", objectComponents);
57
57
  const objectCards = document.getElementById('at-object-cards');
58
58
  if (cardList && cardList.length > 0) {
59
59
  objectCards.innerHTML = ``;
60
60
  cardList.forEach(list => {
61
- const card = renderObjectCard(list);
62
- objectCards.appendChild(card);
61
+ if (objectComponents && objectComponents.length > 0) {
62
+ objectComponents.forEach(comp => {
63
+ const card = renderObjectCard(list, comp);
64
+ objectCards.appendChild(card);
65
+ });
66
+ }
67
+ else {
68
+ const card = renderObjectCard(list);
69
+ objectCards.appendChild(card);
70
+ }
63
71
  });
64
72
  batchAddEventListenerByClassName('at_object_image', (event) => __awaiter(this, void 0, void 0, function* () {
65
73
  //@ts-ignore
@@ -146,14 +154,22 @@ export function updateObjectCard(objectCards, payload) {
146
154
  targetCard.textContent = payload.object_data.name;
147
155
  }
148
156
  }
149
- export function renderObjectList(cardList) {
150
- console.log("renderObjectList()");
157
+ export function renderObjectList(cardList, objectComponents) {
158
+ console.log("renderObjectList(): ", objectComponents);
151
159
  const objectList = document.getElementById('at-object-cards');
152
160
  if (cardList && cardList.length > 0) {
153
161
  objectList.innerHTML = ``;
154
162
  cardList.forEach(list => {
155
- const card = renderObjectRow(list);
156
- objectList.appendChild(card);
163
+ if (objectComponents && objectComponents.length > 0) {
164
+ objectComponents.forEach(comp => {
165
+ const card = renderObjectRow(list, comp);
166
+ objectList.appendChild(card);
167
+ });
168
+ }
169
+ else {
170
+ const card = renderObjectRow(list);
171
+ objectList.appendChild(card);
172
+ }
157
173
  });
158
174
  batchAddEventListenerByClassName('at_card-body', (event) => __awaiter(this, void 0, void 0, function* () {
159
175
  //@ts-ignore
@@ -33,6 +33,7 @@ let currentTag = undefined;
33
33
  let modelsView = 'card';
34
34
  let iTag = null;
35
35
  let _currentPaneId;
36
+ let isPlacingTag = false;
36
37
  function batchAddEventListenerByClassName(className, callback) {
37
38
  if (className) {
38
39
  const elements = document.querySelectorAll(`.${className}`);
@@ -112,10 +113,10 @@ function toggleDisplayPane(targetId) {
112
113
  }
113
114
  }
114
115
  if (paneId === 'at-object-list-pane') {
115
- log.info("Render objects in list");
116
116
  const objectsInSpace = get3DXObjects();
117
+ const objectComponents = objectsInSpace.map(obj => obj.component);
117
118
  const spaceObjects = objectsInSpace.map(obj => obj.object);
118
- renderObjectCards(spaceObjects);
119
+ renderObjectCards(spaceObjects, objectComponents);
119
120
  if (targetId === 'at-cancel-library-btn') {
120
121
  yield cancelModelPlacement();
121
122
  }
@@ -363,6 +364,14 @@ function handlePlaceTag() {
363
364
  };
364
365
  moveTagBtn.addEventListener('click', () => __awaiter(this, void 0, void 0, function* () {
365
366
  var _a, _b;
367
+ if (isPlacingTag) {
368
+ notyf.open({
369
+ type: 'info',
370
+ message: 'Please wait for the current tag to be placed before placing a new one'
371
+ });
372
+ return;
373
+ }
374
+ isPlacingTag = true;
366
375
  const tag = Object.assign({}, initTagData);
367
376
  const payload = getTagFormData();
368
377
  if (!cancelTagPlacementPrompt) {
@@ -431,12 +440,14 @@ function handlePlaceTag() {
431
440
  log.info('_tags', _tags);
432
441
  log.info("Last Tag Pushed", currentTag);
433
442
  cancelTagPlacementPrompt.style.display = 'none';
443
+ isPlacingTag = false;
434
444
  // clearTagFormDropdown()
435
445
  });
436
446
  }
437
447
  }
438
448
  else {
439
449
  notyf.error(`${i18n.t('RequiredFieldsEmpty')}`);
450
+ isPlacingTag = false;
440
451
  }
441
452
  }
442
453
  else {
@@ -460,11 +471,13 @@ function handlePlaceTag() {
460
471
  currentTag = tags[tags.length - 1];
461
472
  log.info("Last Tag Pushed", tags[tags.length - 1]);
462
473
  cancelTagPlacementPrompt.style.display = 'none';
474
+ isPlacingTag = false;
463
475
  });
464
476
  }
465
477
  }
466
478
  else {
467
479
  notyf.error(`${i18n.t('RequiredFieldsEmpty')}`);
480
+ isPlacingTag = false;
468
481
  }
469
482
  }
470
483
  }
@@ -514,11 +527,13 @@ function handlePlaceTag() {
514
527
  log.info("tag not found");
515
528
  }
516
529
  cancelTagPlacementPrompt.style.display = 'none';
530
+ isPlacingTag = false;
517
531
  });
518
532
  }
519
533
  }
520
534
  else {
521
535
  notyf.error(`${i18n.t('RequiredFieldsEmpty')}`);
536
+ isPlacingTag = false;
522
537
  }
523
538
  }
524
539
  else {
@@ -550,11 +565,13 @@ function handlePlaceTag() {
550
565
  log.info("tag not found");
551
566
  }
552
567
  cancelTagPlacementPrompt.style.display = 'none';
568
+ isPlacingTag = false;
553
569
  });
554
570
  }
555
571
  }
556
572
  else {
557
573
  notyf.error(`${i18n.t('RequiredFieldsEmpty')}`);
574
+ isPlacingTag = false;
558
575
  }
559
576
  }
560
577
  }
@@ -584,6 +601,7 @@ function onDisposeTag() {
584
601
  clearTagFormDropdown();
585
602
  iTag = null;
586
603
  cancelTagPlacementPrompt.style.display = 'none';
604
+ isPlacingTag = false;
587
605
  return;
588
606
  }
589
607
  cancelMoveTag();
@@ -594,6 +612,7 @@ function onDisposeTag() {
594
612
  if (cancelTagPlacementPrompt) {
595
613
  cancelTagPlacementPrompt.style.display = 'none';
596
614
  }
615
+ isPlacingTag = false;
597
616
  });
598
617
  }
599
618
  function handleDisposeTag() {
@@ -615,10 +634,12 @@ function handleDisposeTag() {
615
634
  function handleSaveTag() {
616
635
  log.info('handleSaveTag()');
617
636
  const saveTagBtn = document.getElementById('at-save-tag-btn');
618
- saveTagBtn.addEventListener('click', () => __awaiter(this, void 0, void 0, function* () {
637
+ saveTagBtn.addEventListener('click', (event) => __awaiter(this, void 0, void 0, function* () {
638
+ var _a, _b;
619
639
  log.info("save clicked");
620
640
  const tagFormPayload = getTagFormData();
621
641
  log.info('=== tagFormPayload ===', tagFormPayload);
642
+ saveTagBtn.classList.add('at_disabled');
622
643
  if (tagFormMode == "ADD" /* FORM_MODE.ADD */) {
623
644
  log.info("FORM MODE", "ADD" /* FORM_MODE.ADD */);
624
645
  if (_tagCategories) {
@@ -632,6 +653,7 @@ function handleSaveTag() {
632
653
  }
633
654
  else {
634
655
  notyf.error(`${i18n.t('NoTagSave')}`);
656
+ saveTagBtn.classList.remove('at_disabled');
635
657
  }
636
658
  }
637
659
  else {
@@ -645,6 +667,7 @@ function handleSaveTag() {
645
667
  }
646
668
  else {
647
669
  notyf.error(`${i18n.t('NoTagSave')}`);
670
+ saveTagBtn.classList.remove('at_disabled');
648
671
  }
649
672
  }
650
673
  }
@@ -656,12 +679,14 @@ function handleSaveTag() {
656
679
  if (tagFormPayload && tagFormPayload.tagEmbed && _tags[index].media_url !== tagFormPayload.tagEmbed) {
657
680
  if ((yield isValidUrl(tagFormPayload.tagEmbed)) === false) {
658
681
  notyf.error(`${i18n.t('InvalidURL')}`);
682
+ saveTagBtn.classList.remove('at_disabled');
659
683
  return;
660
684
  }
661
685
  }
662
686
  if (_tagCategories) {
663
687
  if (selectedTag && tagFormPayload && tagFormPayload.tagName && tagFormPayload.tagCategoryId && tagFormPayload.tagSubcategoryId) {
664
688
  log.info('selectedTag', selectedTag);
689
+ const targetCategory = _tagCategories.find(cat => cat.uuid === tagFormPayload.tagCategoryId);
665
690
  if (index !== -1) {
666
691
  // Replace the existing object with the current payload
667
692
  editTagLabel({ tagId: selectedTag.json_data.id, label: tagFormPayload.tagName });
@@ -670,7 +695,23 @@ function handleSaveTag() {
670
695
  _tags[index].json_data.label = tagFormPayload.tagName;
671
696
  _tags[index].json_data.description = tagFormPayload.tagDescription;
672
697
  _tags[index].uuid = _tags[index].id.toString();
698
+ if (tagFormPayload.tagSubcategoryId !== _tags[index].category_uuid) {
699
+ try {
700
+ // set tag icon
701
+ const targetSubCat = targetCategory.subcategories.find(subcat => subcat.uuid === tagFormPayload.tagSubcategoryId);
702
+ log.info('__@ [onMoveTag] Icon URL: ', targetSubCat.json_data);
703
+ if (targetSubCat.json_data && targetSubCat.json_data.iconUrl && targetSubCat.json_data.iconUrl !== '' && targetSubCat.json_data.iconUrl.includes('https')) {
704
+ yield setTagIcon({ tag: selectedTag.json_data, iconName: (_a = targetSubCat.json_data.icon) !== null && _a !== void 0 ? _a : '', iconUrl: (_b = targetSubCat.json_data.iconUrl) !== null && _b !== void 0 ? _b : '', color: targetCategory.json_data.color.rgb });
705
+ log.info('__@ [onSaveTag] Tag icon set!');
706
+ }
707
+ }
708
+ catch (error) {
709
+ log.error('__@ [onSaveTag] Error on setTagIcon: ', error);
710
+ notyf.error("Error apply subcategory icon");
711
+ }
712
+ }
673
713
  _tags[index].category_uuid = tagFormPayload.tagSubcategoryId;
714
+ _tags[index].json_data.color = targetCategory.json_data.color.rgb;
674
715
  if (tagFormPayload.tagEmbed !== _tags[index].media_url) {
675
716
  const tagData = {
676
717
  id: _tags[index].json_data.id,
@@ -735,6 +776,7 @@ function handleSaveTag() {
735
776
  }
736
777
  clearTagFormDropdown();
737
778
  iTag = null;
779
+ saveTagBtn.classList.remove('at_disabled');
738
780
  }));
739
781
  }
740
782
  function handleScreenshot() {
@@ -987,7 +1029,8 @@ function handleSetModelsView() {
987
1029
  modelsView = 'card';
988
1030
  log.info("modelCardViewBtn", modelsView);
989
1031
  const spaceObjects = _3DXObjects.map(obj => obj.object);
990
- renderObjectCards(spaceObjects);
1032
+ const objectComponents = _3DXObjects.map(obj => obj.component);
1033
+ renderObjectCards(spaceObjects, objectComponents);
991
1034
  });
992
1035
  modelsListViewBtn.addEventListener('click', () => {
993
1036
  modelsListViewBtn.classList.add('at_ghost_active');
@@ -995,7 +1038,8 @@ function handleSetModelsView() {
995
1038
  modelsView = 'list';
996
1039
  log.info("modelListViewBtn", modelsView);
997
1040
  const spaceObjects = _3DXObjects.map(obj => obj.object);
998
- renderObjectList(spaceObjects);
1041
+ const objectComponents = _3DXObjects.map(obj => obj.component);
1042
+ renderObjectList(spaceObjects, objectComponents);
999
1043
  });
1000
1044
  }
1001
1045
  function handleSetLibraryModelsView() {
package/lib/minimap.js CHANGED
@@ -217,6 +217,7 @@ function setMap(mpSdk, appKey, mapId, openOnLoad) {
217
217
  minimap.style.position = 'absolute';
218
218
  minimap.style.zIndex = '20';
219
219
  minimap.setAttribute('id', _minimapId);
220
+ minimap.setAttribute('data-cy', _minimapId);
220
221
  _mapContainer.appendChild(minimap);
221
222
  }
222
223
  _mapContainer.setAttribute('class', 'floor' + currentFloor.sequence);
@@ -242,6 +243,7 @@ function setMap(mpSdk, appKey, mapId, openOnLoad) {
242
243
  thisSweep.style.position = 'absolute';
243
244
  thisSweep.style.zIndex = '30';
244
245
  thisSweep.setAttribute('id', 'p' + index);
246
+ thisSweep.setAttribute('data-cy', 'p' + index);
245
247
  thisSweep.setAttribute('floor-level', `${item.floorInfo.sequence}`);
246
248
  thisSweep.setAttribute('value', index);
247
249
  thisSweep.setAttribute('class', 'floor' + item.floorInfo.sequence);
@@ -341,6 +343,7 @@ function locateAvatar() {
341
343
  // thisAvatar.style.background = p.color
342
344
  // thisAvatar.style.opacity = '1'
343
345
  thisAvatar.setAttribute('id', 'a' + p.id);
346
+ thisAvatar.setAttribute('data-cy', 'a' + p.id);
344
347
  thisAvatar.setAttribute('value', p.id);
345
348
  const pShape = getColorShape(p.color);
346
349
  log.info('===pShape', pShape);
@@ -425,6 +428,7 @@ function renderOverlaySweep(item, socketId, color) {
425
428
  _thisParticipant.style.bottom = py * 100 + '%';
426
429
  _thisParticipant.setAttribute('id', socketId);
427
430
  _thisParticipant.setAttribute('value', socketId);
431
+ _thisParticipant.setAttribute('data-cy', socketId);
428
432
  _thisParticipant.setAttribute('class', 'floor' + item.floorInfo.sequence);
429
433
  //_thisParticipant.addEventListener('click', onSweepMove);
430
434
  //thisSweep.textContent = sweepIds[index];
@@ -825,6 +829,7 @@ function setStandaloneMap(modelId, appKey, mapId) {
825
829
  thisSweep.style.position = 'absolute';
826
830
  thisSweep.style.zIndex = '30';
827
831
  thisSweep.setAttribute('id', 'p' + swp.id);
832
+ thisSweep.setAttribute('data-cy', 'p' + swp.id);
828
833
  thisSweep.setAttribute('floor-level', `${swp.floor.sequence}`);
829
834
  thisSweep.setAttribute('value', swp.id);
830
835
  thisSweep.setAttribute('class', 'floor' + swp.floor.sequence);
package/lib/types.d.ts CHANGED
@@ -131,7 +131,6 @@ export interface IMPConfig {
131
131
  embedlyKey: string;
132
132
  meetSdkKey?: string;
133
133
  meetSecretKey?: string;
134
- avatartwinKey?: string;
135
134
  awsConfig?: AWSConfig;
136
135
  };
137
136
  debug?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "architwin",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
4
4
  "description": "ArchiTwin Library for Matterport",
5
5
  "main": "./lib/architwin.js",
6
6
  "types": "./lib/architwin.d.ts",
@@ -256,6 +256,49 @@
256
256
  color: var(--text-color-light);
257
257
  }
258
258
 
259
+ /* CSS for tooltip text */
260
+ .at_sidebar_button_icon:hover .at_icon_tooltip {
261
+ transition: opacity 0.3s ease;
262
+ visibility: visible;
263
+ opacity: 1;
264
+
265
+ }
266
+
267
+ .at_sidebar_action_button_icon:hover .at_icon_tooltip {
268
+ transition: opacity 0.3s ease;
269
+ visibility: visible;
270
+ opacity: 1;
271
+
272
+ }
273
+
274
+ .at_icon_tooltip {
275
+ position: absolute;
276
+ top: 50%;
277
+ right: calc(100% + 18px);
278
+ color: #fff;
279
+ transform: translateY(-50%);
280
+ font-size: 12px;
281
+ padding: 4px 8px;
282
+ border-radius: 4px;
283
+ white-space: nowrap;
284
+ z-index: 1;
285
+ visibility: hidden;
286
+ background-color: #2A2B26;
287
+ opacity: 0;
288
+ transition: opacity 0.3s ease;
289
+ }
290
+
291
+ .at_icon_tooltip::after {
292
+ content: "";
293
+ position: absolute;
294
+ top: 50%;
295
+ left: 100%;
296
+ margin-top: -5px;
297
+ border-width: 5px;
298
+ border-style: solid;
299
+ border-color: transparent transparent transparent #2A2B26;
300
+ }
301
+
259
302
  .at_sidebar_button_icon_active {
260
303
  border-radius: var(--border-radius);
261
304
  background-color: var(--bg-accent);