Skip to content

Commit

Permalink
Merge pull request IQSS#459 from IQSS/feat/455-collection-card
Browse files Browse the repository at this point in the history
feat: CollectionCard for Collection Page
  • Loading branch information
GPortas authored Aug 28, 2024
2 parents 69ce4d9 + f021547 commit 7b59288
Show file tree
Hide file tree
Showing 12 changed files with 379 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/collection/domain/models/CollectionPreview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface CollectionPreview {
id: string
name: string
isReleased: boolean
releaseOrCreateDate: Date
parentCollectionId?: string
parentCollectionName?: string
description?: string
affiliation?: string
thumbnail?: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
@use 'sass:color';
@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module";
@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/typography.module";

.container {
margin: 6px 0;
padding: 4px 10px;
border: 1px solid $dv-collection-border-color;
}

.header {
display: flex;
justify-content: space-between;
}

.title {
display: flex;gap: 8px;
}

.icon {
margin-top: 2px;
color: $dv-collection-border-color;
font-size: 1.3em;
line-height: 1.1;

> div >span {
margin-right: 0;
}
}

.thumbnail {
width: 48px;
margin: 8px 12px 6px 0;
font-size: 2.8em;

img {
vertical-align: top;
}
}

.info {
display: flex;
color: $dv-subtext-color;
}

.card-info-container {
display: flex;
font-size: $dv-font-size-sm;
}

.description {
display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical;
flex-direction: column;
width: 100%;
overflow: hidden;
color: black;
}

.date {
color: $dv-subtext-color;

}

.affiliation {
color: $dv-subtext-color;
}

.badge {
margin-right: 0.5em;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { CollectionCardHeader } from './CollectionCardHeader'
import { CollectionCardThumbnail } from './CollectionCardThumbnail'
import { CollectionCardInfo } from './CollectionCardInfo'
import { Stack } from '@iqss/dataverse-design-system'
import { CollectionPreview } from '../../../../collection/domain/models/CollectionPreview'
import styles from './CollectionCard.module.scss'

interface CollectionCardProps {
collectionPreview: CollectionPreview
}

export function CollectionCard({ collectionPreview }: CollectionCardProps) {
return (
<article className={styles.container}>
<CollectionCardHeader collectionPreview={collectionPreview} />
<div className={styles.info}>
<Stack direction={'horizontal'} gap={3}>
<CollectionCardThumbnail collectionPreview={collectionPreview} />
<CollectionCardInfo collectionPreview={collectionPreview} />
</Stack>
</div>
</article>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { LinkToPage } from '../../../shared/link-to-page/LinkToPage'
import { Route } from '../../../Route.enum'
import { CollectionPreview } from '../../../../collection/domain/models/CollectionPreview'
import styles from './CollectionCard.module.scss'
import { Badge, Icon, IconName } from '@iqss/dataverse-design-system'
import { DvObjectType } from '../../../../shared/hierarchy/domain/models/UpwardHierarchyNode'

interface CollectionCardHeaderProps {
collectionPreview: CollectionPreview
}

export function CollectionCardHeader({ collectionPreview }: CollectionCardHeaderProps) {
return (
<>
<div className={styles.header}>
<div className={styles.title}>
<LinkToPage
type={DvObjectType.COLLECTION}
page={Route.COLLECTIONS}
searchParams={{ id: collectionPreview.id.toString() }}>
{collectionPreview.name}
</LinkToPage>
{collectionPreview.affiliation && (
<span className={styles.affiliation}> ({collectionPreview.affiliation})</span>
)}
{!collectionPreview.isReleased && (
<div className={styles.badge}>
<Badge variant="warning">Unpublished</Badge>
</div>
)}
</div>

<div className={styles.icon}>
<Icon name={IconName.COLLECTION} />
</div>
</div>
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {
DatasetLabel,
DatasetLabelSemanticMeaning,
DatasetLabelValue
} from '../../../../dataset/domain/models/Dataset'
export class CollectionCardHelper {
static getLabel(isReleased: boolean) {
const labels: DatasetLabel[] = []

if (!isReleased) {
labels.push(
new DatasetLabel(DatasetLabelSemanticMeaning.WARNING, DatasetLabelValue.UNPUBLISHED)
)
}
return labels
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import styles from './CollectionCard.module.scss'
import { DateHelper } from '../../../../shared/helpers/DateHelper'
import { Stack } from '@iqss/dataverse-design-system'
import { LinkToPage } from '../../../shared/link-to-page/LinkToPage'
import { Route } from '../../../Route.enum'
import { CollectionPreview } from '../../../../collection/domain/models/CollectionPreview'
import { DvObjectType } from '../../../../shared/hierarchy/domain/models/UpwardHierarchyNode'

interface CollectionCardInfoProps {
collectionPreview: CollectionPreview
}

export function CollectionCardInfo({ collectionPreview }: CollectionCardInfoProps) {
return (
<div className={styles['card-info-container']}>
<Stack gap={1}>
<Stack direction="horizontal" gap={2}>
<span className={styles.date}>
{DateHelper.toDisplayFormat(collectionPreview.releaseOrCreateDate)}
</span>
{collectionPreview.parentCollectionName && collectionPreview.parentCollectionId && (
<LinkToPage
type={DvObjectType.COLLECTION}
page={Route.COLLECTIONS}
searchParams={{ id: collectionPreview.parentCollectionId.toString() }}>
{collectionPreview.parentCollectionName}
</LinkToPage>
)}
</Stack>

<p className={styles.description}>{collectionPreview.description}</p>
</Stack>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import styles from './CollectionCard.module.scss'
import { LinkToPage } from '../../../shared/link-to-page/LinkToPage'
import { Route } from '../../../Route.enum'
import { Icon, IconName } from '@iqss/dataverse-design-system'
import { CollectionPreview } from '../../../../collection/domain/models/CollectionPreview'
import { DvObjectType } from '../../../../shared/hierarchy/domain/models/UpwardHierarchyNode'

interface CollectionCardCardThumbnailProps {
collectionPreview: CollectionPreview
}

export function CollectionCardThumbnail({ collectionPreview }: CollectionCardCardThumbnailProps) {
return (
<div className={styles.thumbnail}>
<LinkToPage
type={DvObjectType.COLLECTION}
page={Route.COLLECTIONS}
searchParams={{ id: collectionPreview.id.toString() }}>
{collectionPreview.thumbnail ? (
<img
className={styles['preview-image']}
src={collectionPreview.thumbnail}
alt={collectionPreview.name}
/>
) : (
<div className={styles.icon}>
<Icon name={IconName.COLLECTION} />
</div>
)}
</LinkToPage>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { FileChecksum } from '../../../dataset/dataset-files/files-table/file-in
import { FileTabularData } from '../../../dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileTabularData'
import { FileCardHelper } from './FileCardHelper'
import { DvObjectType } from '../../../../shared/hierarchy/domain/models/UpwardHierarchyNode'
import { FileLabels } from '../../../file/file-labels/FileLabels'

interface FileCardInfoProps {
filePreview: FilePreview
Expand Down Expand Up @@ -37,6 +38,7 @@ export function FileCardInfo({ filePreview, persistentId }: FileCardInfoProps) {
<FileChecksum checksum={filePreview.metadata.checksum} />
</Stack>
</span>
<FileLabels labels={filePreview.metadata.labels}></FileLabels>
<p className={styles.description}>{filePreview.metadata.description}</p>
</Stack>
</div>
Expand Down
37 changes: 37 additions & 0 deletions src/stories/collection/datasets-list/CollectionCard.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Meta, StoryObj } from '@storybook/react'
import { WithI18next } from '../../WithI18next'
import { CollectionCard } from '../../../sections/collection/datasets-list/collection-card/CollectionCard'
import { CollectionPreviewMother } from '../../../../tests/component/collection/domain/models/CollectionPreviewMother'
import { FakerHelper } from '../../../../tests/component/shared/FakerHelper'

const meta: Meta<typeof CollectionCard> = {
title: 'Sections/Collection Page/CollectionCard',
component: CollectionCard,
decorators: [WithI18next]
}

export default meta
type Story = StoryObj<typeof CollectionCard>

export const Default: Story = {
render: () => <CollectionCard collectionPreview={CollectionPreviewMother.createRealistic()} />
}

export const RequiredOnly: Story = {
render: () => (
<CollectionCard collectionPreview={CollectionPreviewMother.createWithOnlyRequiredFields()} />
)
}
export const WithLongDescription: Story = {
render: () => {
const collectionPreview = CollectionPreviewMother.create({
description: FakerHelper.paragraph(20)
})

return <CollectionCard collectionPreview={collectionPreview} />
}
}

export const Unpublished: Story = {
render: () => <CollectionCard collectionPreview={CollectionPreviewMother.createUnpublished()} />
}
19 changes: 18 additions & 1 deletion src/stories/collection/datasets-list/FileCard.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import { Meta, StoryObj } from '@storybook/react'
import { WithI18next } from '../../WithI18next'
import { FileCard } from '../../../sections/collection/datasets-list/file-card/FileCard'
import { FilePreviewMother } from '../../../../tests/component/files/domain/models/FilePreviewMother'
import { FileMetadataMother } from '../../../../tests/component/files/domain/models/FileMetadataMother'
import {
FileLabelMother,
FileMetadataMother
} from '../../../../tests/component/files/domain/models/FileMetadataMother'
import { FakerHelper } from '../../../../tests/component/shared/FakerHelper'
import { DatasetPublishingStatus } from '../../../dataset/domain/models/Dataset'

const meta: Meta<typeof FileCard> = {
title: 'Sections/Collection Page/FileCard',
Expand Down Expand Up @@ -46,3 +50,16 @@ export const ReleasedWithDraft: Story = {
<FileCard persistentId={'testid'} filePreview={FilePreviewMother.createReleasedWithDraft()} />
)
}
export const WithAllLabels: Story = {
render: () => {
const filePreview = FilePreviewMother.createDefault({
datasetPublishingStatus: DatasetPublishingStatus.DRAFT,
someDatasetVersionHasBeenReleased: false,
metadata: FileMetadataMother.createDefault({
description: FakerHelper.paragraph(5),
labels: FileLabelMother.createMany(4)
})
})
return <FileCard persistentId={'testid'} filePreview={filePreview} />
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { faker } from '@faker-js/faker'
import { FakerHelper } from '../../../shared/FakerHelper'
import { CollectionPreview } from '../../../../../src/collection/domain/models/CollectionPreview'

export class CollectionPreviewMother {
static create(props?: Partial<CollectionPreview>): CollectionPreview {
return {
id: faker.datatype.uuid(),
name: faker.lorem.words(3),
isReleased: faker.datatype.boolean(),
releaseOrCreateDate: faker.date.recent(),
parentCollectionId: faker.datatype.boolean() ? faker.datatype.uuid() : undefined,
parentCollectionName: faker.datatype.boolean() ? faker.lorem.words(3) : undefined,
description: faker.datatype.boolean()
? `${faker.lorem.paragraph()} **${faker.lorem.sentence()}** ${faker.lorem.paragraph()}`
: undefined,
affiliation: faker.datatype.boolean() ? faker.lorem.words(3) : undefined,
...props
}
}

static createRealistic(): CollectionPreview {
return CollectionPreviewMother.create({
id: 'science',
isReleased: true,
name: 'Scientific Research Collection',
releaseOrCreateDate: new Date('2021-01-01'),
parentCollectionId: 'parentId',
parentCollectionName: 'University Parent Collection',
description: 'We do all the science.',
affiliation: 'Scientific Research University'
})
}

static createWithOnlyRequiredFields(props?: Partial<CollectionPreview>): CollectionPreview {
return CollectionPreviewMother.create({
id: faker.datatype.uuid(),
name: FakerHelper.collectionName(),
isReleased: faker.datatype.boolean(),
affiliation: undefined,
description: undefined,
...props
})
}

static createComplete(): CollectionPreview {
return CollectionPreviewMother.create({
id: faker.datatype.uuid(),
isReleased: faker.datatype.boolean(),
name: FakerHelper.collectionName(),
parentCollectionId: faker.datatype.uuid(),
parentCollectionName: faker.lorem.words(3),
releaseOrCreateDate: FakerHelper.pastDate(),
description: FakerHelper.paragraph(),
affiliation: FakerHelper.affiliation()
})
}
static createUnpublished(): CollectionPreview {
return CollectionPreviewMother.createWithOnlyRequiredFields({
isReleased: false,
affiliation: FakerHelper.affiliation()
})
}
static createWithDescription(): CollectionPreview {
return CollectionPreviewMother.createWithOnlyRequiredFields({
description: FakerHelper.paragraph()
})
}

static createWithAffiliation(): CollectionPreview {
return CollectionPreviewMother.createWithOnlyRequiredFields({
affiliation: FakerHelper.affiliation()
})
}
}
Loading

0 comments on commit 7b59288

Please sign in to comment.