21357: myfavorites now optimistically renders Arvados-DCO-1.1-Signed-off-by: Lisa...
authorLisa Knox <lisaknox83@gmail.com>
Tue, 12 Mar 2024 15:32:36 +0000 (11:32 -0400)
committerLisa Knox <lisaknox83@gmail.com>
Tue, 12 Mar 2024 15:32:36 +0000 (11:32 -0400)
services/workbench2/src/common/link-update-name.ts
services/workbench2/src/store/side-panel-tree/side-panel-tree-actions.ts

index 8530f5cd380135948ff581dbd8abb3ed4b58fdc6..453c77941e88efe6ceb9a96547f674bd5eea8a51 100644 (file)
@@ -10,24 +10,29 @@ import { Resource, extractUuidKind } from 'models/resource';
 
 type NameableResource = Resource & { name?: string };
 
-export const verifyAndUpdateLinkName = async (link: LinkResource, dispatch: Dispatch, getState: () => RootState, services: ServiceRepository):Promise<string> => {
-  //check if head resource is already in the store
+export const verifyAndUpdateLink = async (link: LinkResource, dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<LinkResource> => {
+    //check if head resource is already in the store
     let headResource: Resource | undefined = getState().resources[link.headUuid];
     //if not, fetch it
     if (!headResource) {
         headResource = await fetchResource(link.headUuid)(dispatch, getState, services);
-        if(!headResource) {
-            console.error('Could not validate link', link, 'because link head', link.headUuid, 'is not available');
-            return link.name;
+        if (!headResource) {
+            if (!link.name) console.error('Could not validate link', link, 'because link head', link.headUuid, 'is not available');
+            return link;
         }
     }
 
-    if (validateLinkNameProp(link, headResource) === true) return link.name;
+    if (validateLinkNameProp(link, headResource) === true) return link;
 
     const updatedLink = updateLinkNameProp(link, headResource);
     updateRemoteLinkName(updatedLink)(dispatch, getState, services);
-    
-    return updatedLink.name;
+
+    return updatedLink;
+};
+
+export const verifyAndUpdateLinks = async (links: LinkResource[], dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    const updatedLinks = links.map((link) => verifyAndUpdateLink(link, dispatch, getState, services));
+        return Promise.all(updatedLinks);
 };
 
 const fetchResource = (uuid: string, showErrors?: boolean) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
@@ -38,29 +43,29 @@ const fetchResource = (uuid: string, showErrors?: boolean) => async (dispatch: D
             const resource = await service.get(uuid, showErrors);
             return resource;
         }
-    } catch(e) {
+    } catch (e) {
         console.error(`Could not fetch resource ${uuid}`, e);
     }
     return undefined;
 };
 
 const validateLinkNameProp = (link: LinkResource, head: NameableResource) => {
-  if(!link.name || link.name !== head.name) return false;
+    if (!link.name || link.name !== head.name) return false;
     return true;
 };
 
 const updateLinkNameProp = (link: LinkResource, head: NameableResource) => {
-  const updatedLink = {...link};
-  if(head.name) updatedLink.name = head.name;
-  return updatedLink;
-}
+    const updatedLink = { ...link };
+    if (head.name) updatedLink.name = head.name;
+    return updatedLink;
+};
 
 const updateRemoteLinkName = (link: LinkResource) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
     try {
         const kind = extractUuidKind(link.uuid);
         const service = getResourceService(kind)(services);
         if (service) {
-            service.update(link.uuid, {name: link.name});
+            service.update(link.uuid, { name: link.name });
         }
     } catch (error) {
         console.error('Could not update link name', link, error);
index a136e2c1e40a867a5bab8286466a360cfca93055..ea4df655fd8023d270bb1231743e86b696a05e89 100644 (file)
@@ -16,8 +16,8 @@ import { OrderBuilder } from 'services/api/order-builder';
 import { ResourceKind } from 'models/resource';
 import { CategoriesListReducer } from 'common/plugintypes';
 import { pluginConfig } from 'plugins';
-import { LinkClass } from 'models/link';
-import { verifyAndUpdateLinkName } from 'common/link-update-name';
+import { LinkClass, LinkResource } from 'models/link';
+import { verifyAndUpdateLinks } from 'common/link-update-name';
 
 export enum SidePanelTreeCategory {
     PROJECTS = 'Home Projects',
@@ -103,7 +103,8 @@ export const loadSidePanelTreeProjects = (projectUuid: string) =>
         if (projectUuid === SidePanelTreeCategory.PUBLIC_FAVORITES) {
             await dispatch<any>(loadPublicFavoritesTree());
         } else if (projectUuid === SidePanelTreeCategory.FAVORITES) {
-            await dispatch<any>(loadFavoritesTree());
+            const unverifiedLinks = await dispatch<any>(loadFavoritesTree());
+            verifyAndUpdateLinkNames(unverifiedLinks, dispatch, getState, services);
         } else if (node || projectUuid !== '') {
             await dispatch<any>(loadProject(projectUuid));
         }
@@ -145,11 +146,7 @@ export const loadFavoritesTree = () => async (dispatch: Dispatch, getState: () =
         limit: SIDEPANEL_TREE_NODE_LIMIT,
     };
 
-    let items = (await services.linkService.list(params)).items;
-    for(let item of items) {
-        const verifiedName = await verifyAndUpdateLinkName(item, dispatch, getState, services);
-        item.name = verifiedName;
-    }
+    const { items } = await services.linkService.list(params);
 
     dispatch(
         treePickerActions.LOAD_TREE_PICKER_NODE_SUCCESS({
@@ -159,7 +156,19 @@ export const loadFavoritesTree = () => async (dispatch: Dispatch, getState: () =
         })
     );
 
-    dispatch(resourcesActions.SET_RESOURCES(items));
+    return items;
+};
+
+const verifyAndUpdateLinkNames = async (links: LinkResource[], dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    const verfifiedLinks = await verifyAndUpdateLinks(links, dispatch, getState, services);
+
+    dispatch(
+        treePickerActions.LOAD_TREE_PICKER_NODE_SUCCESS({
+            id: SidePanelTreeCategory.FAVORITES,
+            pickerId: SIDE_PANEL_TREE,
+            nodes: verfifiedLinks.map(item => initTreeNode({ id: item.headUuid, value: item })),
+        })
+    );
 };
 
 export const loadPublicFavoritesTree = () => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
@@ -205,10 +214,10 @@ export const loadPublicFavoritesTree = () => async (dispatch: Dispatch, getState
 
     const filteredItems = items.filter(item => responseItems.some(responseItem => responseItem.uuid === item.headUuid));
 
-    for(const item of filteredItems) {
-        const verifiedName = await verifyAndUpdateLinkName(item, dispatch, getState, services);
-        item.name = verifiedName;
-    }
+    // for(const item of filteredItems) {
+    //     const verifiedName = await verifyAndUpdateLinkName(item, dispatch, getState, services);
+    //     item.name = verifiedName;
+    // }
 
     dispatch(
         treePickerActions.LOAD_TREE_PICKER_NODE_SUCCESS({