mirror of
https://github.com/ansible/awx.git
synced 2026-05-07 01:17:37 -02:30
prevents dashboard counts from reloading with line chart filters change
This commit is contained in:
@@ -4,13 +4,7 @@ import styled from 'styled-components';
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardHeader,
|
|
||||||
CardActions,
|
|
||||||
CardBody,
|
|
||||||
PageSection,
|
PageSection,
|
||||||
Select,
|
|
||||||
SelectVariant,
|
|
||||||
SelectOption,
|
|
||||||
Tabs,
|
Tabs,
|
||||||
Tab,
|
Tab,
|
||||||
TabTitleText,
|
TabTitleText,
|
||||||
@@ -21,15 +15,9 @@ import { DashboardAPI } from '../../api';
|
|||||||
import ScreenHeader from '../../components/ScreenHeader';
|
import ScreenHeader from '../../components/ScreenHeader';
|
||||||
import JobList from '../../components/JobList';
|
import JobList from '../../components/JobList';
|
||||||
import ContentLoading from '../../components/ContentLoading';
|
import ContentLoading from '../../components/ContentLoading';
|
||||||
import LineChart from './shared/LineChart';
|
|
||||||
import Count from './shared/Count';
|
import Count from './shared/Count';
|
||||||
import TemplateList from '../../components/TemplateList';
|
import TemplateList from '../../components/TemplateList';
|
||||||
|
import DashboardGraph from './DashboardGraph';
|
||||||
const StatusSelect = styled(Select)`
|
|
||||||
&& {
|
|
||||||
--pf-c-select__toggle--MinWidth: 165px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Counts = styled.div`
|
const Counts = styled.div`
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -51,69 +39,25 @@ const MainPageSection = styled(PageSection)`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const GraphCardHeader = styled(CardHeader)`
|
|
||||||
margin-top: var(--pf-global--spacer--lg);
|
|
||||||
`;
|
|
||||||
|
|
||||||
const GraphCardActions = styled(CardActions)`
|
|
||||||
margin-left: initial;
|
|
||||||
padding-left: 0;
|
|
||||||
`;
|
|
||||||
|
|
||||||
function Dashboard() {
|
function Dashboard() {
|
||||||
const [isPeriodDropdownOpen, setIsPeriodDropdownOpen] = useState(false);
|
|
||||||
const [isJobTypeDropdownOpen, setIsJobTypeDropdownOpen] = useState(false);
|
|
||||||
const [isJobStatusDropdownOpen, setIsJobStatusDropdownOpen] = useState(false);
|
|
||||||
const [periodSelection, setPeriodSelection] = useState('month');
|
|
||||||
const [jobTypeSelection, setJobTypeSelection] = useState('all');
|
|
||||||
const [jobStatusSelection, setJobStatusSelection] = useState('all');
|
|
||||||
const [activeTabId, setActiveTabId] = useState(0);
|
const [activeTabId, setActiveTabId] = useState(0);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isLoading,
|
isLoading,
|
||||||
result: { jobGraphData, countData },
|
result: countData,
|
||||||
request: fetchDashboardGraph,
|
request: fetchDashboardGraph,
|
||||||
} = useRequest(
|
} = useRequest(
|
||||||
useCallback(async () => {
|
useCallback(async () => {
|
||||||
const [{ data }, { data: dataFromCount }] = await Promise.all([
|
const { data: dataFromCount } = await DashboardAPI.read();
|
||||||
DashboardAPI.readJobGraph({
|
|
||||||
period: periodSelection,
|
return dataFromCount;
|
||||||
job_type: jobTypeSelection,
|
}, []),
|
||||||
}),
|
{}
|
||||||
DashboardAPI.read(),
|
|
||||||
]);
|
|
||||||
const newData = {};
|
|
||||||
data.jobs.successful.forEach(([dateSecs, count]) => {
|
|
||||||
if (!newData[dateSecs]) {
|
|
||||||
newData[dateSecs] = {};
|
|
||||||
}
|
|
||||||
newData[dateSecs].successful = count;
|
|
||||||
});
|
|
||||||
data.jobs.failed.forEach(([dateSecs, count]) => {
|
|
||||||
if (!newData[dateSecs]) {
|
|
||||||
newData[dateSecs] = {};
|
|
||||||
}
|
|
||||||
newData[dateSecs].failed = count;
|
|
||||||
});
|
|
||||||
const jobData = Object.keys(newData).map(dateSecs => {
|
|
||||||
const [created] = new Date(dateSecs * 1000).toISOString().split('T');
|
|
||||||
newData[dateSecs].created = created;
|
|
||||||
return newData[dateSecs];
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
jobGraphData: jobData,
|
|
||||||
countData: dataFromCount,
|
|
||||||
};
|
|
||||||
}, [periodSelection, jobTypeSelection]),
|
|
||||||
{
|
|
||||||
jobGraphData: [],
|
|
||||||
countData: {},
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchDashboardGraph();
|
fetchDashboardGraph();
|
||||||
}, [fetchDashboardGraph, periodSelection, jobTypeSelection]);
|
}, [fetchDashboardGraph]);
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<PageSection>
|
<PageSection>
|
||||||
@@ -179,97 +123,7 @@ function Dashboard() {
|
|||||||
eventKey={0}
|
eventKey={0}
|
||||||
title={<TabTitleText>{t`Job status`}</TabTitleText>}
|
title={<TabTitleText>{t`Job status`}</TabTitleText>}
|
||||||
>
|
>
|
||||||
<Fragment>
|
<DashboardGraph />
|
||||||
<GraphCardHeader>
|
|
||||||
<GraphCardActions>
|
|
||||||
<Select
|
|
||||||
variant={SelectVariant.single}
|
|
||||||
placeholderText={t`Select period`}
|
|
||||||
aria-label={t`Select period`}
|
|
||||||
typeAheadAriaLabel={t`Select period`}
|
|
||||||
className="periodSelect"
|
|
||||||
onToggle={setIsPeriodDropdownOpen}
|
|
||||||
onSelect={(event, selection) =>
|
|
||||||
setPeriodSelection(selection)
|
|
||||||
}
|
|
||||||
selections={periodSelection}
|
|
||||||
isOpen={isPeriodDropdownOpen}
|
|
||||||
>
|
|
||||||
<SelectOption key="month" value="month">
|
|
||||||
{t`Past month`}
|
|
||||||
</SelectOption>
|
|
||||||
<SelectOption key="two_weeks" value="two_weeks">
|
|
||||||
{t`Past two weeks`}
|
|
||||||
</SelectOption>
|
|
||||||
<SelectOption key="week" value="week">
|
|
||||||
{t`Past week`}
|
|
||||||
</SelectOption>
|
|
||||||
<SelectOption key="day" value="day">
|
|
||||||
{t`Past 24 hours`}
|
|
||||||
</SelectOption>
|
|
||||||
</Select>
|
|
||||||
<Select
|
|
||||||
variant={SelectVariant.single}
|
|
||||||
placeholderText={t`Select job type`}
|
|
||||||
aria-label={t`Select job type`}
|
|
||||||
className="jobTypeSelect"
|
|
||||||
onToggle={setIsJobTypeDropdownOpen}
|
|
||||||
onSelect={(event, selection) =>
|
|
||||||
setJobTypeSelection(selection)
|
|
||||||
}
|
|
||||||
selections={jobTypeSelection}
|
|
||||||
isOpen={isJobTypeDropdownOpen}
|
|
||||||
>
|
|
||||||
<SelectOption key="all" value="all">
|
|
||||||
{t`All job types`}
|
|
||||||
</SelectOption>
|
|
||||||
<SelectOption key="inv_sync" value="inv_sync">
|
|
||||||
{t`Inventory sync`}
|
|
||||||
</SelectOption>
|
|
||||||
<SelectOption key="scm_update" value="scm_update">
|
|
||||||
{t`SCM update`}
|
|
||||||
</SelectOption>
|
|
||||||
<SelectOption key="playbook_run" value="playbook_run">
|
|
||||||
{t`Playbook run`}
|
|
||||||
</SelectOption>
|
|
||||||
</Select>
|
|
||||||
<StatusSelect
|
|
||||||
variant={SelectVariant.single}
|
|
||||||
placeholderText={t`Select status`}
|
|
||||||
aria-label={t`Select status`}
|
|
||||||
className="jobStatusSelect"
|
|
||||||
onToggle={setIsJobStatusDropdownOpen}
|
|
||||||
onSelect={(event, selection) => {
|
|
||||||
setIsJobStatusDropdownOpen(false);
|
|
||||||
setJobStatusSelection(selection);
|
|
||||||
}}
|
|
||||||
selections={jobStatusSelection}
|
|
||||||
isOpen={isJobStatusDropdownOpen}
|
|
||||||
>
|
|
||||||
<SelectOption
|
|
||||||
key="all"
|
|
||||||
value="all"
|
|
||||||
>{t`All jobs`}</SelectOption>
|
|
||||||
<SelectOption
|
|
||||||
key="successful"
|
|
||||||
value="successful"
|
|
||||||
>{t`Successful jobs`}</SelectOption>
|
|
||||||
<SelectOption
|
|
||||||
key="failed"
|
|
||||||
value="failed"
|
|
||||||
>{t`Failed jobs`}</SelectOption>
|
|
||||||
</StatusSelect>
|
|
||||||
</GraphCardActions>
|
|
||||||
</GraphCardHeader>
|
|
||||||
<CardBody>
|
|
||||||
<LineChart
|
|
||||||
jobStatus={jobStatusSelection}
|
|
||||||
height={390}
|
|
||||||
id="d3-line-chart-root"
|
|
||||||
data={jobGraphData}
|
|
||||||
/>
|
|
||||||
</CardBody>
|
|
||||||
</Fragment>
|
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab
|
<Tab
|
||||||
aria-label={t`Recent Jobs list tab`}
|
aria-label={t`Recent Jobs list tab`}
|
||||||
|
|||||||
@@ -46,41 +46,4 @@ describe('<Dashboard />', () => {
|
|||||||
pageWrapper.update();
|
pageWrapper.update();
|
||||||
expect(pageWrapper.find('TemplateList').length).toBe(1);
|
expect(pageWrapper.find('TemplateList').length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renders month-based/all job type chart by default', () => {
|
|
||||||
expect(graphRequest).toHaveBeenCalledWith({
|
|
||||||
job_type: 'all',
|
|
||||||
period: 'month',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
test('should render all three line chart filters with correct number of options', async () => {
|
|
||||||
expect(pageWrapper.find('Select[variant="single"]')).toHaveLength(3);
|
|
||||||
await act(async () => {
|
|
||||||
pageWrapper
|
|
||||||
.find('Select[placeholderText="Select job type"]')
|
|
||||||
.prop('onToggle')(true);
|
|
||||||
});
|
|
||||||
pageWrapper.update();
|
|
||||||
expect(pageWrapper.find('SelectOption')).toHaveLength(4);
|
|
||||||
await act(async () => {
|
|
||||||
pageWrapper
|
|
||||||
.find('Select[placeholderText="Select job type"]')
|
|
||||||
.prop('onToggle')(false);
|
|
||||||
pageWrapper
|
|
||||||
.find('Select[placeholderText="Select period"]')
|
|
||||||
.prop('onToggle')(true);
|
|
||||||
});
|
|
||||||
pageWrapper.update();
|
|
||||||
expect(pageWrapper.find('SelectOption')).toHaveLength(4);
|
|
||||||
await act(async () => {
|
|
||||||
pageWrapper
|
|
||||||
.find('Select[placeholderText="Select period"]')
|
|
||||||
.prop('onToggle')(false);
|
|
||||||
pageWrapper
|
|
||||||
.find('Select[placeholderText="Select status"]')
|
|
||||||
.prop('onToggle')(true);
|
|
||||||
});
|
|
||||||
pageWrapper.update();
|
|
||||||
expect(pageWrapper.find('SelectOption')).toHaveLength(3);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
182
awx/ui_next/src/screens/Dashboard/DashboardGraph.jsx
Normal file
182
awx/ui_next/src/screens/Dashboard/DashboardGraph.jsx
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
import React, { Fragment, useCallback, useEffect, useState } from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
import { t } from '@lingui/macro';
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardHeader,
|
||||||
|
CardActions,
|
||||||
|
CardBody,
|
||||||
|
PageSection,
|
||||||
|
Select,
|
||||||
|
SelectVariant,
|
||||||
|
SelectOption,
|
||||||
|
} from '@patternfly/react-core';
|
||||||
|
|
||||||
|
import useRequest from '../../util/useRequest';
|
||||||
|
import { DashboardAPI } from '../../api';
|
||||||
|
import ContentLoading from '../../components/ContentLoading';
|
||||||
|
import LineChart from './shared/LineChart';
|
||||||
|
|
||||||
|
const StatusSelect = styled(Select)`
|
||||||
|
&& {
|
||||||
|
--pf-c-select__toggle--MinWidth: 165px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const GraphCardHeader = styled(CardHeader)`
|
||||||
|
margin-top: var(--pf-global--spacer--lg);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const GraphCardActions = styled(CardActions)`
|
||||||
|
margin-left: initial;
|
||||||
|
padding-left: 0;
|
||||||
|
`;
|
||||||
|
|
||||||
|
function DashboardGraph() {
|
||||||
|
const [isPeriodDropdownOpen, setIsPeriodDropdownOpen] = useState(false);
|
||||||
|
const [isJobTypeDropdownOpen, setIsJobTypeDropdownOpen] = useState(false);
|
||||||
|
const [isJobStatusDropdownOpen, setIsJobStatusDropdownOpen] = useState(false);
|
||||||
|
const [periodSelection, setPeriodSelection] = useState('month');
|
||||||
|
const [jobTypeSelection, setJobTypeSelection] = useState('all');
|
||||||
|
const [jobStatusSelection, setJobStatusSelection] = useState('all');
|
||||||
|
|
||||||
|
const {
|
||||||
|
isLoading,
|
||||||
|
result: jobGraphData,
|
||||||
|
request: fetchDashboardGraph,
|
||||||
|
} = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
const { data } = await DashboardAPI.readJobGraph({
|
||||||
|
period: periodSelection,
|
||||||
|
job_type: jobTypeSelection,
|
||||||
|
});
|
||||||
|
const newData = {};
|
||||||
|
data.jobs.successful.forEach(([dateSecs, count]) => {
|
||||||
|
if (!newData[dateSecs]) {
|
||||||
|
newData[dateSecs] = {};
|
||||||
|
}
|
||||||
|
newData[dateSecs].successful = count;
|
||||||
|
});
|
||||||
|
data.jobs.failed.forEach(([dateSecs, count]) => {
|
||||||
|
if (!newData[dateSecs]) {
|
||||||
|
newData[dateSecs] = {};
|
||||||
|
}
|
||||||
|
newData[dateSecs].failed = count;
|
||||||
|
});
|
||||||
|
const jobData = Object.keys(newData).map(dateSecs => {
|
||||||
|
const [created] = new Date(dateSecs * 1000).toISOString().split('T');
|
||||||
|
newData[dateSecs].created = created;
|
||||||
|
return newData[dateSecs];
|
||||||
|
});
|
||||||
|
return jobData;
|
||||||
|
}, [periodSelection, jobTypeSelection]),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchDashboardGraph();
|
||||||
|
}, [fetchDashboardGraph, periodSelection, jobTypeSelection]);
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<PageSection>
|
||||||
|
<Card>
|
||||||
|
<ContentLoading />
|
||||||
|
</Card>
|
||||||
|
</PageSection>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<GraphCardHeader>
|
||||||
|
<GraphCardActions>
|
||||||
|
<Select
|
||||||
|
variant={SelectVariant.single}
|
||||||
|
placeholderText={t`Select period`}
|
||||||
|
aria-label={t`Select period`}
|
||||||
|
typeAheadAriaLabel={t`Select period`}
|
||||||
|
className="periodSelect"
|
||||||
|
onToggle={setIsPeriodDropdownOpen}
|
||||||
|
onSelect={(event, selection) => {
|
||||||
|
setIsPeriodDropdownOpen(false);
|
||||||
|
setPeriodSelection(selection);
|
||||||
|
}}
|
||||||
|
selections={periodSelection}
|
||||||
|
isOpen={isPeriodDropdownOpen}
|
||||||
|
>
|
||||||
|
<SelectOption key="month" value="month">
|
||||||
|
{t`Past month`}
|
||||||
|
</SelectOption>
|
||||||
|
<SelectOption key="two_weeks" value="two_weeks">
|
||||||
|
{t`Past two weeks`}
|
||||||
|
</SelectOption>
|
||||||
|
<SelectOption key="week" value="week">
|
||||||
|
{t`Past week`}
|
||||||
|
</SelectOption>
|
||||||
|
<SelectOption key="day" value="day">
|
||||||
|
{t`Past 24 hours`}
|
||||||
|
</SelectOption>
|
||||||
|
</Select>
|
||||||
|
<Select
|
||||||
|
variant={SelectVariant.single}
|
||||||
|
placeholderText={t`Select job type`}
|
||||||
|
aria-label={t`Select job type`}
|
||||||
|
className="jobTypeSelect"
|
||||||
|
onToggle={setIsJobTypeDropdownOpen}
|
||||||
|
onSelect={(event, selection) => {
|
||||||
|
setIsJobTypeDropdownOpen(false);
|
||||||
|
setJobTypeSelection(selection);
|
||||||
|
}}
|
||||||
|
selections={jobTypeSelection}
|
||||||
|
isOpen={isJobTypeDropdownOpen}
|
||||||
|
>
|
||||||
|
<SelectOption key="all" value="all">
|
||||||
|
{t`All job types`}
|
||||||
|
</SelectOption>
|
||||||
|
<SelectOption key="inv_sync" value="inv_sync">
|
||||||
|
{t`Inventory sync`}
|
||||||
|
</SelectOption>
|
||||||
|
<SelectOption key="scm_update" value="scm_update">
|
||||||
|
{t`SCM update`}
|
||||||
|
</SelectOption>
|
||||||
|
<SelectOption key="playbook_run" value="playbook_run">
|
||||||
|
{t`Playbook run`}
|
||||||
|
</SelectOption>
|
||||||
|
</Select>
|
||||||
|
<StatusSelect
|
||||||
|
variant={SelectVariant.single}
|
||||||
|
placeholderText={t`Select status`}
|
||||||
|
aria-label={t`Select status`}
|
||||||
|
className="jobStatusSelect"
|
||||||
|
onToggle={setIsJobStatusDropdownOpen}
|
||||||
|
onSelect={(event, selection) => {
|
||||||
|
setIsJobStatusDropdownOpen(false);
|
||||||
|
setJobStatusSelection(selection);
|
||||||
|
}}
|
||||||
|
selections={jobStatusSelection}
|
||||||
|
isOpen={isJobStatusDropdownOpen}
|
||||||
|
>
|
||||||
|
<SelectOption key="all" value="all">{t`All jobs`}</SelectOption>
|
||||||
|
<SelectOption
|
||||||
|
key="successful"
|
||||||
|
value="successful"
|
||||||
|
>{t`Successful jobs`}</SelectOption>
|
||||||
|
<SelectOption
|
||||||
|
key="failed"
|
||||||
|
value="failed"
|
||||||
|
>{t`Failed jobs`}</SelectOption>
|
||||||
|
</StatusSelect>
|
||||||
|
</GraphCardActions>
|
||||||
|
</GraphCardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<LineChart
|
||||||
|
jobStatus={jobStatusSelection}
|
||||||
|
height={390}
|
||||||
|
id="d3-line-chart-root"
|
||||||
|
data={jobGraphData}
|
||||||
|
/>
|
||||||
|
</CardBody>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default DashboardGraph;
|
||||||
67
awx/ui_next/src/screens/Dashboard/DashboardGraph.test.jsx
Normal file
67
awx/ui_next/src/screens/Dashboard/DashboardGraph.test.jsx
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
|
|
||||||
|
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
|
||||||
|
|
||||||
|
import { DashboardAPI } from '../../api';
|
||||||
|
import DashboardGraph from './DashboardGraph';
|
||||||
|
|
||||||
|
jest.mock('../../api');
|
||||||
|
jest.mock('react-router-dom', () => ({
|
||||||
|
...jest.requireActual('react-router-dom'),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('<DashboardGraph/>', () => {
|
||||||
|
let pageWrapper;
|
||||||
|
let graphRequest;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await act(async () => {
|
||||||
|
DashboardAPI.read.mockResolvedValue({});
|
||||||
|
graphRequest = DashboardAPI.readJobGraph;
|
||||||
|
graphRequest.mockResolvedValue({});
|
||||||
|
pageWrapper = mountWithContexts(<DashboardGraph />);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
pageWrapper.unmount();
|
||||||
|
});
|
||||||
|
test('renders month-based/all job type chart by default', () => {
|
||||||
|
expect(graphRequest).toHaveBeenCalledWith({
|
||||||
|
job_type: 'all',
|
||||||
|
period: 'month',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render all three line chart filters with correct number of options', async () => {
|
||||||
|
expect(pageWrapper.find('Select[variant="single"]')).toHaveLength(3);
|
||||||
|
await act(async () => {
|
||||||
|
pageWrapper
|
||||||
|
.find('Select[placeholderText="Select job type"]')
|
||||||
|
.prop('onToggle')(true);
|
||||||
|
});
|
||||||
|
pageWrapper.update();
|
||||||
|
expect(pageWrapper.find('SelectOption')).toHaveLength(4);
|
||||||
|
await act(async () => {
|
||||||
|
pageWrapper
|
||||||
|
.find('Select[placeholderText="Select job type"]')
|
||||||
|
.prop('onToggle')(false);
|
||||||
|
pageWrapper
|
||||||
|
.find('Select[placeholderText="Select period"]')
|
||||||
|
.prop('onToggle')(true);
|
||||||
|
});
|
||||||
|
pageWrapper.update();
|
||||||
|
expect(pageWrapper.find('SelectOption')).toHaveLength(4);
|
||||||
|
await act(async () => {
|
||||||
|
pageWrapper
|
||||||
|
.find('Select[placeholderText="Select period"]')
|
||||||
|
.prop('onToggle')(false);
|
||||||
|
pageWrapper
|
||||||
|
.find('Select[placeholderText="Select status"]')
|
||||||
|
.prop('onToggle')(true);
|
||||||
|
});
|
||||||
|
pageWrapper.update();
|
||||||
|
expect(pageWrapper.find('SelectOption')).toHaveLength(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user