X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/addb01b6d7636a8963ddb1eff4799ebc96f44739..273119605b7f33940a5ef9b1422eb1ff152d6764:/src/views/user-profile-panel/user-profile-panel-root.tsx diff --git a/src/views/user-profile-panel/user-profile-panel-root.tsx b/src/views/user-profile-panel/user-profile-panel-root.tsx index c0c80e3c..6a556516 100644 --- a/src/views/user-profile-panel/user-profile-panel-root.tsx +++ b/src/views/user-profile-panel/user-profile-panel-root.tsx @@ -4,6 +4,8 @@ import React from 'react'; import { Field, InjectedFormProps } from "redux-form"; +import { DispatchProp } from 'react-redux'; +import { UserResource } from 'models/user'; import { TextField } from "components/text-field/text-field"; import { DataExplorer } from "views-components/data-explorer/data-explorer"; import { NativeSelectField } from "components/select-field/select-field"; @@ -11,42 +13,51 @@ import { StyleRulesCallback, WithStyles, withStyles, - Card, CardContent, Button, Typography, Grid, InputLabel, Tabs, Tab, - Paper + Paper, + Tooltip, + IconButton, } from '@material-ui/core'; import { ArvadosTheme } from 'common/custom-theme'; -import { User } from "models/user"; -import { DataTableDefaultView } from 'components/data-table-default-view/data-table-default-view'; -import { MY_ACCOUNT_VALIDATION } from "validators/validators"; +import { PROFILE_EMAIL_VALIDATION, PROFILE_URL_VALIDATION } from "validators/validators"; import { USER_PROFILE_PANEL_ID } from 'store/user-profile/user-profile-actions'; import { noop } from 'lodash'; -import { GroupsIcon } from 'components/icon/icon'; +import { DetailsIcon, GroupsIcon, MoreOptionsIcon } from 'components/icon/icon'; import { DataColumns } from 'components/data-table/data-table'; -import { ResourceLinkHeadUuid, ResourceLinkHeadPermissionLevel, ResourceLinkHead, ResourceLinkDelete, ResourceLinkTailIsVisible } from 'views-components/data-explorer/renderers'; +import { ResourceLinkHeadUuid, ResourceLinkHeadPermissionLevel, ResourceLinkHead, ResourceLinkDelete, ResourceLinkTailIsVisible, UserResourceAccountStatus } from 'views-components/data-explorer/renderers'; import { createTree } from 'models/tree'; +import { getResource, ResourcesState } from 'store/resources/resources'; +import { DefaultView } from 'components/default-view/default-view'; +import { CopyToClipboardSnackbar } from 'components/copy-to-clipboard-snackbar/copy-to-clipboard-snackbar'; +import { PermissionResource } from 'models/permission'; -type CssRules = 'root' | 'adminRoot' | 'gridItem' | 'label' | 'title' | 'description' | 'actions' | 'content'; +type CssRules = 'root' | 'emptyRoot' | 'gridItem' | 'label' | 'readOnlyValue' | 'title' | 'description' | 'actions' | 'content' | 'copyIcon'; const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ root: { width: '100%', overflow: 'auto' }, - adminRoot: { - // ...theme.mixins.gutters() + emptyRoot: { + width: '100%', + overflow: 'auto', + padding: theme.spacing.unit * 4, }, gridItem: { height: 45, marginBottom: 20 }, label: { - fontSize: '0.675rem' + fontSize: '0.675rem', + color: theme.palette.grey['600'] + }, + readOnlyValue: { + fontSize: '0.875rem', }, title: { fontSize: '1.1rem', @@ -61,23 +72,35 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ content: { // reserve space for the tab bar height: `calc(100% - ${theme.spacing.unit * 7}px)`, + }, + copyIcon: { + marginLeft: theme.spacing.unit, + color: theme.palette.grey["500"], + cursor: 'pointer', + display: 'inline', + '& svg': { + fontSize: '1rem' + } } }); export interface UserProfilePanelRootActionProps { - openSetupShellAccount: (uuid: string) => void; - loginAs: (uuid: string) => void; - openDeactivateDialog: (uuid: string) => void; + handleContextMenu: (event, resource: UserResource) => void; } export interface UserProfilePanelRootDataProps { + isAdmin: boolean; + isSelf: boolean; isPristine: boolean; isValid: boolean; - initialValues?: User; + isInaccessible: boolean; + userUuid: string; + resources: ResourcesState; localCluster: string; } const RoleTypes = [ + { key: '', value: '' }, { key: 'Bio-informatician', value: 'Bio-informatician' }, { key: 'Data Scientist', value: 'Data Scientist' }, { key: 'Analyst', value: 'Analyst' }, @@ -87,12 +110,7 @@ const RoleTypes = [ { key: 'Other', value: 'Other' } ]; -type UserProfilePanelRootProps = InjectedFormProps<{}> & UserProfilePanelRootActionProps & UserProfilePanelRootDataProps & WithStyles; - -// type LocalClusterProp = { localCluster: string }; -// const renderField: React.ComponentType = ({ input, localCluster }) => ( -// {localCluster === input.value.substring(0, 5) ? "" : "federated"} user {input.value} -// ); +type UserProfilePanelRootProps = InjectedFormProps<{}> & UserProfilePanelRootActionProps & UserProfilePanelRootDataProps & DispatchProp & WithStyles; export enum UserProfileGroupsColumnNames { NAME = "Name", @@ -102,7 +120,13 @@ export enum UserProfileGroupsColumnNames { REMOVE = "Remove", } -export const userProfileGroupsColumns: DataColumns = [ +enum TABS { + PROFILE = "PROFILE", + GROUPS = "GROUPS", + +} + +export const userProfileGroupsColumns: DataColumns = [ { name: UserProfileGroupsColumnNames.NAME, selected: true, @@ -140,60 +164,100 @@ export const userProfileGroupsColumns: DataColumns = [ }, ]; +const ReadOnlyField = withStyles(styles)( + (props: ({ label: string, input: {value: string} }) & WithStyles ) => ( + + + {props.label} + + + {props.input.value} + + + ) +); + export const UserProfilePanelRoot = withStyles(styles)( class extends React.Component { state = { - value: 0, + value: TABS.PROFILE, }; componentDidMount() { - this.setState({ value: 0 }); + this.setState({ value: TABS.PROFILE}); } render() { - return - {/* - Logged in as - */} - - - - - - {this.state.value === 0 && - // + if (this.props.isInaccessible) { + return ( + + + + + + ); + } else { + return + + + + + {this.state.value === TABS.PROFILE && -
+ + + + {this.props.userUuid} + + + + + + + + + this.handleContextMenu(event, this.props.userUuid)}> + + + + + + + + - + - + - + - + @@ -202,8 +266,7 @@ export const UserProfilePanelRoot = withStyles(styles)( label="Organization" name="prefs.profile.organization" component={TextField as any} - validate={MY_ACCOUNT_VALIDATION} - required + disabled={!this.props.isAdmin && !this.props.isSelf} /> @@ -211,8 +274,8 @@ export const UserProfilePanelRoot = withStyles(styles)( label="E-mail at Organization" name="prefs.profile.organization_email" component={TextField as any} - validate={MY_ACCOUNT_VALIDATION} - required + disabled={!this.props.isAdmin && !this.props.isSelf} + validate={PROFILE_EMAIL_VALIDATION} /> @@ -222,6 +285,7 @@ export const UserProfilePanelRoot = withStyles(styles)( name="prefs.profile.role" component={NativeSelectField as any} items={RoleTypes} + disabled={!this.props.isAdmin && !this.props.isSelf} /> @@ -229,6 +293,8 @@ export const UserProfilePanelRoot = withStyles(styles)( label="Website" name="prefs.profile.website_url" component={TextField as any} + disabled={!this.props.isAdmin && !this.props.isSelf} + validate={PROFILE_URL_VALIDATION} /> @@ -246,106 +312,26 @@ export const UserProfilePanelRoot = withStyles(styles)(
- //
- } - {this.state.value === 1 && -
- - } /> -
} - {this.state.value === 2 && - - - - - - - Setup Account - - - This button sets up a user. After setup, they will be able use Arvados. This dialog box also allows you to optionally set up a shell account for this user. The login name is automatically generated from the user's e-mail address. - - - - - - - - - - - - - - Deactivate - - - As an admin, you can deactivate and reset this user. This will remove all repository/VM permissions for the user. If you "setup" the user again, the user will have to sign the user agreement again. You may also want to reassign data ownership. - - - - - - - - - - - - - - Log In - - - As an admin, you can log in as this user. When you’ve finished, you will need to log out and log in again with your own account. - - - - - - - - - } -
; + } + {this.state.value === TABS.GROUPS && +
+ +
} + ; + } } handleChange = (event: React.MouseEvent, value: number) => { @@ -353,16 +339,12 @@ export const UserProfilePanelRoot = withStyles(styles)( } handleContextMenu = (event: React.MouseEvent, resourceUuid: string) => { - // const resource = getResource(resourceUuid)(this.props.resources); - // if (resource) { - // this.props.onContextMenu(event, { - // name: '', - // uuid: resource.uuid, - // ownerUuid: resource.ownerUuid, - // kind: resource.kind, - // menuKind: ContextMenuKind.USER - // }); - // } + event.stopPropagation(); + const resource = getResource(resourceUuid)(this.props.resources); + if (resource) { + this.props.handleContextMenu(event, resource); + } } + } );