Extract breadcrumbs view component
[arvados-workbench2.git] / src / views-components / breadcrumbs / breadcrumbs.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { connect } from "react-redux";
6 import { Breadcrumbs as BreadcrumbsComponent, BreadcrumbsProps } from '~/components/breadcrumbs/breadcrumbs';
7 import { RootState } from '~/store/store';
8 import { Breadcrumb } from '~/components/breadcrumbs/breadcrumbs';
9 import { matchProjectRoute } from '~/routes/routes';
10 import { getTreePicker } from '~/store/tree-picker/tree-picker';
11 import { SIDE_PANEL_TREE } from '~/store/side-panel-tree/side-panel-tree-actions';
12 import { getNodeAncestors, getNode } from '~/models/tree';
13 import { Dispatch } from 'redux';
14 import { navigateToResource } from '~/store/navigation/navigation-action';
15
16 interface ResourceBreadcrumb extends Breadcrumb {
17     uuid: string;
18 }
19
20 type BreadcrumbsDataProps = Pick<BreadcrumbsProps, 'items'>;
21 type BreadcrumbsActionProps = Pick<BreadcrumbsProps, 'onClick' | 'onContextMenu'>;
22
23 const memoizedMapStateToProps = () => {
24     let items: ResourceBreadcrumb[] = [];
25     return ({ router, treePicker }: RootState): BreadcrumbsDataProps => {
26         if (router.location) {
27             const projectMatch = matchProjectRoute(location.pathname);
28             const collectionMatch = matchProjectRoute(location.pathname);
29             const uuid = projectMatch && projectMatch.params.id
30                 || collectionMatch && collectionMatch.params.id
31                 || '';
32             const tree = getTreePicker(SIDE_PANEL_TREE)(treePicker);
33             if (tree) {
34                 const ancestors = getNodeAncestors(uuid)(tree);
35                 const node = getNode(uuid)(tree);
36                 const nodes = node ? [...ancestors, node] : ancestors;
37                 items = nodes.map(({ value }) =>
38                     typeof value.value === 'string'
39                         ? { label: value.value, uuid: value.nodeId }
40                         : { label: value.value.name, uuid: value.value.uuid });
41             }
42         }
43         return { items };
44     };
45 };
46
47 const mapDispatchToProps = (dispatch: Dispatch): BreadcrumbsActionProps => ({
48     onClick: ({ uuid }: ResourceBreadcrumb) => {
49         dispatch<any>(navigateToResource(uuid));
50     },
51     onContextMenu: () => { return; }
52 });
53
54 export const Breadcrumbs = connect(memoizedMapStateToProps(), mapDispatchToProps)(BreadcrumbsComponent);