Skip to content

Commit

Permalink
Merge pull request #173 from IQSS/feature/168-integration-file-counts
Browse files Browse the repository at this point in the history
Merging this into feature/167-integration-dataset-page-filters because filters won't work without files count integration
  • Loading branch information
MellyGray authored Sep 22, 2023
2 parents 4d93c0b + 791e990 commit 0cc585e
Show file tree
Hide file tree
Showing 39 changed files with 418 additions and 172 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
"dependencies": {
"@faker-js/faker": "7.6.0",
"@iqss/dataverse-client-javascript": "2.0.0-pr82.33671e5",
"@iqss/dataverse-client-javascript": "2.0.0-pr88.9d7ced6",
"@iqss/dataverse-design-system": "*",
"@istanbuljs/nyc-config-typescript": "1.0.2",
"@tanstack/react-table": "8.9.2",
Expand Down
32 changes: 28 additions & 4 deletions src/files/domain/models/FileCriteria.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,47 @@ export class FileCriteria {
) {}

withSortBy(sortBy: FileSortByOption): FileCriteria {
return new FileCriteria(sortBy, this.filterByType, this.filterByAccess, this.filterByTag)
return new FileCriteria(
sortBy,
this.filterByType,
this.filterByAccess,
this.filterByTag,
this.searchText
)
}

withFilterByType(filterByType: string | undefined): FileCriteria {
const newFilterByType = filterByType === undefined ? undefined : new FileType(filterByType)

return new FileCriteria(this.sortBy, newFilterByType, this.filterByAccess, this.filterByTag)
return new FileCriteria(
this.sortBy,
newFilterByType,
this.filterByAccess,
this.filterByTag,
this.searchText
)
}

withFilterByAccess(filterByAccess: FileAccessOption | undefined): FileCriteria {
return new FileCriteria(this.sortBy, this.filterByType, filterByAccess, this.filterByTag)
return new FileCriteria(
this.sortBy,
this.filterByType,
filterByAccess,
this.filterByTag,
this.searchText
)
}

withFilterByTag(filterByTag: string | undefined): FileCriteria {
const newFilterByTag = filterByTag === undefined ? undefined : new FileTag(filterByTag)

return new FileCriteria(this.sortBy, this.filterByType, this.filterByAccess, newFilterByTag)
return new FileCriteria(
this.sortBy,
this.filterByType,
this.filterByAccess,
newFilterByTag,
this.searchText
)
}

withSearchText(searchText: string | undefined): FileCriteria {
Expand Down
4 changes: 2 additions & 2 deletions src/files/domain/repositories/FileRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export interface FileRepository {
paginationInfo?: FilePaginationInfo,
criteria?: FileCriteria
) => Promise<File[]>
getCountInfoByDatasetPersistentId: (
getFilesCountInfoByDatasetPersistentId: (
datasetPersistentId: string,
datasetVersion: DatasetVersion
) => Promise<FilesCountInfo>
getFileUserPermissionsById: (id: number) => Promise<FileUserPermissions>
getUserPermissionsById: (id: number) => Promise<FileUserPermissions>
}
4 changes: 2 additions & 2 deletions src/files/domain/useCases/checkFileDownloadPermission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export async function checkFileDownloadPermission(
file: File
): Promise<boolean> {
if (file.version.publishingStatus === FilePublishingStatus.DEACCESSIONED) {
return fileRepository.getFileUserPermissionsById(file.id).then((permissions) => {
return fileRepository.getUserPermissionsById(file.id).then((permissions) => {
return permissions.canEditDataset
})
}
Expand All @@ -16,7 +16,7 @@ export async function checkFileDownloadPermission(
return true
}

return fileRepository.getFileUserPermissionsById(file.id).then((permissions) => {
return fileRepository.getUserPermissionsById(file.id).then((permissions) => {
return permissions.canDownloadFile
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export async function checkFileEditDatasetPermission(
fileRepository: FileRepository,
file: File
): Promise<boolean> {
return fileRepository.getFileUserPermissionsById(file.id).then((permissions) => {
return fileRepository.getUserPermissionsById(file.id).then((permissions) => {
return permissions.canEditDataset
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export async function getFilesCountInfoByDatasetPersistentId(
datasetVersion: DatasetVersion
): Promise<FilesCountInfo> {
return fileRepository
.getCountInfoByDatasetPersistentId(datasetPersistentId, datasetVersion)
.getFilesCountInfoByDatasetPersistentId(datasetPersistentId, datasetVersion)
.catch((error: Error) => {
throw new Error(error.message)
})
Expand Down
24 changes: 13 additions & 11 deletions src/files/infrastructure/FileJSDataverseRepository.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { FileRepository } from '../domain/repositories/FileRepository'
import { File, FilePublishingStatus } from '../domain/models/File'
import { FilesCountInfo } from '../domain/models/FilesCountInfo'
import { FilesCountInfoMother } from '../../../tests/component/files/domain/models/FilesCountInfoMother'
import { FilePaginationInfo } from '../domain/models/FilePaginationInfo'
import { FileUserPermissions } from '../domain/models/FileUserPermissions'
import {
getDatasetFileCounts,
getDatasetFiles,
getFileDownloadCount,
getFileUserPermissions,
Expand Down Expand Up @@ -62,21 +62,23 @@ export class FileJSDataverseRepository implements FileRepository {
return Promise.resolve(0)
}

getCountInfoByDatasetPersistentId(
// eslint-disable-next-line unused-imports/no-unused-vars
getFilesCountInfoByDatasetPersistentId(
datasetPersistentId: string,
// eslint-disable-next-line unused-imports/no-unused-vars
datasetVersion: DatasetVersion
): Promise<FilesCountInfo> {
// TODO - implement using js-dataverse
return new Promise((resolve) => {
setTimeout(() => {
resolve(FilesCountInfoMother.create())
}, 1000)
})
// TODO - Take into account the FileCriteria https://github.com/IQSS/dataverse-frontend/issues/172
return getDatasetFileCounts
.execute(datasetPersistentId, datasetVersion.toString())
.then((jsFilesCountInfo) => {
return JSFileMapper.toFilesCountInfo(jsFilesCountInfo)
})
.catch((error: WriteError) => {
console.error('Error getting files count info from Dataverse', error)
throw new Error(error.message)
})
}

getFileUserPermissionsById(id: number): Promise<FileUserPermissions> {
getUserPermissionsById(id: number): Promise<FileUserPermissions> {
return getFileUserPermissions
.execute(id)
.then((jsFileUserPermissions) =>
Expand Down
63 changes: 62 additions & 1 deletion src/files/infrastructure/mappers/JSFileMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,22 @@ import {
import {
File as JSFile,
FileEmbargo as JSFileEmbargo,
FileChecksum as JSFileChecksum
FileChecksum as JSFileChecksum,
FileCounts as JSFilesCountInfo,
FileContentTypeCount as JSFileContentTypeCount,
FileCategoryNameCount as JSFileCategoryNameCount,
FileAccessStatusCount as JSFileAccessStatusCount,
FileAccessStatus as JSFileAccessStatus
} from '@iqss/dataverse-client-javascript'
import { DatasetPublishingStatus, DatasetVersion } from '../../../dataset/domain/models/Dataset'
import { FileUserPermissions } from '../../domain/models/FileUserPermissions'
import {
FileAccessCount,
FilesCountInfo,
FileTagCount,
FileTypeCount
} from '../../domain/models/FilesCountInfo'
import { FileAccessOption, FileTag } from '../../domain/models/FileCriteria'

export class JSFileMapper {
static toFile(jsFile: JSFile, datasetVersion: DatasetVersion): File {
Expand Down Expand Up @@ -169,4 +181,53 @@ export class JSFileMapper {
static toFileDescription(jsFileDescription?: string): string | undefined {
return jsFileDescription
}

static toFilesCountInfo(jsFilesCountInfo: JSFilesCountInfo): FilesCountInfo {
return {
total: jsFilesCountInfo.total,
perFileType: jsFilesCountInfo.perContentType.map((jsFileContentTypeCount) =>
JSFileMapper.toFileTypeCount(jsFileContentTypeCount)
),
perFileTag: jsFilesCountInfo.perCategoryName.map((jsFileCategoryNameCount) =>
JSFileMapper.toFileTagCount(jsFileCategoryNameCount)
),
perAccess: jsFilesCountInfo.perAccessStatus.map((jsFileAccessStatusCount) =>
JSFileMapper.toFileAccessCount(jsFileAccessStatusCount)
)
}
}

static toFileTypeCount(jsFileContentTypeCount: JSFileContentTypeCount): FileTypeCount {
return {
type: new FileType(jsFileContentTypeCount.contentType),
count: jsFileContentTypeCount.count
}
}

static toFileTagCount(jsFileCategoryNameCount: JSFileCategoryNameCount): FileTagCount {
return {
tag: new FileTag(jsFileCategoryNameCount.categoryName),
count: jsFileCategoryNameCount.count
}
}

static toFileAccessCount(jsFileAccessStatusCount: JSFileAccessStatusCount): FileAccessCount {
return {
access: JSFileMapper.toFileAccessOption(jsFileAccessStatusCount.accessStatus),
count: jsFileAccessStatusCount.count
}
}

static toFileAccessOption(jsFileAccessStatus: JSFileAccessStatus): FileAccessOption {
switch (jsFileAccessStatus) {
case JSFileAccessStatus.RESTRICTED:
return FileAccessOption.RESTRICTED
case JSFileAccessStatus.PUBLIC:
return FileAccessOption.PUBLIC
case JSFileAccessStatus.EMBARGOED:
return FileAccessOption.EMBARGOED
case JSFileAccessStatus.EMBARGOED_RESTRICTED:
return FileAccessOption.EMBARGOED_RESTRICTED
}
}
}
3 changes: 2 additions & 1 deletion src/sections/dataset/dataset-files/DatasetFiles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function DatasetFiles({
filesRepository,
datasetPersistentId,
datasetVersion,
setPaginationInfo,
paginationInfo,
criteria
)
Expand All @@ -40,7 +41,7 @@ export function DatasetFiles({
<FilesPagination
page={paginationInfo.page}
pageSize={paginationInfo.pageSize}
total={filesCountInfo.total}
total={paginationInfo.totalFiles}
onPaginationInfoChange={setPaginationInfo}
/>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import { DatasetUploadFilesButton } from '../dataset-upload-files-button/Dataset
interface FileCriteriaInputsProps {
criteria: FileCriteria
onCriteriaChange: (criteria: FileCriteria) => void
filesCountInfo: FilesCountInfo
filesCountInfo: FilesCountInfo | undefined
}
const MINIMUM_FILES_TO_SHOW_CRITERIA_INPUTS = 2
export function FileCriteriaForm({
criteria,
onCriteriaChange,
filesCountInfo
}: FileCriteriaInputsProps) {
if (filesCountInfo.total < MINIMUM_FILES_TO_SHOW_CRITERIA_INPUTS) {
if (!filesCountInfo || filesCountInfo.total < MINIMUM_FILES_TO_SHOW_CRITERIA_INPUTS) {
return <></>
}
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button, Form } from '@iqss/dataverse-design-system'
import { Search } from 'react-bootstrap-icons'
import { FileCriteria } from '../../../../files/domain/models/FileCriteria'
import { ChangeEvent, useState, KeyboardEvent } from 'react'
import { ChangeEvent, useState, KeyboardEvent, MouseEvent } from 'react'
import { useTranslation } from 'react-i18next'

interface FileCriteriaSearchTextProps {
Expand All @@ -18,15 +18,19 @@ export function FileCriteriaSearchText({
const updatedSearchText = event.target.value
setSearchText(updatedSearchText)
}
const handleSubmitSearch = () => {
onCriteriaChange(criteria.withSearchText(searchText))
const handleButtonClick = (event: MouseEvent<HTMLButtonElement>) => {
event.preventDefault()
handleSubmitSearch()
}
const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter') {
event.preventDefault()
handleSubmitSearch()
}
}
const handleSubmitSearch = () => {
onCriteriaChange(criteria.withSearchText(searchText))
}

return (
<Form.Group controlId="search-files">
Expand All @@ -43,7 +47,7 @@ export function FileCriteriaSearchText({
variant="secondary"
icon={<Search />}
aria-label={t('criteria.searchText.submit')}
onClick={handleSubmitSearch}
onClick={handleButtonClick}
/>
</Form.InputGroup>
</Form.Group>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export function FilesPagination({
pageSize,
total
}: FilesPaginationProps) {
console.log('FilesPagination', page, pageSize, total)
const [paginationInfo, setPaginationInfo] = useState<FilePaginationInfo>(
new FilePaginationInfo(page, pageSize, total)
)
Expand All @@ -36,7 +37,7 @@ export function FilesPagination({

useEffect(() => {
onPaginationInfoChange(paginationInfo)
}, [paginationInfo])
}, [paginationInfo.pageSize, paginationInfo.page])

useEffect(() => {
setPaginationInfo(paginationInfo.withTotal(total))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { FileInfoCell } from './file-info/file-info-cell/FileInfoCell'
import { FileInfoHeader } from './file-info/FileInfoHeader'
import { FileActionsHeader } from './file-actions/FileActionsHeader'
import { FileActionsCell } from './file-actions/file-actions-cell/FileActionsCell'
import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo'

export const columns: ColumnDef<File>[] = [
export const createColumnsDefinition = (paginationInfo: FilePaginationInfo): ColumnDef<File>[] => [
{
id: 'select',
header: ({ table }) => (
Expand All @@ -31,13 +32,7 @@ export const columns: ColumnDef<File>[] = [
)
},
{
header: ({ table }) => (
<FileInfoHeader
pageCount={table.getPageCount()}
pageSize={table.getState().pagination.pageSize}
pageIndex={table.getState().pagination.pageIndex}
/>
),
header: () => <FileInfoHeader paginationInfo={paginationInfo} />,
accessorKey: 'info',
cell: (props) => <FileInfoCell file={props.row.original} />
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import styles from '../FilesTable.module.scss'
import { FilePaginationInfo } from '../../../../../files/domain/models/FilePaginationInfo'

interface FileInfoHeaderProps {
pageCount: number
pageIndex: number
pageSize: number
paginationInfo: FilePaginationInfo
}

export function FileInfoHeader({ pageCount, pageIndex, pageSize }: FileInfoHeaderProps) {
const startIndex = pageIndex * pageSize + 1
const fileCount = pageCount * pageSize
const endIndex = Math.min(startIndex + pageSize - 1, fileCount)
export function FileInfoHeader({ paginationInfo }: FileInfoHeaderProps) {
const fileCount = paginationInfo.totalFiles
const startIndex = (paginationInfo.page - 1) * paginationInfo.pageSize + 1
const endIndex = Math.min(startIndex + paginationInfo.pageSize - 1, fileCount)

if (fileCount === 0) {
return <></>
Expand Down
Loading

0 comments on commit 0cc585e

Please sign in to comment.