1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import { connect } from 'react-redux';
7 import { Grid, Button, Typography } from "@material-ui/core";
9 import { DataExplorer } from "~/views-components/data-explorer/data-explorer";
10 import { DataColumns } from '~/components/data-table/data-table';
11 import { SortDirection } from '~/components/data-table/data-column';
12 import { ResourceOwner } from '~/views-components/data-explorer/renderers';
13 import { AddIcon } from '~/components/icon/icon';
14 import { ResourceName } from '~/views-components/data-explorer/renderers';
15 import { createTree } from '~/models/tree';
16 import { GROUPS_PANEL_ID, openCreateGroupDialog } from '~/store/groups-panel/groups-panel-actions';
17 import { noop } from 'lodash/fp';
18 import { ContextMenuKind } from '~/views-components/context-menu/context-menu';
19 import { getResource, ResourcesState, filterResources } from '~/store/resources/resources';
20 import { GroupResource } from '~/models/group';
21 import { RootState } from '~/store/store';
22 import { Dispatch } from 'redux';
23 import { openContextMenu } from '~/store/context-menu/context-menu-actions';
24 import { ResourceKind } from '~/models/resource';
25 import { LinkClass, LinkResource } from '~/models/link';
26 import { navigateToGroupDetails } from '~/store/navigation/navigation-action';
28 export enum GroupsPanelColumnNames {
34 export const groupsPanelColumns: DataColumns<string> = [
36 name: GroupsPanelColumnNames.GROUP,
39 sortDirection: SortDirection.ASC,
40 filters: createTree(),
41 render: uuid => <ResourceName uuid={uuid} />
44 name: GroupsPanelColumnNames.OWNER,
47 filters: createTree(),
48 render: uuid => <ResourceOwner uuid={uuid} />,
51 name: GroupsPanelColumnNames.MEMBERS,
54 filters: createTree(),
55 render: uuid => <GroupMembersCount uuid={uuid} />,
59 const mapStateToProps = (state: RootState) => {
61 resources: state.resources
65 const mapDispatchToProps = {
66 onContextMenu: openContextMenu,
67 onRowDoubleClick: navigateToGroupDetails,
68 onNewGroup: openCreateGroupDialog,
71 export interface GroupsPanelProps {
72 onNewGroup: () => void;
73 onContextMenu: (event: React.MouseEvent<HTMLElement>, item: any) => void;
74 onRowDoubleClick: (item: string) => void;
75 resources: ResourcesState;
78 export const GroupsPanel = connect(
79 mapStateToProps, mapDispatchToProps
81 class GroupsPanel extends React.Component<GroupsPanelProps> {
88 onRowDoubleClick={this.props.onRowDoubleClick}
89 onContextMenu={this.handleContextMenu}
90 contextMenuColumn={true}
93 <Grid container justify='flex-end'>
97 onClick={this.props.onNewGroup}>
105 handleContextMenu = (event: React.MouseEvent<HTMLElement>, resourceUuid: string) => {
106 const resource = getResource<GroupResource>(resourceUuid)(this.props.resources);
108 this.props.onContextMenu(event, {
111 ownerUuid: resource.ownerUuid,
113 menuKind: ContextMenuKind.GROUPS
120 const GroupMembersCount = connect(
121 (state: RootState, props: { uuid: string }) => {
123 const permissions = filterResources((resource: LinkResource) =>
124 resource.kind === ResourceKind.LINK &&
125 resource.linkClass === LinkClass.PERMISSION &&
126 resource.headUuid === props.uuid
130 children: permissions.length,