From 86654908bd342c000657d5abb2e4289023d29f7b Mon Sep 17 00:00:00 2001 From: MellyGray Date: Thu, 21 Dec 2023 15:04:11 +0100 Subject: [PATCH 1/6] feat(DatsetCard): refactor with the new DatasetVersion --- src/dataset/domain/models/DatasetPreview.ts | 6 +---- .../dataset-card/DatasetCard.tsx | 14 +++++++--- .../dataset-card/DatasetCardHeader.tsx | 13 +++++----- .../dataset-card/DatasetCardInfo.tsx | 22 +++++++++++----- .../dataset-card/DatasetCardThumbnail.tsx | 22 +++++++++++----- .../dataset/domain/models/DatasetMother.ts | 2 +- .../domain/models/DatasetPreviewMother.ts | 26 +++++-------------- tests/component/sections/home/Home.spec.tsx | 2 +- .../home/datasets-list/DatasetsList.spec.tsx | 4 +-- .../dataset-card/DatasetCard.spec.tsx | 6 ++--- .../dataset-card/DatasetCardHeader.spec.tsx | 8 +++--- .../dataset-card/DatasetCardInfo.spec.tsx | 20 +++++++++++--- .../DatasetCardThumbnail.spec.tsx | 18 ++++++++++--- 13 files changed, 99 insertions(+), 64 deletions(-) diff --git a/src/dataset/domain/models/DatasetPreview.ts b/src/dataset/domain/models/DatasetPreview.ts index 849ba4691..e7688499d 100644 --- a/src/dataset/domain/models/DatasetPreview.ts +++ b/src/dataset/domain/models/DatasetPreview.ts @@ -1,13 +1,9 @@ -import { DatasetLabel, DatasetVersion } from './Dataset' +import { DatasetVersion } from './Dataset' export class DatasetPreview { constructor( public persistentId: string, - public title: string, public version: DatasetVersion, - public citation: string, - public labels: DatasetLabel[], - public isDeaccessioned: boolean, public releaseOrCreateDate: Date, public description: string, public thumbnail?: string diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCard.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCard.tsx index 6fe1f807e..5e8712da2 100644 --- a/src/sections/home/datasets-list/dataset-card/DatasetCard.tsx +++ b/src/sections/home/datasets-list/dataset-card/DatasetCard.tsx @@ -11,10 +11,18 @@ interface DatasetCardProps { export function DatasetCard({ dataset }: DatasetCardProps) { return (
- +
- - + +
) diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCardHeader.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCardHeader.tsx index 9e927b2fc..30acd8f62 100644 --- a/src/sections/home/datasets-list/dataset-card/DatasetCardHeader.tsx +++ b/src/sections/home/datasets-list/dataset-card/DatasetCardHeader.tsx @@ -2,20 +2,21 @@ import styles from './DatasetCard.module.scss' import { LinkToPage } from '../../../shared/link-to-page/LinkToPage' import { Route } from '../../../Route.enum' import { DatasetLabels } from '../../../dataset/dataset-labels/DatasetLabels' -import { DatasetPreview } from '../../../../dataset/domain/models/DatasetPreview' import { DatasetIcon } from '../../../dataset/dataset-icon/DatasetIcon' +import { DatasetVersion } from '../../../../dataset/domain/models/Dataset' interface DatasetCardHeaderProps { - dataset: DatasetPreview + persistentId: string + version: DatasetVersion } -export function DatasetCardHeader({ dataset }: DatasetCardHeaderProps) { +export function DatasetCardHeader({ persistentId, version }: DatasetCardHeaderProps) { return (
- - {dataset.title} + + {version.title} - +
diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCardInfo.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCardInfo.tsx index 76a03a645..b8b80a1c5 100644 --- a/src/sections/home/datasets-list/dataset-card/DatasetCardInfo.tsx +++ b/src/sections/home/datasets-list/dataset-card/DatasetCardInfo.tsx @@ -1,23 +1,31 @@ import styles from './DatasetCard.module.scss' import { DateHelper } from '../../../../shared/domain/helpers/DateHelper' -import { DatasetPreview } from '../../../../dataset/domain/models/DatasetPreview' import { CitationDescription } from '../../../shared/citation/CitationDescription' +import { DatasetPublishingStatus, DatasetVersion } from '../../../../dataset/domain/models/Dataset' interface DatasetCardInfoProps { - dataset: DatasetPreview + version: DatasetVersion + releaseOrCreateDate: Date + abbreviatedDescription: string } -export function DatasetCardInfo({ dataset }: DatasetCardInfoProps) { +export function DatasetCardInfo({ + version, + releaseOrCreateDate, + abbreviatedDescription +}: DatasetCardInfoProps) { return (
- {DateHelper.toDisplayFormat(dataset.releaseOrCreateDate)} + {DateHelper.toDisplayFormat(releaseOrCreateDate)} - + - {dataset.abbreviatedDescription} + {abbreviatedDescription}
) } diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.tsx index cba65b215..d8065b0fa 100644 --- a/src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.tsx +++ b/src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.tsx @@ -1,21 +1,29 @@ import styles from './DatasetCard.module.scss' -import { DatasetPreview } from '../../../../dataset/domain/models/DatasetPreview' import { LinkToPage } from '../../../shared/link-to-page/LinkToPage' import { Route } from '../../../Route.enum' import { DatasetThumbnail } from '../../../dataset/dataset-thumbnail/DatasetThumbnail' +import { DatasetPublishingStatus, DatasetVersion } from '../../../../dataset/domain/models/Dataset' interface DatasetCardThumbnailProps { - dataset: DatasetPreview + persistentId: string + version: DatasetVersion + thumbnail?: string } -export function DatasetCardThumbnail({ dataset }: DatasetCardThumbnailProps) { +export function DatasetCardThumbnail({ + persistentId, + version, + thumbnail +}: DatasetCardThumbnailProps) { return (
- +
diff --git a/tests/component/dataset/domain/models/DatasetMother.ts b/tests/component/dataset/domain/models/DatasetMother.ts index 81a4f0628..64bd805d7 100644 --- a/tests/component/dataset/domain/models/DatasetMother.ts +++ b/tests/component/dataset/domain/models/DatasetMother.ts @@ -29,7 +29,7 @@ export class DatasetVersionMother { props?.number ?? new DatasetVersionNumber(1, 0), props?.publishingStatus ?? DatasetPublishingStatus.RELEASED, props?.citation ?? - 'Bennet, Elizabeth; Darcy, Fitzwilliam, 2023, "Dataset Title", https://doi.org/10.5072/FK2/BUDNRV, Root, V1', + 'Admin, Dataverse, 2023, "Dataset Title", https://doi.org/10.5072/FK2/BUDNRV, Root, V1', props?.isLatest ?? false, props?.isInReview ?? false, props?.latestVersionPublishingStatus ?? DatasetPublishingStatus.RELEASED, diff --git a/tests/component/dataset/domain/models/DatasetPreviewMother.ts b/tests/component/dataset/domain/models/DatasetPreviewMother.ts index 83e080ff9..f46387170 100644 --- a/tests/component/dataset/domain/models/DatasetPreviewMother.ts +++ b/tests/component/dataset/domain/models/DatasetPreviewMother.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker' import { DatasetPreview } from '../../../../../src/dataset/domain/models/DatasetPreview' -import { DatasetCitationMother, DatasetLabelsMother, DatasetVersionMother } from './DatasetMother' +import { DatasetVersionMother } from './DatasetMother' export class DatasetPreviewMother { static createMany(count: number): DatasetPreview[] { @@ -14,24 +14,16 @@ export class DatasetPreviewMother { static create(props?: Partial): DatasetPreview { const datasetPreview = { persistentId: faker.datatype.uuid(), - title: faker.lorem.sentence(), - labels: DatasetLabelsMother.create(), - isDeaccessioned: faker.datatype.boolean(), - thumbnail: faker.datatype.boolean() ? faker.image.imageUrl() : undefined, - releaseOrCreateDate: faker.date.past(), version: DatasetVersionMother.create(), - citation: DatasetCitationMother.create(), + releaseOrCreateDate: faker.date.past(), description: faker.lorem.paragraph(), + thumbnail: faker.datatype.boolean() ? faker.image.imageUrl() : undefined, ...props } return new DatasetPreview( datasetPreview.persistentId, - datasetPreview.title, datasetPreview.version, - datasetPreview.citation, - datasetPreview.labels, - datasetPreview.isDeaccessioned, datasetPreview.releaseOrCreateDate, datasetPreview.description, datasetPreview.thumbnail @@ -44,25 +36,21 @@ export class DatasetPreviewMother { static createDraft(): DatasetPreview { return this.create({ - isDeaccessioned: false, - labels: DatasetLabelsMother.createDraft(), - citation: DatasetCitationMother.createDraft() + version: DatasetVersionMother.createDraft() }) } static createWithThumbnail(): DatasetPreview { - return this.create({ thumbnail: faker.image.imageUrl(), isDeaccessioned: false }) + return this.create({ thumbnail: faker.image.imageUrl() }) } static createWithNoThumbnail(): DatasetPreview { - return this.create({ thumbnail: undefined, isDeaccessioned: false }) + return this.create({ thumbnail: undefined }) } static createDeaccessioned(): DatasetPreview { return this.create({ - isDeaccessioned: true, - labels: DatasetLabelsMother.createDeaccessioned(), - citation: DatasetCitationMother.createDeaccessioned() + version: DatasetVersionMother.createDeaccessioned() }) } } diff --git a/tests/component/sections/home/Home.spec.tsx b/tests/component/sections/home/Home.spec.tsx index 52fe1d34a..fb3146917 100644 --- a/tests/component/sections/home/Home.spec.tsx +++ b/tests/component/sections/home/Home.spec.tsx @@ -22,7 +22,7 @@ describe('Home page', () => { cy.wrap(datasetRepository.getAll).should('be.calledOnce') datasets.forEach((dataset) => { - cy.findByText(dataset.title).should('exist') + cy.findByText(dataset.version.title).should('exist') }) }) }) diff --git a/tests/component/sections/home/datasets-list/DatasetsList.spec.tsx b/tests/component/sections/home/datasets-list/DatasetsList.spec.tsx index e126ce245..e5e2f79f0 100644 --- a/tests/component/sections/home/datasets-list/DatasetsList.spec.tsx +++ b/tests/component/sections/home/datasets-list/DatasetsList.spec.tsx @@ -17,7 +17,7 @@ describe('Datasets List', () => { cy.findByTestId('datasets-list-skeleton').should('exist') datasets.forEach((dataset) => { - cy.findByRole('link', { name: dataset.title }).should('not.exist') + cy.findByRole('link', { name: dataset.version.title }).should('not.exist') }) }) @@ -38,7 +38,7 @@ describe('Datasets List', () => { cy.findByText('1 to 10 of 200 Datasets').should('exist') datasets.forEach((dataset) => { - cy.findByText(dataset.title) + cy.findByText(dataset.version.title) .should('exist') .should('have.attr', 'href', `/datasets?persistentId=${dataset.persistentId}`) }) diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCard.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCard.spec.tsx index 8b66c37d1..ad6bb084a 100644 --- a/tests/component/sections/home/datasets-list/dataset-card/DatasetCard.spec.tsx +++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCard.spec.tsx @@ -8,11 +8,11 @@ describe('DatasetCard', () => { const dataset = DatasetPreviewMother.createWithThumbnail() cy.customMount() - cy.findByText(dataset.title).should('exist') + cy.findByText(dataset.version.title).should('exist') - cy.findByRole('img', { name: dataset.title }).should('exist') + cy.findByRole('img', { name: dataset.version.title }).should('exist') cy.findByText(DateHelper.toDisplayFormat(dataset.releaseOrCreateDate)).should('exist') - cy.findByText(/Finch, Fiona, 2023, "Darwin's Finches"/) + cy.findByText(/Admin, Dataverse, 2023, "Dataset Title",/) .should('exist') .parent() .should('have.class', styles['citation-box']) diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardHeader.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardHeader.spec.tsx index 1e7773dfc..e428583cb 100644 --- a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardHeader.spec.tsx +++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardHeader.spec.tsx @@ -4,12 +4,14 @@ import { DatasetPreviewMother } from '../../../../dataset/domain/models/DatasetP describe('DatasetCardHeader', () => { it('should render the header', () => { const dataset = DatasetPreviewMother.create() - cy.customMount() + cy.customMount( + + ) - cy.findByText(dataset.title) + cy.findByText(dataset.version.title) .should('exist') .should('have.attr', 'href', `/datasets?persistentId=${dataset.persistentId}`) - dataset.labels.forEach((label) => { + dataset.version.labels.forEach((label) => { cy.findByText(label.value).should('exist') }) cy.findByLabelText('icon-dataset').should('exist') diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardInfo.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardInfo.spec.tsx index 5563fe412..f44e90ced 100644 --- a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardInfo.spec.tsx +++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardInfo.spec.tsx @@ -6,10 +6,16 @@ import { DatasetCardInfo } from '../../../../../../src/sections/home/datasets-li describe('DatasetCardInfo', () => { it('should render the dataset info', () => { const dataset = DatasetPreviewMother.createDraft() - cy.customMount() + cy.customMount( + + ) cy.findByText(DateHelper.toDisplayFormat(dataset.releaseOrCreateDate)).should('exist') - cy.findByText(/Finch, Fiona, 2023, "Darwin's Finches"/) + cy.findByText(/Admin, Dataverse, 2023, "Dataset Title",/) .should('exist') .parent() .should('have.class', styles['citation-box']) @@ -18,9 +24,15 @@ describe('DatasetCardInfo', () => { it('should render the citation with the deaccessioned background if the dataset is deaccessioned', () => { const dataset = DatasetPreviewMother.createDeaccessioned() - cy.customMount() + cy.customMount( + + ) - cy.findByText(/Finch, Fiona, 2023, "Darwin's Finches"/) + cy.findByText(/Admin, Dataverse, 2023, "Dataset Title",/) .should('exist') .parent() .should('have.class', styles['citation-box-deaccessioned']) diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.spec.tsx index e261e32db..b66e98a14 100644 --- a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.spec.tsx +++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.spec.tsx @@ -4,9 +4,15 @@ import { DatasetCardThumbnail } from '../../../../../../src/sections/home/datase describe('DatasetCardThumbnail', () => { it('should render the thumbnail', () => { const dataset = DatasetPreviewMother.createWithThumbnail() - cy.customMount() + cy.customMount( + + ) - cy.findByRole('img', { name: dataset.title }) + cy.findByRole('img', { name: dataset.version.title }) .should('exist') .parent('a') .should('have.attr', 'href', `/datasets?persistentId=${dataset.persistentId}`) @@ -14,7 +20,13 @@ describe('DatasetCardThumbnail', () => { it('should render the placeholder if the dataset has no thumbnail', () => { const dataset = DatasetPreviewMother.createWithNoThumbnail() - cy.customMount() + cy.customMount( + + ) cy.findByRole('img', { name: 'icon-dataset' }) .should('exist') From 3cbbd40a2f24d91cacc57663e10acc71070702e7 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Thu, 21 Dec 2023 16:12:32 +0100 Subject: [PATCH 2/6] feat(FileLabels): add DatasetLabels to File Page --- src/sections/file/File.module.scss | 1 + src/sections/file/File.tsx | 6 ++++-- src/sections/file/FileSkeleton.tsx | 7 +++++-- src/sections/file/file-labels/FileLabels.tsx | 9 +++++++++ tests/component/sections/file/File.spec.tsx | 1 + 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 src/sections/file/file-labels/FileLabels.tsx diff --git a/src/sections/file/File.module.scss b/src/sections/file/File.module.scss index 2c924a81a..695d4f586 100644 --- a/src/sections/file/File.module.scss +++ b/src/sections/file/File.module.scss @@ -6,6 +6,7 @@ .subtext { color: $dv-subtext-color; + margin-bottom: 10px; } .container { diff --git a/src/sections/file/File.tsx b/src/sections/file/File.tsx index 176eee903..42bcd48c2 100644 --- a/src/sections/file/File.tsx +++ b/src/sections/file/File.tsx @@ -7,6 +7,7 @@ import { useFile } from './useFile' import { useEffect } from 'react' import { useLoading } from '../loading/LoadingContext' import { FileSkeleton } from './FileSkeleton' +import { DatasetLabels } from '../dataset/dataset-labels/DatasetLabels' interface FileProps { repository: FileRepository @@ -33,9 +34,10 @@ export function File({ repository, id }: FileProps) {

{file.name}

- +

{t('subtext', { datasetTitle: file.datasetVersion.title })} - +

+
diff --git a/src/sections/file/FileSkeleton.tsx b/src/sections/file/FileSkeleton.tsx index c92f46c0b..e2c8f30de 100644 --- a/src/sections/file/FileSkeleton.tsx +++ b/src/sections/file/FileSkeleton.tsx @@ -1,4 +1,4 @@ -import styles from '../dataset/Dataset.module.scss' +import styles from './File.module.scss' import Skeleton, { SkeletonTheme } from 'react-loading-skeleton' import { Tabs } from '@iqss/dataverse-design-system' @@ -8,8 +8,11 @@ export function FileSkeleton() {

- +

+

+ +

diff --git a/src/sections/file/file-labels/FileLabels.tsx b/src/sections/file/file-labels/FileLabels.tsx new file mode 100644 index 000000000..2b71e350f --- /dev/null +++ b/src/sections/file/file-labels/FileLabels.tsx @@ -0,0 +1,9 @@ +import { DatasetLabel } from '../../../dataset/domain/models/Dataset' + +interface FileLabelsProps { + labels: DatasetLabel[] +} + +export function FileLabels({ labels }: FileLabelsProps) { + return
Not implemented
+} diff --git a/tests/component/sections/file/File.spec.tsx b/tests/component/sections/file/File.spec.tsx index 1377c092a..9f571aaac 100644 --- a/tests/component/sections/file/File.spec.tsx +++ b/tests/component/sections/file/File.spec.tsx @@ -15,6 +15,7 @@ describe('File', () => { cy.findAllByText(testFile.name).should('exist') cy.findByText(`This file is part of "${testFile.datasetVersion.title}".`).should('exist') + cy.findByText('Version 1.0').should('exist') }) it('renders skeleton while loading', () => { From b7bc8ce5e94d664fe6ca1e6a1d9b54ee1744dad1 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Thu, 21 Dec 2023 16:46:11 +0100 Subject: [PATCH 3/6] refactor: FileFileAccessRestrictedIcon move to file folder --- public/locales/en/file.json | 20 ++++++++- public/locales/en/files.json | 18 -------- .../access-file-menu/AccessStatus.tsx | 4 +- .../file-thumbnail/FileThumbnail.module.scss | 20 --------- .../file-thumbnail/FileThumbnail.tsx | 7 +++- .../FileThumbnailRestrictedIcon.tsx | 39 ------------------ .../FileAccessInfoIcon.module.scss | 21 ++++++++++ .../file-access/FileAccessRestrictedIcon.tsx | 41 +++++++++++++++++++ src/sections/file/file-labels/FileLabels.tsx | 9 ---- .../FileAccessRestrictedIcon.spec.tsx | 28 +++++++++++++ 10 files changed, 116 insertions(+), 91 deletions(-) delete mode 100644 src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnailRestrictedIcon.tsx create mode 100644 src/sections/file/file-access/FileAccessInfoIcon.module.scss create mode 100644 src/sections/file/file-access/FileAccessRestrictedIcon.tsx delete mode 100644 src/sections/file/file-labels/FileLabels.tsx create mode 100644 tests/component/sections/file/file-access/FileAccessRestrictedIcon.spec.tsx diff --git a/public/locales/en/file.json b/public/locales/en/file.json index 9e3bd1b68..56ee0fdac 100644 --- a/public/locales/en/file.json +++ b/public/locales/en/file.json @@ -2,5 +2,23 @@ "tabs": { "metadata": "Metadata" }, - "subtext": "This file is part of \"{{datasetTitle}}\"." + "subtext": "This file is part of \"{{datasetTitle}}\".", + "fileAccess": { + "title": "File Access", + "restricted": { + "name": "Restricted", + "icon": "Restricted File Icon" + }, + "restrictedWithAccess": { + "name": "Restricted with Access Granted", + "icon": "Restricted with access Icon" + }, + "embargoed": { + "name": "Embargoed" + }, + "public": { + "name": "Public", + "icon": "Public File Icon" + } + } } diff --git a/public/locales/en/files.json b/public/locales/en/files.json index bbae885f1..1f74f36ca 100644 --- a/public/locales/en/files.json +++ b/public/locales/en/files.json @@ -24,24 +24,6 @@ "published": "Published", "deposited": "Deposited" }, - "fileAccess": { - "title": "File Access", - "restricted": { - "name": "Restricted", - "icon": "Restricted File Icon" - }, - "restrictedWithAccess": { - "name": "Restricted with Access Granted", - "icon": "Restricted with access Icon" - }, - "embargoed": { - "name": "Embargoed" - }, - "public": { - "name": "Public", - "icon": "Public File Icon" - } - }, "copyToClipboard": { "clickToCopy": "Click to copy", "correctlyCopiedIcon": "Correctly copied to clipboard icon", diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.tsx index ea4a67a8d..a7dfd03a0 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.tsx @@ -35,7 +35,7 @@ function AccessStatusIcon({ sessionUserHasFileDownloadPermission: boolean restricted: boolean }) { - const { t } = useTranslation('files') + const { t } = useTranslation('file') if (restricted) { if (sessionUserHasFileDownloadPermission) { return ( @@ -63,7 +63,7 @@ function AccessStatusText({ file: FilePreview sessionUserHasFileDownloadPermission: boolean }) { - const { t } = useTranslation('files') + const { t } = useTranslation('file') const getAccessStatus = () => { if (file.isActivelyEmbargoed) { return 'embargoed' diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.module.scss b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.module.scss index aaaafe437..3e9b6a559 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.module.scss +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.module.scss @@ -37,23 +37,3 @@ .tooltip-preview-image { max-width: 390px; } - -%restricted-icon { - position: absolute; - right: -14px; - bottom: -5px; - font-size: 20px; -} - -.restricted-icon-restricted { - @extend %restricted-icon; - - color: $dv-danger-color; -} - -.restricted-icon-restrictedWithAccess { - @extend %restricted-icon; - - right: -16px; - color: $dv-success-color; -} diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx index ed343cf42..ad61432b3 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx @@ -1,7 +1,7 @@ import { FileThumbnailIcon } from './FileThumbnailIcon' import { FileThumbnailPreviewImage } from './FileThumbnailPreviewImage' import { FilePreview } from '../../../../../../../../files/domain/models/FilePreview' -import { FileThumbnailRestrictedIcon } from './FileThumbnailRestrictedIcon' +import { FileAccessRestrictedIcon } from '../../../../../../../file/file-access/FileAccessRestrictedIcon' import styles from './FileThumbnail.module.scss' import { useFileDownloadPermission } from '../../../../../../../file/file-permissions/useFileDownloadPermission' @@ -24,7 +24,10 @@ export function FileThumbnail({ file }: FileThumbnailProps) { ) : ( )} - +
) } diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnailRestrictedIcon.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnailRestrictedIcon.tsx deleted file mode 100644 index 23f620942..000000000 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnailRestrictedIcon.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { LockFill, UnlockFill } from 'react-bootstrap-icons' -import styles from './FileThumbnail.module.scss' -import { useTranslation } from 'react-i18next' -import { Tooltip } from '@iqss/dataverse-design-system' -import { FilePreview } from '../../../../../../../../files/domain/models/FilePreview' -import { useFileDownloadPermission } from '../../../../../../../file/file-permissions/useFileDownloadPermission' - -export function FileThumbnailRestrictedIcon({ file }: { file: FilePreview }) { - if (!file.access.restricted) { - return <> - } - - const { t } = useTranslation('files') - const { sessionUserHasFileDownloadPermission } = useFileDownloadPermission(file) - return ( - - - {sessionUserHasFileDownloadPermission ? ( - - ) : ( - - )} - - - ) -} diff --git a/src/sections/file/file-access/FileAccessInfoIcon.module.scss b/src/sections/file/file-access/FileAccessInfoIcon.module.scss new file mode 100644 index 000000000..025907f94 --- /dev/null +++ b/src/sections/file/file-access/FileAccessInfoIcon.module.scss @@ -0,0 +1,21 @@ +@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module"; + +%restricted-icon { + position: absolute; + right: -14px; + bottom: -5px; + font-size: 20px; +} + +.restricted-icon-restricted { + @extend %restricted-icon; + + color: $dv-danger-color; +} + +.restricted-icon-restrictedWithAccess { + @extend %restricted-icon; + + right: -16px; + color: $dv-success-color; +} \ No newline at end of file diff --git a/src/sections/file/file-access/FileAccessRestrictedIcon.tsx b/src/sections/file/file-access/FileAccessRestrictedIcon.tsx new file mode 100644 index 000000000..349edc9a8 --- /dev/null +++ b/src/sections/file/file-access/FileAccessRestrictedIcon.tsx @@ -0,0 +1,41 @@ +import { LockFill, UnlockFill } from 'react-bootstrap-icons' +import styles from './FileAccessInfoIcon.module.scss' +import { useTranslation } from 'react-i18next' +import { Tooltip } from '@iqss/dataverse-design-system' + +interface FileAccessInfoIconProps { + isRestricted: boolean + canDownloadFile: boolean +} +export function FileAccessRestrictedIcon({ + isRestricted, + canDownloadFile +}: FileAccessInfoIconProps) { + const { t } = useTranslation('file') + + if (!isRestricted) { + return <> + } + + if (canDownloadFile) { + return ( + + + + + + ) + } + + return ( + + + + + + ) +} diff --git a/src/sections/file/file-labels/FileLabels.tsx b/src/sections/file/file-labels/FileLabels.tsx deleted file mode 100644 index 2b71e350f..000000000 --- a/src/sections/file/file-labels/FileLabels.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { DatasetLabel } from '../../../dataset/domain/models/Dataset' - -interface FileLabelsProps { - labels: DatasetLabel[] -} - -export function FileLabels({ labels }: FileLabelsProps) { - return
Not implemented
-} diff --git a/tests/component/sections/file/file-access/FileAccessRestrictedIcon.spec.tsx b/tests/component/sections/file/file-access/FileAccessRestrictedIcon.spec.tsx new file mode 100644 index 000000000..42a1c5fbf --- /dev/null +++ b/tests/component/sections/file/file-access/FileAccessRestrictedIcon.spec.tsx @@ -0,0 +1,28 @@ +import { FileAccessRestrictedIcon } from '../../../../../src/sections/file/file-access/FileAccessRestrictedIcon' + +describe('FileAccessRestrictedIcon', () => { + it('should render the restricted icon if the file is restricted and the user cannot download the file', () => { + cy.customMount() + + cy.findByTitle('Restricted File Icon').should('exist').parent().trigger('mouseover') + cy.findByText('File Access: Restricted').should('exist') + + cy.findByTitle('Restricted with access Icon').should('not.exist') + }) + + it('should render the restricted with access icon if the file is restricted and the user can download the file', () => { + cy.customMount() + + cy.findByTitle('Restricted with access Icon').should('exist').parent().trigger('mouseover') + cy.findByText('File Access: Restricted with Access Granted').should('exist') + + cy.findByTitle('Restricted File Icon').should('not.exist') + }) + + it('should not render any icon if the file is not restricted', () => { + cy.customMount() + + cy.findByTitle('Restricted with access Icon').should('not.exist') + cy.findByTitle('Restricted File Icon').should('not.exist') + }) +}) From 9b1c321065396cf92d2d486a85bbed61c6eb2647 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Fri, 22 Dec 2023 18:06:08 +0100 Subject: [PATCH 4/6] feat(FileLabels): add Restricted icon to File Labels --- src/files/domain/models/File.ts | 6 +++++ .../access-file-menu/AccessStatus.tsx | 17 +++--------- .../file-thumbnail/FileThumbnail.module.scss | 6 +++++ .../file-thumbnail/FileThumbnail.tsx | 10 ++++--- src/sections/file/File.module.scss | 11 +++++++- src/sections/file/File.tsx | 13 ++++++++- .../FileAccessInfoIcon.module.scss | 3 --- .../file-access/FileAccessRestrictedIcon.tsx | 9 +++---- src/stories/files/File.stories.tsx | 14 ++++++++++ src/stories/files/FileMockRepository.ts | 4 ++- .../files/domain/models/FileMother.ts | 27 +++++++++++++++++++ tests/component/sections/file/File.spec.tsx | 9 +++++++ .../FileAccessRestrictedIcon.spec.tsx | 6 ++--- 13 files changed, 103 insertions(+), 32 deletions(-) diff --git a/src/files/domain/models/File.ts b/src/files/domain/models/File.ts index d348f4df8..6f1eb29db 100644 --- a/src/files/domain/models/File.ts +++ b/src/files/domain/models/File.ts @@ -1,6 +1,12 @@ import { DatasetVersion } from '../../../dataset/domain/models/Dataset' +export interface FilePermissions { + canDownloadFile: boolean +} + export interface File { name: string datasetVersion: DatasetVersion + restricted: boolean + permissions: FilePermissions } diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.tsx index a7dfd03a0..02509ec3c 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.tsx @@ -39,21 +39,12 @@ function AccessStatusIcon({ if (restricted) { if (sessionUserHasFileDownloadPermission) { return ( - + ) } - return ( - - ) + return } - return + return } function AccessStatusText({ @@ -89,7 +80,7 @@ function AccessStatusText({ : 'danger' ] }> - {t(`table.fileAccess.${getAccessStatus()}.name`)} + {t(`fileAccess.${getAccessStatus()}.name`)} ) } diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.module.scss b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.module.scss index 3e9b6a559..b30949ecb 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.module.scss +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.module.scss @@ -37,3 +37,9 @@ .tooltip-preview-image { max-width: 390px; } + +.restricted-icon { + position: absolute; + right: -14px; + bottom: -5px; +} diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx index ad61432b3..7642d03a0 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.tsx @@ -24,10 +24,12 @@ export function FileThumbnail({ file }: FileThumbnailProps) { ) : ( )} - +
+ +
) } diff --git a/src/sections/file/File.module.scss b/src/sections/file/File.module.scss index 695d4f586..d05c34a83 100644 --- a/src/sections/file/File.module.scss +++ b/src/sections/file/File.module.scss @@ -5,8 +5,8 @@ } .subtext { - color: $dv-subtext-color; margin-bottom: 10px; + color: $dv-subtext-color; } .container { @@ -16,4 +16,13 @@ .separation-line { margin: 1em 0; border-bottom: 1px solid #dee2e6; +} + +.labels { + display: flex; + align-items: center; +} + +.restricted-icon { + margin-right: 6px; } \ No newline at end of file diff --git a/src/sections/file/File.tsx b/src/sections/file/File.tsx index 42bcd48c2..399431c14 100644 --- a/src/sections/file/File.tsx +++ b/src/sections/file/File.tsx @@ -8,6 +8,7 @@ import { useEffect } from 'react' import { useLoading } from '../loading/LoadingContext' import { FileSkeleton } from './FileSkeleton' import { DatasetLabels } from '../dataset/dataset-labels/DatasetLabels' +import { FileAccessRestrictedIcon } from './file-access/FileAccessRestrictedIcon' interface FileProps { repository: FileRepository @@ -37,7 +38,17 @@ export function File({ repository, id }: FileProps) {

{t('subtext', { datasetTitle: file.datasetVersion.title })}

- +
+ {file.restricted && ( +
+ +
+ )} + +
diff --git a/src/sections/file/file-access/FileAccessInfoIcon.module.scss b/src/sections/file/file-access/FileAccessInfoIcon.module.scss index 025907f94..7f750214c 100644 --- a/src/sections/file/file-access/FileAccessInfoIcon.module.scss +++ b/src/sections/file/file-access/FileAccessInfoIcon.module.scss @@ -1,9 +1,6 @@ @import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module"; %restricted-icon { - position: absolute; - right: -14px; - bottom: -5px; font-size: 20px; } diff --git a/src/sections/file/file-access/FileAccessRestrictedIcon.tsx b/src/sections/file/file-access/FileAccessRestrictedIcon.tsx index 349edc9a8..426278ac7 100644 --- a/src/sections/file/file-access/FileAccessRestrictedIcon.tsx +++ b/src/sections/file/file-access/FileAccessRestrictedIcon.tsx @@ -4,16 +4,13 @@ import { useTranslation } from 'react-i18next' import { Tooltip } from '@iqss/dataverse-design-system' interface FileAccessInfoIconProps { - isRestricted: boolean + restricted: boolean canDownloadFile: boolean } -export function FileAccessRestrictedIcon({ - isRestricted, - canDownloadFile -}: FileAccessInfoIconProps) { +export function FileAccessRestrictedIcon({ restricted, canDownloadFile }: FileAccessInfoIconProps) { const { t } = useTranslation('file') - if (!isRestricted) { + if (!restricted) { return <> } diff --git a/src/stories/files/File.stories.tsx b/src/stories/files/File.stories.tsx index 060fe8dfc..1f72a8c7d 100644 --- a/src/stories/files/File.stories.tsx +++ b/src/stories/files/File.stories.tsx @@ -5,6 +5,7 @@ import { File } from '../../sections/file/File' import { WithLayout } from '../WithLayout' import { FileMockLoadingRepository } from './FileMockLoadingRepository' import { FileMockNoDataRepository } from './FileMockNoDataRepository' +import { FileMother } from '../../../tests/component/files/domain/models/FileMother' const meta: Meta = { title: 'Pages/File', @@ -19,6 +20,19 @@ export const Default: Story = { render: () => } +export const Restricted: Story = { + render: () => +} + +export const RestrictedWithAccessGranted: Story = { + render: () => ( + + ) +} + export const Loading: Story = { render: () => } diff --git a/src/stories/files/FileMockRepository.ts b/src/stories/files/FileMockRepository.ts index cbb518ecf..73a089ccd 100644 --- a/src/stories/files/FileMockRepository.ts +++ b/src/stories/files/FileMockRepository.ts @@ -13,6 +13,8 @@ import { FileMother } from '../../../tests/component/files/domain/models/FileMot import { File } from '../../files/domain/models/File' export class FileMockRepository implements FileRepository { + constructor(public readonly fileMock?: File) {} + // eslint-disable-next-line unused-imports/no-unused-vars getAllByDatasetPersistentId( datasetPersistentId: string, @@ -67,7 +69,7 @@ export class FileMockRepository implements FileRepository { getById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { - resolve(FileMother.createRealistic()) + resolve(this.fileMock ?? FileMother.createRealistic()) }, 1000) }) } diff --git a/tests/component/files/domain/models/FileMother.ts b/tests/component/files/domain/models/FileMother.ts index 28b245c94..8b63476fa 100644 --- a/tests/component/files/domain/models/FileMother.ts +++ b/tests/component/files/domain/models/FileMother.ts @@ -7,6 +7,10 @@ export class FileMother { return { name: faker.system.fileName(), datasetVersion: DatasetVersionMother.create(), + restricted: faker.datatype.boolean(), + permissions: { + canDownloadFile: faker.datatype.boolean() + }, ...props } } @@ -15,6 +19,29 @@ export class FileMother { return this.create({ name: 'file.csv', datasetVersion: DatasetVersionMother.createRealistic(), + restricted: false, + permissions: { + canDownloadFile: true + }, + ...props + }) + } + + static createRestricted(props?: Partial): File { + return this.createRealistic({ + restricted: true, + permissions: { + canDownloadFile: false + }, + ...props + }) + } + + static createRestrictedWithAccessGranted(props?: Partial): File { + return this.createRestricted({ + permissions: { + canDownloadFile: true + }, ...props }) } diff --git a/tests/component/sections/file/File.spec.tsx b/tests/component/sections/file/File.spec.tsx index 9f571aaac..3049c4b91 100644 --- a/tests/component/sections/file/File.spec.tsx +++ b/tests/component/sections/file/File.spec.tsx @@ -36,4 +36,13 @@ describe('File', () => { cy.findByText('Page Not Found').should('exist') }) + + it('renders the restricted icon if the file is restricted', () => { + const testFile = FileMother.createRestricted() + fileRepository.getById = cy.stub().resolves(testFile) + + cy.customMount() + + cy.findByText('Restricted File Icon').should('exist') + }) }) diff --git a/tests/component/sections/file/file-access/FileAccessRestrictedIcon.spec.tsx b/tests/component/sections/file/file-access/FileAccessRestrictedIcon.spec.tsx index 42a1c5fbf..5d918e82a 100644 --- a/tests/component/sections/file/file-access/FileAccessRestrictedIcon.spec.tsx +++ b/tests/component/sections/file/file-access/FileAccessRestrictedIcon.spec.tsx @@ -2,7 +2,7 @@ import { FileAccessRestrictedIcon } from '../../../../../src/sections/file/file- describe('FileAccessRestrictedIcon', () => { it('should render the restricted icon if the file is restricted and the user cannot download the file', () => { - cy.customMount() + cy.customMount() cy.findByTitle('Restricted File Icon').should('exist').parent().trigger('mouseover') cy.findByText('File Access: Restricted').should('exist') @@ -11,7 +11,7 @@ describe('FileAccessRestrictedIcon', () => { }) it('should render the restricted with access icon if the file is restricted and the user can download the file', () => { - cy.customMount() + cy.customMount() cy.findByTitle('Restricted with access Icon').should('exist').parent().trigger('mouseover') cy.findByText('File Access: Restricted with Access Granted').should('exist') @@ -20,7 +20,7 @@ describe('FileAccessRestrictedIcon', () => { }) it('should not render any icon if the file is not restricted', () => { - cy.customMount() + cy.customMount() cy.findByTitle('Restricted with access Icon').should('not.exist') cy.findByTitle('Restricted File Icon').should('not.exist') From 95fd1a3ddb01bbf9fdd47fafcddf2cf6a53918c6 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Mon, 8 Jan 2024 10:38:38 +0100 Subject: [PATCH 5/6] fix: remove demo dataverse reference in page not found message --- public/locales/en/pageNotFound.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales/en/pageNotFound.json b/public/locales/en/pageNotFound.json index 1fb88259b..19d0dcf7e 100644 --- a/public/locales/en/pageNotFound.json +++ b/public/locales/en/pageNotFound.json @@ -1,4 +1,4 @@ { "heading": "Page Not Found", - "message": "The page you are looking for was not found. If you believe this is an error, please contact Demo Dataverse Support for assistance." + "message": "The page you are looking for was not found." } From 4f9728e52656d9b8be273ffd70f7b018621fde52 Mon Sep 17 00:00:00 2001 From: MellyGray Date: Mon, 8 Jan 2024 12:17:04 +0100 Subject: [PATCH 6/6] fix: e2e test year dependence --- .../DatasetJSDataverseRepository.spec.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts index be2e91bce..dcd078695 100644 --- a/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts +++ b/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts @@ -30,8 +30,14 @@ function getPersistentIdUrl(persistentId: string) { return `https://doi.org/${persistentId.replace('doi:', '')}` } +function getCitationString(persistentId: string, version: 'DRAFT VERSION' | 'V1') { + const year = new Date().getFullYear() + return `Finch, Fiona, ${year}, "Darwin's Finches", ${getPersistentIdUrl(persistentId)}, Root, ${version}` +} + const datasetData = (persistentId: string, versionId: number) => { - const persistentIdUrl = getPersistentIdUrl(persistentId) return { license: { name: 'CC0 1.0', @@ -88,7 +94,7 @@ const datasetData = (persistentId: string, versionId: number) => { latestVersionPublishingStatus: 'draft', isLatest: true, isInReview: false, - citation: `Finch, Fiona, 2023, "Darwin's Finches", ${persistentIdUrl}, Root, DRAFT VERSION`, + citation: getCitationString(persistentId, 'DRAFT VERSION'), title: "Darwin's Finches", labels: [ { semanticMeaning: 'dataset', value: 'Draft' }, @@ -165,9 +171,7 @@ describe('Dataset JSDataverse Repository', () => { minorNumber: 0 }, DatasetPublishingStatus.RELEASED, - `Finch, Fiona, 2023, "Darwin's Finches", ${getPersistentIdUrl(dataset.persistentId)}, Root, V1`, + getCitationString(dataset.persistentId, 'V1'), [new DatasetLabel(DatasetLabelSemanticMeaning.FILE, 'Version 1.0')], true, false, @@ -210,9 +214,7 @@ describe('Dataset JSDataverse Repository', () => { minorNumber: 0 }, DatasetPublishingStatus.RELEASED, - `Finch, Fiona, 2023, "Darwin's Finches", ${getPersistentIdUrl(dataset.persistentId)}, Root, V1`, + getCitationString(dataset.persistentId, 'V1'), [new DatasetLabel(DatasetLabelSemanticMeaning.FILE, 'Version 1.0')], true, false,