Commit 460e625f authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Misc. bug-fixes to upload and dataset page. #706

parent cfacafb6
Pipeline #120758 passed with stages
in 40 minutes and 34 seconds
window.nomadEnv = {
'keycloakBase': 'https://nomad-lab.eu/fairdi/keycloak/auth/',
// Use the production API
// 'keycloakRealm': 'fairdi_nomad_prod',
// 'keycloakClientId': 'nomad_public',
// 'appBase': 'https://nomad-lab.eu/prod/v1',
// Use the local API
'keycloakRealm': 'fairdi_nomad_test',
'keycloakClientId': 'nomad_gui_dev',
'appBase': 'http://localhost:8000/fairdi/nomad/latest',
......
......@@ -26,7 +26,8 @@ import DeleteIcon from '@material-ui/icons/Delete'
import DOIIcon from '@material-ui/icons/Bookmark'
import { DatasetButton } from '../nav/Routes'
import {
addColumnDefaults, combinePagination, Datatable, DatatableLoadMorePagination,
addColumnDefaults, combinePagination, Datatable,
DatatablePagePagination,
DatatableTable, DatatableToolbar } from '../datatable/Datatable'
import Quantity from '../Quantity'
import DialogContentText from '@material-ui/core/DialogContentText'
......@@ -105,7 +106,6 @@ const DatasetActions = React.memo(function VisitDatasetAction({data}) {
</Tooltip>
<Dialog
open={openConfirmDeleteDialog}
aria-describedby="alert-dialog-description"
>
<DialogContent>
<DialogContentText id="alert-dialog-description">
......@@ -140,7 +140,7 @@ DatasetActions.propTypes = {
}
function DatasetsPage() {
const {api} = useApi()
const {api, user} = useApi()
const errors = useErrors()
const [apiData, setApiData] = useState(null)
const data = useMemo(() => apiData?.response, [apiData])
......@@ -148,16 +148,19 @@ function DatasetsPage() {
page_size: 10,
page: 1,
order_by: 'dataset_create_time',
order: 'asc'
order: 'desc'
})
const load = useCallback(() => {
if (!user) {
return
}
const {page_size, page, order_by, order} = pagination
const url = `/datasets/?page_size=${page_size}&page=${page}&order_by=${order_by}&order=${order}`
const url = `/datasets/?page_size=${page_size}&page=${page}&order_by=${order_by}&order=${order}&user_id=${user.sub}`
api.get(url, null, {returnRequest: true})
.then(setApiData)
.catch(errors.raiseError)
}, [pagination, setApiData, errors, api])
}, [pagination, setApiData, errors, api, user])
useEffect(() => {
load()
......@@ -180,7 +183,7 @@ function DatasetsPage() {
</SourceApiDialogButton>
</DatatableToolbar>
<DatatableTable actions={DatasetActions}>
<DatatableLoadMorePagination />
<DatatablePagePagination />
</DatatableTable>
</Datatable>
</Paper>
......
......@@ -121,7 +121,7 @@ export const DatatablePagePagination = React.memo(function DatatablePagePaginati
rowsPerPage={pagination.page_size}
page={pagination.page - 1}
onPageChange={handleChangePage}
onChangeRowsPerPage={handleChangeRowsPerPage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
})
DatatablePagePagination.propTypes = {
......@@ -392,7 +392,7 @@ const DatatableRow = React.memo(function DatatableRow({data, selected, uncollaps
</>
})
DatatableRow.propTypes = {
data: PropTypes.object.isRequired,
data: PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired,
selected: PropTypes.bool,
uncollapsed: PropTypes.bool,
onRowUncollapsed: PropTypes.func.isRequired,
......@@ -701,7 +701,7 @@ Datatable.propTypes = {
shownColumns: PropTypes.arrayOf(PropTypes.string),
sortingColumns: PropTypes.arrayOf(PropTypes.string),
/** Optional table data as array of objects. Default is empty table. */
data: PropTypes.arrayOf(PropTypes.object),
data: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.object, PropTypes.string])),
/** Optional pagination object (e.g. from NOMAD API). Used to display current pagination
* and ordering information. Either based on page (if using DatatablePagePagination) or
* page_after_value (if using DatatableScrollPagination). */
......
......@@ -294,7 +294,7 @@ function EditMembersDialog({...props}) {
<MembersIcon/>
</Tooltip>
</IconButton>
{open && <Dialog classes={{paper: classes.dialog}} open={open} on disableBackdropClick disableEscapeKeyDown>
{open && <Dialog classes={{paper: classes.dialog}} open={open} disableEscapeKeyDown>
<DialogTitle>Manage upload members</DialogTitle>
<DialogContent>
<DialogContentText>
......
......@@ -293,12 +293,13 @@ const ReferencesActions = React.memo((props) => {
</Box>
})
ReferencesActions.propTypes = {
data: PropTypes.object.isRequired
data: PropTypes.string.isRequired
}
function EditDatasets() {
const {data, api, raiseError, setIsDatasetChanged, setDatasets, defaultDatasets, setDefaultDatasets} = useContext(editMetaDataDialogContext)
const [suggestions, setSuggestions] = useState([])
const {data, setIsDatasetChanged, setDatasets, defaultDatasets, setDefaultDatasets} = useContext(editMetaDataDialogContext)
const {api, user} = useApi()
const {raiseError} = useErrors()
const [validation, setValidation] = useState('')
const [allDatasets, setAllDatasets] = useState([])
const [newDataset, setNewDataset] = useState({dataset_id: '', dataset_name: ''})
......@@ -312,7 +313,7 @@ function EditDatasets() {
]), [])
useEffect(() => {
api.get(`/datasets?page_size=${1000}&page=${1}`)
api.get(`/datasets/?page_size=${1000}&page=${1}&user_id=${user.sub}`)
.then(datasets => {
setAllDatasets(datasets?.data)
})
......@@ -320,7 +321,7 @@ function EditDatasets() {
setAllDatasets([])
raiseError(err)
})
}, [api, raiseError])
}, [api, user, raiseError, setAllDatasets])
const checkChanges = useCallback((_datasets) => {
let isSame = defaultDatasets.length === _datasets.length &&
......@@ -328,12 +329,6 @@ function EditDatasets() {
setIsDatasetChanged(!isSame)
}, [defaultDatasets, setIsDatasetChanged])
const handleInputChange = useCallback((event, value) => {
const query = value.toLowerCase()
const withQueryInName = (allDatasets ? allDatasets.filter(dataset => dataset.dataset_name.toLowerCase().indexOf(query) !== -1) : [])
setSuggestions(withQueryInName.slice(0, 5))
}, [allDatasets])
useEffect(() => {
if (data?.data?.length > 0) {
let _datasets = data?.data[0]?.entry_metadata?.datasets
......@@ -448,15 +443,16 @@ function EditDatasets() {
</Box>
<AutoComplete
style={{width: '100%'}}
options={suggestions}
options={allDatasets}
getOptionLabel={option => option.dataset_name}
onInputChange={handleInputChange}
onChange={handleAutoCompleteChange}
renderInput={params => (
<TextField
{...params}
variant='filled' label='Search for an existing dataset' placeholder='Dataset name' argin='normal' fullWidth size='small'
error={isDuplicated || apiValidation} helperText={(isDuplicated ? 'The data is already in the selected dataset' : apiValidation)}
variant='filled' label='Search for an existing dataset'
placeholder='Dataset name' margin='normal' fullWidth size='small'
error={isDuplicated || apiValidation !== ''}
helperText={(isDuplicated ? 'The data is already in the selected dataset' : apiValidation)}
/>
)}
/>
......@@ -626,8 +622,8 @@ function EditMetaDataDialog({...props}) {
{!isIcon && <Button onClick={handleOpenDialog} variant='contained' color='primary' disabled={isProcessing}>
{upload?.entries && (upload?.entries > 1 ? `Edit author metadata of all ${upload?.entries} entries` : `Edit author metadata of all the entries`)}
</Button>}
{open && <Dialog classes={{paper: classes.dialog}} open={open} on disableBackdropClick disableEscapeKeyDown>
<DialogTitle>Manage upload meta data</DialogTitle>
{open && <Dialog classes={{paper: classes.dialog}} open={open} disableEscapeKeyDown>
<DialogTitle>Edit upload meta data</DialogTitle>
<DialogContent>
<DialogContentText>
You can add, remove or edit the meta data for the selected entries.
......@@ -670,7 +666,7 @@ function EditMetaDataDialog({...props}) {
}
EditMetaDataDialog.propTypes = {
isIcon: PropTypes.bool,
selectedEntries: PropTypes.arrayOf(PropTypes.object)
selectedEntries: PropTypes.object
}
export default EditMetaDataDialog
......@@ -167,6 +167,7 @@ UploadName.propTypes = {
function PublishUpload({upload, onPublish}) {
const [embargo, setEmbargo] = useState(upload.embargo_length === undefined ? 0 : upload.embargo_length)
const [openConfirmDialog, setOpenConfirmDialog] = useState(false)
const handlePublish = () => {
onPublish({embargo_length: embargo})
}
......@@ -177,7 +178,25 @@ function PublishUpload({upload, onPublish}) {
`}</Markdown>
}
const buttonLabel = embargo > 0 ? 'Publish with embargo' : 'Publish'
return <React.Fragment>
<Dialog
open={openConfirmDialog}
onClose={() => setOpenConfirmDialog(false)}
>
<DialogTitle>Confirm that you want to publish the upload</DialogTitle>
<DialogContent>
<DialogContentText>
You are about the publish this upload. The upload cannot be removed and
the files and entries in this upload cannot be changed after publication.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpenConfirmDialog(false)} autoFocus>Cancel</Button>
<Button onClick={handlePublish}>{buttonLabel}</Button>
</DialogActions>
</Dialog>
<Markdown>{`
If you agree this upload will be published and move out of your private staging
area into the public NOMAD. This step is final. All public data will be made available under the Creative
......@@ -224,10 +243,10 @@ function PublishUpload({upload, onPublish}) {
<Button
style={{height: 32, minWith: 100}}
size="small" variant="contained"
onClick={() => handlePublish()} color="primary"
onClick={() => setOpenConfirmDialog(true)} color="primary"
disabled={upload.process_running}
>
{embargo > 0 ? 'Publish with embargo' : 'Publish'}
{buttonLabel}
</Button>
</Box>
</Grid>
......
......@@ -144,7 +144,7 @@ async def get_datasets(
request: Request,
dataset_id: str = FastApiQuery(None),
dataset_name: str = FastApiQuery(None),
user_id: str = FastApiQuery(None),
user_id: List[str] = FastApiQuery(None),
dataset_type: str = FastApiQuery(None),
doi: str = FastApiQuery(None),
prefix: str = FastApiQuery(None),
......@@ -152,8 +152,9 @@ async def get_datasets(
'''
Retrieves all datasets that match the given criteria.
'''
mongodb_objects = DatasetDefinitionCls.m_def.a_mongo.objects
query_params = dict(dataset_id=dataset_id, dataset_name=dataset_name, user_id=user_id, dataset_type=dataset_type, doi=doi)
query_params = dict(dataset_id=dataset_id, dataset_name=dataset_name, user_id__in=user_id, dataset_type=dataset_type, doi=doi)
if prefix is not None and prefix != '':
query_params.update(dataset_name=re.compile('^%s.*' % prefix, re.IGNORECASE)) # type: ignore
query_params = {k: v for k, v in query_params.items() if v is not None}
......
Supports Markdown
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