add realm selector (#48)

* WIP realm selector

* realm dropdown is working

* address PR feedback

* address PR feedback and fix conflicts

* fix formatting

* fix path

* address PR feedback from Stan

* update snapshot tests

* fix formatting

* change minwidth
This commit is contained in:
Eugenia 2020-09-04 14:16:11 -04:00 committed by GitHub
parent 87d8414bd7
commit c6a310a827
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 684 additions and 14 deletions

View file

@ -3,3 +3,7 @@
.pf-c-brand { .pf-c-brand {
height: 35px; height: 35px;
} }
button.pf-c-button.pf-m-primary.realmSelectButton {
width: 100%;
}

View file

@ -2,13 +2,13 @@ import React from "react";
import { Nav, NavItem, NavList, PageSidebar } from "@patternfly/react-core"; import { Nav, NavItem, NavList, PageSidebar } from "@patternfly/react-core";
import { RealmSelector } from "./components/realm-selector/RealmSelector"; import { RealmSelector } from "./components/realm-selector/RealmSelector";
export const PageNav = () => { export const PageNav: React.FunctionComponent = () => {
return ( return (
<PageSidebar <PageSidebar
nav={ nav={
<Nav> <Nav>
<NavList> <NavList>
<RealmSelector realm="Master" realmList={["Photoz"]} /> <RealmSelector />
<NavItem id="default-link1" to="/default-link1" itemId={0}> <NavItem id="default-link1" to="/default-link1" itemId={0}>
Link 1 Link 1
</NavItem> </NavItem>

View file

@ -0,0 +1,33 @@
import React from "react";
import { Button, AlertVariant } from "@patternfly/react-core";
import { mount } from "enzyme";
import EnzymeToJson from "enzyme-to-json";
import { act } from "react-dom/test-utils";
import { RealmSelector } from "./RealmSelector";
const WithButton = () => {
const [add, alerts, hide] = useAlerts();
return (
<>
<AlertPanel alerts={alerts} onCloseAlert={hide} />
<Button onClick={() => add("Hello", AlertVariant.default)}>Add</Button>
</>
);
};
it("renders realm selector", () => {
const tree = mount(<RealmSelector />);
const button = tree.find("button");
expect(button).not.toBeNull();
act(() => {
button!.simulate("click");
});
expect(EnzymeToJson(tree)).toMatchSnapshot();
act(() => {
jest.runAllTimers();
});
expect(EnzymeToJson(tree)).toMatchSnapshot();
});

View file

@ -1,27 +1,48 @@
import React, { useState } from "react"; import React, { useState, useContext, useEffect } from "react";
import { useHistory } from "react-router-dom"; import { useHistory } from "react-router-dom";
import { Realm } from "../../models/Realm";
import { import {
Dropdown, Dropdown,
DropdownToggle, DropdownToggle,
DropdownItem, DropdownItem,
Button, Button,
Divider,
} from "@patternfly/react-core"; } from "@patternfly/react-core";
import style from "./realm-selector.module.css"; import style from "./realm-selector.module.css";
import { HttpClientContext } from "../../http-service/HttpClientContext";
type RealmSelectorProps = { export const RealmSelector = () => {
realm: string;
realmList: string[];
};
export const RealmSelector = ({ realm, realmList }: RealmSelectorProps) => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const history = useHistory(); const history = useHistory();
const dropdownItems = realmList.map((r) => ( const httpClient = useContext(HttpClientContext);
<DropdownItem component="a" href="/" key={r}> const [realms, setRealms] = useState([] as Realm[]);
{r} const [currentRealm, setCurrentRealm] = useState("Master");
const getRealms = async () => {
return await httpClient
?.doGet("/admin/realms")
.then((r) => r.data as Realm[]);
};
useEffect(() => {
getRealms().then((result) => {
setRealms(result) !== undefined ? result : [];
});
}, []);
const dropdownItems = realms.map((r) => (
<DropdownItem
component="a"
href={"/#/realms/" + r.id}
key={r.id}
onClick={() => setCurrentRealm(r.realm)}
>
{r.realm.charAt(0).toUpperCase() + r.realm.slice(1)}
</DropdownItem> </DropdownItem>
)); ));
return ( return (
<Dropdown <Dropdown
id="realm-select" id="realm-select"
@ -33,13 +54,19 @@ export const RealmSelector = ({ realm, realmList }: RealmSelectorProps) => {
onToggle={() => setOpen(!open)} onToggle={() => setOpen(!open)}
className={style.toggle} className={style.toggle}
> >
{realm} {currentRealm}
</DropdownToggle> </DropdownToggle>
} }
dropdownItems={[ dropdownItems={[
...dropdownItems, ...dropdownItems,
<Divider key={1} />,
<DropdownItem component="div" key="add"> <DropdownItem component="div" key="add">
<Button onClick={() => history.push("/add-realm")}>Add Realm</Button> <Button
className="realmSelectButton"
onClick={() => history.push("/add-realm")}
>
Create Realm
</Button>
</DropdownItem>, </DropdownItem>,
]} ]}
/> />

View file

@ -0,0 +1,587 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders realm selector 1`] = `
<RealmSelector>
<Dropdown
dropdownItems={
Array [
<Divider />,
<DropdownItem
component="div"
>
<Button
className="realmSelectButton"
onClick={[Function]}
>
Create Realm
</Button>
</DropdownItem>,
]
}
id="realm-select"
isOpen={false}
toggle={
<DropdownToggle
id="realm-select-toggle"
onToggle={[Function]}
>
Master
</DropdownToggle>
}
>
<DropdownWithContext
autoFocus={true}
className=""
direction="down"
dropdownItems={
Array [
<Divider />,
<DropdownItem
component="div"
>
<Button
className="realmSelectButton"
onClick={[Function]}
>
Create Realm
</Button>
</DropdownItem>,
]
}
id="realm-select"
isGrouped={false}
isOpen={false}
isPlain={false}
menuAppendTo="inline"
onSelect={[Function]}
position="left"
toggle={
<DropdownToggle
id="realm-select-toggle"
onToggle={[Function]}
>
Master
</DropdownToggle>
}
>
<div
className="pf-c-dropdown"
data-ouia-component-id={0}
data-ouia-component-type="PF4/Dropdown"
data-ouia-safe={true}
id="realm-select"
>
<DropdownToggle
aria-haspopup={true}
getMenuRef={[Function]}
id="realm-select-toggle"
isOpen={false}
isPlain={false}
key=".0"
onEnter={[Function]}
onToggle={[Function]}
parentRef={
Object {
"current": <div
class="pf-c-dropdown pf-m-expanded"
data-ouia-component-id="1"
data-ouia-component-type="PF4/Dropdown"
data-ouia-safe="true"
id="realm-select"
>
<button
aria-expanded="true"
aria-haspopup="true"
class="pf-c-dropdown__toggle"
id="realm-select-toggle"
type="button"
>
<span
class="pf-c-dropdown__toggle-text"
>
Master
</span>
<span
class="pf-c-dropdown__toggle-icon"
>
<svg
aria-hidden="true"
fill="currentColor"
height="1em"
role="img"
style="vertical-align: -0.125em;"
viewBox="0 0 320 512"
width="1em"
>
<path
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
transform=""
/>
</svg>
</span>
</button>
<ul
aria-labelledby="realm-select-toggle"
class="pf-c-dropdown__menu"
role="menu"
>
<hr
class="pf-c-divider"
index="0"
/>
<li
role="menuitem"
>
<div
class="pf-c-dropdown__menu-item"
tabindex="-1"
>
<button
aria-disabled="false"
class="pf-c-button pf-m-primary realmSelectButton"
data-ouia-component-id="2"
data-ouia-component-type="PF4/Button"
data-ouia-safe="true"
type="button"
>
Create Realm
</button>
</div>
</li>
</ul>
</div>,
}
}
>
<Toggle
aria-haspopup={true}
bubbleEvent={false}
className=""
getMenuRef={[Function]}
id="realm-select-toggle"
isActive={false}
isDisabled={false}
isOpen={false}
isPlain={false}
isPrimary={false}
isSplitButton={false}
onEnter={[Function]}
onToggle={[Function]}
parentRef={
Object {
"current": <div
class="pf-c-dropdown pf-m-expanded"
data-ouia-component-id="1"
data-ouia-component-type="PF4/Dropdown"
data-ouia-safe="true"
id="realm-select"
>
<button
aria-expanded="true"
aria-haspopup="true"
class="pf-c-dropdown__toggle"
id="realm-select-toggle"
type="button"
>
<span
class="pf-c-dropdown__toggle-text"
>
Master
</span>
<span
class="pf-c-dropdown__toggle-icon"
>
<svg
aria-hidden="true"
fill="currentColor"
height="1em"
role="img"
style="vertical-align: -0.125em;"
viewBox="0 0 320 512"
width="1em"
>
<path
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
transform=""
/>
</svg>
</span>
</button>
<ul
aria-labelledby="realm-select-toggle"
class="pf-c-dropdown__menu"
role="menu"
>
<hr
class="pf-c-divider"
index="0"
/>
<li
role="menuitem"
>
<div
class="pf-c-dropdown__menu-item"
tabindex="-1"
>
<button
aria-disabled="false"
class="pf-c-button pf-m-primary realmSelectButton"
data-ouia-component-id="2"
data-ouia-component-type="PF4/Button"
data-ouia-safe="true"
type="button"
>
Create Realm
</button>
</div>
</li>
</ul>
</div>,
}
}
>
<button
aria-expanded={false}
aria-haspopup={true}
className="pf-c-dropdown__toggle"
disabled={false}
id="realm-select-toggle"
onClick={[Function]}
onKeyDown={[Function]}
type="button"
>
<span
className="pf-c-dropdown__toggle-text"
>
Master
</span>
<span
className="pf-c-dropdown__toggle-icon"
>
<CaretDownIcon
color="currentColor"
noVerticalAlign={false}
size="sm"
>
<svg
aria-hidden={true}
aria-labelledby={null}
fill="currentColor"
height="1em"
role="img"
style={
Object {
"verticalAlign": "-0.125em",
}
}
viewBox="0 0 320 512"
width="1em"
>
<path
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
transform=""
/>
</svg>
</CaretDownIcon>
</span>
</button>
</Toggle>
</DropdownToggle>
</div>
</DropdownWithContext>
</Dropdown>
</RealmSelector>
`;
exports[`renders realm selector 2`] = `
<RealmSelector>
<Dropdown
dropdownItems={
Array [
<Divider />,
<DropdownItem
component="div"
>
<Button
className="realmSelectButton"
onClick={[Function]}
>
Create Realm
</Button>
</DropdownItem>,
]
}
id="realm-select"
isOpen={false}
toggle={
<DropdownToggle
id="realm-select-toggle"
onToggle={[Function]}
>
Master
</DropdownToggle>
}
>
<DropdownWithContext
autoFocus={true}
className=""
direction="down"
dropdownItems={
Array [
<Divider />,
<DropdownItem
component="div"
>
<Button
className="realmSelectButton"
onClick={[Function]}
>
Create Realm
</Button>
</DropdownItem>,
]
}
id="realm-select"
isGrouped={false}
isOpen={false}
isPlain={false}
menuAppendTo="inline"
onSelect={[Function]}
position="left"
toggle={
<DropdownToggle
id="realm-select-toggle"
onToggle={[Function]}
>
Master
</DropdownToggle>
}
>
<div
className="pf-c-dropdown"
data-ouia-component-id={0}
data-ouia-component-type="PF4/Dropdown"
data-ouia-safe={true}
id="realm-select"
>
<DropdownToggle
aria-haspopup={true}
getMenuRef={[Function]}
id="realm-select-toggle"
isOpen={false}
isPlain={false}
key=".0"
onEnter={[Function]}
onToggle={[Function]}
parentRef={
Object {
"current": <div
class="pf-c-dropdown pf-m-expanded"
data-ouia-component-id="1"
data-ouia-component-type="PF4/Dropdown"
data-ouia-safe="true"
id="realm-select"
>
<button
aria-expanded="true"
aria-haspopup="true"
class="pf-c-dropdown__toggle"
id="realm-select-toggle"
type="button"
>
<span
class="pf-c-dropdown__toggle-text"
>
Master
</span>
<span
class="pf-c-dropdown__toggle-icon"
>
<svg
aria-hidden="true"
fill="currentColor"
height="1em"
role="img"
style="vertical-align: -0.125em;"
viewBox="0 0 320 512"
width="1em"
>
<path
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
transform=""
/>
</svg>
</span>
</button>
<ul
aria-labelledby="realm-select-toggle"
class="pf-c-dropdown__menu"
role="menu"
>
<hr
class="pf-c-divider"
index="0"
/>
<li
role="menuitem"
>
<div
class="pf-c-dropdown__menu-item"
tabindex="-1"
>
<button
aria-disabled="false"
class="pf-c-button pf-m-primary realmSelectButton"
data-ouia-component-id="2"
data-ouia-component-type="PF4/Button"
data-ouia-safe="true"
type="button"
>
Create Realm
</button>
</div>
</li>
</ul>
</div>,
}
}
>
<Toggle
aria-haspopup={true}
bubbleEvent={false}
className=""
getMenuRef={[Function]}
id="realm-select-toggle"
isActive={false}
isDisabled={false}
isOpen={false}
isPlain={false}
isPrimary={false}
isSplitButton={false}
onEnter={[Function]}
onToggle={[Function]}
parentRef={
Object {
"current": <div
class="pf-c-dropdown pf-m-expanded"
data-ouia-component-id="1"
data-ouia-component-type="PF4/Dropdown"
data-ouia-safe="true"
id="realm-select"
>
<button
aria-expanded="true"
aria-haspopup="true"
class="pf-c-dropdown__toggle"
id="realm-select-toggle"
type="button"
>
<span
class="pf-c-dropdown__toggle-text"
>
Master
</span>
<span
class="pf-c-dropdown__toggle-icon"
>
<svg
aria-hidden="true"
fill="currentColor"
height="1em"
role="img"
style="vertical-align: -0.125em;"
viewBox="0 0 320 512"
width="1em"
>
<path
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
transform=""
/>
</svg>
</span>
</button>
<ul
aria-labelledby="realm-select-toggle"
class="pf-c-dropdown__menu"
role="menu"
>
<hr
class="pf-c-divider"
index="0"
/>
<li
role="menuitem"
>
<div
class="pf-c-dropdown__menu-item"
tabindex="-1"
>
<button
aria-disabled="false"
class="pf-c-button pf-m-primary realmSelectButton"
data-ouia-component-id="2"
data-ouia-component-type="PF4/Button"
data-ouia-safe="true"
type="button"
>
Create Realm
</button>
</div>
</li>
</ul>
</div>,
}
}
>
<button
aria-expanded={false}
aria-haspopup={true}
className="pf-c-dropdown__toggle"
disabled={false}
id="realm-select-toggle"
onClick={[Function]}
onKeyDown={[Function]}
type="button"
>
<span
className="pf-c-dropdown__toggle-text"
>
Master
</span>
<span
className="pf-c-dropdown__toggle-icon"
>
<CaretDownIcon
color="currentColor"
noVerticalAlign={false}
size="sm"
>
<svg
aria-hidden={true}
aria-labelledby={null}
fill="currentColor"
height="1em"
role="img"
style={
Object {
"verticalAlign": "-0.125em",
}
}
viewBox="0 0 320 512"
width="1em"
>
<path
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
transform=""
/>
</svg>
</CaretDownIcon>
</span>
</button>
</Toggle>
</DropdownToggle>
</div>
</DropdownWithContext>
</Dropdown>
</RealmSelector>
`;

View file

@ -1,11 +1,26 @@
.dropdown { .dropdown {
width: 100%; width: 100%;
padding: 32px;
border-bottom: 1px solid var(--pf-c-nav__link--before--BorderColor); border-bottom: 1px solid var(--pf-c-nav__link--before--BorderColor);
outline: 1px solid var(--pf-global--Color--200);
outline-offset:-32px;
}
.menu {
/* setting this to 85% for now */
min-width: 85%;
}
.pf-c-button.pf-m-primary.realmSelectButton {
width: 100%;
} }
.toggle { .toggle {
color: var(--pf-c-nav__link--m-current--Color); color: var(--pf-c-nav__link--m-current--Color);
width: 100%;
background: var(--pf-global--BackgroundColor--dark-100);
} }
.toggle:focus { .toggle:focus {

4
src/models/Realm.ts Normal file
View file

@ -0,0 +1,4 @@
export interface Realm {
id: string;
realm: string;
}