Skip to content

Commit

Permalink
Merge pull request #219 from IQSS/feauter/206-integration-dataset-locks
Browse files Browse the repository at this point in the history
206 - Integration dataset locks
  • Loading branch information
GPortas authored Nov 23, 2023
2 parents 89242ef + 622b8a3 commit 745e2e9
Show file tree
Hide file tree
Showing 23 changed files with 277 additions and 113 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
"dependencies": {
"@faker-js/faker": "7.6.0",
"@iqss/dataverse-client-javascript": "2.0.0-pr97.418bf5e",
"@iqss/dataverse-client-javascript": "2.0.0-pr99.c36f1db",
"@iqss/dataverse-design-system": "*",
"@istanbuljs/nyc-config-typescript": "1.0.2",
"@tanstack/react-table": "8.9.2",
Expand Down
34 changes: 20 additions & 14 deletions src/dataset/domain/models/Dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,20 +243,19 @@ export interface DatasetPermissions {
}

export interface DatasetLock {
id: number
userPersistentId: string
reason: DatasetLockReason
}

export enum DatasetLockReason {
INGEST = 'ingest',
WORKFLOW = 'workflow',
IN_REVIEW = 'inReview',
DCM_UPLOAD = 'dcmUpload',
GLOBUS_UPLOAD = 'globusUpload',
INGEST = 'Ingest',
WORKFLOW = 'Workflow',
IN_REVIEW = 'InReview',
DCM_UPLOAD = 'DcmUpload',
GLOBUS_UPLOAD = 'GlobusUpload',
FINALIZE_PUBLICATION = 'finalizePublication',

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

export interface PrivateUrl {
Expand Down Expand Up @@ -287,8 +286,8 @@ export class Dataset {
return this.metadataBlocks[0].fields.title
}

public get isLockedFromPublishing(): boolean {
return this.isLockedFromEdits
public checkIsLockedFromPublishing(userPersistentId: string): boolean {
return this.checkIsLockedFromEdits(userPersistentId)
}

public get isLocked(): boolean {
Expand All @@ -299,12 +298,19 @@ export class Dataset {
return this.locks.some((lock) => lock.reason === DatasetLockReason.WORKFLOW)
}

public get isLockedFromEdits(): boolean {
public checkIsLockedFromEdits(userPersistentId: string): 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

if (
this.locks.some(
(lock) =>
lock.reason === DatasetLockReason.WORKFLOW && lock.userPersistentId === userPersistentId
)
) {
return false
}

return this.isLocked && !(lockedReasonIsInReview && this.permissions.canPublishDataset)
}
Expand Down
19 changes: 16 additions & 3 deletions src/dataset/infrastructure/mappers/JSDatasetMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {
DatasetMetadataBlock as JSDatasetMetadataBlock,
DatasetMetadataBlocks as JSDatasetMetadataBlocks,
DatasetMetadataFields as JSDatasetMetadataFields,
DatasetVersionInfo as JSDatasetVersionInfo
DatasetVersionInfo as JSDatasetVersionInfo,
DatasetLock as JSDatasetLock
} from '@iqss/dataverse-client-javascript'
import { DatasetVersionState as JSDatasetVersionState } from '@iqss/dataverse-client-javascript/dist/datasets/domain/models/Dataset'
import {
Expand All @@ -14,14 +15,17 @@ import {
DatasetMetadataFields,
DatasetVersion,
MetadataBlockName,
PrivateUrl
PrivateUrl,
DatasetLock,
DatasetLockReason
} from '../../domain/models/Dataset'

export class JSDatasetMapper {
static toDataset(
jsDataset: JSDataset,
citation: string,
summaryFieldsNames: string[],
jsDatasetLocks: JSDatasetLock[],
requestedVersion?: string,
privateUrl?: PrivateUrl
): Dataset {
Expand All @@ -45,7 +49,7 @@ export class JSDatasetMapper {
canManageFilesPermissions: true,
canDeleteDataset: true
}, // TODO Connect with dataset permissions
[], // TODO Connect with dataset locks
JSDatasetMapper.toLocks(jsDatasetLocks),
true, // TODO Connect with dataset hasValidTermsOfAccess
true, // TODO Connect with dataset isValid
jsDataset.versionInfo.releaseTime !== undefined &&
Expand Down Expand Up @@ -185,4 +189,13 @@ export class JSDatasetMapper {

return extraFields
}

static toLocks(jsDatasetLocks: JSDatasetLock[]): DatasetLock[] {
return jsDatasetLocks.map((jsDatasetLock) => {
return {
userPersistentId: jsDatasetLock.userId,
reason: jsDatasetLock.lockType as unknown as DatasetLockReason
}
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import {
Dataset as JSDataset,
getPrivateUrlDataset,
getPrivateUrlDatasetCitation,
ReadError
ReadError,
getDatasetLocks,
DatasetLock as JSDatasetLock
} from '@iqss/dataverse-client-javascript'
import { JSDatasetMapper } from '../mappers/JSDatasetMapper'

Expand All @@ -23,11 +25,24 @@ export class DatasetJSDataverseRepository implements DatasetRepository {
Promise.all([
jsDataset,
getDatasetSummaryFieldNames.execute(),
getDatasetCitation.execute(jsDataset.id, this.versionToVersionId(version))
getDatasetCitation.execute(jsDataset.id, this.versionToVersionId(version)),
getDatasetLocks.execute(jsDataset.id)
])
)
.then(([jsDataset, summaryFieldsNames, citation]: [JSDataset, string[], string]) =>
JSDatasetMapper.toDataset(jsDataset, citation, summaryFieldsNames, requestedVersion)
.then(
([jsDataset, summaryFieldsNames, citation, jsDatasetLocks]: [
JSDataset,
string[],
string,
JSDatasetLock[]
]) =>
JSDatasetMapper.toDataset(
jsDataset,
citation,
summaryFieldsNames,
jsDatasetLocks,
requestedVersion
)
)
.catch((error: ReadError) => {
if (!version) {
Expand All @@ -42,9 +57,9 @@ export class DatasetJSDataverseRepository implements DatasetRepository {
getPrivateUrlDataset.execute(privateUrlToken),
getDatasetSummaryFieldNames.execute(),
getPrivateUrlDatasetCitation.execute(privateUrlToken)
])
]) // TODO - Add getDatasetLocks.execute(privateUrlToken) when it is available in js-dataverse
.then(([jsDataset, summaryFieldsNames, citation]: [JSDataset, string[], string]) =>
JSDatasetMapper.toDataset(jsDataset, citation, summaryFieldsNames, undefined)
JSDatasetMapper.toDataset(jsDataset, citation, summaryFieldsNames, [])
)
.catch((error: ReadError) => {
throw new Error(error.message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import { EditDatasetPermissionsMenu } from './EditDatasetPermissionsMenu'
import { DeleteDatasetButton } from './DeleteDatasetButton'
import { DeaccessionDatasetButton } from './DeaccessionDatasetButton'
import { useTranslation } from 'react-i18next'
import { useSession } from '../../../session/SessionContext'

interface EditDatasetMenuProps {
dataset: Dataset
}

export function EditDatasetMenu({ dataset }: EditDatasetMenuProps) {
if (!dataset.permissions.canUpdateDataset) {
const { user } = useSession()

if (!user || !dataset.permissions.canUpdateDataset) {
return <></>
}

Expand All @@ -21,7 +24,7 @@ export function EditDatasetMenu({ dataset }: EditDatasetMenuProps) {
title={t('datasetActionButtons.editDataset.title')}
asButtonGroup
variant="secondary"
disabled={dataset.isLockedFromEdits}>
disabled={dataset.checkIsLockedFromEdits(user.persistentId)}>
<DropdownButtonItem disabled={!dataset.hasValidTermsOfAccess}>
{t('datasetActionButtons.editDataset.filesUpload')}
</DropdownButtonItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ import { Dataset, DatasetPublishingStatus } from '../../../../dataset/domain/mod
import { DropdownButton, DropdownButtonItem } from '@iqss/dataverse-design-system'
import { ChangeCurationStatusMenu } from './ChangeCurationStatusMenu'
import { useTranslation } from 'react-i18next'
import { useSession } from '../../../session/SessionContext'

interface PublishDatasetMenuProps {
dataset: Dataset
}

export function PublishDatasetMenu({ dataset }: PublishDatasetMenuProps) {
const { user } = useSession()
if (
!dataset.version.isLatest ||
dataset.version.publishingStatus !== DatasetPublishingStatus.DRAFT ||
!user ||
!dataset.permissions.canPublishDataset
) {
return <></>
Expand All @@ -24,7 +27,9 @@ export function PublishDatasetMenu({ dataset }: PublishDatasetMenuProps) {
asButtonGroup
variant="secondary"
disabled={
dataset.isLockedFromPublishing || !dataset.hasValidTermsOfAccess || !dataset.isValid
dataset.checkIsLockedFromPublishing(user.persistentId) ||
!dataset.hasValidTermsOfAccess ||
!dataset.isValid
}>
<DropdownButtonItem>{t('datasetActionButtons.publish.publish')}</DropdownButtonItem>
{dataset.version.isInReview && (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { Dataset, DatasetPublishingStatus } from '../../../../dataset/domain/models/Dataset'
import { Button } from '@iqss/dataverse-design-system'
import { useTranslation } from 'react-i18next'
import { useSession } from '../../../session/SessionContext'

interface SubmitForReviewButtonProps {
dataset: Dataset
}

export function SubmitForReviewButton({ dataset }: SubmitForReviewButtonProps) {
const { user } = useSession()
if (
!dataset.version.isLatest ||
dataset.version.publishingStatus !== DatasetPublishingStatus.DRAFT ||
dataset.isLockedInWorkflow ||
dataset.permissions.canPublishDataset ||
!user ||
!dataset.permissions.canUpdateDataset
) {
return <></>
Expand All @@ -22,7 +25,9 @@ export function SubmitForReviewButton({ dataset }: SubmitForReviewButtonProps) {
<Button
variant="secondary"
disabled={
dataset.isLockedFromPublishing || !dataset.hasValidTermsOfAccess || !dataset.isValid
dataset.checkIsLockedFromPublishing(user.persistentId) ||
!dataset.hasValidTermsOfAccess ||
!dataset.isValid
}>
{dataset.version.isInReview
? t('datasetActionButtons.submitForReview.disabled')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function DatasetUploadFilesButton() {
<Button
onClick={handleClick}
icon={<PlusLg className={styles.icon} />}
disabled={dataset.isLockedFromEdits}>
disabled={dataset.checkIsLockedFromEdits(user.persistentId)}>
{t('datasetActionButtons.uploadFiles')}
</Button>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,36 @@ export function FileCriteriaForm({
onCriteriaChange,
filesCountInfo
}: FileCriteriaInputsProps) {
if (!filesCountInfo || filesCountInfo.total < MINIMUM_FILES_TO_SHOW_CRITERIA_INPUTS) {
return <></>
}
const showFileCriteriaInputs =
filesCountInfo && filesCountInfo.total >= MINIMUM_FILES_TO_SHOW_CRITERIA_INPUTS
return (
<Form>
<Row>
<Col md={5}>
<FileCriteriaSearchText criteria={criteria} onCriteriaChange={onCriteriaChange} />
</Col>
<Col className={styles['upload-files-container']}>
<DatasetUploadFilesButton />
</Col>
</Row>
<Row className={styles['criteria-section']}>
<Col>
<FileCriteriaFilters
criteria={criteria}
onCriteriaChange={onCriteriaChange}
filesCountInfo={filesCountInfo}
/>
</Col>
<Col className={styles['sort-container']}>
<FileCriteriaSortBy criteria={criteria} onCriteriaChange={onCriteriaChange} />
</Col>
</Row>
</Form>
<div className={styles['criteria-section']}>
<Form>
<Row>
{showFileCriteriaInputs && (
<Col md={5}>
<FileCriteriaSearchText criteria={criteria} onCriteriaChange={onCriteriaChange} />
</Col>
)}
<Col className={styles['upload-files-container']}>
<DatasetUploadFilesButton />
</Col>
</Row>
{showFileCriteriaInputs && (
<Row>
<Col>
<FileCriteriaFilters
criteria={criteria}
onCriteriaChange={onCriteriaChange}
filesCountInfo={filesCountInfo}
/>
</Col>
<Col className={styles['sort-container']}>
<FileCriteriaSortBy criteria={criteria} onCriteriaChange={onCriteriaChange} />
</Col>
</Row>
)}
</Form>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function EditFilesMenu({ files, fileSelection }: EditFilesMenuProps) {
variant="secondary"
id="edit-files-menu"
title={t('actions.editFilesMenu.title')}
disabled={dataset.isLockedFromEdits || !dataset.hasValidTermsOfAccess}
disabled={dataset.checkIsLockedFromEdits(user.persistentId) || !dataset.hasValidTermsOfAccess}
icon={<PencilFill className={styles.icon} />}>
<EditFilesOptions files={files} fileSelection={fileSelection} />
</DropdownButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function FileOptionsMenu({ file }: { file: File }) {
<Tooltip placement="top" overlay={<span>{t('actions.optionsMenu.title')}</span>}>
<Button
id={`file-options-file-${file.id}`}
disabled={dataset.isLockedFromEdits}
disabled={dataset.checkIsLockedFromEdits(user.persistentId)}
variant="secondary"
icon={
<ThreeDotsVertical
Expand All @@ -47,7 +47,7 @@ export function FileOptionsMenu({ file }: { file: File }) {
<DropdownButton
id={`file-options-file-${file.id}`}
title=""
disabled={dataset.isLockedFromEdits}
disabled={dataset.checkIsLockedFromEdits(user.persistentId)}
asButtonGroup
variant="secondary"
icon={<ThreeDotsVertical aria-label={t('actions.optionsMenu.title')} />}>
Expand Down
1 change: 1 addition & 0 deletions src/users/domain/models/User.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export interface User {
name: string
persistentId: string
}
Loading

0 comments on commit 745e2e9

Please sign in to comment.