Merge branch 'master' into 14452-my-account
[arvados-workbench2.git] / src / components / file-tree / file-tree-item.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 { TreeItem } from "../tree/tree";
7 import { ProjectIcon, MoreOptionsIcon, DefaultIcon, CollectionIcon } from "../icon/icon";
8 import { Typography, IconButton, StyleRulesCallback, withStyles, WithStyles, Tooltip } from '@material-ui/core';
9 import { formatFileSize } from "~/common/formatters";
10 import { ListItemTextIcon } from "../list-item-text-icon/list-item-text-icon";
11 import { FileTreeData } from "./file-tree-data";
12 import { FileThumbnail } from '~/components/file-tree/file-thumbnail';
13
14 type CssRules = "root" | "spacer" | "sizeInfo" | "button" | "moreOptions";
15
16 const fileTreeItemStyle: StyleRulesCallback<CssRules> = theme => ({
17     root: {
18         display: "flex",
19         alignItems: "center",
20         paddingRight: `${theme.spacing.unit * 1.5}px`
21     },
22     spacer: {
23         flex: "1"
24     },
25     sizeInfo: {
26         width: `${theme.spacing.unit * 8}px`
27     },
28     button: {
29         width: theme.spacing.unit * 3,
30         height: theme.spacing.unit * 3,
31         marginRight: theme.spacing.unit,
32     },
33     moreOptions: {
34         position: 'absolute'
35     }
36 });
37
38 export interface FileTreeItemProps {
39     item: TreeItem<FileTreeData>;
40     onMoreClick: (event: React.MouseEvent<any>, item: TreeItem<FileTreeData>) => void;
41 }
42 export const FileTreeItem = withStyles(fileTreeItemStyle)(
43     class extends React.Component<FileTreeItemProps & WithStyles<CssRules>> {
44         render() {
45             const { classes, item } = this.props;
46             return <>
47                 <div className={classes.root}>
48                     <ListItemTextIcon
49                         icon={getIcon(item)}
50                         name={item.data.name} />
51                     <div className={classes.spacer} />
52                     <Typography
53                         className={classes.sizeInfo}
54                         variant="caption">{formatFileSize(item.data.size)}</Typography>
55                     <Tooltip title="More options" disableFocusListener>
56                         <IconButton
57                             className={classes.button}
58                             onClick={this.handleClick}>
59                             <MoreOptionsIcon className={classes.moreOptions} />
60                         </IconButton>
61                     </Tooltip>
62                 </div >
63                 <FileThumbnail file={item.data} />
64             </>;
65         }
66
67         handleClick = (event: React.MouseEvent<any>) => {
68             this.props.onMoreClick(event, this.props.item);
69         }
70     });
71
72 const getIcon = (item: TreeItem<FileTreeData>) => {
73     switch (item.data.type) {
74         case 'directory':
75             return ProjectIcon;
76         case 'file':
77             return CollectionIcon;
78         default:
79             return DefaultIcon;
80     }
81 };
82