Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/IQSS/dataverse-frontend
Browse files Browse the repository at this point in the history
…into feature/244-integration-download-all-files
  • Loading branch information
MellyGray committed Dec 15, 2023
2 parents 3728ba3 + c3c00ce commit ac81d82
Show file tree
Hide file tree
Showing 17 changed files with 385 additions and 187 deletions.
4 changes: 3 additions & 1 deletion src/files/domain/repositories/FileRepository.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { File } from '../models/File'
import { File, FileDownloadMode } from '../models/File'
import { FileCriteria } from '../models/FileCriteria'
import { FilesCountInfo } from '../models/FilesCountInfo'
import { FilePaginationInfo } from '../models/FilePaginationInfo'
Expand All @@ -23,4 +23,6 @@ export interface FileRepository {
criteria?: FileCriteria
) => Promise<number>
getUserPermissionsById: (id: number) => Promise<FileUserPermissions>
getMultipleFileDownloadUrl: (ids: number[], downloadMode: FileDownloadMode) => string
getFileDownloadUrl: (id: number, downloadMode: FileDownloadMode) => string
}
15 changes: 15 additions & 0 deletions src/files/domain/useCases/getMultipleFileDownloadUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { FileRepository } from '../repositories/FileRepository'
import { FileDownloadMode } from '../models/File'

const ONLY_ONE_FILE = 1
export function getMultipleFileDownloadUrl(
fileRepository: FileRepository,
ids: number[],
downloadMode: FileDownloadMode
): string {
if (ids.length === ONLY_ONE_FILE) {
return fileRepository.getFileDownloadUrl(ids[0], downloadMode)
}

return fileRepository.getMultipleFileDownloadUrl(ids, downloadMode)
}
21 changes: 16 additions & 5 deletions src/files/infrastructure/FileJSDataverseRepository.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { FileRepository } from '../domain/repositories/FileRepository'
import { File } from '../domain/models/File'
import { File, FileDownloadMode } from '../domain/models/File'
import { FilesCountInfo } from '../domain/models/FilesCountInfo'
import { FilePaginationInfo } from '../domain/models/FilePaginationInfo'
import { FileUserPermissions } from '../domain/models/FileUserPermissions'
import {
File as JSFile,
FileDataTable as JSFileTabularData,
FileDownloadSizeMode,
getDatasetFileCounts,
getDatasetFiles,
getDatasetFilesTotalDownloadSize,
getFileDataTables,
getFileDownloadCount,
getFileUserPermissions,
ReadError,
File as JSFile,
getFileDataTables,
FileDataTable as JSFileTabularData
ReadError
} from '@iqss/dataverse-client-javascript'
import { FileCriteria } from '../domain/models/FileCriteria'
import { DomainFileMapper } from './mappers/DomainFileMapper'
Expand Down Expand Up @@ -155,4 +155,15 @@ export class FileJSDataverseRepository implements FileRepository {
throw new Error(error.message)
})
}

getMultipleFileDownloadUrl(ids: number[], downloadMode: FileDownloadMode): string {
return `/api/access/datafiles/${ids.join(',')}?format=${downloadMode}`
}

getFileDownloadUrl(id: number, downloadMode: FileDownloadMode): string {
if (downloadMode === FileDownloadMode.ORIGINAL) {
return `/api/access/datafile/${id}?format=${downloadMode}`
}
return `/api/access/datafile/${id}`
}
}
29 changes: 16 additions & 13 deletions src/sections/dataset/DatasetFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { SettingJSDataverseRepository } from '../../settings/infrastructure/Sett
import { FilePermissionsProvider } from '../file/file-permissions/FilePermissionsProvider'
import { SettingsProvider } from '../settings/SettingsProvider'
import { DatasetProvider } from './DatasetProvider'
import { MultipleFileDownloadProvider } from '../file/multiple-file-download/MultipleFileDownloadProvider'
import { NotImplementedModalProvider } from '../not-implemented/NotImplementedModalProvider'
import { AlertProvider } from '../alerts/AlertProvider'

Expand All @@ -22,19 +23,21 @@ const settingRepository = new SettingJSDataverseRepository()
export class DatasetFactory {
static create(): ReactElement {
return (
<FilePermissionsProvider repository={fileRepository}>
<SettingsProvider repository={settingRepository}>
<NotImplementedModalProvider>
<MetadataBlockInfoProvider repository={metadataBlockInfoRepository}>
<AnonymizedProvider>
<AlertProvider>
<DatasetWithSearchParams />
</AlertProvider>
</AnonymizedProvider>
</MetadataBlockInfoProvider>
</NotImplementedModalProvider>
</SettingsProvider>
</FilePermissionsProvider>
<MultipleFileDownloadProvider repository={fileRepository}>
<FilePermissionsProvider repository={fileRepository}>
<SettingsProvider repository={settingRepository}>
<NotImplementedModalProvider>
<MetadataBlockInfoProvider repository={metadataBlockInfoRepository}>
<AnonymizedProvider>
<AlertProvider>
<DatasetWithSearchParams />
</AlertProvider>
</AnonymizedProvider>
</MetadataBlockInfoProvider>
</NotImplementedModalProvider>
</SettingsProvider>
</FilePermissionsProvider>
</MultipleFileDownloadProvider>
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
} from '../../../../dataset/domain/models/Dataset'
import { DropdownButton, DropdownButtonItem, DropdownHeader } from '@iqss/dataverse-design-system'
import { useTranslation } from 'react-i18next'

import { FileDownloadSize, FileDownloadMode } from '../../../../files/domain/models/File'
import { Download } from 'react-bootstrap-icons'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { File } from '../../../../../../files/domain/models/File'
import { File, FileDownloadMode } from '../../../../../../files/domain/models/File'
import { useDataset } from '../../../../DatasetContext'
import { Button, DropdownButton, DropdownButtonItem } from '@iqss/dataverse-design-system'
import { Download } from 'react-bootstrap-icons'
import styles from './DownloadFilesButton.module.scss'
import { useTranslation } from 'react-i18next'
import { FileSelection } from '../../row-selection/useFileSelection'
import { NoSelectedFilesModal } from '../no-selected-files-modal/NoSelectedFilesModal'
import { useState } from 'react'
import { useNotImplementedModal } from '../../../../../not-implemented/NotImplementedModalContext'
import { MouseEvent, useState } from 'react'
import { useMultipleFileDownload } from '../../../../../file/multiple-file-download/MultipleFileDownloadContext'

interface DownloadFilesButtonProps {
files: File[]
Expand All @@ -21,27 +21,31 @@ export function DownloadFilesButton({ files, fileSelection }: DownloadFilesButto
const { t } = useTranslation('files')
const { dataset } = useDataset()
const [showNoFilesSelectedModal, setShowNoFilesSelectedModal] = useState(false)
const handleClick = () => {
// TODO - Implement upload files
showModal()
const { getMultipleFileDownloadUrl } = useMultipleFileDownload()
const fileSelectionCount = Object.keys(fileSelection).length
const onClick = (event: MouseEvent<HTMLButtonElement>) => {
if (fileSelectionCount === SELECTED_FILES_EMPTY) {
event.preventDefault()
setShowNoFilesSelectedModal(true)
}
}
const { showModal } = useNotImplementedModal()
const getDownloadUrl = (downloadMode: FileDownloadMode): string => {
const allFilesSelected = Object.values(fileSelection).some((file) => file === undefined)
if (allFilesSelected) {
return dataset ? dataset.downloadUrls[downloadMode] : ''
}

return getMultipleFileDownloadUrl(getFileIdsFromSelection(fileSelection), downloadMode)
}

if (
files.length < MINIMUM_FILES_COUNT_TO_SHOW_DOWNLOAD_FILES_BUTTON ||
!dataset?.permissions.canDownloadFiles
) {
return <></>
}

const onClick = () => {
if (Object.keys(fileSelection).length === SELECTED_FILES_EMPTY) {
setShowNoFilesSelectedModal(true)
} else {
handleClick()
}
}

if (files.some((file) => file.isTabularData)) {
if (dataset.hasOneTabularFileAtLeast) {
return (
<>
<DropdownButton
Expand All @@ -50,10 +54,10 @@ export function DownloadFilesButton({ files, fileSelection }: DownloadFilesButto
title={t('actions.downloadFiles.title')}
variant="secondary"
withSpacing>
<DropdownButtonItem onClick={onClick}>
<DropdownButtonItem onClick={onClick} href={getDownloadUrl(FileDownloadMode.ORIGINAL)}>
{t('actions.downloadFiles.options.original')}
</DropdownButtonItem>
<DropdownButtonItem onClick={onClick}>
<DropdownButtonItem onClick={onClick} href={getDownloadUrl(FileDownloadMode.ARCHIVAL)}>
{t('actions.downloadFiles.options.archival')}
</DropdownButtonItem>
</DropdownButton>
Expand All @@ -67,17 +71,25 @@ export function DownloadFilesButton({ files, fileSelection }: DownloadFilesButto

return (
<>
<Button
variant="secondary"
icon={<Download className={styles.icon} />}
withSpacing
onClick={onClick}>
{t('actions.downloadFiles.title')}
</Button>
<a href={getDownloadUrl(FileDownloadMode.ORIGINAL)}>
<Button
variant="secondary"
icon={<Download className={styles.icon} />}
withSpacing
onClick={onClick}>
{t('actions.downloadFiles.title')}
</Button>
</a>
<NoSelectedFilesModal
show={showNoFilesSelectedModal}
handleClose={() => setShowNoFilesSelectedModal(false)}
/>
</>
)
}

const getFileIdsFromSelection = (fileSelection: FileSelection): number[] => {
return Object.values(fileSelection)
.filter((file): file is File => file !== undefined)
.map((file) => file.id)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createContext, useContext } from 'react'
import { FileDownloadMode } from '../../../files/domain/models/File'

interface MultipleFileDownloadContextProps {
getMultipleFileDownloadUrl: (ids: number[], downloadMode: FileDownloadMode) => string
}

export const MultipleFileDownloadContext = createContext<MultipleFileDownloadContextProps>({
getMultipleFileDownloadUrl: () => {
console.error('Not implemented')
return ''
}
})

export const useMultipleFileDownload = () => useContext(MultipleFileDownloadContext)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { PropsWithChildren } from 'react'
import { FileRepository } from '../../../files/domain/repositories/FileRepository'
import { MultipleFileDownloadContext } from './MultipleFileDownloadContext'
import { FileDownloadMode } from '../../../files/domain/models/File'
import { getMultipleFileDownloadUrl } from '../../../files/domain/useCases/getMultipleFileDownloadUrl'

interface MultipleFileDownloadProviderProps {
repository: FileRepository
}

export function MultipleFileDownloadProvider({
repository,
children
}: PropsWithChildren<MultipleFileDownloadProviderProps>) {
const getDownloadUrl = (ids: number[], downloadMode: FileDownloadMode) => {
return getMultipleFileDownloadUrl(repository, ids, downloadMode)
}

return (
<MultipleFileDownloadContext.Provider value={{ getMultipleFileDownloadUrl: getDownloadUrl }}>
{children}
</MultipleFileDownloadContext.Provider>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function mockedSettingResponse<T>(name: SettingName): Setting<T> {
case SettingName.ZIP_DOWNLOAD_LIMIT:
return {
name: SettingName.ZIP_DOWNLOAD_LIMIT,
value: new ZipDownloadLimit(1, FileSizeUnit.BYTES)
value: new ZipDownloadLimit(1, FileSizeUnit.TERABYTES)
} as Setting<T>
case SettingName.ALLOWED_EXTERNAL_STATUSES:
return {
Expand Down
30 changes: 3 additions & 27 deletions src/stories/files/FileMockLoadingRepository.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { FileRepository } from '../../files/domain/repositories/FileRepository'
import { File } from '../../files/domain/models/File'
import { FilesCountInfo } from '../../files/domain/models/FilesCountInfo'
import { FileUserPermissions } from '../../files/domain/models/FileUserPermissions'
import { FileUserPermissionsMother } from '../../../tests/component/files/domain/models/FileUserPermissionsMother'
import { DatasetVersion } from '../../dataset/domain/models/Dataset'
import { FileCriteria } from '../../files/domain/models/FileCriteria'
import { FileMockRepository } from './FileMockRepository'

export class FileMockLoadingRepository implements FileRepository {
export class FileMockLoadingRepository extends FileMockRepository implements FileRepository {
getAllByDatasetPersistentId(
// eslint-disable-next-line unused-imports/no-unused-vars
datasetPersistentId: string,
Expand All @@ -26,35 +25,12 @@ export class FileMockLoadingRepository implements FileRepository {
// eslint-disable-next-line unused-imports/no-unused-vars
datasetVersion: DatasetVersion,
// eslint-disable-next-line unused-imports/no-unused-vars
criteria: FileCriteria
criteria?: FileCriteria
): Promise<FilesCountInfo> {
return new Promise(() => {
setTimeout(() => {
// Do nothing
}, 1000)
})
}
// eslint-disable-next-line unused-imports/no-unused-vars
getUserPermissionsById(id: number): Promise<FileUserPermissions> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(FileUserPermissionsMother.create())
}, 1000)
})
}

getFilesTotalDownloadSizeByDatasetPersistentId(
// eslint-disable-next-line unused-imports/no-unused-vars
datasetPersistentId: string,
// eslint-disable-next-line unused-imports/no-unused-vars
datasetVersion: DatasetVersion,
// eslint-disable-next-line unused-imports/no-unused-vars
criteria?: FileCriteria
): Promise<number> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(19900)
}, 1000)
})
}
}
14 changes: 2 additions & 12 deletions src/stories/files/FileMockNoDataRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import { FileRepository } from '../../files/domain/repositories/FileRepository'
import { File } from '../../files/domain/models/File'
import { FilesCountInfo } from '../../files/domain/models/FilesCountInfo'
import { FilesCountInfoMother } from '../../../tests/component/files/domain/models/FilesCountInfoMother'
import { FileUserPermissions } from '../../files/domain/models/FileUserPermissions'
import { FileUserPermissionsMother } from '../../../tests/component/files/domain/models/FileUserPermissionsMother'
import { DatasetVersion } from '../../dataset/domain/models/Dataset'
import { FileCriteria } from '../../files/domain/models/FileCriteria'
import { FileMockRepository } from './FileMockRepository'

export class FileMockNoDataRepository implements FileRepository {
export class FileMockNoDataRepository extends FileMockRepository implements FileRepository {
getAllByDatasetPersistentId(
// eslint-disable-next-line unused-imports/no-unused-vars
datasetPersistentId: string,
Expand Down Expand Up @@ -48,13 +47,4 @@ export class FileMockNoDataRepository implements FileRepository {
}, 1000)
})
}

// eslint-disable-next-line unused-imports/no-unused-vars
getUserPermissionsById(id: number): Promise<FileUserPermissions> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(FileUserPermissionsMother.create())
}, 1000)
})
}
}
Loading

0 comments on commit ac81d82

Please sign in to comment.