diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f90edbeb..c4b6b2d93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel - Changed the way we were handling DATE type metadata field validation to better match the backend validation and give users better error messages. For example, for an input like “foo AD”, we now show “Production Date is not a valid date. The AD year must be numeric.“. For an input like “99999 AD”, we now show “Production Date is not a valid date. The AD year cant be higher than 9999.“. For an input like “[-9999?], we now show “Production Date is not a valid date. The year in brackets cannot be negative.“, etc. - The SPA now fetches the runtime configuration from `config.js` on each load, allowing configurations without rebuilding the app. We don't use `.env` variables at build time anymore. - Renamed dataset template fetch/create use cases and DTOs to `getTemplatesByCollectionId` and `CreateTemplateDTO` for API alignment, and added new `getTemplate` and `deleteTemplate` use cases for retrieving a single template by ID and deleting templates. +- Dataset page Terms tab title now depends on permissions: users with dataset update permission see `Terms and Guestbook`, and read-only users see `Terms`. ### Fixed @@ -31,6 +32,7 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel - Show toast notification when API token is copied to clipboard. - Dataset versions: (1) file changes should be `Access: Restricted` instead of `isResticted: true/false`; (2) logic of View Detail button. (#879) - File versions: (1) logic of linking to a file version; (2)If file not included, show text information "File not included in this version.". (#879) +- Dataset page publish flow now avoids rendering duplicate tab sets by making tabs skeleton and tabs content mutually exclusive. ### Removed diff --git a/public/locales/en/dataset.json b/public/locales/en/dataset.json index 47c91d018..64740a8ac 100644 --- a/public/locales/en/dataset.json +++ b/public/locales/en/dataset.json @@ -2,6 +2,7 @@ "filesTabTitle": "Files", "metadataTabTitle": "Metadata", "termsTabTitle": "Terms and Guestbook", + "termsTabTitleReadOnly": "Terms", "anonymizedFieldValue": "withheld", "customTerms": { "title": "Custom Dataset Terms", diff --git a/public/locales/es/dataset.json b/public/locales/es/dataset.json index 30ad2dc4e..cf68b11cb 100644 --- a/public/locales/es/dataset.json +++ b/public/locales/es/dataset.json @@ -1,7 +1,8 @@ { "filesTabTitle": "Ficheros", "metadataTabTitle": "Metadatos", - "termsTabTitle": "Términos", + "termsTabTitle": "Términos y libros de visitas", + "termsTabTitleReadOnly": "Términos", "anonymizedFieldValue": "retirado", "customTerms": { "title": "Términos personalizados del dataset", diff --git a/src/sections/dataset/Dataset.tsx b/src/sections/dataset/Dataset.tsx index 2097aa8cd..6f52bc06f 100644 --- a/src/sections/dataset/Dataset.tsx +++ b/src/sections/dataset/Dataset.tsx @@ -113,6 +113,7 @@ export function Dataset({ const currentVersionNumber = dataset.version.number.toString() const canUpdateDataset = dataset.permissions.canUpdateDataset + const termsTabTitle = canUpdateDataset ? t('termsTabTitle') : t('termsTabTitleReadOnly') return ( <> @@ -164,87 +165,86 @@ export function Dataset({ - {publishInProgress && } - - {(!publishInProgress || !isDatasetLoading) && - (isCurrentVersionDeaccessioned && !canUpdateDataset ? ( - - -
- -
-
-
- ) : ( - - -
- {filesTabInfiniteScrollEnabled ? ( - - ) : ( - - )} -
-
- - -
- -
-
- - -
- + ) : isCurrentVersionDeaccessioned && !canUpdateDataset ? ( + + +
+ +
+
+
+ ) : ( + + +
+ {filesTabInfiniteScrollEnabled ? ( + -
-
- - -
- -
-
-
- ))} + )} +
+
+ + +
+ +
+
+ + +
+ +
+
+ + +
+ +
+
+
+ )} diff --git a/tests/component/dataset/domain/models/DatasetMother.ts b/tests/component/dataset/domain/models/DatasetMother.ts index 24f1d697f..fe5c56639 100644 --- a/tests/component/dataset/domain/models/DatasetMother.ts +++ b/tests/component/dataset/domain/models/DatasetMother.ts @@ -227,6 +227,26 @@ export class DatasetPermissionsMother { canDeleteDataset: false }) } + + static createWithReadOnlyAllowed(): DatasetPermissions { + return this.create({ + canDownloadFiles: true, + canUpdateDataset: false, + canPublishDataset: false, + canManageDatasetPermissions: false, + canManageFilesPermissions: false, + canDeleteDataset: false + }) + } +} + +export class DatasetWithoutPermissionsMother { + static create(props?: Partial): Dataset { + return DatasetMother.create({ + permissions: DatasetPermissionsMother.createWithNoDatasetPermissions(), + ...props + }) + } } export class DatasetLockMother { @@ -558,14 +578,7 @@ export class DatasetMother { } } ] as DatasetMetadataBlocks, - permissions: { - canDownloadFiles: true, - canUpdateDataset: false, - canPublishDataset: false, - canManageDatasetPermissions: false, - canManageFilesPermissions: false, - canDeleteDataset: false - }, + permissions: DatasetPermissionsMother.createWithReadOnlyAllowed(), locks: [], hasValidTermsOfAccess: true, hasOneTabularFileAtLeast: true, @@ -615,14 +628,7 @@ export class DatasetMother { static createDeaccessionedwithNoEditPermission(props?: Partial): Dataset { return this.create({ version: DatasetVersionMother.createDeaccessioned(), - permissions: { - canDownloadFiles: true, - canUpdateDataset: false, - canPublishDataset: false, - canManageDatasetPermissions: false, - canManageFilesPermissions: false, - canDeleteDataset: false - }, + permissions: DatasetPermissionsMother.createWithReadOnlyAllowed(), ...props }) } diff --git a/tests/component/sections/dataset/Dataset.spec.tsx b/tests/component/sections/dataset/Dataset.spec.tsx index e2a3107ef..9f8175738 100644 --- a/tests/component/sections/dataset/Dataset.spec.tsx +++ b/tests/component/sections/dataset/Dataset.spec.tsx @@ -1,6 +1,6 @@ import { DatasetRepository } from '../../../../src/dataset/domain/repositories/DatasetRepository' import { Dataset } from '../../../../src/sections/dataset/Dataset' -import { DatasetMother } from '../../dataset/domain/models/DatasetMother' +import { DatasetMother, DatasetPermissionsMother } from '../../dataset/domain/models/DatasetMother' import { LoadingProvider } from '../../../../src/shared/contexts/loading/LoadingProvider' import { ANONYMIZED_FIELD_VALUE, @@ -96,7 +96,8 @@ const testDataset = DatasetMother.create({ ] } } - ] + ], + permissions: DatasetPermissionsMother.createWithAllAllowed() }) const testFilesCountInfo = FilesCountInfoMother.create({ @@ -148,6 +149,7 @@ const versionSummaryInfo: DatasetVersionSummaryInfo[] = [ ] const testDatasetMetadataExportFormats = DatasetMetadataExportFormatsMother.create() +const termsTabLabelRegex = /^Terms(?: and Guestbook)?$/ describe('Dataset', () => { const mountWithDataset = ( @@ -368,6 +370,9 @@ describe('Dataset', () => { ) cy.findByText('Publish in Progress').should('exist') + cy.findAllByRole('tab', { name: 'Files' }).should('have.length', 1) + cy.findAllByRole('tab', { name: 'Metadata' }).should('have.length', 1) + cy.findAllByRole('tab', { name: 'Versions' }).should('have.length', 1) }) it('renders the breadcrumbs', () => { @@ -445,7 +450,7 @@ describe('Dataset', () => { cy.findAllByText(testDataset.version.title).should('exist') - const termsTab = cy.findByRole('tab', { name: 'Terms and Guestbook' }) + const termsTab = cy.findByRole('tab', { name: termsTabLabelRegex }) termsTab.should('exist') termsTab.click() @@ -453,6 +458,27 @@ describe('Dataset', () => { cy.findByText('Dataset Terms').should('exist') }) + it('renders the read-only terms tab title when user cannot edit dataset', () => { + const readOnlyDataset = DatasetMother.create({ + permissions: DatasetPermissionsMother.createWithUpdateDatasetNotAllowed() + }) + + mountWithDataset( + , + readOnlyDataset + ) + + cy.findByRole('tab', { name: 'Terms' }).should('exist') + cy.findByRole('tab', { name: 'Terms and Guestbook' }).should('not.exist') + }) + it('renders the Dataset Files tab', () => { mountWithDataset( { cy.findByRole('button', { name: 'Save Changes' }).click() cy.findByRole('button', { name: 'Cancel' }).click() - cy.findByRole('tab', { name: 'Terms and Guestbook' }).click() + cy.findByRole('tab', { name: /^Terms(?: and Guestbook)?$/ }).click() cy.findByText(/Data can be accessed through the university data center/i).should('exist') cy.findByText(/dataowner@university.edu/i).should('exist') cy.findByText(/500 MB/i).should('exist')