Skip to content

Commit

Permalink
Merge pull request IQSS#181 from IQSS/feature/129-dataset-page-action…
Browse files Browse the repository at this point in the history
…-buttons

129 - Dataset Action Buttons UI
  • Loading branch information
kcondon authored Oct 16, 2023
2 parents 5979bce + 9bf6609 commit 410688d
Show file tree
Hide file tree
Showing 91 changed files with 2,836 additions and 754 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ jobs:
working-directory: packages/design-system
run: npm run build

- name: Install Playwright
run: npx playwright install

- name: Build Storybook Design System
working-directory: packages/design-system
run: npm run build-storybook --quiet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,18 @@ $navbar-brand-font-size: $dv-brand-font-size;
justify-content: end;
}

.dropdown-menu > .dropdown > .dropdown-toggle {
width: 100%;
text-align: start;
background-color: transparent;
border-color: transparent;
}

.dropdown-menu > .dropdown > .dropdown-toggle:hover {
background-color: $dropdown-link-hover-bg;
border-color: transparent;
}

th {
vertical-align: middle;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import "src/lib/assets/styles/design-tokens/colors.module";

.border > button {
.border > button, .border > [role="group"] > button {
border: 1px solid $dv-button-border-color;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,17 @@ interface ButtonGroupProps extends React.HTMLAttributes<HTMLElement> {
vertical?: boolean
}

export function ButtonGroup({ vertical, children, ...props }: PropsWithChildren<ButtonGroupProps>) {
export function ButtonGroup({
vertical,
children,
className,
...props
}: PropsWithChildren<ButtonGroupProps>) {
return (
<ButtonGroupBS vertical={vertical} className={styles.border} {...props}>
<ButtonGroupBS
vertical={vertical}
className={`${styles.border} ${className ? className : ''}`}
{...props}>
{children}
</ButtonGroupBS>
)
Expand Down
39 changes: 37 additions & 2 deletions public/locales/en/dataset.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,43 @@
"learnAbout": "Learn About",
"standards": "Data Citation Standards"
},

"actions": {
"datasetActionButtons": {
"title": "Dataset Action Buttons",
"submitForReview": {
"enabled": "Submit for Review",
"disabled": "Submitted for Review"
},
"publish": {
"title": "Publish Dataset",
"publish": "Publish",
"returnToAuthor": "Return to Author",
"changeCurationStatus": "Change Curation Status",
"removeCurrentStatus": "Remove Current Status"
},
"linkDataset": {
"title": "Link Dataset"
},
"editDataset": {
"title": "Edit Dataset",
"filesUpload": "Files (Upload)",
"metadata": "Metadata",
"terms": "Terms",
"privateUrl": "Private URL",
"thumbnailsPlusWidgets": "Thumbnails + Widgets",
"delete": {
"draft": "Delete Draft Version",
"released": "Delete Dataset"
},
"deaccession": "Deaccession Dataset",
"permissions": {
"title": "Permissions",
"dataset": "Dataset",
"file": "File"
}
},
"accessDataset": {
"title": "Access Dataset"
},
"uploadFiles": "Upload Files"
}
}
79 changes: 72 additions & 7 deletions src/dataset/domain/models/Dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,7 @@ export enum DatasetPublishingStatus {
RELEASED = 'released',
DRAFT = 'draft',
DEACCESSIONED = 'deaccessioned',
EMBARGOED = 'embargoed',
IN_REVIEW = 'inReview'
EMBARGOED = 'embargoed'
}

export enum DatasetNonNumericVersion {
Expand All @@ -214,6 +213,9 @@ export class DatasetVersion {
constructor(
public readonly id: number,
public readonly publishingStatus: DatasetPublishingStatus,
public readonly isLatest: boolean,
public readonly isInReview: boolean,
public readonly latestVersionStatus: DatasetPublishingStatus,
public readonly majorNumber?: number,
public readonly minorNumber?: number
) {}
Expand All @@ -226,6 +228,32 @@ export class DatasetVersion {
}
}

export interface DatasetPermissions {
canDownloadFiles: boolean
canUpdateDataset: boolean
canPublishDataset: boolean
canManageDatasetPermissions: boolean
canManageFilesPermissions: boolean
canDeleteDataset: boolean
}

export interface DatasetLock {
id: number
reason: DatasetLockReason
}

export enum DatasetLockReason {
INGEST = 'ingest',
WORKFLOW = 'workflow',
IN_REVIEW = 'inReview',
DCM_UPLOAD = 'dcmUpload',
GLOBUS_UPLOAD = 'globusUpload',
FINALIZE_PUBLICATION = 'finalizePublication',

EDIT_IN_PROGRESS = 'editInProgress',
FILE_VALIDATION_FAILED = 'fileValidationFailed'
}

export class Dataset {
constructor(
public readonly persistentId: string,
Expand All @@ -234,13 +262,40 @@ export class Dataset {
public readonly labels: DatasetLabel[],
public readonly summaryFields: DatasetMetadataBlock[],
public readonly license: DatasetLicense,
public readonly metadataBlocks: DatasetMetadataBlocks
public readonly metadataBlocks: DatasetMetadataBlocks,
public readonly permissions: DatasetPermissions,
public readonly locks: DatasetLock[],
public readonly hasValidTermsOfAccess: boolean,
public readonly isValid: boolean,
public readonly isReleased: boolean
) {}

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

public get isLockedFromPublishing(): boolean {
return this.isLockedFromEdits
}

public get isLocked(): boolean {
return this.locks.length > 0
}

public get isLockedInWorkflow(): boolean {
return this.locks.some((lock) => lock.reason === DatasetLockReason.WORKFLOW)
}

public get isLockedFromEdits(): boolean {
const lockedReasonIsInReview = this.locks.some(
(lock) => lock.reason === DatasetLockReason.IN_REVIEW
)
// If the lock reason is workflow and the workflow userId is the same as the current user, then the user can edit
// TODO - Ask how we want to manage pending workflows

return this.isLocked && !(lockedReasonIsInReview && this.permissions.canPublishDataset)
}

static Builder = class {
public readonly labels: DatasetLabel[] = []

Expand All @@ -250,7 +305,12 @@ export class Dataset {
public readonly citation: string,
public readonly summaryFields: DatasetMetadataBlock[],
public readonly license: DatasetLicense = defaultLicense,
public readonly metadataBlocks: DatasetMetadataBlocks
public readonly metadataBlocks: DatasetMetadataBlocks,
public readonly permissions: DatasetPermissions,
public readonly locks: DatasetLock[],
public readonly hasValidTermsOfAccess: boolean,
public readonly isValid: boolean,
public readonly isReleased: boolean
) {
this.withLabels()
}
Expand All @@ -267,7 +327,7 @@ export class Dataset {
)
}

if (this.version.publishingStatus !== DatasetPublishingStatus.RELEASED) {
if (!this.isReleased) {
this.labels.push(
new DatasetLabel(DatasetLabelSemanticMeaning.WARNING, DatasetLabelValue.UNPUBLISHED)
)
Expand All @@ -285,7 +345,7 @@ export class Dataset {
)
}

if (this.version.publishingStatus === DatasetPublishingStatus.IN_REVIEW) {
if (this.version.isInReview) {
this.labels.push(
new DatasetLabel(DatasetLabelSemanticMeaning.SUCCESS, DatasetLabelValue.IN_REVIEW)
)
Expand All @@ -308,7 +368,12 @@ export class Dataset {
this.labels,
this.summaryFields,
this.license,
this.metadataBlocks
this.metadataBlocks,
this.permissions,
this.locks,
this.hasValidTermsOfAccess,
this.isValid,
this.isReleased
)
}
}
Expand Down
25 changes: 20 additions & 5 deletions src/dataset/infrastructure/mappers/JSDatasetMapper.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import {
Dataset as JSDataset,
DatasetMetadataBlocks as JSDatasetMetadataBlocks,
DatasetMetadataBlock as JSDatasetMetadataBlock,
DatasetMetadataBlocks as JSDatasetMetadataBlocks,
DatasetMetadataFields as JSDatasetMetadataFields,
DatasetVersionInfo as JSDatasetVersionInfo
} from '@iqss/dataverse-client-javascript'
import { DatasetVersionState as JSDatasetVersionState } from '@iqss/dataverse-client-javascript/dist/datasets/domain/models/Dataset'
import {
Dataset,
DatasetPublishingStatus,
MetadataBlockName,
DatasetMetadataBlock,
DatasetVersion,
DatasetMetadataBlocks,
DatasetMetadataFields,
DatasetMetadataBlocks
DatasetVersion,
MetadataBlockName
} from '../../domain/models/Dataset'

export class JSDatasetMapper {
Expand All @@ -29,7 +29,19 @@ export class JSDatasetMapper {
jsDataset.alternativePersistentId,
jsDataset.publicationDate,
jsDataset.citationDate
)
),
{
canDownloadFiles: true,
canUpdateDataset: true,
canPublishDataset: true,
canManageDatasetPermissions: true,
canManageFilesPermissions: true,
canDeleteDataset: true
}, // TODO Connect with dataset permissions
[], // TODO Connect with dataset locks
true, // TODO Connect with dataset hasValidTermsOfAccess
true, // TODO Connect with dataset isValid
!!jsDataset.versionInfo.releaseTime // TODO Connect with dataset isReleased
).build()
}

Expand All @@ -40,6 +52,9 @@ export class JSDatasetMapper {
return new DatasetVersion(
jDatasetVersionId,
JSDatasetMapper.toStatus(jsDatasetVersionInfo.state),
true, // TODO Connect with dataset version isLatest
false, // TODO Connect with dataset version isInReview
JSDatasetMapper.toStatus(jsDatasetVersionInfo.state), // TODO Connect with dataset version latestVersionState
jsDatasetVersionInfo.majorNumber,
jsDatasetVersionInfo.minorNumber
)
Expand Down
24 changes: 13 additions & 11 deletions src/sections/dataset/Dataset.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { DatasetRepository } from '../../dataset/domain/repositories/DatasetRepository'
import { useDataset } from './useDataset'
import { Tabs, Col, Row } from '@iqss/dataverse-design-system'
import styles from './Dataset.module.scss'
import { DatasetLabels } from './dataset-labels/DatasetLabels'
Expand All @@ -12,22 +10,23 @@ import { DatasetSummary } from './dataset-summary/DatasetSummary'
import { DatasetCitation } from './dataset-citation/DatasetCitation'
import { DatasetFiles } from './dataset-files/DatasetFiles'
import { FileRepository } from '../../files/domain/repositories/FileRepository'
import { DatasetActionButtons } from './dataset-action-buttons/DatasetActionButtons'
import { useDataset } from './DatasetContext'
import { useEffect } from 'react'

interface DatasetProps {
datasetRepository: DatasetRepository
fileRepository: FileRepository
searchParams: {
persistentId?: string
privateUrlToken?: string
version?: string
}
}

export function Dataset({ datasetRepository, fileRepository, searchParams }: DatasetProps) {
const { dataset } = useDataset(datasetRepository, searchParams)
const { isLoading } = useLoading()
export function Dataset({ fileRepository }: DatasetProps) {
const { setIsLoading } = useLoading()
const { dataset, isLoading } = useDataset()
const { t } = useTranslation('dataset')

useEffect(() => {
setIsLoading(isLoading)
}, [isLoading])

if (isLoading) {
return <DatasetSkeleton />
}
Expand All @@ -47,6 +46,9 @@ export function Dataset({ datasetRepository, fileRepository, searchParams }: Dat
<Col sm={9}>
<DatasetCitation citation={dataset.citation} version={dataset.version} />
</Col>
<Col sm={3}>
<DatasetActionButtons dataset={dataset} />
</Col>
</Row>
<Row>
<Col sm={9} className={styles['summary-container']}>
Expand Down
13 changes: 13 additions & 0 deletions src/sections/dataset/DatasetContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { createContext, useContext } from 'react'
import { Dataset } from '../../dataset/domain/models/Dataset'

interface DatasetContextProps {
dataset: Dataset | undefined
isLoading: boolean
}
export const DatasetContext = createContext<DatasetContextProps>({
dataset: undefined,
isLoading: false
})

export const useDataset = () => useContext(DatasetContext)
21 changes: 11 additions & 10 deletions src/sections/dataset/DatasetFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { MetadataBlockInfoJSDataverseRepository } from '../../metadata-block-inf
import { SettingJSDataverseRepository } from '../../settings/infrastructure/SettingJSDataverseRepository'
import { FilePermissionsProvider } from '../file/file-permissions/FilePermissionsProvider'
import { SettingsProvider } from '../settings/SettingsProvider'
import { DatasetProvider } from './DatasetProvider'

const datasetRepository = new DatasetJSDataverseRepository()
const fileRepository = new FileJSDataverseRepository()
Expand Down Expand Up @@ -45,19 +46,19 @@ function DatasetWithSearchParams() {

if (privateUrlToken) {
return (
<Dataset
datasetRepository={datasetRepository}
fileRepository={fileRepository}
searchParams={{ privateUrlToken: privateUrlToken }}
/>
<DatasetProvider
repository={datasetRepository}
searchParams={{ privateUrlToken: privateUrlToken }}>
<Dataset fileRepository={fileRepository} />
</DatasetProvider>
)
}

return (
<Dataset
datasetRepository={datasetRepository}
fileRepository={fileRepository}
searchParams={{ persistentId: persistentId, version: version }}
/>
<DatasetProvider
repository={datasetRepository}
searchParams={{ persistentId: persistentId, version: version }}>
<Dataset fileRepository={fileRepository} />
</DatasetProvider>
)
}
Loading

0 comments on commit 410688d

Please sign in to comment.