From 2f87c5fc5c8d25a3ac19678ee5bc98128085dd65 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Sun, 26 Jan 2025 09:26:26 -0500 Subject: [PATCH 01/45] feat: add TermsOfUse to Dataset model, and update mapping --- package-lock.json | 9 ++--- package.json | 2 +- src/dataset/domain/models/Dataset.ts | 13 +++++++ .../infrastructure/mappers/JSDatasetMapper.ts | 1 + .../dataset/dataset-terms/DatasetTerms.tsx | 38 +++++++++++++++++++ .../dataset/domain/models/DatasetMother.ts | 11 ++++++ .../fixtures/dataset-finch1.json | 10 +++++ .../DatasetJSDataverseRepository.spec.ts | 19 +++++++++- 8 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 src/sections/dataset/dataset-terms/DatasetTerms.tsx diff --git a/package-lock.json b/package-lock.json index 39e3377e1..890a9f7ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-alpha.13", + "@iqss/dataverse-client-javascript": "2.0.0-pr243.ce1c24b", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", @@ -3674,10 +3674,9 @@ }, "node_modules/@iqss/dataverse-client-javascript": { "name": "@IQSS/dataverse-client-javascript", - "version": "2.0.0-alpha.13", - "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-alpha.13/99f81ce18bdd855a54cd79520367516c28b262b8", - "integrity": "sha512-Giv/g1+6bFUTiVcwnzrJhdhWhyMd6gcXLnArN36kxAPrhoR0adRjUa8bevE41Vb5lASw56UoVF17XS/G9Uhj7A==", - "license": "MIT", + "version": "2.0.0-pr243.ce1c24b", + "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr243.ce1c24b/f23dada5c3bac33044c0c718305d5b0104e18ce5", + "integrity": "sha512-gT2GOZyxHN0JlbpSAQquPJoaaYzLBzdZZUi+ltpR5rrlvidro9zU8V+o68FrZbPiMXxsAMADl81a+Mvb+1YFuQ==", "dependencies": { "@types/node": "^18.15.11", "@types/turndown": "^5.0.1", diff --git a/package.json b/package.json index a373e4161..6dccac6a2 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-alpha.13", + "@iqss/dataverse-client-javascript": "2.0.0-pr243.ce1c24b", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts index 0d26023f2..83a9dee2a 100644 --- a/src/dataset/domain/models/Dataset.ts +++ b/src/dataset/domain/models/Dataset.ts @@ -367,6 +367,16 @@ export interface DatasetDownloadUrls { original: string archival: string } +export interface TermsOfUse { + fileAccessRequest: boolean + termsOfAccess?: string + dataAccessPlace?: string + originalArchive?: string + availabilityStatus?: string + contactForAccess?: string + sizeOfCollection?: string + studyCompletion?: string +} export class Dataset { constructor( @@ -375,6 +385,7 @@ export class Dataset { public readonly alerts: Alert[], public readonly summaryFields: DatasetMetadataBlock[], public readonly license: DatasetLicense, + public readonly termsOfUse: TermsOfUse, public readonly metadataBlocks: DatasetMetadataBlocks, public readonly permissions: DatasetPermissions, public readonly locks: DatasetLock[], @@ -467,6 +478,7 @@ export class Dataset { public readonly version: DatasetVersion, public readonly summaryFields: DatasetMetadataBlock[], public readonly license: DatasetLicense = defaultLicense, + public readonly termsOfUse: TermsOfUse, public readonly metadataBlocks: DatasetMetadataBlocks, public readonly permissions: DatasetPermissions, public readonly locks: DatasetLock[], @@ -535,6 +547,7 @@ export class Dataset { this.alerts, this.summaryFields, this.license, + this.termsOfUse, this.metadataBlocks, this.permissions, this.locks, diff --git a/src/dataset/infrastructure/mappers/JSDatasetMapper.ts b/src/dataset/infrastructure/mappers/JSDatasetMapper.ts index d049ef8b0..c63d604e1 100644 --- a/src/dataset/infrastructure/mappers/JSDatasetMapper.ts +++ b/src/dataset/infrastructure/mappers/JSDatasetMapper.ts @@ -61,6 +61,7 @@ export class JSDatasetMapper { version, JSDatasetMapper.toSummaryFields(jsDataset.metadataBlocks, jsDatasetSummaryFieldsNames), jsDataset.license, + jsDataset.termsOfUse, JSDatasetMapper.toMetadataBlocks( jsDataset.metadataBlocks, jsDataset.alternativePersistentId, diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx new file mode 100644 index 000000000..121012f0f --- /dev/null +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -0,0 +1,38 @@ +import { + DatasetMetadataBlock as DatasetMetadataBlockModel + // MetadataBlockName +} from '../../../dataset/domain/models/Dataset' +//import { DatasetMetadataBlock } from '../dataset-metadata/DatasetMetadataBlock' +import { MetadataBlockInfoRepository } from '../../../metadata-block-info/domain/repositories/MetadataBlockInfoRepository' + +interface DatasetTermsProps { + persistentId: string + metadataBlocks: DatasetMetadataBlockModel[] + metadataBlockInfoRepository: MetadataBlockInfoRepository +} + +export function DatasetTerms({ + persistentId, + metadataBlocks, + metadataBlockInfoRepository +}: DatasetTermsProps) { + return null + /* + + {metadataBlocks.map((metadataBlock, index) => { + metadataBlock.fields = + metadataBlock.name === MetadataBlockName.CITATION + ? { persistentId: persistentId, ...metadataBlock.fields } + : metadataBlock.fields + + return ( + + + + ) + })} + */ +} diff --git a/tests/component/dataset/domain/models/DatasetMother.ts b/tests/component/dataset/domain/models/DatasetMother.ts index 16fc4eb1d..7d3ba6350 100644 --- a/tests/component/dataset/domain/models/DatasetMother.ts +++ b/tests/component/dataset/domain/models/DatasetMother.ts @@ -416,6 +416,16 @@ export class DatasetMother { fileDownloadSizes: [], requestedVersion: undefined, hierarchy: UpwardHierarchyNodeMother.createDataset(), + termsOfUse: { + fileAccessRequest: true, + termsOfAccess: 'Terms of access', + dataAccessPlace: 'Data access place', + originalArchive: 'Original archive', + availabilityStatus: 'Availability status', + contactForAccess: 'Contact for access', + sizeOfCollection: 'Size of collection', + studyCompletion: 'Study completion' + }, ...props } @@ -424,6 +434,7 @@ export class DatasetMother { dataset.version, dataset.summaryFields, dataset.license, + dataset.termsOfUse, dataset.metadataBlocks, dataset.permissions, dataset.locks, diff --git a/tests/e2e-integration/fixtures/dataset-finch1.json b/tests/e2e-integration/fixtures/dataset-finch1.json index 3c11cb34c..b44b0525b 100644 --- a/tests/e2e-integration/fixtures/dataset-finch1.json +++ b/tests/e2e-integration/fixtures/dataset-finch1.json @@ -5,6 +5,16 @@ "uri": "http://creativecommons.org/publicdomain/zero/1.0", "iconUri": "https://licensebuttons.net/p/zero/1.0/88x31.png" }, + "termsOfUse": { + "fileAccessRequest": true, + "termsOfAccess": "Terms of access", + "dataAccessPlace": "Data access place", + "originalArchive": "Original archive", + "availabilityStatus": "Availability status", + "contactForAccess": "Contact for access", + "sizeOfCollection": "Size of collection", + "studyCompletion": "Study completion" + }, "metadataBlocks": { "citation": { "fields": [ diff --git a/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts index bab6c46b0..d270e49b2 100644 --- a/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts +++ b/tests/e2e-integration/integration/datasets/DatasetJSDataverseRepository.spec.ts @@ -25,7 +25,7 @@ import { VersionUpdateType } from '../../../../src/dataset/domain/models/Version chai.use(chaiAsPromised) const expect = chai.expect - +const rootCollectionAlias = 'root' function getCurrentDateInYYYYMMDDFormat() { const date = new Date() const [year, month, day] = [ @@ -54,6 +54,16 @@ const datasetData = (persistentId: string, versionId: number) => { uri: 'http://creativecommons.org/publicdomain/zero/1.0', iconUri: 'https://licensebuttons.net/p/zero/1.0/88x31.png' }, + termsOfUse: { + fileAccessRequest: true, + termsOfAccess: 'Terms of access', + dataAccessPlace: 'Data access place', + originalArchive: 'Original archive', + availabilityStatus: 'Availability status', + contactForAccess: 'Contact for access', + sizeOfCollection: 'Size of collection', + studyCompletion: 'Study completion' + }, metadataBlocks: [ { fields: { @@ -364,6 +374,11 @@ describe('Dataset JSDataverse Repository', () => { it('creates a new dataset from DatasetDTO', async () => { const datasetDTO: DatasetDTO = { + licence: { + name: 'CC0 1.0', + uri: 'http://creativecommons.org/publicdomain/zero/1.0', + iconUri: 'https://licensebuttons.net/p/zero/1.0/88x31.png' + }, metadataBlocks: [ { name: MetadataBlockName.CITATION, @@ -391,7 +406,7 @@ describe('Dataset JSDataverse Repository', () => { ] } - await datasetRepository.create(datasetDTO).then((response) => { + await datasetRepository.create(datasetDTO, rootCollectionAlias).then((response) => { expect(response.persistentId).to.exist }) }) From 46c4364785c4b547d6d74b14e8203a82a8a0b8e0 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Sun, 26 Jan 2025 14:35:26 -0500 Subject: [PATCH 02/45] feat: add Edit Terms Button and first iteration of Accordion Items --- public/locales/en/dataset.json | 11 +++ src/dataset/domain/models/Dataset.ts | 6 +- .../DatasetJSDataverseRepository.ts | 1 + src/sections/dataset/Dataset.tsx | 6 ++ .../dataset-terms/DatasetTerms.module.scss | 5 ++ .../dataset/dataset-terms/DatasetTerms.tsx | 67 ++++++++++--------- .../EditDatasetTermsButton.module.scss | 4 ++ .../dataset-terms/EditDatasetTermsButton.tsx | 32 +++++++++ 8 files changed, 96 insertions(+), 36 deletions(-) create mode 100644 src/sections/dataset/dataset-terms/DatasetTerms.module.scss create mode 100644 src/sections/dataset/dataset-terms/EditDatasetTermsButton.module.scss create mode 100644 src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index b37c40265..f490e0b09 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -1,6 +1,7 @@ { "filesTabTitle": "Files", "metadataTabTitle": "Metadata", + "termsTabTitle": "Terms", "anonymizedFieldValue": "withheld", "license": { "title": "License/Data Use Agreement", @@ -116,6 +117,16 @@ "alertText": "This unpublished dataset is being privately shared." } }, + "terms": { + "editTermsButton": "Edit Term Requirements", + "title": "Terms", + "termsOfUse": "Terms of Use", + "termsOfAccess": "Terms of Access", + "termsOfAccessPlaceholder": "Enter terms of access", + "termsOfUsePlaceholder": "Enter terms of use", + "termsOfUseHelpText": "These terms will be displayed to users who download your data.", + "termsOfAccessHelpText": "These terms will be displayed to users who request access to your data." + }, "publish": { "draftQuestion": "Are you sure you want to publish this dataset? Once you do so, it must remain published.", "draftSubtext": "This version of the dataset will be published with the following terms:", diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts index 83a9dee2a..7b429e829 100644 --- a/src/dataset/domain/models/Dataset.ts +++ b/src/dataset/domain/models/Dataset.ts @@ -367,7 +367,7 @@ export interface DatasetDownloadUrls { original: string archival: string } -export interface TermsOfUse { +export interface DatasetTermsOfUse { fileAccessRequest: boolean termsOfAccess?: string dataAccessPlace?: string @@ -385,7 +385,7 @@ export class Dataset { public readonly alerts: Alert[], public readonly summaryFields: DatasetMetadataBlock[], public readonly license: DatasetLicense, - public readonly termsOfUse: TermsOfUse, + public readonly termsOfUse: DatasetTermsOfUse, public readonly metadataBlocks: DatasetMetadataBlocks, public readonly permissions: DatasetPermissions, public readonly locks: DatasetLock[], @@ -478,7 +478,7 @@ export class Dataset { public readonly version: DatasetVersion, public readonly summaryFields: DatasetMetadataBlock[], public readonly license: DatasetLicense = defaultLicense, - public readonly termsOfUse: TermsOfUse, + public readonly termsOfUse: DatasetTermsOfUse, public readonly metadataBlocks: DatasetMetadataBlocks, public readonly permissions: DatasetPermissions, public readonly locks: DatasetLock[], diff --git a/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts b/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts index 91c1d5232..a93326b63 100644 --- a/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts +++ b/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts @@ -178,6 +178,7 @@ export class DatasetJSDataverseRepository implements DatasetRepository { .execute(persistentId, version, includeDeaccessioned) .then((jsDataset) => this.fetchDatasetDetails(jsDataset, version)) .then((datasetDetails) => { + console.log('jsDataset', datasetDetails.jsDataset) return this.fetchDownloadSizes(persistentId, version).then((downloadSizes) => { datasetDetails.jsDatasetFilesTotalOriginalDownloadSize = downloadSizes[0] datasetDetails.jsDatasetFilesTotalArchivalDownloadSize = downloadSizes[1] diff --git a/src/sections/dataset/Dataset.tsx b/src/sections/dataset/Dataset.tsx index 07e115b88..62e3024c5 100644 --- a/src/sections/dataset/Dataset.tsx +++ b/src/sections/dataset/Dataset.tsx @@ -26,6 +26,7 @@ import useUpdateDatasetAlerts from './useUpdateDatasetAlerts' import { QueryParamKey, Route } from '../Route.enum' import { MetadataBlockInfoRepository } from '../../metadata-block-info/domain/repositories/MetadataBlockInfoRepository' import { CollectionRepository } from '../../collection/domain/repositories/CollectionRepository' +import { DatasetTerms } from '@/sections/dataset/dataset-terms/DatasetTerms' interface DatasetProps { datasetRepository: DatasetRepository @@ -152,6 +153,11 @@ export function Dataset({ /> + +
+ +
+
)} diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.module.scss b/src/sections/dataset/dataset-terms/DatasetTerms.module.scss new file mode 100644 index 000000000..ab0acdaf9 --- /dev/null +++ b/src/sections/dataset/dataset-terms/DatasetTerms.module.scss @@ -0,0 +1,5 @@ +.edit-terms-button-container { + display: flex; + justify-content: flex-end; + margin-bottom: 1rem; +} diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index 121012f0f..4893e2910 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -1,38 +1,39 @@ -import { - DatasetMetadataBlock as DatasetMetadataBlockModel - // MetadataBlockName -} from '../../../dataset/domain/models/Dataset' -//import { DatasetMetadataBlock } from '../dataset-metadata/DatasetMetadataBlock' -import { MetadataBlockInfoRepository } from '../../../metadata-block-info/domain/repositories/MetadataBlockInfoRepository' +import { Accordion } from '@iqss/dataverse-design-system' +import { DatasetLicense, DatasetTermsOfUse } from '../../../dataset/domain/models/Dataset' +import { License } from '@/sections/dataset/dataset-summary/License' +import { EditDatasetTermsButton } from '@/sections/dataset/dataset-terms/EditDatasetTermsButton' +import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' interface DatasetTermsProps { - persistentId: string - metadataBlocks: DatasetMetadataBlockModel[] - metadataBlockInfoRepository: MetadataBlockInfoRepository + license: DatasetLicense + termsOfUse: DatasetTermsOfUse } +/* +{termsOfUse.termsOfAccess &&
termsOfUse.termsOfAccess
} + {termsOfUse.dataAccessPlace &&
termsOfUse.dataAccessPlace
} -export function DatasetTerms({ - persistentId, - metadataBlocks, - metadataBlockInfoRepository -}: DatasetTermsProps) { - return null - /* - - {metadataBlocks.map((metadataBlock, index) => { - metadataBlock.fields = - metadataBlock.name === MetadataBlockName.CITATION - ? { persistentId: persistentId, ...metadataBlock.fields } - : metadataBlock.fields - - return ( - - - - ) - })} - */ + */ +export function DatasetTerms({ license, termsOfUse }: DatasetTermsProps) { + return ( + <> +
+ +
+ + + License + + + + + + Terms of Use + + {termsOfUse.termsOfAccess &&
{termsOfUse.termsOfAccess}
} + {termsOfUse.dataAccessPlace &&
{termsOfUse.dataAccessPlace}
} +
+
+
+ + ) } diff --git a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.module.scss b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.module.scss new file mode 100644 index 000000000..2c56411ea --- /dev/null +++ b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.module.scss @@ -0,0 +1,4 @@ +.icon { + margin-right: 0.3rem; + margin-bottom: 0.2rem; +} diff --git a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx new file mode 100644 index 000000000..6f996c6fe --- /dev/null +++ b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx @@ -0,0 +1,32 @@ +import { useTranslation } from 'react-i18next' +import { Backpack } from 'react-bootstrap-icons' +import { Button } from '@iqss/dataverse-design-system' +import styles from './EditDatasetTermsButton.module.scss' +import { useSession } from '@/sections/session/SessionContext' +import { useDataset } from '@/sections/dataset/DatasetContext' +import { useNotImplementedModal } from '@/sections/not-implemented/NotImplementedModalContext' + +export function EditDatasetTermsButton() { + const { t } = useTranslation('dataset') + const { user } = useSession() + const { dataset } = useDataset() + const { showModal } = useNotImplementedModal() + + if (!user || !dataset?.permissions.canUpdateDataset) { + return <> + } + + const handleClick = () => { + showModal() + } + + return ( + + ) +} From e5fc2dea031de57d364cbee6e4c839158d06381c Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Sun, 26 Jan 2025 20:03:17 -0500 Subject: [PATCH 03/45] feat: add termsOfUse fields to AccordionBody --- public/locales/en/dataset.json | 23 +++-- src/sections/dataset/Dataset.tsx | 8 +- .../dataset-terms/DatasetTerms.module.scss | 4 + .../dataset/dataset-terms/DatasetTerms.tsx | 84 +++++++++++++++++-- .../dataset-terms/EditDatasetTermsButton.tsx | 2 +- 5 files changed, 102 insertions(+), 19 deletions(-) diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index f490e0b09..c1264cdec 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -117,15 +117,22 @@ "alertText": "This unpublished dataset is being privately shared." } }, - "terms": { + "termsTab": { "editTermsButton": "Edit Term Requirements", - "title": "Terms", - "termsOfUse": "Terms of Use", - "termsOfAccess": "Terms of Access", - "termsOfAccessPlaceholder": "Enter terms of access", - "termsOfUsePlaceholder": "Enter terms of use", - "termsOfUseHelpText": "These terms will be displayed to users who download your data.", - "termsOfAccessHelpText": "These terms will be displayed to users who request access to your data." + "licenseTitle": "Dataset Terms", + "termsTitle": "Restricted Files + Terms of Access", + "dataAccessPlace": "Data Access Place", + "originalArchive": "Original Archive", + "availabilityStatus": "Availability Status", + "contactForAccess": "Contact for Access", + "sizeOfCollection": "Size of Collection", + "studyCompletion": "Study Completion", + "dataAccessPlaceTip": "If the data is not only in Dataverse, list the location(s) where the data are currently stored.", + "originalArchiveTip": "Archive from which the data was obtained.", + "availabilityStatusTip": "Statement of Dataset availability. A depositor may need to indicate that a Dataset is unavailable because it is embargoed for a period of time, because it has been superseded, because a new edition is imminent, etc.", + "contactForAccessTip": "If different from the Dataset Contact, this is the Contact person or organization (include email or full address, and telephone number if available) that controls access to a collection.", + "sizeOfCollectionTip": "Summary of the number of physical files that exist in a Dataset, recording the number of files that contain data and noting whether the collection contains machine readable documentation and/or other supplementary files and information, such as code, data dictionaries, data definition statements, or data collection instruments.", + "studyCompletionTip": "Relationship of the data collected to the amount of data coded and stored in the Dataset. Information as to why certain items of collected information were not included in the dataset or a specific data file should be provided." }, "publish": { "draftQuestion": "Are you sure you want to publish this dataset? Once you do so, it must remain published.", diff --git a/src/sections/dataset/Dataset.tsx b/src/sections/dataset/Dataset.tsx index 62e3024c5..f148c9430 100644 --- a/src/sections/dataset/Dataset.tsx +++ b/src/sections/dataset/Dataset.tsx @@ -153,9 +153,13 @@ export function Dataset({ /> - +
- +
diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.module.scss b/src/sections/dataset/dataset-terms/DatasetTerms.module.scss index ab0acdaf9..970bfe03d 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.module.scss +++ b/src/sections/dataset/dataset-terms/DatasetTerms.module.scss @@ -3,3 +3,7 @@ justify-content: flex-end; margin-bottom: 1rem; } + +.dataset-terms-row { + margin-bottom: 20px; // Adjust the value as needed +} diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index 4893e2910..0567ba417 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -1,19 +1,26 @@ -import { Accordion } from '@iqss/dataverse-design-system' +import { Accordion, Col, Row } from '@iqss/dataverse-design-system' import { DatasetLicense, DatasetTermsOfUse } from '../../../dataset/domain/models/Dataset' import { License } from '@/sections/dataset/dataset-summary/License' import { EditDatasetTermsButton } from '@/sections/dataset/dataset-terms/EditDatasetTermsButton' +import { useTranslation } from 'react-i18next' +import { QuestionMarkTooltip } from '@iqss/dataverse-design-system' import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' interface DatasetTermsProps { license: DatasetLicense termsOfUse: DatasetTermsOfUse + numberOfRestrictedFiles: number } /* -{termsOfUse.termsOfAccess &&
termsOfUse.termsOfAccess
} - {termsOfUse.dataAccessPlace &&
termsOfUse.dataAccessPlace
} - + dataAccessPlace?: string + originalArchive?: string + availabilityStatus?: string + contactForAccess?: string + sizeOfCollection?: string + studyCompletion?: string */ export function DatasetTerms({ license, termsOfUse }: DatasetTermsProps) { + const { t } = useTranslation('dataset') return ( <>
@@ -21,19 +28,80 @@ export function DatasetTerms({ license, termsOfUse }: DatasetTermsProps) {
- License + {t('termsTab.licenseTitle')} - Terms of Use + {t('termsTab.termsTitle')} - {termsOfUse.termsOfAccess &&
{termsOfUse.termsOfAccess}
} - {termsOfUse.dataAccessPlace &&
{termsOfUse.dataAccessPlace}
} + + + + + +
) } + +interface DatasetTermsRowProps { + title: string + tooltipMessage: string + value: string | undefined +} + +const DatasetTermsRow = ({ title, tooltipMessage, value }: DatasetTermsRowProps) => { + if (value === undefined) { + return null + } + + return ( + + + <> + {title} + + + + + {value && ( +
+ { + //TODO: handle html in value + value + } +
+ )} + +
+ ) +} diff --git a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx index 6f996c6fe..31d52459c 100644 --- a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx +++ b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx @@ -26,7 +26,7 @@ export function EditDatasetTermsButton() { onClick={handleClick} icon={} disabled={dataset.checkIsLockedFromEdits(user.persistentId)}> - {t('terms.editTermsButton')} + {t('termsTab.editTermsButton')} ) } From 413fa43a31f0d67da5b3b73e79c0d2f306d4bd24 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Sun, 26 Jan 2025 22:13:38 -0500 Subject: [PATCH 04/45] feat: add restricted files related fields --- public/locales/en/dataset.json | 10 +++ src/sections/dataset/Dataset.tsx | 4 +- .../dataset/dataset-terms/DatasetTerms.tsx | 77 ++++++++++++++++--- 3 files changed, 79 insertions(+), 12 deletions(-) diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index c1264cdec..235da9e6f 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -121,12 +121,22 @@ "editTermsButton": "Edit Term Requirements", "licenseTitle": "Dataset Terms", "termsTitle": "Restricted Files + Terms of Access", + "restrictedFiles": "Restricted Files", + "termsOfAccess": "Terms of Access for Restricted Files", + "requestAccess": "Request Access", "dataAccessPlace": "Data Access Place", "originalArchive": "Original Archive", "availabilityStatus": "Availability Status", "contactForAccess": "Contact for Access", "sizeOfCollection": "Size of Collection", "studyCompletion": "Study Completion", + "restrictedFilesOne": "There is 1 restricted file in this dataset.", + "restrictedFilesMany": "There are {{count}} restricted files in this dataset.", + "termsOfAccessTip": "Information on how and if users can access restricted files in this Dataset", + "requestAccessTip": "If checked, users can request access to the restricted files in this dataset.", + "requestAccessTrue": "Users may request access to files.", + "requestAccessFalse": "Users may not request access to files.", + "restrictedFilesTip": "The number of restricted files in this dataset.", "dataAccessPlaceTip": "If the data is not only in Dataverse, list the location(s) where the data are currently stored.", "originalArchiveTip": "Archive from which the data was obtained.", "availabilityStatusTip": "Statement of Dataset availability. A depositor may need to indicate that a Dataset is unavailable because it is embargoed for a period of time, because it has been superseded, because a new edition is imminent, etc.", diff --git a/src/sections/dataset/Dataset.tsx b/src/sections/dataset/Dataset.tsx index f148c9430..8521596f4 100644 --- a/src/sections/dataset/Dataset.tsx +++ b/src/sections/dataset/Dataset.tsx @@ -158,7 +158,9 @@ export function Dataset({
diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index 0567ba417..61ad529ea 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -1,26 +1,48 @@ import { Accordion, Col, Row } from '@iqss/dataverse-design-system' -import { DatasetLicense, DatasetTermsOfUse } from '../../../dataset/domain/models/Dataset' +import { + DatasetLicense, + DatasetTermsOfUse, + DatasetVersion +} from '../../../dataset/domain/models/Dataset' import { License } from '@/sections/dataset/dataset-summary/License' import { EditDatasetTermsButton } from '@/sections/dataset/dataset-terms/EditDatasetTermsButton' import { useTranslation } from 'react-i18next' import { QuestionMarkTooltip } from '@iqss/dataverse-design-system' import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' +import { useGetFilesCountInfo } from '@/sections/dataset/dataset-files/useGetFilesCountInfo' +import { FileRepository } from '@/files/domain/repositories/FileRepository' +import { FileAccessCount } from '@/files/domain/models/FilesCountInfo' +import { FileAccessOption } from '@/files/domain/models/FileCriteria' interface DatasetTermsProps { license: DatasetLicense termsOfUse: DatasetTermsOfUse - numberOfRestrictedFiles: number + filesRepository: FileRepository + datasetPersistentId: string + datasetVersion: DatasetVersion } -/* - dataAccessPlace?: string - originalArchive?: string - availabilityStatus?: string - contactForAccess?: string - sizeOfCollection?: string - studyCompletion?: string - */ -export function DatasetTerms({ license, termsOfUse }: DatasetTermsProps) { + +export function DatasetTerms({ + license, + termsOfUse, + filesRepository, + datasetPersistentId, + datasetVersion +}: DatasetTermsProps) { const { t } = useTranslation('dataset') + const { + filesCountInfo, + isLoading: _isLoadingFilesCountInfo, + error: errorFilesCountInfo + } = useGetFilesCountInfo({ + filesRepository, + datasetPersistentId, + datasetVersion + }) + const restrictedFilesCount = filesCountInfo + ? numberOfRestrictedFiles(filesCountInfo.perAccess) + : 0 + return ( <>
@@ -36,6 +58,35 @@ export function DatasetTerms({ license, termsOfUse }: DatasetTermsProps) { {t('termsTab.termsTitle')} + {filesCountInfo && restrictedFilesCount > 0 && ( + <> + + + + + )} { + return fileAccessArray.find((access) => access.access === FileAccessOption.RESTRICTED)?.count || 0 +} + interface DatasetTermsRowProps { title: string tooltipMessage: string From 1750d0c8e5d4af18a5cd41d421294e817a088325 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 28 Jan 2025 12:13:15 -0500 Subject: [PATCH 05/45] feat: add help text to License.tsx, add display logic to Terms Tab --- public/locales/en/dataset.json | 1 + .../dataset/dataset-summary/License.tsx | 22 ++- .../dataset/dataset-terms/DatasetTerms.tsx | 143 +++++++------- .../dataset-terms/DatasetTerms.stories.tsx | 72 +++++++ .../FileMockNoRestrictedFilesRepository.ts | 29 +++ .../file/FileMockRestrictedFilesRepository.ts | 29 +++ .../dataset/domain/models/LicenseMother.ts | 12 ++ .../dataset/domain/models/TermsOfUseMother.ts | 19 ++ .../dataset-terms/DatasetTerms.spec.tsx | 175 ++++++++++++++++++ 9 files changed, 433 insertions(+), 69 deletions(-) create mode 100644 src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx create mode 100644 src/stories/file/FileMockNoRestrictedFilesRepository.ts create mode 100644 src/stories/file/FileMockRestrictedFilesRepository.ts create mode 100644 tests/component/dataset/domain/models/LicenseMother.ts create mode 100644 tests/component/dataset/domain/models/TermsOfUseMother.ts create mode 100644 tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index 235da9e6f..a94124af2 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -121,6 +121,7 @@ "editTermsButton": "Edit Term Requirements", "licenseTitle": "Dataset Terms", "termsTitle": "Restricted Files + Terms of Access", + "licenseHelpText": "Our Community Norms as well as good scientific practices expect that proper credit is given via citation. Please use the data citation shown on the dataset page.", "restrictedFiles": "Restricted Files", "termsOfAccess": "Terms of Access for Restricted Files", "requestAccess": "Request Access", diff --git a/src/sections/dataset/dataset-summary/License.tsx b/src/sections/dataset/dataset-summary/License.tsx index 69c5cc057..5e899dca4 100644 --- a/src/sections/dataset/dataset-summary/License.tsx +++ b/src/sections/dataset/dataset-summary/License.tsx @@ -1,12 +1,13 @@ import { Row, Col } from '@iqss/dataverse-design-system' import { DatasetLicense as LicenseModel } from '../../../dataset/domain/models/Dataset' -import { useTranslation } from 'react-i18next' +import { Trans, useTranslation } from 'react-i18next' interface LicenseProps { license: LicenseModel + includeHelpText?: boolean } -export function License({ license }: LicenseProps) { +export function License({ license, includeHelpText = false }: LicenseProps) { const { t } = useTranslation('dataset') return ( @@ -15,6 +16,23 @@ export function License({ license }: LicenseProps) { {t('license.title')} + {includeHelpText && ( +
+ + ) + }} + /> +
+ )} {license.iconUri && ( {t(`license.altTextPrefix`) value === undefined || typeof value === 'boolean' + ) + if (isLoading) { + return + } return ( <>
- + {t('termsTab.licenseTitle')} - - - - - {t('termsTab.termsTitle')} - - {filesCountInfo && restrictedFilesCount > 0 && ( - <> - - - - - )} - - - - - - + + {!termsOfUseIsEmpty && ( + + {t('termsTab.termsTitle')} + + {filesCountInfo && restrictedFilesCount > 0 && ( + <> + + + + + )} + + + + + + + + + )} ) diff --git a/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx b/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx new file mode 100644 index 000000000..bb23e2264 --- /dev/null +++ b/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx @@ -0,0 +1,72 @@ +import { Meta, StoryObj } from '@storybook/react' +import { WithI18next } from '../../WithI18next' +import { DatasetTerms } from '../../../sections/dataset/dataset-terms/DatasetTerms' +import { FileMockRepository } from '../../file/FileMockRepository' +import { FileMockLoadingRepository } from '../../file/FileMockLoadingRepository' +//import { FileMockNoRestrictedFilesRepository } from '../../file/FileMockNoRestrictedFilesRepository' +import { DatasetMother } from '../../../../tests/component/dataset/domain/models/DatasetMother' +import { LicenseMother } from '../../../../tests/component/dataset/domain/models/LicenseMother' +import { TermsOfUseMother } from '../../../../tests/component/dataset/domain/models/TermsOfUseMother' +import { FileMockRestrictedFilesRepository } from '@/stories/file/FileMockRestrictedFilesRepository' +import { FileMockNoRestrictedFilesRepository } from '@/stories/file/FileMockNoRestrictedFilesRepository' + +const meta: Meta = { + title: 'Sections/Dataset Page/DatasetTerms', + component: DatasetTerms, + decorators: [WithI18next] +} + +export default meta +type Story = StoryObj + +const testDataset = DatasetMother.createRealistic() +const license = LicenseMother.create() +const termsOfUse = TermsOfUseMother.create() + +export const Default: Story = { + render: () => ( + + ) +} + +export const Loading: Story = { + render: () => ( + + ) +} + +export const RestrictedFiles: Story = { + render: () => ( + + ) +} + +export const NoRestrictedFiles: Story = { + render: () => ( + + ) +} diff --git a/src/stories/file/FileMockNoRestrictedFilesRepository.ts b/src/stories/file/FileMockNoRestrictedFilesRepository.ts new file mode 100644 index 000000000..8dfd101df --- /dev/null +++ b/src/stories/file/FileMockNoRestrictedFilesRepository.ts @@ -0,0 +1,29 @@ +import { FileRepository } from '../../files/domain/repositories/FileRepository' +import { FilesCountInfo } from '../../files/domain/models/FilesCountInfo' +import { FilesCountInfoMother } from '../../../tests/component/files/domain/models/FilesCountInfoMother' +import { FileAccessOption } from '../../files/domain/models/FileCriteria' +import { FileMockRepository } from './FileMockRepository' +import { DatasetVersionNumber } from '@/dataset/domain/models/Dataset' + +export class FileMockNoRestrictedFilesRepository + extends FileMockRepository + implements FileRepository +{ + getFilesCountInfoByDatasetPersistentId( + _datasetPersistentId: string, + _datasetVersionNumber: DatasetVersionNumber + ): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve( + FilesCountInfoMother.create({ + perAccess: [ + { access: FileAccessOption.PUBLIC, count: 222 }, + { access: FileAccessOption.RESTRICTED, count: 0 } + ] + }) + ) + }, 1000) + }) + } +} diff --git a/src/stories/file/FileMockRestrictedFilesRepository.ts b/src/stories/file/FileMockRestrictedFilesRepository.ts new file mode 100644 index 000000000..beecf7e15 --- /dev/null +++ b/src/stories/file/FileMockRestrictedFilesRepository.ts @@ -0,0 +1,29 @@ +import { FileRepository } from '../../files/domain/repositories/FileRepository' +import { FilesCountInfo } from '../../files/domain/models/FilesCountInfo' +import { FilesCountInfoMother } from '../../../tests/component/files/domain/models/FilesCountInfoMother' +import { FileAccessOption } from '../../files/domain/models/FileCriteria' +import { FileMockRepository } from './FileMockRepository' +import { DatasetVersionNumber } from '@/dataset/domain/models/Dataset' + +export class FileMockRestrictedFilesRepository + extends FileMockRepository + implements FileRepository +{ + getFilesCountInfoByDatasetPersistentId( + _datasetPersistentId: string, + _datasetVersionNumber: DatasetVersionNumber + ): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve( + FilesCountInfoMother.create({ + perAccess: [ + { access: FileAccessOption.PUBLIC, count: 222 }, + { access: FileAccessOption.RESTRICTED, count: 10 } + ] + }) + ) + }, 1000) + }) + } +} diff --git a/tests/component/dataset/domain/models/LicenseMother.ts b/tests/component/dataset/domain/models/LicenseMother.ts new file mode 100644 index 000000000..1d5e95910 --- /dev/null +++ b/tests/component/dataset/domain/models/LicenseMother.ts @@ -0,0 +1,12 @@ +import { DatasetLicense } from '../../../../../src/dataset/domain/models/Dataset' +export class LicenseMother { + static create(props?: Partial): DatasetLicense { + const defaultLicense: DatasetLicense = { + name: 'CC0 1.0', + uri: 'https://creativecommons.org/publicdomain/zero/1.0/', + iconUri: 'https://licensebuttons.net/p/zero/1.0/88x31.png' + } + + return { ...defaultLicense, ...props } + } +} diff --git a/tests/component/dataset/domain/models/TermsOfUseMother.ts b/tests/component/dataset/domain/models/TermsOfUseMother.ts new file mode 100644 index 000000000..bd8ef5226 --- /dev/null +++ b/tests/component/dataset/domain/models/TermsOfUseMother.ts @@ -0,0 +1,19 @@ +import { faker } from '@faker-js/faker' +import { DatasetTermsOfUse } from '../../../../../src/dataset/domain/models/Dataset' + +export class TermsOfUseMother { + static create(props?: Partial): DatasetTermsOfUse { + const defaultTerms: DatasetTermsOfUse = { + termsOfAccess: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), + fileAccessRequest: true, + dataAccessPlace: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), + originalArchive: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), + availabilityStatus: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), + contactForAccess: 'support@example.com', + sizeOfCollection: '10 GB', + studyCompletion: '2023-01-01' + } + + return { ...defaultTerms, ...props } + } +} diff --git a/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx new file mode 100644 index 000000000..3c6417c5f --- /dev/null +++ b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx @@ -0,0 +1,175 @@ +import { FilesCountInfoMother } from '../../../files/domain/models/FilesCountInfoMother' +import { DatasetTerms } from '../../../../../src/sections/dataset/dataset-terms/DatasetTerms' +import { FileRepository } from '../../../../../src/files/domain/repositories/FileRepository' +import { FileAccessOption } from '../../../../../src/files/domain/models/FileCriteria' +import { DatasetMother } from '../../../dataset/domain/models/DatasetMother' +import { LicenseMother } from '../../../dataset/domain/models/LicenseMother' +import { TermsOfUseMother } from '../../../dataset/domain/models/TermsOfUseMother' + +const datasetPersistentId = 'test-dataset-persistent-id' +const datasetVersion = DatasetMother.create().version +const fileRepository: FileRepository = {} as FileRepository +const testFilesCountInfo = FilesCountInfoMother.create({ + perAccess: [ + { access: FileAccessOption.PUBLIC, count: 222 }, + { access: FileAccessOption.RESTRICTED, count: 10 } + ] +}) +const license = LicenseMother.create() +const termsOfUse = TermsOfUseMother.create() + +describe('DatasetTerms', () => { + beforeEach(() => { + fileRepository.getFilesCountInfoByDatasetPersistentId = cy.stub().resolves(testFilesCountInfo) + }) + + it('renders the license and terms of use sections', () => { + cy.customMount( + + ) + + cy.findByText('License').should('exist') + cy.findByText('Terms').should('exist') + }) + + it('renders the correct number of restricted files', () => { + cy.customMount( + + ) + + cy.findByText('Restricted Files').should('exist') + cy.findByText('10 files are restricted.').should('exist') + }) + + it('renders the terms of access', () => { + cy.customMount( + + ) + + cy.findByText('Terms of Access').should('exist') + cy.findByText(termsOfUse.termsOfAccess as string).should('exist') + }) + + it('renders the request access information', () => { + cy.customMount( + + ) + + cy.findByText('Request Access').should('exist') + cy.findByText(termsOfUse.fileAccessRequest ? 'Yes' : 'No').should('exist') + }) + + it('renders the data access place', () => { + cy.customMount( + + ) + + cy.findByText('Data Access Place').should('exist') + cy.findByText(termsOfUse.dataAccessPlace as string).should('exist') + }) + + it('renders the original archive information', () => { + cy.customMount( + + ) + + cy.findByText('Original Archive').should('exist') + cy.findByText(termsOfUse.originalArchive as string).should('exist') + }) + + it('renders the availability status', () => { + cy.customMount( + + ) + + cy.findByText('Availability Status').should('exist') + cy.findByText(termsOfUse.availabilityStatus as string).should('exist') + }) + + it('renders the contact for access information', () => { + cy.customMount( + + ) + + cy.findByText('Contact for Access').should('exist') + cy.findByText(termsOfUse.contactForAccess as string).should('exist') + }) + + it('renders the size of collection information', () => { + cy.customMount( + + ) + + cy.findByText('Size of Collection').should('exist') + cy.findByText(termsOfUse.sizeOfCollection as string).should('exist') + }) + + it('renders the study completion information', () => { + cy.customMount( + + ) + + cy.findByText('Study Completion').should('exist') + cy.findByText(termsOfUse.studyCompletion as string).should('exist') + }) +}) From 33eabf64d234bf38a42098c80f50955bba536bc3 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 28 Jan 2025 14:49:32 -0500 Subject: [PATCH 06/45] feat: add tests for Tab display logic and Edit Terms button --- .../dataset-terms/EditDatasetTermsButton.tsx | 1 + .../dataset/domain/models/TermsOfUseMother.ts | 12 +++ .../dataset-terms/DatasetTerms.spec.tsx | 58 +++++++++++++-- .../EditDatasetTermsButton.spec.tsx | 73 +++++++++++++++++++ 4 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx diff --git a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx index 31d52459c..f23ec6569 100644 --- a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx +++ b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx @@ -17,6 +17,7 @@ export function EditDatasetTermsButton() { } const handleClick = () => { + console.log('calling showModal') showModal() } diff --git a/tests/component/dataset/domain/models/TermsOfUseMother.ts b/tests/component/dataset/domain/models/TermsOfUseMother.ts index bd8ef5226..1b79afd6e 100644 --- a/tests/component/dataset/domain/models/TermsOfUseMother.ts +++ b/tests/component/dataset/domain/models/TermsOfUseMother.ts @@ -16,4 +16,16 @@ export class TermsOfUseMother { return { ...defaultTerms, ...props } } + static createEmpty(): DatasetTermsOfUse { + return { + termsOfAccess: undefined, + fileAccessRequest: false, + dataAccessPlace: undefined, + originalArchive: undefined, + availabilityStatus: undefined, + contactForAccess: undefined, + sizeOfCollection: undefined, + studyCompletion: undefined + } + } } diff --git a/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx index 3c6417c5f..a3fd9ccf7 100644 --- a/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx +++ b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx @@ -1,7 +1,7 @@ import { FilesCountInfoMother } from '../../../files/domain/models/FilesCountInfoMother' -import { DatasetTerms } from '../../../../../src/sections/dataset/dataset-terms/DatasetTerms' -import { FileRepository } from '../../../../../src/files/domain/repositories/FileRepository' -import { FileAccessOption } from '../../../../../src/files/domain/models/FileCriteria' +import { DatasetTerms } from '@/sections/dataset/dataset-terms/DatasetTerms' +import { FileRepository } from '@/files/domain/repositories/FileRepository' +import { FileAccessOption } from '@/files/domain/models/FileCriteria' import { DatasetMother } from '../../../dataset/domain/models/DatasetMother' import { LicenseMother } from '../../../dataset/domain/models/LicenseMother' import { TermsOfUseMother } from '../../../dataset/domain/models/TermsOfUseMother' @@ -15,8 +15,16 @@ const testFilesCountInfo = FilesCountInfoMother.create({ { access: FileAccessOption.RESTRICTED, count: 10 } ] }) +const noRestrictedFilesCountInfo = FilesCountInfoMother.create({ + perAccess: [ + { access: FileAccessOption.PUBLIC, count: 222 }, + { access: FileAccessOption.RESTRICTED, count: 0 } + ] +}) + const license = LicenseMother.create() const termsOfUse = TermsOfUseMother.create() +const emptyTermsOfUse = TermsOfUseMother.createEmpty() describe('DatasetTerms', () => { beforeEach(() => { @@ -34,8 +42,8 @@ describe('DatasetTerms', () => { /> ) - cy.findByText('License').should('exist') - cy.findByText('Terms').should('exist') + cy.findByText('Dataset Terms').should('exist') + cy.findByText('Restricted Files + Terms of Access').should('exist') }) it('renders the correct number of restricted files', () => { @@ -50,7 +58,7 @@ describe('DatasetTerms', () => { ) cy.findByText('Restricted Files').should('exist') - cy.findByText('10 files are restricted.').should('exist') + cy.findByText('There are 10 restricted files in this dataset.').should('exist') }) it('renders the terms of access', () => { @@ -64,7 +72,7 @@ describe('DatasetTerms', () => { /> ) - cy.findByText('Terms of Access').should('exist') + cy.findByText('Terms of Access for Restricted Files').should('exist') cy.findByText(termsOfUse.termsOfAccess as string).should('exist') }) @@ -80,7 +88,11 @@ describe('DatasetTerms', () => { ) cy.findByText('Request Access').should('exist') - cy.findByText(termsOfUse.fileAccessRequest ? 'Yes' : 'No').should('exist') + cy.findByText( + termsOfUse.fileAccessRequest + ? 'Users may request access to files.' + : 'Users may not request access to files.' + ).should('exist') }) it('renders the data access place', () => { @@ -172,4 +184,34 @@ describe('DatasetTerms', () => { cy.findByText('Study Completion').should('exist') cy.findByText(termsOfUse.studyCompletion as string).should('exist') }) + it('does not render the terms of use AccordionItem if terms of use fields are empty', () => { + cy.customMount( + + ) + + cy.findByText('Restricted Files + Terms of Access').should('not.exist') + }) + it('does not render Request Access field if there are no restricted files', () => { + fileRepository.getFilesCountInfoByDatasetPersistentId = cy + .stub() + .resolves(noRestrictedFilesCountInfo) + cy.customMount( + + ) + + cy.findByText('Request Access').should('not.exist') + cy.findByText('Terms of Access for Restricted Files').should('not.exist') + }) }) diff --git a/tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx b/tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx new file mode 100644 index 000000000..513dbc738 --- /dev/null +++ b/tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx @@ -0,0 +1,73 @@ +import { EditDatasetTermsButton } from '@/sections/dataset/dataset-terms/EditDatasetTermsButton' +import { ReactNode } from 'react' +import { DatasetProvider } from '@/sections/dataset/DatasetProvider' +import { UserMother } from '@tests/component/users/domain/models/UserMother' +import { + DatasetMother, + DatasetPermissionsMother +} from '@tests/component/dataset/domain/models/DatasetMother' +import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' +import { Dataset } from '@/dataset/domain/models/Dataset' +import { NotImplementedModalProvider } from '@/sections/not-implemented/NotImplementedModalProvider' +const datasetRepository: DatasetRepository = {} as DatasetRepository + +describe('EditDatasetTermsButton', () => { + const withProviders = (component: ReactNode, dataset: Dataset | undefined) => { + datasetRepository.getByPersistentId = cy.stub().resolves(dataset) + datasetRepository.getByPrivateUrlToken = cy.stub().resolves(dataset) + + return ( + + {component} + + ) + } + + it('renders the EditDatasetTermsButton if the user has permission to update the dataset', () => { + const user = UserMother.create() + const dataset = DatasetMother.create({ + permissions: DatasetPermissionsMother.createWithUpdateDatasetAllowed() + }) + + cy.mountAuthenticated(withProviders(, dataset)) + + cy.findByRole('button', { name: 'Edit Term Requirements' }).should('exist') + }) + + it('does not render the EditDatasetTermsButton if the user does not have permission to update the dataset', () => { + const dataset = DatasetMother.create({ + permissions: DatasetPermissionsMother.createWithNoneAllowed() + }) + + cy.mountAuthenticated(withProviders(, dataset)) + + cy.findByRole('button', { name: 'Edit Term Requirements' }).should('not.exist') + }) + + it('does not render the EditDatasetTermsButton if there is no user', () => { + const dataset = DatasetMother.create({ + permissions: DatasetPermissionsMother.createWithUpdateDatasetAllowed() + }) + + cy.customMount(withProviders(, dataset)) + + cy.findByRole('button', { name: 'Edit Term Requirements' }).should('not.exist') + }) + + // TODO: test the button click by mocking the showModal function + it('calls showModal when the button is clicked', () => { + const dataset = DatasetMother.create({ + permissions: DatasetPermissionsMother.createWithUpdateDatasetAllowed() + }) + cy.mountAuthenticated(withProviders(, dataset)) + + cy.spy(console, 'log').as('consoleLogSpy') + cy.findByRole('button', { name: 'Edit Term Requirements' }) + .click() + .then(() => { + cy.get('@consoleLogSpy').should('have.been.calledWith', 'calling showModal') + }) + }) +}) From 7b2cb5b5da2ba3024ac20251d37d53c6326342ab Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 28 Jan 2025 16:01:57 -0500 Subject: [PATCH 07/45] fix: JSDatasetMapper.spec.ts --- .../mappers/JSDatasetMapper.spec.ts | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts b/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts index 8a66746f1..44608e682 100644 --- a/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts +++ b/tests/component/dataset/infrastructure/mappers/JSDatasetMapper.spec.ts @@ -37,6 +37,16 @@ const jsDataset = { lastUpdateTime: new Date('2023-09-07T13:40:04.000Z'), releaseTime: undefined }, + termsOfUse: { + fileAccessRequest: true, + termsOfAccess: 'New terms', + dataAccessPlace: 'New place', + originalArchive: 'New archive', + availabilityStatus: 'New status', + contactForAccess: 'New contact', + sizeOfCollection: 'New size', + studyCompletion: 'New completion' + }, metadataBlocks: [ { name: 'citation', @@ -226,6 +236,16 @@ const expectedDataset = { uri: 'http://creativecommons.org/publicdomain/zero/1.0', iconUri: 'https://licensebuttons.net/p/zero/1.0/88x31.png' }, + termsOfUse: { + fileAccessRequest: true, + termsOfAccess: 'New terms', + dataAccessPlace: 'New place', + originalArchive: 'New archive', + availabilityStatus: 'New status', + contactForAccess: 'New contact', + sizeOfCollection: 'New size', + studyCompletion: 'New completion' + }, metadataBlocks: [ { name: 'citation', @@ -325,6 +345,16 @@ const expectedDatasetWithPublicationDate = { uri: 'http://creativecommons.org/publicdomain/zero/1.0', iconUri: 'https://licensebuttons.net/p/zero/1.0/88x31.png' }, + termsOfUse: { + fileAccessRequest: true, + termsOfAccess: 'New terms', + dataAccessPlace: 'New place', + originalArchive: 'New archive', + availabilityStatus: 'New status', + contactForAccess: 'New contact', + sizeOfCollection: 'New size', + studyCompletion: 'New completion' + }, metadataBlocks: [ { name: 'citation', @@ -425,6 +455,16 @@ const expectedDatasetWithNextVersionNumbers = { uri: 'http://creativecommons.org/publicdomain/zero/1.0', iconUri: 'https://licensebuttons.net/p/zero/1.0/88x31.png' }, + termsOfUse: { + fileAccessRequest: true, + termsOfAccess: 'New terms', + dataAccessPlace: 'New place', + originalArchive: 'New archive', + availabilityStatus: 'New status', + contactForAccess: 'New contact', + sizeOfCollection: 'New size', + studyCompletion: 'New completion' + }, metadataBlocks: [ { name: 'citation', @@ -548,6 +588,16 @@ const expectedDatasetAlternateVersion = { uri: 'http://creativecommons.org/publicdomain/zero/1.0', iconUri: 'https://licensebuttons.net/p/zero/1.0/88x31.png' }, + termsOfUse: { + fileAccessRequest: true, + termsOfAccess: 'New terms', + dataAccessPlace: 'New place', + originalArchive: 'New archive', + availabilityStatus: 'New status', + contactForAccess: 'New contact', + sizeOfCollection: 'New size', + studyCompletion: 'New completion' + }, locks: [ { userPersistentId: 'dataverseAdmin', From c55ad3ac88256569feb2d05703f6243bf4a49971 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 28 Jan 2025 16:06:32 -0500 Subject: [PATCH 08/45] feat: Add test of Terms Tab to Dataset.spec.tsx --- .../sections/dataset/Dataset.spec.tsx | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/component/sections/dataset/Dataset.spec.tsx b/tests/component/sections/dataset/Dataset.spec.tsx index c77b5e2b5..73b1edaba 100644 --- a/tests/component/sections/dataset/Dataset.spec.tsx +++ b/tests/component/sections/dataset/Dataset.spec.tsx @@ -212,6 +212,28 @@ describe('Dataset', () => { cy.findByText('Citation Metadata').should('exist') }) + it('renders the Dataset Terms tab', () => { + const testDataset = DatasetMother.create() + + mountWithDataset( + , + testDataset + ) + + cy.findAllByText(testDataset.version.title).should('exist') + + const termsTab = cy.findByRole('tab', { name: 'Terms' }) + termsTab.should('exist') + + termsTab.click() + + cy.findByText('Dataset Terms').should('exist') + }) it('renders the Dataset in anonymized view', () => { const testDatasetAnonymized = DatasetMother.createAnonymized() From c21d3e31f0b55ee5dabaa4d8006a48f2da3fdf8b Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 28 Jan 2025 16:55:45 -0500 Subject: [PATCH 09/45] test: increase code coverage --- .../dataset-terms/DatasetTerms.spec.tsx | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx index a3fd9ccf7..4415887e8 100644 --- a/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx +++ b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx @@ -21,10 +21,19 @@ const noRestrictedFilesCountInfo = FilesCountInfoMother.create({ { access: FileAccessOption.RESTRICTED, count: 0 } ] }) +const singleRestrictedFilesCountInfo = FilesCountInfoMother.create({ + perAccess: [ + { access: FileAccessOption.PUBLIC, count: 222 }, + { access: FileAccessOption.RESTRICTED, count: 1 } + ] +}) const license = LicenseMother.create() const termsOfUse = TermsOfUseMother.create() const emptyTermsOfUse = TermsOfUseMother.createEmpty() +const accessAllowedTermsOfUse = TermsOfUseMother.create({ fileAccessRequest: true }) +const accessNotAllowedTermsOfUse = TermsOfUseMother.create({ fileAccessRequest: false }) +const termsOfUseWithUndefinedValue = TermsOfUseMother.create({ dataAccessPlace: undefined }) describe('DatasetTerms', () => { beforeEach(() => { @@ -60,7 +69,37 @@ describe('DatasetTerms', () => { cy.findByText('Restricted Files').should('exist') cy.findByText('There are 10 restricted files in this dataset.').should('exist') }) + it('does not render a row if the value is undefined', () => { + cy.customMount( + + ) + + cy.findByText('Restricted Files + Terms of Access').should('exist') + cy.findByText('Data Access Place').should('not.exist') + }) + it('renders the one restricted file message', () => { + fileRepository.getFilesCountInfoByDatasetPersistentId = cy + .stub() + .resolves(singleRestrictedFilesCountInfo) + cy.customMount( + + ) + cy.findByText('Restricted Files').should('exist') + cy.findByText('There is 1 restricted file in this dataset.').should('exist') + }) it('renders the terms of access', () => { cy.customMount( { cy.findByText(termsOfUse.termsOfAccess as string).should('exist') }) - it('renders the request access information', () => { + it('renders the request access allowed message', () => { cy.customMount( + ) + + cy.findByText('Request Access').should('exist') + cy.findByText('Users may request access to files.').should('exist') + }) + it('renders the request access not allowed message', () => { + cy.customMount( + { ) cy.findByText('Request Access').should('exist') - cy.findByText( - termsOfUse.fileAccessRequest - ? 'Users may request access to files.' - : 'Users may not request access to files.' - ).should('exist') + cy.findByText('Users may not request access to files.').should('exist') }) it('renders the data access place', () => { From cf29bc3f1dd41e680a1a79baea4fbb8c2505eb42 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 31 Jan 2025 11:51:56 -0500 Subject: [PATCH 10/45] feat: add custom terms --- package.json | 2 +- public/locales/en/dataset.json | 16 ++++++ src/dataset/domain/models/Dataset.ts | 8 +++ .../dataset-terms/DatasetTerms.module.scss | 3 +- .../dataset/dataset-terms/DatasetTerms.tsx | 55 +++++++++++++++---- 5 files changed, 71 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 6dccac6a2..d13efb415 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr243.ce1c24b", + "@iqss/dataverse-client-javascript": "2.0.0-pr248.8d38663", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index a94124af2..f5a7af620 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -131,6 +131,22 @@ "contactForAccess": "Contact for Access", "sizeOfCollection": "Size of Collection", "studyCompletion": "Study Completion", + "termsOfUse": "Terms of Use", + "termsOfUseTip": "The terms of use for this dataset.", + "confidentialityDeclaration": "Confidentiality Declaration", + "specialPermissions": "Special Permissions", + "restrictions": "Restrictions", + "citationRequirements": "Citation Requirements", + "depositorRequirements": "Depositor Requirements", + "conditions": "Conditions", + "disclaimer": "Disclaimer", + "declarationTip": "Indicates whether signing of a confidentiality declaration is needed to access a resource.", + "specialPermissionsTip": "Determine if any special permissions are required to access a resource (e.g., if form is a needed and where to access the form).", + "restrictionsTip": "Any restrictions on access to or use of the collection, such as privacy certification or distribution restrictions, should be indicated here. These can be restrictions applied by the author, producer, or disseminator of the data collection. If the data are restricted to only a certain class of user, specify which type.", + "citationRequirementsTip": "Include special/explicit citation requirements for data to be cited properly in articles or other publications that are based on analysis of the data. For standard data citation requirements refer to our Community Norms.", + "depositorRequirementsTip": "Information regarding user responsibility for informing Dataset Depositors, Authors or Curators of their use of data through providing citations to the published work or providing copies of the manuscripts.", + "conditionsTip": "Any additional information that will assist the user in understanding the access and use conditions of the Dataset.", + "disclaimerTip": "Information regarding responsibility for uses of the Dataset.", "restrictedFilesOne": "There is 1 restricted file in this dataset.", "restrictedFilesMany": "There are {{count}} restricted files in this dataset.", "termsOfAccessTip": "Information on how and if users can access restricted files in this Dataset", diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts index 7b429e829..cde0c1c80 100644 --- a/src/dataset/domain/models/Dataset.ts +++ b/src/dataset/domain/models/Dataset.ts @@ -376,6 +376,14 @@ export interface DatasetTermsOfUse { contactForAccess?: string sizeOfCollection?: string studyCompletion?: string + termsOfUse?: string + confidentialityDeclaration?: string + specialPermissions?: string + restrictions?: string + citationRequirements?: string + depositorRequirements?: string + conditions?: string + disclaimer?: string } export class Dataset { diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.module.scss b/src/sections/dataset/dataset-terms/DatasetTerms.module.scss index 970bfe03d..97b8e1da9 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.module.scss +++ b/src/sections/dataset/dataset-terms/DatasetTerms.module.scss @@ -5,5 +5,6 @@ } .dataset-terms-row { - margin-bottom: 20px; // Adjust the value as needed + margin-top: 1rem; + margin-bottom: 1rem; } diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index 8668be174..beb2f833b 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -8,12 +8,13 @@ import { License } from '@/sections/dataset/dataset-summary/License' import { EditDatasetTermsButton } from '@/sections/dataset/dataset-terms/EditDatasetTermsButton' import { useTranslation } from 'react-i18next' import { QuestionMarkTooltip } from '@iqss/dataverse-design-system' -import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' import { useGetFilesCountInfo } from '@/sections/dataset/dataset-files/useGetFilesCountInfo' import { FileRepository } from '@/files/domain/repositories/FileRepository' import { FileAccessCount } from '@/files/domain/models/FilesCountInfo' import { FileAccessOption } from '@/files/domain/models/FileCriteria' import { SpinnerSymbol } from '@/sections/dataset/dataset-files/files-table/spinner-symbol/SpinnerSymbol' +import { MarkdownComponent } from '@/sections/dataset/markdown/MarkdownComponent' +import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' interface DatasetTermsProps { license: DatasetLicense @@ -50,6 +51,7 @@ export function DatasetTerms({ if (isLoading) { return } + return ( <>
@@ -60,6 +62,46 @@ export function DatasetTerms({ {t('termsTab.licenseTitle')} + + + + + + + + {!termsOfUseIsEmpty && ( @@ -156,16 +198,7 @@ const DatasetTermsRow = ({ title, tooltipMessage, value }: DatasetTermsRowProps) - - {value && ( -
- { - //TODO: handle html in value - value - } -
- )} - + {value &&
{}
} ) } From f42ab278351e66121498756e39d5503ba1863f15 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 31 Jan 2025 12:42:42 -0500 Subject: [PATCH 11/45] feat: move contents of terms tab to separate components --- .../dataset/dataset-terms/DatasetTerms.tsx | 135 ++---------------- .../dataset/dataset-terms/DatasetTermsRow.tsx | 28 ++++ .../dataset/dataset-terms/LicenseTerms.tsx | 86 +++++++++++ .../dataset/dataset-terms/TermsOfAccess.tsx | 93 ++++++++++++ 4 files changed, 215 insertions(+), 127 deletions(-) create mode 100644 src/sections/dataset/dataset-terms/DatasetTermsRow.tsx create mode 100644 src/sections/dataset/dataset-terms/LicenseTerms.tsx create mode 100644 src/sections/dataset/dataset-terms/TermsOfAccess.tsx diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index beb2f833b..5ea48a101 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -1,19 +1,18 @@ -import { Accordion, Col, Row } from '@iqss/dataverse-design-system' +import { Accordion } from '@iqss/dataverse-design-system' import { DatasetLicense, DatasetTermsOfUse, DatasetVersion } from '../../../dataset/domain/models/Dataset' -import { License } from '@/sections/dataset/dataset-summary/License' import { EditDatasetTermsButton } from '@/sections/dataset/dataset-terms/EditDatasetTermsButton' import { useTranslation } from 'react-i18next' -import { QuestionMarkTooltip } from '@iqss/dataverse-design-system' import { useGetFilesCountInfo } from '@/sections/dataset/dataset-files/useGetFilesCountInfo' import { FileRepository } from '@/files/domain/repositories/FileRepository' import { FileAccessCount } from '@/files/domain/models/FilesCountInfo' import { FileAccessOption } from '@/files/domain/models/FileCriteria' import { SpinnerSymbol } from '@/sections/dataset/dataset-files/files-table/spinner-symbol/SpinnerSymbol' -import { MarkdownComponent } from '@/sections/dataset/markdown/MarkdownComponent' +import { LicenseTerms } from '@/sections/dataset/dataset-terms/LicenseTerms' +import { TermsOfAccess } from '@/sections/dataset/dataset-terms/TermsOfAccess' import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' interface DatasetTermsProps { @@ -61,111 +60,17 @@ export function DatasetTerms({ {t('termsTab.licenseTitle')} - - - - - - - - - + {!termsOfUseIsEmpty && ( {t('termsTab.termsTitle')} - {filesCountInfo && restrictedFilesCount > 0 && ( - <> - - - - - )} - - - - - - @@ -178,27 +83,3 @@ export function DatasetTerms({ const numberOfRestrictedFiles = (fileAccessArray: FileAccessCount[]): number => { return fileAccessArray.find((access) => access.access === FileAccessOption.RESTRICTED)?.count || 0 } - -interface DatasetTermsRowProps { - title: string - tooltipMessage: string - value: string | undefined -} - -const DatasetTermsRow = ({ title, tooltipMessage, value }: DatasetTermsRowProps) => { - if (value === undefined) { - return null - } - - return ( - - - <> - {title} - - - - {value &&
{}
} -
- ) -} diff --git a/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx b/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx new file mode 100644 index 000000000..4f5e05ad1 --- /dev/null +++ b/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx @@ -0,0 +1,28 @@ +import { Col, Row } from '@iqss/dataverse-design-system' +import { QuestionMarkTooltip } from '@iqss/dataverse-design-system' +import { MarkdownComponent } from '@/sections/dataset/markdown/MarkdownComponent' +import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' + +interface DatasetTermsRowProps { + title: string + tooltipMessage: string + value: string | undefined +} + +export function DatasetTermsRow({ title, tooltipMessage, value }: DatasetTermsRowProps) { + if (value === undefined) { + return null + } + + return ( + + + <> + {title} + + + + {value &&
{}
} +
+ ) +} diff --git a/src/sections/dataset/dataset-terms/LicenseTerms.tsx b/src/sections/dataset/dataset-terms/LicenseTerms.tsx new file mode 100644 index 000000000..4d4cbf2af --- /dev/null +++ b/src/sections/dataset/dataset-terms/LicenseTerms.tsx @@ -0,0 +1,86 @@ +import { DatasetLicense } from '../../../dataset/domain/models/Dataset' +import { License } from '@/sections/dataset/dataset-summary/License' +import { useTranslation } from 'react-i18next' +import { DatasetTermsRow } from '@/sections/dataset/dataset-terms/DatasetTermsRow' + +interface LicenseTermsProps { + license: DatasetLicense + termsOfUse?: string + confidentialityDeclaration?: string + specialPermissions?: string + restrictions?: string + citationRequirements?: string + depositorRequirements?: string + conditions?: string + disclaimer?: string +} +interface LicenseTermsProps { + license: DatasetLicense + termsOfUse?: string + confidentialityDeclaration?: string + specialPermissions?: string + restrictions?: string + citationRequirements?: string + depositorRequirements?: string + conditions?: string + disclaimer?: string +} +export function LicenseTerms({ + license, + termsOfUse, + confidentialityDeclaration, + specialPermissions, + restrictions, + citationRequirements, + depositorRequirements, + conditions, + disclaimer +}: LicenseTermsProps) { + const { t } = useTranslation('dataset') + + return ( + <> + + + + + + + + + + + ) +} diff --git a/src/sections/dataset/dataset-terms/TermsOfAccess.tsx b/src/sections/dataset/dataset-terms/TermsOfAccess.tsx new file mode 100644 index 000000000..4a0835db2 --- /dev/null +++ b/src/sections/dataset/dataset-terms/TermsOfAccess.tsx @@ -0,0 +1,93 @@ +import { useTranslation } from 'react-i18next' +import { DatasetTermsRow } from './DatasetTermsRow' +import { FilesCountInfo } from '@/files/domain/models/FilesCountInfo' + +interface TermsOfAccessProps { + termsOfAccess?: string | undefined + fileAccessRequest: boolean + dataAccessPlace?: string + originalArchive?: string + availabilityStatus?: string + contactForAccess?: string + sizeOfCollection?: string + studyCompletion?: string + filesCountInfo: FilesCountInfo | undefined + restrictedFilesCount: number +} + +export function TermsOfAccess({ + termsOfAccess, + fileAccessRequest, + dataAccessPlace, + originalArchive, + availabilityStatus, + contactForAccess, + sizeOfCollection, + studyCompletion, + filesCountInfo, + restrictedFilesCount +}: TermsOfAccessProps) { + const { t } = useTranslation('dataset') + + return ( + <> + {filesCountInfo && restrictedFilesCount > 0 && ( + <> + + + + + )} + + + + + + + + ) +} From 0aa98643af7db2530ebfef18ceb9d577743a1f61 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 31 Jan 2025 15:06:40 -0500 Subject: [PATCH 12/45] feat: update logic for Dataset with custom terms --- public/locales/en/dataset.json | 1 + src/dataset/domain/models/Dataset.ts | 6 +-- .../infrastructure/mappers/JSDatasetMapper.ts | 2 +- .../dataset-summary/DatasetSummary.tsx | 2 +- .../dataset/dataset-summary/License.tsx | 35 ++++--------- .../dataset-terms/DatasetTerms.module.scss | 7 +++ .../dataset/dataset-terms/DatasetTerms.tsx | 2 +- .../dataset/dataset-terms/License.tsx | 51 +++++++++++++++++++ .../dataset/dataset-terms/LicenseTerms.tsx | 8 +-- .../DatasetSummary.stories.tsx | 2 +- .../dataset/domain/models/DatasetMother.ts | 2 +- .../dataset-summary/DatasetSummary.spec.tsx | 4 +- 12 files changed, 83 insertions(+), 39 deletions(-) create mode 100644 src/sections/dataset/dataset-terms/License.tsx diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index f5a7af620..277177883 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -122,6 +122,7 @@ "licenseTitle": "Dataset Terms", "termsTitle": "Restricted Files + Terms of Access", "licenseHelpText": "Our Community Norms as well as good scientific practices expect that proper credit is given via citation. Please use the data citation shown on the dataset page.", + "customTermsHelpText": "Custom Dataset Terms — the following Custom Dataset Terms have been defined for this dataset.", "restrictedFiles": "Restricted Files", "termsOfAccess": "Terms of Access for Restricted Files", "requestAccess": "Request Access", diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts index cde0c1c80..d25194cf2 100644 --- a/src/dataset/domain/models/Dataset.ts +++ b/src/dataset/domain/models/Dataset.ts @@ -392,7 +392,6 @@ export class Dataset { public readonly version: DatasetVersion, public readonly alerts: Alert[], public readonly summaryFields: DatasetMetadataBlock[], - public readonly license: DatasetLicense, public readonly termsOfUse: DatasetTermsOfUse, public readonly metadataBlocks: DatasetMetadataBlocks, public readonly permissions: DatasetPermissions, @@ -403,6 +402,7 @@ export class Dataset { public readonly downloadUrls: DatasetDownloadUrls, public readonly fileDownloadSizes: FileDownloadSize[], public readonly hierarchy: UpwardHierarchyNode, + public readonly license?: DatasetLicense, public readonly thumbnail?: string, public readonly privateUrl?: PrivateUrl, // will be set if the user requested a version that did not exist public readonly requestedVersion?: string, @@ -485,7 +485,6 @@ export class Dataset { public readonly persistentId: string, public readonly version: DatasetVersion, public readonly summaryFields: DatasetMetadataBlock[], - public readonly license: DatasetLicense = defaultLicense, public readonly termsOfUse: DatasetTermsOfUse, public readonly metadataBlocks: DatasetMetadataBlocks, public readonly permissions: DatasetPermissions, @@ -496,6 +495,7 @@ export class Dataset { public readonly downloadUrls: DatasetDownloadUrls, public readonly fileDownloadSizes: FileDownloadSize[], public readonly hierarchy: UpwardHierarchyNode, + public readonly license?: DatasetLicense, public readonly thumbnail?: string, public readonly privateUrl?: PrivateUrl, // will be set if the user requested a version that did not exist @@ -554,7 +554,6 @@ export class Dataset { this.version, this.alerts, this.summaryFields, - this.license, this.termsOfUse, this.metadataBlocks, this.permissions, @@ -565,6 +564,7 @@ export class Dataset { this.downloadUrls, this.fileDownloadSizes, this.hierarchy, + this.license, this.thumbnail, this.privateUrl, this.requestedVersion, diff --git a/src/dataset/infrastructure/mappers/JSDatasetMapper.ts b/src/dataset/infrastructure/mappers/JSDatasetMapper.ts index c63d604e1..6ff8a979c 100644 --- a/src/dataset/infrastructure/mappers/JSDatasetMapper.ts +++ b/src/dataset/infrastructure/mappers/JSDatasetMapper.ts @@ -60,7 +60,6 @@ export class JSDatasetMapper { jsDataset.persistentId, version, JSDatasetMapper.toSummaryFields(jsDataset.metadataBlocks, jsDatasetSummaryFieldsNames), - jsDataset.license, jsDataset.termsOfUse, JSDatasetMapper.toMetadataBlocks( jsDataset.metadataBlocks, @@ -84,6 +83,7 @@ export class JSDatasetMapper { version, jsDataset.isPartOf ), + jsDataset.license, undefined, // TODO: get dataset thumbnail from js-dataverse https://github.com/IQSS/dataverse-frontend/issues/203 privateUrl, requestedVersion, diff --git a/src/sections/dataset/dataset-summary/DatasetSummary.tsx b/src/sections/dataset/dataset-summary/DatasetSummary.tsx index 2d18e7d57..6d941f43c 100644 --- a/src/sections/dataset/dataset-summary/DatasetSummary.tsx +++ b/src/sections/dataset/dataset-summary/DatasetSummary.tsx @@ -5,7 +5,7 @@ import { MetadataBlockInfoRepository } from '../../../metadata-block-info/domain interface DatasetSummaryProps { summaryFields: DatasetMetadataBlock[] - license: DatasetLicense + license: DatasetLicense | undefined metadataBlockInfoRepository: MetadataBlockInfoRepository } diff --git a/src/sections/dataset/dataset-summary/License.tsx b/src/sections/dataset/dataset-summary/License.tsx index 5e899dca4..90181ba5f 100644 --- a/src/sections/dataset/dataset-summary/License.tsx +++ b/src/sections/dataset/dataset-summary/License.tsx @@ -1,13 +1,12 @@ import { Row, Col } from '@iqss/dataverse-design-system' import { DatasetLicense as LicenseModel } from '../../../dataset/domain/models/Dataset' -import { Trans, useTranslation } from 'react-i18next' +import { useTranslation } from 'react-i18next' interface LicenseProps { - license: LicenseModel - includeHelpText?: boolean + license: LicenseModel | undefined } -export function License({ license, includeHelpText = false }: LicenseProps) { +export function License({ license }: LicenseProps) { const { t } = useTranslation('dataset') return ( @@ -16,24 +15,7 @@ export function License({ license, includeHelpText = false }: LicenseProps) { {t('license.title')} - {includeHelpText && ( -
- - ) - }} - /> -
- )} - {license.iconUri && ( + {license && license.iconUri && ( {t(`license.altTextPrefix`) )} - - {license.name} - + {license && ( + + {license.name} + + )} + {!license && {'Custom Terms'}} ) diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.module.scss b/src/sections/dataset/dataset-terms/DatasetTerms.module.scss index 97b8e1da9..3e15f48eb 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.module.scss +++ b/src/sections/dataset/dataset-terms/DatasetTerms.module.scss @@ -1,3 +1,5 @@ +@import 'node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module'; + .edit-terms-button-container { display: flex; justify-content: flex-end; @@ -8,3 +10,8 @@ margin-top: 1rem; margin-bottom: 1rem; } + +.community-norms-text { + margin: 10px 0; + color: $dv-subtext-color; +} diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index 5ea48a101..f006906af 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -16,7 +16,7 @@ import { TermsOfAccess } from '@/sections/dataset/dataset-terms/TermsOfAccess' import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' interface DatasetTermsProps { - license: DatasetLicense + license: DatasetLicense | undefined termsOfUse: DatasetTermsOfUse filesRepository: FileRepository datasetPersistentId: string diff --git a/src/sections/dataset/dataset-terms/License.tsx b/src/sections/dataset/dataset-terms/License.tsx new file mode 100644 index 000000000..c62fe27c3 --- /dev/null +++ b/src/sections/dataset/dataset-terms/License.tsx @@ -0,0 +1,51 @@ +import { Row, Col } from '@iqss/dataverse-design-system' +import { DatasetLicense as LicenseModel } from '../../../dataset/domain/models/Dataset' +import { Trans, useTranslation } from 'react-i18next' +import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' + +interface LicenseProps { + license: LicenseModel | undefined +} + +export function License({ license }: LicenseProps) { + const { t } = useTranslation('dataset') + + return ( + + + {t('license.title')} + + +
+ + ) + }} + /> +
+ {license && license.iconUri && ( + {t(`license.altTextPrefix`) + )} + {license && ( + + {license.name} + + )} + {!license && {t('termsTab.customTermsHelpText')}} + +
+ ) +} diff --git a/src/sections/dataset/dataset-terms/LicenseTerms.tsx b/src/sections/dataset/dataset-terms/LicenseTerms.tsx index 4d4cbf2af..b181b4c4b 100644 --- a/src/sections/dataset/dataset-terms/LicenseTerms.tsx +++ b/src/sections/dataset/dataset-terms/LicenseTerms.tsx @@ -1,10 +1,10 @@ import { DatasetLicense } from '../../../dataset/domain/models/Dataset' -import { License } from '@/sections/dataset/dataset-summary/License' +import { License } from '@/sections/dataset/dataset-terms/License' import { useTranslation } from 'react-i18next' import { DatasetTermsRow } from '@/sections/dataset/dataset-terms/DatasetTermsRow' interface LicenseTermsProps { - license: DatasetLicense + license?: DatasetLicense termsOfUse?: string confidentialityDeclaration?: string specialPermissions?: string @@ -15,7 +15,7 @@ interface LicenseTermsProps { disclaimer?: string } interface LicenseTermsProps { - license: DatasetLicense + license?: DatasetLicense termsOfUse?: string confidentialityDeclaration?: string specialPermissions?: string @@ -40,7 +40,7 @@ export function LicenseTerms({ return ( <> - + = { decorators: [WithI18next] } -const licenseMock: DatasetLicense = DatasetMother.createRealistic().license +const licenseMock: DatasetLicense = DatasetMother.createRealistic().license! const summaryFieldsMock: DatasetMetadataBlock[] = DatasetMother.createRealistic().summaryFields export default meta type Story = StoryObj diff --git a/tests/component/dataset/domain/models/DatasetMother.ts b/tests/component/dataset/domain/models/DatasetMother.ts index 7d3ba6350..a18665890 100644 --- a/tests/component/dataset/domain/models/DatasetMother.ts +++ b/tests/component/dataset/domain/models/DatasetMother.ts @@ -433,7 +433,6 @@ export class DatasetMother { dataset.persistentId, dataset.version, dataset.summaryFields, - dataset.license, dataset.termsOfUse, dataset.metadataBlocks, dataset.permissions, @@ -444,6 +443,7 @@ export class DatasetMother { dataset.downloadUrls, dataset.fileDownloadSizes, dataset.hierarchy, + dataset.license, dataset.thumbnail, dataset.privateUrl, dataset.requestedVersion diff --git a/tests/component/sections/dataset/dataset-summary/DatasetSummary.spec.tsx b/tests/component/sections/dataset/dataset-summary/DatasetSummary.spec.tsx index 779fb1ec6..93ddec699 100644 --- a/tests/component/sections/dataset/dataset-summary/DatasetSummary.spec.tsx +++ b/tests/component/sections/dataset/dataset-summary/DatasetSummary.spec.tsx @@ -8,7 +8,7 @@ import { MetadataBlockInfoRepository } from '../../../../../src/metadata-block-i import { MetadataBlockInfoMother } from '../../../metadata-block-info/domain/models/MetadataBlockInfoMother' describe('DatasetSummary', () => { - const licenseMock: DatasetLicense = DatasetMother.create().license + const licenseMock: DatasetLicense | undefined = DatasetMother.create().license const summaryFieldsMock: DatasetMetadataBlock[] = DatasetMother.create().summaryFields const metadataBlockInfoMock = MetadataBlockInfoMother.create() const metadataBlockInfoRepository: MetadataBlockInfoRepository = {} as MetadataBlockInfoRepository @@ -35,7 +35,7 @@ describe('DatasetSummary', () => { }) cy.get('img').should('exist') - cy.findByText(licenseMock.name).should('exist') + licenseMock && cy.findByText(licenseMock.name).should('exist') }) it('renders an empty span if there is an error getting the metadata block display info', () => { From 2f08fc91d3749bde26f7d2d85b10a7060b3228c9 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Mon, 3 Feb 2025 18:39:55 -0500 Subject: [PATCH 13/45] feat: add search param for active tab, and update Custom Terms link so it sets the active tab='terms' --- package-lock.json | 8 ++--- .../src/lib/components/tabs/Tabs.tsx | 30 +++++++++++++++---- src/sections/dataset/Dataset.tsx | 20 +++++++++---- src/sections/dataset/DatasetFactory.tsx | 3 ++ .../dataset-summary/DatasetSummary.tsx | 6 ++-- .../dataset/dataset-summary/License.tsx | 12 +++++--- .../DatasetSummary.stories.tsx | 1 + 7 files changed, 60 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 890a9f7ef..b9a1464c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr243.ce1c24b", + "@iqss/dataverse-client-javascript": "2.0.0-pr248.8d38663", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", @@ -3674,9 +3674,9 @@ }, "node_modules/@iqss/dataverse-client-javascript": { "name": "@IQSS/dataverse-client-javascript", - "version": "2.0.0-pr243.ce1c24b", - "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr243.ce1c24b/f23dada5c3bac33044c0c718305d5b0104e18ce5", - "integrity": "sha512-gT2GOZyxHN0JlbpSAQquPJoaaYzLBzdZZUi+ltpR5rrlvidro9zU8V+o68FrZbPiMXxsAMADl81a+Mvb+1YFuQ==", + "version": "2.0.0-pr248.8d38663", + "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr248.8d38663/136220d05c98acfdc4653a860ab4089d631ff044", + "integrity": "sha512-PV45ylv2RuSGNaHI97Ljknaqsa1PCsXQtiKhITR2vMjHfs0ibgXCi5xveSoWfCXhNSWqSklrWvGjZCXD58CpVQ==", "dependencies": { "@types/node": "^18.15.11", "@types/turndown": "^5.0.1", diff --git a/packages/design-system/src/lib/components/tabs/Tabs.tsx b/packages/design-system/src/lib/components/tabs/Tabs.tsx index a68a5f96a..8496bda8d 100644 --- a/packages/design-system/src/lib/components/tabs/Tabs.tsx +++ b/packages/design-system/src/lib/components/tabs/Tabs.tsx @@ -1,15 +1,35 @@ -import { PropsWithChildren } from 'react' +import { PropsWithChildren, useEffect, useState } from 'react' import { Tab } from './Tab' import { Tabs as TabsBS } from 'react-bootstrap' interface TabsProps { defaultActiveKey: string + onSelect?: (key: string | null) => void } -function Tabs({ defaultActiveKey, children }: PropsWithChildren) { - return {children} -} +function Tabs({ defaultActiveKey, onSelect, children }: PropsWithChildren) { + const [key, setKey] = useState(defaultActiveKey) -Tabs.Tab = Tab + useEffect(() => { + if (defaultActiveKey) { + setKey(defaultActiveKey) + } + }, [defaultActiveKey]) + + const handleSelect = (k: string | null) => { + if (k) { + setKey(k) + if (onSelect) { + onSelect(k) + } + } + } + return ( + + {children} + + ) +} +Tabs.Tab = Tab export { Tabs } diff --git a/src/sections/dataset/Dataset.tsx b/src/sections/dataset/Dataset.tsx index 8521596f4..45921d87c 100644 --- a/src/sections/dataset/Dataset.tsx +++ b/src/sections/dataset/Dataset.tsx @@ -1,4 +1,4 @@ -import { useEffect } from 'react' +import { useEffect, useState } from 'react' import { Col, Row, Tabs } from '@iqss/dataverse-design-system' import styles from './Dataset.module.scss' import { useNavigate } from 'react-router-dom' @@ -37,6 +37,7 @@ interface DatasetProps { metadataUpdated?: boolean filesTabInfiniteScrollEnabled?: boolean publishInProgress?: boolean + tab?: string } export function Dataset({ @@ -47,7 +48,8 @@ export function Dataset({ created, metadataUpdated, filesTabInfiniteScrollEnabled, - publishInProgress + publishInProgress, + tab = 'files' }: DatasetProps) { const { setIsLoading } = useLoading() const { dataset, isLoading: isDatasetLoading } = useDataset() @@ -55,7 +57,7 @@ export function Dataset({ const navigate = useNavigate() const { hideModal, isModalOpen } = useNotImplementedModal() const publishCompleted = useCheckPublishCompleted(publishInProgress, dataset, datasetRepository) - + const [activeTab, setActiveTab] = useState(tab) useUpdateDatasetAlerts({ dataset, created, @@ -79,7 +81,14 @@ export function Dataset({ if (isDatasetLoading && !dataset) { return } - + const handleCustomTermsClick = () => { + setActiveTab('terms') + } + const handleTabSelect = (key: string | null) => { + if (key) { + setActiveTab(key) + } + } return ( <> @@ -119,6 +128,7 @@ export function Dataset({ @@ -126,7 +136,7 @@ export function Dataset({ {publishInProgress && } {(!publishInProgress || !isDatasetLoading) && ( - +
{filesTabInfiniteScrollEnabled ? ( diff --git a/src/sections/dataset/DatasetFactory.tsx b/src/sections/dataset/DatasetFactory.tsx index 5d70637b5..4caa3e5e0 100644 --- a/src/sections/dataset/DatasetFactory.tsx +++ b/src/sections/dataset/DatasetFactory.tsx @@ -48,6 +48,7 @@ function DatasetWithSearchParams() { const persistentId = searchParams.get('persistentId') ?? undefined const privateUrlToken = searchParams.get('privateUrlToken') const searchParamVersion = searchParams.get('version') ?? undefined + const tab = searchParams.get('tab') ?? undefined const version = searchParamVersionToDomainVersion(searchParamVersion) const location = useLocation() const state = location.state as @@ -73,6 +74,7 @@ function DatasetWithSearchParams() { fileRepository={fileRepository} metadataBlockInfoRepository={metadataBlockInfoRepository} filesTabInfiniteScrollEnabled={FILES_TAB_INFINITE_SCROLL_ENABLED} + tab={tab} /> ) @@ -92,6 +94,7 @@ function DatasetWithSearchParams() { publishInProgress={publishInProgress} metadataUpdated={metadataUpdated} filesTabInfiniteScrollEnabled={FILES_TAB_INFINITE_SCROLL_ENABLED} + tab={tab} /> ) diff --git a/src/sections/dataset/dataset-summary/DatasetSummary.tsx b/src/sections/dataset/dataset-summary/DatasetSummary.tsx index 6d941f43c..e59c63b1e 100644 --- a/src/sections/dataset/dataset-summary/DatasetSummary.tsx +++ b/src/sections/dataset/dataset-summary/DatasetSummary.tsx @@ -7,12 +7,14 @@ interface DatasetSummaryProps { summaryFields: DatasetMetadataBlock[] license: DatasetLicense | undefined metadataBlockInfoRepository: MetadataBlockInfoRepository + onCustomTermsClick: () => void } export function DatasetSummary({ summaryFields, license, - metadataBlockInfoRepository + metadataBlockInfoRepository, + onCustomTermsClick }: DatasetSummaryProps) { return ( <> @@ -20,7 +22,7 @@ export function DatasetSummary({ summaryFields={summaryFields} metadataBlockInfoRepository={metadataBlockInfoRepository} /> - + ) } diff --git a/src/sections/dataset/dataset-summary/License.tsx b/src/sections/dataset/dataset-summary/License.tsx index 90181ba5f..f3ad1077e 100644 --- a/src/sections/dataset/dataset-summary/License.tsx +++ b/src/sections/dataset/dataset-summary/License.tsx @@ -1,12 +1,13 @@ -import { Row, Col } from '@iqss/dataverse-design-system' +import { Row, Col, Button } from '@iqss/dataverse-design-system' import { DatasetLicense as LicenseModel } from '../../../dataset/domain/models/Dataset' import { useTranslation } from 'react-i18next' interface LicenseProps { license: LicenseModel | undefined + onCustomTermsClick?: () => void } -export function License({ license }: LicenseProps) { +export function License({ license, onCustomTermsClick }: LicenseProps) { const { t } = useTranslation('dataset') return ( @@ -23,12 +24,15 @@ export function License({ license }: LicenseProps) { style={{ marginRight: '0.5rem' }} /> )} - {license && ( + {license ? ( {license.name} + ) : ( + )} - {!license && {'Custom Terms'}} ) diff --git a/src/stories/dataset/dataset-summary/DatasetSummary.stories.tsx b/src/stories/dataset/dataset-summary/DatasetSummary.stories.tsx index c6537740a..1ef025ccb 100644 --- a/src/stories/dataset/dataset-summary/DatasetSummary.stories.tsx +++ b/src/stories/dataset/dataset-summary/DatasetSummary.stories.tsx @@ -22,6 +22,7 @@ export const Default: Story = { summaryFields={summaryFieldsMock} license={licenseMock} metadataBlockInfoRepository={new MetadataBlockInfoMockRepository()} + onCustomTermsClick={() => console.log('Custom terms clicked')} /> ) } From 1cc7752b390a46ab507ddffde72616027cad4839 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 4 Feb 2025 14:07:52 -0500 Subject: [PATCH 14/45] feat: updates and refactoring required to show Custom License link in PublishDatasetModal.tsx --- .github/CONTRIBUTING.md | 2 +- merged-coverage/lcov.info | 2 +- src/sections/Route.enum.ts | 13 +++++++++- src/sections/dataset/Dataset.tsx | 8 +++++- .../dataset-summary/DatasetSummary.tsx | 4 +-- .../{License.tsx => SummaryLicense.tsx} | 2 +- .../{LicenseTerms.tsx => CustomTerms.tsx} | 3 +-- .../dataset/dataset-terms/DatasetTerms.tsx | 6 +++-- .../publish-dataset/PublishDatasetModal.tsx | 26 +++++++++---------- .../sections/dataset/Dataset.spec.tsx | 22 ++++++++++++++++ ...icense.spec.tsx => SummaryLicenseSpec.tsx} | 8 +++--- 11 files changed, 68 insertions(+), 28 deletions(-) rename src/sections/dataset/dataset-summary/{License.tsx => SummaryLicense.tsx} (92%) rename src/sections/dataset/dataset-terms/{LicenseTerms.tsx => CustomTerms.tsx} (97%) rename tests/component/sections/dataset/dataset-summary/{License.spec.tsx => SummaryLicenseSpec.tsx} (69%) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 5388afa9c..941450bad 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Guidance on how to contribute -> All contributions to this project will be released under the Apache License, Version 2.0. +> All contributions to this project will be released under the Apache SummaryLicense, Version 2.0. > By submitting a pull request or filing a bug, issue, or > feature request, you are agreeing to comply with this waiver of copyright interest. > Details can be found in our [LICENSE](/LICENSE). diff --git a/merged-coverage/lcov.info b/merged-coverage/lcov.info index 209781ecc..32fd70df7 100644 --- a/merged-coverage/lcov.info +++ b/merged-coverage/lcov.info @@ -2412,7 +2412,7 @@ DA:17,201 DA:26,16 BRDA:1,0,0,16 end_of_record -SF:src/sections/dataset/dataset-summary/License.tsx +SF:src/sections/dataset/dataset-summary/SummaryLicense.tsx DA:9,332 DA:10,332 DA:12,327 diff --git a/src/sections/Route.enum.ts b/src/sections/Route.enum.ts index 2a04b4be5..4e94f6de9 100644 --- a/src/sections/Route.enum.ts +++ b/src/sections/Route.enum.ts @@ -19,6 +19,16 @@ export const RouteWithParams = { COLLECTIONS: (collectionId?: string) => collectionId ? `/collections/${collectionId}` : Route.COLLECTIONS_BASE, CREATE_COLLECTION: (parentCollectionId: string) => `/collections/${parentCollectionId}/create`, + DATASETS: (persistentId: string, version?: string, tab?: string): string => { + let url = `${Route.DATASETS}?${QueryParamKey.PERSISTENT_ID}=${persistentId}` + if (version) { + url += `&${QueryParamKey.VERSION}=${version}` + } + if (tab) { + url += `&${QueryParamKey.TAB}=${tab}` + } + return url + }, CREATE_DATASET: (collectionId: string) => `/datasets/${collectionId}/create`, EDIT_COLLECTION: (collectionId: string) => `/collections/${collectionId}/edit` } @@ -27,5 +37,6 @@ export enum QueryParamKey { VERSION = 'version', PERSISTENT_ID = 'persistentId', PAGE = 'page', - COLLECTION_ID = 'collectionId' + COLLECTION_ID = 'collectionId', + TAB = 'tab' } diff --git a/src/sections/dataset/Dataset.tsx b/src/sections/dataset/Dataset.tsx index 45921d87c..6e2195681 100644 --- a/src/sections/dataset/Dataset.tsx +++ b/src/sections/dataset/Dataset.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react' import { Col, Row, Tabs } from '@iqss/dataverse-design-system' import styles from './Dataset.module.scss' -import { useNavigate } from 'react-router-dom' +import { useNavigate, useSearchParams } from 'react-router-dom' import { DatasetLabels } from './dataset-labels/DatasetLabels' import { useLoading } from '../loading/LoadingContext' import { DatasetSkeleton, TabsSkeleton } from './DatasetSkeleton' @@ -55,6 +55,7 @@ export function Dataset({ const { dataset, isLoading: isDatasetLoading } = useDataset() const { t } = useTranslation('dataset') const navigate = useNavigate() + const [searchParams] = useSearchParams() const { hideModal, isModalOpen } = useNotImplementedModal() const publishCompleted = useCheckPublishCompleted(publishInProgress, dataset, datasetRepository) const [activeTab, setActiveTab] = useState(tab) @@ -83,7 +84,12 @@ export function Dataset({ } const handleCustomTermsClick = () => { setActiveTab('terms') + const newParams = new URLSearchParams(searchParams) + newParams.set('tab', 'terms') + // Update URL without reloading + navigate(`?${newParams.toString()}`, { replace: true }) } + const handleTabSelect = (key: string | null) => { if (key) { setActiveTab(key) diff --git a/src/sections/dataset/dataset-summary/DatasetSummary.tsx b/src/sections/dataset/dataset-summary/DatasetSummary.tsx index e59c63b1e..5c7fbed78 100644 --- a/src/sections/dataset/dataset-summary/DatasetSummary.tsx +++ b/src/sections/dataset/dataset-summary/DatasetSummary.tsx @@ -1,6 +1,6 @@ import { SummaryFields } from './SummaryFields' import { DatasetLicense, DatasetMetadataBlock } from '../../../dataset/domain/models/Dataset' -import { License } from './License' +import { SummaryLicense } from './SummaryLicense' import { MetadataBlockInfoRepository } from '../../../metadata-block-info/domain/repositories/MetadataBlockInfoRepository' interface DatasetSummaryProps { @@ -22,7 +22,7 @@ export function DatasetSummary({ summaryFields={summaryFields} metadataBlockInfoRepository={metadataBlockInfoRepository} /> - + ) } diff --git a/src/sections/dataset/dataset-summary/License.tsx b/src/sections/dataset/dataset-summary/SummaryLicense.tsx similarity index 92% rename from src/sections/dataset/dataset-summary/License.tsx rename to src/sections/dataset/dataset-summary/SummaryLicense.tsx index f3ad1077e..142e2ddc1 100644 --- a/src/sections/dataset/dataset-summary/License.tsx +++ b/src/sections/dataset/dataset-summary/SummaryLicense.tsx @@ -7,7 +7,7 @@ interface LicenseProps { onCustomTermsClick?: () => void } -export function License({ license, onCustomTermsClick }: LicenseProps) { +export function SummaryLicense({ license, onCustomTermsClick }: LicenseProps) { const { t } = useTranslation('dataset') return ( diff --git a/src/sections/dataset/dataset-terms/LicenseTerms.tsx b/src/sections/dataset/dataset-terms/CustomTerms.tsx similarity index 97% rename from src/sections/dataset/dataset-terms/LicenseTerms.tsx rename to src/sections/dataset/dataset-terms/CustomTerms.tsx index b181b4c4b..51a437bf1 100644 --- a/src/sections/dataset/dataset-terms/LicenseTerms.tsx +++ b/src/sections/dataset/dataset-terms/CustomTerms.tsx @@ -25,7 +25,7 @@ interface LicenseTermsProps { conditions?: string disclaimer?: string } -export function LicenseTerms({ +export function CustomTerms({ license, termsOfUse, confidentialityDeclaration, @@ -40,7 +40,6 @@ export function LicenseTerms({ return ( <> - {t('termsTab.licenseTitle')} - + + {!termsOfUseIsEmpty && ( diff --git a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx index 4b5cc1941..83673de86 100644 --- a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx +++ b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx @@ -1,23 +1,21 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' +import { useNavigate } from 'react-router-dom' import { Button, Modal, Stack } from '@iqss/dataverse-design-system' import { Form } from '@iqss/dataverse-design-system' import type { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' import { VersionUpdateType } from '@/dataset/domain/models/VersionUpdateType' import { useSession } from '../../session/SessionContext' -import { License } from '../dataset-summary/License' -import { - DatasetNonNumericVersionSearchParam, - defaultLicense -} from '@/dataset/domain/models/Dataset' +import { SummaryLicense } from '../dataset-summary/SummaryLicense' +import { DatasetNonNumericVersionSearchParam } from '@/dataset/domain/models/Dataset' import { SubmissionStatus } from '../../shared/form/DatasetMetadataForm/useSubmitDataset' +import { QueryParamKey, Route } from '../../Route.enum' import { usePublishDataset } from './usePublishDataset' import { PublishDatasetHelpText } from './PublishDatasetHelpText' -import styles from './PublishDatasetModal.module.scss' -import { useNavigate } from 'react-router-dom' -import { QueryParamKey, Route } from '../../Route.enum' import { CollectionRepository } from '@/collection/domain/repositories/CollectionRepository' import { UpwardHierarchyNode } from '@/shared/hierarchy/domain/models/UpwardHierarchyNode' +import { DatasetLicense } from '@/dataset/domain/models/Dataset' +import styles from './PublishDatasetModal.module.scss' interface PublishDatasetModalProps { show: boolean @@ -25,6 +23,7 @@ interface PublishDatasetModalProps { collectionRepository: CollectionRepository parentCollection: UpwardHierarchyNode persistentId: string + license: DatasetLicense releasedVersionExists: boolean handleClose: () => void nextMajorVersion?: string @@ -38,6 +37,7 @@ export function PublishDatasetModal({ collectionRepository, parentCollection, persistentId, + license, releasedVersionExists, handleClose, nextMajorVersion, @@ -120,11 +120,11 @@ export function PublishDatasetModal({ )} - { + const termsUrl = `${Route.DATASETS}?${QueryParamKey.PERSISTENT_ID}=${persistentId}&${QueryParamKey.VERSION}=${DatasetNonNumericVersionSearchParam.DRAFT}&${QueryParamKey.TAB}=terms` + window.open(termsUrl, '_blank') }} />

{t('publish.termsText')}

diff --git a/tests/component/sections/dataset/Dataset.spec.tsx b/tests/component/sections/dataset/Dataset.spec.tsx index 73b1edaba..c8feefd12 100644 --- a/tests/component/sections/dataset/Dataset.spec.tsx +++ b/tests/component/sections/dataset/Dataset.spec.tsx @@ -234,7 +234,29 @@ describe('Dataset', () => { cy.findByText('Dataset Terms').should('exist') }) + it('renders the Dataset Terms tab', () => { + const testDataset = DatasetMother.create() + mountWithDataset( + , + testDataset + ) + + cy.findAllByText(testDataset.version.title).should('exist') + + const termsTab = cy.findByRole('tab', { name: 'Terms' }) + termsTab.should('exist') + + termsTab.click() + + cy.findByText('Dataset Terms').should('exist') + }) it('renders the Dataset in anonymized view', () => { const testDatasetAnonymized = DatasetMother.createAnonymized() diff --git a/tests/component/sections/dataset/dataset-summary/License.spec.tsx b/tests/component/sections/dataset/dataset-summary/SummaryLicenseSpec.tsx similarity index 69% rename from tests/component/sections/dataset/dataset-summary/License.spec.tsx rename to tests/component/sections/dataset/dataset-summary/SummaryLicenseSpec.tsx index 47d9a336e..9714a97fb 100644 --- a/tests/component/sections/dataset/dataset-summary/License.spec.tsx +++ b/tests/component/sections/dataset/dataset-summary/SummaryLicenseSpec.tsx @@ -1,6 +1,6 @@ -import { License } from '../../../../../src/sections/dataset/dataset-summary/License' +import { SummaryLicense } from '@/sections/dataset/dataset-summary/SummaryLicense' -describe('License', () => { +describe('SummaryLicense', () => { it('renders the license information correctly', () => { const licenseMock = { name: 'Test License', @@ -8,9 +8,9 @@ describe('License', () => { uri: 'https://example.com/license' } - cy.customMount() + cy.customMount() - cy.findByText('License/Data Use Agreement').should('exist') + cy.findByText('SummaryLicense/Data Use Agreement').should('exist') cy.findByText(licenseMock.name).should('exist') cy.findByAltText(`License image for ${licenseMock.name}`) From e60b15c0f144834934fdcb0bc36c381fb2d85f68 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Wed, 5 Feb 2025 16:38:14 -0500 Subject: [PATCH 15/45] Feat: Add Custom License and Custom Terms of Use to PublishDatasetModal.tsx --- package-lock.json | 8 +-- package.json | 2 +- public/locales/en/dataset.json | 5 +- src/dataset/domain/models/Dataset.ts | 14 ++++- .../PublishDatasetMenu.tsx | 2 + .../dataset-summary/SummaryLicense.tsx | 2 +- .../dataset/dataset-terms/CustomTerms.tsx | 59 +++++------------ .../dataset/dataset-terms/DatasetTerms.tsx | 8 +-- .../dataset/dataset-terms/DatasetTermsRow.tsx | 1 + .../dataset/dataset-terms/License.tsx | 6 +- .../dataset/dataset-terms/TermsOfAccess.tsx | 36 ++++------- .../publish-dataset/PublishDatasetModal.tsx | 22 +++++-- .../publish-dataset/PublishLicense.tsx | 43 +++++++++++++ .../PublishDatasetModal.stories.tsx | 12 ++++ .../dataset/domain/models/DatasetMother.ts | 13 +--- .../dataset/domain/models/TermsOfUseMother.ts | 53 ++++++++++++---- .../dataset-terms/DatasetTerms.spec.tsx | 63 ++++++++++++------- 17 files changed, 215 insertions(+), 134 deletions(-) create mode 100644 src/sections/dataset/publish-dataset/PublishLicense.tsx diff --git a/package-lock.json b/package-lock.json index b9a1464c9..682aa792d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr248.8d38663", + "@iqss/dataverse-client-javascript": "2.0.0-pr252.03b7ae1", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", @@ -3674,9 +3674,9 @@ }, "node_modules/@iqss/dataverse-client-javascript": { "name": "@IQSS/dataverse-client-javascript", - "version": "2.0.0-pr248.8d38663", - "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr248.8d38663/136220d05c98acfdc4653a860ab4089d631ff044", - "integrity": "sha512-PV45ylv2RuSGNaHI97Ljknaqsa1PCsXQtiKhITR2vMjHfs0ibgXCi5xveSoWfCXhNSWqSklrWvGjZCXD58CpVQ==", + "version": "2.0.0-pr252.03b7ae1", + "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr252.03b7ae1/ddce8479b6e139ee548a6c8ac2e3bb5a9d730336", + "integrity": "sha512-U2uvTAidTY+hjDk5U72OemahYWugpHUu2F7mcklL1VSpeFrs25tb76U8UvkRIY9Roc5pCh6ydhgS8RK5NdJFCQ==", "dependencies": { "@types/node": "^18.15.11", "@types/turndown": "^5.0.1", diff --git a/package.json b/package.json index d13efb415..df49d81b5 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr248.8d38663", + "@iqss/dataverse-client-javascript": "2.0.0-pr252.03b7ae1", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index 277177883..637420ff0 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -3,6 +3,10 @@ "metadataTabTitle": "Metadata", "termsTabTitle": "Terms", "anonymizedFieldValue": "withheld", + "customTerms": { + "title": "Custom Dataset Terms", + "description": "The following custom terms have been defined for this dataset." + }, "license": { "title": "License/Data Use Agreement", "altTextPrefix": "License image for " @@ -122,7 +126,6 @@ "licenseTitle": "Dataset Terms", "termsTitle": "Restricted Files + Terms of Access", "licenseHelpText": "Our Community Norms as well as good scientific practices expect that proper credit is given via citation. Please use the data citation shown on the dataset page.", - "customTermsHelpText": "Custom Dataset Terms — the following Custom Dataset Terms have been defined for this dataset.", "restrictedFiles": "Restricted Files", "termsOfAccess": "Terms of Access for Restricted Files", "requestAccess": "Request Access", diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts index d25194cf2..f216fb281 100644 --- a/src/dataset/domain/models/Dataset.ts +++ b/src/dataset/domain/models/Dataset.ts @@ -367,16 +367,20 @@ export interface DatasetDownloadUrls { original: string archival: string } -export interface DatasetTermsOfUse { + +export interface TermsOfAccess { fileAccessRequest: boolean - termsOfAccess?: string + termsOfAccessForRestrictedFiles?: string dataAccessPlace?: string originalArchive?: string availabilityStatus?: string contactForAccess?: string sizeOfCollection?: string studyCompletion?: string - termsOfUse?: string +} + +export interface CustomTerms { + termsOfUse: string confidentialityDeclaration?: string specialPermissions?: string restrictions?: string @@ -385,6 +389,10 @@ export interface DatasetTermsOfUse { conditions?: string disclaimer?: string } +export interface DatasetTermsOfUse { + termsOfAccess: TermsOfAccess + customTermsOfUse?: CustomTerms +} export class Dataset { constructor( diff --git a/src/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.tsx b/src/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.tsx index 3e5737046..0d41fda44 100644 --- a/src/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.tsx +++ b/src/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.tsx @@ -44,6 +44,8 @@ export function PublishDatasetMenu({ collectionRepository={collectionRepository} parentCollection={dataset.parentCollectionNode} persistentId={dataset.persistentId} + license={dataset.license} + customTerms={dataset.termsOfUse.customTermsOfUse} releasedVersionExists={dataset.version.someDatasetVersionHasBeenReleased} nextMajorVersion={dataset.nextMajorVersion} nextMinorVersion={dataset.nextMinorVersion} diff --git a/src/sections/dataset/dataset-summary/SummaryLicense.tsx b/src/sections/dataset/dataset-summary/SummaryLicense.tsx index 142e2ddc1..215e62f4b 100644 --- a/src/sections/dataset/dataset-summary/SummaryLicense.tsx +++ b/src/sections/dataset/dataset-summary/SummaryLicense.tsx @@ -30,7 +30,7 @@ export function SummaryLicense({ license, onCustomTermsClick }: LicenseProps) { ) : ( )} diff --git a/src/sections/dataset/dataset-terms/CustomTerms.tsx b/src/sections/dataset/dataset-terms/CustomTerms.tsx index 51a437bf1..fb25d9628 100644 --- a/src/sections/dataset/dataset-terms/CustomTerms.tsx +++ b/src/sections/dataset/dataset-terms/CustomTerms.tsx @@ -1,84 +1,57 @@ -import { DatasetLicense } from '../../../dataset/domain/models/Dataset' -import { License } from '@/sections/dataset/dataset-terms/License' import { useTranslation } from 'react-i18next' import { DatasetTermsRow } from '@/sections/dataset/dataset-terms/DatasetTermsRow' +import { CustomTerms as CustomTermsModel } from '../../../dataset/domain/models/Dataset' -interface LicenseTermsProps { - license?: DatasetLicense - termsOfUse?: string - confidentialityDeclaration?: string - specialPermissions?: string - restrictions?: string - citationRequirements?: string - depositorRequirements?: string - conditions?: string - disclaimer?: string +interface CustomTermsProps { + customTerms?: CustomTermsModel } -interface LicenseTermsProps { - license?: DatasetLicense - termsOfUse?: string - confidentialityDeclaration?: string - specialPermissions?: string - restrictions?: string - citationRequirements?: string - depositorRequirements?: string - conditions?: string - disclaimer?: string -} -export function CustomTerms({ - license, - termsOfUse, - confidentialityDeclaration, - specialPermissions, - restrictions, - citationRequirements, - depositorRequirements, - conditions, - disclaimer -}: LicenseTermsProps) { - const { t } = useTranslation('dataset') +export function CustomTerms({ customTerms }: CustomTermsProps) { + const { t } = useTranslation('dataset') + if (!customTerms) { + return null + } return ( <> ) diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index 5a00681f5..0be025ae5 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -44,7 +44,7 @@ export function DatasetTerms({ const restrictedFilesCount = filesCountInfo ? numberOfRestrictedFiles(filesCountInfo.perAccess) : 0 - const termsOfUseIsEmpty = Object.values(termsOfUse).every( + const termsOfAccessIsEmpty = Object.values(termsOfUse.termsOfAccess).every( (value) => value === undefined || typeof value === 'boolean' ) @@ -62,15 +62,15 @@ export function DatasetTerms({ {t('termsTab.licenseTitle')} - + - {!termsOfUseIsEmpty && ( + {!termsOfAccessIsEmpty && ( {t('termsTab.termsTitle')} diff --git a/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx b/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx index 4f5e05ad1..5ffed64d9 100644 --- a/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx @@ -13,6 +13,7 @@ export function DatasetTermsRow({ title, tooltipMessage, value }: DatasetTermsRo if (value === undefined) { return null } + console.log('value', value) return ( diff --git a/src/sections/dataset/dataset-terms/License.tsx b/src/sections/dataset/dataset-terms/License.tsx index c62fe27c3..e4a05dea1 100644 --- a/src/sections/dataset/dataset-terms/License.tsx +++ b/src/sections/dataset/dataset-terms/License.tsx @@ -44,7 +44,11 @@ export function License({ license }: LicenseProps) { {license.name} )} - {!license && {t('termsTab.customTermsHelpText')}} + {!license && ( + + {t('customTerms.title')} - {t('customTerms.description')} + + )} ) diff --git a/src/sections/dataset/dataset-terms/TermsOfAccess.tsx b/src/sections/dataset/dataset-terms/TermsOfAccess.tsx index 4a0835db2..502406557 100644 --- a/src/sections/dataset/dataset-terms/TermsOfAccess.tsx +++ b/src/sections/dataset/dataset-terms/TermsOfAccess.tsx @@ -1,29 +1,15 @@ import { useTranslation } from 'react-i18next' import { DatasetTermsRow } from './DatasetTermsRow' import { FilesCountInfo } from '@/files/domain/models/FilesCountInfo' - +import { TermsOfAccess as TermsOfAccessModel } from '@/dataset/domain/models/Dataset' interface TermsOfAccessProps { - termsOfAccess?: string | undefined - fileAccessRequest: boolean - dataAccessPlace?: string - originalArchive?: string - availabilityStatus?: string - contactForAccess?: string - sizeOfCollection?: string - studyCompletion?: string + termsOfAccess: TermsOfAccessModel filesCountInfo: FilesCountInfo | undefined restrictedFilesCount: number } export function TermsOfAccess({ termsOfAccess, - fileAccessRequest, - dataAccessPlace, - originalArchive, - availabilityStatus, - contactForAccess, - sizeOfCollection, - studyCompletion, filesCountInfo, restrictedFilesCount }: TermsOfAccessProps) { @@ -47,13 +33,15 @@ export function TermsOfAccess({ @@ -61,32 +49,32 @@ export function TermsOfAccess({ ) diff --git a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx index 83673de86..9f27900dc 100644 --- a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx +++ b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx @@ -6,8 +6,10 @@ import { Form } from '@iqss/dataverse-design-system' import type { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' import { VersionUpdateType } from '@/dataset/domain/models/VersionUpdateType' import { useSession } from '../../session/SessionContext' -import { SummaryLicense } from '../dataset-summary/SummaryLicense' -import { DatasetNonNumericVersionSearchParam } from '@/dataset/domain/models/Dataset' +import { + DatasetNonNumericVersionSearchParam, + CustomTerms as CustomTermsModel +} from '@/dataset/domain/models/Dataset' import { SubmissionStatus } from '../../shared/form/DatasetMetadataForm/useSubmitDataset' import { QueryParamKey, Route } from '../../Route.enum' import { usePublishDataset } from './usePublishDataset' @@ -16,6 +18,8 @@ import { CollectionRepository } from '@/collection/domain/repositories/Collectio import { UpwardHierarchyNode } from '@/shared/hierarchy/domain/models/UpwardHierarchyNode' import { DatasetLicense } from '@/dataset/domain/models/Dataset' import styles from './PublishDatasetModal.module.scss' +import { PublishLicense } from '@/sections/dataset/publish-dataset/PublishLicense' +import { CustomTerms } from '@/sections/dataset/dataset-terms/CustomTerms' interface PublishDatasetModalProps { show: boolean @@ -23,7 +27,8 @@ interface PublishDatasetModalProps { collectionRepository: CollectionRepository parentCollection: UpwardHierarchyNode persistentId: string - license: DatasetLicense + license: DatasetLicense | undefined + customTerms?: CustomTermsModel releasedVersionExists: boolean handleClose: () => void nextMajorVersion?: string @@ -38,6 +43,7 @@ export function PublishDatasetModal({ parentCollection, persistentId, license, + customTerms, releasedVersionExists, handleClose, nextMajorVersion, @@ -120,13 +126,17 @@ export function PublishDatasetModal({ )} - { + handleCustomTermsClick={() => { const termsUrl = `${Route.DATASETS}?${QueryParamKey.PERSISTENT_ID}=${persistentId}&${QueryParamKey.VERSION}=${DatasetNonNumericVersionSearchParam.DRAFT}&${QueryParamKey.TAB}=terms` - window.open(termsUrl, '_blank') + const newTabUrl = `${window.location.origin}${import.meta.env.BASE_URL}${termsUrl}` + window.open(newTabUrl, '_blank') }} /> +
+ +

{t('publish.termsText')}

diff --git a/src/sections/dataset/publish-dataset/PublishLicense.tsx b/src/sections/dataset/publish-dataset/PublishLicense.tsx new file mode 100644 index 000000000..e80856949 --- /dev/null +++ b/src/sections/dataset/publish-dataset/PublishLicense.tsx @@ -0,0 +1,43 @@ +import { Row, Col } from '@iqss/dataverse-design-system' +import { DatasetLicense as LicenseModel } from '../../../dataset/domain/models/Dataset' +import { useTranslation } from 'react-i18next' + +interface PublishLicenseProps { + license: LicenseModel | undefined + handleCustomTermsClick: () => void +} + +export function PublishLicense({ license, handleCustomTermsClick }: PublishLicenseProps) { + const { t } = useTranslation('dataset') + + return ( + + + {t('license.title')} + + + {license && license.iconUri && ( + {t(`license.altTextPrefix`) + )} + {license && ( + + {license.name} + + )} + {!license && ( + + + {t('customTerms.title')} + {' '} + - {t('customTerms.description')} + + )} + + + ) +} diff --git a/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx b/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx index a0ee49ba4..2490b01d3 100644 --- a/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx +++ b/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx @@ -6,6 +6,8 @@ import { WithLoggedInSuperUser } from '../../WithLoggedInSuperUser' import { WithLoggedInUser } from '../../WithLoggedInUser' import { CollectionMockRepository } from '@/stories/collection/CollectionMockRepository' import { UpwardHierarchyNodeMother } from '@tests/component/shared/hierarchy/domain/models/UpwardHierarchyNodeMother' +import { CustomTermsMother } from '@tests/component/dataset/domain/models/TermsOfUseMother' +import { LicenseMother } from '@tests/component/dataset/domain/models/LicenseMother' const meta: Meta = { title: 'Sections/Dataset Page/PublishDatasetModal', @@ -26,6 +28,8 @@ export const Default: Story = { collectionRepository={new CollectionMockRepository()} parentCollection={UpwardHierarchyNodeMother.createCollection()} persistentId={'test'} + license={undefined} + customTerms={CustomTermsMother.create()} releasedVersionExists={false} handleClose={() => {}}> ) @@ -39,6 +43,8 @@ export const ReleasedVersionExists: Story = { repository={new DatasetMockRepository()} collectionRepository={new CollectionMockRepository()} parentCollection={UpwardHierarchyNodeMother.createCollection()} + license={LicenseMother.create()} + customTerms={undefined} persistentId={'test'} releasedVersionExists={true} nextMinorVersion={'1.1'} @@ -54,6 +60,8 @@ export const UnReleasedCollection: Story = { repository={new DatasetMockRepository()} collectionRepository={new CollectionMockRepository()} parentCollection={UpwardHierarchyNodeMother.createCollection({ isReleased: false })} + license={LicenseMother.create()} + customTerms={undefined} persistentId={'test'} releasedVersionExists={false} handleClose={() => {}}> @@ -67,6 +75,8 @@ export const Superuser: Story = { repository={new DatasetMockRepository()} collectionRepository={new CollectionMockRepository()} parentCollection={UpwardHierarchyNodeMother.createCollection()} + license={LicenseMother.create()} + customTerms={undefined} persistentId={'test'} releasedVersionExists={true} nextMinorVersion={'1.1'} @@ -84,6 +94,8 @@ export const RequiresMajorVersionUpdate: Story = { parentCollection={UpwardHierarchyNodeMother.createCollection()} persistentId={'test'} releasedVersionExists={true} + license={LicenseMother.create()} + customTerms={undefined} nextMinorVersion={'1.1'} nextMajorVersion={'2.0'} requiresMajorVersionUpdate={true} diff --git a/tests/component/dataset/domain/models/DatasetMother.ts b/tests/component/dataset/domain/models/DatasetMother.ts index a18665890..b7a8e1dbb 100644 --- a/tests/component/dataset/domain/models/DatasetMother.ts +++ b/tests/component/dataset/domain/models/DatasetMother.ts @@ -25,6 +25,7 @@ import { COUNTRY_FIELD_VOCAB_VALUES, SUBJECT_FIELD_VOCAB_VALUES } from '../../../metadata-block-info/domain/models/MetadataBlockInfoMother' +import { TermsOfUseMother } from '@tests/component/dataset/domain/models/TermsOfUseMother' export class DatasetVersionMother { static create(props?: Partial): DatasetVersion { @@ -416,19 +417,9 @@ export class DatasetMother { fileDownloadSizes: [], requestedVersion: undefined, hierarchy: UpwardHierarchyNodeMother.createDataset(), - termsOfUse: { - fileAccessRequest: true, - termsOfAccess: 'Terms of access', - dataAccessPlace: 'Data access place', - originalArchive: 'Original archive', - availabilityStatus: 'Availability status', - contactForAccess: 'Contact for access', - sizeOfCollection: 'Size of collection', - studyCompletion: 'Study completion' - }, + termsOfUse: TermsOfUseMother.create(), ...props } - return new Dataset.Builder( dataset.persistentId, dataset.version, diff --git a/tests/component/dataset/domain/models/TermsOfUseMother.ts b/tests/component/dataset/domain/models/TermsOfUseMother.ts index 1b79afd6e..f79877005 100644 --- a/tests/component/dataset/domain/models/TermsOfUseMother.ts +++ b/tests/component/dataset/domain/models/TermsOfUseMother.ts @@ -1,24 +1,28 @@ import { faker } from '@faker-js/faker' -import { DatasetTermsOfUse } from '../../../../../src/dataset/domain/models/Dataset' +import { DatasetTermsOfUse } from '@/dataset/domain/models/Dataset' +import { CustomTerms } from '@/dataset/domain/models/Dataset' +import { TermsOfAccess } from '@/dataset/domain/models/Dataset' -export class TermsOfUseMother { - static create(props?: Partial): DatasetTermsOfUse { - const defaultTerms: DatasetTermsOfUse = { - termsOfAccess: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), - fileAccessRequest: true, +export class TermsOfAccessMother { + static create(props?: Partial): TermsOfAccess { + const defaultTerms: TermsOfAccess = { + termsOfAccessForRestrictedFiles: faker.lorem.sentence( + faker.datatype.number({ min: 1, max: 100 }) + ), + fileAccessRequest: faker.datatype.boolean(), dataAccessPlace: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), originalArchive: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), availabilityStatus: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), - contactForAccess: 'support@example.com', - sizeOfCollection: '10 GB', - studyCompletion: '2023-01-01' + contactForAccess: faker.internet.email(), + sizeOfCollection: `${faker.datatype.number({ min: 1, max: 100 })} GB`, + studyCompletion: faker.date.past().toISOString().split('T')[0] } return { ...defaultTerms, ...props } } - static createEmpty(): DatasetTermsOfUse { + + static createEmpty(): TermsOfAccess { return { - termsOfAccess: undefined, fileAccessRequest: false, dataAccessPlace: undefined, originalArchive: undefined, @@ -29,3 +33,30 @@ export class TermsOfUseMother { } } } + +export class CustomTermsMother { + static create(props?: Partial): CustomTerms { + const defaultTerms: CustomTerms = { + termsOfUse: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), + confidentialityDeclaration: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), + specialPermissions: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), + restrictions: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), + citationRequirements: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), + depositorRequirements: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), + conditions: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })), + disclaimer: faker.lorem.sentence(faker.datatype.number({ min: 1, max: 100 })) + } + + return { ...defaultTerms, ...props } + } +} + +export class TermsOfUseMother { + static create(props?: Partial): DatasetTermsOfUse { + const defaultTerms: DatasetTermsOfUse = { + termsOfAccess: TermsOfAccessMother.create(), + customTermsOfUse: CustomTermsMother.create() + } + return { ...defaultTerms, ...props } + } +} diff --git a/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx index 4415887e8..8a9509dfe 100644 --- a/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx +++ b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx @@ -4,7 +4,10 @@ import { FileRepository } from '@/files/domain/repositories/FileRepository' import { FileAccessOption } from '@/files/domain/models/FileCriteria' import { DatasetMother } from '../../../dataset/domain/models/DatasetMother' import { LicenseMother } from '../../../dataset/domain/models/LicenseMother' -import { TermsOfUseMother } from '../../../dataset/domain/models/TermsOfUseMother' +import { + TermsOfUseMother, + TermsOfAccessMother +} from '../../../dataset/domain/models/TermsOfUseMother' const datasetPersistentId = 'test-dataset-persistent-id' const datasetVersion = DatasetMother.create().version @@ -30,10 +33,20 @@ const singleRestrictedFilesCountInfo = FilesCountInfoMother.create({ const license = LicenseMother.create() const termsOfUse = TermsOfUseMother.create() -const emptyTermsOfUse = TermsOfUseMother.createEmpty() -const accessAllowedTermsOfUse = TermsOfUseMother.create({ fileAccessRequest: true }) -const accessNotAllowedTermsOfUse = TermsOfUseMother.create({ fileAccessRequest: false }) -const termsOfUseWithUndefinedValue = TermsOfUseMother.create({ dataAccessPlace: undefined }) +const emptyCustomTerms = TermsOfUseMother.create({ customTermsOfUse: undefined }) + +const emptyTermsOfAccess = TermsOfUseMother.create({ + termsOfAccess: TermsOfAccessMother.createEmpty() +}) +const accessAllowedTermsOfUse = TermsOfUseMother.create({ + termsOfAccess: TermsOfAccessMother.create({ fileAccessRequest: true }) +}) +const accessNotAllowedTermsOfUse = TermsOfUseMother.create({ + termsOfAccess: TermsOfAccessMother.create({ fileAccessRequest: false }) +}) +const termsOfUseWithUndefinedValue = TermsOfUseMother.create({ + termsOfAccess: TermsOfAccessMother.create({ dataAccessPlace: undefined }) +}) describe('DatasetTerms', () => { beforeEach(() => { @@ -100,19 +113,21 @@ describe('DatasetTerms', () => { cy.findByText('Restricted Files').should('exist') cy.findByText('There is 1 restricted file in this dataset.').should('exist') }) - it('renders the terms of access', () => { + it('renders the custom terms', () => { cy.customMount( ) - + console.log('termsOfUse', termsOfUse) cy.findByText('Terms of Access for Restricted Files').should('exist') - cy.findByText(termsOfUse.termsOfAccess as string).should('exist') + cy.findByText(termsOfUse.termsOfAccess.termsOfAccessForRestrictedFiles as string).should( + 'exist' + ) }) it('renders the request access allowed message', () => { @@ -148,22 +163,22 @@ describe('DatasetTerms', () => { cy.customMount( ) - + console.log(emptyCustomTerms) cy.findByText('Data Access Place').should('exist') - cy.findByText(termsOfUse.dataAccessPlace as string).should('exist') + cy.findByText(emptyCustomTerms.termsOfAccess.dataAccessPlace as string).should('exist') }) it('renders the original archive information', () => { cy.customMount( { ) cy.findByText('Original Archive').should('exist') - cy.findByText(termsOfUse.originalArchive as string).should('exist') + cy.findByText(emptyCustomTerms.termsOfAccess.originalArchive as string).should('exist') }) it('renders the availability status', () => { cy.customMount( { ) cy.findByText('Availability Status').should('exist') - cy.findByText(termsOfUse.availabilityStatus as string).should('exist') + cy.findByText(emptyCustomTerms.termsOfAccess.availabilityStatus as string).should('exist') }) it('renders the contact for access information', () => { cy.customMount( { ) cy.findByText('Contact for Access').should('exist') - cy.findByText(termsOfUse.contactForAccess as string).should('exist') + cy.findByText(emptyCustomTerms.termsOfAccess.contactForAccess as string).should('exist') }) it('renders the size of collection information', () => { cy.customMount( { ) cy.findByText('Size of Collection').should('exist') - cy.findByText(termsOfUse.sizeOfCollection as string).should('exist') + cy.findByText(emptyCustomTerms.termsOfAccess.sizeOfCollection as string).should('exist') }) it('renders the study completion information', () => { cy.customMount( { ) cy.findByText('Study Completion').should('exist') - cy.findByText(termsOfUse.studyCompletion as string).should('exist') + cy.findByText(emptyCustomTerms.termsOfAccess.studyCompletion as string).should('exist') }) it('does not render the terms of use AccordionItem if terms of use fields are empty', () => { cy.customMount( { cy.customMount( Date: Fri, 7 Feb 2025 08:00:25 -0500 Subject: [PATCH 16/45] Feat: rename customTermsOfUse -> customTerms --- package.json | 2 +- src/dataset/domain/models/Dataset.ts | 2 +- .../PublishDatasetMenu.tsx | 2 +- .../dataset/dataset-terms/DatasetTerms.tsx | 2 +- .../dataset/domain/models/TermsOfUseMother.ts | 2 +- .../PublishDatasetMenu.spec.tsx | 92 ++++++++++++++++--- .../PublishDatasetModal.spec.tsx | 33 +++++++ 7 files changed, 118 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index df49d81b5..73d5cb03e 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr252.03b7ae1", + "@iqss/dataverse-client-javascript": "2.0.0-pr252.3479bb1", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", diff --git a/src/dataset/domain/models/Dataset.ts b/src/dataset/domain/models/Dataset.ts index f216fb281..9afc3c4fa 100644 --- a/src/dataset/domain/models/Dataset.ts +++ b/src/dataset/domain/models/Dataset.ts @@ -391,7 +391,7 @@ export interface CustomTerms { } export interface DatasetTermsOfUse { termsOfAccess: TermsOfAccess - customTermsOfUse?: CustomTerms + customTerms?: CustomTerms } export class Dataset { diff --git a/src/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.tsx b/src/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.tsx index 0d41fda44..a7191c70e 100644 --- a/src/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.tsx +++ b/src/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.tsx @@ -45,7 +45,7 @@ export function PublishDatasetMenu({ parentCollection={dataset.parentCollectionNode} persistentId={dataset.persistentId} license={dataset.license} - customTerms={dataset.termsOfUse.customTermsOfUse} + customTerms={dataset.termsOfUse.customTerms} releasedVersionExists={dataset.version.someDatasetVersionHasBeenReleased} nextMajorVersion={dataset.nextMajorVersion} nextMinorVersion={dataset.nextMinorVersion} diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index 0be025ae5..9e8505f7c 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -62,7 +62,7 @@ export function DatasetTerms({ {t('termsTab.licenseTitle')} - +
{!termsOfAccessIsEmpty && ( diff --git a/tests/component/dataset/domain/models/TermsOfUseMother.ts b/tests/component/dataset/domain/models/TermsOfUseMother.ts index f79877005..0f9d0f463 100644 --- a/tests/component/dataset/domain/models/TermsOfUseMother.ts +++ b/tests/component/dataset/domain/models/TermsOfUseMother.ts @@ -55,7 +55,7 @@ export class TermsOfUseMother { static create(props?: Partial): DatasetTermsOfUse { const defaultTerms: DatasetTermsOfUse = { termsOfAccess: TermsOfAccessMother.create(), - customTermsOfUse: CustomTermsMother.create() + customTerms: CustomTermsMother.create() } return { ...defaultTerms, ...props } } diff --git a/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx index c4904c7f6..ee5d8aa54 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx @@ -5,9 +5,13 @@ import { DatasetPermissionsMother, DatasetVersionMother } from '../../../../dataset/domain/models/DatasetMother' -import { SettingRepository } from '../../../../../../src/settings/domain/repositories/SettingRepository' +import { SettingRepository } from '@/settings/domain/repositories/SettingRepository' +import { CollectionRepository } from '@/collection/domain/repositories/CollectionRepository' +import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' import { SettingMother } from '../../../../settings/domain/models/SettingMother' import { SettingsProvider } from '../../../../../../src/sections/settings/SettingsProvider' +const collectionRepository = {} as CollectionRepository +const datasetRepository = {} as DatasetRepository describe('PublishDatasetMenu', () => { it('renders the PublishDatasetMenu if is dataset latest version and it is a draft and publishing is allowed', () => { @@ -19,7 +23,13 @@ describe('PublishDatasetMenu', () => { isValid: true }) - cy.mountAuthenticated() + cy.mountAuthenticated( + + ) cy.findByRole('button', { name: 'Publish Dataset' }) .should('exist') @@ -45,7 +55,11 @@ describe('PublishDatasetMenu', () => { cy.mountAuthenticated( - + ) @@ -63,7 +77,13 @@ describe('PublishDatasetMenu', () => { isValid: true }) - cy.customMount() + cy.customMount( + + ) cy.findByRole('button', { name: 'Publish Dataset' }).should('not.exist') }) @@ -75,7 +95,13 @@ describe('PublishDatasetMenu', () => { locks: [] }) - cy.mountAuthenticated() + cy.mountAuthenticated( + + ) cy.findByRole('button', { name: 'Publish Dataset' }).should('not.exist') }) @@ -87,7 +113,13 @@ describe('PublishDatasetMenu', () => { locks: [] }) - cy.mountAuthenticated() + cy.mountAuthenticated( + + ) cy.findByRole('button', { name: 'Publish Dataset' }).should('not.exist') }) @@ -99,7 +131,13 @@ describe('PublishDatasetMenu', () => { locks: [] }) - cy.mountAuthenticated() + cy.mountAuthenticated( + + ) cy.findByRole('button', { name: 'Publish Dataset' }).should('not.exist') }) @@ -113,7 +151,13 @@ describe('PublishDatasetMenu', () => { isValid: true }) - cy.mountAuthenticated() + cy.mountAuthenticated( + + ) cy.findByRole('button', { name: 'Publish Dataset' }).should('be.enabled') }) @@ -127,7 +171,13 @@ describe('PublishDatasetMenu', () => { isValid: true }) - cy.mountAuthenticated() + cy.mountAuthenticated( + + ) cy.findByRole('button', { name: 'Publish Dataset' }).should('be.disabled') }) @@ -141,7 +191,13 @@ describe('PublishDatasetMenu', () => { isValid: true }) - cy.mountAuthenticated() + cy.mountAuthenticated( + + ) cy.findByRole('button', { name: 'Publish Dataset' }).should('be.disabled') }) @@ -155,7 +211,13 @@ describe('PublishDatasetMenu', () => { isValid: false }) - cy.mountAuthenticated() + cy.mountAuthenticated( + + ) cy.findByRole('button', { name: 'Publish Dataset' }).should('be.disabled') }) @@ -169,7 +231,13 @@ describe('PublishDatasetMenu', () => { isValid: true }) - cy.mountAuthenticated() + cy.mountAuthenticated( + + ) cy.findByRole('button', { name: 'Publish Dataset' }) .should('exist') diff --git a/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx b/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx index e167f4efa..6b0a9c59b 100644 --- a/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx +++ b/tests/component/sections/dataset/dataset-publish/PublishDatasetModal.spec.tsx @@ -3,6 +3,8 @@ import { DatasetRepository } from '../../../../../src/dataset/domain/repositorie import { PublishDatasetModal } from '../../../../../src/sections/dataset/publish-dataset/PublishDatasetModal' import { CollectionRepository } from '../../../../../src/collection/domain/repositories/CollectionRepository' import { UpwardHierarchyNodeMother } from '../../../shared/hierarchy/domain/models/UpwardHierarchyNodeMother' +import { CustomTermsMother } from '@tests/component/dataset/domain/models/TermsOfUseMother' +import { LicenseMother } from '@tests/component/dataset/domain/models/LicenseMother' describe('PublishDatasetModal', () => { it('display modal for never released dataset', () => { @@ -16,6 +18,7 @@ describe('PublishDatasetModal', () => { { { show={true} repository={repository} collectionRepository={collectionRepository} + license={LicenseMother.create()} parentCollection={parentCollection} persistentId="testPersistentId" releasedVersionExists={false} @@ -101,6 +106,7 @@ describe('PublishDatasetModal', () => { const parentCollection = UpwardHierarchyNodeMother.createCollection() cy.mountAuthenticated( { { const parentCollection = UpwardHierarchyNodeMother.createCollection() cy.mountAuthenticated( { const parentCollection = UpwardHierarchyNodeMother.createCollection() cy.mountAuthenticated( { const parentCollection = UpwardHierarchyNodeMother.createCollection({ isReleased: false }) cy.mountAuthenticated( { .should('have.attr', 'href') .and('include', `/collections/${parentCollection.id}`) }) + + it('Displays custom terms when license is undefined', () => { + const handleClose = cy.stub() + const repository = {} as DatasetRepository // Mock the repository as needed + repository.publish = cy.stub().as('repositoryPublish').resolves() + const collectionRepository = {} as CollectionRepository + collectionRepository.publish = cy.stub().as('collectionRepositoryPublish').resolves() + const parentCollection = UpwardHierarchyNodeMother.createCollection({ isReleased: false }) + cy.mountAuthenticated( + + ) + cy.findByText(/Custom Dataset Terms/).should('exist') + }) }) From f5c6d82469d6f621057d398226853ad597d346bf Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 7 Feb 2025 09:18:58 -0500 Subject: [PATCH 17/45] fix: use latest js-dataverse version from PR --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 682aa792d..b578eeedb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr252.03b7ae1", + "@iqss/dataverse-client-javascript": "2.0.0-pr252.9d25433", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", @@ -3674,9 +3674,9 @@ }, "node_modules/@iqss/dataverse-client-javascript": { "name": "@IQSS/dataverse-client-javascript", - "version": "2.0.0-pr252.03b7ae1", - "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr252.03b7ae1/ddce8479b6e139ee548a6c8ac2e3bb5a9d730336", - "integrity": "sha512-U2uvTAidTY+hjDk5U72OemahYWugpHUu2F7mcklL1VSpeFrs25tb76U8UvkRIY9Roc5pCh6ydhgS8RK5NdJFCQ==", + "version": "2.0.0-pr252.9d25433", + "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr252.9d25433/f658a61735d5f12bd63b9b8afe2bd6d61cb66fe3", + "integrity": "sha512-jOcfh4qBWkYZfEthOPAyaLlgUECivBbbYxsDapHqAwM/6tvAQwnixRIdO6dD17eqYNW1wEkGKWzlqyl4smUD1w==", "dependencies": { "@types/node": "^18.15.11", "@types/turndown": "^5.0.1", diff --git a/package.json b/package.json index 73d5cb03e..fa6debc0a 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr252.3479bb1", + "@iqss/dataverse-client-javascript": "2.0.0-pr252.9d25433", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", From ebb19712b2f631d749e8ce82e9c1f56a245a8529 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 7 Feb 2025 10:50:32 -0500 Subject: [PATCH 18/45] fix: update CollectionDTO.ts to match js-dataverse --- src/collection/domain/useCases/DTOs/CollectionDTO.ts | 2 ++ .../collection-form/useSubmitCollection.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/collection/domain/useCases/DTOs/CollectionDTO.ts b/src/collection/domain/useCases/DTOs/CollectionDTO.ts index 3a2d076e3..00042f10d 100644 --- a/src/collection/domain/useCases/DTOs/CollectionDTO.ts +++ b/src/collection/domain/useCases/DTOs/CollectionDTO.ts @@ -10,6 +10,8 @@ export interface CollectionDTO { metadataBlockNames?: string[] facetIds?: string[] inputLevels?: CollectionInputLevelDTO[] + inheritMetadataBlocksFromParent: boolean + inheritFacetsFromParent: boolean } export interface CollectionInputLevelDTO { diff --git a/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts b/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts index 7c3fc80a0..43b9a6b51 100644 --- a/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts +++ b/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts @@ -102,6 +102,8 @@ export function useSubmitCollection( ) const newOrUpdatedCollection: CollectionDTO = { + inheritFacetsFromParent: false, + inheritMetadataBlocksFromParent: false, name: formData.name, alias: formData.alias, type: formData.type, From 2df59b3239e24b6d6f378c625b1a0d675ae60042 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Fri, 7 Feb 2025 15:29:19 -0500 Subject: [PATCH 19/45] fix: increase code coverage --- .../ChangeCurationStatusMenu.spec.tsx | 23 ++++++++- .../PublishDatasetMenu.spec.tsx | 47 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/ChangeCurationStatusMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/ChangeCurationStatusMenu.spec.tsx index 7e8c81ff8..01ce4397b 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/ChangeCurationStatusMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/ChangeCurationStatusMenu.spec.tsx @@ -3,7 +3,7 @@ import { ChangeCurationStatusMenu } from '../../../../../../src/sections/dataset import { SettingMother } from '../../../../settings/domain/models/SettingMother' import { SettingsProvider } from '../../../../../../src/sections/settings/SettingsProvider' import { SettingRepository } from '../../../../../../src/settings/domain/repositories/SettingRepository' - +import { NotImplementedModalProvider } from '../../../../../../src/sections/not-implemented/NotImplementedModalProvider' describe('ChangeCurationStatusMenu', () => { it('renders the ChangeCurationStatusMenu if external statuses are allowed and the user has update dataset permissions', () => { const settingRepository = {} as SettingRepository @@ -32,4 +32,25 @@ describe('ChangeCurationStatusMenu', () => { cy.findByRole('button', { name: 'Change Curation Status' }).should('not.exist') }) + it('renders the Not Implemented Modal when button is clicked', () => { + const settingRepository = {} as SettingRepository + settingRepository.getByName = cy + .stub() + .resolves(SettingMother.createExternalStatusesAllowed(['Author Contacted', 'Privacy Review'])) + + cy.customMount( + + + + + + ) + + cy.findByRole('button', { name: 'Change Curation Status' }) + .should('exist') + .should('be.enabled') + .click() + + cy.findByRole('button', { name: 'Author Contacted' }).should('exist').click() + }) }) diff --git a/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx index ee5d8aa54..5ead5836b 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/publish-dataset-menu/PublishDatasetMenu.spec.tsx @@ -246,4 +246,51 @@ describe('PublishDatasetMenu', () => { cy.findByRole('button', { name: 'Return to Author' }).should('exist') }) + + it('shows the PublishDatasetModal when the Publish button is clicked', () => { + const dataset = DatasetMother.create({ + version: DatasetVersionMother.createDraftAsLatestVersion(), + permissions: DatasetPermissionsMother.createWithPublishingDatasetAllowed(), + locks: [], + hasValidTermsOfAccess: true, + isValid: true + }) + + cy.mountAuthenticated( + + ) + + cy.findByRole('button', { name: 'Publish Dataset' }).click() + cy.findByRole('button', { name: 'Publish' }).click() + cy.findByRole('dialog').should('exist') + }) + + it('hides the PublishDatasetModal when handleClose is called', () => { + const dataset = DatasetMother.create({ + version: DatasetVersionMother.createDraftAsLatestVersion(), + permissions: DatasetPermissionsMother.createWithPublishingDatasetAllowed(), + locks: [], + hasValidTermsOfAccess: true, + isValid: true + }) + + cy.mountAuthenticated( + + ) + + cy.findByRole('button', { name: 'Publish Dataset' }).click() + cy.findByRole('button', { name: 'Publish' }).click() + cy.findByRole('dialog').should('exist') + + cy.findByRole('button', { name: 'Close' }).click() + cy.findByRole('dialog').should('not.exist') + }) }) From 5061a5353dd74146898edd5a8c28e33503c4b060 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Sat, 8 Feb 2025 16:52:54 -0500 Subject: [PATCH 20/45] fix: increase code coverage --- .../EditDatasetMenu.spec.tsx | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx index 59b75f0d6..c3c6501a1 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/edit-dataset-menu/EditDatasetMenu.spec.tsx @@ -97,4 +97,36 @@ describe('EditDatasetMenu', () => { .should('have.class', 'disabled') cy.findByRole('button', { name: 'Metadata' }).should('exist').should('have.class', 'disabled') }) + it('navigates to the correct URL when Files (Upload) is clicked', () => { + const dataset = DatasetMother.create({ + permissions: DatasetPermissionsMother.createWithAllAllowed(), + locks: [], + hasValidTermsOfAccess: true, + version: DatasetVersionMother.createReleasedWithLatestVersionIsADraft() + }) + + cy.mountAuthenticated() + + cy.findByRole('button', { name: 'Edit Dataset' }).click() + cy.findByRole('button', { name: 'Files (Upload)' }).click() + // TODO: use vite plugin to mock navigate + // https://github.com/cypress-io/cypress/tree/develop/npm/vite-plugin-cypress-esm + // expect(navigateMock).to.have.been.calledWith('/upload-dataset-files') + }) + it('navigates to the correct URL when Edit Metadata is clicked', () => { + const dataset = DatasetMother.create({ + permissions: DatasetPermissionsMother.createWithAllAllowed(), + locks: [], + hasValidTermsOfAccess: true, + version: DatasetVersionMother.createReleasedWithLatestVersionIsADraft() + }) + + cy.mountAuthenticated() + + cy.findByRole('button', { name: 'Edit Dataset' }).click() + cy.findByRole('button', { name: 'Metadata' }).click() + // TODO: use vite plugin to mock navigate + // https://github.com/cypress-io/cypress/tree/develop/npm/vite-plugin-cypress-esm + // expect(navigateMock).to.have.been.calledWith('/upload-dataset-files') + }) }) From 24604b1890f1984cb8266cbfe150713d804681a3 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Mon, 10 Feb 2025 09:05:59 -0500 Subject: [PATCH 21/45] fix: use defined route for custom terms link, remove console.log --- .../DatasetJSDataverseRepository.ts | 1 - .../publish-dataset/PublishDatasetModal.tsx | 7 ++----- .../DatasetSummary.stories.tsx | 13 +++++++++++- .../dataset-terms/DatasetTerms.stories.tsx | 21 ++++++++++++++----- .../dataset/domain/models/DatasetMother.ts | 2 +- .../dataset/domain/models/TermsOfUseMother.ts | 7 +++++++ 6 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts b/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts index a93326b63..91c1d5232 100644 --- a/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts +++ b/src/dataset/infrastructure/repositories/DatasetJSDataverseRepository.ts @@ -178,7 +178,6 @@ export class DatasetJSDataverseRepository implements DatasetRepository { .execute(persistentId, version, includeDeaccessioned) .then((jsDataset) => this.fetchDatasetDetails(jsDataset, version)) .then((datasetDetails) => { - console.log('jsDataset', datasetDetails.jsDataset) return this.fetchDownloadSizes(persistentId, version).then((downloadSizes) => { datasetDetails.jsDatasetFilesTotalOriginalDownloadSize = downloadSizes[0] datasetDetails.jsDatasetFilesTotalArchivalDownloadSize = downloadSizes[1] diff --git a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx index 9f27900dc..7d1892847 100644 --- a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx +++ b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx @@ -6,6 +6,7 @@ import { Form } from '@iqss/dataverse-design-system' import type { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' import { VersionUpdateType } from '@/dataset/domain/models/VersionUpdateType' import { useSession } from '../../session/SessionContext' +import { RouteWithParams } from '../../Route.enum' import { DatasetNonNumericVersionSearchParam, CustomTerms as CustomTermsModel @@ -71,11 +72,7 @@ export function PublishDatasetModal({ const nextMinorVersionString = nextMinorVersion ? nextMinorVersion : '' function onPublishSucceed() { navigate( - `${Route.DATASETS}?${QueryParamKey.PERSISTENT_ID}=${persistentId}&${QueryParamKey.VERSION}=${DatasetNonNumericVersionSearchParam.DRAFT}`, - { - state: { publishInProgress: true }, - replace: true - } + RouteWithParams.DATASETS(persistentId, DatasetNonNumericVersionSearchParam.DRAFT, 'terms') ) handleClose() } diff --git a/src/stories/dataset/dataset-summary/DatasetSummary.stories.tsx b/src/stories/dataset/dataset-summary/DatasetSummary.stories.tsx index 1ef025ccb..7cd2c76f7 100644 --- a/src/stories/dataset/dataset-summary/DatasetSummary.stories.tsx +++ b/src/stories/dataset/dataset-summary/DatasetSummary.stories.tsx @@ -4,6 +4,7 @@ import { DatasetSummary } from '../../../sections/dataset/dataset-summary/Datase import { DatasetMetadataBlock, DatasetLicense } from '../../../dataset/domain/models/Dataset' import { DatasetMother } from '../../../../tests/component/dataset/domain/models/DatasetMother' import { MetadataBlockInfoMockRepository } from '../../shared-mock-repositories/metadata-block-info/MetadataBlockInfoMockRepository' +import { LicenseMother } from '@tests/component/dataset/domain/models/LicenseMother' const meta: Meta = { title: 'Sections/Dataset Page/DatasetSummary', @@ -11,7 +12,7 @@ const meta: Meta = { decorators: [WithI18next] } -const licenseMock: DatasetLicense = DatasetMother.createRealistic().license! +const licenseMock: DatasetLicense = LicenseMother.create() const summaryFieldsMock: DatasetMetadataBlock[] = DatasetMother.createRealistic().summaryFields export default meta type Story = StoryObj @@ -26,3 +27,13 @@ export const Default: Story = { /> ) } +export const withCustomTerms: Story = { + render: () => ( + console.log('Custom terms clicked')} + /> + ) +} diff --git a/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx b/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx index bb23e2264..bac3ded79 100644 --- a/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx +++ b/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx @@ -21,13 +21,13 @@ type Story = StoryObj const testDataset = DatasetMother.createRealistic() const license = LicenseMother.create() -const termsOfUse = TermsOfUseMother.create() +const termsOfUseWithoutCustomTerms = TermsOfUseMother.withoutCustomTerms() export const Default: Story = { render: () => ( ( ( ( + ) +} +export const CustomTerms: Story = { + render: () => ( + ): DatasetTermsOfUse { + const defaultTerms: DatasetTermsOfUse = { + termsOfAccess: TermsOfAccessMother.create(), + customTerms: undefined + } + return { ...defaultTerms, ...props } + } } From d14fd4041358a4e8806429c7a855c8adf9389a49 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Mon, 10 Feb 2025 09:43:28 -0500 Subject: [PATCH 22/45] fix: onPublishSucceed() --- src/sections/dataset/publish-dataset/PublishDatasetModal.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx index 7d1892847..9f2e707ab 100644 --- a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx +++ b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx @@ -71,9 +71,7 @@ export function PublishDatasetModal({ const nextMajorVersionString = nextMajorVersion ? nextMajorVersion : '' const nextMinorVersionString = nextMinorVersion ? nextMinorVersion : '' function onPublishSucceed() { - navigate( - RouteWithParams.DATASETS(persistentId, DatasetNonNumericVersionSearchParam.DRAFT, 'terms') - ) + navigate(RouteWithParams.DATASETS(persistentId, DatasetNonNumericVersionSearchParam.DRAFT)) handleClose() } From 40a16d2d34a29211a44fe360d953267b1e19f39f Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Mon, 10 Feb 2025 10:14:44 -0500 Subject: [PATCH 23/45] fix: revert onPublishSucceed() change --- .../dataset/publish-dataset/PublishDatasetModal.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx index 9f2e707ab..9f27900dc 100644 --- a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx +++ b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx @@ -6,7 +6,6 @@ import { Form } from '@iqss/dataverse-design-system' import type { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' import { VersionUpdateType } from '@/dataset/domain/models/VersionUpdateType' import { useSession } from '../../session/SessionContext' -import { RouteWithParams } from '../../Route.enum' import { DatasetNonNumericVersionSearchParam, CustomTerms as CustomTermsModel @@ -71,7 +70,13 @@ export function PublishDatasetModal({ const nextMajorVersionString = nextMajorVersion ? nextMajorVersion : '' const nextMinorVersionString = nextMinorVersion ? nextMinorVersion : '' function onPublishSucceed() { - navigate(RouteWithParams.DATASETS(persistentId, DatasetNonNumericVersionSearchParam.DRAFT)) + navigate( + `${Route.DATASETS}?${QueryParamKey.PERSISTENT_ID}=${persistentId}&${QueryParamKey.VERSION}=${DatasetNonNumericVersionSearchParam.DRAFT}`, + { + state: { publishInProgress: true }, + replace: true + } + ) handleClose() } From 0a5058e58cd491eb2dcd90e9dd9535407e3e579f Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:25:41 -0500 Subject: [PATCH 24/45] fix: remove unneeded state management from Tabs --- .../src/lib/components/tabs/Tabs.tsx | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/packages/design-system/src/lib/components/tabs/Tabs.tsx b/packages/design-system/src/lib/components/tabs/Tabs.tsx index 8496bda8d..0f9bdff18 100644 --- a/packages/design-system/src/lib/components/tabs/Tabs.tsx +++ b/packages/design-system/src/lib/components/tabs/Tabs.tsx @@ -8,25 +8,8 @@ interface TabsProps { } function Tabs({ defaultActiveKey, onSelect, children }: PropsWithChildren) { - const [key, setKey] = useState(defaultActiveKey) - - useEffect(() => { - if (defaultActiveKey) { - setKey(defaultActiveKey) - } - }, [defaultActiveKey]) - - const handleSelect = (k: string | null) => { - if (k) { - setKey(k) - if (onSelect) { - onSelect(k) - } - } - } - return ( - + {children} ) From bb560fe3c915ede99f622d119a58cf1853525bd8 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:27:32 -0500 Subject: [PATCH 25/45] fix: translation text label --- public/locales/en/dataset.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index 637420ff0..0ee504643 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -144,7 +144,7 @@ "depositorRequirements": "Depositor Requirements", "conditions": "Conditions", "disclaimer": "Disclaimer", - "declarationTip": "Indicates whether signing of a confidentiality declaration is needed to access a resource.", + "confidentialityDeclarationTip": "Indicates whether signing of a confidentiality declaration is needed to access a resource.", "specialPermissionsTip": "Determine if any special permissions are required to access a resource (e.g., if form is a needed and where to access the form).", "restrictionsTip": "Any restrictions on access to or use of the collection, such as privacy certification or distribution restrictions, should be indicated here. These can be restrictions applied by the author, producer, or disseminator of the data collection. If the data are restricted to only a certain class of user, specify which type.", "citationRequirementsTip": "Include special/explicit citation requirements for data to be cited properly in articles or other publications that are based on analysis of the data. For standard data citation requirements refer to our Community Norms.", From a3754cb5bdcf79aa436639fac526ca14995b15ba Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:28:23 -0500 Subject: [PATCH 26/45] feat: add scrollIntoView() for CustomTerms link --- src/sections/dataset/Dataset.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sections/dataset/Dataset.tsx b/src/sections/dataset/Dataset.tsx index 6e2195681..eee832876 100644 --- a/src/sections/dataset/Dataset.tsx +++ b/src/sections/dataset/Dataset.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react' +import { useRef, useEffect, useState } from 'react' import { Col, Row, Tabs } from '@iqss/dataverse-design-system' import styles from './Dataset.module.scss' import { useNavigate, useSearchParams } from 'react-router-dom' @@ -59,6 +59,8 @@ export function Dataset({ const { hideModal, isModalOpen } = useNotImplementedModal() const publishCompleted = useCheckPublishCompleted(publishInProgress, dataset, datasetRepository) const [activeTab, setActiveTab] = useState(tab) + const termsTabRef = useRef(null) + useUpdateDatasetAlerts({ dataset, created, @@ -88,6 +90,7 @@ export function Dataset({ newParams.set('tab', 'terms') // Update URL without reloading navigate(`?${newParams.toString()}`, { replace: true }) + termsTabRef.current?.scrollIntoView({ behavior: 'smooth' }) } const handleTabSelect = (key: string | null) => { @@ -170,7 +173,7 @@ export function Dataset({
-
+
Date: Tue, 11 Feb 2025 15:29:19 -0500 Subject: [PATCH 27/45] fix: revert license text --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 941450bad..5388afa9c 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Guidance on how to contribute -> All contributions to this project will be released under the Apache SummaryLicense, Version 2.0. +> All contributions to this project will be released under the Apache License, Version 2.0. > By submitting a pull request or filing a bug, issue, or > feature request, you are agreeing to comply with this waiver of copyright interest. > Details can be found in our [LICENSE](/LICENSE). From 5543b342862f22730a11f1c9d34484e774408b90 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:29:53 -0500 Subject: [PATCH 28/45] fix: remove comment and unused dependency --- src/sections/dataset/dataset-terms/DatasetTermsRow.tsx | 7 ++----- src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx b/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx index 5ffed64d9..b6e8970bb 100644 --- a/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx @@ -13,15 +13,12 @@ export function DatasetTermsRow({ title, tooltipMessage, value }: DatasetTermsRo if (value === undefined) { return null } - console.log('value', value) return ( - <> - {title} - - + {title} + {value &&
{}
}
diff --git a/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx b/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx index bac3ded79..b6ecb0872 100644 --- a/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx +++ b/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx @@ -3,7 +3,6 @@ import { WithI18next } from '../../WithI18next' import { DatasetTerms } from '../../../sections/dataset/dataset-terms/DatasetTerms' import { FileMockRepository } from '../../file/FileMockRepository' import { FileMockLoadingRepository } from '../../file/FileMockLoadingRepository' -//import { FileMockNoRestrictedFilesRepository } from '../../file/FileMockNoRestrictedFilesRepository' import { DatasetMother } from '../../../../tests/component/dataset/domain/models/DatasetMother' import { LicenseMother } from '../../../../tests/component/dataset/domain/models/LicenseMother' import { TermsOfUseMother } from '../../../../tests/component/dataset/domain/models/TermsOfUseMother' From 8f2573748a1a8c28f896ec670d2e915f251ead19 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:31:35 -0500 Subject: [PATCH 29/45] fix: remove NotImplementedModal test --- .../dataset/dataset-terms/EditDatasetTermsButton.spec.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx b/tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx index 513dbc738..6976cc984 100644 --- a/tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx +++ b/tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx @@ -56,7 +56,6 @@ describe('EditDatasetTermsButton', () => { cy.findByRole('button', { name: 'Edit Term Requirements' }).should('not.exist') }) - // TODO: test the button click by mocking the showModal function it('calls showModal when the button is clicked', () => { const dataset = DatasetMother.create({ permissions: DatasetPermissionsMother.createWithUpdateDatasetAllowed() @@ -64,10 +63,6 @@ describe('EditDatasetTermsButton', () => { cy.mountAuthenticated(withProviders(, dataset)) cy.spy(console, 'log').as('consoleLogSpy') - cy.findByRole('button', { name: 'Edit Term Requirements' }) - .click() - .then(() => { - cy.get('@consoleLogSpy').should('have.been.calledWith', 'calling showModal') - }) + cy.findByRole('button', { name: 'Edit Term Requirements' }).click() }) }) From 1b03ee9fd64ed9ed984802c63599f522b03d4823 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:32:07 -0500 Subject: [PATCH 30/45] fix: Edit Terms Button --- .../dataset/dataset-terms/EditDatasetTermsButton.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx index f23ec6569..787bb5131 100644 --- a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx +++ b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx @@ -1,5 +1,5 @@ import { useTranslation } from 'react-i18next' -import { Backpack } from 'react-bootstrap-icons' +import { BriefcaseFill } from 'react-bootstrap-icons' import { Button } from '@iqss/dataverse-design-system' import styles from './EditDatasetTermsButton.module.scss' import { useSession } from '@/sections/session/SessionContext' @@ -13,19 +13,19 @@ export function EditDatasetTermsButton() { const { showModal } = useNotImplementedModal() if (!user || !dataset?.permissions.canUpdateDataset) { - return <> + return null } const handleClick = () => { - console.log('calling showModal') showModal() } return ( From 54f5f51f0dd80eba23a6de17db852f9d9d61ce75 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:32:33 -0500 Subject: [PATCH 31/45] fix: use null return value --- src/sections/dataset/dataset-terms/License.tsx | 2 +- src/sections/dataset/publish-dataset/PublishLicense.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sections/dataset/dataset-terms/License.tsx b/src/sections/dataset/dataset-terms/License.tsx index e4a05dea1..f640146c9 100644 --- a/src/sections/dataset/dataset-terms/License.tsx +++ b/src/sections/dataset/dataset-terms/License.tsx @@ -4,7 +4,7 @@ import { Trans, useTranslation } from 'react-i18next' import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' interface LicenseProps { - license: LicenseModel | undefined + license?: LicenseModel } export function License({ license }: LicenseProps) { diff --git a/src/sections/dataset/publish-dataset/PublishLicense.tsx b/src/sections/dataset/publish-dataset/PublishLicense.tsx index e80856949..7a2379f6b 100644 --- a/src/sections/dataset/publish-dataset/PublishLicense.tsx +++ b/src/sections/dataset/publish-dataset/PublishLicense.tsx @@ -3,7 +3,7 @@ import { DatasetLicense as LicenseModel } from '../../../dataset/domain/models/D import { useTranslation } from 'react-i18next' interface PublishLicenseProps { - license: LicenseModel | undefined + license?: LicenseModel handleCustomTermsClick: () => void } From d23c37d2d6c25a72528583777eed628547b0e075 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:34:13 -0500 Subject: [PATCH 32/45] fix: prevent unneeded calls to getDataset() --- src/sections/dataset/DatasetProvider.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sections/dataset/DatasetProvider.tsx b/src/sections/dataset/DatasetProvider.tsx index 6e1384047..0b37299b9 100644 --- a/src/sections/dataset/DatasetProvider.tsx +++ b/src/sections/dataset/DatasetProvider.tsx @@ -1,4 +1,5 @@ -import { PropsWithChildren, useCallback, useEffect, useState } from 'react' +import { PropsWithChildren, useEffect, useState } from 'react' +import { useDeepCompareCallback } from 'use-deep-compare' import { DatasetContext } from './DatasetContext' import { DatasetRepository } from '../../dataset/domain/repositories/DatasetRepository' import { Dataset } from '../../dataset/domain/models/Dataset' @@ -23,7 +24,7 @@ export function DatasetProvider({ const [dataset, setDataset] = useState() const [isLoading, setIsLoading] = useState(true) - const getDataset = useCallback(() => { + const getDataset = useDeepCompareCallback(() => { if (searchParams.persistentId) { return getDatasetByPersistentId(repository, searchParams.persistentId, searchParams.version) } @@ -46,7 +47,7 @@ export function DatasetProvider({ console.error('There was an error getting the dataset', error) setIsLoading(false) }) - }, [repository, searchParams, getDataset, isPublishing]) + }, [repository, getDataset, isPublishing]) return ( {children} From 1720b68762ec8da685b629516dfd56a7e6d5702b Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:34:55 -0500 Subject: [PATCH 33/45] fix: remove unused dependency --- src/sections/dataset/dataset-terms/DatasetTerms.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index 9e8505f7c..0b4f94ad6 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -32,11 +32,7 @@ export function DatasetTerms({ datasetVersion }: DatasetTermsProps) { const { t } = useTranslation('dataset') - const { - filesCountInfo, - isLoading, - error: errorFilesCountInfo - } = useGetFilesCountInfo({ + const { filesCountInfo, isLoading } = useGetFilesCountInfo({ filesRepository, datasetPersistentId, datasetVersion From f722b8aaaf1fa8c09a4d14c445bc06a4c06e9f88 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:36:05 -0500 Subject: [PATCH 34/45] fix: create separate story for PublishDatasetModal.tsx WithCustomTerms --- .../PublishDatasetModal.stories.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx b/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx index 2490b01d3..eea4ca804 100644 --- a/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx +++ b/src/stories/dataset/publish-dataset/PublishDatasetModal.stories.tsx @@ -28,8 +28,8 @@ export const Default: Story = { collectionRepository={new CollectionMockRepository()} parentCollection={UpwardHierarchyNodeMother.createCollection()} persistentId={'test'} - license={undefined} - customTerms={CustomTermsMother.create()} + license={LicenseMother.create()} + customTerms={undefined} releasedVersionExists={false} handleClose={() => {}}> ) @@ -102,3 +102,18 @@ export const RequiresMajorVersionUpdate: Story = { handleClose={() => {}}> ) } +export const WithCustomTerms: Story = { + decorators: [WithLoggedInUser], + render: () => ( + {}}> + ) +} From 4771ad044e3662f53f942585d8627e05792664f7 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:36:52 -0500 Subject: [PATCH 35/45] fix: use location object to create CustomTerms url --- .../dataset/publish-dataset/PublishDatasetModal.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx index 9f27900dc..34637e38a 100644 --- a/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx +++ b/src/sections/dataset/publish-dataset/PublishDatasetModal.tsx @@ -129,9 +129,13 @@ export function PublishDatasetModal({ { - const termsUrl = `${Route.DATASETS}?${QueryParamKey.PERSISTENT_ID}=${persistentId}&${QueryParamKey.VERSION}=${DatasetNonNumericVersionSearchParam.DRAFT}&${QueryParamKey.TAB}=terms` - const newTabUrl = `${window.location.origin}${import.meta.env.BASE_URL}${termsUrl}` - window.open(newTabUrl, '_blank') + const searchParams = new URLSearchParams(location.search) + searchParams.set('tab', 'terms') + const newUrl = `${import.meta.env.BASE_URL}${ + location.pathname + }?${searchParams.toString()}` + + window.open(newUrl, '_blank') }} />
From 0356ccdf75a633819843a60f2e55dea753f7ad4f Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:37:07 -0500 Subject: [PATCH 36/45] fix: remove unused Route --- src/sections/Route.enum.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/sections/Route.enum.ts b/src/sections/Route.enum.ts index 4e94f6de9..94aa9582b 100644 --- a/src/sections/Route.enum.ts +++ b/src/sections/Route.enum.ts @@ -19,16 +19,6 @@ export const RouteWithParams = { COLLECTIONS: (collectionId?: string) => collectionId ? `/collections/${collectionId}` : Route.COLLECTIONS_BASE, CREATE_COLLECTION: (parentCollectionId: string) => `/collections/${parentCollectionId}/create`, - DATASETS: (persistentId: string, version?: string, tab?: string): string => { - let url = `${Route.DATASETS}?${QueryParamKey.PERSISTENT_ID}=${persistentId}` - if (version) { - url += `&${QueryParamKey.VERSION}=${version}` - } - if (tab) { - url += `&${QueryParamKey.TAB}=${tab}` - } - return url - }, CREATE_DATASET: (collectionId: string) => `/datasets/${collectionId}/create`, EDIT_COLLECTION: (collectionId: string) => `/collections/${collectionId}/edit` } From 431e9c825afc89020c4ddaf5646c20b3442b87a0 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 11 Feb 2025 15:51:55 -0500 Subject: [PATCH 37/45] fix: lint errors --- packages/design-system/src/lib/components/tabs/Tabs.tsx | 2 +- .../dataset/dataset-terms/EditDatasetTermsButton.spec.tsx | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/design-system/src/lib/components/tabs/Tabs.tsx b/packages/design-system/src/lib/components/tabs/Tabs.tsx index 0f9bdff18..ddbd1e455 100644 --- a/packages/design-system/src/lib/components/tabs/Tabs.tsx +++ b/packages/design-system/src/lib/components/tabs/Tabs.tsx @@ -1,4 +1,4 @@ -import { PropsWithChildren, useEffect, useState } from 'react' +import { PropsWithChildren } from 'react' import { Tab } from './Tab' import { Tabs as TabsBS } from 'react-bootstrap' diff --git a/tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx b/tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx index 6976cc984..c38f3dd17 100644 --- a/tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx +++ b/tests/component/sections/dataset/dataset-terms/EditDatasetTermsButton.spec.tsx @@ -1,7 +1,6 @@ import { EditDatasetTermsButton } from '@/sections/dataset/dataset-terms/EditDatasetTermsButton' import { ReactNode } from 'react' import { DatasetProvider } from '@/sections/dataset/DatasetProvider' -import { UserMother } from '@tests/component/users/domain/models/UserMother' import { DatasetMother, DatasetPermissionsMother @@ -26,7 +25,6 @@ describe('EditDatasetTermsButton', () => { } it('renders the EditDatasetTermsButton if the user has permission to update the dataset', () => { - const user = UserMother.create() const dataset = DatasetMother.create({ permissions: DatasetPermissionsMother.createWithUpdateDatasetAllowed() }) From c3ccb29eb4b7a59013f0add49a18d7a18aa6bb0c Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Wed, 12 Feb 2025 09:41:28 -0500 Subject: [PATCH 38/45] fix: render Terms of Access accordion if fields are empty and restricted files exist --- .../dataset/dataset-terms/DatasetTerms.tsx | 3 ++- .../dataset-terms/DatasetTerms.spec.tsx | 23 +++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index 0b4f94ad6..c1a501fe9 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -43,6 +43,7 @@ export function DatasetTerms({ const termsOfAccessIsEmpty = Object.values(termsOfUse.termsOfAccess).every( (value) => value === undefined || typeof value === 'boolean' ) + const displayTermsOfAccess = !termsOfAccessIsEmpty || restrictedFilesCount > 0 if (isLoading) { return @@ -61,7 +62,7 @@ export function DatasetTerms({ - {!termsOfAccessIsEmpty && ( + {displayTermsOfAccess && ( {t('termsTab.termsTitle')} diff --git a/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx index 8a9509dfe..aedb0b25f 100644 --- a/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx +++ b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx @@ -33,7 +33,7 @@ const singleRestrictedFilesCountInfo = FilesCountInfoMother.create({ const license = LicenseMother.create() const termsOfUse = TermsOfUseMother.create() -const emptyCustomTerms = TermsOfUseMother.create({ customTermsOfUse: undefined }) +const emptyCustomTerms = TermsOfUseMother.withoutCustomTerms() const emptyTermsOfAccess = TermsOfUseMother.create({ termsOfAccess: TermsOfAccessMother.createEmpty() @@ -248,7 +248,10 @@ describe('DatasetTerms', () => { cy.findByText('Study Completion').should('exist') cy.findByText(emptyCustomTerms.termsOfAccess.studyCompletion as string).should('exist') }) - it('does not render the terms of use AccordionItem if terms of use fields are empty', () => { + it('does not render the terms of use AccordionItem if terms of use fields are empty and no restricted files', () => { + fileRepository.getFilesCountInfoByDatasetPersistentId = cy + .stub() + .resolves(noRestrictedFilesCountInfo) cy.customMount( { cy.findByText('Restricted Files + Terms of Access').should('not.exist') }) + it('renders the terms of use AccordionItem if terms of use fields are empty and at least one restricted file', () => { + fileRepository.getFilesCountInfoByDatasetPersistentId = cy + .stub() + .resolves(singleRestrictedFilesCountInfo) + cy.customMount( + + ) + + cy.findByText('Restricted Files + Terms of Access').should('exist') + }) it('does not render Request Access field if there are no restricted files', () => { fileRepository.getFilesCountInfoByDatasetPersistentId = cy .stub() From 6fe6194b026a4009427cce342bb6fb7d95f528f3 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Wed, 12 Feb 2025 15:13:12 -0500 Subject: [PATCH 39/45] fix: follow conventions for optional props, move EditDatasetTermsButton.tsx container div to within the component --- .../DatasetCitationTooltip.tsx | 1 - .../dataset/dataset-summary/DatasetSummary.tsx | 2 +- .../dataset/dataset-summary/SummaryLicense.tsx | 2 +- .../dataset/dataset-terms/DatasetTerms.tsx | 9 +++++---- .../dataset/dataset-terms/DatasetTermsRow.tsx | 2 +- .../EditDatasetTermsButton.module.scss | 6 ++++++ .../dataset-terms/EditDatasetTermsButton.tsx | 18 ++++++++++-------- 7 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/sections/dataset/dataset-citation/DatasetCitationTooltip.tsx b/src/sections/dataset/dataset-citation/DatasetCitationTooltip.tsx index a9e2d2b04..9e7a7c1a3 100644 --- a/src/sections/dataset/dataset-citation/DatasetCitationTooltip.tsx +++ b/src/sections/dataset/dataset-citation/DatasetCitationTooltip.tsx @@ -12,7 +12,6 @@ export function DatasetCitationTooltip({ status }: DatasetCitationTooltipProps) if (status === DatasetPublishingStatus.RELEASED) { return <> } - return ( ) diff --git a/src/sections/dataset/dataset-summary/DatasetSummary.tsx b/src/sections/dataset/dataset-summary/DatasetSummary.tsx index 5c7fbed78..5d9bf73cb 100644 --- a/src/sections/dataset/dataset-summary/DatasetSummary.tsx +++ b/src/sections/dataset/dataset-summary/DatasetSummary.tsx @@ -5,7 +5,7 @@ import { MetadataBlockInfoRepository } from '../../../metadata-block-info/domain interface DatasetSummaryProps { summaryFields: DatasetMetadataBlock[] - license: DatasetLicense | undefined + license?: DatasetLicense metadataBlockInfoRepository: MetadataBlockInfoRepository onCustomTermsClick: () => void } diff --git a/src/sections/dataset/dataset-summary/SummaryLicense.tsx b/src/sections/dataset/dataset-summary/SummaryLicense.tsx index 215e62f4b..b49c668a5 100644 --- a/src/sections/dataset/dataset-summary/SummaryLicense.tsx +++ b/src/sections/dataset/dataset-summary/SummaryLicense.tsx @@ -3,7 +3,7 @@ import { DatasetLicense as LicenseModel } from '../../../dataset/domain/models/D import { useTranslation } from 'react-i18next' interface LicenseProps { - license: LicenseModel | undefined + license?: LicenseModel onCustomTermsClick?: () => void } diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index c1a501fe9..ca472ccf0 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -13,8 +13,9 @@ import { FileAccessOption } from '@/files/domain/models/FileCriteria' import { SpinnerSymbol } from '@/sections/dataset/dataset-files/files-table/spinner-symbol/SpinnerSymbol' import { CustomTerms } from '@/sections/dataset/dataset-terms/CustomTerms' import { TermsOfAccess } from '@/sections/dataset/dataset-terms/TermsOfAccess' -import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' import { License } from '@/sections/dataset/dataset-terms/License' +import { useSession } from '@/sections/session/SessionContext' +import { useDataset } from '@/sections/dataset/DatasetContext' interface DatasetTermsProps { license: DatasetLicense | undefined @@ -32,6 +33,8 @@ export function DatasetTerms({ datasetVersion }: DatasetTermsProps) { const { t } = useTranslation('dataset') + const { user } = useSession() + const { dataset } = useDataset() const { filesCountInfo, isLoading } = useGetFilesCountInfo({ filesRepository, datasetPersistentId, @@ -51,9 +54,7 @@ export function DatasetTerms({ return ( <> -
- -
+ {t('termsTab.licenseTitle')} diff --git a/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx b/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx index b6e8970bb..c58df651f 100644 --- a/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTermsRow.tsx @@ -6,7 +6,7 @@ import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' interface DatasetTermsRowProps { title: string tooltipMessage: string - value: string | undefined + value?: string } export function DatasetTermsRow({ title, tooltipMessage, value }: DatasetTermsRowProps) { diff --git a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.module.scss b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.module.scss index 2c56411ea..89806a165 100644 --- a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.module.scss +++ b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.module.scss @@ -2,3 +2,9 @@ margin-right: 0.3rem; margin-bottom: 0.2rem; } + +.edit-terms-button-container { + display: flex; + justify-content: flex-end; + margin-bottom: 1rem; +} diff --git a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx index 787bb5131..5a384e675 100644 --- a/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx +++ b/src/sections/dataset/dataset-terms/EditDatasetTermsButton.tsx @@ -21,13 +21,15 @@ export function EditDatasetTermsButton() { } return ( - +
+ +
) } From 735c7517810ac2e47c65c719375881d2dbcc2e0a Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Wed, 12 Feb 2025 15:17:20 -0500 Subject: [PATCH 40/45] fix: remove style from DatasetTerms.module.scss, (it has been moved to EditDatasetTermButton.module.scss ) --- src/sections/dataset/dataset-terms/DatasetTerms.module.scss | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.module.scss b/src/sections/dataset/dataset-terms/DatasetTerms.module.scss index 3e15f48eb..98f50427c 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.module.scss +++ b/src/sections/dataset/dataset-terms/DatasetTerms.module.scss @@ -1,11 +1,5 @@ @import 'node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module'; -.edit-terms-button-container { - display: flex; - justify-content: flex-end; - margin-bottom: 1rem; -} - .dataset-terms-row { margin-top: 1rem; margin-bottom: 1rem; From 288dc1a468b514f0f8f6640b1a31b6077fa817c3 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Wed, 12 Feb 2025 15:46:08 -0500 Subject: [PATCH 41/45] fix: remove unused customHooks --- src/sections/dataset/dataset-terms/DatasetTerms.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index ca472ccf0..912a37224 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -14,8 +14,6 @@ import { SpinnerSymbol } from '@/sections/dataset/dataset-files/files-table/spin import { CustomTerms } from '@/sections/dataset/dataset-terms/CustomTerms' import { TermsOfAccess } from '@/sections/dataset/dataset-terms/TermsOfAccess' import { License } from '@/sections/dataset/dataset-terms/License' -import { useSession } from '@/sections/session/SessionContext' -import { useDataset } from '@/sections/dataset/DatasetContext' interface DatasetTermsProps { license: DatasetLicense | undefined @@ -33,8 +31,6 @@ export function DatasetTerms({ datasetVersion }: DatasetTermsProps) { const { t } = useTranslation('dataset') - const { user } = useSession() - const { dataset } = useDataset() const { filesCountInfo, isLoading } = useGetFilesCountInfo({ filesRepository, datasetPersistentId, From 3f84eab571aa3fed8f525854320bd04290a1a1b0 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Wed, 12 Feb 2025 20:17:33 -0500 Subject: [PATCH 42/45] fix: added activeKey prop to Tabs --- .../src/lib/components/tabs/Tabs.tsx | 13 +++++-- .../tests/component/tabs/Tabs.spec.tsx | 38 +++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/packages/design-system/src/lib/components/tabs/Tabs.tsx b/packages/design-system/src/lib/components/tabs/Tabs.tsx index ddbd1e455..bbd6baf7d 100644 --- a/packages/design-system/src/lib/components/tabs/Tabs.tsx +++ b/packages/design-system/src/lib/components/tabs/Tabs.tsx @@ -3,13 +3,20 @@ import { Tab } from './Tab' import { Tabs as TabsBS } from 'react-bootstrap' interface TabsProps { - defaultActiveKey: string + defaultActiveKey?: string + activeKey?: string onSelect?: (key: string | null) => void } -function Tabs({ defaultActiveKey, onSelect, children }: PropsWithChildren) { +function Tabs({ defaultActiveKey, activeKey, onSelect, children }: PropsWithChildren) { + if (activeKey && !onSelect) { + throw new Error('Tabs component requires onSelect function when activeKey is provided') + } + if (!activeKey && !defaultActiveKey) { + throw new Error('Tabs component requires either activeKey or defaultActiveKey') + } return ( - + {children} ) diff --git a/packages/design-system/tests/component/tabs/Tabs.spec.tsx b/packages/design-system/tests/component/tabs/Tabs.spec.tsx index 1c8fb9590..d88c698a8 100644 --- a/packages/design-system/tests/component/tabs/Tabs.spec.tsx +++ b/packages/design-system/tests/component/tabs/Tabs.spec.tsx @@ -56,4 +56,42 @@ describe('Tabs', () => { cy.findByText('Tab 2').should('have.attr', 'disabled') }) + it('renders with active key', () => { + cy.mount( + {}}> + + Content 1 + + + Content 2 + + + Content 3 + + + ) + + cy.findByText('Tab 3').should('have.class', 'active') + cy.findByText('Content 3').should('have.class', 'show').and('have.class', 'active') + }) + + it('calls onSelect when a tab is selected', () => { + const onSelect = cy.stub().as('onSelect') + cy.mount( + + + Content 1 + + + Content 2 + + + Content 3 + + + ) + + cy.findByText('Tab 2').click() + cy.get('@onSelect').should('have.been.calledWith', 'key-2') + }) }) From daf6eeb7964bca16dc8545150581ca01b588d206 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Wed, 12 Feb 2025 20:24:53 -0500 Subject: [PATCH 43/45] fix: change errors to warnings, so that component behavior is not more restrictive than the Bootstrap component. --- packages/design-system/src/lib/components/tabs/Tabs.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/design-system/src/lib/components/tabs/Tabs.tsx b/packages/design-system/src/lib/components/tabs/Tabs.tsx index bbd6baf7d..a9f727659 100644 --- a/packages/design-system/src/lib/components/tabs/Tabs.tsx +++ b/packages/design-system/src/lib/components/tabs/Tabs.tsx @@ -10,10 +10,10 @@ interface TabsProps { function Tabs({ defaultActiveKey, activeKey, onSelect, children }: PropsWithChildren) { if (activeKey && !onSelect) { - throw new Error('Tabs component requires onSelect function when activeKey is provided') + console.warn('Tabs component requires onSelect function when activeKey is provided') } if (!activeKey && !defaultActiveKey) { - throw new Error('Tabs component requires either activeKey or defaultActiveKey') + console.warn('Tabs component requires either activeKey or defaultActiveKey') } return ( From afb30bd378a70c9d8fe8ff3a084ae722d81ee76e Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 18 Feb 2025 15:07:35 -0500 Subject: [PATCH 44/45] fix merge error --- .../collection-form/useSubmitCollection.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts b/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts index c3b81812d..0c51699d6 100644 --- a/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts +++ b/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts @@ -74,8 +74,8 @@ export function useSubmitCollection( const useFacetsFromParentChecked = formData[USE_FACETS_FROM_PARENT] const newOrUpdatedCollection: CollectionDTO = { - inheritFacetsFromParent: false, - inheritMetadataBlocksFromParent: false, + inheritFacetsFromParent: useFacetsFromParentChecked, + inheritMetadataBlocksFromParent: useMetadataFieldsFromParentChecked, name: formData.name, alias: formData.alias, type: formData.type, From e97d3fb7e0c56001112ba0f88523f134be2eeb33 Mon Sep 17 00:00:00 2001 From: Ellen Kraffmiller Date: Tue, 18 Feb 2025 15:15:36 -0500 Subject: [PATCH 45/45] fix: match order of fields to develop branch --- .../collection-form/useSubmitCollection.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts b/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts index 0c51699d6..625f54121 100644 --- a/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts +++ b/src/sections/shared/form/EditCreateCollectionForm/collection-form/useSubmitCollection.ts @@ -74,8 +74,6 @@ export function useSubmitCollection( const useFacetsFromParentChecked = formData[USE_FACETS_FROM_PARENT] const newOrUpdatedCollection: CollectionDTO = { - inheritFacetsFromParent: useFacetsFromParentChecked, - inheritMetadataBlocksFromParent: useMetadataFieldsFromParentChecked, name: formData.name, alias: formData.alias, type: formData.type, @@ -84,7 +82,9 @@ export function useSubmitCollection( contacts: contactsDTO, metadataBlockNames: metadataBlockNamesDTO, inputLevels: inputLevelsDTO, - facetIds: facetIdsDTO + facetIds: facetIdsDTO, + inheritMetadataBlocksFromParent: useMetadataFieldsFromParentChecked, + inheritFacetsFromParent: useFacetsFromParentChecked } if (mode === 'create') {