Skip to content

Commit

Permalink
thuang-1840-authn-prompt
Browse files Browse the repository at this point in the history
  • Loading branch information
tihuan committed Oct 8, 2020
1 parent 6677d0d commit e0cfc1a
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 28 deletions.
96 changes: 91 additions & 5 deletions client/src/components/menubar/authButtons.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,42 @@
import React from "react";
import React, { useState } from "react";

import {
AnchorButton,
Button,
MenuItem,
Tooltip,
Popover,
Menu,
Elevation,
PopoverPosition,
Checkbox,
Card,
} from "@blueprintjs/core";

import { IconNames } from "@blueprintjs/icons";

import * as globals from "../../globals";

import styles from "./menubar.css";

import { storageGet, storageSet, KEYS } from "../util/localStorage";

const BASE_EMOJI = [0x1f9d1, 0x1f468, 0x1f469];
const SKIN_TONES = [0x1f3fb, 0x1f3fc, 0x1f3fd, 0x1f3fe, 0x1f3ff];
const MICROSCOPE = 0x1f52c;
const ZERO_WIDTH_JOINER = 0x0200d;

const LOGIN_PROMPT_OFF = "off";

const Auth = React.memo((props) => {
const [isPromptOpen, setIsPromptOpen] = useState(shouldShowPrompt());

const { auth, userinfo } = props;

const isAuthenticated = userinfo && userinfo.is_authenticated;

window.userinfo = userinfo;

const randomInt = Math.random() * 15;
const sexIndex = Math.floor(randomInt / 5);
const skinToneIndex = Math.floor(randomInt % 5);
Expand All @@ -31,9 +48,9 @@ const Auth = React.memo((props) => {
MICROSCOPE
);

if (!auth?.["requires_client_login"]) return null;
if (!shouldShowAuth()) return null;

if (userinfo?.["is_authenticated"]) {
if (isAuthenticated) {
const PopoverContent = (
<Menu>
<MenuItem
Expand Down Expand Up @@ -67,7 +84,7 @@ const Auth = React.memo((props) => {
);
}

return (
const LoginButton = (
<Tooltip
content="Log in to cellxgene"
position="bottom"
Expand All @@ -76,14 +93,83 @@ const Auth = React.memo((props) => {
<AnchorButton
type="button"
data-testid="log-in"
disabled={false}
href={auth.login}
className={styles.menubarButton}
>
Log In
</AnchorButton>
</Tooltip>
);

if (isPromptOpen) {
return (
<Popover
position={PopoverPosition.AUTO_END}
isOpen
content={<PromptContent setIsPromptOpen={setIsPromptOpen} />}
onInteraction={setIsPromptOpen}
>
{LoginButton}
</Popover>
);
}

return LoginButton;

function shouldShowAuth() {
return auth && auth.requires_client_login;
}

function shouldShowPrompt() {
if (storageGet(KEYS.LOGIN_PROMPT) === LOGIN_PROMPT_OFF) return false;

return shouldShowAuth && !isAuthenticated;
}
});

function PromptContent({ setIsPromptOpen }) {
const [isChecked, setIsChecked] = useState(false);

function handleOKClick() {
if (isChecked) {
storageSet(KEYS.LOGIN_PROMPT, LOGIN_PROMPT_OFF);
}

setIsPromptOpen(false);
}

function handleCheckboxChange() {
setIsChecked(!isChecked);
}

return (
<Card style={{ width: "500px" }} elevation={Elevation.TWO}>
<p>
Logging in will enable you to create your own categories and labels.
Logging in later will reset cellxgene to the default view and cause you
to lose progress.
</p>
<Checkbox
style={{ width: "230px" }}
checked={isChecked}
onChange={handleCheckboxChange}
data-testid="login-hint-do-not-show-again"
>
Do not show me this message again
</Checkbox>
<div
style={{ display: "flex", justifyContent: "flex-end", marginTop: 15 }}
>
<Button
onClick={handleOKClick}
intent="primary"
data-testid="login-hint-yes"
>
Acknowledge
</Button>
</div>
</Card>
);
}

export default Auth;
27 changes: 4 additions & 23 deletions client/src/components/termsPrompt/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,7 @@ import {
Colors,
Icon,
} from "@blueprintjs/core";

const CookieDecision = "cxg.cookieDecision";

function storageGet(key, defaultValue = null) {
try {
const val = window.localStorage.getItem(key);
if (val === null) return defaultValue;
return val;
} catch (e) {
return defaultValue;
}
}

function storageSet(key, value) {
try {
window.localStorage.setItem(key, value);
} catch {
// continue
}
}
import { storageGet, storageSet, KEYS } from "../util/localStorage";

@connect((state) => ({
tosURL: state.config?.parameters?.["about_legal_tos"],
Expand All @@ -37,7 +18,7 @@ class TermsPrompt extends React.PureComponent {
constructor(props) {
super(props);
const { tosURL, privacyURL } = this.props;
const cookieDecision = storageGet(CookieDecision, null);
const cookieDecision = storageGet(KEYS.COOKIE_DECISION, null);
const hasDecided = cookieDecision !== null;
this.state = {
hasDecided,
Expand All @@ -55,7 +36,7 @@ class TermsPrompt extends React.PureComponent {

handleOK = () => {
this.setState({ isOpen: false });
storageSet(CookieDecision, "yes");
storageSet(KEYS.COOKIE_DECISION, "yes");
if (window.cookieDecisionCallback instanceof Function) {
try {
window.cookieDecisionCallback();
Expand All @@ -67,7 +48,7 @@ class TermsPrompt extends React.PureComponent {

handleNo = () => {
this.setState({ isOpen: false });
storageSet(CookieDecision, "no");
storageSet(KEYS.COOKIE_DECISION, "no");
};

renderTos() {
Expand Down
22 changes: 22 additions & 0 deletions client/src/components/util/localStorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export const KEYS = {
COOKIE_DECISION: "cxg.cookieDecision",
LOGIN_PROMPT: "cxg.LOGIN_PROMPT",
};

export function storageGet(key, defaultValue = null) {
try {
const val = window.localStorage.getItem(key);
if (val === null) return defaultValue;
return val;
} catch (e) {
return defaultValue;
}
}

export function storageSet(key, value) {
try {
window.localStorage.setItem(key, value);
} catch {
// continue
}
}

0 comments on commit e0cfc1a

Please sign in to comment.