Commit dee1049c authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Various minor fixes revolvig arround datasets. #303 #345

parent dff91c97
Pipeline #74720 passed with stages
in 21 minutes and 23 seconds
...@@ -3,8 +3,8 @@ import { errorContext } from './errors' ...@@ -3,8 +3,8 @@ import { errorContext } from './errors'
import { apiContext } from './api' import { apiContext } from './api'
import Search from './search/Search' import Search from './search/Search'
import { Typography, makeStyles } from '@material-ui/core' import { Typography, makeStyles } from '@material-ui/core'
import { DatasetActions, DOI } from './search/DatasetList' import { matchPath, useLocation, useRouteMatch } from 'react-router'
import { matchPath, useLocation, useHistory, useRouteMatch } from 'react-router' import { DOI } from './search/DatasetList'
export const help = ` export const help = `
This page allows you to **inspect** and **download** NOMAD datasets. It alsow allows you This page allows you to **inspect** and **download** NOMAD datasets. It alsow allows you
...@@ -31,7 +31,6 @@ export default function DatasetPage() { ...@@ -31,7 +31,6 @@ export default function DatasetPage() {
const {raiseError} = useContext(errorContext) const {raiseError} = useContext(errorContext)
const location = useLocation() const location = useLocation()
const match = useRouteMatch() const match = useRouteMatch()
const history = useHistory()
const {datasetId} = matchPath(location.pathname, { const {datasetId} = matchPath(location.pathname, {
path: `${match.path}/:datasetId` path: `${match.path}/:datasetId`
...@@ -56,18 +55,11 @@ export default function DatasetPage() { ...@@ -56,18 +55,11 @@ export default function DatasetPage() {
}) })
}, [location.pathname, api]) }, [location.pathname, api])
const handleChange = dataset => {
if (dataset) {
setDataset({dataset: dataset})
} else {
history.goBack()
}
}
if (!dataset) { if (!dataset) {
return <div>loading...</div> return <div>loading...</div>
} }
console.log('### DatasetPage', dataset)
return <div> return <div>
<div className={classes.header}> <div className={classes.header}>
<div className={classes.description}> <div className={classes.description}>
...@@ -76,18 +68,11 @@ export default function DatasetPage() { ...@@ -76,18 +68,11 @@ export default function DatasetPage() {
dataset{dataset.doi ? <span>, with DOI <DOI doi={dataset.doi} /></span> : ''} dataset{dataset.doi ? <span>, with DOI <DOI doi={dataset.doi} /></span> : ''}
</Typography> </Typography>
</div> </div>
<div className={classes.actions}>
{dataset && dataset.example && <DatasetActions
dataset={dataset}
onChange={handleChange}/>
}
</div>
</div> </div>
<Search <Search
initialQuery={{owner: 'all'}} initialQuery={{owner: 'all'}}
query={{dataset_id: datasetId}} query={{dataset_id: [datasetId]}}
ownerTypes={['all', 'public']} ownerTypes={['all', 'public']}
initialResultTab="entries" initialResultTab="entries"
availableResultTabs={['entries', 'groups', 'datasets']} availableResultTabs={['entries', 'groups', 'datasets']}
......
...@@ -125,7 +125,7 @@ function handleApiError(e) { ...@@ -125,7 +125,7 @@ function handleApiError(e) {
let error = null let error = null
if (e.response) { if (e.response) {
const body = e.response.body const body = e.response.body
const message = (body && (body.description || body.message)) || e.response.statusText const message = (body && (body.message || body.description)) || e.response.statusText
const errorMessage = `${message} (${e.response.status})` const errorMessage = `${message} (${e.response.status})`
if (e.response.status === 404) { if (e.response.status === 404) {
error = new DoesNotExist(errorMessage) error = new DoesNotExist(errorMessage)
......
...@@ -131,7 +131,7 @@ class DatasetActionsUnstyled extends React.Component { ...@@ -131,7 +131,7 @@ class DatasetActionsUnstyled extends React.Component {
const canAssignDOI = !doi const canAssignDOI = !doi
const canDelete = !doi const canDelete = !doi
const query = {dataset_id: dataset.id} const query = {dataset_id: [dataset.dataset_id]}
return <FormGroup row classes={{root: classes.group}}> return <FormGroup row classes={{root: classes.group}}>
{search && <Tooltip title="Open a search page with entries from this dataset only."> {search && <Tooltip title="Open a search page with entries from this dataset only.">
...@@ -180,6 +180,7 @@ class DatasetListUnstyled extends React.Component { ...@@ -180,6 +180,7 @@ class DatasetListUnstyled extends React.Component {
data: PropTypes.object, data: PropTypes.object,
total: PropTypes.number, total: PropTypes.number,
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
onEdit: PropTypes.func.isRequired,
history: PropTypes.any.isRequired, history: PropTypes.any.isRequired,
datasets_after: PropTypes.string, datasets_after: PropTypes.string,
per_page: PropTypes.number, per_page: PropTypes.number,
...@@ -243,8 +244,8 @@ class DatasetListUnstyled extends React.Component { ...@@ -243,8 +244,8 @@ class DatasetListUnstyled extends React.Component {
} }
renderEntryActions(entry) { renderEntryActions(entry) {
const {onChange} = this.props const {onEdit} = this.props
return <DatasetActions search dataset={entry} onChange={() => onChange({})} /> return <DatasetActions search dataset={entry} onChange={onEdit} />
} }
render() { render() {
......
...@@ -21,7 +21,7 @@ export function Published(props) { ...@@ -21,7 +21,7 @@ export function Published(props) {
</Tooltip> </Tooltip>
} else { } else {
return <Tooltip title="not published yet"> return <Tooltip title="not published yet">
<PrivateIcon color="secondary"/> <PrivateIcon color="error"/>
</Tooltip> </Tooltip>
} }
} }
...@@ -32,6 +32,7 @@ export class EntryListUnstyled extends React.Component { ...@@ -32,6 +32,7 @@ export class EntryListUnstyled extends React.Component {
data: PropTypes.object.isRequired, data: PropTypes.object.isRequired,
query: PropTypes.object.isRequired, query: PropTypes.object.isRequired,
onChange: PropTypes.func, onChange: PropTypes.func,
onEdit: PropTypes.func,
history: PropTypes.any.isRequired, history: PropTypes.any.isRequired,
order_by: PropTypes.string.isRequired, order_by: PropTypes.string.isRequired,
order: PropTypes.number.isRequired, order: PropTypes.number.isRequired,
...@@ -236,7 +237,7 @@ export class EntryListUnstyled extends React.Component { ...@@ -236,7 +237,7 @@ export class EntryListUnstyled extends React.Component {
{(row.datasets || []).map(ds => ( {(row.datasets || []).map(ds => (
<Typography key={ds.dataset_id}> <Typography key={ds.dataset_id}>
<Link component={RouterLink} to={`/dataset/id/${ds.dataset_id}`}>{ds.name}</Link> <Link component={RouterLink} to={`/dataset/id/${ds.dataset_id}`}>{ds.name}</Link>
{ds.doi ? <span>&nbsp; (<Link href={ds.doi}>{ds.doi}</Link>)</span> : <React.Fragment/>} {ds.doi ? <span>&nbsp; (<Link href={`https://dx.doi.org/${ds.doi}`}>{ds.doi}</Link>)</span> : <React.Fragment/>}
</Typography>))} </Typography>))}
</div> </div>
</Quantity> </Quantity>
...@@ -321,7 +322,7 @@ export class EntryListUnstyled extends React.Component { ...@@ -321,7 +322,7 @@ export class EntryListUnstyled extends React.Component {
const createActions = (props, moreActions) => <React.Fragment> const createActions = (props, moreActions) => <React.Fragment>
{example && editable ? <EditUserMetadataDialog {example && editable ? <EditUserMetadataDialog
example={example} total={selected === null ? totalNumber : selected.length} example={example} total={selected === null ? totalNumber : selected.length}
onEditComplete={() => this.props.onChange()} onEditComplete={() => this.props.onEdit()}
{...props} {...props}
/> : ''} /> : ''}
<DownloadButton <DownloadButton
......
...@@ -549,13 +549,14 @@ const useScroll = (apiGroupName, afterParameterName) => { ...@@ -549,13 +549,14 @@ const useScroll = (apiGroupName, afterParameterName) => {
} }
function SearchEntryList(props) { function SearchEntryList(props) {
const {response, requestParameters, apiQuery} = useContext(searchContext) const {response, requestParameters, apiQuery, update} = useContext(searchContext)
const setRequestParameters = usePagination() const setRequestParameters = usePagination()
return <EntryList return <EntryList
query={apiQuery} query={apiQuery}
editable={apiQuery.owner === 'staging' || apiQuery.owner === 'user'} editable={apiQuery.owner === 'staging' || apiQuery.owner === 'user'}
data={response} data={response}
onChange={setRequestParameters} onChange={setRequestParameters}
onEdit={update}
actions={ actions={
<React.Fragment> <React.Fragment>
<ReRunSearchButton/> <ReRunSearchButton/>
...@@ -568,9 +569,10 @@ function SearchEntryList(props) { ...@@ -568,9 +569,10 @@ function SearchEntryList(props) {
} }
function SearchDatasetList(props) { function SearchDatasetList(props) {
const {response} = useContext(searchContext) const {response, update} = useContext(searchContext)
return <DatasetList return <DatasetList
data={response} data={response}
onEdit={update}
actions={<ReRunSearchButton/>} actions={<ReRunSearchButton/>}
{...response} {...props} {...useScroll('datasets')} {...response} {...props} {...useScroll('datasets')}
/> />
...@@ -586,8 +588,9 @@ function SearchGroupList(props) { ...@@ -586,8 +588,9 @@ function SearchGroupList(props) {
} }
function SearchUploadList(props) { function SearchUploadList(props) {
const {response} = useContext(searchContext) const {response, update} = useContext(searchContext)
return <UploadList data={response} return <UploadList data={response}
onEdit={update}
actions={<ReRunSearchButton/>} actions={<ReRunSearchButton/>}
{...response} {...props} {...useScroll('uploads')} {...response} {...props} {...useScroll('uploads')}
/> />
......
...@@ -150,7 +150,7 @@ export default function SearchContext({initialRequest, initialQuery, query, chil ...@@ -150,7 +150,7 @@ export default function SearchContext({initialRequest, initialQuery, query, chil
owner: owner, owner: owner,
...initialQuery, ...initialQuery,
...requestRef.current.query, ...requestRef.current.query,
query ...query
} }
if (dateHistogram) { if (dateHistogram) {
dateHistogramInterval = Dates.intervalSeconds( dateHistogramInterval = Dates.intervalSeconds(
......
...@@ -53,7 +53,7 @@ class UploadActionsUnstyled extends React.Component { ...@@ -53,7 +53,7 @@ class UploadActionsUnstyled extends React.Component {
classes: PropTypes.object.isRequired, classes: PropTypes.object.isRequired,
upload: PropTypes.object.isRequired, upload: PropTypes.object.isRequired,
user: PropTypes.object, user: PropTypes.object,
onChange: PropTypes.func, onEdit: PropTypes.func,
history: PropTypes.object.isRequired history: PropTypes.object.isRequired
} }
...@@ -71,9 +71,9 @@ class UploadActionsUnstyled extends React.Component { ...@@ -71,9 +71,9 @@ class UploadActionsUnstyled extends React.Component {
} }
handleEdit() { handleEdit() {
const {onChange, upload} = this.props const {onEdit, upload} = this.props
if (onChange) { if (onEdit) {
onChange(upload) onEdit(upload)
} }
} }
...@@ -86,7 +86,7 @@ class UploadActionsUnstyled extends React.Component { ...@@ -86,7 +86,7 @@ class UploadActionsUnstyled extends React.Component {
const editable = user && upload.example && const editable = user && upload.example &&
upload.example.authors.find(author => author.user_id === user.sub) upload.example.authors.find(author => author.user_id === user.sub)
const query = {upload_id: upload.example.upload_id} const query = {upload_id: [upload.example.upload_id]}
return <FormGroup row classes={{root: classes.group}}> return <FormGroup row classes={{root: classes.group}}>
<Tooltip title="Open this upload on the uploads page"> <Tooltip title="Open this upload on the uploads page">
...@@ -112,6 +112,7 @@ class UploadListUnstyled extends React.Component { ...@@ -112,6 +112,7 @@ class UploadListUnstyled extends React.Component {
data: PropTypes.object, data: PropTypes.object,
total: PropTypes.number, total: PropTypes.number,
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
onEdit: PropTypes.func.isRequired,
history: PropTypes.any.isRequired, history: PropTypes.any.isRequired,
uploads_after: PropTypes.string, uploads_after: PropTypes.string,
actions: PropTypes.element actions: PropTypes.element
...@@ -176,8 +177,8 @@ class UploadListUnstyled extends React.Component { ...@@ -176,8 +177,8 @@ class UploadListUnstyled extends React.Component {
} }
renderEntryActions(entry) { renderEntryActions(entry) {
const {onChange} = this.props const {onEdit} = this.props
return <UploadActions search upload={entry} onChange={() => onChange({})} /> return <UploadActions search upload={entry} onEdit={onEdit}/>
} }
render() { render() {
......
...@@ -171,7 +171,7 @@ class Upload extends React.Component { ...@@ -171,7 +171,7 @@ class Upload extends React.Component {
cursor: 'pointer' cursor: 'pointer'
}, },
decideIcon: { decideIcon: {
color: theme.palette.secondary.main color: theme.palette.error.main
} }
}) })
...@@ -605,12 +605,13 @@ class Upload extends React.Component { ...@@ -605,12 +605,13 @@ class Upload extends React.Component {
return <EntryList return <EntryList
title={`Upload with ${data.pagination.total} detected entries`} title={`Upload with ${data.pagination.total} detected entries`}
query={{upload_id: upload.upload_id}} query={{upload_id: [upload.upload_id]}}
columns={columns} columns={columns}
selectedColumns={Upload.defaultSelectedColumns} selectedColumns={Upload.defaultSelectedColumns}
editable={tasks_status === 'SUCCESS'} editable={tasks_status === 'SUCCESS'}
data={data} data={data}
onChange={this.handleChange} onChange={this.handleChange}
onEdit={this.handleChange}
actions={actions} actions={actions}
showEntryActions={entry => entry.processed || !running} showEntryActions={entry => entry.processed || !running}
{...this.state.params} {...this.state.params}
...@@ -634,7 +635,7 @@ class Upload extends React.Component { ...@@ -634,7 +635,7 @@ class Upload extends React.Component {
} else if (upload.published) { } else if (upload.published) {
return render(<PublishedIcon size={32} color="primary"/>, 'This upload is published') return render(<PublishedIcon size={32} color="primary"/>, 'This upload is published')
} else { } else {
return render(<UnPublishedIcon size={32} color="secondary"/>, 'This upload is not published yet, and only visible to you') return render(<UnPublishedIcon size={32} color="error"/>, 'This upload is not published yet, and only visible to you')
} }
} }
......
...@@ -554,7 +554,7 @@ class EditRepoCalcsResource(Resource): ...@@ -554,7 +554,7 @@ class EditRepoCalcsResource(Resource):
# remove potentially empty old datasets # remove potentially empty old datasets
if removed_datasets is not None: if removed_datasets is not None:
for dataset in removed_datasets: for dataset in removed_datasets:
if proc.Calc.objects(metadata__dataset_id=dataset).first() is None: if proc.Calc.objects(metadata__datasets=dataset).first() is None:
Dataset.m_def.a_mongo.objects(dataset_id=dataset).delete() Dataset.m_def.a_mongo.objects(dataset_id=dataset).delete()
return json_data, 200 return json_data, 200
......
...@@ -193,7 +193,7 @@ def chown(ctx, username, uploads): ...@@ -193,7 +193,7 @@ def chown(ctx, username, uploads):
search.refresh() search.refresh()
@uploads.command(help='Change the owner of the upload and all its calcs.') @uploads.command(help='Reset the processing state.')
@click.argument('UPLOADS', nargs=-1) @click.argument('UPLOADS', nargs=-1)
@click.option('--with-calcs', is_flag=True, help='Also reset all calculations.') @click.option('--with-calcs', is_flag=True, help='Also reset all calculations.')
@click.pass_context @click.pass_context
...@@ -209,6 +209,7 @@ def reset(ctx, uploads, with_calcs): ...@@ -209,6 +209,7 @@ def reset(ctx, uploads, with_calcs):
dict(upload_id=upload.upload_id), dict(upload_id=upload.upload_id),
{'$set': proc.Calc.reset_pymongo_update()}) {'$set': proc.Calc.reset_pymongo_update()})
upload.process_status = None
upload.reset() upload.reset()
upload.save() upload.save()
i += 1 i += 1
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment