Add typescript paths to top level folders
[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 { ListResults } from "~/common/api/common-resource-service";
10 import { FavoriteOrderBuilder } from "./favorite-order-builder";
11 import { OrderBuilder } from "~/common/api/order-builder";
12
13 export interface FavoriteListArguments {
14     limit?: number;
15     offset?: number;
16     filters?: FilterBuilder;
17     order?: FavoriteOrderBuilder;
18 }
19
20 export class FavoriteService {
21     constructor(
22         private linkService: LinkService,
23         private groupsService: GroupsService
24     ) { }
25
26     create(data: { userUuid: string; resource: { uuid: string; name: string } }) {
27         return this.linkService.create({
28             ownerUuid: data.userUuid,
29             tailUuid: data.userUuid,
30             headUuid: data.resource.uuid,
31             linkClass: LinkClass.STAR,
32             name: data.resource.name
33         });
34     }
35
36     delete(data: { userUuid: string; resourceUuid: string; }) {
37         return this.linkService
38             .list({
39                 filters: FilterBuilder
40                     .create()
41                     .addEqual('tailUuid', data.userUuid)
42                     .addEqual('headUuid', data.resourceUuid)
43                     .addEqual('linkClass', LinkClass.STAR)
44             })
45             .then(results => Promise.all(
46                 results.items.map(item => this.linkService.delete(item.uuid))));
47     }
48
49     list(userUuid: string, { filters, limit, offset, order }: FavoriteListArguments = {}): Promise<ListResults<GroupContentsResource>> {
50         const listFilter = FilterBuilder
51             .create()
52             .addEqual('tailUuid', userUuid)
53             .addEqual('linkClass', LinkClass.STAR);
54
55         return this.linkService
56             .list({
57                 filters: filters ? filters.concat(listFilter) : listFilter,
58                 limit,
59                 offset,
60                 order: order ? order.getLinkOrder() : OrderBuilder.create<LinkResource>()
61             })
62             .then(results => {
63                 const uuids = results.items.map(item => item.headUuid);
64                 return this.groupsService.contents(userUuid, {
65                     limit,
66                     offset,
67                     order: order ? order.getContentOrder() : OrderBuilder.create<GroupContentsResource>(),
68                     filters: FilterBuilder.create().addIn('uuid', uuids),
69                     recursive: true
70                 });
71             });
72     }
73
74     checkPresenceInFavorites(userUuid: string, resourceUuids: string[]): Promise<Record<string, boolean>> {
75         return this.linkService
76             .list({
77                 filters: FilterBuilder
78                     .create()
79                     .addIn("headUuid", resourceUuids)
80                     .addEqual("tailUuid", userUuid)
81                     .addEqual("linkClass", LinkClass.STAR)
82             })
83             .then(({ items }) => resourceUuids.reduce((results, uuid) => {
84                 const isFavorite = items.some(item => item.headUuid === uuid);
85                 return { ...results, [uuid]: isFavorite };
86             }, {}));
87     }
88
89 }