@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openneuro/app",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.20.0-alpha.0",
|
|
4
4
|
"description": "React JS web frontend for the OpenNeuro platform.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "public/client.js",
|
|
@@ -17,18 +17,19 @@
|
|
|
17
17
|
"@apollo/client": "3.7.2",
|
|
18
18
|
"@artsy/fresnel": "^1.3.1",
|
|
19
19
|
"@elastic/apm-rum": "5.11.0",
|
|
20
|
-
"@emotion/react": "11.
|
|
21
|
-
"@emotion/styled": "11.
|
|
20
|
+
"@emotion/react": "11.11.1",
|
|
21
|
+
"@emotion/styled": "11.11.0",
|
|
22
22
|
"@niivue/niivue": "0.34.0",
|
|
23
|
-
"@openneuro/client": "^4.
|
|
24
|
-
"@openneuro/components": "^4.
|
|
23
|
+
"@openneuro/client": "^4.20.0-alpha.0",
|
|
24
|
+
"@openneuro/components": "^4.20.0-alpha.0",
|
|
25
|
+
"@tanstack/react-table": "^8.9.3",
|
|
25
26
|
"bids-validator": "1.10.0",
|
|
26
27
|
"bytes": "^3.0.0",
|
|
27
28
|
"comlink": "^4.0.5",
|
|
28
29
|
"date-fns": "^2.16.1",
|
|
29
30
|
"draft-js": "^0.11.7",
|
|
30
31
|
"email-validator": "^2.0.4",
|
|
31
|
-
"graphql": "
|
|
32
|
+
"graphql": "16.6.0",
|
|
32
33
|
"jwt-decode": "^2.2.0",
|
|
33
34
|
"markdown-to-jsx": "^7.1.2",
|
|
34
35
|
"pluralize": "8.0.0",
|
|
@@ -41,23 +42,11 @@
|
|
|
41
42
|
"react-router-dom": "6.3.0",
|
|
42
43
|
"react-toastify": "6.0.9",
|
|
43
44
|
"react-usestateref": "^1.0.8",
|
|
44
|
-
"react-virtualized": "remorses/react-virtualized-fixed-import.git#9.22.3",
|
|
45
45
|
"semver": "^5.5.0",
|
|
46
46
|
"subscriptions-transport-ws": "0.11.0",
|
|
47
47
|
"universal-cookie": "^4.0.4"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@babel/core": "^7.6.4",
|
|
51
|
-
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
|
52
|
-
"@babel/plugin-proposal-object-rest-spread": "^7.6.2",
|
|
53
|
-
"@babel/plugin-proposal-optional-chaining": "^7.6.0",
|
|
54
|
-
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
|
55
|
-
"@babel/plugin-transform-runtime": "^7.6.2",
|
|
56
|
-
"@babel/preset-env": "^7.6.3",
|
|
57
|
-
"@babel/preset-react": "^7.6.3",
|
|
58
|
-
"@babel/preset-typescript": "^7.7.4",
|
|
59
|
-
"@babel/runtime": "^7.6.3",
|
|
60
|
-
"@babel/runtime-corejs3": "^7.13.10",
|
|
61
50
|
"@testing-library/jest-dom": "^5.11.4",
|
|
62
51
|
"@testing-library/react": "^11.1.0",
|
|
63
52
|
"@types/jsdom": "^16",
|
|
@@ -71,15 +60,15 @@
|
|
|
71
60
|
"history": "5.3.0",
|
|
72
61
|
"jsdom": "^16.5.3",
|
|
73
62
|
"object.fromentries": "^2.0.0",
|
|
74
|
-
"rollup-plugin-polyfill-node": "
|
|
63
|
+
"rollup-plugin-polyfill-node": "0.12.0",
|
|
75
64
|
"sass": "^1.32.8",
|
|
76
65
|
"stream-browserify": "^3.0.0",
|
|
77
|
-
"typescript": "
|
|
66
|
+
"typescript": "5.1.6",
|
|
78
67
|
"vite": "^3.2.7",
|
|
79
|
-
"vitest": "
|
|
68
|
+
"vitest": "0.33.0"
|
|
80
69
|
},
|
|
81
70
|
"publishConfig": {
|
|
82
71
|
"access": "public"
|
|
83
72
|
},
|
|
84
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "cc6822c27d8e66562e325042fc11a2998cb2eef7"
|
|
85
74
|
}
|
package/src/client.jsx
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import jwtDecode from 'jwt-decode'
|
|
2
2
|
|
|
3
|
+
interface OpenNeuroTokenProfile {
|
|
4
|
+
sub: string
|
|
5
|
+
email: string
|
|
6
|
+
provider: string
|
|
7
|
+
name: string
|
|
8
|
+
admin: boolean
|
|
9
|
+
iat: number
|
|
10
|
+
exp: number
|
|
11
|
+
}
|
|
12
|
+
|
|
3
13
|
/**
|
|
4
14
|
* Read JSON object from JWT string
|
|
5
15
|
* @param {string} token
|
|
@@ -9,7 +19,7 @@ export const parseJwt = jwtDecode
|
|
|
9
19
|
/**
|
|
10
20
|
* Retrieve the user profile from JWT cookie
|
|
11
21
|
*/
|
|
12
|
-
export
|
|
22
|
+
export function getProfile(cookies): OpenNeuroTokenProfile {
|
|
13
23
|
const accessToken = cookies['accessToken']
|
|
14
24
|
return accessToken ? parseJwt(accessToken) : null
|
|
15
25
|
}
|
|
@@ -28,7 +38,7 @@ export const getUnexpiredProfile = cookies => {
|
|
|
28
38
|
* @param {object} profile A profile returned by getProfile()
|
|
29
39
|
* @returns {boolean} False if expired
|
|
30
40
|
*/
|
|
31
|
-
export const guardExpired = profile => {
|
|
41
|
+
export const guardExpired = (profile: OpenNeuroTokenProfile): boolean => {
|
|
32
42
|
const now = new Date().getTime() / 1000
|
|
33
43
|
if (profile && now < profile.exp) {
|
|
34
44
|
return true
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
2
|
import React from 'react'
|
|
3
3
|
import { useCookies } from 'react-cookie'
|
|
4
|
-
import { getProfile, guardExpired } from './profile
|
|
4
|
+
import { getProfile, guardExpired } from './profile'
|
|
5
5
|
|
|
6
6
|
const withProfile = WrappedComponent => {
|
|
7
7
|
return props => {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`DataTable component > renders a basic table 1`] = `
|
|
4
|
+
<DocumentFragment>
|
|
5
|
+
<table>
|
|
6
|
+
<thead>
|
|
7
|
+
<tr
|
|
8
|
+
class="css-lxeoei"
|
|
9
|
+
>
|
|
10
|
+
<th
|
|
11
|
+
class="css-ysxg9l"
|
|
12
|
+
colspan="1"
|
|
13
|
+
>
|
|
14
|
+
<div
|
|
15
|
+
class="cursor-pointer select-none"
|
|
16
|
+
>
|
|
17
|
+
col1
|
|
18
|
+
</div>
|
|
19
|
+
</th>
|
|
20
|
+
<th
|
|
21
|
+
class="css-ysxg9l"
|
|
22
|
+
colspan="1"
|
|
23
|
+
>
|
|
24
|
+
<div
|
|
25
|
+
class="cursor-pointer select-none"
|
|
26
|
+
>
|
|
27
|
+
col2
|
|
28
|
+
</div>
|
|
29
|
+
</th>
|
|
30
|
+
<th
|
|
31
|
+
class="css-ysxg9l"
|
|
32
|
+
colspan="1"
|
|
33
|
+
>
|
|
34
|
+
<div
|
|
35
|
+
class="cursor-pointer select-none"
|
|
36
|
+
>
|
|
37
|
+
col3
|
|
38
|
+
</div>
|
|
39
|
+
</th>
|
|
40
|
+
</tr>
|
|
41
|
+
</thead>
|
|
42
|
+
<tbody>
|
|
43
|
+
<tr
|
|
44
|
+
class="css-lxeoei"
|
|
45
|
+
>
|
|
46
|
+
<td
|
|
47
|
+
class="css-14o8u5y"
|
|
48
|
+
>
|
|
49
|
+
text
|
|
50
|
+
</td>
|
|
51
|
+
<td
|
|
52
|
+
class="css-14o8u5y"
|
|
53
|
+
>
|
|
54
|
+
50
|
|
55
|
+
</td>
|
|
56
|
+
<td
|
|
57
|
+
class="css-14o8u5y"
|
|
58
|
+
>
|
|
59
|
+
string value
|
|
60
|
+
</td>
|
|
61
|
+
</tr>
|
|
62
|
+
<tr
|
|
63
|
+
class="css-lxeoei"
|
|
64
|
+
>
|
|
65
|
+
<td
|
|
66
|
+
class="css-14o8u5y"
|
|
67
|
+
>
|
|
68
|
+
more
|
|
69
|
+
</td>
|
|
70
|
+
<td
|
|
71
|
+
class="css-14o8u5y"
|
|
72
|
+
>
|
|
73
|
+
75
|
|
74
|
+
</td>
|
|
75
|
+
<td
|
|
76
|
+
class="css-14o8u5y"
|
|
77
|
+
>
|
|
78
|
+
more strings
|
|
79
|
+
</td>
|
|
80
|
+
</tr>
|
|
81
|
+
</tbody>
|
|
82
|
+
</table>
|
|
83
|
+
</DocumentFragment>
|
|
84
|
+
`;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import { DataTable } from '../data-table'
|
|
4
|
+
|
|
5
|
+
const tableData = [
|
|
6
|
+
{ col1: 'text', col2: 50, col3: 'string value' },
|
|
7
|
+
{ col1: 'more', col2: 75, col3: 'more strings' },
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
describe('DataTable component', () => {
|
|
11
|
+
it('renders a basic table', () => {
|
|
12
|
+
const { asFragment } = render(<DataTable data={tableData}></DataTable>)
|
|
13
|
+
expect(asFragment()).toMatchSnapshot()
|
|
14
|
+
})
|
|
15
|
+
})
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {
|
|
3
|
+
flexRender,
|
|
4
|
+
getCoreRowModel,
|
|
5
|
+
getSortedRowModel,
|
|
6
|
+
useReactTable,
|
|
7
|
+
createColumnHelper,
|
|
8
|
+
SortingState,
|
|
9
|
+
} from '@tanstack/react-table'
|
|
10
|
+
import styled from '@emotion/styled'
|
|
11
|
+
import { format, parseISO, isValid } from 'date-fns'
|
|
12
|
+
|
|
13
|
+
interface DataTableProps {
|
|
14
|
+
data: any[]
|
|
15
|
+
downloadFilename?: string
|
|
16
|
+
hideColumns?: string[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const TH = styled.th`
|
|
20
|
+
border-bottom: 1px solid #ccc;
|
|
21
|
+
margin-right: 2em;
|
|
22
|
+
div {
|
|
23
|
+
display: inline-block;
|
|
24
|
+
}
|
|
25
|
+
`
|
|
26
|
+
|
|
27
|
+
const TR = styled.tr`
|
|
28
|
+
margin-right: 1em;
|
|
29
|
+
margin-bottom: 0.8em;
|
|
30
|
+
`
|
|
31
|
+
|
|
32
|
+
const TD = styled.td`
|
|
33
|
+
padding: 3px;
|
|
34
|
+
`
|
|
35
|
+
|
|
36
|
+
function CellFormat(props): any {
|
|
37
|
+
const value = props.getValue()
|
|
38
|
+
if (typeof value === 'string' && isValid(parseISO(value))) {
|
|
39
|
+
return format(parseISO(value), 'yyyy-MM-dd')
|
|
40
|
+
} else if (typeof value === 'string' && /^ds[0-9]{6}$/.exec(value)) {
|
|
41
|
+
return <a href={`/datasets/${value}`}>{value}</a>
|
|
42
|
+
} else if (Array.isArray(value)) {
|
|
43
|
+
return value.join(',')
|
|
44
|
+
} else {
|
|
45
|
+
return value
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Take a general table-like array of objects (one object per row) and render as a simple table with sortable columns
|
|
51
|
+
*/
|
|
52
|
+
export function DataTable<T>({
|
|
53
|
+
data,
|
|
54
|
+
hideColumns = [],
|
|
55
|
+
}: DataTableProps): React.ReactElement {
|
|
56
|
+
const [sorting, setSorting] = React.useState<SortingState>([])
|
|
57
|
+
const columnHelper = createColumnHelper<T>()
|
|
58
|
+
const columns = React.useMemo(
|
|
59
|
+
() =>
|
|
60
|
+
Object.keys(data[0])
|
|
61
|
+
.filter(name => !hideColumns.includes(name))
|
|
62
|
+
.map(name =>
|
|
63
|
+
columnHelper.accessor(name as any, {
|
|
64
|
+
header: name,
|
|
65
|
+
cell: CellFormat,
|
|
66
|
+
}),
|
|
67
|
+
),
|
|
68
|
+
[data, columnHelper, hideColumns],
|
|
69
|
+
)
|
|
70
|
+
const memoData = React.useMemo(() => data, [data])
|
|
71
|
+
const table = useReactTable({
|
|
72
|
+
data: memoData,
|
|
73
|
+
columns,
|
|
74
|
+
getCoreRowModel: getCoreRowModel(),
|
|
75
|
+
getSortedRowModel: getSortedRowModel(),
|
|
76
|
+
state: {
|
|
77
|
+
sorting,
|
|
78
|
+
},
|
|
79
|
+
onSortingChange: setSorting,
|
|
80
|
+
})
|
|
81
|
+
return (
|
|
82
|
+
<table>
|
|
83
|
+
<thead>
|
|
84
|
+
{table.getHeaderGroups().map(headerGroup => (
|
|
85
|
+
<TR key={headerGroup.id}>
|
|
86
|
+
{headerGroup.headers.map(header => (
|
|
87
|
+
<TH key={header.id} colSpan={header.colSpan}>
|
|
88
|
+
{header.isPlaceholder ? null : (
|
|
89
|
+
<div
|
|
90
|
+
{...{
|
|
91
|
+
className: header.column.getCanSort()
|
|
92
|
+
? 'cursor-pointer select-none'
|
|
93
|
+
: '',
|
|
94
|
+
onClick: header.column.getToggleSortingHandler(),
|
|
95
|
+
}}>
|
|
96
|
+
{flexRender(
|
|
97
|
+
header.column.columnDef.header,
|
|
98
|
+
header.getContext(),
|
|
99
|
+
)}
|
|
100
|
+
|
|
101
|
+
{{
|
|
102
|
+
asc: '▲',
|
|
103
|
+
desc: '▼',
|
|
104
|
+
}[header.column.getIsSorted() as string] ?? null}
|
|
105
|
+
</div>
|
|
106
|
+
)}
|
|
107
|
+
</TH>
|
|
108
|
+
))}
|
|
109
|
+
</TR>
|
|
110
|
+
))}
|
|
111
|
+
</thead>
|
|
112
|
+
<tbody>
|
|
113
|
+
{table.getRowModel().rows.map(row => (
|
|
114
|
+
<TR key={row.id}>
|
|
115
|
+
{row.getVisibleCells().map(cell => (
|
|
116
|
+
<TD key={cell.id}>
|
|
117
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
118
|
+
</TD>
|
|
119
|
+
))}
|
|
120
|
+
</TR>
|
|
121
|
+
))}
|
|
122
|
+
</tbody>
|
|
123
|
+
</table>
|
|
124
|
+
)
|
|
125
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Vitest Snapshot v1
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
3
|
exports[`SnapshotContainer component > includes JSON-LD data in the header 1`] = `
|
|
4
4
|
{
|
|
@@ -74,7 +74,7 @@ exports[`SnapshotContainer component > renders successfully 1`] = `
|
|
|
74
74
|
data-tooltip="Get notified on new versions/comments"
|
|
75
75
|
>
|
|
76
76
|
<span
|
|
77
|
-
class="toggle-counter
|
|
77
|
+
class="toggle-counter"
|
|
78
78
|
>
|
|
79
79
|
<button
|
|
80
80
|
aria-label="Following"
|
|
@@ -105,7 +105,7 @@ exports[`SnapshotContainer component > renders successfully 1`] = `
|
|
|
105
105
|
data-tooltip="Save to your bookmarked datasets"
|
|
106
106
|
>
|
|
107
107
|
<span
|
|
108
|
-
class="toggle-counter
|
|
108
|
+
class="toggle-counter"
|
|
109
109
|
>
|
|
110
110
|
<button
|
|
111
111
|
aria-label="Bookmark"
|
|
@@ -15,8 +15,7 @@ import useDatasetDeletedSubscription, {
|
|
|
15
15
|
datasetDeletedToast,
|
|
16
16
|
} from '../datalad/subscriptions/useDatasetDeletedSubscription.jsx'
|
|
17
17
|
import useDraftSubscription from '../datalad/subscriptions/useDraftSubscription.js'
|
|
18
|
-
|
|
19
|
-
import { DATASET_COMMENTS } from '../datalad/dataset/comments-fragments.js'
|
|
18
|
+
|
|
20
19
|
import ErrorBoundary, {
|
|
21
20
|
ErrorBoundaryAssertionFailureException,
|
|
22
21
|
} from '../errors/errorBoundary.jsx'
|
|
@@ -24,113 +23,7 @@ import DatasetRedirect from '../datalad/routes/dataset-redirect'
|
|
|
24
23
|
import { trackAnalytics } from '../utils/datalad'
|
|
25
24
|
import FourOFourPage from '../errors/404page'
|
|
26
25
|
import FourOThreePage from '../errors/403page'
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Generate the dataset page query
|
|
30
|
-
*/
|
|
31
|
-
export const getDatasetPage = gql`
|
|
32
|
-
query dataset($datasetId: ID!) {
|
|
33
|
-
dataset(id: $datasetId) {
|
|
34
|
-
id
|
|
35
|
-
created
|
|
36
|
-
public
|
|
37
|
-
following
|
|
38
|
-
followers {
|
|
39
|
-
userId
|
|
40
|
-
}
|
|
41
|
-
starred
|
|
42
|
-
stars {
|
|
43
|
-
userId
|
|
44
|
-
}
|
|
45
|
-
worker
|
|
46
|
-
...DatasetDraft
|
|
47
|
-
...DatasetPermissions
|
|
48
|
-
...DatasetSnapshots
|
|
49
|
-
...DatasetIssues
|
|
50
|
-
...DatasetMetadata
|
|
51
|
-
...DatasetComments
|
|
52
|
-
uploader {
|
|
53
|
-
id
|
|
54
|
-
name
|
|
55
|
-
email
|
|
56
|
-
orcid
|
|
57
|
-
}
|
|
58
|
-
analytics {
|
|
59
|
-
downloads
|
|
60
|
-
views
|
|
61
|
-
}
|
|
62
|
-
derivatives {
|
|
63
|
-
name
|
|
64
|
-
s3Url
|
|
65
|
-
dataladUrl
|
|
66
|
-
local
|
|
67
|
-
}
|
|
68
|
-
onBrainlife
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
${DatasetQueryFragments.DRAFT_FRAGMENT}
|
|
72
|
-
${DatasetQueryFragments.PERMISSION_FRAGMENT}
|
|
73
|
-
${DatasetQueryFragments.DATASET_SNAPSHOTS}
|
|
74
|
-
${DatasetQueryFragments.DATASET_ISSUES}
|
|
75
|
-
${DatasetQueryFragments.DATASET_METADATA}
|
|
76
|
-
${DATASET_COMMENTS}
|
|
77
|
-
`
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Add files fragment for draft route
|
|
81
|
-
*/
|
|
82
|
-
export const getDraftPage = gql`
|
|
83
|
-
query dataset($datasetId: ID!) {
|
|
84
|
-
dataset(id: $datasetId) {
|
|
85
|
-
id
|
|
86
|
-
created
|
|
87
|
-
public
|
|
88
|
-
following
|
|
89
|
-
followers {
|
|
90
|
-
userId
|
|
91
|
-
}
|
|
92
|
-
starred
|
|
93
|
-
stars {
|
|
94
|
-
userId
|
|
95
|
-
}
|
|
96
|
-
reviewers {
|
|
97
|
-
id
|
|
98
|
-
expiration
|
|
99
|
-
}
|
|
100
|
-
worker
|
|
101
|
-
...DatasetDraft
|
|
102
|
-
...DatasetDraftFiles
|
|
103
|
-
...DatasetPermissions
|
|
104
|
-
...DatasetSnapshots
|
|
105
|
-
...DatasetIssues
|
|
106
|
-
...DatasetMetadata
|
|
107
|
-
...DatasetComments
|
|
108
|
-
uploader {
|
|
109
|
-
id
|
|
110
|
-
name
|
|
111
|
-
email
|
|
112
|
-
orcid
|
|
113
|
-
}
|
|
114
|
-
analytics {
|
|
115
|
-
downloads
|
|
116
|
-
views
|
|
117
|
-
}
|
|
118
|
-
derivatives {
|
|
119
|
-
name
|
|
120
|
-
s3Url
|
|
121
|
-
dataladUrl
|
|
122
|
-
local
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
${DatasetQueryFragments.DRAFT_FRAGMENT}
|
|
127
|
-
${DatasetQueryFragments.DRAFT_FILES_FRAGMENT}
|
|
128
|
-
${DatasetQueryFragments.PERMISSION_FRAGMENT}
|
|
129
|
-
${DatasetQueryFragments.DATASET_SNAPSHOTS}
|
|
130
|
-
${DatasetQueryFragments.DATASET_ISSUES}
|
|
131
|
-
${DatasetQueryFragments.DATASET_METADATA}
|
|
132
|
-
${DATASET_COMMENTS}
|
|
133
|
-
`
|
|
26
|
+
import { getDatasetPage, getDraftPage } from '../queries/dataset'
|
|
134
27
|
|
|
135
28
|
/**
|
|
136
29
|
* Query to load and render dataset page - most dataset loading is done here
|
|
@@ -121,13 +121,13 @@ const DraftContainer: React.FC<DraftContainerProps> = ({ dataset }) => {
|
|
|
121
121
|
</EditDescriptionField>
|
|
122
122
|
<FollowToggles>
|
|
123
123
|
<FollowDataset
|
|
124
|
-
profile={profile}
|
|
124
|
+
profile={profile !== null}
|
|
125
125
|
datasetId={dataset.id}
|
|
126
126
|
following={dataset.following}
|
|
127
127
|
followers={dataset.followers.length}
|
|
128
128
|
/>
|
|
129
129
|
<StarDataset
|
|
130
|
-
profile={profile}
|
|
130
|
+
profile={profile !== null}
|
|
131
131
|
datasetId={dataset.id}
|
|
132
132
|
starred={dataset.starred}
|
|
133
133
|
stars={dataset.stars.length}
|
|
@@ -7,7 +7,7 @@ import { Media } from '../../styles/media'
|
|
|
7
7
|
import RemoveAnnexObject from '../mutations/remove-annex-object.jsx'
|
|
8
8
|
import FlagAnnexObject from '../mutations/flag-annex-object.jsx'
|
|
9
9
|
import { isAdmin } from '../../authentication/admin-user.jsx'
|
|
10
|
-
import { getProfile, hasEditPermissions } from '../../authentication/profile
|
|
10
|
+
import { getProfile, hasEditPermissions } from '../../authentication/profile'
|
|
11
11
|
import { Icon } from '@openneuro/components/icon'
|
|
12
12
|
import { Tooltip } from '@openneuro/components/tooltip'
|
|
13
13
|
import { useCookies } from 'react-cookie'
|
|
@@ -136,7 +136,8 @@ const File = ({
|
|
|
136
136
|
{filename}
|
|
137
137
|
<span className="filetree-editfile">
|
|
138
138
|
<Media greaterThanOrEqual="medium">
|
|
139
|
-
<Tooltip
|
|
139
|
+
<Tooltip
|
|
140
|
+
tooltip={`Download: ${bytes.format(Number(size)) as string}`}>
|
|
140
141
|
<span className="edit-file download-file">
|
|
141
142
|
<a
|
|
142
143
|
href={
|
|
@@ -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 FileViewerCsv = ({ data }) => {
|
|
7
7
|
const decoder = new TextDecoder()
|