mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-23 13:46:45 +02:00
feat: add operators splash page (#802)
* refactor: fix crash on null-valued project description * refactor: remove unused layout prop * refactor: use routes for splash components * feat: add operators splash page * refactor: fix styling issues * refactor: add some comments
This commit is contained in:
parent
3ccba76d75
commit
2a307523d6
@ -1,5 +1,4 @@
|
|||||||
import ConditionallyRender from './common/ConditionallyRender';
|
import ConditionallyRender from './common/ConditionallyRender';
|
||||||
import EnvironmentSplash from './common/EnvironmentSplash/EnvironmentSplash';
|
|
||||||
import Feedback from './common/Feedback/Feedback';
|
import Feedback from './common/Feedback/Feedback';
|
||||||
import LayoutPicker from './layout/LayoutPicker/LayoutPicker';
|
import LayoutPicker from './layout/LayoutPicker/LayoutPicker';
|
||||||
import Loader from './common/Loader/Loader';
|
import Loader from './common/Loader/Loader';
|
||||||
@ -10,28 +9,15 @@ import ToastRenderer from './common/ToastRenderer/ToastRenderer';
|
|||||||
import styles from './styles.module.scss';
|
import styles from './styles.module.scss';
|
||||||
import { Redirect, Route, Switch } from 'react-router-dom';
|
import { Redirect, Route, Switch } from 'react-router-dom';
|
||||||
import { routes } from './menu/routes';
|
import { routes } from './menu/routes';
|
||||||
import { useAuthDetails } from '../hooks/api/getters/useAuth/useAuthDetails';
|
import { useAuthDetails } from 'hooks/api/getters/useAuth/useAuthDetails';
|
||||||
import { useAuthUser } from '../hooks/api/getters/useAuth/useAuthUser';
|
import { useAuthUser } from 'hooks/api/getters/useAuth/useAuthUser';
|
||||||
import { useAuthSplash } from '../hooks/api/getters/useAuth/useAuthSplash';
|
import { SplashPageRedirect } from 'component/splash/SplashPageRedirect/SplashPageRedirect';
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
const { splash, refetchSplash } = useAuthSplash();
|
|
||||||
const { authDetails } = useAuthDetails();
|
const { authDetails } = useAuthDetails();
|
||||||
const { user } = useAuthUser();
|
const { user } = useAuthUser();
|
||||||
|
|
||||||
const isLoggedIn = Boolean(user?.id);
|
const isLoggedIn = Boolean(user?.id);
|
||||||
const hasFetchedAuth = Boolean(authDetails || user);
|
const hasFetchedAuth = Boolean(authDetails || user);
|
||||||
const showEnvSplash = isLoggedIn && splash?.environment === false;
|
|
||||||
|
|
||||||
const renderMainLayoutRoutes = () => {
|
|
||||||
return routes.filter(route => route.layout === 'main').map(renderRoute);
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderStandaloneRoutes = () => {
|
|
||||||
return routes
|
|
||||||
.filter(route => route.layout === 'standalone')
|
|
||||||
.map(renderRoute);
|
|
||||||
};
|
|
||||||
|
|
||||||
const isUnauthorized = (): boolean => {
|
const isUnauthorized = (): boolean => {
|
||||||
return !isLoggedIn;
|
return !isLoggedIn;
|
||||||
@ -73,34 +59,22 @@ export const App = () => {
|
|||||||
elseShow={
|
elseShow={
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<ToastRenderer />
|
<ToastRenderer />
|
||||||
|
<LayoutPicker>
|
||||||
<ConditionallyRender
|
<Switch>
|
||||||
condition={showEnvSplash}
|
<ProtectedRoute
|
||||||
show={
|
exact
|
||||||
<EnvironmentSplash onFinish={refetchSplash} />
|
path="/"
|
||||||
}
|
unauthorized={isUnauthorized()}
|
||||||
elseShow={
|
component={Redirect}
|
||||||
<LayoutPicker>
|
renderProps={{ to: '/features' }}
|
||||||
<Switch>
|
/>
|
||||||
<ProtectedRoute
|
{routes.map(renderRoute)}
|
||||||
exact
|
<Route path="/404" component={NotFound} />
|
||||||
path="/"
|
<Redirect to="/404" />
|
||||||
unauthorized={isUnauthorized()}
|
</Switch>
|
||||||
component={Redirect}
|
<Feedback openUrl="http://feedback.unleash.run" />
|
||||||
renderProps={{ to: '/features' }}
|
<SplashPageRedirect />
|
||||||
/>
|
</LayoutPicker>
|
||||||
{renderMainLayoutRoutes()}
|
|
||||||
{renderStandaloneRoutes()}
|
|
||||||
<Route
|
|
||||||
path="/404"
|
|
||||||
component={NotFound}
|
|
||||||
/>
|
|
||||||
<Redirect to="/404" />
|
|
||||||
</Switch>
|
|
||||||
<Feedback openUrl="http://feedback.unleash.run" />
|
|
||||||
</LayoutPicker>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -5,10 +5,10 @@ import { CANCEL } from '../ConstraintAccordionEdit';
|
|||||||
import { ConstraintFormHeader } from './ConstraintFormHeader/ConstraintFormHeader';
|
import { ConstraintFormHeader } from './ConstraintFormHeader/ConstraintFormHeader';
|
||||||
import { useStyles } from './ConstraintAccordionEditBody.styles';
|
import { useStyles } from './ConstraintAccordionEditBody.styles';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Alert } from '@material-ui/lab';
|
|
||||||
import { newOperators } from 'constants/operators';
|
import { newOperators } from 'constants/operators';
|
||||||
import ConditionallyRender from 'component/common/ConditionallyRender/ConditionallyRender';
|
import ConditionallyRender from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { oneOf } from 'utils/one-of';
|
import { oneOf } from 'utils/one-of';
|
||||||
|
import { OperatorUpgradeAlert } from 'component/common/OperatorUpgradeAlert/OperatorUpgradeAlert';
|
||||||
|
|
||||||
interface IConstraintAccordionBody {
|
interface IConstraintAccordionBody {
|
||||||
localConstraint: IConstraint;
|
localConstraint: IConstraint;
|
||||||
@ -37,12 +37,7 @@ export const ConstraintAccordionEditBody: React.FC<
|
|||||||
<>
|
<>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={oneOf(newOperators, localConstraint.operator)}
|
condition={oneOf(newOperators, localConstraint.operator)}
|
||||||
show={
|
show={<OperatorUpgradeAlert />}
|
||||||
<Alert severity="warning">
|
|
||||||
In order to use this constraint operator, you need to
|
|
||||||
update your SDK to the latest version.
|
|
||||||
</Alert>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className={styles.inputContainer}>
|
<div className={styles.inputContainer}>
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
import { Alert } from '@material-ui/lab';
|
||||||
|
|
||||||
|
export const OperatorUpgradeAlert = () => {
|
||||||
|
return (
|
||||||
|
<Alert severity="warning">
|
||||||
|
Remember to update your Unleash client! New operators require new
|
||||||
|
SDK versions. <OperatorDocsLink />.
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const OperatorDocsLink = () => {
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
href="https://docs.getunleash.io/advanced/strategy_constraints#strategy-constraint-operators"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
style={{ color: 'inherit' }}
|
||||||
|
>
|
||||||
|
Read more
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
};
|
@ -17,10 +17,12 @@ const LayoutPicker = ({ children }) => {
|
|||||||
const isResetPasswordSuccessPage = matchPath(pathname, {
|
const isResetPasswordSuccessPage = matchPath(pathname, {
|
||||||
path: '/reset-password-success',
|
path: '/reset-password-success',
|
||||||
});
|
});
|
||||||
|
|
||||||
const isForgottenPasswordPage = matchPath(pathname, {
|
const isForgottenPasswordPage = matchPath(pathname, {
|
||||||
path: '/forgotten-password',
|
path: '/forgotten-password',
|
||||||
});
|
});
|
||||||
|
const isSplashPage = matchPath(pathname, {
|
||||||
|
path: '/splash/:id',
|
||||||
|
});
|
||||||
|
|
||||||
const is404 = matchPath(pathname, { path: '/404' });
|
const is404 = matchPath(pathname, { path: '/404' });
|
||||||
|
|
||||||
@ -30,6 +32,7 @@ const LayoutPicker = ({ children }) => {
|
|||||||
isChangePasswordPage ||
|
isChangePasswordPage ||
|
||||||
isResetPasswordSuccessPage ||
|
isResetPasswordSuccessPage ||
|
||||||
isForgottenPasswordPage ||
|
isForgottenPasswordPage ||
|
||||||
|
isSplashPage ||
|
||||||
is404
|
is404
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,13 @@ exports[`returns all baseRoutes 1`] = `
|
|||||||
Array [
|
Array [
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
"menu": Object {},
|
||||||
|
"path": "/splash/:splashId",
|
||||||
|
"title": "Unleash",
|
||||||
|
"type": "protected",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"component": [Function],
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/projects",
|
"parent": "/projects",
|
||||||
"path": "/projects/create",
|
"path": "/projects/create",
|
||||||
@ -13,7 +19,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/projects",
|
"parent": "/projects",
|
||||||
"path": "/projects/:id/edit",
|
"path": "/projects/:id/edit",
|
||||||
@ -22,7 +27,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/archive",
|
"parent": "/archive",
|
||||||
"path": "/projects/:id/archived",
|
"path": "/projects/:id/archived",
|
||||||
@ -31,7 +35,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/projects/:id/features/:name/:activeTab",
|
"parent": "/projects/:id/features/:name/:activeTab",
|
||||||
"path": "/projects/:id/features/:name/:activeTab/copy",
|
"path": "/projects/:id/features/:name/:activeTab/copy",
|
||||||
@ -40,7 +43,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/projects",
|
"parent": "/projects",
|
||||||
"path": "/projects/:projectId/features/:featureId/edit",
|
"path": "/projects/:projectId/features/:featureId/edit",
|
||||||
@ -50,7 +52,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flags": "E",
|
"flags": "E",
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/projects",
|
"parent": "/projects",
|
||||||
"path": "/projects/:projectId/features/:featureId",
|
"path": "/projects/:projectId/features/:featureId",
|
||||||
@ -59,7 +60,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/projects",
|
"parent": "/projects",
|
||||||
"path": "/projects/:id/features/:name/:activeTab",
|
"path": "/projects/:id/features/:name/:activeTab",
|
||||||
@ -68,7 +68,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/projects/:id/features",
|
"parent": "/projects/:id/features",
|
||||||
"path": "/projects/:projectId/create-toggle",
|
"path": "/projects/:projectId/create-toggle",
|
||||||
@ -77,7 +76,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/features",
|
"parent": "/features",
|
||||||
"path": "/projects/:projectId/features2/:name",
|
"path": "/projects/:projectId/features2/:name",
|
||||||
@ -87,7 +85,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "P",
|
"flag": "P",
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/projects",
|
"parent": "/projects",
|
||||||
"path": "/projects/:id/:activeTab",
|
"path": "/projects/:id/:activeTab",
|
||||||
@ -97,7 +94,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "P",
|
"flag": "P",
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/projects",
|
"parent": "/projects",
|
||||||
"path": "/projects/:id",
|
"path": "/projects/:id",
|
||||||
@ -106,7 +102,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"mobile": true,
|
"mobile": true,
|
||||||
},
|
},
|
||||||
@ -116,7 +111,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/features",
|
"parent": "/features",
|
||||||
"path": "/features/:activeTab/:name",
|
"path": "/features/:activeTab/:name",
|
||||||
@ -125,7 +119,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"mobile": true,
|
"mobile": true,
|
||||||
},
|
},
|
||||||
@ -135,7 +128,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/applications",
|
"parent": "/applications",
|
||||||
"path": "/applications/:name",
|
"path": "/applications/:name",
|
||||||
@ -144,7 +136,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"advanced": true,
|
"advanced": true,
|
||||||
"mobile": true,
|
"mobile": true,
|
||||||
@ -156,7 +147,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "C",
|
"flag": "C",
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/context",
|
"parent": "/context",
|
||||||
"path": "/context/create",
|
"path": "/context/create",
|
||||||
@ -166,7 +156,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "C",
|
"flag": "C",
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/context",
|
"parent": "/context",
|
||||||
"path": "/context/edit/:name",
|
"path": "/context/edit/:name",
|
||||||
@ -176,7 +165,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "C",
|
"flag": "C",
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"advanced": true,
|
"advanced": true,
|
||||||
"mobile": true,
|
"mobile": true,
|
||||||
@ -187,7 +175,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/strategies",
|
"parent": "/strategies",
|
||||||
"path": "/strategies/create",
|
"path": "/strategies/create",
|
||||||
@ -196,7 +183,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/strategies",
|
"parent": "/strategies",
|
||||||
"path": "/strategies/:name/edit",
|
"path": "/strategies/:name/edit",
|
||||||
@ -205,7 +191,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/strategies",
|
"parent": "/strategies",
|
||||||
"path": "/strategies/:name",
|
"path": "/strategies/:name",
|
||||||
@ -214,7 +199,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"advanced": true,
|
"advanced": true,
|
||||||
"mobile": true,
|
"mobile": true,
|
||||||
@ -225,7 +209,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/environments",
|
"parent": "/environments",
|
||||||
"path": "/environments/create",
|
"path": "/environments/create",
|
||||||
@ -234,7 +217,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"path": "/environments/:id",
|
"path": "/environments/:id",
|
||||||
"title": "Edit",
|
"title": "Edit",
|
||||||
@ -243,7 +225,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "EEA",
|
"flag": "EEA",
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"advanced": true,
|
"advanced": true,
|
||||||
"mobile": true,
|
"mobile": true,
|
||||||
@ -254,7 +235,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/tag-types",
|
"parent": "/tag-types",
|
||||||
"path": "/tag-types/create",
|
"path": "/tag-types/create",
|
||||||
@ -263,7 +243,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/tag-types",
|
"parent": "/tag-types",
|
||||||
"path": "/tag-types/edit/:name",
|
"path": "/tag-types/edit/:name",
|
||||||
@ -272,7 +251,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"advanced": true,
|
"advanced": true,
|
||||||
"mobile": true,
|
"mobile": true,
|
||||||
@ -283,7 +261,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/addons",
|
"parent": "/addons",
|
||||||
"path": "/addons/create/:providerId",
|
"path": "/addons/create/:providerId",
|
||||||
@ -292,7 +269,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/addons",
|
"parent": "/addons",
|
||||||
"path": "/addons/edit/:addonId",
|
"path": "/addons/edit/:addonId",
|
||||||
@ -302,7 +278,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"advanced": true,
|
"advanced": true,
|
||||||
"mobile": true,
|
"mobile": true,
|
||||||
@ -315,7 +290,6 @@ Array [
|
|||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "SE",
|
"flag": "SE",
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"advanced": true,
|
"advanced": true,
|
||||||
"mobile": true,
|
"mobile": true,
|
||||||
@ -326,7 +300,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/history",
|
"parent": "/history",
|
||||||
"path": "/history/:toggleName",
|
"path": "/history/:toggleName",
|
||||||
@ -335,7 +308,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"adminSettings": true,
|
"adminSettings": true,
|
||||||
},
|
},
|
||||||
@ -345,7 +317,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"path": "/archive",
|
"path": "/archive",
|
||||||
"title": "Archived Toggles",
|
"title": "Archived Toggles",
|
||||||
@ -353,7 +324,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/admin",
|
"parent": "/admin",
|
||||||
"path": "/admin/api/create-token",
|
"path": "/admin/api/create-token",
|
||||||
@ -363,7 +333,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "RE",
|
"flag": "RE",
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"path": "/admin/create-project-role",
|
"path": "/admin/create-project-role",
|
||||||
"title": "Create",
|
"title": "Create",
|
||||||
@ -372,7 +341,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "RE",
|
"flag": "RE",
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"path": "/admin/roles/:id/edit",
|
"path": "/admin/roles/:id/edit",
|
||||||
"title": "Edit",
|
"title": "Edit",
|
||||||
@ -380,7 +348,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"advanced": true,
|
"advanced": true,
|
||||||
"mobile": true,
|
"mobile": true,
|
||||||
@ -392,7 +359,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"adminSettings": true,
|
"adminSettings": true,
|
||||||
},
|
},
|
||||||
@ -403,7 +369,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"parent": "/admin",
|
"parent": "/admin",
|
||||||
"path": "/admin/create-user",
|
"path": "/admin/create-user",
|
||||||
@ -412,7 +377,6 @@ Array [
|
|||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"adminSettings": true,
|
"adminSettings": true,
|
||||||
},
|
},
|
||||||
@ -424,7 +388,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "RE",
|
"flag": "RE",
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {
|
"menu": Object {
|
||||||
"adminSettings": true,
|
"adminSettings": true,
|
||||||
},
|
},
|
||||||
@ -436,7 +399,6 @@ Array [
|
|||||||
Object {
|
Object {
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"layout": "main",
|
|
||||||
"menu": Object {},
|
"menu": Object {},
|
||||||
"path": "/admin",
|
"path": "/admin",
|
||||||
"title": "Admin",
|
"title": "Admin",
|
||||||
|
@ -46,18 +46,26 @@ import { EventHistoryPage } from '../history/EventHistoryPage/EventHistoryPage';
|
|||||||
import { FeatureEventHistoryPage } from '../history/FeatureEventHistoryPage/FeatureEventHistoryPage';
|
import { FeatureEventHistoryPage } from '../history/FeatureEventHistoryPage/FeatureEventHistoryPage';
|
||||||
import { CreateStrategy } from '../strategies/CreateStrategy/CreateStrategy';
|
import { CreateStrategy } from '../strategies/CreateStrategy/CreateStrategy';
|
||||||
import { EditStrategy } from '../strategies/EditStrategy/EditStrategy';
|
import { EditStrategy } from '../strategies/EditStrategy/EditStrategy';
|
||||||
import { SegmentsList } from 'component/segments/SegmentList/SegmentList';
|
import { SegmentsList } from '../segments/SegmentList/SegmentList';
|
||||||
|
import { SplashPage } from '../splash/SplashPage/SplashPage';
|
||||||
|
|
||||||
export const routes = [
|
export const routes = [
|
||||||
// Project
|
// Splash
|
||||||
|
{
|
||||||
|
path: '/splash/:splashId',
|
||||||
|
title: 'Unleash',
|
||||||
|
component: SplashPage,
|
||||||
|
type: 'protected',
|
||||||
|
menu: {},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Project
|
||||||
{
|
{
|
||||||
path: '/projects/create',
|
path: '/projects/create',
|
||||||
parent: '/projects',
|
parent: '/projects',
|
||||||
title: 'Create',
|
title: 'Create',
|
||||||
component: CreateProject,
|
component: CreateProject,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -66,7 +74,6 @@ export const routes = [
|
|||||||
title: ':id',
|
title: ':id',
|
||||||
component: EditProject,
|
component: EditProject,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -75,7 +82,6 @@ export const routes = [
|
|||||||
parent: '/archive',
|
parent: '/archive',
|
||||||
component: RedirectArchive,
|
component: RedirectArchive,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -84,7 +90,6 @@ export const routes = [
|
|||||||
title: 'Copy',
|
title: 'Copy',
|
||||||
component: CopyFeatureToggle,
|
component: CopyFeatureToggle,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -93,7 +98,6 @@ export const routes = [
|
|||||||
title: 'Edit Feature',
|
title: 'Edit Feature',
|
||||||
component: EditFeature,
|
component: EditFeature,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -102,7 +106,6 @@ export const routes = [
|
|||||||
title: 'FeatureView',
|
title: 'FeatureView',
|
||||||
component: FeatureView,
|
component: FeatureView,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
flags: E,
|
flags: E,
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
@ -112,7 +115,6 @@ export const routes = [
|
|||||||
title: ':name',
|
title: ':name',
|
||||||
component: FeatureView,
|
component: FeatureView,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -121,7 +123,6 @@ export const routes = [
|
|||||||
title: 'Create feature toggle',
|
title: 'Create feature toggle',
|
||||||
component: CreateFeature,
|
component: CreateFeature,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -130,7 +131,6 @@ export const routes = [
|
|||||||
title: ':name',
|
title: ':name',
|
||||||
component: RedirectFeatureView,
|
component: RedirectFeatureView,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -140,7 +140,6 @@ export const routes = [
|
|||||||
component: Project,
|
component: Project,
|
||||||
flag: P,
|
flag: P,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -150,7 +149,6 @@ export const routes = [
|
|||||||
component: Project,
|
component: Project,
|
||||||
flag: P,
|
flag: P,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -158,7 +156,6 @@ export const routes = [
|
|||||||
title: 'Projects',
|
title: 'Projects',
|
||||||
component: ProjectListNew,
|
component: ProjectListNew,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { mobile: true },
|
menu: { mobile: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -169,7 +166,6 @@ export const routes = [
|
|||||||
title: ':name',
|
title: ':name',
|
||||||
component: RedirectFeatureView,
|
component: RedirectFeatureView,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -177,7 +173,6 @@ export const routes = [
|
|||||||
title: 'Feature Toggles',
|
title: 'Feature Toggles',
|
||||||
component: FeatureToggleListContainer,
|
component: FeatureToggleListContainer,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { mobile: true },
|
menu: { mobile: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -188,7 +183,6 @@ export const routes = [
|
|||||||
parent: '/applications',
|
parent: '/applications',
|
||||||
component: ApplicationEdit,
|
component: ApplicationEdit,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -196,7 +190,6 @@ export const routes = [
|
|||||||
title: 'Applications',
|
title: 'Applications',
|
||||||
component: ApplicationList,
|
component: ApplicationList,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { mobile: true, advanced: true },
|
menu: { mobile: true, advanced: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -207,7 +200,6 @@ export const routes = [
|
|||||||
title: 'Create',
|
title: 'Create',
|
||||||
component: CreateContext,
|
component: CreateContext,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
flag: C,
|
flag: C,
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
@ -217,7 +209,6 @@ export const routes = [
|
|||||||
title: ':name',
|
title: ':name',
|
||||||
component: EditContext,
|
component: EditContext,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
flag: C,
|
flag: C,
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
@ -227,7 +218,6 @@ export const routes = [
|
|||||||
component: ContextList,
|
component: ContextList,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
flag: C,
|
flag: C,
|
||||||
layout: 'main',
|
|
||||||
menu: { mobile: true, advanced: true },
|
menu: { mobile: true, advanced: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -238,7 +228,6 @@ export const routes = [
|
|||||||
parent: '/strategies',
|
parent: '/strategies',
|
||||||
component: CreateStrategy,
|
component: CreateStrategy,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -247,7 +236,6 @@ export const routes = [
|
|||||||
parent: '/strategies',
|
parent: '/strategies',
|
||||||
component: EditStrategy,
|
component: EditStrategy,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -256,7 +244,6 @@ export const routes = [
|
|||||||
parent: '/strategies',
|
parent: '/strategies',
|
||||||
component: StrategyView,
|
component: StrategyView,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -264,7 +251,6 @@ export const routes = [
|
|||||||
title: 'Strategies',
|
title: 'Strategies',
|
||||||
component: StrategiesList,
|
component: StrategiesList,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { mobile: true, advanced: true },
|
menu: { mobile: true, advanced: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -273,7 +259,6 @@ export const routes = [
|
|||||||
component: CreateEnvironment,
|
component: CreateEnvironment,
|
||||||
parent: '/environments',
|
parent: '/environments',
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -281,7 +266,6 @@ export const routes = [
|
|||||||
title: 'Edit',
|
title: 'Edit',
|
||||||
component: EditEnvironment,
|
component: EditEnvironment,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -289,7 +273,6 @@ export const routes = [
|
|||||||
title: 'Environments',
|
title: 'Environments',
|
||||||
component: EnvironmentList,
|
component: EnvironmentList,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
flag: EEA,
|
flag: EEA,
|
||||||
menu: { mobile: true, advanced: true },
|
menu: { mobile: true, advanced: true },
|
||||||
},
|
},
|
||||||
@ -301,7 +284,6 @@ export const routes = [
|
|||||||
title: 'Create',
|
title: 'Create',
|
||||||
component: CreateTagType,
|
component: CreateTagType,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -310,7 +292,6 @@ export const routes = [
|
|||||||
title: ':name',
|
title: ':name',
|
||||||
component: EditTagType,
|
component: EditTagType,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -318,7 +299,6 @@ export const routes = [
|
|||||||
title: 'Tag types',
|
title: 'Tag types',
|
||||||
component: TagTypeList,
|
component: TagTypeList,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { mobile: true, advanced: true },
|
menu: { mobile: true, advanced: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -329,7 +309,6 @@ export const routes = [
|
|||||||
title: 'Create',
|
title: 'Create',
|
||||||
component: CreateAddon,
|
component: CreateAddon,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -338,7 +317,6 @@ export const routes = [
|
|||||||
title: 'Edit',
|
title: 'Edit',
|
||||||
component: EditAddon,
|
component: EditAddon,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -347,7 +325,6 @@ export const routes = [
|
|||||||
component: AddonList,
|
component: AddonList,
|
||||||
hidden: false,
|
hidden: false,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { mobile: true, advanced: true },
|
menu: { mobile: true, advanced: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -359,7 +336,6 @@ export const routes = [
|
|||||||
component: SegmentsList,
|
component: SegmentsList,
|
||||||
hidden: false,
|
hidden: false,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { mobile: true, advanced: true },
|
menu: { mobile: true, advanced: true },
|
||||||
flag: SE,
|
flag: SE,
|
||||||
},
|
},
|
||||||
@ -371,7 +347,6 @@ export const routes = [
|
|||||||
parent: '/history',
|
parent: '/history',
|
||||||
component: FeatureEventHistoryPage,
|
component: FeatureEventHistoryPage,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -379,7 +354,6 @@ export const routes = [
|
|||||||
title: 'Event History',
|
title: 'Event History',
|
||||||
component: EventHistoryPage,
|
component: EventHistoryPage,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { adminSettings: true },
|
menu: { adminSettings: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -389,7 +363,6 @@ export const routes = [
|
|||||||
title: 'Archived Toggles',
|
title: 'Archived Toggles',
|
||||||
component: ArchiveListContainer,
|
component: ArchiveListContainer,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -400,7 +373,6 @@ export const routes = [
|
|||||||
title: 'API access',
|
title: 'API access',
|
||||||
component: CreateApiToken,
|
component: CreateApiToken,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -408,7 +380,6 @@ export const routes = [
|
|||||||
title: 'Create',
|
title: 'Create',
|
||||||
component: CreateProjectRole,
|
component: CreateProjectRole,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
flag: RE,
|
flag: RE,
|
||||||
},
|
},
|
||||||
@ -417,7 +388,6 @@ export const routes = [
|
|||||||
title: 'Edit',
|
title: 'Edit',
|
||||||
component: EditProjectRole,
|
component: EditProjectRole,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
flag: RE,
|
flag: RE,
|
||||||
},
|
},
|
||||||
@ -426,7 +396,6 @@ export const routes = [
|
|||||||
title: 'Edit',
|
title: 'Edit',
|
||||||
component: EditUser,
|
component: EditUser,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
hidden: true,
|
hidden: true,
|
||||||
},
|
},
|
||||||
@ -436,7 +405,6 @@ export const routes = [
|
|||||||
title: 'API access',
|
title: 'API access',
|
||||||
component: AdminApi,
|
component: AdminApi,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { mobile: true, advanced: true },
|
menu: { mobile: true, advanced: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -445,7 +413,6 @@ export const routes = [
|
|||||||
title: 'Users',
|
title: 'Users',
|
||||||
component: AdminUsers,
|
component: AdminUsers,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { adminSettings: true },
|
menu: { adminSettings: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -454,7 +421,6 @@ export const routes = [
|
|||||||
title: 'Users',
|
title: 'Users',
|
||||||
component: CreateUser,
|
component: CreateUser,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -463,7 +429,6 @@ export const routes = [
|
|||||||
title: 'Single Sign-On',
|
title: 'Single Sign-On',
|
||||||
component: AuthSettings,
|
component: AuthSettings,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { adminSettings: true },
|
menu: { adminSettings: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -472,7 +437,6 @@ export const routes = [
|
|||||||
component: AdminInvoice,
|
component: AdminInvoice,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: { adminSettings: true },
|
menu: { adminSettings: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -481,7 +445,6 @@ export const routes = [
|
|||||||
title: 'Project Roles',
|
title: 'Project Roles',
|
||||||
component: ProjectRoles,
|
component: ProjectRoles,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
flag: RE,
|
flag: RE,
|
||||||
menu: { adminSettings: true },
|
menu: { adminSettings: true },
|
||||||
},
|
},
|
||||||
@ -491,7 +454,6 @@ export const routes = [
|
|||||||
component: Admin,
|
component: Admin,
|
||||||
hidden: false,
|
hidden: false,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
layout: 'main',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
/* If you update this route path, make sure you update the path in SWRProvider.tsx */
|
/* If you update this route path, make sure you update the path in SWRProvider.tsx */
|
||||||
@ -502,7 +464,6 @@ export const routes = [
|
|||||||
component: Login,
|
component: Login,
|
||||||
type: 'unprotected',
|
type: 'unprotected',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
layout: 'standalone',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
/* If you update this route path, make sure you update the path in SWRProvider.tsx */
|
/* If you update this route path, make sure you update the path in SWRProvider.tsx */
|
||||||
@ -512,7 +473,6 @@ export const routes = [
|
|||||||
hidden: true,
|
hidden: true,
|
||||||
component: NewUser,
|
component: NewUser,
|
||||||
type: 'unprotected',
|
type: 'unprotected',
|
||||||
layout: 'standalone',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
/* If you update this route path, make sure you update the path in SWRProvider.tsx */
|
/* If you update this route path, make sure you update the path in SWRProvider.tsx */
|
||||||
@ -522,7 +482,6 @@ export const routes = [
|
|||||||
hidden: true,
|
hidden: true,
|
||||||
component: ResetPassword,
|
component: ResetPassword,
|
||||||
type: 'unprotected',
|
type: 'unprotected',
|
||||||
layout: 'standalone',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -531,7 +490,6 @@ export const routes = [
|
|||||||
hidden: true,
|
hidden: true,
|
||||||
component: ForgottenPassword,
|
component: ForgottenPassword,
|
||||||
type: 'unprotected',
|
type: 'unprotected',
|
||||||
layout: 'standalone',
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -22,7 +22,7 @@ interface IProjectInfoProps {
|
|||||||
memberCount: number;
|
memberCount: number;
|
||||||
featureCount: number;
|
featureCount: number;
|
||||||
health: number;
|
health: number;
|
||||||
description: string;
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProjectInfo = ({
|
const ProjectInfo = ({
|
||||||
@ -42,10 +42,11 @@ const ProjectInfo = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const LONG_DESCRIPTION = 100;
|
const LONG_DESCRIPTION = 100;
|
||||||
|
const isShortDescription =
|
||||||
|
!description || description.length < LONG_DESCRIPTION;
|
||||||
|
|
||||||
const permissionButtonClass = classnames({
|
const permissionButtonClass = classnames({
|
||||||
[styles.permissionButtonShortDesc]:
|
[styles.permissionButtonShortDesc]: isShortDescription,
|
||||||
description.length < LONG_DESCRIPTION,
|
|
||||||
});
|
});
|
||||||
const permissionButton = (
|
const permissionButton = (
|
||||||
<PermissionIconButton
|
<PermissionIconButton
|
||||||
@ -70,9 +71,7 @@ const ProjectInfo = ({
|
|||||||
condition={Boolean(description)}
|
condition={Boolean(description)}
|
||||||
show={
|
show={
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={
|
condition={isShortDescription}
|
||||||
description.length < LONG_DESCRIPTION
|
|
||||||
}
|
|
||||||
show={
|
show={
|
||||||
<p
|
<p
|
||||||
data-loading
|
data-loading
|
||||||
@ -113,7 +112,7 @@ const ProjectInfo = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={description.length < LONG_DESCRIPTION}
|
condition={isShortDescription}
|
||||||
show={permissionButton}
|
show={permissionButton}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
72
frontend/src/component/splash/SplashPage/SplashPage.tsx
Normal file
72
frontend/src/component/splash/SplashPage/SplashPage.tsx
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { Switch, Route, useHistory, Redirect } from 'react-router-dom';
|
||||||
|
import { SplashPageEnvironments } from '../SplashPageEnvironments/SplashPageEnvironments';
|
||||||
|
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||||
|
import useSplashApi from 'hooks/api/actions/useSplashApi/useSplashApi';
|
||||||
|
import { SplashPageOperators } from 'component/splash/SplashPageOperators/SplashPageOperators';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useAuthSplash } from 'hooks/api/getters/useAuth/useAuthSplash';
|
||||||
|
|
||||||
|
// All known splash IDs.
|
||||||
|
export const splashIds = ['environments', 'operators'] as const;
|
||||||
|
|
||||||
|
// Active splash IDs that may be shown to the user.
|
||||||
|
export const activeSplashIds: SplashId[] = ['operators'];
|
||||||
|
|
||||||
|
export type SplashId = typeof splashIds[number];
|
||||||
|
|
||||||
|
export const SplashPage = () => {
|
||||||
|
const splashId = useRequiredPathParam('splashId');
|
||||||
|
const isKnownId = isKnownSplashId(splashId);
|
||||||
|
const { refetchSplash } = useAuthSplash();
|
||||||
|
const { setSplashSeen } = useSplashApi();
|
||||||
|
|
||||||
|
// Close the splash "modal" on escape.
|
||||||
|
useNavigationOnKeydown('Escape', '/');
|
||||||
|
|
||||||
|
// Mark the splash ID as seen.
|
||||||
|
useEffect(() => {
|
||||||
|
if (splashId && isKnownId) {
|
||||||
|
setSplashSeen(splashId)
|
||||||
|
.then(() => refetchSplash())
|
||||||
|
.catch(console.warn);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [splashId, isKnownId]);
|
||||||
|
|
||||||
|
if (!isKnownId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Switch>
|
||||||
|
<Route path="/splash/environments">
|
||||||
|
<SplashPageEnvironments />
|
||||||
|
</Route>
|
||||||
|
<Route path="/splash/operators">
|
||||||
|
<SplashPageOperators />
|
||||||
|
</Route>
|
||||||
|
<Route>
|
||||||
|
<Redirect to="/" />
|
||||||
|
</Route>
|
||||||
|
</Switch>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const useNavigationOnKeydown = (key: string, path: string) => {
|
||||||
|
const { push } = useHistory();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handler = (event: KeyboardEvent) => {
|
||||||
|
if (event.code === key) {
|
||||||
|
push(path);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('keydown', handler);
|
||||||
|
return () => window.removeEventListener('keydown', handler);
|
||||||
|
}, [key, path, push]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isKnownSplashId = (value: string): value is SplashId => {
|
||||||
|
return (splashIds as Readonly<string[]>).includes(value);
|
||||||
|
};
|
@ -1,33 +1,25 @@
|
|||||||
import Splash from '../Splash/Splash';
|
import { SplashPageEnvironmentsContent } from 'component/splash/SplashPageEnvironments/SplashPageEnvironmentsContent/SplashPageEnvironmentsContent';
|
||||||
import EnvironmentSplashPage from './EnvironmentSplashPage/EnvironmentSplashPage';
|
import { SplashPageEnvironmentsContainer } from 'component/splash/SplashPageEnvironments/SplashPageEnvironmentsContainer/SplashPageEnvironmentsContainer';
|
||||||
import { VpnKey, CloudCircle } from '@material-ui/icons';
|
import { VpnKey, CloudCircle } from '@material-ui/icons';
|
||||||
import { useStyles } from './EnvironmentSplash.styles';
|
import { useStyles } from 'component/splash/SplashPageEnvironments/SplashPageEnvironments.styles';
|
||||||
import { ReactComponent as Logo1 } from '../../../assets/img/splash_env1.svg';
|
import { ReactComponent as Logo1 } from 'assets/img/splash_env1.svg';
|
||||||
import { ReactComponent as Logo2 } from '../../../assets/img/splash_env2.svg';
|
import { ReactComponent as Logo2 } from 'assets/img/splash_env2.svg';
|
||||||
import { useEffect } from 'react';
|
import { useHistory } from 'react-router-dom';
|
||||||
import useSplashApi from '../../../hooks/api/actions/useSplashApi/useSplashApi';
|
|
||||||
|
|
||||||
interface IEnvironmentSplashProps {
|
export const SplashPageEnvironments = () => {
|
||||||
onFinish: (status: boolean) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ENVIRONMENT_SPLASH_ID = 'environment';
|
|
||||||
|
|
||||||
const EnvironmentSplash = ({ onFinish }: IEnvironmentSplashProps) => {
|
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { setSplashSeen } = useSplashApi();
|
const { push } = useHistory();
|
||||||
|
|
||||||
useEffect(() => {
|
const onFinish = () => {
|
||||||
setSplashSeen(ENVIRONMENT_SPLASH_ID);
|
push('/');
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
};
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Splash
|
<SplashPageEnvironmentsContent
|
||||||
onFinish={onFinish}
|
onFinish={onFinish}
|
||||||
components={[
|
components={[
|
||||||
<EnvironmentSplashPage
|
<SplashPageEnvironmentsContainer
|
||||||
key={1}
|
key={1}
|
||||||
title={
|
title={
|
||||||
<h2 className={styles.title}>
|
<h2 className={styles.title}>
|
||||||
@ -61,7 +53,7 @@ const EnvironmentSplash = ({ onFinish }: IEnvironmentSplashProps) => {
|
|||||||
}
|
}
|
||||||
image={<CloudCircle className={styles.icon} />}
|
image={<CloudCircle className={styles.icon} />}
|
||||||
/>,
|
/>,
|
||||||
<EnvironmentSplashPage
|
<SplashPageEnvironmentsContainer
|
||||||
key={2}
|
key={2}
|
||||||
title={
|
title={
|
||||||
<h2 className={styles.title}>
|
<h2 className={styles.title}>
|
||||||
@ -79,7 +71,7 @@ const EnvironmentSplash = ({ onFinish }: IEnvironmentSplashProps) => {
|
|||||||
}
|
}
|
||||||
image={<Logo1 className={styles.logo} />}
|
image={<Logo1 className={styles.logo} />}
|
||||||
/>,
|
/>,
|
||||||
<EnvironmentSplashPage
|
<SplashPageEnvironmentsContainer
|
||||||
key={3}
|
key={3}
|
||||||
title={
|
title={
|
||||||
<h2 className={styles.title}>
|
<h2 className={styles.title}>
|
||||||
@ -99,7 +91,7 @@ const EnvironmentSplash = ({ onFinish }: IEnvironmentSplashProps) => {
|
|||||||
}
|
}
|
||||||
image={<Logo2 className={styles.logo} />}
|
image={<Logo2 className={styles.logo} />}
|
||||||
/>,
|
/>,
|
||||||
<EnvironmentSplashPage
|
<SplashPageEnvironmentsContainer
|
||||||
key={4}
|
key={4}
|
||||||
title={
|
title={
|
||||||
<h2 className={styles.title}>
|
<h2 className={styles.title}>
|
||||||
@ -125,7 +117,7 @@ const EnvironmentSplash = ({ onFinish }: IEnvironmentSplashProps) => {
|
|||||||
}
|
}
|
||||||
image={<VpnKey className={styles.icon} />}
|
image={<VpnKey className={styles.icon} />}
|
||||||
/>,
|
/>,
|
||||||
<EnvironmentSplashPage
|
<SplashPageEnvironmentsContainer
|
||||||
key={5}
|
key={5}
|
||||||
title={
|
title={
|
||||||
<h2 className={styles.title}>Want to know more?</h2>
|
<h2 className={styles.title}>Want to know more?</h2>
|
||||||
@ -202,5 +194,3 @@ const EnvironmentSplash = ({ onFinish }: IEnvironmentSplashProps) => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EnvironmentSplash;
|
|
@ -1,18 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
interface EnvironmentSplashPageProps {
|
interface ISplashPageEnvironmentsContainerProps {
|
||||||
title: React.ReactNode;
|
title: React.ReactNode;
|
||||||
topDescription: React.ReactNode;
|
topDescription: React.ReactNode;
|
||||||
image?: React.ReactNode;
|
image?: React.ReactNode;
|
||||||
bottomDescription?: React.ReactNode;
|
bottomDescription?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EnvironmentSplashPage = ({
|
export const SplashPageEnvironmentsContainer = ({
|
||||||
title,
|
title,
|
||||||
topDescription,
|
topDescription,
|
||||||
image,
|
image,
|
||||||
bottomDescription,
|
bottomDescription,
|
||||||
}: EnvironmentSplashPageProps) => {
|
}: ISplashPageEnvironmentsContainerProps) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{title}
|
{title}
|
||||||
@ -22,5 +22,3 @@ const EnvironmentSplashPage = ({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EnvironmentSplashPage;
|
|
@ -4,6 +4,7 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
splashMainContainer: {
|
splashMainContainer: {
|
||||||
backgroundColor: theme.palette.primary.light,
|
backgroundColor: theme.palette.primary.light,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
minHeight: '100vh',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
@ -1,23 +1,22 @@
|
|||||||
import React, { Fragment, useState } from 'react';
|
import React, { Fragment, useState } from 'react';
|
||||||
import { Button, IconButton } from '@material-ui/core';
|
import { Button, IconButton } from '@material-ui/core';
|
||||||
import { useStyles } from './Splash.styles';
|
import { useStyles } from 'component/splash/SplashPageEnvironments/SplashPageEnvironmentsContent/SplashPageEnvironmentsContent.styles';
|
||||||
import {
|
import {
|
||||||
CloseOutlined,
|
CloseOutlined,
|
||||||
FiberManualRecord,
|
FiberManualRecord,
|
||||||
FiberManualRecordOutlined,
|
FiberManualRecordOutlined,
|
||||||
} from '@material-ui/icons';
|
} from '@material-ui/icons';
|
||||||
import ConditionallyRender from '../ConditionallyRender';
|
import ConditionallyRender from 'component/common/ConditionallyRender';
|
||||||
import { CLOSE_SPLASH } from '../../../testIds';
|
import { CLOSE_SPLASH } from 'testIds';
|
||||||
|
|
||||||
interface ISplashProps {
|
interface ISplashPageEnvironmentsContentProps {
|
||||||
components: React.ReactNode[];
|
components: React.ReactNode[];
|
||||||
onFinish: (status: boolean) => void;
|
onFinish: (status: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Splash: React.FC<ISplashProps> = ({
|
export const SplashPageEnvironmentsContent: React.FC<
|
||||||
components,
|
ISplashPageEnvironmentsContentProps
|
||||||
onFinish,
|
> = ({ components, onFinish }: ISplashPageEnvironmentsContentProps) => {
|
||||||
}: ISplashProps) => {
|
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const [counter, setCounter] = useState(0);
|
const [counter, setCounter] = useState(0);
|
||||||
|
|
||||||
@ -76,7 +75,7 @@ const Splash: React.FC<ISplashProps> = ({
|
|||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
data-test={CLOSE_SPLASH}
|
data-test={CLOSE_SPLASH}
|
||||||
>
|
>
|
||||||
<CloseOutlined />
|
<CloseOutlined titleAccess="Close" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</div>
|
||||||
{components[counter]}
|
{components[counter]}
|
||||||
@ -109,5 +108,3 @@ const Splash: React.FC<ISplashProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Splash;
|
|
@ -0,0 +1,78 @@
|
|||||||
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
|
|
||||||
|
export const useStyles = makeStyles(theme => ({
|
||||||
|
container: {
|
||||||
|
backgroundColor: theme.palette.primary.light,
|
||||||
|
minHeight: '100vh',
|
||||||
|
padding: '1rem',
|
||||||
|
display: 'grid',
|
||||||
|
gap: '1rem',
|
||||||
|
alignItems: 'center',
|
||||||
|
alignContent: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gridTemplateColumns: 'minmax(0,auto)',
|
||||||
|
fontWeight: theme.fontWeight.thin,
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
position: 'relative',
|
||||||
|
padding: '2rem',
|
||||||
|
borderRadius: '0.5rem',
|
||||||
|
backgroundColor: theme.palette.primary.main,
|
||||||
|
color: 'white',
|
||||||
|
[theme.breakpoints.up('md')]: {
|
||||||
|
padding: '4rem',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
footer: {
|
||||||
|
display: 'grid',
|
||||||
|
gap: '2rem',
|
||||||
|
textAlign: 'center',
|
||||||
|
justifyItems: 'center',
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
margin: '2rem 0',
|
||||||
|
padding: '2rem 0',
|
||||||
|
borderTop: '1px solid',
|
||||||
|
borderBottom: '1px solid',
|
||||||
|
borderTopColor: theme.palette.primary.light,
|
||||||
|
borderBottomColor: theme.palette.primary.light,
|
||||||
|
},
|
||||||
|
close: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
color: 'inherit',
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontWeight: 'inherit',
|
||||||
|
},
|
||||||
|
ingress: {
|
||||||
|
maxWidth: '32rem',
|
||||||
|
margin: '1.5rem auto 0 auto',
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
padding: '1rem 0',
|
||||||
|
[theme.breakpoints.up('md')]: {
|
||||||
|
padding: '1rem 2rem',
|
||||||
|
},
|
||||||
|
'& li + li': {
|
||||||
|
marginTop: '0.25rem',
|
||||||
|
},
|
||||||
|
'& strong': {
|
||||||
|
padding: '0 .2rem',
|
||||||
|
fontSize: theme.fontSizes.smallBody,
|
||||||
|
fontWeight: 'inherit',
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.2)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
color: 'inherit',
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
background: 'white',
|
||||||
|
color: theme.palette.primary.main,
|
||||||
|
},
|
||||||
|
}));
|
@ -0,0 +1,91 @@
|
|||||||
|
import { useStyles } from 'component/splash/SplashPageOperators/SplashPageOperators.styles';
|
||||||
|
import { Link, useHistory } from 'react-router-dom';
|
||||||
|
import { Button, IconButton } from '@material-ui/core';
|
||||||
|
import { CloseOutlined } from '@material-ui/icons';
|
||||||
|
import { OperatorUpgradeAlert } from 'component/common/OperatorUpgradeAlert/OperatorUpgradeAlert';
|
||||||
|
|
||||||
|
export const SplashPageOperators = () => {
|
||||||
|
const { push } = useHistory();
|
||||||
|
const styles = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={styles.container}>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<header className={styles.header}>
|
||||||
|
<h1 className={styles.title}>New strategy operators</h1>
|
||||||
|
<IconButton
|
||||||
|
className={styles.close}
|
||||||
|
onClick={() => push('/')}
|
||||||
|
>
|
||||||
|
<CloseOutlined titleAccess="Close" />
|
||||||
|
</IconButton>
|
||||||
|
<p className={styles.ingress}>
|
||||||
|
We've added some new feature strategy constraint
|
||||||
|
operators. Fine-tune your feature targeting like never
|
||||||
|
before.
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
<div className={styles.body}>
|
||||||
|
<p>For example:</p>
|
||||||
|
<ul className={styles.list}>
|
||||||
|
<li>
|
||||||
|
<span>Toggle features at dates: </span>
|
||||||
|
<span>
|
||||||
|
<strong>DATE_BEFORE</strong>{' '}
|
||||||
|
<strong>DATE_AFTER</strong>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span>Toggle features for versions: </span>
|
||||||
|
<span>
|
||||||
|
<strong>SEMVER_EQ</strong>{' '}
|
||||||
|
<strong>SEMVER_GT</strong>{' '}
|
||||||
|
<strong>SEMVER_LT</strong>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span>Toggle features for strings: </span>
|
||||||
|
<span>
|
||||||
|
<strong>STR_CONTAINS</strong>{' '}
|
||||||
|
<strong>STR_ENDS_WITH</strong>{' '}
|
||||||
|
<strong>STR_STARTS_WITH</strong>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span>Toggle features for numbers: </span>
|
||||||
|
<span>
|
||||||
|
<strong>NUM_GT</strong> <strong>NUM_GTE</strong>{' '}
|
||||||
|
<strong>NUM_LT</strong> <strong>NUM_LTE</strong>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<footer className={styles.footer}>
|
||||||
|
<p>
|
||||||
|
<a
|
||||||
|
href="https://docs.getunleash.io/advanced/strategy_constraints#numeric-operators"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className={styles.link}
|
||||||
|
>
|
||||||
|
Read all about operators in our in-depth{' '}
|
||||||
|
<strong>docs</strong>
|
||||||
|
</a>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<Button
|
||||||
|
className={styles.button}
|
||||||
|
variant="contained"
|
||||||
|
component={Link}
|
||||||
|
to="/"
|
||||||
|
>
|
||||||
|
Fine, whatever, I have work to do!
|
||||||
|
</Button>
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
<OperatorUpgradeAlert />
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,52 @@
|
|||||||
|
import { useAuthSplash } from 'hooks/api/getters/useAuth/useAuthSplash';
|
||||||
|
import { useLocation, Redirect } from 'react-router-dom';
|
||||||
|
import { matchPath } from 'react-router';
|
||||||
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
|
import { IFlags } from 'interfaces/uiConfig';
|
||||||
|
import { IAuthSplash } from 'hooks/api/getters/useAuth/useAuthEndpoint';
|
||||||
|
import {
|
||||||
|
activeSplashIds,
|
||||||
|
SplashId,
|
||||||
|
} from 'component/splash/SplashPage/SplashPage';
|
||||||
|
|
||||||
|
export const SplashPageRedirect = () => {
|
||||||
|
const { pathname } = useLocation();
|
||||||
|
const { splash } = useAuthSplash();
|
||||||
|
const { uiConfig, loading } = useUiConfig();
|
||||||
|
|
||||||
|
if (!splash || !uiConfig || loading) {
|
||||||
|
// Wait for everything to load.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchPath(pathname, { path: '/splash/:splashId' })) {
|
||||||
|
// We've already redirected to the splash page.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the splash page to show (if any).
|
||||||
|
const showSplashId = activeSplashIds.find(splashId => {
|
||||||
|
return (
|
||||||
|
isSplashRelevant(splashId, uiConfig.flags) &&
|
||||||
|
!hasSeenSplashId(splashId, splash)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!showSplashId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Redirect to={`/splash/${showSplashId}`} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const hasSeenSplashId = (splashId: SplashId, splash: IAuthSplash): boolean => {
|
||||||
|
return Boolean(splash[splashId]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isSplashRelevant = (splashId: SplashId, flags: IFlags): boolean => {
|
||||||
|
if (splashId === 'operators') {
|
||||||
|
return Boolean(flags.C || flags.CO);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
@ -15,7 +15,7 @@ export interface IProject {
|
|||||||
members: number;
|
members: number;
|
||||||
version: string;
|
version: string;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description?: string;
|
||||||
environments: string[];
|
environments: string[];
|
||||||
health: number;
|
health: number;
|
||||||
features: IFeatureToggleListItem[];
|
features: IFeatureToggleListItem[];
|
||||||
|
@ -6,7 +6,6 @@ interface IRoute {
|
|||||||
title?: string;
|
title?: string;
|
||||||
component: React.ComponentType;
|
component: React.ComponentType;
|
||||||
type: string;
|
type: string;
|
||||||
layout: string;
|
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
flag?: string;
|
flag?: string;
|
||||||
parent?: string;
|
parent?: string;
|
||||||
|
Loading…
Reference in New Issue
Block a user