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