[ARVADOS-WORKBENCH2] updated: 1.3.0-18-gfc3370a

Git user git at public.curoverse.com
Wed Dec 5 05:46:51 EST 2018


Summary of changes:
 src/components/data-explorer/data-explorer.tsx     | 10 ++--
 src/index.tsx                                      | 42 ++++++++--------
 src/store/advanced-tab/advanced-tab.ts             | 57 ++++++++++++++++++++--
 src/store/users/users-actions.ts                   |  6 ++-
 ...al-machine-action-set.ts => user-action-set.ts} | 23 ++++++---
 src/views-components/context-menu/context-menu.tsx |  3 +-
 .../attributes-dialog.tsx                          | 34 ++++++++-----
 src/views/user-panel/user-panel.tsx                |  3 +-
 src/views/workbench/workbench.tsx                  |  2 +
 9 files changed, 126 insertions(+), 54 deletions(-)
 copy src/views-components/context-menu/action-sets/{virtual-machine-action-set.ts => user-action-set.ts} (53%)
 copy src/views-components/{virtual-machines-dialog => user-dialog}/attributes-dialog.tsx (70%)

       via  fc3370a1203ae0b83a13ef6a958219cc722cfe75 (commit)
      from  dc95b803fa84b3c9ef7c11a4f81dd0d86077d779 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit fc3370a1203ae0b83a13ef6a958219cc722cfe75
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date:   Wed Dec 5 11:46:34 2018 +0100

    context-menu-for-user-data-explorer
    
    Feature #14504
    
    Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>

diff --git a/src/components/data-explorer/data-explorer.tsx b/src/components/data-explorer/data-explorer.tsx
index 3b09b5b..69f93dd 100644
--- a/src/components/data-explorer/data-explorer.tsx
+++ b/src/components/data-explorer/data-explorer.tsx
@@ -4,13 +4,13 @@
 
 import * as React from 'react';
 import { Grid, Paper, Toolbar, StyleRulesCallback, withStyles, WithStyles, TablePagination, IconButton, Tooltip } from '@material-ui/core';
-import { ColumnSelector } from "../column-selector/column-selector";
-import { DataTable, DataColumns } from "../data-table/data-table";
-import { DataColumn, SortDirection } from "../data-table/data-column";
-import { SearchInput } from '../search-input/search-input';
+import { ColumnSelector } from "~/components/column-selector/column-selector";
+import { DataTable, DataColumns } from "~/components/data-table/data-table";
+import { DataColumn, SortDirection } from "~/components/data-table/data-column";
+import { SearchInput } from '~/components/search-input/search-input';
 import { ArvadosTheme } from "~/common/custom-theme";
 import { createTree } from '~/models/tree';
-import { DataTableFilters } from '../data-table-filters/data-table-filters-tree';
+import { DataTableFilters } from '~/components/data-table-filters/data-table-filters-tree';
 import { MoreOptionsIcon } from '~/components/icon/icon';
 
 type CssRules = 'searchBox' | "toolbar" | "footer" | "root" | 'moreOptionsButton';
diff --git a/src/index.tsx b/src/index.tsx
index d838596..96df16c 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -5,31 +5,31 @@
 import * as React from 'react';
 import * as ReactDOM from 'react-dom';
 import { Provider } from "react-redux";
-import { MainPanel } from './views/main-panel/main-panel';
-import './index.css';
+import { MainPanel } from '~/views/main-panel/main-panel';
+import '~/index.css';
 import { Route, Switch } from 'react-router';
 import createBrowserHistory from "history/createBrowserHistory";
 import { History } from "history";
-import { configureStore, RootStore } from './store/store';
+import { configureStore, RootStore } from '~/store/store';
 import { ConnectedRouter } from "react-router-redux";
-import { ApiToken } from "./views-components/api-token/api-token";
-import { initAuth } from "./store/auth/auth-action";
-import { createServices } from "./services/services";
+import { ApiToken } from "~/views-components/api-token/api-token";
+import { initAuth } from "~/store/auth/auth-action";
+import { createServices } from "~/services/services";
 import { MuiThemeProvider } from '@material-ui/core/styles';
-import { CustomTheme } from './common/custom-theme';
-import { fetchConfig } from './common/config';
-import { addMenuActionSet, ContextMenuKind } from './views-components/context-menu/context-menu';
-import { rootProjectActionSet } from "./views-components/context-menu/action-sets/root-project-action-set";
-import { projectActionSet } from "./views-components/context-menu/action-sets/project-action-set";
-import { resourceActionSet } from './views-components/context-menu/action-sets/resource-action-set';
-import { favoriteActionSet } from "./views-components/context-menu/action-sets/favorite-action-set";
-import { collectionFilesActionSet } from './views-components/context-menu/action-sets/collection-files-action-set';
-import { collectionFilesItemActionSet } from './views-components/context-menu/action-sets/collection-files-item-action-set';
-import { collectionFilesNotSelectedActionSet } from './views-components/context-menu/action-sets/collection-files-not-selected-action-set';
-import { collectionActionSet } from './views-components/context-menu/action-sets/collection-action-set';
-import { collectionResourceActionSet } from './views-components/context-menu/action-sets/collection-resource-action-set';
-import { processActionSet } from './views-components/context-menu/action-sets/process-action-set';
-import { loadWorkbench } from './store/workbench/workbench-actions';
+import { CustomTheme } from '~/common/custom-theme';
+import { fetchConfig } from '~/common/config';
+import { addMenuActionSet, ContextMenuKind } from '~/views-components/context-menu/context-menu';
+import { rootProjectActionSet } from "~/views-components/context-menu/action-sets/root-project-action-set";
+import { projectActionSet } from "~/views-components/context-menu/action-sets/project-action-set";
+import { resourceActionSet } from '~/views-components/context-menu/action-sets/resource-action-set';
+import { favoriteActionSet } from "~/views-components/context-menu/action-sets/favorite-action-set";
+import { collectionFilesActionSet } from '~/views-components/context-menu/action-sets/collection-files-action-set';
+import { collectionFilesItemActionSet } from '~/views-components/context-menu/action-sets/collection-files-item-action-set';
+import { collectionFilesNotSelectedActionSet } from '~/views-components/context-menu/action-sets/collection-files-not-selected-action-set';
+import { collectionActionSet } from '~/views-components/context-menu/action-sets/collection-action-set';
+import { collectionResourceActionSet } from '~/views-components/context-menu/action-sets/collection-resource-action-set';
+import { processActionSet } from '~/views-components/context-menu/action-sets/process-action-set';
+import { loadWorkbench } from '~/store/workbench/workbench-actions';
 import { Routes } from '~/routes/routes';
 import { trashActionSet } from "~/views-components/context-menu/action-sets/trash-action-set";
 import { ServiceRepository } from '~/services/services';
@@ -53,6 +53,7 @@ import { sshKeyActionSet } from '~/views-components/context-menu/action-sets/ssh
 import { keepServiceActionSet } from '~/views-components/context-menu/action-sets/keep-service-action-set';
 import { loadVocabulary } from '~/store/vocabulary/vocabulary-actions';
 import { virtualMachineActionSet } from '~/views-components/context-menu/action-sets/virtual-machine-action-set';
+import { userActionSet } from '~/views-components/context-menu/action-sets/user-action-set';
 
 console.log(`Starting arvados [${getBuildInfo()}]`);
 
@@ -73,6 +74,7 @@ addMenuActionSet(ContextMenuKind.REPOSITORY, repositoryActionSet);
 addMenuActionSet(ContextMenuKind.SSH_KEY, sshKeyActionSet);
 addMenuActionSet(ContextMenuKind.VIRTUAL_MACHINE, virtualMachineActionSet);
 addMenuActionSet(ContextMenuKind.KEEP_SERVICE, keepServiceActionSet);
+addMenuActionSet(ContextMenuKind.USER, userActionSet);
 
 fetchConfig()
     .then(({ config, apiHost }) => {
diff --git a/src/store/advanced-tab/advanced-tab.ts b/src/store/advanced-tab/advanced-tab.ts
index 92d14d7..67d1394 100644
--- a/src/store/advanced-tab/advanced-tab.ts
+++ b/src/store/advanced-tab/advanced-tab.ts
@@ -72,7 +72,8 @@ enum ResourcePrefix {
     REPOSITORIES = 'repositories',
     AUTORIZED_KEYS = 'authorized_keys',
     VIRTUAL_MACHINES = 'virtual_machines',
-    KEEP_SERVICES = 'keep_services'
+    KEEP_SERVICES = 'keep_services',
+    USERS = 'users'
 }
 
 enum KeepServiceData {
@@ -80,9 +81,14 @@ enum KeepServiceData {
     CREATED_AT = 'created_at'
 }
 
-type AdvanceResourceKind = CollectionData | ProcessData | ProjectData | RepositoryData | SshKeyData | VirtualMachineData | KeepServiceData;
+enum UserData {
+    USER = 'user',
+    USERNAME = 'username'
+}
+
+type AdvanceResourceKind = CollectionData | ProcessData | ProjectData | RepositoryData | SshKeyData | VirtualMachineData | KeepServiceData | UserData;
 type AdvanceResourcePrefix = GroupContentsResourcePrefix | ResourcePrefix;
-type AdvanceResponseData = ContainerRequestResource | ProjectResource | CollectionResource | RepositoryResource | SshKeyResource | VirtualMachinesResource | KeepServiceResource | undefined;
+type AdvanceResponseData = ContainerRequestResource | ProjectResource | CollectionResource | RepositoryResource | SshKeyResource | VirtualMachinesResource | KeepServiceResource | UserResource | undefined;
 
 export const openAdvancedTabDialog = (uuid: string) =>
     async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
@@ -193,6 +199,27 @@ export const openAdvancedTabDialog = (uuid: string) =>
                 });
                 dispatch<any>(initAdvancedTabDialog(advanceDataKeepService));
                 break;
+            case ResourceKind.USER:
+                const { resources } = getState();
+                const data = getResource<UserResource>(uuid)(resources);
+                const metadata = await services.linkService.list({
+                    filters: new FilterBuilder()
+                        .addEqual('headUuid', uuid)
+                        .getFilters()
+                });
+                const advanceDataUser = advancedTabData({
+                    uuid,
+                    metadata,
+                    user: '',
+                    apiResponseKind: userApiResponse,
+                    data,
+                    resourceKind: UserData.USER,
+                    resourcePrefix: ResourcePrefix.USERS,
+                    resourceKindProperty: UserData.USERNAME,
+                    property: data!.username
+                });
+                dispatch<any>(initAdvancedTabDialog(advanceDataUser));
+                break;
             default:
                 dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Could not open advanced tab for this resource.", hideDuration: 2000, kind: SnackbarKind.ERROR }));
         }
@@ -441,4 +468,28 @@ const keepServiceApiResponse = (apiResponse: KeepServiceResource) => {
 "read_only": "${stringify(readOnly)}"`;
 
     return response;
+};
+
+const userApiResponse = (apiResponse: UserResource) => {
+    const {
+        uuid, ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid,
+        email, firstName, lastName, identityUrl, isActive, isAdmin, prefs, defaultOwnerUuid, username
+    } = apiResponse;
+    const response = `"uuid": "${uuid}",
+"owner_uuid": "${ownerUuid}",
+"created_at": "${createdAt}",
+"modified_by_client_uuid": ${stringify(modifiedByClientUuid)},
+"modified_by_user_uuid": ${stringify(modifiedByUserUuid)},
+"modified_at": ${stringify(modifiedAt)},
+"email": "${email}",
+"first_name": "${firstName}",
+"last_name": "${stringify(lastName)}",
+"identity_url": "${identityUrl}",
+"is_active": "${isActive},
+"is_admin": "${isAdmin},
+"prefs": "${stringifyObject(prefs)},
+"default_owner_uuid": "${defaultOwnerUuid},
+"username": "${username}"`;
+
+    return response;
 };
\ No newline at end of file
diff --git a/src/store/users/users-actions.ts b/src/store/users/users-actions.ts
index 8ec373a..43d9e6f 100644
--- a/src/store/users/users-actions.ts
+++ b/src/store/users/users-actions.ts
@@ -13,6 +13,7 @@ import { startSubmit, reset, stopSubmit } from "redux-form";
 import { getCommonResourceServiceError, CommonResourceServiceError } from "~/services/common-service/common-resource-service";
 import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
 import { UserResource } from "~/models/user";
+import { getResource } from '~/store/resources/resources';
 
 export const usersPanelActions = unionize({
     SET_USERS: ofType<any>(),
@@ -27,8 +28,9 @@ export const USER_REMOVE_DIALOG = 'repositoryRemoveDialog';
 
 export const openUserAttributes = (uuid: string) =>
     (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const repositoryData = getState().repositories.items.find(it => it.uuid === uuid);
-        dispatch(dialogActions.OPEN_DIALOG({ id: USER_ATTRIBUTES_DIALOG, data: { repositoryData } }));
+        const { resources } = getState();
+        const data = getResource<UserResource>(uuid)(resources);
+        dispatch(dialogActions.OPEN_DIALOG({ id: USER_ATTRIBUTES_DIALOG, data }));
     };
 
 export const openUserCreateDialog = () =>
diff --git a/src/views-components/context-menu/action-sets/user-action-set.ts b/src/views-components/context-menu/action-sets/user-action-set.ts
new file mode 100644
index 0000000..e06a7c2
--- /dev/null
+++ b/src/views-components/context-menu/action-sets/user-action-set.ts
@@ -0,0 +1,35 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ContextMenuActionSet } from "~/views-components/context-menu/context-menu-action-set";
+import { AdvancedIcon, ProjectIcon, AttributesIcon, ShareIcon } from "~/components/icon/icon";
+import { openAdvancedTabDialog } from '~/store/advanced-tab/advanced-tab';
+import { openUserAttributes } from "~/store/users/users-actions";
+
+export const userActionSet: ContextMenuActionSet = [[{
+    name: "Attributes",
+    icon: AttributesIcon,
+    execute: (dispatch, { uuid }) => {
+        dispatch<any>(openUserAttributes(uuid));
+    }
+}, {
+    name: "Project",
+    icon: ProjectIcon,
+    execute: (dispatch, { uuid }) => {
+        dispatch<any>(openAdvancedTabDialog(uuid));
+    }
+}, {
+    name: "Advanced",
+    icon: AdvancedIcon,
+    execute: (dispatch, { uuid }) => {
+        dispatch<any>(openAdvancedTabDialog(uuid));
+    }
+},
+{
+    name: "Manage",
+    icon: ShareIcon,
+    execute: (dispatch, { uuid }) => {
+        dispatch<any>(openAdvancedTabDialog(uuid));
+    }
+}]];
diff --git a/src/views-components/context-menu/context-menu.tsx b/src/views-components/context-menu/context-menu.tsx
index 5f321bf..29b8afb 100644
--- a/src/views-components/context-menu/context-menu.tsx
+++ b/src/views-components/context-menu/context-menu.tsx
@@ -72,5 +72,6 @@ export enum ContextMenuKind {
     REPOSITORY = "Repository",
     SSH_KEY = "SshKey",
     VIRTUAL_MACHINE = "VirtualMachine",
-    KEEP_SERVICE = "KeepService"
+    KEEP_SERVICE = "KeepService",
+    USER = "User"
 }
diff --git a/src/views-components/user-dialog/attributes-dialog.tsx b/src/views-components/user-dialog/attributes-dialog.tsx
new file mode 100644
index 0000000..5f711de
--- /dev/null
+++ b/src/views-components/user-dialog/attributes-dialog.tsx
@@ -0,0 +1,97 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from "react";
+import { Dialog, DialogTitle, DialogContent, DialogActions, Button, Typography, Grid } from "@material-ui/core";
+import { WithDialogProps } from "~/store/dialog/with-dialog";
+import { withDialog } from '~/store/dialog/with-dialog';
+import { WithStyles, withStyles } from '@material-ui/core/styles';
+import { ArvadosTheme } from '~/common/custom-theme';
+import { compose } from "redux";
+import { USER_ATTRIBUTES_DIALOG } from "~/store/users/users-actions";
+import { UserResource } from "~/models/user";
+
+type CssRules = 'rightContainer' | 'leftContainer' | 'spacing';
+
+const styles = withStyles<CssRules>((theme: ArvadosTheme) => ({
+    rightContainer: {
+        textAlign: 'right',
+        paddingRight: theme.spacing.unit * 2,
+        color: theme.palette.grey["500"]
+    },
+    leftContainer: {
+        textAlign: 'left',
+        paddingLeft: theme.spacing.unit * 2
+    },
+    spacing: {
+        paddingTop: theme.spacing.unit * 2
+    },
+}));
+
+interface UserAttributesDataProps {
+    data: UserResource;
+}
+
+type UserAttributesProps = UserAttributesDataProps & WithStyles<CssRules>;
+
+export const UserAttributesDialog = compose(
+    withDialog(USER_ATTRIBUTES_DIALOG),
+    styles)(
+        (props: WithDialogProps<UserAttributesProps> & UserAttributesProps) =>
+            <Dialog open={props.open}
+                onClose={props.closeDialog}
+                fullWidth
+                maxWidth="sm">
+                <DialogTitle>Attributes</DialogTitle>
+                <DialogContent>
+                    <Typography variant="body2" className={props.classes.spacing}>
+                        {props.data && attributes(props.data, props.classes)}
+                    </Typography>
+                </DialogContent>
+                <DialogActions>
+                    <Button
+                        variant='flat'
+                        color='primary'
+                        onClick={props.closeDialog}>
+                        Close
+                </Button>
+                </DialogActions>
+            </Dialog>
+    );
+
+const attributes = (user: UserResource, classes: any) => {
+    const { uuid, ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid, firstName, lastName, href, identityUrl, username } = user;
+    return (
+        <span>
+            <Grid container direction="row">
+                <Grid item xs={5} className={classes.rightContainer}>
+                    <Grid item>First name</Grid>
+                    <Grid item>Last name</Grid>
+                    <Grid item>Owner uuid</Grid>
+                    <Grid item>Created at</Grid>
+                    <Grid item>Modified at</Grid>
+                    <Grid item>Modified by user uuid</Grid>
+                    <Grid item>Modified by client uuid</Grid>
+                    <Grid item>uuid</Grid>
+                    <Grid item>Href</Grid>
+                    <Grid item>Identity url</Grid>
+                    <Grid item>Username</Grid>
+                </Grid>
+                <Grid item xs={7} className={classes.leftContainer}>
+                    <Grid item>{firstName}</Grid>
+                    <Grid item>{lastName}</Grid>
+                    <Grid item>{ownerUuid}</Grid>
+                    <Grid item>{createdAt}</Grid>
+                    <Grid item>{modifiedAt}</Grid>
+                    <Grid item>{modifiedByUserUuid}</Grid>
+                    <Grid item>{modifiedByClientUuid}</Grid>
+                    <Grid item>{uuid}</Grid>
+                    <Grid item>{href}</Grid>
+                    <Grid item>{identityUrl}</Grid>
+                    <Grid item>{username}</Grid>
+                </Grid>
+            </Grid>
+        </span>
+    );
+};
diff --git a/src/views/user-panel/user-panel.tsx b/src/views/user-panel/user-panel.tsx
index 4b9a339..ceaba8c 100644
--- a/src/views/user-panel/user-panel.tsx
+++ b/src/views/user-panel/user-panel.tsx
@@ -133,7 +133,6 @@ export const UserPanel = compose(
     })))(
         class extends React.Component<UserPanelProps> {
             render() {
-                console.log(this.props.resources);
                 return <DataExplorer
                     id={USERS_PANEL_ID}
                     onRowClick={this.handleRowClick}
@@ -156,7 +155,7 @@ export const UserPanel = compose(
                         uuid: resource.uuid,
                         ownerUuid: resource.ownerUuid,
                         kind: resource.kind,
-                        menuKind: ContextMenuKind.TRASH
+                        menuKind: ContextMenuKind.USER
                     }));
                 }
             }
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index 16032c4..11285ba 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -65,6 +65,7 @@ import { AttributesSshKeyDialog } from '~/views-components/ssh-keys-dialog/attri
 import { VirtualMachineAttributesDialog } from '~/views-components/virtual-machines-dialog/attributes-dialog';
 import { RemoveVirtualMachineDialog } from '~/views-components/virtual-machines-dialog/remove-dialog';
 import { UserPanel } from '~/views/user-panel/user-panel';
+import { UserAttributesDialog } from '~/views-components/user-dialog/attributes-dialog';
 
 type CssRules = 'root' | 'container' | 'splitter' | 'asidePanel' | 'contentWrapper' | 'content';
 
@@ -184,6 +185,7 @@ export const WorkbenchPanel =
             <UpdateCollectionDialog />
             <UpdateProcessDialog />
             <UpdateProjectDialog />
+            <UserAttributesDialog />
             <VirtualMachineAttributesDialog />
         </Grid>
     );
\ No newline at end of file

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list