21e8d2789498460028b100e0d35e095dd56b05e1
[arvados-workbench2.git] / src / views / project-explorer / project-explorer.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 DataExplorer, { DataExplorerProps } from "../../components/data-explorer/data-explorer";
7 import { RouteComponentProps } from 'react-router';
8 import { Project } from '../../models/project';
9 import { ProjectState, findTreeItem } from '../../store/project/project-reducer';
10 import { RootState } from '../../store/store';
11 import { connect, DispatchProp } from 'react-redux';
12 import { push } from 'react-router-redux';
13 import projectActions from "../../store/project/project-action";
14 import { Typography } from '@material-ui/core';
15 import { Column } from '../../components/data-explorer/column';
16
17 interface ProjectExplorerViewDataProps {
18     projects: ProjectState;
19 }
20
21 type ProjectExplorerViewProps = ProjectExplorerViewDataProps & RouteComponentProps<{ name: string }> & DispatchProp;
22
23 type ProjectExplorerViewState = Pick<DataExplorerProps<Project>, "columns">;
24
25 class ProjectExplorerView extends React.Component<ProjectExplorerViewProps, ProjectExplorerViewState> {
26
27     state: ProjectExplorerViewState = {
28         columns: [
29             { header: "Name", selected: true, render: item => <Typography noWrap>{renderIcon(item.kind)} {item.name}</Typography> },
30             { header: "Created at", selected: true, render: item => <Typography noWrap>{formatDate(item.createdAt)}</Typography> },
31             { header: "Modified at", selected: true, render: item => <Typography noWrap>{formatDate(item.modifiedAt)}</Typography> },
32             { header: "UUID", selected: true, render: item => <Typography noWrap>{item.uuid}</Typography> },
33             { header: "Owner UUID", selected: true, render: item => <Typography noWrap>{item.ownerUuid}</Typography> },
34             { header: "URL", selected: true, render: item => <Typography noWrap>{item.href}</Typography> }
35         ]
36     };
37
38     render() {
39         const project = findTreeItem(this.props.projects, this.props.match.params.name);
40         const projectItems = project && project.items || [];
41         return (
42             <DataExplorer {...this.state} items={projectItems.map(item => item.data)} onItemClick={this.goToProject} onColumnToggle={this.toggleColumn} />
43         );
44     }
45
46
47     goToProject = (project: Project) => {
48         this.props.dispatch(push(`/project/${project.uuid}`));
49         this.props.dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM(project.uuid));
50     }
51
52     toggleColumn = (column: Column<Project>) => {
53         const index = this.state.columns.indexOf(column);
54         const columns = this.state.columns.slice(0);
55         columns.splice(index, 1, { ...column, selected: !column.selected });
56         this.setState({ columns });
57     }
58 }
59
60 const formatDate = (isoDate: string) => {
61     const date = new Date(isoDate);
62     return date.toLocaleString();
63 };
64
65 const renderIcon = (kind: string) => {
66     switch (kind) {
67         case "arvados#group":
68             return <i className="fas fa-folder" />;
69         case "arvados#groupList":
70             return <i className="fas fa-th" />;
71         default:
72             return <i />;
73     }
74 };
75
76 export default connect(
77     (state: RootState) => ({
78         projects: state.projects
79     })
80 )(ProjectExplorerView);