mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-05 17:53:12 +02:00
Fix/routing (#325)
* fix: filter routes * fix: add archive link to feature toggles list * fix: strategy card name * fix: add breadcrumb keys * fix: update tests * fix: menu placement * fix: remove dot * fix: handle 401 error * fix: add important to styles * fix: adjust positioning * fix: remove unused imports
This commit is contained in:
parent
5febe31e71
commit
b83418f410
@ -3,17 +3,20 @@ import { makeStyles } from '@material-ui/styles';
|
|||||||
export const useCommonStyles = makeStyles(theme => ({
|
export const useCommonStyles = makeStyles(theme => ({
|
||||||
contentSpacingY: {
|
contentSpacingY: {
|
||||||
'& > *': {
|
'& > *': {
|
||||||
margin: '0.5rem 0',
|
marginTop: '0.5rem !important',
|
||||||
|
marginBottom: '0.5rem !important',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
contentSpacingYLarge: {
|
contentSpacingYLarge: {
|
||||||
'& > *': {
|
'& > *': {
|
||||||
margin: '1.5rem 0',
|
marginTop: '1.5rem !important',
|
||||||
|
marginBottom: '1.5rem !important',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
contentSpacingX: {
|
contentSpacingX: {
|
||||||
'& > *': {
|
'& > *': {
|
||||||
margin: '0 0.8rem',
|
marginRight: '0.8rem !important',
|
||||||
|
marginLeft: '0.8rem !important',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
divider: {
|
divider: {
|
||||||
|
@ -40,6 +40,7 @@ const BreadcrumbNav = () => {
|
|||||||
if (lastItem) {
|
if (lastItem) {
|
||||||
return (
|
return (
|
||||||
<p
|
<p
|
||||||
|
key={path}
|
||||||
className={
|
className={
|
||||||
styles.breadcrumbNavParagraph
|
styles.breadcrumbNavParagraph
|
||||||
}
|
}
|
||||||
@ -50,6 +51,7 @@ const BreadcrumbNav = () => {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
|
key={path}
|
||||||
className={styles.breadcrumbLink}
|
className={styles.breadcrumbLink}
|
||||||
to={`/${path}`}
|
to={`/${path}`}
|
||||||
>
|
>
|
||||||
|
@ -58,7 +58,7 @@ const Dialogue = ({
|
|||||||
condition={onClose}
|
condition={onClose}
|
||||||
show={
|
show={
|
||||||
<Button onClick={onClose}>
|
<Button onClick={onClose}>
|
||||||
{secondaryButtonText || 'No take me back.'}{' '}
|
{secondaryButtonText || 'No take me back'}{' '}
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -37,6 +37,7 @@ const FeatureToggleList = ({
|
|||||||
const { hasAccess } = useContext(AccessContext);
|
const { hasAccess } = useContext(AccessContext);
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const smallScreen = useMediaQuery('(max-width:800px)');
|
const smallScreen = useMediaQuery('(max-width:800px)');
|
||||||
|
const mobileView = useMediaQuery('(max-width:600px)');
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
fetcher();
|
fetcher();
|
||||||
@ -120,6 +121,10 @@ const FeatureToggleList = ({
|
|||||||
skeleton: loading,
|
skeleton: loading,
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={!mobileView}
|
||||||
|
show={<Link to="/archive">Archive</Link>}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PageContent
|
<PageContent
|
||||||
|
@ -7,11 +7,11 @@ exports[`renders correctly with one feature 1`] = `
|
|||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-search-5"
|
className="makeStyles-search-6 makeStyles-searchBar-4"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="MuiSvgIcon-root makeStyles-searchIcon-6"
|
className="MuiSvgIcon-root makeStyles-searchIcon-7"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
>
|
>
|
||||||
@ -20,7 +20,7 @@ exports[`renders correctly with one feature 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<div
|
<div
|
||||||
className="MuiInputBase-root makeStyles-inputRoot-7"
|
className="MuiInputBase-root makeStyles-inputRoot-8"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
onKeyPress={[Function]}
|
onKeyPress={[Function]}
|
||||||
>
|
>
|
||||||
@ -38,6 +38,12 @@ exports[`renders correctly with one feature 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<a
|
||||||
|
href="/archive"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
Archive
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
||||||
@ -49,29 +55,29 @@ exports[`renders correctly with one feature 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-headerContainer-8"
|
className="makeStyles-headerContainer-9"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-headerTitleContainer-12"
|
className="makeStyles-headerTitleContainer-13"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className=""
|
className=""
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
>
|
>
|
||||||
<h2
|
<h2
|
||||||
className="MuiTypography-root makeStyles-headerTitle-13 MuiTypography-h2"
|
className="MuiTypography-root makeStyles-headerTitle-14 MuiTypography-h2"
|
||||||
>
|
>
|
||||||
Feature toggles
|
Feature toggles
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-headerActions-14"
|
className="makeStyles-headerActions-15"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-actionsContainer-1"
|
className="makeStyles-actionsContainer-1"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-actions-15"
|
className="makeStyles-actions-16"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
className="MuiTypography-root MuiTypography-body2"
|
className="MuiTypography-root MuiTypography-body2"
|
||||||
@ -217,7 +223,7 @@ exports[`renders correctly with one feature 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-bodyContainer-9"
|
className="makeStyles-bodyContainer-10"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
className="MuiList-root MuiList-padding"
|
className="MuiList-root MuiList-padding"
|
||||||
@ -250,11 +256,11 @@ exports[`renders correctly with one feature without permissions 1`] = `
|
|||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-search-5"
|
className="makeStyles-search-6 makeStyles-searchBar-4"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="MuiSvgIcon-root makeStyles-searchIcon-6"
|
className="MuiSvgIcon-root makeStyles-searchIcon-7"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
>
|
>
|
||||||
@ -263,7 +269,7 @@ exports[`renders correctly with one feature without permissions 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<div
|
<div
|
||||||
className="MuiInputBase-root makeStyles-inputRoot-7"
|
className="MuiInputBase-root makeStyles-inputRoot-8"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
onKeyPress={[Function]}
|
onKeyPress={[Function]}
|
||||||
>
|
>
|
||||||
@ -281,6 +287,12 @@ exports[`renders correctly with one feature without permissions 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<a
|
||||||
|
href="/archive"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
Archive
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
||||||
@ -292,29 +304,29 @@ exports[`renders correctly with one feature without permissions 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-headerContainer-8"
|
className="makeStyles-headerContainer-9"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-headerTitleContainer-12"
|
className="makeStyles-headerTitleContainer-13"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className=""
|
className=""
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
>
|
>
|
||||||
<h2
|
<h2
|
||||||
className="MuiTypography-root makeStyles-headerTitle-13 MuiTypography-h2"
|
className="MuiTypography-root makeStyles-headerTitle-14 MuiTypography-h2"
|
||||||
>
|
>
|
||||||
Feature toggles
|
Feature toggles
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-headerActions-14"
|
className="makeStyles-headerActions-15"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-actionsContainer-1"
|
className="makeStyles-actionsContainer-1"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-actions-15"
|
className="makeStyles-actions-16"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
className="MuiTypography-root MuiTypography-body2"
|
className="MuiTypography-root MuiTypography-body2"
|
||||||
@ -466,7 +478,7 @@ exports[`renders correctly with one feature without permissions 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="makeStyles-bodyContainer-9"
|
className="makeStyles-bodyContainer-10"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
className="MuiList-root MuiList-padding"
|
className="MuiList-root MuiList-padding"
|
||||||
|
@ -10,6 +10,18 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
},
|
},
|
||||||
searchBarContainer: {
|
searchBarContainer: {
|
||||||
marginBottom: '2rem',
|
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: {
|
emptyStateListItem: {
|
||||||
border: `2px dashed ${theme.palette.borders.main}`,
|
border: `2px dashed ${theme.palette.borders.main}`,
|
||||||
|
@ -25,12 +25,14 @@ const StrategyCardHeader = ({
|
|||||||
}}
|
}}
|
||||||
title={
|
title={
|
||||||
<>
|
<>
|
||||||
<Typography
|
<Tooltip title={name}>
|
||||||
variant="subtitle1"
|
<Typography
|
||||||
className={styles.strategyCardHeaderTitle}
|
variant="subtitle1"
|
||||||
>
|
className={styles.strategyCardHeaderTitle}
|
||||||
{name}
|
>
|
||||||
</Typography>
|
{name}
|
||||||
|
</Typography>
|
||||||
|
</Tooltip>
|
||||||
<div className={styles.strategyCardHeaderActions}>
|
<div className={styles.strategyCardHeaderActions}>
|
||||||
<Tooltip title="Edit strategy">
|
<Tooltip title="Edit strategy">
|
||||||
<IconButton onClick={editStrategy}>
|
<IconButton onClick={editStrategy}>
|
||||||
|
@ -15,6 +15,10 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
},
|
},
|
||||||
strategyCardHeaderTitle: {
|
strategyCardHeaderTitle: {
|
||||||
fontSize: theme.fontSizes.subHeader,
|
fontSize: theme.fontSizes.subHeader,
|
||||||
|
maxWidth: '70%',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
overflow: 'hidden',
|
||||||
},
|
},
|
||||||
strategyCardHeaderActions: {
|
strategyCardHeaderActions: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
@ -94,6 +94,7 @@ const Header = () => {
|
|||||||
condition={flags?.P}
|
condition={flags?.P}
|
||||||
show={<Link to="/projects">Projects</Link>}
|
show={<Link to="/projects">Projects</Link>}
|
||||||
/>
|
/>
|
||||||
|
<Link to="/features">Feature toggles</Link>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={styles.advancedNavButton}
|
className={styles.advancedNavButton}
|
||||||
@ -101,7 +102,7 @@ const Header = () => {
|
|||||||
setAnchorElAdvanced(e.currentTarget)
|
setAnchorElAdvanced(e.currentTarget)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Navigate
|
Advanced
|
||||||
<KeyboardArrowDown />
|
<KeyboardArrowDown />
|
||||||
</button>
|
</button>
|
||||||
<NavigationMenu
|
<NavigationMenu
|
||||||
@ -109,6 +110,7 @@ const Header = () => {
|
|||||||
options={filteredMainRoutes.mainNavRoutes}
|
options={filteredMainRoutes.mainNavRoutes}
|
||||||
anchorEl={anchorElAdvanced}
|
anchorEl={anchorElAdvanced}
|
||||||
handleClose={handleCloseAdvanced}
|
handleClose={handleCloseAdvanced}
|
||||||
|
style={{ top: '30px', left: '-55px' }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -150,6 +152,7 @@ const Header = () => {
|
|||||||
options={routes.adminRoutes}
|
options={routes.adminRoutes}
|
||||||
anchorEl={anchorEl}
|
anchorEl={anchorEl}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
|
style={{ top: '40px', left: '-125px' }}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ interface INavigationMenuProps {
|
|||||||
id: string;
|
id: string;
|
||||||
anchorEl: any;
|
anchorEl: any;
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
|
style: Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NavigationMenu = ({
|
const NavigationMenu = ({
|
||||||
@ -13,6 +14,7 @@ const NavigationMenu = ({
|
|||||||
id,
|
id,
|
||||||
handleClose,
|
handleClose,
|
||||||
anchorEl,
|
anchorEl,
|
||||||
|
style,
|
||||||
}: INavigationMenuProps) => {
|
}: INavigationMenuProps) => {
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Popover
|
||||||
@ -21,7 +23,7 @@ const NavigationMenu = ({
|
|||||||
anchorEl={anchorEl}
|
anchorEl={anchorEl}
|
||||||
open={Boolean(anchorEl)}
|
open={Boolean(anchorEl)}
|
||||||
onMouseLeave={handleClose}
|
onMouseLeave={handleClose}
|
||||||
style={{ top: '30px', left: '-90px' }}
|
style={style}
|
||||||
>
|
>
|
||||||
<List>
|
<List>
|
||||||
{options.map(option => {
|
{options.map(option => {
|
||||||
|
@ -5,6 +5,7 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
"layout": "main",
|
||||||
|
"menu": Object {},
|
||||||
"path": "/features",
|
"path": "/features",
|
||||||
"title": "Feature Toggles",
|
"title": "Feature Toggles",
|
||||||
"type": "protected",
|
"type": "protected",
|
||||||
@ -12,6 +13,9 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
"layout": "main",
|
||||||
|
"menu": Object {
|
||||||
|
"advanced": true,
|
||||||
|
},
|
||||||
"path": "/strategies",
|
"path": "/strategies",
|
||||||
"title": "Strategies",
|
"title": "Strategies",
|
||||||
"type": "protected",
|
"type": "protected",
|
||||||
@ -19,6 +23,9 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
"layout": "main",
|
||||||
|
"menu": Object {
|
||||||
|
"adminSettings": true,
|
||||||
|
},
|
||||||
"path": "/history",
|
"path": "/history",
|
||||||
"title": "Event History",
|
"title": "Event History",
|
||||||
"type": "protected",
|
"type": "protected",
|
||||||
@ -26,6 +33,7 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
"layout": "main",
|
||||||
|
"menu": Object {},
|
||||||
"path": "/archive",
|
"path": "/archive",
|
||||||
"title": "Archived Toggles",
|
"title": "Archived Toggles",
|
||||||
"type": "protected",
|
"type": "protected",
|
||||||
@ -33,6 +41,9 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
"layout": "main",
|
||||||
|
"menu": Object {
|
||||||
|
"advanced": true,
|
||||||
|
},
|
||||||
"path": "/applications",
|
"path": "/applications",
|
||||||
"title": "Applications",
|
"title": "Applications",
|
||||||
"type": "protected",
|
"type": "protected",
|
||||||
@ -41,6 +52,9 @@ Array [
|
|||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "C",
|
"flag": "C",
|
||||||
"layout": "main",
|
"layout": "main",
|
||||||
|
"menu": Object {
|
||||||
|
"advanced": true,
|
||||||
|
},
|
||||||
"path": "/context",
|
"path": "/context",
|
||||||
"title": "Context Fields",
|
"title": "Context Fields",
|
||||||
"type": "protected",
|
"type": "protected",
|
||||||
@ -49,6 +63,7 @@ Array [
|
|||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "P",
|
"flag": "P",
|
||||||
"layout": "main",
|
"layout": "main",
|
||||||
|
"menu": Object {},
|
||||||
"path": "/projects",
|
"path": "/projects",
|
||||||
"title": "Projects",
|
"title": "Projects",
|
||||||
"type": "protected",
|
"type": "protected",
|
||||||
@ -56,6 +71,9 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
"layout": "main",
|
||||||
|
"menu": Object {
|
||||||
|
"advanced": true,
|
||||||
|
},
|
||||||
"path": "/tag-types",
|
"path": "/tag-types",
|
||||||
"title": "Tag types",
|
"title": "Tag types",
|
||||||
"type": "protected",
|
"type": "protected",
|
||||||
@ -64,6 +82,9 @@ Array [
|
|||||||
"component": [Function],
|
"component": [Function],
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"layout": "main",
|
"layout": "main",
|
||||||
|
"menu": Object {
|
||||||
|
"advanced": true,
|
||||||
|
},
|
||||||
"path": "/addons",
|
"path": "/addons",
|
||||||
"title": "Addons",
|
"title": "Addons",
|
||||||
"type": "protected",
|
"type": "protected",
|
||||||
@ -71,6 +92,9 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
"layout": "main",
|
||||||
|
"menu": Object {
|
||||||
|
"advanced": true,
|
||||||
|
},
|
||||||
"path": "/reporting",
|
"path": "/reporting",
|
||||||
"title": "Reporting",
|
"title": "Reporting",
|
||||||
"type": "protected",
|
"type": "protected",
|
||||||
@ -79,6 +103,7 @@ Array [
|
|||||||
"component": [Function],
|
"component": [Function],
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"layout": "main",
|
"layout": "main",
|
||||||
|
"menu": Object {},
|
||||||
"path": "/admin",
|
"path": "/admin",
|
||||||
"title": "Admin",
|
"title": "Admin",
|
||||||
"type": "protected",
|
"type": "protected",
|
||||||
|
@ -49,6 +49,7 @@ export const routes = [
|
|||||||
component: CreateFeatureToggle,
|
component: CreateFeatureToggle,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/features/copy/:copyToggle',
|
path: '/features/copy/:copyToggle',
|
||||||
@ -57,6 +58,7 @@ export const routes = [
|
|||||||
component: CopyFeatureToggle,
|
component: CopyFeatureToggle,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/features/:activeTab/:name',
|
path: '/features/:activeTab/:name',
|
||||||
@ -65,6 +67,7 @@ export const routes = [
|
|||||||
component: ViewFeatureToggle,
|
component: ViewFeatureToggle,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/features',
|
path: '/features',
|
||||||
@ -72,6 +75,7 @@ export const routes = [
|
|||||||
component: Features,
|
component: Features,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
|
|
||||||
// Strategies
|
// Strategies
|
||||||
@ -82,6 +86,7 @@ export const routes = [
|
|||||||
component: CreateStrategies,
|
component: CreateStrategies,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/strategies/:activeTab/:strategyName',
|
path: '/strategies/:activeTab/:strategyName',
|
||||||
@ -90,6 +95,7 @@ export const routes = [
|
|||||||
component: StrategyView,
|
component: StrategyView,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/strategies',
|
path: '/strategies',
|
||||||
@ -97,6 +103,7 @@ export const routes = [
|
|||||||
component: Strategies,
|
component: Strategies,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: { advanced: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
// History
|
// History
|
||||||
@ -107,6 +114,7 @@ export const routes = [
|
|||||||
component: HistoryTogglePage,
|
component: HistoryTogglePage,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/history',
|
path: '/history',
|
||||||
@ -114,6 +122,7 @@ export const routes = [
|
|||||||
component: HistoryPage,
|
component: HistoryPage,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: { adminSettings: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
// Archive
|
// Archive
|
||||||
@ -124,6 +133,7 @@ export const routes = [
|
|||||||
component: ShowArchive,
|
component: ShowArchive,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/archive',
|
path: '/archive',
|
||||||
@ -131,6 +141,7 @@ export const routes = [
|
|||||||
component: Archive,
|
component: Archive,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
|
|
||||||
// Applications
|
// Applications
|
||||||
@ -141,6 +152,7 @@ export const routes = [
|
|||||||
component: ApplicationView,
|
component: ApplicationView,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/applications',
|
path: '/applications',
|
||||||
@ -148,6 +160,7 @@ export const routes = [
|
|||||||
component: Applications,
|
component: Applications,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: { advanced: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
// Context
|
// Context
|
||||||
@ -158,6 +171,7 @@ export const routes = [
|
|||||||
component: CreateContextField,
|
component: CreateContextField,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/context/edit/:name',
|
path: '/context/edit/:name',
|
||||||
@ -166,6 +180,7 @@ export const routes = [
|
|||||||
component: EditContextField,
|
component: EditContextField,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/context',
|
path: '/context',
|
||||||
@ -174,6 +189,7 @@ export const routes = [
|
|||||||
type: 'protected',
|
type: 'protected',
|
||||||
flag: C,
|
flag: C,
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: { advanced: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
// Project
|
// Project
|
||||||
@ -184,6 +200,7 @@ export const routes = [
|
|||||||
component: CreateProject,
|
component: CreateProject,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/projects/edit/:id',
|
path: '/projects/edit/:id',
|
||||||
@ -192,6 +209,7 @@ export const routes = [
|
|||||||
component: EditProject,
|
component: EditProject,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/projects/view/:id',
|
path: '/projects/view/:id',
|
||||||
@ -200,6 +218,7 @@ export const routes = [
|
|||||||
component: ViewProject,
|
component: ViewProject,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/projects/:id/access',
|
path: '/projects/:id/access',
|
||||||
@ -208,6 +227,7 @@ export const routes = [
|
|||||||
component: EditProjectAccess,
|
component: EditProjectAccess,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/projects/:id',
|
path: '/projects/:id',
|
||||||
@ -217,6 +237,7 @@ export const routes = [
|
|||||||
flag: P,
|
flag: P,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/projects',
|
path: '/projects',
|
||||||
@ -225,6 +246,7 @@ export const routes = [
|
|||||||
flag: P,
|
flag: P,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -234,6 +256,7 @@ export const routes = [
|
|||||||
component: CreateTagType,
|
component: CreateTagType,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/tag-types/edit/:name',
|
path: '/tag-types/edit/:name',
|
||||||
@ -242,6 +265,7 @@ export const routes = [
|
|||||||
component: EditTagType,
|
component: EditTagType,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/tag-types',
|
path: '/tag-types',
|
||||||
@ -249,6 +273,7 @@ export const routes = [
|
|||||||
component: ListTagTypes,
|
component: ListTagTypes,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: { advanced: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -258,6 +283,7 @@ export const routes = [
|
|||||||
component: CreateTag,
|
component: CreateTag,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/tags',
|
path: '/tags',
|
||||||
@ -266,6 +292,7 @@ export const routes = [
|
|||||||
hidden: true,
|
hidden: true,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
|
|
||||||
// Addons
|
// Addons
|
||||||
@ -276,6 +303,7 @@ export const routes = [
|
|||||||
component: AddonsCreate,
|
component: AddonsCreate,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/addons/edit/:id',
|
path: '/addons/edit/:id',
|
||||||
@ -284,6 +312,7 @@ export const routes = [
|
|||||||
component: AddonsEdit,
|
component: AddonsEdit,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/addons',
|
path: '/addons',
|
||||||
@ -292,6 +321,7 @@ export const routes = [
|
|||||||
hidden: false,
|
hidden: false,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: { advanced: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/reporting',
|
path: '/reporting',
|
||||||
@ -299,6 +329,7 @@ export const routes = [
|
|||||||
component: Reporting,
|
component: Reporting,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: { advanced: true },
|
||||||
},
|
},
|
||||||
// Admin
|
// Admin
|
||||||
{
|
{
|
||||||
@ -308,6 +339,7 @@ export const routes = [
|
|||||||
component: AdminApi,
|
component: AdminApi,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: { advanced: true, adminSettings: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/admin/users',
|
path: '/admin/users',
|
||||||
@ -316,6 +348,7 @@ export const routes = [
|
|||||||
component: AdminUsers,
|
component: AdminUsers,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: { adminSettings: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/admin/auth',
|
path: '/admin/auth',
|
||||||
@ -324,6 +357,7 @@ export const routes = [
|
|||||||
component: AdminAuth,
|
component: AdminAuth,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: { adminSettings: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/admin-invoices',
|
path: '/admin-invoices',
|
||||||
@ -332,6 +366,7 @@ export const routes = [
|
|||||||
hidden: true,
|
hidden: true,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: { adminSettings: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/admin',
|
path: '/admin',
|
||||||
@ -340,6 +375,7 @@ export const routes = [
|
|||||||
hidden: false,
|
hidden: false,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
layout: 'main',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/login',
|
path: '/login',
|
||||||
@ -348,6 +384,7 @@ export const routes = [
|
|||||||
type: 'unprotected',
|
type: 'unprotected',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
layout: 'standalone',
|
layout: 'standalone',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/new-user',
|
path: '/new-user',
|
||||||
@ -356,6 +393,7 @@ export const routes = [
|
|||||||
component: NewUser,
|
component: NewUser,
|
||||||
type: 'unprotected',
|
type: 'unprotected',
|
||||||
layout: 'standalone',
|
layout: 'standalone',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/reset-password',
|
path: '/reset-password',
|
||||||
@ -364,6 +402,7 @@ export const routes = [
|
|||||||
component: ResetPassword,
|
component: ResetPassword,
|
||||||
type: 'unprotected',
|
type: 'unprotected',
|
||||||
layout: 'standalone',
|
layout: 'standalone',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/forgotten-password',
|
path: '/forgotten-password',
|
||||||
@ -372,6 +411,7 @@ export const routes = [
|
|||||||
component: ForgottenPassword,
|
component: ForgottenPassword,
|
||||||
type: 'unprotected',
|
type: 'unprotected',
|
||||||
layout: 'standalone',
|
layout: 'standalone',
|
||||||
|
menu: {},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -382,27 +422,12 @@ export const baseRoutes = routes
|
|||||||
.filter(route => !route.parent);
|
.filter(route => !route.parent);
|
||||||
|
|
||||||
const computeRoutes = () => {
|
const computeRoutes = () => {
|
||||||
const apiAccess = routes.find(route => route.path === '/admin/api');
|
const mainNavRoutes = baseRoutes.filter(route => route.menu.advanced);
|
||||||
const mainNavRoutes =
|
const adminRoutes = routes.filter(route => route.menu.adminSettings);
|
||||||
baseRoutes.filter(
|
|
||||||
route =>
|
|
||||||
route.path !== '/admin' &&
|
|
||||||
route.path !== '/logout' &&
|
|
||||||
route.path !== '/history'
|
|
||||||
) || [];
|
|
||||||
|
|
||||||
mainNavRoutes.push(apiAccess);
|
|
||||||
|
|
||||||
const computedRoutes = {
|
const computedRoutes = {
|
||||||
mainNavRoutes,
|
mainNavRoutes,
|
||||||
adminRoutes:
|
adminRoutes,
|
||||||
routes.filter(
|
|
||||||
route =>
|
|
||||||
(route.path.startsWith('/admin') &&
|
|
||||||
route.path !== '/admin-invoices' &&
|
|
||||||
route.path !== '/admin') ||
|
|
||||||
route.path === '/history'
|
|
||||||
) || [],
|
|
||||||
};
|
};
|
||||||
return () => {
|
return () => {
|
||||||
return computedRoutes;
|
return computedRoutes;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import PropTypes from 'prop-types';
|
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 ConditionallyRender from '../../common/ConditionallyRender';
|
||||||
import { useHistory } from 'react-router';
|
import { useHistory } from 'react-router';
|
||||||
import { useCommonStyles } from '../../../common.styles';
|
import { useCommonStyles } from '../../../common.styles';
|
||||||
@ -9,6 +9,7 @@ import { useStyles } from './PasswordAuth.styles';
|
|||||||
import useQueryParams from '../../../hooks/useQueryParams';
|
import useQueryParams from '../../../hooks/useQueryParams';
|
||||||
import AuthOptions from '../common/AuthOptions/AuthOptions';
|
import AuthOptions from '../common/AuthOptions/AuthOptions';
|
||||||
import DividerText from '../../common/DividerText/DividerText';
|
import DividerText from '../../common/DividerText/DividerText';
|
||||||
|
import { Alert } from '@material-ui/lab';
|
||||||
|
|
||||||
const PasswordAuth = ({ authDetails, passwordLogin }) => {
|
const PasswordAuth = ({ authDetails, passwordLogin }) => {
|
||||||
const commonStyles = useCommonStyles();
|
const commonStyles = useCommonStyles();
|
||||||
@ -57,6 +58,10 @@ const PasswordAuth = ({ authDetails, passwordLogin }) => {
|
|||||||
}));
|
}));
|
||||||
setPassword('');
|
setPassword('');
|
||||||
setUsername('');
|
setUsername('');
|
||||||
|
} else if (error.statusCode === 401) {
|
||||||
|
setErrors({
|
||||||
|
apiError: 'Invalid password and username combination.',
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
setErrors({
|
setErrors({
|
||||||
apiError: 'Unknown error while trying to authenticate.',
|
apiError: 'Unknown error while trying to authenticate.',
|
||||||
@ -70,9 +75,15 @@ const PasswordAuth = ({ authDetails, passwordLogin }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit} action={authDetails.path}>
|
<form onSubmit={handleSubmit} action={authDetails.path}>
|
||||||
<Typography variant="subtitle2" className={styles.apiError}>
|
<ConditionallyRender
|
||||||
{apiError}
|
condition={apiError}
|
||||||
</Typography>
|
show={
|
||||||
|
<Alert severity="error" className={styles.apiError}>
|
||||||
|
{apiError}
|
||||||
|
</Alert>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={classnames(
|
className={classnames(
|
||||||
styles.contentContainer,
|
styles.contentContainer,
|
||||||
|
@ -14,5 +14,6 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
},
|
},
|
||||||
apiError: {
|
apiError: {
|
||||||
color: theme.palette.error.main,
|
color: theme.palette.error.main,
|
||||||
|
marginBottom: '0.5rem',
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -9,14 +9,12 @@ import {
|
|||||||
Select,
|
Select,
|
||||||
InputLabel,
|
InputLabel,
|
||||||
} from '@material-ui/core';
|
} from '@material-ui/core';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { useStyles } from './UserProfileContent.styles';
|
import { useStyles } from './UserProfileContent.styles';
|
||||||
import { useCommonStyles } from '../../../../common.styles';
|
import { useCommonStyles } from '../../../../common.styles';
|
||||||
import { Alert } from '@material-ui/lab';
|
import { Alert } from '@material-ui/lab';
|
||||||
import EditProfile from '../EditProfile/EditProfile';
|
import EditProfile from '../EditProfile/EditProfile';
|
||||||
import legacyStyles from '../../user.module.scss';
|
import legacyStyles from '../../user.module.scss';
|
||||||
import usePermissions from '../../../../hooks/usePermissions';
|
|
||||||
import { getBasePath } from '../../../../utils/format-path';
|
import { getBasePath } from '../../../../utils/format-path';
|
||||||
|
|
||||||
const UserProfileContent = ({
|
const UserProfileContent = ({
|
||||||
@ -32,7 +30,6 @@ const UserProfileContent = ({
|
|||||||
const [updatedPassword, setUpdatedPassword] = useState(false);
|
const [updatedPassword, setUpdatedPassword] = useState(false);
|
||||||
const [edititingProfile, setEditingProfile] = useState(false);
|
const [edititingProfile, setEditingProfile] = useState(false);
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { isAdmin } = usePermissions();
|
|
||||||
|
|
||||||
const setLocale = value => {
|
const setLocale = value => {
|
||||||
updateSettingLocation('locale', value);
|
updateSettingLocation('locale', value);
|
||||||
@ -131,17 +128,6 @@ const UserProfileContent = ({
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
<div className={commonStyles.divider} />
|
<div className={commonStyles.divider} />
|
||||||
<ConditionallyRender
|
|
||||||
condition={isAdmin()}
|
|
||||||
show={
|
|
||||||
<Link
|
|
||||||
to="/admin-invoices"
|
|
||||||
className={styles.link}
|
|
||||||
>
|
|
||||||
Account and billing
|
|
||||||
</Link>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<a
|
<a
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
href="https://www.getunleash.io/privacy-policy"
|
href="https://www.getunleash.io/privacy-policy"
|
||||||
|
Loading…
Reference in New Issue
Block a user