@@ -18,6 +18,8 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { Link } from 'react-router'; | |||
import SearchBox from 'sonar-ui-common/components/controls/SearchBox'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
@@ -28,6 +30,7 @@ import { | |||
} from '../../../types/alm-integration'; | |||
import BitbucketRepositories from './BitbucketRepositories'; | |||
import BitbucketSearchResults from './BitbucketSearchResults'; | |||
import { CreateProjectModes } from './types'; | |||
export interface BitbucketImportRepositoryFormProps { | |||
disableRepositories: boolean; | |||
@@ -53,7 +56,21 @@ export default function BitbucketImportRepositoryForm(props: BitbucketImportRepo | |||
if (projects.length === 0) { | |||
return ( | |||
<Alert className="spacer-top" variant="warning"> | |||
{translate('onboarding.create_project.no_bbs_projects')} | |||
<FormattedMessage | |||
defaultMessage={translate('onboarding.create_project.no_bbs_projects')} | |||
id="onboarding.create_project.no_bbs_projects" | |||
values={{ | |||
link: ( | |||
<Link | |||
to={{ | |||
pathname: '/projects/create', | |||
query: { mode: CreateProjectModes.BitbucketServer, resetPat: 1 } | |||
}}> | |||
{translate('onboarding.create_project.update_your_token')} | |||
</Link> | |||
) | |||
}} | |||
/> | |||
</Alert> | |||
); | |||
} |
@@ -32,6 +32,7 @@ export interface BitbucketPersonalAccessTokenFormProps { | |||
bitbucketSetting: AlmSettingsInstance; | |||
onPersonalAccessTokenCreate: (token: string) => void; | |||
submitting?: boolean; | |||
validationFailed: boolean; | |||
} | |||
export default function BitbucketPersonalAccessTokenForm( | |||
@@ -39,17 +40,24 @@ export default function BitbucketPersonalAccessTokenForm( | |||
) { | |||
const { | |||
bitbucketSetting: { url }, | |||
submitting = false | |||
submitting = false, | |||
validationFailed | |||
} = props; | |||
const [personalAccessToken, setPersonalAccessToken] = React.useState(''); | |||
const isValid = personalAccessToken.length > 0; | |||
const [touched, setTouched] = React.useState(false); | |||
React.useEffect(() => { | |||
setTouched(false); | |||
}, [submitting]); | |||
const isInvalid = validationFailed && !touched; | |||
return ( | |||
<div className="display-flex-start"> | |||
<form | |||
onSubmit={(e: React.SyntheticEvent<HTMLFormElement>) => { | |||
e.preventDefault(); | |||
props.onPersonalAccessTokenCreate(personalAccessToken); | |||
const value = new FormData(e.currentTarget).get('personal_access_token') as string; | |||
props.onPersonalAccessTokenCreate(value); | |||
}}> | |||
<h2 className="big">{translate('onboarding.create_project.grant_access_to_bbs.title')}</h2> | |||
<p className="big-spacer-top big-spacer-bottom"> | |||
@@ -57,28 +65,30 @@ export default function BitbucketPersonalAccessTokenForm( | |||
</p> | |||
<ValidationInput | |||
error={undefined} | |||
error={isInvalid ? translate('onboarding.create_project.pat_incorrect') : undefined} | |||
id="personal_access_token" | |||
isInvalid={false} | |||
isValid={isValid} | |||
isInvalid={isInvalid} | |||
isValid={false} | |||
label={translate('onboarding.create_project.enter_pat')} | |||
required={true}> | |||
<input | |||
autoFocus={true} | |||
className={classNames('input-super-large', { | |||
'is-valid': isValid | |||
'is-invalid': isInvalid | |||
})} | |||
id="personal_access_token" | |||
minLength={1} | |||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => | |||
setPersonalAccessToken(e.currentTarget.value) | |||
} | |||
name="personal_access_token" | |||
onChange={() => { | |||
setTouched(true); | |||
}} | |||
type="text" | |||
value={personalAccessToken} | |||
/> | |||
</ValidationInput> | |||
<SubmitButton disabled={!isValid || submitting}>{translate('save')}</SubmitButton> | |||
<SubmitButton disabled={isInvalid || submitting || !touched}> | |||
{translate('save')} | |||
</SubmitButton> | |||
<DeferredSpinner className="spacer-left" loading={submitting} /> | |||
</form> | |||
@@ -19,16 +19,17 @@ | |||
*/ | |||
import * as classNames from 'classnames'; | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { Link } from 'react-router'; | |||
import BoxedGroupAccordion from 'sonar-ui-common/components/controls/BoxedGroupAccordion'; | |||
import Radio from 'sonar-ui-common/components/controls/Radio'; | |||
import Tooltip from 'sonar-ui-common/components/controls/Tooltip'; | |||
import CheckIcon from 'sonar-ui-common/components/icons/CheckIcon'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n'; | |||
import { colors } from '../../../app/theme'; | |||
import { getProjectUrl } from '../../../helpers/urls'; | |||
import { BitbucketProject, BitbucketRepository } from '../../../types/alm-integration'; | |||
import { CreateProjectModes } from './types'; | |||
export interface BitbucketProjectAccordionProps { | |||
disableRepositories: boolean; | |||
@@ -73,7 +74,23 @@ export default function BitbucketProjectAccordion(props: BitbucketProjectAccordi | |||
{open && ( | |||
<div className="display-flex-wrap"> | |||
{repositoryCount === 0 && ( | |||
<Alert variant="warning">{translate('onboarding.create_project.no_bbs_repos')}</Alert> | |||
<Alert variant="warning"> | |||
<FormattedMessage | |||
defaultMessage={translate('onboarding.create_project.no_bbs_repos')} | |||
id="onboarding.create_project.no_bbs_repos" | |||
values={{ | |||
link: ( | |||
<Link | |||
to={{ | |||
pathname: '/projects/create', | |||
query: { mode: CreateProjectModes.BitbucketServer, resetPat: 1 } | |||
}}> | |||
{translate('onboarding.create_project.update_your_token')} | |||
</Link> | |||
) | |||
}} | |||
/> | |||
</Alert> | |||
)} | |||
{repositories.map(repo => | |||
@@ -84,11 +101,9 @@ export default function BitbucketProjectAccordion(props: BitbucketProjectAccordi | |||
<CheckIcon className="spacer-right" fill={colors.green} size={14} /> | |||
<div className="overflow-hidden"> | |||
<div className="little-spacer-bottom text-ellipsis"> | |||
<Tooltip overlay={repo.name}> | |||
<strong> | |||
<Link to={getProjectUrl(repo.sqProjectKey)}>{repo.name}</Link> | |||
</strong> | |||
</Tooltip> | |||
<strong title={repo.name}> | |||
<Link to={getProjectUrl(repo.sqProjectKey)}>{repo.name}</Link> | |||
</strong> | |||
</div> | |||
<em>{translate('onboarding.create_project.repository_imported')}</em> | |||
</div> | |||
@@ -107,9 +122,9 @@ export default function BitbucketProjectAccordion(props: BitbucketProjectAccordi | |||
key={repo.id} | |||
onCheck={() => props.onSelectRepository(repo)} | |||
value={String(repo.id)}> | |||
<Tooltip overlay={repo.name}> | |||
<strong className="text-ellipsis">{repo.name}</strong> | |||
</Tooltip> | |||
<strong className="text-ellipsis" title={repo.name}> | |||
{repo.name} | |||
</strong> | |||
</Radio> | |||
) | |||
)} |
@@ -55,6 +55,7 @@ interface State { | |||
searchResults?: BitbucketRepository[]; | |||
selectedRepository?: BitbucketRepository; | |||
submittingToken?: boolean; | |||
tokenValidationFailed: boolean; | |||
} | |||
export class BitbucketProjectCreate extends React.PureComponent<Props, State> { | |||
@@ -68,7 +69,8 @@ export class BitbucketProjectCreate extends React.PureComponent<Props, State> { | |||
bitbucketSetting: props.bitbucketSettings[0], | |||
importing: false, | |||
loading: false, | |||
searching: false | |||
searching: false, | |||
tokenValidationFailed: false | |||
}; | |||
} | |||
@@ -79,8 +81,9 @@ export class BitbucketProjectCreate extends React.PureComponent<Props, State> { | |||
componentDidUpdate(prevProps: Props) { | |||
if (prevProps.bitbucketSettings.length === 0 && this.props.bitbucketSettings.length > 0) { | |||
this.setState({ bitbucketSetting: this.props.bitbucketSettings[0] }); | |||
this.fetchInitialData(); | |||
this.setState({ bitbucketSetting: this.props.bitbucketSettings[0] }, () => | |||
this.fetchInitialData() | |||
); | |||
} | |||
} | |||
@@ -169,12 +172,15 @@ export class BitbucketProjectCreate extends React.PureComponent<Props, State> { | |||
return; | |||
} | |||
this.setState({ submittingToken: true }); | |||
this.setState({ submittingToken: true, tokenValidationFailed: false }); | |||
setAlmPersonalAccessToken(bitbucketSetting.key, token) | |||
.then(() => { | |||
.then(this.checkPersonalAccessToken) | |||
.then(patIsValid => { | |||
if (this.mounted) { | |||
this.setState({ submittingToken: false }); | |||
this.fetchInitialData(); | |||
this.setState({ submittingToken: false, patIsValid, tokenValidationFailed: !patIsValid }); | |||
if (patIsValid) { | |||
this.fetchInitialData(); | |||
} | |||
} | |||
}) | |||
.catch(() => { | |||
@@ -241,7 +247,7 @@ export class BitbucketProjectCreate extends React.PureComponent<Props, State> { | |||
}; | |||
render() { | |||
const { canAdmin, loadingBindings } = this.props; | |||
const { canAdmin, loadingBindings, location } = this.props; | |||
const { | |||
bitbucketSetting, | |||
importing, | |||
@@ -252,7 +258,8 @@ export class BitbucketProjectCreate extends React.PureComponent<Props, State> { | |||
searching, | |||
searchResults, | |||
selectedRepository, | |||
submittingToken | |||
submittingToken, | |||
tokenValidationFailed | |||
} = this.state; | |||
return ( | |||
@@ -271,8 +278,9 @@ export class BitbucketProjectCreate extends React.PureComponent<Props, State> { | |||
searchResults={searchResults} | |||
searching={searching} | |||
selectedRepository={selectedRepository} | |||
showPersonalAccessTokenForm={!patIsValid} | |||
showPersonalAccessTokenForm={!patIsValid || Boolean(location.query.resetPat)} | |||
submittingToken={submittingToken} | |||
tokenValidationFailed={tokenValidationFailed} | |||
/> | |||
); | |||
} |
@@ -53,6 +53,7 @@ export interface BitbucketProjectCreateRendererProps { | |||
selectedRepository?: BitbucketRepository; | |||
showPersonalAccessTokenForm?: boolean; | |||
submittingToken?: boolean; | |||
tokenValidationFailed: boolean; | |||
} | |||
export default function BitbucketProjectCreateRenderer(props: BitbucketProjectCreateRendererProps) { | |||
@@ -67,7 +68,8 @@ export default function BitbucketProjectCreateRenderer(props: BitbucketProjectCr | |||
searching, | |||
searchResults, | |||
showPersonalAccessTokenForm, | |||
submittingToken | |||
submittingToken, | |||
tokenValidationFailed | |||
} = props; | |||
return ( | |||
@@ -133,6 +135,7 @@ export default function BitbucketProjectCreateRenderer(props: BitbucketProjectCr | |||
bitbucketSetting={bitbucketSetting} | |||
onPersonalAccessTokenCreate={props.onPersonalAccessTokenCreate} | |||
submitting={submittingToken} | |||
validationFailed={tokenValidationFailed} | |||
/> | |||
) : ( | |||
<BitbucketImportRepositoryForm |
@@ -21,7 +21,7 @@ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { SubmitButton } from 'sonar-ui-common/components/controls/buttons'; | |||
import { change, submit, waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { change, submit } from 'sonar-ui-common/helpers/testUtils'; | |||
import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; | |||
import { AlmKeys } from '../../../../types/alm-settings'; | |||
import BitbucketPersonalAccessTokenForm, { | |||
@@ -31,9 +31,10 @@ import BitbucketPersonalAccessTokenForm, { | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot('default'); | |||
expect(shallowRender({ submitting: true })).toMatchSnapshot('submitting'); | |||
expect(shallowRender({ validationFailed: true })).toMatchSnapshot('validation failed'); | |||
}); | |||
it('should correctly handle form interactions', async () => { | |||
it('should correctly handle form interactions', () => { | |||
const onPersonalAccessTokenCreate = jest.fn(); | |||
const wrapper = shallowRender({ onPersonalAccessTokenCreate }); | |||
@@ -46,8 +47,14 @@ it('should correctly handle form interactions', async () => { | |||
// Expect correct calls to be made when submitting. | |||
submit(wrapper.find('form')); | |||
await waitAndUpdate(wrapper); | |||
expect(onPersonalAccessTokenCreate).toBeCalled(); | |||
// If validation fails, we toggle the submitting flag and call useEffect() | |||
// to set the `touched` flag to false again. Trigger a re-render, and mock | |||
// useEffect(). This should de-activate the submit button again. | |||
jest.spyOn(React, 'useEffect').mockImplementationOnce(f => f()); | |||
wrapper.setProps({ submitting: false }); | |||
expect(wrapper.find(SubmitButton).prop('disabled')).toBe(true); | |||
}); | |||
function shallowRender(props: Partial<BitbucketPersonalAccessTokenFormProps> = {}) { | |||
@@ -58,6 +65,7 @@ function shallowRender(props: Partial<BitbucketPersonalAccessTokenFormProps> = { | |||
url: 'http://www.example.com' | |||
})} | |||
onPersonalAccessTokenCreate={jest.fn()} | |||
validationFailed={false} | |||
{...props} | |||
/> | |||
); |
@@ -92,10 +92,17 @@ it('should correctly handle an invalid PAT', async () => { | |||
expect(wrapper.state().patIsValid).toBe(false); | |||
}); | |||
it('should correctly handle setting a new PAT', () => { | |||
it('should correctly handle setting a new PAT', async () => { | |||
const wrapper = shallowRender(); | |||
wrapper.instance().handlePersonalAccessTokenCreate('token'); | |||
expect(setAlmPersonalAccessToken).toBeCalledWith('foo', 'token'); | |||
expect(wrapper.state().submittingToken).toBe(true); | |||
(checkPersonalAccessTokenIsValid as jest.Mock).mockResolvedValueOnce(false); | |||
await waitAndUpdate(wrapper); | |||
expect(checkPersonalAccessTokenIsValid).toBeCalled(); | |||
expect(wrapper.state().submittingToken).toBe(false); | |||
expect(wrapper.state().tokenValidationFailed).toBe(true); | |||
}); | |||
it('should correctly fetch projects and repos', async () => { |
@@ -60,6 +60,7 @@ function shallowRender(props: Partial<BitbucketProjectCreateRendererProps> = {}) | |||
projectRepositories={{ foo: { allShown: true, repositories: [mockBitbucketRepository()] } }} | |||
projects={[mockBitbucketProject({ key: 'foo' })]} | |||
searching={false} | |||
tokenValidationFailed={false} | |||
{...props} | |||
/> | |||
); |
@@ -56,7 +56,29 @@ exports[`should render correctly: no projects 1`] = ` | |||
className="spacer-top" | |||
variant="warning" | |||
> | |||
onboarding.create_project.no_bbs_projects | |||
<FormattedMessage | |||
defaultMessage="onboarding.create_project.no_bbs_projects" | |||
id="onboarding.create_project.no_bbs_projects" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/projects/create", | |||
"query": Object { | |||
"mode": "bbs", | |||
"resetPat": 1, | |||
}, | |||
} | |||
} | |||
> | |||
onboarding.create_project.update_your_token | |||
</Link>, | |||
} | |||
} | |||
/> | |||
</Alert> | |||
`; | |||
@@ -29,9 +29,9 @@ exports[`should render correctly: default 1`] = ` | |||
className="input-super-large" | |||
id="personal_access_token" | |||
minLength={1} | |||
name="personal_access_token" | |||
onChange={[Function]} | |||
type="text" | |||
value="" | |||
/> | |||
</ValidationInput> | |||
<SubmitButton | |||
@@ -141,9 +141,9 @@ exports[`should render correctly: submitting 1`] = ` | |||
className="input-super-large" | |||
id="personal_access_token" | |||
minLength={1} | |||
name="personal_access_token" | |||
onChange={[Function]} | |||
type="text" | |||
value="" | |||
/> | |||
</ValidationInput> | |||
<SubmitButton | |||
@@ -223,3 +223,116 @@ exports[`should render correctly: submitting 1`] = ` | |||
</Alert> | |||
</div> | |||
`; | |||
exports[`should render correctly: validation failed 1`] = ` | |||
<div | |||
className="display-flex-start" | |||
> | |||
<form | |||
onSubmit={[Function]} | |||
> | |||
<h2 | |||
className="big" | |||
> | |||
onboarding.create_project.grant_access_to_bbs.title | |||
</h2> | |||
<p | |||
className="big-spacer-top big-spacer-bottom" | |||
> | |||
onboarding.create_project.grant_access_to_bbs.help | |||
</p> | |||
<ValidationInput | |||
error="onboarding.create_project.pat_incorrect" | |||
id="personal_access_token" | |||
isInvalid={true} | |||
isValid={false} | |||
label="onboarding.create_project.enter_pat" | |||
required={true} | |||
> | |||
<input | |||
autoFocus={true} | |||
className="input-super-large is-invalid" | |||
id="personal_access_token" | |||
minLength={1} | |||
name="personal_access_token" | |||
onChange={[Function]} | |||
type="text" | |||
/> | |||
</ValidationInput> | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
save | |||
</SubmitButton> | |||
<DeferredSpinner | |||
className="spacer-left" | |||
loading={false} | |||
timeout={100} | |||
/> | |||
</form> | |||
<Alert | |||
className="big-spacer-left big-spacer-top" | |||
display="block" | |||
variant="info" | |||
> | |||
<h3> | |||
onboarding.create_project.pat_help.title | |||
</h3> | |||
<p | |||
className="big-spacer-top big-spacer-bottom" | |||
> | |||
onboarding.create_project.pat_help.bbs_help_1 | |||
</p> | |||
<div | |||
className="text-middle" | |||
> | |||
<img | |||
alt="" | |||
className="spacer-right" | |||
height="16" | |||
src="/images/alm/bitbucket.svg" | |||
/> | |||
<a | |||
href="http://www.example.com/plugins/servlet/access-tokens/add" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.create_project.pat_help.link | |||
</a> | |||
</div> | |||
<p | |||
className="big-spacer-top big-spacer-bottom" | |||
> | |||
onboarding.create_project.pat_help.bbs_help_2 | |||
</p> | |||
<ul> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage="onboarding.create_project.pat_help.bbs_permission_projects" | |||
id="onboarding.create_project.pat_help.bbs_permission_projects" | |||
values={ | |||
Object { | |||
"perm": <strong> | |||
onboarding.create_project.pat_help.read_permission | |||
</strong>, | |||
} | |||
} | |||
/> | |||
</li> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage="onboarding.create_project.pat_help.bbs_permission_repos" | |||
id="onboarding.create_project.pat_help.bbs_permission_repos" | |||
values={ | |||
Object { | |||
"perm": <strong> | |||
onboarding.create_project.pat_help.read_permission | |||
</strong>, | |||
} | |||
} | |||
/> | |||
</li> | |||
</ul> | |||
</Alert> | |||
</div> | |||
`; |
@@ -36,15 +36,12 @@ exports[`should render correctly: default 1`] = ` | |||
onCheck={[Function]} | |||
value="1" | |||
> | |||
<Tooltip | |||
overlay="Repo" | |||
<strong | |||
className="text-ellipsis" | |||
title="Repo" | |||
> | |||
<strong | |||
className="text-ellipsis" | |||
> | |||
Repo | |||
</strong> | |||
</Tooltip> | |||
Repo | |||
</strong> | |||
</Radio> | |||
<div | |||
className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo" | |||
@@ -61,27 +58,25 @@ exports[`should render correctly: default 1`] = ` | |||
<div | |||
className="little-spacer-bottom text-ellipsis" | |||
> | |||
<Tooltip | |||
overlay="Bar" | |||
<strong | |||
title="Bar" | |||
> | |||
<strong> | |||
<Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/dashboard", | |||
"query": Object { | |||
"branch": undefined, | |||
"id": "bar", | |||
}, | |||
} | |||
<Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/dashboard", | |||
"query": Object { | |||
"branch": undefined, | |||
"id": "bar", | |||
}, | |||
} | |||
> | |||
Bar | |||
</Link> | |||
</strong> | |||
</Tooltip> | |||
} | |||
> | |||
Bar | |||
</Link> | |||
</strong> | |||
</div> | |||
<em> | |||
onboarding.create_project.repository_imported | |||
@@ -114,15 +109,12 @@ exports[`should render correctly: disable options 1`] = ` | |||
onCheck={[Function]} | |||
value="1" | |||
> | |||
<Tooltip | |||
overlay="Repo" | |||
<strong | |||
className="text-ellipsis" | |||
title="Repo" | |||
> | |||
<strong | |||
className="text-ellipsis" | |||
> | |||
Repo | |||
</strong> | |||
</Tooltip> | |||
Repo | |||
</strong> | |||
</Radio> | |||
<div | |||
className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo" | |||
@@ -139,27 +131,25 @@ exports[`should render correctly: disable options 1`] = ` | |||
<div | |||
className="little-spacer-bottom text-ellipsis" | |||
> | |||
<Tooltip | |||
overlay="Bar" | |||
<strong | |||
title="Bar" | |||
> | |||
<strong> | |||
<Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/dashboard", | |||
"query": Object { | |||
"branch": undefined, | |||
"id": "bar", | |||
}, | |||
} | |||
<Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/dashboard", | |||
"query": Object { | |||
"branch": undefined, | |||
"id": "bar", | |||
}, | |||
} | |||
> | |||
Bar | |||
</Link> | |||
</strong> | |||
</Tooltip> | |||
} | |||
> | |||
Bar | |||
</Link> | |||
</strong> | |||
</div> | |||
<em> | |||
onboarding.create_project.repository_imported | |||
@@ -192,15 +182,12 @@ exports[`should render correctly: no click handler 1`] = ` | |||
onCheck={[Function]} | |||
value="1" | |||
> | |||
<Tooltip | |||
overlay="Repo" | |||
<strong | |||
className="text-ellipsis" | |||
title="Repo" | |||
> | |||
<strong | |||
className="text-ellipsis" | |||
> | |||
Repo | |||
</strong> | |||
</Tooltip> | |||
Repo | |||
</strong> | |||
</Radio> | |||
<div | |||
className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo" | |||
@@ -217,27 +204,25 @@ exports[`should render correctly: no click handler 1`] = ` | |||
<div | |||
className="little-spacer-bottom text-ellipsis" | |||
> | |||
<Tooltip | |||
overlay="Bar" | |||
<strong | |||
title="Bar" | |||
> | |||
<strong> | |||
<Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/dashboard", | |||
"query": Object { | |||
"branch": undefined, | |||
"id": "bar", | |||
}, | |||
} | |||
<Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/dashboard", | |||
"query": Object { | |||
"branch": undefined, | |||
"id": "bar", | |||
}, | |||
} | |||
> | |||
Bar | |||
</Link> | |||
</strong> | |||
</Tooltip> | |||
} | |||
> | |||
Bar | |||
</Link> | |||
</strong> | |||
</div> | |||
<em> | |||
onboarding.create_project.repository_imported | |||
@@ -266,7 +251,29 @@ exports[`should render correctly: no repos 1`] = ` | |||
<Alert | |||
variant="warning" | |||
> | |||
onboarding.create_project.no_bbs_repos | |||
<FormattedMessage | |||
defaultMessage="onboarding.create_project.no_bbs_repos" | |||
id="onboarding.create_project.no_bbs_repos" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/projects/create", | |||
"query": Object { | |||
"mode": "bbs", | |||
"resetPat": 1, | |||
}, | |||
} | |||
} | |||
> | |||
onboarding.create_project.update_your_token | |||
</Link>, | |||
} | |||
} | |||
/> | |||
</Alert> | |||
</div> | |||
</BoxedGroupAccordion> | |||
@@ -294,15 +301,12 @@ exports[`should render correctly: not showing all repos 1`] = ` | |||
onCheck={[Function]} | |||
value="1" | |||
> | |||
<Tooltip | |||
overlay="Repo" | |||
<strong | |||
className="text-ellipsis" | |||
title="Repo" | |||
> | |||
<strong | |||
className="text-ellipsis" | |||
> | |||
Repo | |||
</strong> | |||
</Tooltip> | |||
Repo | |||
</strong> | |||
</Radio> | |||
<div | |||
className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo" | |||
@@ -319,27 +323,25 @@ exports[`should render correctly: not showing all repos 1`] = ` | |||
<div | |||
className="little-spacer-bottom text-ellipsis" | |||
> | |||
<Tooltip | |||
overlay="Bar" | |||
<strong | |||
title="Bar" | |||
> | |||
<strong> | |||
<Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/dashboard", | |||
"query": Object { | |||
"branch": undefined, | |||
"id": "bar", | |||
}, | |||
} | |||
<Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/dashboard", | |||
"query": Object { | |||
"branch": undefined, | |||
"id": "bar", | |||
}, | |||
} | |||
> | |||
Bar | |||
</Link> | |||
</strong> | |||
</Tooltip> | |||
} | |||
> | |||
Bar | |||
</Link> | |||
</strong> | |||
</div> | |||
<em> | |||
onboarding.create_project.repository_imported | |||
@@ -377,15 +379,12 @@ exports[`should render correctly: selected repo 1`] = ` | |||
onCheck={[Function]} | |||
value="1" | |||
> | |||
<Tooltip | |||
overlay="Repo" | |||
<strong | |||
className="text-ellipsis" | |||
title="Repo" | |||
> | |||
<strong | |||
className="text-ellipsis" | |||
> | |||
Repo | |||
</strong> | |||
</Tooltip> | |||
Repo | |||
</strong> | |||
</Radio> | |||
<div | |||
className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo" | |||
@@ -402,27 +401,25 @@ exports[`should render correctly: selected repo 1`] = ` | |||
<div | |||
className="little-spacer-bottom text-ellipsis" | |||
> | |||
<Tooltip | |||
overlay="Bar" | |||
<strong | |||
title="Bar" | |||
> | |||
<strong> | |||
<Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/dashboard", | |||
"query": Object { | |||
"branch": undefined, | |||
"id": "bar", | |||
}, | |||
} | |||
<Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/dashboard", | |||
"query": Object { | |||
"branch": undefined, | |||
"id": "bar", | |||
}, | |||
} | |||
> | |||
Bar | |||
</Link> | |||
</strong> | |||
</Tooltip> | |||
} | |||
> | |||
Bar | |||
</Link> | |||
</strong> | |||
</div> | |||
<em> | |||
onboarding.create_project.repository_imported |
@@ -17,5 +17,6 @@ exports[`should render correctly 1`] = ` | |||
onSelectRepository={[Function]} | |||
searching={false} | |||
showPersonalAccessTokenForm={true} | |||
tokenValidationFailed={false} | |||
/> | |||
`; |
@@ -316,6 +316,7 @@ exports[`should render correctly: pat form 1`] = ` | |||
} | |||
} | |||
onPersonalAccessTokenCreate={[MockFunction]} | |||
validationFailed={false} | |||
/> | |||
</Fragment> | |||
`; |
@@ -3114,6 +3114,7 @@ onboarding.create_project.bbs_not_configured=This feature isn't available | |||
onboarding.create_project.no_bbs_binding=You must have exactly at least 1 Bitbucket Server instance configured in order to use this method, but none were found. Either create the project manually, or contact your system administrator. | |||
onboarding.create_project.no_bbs_binding.admin=You must have exactly at least 1 Bitbucket Server instance configured in order to use this method. You can configure instances under {url}. | |||
onboarding.create_project.enter_pat=Enter personal access token | |||
onboarding.create_project.pat_incorrect=Your personal access token failed to validate. | |||
onboarding.create_project.pat_help.title=How to create a personal access token? | |||
onboarding.create_project.pat_help.bbs_help_1=Click the following link to generate a token in Bitbucket Server, and copy-paste it into the personal access token field. | |||
onboarding.create_project.pat_help.bbs_help_2=Set a name, for example "SonarQube", and select the following permissions: | |||
@@ -3121,10 +3122,9 @@ onboarding.create_project.pat_help.link=Create personal access token | |||
onboarding.create_project.pat_help.bbs_permission_projects=Projects: {perm} | |||
onboarding.create_project.pat_help.bbs_permission_repos=Repositories: {perm} | |||
onboarding.create_project.pat_help.read_permission=Read | |||
onboarding.create_project.error_fetching_bbs_projects=There was an error fetching the projects from Bitbucket Server. Contact your system administrator, or check your personal access token. | |||
onboarding.create_project.error_fetching_bbs_repos=There was an error fetching the repositories from Bitbucket Server. Contact your system administrator, or check your personal access token. | |||
onboarding.create_project.no_bbs_projects=No projects could be fetched from Bitbucket Server. Contact your system administrator, or check your personal access token. | |||
onboarding.create_project.no_bbs_repos=No repositories were found for this project. Contact your system administrator, or check your personal access token. | |||
onboarding.create_project.no_bbs_projects=No projects could be fetched from Bitbucket Server. Contact your system administrator, or {link}. | |||
onboarding.create_project.no_bbs_repos=No repositories were found for this project. Contact your system administrator, or {link}. | |||
onboarding.create_project.update_your_token=update your personal access token | |||
onboarding.create_project.no_bbs_repos.filter=No repositories match your filter. | |||
onboarding.create_project.only_showing_X_first_repos=We're only displaying the first {0} repositories. If you're looking for a repository that's not in this list, use the search above. | |||
onboarding.create_project.import_selected_repo=Set up selected repository |