From 12531884583ab85a114eed12f5179ed0b5fb8a88 Mon Sep 17 00:00:00 2001 From: Michal Klobukowski Date: Mon, 10 Dec 2018 17:34:32 +0100 Subject: [PATCH] Initialize groups panel store and view component Feature #14505 Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski --- .../groups-panel/groups-panel-actions.ts | 10 +++ .../groups-panel-middleware-service.ts | 69 ++++++++++++++++ src/store/store.ts | 8 +- src/store/workbench/workbench-actions.ts | 4 + src/views/groups-panel/groups-panel.tsx | 79 +++++++++++++++++++ src/views/workbench/workbench.tsx | 3 +- 6 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 src/store/groups-panel/groups-panel-actions.ts create mode 100644 src/store/groups-panel/groups-panel-middleware-service.ts create mode 100644 src/views/groups-panel/groups-panel.tsx diff --git a/src/store/groups-panel/groups-panel-actions.ts b/src/store/groups-panel/groups-panel-actions.ts new file mode 100644 index 0000000000..5adce5c672 --- /dev/null +++ b/src/store/groups-panel/groups-panel-actions.ts @@ -0,0 +1,10 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import { bindDataExplorerActions } from "~/store/data-explorer/data-explorer-action"; + +export const GROUPS_PANEL_ID = "groupsPanel"; +export const GroupsPanelActions = bindDataExplorerActions(GROUPS_PANEL_ID); + +export const loadGroupsPanel = () => GroupsPanelActions.REQUEST_ITEMS(); diff --git a/src/store/groups-panel/groups-panel-middleware-service.ts b/src/store/groups-panel/groups-panel-middleware-service.ts new file mode 100644 index 0000000000..9d43b1165d --- /dev/null +++ b/src/store/groups-panel/groups-panel-middleware-service.ts @@ -0,0 +1,69 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import { Dispatch, MiddlewareAPI } from "redux"; +import { DataExplorerMiddlewareService, listResultsToDataExplorerItemsMeta, dataExplorerToListParams } 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 { GroupsPanelActions } from '~/store/groups-panel/groups-panel-actions'; +import { FilterBuilder } from '~/services/api/filter-builder'; +import { updateResources } from '~/store/resources/resources-actions'; + +export class GroupsPanelMiddlewareService extends DataExplorerMiddlewareService { + + constructor(private services: ServiceRepository, id: string) { + super(id); + } + + async requestItems(api: MiddlewareAPI) { + + const dataExplorer = getDataExplorer(api.getState().dataExplorer, this.getId()); + + if (!dataExplorer) { + + api.dispatch(groupsPanelDataExplorerIsNotSet()); + + } else { + + try { + + const filters = new FilterBuilder() + .addEqual('groupClass', null) + .getFilters(); + + const response = await this.services.groupsService + .list({ + ...dataExplorerToListParams(dataExplorer), + filters, + }); + + api.dispatch(updateResources(response.items)); + + api.dispatch(GroupsPanelActions.SET_ITEMS({ + ...listResultsToDataExplorerItemsMeta(response), + items: response.items.map(item => item.uuid), + })); + + + } catch (e) { + + api.dispatch(couldNotFetchFavoritesContents()); + + } + } + } +} + +const groupsPanelDataExplorerIsNotSet = () => + snackbarActions.OPEN_SNACKBAR({ + message: 'Groups panel is not ready.' + }); + +const couldNotFetchFavoritesContents = () => + snackbarActions.OPEN_SNACKBAR({ + message: 'Could not fetch groups.', + kind: SnackbarKind.ERROR + }); diff --git a/src/store/store.ts b/src/store/store.ts index 2b0ada81af..c04789d772 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -50,6 +50,8 @@ import { UserMiddlewareService } from '~/store/users/user-panel-middleware-servi import { USERS_PANEL_ID } from '~/store/users/users-actions'; import { computeNodesReducer } from '~/store/compute-nodes/compute-nodes-reducer'; import { apiClientAuthorizationsReducer } from '~/store/api-client-authorizations/api-client-authorizations-reducer'; +import { GroupsPanelMiddlewareService } from '~/store/groups-panel/groups-panel-middleware-service'; +import { GROUPS_PANEL_ID } from '~/store/groups-panel/groups-panel-actions'; const composeEnhancers = (process.env.NODE_ENV === 'development' && @@ -84,6 +86,9 @@ export function configureStore(history: History, services: ServiceRepository): R const userPanelMiddleware = dataExplorerMiddleware( new UserMiddlewareService(services, USERS_PANEL_ID) ); + const groupsPanelMiddleware = dataExplorerMiddleware( + new GroupsPanelMiddlewareService(services, GROUPS_PANEL_ID) + ); const middlewares: Middleware[] = [ routerMiddleware(history), @@ -94,7 +99,8 @@ export function configureStore(history: History, services: ServiceRepository): R searchResultsPanelMiddleware, sharedWithMePanelMiddleware, workflowPanelMiddleware, - userPanelMiddleware + userPanelMiddleware, + groupsPanelMiddleware, ]; const enhancer = composeEnhancers(applyMiddleware(...middlewares)); return createStore(rootReducer, enhancer); diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts index e0195f9409..2ae5902954 100644 --- a/src/store/workbench/workbench-actions.ts +++ b/src/store/workbench/workbench-actions.ts @@ -62,6 +62,8 @@ import { loadUsersPanel, userBindedActions } from '~/store/users/users-actions'; import { userPanelColumns } from '~/views/user-panel/user-panel'; import { loadComputeNodesPanel } from '~/store/compute-nodes/compute-nodes-actions'; import { loadApiClientAuthorizationsPanel } from '~/store/api-client-authorizations/api-client-authorizations-actions'; +import * as groupPanelActions from '~/store/groups-panel/groups-panel-actions'; +import { groupsPanelColumns } from '~/views/groups-panel/groups-panel'; export const WORKBENCH_LOADING_SCREEN = 'workbenchLoadingScreen'; @@ -96,6 +98,7 @@ export const loadWorkbench = () => dispatch(workflowPanelActions.SET_COLUMNS({ columns: workflowPanelColumns })); dispatch(searchResultsPanelActions.SET_COLUMNS({ columns: searchResultsPanelColumns })); dispatch(userBindedActions.SET_COLUMNS({ columns: userPanelColumns })); + dispatch(groupPanelActions.GroupsPanelActions.SET_COLUMNS({ columns: groupsPanelColumns })); dispatch(initSidePanelTree()); if (router.location) { const match = matchRootRoute(router.location.pathname); @@ -448,6 +451,7 @@ export const loadApiClientAuthorizations = handleFirstTimeLoad( export const loadGroupsPanel = handleFirstTimeLoad( (dispatch: Dispatch) => { dispatch(setBreadcrumbs([{ label: 'Groups' }])); + dispatch(groupPanelActions.loadGroupsPanel()); }); const finishLoadingProject = (project: GroupContentsResource | string) => diff --git a/src/views/groups-panel/groups-panel.tsx b/src/views/groups-panel/groups-panel.tsx new file mode 100644 index 0000000000..c404f1e4b2 --- /dev/null +++ b/src/views/groups-panel/groups-panel.tsx @@ -0,0 +1,79 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import * as React from 'react'; +import withStyles from "@material-ui/core/styles/withStyles"; +import { DispatchProp, connect } from 'react-redux'; +import { RouteComponentProps } from 'react-router'; +import { StyleRulesCallback, WithStyles, Typography } from "@material-ui/core"; + +import { DataExplorer } from "~/views-components/data-explorer/data-explorer"; +import { DataColumns } from '~/components/data-table/data-table'; +import { RootState } from '~/store/store'; +import { DataTableFilterItem } from '~/components/data-table-filters/data-table-filters'; +import { ContainerRequestState } from '~/models/container-request'; +import { SortDirection } from '~/components/data-table/data-column'; +import { ResourceKind, Resource } from '~/models/resource'; +import { ResourceFileSize, ResourceLastModifiedDate, ProcessStatus, ResourceType, ResourceOwner } from '~/views-components/data-explorer/renderers'; +import { ProjectIcon } from '~/components/icon/icon'; +import { ResourceName } from '~/views-components/data-explorer/renderers'; +import { ResourcesState, getResource } from '~/store/resources/resources'; +import { loadDetailsPanel } from '~/store/details-panel/details-panel-action'; +import { resourceKindToContextMenuKind, openContextMenu } from '~/store/context-menu/context-menu-actions'; +import { ProjectResource } from '~/models/project'; +import { navigateTo } from '~/store/navigation/navigation-action'; +import { getProperty } from '~/store/properties/properties'; +import { PROJECT_PANEL_CURRENT_UUID } from '~/store/project-panel/project-panel-action'; +import { DataTableDefaultView } from '~/components/data-table-default-view/data-table-default-view'; +import { ArvadosTheme } from "~/common/custom-theme"; +import { createTree } from '~/models/tree'; +import { getInitialResourceTypeFilters } from '~/store/resource-type-filters/resource-type-filters'; +import { GROUPS_PANEL_ID } from '~/store/groups-panel/groups-panel-actions'; +import { noop } from 'lodash/fp'; +import { GroupResource } from '~/models/group'; + +export enum ProjectPanelColumnNames { + GROUP = "Name", + OWNER = "Owner", + MEMBERS = "Members", +} + +export const groupsPanelColumns: DataColumns = [ + { + name: ProjectPanelColumnNames.GROUP, + selected: true, + configurable: true, + sortDirection: SortDirection.ASC, + filters: createTree(), + render: uuid => + }, + { + name: ProjectPanelColumnNames.OWNER, + selected: true, + configurable: true, + filters: createTree(), + render: uuid => , + }, + { + name: ProjectPanelColumnNames.MEMBERS, + selected: true, + configurable: true, + filters: createTree(), + render: uuid => 0, + }, +]; + +export class GroupsPanel extends React.Component { + + render() { + return ( + + ); + } +} diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx index f4124e26d3..468797eb62 100644 --- a/src/views/workbench/workbench.tsx +++ b/src/views/workbench/workbench.tsx @@ -75,6 +75,7 @@ import { UserPanel } from '~/views/user-panel/user-panel'; import { UserAttributesDialog } from '~/views-components/user-dialog/attributes-dialog'; import { CreateUserDialog } from '~/views-components/dialog-forms/create-user-dialog'; import { HelpApiClientAuthorizationDialog } from '~/views-components/api-client-authorizations-dialog/help-dialog'; +import { GroupsPanel } from '~/views/groups-panel/groups-panel'; type CssRules = 'root' | 'container' | 'splitter' | 'asidePanel' | 'contentWrapper' | 'content'; @@ -152,7 +153,7 @@ export const WorkbenchPanel = -

Groups panel

} /> + -- 2.30.2