Skip to content

Commit 204796f

Browse files
authored
Merge pull request #346 from IQSS/325-link-unlink-collection
Add linkCollection, unlinkCollection and getCollectionLinks use cases
2 parents 3219a71 + 396c348 commit 204796f

File tree

16 files changed

+493
-3
lines changed

16 files changed

+493
-3
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ node_modules
1010
# unit tests
1111
coverage
1212

13+
# macOS
14+
.DS_Store
15+
1316
# ignore npm lock
1417
package-json.lock
1518
.npmrc
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { CollectionSummary } from './CollectionSummary'
2+
import { DatasetSummary } from '../../../datasets/domain/models/DatasetSummary'
3+
4+
export interface CollectionLinks {
5+
linkedCollections: CollectionSummary[]
6+
collectionsLinkingToThis: CollectionSummary[]
7+
linkedDatasets: DatasetSummary[]
8+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface CollectionSummary {
2+
id: number
3+
alias: string
4+
displayName: string
5+
}

src/collections/domain/repositories/ICollectionsRepository.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { CollectionSearchCriteria } from '../models/CollectionSearchCriteria'
99
import { CollectionUserPermissions } from '../models/CollectionUserPermissions'
1010
import { PublicationStatus } from '../../../core/domain/models/PublicationStatus'
1111
import { CollectionItemType } from '../../../collections/domain/models/CollectionItemType'
12+
import { CollectionLinks } from '../models/CollectionLinks'
1213

1314
export interface ICollectionsRepository {
1415
getCollection(collectionIdOrAlias: number | string): Promise<Collection>
@@ -50,4 +51,13 @@ export interface ICollectionsRepository {
5051
): Promise<FeaturedItem[]>
5152
deleteCollectionFeaturedItems(collectionIdOrAlias: number | string): Promise<void>
5253
deleteCollectionFeaturedItem(featuredItemId: number): Promise<void>
54+
linkCollection(
55+
linkedCollectionIdOrAlias: number | string,
56+
linkingCollectionIdOrAlias: number | string
57+
): Promise<void>
58+
unlinkCollection(
59+
linkedCollectionIdOrAlias: number | string,
60+
linkingCollectionIdOrAlias: number | string
61+
): Promise<void>
62+
getCollectionLinks(collectionIdOrAlias: number | string): Promise<CollectionLinks>
5363
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
3+
import { CollectionLinks } from '../models/CollectionLinks'
4+
5+
export class GetCollectionLinks implements UseCase<CollectionLinks> {
6+
private collectionsRepository: ICollectionsRepository
7+
8+
constructor(collectionsRepository: ICollectionsRepository) {
9+
this.collectionsRepository = collectionsRepository
10+
}
11+
12+
/**
13+
* Returns a CollectionLinks object containing other collections this collection is linked to, the other collections linking to this collection, and datasets linked to this collection, given the collection identifier or alias.
14+
*
15+
* @param {number | string} [collectionIdOrAlias] - A generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId)
16+
* If this parameter is not set, the default value is: ':root'
17+
* @returns {Promise<CollectionLinks>}
18+
*/
19+
async execute(collectionId: number | string): Promise<CollectionLinks> {
20+
return await this.collectionsRepository.getCollectionLinks(collectionId)
21+
}
22+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
3+
4+
export class LinkCollection implements UseCase<void> {
5+
private collectionsRepository: ICollectionsRepository
6+
7+
constructor(collectionsRepository: ICollectionsRepository) {
8+
this.collectionsRepository = collectionsRepository
9+
}
10+
11+
/**
12+
* Creates a link between two collections. The linked collection will be linked to the linking collection.:
13+
*
14+
* @param {number| string} [linkedCollectionIdOrAlias] - The collection to be linked. Can be either a string (collection alias), or a number (collection id)
15+
* @param { number | string} [linkingCollectionIdOrAlias] - The collection that will be linking to the linked collection. Can be either a string (collection alias), or a number (collection id)
16+
* @returns {Promise<void>} -This method does not return anything upon successful completion.
17+
*/
18+
async execute(
19+
linkedCollectionIdOrAlias: number | string,
20+
linkingCollectionIdOrAlias: number | string
21+
): Promise<void> {
22+
return await this.collectionsRepository.linkCollection(
23+
linkedCollectionIdOrAlias,
24+
linkingCollectionIdOrAlias
25+
)
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
3+
4+
export class UnlinkCollection implements UseCase<void> {
5+
private collectionsRepository: ICollectionsRepository
6+
7+
constructor(collectionsRepository: ICollectionsRepository) {
8+
this.collectionsRepository = collectionsRepository
9+
}
10+
11+
/**
12+
* Unlinks a collection from the collection that links to it
13+
*
14+
* @param {number| string} [linkedCollectionIdOrAlias] - The collection that is linked. Can be either a string (collection alias), or a number (collection id)
15+
* @param { number | string} [linkingCollectionIdOrAlias] - The collection that links to the linked collection. Can be either a string (collection alias), or a number (collection id)
16+
* @returns {Promise<void>} -This method does not return anything upon successful completion.
17+
*/
18+
async execute(
19+
linkedCollectionIdOrAlias: number | string,
20+
linkingCollectionIdOrAlias: number | string
21+
): Promise<void> {
22+
return await this.collectionsRepository.unlinkCollection(
23+
linkedCollectionIdOrAlias,
24+
linkingCollectionIdOrAlias
25+
)
26+
}
27+
}

src/collections/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import { DeleteCollectionFeaturedItems } from './domain/useCases/DeleteCollectio
1212
import { DeleteCollection } from './domain/useCases/DeleteCollection'
1313
import { GetMyDataCollectionItems } from './domain/useCases/GetMyDataCollectionItems'
1414
import { DeleteCollectionFeaturedItem } from './domain/useCases/DeleteCollectionFeaturedItem'
15+
import { LinkCollection } from './domain/useCases/LinkCollection'
16+
import { UnlinkCollection } from './domain/useCases/UnlinkCollection'
17+
import { GetCollectionLinks } from './domain/useCases/GetCollectionLinks'
1518

1619
const collectionsRepository = new CollectionsRepository()
1720

@@ -28,6 +31,9 @@ const updateCollectionFeaturedItems = new UpdateCollectionFeaturedItems(collecti
2831
const deleteCollectionFeaturedItems = new DeleteCollectionFeaturedItems(collectionsRepository)
2932
const deleteCollection = new DeleteCollection(collectionsRepository)
3033
const deleteCollectionFeaturedItem = new DeleteCollectionFeaturedItem(collectionsRepository)
34+
const linkCollection = new LinkCollection(collectionsRepository)
35+
const unlinkCollection = new UnlinkCollection(collectionsRepository)
36+
const getCollectionLinks = new GetCollectionLinks(collectionsRepository)
3137

3238
export {
3339
getCollection,
@@ -42,7 +48,10 @@ export {
4248
updateCollectionFeaturedItems,
4349
deleteCollectionFeaturedItems,
4450
deleteCollection,
45-
deleteCollectionFeaturedItem
51+
deleteCollectionFeaturedItem,
52+
linkCollection,
53+
unlinkCollection,
54+
getCollectionLinks
4655
}
4756
export { Collection, CollectionInputLevel } from './domain/models/Collection'
4857
export { CollectionFacet } from './domain/models/CollectionFacet'

src/collections/infra/repositories/CollectionsRepository.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ICollectionsRepository } from '../../domain/repositories/ICollectionsRe
33
import {
44
transformCollectionFacetsResponseToCollectionFacets,
55
transformCollectionItemsResponseToCollectionItemSubset,
6+
transformCollectionLinksResponseToCollectionLinks,
67
transformCollectionResponseToCollection,
78
transformMyDataResponseToCollectionItemSubset
89
} from './transformers/collectionTransformers'
@@ -36,6 +37,7 @@ import {
3637
import { ApiConstants } from '../../../core/infra/repositories/ApiConstants'
3738
import { PublicationStatus } from '../../../core/domain/models/PublicationStatus'
3839
import { ReadError } from '../../../core/domain/repositories/ReadError'
40+
import { CollectionLinks } from '../../domain/models/CollectionLinks'
3941

4042
export interface NewCollectionRequestPayload {
4143
alias: string
@@ -446,4 +448,38 @@ export class CollectionsRepository extends ApiRepository implements ICollections
446448
throw error
447449
})
448450
}
451+
public async linkCollection(
452+
linkedCollectionIdOrAlias: number | string,
453+
linkingCollectionIdOrAlias: number | string
454+
): Promise<void> {
455+
return this.doPut(
456+
`/dataverses/${linkedCollectionIdOrAlias}/link/${linkingCollectionIdOrAlias}`,
457+
{} // No data is needed for this operation
458+
)
459+
.then(() => undefined)
460+
.catch((error) => {
461+
throw error
462+
})
463+
}
464+
public async unlinkCollection(
465+
linkedCollectionIdOrAlias: number | string,
466+
linkingCollectionIdOrAlias: number | string
467+
): Promise<void> {
468+
return this.doDelete(
469+
`/dataverses/${linkedCollectionIdOrAlias}/deleteLink/${linkingCollectionIdOrAlias}`
470+
)
471+
.then(() => undefined)
472+
.catch((error) => {
473+
throw error
474+
})
475+
}
476+
public async getCollectionLinks(collectionIdOrAlias: number | string): Promise<CollectionLinks> {
477+
return this.doGet(`/${this.collectionsResourceName}/${collectionIdOrAlias}/links`, true)
478+
.then((response) => {
479+
return transformCollectionLinksResponseToCollectionLinks(response)
480+
})
481+
.catch((error) => {
482+
throw error
483+
})
484+
}
449485
}

src/collections/infra/repositories/transformers/collectionTransformers.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
PublicationStatusCount
4545
} from '../../../domain/models/MyDataCollectionItemSubset'
4646
import { PublicationStatus } from '../../../../core/domain/models/PublicationStatus'
47+
import { CollectionLinks } from '../../../domain/models/CollectionLinks'
4748

4849
export const transformCollectionResponseToCollection = (response: AxiosResponse): Collection => {
4950
const collectionPayload = response.data.data
@@ -152,7 +153,19 @@ export const transformCollectionItemsResponseToCollectionItemSubset = (
152153
...(countPerObjectType && { countPerObjectType })
153154
}
154155
}
155-
156+
export const transformCollectionLinksResponseToCollectionLinks = (
157+
response: AxiosResponse
158+
): CollectionLinks => {
159+
const responseDataPayload = response.data.data
160+
const linkedCollections = responseDataPayload.linkedDataverses
161+
const collectionsLinkingToThis = responseDataPayload.dataversesLinkingToThis
162+
const linkedDatasets = responseDataPayload.linkedDatasets
163+
return {
164+
linkedCollections,
165+
collectionsLinkingToThis,
166+
linkedDatasets
167+
}
168+
}
156169
export const transformMyDataResponseToCollectionItemSubset = (
157170
response: AxiosResponse
158171
): MyDataCollectionItemSubset => {

0 commit comments

Comments
 (0)