import { userActionSet } from '~/views-components/context-menu/action-sets/user-action-set';
import { computeNodeActionSet } from '~/views-components/context-menu/action-sets/compute-node-action-set';
import { apiClientAuthorizationActionSet } from '~/views-components/context-menu/action-sets/api-client-authorization-action-set';
+import { groupActionSet } from '~/views-components/context-menu/action-sets/group-action-set';
+import { groupMemberActionSet } from '~/views-components/context-menu/action-sets/group-member-action-set';
+ import { linkActionSet } from '~/views-components/context-menu/action-sets/link-action-set';
console.log(`Starting arvados [${getBuildInfo()}]`);
addMenuActionSet(ContextMenuKind.VIRTUAL_MACHINE, virtualMachineActionSet);
addMenuActionSet(ContextMenuKind.KEEP_SERVICE, keepServiceActionSet);
addMenuActionSet(ContextMenuKind.USER, userActionSet);
+ addMenuActionSet(ContextMenuKind.LINK, linkActionSet);
addMenuActionSet(ContextMenuKind.NODE, computeNodeActionSet);
addMenuActionSet(ContextMenuKind.API_CLIENT_AUTHORIZATION, apiClientAuthorizationActionSet);
+addMenuActionSet(ContextMenuKind.GROUPS, groupActionSet);
+addMenuActionSet(ContextMenuKind.GROUP_MEMBER, groupMemberActionSet);
fetchConfig()
.then(({ config, apiHost }) => {
//
// SPDX-License-Identifier: AGPL-3.0
- import { Resource, ResourceKind } from "./resource";
-import { Resource } from "./resource";
import { TagProperty } from "~/models/tag";
-import { ResourceKind } from '~/models/resource';
++import { Resource, ResourceKind } from '~/models/resource';
export interface LinkResource extends Resource {
headUuid: string;
const apiClientAuthorizationsMatch = Routes.matchApiClientAuthorizationsRoute(pathname);
const myAccountMatch = Routes.matchMyAccountRoute(pathname);
const userMatch = Routes.matchUsersRoute(pathname);
+ const groupsMatch = Routes.matchGroupsRoute(pathname);
+ const groupDetailsMatch = Routes.matchGroupDetailsRoute(pathname);
+ const linksMatch = Routes.matchLinksRoute(pathname);
+
+ store.dispatch(dialogActions.CLOSE_ALL_DIALOGS());
if (projectMatch) {
store.dispatch(WorkbenchActions.loadProject(projectMatch.params.id));
store.dispatch(WorkbenchActions.loadApiClientAuthorizations);
} else if (myAccountMatch) {
store.dispatch(WorkbenchActions.loadMyAccount);
- }else if (userMatch) {
+ } else if (userMatch) {
store.dispatch(WorkbenchActions.loadUsers);
+ } else if (groupsMatch) {
+ store.dispatch(WorkbenchActions.loadGroupsPanel);
+ } else if (groupDetailsMatch) {
+ store.dispatch(WorkbenchActions.loadGroupDetailsPanel(groupDetailsMatch.params.id));
+ } else if (linksMatch) {
+ store.dispatch(WorkbenchActions.loadLinks);
}
};
COMPUTE_NODES: `/nodes`,
USERS: '/users',
API_CLIENT_AUTHORIZATIONS: `/api_client_authorizations`,
+ GROUPS: '/groups',
+ GROUP_DETAILS: `/group/:id(${RESOURCE_UUID_PATTERN})`,
+ LINKS: '/links'
};
export const getResourceUrl = (uuid: string) => {
export const matchApiClientAuthorizationsRoute = (route: string) =>
matchPath(route, { path: Routes.API_CLIENT_AUTHORIZATIONS });
- matchPath(route, { path: Routes.LINKS });
+export const matchGroupsRoute = (route: string) =>
+ matchPath(route, { path: Routes.GROUPS });
+
+export const matchGroupDetailsRoute = (route: string) =>
+ matchPath<ResourceRouteParams>(route, { path: Routes.GROUP_DETAILS });
++
+ export const matchLinksRoute = (route: string) =>
++ matchPath(route, { path: Routes.LINKS });
export const navigateToApiClientAuthorizations = push(Routes.API_CLIENT_AUTHORIZATIONS);
-export const navigateToLinks = push(Routes.LINKS);
+export const navigateToGroups = push(Routes.GROUPS);
+
+export const navigateToGroupDetails = compose(push, getGroupUrl);
++
++export const navigateToLinks = push(Routes.LINKS);
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';
+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 { LINK_PANEL_ID } from '~/store/link-panel/link-panel-actions';
+ import { LinkMiddlewareService } from '~/store/link-panel/link-panel-middleware-service';
const composeEnhancers =
(process.env.NODE_ENV === 'development' &&
const userPanelMiddleware = dataExplorerMiddleware(
new UserMiddlewareService(services, USERS_PANEL_ID)
);
+ const groupsPanelMiddleware = dataExplorerMiddleware(
+ new GroupsPanelMiddlewareService(services, GROUPS_PANEL_ID)
+ );
+ const groupDetailsPanelMiddleware = dataExplorerMiddleware(
+ new GroupDetailsPanelMiddlewareService(services, GROUP_DETAILS_PANEL_ID)
+ );
+
+ const linkPanelMiddleware = dataExplorerMiddleware(
+ new LinkMiddlewareService(services, LINK_PANEL_ID)
+ );
const middlewares: Middleware[] = [
routerMiddleware(history),
thunkMiddleware.withExtraArgument(services),
sharedWithMePanelMiddleware,
workflowPanelMiddleware,
userPanelMiddleware,
+ groupsPanelMiddleware,
+ groupDetailsPanelMiddleware,
+ linkPanelMiddleware
];
const enhancer = composeEnhancers(applyMiddleware(...middlewares));
return createStore(rootReducer, enhancer);
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(groupDetailsPanelActions.GroupDetailsPanelActions.SET_COLUMNS({columns: groupDetailsPanelColumns}));
+ dispatch(linkPanelActions.SET_COLUMNS({ columns: linkPanelColumns }));
dispatch<any>(initSidePanelTree());
if (router.location) {
const match = matchRootRoute(router.location.pathname);
VIRTUAL_MACHINE = "VirtualMachine",
KEEP_SERVICE = "KeepService",
USER = "User",
- GROUP_MEMBER = "GroupMember"
+ NODE = "Node",
+ GROUPS = "Group",
- NODE = "Node"
++ GROUP_MEMBER = "GroupMember",
+ LINK = "Link",
}
import { RootState } from "~/store/store";
import { openCurrentTokenDialog } from '~/store/current-token-dialog/current-token-dialog-actions';
import { openRepositoriesPanel } from "~/store/repositories/repositories-actions";
- import {
- navigateToSshKeys, navigateToKeepServices, navigateToComputeNodes,
- navigateToApiClientAuthorizations, navigateToMyAccount, navigateToGroups
++import {
++ navigateToKeepServices, navigateToComputeNodes,
++ navigateToApiClientAuthorizations, navigateToGroups
+} from '~/store/navigation/navigation-action';
- import { openVirtualMachines } from "~/store/virtual-machines/virtual-machines-actions";
+import { navigateToUsers } from '~/store/navigation/navigation-action';
+ import { navigateToSshKeysUser, navigateToMyAccount } from '~/store/navigation/navigation-action';
+ import { openUserVirtualMachines } from "~/store/virtual-machines/virtual-machines-actions";
interface AccountMenuProps {
user?: User;
<MenuItem>
{getUserFullname(user)}
</MenuItem>
- <MenuItem onClick={() => dispatch(openVirtualMachines())}>Virtual Machines</MenuItem>
- <MenuItem onClick={() => dispatch(openRepositoriesPanel())}>Repositories</MenuItem>
+ <MenuItem onClick={() => dispatch(openUserVirtualMachines())}>Virtual Machines</MenuItem>
+ {!user.isAdmin && <MenuItem onClick={() => dispatch(openRepositoriesPanel())}>Repositories</MenuItem>}
<MenuItem onClick={() => dispatch(openCurrentTokenDialog)}>Current token</MenuItem>
- <MenuItem onClick={() => dispatch(navigateToSshKeys)}>Ssh Keys</MenuItem>
+ <MenuItem onClick={() => dispatch(navigateToUsers)}>Users</MenuItem>
- { user.isAdmin && <MenuItem onClick={() => dispatch(navigateToGroups)}>Groups</MenuItem> }
- { user.isAdmin && <MenuItem onClick={() => dispatch(navigateToApiClientAuthorizations)}>Api Tokens</MenuItem> }
- { user.isAdmin && <MenuItem onClick={() => dispatch(navigateToKeepServices)}>Keep Services</MenuItem> }
- { user.isAdmin && <MenuItem onClick={() => dispatch(navigateToComputeNodes)}>Compute Nodes</MenuItem> }
++ {user.isAdmin && <MenuItem onClick={() => dispatch(navigateToGroups)}>Groups</MenuItem>}
++ {user.isAdmin && <MenuItem onClick={() => dispatch(navigateToApiClientAuthorizations)}>Api Tokens</MenuItem>}
++ {user.isAdmin && <MenuItem onClick={() => dispatch(navigateToKeepServices)}>Keep Services</MenuItem>}
++ {user.isAdmin && <MenuItem onClick={() => dispatch(navigateToComputeNodes)}>Compute Nodes</MenuItem>}
+ <MenuItem onClick={() => dispatch(navigateToSshKeysUser)}>Ssh Keys</MenuItem>
<MenuItem onClick={() => dispatch(navigateToMyAccount)}>My account</MenuItem>
<MenuItem onClick={() => dispatch(logout())}>Logout</MenuItem>
</DropdownMenu>
<Route path={Routes.COMPUTE_NODES} component={ComputeNodePanel} />
<Route path={Routes.API_CLIENT_AUTHORIZATIONS} component={ApiClientAuthorizationPanel} />
<Route path={Routes.MY_ACCOUNT} component={MyAccountPanel} />
+ <Route path={Routes.GROUPS} component={GroupsPanel} />
+ <Route path={Routes.GROUP_DETAILS} component={GroupDetailsPanel} />
+ <Route path={Routes.LINKS} component={LinkPanel} />
</Switch>
</Grid>
</Grid>
<ProjectPropertiesDialog />
<RemoveApiClientAuthorizationDialog />
<RemoveComputeNodeDialog />
+ <RemoveGroupDialog />
+ <RemoveGroupMemberDialog />
<RemoveKeepServiceDialog />
+ <RemoveLinkDialog />
<RemoveProcessDialog />
<RemoveRepositoryDialog />
<RemoveSshKeyDialog />