Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
nomad-lab
nomad-FAIR
Commits
05d2f050
Commit
05d2f050
authored
Dec 17, 2021
by
Markus Scheidgen
Browse files
Various metainfo related fixes and imporvements.
parent
76ddd3ce
Pipeline
#120856
passed with stages
in 29 minutes and 13 seconds
Changes
6
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
gui/src/components/archive/Browser.js
View file @
05d2f050
...
...
@@ -71,7 +71,7 @@ const useBrowserStyles = makeStyles(theme => ({
width
:
'
fit-content
'
}
}))
export
default
function
Browser
({
adaptor
,
form
})
{
export
const
Browser
=
React
.
memo
(
function
Browser
({
adaptor
,
form
})
{
const
classes
=
useBrowserStyles
()
const
rootRef
=
useRef
()
const
outerRef
=
useRef
()
...
...
@@ -100,17 +100,24 @@ export default function Browser({adaptor, form}) {
next
:
null
}),
[
adaptor
,
url
])
const
lanes
=
[
root
]
archivePath
.
filter
(
segment
=>
segment
).
forEach
((
segment
,
i
)
=>
{
const
prev
=
lanes
[
i
]
const
lane
=
{
key
:
segment
,
path
:
`
${
prev
.
path
}
/
${
segment
}
`
,
adaptor
:
prev
.
adaptor
.
itemAdaptor
(
segment
)
}
lanes
.
push
(
lane
)
prev
.
next
=
lane
})
const
memoedAdapters
=
useRef
({})
const
lanes
=
useMemo
(()
=>
{
const
lanes
=
[
root
]
archivePath
.
filter
(
segment
=>
segment
).
forEach
((
segment
,
i
)
=>
{
const
prev
=
lanes
[
i
]
const
path
=
`
${
prev
.
path
}
/
${
segment
}
`
const
adaptor
=
memoedAdapters
.
current
[
path
]
||
prev
.
adaptor
.
itemAdaptor
(
segment
)
memoedAdapters
.
current
[
path
]
=
adaptor
const
lane
=
{
key
:
segment
,
path
:
path
,
adaptor
:
adaptor
}
lanes
.
push
(
lane
)
prev
.
next
=
lane
})
return
lanes
},
[
root
,
archivePath
,
memoedAdapters
])
return
<
RecoilRoot
>
{
form
}
...
...
@@ -128,11 +135,12 @@ export default function Browser({adaptor, form}) {
<
/CardContent
>
<
/Card
>
<
/RecoilRoot
>
}
}
)
Browser
.
propTypes
=
({
adaptor
:
PropTypes
.
object
.
isRequired
,
form
:
PropTypes
.
node
})
export
default
Browser
export
const
laneContext
=
React
.
createContext
()
const
useLaneStyles
=
makeStyles
(
theme
=>
({
...
...
@@ -151,20 +159,25 @@ const useLaneStyles = makeStyles(theme => ({
margin
:
theme
.
spacing
(
1
)
}
}))
function
Lane
({
lane
})
{
const
Lane
=
React
.
memo
(
function
Lane
({
lane
})
{
const
classes
=
useLaneStyles
()
const
{
adaptor
}
=
lane
return
<
div
className
=
{
classes
.
root
}
>
<
div
className
=
{
classes
.
container
}
>
<
laneContext
.
Provider
value
=
{
lane
}
>
<
ErrorHandler
message
=
'
This section could not be rendered, due to an unexpected error.
'
className
=
{
classes
.
error
}
>
{
adaptor
.
render
()}
<
/ErrorHandler
>
<
/laneContext.Provider
>
const
{
key
,
selected
,
adaptor
,
next
}
=
lane
const
content
=
useMemo
(()
=>
{
return
<
div
className
=
{
classes
.
root
}
>
<
div
className
=
{
classes
.
container
}
>
<
laneContext
.
Provider
value
=
{
lane
}
>
<
ErrorHandler
message
=
'
This section could not be rendered, due to an unexpected error.
'
className
=
{
classes
.
error
}
>
{
adaptor
.
render
()}
<
/ErrorHandler
>
<
/laneContext.Provider
>
<
/div
>
<
/div
>
<
/div
>
}
// We deliberetly break the React rules here. The goal is to only update if the
// lanes contents change and not the lane object.
// eslint-disable-next-line
},
[
key
,
selected
,
adaptor
,
next
?.
key
,
classes
])
return
content
})
Lane
.
propTypes
=
({
lane
:
PropTypes
.
object
.
isRequired
})
...
...
gui/src/components/archive/MetainfoBrowser.js
View file @
05d2f050
...
...
@@ -88,13 +88,14 @@ export function MetainfoPage() {
}
export
default
function
MetainfoBrowser
()
{
const
adaptor
=
useMemo
(()
=>
new
MetainfoRootAdaptor
(),
[])
return
<
Browser
adaptor
=
{
new
MetainfoRootA
daptor
()
}
adaptor
=
{
a
daptor
}
form
=
{
<
MetainfoConfigForm
/>
}
/
>
}
function
MetainfoConfigForm
(
props
)
{
const
MetainfoConfigForm
=
React
.
memo
(
function
MetainfoConfigForm
(
props
)
{
const
[
config
,
setConfig
]
=
useRecoilState
(
metainfoConfigState
)
const
history
=
useHistory
()
...
...
@@ -150,7 +151,7 @@ function MetainfoConfigForm(props) {
<
/FormGroup
>
<
/Box
>
)
}
}
)
export
function
metainfoAdaptorFactory
(
obj
)
{
if
(
obj
.
m_def
===
'
Section
'
)
{
...
...
@@ -250,7 +251,7 @@ export class PackagePrefixAdaptor extends MetainfoAdaptor {
}
}
function
Metainfo
(
props
)
{
const
Metainfo
=
React
.
memo
(
function
Metainfo
(
props
)
{
return
<
Content
>
<
Compartment
title
=
"
archive root section
"
>
<
Item
itemKey
=
"
EntryArchive
"
>
...
...
@@ -258,8 +259,8 @@ function Metainfo(props) {
<
/Item
>
<
/Compartment
>
<
Compartment
title
=
"
other root sections
"
>
{
rootSections
.
filter
(
def
=>
def
.
name
!==
'
EntryArchive
'
).
map
(
def
=>
(
<
Item
key
=
{
def
.
name
}
itemKey
=
{
def
.
name
}
>
{
rootSections
.
filter
(
def
=>
def
.
name
!==
'
EntryArchive
'
).
map
(
(
def
,
i
)
=>
(
<
Item
key
=
{
i
}
itemKey
=
{
def
.
name
}
>
<
Typography
>
{
def
.
name
}
<
/Typography
>
...
...
@@ -272,7 +273,7 @@ function Metainfo(props) {
<
/Item>
)
}
<
/Compartment
>
<
/Content
>
}
}
)
export
class
SectionDefAdaptor
extends
MetainfoAdaptor
{
itemAdaptor
(
key
)
{
...
...
gui/src/components/archive/metainfo.js
View file @
05d2f050
...
...
@@ -51,8 +51,7 @@ metainfo.packages.forEach(pkg => {
addDef
(
categoryDef
)
})
const
addSectionDef
=
(
sectionDef
,
parentDef
)
=>
{
pkg
.
_sections
[
sectionDef
.
name
]
=
sectionDef
const
initSection
=
sectionDef
=>
{
sectionDef
.
base_sections
=
sectionDef
.
base_sections
||
[]
sectionDef
.
quantities
=
sectionDef
.
quantities
||
[]
sectionDef
.
sub_sections
=
sectionDef
.
sub_sections
||
[]
...
...
@@ -60,6 +59,33 @@ metainfo.packages.forEach(pkg => {
sectionDef
.
_incomingRefs
=
sectionDef
.
_incomingRefs
||
[]
sectionDef
.
_parentSections
=
sectionDef
.
_parentSections
||
[]
sectionDef
.
_parentSubSections
=
sectionDef
.
_parentSubSections
||
[]
}
const
computeAllProperties
=
sectionDef
=>
{
const
results
=
{}
function
addProperties
(
sectionDef
)
{
sectionDef
.
quantities
.
concat
(
sectionDef
.
sub_sections
).
forEach
(
property
=>
{
results
[
property
.
name
]
=
property
})
}
const
baseSections
=
[]
function
addBaseSection
(
sectionDef
)
{
initSection
(
sectionDef
)
if
(
!
sectionDef
.
extends_base_section
)
{
sectionDef
.
base_sections
.
map
(
baseSectionRef
=>
resolveRef
(
baseSectionRef
)).
forEach
(
addBaseSection
)
}
baseSections
.
push
(
sectionDef
)
}
addBaseSection
(
sectionDef
)
baseSections
.
forEach
(
addProperties
)
return
Object
.
keys
(
results
).
sort
().
map
(
key
=>
results
[
key
])
}
const
addSectionDef
=
(
sectionDef
,
parentDef
)
=>
{
sectionDef
.
_parent
=
parentDef
pkg
.
_sections
[
sectionDef
.
name
]
=
sectionDef
initSection
(
sectionDef
)
sectionDef
.
_qualifiedName
=
parentDef
?
`
${
parentDef
.
_qualifiedName
||
parentDef
.
name
}
.
${
sectionDef
.
name
}
`
:
sectionDef
.
name
sectionDef
.
_package
=
pkg
...
...
@@ -88,7 +114,6 @@ metainfo.packages.forEach(pkg => {
property
.
_section
=
sectionDef
property
.
_qualifiedName
=
`
${
sectionDef
.
_qualifiedName
}
.
${
property
.
name
}
`
}
property
.
_parentSections
=
[
sectionDef
]
property
.
_package
=
pkg
addDef
(
property
)
}
...
...
@@ -102,10 +127,10 @@ metainfo.packages.forEach(pkg => {
referencedSection
.
_incomingRefs
.
push
(
property
)
}
}
else
if
(
property
.
m_def
===
'
SubSection
'
)
{
const
subSectionsSectionDef
=
resolveRef
(
property
.
sub_section
)
subSectionsSectionDef
.
_parentSections
=
subSectionsSectionDef
.
_parentSections
||
[]
property
.
_subSection
=
resolveRef
(
property
.
sub_section
)
const
subSectionsSectionDef
=
property
.
_subSection
initSection
(
subSectionsSectionDef
)
subSectionsSectionDef
.
_parentSections
.
push
(
sectionDef
)
subSectionsSectionDef
.
_parentSubSections
=
subSectionsSectionDef
.
_parentSubSections
||
[]
subSectionsSectionDef
.
_parentSubSections
.
push
(
property
)
property
.
_section
=
sectionDef
}
...
...
@@ -115,26 +140,6 @@ metainfo.packages.forEach(pkg => {
pkg
.
section_definitions
.
forEach
(
sectionDef
=>
addSectionDef
(
sectionDef
,
pkg
))
})
function
computeAllProperties
(
sectionDef
)
{
const
results
=
{}
function
addProperties
(
sectionDef
)
{
sectionDef
.
quantities
.
concat
(
sectionDef
.
sub_sections
).
forEach
(
property
=>
{
results
[
property
.
name
]
=
property
})
}
const
baseSections
=
[]
function
addBaseSection
(
sectionDef
)
{
if
(
!
sectionDef
.
extends_base_section
)
{
sectionDef
.
base_sections
.
map
(
baseSectionRef
=>
resolveRef
(
baseSectionRef
)).
forEach
(
addBaseSection
)
}
baseSections
.
push
(
sectionDef
)
}
addBaseSection
(
sectionDef
)
baseSections
.
forEach
(
addProperties
)
return
Object
.
keys
(
results
).
sort
().
map
(
key
=>
results
[
key
])
}
export
const
rootSections
=
sortDefs
(
defs
.
filter
(
def
=>
(
def
.
m_def
===
'
Section
'
&&
!
def
.
extends_base_section
&&
def
.
_parentSections
.
length
===
0
)
))
...
...
gui/src/components/entry/EditUserMetadataDialog.js
View file @
05d2f050
...
...
@@ -412,6 +412,21 @@ class ListTextInputUnstyled extends React.Component {
component
:
PropTypes
.
any
}
static
styles
=
theme
=>
({
root
:
{},
row
:
{
display
:
'
flex
'
},
buttonContainer
:
{
position
:
'
relative
'
,
width
:
52
},
button
:
{
position
:
'
absolute
'
,
bottom
:
0
}
})
render
()
{
const
{
classes
,
values
,
onChange
,
label
,
component
,
...
fieldProps
}
=
this
.
props
...
...
gui/src/components/search/menus/FilterSubMenuArchive.js
View file @
05d2f050
...
...
@@ -149,8 +149,13 @@ const FilterSubMenuArchive = React.memo(({
const
root
=
useMemo
(()
=>
rootSections
.
find
(
def
=>
def
.
name
===
'
EntryArchive
'
),
[])
const
options
=
useMemo
(()
=>
{
const
options
=
[]
const
defsSet
=
new
Set
()
function
addDef
(
def
,
prefix
)
{
const
fullName
=
prefix
?
`
${
prefix
}
.
${
def
.
name
}
`
:
def
.
name
if
(
defsSet
.
has
(
def
))
{
return
}
defsSet
.
add
(
def
)
options
.
push
({
value
:
fullName
})
if
(
def
.
m_def
===
'
SubSection
'
&&
def
.
sub_section
)
{
def
=
resolveRef
(
def
.
sub_section
)
...
...
nomad/metainfo/metainfo.py
View file @
05d2f050
...
...
@@ -2872,7 +2872,7 @@ class Section(Definition):
def
section_cls
(
self
)
->
Type
[
MSection
]:
if
self
.
_section_cls
is
None
:
# set a temporary to avoid endless recursion
self
.
_section_cls
=
type
(
self
.
name
,
(
MSection
,),
{}
)
self
.
_section_cls
=
type
(
self
.
name
,
(
MSection
,),
dict
(
do_init
=
False
)
)
# Create a section class if this does not exist. This happens if the section
# is not created through a class definition.
...
...
@@ -2884,7 +2884,11 @@ class Section(Definition):
attrs
[
name
]
=
inner_section_def
.
section_cls
attrs
.
update
(
m_def
=
self
,
do_init
=
False
)
self
.
_section_cls
=
type
(
self
.
name
,
(
MSection
,),
attrs
)
if
len
(
self
.
base_sections
)
>
0
:
bases
=
tuple
(
base_section
.
section_cls
for
base_section
in
self
.
base_sections
)
else
:
bases
=
(
MSection
,)
self
.
_section_cls
=
type
(
self
.
name
,
bases
,
attrs
)
return
self
.
_section_cls
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment