From b866ceca7c38f0408a1e3f6a93c382d6f036b32d Mon Sep 17 00:00:00 2001
From: Markus Scheidgen <markus.scheidgen@gmail.com>
Date: Mon, 18 May 2020 20:39:16 +0200
Subject: [PATCH] Many minor bugfixes. #342

---
 gui/src/components/App.js                     | 269 ++++++++++--------
 gui/src/components/DataTable.js               |  29 +-
 gui/src/components/UserdataPage.js            |   2 +-
 gui/src/components/dft/DFTVisualizations.js   |  18 +-
 .../metaInfoBrowser/MetaInfoBrowser.js        |  24 +-
 gui/src/components/search/DatasetList.js      |   1 +
 gui/src/components/search/EntryList.js        |   1 +
 gui/src/components/search/GroupList.js        |   1 +
 gui/src/components/search/Search.js           |  25 +-
 gui/src/components/search/UploadsList.js      |   1 +
 gui/src/components/uploads/Upload.js          |   1 +
 gui/src/searchQuantities.json                 |   4 +-
 nomad/cli/admin/uploads.py                    |   7 +
 nomad/datamodel/dft.py                        |   9 +-
 14 files changed, 230 insertions(+), 162 deletions(-)

diff --git a/gui/src/components/App.js b/gui/src/components/App.js
index fa6feadacc..21dde12316 100644
--- a/gui/src/components/App.js
+++ b/gui/src/components/App.js
@@ -1,6 +1,6 @@
 // trigger rebuild
 
-import React, { useEffect, useState, useContext, useCallback } from 'react'
+import React, { useEffect, useState, useContext, useCallback, useRef } from 'react'
 import PropTypes, { instanceOf } from 'prop-types'
 import { compose } from 'recompose'
 import classNames from 'classnames'
@@ -37,6 +37,7 @@ import {help as userdataHelp, default as UserdataPage} from './UserdataPage'
 import ResolveDOI from './dataset/ResolveDOI'
 import FAQ from './FAQ'
 import EntryQuery from './entry/EntryQuery'
+import KeepState from './KeepState'
 
 export const ScrollContext = React.createContext({scrollParentRef: null})
 
@@ -97,7 +98,6 @@ function MainMenuItem({tooltip, title, path, href, icon}) {
     </Button>
   </Tooltip>
 }
-
 MainMenuItem.propTypes = {
   'tooltip': PropTypes.string.isRequired,
   'title': PropTypes.string.isRequired,
@@ -106,6 +106,90 @@ MainMenuItem.propTypes = {
   'icon': PropTypes.element.isRequired
 }
 
+const useMainMenuStyles = makeStyles(theme => ({
+  root: {
+    display: 'inline-flex',
+    padding: 0,
+    width: '100%',
+    backgroundColor: 'white'
+  },
+  divider: {
+    width: theme.spacing(3)
+  }
+}))
+
+function MainMenu() {
+  const classes = useMainMenuStyles()
+
+  // We keep the URL of those path where components keep meaningful state in the URL.
+  // If the menu is used to comeback, the old URL is used. Therefore, it appears as
+  // if the same component instance with the same state is still there.
+  const {pathname, search} = useLocation()
+  const historyRef = useRef({
+    search: '/search',
+    userdata: '/userdata'
+  })
+  const history = {...historyRef.current}
+  Object.keys(historyRef.current).forEach(key => {
+    if (pathname.startsWith('/' + key)) {
+      historyRef.current[key] = pathname + (search || '')
+      history[key] = '/' + key
+    }
+  })
+
+  return <MenuList classes={{root: classes.root}}>
+    <MainMenuItem
+      title="Search"
+      path={history.search}
+      tooltip="Find and download data"
+      icon={<SearchIcon/>}
+    />
+    <MainMenuItem
+      title="Upload"
+      path="/uploads"
+      tooltip="Upload and publish data"
+      icon={<BackupIcon/>}
+    />
+    <MainMenuItem
+      title="Your data"
+      path={history.userdata}
+      tooltip="Manage your data"
+      icon={<UserDataIcon/>}
+    />
+    <MainMenuItem
+      title="Meta Info"
+      path="/metainfo"
+      tooltip="Browse the archive schema"
+      icon={<MetainfoIcon/>}
+    />
+    <div className={classes.divider} />
+    <MainMenuItem
+      title="About"
+      path="/"
+      tooltip="NOMAD Repository and Archive"
+      icon={<AboutIcon/>}
+    />
+    <MainMenuItem
+      title="FAQ"
+      path="/faq"
+      tooltip="Frequently Asked Questions (FAQ)"
+      icon={<FAQIcon/>}
+    />
+    <MainMenuItem
+      title="Docs"
+      href={`${appBase}/docs/index.html`}
+      tooltip="The NOMAD documentation"
+      icon={<DocIcon/>}
+    />
+    <MainMenuItem
+      title="Sources"
+      href="https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR"
+      tooltip="NOMAD's Gitlab project"
+      icon={<CodeIcon/>}
+    />
+  </MenuList>
+}
+
 class NavigationUnstyled extends React.Component {
   static propTypes = {
     classes: PropTypes.object.isRequired,
@@ -154,12 +238,6 @@ class NavigationUnstyled extends React.Component {
       height: theme.spacing(7),
       marginRight: theme.spacing(2)
     },
-    menu: {
-      display: 'inline-flex',
-      padding: 0,
-      width: '100%',
-      backgroundColor: 'white'
-    },
     content: {
       marginTop: theme.spacing(13),
       flexGrow: 1,
@@ -184,9 +262,6 @@ class NavigationUnstyled extends React.Component {
     barButton: {
       borderColor: theme.palette.getContrastText(theme.palette.primary.main),
       marginRight: 0
-    },
-    divider: {
-      width: theme.spacing(3)
     }
   })
 
@@ -285,57 +360,7 @@ class NavigationUnstyled extends React.Component {
                   <LoginLogout color="primary" classes={{button: classes.barButton}} />
                 </div>
               </Toolbar>
-              <MenuList classes={{root: classes.menu}}>
-                <MainMenuItem
-                  title="Search"
-                  path="/search"
-                  tooltip="Find and download data"
-                  icon={<SearchIcon/>}
-                />
-                <MainMenuItem
-                  title="Upload"
-                  path="/uploads"
-                  tooltip="Upload and publish data"
-                  icon={<BackupIcon/>}
-                />
-                <MainMenuItem
-                  title="Your data"
-                  path="/userdata"
-                  tooltip="Manage your data"
-                  icon={<UserDataIcon/>}
-                />
-                <MainMenuItem
-                  title="Meta Info"
-                  path="/metainfo"
-                  tooltip="Browse the archive schema"
-                  icon={<MetainfoIcon/>}
-                />
-                <div className={classes.divider} />
-                <MainMenuItem
-                  title="About"
-                  path="/"
-                  tooltip="NOMAD Repository and Archive"
-                  icon={<AboutIcon/>}
-                />
-                <MainMenuItem
-                  title="FAQ"
-                  path="/faq"
-                  tooltip="Frequently Asked Questions (FAQ)"
-                  icon={<FAQIcon/>}
-                />
-                <MainMenuItem
-                  title="Docs"
-                  href={`${appBase}/docs/index.html`}
-                  tooltip="The NOMAD documentation"
-                  icon={<DocIcon/>}
-                />
-                <MainMenuItem
-                  title="Sources"
-                  href="https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR"
-                  tooltip="NOMAD's Gitlab project"
-                  icon={<CodeIcon/>}
-                />
-              </MenuList>
+              <MainMenu />
               <LoadingIndicator />
             </AppBar>
 
@@ -410,74 +435,82 @@ class LicenseAgreementUnstyled extends React.Component {
 
 const LicenseAgreement = compose(withCookies, withStyles(LicenseAgreementUnstyled.styles))(LicenseAgreementUnstyled)
 
-class App extends React.PureComponent {
-  routes = {
-    'about': {
-      exact: true,
-      path: '/',
-      component: About
-    },
-    'faq': {
-      exact: true,
-      path: '/faq',
-      component: FAQ
-    },
-    'search': {
-      exact: true,
-      path: '/search',
-      component: SearchPage
-    },
-    'userdata': {
-      exact: true,
-      path: '/userdata',
-      component: UserdataPage
-    },
-    'entry': {
-      path: '/entry/id',
-      component: EntryPage
-    },
-    'entry_query': {
-      exact: true,
-      path: '/entry/query',
-      component: EntryQuery
-    },
-    'entry_pid': {
-      path: '/entry/pid',
-      component: ResolvePID
-    },
-    'dataset': {
-      path: '/dataset/id',
-      component: DatasetPage
-    },
-    'dataset_doi': {
-      path: '/dataset/doi',
-      component: ResolveDOI
-    },
-    'uploads': {
-      exact: true,
-      path: '/uploads',
-      component: UploadPage
-    },
-    'metainfo': {
-      path: '/metainfo',
-      component: MetaInfoBrowser
-    }
+const routes = {
+  'about': {
+    exact: true,
+    path: '/',
+    component: About
+  },
+  'faq': {
+    exact: true,
+    path: '/faq',
+    component: FAQ
+  },
+  'search': {
+    exact: true,
+    path: '/search',
+    component: SearchPage
+  },
+  'userdata': {
+    exact: true,
+    path: '/userdata',
+    component: UserdataPage
+  },
+  'entry': {
+    path: '/entry/id',
+    component: EntryPage
+  },
+  'entry_query': {
+    exact: true,
+    path: '/entry/query',
+    component: EntryQuery
+  },
+  'entry_pid': {
+    path: '/entry/pid',
+    component: ResolvePID
+  },
+  'dataset': {
+    path: '/dataset/id',
+    component: DatasetPage
+  },
+  'dataset_doi': {
+    path: '/dataset/doi',
+    component: ResolveDOI
+  },
+  'uploads': {
+    exact: true,
+    path: '/uploads',
+    component: UploadPage
+  },
+  'metainfo': {
+    path: '/metainfo',
+    keepState: true,
+    exists: false,
+    component: MetaInfoBrowser
   }
+}
 
+class App extends React.PureComponent {
   render() {
     return (
       <MuiThemeProvider theme={nomadTheme}>
         <ErrorSnacks>
           <ApiProvider>
             <Navigation>
-              {Object.keys(this.routes).map(routeKey => {
-                const route = this.routes[routeKey]
+              {Object.keys(routes).map(routeKey => {
+                const route = routes[routeKey]
                 const { path, exact } = route
                 return <Route key={routeKey} exact={exact} path={path}
                   // eslint-disable-next-line react/no-children-prop
                   children={props => {
-                    // return <KeepState visible={props.match && true} render={(props) => <route.component {...props} />} {...props} />
-                    return props.match && <route.component {...props} />
+                    if (route.keepState) {
+                      if (props.match || route.exists) {
+                        route.exists = true
+                        return <route.component visible={props.match && true} {...props} />
+                      }
+                    } else {
+                      return props.match && <route.component {...props} />
+                    }
                   }}
                 />
               })}
diff --git a/gui/src/components/DataTable.js b/gui/src/components/DataTable.js
index 2cd19d9783..3953f789e7 100644
--- a/gui/src/components/DataTable.js
+++ b/gui/src/components/DataTable.js
@@ -18,6 +18,8 @@ import { Popover, List, ListItemText, ListItem, Collapse } from '@material-ui/co
 import { compose } from 'recompose'
 import _ from 'lodash'
 
+const globalSelectedColumns = {}
+
 class DataTableToolbarUnStyled extends React.Component {
   static propTypes = {
     classes: PropTypes.object.isRequired,
@@ -169,6 +171,11 @@ class DataTableUnStyled extends React.Component {
      * The set of columns initially shown as an array of column keys.
      */
     selectedColumns: PropTypes.arrayOf(PropTypes.string),
+    /**
+     * If this key is given, it is used to globaly store user modifications to the selected
+     * columns under this key.
+     */
+    selectedColumnsKey: PropTypes.string,
     /**
      * Single element that is rendered to display actions for the selection. With no
      * select actions, no selection will be shown.
@@ -285,9 +292,14 @@ class DataTableUnStyled extends React.Component {
   constructor(props) {
     super(props)
     this.handleSelectAllClick = this.handleSelectAllClick.bind(this)
+    this.handleSelectedColumnsChanged = this.handleSelectedColumnsChanged.bind(this)
+    let selectedColumns = this.props.selectedColumns || Object.keys(this.props.columns)
+    if (this.props.selectedColumnsKey) {
+      selectedColumns = globalSelectedColumns[this.props.selectedColumnsKey] || selectedColumns
+    }
     this.state = {
       ...this.state,
-      selectedColumns: this.props.selectedColumns || Object.keys(this.props.columns)
+      selectedColumns: selectedColumns
     }
   }
 
@@ -296,12 +308,6 @@ class DataTableUnStyled extends React.Component {
     selectedColumns: null
   }
 
-  componentDidUpdate(prevProps) {
-    if (prevProps.columns !== this.props.columns) {
-      this.setState({selectedColumns: this.props.selectedColumns})
-    }
-  }
-
   handleRequestSort(event, property) {
     const { orderBy, order, onOrderChanged } = this.props
     const isDesc = orderBy === property && order === 'desc'
@@ -360,6 +366,13 @@ class DataTableUnStyled extends React.Component {
     }
   }
 
+  handleSelectedColumnsChanged(columns) {
+    if (this.props.selectedColumnsKey) {
+      globalSelectedColumns[this.props.selectedColumnsKey] = columns
+    }
+    this.setState({selectedColumns: columns})
+  }
+
   renderDetails(row) {
     const { classes, entryDetails, id, entryActions } = this.props
     const { selectedColumns, selectedEntry } = this.state
@@ -415,7 +428,7 @@ class DataTableUnStyled extends React.Component {
           selectedColumns={selectedColumns}
           selectActions={selectActions}
           actions={actions}
-          onColumnsChanged={columns => this.setState({selectedColumns: columns})}
+          onColumnsChanged={this.handleSelectedColumnsChanged}
         />
         <div className={classes.tableWrapper}>
           <Table className={classes.table} size="small">
diff --git a/gui/src/components/UserdataPage.js b/gui/src/components/UserdataPage.js
index 1d5b876746..725e99ec7a 100644
--- a/gui/src/components/UserdataPage.js
+++ b/gui/src/components/UserdataPage.js
@@ -59,7 +59,7 @@ function UserdataPage() {
     initialRequest={{order_by: 'upload_time', uploads_grouped: true}}
     initialResultTab="uploads"
     availableResultTabs={['uploads', 'datasets', 'entries']}
-    resultListProps={{selectedColumns: ['formula', 'upload_time', 'mainfile', 'published', 'co_authors', 'references', 'datasets']}}
+    resultListProps={{selectedColumnsKey: 'userEntries', selectedColumns: ['formula', 'upload_time', 'mainfile', 'published', 'co_authors', 'references', 'datasets']}}
   />
 }
 
diff --git a/gui/src/components/dft/DFTVisualizations.js b/gui/src/components/dft/DFTVisualizations.js
index 073f5efec7..43c36b4c49 100644
--- a/gui/src/components/dft/DFTVisualizations.js
+++ b/gui/src/components/dft/DFTVisualizations.js
@@ -65,15 +65,15 @@ export function DFTSystemVisualizations(props) {
 
   return (
     <Grid container spacing={2}>
-      <Grid item xs={4}>
-        <QuantityHistogram quantity="dft.compound_type" title="Compound type" initialScale={0.25} />
-      </Grid>
       <Grid item xs={4}>
         <QuantityHistogram quantity="dft.system" title="System type" initialScale={0.25} />
         <QuantityHistogram quantity="dft.crystal_system" title="Crystal system" />
       </Grid>
       <Grid item xs={4}>
-        <QuantityHistogram quantity="dft.labels_springer_compound_class" title="Springer compound" />
+        <QuantityHistogram quantity="dft.compound_type" title="Compound type" initialScale={0.25} />
+      </Grid>
+      <Grid item xs={4}>
+        <QuantityHistogram quantity="dft.labels_springer_compound_class" title="Compound classification" />
       </Grid>
     </Grid>
   )
@@ -97,13 +97,13 @@ const electronic_quantities = [
   'eigenvalues_values',
   'volumetric_data_values',
   'electronic_kinetic_energy',
-  'total_charge',
-  'atomic_multipole_values'
+  'total_charge'
+  // 'atomic_multipole_values'
 ]
 const forces_quantities = [
   'atom_forces_free',
   'atom_forces_raw',
-  'atom_forces_T0',
+  // 'atom_forces_T0',
   'atom_forces',
   'stress_tensor'
 ]
@@ -177,6 +177,7 @@ export function DFTPropertyVisualizations(props) {
       <Grid item xs={4}>
         <QuantityHistogram quantity="dft.searchable_quantities" values={energy_quantities} valueLabels={labels} title="Energy" initialScale={0.5} tooltips />
         <QuantityHistogram quantity="dft.searchable_quantities" values={electronic_quantities} valueLabels={labels} title="Electronic" initialScale={0.5} tooltips />
+        <QuantityHistogram quantity="dft.searchable_quantities" values={magnetic_quantities} valueLabels={labels} title="Magnetic" initialScale={1} tooltips />
       </Grid>
       <Grid item xs={4}>
         <QuantityHistogram quantity="dft.searchable_quantities" values={forces_quantities} valueLabels={labels} title="Forces" initialScale={0.5} tooltips />
@@ -184,8 +185,7 @@ export function DFTPropertyVisualizations(props) {
         <QuantityHistogram quantity="dft.searchable_quantities" values={optical_quantities} valueLabels={labels} title="Optical" initialScale={1} tooltips />
       </Grid>
       <Grid item xs={4}>
-        <QuantityHistogram quantity="dft.labels_springer_classification" title="Springer classification" initialScale={1} tooltips />
-        <QuantityHistogram quantity="dft.searchable_quantities" values={magnetic_quantities} valueLabels={labels} title="Magnetic" initialScale={1} tooltips />
+        <QuantityHistogram quantity="dft.labels_springer_classification" title="Property classification" initialScale={1} tooltips />
       </Grid>
     </Grid>
   )
diff --git a/gui/src/components/metaInfoBrowser/MetaInfoBrowser.js b/gui/src/components/metaInfoBrowser/MetaInfoBrowser.js
index f37fd5b8eb..c7007fe2ed 100644
--- a/gui/src/components/metaInfoBrowser/MetaInfoBrowser.js
+++ b/gui/src/components/metaInfoBrowser/MetaInfoBrowser.js
@@ -1,5 +1,6 @@
 
-import React, { useContext, useState, useEffect } from 'react'
+import React, { useContext, useState, useEffect, useRef } from 'react'
+import PropTypes from 'prop-types'
 import { matchPath, useLocation, useHistory, useRouteMatch } from 'react-router-dom'
 import Viewer from './Viewer'
 import { apiContext } from '../api'
@@ -60,14 +61,22 @@ const useStyles = makeStyles(theme => ({
   }
 }))
 
-export default function MetaInfoBrowser(props) {
+export default function MetaInfoBrowser({visible}) {
   const classes = useStyles()
 
-  const location = useLocation()
-  const history = useHistory()
+  const routingRef = useRef({})
+  const routing = {
+    location: useLocation(),
+    history: useHistory(),
+    routeMatch: useRouteMatch()
+  }
+  if (visible) {
+    routingRef.current = routing
+  }
+  const {location, history, routeMatch} = routingRef.current
 
   const match = matchPath(location.pathname, {
-    path: `${useRouteMatch().path}/:pkg?/:metainfo?`
+    path: `${routeMatch.path}/:pkg?/:metainfo?`
   })
   const pkg = match.params.pkg || 'general'
   const metainfoName = match.params.metainfo || 'section_run'
@@ -112,7 +121,7 @@ export default function MetaInfoBrowser(props) {
   const metainfo = metainfos.resolve(metainfos.createProxy(metainfoName))
   console.log(metainfoName)
 
-  return <div>
+  return <div style={{display: visible ? 'block' : 'none'}}>
     <div className={classes.forms}>
       <form style={{ display: 'flex' }}>
         <MetainfoSearch
@@ -143,3 +152,6 @@ export default function MetaInfoBrowser(props) {
     <Viewer key={`${metainfo.package.name}/${metainfo.name}`} rootElement={metainfo} packages={metainfos.contents} />
   </div>
 }
+MetaInfoBrowser.propTypes = {
+  visible: PropTypes.bool
+}
diff --git a/gui/src/components/search/DatasetList.js b/gui/src/components/search/DatasetList.js
index 631fa0aaf6..72e5cfa146 100644
--- a/gui/src/components/search/DatasetList.js
+++ b/gui/src/components/search/DatasetList.js
@@ -289,6 +289,7 @@ class DatasetListUnstyled extends React.Component {
       total={total}
       columns={this.columns}
       selectedColumns={['name', 'DOI', 'entries', 'authors']}
+      selectedColumnsKey="datasets"
       entryActions={this.renderEntryActions}
       data={results}
       rows={perPage}
diff --git a/gui/src/components/search/EntryList.js b/gui/src/components/search/EntryList.js
index 9ef43038d8..1091ba61aa 100644
--- a/gui/src/components/search/EntryList.js
+++ b/gui/src/components/search/EntryList.js
@@ -342,6 +342,7 @@ export class EntryListUnstyled extends React.Component {
           total={total}
           columns={columns}
           selectedColumns={defaultSelectedColumns}
+          selectedColumnsKey="entries"
           entryDetails={this.renderEntryDetails.bind(this)}
           entryActions={this.renderEntryActions.bind(this)}
           data={results}
diff --git a/gui/src/components/search/GroupList.js b/gui/src/components/search/GroupList.js
index 2ed13e297b..869ecd5e5f 100644
--- a/gui/src/components/search/GroupList.js
+++ b/gui/src/components/search/GroupList.js
@@ -210,6 +210,7 @@ class GroupListUnstyled extends React.Component {
       total={total}
       columns={this.columns}
       selectedColumns={defaultSelectedColumns}
+      selectedColumnsKey="groups"
       entryDetails={this.renderEntryDetails.bind(this)}
       entryActions={this.renderEntryActions}
       data={results}
diff --git a/gui/src/components/search/Search.js b/gui/src/components/search/Search.js
index 3e88d4525e..334e15765c 100644
--- a/gui/src/components/search/Search.js
+++ b/gui/src/components/search/Search.js
@@ -43,19 +43,6 @@ const resultTabs = {
   }
 }
 
-const defaultVisalizations = {
-  'elements': {
-    component: ElementsVisualization,
-    label: 'Elements',
-    description: 'Shows data as a heatmap over the periodic table'
-  },
-  'users': {
-    component: UsersVisualization,
-    label: 'Users',
-    description: 'Show statistics on user metadata'
-  }
-}
-
 const useSearchStyles = makeStyles(theme => ({
   root: {
     padding: theme.spacing(3)
@@ -162,8 +149,18 @@ function SearchEntry({initialTab, initialOwner, ownerTypes, initialDomain, initi
   const {domain} = useContext(searchContext)
 
   const visualizations = {}
-  Object.assign(visualizations, defaultVisalizations)
+  visualizations.elements = {
+    component: ElementsVisualization,
+    label: 'Elements',
+    description: 'Shows data as a heatmap over the periodic table'
+  }
   Object.assign(visualizations, domain.searchVisualizations)
+  visualizations.users = {
+    component: UsersVisualization,
+    label: 'Uploads',
+    description: 'Show statistics about when and by whom data was uploaded'
+  }
+
   const openVisualizationKey = openVisualizationParam || initialTab
   const openVisualizationTab = visualizations[openVisualizationKey]
 
diff --git a/gui/src/components/search/UploadsList.js b/gui/src/components/search/UploadsList.js
index 06bd5d93f1..ab41490a2c 100644
--- a/gui/src/components/search/UploadsList.js
+++ b/gui/src/components/search/UploadsList.js
@@ -220,6 +220,7 @@ class UploadListUnstyled extends React.Component {
       total={total}
       columns={this.columns}
       selectedColumns={['upload_time', 'upload_id', 'entries', 'published']}
+      selectedColumnsKey="uploads"
       entryActions={this.renderEntryActions}
       data={results}
       rows={per_page}
diff --git a/gui/src/components/uploads/Upload.js b/gui/src/components/uploads/Upload.js
index 8f1ae4c715..f01ae2df04 100644
--- a/gui/src/components/uploads/Upload.js
+++ b/gui/src/components/uploads/Upload.js
@@ -608,6 +608,7 @@ class Upload extends React.Component {
       query={{upload_id: [upload.upload_id]}}
       columns={columns}
       selectedColumns={Upload.defaultSelectedColumns}
+      selectedColumnsKey={null}
       editable={tasks_status === 'SUCCESS'}
       data={data}
       onChange={this.handleChange}
diff --git a/gui/src/searchQuantities.json b/gui/src/searchQuantities.json
index 595b9aebab..15f889e986 100644
--- a/gui/src/searchQuantities.json
+++ b/gui/src/searchQuantities.json
@@ -306,7 +306,7 @@
     "name": "dft.searchable_quantities",
     "description": "All quantities with existence filters in the search GUI.",
     "many": true,
-    "statistic_size": 25
+    "statistic_size": 23
   },
   "dft.geometries": {
     "name": "dft.geometries",
@@ -328,7 +328,7 @@
     "name": "dft.labels_springer_classification",
     "description": "Springer classification by property.",
     "many": true,
-    "statistic_size": 10
+    "statistic_size": 20
   },
   "upload_id": {
     "name": "upload_id",
diff --git a/nomad/cli/admin/uploads.py b/nomad/cli/admin/uploads.py
index 621b253add..44eb821720 100644
--- a/nomad/cli/admin/uploads.py
+++ b/nomad/cli/admin/uploads.py
@@ -228,6 +228,13 @@ def index(ctx, uploads):
     i, failed = 0, 0
     for upload in uploads:
         with upload.entries_metadata() as calcs:
+            # This is just a temporary fix to update the group hash without re-processing
+            try:
+                for calc in calcs:
+                    if calc.dft is not None:
+                        calc.dft.update_group_hash()
+            except Exception:
+                pass
             failed += search.index_all(calcs)
             i += 1
 
diff --git a/nomad/datamodel/dft.py b/nomad/datamodel/dft.py
index 5781e8d352..5ab78150e5 100644
--- a/nomad/datamodel/dft.py
+++ b/nomad/datamodel/dft.py
@@ -71,12 +71,13 @@ _electronic_quantities = [
     'volumetric_data_values',
     'electronic_kinetic_energy',
     'total_charge',
-    'atomic_multipole_values']
+    # 'atomic_multipole_values'
+]
 
 _forces_quantities = [
     'atom_forces_free',
     'atom_forces_raw',
-    'atom_forces_T0',
+    # 'atom_forces_T0',
     'atom_forces',
     'stress_tensor']
 
@@ -254,7 +255,7 @@ class DFTMetadata(MSection):
         type=str, shape=['0..*'],
         description='Springer classification by property.',
         a_search=Search(
-            many_and='append', statistic_size=10,
+            many_and='append', statistic_size=20,
             statistic_order='_count'))
 
     optimade = SubSection(
@@ -280,7 +281,7 @@ class DFTMetadata(MSection):
             self.code_name,
             self.code_version,
             self.m_parent.with_embargo,
-            self.m_parent.uploader)
+            self.m_parent.uploader.user_id)
 
     def apply_domain_metadata(self, backend):
         from nomad.normalizing.system import normalized_atom_labels
-- 
GitLab