Skip to content

Commit

Permalink
Merge pull request #271 from IQSS/feature/262-file-labels-section-of-…
Browse files Browse the repository at this point in the history
…the-file-page

262 - File labels section of the File page
  • Loading branch information
ekraffmiller authored Jan 8, 2024
2 parents 4f9728e + 9b1c321 commit b5f65e2
Show file tree
Hide file tree
Showing 17 changed files with 207 additions and 95 deletions.
20 changes: 19 additions & 1 deletion public/locales/en/file.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
}
18 changes: 0 additions & 18 deletions public/locales/en/files.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
6 changes: 6 additions & 0 deletions src/files/domain/models/File.ts
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,16 @@ function AccessStatusIcon({
sessionUserHasFileDownloadPermission: boolean
restricted: boolean
}) {
const { t } = useTranslation('files')
const { t } = useTranslation('file')
if (restricted) {
if (sessionUserHasFileDownloadPermission) {
return (
<UnlockFill
title={t('table.fileAccess.restrictedWithAccess.icon')}
className={styles.success}
/>
<UnlockFill title={t('fileAccess.restrictedWithAccess.icon')} className={styles.success} />
)
}
return (
<LockFill
role="img"
title={t('table.fileAccess.restricted.icon')}
className={styles.danger}
/>
)
return <LockFill role="img" title={t('fileAccess.restricted.icon')} className={styles.danger} />
}
return <Globe role="img" title={t('table.fileAccess.public.icon')} className={styles.success} />
return <Globe role="img" title={t('fileAccess.public.icon')} className={styles.success} />
}

function AccessStatusText({
Expand All @@ -63,7 +54,7 @@ function AccessStatusText({
file: FilePreview
sessionUserHasFileDownloadPermission: boolean
}) {
const { t } = useTranslation('files')
const { t } = useTranslation('file')
const getAccessStatus = () => {
if (file.isActivelyEmbargoed) {
return 'embargoed'
Expand All @@ -89,7 +80,7 @@ function AccessStatusText({
: 'danger'
]
}>
{t(`table.fileAccess.${getAccessStatus()}.name`)}
{t(`fileAccess.${getAccessStatus()}.name`)}
</span>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,8 @@
max-width: 390px;
}

%restricted-icon {
.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;
}
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -24,7 +24,12 @@ export function FileThumbnail({ file }: FileThumbnailProps) {
) : (
<FileThumbnailIcon type={file.type} />
)}
<FileThumbnailRestrictedIcon file={file} />
<div className={styles['restricted-icon']}>
<FileAccessRestrictedIcon
restricted={file.access.restricted}
canDownloadFile={sessionUserHasFileDownloadPermission}
/>
</div>
</div>
)
}

This file was deleted.

10 changes: 10 additions & 0 deletions src/sections/file/File.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
}

.subtext {
margin-bottom: 10px;
color: $dv-subtext-color;
}

Expand All @@ -15,4 +16,13 @@
.separation-line {
margin: 1em 0;
border-bottom: 1px solid #dee2e6;
}

.labels {
display: flex;
align-items: center;
}

.restricted-icon {
margin-right: 6px;
}
17 changes: 15 additions & 2 deletions src/sections/file/File.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { useFile } from './useFile'
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
Expand All @@ -33,9 +35,20 @@ export function File({ repository, id }: FileProps) {
<article>
<header className={styles.header}>
<h1>{file.name}</h1>
<span className={styles.subtext}>
<p className={styles.subtext}>
{t('subtext', { datasetTitle: file.datasetVersion.title })}
</span>
</p>
<div className={styles.labels}>
{file.restricted && (
<div className={styles['restricted-icon']}>
<FileAccessRestrictedIcon
restricted={file.restricted}
canDownloadFile={file.permissions.canDownloadFile}
/>
</div>
)}
<DatasetLabels labels={file.datasetVersion.labels} />
</div>
</header>
<div className={styles.container}>
<Tabs defaultActiveKey="metadata">
Expand Down
7 changes: 5 additions & 2 deletions src/sections/file/FileSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -8,8 +8,11 @@ export function FileSkeleton() {
<article data-testid="file-skeleton">
<header className={styles.header}>
<h1>
<Skeleton width="30%" />
<Skeleton width="15%" />
</h1>
<p className={styles.subtext}>
<Skeleton width="20%" />
</p>
<Skeleton width="10%" />
</header>
<div className={styles.container}>
Expand Down
18 changes: 18 additions & 0 deletions src/sections/file/file-access/FileAccessInfoIcon.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module";

%restricted-icon {
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;
}
38 changes: 38 additions & 0 deletions src/sections/file/file-access/FileAccessRestrictedIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
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 {
restricted: boolean
canDownloadFile: boolean
}
export function FileAccessRestrictedIcon({ restricted, canDownloadFile }: FileAccessInfoIconProps) {
const { t } = useTranslation('file')

if (!restricted) {
return <></>
}

if (canDownloadFile) {
return (
<span className={styles['restricted-icon-restrictedWithAccess']}>
<Tooltip
overlay={`${t('fileAccess.title')}: ${t('fileAccess.restrictedWithAccess.name')}`}
placement="top">
<UnlockFill role="img" title={t('fileAccess.restrictedWithAccess.icon')} />
</Tooltip>
</span>
)
}

return (
<span className={styles['restricted-icon-restricted']}>
<Tooltip
overlay={`${t('fileAccess.title')}: ${t('fileAccess.restricted.name')}`}
placement="top">
<LockFill role="img" title={t('fileAccess.restricted.icon')} />
</Tooltip>
</span>
)
}
14 changes: 14 additions & 0 deletions src/stories/files/File.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof File> = {
title: 'Pages/File',
Expand All @@ -19,6 +20,19 @@ export const Default: Story = {
render: () => <File repository={new FileMockRepository()} id={56} />
}

export const Restricted: Story = {
render: () => <File repository={new FileMockRepository(FileMother.createRestricted())} id={56} />
}

export const RestrictedWithAccessGranted: Story = {
render: () => (
<File
repository={new FileMockRepository(FileMother.createRestrictedWithAccessGranted())}
id={56}
/>
)
}

export const Loading: Story = {
render: () => <File repository={new FileMockLoadingRepository()} id={56} />
}
Expand Down
4 changes: 3 additions & 1 deletion src/stories/files/FileMockRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -67,7 +69,7 @@ export class FileMockRepository implements FileRepository {
getById(id: number): Promise<File | undefined> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(FileMother.createRealistic())
resolve(this.fileMock ?? FileMother.createRealistic())
}, 1000)
})
}
Expand Down
Loading

0 comments on commit b5f65e2

Please sign in to comment.