453c77941e88efe6ceb9a96547f674bd5eea8a51
[arvados.git] / services / workbench2 / src / common / link-update-name.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { LinkResource } from 'models/link';
6 import { Dispatch } from 'redux';
7 import { RootState } from 'store/store';
8 import { ServiceRepository, getResourceService } from 'services/services';
9 import { Resource, extractUuidKind } from 'models/resource';
10
11 type NameableResource = Resource & { name?: string };
12
13 export const verifyAndUpdateLink = async (link: LinkResource, dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<LinkResource> => {
14     //check if head resource is already in the store
15     let headResource: Resource | undefined = getState().resources[link.headUuid];
16     //if not, fetch it
17     if (!headResource) {
18         headResource = await fetchResource(link.headUuid)(dispatch, getState, services);
19         if (!headResource) {
20             if (!link.name) console.error('Could not validate link', link, 'because link head', link.headUuid, 'is not available');
21             return link;
22         }
23     }
24
25     if (validateLinkNameProp(link, headResource) === true) return link;
26
27     const updatedLink = updateLinkNameProp(link, headResource);
28     updateRemoteLinkName(updatedLink)(dispatch, getState, services);
29
30     return updatedLink;
31 };
32
33 export const verifyAndUpdateLinks = async (links: LinkResource[], dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
34     const updatedLinks = links.map((link) => verifyAndUpdateLink(link, dispatch, getState, services));
35         return Promise.all(updatedLinks);
36 };
37
38 const fetchResource = (uuid: string, showErrors?: boolean) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
39     try {
40         const kind = extractUuidKind(uuid);
41         const service = getResourceService(kind)(services);
42         if (service) {
43             const resource = await service.get(uuid, showErrors);
44             return resource;
45         }
46     } catch (e) {
47         console.error(`Could not fetch resource ${uuid}`, e);
48     }
49     return undefined;
50 };
51
52 const validateLinkNameProp = (link: LinkResource, head: NameableResource) => {
53     if (!link.name || link.name !== head.name) return false;
54     return true;
55 };
56
57 const updateLinkNameProp = (link: LinkResource, head: NameableResource) => {
58     const updatedLink = { ...link };
59     if (head.name) updatedLink.name = head.name;
60     return updatedLink;
61 };
62
63 const updateRemoteLinkName = (link: LinkResource) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
64     try {
65         const kind = extractUuidKind(link.uuid);
66         const service = getResourceService(kind)(services);
67         if (service) {
68             service.update(link.uuid, { name: link.name });
69         }
70     } catch (error) {
71         console.error('Could not update link name', link, error);
72     }
73 };