import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
import { UserResource, getUserDisplayName } from 'models/user';
-export const GROUP_DETAILS_PANEL_ID = 'groupMembersPanel';
-export const GROUP_PERMISSIONS_PANEL_ID = 'groupPermissionsPanel';
+export const GROUP_DETAILS_MEMBERS_PANEL_ID = 'groupDetailsMembersPanel';
+export const GROUP_DETAILS_PERMISSIONS_PANEL_ID = 'groupDetailsPermissionsPanel';
export const ADD_GROUP_MEMBERS_DIALOG = 'addGrupMembers';
export const ADD_GROUP_MEMBERS_FORM = 'addGrupMembers';
export const ADD_GROUP_MEMBERS_USERS_FIELD_NAME = 'users';
export const MEMBER_ATTRIBUTES_DIALOG = 'memberAttributesDialog';
export const MEMBER_REMOVE_DIALOG = 'memberRemoveDialog';
-export const GroupMembersPanelActions = bindDataExplorerActions(GROUP_DETAILS_PANEL_ID);
-export const GroupPermissionsPanelActions = bindDataExplorerActions(GROUP_PERMISSIONS_PANEL_ID);
+export const GroupMembersPanelActions = bindDataExplorerActions(GROUP_DETAILS_MEMBERS_PANEL_ID);
+export const GroupPermissionsPanelActions = bindDataExplorerActions(GROUP_DETAILS_PERMISSIONS_PANEL_ID);
export const loadGroupDetailsPanel = (groupUuid: string) =>
(dispatch: Dispatch) => {
- dispatch(propertiesActions.SET_PROPERTY({ key: GROUP_DETAILS_PANEL_ID, value: groupUuid }));
+ dispatch(propertiesActions.SET_PROPERTY({ key: GROUP_DETAILS_MEMBERS_PANEL_ID, value: groupUuid }));
dispatch(GroupMembersPanelActions.REQUEST_ITEMS());
- dispatch(propertiesActions.SET_PROPERTY({ key: GROUP_PERMISSIONS_PANEL_ID, value: groupUuid }));
+ dispatch(propertiesActions.SET_PROPERTY({ key: GROUP_DETAILS_PERMISSIONS_PANEL_ID, value: groupUuid }));
dispatch(GroupPermissionsPanelActions.REQUEST_ITEMS());
};
-export const getCurrentGroupDetailsPanelUuid = getProperty<string>(GROUP_DETAILS_PANEL_ID);
+export const getCurrentGroupDetailsPanelUuid = getProperty<string>(GROUP_DETAILS_MEMBERS_PANEL_ID);
export interface AddGroupMembersFormData {
[ADD_GROUP_MEMBERS_USERS_FIELD_NAME]: Participant[];
import { getDataExplorer } from "store/data-explorer/data-explorer-reducer";
import { FilterBuilder } from 'services/api/filter-builder';
import { updateResources } from 'store/resources/resources-actions';
-import { getCurrentGroupDetailsPanelUuid, GroupMembersPanelActions, GroupPermissionsPanelActions } from 'store/group-details-panel/group-details-panel-actions';
+import { getCurrentGroupDetailsPanelUuid, GroupMembersPanelActions } from 'store/group-details-panel/group-details-panel-actions';
import { LinkClass } from 'models/link';
-export class GroupDetailsPanelMiddlewareService extends DataExplorerMiddlewareService {
+export class GroupDetailsPanelMembersMiddlewareService extends DataExplorerMiddlewareService {
constructor(private services: ServiceRepository, id: string) {
super(id);
api.dispatch(groupsDetailsPanelDataExplorerIsNotSet());
} else {
try {
- const permissionsIn = await this.services.permissionService.list({
+ const permissions = await this.services.permissionService.list({
filters: new FilterBuilder()
.addEqual('head_uuid', groupUuid)
.addEqual('link_class', LinkClass.PERMISSION)
.getFilters()
});
- api.dispatch(updateResources(permissionsIn.items));
- const permissionsOut = await this.services.permissionService.list({
- filters: new FilterBuilder()
- .addEqual('tail_uuid', groupUuid)
- .addEqual('link_class', LinkClass.PERMISSION)
- .getFilters()
- });
- api.dispatch(updateResources(permissionsOut.items));
+ api.dispatch(updateResources(permissions.items));
+
const users = await this.services.userService.list({
filters: new FilterBuilder()
- .addIn('uuid', permissionsIn.items.map(item => item.tailUuid))
- .getFilters(),
- count: "none"
- });
- const usersOut = await this.services.userService.list({
- filters: new FilterBuilder()
- .addIn('uuid', permissionsOut.items.map(item => item.tailUuid))
+ .addIn('uuid', permissions.items.map(item => item.tailUuid))
.getFilters(),
count: "none"
});
+ api.dispatch(updateResources(users.items));
+
api.dispatch(GroupMembersPanelActions.SET_ITEMS({
- ...listResultsToDataExplorerItemsMeta(permissionsIn),
+ ...listResultsToDataExplorerItemsMeta(permissions),
items: users.items.map(item => item.uuid),
}));
- api.dispatch(GroupPermissionsPanelActions.SET_ITEMS({
- ...listResultsToDataExplorerItemsMeta(permissionsOut),
- items: usersOut.items.map(item => item.uuid),
- }));
- api.dispatch(updateResources(users.items));
} catch (e) {
api.dispatch(couldNotFetchGroupDetailsContents());
}
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Dispatch, MiddlewareAPI } from "redux";
+import { DataExplorerMiddlewareService, listResultsToDataExplorerItemsMeta } from "store/data-explorer/data-explorer-middleware-service";
+import { RootState } from "store/store";
+import { ServiceRepository } from "services/services";
+import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
+import { getDataExplorer } from "store/data-explorer/data-explorer-reducer";
+import { FilterBuilder } from 'services/api/filter-builder';
+import { updateResources } from 'store/resources/resources-actions';
+import { getCurrentGroupDetailsPanelUuid, GroupPermissionsPanelActions } from 'store/group-details-panel/group-details-panel-actions';
+import { LinkClass } from 'models/link';
+
+export class GroupDetailsPanelPermissionsMiddlewareService extends DataExplorerMiddlewareService {
+
+ constructor(private services: ServiceRepository, id: string) {
+ super(id);
+ }
+
+ async requestItems(api: MiddlewareAPI<Dispatch, RootState>) {
+ const dataExplorer = getDataExplorer(api.getState().dataExplorer, this.getId());
+ const groupUuid = getCurrentGroupDetailsPanelUuid(api.getState().properties);
+ if (!dataExplorer || !groupUuid) {
+ api.dispatch(groupsDetailsPanelDataExplorerIsNotSet());
+ } else {
+ try {
+ const permissions = await this.services.permissionService.list({
+ filters: new FilterBuilder()
+ .addEqual('tail_uuid', groupUuid)
+ .addEqual('link_class', LinkClass.PERMISSION)
+ .getFilters()
+ });
+ api.dispatch(updateResources(permissions.items));
+
+ const users = await this.services.userService.list({
+ filters: new FilterBuilder()
+ .addIn('uuid', permissions.items.map(item => item.headUuid))
+ .getFilters(),
+ count: "none"
+ });
+ api.dispatch(updateResources(users.items));
+
+ const collections = await this.services.collectionService.list({
+ filters: new FilterBuilder()
+ .addIn('uuid', permissions.items.map(item => item.headUuid))
+ .getFilters(),
+ count: "none"
+ });
+ api.dispatch(updateResources(collections.items));
+
+ const projects = await this.services.projectService.list({
+ filters: new FilterBuilder()
+ .addIn('uuid', permissions.items.map(item => item.headUuid))
+ .getFilters(),
+ count: "none"
+ });
+ api.dispatch(updateResources(projects.items));
+
+ api.dispatch(GroupPermissionsPanelActions.SET_ITEMS({
+ ...listResultsToDataExplorerItemsMeta(permissions),
+ items: permissions.items.map(item => item.uuid),
+ }));
+ } catch (e) {
+ api.dispatch(couldNotFetchGroupDetailsContents());
+ }
+ }
+ }
+}
+
+const groupsDetailsPanelDataExplorerIsNotSet = () =>
+ snackbarActions.OPEN_SNACKBAR({
+ message: 'Group permissions panel is not ready.',
+ kind: SnackbarKind.ERROR
+ });
+
+const couldNotFetchGroupDetailsContents = () =>
+ snackbarActions.OPEN_SNACKBAR({
+ message: 'Could not fetch group permissions.',
+ kind: SnackbarKind.ERROR
+ });
import { USERS_PANEL_ID } from 'store/users/users-actions';
import { GroupsPanelMiddlewareService } from 'store/groups-panel/groups-panel-middleware-service';
import { GROUPS_PANEL_ID } from 'store/groups-panel/groups-panel-actions';
-import { GroupDetailsPanelMiddlewareService } from 'store/group-details-panel/group-details-panel-middleware-service';
-import { GROUP_DETAILS_PANEL_ID } from 'store/group-details-panel/group-details-panel-actions';
+import { GroupDetailsPanelMembersMiddlewareService } from 'store/group-details-panel/group-details-panel-members-middleware-service';
+import { GroupDetailsPanelPermissionsMiddlewareService } from 'store/group-details-panel/group-details-panel-permissions-middleware-service';
+import { GROUP_DETAILS_MEMBERS_PANEL_ID, GROUP_DETAILS_PERMISSIONS_PANEL_ID } from 'store/group-details-panel/group-details-panel-actions';
import { LINK_PANEL_ID } from 'store/link-panel/link-panel-actions';
import { LinkMiddlewareService } from 'store/link-panel/link-panel-middleware-service';
import { API_CLIENT_AUTHORIZATION_PANEL_ID } from 'store/api-client-authorizations/api-client-authorizations-actions';
const groupsPanelMiddleware = dataExplorerMiddleware(
new GroupsPanelMiddlewareService(services, GROUPS_PANEL_ID)
);
- const groupDetailsPanelMiddleware = dataExplorerMiddleware(
- new GroupDetailsPanelMiddlewareService(services, GROUP_DETAILS_PANEL_ID)
+ const groupDetailsPanelMembersMiddleware = dataExplorerMiddleware(
+ new GroupDetailsPanelMembersMiddlewareService(services, GROUP_DETAILS_MEMBERS_PANEL_ID)
+ );
+ const groupDetailsPanelPermissionsMiddleware = dataExplorerMiddleware(
+ new GroupDetailsPanelPermissionsMiddlewareService(services, GROUP_DETAILS_PERMISSIONS_PANEL_ID)
);
const linkPanelMiddleware = dataExplorerMiddleware(
new LinkMiddlewareService(services, LINK_PANEL_ID)
workflowPanelMiddleware,
userPanelMiddleware,
groupsPanelMiddleware,
- groupDetailsPanelMiddleware,
+ groupDetailsPanelMembersMiddleware,
+ groupDetailsPanelPermissionsMiddleware,
linkPanelMiddleware,
apiClientAuthorizationMiddlewareService,
publicFavoritesMiddleware,
import * as groupPanelActions from 'store/groups-panel/groups-panel-actions';
import { groupsPanelColumns } from 'views/groups-panel/groups-panel';
import * as groupDetailsPanelActions from 'store/group-details-panel/group-details-panel-actions';
-import { groupDetailsPanelColumns } from 'views/group-details-panel/group-details-panel';
+import { groupDetailsMembersPanelColumns, groupDetailsPermissionsPanelColumns } from 'views/group-details-panel/group-details-panel';
import { DataTableFetchMode } from "components/data-table/data-table";
import { loadPublicFavoritePanel, publicFavoritePanelActions } from 'store/public-favorites-panel/public-favorites-action';
import { publicFavoritePanelColumns } from 'views/public-favorites-panel/public-favorites-panel';
dispatch(searchResultsPanelActions.SET_COLUMNS({ columns: searchResultsPanelColumns }));
dispatch(userBindedActions.SET_COLUMNS({ columns: userPanelColumns }));
dispatch(groupPanelActions.GroupsPanelActions.SET_COLUMNS({ columns: groupsPanelColumns }));
- dispatch(groupDetailsPanelActions.GroupMembersPanelActions.SET_COLUMNS({ columns: groupDetailsPanelColumns }));
- dispatch(groupDetailsPanelActions.GroupPermissionsPanelActions.SET_COLUMNS({ columns: groupDetailsPanelColumns }));
+ dispatch(groupDetailsPanelActions.GroupMembersPanelActions.SET_COLUMNS({ columns: groupDetailsMembersPanelColumns }));
+ dispatch(groupDetailsPanelActions.GroupPermissionsPanelActions.SET_COLUMNS({ columns: groupDetailsPermissionsPanelColumns }));
dispatch(linkPanelActions.SET_COLUMNS({ columns: linkPanelColumns }));
dispatch(apiClientAuthorizationsActions.SET_COLUMNS({ columns: apiClientAuthorizationPanelColumns }));
dispatch(collectionsContentAddressActions.SET_COLUMNS({ columns: collectionContentAddressPanelColumns }));
import { ResourceStatus as WorkflowStatus } from 'views/workflow-panel/workflow-panel-view';
import { getUuidPrefix, openRunProcess } from 'store/workflow-panel/workflow-panel-actions';
import { openSharingDialog } from 'store/sharing-dialog/sharing-dialog-actions';
-import { getUserFullname, User, UserResource } from 'models/user';
+import { getUserFullname, getUserDisplayName, User, UserResource } from 'models/user';
import { toggleIsActive, toggleIsAdmin } from 'store/users/users-actions';
import { LinkResource } from 'models/link';
import { navigateTo } from 'store/navigation/navigation-action';
return resource || { linkClass: '' };
})(renderLinkClass);
-const renderLinkTail = (dispatch: Dispatch, item: { uuid: string, tailUuid: string, tailKind: string }) => {
- const currentLabel = resourceLabel(item.tailKind);
- const isUnknow = currentLabel === "Unknown";
- return (<div>
- {!isUnknow ? (
- renderLink(dispatch, item.tailUuid, currentLabel)
- ) : (
- <Typography noWrap color="default">
- {item.tailUuid}
- </Typography>
- )}
- </div>);
-};
-
-const renderLink = (dispatch: Dispatch, uuid: string, label: string) =>
- <Typography noWrap color="primary" style={{ 'cursor': 'pointer' }} onClick={() => dispatch<any>(navigateTo(uuid))}>
- {label}: {uuid}
+// const renderLinkTail = (dispatch: Dispatch, item: { uuid: string, tailUuid: string, tailKind: string }) => {
+// const currentLabel = resourceLabel(item.tailKind);
+// const isUnknow = currentLabel === "Unknown";
+// return (<div>
+// {!isUnknow ? (
+// renderLink(dispatch, item.tailUuid, "name", currentLabel)
+// ) : (
+// <Typography noWrap color="default">
+// {item.tailUuid}
+// </Typography>
+// )}
+// </div>);
+// };
+
+const renderLink = (dispatch: Dispatch, item: Resource) => {
+ const name = (item as LinkResource).name;
+ const fullName = getUserDisplayName(item as UserResource);
+
+ return <Typography noWrap color="primary" style={{ 'cursor': 'pointer' }} onClick={() => dispatch<any>(navigateTo(item.uuid))}>
+ {resourceLabel(item.kind)}: {name || fullName || item.uuid}
</Typography>;
+}
export const ResourceLinkTail = connect(
(state: RootState, props: { uuid: string }) => {
const resource = getResource<LinkResource>(props.uuid)(state.resources);
+ const tailResource = getResource<Resource>(resource?.tailUuid || '')(state.resources);
+
return {
- item: resource || { uuid: '', tailUuid: '', tailKind: ResourceKind.NONE }
+ item: tailResource || { uuid: resource?.tailUuid || '', kind: resource?.headKind || ResourceKind.NONE }
};
- })((props: { item: any } & DispatchProp<any>) =>
- renderLinkTail(props.dispatch, props.item));
-
-const renderLinkHead = (dispatch: Dispatch, item: { uuid: string, headUuid: string, headKind: ResourceKind }) =>
- renderLink(dispatch, item.headUuid, resourceLabel(item.headKind));
+ })((props: { item: Resource } & DispatchProp<any>) =>
+ renderLink(props.dispatch, props.item));
export const ResourceLinkHead = connect(
(state: RootState, props: { uuid: string }) => {
const resource = getResource<LinkResource>(props.uuid)(state.resources);
+ const headResource = getResource<Resource>(resource?.headUuid || '')(state.resources);
+
return {
- item: resource || { uuid: '', headUuid: '', headKind: ResourceKind.NONE }
+ item: headResource || { uuid: resource?.headUuid || '', kind: resource?.headKind || ResourceKind.NONE }
};
- })((props: { item: any } & DispatchProp<any>) =>
- renderLinkHead(props.dispatch, props.item));
+ })((props: { item: Resource } & DispatchProp<any>) =>
+ renderLink(props.dispatch, props.item));
export const ResourceLinkUuid = connect(
(state: RootState, props: { uuid: string }) => {
import { DataExplorer } from "views-components/data-explorer/data-explorer";
import { DataColumns } from 'components/data-table/data-table';
-import { ResourceFullName, ResourceUuid, ResourceEmail, ResourceUsername } from 'views-components/data-explorer/renderers';
+import { ResourceFullName, ResourceUuid, ResourceEmail, ResourceUsername, ResourceLinkName, ResourceLinkHead, ResourceName } from 'views-components/data-explorer/renderers';
import { createTree } from 'models/tree';
import { noop } from 'lodash/fp';
import { RootState } from 'store/store';
-import { GROUP_DETAILS_PANEL_ID, GROUP_PERMISSIONS_PANEL_ID, openAddGroupMembersDialog } from 'store/group-details-panel/group-details-panel-actions';
+import { GROUP_DETAILS_MEMBERS_PANEL_ID, GROUP_DETAILS_PERMISSIONS_PANEL_ID, openAddGroupMembersDialog } from 'store/group-details-panel/group-details-panel-actions';
import { openContextMenu } from 'store/context-menu/context-menu-actions';
import { ResourcesState, getResource } from 'store/resources/resources';
import { ContextMenuKind } from 'views-components/context-menu/context-menu';
import { Grid, Button, Tabs, Tab, Paper } from '@material-ui/core';
import { AddIcon } from 'components/icon/icon';
-export enum GroupDetailsPanelColumnNames {
+export enum GroupDetailsPanelMembersColumnNames {
FULL_NAME = "Name",
UUID = "UUID",
EMAIL = "Email",
USERNAME = "Username",
}
-export const groupDetailsPanelColumns: DataColumns<string> = [
+export enum GroupDetailsPanelPermissionsColumnNames {
+ HEAD = "Head",
+ NAME = "Name",
+ UUID = "UUID",
+}
+
+export const groupDetailsMembersPanelColumns: DataColumns<string> = [
{
- name: GroupDetailsPanelColumnNames.FULL_NAME,
+ name: GroupDetailsPanelMembersColumnNames.FULL_NAME,
selected: true,
configurable: true,
filters: createTree(),
render: uuid => <ResourceFullName uuid={uuid} />
},
{
- name: GroupDetailsPanelColumnNames.USERNAME,
+ name: GroupDetailsPanelMembersColumnNames.USERNAME,
selected: true,
configurable: true,
filters: createTree(),
render: uuid => <ResourceUsername uuid={uuid} />
},
{
- name: GroupDetailsPanelColumnNames.UUID,
+ name: GroupDetailsPanelMembersColumnNames.UUID,
selected: true,
configurable: true,
filters: createTree(),
render: uuid => <ResourceUuid uuid={uuid} />
},
{
- name: GroupDetailsPanelColumnNames.EMAIL,
+ name: GroupDetailsPanelMembersColumnNames.EMAIL,
selected: true,
configurable: true,
filters: createTree(),
},
];
+export const groupDetailsPermissionsPanelColumns: DataColumns<string> = [
+ {
+ name: GroupDetailsPanelPermissionsColumnNames.HEAD,
+ selected: true,
+ configurable: true,
+ filters: createTree(),
+ render: uuid => <ResourceLinkHead uuid={uuid} />
+ },
+ {
+ name: GroupDetailsPanelPermissionsColumnNames.NAME,
+ selected: true,
+ configurable: true,
+ filters: createTree(),
+ render: uuid => <ResourceLinkName uuid={uuid} />
+ },
+ {
+ name: GroupDetailsPanelPermissionsColumnNames.UUID,
+ selected: true,
+ configurable: true,
+ filters: createTree(),
+ render: uuid => <ResourceUuid uuid={uuid} />
+ },
+];
+
const mapStateToProps = (state: RootState) => {
return {
resources: state.resources
const { value } = this.state;
return (
<Paper>
- <Tabs value={value} onChange={this.handleChange} fullWidth>
+ <Tabs value={value} onChange={this.handleChange} variant="fullWidth">
<Tab label="MEMBERS" />
<Tab label="PERMISSIONS" />
</Tabs>
{value === 0 &&
<DataExplorer
- id={GROUP_DETAILS_PANEL_ID}
+ id={GROUP_DETAILS_MEMBERS_PANEL_ID}
onRowClick={noop}
onRowDoubleClick={noop}
onContextMenu={this.handleContextMenu}
}
{value === 1 &&
<DataExplorer
- id={GROUP_PERMISSIONS_PANEL_ID}
+ id={GROUP_DETAILS_PERMISSIONS_PANEL_ID}
onRowClick={noop}
onRowDoubleClick={noop}
onContextMenu={this.handleContextMenu}