-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
external tooltip to functional, break up tooltip row into smaller com…
…ponent
- Loading branch information
1 parent
bce0748
commit a1f2617
Showing
8 changed files
with
257 additions
and
370 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { CompanyTypeahead } from '../../Filters/CompanyTypeahead'; | ||
import { useSelector } from 'react-redux'; | ||
import { TooltipRow } from './TooltipRow'; | ||
import { | ||
selectQueryFocus, | ||
selectQueryLens, | ||
} from '../../../reducers/query/selectors'; | ||
import { | ||
selectTrendsChartType, | ||
selectTrendsTooltip, | ||
} from '../../../reducers/trends/selectors'; | ||
import { externalTooltipFormatter } from '../../../utils/chart'; | ||
|
||
const WARN_SERIES_BREAK = | ||
'CFPB updated product and issue options in April 2017 and August 2023.'; | ||
|
||
const LEARN_SERIES_BREAK = | ||
'https://www.consumerfinance.gov/data-research/consumer-complaints/#past-changes'; | ||
|
||
export const ExternalTooltip = () => { | ||
const trendsFocus = useSelector(selectQueryFocus); | ||
const focus = trendsFocus ? 'focus' : ''; | ||
const lens = useSelector(selectQueryLens); | ||
const chartType = useSelector(selectTrendsChartType); | ||
const tip = useSelector(selectTrendsTooltip); | ||
const hasCompanyTypeahead = lens === 'Company' && !focus; | ||
const hasTotal = chartType === 'area'; | ||
const tooltip = externalTooltipFormatter(tip); | ||
if (tooltip && tooltip.values) { | ||
return ( | ||
<section className="tooltip-container u-clearfix"> | ||
{!!hasCompanyTypeahead && <CompanyTypeahead id="external-tooltip" />} | ||
<p className="a-micro-copy"> | ||
<span className="heading">{tooltip.heading}</span> | ||
<span className="date">{tooltip.date}</span> | ||
</p> | ||
<div> | ||
<ul className="tooltip-ul"> | ||
{tooltip.values.map((val, key) => ( | ||
<li className={'color__' + val.colorIndex} key={key + '-id'}> | ||
<TooltipRow value={val} /> | ||
<span className="u-right">{val.value.toLocaleString()}</span> | ||
</li> | ||
))} | ||
</ul> | ||
|
||
{!!hasTotal && ( | ||
<ul className="m-list--unstyled tooltip-ul total"> | ||
<li> | ||
<span className="u-left">Total</span> | ||
<span className="u-right"> | ||
{tooltip.total.toLocaleString()} | ||
</span> | ||
</li> | ||
</ul> | ||
)} | ||
</div> | ||
<p className="a-micro-copy warn"> | ||
{WARN_SERIES_BREAK}{' '} | ||
<a | ||
href={LEARN_SERIES_BREAK} | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
aria-label="Learn more about Product and | ||
Issue changes (opens in new window)" | ||
> | ||
Learn More | ||
</a> | ||
</p> | ||
</section> | ||
); | ||
} | ||
return null; | ||
}; |
105 changes: 105 additions & 0 deletions
105
src/components/Trends/ExternalTooltip/ExternalTooltip.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { ExternalTooltip } from './ExternalTooltip'; | ||
import { merge } from '../../../testUtils/functionHelpers'; | ||
import { defaultQuery } from '../../../reducers/query/query'; | ||
import { defaultTrends } from '../../../reducers/trends/trends'; | ||
import * as filterActions from '../../../actions/filter'; | ||
import { testRender as render, screen } from '../../../testUtils/test-utils'; | ||
import userEvent from '@testing-library/user-event'; | ||
|
||
const renderComponent = (newQueryState, newTrendsState) => { | ||
merge(newTrendsState, defaultQuery); | ||
merge(newTrendsState, defaultTrends); | ||
|
||
const data = { | ||
query: newQueryState, | ||
trends: newTrendsState, | ||
}; | ||
|
||
render(<ExternalTooltip />, { | ||
preloadedState: data, | ||
}); | ||
}; | ||
|
||
jest.useRealTimers(); | ||
|
||
describe('component: ExternalTooltip', () => { | ||
const user = userEvent.setup(); | ||
test('empty rendering', () => { | ||
renderComponent({}, {}); | ||
expect(screen.queryByText('foobar')).toBeNull(); | ||
}); | ||
test('rendering', () => { | ||
const query = { | ||
focus: '', | ||
lens: '', | ||
}; | ||
const trends = { | ||
tooltip: { | ||
title: 'Date Range: 1/1/1900 - 1/1/2000', | ||
total: 2900, | ||
values: [ | ||
{ colorIndex: 1, name: 'foo', value: 1000 }, | ||
{ colorIndex: 2, name: 'bar', value: 1000 }, | ||
{ colorIndex: 3, name: 'All other', value: 900 }, | ||
{ colorIndex: 4, name: "Eat at Joe's", value: 1000 }, | ||
], | ||
}, | ||
}; | ||
renderComponent(query, trends); | ||
expect(screen.getByText('foo')).toBeInTheDocument(); | ||
expect(screen.getByText('Date Range:')).toBeInTheDocument(); | ||
expect(screen.getByText('1/1/1900 - 1/1/2000')).toBeInTheDocument(); | ||
expect(screen.getByText('900')).toBeInTheDocument(); | ||
}); | ||
|
||
test('rendering Company typeahead', async () => { | ||
const filterRemovedSpy = jest.spyOn(filterActions, 'removeFilter'); | ||
const query = { focus: '', lens: 'Company' }; | ||
const trends = { | ||
tooltip: { | ||
title: 'Date Range: 1/1/1900 - 1/1/2000', | ||
total: 2900, | ||
values: [ | ||
{ colorIndex: 1, name: 'foo', value: 1000 }, | ||
{ colorIndex: 2, name: 'bar', value: 1000 }, | ||
{ colorIndex: 3, name: 'All other', value: 900 }, | ||
{ colorIndex: 4, name: "Eat at Joe's", value: 1000 }, | ||
], | ||
}, | ||
}; | ||
renderComponent(query, trends); | ||
expect(screen.getByText('foo')).toBeInTheDocument(); | ||
expect( | ||
screen.getByPlaceholderText('Enter company name'), | ||
).toBeInTheDocument(); | ||
expect( | ||
screen.getByRole('button', { name: 'Remove foo from comparison set' }), | ||
).toBeInTheDocument(); | ||
await user.click( | ||
screen.getByRole('button', { name: 'Remove foo from comparison set' }), | ||
); | ||
expect(filterRemovedSpy).toHaveBeenCalledWith('company', 'foo'); | ||
}); | ||
|
||
test('hide Company typeahead in company Focus Mode', () => { | ||
const query = { | ||
focus: 'Acme Foobar', | ||
lens: 'Company', | ||
}; | ||
const trends = { | ||
tooltip: { | ||
title: 'Date Range: 1/1/1900 - 1/1/2000', | ||
total: 2900, | ||
values: [ | ||
{ colorIndex: 1, name: 'foo', value: 1000 }, | ||
{ colorIndex: 2, name: 'bar', value: 1000 }, | ||
{ colorIndex: 3, name: 'All other', value: 900 }, | ||
{ colorIndex: 4, name: "Eat at Joe's", value: 1000 }, | ||
], | ||
}, | ||
}; | ||
renderComponent(query, trends); | ||
expect(screen.getByText('foo')).toBeInTheDocument(); | ||
expect(screen.queryByPlaceholderText('Enter company name')).toBeNull(); | ||
}); | ||
}); |
Oops, something went wrong.