915235d1ec14ef14ec4c97801513e378033f3397
[arvados-workbench2.git] / src / store / resources / resources.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { Resource, EditableResource } from "~/models/resource";
6 import { ResourceKind } from '~/models/resource';
7 import { ProjectResource } from "~/models/project";
8 import { GroupResource } from "~/models/group";
9 import { extractUuidObjectType, ResourceObjectType } from "~/models/resource";
10 import { GroupClass } from '~/models/group';
11
12 export type ResourcesState = { [key: string]: Resource };
13
14 const getResourceWritableBy = (state: ResourcesState, id: string, userUuid: string): string[] => {
15     if (!id) {
16         return [];
17     }
18
19     if (id === userUuid) {
20         return [userUuid];
21     }
22
23     const resource = (state[id] as ProjectResource);
24
25     if (!resource) {
26         return [];
27     }
28
29     const { writableBy } = resource;
30
31     return writableBy || getResourceWritableBy(state, resource.ownerUuid, userUuid);
32 };
33
34 export const getResourceWithEditableStatus = <T extends EditableResource & GroupResource>(id: string, userUuid?: string) =>
35     (state: ResourcesState): T | undefined => {
36         if (state[id] === undefined) { return; }
37
38         const resource = JSON.parse(JSON.stringify(state[id] as T));
39
40         if (resource) {
41             const objectType = extractUuidObjectType(resource.uuid);
42             switch (objectType) {
43               case ResourceObjectType.GROUP:
44                 // filter groups are read-only for now
45                 if (resource.groupClass === GroupClass.FILTER) {
46                   resource.isEditable = false;
47                   return resource;
48                 }
49             }
50             resource.isEditable = userUuid ? getResourceWritableBy(state, id, userUuid).indexOf(userUuid) > -1 : false;
51         }
52
53         return resource;
54     };
55
56 export const getResource = <T extends Resource = Resource>(id: string) =>
57     (state: ResourcesState): T | undefined =>
58         state[id] as T;
59
60 export const setResource = <T extends Resource>(id: string, data: T) =>
61     (state: ResourcesState) => ({
62         ...state,
63         [id]: data
64     });
65
66 export const deleteResource = (id: string) =>
67     (state: ResourcesState) => {
68         const newState = { ...state };
69         delete newState[id];
70         return newState;
71     };
72
73 export const filterResources = (filter: (resource: Resource) => boolean) =>
74     (state: ResourcesState) =>
75         Object
76             .keys(state)
77             .reduce((resources, id) => {
78                 const resource = getResource(id)(state);
79                 return resource
80                     ? [...resources, resource]
81                     : resources;
82             }, [])
83             .filter(filter);
84
85 export const filterResourcesByKind = (kind: ResourceKind) =>
86     (state: ResourcesState) =>
87         filterResources(resource => resource.kind === kind)(state);