diff --git a/CHANGELOG.md b/CHANGELOG.md index 56926bf8..6f3a2c92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,18 +8,27 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel ### Added +- Datasets: Added `updateDatasetLicense` use case and repository method to support Dataverse endpoint `PUT /datasets/{id}/license`, for updating dataset license or custom terms. +- Datasets: Added `getDatasetStorageDriver` use case and repository method to support Dataverse endpoint `GET /datasets/{identifier}/storageDriver`, for retrieving dataset storage driver configuration with properties: name, type, label, directUpload, directDownload, and uploadOutOfBand. - Datasets: Added `updateDatasetLicense` use case and repository method to support Dataverse endpoint `PUT /datasets/{id}/license`, for updating dataset license or custom terms - New Use Case: [Get Collections For Linking Use Case](./docs/useCases.md#get-collections-for-linking). -- New Use Case: [Create a Dataset Template](./docs/useCases.md#create-a-dataset-template) under Collections. - +- New Use Case: [Create a Template](./docs/useCases.md#create-a-template) under Templates. +- New Use Case: [Get a Template](./docs/useCases.md#get-a-template) under Templates. +- New Use Case: [Delete a Template](./docs/useCases.md#delete-a-template) under Templates. - New Use Case: [Update Terms of Access](./docs/useCases.md#update-terms-of-access). ### Changed -- Add pagination query parameters to Dataset Version Summeries and File Version Summaries use cases +- Add pagination query parameters to Dataset Version Summeries and File Version Summaries use cases. +- Templates: Rename `CreateDatasetTemplateDTO` to `CreateTemplateDTO`. +- Templates: Rename `createDatasetTemplate` repository method to `createTemplate`. +- Templates: Rename `getDatasetTemplates` repository method to `getTemplatesByCollectionId`. ### Fixed +- In GetAllNotificationsByUser use case, additionalInfo field is returned as an object instead of a string. +- In GetAllNotificationsByUser use case, added support for filtering unread messages and pagination. + ### Removed - Removed date fields validations in create and update dataset use cases, since validation is already handled in the backend and SPA frontend (other clients should perform client side validation also). This avoids duplicated logic and keeps the package focused on its core responsibility. @@ -48,7 +57,7 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel - Use cases for External Tools: GetExternalTools, GetDatasetExternalToolResolved, GetFileExternalToolResolved. -- Use case: GetDatasetTemplates. +- Use case: GetTemplatesByCollectionId. - Use case: GetAvailableStandardLicenses. diff --git a/README.md b/README.md index 44b2266d..69ee09e0 100644 --- a/README.md +++ b/README.md @@ -36,18 +36,18 @@ getDataset.execute(datasetIdentifier, datasetVersion).then((dataset: Dataset) => /* ... */ ``` -For detailed information about available use cases see [Use Cases Docs](https://github.com/IQSS/dataverse-client-javascript/blob/main/docs/useCases.md). +For detailed information about available use cases see [Use Cases Docs](docs/useCases.md). -For detailed information about usage see [Usage Docs](https://github.com/IQSS/dataverse-client-javascript/blob/main/docs/usage.md). +For detailed information about usage see [Usage Docs](docs/usage.md). ## Changelog -See [CHANGELOG.md](https://github.com/IQSS/dataverse-client-javascript/blob/main/CHANGELOG.md) for a detailed history of changes to this project. +See [CHANGELOG.md](CHANGELOG.md) for a detailed history of changes to this project. ## Contributing -Want to add a new use case or improve an existing one? Please check the [Contributing](https://github.com/IQSS/dataverse-client-javascript/blob/main/CONTRIBUTING.md) section. +Want to add a new use case or improve an existing one? Please check the [Contributing](CONTRIBUTING.md) section. ## License -This project is open source and available under the [MIT License](https://github.com/IQSS/dataverse-client-javascript/blob/main/LICENSE). +This project is open source and available under the [MIT License](LICENSE). diff --git a/docs/useCases.md b/docs/useCases.md index 3254e4a5..f77a40e1 100644 --- a/docs/useCases.md +++ b/docs/useCases.md @@ -25,7 +25,13 @@ The different use cases currently available in the package are classified below, - [Update Collection Featured Items](#update-collection-featured-items) - [Delete Collection Featured Items](#delete-collection-featured-items) - [Delete a Collection Featured Item](#delete-a-collection-featured-item) - - [Create a Dataset Template](#create-a-dataset-template) +- [Templates](#Templates) + - [Templates read use cases](#templates-read-use-cases) + - [Get a Template](#get-a-template) + - [Get Templates By Collection Id](#get-templates-by-collection-id) + - [Templates write use cases](#templates-write-use-cases) + - [Create a Template](#create-a-template) + - [Delete a Template](#delete-a-template) - [Datasets](#Datasets) - [Datasets read use cases](#datasets-read-use-cases) - [Get a Dataset](#get-a-dataset) @@ -41,6 +47,7 @@ The different use cases currently available in the package are classified below, - [Get Dataset Linked Collections](#get-dataset-linked-collections) - [Get Dataset Available Categories](#get-dataset-available-categories) - [Get Dataset Templates](#get-dataset-templates) + - [Get Dataset Storage Driver](#get-dataset-storage-driver) - [Get Dataset Available Dataset Types](#get-dataset-available-dataset-types) - [Get Dataset Available Dataset Type](#get-dataset-available-dataset-type) - [Datasets write use cases](#datasets-write-use-cases) @@ -569,18 +576,60 @@ deleteCollectionFeaturedItem.execute(featuredItemId) _See [use case](../src/collections/domain/useCases/DeleteCollectionFeaturedItem.ts)_ definition. -#### Create a Dataset Template +## Templates -Creates a dataset template for a given Dataverse collection id or alias. +### Templates Read Use Cases + +#### Get a Template + +Returns a [Template](../src/templates/domain/models/Template.ts) by its template id. + +##### Example call: + +```typescript +import { getTemplate } from '@iqss/dataverse-client-javascript' + +const templateId = 12345 + +getTemplate.execute(templateId).then((template: Template) => { + /* ... */ +}) +``` + +_See [use case](../src/templates/domain/useCases/GetTemplate.ts)_ definition. + +#### Get Templates By Collection Id + +Returns a [Template](../src/templates/domain/models/Template.ts) array containing the templates of the requested collection, given the collection identifier or alias. + +##### Example call: + +```typescript +import { getTemplatesByCollectionId } from '@iqss/dataverse-client-javascript' + +const collectionIdOrAlias = 12345 + +getTemplatesByCollectionId.execute(collectionIdOrAlias).then((template: Template[]) => { + /* ... */ +}) +``` + +_See [use case](../src/templates/domain/useCases/GetTemplatesByCollectionId.ts)_ definition. + +### Templates Write Use Cases + +#### Create a Template + +Creates a template for a given Dataverse collection id or alias. ##### Example call: ```typescript -import { createDatasetTemplate } from '@iqss/dataverse-client-javascript' -import { TemplateCreateDTO } from '@iqss/dataverse-client-javascript' +import { createTemplate } from '@iqss/dataverse-client-javascript' +import { CreateTemplateDTO } from '@iqss/dataverse-client-javascript' const collectionAlias = ':root' -const template: TemplateCreateDTO = { +const template: CreateTemplateDTO = { name: 'Dataverse template', isDefault: true, fields: [ @@ -599,10 +648,26 @@ const template: TemplateCreateDTO = { instructions: [{ instructionField: 'author', instructionText: 'The author data' }] } -await createDatasetTemplate.execute(template, collectionAlias) +await createTemplate.execute(template, collectionAlias) ``` -_See [use case](../src/collections/domain/useCases/CreateDatasetTemplate.ts) implementation_. +_See [use case](../src/templates/domain/useCases/CreateTemplate.ts) implementation_. + +#### Delete a Template + +Deletes a template by its template id. + +##### Example call: + +```typescript +import { deleteTemplate } from '@iqss/dataverse-client-javascript' + +const templateId = 12345 + +await deleteTemplate.execute(templateId) +``` + +_See [use case](../src/templates/domain/useCases/DeleteTemplate.ts)_ definition. ## Datasets @@ -1333,6 +1398,8 @@ _See [use case](../src/datasets/domain/useCases/GetDatasetAvailableCategories.ts The `datasetId` parameter is a number for numeric identifiers or string for persistent identifiers. +# <<<<<<< HEAD + #### Get Dataset Templates Returns a [DatasetTemplate](../src/datasets/domain/models/DatasetTemplate.ts) array containing the dataset templates of the requested collection, given the collection identifier or alias. @@ -1351,6 +1418,32 @@ getDatasetTemplates.execute(collectionIdOrAlias).then((datasetTemplates: Dataset _See [use case](../src/datasets/domain/useCases/GetDatasetTemplates.ts)_ definition. +#### Get Dataset Storage Driver + +Returns a [StorageDriver](../src/datasets/domain/models/StorageDriver.ts) instance with storage driver configuration for a dataset, including properties like name, type, label, and upload/download capabilities. + +##### Example call: + +```typescript +import { getDatasetStorageDriver } from '@iqss/dataverse-client-javascript' + +/* ... */ + +const datasetId = 'doi:10.77777/FK2/AAAAAA' + +getDatasetStorageDriver.execute(datasetId).then((storageDriver: StorageDriver) => { + /* ... */ +}) + +/* ... */ +``` + +_See [use case](../src/datasets/domain/useCases/GetDatasetStorageDriver.ts) implementation_. + +The `datasetId` parameter can be a string, for persistent identifiers, or a number, for numeric identifiers. + +> > > > > > > develop + #### Add a Dataset Type Adds a dataset types that can be used at dataset creation. diff --git a/src/collections/domain/repositories/ICollectionsRepository.ts b/src/collections/domain/repositories/ICollectionsRepository.ts index cae28415..bc8960c8 100644 --- a/src/collections/domain/repositories/ICollectionsRepository.ts +++ b/src/collections/domain/repositories/ICollectionsRepository.ts @@ -12,7 +12,6 @@ import { CollectionItemType } from '../../../collections/domain/models/Collectio import { CollectionLinks } from '../models/CollectionLinks' import { CollectionSummary } from '../models/CollectionSummary' import { LinkingObjectType } from '../useCases/GetCollectionsForLinking' -import { CreateDatasetTemplateDTO } from '../dtos/CreateDatasetTemplateDTO' export interface ICollectionsRepository { getCollection(collectionIdOrAlias: number | string): Promise @@ -69,8 +68,4 @@ export interface ICollectionsRepository { searchTerm: string, alreadyLinked: boolean ): Promise - createDatasetTemplate( - collectionIdOrAlias: number | string, - template: CreateDatasetTemplateDTO - ): Promise } diff --git a/src/collections/domain/useCases/CreateDatasetTemplate.ts b/src/collections/domain/useCases/CreateDatasetTemplate.ts deleted file mode 100644 index ffb443f6..00000000 --- a/src/collections/domain/useCases/CreateDatasetTemplate.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ROOT_COLLECTION_ID } from '../models/Collection' -import { UseCase } from '../../../core/domain/useCases/UseCase' -import { ICollectionsRepository } from '../repositories/ICollectionsRepository' -import { CreateDatasetTemplateDTO } from '../dtos/CreateDatasetTemplateDTO' - -export class CreateDatasetTemplate implements UseCase { - private collectionsRepository: ICollectionsRepository - - constructor(collectionsRepository: ICollectionsRepository) { - this.collectionsRepository = collectionsRepository - } - - /** - * Creates a Dataset Template in the specified collection. - * - * @param {CreateDatasetTemplateDTO} template - Template definition payload. - * @param {number | string} [collectionIdOrAlias = ':root'] - A generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId) - * If this parameter is not set, the default value is: ':root'. - * @returns {Promise} - */ - async execute( - template: CreateDatasetTemplateDTO, - collectionIdOrAlias: number | string = ROOT_COLLECTION_ID - ): Promise { - return await this.collectionsRepository.createDatasetTemplate(collectionIdOrAlias, template) - } -} diff --git a/src/collections/index.ts b/src/collections/index.ts index df7b6af5..59e2e50b 100644 --- a/src/collections/index.ts +++ b/src/collections/index.ts @@ -16,7 +16,6 @@ import { LinkCollection } from './domain/useCases/LinkCollection' import { UnlinkCollection } from './domain/useCases/UnlinkCollection' import { GetCollectionLinks } from './domain/useCases/GetCollectionLinks' import { GetCollectionsForLinking } from './domain/useCases/GetCollectionsForLinking' -import { CreateDatasetTemplate } from './domain/useCases/CreateDatasetTemplate' const collectionsRepository = new CollectionsRepository() @@ -37,7 +36,6 @@ const linkCollection = new LinkCollection(collectionsRepository) const unlinkCollection = new UnlinkCollection(collectionsRepository) const getCollectionLinks = new GetCollectionLinks(collectionsRepository) const getCollectionsForLinking = new GetCollectionsForLinking(collectionsRepository) -const createDatasetTemplate = new CreateDatasetTemplate(collectionsRepository) export { getCollection, @@ -56,8 +54,7 @@ export { linkCollection, unlinkCollection, getCollectionLinks, - getCollectionsForLinking, - createDatasetTemplate + getCollectionsForLinking } export { Collection, CollectionInputLevel } from './domain/models/Collection' export { CollectionFacet } from './domain/models/CollectionFacet' diff --git a/src/collections/infra/repositories/CollectionsRepository.ts b/src/collections/infra/repositories/CollectionsRepository.ts index 53ebfff3..e0e459b0 100644 --- a/src/collections/infra/repositories/CollectionsRepository.ts +++ b/src/collections/infra/repositories/CollectionsRepository.ts @@ -40,7 +40,6 @@ import { ReadError } from '../../../core/domain/repositories/ReadError' import { CollectionLinks } from '../../domain/models/CollectionLinks' import { CollectionSummary } from '../../domain/models/CollectionSummary' import { LinkingObjectType } from '../../domain/useCases/GetCollectionsForLinking' -import { CreateDatasetTemplateDTO } from '../../domain/dtos/CreateDatasetTemplateDTO' export interface NewCollectionRequestPayload { alias: string @@ -529,18 +528,4 @@ export class CollectionsRepository extends ApiRepository implements ICollections throw error }) } - - public async createDatasetTemplate( - collectionIdOrAlias: number | string, - template: CreateDatasetTemplateDTO - ): Promise { - return this.doPost( - `/${this.collectionsResourceName}/${collectionIdOrAlias}/templates`, - template - ) - .then(() => undefined) - .catch((error) => { - throw error - }) - } } diff --git a/src/datasets/domain/models/StorageDriver.ts b/src/datasets/domain/models/StorageDriver.ts new file mode 100644 index 00000000..9c04b400 --- /dev/null +++ b/src/datasets/domain/models/StorageDriver.ts @@ -0,0 +1,8 @@ +export interface StorageDriver { + name: string + type: string + label: string + directUpload: boolean + directDownload: boolean + uploadOutOfBand: boolean +} diff --git a/src/datasets/domain/repositories/IDatasetsRepository.ts b/src/datasets/domain/repositories/IDatasetsRepository.ts index 8a52f8f9..09859777 100644 --- a/src/datasets/domain/repositories/IDatasetsRepository.ts +++ b/src/datasets/domain/repositories/IDatasetsRepository.ts @@ -12,11 +12,11 @@ import { DatasetVersionSummarySubset } from '../models/DatasetVersionSummaryInfo import { DatasetLinkedCollection } from '../models/DatasetLinkedCollection' import { CitationFormat } from '../models/CitationFormat' import { FormattedCitation } from '../models/FormattedCitation' -import { DatasetTemplate } from '../models/DatasetTemplate' import { DatasetType } from '../models/DatasetType' import { TermsOfAccess } from '../models/Dataset' import { DatasetLicenseUpdateRequest } from '../dtos/DatasetLicenseUpdateRequest' import { DatasetTypeDTO } from '../dtos/DatasetTypeDTO' +import { StorageDriver } from '../models/StorageDriver' export interface IDatasetsRepository { getDataset( @@ -84,7 +84,6 @@ export interface IDatasetsRepository { format: CitationFormat, includeDeaccessioned?: boolean ): Promise - getDatasetTemplates(collectionIdOrAlias: number | string): Promise getDatasetAvailableDatasetTypes(): Promise getDatasetAvailableDatasetType(datasetTypeId: number | string): Promise addDatasetType(datasetType: DatasetTypeDTO): Promise @@ -102,4 +101,5 @@ export interface IDatasetsRepository { datasetId: number | string, payload: DatasetLicenseUpdateRequest ): Promise + getDatasetStorageDriver(datasetId: number | string): Promise } diff --git a/src/datasets/domain/useCases/GetDatasetStorageDriver.ts b/src/datasets/domain/useCases/GetDatasetStorageDriver.ts new file mode 100644 index 00000000..361d1db9 --- /dev/null +++ b/src/datasets/domain/useCases/GetDatasetStorageDriver.ts @@ -0,0 +1,21 @@ +import { UseCase } from '../../../core/domain/useCases/UseCase' +import { IDatasetsRepository } from '../repositories/IDatasetsRepository' +import { StorageDriver } from '../models/StorageDriver' + +export class GetDatasetStorageDriver implements UseCase { + private datasetsRepository: IDatasetsRepository + + constructor(datasetsRepository: IDatasetsRepository) { + this.datasetsRepository = datasetsRepository + } + + /** + * Returns the storage driver information for a given Dataset. + * + * @param {number | string} [datasetId] - The dataset identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers). + * @returns {Promise} + */ + async execute(datasetId: number | string): Promise { + return this.datasetsRepository.getDatasetStorageDriver(datasetId) + } +} diff --git a/src/datasets/domain/useCases/GetDatasetTemplates.ts b/src/datasets/domain/useCases/GetDatasetTemplates.ts deleted file mode 100644 index 6878e625..00000000 --- a/src/datasets/domain/useCases/GetDatasetTemplates.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ROOT_COLLECTION_ID } from '../../../collections/domain/models/Collection' -import { UseCase } from '../../../core/domain/useCases/UseCase' -import { DatasetTemplate } from '../models/DatasetTemplate' -import { IDatasetsRepository } from '../repositories/IDatasetsRepository' - -export class GetDatasetTemplates implements UseCase { - private datasetsRepository: IDatasetsRepository - - constructor(datasetsRepository: IDatasetsRepository) { - this.datasetsRepository = datasetsRepository - } - - /** - * Returns a DatasetTemplate array containing the dataset templates of the requested collection, given the collection identifier or alias. - * - * @param {number | string} [collectionIdOrAlias = ':root'] - A generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId) - * If this parameter is not set, the default value is: ':root' - * @returns {Promise} - */ - async execute( - collectionIdOrAlias: number | string = ROOT_COLLECTION_ID - ): Promise { - return await this.datasetsRepository.getDatasetTemplates(collectionIdOrAlias) - } -} diff --git a/src/datasets/index.ts b/src/datasets/index.ts index b8edb5b3..3c081fc6 100644 --- a/src/datasets/index.ts +++ b/src/datasets/index.ts @@ -31,9 +31,9 @@ import { LinkDatasetTypeWithMetadataBlocks } from './domain/useCases/LinkDataset import { SetAvailableLicensesForDatasetType } from './domain/useCases/SetAvailableLicensesForDatasetType' import { DeleteDatasetType } from './domain/useCases/DeleteDatasetType' import { GetDatasetCitationInOtherFormats } from './domain/useCases/GetDatasetCitationInOtherFormats' -import { GetDatasetTemplates } from './domain/useCases/GetDatasetTemplates' import { UpdateTermsOfAccess } from './domain/useCases/UpdateTermsOfAccess' import { UpdateDatasetLicense } from './domain/useCases/UpdateDatasetLicense' +import { GetDatasetStorageDriver } from './domain/useCases/GetDatasetStorageDriver' const datasetsRepository = new DatasetsRepository() @@ -81,9 +81,9 @@ const setAvailableLicensesForDatasetType = new SetAvailableLicensesForDatasetTyp ) const deleteDatasetType = new DeleteDatasetType(datasetsRepository) const getDatasetCitationInOtherFormats = new GetDatasetCitationInOtherFormats(datasetsRepository) -const getDatasetTemplates = new GetDatasetTemplates(datasetsRepository) const updateTermsOfAccess = new UpdateTermsOfAccess(datasetsRepository) const updateDatasetLicense = new UpdateDatasetLicense(datasetsRepository) +const getDatasetStorageDriver = new GetDatasetStorageDriver(datasetsRepository) export { getDataset, @@ -107,7 +107,6 @@ export { getDatasetLinkedCollections, getDatasetAvailableCategories, getDatasetCitationInOtherFormats, - getDatasetTemplates, updateTermsOfAccess, getDatasetAvailableDatasetTypes, getDatasetAvailableDatasetType, @@ -115,7 +114,8 @@ export { linkDatasetTypeWithMetadataBlocks, setAvailableLicensesForDatasetType, deleteDatasetType, - updateDatasetLicense + updateDatasetLicense, + getDatasetStorageDriver } export { DatasetNotNumberedVersion } from './domain/models/DatasetNotNumberedVersion' export { DatasetUserPermissions } from './domain/models/DatasetUserPermissions' @@ -154,3 +154,4 @@ export { export { DatasetLinkedCollection } from './domain/models/DatasetLinkedCollection' export { DatasetType } from './domain/models/DatasetType' export { DatasetTypeDTO } from './domain/dtos/DatasetTypeDTO' +export { StorageDriver } from './domain/models/StorageDriver' diff --git a/src/datasets/infra/repositories/DatasetsRepository.ts b/src/datasets/infra/repositories/DatasetsRepository.ts index 849cf658..c29db6c0 100644 --- a/src/datasets/infra/repositories/DatasetsRepository.ts +++ b/src/datasets/infra/repositories/DatasetsRepository.ts @@ -1,4 +1,3 @@ -import { AxiosResponse } from 'axios' import { ApiRepository } from '../../../core/infra/repositories/ApiRepository' import { IDatasetsRepository } from '../../domain/repositories/IDatasetsRepository' import { Dataset, VersionUpdateType } from '../../domain/models/Dataset' @@ -25,14 +24,12 @@ import { DatasetLinkedCollection } from '../../domain/models/DatasetLinkedCollec import { CitationFormat } from '../../domain/models/CitationFormat' import { transformDatasetLinkedCollectionsResponseToDatasetLinkedCollection } from './transformers/datasetLinkedCollectionsTransformers' import { FormattedCitation } from '../../domain/models/FormattedCitation' -import { DatasetTemplate } from '../../domain/models/DatasetTemplate' -import { DatasetTemplatePayload } from './transformers/DatasetTemplatePayload' -import { transformDatasetTemplatePayloadToDatasetTemplate } from './transformers/datasetTemplateTransformers' import { DatasetType } from '../../domain/models/DatasetType' import { TermsOfAccess } from '../../domain/models/Dataset' import { transformTermsOfAccessToUpdatePayload } from './transformers/termsOfAccessTransformers' import { DatasetLicenseUpdateRequest } from '../../domain/dtos/DatasetLicenseUpdateRequest' import { DatasetTypeDTO } from '../../domain/dtos/DatasetTypeDTO' +import { StorageDriver } from '../../domain/models/StorageDriver' export interface GetAllDatasetPreviewsQueryParams { per_page?: number @@ -402,18 +399,6 @@ export class DatasetsRepository extends ApiRepository implements IDatasetsReposi }) } - public async getDatasetTemplates( - collectionIdOrAlias: number | string - ): Promise { - return this.doGet(`/dataverses/${collectionIdOrAlias}/templates`, true) - .then((response: AxiosResponse<{ data: DatasetTemplatePayload[] }>) => - transformDatasetTemplatePayloadToDatasetTemplate(response.data.data) - ) - .catch((error) => { - throw error - }) - } - public async getDatasetAvailableDatasetTypes(): Promise { return this.doGet(this.buildApiEndpoint(this.datasetsResourceName, 'datasetTypes')) .then((response) => response.data.data) @@ -515,4 +500,15 @@ export class DatasetsRepository extends ApiRepository implements IDatasetsReposi throw error }) } + + public async getDatasetStorageDriver(datasetId: number | string): Promise { + return this.doGet( + this.buildApiEndpoint(this.datasetsResourceName, 'storageDriver', datasetId), + true + ) + .then((response) => response.data.data as StorageDriver) + .catch((error) => { + throw error + }) + } } diff --git a/src/datasets/infra/repositories/transformers/datasetTemplateTransformers.ts b/src/datasets/infra/repositories/transformers/datasetTemplateTransformers.ts deleted file mode 100644 index 32486199..00000000 --- a/src/datasets/infra/repositories/transformers/datasetTemplateTransformers.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { transformPayloadLicenseToLicense } from '../../../../licenses/domain/repositories/transformers/licenseTransformers' -import { DatasetTemplate } from '../../../domain/models/DatasetTemplate' -import { DatasetTemplatePayload } from './DatasetTemplatePayload' -import { transformPayloadToDatasetMetadataBlocks } from './datasetTransformers' - -export const transformDatasetTemplatePayloadToDatasetTemplate = ( - collectionDatasetTemplatePayload: DatasetTemplatePayload[] -): DatasetTemplate[] => { - return collectionDatasetTemplatePayload.map((payload) => { - const datasetTemplate: DatasetTemplate = { - id: payload.id, - name: payload.name, - collectionAlias: payload.dataverseAlias, - isDefault: payload.isDefault, - usageCount: payload.usageCount, - createTime: payload.createTime, - createDate: payload.createDate, - datasetMetadataBlocks: transformPayloadToDatasetMetadataBlocks(payload.datasetFields, false), - instructions: payload.instructions.map((instruction) => ({ - instructionField: instruction.instructionField, - instructionText: instruction.instructionText - })), - termsOfUse: { - termsOfAccess: { - fileAccessRequest: payload.termsOfUseAndAccess.fileAccessRequest, - termsOfAccessForRestrictedFiles: payload.termsOfUseAndAccess.termsOfAccess, - dataAccessPlace: payload.termsOfUseAndAccess.dataAccessPlace, - originalArchive: payload.termsOfUseAndAccess.originalArchive, - availabilityStatus: payload.termsOfUseAndAccess.availabilityStatus, - contactForAccess: payload.termsOfUseAndAccess.contactForAccess, - sizeOfCollection: payload.termsOfUseAndAccess.sizeOfCollection, - studyCompletion: payload.termsOfUseAndAccess.studyCompletion - } - } - } - - if (payload.termsOfUseAndAccess.license) { - datasetTemplate.license = transformPayloadLicenseToLicense( - payload.termsOfUseAndAccess.license - ) - } else { - datasetTemplate.termsOfUse.customTerms = { - termsOfUse: payload.termsOfUseAndAccess.termsOfUse as string, - confidentialityDeclaration: payload.termsOfUseAndAccess - .confidentialityDeclaration as string, - specialPermissions: payload.termsOfUseAndAccess.specialPermissions as string, - restrictions: payload.termsOfUseAndAccess.restrictions as string, - citationRequirements: payload.termsOfUseAndAccess.citationRequirements as string, - depositorRequirements: payload.termsOfUseAndAccess.depositorRequirements as string, - conditions: payload.termsOfUseAndAccess.conditions as string, - disclaimer: payload.termsOfUseAndAccess.disclaimer as string - } - } - - return datasetTemplate - }) -} diff --git a/src/index.ts b/src/index.ts index 9e64baa6..578f1924 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,3 +12,4 @@ export * from './notifications' export * from './search' export * from './licenses' export * from './externalTools' +export * from './templates' diff --git a/src/notifications/domain/models/Notification.ts b/src/notifications/domain/models/Notification.ts index 001d0933..f60b0ced 100644 --- a/src/notifications/domain/models/Notification.ts +++ b/src/notifications/domain/models/Notification.ts @@ -67,6 +67,6 @@ export interface Notification { dataFileId?: number dataFileDisplayName?: string currentCurationStatus?: string - additionalInfo?: string + additionalInfo?: Record objectDeleted?: boolean } diff --git a/src/notifications/domain/models/NotificationSubset.ts b/src/notifications/domain/models/NotificationSubset.ts new file mode 100644 index 00000000..fe4644b6 --- /dev/null +++ b/src/notifications/domain/models/NotificationSubset.ts @@ -0,0 +1,6 @@ +import { Notification } from './Notification' + +export interface NotificationSubset { + notifications: Notification[] + totalNotificationCount: number +} diff --git a/src/notifications/domain/repositories/INotificationsRepository.ts b/src/notifications/domain/repositories/INotificationsRepository.ts index 9392c543..6835f119 100644 --- a/src/notifications/domain/repositories/INotificationsRepository.ts +++ b/src/notifications/domain/repositories/INotificationsRepository.ts @@ -1,7 +1,12 @@ -import { Notification } from '../models/Notification' +import { NotificationSubset } from '../models/NotificationSubset' export interface INotificationsRepository { - getAllNotificationsByUser(inAppNotificationFormat?: boolean): Promise + getAllNotificationsByUser( + inAppNotificationFormat?: boolean, + onlyUnread?: boolean, + limit?: number, + offset?: number + ): Promise deleteNotification(notificationId: number): Promise getUnreadNotificationsCount(): Promise markNotificationAsRead(notificationId: number): Promise diff --git a/src/notifications/domain/useCases/GetAllNotificationsByUser.ts b/src/notifications/domain/useCases/GetAllNotificationsByUser.ts index 43555ccc..b4b2e6f6 100644 --- a/src/notifications/domain/useCases/GetAllNotificationsByUser.ts +++ b/src/notifications/domain/useCases/GetAllNotificationsByUser.ts @@ -1,19 +1,30 @@ import { UseCase } from '../../../core/domain/useCases/UseCase' -import { Notification } from '../models/Notification' import { INotificationsRepository } from '../repositories/INotificationsRepository' +import { NotificationSubset } from '../models/NotificationSubset' -export class GetAllNotificationsByUser implements UseCase { +export class GetAllNotificationsByUser implements UseCase { constructor(private readonly notificationsRepository: INotificationsRepository) {} /** * Use case for retrieving all notifications for the current user. * * @param inAppNotificationFormat - Optional parameter to retrieve fields needed for in-app notifications - * @returns {Promise} - A promise that resolves to an array of Notification instances. + * @param onlyUnread - Optional parameter to filter only unread notifications + * @param limit - Optional parameter to limit the number of notifications returned + * @param offset - Optional parameter to skip a number of notifications (for pagination) + * @returns {Promise} - A promise that resolves to an array of Notification instances. */ - async execute(inAppNotificationFormat?: boolean): Promise { + async execute( + inAppNotificationFormat?: boolean, + onlyUnread?: boolean, + limit?: number, + offset?: number + ): Promise { return (await this.notificationsRepository.getAllNotificationsByUser( - inAppNotificationFormat - )) as Notification[] + inAppNotificationFormat, + onlyUnread, + limit, + offset + )) as NotificationSubset } } diff --git a/src/notifications/infra/repositories/NotificationsRepository.ts b/src/notifications/infra/repositories/NotificationsRepository.ts index f310c34a..99e37c82 100644 --- a/src/notifications/infra/repositories/NotificationsRepository.ts +++ b/src/notifications/infra/repositories/NotificationsRepository.ts @@ -2,22 +2,30 @@ import { ApiRepository } from '../../../core/infra/repositories/ApiRepository' import { INotificationsRepository } from '../../domain/repositories/INotificationsRepository' import { Notification } from '../../domain/models/Notification' import { NotificationPayload } from '../transformers/NotificationPayload' +import { NotificationSubset } from '../../domain/models/NotificationSubset' export class NotificationsRepository extends ApiRepository implements INotificationsRepository { private readonly notificationsResourceName: string = 'notifications' public async getAllNotificationsByUser( - inAppNotificationFormat?: boolean - ): Promise { - const queryParams = inAppNotificationFormat ? { inAppNotificationFormat: 'true' } : undefined + inAppNotificationFormat?: boolean, + onlyUnread?: boolean, + limit?: number, + offset?: number + ): Promise { + const queryParams = new URLSearchParams() + + if (inAppNotificationFormat) queryParams.set('inAppNotificationFormat', 'true') + if (onlyUnread) queryParams.set('onlyUnread', 'true') + if (limit !== undefined) queryParams.set('limit', limit.toString()) + if (offset !== undefined) queryParams.set('offset', offset.toString()) return this.doGet( this.buildApiEndpoint(this.notificationsResourceName, 'all'), true, queryParams ) .then((response) => { - const notifications = response.data.data.notifications - return notifications.map((notification: NotificationPayload) => { + const notifications = response.data.data.map((notification: NotificationPayload) => { const { dataverseDisplayName, dataverseAlias, ...restNotification } = notification return { ...restNotification, @@ -25,6 +33,8 @@ export class NotificationsRepository extends ApiRepository implements INotificat ...(dataverseAlias && { collectionAlias: dataverseAlias }) } }) as Notification[] + const totalNotificationCount = response.data.totalCount + return { notifications, totalNotificationCount } }) .catch((error) => { throw error diff --git a/src/notifications/infra/transformers/NotificationPayload.ts b/src/notifications/infra/transformers/NotificationPayload.ts index 96d381ac..d63bde79 100644 --- a/src/notifications/infra/transformers/NotificationPayload.ts +++ b/src/notifications/infra/transformers/NotificationPayload.ts @@ -25,6 +25,6 @@ export interface NotificationPayload { dataFileId?: number dataFileDisplayName?: string currentCurationStatus?: string - additionalInfo?: string + additionalInfo?: Record objectDeleted?: boolean } diff --git a/src/collections/domain/dtos/CreateDatasetTemplateDTO.ts b/src/templates/domain/dtos/CreateTemplateDTO.ts similarity index 96% rename from src/collections/domain/dtos/CreateDatasetTemplateDTO.ts rename to src/templates/domain/dtos/CreateTemplateDTO.ts index 52ba24cc..871fee8b 100644 --- a/src/collections/domain/dtos/CreateDatasetTemplateDTO.ts +++ b/src/templates/domain/dtos/CreateTemplateDTO.ts @@ -1,6 +1,6 @@ import { MetadataFieldTypeClass } from '../../../metadataBlocks/domain/models/MetadataBlock' -export interface CreateDatasetTemplateDTO { +export interface CreateTemplateDTO { name: string isDefault?: boolean fields?: TemplateFieldDTO[] diff --git a/src/datasets/domain/models/DatasetTemplate.ts b/src/templates/domain/models/Template.ts similarity index 72% rename from src/datasets/domain/models/DatasetTemplate.ts rename to src/templates/domain/models/Template.ts index 9be71f23..b5b93b62 100644 --- a/src/datasets/domain/models/DatasetTemplate.ts +++ b/src/templates/domain/models/Template.ts @@ -1,7 +1,7 @@ -import { DatasetMetadataBlock, TermsOfUse } from './Dataset' +import { DatasetMetadataBlock, TermsOfUse } from '../../../datasets/domain/models/Dataset' import { License } from '../../../licenses/domain/models/License' -export interface DatasetTemplate { +export interface Template { id: number name: string collectionAlias: string @@ -11,13 +11,13 @@ export interface DatasetTemplate { createDate: string // 👇 From Edit Template Metadata datasetMetadataBlocks: DatasetMetadataBlock[] - instructions: DatasetTemplateInstruction[] + instructions: TemplateInstruction[] // 👇 From Edit Template Terms termsOfUse: TermsOfUse license?: License // This license property is going to be present if not custom terms are added in the UI } -export interface DatasetTemplateInstruction { +export interface TemplateInstruction { instructionField: string instructionText: string } diff --git a/src/templates/domain/repositories/ITemplatesRepository.ts b/src/templates/domain/repositories/ITemplatesRepository.ts new file mode 100644 index 00000000..3482d340 --- /dev/null +++ b/src/templates/domain/repositories/ITemplatesRepository.ts @@ -0,0 +1,9 @@ +import { CreateTemplateDTO } from '../dtos/CreateTemplateDTO' +import { Template } from '../models/Template' + +export interface ITemplatesRepository { + createTemplate(collectionIdOrAlias: number | string, template: CreateTemplateDTO): Promise + getTemplate(templateId: number): Promise