Commit 00e1ed8c authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Merge branch 'v0-hotfixes' into 'v0.10.9'

Hotfixes v0.10.9. Fixes #644, #649

See merge request !447
parents 31c542cd 2c91a47a
Pipeline #114608 passed with stages
in 27 minutes and 58 seconds
......@@ -61,7 +61,7 @@ gui linting:
image: node
script:
- cd gui
- yarn
- yarn --network-timeout 1200000
- yarn run lint
except:
refs:
......@@ -107,7 +107,7 @@ gui tests:
image: node
script:
- cd gui
- yarn
- yarn --network-timeout 1200000
- yarn run test
except:
refs:
......
......@@ -15,7 +15,7 @@ Otherwise, clone using HTTPS URL:
git clone https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR.git nomad
```
then change directory to nomad
then change directory to nomad
```
cd nomad
......@@ -238,11 +238,7 @@ yarn start
To run the tests some additional settings and files are necessary that are not part
of the code base.
First, you need to provide the `springer.msg` Springer materials database. It can
be copied from `/nomad/fairdi/db/data/springer.msg` on our servers and should
be placed at `nomad/normalizing/data/springer.msg`.
Second, you have to provide static files to serve the docs and NOMAD distribution:
You have to provide static files to serve the docs and NOMAD distribution:
```sh
cd docs
make html
......
......@@ -33,7 +33,6 @@
"object-hash": "^2.0.3",
"pace": "^0.0.4",
"pace-js": "^1.0.2",
"piwik-react-router": "^0.12.1",
"plotly.js-cartesian-dist-min": "^1.54.7",
"qs": "^6.8.0",
"react": "^16.13.1",
......
......@@ -5,9 +5,6 @@ window.nomadEnv = {
'appBase': 'http://nomad-lab.eu/prod/rae/beta',
'appBase': 'http://localhost:8000/fairdi/nomad/latest',
'debug': false,
'matomoEnabled': false,
'matomoUrl': 'https://nomad-lab.eu/fairdi/stat',
'matomoSiteId': '2',
'version': {
'label': '0.10.9',
'isBeta': false,
......@@ -16,6 +13,6 @@ window.nomadEnv = {
'officialUrl': 'https://nomad-lab.eu/prod/rae/gui'
},
'encyclopediaEnabled': true,
'aitoolkitEnabled': true,
'aitoolkitEnabled': false,
'oasis': false
}
......@@ -19,7 +19,7 @@ import React, { useContext, useLayoutEffect, useRef, useCallback, useEffect, use
import { ReactComponent as AboutSvg } from '../images/about.svg'
import PropTypes from 'prop-types'
import Markdown from './Markdown'
import { appBase, debug, consent, aitoolkitEnabled, encyclopediaEnabled } from '../config'
import { appBase, debug, aitoolkitEnabled, encyclopediaEnabled } from '../config'
import { apiContext } from './api'
import packageJson from '../../package.json'
import { domains } from './domains'
......@@ -248,7 +248,7 @@ export default function About() {
<Grid className={classes.container} container spacing={2}>
<Grid item xs={12}>
<Markdown>{`
# The NOMAD Repository and Archive
# **NOMAD** &ndash; Manage and Publish Materials Data
This is the *graphical user interface* (GUI) for the NOMAD Repository and
Archive. It allows you to **search, access, and download all NOMAD data** in its
......@@ -375,9 +375,6 @@ export default function About() {
used for data that has no provenance with the original NOMAD CoE database.
` : ''}
### Terms of use and licenses
${consent}
### About this version
- version (API): \`${info ? info.version : 'loading'}/${info ? info.git.commit : 'loading'}\`
- version (GUI): \`${packageJson.version}/${packageJson.commit}\`
......
......@@ -19,9 +19,7 @@ import React from 'react'
import { Router, Route } from 'react-router-dom'
import { QueryParamProvider } from 'use-query-params'
import history from '../history'
import PiwikReactRouter from 'piwik-react-router'
import { nomadTheme, matomoEnabled, matomoUrl, matomoSiteId, keycloakBase, keycloakRealm,
keycloakClientId } from '../config'
import { nomadTheme, keycloakBase, keycloakRealm, keycloakClientId } from '../config'
import Keycloak from 'keycloak-js'
import { KeycloakProvider } from 'react-keycloak'
import { MuiThemeProvider } from '@material-ui/core/styles'
......@@ -29,15 +27,6 @@ import { ApiProvider } from './api'
import { ErrorSnacks, ErrorBoundary } from './errors'
import Navigation from './nav/Navigation'
export const matomo = matomoEnabled ? PiwikReactRouter({
url: matomoUrl,
siteId: matomoSiteId,
clientTrackerName: 'stat.js',
serverTrackerName: 'stat'
}) : []
// matomo.push('requireConsent')
const keycloak = Keycloak({
url: keycloakBase,
realm: keycloakRealm,
......@@ -47,7 +36,7 @@ const keycloak = Keycloak({
export default function App() {
return (
<KeycloakProvider keycloak={keycloak} initConfig={{ onLoad: 'check-sso', 'checkLoginIframe': false }} LoadingComponent={<div />}>
<Router history={matomoEnabled ? matomo.connectToHistory(history) : history}>
<Router history={history}>
<QueryParamProvider ReactRouterRoute={Route}>
<MuiThemeProvider theme={nomadTheme}>
<ErrorSnacks>
......
......@@ -35,6 +35,7 @@ import ArrowIcon from '../../images/AIT_ico_bd_link_go_to.svg'
import ReproduceIcon from '../../images/AIT_ico_bp_replicate.svg'
import AccordionsList from './AccordionsList'
import FigureAI from '../../images/AIT_illu_AIT.svg'
import { aitoolkitEnabled } from '../../config'
export default function ReproducePage() {
const styles = useStyles()
......@@ -87,7 +88,8 @@ export default function ReproducePage() {
<Grid item xs={4} style={{marginTop: '-100px', marginLeft: '-20px'}}>
<IconButton
component={Link}
to="main">
{...(aitoolkitEnabled ? ({to: 'main', component: Link}) : ({href: 'https://nomad-lab.eu/AIToolkit', component: 'a'}))}
>
<img alt='AI toolkit logo' src={FigureAI} style={{width: '120px'}}/>
</IconButton>
</Grid>
......@@ -216,7 +218,7 @@ export default function ReproducePage() {
<Grid item xs={4}>
<IconButton
component={Link}
to="main"
{...(aitoolkitEnabled ? ({to: 'main', component: Link}) : ({href: 'https://nomad-lab.eu/AIToolkit', component: 'a'}))}
style={{marginRight: '0px', marginTop: '20px'}}
>
<img alt='AI toolkit logo' src={FigureAI} style={{width: '120px'}}/>
......
......@@ -35,6 +35,7 @@ import ReproduceIcon from '../../images/AIT_ico_bb_replicate.svg'
import AccordionsList from './AccordionsList'
import FigureAI from '../../images/AIT_illu_AIT.svg'
import tutorials from '../../toolkitMetadata'
import { aitoolkitEnabled } from '../../config'
export const useStyles = makeStyles(theme => ({
root: {
......@@ -185,8 +186,8 @@ export default function TutorialsPage() {
<Grid container spacing={0}>
<Grid item xs={4} style={{marginTop: '-100px', marginLeft: '-20px'}}>
<IconButton
component={Link}
to="main">
{...(aitoolkitEnabled ? ({to: 'main', component: Link}) : ({href: 'https://nomad-lab.eu/AIToolkit', component: 'a'}))}
>
<img alt='AI toolkit logo' src={FigureAI} style={{width: '120px'}}/>
</IconButton>
</Grid>
......@@ -380,7 +381,7 @@ export default function TutorialsPage() {
<Grid item xs={4}>
<IconButton
component={Link}
to="main"
{...(aitoolkitEnabled ? ({to: 'main', component: Link}) : ({href: 'https://nomad-lab.eu/AIToolkit', component: 'a'}))}
style={{marginRight: '0px', marginTop: '20px'}}
>
<img alt='AI toolkit logo' src={FigureAI} style={{width: '120px'}}/>
......
......@@ -16,16 +16,10 @@
* limitations under the License.
*/
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, FormControlLabel,
FormGroup,
Switch} from '@material-ui/core'
import React, { useEffect, useMemo, useState } from 'react'
import Markdown from '../Markdown'
import React from 'react'
import { useRoute } from './Routes'
import { matomo } from '../App'
import { useCookies } from 'react-cookie'
import { MenuBar, MenuBarItem, MenuBarMenu } from './MenuBar'
import { guiBase, consent, appBase, oasis, aitoolkitEnabled, encyclopediaEnabled } from '../../config'
import { appBase, oasis, aitoolkitEnabled, encyclopediaEnabled } from '../../config'
import BackupIcon from '@material-ui/icons/Backup'
import SearchIcon from '@material-ui/icons/Search'
......@@ -40,82 +34,6 @@ import CodeIcon from '@material-ui/icons/Code'
import TermsIcon from '@material-ui/icons/Assignment'
import AnalyticsIcon from '@material-ui/icons/ShowChart'
function Consent(moreProps) {
const [cookies, setCookie] = useCookies()
const [accepted, setAccepted] = useState(cookies['terms-accepted'])
const [optOut, setOptOut] = useState(cookies['tracking-enabled'] === 'false')
const cookieOptions = useMemo(() => ({
expires: new Date(2147483647 * 1000),
path: '/' + guiBase.split('/').slice(1).join('/')
}), [])
useEffect(() => {
if (!optOut) {
matomo.push(['setConsentGiven'])
} else {
matomo.push(['requireConsent'])
}
})
// Write again to push forwards Safari's hard-coded 7 days ITP window
useEffect(() => {
setCookie('terms-accepted', cookies['terms-accepted'], cookieOptions)
setCookie('tracking-enabled', cookies['tracking-enabled'], cookieOptions)
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[])
const handleClosed = accepted => {
if (accepted) {
setCookie('terms-accepted', true, cookieOptions)
setCookie('tracking-enabled', !optOut, cookieOptions)
setAccepted(true)
}
}
const handleOpen = () => {
setCookie('terms-accepted', false, cookieOptions)
setAccepted(false)
}
return (
<React.Fragment>
<MenuBarItem
name="terms"
onClick={handleOpen}
tooltip="The terms of service and cookie consent"
icon={<TermsIcon/>}
{...moreProps}
/>
<Dialog
disableBackdropClick disableEscapeKeyDown
open={!accepted}
>
<DialogTitle>Terms of Use</DialogTitle>
<DialogContent>
<Markdown>{consent}</Markdown>
<FormGroup>
<FormControlLabel
control={<Switch
checked={optOut}
onChange={(e) => {
setOptOut(!optOut)
}}
color="primary"
/>}
label="Do not provide information about your use of NOMAD (opt-out)."
/>
</FormGroup>
</DialogContent>
<DialogActions>
<Button onClick={() => handleClosed(true)} color="primary">
Accept
</Button>
</DialogActions>
</Dialog>
</React.Fragment>
)
}
export default function MainMenu() {
const route = useRoute()
const selected = (route?.navPath) || 'publish/uploads'
......@@ -192,7 +110,12 @@ export default function MainMenu() {
tooltip="NOMAD's main Gitlab project"
icon={<CodeIcon/>}
/>
<Consent />
<MenuBarItem
name="terms"
href="https://nomad-lab.eu/terms"
tooltip="The terms of service"
icon={<TermsIcon/>}
/>
</MenuBarMenu>
</MenuBar>
}
......@@ -16,19 +16,20 @@
* limitations under the License.
*/
import React, { useEffect, useRef, useState } from 'react'
import React, { useEffect, useMemo, useRef, useState } from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { useLocation } from 'react-router-dom'
import { Snackbar, SnackbarContent, IconButton, Link as MuiLink, Button } from '@material-ui/core'
import { Snackbar, SnackbarContent, IconButton, Link as MuiLink, Button, Link } from '@material-ui/core'
import UnderstoodIcon from '@material-ui/icons/Check'
import ReloadIcon from '@material-ui/icons/Replay'
import { amber } from '@material-ui/core/colors'
import AppBar from './AppBar'
import { version } from '../../config'
import { version, guiBase } from '../../config'
import Routes from './Routes'
import { withApi } from '../api'
import { serviceWorkerUpdateHandlerRef } from '../../index'
import { ErrorBoundary } from '../errors'
import { useCookies } from 'react-cookie'
export const ScrollContext = React.createContext({scrollParentRef: null})
......@@ -72,6 +73,43 @@ function ReloadSnack() {
</Snackbar>
}
function TermsSnack() {
const [cookies, setCookie] = useCookies()
const [accepted, setAccepted] = useState(cookies['terms-accepted'])
const cookieOptions = useMemo(() => ({
expires: new Date(2147483647 * 1000),
path: '/' + guiBase.split('/').slice(1).join('/')
}), [])
return <Snackbar
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left'
}}
open={!accepted}
>
<SnackbarContent
message={<span>
NOMAD only uses cookies that are strictly necessary for this site&apos;s functionality.
No tracking or marketing cookies are used. By using this site you agree to
our <Link href="https://nomad-lab.eu/terms" title="terms of service">terms of service</Link>.
</span>}
action={[
<IconButton
size="small" key={0} color="inherit"
onClick={() => {
setCookie('terms-accepted', true, cookieOptions)
setAccepted(true)
}}
>
<UnderstoodIcon />
</IconButton>
]}
/>
</Snackbar>
}
const useBetaSnackStyles = makeStyles(theme => ({
root: {},
snack: {
......@@ -153,6 +191,7 @@ function Navigation() {
<ReloadSnack/>
<ErrorBoundary>
<BetaSnack />
<TermsSnack />
<AppBar />
<main className={classes.content} ref={scrollParentRef}>
<ScrollContext.Provider value={{scrollParentRef: scrollParentRef}}>
......
......@@ -23,35 +23,16 @@ export const appBase = window.nomadEnv.appBase.replace(/\/$/, '')
// export const apiBase = 'http://nomad-lab.eu/prod/rae/api'
export const apiBase = `${appBase}/api`
export const guiBase = process.env.PUBLIC_URL
export const matomoUrl = window.nomadEnv.matomoUrl
export const matomoSiteId = window.nomadEnv.matomoSiteId
export const keycloakBase = window.nomadEnv.keycloakBase
export const keycloakRealm = window.nomadEnv.keycloakRealm
export const keycloakClientId = window.nomadEnv.keycloakClientId
export const debug = window.nomadEnv.debug || false
export const matomoEnabled = window.nomadEnv.matomoEnabled || false
export const encyclopediaEnabled = window.nomadEnv.encyclopediaEnabled || false
export const aitoolkitEnabled = window.nomadEnv.aitoolkitEnabled || false
export const oasis = window.nomadEnv.oasis || false
export const email = 'support@nomad-lab.eu'
export const maxLogsToShow = 50
export const consent = `
By using this web-site and by uploading and downloading data, you agree to the
[terms of use](https://nomad-lab.eu/terms).
Uploaded data is licensed under the Creative Commons Attribution license
([CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)). You can publish
uploaded data with an *embargo*. Data with an *embargo* is only visible to
you and users you share your data with. The *embargo period* lasts up to 36 months.
After the *embargo* your published data will be public. **Note that public data
is visible to others and files become downloadable by everyone.**
This web-site uses *cookies*. We use cookies to track your login status for all NOMAD services
and optionally to store information about your use of NOMAD. None of this information is
shared with other parties. By using this web-site you agree to the described use of *cookies*.
[Learn more](https://www.cookiesandyou.com/).
`
export const nomadPrimaryColor = {
main: '#008DC3',
light: '#03B9FF',
......
......@@ -4,9 +4,6 @@ global.nomadEnv = {
'keycloakClientId': 'nomad_gui_dev',
'appBase': 'http://nomad-lab.eu/prod/rae/beta',
'debug': false,
'matomoEnabled': false,
'matomoUrl': 'https://nomad-lab.eu/fairdi/stat',
'matomoSiteId': '2',
'version': {
'label': '0.10.9',
'isBeta': false,
......
......@@ -10054,8 +10054,9 @@ node-releases@^1.1.52, node-releases@^1.1.69:
integrity sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA==
 
"nomad-fair-gui@file:.":
version "0.10.1"
version "0.10.9"
dependencies:
"@fontsource/material-icons" "^4.2.1"
"@fontsource/titillium-web" "^4.2.2"
"@material-ui/core" "^4.0.0"
"@material-ui/icons" "^4.0.0"
......@@ -10077,11 +10078,10 @@ node-releases@^1.1.52, node-releases@^1.1.69:
material-ui-chip-input "^1.0.0-beta.14"
material-ui-flat-pagination "^4.0.0"
mathjs "^7.1.0"
nomad-fair-gui "file:../../../../Library/Caches/Yarn/v6/npm-nomad-fair-gui-0.10.1-caae6be0-51b7-44c5-86db-e97037c5c024-1617035416277/node_modules/nomad-fair-gui"
nomad-fair-gui "file:../../../../Library/Caches/Yarn/v6/npm-nomad-fair-gui-0.10.9-324b8cac-66d6-4e0f-9509-5fe7a9244edb-1636106710154/node_modules/nomad-fair-gui"
object-hash "^2.0.3"
pace "^0.0.4"
pace-js "^1.0.2"
piwik-react-router "^0.12.1"
plotly.js-cartesian-dist-min "^1.54.7"
qs "^6.8.0"
react "^16.13.1"
......@@ -10885,14 +10885,6 @@ pirates@^4.0.1:
dependencies:
node-modules-regexp "^1.0.0"
 
piwik-react-router@^0.12.1:
version "0.12.1"
resolved "https://registry.yarnpkg.com/piwik-react-router/-/piwik-react-router-0.12.1.tgz#0caf984715a5b22c85610e0c02ae372b1ca37c41"
integrity sha512-Ebi7rBKV/S+YJ3UF/6t6n/wRx1/4yilR1caG/JhdefkYHh8gopqy2kxjaaD++LS9tTmtPNfokEHWbXTbw2W7OA==
dependencies:
url-join "^1.1.0"
warning "^3.0.0"
pkg-dir@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4"
......@@ -14857,11 +14849,6 @@ urix@^0.1.0:
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
 
url-join@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78"
integrity sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=
url-loader@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-2.3.0.tgz#e0e2ef658f003efb8ca41b0f3ffbf76bab88658b"
......@@ -15148,13 +15135,6 @@ walker@^1.0.7, walker@~1.0.5:
dependencies:
makeerror "1.0.x"
 
warning@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=
dependencies:
loose-envify "^1.0.0"
warning@^4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
......
......@@ -715,6 +715,7 @@ def gui_config():
from nomad import config
import glob
import shutil
import json
gui_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../app/flask/static/gui'))
run_gui_folder = os.path.join(gui_folder, '../.gui_configured')
......@@ -734,10 +735,10 @@ window.nomadEnv = {{
'keycloakRealm': '{config.keycloak.realm_name}',
'keycloakClientId': '{config.keycloak.client_id}',
'debug': false,
'matomoEnabled': false,
'encyclopediaEnabled': {'true' if config.encyclopedia_enabled else 'false'},
'aitoolkitEnabled': {'true' if config.aitoolkit_enabled else 'false'},
'oasis': {'true' if config.keycloak.oasis else 'false'}
'oasis': {'true' if config.keycloak.oasis else 'false'},
'version': {json.dumps(config.meta.beta) if config.meta.beta else dict()}
}};''')
# replace base path in all GUI files
......
......@@ -295,7 +295,8 @@ meta = NomadConfig(
homepage='https://nomad-lab.eu',
source_url='https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR',
maintainer_email='markus.scheidgen@physik.hu-berlin.de',
deployment_id='nomad-lab.eu/prod/rae'
deployment_id='nomad-lab.eu/prod/rae',
beta=None
)
gitlab = NomadConfig(
......@@ -317,7 +318,7 @@ metadata_file_name = 'nomad'
metadata_file_extensions = ('json', 'yaml', 'yml')
enable_lazy_import = True
encyclopedia_enabled = True
aitoolkit_enabled = True
aitoolkit_enabled = False
def normalize_loglevel(value, default_level=logging.INFO):
......
version:
label: "v0.9.8"
label: "v0.10.9"
isBeta: true
usesBetaData: false
officialUrl: "https://nomad-lab.eu/prod/rae/gui"
......@@ -17,10 +17,6 @@ proxy:
gui:
debug: true
matomoEnabled: false
matomoSiteId: 2
encyclopediaEnabled: true
aitoolkitEnabled: true
app:
replicas: 2
......
version:
label: "v0.9.8"
label: "v0.10.9"
isBeta: true
usesBetaData: false
officialUrl: "https://nomad-lab.eu/prod/rae/gui"
......@@ -17,10 +17,6 @@ proxy:
gui:
debug: true
matomoEnabled: false
matomoSiteId: 2
encyclopediaEnabled: true
aitoolkitEnabled: true
app:
replicas: 1
......
......@@ -74,55 +74,6 @@ data:
worker_connections = 1000
workers = {{ .Values.app.worker }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "nomad.fullname" . }}-gui-env-js
labels:
app.kubernetes.io/name: {{ include "nomad.name" . }}-gui-env-js
helm.sh/chart: {{ include "nomad.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
data:
env.js: |
window.nomadEnv = {
"appBase": "{{ .Values.proxy.external.path }}",
"keycloakBase": "{{ .Values.keycloak.serverExternalUrl }}",
"keycloakRealm": "{{ .Values.keycloak.realmName }}",
"keycloakClientId": "{{ .Values.keycloak.guiClientId }}",
"matomoSiteId": {{ .Values.gui.matomoSiteId }},
"matomoUrl": "{{ .Values.gui.matomoUrl }}",
"matomoEnabled": {{ .Values.gui.matomoEnabled }},
"debug": {{ .Values.gui.debug }},
"version": {
"label": "{{ .Values.version.label }}",
"isBeta": {{ .Values.version.isBeta }},
"isTest": {{ .Values.version.isTest }},
"usesBetaData": {{ .Values.version.usesBetaData }},
"officialUrl": "{{ .Values.version.officialUrl }}"
},
"encyclopediaEnabled": {{ .Values.gui.encyclopediaEnabled }},
"aitoolkitEnabled": {{ .Values.gui.aitoolkitEnabled }}
};
---