@dative-gpi/foundation-core-components 1.0.65 → 1.0.67-map-edit

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/components/autocompletes/FSAutocompleteChart.vue +15 -8
  2. package/components/autocompletes/FSAutocompleteDashboard.vue +14 -6
  3. package/components/autocompletes/FSAutocompleteDashboardOrganisation.vue +7 -1
  4. package/components/autocompletes/FSAutocompleteDataCategory.vue +11 -5
  5. package/components/autocompletes/FSAutocompleteDataDefinition.vue +7 -1
  6. package/components/autocompletes/FSAutocompleteGroup.vue +7 -1
  7. package/components/autocompletes/FSAutocompleteLocation.vue +6 -0
  8. package/components/autocompletes/FSAutocompleteManufacturer.vue +8 -0
  9. package/components/autocompletes/FSAutocompleteModel.vue +9 -1
  10. package/components/autocompletes/FSAutocompleteOrganisationType.vue +7 -1
  11. package/components/autocompletes/FSAutocompleteRole.vue +14 -6
  12. package/components/autocompletes/FSAutocompleteServiceAccountRoleOrganisation.vue +7 -1
  13. package/components/autocompletes/FSAutocompleteUserOrganisation.vue +9 -1
  14. package/components/customProperties/FSMetaField.vue +35 -40
  15. package/components/customProperties/FSMetaFormContent.vue +4 -3
  16. package/components/customProperties/FSMetaHistory.vue +2 -2
  17. package/components/customProperties/helpers.ts +57 -165
  18. package/components/entities/FSBaseEntitiesList.vue +12 -2
  19. package/components/entities/FSDialogSelectEntities.vue +19 -2
  20. package/components/entities/FSEntityField.vue +75 -14
  21. package/components/entities/FSSelectEntitiesList.vue +40 -7
  22. package/components/explorers/FSBaseDevicesExplorer.vue +322 -0
  23. package/components/explorers/FSBaseFoldersExplorer.vue +126 -24
  24. package/components/lists/FSDataTable.vue +22 -16
  25. package/components/lists/alerts/FSBaseAlertsList.vue +96 -106
  26. package/components/lists/alerts/FSButtonAcknowledgeAlert.vue +4 -4
  27. package/components/lists/authTokens/FSBaseAuthTokensList.vue +6 -4
  28. package/components/lists/chartOrganisationTypes/FSBaseChartOrganisationTypesList.vue +97 -34
  29. package/components/lists/chartOrganisations/FSBaseChartOrganisationsList.vue +98 -34
  30. package/components/lists/charts/FSBaseChartsList.vue +153 -64
  31. package/components/lists/comments/FSBaseCommentsList.vue +39 -23
  32. package/components/lists/connectivityScenarios/FSBaseConnectivityScenariosList.vue +128 -0
  33. package/components/lists/dashboardOrganisationTypes/FSBaseDashboardOrganisationTypesList.vue +41 -8
  34. package/components/lists/dashboards/FSBaseDashboardsList.vue +76 -16
  35. package/components/lists/dashboards/FSSimpleDashboardsList.vue +33 -7
  36. package/components/lists/dataCategories/FSBaseDataCategoriesList.vue +8 -6
  37. package/components/lists/dataDefinitions/FSBaseDataDefinitionsList.vue +8 -5
  38. package/components/lists/deviceOrganisations/FSBaseDeviceOrganisationsList.vue +70 -44
  39. package/components/lists/folders/FSBaseFoldersList.vue +27 -15
  40. package/components/lists/groups/FSBaseGroupsList.vue +13 -9
  41. package/components/lists/locations/FSBaseLocationsList.vue +17 -13
  42. package/components/lists/models/FSBaseModelsList.vue +31 -13
  43. package/components/lists/playlists/FSSimplePlaylistsList.vue +44 -0
  44. package/components/lists/roleOrganisationTypes/FSBaseRoleOrganisationTypesList.vue +6 -5
  45. package/components/lists/roleOrganisations/FSBaseRoleOrganisationsList.vue +17 -16
  46. package/components/lists/scenarioOrganisationTypes/FSBaseScenarioOrganisationTypesList.vue +45 -8
  47. package/components/lists/scenarioOrganisations/FSBaseScenarioOrganisationsList.vue +45 -7
  48. package/components/lists/scenarios/FSBaseScenariosList.vue +121 -86
  49. package/components/lists/serviceAccountOrganisations/FSBaseServiceAccountOrganisationsList.vue +10 -7
  50. package/components/lists/serviceAccountRoleOrganisations/FSBaseServiceAccountRoleOrganisationsList.vue +128 -0
  51. package/components/lists/userOrganisations/FSBaseUserOrganisationsList.vue +10 -7
  52. package/components/lists/userOrganisations/FSChipUserOrganisationsList.vue +61 -0
  53. package/components/tiles/FSChartTile.vue +71 -0
  54. package/components/tiles/FSDashboardOrganisationTile.vue +3 -3
  55. package/components/tiles/FSDashboardOrganisationTypeTile.vue +3 -3
  56. package/components/tiles/FSDashboardShallowTile.vue +3 -3
  57. package/components/tiles/FSDeviceOrganisationTile.vue +3 -3
  58. package/components/tiles/FSFolderTile.vue +7 -5
  59. package/components/tiles/FSGroupTile.vue +3 -3
  60. package/components/tiles/FSLocationTile.vue +5 -3
  61. package/components/tiles/FSModelTile.vue +64 -0
  62. package/components/tiles/FSServiceAccountOrganisationTile.vue +3 -3
  63. package/components/tiles/FSUserOrganisationTile.vue +3 -3
  64. package/components/treeviews/FSTreeViewGroup.vue +7 -1
  65. package/package.json +9 -9
  66. package/utils/dashboards.ts +4 -4
  67. package/utils/index.ts +0 -1
  68. package/utils/roles.ts +3 -3
  69. package/utils/users.ts +3 -3
  70. package/components/selects/FSAggregationSelector.vue +0 -51
  71. package/components/selects/FSAxisTypeSelector.vue +0 -48
  72. package/components/selects/FSDisplayAsSelector.vue +0 -52
  73. package/components/selects/FSFilterTypeSelector.vue +0 -53
  74. package/components/selects/FSHeatmapRuleSelector.vue +0 -52
  75. package/components/selects/FSOperationOnSelector.vue +0 -51
  76. package/components/selects/FSPlanningTypeSelector.vue +0 -51
  77. package/components/selects/FSPlotPerSelector.vue +0 -51
  78. package/components/selects/FSSelectEntityType.vue +0 -59
  79. package/components/selects/FSSerieTypeSelector.vue +0 -51
  80. package/utils/charts.ts +0 -137
@@ -3,14 +3,15 @@
3
3
  :description="$props.description"
4
4
  :hideHeader="$props.hideHeader"
5
5
  :required="$props.required"
6
- :editable="$props.editable"
6
+ :disabled="$props.disabled"
7
7
  :label="$props.label"
8
8
  :messages="$props.messages"
9
9
  :entityType="$props.entityType"
10
10
  :allowedEntityTypes="$props.allowedEntityTypes || []"
11
11
  :itemsCount="($props.modelValue || []).length"
12
- @update:entityType="$emit('update:entityType', $event); $emit('update:modelValue', [])"
12
+ @update:entityType="onEntityTypeChanged"
13
13
  :showEntities="$props.showEntities"
14
+ :showCount="$props.showCount"
14
15
  @click:select="dialog = true"
15
16
  >
16
17
  <template
@@ -18,18 +19,19 @@
18
19
  >
19
20
  <FSSimpleEntitiesList
20
21
  :entity-type="$props.entityType"
21
- :filters="listComponentFilters"
22
+ :filters="simpleListFilters"
22
23
  :showEdit="false"
23
24
  @click:remove="onRemove"
24
25
  />
25
26
  </template>
26
27
  </FSEntityFieldUI>
27
28
  <FSDialogSelectEntities
29
+ :singleSelect="$props.singleSelect"
28
30
  :entity-type="$props.entityType"
29
31
  :filters="$props.filters"
30
32
  v-model="dialog"
31
33
  :selecteds="$props.modelValue || []"
32
- @update:selecteds="$emit('update:modelValue', $event)"
34
+ @update:selecteds="onModelValueChanged"
33
35
  />
34
36
  </template>
35
37
 
@@ -39,7 +41,7 @@ import { defineComponent, ref, type PropType, computed } from "vue";
39
41
 
40
42
  import { EntityType } from "@dative-gpi/foundation-shared-domain/enums";
41
43
 
42
- import type { DeviceOrganisationFilters } from "@dative-gpi/foundation-core-domain/models";
44
+ import type { DashboardOrganisationFilters, DashboardOrganisationTypeFilters, DeviceOrganisationFilters, FolderFilters, GroupFilters, LocationFilters, ModelFilters, UserOrganisationFilters } from "@dative-gpi/foundation-core-domain/models";
43
45
 
44
46
  import FSEntityFieldUI from "@dative-gpi/foundation-shared-components/components/fields/FSEntityFieldUI.vue";
45
47
 
@@ -94,10 +96,10 @@ export default defineComponent({
94
96
  required: false,
95
97
  default: null
96
98
  },
97
- editable: {
99
+ disabled: {
98
100
  type: Boolean,
99
101
  required: false,
100
- default: true
102
+ default: false
101
103
  },
102
104
  entityType: {
103
105
  type: Number as PropType<EntityType>,
@@ -112,32 +114,91 @@ export default defineComponent({
112
114
  type: Boolean,
113
115
  required: false,
114
116
  default: true
117
+ },
118
+ singleSelect: {
119
+ type: Boolean,
120
+ required: false,
121
+ default: false
122
+ },
123
+ showCount: {
124
+ type: Boolean,
125
+ required: false,
126
+ default: true
115
127
  }
116
128
  },
117
- emits: ["update:modelValue", "update:entityType"],
129
+ emits: ["update","update:modelValue", "update:entityType"],
118
130
  setup(props, { emit }) {
119
131
  const dialog = ref(false);
120
132
 
121
- const listComponentFilters = computed(() => {
133
+ const simpleListFilters = computed(() => {
122
134
  switch(props.entityType) {
123
135
  case EntityType.Device:
124
136
  return {
125
137
  deviceOrganisationsIds: props.modelValue
126
138
  } satisfies DeviceOrganisationFilters;
139
+ case EntityType.Dashboard:
140
+ return {
141
+ dashboardOrganisationsIds: props.modelValue,
142
+ dashboardOrganisationTypesIds: props.modelValue,
143
+ dashboardShallowsIds: props.modelValue
144
+ } satisfies DashboardOrganisationFilters & DashboardOrganisationTypeFilters;
145
+ case EntityType.Group:
146
+ return {
147
+ groupsIds: props.modelValue
148
+ } satisfies GroupFilters;
149
+ case EntityType.Folder:
150
+ return {
151
+ foldersIds: props.modelValue
152
+ } satisfies FolderFilters;
153
+ case EntityType.Location:
154
+ return {
155
+ locationsIds: props.modelValue
156
+ } satisfies LocationFilters;
157
+ case EntityType.User:
158
+ return {
159
+ userOrganisationsIds: props.modelValue
160
+ } satisfies UserOrganisationFilters;
161
+ case EntityType.Model:
162
+ return {
163
+ modelsIds: props.modelValue
164
+ } satisfies ModelFilters;
127
165
  default:
128
- return {};
166
+ return undefined;
129
167
  };
130
- });
168
+ })
131
169
 
132
170
  const onRemove = (id: string) => {
133
171
  emit("update:modelValue", props.modelValue.filter((i) => i !== id));
172
+ emit("update", {
173
+ entityType: props.entityType,
174
+ modelValue: props.modelValue.filter((i) => i !== id)
175
+ })
176
+ }
177
+
178
+ const onEntityTypeChanged = (entityType: EntityType) => {
179
+ emit('update:entityType', entityType);
180
+ emit('update:modelValue', []);
181
+ emit("update", {
182
+ entityType,
183
+ modelValue: []
184
+ })
185
+ }
186
+
187
+ const onModelValueChanged = (modelValue: string[]) => {
188
+ emit('update:modelValue', modelValue);
189
+ emit("update", {
190
+ entityType: props.entityType,
191
+ modelValue
192
+ })
134
193
  }
135
194
 
136
195
  return {
137
196
  dialog,
138
- listComponentFilters,
139
- onRemove
197
+ simpleListFilters,
198
+ onRemove,
199
+ onEntityTypeChanged,
200
+ onModelValueChanged
140
201
  }
141
202
  }
142
203
  });
143
- </script>
204
+ </script>
@@ -19,7 +19,8 @@
19
19
  :entity-type="$props.entityType"
20
20
  :filters="simpleListFilters"
21
21
  :showEdit="false"
22
- :showRemove="false"
22
+ :showRemove="showRemove"
23
+ @click:remove="onRemove"
23
24
  direction="row"
24
25
  />
25
26
  </FSSlideGroup>
@@ -38,12 +39,23 @@
38
39
  {{ $tr("ui.common.entities-list", "Entities list") }}
39
40
  </FSText>
40
41
  <FSBaseEntitiesList
42
+ :singleSelect="$props.singleSelect"
41
43
  :entity-type="$props.entityType"
42
44
  :tableCode="tableCode"
43
45
  :modelValue="$props.modelValue"
44
46
  @update:modelValue="$emit('update:modelValue', $event)"
45
47
  v-bind="baseTableAttrs"
46
- />
48
+ >
49
+ <template
50
+ v-for="(_, name) in $slots"
51
+ v-slot:[getNameSlot(name)]="slotData"
52
+ >
53
+ <slot
54
+ :name="name"
55
+ v-bind="slotData"
56
+ />
57
+ </template>
58
+ </FSBaseEntitiesList>
47
59
  </FSCol>
48
60
  </FSCol>
49
61
  </template>
@@ -52,7 +64,7 @@
52
64
  import { defineComponent, type PropType, computed } from "vue";
53
65
 
54
66
  import { EntityType } from "@dative-gpi/foundation-shared-domain/enums";
55
- import type { DashboardOrganisationFilters, DashboardOrganisationTypeFilters, DeviceOrganisationFilters, FolderFilters, GroupFilters, LocationFilters, ModelFilters, UserOrganisationFilters } from "@dative-gpi/foundation-core-domain/models";
67
+ import type { DashboardOrganisationFilters, DashboardOrganisationTypeFilters, DashboardShallowFilters, DeviceOrganisationFilters, FolderFilters, GroupFilters, LocationFilters, ModelFilters, UserOrganisationFilters } from "@dative-gpi/foundation-core-domain/models";
56
68
 
57
69
  import { TABLES as T } from "../../utils";
58
70
 
@@ -81,6 +93,11 @@ export default defineComponent({
81
93
  type: Number as PropType<EntityType>,
82
94
  required: true
83
95
  },
96
+ singleSelect: {
97
+ type: Boolean,
98
+ required: false,
99
+ default: false
100
+ },
84
101
  modelValue: {
85
102
  type: Array as PropType<string[]>,
86
103
  required: false,
@@ -90,9 +107,14 @@ export default defineComponent({
90
107
  type: Object,
91
108
  required: false,
92
109
  default: null
110
+ },
111
+ showRemove: {
112
+ type: Boolean,
113
+ required: false,
114
+ default: false
93
115
  }
94
116
  },
95
- setup(props, { attrs }){
117
+ setup(props, { emit, attrs }){
96
118
  const simpleListFilters = computed(() => {
97
119
  switch(props.entityType) {
98
120
  case EntityType.Device:
@@ -102,8 +124,9 @@ export default defineComponent({
102
124
  case EntityType.Dashboard:
103
125
  return {
104
126
  dashboardOrganisationsIds: props.modelValue,
105
- dashboardOrganisationTypesIds: props.modelValue
106
- } satisfies DashboardOrganisationFilters & DashboardOrganisationTypeFilters;
127
+ dashboardOrganisationTypesIds: props.modelValue,
128
+ dashboardShallowsIds: props.modelValue
129
+ } satisfies DashboardOrganisationFilters & DashboardOrganisationTypeFilters & DashboardShallowFilters;
107
130
  case EntityType.Group:
108
131
  return {
109
132
  groupsIds: props.modelValue
@@ -182,10 +205,20 @@ export default defineComponent({
182
205
  };
183
206
  });
184
207
 
208
+ const onRemove = (id: string) => {
209
+ emit("update:modelValue", props.modelValue.filter((i) => i !== id));
210
+ }
211
+
212
+ const getNameSlot = (name: string | number) => {
213
+ return name.toString().replace("base-list-", "");
214
+ }
215
+
185
216
  return {
186
217
  simpleListFilters,
187
218
  baseTableAttrs,
188
- tableCode
219
+ tableCode,
220
+ onRemove,
221
+ getNameSlot
189
222
  }
190
223
  }
191
224
  });
@@ -0,0 +1,322 @@
1
+ <template>
2
+ <FSDataTable
3
+ defaultMode="iterator"
4
+ :loading="fetchingDeviceExplorerElements"
5
+ :singleSelect="$props.singleSelect"
6
+ :items="deviceExplorerElements"
7
+ :selectable="$props.selectable"
8
+ :tableCode="$props.tableCode"
9
+ :itemTo="$props.itemTo"
10
+ :noSearch="$props.recursiveSearch"
11
+ :modelValue="$props.modelValue"
12
+ @update:modelValue="onUpdate"
13
+ v-model:search="search"
14
+ v-bind="$attrs"
15
+ >
16
+ <template
17
+ v-for="(_, name) in $slots"
18
+ v-slot:[name]="slotData"
19
+ >
20
+ <slot
21
+ :name="name"
22
+ v-bind="slotData"
23
+ />
24
+ </template>
25
+ <template
26
+ #header.imageId-title
27
+ >
28
+ <FSIcon>
29
+ mdi-panorama-variant-outline
30
+ </FSIcon>
31
+ </template>
32
+ <template
33
+ #header.connectivity-title
34
+ >
35
+ <FSIcon>
36
+ mdi-wifi
37
+ </FSIcon>
38
+ </template>
39
+ <template
40
+ #item.imageId="{ item }"
41
+ >
42
+ <FSImage
43
+ v-if="item.imageId"
44
+ height="32px"
45
+ width="32px"
46
+ :imageId="item.imageId"
47
+ :thumbnail="true"
48
+ />
49
+ </template>
50
+ <template
51
+ #item.tags="{ item }"
52
+ >
53
+ <FSTagGroup
54
+ variant="slide"
55
+ :showRemove="false"
56
+ :tags="item.tags"
57
+ />
58
+ </template>
59
+ <template
60
+ #item.type="{ item }"
61
+ >
62
+ <FSIcon
63
+ v-if="item.type === DeviceExplorerElementType.Group"
64
+ >
65
+ mdi-folder-outline
66
+ </FSIcon>
67
+ <FSIcon
68
+ v-else
69
+ >
70
+ mdi-widgets-outline
71
+ </FSIcon>
72
+ </template>
73
+
74
+ <template
75
+ #item.icon="{ item }"
76
+ >
77
+ <FSIcon
78
+ v-if="item.type === DeviceExplorerElementType.Group"
79
+ >
80
+ {{ item.icon }}
81
+ </FSIcon>
82
+ </template>
83
+ <template
84
+ #item.connectivity="{ item }"
85
+ >
86
+ <FSCol
87
+ v-if="item.type === DeviceExplorerElementType.DeviceOrganisation"
88
+ >
89
+ <FSConnectivity
90
+ v-if="item.connectivity.status != ConnectivityStatus.None"
91
+ :deviceConnectivity="item.connectivity"
92
+ />
93
+ </FSCol>
94
+ </template>
95
+ <template
96
+ #item.worstAlert="{ item }"
97
+ >
98
+ <FSWorstAlert
99
+ v-if="item.worstAlert"
100
+ :deviceWorstAlert="item.worstAlert"
101
+ :deviceAlerts="item.alerts"
102
+ :alertTo="$props.alertTo"
103
+ />
104
+ <div
105
+ v-else
106
+ />
107
+ </template>
108
+ <template
109
+ #item.alerts="{ item }"
110
+ >
111
+ <FSWorstAlert
112
+ v-if="item.worstAlert"
113
+ :deviceWorstAlert="item.worstAlert"
114
+ :deviceAlerts="item.alerts"
115
+ :alertTo="$props.alertTo"
116
+ />
117
+ <div
118
+ v-else
119
+ />
120
+ </template>
121
+ <template
122
+ #item.status="{ item }"
123
+ >
124
+ <FSStatusesCarousel
125
+ v-if="item.type === DeviceExplorerElementType.DeviceOrganisation"
126
+ :modelStatuses="item.modelStatuses"
127
+ :deviceStatuses="item.status.statuses"
128
+ />
129
+ </template>
130
+
131
+ <template
132
+ #item.tile="{ index, item, toggleSelect }"
133
+ >
134
+ <FSGroupTileUI
135
+ v-if="item.type === DeviceExplorerElementType.Group"
136
+ :key="index"
137
+ :to="$props.itemTo && $props.itemTo(item)"
138
+ :imageId="item.imageId"
139
+ :icon="item.icon"
140
+ :label="item.label"
141
+ :code="item.code"
142
+ :recursiveGroupsIds="item.recursiveGroupsIds"
143
+ :recursiveDeviceOrganisationsIds="item.recursiveDeviceOrganisationsIds"
144
+ :modelValue="isSelected(item.id)"
145
+ :selectable="$props.selectable"
146
+ @update:modelValue="toggleSelect(item)"
147
+ />
148
+ <FSDeviceOrganisationTileUI
149
+ v-if="item.type === DeviceExplorerElementType.DeviceOrganisation"
150
+ :key="index"
151
+ :to="$props.itemTo && $props.itemTo(item)"
152
+ :deviceConnectivity="item.connectivity"
153
+ :deviceStatuses="item.status.statuses"
154
+ :deviceWorstAlert="item.worstAlert"
155
+ :deviceAlerts="item.alerts"
156
+ :imageId="item.imageId"
157
+ :label="item.label"
158
+ :code="item.code"
159
+ :modelStatuses="item.modelStatuses"
160
+ :alertTo="$props.alertTo"
161
+ :modelValue="isSelected(item.id)"
162
+ :selectable="$props.selectable"
163
+ @update:modelValue="toggleSelect(item)"
164
+ />
165
+ </template>
166
+ </FSDataTable>
167
+ </template>
168
+
169
+ <script lang="ts">
170
+ import { computed, defineComponent, type PropType, ref, watch } from "vue";
171
+ import { type RouteLocation } from "vue-router";
172
+ import _ from "lodash";
173
+
174
+ import { ConnectivityStatus, DeviceExplorerElementType } from "@dative-gpi/foundation-shared-domain/enums";
175
+ import { useDeviceExplorerElements } from "@dative-gpi/foundation-core-services/composables";
176
+ import { type DeviceExplorerElementInfos} from "@dative-gpi/foundation-core-domain/models";
177
+ import { useDebounce } from "@dative-gpi/foundation-shared-components/composables";
178
+
179
+ import FSDeviceOrganisationTileUI from "@dative-gpi/foundation-shared-components/components/tiles/FSDeviceOrganisationTileUI.vue";
180
+ import FSStatusesCarousel from "@dative-gpi/foundation-shared-components/components/deviceOrganisations/FSStatusesCarousel.vue";
181
+ import FSConnectivity from "@dative-gpi/foundation-shared-components/components/deviceOrganisations/FSConnectivity.vue";
182
+ import FSWorstAlert from "@dative-gpi/foundation-shared-components/components/deviceOrganisations/FSWorstAlert.vue";
183
+ import FSGroupTileUI from "@dative-gpi/foundation-shared-components/components/tiles/FSGroupTileUI.vue";
184
+ import FSTagGroup from "@dative-gpi/foundation-shared-components/components/FSTagGroup.vue";
185
+ import FSImage from "@dative-gpi/foundation-shared-components/components/FSImage.vue";
186
+
187
+ import FSDataTable from "../lists/FSDataTable.vue";
188
+
189
+ export default defineComponent({
190
+ name: "FSBaseDevicesExplorer",
191
+ components: {
192
+ FSDeviceOrganisationTileUI,
193
+ FSStatusesCarousel,
194
+ FSConnectivity,
195
+ FSGroupTileUI,
196
+ FSWorstAlert,
197
+ FSDataTable,
198
+ FSTagGroup,
199
+ FSImage
200
+ },
201
+ props: {
202
+ tableCode: {
203
+ type: String as PropType<string | null>,
204
+ required: false,
205
+ default: null
206
+ },
207
+ recursiveSearch: {
208
+ type: Boolean,
209
+ required: false,
210
+ default: true
211
+ },
212
+ parentId: {
213
+ type: String as PropType<string | null>,
214
+ required: false,
215
+ default: null
216
+ },
217
+ root: {
218
+ type: Boolean,
219
+ required: false,
220
+ default: true
221
+ },
222
+ connectedOnly: {
223
+ type: Boolean,
224
+ required: false,
225
+ default: false
226
+ },
227
+ itemTo: {
228
+ type: Function as PropType<(item: DeviceExplorerElementInfos) => Partial<RouteLocation>>,
229
+ required: false
230
+ },
231
+ alertTo: {
232
+ type: Function,
233
+ required: false,
234
+ default: null
235
+ },
236
+ selectable: {
237
+ type: Boolean,
238
+ required: false,
239
+ default: true
240
+ },
241
+ singleSelect: {
242
+ type: Boolean,
243
+ required: false,
244
+ default: false
245
+ },
246
+ modelValue: {
247
+ type: Array as PropType<string[]>,
248
+ default: () => [],
249
+ required: false
250
+ }
251
+ },
252
+ emits: ["update:modelValue", "update:types"],
253
+ setup(props, { emit }) {
254
+ const { entities, fetching: fetchingDeviceExplorerElements, getMany: getManyDeviceExplorerElements } = useDeviceExplorerElements();
255
+ const { debounce } = useDebounce();
256
+
257
+ const search = ref("");
258
+
259
+ const deviceExplorerElements = computed((): DeviceExplorerElementInfos[] => {
260
+ let elements = entities.value.slice();
261
+ if (props.connectedOnly) {
262
+ elements = elements.filter(dee =>
263
+ dee.type === DeviceExplorerElementType.Group ||
264
+ (dee.connectivity != null && dee.connectivity.status != ConnectivityStatus.None)
265
+ );
266
+ }
267
+ return elements.sort((a, b) => a.type - b.type);
268
+ });
269
+
270
+ const isSelected = (id: string): boolean => {
271
+ return props.modelValue.includes(id);
272
+ };
273
+
274
+ const onUpdate = (value: string[]): void => {
275
+ const types = value.map(id => entities.value.find(dee => dee.id === id)?.type);
276
+ emit("update:types", types);
277
+
278
+ emit("update:modelValue", value);
279
+ }
280
+
281
+ const fetch = () => {
282
+ if (props.recursiveSearch && search.value) {
283
+ getManyDeviceExplorerElements({
284
+ ancestorId: props.parentId,
285
+ search: search.value
286
+ });
287
+ }
288
+ else {
289
+ getManyDeviceExplorerElements({
290
+ parentId: props.parentId,
291
+ root: props.root
292
+ });
293
+ }
294
+ }
295
+
296
+ // Delay to wait before fetching after a search change
297
+ const debounceFetch = (): void => debounce(fetch, 1000);
298
+
299
+ watch([() => props.parentId, () => props.root], (next, previous) => {
300
+ if ((!next && !previous) || !_.isEqual(next, previous)) {
301
+ fetch();
302
+ }
303
+ }, { immediate: true });
304
+
305
+ watch(search, (next, previous) => {
306
+ if (props.recursiveSearch && next !== previous) {
307
+ debounceFetch();
308
+ }
309
+ });
310
+
311
+ return {
312
+ fetchingDeviceExplorerElements,
313
+ DeviceExplorerElementType,
314
+ deviceExplorerElements,
315
+ ConnectivityStatus,
316
+ search,
317
+ isSelected,
318
+ onUpdate
319
+ };
320
+ }
321
+ });
322
+ </script>