ae64b62890f2f31bf1ce9ac8f0e3bcaa2f850e17
[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 { ResourceLinkHeadUuid, ResourceLinkTailUuid, ResourceLinkTailEmail, ResourceLinkTailUsername, ResourceLinkHeadPermissionLevel, ResourceLinkTailPermissionLevel, ResourceLinkHead, ResourceLinkTail, ResourceLinkDelete, ResourceLinkTailIsActive, ResourceLinkTailIsHidden } 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_MEMBERS_PANEL_ID, GROUP_DETAILS_PERMISSIONS_PANEL_ID, openAddGroupMembersDialog, getCurrentGroupDetailsPanelUuid } 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 { Grid, Button, Tabs, Tab, Paper } from '@material-ui/core';
18 import { AddIcon } from 'components/icon/icon';
19 import { getUserUuid } from 'common/getuser';
20 import { GroupResource, isBuiltinGroup } from 'models/group';
21
22 export enum GroupDetailsPanelMembersColumnNames {
23     FULL_NAME = "Name",
24     USERNAME = "Username",
25     EMAIL = "Email",
26     ACTIVE = "User Active",
27     HIDDEN = "Member Hidden",
28     PERMISSION = "Permission",
29     UUID = "UUID",
30     REMOVE = "Remove",
31 }
32
33 export enum GroupDetailsPanelPermissionsColumnNames {
34     NAME = "Name",
35     PERMISSION = "Permission",
36     UUID = "UUID",
37     REMOVE = "Remove",
38 }
39
40 export const groupDetailsMembersPanelColumns: DataColumns<string> = [
41     {
42         name: GroupDetailsPanelMembersColumnNames.FULL_NAME,
43         selected: true,
44         configurable: true,
45         filters: createTree(),
46         render: uuid => <ResourceLinkTail uuid={uuid} />
47     },
48     {
49         name: GroupDetailsPanelMembersColumnNames.USERNAME,
50         selected: true,
51         configurable: true,
52         filters: createTree(),
53         render: uuid => <ResourceLinkTailUsername uuid={uuid} />
54     },
55     {
56         name: GroupDetailsPanelMembersColumnNames.EMAIL,
57         selected: true,
58         configurable: true,
59         filters: createTree(),
60         render: uuid => <ResourceLinkTailEmail uuid={uuid} />
61     },
62     {
63         name: GroupDetailsPanelMembersColumnNames.ACTIVE,
64         selected: true,
65         configurable: true,
66         filters: createTree(),
67         render: uuid => <ResourceLinkTailIsActive uuid={uuid} />
68     },
69     {
70         name: GroupDetailsPanelMembersColumnNames.HIDDEN,
71         selected: true,
72         configurable: true,
73         filters: createTree(),
74         render: uuid => <ResourceLinkTailIsHidden uuid={uuid} />
75     },
76     {
77         name: GroupDetailsPanelMembersColumnNames.PERMISSION,
78         selected: true,
79         configurable: true,
80         filters: createTree(),
81         render: uuid => <ResourceLinkTailPermissionLevel uuid={uuid} />
82     },
83     {
84         name: GroupDetailsPanelMembersColumnNames.UUID,
85         selected: true,
86         configurable: true,
87         filters: createTree(),
88         render: uuid => <ResourceLinkTailUuid uuid={uuid} />
89     },
90     {
91         name: GroupDetailsPanelMembersColumnNames.REMOVE,
92         selected: true,
93         configurable: true,
94         filters: createTree(),
95         render: uuid => <ResourceLinkDelete uuid={uuid} />
96     },
97 ];
98
99 export const groupDetailsPermissionsPanelColumns: DataColumns<string> = [
100     {
101         name: GroupDetailsPanelPermissionsColumnNames.NAME,
102         selected: true,
103         configurable: true,
104         filters: createTree(),
105         render: uuid => <ResourceLinkHead uuid={uuid} />
106     },
107     {
108         name: GroupDetailsPanelPermissionsColumnNames.PERMISSION,
109         selected: true,
110         configurable: true,
111         filters: createTree(),
112         render: uuid => <ResourceLinkHeadPermissionLevel uuid={uuid} />
113     },
114     {
115         name: GroupDetailsPanelPermissionsColumnNames.UUID,
116         selected: true,
117         configurable: true,
118         filters: createTree(),
119         render: uuid => <ResourceLinkHeadUuid uuid={uuid} />
120     },
121     {
122         name: GroupDetailsPanelPermissionsColumnNames.REMOVE,
123         selected: true,
124         configurable: true,
125         filters: createTree(),
126         render: uuid => <ResourceLinkDelete uuid={uuid} />
127     },
128 ];
129
130 const mapStateToProps = (state: RootState) => {
131     const groupUuid = getCurrentGroupDetailsPanelUuid(state.properties);
132     const group = getResource<GroupResource>(groupUuid || '')(state.resources);
133     const userUuid = getUserUuid(state);
134
135     return {
136         resources: state.resources,
137         groupCanManage: userUuid && !isBuiltinGroup(group?.uuid || '')
138                             ? group?.writableBy?.includes(userUuid)
139                             : false,
140     };
141 };
142
143 const mapDispatchToProps = {
144     onContextMenu: openContextMenu,
145     onAddUser: openAddGroupMembersDialog,
146 };
147
148 export interface GroupDetailsPanelProps {
149     onContextMenu: (event: React.MouseEvent<HTMLElement>, item: any) => void;
150     onAddUser: () => void;
151     resources: ResourcesState;
152     groupCanManage: boolean;
153 }
154
155 export const GroupDetailsPanel = connect(
156     mapStateToProps, mapDispatchToProps
157 )(
158     class GroupDetailsPanel extends React.Component<GroupDetailsPanelProps> {
159         state = {
160           value: 0,
161         };
162
163         componentDidMount() {
164             this.setState({ value: 0 });
165         }
166
167         render() {
168             const { value } = this.state;
169             return (
170                 <Paper>
171                   <Tabs value={value} onChange={this.handleChange} variant="fullWidth">
172                       <Tab data-cy="group-details-members-tab" label="MEMBERS" />
173                       <Tab data-cy="group-details-permissions-tab" label="PERMISSIONS" />
174                   </Tabs>
175                   {value === 0 &&
176                       <DataExplorer
177                           id={GROUP_DETAILS_MEMBERS_PANEL_ID}
178                           data-cy="group-members-data-explorer"
179                           onRowClick={noop}
180                           onRowDoubleClick={noop}
181                           onContextMenu={noop}
182                           contextMenuColumn={false}
183                           hideColumnSelector
184                           hideSearchInput
185                           actions={
186                                 this.props.groupCanManage &&
187                                 <Grid container justify='flex-end'>
188                                     <Button
189                                       data-cy="group-member-add"
190                                       variant="contained"
191                                       color="primary"
192                                       onClick={this.props.onAddUser}>
193                                       <AddIcon /> Add user
194                                     </Button>
195                                 </Grid>
196                           }
197                           paperProps={{
198                               elevation: 0,
199                           }} />
200                   }
201                   {value === 1 &&
202                       <DataExplorer
203                           id={GROUP_DETAILS_PERMISSIONS_PANEL_ID}
204                           data-cy="group-permissions-data-explorer"
205                           onRowClick={noop}
206                           onRowDoubleClick={noop}
207                           onContextMenu={noop}
208                           contextMenuColumn={false}
209                           hideColumnSelector
210                           hideSearchInput
211                           paperProps={{
212                               elevation: 0,
213                           }} />
214                   }
215                 </Paper>
216             );
217         }
218
219         handleChange = (event: React.MouseEvent<HTMLElement>, value: number) => {
220             this.setState({ value });
221         }
222     });