Skip to content

Commit a9b1df2

Browse files
committed
feat(DatasetActionButtons): add PublishDatasetMenu component
1 parent 2f512a1 commit a9b1df2

13 files changed

Lines changed: 316 additions & 53 deletions

File tree

src/dataset/domain/models/Dataset.ts

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ export class DatasetVersion {
211211
constructor(
212212
public readonly majorNumber: number,
213213
public readonly minorNumber: number,
214-
public readonly status: DatasetStatus
214+
public readonly status: DatasetStatus,
215+
public readonly isLatest: boolean
215216
) {}
216217

217218
toString(): string {
@@ -222,6 +223,24 @@ export class DatasetVersion {
222223
export interface DatasetPermissions {
223224
canDownloadFiles: boolean
224225
canUpdateDataset: boolean
226+
canPublishDataset: boolean
227+
}
228+
229+
export interface DatasetLock {
230+
id: number
231+
reason: DatasetLockReason
232+
}
233+
234+
export enum DatasetLockReason {
235+
INGEST = 'ingest',
236+
WORKFLOW = 'workflow',
237+
IN_REVIEW = 'inReview',
238+
DCM_UPLOAD = 'dcmUpload',
239+
GLOBUS_UPLOAD = 'globusUpload',
240+
FINALIZE_PUBLICATION = 'finalizePublication',
241+
242+
EDIT_IN_PROGRESS = 'editInProgress',
243+
FILE_VALIDATION_FAILED = 'fileValidationFailed'
225244
}
226245

227246
export class Dataset {
@@ -233,13 +252,26 @@ export class Dataset {
233252
public readonly summaryFields: DatasetMetadataBlock[],
234253
public readonly license: DatasetLicense,
235254
public readonly metadataBlocks: DatasetMetadataBlocks,
236-
public readonly permissions: DatasetPermissions
255+
public readonly permissions: DatasetPermissions,
256+
public readonly locks: DatasetLock[]
237257
) {}
238258

239259
public getTitle(): string {
240260
return this.metadataBlocks[0].fields.title
241261
}
242262

263+
public get isLockedFromPublishing(): boolean {
264+
const lockedReasonIsInReview = this.locks.some(
265+
(lock) => lock.reason === DatasetLockReason.IN_REVIEW
266+
)
267+
268+
return this.isLocked && !(lockedReasonIsInReview && this.permissions.canPublishDataset)
269+
}
270+
271+
public get isLocked(): boolean {
272+
return this.locks.length > 0
273+
}
274+
243275
static Builder = class {
244276
public readonly labels: DatasetLabel[] = []
245277

@@ -250,7 +282,8 @@ export class Dataset {
250282
public readonly summaryFields: DatasetMetadataBlock[],
251283
public readonly license: DatasetLicense = defaultLicense,
252284
public readonly metadataBlocks: DatasetMetadataBlocks,
253-
public readonly permissions: DatasetPermissions
285+
public readonly permissions: DatasetPermissions,
286+
public readonly locks: DatasetLock[]
254287
) {
255288
this.withLabels()
256289
}
@@ -309,7 +342,8 @@ export class Dataset {
309342
this.summaryFields,
310343
this.license,
311344
this.metadataBlocks,
312-
this.permissions
345+
this.permissions,
346+
this.locks
313347
)
314348
}
315349
}

src/dataset/infrastructure/mappers/JSDatasetMapper.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ export class JSDatasetMapper {
3333
return new DatasetVersion(
3434
jsDatasetVersionInfo.majorNumber,
3535
jsDatasetVersionInfo.minorNumber,
36-
JSDatasetMapper.toStatus(jsDatasetVersionInfo.state)
36+
JSDatasetMapper.toStatus(jsDatasetVersionInfo.state),
37+
false
3738
)
3839
}
3940

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,34 @@
1-
import { Dataset, DatasetStatus } from '../../../dataset/domain/models/Dataset'
1+
import {
2+
Dataset,
3+
DatasetPermissions,
4+
DatasetStatus,
5+
DatasetVersion
6+
} from '../../../dataset/domain/models/Dataset'
27
import { DropdownButton, DropdownButtonItem } from '@iqss/dataverse-design-system'
38

49
interface AccessDatasetMenuProps {
5-
dataset: Dataset
10+
version: DatasetVersion
11+
permissions: DatasetPermissions
612
}
713

8-
export function AccessDatasetMenu({ dataset }: AccessDatasetMenuProps) {
14+
export function AccessDatasetMenu({ version, permissions }: AccessDatasetMenuProps) {
915
if (
10-
!dataset.permissions.canDownloadFiles ||
11-
(dataset.version.status === DatasetStatus.DEACCESSIONED &&
12-
!dataset.permissions.canUpdateDataset)
16+
!permissions.canDownloadFiles ||
17+
(version.status === DatasetStatus.DEACCESSIONED && !permissions.canUpdateDataset)
1318
) {
1419
return <></>
1520
}
1621

1722
return (
1823
<DropdownButton
19-
id={`dataset-access-menu`}
24+
id={`access-dataset-menu`}
2025
title="Access Dataset"
2126
asButtonGroup
2227
variant="primary">
2328
<DropdownButtonItem>Download</DropdownButtonItem>
2429
</DropdownButton>
2530
)
2631
}
32+
// TODO: add download feature https://github.com/IQSS/dataverse-frontend/issues/63
33+
// TODO: add explore feature
34+
// TODO: add compute feature
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Dataset } from '../../../dataset/domain/models/Dataset'
22
import { ButtonGroup } from '@iqss/dataverse-design-system'
33
import { AccessDatasetMenu } from './AccessDatasetMenu'
4+
import { PublishDatasetMenu } from './PublishDatasetMenu'
45

56
interface DatasetActionButtonsProps {
67
dataset: Dataset
@@ -9,7 +10,8 @@ interface DatasetActionButtonsProps {
910
export function DatasetActionButtons({ dataset }: DatasetActionButtonsProps) {
1011
return (
1112
<ButtonGroup aria-label="Dataset Action Buttons">
12-
<AccessDatasetMenu dataset={dataset} />
13+
<AccessDatasetMenu version={dataset.version} permissions={dataset.permissions} />
14+
<PublishDatasetMenu dataset={dataset} />
1315
</ButtonGroup>
1416
)
1517
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {
2+
Dataset,
3+
DatasetPermissions,
4+
DatasetStatus,
5+
DatasetVersion
6+
} from '../../../dataset/domain/models/Dataset'
7+
import { DropdownButton, DropdownButtonItem } from '@iqss/dataverse-design-system'
8+
9+
interface PublishDatasetMenuProps {
10+
dataset: Dataset
11+
}
12+
13+
export function PublishDatasetMenu({ dataset }: PublishDatasetMenuProps) {
14+
if (
15+
!dataset.version.isLatest ||
16+
dataset.version.status !== DatasetStatus.DRAFT ||
17+
!dataset.permissions.canPublishDataset
18+
) {
19+
return <></>
20+
}
21+
22+
return (
23+
<DropdownButton
24+
id={`publish-dataset-menu`}
25+
title="Publish Dataset"
26+
asButtonGroup
27+
variant="secondary"
28+
disabled={dataset.isLockedFromPublishing}>
29+
<DropdownButtonItem>Publish</DropdownButtonItem>
30+
</DropdownButton>
31+
)
32+
}

src/stories/dataset/DatasetMockData.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const DatasetMockData = (props?: Partial<Dataset>, anonymized = false): D
1515
citation: `${
1616
anonymized ? 'Author name(s) withheld' : 'Bennet, Elizabeth; Darcy, Fitzwilliam'
1717
}, 2023, "Dataset Title", <a href="https://doi.org/10.5072/FK2/BUDNRV" target="_blank">https://doi.org/10.5072/FK2/BUDNRV</a>, Root, V1`,
18-
version: new DatasetVersion(1, 0, DatasetStatus.RELEASED),
18+
version: new DatasetVersion(1, 0, DatasetStatus.RELEASED, false),
1919
labels: [
2020
{ value: 'Version 1.0', semanticMeaning: DatasetLabelSemanticMeaning.FILE },
2121
{ value: DatasetLabelValue.DRAFT, semanticMeaning: DatasetLabelSemanticMeaning.DATASET }

src/stories/dataset/dataset-citation/DatasetCitation.stories.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export const DraftVersion: Story = {
3131
const dataset = DatasetMockData({
3232
citation:
3333
'Admin, Dataverse, 2023, "Dataset Title", <a href="https://doi.org/10.5072/FK2/BUDNRV" target="_blank">https://doi.org/10.5072/FK2/BUDNRV</a>, Root, DRAFT VERSION',
34-
version: new DatasetVersion(1, 0, DatasetStatus.DRAFT)
34+
version: new DatasetVersion(1, 0, DatasetStatus.DRAFT, false)
3535
})
3636

3737
/*
@@ -52,7 +52,7 @@ export const Deaccessioned: Story = {
5252
const dataset = DatasetMockData({
5353
citation:
5454
'Admin, Dataverse, 2023, "Dataset Title", <a href="https://doi.org/10.5072/FK2/BUDNRV" target="_blank">https://doi.org/10.5072/FK2/BUDNRV</a>, Root, V1 DEACCESSIONED VERSION',
55-
version: new DatasetVersion(1, 0, DatasetStatus.DEACCESSIONED)
55+
version: new DatasetVersion(1, 0, DatasetStatus.DEACCESSIONED, false)
5656
})
5757

5858
/*

tests/component/dataset/domain/models/DatasetMother.ts

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,80 @@ import {
77
DatasetStatus,
88
DatasetVersion,
99
MetadataBlockName,
10-
DatasetMetadataBlocks
10+
DatasetMetadataBlocks,
11+
DatasetPermissions
1112
} from '../../../../../src/dataset/domain/models/Dataset'
1213

14+
export class DatasetVersionMother {
15+
static create(props?: Partial<DatasetVersion>): DatasetVersion {
16+
return new DatasetVersion(
17+
props?.majorNumber ?? 1,
18+
props?.minorNumber ?? 0,
19+
props?.status ?? DatasetStatus.RELEASED,
20+
props?.isLatest ?? false
21+
)
22+
}
23+
24+
static createReleased(): DatasetVersion {
25+
return new DatasetVersion(1, 0, DatasetStatus.RELEASED, false)
26+
}
27+
28+
static createDeaccessioned(): DatasetVersion {
29+
return new DatasetVersion(1, 0, DatasetStatus.DEACCESSIONED, false)
30+
}
31+
32+
static createDraftAsLatestVersion(): DatasetVersion {
33+
return new DatasetVersion(1, 0, DatasetStatus.DRAFT, true)
34+
}
35+
36+
static createDraft(): DatasetVersion {
37+
return new DatasetVersion(1, 0, DatasetStatus.DRAFT, false)
38+
}
39+
}
40+
41+
export class DatasetPermissionsMother {
42+
static create(props?: Partial<DatasetPermissions>): DatasetPermissions {
43+
return {
44+
canDownloadFiles: faker.datatype.boolean(),
45+
canUpdateDataset: faker.datatype.boolean(),
46+
canPublishDataset: faker.datatype.boolean(),
47+
...props
48+
}
49+
}
50+
51+
static createWithFilesDownloadAllowed(): DatasetPermissions {
52+
return this.create({ canDownloadFiles: true })
53+
}
54+
55+
static createWithFilesDownloadNotAllowed(): DatasetPermissions {
56+
return this.create({ canDownloadFiles: false })
57+
}
58+
59+
static createWithUpdateDatasetAllowed(): DatasetPermissions {
60+
return this.create({ canUpdateDataset: true })
61+
}
62+
63+
static createWithUpdateDatasetNotAllowed(): DatasetPermissions {
64+
return this.create({ canUpdateDataset: false })
65+
}
66+
67+
static createWithAllAllowed(): DatasetPermissions {
68+
return this.create({
69+
canDownloadFiles: true,
70+
canUpdateDataset: true,
71+
canPublishDataset: true
72+
})
73+
}
74+
75+
static createWithPublishingDatasetAllowed(): DatasetPermissions {
76+
return this.create({ canPublishDataset: true })
77+
}
78+
79+
static createWithPublishingDatasetNotAllowed(): DatasetPermissions {
80+
return this.create({ canPublishDataset: false })
81+
}
82+
}
83+
1384
export class DatasetMother {
1485
static createEmpty(): undefined {
1586
return undefined
@@ -19,7 +90,7 @@ export class DatasetMother {
1990
const dataset = {
2091
persistentId: faker.datatype.uuid(),
2192
title: faker.lorem.sentence(),
22-
version: new DatasetVersion(1, 0, DatasetStatus.RELEASED),
93+
version: DatasetVersionMother.create(),
2394
citation:
2495
'Bennet, Elizabeth; Darcy, Fitzwilliam, 2023, "Dataset Title", <a href="https://doi.org/10.5072/FK2/BUDNRV" target="_blank">https://doi.org/10.5072/FK2/BUDNRV</a>, Root, V1',
2596
license: {
@@ -100,7 +171,8 @@ export class DatasetMother {
100171
}
101172
}
102173
] as DatasetMetadataBlocks,
103-
permissions: { canDownloadFiles: false, canUpdateDataset: false },
174+
permissions: DatasetPermissionsMother.create(),
175+
locks: [],
104176
...props
105177
}
106178

@@ -111,7 +183,8 @@ export class DatasetMother {
111183
dataset.summaryFields,
112184
dataset.license,
113185
dataset.metadataBlocks,
114-
dataset.permissions
186+
dataset.permissions,
187+
dataset.locks
115188
).build()
116189
}
117190

tests/component/sections/dataset/dataset-action-buttons/AccessDatasetMenu.spec.tsx

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,45 @@
11
import { AccessDatasetMenu } from '../../../../../src/sections/dataset/dataset-action-buttons/AccessDatasetMenu'
2-
import { DatasetMother } from '../../../dataset/domain/models/DatasetMother'
3-
import { DatasetStatus, DatasetVersion } from '../../../../../src/dataset/domain/models/Dataset'
2+
import {
3+
DatasetPermissionsMother,
4+
DatasetVersionMother
5+
} from '../../../dataset/domain/models/DatasetMother'
46

57
describe('AccessDatasetMenu', () => {
6-
it('renders the DatasetActionButtons if the user has download files permissions and the dataset is not deaccessioned', () => {
7-
const version = new DatasetVersion(1, 0, DatasetStatus.RELEASED)
8-
const dataset = DatasetMother.create({
9-
permissions: { canDownloadFiles: true, canUpdateDataset: false },
10-
version: version
11-
})
8+
it('renders the AccessDatasetMenu if the user has download files permissions and the dataset is not deaccessioned', () => {
9+
const version = DatasetVersionMother.createReleased()
10+
const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed()
1211

13-
cy.customMount(<AccessDatasetMenu dataset={dataset} />)
12+
cy.customMount(<AccessDatasetMenu version={version} permissions={permissions} />)
1413

1514
cy.findByRole('button', { name: 'Access Dataset' }).should('exist')
1615
})
1716

18-
it('renders the DatasetActionButtons if the user has download files permissions and the dataset is deaccessioned with update dataset permissions', () => {
19-
const version = new DatasetVersion(1, 0, DatasetStatus.DEACCESSIONED)
20-
const dataset = DatasetMother.create({
21-
permissions: { canDownloadFiles: true, canUpdateDataset: true },
22-
version: version
17+
it('renders the AccessDatasetMenu if the user has download files permissions and the dataset is deaccessioned with update dataset permissions', () => {
18+
const version = DatasetVersionMother.createDeaccessioned()
19+
const permissions = DatasetPermissionsMother.create({
20+
canUpdateDataset: true,
21+
canDownloadFiles: true
2322
})
2423

25-
cy.customMount(<AccessDatasetMenu dataset={dataset} />)
24+
cy.customMount(<AccessDatasetMenu version={version} permissions={permissions} />)
2625

2726
cy.findByRole('button', { name: 'Access Dataset' }).should('exist')
2827
})
2928

30-
it('does not render the DatasetActionButtons if the user do not have download files permissions', () => {
31-
const version = new DatasetVersion(1, 0, DatasetStatus.RELEASED)
32-
const dataset = DatasetMother.create({
33-
permissions: { canDownloadFiles: false, canUpdateDataset: false },
34-
version: version
35-
})
29+
it('does not render the AccessDatasetMenu if the user do not have download files permissions', () => {
30+
const version = DatasetVersionMother.create()
31+
const permissions = DatasetPermissionsMother.createWithFilesDownloadNotAllowed()
3632

37-
cy.customMount(<AccessDatasetMenu dataset={dataset} />)
33+
cy.customMount(<AccessDatasetMenu version={version} permissions={permissions} />)
3834

3935
cy.findByRole('button', { name: 'Access Dataset' }).should('not.exist')
4036
})
4137

42-
it('does not render the DatasetActionButtons if the dataset is deaccessioned and the user does not have update dataset permissions', () => {
43-
const version = new DatasetVersion(1, 0, DatasetStatus.DEACCESSIONED)
44-
const dataset = DatasetMother.create({
45-
permissions: { canDownloadFiles: false, canUpdateDataset: false },
46-
version: version
47-
})
38+
it('does not render the AccessDatasetMenu if the dataset is deaccessioned and the user does not have update dataset permissions', () => {
39+
const version = DatasetVersionMother.createDeaccessioned()
40+
const permissions = DatasetPermissionsMother.createWithUpdateDatasetNotAllowed()
4841

49-
cy.customMount(<AccessDatasetMenu dataset={dataset} />)
42+
cy.customMount(<AccessDatasetMenu version={version} permissions={permissions} />)
5043

5144
cy.findByRole('button', { name: 'Access Dataset' }).should('not.exist')
5245
})

0 commit comments

Comments
 (0)