architwin 1.15.0 → 1.15.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.
- package/lib/architwin.d.ts +2 -1
- package/lib/architwin.js +1 -1
- package/lib/atwinui/components/toolbar/i18n.js +2 -1
- package/lib/atwinui/components/toolbar/index.d.ts +2 -1
- package/lib/atwinui/components/toolbar/index.js +3 -1
- package/lib/atwinui/components/toolbar/previewModal.d.ts +6 -0
- package/lib/atwinui/components/toolbar/previewModal.js +104 -0
- package/lib/atwinui/components/toolbar/spacePartition/roomFormPane.js +48 -42
- package/lib/atwinui/components/toolbar/spacePartition/roomTreePane.d.ts +6 -1
- package/lib/atwinui/components/toolbar/spacePartition/roomTreePane.js +54 -30
- package/lib/atwinui/components/toolbar/tagListPane.js +2 -2
- package/lib/atwinui/events.js +9 -1
- package/lib/loaders/polydrawerLoader.js +24 -5
- package/package.json +1 -1
- package/static/atwinui.css +338 -4
- package/static/utility.css +4 -1
|
@@ -538,7 +538,8 @@ i18n
|
|
|
538
538
|
"PressEscCancelRelocation": "再配置をキャンセルするには、Esc キーを押します。",
|
|
539
539
|
"Window": "建具",
|
|
540
540
|
"CannotBackDrawingMode": "描画モードがアクティブな間は戻ることができません。",
|
|
541
|
-
"PleaseOffDrawingMode": "操作を行う前に、描画モードをオフにしてください。"
|
|
541
|
+
"PleaseOffDrawingMode": "操作を行う前に、描画モードをオフにしてください。",
|
|
542
|
+
"Successfully Deleted Tag": "タグを削除しました"
|
|
542
543
|
}
|
|
543
544
|
}
|
|
544
545
|
},
|
|
@@ -3,6 +3,7 @@ import { setActiveMenu, clearActiveMenu, getObjectListStatus } from "./menuBar";
|
|
|
3
3
|
import { renderObjectCards, removeObjectCard } from "./objectListPane";
|
|
4
4
|
import { getTagFormData, setTagCategoriesOption, tagFormMode, selectedTag, renderCategoryDropdownOptions, toggleDropdown } from "./tagFormPane";
|
|
5
5
|
import { renderTags, renderTagRow, addClickEventToTagRow, setTagLink, getTagLink, selectedCategoryFilterId, selectedSubCategoryFilterId, filterTagList } from "./tagListPane";
|
|
6
|
+
import { renderPreviewModal, togglePreviewModal, closePreviewModal, setPreviewModalAction, activePreviewModal } from "./previewModal";
|
|
6
7
|
import { setActiveActionBtn, clearActiveActionBtn, toggleActionBarButtons } from "./actionBar";
|
|
7
8
|
import { renderLibraryCards } from "./libraryPane";
|
|
8
9
|
import { setActiveThemeCard } from "./themePane";
|
|
@@ -21,4 +22,4 @@ declare let actionBar: HTMLElement;
|
|
|
21
22
|
*/
|
|
22
23
|
declare function setPreferredLanguage(): void;
|
|
23
24
|
declare function renderToolbarUI(payload: IToolbarData): void;
|
|
24
|
-
export { actionBar, tagFormMode, selectedTag, selectedCategoryFilterId, selectedSubCategoryFilterId, renderToolbarUI, renderObjectCards, setActiveMenu, clearActiveMenu, setActiveActionBtn, renderLibraryCards, renderTags, getTagFormData, renderTagRow, addClickEventToTagRow, setTagCategoriesOption, setActiveThemeCard, setActiveCard, setActiveLibraryCard, clearActiveCard, clearActiveLibraryCard, removeObjectCard, renderRecepientOptions, renderTagMessages, createTagMessage, renderCategoryDropdownOptions, toggleDropdown, setTagLink, getTagLink, setTagMessagingDetails, clearTagFormDropdown, clearTagFilterDropdown, getObjectListStatus, toggleModal, setModalAction, toggleModelControl, toggleActionSettings, clearActiveActionBtn, toggleActionBarButtons, filterTagList, setPreferredLanguage };
|
|
25
|
+
export { actionBar, tagFormMode, selectedTag, selectedCategoryFilterId, selectedSubCategoryFilterId, renderToolbarUI, renderObjectCards, setActiveMenu, clearActiveMenu, setActiveActionBtn, renderLibraryCards, renderTags, getTagFormData, renderTagRow, addClickEventToTagRow, setTagCategoriesOption, setActiveThemeCard, setActiveCard, setActiveLibraryCard, clearActiveCard, clearActiveLibraryCard, removeObjectCard, renderRecepientOptions, renderTagMessages, createTagMessage, renderCategoryDropdownOptions, toggleDropdown, setTagLink, getTagLink, setTagMessagingDetails, clearTagFormDropdown, clearTagFilterDropdown, getObjectListStatus, toggleModal, setModalAction, toggleModelControl, toggleActionSettings, clearActiveActionBtn, toggleActionBarButtons, filterTagList, setPreferredLanguage, renderPreviewModal, togglePreviewModal, closePreviewModal, setPreviewModalAction, activePreviewModal };
|
|
@@ -7,6 +7,7 @@ import { renderViewingRemoteSpace } from "./viewingRemoteSpace";
|
|
|
7
7
|
import { renderAddObjectPane } from "./addObjectPane";
|
|
8
8
|
import { renderTagFormPane, getTagFormData, setTagCategoriesOption, tagFormMode, selectedTag, renderCategoryDropdownOptions, toggleDropdown } from "./tagFormPane";
|
|
9
9
|
import { renderTagListPane, renderTags, renderTagRow, addClickEventToTagRow, setTagLink, getTagLink, selectedCategoryFilterId, selectedSubCategoryFilterId, filterTagList } from "./tagListPane";
|
|
10
|
+
import { renderPreviewModal, togglePreviewModal, closePreviewModal, setPreviewModalAction, activePreviewModal } from "./previewModal";
|
|
10
11
|
import { renderAddMediascreenFormPane } from "./addMediascreenFormPane";
|
|
11
12
|
import { renderActionBar, setActiveActionBtn, clearActiveActionBtn, toggleActionBarButtons } from "./actionBar";
|
|
12
13
|
import { renderLibraryPane, renderLibraryCards } from "./libraryPane";
|
|
@@ -108,6 +109,7 @@ function renderToolbarUI(payload) {
|
|
|
108
109
|
pipeListPane = pipeList.renderPane();
|
|
109
110
|
pipeFormPane = pipeForm.renderPane();
|
|
110
111
|
renderModal();
|
|
112
|
+
renderPreviewModal();
|
|
111
113
|
sidebarContainer.appendChild(modelControlPane);
|
|
112
114
|
sidebarContainer.appendChild(basepointCalibratePane);
|
|
113
115
|
sidebarContainer.appendChild(actionBar);
|
|
@@ -165,4 +167,4 @@ function renderToolbarUI(payload) {
|
|
|
165
167
|
themeManager(config);
|
|
166
168
|
}
|
|
167
169
|
}
|
|
168
|
-
export { actionBar, tagFormMode, selectedTag, selectedCategoryFilterId, selectedSubCategoryFilterId, renderToolbarUI, renderObjectCards, setActiveMenu, clearActiveMenu, setActiveActionBtn, renderLibraryCards, renderTags, getTagFormData, renderTagRow, addClickEventToTagRow, setTagCategoriesOption, setActiveThemeCard, setActiveCard, setActiveLibraryCard, clearActiveCard, clearActiveLibraryCard, removeObjectCard, renderRecepientOptions, renderTagMessages, createTagMessage, renderCategoryDropdownOptions, toggleDropdown, setTagLink, getTagLink, setTagMessagingDetails, clearTagFormDropdown, clearTagFilterDropdown, getObjectListStatus, toggleModal, setModalAction, toggleModelControl, toggleActionSettings, clearActiveActionBtn, toggleActionBarButtons, filterTagList, setPreferredLanguage };
|
|
170
|
+
export { actionBar, tagFormMode, selectedTag, selectedCategoryFilterId, selectedSubCategoryFilterId, renderToolbarUI, renderObjectCards, setActiveMenu, clearActiveMenu, setActiveActionBtn, renderLibraryCards, renderTags, getTagFormData, renderTagRow, addClickEventToTagRow, setTagCategoriesOption, setActiveThemeCard, setActiveCard, setActiveLibraryCard, clearActiveCard, clearActiveLibraryCard, removeObjectCard, renderRecepientOptions, renderTagMessages, createTagMessage, renderCategoryDropdownOptions, toggleDropdown, setTagLink, getTagLink, setTagMessagingDetails, clearTagFormDropdown, clearTagFilterDropdown, getObjectListStatus, toggleModal, setModalAction, toggleModelControl, toggleActionSettings, clearActiveActionBtn, toggleActionBarButtons, filterTagList, setPreferredLanguage, renderPreviewModal, togglePreviewModal, closePreviewModal, setPreviewModalAction, activePreviewModal };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ModalContent } from '../../../types';
|
|
2
|
+
export declare let activePreviewModal: boolean;
|
|
3
|
+
export declare function renderPreviewModal(): void;
|
|
4
|
+
export declare function togglePreviewModal(visible?: boolean): void;
|
|
5
|
+
export declare function closePreviewModal(): void;
|
|
6
|
+
export declare function setPreviewModalAction(content: ModalContent, iframeSrc?: string): Promise<void>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
export let activePreviewModal = false;
|
|
11
|
+
export function renderPreviewModal() {
|
|
12
|
+
const element = document.createElement('div');
|
|
13
|
+
element.setAttribute('id', 'at-preview-modal-overlay');
|
|
14
|
+
element.setAttribute('data-cy', 'at-preview-modal-overlay');
|
|
15
|
+
element.innerHTML = `
|
|
16
|
+
<div class="at_preview_modal">
|
|
17
|
+
<div class="at_preview_modal-header">
|
|
18
|
+
<h2 class="at_preview_modal-title" id="at-preview-modal-content-heading" data-cy="at-preview-modal-content-heading"></h2>
|
|
19
|
+
<button class="at_preview_modal-close-btn" data-cy="at-preview-modal-close-btn">×</button>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="at_preview_modal-body">
|
|
22
|
+
<div class="at_preview_modal-content" id="at-preview-modal-content-subheading" data-cy="at-preview-modal-content-subheading">
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
`;
|
|
27
|
+
document.body.appendChild(element);
|
|
28
|
+
const modalOverlay = document.getElementById('at-preview-modal-overlay');
|
|
29
|
+
const modalCloseBtn = document.querySelector('.at_preview_modal-close-btn');
|
|
30
|
+
if (modalCloseBtn) {
|
|
31
|
+
modalCloseBtn.addEventListener('click', () => {
|
|
32
|
+
modalOverlay.classList.remove('show');
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
if (modalOverlay) {
|
|
36
|
+
modalOverlay.addEventListener('click', (event) => {
|
|
37
|
+
if (event.target === modalOverlay) {
|
|
38
|
+
modalOverlay.classList.remove('show');
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const handleEscape = (event) => {
|
|
43
|
+
if (event.key === 'Escape') {
|
|
44
|
+
modalOverlay.classList.remove('show');
|
|
45
|
+
document.removeEventListener('keydown', handleEscape);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
document.addEventListener('keydown', handleEscape);
|
|
49
|
+
}
|
|
50
|
+
export function togglePreviewModal(visible = true) {
|
|
51
|
+
const modalOverlay = document.getElementById('at-preview-modal-overlay');
|
|
52
|
+
if (!modalOverlay) {
|
|
53
|
+
console.error("Preview modal overlay is undefined");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (visible) {
|
|
57
|
+
modalOverlay.classList.add('show');
|
|
58
|
+
activePreviewModal = true;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
modalOverlay.classList.remove('show');
|
|
62
|
+
activePreviewModal = false;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
export function closePreviewModal() {
|
|
66
|
+
const modalOverlay = document.getElementById('at-preview-modal-overlay');
|
|
67
|
+
if (modalOverlay) {
|
|
68
|
+
modalOverlay.classList.remove('show');
|
|
69
|
+
activePreviewModal = false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export function setPreviewModalAction(content, iframeSrc) {
|
|
73
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
const modalAcceptBtn = document.querySelector('.at_modal-accept-button');
|
|
75
|
+
const modalTitle = document.getElementById('at-preview-modal-content-heading');
|
|
76
|
+
const modelDesc = document.getElementById('at-preview-modal-content-subheading');
|
|
77
|
+
if (content) {
|
|
78
|
+
if (modalTitle && content.title) {
|
|
79
|
+
modalTitle.textContent = content.title;
|
|
80
|
+
}
|
|
81
|
+
if (modelDesc) {
|
|
82
|
+
if (iframeSrc) {
|
|
83
|
+
// If iframeSrc is provided, create iframe instead of text
|
|
84
|
+
modelDesc.innerHTML = `<iframe src="${iframeSrc}" class="at_preview_modal-iframe"></iframe>`;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
modelDesc.innerHTML = `<div class="at_preview_modal-content">${content.description}</div>`;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// if (modalAcceptBtn) {
|
|
92
|
+
// if (content && content.buttonLabel) {
|
|
93
|
+
// modalAcceptBtn.textContent = content.buttonLabel
|
|
94
|
+
// }
|
|
95
|
+
// if (callback) {
|
|
96
|
+
// modalAcceptBtn.onclick = async () => {
|
|
97
|
+
// await callback()
|
|
98
|
+
// }
|
|
99
|
+
// }else{
|
|
100
|
+
// modalAcceptBtn.onclick = closePreviewModal
|
|
101
|
+
// }
|
|
102
|
+
// }
|
|
103
|
+
});
|
|
104
|
+
}
|
|
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import i18n from '../i18n';
|
|
11
11
|
import { SPACE_EVENTS } from "../../../../types";
|
|
12
12
|
import { batchAddEventListenerByClassName } from "../../../events";
|
|
13
|
-
import { startDraw, cancelDraw, disposeModel, _3DXObjects, getCurrentPolygon, dispatchSpaceEvent, enableVerticeControls, setCurrentPolygon, setMeshChildrenMaterialProperty, get3DXObjects, getChildrenOfModel, clearSelectedObject, renderPolygon, addUndoDrawActions, setWallBaseHeight, clearWallBaseHeight, setDrawingConfig, resetDrawingConfig, goToPosition } from '../../../../architwin';
|
|
13
|
+
import { startDraw, cancelDraw, disposeModel, _3DXObjects, getCurrentPolygon, dispatchSpaceEvent, enableVerticeControls, setCurrentPolygon, setMeshChildrenMaterialProperty, get3DXObjects, getChildrenOfModel, clearSelectedObject, renderPolygon, addUndoDrawActions, setWallBaseHeight, clearWallBaseHeight, setDrawingConfig, resetDrawingConfig, goToPosition, clearFloorBaseHeight } from '../../../../architwin';
|
|
14
14
|
import { generateUUID, extractUUID } from '../../../../utils';
|
|
15
15
|
import { getCurrentEditRoomData } from './roomTreePane';
|
|
16
16
|
import { toggleModal, setModalAction } from "../modal";
|
|
@@ -249,6 +249,7 @@ export function toggleDrawWindowButton() {
|
|
|
249
249
|
`;
|
|
250
250
|
const objectIndex = _3DXObjects.findIndex(obj => obj.object.id == currentObject.object.id);
|
|
251
251
|
log.info("objectIndex", objectIndex);
|
|
252
|
+
clearFloorBaseHeight();
|
|
252
253
|
drawingConfig = {
|
|
253
254
|
lineTypeComponentConfig: {
|
|
254
255
|
renderPolygonOnAdd: false,
|
|
@@ -1023,48 +1024,53 @@ function setupDeleteWindow(element, window) {
|
|
|
1023
1024
|
if (!deleteBtn)
|
|
1024
1025
|
return;
|
|
1025
1026
|
deleteBtn.addEventListener("click", () => {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
windowLists
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
_3DXObjects[objectIndex].children
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1027
|
+
if (!isDrawing) {
|
|
1028
|
+
toggleModal();
|
|
1029
|
+
setModalAction({
|
|
1030
|
+
title: i18n.t("DeleteWindow"),
|
|
1031
|
+
description: i18n.t("ConfirmDeleteWindow"),
|
|
1032
|
+
buttonLabel: i18n.t("YesDelete"),
|
|
1033
|
+
}, () => __awaiter(this, void 0, void 0, function* () {
|
|
1034
|
+
element.remove();
|
|
1035
|
+
log.info("Deleted window:", window.index);
|
|
1036
|
+
toggleModal(false);
|
|
1037
|
+
// Update wall windows
|
|
1038
|
+
currentPolygonData.walls = currentPolygonData.walls.map(wall => {
|
|
1039
|
+
if (wall.uuid !== currentWall.uuid)
|
|
1040
|
+
return wall;
|
|
1041
|
+
if (wall.windows.length === 1) {
|
|
1042
|
+
const windowLists = document.getElementById(`at-window-list-${wall.uuid}`);
|
|
1043
|
+
if (windowLists)
|
|
1044
|
+
windowLists.style.display = "none";
|
|
1045
|
+
}
|
|
1046
|
+
currentWall = Object.assign(Object.assign({}, wall), { windows: wall.windows.filter((w) => w.index !== window.index) });
|
|
1047
|
+
return currentWall;
|
|
1048
|
+
});
|
|
1049
|
+
const objectIndex = _3DXObjects.findIndex(obj => obj.object.object_id == currentObject.object.object_id);
|
|
1050
|
+
if (objectIndex != null) {
|
|
1051
|
+
log.info("objectIndex", objectIndex);
|
|
1052
|
+
if (_3DXObjects[objectIndex].children) {
|
|
1053
|
+
_3DXObjects[objectIndex].children.map((win) => __awaiter(this, void 0, void 0, function* () {
|
|
1054
|
+
log.info("WIND", win);
|
|
1055
|
+
if (win.index == window.index && win.wallUUID == currentWall.uuid) {
|
|
1056
|
+
yield disposeModel(win);
|
|
1057
|
+
}
|
|
1058
|
+
}));
|
|
1059
|
+
}
|
|
1057
1060
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
}
|
|
1061
|
+
// Save + rerender window
|
|
1062
|
+
currentObject.object.object_data.json_data = currentPolygonData;
|
|
1063
|
+
saveWallChanges();
|
|
1064
|
+
notify.success(`${i18n.t('SuccessWindowDelete')}`);
|
|
1065
|
+
log.info("currentPartition polygonJson", JSON.parse(currentPartitionData.polygon_json));
|
|
1066
|
+
log.info("currentObject", currentObject);
|
|
1067
|
+
log.info("currentWall", currentWall);
|
|
1068
|
+
log.info("currentPolygonData", currentPolygonData);
|
|
1069
|
+
}));
|
|
1070
|
+
}
|
|
1071
|
+
else {
|
|
1072
|
+
notify.error(i18n.t("PleaseOffDrawingMode"));
|
|
1073
|
+
}
|
|
1068
1074
|
});
|
|
1069
1075
|
}
|
|
1070
1076
|
/**
|
|
@@ -81,7 +81,7 @@ export declare function highlightSelectedPartitionChild(partitionId: string, nam
|
|
|
81
81
|
* @param name - The specific name/identifier of the child element whose container to toggle
|
|
82
82
|
* @param expand - Optional boolean to explicitly set expansion state (true = show, false = hide). If undefined, toggles current state
|
|
83
83
|
*/
|
|
84
|
-
export declare function
|
|
84
|
+
export declare function toggleExpandPartitionWallChild(partitionId: string, name: string, expand?: boolean): void;
|
|
85
85
|
/**
|
|
86
86
|
* Highlights the selected window element by toggling CSS classes and ensures its parent partition is expanded.
|
|
87
87
|
* @param wallUuid - The unique identifier of the wall containing the window elements
|
|
@@ -92,6 +92,11 @@ export declare function highlightSelectedWindow(wallUuid: string, index: number
|
|
|
92
92
|
* Removes the highlight from all selected window items by removing the 'selected' CSS class.
|
|
93
93
|
*/
|
|
94
94
|
export declare function toggleHighlightedWindowItem(): void;
|
|
95
|
+
/**
|
|
96
|
+
* Toggles the highlighted state of partition items by adding 'selected' class to the matching partition and removing it from others.
|
|
97
|
+
* @param partitionId - The partition ID to highlight (only the prefix before the first hyphen is used for matching)
|
|
98
|
+
*/
|
|
99
|
+
export declare function toggleHighlightedPartitionItem(partitionId: string): void;
|
|
95
100
|
/**
|
|
96
101
|
* Calculates the midpoint (centroid) of multiple 3D coordinates by averaging their x, y, and z values.
|
|
97
102
|
* @param coords - An array of objects containing start Vector3 coordinates
|
|
@@ -120,7 +120,7 @@ export function displayRoomPartition(partition, objectData) {
|
|
|
120
120
|
element.innerHTML = `
|
|
121
121
|
<li class="at_room_tree_parent">
|
|
122
122
|
<div id="at-div-room-${partition.uuid}" class="at_flex at_space_between at_toggle">
|
|
123
|
-
<span class="toggle selectable" id="at-room-${partition.uuid}">▶ ${partition.name}</span>
|
|
123
|
+
<span class="at_room_name_text toggle selectable" id="at-room-${partition.uuid}">▶ ${partition.name}</span>
|
|
124
124
|
<div>
|
|
125
125
|
<span id="at-room-edit-${partition.uuid}-btn" class="mdi mdi-pencil at_room_edit_btn" target-pane="at-room-form-pane"></span>
|
|
126
126
|
<span id="at-room-visibility-btn-${partition.uuid}" class="mdi ${isVisible ? 'mdi-eye ' : 'mdi-eye-off'} at_room_visible_btn"></span>
|
|
@@ -182,8 +182,8 @@ export function displayChildPartitions(partitions, parentPartitionId, objectData
|
|
|
182
182
|
return `
|
|
183
183
|
|
|
184
184
|
<li class="at_room_tree_child">
|
|
185
|
-
<div id="at-child-partition-${partition.uuid.split('-')[0]}" class="at_flex at_space_between at_toggle">
|
|
186
|
-
<span class="toggle selectable" id="at-partition-${partition.uuid}" object-id="${objectId}" parentId="at-partition-${parentPartitionId}">▶ ${i18n.t(`${partition.name}`)}</span>
|
|
185
|
+
<div id="at-child-partition-${partition.uuid.split('-')[0]}" class="at_partion_row_item at_flex at_space_between at_toggle">
|
|
186
|
+
<span class="at_partition_name_text toggle selectable" id="at-partition-${partition.uuid}" object-id="${objectId}" parentId="at-partition-${parentPartitionId}">▶ ${i18n.t(`${partition.name}`)}</span>
|
|
187
187
|
<div>
|
|
188
188
|
<span id="at-partition-visibility-btn-${objectId}" parent-id="${parentPartitionId}"
|
|
189
189
|
class="mdi ${isVisible ? 'mdi-eye ' : 'mdi-eye-off'} at_room_visible_btn"></span>
|
|
@@ -363,7 +363,7 @@ function toggleSelectedPartition() {
|
|
|
363
363
|
yield new Promise(resolve => setTimeout(resolve, 0));
|
|
364
364
|
yield new Promise(resolve => requestAnimationFrame(resolve));
|
|
365
365
|
const wallId = target.getAttribute('polygon-item-id');
|
|
366
|
-
const windowItems = document.querySelectorAll(`li.
|
|
366
|
+
const windowItems = document.querySelectorAll(`li.at_window_row_item[wall-id="${wallId}"]`);
|
|
367
367
|
if (windowItems && windowItems.length > 0) {
|
|
368
368
|
windowItems.forEach((windowLi) => {
|
|
369
369
|
const visibilityBtn = windowLi.querySelector('.at_child_visible_btn');
|
|
@@ -387,6 +387,7 @@ function toggleSelectedPartition() {
|
|
|
387
387
|
yield goToPosition(wallBottomMidPoint);
|
|
388
388
|
highlightSelectedPartitionChild(partitionId, objectName);
|
|
389
389
|
toggleHighlightedWindowItem();
|
|
390
|
+
toggleHighlightedPartitionItem(partitionId);
|
|
390
391
|
}
|
|
391
392
|
catch (e) {
|
|
392
393
|
log.info('goToPosition failed: ', e);
|
|
@@ -404,6 +405,7 @@ function toggleSelectedPartition() {
|
|
|
404
405
|
const floorMidPoint = calculateMidPoint(floorCoords);
|
|
405
406
|
yield goToPosition(floorMidPoint);
|
|
406
407
|
highlightSelectedPartitionChild(partitionId, objectName);
|
|
408
|
+
toggleHighlightedPartitionItem(partitionId);
|
|
407
409
|
}
|
|
408
410
|
catch (e) {
|
|
409
411
|
log.info('goToPosition failed: ', e);
|
|
@@ -441,18 +443,21 @@ function toggleSelectedPartition() {
|
|
|
441
443
|
log.info('goToPosition failed: ', e);
|
|
442
444
|
}
|
|
443
445
|
}));
|
|
444
|
-
batchAddEventListenerByClassName('
|
|
446
|
+
batchAddEventListenerByClassName('at_window_row_item', (event) => __awaiter(this, void 0, void 0, function* () {
|
|
445
447
|
event.stopPropagation();
|
|
446
448
|
const targetElement = event.currentTarget;
|
|
447
449
|
const wallUuid = targetElement.getAttribute('wall-id');
|
|
448
450
|
const windowIndex = targetElement.getAttribute('window-index');
|
|
451
|
+
const partitionId = targetElement.getAttribute('partition-id');
|
|
449
452
|
const windowCoordsEncoded = targetElement.getAttribute('window-coords');
|
|
450
453
|
const windowCoordsJSON = atob(windowCoordsEncoded);
|
|
451
454
|
const windowCoords = JSON.parse(windowCoordsJSON);
|
|
452
455
|
try {
|
|
453
456
|
const windowBottomMidPoint = calculateMidPoint(windowCoords);
|
|
454
457
|
yield goToPosition(windowBottomMidPoint);
|
|
458
|
+
toggleHighlightedWindowItem();
|
|
455
459
|
highlightSelectedWindow(wallUuid, windowIndex);
|
|
460
|
+
toggleHighlightedPartitionItem(partitionId);
|
|
456
461
|
}
|
|
457
462
|
catch (e) {
|
|
458
463
|
log.info('goToPosition failed: ', e);
|
|
@@ -720,20 +725,15 @@ export function highlightSelectedPartitionChild(partitionId, name) {
|
|
|
720
725
|
partitionChildren.forEach((partitionChild) => {
|
|
721
726
|
const isSelected = partitionChild.id === targetId;
|
|
722
727
|
const header = partitionChild.querySelector('.at_partition_child_header');
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
arrow.textContent = arrow.textContent.replace('▼', '▶');
|
|
733
|
-
toggleExpandParitionWallChild(partitionId, name, true);
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
}
|
|
728
|
+
const listContainer = partitionChild.querySelector('.at_wall_children_container');
|
|
729
|
+
const arrow = header === null || header === void 0 ? void 0 : header.querySelector('.at_partition_child_expand_icon');
|
|
730
|
+
header === null || header === void 0 ? void 0 : header.classList.toggle('selected', isSelected);
|
|
731
|
+
if (!header || !(arrow === null || arrow === void 0 ? void 0 : arrow.textContent) || !listContainer)
|
|
732
|
+
return;
|
|
733
|
+
// for selected: toggle expand/collapse, for non-selected: always collapse
|
|
734
|
+
const shouldExpand = isSelected && arrow.textContent.includes('▶');
|
|
735
|
+
arrow.textContent = arrow.textContent.replace(shouldExpand ? '▶' : '▼', shouldExpand ? '▼' : '▶');
|
|
736
|
+
listContainer.classList.toggle('at_hidden', !shouldExpand);
|
|
737
737
|
});
|
|
738
738
|
}
|
|
739
739
|
/**
|
|
@@ -742,20 +742,27 @@ export function highlightSelectedPartitionChild(partitionId, name) {
|
|
|
742
742
|
* @param name - The specific name/identifier of the child element whose container to toggle
|
|
743
743
|
* @param expand - Optional boolean to explicitly set expansion state (true = show, false = hide). If undefined, toggles current state
|
|
744
744
|
*/
|
|
745
|
-
export function
|
|
745
|
+
export function toggleExpandPartitionWallChild(partitionId, name, expand) {
|
|
746
746
|
const partitionChildren = document.querySelectorAll(`li[partition-li-id="${partitionId}"]`);
|
|
747
747
|
const targetId = `partition-child-${name}`;
|
|
748
748
|
partitionChildren.forEach((partitionChild) => {
|
|
749
749
|
const isSelected = partitionChild.id === targetId;
|
|
750
|
+
const header = partitionChild.querySelector('.at_partition_child_header');
|
|
750
751
|
const listContainer = partitionChild.querySelector('.at_wall_children_container');
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
752
|
+
const arrow = header === null || header === void 0 ? void 0 : header.querySelector('.at_partition_child_expand_icon');
|
|
753
|
+
if (!header || !(arrow === null || arrow === void 0 ? void 0 : arrow.textContent) || !listContainer)
|
|
754
|
+
return;
|
|
755
|
+
// Determine if should be expanded
|
|
756
|
+
let shouldExpand;
|
|
757
|
+
if (isSelected) {
|
|
758
|
+
shouldExpand = expand !== undefined ? expand : !arrow.textContent.includes('▶');
|
|
759
|
+
}
|
|
760
|
+
else {
|
|
761
|
+
shouldExpand = false;
|
|
758
762
|
}
|
|
763
|
+
// Update arrow and container based on shouldExpand
|
|
764
|
+
arrow.textContent = arrow.textContent.replace(shouldExpand ? '▶' : '▼', shouldExpand ? '▼' : '▶');
|
|
765
|
+
listContainer.classList.toggle('at_hidden', !shouldExpand);
|
|
759
766
|
});
|
|
760
767
|
}
|
|
761
768
|
function displayWindows(wall, partitionId, parentId) {
|
|
@@ -767,7 +774,7 @@ function displayWindows(wall, partitionId, parentId) {
|
|
|
767
774
|
const windowCoords = JSON.stringify(window.edges);
|
|
768
775
|
const windowCoordsEncoded = btoa(windowCoords);
|
|
769
776
|
itemsHTML += `
|
|
770
|
-
<li window-coords="${windowCoordsEncoded}" id="window-${wall.uuid}-${window.index}" wall-id="${wall.uuid}" window-name="${window.name}" window-index="${window.index}" class="
|
|
777
|
+
<li window-coords="${windowCoordsEncoded}" partition-id="${partitionId}" id="window-${wall.uuid}-${window.index}" wall-id="${wall.uuid}" window-name="${window.name}" window-index="${window.index}" class="at_window_row_item">
|
|
771
778
|
<div>${window.name}</div>
|
|
772
779
|
<div>
|
|
773
780
|
<span window-coords="${windowCoordsEncoded}" partition-id="${partitionId}" partition-parent-uuid="${parentId}" polygon-item-id="${wall.uuid}" index="${window.index}" class="mdi mdi-pencil at_window_edit_btn"></span>
|
|
@@ -843,7 +850,7 @@ export function highlightSelectedWindow(wallUuid, index) {
|
|
|
843
850
|
const parentWallItem = windowElement.closest('li.at_partition_wall_row_item');
|
|
844
851
|
const partitionId = parentWallItem.getAttribute('partition-li-id');
|
|
845
852
|
const objectName = parentWallItem.getAttribute('object-name');
|
|
846
|
-
|
|
853
|
+
toggleExpandPartitionWallChild(partitionId, objectName, true);
|
|
847
854
|
}
|
|
848
855
|
windowElement.classList.toggle('selected', windowElement.id === targetId);
|
|
849
856
|
});
|
|
@@ -852,11 +859,28 @@ export function highlightSelectedWindow(wallUuid, index) {
|
|
|
852
859
|
* Removes the highlight from all selected window items by removing the 'selected' CSS class.
|
|
853
860
|
*/
|
|
854
861
|
export function toggleHighlightedWindowItem() {
|
|
855
|
-
const windowItems = document.querySelectorAll('li.
|
|
862
|
+
const windowItems = document.querySelectorAll('li.at_window_row_item.selected');
|
|
856
863
|
windowItems.forEach(el => {
|
|
857
864
|
el.classList.remove('selected');
|
|
858
865
|
});
|
|
859
866
|
}
|
|
867
|
+
/**
|
|
868
|
+
* Toggles the highlighted state of partition items by adding 'selected' class to the matching partition and removing it from others.
|
|
869
|
+
* @param partitionId - The partition ID to highlight (only the prefix before the first hyphen is used for matching)
|
|
870
|
+
*/
|
|
871
|
+
export function toggleHighlightedPartitionItem(partitionId) {
|
|
872
|
+
const partitions = document.querySelectorAll('div.at_partion_row_item');
|
|
873
|
+
partitions === null || partitions === void 0 ? void 0 : partitions.forEach(partition => {
|
|
874
|
+
if (partition.getAttribute('id') === `at-child-partition-${partitionId.split('-')[0]}`) {
|
|
875
|
+
partition.classList.add('selected');
|
|
876
|
+
partition.querySelector('.at_partition_name_text').classList.add('selected'); // Added dot
|
|
877
|
+
}
|
|
878
|
+
else {
|
|
879
|
+
partition.classList.remove('selected');
|
|
880
|
+
partition.querySelector('.at_partition_name_text').classList.remove('selected'); // Added dot
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
}
|
|
860
884
|
/**
|
|
861
885
|
* Calculates the midpoint (centroid) of multiple 3D coordinates by averaging their x, y, and z values.
|
|
862
886
|
* @param coords - An array of objects containing start Vector3 coordinates
|
|
@@ -245,7 +245,7 @@ export function renderTags(tags, showOwnTagsOnly = false) {
|
|
|
245
245
|
const payload = { tag: targetTag };
|
|
246
246
|
dispatchSpaceEvent(SPACE_EVENTS.TAG_DISPOSED, payload);
|
|
247
247
|
toggleModal(false);
|
|
248
|
-
notify.success(
|
|
248
|
+
notify.success(i18n.t('Successfully deleted tag'));
|
|
249
249
|
}
|
|
250
250
|
else {
|
|
251
251
|
toggleModal(false);
|
|
@@ -414,7 +414,7 @@ export function addClickEventToTagRow(tag) {
|
|
|
414
414
|
yield disposeTag({ tagId: tagId });
|
|
415
415
|
const tagRow = document.getElementById(`at-tag-row-${tagId}`);
|
|
416
416
|
tagRow.remove();
|
|
417
|
-
notify.success(
|
|
417
|
+
notify.success(i18n.t('Successfully deleted tag'));
|
|
418
418
|
}
|
|
419
419
|
else {
|
|
420
420
|
notify.error("Tag id not found!");
|
package/lib/atwinui/events.js
CHANGED
|
@@ -3776,7 +3776,15 @@ function handleClickEventInTagSortOption() {
|
|
|
3776
3776
|
if (closestOption) {
|
|
3777
3777
|
const sortOption = closestOption.dataset.sort;
|
|
3778
3778
|
updateSelectedTagSortOption(sortOption);
|
|
3779
|
-
|
|
3779
|
+
log.info("_@ _tags: ", _tags);
|
|
3780
|
+
let tags;
|
|
3781
|
+
if (currentTagPaneMode == TAG_TYPE.MP) {
|
|
3782
|
+
tags = getMpTags().filter(tag => (tag.tag_type === TAG_TYPE.MP || tag.tag_type === undefined));
|
|
3783
|
+
}
|
|
3784
|
+
else {
|
|
3785
|
+
tags = getMpTags().filter(tag => tag.tag_type === TAG_TYPE.IOT);
|
|
3786
|
+
}
|
|
3787
|
+
// const tags = getMpTags()
|
|
3780
3788
|
const filteredTags = filterTagList(tags);
|
|
3781
3789
|
const sortConfig = sortTagOptions[sortOption] || { by: 'label', order: 'asc' };
|
|
3782
3790
|
if (selectedCategoryFilterId || selectedSubCategoryFilterId) {
|
|
@@ -1114,12 +1114,31 @@ export class BufferGeometry {
|
|
|
1114
1114
|
const p2 = new THREE.Vector3(path3D[2].x, path3D[2].y, path3D[2].z);
|
|
1115
1115
|
const v1 = new THREE.Vector3().subVectors(p1, p0);
|
|
1116
1116
|
const v2 = new THREE.Vector3().subVectors(p2, p0);
|
|
1117
|
-
|
|
1117
|
+
let normal = new THREE.Vector3().crossVectors(v1, v2);
|
|
1118
1118
|
const normalLen = normal.length();
|
|
1119
1119
|
if (normalLen === 0) {
|
|
1120
1120
|
continue;
|
|
1121
1121
|
}
|
|
1122
1122
|
normal.divideScalar(normalLen);
|
|
1123
|
+
// CRITICAL FIX: Ensure normal points outward from the wall
|
|
1124
|
+
// Calculate the centroid of the main polygon (floor)
|
|
1125
|
+
const centroid = new THREE.Vector3();
|
|
1126
|
+
for (const point of this.inputs.path) {
|
|
1127
|
+
centroid.add(new THREE.Vector3(point.x, point.y, point.z));
|
|
1128
|
+
}
|
|
1129
|
+
centroid.divideScalar(this.inputs.path.length);
|
|
1130
|
+
// Calculate window center
|
|
1131
|
+
const windowCenter = new THREE.Vector3();
|
|
1132
|
+
for (const point of path3D) {
|
|
1133
|
+
windowCenter.add(new THREE.Vector3(point.x, point.y, point.z));
|
|
1134
|
+
}
|
|
1135
|
+
windowCenter.divideScalar(path3D.length);
|
|
1136
|
+
// Vector from centroid to window center
|
|
1137
|
+
const outwardVector = new THREE.Vector3().subVectors(windowCenter, centroid);
|
|
1138
|
+
// If normal points inward (dot product < 0), flip it
|
|
1139
|
+
if (normal.dot(outwardVector) < 0) {
|
|
1140
|
+
normal.negate();
|
|
1141
|
+
}
|
|
1123
1142
|
const uAxis = v1.clone().normalize();
|
|
1124
1143
|
const vAxis = new THREE.Vector3().crossVectors(normal, uAxis).normalize();
|
|
1125
1144
|
const shapePoints2D = [];
|
|
@@ -1140,8 +1159,8 @@ export class BufferGeometry {
|
|
|
1140
1159
|
const basisMatrix = new THREE.Matrix4().makeBasis(uAxis, vAxis, normal);
|
|
1141
1160
|
const translation = new THREE.Matrix4().makeTranslation(p0.x, p0.y, p0.z);
|
|
1142
1161
|
const worldMatrix = new THREE.Matrix4().multiplyMatrices(translation, basisMatrix);
|
|
1143
|
-
// Apply a small offset along the wall normal to avoid z-fighting
|
|
1144
|
-
const offset = -0.
|
|
1162
|
+
// Apply a small offset along the wall normal to avoid z-fighting
|
|
1163
|
+
const offset = -0.08;
|
|
1145
1164
|
const offsetMatrix = new THREE.Matrix4().makeTranslation(normal.x * offset, normal.y * offset, normal.z * offset);
|
|
1146
1165
|
const finalMatrix = new THREE.Matrix4().multiplyMatrices(offsetMatrix, worldMatrix);
|
|
1147
1166
|
windowGeometry.applyMatrix4(finalMatrix);
|
|
@@ -1192,7 +1211,6 @@ export class BufferGeometry {
|
|
|
1192
1211
|
let windowLabelText = windows[i].name ? `${windows[i].name}` : windowMesh.name;
|
|
1193
1212
|
windowLabelText = windows[i].material ? `${windowLabelText}_${windows[i].material}: ${windowDimension.area.toFixed(2)}m²` : `${windowLabelText}: ${windowDimension.area.toFixed(2)}m²`;
|
|
1194
1213
|
log.info("windowLabelText ", windowLabelText);
|
|
1195
|
-
//const windowLabel = windows[i].name ? `${windows[i].name}_${windows[i].material}` : `Window ${i}_${windows[i].material}`
|
|
1196
1214
|
const windowCanvas = this.createLabelCanvas(windowLabelText);
|
|
1197
1215
|
const windowArea = Math.abs(twiceSignedArea * 0.5);
|
|
1198
1216
|
const labelWidth = Math.max(0.5, Math.min(2, Math.sqrt(Math.max(0.0001, windowArea))));
|
|
@@ -1209,11 +1227,12 @@ export class BufferGeometry {
|
|
|
1209
1227
|
.addScaledVector(vAxis, centerV)
|
|
1210
1228
|
.add(p0);
|
|
1211
1229
|
const labelOffset = 0.01;
|
|
1230
|
+
// Position label slightly offset from window, facing inward (opposite to normal)
|
|
1212
1231
|
windowCenterLabel.position.copy(center3D).addScaledVector(normal.clone().negate(), labelOffset);
|
|
1213
1232
|
windowCenterLabel.name = windowMesh.name;
|
|
1214
1233
|
windowCenterLabel.visible = windows[i].options ? windows[i].options.is_visible : true;
|
|
1234
|
+
// Make label face inward (opposite direction of the outward normal)
|
|
1215
1235
|
windowCenterLabel.lookAt(windowCenterLabel.position.clone().add(normal.clone().negate()));
|
|
1216
|
-
//windowCenterLabel.name = windows[i].uuid ? `${windows[i].uuid}_windowLabel` : `windowLabel-${i}`;
|
|
1217
1236
|
this.groupedMesh.add(windowCenterLabel);
|
|
1218
1237
|
}
|
|
1219
1238
|
catch (e) {
|