Browse Source

SONAR-10487 Improve UX of filter option in Quality Profiles page

tags/7.6
Wouter Admiraal 5 years ago
parent
commit
3e64f2c04a

+ 40
- 46
server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.tsx View File

@@ -18,62 +18,56 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import { IndexLink } from 'react-router';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { Option } from 'react-select';
import { translate } from '../../../helpers/l10n';
import { getProfilesPath, getProfilesForLanguagePath } from '../utils';
import Dropdown from '../../../components/controls/Dropdown';
import DropdownIcon from '../../../components/icons-components/DropdownIcon';
import Select from '../../../components/controls/Select';
import { withRouter, Router } from '../../../components/hoc/withRouter';

interface Props {
currentFilter?: string;
languages: Array<{ key: string; name: string }>;
organization: string | null;
router: Pick<Router, 'replace'>;
}

export default function ProfilesListHeader({ currentFilter, languages, organization }: Props) {
if (languages.length < 2) {
return null;
}
export class ProfilesListHeader extends React.PureComponent<Props> {
handleChange = (option: { value: string } | null) => {
const { organization, router } = this.props;

const currentLanguage = currentFilter && languages.find(l => l.key === currentFilter);
router.replace(
!option
? getProfilesPath(organization)
: getProfilesForLanguagePath(option.value, organization)
);
};

// if unknown language, then
if (currentFilter && !currentLanguage) {
return null;
}
render() {
const { currentFilter, languages } = this.props;
if (languages.length < 2) {
return null;
}

const options: Option[] = languages.map(language => ({
label: language.name,
value: language.key
}));

const label = currentLanguage
? translateWithParameters('quality_profiles.x_Profiles', currentLanguage.name)
: translate('quality_profiles.all_profiles');
const currentLanguage = currentFilter && options.find(l => l.value === currentFilter);

return (
<header className="quality-profiles-list-header clearfix">
<Dropdown
className="display-inline-block"
overlay={
<ul className="menu">
<li>
<IndexLink to={getProfilesPath(organization)}>
{translate('quality_profiles.all_profiles')}
</IndexLink>
</li>
{languages.map(language => (
<li key={language.key}>
<IndexLink
className="js-language-filter-option"
data-language={language.key}
to={getProfilesForLanguagePath(language.key, organization)}>
{language.name}
</IndexLink>
</li>
))}
</ul>
}>
<a className="dropdown-toggle link-no-underline js-language-filter" href="#">
<span className="text-middle">{label}</span>
<DropdownIcon className="little-spacer-left text-middle" />
</a>
</Dropdown>
</header>
);
return (
<header className="quality-profiles-list-header clearfix">
<span className="spacer-right">{translate('quality_profiles.filter_by')}:</span>
<Select
className="input-medium"
clearable={true}
onChange={this.handleChange}
options={options}
value={currentLanguage}
/>
</header>
);
}
}

export default withRouter(ProfilesListHeader);

+ 39
- 0
server/sonar-web/src/main/js/apps/quality-profiles/home/__tests__/ProfilesListHeader-test.tsx View File

@@ -0,0 +1,39 @@
/*
* SonarQube
* Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
import { ProfilesListHeader } from '../ProfilesListHeader';
import { mockRouter } from '../../../../helpers/testUtils';

it('should render correctly', () => {
const wrapper = shallowRender();
expect(wrapper).toMatchSnapshot();
});

function shallowRender(props: Partial<ProfilesListHeader['props']> = {}) {
return shallow(
<ProfilesListHeader
languages={[{ key: 'js', name: 'JavaScript' }, { key: 'java', name: 'Java' }]}
organization="foo"
router={mockRouter()}
{...props}
/>
);
}

+ 31
- 0
server/sonar-web/src/main/js/apps/quality-profiles/home/__tests__/__snapshots__/ProfilesListHeader-test.tsx.snap View File

@@ -0,0 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly 1`] = `
<header
className="quality-profiles-list-header clearfix"
>
<span
className="spacer-right"
>
quality_profiles.filter_by
:
</span>
<Select
className="input-medium"
clearable={true}
onChange={[Function]}
options={
Array [
Object {
"label": "JavaScript",
"value": "js",
},
Object {
"label": "Java",
"value": "java",
},
]
}
/>
</header>
`;

+ 1
- 0
sonar-core/src/main/resources/org/sonar/l10n/core.properties View File

@@ -1142,6 +1142,7 @@ projects_management.project_has_been_successfully_created=Project {project} has

quality_profiles.new_profile=New Profile
quality_profiles.compare_with=Compare with
quality_profiles.filter_by=Filter profiles by
quality_profiles.restore_profile=Restore Profile
quality_profiles.restore_profile.success={1} rule(s) restored in profile "{0}"
quality_profiles.restore_profile.warning={1} rule(s) restored, {2} rule(s) ignored in profile "{0}"

Loading…
Cancel
Save