|
16 | 16 | <v-expansion-panels multiple v-model="panels"> |
17 | 17 | <v-expansion-panel title="Sites"> |
18 | 18 | <v-expansion-panel-text> |
| 19 | + <v-text-field |
| 20 | + v-model="searchThing" |
| 21 | + prepend-inner-icon="mdi-magnify" |
| 22 | + label="Search" |
| 23 | + dense |
| 24 | + hide-details |
| 25 | + /> |
| 26 | + |
19 | 27 | <v-virtual-scroll |
20 | 28 | :items="sortedThings" |
21 | 29 | :height="sortedThings.length < 6 ? sortedThings.length * 40 : 250" |
|
34 | 42 | </v-expansion-panel-text> |
35 | 43 | </v-expansion-panel> |
36 | 44 |
|
37 | | - <v-expansion-panel title="Time"> |
| 45 | + <v-expansion-panel title="Observed Properties"> |
38 | 46 | <v-expansion-panel-text> |
39 | | - <div class="d-flex justify-center mb-3"> |
40 | | - <v-btn |
41 | | - v-for="option in dateOptions" |
42 | | - :key="option.id" |
43 | | - :color=" |
44 | | - selectedDateBtnId === option.id ? 'blue' : 'blue-grey-lighten-4' |
45 | | - " |
46 | | - @click="setDateRange(option.id)" |
47 | | - > |
48 | | - {{ option.label }} |
49 | | - </v-btn> |
50 | | - </div> |
51 | | - |
52 | | - <DatePickerField |
53 | | - :model-value="beginDate" |
54 | | - placeholder="Begin Date" |
55 | | - @update:model-value="handleCustomDateSelection('begin', $event)" |
| 47 | + <v-text-field |
| 48 | + v-model="searchObservedProperty" |
| 49 | + prepend-inner-icon="mdi-magnify" |
| 50 | + label="Search" |
| 51 | + dense |
| 52 | + hide-details |
56 | 53 | /> |
57 | | - <DatePickerField |
58 | | - :model-value="endDate" |
59 | | - placeholder="End Date" |
60 | | - @update:model-value="handleCustomDateSelection('end', $event)" |
61 | | - /> |
62 | | - </v-expansion-panel-text> |
63 | | - </v-expansion-panel> |
64 | 54 |
|
65 | | - <v-expansion-panel title="Observed Properties"> |
66 | | - <v-expansion-panel-text> |
67 | 55 | <v-virtual-scroll |
68 | 56 | :items="sortedObservedPropertyNames" |
69 | 57 | :height=" |
|
87 | 75 |
|
88 | 76 | <v-expansion-panel title="Processing Levels"> |
89 | 77 | <v-expansion-panel-text> |
| 78 | + <v-text-field |
| 79 | + v-model="searchProcessingLevel" |
| 80 | + prepend-inner-icon="mdi-magnify" |
| 81 | + label="Search" |
| 82 | + dense |
| 83 | + hide-details |
| 84 | + /> |
| 85 | + |
90 | 86 | <v-virtual-scroll |
91 | 87 | :items="sortedProcessingLevelNames" |
92 | 88 | :height=" |
|
118 | 114 | <script setup lang="ts"> |
119 | 115 | import { computed, ref } from 'vue' |
120 | 116 | import { useDisplay } from 'vuetify/lib/framework.mjs' |
121 | | -import DatePickerField from '@/components/TimeSeriesAnalyst/DatePickerField.vue' |
122 | 117 | import { useTSAStore } from '@/store/timeSeriesAnalyst' |
123 | 118 | import { storeToRefs } from 'pinia' |
124 | 119 |
|
125 | | -const { clearFilters, setDateRange } = useTSAStore() |
| 120 | +const { |
| 121 | + matchesSelectedObservedProperty, |
| 122 | + matchesSelectedProcessingLevel, |
| 123 | + matchesSelectedThing, |
| 124 | +} = useTSAStore() |
126 | 125 | const { |
127 | 126 | things, |
| 127 | + datastreams, |
128 | 128 | processingLevels, |
129 | 129 | observedProperties, |
130 | 130 | selectedThings, |
131 | 131 | selectedObservedPropertyNames, |
132 | 132 | selectedProcessingLevelNames, |
133 | | - beginDate, |
134 | | - endDate, |
135 | | - dateOptions, |
136 | | - selectedDateBtnId, |
137 | 133 | } = storeToRefs(useTSAStore()) |
138 | 134 |
|
| 135 | +const searchThing = ref('') |
| 136 | +const searchObservedProperty = ref('') |
| 137 | +const searchProcessingLevel = ref('') |
| 138 | +
|
| 139 | +// Only show list items that are referenced by at least one datastream |
| 140 | +// Then mutually filter the lists by selected filters. |
139 | 141 | const sortedProcessingLevelNames = computed(() => { |
140 | | - const names = processingLevels.value.map((pl) => pl.definition) |
| 142 | + const filteredPLs = processingLevels.value.filter( |
| 143 | + (pl) => |
| 144 | + pl.definition |
| 145 | + .toLowerCase() |
| 146 | + .includes(searchProcessingLevel.value.toLowerCase()) && |
| 147 | + datastreams.value.some( |
| 148 | + (ds) => |
| 149 | + ds.processingLevelId === pl.id && |
| 150 | + matchesSelectedThing(ds) && |
| 151 | + matchesSelectedObservedProperty(ds) |
| 152 | + ) |
| 153 | + ) |
| 154 | + const names = filteredPLs.map((pl) => pl.definition) |
141 | 155 | return [...new Set(names)].sort() |
142 | 156 | }) |
143 | 157 |
|
144 | 158 | const sortedThings = computed(() => { |
145 | | - return things.value.slice().sort((a, b) => { |
146 | | - return a.name.localeCompare(b.name) |
147 | | - }) |
| 159 | + return things.value |
| 160 | + .filter( |
| 161 | + (thing) => |
| 162 | + thing.name.toLowerCase().includes(searchThing.value.toLowerCase()) && |
| 163 | + datastreams.value.some( |
| 164 | + (ds) => |
| 165 | + ds.thingId === thing.id && |
| 166 | + matchesSelectedObservedProperty(ds) && |
| 167 | + matchesSelectedProcessingLevel(ds) |
| 168 | + ) |
| 169 | + ) |
| 170 | + .sort((a, b) => a.name.localeCompare(b.name)) |
148 | 171 | }) |
149 | 172 |
|
150 | 173 | const sortedObservedPropertyNames = computed(() => { |
151 | | - const names = observedProperties.value.map((pl) => pl.name) |
| 174 | + const filteredProperties = observedProperties.value.filter( |
| 175 | + (op) => |
| 176 | + op.name |
| 177 | + .toLowerCase() |
| 178 | + .includes(searchObservedProperty.value.toLowerCase()) && |
| 179 | + datastreams.value.some( |
| 180 | + (ds) => |
| 181 | + ds.observedPropertyId === op.id && |
| 182 | + matchesSelectedThing(ds) && |
| 183 | + matchesSelectedProcessingLevel(ds) |
| 184 | + ) |
| 185 | + ) |
| 186 | +
|
| 187 | + const names = filteredProperties.map((pl) => pl.name) |
152 | 188 | return [...new Set(names)].sort() |
153 | 189 | }) |
154 | 190 |
|
| 191 | +const clearFilters = () => { |
| 192 | + selectedThings.value = [] |
| 193 | + selectedObservedPropertyNames.value = [] |
| 194 | + selectedProcessingLevelNames.value = [] |
| 195 | +
|
| 196 | + searchThing.value = '' |
| 197 | + searchObservedProperty.value = '' |
| 198 | + searchProcessingLevel.value = '' |
| 199 | +} |
| 200 | +
|
155 | 201 | const { smAndDown } = useDisplay() |
156 | 202 | const panels = ref([0, 1, 2, 3]) |
157 | 203 | const drawer = ref(!!smAndDown) |
158 | | -
|
159 | | -const handleCustomDateSelection = (type: 'begin' | 'end', date: Date) => { |
160 | | - if (type === 'begin') beginDate.value = date |
161 | | - else endDate.value = date |
162 | | - selectedDateBtnId.value = -1 |
163 | | -} |
164 | 204 | </script> |
0 commit comments