From 0a563e3e59e9802090424591c66f623baeeb3a2f Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 25 Jan 2022 17:40:27 +0100 Subject: [PATCH] SONAR-15464 project settings search --- .../js/apps/settings/__tests__/utils-test.ts | 18 ++++++++++-- .../apps/settings/components/PageHeader.tsx | 10 ++----- .../settings/components/SettingsSearch.tsx | 14 +++++++-- .../components/SettingsSearchRenderer.tsx | 5 ++-- .../__tests__/SettingsSearch-test.tsx | 9 ++++++ .../__snapshots__/PageHeader-test.tsx.snap | 29 +++++++++++++++++-- .../src/main/js/apps/settings/styles.css | 9 ++---- .../src/main/js/apps/settings/utils.ts | 29 +++++++++++++++++-- 8 files changed, 98 insertions(+), 25 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/settings/__tests__/utils-test.ts b/server/sonar-web/src/main/js/apps/settings/__tests__/utils-test.ts index 5e9861a8cdd..cea516047c7 100644 --- a/server/sonar-web/src/main/js/apps/settings/__tests__/utils-test.ts +++ b/server/sonar-web/src/main/js/apps/settings/__tests__/utils-test.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 { mockComponent } from '../../../helpers/mocks/component'; import { mockDefinition } from '../../../helpers/mocks/settings'; import { Setting, @@ -90,10 +91,12 @@ describe('buildSettingLink', () => { it.each([ [ mockDefinition({ key: 'anykey' }), + undefined, { hash: '#anykey', pathname: '/admin/settings', query: { category: 'foo category' } } ], [ mockDefinition({ key: 'sonar.auth.gitlab.name' }), + undefined, { hash: '#sonar.auth.gitlab.name', pathname: '/admin/settings', @@ -102,6 +105,7 @@ describe('buildSettingLink', () => { ], [ mockDefinition({ key: 'sonar.auth.github.token' }), + undefined, { hash: '#sonar.auth.github.token', pathname: '/admin/settings', @@ -110,13 +114,23 @@ describe('buildSettingLink', () => { ], [ mockDefinition({ key: 'sonar.almintegration.azure' }), + undefined, { hash: '#sonar.almintegration.azure', pathname: '/admin/settings', query: { alm: 'azure', category: 'foo category' } } + ], + [ + mockDefinition({ key: 'defKey' }), + mockComponent({ key: 'componentKey' }), + { + hash: '#defKey', + pathname: '/project/settings', + query: { id: 'componentKey', category: 'foo category' } + } ] - ])('should work as expected', (definition, expectedUrl) => { - expect(buildSettingLink(definition)).toEqual(expectedUrl); + ])('should work as expected', (definition, component, expectedUrl) => { + expect(buildSettingLink(definition, component)).toEqual(expectedUrl); }); }); diff --git a/server/sonar-web/src/main/js/apps/settings/components/PageHeader.tsx b/server/sonar-web/src/main/js/apps/settings/components/PageHeader.tsx index b6052ab4c85..b18ad5646fb 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/PageHeader.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/PageHeader.tsx @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import classNames from 'classnames'; import * as React from 'react'; import InstanceMessage from '../../../components/common/InstanceMessage'; import { translate } from '../../../helpers/l10n'; @@ -37,15 +36,12 @@ export default function PageHeader({ component }: PageHeaderProps) { ); return ( -
+
-
+

{title}

{description}
- {!component && } +
diff --git a/server/sonar-web/src/main/js/apps/settings/components/SettingsSearch.tsx b/server/sonar-web/src/main/js/apps/settings/components/SettingsSearch.tsx index 0d3bed68fd4..d868ed7ad30 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/SettingsSearch.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/SettingsSearch.tsx @@ -26,11 +26,16 @@ import { withRouter } from '../../../components/hoc/withRouter'; import { KeyboardCodes } from '../../../helpers/keycodes'; import { getSettingsAppAllDefinitions, Store } from '../../../store/rootReducer'; import { SettingCategoryDefinition } from '../../../types/settings'; -import { ADDITIONAL_SETTING_DEFINITIONS, buildSettingLink } from '../utils'; +import { + ADDITIONAL_PROJECT_SETTING_DEFINITIONS, + ADDITIONAL_SETTING_DEFINITIONS, + buildSettingLink +} from '../utils'; import SettingsSearchRenderer from './SettingsSearchRenderer'; interface Props { className?: string; + component?: T.Component; definitions: SettingCategoryDefinition[]; router: InjectedRouter; } @@ -58,7 +63,9 @@ export class SettingsSearch extends React.Component { this.doSearch = debounce(this.doSearch, DEBOUNCE_DELAY); this.handleFocus = debounce(this.handleFocus, DEBOUNCE_DELAY); - const definitions = props.definitions.concat(ADDITIONAL_SETTING_DEFINITIONS); + const definitions = props.definitions.concat( + props.component ? ADDITIONAL_PROJECT_SETTING_DEFINITIONS : ADDITIONAL_SETTING_DEFINITIONS + ); this.index = this.buildSearchIndex(definitions); this.definitionsByKey = keyBy(definitions, 'key'); } @@ -171,11 +178,12 @@ export class SettingsSearch extends React.Component { }; render() { - const { className } = this.props; + const { className, component } = this.props; return ( (null); @@ -79,7 +80,7 @@ export default function SettingsSearchRenderer(props: SettingsSearchRendererProp props.onMouseOverResult(r.key)} - to={buildSettingLink(r)}> + to={buildSettingLink(r, component)}>

{r.name || r.subCategory}

diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/SettingsSearch-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/__tests__/SettingsSearch-test.tsx index f6ea708a34d..d12e7c62b03 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/SettingsSearch-test.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/SettingsSearch-test.tsx @@ -20,6 +20,7 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { KeyboardCodes } from '../../../../helpers/keycodes'; +import { mockComponent } from '../../../../helpers/mocks/component'; import { mockDefinition } from '../../../../helpers/mocks/settings'; import { mockRouter } from '../../../../helpers/testMocks'; import { mockEvent, waitAndUpdate } from '../../../../helpers/testUtils'; @@ -137,6 +138,14 @@ describe('instance', () => { }); }); +describe('project settings search', () => { + it('should load the correct definitions', () => { + const wrapper = shallowRender({ component: mockComponent(), definitions: [] }); + + expect(Object.keys(wrapper.instance().definitionsByKey)).toHaveLength(1); + }); +}); + function shallowRender(overrides: Partial = {}) { return shallow( diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/PageHeader-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/PageHeader-test.tsx.snap index 682807a8995..9f54727d6a1 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/PageHeader-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/PageHeader-test.tsx.snap @@ -20,6 +20,31 @@ exports[`should render correctly: for project 1`] = ` > project_settings.page.description +
@@ -27,13 +52,13 @@ exports[`should render correctly: for project 1`] = ` exports[`should render correctly: global 1`] = `

= {}; if (key.startsWith('sonar.auth.gitlab')) { @@ -187,6 +197,21 @@ export function buildSettingLink(definition: SettingCategoryDefinition): Locatio }; } +export const ADDITIONAL_PROJECT_SETTING_DEFINITIONS: SettingCategoryDefinition[] = [ + { + name: 'DevOps Platform Integration', + description: ` + Display your Quality Gate status directly in your DevOps Platform. + Each DevOps Platform instance must be configured globally first, and given a unique name. Pick the instance your project is hosted on. + `, + category: 'pull_request_decoration_binding', + key: ``, + fields: [], + options: [], + subCategory: '' + } +]; + export const ADDITIONAL_SETTING_DEFINITIONS: SettingCategoryDefinition[] = [ { name: 'Default New Code behavior', -- 2.39.5