@@ -9,11 +9,13 @@ import { getFolder } from 'platform/web-girder/api';
99import { useStore } from ' platform/web-girder/store/types' ;
1010import { useHandler } from ' vue-media-annotator/provides' ;
1111import DIVEMetadataEditKey from ' platform/web-girder/views/DIVEMetadata/DIVEMetadataEditKey.vue' ;
12+ import MetadataKeyLabel from ' platform/web-girder/views/DIVEMetadata/MetadataKeyLabel.vue' ;
1213import {
1314 FilterDisplayConfig ,
1415 filterDiveMetadata ,
1516 getMetadataFilterValues ,
1617 MetadataFilterKeysItem ,
18+ partitionMetadataKeys ,
1719 setDiveDatasetMetadataKey ,
1820} from ' platform/web-girder/api/divemetadata.service' ;
1921import { usePrompt } from ' dive-common/vue-utilities/prompt-service' ;
@@ -23,6 +25,7 @@ export default defineComponent({
2325 components: {
2426 StackedVirtualSidebarContainer ,
2527 DIVEMetadataEditKey ,
28+ MetadataKeyLabel ,
2629 },
2730
2831 props: {
@@ -45,6 +48,7 @@ export default defineComponent({
4548 display: [], hide: [], categoricalLimit: 50 , slicerCLI: ' Disabled' ,
4649 });
4750 const unlockedMap: Ref <Record <string , MetadataFilterKeysItem >> = ref ({});
51+ const metadataKeysByName: Ref <Record <string , MetadataFilterKeysItem >> = ref ({});
4852 const getMetadata = async () => {
4953 if (store .state .Dataset .meta ) {
5054 const resp = await getFolder (store .state .Dataset .meta ?.id );
@@ -74,6 +78,7 @@ export default defineComponent({
7478 },
7579 );
7680 const filterData = await getMetadataFilterValues (diveMetadataRootId .value );
81+ metadataKeysByName .value = filterData .data .metadataKeys || {};
7782 const { unlocked } = filterData .data ;
7883 unlockedMap .value = {};
7984 if (unlocked ) {
@@ -89,17 +94,52 @@ export default defineComponent({
8994
9095 const processedDatasetMetadata = computed (() => {
9196 if (! datasetMetadata .value || ! diveMetadataFilter .value ) return null ;
92- // eslint-disable-next-line @typescript-eslint/no-explicit-any
93- const display: { default: Record <string , any >, advanced: Record <string , any >} = { default: {}, advanced: {} };
94- display .default .FileName = datasetMetadata .value .filename || ' N/A' ;
95- Object .keys (datasetMetadata .value .metadata ).forEach ((field ) => {
96- if (datasetMetadata .value === null ) return ;
97- if (diveMetadataFilter .value .display .includes (field )) {
98- display .default [field ] = datasetMetadata .value .metadata [field ];
99- } else if (! diveMetadataFilter .value .hide .includes (field )) {
100- display .advanced [field ] = datasetMetadata .value .metadata [field ];
101- }
102- });
97+ type MetadataField = { name: string ; value: unknown };
98+ type MetadataGroup = { id: string ; name: string ; description? : string ; items: MetadataField [] };
99+ const display: {
100+ default: MetadataField [];
101+ defaultGroups: MetadataGroup [];
102+ advanced: MetadataField [];
103+ advancedGroups: MetadataGroup [];
104+ } = {
105+ default: [{ name: ' FileName' , value: datasetMetadata .value .filename || ' N/A' }],
106+ defaultGroups: [],
107+ advanced: [],
108+ advancedGroups: [],
109+ };
110+ const allKeys = Object .keys (datasetMetadata .value .metadata );
111+ const defaultKeys = allKeys .filter ((field ) => diveMetadataFilter .value .display .includes (field ));
112+ const advancedKeys = allKeys .filter ((field ) => ! diveMetadataFilter .value .display .includes (field ) && ! diveMetadataFilter .value .hide .includes (field ));
113+
114+ const defaultPartition = partitionMetadataKeys (defaultKeys , diveMetadataFilter .value );
115+ display .default .push (... defaultPartition .ungrouped .map ((name ) => ({
116+ name ,
117+ value: datasetMetadata .value ?.metadata [name ],
118+ })));
119+ display .defaultGroups = defaultPartition .groups .map ((group ) => ({
120+ id: group .id ,
121+ name: group .name ,
122+ description: group .description ,
123+ items: group .keys .map ((name ) => ({
124+ name ,
125+ value: datasetMetadata .value ?.metadata [name ],
126+ })),
127+ }));
128+
129+ const advancedPartition = partitionMetadataKeys (advancedKeys , diveMetadataFilter .value );
130+ display .advanced = advancedPartition .ungrouped .map ((name ) => ({
131+ name ,
132+ value: datasetMetadata .value ?.metadata [name ],
133+ }));
134+ display .advancedGroups = advancedPartition .groups .map ((group ) => ({
135+ id: group .id ,
136+ name: group .name ,
137+ description: group .description ,
138+ items: group .keys .map ((name ) => ({
139+ name ,
140+ value: datasetMetadata .value ?.metadata [name ],
141+ })),
142+ }));
103143 return display ;
104144 });
105145 const datasetInfoLength = computed (() => Object .keys (datasetInfo .value || []).length );
@@ -119,6 +159,16 @@ export default defineComponent({
119159 });
120160 }
121161 };
162+ const getEditableValue = (value : unknown ): string | number | boolean | null => {
163+ if (typeof value === ' string' || typeof value === ' number' || typeof value === ' boolean' ) {
164+ return value ;
165+ }
166+ return null ;
167+ };
168+ const getEditableSetValues = (key : string ): string [] => {
169+ const values = unlockedMap .value [key ]?.set || [];
170+ return values .filter ((value ): value is string => typeof value === ' string' );
171+ };
122172
123173 return {
124174 datasetInfo ,
@@ -127,7 +177,10 @@ export default defineComponent({
127177 processedDatasetMetadata ,
128178 panels ,
129179 unlockedMap ,
180+ metadataKeysByName ,
130181 updateDiveMetadataKeyVal ,
182+ getEditableValue ,
183+ getEditableSetValues ,
131184 };
132185 },
133186});
@@ -172,52 +225,150 @@ export default defineComponent({
172225 <v-expansion-panel v-if =" processedDatasetMetadata" class =" border" >
173226 <v-expansion-panel-header >DIVE Metadata</v-expansion-panel-header >
174227 <v-expansion-panel-content class =" pa-0" >
175- <v-list-item v-for =" (value, name) in processedDatasetMetadata.default" :key =" `datasetMetadata_${name}`" two-line dense >
228+ <v-list-item v-for =" item in processedDatasetMetadata.default" :key =" `datasetMetadata_${item. name}`" two-line dense >
176229 <v-list-item-content >
177230 <v-list-item-title >
178- {{ name }}
231+ <MetadataKeyLabel
232+ :key-name =" item.name"
233+ :description =" metadataKeysByName[item.name] ? metadataKeysByName[item.name].description : undefined"
234+ />
179235 </v-list-item-title >
180236 <v-list-item-subtitle class =" wrap-text" >
181- <span v-if =" unlockedMap[name] !== undefined" >
237+ <span v-if =" unlockedMap[item. name] !== undefined" >
182238 <DIVEMetadataEditKey
183- :category =" unlockedMap[name].category"
184- :value =" value"
185- :set-values =" unlockedMap[name].set || [] "
239+ :category =" unlockedMap[item. name].category"
240+ :value =" getEditableValue(item. value) "
241+ :set-values =" getEditableSetValues(item.name) "
186242 class =" pl-2"
187- @update =" updateDiveMetadataKeyVal(name, $event)"
243+ @update =" updateDiveMetadataKeyVal(item. name, $event)"
188244 />
189245 </span >
190246 <span v-else >
191- {{ value !== undefined ? value.toString() : '' }}
247+ {{ item. value !== undefined ? item. value.toString() : '' }}
192248 </span >
193249 </v-list-item-subtitle >
194250 </v-list-item-content >
195251 </v-list-item >
252+ <v-expansion-panels >
253+ <v-expansion-panel
254+ v-for =" group in processedDatasetMetadata.defaultGroups"
255+ :key =" `datasetMetadata_default_group_${group.id}`"
256+ >
257+ <v-expansion-panel-header >
258+ <span class =" d-inline-flex align-center" >
259+ {{ group.name }}
260+ <v-tooltip v-if =" group.description" bottom max-width =" 320" open-delay =" 200" >
261+ <template #activator =" { on } " >
262+ <v-icon small class =" ml-1" color =" grey lighten-1" v-on =" on" >
263+ mdi-information
264+ </v-icon >
265+ </template >
266+ <span >{{ group.description }}</span >
267+ </v-tooltip >
268+ </span >
269+ </v-expansion-panel-header >
270+ <v-expansion-panel-content class =" pa-0" >
271+ <v-list-item v-for =" item in group.items" :key =" `datasetMetadata_${group.id}_${item.name}`" two-line dense >
272+ <v-list-item-content >
273+ <v-list-item-title >
274+ <MetadataKeyLabel
275+ :key-name =" item.name"
276+ :description =" metadataKeysByName[item.name] ? metadataKeysByName[item.name].description : undefined"
277+ />
278+ </v-list-item-title >
279+ <v-list-item-subtitle class =" wrap-text" >
280+ <span v-if =" unlockedMap[item.name] !== undefined" >
281+ <DIVEMetadataEditKey
282+ :category =" unlockedMap[item.name].category"
283+ :value =" getEditableValue(item.value)"
284+ :set-values =" getEditableSetValues(item.name)"
285+ class =" pl-2"
286+ @update =" updateDiveMetadataKeyVal(item.name, $event)"
287+ />
288+ </span >
289+ <span v-else >
290+ {{ item.value !== undefined ? item.value.toString() : '' }}
291+ </span >
292+ </v-list-item-subtitle >
293+ </v-list-item-content >
294+ </v-list-item >
295+ </v-expansion-panel-content >
296+ </v-expansion-panel >
297+ </v-expansion-panels >
196298 <v-expansion-panels >
197299 <v-expansion-panel >
198300 <v-expansion-panel-header >Advanced</v-expansion-panel-header >
199301 <v-expansion-panel-content class =" pa-0" >
200- <v-list-item v-for =" (value, name) in processedDatasetMetadata.advanced" :key =" `datasetMetadata_${name}`" two-line dense >
302+ <v-list-item v-for =" item in processedDatasetMetadata.advanced" :key =" `datasetMetadata_${item. name}`" two-line dense >
201303 <v-list-item-content >
202304 <v-list-item-title >
203- {{ name }}
305+ <MetadataKeyLabel
306+ :key-name =" item.name"
307+ :description =" metadataKeysByName[item.name] ? metadataKeysByName[item.name].description : undefined"
308+ />
204309 </v-list-item-title >
205310 <v-list-item-subtitle class =" wrap-text" >
206- <span v-if =" unlockedMap[name] !== undefined" >
311+ <span v-if =" unlockedMap[item. name] !== undefined" >
207312 <DIVEMetadataEditKey
208- :category =" unlockedMap[name].category"
209- :value =" value"
210- :set-values =" unlockedMap[name].set || [] "
313+ :category =" unlockedMap[item. name].category"
314+ :value =" getEditableValue(item. value) "
315+ :set-values =" getEditableSetValues(item.name) "
211316 class =" pl-2"
212- @update =" updateDiveMetadataKeyVal(name, $event)"
317+ @update =" updateDiveMetadataKeyVal(item. name, $event)"
213318 />
214319 </span >
215320 <span v-else >
216- {{ value !== undefined ? value.toString() : '' }}
321+ {{ item. value !== undefined ? item. value.toString() : '' }}
217322 </span >
218323 </v-list-item-subtitle >
219324 </v-list-item-content >
220325 </v-list-item >
326+ <v-expansion-panels >
327+ <v-expansion-panel
328+ v-for =" group in processedDatasetMetadata.advancedGroups"
329+ :key =" `datasetMetadata_advanced_group_${group.id}`"
330+ >
331+ <v-expansion-panel-header >
332+ <span class =" d-inline-flex align-center" >
333+ {{ group.name }}
334+ <v-tooltip v-if =" group.description" bottom max-width =" 320" open-delay =" 200" >
335+ <template #activator =" { on } " >
336+ <v-icon small class =" ml-1" color =" grey lighten-1" v-on =" on" >
337+ mdi-information
338+ </v-icon >
339+ </template >
340+ <span >{{ group.description }}</span >
341+ </v-tooltip >
342+ </span >
343+ </v-expansion-panel-header >
344+ <v-expansion-panel-content class =" pa-0" >
345+ <v-list-item v-for =" item in group.items" :key =" `datasetMetadata_${group.id}_${item.name}`" two-line dense >
346+ <v-list-item-content >
347+ <v-list-item-title >
348+ <MetadataKeyLabel
349+ :key-name =" item.name"
350+ :description =" metadataKeysByName[item.name] ? metadataKeysByName[item.name].description : undefined"
351+ />
352+ </v-list-item-title >
353+ <v-list-item-subtitle class =" wrap-text" >
354+ <span v-if =" unlockedMap[item.name] !== undefined" >
355+ <DIVEMetadataEditKey
356+ :category =" unlockedMap[item.name].category"
357+ :value =" getEditableValue(item.value)"
358+ :set-values =" getEditableSetValues(item.name)"
359+ class =" pl-2"
360+ @update =" updateDiveMetadataKeyVal(item.name, $event)"
361+ />
362+ </span >
363+ <span v-else >
364+ {{ item.value !== undefined ? item.value.toString() : '' }}
365+ </span >
366+ </v-list-item-subtitle >
367+ </v-list-item-content >
368+ </v-list-item >
369+ </v-expansion-panel-content >
370+ </v-expansion-panel >
371+ </v-expansion-panels >
221372 </v-expansion-panel-content >
222373 </v-expansion-panel >
223374 </v-expansion-panels >
0 commit comments