lastName: string;
uuid: string;
ownerUuid: string;
- identityUrl: string;
+ username: string;
prefs: UserPrefs;
isAdmin: boolean;
}
username: string;
firstName: string;
lastName: string;
- identityUrl: string;
isAdmin: boolean;
prefs: UserPrefs;
defaultOwnerUuid: string;
isActive: boolean;
writableBy: string[];
-}
\ No newline at end of file
+}
export const USER_UUID_KEY = 'userUuid';
export const USER_OWNER_UUID_KEY = 'userOwnerUuid';
export const USER_IS_ADMIN = 'isAdmin';
-export const USER_IDENTITY_URL = 'identityUrl';
+export const USER_USERNAME = 'username';
export const USER_PREFS = 'prefs';
export interface UserDetailsResponse {
uuid: string;
owner_uuid: string;
is_admin: boolean;
- identity_url: string;
+ username: string;
prefs: UserPrefs;
}
const uuid = this.getUuid();
const ownerUuid = this.getOwnerUuid();
const isAdmin = this.getIsAdmin();
- const identityUrl = localStorage.getItem(USER_IDENTITY_URL);
+ const username = localStorage.getItem(USER_USERNAME);
const prefs = JSON.parse(localStorage.getItem(USER_PREFS) || '{"profile": {}}');
- return email && firstName && lastName && uuid && ownerUuid && identityUrl && prefs
- ? { email, firstName, lastName, uuid, ownerUuid, isAdmin, identityUrl, prefs }
+ return email && firstName && lastName && uuid && ownerUuid && username && prefs
+ ? { email, firstName, lastName, uuid, ownerUuid, isAdmin, username, prefs }
: undefined;
}
localStorage.setItem(USER_UUID_KEY, user.uuid);
localStorage.setItem(USER_OWNER_UUID_KEY, user.ownerUuid);
localStorage.setItem(USER_IS_ADMIN, JSON.stringify(user.isAdmin));
- localStorage.setItem(USER_IDENTITY_URL, user.identityUrl);
+ localStorage.setItem(USER_USERNAME, user.username);
localStorage.setItem(USER_PREFS, JSON.stringify(user.prefs));
}
localStorage.removeItem(USER_UUID_KEY);
localStorage.removeItem(USER_OWNER_UUID_KEY);
localStorage.removeItem(USER_IS_ADMIN);
- localStorage.removeItem(USER_IDENTITY_URL);
+ localStorage.removeItem(USER_USERNAME);
localStorage.removeItem(USER_PREFS);
}
uuid: resp.data.uuid,
ownerUuid: resp.data.owner_uuid,
isAdmin: resp.data.is_admin,
- identityUrl: resp.data.identity_url,
+ username: resp.data.username,
prefs
};
})
const userApiResponse = (apiResponse: UserResource) => {
const {
uuid, ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid,
- email, firstName, lastName, identityUrl, isActive, isAdmin, prefs, defaultOwnerUuid, username
+ email, firstName, lastName, username, isActive, isAdmin, prefs, defaultOwnerUuid,
} = apiResponse;
const response = `
"uuid": "${uuid}",
"email": "${email}",
"first_name": "${firstName}",
"last_name": "${stringify(lastName)}",
-"identity_url": "${identityUrl}",
+"username": "${username}",
"is_active": "${isActive},
"is_admin": "${isAdmin},
"prefs": "${stringifyObject(prefs)},
"properties": "${JSON.stringify(properties, null, 2)}"`;
return <span style={{ marginLeft: '-15px' }}>{'{'} {response} {'\n'} <span style={{ marginLeft: '-15px' }}>{'}'}</span></span>;
-};
\ No newline at end of file
+};
ownerUuid: user.owner_uuid,
email: user.email,
isAdmin: user.is_admin,
- identityUrl: user.identity_url,
+ username: user.username,
prefs: user.prefs
},
token: saltedToken
USER_LAST_NAME_KEY,
USER_OWNER_UUID_KEY,
USER_UUID_KEY,
- USER_IS_ADMIN, USER_IDENTITY_URL, USER_PREFS
+ USER_IS_ADMIN, USER_USERNAME, USER_PREFS
} from "~/services/auth-service/auth-service";
import 'jest-localstorage-mock';
let reducer: (state: AuthState | undefined, action: AuthAction) => any;
let store: RootStore;
const actions: ApiActions = {
- progressFn: (id: string, working: boolean) => {},
- errorFn: (id: string, message: string) => {}
+ progressFn: (id: string, working: boolean) => { },
+ errorFn: (id: string, message: string) => { }
};
beforeEach(() => {
localStorage.setItem(USER_FIRST_NAME_KEY, "John");
localStorage.setItem(USER_LAST_NAME_KEY, "Doe");
localStorage.setItem(USER_UUID_KEY, "uuid");
- localStorage.setItem(USER_IDENTITY_URL, "identityUrl");
+ localStorage.setItem(USER_USERNAME, "username");
localStorage.setItem(USER_PREFS, JSON.stringify({}));
localStorage.setItem(USER_OWNER_UUID_KEY, "ownerUuid");
localStorage.setItem(USER_IS_ADMIN, JSON.stringify("false"));
lastName: "Doe",
uuid: "uuid",
ownerUuid: "ownerUuid",
- identityUrl: "identityUrl",
+ username: "username",
prefs: {},
isAdmin: false
}
});
*/
});
-
-
describe('auth-reducer', () => {
let reducer: (state: AuthState | undefined, action: AuthAction) => any;
const actions: ApiActions = {
- progressFn: (id: string, working: boolean) => {},
- errorFn: (id: string, message: string) => {}
+ progressFn: (id: string, working: boolean) => { },
+ errorFn: (id: string, message: string) => { }
};
beforeAll(() => {
lastName: "Doe",
uuid: "uuid",
ownerUuid: "ownerUuid",
- identityUrl: "identityUrl",
+ username: "username",
prefs: {},
isAdmin: false
};
lastName: "Doe",
uuid: "uuid",
ownerUuid: "ownerUuid",
- identityUrl: "identityUrl",
+ username: "username",
prefs: {},
isAdmin: false
};
lastName: "Doe",
uuid: "uuid",
ownerUuid: "ownerUuid",
- identityUrl: "identityUrl",
+ username: "username",
prefs: {},
isAdmin: false
}
// SPDX-License-Identifier: AGPL-3.0
import * as React from "react";
-import { MenuItem } from "@material-ui/core";
+import { MenuItem, Divider } from "@material-ui/core";
import { User, getUserFullname } from "~/models/user";
import { DropdownMenu } from "~/components/dropdown-menu/dropdown-menu";
import { UserPanelIcon } from "~/components/icon/icon";
id="account-menu"
title="Account Management"
key={currentRoute}>
- <MenuItem>
- {getUserFullname(user)} ({user.uuid.substr(0, 5)})
+ <MenuItem disabled>
+ {getUserFullname(user)}
</MenuItem>
<MenuItem onClick={() => dispatch(openUserVirtualMachines())}>Virtual Machines</MenuItem>
{!user.isAdmin && <MenuItem onClick={() => dispatch(openRepositoriesPanel())}>Repositories</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 attributes = (user: UserResource, classes: any) => {
- const { uuid, ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid, firstName, lastName, href, identityUrl, username } = user;
+ const { uuid, ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid, firstName, lastName, href, username } = user;
return (
<span>
<Grid container direction="row">
{modifiedByClientUuid && <Grid item>Modified by client uuid</Grid>}
{uuid && <Grid item>uuid</Grid>}
{href && <Grid item>Href</Grid>}
- {identityUrl && <Grid item>Identity url</Grid>}
+ {username && <Grid item>Username</Grid>}
{username && <Grid item>Username</Grid>}
</Grid>
<Grid item xs={7} className={classes.leftContainer}>
<Grid item>{modifiedByClientUuid}</Grid>
<Grid item>{uuid}</Grid>
<Grid item>{href}</Grid>
- <Grid item>{identityUrl}</Grid>
+ <Grid item>{username}</Grid>
<Grid item>{username}</Grid>
</Grid>
</Grid>
homeCluster: state.auth.homeCluster,
uuidPrefix: state.auth.localCluster
}))(({ classes, dispatch, remoteHosts, homeCluster, uuidPrefix }: LoginPanelProps) =>
- <Grid container direction="column" item xs alignItems="center" justify="center" className={classes.root}>
+ <Grid container justify="center" alignItems="center"
+ className={classes.root}
+ style={{ marginTop: 56, overflowY: "auto" }}>
<Grid item className={classes.container}>
<Typography variant='h6' align="center" className={classes.title}>
Welcome to the Arvados Workbench
</Button>
</Typography>
</Grid>
- </Grid>
+ </Grid >
));
} from '@material-ui/core';
import { ArvadosTheme } from '~/common/custom-theme';
import { User } from "~/models/user";
-import { MY_ACCOUNT_VALIDATION} from "~/validators/validators";
+import { MY_ACCOUNT_VALIDATION } from "~/validators/validators";
type CssRules = 'root' | 'gridItem' | 'label' | 'title' | 'actions';
}
});
-export interface MyAccountPanelRootActionProps {}
+export interface MyAccountPanelRootActionProps { }
export interface MyAccountPanelRootDataProps {
isPristine: boolean;
}
const RoleTypes = [
- {key: 'Bio-informatician', value: 'Bio-informatician'},
- {key: 'Data Scientist', value: 'Data Scientist'},
- {key: 'Analyst', value: 'Analyst'},
- {key: 'Researcher', value: 'Researcher'},
- {key: 'Software Developer', value: 'Software Developer'},
- {key: 'System Administrator', value: 'System Administrator'},
- {key: 'Other', value: 'Other'}
+ { key: 'Bio-informatician', value: 'Bio-informatician' },
+ { key: 'Data Scientist', value: 'Data Scientist' },
+ { key: 'Analyst', value: 'Analyst' },
+ { key: 'Researcher', value: 'Researcher' },
+ { key: 'Software Developer', value: 'Software Developer' },
+ { key: 'System Administrator', value: 'System Administrator' },
+ { key: 'Other', value: 'Other' }
];
type MyAccountPanelRootProps = InjectedFormProps<MyAccountPanelRootActionProps> & MyAccountPanelRootDataProps & WithStyles<CssRules>;
({ classes, isValid, handleSubmit, reset, isPristine, invalid, submitting }: MyAccountPanelRootProps) => {
return <Card className={classes.root}>
<CardContent>
- <Typography variant='h6' className={classes.title}>User profile</Typography>
<form onSubmit={handleSubmit}>
- <Grid container direction="row" spacing={24}>
- <Grid item xs={6}>
- <Grid item className={classes.gridItem}>
- <Field
- label="E-mail"
- name="email"
- component={TextField}
- disabled
- />
- </Grid>
- <Grid item className={classes.gridItem}>
- <Field
- label="First name"
- name="firstName"
- component={TextField}
- disabled
- />
- </Grid>
- <Grid item className={classes.gridItem}>
- <Field
- label="Identity URL"
- name="identityUrl"
- component={TextField}
- disabled
- />
- </Grid>
- <Grid item className={classes.gridItem}>
- <Field
- label="Organization"
- name="prefs.profile.organization"
- component={TextField}
- validate={MY_ACCOUNT_VALIDATION}
- required
- />
- </Grid>
- <Grid item className={classes.gridItem}>
- <Field
- label="Website"
- name="prefs.profile.website_url"
- component={TextField}
- />
- </Grid>
- <Grid item className={classes.gridItem}>
- <InputLabel className={classes.label} htmlFor="prefs.profile.role">Role</InputLabel>
- <Field
- id="prefs.profile.role"
- name="prefs.profile.role"
- component={NativeSelectField}
- items={RoleTypes}
- />
- </Grid>
+ <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 xs={6}>
- <Grid item className={classes.gridItem} />
- <Grid item className={classes.gridItem}>
- <Field
- label="Last name"
- name="lastName"
- component={TextField}
- disabled
- />
- </Grid>
- <Grid item className={classes.gridItem} />
- <Grid item className={classes.gridItem}>
- <Field
- label="E-mail at Organization"
- name="prefs.profile.organization_email"
- component={TextField}
- validate={MY_ACCOUNT_VALIDATION}
- required
- />
- </Grid>
+ <Grid item className={classes.gridItem} sm={6} xs={12}>
+ <Field
+ label="First name"
+ name="firstName"
+ component={TextField}
+ disabled
+ />
</Grid>
- <Grid item xs={12} className={classes.actions}>
+ <Grid item className={classes.gridItem} sm={6} xs={12}>
+ <Field
+ label="Last name"
+ name="lastName"
+ component={TextField}
+ disabled
+ />
+ </Grid>
+ <Grid item className={classes.gridItem} sm={6} xs={12}>
+ <Field
+ label="E-mail"
+ name="email"
+ component={TextField}
+ disabled
+ />
+ </Grid>
+ <Grid item className={classes.gridItem} sm={6} xs={12}>
+ <Field
+ label="Username"
+ name="username"
+ component={TextField}
+ disabled
+ />
+ </Grid>
+ <Grid item className={classes.gridItem} sm={6} xs={12}>
+ <Field
+ label="Organization"
+ name="prefs.profile.organization"
+ component={TextField}
+ validate={MY_ACCOUNT_VALIDATION}
+ required
+ />
+ </Grid>
+ <Grid item className={classes.gridItem} sm={6} xs={12}>
+ <Field
+ label="E-mail at Organization"
+ name="prefs.profile.organization_email"
+ component={TextField}
+ validate={MY_ACCOUNT_VALIDATION}
+ required
+ />
+ </Grid>
+ <Grid item className={classes.gridItem} sm={6} xs={12}>
+ <InputLabel className={classes.label} htmlFor="prefs.profile.role">Role</InputLabel>
+ <Field
+ id="prefs.profile.role"
+ name="prefs.profile.role"
+ component={NativeSelectField}
+ items={RoleTypes}
+ />
+ </Grid>
+ <Grid item className={classes.gridItem} sm={6} xs={12}>
+ <Field
+ label="Website"
+ name="prefs.profile.website_url"
+ component={TextField}
+ />
+ </Grid>
+ <Grid container direction="row" justify="flex-end" >
<Button color="primary" onClick={reset} disabled={isPristine}>Discard changes</Button>
<Button
color="primary"
variant="contained"
type="submit"
disabled={isPristine || invalid || submitting}>
- Save changes
- </Button>
+ Save changes
+ </Button>
</Grid>
</Grid>
- </form>
- </CardContent>
- </Card>;}
-);
\ No newline at end of file
+ </form >
+ </CardContent >
+ </Card >;
+ }
+);