mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-10 12:00:57 +08:00
Auth UI tweaks (#1915)
* remove auth buttons and dataset info from info menu * add auth buttons to menubar * remove auth from top left * new auth buttons * move infomenu to lsb dir * styling fixes * feedback * more feedback Co-authored-by: Timmy Huang <thuang@chanzuckerberg.com>
This commit is contained in:
co-authored by
Timmy Huang
parent
cf77a8da9e
commit
1c4c501c43
@@ -0,0 +1,72 @@
|
|||||||
|
// jshint esversion: 6
|
||||||
|
import React from "react";
|
||||||
|
import { Button, Menu, MenuItem, Popover, Position } from "@blueprintjs/core";
|
||||||
|
import { IconNames } from "@blueprintjs/icons";
|
||||||
|
|
||||||
|
const InformationMenu = React.memo((props) => {
|
||||||
|
const { libraryVersions, tosURL, privacyURL } = props;
|
||||||
|
return (
|
||||||
|
<Popover
|
||||||
|
content={
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
href="https://chanzuckerberg.github.io/cellxgene/"
|
||||||
|
target="_blank"
|
||||||
|
icon="book"
|
||||||
|
text="Documentation"
|
||||||
|
rel="noopener"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
href="https://join-cellxgene-users.herokuapp.com/"
|
||||||
|
target="_blank"
|
||||||
|
icon="chat"
|
||||||
|
text="Chat"
|
||||||
|
rel="noopener"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
href="https://github.com/chanzuckerberg/cellxgene"
|
||||||
|
target="_blank"
|
||||||
|
icon="git-branch"
|
||||||
|
text="Github"
|
||||||
|
rel="noopener"
|
||||||
|
/>
|
||||||
|
<MenuItem target="_blank" text={libraryVersions?.cellxgene || null} />
|
||||||
|
<MenuItem text="MIT License" />
|
||||||
|
{tosURL && (
|
||||||
|
<MenuItem
|
||||||
|
href={tosURL}
|
||||||
|
target="_blank"
|
||||||
|
text="Terms of Service"
|
||||||
|
rel="noopener"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{privacyURL && (
|
||||||
|
<MenuItem
|
||||||
|
href={privacyURL}
|
||||||
|
target="_blank"
|
||||||
|
text="Privacy Policy"
|
||||||
|
rel="noopener"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Menu>
|
||||||
|
}
|
||||||
|
position={Position.BOTTOM_RIGHT}
|
||||||
|
modifiers={{
|
||||||
|
preventOverflow: { enabled: false },
|
||||||
|
hide: { enabled: false },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
data-testid="menu"
|
||||||
|
type="button"
|
||||||
|
icon={IconNames.INFO_SIGN}
|
||||||
|
style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
verticalAlign: "middle",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default InformationMenu;
|
||||||
@@ -7,15 +7,12 @@ import * as globals from "../../globals";
|
|||||||
import Logo from "../framework/logo";
|
import Logo from "../framework/logo";
|
||||||
import Truncate from "../util/truncate";
|
import Truncate from "../util/truncate";
|
||||||
import InfoDrawer from "../infoDrawer/infoDrawer";
|
import InfoDrawer from "../infoDrawer/infoDrawer";
|
||||||
import AuthButtons from "../menubar/authButtons";
|
import InformationMenu from "./infoMenu";
|
||||||
import InformationMenu from "../menubar/infoMenu";
|
|
||||||
|
|
||||||
const DATASET_TITLE_FONT_SIZE = 14;
|
const DATASET_TITLE_FONT_SIZE = 14;
|
||||||
|
|
||||||
@connect((state) => ({
|
@connect((state) => ({
|
||||||
datasetTitle: state.config?.displayNames?.dataset ?? "",
|
datasetTitle: state.config?.displayNames?.dataset ?? "",
|
||||||
auth: state.config?.authentication,
|
|
||||||
userinfo: state.userinfo,
|
|
||||||
libraryVersions: state.config?.["library_versions"],
|
libraryVersions: state.config?.["library_versions"],
|
||||||
aboutLink: state.config?.links?.["about-dataset"],
|
aboutLink: state.config?.links?.["about-dataset"],
|
||||||
tosURL: state.config?.parameters?.["about_legal_tos"],
|
tosURL: state.config?.parameters?.["about_legal_tos"],
|
||||||
@@ -30,8 +27,6 @@ class LeftSideBar extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
datasetTitle,
|
datasetTitle,
|
||||||
auth,
|
|
||||||
userinfo,
|
|
||||||
libraryVersions,
|
libraryVersions,
|
||||||
aboutLink,
|
aboutLink,
|
||||||
privacyURL,
|
privacyURL,
|
||||||
@@ -79,7 +74,7 @@ class LeftSideBar extends React.Component {
|
|||||||
gene
|
gene
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ marginRight: 5, position: "relative", top: -7 }}>
|
<div style={{ marginRight: 5, height: "100%" }}>
|
||||||
<Button
|
<Button
|
||||||
minimal
|
minimal
|
||||||
style={{
|
style={{
|
||||||
@@ -102,14 +97,9 @@ class LeftSideBar extends React.Component {
|
|||||||
aboutLink,
|
aboutLink,
|
||||||
tosURL,
|
tosURL,
|
||||||
privacyURL,
|
privacyURL,
|
||||||
auth,
|
|
||||||
dispatch,
|
dispatch,
|
||||||
userinfo,
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{!userinfo.is_authenticated ? (
|
|
||||||
<AuthButtons auth={auth} userinfo={userinfo} />
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,30 +1,83 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { AnchorButton, ButtonGroup, Tooltip } from "@blueprintjs/core";
|
import {
|
||||||
|
AnchorButton,
|
||||||
|
Button,
|
||||||
|
MenuItem,
|
||||||
|
Tooltip,
|
||||||
|
Popover,
|
||||||
|
Menu,
|
||||||
|
} from "@blueprintjs/core";
|
||||||
|
import { IconNames } from "@blueprintjs/icons";
|
||||||
|
|
||||||
import * as globals from "../../globals";
|
import * as globals from "../../globals";
|
||||||
import styles from "./menubar.css";
|
import styles from "./menubar.css";
|
||||||
|
|
||||||
|
const BASE_EMOJI = [0x1f9d1, 0x1f468, 0x1f469];
|
||||||
|
const SKIN_TONES = [0x1f3fb, 0x1f3fc, 0x1f3fd, 0x1f3fe, 0x1f3ff];
|
||||||
|
const MICROSCOPE = 0x1f52c;
|
||||||
|
const ZERO_WIDTH_JOINER = 0x0200d;
|
||||||
|
|
||||||
const Auth = React.memo((props) => {
|
const Auth = React.memo((props) => {
|
||||||
const { auth, userinfo } = props;
|
const { auth, userinfo } = props;
|
||||||
|
|
||||||
if (!auth || (auth && !auth.requires_client_login)) return null;
|
const randomInt = Math.random() * 15;
|
||||||
|
const sexIndex = Math.floor(randomInt / 5);
|
||||||
|
const skinToneIndex = Math.floor(randomInt % 5);
|
||||||
|
|
||||||
|
const scientist = String.fromCodePoint(
|
||||||
|
BASE_EMOJI[sexIndex],
|
||||||
|
SKIN_TONES[skinToneIndex],
|
||||||
|
ZERO_WIDTH_JOINER,
|
||||||
|
MICROSCOPE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!auth?.["requires_client_login"]) return null;
|
||||||
|
|
||||||
|
if (userinfo?.["is_authenticated"]) {
|
||||||
|
const PopoverContent = (
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
data-testid="user-email"
|
||||||
|
text={`Logged in as: ${userinfo.email}`}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
data-testid="log-out"
|
||||||
|
text="Log Out"
|
||||||
|
href={auth.logout}
|
||||||
|
icon={IconNames.LOG_OUT}
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover content={PopoverContent}>
|
||||||
|
<Button className={styles.menubarButton} style={{ padding: 0 }}>
|
||||||
|
{userinfo?.picture ? (
|
||||||
|
<img alt="profile" src={userinfo?.picture} />
|
||||||
|
) : (
|
||||||
|
<span style={{ fontSize: "18px" }}>{scientist}</span>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ButtonGroup className={styles.menubarButton}>
|
<Tooltip
|
||||||
<Tooltip
|
content="Log in to cellxgene"
|
||||||
content="Log in to cellxgene"
|
position="bottom"
|
||||||
position="bottom"
|
hoverOpenDelay={globals.tooltipHoverOpenDelay}
|
||||||
hoverOpenDelay={globals.tooltipHoverOpenDelay}
|
>
|
||||||
|
<AnchorButton
|
||||||
|
type="button"
|
||||||
|
data-testid="log-in"
|
||||||
|
disabled={false}
|
||||||
|
href={auth.login}
|
||||||
|
className={styles.menubarButton}
|
||||||
>
|
>
|
||||||
<AnchorButton
|
Log In
|
||||||
type="button"
|
</AnchorButton>
|
||||||
data-testid="auth-button"
|
</Tooltip>
|
||||||
disabled={false}
|
|
||||||
href={!userinfo.is_authenticated ? auth.login : auth.logout}
|
|
||||||
>
|
|
||||||
{!userinfo.is_authenticated ? "Log In" : "Log Out"}
|
|
||||||
</AnchorButton>
|
|
||||||
</Tooltip>
|
|
||||||
</ButtonGroup>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import styles from "./menubar.css";
|
|||||||
import actions from "../../actions";
|
import actions from "../../actions";
|
||||||
import Clip from "./clip";
|
import Clip from "./clip";
|
||||||
|
|
||||||
|
import AuthButtons from "./authButtons";
|
||||||
import Subset from "./subset";
|
import Subset from "./subset";
|
||||||
import UndoRedoReset from "./undoRedo";
|
import UndoRedoReset from "./undoRedo";
|
||||||
import DiffexpButtons from "./diffexpButtons";
|
import DiffexpButtons from "./diffexpButtons";
|
||||||
@@ -216,6 +217,8 @@ class MenuBar extends React.PureComponent {
|
|||||||
subsetPossible,
|
subsetPossible,
|
||||||
subsetResetPossible,
|
subsetResetPossible,
|
||||||
enableReembedding,
|
enableReembedding,
|
||||||
|
userinfo,
|
||||||
|
auth,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { pendingClipPercentiles } = this.state;
|
const { pendingClipPercentiles } = this.state;
|
||||||
|
|
||||||
@@ -241,6 +244,7 @@ class MenuBar extends React.PureComponent {
|
|||||||
zIndex: 3,
|
zIndex: 3,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<AuthButtons auth={auth} userinfo={userinfo} />
|
||||||
<UndoRedoReset
|
<UndoRedoReset
|
||||||
dispatch={dispatch}
|
dispatch={dispatch}
|
||||||
undoDisabled={undoDisabled}
|
undoDisabled={undoDisabled}
|
||||||
|
|||||||
@@ -1,108 +0,0 @@
|
|||||||
// jshint esversion: 6
|
|
||||||
import React from "react";
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
ButtonGroup,
|
|
||||||
Classes,
|
|
||||||
Menu,
|
|
||||||
MenuItem,
|
|
||||||
Popover,
|
|
||||||
Position,
|
|
||||||
} from "@blueprintjs/core";
|
|
||||||
import styles from "./menubar.css";
|
|
||||||
|
|
||||||
const handleClick = (dispatch) => {
|
|
||||||
dispatch({ type: "toggle dataset drawer" });
|
|
||||||
};
|
|
||||||
|
|
||||||
const InformationMenu = React.memo((props) => {
|
|
||||||
const {
|
|
||||||
libraryVersions,
|
|
||||||
tosURL,
|
|
||||||
privacyURL,
|
|
||||||
auth,
|
|
||||||
userinfo,
|
|
||||||
dispatch,
|
|
||||||
} = props;
|
|
||||||
return (
|
|
||||||
<ButtonGroup className={`${styles.menubarButton}`}>
|
|
||||||
<Popover
|
|
||||||
content={
|
|
||||||
<Menu>
|
|
||||||
<MenuItem
|
|
||||||
onClick={() => handleClick(dispatch)}
|
|
||||||
icon="info-sign"
|
|
||||||
text="Dataset Overview"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<MenuItem
|
|
||||||
href="https://chanzuckerberg.github.io/cellxgene/"
|
|
||||||
target="_blank"
|
|
||||||
icon="book"
|
|
||||||
text="Documentation"
|
|
||||||
rel="noopener"
|
|
||||||
/>
|
|
||||||
<MenuItem
|
|
||||||
href="https://join-cellxgene-users.herokuapp.com/"
|
|
||||||
target="_blank"
|
|
||||||
icon="chat"
|
|
||||||
text="Chat"
|
|
||||||
rel="noopener"
|
|
||||||
/>
|
|
||||||
<MenuItem
|
|
||||||
href="https://github.com/chanzuckerberg/cellxgene"
|
|
||||||
target="_blank"
|
|
||||||
icon="git-branch"
|
|
||||||
text="Github"
|
|
||||||
rel="noopener"
|
|
||||||
/>
|
|
||||||
<MenuItem
|
|
||||||
target="_blank"
|
|
||||||
text={
|
|
||||||
libraryVersions && libraryVersions.cellxgene
|
|
||||||
? libraryVersions.cellxgene
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<MenuItem text="MIT License" />
|
|
||||||
{tosURL ? (
|
|
||||||
<MenuItem href={tosURL} target="_blank" text="Terms of Service" />
|
|
||||||
) : null}
|
|
||||||
{privacyURL ? (
|
|
||||||
<MenuItem
|
|
||||||
href={privacyURL}
|
|
||||||
target="_blank"
|
|
||||||
text="Privacy Policy"
|
|
||||||
rel="noopener"
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{auth?.["requires_client_login"] &&
|
|
||||||
userinfo?.["is_authenticated"] ? (
|
|
||||||
<>
|
|
||||||
<MenuItem text={`Logged in as: ${userinfo.email}`} />
|
|
||||||
<MenuItem text="Log Out" href={auth.logout} />
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</Menu>
|
|
||||||
}
|
|
||||||
position={Position.BOTTOM_RIGHT}
|
|
||||||
modifiers={{
|
|
||||||
preventOverflow: { enabled: false },
|
|
||||||
hide: { enabled: false },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
data-testid="menu"
|
|
||||||
type="button"
|
|
||||||
className={`${Classes.BUTTON} bp3-icon-info-sign`}
|
|
||||||
style={{
|
|
||||||
cursor: "pointer",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Popover>
|
|
||||||
</ButtonGroup>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
export default InformationMenu;
|
|
||||||
Reference in New Issue
Block a user