diff --git a/gui/src/components/archive/metainfo.js b/gui/src/components/archive/metainfo.js index caffac3ed98ae12bfe97625789196ae6ce83da57..dec6f815a0ba48c0102a5d5f0bcb5c064f1e9fbb 100644 --- a/gui/src/components/archive/metainfo.js +++ b/gui/src/components/archive/metainfo.js @@ -826,9 +826,14 @@ export function getMetainfoFromDefinition(definition) { * @param {str} path The archive path to the section * @param {function} callback The callback that is called on each section */ -export function traverse(section, definition, path, callback) { +export async function traverse(section, definition, path, callback) { callback(section, definition, path) + + // Loop through all subsection definitions for (const subSectionDef of definition._allProperties.filter(prop => prop.m_def === SubSectionMDef)) { + let sectionDef = subSectionDef.sub_section + + // Find all subsection instances let subSections = [] if (!subSectionDef.repeats) { const subSection = section[subSectionDef.name] @@ -839,13 +844,25 @@ export function traverse(section, definition, path, callback) { subSections = section[subSectionDef.name] || [] } - subSections.forEach((subSection, index) => { + // For each found instance, check for m_def definition override in the data + // and trigger the recursion. + let index = 0 + for (const subSection of subSections) { let childPath = `${path}/${subSectionDef.name}` if (subSectionDef.repeats) { childPath = `${childPath}/${index}` } - traverse(subSection, subSectionDef.sub_section, childPath, callback) - }) + // Here the final definition is resolved based on the presence of an + // m_def. TODO: m_defs that point to a definition that is not within the + // same metainfo that the original definition came from are not here + // properly resolved. + if (subSection.m_def && !subSection.m_def.startsWith('../upload/')) { + const metainfo = getMetainfoFromDefinition(definition) + sectionDef = await metainfo.resolveDefinition(subSection.m_def) + } + await traverse(subSection, sectionDef, childPath, callback) + ++index + } } } diff --git a/gui/src/components/entry/OverviewView.js b/gui/src/components/entry/OverviewView.js index 447db48239ab1d0511dd99cbdf0e789a5e0fb544..6e0232d8b3af2b044a24a248e7b4f1269e74db8e 100644 --- a/gui/src/components/entry/OverviewView.js +++ b/gui/src/components/entry/OverviewView.js @@ -169,7 +169,7 @@ const OverviewView = React.memo(() => { } const getSections = async () => { const sections = [] - traverse(archive.data, dataMetainfoDef, 'data', (section, sectionDef, path) => { + await traverse(archive.data, dataMetainfoDef, 'data', (section, sectionDef, path) => { if (path === 'data' || sectionDef.m_annotations?.eln?.[0]?.overview) { sections.push({ archivePath: path, diff --git a/gui/src/components/uploads/SectionSelectDialog.js b/gui/src/components/uploads/SectionSelectDialog.js index acefa519c6b983e0eda5410adce2ddfa6d1da009..16b17b6b2c7adb73ba6d9560b5495e4dda99719a 100644 --- a/gui/src/components/uploads/SectionSelectDialog.js +++ b/gui/src/components/uploads/SectionSelectDialog.js @@ -98,8 +98,8 @@ export async function getSectionsInfo(api, dataStore, reference, entry_id) { const url = dataArchive.metadata.upload_id ? `${apiBase}/uploads/${dataArchive.metadata.upload_id}/archive/${entry_id}` : undefined const dataMetainfoDefUrl = resolveNomadUrlNoThrow(m_def, url) const sectionDef = await dataStore.getMetainfoDefAsync(dataMetainfoDefUrl) - traverse(dataArchive[section], sectionDef, section, (section, sectionDef, path) => { - const ref = reference && [...reference][0] + const ref = reference && [...reference][0] + await traverse(dataArchive[section], sectionDef, section, (section, sectionDef, path) => { if (ref && (sectionDef._qualifiedName === ref || sectionDef._allBaseSections?.map(section => section._qualifiedName).includes(ref))) { const itemLabelKey = getItemLabelKey(sectionDef) @@ -109,8 +109,7 @@ export async function getSectionsInfo(api, dataStore, reference, entry_id) { }) } } - const references = referencedSubSections || [] - return references.map(reference => { + return (referencedSubSections || []).map(reference => { const fullPath = reference?.path && reference.path !== '/data' && reference.path !== 'data' ? `${dataArchive?.metadata?.mainfile}#${reference.path}` : dataArchive?.metadata?.mainfile return { label: reference.name ? `${reference.name} (./${reference?.path})` : `./${reference?.path}`,