Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

206 - Integration dataset locks #219

Merged
merged 6 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -259,20 +259,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 @@ -303,8 +302,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 @@ -315,12 +314,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