@@ -23,6 +23,7 @@ import java.util.Arrays; | |||
import java.util.List; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.config.Configuration; | |||
import org.sonar.api.config.PropertyDefinition; | |||
@@ -42,7 +43,7 @@ public class GitHubSettings { | |||
private static final String ORGANIZATIONS = "sonar.auth.github.organizations"; | |||
private static final String CATEGORY = "security"; | |||
private static final String CATEGORY = CoreProperties.CATEGORY_ALM_INTEGRATION; | |||
private static final String SUBCATEGORY = "github"; | |||
private final Configuration configuration; |
@@ -38,7 +38,7 @@ public class GitLabSettings { | |||
static final String GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP = "sonar.auth.gitlab.allowUsersToSignUp"; | |||
static final String GITLAB_AUTH_SYNC_USER_GROUPS = "sonar.auth.gitlab.groupsSync"; | |||
private static final String CATEGORY = CoreProperties.CATEGORY_SECURITY; | |||
private static final String CATEGORY = CoreProperties.CATEGORY_ALM_INTEGRATION; | |||
private static final String SUBCATEGORY = "gitlab"; | |||
private final Configuration configuration; |
@@ -152,6 +152,14 @@ th.hide-overflow { | |||
padding-top: calc(var(--gridSize) / 2) !important; | |||
} | |||
.big-padded-top { | |||
padding-top: calc(2 * var(--gridSize)); | |||
} | |||
.huge-padded-top { | |||
padding-top: 40px; | |||
} | |||
td.little-spacer-left { | |||
padding-left: 4px !important; | |||
} | |||
@@ -305,6 +313,10 @@ th.huge-spacer-right { | |||
width: 600px !important; | |||
} | |||
.abs-height-100 { | |||
height: 100% !important; | |||
} | |||
.max-height-100 { | |||
max-height: 100% !important; | |||
} |
@@ -22,11 +22,11 @@ import { Helmet } from 'react-helmet-async'; | |||
import { WithRouterProps } from 'react-router'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { addWhitePageClass, removeWhitePageClass } from 'sonar-ui-common/helpers/pages'; | |||
import { getAlmSettings } from '../../../api/almSettings'; | |||
import { getAlmSettings } from '../../../api/alm-settings'; | |||
import { whenLoggedIn } from '../../../components/hoc/whenLoggedIn'; | |||
import { withAppState } from '../../../components/hoc/withAppState'; | |||
import { getProjectUrl } from '../../../helpers/urls'; | |||
import { AlmSettingsInstance, ALM_KEYS } from '../../../types/alm-settings'; | |||
import { AlmKeys, AlmSettingsInstance } from '../../../types/alm-settings'; | |||
import BitbucketProjectCreate from './BitbucketProjectCreate'; | |||
import CreateProjectModeSelection from './CreateProjectModeSelection'; | |||
import ManualProjectCreate from './ManualProjectCreate'; | |||
@@ -81,7 +81,7 @@ export class CreateProjectPageSonarQube extends React.PureComponent<Props, State | |||
.then(almSettings => { | |||
if (this.mounted) { | |||
this.setState({ | |||
bitbucketSettings: almSettings.filter(s => s.alm === ALM_KEYS.BITBUCKET), | |||
bitbucketSettings: almSettings.filter(s => s.alm === AlmKeys.Bitbucket), | |||
loading: false | |||
}); | |||
} |
@@ -23,7 +23,7 @@ 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 { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; | |||
import { ALM_KEYS } from '../../../../types/alm-settings'; | |||
import { AlmKeys } from '../../../../types/alm-settings'; | |||
import BitbucketPersonalAccessTokenForm, { | |||
BitbucketPersonalAccessTokenFormProps | |||
} from '../BitbucketPersonalAccessTokenForm'; | |||
@@ -54,7 +54,7 @@ function shallowRender(props: Partial<BitbucketPersonalAccessTokenFormProps> = { | |||
return shallow<BitbucketPersonalAccessTokenFormProps>( | |||
<BitbucketPersonalAccessTokenForm | |||
bitbucketSetting={mockAlmSettingsInstance({ | |||
alm: ALM_KEYS.BITBUCKET, | |||
alm: AlmKeys.Bitbucket, | |||
url: 'http://www.example.com' | |||
})} | |||
onPersonalAccessTokenCreate={jest.fn()} |
@@ -31,7 +31,7 @@ import { | |||
import { mockBitbucketRepository } from '../../../../helpers/mocks/alm-integrations'; | |||
import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; | |||
import { mockLocation } from '../../../../helpers/testMocks'; | |||
import { ALM_KEYS } from '../../../../types/alm-settings'; | |||
import { AlmKeys } from '../../../../types/alm-settings'; | |||
import { BitbucketProjectCreate } from '../BitbucketProjectCreate'; | |||
jest.mock('../../../../api/alm-integrations', () => { | |||
@@ -129,7 +129,7 @@ it('should correctly import a repo', async () => { | |||
function shallowRender(props: Partial<BitbucketProjectCreate['props']> = {}) { | |||
return shallow<BitbucketProjectCreate>( | |||
<BitbucketProjectCreate | |||
bitbucketSettings={[mockAlmSettingsInstance({ alm: ALM_KEYS.BITBUCKET, key: 'foo' })]} | |||
bitbucketSettings={[mockAlmSettingsInstance({ alm: AlmKeys.Bitbucket, key: 'foo' })]} | |||
loadingBindings={false} | |||
location={mockLocation()} | |||
onProjectCreate={jest.fn()} |
@@ -25,7 +25,7 @@ import { | |||
mockBitbucketRepository | |||
} from '../../../../helpers/mocks/alm-integrations'; | |||
import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; | |||
import { ALM_KEYS } from '../../../../types/alm-settings'; | |||
import { AlmKeys } from '../../../../types/alm-settings'; | |||
import BitbucketProjectCreateRenderer, { | |||
BitbucketProjectCreateRendererProps | |||
} from '../BitbucketProjectCreateRenderer'; | |||
@@ -49,7 +49,7 @@ it('should render correctly', () => { | |||
function shallowRender(props: Partial<BitbucketProjectCreateRendererProps> = {}) { | |||
return shallow<BitbucketProjectCreateRendererProps>( | |||
<BitbucketProjectCreateRenderer | |||
bitbucketSetting={mockAlmSettingsInstance({ alm: ALM_KEYS.BITBUCKET })} | |||
bitbucketSetting={mockAlmSettingsInstance({ alm: AlmKeys.Bitbucket })} | |||
importing={false} | |||
loading={false} | |||
onImportRepository={jest.fn()} |
@@ -21,14 +21,14 @@ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { addWhitePageClass } from 'sonar-ui-common/helpers/pages'; | |||
import { getAlmSettings } from '../../../../api/almSettings'; | |||
import { getAlmSettings } from '../../../../api/alm-settings'; | |||
import { mockLocation, mockLoggedInUser, mockRouter } from '../../../../helpers/testMocks'; | |||
import { ALM_KEYS } from '../../../../types/alm-settings'; | |||
import { AlmKeys } from '../../../../types/alm-settings'; | |||
import { CreateProjectPageSonarQube } from '../CreateProjectPageSonarQube'; | |||
import { CreateProjectModes } from '../types'; | |||
jest.mock('../../../../api/almSettings', () => ({ | |||
getAlmSettings: jest.fn().mockResolvedValue([{ alm: ALM_KEYS.BITBUCKET, key: 'foo' }]) | |||
jest.mock('../../../../api/alm-settings', () => ({ | |||
getAlmSettings: jest.fn().mockResolvedValue([{ alm: AlmKeys.Bitbucket, key: 'foo' }]) | |||
})); | |||
jest.mock('sonar-ui-common/helpers/pages', () => ({ |
@@ -179,7 +179,7 @@ exports[`should render correctly: invalid config, admin user 1`] = ` | |||
Object { | |||
"pathname": "/admin/settings", | |||
"query": Object { | |||
"category": "pull_request_decoration", | |||
"category": "almintegration", | |||
}, | |||
} | |||
} |
@@ -20,16 +20,16 @@ | |||
import * as React from 'react'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { | |||
ALM_INTEGRATION, | |||
ANALYSIS_SCOPE_CATEGORY, | |||
LANGUAGES_CATEGORY, | |||
NEW_CODE_PERIOD_CATEGORY, | |||
PULL_REQUEST_DECORATION_BINDING_CATEGORY, | |||
PULL_REQUEST_DECORATION_CATEGORY | |||
PULL_REQUEST_DECORATION_BINDING_CATEGORY | |||
} from './AdditionalCategoryKeys'; | |||
import AlmIntegration from './almIntegration/AlmIntegration'; | |||
import { AnalysisScope } from './AnalysisScope'; | |||
import Languages from './Languages'; | |||
import NewCodePeriod from './NewCodePeriod'; | |||
import PullRequestDecoration from './pullRequestDecoration/PullRequestDecoration'; | |||
import PullRequestDecorationBinding from './pullRequestDecorationBinding/PRDecorationBinding'; | |||
export interface AdditionalCategoryComponentProps { | |||
@@ -73,13 +73,12 @@ export const ADDITIONAL_CATEGORIES: AdditionalCategory[] = [ | |||
displayTab: false | |||
}, | |||
{ | |||
key: PULL_REQUEST_DECORATION_CATEGORY, | |||
name: translate('settings.pr_decoration.category'), | |||
renderComponent: getPullRequestDecorationComponent, | |||
key: ALM_INTEGRATION, | |||
name: translate('property.category.almintegration'), | |||
renderComponent: getAlmIntegrationComponent, | |||
availableGlobally: true, | |||
availableForProject: false, | |||
displayTab: true, | |||
requiresBranchesEnabled: true | |||
displayTab: false | |||
}, | |||
{ | |||
key: PULL_REQUEST_DECORATION_BINDING_CATEGORY, | |||
@@ -104,8 +103,8 @@ function getAnalysisScopeComponent(props: AdditionalCategoryComponentProps) { | |||
return <AnalysisScope {...props} />; | |||
} | |||
function getPullRequestDecorationComponent() { | |||
return <PullRequestDecoration />; | |||
function getAlmIntegrationComponent(props: AdditionalCategoryComponentProps) { | |||
return <AlmIntegration {...props} />; | |||
} | |||
function getPullRequestDecorationBindingComponent(props: AdditionalCategoryComponentProps) { |
@@ -17,8 +17,8 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
export const ALM_INTEGRATION = 'almintegration'; | |||
export const ANALYSIS_SCOPE_CATEGORY = 'exclusions'; | |||
export const LANGUAGES_CATEGORY = 'languages'; | |||
export const NEW_CODE_PERIOD_CATEGORY = 'new_code_period'; | |||
export const PULL_REQUEST_DECORATION_CATEGORY = 'pull_request_decoration'; | |||
export const PULL_REQUEST_DECORATION_BINDING_CATEGORY = 'pull_request_decoration_binding'; |
@@ -28,6 +28,7 @@ interface Props { | |||
component?: T.Component; | |||
fetchValues: Function; | |||
settings: Array<T.Setting & { definition: T.SettingCategoryDefinition }>; | |||
subCategory?: string; | |||
} | |||
export default class SubCategoryDefinitionsList extends React.PureComponent<Props> { | |||
@@ -66,9 +67,12 @@ export default class SubCategoryDefinitionsList extends React.PureComponent<Prop | |||
const sortedSubCategories = sortBy(subCategories, subCategory => | |||
subCategory.name.toLowerCase() | |||
); | |||
const filteredSubCategories = this.props.subCategory | |||
? sortedSubCategories.filter(c => c.key === this.props.subCategory) | |||
: sortedSubCategories; | |||
return ( | |||
<ul className="settings-sub-categories-list"> | |||
{sortedSubCategories.map(subCategory => ( | |||
{filteredSubCategories.map(subCategory => ( | |||
<li key={subCategory.key}> | |||
<h2 className="settings-sub-category-name">{subCategory.name}</h2> | |||
{subCategory.description != null && ( |
@@ -22,11 +22,11 @@ import * as React from 'react'; | |||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { mockLocation, mockRouter } from '../../../../helpers/testMocks'; | |||
import { | |||
ALM_INTEGRATION, | |||
ANALYSIS_SCOPE_CATEGORY, | |||
LANGUAGES_CATEGORY, | |||
NEW_CODE_PERIOD_CATEGORY, | |||
PULL_REQUEST_DECORATION_BINDING_CATEGORY, | |||
PULL_REQUEST_DECORATION_CATEGORY | |||
PULL_REQUEST_DECORATION_BINDING_CATEGORY | |||
} from '../AdditionalCategoryKeys'; | |||
import { App } from '../AppContainer'; | |||
@@ -64,9 +64,9 @@ it('should render analysis scope correctly', async () => { | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
it('should render pull request decoration correctly', async () => { | |||
it('should render ALM integration correctly', async () => { | |||
const wrapper = shallowRender({ | |||
location: mockLocation({ query: { category: PULL_REQUEST_DECORATION_CATEGORY } }) | |||
location: mockLocation({ query: { category: ALM_INTEGRATION } }) | |||
}); | |||
await waitAndUpdate(wrapper); |
@@ -60,7 +60,34 @@ exports[`should render additional categories component correctly 3`] = ` | |||
/> | |||
`; | |||
exports[`should render additional categories component correctly 4`] = `<PullRequestDecoration />`; | |||
exports[`should render additional categories component correctly 4`] = ` | |||
<Connect(withAppState(AlmIntegration)) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
selectedCategory="TEST" | |||
/> | |||
`; | |||
exports[`should render additional categories component correctly 5`] = ` | |||
<PRDecorationBinding |
@@ -1,6 +1,6 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render analysis scope correctly 1`] = ` | |||
exports[`should render ALM integration correctly 1`] = ` | |||
<div | |||
className="page page-limited" | |||
id="settings-page" | |||
@@ -22,21 +22,21 @@ exports[`should render analysis scope correctly 1`] = ` | |||
> | |||
<Connect(CategoriesList) | |||
defaultCategory="general" | |||
selectedCategory="exclusions" | |||
selectedCategory="almintegration" | |||
/> | |||
</div> | |||
<div | |||
className="side-tabs-main" | |||
> | |||
<AnalysisScope | |||
selectedCategory="exclusions" | |||
<Connect(withAppState(AlmIntegration)) | |||
selectedCategory="almintegration" | |||
/> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render default view correctly 1`] = ` | |||
exports[`should render analysis scope correctly 1`] = ` | |||
<div | |||
className="page page-limited" | |||
id="settings-page" | |||
@@ -58,21 +58,21 @@ exports[`should render default view correctly 1`] = ` | |||
> | |||
<Connect(CategoriesList) | |||
defaultCategory="general" | |||
selectedCategory="general" | |||
selectedCategory="exclusions" | |||
/> | |||
</div> | |||
<div | |||
className="side-tabs-main" | |||
> | |||
<Connect(SubCategoryDefinitionsList) | |||
category="general" | |||
<AnalysisScope | |||
selectedCategory="exclusions" | |||
/> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render languages correctly 1`] = ` | |||
exports[`should render default view correctly 1`] = ` | |||
<div | |||
className="page page-limited" | |||
id="settings-page" | |||
@@ -94,21 +94,21 @@ exports[`should render languages correctly 1`] = ` | |||
> | |||
<Connect(CategoriesList) | |||
defaultCategory="general" | |||
selectedCategory="languages" | |||
selectedCategory="general" | |||
/> | |||
</div> | |||
<div | |||
className="side-tabs-main" | |||
> | |||
<withRouter(Connect(Languages)) | |||
selectedCategory="languages" | |||
<Connect(SubCategoryDefinitionsList) | |||
category="general" | |||
/> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render newCodePeriod correctly 1`] = ` | |||
exports[`should render languages correctly 1`] = ` | |||
<div | |||
className="page page-limited" | |||
id="settings-page" | |||
@@ -130,19 +130,21 @@ exports[`should render newCodePeriod correctly 1`] = ` | |||
> | |||
<Connect(CategoriesList) | |||
defaultCategory="general" | |||
selectedCategory="new_code_period" | |||
selectedCategory="languages" | |||
/> | |||
</div> | |||
<div | |||
className="side-tabs-main" | |||
> | |||
<NewCodePeriod /> | |||
<withRouter(Connect(Languages)) | |||
selectedCategory="languages" | |||
/> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render pull request decoration binding correctly 1`] = ` | |||
exports[`should render newCodePeriod correctly 1`] = ` | |||
<div | |||
className="page page-limited" | |||
id="settings-page" | |||
@@ -164,21 +166,19 @@ exports[`should render pull request decoration binding correctly 1`] = ` | |||
> | |||
<Connect(CategoriesList) | |||
defaultCategory="general" | |||
selectedCategory="pull_request_decoration_binding" | |||
selectedCategory="new_code_period" | |||
/> | |||
</div> | |||
<div | |||
className="side-tabs-main" | |||
> | |||
<Connect(SubCategoryDefinitionsList) | |||
category="pull_request_decoration_binding" | |||
/> | |||
<NewCodePeriod /> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render pull request decoration correctly 1`] = ` | |||
exports[`should render pull request decoration binding correctly 1`] = ` | |||
<div | |||
className="page page-limited" | |||
id="settings-page" | |||
@@ -200,13 +200,15 @@ exports[`should render pull request decoration correctly 1`] = ` | |||
> | |||
<Connect(CategoriesList) | |||
defaultCategory="general" | |||
selectedCategory="pull_request_decoration" | |||
selectedCategory="pull_request_decoration_binding" | |||
/> | |||
</div> | |||
<div | |||
className="side-tabs-main" | |||
> | |||
<PullRequestDecoration /> | |||
<Connect(SubCategoryDefinitionsList) | |||
category="pull_request_decoration_binding" | |||
/> | |||
</div> | |||
</div> | |||
</div> |
@@ -19,11 +19,11 @@ | |||
*/ | |||
import { isEqual, omit } from 'lodash'; | |||
import * as React from 'react'; | |||
import { AlmSettingsBinding, ALM_KEYS } from '../../../../types/alm-settings'; | |||
import AlmPRDecorationFormModalRenderer from './AlmPRDecorationFormModalRenderer'; | |||
import AlmPRDecorationFormRenderer from './AlmPRDecorationFormRenderer'; | |||
import { AlmBindingDefinition } from '../../../../types/alm-settings'; | |||
import AlmBindingDefinitionFormModalRenderer from './AlmBindingDefinitionFormModalRenderer'; | |||
import AlmBindingDefinitionFormRenderer from './AlmBindingDefinitionFormRenderer'; | |||
export interface AlmPRDecorationFormChildrenProps<B> { | |||
export interface AlmBindingDefinitionFormChildrenProps<B> { | |||
formData: B; | |||
hideKeyField?: boolean; | |||
onFieldChange: (fieldId: keyof B, value: string) => void; | |||
@@ -31,9 +31,8 @@ export interface AlmPRDecorationFormChildrenProps<B> { | |||
} | |||
interface Props<B> { | |||
alm: ALM_KEYS; | |||
bindingDefinition: B; | |||
children: (props: AlmPRDecorationFormChildrenProps<B>) => React.ReactNode; | |||
children: (props: AlmBindingDefinitionFormChildrenProps<B>) => React.ReactNode; | |||
help?: React.ReactNode; | |||
hideKeyField?: boolean; | |||
loading?: boolean; | |||
@@ -51,10 +50,9 @@ interface State<B> { | |||
touched: boolean; | |||
} | |||
export default class AlmPRDecorationForm<B extends AlmSettingsBinding> extends React.PureComponent< | |||
Props<B>, | |||
State<B> | |||
> { | |||
export default class AlmBindingDefinitionForm< | |||
B extends AlmBindingDefinition | |||
> extends React.PureComponent<Props<B>, State<B>> { | |||
constructor(props: Props<B>) { | |||
super(props); | |||
this.state = { formData: props.bindingDefinition, touched: false }; | |||
@@ -115,7 +113,6 @@ export default class AlmPRDecorationForm<B extends AlmSettingsBinding> extends R | |||
render() { | |||
const { | |||
alm, | |||
bindingDefinition, | |||
children, | |||
help, | |||
@@ -132,9 +129,8 @@ export default class AlmPRDecorationForm<B extends AlmSettingsBinding> extends R | |||
const showDelete = showEdit && this.props.onDelete !== undefined; | |||
return showInModal ? ( | |||
<AlmPRDecorationFormModalRenderer | |||
<AlmBindingDefinitionFormModalRenderer | |||
action={bindingDefinition.key ? 'edit' : 'create'} | |||
alm={alm} | |||
canSubmit={this.canSubmit} | |||
help={help} | |||
onCancel={this.handleCancel} | |||
@@ -143,9 +139,9 @@ export default class AlmPRDecorationForm<B extends AlmSettingsBinding> extends R | |||
formData, | |||
onFieldChange: this.handleFieldChange | |||
})} | |||
</AlmPRDecorationFormModalRenderer> | |||
</AlmBindingDefinitionFormModalRenderer> | |||
) : ( | |||
<AlmPRDecorationFormRenderer | |||
<AlmBindingDefinitionFormRenderer | |||
canSubmit={this.canSubmit} | |||
help={help} | |||
loading={loading} | |||
@@ -160,7 +156,7 @@ export default class AlmPRDecorationForm<B extends AlmSettingsBinding> extends R | |||
onFieldChange: this.handleFieldChange, | |||
readOnly | |||
})} | |||
</AlmPRDecorationFormRenderer> | |||
</AlmBindingDefinitionFormRenderer> | |||
); | |||
} | |||
} |
@@ -20,9 +20,9 @@ | |||
import * as React from 'react'; | |||
import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { AlmSettingsBinding } from '../../../../types/alm-settings'; | |||
import { AlmBindingDefinition } from '../../../../types/alm-settings'; | |||
export interface AlmDefinitionFormFieldProps<B extends AlmSettingsBinding> { | |||
export interface AlmBindingDefinitionFormFieldProps<B extends AlmBindingDefinition> { | |||
autoFocus?: boolean; | |||
help?: React.ReactNode; | |||
id: string; | |||
@@ -34,8 +34,8 @@ export interface AlmDefinitionFormFieldProps<B extends AlmSettingsBinding> { | |||
value: string; | |||
} | |||
export function AlmDefinitionFormField<B extends AlmSettingsBinding>( | |||
props: AlmDefinitionFormFieldProps<B> | |||
export function AlmBindingDefinitionFormField<B extends AlmBindingDefinition>( | |||
props: AlmBindingDefinitionFormFieldProps<B> | |||
) { | |||
const { | |||
autoFocus, | |||
@@ -52,7 +52,7 @@ export function AlmDefinitionFormField<B extends AlmSettingsBinding>( | |||
return ( | |||
<div className="modal-field"> | |||
<label className="display-flex-center" htmlFor={id}> | |||
{translate('settings.pr_decoration.form', id)} | |||
{translate('settings.almintegration.form', id)} | |||
<em className="mandatory spacer-right">*</em> | |||
{help && <HelpTooltip overlay={help} placement="right" />} | |||
</label> |
@@ -23,11 +23,9 @@ import SimpleModal from 'sonar-ui-common/components/controls/SimpleModal'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { ALM_KEYS } from '../../../../types/alm-settings'; | |||
export interface AlmPRDecorationFormModalProps { | |||
export interface AlmBindingDefinitionFormModalProps { | |||
action: 'edit' | 'create'; | |||
alm: ALM_KEYS; | |||
canSubmit: () => boolean; | |||
children: React.ReactNode; | |||
help?: React.ReactNode; | |||
@@ -35,14 +33,11 @@ export interface AlmPRDecorationFormModalProps { | |||
onSubmit: () => void; | |||
} | |||
export default function AlmPRDecorationFormModalRenderer(props: AlmPRDecorationFormModalProps) { | |||
const { alm, action, children, help } = props; | |||
const header = translate( | |||
'settings', | |||
alm === ALM_KEYS.GITLAB ? 'mr_decoration' : 'pr_decoration', | |||
'form.header', | |||
action | |||
); | |||
export default function AlmBindingDefinitionFormModalRenderer( | |||
props: AlmBindingDefinitionFormModalProps | |||
) { | |||
const { action, children, help } = props; | |||
const header = translate('settings.almintegration.form.header', action); | |||
return ( | |||
<SimpleModal header={header} onClose={props.onCancel} onSubmit={props.onSubmit} size="medium"> | |||
@@ -53,18 +48,21 @@ export default function AlmPRDecorationFormModalRenderer(props: AlmPRDecorationF | |||
</div> | |||
<div className="modal-body modal-container"> | |||
{help && ( | |||
<Alert className="big-spacer-bottom" variant="info"> | |||
{help} | |||
</Alert> | |||
)} | |||
{children} | |||
<div className="display-flex-start"> | |||
<div className="flex-1">{children}</div> | |||
{help && ( | |||
<Alert className="huge-spacer-left flex-1" variant="info"> | |||
{help} | |||
</Alert> | |||
)} | |||
</div> | |||
</div> | |||
<div className="modal-foot"> | |||
<DeferredSpinner className="spacer-right" loading={submitting} /> | |||
<SubmitButton disabled={submitting || !props.canSubmit()}> | |||
{translate('settings.pr_decoration.form.save')} | |||
{translate('settings.almintegration.form.save')} | |||
</SubmitButton> | |||
<ResetButtonLink onClick={onCloseClick}>{translate('cancel')}</ResetButtonLink> | |||
</div> |
@@ -24,7 +24,7 @@ import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
export interface AlmPRDecorationFormRendererProps { | |||
export interface AlmBindingDefinitionFormRendererProps { | |||
canSubmit: () => boolean; | |||
children: React.ReactNode; | |||
help?: React.ReactNode; | |||
@@ -36,7 +36,9 @@ export interface AlmPRDecorationFormRendererProps { | |||
success: boolean; | |||
} | |||
export default function AlmPRDecorationFormRenderer(props: AlmPRDecorationFormRendererProps) { | |||
export default function AlmBindingDefinitionFormRenderer( | |||
props: AlmBindingDefinitionFormRendererProps | |||
) { | |||
const { children, help, loading, success } = props; | |||
return ( | |||
@@ -47,40 +49,47 @@ export default function AlmPRDecorationFormRenderer(props: AlmPRDecorationFormRe | |||
e.preventDefault(); | |||
props.onSubmit(); | |||
}}> | |||
{help && ( | |||
<Alert className="big-spacer-bottom" variant="info"> | |||
{help} | |||
</Alert> | |||
)} | |||
<div className="display-flex-start"> | |||
<div className="flex-1"> | |||
{children} | |||
{children} | |||
<div className="display-flex-center"> | |||
{props.onEdit === undefined ? ( | |||
<SubmitButton disabled={loading || !props.canSubmit()}> | |||
{translate('settings.almintegration.form.save')} | |||
</SubmitButton> | |||
) : ( | |||
<Button disabled={loading} onClick={props.onEdit}> | |||
{translate('edit')} | |||
</Button> | |||
)} | |||
{props.onDelete && ( | |||
<Button | |||
className="button-red spacer-left" | |||
disabled={loading} | |||
onClick={props.onDelete}> | |||
{translate('delete')} | |||
</Button> | |||
)} | |||
{props.onCancel && ( | |||
<ResetButtonLink className="spacer-left" onClick={props.onCancel}> | |||
{translate('cancel')} | |||
</ResetButtonLink> | |||
)} | |||
{loading && <DeferredSpinner className="spacer-left" />} | |||
{!loading && success && ( | |||
<span className="text-success spacer-left"> | |||
<AlertSuccessIcon className="spacer-right" /> | |||
{translate('settings.state.saved')} | |||
</span> | |||
)} | |||
</div> | |||
</div> | |||
<div className="display-flex-center"> | |||
{props.onEdit === undefined ? ( | |||
<SubmitButton disabled={loading || !props.canSubmit()}> | |||
{translate('settings.pr_decoration.form.save')} | |||
</SubmitButton> | |||
) : ( | |||
<Button disabled={loading} onClick={props.onEdit}> | |||
{translate('edit')} | |||
</Button> | |||
)} | |||
{props.onDelete && ( | |||
<Button className="button-red spacer-left" disabled={loading} onClick={props.onDelete}> | |||
{translate('delete')} | |||
</Button> | |||
)} | |||
{props.onCancel && ( | |||
<ResetButtonLink className="spacer-left" onClick={props.onCancel}> | |||
{translate('cancel')} | |||
</ResetButtonLink> | |||
)} | |||
{loading && <DeferredSpinner className="spacer-left" />} | |||
{!loading && success && ( | |||
<span className="text-success spacer-left"> | |||
<AlertSuccessIcon className="spacer-right" /> | |||
{translate('settings.state.saved')} | |||
</span> | |||
{help && ( | |||
<Alert className="huge-spacer-left flex-1" variant="info"> | |||
{help} | |||
</Alert> | |||
)} | |||
</div> | |||
</form> |
@@ -21,11 +21,12 @@ import * as React from 'react'; | |||
import { Button, ButtonIcon, DeleteButton } from 'sonar-ui-common/components/controls/buttons'; | |||
import EditIcon from 'sonar-ui-common/components/icons/EditIcon'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { ALM_KEYS } from '../../../../types/alm-settings'; | |||
import { AlmKeys } from '../../../../types/alm-settings'; | |||
export interface AlmPRDecorationTableProps { | |||
export interface AlmBindingDefinitionsTableProps { | |||
additionalColumnsHeaders: Array<string>; | |||
alm: ALM_KEYS; | |||
additionalTableInfo?: React.ReactNode; | |||
alm: AlmKeys; | |||
definitions: Array<{ | |||
key: string; | |||
additionalColumns: Array<string>; | |||
@@ -35,36 +36,34 @@ export interface AlmPRDecorationTableProps { | |||
onEdit: (definitionKey: string) => void; | |||
} | |||
export default function AlmPRDecorationTable(props: AlmPRDecorationTableProps) { | |||
const { additionalColumnsHeaders, alm, definitions } = props; | |||
export default function AlmBindingDefinitionsTable(props: AlmBindingDefinitionsTableProps) { | |||
const { additionalColumnsHeaders, additionalTableInfo, alm, definitions } = props; | |||
return ( | |||
<> | |||
<div className="spacer-top big-spacer-bottom display-flex-space-between"> | |||
<h4 className="display-inline"> | |||
{translate( | |||
'settings', | |||
alm === ALM_KEYS.GITLAB ? 'mr_decoration' : 'pr_decoration', | |||
'table.title' | |||
)} | |||
</h4> | |||
<h2 className="settings-sub-category-name"> | |||
{translate('settings.almintegration.table.title')} | |||
</h2> | |||
<Button data-test="settings__alm-create" onClick={props.onCreate}> | |||
{translate('settings.pr_decoration.table.create')} | |||
{translate('settings.almintegration.table.create')} | |||
</Button> | |||
</div> | |||
{additionalTableInfo} | |||
<table className="data zebra fixed spacer-bottom"> | |||
<thead> | |||
<tr> | |||
<th>{translate('settings.pr_decoration.table.column.name')}</th> | |||
<th>{translate('settings.almintegration.table.column.name')}</th> | |||
{additionalColumnsHeaders.map(h => ( | |||
<th key={h}>{h}</th> | |||
))} | |||
<th className="action-small text-center"> | |||
{translate('settings.pr_decoration.table.column.edit')} | |||
{translate('settings.almintegration.table.column.edit')} | |||
</th> | |||
<th className="action text-center"> | |||
{translate('settings.pr_decoration.table.column.delete')} | |||
{translate('settings.almintegration.table.column.delete')} | |||
</th> | |||
</tr> | |||
</thead> | |||
@@ -72,7 +71,7 @@ export default function AlmPRDecorationTable(props: AlmPRDecorationTableProps) { | |||
{definitions.length === 0 ? ( | |||
<tr data-test="settings__alm-empty-table"> | |||
<td colSpan={3 + additionalColumnsHeaders.length}> | |||
{translate('settings.pr_decoration.table.empty', alm)} | |||
{translate('settings.almintegration.table.empty', alm)} | |||
</td> | |||
</tr> | |||
) : ( |
@@ -22,27 +22,33 @@ import { | |||
countBindedProjects, | |||
deleteConfiguration, | |||
getAlmDefinitions | |||
} from '../../../../api/almSettings'; | |||
import { AlmSettingsBindingDefinitions, ALM_KEYS } from '../../../../types/alm-settings'; | |||
import PRDecorationTabs from './PRDecorationTabs'; | |||
} from '../../../../api/alm-settings'; | |||
import { withAppState } from '../../../../components/hoc/withAppState'; | |||
import { AlmKeys, AlmSettingsBindingDefinitions } from '../../../../types/alm-settings'; | |||
import AlmIntegrationRenderer from './AlmIntegrationRenderer'; | |||
interface Props { | |||
appState: Pick<T.AppState, 'branchesEnabled' | 'multipleAlmEnabled'>; | |||
component?: T.Component; | |||
} | |||
interface State { | |||
currentAlm: ALM_KEYS; | |||
currentAlm: AlmKeys; | |||
definitionKeyForDeletion?: string; | |||
definitions: AlmSettingsBindingDefinitions; | |||
loading: boolean; | |||
projectCount?: number; | |||
} | |||
export default class PullRequestDecoration extends React.PureComponent<{}, State> { | |||
export class AlmIntegration extends React.PureComponent<Props, State> { | |||
mounted = false; | |||
state: State = { | |||
currentAlm: ALM_KEYS.GITHUB, | |||
currentAlm: AlmKeys.GitHub, | |||
definitions: { | |||
[ALM_KEYS.AZURE]: [], | |||
[ALM_KEYS.BITBUCKET]: [], | |||
[ALM_KEYS.GITHUB]: [], | |||
[ALM_KEYS.GITLAB]: [] | |||
[AlmKeys.Azure]: [], | |||
[AlmKeys.Bitbucket]: [], | |||
[AlmKeys.GitHub]: [], | |||
[AlmKeys.GitLab]: [] | |||
}, | |||
loading: true | |||
}; | |||
@@ -67,6 +73,14 @@ export default class PullRequestDecoration extends React.PureComponent<{}, State | |||
}; | |||
fetchPullRequestDecorationSetting = () => { | |||
const { | |||
appState: { branchesEnabled } | |||
} = this.props; | |||
if (!branchesEnabled) { | |||
return Promise.resolve(); | |||
} | |||
this.setState({ loading: true }); | |||
return getAlmDefinitions() | |||
.then(definitions => { | |||
@@ -84,7 +98,7 @@ export default class PullRequestDecoration extends React.PureComponent<{}, State | |||
}); | |||
}; | |||
handleSelectAlm = (currentAlm: ALM_KEYS) => { | |||
handleSelectAlm = (currentAlm: AlmKeys) => { | |||
this.setState({ currentAlm }); | |||
}; | |||
@@ -112,8 +126,15 @@ export default class PullRequestDecoration extends React.PureComponent<{}, State | |||
}; | |||
render() { | |||
const { | |||
appState: { branchesEnabled, multipleAlmEnabled }, | |||
component | |||
} = this.props; | |||
return ( | |||
<PRDecorationTabs | |||
<AlmIntegrationRenderer | |||
branchesEnabled={Boolean(branchesEnabled)} | |||
component={component} | |||
multipleAlmEnabled={Boolean(multipleAlmEnabled)} | |||
onCancel={this.handleCancel} | |||
onConfirmDelete={this.deleteConfiguration} | |||
onDelete={this.handleDelete} | |||
@@ -124,3 +145,5 @@ export default class PullRequestDecoration extends React.PureComponent<{}, State | |||
); | |||
} | |||
} | |||
export default withAppState(AlmIntegration); |
@@ -0,0 +1,67 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 classNames from 'classnames'; | |||
import * as React from 'react'; | |||
import CheckIcon from 'sonar-ui-common/components/icons/CheckIcon'; | |||
import ClearIcon from 'sonar-ui-common/components/icons/ClearIcon'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { colors } from '../../../../app/theme'; | |||
export interface AlmIntegrationFeatureBoxProps { | |||
active: boolean; | |||
description: React.ReactNode; | |||
inactiveReason?: React.ReactNode; | |||
name: React.ReactNode; | |||
} | |||
export default function AlmIntegrationFeatureBox(props: AlmIntegrationFeatureBoxProps) { | |||
const { active, description, inactiveReason, name } = props; | |||
return ( | |||
<div | |||
className={classNames( | |||
'boxed-group-inner display-flex-start width-30 spacer-right spacer-bottom bordered', | |||
{ | |||
'bg-muted': !active | |||
} | |||
)}> | |||
{active ? ( | |||
<CheckIcon className="little-spacer-top spacer-right" fill={colors.green} /> | |||
) : ( | |||
<ClearIcon className="little-spacer-top spacer-right" fill={colors.gray60} /> | |||
)} | |||
<div className="display-flex-column abs-height-100"> | |||
<h4>{name}</h4> | |||
<div className="spacer-top flex-1">{description}</div> | |||
<div className="spacer-top"> | |||
{active ? ( | |||
<em className="text-success">{translate('settings.almintegration.feature.enabled')}</em> | |||
) : ( | |||
<em className="text-muted"> | |||
{inactiveReason || translate('settings.almintegration.feature.disabled')} | |||
</em> | |||
)} | |||
</div> | |||
</div> | |||
</div> | |||
); | |||
} |
@@ -0,0 +1,185 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 BoxedTabs from 'sonar-ui-common/components/controls/BoxedTabs'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { getBaseUrl } from 'sonar-ui-common/helpers/urls'; | |||
import { AlmKeys, AlmSettingsBindingDefinitions } from '../../../../types/alm-settings'; | |||
import AzureTab from './AzureTab'; | |||
import BitbucketTab from './BitbucketTab'; | |||
import DeleteModal from './DeleteModal'; | |||
import GithubTab from './GithubTab'; | |||
import GitlabTab from './GitlabTab'; | |||
export interface AlmIntegrationRendererProps { | |||
branchesEnabled: boolean; | |||
component?: T.Component; | |||
currentAlm: AlmKeys; | |||
definitionKeyForDeletion?: string; | |||
definitions: AlmSettingsBindingDefinitions; | |||
loading: boolean; | |||
multipleAlmEnabled: boolean; | |||
onCancel: () => void; | |||
onConfirmDelete: (definitionKey: string) => void; | |||
onDelete: (definitionKey: string) => void; | |||
onSelectAlm: (alm: AlmKeys) => void; | |||
onUpdateDefinitions: () => void; | |||
projectCount?: number; | |||
} | |||
const tabs = [ | |||
{ | |||
key: AlmKeys.GitHub, | |||
label: ( | |||
<> | |||
<img | |||
alt="github" | |||
className="spacer-right" | |||
height={16} | |||
src={`${getBaseUrl()}/images/alm/github.svg`} | |||
/> | |||
GitHub | |||
</> | |||
) | |||
}, | |||
{ | |||
key: AlmKeys.Bitbucket, | |||
label: ( | |||
<> | |||
<img | |||
alt="bitbucket" | |||
className="spacer-right" | |||
height={16} | |||
src={`${getBaseUrl()}/images/alm/bitbucket.svg`} | |||
/> | |||
Bitbucket Server | |||
</> | |||
), | |||
requiresBranchesEnabled: true | |||
}, | |||
{ | |||
key: AlmKeys.Azure, | |||
label: ( | |||
<> | |||
<img | |||
alt="azure" | |||
className="spacer-right" | |||
height={16} | |||
src={`${getBaseUrl()}/images/alm/azure.svg`} | |||
/> | |||
Azure DevOps Server | |||
</> | |||
), | |||
requiresBranchesEnabled: true | |||
}, | |||
{ | |||
key: AlmKeys.GitLab, | |||
label: ( | |||
<> | |||
<img | |||
alt="gitlab" | |||
className="spacer-right" | |||
height={16} | |||
src={`${getBaseUrl()}/images/alm/gitlab.svg`} | |||
/> | |||
GitLab | |||
</> | |||
) | |||
} | |||
]; | |||
export default function AlmIntegrationRenderer(props: AlmIntegrationRendererProps) { | |||
const { | |||
component, | |||
definitionKeyForDeletion, | |||
definitions, | |||
currentAlm, | |||
loading, | |||
branchesEnabled, | |||
multipleAlmEnabled, | |||
projectCount | |||
} = props; | |||
return ( | |||
<> | |||
<header className="page-header"> | |||
<h1 className="page-title">{translate('settings.almintegration.title')}</h1> | |||
</header> | |||
<div className="markdown small spacer-top big-spacer-bottom"> | |||
{translate('settings.almintegration.description')} | |||
</div> | |||
<BoxedTabs | |||
onSelect={props.onSelectAlm} | |||
selected={currentAlm} | |||
tabs={tabs.filter(tab => !(tab.requiresBranchesEnabled && !branchesEnabled))} | |||
/> | |||
{currentAlm === AlmKeys.Azure && ( | |||
<AzureTab | |||
definitions={definitions.azure} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
/> | |||
)} | |||
{currentAlm === AlmKeys.Bitbucket && ( | |||
<BitbucketTab | |||
definitions={definitions.bitbucket} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
/> | |||
)} | |||
{currentAlm === AlmKeys.GitHub && ( | |||
<GithubTab | |||
branchesEnabled={branchesEnabled} | |||
component={component} | |||
definitions={definitions.github} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
/> | |||
)} | |||
{currentAlm === AlmKeys.GitLab && ( | |||
<GitlabTab | |||
branchesEnabled={branchesEnabled} | |||
definitions={definitions.gitlab} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
/> | |||
)} | |||
{definitionKeyForDeletion && ( | |||
<DeleteModal | |||
id={definitionKeyForDeletion} | |||
onCancel={props.onCancel} | |||
onDelete={props.onConfirmDelete} | |||
projectCount={projectCount} | |||
/> | |||
)} | |||
</> | |||
); | |||
} |
@@ -18,18 +18,22 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { AlmSettingsBinding, ALM_KEYS } from '../../../../types/alm-settings'; | |||
import { AlmPRDecorationFormChildrenProps } from './AlmPRDecorationForm'; | |||
import { AlmBindingDefinition, AlmKeys } from '../../../../types/alm-settings'; | |||
import { AlmBindingDefinitionFormChildrenProps } from './AlmBindingDefinitionForm'; | |||
import { AlmIntegrationFeatureBoxProps } from './AlmIntegrationFeatureBox'; | |||
import AlmTabRenderer from './AlmTabRenderer'; | |||
interface Props<B> { | |||
alm: ALM_KEYS; | |||
alm: AlmKeys; | |||
additionalColumnsHeaders?: string[]; | |||
additionalColumnsKeys?: Array<keyof B>; | |||
additionalTableInfo?: React.ReactNode; | |||
createConfiguration: (data: B) => Promise<void>; | |||
defaultBinding: B; | |||
definitions: B[]; | |||
form: (props: AlmPRDecorationFormChildrenProps<B>) => React.ReactNode; | |||
features?: AlmIntegrationFeatureBoxProps[]; | |||
form: (props: AlmBindingDefinitionFormChildrenProps<B>) => React.ReactNode; | |||
help?: React.ReactNode; | |||
loading: boolean; | |||
multipleAlmEnabled: boolean; | |||
onDelete: (definitionKey: string) => void; | |||
@@ -43,7 +47,7 @@ interface State<B> { | |||
success: boolean; | |||
} | |||
export default class AlmTab<B extends AlmSettingsBinding> extends React.PureComponent< | |||
export default class AlmTab<B extends AlmBindingDefinition> extends React.PureComponent< | |||
Props<B>, | |||
State<B> | |||
> { | |||
@@ -100,10 +104,13 @@ export default class AlmTab<B extends AlmSettingsBinding> extends React.PureComp | |||
const { | |||
additionalColumnsHeaders = [], | |||
additionalColumnsKeys = [], | |||
additionalTableInfo, | |||
alm, | |||
defaultBinding, | |||
definitions, | |||
features, | |||
form, | |||
help, | |||
loading, | |||
multipleAlmEnabled | |||
} = this.props; | |||
@@ -113,11 +120,14 @@ export default class AlmTab<B extends AlmSettingsBinding> extends React.PureComp | |||
<AlmTabRenderer | |||
additionalColumnsHeaders={additionalColumnsHeaders} | |||
additionalColumnsKeys={additionalColumnsKeys} | |||
additionalTableInfo={additionalTableInfo} | |||
alm={alm} | |||
defaultBinding={defaultBinding} | |||
definitions={definitions} | |||
editedDefinition={editedDefinition} | |||
features={features} | |||
form={form} | |||
help={help} | |||
loading={loading || submitting} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onCancel={this.handleCancel} |
@@ -0,0 +1,160 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { FormattedMessage } from 'react-intl'; | |||
import { Link } from 'react-router'; | |||
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { AlmBindingDefinition, AlmKeys } from '../../../../types/alm-settings'; | |||
import AlmBindingDefinitionForm, { | |||
AlmBindingDefinitionFormChildrenProps | |||
} from './AlmBindingDefinitionForm'; | |||
import AlmBindingDefinitionsTable from './AlmBindingDefinitionsTable'; | |||
import AlmIntegrationFeatureBox, { | |||
AlmIntegrationFeatureBoxProps | |||
} from './AlmIntegrationFeatureBox'; | |||
export interface AlmTabRendererProps<B> { | |||
additionalColumnsHeaders: string[]; | |||
additionalColumnsKeys: Array<keyof B>; | |||
additionalTableInfo?: React.ReactNode; | |||
alm: AlmKeys; | |||
editedDefinition?: B; | |||
defaultBinding: B; | |||
definitions: B[]; | |||
features?: AlmIntegrationFeatureBoxProps[]; | |||
form: (props: AlmBindingDefinitionFormChildrenProps<B>) => React.ReactNode; | |||
help?: React.ReactNode; | |||
loading: boolean; | |||
multipleAlmEnabled: boolean; | |||
onCancel: () => void; | |||
onCreate: () => void; | |||
onDelete: (definitionKey: string) => void; | |||
onEdit: (definitionKey: string) => void; | |||
onSubmit: (config: B, originalKey: string) => void; | |||
success: boolean; | |||
} | |||
export default function AlmTabRenderer<B extends AlmBindingDefinition>( | |||
props: AlmTabRendererProps<B> | |||
) { | |||
const { | |||
additionalColumnsHeaders, | |||
additionalColumnsKeys, | |||
additionalTableInfo, | |||
alm, | |||
defaultBinding, | |||
definitions, | |||
editedDefinition, | |||
features = [], | |||
form, | |||
loading, | |||
multipleAlmEnabled, | |||
success, | |||
help = ( | |||
<FormattedMessage | |||
defaultMessage={translate(`settings.almintegration.${alm}.info`)} | |||
id={`settings.almintegration.${alm}.info`} | |||
values={{ | |||
link: ( | |||
<Link target="_blank" to="/documentation/analysis/pr-decoration/"> | |||
{translate('learn_more')} | |||
</Link> | |||
) | |||
}} | |||
/> | |||
) | |||
} = props; | |||
let definition: B | undefined; | |||
let mappedDefinitions: Array<{ key: string; additionalColumns: string[] }> = []; | |||
let showEdit: boolean | undefined; | |||
if (!multipleAlmEnabled) { | |||
definition = editedDefinition; | |||
if (definition === undefined && definitions.length > 0) { | |||
definition = definitions[0]; | |||
} | |||
showEdit = definition && editedDefinition === undefined; | |||
} else { | |||
mappedDefinitions = definitions.map(({ key, ...properties }) => { | |||
const additionalColumns = additionalColumnsKeys.map(k => (properties as any)[k]); | |||
return { | |||
key, | |||
additionalColumns | |||
}; | |||
}); | |||
} | |||
return ( | |||
<div className="big-padded"> | |||
{multipleAlmEnabled ? ( | |||
<DeferredSpinner loading={loading}> | |||
<AlmBindingDefinitionsTable | |||
additionalColumnsHeaders={additionalColumnsHeaders} | |||
additionalTableInfo={additionalTableInfo} | |||
alm={alm} | |||
definitions={mappedDefinitions} | |||
onCreate={props.onCreate} | |||
onDelete={props.onDelete} | |||
onEdit={props.onEdit} | |||
/> | |||
{editedDefinition && ( | |||
<AlmBindingDefinitionForm | |||
bindingDefinition={editedDefinition} | |||
help={help} | |||
onCancel={props.onCancel} | |||
onSubmit={props.onSubmit} | |||
showInModal={true}> | |||
{form} | |||
</AlmBindingDefinitionForm> | |||
)} | |||
</DeferredSpinner> | |||
) : ( | |||
<AlmBindingDefinitionForm | |||
bindingDefinition={definition || defaultBinding} | |||
help={help} | |||
hideKeyField={true} | |||
loading={loading} | |||
onCancel={props.onCancel} | |||
onDelete={definition ? props.onDelete : undefined} | |||
onEdit={showEdit ? props.onEdit : undefined} | |||
onSubmit={props.onSubmit} | |||
readOnly={showEdit} | |||
success={success}> | |||
{form} | |||
</AlmBindingDefinitionForm> | |||
)} | |||
{features.length > 0 && ( | |||
<div className="big-spacer-top big-padded-top bordered-top"> | |||
<h3 className="big-spacer-bottom">{translate('settings.almintegration.features')}</h3> | |||
<div className="display-flex-wrap"> | |||
{features.map((feature, i) => ( | |||
<AlmIntegrationFeatureBox key={i} {...feature} /> | |||
))} | |||
</div> | |||
</div> | |||
)} | |||
</div> | |||
); | |||
} |
@@ -20,7 +20,7 @@ | |||
import * as React from 'react'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { AzureBindingDefinition } from '../../../../types/alm-settings'; | |||
import { AlmDefinitionFormField } from './AlmDefinitionFormField'; | |||
import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField'; | |||
export interface AzureFormProps { | |||
formData: AzureBindingDefinition; | |||
@@ -35,9 +35,9 @@ export default function AzureForm(props: AzureFormProps) { | |||
return ( | |||
<> | |||
{!hideKeyField && ( | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help={translate('settings.pr_decoration.form.name.azure.help')} | |||
help={translate('settings.almintegration.form.name.azure.help')} | |||
id="name.azure" | |||
onFieldChange={onFieldChange} | |||
propKey="key" | |||
@@ -45,8 +45,8 @@ export default function AzureForm(props: AzureFormProps) { | |||
value={formData.key} | |||
/> | |||
)} | |||
<AlmDefinitionFormField | |||
help={translate('settings.pr_decoration.form.personal_access_token.azure.help')} | |||
<AlmBindingDefinitionFormField | |||
help={translate('settings.almintegration.form.personal_access_token.azure.help')} | |||
id="personal_access_token" | |||
isTextArea={true} | |||
onFieldChange={onFieldChange} |
@@ -18,8 +18,9 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { createAzureConfiguration, updateAzureConfiguration } from '../../../../api/almSettings'; | |||
import { ALM_KEYS, AzureBindingDefinition } from '../../../../types/alm-settings'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { createAzureConfiguration, updateAzureConfiguration } from '../../../../api/alm-settings'; | |||
import { AlmKeys, AzureBindingDefinition } from '../../../../types/alm-settings'; | |||
import AlmTab from './AlmTab'; | |||
import AzureForm from './AzureForm'; | |||
@@ -35,17 +36,27 @@ export default function AzureTab(props: AzureTabProps) { | |||
const { multipleAlmEnabled, definitions, loading } = props; | |||
return ( | |||
<AlmTab | |||
alm={ALM_KEYS.AZURE} | |||
createConfiguration={createAzureConfiguration} | |||
defaultBinding={{ key: '', personalAccessToken: '' }} | |||
definitions={definitions} | |||
form={childProps => <AzureForm {...childProps} />} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
updateConfiguration={updateAzureConfiguration} | |||
/> | |||
<div className="bordered"> | |||
<AlmTab | |||
alm={AlmKeys.Azure} | |||
createConfiguration={createAzureConfiguration} | |||
defaultBinding={{ key: '', personalAccessToken: '' }} | |||
definitions={definitions} | |||
features={[ | |||
{ | |||
name: translate('settings.almintegration.feature.pr_decoration.title'), | |||
active: definitions.length > 0, | |||
description: translate('settings.almintegration.feature.pr_decoration.description'), | |||
inactiveReason: translate('settings.almintegration.feature.need_at_least_1_binding') | |||
} | |||
]} | |||
form={childProps => <AzureForm {...childProps} />} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
updateConfiguration={updateAzureConfiguration} | |||
/> | |||
</div> | |||
); | |||
} |
@@ -21,7 +21,7 @@ import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { BitbucketBindingDefinition } from '../../../../types/alm-settings'; | |||
import { AlmDefinitionFormField } from './AlmDefinitionFormField'; | |||
import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField'; | |||
export interface BitbucketFormProps { | |||
formData: BitbucketBindingDefinition; | |||
@@ -36,9 +36,9 @@ export default function BitbucketForm(props: BitbucketFormProps) { | |||
return ( | |||
<> | |||
{!hideKeyField && ( | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help={translate('settings.pr_decoration.form.name.bitbucket.help')} | |||
help={translate('settings.almintegration.form.name.bitbucket.help')} | |||
id="name.bitbucket" | |||
maxLength={100} | |||
onFieldChange={onFieldChange} | |||
@@ -47,11 +47,11 @@ export default function BitbucketForm(props: BitbucketFormProps) { | |||
value={formData.key} | |||
/> | |||
)} | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
help={ | |||
<FormattedMessage | |||
defaultMessage={translate('settings.pr_decoration.form.url.bitbucket.help')} | |||
id="settings.pr_decoration.form.url.bitbucket.help" | |||
defaultMessage={translate('settings.almintegration.form.url.bitbucket.help')} | |||
id="settings.almintegration.form.url.bitbucket.help" | |||
values={{ example: 'https://bitbucket-server.your-company.com' }} | |||
/> | |||
} | |||
@@ -62,7 +62,7 @@ export default function BitbucketForm(props: BitbucketFormProps) { | |||
readOnly={readOnly} | |||
value={formData.url} | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
id="personal_access_token" | |||
isTextArea={true} | |||
onFieldChange={onFieldChange} |
@@ -0,0 +1,114 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { FormattedMessage } from 'react-intl'; | |||
import { Link } from 'react-router'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n'; | |||
import { | |||
createBitbucketConfiguration, | |||
updateBitbucketConfiguration | |||
} from '../../../../api/alm-settings'; | |||
import { AlmKeys, BitbucketBindingDefinition } from '../../../../types/alm-settings'; | |||
import AlmTab from './AlmTab'; | |||
import BitbucketForm from './BitbucketForm'; | |||
export interface BitbucketTabProps { | |||
definitions: BitbucketBindingDefinition[]; | |||
loading: boolean; | |||
multipleAlmEnabled: boolean; | |||
onDelete: (definitionKey: string) => void; | |||
onUpdateDefinitions: () => void; | |||
} | |||
export default function BitbucketTab(props: BitbucketTabProps) { | |||
const { multipleAlmEnabled, definitions, loading } = props; | |||
return ( | |||
<div className="bordered"> | |||
<AlmTab | |||
additionalColumnsHeaders={[translate('settings.almintegration.table.column.bitbucket.url')]} | |||
additionalColumnsKeys={['url']} | |||
additionalTableInfo={ | |||
<Alert className="big-spacer-bottom width-50" variant="info"> | |||
<FormattedMessage | |||
defaultMessage={translate( | |||
'settings.almintegration.feature.alm_repo_import.disabled_if_multiple_bbs_instances' | |||
)} | |||
id="settings.almintegration.feature.alm_repo_import.disabled_if_multiple_bbs_instances" | |||
values={{ | |||
feature: ( | |||
<em>{translate('settings.almintegration.feature.alm_repo_import.title')}</em> | |||
) | |||
}} | |||
/> | |||
</Alert> | |||
} | |||
alm={AlmKeys.Bitbucket} | |||
createConfiguration={createBitbucketConfiguration} | |||
defaultBinding={{ key: '', url: '', personalAccessToken: '' }} | |||
definitions={definitions} | |||
features={[ | |||
{ | |||
name: translate('settings.almintegration.feature.pr_decoration.title'), | |||
active: definitions.length > 0, | |||
description: translate('settings.almintegration.feature.pr_decoration.description'), | |||
inactiveReason: translate('settings.almintegration.feature.need_at_least_1_binding') | |||
}, | |||
{ | |||
name: translate('settings.almintegration.feature.alm_repo_import.title'), | |||
active: definitions.length === 1, | |||
description: translate('settings.almintegration.feature.alm_repo_import.description'), | |||
inactiveReason: translateWithParameters( | |||
'onboarding.create_project.too_many_bbs_instances_X', | |||
definitions.length | |||
) | |||
} | |||
]} | |||
form={childProps => <BitbucketForm {...childProps} />} | |||
help={ | |||
<> | |||
<h3>{translate('onboarding.create_project.pat_help.title')}</h3> | |||
<p className="big-spacer-top"> | |||
{translate('settings.almintegration.bitbucket.help_1')} | |||
</p> | |||
<ul className="big-spacer-top list-styled"> | |||
<li>{translate('settings.almintegration.bitbucket.help_2')}</li> | |||
<li>{translate('settings.almintegration.bitbucket.help_3')}</li> | |||
</ul> | |||
<p className="big-spacer-top big-spacer-bottom"> | |||
<Link target="_blank" to="/documentation/analysis/pr-decoration/"> | |||
{translate('learn_more')} | |||
</Link> | |||
</p> | |||
</> | |||
} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
updateConfiguration={updateBitbucketConfiguration} | |||
/> | |||
</div> | |||
); | |||
} |
@@ -31,11 +31,11 @@ export interface DeleteModalProps { | |||
function showProjectCountWarning(projectCount?: number) { | |||
if (projectCount === undefined) { | |||
return <p>{translate('settings.pr_decoration.delete.no_info')}</p>; | |||
return <p>{translate('settings.almintegration.delete.no_info')}</p>; | |||
} | |||
return projectCount ? ( | |||
<p>{translateWithParameters('settings.pr_decoration.delete.info', projectCount)} </p> | |||
<p>{translateWithParameters('settings.almintegration.delete.info', projectCount)} </p> | |||
) : null; | |||
} | |||
@@ -44,15 +44,15 @@ export default function DeleteModal({ id, onDelete, onCancel, projectCount }: De | |||
<ConfirmModal | |||
confirmButtonText={translate('delete')} | |||
confirmData={id} | |||
header={translate('settings.pr_decoration.delete.header')} | |||
header={translate('settings.almintegration.delete.header')} | |||
isDestructive={true} | |||
onClose={onCancel} | |||
onConfirm={onDelete}> | |||
<> | |||
<p className="spacer-bottom"> | |||
<FormattedMessage | |||
defaultMessage={translate('settings.pr_decoration.delete.message')} | |||
id="settings.pr_decoration.delete.message" | |||
defaultMessage={translate('settings.almintegration.delete.message')} | |||
id="settings.almintegration.delete.message" | |||
values={{ id: <b>{id}</b> }} | |||
/> | |||
</p> |
@@ -20,7 +20,7 @@ | |||
import * as React from 'react'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { GithubBindingDefinition } from '../../../../types/alm-settings'; | |||
import { AlmDefinitionFormField } from './AlmDefinitionFormField'; | |||
import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField'; | |||
export interface GithubFormProps { | |||
formData: GithubBindingDefinition; | |||
@@ -35,9 +35,9 @@ export default function GithubForm(props: GithubFormProps) { | |||
return ( | |||
<> | |||
{!hideKeyField && ( | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help={translate('settings.pr_decoration.form.name.github.help')} | |||
help={translate('settings.almintegration.form.name.github.help')} | |||
id="name.github" | |||
onFieldChange={onFieldChange} | |||
propKey="key" | |||
@@ -45,15 +45,15 @@ export default function GithubForm(props: GithubFormProps) { | |||
value={formData.key} | |||
/> | |||
)} | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
help={ | |||
<> | |||
{translate('settings.pr_decoration.form.url.github.help1')} | |||
{translate('settings.almintegration.form.url.github.help1')} | |||
<br /> | |||
<em>https://github.company.com/api/v3</em> | |||
<br /> | |||
<br /> | |||
{translate('settings.pr_decoration.form.url.github.help2')} | |||
{translate('settings.almintegration.form.url.github.help2')} | |||
<br /> | |||
<em>https://api.github.com/</em> | |||
</> | |||
@@ -65,7 +65,7 @@ export default function GithubForm(props: GithubFormProps) { | |||
readOnly={readOnly} | |||
value={formData.url} | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
id="app_id" | |||
maxLength={80} | |||
onFieldChange={onFieldChange} | |||
@@ -73,7 +73,7 @@ export default function GithubForm(props: GithubFormProps) { | |||
readOnly={readOnly} | |||
value={formData.appId} | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
id="private_key" | |||
isTextArea={true} | |||
onFieldChange={onFieldChange} |
@@ -0,0 +1,85 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { createGithubConfiguration, updateGithubConfiguration } from '../../../../api/alm-settings'; | |||
import { AlmKeys, GithubBindingDefinition } from '../../../../types/alm-settings'; | |||
import { ALM_INTEGRATION } from '../AdditionalCategoryKeys'; | |||
import CategoryDefinitionsList from '../CategoryDefinitionsList'; | |||
import AlmTab from './AlmTab'; | |||
import GithubForm from './GithubForm'; | |||
export interface GithubTabProps { | |||
branchesEnabled: boolean; | |||
component?: T.Component; | |||
definitions: GithubBindingDefinition[]; | |||
loading: boolean; | |||
multipleAlmEnabled: boolean; | |||
onDelete: (definitionKey: string) => void; | |||
onUpdateDefinitions: () => void; | |||
} | |||
export default function GithubTab(props: GithubTabProps) { | |||
const { branchesEnabled, component, multipleAlmEnabled, definitions, loading } = props; | |||
return ( | |||
<div className="bordered"> | |||
{branchesEnabled && ( | |||
<> | |||
<AlmTab | |||
additionalColumnsHeaders={[ | |||
translate('settings.almintegration.table.column.github.url'), | |||
translate('settings.almintegration.table.column.app_id') | |||
]} | |||
additionalColumnsKeys={['appId', 'url']} | |||
alm={AlmKeys.GitHub} | |||
createConfiguration={createGithubConfiguration} | |||
defaultBinding={{ key: '', appId: '', url: '', privateKey: '' }} | |||
definitions={definitions} | |||
features={[ | |||
{ | |||
name: translate('settings.almintegration.feature.pr_decoration.title'), | |||
active: definitions.length > 0, | |||
description: translate('settings.almintegration.feature.pr_decoration.description'), | |||
inactiveReason: translate('settings.almintegration.feature.need_at_least_1_binding') | |||
} | |||
]} | |||
form={childProps => <GithubForm {...childProps} />} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
updateConfiguration={updateGithubConfiguration} | |||
/> | |||
<div className="huge-spacer-top huge-spacer-bottom bordered-top" /> | |||
</> | |||
)} | |||
<div className="big-padded"> | |||
<CategoryDefinitionsList | |||
category={ALM_INTEGRATION} | |||
component={component} | |||
subCategory={AlmKeys.GitHub} | |||
/> | |||
</div> | |||
</div> | |||
); | |||
} |
@@ -20,7 +20,7 @@ | |||
import * as React from 'react'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { GitlabBindingDefinition } from '../../../../types/alm-settings'; | |||
import { AlmDefinitionFormField } from './AlmDefinitionFormField'; | |||
import { AlmBindingDefinitionFormField } from './AlmBindingDefinitionFormField'; | |||
export interface GitlabFormProps { | |||
formData: GitlabBindingDefinition; | |||
@@ -35,9 +35,9 @@ export default function GitlabForm(props: GitlabFormProps) { | |||
return ( | |||
<> | |||
{!hideKeyField && ( | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help={translate('settings.pr_decoration.form.name.gitlab.help')} | |||
help={translate('settings.almintegration.form.name.gitlab.help')} | |||
id="name.gitlab" | |||
onFieldChange={onFieldChange} | |||
propKey="key" | |||
@@ -45,8 +45,8 @@ export default function GitlabForm(props: GitlabFormProps) { | |||
value={formData.key} | |||
/> | |||
)} | |||
<AlmDefinitionFormField | |||
help={translate('settings.pr_decoration.form.personal_access_token.gitlab.help')} | |||
<AlmBindingDefinitionFormField | |||
help={translate('settings.almintegration.form.personal_access_token.gitlab.help')} | |||
id="personal_access_token" | |||
isTextArea={true} | |||
onFieldChange={onFieldChange} |
@@ -0,0 +1,80 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { createGitlabConfiguration, updateGitlabConfiguration } from '../../../../api/alm-settings'; | |||
import { AlmKeys, GitlabBindingDefinition } from '../../../../types/alm-settings'; | |||
import { ALM_INTEGRATION } from '../AdditionalCategoryKeys'; | |||
import CategoryDefinitionsList from '../CategoryDefinitionsList'; | |||
import AlmTab from './AlmTab'; | |||
import GitlabForm from './GitlabForm'; | |||
export interface GitlabTabProps { | |||
branchesEnabled: boolean; | |||
component?: T.Component; | |||
definitions: GitlabBindingDefinition[]; | |||
loading: boolean; | |||
multipleAlmEnabled: boolean; | |||
onDelete: (definitionKey: string) => void; | |||
onUpdateDefinitions: () => void; | |||
} | |||
export default function GitlabTab(props: GitlabTabProps) { | |||
const { branchesEnabled, component, multipleAlmEnabled, definitions, loading } = props; | |||
return ( | |||
<div className="bordered"> | |||
{branchesEnabled && ( | |||
<> | |||
<AlmTab | |||
alm={AlmKeys.GitLab} | |||
createConfiguration={createGitlabConfiguration} | |||
defaultBinding={{ key: '', personalAccessToken: '' }} | |||
definitions={definitions} | |||
features={[ | |||
{ | |||
name: translate('settings.almintegration.feature.mr_decoration.title'), | |||
active: definitions.length > 0, | |||
description: translate('settings.almintegration.feature.mr_decoration.description'), | |||
inactiveReason: translate('settings.almintegration.feature.need_at_least_1_binding') | |||
} | |||
]} | |||
form={childProps => <GitlabForm {...childProps} />} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
updateConfiguration={updateGitlabConfiguration} | |||
/> | |||
<div className="huge-spacer-top huge-spacer-bottom bordered-top" /> | |||
</> | |||
)} | |||
<div className="big-padded"> | |||
<CategoryDefinitionsList | |||
category={ALM_INTEGRATION} | |||
component={component} | |||
subCategory={AlmKeys.GitLab} | |||
/> | |||
</div> | |||
</div> | |||
); | |||
} |
@@ -21,8 +21,8 @@ import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { mockGithubDefinition } from '../../../../../helpers/mocks/alm-settings'; | |||
import { ALM_KEYS, GithubBindingDefinition } from '../../../../../types/alm-settings'; | |||
import AlmPRDecorationForm from '../AlmPRDecorationForm'; | |||
import { GithubBindingDefinition } from '../../../../../types/alm-settings'; | |||
import AlmBindingDefinitionForm from '../AlmBindingDefinitionForm'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
@@ -121,15 +121,16 @@ it('should (dis)allow submit by validating its state', () => { | |||
expect(wrapper.instance().canSubmit()).toBe(true); | |||
}); | |||
function shallowRender(props: Partial<AlmPRDecorationForm<GithubBindingDefinition>['props']> = {}) { | |||
return shallow<AlmPRDecorationForm<GithubBindingDefinition>>( | |||
<AlmPRDecorationForm | |||
alm={ALM_KEYS.GITHUB} | |||
function shallowRender( | |||
props: Partial<AlmBindingDefinitionForm<GithubBindingDefinition>['props']> = {} | |||
) { | |||
return shallow<AlmBindingDefinitionForm<GithubBindingDefinition>>( | |||
<AlmBindingDefinitionForm | |||
bindingDefinition={{ appId: '', key: '', privateKey: '', url: '' }} | |||
onCancel={jest.fn()} | |||
onSubmit={jest.fn()} | |||
{...props}> | |||
{() => null} | |||
</AlmPRDecorationForm> | |||
</AlmBindingDefinitionForm> | |||
); | |||
} |
@@ -19,8 +19,11 @@ | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { AlmSettingsBinding } from '../../../../../types/alm-settings'; | |||
import { AlmDefinitionFormField, AlmDefinitionFormFieldProps } from '../AlmDefinitionFormField'; | |||
import { AlmBindingDefinition } from '../../../../../types/alm-settings'; | |||
import { | |||
AlmBindingDefinitionFormField, | |||
AlmBindingDefinitionFormFieldProps | |||
} from '../AlmBindingDefinitionFormField'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
@@ -42,9 +45,11 @@ it('should call onFieldChange', () => { | |||
expect(onTextAreaChange).toBeCalled(); | |||
}); | |||
function shallowRender(props: Partial<AlmDefinitionFormFieldProps<AlmSettingsBinding>> = {}) { | |||
function shallowRender( | |||
props: Partial<AlmBindingDefinitionFormFieldProps<AlmBindingDefinition>> = {} | |||
) { | |||
return shallow( | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
id="key" | |||
isTextArea={false} | |||
maxLength={40} |
@@ -19,26 +19,24 @@ | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { ALM_KEYS } from '../../../../../types/alm-settings'; | |||
import AlmPRDecorationFormModalRenderer, { | |||
AlmPRDecorationFormModalProps | |||
} from '../AlmPRDecorationFormModalRenderer'; | |||
import AlmBindingDefinitionFormModalRenderer, { | |||
AlmBindingDefinitionFormModalProps | |||
} from '../AlmBindingDefinitionFormModalRenderer'; | |||
it('should render correctly', () => { | |||
expect(shallowRender().dive()).toMatchSnapshot(); | |||
expect(shallowRender({ help: <span>Help me</span> }).dive()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<AlmPRDecorationFormModalProps> = {}) { | |||
function shallowRender(props: Partial<AlmBindingDefinitionFormModalProps> = {}) { | |||
return shallow( | |||
<AlmPRDecorationFormModalRenderer | |||
<AlmBindingDefinitionFormModalRenderer | |||
action="create" | |||
alm={ALM_KEYS.GITHUB} | |||
canSubmit={jest.fn()} | |||
onCancel={jest.fn()} | |||
onSubmit={jest.fn()} | |||
{...props}> | |||
{() => null} | |||
</AlmPRDecorationFormModalRenderer> | |||
</AlmBindingDefinitionFormModalRenderer> | |||
); | |||
} |
@@ -21,9 +21,9 @@ import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { SubmitButton } from 'sonar-ui-common/components/controls/buttons'; | |||
import { submit } from 'sonar-ui-common/helpers/testUtils'; | |||
import AlmPRDecorationFormRenderer, { | |||
AlmPRDecorationFormRendererProps | |||
} from '../AlmPRDecorationFormRenderer'; | |||
import AlmBindingDefinitionFormRenderer, { | |||
AlmBindingDefinitionFormRendererProps | |||
} from '../AlmBindingDefinitionFormRenderer'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
@@ -54,15 +54,15 @@ it('should correctly submit the form', () => { | |||
expect(onSubmit).toBeCalled(); | |||
}); | |||
function shallowRender(props: Partial<AlmPRDecorationFormRendererProps> = {}) { | |||
function shallowRender(props: Partial<AlmBindingDefinitionFormRendererProps> = {}) { | |||
return shallow( | |||
<AlmPRDecorationFormRenderer | |||
<AlmBindingDefinitionFormRenderer | |||
canSubmit={jest.fn()} | |||
loading={false} | |||
onSubmit={jest.fn()} | |||
success={false} | |||
{...props}> | |||
{() => null} | |||
</AlmPRDecorationFormRenderer> | |||
</AlmBindingDefinitionFormRenderer> | |||
); | |||
} |
@@ -19,22 +19,24 @@ | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { ALM_KEYS } from '../../../../../types/alm-settings'; | |||
import AlmPRDecorationTable, { AlmPRDecorationTableProps } from '../AlmPRDecorationTable'; | |||
import { AlmKeys } from '../../../../../types/alm-settings'; | |||
import AlmBindingDefinitionsTable, { | |||
AlmBindingDefinitionsTableProps | |||
} from '../AlmBindingDefinitionsTable'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
expect( | |||
shallowRender({ | |||
additionalColumnsHeaders: ['additional1', 'additional2'], | |||
alm: ALM_KEYS.GITHUB, | |||
alm: AlmKeys.GitHub, | |||
definitions: [ | |||
{ key: 'definition1', additionalColumns: ['def1-v1', 'def1-v2'] }, | |||
{ key: 'definition2', additionalColumns: ['def2-v1', 'def2-v2'] } | |||
] | |||
}) | |||
).toMatchSnapshot('additional columns'); | |||
expect(shallowRender({ alm: ALM_KEYS.GITHUB })).toMatchSnapshot('title adjusts for GitLab'); | |||
expect(shallowRender({ alm: AlmKeys.GitLab })).toMatchSnapshot('title adjusts for GitLab'); | |||
}); | |||
it('should correctly trigger create, delete, and edit', () => { | |||
@@ -44,7 +46,7 @@ it('should correctly trigger create, delete, and edit', () => { | |||
const wrapper = shallowRender({ | |||
additionalColumnsHeaders: [], | |||
alm: ALM_KEYS.BITBUCKET, | |||
alm: AlmKeys.Bitbucket, | |||
definitions: [{ key: 'defKey', additionalColumns: [] }], | |||
onCreate, | |||
onDelete, | |||
@@ -61,11 +63,11 @@ it('should correctly trigger create, delete, and edit', () => { | |||
expect(onEdit).toBeCalledWith('defKey'); | |||
}); | |||
function shallowRender(props: Partial<AlmPRDecorationTableProps> = {}) { | |||
function shallowRender(props: Partial<AlmBindingDefinitionsTableProps> = {}) { | |||
return shallow( | |||
<AlmPRDecorationTable | |||
<AlmBindingDefinitionsTable | |||
additionalColumnsHeaders={[]} | |||
alm={ALM_KEYS.AZURE} | |||
alm={AlmKeys.Azure} | |||
definitions={[]} | |||
onCreate={jest.fn()} | |||
onDelete={jest.fn()} |
@@ -24,11 +24,11 @@ import { | |||
countBindedProjects, | |||
deleteConfiguration, | |||
getAlmDefinitions | |||
} from '../../../../../api/almSettings'; | |||
import { ALM_KEYS } from '../../../../../types/alm-settings'; | |||
import PullRequestDecoration from '../PullRequestDecoration'; | |||
} from '../../../../../api/alm-settings'; | |||
import { AlmKeys } from '../../../../../types/alm-settings'; | |||
import { AlmIntegration } from '../AlmIntegration'; | |||
jest.mock('../../../../../api/almSettings', () => ({ | |||
jest.mock('../../../../../api/alm-settings', () => ({ | |||
countBindedProjects: jest.fn().mockResolvedValue(0), | |||
deleteConfiguration: jest.fn().mockResolvedValue(undefined), | |||
getAlmDefinitions: jest.fn().mockResolvedValue({ github: [] }) | |||
@@ -45,13 +45,13 @@ it('should render correctly', () => { | |||
it('should handle alm selection', async () => { | |||
const wrapper = shallowRender(); | |||
wrapper.setState({ currentAlm: ALM_KEYS.AZURE }); | |||
wrapper.setState({ currentAlm: AlmKeys.Azure }); | |||
wrapper.instance().handleSelectAlm(ALM_KEYS.GITHUB); | |||
wrapper.instance().handleSelectAlm(AlmKeys.GitHub); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.state().currentAlm).toBe(ALM_KEYS.GITHUB); | |||
expect(wrapper.state().currentAlm).toBe(AlmKeys.GitHub); | |||
}); | |||
it('should handle delete', async () => { | |||
@@ -90,5 +90,5 @@ it('should fetch settings', async () => { | |||
}); | |||
function shallowRender() { | |||
return shallow<PullRequestDecoration>(<PullRequestDecoration />); | |||
return shallow<AlmIntegration>(<AlmIntegration appState={{ branchesEnabled: true }} />); | |||
} |
@@ -0,0 +1,39 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import AlmIntegrationFeatureBox, { | |||
AlmIntegrationFeatureBoxProps | |||
} from '../AlmIntegrationFeatureBox'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot('default'); | |||
expect(shallowRender({ active: false })).toMatchSnapshot('inactive'); | |||
expect(shallowRender({ active: false, inactiveReason: "Bar is foo'd" })).toMatchSnapshot( | |||
'inactive, with reason' | |||
); | |||
}); | |||
function shallowRender(props: Partial<AlmIntegrationFeatureBoxProps> = {}) { | |||
return shallow<AlmIntegrationFeatureBoxProps>( | |||
<AlmIntegrationFeatureBox active={true} description="Foo bar..." name="Foo" {...props} /> | |||
); | |||
} |
@@ -19,24 +19,28 @@ | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { ALM_KEYS } from '../../../../../types/alm-settings'; | |||
import { PRDecorationTabs, PRDecorationTabsProps } from '../PRDecorationTabs'; | |||
import { AlmKeys } from '../../../../../types/alm-settings'; | |||
import AlmIntegrationRenderer, { AlmIntegrationRendererProps } from '../AlmIntegrationRenderer'; | |||
it('should render correctly', () => { | |||
expect(shallowRender({ loading: true })).toMatchSnapshot(); | |||
expect(shallowRender({ definitionKeyForDeletion: 'keyToDelete' })).toMatchSnapshot(); | |||
expect(shallowRender({ currentAlm: ALM_KEYS.AZURE })).toMatchSnapshot(); | |||
expect(shallowRender({ currentAlm: ALM_KEYS.BITBUCKET })).toMatchSnapshot(); | |||
expect(shallowRender({ currentAlm: ALM_KEYS.GITLAB })).toMatchSnapshot(); | |||
expect(shallowRender()).toMatchSnapshot('default'); | |||
expect(shallowRender({ loading: true })).toMatchSnapshot('loading'); | |||
expect(shallowRender({ definitionKeyForDeletion: 'keyToDelete' })).toMatchSnapshot( | |||
'delete modal' | |||
); | |||
expect(shallowRender({ currentAlm: AlmKeys.Azure })).toMatchSnapshot('azure'); | |||
expect(shallowRender({ currentAlm: AlmKeys.Bitbucket })).toMatchSnapshot('bitbucket'); | |||
expect(shallowRender({ currentAlm: AlmKeys.GitLab })).toMatchSnapshot('gitlab'); | |||
}); | |||
function shallowRender(props: Partial<PRDecorationTabsProps> = {}) { | |||
function shallowRender(props: Partial<AlmIntegrationRendererProps> = {}) { | |||
return shallow( | |||
<PRDecorationTabs | |||
appState={{ multipleAlmEnabled: false }} | |||
currentAlm={ALM_KEYS.GITHUB} | |||
<AlmIntegrationRenderer | |||
branchesEnabled={true} | |||
currentAlm={AlmKeys.GitHub} | |||
definitions={{ azure: [], bitbucket: [], github: [], gitlab: [] }} | |||
loading={false} | |||
multipleAlmEnabled={false} | |||
onCancel={jest.fn()} | |||
onConfirmDelete={jest.fn()} | |||
onDelete={jest.fn()} |
@@ -21,7 +21,7 @@ import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { mockAzureDefinition } from '../../../../../helpers/mocks/alm-settings'; | |||
import { ALM_KEYS, AzureBindingDefinition } from '../../../../../types/alm-settings'; | |||
import { AlmKeys, AzureBindingDefinition } from '../../../../../types/alm-settings'; | |||
import AlmTab from '../AlmTab'; | |||
const DEFAULT_BINDING = { | |||
@@ -93,7 +93,7 @@ it('should update config', async () => { | |||
function shallowRender(props: Partial<AlmTab<AzureBindingDefinition>['props']> = {}) { | |||
return shallow<AlmTab<AzureBindingDefinition>>( | |||
<AlmTab | |||
alm={ALM_KEYS.AZURE} | |||
alm={AlmKeys.Azure} | |||
createConfiguration={jest.fn()} | |||
defaultBinding={DEFAULT_BINDING} | |||
definitions={[mockAzureDefinition()]} |
@@ -20,7 +20,7 @@ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockGithubDefinition } from '../../../../../helpers/mocks/alm-settings'; | |||
import { ALM_KEYS, GithubBindingDefinition } from '../../../../../types/alm-settings'; | |||
import { AlmKeys, GithubBindingDefinition } from '../../../../../types/alm-settings'; | |||
import AlmTabRenderer, { AlmTabRendererProps } from '../AlmTabRenderer'; | |||
it('should render correctly for multi-ALM binding', () => { | |||
@@ -29,6 +29,22 @@ it('should render correctly for multi-ALM binding', () => { | |||
expect(shallowRender({ editedDefinition: mockGithubDefinition() })).toMatchSnapshot( | |||
'editing a definition' | |||
); | |||
expect( | |||
shallowRender({ | |||
features: [ | |||
{ | |||
active: true, | |||
name: 'Foo', | |||
description: 'Bar' | |||
}, | |||
{ | |||
active: false, | |||
name: 'Baz', | |||
description: 'Bim' | |||
} | |||
] | |||
}) | |||
).toMatchSnapshot('with features'); | |||
}); | |||
it('should render correctly for single-ALM binding', () => { | |||
@@ -44,7 +60,7 @@ function shallowRender(props: Partial<AlmTabRendererProps<GithubBindingDefinitio | |||
<AlmTabRenderer | |||
additionalColumnsHeaders={['url', 'app_id']} | |||
additionalColumnsKeys={['url', 'appId']} | |||
alm={ALM_KEYS.GITHUB} | |||
alm={AlmKeys.GitHub} | |||
defaultBinding={mockGithubDefinition()} | |||
definitions={[mockGithubDefinition()]} | |||
form={jest.fn()} |
@@ -23,12 +23,14 @@ import { mockGithubDefinition } from '../../../../../helpers/mocks/alm-settings' | |||
import GithubTab, { GithubTabProps } from '../GithubTab'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
expect(shallowRender()).toMatchSnapshot('with branch support'); | |||
expect(shallowRender({ branchesEnabled: false })).toMatchSnapshot('without branch support'); | |||
}); | |||
function shallowRender(props: Partial<GithubTabProps> = {}) { | |||
return shallow( | |||
<GithubTab | |||
branchesEnabled={true} | |||
definitions={[mockGithubDefinition()]} | |||
loading={false} | |||
multipleAlmEnabled={true} |
@@ -23,12 +23,14 @@ import { mockGitlabDefinition } from '../../../../../helpers/mocks/alm-settings' | |||
import GitlabTab, { GitlabTabProps } from '../GitlabTab'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
expect(shallowRender()).toMatchSnapshot('with branch support'); | |||
expect(shallowRender({ branchesEnabled: false })).toMatchSnapshot('without branch support'); | |||
}); | |||
function shallowRender(props: Partial<GitlabTabProps> = {}) { | |||
return shallow( | |||
<GitlabTab | |||
branchesEnabled={true} | |||
definitions={[mockGitlabDefinition()]} | |||
loading={false} | |||
multipleAlmEnabled={true} |
@@ -1,7 +1,7 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<AlmPRDecorationFormRenderer | |||
<AlmBindingDefinitionFormRenderer | |||
canSubmit={[Function]} | |||
loading={false} | |||
onCancel={[Function]} |
@@ -8,7 +8,7 @@ exports[`should render correctly 1`] = ` | |||
className="display-flex-center" | |||
htmlFor="key" | |||
> | |||
settings.pr_decoration.form.key | |||
settings.almintegration.form.key | |||
<em | |||
className="mandatory spacer-right" | |||
> | |||
@@ -37,7 +37,7 @@ exports[`should render correctly 2`] = ` | |||
className="display-flex-center" | |||
htmlFor="key" | |||
> | |||
settings.pr_decoration.form.key | |||
settings.almintegration.form.key | |||
<em | |||
className="mandatory spacer-right" | |||
> | |||
@@ -70,7 +70,7 @@ exports[`should render correctly 3`] = ` | |||
className="display-flex-center" | |||
htmlFor="key" | |||
> | |||
settings.pr_decoration.form.key | |||
settings.almintegration.form.key | |||
<em | |||
className="mandatory spacer-right" | |||
> |
@@ -2,7 +2,7 @@ | |||
exports[`should render correctly 1`] = ` | |||
<Modal | |||
contentLabel="settings.pr_decoration.form.header.create" | |||
contentLabel="settings.almintegration.form.header.create" | |||
onRequestClose={[MockFunction]} | |||
size="medium" | |||
> | |||
@@ -14,13 +14,21 @@ exports[`should render correctly 1`] = ` | |||
className="modal-head" | |||
> | |||
<h2> | |||
settings.pr_decoration.form.header.create | |||
settings.almintegration.form.header.create | |||
</h2> | |||
</div> | |||
<div | |||
className="modal-body modal-container" | |||
> | |||
<Component /> | |||
<div | |||
className="display-flex-start" | |||
> | |||
<div | |||
className="flex-1" | |||
> | |||
<Component /> | |||
</div> | |||
</div> | |||
</div> | |||
<div | |||
className="modal-foot" | |||
@@ -33,7 +41,7 @@ exports[`should render correctly 1`] = ` | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.pr_decoration.form.save | |||
settings.almintegration.form.save | |||
</SubmitButton> | |||
<ResetButtonLink | |||
onClick={[Function]} | |||
@@ -47,7 +55,7 @@ exports[`should render correctly 1`] = ` | |||
exports[`should render correctly 2`] = ` | |||
<Modal | |||
contentLabel="settings.pr_decoration.form.header.create" | |||
contentLabel="settings.almintegration.form.header.create" | |||
onRequestClose={[MockFunction]} | |||
size="medium" | |||
> | |||
@@ -59,21 +67,29 @@ exports[`should render correctly 2`] = ` | |||
className="modal-head" | |||
> | |||
<h2> | |||
settings.pr_decoration.form.header.create | |||
settings.almintegration.form.header.create | |||
</h2> | |||
</div> | |||
<div | |||
className="modal-body modal-container" | |||
> | |||
<Alert | |||
className="big-spacer-bottom" | |||
variant="info" | |||
<div | |||
className="display-flex-start" | |||
> | |||
<span> | |||
Help me | |||
</span> | |||
</Alert> | |||
<Component /> | |||
<div | |||
className="flex-1" | |||
> | |||
<Component /> | |||
</div> | |||
<Alert | |||
className="huge-spacer-left flex-1" | |||
variant="info" | |||
> | |||
<span> | |||
Help me | |||
</span> | |||
</Alert> | |||
</div> | |||
</div> | |||
<div | |||
className="modal-foot" | |||
@@ -86,7 +102,7 @@ exports[`should render correctly 2`] = ` | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.pr_decoration.form.save | |||
settings.almintegration.form.save | |||
</SubmitButton> | |||
<ResetButtonLink | |||
onClick={[Function]} |
@@ -0,0 +1,161 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<form | |||
className="views-form" | |||
data-test="settings__alm-form" | |||
onSubmit={[Function]} | |||
> | |||
<div | |||
className="display-flex-start" | |||
> | |||
<div | |||
className="flex-1" | |||
> | |||
<Component /> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.almintegration.form.save | |||
</SubmitButton> | |||
</div> | |||
</div> | |||
</div> | |||
</form> | |||
`; | |||
exports[`should render correctly 2`] = ` | |||
<form | |||
className="views-form" | |||
data-test="settings__alm-form" | |||
onSubmit={[Function]} | |||
> | |||
<div | |||
className="display-flex-start" | |||
> | |||
<div | |||
className="flex-1" | |||
> | |||
<Component /> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.almintegration.form.save | |||
</SubmitButton> | |||
<ResetButtonLink | |||
className="spacer-left" | |||
onClick={[MockFunction]} | |||
> | |||
cancel | |||
</ResetButtonLink> | |||
</div> | |||
</div> | |||
</div> | |||
</form> | |||
`; | |||
exports[`should render correctly 3`] = ` | |||
<form | |||
className="views-form" | |||
data-test="settings__alm-form" | |||
onSubmit={[Function]} | |||
> | |||
<div | |||
className="display-flex-start" | |||
> | |||
<div | |||
className="flex-1" | |||
> | |||
<Component /> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.almintegration.form.save | |||
</SubmitButton> | |||
<Button | |||
className="button-red spacer-left" | |||
disabled={false} | |||
onClick={[MockFunction]} | |||
> | |||
delete | |||
</Button> | |||
</div> | |||
</div> | |||
</div> | |||
</form> | |||
`; | |||
exports[`should render correctly 4`] = ` | |||
<form | |||
className="views-form" | |||
data-test="settings__alm-form" | |||
onSubmit={[Function]} | |||
> | |||
<div | |||
className="display-flex-start" | |||
> | |||
<div | |||
className="flex-1" | |||
> | |||
<Component /> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.almintegration.form.save | |||
</SubmitButton> | |||
<span | |||
className="text-success spacer-left" | |||
> | |||
<AlertSuccessIcon | |||
className="spacer-right" | |||
/> | |||
settings.state.saved | |||
</span> | |||
</div> | |||
</div> | |||
</div> | |||
</form> | |||
`; | |||
exports[`should render correctly 5`] = ` | |||
<form | |||
className="views-form" | |||
data-test="settings__alm-form" | |||
onSubmit={[Function]} | |||
> | |||
<div | |||
className="display-flex-start" | |||
> | |||
<div | |||
className="flex-1" | |||
> | |||
<Component /> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.almintegration.form.save | |||
</SubmitButton> | |||
<DeferredSpinner | |||
className="spacer-left" | |||
timeout={100} | |||
/> | |||
</div> | |||
</div> | |||
</div> | |||
</form> | |||
`; |
@@ -5,16 +5,16 @@ exports[`should render correctly 1`] = ` | |||
<div | |||
className="spacer-top big-spacer-bottom display-flex-space-between" | |||
> | |||
<h4 | |||
className="display-inline" | |||
<h2 | |||
className="settings-sub-category-name" | |||
> | |||
settings.pr_decoration.table.title | |||
</h4> | |||
settings.almintegration.table.title | |||
</h2> | |||
<Button | |||
data-test="settings__alm-create" | |||
onClick={[MockFunction]} | |||
> | |||
settings.pr_decoration.table.create | |||
settings.almintegration.table.create | |||
</Button> | |||
</div> | |||
<table | |||
@@ -23,17 +23,17 @@ exports[`should render correctly 1`] = ` | |||
<thead> | |||
<tr> | |||
<th> | |||
settings.pr_decoration.table.column.name | |||
settings.almintegration.table.column.name | |||
</th> | |||
<th | |||
className="action-small text-center" | |||
> | |||
settings.pr_decoration.table.column.edit | |||
settings.almintegration.table.column.edit | |||
</th> | |||
<th | |||
className="action text-center" | |||
> | |||
settings.pr_decoration.table.column.delete | |||
settings.almintegration.table.column.delete | |||
</th> | |||
</tr> | |||
</thead> | |||
@@ -44,7 +44,7 @@ exports[`should render correctly 1`] = ` | |||
<td | |||
colSpan={3} | |||
> | |||
settings.pr_decoration.table.empty.azure | |||
settings.almintegration.table.empty.azure | |||
</td> | |||
</tr> | |||
</tbody> | |||
@@ -57,16 +57,16 @@ exports[`should render correctly: additional columns 1`] = ` | |||
<div | |||
className="spacer-top big-spacer-bottom display-flex-space-between" | |||
> | |||
<h4 | |||
className="display-inline" | |||
<h2 | |||
className="settings-sub-category-name" | |||
> | |||
settings.pr_decoration.table.title | |||
</h4> | |||
settings.almintegration.table.title | |||
</h2> | |||
<Button | |||
data-test="settings__alm-create" | |||
onClick={[MockFunction]} | |||
> | |||
settings.pr_decoration.table.create | |||
settings.almintegration.table.create | |||
</Button> | |||
</div> | |||
<table | |||
@@ -75,7 +75,7 @@ exports[`should render correctly: additional columns 1`] = ` | |||
<thead> | |||
<tr> | |||
<th> | |||
settings.pr_decoration.table.column.name | |||
settings.almintegration.table.column.name | |||
</th> | |||
<th | |||
key="additional1" | |||
@@ -90,12 +90,12 @@ exports[`should render correctly: additional columns 1`] = ` | |||
<th | |||
className="action-small text-center" | |||
> | |||
settings.pr_decoration.table.column.edit | |||
settings.almintegration.table.column.edit | |||
</th> | |||
<th | |||
className="action text-center" | |||
> | |||
settings.pr_decoration.table.column.delete | |||
settings.almintegration.table.column.delete | |||
</th> | |||
</tr> | |||
</thead> | |||
@@ -196,16 +196,16 @@ exports[`should render correctly: title adjusts for GitLab 1`] = ` | |||
<div | |||
className="spacer-top big-spacer-bottom display-flex-space-between" | |||
> | |||
<h4 | |||
className="display-inline" | |||
<h2 | |||
className="settings-sub-category-name" | |||
> | |||
settings.pr_decoration.table.title | |||
</h4> | |||
settings.almintegration.table.title | |||
</h2> | |||
<Button | |||
data-test="settings__alm-create" | |||
onClick={[MockFunction]} | |||
> | |||
settings.pr_decoration.table.create | |||
settings.almintegration.table.create | |||
</Button> | |||
</div> | |||
<table | |||
@@ -214,17 +214,17 @@ exports[`should render correctly: title adjusts for GitLab 1`] = ` | |||
<thead> | |||
<tr> | |||
<th> | |||
settings.pr_decoration.table.column.name | |||
settings.almintegration.table.column.name | |||
</th> | |||
<th | |||
className="action-small text-center" | |||
> | |||
settings.pr_decoration.table.column.edit | |||
settings.almintegration.table.column.edit | |||
</th> | |||
<th | |||
className="action text-center" | |||
> | |||
settings.pr_decoration.table.column.delete | |||
settings.almintegration.table.column.delete | |||
</th> | |||
</tr> | |||
</thead> | |||
@@ -235,7 +235,7 @@ exports[`should render correctly: title adjusts for GitLab 1`] = ` | |||
<td | |||
colSpan={3} | |||
> | |||
settings.pr_decoration.table.empty.github | |||
settings.almintegration.table.empty.gitlab | |||
</td> | |||
</tr> | |||
</tbody> |
@@ -1,7 +1,8 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Connect(withAppState(PRDecorationTabs)) | |||
<AlmIntegrationRenderer | |||
branchesEnabled={true} | |||
currentAlm="github" | |||
definitions={ | |||
Object { | |||
@@ -12,6 +13,7 @@ exports[`should render correctly 1`] = ` | |||
} | |||
} | |||
loading={true} | |||
multipleAlmEnabled={false} | |||
onCancel={[Function]} | |||
onConfirmDelete={[Function]} | |||
onDelete={[Function]} |
@@ -0,0 +1,97 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: default 1`] = ` | |||
<div | |||
className="boxed-group-inner display-flex-start width-30 spacer-right spacer-bottom bordered" | |||
> | |||
<CheckIcon | |||
className="little-spacer-top spacer-right" | |||
fill="#00aa00" | |||
/> | |||
<div | |||
className="display-flex-column abs-height-100" | |||
> | |||
<h4> | |||
Foo | |||
</h4> | |||
<div | |||
className="spacer-top flex-1" | |||
> | |||
Foo bar... | |||
</div> | |||
<div | |||
className="spacer-top" | |||
> | |||
<em | |||
className="text-success" | |||
> | |||
settings.almintegration.feature.enabled | |||
</em> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correctly: inactive 1`] = ` | |||
<div | |||
className="boxed-group-inner display-flex-start width-30 spacer-right spacer-bottom bordered bg-muted" | |||
> | |||
<ClearIcon | |||
className="little-spacer-top spacer-right" | |||
fill="#999" | |||
/> | |||
<div | |||
className="display-flex-column abs-height-100" | |||
> | |||
<h4> | |||
Foo | |||
</h4> | |||
<div | |||
className="spacer-top flex-1" | |||
> | |||
Foo bar... | |||
</div> | |||
<div | |||
className="spacer-top" | |||
> | |||
<em | |||
className="text-muted" | |||
> | |||
settings.almintegration.feature.disabled | |||
</em> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correctly: inactive, with reason 1`] = ` | |||
<div | |||
className="boxed-group-inner display-flex-start width-30 spacer-right spacer-bottom bordered bg-muted" | |||
> | |||
<ClearIcon | |||
className="little-spacer-top spacer-right" | |||
fill="#999" | |||
/> | |||
<div | |||
className="display-flex-column abs-height-100" | |||
> | |||
<h4> | |||
Foo | |||
</h4> | |||
<div | |||
className="spacer-top flex-1" | |||
> | |||
Foo bar... | |||
</div> | |||
<div | |||
className="spacer-top" | |||
> | |||
<em | |||
className="text-muted" | |||
> | |||
Bar is foo'd | |||
</em> | |||
</div> | |||
</div> | |||
</div> | |||
`; |
@@ -1,6 +1,6 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
exports[`should render correctly: azure 1`] = ` | |||
<Fragment> | |||
<header | |||
className="page-header" | |||
@@ -8,17 +8,17 @@ exports[`should render correctly 1`] = ` | |||
<h1 | |||
className="page-title" | |||
> | |||
settings.pr_decoration.title | |||
settings.almintegration.title | |||
</h1> | |||
</header> | |||
<div | |||
className="markdown small spacer-top big-spacer-bottom" | |||
> | |||
settings.pr_decoration.description | |||
settings.almintegration.description | |||
</div> | |||
<BoxedTabs | |||
onSelect={[MockFunction]} | |||
selected="github" | |||
selected="azure" | |||
tabs={ | |||
Array [ | |||
Object { | |||
@@ -44,6 +44,7 @@ exports[`should render correctly 1`] = ` | |||
/> | |||
Bitbucket Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "azure", | |||
@@ -56,6 +57,7 @@ exports[`should render correctly 1`] = ` | |||
/> | |||
Azure DevOps Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "gitlab", | |||
@@ -72,21 +74,17 @@ exports[`should render correctly 1`] = ` | |||
] | |||
} | |||
/> | |||
<div | |||
className="boxed-group boxed-group-inner" | |||
> | |||
<GithubTab | |||
definitions={Array []} | |||
loading={true} | |||
multipleAlmEnabled={false} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
/> | |||
</div> | |||
<AzureTab | |||
definitions={Array []} | |||
loading={false} | |||
multipleAlmEnabled={false} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly 2`] = ` | |||
exports[`should render correctly: bitbucket 1`] = ` | |||
<Fragment> | |||
<header | |||
className="page-header" | |||
@@ -94,17 +92,17 @@ exports[`should render correctly 2`] = ` | |||
<h1 | |||
className="page-title" | |||
> | |||
settings.pr_decoration.title | |||
settings.almintegration.title | |||
</h1> | |||
</header> | |||
<div | |||
className="markdown small spacer-top big-spacer-bottom" | |||
> | |||
settings.pr_decoration.description | |||
settings.almintegration.description | |||
</div> | |||
<BoxedTabs | |||
onSelect={[MockFunction]} | |||
selected="github" | |||
selected="bitbucket" | |||
tabs={ | |||
Array [ | |||
Object { | |||
@@ -130,6 +128,7 @@ exports[`should render correctly 2`] = ` | |||
/> | |||
Bitbucket Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "azure", | |||
@@ -142,6 +141,7 @@ exports[`should render correctly 2`] = ` | |||
/> | |||
Azure DevOps Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "gitlab", | |||
@@ -158,26 +158,17 @@ exports[`should render correctly 2`] = ` | |||
] | |||
} | |||
/> | |||
<div | |||
className="boxed-group boxed-group-inner" | |||
> | |||
<GithubTab | |||
definitions={Array []} | |||
loading={false} | |||
multipleAlmEnabled={false} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
/> | |||
</div> | |||
<DeleteModal | |||
id="keyToDelete" | |||
onCancel={[MockFunction]} | |||
<BitbucketTab | |||
definitions={Array []} | |||
loading={false} | |||
multipleAlmEnabled={false} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly 3`] = ` | |||
exports[`should render correctly: default 1`] = ` | |||
<Fragment> | |||
<header | |||
className="page-header" | |||
@@ -185,17 +176,17 @@ exports[`should render correctly 3`] = ` | |||
<h1 | |||
className="page-title" | |||
> | |||
settings.pr_decoration.title | |||
settings.almintegration.title | |||
</h1> | |||
</header> | |||
<div | |||
className="markdown small spacer-top big-spacer-bottom" | |||
> | |||
settings.pr_decoration.description | |||
settings.almintegration.description | |||
</div> | |||
<BoxedTabs | |||
onSelect={[MockFunction]} | |||
selected="azure" | |||
selected="github" | |||
tabs={ | |||
Array [ | |||
Object { | |||
@@ -221,6 +212,7 @@ exports[`should render correctly 3`] = ` | |||
/> | |||
Bitbucket Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "azure", | |||
@@ -233,6 +225,7 @@ exports[`should render correctly 3`] = ` | |||
/> | |||
Azure DevOps Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "gitlab", | |||
@@ -249,21 +242,18 @@ exports[`should render correctly 3`] = ` | |||
] | |||
} | |||
/> | |||
<div | |||
className="boxed-group boxed-group-inner" | |||
> | |||
<AzureTab | |||
definitions={Array []} | |||
loading={false} | |||
multipleAlmEnabled={false} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
/> | |||
</div> | |||
<GithubTab | |||
branchesEnabled={true} | |||
definitions={Array []} | |||
loading={false} | |||
multipleAlmEnabled={false} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly 4`] = ` | |||
exports[`should render correctly: delete modal 1`] = ` | |||
<Fragment> | |||
<header | |||
className="page-header" | |||
@@ -271,17 +261,17 @@ exports[`should render correctly 4`] = ` | |||
<h1 | |||
className="page-title" | |||
> | |||
settings.pr_decoration.title | |||
settings.almintegration.title | |||
</h1> | |||
</header> | |||
<div | |||
className="markdown small spacer-top big-spacer-bottom" | |||
> | |||
settings.pr_decoration.description | |||
settings.almintegration.description | |||
</div> | |||
<BoxedTabs | |||
onSelect={[MockFunction]} | |||
selected="bitbucket" | |||
selected="github" | |||
tabs={ | |||
Array [ | |||
Object { | |||
@@ -307,6 +297,7 @@ exports[`should render correctly 4`] = ` | |||
/> | |||
Bitbucket Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "azure", | |||
@@ -319,6 +310,7 @@ exports[`should render correctly 4`] = ` | |||
/> | |||
Azure DevOps Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "gitlab", | |||
@@ -335,21 +327,23 @@ exports[`should render correctly 4`] = ` | |||
] | |||
} | |||
/> | |||
<div | |||
className="boxed-group boxed-group-inner" | |||
> | |||
<BitbucketTab | |||
definitions={Array []} | |||
loading={false} | |||
multipleAlmEnabled={false} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
/> | |||
</div> | |||
<GithubTab | |||
branchesEnabled={true} | |||
definitions={Array []} | |||
loading={false} | |||
multipleAlmEnabled={false} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
/> | |||
<DeleteModal | |||
id="keyToDelete" | |||
onCancel={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly 5`] = ` | |||
exports[`should render correctly: gitlab 1`] = ` | |||
<Fragment> | |||
<header | |||
className="page-header" | |||
@@ -357,13 +351,13 @@ exports[`should render correctly 5`] = ` | |||
<h1 | |||
className="page-title" | |||
> | |||
settings.pr_decoration.title | |||
settings.almintegration.title | |||
</h1> | |||
</header> | |||
<div | |||
className="markdown small spacer-top big-spacer-bottom" | |||
> | |||
settings.pr_decoration.description | |||
settings.almintegration.description | |||
</div> | |||
<BoxedTabs | |||
onSelect={[MockFunction]} | |||
@@ -393,6 +387,7 @@ exports[`should render correctly 5`] = ` | |||
/> | |||
Bitbucket Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "azure", | |||
@@ -405,6 +400,7 @@ exports[`should render correctly 5`] = ` | |||
/> | |||
Azure DevOps Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "gitlab", | |||
@@ -421,16 +417,98 @@ exports[`should render correctly 5`] = ` | |||
] | |||
} | |||
/> | |||
<GitlabTab | |||
branchesEnabled={true} | |||
definitions={Array []} | |||
loading={false} | |||
multipleAlmEnabled={false} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: loading 1`] = ` | |||
<Fragment> | |||
<header | |||
className="page-header" | |||
> | |||
<h1 | |||
className="page-title" | |||
> | |||
settings.almintegration.title | |||
</h1> | |||
</header> | |||
<div | |||
className="boxed-group boxed-group-inner" | |||
className="markdown small spacer-top big-spacer-bottom" | |||
> | |||
<GitlabTab | |||
definitions={Array []} | |||
loading={false} | |||
multipleAlmEnabled={false} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
/> | |||
settings.almintegration.description | |||
</div> | |||
<BoxedTabs | |||
onSelect={[MockFunction]} | |||
selected="github" | |||
tabs={ | |||
Array [ | |||
Object { | |||
"key": "github", | |||
"label": <React.Fragment> | |||
<img | |||
alt="github" | |||
className="spacer-right" | |||
height={16} | |||
src="/images/alm/github.svg" | |||
/> | |||
GitHub | |||
</React.Fragment>, | |||
}, | |||
Object { | |||
"key": "bitbucket", | |||
"label": <React.Fragment> | |||
<img | |||
alt="bitbucket" | |||
className="spacer-right" | |||
height={16} | |||
src="/images/alm/bitbucket.svg" | |||
/> | |||
Bitbucket Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "azure", | |||
"label": <React.Fragment> | |||
<img | |||
alt="azure" | |||
className="spacer-right" | |||
height={16} | |||
src="/images/alm/azure.svg" | |||
/> | |||
Azure DevOps Server | |||
</React.Fragment>, | |||
"requiresBranchesEnabled": true, | |||
}, | |||
Object { | |||
"key": "gitlab", | |||
"label": <React.Fragment> | |||
<img | |||
alt="gitlab" | |||
className="spacer-right" | |||
height={16} | |||
src="/images/alm/gitlab.svg" | |||
/> | |||
GitLab | |||
</React.Fragment>, | |||
}, | |||
] | |||
} | |||
/> | |||
<GithubTab | |||
branchesEnabled={true} | |||
definitions={Array []} | |||
loading={true} | |||
multipleAlmEnabled={false} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
/> | |||
</Fragment> | |||
`; |
@@ -0,0 +1,334 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly for multi-ALM binding: editing a definition 1`] = ` | |||
<div | |||
className="big-padded" | |||
> | |||
<DeferredSpinner | |||
loading={false} | |||
timeout={100} | |||
> | |||
<AlmBindingDefinitionsTable | |||
additionalColumnsHeaders={ | |||
Array [ | |||
"url", | |||
"app_id", | |||
] | |||
} | |||
alm="github" | |||
definitions={ | |||
Array [ | |||
Object { | |||
"additionalColumns": Array [ | |||
"http://github.enterprise.com", | |||
"123456", | |||
], | |||
"key": "key", | |||
}, | |||
] | |||
} | |||
onCreate={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
/> | |||
<AlmBindingDefinitionForm | |||
bindingDefinition={ | |||
Object { | |||
"appId": "123456", | |||
"key": "key", | |||
"privateKey": "asdf1234", | |||
"url": "http://github.enterprise.com", | |||
} | |||
} | |||
help={ | |||
<FormattedMessage | |||
defaultMessage="settings.almintegration.github.info" | |||
id="settings.almintegration.github.info" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/pr-decoration/" | |||
> | |||
learn_more | |||
</Link>, | |||
} | |||
} | |||
/> | |||
} | |||
onCancel={[MockFunction]} | |||
onSubmit={[MockFunction]} | |||
showInModal={true} | |||
> | |||
<Component /> | |||
</AlmBindingDefinitionForm> | |||
</DeferredSpinner> | |||
</div> | |||
`; | |||
exports[`should render correctly for multi-ALM binding: loaded 1`] = ` | |||
<div | |||
className="big-padded" | |||
> | |||
<DeferredSpinner | |||
loading={false} | |||
timeout={100} | |||
> | |||
<AlmBindingDefinitionsTable | |||
additionalColumnsHeaders={ | |||
Array [ | |||
"url", | |||
"app_id", | |||
] | |||
} | |||
alm="github" | |||
definitions={ | |||
Array [ | |||
Object { | |||
"additionalColumns": Array [ | |||
"http://github.enterprise.com", | |||
"123456", | |||
], | |||
"key": "key", | |||
}, | |||
] | |||
} | |||
onCreate={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
/> | |||
</DeferredSpinner> | |||
</div> | |||
`; | |||
exports[`should render correctly for multi-ALM binding: loading 1`] = ` | |||
<div | |||
className="big-padded" | |||
> | |||
<DeferredSpinner | |||
loading={true} | |||
timeout={100} | |||
> | |||
<AlmBindingDefinitionsTable | |||
additionalColumnsHeaders={ | |||
Array [ | |||
"url", | |||
"app_id", | |||
] | |||
} | |||
alm="github" | |||
definitions={ | |||
Array [ | |||
Object { | |||
"additionalColumns": Array [ | |||
"http://github.enterprise.com", | |||
"123456", | |||
], | |||
"key": "key", | |||
}, | |||
] | |||
} | |||
onCreate={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
/> | |||
</DeferredSpinner> | |||
</div> | |||
`; | |||
exports[`should render correctly for multi-ALM binding: with features 1`] = ` | |||
<div | |||
className="big-padded" | |||
> | |||
<DeferredSpinner | |||
loading={false} | |||
timeout={100} | |||
> | |||
<AlmBindingDefinitionsTable | |||
additionalColumnsHeaders={ | |||
Array [ | |||
"url", | |||
"app_id", | |||
] | |||
} | |||
alm="github" | |||
definitions={ | |||
Array [ | |||
Object { | |||
"additionalColumns": Array [ | |||
"http://github.enterprise.com", | |||
"123456", | |||
], | |||
"key": "key", | |||
}, | |||
] | |||
} | |||
onCreate={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
/> | |||
</DeferredSpinner> | |||
<div | |||
className="big-spacer-top big-padded-top bordered-top" | |||
> | |||
<h3 | |||
className="big-spacer-bottom" | |||
> | |||
settings.almintegration.features | |||
</h3> | |||
<div | |||
className="display-flex-wrap" | |||
> | |||
<AlmIntegrationFeatureBox | |||
active={true} | |||
description="Bar" | |||
key="0" | |||
name="Foo" | |||
/> | |||
<AlmIntegrationFeatureBox | |||
active={false} | |||
description="Bim" | |||
key="1" | |||
name="Baz" | |||
/> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correctly for single-ALM binding 1`] = ` | |||
<div | |||
className="big-padded" | |||
> | |||
<AlmBindingDefinitionForm | |||
bindingDefinition={ | |||
Object { | |||
"appId": "123456", | |||
"key": "key", | |||
"privateKey": "asdf1234", | |||
"url": "http://github.enterprise.com", | |||
} | |||
} | |||
help={ | |||
<FormattedMessage | |||
defaultMessage="settings.almintegration.github.info" | |||
id="settings.almintegration.github.info" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/pr-decoration/" | |||
> | |||
learn_more | |||
</Link>, | |||
} | |||
} | |||
/> | |||
} | |||
hideKeyField={true} | |||
loading={true} | |||
onCancel={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
onSubmit={[MockFunction]} | |||
readOnly={true} | |||
success={false} | |||
> | |||
<Component /> | |||
</AlmBindingDefinitionForm> | |||
</div> | |||
`; | |||
exports[`should render correctly for single-ALM binding 2`] = ` | |||
<div | |||
className="big-padded" | |||
> | |||
<AlmBindingDefinitionForm | |||
bindingDefinition={ | |||
Object { | |||
"appId": "123456", | |||
"key": "key", | |||
"privateKey": "asdf1234", | |||
"url": "http://github.enterprise.com", | |||
} | |||
} | |||
help={ | |||
<FormattedMessage | |||
defaultMessage="settings.almintegration.github.info" | |||
id="settings.almintegration.github.info" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/pr-decoration/" | |||
> | |||
learn_more | |||
</Link>, | |||
} | |||
} | |||
/> | |||
} | |||
hideKeyField={true} | |||
loading={false} | |||
onCancel={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
onSubmit={[MockFunction]} | |||
readOnly={true} | |||
success={false} | |||
> | |||
<Component /> | |||
</AlmBindingDefinitionForm> | |||
</div> | |||
`; | |||
exports[`should render correctly for single-ALM binding 3`] = ` | |||
<div | |||
className="big-padded" | |||
> | |||
<AlmBindingDefinitionForm | |||
bindingDefinition={ | |||
Object { | |||
"appId": "123456", | |||
"key": "key", | |||
"privateKey": "asdf1234", | |||
"url": "http://github.enterprise.com", | |||
} | |||
} | |||
help={ | |||
<FormattedMessage | |||
defaultMessage="settings.almintegration.github.info" | |||
id="settings.almintegration.github.info" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/pr-decoration/" | |||
> | |||
learn_more | |||
</Link>, | |||
} | |||
} | |||
/> | |||
} | |||
hideKeyField={true} | |||
loading={false} | |||
onCancel={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
onSubmit={[MockFunction]} | |||
readOnly={true} | |||
success={false} | |||
> | |||
<Component /> | |||
</AlmBindingDefinitionForm> | |||
</div> | |||
`; |
@@ -2,16 +2,16 @@ | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help="settings.pr_decoration.form.name.azure.help" | |||
help="settings.almintegration.form.name.azure.help" | |||
id="name.azure" | |||
onFieldChange={[MockFunction]} | |||
propKey="key" | |||
value="" | |||
/> | |||
<AlmDefinitionFormField | |||
help="settings.pr_decoration.form.personal_access_token.azure.help" | |||
<AlmBindingDefinitionFormField | |||
help="settings.almintegration.form.personal_access_token.azure.help" | |||
id="personal_access_token" | |||
isTextArea={true} | |||
onFieldChange={[MockFunction]} | |||
@@ -23,16 +23,16 @@ exports[`should render correctly 1`] = ` | |||
exports[`should render correctly 2`] = ` | |||
<Fragment> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help="settings.pr_decoration.form.name.azure.help" | |||
help="settings.almintegration.form.name.azure.help" | |||
id="name.azure" | |||
onFieldChange={[MockFunction]} | |||
propKey="key" | |||
value="key" | |||
/> | |||
<AlmDefinitionFormField | |||
help="settings.pr_decoration.form.personal_access_token.azure.help" | |||
<AlmBindingDefinitionFormField | |||
help="settings.almintegration.form.personal_access_token.azure.help" | |||
id="personal_access_token" | |||
isTextArea={true} | |||
onFieldChange={[MockFunction]} |
@@ -0,0 +1,42 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<div | |||
className="bordered" | |||
> | |||
<AlmTab | |||
alm="azure" | |||
createConfiguration={[Function]} | |||
defaultBinding={ | |||
Object { | |||
"key": "", | |||
"personalAccessToken": "", | |||
} | |||
} | |||
definitions={ | |||
Array [ | |||
Object { | |||
"key": "key", | |||
"personalAccessToken": "asdf1234", | |||
}, | |||
] | |||
} | |||
features={ | |||
Array [ | |||
Object { | |||
"active": true, | |||
"description": "settings.almintegration.feature.pr_decoration.description", | |||
"inactiveReason": "settings.almintegration.feature.need_at_least_1_binding", | |||
"name": "settings.almintegration.feature.pr_decoration.title", | |||
}, | |||
] | |||
} | |||
form={[Function]} | |||
loading={false} | |||
multipleAlmEnabled={true} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
updateConfiguration={[Function]} | |||
/> | |||
</div> | |||
`; |
@@ -2,20 +2,20 @@ | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help="settings.pr_decoration.form.name.bitbucket.help" | |||
help="settings.almintegration.form.name.bitbucket.help" | |||
id="name.bitbucket" | |||
maxLength={100} | |||
onFieldChange={[MockFunction]} | |||
propKey="key" | |||
value="" | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
help={ | |||
<FormattedMessage | |||
defaultMessage="settings.pr_decoration.form.url.bitbucket.help" | |||
id="settings.pr_decoration.form.url.bitbucket.help" | |||
defaultMessage="settings.almintegration.form.url.bitbucket.help" | |||
id="settings.almintegration.form.url.bitbucket.help" | |||
values={ | |||
Object { | |||
"example": "https://bitbucket-server.your-company.com", | |||
@@ -29,7 +29,7 @@ exports[`should render correctly 1`] = ` | |||
propKey="url" | |||
value="" | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
id="personal_access_token" | |||
isTextArea={true} | |||
onFieldChange={[MockFunction]} | |||
@@ -41,20 +41,20 @@ exports[`should render correctly 1`] = ` | |||
exports[`should render correctly 2`] = ` | |||
<Fragment> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help="settings.pr_decoration.form.name.bitbucket.help" | |||
help="settings.almintegration.form.name.bitbucket.help" | |||
id="name.bitbucket" | |||
maxLength={100} | |||
onFieldChange={[MockFunction]} | |||
propKey="key" | |||
value="key" | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
help={ | |||
<FormattedMessage | |||
defaultMessage="settings.pr_decoration.form.url.bitbucket.help" | |||
id="settings.pr_decoration.form.url.bitbucket.help" | |||
defaultMessage="settings.almintegration.form.url.bitbucket.help" | |||
id="settings.almintegration.form.url.bitbucket.help" | |||
values={ | |||
Object { | |||
"example": "https://bitbucket-server.your-company.com", | |||
@@ -68,7 +68,7 @@ exports[`should render correctly 2`] = ` | |||
propKey="url" | |||
value="http://bbs.enterprise.com" | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
id="personal_access_token" | |||
isTextArea={true} | |||
onFieldChange={[MockFunction]} |
@@ -0,0 +1,112 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<div | |||
className="bordered" | |||
> | |||
<AlmTab | |||
additionalColumnsHeaders={ | |||
Array [ | |||
"settings.almintegration.table.column.bitbucket.url", | |||
] | |||
} | |||
additionalColumnsKeys={ | |||
Array [ | |||
"url", | |||
] | |||
} | |||
additionalTableInfo={ | |||
<Alert | |||
className="big-spacer-bottom width-50" | |||
variant="info" | |||
> | |||
<FormattedMessage | |||
defaultMessage="settings.almintegration.feature.alm_repo_import.disabled_if_multiple_bbs_instances" | |||
id="settings.almintegration.feature.alm_repo_import.disabled_if_multiple_bbs_instances" | |||
values={ | |||
Object { | |||
"feature": <em> | |||
settings.almintegration.feature.alm_repo_import.title | |||
</em>, | |||
} | |||
} | |||
/> | |||
</Alert> | |||
} | |||
alm="bitbucket" | |||
createConfiguration={[Function]} | |||
defaultBinding={ | |||
Object { | |||
"key": "", | |||
"personalAccessToken": "", | |||
"url": "", | |||
} | |||
} | |||
definitions={ | |||
Array [ | |||
Object { | |||
"key": "key", | |||
"personalAccessToken": "asdf1234", | |||
"url": "http://bbs.enterprise.com", | |||
}, | |||
] | |||
} | |||
features={ | |||
Array [ | |||
Object { | |||
"active": true, | |||
"description": "settings.almintegration.feature.pr_decoration.description", | |||
"inactiveReason": "settings.almintegration.feature.need_at_least_1_binding", | |||
"name": "settings.almintegration.feature.pr_decoration.title", | |||
}, | |||
Object { | |||
"active": true, | |||
"description": "settings.almintegration.feature.alm_repo_import.description", | |||
"inactiveReason": "onboarding.create_project.too_many_bbs_instances_X.1", | |||
"name": "settings.almintegration.feature.alm_repo_import.title", | |||
}, | |||
] | |||
} | |||
form={[Function]} | |||
help={ | |||
<React.Fragment> | |||
<h3> | |||
onboarding.create_project.pat_help.title | |||
</h3> | |||
<p | |||
className="big-spacer-top" | |||
> | |||
settings.almintegration.bitbucket.help_1 | |||
</p> | |||
<ul | |||
className="big-spacer-top list-styled" | |||
> | |||
<li> | |||
settings.almintegration.bitbucket.help_2 | |||
</li> | |||
<li> | |||
settings.almintegration.bitbucket.help_3 | |||
</li> | |||
</ul> | |||
<p | |||
className="big-spacer-top big-spacer-bottom" | |||
> | |||
<Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/pr-decoration/" | |||
> | |||
learn_more | |||
</Link> | |||
</p> | |||
</React.Fragment> | |||
} | |||
loading={false} | |||
multipleAlmEnabled={true} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
updateConfiguration={[Function]} | |||
/> | |||
</div> | |||
`; |
@@ -4,7 +4,7 @@ exports[`should render correctly 1`] = ` | |||
<ConfirmModal | |||
confirmButtonText="delete" | |||
confirmData="1" | |||
header="settings.pr_decoration.delete.header" | |||
header="settings.almintegration.delete.header" | |||
isDestructive={true} | |||
onClose={[MockFunction]} | |||
onConfirm={[MockFunction]} | |||
@@ -13,8 +13,8 @@ exports[`should render correctly 1`] = ` | |||
className="spacer-bottom" | |||
> | |||
<FormattedMessage | |||
defaultMessage="settings.pr_decoration.delete.message" | |||
id="settings.pr_decoration.delete.message" | |||
defaultMessage="settings.almintegration.delete.message" | |||
id="settings.almintegration.delete.message" | |||
values={ | |||
Object { | |||
"id": <b> | |||
@@ -25,7 +25,7 @@ exports[`should render correctly 1`] = ` | |||
/> | |||
</p> | |||
<p> | |||
settings.pr_decoration.delete.info.4 | |||
settings.almintegration.delete.info.4 | |||
</p> | |||
</ConfirmModal> | |||
@@ -35,7 +35,7 @@ exports[`should render correctly 2`] = ` | |||
<ConfirmModal | |||
confirmButtonText="delete" | |||
confirmData="1" | |||
header="settings.pr_decoration.delete.header" | |||
header="settings.almintegration.delete.header" | |||
isDestructive={true} | |||
onClose={[MockFunction]} | |||
onConfirm={[MockFunction]} | |||
@@ -44,8 +44,8 @@ exports[`should render correctly 2`] = ` | |||
className="spacer-bottom" | |||
> | |||
<FormattedMessage | |||
defaultMessage="settings.pr_decoration.delete.message" | |||
id="settings.pr_decoration.delete.message" | |||
defaultMessage="settings.almintegration.delete.message" | |||
id="settings.almintegration.delete.message" | |||
values={ | |||
Object { | |||
"id": <b> | |||
@@ -56,7 +56,7 @@ exports[`should render correctly 2`] = ` | |||
/> | |||
</p> | |||
<p> | |||
settings.pr_decoration.delete.no_info | |||
settings.almintegration.delete.no_info | |||
</p> | |||
</ConfirmModal> | |||
`; |
@@ -2,25 +2,25 @@ | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help="settings.pr_decoration.form.name.github.help" | |||
help="settings.almintegration.form.name.github.help" | |||
id="name.github" | |||
onFieldChange={[MockFunction]} | |||
propKey="key" | |||
value="" | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
help={ | |||
<React.Fragment> | |||
settings.pr_decoration.form.url.github.help1 | |||
settings.almintegration.form.url.github.help1 | |||
<br /> | |||
<em> | |||
https://github.company.com/api/v3 | |||
</em> | |||
<br /> | |||
<br /> | |||
settings.pr_decoration.form.url.github.help2 | |||
settings.almintegration.form.url.github.help2 | |||
<br /> | |||
<em> | |||
https://api.github.com/ | |||
@@ -33,14 +33,14 @@ exports[`should render correctly 1`] = ` | |||
propKey="url" | |||
value="" | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
id="app_id" | |||
maxLength={80} | |||
onFieldChange={[MockFunction]} | |||
propKey="appId" | |||
value="" | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
id="private_key" | |||
isTextArea={true} | |||
onFieldChange={[MockFunction]} | |||
@@ -52,25 +52,25 @@ exports[`should render correctly 1`] = ` | |||
exports[`should render correctly 2`] = ` | |||
<Fragment> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help="settings.pr_decoration.form.name.github.help" | |||
help="settings.almintegration.form.name.github.help" | |||
id="name.github" | |||
onFieldChange={[MockFunction]} | |||
propKey="key" | |||
value="key" | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
help={ | |||
<React.Fragment> | |||
settings.pr_decoration.form.url.github.help1 | |||
settings.almintegration.form.url.github.help1 | |||
<br /> | |||
<em> | |||
https://github.company.com/api/v3 | |||
</em> | |||
<br /> | |||
<br /> | |||
settings.pr_decoration.form.url.github.help2 | |||
settings.almintegration.form.url.github.help2 | |||
<br /> | |||
<em> | |||
https://api.github.com/ | |||
@@ -83,14 +83,14 @@ exports[`should render correctly 2`] = ` | |||
propKey="url" | |||
value="http://github.enterprise.com" | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
id="app_id" | |||
maxLength={80} | |||
onFieldChange={[MockFunction]} | |||
propKey="appId" | |||
value="123456" | |||
/> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
id="private_key" | |||
isTextArea={true} | |||
onFieldChange={[MockFunction]} |
@@ -0,0 +1,84 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: with branch support 1`] = ` | |||
<div | |||
className="bordered" | |||
> | |||
<AlmTab | |||
additionalColumnsHeaders={ | |||
Array [ | |||
"settings.almintegration.table.column.github.url", | |||
"settings.almintegration.table.column.app_id", | |||
] | |||
} | |||
additionalColumnsKeys={ | |||
Array [ | |||
"appId", | |||
"url", | |||
] | |||
} | |||
alm="github" | |||
createConfiguration={[Function]} | |||
defaultBinding={ | |||
Object { | |||
"appId": "", | |||
"key": "", | |||
"privateKey": "", | |||
"url": "", | |||
} | |||
} | |||
definitions={ | |||
Array [ | |||
Object { | |||
"appId": "123456", | |||
"key": "key", | |||
"privateKey": "asdf1234", | |||
"url": "http://github.enterprise.com", | |||
}, | |||
] | |||
} | |||
features={ | |||
Array [ | |||
Object { | |||
"active": true, | |||
"description": "settings.almintegration.feature.pr_decoration.description", | |||
"inactiveReason": "settings.almintegration.feature.need_at_least_1_binding", | |||
"name": "settings.almintegration.feature.pr_decoration.title", | |||
}, | |||
] | |||
} | |||
form={[Function]} | |||
loading={false} | |||
multipleAlmEnabled={true} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
updateConfiguration={[Function]} | |||
/> | |||
<div | |||
className="huge-spacer-top huge-spacer-bottom bordered-top" | |||
/> | |||
<div | |||
className="big-padded" | |||
> | |||
<Connect(SubCategoryDefinitionsList) | |||
category="almintegration" | |||
subCategory="github" | |||
/> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correctly: without branch support 1`] = ` | |||
<div | |||
className="bordered" | |||
> | |||
<div | |||
className="big-padded" | |||
> | |||
<Connect(SubCategoryDefinitionsList) | |||
category="almintegration" | |||
subCategory="github" | |||
/> | |||
</div> | |||
</div> | |||
`; |
@@ -2,16 +2,16 @@ | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help="settings.pr_decoration.form.name.gitlab.help" | |||
help="settings.almintegration.form.name.gitlab.help" | |||
id="name.gitlab" | |||
onFieldChange={[MockFunction]} | |||
propKey="key" | |||
value="" | |||
/> | |||
<AlmDefinitionFormField | |||
help="settings.pr_decoration.form.personal_access_token.gitlab.help" | |||
<AlmBindingDefinitionFormField | |||
help="settings.almintegration.form.personal_access_token.gitlab.help" | |||
id="personal_access_token" | |||
isTextArea={true} | |||
onFieldChange={[MockFunction]} | |||
@@ -23,16 +23,16 @@ exports[`should render correctly 1`] = ` | |||
exports[`should render correctly 2`] = ` | |||
<Fragment> | |||
<AlmDefinitionFormField | |||
<AlmBindingDefinitionFormField | |||
autoFocus={true} | |||
help="settings.pr_decoration.form.name.gitlab.help" | |||
help="settings.almintegration.form.name.gitlab.help" | |||
id="name.gitlab" | |||
onFieldChange={[MockFunction]} | |||
propKey="key" | |||
value="foo" | |||
/> | |||
<AlmDefinitionFormField | |||
help="settings.pr_decoration.form.personal_access_token.gitlab.help" | |||
<AlmBindingDefinitionFormField | |||
help="settings.almintegration.form.personal_access_token.gitlab.help" | |||
id="personal_access_token" | |||
isTextArea={true} | |||
onFieldChange={[MockFunction]} |
@@ -0,0 +1,68 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: with branch support 1`] = ` | |||
<div | |||
className="bordered" | |||
> | |||
<AlmTab | |||
alm="gitlab" | |||
createConfiguration={[Function]} | |||
defaultBinding={ | |||
Object { | |||
"key": "", | |||
"personalAccessToken": "", | |||
} | |||
} | |||
definitions={ | |||
Array [ | |||
Object { | |||
"key": "foo", | |||
"personalAccessToken": "foobar", | |||
}, | |||
] | |||
} | |||
features={ | |||
Array [ | |||
Object { | |||
"active": true, | |||
"description": "settings.almintegration.feature.mr_decoration.description", | |||
"inactiveReason": "settings.almintegration.feature.need_at_least_1_binding", | |||
"name": "settings.almintegration.feature.mr_decoration.title", | |||
}, | |||
] | |||
} | |||
form={[Function]} | |||
loading={false} | |||
multipleAlmEnabled={true} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
updateConfiguration={[Function]} | |||
/> | |||
<div | |||
className="huge-spacer-top huge-spacer-bottom bordered-top" | |||
/> | |||
<div | |||
className="big-padded" | |||
> | |||
<Connect(SubCategoryDefinitionsList) | |||
category="almintegration" | |||
subCategory="gitlab" | |||
/> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correctly: without branch support 1`] = ` | |||
<div | |||
className="bordered" | |||
> | |||
<div | |||
className="big-padded" | |||
> | |||
<Connect(SubCategoryDefinitionsList) | |||
category="almintegration" | |||
subCategory="gitlab" | |||
/> | |||
</div> | |||
</div> | |||
`; |
@@ -1,136 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { FormattedMessage } from 'react-intl'; | |||
import { Link } from 'react-router'; | |||
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { AlmSettingsBinding, ALM_KEYS } from '../../../../types/alm-settings'; | |||
import AlmPRDecorationForm, { AlmPRDecorationFormChildrenProps } from './AlmPRDecorationForm'; | |||
import AlmPRDecorationTable from './AlmPRDecorationTable'; | |||
export interface AlmTabRendererProps<B> { | |||
additionalColumnsHeaders: string[]; | |||
additionalColumnsKeys: Array<keyof B>; | |||
alm: ALM_KEYS; | |||
editedDefinition?: B; | |||
defaultBinding: B; | |||
definitions: B[]; | |||
form: (props: AlmPRDecorationFormChildrenProps<B>) => React.ReactNode; | |||
loading: boolean; | |||
multipleAlmEnabled: boolean; | |||
onCancel: () => void; | |||
onCreate: () => void; | |||
onDelete: (definitionKey: string) => void; | |||
onEdit: (definitionKey: string) => void; | |||
onSubmit: (config: B, originalKey: string) => void; | |||
success: boolean; | |||
} | |||
export default function AlmTabRenderer<B extends AlmSettingsBinding>( | |||
props: AlmTabRendererProps<B> | |||
) { | |||
const { | |||
additionalColumnsHeaders, | |||
additionalColumnsKeys, | |||
alm, | |||
defaultBinding, | |||
definitions, | |||
editedDefinition, | |||
form, | |||
loading, | |||
multipleAlmEnabled, | |||
success | |||
} = props; | |||
let definition: B | undefined; | |||
let mappedDefinitions: Array<{ key: string; additionalColumns: string[] }> = []; | |||
let showEdit: boolean | undefined; | |||
if (!multipleAlmEnabled) { | |||
definition = editedDefinition; | |||
if (definition === undefined && definitions.length > 0) { | |||
definition = definitions[0]; | |||
} | |||
showEdit = definition && editedDefinition === undefined; | |||
} else { | |||
mappedDefinitions = definitions.map(({ key, ...properties }) => { | |||
const additionalColumns = additionalColumnsKeys.map(k => (properties as any)[k]); | |||
return { | |||
key, | |||
additionalColumns | |||
}; | |||
}); | |||
} | |||
const help = ( | |||
<FormattedMessage | |||
defaultMessage={translate(`settings.pr_decoration.${alm}.info`)} | |||
id={`settings.pr_decoration.${alm}.info`} | |||
values={{ | |||
link: ( | |||
<Link target="_blank" to="/documentation/analysis/pr-decoration/"> | |||
{translate('learn_more')} | |||
</Link> | |||
) | |||
}} | |||
/> | |||
); | |||
return multipleAlmEnabled ? ( | |||
<DeferredSpinner loading={loading}> | |||
<AlmPRDecorationTable | |||
additionalColumnsHeaders={additionalColumnsHeaders} | |||
alm={alm} | |||
definitions={mappedDefinitions} | |||
onCreate={props.onCreate} | |||
onDelete={props.onDelete} | |||
onEdit={props.onEdit} | |||
/> | |||
{editedDefinition && ( | |||
<AlmPRDecorationForm | |||
alm={alm} | |||
bindingDefinition={editedDefinition} | |||
help={help} | |||
onCancel={props.onCancel} | |||
onSubmit={props.onSubmit} | |||
showInModal={true}> | |||
{form} | |||
</AlmPRDecorationForm> | |||
)} | |||
</DeferredSpinner> | |||
) : ( | |||
<AlmPRDecorationForm | |||
alm={alm} | |||
bindingDefinition={definition || defaultBinding} | |||
help={help} | |||
hideKeyField={true} | |||
loading={loading} | |||
onCancel={props.onCancel} | |||
onDelete={definition ? props.onDelete : undefined} | |||
onEdit={showEdit ? props.onEdit : undefined} | |||
onSubmit={props.onSubmit} | |||
readOnly={showEdit} | |||
success={success}> | |||
{form} | |||
</AlmPRDecorationForm> | |||
); | |||
} |
@@ -1,57 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { | |||
createBitbucketConfiguration, | |||
updateBitbucketConfiguration | |||
} from '../../../../api/almSettings'; | |||
import { ALM_KEYS, BitbucketBindingDefinition } from '../../../../types/alm-settings'; | |||
import AlmTab from './AlmTab'; | |||
import BitbucketForm from './BitbucketForm'; | |||
export interface BitbucketTabProps { | |||
definitions: BitbucketBindingDefinition[]; | |||
loading: boolean; | |||
multipleAlmEnabled: boolean; | |||
onDelete: (definitionKey: string) => void; | |||
onUpdateDefinitions: () => void; | |||
} | |||
export default function BitbucketTab(props: BitbucketTabProps) { | |||
const { multipleAlmEnabled, definitions, loading } = props; | |||
return ( | |||
<AlmTab | |||
additionalColumnsHeaders={[translate('settings.pr_decoration.table.column.bitbucket.url')]} | |||
additionalColumnsKeys={['url']} | |||
alm={ALM_KEYS.BITBUCKET} | |||
createConfiguration={createBitbucketConfiguration} | |||
defaultBinding={{ key: '', url: '', personalAccessToken: '' }} | |||
definitions={definitions} | |||
form={childProps => <BitbucketForm {...childProps} />} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
updateConfiguration={updateBitbucketConfiguration} | |||
/> | |||
); | |||
} |
@@ -1,57 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { createGithubConfiguration, updateGithubConfiguration } from '../../../../api/almSettings'; | |||
import { ALM_KEYS, GithubBindingDefinition } from '../../../../types/alm-settings'; | |||
import AlmTab from './AlmTab'; | |||
import GithubForm from './GithubForm'; | |||
export interface GithubTabProps { | |||
definitions: GithubBindingDefinition[]; | |||
loading: boolean; | |||
multipleAlmEnabled: boolean; | |||
onDelete: (definitionKey: string) => void; | |||
onUpdateDefinitions: () => void; | |||
} | |||
export default function GithubTab(props: GithubTabProps) { | |||
const { multipleAlmEnabled, definitions, loading } = props; | |||
return ( | |||
<AlmTab | |||
additionalColumnsHeaders={[ | |||
translate('settings.pr_decoration.table.column.github.url'), | |||
translate('settings.pr_decoration.table.column.app_id') | |||
]} | |||
additionalColumnsKeys={['appId', 'url']} | |||
alm={ALM_KEYS.GITHUB} | |||
createConfiguration={createGithubConfiguration} | |||
defaultBinding={{ key: '', appId: '', url: '', privateKey: '' }} | |||
definitions={definitions} | |||
form={childProps => <GithubForm {...childProps} />} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
updateConfiguration={updateGithubConfiguration} | |||
/> | |||
); | |||
} |
@@ -1,51 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { createGitlabConfiguration, updateGitlabConfiguration } from '../../../../api/almSettings'; | |||
import { ALM_KEYS, GitlabBindingDefinition } from '../../../../types/alm-settings'; | |||
import AlmTab from './AlmTab'; | |||
import GitlabForm from './GitlabForm'; | |||
export interface GitlabTabProps { | |||
definitions: GitlabBindingDefinition[]; | |||
loading: boolean; | |||
multipleAlmEnabled: boolean; | |||
onDelete: (definitionKey: string) => void; | |||
onUpdateDefinitions: () => void; | |||
} | |||
export default function GitlabTab(props: GitlabTabProps) { | |||
const { multipleAlmEnabled, definitions, loading } = props; | |||
return ( | |||
<AlmTab | |||
alm={ALM_KEYS.GITLAB} | |||
createConfiguration={createGitlabConfiguration} | |||
defaultBinding={{ key: '', personalAccessToken: '' }} | |||
definitions={definitions} | |||
form={childProps => <GitlabForm {...childProps} />} | |||
loading={loading} | |||
multipleAlmEnabled={multipleAlmEnabled} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
updateConfiguration={updateGitlabConfiguration} | |||
/> | |||
); | |||
} |
@@ -1,186 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 BoxedTabs from 'sonar-ui-common/components/controls/BoxedTabs'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { getBaseUrl } from 'sonar-ui-common/helpers/urls'; | |||
import { withAppState } from '../../../../components/hoc/withAppState'; | |||
import { AlmSettingsBindingDefinitions, ALM_KEYS } from '../../../../types/alm-settings'; | |||
import AzureTab from './AzureTab'; | |||
import BitbucketTab from './BitbucketTab'; | |||
import DeleteModal from './DeleteModal'; | |||
import GithubTab from './GithubTab'; | |||
import GitlabTab from './GitlabTab'; | |||
export interface PRDecorationTabsProps { | |||
appState: Pick<T.AppState, 'multipleAlmEnabled'>; | |||
currentAlm: ALM_KEYS; | |||
definitionKeyForDeletion?: string; | |||
definitions: AlmSettingsBindingDefinitions; | |||
loading: boolean; | |||
onCancel: () => void; | |||
onConfirmDelete: (definitionKey: string) => void; | |||
onDelete: (definitionKey: string) => void; | |||
onSelectAlm: (alm: ALM_KEYS) => void; | |||
onUpdateDefinitions: () => void; | |||
projectCount?: number; | |||
} | |||
export const almName = { | |||
[ALM_KEYS.AZURE]: 'Azure DevOps Server', | |||
[ALM_KEYS.BITBUCKET]: 'Bitbucket Server', | |||
[ALM_KEYS.GITHUB]: 'GitHub', | |||
[ALM_KEYS.GITLAB]: 'GitLab' | |||
}; | |||
export function PRDecorationTabs(props: PRDecorationTabsProps) { | |||
const { | |||
appState: { multipleAlmEnabled }, | |||
definitionKeyForDeletion, | |||
definitions, | |||
currentAlm, | |||
loading, | |||
projectCount | |||
} = props; | |||
return ( | |||
<> | |||
<header className="page-header"> | |||
<h1 className="page-title">{translate('settings.pr_decoration.title')}</h1> | |||
</header> | |||
<div className="markdown small spacer-top big-spacer-bottom"> | |||
{translate('settings.pr_decoration.description')} | |||
</div> | |||
<BoxedTabs | |||
onSelect={props.onSelectAlm} | |||
selected={currentAlm} | |||
tabs={[ | |||
{ | |||
key: ALM_KEYS.GITHUB, | |||
label: ( | |||
<> | |||
<img | |||
alt="github" | |||
className="spacer-right" | |||
height={16} | |||
src={`${getBaseUrl()}/images/alm/github.svg`} | |||
/> | |||
{almName[ALM_KEYS.GITHUB]} | |||
</> | |||
) | |||
}, | |||
{ | |||
key: ALM_KEYS.BITBUCKET, | |||
label: ( | |||
<> | |||
<img | |||
alt="bitbucket" | |||
className="spacer-right" | |||
height={16} | |||
src={`${getBaseUrl()}/images/alm/bitbucket.svg`} | |||
/> | |||
{almName[ALM_KEYS.BITBUCKET]} | |||
</> | |||
) | |||
}, | |||
{ | |||
key: ALM_KEYS.AZURE, | |||
label: ( | |||
<> | |||
<img | |||
alt="azure" | |||
className="spacer-right" | |||
height={16} | |||
src={`${getBaseUrl()}/images/alm/azure.svg`} | |||
/> | |||
{almName[ALM_KEYS.AZURE]} | |||
</> | |||
) | |||
}, | |||
{ | |||
key: ALM_KEYS.GITLAB, | |||
label: ( | |||
<> | |||
<img | |||
alt="gitlab" | |||
className="spacer-right" | |||
height={16} | |||
src={`${getBaseUrl()}/images/alm/gitlab.svg`} | |||
/> | |||
{almName[ALM_KEYS.GITLAB]} | |||
</> | |||
) | |||
} | |||
]} | |||
/> | |||
<div className="boxed-group boxed-group-inner"> | |||
{currentAlm === ALM_KEYS.AZURE && ( | |||
<AzureTab | |||
definitions={definitions.azure} | |||
loading={loading} | |||
multipleAlmEnabled={Boolean(multipleAlmEnabled)} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
/> | |||
)} | |||
{currentAlm === ALM_KEYS.BITBUCKET && ( | |||
<BitbucketTab | |||
definitions={definitions.bitbucket} | |||
loading={loading} | |||
multipleAlmEnabled={Boolean(multipleAlmEnabled)} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
/> | |||
)} | |||
{currentAlm === ALM_KEYS.GITHUB && ( | |||
<GithubTab | |||
definitions={definitions.github} | |||
loading={loading} | |||
multipleAlmEnabled={Boolean(multipleAlmEnabled)} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
/> | |||
)} | |||
{currentAlm === ALM_KEYS.GITLAB && ( | |||
<GitlabTab | |||
definitions={definitions.gitlab} | |||
loading={loading} | |||
multipleAlmEnabled={Boolean(multipleAlmEnabled)} | |||
onDelete={props.onDelete} | |||
onUpdateDefinitions={props.onUpdateDefinitions} | |||
/> | |||
)} | |||
</div> | |||
{definitionKeyForDeletion && ( | |||
<DeleteModal | |||
id={definitionKeyForDeletion} | |||
onCancel={props.onCancel} | |||
onDelete={props.onConfirmDelete} | |||
projectCount={projectCount} | |||
/> | |||
)} | |||
</> | |||
); | |||
} | |||
export default withAppState(PRDecorationTabs); |
@@ -1,121 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<form | |||
className="views-form" | |||
data-test="settings__alm-form" | |||
onSubmit={[Function]} | |||
> | |||
<Component /> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.pr_decoration.form.save | |||
</SubmitButton> | |||
</div> | |||
</form> | |||
`; | |||
exports[`should render correctly 2`] = ` | |||
<form | |||
className="views-form" | |||
data-test="settings__alm-form" | |||
onSubmit={[Function]} | |||
> | |||
<Component /> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.pr_decoration.form.save | |||
</SubmitButton> | |||
<ResetButtonLink | |||
className="spacer-left" | |||
onClick={[MockFunction]} | |||
> | |||
cancel | |||
</ResetButtonLink> | |||
</div> | |||
</form> | |||
`; | |||
exports[`should render correctly 3`] = ` | |||
<form | |||
className="views-form" | |||
data-test="settings__alm-form" | |||
onSubmit={[Function]} | |||
> | |||
<Component /> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.pr_decoration.form.save | |||
</SubmitButton> | |||
<Button | |||
className="button-red spacer-left" | |||
disabled={false} | |||
onClick={[MockFunction]} | |||
> | |||
delete | |||
</Button> | |||
</div> | |||
</form> | |||
`; | |||
exports[`should render correctly 4`] = ` | |||
<form | |||
className="views-form" | |||
data-test="settings__alm-form" | |||
onSubmit={[Function]} | |||
> | |||
<Component /> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.pr_decoration.form.save | |||
</SubmitButton> | |||
<span | |||
className="text-success spacer-left" | |||
> | |||
<AlertSuccessIcon | |||
className="spacer-right" | |||
/> | |||
settings.state.saved | |||
</span> | |||
</div> | |||
</form> | |||
`; | |||
exports[`should render correctly 5`] = ` | |||
<form | |||
className="views-form" | |||
data-test="settings__alm-form" | |||
onSubmit={[Function]} | |||
> | |||
<Component /> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<SubmitButton | |||
disabled={true} | |||
> | |||
settings.pr_decoration.form.save | |||
</SubmitButton> | |||
<DeferredSpinner | |||
className="spacer-left" | |||
timeout={100} | |||
/> | |||
</div> | |||
</form> | |||
`; |
@@ -1,254 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly for multi-ALM binding: editing a definition 1`] = ` | |||
<DeferredSpinner | |||
loading={false} | |||
timeout={100} | |||
> | |||
<AlmPRDecorationTable | |||
additionalColumnsHeaders={ | |||
Array [ | |||
"url", | |||
"app_id", | |||
] | |||
} | |||
alm="github" | |||
definitions={ | |||
Array [ | |||
Object { | |||
"additionalColumns": Array [ | |||
"http://github.enterprise.com", | |||
"123456", | |||
], | |||
"key": "key", | |||
}, | |||
] | |||
} | |||
onCreate={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
/> | |||
<AlmPRDecorationForm | |||
alm="github" | |||
bindingDefinition={ | |||
Object { | |||
"appId": "123456", | |||
"key": "key", | |||
"privateKey": "asdf1234", | |||
"url": "http://github.enterprise.com", | |||
} | |||
} | |||
help={ | |||
<FormattedMessage | |||
defaultMessage="settings.pr_decoration.github.info" | |||
id="settings.pr_decoration.github.info" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/pr-decoration/" | |||
> | |||
learn_more | |||
</Link>, | |||
} | |||
} | |||
/> | |||
} | |||
onCancel={[MockFunction]} | |||
onSubmit={[MockFunction]} | |||
showInModal={true} | |||
> | |||
<Component /> | |||
</AlmPRDecorationForm> | |||
</DeferredSpinner> | |||
`; | |||
exports[`should render correctly for multi-ALM binding: loaded 1`] = ` | |||
<DeferredSpinner | |||
loading={false} | |||
timeout={100} | |||
> | |||
<AlmPRDecorationTable | |||
additionalColumnsHeaders={ | |||
Array [ | |||
"url", | |||
"app_id", | |||
] | |||
} | |||
alm="github" | |||
definitions={ | |||
Array [ | |||
Object { | |||
"additionalColumns": Array [ | |||
"http://github.enterprise.com", | |||
"123456", | |||
], | |||
"key": "key", | |||
}, | |||
] | |||
} | |||
onCreate={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
/> | |||
</DeferredSpinner> | |||
`; | |||
exports[`should render correctly for multi-ALM binding: loading 1`] = ` | |||
<DeferredSpinner | |||
loading={true} | |||
timeout={100} | |||
> | |||
<AlmPRDecorationTable | |||
additionalColumnsHeaders={ | |||
Array [ | |||
"url", | |||
"app_id", | |||
] | |||
} | |||
alm="github" | |||
definitions={ | |||
Array [ | |||
Object { | |||
"additionalColumns": Array [ | |||
"http://github.enterprise.com", | |||
"123456", | |||
], | |||
"key": "key", | |||
}, | |||
] | |||
} | |||
onCreate={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
/> | |||
</DeferredSpinner> | |||
`; | |||
exports[`should render correctly for single-ALM binding 1`] = ` | |||
<AlmPRDecorationForm | |||
alm="github" | |||
bindingDefinition={ | |||
Object { | |||
"appId": "123456", | |||
"key": "key", | |||
"privateKey": "asdf1234", | |||
"url": "http://github.enterprise.com", | |||
} | |||
} | |||
help={ | |||
<FormattedMessage | |||
defaultMessage="settings.pr_decoration.github.info" | |||
id="settings.pr_decoration.github.info" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/pr-decoration/" | |||
> | |||
learn_more | |||
</Link>, | |||
} | |||
} | |||
/> | |||
} | |||
hideKeyField={true} | |||
loading={true} | |||
onCancel={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
onSubmit={[MockFunction]} | |||
readOnly={true} | |||
success={false} | |||
> | |||
<Component /> | |||
</AlmPRDecorationForm> | |||
`; | |||
exports[`should render correctly for single-ALM binding 2`] = ` | |||
<AlmPRDecorationForm | |||
alm="github" | |||
bindingDefinition={ | |||
Object { | |||
"appId": "123456", | |||
"key": "key", | |||
"privateKey": "asdf1234", | |||
"url": "http://github.enterprise.com", | |||
} | |||
} | |||
help={ | |||
<FormattedMessage | |||
defaultMessage="settings.pr_decoration.github.info" | |||
id="settings.pr_decoration.github.info" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/pr-decoration/" | |||
> | |||
learn_more | |||
</Link>, | |||
} | |||
} | |||
/> | |||
} | |||
hideKeyField={true} | |||
loading={false} | |||
onCancel={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
onSubmit={[MockFunction]} | |||
readOnly={true} | |||
success={false} | |||
> | |||
<Component /> | |||
</AlmPRDecorationForm> | |||
`; | |||
exports[`should render correctly for single-ALM binding 3`] = ` | |||
<AlmPRDecorationForm | |||
alm="github" | |||
bindingDefinition={ | |||
Object { | |||
"appId": "123456", | |||
"key": "key", | |||
"privateKey": "asdf1234", | |||
"url": "http://github.enterprise.com", | |||
} | |||
} | |||
help={ | |||
<FormattedMessage | |||
defaultMessage="settings.pr_decoration.github.info" | |||
id="settings.pr_decoration.github.info" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/pr-decoration/" | |||
> | |||
learn_more | |||
</Link>, | |||
} | |||
} | |||
/> | |||
} | |||
hideKeyField={true} | |||
loading={false} | |||
onCancel={[MockFunction]} | |||
onDelete={[MockFunction]} | |||
onEdit={[MockFunction]} | |||
onSubmit={[MockFunction]} | |||
readOnly={true} | |||
success={false} | |||
> | |||
<Component /> | |||
</AlmPRDecorationForm> | |||
`; |
@@ -1,28 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<AlmTab | |||
alm="azure" | |||
createConfiguration={[Function]} | |||
defaultBinding={ | |||
Object { | |||
"key": "", | |||
"personalAccessToken": "", | |||
} | |||
} | |||
definitions={ | |||
Array [ | |||
Object { | |||
"key": "key", | |||
"personalAccessToken": "asdf1234", | |||
}, | |||
] | |||
} | |||
form={[Function]} | |||
loading={false} | |||
multipleAlmEnabled={true} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
updateConfiguration={[Function]} | |||
/> | |||
`; |
@@ -1,40 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<AlmTab | |||
additionalColumnsHeaders={ | |||
Array [ | |||
"settings.pr_decoration.table.column.bitbucket.url", | |||
] | |||
} | |||
additionalColumnsKeys={ | |||
Array [ | |||
"url", | |||
] | |||
} | |||
alm="bitbucket" | |||
createConfiguration={[Function]} | |||
defaultBinding={ | |||
Object { | |||
"key": "", | |||
"personalAccessToken": "", | |||
"url": "", | |||
} | |||
} | |||
definitions={ | |||
Array [ | |||
Object { | |||
"key": "key", | |||
"personalAccessToken": "asdf1234", | |||
"url": "http://bbs.enterprise.com", | |||
}, | |||
] | |||
} | |||
form={[Function]} | |||
loading={false} | |||
multipleAlmEnabled={true} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
updateConfiguration={[Function]} | |||
/> | |||
`; |
@@ -1,44 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<AlmTab | |||
additionalColumnsHeaders={ | |||
Array [ | |||
"settings.pr_decoration.table.column.github.url", | |||
"settings.pr_decoration.table.column.app_id", | |||
] | |||
} | |||
additionalColumnsKeys={ | |||
Array [ | |||
"appId", | |||
"url", | |||
] | |||
} | |||
alm="github" | |||
createConfiguration={[Function]} | |||
defaultBinding={ | |||
Object { | |||
"appId": "", | |||
"key": "", | |||
"privateKey": "", | |||
"url": "", | |||
} | |||
} | |||
definitions={ | |||
Array [ | |||
Object { | |||
"appId": "123456", | |||
"key": "key", | |||
"privateKey": "asdf1234", | |||
"url": "http://github.enterprise.com", | |||
}, | |||
] | |||
} | |||
form={[Function]} | |||
loading={false} | |||
multipleAlmEnabled={true} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
updateConfiguration={[Function]} | |||
/> | |||
`; |
@@ -1,28 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<AlmTab | |||
alm="gitlab" | |||
createConfiguration={[Function]} | |||
defaultBinding={ | |||
Object { | |||
"key": "", | |||
"personalAccessToken": "", | |||
} | |||
} | |||
definitions={ | |||
Array [ | |||
Object { | |||
"key": "foo", | |||
"personalAccessToken": "foobar", | |||
}, | |||
] | |||
} | |||
form={[Function]} | |||
loading={false} | |||
multipleAlmEnabled={true} | |||
onDelete={[MockFunction]} | |||
onUpdateDefinitions={[MockFunction]} | |||
updateConfiguration={[Function]} | |||
/> | |||
`; |
@@ -26,9 +26,9 @@ import { | |||
setProjectBitbucketBinding, | |||
setProjectGithubBinding, | |||
setProjectGitlabBinding | |||
} from '../../../../api/almSettings'; | |||
} from '../../../../api/alm-settings'; | |||
import throwGlobalError from '../../../../app/utils/throwGlobalError'; | |||
import { AlmSettingsInstance, ALM_KEYS, ProjectAlmBinding } from '../../../../types/alm-settings'; | |||
import { AlmKeys, AlmSettingsInstance, ProjectAlmBinding } from '../../../../types/alm-settings'; | |||
import PRDecorationBindingRenderer from './PRDecorationBindingRenderer'; | |||
interface Props { | |||
@@ -45,11 +45,11 @@ interface State { | |||
success: boolean; | |||
} | |||
const FIELDS_BY_ALM: { [almKey in ALM_KEYS]: Array<keyof T.Omit<ProjectAlmBinding, 'key'>> } = { | |||
[ALM_KEYS.AZURE]: [], | |||
[ALM_KEYS.BITBUCKET]: ['repository', 'slug'], | |||
[ALM_KEYS.GITHUB]: ['repository'], | |||
[ALM_KEYS.GITLAB]: [] | |||
const FIELDS_BY_ALM: { [almKey in AlmKeys]: Array<keyof T.Omit<ProjectAlmBinding, 'key'>> } = { | |||
[AlmKeys.Azure]: [], | |||
[AlmKeys.Bitbucket]: ['repository', 'slug'], | |||
[AlmKeys.GitHub]: ['repository'], | |||
[AlmKeys.GitLab]: [] | |||
}; | |||
export default class PRDecorationBinding extends React.PureComponent<Props, State> { | |||
@@ -133,7 +133,7 @@ export default class PRDecorationBinding extends React.PureComponent<Props, Stat | |||
}; | |||
submitProjectAlmBinding( | |||
alm: ALM_KEYS, | |||
alm: AlmKeys, | |||
key: string, | |||
almSpecificFields?: T.Omit<ProjectAlmBinding, 'key'> | |||
): Promise<void> { | |||
@@ -141,12 +141,12 @@ export default class PRDecorationBinding extends React.PureComponent<Props, Stat | |||
const project = this.props.component.key; | |||
switch (alm) { | |||
case ALM_KEYS.AZURE: | |||
case AlmKeys.Azure: | |||
return setProjectAzureBinding({ | |||
almSetting, | |||
project | |||
}); | |||
case ALM_KEYS.BITBUCKET: { | |||
case AlmKeys.Bitbucket: { | |||
if (!almSpecificFields) { | |||
return Promise.reject(); | |||
} | |||
@@ -158,7 +158,7 @@ export default class PRDecorationBinding extends React.PureComponent<Props, Stat | |||
slug | |||
}); | |||
} | |||
case ALM_KEYS.GITHUB: { | |||
case AlmKeys.GitHub: { | |||
const repository = almSpecificFields && almSpecificFields.repository; | |||
if (!repository) { | |||
return Promise.reject(); | |||
@@ -170,7 +170,7 @@ export default class PRDecorationBinding extends React.PureComponent<Props, Stat | |||
}); | |||
} | |||
case ALM_KEYS.GITLAB: | |||
case AlmKeys.GitLab: | |||
return setProjectGitlabBinding({ | |||
almSetting, | |||
project |
@@ -27,7 +27,7 @@ import AlertSuccessIcon from 'sonar-ui-common/components/icons/AlertSuccessIcon' | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { AlmSettingsInstance, ALM_KEYS, ProjectAlmBinding } from '../../../../types/alm-settings'; | |||
import { AlmKeys, AlmSettingsInstance, ProjectAlmBinding } from '../../../../types/alm-settings'; | |||
export interface PRDecorationBindingRendererProps { | |||
formData: ProjectAlmBinding; | |||
@@ -179,7 +179,7 @@ export default function PRDecorationBindingRenderer(props: PRDecorationBindingRe | |||
/> | |||
</div> | |||
{alm === ALM_KEYS.BITBUCKET && ( | |||
{alm === AlmKeys.Bitbucket && ( | |||
<> | |||
{renderField({ | |||
help: true, | |||
@@ -216,7 +216,7 @@ export default function PRDecorationBindingRenderer(props: PRDecorationBindingRe | |||
</> | |||
)} | |||
{alm === ALM_KEYS.GITHUB && | |||
{alm === AlmKeys.GitHub && | |||
renderField({ | |||
help: true, | |||
helpParams: { example: 'SonarSource/sonarqube' }, |
@@ -27,12 +27,12 @@ import { | |||
setProjectAzureBinding, | |||
setProjectBitbucketBinding, | |||
setProjectGithubBinding | |||
} from '../../../../../api/almSettings'; | |||
} from '../../../../../api/alm-settings'; | |||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||
import { ALM_KEYS } from '../../../../../types/alm-settings'; | |||
import { AlmKeys } from '../../../../../types/alm-settings'; | |||
import PRDecorationBinding from '../PRDecorationBinding'; | |||
jest.mock('../../../../../api/almSettings', () => ({ | |||
jest.mock('../../../../../api/alm-settings', () => ({ | |||
getAlmSettings: jest.fn().mockResolvedValue([]), | |||
getProjectAlmBinding: jest.fn().mockResolvedValue(undefined), | |||
setProjectAzureBinding: jest.fn().mockResolvedValue(undefined), | |||
@@ -53,7 +53,7 @@ it('should render correctly', () => { | |||
it('should fill selects and fill formdata', async () => { | |||
const url = 'github.com'; | |||
const instances = [{ key: 'instance1', url, alm: ALM_KEYS.GITHUB }]; | |||
const instances = [{ key: 'instance1', url, alm: AlmKeys.GitHub }]; | |||
const formdata = { | |||
key: 'instance1', | |||
repository: 'account/repo' | |||
@@ -89,9 +89,9 @@ it('should handle reset', async () => { | |||
describe('handleSubmit', () => { | |||
const instances = [ | |||
{ key: 'github', alm: ALM_KEYS.GITHUB }, | |||
{ key: 'azure', alm: ALM_KEYS.AZURE }, | |||
{ key: 'bitbucket', alm: ALM_KEYS.BITBUCKET } | |||
{ key: 'github', alm: AlmKeys.GitHub }, | |||
{ key: 'azure', alm: AlmKeys.Azure }, | |||
{ key: 'bitbucket', alm: AlmKeys.Bitbucket } | |||
]; | |||
it('should work for github', async () => { | |||
@@ -195,9 +195,9 @@ it('should validate form', async () => { | |||
wrapper.setState({ | |||
instances: [ | |||
{ key: 'azure', alm: ALM_KEYS.AZURE }, | |||
{ key: 'bitbucket', alm: ALM_KEYS.BITBUCKET }, | |||
{ key: 'github', alm: ALM_KEYS.GITHUB } | |||
{ key: 'azure', alm: AlmKeys.Azure }, | |||
{ key: 'bitbucket', alm: AlmKeys.Bitbucket }, | |||
{ key: 'github', alm: AlmKeys.GitHub } | |||
] | |||
}); | |||
expect(wrapper.instance().validateForm({ key: 'azure' })).toBe(true); |
@@ -21,7 +21,7 @@ import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import Select from 'sonar-ui-common/components/controls/Select'; | |||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { ALM_KEYS } from '../../../../../types/alm-settings'; | |||
import { AlmKeys } from '../../../../../types/alm-settings'; | |||
import PRDecorationBindingRenderer, { | |||
PRDecorationBindingRendererProps | |||
} from '../PRDecorationBindingRenderer'; | |||
@@ -35,7 +35,7 @@ it('should render single instance correctly', () => { | |||
const singleInstance = { | |||
key: 'single', | |||
url: 'http://single.url', | |||
alm: ALM_KEYS.GITHUB | |||
alm: AlmKeys.GitHub | |||
}; | |||
expect( | |||
shallowRender({ | |||
@@ -49,22 +49,22 @@ it('should render multiple instances correctly', () => { | |||
const urls = ['http://github.enterprise.com', 'http://bbs.enterprise.com']; | |||
const instances = [ | |||
{ | |||
alm: ALM_KEYS.GITHUB, | |||
alm: AlmKeys.GitHub, | |||
key: 'i1', | |||
url: urls[0] | |||
}, | |||
{ | |||
alm: ALM_KEYS.GITHUB, | |||
alm: AlmKeys.GitHub, | |||
key: 'i2', | |||
url: urls[0] | |||
}, | |||
{ | |||
alm: ALM_KEYS.BITBUCKET, | |||
alm: AlmKeys.Bitbucket, | |||
key: 'i3', | |||
url: urls[1] | |||
}, | |||
{ | |||
alm: ALM_KEYS.AZURE, | |||
alm: AlmKeys.Azure, | |||
key: 'i4' | |||
} | |||
]; | |||
@@ -96,7 +96,7 @@ it('should render multiple instances correctly', () => { | |||
it('should display action state correctly', () => { | |||
const urls = ['http://url.com']; | |||
const instances = [{ key: 'key', url: urls[0], alm: ALM_KEYS.GITHUB }]; | |||
const instances = [{ key: 'key', url: urls[0], alm: AlmKeys.GitHub }]; | |||
expect(shallowRender({ instances, loading: false, saving: true })).toMatchSnapshot(); | |||
expect(shallowRender({ instances, loading: false, success: true })).toMatchSnapshot(); | |||
@@ -112,11 +112,11 @@ it('should display action state correctly', () => { | |||
it('should render select options correctly', async () => { | |||
const instances = [ | |||
{ | |||
alm: ALM_KEYS.AZURE, | |||
alm: AlmKeys.Azure, | |||
key: 'azure' | |||
}, | |||
{ | |||
alm: ALM_KEYS.GITHUB, | |||
alm: AlmKeys.GitHub, | |||
key: 'github', | |||
url: 'gh.url.com' | |||
} |
@@ -18,8 +18,8 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { | |||
AlmKeys, | |||
AlmSettingsInstance, | |||
ALM_KEYS, | |||
AzureBindingDefinition, | |||
BitbucketBindingDefinition, | |||
GithubBindingDefinition, | |||
@@ -30,7 +30,7 @@ export function mockAlmSettingsInstance( | |||
overrides: Partial<AlmSettingsInstance> = {} | |||
): AlmSettingsInstance { | |||
return { | |||
alm: ALM_KEYS.GITHUB, | |||
alm: AlmKeys.GitHub, | |||
key: 'key', | |||
...overrides | |||
}; |
@@ -17,46 +17,33 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
export const enum ALM_KEYS { | |||
AZURE = 'azure', | |||
BITBUCKET = 'bitbucket', | |||
GITHUB = 'github', | |||
GITLAB = 'gitlab' | |||
export const enum AlmKeys { | |||
Azure = 'azure', | |||
Bitbucket = 'bitbucket', | |||
GitHub = 'github', | |||
GitLab = 'gitlab' | |||
} | |||
export interface AlmSettingsBinding { | |||
export interface AlmBindingDefinition { | |||
key: string; | |||
} | |||
export interface AlmSettingsInstance { | |||
alm: ALM_KEYS; | |||
key: string; | |||
url?: string; | |||
} | |||
export interface AlmSettingsBindingDefinitions { | |||
azure: AzureBindingDefinition[]; | |||
bitbucket: BitbucketBindingDefinition[]; | |||
github: GithubBindingDefinition[]; | |||
gitlab: GitlabBindingDefinition[]; | |||
} | |||
export interface AzureBindingDefinition extends AlmSettingsBinding { | |||
export interface AzureBindingDefinition extends AlmBindingDefinition { | |||
personalAccessToken: string; | |||
} | |||
export interface BitbucketBindingDefinition extends AlmSettingsBinding { | |||
export interface BitbucketBindingDefinition extends AlmBindingDefinition { | |||
personalAccessToken: string; | |||
url: string; | |||
} | |||
export interface GithubBindingDefinition extends AlmSettingsBinding { | |||
export interface GithubBindingDefinition extends AlmBindingDefinition { | |||
appId: string; | |||
privateKey: string; | |||
url: string; | |||
} | |||
export interface GitlabBindingDefinition extends AlmSettingsBinding { | |||
export interface GitlabBindingDefinition extends AlmBindingDefinition { | |||
personalAccessToken: string; | |||
} | |||
@@ -88,3 +75,16 @@ export interface GitlabProjectAlmBinding { | |||
almSetting: string; | |||
project: string; | |||
} | |||
export interface AlmSettingsInstance { | |||
alm: AlmKeys; | |||
key: string; | |||
url?: string; | |||
} | |||
export interface AlmSettingsBindingDefinitions { | |||
azure: AzureBindingDefinition[]; | |||
bitbucket: BitbucketBindingDefinition[]; | |||
github: GithubBindingDefinition[]; | |||
gitlab: GitlabBindingDefinition[]; | |||
} |
@@ -1016,55 +1016,64 @@ settings.new_code_period.description2=This setting is the default for all projec | |||
settings.languages.select_a_language_placeholder=Select a language | |||
settings.pr_decoration.category=Pull Request Decoration | |||
settings.pr_decoration.title=Pull Request Decoration | |||
settings.pr_decoration.description=Pull Request Decoration adds SonarQube analysis and a Quality Gate to your Pull Requests directly in your ALM provider's interface. | |||
settings.pr_decoration.manage_instances=Manage instances | |||
settings.pr_decoration.azure.info=Accounts that will be used to decorate Pull Requests need Code: Read & Write permission. {link} | |||
settings.pr_decoration.bitbucket.info=Accounts that will be used to decorate Pull Requests need write permission. {link} | |||
settings.pr_decoration.github.info=You need to install a GitHub App with specific settings and permissions to enable Pull Request Decoration on your Organization or Repository. {link} | |||
settings.pr_decoration.gitlab.info=Accounts that will be used to decorate Merge Requests need comment permissions on projects. The personal key needs the API scope permission. {link} | |||
settings.pr_decoration.table.title=Pull Request Decoration configurations | |||
settings.mr_decoration.table.title=Merge Request Decoration configurations | |||
settings.pr_decoration.table.empty.azure=Create your first Azure DevOps configuration to enable Pull Request Decoration on your projects. | |||
settings.pr_decoration.table.empty.bitbucket=Create your first Bitbucket configuration to enable Pull Request Decoration on your projects. | |||
settings.pr_decoration.table.empty.github=Create your first GitHub configuration to enable Pull Request Decoration on your organization or repository. | |||
settings.pr_decoration.table.empty.gitlab=Create your first GitLab configuration to enable Merge Request Decoration on your repository. | |||
settings.pr_decoration.table.create=Create configuration | |||
settings.pr_decoration.table.column.name=Name | |||
settings.pr_decoration.table.column.bitbucket.url=Bitbucket Server URL | |||
settings.pr_decoration.table.column.github.url=GitHub Enterprise or GitHub.com URL | |||
settings.pr_decoration.table.column.app_id=App ID | |||
settings.pr_decoration.table.column.edit=Edit | |||
settings.pr_decoration.table.column.delete=Delete | |||
settings.pr_decoration.delete.header=Delete configuration | |||
settings.pr_decoration.delete.message=Are you sure you want to delete the {id} configuration? | |||
settings.pr_decoration.delete.info={0} projects will no longer get Pull Request Decorations. | |||
settings.pr_decoration.delete.no_info=An unknown number of projects will no longer get Pull Request Decorations. | |||
settings.pr_decoration.form.header.create=Create a Pull Request Decoration configuration | |||
settings.mr_decoration.form.header.create=Create a Merge Request Decoration configuration | |||
settings.pr_decoration.form.header.edit=Edit the Pull Request Decoration configuration | |||
settings.mr_decoration.form.header.edit=Edit the Merge Request Decoration configuration | |||
settings.pr_decoration.form.name.azure=Configuration name | |||
settings.pr_decoration.form.name.azure.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured Azure instance for a project. | |||
settings.pr_decoration.form.name.bitbucket=Configuration name | |||
settings.pr_decoration.form.name.bitbucket.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured Bitbucket instance for a project. | |||
settings.pr_decoration.form.name.github=Configuration name | |||
settings.pr_decoration.form.name.github.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured GitHub App for a project. | |||
settings.pr_decoration.form.name.gitlab=Configuration name | |||
settings.pr_decoration.form.name.gitlab.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured GitLab instance for a project. | |||
settings.pr_decoration.form.url.bitbucket=Bitbucket Server URL | |||
settings.pr_decoration.form.url.bitbucket.help=Example: {example} | |||
settings.pr_decoration.form.url.github=GitHub URL | |||
settings.pr_decoration.form.url.github.help1=Example for Github Enterprise: | |||
settings.pr_decoration.form.url.github.help2=If using GitHub.com: | |||
settings.pr_decoration.form.app_id=GitHub App ID | |||
settings.pr_decoration.form.private_key=Private Key | |||
settings.pr_decoration.form.personal_access_token=Personal Access token | |||
settings.pr_decoration.form.personal_access_token.azure.help=Token of the user that will be used to decorate the Pull Requests. Needs authorized scope: "Code (read and write)". | |||
settings.pr_decoration.form.personal_access_token.gitlab.help=Token of the user that will be used to decorate the Merge Requests. Needs API scope authorization. | |||
settings.pr_decoration.form.save=Save configuration | |||
settings.pr_decoration.form.cancel=Cancel | |||
settings.almintegration.title=Integration configurations | |||
settings.almintegration.description=ALM integrations allow SonarQube to interact with your ALM. This enables things like authentication, or providing analysis details and a Quality Gate to your Pull Requests directly in your ALM provider's interface. | |||
settings.almintegration.manage_instances=Manage instances | |||
settings.almintegration.azure.info=Accounts that will be used to decorate Pull Requests need Code: Read & Write permission. {link} | |||
settings.almintegration.github.info=You need to install a GitHub App with specific settings and permissions to enable Pull Request Decoration on your Organization or Repository. {link} | |||
settings.almintegration.gitlab.info=Accounts that will be used to decorate Merge Requests need comment permissions on projects. The personal key needs the API scope permission. {link} | |||
settings.almintegration.bitbucket.help_1=SonarQube needs a Personal Access Token to communicate with Bitbucket Server. This token will be used to decorate Pull Requests. | |||
settings.almintegration.bitbucket.help_2=The account used for integration needs write permission. | |||
settings.almintegration.bitbucket.help_3=We recommend to integrate with SonarQube using a Bitbucket Server Service Account. | |||
settings.almintegration.table.title=ALM integration configurations | |||
settings.almintegration.table.empty.azure=Create your first Azure DevOps configuration to enable Pull Request Decoration on your projects. | |||
settings.almintegration.table.empty.bitbucket=Create your first Bitbucket configuration to enable Pull Request Decoration on your projects. | |||
settings.almintegration.table.empty.github=Create your first GitHub configuration to enable Pull Request Decoration on your organization or repository. | |||
settings.almintegration.table.empty.gitlab=Create your first GitLab configuration to enable Merge Request Decoration on your repository. | |||
settings.almintegration.table.create=Create configuration | |||
settings.almintegration.table.column.name=Name | |||
settings.almintegration.table.column.bitbucket.url=Bitbucket Server URL | |||
settings.almintegration.table.column.github.url=GitHub Enterprise or GitHub.com URL | |||
settings.almintegration.table.column.app_id=App ID | |||
settings.almintegration.table.column.edit=Edit | |||
settings.almintegration.table.column.delete=Delete | |||
settings.almintegration.delete.header=Delete configuration | |||
settings.almintegration.delete.message=Are you sure you want to delete the {id} configuration? | |||
settings.almintegration.delete.info={0} projects will no longer get Pull Request Decorations. | |||
settings.almintegration.delete.no_info=An unknown number of projects will no longer get Pull Request Decorations. | |||
settings.almintegration.form.header.create=Create a configuration | |||
settings.almintegration.form.header.edit=Edit the configuration | |||
settings.almintegration.form.name.azure=Configuration name | |||
settings.almintegration.form.name.azure.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured Azure instance for a project. | |||
settings.almintegration.form.name.bitbucket=Configuration name | |||
settings.almintegration.form.name.bitbucket.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured Bitbucket instance for a project. | |||
settings.almintegration.form.name.github=Configuration name | |||
settings.almintegration.form.name.github.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured GitHub App for a project. | |||
settings.almintegration.form.name.gitlab=Configuration name | |||
settings.almintegration.form.name.gitlab.help=Give your configuration a clear and succinct name. This name will be used at project level to identify the correct configured GitLab instance for a project. | |||
settings.almintegration.form.url.bitbucket=Bitbucket Server URL | |||
settings.almintegration.form.url.bitbucket.help=Example: {example} | |||
settings.almintegration.form.url.github=GitHub URL | |||
settings.almintegration.form.url.github.help1=Example for Github Enterprise: | |||
settings.almintegration.form.url.github.help2=If using GitHub.com: | |||
settings.almintegration.form.app_id=GitHub App ID | |||
settings.almintegration.form.private_key=Private Key | |||
settings.almintegration.form.personal_access_token=Personal Access token | |||
settings.almintegration.form.personal_access_token.azure.help=Token of the user that will be used to decorate the Pull Requests. Needs authorized scope: "Code (read and write)". | |||
settings.almintegration.form.personal_access_token.gitlab.help=Token of the user that will be used to decorate the Merge Requests. Needs API scope authorization. | |||
settings.almintegration.form.save=Save configuration | |||
settings.almintegration.form.cancel=Cancel | |||
settings.almintegration.features=ALM integration features | |||
settings.almintegration.feature.enabled=This feature is enabled | |||
settings.almintegration.feature.disabled=This feature is currently disabled | |||
settings.almintegration.feature.need_at_least_1_binding=You need to have at least 1 binding configured to use this feature | |||
settings.almintegration.feature.pr_decoration.title=Pull Request Decoration | |||
settings.almintegration.feature.pr_decoration.description=Add analysis and a Quality Gate to your Pull Requests directly in your ALM provider's interface. | |||
settings.almintegration.feature.mr_decoration.title=Merge Request Decoration | |||
settings.almintegration.feature.mr_decoration.description=Add analysis and a Quality Gate to your Merge Requests directly in your ALM provider's interface. | |||
settings.almintegration.feature.alm_repo_import.title=Import repositories from your ALM | |||
settings.almintegration.feature.alm_repo_import.description=Select repositories from your ALM, and import them into SonarQube. | |||
settings.almintegration.feature.alm_repo_import.disabled_if_multiple_bbs_instances=Connecting to multiple Bitbucket Server instances will deactivate the {feature} feature. Projects will have to be set up manually. | |||
settings.pr_decoration.binding.category=Pull Request Decoration | |||
settings.pr_decoration.binding.no_bindings=This feature must first be enabled in the global settings. {link} | |||
@@ -1088,13 +1097,14 @@ property.category.general.databaseCleaner=Database Cleaner | |||
property.category.general.looknfeel=Look & Feel | |||
property.category.general.issues=Issues | |||
property.category.general.subProjects=Sub-projects | |||
property.category.almintegration=ALM Integrations | |||
property.category.almintegration.github=GitHub Authentication | |||
property.category.almintegration.github.description=In order to enable authentication on GitHub.com or GitHub Enterprise:<ul><li>SonarQube must be publicly accessible through HTTPS only</li><li>The property 'sonar.core.serverBaseURL' must be set to this public HTTPS URL</li><li>In your GitHub profile, you need to create a Developer Application for which the 'Authorization callback URL' must be set to <code>'<value_of_sonar.core.serverBaseURL_property>/oauth2/callback'</code>.</li></ul> | |||
property.category.almintegration.gitlab=GitLab Authentication | |||
property.category.almintegration.gitlab.description=In order to enable GitLab authentication, the property 'sonar.core.serverBaseURL' must be set to the public URL | |||
property.category.organizations=Organizations | |||
property.category.security=Security | |||
property.category.security.encryption=Encryption | |||
property.category.security.github=GitHub | |||
property.category.security.github.description=In order to enable authentication on GitHub.com or GitHub Enterprise:<ul><li>SonarQube must be publicly accessible through HTTPS only</li><li>The property 'sonar.core.serverBaseURL' must be set to this public HTTPS URL</li><li>In your GitHub profile, you need to create a Developer Application for which the 'Authorization callback URL' must be set to <code>'<value_of_sonar.core.serverBaseURL_property>/oauth2/callback'</code>.</li></ul> | |||
property.category.security.gitlab=Gitlab | |||
property.category.security.gitlab.description=In order to enable Gitlab authentication, the property 'sonar.core.serverBaseURL' must be set to the public URL | |||
property.category.security.saml=SAML | |||
property.category.security.saml.description=In order to enable SAML authentication, the property 'sonar.core.serverBaseURL' must be set to the public URL | |||
property.category.java=Java |
@@ -56,6 +56,11 @@ public interface CoreProperties { | |||
*/ | |||
String SUBCATEGORY_DUPLICATIONS = "duplications"; | |||
/** | |||
* @since 8.2 | |||
*/ | |||
String CATEGORY_ALM_INTEGRATION = "almintegration"; | |||
/** | |||
* @since 8.1 | |||
*/ |