From 0b300062638feb0c08d280f6b8f5a1024ee9beb4 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Mon, 13 Nov 2023 15:20:08 -0500 Subject: [PATCH 01/11] feat: add Dataset Dropdown options to AccessDatasetMenu.tsx --- public/locales/en/dataset.json | 5 +- .../access-dataset-menu/AccessDatasetMenu.tsx | 59 ++++++++++++++++++- .../AccessDatasetMenu.stories.tsx | 13 ++++ 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index 916ab30b4..2e847daeb 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -53,7 +53,10 @@ } }, "accessDataset": { - "title": "Access Dataset" + "title": "Access Dataset", + "downloadZip": "Download ZIP", + "downloadOriginalZip": "Original Format ZIP", + "downloadArchiveZip": "Archive Format (.tab) ZIP" }, "uploadFiles": "Upload Files" }, diff --git a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx index 542ad49c0..923743376 100644 --- a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx +++ b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx @@ -3,15 +3,23 @@ import { DatasetPublishingStatus, DatasetVersion } from '../../../../dataset/domain/models/Dataset' -import { DropdownButton, DropdownButtonItem } from '@iqss/dataverse-design-system' +import { DropdownButton, DropdownButtonItem, DropdownHeader } from '@iqss/dataverse-design-system' import { useTranslation } from 'react-i18next' +import { Download } from 'react-bootstrap-icons' interface AccessDatasetMenuProps { version: DatasetVersion permissions: DatasetPermissions + datasetContainsTabularFiles?: boolean //TODO: get this from backend + fileSize?: string //TODO: get file size from backend } -export function AccessDatasetMenu({ version, permissions }: AccessDatasetMenuProps) { +export function AccessDatasetMenu({ + version, + permissions, + datasetContainsTabularFiles = true, //TODO: remove default when backend is ready + fileSize = '1.2 GB' //TODO: remove default when backend is ready +}: AccessDatasetMenuProps) { if ( !permissions.canDownloadFiles || (version.publishingStatus === DatasetPublishingStatus.DEACCESSIONED && @@ -19,6 +27,50 @@ export function AccessDatasetMenu({ version, permissions }: AccessDatasetMenuPro ) { return <> } + type DownloadType = 'original' | 'archive' + + const handleDownload = (type: DownloadType) => { + //TODO: implement download feature + console.log(`Downloading ${type} zip file`) + } + const renderDownloadOptions = (datasetContainsTabularFiles: boolean) => { + // Define the options based on whether the dataset contains tabular files + const downloadOptions: { key: string; downloadType: DownloadType; translationKey: string }[] = + datasetContainsTabularFiles + ? [ + { + key: 'original', + downloadType: 'original', + translationKey: 'datasetActionButtons.accessDataset.downloadOriginalZip' + }, + { + key: 'archive', + downloadType: 'archive', + translationKey: 'datasetActionButtons.accessDataset.downloadArchiveZip' + } + ] + : [ + { + key: 'standard', + downloadType: 'original', + translationKey: 'datasetActionButtons.accessDataset.downloadZip' + } + ] + + // Map the options to DropdownButtonItem components + return ( + <> + + Download Options + + {downloadOptions.map((option) => ( + handleDownload(option.downloadType)}> + {t(option.translationKey)} ({fileSize}) + + ))} + + ) + } const { t } = useTranslation('dataset') return ( @@ -27,10 +79,11 @@ export function AccessDatasetMenu({ version, permissions }: AccessDatasetMenuPro title={t('datasetActionButtons.accessDataset.title')} asButtonGroup variant="primary"> - Download + {renderDownloadOptions(datasetContainsTabularFiles)} ) } + // TODO: add download feature https://github.com/IQSS/dataverse-frontend/issues/63 // TODO: add explore feature // TODO: add compute feature diff --git a/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx b/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx index 8aba8ca0c..15b4d7cfc 100644 --- a/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx +++ b/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx @@ -23,6 +23,19 @@ type Story = StoryObj export const WithAllPermissions: Story = { render: () => ( + ) +} + +export const WithTabularFiles: Story = { + render: () => ( + From e112c2aac96e0a8a68e2461b7e8963289746d5fb Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 14 Nov 2023 15:32:31 -0500 Subject: [PATCH 02/11] feat: add FileDownloadSize, update stories and tests --- src/dataset/domain/models/Dataset.ts | 23 +++++- .../infrastructure/mappers/JSDatasetMapper.ts | 4 +- .../DatasetActionButtons.tsx | 8 +- .../access-dataset-menu/AccessDatasetMenu.tsx | 81 ++++++++++++------- .../DatasetActionButtons.stories.tsx | 6 ++ .../AccessDatasetMenu.stories.tsx | 25 ++++-- .../dataset/domain/models/DatasetMother.ts | 31 ++++++- .../mappers/JSDatasetMapper.spec.ts | 6 +- 8 files changed, 141 insertions(+), 43 deletions(-) diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts index 409a7ab5e..a0970744c 100644 --- a/src/dataset/domain/models/Dataset.ts +++ b/src/dataset/domain/models/Dataset.ts @@ -280,6 +280,17 @@ export interface PrivateUrl { urlSnippet: string } +export enum FileDownloadSizeMode { + ALL = 'All', + ORIGINAL = 'Original', + ARCHIVAL = 'Archival' +} + +export interface FileDownloadSize { + size: number + fileDownloadSizeMode: FileDownloadSizeMode +} + export class Dataset { constructor( public readonly persistentId: string, @@ -293,10 +304,12 @@ export class Dataset { public readonly permissions: DatasetPermissions, public readonly locks: DatasetLock[], public readonly hasValidTermsOfAccess: boolean, + public readonly hasOneTabularFileAtLeast: boolean, public readonly isValid: boolean, public readonly isReleased: boolean, public readonly thumbnail?: string, - public readonly privateUrl?: PrivateUrl + public readonly privateUrl?: PrivateUrl, + public readonly fileDownloadSizes?: FileDownloadSize[] ) {} public getTitle(): string { @@ -339,10 +352,12 @@ export class Dataset { public readonly permissions: DatasetPermissions, public readonly locks: DatasetLock[], public readonly hasValidTermsOfAccess: boolean, + public readonly hasOneTabularFileAtLeast: boolean, public readonly isValid: boolean, public readonly isReleased: boolean, public readonly thumbnail?: string, - public readonly privateUrl?: PrivateUrl + public readonly privateUrl?: PrivateUrl, + public readonly fileDownloadSizes?: FileDownloadSize[] ) { this.withLabels() this.withAlerts() @@ -455,10 +470,12 @@ export class Dataset { this.permissions, this.locks, this.hasValidTermsOfAccess, + this.hasOneTabularFileAtLeast, this.isValid, this.isReleased, this.thumbnail, - this.privateUrl + this.privateUrl, + this.fileDownloadSizes ) } } diff --git a/src/dataset/infrastructure/mappers/JSDatasetMapper.ts b/src/dataset/infrastructure/mappers/JSDatasetMapper.ts index 77a8c3031..f8ebf5f97 100644 --- a/src/dataset/infrastructure/mappers/JSDatasetMapper.ts +++ b/src/dataset/infrastructure/mappers/JSDatasetMapper.ts @@ -47,11 +47,13 @@ export class JSDatasetMapper { }, // TODO Connect with dataset permissions [], // TODO Connect with dataset locks true, // TODO Connect with dataset hasValidTermsOfAccess + true, // TODO Connect with dataset hasOneTabularFileAtLeast true, // TODO Connect with dataset isValid jsDataset.versionInfo.releaseTime !== undefined && !isNaN(jsDataset.versionInfo.releaseTime.getTime()), // TODO Connect with dataset isReleased, undefined, // TODO: get dataset thumbnail from Dataverse https://github.com/IQSS/dataverse-frontend/issues/203 - privateUrl + privateUrl, + [] // TODO: Connect with file download use case ).build() } diff --git a/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx b/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx index ce57675e0..c95f2c008 100644 --- a/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx +++ b/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx @@ -14,9 +14,15 @@ interface DatasetActionButtonsProps { export function DatasetActionButtons({ dataset }: DatasetActionButtonsProps) { const { t } = useTranslation('dataset') + console.log(JSON.stringify(dataset.fileDownloadSizes)) return ( - + diff --git a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx index 923743376..002dbd8c5 100644 --- a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx +++ b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx @@ -1,7 +1,9 @@ import { DatasetPermissions, DatasetPublishingStatus, - DatasetVersion + DatasetVersion, + FileDownloadSize, + FileDownloadSizeMode } from '../../../../dataset/domain/models/Dataset' import { DropdownButton, DropdownButtonItem, DropdownHeader } from '@iqss/dataverse-design-system' import { useTranslation } from 'react-i18next' @@ -10,15 +12,15 @@ import { Download } from 'react-bootstrap-icons' interface AccessDatasetMenuProps { version: DatasetVersion permissions: DatasetPermissions - datasetContainsTabularFiles?: boolean //TODO: get this from backend - fileSize?: string //TODO: get file size from backend + hasOneTabularFileAtLeast: boolean + fileDownloadSizes?: FileDownloadSize[] } export function AccessDatasetMenu({ version, permissions, - datasetContainsTabularFiles = true, //TODO: remove default when backend is ready - fileSize = '1.2 GB' //TODO: remove default when backend is ready + hasOneTabularFileAtLeast, + fileDownloadSizes }: AccessDatasetMenuProps) { if ( !permissions.canDownloadFiles || @@ -27,35 +29,49 @@ export function AccessDatasetMenu({ ) { return <> } - type DownloadType = 'original' | 'archive' - const handleDownload = (type: DownloadType) => { + function formatFileSize(bytes: number): string { + if (bytes < 1024) { + return `${bytes} B` + } else if (bytes < 1024 * 1024) { + return `${(bytes / 1024).toFixed(2)} KB` + } else if (bytes < 1024 * 1024 * 1024) { + return `${(bytes / 1024 / 1024).toFixed(2)} MB` + } else { + return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB` + } + } + + const handleDownload = (type: FileDownloadSizeMode) => { //TODO: implement download feature console.log(`Downloading ${type} zip file`) } const renderDownloadOptions = (datasetContainsTabularFiles: boolean) => { // Define the options based on whether the dataset contains tabular files - const downloadOptions: { key: string; downloadType: DownloadType; translationKey: string }[] = - datasetContainsTabularFiles - ? [ - { - key: 'original', - downloadType: 'original', - translationKey: 'datasetActionButtons.accessDataset.downloadOriginalZip' - }, - { - key: 'archive', - downloadType: 'archive', - translationKey: 'datasetActionButtons.accessDataset.downloadArchiveZip' - } - ] - : [ - { - key: 'standard', - downloadType: 'original', - translationKey: 'datasetActionButtons.accessDataset.downloadZip' - } - ] + const downloadOptions: { + key: string + downloadType: FileDownloadSizeMode + translationKey: string + }[] = datasetContainsTabularFiles + ? [ + { + key: 'original', + downloadType: FileDownloadSizeMode.ORIGINAL, + translationKey: 'datasetActionButtons.accessDataset.downloadOriginalZip' + }, + { + key: 'archive', + downloadType: FileDownloadSizeMode.ARCHIVAL, + translationKey: 'datasetActionButtons.accessDataset.downloadArchiveZip' + } + ] + : [ + { + key: 'standard', + downloadType: FileDownloadSizeMode.ORIGINAL, + translationKey: 'datasetActionButtons.accessDataset.downloadZip' + } + ] // Map the options to DropdownButtonItem components return ( @@ -65,7 +81,12 @@ export function AccessDatasetMenu({ {downloadOptions.map((option) => ( handleDownload(option.downloadType)}> - {t(option.translationKey)} ({fileSize}) + {t(option.translationKey)} ( + {formatFileSize( + fileDownloadSizes?.find((size) => size.fileDownloadSizeMode === option.downloadType) + ?.size || 0 + )} + ) ))} @@ -79,7 +100,7 @@ export function AccessDatasetMenu({ title={t('datasetActionButtons.accessDataset.title')} asButtonGroup variant="primary"> - {renderDownloadOptions(datasetContainsTabularFiles)} + {renderDownloadOptions(hasOneTabularFileAtLeast)} ) } diff --git a/src/stories/dataset/dataset-action-buttons/DatasetActionButtons.stories.tsx b/src/stories/dataset/dataset-action-buttons/DatasetActionButtons.stories.tsx index 173f83561..9226ec599 100644 --- a/src/stories/dataset/dataset-action-buttons/DatasetActionButtons.stories.tsx +++ b/src/stories/dataset/dataset-action-buttons/DatasetActionButtons.stories.tsx @@ -3,6 +3,7 @@ import { WithI18next } from '../../WithI18next' import { WithSettings } from '../../WithSettings' import { DatasetActionButtons } from '../../../sections/dataset/dataset-action-buttons/DatasetActionButtons' import { + DatasetFileDownloadSizeMother, DatasetMother, DatasetPermissionsMother, DatasetVersionMother @@ -28,6 +29,11 @@ export const WithPublishPermissions: Story = { permissions: DatasetPermissionsMother.createWithAllAllowed(), version: DatasetVersionMother.createDraftAsLatestVersion(), hasValidTermsOfAccess: true, + hasOneTabularFileAtLeast: true, + fileDownloadSizes: [ + DatasetFileDownloadSizeMother.createOriginal(), + DatasetFileDownloadSizeMother.createArchival() + ], isValid: true, isReleased: true })} diff --git a/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx b/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx index 15b4d7cfc..402e9753e 100644 --- a/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx +++ b/src/stories/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.stories.tsx @@ -2,6 +2,7 @@ import { Meta, StoryObj } from '@storybook/react' import { WithI18next } from '../../../WithI18next' import { WithSettings } from '../../../WithSettings' import { + DatasetFileDownloadSizeMother, DatasetPermissionsMother, DatasetVersionMother } from '../../../../../tests/component/dataset/domain/models/DatasetMother' @@ -20,24 +21,36 @@ const meta: Meta = { export default meta type Story = StoryObj -export const WithAllPermissions: Story = { +export const WithDownloadNotAllowed: Story = { render: () => ( + ) +} +export const WithoutTabularFiles: Story = { + render: () => ( + ) } - export const WithTabularFiles: Story = { render: () => ( ) } diff --git a/tests/component/dataset/domain/models/DatasetMother.ts b/tests/component/dataset/domain/models/DatasetMother.ts index bca8773c5..30d6adadb 100644 --- a/tests/component/dataset/domain/models/DatasetMother.ts +++ b/tests/component/dataset/domain/models/DatasetMother.ts @@ -10,8 +10,10 @@ import { DatasetPermissions, DatasetPublishingStatus, DatasetVersion, + FileDownloadSize, MetadataBlockName } from '../../../../../src/dataset/domain/models/Dataset' +import { FileDownloadSizeMode } from '@iqss/dataverse-client-javascript' export class DatasetVersionMother { static create(props?: Partial): DatasetVersion { @@ -185,6 +187,24 @@ export class DatasetLockMother { } } +export class DatasetFileDownloadSizeMother { + static create(props?: Partial): FileDownloadSize { + return { + size: faker.datatype.number(), + fileDownloadSizeMode: faker.helpers.arrayElement(Object.values(FileDownloadSizeMode)), + ...props + } + } + + static createArchival(): FileDownloadSize { + return this.create({ fileDownloadSizeMode: FileDownloadSizeMode.ARCHIVAL }) + } + + static createOriginal(): FileDownloadSize { + return this.create({ fileDownloadSizeMode: FileDownloadSizeMode.ORIGINAL }) + } +} + export class DatasetMother { static createEmpty(): undefined { return undefined @@ -285,10 +305,12 @@ export class DatasetMother { permissions: DatasetPermissionsMother.create(), locks: [], hasValidTermsOfAccess: faker.datatype.boolean(), + hasOneTabularFileAtLeast: faker.datatype.boolean(), isValid: faker.datatype.boolean(), isReleased: faker.datatype.boolean(), thumbnail: undefined, privateUrl: undefined, + fileDownloadSizes: undefined, ...props } @@ -302,10 +324,12 @@ export class DatasetMother { dataset.permissions, dataset.locks, dataset.hasValidTermsOfAccess, + dataset.hasOneTabularFileAtLeast, dataset.isValid, dataset.isReleased, dataset.thumbnail, - dataset.privateUrl + dataset.privateUrl, + dataset.fileDownloadSizes ).build() } @@ -437,6 +461,11 @@ export class DatasetMother { locks: [], isReleased: true, hasValidTermsOfAccess: true, + hasOneTabularFileAtLeast: true, + fileDownloadSizes: [ + { size: 219829, fileDownloadSizeMode: FileDownloadSizeMode.ORIGINAL }, + { size: 253629, fileDownloadSizeMode: FileDownloadSizeMode.ARCHIVAL } + ], isValid: true, ...props }) diff --git a/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts b/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts index 699c3d8a7..37b813b75 100644 --- a/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts +++ b/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts @@ -118,10 +118,12 @@ const expectedDataset = { }, locks: [], hasValidTermsOfAccess: true, + hasOneTabularFileAtLeast: true, isValid: true, isReleased: false, thumbnail: undefined, - privateUrl: undefined + privateUrl: undefined, + fileDownloadSizes: [] } const expectedDatasetAlternateVersion = { persistentId: 'doi:10.5072/FK2/B4B2MJ', @@ -138,9 +140,11 @@ const expectedDatasetAlternateVersion = { citation: 'Finch, Fiona, 2023, "Darwin\'s Finches", https://doi.org/10.5072/FK2/B4B2MJ, Root, DRAFT VERSION', hasValidTermsOfAccess: true, + hasOneTabularFileAtLeast: true, isReleased: false, isValid: true, privateUrl: undefined, + fileDownloadSizes: [], labels: [ { semanticMeaning: 'dataset', value: 'Draft' }, { semanticMeaning: 'warning', value: 'Unpublished' } From 36baaf64a62e0d44079d9cb18fd5f6829700b5c3 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Wed, 15 Nov 2023 12:36:31 -0500 Subject: [PATCH 03/11] feat: update unit test --- .../AccessDatasetMenu.spec.tsx | 97 ++++++++++++++++--- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx index c30dac356..7132badfd 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx @@ -1,5 +1,6 @@ import { AccessDatasetMenu } from '../../../../../../src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu' import { + DatasetFileDownloadSizeMother, DatasetPermissionsMother, DatasetVersionMother } from '../../../../dataset/domain/models/DatasetMother' @@ -8,8 +9,18 @@ describe('AccessDatasetMenu', () => { it('renders the AccessDatasetMenu if the user has download files permissions and the dataset is not deaccessioned', () => { const version = DatasetVersionMother.createReleased() const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() - - cy.customMount() + const fileDownloadSizes = [ + DatasetFileDownloadSizeMother.createOriginal(), + DatasetFileDownloadSizeMother.createArchival() + ] + cy.customMount( + + ) cy.findByRole('button', { name: 'Access Dataset' }).should('exist') }) @@ -20,27 +31,91 @@ describe('AccessDatasetMenu', () => { canUpdateDataset: true, canDownloadFiles: true }) - - cy.customMount() - + const fileDownloadSizes = [ + DatasetFileDownloadSizeMother.createOriginal(), + DatasetFileDownloadSizeMother.createArchival() + ] + cy.customMount( + + ) cy.findByRole('button', { name: 'Access Dataset' }).should('exist') }) it('does not render the AccessDatasetMenu if the user do not have download files permissions', () => { const version = DatasetVersionMother.create() const permissions = DatasetPermissionsMother.createWithFilesDownloadNotAllowed() - - cy.customMount() - + const fileDownloadSizes = [ + DatasetFileDownloadSizeMother.createOriginal(), + DatasetFileDownloadSizeMother.createArchival() + ] + cy.customMount( + + ) cy.findByRole('button', { name: 'Access Dataset' }).should('not.exist') }) it('does not render the AccessDatasetMenu if the dataset is deaccessioned and the user does not have update dataset permissions', () => { const version = DatasetVersionMother.createDeaccessioned() const permissions = DatasetPermissionsMother.createWithUpdateDatasetNotAllowed() - - cy.customMount() - + const fileDownloadSizes = [ + DatasetFileDownloadSizeMother.createOriginal(), + DatasetFileDownloadSizeMother.createArchival() + ] + cy.customMount( + + ) cy.findByRole('button', { name: 'Access Dataset' }).should('not.exist') }) + it('displays one dropdown option if there are no tabular files', () => { + const version = DatasetVersionMother.createReleased() + const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() + const fileDownloadSizes = [DatasetFileDownloadSizeMother.createOriginal()] + // const menuItemName = 'Download ZIP' + ' (' + formatFileSize(fileDownloadSizes[0].size) + ')' + cy.customMount( + + ) + cy.findByRole('button', { name: 'Access Dataset' }).should('exist') + cy.findByRole('button', { name: 'Access Dataset' }).click() + cy.findByText(/Download ZIP \(\d+(\.\d+)? KB\)/).should('exist') + }) + it('displays two dropdown options if there is at least one', () => { + const version = DatasetVersionMother.createReleased() + const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() + const fileDownloadSizes = [ + DatasetFileDownloadSizeMother.createOriginal(), + DatasetFileDownloadSizeMother.createArchival() + ] + cy.customMount( + + ) + cy.findByRole('button', { name: 'Access Dataset' }).should('exist') + cy.findByRole('button', { name: 'Access Dataset' }).click() + cy.findByText(/Original Format ZIP \(\d+(\.\d+)? KB\)/).should('exist') + cy.findByText(/Archive Format \(\.tab\) ZIP \(\d+(\.\d+)? KB\)/).should('exist') + }) }) From 4baf5362ea611f57057ed01eec02568094b92a75 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Mon, 20 Nov 2023 18:26:05 -0500 Subject: [PATCH 04/11] fix: remove console.log() --- .../dataset/dataset-action-buttons/DatasetActionButtons.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx b/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx index c95f2c008..1c5a41116 100644 --- a/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx +++ b/src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx @@ -14,7 +14,6 @@ interface DatasetActionButtonsProps { export function DatasetActionButtons({ dataset }: DatasetActionButtonsProps) { const { t } = useTranslation('dataset') - console.log(JSON.stringify(dataset.fileDownloadSizes)) return ( Date: Mon, 20 Nov 2023 21:47:44 -0500 Subject: [PATCH 05/11] fix: refactoring FileDownloadSize and DownloadOptions remove comments and console.log() --- src/dataset/domain/models/Dataset.ts | 12 +-- src/files/domain/models/File.ts | 17 ++++ .../access-dataset-menu/AccessDatasetMenu.tsx | 86 +++++++------------ .../dataset/domain/models/DatasetMother.ts | 25 +++--- .../AccessDatasetMenu.spec.tsx | 7 +- 5 files changed, 65 insertions(+), 82 deletions(-) diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts index a0970744c..75098b40d 100644 --- a/src/dataset/domain/models/Dataset.ts +++ b/src/dataset/domain/models/Dataset.ts @@ -1,4 +1,5 @@ import { AlertVariant } from '@iqss/dataverse-design-system/dist/components/alert/AlertVariant' +import { FileDownloadSize } from '../../../files/domain/models/File' export enum DatasetLabelSemanticMeaning { DATASET = 'dataset', @@ -280,17 +281,6 @@ export interface PrivateUrl { urlSnippet: string } -export enum FileDownloadSizeMode { - ALL = 'All', - ORIGINAL = 'Original', - ARCHIVAL = 'Archival' -} - -export interface FileDownloadSize { - size: number - fileDownloadSizeMode: FileDownloadSizeMode -} - export class Dataset { constructor( public readonly persistentId: string, diff --git a/src/files/domain/models/File.ts b/src/files/domain/models/File.ts index d4255cda8..f5a376b0c 100644 --- a/src/files/domain/models/File.ts +++ b/src/files/domain/models/File.ts @@ -61,6 +61,22 @@ export class FileSize { } } +export enum FileDownloadSizeMode { + ALL = 'All', + ORIGINAL = 'Original', + ARCHIVAL = 'Archival' +} + +export class FileDownloadSize extends FileSize { + constructor( + readonly value: number, + readonly unit: FileSizeUnit, + readonly mode: FileDownloadSizeMode + ) { + super(value, unit) + } +} + export interface FileAccess { restricted: boolean latestVersionRestricted: boolean @@ -113,6 +129,7 @@ export enum FileLabelType { CATEGORY = 'category', TAG = 'tag' } + export interface FileLabel { type: FileLabelType value: string diff --git a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx index 002dbd8c5..8498df9b7 100644 --- a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx +++ b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx @@ -1,12 +1,12 @@ import { DatasetPermissions, DatasetPublishingStatus, - DatasetVersion, - FileDownloadSize, - FileDownloadSizeMode + DatasetVersion } from '../../../../dataset/domain/models/Dataset' import { DropdownButton, DropdownButtonItem, DropdownHeader } from '@iqss/dataverse-design-system' import { useTranslation } from 'react-i18next' + +import { FileDownloadSize, FileDownloadSizeMode } from '../../../../files/domain/models/File' import { Download } from 'react-bootstrap-icons' interface AccessDatasetMenuProps { @@ -22,6 +22,7 @@ export function AccessDatasetMenu({ hasOneTabularFileAtLeast, fileDownloadSizes }: AccessDatasetMenuProps) { + console.log('fileDownloadSizes' + JSON.stringify(fileDownloadSizes)) if ( !permissions.canDownloadFiles || (version.publishingStatus === DatasetPublishingStatus.DEACCESSIONED && @@ -30,66 +31,36 @@ export function AccessDatasetMenu({ return <> } - function formatFileSize(bytes: number): string { - if (bytes < 1024) { - return `${bytes} B` - } else if (bytes < 1024 * 1024) { - return `${(bytes / 1024).toFixed(2)} KB` - } else if (bytes < 1024 * 1024 * 1024) { - return `${(bytes / 1024 / 1024).toFixed(2)} MB` - } else { - return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB` - } + function getFormattedFileSize(mode: FileDownloadSizeMode): string { + const foundSize = fileDownloadSizes && fileDownloadSizes.find((size) => size.mode === mode) + return foundSize ? foundSize.toString() : '' } const handleDownload = (type: FileDownloadSizeMode) => { //TODO: implement download feature - console.log(`Downloading ${type} zip file`) } - const renderDownloadOptions = (datasetContainsTabularFiles: boolean) => { - // Define the options based on whether the dataset contains tabular files - const downloadOptions: { - key: string - downloadType: FileDownloadSizeMode - translationKey: string - }[] = datasetContainsTabularFiles - ? [ - { - key: 'original', - downloadType: FileDownloadSizeMode.ORIGINAL, - translationKey: 'datasetActionButtons.accessDataset.downloadOriginalZip' - }, - { - key: 'archive', - downloadType: FileDownloadSizeMode.ARCHIVAL, - translationKey: 'datasetActionButtons.accessDataset.downloadArchiveZip' - } - ] - : [ - { - key: 'standard', - downloadType: FileDownloadSizeMode.ORIGINAL, - translationKey: 'datasetActionButtons.accessDataset.downloadZip' - } - ] - // Map the options to DropdownButtonItem components - return ( + interface DatasetDownloadOptionsProps { + datasetContainsTabularFiles: boolean + } + + const DatasetDownloadOptions = ({ datasetContainsTabularFiles }: DatasetDownloadOptionsProps) => { + return datasetContainsTabularFiles ? ( <> - - Download Options - - {downloadOptions.map((option) => ( - handleDownload(option.downloadType)}> - {t(option.translationKey)} ( - {formatFileSize( - fileDownloadSizes?.find((size) => size.fileDownloadSizeMode === option.downloadType) - ?.size || 0 - )} - ) - - ))} + handleDownload(FileDownloadSizeMode.ORIGINAL)}> + {t('datasetActionButtons.accessDataset.downloadOriginalZip')} ( + {getFormattedFileSize(FileDownloadSizeMode.ORIGINAL)}) + + handleDownload(FileDownloadSizeMode.ARCHIVAL)}> + {t('datasetActionButtons.accessDataset.downloadArchiveZip')} ( + {getFormattedFileSize(FileDownloadSizeMode.ARCHIVAL)}) ) + + ) : ( + handleDownload(FileDownloadSizeMode.ORIGINAL)}> + {t('datasetActionButtons.accessDataset.downloadZip')} ( + {getFormattedFileSize(FileDownloadSizeMode.ORIGINAL)}) ) + ) } @@ -100,7 +71,10 @@ export function AccessDatasetMenu({ title={t('datasetActionButtons.accessDataset.title')} asButtonGroup variant="primary"> - {renderDownloadOptions(hasOneTabularFileAtLeast)} + + Download Options + + ) } diff --git a/tests/component/dataset/domain/models/DatasetMother.ts b/tests/component/dataset/domain/models/DatasetMother.ts index 30d6adadb..3e6794c1d 100644 --- a/tests/component/dataset/domain/models/DatasetMother.ts +++ b/tests/component/dataset/domain/models/DatasetMother.ts @@ -10,10 +10,13 @@ import { DatasetPermissions, DatasetPublishingStatus, DatasetVersion, - FileDownloadSize, MetadataBlockName } from '../../../../../src/dataset/domain/models/Dataset' -import { FileDownloadSizeMode } from '@iqss/dataverse-client-javascript' +import { + FileDownloadSize, + FileDownloadSizeMode, + FileSizeUnit +} from '../../../../../src/files/domain/models/File' export class DatasetVersionMother { static create(props?: Partial): DatasetVersion { @@ -189,19 +192,19 @@ export class DatasetLockMother { export class DatasetFileDownloadSizeMother { static create(props?: Partial): FileDownloadSize { - return { - size: faker.datatype.number(), - fileDownloadSizeMode: faker.helpers.arrayElement(Object.values(FileDownloadSizeMode)), - ...props - } + return new FileDownloadSize( + props?.value ?? faker.datatype.number(), + props?.unit ?? faker.helpers.arrayElement(Object.values(FileSizeUnit)), + props?.mode ?? faker.helpers.arrayElement(Object.values(FileDownloadSizeMode)) + ) } static createArchival(): FileDownloadSize { - return this.create({ fileDownloadSizeMode: FileDownloadSizeMode.ARCHIVAL }) + return this.create({ mode: FileDownloadSizeMode.ARCHIVAL }) } static createOriginal(): FileDownloadSize { - return this.create({ fileDownloadSizeMode: FileDownloadSizeMode.ORIGINAL }) + return this.create({ mode: FileDownloadSizeMode.ORIGINAL }) } } @@ -463,8 +466,8 @@ export class DatasetMother { hasValidTermsOfAccess: true, hasOneTabularFileAtLeast: true, fileDownloadSizes: [ - { size: 219829, fileDownloadSizeMode: FileDownloadSizeMode.ORIGINAL }, - { size: 253629, fileDownloadSizeMode: FileDownloadSizeMode.ARCHIVAL } + new FileDownloadSize(21.98, FileSizeUnit.KILOBYTES, FileDownloadSizeMode.ORIGINAL), + new FileDownloadSize(21.98, FileSizeUnit.KILOBYTES, FileDownloadSizeMode.ARCHIVAL) ], isValid: true, ...props diff --git a/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx index 7132badfd..3a4a65804 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx @@ -85,7 +85,6 @@ describe('AccessDatasetMenu', () => { const version = DatasetVersionMother.createReleased() const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() const fileDownloadSizes = [DatasetFileDownloadSizeMother.createOriginal()] - // const menuItemName = 'Download ZIP' + ' (' + formatFileSize(fileDownloadSizes[0].size) + ')' cy.customMount( { ) cy.findByRole('button', { name: 'Access Dataset' }).should('exist') cy.findByRole('button', { name: 'Access Dataset' }).click() - cy.findByText(/Download ZIP \(\d+(\.\d+)? KB\)/).should('exist') + cy.findByText(/Download ZIP \(\d+(\.\d+)? (B|KB|MB|GB|TB|PB)\)/).should('exist') }) it('displays two dropdown options if there is at least one', () => { const version = DatasetVersionMother.createReleased() @@ -115,7 +114,7 @@ describe('AccessDatasetMenu', () => { ) cy.findByRole('button', { name: 'Access Dataset' }).should('exist') cy.findByRole('button', { name: 'Access Dataset' }).click() - cy.findByText(/Original Format ZIP \(\d+(\.\d+)? KB\)/).should('exist') - cy.findByText(/Archive Format \(\.tab\) ZIP \(\d+(\.\d+)? KB\)/).should('exist') + cy.findByText(/Original Format ZIP \(\d+(\.\d+)? (B|KB|MB|GB|TB|PB)\)/).should('exist') + cy.findByText(/Archive Format \(\.tab\) ZIP \(\d+(\.\d+)? (B|KB|MB|GB|TB|PB)\)/).should('exist') }) }) From f5a3260033a39c7b1d95b2a2933463f2eb7fc1cd Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Mon, 20 Nov 2023 21:51:02 -0500 Subject: [PATCH 06/11] fix: adding console.log() as placeholder --- .../access-dataset-menu/AccessDatasetMenu.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx index 8498df9b7..cc72f8bc5 100644 --- a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx +++ b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx @@ -38,6 +38,7 @@ export function AccessDatasetMenu({ const handleDownload = (type: FileDownloadSizeMode) => { //TODO: implement download feature + console.log('downloading file ' + type) } interface DatasetDownloadOptionsProps { From 29d8928e31c17a5cfd123d632e1c4058427e1178 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 21 Nov 2023 10:36:17 -0500 Subject: [PATCH 07/11] fix: remove console.log() --- .../access-dataset-menu/AccessDatasetMenu.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx index cc72f8bc5..9a991b0b2 100644 --- a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx +++ b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx @@ -22,7 +22,6 @@ export function AccessDatasetMenu({ hasOneTabularFileAtLeast, fileDownloadSizes }: AccessDatasetMenuProps) { - console.log('fileDownloadSizes' + JSON.stringify(fileDownloadSizes)) if ( !permissions.canDownloadFiles || (version.publishingStatus === DatasetPublishingStatus.DEACCESSIONED && From d0650951cd061f00bcd6cebaaec932305ab0e31d Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Mon, 11 Dec 2023 20:50:40 -0500 Subject: [PATCH 08/11] fix: remove extra parenthesis --- .../access-dataset-menu/AccessDatasetMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx index 9a991b0b2..0f4a7445b 100644 --- a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx +++ b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx @@ -53,7 +53,7 @@ export function AccessDatasetMenu({ handleDownload(FileDownloadSizeMode.ARCHIVAL)}> {t('datasetActionButtons.accessDataset.downloadArchiveZip')} ( - {getFormattedFileSize(FileDownloadSizeMode.ARCHIVAL)}) ) + {getFormattedFileSize(FileDownloadSizeMode.ARCHIVAL)}) ) : ( From 6a44d6f93c2352e10a9aec4188a610c80c2fd24c Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Mon, 11 Dec 2023 20:51:11 -0500 Subject: [PATCH 09/11] fix: add test data for fileDownloadSizes --- .../DatasetActionButtons.stories.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/stories/dataset/dataset-action-buttons/DatasetActionButtons.stories.tsx b/src/stories/dataset/dataset-action-buttons/DatasetActionButtons.stories.tsx index 9226ec599..87570d5de 100644 --- a/src/stories/dataset/dataset-action-buttons/DatasetActionButtons.stories.tsx +++ b/src/stories/dataset/dataset-action-buttons/DatasetActionButtons.stories.tsx @@ -48,6 +48,10 @@ export const WithNoDatasetPermissions: Story = { permissions: DatasetPermissionsMother.createWithNoDatasetPermissions(), version: DatasetVersionMother.createDraftAsLatestVersion(), hasValidTermsOfAccess: true, + fileDownloadSizes: [ + DatasetFileDownloadSizeMother.createOriginal(), + DatasetFileDownloadSizeMother.createArchival() + ], isValid: true, isReleased: true })} @@ -66,6 +70,10 @@ export const WithUpdateAndNoPublishDatasetPermissions: Story = { }), version: DatasetVersionMother.createDraftAsLatestVersion(), hasValidTermsOfAccess: true, + fileDownloadSizes: [ + DatasetFileDownloadSizeMother.createOriginal(), + DatasetFileDownloadSizeMother.createArchival() + ], isValid: true, isReleased: true })} From 0cf51765ac1c07469ae1c53edde5030b3f502858 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 12 Dec 2023 08:05:49 -0500 Subject: [PATCH 10/11] fix: Add tests to AccessDatasetMenu.spec.tsx --- .../AccessDatasetMenu.spec.tsx | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx index 3a4a65804..f085f51d2 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx @@ -6,6 +6,54 @@ import { } from '../../../../dataset/domain/models/DatasetMother' describe('AccessDatasetMenu', () => { + it('returns the correct file size string', () => { + const version = DatasetVersionMother.createReleased() + const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() + const originalFileDownloadSize = DatasetFileDownloadSizeMother.createOriginal() + const archivalDownloadSize = DatasetFileDownloadSizeMother.createArchival() + const fileDownloadSizes = [originalFileDownloadSize, archivalDownloadSize] + cy.customMount( + + ) + cy.findByRole('button', { name: 'Access Dataset' }).should('exist') + cy.findByRole('button', { name: 'Access Dataset' }).click() + + cy.contains(originalFileDownloadSize.value.toString()).should('be.visible') + cy.contains(archivalDownloadSize.value.toString()).should('be.visible') + cy.contains(originalFileDownloadSize.unit.toString()).should('be.visible') + cy.contains(archivalDownloadSize.unit.toString()).should('be.visible') + }) + + it('logs the correct message when handleDownload is called', () => { + const version = DatasetVersionMother.createReleased() + const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() + const fileDownloadSizes = [ + DatasetFileDownloadSizeMother.createOriginal(), + DatasetFileDownloadSizeMother.createArchival() + ] + cy.customMount( + + ) + const consoleLogStub = cy.stub(console, 'log').as('consoleLog') + cy.findByRole('button', { name: 'Access Dataset' }).should('exist') + cy.findByRole('button', { name: 'Access Dataset' }).click() + cy.contains('Original Format ZIP').click() + cy.get('@consoleLog').should('have.been.calledWith', 'downloading file Original') + cy.findByRole('button', { name: 'Access Dataset' }).click() + cy.contains('Archive Format').click() + cy.get('@consoleLog').should('have.been.calledWith', 'downloading file Archival') + }) + it('renders the AccessDatasetMenu if the user has download files permissions and the dataset is not deaccessioned', () => { const version = DatasetVersionMother.createReleased() const permissions = DatasetPermissionsMother.createWithFilesDownloadAllowed() From 249a61993998994f8a5c3f243d1df265590ef4cf Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 12 Dec 2023 09:19:42 -0500 Subject: [PATCH 11/11] fix: remove extra parenthesis --- .../access-dataset-menu/AccessDatasetMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx index 0f4a7445b..23a52d5a5 100644 --- a/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx +++ b/src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx @@ -59,7 +59,7 @@ export function AccessDatasetMenu({ ) : ( handleDownload(FileDownloadSizeMode.ORIGINAL)}> {t('datasetActionButtons.accessDataset.downloadZip')} ( - {getFormattedFileSize(FileDownloadSizeMode.ORIGINAL)}) ) + {getFormattedFileSize(FileDownloadSizeMode.ORIGINAL)}) ) }