Merge branch 'master' into 13786-current-token
[arvados-workbench2.git] / src / services / favorite-service / favorite-service.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { LinkService } from "../link-service/link-service";
6 import { GroupsService, GroupContentsResource } from "../groups-service/groups-service";
7 import { LinkResource, LinkClass } from "../../models/link";
8 import { FilterBuilder } from "../../common/api/filter-builder";
9 import { ListArguments, ListResults } from "../../common/api/common-resource-service";
10 import { OrderBuilder } from "../../common/api/order-builder";
11
12 export interface FavoriteListArguments extends ListArguments {
13     filters?: FilterBuilder<LinkResource>;
14     order?: OrderBuilder<LinkResource>;
15 }
16 export class FavoriteService {
17     constructor(
18         private linkService: LinkService,
19         private groupsService: GroupsService
20     ) { }
21
22     create(data: { userUuid: string; resource: { uuid: string; name: string } }) {
23         return this.linkService.create({
24             ownerUuid: data.userUuid,
25             tailUuid: data.userUuid,
26             headUuid: data.resource.uuid,
27             linkClass: LinkClass.STAR,
28             name: data.resource.name
29         });
30     }
31
32     delete(data: { userUuid: string; resourceUuid: string; }) {
33         return this.linkService
34             .list({
35                 filters: FilterBuilder
36                     .create<LinkResource>()
37                     .addEqual('tailUuid', data.userUuid)
38                     .addEqual('headUuid', data.resourceUuid)
39                     .addEqual('linkClass', LinkClass.STAR)
40             })
41             .then(results => Promise.all(
42                 results.items.map(item => this.linkService.delete(item.uuid))));
43     }
44
45     list(userUuid: string, args: FavoriteListArguments = {}): Promise<ListResults<GroupContentsResource>> {
46         const listFilter = FilterBuilder
47             .create<LinkResource>()
48             .addEqual('tailUuid', userUuid)
49             .addEqual('linkClass', LinkClass.STAR);
50
51         return this.linkService
52             .list({
53                 ...args,
54                 filters: args.filters ? args.filters.concat(listFilter) : listFilter
55             })
56             .then(results => {
57                 const uuids = results.items.map(item => item.headUuid);
58                 return this.groupsService.contents(userUuid, {
59                     limit: args.limit,
60                     offset: args.offset,
61                     filters: FilterBuilder.create<GroupContentsResource>().addIn('uuid', uuids),
62                     recursive: true
63                 });
64             });
65     }
66
67     checkPresenceInFavorites(userUuid: string, resourceUuids: string[]): Promise<Record<string, boolean>> {
68         return this.linkService
69             .list({
70                 filters: FilterBuilder
71                     .create<LinkResource>()
72                     .addIn("headUuid", resourceUuids)
73                     .addEqual("tailUuid", userUuid)
74                     .addEqual("linkClass", LinkClass.STAR)
75             })
76             .then(({ items }) => resourceUuids.reduce((results, uuid) => {
77                 const isFavorite = items.some(item => item.headUuid === uuid);
78                 return { ...results, [uuid]: isFavorite };
79             }, {}));
80     }
81
82
83 }