mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-20 00:08:02 +01:00
fix: announce navigation to screen readers (#911)
* refactor: unify page titles * refactor: update page title on navigation * refactor: add AnnouncerContext to test contexts * fix: announce navigation to screen readers
This commit is contained in:
parent
06232a5522
commit
f7266cde10
@ -8,7 +8,7 @@
|
||||
<meta name="cdnPrefix" content="::cdnPrefix::" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="unleash" />
|
||||
<title>Unleash - Enterprise ready feature toggles</title>
|
||||
<title>Unleash</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { render } from 'utils/testRenderer';
|
||||
import { AnnouncerProvider } from 'component/common/Announcer/AnnouncerProvider/AnnouncerProvider';
|
||||
import { AnnouncerContext } from 'component/common/Announcer/AnnouncerContext/AnnouncerContext';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { screen } from '@testing-library/react';
|
||||
import { ANNOUNCER_ELEMENT_TEST_ID } from 'utils/testIds';
|
||||
|
||||
test('AnnouncerContext', async () => {
|
||||
const TestComponent = () => {
|
||||
@ -16,12 +16,9 @@ test('AnnouncerContext', async () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
render(
|
||||
<AnnouncerProvider>
|
||||
<TestComponent />
|
||||
</AnnouncerProvider>
|
||||
);
|
||||
render(<TestComponent />);
|
||||
|
||||
expect(screen.getByRole('status')).not.toHaveTextContent('Foo');
|
||||
expect(screen.getByRole('status')).toHaveTextContent('Bar');
|
||||
const el = screen.getByTestId(ANNOUNCER_ELEMENT_TEST_ID);
|
||||
expect(el).not.toHaveTextContent('Foo');
|
||||
expect(el).toHaveTextContent('Bar');
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { ReactElement } from 'react';
|
||||
import { useStyles } from 'component/common/Announcer/AnnouncerElement/AnnouncerElement.styles';
|
||||
import { ANNOUNCER_ELEMENT_TEST_ID } from 'utils/testIds';
|
||||
|
||||
interface IAnnouncerElementProps {
|
||||
announcement?: string;
|
||||
@ -16,6 +17,7 @@ export const AnnouncerElement = ({
|
||||
aria-live="polite"
|
||||
aria-atomic
|
||||
className={styles.container}
|
||||
data-testid={ANNOUNCER_ELEMENT_TEST_ID}
|
||||
>
|
||||
{announcement}
|
||||
</div>
|
||||
|
@ -6,6 +6,7 @@ import { Typography } from '@material-ui/core';
|
||||
import ConditionallyRender from '../ConditionallyRender/ConditionallyRender';
|
||||
|
||||
import { useStyles } from './styles';
|
||||
import { usePageTitle } from 'hooks/usePageTitle';
|
||||
|
||||
const HeaderTitle = ({
|
||||
title,
|
||||
@ -18,6 +19,8 @@ const HeaderTitle = ({
|
||||
const styles = useStyles();
|
||||
const headerClasses = classnames({ skeleton: loading });
|
||||
|
||||
usePageTitle(title);
|
||||
|
||||
return (
|
||||
<div className={styles.headerTitleContainer}>
|
||||
<div className={headerClasses} data-loading>
|
||||
|
@ -96,12 +96,12 @@ const FeatureToggleList = ({
|
||||
};
|
||||
|
||||
const searchResultsHeader = filter.query
|
||||
? `(${features.length} matches)`
|
||||
? ` (${features.length} matches)`
|
||||
: '';
|
||||
|
||||
const headerTitle = archive
|
||||
? `Archived Features ${searchResultsHeader}`
|
||||
: `Features ${searchResultsHeader}`;
|
||||
? `Archived feature toggles${searchResultsHeader}`
|
||||
: `Feature toggles${searchResultsHeader}`;
|
||||
|
||||
return (
|
||||
<div className={styles.featureContainer}>
|
||||
|
@ -6,6 +6,7 @@ import renderer from 'react-test-renderer';
|
||||
import theme from 'themes/mainTheme';
|
||||
import { CREATE_FEATURE } from 'component/providers/AccessProvider/permissions';
|
||||
import AccessProvider from 'component/providers/AccessProvider/AccessProvider';
|
||||
import { AnnouncerProvider } from 'component/common/Announcer/AnnouncerProvider/AnnouncerProvider';
|
||||
|
||||
jest.mock('./FeatureToggleListItem/FeatureToggleListItem', () => ({
|
||||
__esModule: true,
|
||||
@ -24,18 +25,22 @@ test('renders correctly with one feature', () => {
|
||||
const tree = renderer.create(
|
||||
<MemoryRouter>
|
||||
<ThemeProvider theme={theme}>
|
||||
<AccessProvider permissions={[{ permission: CREATE_FEATURE }]}>
|
||||
<FeatureToggleList
|
||||
updateSetting={jest.fn()}
|
||||
filter={{}}
|
||||
setFilter={jest.fn()}
|
||||
sort={{}}
|
||||
setSort={jest.fn()}
|
||||
features={features}
|
||||
fetcher={jest.fn()}
|
||||
flags={{}}
|
||||
/>
|
||||
</AccessProvider>
|
||||
<AnnouncerProvider>
|
||||
<AccessProvider
|
||||
permissions={[{ permission: CREATE_FEATURE }]}
|
||||
>
|
||||
<FeatureToggleList
|
||||
updateSetting={jest.fn()}
|
||||
filter={{}}
|
||||
setFilter={jest.fn()}
|
||||
sort={{}}
|
||||
setSort={jest.fn()}
|
||||
features={features}
|
||||
fetcher={jest.fn()}
|
||||
flags={{}}
|
||||
/>
|
||||
</AccessProvider>
|
||||
</AnnouncerProvider>
|
||||
</ThemeProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
@ -52,17 +57,21 @@ test('renders correctly with one feature without permissions', () => {
|
||||
const tree = renderer.create(
|
||||
<MemoryRouter>
|
||||
<ThemeProvider theme={theme}>
|
||||
<AccessProvider permissions={[{ permission: CREATE_FEATURE }]}>
|
||||
<FeatureToggleList
|
||||
filter={{}}
|
||||
setFilter={jest.fn()}
|
||||
sort={{}}
|
||||
setSort={jest.fn()}
|
||||
features={features}
|
||||
fetcher={jest.fn()}
|
||||
flags={{}}
|
||||
/>
|
||||
</AccessProvider>
|
||||
<AnnouncerProvider>
|
||||
<AccessProvider
|
||||
permissions={[{ permission: CREATE_FEATURE }]}
|
||||
>
|
||||
<FeatureToggleList
|
||||
filter={{}}
|
||||
setFilter={jest.fn()}
|
||||
sort={{}}
|
||||
setSort={jest.fn()}
|
||||
features={features}
|
||||
fetcher={jest.fn()}
|
||||
flags={{}}
|
||||
/>
|
||||
</AccessProvider>
|
||||
</AnnouncerProvider>
|
||||
</ThemeProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
@ -1,348 +1,368 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly with one feature 1`] = `
|
||||
<div>
|
||||
<div
|
||||
className="makeStyles-searchBarContainer-3"
|
||||
>
|
||||
<form
|
||||
className="makeStyles-container-6"
|
||||
role="search"
|
||||
>
|
||||
<div
|
||||
className="makeStyles-search-7 makeStyles-searchBar-4"
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root makeStyles-searchIcon-8"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
|
||||
/>
|
||||
</svg>
|
||||
<div
|
||||
className="MuiInputBase-root makeStyles-inputRoot-9"
|
||||
onClick={[Function]}
|
||||
onKeyPress={[Function]}
|
||||
>
|
||||
<input
|
||||
aria-label="search"
|
||||
className="MuiInputBase-input MuiInputBase-inputTypeSearch"
|
||||
onAnimationStart={[Function]}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder="Search..."
|
||||
type="search"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<a
|
||||
href="/archive"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Archive
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": "10px",
|
||||
"boxShadow": "none",
|
||||
}
|
||||
}
|
||||
>
|
||||
Array [
|
||||
<div>
|
||||
<div
|
||||
className="makeStyles-headerContainer-10"
|
||||
className="makeStyles-searchBarContainer-3"
|
||||
>
|
||||
<div
|
||||
className="makeStyles-headerTitleContainer-14"
|
||||
<form
|
||||
className="makeStyles-container-6"
|
||||
role="search"
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
data-loading={true}
|
||||
className="makeStyles-search-7 makeStyles-searchBar-4"
|
||||
>
|
||||
<h1
|
||||
className="MuiTypography-root makeStyles-headerTitle-15 MuiTypography-h1"
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root makeStyles-searchIcon-8"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
Features
|
||||
</h1>
|
||||
<path
|
||||
d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
|
||||
/>
|
||||
</svg>
|
||||
<div
|
||||
className="MuiInputBase-root makeStyles-inputRoot-9"
|
||||
onClick={[Function]}
|
||||
onKeyPress={[Function]}
|
||||
>
|
||||
<input
|
||||
aria-label="search"
|
||||
className="MuiInputBase-input MuiInputBase-inputTypeSearch"
|
||||
onAnimationStart={[Function]}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder="Search..."
|
||||
type="search"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<a
|
||||
href="/archive"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Archive
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": "10px",
|
||||
"boxShadow": "none",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="makeStyles-headerContainer-10"
|
||||
>
|
||||
<div
|
||||
className="makeStyles-headerActions-16"
|
||||
className="makeStyles-headerTitleContainer-14"
|
||||
>
|
||||
<div
|
||||
className="makeStyles-actionsContainer-1"
|
||||
className=""
|
||||
data-loading={true}
|
||||
>
|
||||
<h1
|
||||
className="MuiTypography-root makeStyles-headerTitle-15 MuiTypography-h1"
|
||||
>
|
||||
Feature toggles
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
className="makeStyles-headerActions-16"
|
||||
>
|
||||
<div
|
||||
className="makeStyles-actions-17"
|
||||
className="makeStyles-actionsContainer-1"
|
||||
>
|
||||
<p
|
||||
className="MuiTypography-root MuiTypography-body2"
|
||||
data-loading={true}
|
||||
<div
|
||||
className="makeStyles-actions-17"
|
||||
>
|
||||
Sorted by:
|
||||
</p>
|
||||
<button
|
||||
aria-controls="sorting"
|
||||
aria-haspopup="true"
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-text"
|
||||
data-loading={true}
|
||||
disabled={false}
|
||||
id="sorting"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fontWeight": "normal",
|
||||
"textTransform": "lowercase",
|
||||
}
|
||||
}
|
||||
tabIndex={0}
|
||||
title="Sort by"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="MuiButton-label"
|
||||
<p
|
||||
className="MuiTypography-root MuiTypography-body2"
|
||||
data-loading={true}
|
||||
>
|
||||
Sorted by:
|
||||
</p>
|
||||
<button
|
||||
aria-controls="sorting"
|
||||
aria-haspopup="true"
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-text"
|
||||
data-loading={true}
|
||||
disabled={false}
|
||||
id="sorting"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fontWeight": "normal",
|
||||
"textTransform": "lowercase",
|
||||
}
|
||||
}
|
||||
tabIndex={0}
|
||||
title="Sort by"
|
||||
type="button"
|
||||
>
|
||||
By Name
|
||||
<span
|
||||
className="MuiButton-endIcon MuiButton-iconSizeMedium"
|
||||
className="MuiButton-label"
|
||||
>
|
||||
By Name
|
||||
<span
|
||||
aria-hidden={true}
|
||||
className="material-icons MuiIcon-root"
|
||||
className="MuiButton-endIcon MuiButton-iconSizeMedium"
|
||||
>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
<span
|
||||
aria-hidden={true}
|
||||
className="material-icons MuiIcon-root"
|
||||
>
|
||||
<path
|
||||
d="M7 10l5 5 5-5z"
|
||||
/>
|
||||
<title>
|
||||
Toggle
|
||||
</title>
|
||||
</svg>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M7 10l5 5 5-5z"
|
||||
/>
|
||||
<title>
|
||||
Toggle
|
||||
</title>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="makeStyles-bodyContainer-11"
|
||||
>
|
||||
<ul
|
||||
className="MuiList-root MuiList-padding"
|
||||
<div
|
||||
className="makeStyles-bodyContainer-11"
|
||||
>
|
||||
<ListItem
|
||||
feature={
|
||||
Object {
|
||||
"name": "Another",
|
||||
"reviveName": "Another",
|
||||
<ul
|
||||
className="MuiList-root MuiList-padding"
|
||||
>
|
||||
<ListItem
|
||||
feature={
|
||||
Object {
|
||||
"name": "Another",
|
||||
"reviveName": "Another",
|
||||
}
|
||||
}
|
||||
}
|
||||
flags={Object {}}
|
||||
hasAccess={[Function]}
|
||||
/>
|
||||
</ul>
|
||||
flags={Object {}}
|
||||
hasAccess={[Function]}
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
aria-atomic={true}
|
||||
aria-live="polite"
|
||||
className="makeStyles-container-18"
|
||||
data-testid="ANNOUNCER_ELEMENT_TEST_ID"
|
||||
role="status"
|
||||
/>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders correctly with one feature without permissions 1`] = `
|
||||
<div>
|
||||
<div
|
||||
className="makeStyles-searchBarContainer-3"
|
||||
>
|
||||
<form
|
||||
className="makeStyles-container-6"
|
||||
role="search"
|
||||
>
|
||||
<div
|
||||
className="makeStyles-search-7 makeStyles-searchBar-4"
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root makeStyles-searchIcon-8"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
|
||||
/>
|
||||
</svg>
|
||||
<div
|
||||
className="MuiInputBase-root makeStyles-inputRoot-9"
|
||||
onClick={[Function]}
|
||||
onKeyPress={[Function]}
|
||||
>
|
||||
<input
|
||||
aria-label="search"
|
||||
className="MuiInputBase-input MuiInputBase-inputTypeSearch"
|
||||
onAnimationStart={[Function]}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder="Search..."
|
||||
type="search"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<a
|
||||
href="/archive"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Archive
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": "10px",
|
||||
"boxShadow": "none",
|
||||
}
|
||||
}
|
||||
>
|
||||
Array [
|
||||
<div>
|
||||
<div
|
||||
className="makeStyles-headerContainer-10"
|
||||
className="makeStyles-searchBarContainer-3"
|
||||
>
|
||||
<div
|
||||
className="makeStyles-headerTitleContainer-14"
|
||||
<form
|
||||
className="makeStyles-container-6"
|
||||
role="search"
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
data-loading={true}
|
||||
className="makeStyles-search-7 makeStyles-searchBar-4"
|
||||
>
|
||||
<h1
|
||||
className="MuiTypography-root makeStyles-headerTitle-15 MuiTypography-h1"
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root makeStyles-searchIcon-8"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
Features
|
||||
</h1>
|
||||
<path
|
||||
d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
|
||||
/>
|
||||
</svg>
|
||||
<div
|
||||
className="MuiInputBase-root makeStyles-inputRoot-9"
|
||||
onClick={[Function]}
|
||||
onKeyPress={[Function]}
|
||||
>
|
||||
<input
|
||||
aria-label="search"
|
||||
className="MuiInputBase-input MuiInputBase-inputTypeSearch"
|
||||
onAnimationStart={[Function]}
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder="Search..."
|
||||
type="search"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<a
|
||||
href="/archive"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Archive
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": "10px",
|
||||
"boxShadow": "none",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="makeStyles-headerContainer-10"
|
||||
>
|
||||
<div
|
||||
className="makeStyles-headerActions-16"
|
||||
className="makeStyles-headerTitleContainer-14"
|
||||
>
|
||||
<div
|
||||
className="makeStyles-actionsContainer-1"
|
||||
className=""
|
||||
data-loading={true}
|
||||
>
|
||||
<h1
|
||||
className="MuiTypography-root makeStyles-headerTitle-15 MuiTypography-h1"
|
||||
>
|
||||
Feature toggles
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
className="makeStyles-headerActions-16"
|
||||
>
|
||||
<div
|
||||
className="makeStyles-actions-17"
|
||||
className="makeStyles-actionsContainer-1"
|
||||
>
|
||||
<p
|
||||
className="MuiTypography-root MuiTypography-body2"
|
||||
data-loading={true}
|
||||
<div
|
||||
className="makeStyles-actions-17"
|
||||
>
|
||||
Sorted by:
|
||||
</p>
|
||||
<button
|
||||
aria-controls="sorting"
|
||||
aria-haspopup="true"
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-text"
|
||||
data-loading={true}
|
||||
disabled={false}
|
||||
id="sorting"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fontWeight": "normal",
|
||||
"textTransform": "lowercase",
|
||||
}
|
||||
}
|
||||
tabIndex={0}
|
||||
title="Sort by"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="MuiButton-label"
|
||||
<p
|
||||
className="MuiTypography-root MuiTypography-body2"
|
||||
data-loading={true}
|
||||
>
|
||||
Sorted by:
|
||||
</p>
|
||||
<button
|
||||
aria-controls="sorting"
|
||||
aria-haspopup="true"
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-text"
|
||||
data-loading={true}
|
||||
disabled={false}
|
||||
id="sorting"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"fontWeight": "normal",
|
||||
"textTransform": "lowercase",
|
||||
}
|
||||
}
|
||||
tabIndex={0}
|
||||
title="Sort by"
|
||||
type="button"
|
||||
>
|
||||
By Name
|
||||
<span
|
||||
className="MuiButton-endIcon MuiButton-iconSizeMedium"
|
||||
className="MuiButton-label"
|
||||
>
|
||||
By Name
|
||||
<span
|
||||
aria-hidden={true}
|
||||
className="material-icons MuiIcon-root"
|
||||
className="MuiButton-endIcon MuiButton-iconSizeMedium"
|
||||
>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
<span
|
||||
aria-hidden={true}
|
||||
className="material-icons MuiIcon-root"
|
||||
>
|
||||
<path
|
||||
d="M7 10l5 5 5-5z"
|
||||
/>
|
||||
<title>
|
||||
Toggle
|
||||
</title>
|
||||
</svg>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M7 10l5 5 5-5z"
|
||||
/>
|
||||
<title>
|
||||
Toggle
|
||||
</title>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
className="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<span
|
||||
className="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="makeStyles-bodyContainer-11"
|
||||
>
|
||||
<ul
|
||||
className="MuiList-root MuiList-padding"
|
||||
<div
|
||||
className="makeStyles-bodyContainer-11"
|
||||
>
|
||||
<ListItem
|
||||
feature={
|
||||
Object {
|
||||
"name": "Another",
|
||||
"reviveName": "Another",
|
||||
<ul
|
||||
className="MuiList-root MuiList-padding"
|
||||
>
|
||||
<ListItem
|
||||
feature={
|
||||
Object {
|
||||
"name": "Another",
|
||||
"reviveName": "Another",
|
||||
}
|
||||
}
|
||||
}
|
||||
flags={Object {}}
|
||||
hasAccess={[Function]}
|
||||
/>
|
||||
</ul>
|
||||
flags={Object {}}
|
||||
hasAccess={[Function]}
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
aria-atomic={true}
|
||||
aria-live="polite"
|
||||
className="makeStyles-container-18"
|
||||
data-testid="ANNOUNCER_ELEMENT_TEST_ID"
|
||||
role="status"
|
||||
>
|
||||
Navigated to Feature toggles
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
@ -16,12 +16,14 @@ import { FeatureMetricsChips } from './FeatureMetricsChips/FeatureMetricsChips';
|
||||
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
|
||||
import ConditionallyRender from 'component/common/ConditionallyRender';
|
||||
import { useStyles } from './FeatureMetrics.styles';
|
||||
import { usePageTitle } from 'hooks/usePageTitle';
|
||||
|
||||
export const FeatureMetrics = () => {
|
||||
const { projectId, featureId } = useParams<IFeatureViewParams>();
|
||||
const environments = useFeatureMetricsEnvironments(projectId, featureId);
|
||||
const applications = useFeatureMetricsApplications(featureId);
|
||||
const styles = useStyles();
|
||||
usePageTitle('Metrics');
|
||||
|
||||
const [hoursBack = FEATURE_METRIC_HOURS_BACK_MAX, setHoursBack] =
|
||||
useQueryStringNumberState('hoursBack');
|
||||
|
@ -10,15 +10,16 @@ import {
|
||||
formatFeaturePath,
|
||||
} from 'component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit';
|
||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||
import { usePageTitle } from 'hooks/usePageTitle';
|
||||
|
||||
const FeatureOverview = () => {
|
||||
const styles = useStyles();
|
||||
const { push } = useHistory();
|
||||
|
||||
const projectId = useRequiredPathParam('projectId');
|
||||
const featureId = useRequiredPathParam('featureId');
|
||||
const featurePath = formatFeaturePath(projectId, featureId);
|
||||
const onSidebarClose = () => push(featurePath);
|
||||
usePageTitle(featureId);
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { useStyles } from './FeatureVariants.styles';
|
||||
import FeatureOverviewVariants from './FeatureVariantsList/FeatureVariantsList';
|
||||
import { usePageTitle } from 'hooks/usePageTitle';
|
||||
|
||||
const FeatureVariants = () => {
|
||||
const styles = useStyles();
|
||||
usePageTitle('Variants');
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
|
@ -8,5 +8,5 @@ export const EventHistory = () => {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <EventLog history={events} title="Recent changes" />;
|
||||
return <EventLog history={events} title="Event log" />;
|
||||
};
|
||||
|
@ -10,7 +10,7 @@ export const FeatureEventHistory = ({ toggleName }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<EventLog history={events} hideName title="Change log" displayInline />
|
||||
<EventLog history={events} hideName title="Event log" displayInline />
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -23,6 +23,13 @@ exports[`renders correctly with empty version 1`] = `
|
||||
</small>
|
||||
<br />
|
||||
</section>
|
||||
<div
|
||||
aria-atomic="true"
|
||||
aria-live="polite"
|
||||
class="makeStyles-container-2"
|
||||
data-testid="ANNOUNCER_ELEMENT_TEST_ID"
|
||||
role="status"
|
||||
/>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
@ -34,7 +41,7 @@ exports[`renders correctly with ui-config 1`] = `
|
||||
title="API details"
|
||||
>
|
||||
<h2
|
||||
class="makeStyles-title-2"
|
||||
class="makeStyles-title-3"
|
||||
>
|
||||
Unleash 1.1.0
|
||||
|
||||
@ -50,6 +57,13 @@ exports[`renders correctly with ui-config 1`] = `
|
||||
</small>
|
||||
<br />
|
||||
</section>
|
||||
<div
|
||||
aria-atomic="true"
|
||||
aria-live="polite"
|
||||
class="makeStyles-container-4"
|
||||
data-testid="ANNOUNCER_ELEMENT_TEST_ID"
|
||||
role="status"
|
||||
/>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
@ -61,7 +75,7 @@ exports[`renders correctly with versionInfo 1`] = `
|
||||
title="API details"
|
||||
>
|
||||
<h2
|
||||
class="makeStyles-title-4"
|
||||
class="makeStyles-title-7"
|
||||
>
|
||||
Unleash 1.2.3
|
||||
|
||||
@ -77,6 +91,13 @@ exports[`renders correctly with versionInfo 1`] = `
|
||||
1
|
||||
</small>
|
||||
</section>
|
||||
<div
|
||||
aria-atomic="true"
|
||||
aria-live="polite"
|
||||
class="makeStyles-container-8"
|
||||
data-testid="ANNOUNCER_ELEMENT_TEST_ID"
|
||||
role="status"
|
||||
/>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
@ -88,7 +109,7 @@ exports[`renders correctly without uiConfig 1`] = `
|
||||
title="API details"
|
||||
>
|
||||
<h2
|
||||
class="makeStyles-title-3"
|
||||
class="makeStyles-title-5"
|
||||
>
|
||||
Unleash 1.1.0
|
||||
|
||||
@ -97,6 +118,13 @@ exports[`renders correctly without uiConfig 1`] = `
|
||||
<small />
|
||||
<br />
|
||||
</section>
|
||||
<div
|
||||
aria-atomic="true"
|
||||
aria-live="polite"
|
||||
class="makeStyles-container-6"
|
||||
data-testid="ANNOUNCER_ELEMENT_TEST_ID"
|
||||
role="status"
|
||||
/>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
|
@ -46,7 +46,7 @@ Array [
|
||||
"menu": Object {},
|
||||
"parent": "/projects",
|
||||
"path": "/projects/:projectId/features/:featureId/edit",
|
||||
"title": "Edit Feature",
|
||||
"title": "Edit feature",
|
||||
"type": "protected",
|
||||
},
|
||||
Object {
|
||||
@ -122,7 +122,7 @@ Array [
|
||||
"mobile": true,
|
||||
},
|
||||
"path": "/features",
|
||||
"title": "Feature Toggles",
|
||||
"title": "Feature toggles",
|
||||
"type": "protected",
|
||||
},
|
||||
Object {
|
||||
@ -169,7 +169,7 @@ Array [
|
||||
"mobile": true,
|
||||
},
|
||||
"path": "/context",
|
||||
"title": "Context Fields",
|
||||
"title": "Context fields",
|
||||
"type": "protected",
|
||||
},
|
||||
Object {
|
||||
@ -331,14 +331,14 @@ Array [
|
||||
"adminSettings": true,
|
||||
},
|
||||
"path": "/history",
|
||||
"title": "Event History",
|
||||
"title": "Event log",
|
||||
"type": "protected",
|
||||
},
|
||||
Object {
|
||||
"component": [Function],
|
||||
"menu": Object {},
|
||||
"path": "/archive",
|
||||
"title": "Archived Toggles",
|
||||
"title": "Archived toggles",
|
||||
"type": "protected",
|
||||
},
|
||||
Object {
|
||||
@ -402,7 +402,7 @@ Array [
|
||||
},
|
||||
"parent": "/admin",
|
||||
"path": "/admin/roles",
|
||||
"title": "Project Roles",
|
||||
"title": "Project roles",
|
||||
"type": "protected",
|
||||
},
|
||||
Object {
|
||||
@ -412,7 +412,7 @@ Array [
|
||||
},
|
||||
"parent": "/admin",
|
||||
"path": "/admin/auth",
|
||||
"title": "Single Sign-On",
|
||||
"title": "Single sign-on",
|
||||
"type": "protected",
|
||||
},
|
||||
Object {
|
||||
|
@ -98,7 +98,7 @@ export const routes: IRoute[] = [
|
||||
{
|
||||
path: '/projects/:projectId/features/:featureId/edit',
|
||||
parent: '/projects',
|
||||
title: 'Edit Feature',
|
||||
title: 'Edit feature',
|
||||
component: EditFeature,
|
||||
type: 'protected',
|
||||
menu: {},
|
||||
@ -172,7 +172,7 @@ export const routes: IRoute[] = [
|
||||
},
|
||||
{
|
||||
path: '/features',
|
||||
title: 'Feature Toggles',
|
||||
title: 'Feature toggles',
|
||||
component: FeatureToggleListContainer,
|
||||
type: 'protected',
|
||||
menu: { mobile: true },
|
||||
@ -216,7 +216,7 @@ export const routes: IRoute[] = [
|
||||
},
|
||||
{
|
||||
path: '/context',
|
||||
title: 'Context Fields',
|
||||
title: 'Context fields',
|
||||
component: ContextList,
|
||||
type: 'protected',
|
||||
flag: C,
|
||||
@ -372,7 +372,7 @@ export const routes: IRoute[] = [
|
||||
},
|
||||
{
|
||||
path: '/history',
|
||||
title: 'Event History',
|
||||
title: 'Event log',
|
||||
component: EventHistoryPage,
|
||||
type: 'protected',
|
||||
menu: { adminSettings: true },
|
||||
@ -381,7 +381,7 @@ export const routes: IRoute[] = [
|
||||
// Archive
|
||||
{
|
||||
path: '/archive',
|
||||
title: 'Archived Toggles',
|
||||
title: 'Archived toggles',
|
||||
component: ArchiveListContainer,
|
||||
type: 'protected',
|
||||
menu: {},
|
||||
@ -447,7 +447,7 @@ export const routes: IRoute[] = [
|
||||
{
|
||||
path: '/admin/roles',
|
||||
parent: '/admin',
|
||||
title: 'Project Roles',
|
||||
title: 'Project roles',
|
||||
component: ProjectRoles,
|
||||
type: 'protected',
|
||||
flag: RE,
|
||||
@ -456,7 +456,7 @@ export const routes: IRoute[] = [
|
||||
{
|
||||
path: '/admin/auth',
|
||||
parent: '/admin',
|
||||
title: 'Single Sign-On',
|
||||
title: 'Single sign-on',
|
||||
component: AuthSettings,
|
||||
type: 'protected',
|
||||
menu: { adminSettings: true },
|
||||
|
@ -49,7 +49,7 @@ export const ProjectFeatureToggles = ({
|
||||
headerContent={
|
||||
<HeaderTitle
|
||||
className={styles.title}
|
||||
title={`Feature toggles (${filteredFeatures.length})`}
|
||||
title={`Project features (${filteredFeatures.length})`}
|
||||
actions={
|
||||
<div className={styles.actionsContainer}>
|
||||
<SearchField
|
||||
|
@ -3,12 +3,15 @@ import ApiError from 'component/common/ApiError/ApiError';
|
||||
import ConditionallyRender from 'component/common/ConditionallyRender';
|
||||
import ReportToggleList from 'component/Reporting/ReportToggleList/ReportToggleList';
|
||||
import { ReportCard } from 'component/Reporting/ReportCard/ReportCard';
|
||||
import { usePageTitle } from 'hooks/usePageTitle';
|
||||
|
||||
interface IProjectHealthProps {
|
||||
projectId: string;
|
||||
}
|
||||
|
||||
const ProjectHealth = ({ projectId }: IProjectHealthProps) => {
|
||||
usePageTitle('Project health');
|
||||
|
||||
const { healthReport, refetchHealthReport, error } =
|
||||
useHealthReport(projectId);
|
||||
|
||||
|
@ -6,6 +6,7 @@ import theme from 'themes/mainTheme';
|
||||
import AccessProvider from 'component/providers/AccessProvider/AccessProvider';
|
||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||
import UIProvider from 'component/providers/UIProvider/UIProvider';
|
||||
import { AnnouncerProvider } from 'component/common/Announcer/AnnouncerProvider/AnnouncerProvider';
|
||||
|
||||
test('renders correctly with one strategy', () => {
|
||||
const strategy = {
|
||||
@ -15,17 +16,19 @@ test('renders correctly with one strategy', () => {
|
||||
const tree = renderer.create(
|
||||
<MemoryRouter>
|
||||
<ThemeProvider theme={theme}>
|
||||
<UIProvider>
|
||||
<AccessProvider permissions={[{ permission: ADMIN }]}>
|
||||
<StrategiesList
|
||||
strategies={[strategy]}
|
||||
fetchStrategies={jest.fn()}
|
||||
removeStrategy={jest.fn()}
|
||||
deprecateStrategy={jest.fn()}
|
||||
reactivateStrategy={jest.fn()}
|
||||
/>
|
||||
</AccessProvider>
|
||||
</UIProvider>
|
||||
<AnnouncerProvider>
|
||||
<UIProvider>
|
||||
<AccessProvider permissions={[{ permission: ADMIN }]}>
|
||||
<StrategiesList
|
||||
strategies={[strategy]}
|
||||
fetchStrategies={jest.fn()}
|
||||
removeStrategy={jest.fn()}
|
||||
deprecateStrategy={jest.fn()}
|
||||
reactivateStrategy={jest.fn()}
|
||||
/>
|
||||
</AccessProvider>
|
||||
</UIProvider>
|
||||
</AnnouncerProvider>
|
||||
</ThemeProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
@ -41,17 +44,19 @@ test('renders correctly with one strategy without permissions', () => {
|
||||
const tree = renderer.create(
|
||||
<MemoryRouter>
|
||||
<ThemeProvider theme={theme}>
|
||||
<UIProvider>
|
||||
<AccessProvider permissions={[{ permission: ADMIN }]}>
|
||||
<StrategiesList
|
||||
strategies={[strategy]}
|
||||
fetchStrategies={jest.fn()}
|
||||
removeStrategy={jest.fn()}
|
||||
deprecateStrategy={jest.fn()}
|
||||
reactivateStrategy={jest.fn()}
|
||||
/>
|
||||
</AccessProvider>
|
||||
</UIProvider>
|
||||
<AnnouncerProvider>
|
||||
<UIProvider>
|
||||
<AccessProvider permissions={[{ permission: ADMIN }]}>
|
||||
<StrategiesList
|
||||
strategies={[strategy]}
|
||||
fetchStrategies={jest.fn()}
|
||||
removeStrategy={jest.fn()}
|
||||
deprecateStrategy={jest.fn()}
|
||||
reactivateStrategy={jest.fn()}
|
||||
/>
|
||||
</AccessProvider>
|
||||
</UIProvider>
|
||||
</AnnouncerProvider>
|
||||
</ThemeProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
@ -1,139 +1,42 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly with one strategy 1`] = `
|
||||
<div
|
||||
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": "10px",
|
||||
"boxShadow": "none",
|
||||
}
|
||||
}
|
||||
>
|
||||
Array [
|
||||
<div
|
||||
className="makeStyles-headerContainer-2"
|
||||
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": "10px",
|
||||
"boxShadow": "none",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="makeStyles-headerTitleContainer-6"
|
||||
className="makeStyles-headerContainer-2"
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
data-loading={true}
|
||||
>
|
||||
<h1
|
||||
className="MuiTypography-root makeStyles-headerTitle-7 MuiTypography-h1"
|
||||
>
|
||||
Strategies
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
className="makeStyles-headerActions-8"
|
||||
>
|
||||
<span
|
||||
id="useId-0"
|
||||
>
|
||||
<button
|
||||
aria-describedby="useId-0"
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary"
|
||||
data-testid="ADD_NEW_STRATEGY_ID"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={0}
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="MuiButton-label"
|
||||
>
|
||||
New strategy
|
||||
<span
|
||||
className="MuiButton-endIcon MuiButton-iconSizeMedium"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
className="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="makeStyles-bodyContainer-3"
|
||||
>
|
||||
<ul
|
||||
className="MuiList-root MuiList-padding"
|
||||
>
|
||||
<li
|
||||
className="MuiListItem-root makeStyles-listItem-1 MuiListItem-gutters"
|
||||
disabled={false}
|
||||
className="makeStyles-headerTitleContainer-6"
|
||||
>
|
||||
<div
|
||||
className="MuiListItemAvatar-root"
|
||||
className=""
|
||||
data-loading={true}
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
style={
|
||||
Object {
|
||||
"color": "#0000008a",
|
||||
}
|
||||
}
|
||||
viewBox="0 0 24 24"
|
||||
<h1
|
||||
className="MuiTypography-root makeStyles-headerTitle-7 MuiTypography-h1"
|
||||
>
|
||||
<path
|
||||
d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"
|
||||
/>
|
||||
</svg>
|
||||
Strategies
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
className="MuiListItemText-root MuiListItemText-multiline"
|
||||
className="makeStyles-headerActions-8"
|
||||
>
|
||||
<span
|
||||
className="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||
>
|
||||
<a
|
||||
href="/strategies/flexibleRollout"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<strong>
|
||||
Gradual rollout
|
||||
</strong>
|
||||
</a>
|
||||
</span>
|
||||
<p
|
||||
className="MuiTypography-root MuiListItemText-secondary MuiTypography-body2 MuiTypography-colorTextSecondary MuiTypography-displayBlock"
|
||||
>
|
||||
Roll out to a percentage of your userbase, and ensure that the experience is the same for the user on each visit.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
id="useId-1"
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="Deprecate strategy"
|
||||
id="useId-0"
|
||||
>
|
||||
<button
|
||||
aria-labelledby="useId-1"
|
||||
className="MuiButtonBase-root MuiIconButton-root"
|
||||
aria-describedby="useId-0"
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary"
|
||||
data-testid="ADD_NEW_STRATEGY_ID"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
@ -151,18 +54,12 @@ exports[`renders correctly with one strategy 1`] = `
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
className="MuiButton-label"
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"
|
||||
/>
|
||||
</svg>
|
||||
New strategy
|
||||
<span
|
||||
className="MuiButton-endIcon MuiButton-iconSizeMedium"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
className="MuiTouchRipple-root"
|
||||
@ -170,240 +67,257 @@ exports[`renders correctly with one strategy 1`] = `
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="You cannot delete a built-in strategy"
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="makeStyles-bodyContainer-3"
|
||||
>
|
||||
<ul
|
||||
className="MuiList-root MuiList-padding"
|
||||
>
|
||||
<li
|
||||
className="MuiListItem-root makeStyles-listItem-1 MuiListItem-gutters"
|
||||
disabled={false}
|
||||
>
|
||||
<button
|
||||
className="MuiButtonBase-root MuiIconButton-root Mui-disabled Mui-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={-1}
|
||||
type="button"
|
||||
<div
|
||||
className="MuiListItemAvatar-root"
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
style={
|
||||
Object {
|
||||
"color": "#0000008a",
|
||||
}
|
||||
}
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
className="MuiListItemText-root MuiListItemText-multiline"
|
||||
>
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
className="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||
>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
<a
|
||||
href="/strategies/flexibleRollout"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<path
|
||||
d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"
|
||||
/>
|
||||
<title>
|
||||
Edit strategy
|
||||
</title>
|
||||
</svg>
|
||||
<strong>
|
||||
Gradual rollout
|
||||
</strong>
|
||||
</a>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="You cannot delete a built-in strategy"
|
||||
>
|
||||
<button
|
||||
className="MuiButtonBase-root MuiIconButton-root Mui-disabled Mui-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={-1}
|
||||
type="button"
|
||||
>
|
||||
<p
|
||||
className="MuiTypography-root MuiListItemText-secondary MuiTypography-body2 MuiTypography-colorTextSecondary MuiTypography-displayBlock"
|
||||
>
|
||||
Roll out to a percentage of your userbase, and ensure that the experience is the same for the user on each visit.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
id="useId-1"
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="Deprecate strategy"
|
||||
>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
<button
|
||||
aria-labelledby="useId-1"
|
||||
className="MuiButtonBase-root MuiIconButton-root"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={0}
|
||||
type="button"
|
||||
>
|
||||
<path
|
||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
className="MuiTouchRipple-root"
|
||||
/>
|
||||
<title>
|
||||
Delete strategy
|
||||
</title>
|
||||
</svg>
|
||||
</button>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="You cannot delete a built-in strategy"
|
||||
>
|
||||
<button
|
||||
className="MuiButtonBase-root MuiIconButton-root Mui-disabled Mui-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={-1}
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"
|
||||
/>
|
||||
<title>
|
||||
Edit strategy
|
||||
</title>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="You cannot delete a built-in strategy"
|
||||
>
|
||||
<button
|
||||
className="MuiButtonBase-root MuiIconButton-root Mui-disabled Mui-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={-1}
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
||||
/>
|
||||
<title>
|
||||
Delete strategy
|
||||
</title>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
aria-atomic={true}
|
||||
aria-live="polite"
|
||||
className="makeStyles-container-11"
|
||||
data-testid="ANNOUNCER_ELEMENT_TEST_ID"
|
||||
role="status"
|
||||
>
|
||||
Navigated to Strategies
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders correctly with one strategy without permissions 1`] = `
|
||||
<div
|
||||
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": "10px",
|
||||
"boxShadow": "none",
|
||||
}
|
||||
}
|
||||
>
|
||||
Array [
|
||||
<div
|
||||
className="makeStyles-headerContainer-2"
|
||||
className="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded"
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": "10px",
|
||||
"boxShadow": "none",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="makeStyles-headerTitleContainer-6"
|
||||
className="makeStyles-headerContainer-2"
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
data-loading={true}
|
||||
>
|
||||
<h1
|
||||
className="MuiTypography-root makeStyles-headerTitle-7 MuiTypography-h1"
|
||||
>
|
||||
Strategies
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
className="makeStyles-headerActions-8"
|
||||
>
|
||||
<span
|
||||
id="useId-2"
|
||||
>
|
||||
<button
|
||||
aria-describedby="useId-2"
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary"
|
||||
data-testid="ADD_NEW_STRATEGY_ID"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={0}
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="MuiButton-label"
|
||||
>
|
||||
New strategy
|
||||
<span
|
||||
className="MuiButton-endIcon MuiButton-iconSizeMedium"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
className="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="makeStyles-bodyContainer-3"
|
||||
>
|
||||
<ul
|
||||
className="MuiList-root MuiList-padding"
|
||||
>
|
||||
<li
|
||||
className="MuiListItem-root makeStyles-listItem-1 MuiListItem-gutters"
|
||||
disabled={false}
|
||||
className="makeStyles-headerTitleContainer-6"
|
||||
>
|
||||
<div
|
||||
className="MuiListItemAvatar-root"
|
||||
className=""
|
||||
data-loading={true}
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
style={
|
||||
Object {
|
||||
"color": "#0000008a",
|
||||
}
|
||||
}
|
||||
viewBox="0 0 24 24"
|
||||
<h1
|
||||
className="MuiTypography-root makeStyles-headerTitle-7 MuiTypography-h1"
|
||||
>
|
||||
<path
|
||||
d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"
|
||||
/>
|
||||
</svg>
|
||||
Strategies
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
className="MuiListItemText-root MuiListItemText-multiline"
|
||||
className="makeStyles-headerActions-8"
|
||||
>
|
||||
<span
|
||||
className="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||
>
|
||||
<a
|
||||
href="/strategies/flexibleRollout"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<strong>
|
||||
Gradual rollout
|
||||
</strong>
|
||||
</a>
|
||||
</span>
|
||||
<p
|
||||
className="MuiTypography-root MuiListItemText-secondary MuiTypography-body2 MuiTypography-colorTextSecondary MuiTypography-displayBlock"
|
||||
>
|
||||
Roll out to a percentage of your userbase, and ensure that the experience is the same for the user on each visit.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
id="useId-3"
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="Deprecate strategy"
|
||||
id="useId-2"
|
||||
>
|
||||
<button
|
||||
aria-labelledby="useId-3"
|
||||
className="MuiButtonBase-root MuiIconButton-root"
|
||||
aria-describedby="useId-2"
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary"
|
||||
data-testid="ADD_NEW_STRATEGY_ID"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
@ -421,18 +335,12 @@ exports[`renders correctly with one strategy without permissions 1`] = `
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
className="MuiButton-label"
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"
|
||||
/>
|
||||
</svg>
|
||||
New strategy
|
||||
<span
|
||||
className="MuiButton-endIcon MuiButton-iconSizeMedium"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
className="MuiTouchRipple-root"
|
||||
@ -440,102 +348,216 @@ exports[`renders correctly with one strategy without permissions 1`] = `
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="You cannot delete a built-in strategy"
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="makeStyles-bodyContainer-3"
|
||||
>
|
||||
<ul
|
||||
className="MuiList-root MuiList-padding"
|
||||
>
|
||||
<li
|
||||
className="MuiListItem-root makeStyles-listItem-1 MuiListItem-gutters"
|
||||
disabled={false}
|
||||
>
|
||||
<button
|
||||
className="MuiButtonBase-root MuiIconButton-root Mui-disabled Mui-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={-1}
|
||||
type="button"
|
||||
<div
|
||||
className="MuiListItemAvatar-root"
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
style={
|
||||
Object {
|
||||
"color": "#0000008a",
|
||||
}
|
||||
}
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
className="MuiListItemText-root MuiListItemText-multiline"
|
||||
>
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
className="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||
>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
<a
|
||||
href="/strategies/flexibleRollout"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<path
|
||||
d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"
|
||||
/>
|
||||
<title>
|
||||
Edit strategy
|
||||
</title>
|
||||
</svg>
|
||||
<strong>
|
||||
Gradual rollout
|
||||
</strong>
|
||||
</a>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="You cannot delete a built-in strategy"
|
||||
>
|
||||
<button
|
||||
className="MuiButtonBase-root MuiIconButton-root Mui-disabled Mui-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={-1}
|
||||
type="button"
|
||||
>
|
||||
<p
|
||||
className="MuiTypography-root MuiListItemText-secondary MuiTypography-body2 MuiTypography-colorTextSecondary MuiTypography-displayBlock"
|
||||
>
|
||||
Roll out to a percentage of your userbase, and ensure that the experience is the same for the user on each visit.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
id="useId-3"
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="Deprecate strategy"
|
||||
>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
<button
|
||||
aria-labelledby="useId-3"
|
||||
className="MuiButtonBase-root MuiIconButton-root"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={0}
|
||||
type="button"
|
||||
>
|
||||
<path
|
||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
>
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
className="MuiTouchRipple-root"
|
||||
/>
|
||||
<title>
|
||||
Delete strategy
|
||||
</title>
|
||||
</svg>
|
||||
</button>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="You cannot delete a built-in strategy"
|
||||
>
|
||||
<button
|
||||
className="MuiButtonBase-root MuiIconButton-root Mui-disabled Mui-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={-1}
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"
|
||||
/>
|
||||
<title>
|
||||
Edit strategy
|
||||
</title>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
aria-describedby={null}
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
title="You cannot delete a built-in strategy"
|
||||
>
|
||||
<button
|
||||
className="MuiButtonBase-root MuiIconButton-root Mui-disabled Mui-disabled"
|
||||
disabled={true}
|
||||
onBlur={[Function]}
|
||||
onDragLeave={[Function]}
|
||||
onFocus={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
onKeyUp={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchMove={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
tabIndex={-1}
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="MuiIconButton-label"
|
||||
>
|
||||
<svg
|
||||
className="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
||||
/>
|
||||
<title>
|
||||
Delete strategy
|
||||
</title>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
aria-atomic={true}
|
||||
aria-live="polite"
|
||||
className="makeStyles-container-11"
|
||||
data-testid="ANNOUNCER_ELEMENT_TEST_ID"
|
||||
role="status"
|
||||
>
|
||||
Navigated to Strategies
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
21
frontend/src/hooks/usePageTitle.ts
Normal file
21
frontend/src/hooks/usePageTitle.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { useEffect, useContext } from 'react';
|
||||
import { AnnouncerContext } from 'component/common/Announcer/AnnouncerContext/AnnouncerContext';
|
||||
|
||||
export const usePageTitle = (title: string) => {
|
||||
const { setAnnouncement } = useContext(AnnouncerContext);
|
||||
|
||||
useEffect(() => {
|
||||
document.title = title;
|
||||
return () => {
|
||||
document.title = DEFAULT_PAGE_TITLE;
|
||||
};
|
||||
}, [title]);
|
||||
|
||||
useEffect(() => {
|
||||
if (title !== DEFAULT_PAGE_TITLE) {
|
||||
setAnnouncement(`Navigated to ${title}`);
|
||||
}
|
||||
}, [setAnnouncement, title]);
|
||||
};
|
||||
|
||||
const DEFAULT_PAGE_TITLE = 'Unleash';
|
@ -49,3 +49,4 @@ export const INPUT_ERROR_TEXT = 'INPUT_ERROR_TEXT';
|
||||
export const HEADER_USER_AVATAR = 'HEADER_USER_AVATAR';
|
||||
export const SIDEBAR_MODAL_ID = 'SIDEBAR_MODAL_ID';
|
||||
export const AUTH_PAGE_ID = 'AUTH_PAGE_ID';
|
||||
export const ANNOUNCER_ELEMENT_TEST_ID = 'ANNOUNCER_ELEMENT_TEST_ID';
|
||||
|
@ -3,6 +3,7 @@ import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import { render as rtlRender, RenderOptions } from '@testing-library/react';
|
||||
import { SWRConfig } from 'swr';
|
||||
import { MainThemeProvider } from 'themes/MainThemeProvider';
|
||||
import { AnnouncerProvider } from 'component/common/Announcer/AnnouncerProvider/AnnouncerProvider';
|
||||
|
||||
export const render = (
|
||||
ui: JSX.Element,
|
||||
@ -23,7 +24,9 @@ const Wrapper: FC = ({ children }) => {
|
||||
return (
|
||||
<SWRConfig value={{ provider: () => new Map() }}>
|
||||
<MainThemeProvider>
|
||||
<Router>{children}</Router>
|
||||
<AnnouncerProvider>
|
||||
<Router>{children}</Router>
|
||||
</AnnouncerProvider>
|
||||
</MainThemeProvider>
|
||||
</SWRConfig>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user