diff --git a/frontend/src/common.styles.js b/frontend/src/common.styles.js index 318abaaa33..f61dcac6ed 100644 --- a/frontend/src/common.styles.js +++ b/frontend/src/common.styles.js @@ -3,17 +3,20 @@ import { makeStyles } from '@material-ui/styles'; export const useCommonStyles = makeStyles(theme => ({ contentSpacingY: { '& > *': { - margin: '0.5rem 0', + marginTop: '0.5rem !important', + marginBottom: '0.5rem !important', }, }, contentSpacingYLarge: { '& > *': { - margin: '1.5rem 0', + marginTop: '1.5rem !important', + marginBottom: '1.5rem !important', }, }, contentSpacingX: { '& > *': { - margin: '0 0.8rem', + marginRight: '0.8rem !important', + marginLeft: '0.8rem !important', }, }, divider: { diff --git a/frontend/src/component/common/BreadcrumbNav/BreadcrumbNav.tsx b/frontend/src/component/common/BreadcrumbNav/BreadcrumbNav.tsx index cd23dc406a..d070959ae5 100644 --- a/frontend/src/component/common/BreadcrumbNav/BreadcrumbNav.tsx +++ b/frontend/src/component/common/BreadcrumbNav/BreadcrumbNav.tsx @@ -40,6 +40,7 @@ const BreadcrumbNav = () => { if (lastItem) { return (

{ } return ( diff --git a/frontend/src/component/common/Dialogue/Dialogue.jsx b/frontend/src/component/common/Dialogue/Dialogue.jsx index f386faf778..23c78205c2 100644 --- a/frontend/src/component/common/Dialogue/Dialogue.jsx +++ b/frontend/src/component/common/Dialogue/Dialogue.jsx @@ -58,7 +58,7 @@ const Dialogue = ({ condition={onClose} show={ } /> diff --git a/frontend/src/component/feature/FeatureToggleList/FeatureToggleList.jsx b/frontend/src/component/feature/FeatureToggleList/FeatureToggleList.jsx index ddb06c59ae..72a815b546 100644 --- a/frontend/src/component/feature/FeatureToggleList/FeatureToggleList.jsx +++ b/frontend/src/component/feature/FeatureToggleList/FeatureToggleList.jsx @@ -37,6 +37,7 @@ const FeatureToggleList = ({ const { hasAccess } = useContext(AccessContext); const styles = useStyles(); const smallScreen = useMediaQuery('(max-width:800px)'); + const mobileView = useMediaQuery('(max-width:600px)'); useLayoutEffect(() => { fetcher(); @@ -120,6 +121,10 @@ const FeatureToggleList = ({ skeleton: loading, })} /> + Archive} + />

@@ -20,7 +20,7 @@ exports[`renders correctly with one feature 1`] = ` />
@@ -38,6 +38,12 @@ exports[`renders correctly with one feature 1`] = `
+ + Archive +

Feature toggles

    @@ -263,7 +269,7 @@ exports[`renders correctly with one feature without permissions 1`] = ` />
    @@ -281,6 +287,12 @@ exports[`renders correctly with one feature without permissions 1`] = `
    + + Archive +

Feature toggles

    ({ }, searchBarContainer: { marginBottom: '2rem', + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + [theme.breakpoints.down('xs')]: { + display: 'block', + }, + }, + searchBar: { + minWidth: '450px', + [theme.breakpoints.down('xs')]: { + minWidth: '100%', + }, }, emptyStateListItem: { border: `2px dashed ${theme.palette.borders.main}`, diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.jsx b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.jsx index 1f2557ee59..94ba5af18f 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.jsx +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.jsx @@ -25,12 +25,14 @@ const StrategyCardHeader = ({ }} title={ <> - - {name} - + + + {name} + +
    diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.styles.js b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.styles.js index f980091f8d..bc11fc4059 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.styles.js +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.styles.js @@ -15,6 +15,10 @@ export const useStyles = makeStyles(theme => ({ }, strategyCardHeaderTitle: { fontSize: theme.fontSizes.subHeader, + maxWidth: '70%', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + overflow: 'hidden', }, strategyCardHeaderActions: { display: 'flex', diff --git a/frontend/src/component/menu/Header/Header.tsx b/frontend/src/component/menu/Header/Header.tsx index bda2759a9e..59ddbd1d6b 100644 --- a/frontend/src/component/menu/Header/Header.tsx +++ b/frontend/src/component/menu/Header/Header.tsx @@ -94,6 +94,7 @@ const Header = () => { condition={flags?.P} show={Projects} /> + Feature toggles { options={filteredMainRoutes.mainNavRoutes} anchorEl={anchorElAdvanced} handleClose={handleCloseAdvanced} + style={{ top: '30px', left: '-55px' }} />
    } @@ -150,6 +152,7 @@ const Header = () => { options={routes.adminRoutes} anchorEl={anchorEl} handleClose={handleClose} + style={{ top: '40px', left: '-125px' }} /> } diff --git a/frontend/src/component/menu/Header/NavigationMenu/NavigationMenu.tsx b/frontend/src/component/menu/Header/NavigationMenu/NavigationMenu.tsx index c562d9aa3e..a76a155424 100644 --- a/frontend/src/component/menu/Header/NavigationMenu/NavigationMenu.tsx +++ b/frontend/src/component/menu/Header/NavigationMenu/NavigationMenu.tsx @@ -6,6 +6,7 @@ interface INavigationMenuProps { id: string; anchorEl: any; handleClose: () => void; + style: Object; } const NavigationMenu = ({ @@ -13,6 +14,7 @@ const NavigationMenu = ({ id, handleClose, anchorEl, + style, }: INavigationMenuProps) => { return ( {options.map(option => { diff --git a/frontend/src/component/menu/__tests__/__snapshots__/routes-test.jsx.snap b/frontend/src/component/menu/__tests__/__snapshots__/routes-test.jsx.snap index 742f132ac8..b0638bf50c 100644 --- a/frontend/src/component/menu/__tests__/__snapshots__/routes-test.jsx.snap +++ b/frontend/src/component/menu/__tests__/__snapshots__/routes-test.jsx.snap @@ -5,6 +5,7 @@ Array [ Object { "component": [Function], "layout": "main", + "menu": Object {}, "path": "/features", "title": "Feature Toggles", "type": "protected", @@ -12,6 +13,9 @@ Array [ Object { "component": [Function], "layout": "main", + "menu": Object { + "advanced": true, + }, "path": "/strategies", "title": "Strategies", "type": "protected", @@ -19,6 +23,9 @@ Array [ Object { "component": [Function], "layout": "main", + "menu": Object { + "adminSettings": true, + }, "path": "/history", "title": "Event History", "type": "protected", @@ -26,6 +33,7 @@ Array [ Object { "component": [Function], "layout": "main", + "menu": Object {}, "path": "/archive", "title": "Archived Toggles", "type": "protected", @@ -33,6 +41,9 @@ Array [ Object { "component": [Function], "layout": "main", + "menu": Object { + "advanced": true, + }, "path": "/applications", "title": "Applications", "type": "protected", @@ -41,6 +52,9 @@ Array [ "component": [Function], "flag": "C", "layout": "main", + "menu": Object { + "advanced": true, + }, "path": "/context", "title": "Context Fields", "type": "protected", @@ -49,6 +63,7 @@ Array [ "component": [Function], "flag": "P", "layout": "main", + "menu": Object {}, "path": "/projects", "title": "Projects", "type": "protected", @@ -56,6 +71,9 @@ Array [ Object { "component": [Function], "layout": "main", + "menu": Object { + "advanced": true, + }, "path": "/tag-types", "title": "Tag types", "type": "protected", @@ -64,6 +82,9 @@ Array [ "component": [Function], "hidden": false, "layout": "main", + "menu": Object { + "advanced": true, + }, "path": "/addons", "title": "Addons", "type": "protected", @@ -71,6 +92,9 @@ Array [ Object { "component": [Function], "layout": "main", + "menu": Object { + "advanced": true, + }, "path": "/reporting", "title": "Reporting", "type": "protected", @@ -79,6 +103,7 @@ Array [ "component": [Function], "hidden": false, "layout": "main", + "menu": Object {}, "path": "/admin", "title": "Admin", "type": "protected", diff --git a/frontend/src/component/menu/routes.js b/frontend/src/component/menu/routes.js index 67c9fe64ca..cae0865ebd 100644 --- a/frontend/src/component/menu/routes.js +++ b/frontend/src/component/menu/routes.js @@ -49,6 +49,7 @@ export const routes = [ component: CreateFeatureToggle, type: 'protected', layout: 'main', + menu: {}, }, { path: '/features/copy/:copyToggle', @@ -57,6 +58,7 @@ export const routes = [ component: CopyFeatureToggle, type: 'protected', layout: 'main', + menu: {}, }, { path: '/features/:activeTab/:name', @@ -65,6 +67,7 @@ export const routes = [ component: ViewFeatureToggle, type: 'protected', layout: 'main', + menu: {}, }, { path: '/features', @@ -72,6 +75,7 @@ export const routes = [ component: Features, type: 'protected', layout: 'main', + menu: {}, }, // Strategies @@ -82,6 +86,7 @@ export const routes = [ component: CreateStrategies, type: 'protected', layout: 'main', + menu: {}, }, { path: '/strategies/:activeTab/:strategyName', @@ -90,6 +95,7 @@ export const routes = [ component: StrategyView, type: 'protected', layout: 'main', + menu: {}, }, { path: '/strategies', @@ -97,6 +103,7 @@ export const routes = [ component: Strategies, type: 'protected', layout: 'main', + menu: { advanced: true }, }, // History @@ -107,6 +114,7 @@ export const routes = [ component: HistoryTogglePage, type: 'protected', layout: 'main', + menu: {}, }, { path: '/history', @@ -114,6 +122,7 @@ export const routes = [ component: HistoryPage, type: 'protected', layout: 'main', + menu: { adminSettings: true }, }, // Archive @@ -124,6 +133,7 @@ export const routes = [ component: ShowArchive, type: 'protected', layout: 'main', + menu: {}, }, { path: '/archive', @@ -131,6 +141,7 @@ export const routes = [ component: Archive, type: 'protected', layout: 'main', + menu: {}, }, // Applications @@ -141,6 +152,7 @@ export const routes = [ component: ApplicationView, type: 'protected', layout: 'main', + menu: {}, }, { path: '/applications', @@ -148,6 +160,7 @@ export const routes = [ component: Applications, type: 'protected', layout: 'main', + menu: { advanced: true }, }, // Context @@ -158,6 +171,7 @@ export const routes = [ component: CreateContextField, type: 'protected', layout: 'main', + menu: {}, }, { path: '/context/edit/:name', @@ -166,6 +180,7 @@ export const routes = [ component: EditContextField, type: 'protected', layout: 'main', + menu: {}, }, { path: '/context', @@ -174,6 +189,7 @@ export const routes = [ type: 'protected', flag: C, layout: 'main', + menu: { advanced: true }, }, // Project @@ -184,6 +200,7 @@ export const routes = [ component: CreateProject, type: 'protected', layout: 'main', + menu: {}, }, { path: '/projects/edit/:id', @@ -192,6 +209,7 @@ export const routes = [ component: EditProject, type: 'protected', layout: 'main', + menu: {}, }, { path: '/projects/view/:id', @@ -200,6 +218,7 @@ export const routes = [ component: ViewProject, type: 'protected', layout: 'main', + menu: {}, }, { path: '/projects/:id/access', @@ -208,6 +227,7 @@ export const routes = [ component: EditProjectAccess, type: 'protected', layout: 'main', + menu: {}, }, { path: '/projects/:id', @@ -217,6 +237,7 @@ export const routes = [ flag: P, type: 'protected', layout: 'main', + menu: {}, }, { path: '/projects', @@ -225,6 +246,7 @@ export const routes = [ flag: P, type: 'protected', layout: 'main', + menu: {}, }, { @@ -234,6 +256,7 @@ export const routes = [ component: CreateTagType, type: 'protected', layout: 'main', + menu: {}, }, { path: '/tag-types/edit/:name', @@ -242,6 +265,7 @@ export const routes = [ component: EditTagType, type: 'protected', layout: 'main', + menu: {}, }, { path: '/tag-types', @@ -249,6 +273,7 @@ export const routes = [ component: ListTagTypes, type: 'protected', layout: 'main', + menu: { advanced: true }, }, { @@ -258,6 +283,7 @@ export const routes = [ component: CreateTag, type: 'protected', layout: 'main', + menu: {}, }, { path: '/tags', @@ -266,6 +292,7 @@ export const routes = [ hidden: true, type: 'protected', layout: 'main', + menu: {}, }, // Addons @@ -276,6 +303,7 @@ export const routes = [ component: AddonsCreate, type: 'protected', layout: 'main', + menu: {}, }, { path: '/addons/edit/:id', @@ -284,6 +312,7 @@ export const routes = [ component: AddonsEdit, type: 'protected', layout: 'main', + menu: {}, }, { path: '/addons', @@ -292,6 +321,7 @@ export const routes = [ hidden: false, type: 'protected', layout: 'main', + menu: { advanced: true }, }, { path: '/reporting', @@ -299,6 +329,7 @@ export const routes = [ component: Reporting, type: 'protected', layout: 'main', + menu: { advanced: true }, }, // Admin { @@ -308,6 +339,7 @@ export const routes = [ component: AdminApi, type: 'protected', layout: 'main', + menu: { advanced: true, adminSettings: true }, }, { path: '/admin/users', @@ -316,6 +348,7 @@ export const routes = [ component: AdminUsers, type: 'protected', layout: 'main', + menu: { adminSettings: true }, }, { path: '/admin/auth', @@ -324,6 +357,7 @@ export const routes = [ component: AdminAuth, type: 'protected', layout: 'main', + menu: { adminSettings: true }, }, { path: '/admin-invoices', @@ -332,6 +366,7 @@ export const routes = [ hidden: true, type: 'protected', layout: 'main', + menu: { adminSettings: true }, }, { path: '/admin', @@ -340,6 +375,7 @@ export const routes = [ hidden: false, type: 'protected', layout: 'main', + menu: {}, }, { path: '/login', @@ -348,6 +384,7 @@ export const routes = [ type: 'unprotected', hidden: true, layout: 'standalone', + menu: {}, }, { path: '/new-user', @@ -356,6 +393,7 @@ export const routes = [ component: NewUser, type: 'unprotected', layout: 'standalone', + menu: {}, }, { path: '/reset-password', @@ -364,6 +402,7 @@ export const routes = [ component: ResetPassword, type: 'unprotected', layout: 'standalone', + menu: {}, }, { path: '/forgotten-password', @@ -372,6 +411,7 @@ export const routes = [ component: ForgottenPassword, type: 'unprotected', layout: 'standalone', + menu: {}, }, ]; @@ -382,27 +422,12 @@ export const baseRoutes = routes .filter(route => !route.parent); const computeRoutes = () => { - const apiAccess = routes.find(route => route.path === '/admin/api'); - const mainNavRoutes = - baseRoutes.filter( - route => - route.path !== '/admin' && - route.path !== '/logout' && - route.path !== '/history' - ) || []; - - mainNavRoutes.push(apiAccess); + const mainNavRoutes = baseRoutes.filter(route => route.menu.advanced); + const adminRoutes = routes.filter(route => route.menu.adminSettings); const computedRoutes = { mainNavRoutes, - adminRoutes: - routes.filter( - route => - (route.path.startsWith('/admin') && - route.path !== '/admin-invoices' && - route.path !== '/admin') || - route.path === '/history' - ) || [], + adminRoutes, }; return () => { return computedRoutes; diff --git a/frontend/src/component/user/PasswordAuth/PasswordAuth.jsx b/frontend/src/component/user/PasswordAuth/PasswordAuth.jsx index 275fba6740..75be2b5e14 100644 --- a/frontend/src/component/user/PasswordAuth/PasswordAuth.jsx +++ b/frontend/src/component/user/PasswordAuth/PasswordAuth.jsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import classnames from 'classnames'; import PropTypes from 'prop-types'; -import { Button, TextField, Typography } from '@material-ui/core'; +import { Button, TextField } from '@material-ui/core'; import ConditionallyRender from '../../common/ConditionallyRender'; import { useHistory } from 'react-router'; import { useCommonStyles } from '../../../common.styles'; @@ -9,6 +9,7 @@ import { useStyles } from './PasswordAuth.styles'; import useQueryParams from '../../../hooks/useQueryParams'; import AuthOptions from '../common/AuthOptions/AuthOptions'; import DividerText from '../../common/DividerText/DividerText'; +import { Alert } from '@material-ui/lab'; const PasswordAuth = ({ authDetails, passwordLogin }) => { const commonStyles = useCommonStyles(); @@ -57,6 +58,10 @@ const PasswordAuth = ({ authDetails, passwordLogin }) => { })); setPassword(''); setUsername(''); + } else if (error.statusCode === 401) { + setErrors({ + apiError: 'Invalid password and username combination.', + }); } else { setErrors({ apiError: 'Unknown error while trying to authenticate.', @@ -70,9 +75,15 @@ const PasswordAuth = ({ authDetails, passwordLogin }) => { return (
    - - {apiError} - + + {apiError} + + } + /> +
    ({ }, apiError: { color: theme.palette.error.main, + marginBottom: '0.5rem', }, })); diff --git a/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.jsx b/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.jsx index fe365e8dec..f11a105b6d 100644 --- a/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.jsx +++ b/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.jsx @@ -9,14 +9,12 @@ import { Select, InputLabel, } from '@material-ui/core'; -import { Link } from 'react-router-dom'; import classnames from 'classnames'; import { useStyles } from './UserProfileContent.styles'; import { useCommonStyles } from '../../../../common.styles'; import { Alert } from '@material-ui/lab'; import EditProfile from '../EditProfile/EditProfile'; import legacyStyles from '../../user.module.scss'; -import usePermissions from '../../../../hooks/usePermissions'; import { getBasePath } from '../../../../utils/format-path'; const UserProfileContent = ({ @@ -32,7 +30,6 @@ const UserProfileContent = ({ const [updatedPassword, setUpdatedPassword] = useState(false); const [edititingProfile, setEditingProfile] = useState(false); const styles = useStyles(); - const { isAdmin } = usePermissions(); const setLocale = value => { updateSettingLocation('locale', value); @@ -131,17 +128,6 @@ const UserProfileContent = ({
    - - Account and billing - - } - />