diff --git a/frontend/packages/core/package.json b/frontend/packages/core/package.json
index fb5f3cc6de..7e6782bbb2 100644
--- a/frontend/packages/core/package.json
+++ b/frontend/packages/core/package.json
@@ -16,7 +16,8 @@
"react-dom": "^16.12.0",
"react-helmet":"5.2.1",
"tinycolor2": "1.4.1",
- "react-addons-text-content": "0.0.4"
+ "react-addons-text-content": "0.0.4",
+ "recompose": "0.30.0"
},
"scripts": {
"lint": "web-scripts lint",
diff --git a/frontend/packages/core/src/assets/bursts/bursts.css b/frontend/packages/core/src/assets/bursts/bursts.css
deleted file mode 100644
index 92499bf056..0000000000
--- a/frontend/packages/core/src/assets/bursts/bursts.css
+++ /dev/null
@@ -1,19 +0,0 @@
-
-.burst {
- position: absolute;
- top: 0;
- left: 0;
- height: 100%;
- width: 100%;
- z-index: -1;
-}
-
-/* base style of burst shape SVGs */
-.burst-shape {
- position: absolute;
- right: 0;
- height: 100%;
- background-repeat: no-repeat;
- background-size: cover;
- opacity:0.1;
-}
diff --git a/frontend/packages/core/src/assets/bursts/circle-1.svg b/frontend/packages/core/src/assets/bursts/circle-1.svg
deleted file mode 100644
index 9ee5157ab8..0000000000
--- a/frontend/packages/core/src/assets/bursts/circle-1.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/frontend/packages/core/src/assets/bursts/circle-2.svg b/frontend/packages/core/src/assets/bursts/circle-2.svg
deleted file mode 100644
index 15b89e96db..0000000000
--- a/frontend/packages/core/src/assets/bursts/circle-2.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/frontend/packages/core/src/assets/bursts/rectangle-1.svg b/frontend/packages/core/src/assets/bursts/rectangle-1.svg
deleted file mode 100644
index 4403b0031a..0000000000
--- a/frontend/packages/core/src/assets/bursts/rectangle-1.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/frontend/packages/core/src/assets/bursts/rectangle-2.svg b/frontend/packages/core/src/assets/bursts/rectangle-2.svg
deleted file mode 100644
index 2d307d75f6..0000000000
--- a/frontend/packages/core/src/assets/bursts/rectangle-2.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/frontend/packages/core/src/assets/bursts/rectangle-3.svg b/frontend/packages/core/src/assets/bursts/rectangle-3.svg
deleted file mode 100644
index 947df51df9..0000000000
--- a/frontend/packages/core/src/assets/bursts/rectangle-3.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/frontend/packages/core/src/assets/bursts/triangle-1.svg b/frontend/packages/core/src/assets/bursts/triangle-1.svg
deleted file mode 100644
index 7a33cf3f5c..0000000000
--- a/frontend/packages/core/src/assets/bursts/triangle-1.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/frontend/packages/core/src/assets/bursts/triangle-2.svg b/frontend/packages/core/src/assets/bursts/triangle-2.svg
deleted file mode 100644
index 184e714b89..0000000000
--- a/frontend/packages/core/src/assets/bursts/triangle-2.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/frontend/packages/core/src/assets/bursts/triangle-3.svg b/frontend/packages/core/src/assets/bursts/triangle-3.svg
deleted file mode 100644
index e8b0cb1f7c..0000000000
--- a/frontend/packages/core/src/assets/bursts/triangle-3.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/frontend/packages/core/src/components/Lifecycle/Lifecycle.js b/frontend/packages/core/src/components/Lifecycle/Lifecycle.js
new file mode 100644
index 0000000000..5c11599f92
--- /dev/null
+++ b/frontend/packages/core/src/components/Lifecycle/Lifecycle.js
@@ -0,0 +1,44 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+class Lifecycle extends Component {
+ static propTypes = {
+ isShorthand: PropTypes.bool,
+ fontSize: PropTypes.string,
+ };
+}
+
+const styles = {
+ alpha: {
+ color: '#d00150',
+ fontFamily: 'serif',
+ fontWeight: 'normal',
+ fontStyle: 'italic',
+ },
+ beta: {
+ color: '#4d65cc',
+ fontFamily: 'serif',
+ fontWeight: 'normal',
+ fontStyle: 'italic',
+ },
+};
+
+export class AlphaLabel extends Lifecycle {
+ render() {
+ const style = fontSize => ({ ...styles.alpha, fontSize, ...this.props.style });
+ return this.props.isShorthand ? (
+ α
+ ) : (
+ Alpha
+ );
+ }
+}
+
+export class BetaLabel extends Lifecycle {
+ render() {
+ const fontSize = this.props.fontSize ? this.props.fontSize : this.props.isShorthand ? '120%' : '100%';
+ const style = { ...styles.beta, fontSize, ...this.props.style };
+
+ return this.props.isShorthand ? β : Beta;
+ }
+}
diff --git a/frontend/packages/core/src/components/Lifecycle/index.js b/frontend/packages/core/src/components/Lifecycle/index.js
new file mode 100644
index 0000000000..a5b40c210e
--- /dev/null
+++ b/frontend/packages/core/src/components/Lifecycle/index.js
@@ -0,0 +1 @@
+export { AlphaLabel, BetaLabel } from './Lifecycle';
diff --git a/frontend/packages/core/src/components/Status/Status.js b/frontend/packages/core/src/components/Status/Status.js
new file mode 100644
index 0000000000..04fff2a552
--- /dev/null
+++ b/frontend/packages/core/src/components/Status/Status.js
@@ -0,0 +1,79 @@
+import React from 'react';
+import { pure } from 'recompose';
+import { withStyles } from '@material-ui/core';
+
+const styles = theme => ({
+ status: {
+ width: 12,
+ height: 12,
+ display: 'inline-block',
+ marginRight: 1,
+ },
+ ok: {
+ backgroundColor: theme.palette.status.ok,
+ borderRadius: '50%',
+ },
+ warning: {
+ backgroundColor: theme.palette.status.warning,
+ },
+ error: {
+ width: '0',
+ height: '0',
+ borderLeft: '7px solid transparent',
+ borderRight: '7px solid transparent',
+ borderBottom: `14px solid ${theme.palette.status.error}`,
+ },
+ pending: {
+ backgroundColor: theme.palette.status.pending,
+ },
+ failed: {
+ backgroundColor: 'rgba(245, 155, 35, 0.5)',
+ },
+ running: {
+ animation: 'blink 0.8s step-start 0s infinite',
+ backgroundColor: theme.palette.status.running,
+ },
+ '@keyframes blink': {
+ '50%': {
+ backgroundColor: theme.palette.status.background,
+ },
+ },
+});
+
+export const StatusOK = pure(
+ withStyles(styles)(props => (
+
+ )),
+);
+
+export const StatusWarning = pure(
+ withStyles(styles)(props => (
+
+ )),
+);
+
+export const StatusError = pure(
+ withStyles(styles)(props => (
+
+ )),
+);
+
+export const StatusNA = pure(() => N/A);
+
+export const StatusPending = pure(
+ withStyles(styles)(props => (
+
+ )),
+);
+
+export const StatusRunning = pure(
+ withStyles(styles)(props => (
+
+ )),
+);
+
+export const StatusFailed = pure(
+ withStyles(styles)(props => (
+
+ )),
+);
diff --git a/frontend/packages/core/src/components/Status/index.js b/frontend/packages/core/src/components/Status/index.js
new file mode 100644
index 0000000000..4b037648e3
--- /dev/null
+++ b/frontend/packages/core/src/components/Status/index.js
@@ -0,0 +1 @@
+export { StatusError, StatusFailed, StatusNA, StatusOK, StatusPending, StatusRunning, StatusWarning } from './Status';
diff --git a/frontend/packages/core/src/index.ts b/frontend/packages/core/src/index.ts
index f741f0e384..353b29ff72 100644
--- a/frontend/packages/core/src/index.ts
+++ b/frontend/packages/core/src/index.ts
@@ -1,7 +1,7 @@
export * from './types';
export { default as createPlugin } from './createPlugin';
export { default as Page } from '../src/layout/Page';
-export { shapes, gradients, theme } from '../src/layout/Page';
+export { gradients, theme } from '../src/layout/Page';
export { default as Header } from '../src/layout/Header/Header';
export { default as HeaderLabel } from '../src/layout/HeaderLabel';
export { default as InfoCard } from '../src/layout/InfoCard';
diff --git a/frontend/packages/core/src/layout/Header/Burst.js b/frontend/packages/core/src/layout/Header/Burst.js
index 64d95f7e07..f61da40956 100644
--- a/frontend/packages/core/src/layout/Header/Burst.js
+++ b/frontend/packages/core/src/layout/Header/Burst.js
@@ -1,16 +1,34 @@
-import React, { Component } from 'react';
-import '../../assets/bursts/bursts.css';
+import React from 'react';
+import { makeStyles } from '@material-ui/core';
-class Burst extends Component {
- render() {
- const { theme } = this.props;
-
- return (
-
- );
+const useStyles = makeStyles(theme => ({
+ burst: {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ height: '100%',
+ width: '100%',
+ 'z-index': -1,
+ },
+ /* base style of burst shape SVGs */
+ burstShape: {
+ position: 'absolute',
+ right: 0,
+ height: '100%',
+ 'background-repeat': 'no-repeat',
+ 'background-size': 'cover',
+ opacity:0.1,
}
+}));
+
+const Burst = ({theme}) => {
+ const classes = useStyles();
+
+ return (
+
+ );
}
export default Burst;
diff --git a/frontend/packages/core/src/layout/HeaderActionMenu/HeaderActionMenu.js b/frontend/packages/core/src/layout/HeaderActionMenu/HeaderActionMenu.js
index d16556d4c2..4fc30019a3 100644
--- a/frontend/packages/core/src/layout/HeaderActionMenu/HeaderActionMenu.js
+++ b/frontend/packages/core/src/layout/HeaderActionMenu/HeaderActionMenu.js
@@ -1,6 +1,6 @@
import React, { Fragment } from 'react';
import { IconButton, List, ListItem, ListItemIcon, ListItemText, Popover } from '@material-ui/core';
-import { KebabMenuIcon } from 'shared/icons';
+import { default as KebabMenuIcon } from './MenuVertical';
const ActionItem = ({ label, secondaryLabel, icon, disabled = false, onClick, WrapperComponent = React.Fragment }) => {
return (
diff --git a/frontend/packages/core/src/layout/HeaderActionMenu/MenuVertical.tsx b/frontend/packages/core/src/layout/HeaderActionMenu/MenuVertical.tsx
new file mode 100644
index 0000000000..fa744f861e
--- /dev/null
+++ b/frontend/packages/core/src/layout/HeaderActionMenu/MenuVertical.tsx
@@ -0,0 +1,11 @@
+import React from 'react';
+import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
+
+const SvgMenuVertical = (props: SvgIconProps) =>
+ React.createElement(
+ SvgIcon,
+ props,
+ ,
+ );
+
+export default SvgMenuVertical;
diff --git a/frontend/packages/core/src/layout/HeaderLabel/HeaderLabel.js b/frontend/packages/core/src/layout/HeaderLabel/HeaderLabel.js
index 91290412b3..72f2cc86a0 100644
--- a/frontend/packages/core/src/layout/HeaderLabel/HeaderLabel.js
+++ b/frontend/packages/core/src/layout/HeaderLabel/HeaderLabel.js
@@ -41,7 +41,7 @@ class HeaderLabel extends Component {
return (
{label}
- {url ? {content} : content}
+ {url ? {content} : content}
);
}
diff --git a/frontend/packages/core/src/layout/HeaderLabel/OwnerHeaderLabel.js b/frontend/packages/core/src/layout/HeaderLabel/OwnerHeaderLabel.js
index 5c71c1b6ea..01a694e99a 100644
--- a/frontend/packages/core/src/layout/HeaderLabel/OwnerHeaderLabel.js
+++ b/frontend/packages/core/src/layout/HeaderLabel/OwnerHeaderLabel.js
@@ -1,10 +1,9 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import { Tooltip, withStyles } from '@material-ui/core';
+import { Tooltip, Link, withStyles } from '@material-ui/core';
-import { StatusError } from 'shared/components/Status';
-import Link from 'shared/components/Link';
-import HeaderLabel from 'shared/components/layout/HeaderLabel';
+import { StatusError } from '../../components/Status';
+import HeaderLabel from './HeaderLabel';
const style = theme => ({
notVerified: {
@@ -33,7 +32,7 @@ class OwnerHeaderLabel extends Component {
const isBadSquad = owner.type !== 'squad';
const notVerified = isBadSquad && (
-
+
Squad not verified!
diff --git a/frontend/packages/core/src/layout/HeaderLabel/OwnerHeaderLabel.test.js b/frontend/packages/core/src/layout/HeaderLabel/OwnerHeaderLabel.test.js
index b4e64f64b0..8ced9035e0 100644
--- a/frontend/packages/core/src/layout/HeaderLabel/OwnerHeaderLabel.test.js
+++ b/frontend/packages/core/src/layout/HeaderLabel/OwnerHeaderLabel.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { render } from '@testing-library/react';
+import { render, prettyDOM } from '@testing-library/react';
import OwnerHeaderLabel from './OwnerHeaderLabel';
import { wrapInThemedTestApp } from '../../testUtils';
diff --git a/frontend/packages/core/src/layout/InfoCard/BottomLink.js b/frontend/packages/core/src/layout/InfoCard/BottomLink.js
index c6b259cb72..d248da6063 100644
--- a/frontend/packages/core/src/layout/InfoCard/BottomLink.js
+++ b/frontend/packages/core/src/layout/InfoCard/BottomLink.js
@@ -17,7 +17,7 @@ export default class BottomLink extends Component {
return (
-
+
diff --git a/frontend/packages/core/src/layout/Navigation/GcpProjectByTools.tsx b/frontend/packages/core/src/layout/Navigation/GcpProjectByTools.tsx
deleted file mode 100644
index 104fcee7d3..0000000000
--- a/frontend/packages/core/src/layout/Navigation/GcpProjectByTools.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from 'react';
-import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
-
-const SvgGcpProjectByTools = (props: SvgIconProps) =>
- React.createElement(
- SvgIcon,
- props,
- ,
- );
-
-export default SvgGcpProjectByTools;
diff --git a/frontend/packages/core/src/layout/Navigation/InfoSquared.tsx b/frontend/packages/core/src/layout/Navigation/InfoSquared.tsx
deleted file mode 100644
index 0f51727069..0000000000
--- a/frontend/packages/core/src/layout/Navigation/InfoSquared.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react';
-import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
-
-const SvgInfoSquared = (props: SvgIconProps) =>
- React.createElement(
- SvgIcon,
- props,
- ,
- );
-
-export default SvgInfoSquared;
diff --git a/frontend/packages/core/src/layout/Navigation/NavItem.js b/frontend/packages/core/src/layout/Navigation/NavItem.js
deleted file mode 100644
index b6d47ab9f6..0000000000
--- a/frontend/packages/core/src/layout/Navigation/NavItem.js
+++ /dev/null
@@ -1,168 +0,0 @@
-import React, { Component, Fragment } from 'react';
-import { matchPath } from 'react-router';
-import { ListItem, ListItemIcon, ListItemText, Typography, withStyles, Tooltip, IconButton } from '@material-ui/core';
-import { AlphaLabel, BetaLabel } from 'shared/components/Lifecycle';
-import Link from 'shared/components/Link';
-import { Theme } from 'shared/components/layout/Page';
-import ArrowDropUp from '@material-ui/icons/ArrowDropUp';
-import ArrowDropDown from '@material-ui/icons/ArrowDropDown';
-
-const styles = theme => ({
- root: {
- display: 'block',
- overflow: 'hidden',
- '&:first-child': {
- borderTopRightRadius: 6,
- borderTopLeftRadius: 6,
- },
- '&:last-child': {
- borderBottomRightRadius: 6,
- borderBottomLeftRadius: 6,
- },
- },
- child: {
- paddingLeft: theme.spacing(7),
- '&:last-child': {
- borderBottom: '1px solid #727272',
- },
- },
- boldLabel: {
- color: '#FFFFFF',
- fontWeight: 'bolder',
- },
- childLabel: {
- color: theme.palette.textVerySubtle,
- fontSize: 14,
- },
- label: {
- whiteSpace: 'nowrap',
- lineHeight: 1.0,
- },
- iconImg: {
- width: 24,
- height: 24,
- },
- icon: {
- margin: theme.spacing(0.5, 2, 0.5, 0),
- minWidth: 0,
- },
- expand: {
- color: 'white',
- },
-});
-
-class NavItem extends Component {
- static defaultProps = {
- title: 'Mystery Link',
- href: '/',
- exact: true, // Only used for react-router matchPath to see if this sidebar item is active
- icon: null,
- isAlpha: false,
- isBeta: false,
- type: 'other', // Provided by Navigation
- child: false, // Whether this is a child of another NavItem (for indenting)
- };
-
- // If NavItem has React children, the sub-navigation can be expanded or collapsed
- state = {
- expanded: false,
- };
-
- static isActive(href, exact) {
- return matchPath(window.location.pathname, { path: href, exact: exact });
- }
-
- maybeActiveNavStyle(theme) {
- return NavItem.isActive(this.props.href, this.props.exact)
- ? {
- background: `linear-gradient(to right, ${theme.activeNavLinkColor} 0px, ${theme.activeNavLinkColor} 6px, #4F4F4F 6px, #4F4F4F 100%)`,
- }
- : {};
- }
-
- renderIcon = (condensed, iconElement, title, classes) => {
- if (!iconElement) return null;
- const listItemIcon = {iconElement};
- return condensed ? (
-
- {listItemIcon}
-
- ) : (
- listItemIcon
- );
- };
-
- render() {
- const { title, href, icon, isAlpha, isBeta, classes, condensed, child, children } = this.props;
- const { expanded } = this.state;
- const isSection = !!children;
-
- // Automatically expand nested nav if one of the child elements is active
- const isChildActive = React.Children.toArray(children).some(c => NavItem.isActive(c.props.href, c.props.exact));
- const isExpanded = expanded || isChildActive;
- const selfAwareChildren = children && React.cloneElement(children, { child: true });
-
- let iconElement;
-
- if (icon) {
- iconElement = typeof icon === 'object' ? icon :
;
- }
-
- return (
-
- {theme => (
- <>
-
-
- {this.renderIcon(condensed, iconElement, title, classes)}
- {!condensed && (
- <>
-
- {title}
- {isAlpha && (
-
-
-
-
- )}
- {isBeta && (
-
-
-
-
- )}
-
- }
- disableTypography
- />
- {isSection && (
- this.setState(prev => ({ expanded: !prev.expanded }))}
- style={{ padding: 4 }}
- data-testid="expand-toggle"
- >
- {isExpanded ? (
-
- ) : (
-
- )}
-
- )}
- >
- )}
-
-
- {isExpanded && selfAwareChildren}
- >
- )}
-
- );
- }
-}
-
-export default withStyles(styles)(NavItem);
diff --git a/frontend/packages/core/src/layout/Navigation/NavItem.test.js b/frontend/packages/core/src/layout/Navigation/NavItem.test.js
deleted file mode 100644
index 3cc95b635b..0000000000
--- a/frontend/packages/core/src/layout/Navigation/NavItem.test.js
+++ /dev/null
@@ -1,94 +0,0 @@
-import React from 'react';
-import { matchPath } from 'react-router';
-import { fireEvent, render } from '@testing-library/react';
-import NavItem from './NavItem';
-import { wrapInThemedTestApp } from '../../testUtils';
-
-jest.mock('react-router', () => ({
- ...jest.requireActual('react-router'),
- matchPath: jest.fn(),
-}));
-
-const minProps = {
- title: 'A link title',
- href: '/mocked',
-};
-
-const minChildProps = {
- title: 'A child title',
- href: '/child',
-};
-
-describe('', () => {
- it('renders without exploding', () => {
- const rendered = render(wrapInThemedTestApp());
- expect(rendered.getByText('A link title')).toBeInTheDocument();
- });
-
- it('should have an anchor with correct href', () => {
- const rendered = render(wrapInThemedTestApp());
- const anchor = rendered.container.querySelector('a');
- expect(anchor.href).toBe('http://localhost/mocked');
- });
-
- it('renders with icon src', () => {
- const rendered = render(wrapInThemedTestApp());
- const icon = rendered.getByAltText('A link title');
- expect(icon.src).toBe('http://localhost/mocked-icon.png');
- });
-
- it('renders with icon component', () => {
- const Falafel = () => falafel
;
- const rendered = render(wrapInThemedTestApp(} {...minProps} />));
- const icon = rendered.getByText('falafel');
- expect(icon).toBeInTheDocument();
- });
-
- it('shows alpha icon', () => {
- const rendered = render(wrapInThemedTestApp());
- expect(rendered.getByText('α')).toBeInTheDocument();
- });
-
- it('shows beta icon', () => {
- const rendered = render(wrapInThemedTestApp());
- expect(rendered.getByText('β')).toBeInTheDocument();
- });
-
- it('renders nested navigation without exploding', () => {
- const { getByText, getByTestId } = render(
- wrapInThemedTestApp(
-
-
- ,
- ),
- );
- expect(getByText('A link title')).toBeInTheDocument();
- expect(getByTestId('expand-toggle')).toBeInTheDocument();
- });
-
- it('toggles nested navigation', () => {
- const { getByText, getByTestId, queryByText } = render(
- wrapInThemedTestApp(
-
-
- ,
- ),
- );
- expect(queryByText('A child link')).not.toBeInTheDocument();
- fireEvent.click(getByTestId('expand-toggle'));
- expect(getByText('A child title')).toBeInTheDocument();
- });
-
- it('shows nested navigation automatically if the child is active', () => {
- matchPath.mockReturnValue(true);
- const { getByText } = render(
- wrapInThemedTestApp(
-
-
- ,
- ),
- );
- expect(getByText('A link title')).toBeInTheDocument();
- expect(getByText('A child title')).toBeInTheDocument();
- });
-});
diff --git a/frontend/packages/core/src/layout/Navigation/Navigation.js b/frontend/packages/core/src/layout/Navigation/Navigation.js
deleted file mode 100644
index fc5c15340f..0000000000
--- a/frontend/packages/core/src/layout/Navigation/Navigation.js
+++ /dev/null
@@ -1,91 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { List, withStyles } from '@material-ui/core';
-import ChevronLeft from '@material-ui/icons/ChevronLeft';
-import ChevronRight from '@material-ui/icons/ChevronRight';
-
-import { IconButton } from 'shared/components';
-import { getFromStore, saveToStore } from 'shared/apis/storage/persistentStore';
-
-const styles = theme => ({
- nav: {
- gridArea: 'pageNav',
- width: 62,
- marginLeft: theme.spacing(3),
- marginTop: theme.spacing(3),
- transition: 'width 0.07s, height 0s',
- transitionTimingFunction: 'ease-in',
- },
- item: {
- display: 'block',
- },
- list: {
- padding: 0,
- border: '0px solid #333333',
- borderRadius: 6,
- backgroundColor: '#333333',
- },
- buttonContainer: {
- marginLeft: 'auto',
- marginRight: 'auto',
- marginTop: theme.spacing(0.5),
- width: 48,
- },
- button: {
- color: '#888',
- },
-});
-
-class Navigation extends Component {
- static propTypes = {
- condensable: PropTypes.bool,
- };
-
- state = {
- condensed: false,
- };
-
- constructor(props) {
- super(props);
-
- const condensedPref = getFromStore('navigation', 'condensed', false);
- this.state.condensed = this.props.condensable && condensedPref;
- }
-
- buttonClicked = () => {
- const condensed = !this.state.condensed;
- saveToStore('navigation', 'condensed', condensed);
- this.setState({ condensed });
- };
-
- render() {
- const { classes, condensable } = this.props;
- const { condensed } = this.state;
-
- const ExpandButton = condensable && (
-
-
- {condensed ? : }
-
-
- );
-
- const children = React.Children.map(this.props.children, child => {
- if (!child) return null;
- return React.cloneElement(child, {
- condensed: condensed,
- });
- });
-
- return (
-
- );
- }
-}
-
-export default withStyles(styles)(Navigation);
diff --git a/frontend/packages/core/src/layout/Navigation/Navigation.test.js b/frontend/packages/core/src/layout/Navigation/Navigation.test.js
deleted file mode 100644
index ed18457637..0000000000
--- a/frontend/packages/core/src/layout/Navigation/Navigation.test.js
+++ /dev/null
@@ -1,75 +0,0 @@
-import React from 'react';
-import { render, fireEvent } from '@testing-library/react';
-
-import Navigation from './Navigation';
-import NavItem from './NavItem';
-import { wrapInThemedTestApp } from '../../testUtils';
-
-import { default as GcpProjectIcon } from './GcpProjectByTools';
-import { default as OverviewIcon } from './InfoSquared';
-
-describe('', () => {
- it('renders without exploding', () => {
- const nav = (
-
- } href={'/'} />
- }
- href={'/projects'}
- />
-
- );
- const rendered = render(wrapInThemedTestApp(nav));
- expect(rendered.getByText('Overview')).toBeInTheDocument();
- expect(rendered.getByText('Projects')).toBeInTheDocument();
- });
-
- it('renders a condenseable navigation bar', () => {
- const nav = (
-
- } href={'/'} />
- }
- href={'/projects'}
- />
-
- );
- const rendered = render(wrapInThemedTestApp(nav));
- const btn = rendered.getByTestId('nav-expand-toggle');
- expect(btn).toBeInTheDocument();
- });
-
- it('is condenseable', () => {
- const nav = (
-
- } href={'/'} />
- }
- href={'/projects'}
- />
-
- );
- const rendered = render(wrapInThemedTestApp(nav));
- const btn = rendered.getByTestId('nav-expand-toggle');
- fireEvent.click(btn);
- expect(rendered.queryByText('Overview')).not.toBeInTheDocument();
- });
-
- it('should have an anchor with correct href', () => {
- const nav = (
-
- }
- href={'/projects'}
- />
-
- );
- const rendered = render(wrapInThemedTestApp(nav));
- const anchor = rendered.container.querySelector('a');
- expect(anchor.href).toBe('http://localhost/projects');
- });
-});
diff --git a/frontend/packages/core/src/layout/Page/PageThemeProvider.js b/frontend/packages/core/src/layout/Page/PageThemeProvider.js
index d6832b82d3..60fef3487e 100644
--- a/frontend/packages/core/src/layout/Page/PageThemeProvider.js
+++ b/frontend/packages/core/src/layout/Page/PageThemeProvider.js
@@ -1,52 +1,3 @@
-import '../../assets/bursts/bursts.css';
-import circle1 from '../../assets/bursts/circle-1.svg';
-import circle2 from '../../assets/bursts/circle-2.svg';
-import triangle1 from '../../assets/bursts/triangle-1.svg';
-import triangle2 from '../../assets/bursts/triangle-2.svg';
-import triangle3 from '../../assets/bursts/triangle-3.svg';
-import rectangle1 from '../../assets/bursts/rectangle-1.svg';
-import rectangle2 from '../../assets/bursts/rectangle-2.svg';
-
-// TODO move this file to shared and out of core
-
-export const shapes = {
- circle1: {
- backgroundImage: `url(${circle1})`,
- width: 'calc(400px + 20%)',
- backgroundPosition: '100px 60%',
- },
- circle2: {
- backgroundImage: `url(${circle2})`,
- width: 'calc(400px + 20%)',
- backgroundPosition: '100px 58%',
- },
- rectangle1: {
- backgroundImage: `url(${rectangle1})`,
- width: 'calc(400px + 20%)',
- backgroundPosition: '100px 60%',
- },
- rectangle2: {
- backgroundImage: `url(${rectangle2})`,
- width: 'calc(400px + 20%)',
- backgroundPosition: '30px 35%',
- },
- triangle1: {
- backgroundImage: `url(${triangle1})`,
- width: 'calc(500px + 30%)',
- backgroundPosition: '100px calc(50px + 45%)',
- },
- triangle2: {
- backgroundImage: `url(${triangle2})`,
- width: 'calc(400px + 20%)',
- backgroundPosition: '100px 38%',
- },
- triangle3: {
- backgroundImage: `url(${triangle3})`,
- width: 'calc(400px + 20%)',
- backgroundPosition: '100px 76%',
- },
-};
-
export const gradients = {
blue: 'linear-gradient(135deg, #2D46B9 0%, #509BF5 100%)',
darkBlue: 'linear-gradient(44deg, #1E3264 0%, #A0C3D2 100%)',
@@ -71,102 +22,26 @@ export const theme = {
service: {
activeNavLinkColor: '#1D7F6E',
gradient: gradients.tealGreen,
- burstShape: shapes.rectangle2,
- },
- appFeature: {
- activeNavLinkColor: '#FF6437',
- gradient: gradients.orangeYellow,
- burstShape: shapes.triangle1,
- },
- app: {
- activeNavLinkColor: '#A72525',
- gradient: gradients.redOrange,
- burstShape: shapes.triangle1,
- },
- endpoint: {
- activeNavLinkColor: '#9315b0',
- gradient: gradients.purpleBlue,
- burstShape: shapes.circle1,
- },
- pipeline: {
- activeNavLinkColor: '#9315b0',
- gradient: gradients.purpleBlue,
- burstShape: shapes.circle1,
+ burstShape: null,
},
website: {
activeNavLinkColor: '#765d90',
gradient: gradients.purple,
- burstShape: shapes.rectangle2,
- },
- workflow: {
- activeNavLinkColor: '#AF2996',
- secondary: '#9315b0',
- gradient: gradients.purpleBlue,
- burstShape: shapes.circle1,
- },
- library: {
- activeNavLinkColor: '#B39AC8',
- gradient: gradients.sunset,
- burstShape: shapes.triangle3,
- },
- other: {
- activeNavLinkColor: '#8f6858',
- gradient: gradients.brown,
- burstShape: shapes.rectangle1,
- },
- system: {
- activeNavLinkColor: '#526C90',
- gradient: gradients.darkBlue,
- burstShape: shapes.triangle2,
- },
- project: {
- activeNavLinkColor: '#F13DA2',
- gradient: gradients.pinkOrange,
- burstShape: shapes.triangle3,
- },
- tool: {
- activeNavLinkColor: '#B39AC8',
- gradient: gradients.violetPeach,
- burstShape: shapes.rectangle1,
+ burstShape: null,
},
home: {
activeNavLinkColor: '#00814e',
gradient: gradients.green,
- burstShape: shapes.triangle2,
+ burstShape: null,
},
org: {
activeNavLinkColor: '#6044ef',
gradient: gradients.violetGreen,
- burstShape: shapes.triangle3,
+ burstShape: null,
},
documentation: {
activeNavLinkColor: '#04c2ba',
gradient: gradients.tpm,
- burstShape: shapes.circle2,
- },
- blogPost: {
- activeNavLinkColor: '#FFF',
- gradient: 'linear-gradient(90deg, #033A45 0%, #033A45 100%)',
- burstShape: shapes.circle2,
- },
- machineLearning: {
- activeNavLinkColor: '#0033DD',
- gradient: gradients.royalBlue,
- burstShape: shapes.circle1,
- },
- partnership: {
- activeNavLinkColor: '#000000',
- gradient: gradients.grey,
- burstShape: shapes.rectangle2,
- },
- ml: {
- activeNavLinkColor: '#B39AC8',
- gradient: gradients.blue,
- burstShape: shapes.circle1,
- },
- scienceBox: {
- activeNavLinkColor: '#69B9FF', // matches sky gradient beginning point
- gradient: gradients.sky,
- burstShape: shapes.circle1,
+ burstShape: null,
},
};
\ No newline at end of file
diff --git a/frontend/packages/core/src/layout/Page/index.ts b/frontend/packages/core/src/layout/Page/index.ts
index 889778f7e8..34a8b93753 100644
--- a/frontend/packages/core/src/layout/Page/index.ts
+++ b/frontend/packages/core/src/layout/Page/index.ts
@@ -1,2 +1,2 @@
export { default } from './Page';
-export { shapes, gradients, theme } from './PageThemeProvider';
\ No newline at end of file
+export { gradients, theme } from './PageThemeProvider';
\ No newline at end of file
diff --git a/frontend/packages/core/src/layout/SupportButton/SupportButton.js b/frontend/packages/core/src/layout/SupportButton/SupportButton.js
deleted file mode 100644
index b8663fcb77..0000000000
--- a/frontend/packages/core/src/layout/SupportButton/SupportButton.js
+++ /dev/null
@@ -1,114 +0,0 @@
-import React, { Component, Fragment } from 'react';
-import PropTypes from 'prop-types';
-import { compose } from 'recompose';
-import { List, ListItem, ListItemIcon, Popover, Typography, withStyles } from '@material-ui/core';
-import { withPluginContext } from 'core/app/withPluginContext';
-import { EmailIcon, SlackIcon, SupportIcon } from 'shared/icons';
-import { Button, Link } from 'shared/components';
-import { StackOverflow, StackOverflowTag } from 'shared/components/layout';
-
-class SupportButton extends Component {
- static defaultProps = {
- slackChannel: '#backstage',
- };
-
- static propTypes = {
- slackChannel: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
- };
-
- state = {
- popoverOpen: false,
- anchorEl: null,
- };
-
- button_clickHandler = event => {
- this.setState({ anchorEl: event.currentTarget, popoverOpen: true });
- };
-
- popover_closeHandler = () => {
- this.setState({ popoverOpen: false });
- };
-
- render() {
- const { slackChannel, email, children, classes, plugin } = this.props;
- const tags = plugin ? plugin.stackoverflowTags : undefined; // plugin is undefined on base routes
- const { popoverOpen, anchorEl } = this.state;
- const slackChannels = slackChannel ? (Array.isArray(slackChannel) ? slackChannel : [slackChannel]) : null;
- const contactEmails = email ? (Array.isArray(email) ? email : [email]) : null;
-
- return (
-
-
-
-
- {React.Children.map(children, (child, index) => (
-
- {child}
-
- ))}
- {tags && tags.length > 0 && (
-
-
- {tags.map((tag, idx) => (
-
- ))}
-
-
- )}
- {slackChannels && (
-
-
-
-
-
- Support
- {slackChannels.map((channel, index) => (
-
- {channel}
-
- ))}
-
-
- )}
- {contactEmails && (
-
-
-
-
-
- Contact
- {contactEmails.map((email, index) => (
-
- {email}
-
- ))}
-
-
- )}
-
-
-
- );
- }
-}
-
-const styles = theme => ({
- leftIcon: {
- marginRight: theme.spacing(1),
- },
- popoverList: {
- minWidth: 260,
- maxWidth: 320,
- },
-});
-
-export default compose(withStyles(styles), withPluginContext)(SupportButton);
diff --git a/frontend/packages/core/src/layout/SupportButton/SupportButton.test.js b/frontend/packages/core/src/layout/SupportButton/SupportButton.test.js
deleted file mode 100644
index d008fc42b6..0000000000
--- a/frontend/packages/core/src/layout/SupportButton/SupportButton.test.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from 'react';
-import { render, fireEvent, waitForElement } from '@testing-library/react';
-
-import SupportButton from './SupportButton';
-import { wrapInThemedTestApp, Keyboard } from '../../testUtils';
-
-describe('', () => {
- it('renders without exploding', () => {
- const rendered = render();
- rendered.getByText('Support');
-
- fireEvent.click(rendered.baseElement);
- });
-
- it('should show popover', () => {
- const rendered = render(
- wrapInThemedTestApp(),
- );
-
- expect(rendered.queryByText('Contact')).not.toBeInTheDocument();
- fireEvent.click(rendered.getByText('Support'));
- expect(rendered.queryByText('Contact')).toBeInTheDocument();
- rendered.getByText('a@b.com');
- rendered.getByText('a-tag');
- });
-
- it('should close popover when hitting escape', async () => {
- const rendered = render(wrapInThemedTestApp());
-
- fireEvent.click(rendered.getByText('Support'));
- expect(rendered.queryByText('Contact')).toBeInTheDocument();
- await Keyboard.type(rendered, '');
- await waitForElement(() => !rendered.queryByText('Contact'));
- expect(rendered.queryByText('Contact')).not.toBeInTheDocument();
- });
-});
diff --git a/frontend/packages/core/src/testUtils/index.js b/frontend/packages/core/src/testUtils/index.js
index 5c5ed40741..ae521780e7 100644
--- a/frontend/packages/core/src/testUtils/index.js
+++ b/frontend/packages/core/src/testUtils/index.js
@@ -1,46 +1,31 @@
/**
- * Helpers for testing redux components and containers
+ * Helpers for testing components
*/
+import React from 'react';
import { MuiThemeProvider } from '@material-ui/core';
import { ThemeProvider } from '@material-ui/styles';
-import React from 'react';
-import { act } from 'react-dom/test-utils';
-import { ApolloProvider } from '@apollo/react-hooks';
-import { Provider } from 'react-redux';
+
import { MemoryRouter } from 'react-router';
import { Route } from 'react-router-dom';
-import configureStore from 'redux-mock-store';
-import thunk from 'redux-thunk';
-import { V1 } from 'core/app/Themes';
-import defaultAppState from 'core/defaultAppState';
-import store from 'core/store';
-import ErrorBoundary from 'shared/components/ErrorBoundary';
-import { SearchProvider } from 'plugins/searchPage/SearchContext';
-
-import { render } from '@testing-library/react';
-import { FirestoreProvider } from 'shared/apis/firestore';
-import MockFirestoreStorage from 'shared/apis/firestore/MockFirestoreStorage';
-import { UserInfoProvider, defaultMockUser } from 'shared/apis/user';
+import { V1 } from '../theme/BackstageTheme';
+import ErrorBoundary from '../layout/ErrorBoundary';
export { default as Keyboard } from './Keyboard';
export { default as mockBreakpoint } from './mockBreakpoint';
-export function wrapInTestApp(Component, initialRouterEntries, user = defaultMockUser) {
+export function wrapInTestApp(
+ Component,
+ initialRouterEntries,
+) {
const Wrapper = Component instanceof Function ? Component : () => Component;
return (
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
);
}
@@ -53,227 +38,6 @@ export function wrapInThemedTestApp(component, initialRouterEntries) {
return wrapInTestApp(themed, initialRouterEntries);
}
-export function wrapInSearchTestApp(component) {
- const search = {component};
- return wrapInThemedTestApp(search);
-}
-
-export function getTestStore(state) {
- const appState = state ? state : defaultAppState;
- const mockStore = configureStore([thunk]);
- return mockStore(appState);
-}
-
-export function getGoogleProfile() {
- return {
- getName: () => 'Niklas',
- getGivenName: () => 'Niklas',
- getEmail: () => 'niklas@spotify.com',
- getImageUrl: () => 'http://img.url',
- getId: () => '123456',
- };
-}
-
-const DEFAULT_APOLLO_STATE = {
- data: { loading: true },
-};
-
-export const ApolloMock = ({ children, state = DEFAULT_APOLLO_STATE }) => {
- // Hideous mocking of the ApolloClient to use the ApolloProvider
- // The test do not have information about the GraphQL queries made by the components
- // and hence we cant use MockedProvider and use the one below.
- const mockClient = {
- query: async () => state,
- watchQuery: () => {
- return {
- refetch: () => {},
- fetchMore: () => {},
- updateQuery: () => {},
- startPolling: () => {},
- stopPolling: () => {},
- subscribeToMore: () => {},
- options: {
- fetchPolicy: {},
- },
- getLastResult: () => {},
- currentResult: () => state,
- getCurrentResult: () => state,
- resetQueryStoreErrors: () => {},
- subscribe: () => {},
- setOptions: () => Promise.resolve({}),
- };
- },
- };
- return {children};
-};
-
-/**
- * Return a builder for a given Component which will permit fluent immutable
- * configuration and access to @testing-library/react rendering functions.
- *
- * A full example will make the utility of this more clear:
- *
- * const builder = buildComponentInApp(MyComponent)
- * .withProps({myProp: 'myValue'})
- *
- * // MuiThemeProvider will wrap MyComponent when this is called:
- * .withTheme()
- *
- * // MemoryRouter can be configured with initialEntries:
- * .withRouterEntries(['/'])
- *
- * // ApolloProvider wraps MyComponent with a mock client setup to
- * // provide the given data:
- * .withApolloData({
- * component: {id: 'my-component', system: 'my-system'}
- * });
- *
- * // Test 1: Use the defaults from above when mounting
- * const { getByText } = builder.render();
- * expect(getByText('Display Text').querySelectorAll('td')).toHaveLength(1);
-
- * // Test 2: ApolloRouter provides loading=true state instead of valid data
- * const { queryByText } = builder.withApolloLoading().render();
- * queryByText('Content').toBeNull();
- */
-export function buildComponentInApp(Component) {
- function createBuilder(opt = {}) {
- const builder = {
- withProps: (props = {}) =>
- createBuilder({
- ...opt,
- props: Object.assign(opt.props || {}, props),
- }),
- withTheme: (theme = V1) =>
- createBuilder({
- ...opt,
- theme,
- }),
- withRouterEntries: routerEntries =>
- createBuilder({
- ...opt,
- routerEntries,
- }),
- withApolloLoading: () =>
- // Support `data.loading` (errorOrLoading) or just `loading` (Query)
- createBuilder({
- ...opt,
- apolloState: { data: { loading: true }, loading: true },
- }),
- withApolloData: data =>
- createBuilder({
- ...opt,
- apolloState: { data: { loading: false, ...data } },
- }),
- withApolloError: error =>
- createBuilder({
- ...opt,
- apolloState: { error: error },
- }),
- withUser: user =>
- createBuilder({
- ...opt,
- user,
- }),
- build: (argProps = {}) => {
- const props = { ...(opt.props || {}), ...argProps };
- const component = ;
- const routed = wrapInTestApp(component, opt.routerEntries, opt.user);
- const themed = opt.theme ? {routed} : routed;
- return opt.apolloState ? {themed} : themed;
- },
- render: props => {
- return render(builder.build(props));
- },
- renderWithEffects: async props => {
- return renderWithEffects(builder.build(props));
- },
- };
- return builder;
- }
- return createBuilder();
-}
-
-// Components using useEffect to perform an asynchronous action (such as fetch) must be rendered within an async
-// act call to properly get the final state, even with mocked responses. This utility method makes the signature a bit
-// cleaner, since act doesn't return the result of the evaluated function.
-// https://github.com/testing-library/react-testing-library/issues/281
-// https://github.com/facebook/react/pull/14853
-export async function renderWithEffects(nodes) {
- let value;
- await act(async () => {
- value = await render(nodes);
- });
- return value;
-}
-
-export function logBoundaryErrors() {
- ErrorBoundary.onError = error => console.error('ErrorBoundary received error', error);
-}
-
-// Runs a function with all error logging captured and returned as an array.
-// If the callback function is async this one will be too.
-export function withLogCollector(logsToCollect, callback) {
- if (typeof logsToCollect === 'function') {
- callback = logsToCollect;
- logsToCollect = ['log', 'warn', 'error'];
- }
- const logs = {
- log: [],
- warn: [],
- error: [],
- };
-
- const origLog = console.log;
- const origWarn = console.warn;
- const origError = console.error;
-
- if (logsToCollect.includes('log')) {
- console.log = message => {
- logs.log.push(message);
- };
- }
- if (logsToCollect.includes('warn')) {
- console.warn = message => {
- logs.warn.push(message);
- };
- }
- if (logsToCollect.includes('error')) {
- console.error = message => {
- logs.error.push(message);
- };
- }
-
- const restore = () => {
- console.log = origLog;
- console.warn = origWarn;
- console.error = origError;
- };
-
- try {
- const ret = callback();
-
- if (!ret || !ret.then) {
- restore();
- return logs;
- }
-
- return ret.then(
- () => {
- restore();
- return logs;
- },
- error => {
- restore();
- throw error;
- },
- );
- } catch (error) {
- restore();
- throw error;
- }
-}
-
export const wrapInTheme = (component, theme = V1) => (
{component}
diff --git a/frontend/packages/core/src/theme/BackstageTheme.js b/frontend/packages/core/src/theme/BackstageTheme.js
index d69a86ac37..5185aa8cd7 100644
--- a/frontend/packages/core/src/theme/BackstageTheme.js
+++ b/frontend/packages/core/src/theme/BackstageTheme.js
@@ -355,4 +355,4 @@ const styles = theme => ({
});
export const withGlobalStyles = withStyles(styles);
-export default BackstageTheme;
\ No newline at end of file
+export default BackstageTheme;
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 64df4b69f2..cd1327d08d 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -3596,7 +3596,7 @@ arrify@^1.0.1:
resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
-asap@^2.0.0, asap@~2.0.6:
+asap@^2.0.0, asap@~2.0.3, asap@~2.0.6:
version "2.0.6"
resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
@@ -4452,6 +4452,11 @@ chalk@^1.0.0, chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
+change-emitter@^0.1.2:
+ version "0.1.6"
+ resolved "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515"
+ integrity sha1-6LL+PX8at9aaMhma/5HqaTFAlRU=
+
chardet@^0.7.0:
version "0.7.0"
resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
@@ -5123,6 +5128,11 @@ core-js-pure@^3.0.0:
resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a"
integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw==
+core-js@^1.0.0:
+ version "1.2.7"
+ resolved "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
+ integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
+
core-js@^2.4.0, core-js@^2.5.0:
version "2.6.11"
resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
@@ -6776,6 +6786,19 @@ fb-watchman@^2.0.0:
dependencies:
bser "2.1.1"
+fbjs@^0.8.1:
+ version "0.8.17"
+ resolved "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
+ integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=
+ dependencies:
+ core-js "^1.0.0"
+ isomorphic-fetch "^2.1.1"
+ loose-envify "^1.0.0"
+ object-assign "^4.1.0"
+ promise "^7.1.1"
+ setimmediate "^1.0.5"
+ ua-parser-js "^0.7.18"
+
figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
version "3.5.1"
resolved "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
@@ -7685,6 +7708,11 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
+hoist-non-react-statics@^2.3.1:
+ version "2.5.5"
+ resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
+ integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==
+
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.2.1, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
@@ -8572,7 +8600,7 @@ is-ssh@^1.3.0:
dependencies:
protocols "^1.1.0"
-is-stream@^1.0.0, is-stream@^1.1.0:
+is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
@@ -8665,6 +8693,14 @@ isobject@^4.0.0:
resolved "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0"
integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==
+isomorphic-fetch@^2.1.1:
+ version "2.2.1"
+ resolved "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
+ integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=
+ dependencies:
+ node-fetch "^1.0.1"
+ whatwg-fetch ">=0.10.0"
+
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@@ -11053,6 +11089,14 @@ node-fetch-npm@^2.0.2:
json-parse-better-errors "^1.0.0"
safe-buffer "^5.1.1"
+node-fetch@^1.0.1:
+ version "1.7.3"
+ resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
+ integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==
+ dependencies:
+ encoding "^0.1.11"
+ is-stream "^1.0.1"
+
node-fetch@^2.3.0, node-fetch@^2.5.0:
version "2.6.0"
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
@@ -13015,6 +13059,13 @@ promise-retry@^1.1.1:
err-code "^1.0.0"
retry "^0.10.0"
+promise@^7.1.1:
+ version "7.3.1"
+ resolved "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+ integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
+ dependencies:
+ asap "~2.0.3"
+
promise@^8.0.3:
version "8.0.3"
resolved "https://registry.npmjs.org/promise/-/promise-8.0.3.tgz#f592e099c6cddc000d538ee7283bb190452b0bf6"
@@ -13329,6 +13380,11 @@ react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-i
resolved "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"
integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==
+react-lifecycles-compat@^3.0.2:
+ version "3.0.4"
+ resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
+ integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
+
react-router-dom@^5.1.2:
version "5.1.2"
resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.1.2.tgz#06701b834352f44d37fbb6311f870f84c76b9c18"
@@ -13583,6 +13639,18 @@ rechoir@^0.6.2:
dependencies:
resolve "^1.1.6"
+recompose@0.30.0:
+ version "0.30.0"
+ resolved "https://registry.npmjs.org/recompose/-/recompose-0.30.0.tgz#82773641b3927e8c7d24a0d87d65aeeba18aabd0"
+ integrity sha512-ZTrzzUDa9AqUIhRk4KmVFihH0rapdCSMFXjhHbNrjAWxBuUD/guYlyysMnuHjlZC/KRiOKRtB4jf96yYSkKE8w==
+ dependencies:
+ "@babel/runtime" "^7.0.0"
+ change-emitter "^0.1.2"
+ fbjs "^0.8.1"
+ hoist-non-react-statics "^2.3.1"
+ react-lifecycles-compat "^3.0.2"
+ symbol-observable "^1.0.4"
+
recursive-readdir@2.2.2:
version "2.2.2"
resolved "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f"
@@ -14287,7 +14355,7 @@ set-value@^2.0.0, set-value@^2.0.1:
is-plain-object "^2.0.3"
split-string "^3.0.1"
-setimmediate@^1.0.4:
+setimmediate@^1.0.4, setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
@@ -15093,7 +15161,7 @@ svgo@^1.0.0, svgo@^1.2.2:
unquote "~1.1.1"
util.promisify "~1.0.0"
-symbol-observable@^1.1.0:
+symbol-observable@^1.0.4, symbol-observable@^1.1.0:
version "1.2.0"
resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
@@ -15548,6 +15616,11 @@ typescript@^3.7.4, typescript@^3.7.5:
resolved "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae"
integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==
+ua-parser-js@^0.7.18:
+ version "0.7.21"
+ resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777"
+ integrity sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==
+
uglify-js@3.4.x:
version "3.4.10"
resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f"
@@ -16057,7 +16130,7 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5:
dependencies:
iconv-lite "0.4.24"
-whatwg-fetch@^3.0.0:
+whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==