@@ -23,15 +23,18 @@ import { ResetButtonLink, SubmitButton } from 'sonar-ui-common/components/contro | |||
import Modal from 'sonar-ui-common/components/controls/Modal'; | |||
import Select from 'sonar-ui-common/components/controls/Select'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { parseAsOptionalString } from 'sonar-ui-common/helpers/query'; | |||
import { | |||
changeProfileParent, | |||
createQualityProfile, | |||
getImporters | |||
} from '../../../api/quality-profiles'; | |||
import { Location } from '../../../components/hoc/withRouter'; | |||
import { Profile } from '../types'; | |||
interface Props { | |||
languages: Array<{ key: string; name: string }>; | |||
location: Location; | |||
onClose: () => void; | |||
onCreate: Function; | |||
organization: string | null; | |||
@@ -115,10 +118,11 @@ export default class CreateProfileForm extends React.PureComponent<Props, State> | |||
render() { | |||
const header = translate('quality_profiles.new_profile'); | |||
const languageQueryFilter = parseAsOptionalString(this.props.location.query.language); | |||
const languages = sortBy(this.props.languages, 'name'); | |||
let profiles: Array<{ label: string; value: string }> = []; | |||
const selectedLanguage = this.state.language || languages[0].key; | |||
const selectedLanguage = this.state.language || languageQueryFilter || languages[0].key; | |||
const importers = this.state.importers.filter(importer => | |||
importer.languages.includes(selectedLanguage) | |||
); | |||
@@ -176,9 +180,9 @@ export default class CreateProfileForm extends React.PureComponent<Props, State> | |||
id="create-profile-language" | |||
name="language" | |||
onChange={this.handleLanguageChange} | |||
options={languages.map(language => ({ | |||
label: language.name, | |||
value: language.key | |||
options={languages.map(l => ({ | |||
label: l.name, | |||
value: l.key | |||
}))} | |||
value={selectedLanguage} | |||
/> |
@@ -19,6 +19,7 @@ | |||
*/ | |||
import * as React from 'react'; | |||
import { Actions } from '../../../api/quality-profiles'; | |||
import { Location } from '../../../components/hoc/withRouter'; | |||
import { Profile } from '../types'; | |||
import Evolution from './Evolution'; | |||
import PageHeader from './PageHeader'; | |||
@@ -27,7 +28,7 @@ import ProfilesList from './ProfilesList'; | |||
interface Props { | |||
actions: Actions; | |||
languages: Array<{ key: string; name: string }>; | |||
location: { query: T.Dict<string> }; | |||
location: Location; | |||
organization: string | null; | |||
profiles: Profile[]; | |||
updateProfiles: () => Promise<void>; |
@@ -23,7 +23,7 @@ import { Button } from 'sonar-ui-common/components/controls/buttons'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { Actions } from '../../../api/quality-profiles'; | |||
import { Router, withRouter } from '../../../components/hoc/withRouter'; | |||
import { Location, Router, withRouter } from '../../../components/hoc/withRouter'; | |||
import { Profile } from '../types'; | |||
import { getProfilePath } from '../utils'; | |||
import CreateProfileForm from './CreateProfileForm'; | |||
@@ -32,6 +32,7 @@ import RestoreProfileForm from './RestoreProfileForm'; | |||
interface Props { | |||
actions: Actions; | |||
languages: Array<{ key: string; name: string }>; | |||
location: Location; | |||
organization: string | null; | |||
profiles: Profile[]; | |||
router: Pick<Router, 'push'>; | |||
@@ -77,7 +78,7 @@ export class PageHeader extends React.PureComponent<Props, State> { | |||
}; | |||
render() { | |||
const { actions, languages, organization, profiles } = this.props; | |||
const { actions, languages, location, organization, profiles } = this.props; | |||
return ( | |||
<header className="page-header"> | |||
<h1 className="page-title">{translate('quality_profiles.page')}</h1> | |||
@@ -129,6 +130,7 @@ export class PageHeader extends React.PureComponent<Props, State> { | |||
{this.state.createFormOpen && ( | |||
<CreateProfileForm | |||
languages={languages} | |||
location={location} | |||
onClose={this.closeCreateForm} | |||
onCreate={this.handleCreate} | |||
organization={organization} |
@@ -21,7 +21,7 @@ import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockEvent, waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { changeProfileParent, createQualityProfile } from '../../../../api/quality-profiles'; | |||
import { mockQualityProfile } from '../../../../helpers/testMocks'; | |||
import { mockLocation, mockQualityProfile } from '../../../../helpers/testMocks'; | |||
import CreateProfileForm from '../CreateProfileForm'; | |||
beforeEach(() => jest.clearAllMocks()); | |||
@@ -32,7 +32,7 @@ jest.mock('../../../../api/quality-profiles', () => ({ | |||
getImporters: jest.fn().mockResolvedValue([ | |||
{ | |||
key: 'key_importer', | |||
languages: ['lang1_importer', 'lang2_importer', 'kr'], | |||
languages: ['lang1_importer', 'lang2_importer', 'js'], | |||
name: 'name_importer' | |||
} | |||
]) | |||
@@ -41,7 +41,11 @@ jest.mock('../../../../api/quality-profiles', () => ({ | |||
it('should render correctly', async () => { | |||
const wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper).toMatchSnapshot(); | |||
expect(wrapper).toMatchSnapshot('default'); | |||
expect( | |||
wrapper.setProps({ location: mockLocation({ query: { language: 'js' } }) }) | |||
).toMatchSnapshot('with query filter'); | |||
}); | |||
it('should handle form submit correctly', async () => { | |||
@@ -72,11 +76,15 @@ it('should handle form submit without parent correctly', async () => { | |||
function shallowRender(props?: Partial<CreateProfileForm['props']>) { | |||
return shallow<CreateProfileForm>( | |||
<CreateProfileForm | |||
languages={[{ key: 'kr', name: 'Hangeul' }]} | |||
languages={[ | |||
{ key: 'js', name: 'JavaScript' }, | |||
{ key: 'css', name: 'CSS' } | |||
]} | |||
location={mockLocation()} | |||
onClose={jest.fn()} | |||
onCreate={jest.fn()} | |||
organization="org" | |||
profiles={[mockQualityProfile()]} | |||
profiles={[mockQualityProfile(), mockQualityProfile({ language: 'css' })]} | |||
{...props} | |||
/> | |||
); |
@@ -20,7 +20,12 @@ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { click } from 'sonar-ui-common/helpers/testUtils'; | |||
import { mockLanguage, mockQualityProfile, mockRouter } from '../../../../helpers/testMocks'; | |||
import { | |||
mockLanguage, | |||
mockLocation, | |||
mockQualityProfile, | |||
mockRouter | |||
} from '../../../../helpers/testMocks'; | |||
import { PageHeader } from '../PageHeader'; | |||
it('should render correctly', () => { | |||
@@ -46,6 +51,7 @@ function shallowRender(props: Partial<PageHeader['props']> = {}) { | |||
<PageHeader | |||
actions={{ create: false }} | |||
languages={[mockLanguage()]} | |||
location={mockLocation()} | |||
organization="foo" | |||
profiles={[mockQualityProfile()]} | |||
router={mockRouter()} |
@@ -1,6 +1,6 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
exports[`should render correctly: default 1`] = ` | |||
<Modal | |||
contentLabel="quality_profiles.new_profile" | |||
onRequestClose={[MockFunction]} | |||
@@ -66,12 +66,148 @@ exports[`should render correctly 1`] = ` | |||
options={ | |||
Array [ | |||
Object { | |||
"label": "Hangeul", | |||
"value": "kr", | |||
"label": "CSS", | |||
"value": "css", | |||
}, | |||
Object { | |||
"label": "JavaScript", | |||
"value": "js", | |||
}, | |||
] | |||
} | |||
value="css" | |||
/> | |||
</div> | |||
<div | |||
className="modal-field" | |||
> | |||
<label | |||
htmlFor="create-profile-parent" | |||
> | |||
quality_profiles.parent | |||
</label> | |||
<Select | |||
clearable={true} | |||
id="create-profile-parent" | |||
name="parentKey" | |||
onChange={[Function]} | |||
options={ | |||
Array [ | |||
Object { | |||
"label": "none", | |||
"value": "", | |||
}, | |||
Object { | |||
"label": "name", | |||
"value": "key", | |||
}, | |||
] | |||
} | |||
value="" | |||
/> | |||
</div> | |||
<input | |||
name="hello-ie11" | |||
type="hidden" | |||
value="" | |||
/> | |||
</div> | |||
<div | |||
className="modal-foot" | |||
> | |||
<SubmitButton | |||
disabled={false} | |||
id="create-profile-submit" | |||
> | |||
create | |||
</SubmitButton> | |||
<ResetButtonLink | |||
id="create-profile-cancel" | |||
onClick={[MockFunction]} | |||
> | |||
cancel | |||
</ResetButtonLink> | |||
</div> | |||
</form> | |||
</Modal> | |||
`; | |||
exports[`should render correctly: with query filter 1`] = ` | |||
<Modal | |||
contentLabel="quality_profiles.new_profile" | |||
onRequestClose={[MockFunction]} | |||
size="small" | |||
> | |||
<form | |||
id="create-profile-form" | |||
onSubmit={[Function]} | |||
> | |||
<div | |||
className="modal-head" | |||
> | |||
<h2> | |||
quality_profiles.new_profile | |||
</h2> | |||
</div> | |||
<div | |||
className="modal-body" | |||
> | |||
<div | |||
className="modal-field" | |||
> | |||
<label | |||
htmlFor="create-profile-name" | |||
> | |||
name | |||
<em | |||
className="mandatory" | |||
> | |||
* | |||
</em> | |||
</label> | |||
<input | |||
autoFocus={true} | |||
id="create-profile-name" | |||
maxLength={100} | |||
name="name" | |||
onChange={[Function]} | |||
required={true} | |||
size={50} | |||
type="text" | |||
value="" | |||
/> | |||
</div> | |||
<div | |||
className="modal-field" | |||
> | |||
<label | |||
htmlFor="create-profile-language" | |||
> | |||
language | |||
<em | |||
className="mandatory" | |||
> | |||
* | |||
</em> | |||
</label> | |||
<Select | |||
clearable={false} | |||
id="create-profile-language" | |||
name="language" | |||
onChange={[Function]} | |||
options={ | |||
Array [ | |||
Object { | |||
"label": "CSS", | |||
"value": "css", | |||
}, | |||
Object { | |||
"label": "JavaScript", | |||
"value": "js", | |||
}, | |||
] | |||
} | |||
value="kr" | |||
value="js" | |||
/> | |||
</div> | |||
<div | |||
@@ -93,6 +229,10 @@ exports[`should render correctly 1`] = ` | |||
"label": "none", | |||
"value": "", | |||
}, | |||
Object { | |||
"label": "name", | |||
"value": "key", | |||
}, | |||
] | |||
} | |||
value="" |
@@ -194,6 +194,17 @@ exports[`should show a create form 1`] = ` | |||
}, | |||
] | |||
} | |||
location={ | |||
Object { | |||
"action": "PUSH", | |||
"hash": "", | |||
"key": "key", | |||
"pathname": "/path", | |||
"query": Object {}, | |||
"search": "", | |||
"state": Object {}, | |||
} | |||
} | |||
onClose={[Function]} | |||
onCreate={[Function]} | |||
organization="foo" |