19231: Add smaller page sizes (10 and 20 items) to load faster
[arvados-workbench2.git] / src / views / all-processes-panel / all-processes-panel.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import 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 { ArvadosTheme } from 'common/custom-theme';
15 import { ALL_PROCESSES_PANEL_ID } from 'store/all-processes-panel/all-processes-panel-action';
16 import {
17     ProcessStatus,
18     ResourceName,
19     ResourceOwnerWithName,
20     ResourceType,
21     ContainerRunTime,
22     ResourceCreatedAtDate
23 } from 'views-components/data-explorer/renderers';
24 import { ProcessIcon } from 'components/icon/icon';
25 import { openProcessContextMenu } from 'store/context-menu/context-menu-actions';
26 import { loadDetailsPanel } from 'store/details-panel/details-panel-action';
27 import { navigateTo } from 'store/navigation/navigation-action';
28 import { ContainerRequestState } from "models/container-request";
29 import { RootState } from 'store/store';
30 import { createTree } from 'models/tree';
31 import { getInitialProcessStatusFilters, getInitialProcessTypeFilters } from 'store/resource-type-filters/resource-type-filters';
32 import { getProcess } from 'store/processes/process';
33 import { ResourcesState } from 'store/resources/resources';
34
35 type CssRules = "toolbar" | "button" | "root";
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     root: {
46         width: '100%',
47     }
48 });
49
50 export enum AllProcessesPanelColumnNames {
51     NAME = "Name",
52     STATUS = "Status",
53     TYPE = "Type",
54     OWNER = "Owner",
55     CREATED_AT = "Created at",
56     RUNTIME = "Run Time"
57 }
58
59 export interface AllProcessesPanelFilter extends DataTableFilterItem {
60     type: ResourceKind | ContainerRequestState;
61 }
62
63 export const allProcessesPanelColumns: DataColumns<string> = [
64     {
65         name: AllProcessesPanelColumnNames.NAME,
66         selected: true,
67         configurable: true,
68         sortDirection: SortDirection.NONE,
69         filters: createTree(),
70         render: uuid => <ResourceName uuid={uuid} />
71     },
72     {
73         name: AllProcessesPanelColumnNames.STATUS,
74         selected: true,
75         configurable: true,
76         mutuallyExclusiveFilters: true,
77         filters: getInitialProcessStatusFilters(),
78         render: uuid => <ProcessStatus uuid={uuid} />
79     },
80     {
81         name: AllProcessesPanelColumnNames.TYPE,
82         selected: true,
83         configurable: true,
84         filters: getInitialProcessTypeFilters(),
85         render: uuid => <ResourceType uuid={uuid} />
86     },
87     {
88         name: AllProcessesPanelColumnNames.OWNER,
89         selected: true,
90         configurable: true,
91         filters: createTree(),
92         render: uuid => <ResourceOwnerWithName uuid={uuid} />
93     },
94     {
95         name: AllProcessesPanelColumnNames.CREATED_AT,
96         selected: true,
97         configurable: true,
98         sortDirection: SortDirection.DESC,
99         filters: createTree(),
100         render: uuid => <ResourceCreatedAtDate uuid={uuid} />
101     },
102     {
103         name: AllProcessesPanelColumnNames.RUNTIME,
104         selected: true,
105         configurable: true,
106         filters: createTree(),
107         render: uuid => <ContainerRunTime uuid={uuid} />
108     }
109 ];
110
111 interface AllProcessesPanelDataProps {
112     resources: ResourcesState;
113 }
114
115 interface AllProcessesPanelActionProps {
116     onItemClick: (item: string) => void;
117     onDialogOpen: (ownerUuid: string) => void;
118     onItemDoubleClick: (item: string) => void;
119 }
120 const mapStateToProps = (state : RootState): AllProcessesPanelDataProps => ({
121     resources: state.resources
122 });
123
124 type AllProcessesPanelProps = AllProcessesPanelDataProps & AllProcessesPanelActionProps & DispatchProp
125     & WithStyles<CssRules> & RouteComponentProps<{ id: string }>;
126
127 export const AllProcessesPanel = withStyles(styles)(
128     connect(mapStateToProps)(
129         class extends React.Component<AllProcessesPanelProps> {
130             handleContextMenu = (event: React.MouseEvent<HTMLElement>, resourceUuid: string) => {
131                 const process = getProcess(resourceUuid)(this.props.resources);
132                 if (process) {
133                     this.props.dispatch<any>(openProcessContextMenu(event, process));
134                 }
135                 this.props.dispatch<any>(loadDetailsPanel(resourceUuid));
136             }
137
138             handleRowDoubleClick = (uuid: string) => {
139                 this.props.dispatch<any>(navigateTo(uuid));
140             }
141
142             handleRowClick = (uuid: string) => {
143                 this.props.dispatch<any>(loadDetailsPanel(uuid));
144             }
145
146             render() {
147                 return <div className={this.props.classes.root}><DataExplorer
148                     id={ALL_PROCESSES_PANEL_ID}
149                     onRowClick={this.handleRowClick}
150                     onRowDoubleClick={this.handleRowDoubleClick}
151                     onContextMenu={this.handleContextMenu}
152                     contextMenuColumn={true}
153                     defaultViewIcon={ProcessIcon}
154                     defaultViewMessages={['Processes list empty.']} />
155                 </div>
156             }
157         }
158     )
159 );