Skip to content

Commit 40db91c

Browse files
authored
Merge pull request #294 from IQSS/283-implement-my-data-use-case
Implement GetMyDataCollectionItems use case
2 parents 8bf07fe + 51208b7 commit 40db91c

28 files changed

+1237
-31
lines changed

docs/useCases.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The different use cases currently available in the package are classified below,
1414
- [Get Collection Facets](#get-collection-facets)
1515
- [Get User Permissions on a Collection](#get-user-permissions-on-a-collection)
1616
- [List All Collection Items](#list-all-collection-items)
17+
- [List My Data Collection Items](#list-my-data-collection-items)
1718
- [Get Collection Featured Items](#get-collection-featured-items)
1819
- [Collections write use cases](#collections-write-use-cases)
1920
- [Create a Collection](#create-a-collection)
@@ -215,6 +216,62 @@ This use case supports the following optional parameters depending on the search
215216
- **offset**: (number) Offset for pagination.
216217
- **collectionSearchCriteria**: ([CollectionSearchCriteria](../src/collections/domain/models/CollectionSearchCriteria.ts)) Supports filtering the collection items by different properties.
217218

219+
#### List My Data Collection Items
220+
221+
Returns an instance of [CollectionItemSubset](../src/collections/domain/models/CollectionItemSubset.ts) that contains reduced information for each collection item for which the calling user has a role.
222+
223+
##### Example call:
224+
225+
```typescript
226+
import { getMyDataCollectionItems } from '@iqss/dataverse-client-javascript'
227+
228+
/* ... */
229+
230+
const roleIds = [1, 2]
231+
const collectionItemTypes = [CollectionItemType.DATASET, CollectionItemType.FILE]
232+
const publishingStatuses = [
233+
PublicationStatus.Published,
234+
PublicationStatus.Draft,
235+
PublicationStatus.Unpublished
236+
]
237+
const limit = 10
238+
const selectedPage = 1
239+
const searchText = 'search text'
240+
const otherUserName = 'otherUserName'
241+
242+
getMyDataCollectionItems
243+
.execute(
244+
roleIds,
245+
collectionItemTypes,
246+
publishingStatuses,
247+
limit,
248+
selectedPage,
249+
searchText,
250+
otherUserName
251+
)
252+
.then((subset: CollectionItemSubset) => {
253+
/* ... */
254+
})
255+
256+
/* ... */
257+
```
258+
259+
_See [use case](../src/collections/domain/useCases/GetMyDataCollectionItems.ts) implementation_.
260+
This use case requires the following parameters:
261+
262+
- **roleIds** is an array of user role identifiers to filter the results. At least one roleId must be specified.
263+
- **collectionItemTypes** is an array of collection item types to filter the results. At least one collectionItemType must be specified.
264+
- **publishingStatuses** is an array of publishing statuses to filter the results. At least one publishingStatus must be specified.
265+
266+
This use case supports the following optional parameters depending on the search goals:
267+
268+
- **limit**: (number) Limit of items per page for pagination. (default is 10)
269+
- **selectedPage**: (number) the page of results to be returned. (default is 1)
270+
- **searchText** is an optional string to filter the results by.
271+
- **otherUserName** is an optional string to return the collection items of another user. If not set, the calling user will be used. _Only superusers can use this parameter_.
272+
273+
The `CollectionItemSubset`returned instance contains a property called `totalItemCount` which is necessary for pagination.
274+
218275
#### Get Collection Featured Items
219276

220277
Returns a [CollectionFeaturedItem](../src/collections/domain/models/CollectionFeaturedItem.ts) array containing the featured items of the requested collection, given the collection identifier or alias.

src/collections/domain/models/CollectionItemSubset.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ export interface CollectionItemsFacet {
1515
labels: CollectionItemsFacetLabel[]
1616
}
1717

18-
interface CollectionItemsFacetLabel {
18+
export interface CollectionItemsFacetLabel {
1919
name: string
2020
count: number
2121
}
2222

2323
interface CountPerObjectType {
24-
dataverses: number
24+
collections: number
2525
datasets: number
2626
files: number
2727
}

src/collections/domain/models/CollectionPreview.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ export interface CollectionPreview {
1212
publicationStatuses: PublicationStatus[]
1313
releaseOrCreateDate: Date
1414
imageUrl?: string
15+
userRoles?: string[]
1516
}

src/collections/domain/repositories/ICollectionsRepository.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { CollectionFeaturedItem } from '../models/CollectionFeaturedItem'
66
import { CollectionItemSubset } from '../models/CollectionItemSubset'
77
import { CollectionSearchCriteria } from '../models/CollectionSearchCriteria'
88
import { CollectionUserPermissions } from '../models/CollectionUserPermissions'
9+
import { PublicationStatus } from '../../../../src/core/domain/models/PublicationStatus'
10+
import { CollectionItemType } from '../../../../src/collections/domain/models/CollectionItemType'
911

1012
export interface ICollectionsRepository {
1113
getCollection(collectionIdOrAlias: number | string): Promise<Collection>
@@ -25,6 +27,15 @@ export interface ICollectionsRepository {
2527
offset?: number,
2628
collectionSearchCriteria?: CollectionSearchCriteria
2729
): Promise<CollectionItemSubset>
30+
getMyDataCollectionItems(
31+
roleIds: number[],
32+
collectionItemTypes: CollectionItemType[],
33+
publicationStatuses: PublicationStatus[],
34+
limit?: number,
35+
selectedPage?: number,
36+
searchText?: string,
37+
otherUserName?: string
38+
): Promise<CollectionItemSubset>
2839
updateCollection(
2940
collectionIdOrAlias: number | string,
3041
updatedCollection: CollectionDTO
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { CollectionItemSubset } from '../models/CollectionItemSubset'
3+
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
4+
import { CollectionItemType } from '../../../../src/collections/domain/models/CollectionItemType'
5+
import { PublicationStatus } from '../../../../src/core/domain/models/PublicationStatus'
6+
7+
export class GetMyDataCollectionItems implements UseCase<CollectionItemSubset> {
8+
private collectionsRepository: ICollectionsRepository
9+
10+
constructor(collectionsRepository: ICollectionsRepository) {
11+
this.collectionsRepository = collectionsRepository
12+
}
13+
14+
/**
15+
* Returns an instance of MyDataCollectionItemSubset that contains the items for which the user has the specified role or roles
16+
*
17+
* @param {number[]} [roleIds] - the ids of the roles to filter the items by.
18+
* @param {CollectionItemType[]} [collectionItemTypes] - the types of items to filter by.
19+
* @param {PublicationStatus[]} [publicationStatuses] - the publication statuses to filter by.
20+
* @param {number} [limit] - Limit number of items to return for pagination (optional).
21+
* @param {number} [selectedPage] - Offset (starting point) for pagination (optional).
22+
* @param {string} [searchText] - filter by searching for this text in the results (optional).
23+
* @param {string} [otherUserName] - filter by searching for this text in the results (optional).
24+
* * @returns {Promise<CollectionItemSubset>}
25+
*/
26+
async execute(
27+
roleIds: number[],
28+
collectionItemTypes: CollectionItemType[],
29+
publicationStatuses: PublicationStatus[],
30+
limit?: number,
31+
selectedPage?: number,
32+
searchText?: string,
33+
otherUserName?: string
34+
): Promise<CollectionItemSubset> {
35+
return this.collectionsRepository.getMyDataCollectionItems(
36+
roleIds,
37+
collectionItemTypes,
38+
publicationStatuses,
39+
limit,
40+
selectedPage,
41+
searchText,
42+
otherUserName
43+
)
44+
}
45+
}

src/collections/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { CollectionsRepository } from './infra/repositories/CollectionsRepositor
1010
import { UpdateCollectionFeaturedItems } from './domain/useCases/UpdateCollectionFeaturedItems'
1111
import { DeleteCollectionFeaturedItems } from './domain/useCases/DeleteCollectionFeaturedItems'
1212
import { DeleteCollection } from './domain/useCases/DeleteCollection'
13+
import { GetMyDataCollectionItems } from './domain/useCases/GetMyDataCollectionItems'
1314

1415
const collectionsRepository = new CollectionsRepository()
1516

@@ -18,6 +19,7 @@ const createCollection = new CreateCollection(collectionsRepository)
1819
const getCollectionFacets = new GetCollectionFacets(collectionsRepository)
1920
const getCollectionUserPermissions = new GetCollectionUserPermissions(collectionsRepository)
2021
const getCollectionItems = new GetCollectionItems(collectionsRepository)
22+
const getMyDataCollectionItems = new GetMyDataCollectionItems(collectionsRepository)
2123
const publishCollection = new PublishCollection(collectionsRepository)
2224
const updateCollection = new UpdateCollection(collectionsRepository)
2325
const getCollectionFeaturedItems = new GetCollectionFeaturedItems(collectionsRepository)
@@ -31,6 +33,7 @@ export {
3133
getCollectionFacets,
3234
getCollectionUserPermissions,
3335
getCollectionItems,
36+
getMyDataCollectionItems,
3437
publishCollection,
3538
updateCollection,
3639
getCollectionFeaturedItems,

src/collections/infra/repositories/CollectionsRepository.ts

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { ICollectionsRepository } from '../../domain/repositories/ICollectionsRe
33
import {
44
transformCollectionFacetsResponseToCollectionFacets,
55
transformCollectionItemsResponseToCollectionItemSubset,
6-
transformCollectionResponseToCollection
6+
transformCollectionResponseToCollection,
7+
transformMyDataResponseToCollectionItemSubset
78
} from './transformers/collectionTransformers'
89
import { Collection, ROOT_COLLECTION_ID } from '../../domain/models/Collection'
910
import { CollectionDTO } from '../../domain/dtos/CollectionDTO'
@@ -21,6 +22,8 @@ import { CollectionFeaturedItem } from '../../domain/models/CollectionFeaturedIt
2122
import { transformCollectionFeaturedItemsPayloadToCollectionFeaturedItems } from './transformers/collectionFeaturedItemsTransformer'
2223
import { CollectionFeaturedItemsDTO } from '../../domain/dtos/CollectionFeaturedItemsDTO'
2324
import { ApiConstants } from '../../../core/infra/repositories/ApiConstants'
25+
import { PublicationStatus } from '../../../../src/core/domain/models/PublicationStatus'
26+
import { ReadError } from '../../../core/domain/repositories/ReadError'
2427

2528
export interface NewCollectionRequestPayload {
2629
alias: string
@@ -63,6 +66,16 @@ export enum GetCollectionItemsQueryParams {
6366
SHOW_TYPE_COUNTS = 'show_type_counts'
6467
}
6568

69+
export enum GetMyDataCollectionItemsQueryParams {
70+
SEARCH_TEXT = 'mydata_search_term',
71+
PER_PAGE = 'per_page',
72+
SELECTED_PAGE = 'selected_page',
73+
ROLE_ID = 'role_ids',
74+
TYPE = 'dvobject_types',
75+
PUBLISHED_STATES = 'published_states',
76+
USER_IDENTIFIER = 'userIdentifier'
77+
}
78+
6679
export class CollectionsRepository extends ApiRepository implements ICollectionsRepository {
6780
private readonly collectionsResourceName: string = 'dataverses'
6881

@@ -188,6 +201,76 @@ export class CollectionsRepository extends ApiRepository implements ICollections
188201
})
189202
}
190203

204+
public async getMyDataCollectionItems(
205+
roleIds: number[],
206+
collectionItemTypes: CollectionItemType[],
207+
publicationStatuses: PublicationStatus[],
208+
limit?: number,
209+
selectedPage?: number,
210+
searchText?: string,
211+
userIdentifier?: string
212+
): Promise<CollectionItemSubset> {
213+
const queryParams = new URLSearchParams()
214+
215+
if (limit) {
216+
queryParams.set(GetMyDataCollectionItemsQueryParams.PER_PAGE, limit.toString())
217+
}
218+
219+
if (selectedPage) {
220+
queryParams.set(GetMyDataCollectionItemsQueryParams.SELECTED_PAGE, selectedPage.toString())
221+
}
222+
223+
if (searchText) {
224+
queryParams.set(
225+
GetMyDataCollectionItemsQueryParams.SEARCH_TEXT,
226+
encodeURIComponent(searchText)
227+
)
228+
}
229+
230+
roleIds.forEach((roleId) => {
231+
queryParams.append(GetMyDataCollectionItemsQueryParams.ROLE_ID, roleId.toString())
232+
})
233+
if (userIdentifier) {
234+
queryParams.set(GetMyDataCollectionItemsQueryParams.USER_IDENTIFIER, userIdentifier)
235+
}
236+
237+
collectionItemTypes.forEach((itemType) => {
238+
let mappedItemType: string
239+
240+
switch (itemType) {
241+
case CollectionItemType.COLLECTION:
242+
mappedItemType = 'Dataverse'
243+
break
244+
case CollectionItemType.DATASET:
245+
mappedItemType = 'Dataset'
246+
break
247+
case CollectionItemType.FILE:
248+
mappedItemType = 'DataFile'
249+
break
250+
}
251+
queryParams.append(GetMyDataCollectionItemsQueryParams.TYPE, mappedItemType)
252+
})
253+
254+
publicationStatuses.forEach((publicationStatus) => {
255+
queryParams.append(
256+
GetMyDataCollectionItemsQueryParams.PUBLISHED_STATES,
257+
publicationStatus.toString()
258+
)
259+
})
260+
const result = await this.doGet('/mydata/retrieve', true, queryParams)
261+
.then((response) => {
262+
if (response.data.success !== true) {
263+
throw new ReadError(response.data.error_message)
264+
}
265+
return transformMyDataResponseToCollectionItemSubset(response)
266+
})
267+
.catch((error) => {
268+
throw error
269+
})
270+
271+
return result
272+
}
273+
191274
private createCreateOrUpdateRequestBody(
192275
collectionDTO: CollectionDTO
193276
): NewCollectionRequestPayload {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export interface MyDataCollectionPreviewPayload {
2+
name: string
3+
parentDataverseName: string
4+
identifier: string
5+
parentDataverseIdentifier: string
6+
url: string
7+
image_url: string
8+
description: string
9+
type?: string
10+
publicationStatuses: string[]
11+
affiliation: string
12+
published_at: string
13+
user_roles: string[]
14+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface MyDataCountPerObjectTypePayload {
2+
dataverses_count: number
3+
datasets_count: number
4+
files_count: number
5+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface MyDataPublicationStatusCountsPayload {
2+
deaccessioned_count: number
3+
draft_count: number
4+
in_review_count: number
5+
published_count: number
6+
unpublished_count: number
7+
}

0 commit comments

Comments
 (0)