@openneuro/app 4.2.5 → 4.3.0-alpha.4
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 +5 -4
- package/src/scripts/datalad/dataset/dataset-query-fragments.js +6 -0
- package/src/scripts/refactor_2021/dataset/dataset-query.jsx +2 -4
- package/src/scripts/refactor_2021/dataset/dataset-routes.jsx +6 -0
- package/src/scripts/refactor_2021/dataset/draft-container.tsx +6 -23
- package/src/scripts/refactor_2021/dataset/fragments/__tests__/dataset-alert-draft.spec.tsx +72 -0
- package/src/scripts/refactor_2021/dataset/fragments/dataset-alert-draft.tsx +79 -0
- package/src/scripts/refactor_2021/dataset/fragments/dataset-alert-version.tsx +24 -0
- package/src/scripts/refactor_2021/dataset/mutations/__tests__/__snapshots__/deprecate-snapshot.spec.tsx.snap +14 -0
- package/src/scripts/refactor_2021/dataset/mutations/__tests__/__snapshots__/deprecate-version.spec.tsx.snap +14 -0
- package/src/scripts/refactor_2021/dataset/mutations/__tests__/deprecate-snapshot.spec.tsx +71 -0
- package/src/scripts/refactor_2021/dataset/mutations/__tests__/deprecate-version.spec.tsx +71 -0
- package/src/scripts/refactor_2021/dataset/mutations/deprecate-version.tsx +46 -0
- package/src/scripts/refactor_2021/dataset/mutations/description.jsx +1 -1
- package/src/scripts/refactor_2021/dataset/mutations/readme.jsx +1 -1
- package/src/scripts/refactor_2021/dataset/mutations/submit-metadata.jsx +1 -1
- package/src/scripts/refactor_2021/dataset/mutations/undo-deprecate-version.tsx +43 -0
- package/src/scripts/refactor_2021/dataset/routes/add-metadata.jsx +0 -1
- package/src/scripts/refactor_2021/dataset/routes/deprecate-snapshot-page.tsx +46 -0
- package/src/scripts/refactor_2021/dataset/snapshot-container.tsx +19 -23
- package/src/scripts/refactor_2021/dataset/dataset-query-fragments.js +0 -220
- package/src/scripts/refactor_2021/dataset/queries/dataset-query-fragments.js +0 -220
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openneuro/app",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0-alpha.4",
|
|
4
4
|
"description": "React JS web frontend for the OpenNeuro platform.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "public/client.js",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"@elastic/apm-rum": "5.9.1",
|
|
20
20
|
"@emotion/react": "11.6.0",
|
|
21
21
|
"@emotion/styled": "11.6.0",
|
|
22
|
-
"@openneuro/client": "^4.
|
|
23
|
-
"@openneuro/components": "^4.
|
|
22
|
+
"@openneuro/client": "^4.3.0-alpha.4",
|
|
23
|
+
"@openneuro/components": "^4.3.0-alpha.4",
|
|
24
24
|
"babel-runtime": "^6.26.0",
|
|
25
25
|
"bids-validator": "1.8.8",
|
|
26
26
|
"bytes": "^3.0.0",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"email-validator": "^2.0.4",
|
|
33
33
|
"express": "^4.17.1",
|
|
34
34
|
"graphql": "14.7.0",
|
|
35
|
+
"history": "5.2.0",
|
|
35
36
|
"jwt-decode": "^2.2.0",
|
|
36
37
|
"markdown-to-jsx": "^7.1.2",
|
|
37
38
|
"os-browserify": "^0.3.0",
|
|
@@ -115,5 +116,5 @@
|
|
|
115
116
|
"publishConfig": {
|
|
116
117
|
"access": "public"
|
|
117
118
|
},
|
|
118
|
-
"gitHead": "
|
|
119
|
+
"gitHead": "5637774c7c1a5497a8b4260f8de90ebfcc4d5e29"
|
|
119
120
|
}
|
|
@@ -172,8 +172,7 @@ export const DatasetQueryHook = ({ datasetId, draft, history }) => {
|
|
|
172
172
|
datasetId,
|
|
173
173
|
fetchMore,
|
|
174
174
|
error,
|
|
175
|
-
}}
|
|
176
|
-
>
|
|
175
|
+
}}>
|
|
177
176
|
<DatasetRoutes dataset={data.dataset} />
|
|
178
177
|
<FilesSubscription datasetId={datasetId} />
|
|
179
178
|
</DatasetQueryContext.Provider>
|
|
@@ -208,8 +207,7 @@ const DatasetQuery = ({ match, history }) => {
|
|
|
208
207
|
<>
|
|
209
208
|
<DatasetRedirect />
|
|
210
209
|
<ErrorBoundaryAssertionFailureException
|
|
211
|
-
subject={'error in dataset query'}
|
|
212
|
-
>
|
|
210
|
+
subject={'error in dataset query'}>
|
|
213
211
|
<DatasetQueryHook
|
|
214
212
|
datasetId={datasetId}
|
|
215
213
|
draft={!snapshotId}
|
|
@@ -12,6 +12,7 @@ import Share from './routes/manage-permissions.jsx'
|
|
|
12
12
|
import Snapshot from './routes/snapshot.jsx'
|
|
13
13
|
import AddMetadata from './routes/add-metadata.jsx'
|
|
14
14
|
import DeletePage from './routes/delete-page'
|
|
15
|
+
import { DeprecateSnapshotPage } from './routes/deprecate-snapshot-page'
|
|
15
16
|
import { FileDisplay } from './files'
|
|
16
17
|
|
|
17
18
|
//TODO imports
|
|
@@ -119,6 +120,11 @@ const DatasetRoutes = ({ dataset, error }) => {
|
|
|
119
120
|
/>
|
|
120
121
|
)}
|
|
121
122
|
/>
|
|
123
|
+
<Route
|
|
124
|
+
exact
|
|
125
|
+
path="/datasets/:datasetId/versions/:snapshotTag/deprecate"
|
|
126
|
+
component={() => <DeprecateSnapshotPage />}
|
|
127
|
+
/>
|
|
122
128
|
<Route
|
|
123
129
|
path="/datasets/:datasetId/versions/:snapshotTag/file-display/:filePath"
|
|
124
130
|
render={({
|
|
@@ -11,9 +11,11 @@ import { config } from '../../config'
|
|
|
11
11
|
import {
|
|
12
12
|
getUnexpiredProfile,
|
|
13
13
|
hasEditPermissions,
|
|
14
|
+
hasDatasetAdminPermissions,
|
|
14
15
|
} from '../authentication/profile'
|
|
15
16
|
import { useCookies } from 'react-cookie'
|
|
16
17
|
import Comments from './comments/comments.jsx'
|
|
18
|
+
import { DatasetAlertDraft } from './fragments/dataset-alert-draft'
|
|
17
19
|
import {
|
|
18
20
|
MetaDataBlock,
|
|
19
21
|
ModalitiesMetaDataBlock,
|
|
@@ -21,14 +23,12 @@ import {
|
|
|
21
23
|
ValidationBlock,
|
|
22
24
|
CloneDropdown,
|
|
23
25
|
DatasetHeader,
|
|
24
|
-
DatasetAlert,
|
|
25
26
|
DatasetHeaderMeta,
|
|
26
27
|
DatasetPage,
|
|
27
28
|
DatasetGitAccess,
|
|
28
29
|
VersionList,
|
|
29
30
|
DatasetTools,
|
|
30
31
|
} from '@openneuro/components/dataset'
|
|
31
|
-
import { Modal } from '@openneuro/components/modal'
|
|
32
32
|
import { ReadMore } from '@openneuro/components/read-more'
|
|
33
33
|
|
|
34
34
|
import { FollowDataset } from './mutations/follow'
|
|
@@ -56,8 +56,6 @@ const DraftContainer: React.FC<DraftContainerProps> = ({ dataset }) => {
|
|
|
56
56
|
const activeDataset = snapshotVersion(location) || 'draft'
|
|
57
57
|
|
|
58
58
|
const [selectedVersion, setSelectedVersion] = React.useState(activeDataset)
|
|
59
|
-
const [deprecatedmodalIsOpen, setDeprecatedModalIsOpen] =
|
|
60
|
-
React.useState(false)
|
|
61
59
|
|
|
62
60
|
const summary = dataset.draft.summary
|
|
63
61
|
const description = dataset.draft.description
|
|
@@ -73,12 +71,7 @@ const DraftContainer: React.FC<DraftContainerProps> = ({ dataset }) => {
|
|
|
73
71
|
parseISO(dataset.draft.modified),
|
|
74
72
|
)
|
|
75
73
|
const isSnapshot = activeDataset !== 'draft'
|
|
76
|
-
const rootPath = isSnapshot
|
|
77
|
-
? `/datasets/${datasetId}/versions/${activeDataset}`
|
|
78
|
-
: `/datasets/${datasetId}`
|
|
79
74
|
|
|
80
|
-
//TODO deprecated needs to be added to the dataset snapshot obj and an admin needs to be able to say a version is deprecated somehow.
|
|
81
|
-
const isPublic = dataset.public === true
|
|
82
75
|
const [cookies] = useCookies()
|
|
83
76
|
const profile = getUnexpiredProfile(cookies)
|
|
84
77
|
const isAdmin = profile?.admin
|
|
@@ -88,6 +81,8 @@ const DraftContainer: React.FC<DraftContainerProps> = ({ dataset }) => {
|
|
|
88
81
|
dataset.snapshots.length === 0 ||
|
|
89
82
|
dataset.draft.head !==
|
|
90
83
|
dataset.snapshots[dataset.snapshots.length - 1].hexsha
|
|
84
|
+
const isDatasetAdmin =
|
|
85
|
+
hasDatasetAdminPermissions(dataset.permissions, profile?.sub) || isAdmin
|
|
91
86
|
|
|
92
87
|
return (
|
|
93
88
|
<>
|
|
@@ -122,7 +117,7 @@ const DraftContainer: React.FC<DraftContainerProps> = ({ dataset }) => {
|
|
|
122
117
|
renderAlert={() => (
|
|
123
118
|
<>
|
|
124
119
|
{hasEdit && (
|
|
125
|
-
<
|
|
120
|
+
<DatasetAlertDraft
|
|
126
121
|
isPrivate={!dataset.public}
|
|
127
122
|
datasetId={dataset.id}
|
|
128
123
|
hasDraftChanges={hasDraftChanges}
|
|
@@ -191,6 +186,7 @@ const DraftContainer: React.FC<DraftContainerProps> = ({ dataset }) => {
|
|
|
191
186
|
datasetId={datasetId}
|
|
192
187
|
isAdmin={isAdmin}
|
|
193
188
|
hasSnapshot={dataset.snapshots.length !== 0}
|
|
189
|
+
isDatasetAdmin={isDatasetAdmin}
|
|
194
190
|
/>
|
|
195
191
|
)}
|
|
196
192
|
renderFiles={() => (
|
|
@@ -263,7 +259,6 @@ const DraftContainer: React.FC<DraftContainerProps> = ({ dataset }) => {
|
|
|
263
259
|
dateModified={dateModified}
|
|
264
260
|
selected={selectedVersion}
|
|
265
261
|
setSelected={setSelectedVersion}
|
|
266
|
-
setDeprecatedModalIsOpen={setDeprecatedModalIsOpen}
|
|
267
262
|
/>
|
|
268
263
|
</div>
|
|
269
264
|
}
|
|
@@ -427,18 +422,6 @@ const DraftContainer: React.FC<DraftContainerProps> = ({ dataset }) => {
|
|
|
427
422
|
</EditDescriptionList>
|
|
428
423
|
</>
|
|
429
424
|
)}
|
|
430
|
-
renderDeprecatedModal={() => (
|
|
431
|
-
<Modal
|
|
432
|
-
isOpen={deprecatedmodalIsOpen}
|
|
433
|
-
toggle={() => setDeprecatedModalIsOpen(prevIsOpen => !prevIsOpen)}
|
|
434
|
-
closeText={'close'}
|
|
435
|
-
className="deprecated-modal">
|
|
436
|
-
<p>
|
|
437
|
-
You have selected a deprecated version. The author of the dataset
|
|
438
|
-
does not recommend this specific version.
|
|
439
|
-
</p>
|
|
440
|
-
</Modal>
|
|
441
|
-
)}
|
|
442
425
|
renderComments={() => (
|
|
443
426
|
<Comments
|
|
444
427
|
datasetId={dataset.id}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen } from '@testing-library/react'
|
|
3
|
+
import '@testing-library/jest-dom/extend-expect'
|
|
4
|
+
import { MemoryRouter } from 'react-router-dom'
|
|
5
|
+
import { DatasetAlertDraft } from '../dataset-alert-draft'
|
|
6
|
+
|
|
7
|
+
describe('DatasetAlertDraft component', () => {
|
|
8
|
+
it('renders the correct text for private drafts with changes', () => {
|
|
9
|
+
render(
|
|
10
|
+
<DatasetAlertDraft
|
|
11
|
+
isPrivate
|
|
12
|
+
hasSnapshot
|
|
13
|
+
hasDraftChanges
|
|
14
|
+
datasetId="test00001"
|
|
15
|
+
/>,
|
|
16
|
+
{ wrapper: MemoryRouter },
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
expect(
|
|
20
|
+
screen.queryByText(/there have been changes to the draft/i),
|
|
21
|
+
).toBeInTheDocument()
|
|
22
|
+
})
|
|
23
|
+
it('renders the correct text for private drafts with no snapshots', () => {
|
|
24
|
+
render(
|
|
25
|
+
<DatasetAlertDraft
|
|
26
|
+
isPrivate
|
|
27
|
+
hasDraftChanges
|
|
28
|
+
hasSnapshot={false}
|
|
29
|
+
datasetId="test00001"
|
|
30
|
+
/>,
|
|
31
|
+
{ wrapper: MemoryRouter },
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
expect(
|
|
35
|
+
screen.queryByText(/before it can be published/i),
|
|
36
|
+
).toBeInTheDocument()
|
|
37
|
+
})
|
|
38
|
+
it('renders the correct text for public drafts with changes', () => {
|
|
39
|
+
render(
|
|
40
|
+
<DatasetAlertDraft
|
|
41
|
+
hasDraftChanges
|
|
42
|
+
isPrivate={false}
|
|
43
|
+
hasSnapshot={false}
|
|
44
|
+
datasetId="test00001"
|
|
45
|
+
/>,
|
|
46
|
+
{
|
|
47
|
+
wrapper: MemoryRouter,
|
|
48
|
+
},
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
expect(
|
|
52
|
+
screen.queryByText(/there are currently unsaved changes to this draft/i),
|
|
53
|
+
).toBeInTheDocument()
|
|
54
|
+
})
|
|
55
|
+
it('renders the correct text for public drafts without changes', () => {
|
|
56
|
+
render(
|
|
57
|
+
<DatasetAlertDraft
|
|
58
|
+
hasDraftChanges={false}
|
|
59
|
+
isPrivate={false}
|
|
60
|
+
hasSnapshot={false}
|
|
61
|
+
datasetId="test00001"
|
|
62
|
+
/>,
|
|
63
|
+
{
|
|
64
|
+
wrapper: MemoryRouter,
|
|
65
|
+
},
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
expect(
|
|
69
|
+
screen.queryByText(/you can make changes to this draft page/i),
|
|
70
|
+
).toBeInTheDocument()
|
|
71
|
+
})
|
|
72
|
+
})
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Link } from 'react-router-dom'
|
|
3
|
+
import { DatasetAlert } from '@openneuro/components/dataset'
|
|
4
|
+
|
|
5
|
+
export interface DatasetAlertDraftProps {
|
|
6
|
+
isPrivate: boolean
|
|
7
|
+
datasetId: string
|
|
8
|
+
hasDraftChanges: boolean
|
|
9
|
+
hasSnapshot: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const DatasetAlertDraft: React.FC<DatasetAlertDraftProps> = ({
|
|
13
|
+
isPrivate,
|
|
14
|
+
datasetId,
|
|
15
|
+
hasDraftChanges,
|
|
16
|
+
hasSnapshot,
|
|
17
|
+
}) => {
|
|
18
|
+
if (isPrivate) {
|
|
19
|
+
if (hasSnapshot) {
|
|
20
|
+
return (
|
|
21
|
+
<DatasetAlert
|
|
22
|
+
alert="This dataset has not been published!"
|
|
23
|
+
footer={
|
|
24
|
+
hasDraftChanges &&
|
|
25
|
+
'* There have been changes to the draft since your last version'
|
|
26
|
+
}
|
|
27
|
+
level="warning">
|
|
28
|
+
<>
|
|
29
|
+
<Link
|
|
30
|
+
className="dataset-tool"
|
|
31
|
+
to={'/datasets/' + datasetId + '/publish'}>
|
|
32
|
+
Publish this dataset
|
|
33
|
+
</Link>
|
|
34
|
+
  to make all versions available publicly.
|
|
35
|
+
</>
|
|
36
|
+
</DatasetAlert>
|
|
37
|
+
)
|
|
38
|
+
} else {
|
|
39
|
+
return (
|
|
40
|
+
<DatasetAlert
|
|
41
|
+
alert="This dataset has not been published!"
|
|
42
|
+
level="warning">
|
|
43
|
+
Before it can be published, please 
|
|
44
|
+
<Link
|
|
45
|
+
className="dataset-tool"
|
|
46
|
+
to={'/datasets/' + datasetId + '/snapshot'}>
|
|
47
|
+
create a version
|
|
48
|
+
</Link>
|
|
49
|
+
</DatasetAlert>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
if (hasDraftChanges) {
|
|
54
|
+
return (
|
|
55
|
+
<DatasetAlert alert="This dataset has been published!" level="warning">
|
|
56
|
+
There are currently unsaved changes to this Draft. Changes made here
|
|
57
|
+
become public when you 
|
|
58
|
+
<Link
|
|
59
|
+
className="dataset-tool"
|
|
60
|
+
to={'/datasets/' + datasetId + '/snapshot'}>
|
|
61
|
+
create a new version.
|
|
62
|
+
</Link>
|
|
63
|
+
</DatasetAlert>
|
|
64
|
+
)
|
|
65
|
+
} else {
|
|
66
|
+
return (
|
|
67
|
+
<DatasetAlert alert="This dataset has been published!">
|
|
68
|
+
You can make changes to this Draft page, then 
|
|
69
|
+
<Link
|
|
70
|
+
className="dataset-tool"
|
|
71
|
+
to={'/datasets/' + datasetId + '/snapshot'}>
|
|
72
|
+
create a new version
|
|
73
|
+
</Link>
|
|
74
|
+
 to make them public.
|
|
75
|
+
</DatasetAlert>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { DatasetAlert } from '@openneuro/components/dataset'
|
|
3
|
+
import { UndoDeprecateVersion } from '../mutations/undo-deprecate-version'
|
|
4
|
+
|
|
5
|
+
export interface DatasetAlertVersionProps {
|
|
6
|
+
datasetId: string
|
|
7
|
+
tag: string
|
|
8
|
+
reason: string
|
|
9
|
+
hasEdit: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const DatasetAlertVersion: React.FC<DatasetAlertVersionProps> = ({
|
|
13
|
+
datasetId,
|
|
14
|
+
tag,
|
|
15
|
+
reason,
|
|
16
|
+
hasEdit,
|
|
17
|
+
}) => (
|
|
18
|
+
<DatasetAlert
|
|
19
|
+
alert="This version has been deprecated!"
|
|
20
|
+
level="error"
|
|
21
|
+
footer={reason}>
|
|
22
|
+
{hasEdit && <UndoDeprecateVersion datasetId={datasetId} tag={tag} />}
|
|
23
|
+
</DatasetAlert>
|
|
24
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`DeprecateVersion mutation renders with typical props 1`] = `
|
|
4
|
+
<DocumentFragment>
|
|
5
|
+
<button
|
|
6
|
+
aria-label="Deprecate Version"
|
|
7
|
+
class="on-button on-button--small on-button--primary btn-modal-action"
|
|
8
|
+
role="button"
|
|
9
|
+
type="button"
|
|
10
|
+
>
|
|
11
|
+
Deprecate Version
|
|
12
|
+
</button>
|
|
13
|
+
</DocumentFragment>
|
|
14
|
+
`;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`DeprecateVersion mutation renders with typical props 1`] = `
|
|
4
|
+
<DocumentFragment>
|
|
5
|
+
<button
|
|
6
|
+
aria-label="Deprecate Version"
|
|
7
|
+
class="on-button on-button--small on-button--primary btn-modal-action"
|
|
8
|
+
role="button"
|
|
9
|
+
type="button"
|
|
10
|
+
>
|
|
11
|
+
Deprecate Version
|
|
12
|
+
</button>
|
|
13
|
+
</DocumentFragment>
|
|
14
|
+
`;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, fireEvent, screen, waitFor } from '@testing-library/react'
|
|
3
|
+
import { MockedProvider } from '@apollo/client/testing'
|
|
4
|
+
import { Router } from 'react-router-dom'
|
|
5
|
+
import { createMemoryHistory } from 'history'
|
|
6
|
+
import { DeprecateVersion, DEPRECATE_VERSION } from '../deprecate-version'
|
|
7
|
+
|
|
8
|
+
describe('DeprecateVersion mutation', () => {
|
|
9
|
+
it('renders with typical props', () => {
|
|
10
|
+
const { asFragment } = render(
|
|
11
|
+
<MockedProvider>
|
|
12
|
+
<DeprecateVersion
|
|
13
|
+
datasetId="test00001"
|
|
14
|
+
tag="1.0.0"
|
|
15
|
+
reason="This is a test suite."
|
|
16
|
+
/>
|
|
17
|
+
</MockedProvider>,
|
|
18
|
+
)
|
|
19
|
+
expect(asFragment()).toMatchSnapshot()
|
|
20
|
+
})
|
|
21
|
+
it('calls the DEPRECATE_VERSION mutation when clicked and navigates to the snapshot on success', async () => {
|
|
22
|
+
const datasetId = 'test00001'
|
|
23
|
+
const tag = '1.0.0'
|
|
24
|
+
const reason = 'This is a test suite.'
|
|
25
|
+
const history = createMemoryHistory({
|
|
26
|
+
initialEntries: [`/datasets/${datasetId}/versions/${tag}/deprecate`],
|
|
27
|
+
})
|
|
28
|
+
const historyPushSpy = jest.spyOn(history, 'push')
|
|
29
|
+
const snapshotId = `${datasetId}:${tag}`
|
|
30
|
+
const deprecateSnapshotMock = {
|
|
31
|
+
request: {
|
|
32
|
+
query: DEPRECATE_VERSION,
|
|
33
|
+
variables: {
|
|
34
|
+
datasetId,
|
|
35
|
+
tag,
|
|
36
|
+
reason,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
result: {
|
|
40
|
+
data: {
|
|
41
|
+
deprecateSnapshot: {
|
|
42
|
+
__typename: 'Snapshot',
|
|
43
|
+
id: snapshotId,
|
|
44
|
+
deprecated: {
|
|
45
|
+
__typename: 'DeprecatedSnapshot',
|
|
46
|
+
id: snapshotId,
|
|
47
|
+
user: '1245',
|
|
48
|
+
reason,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
render(
|
|
56
|
+
<Router history={history}>
|
|
57
|
+
<MockedProvider mocks={[deprecateSnapshotMock]} addTypename={false}>
|
|
58
|
+
<DeprecateVersion datasetId={datasetId} tag={tag} reason={reason} />
|
|
59
|
+
</MockedProvider>
|
|
60
|
+
</Router>,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
fireEvent.click(screen.getByLabelText(/Deprecate Version/i))
|
|
64
|
+
|
|
65
|
+
await waitFor(() => expect(historyPushSpy).toHaveBeenCalledTimes(1))
|
|
66
|
+
|
|
67
|
+
expect(history.location.pathname).toBe(
|
|
68
|
+
`/datasets/${datasetId}/versions/${tag}`,
|
|
69
|
+
)
|
|
70
|
+
})
|
|
71
|
+
})
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, fireEvent, screen, waitFor } from '@testing-library/react'
|
|
3
|
+
import { MockedProvider } from '@apollo/client/testing'
|
|
4
|
+
import { Router } from 'react-router-dom'
|
|
5
|
+
import { createMemoryHistory } from 'history'
|
|
6
|
+
import { DeprecateVersion, DEPRECATE_VERSION } from '../deprecate-version'
|
|
7
|
+
|
|
8
|
+
describe('DeprecateVersion mutation', () => {
|
|
9
|
+
it('renders with typical props', () => {
|
|
10
|
+
const { asFragment } = render(
|
|
11
|
+
<MockedProvider>
|
|
12
|
+
<DeprecateVersion
|
|
13
|
+
datasetId="test00001"
|
|
14
|
+
tag="1.0.0"
|
|
15
|
+
reason="This is a test suite."
|
|
16
|
+
/>
|
|
17
|
+
</MockedProvider>,
|
|
18
|
+
)
|
|
19
|
+
expect(asFragment()).toMatchSnapshot()
|
|
20
|
+
})
|
|
21
|
+
it('calls the DEPRECATE_VERSION mutation when clicked and navigates to the snapshot on success', async () => {
|
|
22
|
+
const datasetId = 'test00001'
|
|
23
|
+
const tag = '1.0.0'
|
|
24
|
+
const reason = 'This is a test suite.'
|
|
25
|
+
const history = createMemoryHistory({
|
|
26
|
+
initialEntries: [`/datasets/${datasetId}/versions/${tag}/deprecate`],
|
|
27
|
+
})
|
|
28
|
+
const historyPushSpy = jest.spyOn(history, 'push')
|
|
29
|
+
const snapshotId = `${datasetId}:${tag}`
|
|
30
|
+
const deprecateSnapshotMock = {
|
|
31
|
+
request: {
|
|
32
|
+
query: DEPRECATE_VERSION,
|
|
33
|
+
variables: {
|
|
34
|
+
datasetId,
|
|
35
|
+
tag,
|
|
36
|
+
reason,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
result: {
|
|
40
|
+
data: {
|
|
41
|
+
deprecateSnapshot: {
|
|
42
|
+
__typename: 'Snapshot',
|
|
43
|
+
id: snapshotId,
|
|
44
|
+
deprecated: {
|
|
45
|
+
__typename: 'DeprecatedSnapshot',
|
|
46
|
+
id: snapshotId,
|
|
47
|
+
user: '1245',
|
|
48
|
+
reason,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
render(
|
|
56
|
+
<Router history={history}>
|
|
57
|
+
<MockedProvider mocks={[deprecateSnapshotMock]} addTypename={false}>
|
|
58
|
+
<DeprecateVersion datasetId={datasetId} tag={tag} reason={reason} />
|
|
59
|
+
</MockedProvider>
|
|
60
|
+
</Router>,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
fireEvent.click(screen.getByLabelText(/Deprecate Version/i))
|
|
64
|
+
|
|
65
|
+
await waitFor(() => expect(historyPushSpy).toHaveBeenCalledTimes(1))
|
|
66
|
+
|
|
67
|
+
expect(history.location.pathname).toBe(
|
|
68
|
+
`/datasets/${datasetId}/versions/${tag}`,
|
|
69
|
+
)
|
|
70
|
+
})
|
|
71
|
+
})
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React, { FC } from 'react'
|
|
2
|
+
import { gql, useMutation } from '@apollo/client'
|
|
3
|
+
import { Button } from '@openneuro/components/button'
|
|
4
|
+
import { useHistory } from 'react-router-dom'
|
|
5
|
+
|
|
6
|
+
export const DEPRECATE_VERSION = gql`
|
|
7
|
+
mutation deprecateSnapshot($datasetId: ID!, $tag: String!, $reason: String!) {
|
|
8
|
+
deprecateSnapshot(datasetId: $datasetId, tag: $tag, reason: $reason) {
|
|
9
|
+
id
|
|
10
|
+
deprecated {
|
|
11
|
+
reason
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
`
|
|
16
|
+
|
|
17
|
+
interface DeprecateVersionProps {
|
|
18
|
+
datasetId: string
|
|
19
|
+
tag: string
|
|
20
|
+
reason: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const DeprecateVersion: FC<DeprecateVersionProps> = ({
|
|
24
|
+
datasetId,
|
|
25
|
+
tag,
|
|
26
|
+
reason,
|
|
27
|
+
}) => {
|
|
28
|
+
const history = useHistory()
|
|
29
|
+
const [DeprecateVersionMutation] = useMutation(DEPRECATE_VERSION)
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<Button
|
|
33
|
+
className="btn-modal-action"
|
|
34
|
+
primary={true}
|
|
35
|
+
label="Deprecate Version"
|
|
36
|
+
size="small"
|
|
37
|
+
onClick={() =>
|
|
38
|
+
DeprecateVersionMutation({
|
|
39
|
+
variables: { datasetId, tag, reason },
|
|
40
|
+
}).then(() => {
|
|
41
|
+
history.push(`/datasets/${datasetId}/versions/${tag}`)
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
|
|
3
3
|
import { gql } from '@apollo/client'
|
|
4
4
|
import { Mutation } from '@apollo/client/react/components'
|
|
5
5
|
import { SaveButton } from '../fragments/save-button'
|
|
6
|
-
import { DRAFT_FRAGMENT } from '
|
|
6
|
+
import { DRAFT_FRAGMENT } from '../../../datalad/dataset/dataset-query-fragments'
|
|
7
7
|
import { datasetCacheId } from './cache-id.js'
|
|
8
8
|
|
|
9
9
|
export const UPDATE_DESCRIPTION = gql`
|
|
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
|
|
3
3
|
import { gql } from '@apollo/client'
|
|
4
4
|
import { Mutation } from '@apollo/client/react/components'
|
|
5
5
|
import { SaveButton } from '../fragments/save-button'
|
|
6
|
-
import { DRAFT_FRAGMENT } from '
|
|
6
|
+
import { DRAFT_FRAGMENT } from '../../../datalad/dataset/dataset-query-fragments'
|
|
7
7
|
import { datasetCacheId } from './cache-id.js'
|
|
8
8
|
|
|
9
9
|
const UPDATE_README = gql`
|
|
@@ -2,7 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { gql } from '@apollo/client'
|
|
4
4
|
import { Mutation } from '@apollo/client/react/components'
|
|
5
|
-
import { DATASET_METADATA } from '
|
|
5
|
+
import { DATASET_METADATA } from '../../../datalad/dataset/dataset-query-fragments'
|
|
6
6
|
import { datasetCacheId } from './cache-id.js'
|
|
7
7
|
import { Button } from '@openneuro/components/button'
|
|
8
8
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React, { FC } from 'react'
|
|
2
|
+
import { gql, useMutation } from '@apollo/client'
|
|
3
|
+
import { Button } from '@openneuro/components/button'
|
|
4
|
+
import { Tooltip } from '@openneuro/components/tooltip'
|
|
5
|
+
|
|
6
|
+
const UNDO_DEPRECATE_VERSION = gql`
|
|
7
|
+
mutation undoDeprecateSnapshot($datasetId: ID!, $tag: String!) {
|
|
8
|
+
undoDeprecateSnapshot(datasetId: $datasetId, tag: $tag) {
|
|
9
|
+
id
|
|
10
|
+
deprecated {
|
|
11
|
+
reason
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
`
|
|
16
|
+
|
|
17
|
+
interface UndoDeprecateVersionProps {
|
|
18
|
+
datasetId: string
|
|
19
|
+
tag: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const UndoDeprecateVersion: FC<UndoDeprecateVersionProps> = ({
|
|
23
|
+
datasetId,
|
|
24
|
+
tag,
|
|
25
|
+
}) => {
|
|
26
|
+
const [UndoDeprecateVersion] = useMutation(UNDO_DEPRECATE_VERSION)
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Tooltip tooltip="Undo Deprecation" flow="right">
|
|
30
|
+
<Button
|
|
31
|
+
icon="fa fa-undo"
|
|
32
|
+
iconOnly
|
|
33
|
+
label="Undo"
|
|
34
|
+
size="xsmall"
|
|
35
|
+
onClick={() =>
|
|
36
|
+
UndoDeprecateVersion({
|
|
37
|
+
variables: { datasetId, tag },
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
/>
|
|
41
|
+
</Tooltip>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
@@ -112,7 +112,6 @@ const AddMetadata = ({ dataset }) => {
|
|
|
112
112
|
const errors = runValidations(newValues)
|
|
113
113
|
if (hasChanged(errors, validationErrors)) setValidationErrors(errors)
|
|
114
114
|
}
|
|
115
|
-
// @ts-expect-error Weak type definition for state
|
|
116
115
|
const submitPath = location.state && location.state.submitPath
|
|
117
116
|
const user = getProfile(cookies)
|
|
118
117
|
const hasEdit =
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { Link, useRouteMatch } from 'react-router-dom'
|
|
3
|
+
import { DeprecateVersion } from '../mutations/deprecate-version'
|
|
4
|
+
import { Input } from '@openneuro/components/input'
|
|
5
|
+
import LoggedIn from '../../authentication/logged-in.jsx'
|
|
6
|
+
|
|
7
|
+
interface DeprecateSnapshotRouteParams {
|
|
8
|
+
datasetId: string
|
|
9
|
+
snapshotTag: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const DeprecateSnapshotPage = (): React.ReactElement => {
|
|
13
|
+
const {
|
|
14
|
+
params: { datasetId, snapshotTag },
|
|
15
|
+
} = useRouteMatch<DeprecateSnapshotRouteParams>()
|
|
16
|
+
const [reason, setReason] = useState('')
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="container">
|
|
20
|
+
<h2>Deprecate Version</h2>
|
|
21
|
+
<p>
|
|
22
|
+
{`Deprecate ${datasetId} version ${snapshotTag} to let other users know about an issue with this version. The reason provided will be displayed for users visiting the version.`}
|
|
23
|
+
</p>
|
|
24
|
+
<Input
|
|
25
|
+
placeholder="Explanation for deprecation"
|
|
26
|
+
type="text"
|
|
27
|
+
name="front-page-search"
|
|
28
|
+
labelStyle="default"
|
|
29
|
+
setValue={setReason}
|
|
30
|
+
/>
|
|
31
|
+
<hr />
|
|
32
|
+
<div className="dataset-form-controls">
|
|
33
|
+
<LoggedIn>
|
|
34
|
+
<DeprecateVersion
|
|
35
|
+
datasetId={datasetId}
|
|
36
|
+
tag={snapshotTag}
|
|
37
|
+
reason={reason}
|
|
38
|
+
/>
|
|
39
|
+
</LoggedIn>
|
|
40
|
+
<Link className="return-link" to={`/datasets/${datasetId}`}>
|
|
41
|
+
Return to Dataset
|
|
42
|
+
</Link>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
@@ -12,6 +12,7 @@ import Validation from '../validation/validation.jsx'
|
|
|
12
12
|
import { config } from '../../config'
|
|
13
13
|
import Comments from './comments/comments.jsx'
|
|
14
14
|
import DatasetCitation from './fragments/dataset-citation.jsx'
|
|
15
|
+
import { DatasetAlertVersion } from './fragments/dataset-alert-version'
|
|
15
16
|
|
|
16
17
|
import {
|
|
17
18
|
ModalitiesMetaDataBlock,
|
|
@@ -31,16 +32,16 @@ import { Loading } from '@openneuro/components/loading'
|
|
|
31
32
|
import {
|
|
32
33
|
getUnexpiredProfile,
|
|
33
34
|
hasEditPermissions,
|
|
35
|
+
hasDatasetAdminPermissions,
|
|
34
36
|
} from '../authentication/profile'
|
|
35
37
|
import { useCookies } from 'react-cookie'
|
|
36
|
-
import { Modal } from '@openneuro/components/modal'
|
|
37
38
|
|
|
38
39
|
import { ReadMore } from '@openneuro/components/read-more'
|
|
39
40
|
|
|
40
41
|
import { FollowDataset } from './mutations/follow'
|
|
41
42
|
import { StarDataset } from './mutations/star'
|
|
42
43
|
|
|
43
|
-
import { SNAPSHOT_FIELDS } from '
|
|
44
|
+
import { SNAPSHOT_FIELDS } from '../../datalad/dataset/dataset-query-fragments.js'
|
|
44
45
|
import { DOILink } from './fragments/doi-link'
|
|
45
46
|
|
|
46
47
|
const formatDate = dateObject =>
|
|
@@ -67,8 +68,6 @@ const SnapshotContainer: React.FC<SnapshotContainerProps> = ({
|
|
|
67
68
|
const activeDataset = snapshotVersion(location) || 'draft'
|
|
68
69
|
|
|
69
70
|
const [selectedVersion, setSelectedVersion] = React.useState(activeDataset)
|
|
70
|
-
const [deprecatedmodalIsOpen, setDeprecatedModalIsOpen] =
|
|
71
|
-
React.useState(false)
|
|
72
71
|
|
|
73
72
|
const summary = snapshot.summary
|
|
74
73
|
const description = snapshot.description
|
|
@@ -81,18 +80,15 @@ const SnapshotContainer: React.FC<SnapshotContainerProps> = ({
|
|
|
81
80
|
const dateAddedDifference = formatDistanceToNow(parseISO(dataset.created))
|
|
82
81
|
const dateModified = formatDate(snapshot.created)
|
|
83
82
|
const dateUpdatedDifference = formatDistanceToNow(parseISO(snapshot.created))
|
|
84
|
-
const rootPath = `/datasets/${datasetId}/versions/${activeDataset}`
|
|
85
83
|
|
|
86
|
-
//TODO deprecated needs to be added to the dataset snapshot obj and an admin needs to be able to say a version is deprecated somehow.
|
|
87
84
|
const [cookies] = useCookies()
|
|
88
85
|
const profile = getUnexpiredProfile(cookies)
|
|
89
86
|
const isAdmin = profile?.admin
|
|
90
87
|
const hasEdit =
|
|
91
88
|
hasEditPermissions(dataset.permissions, profile?.sub) || isAdmin
|
|
92
|
-
const
|
|
93
|
-
dataset.
|
|
94
|
-
|
|
95
|
-
dataset.snapshots[dataset.snapshots.length - 1].hexsha
|
|
89
|
+
const isDatasetAdmin =
|
|
90
|
+
hasDatasetAdminPermissions(dataset.permissions, profile?.sub) || isAdmin
|
|
91
|
+
|
|
96
92
|
return (
|
|
97
93
|
<>
|
|
98
94
|
<DatasetPage
|
|
@@ -107,6 +103,18 @@ const SnapshotContainer: React.FC<SnapshotContainerProps> = ({
|
|
|
107
103
|
)}
|
|
108
104
|
</>
|
|
109
105
|
)}
|
|
106
|
+
renderAlert={() => (
|
|
107
|
+
<>
|
|
108
|
+
{snapshot?.deprecated && (
|
|
109
|
+
<DatasetAlertVersion
|
|
110
|
+
datasetId={dataset.id}
|
|
111
|
+
tag={snapshot.tag}
|
|
112
|
+
reason={snapshot.deprecated.reason}
|
|
113
|
+
hasEdit={hasEdit}
|
|
114
|
+
/>
|
|
115
|
+
)}
|
|
116
|
+
</>
|
|
117
|
+
)}
|
|
110
118
|
renderHeaderMeta={() => (
|
|
111
119
|
<>
|
|
112
120
|
{summary && (
|
|
@@ -166,6 +174,7 @@ const SnapshotContainer: React.FC<SnapshotContainerProps> = ({
|
|
|
166
174
|
datasetId={datasetId}
|
|
167
175
|
isSnapshot={true}
|
|
168
176
|
isAdmin={isAdmin}
|
|
177
|
+
isDatasetAdmin={isDatasetAdmin}
|
|
169
178
|
/>
|
|
170
179
|
)}
|
|
171
180
|
renderFiles={() => (
|
|
@@ -233,7 +242,6 @@ const SnapshotContainer: React.FC<SnapshotContainerProps> = ({
|
|
|
233
242
|
dateModified={dateModified}
|
|
234
243
|
selected={selectedVersion}
|
|
235
244
|
setSelected={setSelectedVersion}
|
|
236
|
-
setDeprecatedModalIsOpen={setDeprecatedModalIsOpen}
|
|
237
245
|
/>
|
|
238
246
|
</div>
|
|
239
247
|
}
|
|
@@ -371,18 +379,6 @@ const SnapshotContainer: React.FC<SnapshotContainerProps> = ({
|
|
|
371
379
|
/>
|
|
372
380
|
</>
|
|
373
381
|
)}
|
|
374
|
-
renderDeprecatedModal={() => (
|
|
375
|
-
<Modal
|
|
376
|
-
isOpen={deprecatedmodalIsOpen}
|
|
377
|
-
toggle={() => setDeprecatedModalIsOpen(prevIsOpen => !prevIsOpen)}
|
|
378
|
-
closeText={'close'}
|
|
379
|
-
className="deprecated-modal">
|
|
380
|
-
<p>
|
|
381
|
-
You have selected a deprecated version. The author of the dataset
|
|
382
|
-
does not recommend this specific version.
|
|
383
|
-
</p>
|
|
384
|
-
</Modal>
|
|
385
|
-
)}
|
|
386
382
|
renderComments={() => (
|
|
387
383
|
<Comments
|
|
388
384
|
datasetId={dataset.id}
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { gql } from '@apollo/client'
|
|
2
|
-
|
|
3
|
-
export const DRAFT_FRAGMENT = gql`
|
|
4
|
-
fragment DatasetDraft on Dataset {
|
|
5
|
-
id
|
|
6
|
-
draft {
|
|
7
|
-
id
|
|
8
|
-
modified
|
|
9
|
-
readme
|
|
10
|
-
head
|
|
11
|
-
description {
|
|
12
|
-
Name
|
|
13
|
-
Authors
|
|
14
|
-
DatasetDOI
|
|
15
|
-
License
|
|
16
|
-
Acknowledgements
|
|
17
|
-
HowToAcknowledge
|
|
18
|
-
Funding
|
|
19
|
-
ReferencesAndLinks
|
|
20
|
-
EthicsApprovals
|
|
21
|
-
}
|
|
22
|
-
summary {
|
|
23
|
-
modalities
|
|
24
|
-
secondaryModalities
|
|
25
|
-
sessions
|
|
26
|
-
subjects
|
|
27
|
-
subjectMetadata {
|
|
28
|
-
participantId
|
|
29
|
-
age
|
|
30
|
-
sex
|
|
31
|
-
group
|
|
32
|
-
}
|
|
33
|
-
tasks
|
|
34
|
-
size
|
|
35
|
-
totalFiles
|
|
36
|
-
dataProcessed
|
|
37
|
-
pet {
|
|
38
|
-
BodyPart
|
|
39
|
-
ScannerManufacturer
|
|
40
|
-
ScannerManufacturersModelName
|
|
41
|
-
TracerName
|
|
42
|
-
TracerRadionuclide
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
`
|
|
48
|
-
|
|
49
|
-
export const DRAFT_FILES_FRAGMENT = gql`
|
|
50
|
-
fragment DatasetDraftFiles on Dataset {
|
|
51
|
-
id
|
|
52
|
-
draft {
|
|
53
|
-
id
|
|
54
|
-
files {
|
|
55
|
-
id
|
|
56
|
-
key
|
|
57
|
-
filename
|
|
58
|
-
size
|
|
59
|
-
directory
|
|
60
|
-
annexed
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
`
|
|
65
|
-
|
|
66
|
-
export const PERMISSION_FRAGMENT = gql`
|
|
67
|
-
fragment DatasetPermissions on Dataset {
|
|
68
|
-
id
|
|
69
|
-
permissions {
|
|
70
|
-
id
|
|
71
|
-
userPermissions {
|
|
72
|
-
user {
|
|
73
|
-
id
|
|
74
|
-
email
|
|
75
|
-
}
|
|
76
|
-
level
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
`
|
|
81
|
-
|
|
82
|
-
export const DATASET_SNAPSHOTS = gql`
|
|
83
|
-
fragment DatasetSnapshots on Dataset {
|
|
84
|
-
id
|
|
85
|
-
snapshots {
|
|
86
|
-
id
|
|
87
|
-
tag
|
|
88
|
-
created
|
|
89
|
-
hexsha
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
`
|
|
93
|
-
|
|
94
|
-
export const ISSUE_FIELDS = `
|
|
95
|
-
severity
|
|
96
|
-
code
|
|
97
|
-
reason
|
|
98
|
-
files {
|
|
99
|
-
evidence
|
|
100
|
-
line
|
|
101
|
-
character
|
|
102
|
-
reason
|
|
103
|
-
file {
|
|
104
|
-
name
|
|
105
|
-
path
|
|
106
|
-
relativePath
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
additionalFileCount
|
|
110
|
-
`
|
|
111
|
-
|
|
112
|
-
export const DATASET_ISSUES = gql`
|
|
113
|
-
fragment DatasetIssues on Dataset {
|
|
114
|
-
id
|
|
115
|
-
draft {
|
|
116
|
-
id
|
|
117
|
-
issues {
|
|
118
|
-
${ISSUE_FIELDS}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
`
|
|
123
|
-
|
|
124
|
-
export const SNAPSHOT_ISSUES = gql`
|
|
125
|
-
fragment SnapshotIssues on Snapshot {
|
|
126
|
-
id
|
|
127
|
-
issues {
|
|
128
|
-
${ISSUE_FIELDS}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
`
|
|
132
|
-
|
|
133
|
-
export const SNAPSHOT_FIELDS = gql`
|
|
134
|
-
fragment SnapshotFields on Snapshot {
|
|
135
|
-
id
|
|
136
|
-
tag
|
|
137
|
-
created
|
|
138
|
-
readme
|
|
139
|
-
description {
|
|
140
|
-
Name
|
|
141
|
-
Authors
|
|
142
|
-
DatasetDOI
|
|
143
|
-
License
|
|
144
|
-
Acknowledgements
|
|
145
|
-
HowToAcknowledge
|
|
146
|
-
Funding
|
|
147
|
-
ReferencesAndLinks
|
|
148
|
-
EthicsApprovals
|
|
149
|
-
}
|
|
150
|
-
files {
|
|
151
|
-
id
|
|
152
|
-
key
|
|
153
|
-
filename
|
|
154
|
-
size
|
|
155
|
-
directory
|
|
156
|
-
annexed
|
|
157
|
-
}
|
|
158
|
-
summary {
|
|
159
|
-
modalities
|
|
160
|
-
secondaryModalities
|
|
161
|
-
sessions
|
|
162
|
-
subjects
|
|
163
|
-
subjectMetadata {
|
|
164
|
-
participantId
|
|
165
|
-
age
|
|
166
|
-
sex
|
|
167
|
-
group
|
|
168
|
-
}
|
|
169
|
-
tasks
|
|
170
|
-
size
|
|
171
|
-
totalFiles
|
|
172
|
-
dataProcessed
|
|
173
|
-
pet {
|
|
174
|
-
BodyPart
|
|
175
|
-
ScannerManufacturer
|
|
176
|
-
ScannerManufacturersModelName
|
|
177
|
-
TracerName
|
|
178
|
-
TracerRadionuclide
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
analytics {
|
|
182
|
-
downloads
|
|
183
|
-
views
|
|
184
|
-
}
|
|
185
|
-
...SnapshotIssues
|
|
186
|
-
hexsha
|
|
187
|
-
}
|
|
188
|
-
${SNAPSHOT_ISSUES}
|
|
189
|
-
`
|
|
190
|
-
|
|
191
|
-
export const DATASET_METADATA = gql`
|
|
192
|
-
fragment DatasetMetadata on Dataset {
|
|
193
|
-
id
|
|
194
|
-
metadata {
|
|
195
|
-
datasetId
|
|
196
|
-
datasetUrl
|
|
197
|
-
datasetName
|
|
198
|
-
firstSnapshotCreatedAt
|
|
199
|
-
latestSnapshotCreatedAt
|
|
200
|
-
dxStatus
|
|
201
|
-
tasksCompleted
|
|
202
|
-
trialCount
|
|
203
|
-
grantFunderName
|
|
204
|
-
grantIdentifier
|
|
205
|
-
studyDesign
|
|
206
|
-
studyDomain
|
|
207
|
-
studyLongitudinal
|
|
208
|
-
dataProcessed
|
|
209
|
-
species
|
|
210
|
-
associatedPaperDOI
|
|
211
|
-
openneuroPaperDOI
|
|
212
|
-
seniorAuthor
|
|
213
|
-
adminUsers
|
|
214
|
-
ages
|
|
215
|
-
modalities
|
|
216
|
-
affirmedDefaced
|
|
217
|
-
affirmedConsent
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
`
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { gql } from '@apollo/client'
|
|
2
|
-
|
|
3
|
-
export const DRAFT_FRAGMENT = gql`
|
|
4
|
-
fragment DatasetDraft on Dataset {
|
|
5
|
-
id
|
|
6
|
-
draft {
|
|
7
|
-
id
|
|
8
|
-
modified
|
|
9
|
-
readme
|
|
10
|
-
head
|
|
11
|
-
description {
|
|
12
|
-
Name
|
|
13
|
-
Authors
|
|
14
|
-
DatasetDOI
|
|
15
|
-
License
|
|
16
|
-
Acknowledgements
|
|
17
|
-
HowToAcknowledge
|
|
18
|
-
Funding
|
|
19
|
-
ReferencesAndLinks
|
|
20
|
-
EthicsApprovals
|
|
21
|
-
}
|
|
22
|
-
summary {
|
|
23
|
-
modalities
|
|
24
|
-
secondaryModalities
|
|
25
|
-
sessions
|
|
26
|
-
subjects
|
|
27
|
-
subjectMetadata {
|
|
28
|
-
participantId
|
|
29
|
-
age
|
|
30
|
-
sex
|
|
31
|
-
group
|
|
32
|
-
}
|
|
33
|
-
tasks
|
|
34
|
-
size
|
|
35
|
-
totalFiles
|
|
36
|
-
dataProcessed
|
|
37
|
-
pet {
|
|
38
|
-
BodyPart
|
|
39
|
-
ScannerManufacturer
|
|
40
|
-
ScannerManufacturersModelName
|
|
41
|
-
TracerName
|
|
42
|
-
TracerRadionuclide
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
`
|
|
48
|
-
|
|
49
|
-
export const DRAFT_FILES_FRAGMENT = gql`
|
|
50
|
-
fragment DatasetDraftFiles on Dataset {
|
|
51
|
-
id
|
|
52
|
-
draft {
|
|
53
|
-
id
|
|
54
|
-
files {
|
|
55
|
-
id
|
|
56
|
-
key
|
|
57
|
-
filename
|
|
58
|
-
size
|
|
59
|
-
directory
|
|
60
|
-
annexed
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
`
|
|
65
|
-
|
|
66
|
-
export const PERMISSION_FRAGMENT = gql`
|
|
67
|
-
fragment DatasetPermissions on Dataset {
|
|
68
|
-
id
|
|
69
|
-
permissions {
|
|
70
|
-
id
|
|
71
|
-
userPermissions {
|
|
72
|
-
user {
|
|
73
|
-
id
|
|
74
|
-
email
|
|
75
|
-
}
|
|
76
|
-
level
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
`
|
|
81
|
-
|
|
82
|
-
export const DATASET_SNAPSHOTS = gql`
|
|
83
|
-
fragment DatasetSnapshots on Dataset {
|
|
84
|
-
id
|
|
85
|
-
snapshots {
|
|
86
|
-
id
|
|
87
|
-
tag
|
|
88
|
-
created
|
|
89
|
-
hexsha
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
`
|
|
93
|
-
|
|
94
|
-
export const ISSUE_FIELDS = `
|
|
95
|
-
severity
|
|
96
|
-
code
|
|
97
|
-
reason
|
|
98
|
-
files {
|
|
99
|
-
evidence
|
|
100
|
-
line
|
|
101
|
-
character
|
|
102
|
-
reason
|
|
103
|
-
file {
|
|
104
|
-
name
|
|
105
|
-
path
|
|
106
|
-
relativePath
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
additionalFileCount
|
|
110
|
-
`
|
|
111
|
-
|
|
112
|
-
export const DATASET_ISSUES = gql`
|
|
113
|
-
fragment DatasetIssues on Dataset {
|
|
114
|
-
id
|
|
115
|
-
draft {
|
|
116
|
-
id
|
|
117
|
-
issues {
|
|
118
|
-
${ISSUE_FIELDS}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
`
|
|
123
|
-
|
|
124
|
-
export const SNAPSHOT_ISSUES = gql`
|
|
125
|
-
fragment SnapshotIssues on Snapshot {
|
|
126
|
-
id
|
|
127
|
-
issues {
|
|
128
|
-
${ISSUE_FIELDS}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
`
|
|
132
|
-
|
|
133
|
-
export const SNAPSHOT_FIELDS = gql`
|
|
134
|
-
fragment SnapshotFields on Snapshot {
|
|
135
|
-
id
|
|
136
|
-
tag
|
|
137
|
-
created
|
|
138
|
-
readme
|
|
139
|
-
description {
|
|
140
|
-
Name
|
|
141
|
-
Authors
|
|
142
|
-
DatasetDOI
|
|
143
|
-
License
|
|
144
|
-
Acknowledgements
|
|
145
|
-
HowToAcknowledge
|
|
146
|
-
Funding
|
|
147
|
-
ReferencesAndLinks
|
|
148
|
-
EthicsApprovals
|
|
149
|
-
}
|
|
150
|
-
files {
|
|
151
|
-
id
|
|
152
|
-
key
|
|
153
|
-
filename
|
|
154
|
-
size
|
|
155
|
-
directory
|
|
156
|
-
annexed
|
|
157
|
-
}
|
|
158
|
-
summary {
|
|
159
|
-
modalities
|
|
160
|
-
secondaryModalities
|
|
161
|
-
sessions
|
|
162
|
-
subjects
|
|
163
|
-
subjectMetadata {
|
|
164
|
-
participantId
|
|
165
|
-
age
|
|
166
|
-
sex
|
|
167
|
-
group
|
|
168
|
-
}
|
|
169
|
-
tasks
|
|
170
|
-
size
|
|
171
|
-
totalFiles
|
|
172
|
-
dataProcessed
|
|
173
|
-
pet {
|
|
174
|
-
BodyPart
|
|
175
|
-
ScannerManufacturer
|
|
176
|
-
ScannerManufacturersModelName
|
|
177
|
-
TracerName
|
|
178
|
-
TracerRadionuclide
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
analytics {
|
|
182
|
-
downloads
|
|
183
|
-
views
|
|
184
|
-
}
|
|
185
|
-
...SnapshotIssues
|
|
186
|
-
hexsha
|
|
187
|
-
}
|
|
188
|
-
${SNAPSHOT_ISSUES}
|
|
189
|
-
`
|
|
190
|
-
|
|
191
|
-
export const DATASET_METADATA = gql`
|
|
192
|
-
fragment DatasetMetadata on Dataset {
|
|
193
|
-
id
|
|
194
|
-
metadata {
|
|
195
|
-
datasetId
|
|
196
|
-
datasetUrl
|
|
197
|
-
datasetName
|
|
198
|
-
firstSnapshotCreatedAt
|
|
199
|
-
latestSnapshotCreatedAt
|
|
200
|
-
dxStatus
|
|
201
|
-
tasksCompleted
|
|
202
|
-
trialCount
|
|
203
|
-
grantFunderName
|
|
204
|
-
grantIdentifier
|
|
205
|
-
studyDesign
|
|
206
|
-
studyDomain
|
|
207
|
-
studyLongitudinal
|
|
208
|
-
dataProcessed
|
|
209
|
-
species
|
|
210
|
-
associatedPaperDOI
|
|
211
|
-
openneuroPaperDOI
|
|
212
|
-
seniorAuthor
|
|
213
|
-
adminUsers
|
|
214
|
-
ages
|
|
215
|
-
modalities
|
|
216
|
-
affirmedDefaced
|
|
217
|
-
affirmedConsent
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
`
|