21700: Install Bundler system-wide in Rails postinst
[arvados.git] / services / workbench2 / src / views / groups-panel / groups-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 { connect } from 'react-redux';
7 import { Grid, Button, StyleRulesCallback, WithStyles, withStyles } from "@material-ui/core";
8 import { DataExplorer } from "views-components/data-explorer/data-explorer";
9 import { DataColumns } from 'components/data-table/data-table';
10 import { SortDirection } from 'components/data-table/data-column';
11 import { GroupMembersCount, ResourceUuid } from 'views-components/data-explorer/renderers';
12 import { AddIcon } from 'components/icon/icon';
13 import { ResourceName } from 'views-components/data-explorer/renderers';
14 import { createTree } from 'models/tree';
15 import { GROUPS_PANEL_ID, openCreateGroupDialog } from 'store/groups-panel/groups-panel-actions';
16 import { noop } from 'lodash/fp';
17 import { ContextMenuKind } from 'views-components/context-menu/menu-item-sort';
18 import { getResource, ResourcesState } from 'store/resources/resources';
19 import { GroupResource } from 'models/group';
20 import { RootState } from 'store/store';
21 import { openContextMenu } from 'store/context-menu/context-menu-actions';
22 import { ArvadosTheme } from 'common/custom-theme';
23
24 type CssRules = "root";
25
26 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
27     root: {
28         width: '100%',
29     }
30 });
31
32 export enum GroupsPanelColumnNames {
33     GROUP = "Name",
34     UUID = "UUID",
35     MEMBERS = "Members",
36 }
37
38 export const groupsPanelColumns: DataColumns<string, GroupResource> = [
39     {
40         name: GroupsPanelColumnNames.GROUP,
41         selected: true,
42         configurable: true,
43         sort: {direction: SortDirection.ASC, field: "name"},
44         filters: createTree(),
45         render: uuid => <ResourceName uuid={uuid} />
46     },
47     {
48         name: GroupsPanelColumnNames.UUID,
49         selected: true,
50         configurable: true,
51         filters: createTree(),
52         render: uuid => <ResourceUuid uuid={uuid} />,
53     },
54     {
55         name: GroupsPanelColumnNames.MEMBERS,
56         selected: true,
57         configurable: true,
58         filters: createTree(),
59         render: uuid => <GroupMembersCount uuid={uuid} />,
60     },
61 ];
62
63 const mapStateToProps = (state: RootState) => {
64     return {
65         resources: state.resources
66     };
67 };
68
69 const mapDispatchToProps = {
70     onContextMenu: openContextMenu,
71     onNewGroup: openCreateGroupDialog,
72 };
73
74 export interface GroupsPanelProps {
75     onNewGroup: () => void;
76     onContextMenu: (event: React.MouseEvent<HTMLElement>, item: any) => void;
77     resources: ResourcesState;
78 }
79
80 export const GroupsPanel = withStyles(styles)(connect(
81     mapStateToProps, mapDispatchToProps
82 )(
83     class GroupsPanel extends React.Component<GroupsPanelProps & WithStyles<CssRules>> {
84
85         render() {
86             return (
87                 <div className={this.props.classes.root}><DataExplorer
88                     id={GROUPS_PANEL_ID}
89                     data-cy="groups-panel-data-explorer"
90                     onRowClick={noop}
91                     onRowDoubleClick={noop}
92                     onContextMenu={this.handleContextMenu}
93                     contextMenuColumn={true}
94                     hideColumnSelector
95                     actions={
96                         <Grid container justify='flex-end'>
97                             <Button
98                                 data-cy="groups-panel-new-group"
99                                 variant="contained"
100                                 color="primary"
101                                 onClick={this.props.onNewGroup}>
102                                 <AddIcon /> New group
103                         </Button>
104                         </Grid>
105                     } /></div>
106             );
107         }
108
109         handleContextMenu = (event: React.MouseEvent<HTMLElement>, resourceUuid: string) => {
110             const resource = getResource<GroupResource>(resourceUuid)(this.props.resources);
111             if (resource) {
112                 this.props.onContextMenu(event, {
113                     name: resource.name,
114                     uuid: resource.uuid,
115                     description: resource.description,
116                     ownerUuid: resource.ownerUuid,
117                     kind: resource.kind,
118                     menuKind: ContextMenuKind.GROUPS
119                 });
120             }
121         }
122     }));