@openneuro/app 4.19.2 → 4.20.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +11 -22
- package/src/client.jsx +0 -1
- package/src/scripts/authentication/__tests__/profile.spec.js +1 -1
- package/src/scripts/authentication/admin-user.jsx +1 -1
- package/src/scripts/authentication/loginCheck.js +1 -1
- package/src/scripts/authentication/{profile.js → profile.ts} +12 -2
- package/src/scripts/authentication/regular-user.tsx +1 -1
- package/src/scripts/authentication/withProfile.jsx +1 -1
- package/src/scripts/common/forms/__tests__/__snapshots__/warn-button.spec.jsx.snap +1 -1
- package/src/scripts/components/__tests__/__snapshots__/data-table.spec.tsx.snap +84 -0
- package/src/scripts/components/__tests__/data-table.spec.tsx +15 -0
- package/src/scripts/components/data-table.tsx +125 -0
- package/src/scripts/datalad/subscriptions/__tests__/__snapshots__/files-subscription.spec.jsx.snap +1 -1
- package/src/scripts/dataset/__tests__/__snapshots__/snapshot-container.spec.tsx.snap +3 -3
- package/src/scripts/dataset/comments/__tests__/__snapshots__/comment.spec.jsx.snap +1 -1
- package/src/scripts/dataset/comments/__tests__/__snapshots__/comments.spec.jsx.snap +1 -1
- package/src/scripts/dataset/common/follow-toggles.tsx +2 -0
- package/src/scripts/dataset/dataset-query.jsx +2 -109
- package/src/scripts/dataset/download/__tests__/__snapshots__/download-command-line.spec.jsx.snap +1 -1
- package/src/scripts/dataset/download/__tests__/__snapshots__/download-link.spec.jsx.snap +1 -1
- package/src/scripts/dataset/download/__tests__/__snapshots__/shell-example.spec.jsx.snap +1 -1
- package/src/scripts/dataset/draft-container.tsx +2 -2
- package/src/scripts/dataset/files/__tests__/__snapshots__/file-tree.spec.jsx.snap +1 -1
- package/src/scripts/dataset/files/__tests__/__snapshots__/file.spec.jsx.snap +1 -1
- package/src/scripts/dataset/files/file.tsx +3 -2
- package/src/scripts/dataset/files/viewers/__tests__/__snapshots__/file-viewer-json.spec.jsx.snap +1 -1
- package/src/scripts/dataset/files/viewers/file-viewer-csv.jsx +1 -1
- package/src/scripts/dataset/files/viewers/file-viewer-table.tsx +18 -0
- package/src/scripts/dataset/files/viewers/file-viewer-tsv.jsx +1 -1
- package/src/scripts/dataset/fragments/__tests__/__snapshots__/cancel-button.spec.tsx.snap +1 -1
- package/src/scripts/dataset/fragments/__tests__/__snapshots__/edit-button.spec.tsx.snap +1 -1
- package/src/scripts/dataset/fragments/__tests__/__snapshots__/edit-list.spec.jsx.snap +1 -1
- package/src/scripts/dataset/fragments/__tests__/__snapshots__/save-button.spec.tsx.snap +1 -1
- package/src/scripts/dataset/fragments/__tests__/__snapshots__/select-input.spec.tsx.snap +1 -1
- package/src/scripts/dataset/fragments/comments-fragments.js +2 -1
- package/src/scripts/dataset/fragments/text-input.tsx +1 -1
- package/src/scripts/dataset/mutations/__tests__/__snapshots__/delete.spec.jsx.snap +1 -1
- package/src/scripts/dataset/mutations/__tests__/__snapshots__/deprecate-snapshot.spec.tsx.snap +1 -1
- package/src/scripts/dataset/mutations/__tests__/__snapshots__/deprecate-version.spec.tsx.snap +1 -1
- package/src/scripts/dataset/mutations/__tests__/__snapshots__/description.spec.jsx.snap +1 -1
- package/src/scripts/dataset/mutations/__tests__/__snapshots__/update-permissions.spec.jsx.snap +1 -1
- package/src/scripts/dataset/mutations/comment.jsx +1 -1
- package/src/scripts/dataset/mutations/delete-anonymous-reviewer.tsx +4 -1
- package/src/scripts/dataset/mutations/snapshot.tsx +10 -2
- package/src/scripts/dataset/routes/add-metadata.jsx +1 -1
- package/src/scripts/dataset/routes/delete-page.tsx +1 -1
- package/src/scripts/dataset/routes/manage-permissions.jsx +1 -2
- package/src/scripts/dataset/routes/{snapshot.jsx → snapshot.tsx} +8 -11
- package/src/scripts/dataset/routes/styles/dataset-page-border.tsx +2 -0
- package/src/scripts/dataset/routes/styles/dataset-page-tab-container.tsx +2 -0
- package/src/scripts/dataset/routes/styles/header-row.tsx +2 -0
- package/src/scripts/dataset/routes/tab-routes-draft.tsx +1 -1
- package/src/scripts/dataset/snapshot-container.tsx +2 -2
- package/src/scripts/pages/admin/user-tools.tsx +1 -1
- package/src/scripts/pages/faq/faq.tsx +8 -0
- package/src/scripts/pages/metadata/dataset-metadata.tsx +86 -0
- package/src/scripts/queries/dataset.ts +113 -0
- package/src/scripts/routes.tsx +2 -0
- package/src/scripts/search/__helpers__/search-render.tsx +1 -0
- package/src/scripts/search/initial-search-params.tsx +1 -1
- package/src/scripts/search/search-routes.tsx +1 -1
- package/src/scripts/search/use-search-results.tsx +1 -1
- package/src/scripts/styles/media.tsx +2 -0
- package/src/scripts/utils/__tests__/csv.spec.ts +41 -0
- package/src/scripts/utils/csv.ts +41 -0
- package/src/scripts/utils/schema-validator.js +1 -1
- package/src/scripts/dataset/files/viewers/file-viewer-table.jsx +0 -35
- package/src/scripts/pages/faq/__tests__/__snapshots__/faq.spec.jsx.snap +0 -302
- package/src/scripts/pages/faq/__tests__/faq.spec.jsx +0 -10
- package/src/scripts/pages/faq/faq-content.js +0 -121
- package/src/scripts/pages/faq/faq.jsx +0 -16
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { DataTable } from '../../../components/data-table'
|
|
3
|
+
import styled from '@emotion/styled'
|
|
4
|
+
|
|
5
|
+
const TableOverlow = styled.div`
|
|
6
|
+
overflow-x: scroll;
|
|
7
|
+
height: 64vh;
|
|
8
|
+
`
|
|
9
|
+
|
|
10
|
+
const FileViewerTable = ({ tableData }): React.ReactElement => {
|
|
11
|
+
return (
|
|
12
|
+
<TableOverlow>
|
|
13
|
+
<DataTable data={tableData}></DataTable>
|
|
14
|
+
</TableOverlow>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default FileViewerTable
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import parseTabular from './parse-tabular.js'
|
|
4
|
-
import FileViewerTable from './file-viewer-table
|
|
4
|
+
import FileViewerTable from './file-viewer-table'
|
|
5
5
|
|
|
6
6
|
const FileViewerTsv = ({ data }) => {
|
|
7
7
|
const decoder = new TextDecoder()
|
|
@@ -107,7 +107,7 @@ const TextInput = ({
|
|
|
107
107
|
required,
|
|
108
108
|
onChange,
|
|
109
109
|
}): React.ReactElement => {
|
|
110
|
-
if (value === null) {
|
|
110
|
+
if (value === null || value === undefined) {
|
|
111
111
|
if (nullMessage) value = nullMessage
|
|
112
112
|
else value = ''
|
|
113
113
|
} else value = value.toString()
|
|
@@ -70,7 +70,7 @@ export const newCommentsReducer = (
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
|
-
* Modify an
|
|
73
|
+
* Modify an existing comment and return new state based on arguments
|
|
74
74
|
* @param {Object[]} comments
|
|
75
75
|
* @param {Object} arguments
|
|
76
76
|
* @param {string} arguments.commentId
|
|
@@ -20,10 +20,13 @@ interface DeleteReviewerLinkProps {
|
|
|
20
20
|
export const DeleteReviewerLink: FC<DeleteReviewerLinkProps> = ({
|
|
21
21
|
datasetId,
|
|
22
22
|
id,
|
|
23
|
+
}: {
|
|
24
|
+
datasetId: string
|
|
25
|
+
id: string
|
|
23
26
|
}) => {
|
|
24
27
|
const [DeleteReviewerLink] = useMutation(DELETE_REVIEWER, {
|
|
25
28
|
update(cache, { data: { deleteReviewer } }) {
|
|
26
|
-
const { reviewers } = cache.readFragment({
|
|
29
|
+
const { reviewers } = cache.readFragment<{ reviewers: any[] }>({
|
|
27
30
|
id: `Dataset:${datasetId}`,
|
|
28
31
|
fragment: DATASET_REVIEWERS,
|
|
29
32
|
})
|
|
@@ -4,12 +4,15 @@ import { gql, useMutation } from '@apollo/client'
|
|
|
4
4
|
import { useNavigate } from 'react-router-dom'
|
|
5
5
|
import ErrorBoundary from '../../errors/errorBoundary.jsx'
|
|
6
6
|
import { Button } from '@openneuro/components/button'
|
|
7
|
+
import { getDatasetPage, getDraftPage } from '../../queries/dataset'
|
|
7
8
|
|
|
8
9
|
const CREATE_SNAPSHOT = gql`
|
|
9
10
|
mutation createSnapshot($datasetId: ID!, $tag: String!, $changes: [String!]) {
|
|
10
11
|
createSnapshot(datasetId: $datasetId, tag: $tag, changes: $changes) {
|
|
11
12
|
id
|
|
12
13
|
tag
|
|
14
|
+
created
|
|
15
|
+
hexsha
|
|
13
16
|
}
|
|
14
17
|
}
|
|
15
18
|
`
|
|
@@ -28,7 +31,9 @@ const CreateSnapshotMutation = ({
|
|
|
28
31
|
disabled,
|
|
29
32
|
}: CreateSnapshotMutationProps) => {
|
|
30
33
|
const navigate = useNavigate()
|
|
31
|
-
const [snapshotDataset, { loading, error }] = useMutation(CREATE_SNAPSHOT
|
|
34
|
+
const [snapshotDataset, { loading, error }] = useMutation(CREATE_SNAPSHOT, {
|
|
35
|
+
refetchQueries: [getDatasetPage, getDraftPage],
|
|
36
|
+
})
|
|
32
37
|
|
|
33
38
|
if (error) throw error
|
|
34
39
|
|
|
@@ -42,7 +47,10 @@ const CreateSnapshotMutation = ({
|
|
|
42
47
|
onClick={(): void => {
|
|
43
48
|
void snapshotDataset({
|
|
44
49
|
variables: { datasetId, tag, changes },
|
|
45
|
-
}).then(
|
|
50
|
+
}).then(data => {
|
|
51
|
+
console.log(data)
|
|
52
|
+
navigate(`/datasets/${datasetId}/versions/${tag}`)
|
|
53
|
+
})
|
|
46
54
|
}}
|
|
47
55
|
disabled={disabled}
|
|
48
56
|
label="Create Version"
|
|
@@ -6,7 +6,7 @@ import MetadataForm from '../mutations/metadata-form.jsx'
|
|
|
6
6
|
import { DatasetRelations } from '../mutations/dataset-relations'
|
|
7
7
|
import SubmitMetadata from '../mutations/submit-metadata.jsx'
|
|
8
8
|
import LoggedIn from '../../authentication/logged-in.jsx'
|
|
9
|
-
import { hasEditPermissions, getProfile } from '../../authentication/profile
|
|
9
|
+
import { hasEditPermissions, getProfile } from '../../authentication/profile'
|
|
10
10
|
import { DatasetPageBorder } from './styles/dataset-page-border'
|
|
11
11
|
import { HeaderRow3, HeaderRow4 } from './styles/header-row'
|
|
12
12
|
|
|
@@ -3,7 +3,7 @@ import { useCookies } from 'react-cookie'
|
|
|
3
3
|
import DeleteDatasetForm from '../mutations/delete-dataset-form.jsx'
|
|
4
4
|
import DeleteDataset from '../mutations/delete.jsx'
|
|
5
5
|
import LoggedIn from '../../authentication/logged-in.jsx'
|
|
6
|
-
import { getProfile } from '../../authentication/profile
|
|
6
|
+
import { getProfile } from '../../authentication/profile'
|
|
7
7
|
import AdminUser from '../../authentication/admin-user.jsx'
|
|
8
8
|
import { RegularUser } from '../../authentication/regular-user'
|
|
9
9
|
import { DatasetPageBorder } from './styles/dataset-page-border'
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
|
-
import { Link } from 'react-router-dom'
|
|
4
3
|
import { Button } from '@openneuro/components/button'
|
|
5
4
|
|
|
6
5
|
import { RemovePermissions } from '../mutations/remove-permissions'
|
|
@@ -140,7 +139,7 @@ Share.propTypes = {
|
|
|
140
139
|
datasetId: PropTypes.string,
|
|
141
140
|
permissions: PropTypes.object,
|
|
142
141
|
reviewers: PropTypes.array,
|
|
143
|
-
hasSnapshot: PropTypes.
|
|
142
|
+
hasSnapshot: PropTypes.bool,
|
|
144
143
|
}
|
|
145
144
|
|
|
146
145
|
export default Share
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
|
-
import
|
|
3
|
-
import semver from 'semver'
|
|
2
|
+
import semver, { ReleaseType } from 'semver'
|
|
4
3
|
import SnapshotDataset from '../mutations/snapshot'
|
|
5
4
|
import EditList from '../fragments/edit-list.jsx'
|
|
6
5
|
import { Button } from '@openneuro/components/button'
|
|
@@ -38,7 +37,12 @@ export const NoErrors = ({ issues, children }) => {
|
|
|
38
37
|
}
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
const SnapshotRoute = ({
|
|
40
|
+
const SnapshotRoute = ({
|
|
41
|
+
datasetId,
|
|
42
|
+
snapshots,
|
|
43
|
+
issues,
|
|
44
|
+
description,
|
|
45
|
+
}): React.ReactElement => {
|
|
42
46
|
const [changes, setChanges] = useState([])
|
|
43
47
|
const [semanticLevel, setSemanticLevel] = useState('patch')
|
|
44
48
|
const draftLicense = (description && description.License) || 'none'
|
|
@@ -48,7 +52,7 @@ const SnapshotRoute = ({ datasetId, snapshots, issues, description }) => {
|
|
|
48
52
|
const latestSnapshot = snapshots.length && snapshots[snapshots.length - 1]
|
|
49
53
|
const newVersion =
|
|
50
54
|
snapshots.length && semver.valid(latestSnapshot.tag)
|
|
51
|
-
? semver.inc(latestSnapshot.tag, semanticLevel)
|
|
55
|
+
? semver.inc(latestSnapshot.tag, semanticLevel as ReleaseType)
|
|
52
56
|
: '1.0.0'
|
|
53
57
|
|
|
54
58
|
const majorActive = semanticLevel === 'major' && 'active'
|
|
@@ -138,11 +142,4 @@ const SnapshotRoute = ({ datasetId, snapshots, issues, description }) => {
|
|
|
138
142
|
)
|
|
139
143
|
}
|
|
140
144
|
|
|
141
|
-
SnapshotRoute.propTypes = {
|
|
142
|
-
datasetId: PropTypes.string,
|
|
143
|
-
snapshots: PropTypes.array,
|
|
144
|
-
issues: PropTypes.array,
|
|
145
|
-
description: PropTypes.object,
|
|
146
|
-
}
|
|
147
|
-
|
|
148
145
|
export default SnapshotRoute
|
|
@@ -55,7 +55,7 @@ export const TabRoutesDraft = ({ dataset, hasEdit }) => {
|
|
|
55
55
|
datasetId={dataset.id}
|
|
56
56
|
permissions={dataset.permissions}
|
|
57
57
|
reviewers={dataset.reviewers}
|
|
58
|
-
hasSnapshot={dataset.snapshots.length}
|
|
58
|
+
hasSnapshot={dataset.snapshots.length !== 0}
|
|
59
59
|
/>
|
|
60
60
|
}
|
|
61
61
|
/>
|
|
@@ -108,13 +108,13 @@ export const SnapshotContainer: React.FC<SnapshotContainerProps> = ({
|
|
|
108
108
|
modality={summary?.modalities[0]}>
|
|
109
109
|
<FollowToggles>
|
|
110
110
|
<FollowDataset
|
|
111
|
-
profile={profile}
|
|
111
|
+
profile={profile !== null}
|
|
112
112
|
datasetId={dataset.id}
|
|
113
113
|
following={dataset.following}
|
|
114
114
|
followers={dataset.followers.length}
|
|
115
115
|
/>
|
|
116
116
|
<StarDataset
|
|
117
|
-
profile={profile}
|
|
117
|
+
profile={profile !== null}
|
|
118
118
|
datasetId={dataset.id}
|
|
119
119
|
starred={dataset.starred}
|
|
120
120
|
stars={dataset.stars.length}
|
|
@@ -2,7 +2,7 @@ import React, { FC, ReactElement } from 'react'
|
|
|
2
2
|
import { gql } from '@apollo/client'
|
|
3
3
|
import { Mutation } from '@apollo/client/react/components'
|
|
4
4
|
import { WarnButton } from '@openneuro/components/warn-button'
|
|
5
|
-
import { getProfile } from '../../authentication/profile
|
|
5
|
+
import { getProfile } from '../../authentication/profile'
|
|
6
6
|
import { useCookies } from 'react-cookie'
|
|
7
7
|
import { USER_FRAGMENT } from './user-fragment'
|
|
8
8
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import styled from '@emotion/styled'
|
|
3
|
+
import { DataTable } from '../../components/data-table'
|
|
4
|
+
import { gql, useQuery } from '@apollo/client'
|
|
5
|
+
import { Loading } from '@openneuro/components/loading'
|
|
6
|
+
import { makeCsv } from '../../utils/csv'
|
|
7
|
+
|
|
8
|
+
const MetadataPageStyle = styled.div`
|
|
9
|
+
background: white;
|
|
10
|
+
overflow-x: scroll;
|
|
11
|
+
padding: 1em;
|
|
12
|
+
height: calc(100vh - 125px);
|
|
13
|
+
white-space: nowrap;
|
|
14
|
+
`
|
|
15
|
+
|
|
16
|
+
const MetadataPageButton = styled.button`
|
|
17
|
+
display: inline-block;
|
|
18
|
+
margin-right: 1em;
|
|
19
|
+
`
|
|
20
|
+
|
|
21
|
+
const METADATA_QUERY = gql`
|
|
22
|
+
query {
|
|
23
|
+
publicMetadata {
|
|
24
|
+
datasetId
|
|
25
|
+
datasetUrl
|
|
26
|
+
datasetName
|
|
27
|
+
firstSnapshotCreatedAt
|
|
28
|
+
latestSnapshotCreatedAt
|
|
29
|
+
dxStatus
|
|
30
|
+
tasksCompleted
|
|
31
|
+
trialCount
|
|
32
|
+
grantFunderName
|
|
33
|
+
grantIdentifier
|
|
34
|
+
studyDesign
|
|
35
|
+
studyDomain
|
|
36
|
+
studyLongitudinal
|
|
37
|
+
dataProcessed
|
|
38
|
+
species
|
|
39
|
+
associatedPaperDOI
|
|
40
|
+
openneuroPaperDOI
|
|
41
|
+
seniorAuthor
|
|
42
|
+
adminUsers
|
|
43
|
+
ages
|
|
44
|
+
modalities
|
|
45
|
+
affirmedDefaced
|
|
46
|
+
affirmedConsent
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
`
|
|
50
|
+
|
|
51
|
+
export function DatasetMetadata(): React.ReactElement {
|
|
52
|
+
const { loading, error, data } = useQuery(METADATA_QUERY, {
|
|
53
|
+
errorPolicy: 'all',
|
|
54
|
+
})
|
|
55
|
+
if (loading || error) {
|
|
56
|
+
return <Loading />
|
|
57
|
+
} else {
|
|
58
|
+
return (
|
|
59
|
+
<MetadataPageStyle>
|
|
60
|
+
<p>
|
|
61
|
+
<MetadataPageButton
|
|
62
|
+
role="button"
|
|
63
|
+
type="button"
|
|
64
|
+
className="on-button on-button--small on-button--primary icon-text"
|
|
65
|
+
aria-label="Download"
|
|
66
|
+
onClick={() =>
|
|
67
|
+
makeCsv(data?.publicMetadata, 'openneuro-metadata.csv')
|
|
68
|
+
}>
|
|
69
|
+
<i className="fa fa-download css-0" aria-hidden="true"></i>Download
|
|
70
|
+
CSV
|
|
71
|
+
</MetadataPageButton>
|
|
72
|
+
Metadata collected for all public datasets on OpenNeuro.
|
|
73
|
+
</p>
|
|
74
|
+
<DataTable
|
|
75
|
+
data={data?.publicMetadata}
|
|
76
|
+
downloadFilename="openneuro-metadata.csv"
|
|
77
|
+
hideColumns={[
|
|
78
|
+
'__typename',
|
|
79
|
+
'datasetUrl',
|
|
80
|
+
'affirmedDefaced',
|
|
81
|
+
'affirmedConsent',
|
|
82
|
+
]}></DataTable>
|
|
83
|
+
</MetadataPageStyle>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Top level dataset queries only, mutations may cause refetches of these
|
|
3
|
+
*/
|
|
4
|
+
import { gql } from '@apollo/client'
|
|
5
|
+
import * as DatasetQueryFragments from '../datalad/dataset/dataset-query-fragments.js'
|
|
6
|
+
import { DATASET_COMMENTS } from '../datalad/dataset/comments-fragments.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Generate the dataset page query
|
|
10
|
+
*/
|
|
11
|
+
export const getDatasetPage = gql`
|
|
12
|
+
query dataset($datasetId: ID!) {
|
|
13
|
+
dataset(id: $datasetId) {
|
|
14
|
+
id
|
|
15
|
+
created
|
|
16
|
+
public
|
|
17
|
+
following
|
|
18
|
+
followers {
|
|
19
|
+
userId
|
|
20
|
+
}
|
|
21
|
+
starred
|
|
22
|
+
stars {
|
|
23
|
+
userId
|
|
24
|
+
}
|
|
25
|
+
worker
|
|
26
|
+
...DatasetDraft
|
|
27
|
+
...DatasetPermissions
|
|
28
|
+
...DatasetSnapshots
|
|
29
|
+
...DatasetIssues
|
|
30
|
+
...DatasetMetadata
|
|
31
|
+
...DatasetComments
|
|
32
|
+
uploader {
|
|
33
|
+
id
|
|
34
|
+
name
|
|
35
|
+
email
|
|
36
|
+
orcid
|
|
37
|
+
}
|
|
38
|
+
analytics {
|
|
39
|
+
downloads
|
|
40
|
+
views
|
|
41
|
+
}
|
|
42
|
+
derivatives {
|
|
43
|
+
name
|
|
44
|
+
s3Url
|
|
45
|
+
dataladUrl
|
|
46
|
+
local
|
|
47
|
+
}
|
|
48
|
+
onBrainlife
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
${DatasetQueryFragments.DRAFT_FRAGMENT}
|
|
52
|
+
${DatasetQueryFragments.PERMISSION_FRAGMENT}
|
|
53
|
+
${DatasetQueryFragments.DATASET_SNAPSHOTS}
|
|
54
|
+
${DatasetQueryFragments.DATASET_ISSUES}
|
|
55
|
+
${DatasetQueryFragments.DATASET_METADATA}
|
|
56
|
+
${DATASET_COMMENTS}
|
|
57
|
+
`
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Add files fragment for draft route
|
|
61
|
+
*/
|
|
62
|
+
export const getDraftPage = gql`
|
|
63
|
+
query dataset($datasetId: ID!) {
|
|
64
|
+
dataset(id: $datasetId) {
|
|
65
|
+
id
|
|
66
|
+
created
|
|
67
|
+
public
|
|
68
|
+
following
|
|
69
|
+
followers {
|
|
70
|
+
userId
|
|
71
|
+
}
|
|
72
|
+
starred
|
|
73
|
+
stars {
|
|
74
|
+
userId
|
|
75
|
+
}
|
|
76
|
+
reviewers {
|
|
77
|
+
id
|
|
78
|
+
expiration
|
|
79
|
+
}
|
|
80
|
+
worker
|
|
81
|
+
...DatasetDraft
|
|
82
|
+
...DatasetDraftFiles
|
|
83
|
+
...DatasetPermissions
|
|
84
|
+
...DatasetSnapshots
|
|
85
|
+
...DatasetIssues
|
|
86
|
+
...DatasetMetadata
|
|
87
|
+
...DatasetComments
|
|
88
|
+
uploader {
|
|
89
|
+
id
|
|
90
|
+
name
|
|
91
|
+
email
|
|
92
|
+
orcid
|
|
93
|
+
}
|
|
94
|
+
analytics {
|
|
95
|
+
downloads
|
|
96
|
+
views
|
|
97
|
+
}
|
|
98
|
+
derivatives {
|
|
99
|
+
name
|
|
100
|
+
s3Url
|
|
101
|
+
dataladUrl
|
|
102
|
+
local
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
${DatasetQueryFragments.DRAFT_FRAGMENT}
|
|
107
|
+
${DatasetQueryFragments.DRAFT_FILES_FRAGMENT}
|
|
108
|
+
${DatasetQueryFragments.PERMISSION_FRAGMENT}
|
|
109
|
+
${DatasetQueryFragments.DATASET_SNAPSHOTS}
|
|
110
|
+
${DatasetQueryFragments.DATASET_ISSUES}
|
|
111
|
+
${DatasetQueryFragments.DATASET_METADATA}
|
|
112
|
+
${DATASET_COMMENTS}
|
|
113
|
+
`
|
package/src/scripts/routes.tsx
CHANGED
|
@@ -15,6 +15,7 @@ import { PETRedirect } from './pages/pet-redirect'
|
|
|
15
15
|
import Citation from './pages/citation-page'
|
|
16
16
|
import FourOFourPage from './errors/404page'
|
|
17
17
|
import { ImportDataset } from './pages/import-dataset'
|
|
18
|
+
import { DatasetMetadata } from './pages/metadata/dataset-metadata'
|
|
18
19
|
|
|
19
20
|
const AppRoutes: React.VoidFunctionComponent = () => (
|
|
20
21
|
<Routes>
|
|
@@ -28,6 +29,7 @@ const AppRoutes: React.VoidFunctionComponent = () => (
|
|
|
28
29
|
<Route path="/pet" element={<PETRedirect />} />
|
|
29
30
|
<Route path="/cite" element={<Citation />} />
|
|
30
31
|
<Route path="/import" element={<ImportDataset />} />
|
|
32
|
+
<Route path="/metadata" element={<DatasetMetadata />} />
|
|
31
33
|
<Route path="/public" element={<Navigate to="/search" replace />} />
|
|
32
34
|
<Route
|
|
33
35
|
path="/saved"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { FC } from 'react'
|
|
2
2
|
import { Route, Routes } from 'react-router-dom'
|
|
3
3
|
import SearchContainer from './search-container'
|
|
4
|
-
import { portalContent } from '@openneuro/components/
|
|
4
|
+
import { portalContent } from '@openneuro/components/content'
|
|
5
5
|
|
|
6
6
|
const SearchRoutes: FC = () => (
|
|
7
7
|
<Routes>
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
sqsJoinWithAND,
|
|
12
12
|
joinWithOR,
|
|
13
13
|
} from './es-query-builders'
|
|
14
|
-
import { species_list } from '@openneuro/components/
|
|
14
|
+
import { species_list } from '@openneuro/components/content'
|
|
15
15
|
|
|
16
16
|
const searchQuery = gql`
|
|
17
17
|
query advancedSearchDatasets(
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { convertArrayToCSV } from '../csv'
|
|
2
|
+
|
|
3
|
+
describe('utils/csv', () => {
|
|
4
|
+
it('converts to a valid CSV', () => {
|
|
5
|
+
const obj = [
|
|
6
|
+
{ exampleCol: 'test', exampleCol2: 'test2', __typename: 'example' },
|
|
7
|
+
{ exampleCol: 'test4', exampleCol2: 'test3', __typename: 'example' },
|
|
8
|
+
]
|
|
9
|
+
expect(convertArrayToCSV(obj)).toEqual(
|
|
10
|
+
'exampleCol,exampleCol2\n"test","test2"\n"test4","test3"',
|
|
11
|
+
)
|
|
12
|
+
})
|
|
13
|
+
it('escapes comma values correctly', () => {
|
|
14
|
+
const obj = [
|
|
15
|
+
{ exampleCol: 'test', modalities: 'PET,MRI', __typename: 'example' },
|
|
16
|
+
{ exampleCol: 'test4', modalities: 'MRI', __typename: 'example' },
|
|
17
|
+
]
|
|
18
|
+
expect(convertArrayToCSV(obj)).toEqual(
|
|
19
|
+
'exampleCol,modalities\n"test","PET,MRI"\n"test4","MRI"',
|
|
20
|
+
)
|
|
21
|
+
})
|
|
22
|
+
it('escapes double quotes', () => {
|
|
23
|
+
const obj = [
|
|
24
|
+
{
|
|
25
|
+
exampleCol: 'test',
|
|
26
|
+
modalities: 'PET,MRI',
|
|
27
|
+
name: 'A "Dataset"',
|
|
28
|
+
__typename: 'example',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
exampleCol: 'test4',
|
|
32
|
+
modalities: 'MRI',
|
|
33
|
+
name: 'Another Dataset',
|
|
34
|
+
__typename: 'example',
|
|
35
|
+
},
|
|
36
|
+
]
|
|
37
|
+
expect(convertArrayToCSV(obj)).toEqual(
|
|
38
|
+
'exampleCol,modalities,name\n"test","PET,MRI","A ""Dataset"""\n"test4","MRI","Another Dataset"',
|
|
39
|
+
)
|
|
40
|
+
})
|
|
41
|
+
})
|