Skip to content

Commit

Permalink
Merge pull request #169 from IQSS/feature/134-integration-files-table…
Browse files Browse the repository at this point in the history
…-display-data

134 - Files table UI [1/2] - Integration display data
  • Loading branch information
kcondon authored Sep 22, 2023
2 parents c008e4d + ec7e914 commit a220c4f
Show file tree
Hide file tree
Showing 76 changed files with 1,683 additions and 505 deletions.
4 changes: 2 additions & 2 deletions dev.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
FROM node:19.6.1-alpine as BUILD_IMAGE

RUN apk --no-cache add python3 make g++

WORKDIR /usr/src/app/packages/design-system
COPY ./packages/design-system ./
RUN npm install
RUN npm run build

WORKDIR /usr/src/app
COPY package.json ./
COPY package-lock.json ./
COPY .npmrc ./
RUN npm uninstall --save-dev lerna
RUN npm install

FROM node:19.6.1-alpine
Expand Down
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-pr80.378cc1e",
"@iqss/dataverse-client-javascript": "2.0.0-pr80.3e0c21e",
"@iqss/dataverse-design-system": "*",
"@istanbuljs/nyc-config-typescript": "1.0.2",
"@tanstack/react-table": "8.9.2",
Expand Down
3 changes: 2 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { ApiConfig } from '@iqss/dataverse-client-javascript/dist/core'
import { Router } from './Router'
import { SessionProvider } from './sections/session/SessionProvider'
import { UserJSDataverseRepository } from './users/infrastructure/repositories/UserJSDataverseRepository'
import { DataverseApiAuthMechanism } from '@iqss/dataverse-client-javascript/dist/core/infra/repositories/ApiConfig'

const VITE_DATAVERSE_BACKEND_URL = (import.meta.env.VITE_DATAVERSE_BACKEND_URL as string) ?? ''
if (VITE_DATAVERSE_BACKEND_URL) {
ApiConfig.init(`${VITE_DATAVERSE_BACKEND_URL}/api/v1`)
ApiConfig.init(`${VITE_DATAVERSE_BACKEND_URL}/api/v1`, DataverseApiAuthMechanism.SESSION_COOKIE)
} else {
throw Error('VITE_DATAVERSE_BACKEND_URL environment variable should be specified.')
}
Expand Down
31 changes: 20 additions & 11 deletions src/dataset/domain/models/Dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,22 +197,31 @@ const defaultLicense: DatasetLicense = {
iconUri: 'https://licensebuttons.net/p/zero/1.0/88x31.png'
}

export enum DatasetStatus {
export enum DatasetPublishingStatus {
RELEASED = 'released',
DRAFT = 'draft',
DEACCESSIONED = 'deaccessioned',
EMBARGOED = 'embargoed',
IN_REVIEW = 'inReview'
}

export enum DatasetNonNumericVersion {
LATEST = ':latest',
DRAFT = ':draft'
}

export class DatasetVersion {
constructor(
public readonly majorNumber: number,
public readonly minorNumber: number,
public readonly status: DatasetStatus
public readonly id: number,
public readonly publishingStatus: DatasetPublishingStatus,
public readonly majorNumber?: number,
public readonly minorNumber?: number
) {}

toString(): string {
toString(): string | DatasetNonNumericVersion {
if (this.majorNumber === undefined || this.minorNumber === undefined) {
return DatasetNonNumericVersion.DRAFT
}
return `${this.majorNumber}.${this.minorNumber}`
}
}
Expand Down Expand Up @@ -252,39 +261,39 @@ export class Dataset {
}

private withStatusLabel(): void {
if (this.version.status === DatasetStatus.DRAFT) {
if (this.version.publishingStatus === DatasetPublishingStatus.DRAFT) {
this.labels.push(
new DatasetLabel(DatasetLabelSemanticMeaning.DATASET, DatasetLabelValue.DRAFT)
)
}

if (this.version.status !== DatasetStatus.RELEASED) {
if (this.version.publishingStatus !== DatasetPublishingStatus.RELEASED) {
this.labels.push(
new DatasetLabel(DatasetLabelSemanticMeaning.WARNING, DatasetLabelValue.UNPUBLISHED)
)
}

if (this.version.status === DatasetStatus.DEACCESSIONED) {
if (this.version.publishingStatus === DatasetPublishingStatus.DEACCESSIONED) {
this.labels.push(
new DatasetLabel(DatasetLabelSemanticMeaning.DANGER, DatasetLabelValue.DEACCESSIONED)
)
}

if (this.version.status === DatasetStatus.EMBARGOED) {
if (this.version.publishingStatus === DatasetPublishingStatus.EMBARGOED) {
this.labels.push(
new DatasetLabel(DatasetLabelSemanticMeaning.DATASET, DatasetLabelValue.EMBARGOED)
)
}

if (this.version.status === DatasetStatus.IN_REVIEW) {
if (this.version.publishingStatus === DatasetPublishingStatus.IN_REVIEW) {
this.labels.push(
new DatasetLabel(DatasetLabelSemanticMeaning.SUCCESS, DatasetLabelValue.IN_REVIEW)
)
}
}

private withVersionLabel(): void {
if (this.version.status === DatasetStatus.RELEASED) {
if (this.version.publishingStatus === DatasetPublishingStatus.RELEASED) {
this.labels.push(
new DatasetLabel(DatasetLabelSemanticMeaning.FILE, `Version ${this.version.toString()}`)
)
Expand Down
24 changes: 14 additions & 10 deletions src/dataset/infrastructure/mappers/JSDatasetMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { DatasetVersionState as JSDatasetVersionState } from '@iqss/dataverse-client-javascript/dist/datasets/domain/models/Dataset'
import {
Dataset,
DatasetStatus,
DatasetPublishingStatus,
MetadataBlockName,
DatasetMetadataBlock,
DatasetVersion,
Expand All @@ -20,7 +20,7 @@ export class JSDatasetMapper {
static toDataset(jsDataset: JSDataset, citation: string, summaryFieldsNames: string[]): Dataset {
return new Dataset.Builder(
jsDataset.persistentId,
JSDatasetMapper.toVersion(jsDataset.versionInfo),
JSDatasetMapper.toVersion(jsDataset.versionId, jsDataset.versionInfo),
citation,
JSDatasetMapper.toSummaryFields(jsDataset.metadataBlocks, summaryFieldsNames),
jsDataset.license,
Expand All @@ -33,24 +33,28 @@ export class JSDatasetMapper {
).build()
}

static toVersion(jsDatasetVersionInfo: JSDatasetVersionInfo): DatasetVersion {
static toVersion(
jDatasetVersionId: number,
jsDatasetVersionInfo: JSDatasetVersionInfo
): DatasetVersion {
return new DatasetVersion(
jDatasetVersionId,
JSDatasetMapper.toStatus(jsDatasetVersionInfo.state),
jsDatasetVersionInfo.majorNumber,
jsDatasetVersionInfo.minorNumber,
JSDatasetMapper.toStatus(jsDatasetVersionInfo.state)
jsDatasetVersionInfo.minorNumber
)
}

static toStatus(jsDatasetVersionState: JSDatasetVersionState): DatasetStatus {
static toStatus(jsDatasetVersionState: JSDatasetVersionState): DatasetPublishingStatus {
switch (jsDatasetVersionState) {
case JSDatasetVersionState.DRAFT:
return DatasetStatus.DRAFT
return DatasetPublishingStatus.DRAFT
case JSDatasetVersionState.DEACCESSIONED:
return DatasetStatus.DEACCESSIONED
return DatasetPublishingStatus.DEACCESSIONED
case JSDatasetVersionState.RELEASED:
return DatasetStatus.RELEASED
return DatasetPublishingStatus.RELEASED
default:
return DatasetStatus.RELEASED
return DatasetPublishingStatus.DRAFT
}
}

Expand Down
89 changes: 60 additions & 29 deletions src/files/domain/models/File.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,56 @@ export enum FileSizeUnit {
}

export class FileSize {
constructor(readonly value: number, readonly unit: FileSizeUnit) {}
static readonly multiplier = {
[FileSizeUnit.BYTES]: 1,
[FileSizeUnit.KILOBYTES]: 1024,
[FileSizeUnit.MEGABYTES]: 1024 ** 2,
[FileSizeUnit.GIGABYTES]: 1024 ** 3,
[FileSizeUnit.TERABYTES]: 1024 ** 4,
[FileSizeUnit.PETABYTES]: 1024 ** 5
}

constructor(readonly value: number, readonly unit: FileSizeUnit) {
;[this.value, this.unit] = this.convertToLargestUnit(value, unit)
}

toString(): string {
return `${this.value} ${this.unit}`
const formattedValue =
this.value % 1 === 0 ? this.value.toFixed(0) : (Math.round(this.value * 10) / 10).toString()
return `${formattedValue} ${this.unit}`
}

toBytes(): number {
const multiplier = {
[FileSizeUnit.BYTES]: 1,
[FileSizeUnit.KILOBYTES]: 1024,
[FileSizeUnit.MEGABYTES]: 1024 ** 2,
[FileSizeUnit.GIGABYTES]: 1024 ** 3,
[FileSizeUnit.TERABYTES]: 1024 ** 4,
[FileSizeUnit.PETABYTES]: 1024 ** 5
return this.value * FileSize.multiplier[this.unit]
}

private convertToLargestUnit(value: number, unit: FileSizeUnit): [number, FileSizeUnit] {
let convertedValue = value
let convertedUnit = unit

while (convertedValue >= 1024 && convertedUnit !== FileSizeUnit.PETABYTES) {
convertedValue /= 1024
convertedUnit = this.getNextUnit(convertedUnit)
}

return this.value * multiplier[this.unit]
return [convertedValue, convertedUnit]
}

private getNextUnit(unit: FileSizeUnit): FileSizeUnit {
switch (unit) {
case FileSizeUnit.BYTES:
return FileSizeUnit.KILOBYTES
case FileSizeUnit.KILOBYTES:
return FileSizeUnit.MEGABYTES
case FileSizeUnit.MEGABYTES:
return FileSizeUnit.GIGABYTES
case FileSizeUnit.GIGABYTES:
return FileSizeUnit.TERABYTES
case FileSizeUnit.TERABYTES:
return FileSizeUnit.PETABYTES
default:
return unit
}
}
}

Expand All @@ -35,22 +68,15 @@ export interface FileAccess {
requested: boolean
}

export enum FileStatus {
export enum FilePublishingStatus {
DRAFT = 'draft',
RELEASED = 'released',
DEACCESSIONED = 'deaccessioned'
}

export class FileVersion {
constructor(
public readonly majorNumber: number,
public readonly minorNumber: number,
public readonly status: FileStatus
) {}

toString(): string {
return `${this.majorNumber}.${this.minorNumber}`
}
export interface FileVersion {
number: number
publishingStatus: FilePublishingStatus
}

export enum FileDateType {
Expand All @@ -66,7 +92,7 @@ export enum FileVersionNotNumber {

export interface FileDate {
type: FileDateType
date: string
date: Date
}

export class FileEmbargo {
Expand Down Expand Up @@ -105,6 +131,11 @@ export class FileType {
}
}

export interface FileChecksum {
algorithm: string
value: string
}

export enum FileIngestStatus {
NONE = 'none',
IN_PROGRESS = 'inProgress',
Expand All @@ -119,27 +150,27 @@ export interface FileIngest {

export class File {
constructor(
readonly id: string,
readonly id: number,
readonly version: FileVersion,
readonly name: string,
readonly access: FileAccess,
readonly type: FileType,
readonly size: FileSize,
readonly date: FileDate,
readonly downloads: number,
public downloadCount: number,
readonly labels: FileLabel[],
public readonly isDeleted: boolean,
public readonly ingest: FileIngest,
readonly checksum?: string,
readonly embargo?: FileEmbargo,
readonly checksum?: FileChecksum,
readonly thumbnail?: string,
readonly directory?: string,
readonly description?: string,
readonly embargo?: FileEmbargo,
readonly tabularData?: FileTabularData,
readonly thumbnail?: string
readonly description?: string
) {}

getLink(): string {
return `/file?id=${this.id}&version=${this.version.toString()}`
return `/file?id=${this.id}&version=${this.version.number}`
}

get isActivelyEmbargoed(): boolean {
Expand Down
2 changes: 1 addition & 1 deletion src/files/domain/models/FileUserPermissions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface FileUserPermissions {
fileId: string
fileId: number
canDownloadFile: boolean
canEditDataset: boolean
}
Expand Down
7 changes: 4 additions & 3 deletions src/files/domain/repositories/FileRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ import { FileCriteria } from '../models/FileCriteria'
import { FilesCountInfo } from '../models/FilesCountInfo'
import { FilePaginationInfo } from '../models/FilePaginationInfo'
import { FileUserPermissions } from '../models/FileUserPermissions'
import { DatasetVersion } from '../../../dataset/domain/models/Dataset'

export interface FileRepository {
getAllByDatasetPersistentId: (
datasetPersistentId: string,
version?: string,
datasetVersion: DatasetVersion,
paginationInfo?: FilePaginationInfo,
criteria?: FileCriteria
) => Promise<File[]>
getCountInfoByDatasetPersistentId: (
datasetPersistentId: string,
version?: string
datasetVersion: DatasetVersion
) => Promise<FilesCountInfo>
getFileUserPermissionsById: (id: string) => Promise<FileUserPermissions>
getFileUserPermissionsById: (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
@@ -1,11 +1,11 @@
import { FileRepository } from '../repositories/FileRepository'
import { File, FileStatus } from '../models/File'
import { File, FilePublishingStatus } from '../models/File'

export async function checkFileDownloadPermission(
fileRepository: FileRepository,
file: File
): Promise<boolean> {
if (file.version.status === FileStatus.DEACCESSIONED) {
if (file.version.publishingStatus === FilePublishingStatus.DEACCESSIONED) {
return fileRepository.getFileUserPermissionsById(file.id).then((permissions) => {
return permissions.canEditDataset
})
Expand Down
Loading

0 comments on commit a220c4f

Please sign in to comment.