@openneuro/app 4.36.2 → 4.37.0-alpha.1

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.
Files changed (74) hide show
  1. package/package.json +5 -3
  2. package/src/scripts/components/accordion/accordion.scss +1 -1
  3. package/src/scripts/components/activity-slider/ActivitySlider.tsx +4 -22
  4. package/src/scripts/components/activity-slider/slider.scss +1 -82
  5. package/src/scripts/components/button/button.scss +1 -1
  6. package/src/scripts/components/count-toggle/count-toggle.scss +1 -1
  7. package/src/scripts/components/dropdown/dropdown.scss +1 -1
  8. package/src/scripts/components/facets/facet.scss +5 -4
  9. package/src/scripts/components/footer/footer.scss +1 -1
  10. package/src/scripts/components/front-page/front-page.scss +1 -1
  11. package/src/scripts/components/header/header.scss +1 -1
  12. package/src/scripts/components/input/input.scss +1 -1
  13. package/src/scripts/components/input/term-search.scss +1 -1
  14. package/src/scripts/components/loading/loading.scss +1 -1
  15. package/src/scripts/components/modal/modal.scss +1 -1
  16. package/src/scripts/components/modality-cube/ModalityHexagon.tsx +29 -0
  17. package/src/scripts/components/modality-cube/modality-cube.scss +1 -1
  18. package/src/scripts/components/modality-cube/modality-hexagon.scss +93 -0
  19. package/src/scripts/components/page/page.scss +1 -1
  20. package/src/scripts/components/progress-bar/progress-bar.scss +1 -1
  21. package/src/scripts/components/radio/radio.scss +2 -2
  22. package/src/scripts/components/range/TwoHandleRange.scss +3 -3
  23. package/src/scripts/components/read-more/read-more.scss +1 -1
  24. package/src/scripts/components/scss/upload-modal.scss +1 -1
  25. package/src/scripts/components/tooltip/tooltip.scss +1 -1
  26. package/src/scripts/dataset/__tests__/__snapshots__/snapshot-container.spec.tsx.snap +132 -128
  27. package/src/scripts/dataset/__tests__/draft-container.spec.tsx +136 -0
  28. package/src/scripts/dataset/common/follow-toggles.tsx +1 -1
  29. package/src/scripts/dataset/components/DatasetHeader.tsx +13 -16
  30. package/src/scripts/dataset/components/DatasetToolButton.tsx +6 -7
  31. package/src/scripts/dataset/components/DatasetTools.tsx +6 -2
  32. package/src/scripts/dataset/draft-container.tsx +30 -24
  33. package/src/scripts/dataset/files/{file-display.jsx → file-display.tsx} +32 -19
  34. package/src/scripts/dataset/routes/tab-routes-draft.tsx +6 -1
  35. package/src/scripts/dataset/routes/tab-routes-snapshot.tsx +5 -1
  36. package/src/scripts/dataset/snapshot-container.tsx +37 -43
  37. package/src/scripts/scss/dataset/dataset-page.scss +44 -120
  38. package/src/scripts/scss/variables.scss +65 -13
  39. package/src/scripts/{components/search-page → search}/__tests__/NuerobagelSearch.spec.tsx +1 -1
  40. package/src/scripts/search/components/DatasetsRadioTabs.tsx +103 -0
  41. package/src/scripts/{components/search-page → search/components}/FilterListItem.tsx +1 -1
  42. package/src/scripts/{components/search-page → search/components}/FiltersBlock.tsx +5 -8
  43. package/src/scripts/search/components/MetaListItemList.tsx +31 -0
  44. package/src/scripts/{components/search-page → search/components}/SearchPage.tsx +15 -8
  45. package/src/scripts/search/components/SearchResultDetails.tsx +167 -0
  46. package/src/scripts/{components/search-page → search/components}/SearchResultItem.tsx +57 -173
  47. package/src/scripts/search/components/SearchResultsList.tsx +45 -0
  48. package/src/scripts/{components/search-page → search/components}/SearchSort.tsx +2 -2
  49. package/src/scripts/search/filters-block-container.tsx +1 -1
  50. package/src/scripts/search/inputs/index.ts +0 -4
  51. package/src/scripts/search/inputs/sliding-radio-group.tsx +127 -0
  52. package/src/scripts/search/inputs/sort-by-select.tsx +1 -1
  53. package/src/scripts/{components/search-page → search/scss}/filters-block.scss +1 -1
  54. package/src/scripts/{components/search-page → search/scss}/search-page.scss +123 -92
  55. package/src/scripts/search/scss/search-result-details.scss +70 -0
  56. package/src/scripts/{components/search-page → search/scss}/search-result.scss +29 -56
  57. package/src/scripts/{components/search-page → search/scss}/search-sort.scss +1 -1
  58. package/src/scripts/search/scss/sliding-radio-group.scss +115 -0
  59. package/src/scripts/search/search-container.tsx +90 -24
  60. package/src/scripts/search/use-search-results.tsx +3 -0
  61. package/src/scripts/users/github-auth-button.tsx +1 -1
  62. package/src/scripts/components/scss/_variables.scss +0 -245
  63. package/src/scripts/components/search-page/SearchResultsList.tsx +0 -29
  64. package/src/scripts/dataset/files/index.tsx +0 -6
  65. package/src/scripts/search/inputs/admin-allDatasets-toggle.tsx +0 -47
  66. package/src/scripts/search/inputs/show-datasets-radios.tsx +0 -74
  67. /package/src/scripts/{components/search-page → search/components}/CommunityHeader.tsx +0 -0
  68. /package/src/scripts/{components/search-page → search/components}/FacetBlockContainerExample.tsx +0 -0
  69. /package/src/scripts/{components/search-page → search/components}/FilterDateItem.tsx +0 -0
  70. /package/src/scripts/{components/search-page → search/components}/ModalityHeader.tsx +0 -0
  71. /package/src/scripts/{components/search-page → search/components}/NeurobagelSearch.tsx +0 -0
  72. /package/src/scripts/{components/search-page → search/components}/SearchSortContainerExample.tsx +0 -0
  73. /package/src/scripts/{components/search-page → search/components}/TermListItem.tsx +0 -0
  74. /package/src/scripts/{components/search-page → search/components}/neurobagel_logo.svg +0 -0
@@ -39,10 +39,10 @@ exports[`SnapshotContainer component > renders successfully 1`] = `
39
39
  class="container"
40
40
  >
41
41
  <div
42
- class="grid grid-between"
42
+ class="ds-header-inner"
43
43
  >
44
44
  <div
45
- class="col"
45
+ class="ds-inner-left"
46
46
  >
47
47
  <h1>
48
48
  <a
@@ -52,7 +52,7 @@ exports[`SnapshotContainer component > renders successfully 1`] = `
52
52
  class="hexagon-wrapper"
53
53
  >
54
54
  <div
55
- class="hexagon no-modality"
55
+ class="hexagon mri"
56
56
  />
57
57
  <div
58
58
  class="label"
@@ -62,73 +62,157 @@ exports[`SnapshotContainer component > renders successfully 1`] = `
62
62
  </div>
63
63
  </a>
64
64
  DS003-downsampled (only T1)
65
- <div
66
- class="css-1dyyc64"
65
+ </h1>
66
+ <div
67
+ class="dataset-tool-buttons"
68
+ >
69
+ <span
70
+ class="css-1dvuowd"
67
71
  >
68
- <div
69
- class="toggle-counter-wrap"
72
+ <span
73
+ class="css-1hlo510"
70
74
  >
71
75
  <span
72
76
  class=" "
73
77
  data-flow="up"
74
- data-tooltip="Get notified on new versions/comments"
78
+ data-tooltip="View the dataset file tree"
75
79
  >
76
- <span
77
- class="toggle-counter"
80
+ <a
81
+ href="/datasets/ds001032/versions/1.0.0"
78
82
  >
79
- <button
80
- aria-label="Following"
81
- class="on-button on-button--medium on-button--default icon-text toggle-btn active"
82
- role="button"
83
- type="button"
83
+ <span
84
+ aria-label="Files"
85
+ class=" on-icon icon-text "
86
+ role="img"
84
87
  >
85
88
  <i
86
- aria-hidden="true"
87
- class="fa fa-star css-1qxtz39"
89
+ class="fa fa-folder"
88
90
  />
89
- Following
90
- <span
91
- class="count-span"
92
- >
93
- 1
94
- </span>
95
- </button>
96
- </span>
91
+ Files
92
+ </span>
93
+ </a>
97
94
  </span>
98
- </div>
99
- <div
100
- class="toggle-counter-wrap"
95
+ </span>
96
+ <span
97
+ class="css-126f3py"
101
98
  >
102
99
  <span
103
100
  class=" "
104
101
  data-flow="up"
105
- data-tooltip="Save to your bookmarked datasets"
102
+ data-tooltip="Agree to Terms of Service to Download"
106
103
  >
107
- <span
108
- class="toggle-counter"
104
+ <a
105
+ href="/datasets/ds001032/versions/1.0.0/download"
109
106
  >
110
- <button
111
- aria-label="Bookmark"
112
- class="on-button on-button--medium on-button--default icon-text toggle-btn"
113
- role="button"
114
- type="button"
107
+ <span
108
+ aria-label="Download"
109
+ class=" on-icon icon-text "
110
+ role="img"
115
111
  >
116
112
  <i
117
- aria-hidden="true"
118
- class="fa fa-bookmark css-1qxtz39"
113
+ class="fa fa-download"
119
114
  />
120
- Bookmark
121
- <span
122
- class="count-span"
123
- >
124
- 0
125
- </span>
126
- </button>
127
- </span>
115
+ Download
116
+ </span>
117
+ </a>
128
118
  </span>
129
- </div>
119
+ </span>
120
+ <span
121
+ class="css-1hlo510"
122
+ >
123
+ <span
124
+ class=" "
125
+ data-flow="up"
126
+ data-tooltip="View the dataset metadata"
127
+ >
128
+ <a
129
+ href="/datasets/ds001032/versions/1.0.0/metadata"
130
+ >
131
+ <span
132
+ aria-label="Metadata"
133
+ class=" on-icon icon-text "
134
+ role="img"
135
+ >
136
+ <i
137
+ class="fa fa-file-code"
138
+ />
139
+ Metadata
140
+ </span>
141
+ </a>
142
+ </span>
143
+ </span>
144
+ </span>
145
+ </div>
146
+ </div>
147
+ <div
148
+ class="ds-inner-right"
149
+ >
150
+ <div
151
+ class="css-zw18vc"
152
+ >
153
+ <div
154
+ class="toggle-counter-wrap"
155
+ >
156
+ <span
157
+ class=" "
158
+ data-flow="up"
159
+ data-tooltip="Get notified on new versions/comments"
160
+ >
161
+ <span
162
+ class="toggle-counter"
163
+ >
164
+ <button
165
+ aria-label="Following"
166
+ class="on-button on-button--medium on-button--default icon-text toggle-btn active"
167
+ role="button"
168
+ type="button"
169
+ >
170
+ <i
171
+ aria-hidden="true"
172
+ class="fa fa-star css-1qxtz39"
173
+ />
174
+ Following
175
+ <span
176
+ class="count-span"
177
+ >
178
+ 1
179
+ </span>
180
+ </button>
181
+ </span>
182
+ </span>
130
183
  </div>
131
- </h1>
184
+ <div
185
+ class="toggle-counter-wrap"
186
+ >
187
+ <span
188
+ class=" "
189
+ data-flow="up"
190
+ data-tooltip="Save to your bookmarked datasets"
191
+ >
192
+ <span
193
+ class="toggle-counter"
194
+ >
195
+ <button
196
+ aria-label="Bookmark"
197
+ class="on-button on-button--medium on-button--default icon-text toggle-btn"
198
+ role="button"
199
+ type="button"
200
+ >
201
+ <i
202
+ aria-hidden="true"
203
+ class="fa fa-bookmark css-1qxtz39"
204
+ />
205
+ Bookmark
206
+ <span
207
+ class="count-span"
208
+ >
209
+ 0
210
+ </span>
211
+ </button>
212
+ </span>
213
+ </span>
214
+ </div>
215
+ </div>
132
216
  </div>
133
217
  </div>
134
218
  </div>
@@ -371,86 +455,6 @@ exports[`SnapshotContainer component > renders successfully 1`] = `
371
455
  </div>
372
456
  </div>
373
457
  </div>
374
- <div
375
- class="dataset-tool-buttons"
376
- >
377
- <span
378
- class="css-1dvuowd"
379
- >
380
- <span
381
- class="css-1mdlu11"
382
- >
383
- <span
384
- class=" "
385
- data-flow="up"
386
- data-tooltip="View the dataset file tree"
387
- >
388
- <a
389
- href="/datasets/ds001032/versions/1.0.0"
390
- >
391
- <span
392
- aria-label="Files"
393
- class=" on-icon icon-text "
394
- role="img"
395
- >
396
- <i
397
- class="fa fa-folder"
398
- />
399
- Files
400
- </span>
401
- </a>
402
- </span>
403
- </span>
404
- <span
405
- class="css-aokf2s"
406
- >
407
- <span
408
- class=" "
409
- data-flow="up"
410
- data-tooltip="How to Download"
411
- >
412
- <a
413
- href="/datasets/ds001032/versions/1.0.0/download"
414
- >
415
- <span
416
- aria-label="Download"
417
- class=" on-icon icon-text "
418
- role="img"
419
- >
420
- <i
421
- class="fa fa-download"
422
- />
423
- Download
424
- </span>
425
- </a>
426
- </span>
427
- </span>
428
- <span
429
- class="css-1mdlu11"
430
- >
431
- <span
432
- class=" "
433
- data-flow="up"
434
- data-tooltip="View the dataset metadata"
435
- >
436
- <a
437
- href="/datasets/ds001032/versions/1.0.0/metadata"
438
- >
439
- <span
440
- aria-label="Metadata"
441
- class=" on-icon icon-text "
442
- role="img"
443
- >
444
- <i
445
- class="fa fa-file-code"
446
- />
447
- Metadata
448
- </span>
449
- </a>
450
- </span>
451
- </span>
452
- </span>
453
- </div>
454
458
  <div
455
459
  class="css-1xk6djt"
456
460
  >
@@ -0,0 +1,136 @@
1
+ import React from "react"
2
+ import { vi } from "vitest"
3
+ import { act, render, screen, within } from "@testing-library/react"
4
+ import userEvent from "@testing-library/user-event"
5
+ import { MemoryRouter } from "react-router-dom"
6
+ import { MockedProvider } from "@apollo/client/testing"
7
+ import DraftContainer from "../draft-container"
8
+ import type { DraftContainerProps } from "../draft-container"
9
+ import { UserModalOpenProvider } from "../../utils/user-login-modal-ctx"
10
+ import { Cookies, CookiesProvider } from "react-cookie"
11
+
12
+ vi.mock("../../config.ts")
13
+
14
+ // admin: false
15
+ const mockUser =
16
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsInN1YiI6IjcxZGRiMjRjLTczZjgtNDgzYS1iODVjLTU4ZTY1ZmQwN2YyYiIsImV4cCI6MzM5MTg5Nzg3MywiaWF0IjoxNzUwODc3NDkwfQ.vV66iD3RL_3O9Ofa0BazVYesGLengw8qu-MrneKoJOM"
17
+
18
+ const mockDataset = {
19
+ id: "ds000001",
20
+ created: "2023-01-01T00:00:00.000Z",
21
+ draft: {
22
+ id: "ds000001",
23
+ head: "dce4b7b6653bcde9bdb7226a7c2b9499e77f2724",
24
+ created: "2023-01-01T00:00:00.000Z",
25
+ modified: "2023-01-01T00:00:00.000Z",
26
+ description: {
27
+ Name: "Test Dataset Name",
28
+ Authors: ["Author One", "Author Two"],
29
+ },
30
+ summary: {
31
+ totalFiles: 10,
32
+ size: 1234567,
33
+ modalities: ["T1w", "bold"],
34
+ sessions: [],
35
+ tasks: [],
36
+ subjects: [],
37
+ },
38
+ readme: "This is a test dataset readme.",
39
+ },
40
+ snapshots: [],
41
+ derivatives: [],
42
+ followers: [],
43
+ stars: [],
44
+ public: true,
45
+ permissions: {
46
+ userPermissions: [],
47
+ },
48
+ analytics: {
49
+ views: 100,
50
+ downloads: 10,
51
+ },
52
+ comments: [],
53
+ uploader: {
54
+ name: "Test User",
55
+ orcid: "1234-5678-9012-3456",
56
+ },
57
+ }
58
+
59
+ const renderComponent = (
60
+ props: DraftContainerProps,
61
+ mocks = [],
62
+ token = mockUser,
63
+ ) => {
64
+ // Mock the login state
65
+ const cookieObject = new Cookies()
66
+ cookieObject.set("accessToken", token)
67
+ return render(
68
+ <MemoryRouter>
69
+ <UserModalOpenProvider>
70
+ <MockedProvider mocks={mocks} addTypename={false}>
71
+ <CookiesProvider cookies={cookieObject}>
72
+ <DraftContainer {...props} />
73
+ </CookiesProvider>
74
+ </MockedProvider>
75
+ </UserModalOpenProvider>
76
+ </MemoryRouter>,
77
+ )
78
+ }
79
+
80
+ describe("DraftContainer", () => {
81
+ it("renders dataset name and authors", async () => {
82
+ renderComponent({ dataset: mockDataset })
83
+ expect(await screen.findByRole("heading", { level: 1 })).toHaveTextContent(
84
+ /Test Dataset Name/,
85
+ )
86
+ expect(await screen.findByText(/Author One/)).toBeInTheDocument()
87
+ expect(await screen.findByText(/Author Two/)).toBeInTheDocument()
88
+ })
89
+
90
+ describe("dataset name field", () => {
91
+ it("is editable for users with permissions", async () => {
92
+ const datasetWithPermissions = {
93
+ ...mockDataset,
94
+ permissions: {
95
+ userPermissions: [
96
+ {
97
+ user: {
98
+ id: "71ddb24c-73f8-483a-b85c-58e65fd07f2b",
99
+ email: "test@example.com",
100
+ orcid: "0000-0003-4848-1153",
101
+ name: "Test User",
102
+ },
103
+ level: "admin",
104
+ },
105
+ ],
106
+ },
107
+ }
108
+ const user = userEvent.setup()
109
+ renderComponent({ dataset: datasetWithPermissions })
110
+ const h1 = await screen.findByRole("heading", { level: 1 })
111
+ const editButton = await within(h1).findByRole("button", {
112
+ name: /edit/i,
113
+ })
114
+ await act(async () => {
115
+ await user.click(editButton)
116
+ })
117
+ const textbox = await within(h1).findByRole("textbox")
118
+ expect(textbox).toHaveValue(mockDataset.draft.description.Name)
119
+ })
120
+
121
+ it("is not editable for users without permissions", async () => {
122
+ renderComponent({ dataset: mockDataset })
123
+ const h1 = await screen.findByRole("heading", { level: 1 })
124
+ expect(
125
+ within(h1).queryByRole("button", { name: /edit/i }),
126
+ ).not.toBeInTheDocument()
127
+ })
128
+ })
129
+
130
+ it("renders the readme content if available", async () => {
131
+ renderComponent({ dataset: mockDataset })
132
+ expect(
133
+ await screen.findByText("This is a test dataset readme."),
134
+ ).toBeInTheDocument()
135
+ })
136
+ })
@@ -4,7 +4,7 @@ import "@emotion/react"
4
4
  export const FollowToggles = styled.div`
5
5
  display: flex;
6
6
  font-size: 14px;
7
- margin-left: auto;
7
+ margin: 10px 0;
8
8
 
9
9
  .toggle-counter-wrap {
10
10
  display: inline-flex;
@@ -1,41 +1,38 @@
1
1
  import React from "react"
2
2
  import { Link } from "react-router-dom"
3
+ import { ModalityHexagon } from "../../components/modality-cube/ModalityHexagon"
3
4
 
4
5
  export interface DatasetHeaderProps {
5
- modality: string
6
+ modality: string | null | undefined
6
7
  pageHeading: string
7
8
  renderEditor?: () => React.ReactNode
8
- children?: JSX.Element
9
+ datasetUserActions?: React.ReactNode
10
+ datasetHeaderTools?: React.ReactNode
9
11
  }
10
12
 
11
13
  export const DatasetHeader: React.FC<DatasetHeaderProps> = ({
12
14
  pageHeading,
13
15
  modality,
14
16
  renderEditor,
15
- children,
17
+ datasetHeaderTools,
18
+ datasetUserActions,
16
19
  }) => {
17
20
  return (
18
21
  <div className="dataset-header">
19
22
  <div className="container">
20
- <div className="grid grid-between">
21
- <div className="col">
23
+ <div className="ds-header-inner">
24
+ <div className="ds-inner-left">
22
25
  <h1>
23
26
  <Link to={"/search/modality/" + modality}>
24
- <div className="hexagon-wrapper">
25
- <div className="hexagon no-modality"></div>
26
- <div className="label">
27
- {modality
28
- ? (
29
- modality.substr(0, 4)
30
- )
31
- : <i className="fa fa-circle-o-notch fa-spin"></i>}
32
- </div>
33
- </div>
27
+ <ModalityHexagon
28
+ primaryModality={modality ? modality.substr(0, 4) : null}
29
+ />
34
30
  </Link>
35
31
  {renderEditor?.() || pageHeading}
36
- {children}
37
32
  </h1>
33
+ {datasetHeaderTools}
38
34
  </div>
35
+ <div className="ds-inner-right">{datasetUserActions}</div>
39
36
  </div>
40
37
  </div>
41
38
  </div>
@@ -15,29 +15,28 @@ export const DatasetToolStyle: StyledComponent<DatasetToolStyleProps> = styled
15
15
  .span<DatasetToolStyleProps>(
16
16
  (props) => `
17
17
  display: flex;
18
- margin: 0 auto 10px;
18
+ margin: 0;
19
19
  flex-basis: auto;
20
20
  padding: 0 15px;
21
21
  justify-content: center;
22
22
  a {
23
23
  pointer-events: ${props.disable ? "none" : "auto"};
24
- color: ${
25
- props.disable ? "rgba(0, 0, 0, 0.5);" : "var(--current-theme-primary);"
26
- }
24
+ color: ${props.disable ? "rgba(255, 255, 255, 0.7)" : "#fff"};
27
25
  font-size: 17px;
28
26
  text-decoration: none;
29
27
  font-weight: 400;
30
28
  padding: 4px;
31
- border-bottom: 2px solid transparent;
29
+ border-bottom: 8px solid transparent;
32
30
  border-bottom-color: ${
33
- props.active ? "var(--current-theme-primary)" : "transparent"
31
+ props.active ? "var(--current-theme-primary-light);" : "transparent;"
34
32
  };
35
33
  i {
36
34
  margin-right: 6px;
37
35
  font-size: 15px;
38
36
  }
39
37
  &:hover {
40
- border-bottom-color: var(--current-theme-primary);
38
+ color: #fff;
39
+ border-bottom-color: #fff;
41
40
  }
42
41
  }
43
42
  `,
@@ -99,7 +99,9 @@ export const DatasetTools = ({
99
99
  />
100
100
  )}
101
101
  <DatasetToolButton
102
- tooltip="How to Download"
102
+ tooltip={agree
103
+ ? "How to Download"
104
+ : "Agree to Terms of Service to Download"}
103
105
  path={snapshotId
104
106
  ? `/datasets/${datasetId}/versions/${snapshotId}/download`
105
107
  : `/datasets/${datasetId}/download`}
@@ -109,7 +111,9 @@ export const DatasetTools = ({
109
111
  />
110
112
  {hasDerivatives && (
111
113
  <DatasetToolButton
112
- tooltip="Available Derivatives"
114
+ tooltip={agree
115
+ ? "Available Derivatives"
116
+ : "Agree to Terms of Service to access Derivatives"}
113
117
  path={snapshotId
114
118
  ? `/datasets/${datasetId}/versions/${snapshotId}/derivatives`
115
119
  : `/datasets/${datasetId}/derivatives`}
@@ -93,7 +93,20 @@ const DraftContainer: React.FC<DraftContainerProps> = ({ dataset }) => {
93
93
  >
94
94
  <DatasetHeader
95
95
  pageHeading={description.Name}
96
- modality={modality}
96
+ modality={summary?.modalities[0]}
97
+ datasetHeaderTools={
98
+ <div className="dataset-tool-buttons">
99
+ <DatasetTools
100
+ hasEdit={hasEdit}
101
+ isPublic={dataset.public}
102
+ datasetId={datasetId}
103
+ isAdmin={isAdmin}
104
+ isDatasetAdmin={isDatasetAdmin}
105
+ hasDerivatives={hasDerivatives}
106
+ hasSnapshot={dataset.snapshots.length !== 0}
107
+ />
108
+ </div>
109
+ }
97
110
  renderEditor={() => (
98
111
  <>
99
112
  <EditDescriptionField
@@ -105,22 +118,24 @@ const DraftContainer: React.FC<DraftContainerProps> = ({ dataset }) => {
105
118
  >
106
119
  {description.Name}
107
120
  </EditDescriptionField>
108
- <FollowToggles>
109
- <FollowDataset
110
- profile={profile !== null}
111
- datasetId={dataset.id}
112
- following={dataset.following}
113
- followers={dataset.followers.length}
114
- />
115
- <StarDataset
116
- profile={profile !== null}
117
- datasetId={dataset.id}
118
- starred={dataset.starred}
119
- stars={dataset.stars.length}
120
- />
121
- </FollowToggles>
122
121
  </>
123
122
  )}
123
+ datasetUserActions={
124
+ <FollowToggles>
125
+ <FollowDataset
126
+ profile={profile !== null}
127
+ datasetId={dataset.id}
128
+ following={dataset.following}
129
+ followers={dataset.followers.length}
130
+ />
131
+ <StarDataset
132
+ profile={profile !== null}
133
+ datasetId={dataset.id}
134
+ starred={dataset.starred}
135
+ stars={dataset.stars.length}
136
+ />
137
+ </FollowToggles>
138
+ }
124
139
  />
125
140
  <DatasetAlertDraft
126
141
  isPrivate={!dataset.public}
@@ -151,15 +166,6 @@ const DraftContainer: React.FC<DraftContainerProps> = ({ dataset }) => {
151
166
  }
152
167
  />
153
168
  </div>
154
- <DatasetTools
155
- hasEdit={hasEdit}
156
- isPublic={dataset.public}
157
- datasetId={datasetId}
158
- isAdmin={isAdmin}
159
- hasSnapshot={dataset.snapshots.length !== 0}
160
- isDatasetAdmin={isDatasetAdmin}
161
- hasDerivatives={hasDerivatives}
162
- />
163
169
  <DatasetPageTabContainer>
164
170
  <TabRoutesDraft dataset={dataset} hasEdit={hasEdit} />
165
171
  </DatasetPageTabContainer>