18123: Add permissions data explorer and tab in groups edit
[arvados-workbench2.git] / src / views / group-details-panel / group-details-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
8 import { DataExplorer } from "views-components/data-explorer/data-explorer";
9 import { DataColumns } from 'components/data-table/data-table';
10 import { ResourceFullName, ResourceUuid, ResourceEmail, ResourceUsername } from 'views-components/data-explorer/renderers';
11 import { createTree } from 'models/tree';
12 import { noop } from 'lodash/fp';
13 import { RootState } from 'store/store';
14 import { GROUP_DETAILS_PANEL_ID, GROUP_PERMISSIONS_PANEL_ID, openAddGroupMembersDialog } from 'store/group-details-panel/group-details-panel-actions';
15 import { openContextMenu } from 'store/context-menu/context-menu-actions';
16 import { ResourcesState, getResource } from 'store/resources/resources';
17 import { ContextMenuKind } from 'views-components/context-menu/context-menu';
18 import { PermissionResource } from 'models/permission';
19 import { Grid, Button, Tabs, Tab, Paper } from '@material-ui/core';
20 import { AddIcon } from 'components/icon/icon';
21
22 export enum GroupDetailsPanelColumnNames {
23     FULL_NAME = "Name",
24     UUID = "UUID",
25     EMAIL = "Email",
26     USERNAME = "Username",
27 }
28
29 export const groupDetailsPanelColumns: DataColumns<string> = [
30     {
31         name: GroupDetailsPanelColumnNames.FULL_NAME,
32         selected: true,
33         configurable: true,
34         filters: createTree(),
35         render: uuid => <ResourceFullName uuid={uuid} />
36     },
37     {
38         name: GroupDetailsPanelColumnNames.USERNAME,
39         selected: true,
40         configurable: true,
41         filters: createTree(),
42         render: uuid => <ResourceUsername uuid={uuid} />
43     },
44     {
45         name: GroupDetailsPanelColumnNames.UUID,
46         selected: true,
47         configurable: true,
48         filters: createTree(),
49         render: uuid => <ResourceUuid uuid={uuid} />
50     },
51     {
52         name: GroupDetailsPanelColumnNames.EMAIL,
53         selected: true,
54         configurable: true,
55         filters: createTree(),
56         render: uuid => <ResourceEmail uuid={uuid} />
57     },
58 ];
59
60 const mapStateToProps = (state: RootState) => {
61     return {
62         resources: state.resources
63     };
64 };
65
66 const mapDispatchToProps = {
67     onContextMenu: openContextMenu,
68     onAddUser: openAddGroupMembersDialog,
69 };
70
71 export interface GroupDetailsPanelProps {
72     onContextMenu: (event: React.MouseEvent<HTMLElement>, item: any) => void;
73     onAddUser: () => void;
74     resources: ResourcesState;
75 }
76
77 export const GroupDetailsPanel = connect(
78     mapStateToProps, mapDispatchToProps
79 )(
80     class GroupDetailsPanel extends React.Component<GroupDetailsPanelProps> {
81         state = {
82           value: 0,
83         };
84
85         componentDidMount() {
86             this.setState({ value: 0 });
87         }
88
89         render() {
90             const { value } = this.state;
91             return (
92                 <Paper>
93                   <Tabs value={value} onChange={this.handleChange} fullWidth>
94                       <Tab label="MEMBERS" />
95                       <Tab label="PERMISSIONS" />
96                   </Tabs>
97                   {value === 0 &&
98                       <DataExplorer
99                           id={GROUP_DETAILS_PANEL_ID}
100                           onRowClick={noop}
101                           onRowDoubleClick={noop}
102                           onContextMenu={this.handleContextMenu}
103                           contextMenuColumn={true}
104                           hideColumnSelector
105                           hideSearchInput
106                           actions={
107                               <Grid container justify='flex-end'>
108                                   <Button
109                                       variant="contained"
110                                       color="primary"
111                                       onClick={this.props.onAddUser}>
112                                       <AddIcon /> Add user
113                               </Button>
114                               </Grid>
115                           }
116                           paperProps={{
117                               elevation: 0,
118                           }} />
119                   }
120                   {value === 1 &&
121                       <DataExplorer
122                           id={GROUP_PERMISSIONS_PANEL_ID}
123                           onRowClick={noop}
124                           onRowDoubleClick={noop}
125                           onContextMenu={this.handleContextMenu}
126                           contextMenuColumn={true}
127                           hideColumnSelector
128                           hideSearchInput
129                           actions={
130                               <Grid container justify='flex-end'>
131                                   <Button
132                                       variant="contained"
133                                       color="primary"
134                                       onClick={this.props.onAddUser}>
135                                       <AddIcon /> Add user
136                               </Button>
137                               </Grid>
138                           }
139                           paperProps={{
140                               elevation: 0,
141                           }} />
142                   }
143                 </Paper>
144             );
145         }
146
147         handleContextMenu = (event: React.MouseEvent<HTMLElement>, resourceUuid: string) => {
148             const resource = getResource<PermissionResource>(resourceUuid)(this.props.resources);
149             if (resource) {
150                 this.props.onContextMenu(event, {
151                     name: '',
152                     uuid: resource.uuid,
153                     ownerUuid: resource.ownerUuid,
154                     kind: resource.kind,
155                     menuKind: ContextMenuKind.GROUP_MEMBER
156                 });
157             }
158         }
159
160         handleChange = (event: React.MouseEvent<HTMLElement>, value: number) => {
161             this.setState({ value });
162         }
163     });