diff options
author | Jeremy Davis <jeremy.davis@sonarsource.com> | 2022-08-03 16:12:20 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-08-05 20:03:27 +0000 |
commit | c92a1586c459a2e351cec20cdf40b474f56a94c3 (patch) | |
tree | 3f6ded6b29ac9bfbe3c3a2f7101f4d0ed3f45545 | |
parent | aaacc791345ceefcf458bb4b368280df864dba5b (diff) | |
download | sonarqube-c92a1586c459a2e351cec20cdf40b474f56a94c3.tar.gz sonarqube-c92a1586c459a2e351cec20cdf40b474f56a94c3.zip |
SONAR-16731 [891608] Purpose of link is not clear in context
25 files changed, 248 insertions, 46 deletions
diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx index 2940711cbbc..b5f1e51794c 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/PageSidebar-test.tsx @@ -17,55 +17,72 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { shallow } from 'enzyme'; +import { screen } from '@testing-library/react'; import * as React from 'react'; +import { CurrentUserContext } from '../../../../app/components/current-user/CurrentUserContext'; +import { mockCurrentUser } from '../../../../helpers/testMocks'; +import { renderComponent } from '../../../../helpers/testReactTestingUtils'; +import { CurrentUser } from '../../../../types/users'; import PageSidebar, { PageSidebarProps } from '../PageSidebar'; -it('should render correctly', () => { - const sidebar = shallowRender({ - query: { size: '3' }, - view: 'overall' +it('should render the right facets for overview', () => { + renderPageSidebar({ + query: { size: '3' } }); - expect(sidebar).toMatchSnapshot(); + expect(screen.getByRole('heading', { level: 3, name: 'metric_domain.Size' })).toBeInTheDocument(); + + expect( + screen.getByRole('heading', { level: 3, name: 'projects.facets.qualifier' }) + ).toBeInTheDocument(); + + expect( + screen.queryByRole('heading', { level: 3, name: 'projects.facets.new_lines' }) + ).not.toBeInTheDocument(); }); -it('should render correctly with no applications', () => { - const sidebar = shallowRender({ +it('should not show the qualifier facet with no applications', () => { + renderPageSidebar({ applicationsEnabled: false, - query: { size: '3' }, - view: 'overall' + query: { size: '3' } }); - expect(sidebar).toMatchSnapshot(); + expect( + screen.queryByRole('heading', { level: 3, name: 'projects.facets.qualifier' }) + ).not.toBeInTheDocument(); }); -it('should render `leak` view correctly', () => { - const sidebar = shallowRender({ +it('should show "new lines" instead of "size" when in `leak` view', () => { + renderPageSidebar({ query: { view: 'leak' }, view: 'leak' }); - expect(sidebar).toMatchSnapshot(); -}); -it('should render `leak` view correctly with no applications', () => { - const sidebar = shallowRender({ - applicationsEnabled: false, - query: { view: 'leak' }, - view: 'leak' - }); - expect(sidebar).toMatchSnapshot(); + expect( + screen.queryByRole('heading', { level: 3, name: 'metric_domain.Size' }) + ).not.toBeInTheDocument(); + + expect( + screen.getByRole('heading', { level: 3, name: 'projects.facets.new_lines' }) + ).toBeInTheDocument(); }); -function shallowRender(overrides: Partial<PageSidebarProps> = {}) { - return shallow( - <PageSidebar - applicationsEnabled={true} - onClearAll={jest.fn()} - onQueryChange={jest.fn()} - query={{ view: 'overall' }} - view="overall" - {...overrides} - /> - ); +function renderPageSidebar(overrides: Partial<PageSidebarProps> = {}, currentUser?: CurrentUser) { + return renderComponent( + <CurrentUserContext.Provider + value={{ + currentUser: currentUser ?? mockCurrentUser(), + updateCurrentUserHomepage: jest.fn(), + updateDismissedNotices: jest.fn() + }}> + <PageSidebar + applicationsEnabled={true} + onClearAll={jest.fn()} + onQueryChange={jest.fn()} + query={{ view: 'overall' }} + view="overall" + {...overrides} + /> + </CurrentUserContext.Provider> + ).container; } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.tsx index a93ca431ea0..54717829ac2 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.tsx @@ -19,7 +19,7 @@ */ import * as React from 'react'; import CoverageRating from '../../../components/ui/CoverageRating'; -import { translate } from '../../../helpers/l10n'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; import { getCoverageRatingAverageValue, getCoverageRatingLabel } from '../../../helpers/ratings'; import { RawQuery } from '../../../types/types'; import { Facet } from '../types'; @@ -35,6 +35,8 @@ export interface Props { value?: any; } +const NO_DATA_OPTION = 6; + export default function CoverageFilter(props: Props) { const { property = 'coverage' } = props; @@ -50,6 +52,7 @@ export default function CoverageFilter(props: Props) { onQueryChange={props.onQueryChange} options={[1, 2, 3, 4, 5, 6]} property={property} + renderAccessibleLabel={renderAccessibleLabel} renderOption={renderOption} value={props.value} /> @@ -61,10 +64,19 @@ function getFacetValueForOption(facet: Facet, option: number): number { return facet[map[option - 1]]; } +function renderAccessibleLabel(option: number) { + return option < NO_DATA_OPTION + ? translate('projects.facets.coverage.label', option.toString()) + : translateWithParameters( + 'projects.facets.label_no_data_x', + translate('metric_domain.Coverage') + ); +} + function renderOption(option: number, selected: boolean) { return ( <div className="display-flex-center"> - {option < 6 && ( + {option < NO_DATA_OPTION && ( <CoverageRating muted={!selected} size="small" @@ -72,7 +84,7 @@ function renderOption(option: number, selected: boolean) { /> )} <span className="spacer-left"> - {option < 6 ? ( + {option < NO_DATA_OPTION ? ( getCoverageRatingLabel(option) ) : ( <span className="big-spacer-left">{translate('no_data')}</span> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.tsx index c3821b81ed4..0520515fa44 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.tsx @@ -19,7 +19,7 @@ */ import * as React from 'react'; import DuplicationsRating from '../../../components/ui/DuplicationsRating'; -import { translate } from '../../../helpers/l10n'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; import { getDuplicationsRatingAverageValue, getDuplicationsRatingLabel @@ -38,6 +38,8 @@ export interface Props { value?: any; } +const NO_DATA_OPTION = 6; + export default function DuplicationsFilter(props: Props) { const { property = 'duplications' } = props; return ( @@ -52,6 +54,7 @@ export default function DuplicationsFilter(props: Props) { onQueryChange={props.onQueryChange} options={[1, 2, 3, 4, 5, 6]} property={property} + renderAccessibleLabel={renderAccessibleLabel} renderOption={renderOption} value={props.value} /> @@ -63,10 +66,19 @@ function getFacetValueForOption(facet: Facet, option: number) { return facet[map[option - 1]]; } +function renderAccessibleLabel(option: number) { + return option < NO_DATA_OPTION + ? translate('projects.facets.duplication.label', option.toString()) + : translateWithParameters( + 'projects.facets.label_no_data_x', + translate('metric_domain.Duplications') + ); +} + function renderOption(option: number, selected: boolean) { return ( <div className="display-flex-center"> - {option < 6 && ( + {option < NO_DATA_OPTION && ( <DuplicationsRating muted={!selected} size="small" @@ -74,7 +86,7 @@ function renderOption(option: number, selected: boolean) { /> )} <span className="spacer-left"> - {option < 6 ? ( + {option < NO_DATA_OPTION ? ( getDuplicationsRatingLabel(option) ) : ( <span className="big-spacer-left">{translate('no_data')}</span> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx index 7f5c5db9fce..1693fd2494f 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/Filter.tsx @@ -31,6 +31,7 @@ interface Props { className?: string; onQueryChange: (change: RawQuery) => void; options: Option[]; + renderAccessibleLabel: (option: Option) => string; renderOption: (option: Option, isSelected: boolean) => React.ReactNode; value?: Option | Option[]; @@ -126,7 +127,13 @@ export default class Filter extends React.PureComponent<Props> { option > value; return ( - <a className={className} data-key={option} href="#" key={option} onClick={this.handleClick}> + <a + aria-label={this.props.renderAccessibleLabel(option)} + className={className} + data-key={option} + href="#" + key={option} + onClick={this.handleClick}> <span className="facet-name"> {this.props.renderOption(option, this.isSelected(option) || isUnderSelectedOption)} </span> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.tsx index 28ec1bbf4cb..57d9ac71690 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.tsx @@ -19,7 +19,8 @@ */ import * as React from 'react'; import Rating from '../../../components/ui/Rating'; -import { translate } from '../../../helpers/l10n'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; +import { formatMeasure } from '../../../helpers/measures'; import { RawQuery } from '../../../types/types'; import { Facet } from '../types'; import Filter from './Filter'; @@ -37,6 +38,27 @@ interface Props { } export default function IssuesFilter(props: Props) { + const { name } = props; + + const renderAccessibleLabel = React.useCallback( + (option: number) => { + if (option === 1) { + return translateWithParameters( + 'projects.facets.rating_label_single_x', + translate('metric_domain', name), + formatMeasure(option, 'RATING') + ); + } + + return translateWithParameters( + 'projects.facets.rating_label_multi_x', + translate('metric_domain', name), + formatMeasure(option, 'RATING') + ); + }, + [name] + ); + return ( <Filter className={props.className} @@ -51,6 +73,7 @@ export default function IssuesFilter(props: Props) { onQueryChange={props.onQueryChange} options={[1, 2, 3, 4, 5]} property={props.property} + renderAccessibleLabel={renderAccessibleLabel} renderOption={renderOption} value={props.value} /> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx index 141fd43f77b..4967425be1b 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx @@ -20,7 +20,7 @@ import { difference, sortBy } from 'lodash'; import * as React from 'react'; import withLanguagesContext from '../../../app/components/languages/withLanguagesContext'; -import { translate } from '../../../helpers/l10n'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; import { Languages } from '../../../types/languages'; import { Dict, RawQuery } from '../../../types/types'; import { Facet } from '../types'; @@ -52,6 +52,15 @@ export class LanguagesFilter extends React.Component<Props> { getSortedOptions = (facet: Facet = {}) => sortBy(Object.keys(facet), [(option: string) => -facet[option], (option: string) => option]); + renderAccessibleLabel = (option: string) => { + const { languages } = this.props; + return translateWithParameters( + 'projects.facets.label_text_x', + translate('projects.facets.languages'), + languages[option]?.name || option + ); + }; + renderOption = (option: string) => ( <SearchableFilterOption option={this.props.languages[option]} optionKey={option} /> ); @@ -75,6 +84,7 @@ export class LanguagesFilter extends React.Component<Props> { onQueryChange={this.props.onQueryChange} options={this.getSortedOptions(this.props.facet)} property={property} + renderAccessibleLabel={this.renderAccessibleLabel} renderOption={this.renderOption} value={this.props.value} /> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/NewLinesFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/NewLinesFilter.tsx index 106ab095f92..4ca2c1d8264 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/NewLinesFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/NewLinesFilter.tsx @@ -47,6 +47,7 @@ export default function NewLinesFilter(props: Props) { onQueryChange={props.onQueryChange} options={[1, 2, 3, 4, 5]} property={property} + renderAccessibleLabel={renderAccessibleLabel} renderOption={renderOption} value={props.value} /> @@ -61,3 +62,7 @@ function getFacetValueForOption(facet: Facet, option: number) { function renderOption(option: number) { return <span>{getSizeRatingLabel(option)}</span>; } + +function renderAccessibleLabel(option: number) { + return translate('projects.facets.new_lines.label', option.toString()); +} diff --git a/server/sonar-web/src/main/js/apps/projects/filters/QualifierFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/QualifierFilter.tsx index 26be7822881..8b45934dc73 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/QualifierFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/QualifierFilter.tsx @@ -19,7 +19,7 @@ */ import * as React from 'react'; import QualifierIcon from '../../../components/icons/QualifierIcon'; -import { translate } from '../../../helpers/l10n'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; import { ComponentQualifier } from '../../../types/component'; import { RawQuery } from '../../../types/types'; import { Facet } from '../types'; @@ -46,12 +46,21 @@ export default function QualifierFilter(props: QualifierFilterProps) { onQueryChange={props.onQueryChange} options={options} property="qualifier" + renderAccessibleLabel={renderAccessibleLabel} renderOption={renderOption} value={value} /> ); } +function renderAccessibleLabel(option: string) { + return translateWithParameters( + 'projects.facets.label_text_x', + translate('projects.facets.qualifier'), + translate('qualifier', option) + ); +} + function renderOption(option: string, selected: boolean) { return ( <span className="display-flex-center"> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.tsx index c0d5e024c73..4501f9e2de0 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.tsx @@ -20,7 +20,7 @@ import * as React from 'react'; import HelpTooltip from '../../../components/controls/HelpTooltip'; import Level from '../../../components/ui/Level'; -import { translate } from '../../../helpers/l10n'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; import { RawQuery } from '../../../types/types'; import { Facet } from '../types'; import Filter from './Filter'; @@ -33,6 +33,13 @@ export interface Props { value?: any; } +function renderAccessibleLabel(option: string) { + return translateWithParameters( + 'projects.facets.qualitygate_label_x', + translate('metric.level', option) + ); +} + export default function QualityGateFilter(props: Props) { const hasWarnStatus = props.facet && props.facet['WARN'] !== undefined; const options = hasWarnStatus ? ['OK', 'WARN', 'ERROR'] : ['OK', 'ERROR']; @@ -46,6 +53,7 @@ export default function QualityGateFilter(props: Props) { options={options} property="gate" renderOption={renderOption} + renderAccessibleLabel={renderAccessibleLabel} value={props.value} /> ); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SecurityReviewFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/SecurityReviewFilter.tsx index 0afe3b293cb..dfe0491984c 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/SecurityReviewFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/SecurityReviewFilter.tsx @@ -20,7 +20,8 @@ import * as React from 'react'; import SecurityHotspotIcon from '../../../components/icons/SecurityHotspotIcon'; import Rating from '../../../components/ui/Rating'; -import { translate } from '../../../helpers/l10n'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; +import { formatMeasure } from '../../../helpers/measures'; import { Dict, RawQuery } from '../../../types/types'; import { Facet } from '../types'; import Filter from './Filter'; @@ -65,12 +66,29 @@ export default function SecurityReviewFilter(props: Props) { onQueryChange={props.onQueryChange} options={[1, 2, 3, 4, 5]} property={property} + renderAccessibleLabel={renderAccessibleLabel} renderOption={renderOption} value={props.value} /> ); } +function renderAccessibleLabel(option: number) { + if (option === 1) { + return translateWithParameters( + 'projects.facets.rating_label_single_x', + translate('metric_domain.SecurityReview'), + formatMeasure(option, 'RATING') + ); + } + + return translateWithParameters( + 'projects.facets.rating_label_multi_x', + translate('metric_domain.SecurityReview'), + formatMeasure(option, 'RATING') + ); +} + function renderOption(option: number, selected: boolean) { return ( <span> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.tsx index 529d33ce4d2..0eb7ad04860 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.tsx @@ -49,6 +49,7 @@ export default function SizeFilter(props: Props) { onQueryChange={props.onQueryChange} options={[1, 2, 3, 4, 5]} property={property} + renderAccessibleLabel={renderAccessibleLabel} renderOption={renderOption} value={props.value} /> @@ -68,3 +69,7 @@ function renderOption(option: number, selected: boolean) { </div> ); } + +function renderAccessibleLabel(option: number) { + return translate('projects.facets.size.label', option.toString()); +} diff --git a/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.tsx index b4844f47deb..ea0e9da5dc0 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.tsx @@ -20,7 +20,7 @@ import { debounce, difference, size, sortBy } from 'lodash'; import * as React from 'react'; import { searchProjectTags } from '../../../api/components'; -import { translate } from '../../../helpers/l10n'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; import { Dict, RawQuery } from '../../../types/types'; import { Facet } from '../types'; import Filter from './Filter'; @@ -45,6 +45,14 @@ interface State { const LIST_SIZE = 10; +function renderAccessibleLabel(option: string) { + return translateWithParameters( + 'projects.facets.label_text_x', + translate('projects.facets.tags'), + option + ); +} + export default class TagsFilter extends React.PureComponent<Props, State> { mounted = false; @@ -119,6 +127,7 @@ export default class TagsFilter extends React.PureComponent<Props, State> { onQueryChange={this.props.onQueryChange} options={this.getSortedOptions(this.props.facet)} property={property} + renderAccessibleLabel={renderAccessibleLabel} renderOption={this.renderOption} value={this.props.value} /> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/Filter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/Filter-test.tsx index c6c80b6a102..14b9a2c55e3 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/Filter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/Filter-test.tsx @@ -67,6 +67,7 @@ function shallowRender(overrides: Partial<Filter['props']> = {}) { options={[1, 2, 3]} property="foo" renderOption={option => option} + renderAccessibleLabel={option => option.toString()} {...overrides} /> ); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/CoverageFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/CoverageFilter-test.tsx.snap index a77a3e20f95..04f540477f7 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/CoverageFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/CoverageFilter-test.tsx.snap @@ -22,6 +22,7 @@ exports[`renders 1`] = ` ] } property="coverage" + renderAccessibleLabel={[Function]} renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/DuplicationsFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/DuplicationsFilter-test.tsx.snap index 4672e648690..b20207155db 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/DuplicationsFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/DuplicationsFilter-test.tsx.snap @@ -22,6 +22,7 @@ exports[`renders 1`] = ` ] } property="duplications" + renderAccessibleLabel={[Function]} renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/Filter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/Filter-test.tsx.snap index d0d09c08b8c..c63c31cecea 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/Filter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/Filter-test.tsx.snap @@ -9,6 +9,7 @@ exports[`highlights under 1`] = ` className="search-navigator-facet-list projects-facet-list" > <a + aria-label="1" className="facet search-navigator-facet projects-facet" data-key={1} href="#" @@ -25,6 +26,7 @@ exports[`highlights under 1`] = ` className="search-navigator-facet-highlight-under-container" > <a + aria-label="2" className="facet search-navigator-facet projects-facet" data-key={2} href="#" @@ -38,6 +40,7 @@ exports[`highlights under 1`] = ` </span> </a> <a + aria-label="3" className="facet search-navigator-facet projects-facet" data-key={3} href="#" @@ -64,6 +67,7 @@ exports[`hightlights under selected 1`] = ` className="search-navigator-facet-list projects-facet-list" > <a + aria-label="1" className="facet search-navigator-facet projects-facet" data-key={1} href="#" @@ -80,6 +84,7 @@ exports[`hightlights under selected 1`] = ` className="search-navigator-facet-highlight-under-container" > <a + aria-label="2" className="facet search-navigator-facet projects-facet active" data-key={2} href="#" @@ -93,6 +98,7 @@ exports[`hightlights under selected 1`] = ` </span> </a> <a + aria-label="3" className="facet search-navigator-facet projects-facet" data-key={3} href="#" @@ -119,6 +125,7 @@ exports[`renders 1`] = ` className="search-navigator-facet-list projects-facet-list" > <a + aria-label="1" className="facet search-navigator-facet projects-facet" data-key={1} href="#" @@ -132,6 +139,7 @@ exports[`renders 1`] = ` </span> </a> <a + aria-label="2" className="facet search-navigator-facet projects-facet" data-key={2} href="#" @@ -145,6 +153,7 @@ exports[`renders 1`] = ` </span> </a> <a + aria-label="3" className="facet search-navigator-facet projects-facet" data-key={3} href="#" @@ -170,6 +179,7 @@ exports[`renders facet bar chart 1`] = ` className="search-navigator-facet-list projects-facet-list" > <a + aria-label="a" className="facet search-navigator-facet projects-facet" data-key="a" href="#" @@ -200,6 +210,7 @@ exports[`renders facet bar chart 1`] = ` </span> </a> <a + aria-label="b" className="facet search-navigator-facet projects-facet" data-key="b" href="#" @@ -230,6 +241,7 @@ exports[`renders facet bar chart 1`] = ` </span> </a> <a + aria-label="c" className="facet search-navigator-facet projects-facet" data-key="c" href="#" @@ -273,6 +285,7 @@ exports[`renders header and footer 1`] = ` className="search-navigator-facet-list projects-facet-list" > <a + aria-label="1" className="facet search-navigator-facet projects-facet" data-key={1} href="#" @@ -286,6 +299,7 @@ exports[`renders header and footer 1`] = ` </span> </a> <a + aria-label="2" className="facet search-navigator-facet projects-facet" data-key={2} href="#" @@ -299,6 +313,7 @@ exports[`renders header and footer 1`] = ` </span> </a> <a + aria-label="3" className="facet search-navigator-facet projects-facet" data-key={3} href="#" @@ -325,6 +340,7 @@ exports[`renders multiple selected 1`] = ` className="search-navigator-facet-list projects-facet-list" > <a + aria-label="1" className="facet search-navigator-facet projects-facet active" data-key={1} href="#" @@ -338,6 +354,7 @@ exports[`renders multiple selected 1`] = ` </span> </a> <a + aria-label="2" className="facet search-navigator-facet projects-facet active" data-key={2} href="#" @@ -351,6 +368,7 @@ exports[`renders multiple selected 1`] = ` </span> </a> <a + aria-label="3" className="facet search-navigator-facet projects-facet" data-key={3} href="#" @@ -389,6 +407,7 @@ exports[`renders selected 1`] = ` className="search-navigator-facet-list projects-facet-list" > <a + aria-label="1" className="facet search-navigator-facet projects-facet" data-key={1} href="#" @@ -402,6 +421,7 @@ exports[`renders selected 1`] = ` </span> </a> <a + aria-label="2" className="facet search-navigator-facet projects-facet active" data-key={2} href="#" @@ -415,6 +435,7 @@ exports[`renders selected 1`] = ` </span> </a> <a + aria-label="3" className="facet search-navigator-facet projects-facet" data-key={3} href="#" diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/IssuesFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/IssuesFilter-test.tsx.snap index 64e83a0b6a2..d8e685cdb57 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/IssuesFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/IssuesFilter-test.tsx.snap @@ -19,6 +19,7 @@ exports[`renders 1`] = ` ] } property="bugs" + renderAccessibleLabel={[Function]} renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap index c366f8e6858..4e2ba5f9db3 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/LanguagesFilter-test.tsx.snap @@ -53,6 +53,7 @@ exports[`should render the languages facet with the selected languages 1`] = ` ] } property="languages" + renderAccessibleLabel={[Function]} renderOption={[Function]} value={ Array [ @@ -75,6 +76,7 @@ exports[`should render the languages facet with the selected languages 2`] = ` className="search-navigator-facet-list projects-facet-list" > <a + aria-label="projects.facets.label_text_x.projects.facets.languages.Java" className="facet search-navigator-facet projects-facet active" data-key="java" href="#" @@ -101,6 +103,7 @@ exports[`should render the languages facet with the selected languages 2`] = ` </span> </a> <a + aria-label="projects.facets.label_text_x.projects.facets.languages.C#" className="facet search-navigator-facet projects-facet active" data-key="cs" href="#" @@ -127,6 +130,7 @@ exports[`should render the languages facet with the selected languages 2`] = ` </span> </a> <a + aria-label="projects.facets.label_text_x.projects.facets.languages.JavaScript" className="facet search-navigator-facet projects-facet" data-key="js" href="#" @@ -234,6 +238,7 @@ exports[`should render the languages without the ones in the facet 1`] = ` ] } property="languages" + renderAccessibleLabel={[Function]} renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewLinesFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewLinesFilter-test.tsx.snap index 6d4b91aa8b8..0997f882a49 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewLinesFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewLinesFilter-test.tsx.snap @@ -21,6 +21,7 @@ exports[`renders 1`] = ` ] } property="new_lines" + renderAccessibleLabel={[Function]} renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualifierFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualifierFilter-test.tsx.snap index 78a419e37a4..a4f41ad201c 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualifierFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualifierFilter-test.tsx.snap @@ -15,6 +15,7 @@ exports[`renders 1`] = ` ] } property="qualifier" + renderAccessibleLabel={[Function]} renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualityGateFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualityGateFilter-test.tsx.snap index f886d4bf11d..dccd1856c4e 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualityGateFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualityGateFilter-test.tsx.snap @@ -15,6 +15,7 @@ exports[`renders 1`] = ` ] } property="gate" + renderAccessibleLabel={[Function]} renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityReviewFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityReviewFilter-test.tsx.snap index d035ae827e5..9345ad925c2 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityReviewFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityReviewFilter-test.tsx.snap @@ -30,6 +30,7 @@ exports[`renders 1`] = ` ] } property="security_review" + renderAccessibleLabel={[Function]} renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SizeFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SizeFilter-test.tsx.snap index 24fa109ec75..bd9faa3be3e 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SizeFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SizeFilter-test.tsx.snap @@ -20,6 +20,7 @@ exports[`renders 1`] = ` ] } property="size" + renderAccessibleLabel={[Function]} renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap index 8c1830ec284..f9c28886877 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/TagsFilter-test.tsx.snap @@ -86,6 +86,7 @@ exports[`should render maximum 10 tags in the searchbox results 1`] = ` ] } property="tags" + renderAccessibleLabel={[Function]} renderOption={[Function]} value={ Array [ @@ -137,6 +138,7 @@ exports[`should render the tags facet with the selected tags 1`] = ` ] } property="tags" + renderAccessibleLabel={[Function]} renderOption={[Function]} value={ Array [ @@ -159,6 +161,7 @@ exports[`should render the tags facet with the selected tags 2`] = ` className="search-navigator-facet-list projects-facet-list" > <a + aria-label="projects.facets.label_text_x.projects.facets.tags.lang" className="facet search-navigator-facet projects-facet active" data-key="lang" href="#" @@ -179,6 +182,7 @@ exports[`should render the tags facet with the selected tags 2`] = ` </span> </a> <a + aria-label="projects.facets.label_text_x.projects.facets.tags.sonar" className="facet search-navigator-facet projects-facet active" data-key="sonar" href="#" @@ -199,6 +203,7 @@ exports[`should render the tags facet with the selected tags 2`] = ` </span> </a> <a + aria-label="projects.facets.label_text_x.projects.facets.tags.csharp" className="facet search-navigator-facet projects-facet" data-key="csharp" href="#" @@ -276,6 +281,7 @@ exports[`should render the tags without the ones in the facet 1`] = ` ] } property="tags" + renderAccessibleLabel={[Function]} renderOption={[Function]} /> `; @@ -333,6 +339,7 @@ exports[`should render the tags without the ones in the facet 2`] = ` ] } property="tags" + renderAccessibleLabel={[Function]} renderOption={[Function]} /> `; diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 95aef3ccd94..de3dc9b4373 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -1064,6 +1064,31 @@ projects.facets.languages=Languages projects.facets.new_lines=New Lines projects.facets.tags=Tags projects.facets.qualifier=Type +projects.facets.qualitygate_label_x=Click to filter projects with a {0} quality gate. +projects.facets.rating_label_single_x=Click to filter projects with a {0} rating of {1}. +projects.facets.rating_label_multi_x=Click to filter projects with a {0} rating of {1} or worse. +projects.facets.label_no_data_x=Click to filter projects with no {0} data. +projects.facets.label_text_x=Click to filter projects by {0}: {1} +projects.facets.size.label.1=Click to filter projects with fewer than 1k lines of code +projects.facets.size.label.2=Click to filter projects with 1k lines of code or more +projects.facets.size.label.3=Click to filter projects with 10k lines of code or more +projects.facets.size.label.4=Click to filter projects with 100k lines of code or more +projects.facets.size.label.5=Click to filter projects with more than 500k lines of code +projects.facets.new_lines.label.1=Click to filter projects with fewer than 1k new lines +projects.facets.new_lines.label.2=Click to filter projects with 1k new lines or more +projects.facets.new_lines.label.3=Click to filter projects with 10k new lines or more +projects.facets.new_lines.label.4=Click to filter projects with 100k new lines or more +projects.facets.new_lines.label.5=Click to filter projects with more than 500k new lines +projects.facets.coverage.label.1=Click to filter projects with more than 80% coverage +projects.facets.coverage.label.2=Click to filter projects with less than 80% coverage +projects.facets.coverage.label.3=Click to filter projects with less than 70% coverage +projects.facets.coverage.label.4=Click to filter projects with less than 50% coverage +projects.facets.coverage.label.5=Click to filter projects with less than 30% coverage +projects.facets.duplication.label.1=Click to filter projects with less than 3% duplication +projects.facets.duplication.label.2=Click to filter projects with more than 3% duplication +projects.facets.duplication.label.3=Click to filter projects with more than 5% duplication +projects.facets.duplication.label.4=Click to filter projects with more than 10% duplication +projects.facets.duplication.label.5=Click to filter projects with more than 20% duplication projects.sort.disabled=Disabled because sorting cannot affect the displayed result with the current project selection. projects.sort.analysis_date=by last analysis date (oldest first) projects.sort.-analysis_date=by last analysis date (latest first) |