17119: add basic filter group support.
[arvados-workbench2.git] / src / store / resources / resources.ts
index add4efef54b4cd4d63178e0239927f4619587160..915235d1ec14ef14ec4c97801513e378033f3397 100644 (file)
@@ -2,11 +2,57 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import { Resource } from "~/models/resource";
-import { ResourceKind } from '../../models/resource';
+import { Resource, EditableResource } from "~/models/resource";
+import { ResourceKind } from '~/models/resource';
+import { ProjectResource } from "~/models/project";
+import { GroupResource } from "~/models/group";
+import { extractUuidObjectType, ResourceObjectType } from "~/models/resource";
+import { GroupClass } from '~/models/group';
 
 export type ResourcesState = { [key: string]: Resource };
 
+const getResourceWritableBy = (state: ResourcesState, id: string, userUuid: string): string[] => {
+    if (!id) {
+        return [];
+    }
+
+    if (id === userUuid) {
+        return [userUuid];
+    }
+
+    const resource = (state[id] as ProjectResource);
+
+    if (!resource) {
+        return [];
+    }
+
+    const { writableBy } = resource;
+
+    return writableBy || getResourceWritableBy(state, resource.ownerUuid, userUuid);
+};
+
+export const getResourceWithEditableStatus = <T extends EditableResource & GroupResource>(id: string, userUuid?: string) =>
+    (state: ResourcesState): T | undefined => {
+        if (state[id] === undefined) { return; }
+
+        const resource = JSON.parse(JSON.stringify(state[id] as T));
+
+        if (resource) {
+            const objectType = extractUuidObjectType(resource.uuid);
+            switch (objectType) {
+              case ResourceObjectType.GROUP:
+                // filter groups are read-only for now
+                if (resource.groupClass === GroupClass.FILTER) {
+                  resource.isEditable = false;
+                  return resource;
+                }
+            }
+            resource.isEditable = userUuid ? getResourceWritableBy(state, id, userUuid).indexOf(userUuid) > -1 : false;
+        }
+
+        return resource;
+    };
+
 export const getResource = <T extends Resource = Resource>(id: string) =>
     (state: ResourcesState): T | undefined =>
         state[id] as T;
@@ -19,7 +65,7 @@ export const setResource = <T extends Resource>(id: string, data: T) =>
 
 export const deleteResource = (id: string) =>
     (state: ResourcesState) => {
-        const newState = {...state};
+        const newState = { ...state };
         delete newState[id];
         return newState;
     };
@@ -28,10 +74,14 @@ export const filterResources = (filter: (resource: Resource) => boolean) =>
     (state: ResourcesState) =>
         Object
             .keys(state)
-            .map(id => getResource(id)(state))
+            .reduce((resources, id) => {
+                const resource = getResource(id)(state);
+                return resource
+                    ? [...resources, resource]
+                    : resources;
+            }, [])
             .filter(filter);
 
 export const filterResourcesByKind = (kind: ResourceKind) =>
     (state: ResourcesState) =>
         filterResources(resource => resource.kind === kind)(state);
-