Move default views to corresponding panels
[arvados-workbench2.git] / src / views / favorite-panel / favorite-panel.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from 'react';
6 import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core';
7 import { DataExplorer } from "~/views-components/data-explorer/data-explorer";
8 import { connect, DispatchProp } from 'react-redux';
9 import { DataColumns } from '~/components/data-table/data-table';
10 import { RouteComponentProps } from 'react-router';
11 import { DataTableFilterItem } from '~/components/data-table-filters/data-table-filters';
12 import { SortDirection } from '~/components/data-table/data-column';
13 import { ResourceKind } from '~/models/resource';
14 import { resourceLabel } from '~/common/labels';
15 import { ArvadosTheme } from '~/common/custom-theme';
16 import { FAVORITE_PANEL_ID } from "~/store/favorite-panel/favorite-panel-action";
17 import {
18     ProcessStatus,
19     ResourceFileSize,
20     ResourceLastModifiedDate,
21     ResourceName,
22     ResourceOwner,
23     ResourceType
24 } from '~/views-components/data-explorer/renderers';
25 import { FavoriteIcon } from '~/components/icon/icon';
26 import { Dispatch } from 'redux';
27 import { openContextMenu, resourceKindToContextMenuKind } from '~/store/context-menu/context-menu-actions';
28 import { loadDetailsPanel } from '~/store/details-panel/details-panel-action';
29 import { navigateTo } from '~/store/navigation/navigation-action';
30 import { ContainerRequestState } from "~/models/container-request";
31 import { DefaultView } from '~/components/default-view/default-view';
32 import { FavoritesState } from '../../store/favorites/favorites-reducer';
33 import { RootState } from '~/store/store';
34
35 type CssRules = "toolbar" | "button";
36
37 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
38     toolbar: {
39         paddingBottom: theme.spacing.unit * 3,
40         textAlign: "right"
41     },
42     button: {
43         marginLeft: theme.spacing.unit
44     },
45 });
46
47 export enum FavoritePanelColumnNames {
48     NAME = "Name",
49     STATUS = "Status",
50     TYPE = "Type",
51     OWNER = "Owner",
52     FILE_SIZE = "File size",
53     LAST_MODIFIED = "Last modified"
54 }
55
56 export interface FavoritePanelFilter extends DataTableFilterItem {
57     type: ResourceKind | ContainerRequestState;
58 }
59
60 export const favoritePanelColumns: DataColumns<string, FavoritePanelFilter> = [
61     {
62         name: FavoritePanelColumnNames.NAME,
63         selected: true,
64         configurable: true,
65         sortDirection: SortDirection.ASC,
66         filters: [],
67         render: uuid => <ResourceName uuid={uuid} />,
68         width: "450px"
69     },
70     {
71         name: "Status",
72         selected: true,
73         configurable: true,
74         filters: [],
75         render: uuid => <ProcessStatus uuid={uuid} />,
76         width: "75px"
77     },
78     {
79         name: FavoritePanelColumnNames.TYPE,
80         selected: true,
81         configurable: true,
82         filters: [
83             {
84                 name: resourceLabel(ResourceKind.COLLECTION),
85                 selected: true,
86                 type: ResourceKind.COLLECTION
87             },
88             {
89                 name: resourceLabel(ResourceKind.PROCESS),
90                 selected: true,
91                 type: ResourceKind.PROCESS
92             },
93             {
94                 name: resourceLabel(ResourceKind.PROJECT),
95                 selected: true,
96                 type: ResourceKind.PROJECT
97             }
98         ],
99         render: uuid => <ResourceType uuid={uuid} />,
100         width: "125px"
101     },
102     {
103         name: FavoritePanelColumnNames.OWNER,
104         selected: true,
105         configurable: true,
106         filters: [],
107         render: uuid => <ResourceOwner uuid={uuid} />,
108         width: "200px"
109     },
110     {
111         name: FavoritePanelColumnNames.FILE_SIZE,
112         selected: true,
113         configurable: true,
114         filters: [],
115         render: uuid => <ResourceFileSize uuid={uuid} />,
116         width: "50px"
117     },
118     {
119         name: FavoritePanelColumnNames.LAST_MODIFIED,
120         selected: true,
121         configurable: true,
122         sortDirection: SortDirection.NONE,
123         filters: [],
124         render: uuid => <ResourceLastModifiedDate uuid={uuid} />,
125         width: "150px"
126     }
127 ];
128
129 interface FavoritePanelDataProps {
130     favorites: FavoritesState;
131 }
132
133 interface FavoritePanelActionProps {
134     onItemClick: (item: string) => void;
135     onContextMenu: (event: React.MouseEvent<HTMLElement>, item: string) => void;
136     onDialogOpen: (ownerUuid: string) => void;
137     onItemDoubleClick: (item: string) => void;
138 }
139 const mapStateToProps = ({ favorites }: RootState): FavoritePanelDataProps => ({
140     favorites
141 });
142
143 const mapDispatchToProps = (dispatch: Dispatch): FavoritePanelActionProps => ({
144     onContextMenu: (event, resourceUuid) => {
145         const kind = resourceKindToContextMenuKind(resourceUuid);
146         if (kind) {
147             dispatch<any>(openContextMenu(event, {
148                 name: '',
149                 uuid: resourceUuid,
150                 ownerUuid: '',
151                 kind: ResourceKind.NONE,
152                 menuKind: kind
153             }));
154         }
155     },
156     onDialogOpen: (ownerUuid: string) => { return; },
157     onItemClick: (resourceUuid: string) => {
158         dispatch<any>(loadDetailsPanel(resourceUuid));
159     },
160     onItemDoubleClick: uuid => {
161         dispatch<any>(navigateTo(uuid));
162     }
163 });
164
165 type FavoritePanelProps = FavoritePanelDataProps & FavoritePanelActionProps & DispatchProp
166     & WithStyles<CssRules> & RouteComponentProps<{ id: string }>;
167
168 export const FavoritePanel = withStyles(styles)(
169     connect(mapStateToProps, mapDispatchToProps)(
170         class extends React.Component<FavoritePanelProps> {
171             render() {
172                 return this.hasAnyFavorites()
173                     ? <DataExplorer
174                         id={FAVORITE_PANEL_ID}
175                         onRowClick={this.props.onItemClick}
176                         onRowDoubleClick={this.props.onItemDoubleClick}
177                         onContextMenu={this.props.onContextMenu}
178                         contextMenuColumn={true} />
179                     : <DefaultView
180                         icon={FavoriteIcon}
181                         messages={['Your favorites list is empty.']} />;
182             }
183
184             hasAnyFavorites = () => {
185                 return Object
186                     .keys(this.props.favorites)
187                     .find(uuid => this.props.favorites[uuid]);
188             }
189         }
190     )
191 );