diff options
author | Jeremy Davis <jeremy.davis@sonarsource.com> | 2020-04-01 16:40:30 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2020-04-15 20:03:38 +0000 |
commit | afa5ca444414f8c4352afb53528b9514d1c22c77 (patch) | |
tree | 24e34f6255bb9dc131443c7749f230fb61eaa38d /server/sonar-web/src/main/js/apps/projects | |
parent | f535e9b3fc11d6020a0d6143ab3931d2d5566627 (diff) | |
download | sonarqube-afa5ca444414f8c4352afb53528b9514d1c22c77.tar.gz sonarqube-afa5ca444414f8c4352afb53528b9514d1c22c77.zip |
SONAR-13189 Add qualifier facet to projects
Diffstat (limited to 'server/sonar-web/src/main/js/apps/projects')
61 files changed, 381 insertions, 518 deletions
diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx index 07aee81409d..89e22be3c20 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx @@ -28,13 +28,11 @@ import { addSideBarClass, removeSideBarClass } from 'sonar-ui-common/helpers/pag import { get, save } from 'sonar-ui-common/helpers/storage'; import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget'; import Suggestions from '../../../app/components/embed-docs-modal/Suggestions'; -import { OnboardingContext } from '../../../app/components/OnboardingContext'; import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper'; import { Location, Router, withRouter } from '../../../components/hoc/withRouter'; import '../../../components/search-navigator.css'; -import { isSonarCloud } from '../../../helpers/system'; import { isLoggedIn } from '../../../helpers/users'; -import OrganizationEmpty from '../../organizations/components/OrganizationEmpty'; +import { ComponentQualifier } from '../../../types/component'; import { hasFilterParams, hasVisualizationParams, parseUrlQuery, Query } from '../query'; import '../styles.css'; import { Facets, Project } from '../types'; @@ -49,13 +47,13 @@ interface Props { isFavorite: boolean; location: Pick<Location, 'pathname' | 'query'>; organization: T.Organization | undefined; + qualifiers: ComponentQualifier[]; router: Pick<Router, 'push' | 'replace'>; storageOptionsSuffix?: string; } interface State { facets?: Facets; - initialLoading: boolean; loading: boolean; pageIndex?: number; projects?: Project[]; @@ -72,7 +70,7 @@ export class AllProjects extends React.PureComponent<Props, State> { constructor(props: Props) { super(props); - this.state = { initialLoading: true, loading: true, query: {} }; + this.state = { loading: true, query: {} }; } componentDidMount() { @@ -83,23 +81,13 @@ export class AllProjects extends React.PureComponent<Props, State> { return; } this.handleQueryChange(true); - this.updateFooterClass(); + addSideBarClass(); } componentDidUpdate(prevProps: Props) { if (prevProps.location.query !== this.props.location.query) { this.handleQueryChange(false); } - - if ( - prevProps.organization && - this.props.organization && - prevProps.organization.key !== this.props.organization.key - ) { - this.setState({ initialLoading: true }); - } - - this.updateFooterClass(); } componentWillUnmount() { @@ -113,7 +101,6 @@ export class AllProjects extends React.PureComponent<Props, State> { if (this.mounted) { this.setState({ facets: response.facets, - initialLoading: false, loading: false, pageIndex: 1, projects: response.projects, @@ -232,7 +219,7 @@ export class AllProjects extends React.PureComponent<Props, State> { stopLoading = () => { if (this.mounted) { - this.setState({ initialLoading: false, loading: false }); + this.setState({ loading: false }); } }; @@ -241,19 +228,6 @@ export class AllProjects extends React.PureComponent<Props, State> { this.props.router.push({ pathname: this.props.location.pathname, query }); }; - updateFooterClass = () => { - const { organization } = this.props; - const { initialLoading, projects } = this.state; - const isOrganizationContext = isSonarCloud() && organization; - const isEmpty = projects && projects.length === 0; - - if (isOrganizationContext && (initialLoading || isEmpty)) { - removeSideBarClass(); - } else { - addSideBarClass(); - } - }; - renderSide = () => ( <ScreenPositionHelper className="layout-page-side-outer"> {({ top }) => ( @@ -267,12 +241,12 @@ export class AllProjects extends React.PureComponent<Props, State> { /> <PageSidebar + applicationsEnabled={this.props.qualifiers.includes(ComponentQualifier.Application)} facets={this.state.facets} onClearAll={this.handleClearAll} onQueryChange={this.updateLocationQuery} organization={this.props.organization} query={this.state.query} - showFavoriteFilter={!isSonarCloud()} view={this.getView()} visualization={this.getVisualization()} /> @@ -316,7 +290,7 @@ export class AllProjects extends React.PureComponent<Props, State> { <div className="layout-page-main-inner"> {this.state.projects && ( <Visualizations - displayOrganizations={!this.props.organization && isSonarCloud()} + displayOrganizations={false} projects={this.state.projects} sort={this.state.query.sort} total={this.state.total} @@ -350,51 +324,19 @@ export class AllProjects extends React.PureComponent<Props, State> { }; render() { - const { organization } = this.props; - const { projects } = this.state; - const isOrganizationContext = isSonarCloud() && organization; - const initialLoading = isOrganizationContext && this.state.initialLoading; - const organizationEmpty = - isOrganizationContext && - projects && - projects.length === 0 && - !this.state.loading && - !hasFilterParams(this.state.query); - return ( <div className="layout-page projects-page" id="projects-page"> <Suggestions suggestions="projects" /> <Helmet defer={false} title={translate('projects.page')} /> - {initialLoading ? ( - <div className="display-flex-space-around width-100 huge-spacer-top"> - <DeferredSpinner /> - </div> - ) : ( - <> - {!organizationEmpty && this.renderSide()} - - <div className="layout-page-main"> - <A11ySkipTarget anchor="projects_main" /> - - {organizationEmpty && organization ? ( - <OnboardingContext.Consumer> - {openProjectOnboarding => ( - <OrganizationEmpty - openProjectOnboarding={openProjectOnboarding} - organization={organization} - /> - )} - </OnboardingContext.Consumer> - ) : ( - <> - {this.renderHeader()} - {this.renderMain()} - </> - )} - </div> - </> - )} + {this.renderSide()} + + <div className="layout-page-main"> + <A11ySkipTarget anchor="projects_main" /> + + {this.renderHeader()} + {this.renderMain()} + </div> </div> ); } diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx index 09c3f522345..640630d61ed 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx @@ -19,11 +19,12 @@ */ import { connect } from 'react-redux'; import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; -import { areThereCustomOrganizations, getCurrentUser, Store } from '../../../store/rootReducer'; +import { getAppState, getCurrentUser, Store } from '../../../store/rootReducer'; +import { ComponentQualifier } from '../../../types/component'; const stateToProps = (state: Store) => ({ currentUser: getCurrentUser(state), - organizationsEnabled: areThereCustomOrganizations(state) + qualifiers: getAppState(state).qualifiers as ComponentQualifier[] }); export default connect(stateToProps)(lazyLoadComponent(() => import('./AllProjects'))); diff --git a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx index 722640090be..b92e20b1e66 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.tsx @@ -30,6 +30,7 @@ import NewLinesFilter from '../filters/NewLinesFilter'; import NewMaintainabilityFilter from '../filters/NewMaintainabilityFilter'; import NewReliabilityFilter from '../filters/NewReliabilityFilter'; import NewSecurityFilter from '../filters/NewSecurityFilter'; +import QualifierFilter from '../filters/QualifierFilter'; import QualityGateFilter from '../filters/QualityGateFilter'; import ReliabilityFilter from '../filters/ReliabilityFilter'; import SecurityFilter from '../filters/SecurityFilter'; @@ -41,23 +42,31 @@ import { Facets } from '../types'; import ClearAll from './ClearAll'; import FavoriteFilterContainer from './FavoriteFilterContainer'; -interface Props { +export interface PageSidebarProps { + applicationsEnabled: boolean; facets?: Facets; onClearAll: () => void; onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; query: T.RawQuery; - showFavoriteFilter: boolean; view: string; visualization: string; } -export default function PageSidebar(props: Props) { - const { facets, onQueryChange, query, organization, view, visualization } = props; +export default function PageSidebar(props: PageSidebarProps) { + const { + applicationsEnabled, + facets, + onQueryChange, + query, + organization, + view, + visualization + } = props; const isFiltered = hasFilterParams(query); const isLeakView = view === 'leak'; const maxFacetValue = getMaxFacetValue(facets); - const facetProps = { onQueryChange, maxFacetValue, organization, query }; + const facetProps = { onQueryChange, maxFacetValue, organization }; let linkQuery: T.RawQuery | undefined = undefined; if (view !== 'overall') { @@ -70,9 +79,7 @@ export default function PageSidebar(props: Props) { return ( <div> - {props.showFavoriteFilter && ( - <FavoriteFilterContainer organization={organization} query={linkQuery} /> - )} + <FavoriteFilterContainer organization={organization} query={linkQuery} /> <div className="projects-facets-header clearfix"> {isFiltered && <ClearAll onClearAll={props.onClearAll} />} @@ -161,9 +168,22 @@ export default function PageSidebar(props: Props) { <LanguagesFilterContainer {...facetProps} facet={getFacet(facets, 'languages')} + query={query} value={query.languages} /> - <TagsFilter {...facetProps} facet={getFacet(facets, 'tags')} value={query.tags} /> + {applicationsEnabled && ( + <QualifierFilter + {...facetProps} + facet={getFacet(facets, 'qualifier')} + value={query.qualifier} + /> + )} + <TagsFilter + {...facetProps} + facet={getFacet(facets, 'tags')} + query={query} + value={query.tags} + /> </div> ); } diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx b/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx index 3add3f6bbcb..438e519eb61 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/AllProjects-test.tsx @@ -20,8 +20,6 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { get, save } from 'sonar-ui-common/helpers/storage'; -import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; -import { isSonarCloud } from '../../../../helpers/system'; import { ComponentQualifier } from '../../../../types/component'; import { AllProjects } from '../AllProjects'; @@ -57,14 +55,11 @@ jest.mock('sonar-ui-common/helpers/storage', () => ({ save: jest.fn() })); -jest.mock('../../../../helpers/system', () => ({ isSonarCloud: jest.fn() })); - const fetchProjects = require('../../utils').fetchProjects as jest.Mock; beforeEach(() => { (get as jest.Mock).mockImplementation(() => null); (save as jest.Mock).mockClear(); - (isSonarCloud as jest.Mock).mockReturnValue(false); fetchProjects.mockClear(); }); @@ -166,28 +161,6 @@ it('changes perspective to risk visualization', () => { expect(save).toHaveBeenCalledWith('sonarqube.projects.visualization', 'risk', undefined); }); -it('renders correctly empty organization', async () => { - (isSonarCloud as jest.Mock).mockReturnValue(true); - const wrapper = shallow( - <AllProjects - currentUser={{ isLoggedIn: true }} - isFavorite={false} - location={{ pathname: '/projects', query: {} }} - organization={{ key: 'foo', name: 'Foo' }} - router={{ push: jest.fn(), replace: jest.fn() }} - /> - ); - expect(wrapper).toMatchSnapshot(); - await waitAndUpdate(wrapper); - expect(wrapper).toMatchSnapshot(); - wrapper.setState({ - loading: false, - projects: [{ key: 'foo', measures: {}, name: 'Foo' }], - total: 0 - }); - expect(wrapper).toMatchSnapshot(); -}); - it('handles favorite projects', () => { const wrapper = shallowRender(); expect(wrapper.state('projects')).toMatchSnapshot(); @@ -207,6 +180,7 @@ function shallowRender( isFavorite={false} location={{ pathname: '/projects', query: {} }} organization={undefined} + qualifiers={[ComponentQualifier.Project, ComponentQualifier.Application]} router={{ push, replace }} {...props} /> 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 197b42b5ea9..fc9969d2363 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 @@ -19,48 +19,70 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import PageSidebar from '../PageSidebar'; +import PageSidebar, { PageSidebarProps } from '../PageSidebar'; it('should render correctly', () => { - const sidebar = shallow( - <PageSidebar - onClearAll={jest.fn()} - onQueryChange={jest.fn()} - query={{ size: '3' }} - showFavoriteFilter={true} - view="overall" - visualization="risk" - /> - ); + const sidebar = shallowRender({ + query: { size: '3' }, + view: 'overall', + visualization: 'risk' + }); + + expect(sidebar).toMatchSnapshot(); +}); + +it('should render correctly with no applications', () => { + const sidebar = shallowRender({ + applicationsEnabled: false, + query: { size: '3' }, + view: 'overall', + visualization: 'risk' + }); + expect(sidebar).toMatchSnapshot(); }); it('should render `leak` view correctly', () => { - const sidebar = shallow( - <PageSidebar - onClearAll={jest.fn()} - onQueryChange={jest.fn()} - query={{ view: 'leak' }} - showFavoriteFilter={true} - view="leak" - visualization="risk" - /> - ); + const sidebar = shallowRender({ + query: { view: 'leak' }, + view: 'leak', + visualization: 'risk' + }); + expect(sidebar).toMatchSnapshot(); +}); + +it('should render `leak` view correctly with no applications', () => { + const sidebar = shallowRender({ + applicationsEnabled: false, + query: { view: 'leak' }, + view: 'leak', + visualization: 'risk' + }); expect(sidebar).toMatchSnapshot(); }); it('reset function should work correctly with view and visualizations', () => { - const sidebar = shallow( + const sidebar = shallowRender({ + query: { view: 'visualizations', visualization: 'bugs' }, + view: 'visualizations', + visualization: 'bugs' + }); + + expect(sidebar.find('ClearAll').exists()).toBe(false); + sidebar.setProps({ query: { size: '3' } }); + expect(sidebar.find('ClearAll').exists()).toBe(true); +}); + +function shallowRender(overrides: Partial<PageSidebarProps> = {}) { + return shallow( <PageSidebar + applicationsEnabled={true} onClearAll={jest.fn()} onQueryChange={jest.fn()} query={{ view: 'visualizations', visualization: 'bugs' }} - showFavoriteFilter={true} - view="visualizations" + view="overall" visualization="bugs" + {...overrides} /> ); - expect(sidebar.find('ClearAll').exists()).toBe(false); - sidebar.setProps({ query: { size: '3' } }); - expect(sidebar.find('ClearAll').exists()).toBe(true); -}); +} diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap index 58f1e3f2750..dd7306ad88d 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/AllProjects-test.tsx.snap @@ -97,6 +97,7 @@ exports[`renders 1`] = ` "new_reliability": undefined, "new_security": undefined, "new_security_review_rating": undefined, + "qualifier": undefined, "reliability": undefined, "search": undefined, "security": undefined, @@ -155,6 +156,7 @@ exports[`renders 1`] = ` "new_reliability": undefined, "new_security": undefined, "new_security_review_rating": undefined, + "qualifier": undefined, "reliability": undefined, "search": undefined, "security": undefined, @@ -272,210 +274,3 @@ exports[`renders 2`] = ` </div> </div> `; - -exports[`renders correctly empty organization 1`] = ` -<div - className="layout-page projects-page" - id="projects-page" -> - <Suggestions - suggestions="projects" - /> - <Helmet - defer={false} - encodeSpecialCharacters={true} - title="projects.page" - /> - <div - className="display-flex-space-around width-100 huge-spacer-top" - > - <DeferredSpinner - timeout={100} - /> - </div> -</div> -`; - -exports[`renders correctly empty organization 2`] = ` -<div - className="layout-page projects-page" - id="projects-page" -> - <Suggestions - suggestions="projects" - /> - <Helmet - defer={false} - encodeSpecialCharacters={true} - title="projects.page" - /> - <div - className="layout-page-main" - > - <A11ySkipTarget - anchor="projects_main" - /> - <ContextConsumer> - <Component /> - </ContextConsumer> - </div> -</div> -`; - -exports[`renders correctly empty organization 3`] = ` -<div - className="layout-page projects-page" - id="projects-page" -> - <Suggestions - suggestions="projects" - /> - <Helmet - defer={false} - encodeSpecialCharacters={true} - title="projects.page" - /> - <ScreenPositionHelper - className="layout-page-side-outer" - > - <Component /> - </ScreenPositionHelper> - <div - className="layout-page-main" - > - <A11ySkipTarget - anchor="projects_main" - /> - <div - className="layout-page-header-panel layout-page-main-header" - > - <div - className="layout-page-header-panel-inner layout-page-main-header-inner" - > - <div - className="layout-page-main-inner" - > - <PageHeader - currentUser={ - Object { - "isLoggedIn": true, - } - } - isFavorite={false} - loading={false} - onPerspectiveChange={[Function]} - onQueryChange={[Function]} - onSortChange={[Function]} - organization={ - Object { - "key": "foo", - "name": "Foo", - } - } - projects={ - Array [ - Object { - "key": "foo", - "measures": Object {}, - "name": "Foo", - }, - ] - } - query={ - Object { - "coverage": undefined, - "duplications": undefined, - "gate": undefined, - "languages": undefined, - "maintainability": undefined, - "new_coverage": undefined, - "new_duplications": undefined, - "new_lines": undefined, - "new_maintainability": undefined, - "new_reliability": undefined, - "new_security": undefined, - "new_security_review_rating": undefined, - "reliability": undefined, - "search": undefined, - "security": undefined, - "security_review_rating": undefined, - "size": undefined, - "sort": undefined, - "tags": undefined, - "view": undefined, - "visualization": undefined, - } - } - selectedSort="name" - total={0} - view="overall" - visualization="risk" - /> - </div> - </div> - </div> - <div - className="layout-page-main-inner" - > - <ProjectsList - cardType="overall" - currentUser={ - Object { - "isLoggedIn": true, - } - } - handleFavorite={[Function]} - isFavorite={false} - isFiltered={false} - organization={ - Object { - "key": "foo", - "name": "Foo", - } - } - projects={ - Array [ - Object { - "key": "foo", - "measures": Object {}, - "name": "Foo", - }, - ] - } - query={ - Object { - "coverage": undefined, - "duplications": undefined, - "gate": undefined, - "languages": undefined, - "maintainability": undefined, - "new_coverage": undefined, - "new_duplications": undefined, - "new_lines": undefined, - "new_maintainability": undefined, - "new_reliability": undefined, - "new_security": undefined, - "new_security_review_rating": undefined, - "reliability": undefined, - "search": undefined, - "security": undefined, - "security_review_rating": undefined, - "size": undefined, - "sort": undefined, - "tags": undefined, - "view": undefined, - "visualization": undefined, - } - } - /> - <ListFooter - count={1} - loadMore={[Function]} - loading={false} - ready={true} - total={0} - /> - </div> - </div> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageSidebar-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageSidebar-test.tsx.snap index 8c607217185..ac6904b4bc7 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageSidebar-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PageSidebar-test.tsx.snap @@ -18,55 +18,42 @@ exports[`should render \`leak\` view correctly 1`] = ` </div> <QualityGateFilter onQueryChange={[MockFunction]} - query={ - Object { - "view": "leak", - } - } /> <NewReliabilityFilter onQueryChange={[MockFunction]} - query={ - Object { - "view": "leak", - } - } /> <NewSecurityFilter onQueryChange={[MockFunction]} - query={ - Object { - "view": "leak", - } - } /> <SecurityReviewFilter className="leak-facet-box" onQueryChange={[MockFunction]} property="new_security_review_rating" - query={ - Object { - "view": "leak", - } - } /> <NewMaintainabilityFilter onQueryChange={[MockFunction]} - query={ - Object { - "view": "leak", - } - } /> <NewCoverageFilter onQueryChange={[MockFunction]} + /> + <NewDuplicationsFilter + onQueryChange={[MockFunction]} + /> + <NewLinesFilter + onQueryChange={[MockFunction]} + /> + <Connect(LanguagesFilter) + onQueryChange={[MockFunction]} query={ Object { "view": "leak", } } /> - <NewDuplicationsFilter + <QualifierFilter + onQueryChange={[MockFunction]} + /> + <TagsFilter onQueryChange={[MockFunction]} query={ Object { @@ -74,14 +61,51 @@ exports[`should render \`leak\` view correctly 1`] = ` } } /> - <NewLinesFilter - onQueryChange={[MockFunction]} +</div> +`; + +exports[`should render \`leak\` view correctly with no applications 1`] = ` +<div> + <Connect(FavoriteFilter) query={ Object { "view": "leak", } } /> + <div + className="projects-facets-header clearfix" + > + <h3> + filters + </h3> + </div> + <QualityGateFilter + onQueryChange={[MockFunction]} + /> + <NewReliabilityFilter + onQueryChange={[MockFunction]} + /> + <NewSecurityFilter + onQueryChange={[MockFunction]} + /> + <SecurityReviewFilter + className="leak-facet-box" + onQueryChange={[MockFunction]} + property="new_security_review_rating" + /> + <NewMaintainabilityFilter + onQueryChange={[MockFunction]} + /> + <NewCoverageFilter + onQueryChange={[MockFunction]} + /> + <NewDuplicationsFilter + onQueryChange={[MockFunction]} + /> + <NewLinesFilter + onQueryChange={[MockFunction]} + /> <Connect(LanguagesFilter) onQueryChange={[MockFunction]} query={ @@ -116,67 +140,87 @@ exports[`should render correctly 1`] = ` </div> <QualityGateFilter onQueryChange={[MockFunction]} - query={ - Object { - "size": "3", - } - } /> <ReliabilityFilter onQueryChange={[MockFunction]} - query={ - Object { - "size": "3", - } - } /> <SecurityFilter onQueryChange={[MockFunction]} - query={ - Object { - "size": "3", - } - } /> <SecurityReviewFilter onQueryChange={[MockFunction]} - query={ - Object { - "size": "3", - } - } /> <MaintainabilityFilter onQueryChange={[MockFunction]} - query={ - Object { - "size": "3", - } - } /> <CoverageFilter onQueryChange={[MockFunction]} - query={ - Object { - "size": "3", - } - } /> <DuplicationsFilter onQueryChange={[MockFunction]} + /> + <SizeFilter + onQueryChange={[MockFunction]} + value="3" + /> + <Connect(LanguagesFilter) + onQueryChange={[MockFunction]} query={ Object { "size": "3", } } /> - <SizeFilter + <QualifierFilter + onQueryChange={[MockFunction]} + /> + <TagsFilter onQueryChange={[MockFunction]} query={ Object { "size": "3", } } + /> +</div> +`; + +exports[`should render correctly with no applications 1`] = ` +<div> + <Connect(FavoriteFilter) /> + <div + className="projects-facets-header clearfix" + > + <ClearAll + onClearAll={[MockFunction]} + /> + <h3> + filters + </h3> + </div> + <QualityGateFilter + onQueryChange={[MockFunction]} + /> + <ReliabilityFilter + onQueryChange={[MockFunction]} + /> + <SecurityFilter + onQueryChange={[MockFunction]} + /> + <SecurityReviewFilter + onQueryChange={[MockFunction]} + /> + <MaintainabilityFilter + onQueryChange={[MockFunction]} + /> + <CoverageFilter + onQueryChange={[MockFunction]} + /> + <DuplicationsFilter + onQueryChange={[MockFunction]} + /> + <SizeFilter + onQueryChange={[MockFunction]} value="3" /> <Connect(LanguagesFilter) 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 b3e6b4ac240..4f720583ce7 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 @@ -35,7 +35,6 @@ export interface Props { onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; property?: string; - query: T.Dict<any>; value?: any; } @@ -55,7 +54,6 @@ export default function CoverageFilter(props: Props) { options={[1, 2, 3, 4, 5, 6]} organization={props.organization} property={property} - query={props.query} renderOption={renderOption} value={props.value} /> 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 7b9875cfb14..673a0d5df2a 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 @@ -35,7 +35,6 @@ export interface Props { onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; property?: string; - query: T.Dict<any>; value?: any; } @@ -54,7 +53,6 @@ export default function DuplicationsFilter(props: Props) { options={[1, 2, 3, 4, 5, 6]} organization={props.organization} property={property} - query={props.query} renderOption={renderOption} value={props.value} /> 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 0c331e76bdd..a76a69d6ceb 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 @@ -30,7 +30,6 @@ interface Props { className?: string; onQueryChange: (change: T.RawQuery) => void; options: Option[]; - query: T.Dict<any>; renderOption: (option: Option, isSelected: boolean) => React.ReactNode; value?: Option | Option[]; 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 324541f8441..9ff16d6a5a6 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 @@ -33,7 +33,6 @@ interface Props { onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; property: string; - query: T.Dict<any>; value?: any; } @@ -53,7 +52,6 @@ export default function IssuesFilter(props: Props) { options={[1, 2, 3, 4, 5]} organization={props.organization} property={props.property} - query={props.query} 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 2c75faaa03a..1a6c9a3ec3a 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 @@ -79,7 +79,6 @@ export default class LanguagesFilter extends React.Component<Props> { options={this.getSortedOptions(this.props.facet)} organization={this.props.organization} property={property} - query={this.props.query} renderOption={this.renderOption} value={this.props.value} /> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.tsx index a1798e6e98c..7d95f9cf26f 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.tsx @@ -30,7 +30,6 @@ interface Props { maxFacetValue?: number; onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; - query: T.Dict<any>; value?: any; } 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 e760076cb0b..93bb00e69da 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 @@ -31,7 +31,6 @@ export interface Props { onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; property?: string; - query: T.Dict<any>; value?: any; } @@ -50,7 +49,6 @@ export default function NewLinesFilter(props: Props) { options={[1, 2, 3, 4, 5]} organization={props.organization} property={property} - query={props.query} renderOption={renderOption} value={props.value} /> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/NewMaintainabilityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/NewMaintainabilityFilter.tsx index cb326c2ff9f..ae1cf6cec6f 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/NewMaintainabilityFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/NewMaintainabilityFilter.tsx @@ -29,7 +29,6 @@ interface Props { maxFacetValue?: number; onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; - query: T.Dict<any>; value?: any; } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/NewReliabilityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/NewReliabilityFilter.tsx index 4000d2837da..d17247295e8 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/NewReliabilityFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/NewReliabilityFilter.tsx @@ -29,7 +29,6 @@ interface Props { maxFacetValue?: number; onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; - query: T.Dict<any>; value?: any; } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/NewSecurityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/NewSecurityFilter.tsx index 6c13f553e5e..1cc7f4a768e 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/NewSecurityFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/NewSecurityFilter.tsx @@ -29,7 +29,6 @@ interface Props { maxFacetValue?: number; onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; - query: T.Dict<any>; value?: any; } 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 new file mode 100644 index 00000000000..4a8ada5c833 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projects/filters/QualifierFilter.tsx @@ -0,0 +1,67 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; +import { translate } from 'sonar-ui-common/helpers/l10n'; +import { ComponentQualifier } from '../../../types/component'; +import { Facet } from '../types'; +import Filter from './Filter'; +import FilterHeader from './FilterHeader'; + +export interface QualifierFilterProps { + facet?: Facet; + maxFacetValue?: number; + onQueryChange: (change: T.RawQuery) => void; + organization?: { key: string }; + value: ComponentQualifier | undefined; +} + +const options = [ComponentQualifier.Project, ComponentQualifier.Application]; + +export default function QualifierFilter(props: QualifierFilterProps) { + const { facet, maxFacetValue, organization, value } = props; + + return ( + <Filter + facet={facet} + header={<FilterHeader name={translate('projects.facets.qualifier')} />} + maxFacetValue={maxFacetValue} + onQueryChange={props.onQueryChange} + options={options} + organization={organization} + property="qualifier" + renderOption={renderOption} + value={value} + /> + ); +} + +function renderOption(option: string, selected: boolean) { + return ( + <span className="display-flex-center"> + <QualifierIcon + className="spacer-right" + fill={selected ? undefined : 'currentColor'} + qualifier={option} + /> + {translate('qualifier', option)} + </span> + ); +} 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 2bee422e1e9..c93b7714e96 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 @@ -31,7 +31,6 @@ export interface Props { maxFacetValue?: number; onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; - query: T.Dict<any>; value?: any; } @@ -48,7 +47,6 @@ export default function QualityGateFilter(props: Props) { options={options} organization={props.organization} property="gate" - query={props.query} renderOption={renderOption} value={props.value} /> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.tsx index fae5e9cc80f..c77839c16ba 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.tsx @@ -30,7 +30,6 @@ interface Props { maxFacetValue?: number; onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; - query: T.Dict<any>; value?: any; } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.tsx index 0e771cdf8cd..308af85f589 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.tsx @@ -30,7 +30,6 @@ interface Props { maxFacetValue?: number; onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; - query: T.Dict<any>; value?: any; } 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 971f5f7a08e..df7a9ad7b39 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 @@ -32,7 +32,6 @@ export interface Props { onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; property?: string; - query: T.Dict<any>; value?: any; } @@ -53,14 +52,12 @@ export default function SecurityReviewFilter(props: Props) { facet={props.facet} header={ <FilterHeader name={translate('metric_domain.SecurityReview')}> - { - <span className="note little-spacer-left"> - {'( '} - <SecurityHotspotIcon className="little-spacer-right" /> - {translate('metric.security_hotspots.name')} - {' )'} - </span> - } + <span className="note little-spacer-left"> + {'( '} + <SecurityHotspotIcon className="little-spacer-right" /> + {translate('metric.security_hotspots.name')} + {' )'} + </span> </FilterHeader> } highlightUnder={1} @@ -69,7 +66,6 @@ export default function SecurityReviewFilter(props: Props) { options={[1, 2, 3, 4, 5]} organization={props.organization} property={property} - query={props.query} renderOption={renderOption} value={props.value} /> 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 386ceb7b995..235e6a81904 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 @@ -32,7 +32,6 @@ export interface Props { onQueryChange: (change: T.RawQuery) => void; organization?: { key: string }; property?: string; - query: T.Dict<any>; value?: any; } @@ -51,7 +50,6 @@ export default function SizeFilter(props: Props) { options={[1, 2, 3, 4, 5]} organization={props.organization} property={property} - query={props.query} renderOption={renderOption} value={props.value} /> 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 d31b017be9b..2fe20cbe45b 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 @@ -121,7 +121,6 @@ export default class TagsFilter extends React.PureComponent<Props, State> { options={this.getSortedOptions(this.props.facet)} organization={this.props.organization} property={property} - query={this.props.query} renderOption={this.renderOption} value={this.props.value} /> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/CoverageFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/CoverageFilter-test.tsx index e39cbd85d43..573c1e0d69f 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/CoverageFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/CoverageFilter-test.tsx @@ -22,7 +22,7 @@ import * as React from 'react'; import CoverageFilter from '../CoverageFilter'; it('renders', () => { - const wrapper = shallow(<CoverageFilter onQueryChange={jest.fn()} query={{}} />); + const wrapper = shallow(<CoverageFilter onQueryChange={jest.fn()} />); expect(wrapper).toMatchSnapshot(); const renderOption = wrapper.prop('renderOption'); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/DuplicationsFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/DuplicationsFilter-test.tsx index 5a72e02355a..c40816fd91a 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/DuplicationsFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/DuplicationsFilter-test.tsx @@ -22,7 +22,7 @@ import * as React from 'react'; import DuplicationsFilter from '../DuplicationsFilter'; it('renders', () => { - const wrapper = shallow(<DuplicationsFilter onQueryChange={jest.fn()} query={{}} />); + const wrapper = shallow(<DuplicationsFilter onQueryChange={jest.fn()} />); expect(wrapper).toMatchSnapshot(); const renderOption = wrapper.prop('renderOption'); 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 2d25b9691be..d95f494f863 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 @@ -60,15 +60,14 @@ it('renders facet bar chart', () => { ).toMatchSnapshot(); }); -function shallowRender(props?: any) { - return shallow( +function shallowRender(overrides: Partial<Filter['props']> = {}) { + return shallow<Filter>( <Filter onQueryChange={jest.fn()} options={[1, 2, 3]} property="foo" - query={{}} renderOption={option => option} - {...props} + {...overrides} /> ); } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/IssuesFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/IssuesFilter-test.tsx index 38608957ba3..6d3ccf1ad84 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/IssuesFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/IssuesFilter-test.tsx @@ -22,9 +22,7 @@ import * as React from 'react'; import IssuesFilter from '../IssuesFilter'; it('renders', () => { - const wrapper = shallow( - <IssuesFilter name="bugs" onQueryChange={jest.fn()} property="bugs" query={{}} /> - ); + const wrapper = shallow(<IssuesFilter name="bugs" onQueryChange={jest.fn()} property="bugs" />); expect(wrapper).toMatchSnapshot(); const renderOption = wrapper.prop('renderOption'); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/MaintainabilityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/MaintainabilityFilter-test.tsx index dc4c182f99b..1d5c8a0d3f0 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/MaintainabilityFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/MaintainabilityFilter-test.tsx @@ -22,5 +22,5 @@ import * as React from 'react'; import MaintainabilityFilter from '../MaintainabilityFilter'; it('renders', () => { - expect(shallow(<MaintainabilityFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot(); + expect(shallow(<MaintainabilityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewCoverageFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewCoverageFilter-test.tsx index 811300cb54d..d23c0d049bf 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewCoverageFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewCoverageFilter-test.tsx @@ -22,5 +22,5 @@ import * as React from 'react'; import NewCoverageFilter from '../NewCoverageFilter'; it('renders', () => { - expect(shallow(<NewCoverageFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot(); + expect(shallow(<NewCoverageFilter onQueryChange={jest.fn()} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewDuplicationsFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewDuplicationsFilter-test.tsx index bca7edaf6aa..7e3f9c456eb 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewDuplicationsFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewDuplicationsFilter-test.tsx @@ -22,5 +22,5 @@ import * as React from 'react'; import NewDuplicationsFilter from '../NewDuplicationsFilter'; it('renders', () => { - expect(shallow(<NewDuplicationsFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot(); + expect(shallow(<NewDuplicationsFilter onQueryChange={jest.fn()} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewLinesFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewLinesFilter-test.tsx index f6b78344090..1afeb0dfe50 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewLinesFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewLinesFilter-test.tsx @@ -22,7 +22,7 @@ import * as React from 'react'; import NewLinesFilter from '../NewLinesFilter'; it('renders', () => { - const wrapper = shallow(<NewLinesFilter onQueryChange={jest.fn()} query={{}} />); + const wrapper = shallow(<NewLinesFilter onQueryChange={jest.fn()} />); expect(wrapper).toMatchSnapshot(); const renderOption = wrapper.prop('renderOption'); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewMaintainabilityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewMaintainabilityFilter-test.tsx index fb8474f0a02..e93f0e37abd 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewMaintainabilityFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewMaintainabilityFilter-test.tsx @@ -22,7 +22,5 @@ import * as React from 'react'; import NewMaintainabilityFilter from '../NewMaintainabilityFilter'; it('renders', () => { - expect( - shallow(<NewMaintainabilityFilter onQueryChange={jest.fn()} query={{}} />) - ).toMatchSnapshot(); + expect(shallow(<NewMaintainabilityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewReliabilityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewReliabilityFilter-test.tsx index 8ceb711739f..c415d02831a 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewReliabilityFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewReliabilityFilter-test.tsx @@ -22,5 +22,5 @@ import * as React from 'react'; import NewReliabilityFilter from '../NewReliabilityFilter'; it('renders', () => { - expect(shallow(<NewReliabilityFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot(); + expect(shallow(<NewReliabilityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewSecurityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewSecurityFilter-test.tsx index 99bb0d94389..08fce4a26bf 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewSecurityFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/NewSecurityFilter-test.tsx @@ -22,5 +22,5 @@ import * as React from 'react'; import NewSecurityFilter from '../NewSecurityFilter'; it('renders', () => { - expect(shallow(<NewSecurityFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot(); + expect(shallow(<NewSecurityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualifierFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualifierFilter-test.tsx new file mode 100644 index 00000000000..b0797968910 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualifierFilter-test.tsx @@ -0,0 +1,38 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * 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 * as React from 'react'; +import { ComponentQualifier } from '../../../../types/component'; +import Filter from '../Filter'; +import QualifierFilter, { QualifierFilterProps } from '../QualifierFilter'; + +it('renders', () => { + const wrapper = shallowRender(); + expect(wrapper).toMatchSnapshot(); + + const { renderOption } = wrapper.find(Filter).props(); + expect(renderOption(ComponentQualifier.Application, false)).toMatchSnapshot( + 'renderOption result' + ); +}); + +function shallowRender(props: Partial<QualifierFilterProps> = {}) { + return shallow(<QualifierFilter onQueryChange={jest.fn()} value={undefined} {...props} />); +} diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualityGateFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualityGateFilter-test.tsx index 756a3eac786..6ff157649a1 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualityGateFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/QualityGateFilter-test.tsx @@ -38,5 +38,5 @@ it('should render with warning facet', () => { }); function shallowRender(props: Partial<Props> = {}) { - return shallow(<QualityGateFilter onQueryChange={jest.fn()} query={{}} {...props} />); + return shallow(<QualityGateFilter onQueryChange={jest.fn()} {...props} />); } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/ReliabilityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/ReliabilityFilter-test.tsx index 8232d5cb3b5..005e070025e 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/ReliabilityFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/ReliabilityFilter-test.tsx @@ -22,5 +22,5 @@ import * as React from 'react'; import ReliabilityFilter from '../ReliabilityFilter'; it('renders', () => { - expect(shallow(<ReliabilityFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot(); + expect(shallow(<ReliabilityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityFilter-test.tsx index 56f7d0e9915..387a7ba895f 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityFilter-test.tsx @@ -22,5 +22,5 @@ import * as React from 'react'; import SecurityFilter from '../SecurityFilter'; it('renders', () => { - expect(shallow(<SecurityFilter onQueryChange={jest.fn()} query={{}} />)).toMatchSnapshot(); + expect(shallow(<SecurityFilter onQueryChange={jest.fn()} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityReviewFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityReviewFilter-test.tsx index ecd7cc0995d..568c522000a 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityReviewFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SecurityReviewFilter-test.tsx @@ -22,7 +22,7 @@ import * as React from 'react'; import SecurityReviewFilter from '../SecurityReviewFilter'; it('renders', () => { - const wrapper = shallow(<SecurityReviewFilter onQueryChange={jest.fn()} query={{}} />); + const wrapper = shallow(<SecurityReviewFilter onQueryChange={jest.fn()} />); expect(wrapper).toMatchSnapshot(); const renderOption = wrapper.prop('renderOption'); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SizeFilter-test.tsx b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SizeFilter-test.tsx index 37b42810cd8..c7462eb6d63 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SizeFilter-test.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SizeFilter-test.tsx @@ -22,7 +22,7 @@ import * as React from 'react'; import SizeFilter from '../SizeFilter'; it('renders', () => { - const wrapper = shallow(<SizeFilter onQueryChange={jest.fn()} query={{}} />); + const wrapper = shallow(<SizeFilter onQueryChange={jest.fn()} />); expect(wrapper).toMatchSnapshot(); const renderOption = wrapper.prop('renderOption'); 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 9ce9bc4f614..9c45a22ef8e 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,7 +22,6 @@ exports[`renders 1`] = ` ] } property="coverage" - query={Object {}} 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 2c3c409178a..a0c1acb0b3c 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,7 +22,6 @@ exports[`renders 1`] = ` ] } property="duplications" - query={Object {}} renderOption={[Function]} /> `; 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 25be3053bcd..518429562a1 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,7 +19,6 @@ exports[`renders 1`] = ` ] } property="bugs" - query={Object {}} 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 250afc75ced..c366f8e6858 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,14 +53,6 @@ exports[`should render the languages facet with the selected languages 1`] = ` ] } property="languages" - query={ - Object { - "languages": Array [ - "java", - "cs", - ], - } - } renderOption={[Function]} value={ Array [ @@ -242,11 +234,6 @@ exports[`should render the languages without the ones in the facet 1`] = ` ] } property="languages" - query={ - Object { - "languages": null, - } - } renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/MaintainabilityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/MaintainabilityFilter-test.tsx.snap index 5a3cec2fbff..74c863bc426 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/MaintainabilityFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/MaintainabilityFilter-test.tsx.snap @@ -17,6 +17,5 @@ exports[`renders 1`] = ` name="Maintainability" onQueryChange={[MockFunction]} property="maintainability" - query={Object {}} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewCoverageFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewCoverageFilter-test.tsx.snap index 11e95aab04c..893586a9cfc 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewCoverageFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewCoverageFilter-test.tsx.snap @@ -5,6 +5,5 @@ exports[`renders 1`] = ` className="leak-facet-box" onQueryChange={[MockFunction]} property="new_coverage" - query={Object {}} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewDuplicationsFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewDuplicationsFilter-test.tsx.snap index 91a1620bb86..4fce695bb25 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewDuplicationsFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewDuplicationsFilter-test.tsx.snap @@ -5,6 +5,5 @@ exports[`renders 1`] = ` className="leak-facet-box" onQueryChange={[MockFunction]} property="new_duplications" - query={Object {}} /> `; 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 1f04f9c5073..6d4b91aa8b8 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,7 +21,6 @@ exports[`renders 1`] = ` ] } property="new_lines" - query={Object {}} renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewMaintainabilityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewMaintainabilityFilter-test.tsx.snap index ff717a23c48..aee66f09413 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewMaintainabilityFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewMaintainabilityFilter-test.tsx.snap @@ -18,6 +18,5 @@ exports[`renders 1`] = ` name="Maintainability" onQueryChange={[MockFunction]} property="new_maintainability" - query={Object {}} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewReliabilityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewReliabilityFilter-test.tsx.snap index 33bac4a52fe..c2a1184a792 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewReliabilityFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewReliabilityFilter-test.tsx.snap @@ -18,6 +18,5 @@ exports[`renders 1`] = ` name="Reliability" onQueryChange={[MockFunction]} property="new_reliability" - query={Object {}} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewSecurityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewSecurityFilter-test.tsx.snap index 9c14c735545..ff165f6d2c7 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewSecurityFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/NewSecurityFilter-test.tsx.snap @@ -18,6 +18,5 @@ exports[`renders 1`] = ` name="Security" onQueryChange={[MockFunction]} property="new_security" - query={Object {}} /> `; 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 new file mode 100644 index 00000000000..78a419e37a4 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/QualifierFilter-test.tsx.snap @@ -0,0 +1,33 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders 1`] = ` +<Filter + header={ + <FilterHeader + name="projects.facets.qualifier" + /> + } + onQueryChange={[MockFunction]} + options={ + Array [ + "TRK", + "APP", + ] + } + property="qualifier" + renderOption={[Function]} +/> +`; + +exports[`renders: renderOption result 1`] = ` +<span + className="display-flex-center" +> + <QualifierIcon + className="spacer-right" + fill="currentColor" + qualifier="APP" + /> + qualifier.APP +</span> +`; 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 646483a9a19..f886d4bf11d 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,7 +15,6 @@ exports[`renders 1`] = ` ] } property="gate" - query={Object {}} renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/ReliabilityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/ReliabilityFilter-test.tsx.snap index db4d08b6663..355fccc7ef6 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/ReliabilityFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/ReliabilityFilter-test.tsx.snap @@ -17,6 +17,5 @@ exports[`renders 1`] = ` name="Reliability" onQueryChange={[MockFunction]} property="reliability" - query={Object {}} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityFilter-test.tsx.snap b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityFilter-test.tsx.snap index b2fe4443191..9039e7ab671 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityFilter-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/__snapshots__/SecurityFilter-test.tsx.snap @@ -17,6 +17,5 @@ exports[`renders 1`] = ` name="Security" onQueryChange={[MockFunction]} property="security" - query={Object {}} /> `; 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 1ca6b42af8d..d035ae827e5 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,7 +30,6 @@ exports[`renders 1`] = ` ] } property="security_review" - query={Object {}} 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 f956104ccb9..a950d21b0d1 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,7 +20,6 @@ exports[`renders 1`] = ` ] } property="size" - query={Object {}} 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 39ca1365278..8c1830ec284 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,14 +86,6 @@ exports[`should render maximum 10 tags in the searchbox results 1`] = ` ] } property="tags" - query={ - Object { - "languages": Array [ - "java", - "ad", - ], - } - } renderOption={[Function]} value={ Array [ @@ -145,14 +137,6 @@ exports[`should render the tags facet with the selected tags 1`] = ` ] } property="tags" - query={ - Object { - "tags": Array [ - "lang", - "sonar", - ], - } - } renderOption={[Function]} value={ Array [ @@ -292,11 +276,6 @@ exports[`should render the tags without the ones in the facet 1`] = ` ] } property="tags" - query={ - Object { - "tags": null, - } - } renderOption={[Function]} /> `; @@ -354,11 +333,6 @@ exports[`should render the tags without the ones in the facet 2`] = ` ] } property="tags" - query={ - Object { - "tags": null, - } - } renderOption={[Function]} /> `; diff --git a/server/sonar-web/src/main/js/apps/projects/query.ts b/server/sonar-web/src/main/js/apps/projects/query.ts index e40e9c9af0c..727ca3439d2 100644 --- a/server/sonar-web/src/main/js/apps/projects/query.ts +++ b/server/sonar-web/src/main/js/apps/projects/query.ts @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { ComponentQualifier } from '../../types/component'; import { VISUALIZATIONS } from './utils'; type Level = 'ERROR' | 'WARN' | 'OK'; @@ -38,6 +39,7 @@ export interface Query { size?: number; new_lines?: number; languages?: string[]; + qualifier?: ComponentQualifier; tags?: string[]; search?: string; sort?: string; @@ -65,6 +67,7 @@ export function parseUrlQuery(urlQuery: T.RawQuery): Query { new_lines: getAsNumericRating(urlQuery['new_lines']), languages: getAsStringArray(urlQuery['languages']), tags: getAsStringArray(urlQuery['tags']), + qualifier: getAsQualifier(urlQuery['qualifier']), search: getAsString(urlQuery['search']), sort: getAsString(urlQuery['sort']), view: getView(urlQuery['view']), @@ -106,7 +109,7 @@ export function convertToFilter(query: Query, isFavorite: boolean): string { 'new_maintainability' ].forEach(property => pushMetricToArray(query, property, conditions, convertIssuesRating)); - ['languages', 'tags'].forEach(property => + ['languages', 'tags', 'qualifier'].forEach(property => pushMetricToArray(query, property, conditions, convertArrayMetric) ); @@ -160,6 +163,10 @@ function getAsStringArray(value: any): string[] | undefined { return value.split(','); } +function getAsQualifier(value: string | undefined): ComponentQualifier | undefined { + return value ? (value as ComponentQualifier) : undefined; +} + function getView(value: any): string | undefined { return typeof value !== 'string' || value === 'overall' ? undefined : value; } @@ -251,7 +258,8 @@ function mapPropertyToMetric(property?: string): string | undefined { gate: 'alert_status', languages: 'languages', tags: 'tags', - search: 'query' + search: 'query', + qualifier: 'qualifier' }; return property && map[property]; } diff --git a/server/sonar-web/src/main/js/apps/projects/utils.ts b/server/sonar-web/src/main/js/apps/projects/utils.ts index 445c5119601..753a9c457d0 100644 --- a/server/sonar-web/src/main/js/apps/projects/utils.ts +++ b/server/sonar-web/src/main/js/apps/projects/utils.ts @@ -166,7 +166,8 @@ export const FACETS = [ 'ncloc', 'alert_status', 'languages', - 'tags' + 'tags', + 'qualifier' ]; export const LEAK_FACETS = [ @@ -179,7 +180,8 @@ export const LEAK_FACETS = [ 'new_lines', 'alert_status', 'languages', - 'tags' + 'tags', + 'qualifier' ]; const REVERSED_FACETS = ['coverage', 'new_coverage']; @@ -333,7 +335,8 @@ const propertyToMetricMap: T.Dict<string | undefined> = { gate: 'alert_status', languages: 'languages', tags: 'tags', - search: 'query' + search: 'query', + qualifier: 'qualifier' }; const metricToPropertyMap = invert(propertyToMetricMap); |