architwin 1.14.9 → 1.14.11
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/atwinui/components/toolbar/i18n.js +1 -1
- package/lib/atwinui/components/toolbar/spacePartition/roomFormPane.js +28 -44
- package/lib/atwinui/components/toolbar/spacePartition/roomTreePane.js +1 -1
- package/lib/atwinui/components/toolbar/tagIotFormPane.d.ts +1 -0
- package/lib/atwinui/components/toolbar/tagIotFormPane.js +163 -96
- package/lib/atwinui/components/toolbar/viewingRemoteSpace.d.ts +1 -0
- package/lib/atwinui/components/toolbar/viewingRemoteSpace.js +6 -0
- package/lib/atwinui/events.js +3 -1
- package/lib/loaders/polydrawerLoader.d.ts +16 -0
- package/lib/loaders/polydrawerLoader.js +130 -15
- package/lib/types.d.ts +2 -0
- package/lib/types.js +1 -0
- package/package.json +1 -1
- package/static/atwinui.css +2 -1
|
@@ -219,7 +219,7 @@ i18n
|
|
|
219
219
|
"ViewingInstructions": "During a remote space sharing session, you cannot navigate around the space, only your host has control during the session",
|
|
220
220
|
"Pending": "Pending",
|
|
221
221
|
"NowSharing": "Now Sharing",
|
|
222
|
-
"ConfirmLeaveSession": "
|
|
222
|
+
"ConfirmLeaveSession": "Do you want to leave sharing session?",
|
|
223
223
|
"ConfirmLeaveSessionReminder": "",
|
|
224
224
|
"InSession": "In Session",
|
|
225
225
|
"Leave": "Leave",
|
|
@@ -54,7 +54,7 @@ export function renderRoomFormPane() {
|
|
|
54
54
|
</div>
|
|
55
55
|
<form class="at_form_container at_scrollable_container at_h-min-70" id="at-room-form" data-cy="at-room-form">
|
|
56
56
|
<div class="at-field at_flex_row">
|
|
57
|
-
<label for="">${i18n.t('Name')}</label>
|
|
57
|
+
<label for="" style="font-size: 0.95rem;">${i18n.t('Name')}</label>
|
|
58
58
|
<input class="at_field_input at_w-full" type="text" name="room_name" id="at-room-name-input" data-cy="at-room-name-input" placeholder="Room 1">
|
|
59
59
|
</div>
|
|
60
60
|
<div class="at-field at_flex_column">
|
|
@@ -105,13 +105,13 @@ export function renderRoomFormPane() {
|
|
|
105
105
|
<span class="mdi mdi-chevron-left at_back_btn" id="at-back-floors"></span>
|
|
106
106
|
<label for="">
|
|
107
107
|
<span class="mdi mdi-vector-polygon"></span>
|
|
108
|
-
|
|
108
|
+
<span id="at-wall-name"></span>
|
|
109
109
|
</label>
|
|
110
110
|
<div> </div>
|
|
111
111
|
</div>
|
|
112
112
|
|
|
113
113
|
<div class="at_edit_name" id="at-edit-wall-material" style="display: none;">
|
|
114
|
-
<input class="at_edit_name_input" type="text" id="at-edit-wall-input" data-cy="at-edit-wall-material-input" placeholder="${i18n.t('EnterWallMaterial')}" disabled>
|
|
114
|
+
<input class="at_edit_name_input" type="text" id="at-edit-wall-input" data-cy="at-edit-wall-material-input" placeholder="${i18n.t('EnterWallMaterial')}" disabled style="font-size: 0.75rem !important;">
|
|
115
115
|
<span class="mdi mdi-pencil" style="display: none; cursor: pointer;" id="at-wall-edit-material-btn"></span>
|
|
116
116
|
<span class="mdi mdi-check" id="at-confirm-edit-wall-btn" style="display: none;"></span>
|
|
117
117
|
</div>
|
|
@@ -247,6 +247,7 @@ export function toggleDrawWindowButton() {
|
|
|
247
247
|
targetUUID: currentWall.uuid
|
|
248
248
|
}
|
|
249
249
|
};
|
|
250
|
+
log.info("drawingConfig", drawingConfig);
|
|
250
251
|
setDrawingConfig(drawingConfig);
|
|
251
252
|
startDraw();
|
|
252
253
|
}
|
|
@@ -733,43 +734,17 @@ function displayFaces(polygon) {
|
|
|
733
734
|
floorMaterialEdit.style.display = "none";
|
|
734
735
|
floorMaterialConfirm.style.display = "block";
|
|
735
736
|
}));
|
|
736
|
-
addEventListenerById('at-confirm-edit-wall-btn', (
|
|
737
|
+
addEventListenerById('at-confirm-edit-wall-btn', () => __awaiter(this, void 0, void 0, function* () {
|
|
737
738
|
console.log('@caroline wall check', wallMaterial, currentWall.material, currentWall);
|
|
738
739
|
const wallEditMaterial = document.getElementById('at-wall-edit-material-btn');
|
|
739
740
|
const wallConfirmMaterial = document.getElementById('at-confirm-edit-wall-btn');
|
|
740
741
|
const wallMaterialInput = document.getElementById('at-edit-wall-input');
|
|
741
|
-
const
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
}
|
|
748
|
-
currentPartitionData.polygon_json = JSON.stringify(partitionData);
|
|
749
|
-
console.log('@caroline partition data: ', currentPartitionData);
|
|
750
|
-
}
|
|
751
|
-
currentPartitionDataArray.some(partition => {
|
|
752
|
-
const parsed = JSON.parse(partition.polygon_json);
|
|
753
|
-
parsed.walls.find(wall => {
|
|
754
|
-
if (wall.uuid == currentWall.uuid) {
|
|
755
|
-
wall.material = wallMaterial;
|
|
756
|
-
}
|
|
757
|
-
});
|
|
758
|
-
});
|
|
759
|
-
console.log('[wall] currentPartition: ', currentPartition);
|
|
760
|
-
if (currentPartition) {
|
|
761
|
-
const wall = currentPartition.object.object_data.json_data.walls.find(wall => wall.uuid == currentWall.uuid);
|
|
762
|
-
wall.material = wallMaterial;
|
|
763
|
-
}
|
|
764
|
-
currentWall.material = wallMaterial;
|
|
765
|
-
//rerender to display material value in space
|
|
766
|
-
const polyData = {
|
|
767
|
-
uuid: currentPartition.object.object_data.uuid,
|
|
768
|
-
polygon_json: partitionData
|
|
769
|
-
};
|
|
770
|
-
// renderPolygon(polyData)
|
|
771
|
-
console.log('[wall] Partition to be saved: ', currentPartitionData, JSON.parse(currentPartitionData.polygon_json));
|
|
772
|
-
dispatchSpaceEvent(SPACE_EVENTS.PARTITION_EDITED, { data: currentPartitionData });
|
|
742
|
+
const newMaterial = wallMaterialInput.value.trim();
|
|
743
|
+
log.info("newMaterial", newMaterial);
|
|
744
|
+
currentWall.material = newMaterial;
|
|
745
|
+
log.info("currentWall", currentWall);
|
|
746
|
+
log.info("currentObject", currentObject);
|
|
747
|
+
saveWallChanges();
|
|
773
748
|
wallMaterialInput.disabled = true;
|
|
774
749
|
wallEditMaterial.style.display = "block";
|
|
775
750
|
wallConfirmMaterial.style.display = "none";
|
|
@@ -804,8 +779,8 @@ function displayWall(wall) {
|
|
|
804
779
|
<div class="at_subitem_left">
|
|
805
780
|
<span class="mdi mdi-vector-line"></span>
|
|
806
781
|
</div>
|
|
807
|
-
<div class="at_subitem_center" id="at-expand-btn-${wall.uuid}" data-cy="at-expand-btn-${wall.uuid}">
|
|
808
|
-
${
|
|
782
|
+
<div class="at_subitem_center" id="at-expand-btn-${wall.uuid}" data-cy="at-expand-btn-${wall.uuid}" style="width: 150px !important;">
|
|
783
|
+
${i18n.t('WindowsDoors')}
|
|
809
784
|
<span class="mdi mdi-chevron-up" id="at-chevron-${wall.uuid}"></span>
|
|
810
785
|
</div>
|
|
811
786
|
<div class="at_subitem_right at_invisible">
|
|
@@ -932,10 +907,10 @@ function setupEditWindow(element, window) {
|
|
|
932
907
|
confirmBtn.style.display = "none";
|
|
933
908
|
const windowTooltip = document.getElementById(`at-window-name-tooltip-${window.index}`);
|
|
934
909
|
windowTooltip.innerText = `${window.name}`;
|
|
935
|
-
|
|
910
|
+
saveWallChanges();
|
|
936
911
|
});
|
|
937
912
|
}
|
|
938
|
-
function
|
|
913
|
+
function saveWallChanges() {
|
|
939
914
|
updateWallInPolygon(currentWall);
|
|
940
915
|
updatePartitionData();
|
|
941
916
|
setCurrentPolygon(currentObject);
|
|
@@ -995,7 +970,7 @@ function setupDeleteWindow(element, window) {
|
|
|
995
970
|
});
|
|
996
971
|
// Save + rerender window
|
|
997
972
|
currentObject.object.object_data.json_data = currentPolygonData;
|
|
998
|
-
|
|
973
|
+
saveWallChanges();
|
|
999
974
|
notify.success(`${i18n.t('SuccessWindowDelete')}`);
|
|
1000
975
|
log.info("currentPartition polygonJson", JSON.parse(currentPartitionData.polygon_json));
|
|
1001
976
|
log.info("currentObject", currentObject);
|
|
@@ -1076,7 +1051,7 @@ function displayFloor(floor, walls, floorModel) {
|
|
|
1076
1051
|
</div>
|
|
1077
1052
|
|
|
1078
1053
|
<div class="at_edit_name" id="at-edit-floor-material">
|
|
1079
|
-
<input class="at_edit_name_input at_ml_1" type="text" id="at-edit-floor-material-input" data-cy="at-edit-floor-material-input" value="${floor.material ? floor.material : ''}" placeholder="${i18n.t('EnterFloorMaterial')}">
|
|
1054
|
+
<input class="at_edit_name_input at_ml_1" type="text" id="at-edit-floor-material-input" data-cy="at-edit-floor-material-input" value="${floor.material ? floor.material : ''}" placeholder="${i18n.t('EnterFloorMaterial')}" style="font-size: 0.75rem !important;">
|
|
1080
1055
|
<span class="mdi mdi-pencil at_mr-1" style="display: none; cursor: pointer;" id="at-floor-edit-material-btn"></span>
|
|
1081
1056
|
<span class="mdi mdi-check at_mr-1" id="at-confirm-edit-floor-name" style="display: none;"></span>
|
|
1082
1057
|
</div>
|
|
@@ -1431,6 +1406,7 @@ export function setCurrentPartitionData() {
|
|
|
1431
1406
|
}
|
|
1432
1407
|
if (drawingMode === 'partition') {
|
|
1433
1408
|
displayFaceLists();
|
|
1409
|
+
currentObject = currentObjectData;
|
|
1434
1410
|
}
|
|
1435
1411
|
}, 50); // Check every 50ms
|
|
1436
1412
|
});
|
|
@@ -1495,7 +1471,7 @@ function updatePartitionDataArray(payload, currentPartitionDataArray) {
|
|
|
1495
1471
|
if (existingIndex === -1) {
|
|
1496
1472
|
if (payload.name == null)
|
|
1497
1473
|
payload.name = partitionName.value || `${i18n.t('Partition')} ${currentPartitionDataArray.length + 1}`;
|
|
1498
|
-
log.info("
|
|
1474
|
+
log.info("payload", payload.name);
|
|
1499
1475
|
// Add the new partition
|
|
1500
1476
|
currentPartitionDataArray.push(payload);
|
|
1501
1477
|
newlyAddedPartition.push(payload);
|
|
@@ -1640,7 +1616,6 @@ export function handlePartitionWallEditBtn(wallUuid) {
|
|
|
1640
1616
|
log.info("currentPartitionData", currentPartitionData);
|
|
1641
1617
|
log.info("polygonJson", JSON.parse(currentPartitionData.polygon_json));
|
|
1642
1618
|
log.info("getCurrentPolygon()", getCurrentPolygon());
|
|
1643
|
-
setDrawingMode(false);
|
|
1644
1619
|
const elements = {
|
|
1645
1620
|
'at-face-title': 'none',
|
|
1646
1621
|
'at-window-door-title': 'flex',
|
|
@@ -1654,6 +1629,7 @@ export function handlePartitionWallEditBtn(wallUuid) {
|
|
|
1654
1629
|
});
|
|
1655
1630
|
const faceVertexContainer = document.getElementById('at-face-vertex-container');
|
|
1656
1631
|
faceVertexContainer.innerHTML = '';
|
|
1632
|
+
const wallName = document.getElementById('at-wall-name');
|
|
1657
1633
|
currentWall = JSON.parse(currentPartitionData.polygon_json).walls.find((wall) => wall.uuid == wallUuid);
|
|
1658
1634
|
log.info("currenWall", currentWall);
|
|
1659
1635
|
const wallBottomMidPoint = {
|
|
@@ -1665,10 +1641,18 @@ export function handlePartitionWallEditBtn(wallUuid) {
|
|
|
1665
1641
|
z: ((currentWall.edges[0].start.z + currentWall.edges[1].start.z + currentWall.edges[2].start.z + currentWall.edges[3].start.z) / 4),
|
|
1666
1642
|
};
|
|
1667
1643
|
yield goToPosition(wallBottomMidPoint);
|
|
1644
|
+
const match = currentWall.name.match(/wall-(\d+)$/);
|
|
1645
|
+
if (match) {
|
|
1646
|
+
console.log('@caroline wall test display: ', match);
|
|
1647
|
+
const wallNumber = parseInt(match[1]) + 1;
|
|
1648
|
+
wallName.innerText = `${i18n.t('Wall')} ${wallNumber}`;
|
|
1649
|
+
}
|
|
1668
1650
|
faceVertexContainer.append(displayWall(currentWall));
|
|
1669
1651
|
//sets material and icon
|
|
1670
1652
|
setWallMaterial(currentWall.material);
|
|
1671
1653
|
setWallMaterialIcon(currentWall.material);
|
|
1654
|
+
currentPolygonData = JSON.parse(currentPartitionData.polygon_json);
|
|
1655
|
+
setDrawingMode(false);
|
|
1672
1656
|
cancelDrawing();
|
|
1673
1657
|
});
|
|
1674
1658
|
}
|
|
@@ -404,7 +404,7 @@ function toggleSelectedPartition() {
|
|
|
404
404
|
handlePartitionRowEditBtnClickEvent(currentEditRoomData.children, partitionRowEdit);
|
|
405
405
|
if (isWall) {
|
|
406
406
|
const polygonId = target.getAttribute('polygon-item-id');
|
|
407
|
-
handlePartitionWallEditBtn(polygonId);
|
|
407
|
+
yield handlePartitionWallEditBtn(polygonId);
|
|
408
408
|
}
|
|
409
409
|
}
|
|
410
410
|
else {
|
|
@@ -4,6 +4,7 @@ export declare let selectedIoTSystem: string;
|
|
|
4
4
|
export declare let selectedIotTag: any;
|
|
5
5
|
export declare function renderTagIOTFormPane(): HTMLDivElement;
|
|
6
6
|
export declare function setIotCategoryOptions(): void;
|
|
7
|
+
export declare function getIotCategoryOption(): ITagIOTCategory;
|
|
7
8
|
export declare function toggleIoTCategoryOptions(): void;
|
|
8
9
|
export declare function toggleIoTDevicesOptions(): void;
|
|
9
10
|
/**
|
|
@@ -11,17 +11,20 @@ import { IOT_LINKED_SYSTEMS, SPACE_EVENTS, TAG_TYPE } from '../../../types';
|
|
|
11
11
|
import log from 'loglevel';
|
|
12
12
|
import i18n from './i18n';
|
|
13
13
|
import { dispatchSpaceEvent, _tagIotCategoryTypes, _tagIotDevices, _tags } from '../../../architwin';
|
|
14
|
-
import { stringContains } from "../../../utils";
|
|
14
|
+
import { stringContains, generateUUID } from "../../../utils";
|
|
15
15
|
import { batchAddEventListenerByClassName } from '../../events';
|
|
16
|
+
import { toggleModal, setModalAction } from "./modal";
|
|
17
|
+
import { Notyf } from 'notyf';
|
|
16
18
|
let selectedIoTCatOption;
|
|
17
19
|
let selectedIoTDeviceOption;
|
|
18
20
|
export let iotTagFormMode = "ADD" /* FORM_MODE.ADD */;
|
|
19
21
|
export let selectedIoTSystem = '';
|
|
20
22
|
export let selectedIotTag = undefined;
|
|
21
23
|
let tagIotName, iotModelName, iotSerialNumber, iotMfrName, iotSystemLink;
|
|
22
|
-
let
|
|
24
|
+
let selectedIoTCat;
|
|
23
25
|
let linkedDevicesArray = [];
|
|
24
26
|
let iotCategoryIconList = ['mdi-power', 'mdi-thermometer', 'mdi-water-percent', 'mdi-gauge', 'mdi-leak', 'mdi-water', 'mdi-lightbulb-on', 'mdi-gas-cylinder', 'mdi-flask', 'mdi-meter-electric', 'mdi-information-symbol', 'mdi-sine-wave'];
|
|
27
|
+
let notify = new Notyf({ position: { x: 'left', y: 'bottom' } });
|
|
25
28
|
export function renderTagIOTFormPane() {
|
|
26
29
|
const element = document.createElement('div');
|
|
27
30
|
element.classList.add('at_container');
|
|
@@ -34,7 +37,7 @@ export function renderTagIOTFormPane() {
|
|
|
34
37
|
</div>
|
|
35
38
|
|
|
36
39
|
<div class="at_form_container at_scrollable_container at_h-min-70">
|
|
37
|
-
<label for="">${i18n.t('
|
|
40
|
+
<label for="">${i18n.t('LinkedSystems')}</label>
|
|
38
41
|
<div class="at_gap_2" style="display: inline-flex">
|
|
39
42
|
<label class="at_flex at_align_center at_text_xs at_gap_1">
|
|
40
43
|
<input type="radio" id="at-linked-radio-bemac" name="iot-link-system" checked value=${IOT_LINKED_SYSTEMS.BEMAC} selected />
|
|
@@ -46,7 +49,7 @@ export function renderTagIOTFormPane() {
|
|
|
46
49
|
</label>
|
|
47
50
|
<label class="at_flex at_align_center at_text_xs at_gap_1">
|
|
48
51
|
<input type="radio" id="at-linked-radio-link" name="iot-link-system" value=${IOT_LINKED_SYSTEMS.URL_LINK} />
|
|
49
|
-
${i18n.t("
|
|
52
|
+
${i18n.t("URLLink")}
|
|
50
53
|
</label>
|
|
51
54
|
</div>
|
|
52
55
|
|
|
@@ -73,22 +76,22 @@ export function renderTagIOTFormPane() {
|
|
|
73
76
|
</div>
|
|
74
77
|
|
|
75
78
|
<div class="at-field at_flex_row at_justify_between">
|
|
76
|
-
<label for="">${i18n.t('
|
|
79
|
+
<label for="">${i18n.t('ModelName')}</label>
|
|
77
80
|
<input class="at_field_input at_w-full" type="text" name="model_name" id="at-iot-model-input" data-cy="at-iot-model-input" />
|
|
78
81
|
</div>
|
|
79
82
|
|
|
80
83
|
<div class="at-field at_flex_row at_justify_between">
|
|
81
|
-
<label for="">${i18n.t('
|
|
84
|
+
<label for="">${i18n.t('SerialNumber')}</label>
|
|
82
85
|
<input class="at_field_input at_w-full" type="text" name="serial_name" id="at-iot-serial-input" data-cy="at-iot-serial-input" />
|
|
83
86
|
</div>
|
|
84
87
|
|
|
85
88
|
<div class="at-field at_flex_row at_justify_between">
|
|
86
|
-
<label for="">${i18n.t('
|
|
89
|
+
<label for="">${i18n.t('ManufacturerSite')}</label>
|
|
87
90
|
<input class="at_field_input at_w-full" type="text" name="manufacturer_site" id="at-iot-manufacturer-input" data-cy="at-iot-manufacturer-input" />
|
|
88
91
|
</div>
|
|
89
92
|
|
|
90
93
|
<div class="at-field at_flex_row at_justify_between" id="at-iot-system-link-container" style="display: none">
|
|
91
|
-
<label for="">${i18n.t('
|
|
94
|
+
<label for="">${i18n.t('SystemLink')}</label>
|
|
92
95
|
<input class="at_field_input at_w-full" type="text" name="system_link" id="at-iot-system-link-input" data-cy="at-iot-system-link-input" />
|
|
93
96
|
</div>
|
|
94
97
|
|
|
@@ -98,9 +101,9 @@ export function renderTagIOTFormPane() {
|
|
|
98
101
|
</div>
|
|
99
102
|
|
|
100
103
|
<div class="at_field at_flex_column" id="at-iot-device-main-container">
|
|
101
|
-
<label for="">${i18n.t('
|
|
102
|
-
<div id="at-iot-devices-dropdown" data-cy="at-iot-devices-dropdown">
|
|
103
|
-
<div id="at-
|
|
104
|
+
<label for="">${i18n.t('IoTDevices')}</label>
|
|
105
|
+
<div id="at-iot-devices-dropdown" data-cy="at-iot-devices-dropdown" class="at-device-dropdown">
|
|
106
|
+
<div id="at-iot-devices-filter-dropdown" class="at_dropdown at_flex at_flex_row at_space_between">
|
|
104
107
|
<div class="at_dropdown_toggle" id="at-iot-selected-device" data-cy="at-iot-selected-device">${i18n.t(selectedIoTDeviceOption)}</div>
|
|
105
108
|
<span class="mdi mdi-chevron-down at_chevron" id="at-iot-cat-filter-chevron" data-cy="at-iot-cat-filter-chevron"></span>
|
|
106
109
|
</div>
|
|
@@ -112,17 +115,19 @@ export function renderTagIOTFormPane() {
|
|
|
112
115
|
</div>
|
|
113
116
|
</div>
|
|
114
117
|
|
|
115
|
-
<div class="
|
|
118
|
+
<div class="at_iot_list_container at_h-min-40" id="at-iot-device-list-container" data-cy="at-iot-device-list-container">
|
|
116
119
|
|
|
117
|
-
<div class="
|
|
120
|
+
<div class="at_section at_iot_item_container at_scrollable_container" id="at-linked-device-container" data-cy="at-linked-device-container">
|
|
118
121
|
|
|
119
|
-
<div class="
|
|
122
|
+
<div class="at_title" style="padding-left: 20px !important;">
|
|
120
123
|
<div> </div>
|
|
121
|
-
<label for="">${i18n.t('
|
|
124
|
+
<label for="">${i18n.t('LinkedIoTDevices')}</label>
|
|
122
125
|
<div> </div>
|
|
123
126
|
</div>
|
|
124
127
|
|
|
125
|
-
<div
|
|
128
|
+
<div>
|
|
129
|
+
<div class="at_body at_linked_device_container" id="at-device-item-container">
|
|
130
|
+
</div>
|
|
126
131
|
</div>
|
|
127
132
|
|
|
128
133
|
</div>
|
|
@@ -155,19 +160,24 @@ function displayFormTitle() {
|
|
|
155
160
|
title.innerHTML = '';
|
|
156
161
|
const span = document.createElement('span');
|
|
157
162
|
span.textContent = iotTagFormMode === "ADD" /* FORM_MODE.ADD */
|
|
158
|
-
? i18n.t('
|
|
159
|
-
: i18n.t('
|
|
163
|
+
? i18n.t('AddIoTTag')
|
|
164
|
+
: i18n.t('EditIoTTag');
|
|
160
165
|
title.appendChild(span);
|
|
161
166
|
}
|
|
167
|
+
// displays selected Category in the dropdown
|
|
162
168
|
function setSelectedIoTCat(payload) {
|
|
163
169
|
log.info('setSelectedIoTCat()', payload);
|
|
164
170
|
const selectedOption = document.getElementById('at-iot-selected-cat');
|
|
165
|
-
selectedOption.innerText = payload;
|
|
171
|
+
selectedOption.innerText = i18n.t(payload.name);
|
|
166
172
|
}
|
|
173
|
+
// displays selected Device in the dropdown
|
|
167
174
|
function setSelectedIoTDevice(payload) {
|
|
168
175
|
log.info('setSelectedIoTDevice()', payload);
|
|
169
176
|
const selectedDevice = document.getElementById('at-iot-selected-device');
|
|
170
|
-
selectedDevice.innerText =
|
|
177
|
+
selectedDevice.innerText = '';
|
|
178
|
+
if (payload) {
|
|
179
|
+
selectedDevice.innerText = payload;
|
|
180
|
+
}
|
|
171
181
|
}
|
|
172
182
|
function setInputFields() {
|
|
173
183
|
log.info('setInputFields()');
|
|
@@ -180,17 +190,37 @@ function setInputFields() {
|
|
|
180
190
|
export function setIotCategoryOptions() {
|
|
181
191
|
log.info('setIotCategoryOptions()');
|
|
182
192
|
dispatchSpaceEvent(SPACE_EVENTS.GET_IOT_CATEGORIES, { payload: 'hello from library' });
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
193
|
+
if (_tagIotCategoryTypes) {
|
|
194
|
+
renderIotCategoryDropdownOptions('at-iot-category-options', _tagIotCategoryTypes);
|
|
195
|
+
batchAddEventListenerByClassName('at_iot_cat_option', (event) => {
|
|
196
|
+
//@ts-ignore
|
|
197
|
+
const selectedCat = event.target;
|
|
198
|
+
const catUUID = selectedCat.getAttribute('iot-category-uuid');
|
|
199
|
+
const getCatName = _tagIotCategoryTypes.find(cat => cat.uuid === catUUID);
|
|
200
|
+
if (getCatName) {
|
|
201
|
+
selectedIoTCat = { uuid: catUUID, name: getCatName.name };
|
|
202
|
+
setSelectedIoTCat(selectedIoTCat);
|
|
203
|
+
log.info('cat id: ', selectedIoTCat);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// gets selected Category and returns the object
|
|
209
|
+
export function getIotCategoryOption() {
|
|
210
|
+
log.info('getIotCategoryOption()');
|
|
211
|
+
let foundCat = {};
|
|
212
|
+
if (linkedDevicesArray.length > 1) {
|
|
213
|
+
foundCat = _tagIotCategoryTypes.find((cat) => {
|
|
214
|
+
return i18n.t(cat.name) === 'Multiple';
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
foundCat = _tagIotCategoryTypes.find((cat) => {
|
|
219
|
+
return i18n.t(cat.uuid) === selectedIoTCat.uuid;
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
log.info('foundCat: ', foundCat);
|
|
223
|
+
return foundCat;
|
|
194
224
|
}
|
|
195
225
|
export function toggleIoTCategoryOptions() {
|
|
196
226
|
log.info('toggleIoTCategoryOptions');
|
|
@@ -250,7 +280,7 @@ export function clearIoTDropdowns() {
|
|
|
250
280
|
const catDropdown = document.getElementById('at-iot-selected-cat');
|
|
251
281
|
const devicesDropdown = document.getElementById('at-iot-selected-device');
|
|
252
282
|
catDropdown.innerText = i18n.t('NoSelection');
|
|
253
|
-
devicesDropdown.innerText = i18n.t('
|
|
283
|
+
devicesDropdown.innerText = i18n.t('SelectDevice');
|
|
254
284
|
}
|
|
255
285
|
/**
|
|
256
286
|
* Initializes Form Data
|
|
@@ -260,12 +290,14 @@ export function clearIoTDropdowns() {
|
|
|
260
290
|
export function initIoTFormData(tagId) {
|
|
261
291
|
log.info('initIoTFormData()');
|
|
262
292
|
displayFormTitle();
|
|
293
|
+
const iotSave = document.getElementById('at-save-iot-btn');
|
|
294
|
+
iotSave.classList.remove('at_disabled');
|
|
263
295
|
// Add Mode
|
|
264
296
|
if (!tagId) {
|
|
265
|
-
|
|
297
|
+
clearIoTDropdowns();
|
|
298
|
+
clearIotFields();
|
|
266
299
|
if (iotTagFormMode == "ADD" /* FORM_MODE.ADD */) {
|
|
267
300
|
if (tagIotName === null || tagIotName == undefined) {
|
|
268
|
-
log.info('initIoTFormData() tagname check', tagIotName);
|
|
269
301
|
setInputFields();
|
|
270
302
|
}
|
|
271
303
|
tagIotName.value = '';
|
|
@@ -273,11 +305,12 @@ export function initIoTFormData(tagId) {
|
|
|
273
305
|
iotSerialNumber.value = '';
|
|
274
306
|
iotMfrName.value = '';
|
|
275
307
|
iotSystemLink.value = '';
|
|
308
|
+
linkedDevicesArray = [];
|
|
309
|
+
setIotDeviceOptions();
|
|
276
310
|
}
|
|
277
311
|
}
|
|
278
312
|
else {
|
|
279
313
|
const foundTag = _tags.find(tag => tag.json_data.id === tagId);
|
|
280
|
-
log.info('initIoTFormData() foundTag: ', foundTag, _tags);
|
|
281
314
|
if (foundTag) {
|
|
282
315
|
selectedIotTag = foundTag;
|
|
283
316
|
if (tagIotName === null || tagIotName == undefined) {
|
|
@@ -299,23 +332,25 @@ export function initIoTFormData(tagId) {
|
|
|
299
332
|
setSelectedIoTSystemRadio(IOT_LINKED_SYSTEMS.BEMAC);
|
|
300
333
|
}
|
|
301
334
|
if (iotData.iot_category) {
|
|
302
|
-
|
|
335
|
+
log.info('found cat 1: ', i18n.t(iotData.iot_category), iotData.iot_category, _tagIotCategoryTypes);
|
|
336
|
+
const cat = _tagIotCategoryTypes.find(cat => i18n.t(cat.name.toLocaleLowerCase()) === iotData.iot_category.toLocaleLowerCase());
|
|
303
337
|
if (cat) {
|
|
304
|
-
|
|
305
|
-
|
|
338
|
+
log.info('found cat: ', cat);
|
|
339
|
+
setSelectedIoTCat({ uuid: cat.uuid, name: cat.name });
|
|
340
|
+
selectedIoTCat = { uuid: cat.uuid, name: cat.name };
|
|
306
341
|
}
|
|
307
342
|
else {
|
|
308
343
|
// for the Dummy data from App Side
|
|
309
|
-
setSelectedIoTCat(i18n.t('NoSelection'));
|
|
344
|
+
setSelectedIoTCat({ uuid: generateUUID(), name: i18n.t('NoSelection') });
|
|
310
345
|
renderIotCategoryDropdownOptions('at-iot-category-options', _tagIotCategoryTypes);
|
|
311
346
|
}
|
|
312
347
|
}
|
|
313
348
|
log.info("iotData.linked_devices: ", iotData.linked_devices);
|
|
314
349
|
if (iotData.linked_devices && iotData.linked_devices.length > 0) {
|
|
350
|
+
setIotDeviceOptions();
|
|
315
351
|
// renderIotDeviceDropdownOptions('at-iot-device-options', _tagIotDevices)
|
|
316
352
|
setSelectedIoTDevice(iotData.linked_devices[0].name);
|
|
317
353
|
linkedDevicesArray = iotData.linked_devices;
|
|
318
|
-
log.info("EDIT linkedDevicesArray: ", linkedDevicesArray);
|
|
319
354
|
renderLinkedDevices(linkedDevicesArray);
|
|
320
355
|
}
|
|
321
356
|
else {
|
|
@@ -328,7 +363,7 @@ export function initIoTFormData(tagId) {
|
|
|
328
363
|
// this is due to selecting the tags created from James
|
|
329
364
|
log.info('initIoTFormData()', iotData);
|
|
330
365
|
setSelectedIoTSystemRadio(IOT_LINKED_SYSTEMS.BEMAC);
|
|
331
|
-
setSelectedIoTCat(
|
|
366
|
+
setSelectedIoTCat({ uuid: generateUUID(), name: i18n.t('NoSelection') });
|
|
332
367
|
renderIotCategoryDropdownOptions('at-iot-category-options', _tagIotCategoryTypes);
|
|
333
368
|
renderIotDeviceDropdownOptions('at-iot-device-options', _tagIotDevices);
|
|
334
369
|
}
|
|
@@ -370,8 +405,10 @@ export function renderIotCategoryDropdownOptions(elementId, items) {
|
|
|
370
405
|
return;
|
|
371
406
|
}
|
|
372
407
|
items.forEach((item, index) => {
|
|
373
|
-
|
|
374
|
-
|
|
408
|
+
if (item.name != 'Multiple') {
|
|
409
|
+
const option = createCatOptionElement(item, 'iotcategory', index);
|
|
410
|
+
element.appendChild(option);
|
|
411
|
+
}
|
|
375
412
|
});
|
|
376
413
|
}
|
|
377
414
|
function createCatOptionElement(item, dropdownType, index) {
|
|
@@ -394,28 +431,33 @@ function createCatOptionElement(item, dropdownType, index) {
|
|
|
394
431
|
return option;
|
|
395
432
|
}
|
|
396
433
|
function selectCatOption(option, elementId) {
|
|
397
|
-
|
|
434
|
+
dispatchSpaceEvent(SPACE_EVENTS.GET_IOT_CAT_ICON, { payload: option });
|
|
398
435
|
}
|
|
436
|
+
// selects Devices from Arrayat-device-item-container
|
|
399
437
|
export function setIotDeviceOptions() {
|
|
400
438
|
log.info('setIotDeviceOptions()');
|
|
401
439
|
dispatchSpaceEvent(SPACE_EVENTS.GET_IOT_DEVICES, { payload: 'hello from library' });
|
|
402
440
|
renderIotDeviceDropdownOptions('at-iot-device-options', _tagIotDevices);
|
|
403
|
-
batchAddEventListenerByClassName('
|
|
441
|
+
batchAddEventListenerByClassName('at_option', (event) => {
|
|
404
442
|
//@ts-ignore
|
|
405
|
-
const selectedDev = event.target;
|
|
406
|
-
const parent = selectedDev.
|
|
407
|
-
log.info('@caroline parent: ', parent);
|
|
443
|
+
const selectedDev = document.getElementById(event.target.id);
|
|
444
|
+
const parent = selectedDev.closest('div');
|
|
408
445
|
const deviceId = parent.getAttribute('iot-device-uuid');
|
|
409
|
-
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
446
|
+
// adds selected device to array
|
|
447
|
+
const devFound = _tagIotDevices.find(device => device.id === deviceId);
|
|
448
|
+
if (devFound) {
|
|
449
|
+
selectedDev.setAttribute('disabled', 'true');
|
|
450
|
+
setSelectedIoTDevice(selectedDev.innerText);
|
|
451
|
+
linkedDevicesArray.push(devFound);
|
|
452
|
+
//hides the selected device in dropdown
|
|
453
|
+
parent.style.display = 'none'; //hides
|
|
454
|
+
renderDeviceRow(devFound);
|
|
455
|
+
selectedDev.setAttribute('disabled', 'false');
|
|
456
|
+
}
|
|
415
457
|
});
|
|
416
458
|
}
|
|
417
459
|
export function renderIotDeviceDropdownOptions(elementId, items) {
|
|
418
|
-
log.info("renderIotDeviceDropdownOptions: "
|
|
460
|
+
log.info("renderIotDeviceDropdownOptions: ");
|
|
419
461
|
const element = document.getElementById(elementId);
|
|
420
462
|
if (!element) {
|
|
421
463
|
console.error("Parameter element is undefined");
|
|
@@ -430,19 +472,19 @@ export function renderIotDeviceDropdownOptions(elementId, items) {
|
|
|
430
472
|
element.innerHTML = ``;
|
|
431
473
|
const selectedIotDeviceOption = document.getElementById(isFilterDropdown ? 'at-iot-device-filter-dropdown-toggle' : 'at-iot-device-dropdown-toggle');
|
|
432
474
|
if (selectedIotDeviceOption) {
|
|
433
|
-
selectedIotDeviceOption.textContent = `${i18n.t('
|
|
475
|
+
selectedIotDeviceOption.textContent = `${i18n.t('SelectDevice')}`;
|
|
434
476
|
selectedIoTDeviceOption = undefined;
|
|
435
477
|
}
|
|
436
478
|
//Add the no selection option
|
|
437
479
|
const selectDevice = document.createElement('div');
|
|
438
|
-
selectDevice.classList.add('
|
|
480
|
+
selectDevice.classList.add('at_option');
|
|
439
481
|
selectDevice.setAttribute('iot-device-uuid', '');
|
|
440
482
|
selectDevice.setAttribute('dropdown-type', 'iotdevice');
|
|
441
483
|
selectDevice.innerHTML = `
|
|
442
|
-
<span></span> ${i18n.t('
|
|
484
|
+
<span></span> ${i18n.t('SelectDevice')}
|
|
443
485
|
`;
|
|
444
486
|
selectDevice.onclick = () => {
|
|
445
|
-
log.info('
|
|
487
|
+
log.info('item selected: ', selectDevice, linkedDevicesArray);
|
|
446
488
|
selectDeviceOption(selectDevice, isFilterDropdown ? 'at-iot-device-filter-dropdown-toggle' : 'at-iot-device-filter-dropdown-toggle');
|
|
447
489
|
};
|
|
448
490
|
element.appendChild(selectDevice);
|
|
@@ -466,21 +508,23 @@ function createDeviceOptionElement(item, dropdownType) {
|
|
|
466
508
|
option.style.justifyContent = 'left';
|
|
467
509
|
option.style.alignItems = 'center';
|
|
468
510
|
option.style.gap = '2px';
|
|
511
|
+
// option.classList.add('at_option')
|
|
469
512
|
option.classList.add('at_option');
|
|
470
|
-
option.classList.add('at_iot_dev_option');
|
|
471
513
|
option.setAttribute('iot-device-uuid', item.id);
|
|
472
514
|
option.setAttribute('dropdown-type', dropdownType);
|
|
473
515
|
option.setAttribute('data-cy', `at-iot-category-option-${item.id}`);
|
|
474
|
-
if (dropdownType == 'category') {
|
|
475
|
-
option.innerHTML = `
|
|
476
|
-
<span class="at_colored-indicator"></span>
|
|
477
|
-
${item.name}
|
|
478
|
-
`;
|
|
479
|
-
return option;
|
|
480
|
-
}
|
|
481
516
|
option.innerHTML = `
|
|
482
|
-
<span>${item.name}</span>
|
|
517
|
+
<span style="width: 100%; display: block; padding: 4px 8px; cursor: pointer" id="${item.id}">${item.name}</span>
|
|
483
518
|
`;
|
|
519
|
+
if (selectedIotTag) {
|
|
520
|
+
const iotTag = selectedIotTag.iot_tag;
|
|
521
|
+
const hideOption = iotTag.linked_devices.find((dev) => {
|
|
522
|
+
return dev.id === item.id;
|
|
523
|
+
});
|
|
524
|
+
if (hideOption != undefined) {
|
|
525
|
+
option.style.setProperty('display', 'none', 'important');
|
|
526
|
+
}
|
|
527
|
+
}
|
|
484
528
|
return option;
|
|
485
529
|
}
|
|
486
530
|
/**
|
|
@@ -499,7 +543,8 @@ export function getIotTagFormData() {
|
|
|
499
543
|
modelName: iotModelName.value,
|
|
500
544
|
serialNumber: iotSerialNumber.value,
|
|
501
545
|
tagMf: iotMfrName.value,
|
|
502
|
-
tagCategoryId:
|
|
546
|
+
// tagCategoryId: selectedIoTCat.uuid,
|
|
547
|
+
tagCategoryId: selectedIoTCat.name,
|
|
503
548
|
systemLink: iotSystemLink.value,
|
|
504
549
|
linkedDevices: linkedDevicesArray,
|
|
505
550
|
iotSystem: selectedIoTSystem,
|
|
@@ -508,55 +553,78 @@ export function getIotTagFormData() {
|
|
|
508
553
|
return formData;
|
|
509
554
|
}
|
|
510
555
|
function renderLinkedDevices(linkedDevices) {
|
|
511
|
-
log.info('renderLinkedDevices()'
|
|
556
|
+
log.info('renderLinkedDevices()');
|
|
512
557
|
if (linkedDevices) {
|
|
513
|
-
const devicesContainer = document.getElementById('at-
|
|
558
|
+
// const devicesContainer = document.getElementById('at-device-item-container')
|
|
514
559
|
if (linkedDevices.length > 0) {
|
|
515
|
-
devicesContainer.innerHTML = ``;
|
|
516
560
|
linkedDevices.forEach(device => {
|
|
517
|
-
log.info("@caroline device: ", device);
|
|
518
561
|
renderDeviceRow(device);
|
|
519
562
|
});
|
|
520
563
|
}
|
|
521
564
|
}
|
|
522
565
|
}
|
|
523
566
|
function renderDeviceRow(payload) {
|
|
524
|
-
log.info('renderDeviceRow()'
|
|
525
|
-
const devicesContainer = document.getElementById('at-
|
|
567
|
+
log.info('renderDeviceRow()');
|
|
568
|
+
const devicesContainer = document.getElementById('at-device-item-container');
|
|
526
569
|
if (payload) {
|
|
527
570
|
const deviceRow = document.createElement('div');
|
|
528
571
|
deviceRow.classList.add('at_flex_row');
|
|
529
|
-
deviceRow.classList.add('
|
|
572
|
+
deviceRow.classList.add('at_item');
|
|
530
573
|
deviceRow.innerHTML = `
|
|
531
|
-
<div class="
|
|
574
|
+
<div class="at_subitem_left">
|
|
532
575
|
<span class="mdi mdi-cube-outline"></span>
|
|
533
576
|
</div>
|
|
534
577
|
|
|
535
|
-
<div class="
|
|
578
|
+
<div class="at_name">
|
|
536
579
|
<div></div>
|
|
537
580
|
<label for="">${payload.name}</label>
|
|
538
581
|
<div></div>
|
|
539
582
|
</div>
|
|
540
|
-
<div class="
|
|
541
|
-
<span class="mdi mdi-delete-outline at_delete_device_btn" id="at-delete-device-${payload.
|
|
583
|
+
<div class="at_subitem_right">
|
|
584
|
+
<span class="mdi mdi-delete-outline at_delete_device_btn" id="at-delete-device-${payload.id}"></span>
|
|
542
585
|
</div>
|
|
543
586
|
`;
|
|
544
587
|
devicesContainer.appendChild(deviceRow);
|
|
545
588
|
batchAddEventListenerByClassName('at_delete_device_btn', (event) => __awaiter(this, void 0, void 0, function* () {
|
|
546
|
-
log.info('deleteSelectedLinkedDevice is clicked', event);
|
|
547
589
|
//@ts-ignore
|
|
548
|
-
const selectedDevice =
|
|
590
|
+
const selectedDevice = event.target;
|
|
549
591
|
if (selectedDevice) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
592
|
+
toggleModal();
|
|
593
|
+
setModalAction({
|
|
594
|
+
title: `${i18n.t('DeleteDevice')}`,
|
|
595
|
+
description: `${i18n.t('ConfirmDeleteDevice')}`,
|
|
596
|
+
buttonLabel: `${i18n.t('YesDelete')}`
|
|
597
|
+
}, () => __awaiter(this, void 0, void 0, function* () {
|
|
598
|
+
// gets the device id
|
|
599
|
+
const devId = selectedDevice.id.split('at-delete-device-')[1];
|
|
600
|
+
// finds the index of the selected device
|
|
601
|
+
const findDevice = linkedDevicesArray.findIndex(dev => dev.id === devId);
|
|
602
|
+
if (findDevice > -1) {
|
|
603
|
+
selectedDevice.setAttribute('disabled', 'true');
|
|
604
|
+
const parent = selectedDevice.closest('.at_partition_item');
|
|
605
|
+
if (parent) {
|
|
606
|
+
// displays delete Device back in Dropdown List
|
|
607
|
+
const findHideDev = document.querySelector(`div[iot-device-uuid="${devId}"]`);
|
|
608
|
+
const devicesDropdown = document.getElementById('at-iot-selected-device');
|
|
609
|
+
if (findHideDev) {
|
|
610
|
+
findHideDev.style.display = "block";
|
|
611
|
+
parent.style.display = 'none';
|
|
612
|
+
linkedDevicesArray.splice(findDevice, 1);
|
|
613
|
+
}
|
|
614
|
+
if (linkedDevicesArray.length === 0) {
|
|
615
|
+
devicesDropdown.innerText = i18n.t('SelectDevice');
|
|
616
|
+
setIotDeviceOptions();
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
toggleModal(false);
|
|
620
|
+
notify.success(`${i18n.t('SuccessDeleteDevice')}`);
|
|
621
|
+
selectedDevice.setAttribute('disabled', 'false');
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
toggleModal(false);
|
|
625
|
+
notify.error("Tag id not found!");
|
|
626
|
+
}
|
|
627
|
+
}));
|
|
560
628
|
}
|
|
561
629
|
}));
|
|
562
630
|
return;
|
|
@@ -573,7 +641,7 @@ export function clearIotFields() {
|
|
|
573
641
|
iotSerialNumber = document.getElementById('at-iot-serial-input');
|
|
574
642
|
iotMfrName = document.getElementById('at-iot-manufacturer-input');
|
|
575
643
|
iotSystemLink = document.getElementById('at-iot-system-link-input');
|
|
576
|
-
const deviceContainer = document.getElementById(
|
|
644
|
+
const deviceContainer = document.getElementById('at-device-item-container');
|
|
577
645
|
tagIotName.innerText = '';
|
|
578
646
|
iotModelName.innerText = '';
|
|
579
647
|
iotSerialNumber.innerText = '';
|
|
@@ -582,10 +650,9 @@ export function clearIotFields() {
|
|
|
582
650
|
linkedDevicesArray = [];
|
|
583
651
|
selectedIoTSystem = '';
|
|
584
652
|
setSelectedIoTSystemRadio(IOT_LINKED_SYSTEMS.BEMAC);
|
|
585
|
-
|
|
586
|
-
deviceContainer.innerHTML = '';
|
|
587
|
-
}
|
|
653
|
+
deviceContainer.innerHTML = '';
|
|
588
654
|
iotTagFormMode = "ADD" /* FORM_MODE.ADD */;
|
|
655
|
+
selectedIotTag = undefined;
|
|
589
656
|
}
|
|
590
657
|
/**
|
|
591
658
|
* Sets the form mode for the IOT form.
|
|
@@ -6,3 +6,4 @@ export declare function renderViewingRemoteSpace(): HTMLElement;
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function renderRemoteSpaceViewing(user: ScreenShareUser): void;
|
|
8
8
|
export declare function handleRemoteViewResponsiveChanges(): void;
|
|
9
|
+
export declare function handleScreenShareRemoteEndSessionEvent(): void;
|
|
@@ -100,3 +100,9 @@ export function handleRemoteViewResponsiveChanges() {
|
|
|
100
100
|
container.classList.toggle("at_display_flex_end", isMobile);
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
+
export function handleScreenShareRemoteEndSessionEvent() {
|
|
104
|
+
const element = document.getElementById("at-viewing-remote-space-pane");
|
|
105
|
+
if (element) {
|
|
106
|
+
element.style.display = 'none';
|
|
107
|
+
}
|
|
108
|
+
}
|
package/lib/atwinui/events.js
CHANGED
|
@@ -30,7 +30,7 @@ import { getBasepointCalibrateBpCoordinateValues, getBasepointCalibrateMpCoordin
|
|
|
30
30
|
import { toggleGeneralMapOptions, initGeneralSelectedMap, getSelectedMapOption } from './components/toolbar/generalSettingsMenuPane';
|
|
31
31
|
import { searchTagList, setSearchTagTerm, searchClearfield, getSearchTagTerm, sortTags, updateSelectedTagSortOption, resetSelectedTagSortOption } from './components/toolbar/tagListPane';
|
|
32
32
|
import { renderUserRows } from "./components/toolbar/spaceUserListPane";
|
|
33
|
-
import { handleRemoteViewResponsiveChanges, renderRemoteSpaceViewing } from "./components/toolbar/viewingRemoteSpace";
|
|
33
|
+
import { handleRemoteViewResponsiveChanges, handleScreenShareRemoteEndSessionEvent, renderRemoteSpaceViewing } from "./components/toolbar/viewingRemoteSpace";
|
|
34
34
|
import { PipeList } from "./components/toolbar/pipeListPane";
|
|
35
35
|
import { PipeForm } from "./components/toolbar/pipeFormPane";
|
|
36
36
|
import { unsendComment, timedoutComment, getTheseTagMessages } from './components/toolbar/tagMessagingPane';
|
|
@@ -1439,6 +1439,7 @@ function setupSpaceEventSubscriptions() {
|
|
|
1439
1439
|
subscribeSpaceEvent(SPACE_EVENTS.SCREEN_SHARE_HOST_END_SESSION, handleScreenShareEndSessionEvent);
|
|
1440
1440
|
subscribeSpaceEvent(SPACE_EVENTS.SCREEN_SHARE_ACCEPT_REQUEST, handleScreenShareAcceptRequest);
|
|
1441
1441
|
subscribeSpaceEvent(SPACE_EVENTS.SCREEN_SHARE_BACK_USER_LIST_PANE, handleScreenShareBackUserListPane);
|
|
1442
|
+
subscribeSpaceEvent(SPACE_EVENTS.SCREEN_SHARE_TERMINATED, handleScreenShareRemoteEndSessionEvent);
|
|
1442
1443
|
}
|
|
1443
1444
|
function handlePartitionColiderClickSelected(payload) {
|
|
1444
1445
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1529,6 +1530,7 @@ function handleVertexPlace(payload) {
|
|
|
1529
1530
|
if (isToolbarFeatureEnabled('roomCreation')) {
|
|
1530
1531
|
log.info("getDrawingMode()", getDrawingMode());
|
|
1531
1532
|
if (getDrawingMode() === 'window') {
|
|
1533
|
+
log.info("current polygon", getCurrentPolygon());
|
|
1532
1534
|
}
|
|
1533
1535
|
if (getDrawingMode() === 'partition') {
|
|
1534
1536
|
// setCurrentPartitionData()
|
|
@@ -137,6 +137,8 @@ export declare class BufferGeometry {
|
|
|
137
137
|
windowData: any;
|
|
138
138
|
targetIndex: any;
|
|
139
139
|
targetUUID: any;
|
|
140
|
+
deductWindowFromWallArea: boolean;
|
|
141
|
+
windowOutlineColor: number;
|
|
140
142
|
};
|
|
141
143
|
outputs: Record<string, unknown> & MpSdk.Scene.PredefinedOutputs;
|
|
142
144
|
context: MpSdk.Scene.IComponentContext;
|
|
@@ -157,6 +159,20 @@ export declare class BufferGeometry {
|
|
|
157
159
|
onTick: (delta: any) => void;
|
|
158
160
|
onDestroy(): void;
|
|
159
161
|
createLabelCanvas(text: string): HTMLCanvasElement;
|
|
162
|
+
/**
|
|
163
|
+
* Projects 3D window coordinates to 2D for accurate area calculation
|
|
164
|
+
* @param path3D Array of 3D coordinates
|
|
165
|
+
* @returns Object with area and perimeter calculated from projected 2D coordinates
|
|
166
|
+
*/
|
|
167
|
+
calculateWindowDimensions(path3D: Array<{
|
|
168
|
+
x: number;
|
|
169
|
+
y: number;
|
|
170
|
+
z: number;
|
|
171
|
+
}>): {
|
|
172
|
+
area: number;
|
|
173
|
+
perimeter: number;
|
|
174
|
+
};
|
|
175
|
+
calculateWallNormal(wallIndex: number, startPoint: any, endPoint: any): THREE.Vector3;
|
|
160
176
|
renderWindow(WALL_HEIGHT: number): void;
|
|
161
177
|
renderWalls(WALL_HEIGHT: number, metadata?: PolygonData): (WallPolyData[] | EdgePolyData[])[];
|
|
162
178
|
renderWindows(windows: WindowPolyData[]): void;
|
|
@@ -511,6 +511,8 @@ export class BufferGeometry {
|
|
|
511
511
|
windowData: undefined,
|
|
512
512
|
targetIndex: undefined,
|
|
513
513
|
targetUUID: undefined,
|
|
514
|
+
deductWindowFromWallArea: true,
|
|
515
|
+
windowOutlineColor: 0x253D5B
|
|
514
516
|
};
|
|
515
517
|
this.emits = {
|
|
516
518
|
changed: true,
|
|
@@ -693,6 +695,17 @@ export class BufferGeometry {
|
|
|
693
695
|
if (wall.windows && wall.windows.length > 0) {
|
|
694
696
|
acc = [...acc, ...wall.windows];
|
|
695
697
|
wallDataArray[index].windows = wall.windows;
|
|
698
|
+
// if (this.inputs.deductWindowFromWallArea) {
|
|
699
|
+
// // Calculate total window area for this wall
|
|
700
|
+
// let totalWindowArea = 0;
|
|
701
|
+
// if (wall.windows && wall.windows.length > 0) {
|
|
702
|
+
// totalWindowArea = wall.windows.reduce((sum, window) => {
|
|
703
|
+
// return sum + (window.area || 0);
|
|
704
|
+
// }, 0);
|
|
705
|
+
// }
|
|
706
|
+
// // Subtract window area from wall area
|
|
707
|
+
// wallDataArray[index].area = Math.max(0, wallDataArray[index].area - totalWindowArea);
|
|
708
|
+
// }
|
|
696
709
|
}
|
|
697
710
|
return acc;
|
|
698
711
|
}, []);
|
|
@@ -728,7 +741,8 @@ export class BufferGeometry {
|
|
|
728
741
|
if (!polyData.walls[targetWallIndex].windows)
|
|
729
742
|
polyData.walls[targetWallIndex].windows = [];
|
|
730
743
|
const currentWindowCount = polyData.walls[targetWallIndex].windows ? polyData.walls[targetWallIndex].windows.length + 1 : 0;
|
|
731
|
-
|
|
744
|
+
// Calculate window dimensions using proper 3D to 2D projection
|
|
745
|
+
const windowDimension = this.calculateWindowDimensions(this.inputs.path);
|
|
732
746
|
let windowDataArray = [];
|
|
733
747
|
for (let i = 0; i < this.inputs.path.length; i++) {
|
|
734
748
|
const startPoint = this.inputs.path[i];
|
|
@@ -771,6 +785,15 @@ export class BufferGeometry {
|
|
|
771
785
|
log.error("Error rendering windows ", error);
|
|
772
786
|
}
|
|
773
787
|
polyData.walls[targetWallIndex].windows[this.inputs.targetIndex] = (windowData);
|
|
788
|
+
if (this.inputs.deductWindowFromWallArea) {
|
|
789
|
+
let totalWindowArea = 0;
|
|
790
|
+
if (polyData.walls[targetWallIndex].windows && polyData.walls[targetWallIndex].windows.length > 0) {
|
|
791
|
+
totalWindowArea = polyData.walls[targetWallIndex].windows.reduce((sum, window) => {
|
|
792
|
+
return sum + (window.area || 0);
|
|
793
|
+
}, 0);
|
|
794
|
+
}
|
|
795
|
+
polyData.walls[targetWallIndex].area = Math.max(0, polyData.walls[targetWallIndex].area - totalWindowArea);
|
|
796
|
+
}
|
|
774
797
|
partitionData = polyData;
|
|
775
798
|
}
|
|
776
799
|
}
|
|
@@ -817,6 +840,83 @@ export class BufferGeometry {
|
|
|
817
840
|
return canvas;
|
|
818
841
|
}
|
|
819
842
|
;
|
|
843
|
+
/**
|
|
844
|
+
* Projects 3D window coordinates to 2D for accurate area calculation
|
|
845
|
+
* @param path3D Array of 3D coordinates
|
|
846
|
+
* @returns Object with area and perimeter calculated from projected 2D coordinates
|
|
847
|
+
*/
|
|
848
|
+
calculateWindowDimensions(path3D) {
|
|
849
|
+
const THREE = this.context.three;
|
|
850
|
+
if (!path3D || path3D.length < 3) {
|
|
851
|
+
return PolygonCalculator.calculatePolygonProperties(path3D, true);
|
|
852
|
+
}
|
|
853
|
+
const p0 = new THREE.Vector3(path3D[0].x, path3D[0].y, path3D[0].z);
|
|
854
|
+
const p1 = new THREE.Vector3(path3D[1].x, path3D[1].y, path3D[1].z);
|
|
855
|
+
const p2 = new THREE.Vector3(path3D[2].x, path3D[2].y, path3D[2].z);
|
|
856
|
+
const v1 = new THREE.Vector3().subVectors(p1, p0);
|
|
857
|
+
const v2 = new THREE.Vector3().subVectors(p2, p0);
|
|
858
|
+
const normal = new THREE.Vector3().crossVectors(v1, v2);
|
|
859
|
+
const normalLen = normal.length();
|
|
860
|
+
if (normalLen > 0) {
|
|
861
|
+
normal.divideScalar(normalLen);
|
|
862
|
+
const uAxis = v1.clone().normalize();
|
|
863
|
+
const vAxis = new THREE.Vector3().crossVectors(normal, uAxis).normalize();
|
|
864
|
+
const shapePoints2D = [];
|
|
865
|
+
for (let j = 0; j < path3D.length; j++) {
|
|
866
|
+
const pj = new THREE.Vector3(path3D[j].x, path3D[j].y, path3D[j].z);
|
|
867
|
+
const rel = new THREE.Vector3().subVectors(pj, p0);
|
|
868
|
+
const x = rel.dot(uAxis);
|
|
869
|
+
const y = rel.dot(vAxis);
|
|
870
|
+
shapePoints2D.push(new THREE.Vector2(x, y));
|
|
871
|
+
}
|
|
872
|
+
let twiceSignedArea = 0;
|
|
873
|
+
let perimeter = 0;
|
|
874
|
+
console.log('Window projection debug:');
|
|
875
|
+
console.log('Original 3D points:', path3D);
|
|
876
|
+
console.log('Projected 2D points:', shapePoints2D);
|
|
877
|
+
for (let j = 0; j < shapePoints2D.length; j++) {
|
|
878
|
+
const p1 = shapePoints2D[j];
|
|
879
|
+
const p2 = shapePoints2D[(j + 1) % shapePoints2D.length];
|
|
880
|
+
const cross = p1.x * p2.y - p2.x * p1.y;
|
|
881
|
+
twiceSignedArea += cross;
|
|
882
|
+
const distance = Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
|
|
883
|
+
perimeter += distance;
|
|
884
|
+
console.log(`Edge ${j}: p1(${p1.x.toFixed(3)}, ${p1.y.toFixed(3)}) -> p2(${p2.x.toFixed(3)}, ${p2.y.toFixed(3)}), cross=${cross.toFixed(3)}, distance=${distance.toFixed(3)}`);
|
|
885
|
+
}
|
|
886
|
+
const area = Math.abs(twiceSignedArea * 0.5);
|
|
887
|
+
console.log(`Final calculation: twiceSignedArea=${twiceSignedArea.toFixed(3)}, area=${area.toFixed(3)}, perimeter=${perimeter.toFixed(3)}`);
|
|
888
|
+
return { area, perimeter };
|
|
889
|
+
}
|
|
890
|
+
else {
|
|
891
|
+
return PolygonCalculator.calculatePolygonProperties(path3D, true);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
calculateWallNormal(wallIndex, startPoint, endPoint) {
|
|
895
|
+
const THREE = this.context.three;
|
|
896
|
+
const wallDirection = new THREE.Vector3(endPoint.x - startPoint.x, endPoint.y - startPoint.y, endPoint.z - startPoint.z).normalize();
|
|
897
|
+
if (this.inputs.path.length >= 3) {
|
|
898
|
+
const p0 = new THREE.Vector3(this.inputs.path[0].x, this.inputs.path[0].y, this.inputs.path[0].z);
|
|
899
|
+
const p1 = new THREE.Vector3(this.inputs.path[1].x, this.inputs.path[1].y, this.inputs.path[1].z);
|
|
900
|
+
const p2 = new THREE.Vector3(this.inputs.path[2].x, this.inputs.path[2].y, this.inputs.path[2].z);
|
|
901
|
+
const v1 = new THREE.Vector3().subVectors(p1, p0);
|
|
902
|
+
const v2 = new THREE.Vector3().subVectors(p2, p0);
|
|
903
|
+
const polygonNormal = new THREE.Vector3().crossVectors(v1, v2).normalize();
|
|
904
|
+
const wallNormal = new THREE.Vector3().crossVectors(wallDirection, polygonNormal).normalize();
|
|
905
|
+
// If the normal is too small (wall is parallel to polygon normal), use a fallback
|
|
906
|
+
if (wallNormal.lengthSq() < 0.001) {
|
|
907
|
+
// Use the wall direction rotated 90 degrees around the Y axis
|
|
908
|
+
wallNormal.set(-wallDirection.z, 0, wallDirection.x).normalize();
|
|
909
|
+
}
|
|
910
|
+
return wallNormal;
|
|
911
|
+
}
|
|
912
|
+
// Fallback: use the original method if we don't have enough points
|
|
913
|
+
const up = new THREE.Vector3(0, 1, 0);
|
|
914
|
+
const wallNormal = new THREE.Vector3().crossVectors(wallDirection, up).normalize();
|
|
915
|
+
if (wallNormal.lengthSq() < 0.001) {
|
|
916
|
+
wallNormal.set(1, 0, 0);
|
|
917
|
+
}
|
|
918
|
+
return wallNormal;
|
|
919
|
+
}
|
|
820
920
|
renderWindow(WALL_HEIGHT) {
|
|
821
921
|
// const THREE = this.context.three
|
|
822
922
|
// const windowData:WindowPolyData = this.inputs.windowData
|
|
@@ -864,7 +964,19 @@ export class BufferGeometry {
|
|
|
864
964
|
wallMesh.add(outlineMesh);
|
|
865
965
|
wallMesh.name = this.inputs.uuid != '' ? `${this.inputs.uuid}_wall-${i}` : `wall-${i}`;
|
|
866
966
|
const wallLength = new THREE.Vector3(endPoint.x - startPoint.x, endPoint.y - startPoint.y, endPoint.z - startPoint.z).length();
|
|
867
|
-
|
|
967
|
+
let wallArea = wallLength * WALL_HEIGHT;
|
|
968
|
+
if (this.inputs.deductWindowFromWallArea && metadata) {
|
|
969
|
+
const currentWallIndex = wallDataArray.length == 0 ? wallDataArray.length : wallDataArray.length - 1;
|
|
970
|
+
let totalWindowArea = 0;
|
|
971
|
+
if (metadata.walls[currentWallIndex].windows && metadata.walls[currentWallIndex].windows.length > 0) {
|
|
972
|
+
totalWindowArea = metadata.walls[currentWallIndex].windows.reduce((sum, window) => {
|
|
973
|
+
const dimension = this.calculateWindowDimensions(window.path);
|
|
974
|
+
return sum + (dimension.area || 0);
|
|
975
|
+
}, 0);
|
|
976
|
+
}
|
|
977
|
+
// Subtract window area from wall area
|
|
978
|
+
wallArea = Math.max(0, wallArea - totalWindowArea);
|
|
979
|
+
}
|
|
868
980
|
// Create wall label
|
|
869
981
|
let wallMaterial;
|
|
870
982
|
if (metadata && metadata.walls[i] && metadata.walls[i].material)
|
|
@@ -879,14 +991,9 @@ export class BufferGeometry {
|
|
|
879
991
|
z: (startPoint.z + endPoint.z) / 2
|
|
880
992
|
};
|
|
881
993
|
const direction = new THREE.Vector3(endPoint.x - startPoint.x, endPoint.y - startPoint.y, endPoint.z - startPoint.z).normalize();
|
|
882
|
-
// Calculate the normal vector to the wall
|
|
883
|
-
|
|
884
|
-
const wallNormal =
|
|
885
|
-
// For flat walls, if the normal is close to zero (wall is vertical along Y),
|
|
886
|
-
if (wallNormal.lengthSq() < 0.001) {
|
|
887
|
-
// Wall is perfectly vertical, use a default normal
|
|
888
|
-
wallNormal.set(1, 0, 0);
|
|
889
|
-
}
|
|
994
|
+
// Calculate the normal vector to the wall based on polygon winding order
|
|
995
|
+
// Negate to keep labels inside, remove the negate to render all labels outside
|
|
996
|
+
const wallNormal = this.calculateWallNormal(i, startPoint, endPoint).negate();
|
|
890
997
|
// Negation to position labels on the original side of the wall
|
|
891
998
|
// wallNormal.negate();
|
|
892
999
|
const edgeLength = direction.length();
|
|
@@ -975,7 +1082,7 @@ export class BufferGeometry {
|
|
|
975
1082
|
is_deleted: wallDeleted
|
|
976
1083
|
},
|
|
977
1084
|
index: i,
|
|
978
|
-
area:
|
|
1085
|
+
area: wallArea,
|
|
979
1086
|
width: wallDimensions.width,
|
|
980
1087
|
perimeter: wallDimensions.perimeter,
|
|
981
1088
|
wall_height: WALL_HEIGHT,
|
|
@@ -1045,8 +1152,12 @@ export class BufferGeometry {
|
|
|
1045
1152
|
depthWrite: false
|
|
1046
1153
|
}));
|
|
1047
1154
|
windowMesh.name = windows[i].uuid ? `${windows[i].uuid}_window` : `window-${i}`;
|
|
1155
|
+
const outlineGeometry = new THREE.EdgesGeometry(windowGeometry);
|
|
1156
|
+
const outlineMaterial = new THREE.LineBasicMaterial({ color: this.inputs.windowOutlineColor, linewidth: 3 });
|
|
1157
|
+
const outlineMesh = new THREE.LineSegments(outlineGeometry, outlineMaterial);
|
|
1158
|
+
windowMesh.add(outlineMesh);
|
|
1048
1159
|
// Add window center label if material is defined
|
|
1049
|
-
if (windows[i].material) {
|
|
1160
|
+
if (windows[i].material || windows[i].name) {
|
|
1050
1161
|
try {
|
|
1051
1162
|
let twiceSignedArea = 0;
|
|
1052
1163
|
let centroidU = 0;
|
|
@@ -1071,9 +1182,13 @@ export class BufferGeometry {
|
|
|
1071
1182
|
centerU = sum.x / shapePoints2D.length;
|
|
1072
1183
|
centerV = sum.y / shapePoints2D.length;
|
|
1073
1184
|
}
|
|
1074
|
-
//
|
|
1075
|
-
const
|
|
1076
|
-
|
|
1185
|
+
// Calculate window area using the projected 2D coordinates
|
|
1186
|
+
const windowDimension = this.calculateWindowDimensions(windows[i].path);
|
|
1187
|
+
let windowLabelText = windows[i].name ? `${windows[i].name}` : windowMesh.name;
|
|
1188
|
+
windowLabelText = windows[i].material ? `${windowLabelText}_${windows[i].material}: ${windowDimension.area.toFixed(2)}m²` : `${windowLabelText}: ${windowDimension.area.toFixed(2)}m²`;
|
|
1189
|
+
log.info("windowLabelText ", windowLabelText);
|
|
1190
|
+
//const windowLabel = windows[i].name ? `${windows[i].name}_${windows[i].material}` : `Window ${i}_${windows[i].material}`
|
|
1191
|
+
const windowCanvas = this.createLabelCanvas(windowLabelText);
|
|
1077
1192
|
const windowArea = Math.abs(twiceSignedArea * 0.5);
|
|
1078
1193
|
const labelWidth = Math.max(0.5, Math.min(2, Math.sqrt(Math.max(0.0001, windowArea))));
|
|
1079
1194
|
const labelHeight = labelWidth / 4;
|
package/lib/types.d.ts
CHANGED
|
@@ -461,6 +461,7 @@ export interface ComponentOptions {
|
|
|
461
461
|
drawingMode?: string | undefined;
|
|
462
462
|
targetIndex?: number | undefined;
|
|
463
463
|
targetUUID?: string | undefined;
|
|
464
|
+
deductWindowFromWallArea?: boolean | undefined;
|
|
464
465
|
}
|
|
465
466
|
export interface VectorCoords {
|
|
466
467
|
object_position: Vector3;
|
|
@@ -762,6 +763,7 @@ export declare enum SPACE_EVENTS {
|
|
|
762
763
|
SCREEN_SHARE_HOST_END_SESSION = "SCREEN_SHARE_HOST_END_SESSION",
|
|
763
764
|
SCREEN_SHARE_GUEST_LEAVE_SESSION = "SCREEN_SHARE_GUEST_LEAVE_SESSION",
|
|
764
765
|
SCREEN_SHARE_BACK_USER_LIST_PANE = "SCREEN_SHARE_BACK_USER_LIST_PANE",
|
|
766
|
+
SCREEN_SHARE_TERMINATED = "SCREEN_SHARE_TERMINATED",
|
|
765
767
|
PIPE_INIT = "PIPE_INIT",
|
|
766
768
|
PIPE_CATEGORY_REMOVED = "PIPE_CATEGORY_REMOVED",
|
|
767
769
|
PIPE_CATEGORY_SAVED = "PIPE_CATEGORY_SAVED",
|
package/lib/types.js
CHANGED
|
@@ -124,6 +124,7 @@ export var SPACE_EVENTS;
|
|
|
124
124
|
SPACE_EVENTS["SCREEN_SHARE_HOST_END_SESSION"] = "SCREEN_SHARE_HOST_END_SESSION";
|
|
125
125
|
SPACE_EVENTS["SCREEN_SHARE_GUEST_LEAVE_SESSION"] = "SCREEN_SHARE_GUEST_LEAVE_SESSION";
|
|
126
126
|
SPACE_EVENTS["SCREEN_SHARE_BACK_USER_LIST_PANE"] = "SCREEN_SHARE_BACK_USER_LIST_PANE";
|
|
127
|
+
SPACE_EVENTS["SCREEN_SHARE_TERMINATED"] = "SCREEN_SHARE_TERMINATED";
|
|
127
128
|
// PIPE
|
|
128
129
|
SPACE_EVENTS["PIPE_INIT"] = "PIPE_INIT";
|
|
129
130
|
SPACE_EVENTS["PIPE_CATEGORY_REMOVED"] = "PIPE_CATEGORY_REMOVED";
|
package/package.json
CHANGED
package/static/atwinui.css
CHANGED
|
@@ -2054,7 +2054,8 @@ dialog#at-screen-share-request-modal::backdrop {
|
|
|
2054
2054
|
|
|
2055
2055
|
.at_screen_share_request_message {
|
|
2056
2056
|
font-size: 24px;
|
|
2057
|
-
font-weight:
|
|
2057
|
+
font-weight: 700;
|
|
2058
|
+
color: #263646ef !important;
|
|
2058
2059
|
padding: none !important;
|
|
2059
2060
|
margin: none !important;
|
|
2060
2061
|
}
|