diff --git a/CHANGELOG.md b/CHANGELOG.md index a7f6dcae..22a27a98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel ### Added +- Collections: Added `allowedDatasetTypes` field to the [Collection](./src/collections/domain/models/Collection.ts) model. This field is optional and only populated the feature is enabled on the installation and configured on the collection. + ### Changed ### Fixed diff --git a/docs/useCases.md b/docs/useCases.md index 496ae7d8..8f51ada5 100644 --- a/docs/useCases.md +++ b/docs/useCases.md @@ -197,6 +197,20 @@ The `collectionIdOrAlias` is a generic collection identifier, which can be eithe If no collection identifier is specified, the default collection identifier; `:root` will be used. If you want to search for a different collection, you must add the collection identifier as a parameter in the use case call. +##### Collection Allowed Dataset Types + +Collections can optionally restrict which [DatasetType](../src/datasets/domain/models/DatasetType.ts) objects can be created within them. The `allowedDatasetTypes` field contains an array of dataset types allowed on the collection when configured. If not configured on the collection, this field will be `undefined`. + +```typescript +getCollection.execute('myCollection').then((collection: Collection) => { + if (collection.allowedDatasetTypes) { + collection.allowedDatasetTypes.forEach((datasetType) => { + console.log(`Allowed type: ${datasetType.displayName}`) + }) + } +}) +``` + #### Get Collection Storage Driver Returns a [StorageDriver](../src/core/domain/models/StorageDriver.ts) instance describing the collection's assigned storage driver. diff --git a/src/collections/domain/models/Collection.ts b/src/collections/domain/models/Collection.ts index cbcf01ca..586b054b 100644 --- a/src/collections/domain/models/Collection.ts +++ b/src/collections/domain/models/Collection.ts @@ -1,6 +1,7 @@ import { DvObjectOwnerNode } from '../../../core' import { CollectionContact } from './CollectionContact' import { CollectionType } from './CollectionType' +import { DatasetType } from '../../../datasets' export interface Collection { id: number @@ -13,6 +14,7 @@ export interface Collection { inputLevels?: CollectionInputLevel[] type: CollectionType contacts?: CollectionContact[] + allowedDatasetTypes?: DatasetType[] isMetadataBlockRoot: boolean isFacetRoot: boolean childCount: number diff --git a/src/collections/infra/repositories/transformers/CollectionPayload.ts b/src/collections/infra/repositories/transformers/CollectionPayload.ts index f478ca13..53ec59fd 100644 --- a/src/collections/infra/repositories/transformers/CollectionPayload.ts +++ b/src/collections/infra/repositories/transformers/CollectionPayload.ts @@ -10,6 +10,7 @@ export interface CollectionPayload { isPartOf: OwnerNodePayload inputLevels?: CollectionInputLevelPayload[] dataverseContacts?: CollectionContactPayload[] + allowedDatasetTypes?: AllowedDatasetTypePayload[] dataverseType: string isMetadataBlockRoot: boolean isFacetRoot: boolean @@ -26,3 +27,10 @@ export interface CollectionContactPayload { contactEmail: string displayOrder: number } + +export interface AllowedDatasetTypePayload { + id: number + name: string + displayName: string + description?: string +} diff --git a/src/collections/infra/repositories/transformers/collectionTransformers.ts b/src/collections/infra/repositories/transformers/collectionTransformers.ts index fa23b8ed..008c15cd 100644 --- a/src/collections/infra/repositories/transformers/collectionTransformers.ts +++ b/src/collections/infra/repositories/transformers/collectionTransformers.ts @@ -3,7 +3,8 @@ import { AxiosResponse } from 'axios' import { CollectionContactPayload, CollectionInputLevelPayload, - CollectionPayload + CollectionPayload, + AllowedDatasetTypePayload } from './CollectionPayload' import { transformPayloadToOwnerNode } from '../../../../core/infra/repositories/transformers/dvObjectOwnerNodeTransformer' import { CollectionFacet } from '../../../domain/models/CollectionFacet' @@ -13,7 +14,7 @@ import { CollectionItemSubset, CountPerObjectType } from '../../../domain/models/CollectionItemSubset' -import { DatasetPreview } from '../../../../datasets' +import { DatasetPreview, DatasetType } from '../../../../datasets' import { FilePreview } from '../../../../files' import { DatasetPreviewPayload } from '../../../../datasets/infra/repositories/transformers/DatasetPreviewPayload' import { FilePreviewPayload } from '../../../../files/infra/repositories/transformers/FilePreviewPayload' @@ -82,6 +83,11 @@ const transformPayloadToCollection = (collectionPayload: CollectionPayload): Col }), ...(collectionPayload.dataverseContacts && { contacts: transformContactsPayloadToContacts(collectionPayload.dataverseContacts) + }), + ...(collectionPayload.allowedDatasetTypes && { + allowedDatasetTypes: transformAllowedDatasetTypesPayloadToAllowedDatasetTypes( + collectionPayload.allowedDatasetTypes + ) }) } return collectionModel @@ -252,3 +258,14 @@ const transformContactsPayloadToContacts = ( displayOrder: contactPayload.displayOrder })) } + +const transformAllowedDatasetTypesPayloadToAllowedDatasetTypes = ( + allowedDatasetTypesPayload: AllowedDatasetTypePayload[] +): DatasetType[] => { + return allowedDatasetTypesPayload.map((allowedDatasetType) => ({ + id: allowedDatasetType.id, + name: allowedDatasetType.name, + displayName: allowedDatasetType.displayName, + description: allowedDatasetType.description + })) +} diff --git a/test/integration/collections/CollectionsRepository.test.ts b/test/integration/collections/CollectionsRepository.test.ts index 56a24650..273718a6 100644 --- a/test/integration/collections/CollectionsRepository.test.ts +++ b/test/integration/collections/CollectionsRepository.test.ts @@ -176,6 +176,13 @@ describe('CollectionsRepository', () => { expect(actualAfterDatasetDeletion.childCount).toBe(0) await deleteCollectionViaApi(parentCollectionAlias) }) + + test('should transform allowedDatasetTypes correctly when retrieving a collection', async () => { + const actual = await sut.getCollection(testCollectionAlias) + expect( + actual.allowedDatasetTypes === undefined || Array.isArray(actual.allowedDatasetTypes) + ).toBe(true) + }) }) describe('publishCollection', () => { diff --git a/test/testHelpers/collections/collectionHelper.ts b/test/testHelpers/collections/collectionHelper.ts index 6d274deb..4b69a058 100644 --- a/test/testHelpers/collections/collectionHelper.ts +++ b/test/testHelpers/collections/collectionHelper.ts @@ -45,6 +45,14 @@ export const createCollectionModel = (): Collection => { displayOrder: 0 } ], + allowedDatasetTypes: [ + { + id: 1, + name: 'review', + displayName: 'Review', + description: 'A review of a dataset compiled by the expert community.' + } + ], isMetadataBlockRoot: true, isFacetRoot: true, childCount: 0 @@ -75,6 +83,14 @@ export const createCollectionPayload = (): CollectionPayload => { displayOrder: 0 } ], + allowedDatasetTypes: [ + { + id: 1, + name: 'review', + displayName: 'Review', + description: 'A review of a dataset compiled by the expert community.' + } + ], isMetadataBlockRoot: true, isFacetRoot: true, childCount: 0