architwin 1.16.9 → 1.17.1

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.
@@ -12,13 +12,15 @@ import { batchAddEventListenerByClassName, handleDeletePartition, handlePartitio
12
12
  import i18n from "../i18n";
13
13
  import { getCurrentPolygonData, handlePartitionRowEditBtnClickEvent, handlePartitionWallEditBtn, setCurrentEditWindowIndex, setDrawConfig, setDrawingMode, setIsEditWindow, setPartitionFormMode } from "./roomFormPane";
14
14
  import { SPACE_EVENTS } from "../../../../types";
15
- import { _3DXObjects, dispatchSpaceEvent, enableVerticeControls, getChildrenOfModel, goToModel, goToPosition, renderPolygon, setSelectedObject } from "../../../../architwin";
15
+ import { _3DXObjects, dispatchSpaceEvent, enableVerticeControls, getChildrenOfModel, getIsPolygonVisible, goToModel, goToPosition, renderPolygon, setSelectedObject } from "../../../../architwin";
16
16
  import log from 'loglevel';
17
17
  import { getShortcutTooltipHTML } from "../static/common";
18
+ import { Notyf } from "notyf";
18
19
  let roomDataArray = [];
19
20
  let currentEditRoomData = null;
20
21
  let currentSelectedPartitionId = null;
21
22
  let currentFilteredDisplay = "All";
23
+ let notify = new Notyf({ position: { x: 'left', y: 'bottom' } });
22
24
  /**
23
25
  * Renders and returns the HTML element for the room tree pane.
24
26
  * @returns {HTMLElement} The HTML element representing the room tree pane.
@@ -341,39 +343,51 @@ function toggleSelectedPartition() {
341
343
  toggleDisplayPane(event.target.id);
342
344
  }));
343
345
  batchAddEventListenerByClassName('at_room_visible_btn', (event) => __awaiter(this, void 0, void 0, function* () {
344
- toggleRoomTreeClickDisability(true);
345
- log.info('Event', event);
346
- const target = event.target;
347
- // Prevent event from propagating up to parent elements
348
- event.stopPropagation();
349
- // Highlight selected item
350
- highlightSelectedItem(event);
351
- // Handle visibility logic
352
- handlePartitionVisibility(target.id);
346
+ const isPolygonVisible = getIsPolygonVisible();
347
+ if (isPolygonVisible) {
348
+ toggleRoomTreeClickDisability(true);
349
+ log.info('Event', event);
350
+ const target = event.target;
351
+ // Prevent event from propagating up to parent elements
352
+ event.stopPropagation();
353
+ // Highlight selected item
354
+ highlightSelectedItem(event);
355
+ // Handle visibility logic
356
+ handlePartitionVisibility(target.id);
357
+ }
358
+ else {
359
+ notify.error(`${i18n.t('PleaseOnPolygonVisibility')}`);
360
+ }
353
361
  }));
354
362
  batchAddEventListenerByClassName('at_child_visible_btn', (event) => __awaiter(this, void 0, void 0, function* () {
355
363
  var _a;
356
- toggleRoomTreeClickDisability(true);
357
- const target = event.currentTarget;
358
- const li = target.closest('li');
359
- if ((_a = li === null || li === void 0 ? void 0 : li.getAttribute('id')) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes('window')) {
360
- event.stopPropagation();
361
- handleWindowVisibility(target, true);
364
+ const isPolygonVisible = getIsPolygonVisible();
365
+ if (isPolygonVisible) {
366
+ toggleRoomTreeClickDisability(true);
367
+ const target = event.currentTarget;
368
+ const li = target.closest('li');
369
+ if ((_a = li === null || li === void 0 ? void 0 : li.getAttribute('id')) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes('window')) {
370
+ event.stopPropagation();
371
+ handleWindowVisibility(target, true);
372
+ }
373
+ else {
374
+ const wallId = target.getAttribute('polygon-item-id');
375
+ const windowItems = document.querySelectorAll(`li.at_window_row_item[wall-id="${wallId}"]`);
376
+ yield new Promise(resolve => setTimeout(resolve, 1));
377
+ yield new Promise(resolve => requestAnimationFrame(resolve));
378
+ const parentVisibleState = yield handlePolygonVisibility(target.id);
379
+ if (windowItems && windowItems.length > 0) {
380
+ windowItems.forEach((windowLi) => {
381
+ const visibilityBtn = windowLi.querySelector('.at_child_visible_btn');
382
+ if (visibilityBtn) {
383
+ handleWindowVisibility(visibilityBtn, false, parentVisibleState);
384
+ }
385
+ });
386
+ }
387
+ }
362
388
  }
363
389
  else {
364
- const wallId = target.getAttribute('polygon-item-id');
365
- const windowItems = document.querySelectorAll(`li.at_window_row_item[wall-id="${wallId}"]`);
366
- yield new Promise(resolve => setTimeout(resolve, 1));
367
- yield new Promise(resolve => requestAnimationFrame(resolve));
368
- const parentVisibleState = yield handlePolygonVisibility(target.id);
369
- if (windowItems && windowItems.length > 0) {
370
- windowItems.forEach((windowLi) => {
371
- const visibilityBtn = windowLi.querySelector('.at_child_visible_btn');
372
- if (visibilityBtn) {
373
- handleWindowVisibility(visibilityBtn, false, parentVisibleState);
374
- }
375
- });
376
- }
390
+ notify.error(`${i18n.t('PleaseOnPolygonVisibility')}`);
377
391
  }
378
392
  }));
379
393
  batchAddEventListenerByClassName('at_partition_wall_row_item', (event) => __awaiter(this, void 0, void 0, function* () {
@@ -11,7 +11,7 @@ export declare function toggleIoTDevicesOptions(): void;
11
11
  * Sets Radio Button of the IoT's the Linked System
12
12
  *
13
13
  */
14
- export declare function setSelectedIoTSystemRadio(payload: string): void;
14
+ export declare function setSelectedIoTSystem(payload: string): void;
15
15
  /**
16
16
  * Clears dropdowns for both Category and Devices
17
17
  *
@@ -43,6 +43,8 @@ export declare function getIotTagFormData(): {
43
43
  iotSystem: string;
44
44
  tag_type: TAG_TYPE;
45
45
  };
46
+ export declare function initIoTLinkedSystemOptions(): void;
47
+ export declare function selectIoTLinkedSystemOptions(): void;
46
48
  /**
47
49
  * Clears all Fields Input Fields including the Linked Devices Table
48
50
  *
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { IOT_LINKED_SYSTEMS, SPACE_EVENTS, TAG_TYPE } from '../../../types';
11
11
  import log from 'loglevel';
12
12
  import i18n from './i18n';
13
- import { dispatchSpaceEvent, _tagIotCategoryTypes, _tagIotDevices, _tags } from '../../../architwin';
13
+ import { dispatchSpaceEvent, _tagIotCategoryTypes, _tagIotDevices, _tags, _iotLinkedSyatemOptions } from '../../../architwin';
14
14
  import { stringContains, generateUUID } from "../../../utils";
15
15
  import { batchAddEventListenerByClassName } from '../../events';
16
16
  import { toggleModal, setModalAction } from "./modal";
@@ -18,12 +18,13 @@ import { Notyf } from 'notyf';
18
18
  let selectedIoTCatOption;
19
19
  let selectedIoTDeviceOption;
20
20
  export let iotTagFormMode = "ADD" /* FORM_MODE.ADD */;
21
- export let selectedIoTSystem = '';
21
+ export let selectedIoTSystem = IOT_LINKED_SYSTEMS.BEMAC;
22
22
  export let selectedIotTag = undefined;
23
23
  let tagIotName, iotModelName, iotSerialNumber, iotMfrName, iotSystemLink;
24
24
  let selectedIoTCat;
25
25
  let linkedDevicesArray = [];
26
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', 'mdi-camera', 'mdi-dots-horizontal'];
27
+ let iotLinkedSystemOptions = ['BEMAC', 'HANASYS', 'Url Link', 'i-MTEC'];
27
28
  let notify = new Notyf({ position: { x: 'left', y: 'bottom' } });
28
29
  export function renderTagIOTFormPane() {
29
30
  const element = document.createElement('div');
@@ -37,38 +38,27 @@ export function renderTagIOTFormPane() {
37
38
  </div>
38
39
 
39
40
  <div class="at_form_container at_scrollable_container at_h-min-70">
40
- <label for="">${i18n.t('LinkedSystems')}</label>
41
- <div class="at_linked_systems_options_contianer at_gap_2" style="display: inline-flex">
42
- <label class="at_flex at_align_center at_text_xs at_gap_1">
43
- <input type="radio" id="at-linked-radio-bemac" name="iot-link-system" checked value=${IOT_LINKED_SYSTEMS.BEMAC} selected />
44
- ${i18n.t("BEMAC")}
45
- </label>
46
- <label class="at_flex at_align_center at_text_xs at_gap_1">
47
- <input type="radio" id="at-linked-radio-hanasys" name="iot-link-system" value=${IOT_LINKED_SYSTEMS.HANASYS} />
48
- ${i18n.t("HANASYS")}
49
- </label>
50
- <label class="at_flex at_align_center at_text_xs at_gap_1">
51
- <input type="radio" id="at-linked-radio-link" name="iot-link-system" value=${IOT_LINKED_SYSTEMS.URL_LINK} />
52
- ${i18n.t("URLLink")}
53
- </label>
54
- </div>
41
+ <div class="at_field at_flex_column">
55
42
 
56
- <div class="at_field at_flex_column">
57
- <label for="">${i18n.t('Category')}</label>
58
- <div id="at-iot-category-dropdown" data-cy="at-iot-category-dropdown">
59
- <div id="at-iot-cat-filter-dropdown" class="at_dropdown at_flex at_flex_row at_space_between">
60
- <div class="at_dropdown_toggle" id="at-iot-selected-cat" data-cy="at-iot-selected-cat">${i18n.t(selectedIoTCatOption)}</div>
61
- <span class="mdi mdi-chevron-down at_chevron" id="at-iot-cat-filter-chevron" data-cy="at-iot-cat-filter-chevron"></span>
62
- </div>
63
-
64
- <div style="position:absolute;">
65
- <div class="at_dropdown_options" id="at-iot-category-options" data-cy="at-iot-category-options">
43
+ <label>${i18n.t('LinkedSystems')}</label>
66
44
 
67
- </div>
68
- </div>
45
+ <div id="at-iot-linked-system-listbox" class="at_listbox" data-cy="at-iot-linked-system-listbox">
46
+ <ul class="at_listbox_options" role="listbox" aria-label="Linked Systems">
47
+
48
+ </ul>
49
+ </div>
69
50
 
70
- </div>
51
+ <label for="">${i18n.t('Category')}</label>
52
+ <div id="at-iot-category-dropdown" data-cy="at-iot-category-dropdown">
53
+ <div id="at-iot-cat-filter-dropdown" class="at_dropdown at_flex at_flex_row at_space_between">
54
+ <div class="at_dropdown_toggle" id="at-iot-selected-cat" data-cy="at-iot-selected-cat">${i18n.t(selectedIoTCatOption)}</div>
55
+ <span class="mdi mdi-chevron-down at_chevron" id="at-iot-cat-filter-chevron" data-cy="at-iot-cat-filter-chevron"></span>
56
+ </div>
57
+ <div style="position:absolute;">
58
+ <div class="at_dropdown_options" id="at-iot-category-options" data-cy="at-iot-category-options"></div>
71
59
  </div>
60
+ </div>
61
+ </div>
72
62
 
73
63
  <div class="at-field at_flex_row at_justify_between">
74
64
  <label for="">${i18n.t('TagName')}</label>
@@ -189,7 +179,6 @@ function setInputFields() {
189
179
  }
190
180
  export function setIotCategoryOptions() {
191
181
  log.info('setIotCategoryOptions()');
192
- dispatchSpaceEvent(SPACE_EVENTS.GET_IOT_CATEGORIES, { payload: 'hello from library' });
193
182
  if (_tagIotCategoryTypes) {
194
183
  renderIotCategoryDropdownOptions('at-iot-category-options', _tagIotCategoryTypes);
195
184
  batchAddEventListenerByClassName('at_iot_cat_option', (event) => {
@@ -242,34 +231,21 @@ export function toggleIoTDevicesOptions() {
242
231
  * Sets Radio Button of the IoT's the Linked System
243
232
  *
244
233
  */
245
- export function setSelectedIoTSystemRadio(payload) {
246
- log.info('setSelectedIoTSystemRadio()');
247
- const linkedDeviceContainer = document.getElementById('at-iot-device-main-container');
248
- const systemLinkContainer = document.getElementById('at-iot-system-link-container');
249
- let targetId = '';
250
- if (payload == IOT_LINKED_SYSTEMS.BEMAC) {
251
- targetId = 'at-linked-radio-bemac';
252
- }
253
- else if (payload == IOT_LINKED_SYSTEMS.HANASYS) {
254
- targetId = 'at-linked-radio-hanasys';
255
- }
256
- else if (payload == IOT_LINKED_SYSTEMS.URL_LINK) {
257
- targetId = 'at-linked-radio-link';
258
- }
259
- const linkedRadio = document.getElementById(targetId);
260
- if (linkedRadio) {
261
- selectedIoTSystem = payload;
262
- linkedRadio.checked = true;
263
- }
264
- if (payload === IOT_LINKED_SYSTEMS.URL_LINK) {
265
- log.info('payload == IOT_LINKED_SYSTEMS.URL_LINK', payload, IOT_LINKED_SYSTEMS.URL_LINK);
266
- linkedDeviceContainer.style.display = 'none';
267
- systemLinkContainer.style.display = 'block';
268
- }
269
- else {
270
- linkedDeviceContainer.style.display = 'block';
271
- systemLinkContainer.style.display = 'none';
272
- }
234
+ export function setSelectedIoTSystem(payload) {
235
+ log.info('setSelectedIoTSystem()', payload);
236
+ selectedIoTSystem = payload;
237
+ const options = document.querySelectorAll('.at_listbox_option');
238
+ options.forEach(option => {
239
+ log.info("option.getAttribute('data-value') == selectedIoTSystem", option.getAttribute('data-value'), selectedIoTSystem);
240
+ if (option.getAttribute('data-value') == selectedIoTSystem) {
241
+ log.info("selected");
242
+ option.classList.add('is-selected');
243
+ }
244
+ else {
245
+ log.info("unselected");
246
+ option.classList.remove('is-selected');
247
+ }
248
+ });
273
249
  }
274
250
  /**
275
251
  * Clears dropdowns for both Category and Devices
@@ -321,15 +297,16 @@ export function initIoTFormData(tagId) {
321
297
  const iotData = foundTag.iot_tag;
322
298
  //@ts-ignore
323
299
  if (iotData) {
300
+ log.info("iotData", iotData);
324
301
  iotModelName.value = iotData.model_name;
325
302
  iotSerialNumber.value = iotData.serial_number;
326
303
  iotMfrName.value = iotData.manufacturer_site;
327
304
  iotSystemLink.value = iotData.system_link;
328
305
  if (iotData.linked_system) {
329
- setSelectedIoTSystemRadio(iotData.linked_system);
306
+ setSelectedIoTSystem(iotData.linked_system);
330
307
  }
331
308
  else {
332
- setSelectedIoTSystemRadio(IOT_LINKED_SYSTEMS.BEMAC);
309
+ setSelectedIoTSystem(IOT_LINKED_SYSTEMS.BEMAC);
333
310
  }
334
311
  if (iotData.iot_category) {
335
312
  log.info('found cat 1: ', i18n.t(iotData.iot_category), iotData.iot_category, _tagIotCategoryTypes);
@@ -362,7 +339,7 @@ export function initIoTFormData(tagId) {
362
339
  else {
363
340
  // this is due to selecting the tags created from James
364
341
  log.info('initIoTFormData()', iotData);
365
- setSelectedIoTSystemRadio(IOT_LINKED_SYSTEMS.BEMAC);
342
+ setSelectedIoTSystem(IOT_LINKED_SYSTEMS.BEMAC);
366
343
  setSelectedIoTCat({ uuid: generateUUID(), name: i18n.t('NoSelection') });
367
344
  renderIotCategoryDropdownOptions('at-iot-category-options', _tagIotCategoryTypes);
368
345
  renderIotDeviceDropdownOptions('at-iot-device-options', _tagIotDevices);
@@ -424,9 +401,18 @@ function createCatOptionElement(item, dropdownType, index) {
424
401
  option.setAttribute('iot-category-uuid', item.uuid);
425
402
  option.setAttribute('dropdown-type', dropdownType);
426
403
  option.setAttribute('data-cy', `at-iot-category-option-${item.uuid}`);
404
+ // option.innerHTML = `
405
+ // <span id="at-device-${item.name}" class="mdi ${iotCategoryIconList[index]}"></span>
406
+ // ${i18n.t(item.name)}
407
+ // `
427
408
  option.innerHTML = `
428
- <span id="at-device-${item.name}" class="mdi ${iotCategoryIconList[index]}"></span>
429
- ${i18n.t(item.name)}
409
+ <img
410
+ id="at-device-${item.name}"
411
+ src="data:image/png;base64,${item.json_data.iconBase64}"
412
+ alt="${item.name}"
413
+ style="width: 1.2em; height: 1.2em; vertical-align: middle; margin-right: 0.3em;"
414
+ />
415
+ ${i18n.t(item.name)}
430
416
  `;
431
417
  return option;
432
418
  }
@@ -545,7 +531,7 @@ export function getIotTagFormData() {
545
531
  tagMf: iotMfrName.value,
546
532
  // tagCategoryId: selectedIoTCat.uuid,
547
533
  tagCategoryId: selectedIoTCat ? selectedIoTCat.name : undefined,
548
- systemLink: iotSystemLink.value,
534
+ systemLink: selectedIoTSystem,
549
535
  linkedDevices: linkedDevicesArray,
550
536
  iotSystem: selectedIoTSystem,
551
537
  tag_type: TAG_TYPE.IOT
@@ -659,6 +645,38 @@ function deleteDeviceRow(deviceId) {
659
645
  }
660
646
  }
661
647
  }
648
+ export function initIoTLinkedSystemOptions() {
649
+ dispatchSpaceEvent(SPACE_EVENTS.GET_IOT_LINKED_SYSTEM_OPTIONS, { payload: 'hello from library' });
650
+ const listbox = document.querySelector('#at-iot-linked-system-listbox .at_listbox_options');
651
+ iotLinkedSystemOptions = _iotLinkedSyatemOptions;
652
+ log.info("_iotLinkedSyatemOptions", _iotLinkedSyatemOptions);
653
+ log.info("iotLinkedSystemOptions", iotLinkedSystemOptions);
654
+ listbox.innerHTML = iotLinkedSystemOptions
655
+ .map((option, index) => `
656
+ <li
657
+ class="at_listbox_option ${index === 0 ? 'is-selected' : ''}"
658
+ role="option"
659
+ data-value="${option}"
660
+ tabindex="0"
661
+ >
662
+ ${option}
663
+ </li>
664
+ `)
665
+ .join('');
666
+ }
667
+ export function selectIoTLinkedSystemOptions() {
668
+ log.info("selectIoTLinkedSystemOptions");
669
+ const options = document.querySelectorAll('.at_listbox_option');
670
+ options.forEach(option => {
671
+ option.addEventListener('click', () => {
672
+ log.info("option", option);
673
+ options.forEach(o => o.classList.remove('is-selected'));
674
+ option.classList.add('is-selected');
675
+ selectedIoTSystem = option.getAttribute('data-value');
676
+ log.info("selectedLinkedSystem", selectedIoTSystem);
677
+ });
678
+ });
679
+ }
662
680
  /**
663
681
  * Clears all Fields Input Fields including the Linked Devices Table
664
682
  *
@@ -679,7 +697,7 @@ export function clearIotFields() {
679
697
  linkedDevicesArray = [];
680
698
  selectedIoTSystem = '';
681
699
  selectedIoTCat = undefined;
682
- setSelectedIoTSystemRadio(IOT_LINKED_SYSTEMS.BEMAC);
700
+ setSelectedIoTSystem(IOT_LINKED_SYSTEMS.BEMAC);
683
701
  deviceContainer.innerHTML = '';
684
702
  iotTagFormMode = "ADD" /* FORM_MODE.ADD */;
685
703
  selectedIotTag = undefined;
@@ -1,4 +1,4 @@
1
- import { ITag, ITagCategory, SortConfig, TAG_TYPE } from "../../../types";
1
+ import { ITag, ITagCategory, SortConfig, TAG_TYPE, ITagIOTCategory } from "../../../types";
2
2
  import { MpSdk } from "../../../../bundle/sdk";
3
3
  export declare const tagVisibility: Record<TAG_TYPE, Record<string, boolean>>;
4
4
  export declare let selectedCategoryFilterId: any;
@@ -31,3 +31,7 @@ export declare function saveTagVisibilityToStorage(tagVisibility: Record<TAG_TYP
31
31
  export declare function initializeTagVisibility(): void;
32
32
  export declare function updateShowAllButton(): void;
33
33
  export declare function clearTagVisibilityStorage(): void;
34
+ export declare function setIotCategoryFilterOptions(): void;
35
+ export declare function filterIotTagByCategory(tags: ITag[]): void;
36
+ export declare function setSelectedIoTCategoryFilter(payload: ITagIOTCategory): void;
37
+ export declare function renderIotCategoryDropdownFilterOptions(elementId: string, items: Array<ITagIOTCategory>): void;
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { SPACE_EVENTS, sortTagOptions, TAG_TYPE } from "../../../types";
11
11
  import { batchAddEventListenerByClassName, toggleDisplayPane, batchAddEventListenerByDataAttribute } from "../../events";
12
- import { convertToCssRgb, getBundleVersion } from "../../../utils";
13
- import { gotoTag, disposeTag, dispatchSpaceEvent, _tags, getUserAssignedCategories, _mpConfig, moveTag, getAtwinSdk, toggleVisibilityTag } from "../../../architwin";
12
+ import { convertToCssRgb, getBundleVersion, stringContains } from "../../../utils";
13
+ import { gotoTag, disposeTag, dispatchSpaceEvent, _tags, getUserAssignedCategories, _mpConfig, moveTag, getAtwinSdk, toggleVisibilityTag, _tagIotCategoryTypes } from "../../../architwin";
14
14
  import { initFormData, toggleDropdown } from "./tagFormPane";
15
15
  import { toggleModal, setModalAction } from "./modal";
16
16
  import { initIoTFormData, setIoTFormMode } from './tagIotFormPane';
@@ -34,12 +34,14 @@ const notify = new Notyf({
34
34
  let _tagLink;
35
35
  let isChevronEventAdded = false;
36
36
  let allSubcategories = [];
37
+ let selectedIoTCategoryFilterOption;
38
+ let selectedIoTCategoryFilter;
39
+ let iotTags = [];
37
40
  let tagSearchTerm = '';
38
41
  export const tagVisibility = {
39
42
  [TAG_TYPE.MP]: {},
40
43
  [TAG_TYPE.IOT]: {}
41
44
  };
42
- let iotTags = [];
43
45
  export let selectedCategoryFilterId = undefined;
44
46
  export let selectedSubCategoryFilterId = undefined;
45
47
  export let isTagPaneActive = true;
@@ -89,7 +91,7 @@ export function renderTagListPane() {
89
91
  </button>
90
92
 
91
93
  </div>
92
- <div class="at_field at_flex_column" style="${_tagCategories ? '' : 'display: none;'}">
94
+ <div class="at_field at_flex_column" style="${_tagCategories ? '' : 'display: none;'}" id="at-custom-category-filter-dropdown-container">
93
95
  <label for="">${i18n.t('Category')}</label>
94
96
  <div id="at-custom-category-filter-dropdown" data-cy="at-custom-category-filter-dropdown">
95
97
  <div id="at-category-filter-dropdown" class="at_dropdown at_flex at_flex_row at_space_between">
@@ -117,6 +119,19 @@ export function renderTagListPane() {
117
119
  </div>
118
120
  </div>
119
121
  </div>
122
+
123
+ <div class="at_field at_flex_column" id="at-custom-iot-category-filter-dropdown-container">
124
+ <label for="">${i18n.t('Category')}</label>
125
+ <div id="at-custom-iot-category-filter-dropdown" data-cy="at-custom-iot-category-filterdropdown">
126
+ <div id="at-custom-iot-cat-filter-dropdown" class="at_dropdown at_flex at_flex_row at_space_between">
127
+ <div class="at_dropdown_toggle" id="at-custom-iot-selected-filter-category" data-cy="at-custom-iot-selected-filter-category">${i18n.t('NoSelection')}</div>
128
+ <span class="mdi mdi-chevron-down at_chevron" id="at-iot-category-filter-chevron" data-cy="at-iot-category-filter-chevron"></span>
129
+ </div>
130
+ <div style="position:absolute;">
131
+ <div class="at_dropdown_options" id="at-iot-category-filter-options" data-cy="at-iot-category-filter-options"></div>
132
+ </div>
133
+ </div>
134
+ </div>
120
135
  </div>
121
136
  <div class="at_form_container at_scrollable_container at_h-min-45" id="at-tag-list-scrollable-container">
122
137
  <table id="at-tag-list-container">
@@ -596,6 +611,7 @@ export function setSelectedSubcategoryFilter(subcategoryId) {
596
611
  function initDropdownEventListeners() {
597
612
  const categoryChevron = document.getElementById('at-category-filter-dropdown');
598
613
  const subcategoryChevron = document.getElementById('at-subcategory-filter-dropdown');
614
+ const iotCategoryChevron = document.getElementById('at-custom-iot-cat-filter-dropdown');
599
615
  if (categoryChevron) {
600
616
  if (isChevronEventAdded == false) {
601
617
  categoryChevron.addEventListener('click', () => {
@@ -616,6 +632,16 @@ function initDropdownEventListeners() {
616
632
  console.log("Click event already attached to subcategory chevron");
617
633
  }
618
634
  }
635
+ if (iotCategoryChevron) {
636
+ if (isChevronEventAdded == false) {
637
+ iotCategoryChevron.addEventListener('click', () => {
638
+ toggleDropdown('at-iot-category-filter-options');
639
+ });
640
+ }
641
+ else {
642
+ console.log("Click event already attached to subcategory chevron");
643
+ }
644
+ }
619
645
  isChevronEventAdded = true;
620
646
  }
621
647
  export function getSearchTagTerm() {
@@ -825,3 +851,115 @@ export function clearTagVisibilityStorage() {
825
851
  log.info('No tag in storage found');
826
852
  }
827
853
  }
854
+ export function setIotCategoryFilterOptions() {
855
+ log.info('setIotCategoryOptions()');
856
+ if (_tagIotCategoryTypes) {
857
+ renderIotCategoryDropdownFilterOptions('at-iot-category-filter-options', _tagIotCategoryTypes);
858
+ batchAddEventListenerByClassName('at_iot_cat_filter_option', (event) => {
859
+ log.info("category filter clicked");
860
+ //@ts-ignore
861
+ const selectedCat = event.target;
862
+ const catUUID = selectedCat.getAttribute('iot-category-filter-uuid');
863
+ const iotTags = _tags.filter(tag => tag.tag_type == TAG_TYPE.IOT);
864
+ if (catUUID == '') {
865
+ // no selection selected
866
+ selectedIoTCategoryFilter = { uuid: '', name: 'NoSelection' };
867
+ setSelectedIoTCategoryFilter(selectedIoTCategoryFilter);
868
+ renderTags(iotTags);
869
+ }
870
+ const getCatName = _tagIotCategoryTypes.find(cat => cat.uuid === catUUID);
871
+ if (getCatName) {
872
+ selectedIoTCategoryFilter = { uuid: catUUID, name: getCatName.name };
873
+ setSelectedIoTCategoryFilter(selectedIoTCategoryFilter);
874
+ log.info('cat id: ', selectedIoTCategoryFilter);
875
+ filterIotTagByCategory(iotTags);
876
+ }
877
+ toggleDropdown('at-iot-category-filter-options');
878
+ });
879
+ }
880
+ }
881
+ export function filterIotTagByCategory(tags) {
882
+ log.info("selectedIoTCategoryFilter", selectedIoTCategoryFilter, _tags);
883
+ const filteredTags = tags.filter(tag => tag.iot_tag.iot_category == selectedIoTCategoryFilter.name);
884
+ renderTags(filteredTags);
885
+ }
886
+ // displays selected Category in the dropdown
887
+ export function setSelectedIoTCategoryFilter(payload) {
888
+ log.info('setSelectedIoTCat()', payload);
889
+ const selectedOption = document.getElementById('at-custom-iot-selected-filter-category');
890
+ selectedOption.innerText = i18n.t(payload.name);
891
+ }
892
+ export function renderIotCategoryDropdownFilterOptions(elementId, items) {
893
+ const element = document.getElementById(elementId);
894
+ if (!element) {
895
+ console.error("Parameter element is undefined");
896
+ return;
897
+ }
898
+ if (!items) {
899
+ console.error("Parameter items is undefined");
900
+ return;
901
+ }
902
+ const isFilterDropdown = stringContains(elementId, 'filter');
903
+ log.info("isFilterDropdown", isFilterDropdown);
904
+ //Clear previosly appended children
905
+ element.innerHTML = ``;
906
+ const selectedIotCategoryOption = document.getElementById(isFilterDropdown ? 'at-iot-category-filter-dropdown-toggle' : 'at-iot-category-dropdown-toggle');
907
+ if (selectedIotCategoryOption) {
908
+ selectedIotCategoryOption.textContent = `${i18n.t('NoSelection')}`;
909
+ selectedIoTCategoryFilterOption = undefined;
910
+ }
911
+ //Add the no selection option
912
+ const noSelection = document.createElement('div');
913
+ noSelection.classList.add('at_option');
914
+ noSelection.classList.add('at_iot_cat_filter_option');
915
+ noSelection.setAttribute('iot-category-filter-uuid', '');
916
+ noSelection.setAttribute('dropdown-type', 'iotcategory');
917
+ noSelection.innerHTML = `
918
+ <span class="mdi mdi-circle-slice-1"></span> ${i18n.t('NoSelection')}
919
+ `;
920
+ noSelection.onclick = () => {
921
+ selectCatOption(noSelection, isFilterDropdown ? 'at-iot-category-filter-dropdown-toggle' : 'at-iot-category-filter-dropdown-toggle');
922
+ };
923
+ element.appendChild(noSelection);
924
+ if (items.length <= 0) {
925
+ console.log("No items to render");
926
+ return;
927
+ }
928
+ items.forEach((item, index) => {
929
+ if (item.name != 'Multiple') {
930
+ const option = createCatOptionElement(item, 'iotcategoryfilter', index);
931
+ element.appendChild(option);
932
+ }
933
+ });
934
+ }
935
+ function selectCatOption(option, elementId) {
936
+ dispatchSpaceEvent(SPACE_EVENTS.GET_IOT_CAT_ICON, { payload: option });
937
+ }
938
+ function createCatOptionElement(item, dropdownType, index) {
939
+ console.log("createCatOptionElement()", item, index);
940
+ const option = document.createElement('div');
941
+ option.style.display = 'flex';
942
+ option.style.flexDirection = 'row';
943
+ option.style.justifyContent = 'left';
944
+ option.style.alignItems = 'center';
945
+ option.style.gap = '2px';
946
+ option.classList.add('at_option');
947
+ option.classList.add('at_iot_cat_filter_option');
948
+ option.setAttribute('iot-category-filter-uuid', item.uuid);
949
+ option.setAttribute('dropdown-type', dropdownType);
950
+ option.setAttribute('data-cy', `at-iot-category-filter-option-${item.uuid}`);
951
+ // option.innerHTML = `
952
+ // <span id="at-device-${item.name}" class="mdi ${iotCategoryIconList[index]}"></span>
953
+ // ${i18n.t(item.name)}
954
+ // `
955
+ option.innerHTML = `
956
+ <img
957
+ id="at-device-${item.name}"
958
+ src="data:image/png;base64,${item.json_data.iconBase64}"
959
+ alt="${item.name}"
960
+ style="width: 1.2em; height: 1.2em; vertical-align: middle; margin-right: 0.3em;"
961
+ />
962
+ ${i18n.t(item.name)}
963
+ `;
964
+ return option;
965
+ }