diff --git a/src/dataset/domain/models/DatasetPreview.ts b/src/dataset/domain/models/DatasetPreview.ts index 9acae6281..849ba4691 100644 --- a/src/dataset/domain/models/DatasetPreview.ts +++ b/src/dataset/domain/models/DatasetPreview.ts @@ -1,4 +1,22 @@ -export interface DatasetPreview { - persistentId: string - title: string +import { DatasetLabel, DatasetVersion } from './Dataset' + +export class DatasetPreview { + constructor( + public persistentId: string, + public title: string, + public version: DatasetVersion, + public citation: string, + public labels: DatasetLabel[], + public isDeaccessioned: boolean, + public releaseOrCreateDate: Date, + public description: string, + public thumbnail?: string + ) {} + + get abbreviatedDescription(): string { + if (this.description.length > 280) { + return `${this.description.substring(0, 280)}...` + } + return this.description + } } diff --git a/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts b/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts index c062faa8d..59ea3c23a 100644 --- a/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts +++ b/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts @@ -23,7 +23,7 @@ export class DatasetJSDataverseRepository implements DatasetRepository { // TODO - Implement using the js-dataverse-client return new Promise((resolve) => { setTimeout(() => { - resolve(DatasetPreviewMother.createMany(200)) + resolve(DatasetPreviewMother.createManyRealistic(10)) }, 1000) }) } diff --git a/src/sections/dataset/dataset-citation/CitationThumbnail.tsx b/src/sections/dataset/dataset-citation/CitationThumbnail.tsx deleted file mode 100644 index 57cda7c95..000000000 --- a/src/sections/dataset/dataset-citation/CitationThumbnail.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { DatasetPublishingStatus } from '../../../dataset/domain/models/Dataset' -import styles from './DatasetCitation.module.scss' -import { Icon, IconName } from '@iqss/dataverse-design-system' - -interface CitationThumbnailProps { - thumbnail?: string - title: string - publishingStatus: DatasetPublishingStatus -} - -export function CitationThumbnail({ thumbnail, title, publishingStatus }: CitationThumbnailProps) { - if (thumbnail && publishingStatus !== DatasetPublishingStatus.DEACCESSIONED) { - return {title} - } - - return ( -
- -
- ) -} diff --git a/src/sections/dataset/dataset-citation/DatasetCitation.module.scss b/src/sections/dataset/dataset-citation/DatasetCitation.module.scss index 4e3ecc9ea..4dfa0ae50 100644 --- a/src/sections/dataset/dataset-citation/DatasetCitation.module.scss +++ b/src/sections/dataset/dataset-citation/DatasetCitation.module.scss @@ -17,20 +17,11 @@ min-height: 150px; border: 1px solid $dv-danger-color; } -.icon { - color: #428BCA; - font-size: 7.5em; - line-height: 1.1; -} - -.preview-image { - width: 100%; - max-width: 140px; - height: auto; - max-height: 140px; -} - .row { margin-right: -15px; margin-left: -15px; +} + +.thumbnail { + font-size: 7.5em; } \ No newline at end of file diff --git a/src/sections/dataset/dataset-citation/DatasetCitation.tsx b/src/sections/dataset/dataset-citation/DatasetCitation.tsx index 9b523c7c7..9f1450830 100644 --- a/src/sections/dataset/dataset-citation/DatasetCitation.tsx +++ b/src/sections/dataset/dataset-citation/DatasetCitation.tsx @@ -1,9 +1,10 @@ -import { Col, QuestionMarkTooltip, Row } from '@iqss/dataverse-design-system' +import { Col, Row } from '@iqss/dataverse-design-system' import styles from './DatasetCitation.module.scss' import { useTranslation } from 'react-i18next' import { DatasetPublishingStatus, DatasetVersion } from '../../../dataset/domain/models/Dataset' -import parse from 'html-react-parser' -import { CitationThumbnail } from './CitationThumbnail' +import { DatasetThumbnail } from '../dataset-thumbnail/DatasetThumbnail' +import { CitationDescription } from '../../shared/citation/CitationDescription' +import { DatasetCitationTooltip } from './DatasetCitationTooltip' interface DatasetCitationProps { thumbnail?: string @@ -23,16 +24,19 @@ export function DatasetCitation({ thumbnail, title, citation, version }: Dataset : styles.container }> - - + - + + + +
@@ -52,35 +56,3 @@ export function DatasetCitation({ thumbnail, title, citation, version }: Dataset ) } - -function CitationDescription({ citation, version }: { citation: string; version: DatasetVersion }) { - const citationAsReactElement = parse(citation) - - return ( - - {citationAsReactElement} - - - ) -} - -interface CitationDatasetStatusProps { - status: DatasetPublishingStatus -} - -function CitationTooltip({ status }: CitationDatasetStatusProps) { - const { t } = useTranslation('dataset') - - if (status !== DatasetPublishingStatus.RELEASED) { - return ( - <> - {' '} - - - ) - } - return <> -} diff --git a/src/sections/dataset/dataset-citation/DatasetCitationTooltip.tsx b/src/sections/dataset/dataset-citation/DatasetCitationTooltip.tsx new file mode 100644 index 000000000..0ae1676b1 --- /dev/null +++ b/src/sections/dataset/dataset-citation/DatasetCitationTooltip.tsx @@ -0,0 +1,24 @@ +import { DatasetPublishingStatus } from '../../../dataset/domain/models/Dataset' +import { useTranslation } from 'react-i18next' +import { QuestionMarkTooltip } from '@iqss/dataverse-design-system' + +interface DatasetCitationTooltipProps { + status: DatasetPublishingStatus +} + +export function DatasetCitationTooltip({ status }: DatasetCitationTooltipProps) { + const { t } = useTranslation('dataset') + + if (status !== DatasetPublishingStatus.RELEASED) { + return ( + <> + {' '} + + + ) + } + return <> +} diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx index 61ddb0c44..054ab4b89 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate.tsx @@ -1,17 +1,13 @@ import { FileDate as FileDateModel } from '../../../../../../../files/domain/models/File' import { useTranslation } from 'react-i18next' +import { DateHelper } from '../../../../../../../shared/domain/helpers/DateHelper' export function FileDate({ date }: { date: FileDateModel }) { const { t } = useTranslation('files') return (
- {t(`table.date.${date.type}`)}{' '} - {date.date.toLocaleDateString(Intl.DateTimeFormat().resolvedOptions().locale, { - year: 'numeric', - month: 'short', - day: 'numeric' - })} + {t(`table.date.${date.type}`)} {DateHelper.toDisplayFormat(date.date)}
) diff --git a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileEmbargoDate.tsx b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileEmbargoDate.tsx index 4c61171b9..50db565fa 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileEmbargoDate.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileEmbargoDate.tsx @@ -1,5 +1,6 @@ import { FileEmbargo, FilePublishingStatus } from '../../../../../../../files/domain/models/File' import { useTranslation } from 'react-i18next' +import { DateHelper } from '../../../../../../../shared/domain/helpers/DateHelper' interface FileEmbargoDateProps { embargo: FileEmbargo | undefined @@ -17,11 +18,7 @@ export function FileEmbargoDate({ embargo, publishingStatus }: FileEmbargoDatePr
{t(embargoTypeOfDate(embargo.isActive, publishingStatus))}{' '} - {embargo.dateAvailable.toLocaleDateString(Intl.DateTimeFormat().resolvedOptions().locale, { - year: 'numeric', - month: 'short', - day: 'numeric' - })} + {DateHelper.toDisplayFormat(embargo.dateAvailable)}
) diff --git a/src/sections/dataset/dataset-icon/DatasetIcon.module.scss b/src/sections/dataset/dataset-icon/DatasetIcon.module.scss new file mode 100644 index 000000000..4025c0bbe --- /dev/null +++ b/src/sections/dataset/dataset-icon/DatasetIcon.module.scss @@ -0,0 +1,6 @@ +@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module"; + +.icon { + color: $dv-info-border-color; + line-height: 1.1; +} \ No newline at end of file diff --git a/src/sections/dataset/dataset-icon/DatasetIcon.tsx b/src/sections/dataset/dataset-icon/DatasetIcon.tsx new file mode 100644 index 000000000..ac68ba92b --- /dev/null +++ b/src/sections/dataset/dataset-icon/DatasetIcon.tsx @@ -0,0 +1,10 @@ +import styles from './DatasetIcon.module.scss' +import { Icon, IconName } from '@iqss/dataverse-design-system' + +export function DatasetIcon() { + return ( +
+ +
+ ) +} diff --git a/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.module.scss b/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.module.scss new file mode 100644 index 000000000..a464f4dc4 --- /dev/null +++ b/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.module.scss @@ -0,0 +1,6 @@ +.preview-image { + width: 100%; + max-width: 140px; + height: auto; + max-height: 140px; +} \ No newline at end of file diff --git a/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.tsx b/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.tsx new file mode 100644 index 000000000..628cdd8ac --- /dev/null +++ b/src/sections/dataset/dataset-thumbnail/DatasetThumbnail.tsx @@ -0,0 +1,16 @@ +import styles from './DatasetThumbnail.module.scss' +import { DatasetIcon } from '../dataset-icon/DatasetIcon' + +interface DatasetThumbnailProps { + thumbnail?: string + title: string + isDeaccessioned?: boolean +} + +export function DatasetThumbnail({ thumbnail, title, isDeaccessioned }: DatasetThumbnailProps) { + if (thumbnail && !isDeaccessioned) { + return {title} + } + + return +} diff --git a/src/sections/home/datasets-list/DatasetsList.module.scss b/src/sections/home/datasets-list/DatasetsList.module.scss index 852fa280c..15aff10a5 100644 --- a/src/sections/home/datasets-list/DatasetsList.module.scss +++ b/src/sections/home/datasets-list/DatasetsList.module.scss @@ -1,7 +1,8 @@ @import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module"; .container { - padding:15px; + min-height: calc(100vh + 100px); + padding:15px; border: 1px solid #ddd; border-radius: 4px; } @@ -9,4 +10,4 @@ .empty-message-container { padding: .5em 1em; background: $dv-warning-box-color; -} \ No newline at end of file +} diff --git a/src/sections/home/datasets-list/DatasetsList.tsx b/src/sections/home/datasets-list/DatasetsList.tsx index c2f902295..da13f06d3 100644 --- a/src/sections/home/datasets-list/DatasetsList.tsx +++ b/src/sections/home/datasets-list/DatasetsList.tsx @@ -5,11 +5,10 @@ import { useEffect, useState } from 'react' import { PaginationResultsInfo } from '../../shared/pagination/PaginationResultsInfo' import { PaginationControls } from '../../shared/pagination/PaginationControls' import { DatasetPaginationInfo } from '../../../dataset/domain/models/DatasetPaginationInfo' -import { LinkToPage } from '../../shared/link-to-page/LinkToPage' -import { Route } from '../../Route.enum' import { useLoading } from '../../loading/LoadingContext' import { DatasetsListSkeleton } from './DatasetsListSkeleton' import { NoDatasetsMessage } from './NoDatasetsMessage' +import { DatasetCard } from './dataset-card/DatasetCard' interface DatasetsListProps { datasetRepository: DatasetRepository @@ -40,13 +39,7 @@ export function DatasetsList({ datasetRepository }: DatasetsListProps) {
{datasets.map((dataset) => ( -
- - {dataset.title} - -
+ ))}
- - - - - - - - - - + + + + + + + + + +
diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCard.module.scss b/src/sections/home/datasets-list/dataset-card/DatasetCard.module.scss new file mode 100644 index 000000000..92f7696b2 --- /dev/null +++ b/src/sections/home/datasets-list/dataset-card/DatasetCard.module.scss @@ -0,0 +1,71 @@ +@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-info-border-color; +} + +.header { + display: flex; + justify-content: space-between; +} + +.title { + display: flex; + + > * { + margin-right: .5em; + } +} + +.icon { + margin-top: 2px; + font-size: 1.3em; + + > div >span { + margin-right: 0; + } +} + +.thumbnail { + width: 48px; + margin: 8px 12px 6px 0; + font-size: 2.8em; + + img { + vertical-align: top; + } +} + +.info { + display: flex; +} + +.description { + display: flex; + flex-direction: column; + width: 100%; + font-size: $dv-font-size-sm; +} + +.date { + color: $dv-subtext-color; + +} + +.citation-box { + margin-top: 4px; + margin-bottom: .5em; + padding: 4px; + background-color: color.adjust($dv-primary-color, $lightness: 51%) ; +} + +.citation-box-deaccessioned { + margin-top: 4px; + margin-bottom: .5em; + padding: 4px; + background-color: color.adjust($dv-danger-box-color, $lightness: 6%); +} \ No newline at end of file diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCard.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCard.tsx new file mode 100644 index 000000000..6fe1f807e --- /dev/null +++ b/src/sections/home/datasets-list/dataset-card/DatasetCard.tsx @@ -0,0 +1,21 @@ +import { DatasetPreview } from '../../../../dataset/domain/models/DatasetPreview' +import styles from './DatasetCard.module.scss' +import { DatasetCardHeader } from './DatasetCardHeader' +import { DatasetCardThumbnail } from './DatasetCardThumbnail' +import { DatasetCardInfo } from './DatasetCardInfo' + +interface DatasetCardProps { + dataset: DatasetPreview +} + +export function DatasetCard({ dataset }: DatasetCardProps) { + return ( +
+ +
+ + +
+
+ ) +} diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCardHeader.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCardHeader.tsx new file mode 100644 index 000000000..9e927b2fc --- /dev/null +++ b/src/sections/home/datasets-list/dataset-card/DatasetCardHeader.tsx @@ -0,0 +1,25 @@ +import styles from './DatasetCard.module.scss' +import { LinkToPage } from '../../../shared/link-to-page/LinkToPage' +import { Route } from '../../../Route.enum' +import { DatasetLabels } from '../../../dataset/dataset-labels/DatasetLabels' +import { DatasetPreview } from '../../../../dataset/domain/models/DatasetPreview' +import { DatasetIcon } from '../../../dataset/dataset-icon/DatasetIcon' + +interface DatasetCardHeaderProps { + dataset: DatasetPreview +} +export function DatasetCardHeader({ dataset }: DatasetCardHeaderProps) { + return ( +
+
+ + {dataset.title} + + +
+
+ +
+
+ ) +} diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCardInfo.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCardInfo.tsx new file mode 100644 index 000000000..76a03a645 --- /dev/null +++ b/src/sections/home/datasets-list/dataset-card/DatasetCardInfo.tsx @@ -0,0 +1,23 @@ +import styles from './DatasetCard.module.scss' +import { DateHelper } from '../../../../shared/domain/helpers/DateHelper' +import { DatasetPreview } from '../../../../dataset/domain/models/DatasetPreview' +import { CitationDescription } from '../../../shared/citation/CitationDescription' + +interface DatasetCardInfoProps { + dataset: DatasetPreview +} + +export function DatasetCardInfo({ dataset }: DatasetCardInfoProps) { + return ( +
+ {DateHelper.toDisplayFormat(dataset.releaseOrCreateDate)} + + + + {dataset.abbreviatedDescription} +
+ ) +} diff --git a/src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.tsx b/src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.tsx new file mode 100644 index 000000000..cba65b215 --- /dev/null +++ b/src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.tsx @@ -0,0 +1,23 @@ +import styles from './DatasetCard.module.scss' +import { DatasetPreview } from '../../../../dataset/domain/models/DatasetPreview' +import { LinkToPage } from '../../../shared/link-to-page/LinkToPage' +import { Route } from '../../../Route.enum' +import { DatasetThumbnail } from '../../../dataset/dataset-thumbnail/DatasetThumbnail' + +interface DatasetCardThumbnailProps { + dataset: DatasetPreview +} + +export function DatasetCardThumbnail({ dataset }: DatasetCardThumbnailProps) { + return ( +
+ + + +
+ ) +} diff --git a/src/sections/shared/citation/CitationDescription.tsx b/src/sections/shared/citation/CitationDescription.tsx new file mode 100644 index 000000000..eb2730bd2 --- /dev/null +++ b/src/sections/shared/citation/CitationDescription.tsx @@ -0,0 +1,11 @@ +import parse from 'html-react-parser' + +interface CitationDescriptionProps { + citation: string +} + +export function CitationDescription({ citation }: CitationDescriptionProps) { + const citationAsReactElement = parse(citation) + + return {citationAsReactElement} +} diff --git a/src/shared/domain/helpers/DateHelper.ts b/src/shared/domain/helpers/DateHelper.ts new file mode 100644 index 000000000..021ec2a68 --- /dev/null +++ b/src/shared/domain/helpers/DateHelper.ts @@ -0,0 +1,9 @@ +export class DateHelper { + static toDisplayFormat(date: Date): string { + return date.toLocaleDateString(Intl.DateTimeFormat().resolvedOptions().locale, { + year: 'numeric', + month: 'short', + day: 'numeric' + }) + } +} diff --git a/src/stories/dataset/DatasetMockRepository.ts b/src/stories/dataset/DatasetMockRepository.ts index 263d789a9..9ffa083ed 100644 --- a/src/stories/dataset/DatasetMockRepository.ts +++ b/src/stories/dataset/DatasetMockRepository.ts @@ -11,7 +11,7 @@ export class DatasetMockRepository implements DatasetRepository { getAll(paginationInfo: DatasetPaginationInfo): Promise { return new Promise((resolve) => { setTimeout(() => { - resolve(DatasetPreviewMother.createMany(paginationInfo.pageSize)) + resolve(DatasetPreviewMother.createManyRealistic(paginationInfo.pageSize)) }, 1000) }) } diff --git a/src/stories/home/datasets-list/DatasetCard.stories.tsx b/src/stories/home/datasets-list/DatasetCard.stories.tsx new file mode 100644 index 000000000..26f6af0da --- /dev/null +++ b/src/stories/home/datasets-list/DatasetCard.stories.tsx @@ -0,0 +1,21 @@ +import { Meta, StoryObj } from '@storybook/react' +import { WithI18next } from '../../WithI18next' +import { DatasetCard } from '../../../sections/home/datasets-list/dataset-card/DatasetCard' +import { DatasetPreviewMother } from '../../../../tests/component/dataset/domain/models/DatasetPreviewMother' + +const meta: Meta = { + title: 'Sections/Home/DatasetCard', + component: DatasetCard, + decorators: [WithI18next] +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => +} + +export const Deaccessioned: Story = { + render: () => +} diff --git a/src/stories/home/datasets-list/DatasetsList.stories.tsx b/src/stories/home/datasets-list/DatasetsList.stories.tsx index 7f2d32c02..51287336f 100644 --- a/src/stories/home/datasets-list/DatasetsList.stories.tsx +++ b/src/stories/home/datasets-list/DatasetsList.stories.tsx @@ -1,19 +1,18 @@ import { Meta, StoryObj } from '@storybook/react' -import { Home } from '../../../sections/home/Home' import { WithI18next } from '../../WithI18next' import { DatasetMockRepository } from '../../dataset/DatasetMockRepository' import { DatasetsList } from '../../../sections/home/datasets-list/DatasetsList' import { DatasetLoadingMockRepository } from '../../dataset/DatasetLoadingMockRepository' import { NoDatasetsMockRepository } from '../../dataset/NoDatasetsMockRepository' -const meta: Meta = { +const meta: Meta = { title: 'Sections/Home/DatasetsList', - component: Home, + component: DatasetsList, decorators: [WithI18next] } export default meta -type Story = StoryObj +type Story = StoryObj export const Default: Story = { render: () => diff --git a/tests/component/dataset/domain/models/DatasetMother.ts b/tests/component/dataset/domain/models/DatasetMother.ts index 51a959267..6c2a01f28 100644 --- a/tests/component/dataset/domain/models/DatasetMother.ts +++ b/tests/component/dataset/domain/models/DatasetMother.ts @@ -2,6 +2,7 @@ import { faker } from '@faker-js/faker' import { ANONYMIZED_FIELD_VALUE, Dataset, + DatasetLabel, DatasetLabelSemanticMeaning, DatasetLabelValue, DatasetLock, @@ -189,6 +190,45 @@ export class DatasetLockMother { } } +export class DatasetLabelsMother { + static create(): DatasetLabel[] { + return [{ value: 'Version 1.0', semanticMeaning: DatasetLabelSemanticMeaning.FILE }] + } + + static createDraft(): DatasetLabel[] { + return [ + { + value: DatasetLabelValue.UNPUBLISHED, + semanticMeaning: DatasetLabelSemanticMeaning.WARNING + }, + { value: DatasetLabelValue.DRAFT, semanticMeaning: DatasetLabelSemanticMeaning.DATASET } + ] + } + + static createDeaccessioned(): DatasetLabel[] { + return [ + { + value: DatasetLabelValue.DEACCESSIONED, + semanticMeaning: DatasetLabelSemanticMeaning.DANGER + } + ] + } +} + +export class DatasetCitationMother { + static create(): string { + return 'Finch, Fiona, 2023, "Darwin\'s Finches", https://doi.org/10.5072/FK2/0YFWKL, Root, V1' + } + + static createDraft(): string { + return 'Finch, Fiona, 2023, "Darwin\'s Finches", https://doi.org/10.5072/FK2/0YFWKL, Root, DRAFT VERSION' + } + + static createDeaccessioned(): string { + return 'Finch, Fiona, 2023, "Darwin\'s Finches", https://doi.org/10.5072/FK2/0YFWKL, Root, V1, DEACCESSIONED VERSION' + } +} + export class DatasetMother { static createEmpty(): undefined { return undefined @@ -210,24 +250,7 @@ export class DatasetMother { uri: 'https://creativecommons.org/publicdomain/zero/1.0/', iconUri: 'https://licensebuttons.net/p/zero/1.0/88x31.png' }, - labels: [ - { - value: DatasetLabelValue.IN_REVIEW, - semanticMeaning: faker.helpers.arrayElement(Object.values(DatasetLabelSemanticMeaning)) - }, - { - value: DatasetLabelValue.EMBARGOED, - semanticMeaning: faker.helpers.arrayElement(Object.values(DatasetLabelSemanticMeaning)) - }, - { - value: DatasetLabelValue.UNPUBLISHED, - semanticMeaning: faker.helpers.arrayElement(Object.values(DatasetLabelSemanticMeaning)) - }, - { - value: `Version ${faker.lorem.word()}`, - semanticMeaning: faker.helpers.arrayElement(Object.values(DatasetLabelSemanticMeaning)) - } - ], + labels: DatasetLabelsMother.create(), summaryFields: [ { name: MetadataBlockName.CITATION, diff --git a/tests/component/dataset/domain/models/DatasetPreviewMother.ts b/tests/component/dataset/domain/models/DatasetPreviewMother.ts index 3932aa6b6..83e080ff9 100644 --- a/tests/component/dataset/domain/models/DatasetPreviewMother.ts +++ b/tests/component/dataset/domain/models/DatasetPreviewMother.ts @@ -1,16 +1,68 @@ import { faker } from '@faker-js/faker' import { DatasetPreview } from '../../../../../src/dataset/domain/models/DatasetPreview' +import { DatasetCitationMother, DatasetLabelsMother, DatasetVersionMother } from './DatasetMother' export class DatasetPreviewMother { static createMany(count: number): DatasetPreview[] { return Array.from({ length: count }, () => this.create()) } + static createManyRealistic(count: number): DatasetPreview[] { + return Array.from({ length: count }, () => this.createRealistic()) + } + static create(props?: Partial): DatasetPreview { - return { + const datasetPreview = { persistentId: faker.datatype.uuid(), title: faker.lorem.sentence(), + labels: DatasetLabelsMother.create(), + isDeaccessioned: faker.datatype.boolean(), + thumbnail: faker.datatype.boolean() ? faker.image.imageUrl() : undefined, + releaseOrCreateDate: faker.date.past(), + version: DatasetVersionMother.create(), + citation: DatasetCitationMother.create(), + description: faker.lorem.paragraph(), ...props } + + return new DatasetPreview( + datasetPreview.persistentId, + datasetPreview.title, + datasetPreview.version, + datasetPreview.citation, + datasetPreview.labels, + datasetPreview.isDeaccessioned, + datasetPreview.releaseOrCreateDate, + datasetPreview.description, + datasetPreview.thumbnail + ) + } + + static createRealistic(): DatasetPreview { + return faker.datatype.boolean() ? this.createDraft() : this.createDeaccessioned() + } + + static createDraft(): DatasetPreview { + return this.create({ + isDeaccessioned: false, + labels: DatasetLabelsMother.createDraft(), + citation: DatasetCitationMother.createDraft() + }) + } + + static createWithThumbnail(): DatasetPreview { + return this.create({ thumbnail: faker.image.imageUrl(), isDeaccessioned: false }) + } + + static createWithNoThumbnail(): DatasetPreview { + return this.create({ thumbnail: undefined, isDeaccessioned: false }) + } + + static createDeaccessioned(): DatasetPreview { + return this.create({ + isDeaccessioned: true, + labels: DatasetLabelsMother.createDeaccessioned(), + citation: DatasetCitationMother.createDeaccessioned() + }) } } diff --git a/tests/component/sections/dataset/dataset-citation/CitationThumbnail.spec.tsx b/tests/component/sections/dataset/dataset-citation/CitationThumbnail.spec.tsx deleted file mode 100644 index c73ab2359..000000000 --- a/tests/component/sections/dataset/dataset-citation/CitationThumbnail.spec.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { DatasetPublishingStatus } from '../../../../../src/dataset/domain/models/Dataset' -import { CitationThumbnail } from '../../../../../src/sections/dataset/dataset-citation/CitationThumbnail' - -describe('CitationThumbnail', () => { - it('renders the dataset icon when there is no thumbnail', () => { - cy.customMount( - - ) - - cy.findByLabelText('icon-dataset').should('exist') - }) - - it('renders the dataset icon when the dataset is deaccessioned', () => { - cy.customMount( - - ) - - cy.findByLabelText('icon-dataset').should('exist') - }) - - it('renders the dataset thumbnail when there is one and the dataset is not deaccessioned', () => { - cy.customMount( - - ) - - cy.findByRole('img', { name: 'Dataset title' }).should('exist') - }) -}) diff --git a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx index 851029fa5..9f605cc54 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/FileDate.spec.tsx @@ -1,16 +1,13 @@ import { FileDate } from '../../../../../../../../../src/sections/dataset/dataset-files/files-table/file-info/file-info-cell/file-info-data/FileDate' import { FileDateType } from '../../../../../../../../../src/files/domain/models/File' +import { DateHelper } from '../../../../../../../../../src/shared/domain/helpers/DateHelper' describe('FileDate', () => { it('renders the date', () => { const fileDate = new Date('2023-09-18') const date = { type: FileDateType.PUBLISHED, date: fileDate } cy.customMount() - const dateString = fileDate.toLocaleDateString(Intl.DateTimeFormat().resolvedOptions().locale, { - year: 'numeric', - month: 'short', - day: 'numeric' - }) + const dateString = DateHelper.toDisplayFormat(fileDate) cy.findByText(`Published ` + dateString).should('exist') }) }) diff --git a/tests/component/sections/dataset/dataset-icon/DatasetIcon.spec.tsx b/tests/component/sections/dataset/dataset-icon/DatasetIcon.spec.tsx new file mode 100644 index 000000000..163759a50 --- /dev/null +++ b/tests/component/sections/dataset/dataset-icon/DatasetIcon.spec.tsx @@ -0,0 +1,9 @@ +import { DatasetIcon } from '../../../../../src/sections/dataset/dataset-icon/DatasetIcon' + +describe('DatasetIcon', () => { + it('renders the dataset icon', () => { + cy.customMount() + + cy.findByLabelText('icon-dataset').should('exist') + }) +}) diff --git a/tests/component/sections/dataset/dataset-thumbanil/DatasetThumbnail.spec.tsx b/tests/component/sections/dataset/dataset-thumbanil/DatasetThumbnail.spec.tsx new file mode 100644 index 000000000..1bb47523e --- /dev/null +++ b/tests/component/sections/dataset/dataset-thumbanil/DatasetThumbnail.spec.tsx @@ -0,0 +1,29 @@ +import { DatasetThumbnail } from '../../../../../src/sections/dataset/dataset-thumbnail/DatasetThumbnail' + +describe('DatasetThumbnail', () => { + it('renders the dataset icon when there is no thumbnail', () => { + cy.customMount() + + cy.findByLabelText('icon-dataset').should('exist') + }) + + it('renders the dataset icon when the dataset is deaccessioned', () => { + cy.customMount( + + ) + + cy.findByLabelText('icon-dataset').should('exist') + }) + + it('renders the dataset thumbnail when there is one and the dataset is not deaccessioned', () => { + cy.customMount( + + ) + + cy.findByRole('img', { name: 'Dataset title' }).should('exist') + }) +}) diff --git a/tests/component/sections/home/datasets-list/DatasetsList.spec.tsx b/tests/component/sections/home/datasets-list/DatasetsList.spec.tsx index 2623da1d7..e126ce245 100644 --- a/tests/component/sections/home/datasets-list/DatasetsList.spec.tsx +++ b/tests/component/sections/home/datasets-list/DatasetsList.spec.tsx @@ -38,7 +38,7 @@ describe('Datasets List', () => { cy.findByText('1 to 10 of 200 Datasets').should('exist') datasets.forEach((dataset) => { - cy.findByRole('link', { name: dataset.title }) + cy.findByText(dataset.title) .should('exist') .should('have.attr', 'href', `/datasets?persistentId=${dataset.persistentId}`) }) diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCard.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCard.spec.tsx new file mode 100644 index 000000000..8b66c37d1 --- /dev/null +++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCard.spec.tsx @@ -0,0 +1,21 @@ +import { DatasetPreviewMother } from '../../../../dataset/domain/models/DatasetPreviewMother' +import { DatasetCard } from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCard' +import { DateHelper } from '../../../../../../src/shared/domain/helpers/DateHelper' +import styles from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCard.module.scss' + +describe('DatasetCard', () => { + it('should render the card', () => { + const dataset = DatasetPreviewMother.createWithThumbnail() + cy.customMount() + + cy.findByText(dataset.title).should('exist') + + cy.findByRole('img', { name: dataset.title }).should('exist') + cy.findByText(DateHelper.toDisplayFormat(dataset.releaseOrCreateDate)).should('exist') + cy.findByText(/Finch, Fiona, 2023, "Darwin's Finches"/) + .should('exist') + .parent() + .should('have.class', styles['citation-box']) + cy.findByText(dataset.abbreviatedDescription).should('exist') + }) +}) diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardHeader.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardHeader.spec.tsx new file mode 100644 index 000000000..1e7773dfc --- /dev/null +++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardHeader.spec.tsx @@ -0,0 +1,17 @@ +import { DatasetCardHeader } from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCardHeader' +import { DatasetPreviewMother } from '../../../../dataset/domain/models/DatasetPreviewMother' + +describe('DatasetCardHeader', () => { + it('should render the header', () => { + const dataset = DatasetPreviewMother.create() + cy.customMount() + + cy.findByText(dataset.title) + .should('exist') + .should('have.attr', 'href', `/datasets?persistentId=${dataset.persistentId}`) + dataset.labels.forEach((label) => { + cy.findByText(label.value).should('exist') + }) + cy.findByLabelText('icon-dataset').should('exist') + }) +}) diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardInfo.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardInfo.spec.tsx new file mode 100644 index 000000000..5563fe412 --- /dev/null +++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardInfo.spec.tsx @@ -0,0 +1,28 @@ +import { DatasetPreviewMother } from '../../../../dataset/domain/models/DatasetPreviewMother' +import { DateHelper } from '../../../../../../src/shared/domain/helpers/DateHelper' +import styles from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCard.module.scss' +import { DatasetCardInfo } from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCardInfo' + +describe('DatasetCardInfo', () => { + it('should render the dataset info', () => { + const dataset = DatasetPreviewMother.createDraft() + cy.customMount() + + cy.findByText(DateHelper.toDisplayFormat(dataset.releaseOrCreateDate)).should('exist') + cy.findByText(/Finch, Fiona, 2023, "Darwin's Finches"/) + .should('exist') + .parent() + .should('have.class', styles['citation-box']) + cy.findByText(dataset.abbreviatedDescription).should('exist') + }) + + it('should render the citation with the deaccessioned background if the dataset is deaccessioned', () => { + const dataset = DatasetPreviewMother.createDeaccessioned() + cy.customMount() + + cy.findByText(/Finch, Fiona, 2023, "Darwin's Finches"/) + .should('exist') + .parent() + .should('have.class', styles['citation-box-deaccessioned']) + }) +}) diff --git a/tests/component/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.spec.tsx b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.spec.tsx new file mode 100644 index 000000000..e261e32db --- /dev/null +++ b/tests/component/sections/home/datasets-list/dataset-card/DatasetCardThumbnail.spec.tsx @@ -0,0 +1,25 @@ +import { DatasetPreviewMother } from '../../../../dataset/domain/models/DatasetPreviewMother' +import { DatasetCardThumbnail } from '../../../../../../src/sections/home/datasets-list/dataset-card/DatasetCardThumbnail' + +describe('DatasetCardThumbnail', () => { + it('should render the thumbnail', () => { + const dataset = DatasetPreviewMother.createWithThumbnail() + cy.customMount() + + cy.findByRole('img', { name: dataset.title }) + .should('exist') + .parent('a') + .should('have.attr', 'href', `/datasets?persistentId=${dataset.persistentId}`) + }) + + it('should render the placeholder if the dataset has no thumbnail', () => { + const dataset = DatasetPreviewMother.createWithNoThumbnail() + cy.customMount() + + cy.findByRole('img', { name: 'icon-dataset' }) + .should('exist') + .parent() + .parent('a') + .should('have.attr', 'href', `/datasets?persistentId=${dataset.persistentId}`) + }) +}) diff --git a/tests/component/sections/shared/citation/CitationDescription.spec.tsx b/tests/component/sections/shared/citation/CitationDescription.spec.tsx new file mode 100644 index 000000000..ce5b1a57e --- /dev/null +++ b/tests/component/sections/shared/citation/CitationDescription.spec.tsx @@ -0,0 +1,12 @@ +import { CitationDescription } from '../../../../../src/sections/shared/citation/CitationDescription' + +describe('CitationDescription', () => { + it('renders the citation', () => { + const citation = + 'Finch, Fiona, 2023, "Darwin\'s Finches", https://doi.org/10.5072/FK2/0YFWKL, Root, V1' + cy.customMount() + + cy.findByText(/Finch, Fiona, 2023, "Darwin's Finches",/).should('exist') + cy.findByRole('link', { name: 'https://doi.org/10.5072/FK2/0YFWKL' }).should('exist') + }) +})