@@ -109,6 +109,7 @@ | |||
margin-bottom: 10px; | |||
margin-left: 10px; | |||
line-height: var(--controlHeight); | |||
text-align: right; | |||
} | |||
.page-actions .badge { |
@@ -24,6 +24,7 @@ import RestoreProfileForm from './RestoreProfileForm'; | |||
import { Profile } from '../types'; | |||
import { getProfilePath } from '../utils'; | |||
import { Actions } from '../../../api/quality-profiles'; | |||
import { Alert } from '../../../components/ui/Alert'; | |||
import { Button } from '../../../components/ui/buttons'; | |||
import { translate } from '../../../helpers/l10n'; | |||
import { withRouter, Router } from '../../../components/hoc/withRouter'; | |||
@@ -42,7 +43,7 @@ interface State { | |||
restoreFormOpen: boolean; | |||
} | |||
class PageHeader extends React.PureComponent<Props, State> { | |||
export class PageHeader extends React.PureComponent<Props, State> { | |||
state: State = { | |||
createFormOpen: false, | |||
restoreFormOpen: false | |||
@@ -76,13 +77,17 @@ class PageHeader extends React.PureComponent<Props, State> { | |||
}; | |||
render() { | |||
const { actions, languages, organization, profiles } = this.props; | |||
return ( | |||
<header className="page-header"> | |||
<h1 className="page-title">{translate('quality_profiles.page')}</h1> | |||
{this.props.actions.create && ( | |||
{actions.create && ( | |||
<div className="page-actions"> | |||
<Button id="quality-profiles-create" onClick={this.handleCreateClick}> | |||
<Button | |||
disabled={languages.length === 0} | |||
id="quality-profiles-create" | |||
onClick={this.handleCreateClick}> | |||
{translate('create')} | |||
</Button> | |||
<Button | |||
@@ -91,6 +96,11 @@ class PageHeader extends React.PureComponent<Props, State> { | |||
onClick={this.handleRestoreClick}> | |||
{translate('restore')} | |||
</Button> | |||
{languages.length === 0 && ( | |||
<Alert className="spacer-top" variant="warning"> | |||
{translate('quality_profiles.no_languages_available')} | |||
</Alert> | |||
)} | |||
</div> | |||
)} | |||
@@ -112,17 +122,17 @@ class PageHeader extends React.PureComponent<Props, State> { | |||
<RestoreProfileForm | |||
onClose={this.closeRestoreForm} | |||
onRestore={this.props.updateProfiles} | |||
organization={this.props.organization} | |||
organization={organization} | |||
/> | |||
)} | |||
{this.state.createFormOpen && ( | |||
<CreateProfileForm | |||
languages={this.props.languages} | |||
languages={languages} | |||
onClose={this.closeCreateForm} | |||
onCreate={this.handleCreate} | |||
organization={this.props.organization} | |||
profiles={this.props.profiles} | |||
organization={organization} | |||
profiles={profiles} | |||
/> | |||
)} | |||
</header> |
@@ -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 * as React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import { PageHeader } from '../PageHeader'; | |||
import { mockLanguage, mockQualityProfile, mockRouter } from '../../../../helpers/testMocks'; | |||
import { click } from '../../../../helpers/testUtils'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
expect(shallowRender({ actions: { create: true } })).toMatchSnapshot(); | |||
expect(shallowRender({ actions: { create: true }, languages: [] })).toMatchSnapshot(); | |||
}); | |||
it('should show a create form', () => { | |||
const wrapper = shallowRender({ actions: { create: true } }); | |||
click(wrapper.find('#quality-profiles-create')); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
it('should show a restore form', () => { | |||
const wrapper = shallowRender({ actions: { create: true } }); | |||
click(wrapper.find('#quality-profiles-restore')); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<PageHeader['props']> = {}) { | |||
return shallow( | |||
<PageHeader | |||
actions={{ create: false }} | |||
languages={[mockLanguage()]} | |||
organization="foo" | |||
profiles={[mockQualityProfile()]} | |||
router={mockRouter()} | |||
updateProfiles={jest.fn()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,276 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<header | |||
className="page-header" | |||
> | |||
<h1 | |||
className="page-title" | |||
> | |||
quality_profiles.page | |||
</h1> | |||
<div | |||
className="page-description markdown" | |||
> | |||
quality_profiles.intro1 | |||
<br /> | |||
quality_profiles.intro2 | |||
<Link | |||
className="spacer-left" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to={ | |||
Object { | |||
"pathname": "/documentation/instance-administration/quality-profiles/", | |||
} | |||
} | |||
> | |||
learn_more | |||
</Link> | |||
</div> | |||
</header> | |||
`; | |||
exports[`should render correctly 2`] = ` | |||
<header | |||
className="page-header" | |||
> | |||
<h1 | |||
className="page-title" | |||
> | |||
quality_profiles.page | |||
</h1> | |||
<div | |||
className="page-actions" | |||
> | |||
<Button | |||
disabled={false} | |||
id="quality-profiles-create" | |||
onClick={[Function]} | |||
> | |||
create | |||
</Button> | |||
<Button | |||
className="little-spacer-left" | |||
id="quality-profiles-restore" | |||
onClick={[Function]} | |||
> | |||
restore | |||
</Button> | |||
</div> | |||
<div | |||
className="page-description markdown" | |||
> | |||
quality_profiles.intro1 | |||
<br /> | |||
quality_profiles.intro2 | |||
<Link | |||
className="spacer-left" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to={ | |||
Object { | |||
"pathname": "/documentation/instance-administration/quality-profiles/", | |||
} | |||
} | |||
> | |||
learn_more | |||
</Link> | |||
</div> | |||
</header> | |||
`; | |||
exports[`should render correctly 3`] = ` | |||
<header | |||
className="page-header" | |||
> | |||
<h1 | |||
className="page-title" | |||
> | |||
quality_profiles.page | |||
</h1> | |||
<div | |||
className="page-actions" | |||
> | |||
<Button | |||
disabled={true} | |||
id="quality-profiles-create" | |||
onClick={[Function]} | |||
> | |||
create | |||
</Button> | |||
<Button | |||
className="little-spacer-left" | |||
id="quality-profiles-restore" | |||
onClick={[Function]} | |||
> | |||
restore | |||
</Button> | |||
<Alert | |||
className="spacer-top" | |||
variant="warning" | |||
> | |||
quality_profiles.no_languages_available | |||
</Alert> | |||
</div> | |||
<div | |||
className="page-description markdown" | |||
> | |||
quality_profiles.intro1 | |||
<br /> | |||
quality_profiles.intro2 | |||
<Link | |||
className="spacer-left" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to={ | |||
Object { | |||
"pathname": "/documentation/instance-administration/quality-profiles/", | |||
} | |||
} | |||
> | |||
learn_more | |||
</Link> | |||
</div> | |||
</header> | |||
`; | |||
exports[`should show a create form 1`] = ` | |||
<header | |||
className="page-header" | |||
> | |||
<h1 | |||
className="page-title" | |||
> | |||
quality_profiles.page | |||
</h1> | |||
<div | |||
className="page-actions" | |||
> | |||
<Button | |||
disabled={false} | |||
id="quality-profiles-create" | |||
onClick={[Function]} | |||
> | |||
create | |||
</Button> | |||
<Button | |||
className="little-spacer-left" | |||
id="quality-profiles-restore" | |||
onClick={[Function]} | |||
> | |||
restore | |||
</Button> | |||
</div> | |||
<div | |||
className="page-description markdown" | |||
> | |||
quality_profiles.intro1 | |||
<br /> | |||
quality_profiles.intro2 | |||
<Link | |||
className="spacer-left" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to={ | |||
Object { | |||
"pathname": "/documentation/instance-administration/quality-profiles/", | |||
} | |||
} | |||
> | |||
learn_more | |||
</Link> | |||
</div> | |||
<CreateProfileForm | |||
languages={ | |||
Array [ | |||
Object { | |||
"key": "css", | |||
"name": "CSS", | |||
}, | |||
] | |||
} | |||
onClose={[Function]} | |||
onCreate={[Function]} | |||
organization="foo" | |||
profiles={ | |||
Array [ | |||
Object { | |||
"activeDeprecatedRuleCount": 2, | |||
"activeRuleCount": 10, | |||
"childrenCount": 0, | |||
"depth": 1, | |||
"isBuiltIn": false, | |||
"isDefault": false, | |||
"isInherited": false, | |||
"key": "key", | |||
"language": "js", | |||
"languageName": "JavaScript", | |||
"name": "name", | |||
"organization": "foo", | |||
"projectCount": 3, | |||
}, | |||
] | |||
} | |||
/> | |||
</header> | |||
`; | |||
exports[`should show a restore form 1`] = ` | |||
<header | |||
className="page-header" | |||
> | |||
<h1 | |||
className="page-title" | |||
> | |||
quality_profiles.page | |||
</h1> | |||
<div | |||
className="page-actions" | |||
> | |||
<Button | |||
disabled={false} | |||
id="quality-profiles-create" | |||
onClick={[Function]} | |||
> | |||
create | |||
</Button> | |||
<Button | |||
className="little-spacer-left" | |||
id="quality-profiles-restore" | |||
onClick={[Function]} | |||
> | |||
restore | |||
</Button> | |||
</div> | |||
<div | |||
className="page-description markdown" | |||
> | |||
quality_profiles.intro1 | |||
<br /> | |||
quality_profiles.intro2 | |||
<Link | |||
className="spacer-left" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to={ | |||
Object { | |||
"pathname": "/documentation/instance-administration/quality-profiles/", | |||
} | |||
} | |||
> | |||
learn_more | |||
</Link> | |||
</div> | |||
<RestoreProfileForm | |||
onClose={[Function]} | |||
onRestore={[MockFunction]} | |||
organization="foo" | |||
/> | |||
</header> | |||
`; |
@@ -1141,6 +1141,7 @@ 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}" | |||
quality_profiles.optional_configuration_file=Optional configuration file | |||
quality_profiles.new_name=New name | |||
quality_profiles.no_languages_available=There are no languages available. You cannot create a new profile. | |||
quality_profiles.delete_confirm_title=Delete Profile | |||
quality_profiles.are_you_sure_want_delete_profile_x=Are you sure that you want to delete the profile "{0}"? | |||
quality_profiles.are_you_sure_want_delete_profile_x_and_descendants=Are you sure that you want to delete the profile "{0}" and all its descendants? |