[ARVADOS-WORKBENCH2] created: 1.3.1-362-ga67a8e83

Git user git at public.curoverse.com
Fri Feb 22 15:04:18 EST 2019


        at  a67a8e8330787ac509d15a28317e5c6915cc3a07 (commit)


commit a67a8e8330787ac509d15a28317e5c6915cc3a07
Author: Peter Amstutz <pamstutz at veritasgenetics.com>
Date:   Fri Feb 22 14:59:50 2019 -0500

    14720: "My account" page now explicitly when user is federated
    
    Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <pamstutz at veritasgenetics.com>

diff --git a/src/store/auth/auth-reducer.ts b/src/store/auth/auth-reducer.ts
index e7087b58..03357526 100644
--- a/src/store/auth/auth-reducer.ts
+++ b/src/store/auth/auth-reducer.ts
@@ -37,7 +37,7 @@ export const authReducer = (services: ServiceRepository) => (state = initialStat
             return {
                 ...state,
                 localCluster: config.uuidPrefix,
-                remoteHosts: config.remoteHosts,
+                remoteHosts: { ...config.remoteHosts, [config.uuidPrefix]: new URL(config.rootUrl).host },
                 homeCluster: config.uuidPrefix
             };
         },
diff --git a/src/views/my-account-panel/my-account-panel-root.tsx b/src/views/my-account-panel/my-account-panel-root.tsx
index e728c4eb..e84b3b64 100644
--- a/src/views/my-account-panel/my-account-panel-root.tsx
+++ b/src/views/my-account-panel/my-account-panel-root.tsx
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { Field, InjectedFormProps } from "redux-form";
+import { Field, InjectedFormProps, WrappedFieldProps } from "redux-form";
 import { TextField } from "~/components/text-field/text-field";
 import { NativeSelectField } from "~/components/select-field/select-field";
 import {
@@ -51,6 +51,7 @@ export interface MyAccountPanelRootDataProps {
     isPristine: boolean;
     isValid: boolean;
     initialValues?: User;
+    localCluster: string;
 }
 
 const RoleTypes = [
@@ -65,21 +66,20 @@ const RoleTypes = [
 
 type MyAccountPanelRootProps = InjectedFormProps<MyAccountPanelRootActionProps> & MyAccountPanelRootDataProps & WithStyles<CssRules>;
 
+type LocalClusterProp = { localCluster: string };
+const renderField: React.ComponentType<WrappedFieldProps & LocalClusterProp> = ({ input, localCluster }) => (
+    <span>{localCluster === input.value.substr(0, 5) ? "" : "federated"} user {input.value}</span>
+);
+
 export const MyAccountPanelRoot = withStyles(styles)(
-    ({ classes, isValid, handleSubmit, reset, isPristine, invalid, submitting }: MyAccountPanelRootProps) => {
+    ({ classes, isValid, handleSubmit, reset, isPristine, invalid, submitting, localCluster }: MyAccountPanelRootProps) => {
         return <Card className={classes.root}>
             <CardContent>
+                <Typography variant="title" className={classes.title}>
+                    Logged in as <Field name="uuid" component={renderField} localCluster={localCluster} />
+                </Typography>
                 <form onSubmit={handleSubmit}>
                     <Grid container spacing={24}>
-                        <Grid item xs={6} />
-                        <Grid item className={classes.gridItem} sm={6} xs={12}>
-                            <Field
-                                label="UUID"
-                                name="uuid"
-                                component={TextField}
-                                disabled
-                            />
-                        </Grid>
                         <Grid item className={classes.gridItem} sm={6} xs={12}>
                             <Field
                                 label="First name"
@@ -154,7 +154,7 @@ export const MyAccountPanelRoot = withStyles(styles)(
                                 type="submit"
                                 disabled={isPristine || invalid || submitting}>
                                 Save changes
-                        </Button>
+                            </Button>
                         </Grid>
                     </Grid>
                 </form >
diff --git a/src/views/my-account-panel/my-account-panel.tsx b/src/views/my-account-panel/my-account-panel.tsx
index 5c2c5317..bd1f5874 100644
--- a/src/views/my-account-panel/my-account-panel.tsx
+++ b/src/views/my-account-panel/my-account-panel.tsx
@@ -13,14 +13,15 @@ import { MY_ACCOUNT_FORM } from "~/store/my-account/my-account-panel-actions";
 const mapStateToProps = (state: RootState): MyAccountPanelRootDataProps => ({
     isPristine: isPristine(MY_ACCOUNT_FORM)(state),
     isValid: isValid(MY_ACCOUNT_FORM)(state),
-    initialValues: state.auth.user
+    initialValues: state.auth.user,
+    localCluster: state.auth.localCluster
 });
 
 export const MyAccountPanel = compose(
     connect(mapStateToProps),
     reduxForm({
-    form: MY_ACCOUNT_FORM,
-    onSubmit: (data, dispatch) => {
-        dispatch(saveEditedUser(data));
-    }
-}))(MyAccountPanelRoot);
\ No newline at end of file
+        form: MY_ACCOUNT_FORM,
+        onSubmit: (data, dispatch) => {
+            dispatch(saveEditedUser(data));
+        }
+    }))(MyAccountPanelRoot);

commit 8882246b577a8d24a0e83dcd8905069f7b1937c8
Author: Peter Amstutz <pamstutz at veritasgenetics.com>
Date:   Fri Feb 22 11:04:38 2019 -0500

    14841: Simplify configReducer
    
    Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <pamstutz at veritasgenetics.com>

diff --git a/src/store/config/config-reducer.ts b/src/store/config/config-reducer.ts
index 070bae18..f0b76b14 100644
--- a/src/store/config/config-reducer.ts
+++ b/src/store/config/config-reducer.ts
@@ -3,21 +3,13 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import { configActions, ConfigAction } from "./config-action";
-import { Config, mockConfig } from '~/common/config';
+import { mockConfig } from '~/common/config';
 
-export interface ConfigState {
-    config: Config;
-}
-
-const initialState: ConfigState = {
-    config: mockConfig({}),
-};
-
-export const configReducer = (state = initialState, action: ConfigAction) => {
+export const configReducer = (state = mockConfig({}), action: ConfigAction) => {
     return configActions.match(action, {
         CONFIG: ({ config }) => {
             return {
-                ...state, config
+                ...state, ...config
             };
         },
         default: () => state
diff --git a/src/views-components/main-app-bar/account-menu.tsx b/src/views-components/main-app-bar/account-menu.tsx
index c4f7e36f..271cf00f 100644
--- a/src/views-components/main-app-bar/account-menu.tsx
+++ b/src/views-components/main-app-bar/account-menu.tsx
@@ -30,7 +30,7 @@ interface AccountMenuProps {
 const mapStateToProps = (state: RootState): AccountMenuProps => ({
     user: state.auth.user,
     currentRoute: state.router.location ? state.router.location.pathname : '',
-    workbenchURL: state.config.config.workbenchUrl,
+    workbenchURL: state.config.workbenchUrl,
 });
 
 const wb1URL = (route: string) => {

commit f41a161af85e740c85ecc6a805644ff712cd4620
Author: Peter Amstutz <pamstutz at veritasgenetics.com>
Date:   Thu Feb 14 14:12:03 2019 -0500

    14841: Add link to workbench v1
    
    * Add a reducer that holds discovery document config, to read
      workbenchURL & for future things that need cluster config.
    
    * Projects, collections and "processes" are routed to equivalent page
      on wb1, rest are sent to entry page.
    
    Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <pamstutz at veritasgenetics.com>

diff --git a/src/index.tsx b/src/index.tsx
index d0eb7d3b..cfaff70a 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -14,6 +14,7 @@ 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 { configActions } from "~/store/config/config-action";
 import { createServices } from "~/services/services";
 import { MuiThemeProvider } from '@material-ui/core/styles';
 import { CustomTheme } from '~/common/custom-theme';
diff --git a/src/store/auth/auth-action.ts b/src/store/auth/auth-action.ts
index cc1a5a0a..fdaa2e1a 100644
--- a/src/store/auth/auth-action.ts
+++ b/src/store/auth/auth-action.ts
@@ -17,7 +17,7 @@ export const authActions = unionize({
     SAVE_API_TOKEN: ofType<string>(),
     LOGIN: {},
     LOGOUT: {},
-    CONFIG: ofType<{ uuidPrefix: string, remoteHosts: { [key: string]: string } }>(),
+    CONFIG: ofType<{ config: Config }>(),
     INIT: ofType<{ user: User, token: string }>(),
     USER_DETAILS_REQUEST: {},
     USER_DETAILS_SUCCESS: ofType<User>(),
@@ -50,7 +50,7 @@ export const initAuth = (config: Config) => (dispatch: Dispatch, getState: () =>
     if (token) {
         setAuthorizationHeader(services, token);
     }
-    dispatch(authActions.CONFIG({ uuidPrefix: config.uuidPrefix, remoteHosts: config.remoteHosts }));
+    dispatch(authActions.CONFIG({ config }));
     if (token && user) {
         dispatch(authActions.INIT({ user, token }));
         dispatch<any>(initSessions(services.authService, config, user));
diff --git a/src/store/auth/auth-reducer.ts b/src/store/auth/auth-reducer.ts
index 0504dd48..e7087b58 100644
--- a/src/store/auth/auth-reducer.ts
+++ b/src/store/auth/auth-reducer.ts
@@ -33,9 +33,12 @@ export const authReducer = (services: ServiceRepository) => (state = initialStat
         SAVE_API_TOKEN: (token: string) => {
             return { ...state, apiToken: token };
         },
-        CONFIG: ({ uuidPrefix, remoteHosts }) => {
+        CONFIG: ({ config }) => {
             return {
-                ...state, localCluster: uuidPrefix, remoteHosts, homeCluster: uuidPrefix
+                ...state,
+                localCluster: config.uuidPrefix,
+                remoteHosts: config.remoteHosts,
+                homeCluster: config.uuidPrefix
             };
         },
         INIT: ({ user, token }) => {
diff --git a/src/store/config/config-action.ts b/src/store/config/config-action.ts
new file mode 100644
index 00000000..fd792948
--- /dev/null
+++ b/src/store/config/config-action.ts
@@ -0,0 +1,12 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ofType, unionize, UnionOf } from '~/common/unionize';
+import { Config } from '~/common/config';
+
+export const configActions = unionize({
+    CONFIG: ofType<{ config: Config }>(),
+});
+
+export type ConfigAction = UnionOf<typeof configActions>;
diff --git a/src/store/config/config-reducer.ts b/src/store/config/config-reducer.ts
new file mode 100644
index 00000000..070bae18
--- /dev/null
+++ b/src/store/config/config-reducer.ts
@@ -0,0 +1,25 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { configActions, ConfigAction } from "./config-action";
+import { Config, mockConfig } from '~/common/config';
+
+export interface ConfigState {
+    config: Config;
+}
+
+const initialState: ConfigState = {
+    config: mockConfig({}),
+};
+
+export const configReducer = (state = initialState, action: ConfigAction) => {
+    return configActions.match(action, {
+        CONFIG: ({ config }) => {
+            return {
+                ...state, config
+            };
+        },
+        default: () => state
+    });
+};
diff --git a/src/store/store.ts b/src/store/store.ts
index 0be577c4..04813b1c 100644
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@ -8,6 +8,7 @@ import thunkMiddleware from 'redux-thunk';
 import { History } from "history";
 
 import { authReducer } from "./auth/auth-reducer";
+import { configReducer } from "./config/config-reducer";
 import { dataExplorerReducer } from './data-explorer/data-explorer-reducer';
 import { detailsPanelReducer } from './details-panel/details-panel-reducer';
 import { contextMenuReducer } from './context-menu/context-menu-reducer';
@@ -61,8 +62,8 @@ import { ApiClientAuthorizationMiddlewareService } from '~/store/api-client-auth
 
 const composeEnhancers =
     (process.env.NODE_ENV === 'development' &&
-     window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ &&
-     window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({trace: true, traceLimit: 25})) ||
+        window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ &&
+        window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ trace: true, traceLimit: 25 })) ||
     compose;
 
 export type RootState = ReturnType<ReturnType<typeof createRootReducer>>;
@@ -130,6 +131,7 @@ export function configureStore(history: History, services: ServiceRepository): R
 
 const createRootReducer = (services: ServiceRepository) => combineReducers({
     auth: authReducer(services),
+    config: configReducer,
     collectionPanel: collectionPanelReducer,
     collectionPanelFiles: collectionPanelFilesReducer,
     contextMenu: contextMenuReducer,
diff --git a/src/views-components/main-app-bar/account-menu.tsx b/src/views-components/main-app-bar/account-menu.tsx
index 2aec77e2..c4f7e36f 100644
--- a/src/views-components/main-app-bar/account-menu.tsx
+++ b/src/views-components/main-app-bar/account-menu.tsx
@@ -4,8 +4,10 @@
 
 import * as React from "react";
 import { MenuItem, Divider } from "@material-ui/core";
+import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
 import { User, getUserFullname } from "~/models/user";
 import { DropdownMenu } from "~/components/dropdown-menu/dropdown-menu";
+import { Link } from "react-router-dom";
 import { UserPanelIcon } from "~/components/icon/icon";
 import { DispatchProp, connect } from 'react-redux';
 import { logout } from '~/store/auth/auth-action';
@@ -22,31 +24,57 @@ import { openUserVirtualMachines } from "~/store/virtual-machines/virtual-machin
 interface AccountMenuProps {
     user?: User;
     currentRoute: string;
+    workbenchURL: string;
 }
 
 const mapStateToProps = (state: RootState): AccountMenuProps => ({
     user: state.auth.user,
-    currentRoute: state.router.location ? state.router.location.pathname : ''
+    currentRoute: state.router.location ? state.router.location.pathname : '',
+    workbenchURL: state.config.config.workbenchUrl,
 });
 
-export const AccountMenu = connect(mapStateToProps)(
-    ({ user, dispatch, currentRoute }: AccountMenuProps & DispatchProp<any>) =>
-        user
-            ? <DropdownMenu
-                icon={<UserPanelIcon />}
-                id="account-menu"
-                title="Account Management"
-                key={currentRoute}>
-                <MenuItem disabled>
-                    {getUserFullname(user)}
-                </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(navigateToSshKeysUser)}>Ssh Keys</MenuItem>
-                <MenuItem onClick={() => dispatch(navigateToSiteManager)}>Site Manager</MenuItem>
-                <MenuItem onClick={() => dispatch(navigateToMyAccount)}>My account</MenuItem>
-                <Divider />
-                <MenuItem onClick={() => dispatch(logout())}>Logout</MenuItem>
-            </DropdownMenu>
-            : null);
+const wb1URL = (route: string) => {
+    const r = route.replace(/^\//, "");
+    if (r.match(/^(projects|collections)\//)) {
+        return r;
+    } else if (r.match(/^processes\//)) {
+        return r.replace(/^processes/, "container_requests");
+    }
+    return "";
+};
+
+type CssRules = 'link';
+
+const styles: StyleRulesCallback<CssRules> = () => ({
+    link: {
+        textDecoration: 'none',
+        color: 'inherit'
+    }
+});
+
+export const AccountMenu = withStyles(styles)(
+    connect(mapStateToProps)(
+        ({ user, dispatch, currentRoute, workbenchURL, classes }: AccountMenuProps & DispatchProp<any> & WithStyles<CssRules>) =>
+            user
+                ? <DropdownMenu
+                    icon={<UserPanelIcon />}
+                    id="account-menu"
+                    title="Account Management"
+                    key={currentRoute}>
+                    <MenuItem disabled>
+                        {getUserFullname(user)}
+                    </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(navigateToSshKeysUser)}>Ssh Keys</MenuItem>
+                    <MenuItem onClick={() => dispatch(navigateToSiteManager)}>Site Manager</MenuItem>
+                    <MenuItem onClick={() => dispatch(navigateToMyAccount)}>My account</MenuItem>
+                    <MenuItem>
+                        <a href={`${workbenchURL.replace(/\/$/, "")}/${wb1URL(currentRoute)}`}
+                            className={classes.link}>
+                            Switch to Workbench v1</a></MenuItem>
+                    <Divider />
+                    <MenuItem onClick={() => dispatch(logout())}>Logout</MenuItem>
+                </DropdownMenu>
+                : null));

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list