1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import { RouteComponentProps } from 'react-router';
7 import { ProjectState } from '../../store/project/project-reducer';
8 import { RootState } from '../../store/store';
9 import { connect, DispatchProp } from 'react-redux';
10 import { CollectionState } from "../../store/collection/collection-reducer";
11 import { ItemMode, setProjectItem } from "../../store/navigation/navigation-action";
12 import ProjectExplorer from "../../views-components/project-explorer/project-explorer";
13 import { projectExplorerItems } from "./project-panel-selectors";
14 import { ProjectExplorerItem } from "../../views-components/project-explorer/project-explorer-item";
15 import { Button, StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core';
16 import { DataColumn, SortDirection } from '../../components/data-table/data-column';
17 import { DataTableFilterItem } from '../../components/data-table-filters/data-table-filters';
19 interface ProjectPanelDataProps {
20 projects: ProjectState;
21 collections: CollectionState;
24 type ProjectPanelProps = ProjectPanelDataProps & RouteComponentProps<{ name: string }> & DispatchProp;
26 interface ProjectPanelState {
29 direction: SortDirection;
34 class ProjectPanel extends React.Component<ProjectPanelProps & WithStyles<CssRules>, ProjectPanelState> {
35 state: ProjectPanelState = {
40 filters: ['collection', 'project']
44 const items = projectExplorerItems(
45 this.props.projects.items,
46 this.props.projects.currentItemId,
47 this.props.collections
49 const [goBackItem, ...otherItems] = items;
50 const filteredItems = otherItems.filter(i => this.state.filters.some(f => f === i.kind));
51 const sortedItems = sortItems(this.state.sort, filteredItems);
54 <div className={this.props.classes.toolbar}>
55 <Button color="primary" variant="raised" className={this.props.classes.button}>
58 <Button color="primary" variant="raised" className={this.props.classes.button}>
61 <Button color="primary" variant="raised" className={this.props.classes.button}>
66 items={goBackItem ? [goBackItem, ...sortedItems] : sortedItems}
67 onRowClick={this.goToItem}
68 onToggleSort={this.toggleSort}
69 onChangeFilters={this.changeFilters}
75 goToItem = (item: ProjectExplorerItem) => {
76 this.props.dispatch<any>(setProjectItem(this.props.projects.items, item.uuid, item.kind, ItemMode.BOTH));
79 toggleSort = (column: DataColumn<ProjectExplorerItem>) => {
82 columnName: column.name,
83 direction: column.sortDirection || "none"
88 changeFilters = (filters: DataTableFilterItem[]) => {
89 this.setState({ filters: filters.filter(f => f.selected).map(f => f.name.toLowerCase()) });
93 const sortItems = (sort: { columnName: string, direction: SortDirection }, items: ProjectExplorerItem[]) => {
94 const sortedItems = items.slice(0);
95 const direction = sort.direction === "asc" ? -1 : 1;
96 sortedItems.sort((a, b) => {
97 if (sort.columnName === "Last modified") {
98 return ((new Date(a.lastModified)).getTime() - (new Date(b.lastModified)).getTime()) * direction;
100 return a.name.localeCompare(b.name) * direction;
106 type CssRules = "toolbar" | "button";
108 const styles: StyleRulesCallback<CssRules> = theme => ({
110 marginBottom: theme.spacing.unit * 3,
112 justifyContent: "flex-end"
115 marginLeft: theme.spacing.unit
119 export default withStyles(styles)(
121 (state: RootState) => ({
122 projects: state.projects,
123 collections: state.collections