diff options
author | Philippe Perrin <philippe.perrin@sonarsource.com> | 2019-10-02 18:39:32 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2019-10-07 20:21:05 +0200 |
commit | daf5a60dd259039b97fd3598f894169d7ecc74e5 (patch) | |
tree | 29cf6b11a2d998f0c4bf4fac6d740407d79de78e | |
parent | dfe6b9e39a63507bba9900f5a68565ca82f3627f (diff) | |
download | sonarqube-daf5a60dd259039b97fd3598f894169d7ecc74e5.tar.gz sonarqube-daf5a60dd259039b97fd3598f894169d7ecc74e5.zip |
SONAR-8884 Group languages related settings in a single Languages tab
14 files changed, 559 insertions, 39 deletions
diff --git a/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx b/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx new file mode 100644 index 00000000000..4a4e634c2ee --- /dev/null +++ b/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx @@ -0,0 +1,61 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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 { translate } from 'sonar-ui-common/helpers/l10n'; +import { LANGUAGES_CATEGORY, NEW_CODE_PERIOD_CATEGORY } from './AdditionalCategoryKeys'; +import Languages from './Languages'; +import NewCodePeriod from './NewCodePeriod'; + +export interface AdditionalCategory { + key: string; + name: string; + renderComponent: ( + parentComponent: T.Component | undefined, + selectedCategory: string + ) => JSX.Element; + availableGlobally: boolean; + availableForProject: boolean; +} + +export const ADDITIONAL_CATEGORIES: AdditionalCategory[] = [ + { + key: LANGUAGES_CATEGORY, + name: translate('property.category.languages'), + renderComponent: getLanguagesComponent, + availableGlobally: true, + availableForProject: true + }, + { + key: NEW_CODE_PERIOD_CATEGORY, + name: translate('settings.new_code_period.category'), + renderComponent: getNewCodePeriodComponent, + availableGlobally: true, + availableForProject: false + } +]; + +function getLanguagesComponent(component: any, originalCategory: string) { + return <Languages component={component} selectedCategory={originalCategory} />; +} + +function getNewCodePeriodComponent() { + return <NewCodePeriod />; +} diff --git a/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategoryKeys.ts b/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategoryKeys.ts new file mode 100644 index 00000000000..a1ef533670a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategoryKeys.ts @@ -0,0 +1,22 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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. + */ + +export const LANGUAGES_CATEGORY = 'languages'; +export const NEW_CODE_PERIOD_CATEGORY = 'new_code_period'; diff --git a/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx b/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx index 02cedc53b09..29e22177b69 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx @@ -22,27 +22,24 @@ import { sortBy } from 'lodash'; import * as React from 'react'; import { connect } from 'react-redux'; import { IndexLink } from 'react-router'; -import { translate } from 'sonar-ui-common/helpers/l10n'; import { getSettingsAppAllCategories, Store } from '../../../store/rootReducer'; import { getCategoryName } from '../utils'; +import { ADDITIONAL_CATEGORIES } from './AdditionalCategories'; +import { CATEGORY_OVERRIDES } from './CategoryOverrides'; interface Category { key: string; name: string; } -interface Props { +export interface CategoriesListProps { categories: string[]; component?: T.Component; defaultCategory: string; selectedCategory: string; } -const FIXED_CATEGORIES = [ - { key: 'new_code_period', name: translate('settings.new_code_period.category') } -]; - -export class CategoriesList extends React.PureComponent<Props> { +export class CategoriesList extends React.PureComponent<CategoriesListProps> { renderLink(category: Category) { const { component, defaultCategory, selectedCategory } = this.props; const pathname = this.props.component ? '/project/settings' : '/settings'; @@ -64,11 +61,18 @@ export class CategoriesList extends React.PureComponent<Props> { render() { const categoriesWithName = this.props.categories + .filter(key => !CATEGORY_OVERRIDES[key.toLowerCase()]) .map(key => ({ key, name: getCategoryName(key) })) - .concat(!this.props.component ? FIXED_CATEGORIES : []); + .concat( + this.props.component + ? // Project settings + ADDITIONAL_CATEGORIES.filter(c => c.availableForProject) + : // Global settings + ADDITIONAL_CATEGORIES.filter(c => c.availableGlobally) + ); const sortedCategories = sortBy(categoriesWithName, category => category.name.toLowerCase()); return ( <ul className="side-tabs-menu"> diff --git a/server/sonar-web/src/main/js/apps/settings/components/AppContainer.tsx b/server/sonar-web/src/main/js/apps/settings/components/AppContainer.tsx index 3a2d3a956da..0880ce8edff 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/AppContainer.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/AppContainer.tsx @@ -17,6 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +import { find } from 'lodash'; import * as React from 'react'; import Helmet from 'react-helmet'; import { connect } from 'react-redux'; @@ -27,9 +29,10 @@ import { getSettingsAppDefaultCategory, Store } from '../../../store/rootReducer import '../side-tabs.css'; import { fetchSettings } from '../store/actions'; import '../styles.css'; +import { ADDITIONAL_CATEGORIES } from './AdditionalCategories'; import AllCategoriesList from './AllCategoriesList'; import CategoryDefinitionsList from './CategoryDefinitionsList'; -import NewCodePeriod from './NewCodePeriod'; +import { CATEGORY_OVERRIDES } from './CategoryOverrides'; import PageHeader from './PageHeader'; import WildcardsHelp from './WildcardsHelp'; @@ -79,7 +82,16 @@ export class App extends React.PureComponent<Props & WithRouterProps, State> { } const { query } = this.props.location; - const selectedCategory = query.category || this.props.defaultCategory; + + const originalCategory = (query.category as string) || this.props.defaultCategory; + const overriddenCategory = CATEGORY_OVERRIDES[originalCategory.toLowerCase()]; + const selectedCategory = overriddenCategory || originalCategory; + const foundAdditionalCategory = find(ADDITIONAL_CATEGORIES, c => c.key === selectedCategory); + const isProjectSettings = this.props.component; + const shouldRenderAdditionalCategory = + foundAdditionalCategory && + ((isProjectSettings && foundAdditionalCategory.availableForProject) || + (!isProjectSettings && foundAdditionalCategory.availableGlobally)); return ( <div className="page page-limited" id="settings-page"> @@ -97,8 +109,8 @@ export class App extends React.PureComponent<Props & WithRouterProps, State> { /> </div> <div className="side-tabs-main"> - {!this.props.component && selectedCategory === 'new_code_period' ? ( - <NewCodePeriod /> + {foundAdditionalCategory && shouldRenderAdditionalCategory ? ( + foundAdditionalCategory.renderComponent(this.props.component, originalCategory) ) : ( <CategoryDefinitionsList category={selectedCategory} diff --git a/server/sonar-web/src/main/js/apps/settings/components/CategoryOverrides.ts b/server/sonar-web/src/main/js/apps/settings/components/CategoryOverrides.ts new file mode 100644 index 00000000000..df960088334 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/settings/components/CategoryOverrides.ts @@ -0,0 +1,49 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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 { LANGUAGES_CATEGORY } from './AdditionalCategoryKeys'; + +export const CATEGORY_OVERRIDES: T.Dict<string> = { + abap: LANGUAGES_CATEGORY, + apex: LANGUAGES_CATEGORY, + 'c / c++ / objective-c': LANGUAGES_CATEGORY, + 'c#': LANGUAGES_CATEGORY, + cobol: LANGUAGES_CATEGORY, + css: LANGUAGES_CATEGORY, + flex: LANGUAGES_CATEGORY, + go: LANGUAGES_CATEGORY, + html: LANGUAGES_CATEGORY, + java: LANGUAGES_CATEGORY, + javascript: LANGUAGES_CATEGORY, + kotlin: LANGUAGES_CATEGORY, + php: LANGUAGES_CATEGORY, + 'pl/i': LANGUAGES_CATEGORY, + 'pl/sql': LANGUAGES_CATEGORY, + python: LANGUAGES_CATEGORY, + rpg: LANGUAGES_CATEGORY, + ruby: LANGUAGES_CATEGORY, + scala: LANGUAGES_CATEGORY, + swift: LANGUAGES_CATEGORY, + 't-sql': LANGUAGES_CATEGORY, + typescript: LANGUAGES_CATEGORY, + 'vb.net': LANGUAGES_CATEGORY, + 'visual basic': LANGUAGES_CATEGORY, + xml: LANGUAGES_CATEGORY +}; diff --git a/server/sonar-web/src/main/js/apps/settings/components/Languages.tsx b/server/sonar-web/src/main/js/apps/settings/components/Languages.tsx new file mode 100644 index 00000000000..35a88f9280a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/settings/components/Languages.tsx @@ -0,0 +1,130 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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 { connect } from 'react-redux'; +import Select from 'sonar-ui-common/components/controls/Select'; +import { translate } from 'sonar-ui-common/helpers/l10n'; +import { Location, Router, withRouter } from '../../../components/hoc/withRouter'; +import { getSettingsAppAllCategories, Store } from '../../../store/rootReducer'; +import { getCategoryName } from '../utils'; +import { LANGUAGES_CATEGORY } from './AdditionalCategoryKeys'; +import CategoryDefinitionsList from './CategoryDefinitionsList'; +import { CATEGORY_OVERRIDES } from './CategoryOverrides'; + +export interface LanguagesProps { + categories: string[]; + component?: T.Component; + location: Location; + selectedCategory: string; + router: Router; +} + +interface LanguagesState { + availableLanguages: SelectOption[]; + selectedLanguage: string | undefined; +} + +interface SelectOption { + label: string; + originalValue: string; + value: string; +} + +export class Languages extends React.PureComponent<LanguagesProps, LanguagesState> { + constructor(props: LanguagesProps) { + super(props); + + this.state = { + availableLanguages: [], + selectedLanguage: undefined + }; + } + + componentDidMount() { + const { selectedCategory, categories } = this.props; + const lowerCasedLanguagesCategory = LANGUAGES_CATEGORY.toLowerCase(); + const lowerCasedSelectedCategory = selectedCategory.toLowerCase(); + + const availableLanguages = categories + .filter(c => CATEGORY_OVERRIDES[c.toLowerCase()] === lowerCasedLanguagesCategory) + .map(c => ({ + label: getCategoryName(c), + value: c.toLowerCase(), + originalValue: c + })); + + let selectedLanguage = undefined; + + if ( + lowerCasedSelectedCategory !== lowerCasedLanguagesCategory && + availableLanguages.find(c => c.value === lowerCasedSelectedCategory) + ) { + selectedLanguage = lowerCasedSelectedCategory; + } + + this.setState({ + availableLanguages, + selectedLanguage + }); + } + + handleOnChange = (newOption: SelectOption) => { + this.setState({ selectedLanguage: newOption.value }); + + const { location, router } = this.props; + + router.push({ + ...location, + query: { ...location.query, category: newOption.originalValue } + }); + }; + + render() { + const { component } = this.props; + const { availableLanguages, selectedLanguage } = this.state; + + return ( + <> + <h2 className="settings-sub-category-name">{translate('property.category.languages')}</h2> + <div data-test="language-select"> + <Select + className="input-large" + onChange={this.handleOnChange} + options={availableLanguages} + placeholder={translate('settings.languages.select_a_language_placeholder')} + value={selectedLanguage} + /> + </div> + {selectedLanguage && ( + <div className="settings-sub-category"> + <CategoryDefinitionsList category={selectedLanguage} component={component} /> + </div> + )} + </> + ); + } +} + +export default withRouter( + connect((state: Store) => ({ + categories: getSettingsAppAllCategories(state) + }))(Languages) +); diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/AllCategoriesList-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/__tests__/AllCategoriesList-test.tsx index 699ee214aab..9bbdb156d93 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/AllCategoriesList-test.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/AllCategoriesList-test.tsx @@ -19,16 +19,46 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { CategoriesList } from '../AllCategoriesList'; +import { mockComponent } from '../../../../helpers/testMocks'; +import { AdditionalCategory } from '../AdditionalCategories'; +import { CategoriesList, CategoriesListProps } from '../AllCategoriesList'; -it('should render correctly', () => { - const wrapper = shallowRender(); - expect(wrapper).toMatchSnapshot(); - expect(wrapper.find('li')).toHaveLength(3); +jest.mock('../AdditionalCategories', () => ({ + ADDITIONAL_CATEGORIES: [ + { + key: 'CAT_1', + name: 'CAT_1_NAME', + renderComponent: jest.fn(), + availableGlobally: true, + availableForProject: true + }, + { + key: 'CAT_2', + name: 'CAT_2_NAME', + renderComponent: jest.fn(), + availableGlobally: true, + availableForProject: false + }, + { + key: 'CAT_3', + name: 'CAT_3_NAME', + renderComponent: jest.fn(), + availableGlobally: false, + availableForProject: true + } + ] as AdditionalCategory[] +})); + +it('should render correctly in global mode', () => { + expect(shallowRender()).toMatchSnapshot(); +}); + +it('should render correctly in project mode', () => { + expect(shallowRender({ component: mockComponent() })).toMatchSnapshot(); }); -function shallowRender(props: Partial<CategoriesList['props']> = {}) { - const categories = ['COBOL', 'general']; +function shallowRender(props?: Partial<CategoriesListProps>) { + const categories = ['general']; return shallow( <CategoriesList diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/AppContainer-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/__tests__/AppContainer-test.tsx index 65bbcb4824e..46e41ab1b67 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/AppContainer-test.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/AppContainer-test.tsx @@ -19,8 +19,9 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { App } from '../AppContainer'; import { mockLocation, mockRouter } from '../../../../helpers/testMocks'; +import { LANGUAGES_CATEGORY, NEW_CODE_PERIOD_CATEGORY } from '../AdditionalCategoryKeys'; +import { App } from '../AppContainer'; it('should render correctly', () => { const wrapper = shallowRender(); @@ -29,7 +30,14 @@ it('should render correctly', () => { it('should render newCodePeriod correctly', () => { const wrapper = shallowRender({ - location: mockLocation({ query: { category: 'new_code_period' } }) + location: mockLocation({ query: { category: NEW_CODE_PERIOD_CATEGORY } }) + }); + expect(wrapper).toMatchSnapshot(); +}); + +it('should render languages correctly', () => { + const wrapper = shallowRender({ + location: mockLocation({ query: { category: LANGUAGES_CATEGORY } }) }); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/Languages-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/__tests__/Languages-test.tsx new file mode 100644 index 00000000000..1ab345b09e9 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/Languages-test.tsx @@ -0,0 +1,56 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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 { mockLocation, mockRouter } from '../../../../helpers/testMocks'; +import { Languages, LanguagesProps } from '../Languages'; + +it('should render correctly', () => { + const wrapper = shallowRender(); + expect(wrapper).toMatchSnapshot(); +}); + +it('should render correctly with an unknow language', () => { + const wrapper = shallowRender({ selectedCategory: 'unknown' }); + expect(wrapper).toMatchSnapshot(); +}); + +it('should correctly handle a change of the selected language', () => { + const push = jest.fn(); + const router = mockRouter({ push }); + const wrapper = shallowRender({ router }); + expect(wrapper.state().selectedLanguage).toBe('java'); + + wrapper.instance().handleOnChange({ label: '', originalValue: 'CoBoL', value: 'cobol' }); + expect(wrapper.state().selectedLanguage).toBe('cobol'); + expect(push).toHaveBeenCalledWith(expect.objectContaining({ query: { category: 'CoBoL' } })); +}); + +function shallowRender(props: Partial<LanguagesProps> = {}) { + return shallow<Languages>( + <Languages + categories={['Java', 'JavaScript', 'COBOL']} + location={mockLocation()} + router={mockRouter()} + selectedCategory="java" + {...props} + /> + ); +} diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap index 88899f05465..d2529468bd1 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AllCategoriesList-test.tsx.snap @@ -1,26 +1,45 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should render correctly 1`] = ` +exports[`should render correctly in global mode 1`] = ` <ul className="side-tabs-menu" > <li - key="COBOL" + key="CAT_1" > <IndexLink className="" - title="COBOL" + title="CAT_1_NAME" to={ Object { "pathname": "/settings", "query": Object { - "category": "cobol", + "category": "cat_1", "id": undefined, }, } } > - COBOL + CAT_1_NAME + </IndexLink> + </li> + <li + key="CAT_2" + > + <IndexLink + className="" + title="CAT_2_NAME" + to={ + Object { + "pathname": "/settings", + "query": Object { + "category": "cat_2", + "id": undefined, + }, + } + } + > + CAT_2_NAME </IndexLink> </li> <li @@ -42,23 +61,68 @@ exports[`should render correctly 1`] = ` general </IndexLink> </li> +</ul> +`; + +exports[`should render correctly in project mode 1`] = ` +<ul + className="side-tabs-menu" +> <li - key="new_code_period" + key="CAT_1" > <IndexLink className="" - title="settings.new_code_period.category" + title="CAT_1_NAME" to={ Object { - "pathname": "/settings", + "pathname": "/project/settings", "query": Object { - "category": "new_code_period", - "id": undefined, + "category": "cat_1", + "id": "my-project", }, } } > - settings.new_code_period.category + CAT_1_NAME + </IndexLink> + </li> + <li + key="CAT_3" + > + <IndexLink + className="" + title="CAT_3_NAME" + to={ + Object { + "pathname": "/project/settings", + "query": Object { + "category": "cat_3", + "id": "my-project", + }, + } + } + > + CAT_3_NAME + </IndexLink> + </li> + <li + key="general" + > + <IndexLink + className="" + title="general" + to={ + Object { + "pathname": "/project/settings", + "query": Object { + "category": undefined, + "id": "my-project", + }, + } + } + > + general </IndexLink> </li> </ul> diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AppContainer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AppContainer-test.tsx.snap index 1c4a7ae75b8..2f43729d145 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AppContainer-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/AppContainer-test.tsx.snap @@ -2,4 +2,6 @@ exports[`should render correctly 1`] = `""`; +exports[`should render languages correctly 1`] = `""`; + exports[`should render newCodePeriod correctly 1`] = `""`; diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap new file mode 100644 index 00000000000..b351829d1cc --- /dev/null +++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/Languages-test.tsx.snap @@ -0,0 +1,85 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` +<Fragment> + <h2 + className="settings-sub-category-name" + > + property.category.languages + </h2> + <div + data-test="language-select" + > + <Select + className="input-large" + onChange={[Function]} + options={ + Array [ + Object { + "label": "Java", + "originalValue": "Java", + "value": "java", + }, + Object { + "label": "JavaScript", + "originalValue": "JavaScript", + "value": "javascript", + }, + Object { + "label": "COBOL", + "originalValue": "COBOL", + "value": "cobol", + }, + ] + } + placeholder="settings.languages.select_a_language_placeholder" + value="java" + /> + </div> + <div + className="settings-sub-category" + > + <Connect(SubCategoryDefinitionsList) + category="java" + /> + </div> +</Fragment> +`; + +exports[`should render correctly with an unknow language 1`] = ` +<Fragment> + <h2 + className="settings-sub-category-name" + > + property.category.languages + </h2> + <div + data-test="language-select" + > + <Select + className="input-large" + onChange={[Function]} + options={ + Array [ + Object { + "label": "Java", + "originalValue": "Java", + "value": "java", + }, + Object { + "label": "JavaScript", + "originalValue": "JavaScript", + "value": "javascript", + }, + Object { + "label": "COBOL", + "originalValue": "COBOL", + "value": "cobol", + }, + ] + } + placeholder="settings.languages.select_a_language_placeholder" + /> + </div> +</Fragment> +`; diff --git a/server/sonar-web/src/main/js/apps/settings/styles.css b/server/sonar-web/src/main/js/apps/settings/styles.css index bdbca6a2ad7..37198351c10 100644 --- a/server/sonar-web/src/main/js/apps/settings/styles.css +++ b/server/sonar-web/src/main/js/apps/settings/styles.css @@ -82,13 +82,8 @@ border-top: 1px dotted var(--barBorderColor); } -.settings-sub-categories-list { -} - -.settings-sub-categories-list > li { -} - -.settings-sub-categories-list > li + li { +.settings-sub-categories-list > li + li, +.settings-sub-category { margin: 30px -20px 0; padding: 30px 20px; border-top: 1px solid var(--barBorderColor); 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 707315c440f..105b7be3c1c 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -920,6 +920,7 @@ settings.new_code_period.title=Default New Code Period behavior settings.new_code_period.description=The New Code Period is the period used to compare measures and track new issues. {link} settings.new_code_period.description2=This setting is the default for all projects. A specific New Code Period setting can be configured at project level. +settings.languages.select_a_language_placeholder=Select a language property.category.general=General property.category.general.email=Email @@ -941,6 +942,7 @@ property.category.duplications=Duplications property.category.localization=Localization property.category.exclusions=Analysis Scope property.category.webhooks=Webhooks +property.category.languages=Languages property.sonar.inclusions.name=Source File Inclusions property.sonar.inclusions.description=Patterns used to include some source files and only these ones in analysis. property.sonar.test.inclusions.name=Test File Inclusions |