return post('/api/alm_settings/update_github', data).catch(throwGlobalError);
}
+export function createAzureConfiguration(data: T.AzureBindingDefinition) {
+ return post('/api/alm_settings/create_azure', data).catch(throwGlobalError);
+}
+
+export function updateAzureConfiguration(data: T.AzureBindingDefinition & { newKey: string }) {
+ return post('/api/alm_settings/update_azure', data).catch(throwGlobalError);
+}
+
export function deleteConfiguration(key: string) {
return post('/api/alm_settings/delete', { key }).catch(throwGlobalError);
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+
+export interface AlmDefinitionFormFieldProps<B extends T.AlmSettingsBinding> {
+ autoFocus?: boolean;
+ formData: B;
+ help: boolean;
+ id: string;
+ isTextArea: boolean;
+ maxLength: number;
+ onFieldChange: (id: keyof B, value: string) => void;
+ propKey: keyof B;
+}
+
+export function AlmDefinitionFormField<B extends T.AlmSettingsBinding>(
+ props: AlmDefinitionFormFieldProps<B>
+) {
+ const { autoFocus, formData, help, id, isTextArea, maxLength, onFieldChange, propKey } = props;
+
+ return (
+ <div className="modal-field">
+ <label className="display-flex-center" htmlFor={id}>
+ {translate('settings.pr_decoration.form', id)}
+ <em className="mandatory spacer-right">*</em>
+ {help && <HelpTooltip overlay={translate('settings.pr_decoration.form', id, 'help')} />}
+ </label>
+ {isTextArea ? (
+ <textarea
+ className="settings-large-input"
+ id="privateKey"
+ maxLength={maxLength}
+ onChange={e => onFieldChange(propKey, e.currentTarget.value)}
+ required={true}
+ rows={5}
+ value={String(formData[propKey])}
+ />
+ ) : (
+ <input
+ autoFocus={autoFocus}
+ className="input-super-large"
+ id={id}
+ maxLength={maxLength}
+ name={id}
+ onChange={e => onFieldChange(propKey, e.currentTarget.value)}
+ size={50}
+ type="text"
+ value={String(formData[propKey])}
+ />
+ )}
+ </div>
+ );
+}
import * as React from 'react';
import AlmPRDecorationFormModalRenderer from './AlmPRDecorationFormModalRenderer';
-interface Props {
- alm: string;
- bindingDefinition: T.GithubBindingDefinition;
+interface ChildrenProps<AlmBindingDefinitionType> {
+ formData: AlmBindingDefinitionType;
+ onFieldChange: (fieldId: keyof AlmBindingDefinitionType, value: string) => void;
+}
+
+interface Props<B> {
+ children: (props: ChildrenProps<B>) => React.ReactNode;
+ bindingDefinition: B;
onCancel: () => void;
- onSubmit: (bindingDefinition: T.GithubBindingDefinition, originalKey: string) => void;
+ onSubmit: (data: B, originalKey: string) => void;
}
-interface State {
- formData: T.GithubBindingDefinition;
+interface State<AlmBindingDefinitionType> {
+ formData: AlmBindingDefinitionType;
}
-export default class AlmPRDecorationFormModal extends React.PureComponent<Props, State> {
- constructor(props: Props) {
+export default class AlmPRDecorationFormModal<
+ B extends T.AlmSettingsBinding
+> extends React.PureComponent<Props<B>, State<B>> {
+ constructor(props: Props<B>) {
super(props);
this.state = { formData: props.bindingDefinition };
}
- handleFieldChange = (fieldId: keyof T.GithubBindingDefinition, value: string) => {
+ handleFieldChange = (fieldId: keyof B, value: string) => {
this.setState(({ formData }) => ({
formData: {
...formData,
};
render() {
- const { alm, bindingDefinition } = this.props;
+ const { children, bindingDefinition } = this.props;
const { formData } = this.state;
return (
<AlmPRDecorationFormModalRenderer
- alm={alm}
canSubmit={this.canSubmit}
- formData={formData}
onCancel={this.props.onCancel}
- onFieldChange={this.handleFieldChange}
onSubmit={this.handleFormSubmit}
- originalKey={bindingDefinition.key}
- />
+ originalKey={bindingDefinition.key}>
+ {children({
+ formData,
+ onFieldChange: this.handleFieldChange
+ })}
+ </AlmPRDecorationFormModalRenderer>
);
}
}
*/
import * as React from 'react';
import { ResetButtonLink, SubmitButton } from 'sonar-ui-common/components/controls/buttons';
-import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
import SimpleModal from 'sonar-ui-common/components/controls/SimpleModal';
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { ALM_KEYS } from '../../utils';
export interface AlmPRDecorationFormModalProps {
- alm: string;
canSubmit: () => boolean;
- formData: T.GithubBindingDefinition;
+ children: React.ReactNode;
onCancel: () => void;
onSubmit: () => void;
- onFieldChange: (id: string, value: string) => void;
originalKey: string;
}
-function renderField(params: {
- autoFocus?: boolean;
- formData: T.GithubBindingDefinition;
- help: boolean;
- id: string;
- isTextArea: boolean;
- maxLength: number;
- onFieldChange: (id: string, value: string) => void;
- propKey: keyof T.GithubBindingDefinition;
-}) {
- const { autoFocus, formData, help, id, isTextArea, maxLength, onFieldChange, propKey } = params;
- return (
- <div className="modal-field">
- <label className="display-flex-center" htmlFor={id}>
- {translate('settings.pr_decoration.form', id)}
- <em className="mandatory spacer-right">*</em>
- {help && <HelpTooltip overlay={translate('settings.pr_decoration.form', id, 'help')} />}
- </label>
- {isTextArea ? (
- <textarea
- className="settings-large-input"
- id="privateKey"
- maxLength={maxLength}
- onChange={e => onFieldChange(propKey, e.currentTarget.value)}
- required={true}
- rows={5}
- value={formData[propKey]}
- />
- ) : (
- <input
- autoFocus={autoFocus}
- className="input-super-large"
- id={id}
- maxLength={maxLength}
- name={id}
- onChange={e => onFieldChange(propKey, e.currentTarget.value)}
- size={50}
- type="text"
- value={formData[propKey]}
- />
- )}
- </div>
- );
-}
-
export default function AlmPRDecorationFormModalRenderer(props: AlmPRDecorationFormModalProps) {
- const { alm, formData, onFieldChange, originalKey } = props;
+ const { children, originalKey } = props;
const header = translate('settings.pr_decoration.form.header', originalKey ? 'edit' : 'create');
return (
<h2>{header}</h2>
</div>
- <div className="modal-body modal-container">
- {renderField({
- autoFocus: true,
- id: 'name',
- formData,
- propKey: 'key',
- maxLength: 40,
- onFieldChange,
- help: true,
- isTextArea: false
- })}
- {renderField({
- id: `url.${alm}`,
- formData,
- propKey: 'url',
- maxLength: 2000,
- onFieldChange,
- help: false,
- isTextArea: false
- })}
- {alm === ALM_KEYS.GITHUB &&
- renderField({
- id: 'app_id',
- formData,
- propKey: 'appId',
- maxLength: 80,
- onFieldChange,
- help: false,
- isTextArea: false
- })}
- {renderField({
- id: 'private_key',
- formData,
- propKey: 'privateKey',
- maxLength: 2000,
- onFieldChange,
- help: false,
- isTextArea: true
- })}
- </div>
+ <div className="modal-body modal-container">{children}</div>
<div className="modal-foot">
<DeferredSpinner className="spacer-right" loading={submitting} />
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { AlmDefinitionFormField } from './AlmDefinitionFormField';
+
+export interface AzureFormModalProps {
+ formData: T.AzureBindingDefinition;
+ onFieldChange: (fieldId: keyof T.AzureBindingDefinition, value: string) => void;
+}
+
+export default function AzureFormModal(props: AzureFormModalProps) {
+ const { formData, onFieldChange } = props;
+
+ return (
+ <>
+ <AlmDefinitionFormField
+ autoFocus={true}
+ formData={formData}
+ help={true}
+ id="name"
+ isTextArea={false}
+ maxLength={40}
+ onFieldChange={onFieldChange}
+ propKey="key"
+ />
+ <AlmDefinitionFormField
+ formData={formData}
+ help={true}
+ id="personal_access_token"
+ isTextArea={true}
+ maxLength={2000}
+ onFieldChange={onFieldChange}
+ propKey="personalAccessToken"
+ />
+ </>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { createAzureConfiguration, updateAzureConfiguration } from '../../../../api/almSettings';
+import AzureTabRenderer from './AzureTabRenderer';
+
+interface Props {
+ definitions: T.AzureBindingDefinition[];
+ loading: boolean;
+ onDelete: (definitionKey: string) => void;
+ onUpdateDefinitions: () => void;
+}
+
+interface State {
+ editedDefinition?: T.AzureBindingDefinition;
+ projectCount?: number;
+}
+
+export default class AzureTab extends React.PureComponent<Props, State> {
+ mounted = false;
+ state: State = {};
+
+ componentDidMount() {
+ this.mounted = true;
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ handleCancel = () => {
+ this.setState({
+ editedDefinition: undefined
+ });
+ };
+
+ handleCreate = () => {
+ this.setState({ editedDefinition: { key: '', personalAccessToken: '' } });
+ };
+
+ handleEdit = (config: T.AzureBindingDefinition) => {
+ this.setState({ editedDefinition: config });
+ };
+
+ handleSubmit = (config: T.AzureBindingDefinition, originalKey: string) => {
+ const call = originalKey
+ ? updateAzureConfiguration({ newKey: config.key, ...config, key: originalKey })
+ : createAzureConfiguration(config);
+ return call.then(this.props.onUpdateDefinitions).then(() => {
+ if (this.mounted) {
+ this.setState({ editedDefinition: undefined });
+ }
+ });
+ };
+
+ render() {
+ const { definitions, loading } = this.props;
+ const { editedDefinition } = this.state;
+ return (
+ <AzureTabRenderer
+ definitions={definitions}
+ editedDefinition={editedDefinition}
+ loading={loading}
+ onCancel={this.handleCancel}
+ onCreate={this.handleCreate}
+ onDelete={this.props.onDelete}
+ onEdit={this.handleEdit}
+ onSubmit={this.handleSubmit}
+ />
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { ALM_KEYS } from '../../utils';
+import AlmPRDecorationFormModal from './AlmPRDecorationFormModal';
+import AzureFormModal from './AzureFormModal';
+import AzureTable from './AzureTable';
+import TabHeader from './TabHeader';
+
+export interface AzureTabRendererProps {
+ editedDefinition?: T.AzureBindingDefinition;
+ definitions: T.AzureBindingDefinition[];
+ loading: boolean;
+ onCancel: () => void;
+ onCreate: () => void;
+ onDelete: (definitionKey: string) => void;
+ onEdit: (config: T.AzureBindingDefinition) => void;
+ onSubmit: (config: T.AzureBindingDefinition, originalKey: string) => void;
+}
+
+export default function AzureTabRenderer(props: AzureTabRendererProps) {
+ const { definitions, editedDefinition, loading } = props;
+ return (
+ <>
+ <TabHeader alm={ALM_KEYS.AZURE} onCreate={props.onCreate} />
+
+ <AzureTable
+ definitions={definitions}
+ loading={loading}
+ onDelete={props.onDelete}
+ onEdit={props.onEdit}
+ />
+
+ {editedDefinition && (
+ <AlmPRDecorationFormModal
+ bindingDefinition={editedDefinition}
+ onCancel={props.onCancel}
+ onSubmit={props.onSubmit}>
+ {childProps => <AzureFormModal {...childProps} />}
+ </AlmPRDecorationFormModal>
+ )}
+ </>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { ButtonIcon, DeleteButton } from 'sonar-ui-common/components/controls/buttons';
+import EditIcon from 'sonar-ui-common/components/icons/EditIcon';
+import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+
+export interface AzureTableProps {
+ definitions: T.AzureBindingDefinition[];
+ loading: boolean;
+ onDelete: (definitionKey: string) => void;
+ onEdit: (config: T.AzureBindingDefinition) => void;
+}
+
+export default function AzureTable(props: AzureTableProps) {
+ const { definitions, loading } = props;
+
+ if (loading) {
+ return <DeferredSpinner />;
+ }
+
+ return (
+ <table className="data zebra spacer-bottom">
+ <thead>
+ <tr>
+ <th>{translate('settings.pr_decoration.table.column.name')}</th>
+ <th className="thin">{translate('settings.pr_decoration.table.column.edit')}</th>
+ <th className="thin">{translate('settings.pr_decoration.table.column.delete')}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {definitions.length < 1 ? (
+ <tr>
+ <td colSpan={3}>{translate('settings.pr_decoration.table.empty.azure')}</td>
+ </tr>
+ ) : (
+ definitions.map(definition => (
+ <tr key={definition.key}>
+ <td>{definition.key}</td>
+ <td>
+ <ButtonIcon onClick={() => props.onEdit(definition)}>
+ <EditIcon />
+ </ButtonIcon>
+ </td>
+ <td>
+ <DeleteButton onClick={() => props.onDelete(definition.key)} />
+ </td>
+ </tr>
+ ))
+ )}
+ </tbody>
+ </table>
+ );
+}
confirmButtonText={translate('delete')}
confirmData={id}
header={translate('settings.pr_decoration.delete.header')}
+ isDestructive={true}
onClose={onCancel}
onConfirm={onDelete}>
<>
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { AlmDefinitionFormField } from './AlmDefinitionFormField';
+
+export interface GithubFormModalProps {
+ formData: T.GithubBindingDefinition;
+ onFieldChange: (fieldId: keyof T.GithubBindingDefinition, value: string) => void;
+}
+
+export default function GithubFormModal(props: GithubFormModalProps) {
+ const { formData, onFieldChange } = props;
+
+ return (
+ <>
+ <AlmDefinitionFormField
+ autoFocus={true}
+ formData={formData}
+ help={true}
+ id="name"
+ isTextArea={false}
+ maxLength={40}
+ onFieldChange={onFieldChange}
+ propKey="key"
+ />
+ <AlmDefinitionFormField
+ formData={formData}
+ help={false}
+ id="url.github"
+ isTextArea={false}
+ maxLength={2000}
+ onFieldChange={onFieldChange}
+ propKey="url"
+ />
+ <AlmDefinitionFormField
+ formData={formData}
+ help={false}
+ id="app_id"
+ isTextArea={false}
+ maxLength={80}
+ onFieldChange={onFieldChange}
+ propKey="appId"
+ />
+ <AlmDefinitionFormField
+ formData={formData}
+ help={false}
+ id="private_key"
+ isTextArea={true}
+ maxLength={2000}
+ onFieldChange={onFieldChange}
+ propKey="privateKey"
+ />
+ </>
+ );
+}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import {
- countBindedProjects,
- createGithubConfiguration,
- deleteConfiguration,
- updateGithubConfiguration
-} from '../../../../api/almSettings';
-import { ALM_KEYS } from '../../utils';
-import TabRenderer from './TabRenderer';
+import { createGithubConfiguration, updateGithubConfiguration } from '../../../../api/almSettings';
+import GithubTabRenderer from './GithubTabRenderer';
interface Props {
definitions: T.GithubBindingDefinition[];
+ loading: boolean;
+ onDelete: (definitionKey: string) => void;
onUpdateDefinitions: () => void;
}
interface State {
- definitionInEdition?: T.GithubBindingDefinition;
- definitionKeyForDeletion?: string;
+ editedDefinition?: T.GithubBindingDefinition;
projectCount?: number;
}
handleCancel = () => {
this.setState({
- definitionKeyForDeletion: undefined,
- definitionInEdition: undefined,
- projectCount: undefined
+ editedDefinition: undefined
});
};
- deleteConfiguration = (id: string) => {
- return deleteConfiguration(id)
- .then(this.props.onUpdateDefinitions)
- .then(() => {
- if (this.mounted) {
- this.setState({ definitionKeyForDeletion: undefined });
- }
- });
- };
-
handleCreate = () => {
- this.setState({ definitionInEdition: { key: '', appId: '', url: '', privateKey: '' } });
- };
-
- handleDelete = (config: T.GithubBindingDefinition) => {
- this.setState({ definitionKeyForDeletion: config.key });
-
- return countBindedProjects(config.key).then(projectCount => {
- if (this.mounted) {
- this.setState({ projectCount });
- }
- });
+ this.setState({ editedDefinition: { key: '', appId: '', url: '', privateKey: '' } });
};
handleEdit = (config: T.GithubBindingDefinition) => {
- this.setState({ definitionInEdition: config });
+ this.setState({ editedDefinition: config });
};
handleSubmit = (config: T.GithubBindingDefinition, originalKey: string) => {
const call = originalKey
? updateGithubConfiguration({ newKey: config.key, ...config, key: originalKey })
: createGithubConfiguration(config);
- return call.then(this.props.onUpdateDefinitions).then(() => {
- if (this.mounted) {
- this.setState({ definitionInEdition: undefined });
- }
- });
+ return call
+ .then(() => {
+ if (this.mounted) {
+ this.setState({ editedDefinition: undefined });
+ }
+ })
+ .then(this.props.onUpdateDefinitions);
};
render() {
- const { definitions } = this.props;
- const { definitionKeyForDeletion, definitionInEdition, projectCount } = this.state;
+ const { definitions, loading } = this.props;
+ const { editedDefinition } = this.state;
return (
- <TabRenderer
- alm={ALM_KEYS.GITHUB}
- definitionInEdition={definitionInEdition}
- definitionKeyForDeletion={definitionKeyForDeletion}
+ <GithubTabRenderer
definitions={definitions}
+ editedDefinition={editedDefinition}
+ loading={loading}
onCancel={this.handleCancel}
- onConfirmDelete={this.deleteConfiguration}
onCreate={this.handleCreate}
- onDelete={this.handleDelete}
+ onDelete={this.props.onDelete}
onEdit={this.handleEdit}
onSubmit={this.handleSubmit}
- projectCount={projectCount}
/>
);
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { ALM_KEYS } from '../../utils';
+import AlmPRDecorationFormModal from './AlmPRDecorationFormModal';
+import GithubFormModal from './GithubFormModal';
+import GithubTable from './GithubTable';
+import TabHeader from './TabHeader';
+
+export interface GithubTabRendererProps {
+ editedDefinition?: T.GithubBindingDefinition;
+ definitions: T.GithubBindingDefinition[];
+ loading: boolean;
+ onCancel: () => void;
+ onCreate: () => void;
+ onDelete: (definitionKey: string) => void;
+ onEdit: (config: T.GithubBindingDefinition) => void;
+ onSubmit: (config: T.GithubBindingDefinition, originalKey: string) => void;
+}
+
+export default function GithubTabRenderer(props: GithubTabRendererProps) {
+ const { definitions, editedDefinition, loading } = props;
+ return (
+ <>
+ <TabHeader alm={ALM_KEYS.GITHUB} onCreate={props.onCreate} />
+
+ <GithubTable
+ definitions={definitions}
+ loading={loading}
+ onDelete={props.onDelete}
+ onEdit={props.onEdit}
+ />
+
+ {editedDefinition && (
+ <AlmPRDecorationFormModal
+ bindingDefinition={editedDefinition}
+ onCancel={props.onCancel}
+ onSubmit={props.onSubmit}>
+ {childProps => <GithubFormModal {...childProps} />}
+ </AlmPRDecorationFormModal>
+ )}
+ </>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { ButtonIcon, DeleteButton } from 'sonar-ui-common/components/controls/buttons';
+import EditIcon from 'sonar-ui-common/components/icons/EditIcon';
+import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+
+export interface GithubTableProps {
+ definitions: T.GithubBindingDefinition[];
+ loading: boolean;
+ onDelete: (definitionKey: string) => void;
+ onEdit: (config: T.GithubBindingDefinition) => void;
+}
+
+export default function GithubTable(props: GithubTableProps) {
+ const { definitions, loading } = props;
+
+ if (loading) {
+ return <DeferredSpinner />;
+ }
+
+ return (
+ <table className="data zebra spacer-bottom">
+ <thead>
+ <tr>
+ <th>{translate('settings.pr_decoration.table.column.name')}</th>
+ <th>{translate(`settings.pr_decoration.table.column.github.url`)}</th>
+ <th>{translate('settings.pr_decoration.table.column.app_id')}</th>
+ <th className="thin">{translate('settings.pr_decoration.table.column.edit')}</th>
+ <th className="thin">{translate('settings.pr_decoration.table.column.delete')}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {definitions.map(definition => (
+ <tr key={definition.key}>
+ <td>{definition.key}</td>
+ <td>{definition.url}</td>
+ <td>{definition.appId}</td>
+ <td>
+ <ButtonIcon onClick={() => props.onEdit(definition)}>
+ <EditIcon />
+ </ButtonIcon>
+ </td>
+ <td>
+ <DeleteButton onClick={() => props.onDelete(definition.key)} />
+ </td>
+ </tr>
+ ))}
+ </tbody>
+ </table>
+ );
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import { ButtonIcon } from 'sonar-ui-common/components/controls/buttons';
-import DeleteIcon from 'sonar-ui-common/components/icons/DeleteIcon';
-import EditIcon from 'sonar-ui-common/components/icons/EditIcon';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import { ALM_KEYS } from '../../utils';
-
-export interface PRDecorationTableProps {
- alm: ALM_KEYS;
- definitions: T.GithubBindingDefinition[];
- onDelete: (config: T.GithubBindingDefinition) => void;
- onEdit: (config: T.GithubBindingDefinition) => void;
-}
-
-export default function PRDecorationTable(props: PRDecorationTableProps) {
- const { alm, definitions } = props;
-
- return (
- <>
- <table className="data zebra spacer-bottom">
- <thead>
- <tr>
- <th>{translate('settings.pr_decoration.table.column.name')}</th>
- <th>{translate(`settings.pr_decoration.table.column.${alm}.url`)}</th>
- <th>{translate('settings.pr_decoration.table.column.app_id')}</th>
- <th className="thin">{translate('settings.pr_decoration.table.column.edit')}</th>
- <th className="thin">{translate('settings.pr_decoration.table.column.delete')}</th>
- </tr>
- </thead>
- <tbody>
- {definitions.map(definition => (
- <tr key={definition.key}>
- <td>{definition.key}</td>
- <td>{definition.url}</td>
- <td>{definition.appId}</td>
- <td>
- <ButtonIcon onClick={() => props.onEdit(definition)}>
- <EditIcon />
- </ButtonIcon>
- </td>
- <td>
- <ButtonIcon onClick={() => props.onDelete(definition)}>
- <DeleteIcon />
- </ButtonIcon>
- </td>
- </tr>
- ))}
- </tbody>
- </table>
- </>
- );
-}
*/
import * as React from 'react';
import BoxedTabs from 'sonar-ui-common/components/controls/BoxedTabs';
-import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { almName, ALM_KEYS } from '../../utils';
+import AzureTab from './AzureTab';
+import DeleteModal from './DeleteModal';
import GithubTab from './GithubTab';
export interface PRDecorationTabsProps {
currentAlm: ALM_KEYS;
+ definitionKeyForDeletion?: string;
definitions: T.AlmSettingsBindingDefinitions;
loading: boolean;
+ onCancel: () => void;
+ onConfirmDelete: (definitionKey: string) => void;
+ onDelete: (definitionKey: string) => void;
onSelectAlm: (alm: ALM_KEYS) => void;
onUpdateDefinitions: () => void;
+ projectCount?: number;
}
export default function PRDecorationTabs(props: PRDecorationTabsProps) {
- const { definitions, currentAlm, loading } = props;
-
- if (loading) {
- return <DeferredSpinner />;
- }
+ const { definitionKeyForDeletion, definitions, currentAlm, loading, projectCount } = props;
return (
<>
{
key: ALM_KEYS.GITHUB,
label: almName[ALM_KEYS.GITHUB]
+ },
+ {
+ key: ALM_KEYS.AZURE,
+ label: almName[ALM_KEYS.AZURE]
}
]}
/>
<div className="boxed-group boxed-group-inner">
- <GithubTab
- definitions={definitions.github}
- onUpdateDefinitions={props.onUpdateDefinitions}
- />
+ {currentAlm === ALM_KEYS.AZURE && (
+ <AzureTab
+ definitions={definitions.azure}
+ loading={loading}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ />
+ )}
+ {currentAlm === ALM_KEYS.GITHUB && (
+ <GithubTab
+ definitions={definitions.github}
+ loading={loading}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ />
+ )}
</div>
+
+ {definitionKeyForDeletion && (
+ <DeleteModal
+ id={definitionKeyForDeletion}
+ onCancel={props.onCancel}
+ onDelete={props.onConfirmDelete}
+ projectCount={projectCount}
+ />
+ )}
</>
);
}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { getAlmDefinitions } from '../../../../api/almSettings';
+import {
+ countBindedProjects,
+ deleteConfiguration,
+ getAlmDefinitions
+} from '../../../../api/almSettings';
import { ALM_KEYS } from '../../utils';
import PRDecorationTabs from './PRDecorationTabs';
interface State {
currentAlm: ALM_KEYS;
+ definitionKeyForDeletion?: string;
definitions: T.AlmSettingsBindingDefinitions;
loading: boolean;
+ projectCount?: number;
}
export default class PullRequestDecoration extends React.PureComponent<{}, State> {
state: State = {
currentAlm: ALM_KEYS.GITHUB,
definitions: {
+ [ALM_KEYS.AZURE]: [],
[ALM_KEYS.GITHUB]: []
},
loading: true
this.mounted = false;
}
+ deleteConfiguration = (definitionKey: string) => {
+ return deleteConfiguration(definitionKey)
+ .then(() => {
+ if (this.mounted) {
+ this.setState({ definitionKeyForDeletion: undefined, projectCount: undefined });
+ }
+ })
+ .then(this.fetchPullRequestDecorationSetting);
+ };
+
fetchPullRequestDecorationSetting = () => {
+ this.setState({ loading: true });
return getAlmDefinitions()
.then(definitions => {
if (this.mounted) {
this.setState({ currentAlm });
};
+ handleCancel = () => {
+ this.setState({ definitionKeyForDeletion: undefined, projectCount: undefined });
+ };
+
+ handleDelete = (definitionKey: string) => {
+ return countBindedProjects(definitionKey).then(projectCount => {
+ if (this.mounted) {
+ this.setState({
+ definitionKeyForDeletion: definitionKey,
+ projectCount
+ });
+ }
+ });
+ };
+
render() {
return (
<PRDecorationTabs
+ onCancel={this.handleCancel}
+ onConfirmDelete={this.deleteConfiguration}
+ onDelete={this.handleDelete}
onSelectAlm={this.handleSelectAlm}
onUpdateDefinitions={this.fetchPullRequestDecorationSetting}
{...this.state}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { Link } from 'react-router';
+import { Button } from 'sonar-ui-common/components/controls/buttons';
+import { Alert } from 'sonar-ui-common/components/ui/Alert';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { ALM_KEYS } from '../../utils';
+
+export interface TabHeaderProps {
+ alm: ALM_KEYS;
+ onCreate: () => void;
+}
+
+export default function TabHeader(props: TabHeaderProps) {
+ const { alm } = props;
+ return (
+ <>
+ <Alert className="spacer-top huge-spacer-bottom" variant="info">
+ <FormattedMessage
+ defaultMessage={translate(`settings.pr_decoration.${alm}.info`)}
+ id={`settings.pr_decoration.${alm}.info`}
+ values={{
+ link: (
+ <Link to="/documentation/analysis/pull-request/#pr-decoration">
+ {translate('learn_more')}
+ </Link>
+ )
+ }}
+ />
+ </Alert>
+
+ <div className="big-spacer-bottom display-flex-space-between">
+ <h4 className="display-inline">{translate('settings.pr_decoration.table.title')}</h4>
+ <Button onClick={props.onCreate}>{translate('settings.pr_decoration.table.create')}</Button>
+ </div>
+ </>
+ );
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import { FormattedMessage } from 'react-intl';
-import { Link } from 'react-router';
-import { Button } from 'sonar-ui-common/components/controls/buttons';
-import { Alert } from 'sonar-ui-common/components/ui/Alert';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import { ALM_KEYS } from '../../utils';
-import AlmPRDecorationFormModal from './AlmPRDecorationFormModal';
-import DeleteModal from './DeleteModal';
-import PRDecorationTable from './PRDecorationTable';
-
-export interface TabRendererProps {
- alm: ALM_KEYS;
- definitionInEdition?: T.GithubBindingDefinition;
- definitionKeyForDeletion?: string;
- definitions: T.GithubBindingDefinition[];
- onCancel: () => void;
- onConfirmDelete: (id: string) => void;
- onCreate: () => void;
- onDelete: (config: T.GithubBindingDefinition) => void;
- onEdit: (config: T.GithubBindingDefinition) => void;
- onSubmit: (config: T.GithubBindingDefinition, originalKey: string) => void;
- projectCount?: number;
-}
-
-export default function TabRenderer(props: TabRendererProps) {
- const { alm, definitions, definitionKeyForDeletion, definitionInEdition, projectCount } = props;
- return (
- <>
- <Alert className="spacer-top huge-spacer-bottom" variant="info">
- <FormattedMessage
- defaultMessage={translate(`settings.pr_decoration.${alm}.info`)}
- id={`settings.pr_decoration.${alm}.info`}
- values={{
- link: (
- <Link to="/documentation/analysis/pull-request/#pr-decoration">
- {translate('learn_more')}
- </Link>
- )
- }}
- />
- </Alert>
-
- <div className="big-spacer-bottom display-flex-space-between">
- <h4 className="display-inline">{translate('settings.pr_decoration.table.title')}</h4>
- <Button onClick={props.onCreate}>{translate('settings.pr_decoration.table.create')}</Button>
- </div>
-
- <PRDecorationTable
- alm={alm}
- definitions={definitions}
- onDelete={props.onDelete}
- onEdit={props.onEdit}
- />
- {definitionKeyForDeletion && (
- <DeleteModal
- id={definitionKeyForDeletion}
- onCancel={props.onCancel}
- onDelete={props.onConfirmDelete}
- projectCount={projectCount}
- />
- )}
-
- {definitionInEdition && (
- <AlmPRDecorationFormModal
- alm={ALM_KEYS.GITHUB}
- bindingDefinition={definitionInEdition}
- onCancel={props.onCancel}
- onSubmit={props.onSubmit}
- />
- )}
- </>
- );
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { AlmDefinitionFormField, AlmDefinitionFormFieldProps } from '../AlmDefinitionFormField';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender({ help: true })).toMatchSnapshot();
+ expect(shallowRender({ isTextArea: true })).toMatchSnapshot();
+});
+
+it('should call onFieldChange', () => {
+ const onInputChange = jest.fn();
+ shallowRender({ onFieldChange: onInputChange })
+ .find('input')
+ .simulate('change', { currentTarget: { value: '' } });
+ expect(onInputChange).toBeCalled();
+
+ const onTextAreaChange = jest.fn();
+ shallowRender({ isTextArea: true, onFieldChange: onTextAreaChange })
+ .find('textarea')
+ .simulate('change', { currentTarget: { value: '' } });
+ expect(onTextAreaChange).toBeCalled();
+});
+
+function shallowRender(props: Partial<AlmDefinitionFormFieldProps<T.AlmSettingsBinding>> = {}) {
+ return shallow(
+ <AlmDefinitionFormField
+ formData={{ key: 'key' }}
+ help={false}
+ id="key"
+ isTextArea={false}
+ maxLength={40}
+ onFieldChange={jest.fn()}
+ propKey="key"
+ {...props}
+ />
+ );
+}
import * as React from 'react';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
import { mockGithubDefinition } from '../../../../../helpers/testMocks';
-import { ALM_KEYS } from '../../../utils';
import AlmPRDecorationFormModal from '../AlmPRDecorationFormModal';
it('should render correctly', () => {
expect(wrapper.instance().canSubmit()).toBe(true);
});
-function shallowRender(props: Partial<AlmPRDecorationFormModal['props']> = {}) {
- return shallow<AlmPRDecorationFormModal>(
+function shallowRender(
+ props: Partial<AlmPRDecorationFormModal<T.GithubBindingDefinition>['props']> = {}
+) {
+ return shallow<AlmPRDecorationFormModal<T.GithubBindingDefinition>>(
<AlmPRDecorationFormModal
- alm={ALM_KEYS.GITHUB}
bindingDefinition={{ appId: '', key: '', privateKey: '', url: '' }}
onCancel={jest.fn()}
onSubmit={jest.fn()}
- {...props}
- />
+ {...props}>
+ {() => null}
+ </AlmPRDecorationFormModal>
);
}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockGithubDefinition } from '../../../../../helpers/testMocks';
-import { ALM_KEYS } from '../../../utils';
import AlmPRDecorationFormModalRenderer, {
AlmPRDecorationFormModalProps
} from '../AlmPRDecorationFormModalRenderer';
function shallowRender(props: Partial<AlmPRDecorationFormModalProps> = {}) {
return shallow(
<AlmPRDecorationFormModalRenderer
- alm={ALM_KEYS.GITHUB}
canSubmit={jest.fn()}
- formData={mockGithubDefinition()}
onCancel={jest.fn()}
- onFieldChange={jest.fn()}
onSubmit={jest.fn()}
originalKey=""
- {...props}
- />
+ {...props}>
+ {() => null}
+ </AlmPRDecorationFormModalRenderer>
);
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockAzureDefinition } from '../../../../../helpers/testMocks';
+import AzureFormModal, { AzureFormModalProps } from '../AzureFormModal';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender({ formData: mockAzureDefinition() })).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<AzureFormModalProps> = {}) {
+ return shallow(
+ <AzureFormModal
+ formData={{ key: '', personalAccessToken: '' }}
+ onFieldChange={jest.fn()}
+ {...props}
+ />
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
+import { createAzureConfiguration, updateAzureConfiguration } from '../../../../../api/almSettings';
+import { mockAzureDefinition } from '../../../../../helpers/testMocks';
+import AzureTab from '../AzureTab';
+
+jest.mock('../../../../../api/almSettings', () => ({
+ countBindedProjects: jest.fn().mockResolvedValue(2),
+ createAzureConfiguration: jest.fn().mockResolvedValue({}),
+ deleteConfiguration: jest.fn().mockResolvedValue({}),
+ updateAzureConfiguration: jest.fn().mockResolvedValue({})
+}));
+
+beforeEach(() => {
+ jest.clearAllMocks();
+});
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+});
+
+it('should handle cancel', async () => {
+ const wrapper = shallowRender();
+
+ wrapper.setState({
+ editedDefinition: mockAzureDefinition()
+ });
+
+ wrapper.instance().handleCancel();
+
+ await waitAndUpdate(wrapper);
+
+ expect(wrapper.state().editedDefinition).toBeUndefined();
+});
+
+it('should create config', async () => {
+ const onUpdateDefinitions = jest.fn();
+ const config = mockAzureDefinition();
+ const wrapper = shallowRender({ onUpdateDefinitions });
+ wrapper.setState({ editedDefinition: config });
+
+ await wrapper.instance().handleSubmit(config, '');
+
+ expect(createAzureConfiguration).toBeCalledWith(config);
+ expect(onUpdateDefinitions).toBeCalled();
+ expect(wrapper.state().editedDefinition).toBeUndefined();
+});
+
+it('should update config', async () => {
+ const onUpdateDefinitions = jest.fn();
+ const config = mockAzureDefinition();
+ const wrapper = shallowRender({ onUpdateDefinitions });
+ wrapper.setState({ editedDefinition: config });
+
+ await wrapper.instance().handleSubmit(config, 'originalKey');
+
+ expect(updateAzureConfiguration).toBeCalledWith({
+ newKey: 'key',
+ ...config,
+ key: 'originalKey'
+ });
+ expect(onUpdateDefinitions).toBeCalled();
+ expect(wrapper.state().editedDefinition).toBeUndefined();
+});
+
+function shallowRender(props: Partial<AzureTab['props']> = {}) {
+ return shallow<AzureTab>(
+ <AzureTab
+ definitions={[]}
+ loading={false}
+ onDelete={jest.fn()}
+ onUpdateDefinitions={jest.fn()}
+ {...props}
+ />
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockAzureDefinition } from '../../../../../helpers/testMocks';
+import AzureTabRenderer, { AzureTabRendererProps } from '../AzureTabRenderer';
+
+it('should render correctly', () => {
+ expect(shallowRender({ loading: true })).toMatchSnapshot();
+ expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender({ editedDefinition: mockAzureDefinition() })).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<AzureTabRendererProps> = {}) {
+ return shallow(
+ <AzureTabRenderer
+ definitions={[]}
+ loading={false}
+ onCancel={jest.fn()}
+ onCreate={jest.fn()}
+ onDelete={jest.fn()}
+ onEdit={jest.fn()}
+ onSubmit={jest.fn()}
+ {...props}
+ />
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockAzureDefinition } from '../../../../../helpers/testMocks';
+import AzureTable, { AzureTableProps } from '../AzureTable';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender({ definitions: [mockAzureDefinition()] })).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<AzureTableProps> = {}) {
+ return shallow(
+ <AzureTable
+ definitions={[]}
+ loading={false}
+ onDelete={jest.fn()}
+ onEdit={jest.fn()}
+ {...props}
+ />
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockGithubDefinition } from '../../../../../helpers/testMocks';
+import GithubFormModal, { GithubFormModalProps } from '../GithubFormModal';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender({ formData: mockGithubDefinition() })).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<GithubFormModalProps> = {}) {
+ return shallow(
+ <GithubFormModal
+ formData={{ key: '', appId: '', privateKey: '', url: '' }}
+ onFieldChange={jest.fn()}
+ {...props}
+ />
+ );
+}
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
import {
createGithubConfiguration,
- deleteConfiguration,
updateGithubConfiguration
} from '../../../../../api/almSettings';
import { mockGithubDefinition } from '../../../../../helpers/testMocks';
const wrapper = shallowRender();
wrapper.setState({
- definitionKeyForDeletion: '12321',
- definitionInEdition: mockGithubDefinition()
+ editedDefinition: mockGithubDefinition()
});
wrapper.instance().handleCancel();
await waitAndUpdate(wrapper);
- expect(wrapper.state().definitionKeyForDeletion).toBeUndefined();
- expect(wrapper.state().definitionInEdition).toBeUndefined();
-});
-
-it('should delete config', async () => {
- const onUpdateDefinitions = jest.fn();
- const wrapper = shallowRender({ onUpdateDefinitions });
- wrapper.setState({ definitionKeyForDeletion: '123' });
-
- await wrapper
- .instance()
- .deleteConfiguration('123')
- .then(() => {
- expect(deleteConfiguration).toBeCalledWith('123');
- expect(onUpdateDefinitions).toBeCalled();
- expect(wrapper.state().definitionKeyForDeletion).toBeUndefined();
- });
+ expect(wrapper.state().editedDefinition).toBeUndefined();
});
it('should create config', async () => {
const onUpdateDefinitions = jest.fn();
- const config = {
- key: 'new conf',
- url: 'ewrqewr',
- appId: '3742985',
- privateKey: 'rt7r78ew6t87ret'
- };
+ const config = mockGithubDefinition();
const wrapper = shallowRender({ onUpdateDefinitions });
- wrapper.setState({ definitionInEdition: config });
+ wrapper.setState({ editedDefinition: config });
+
+ await wrapper.instance().handleSubmit(config, '');
- await wrapper
- .instance()
- .handleSubmit(config, '')
- .then(() => {
- expect(createGithubConfiguration).toBeCalledWith(config);
- expect(onUpdateDefinitions).toBeCalled();
- expect(wrapper.state().definitionInEdition).toBeUndefined();
- });
+ expect(createGithubConfiguration).toBeCalledWith(config);
+ expect(onUpdateDefinitions).toBeCalled();
+ expect(wrapper.state().editedDefinition).toBeUndefined();
});
it('should update config', async () => {
const onUpdateDefinitions = jest.fn();
- const config = {
- key: 'new conf',
- url: 'ewrqewr',
- appId: '3742985',
- privateKey: 'rt7r78ew6t87ret'
- };
+ const config = mockGithubDefinition();
const wrapper = shallowRender({ onUpdateDefinitions });
- wrapper.setState({ definitionInEdition: config });
+ wrapper.setState({ editedDefinition: config });
- await wrapper
- .instance()
- .handleSubmit(config, 'originalKey')
- .then(() => {
- expect(updateGithubConfiguration).toBeCalledWith({
- newKey: 'new conf',
- ...config,
- key: 'originalKey'
- });
- expect(onUpdateDefinitions).toBeCalled();
- expect(wrapper.state().definitionInEdition).toBeUndefined();
- });
+ await wrapper.instance().handleSubmit(config, 'originalKey');
+
+ expect(updateGithubConfiguration).toBeCalledWith({
+ newKey: 'key',
+ ...config,
+ key: 'originalKey'
+ });
+ expect(onUpdateDefinitions).toBeCalled();
+ expect(wrapper.state().editedDefinition).toBeUndefined();
});
function shallowRender(props: Partial<GithubTab['props']> = {}) {
return shallow<GithubTab>(
- <GithubTab definitions={[]} onUpdateDefinitions={jest.fn()} {...props} />
+ <GithubTab
+ definitions={[]}
+ loading={false}
+ onDelete={jest.fn()}
+ onUpdateDefinitions={jest.fn()}
+ {...props}
+ />
);
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockGithubDefinition } from '../../../../../helpers/testMocks';
+import GithubTabRenderer, { GithubTabRendererProps } from '../GithubTabRenderer';
+
+it('should render correctly', () => {
+ expect(shallowRender({ loading: true })).toMatchSnapshot();
+ expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender({ editedDefinition: mockGithubDefinition() })).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<GithubTabRendererProps> = {}) {
+ return shallow(
+ <GithubTabRenderer
+ definitions={[]}
+ loading={false}
+ onCancel={jest.fn()}
+ onCreate={jest.fn()}
+ onDelete={jest.fn()}
+ onEdit={jest.fn()}
+ onSubmit={jest.fn()}
+ {...props}
+ />
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockGithubDefinition } from '../../../../../helpers/testMocks';
+import GithubTable, { GithubTableProps } from '../GithubTable';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender({ definitions: [mockGithubDefinition()] })).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<GithubTableProps> = {}) {
+ return shallow(
+ <GithubTable
+ definitions={[]}
+ loading={false}
+ onDelete={jest.fn()}
+ onEdit={jest.fn()}
+ {...props}
+ />
+ );
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { mockGithubDefinition } from '../../../../../helpers/testMocks';
-import { ALM_KEYS } from '../../../utils';
-import PRDecorationTable, { PRDecorationTableProps } from '../PRDecorationTable';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
- expect(shallowRender({ definitions: [mockGithubDefinition()] })).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<PRDecorationTableProps> = {}) {
- return shallow(
- <PRDecorationTable
- alm={ALM_KEYS.GITHUB}
- definitions={[]}
- onDelete={jest.fn()}
- onEdit={jest.fn()}
- {...props}
- />
- );
-}
import PRDecorationTabs, { PRDecorationTabsProps } from '../PRDecorationTabs';
it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
- expect(shallowRender({ loading: false })).toMatchSnapshot();
+ expect(shallowRender({ loading: true })).toMatchSnapshot();
+ expect(shallowRender({ definitionKeyForDeletion: 'keyToDelete' })).toMatchSnapshot();
+ expect(shallowRender({ currentAlm: ALM_KEYS.AZURE })).toMatchSnapshot();
+ expect(shallowRender({ currentAlm: ALM_KEYS.GITHUB })).toMatchSnapshot();
});
function shallowRender(props: Partial<PRDecorationTabsProps> = {}) {
return shallow(
<PRDecorationTabs
currentAlm={ALM_KEYS.GITHUB}
- definitions={{ github: [] }}
- loading={true}
+ definitions={{ azure: [], github: [] }}
+ loading={false}
+ onCancel={jest.fn()}
+ onConfirmDelete={jest.fn()}
+ onDelete={jest.fn()}
onSelectAlm={jest.fn()}
onUpdateDefinitions={jest.fn()}
{...props}
import { shallow } from 'enzyme';
import * as React from 'react';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import { getAlmDefinitions } from '../../../../../api/almSettings';
+import {
+ countBindedProjects,
+ deleteConfiguration,
+ getAlmDefinitions
+} from '../../../../../api/almSettings';
import { ALM_KEYS } from '../../../utils';
import PullRequestDecoration from '../PullRequestDecoration';
jest.mock('../../../../../api/almSettings', () => ({
+ countBindedProjects: jest.fn().mockResolvedValue(0),
+ deleteConfiguration: jest.fn().mockResolvedValue(undefined),
getAlmDefinitions: jest.fn().mockResolvedValue({ github: [] })
}));
it('should handle alm selection', async () => {
const wrapper = shallowRender();
- wrapper.setState({ currentAlm: ALM_KEYS.BITBUCKET });
+ wrapper.setState({ currentAlm: ALM_KEYS.AZURE });
wrapper.instance().handleSelectAlm(ALM_KEYS.GITHUB);
expect(wrapper.state().currentAlm).toBe(ALM_KEYS.GITHUB);
});
+it('should handle delete', async () => {
+ const toBeDeleted = '45672';
+ (countBindedProjects as jest.Mock).mockResolvedValueOnce(7);
+ const wrapper = shallowRender();
+
+ wrapper.instance().handleDelete(toBeDeleted);
+ await waitAndUpdate(wrapper);
+
+ expect(wrapper.state().projectCount).toBe(7);
+ expect(wrapper.state().definitionKeyForDeletion).toBe(toBeDeleted);
+});
+
+it('should delete configuration', async () => {
+ (deleteConfiguration as jest.Mock).mockResolvedValueOnce(undefined);
+ const wrapper = shallowRender();
+ wrapper.instance().deleteConfiguration('8345678');
+
+ await waitAndUpdate(wrapper);
+ expect(wrapper.state().projectCount).toBeUndefined();
+ expect(wrapper.state().definitionKeyForDeletion).toBeUndefined();
+});
+
it('should fetch settings', async () => {
const wrapper = shallowRender();
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { ALM_KEYS } from '../../../utils';
+import TabHeader, { TabHeaderProps } from '../TabHeader';
+
+it('should render correctly', () => {
+ expect(shallowRender(ALM_KEYS.AZURE)).toMatchSnapshot();
+ expect(shallowRender(ALM_KEYS.GITHUB)).toMatchSnapshot();
+});
+
+function shallowRender(alm: ALM_KEYS, props: Partial<TabHeaderProps> = {}) {
+ return shallow(<TabHeader alm={alm} onCreate={jest.fn()} {...props} />);
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { mockGithubDefinition } from '../../../../../helpers/testMocks';
-import { ALM_KEYS } from '../../../utils';
-import TabRenderer, { TabRendererProps } from '../TabRenderer';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
- expect(shallowRender({ definitionKeyForDeletion: '123' })).toMatchSnapshot();
- expect(shallowRender({ definitionInEdition: mockGithubDefinition() })).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<TabRendererProps> = {}) {
- return shallow(
- <TabRenderer
- alm={ALM_KEYS.GITHUB}
- definitions={[]}
- onCancel={jest.fn()}
- onConfirmDelete={jest.fn()}
- onCreate={jest.fn()}
- onDelete={jest.fn()}
- onEdit={jest.fn()}
- onSubmit={jest.fn()}
- {...props}
- />
- );
-}
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<div
+ className="modal-field"
+>
+ <label
+ className="display-flex-center"
+ htmlFor="key"
+ >
+ settings.pr_decoration.form.key
+ <em
+ className="mandatory spacer-right"
+ >
+ *
+ </em>
+ </label>
+ <input
+ className="input-super-large"
+ id="key"
+ maxLength={40}
+ name="key"
+ onChange={[Function]}
+ size={50}
+ type="text"
+ value="key"
+ />
+</div>
+`;
+
+exports[`should render correctly 2`] = `
+<div
+ className="modal-field"
+>
+ <label
+ className="display-flex-center"
+ htmlFor="key"
+ >
+ settings.pr_decoration.form.key
+ <em
+ className="mandatory spacer-right"
+ >
+ *
+ </em>
+ <HelpTooltip
+ overlay="settings.pr_decoration.form.key.help"
+ />
+ </label>
+ <input
+ className="input-super-large"
+ id="key"
+ maxLength={40}
+ name="key"
+ onChange={[Function]}
+ size={50}
+ type="text"
+ value="key"
+ />
+</div>
+`;
+
+exports[`should render correctly 3`] = `
+<div
+ className="modal-field"
+>
+ <label
+ className="display-flex-center"
+ htmlFor="key"
+ >
+ settings.pr_decoration.form.key
+ <em
+ className="mandatory spacer-right"
+ >
+ *
+ </em>
+ </label>
+ <textarea
+ className="settings-large-input"
+ id="privateKey"
+ maxLength={40}
+ onChange={[Function]}
+ required={true}
+ rows={5}
+ value="key"
+ />
+</div>
+`;
exports[`should render correctly 1`] = `
<AlmPRDecorationFormModalRenderer
- alm="github"
canSubmit={[Function]}
- formData={
- Object {
- "appId": "",
- "key": "",
- "privateKey": "",
- "url": "",
- }
- }
onCancel={[MockFunction]}
- onFieldChange={[Function]}
onSubmit={[Function]}
originalKey=""
/>
<div
className="modal-body modal-container"
>
- <div
- className="modal-field"
- >
- <label
- className="display-flex-center"
- htmlFor="name"
- >
- settings.pr_decoration.form.name
- <em
- className="mandatory spacer-right"
- >
- *
- </em>
- <HelpTooltip
- overlay="settings.pr_decoration.form.name.help"
- />
- </label>
- <input
- autoFocus={true}
- className="input-super-large"
- id="name"
- maxLength={40}
- name="name"
- onChange={[Function]}
- size={50}
- type="text"
- value="key"
- />
- </div>
- <div
- className="modal-field"
- >
- <label
- className="display-flex-center"
- htmlFor="url.github"
- >
- settings.pr_decoration.form.url.github
- <em
- className="mandatory spacer-right"
- >
- *
- </em>
- </label>
- <input
- className="input-super-large"
- id="url.github"
- maxLength={2000}
- name="url.github"
- onChange={[Function]}
- size={50}
- type="text"
- value="http:alm.enterprise.com"
- />
- </div>
- <div
- className="modal-field"
- >
- <label
- className="display-flex-center"
- htmlFor="app_id"
- >
- settings.pr_decoration.form.app_id
- <em
- className="mandatory spacer-right"
- >
- *
- </em>
- </label>
- <input
- className="input-super-large"
- id="app_id"
- maxLength={80}
- name="app_id"
- onChange={[Function]}
- size={50}
- type="text"
- value="123456"
- />
- </div>
- <div
- className="modal-field"
- >
- <label
- className="display-flex-center"
- htmlFor="private_key"
- >
- settings.pr_decoration.form.private_key
- <em
- className="mandatory spacer-right"
- >
- *
- </em>
- </label>
- <textarea
- className="settings-large-input"
- id="privateKey"
- maxLength={2000}
- onChange={[Function]}
- required={true}
- rows={5}
- value="asdf1234"
- />
- </div>
+ <Component />
</div>
<div
className="modal-foot"
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Fragment>
+ <AlmDefinitionFormField
+ autoFocus={true}
+ formData={
+ Object {
+ "key": "",
+ "personalAccessToken": "",
+ }
+ }
+ help={true}
+ id="name"
+ isTextArea={false}
+ maxLength={40}
+ onFieldChange={[MockFunction]}
+ propKey="key"
+ />
+ <AlmDefinitionFormField
+ formData={
+ Object {
+ "key": "",
+ "personalAccessToken": "",
+ }
+ }
+ help={true}
+ id="personal_access_token"
+ isTextArea={true}
+ maxLength={2000}
+ onFieldChange={[MockFunction]}
+ propKey="personalAccessToken"
+ />
+</Fragment>
+`;
+
+exports[`should render correctly 2`] = `
+<Fragment>
+ <AlmDefinitionFormField
+ autoFocus={true}
+ formData={
+ Object {
+ "key": "key",
+ "personalAccessToken": "asdf1234",
+ }
+ }
+ help={true}
+ id="name"
+ isTextArea={false}
+ maxLength={40}
+ onFieldChange={[MockFunction]}
+ propKey="key"
+ />
+ <AlmDefinitionFormField
+ formData={
+ Object {
+ "key": "key",
+ "personalAccessToken": "asdf1234",
+ }
+ }
+ help={true}
+ id="personal_access_token"
+ isTextArea={true}
+ maxLength={2000}
+ onFieldChange={[MockFunction]}
+ propKey="personalAccessToken"
+ />
+</Fragment>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<AzureTabRenderer
+ definitions={Array []}
+ loading={false}
+ onCancel={[Function]}
+ onCreate={[Function]}
+ onDelete={[MockFunction]}
+ onEdit={[Function]}
+ onSubmit={[Function]}
+/>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Fragment>
+ <TabHeader
+ alm="azure"
+ onCreate={[MockFunction]}
+ />
+ <AzureTable
+ definitions={Array []}
+ loading={true}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ />
+</Fragment>
+`;
+
+exports[`should render correctly 2`] = `
+<Fragment>
+ <TabHeader
+ alm="azure"
+ onCreate={[MockFunction]}
+ />
+ <AzureTable
+ definitions={Array []}
+ loading={false}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ />
+</Fragment>
+`;
+
+exports[`should render correctly 3`] = `
+<Fragment>
+ <TabHeader
+ alm="azure"
+ onCreate={[MockFunction]}
+ />
+ <AzureTable
+ definitions={Array []}
+ loading={false}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ />
+ <AlmPRDecorationFormModal
+ bindingDefinition={
+ Object {
+ "key": "key",
+ "personalAccessToken": "asdf1234",
+ }
+ }
+ onCancel={[MockFunction]}
+ onSubmit={[MockFunction]}
+ >
+ <Component />
+ </AlmPRDecorationFormModal>
+</Fragment>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<table
+ className="data zebra spacer-bottom"
+>
+ <thead>
+ <tr>
+ <th>
+ settings.pr_decoration.table.column.name
+ </th>
+ <th
+ className="thin"
+ >
+ settings.pr_decoration.table.column.edit
+ </th>
+ <th
+ className="thin"
+ >
+ settings.pr_decoration.table.column.delete
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td
+ colSpan={3}
+ >
+ settings.pr_decoration.table.empty.azure
+ </td>
+ </tr>
+ </tbody>
+</table>
+`;
+
+exports[`should render correctly 2`] = `
+<table
+ className="data zebra spacer-bottom"
+>
+ <thead>
+ <tr>
+ <th>
+ settings.pr_decoration.table.column.name
+ </th>
+ <th
+ className="thin"
+ >
+ settings.pr_decoration.table.column.edit
+ </th>
+ <th
+ className="thin"
+ >
+ settings.pr_decoration.table.column.delete
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ key="key"
+ >
+ <td>
+ key
+ </td>
+ <td>
+ <ButtonIcon
+ onClick={[Function]}
+ >
+ <EditIcon />
+ </ButtonIcon>
+ </td>
+ <td>
+ <DeleteButton
+ onClick={[Function]}
+ />
+ </td>
+ </tr>
+ </tbody>
+</table>
+`;
confirmButtonText="delete"
confirmData="1"
header="settings.pr_decoration.delete.header"
+ isDestructive={true}
onClose={[MockFunction]}
onConfirm={[MockFunction]}
>
confirmButtonText="delete"
confirmData="1"
header="settings.pr_decoration.delete.header"
+ isDestructive={true}
onClose={[MockFunction]}
onConfirm={[MockFunction]}
>
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Fragment>
+ <AlmDefinitionFormField
+ autoFocus={true}
+ formData={
+ Object {
+ "appId": "",
+ "key": "",
+ "privateKey": "",
+ "url": "",
+ }
+ }
+ help={true}
+ id="name"
+ isTextArea={false}
+ maxLength={40}
+ onFieldChange={[MockFunction]}
+ propKey="key"
+ />
+ <AlmDefinitionFormField
+ formData={
+ Object {
+ "appId": "",
+ "key": "",
+ "privateKey": "",
+ "url": "",
+ }
+ }
+ help={false}
+ id="url.github"
+ isTextArea={false}
+ maxLength={2000}
+ onFieldChange={[MockFunction]}
+ propKey="url"
+ />
+ <AlmDefinitionFormField
+ formData={
+ Object {
+ "appId": "",
+ "key": "",
+ "privateKey": "",
+ "url": "",
+ }
+ }
+ help={false}
+ id="app_id"
+ isTextArea={false}
+ maxLength={80}
+ onFieldChange={[MockFunction]}
+ propKey="appId"
+ />
+ <AlmDefinitionFormField
+ formData={
+ Object {
+ "appId": "",
+ "key": "",
+ "privateKey": "",
+ "url": "",
+ }
+ }
+ help={false}
+ id="private_key"
+ isTextArea={true}
+ maxLength={2000}
+ onFieldChange={[MockFunction]}
+ propKey="privateKey"
+ />
+</Fragment>
+`;
+
+exports[`should render correctly 2`] = `
+<Fragment>
+ <AlmDefinitionFormField
+ autoFocus={true}
+ formData={
+ Object {
+ "appId": "123456",
+ "key": "key",
+ "privateKey": "asdf1234",
+ "url": "http:alm.enterprise.com",
+ }
+ }
+ help={true}
+ id="name"
+ isTextArea={false}
+ maxLength={40}
+ onFieldChange={[MockFunction]}
+ propKey="key"
+ />
+ <AlmDefinitionFormField
+ formData={
+ Object {
+ "appId": "123456",
+ "key": "key",
+ "privateKey": "asdf1234",
+ "url": "http:alm.enterprise.com",
+ }
+ }
+ help={false}
+ id="url.github"
+ isTextArea={false}
+ maxLength={2000}
+ onFieldChange={[MockFunction]}
+ propKey="url"
+ />
+ <AlmDefinitionFormField
+ formData={
+ Object {
+ "appId": "123456",
+ "key": "key",
+ "privateKey": "asdf1234",
+ "url": "http:alm.enterprise.com",
+ }
+ }
+ help={false}
+ id="app_id"
+ isTextArea={false}
+ maxLength={80}
+ onFieldChange={[MockFunction]}
+ propKey="appId"
+ />
+ <AlmDefinitionFormField
+ formData={
+ Object {
+ "appId": "123456",
+ "key": "key",
+ "privateKey": "asdf1234",
+ "url": "http:alm.enterprise.com",
+ }
+ }
+ help={false}
+ id="private_key"
+ isTextArea={true}
+ maxLength={2000}
+ onFieldChange={[MockFunction]}
+ propKey="privateKey"
+ />
+</Fragment>
+`;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `
-<TabRenderer
- alm="github"
+<GithubTabRenderer
definitions={Array []}
+ loading={false}
onCancel={[Function]}
- onConfirmDelete={[Function]}
onCreate={[Function]}
- onDelete={[Function]}
+ onDelete={[MockFunction]}
onEdit={[Function]}
onSubmit={[Function]}
/>
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Fragment>
+ <TabHeader
+ alm="github"
+ onCreate={[MockFunction]}
+ />
+ <GithubTable
+ definitions={Array []}
+ loading={true}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ />
+</Fragment>
+`;
+
+exports[`should render correctly 2`] = `
+<Fragment>
+ <TabHeader
+ alm="github"
+ onCreate={[MockFunction]}
+ />
+ <GithubTable
+ definitions={Array []}
+ loading={false}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ />
+</Fragment>
+`;
+
+exports[`should render correctly 3`] = `
+<Fragment>
+ <TabHeader
+ alm="github"
+ onCreate={[MockFunction]}
+ />
+ <GithubTable
+ definitions={Array []}
+ loading={false}
+ onDelete={[MockFunction]}
+ onEdit={[MockFunction]}
+ />
+ <AlmPRDecorationFormModal
+ bindingDefinition={
+ Object {
+ "appId": "123456",
+ "key": "key",
+ "privateKey": "asdf1234",
+ "url": "http:alm.enterprise.com",
+ }
+ }
+ onCancel={[MockFunction]}
+ onSubmit={[MockFunction]}
+ >
+ <Component />
+ </AlmPRDecorationFormModal>
+</Fragment>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<table
+ className="data zebra spacer-bottom"
+>
+ <thead>
+ <tr>
+ <th>
+ settings.pr_decoration.table.column.name
+ </th>
+ <th>
+ settings.pr_decoration.table.column.github.url
+ </th>
+ <th>
+ settings.pr_decoration.table.column.app_id
+ </th>
+ <th
+ className="thin"
+ >
+ settings.pr_decoration.table.column.edit
+ </th>
+ <th
+ className="thin"
+ >
+ settings.pr_decoration.table.column.delete
+ </th>
+ </tr>
+ </thead>
+ <tbody />
+</table>
+`;
+
+exports[`should render correctly 2`] = `
+<table
+ className="data zebra spacer-bottom"
+>
+ <thead>
+ <tr>
+ <th>
+ settings.pr_decoration.table.column.name
+ </th>
+ <th>
+ settings.pr_decoration.table.column.github.url
+ </th>
+ <th>
+ settings.pr_decoration.table.column.app_id
+ </th>
+ <th
+ className="thin"
+ >
+ settings.pr_decoration.table.column.edit
+ </th>
+ <th
+ className="thin"
+ >
+ settings.pr_decoration.table.column.delete
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ key="key"
+ >
+ <td>
+ key
+ </td>
+ <td>
+ http:alm.enterprise.com
+ </td>
+ <td>
+ 123456
+ </td>
+ <td>
+ <ButtonIcon
+ onClick={[Function]}
+ >
+ <EditIcon />
+ </ButtonIcon>
+ </td>
+ <td>
+ <DeleteButton
+ onClick={[Function]}
+ />
+ </td>
+ </tr>
+ </tbody>
+</table>
+`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Fragment>
- <table
- className="data zebra spacer-bottom"
- >
- <thead>
- <tr>
- <th>
- settings.pr_decoration.table.column.name
- </th>
- <th>
- settings.pr_decoration.table.column.github.url
- </th>
- <th>
- settings.pr_decoration.table.column.app_id
- </th>
- <th
- className="thin"
- >
- settings.pr_decoration.table.column.edit
- </th>
- <th
- className="thin"
- >
- settings.pr_decoration.table.column.delete
- </th>
- </tr>
- </thead>
- <tbody />
- </table>
-</Fragment>
-`;
-
-exports[`should render correctly 2`] = `
-<Fragment>
- <table
- className="data zebra spacer-bottom"
- >
- <thead>
- <tr>
- <th>
- settings.pr_decoration.table.column.name
- </th>
- <th>
- settings.pr_decoration.table.column.github.url
- </th>
- <th>
- settings.pr_decoration.table.column.app_id
- </th>
- <th
- className="thin"
- >
- settings.pr_decoration.table.column.edit
- </th>
- <th
- className="thin"
- >
- settings.pr_decoration.table.column.delete
- </th>
- </tr>
- </thead>
- <tbody>
- <tr
- key="key"
- >
- <td>
- key
- </td>
- <td>
- http:alm.enterprise.com
- </td>
- <td>
- 123456
- </td>
- <td>
- <ButtonIcon
- onClick={[Function]}
- >
- <EditIcon />
- </ButtonIcon>
- </td>
- <td>
- <ButtonIcon
- onClick={[Function]}
- >
- <DeleteIcon />
- </ButtonIcon>
- </td>
- </tr>
- </tbody>
- </table>
-</Fragment>
-`;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `
-<DeferredSpinner
- timeout={100}
-/>
+<Fragment>
+ <header
+ className="page-header"
+ >
+ <h1
+ className="page-title"
+ >
+ settings.pr_decoration.title
+ </h1>
+ </header>
+ <div
+ className="markdown small spacer-top big-spacer-bottom"
+ >
+ settings.pr_decoration.description
+ </div>
+ <BoxedTabs
+ onSelect={[MockFunction]}
+ selected="github"
+ tabs={
+ Array [
+ Object {
+ "key": "github",
+ "label": "Github Enterprise",
+ },
+ Object {
+ "key": "azure",
+ "label": "Azure DevOps Server",
+ },
+ ]
+ }
+ />
+ <div
+ className="boxed-group boxed-group-inner"
+ >
+ <GithubTab
+ definitions={Array []}
+ loading={true}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ />
+ </div>
+</Fragment>
`;
exports[`should render correctly 2`] = `
"key": "github",
"label": "Github Enterprise",
},
+ Object {
+ "key": "azure",
+ "label": "Azure DevOps Server",
+ },
+ ]
+ }
+ />
+ <div
+ className="boxed-group boxed-group-inner"
+ >
+ <GithubTab
+ definitions={Array []}
+ loading={false}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ />
+ </div>
+ <DeleteModal
+ id="keyToDelete"
+ onCancel={[MockFunction]}
+ onDelete={[MockFunction]}
+ />
+</Fragment>
+`;
+
+exports[`should render correctly 3`] = `
+<Fragment>
+ <header
+ className="page-header"
+ >
+ <h1
+ className="page-title"
+ >
+ settings.pr_decoration.title
+ </h1>
+ </header>
+ <div
+ className="markdown small spacer-top big-spacer-bottom"
+ >
+ settings.pr_decoration.description
+ </div>
+ <BoxedTabs
+ onSelect={[MockFunction]}
+ selected="azure"
+ tabs={
+ Array [
+ Object {
+ "key": "github",
+ "label": "Github Enterprise",
+ },
+ Object {
+ "key": "azure",
+ "label": "Azure DevOps Server",
+ },
+ ]
+ }
+ />
+ <div
+ className="boxed-group boxed-group-inner"
+ >
+ <AzureTab
+ definitions={Array []}
+ loading={false}
+ onDelete={[MockFunction]}
+ onUpdateDefinitions={[MockFunction]}
+ />
+ </div>
+</Fragment>
+`;
+
+exports[`should render correctly 4`] = `
+<Fragment>
+ <header
+ className="page-header"
+ >
+ <h1
+ className="page-title"
+ >
+ settings.pr_decoration.title
+ </h1>
+ </header>
+ <div
+ className="markdown small spacer-top big-spacer-bottom"
+ >
+ settings.pr_decoration.description
+ </div>
+ <BoxedTabs
+ onSelect={[MockFunction]}
+ selected="github"
+ tabs={
+ Array [
+ Object {
+ "key": "github",
+ "label": "Github Enterprise",
+ },
+ Object {
+ "key": "azure",
+ "label": "Azure DevOps Server",
+ },
]
}
/>
>
<GithubTab
definitions={Array []}
+ loading={false}
+ onDelete={[MockFunction]}
onUpdateDefinitions={[MockFunction]}
/>
</div>
currentAlm="github"
definitions={
Object {
+ "azure": Array [],
"github": Array [],
}
}
loading={true}
+ onCancel={[Function]}
+ onConfirmDelete={[Function]}
+ onDelete={[Function]}
onSelectAlm={[Function]}
onUpdateDefinitions={[Function]}
/>
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Fragment>
+ <Alert
+ className="spacer-top huge-spacer-bottom"
+ variant="info"
+ >
+ <FormattedMessage
+ defaultMessage="settings.pr_decoration.azure.info"
+ id="settings.pr_decoration.azure.info"
+ values={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/documentation/analysis/pull-request/#pr-decoration"
+ >
+ learn_more
+ </Link>,
+ }
+ }
+ />
+ </Alert>
+ <div
+ className="big-spacer-bottom display-flex-space-between"
+ >
+ <h4
+ className="display-inline"
+ >
+ settings.pr_decoration.table.title
+ </h4>
+ <Button
+ onClick={[MockFunction]}
+ >
+ settings.pr_decoration.table.create
+ </Button>
+ </div>
+</Fragment>
+`;
+
+exports[`should render correctly 2`] = `
+<Fragment>
+ <Alert
+ className="spacer-top huge-spacer-bottom"
+ variant="info"
+ >
+ <FormattedMessage
+ defaultMessage="settings.pr_decoration.github.info"
+ id="settings.pr_decoration.github.info"
+ values={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/documentation/analysis/pull-request/#pr-decoration"
+ >
+ learn_more
+ </Link>,
+ }
+ }
+ />
+ </Alert>
+ <div
+ className="big-spacer-bottom display-flex-space-between"
+ >
+ <h4
+ className="display-inline"
+ >
+ settings.pr_decoration.table.title
+ </h4>
+ <Button
+ onClick={[MockFunction]}
+ >
+ settings.pr_decoration.table.create
+ </Button>
+ </div>
+</Fragment>
+`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Fragment>
- <Alert
- className="spacer-top huge-spacer-bottom"
- variant="info"
- >
- <FormattedMessage
- defaultMessage="settings.pr_decoration.github.info"
- id="settings.pr_decoration.github.info"
- values={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- to="/documentation/analysis/pull-request/#pr-decoration"
- >
- learn_more
- </Link>,
- }
- }
- />
- </Alert>
- <div
- className="big-spacer-bottom display-flex-space-between"
- >
- <h4
- className="display-inline"
- >
- settings.pr_decoration.table.title
- </h4>
- <Button
- onClick={[MockFunction]}
- >
- settings.pr_decoration.table.create
- </Button>
- </div>
- <PRDecorationTable
- alm="github"
- definitions={Array []}
- onDelete={[MockFunction]}
- onEdit={[MockFunction]}
- />
-</Fragment>
-`;
-
-exports[`should render correctly 2`] = `
-<Fragment>
- <Alert
- className="spacer-top huge-spacer-bottom"
- variant="info"
- >
- <FormattedMessage
- defaultMessage="settings.pr_decoration.github.info"
- id="settings.pr_decoration.github.info"
- values={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- to="/documentation/analysis/pull-request/#pr-decoration"
- >
- learn_more
- </Link>,
- }
- }
- />
- </Alert>
- <div
- className="big-spacer-bottom display-flex-space-between"
- >
- <h4
- className="display-inline"
- >
- settings.pr_decoration.table.title
- </h4>
- <Button
- onClick={[MockFunction]}
- >
- settings.pr_decoration.table.create
- </Button>
- </div>
- <PRDecorationTable
- alm="github"
- definitions={Array []}
- onDelete={[MockFunction]}
- onEdit={[MockFunction]}
- />
- <DeleteModal
- id="123"
- onCancel={[MockFunction]}
- onDelete={[MockFunction]}
- />
-</Fragment>
-`;
-
-exports[`should render correctly 3`] = `
-<Fragment>
- <Alert
- className="spacer-top huge-spacer-bottom"
- variant="info"
- >
- <FormattedMessage
- defaultMessage="settings.pr_decoration.github.info"
- id="settings.pr_decoration.github.info"
- values={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- to="/documentation/analysis/pull-request/#pr-decoration"
- >
- learn_more
- </Link>,
- }
- }
- />
- </Alert>
- <div
- className="big-spacer-bottom display-flex-space-between"
- >
- <h4
- className="display-inline"
- >
- settings.pr_decoration.table.title
- </h4>
- <Button
- onClick={[MockFunction]}
- >
- settings.pr_decoration.table.create
- </Button>
- </div>
- <PRDecorationTable
- alm="github"
- definitions={Array []}
- onDelete={[MockFunction]}
- onEdit={[MockFunction]}
- />
- <AlmPRDecorationFormModal
- alm="github"
- bindingDefinition={
- Object {
- "appId": "123456",
- "key": "key",
- "privateKey": "asdf1234",
- "url": "http:alm.enterprise.com",
- }
- }
- onCancel={[MockFunction]}
- onSubmit={[MockFunction]}
- />
-</Fragment>
-`;
success: boolean;
}
+function renderLabel(v: T.AlmSettingsInstance) {
+ return v.url ? `${v.key} — ${v.url}` : v.key;
+}
+
export default function PRDecorationBindingRenderer(props: PRDecorationBindingRendererProps) {
const {
formData: { repository, key },
clearable={false}
id="name"
onChange={({ value }: { value: string }) => props.onFieldChange('key', value)}
- options={instances.map(v => ({ value: v.key, label: `${v.key} — ${v.url}` }))}
+ options={instances.map(v => ({ value: v.key, label: renderLabel(v) }))}
searchable={false}
value={key}
/>
export const DEFAULT_CATEGORY = 'general';
export enum ALM_KEYS {
- BITBUCKET = 'bitbucket',
- GITHUB = 'github',
- AZURE_DEVOPS = 'azure_devops'
+ AZURE = 'azure',
+ // BITBUCKET = 'bitbucket',
+ GITHUB = 'github'
}
export const almName = {
- [ALM_KEYS.AZURE_DEVOPS]: 'Azure DevOps Server',
- [ALM_KEYS.BITBUCKET]: 'Bitbucket Server',
+ [ALM_KEYS.AZURE]: 'Azure DevOps Server',
+ // [ALM_KEYS.BITBUCKET]: 'Bitbucket Server',
[ALM_KEYS.GITHUB]: 'Github Enterprise'
};
};
}
+export function mockAzureDefinition(
+ overrides: Partial<T.AzureBindingDefinition> = {}
+): T.AzureBindingDefinition {
+ return {
+ key: 'key',
+ personalAccessToken: 'asdf1234',
+ ...overrides
+ };
+}
+
export function mockGithubDefinition(
overrides: Partial<T.GithubBindingDefinition> = {}
): T.GithubBindingDefinition {
declare namespace T {
export interface AlmSettingsBinding {
key: string;
- url: string;
}
- export interface AlmSettingsInstance extends AlmSettingsBinding {
+ export interface AlmSettingsInstance {
alm: string;
+ key: string;
+ url?: string;
}
export interface AlmSettingsBindingDefinitions {
+ azure: AzureBindingDefinition[];
github: GithubBindingDefinition[];
}
export interface GithubBindingDefinition extends AlmSettingsBinding {
+ url: string;
appId: string;
privateKey: string;
}
+ export interface AzureBindingDefinition extends AlmSettingsBinding {
+ personalAccessToken: string;
+ }
+
export interface ProjectAlmBinding {
key: string;
alm: string;
settings.pr_decoration.title=Pull Requests decoration
settings.pr_decoration.description=When Pull Request decoration is enabled, SonarQube publishes the status of the analysis directly in your ALM Pull requests.
settings.pr_decoration.manage_instances=Manage instances
+settings.pr_decoration.azure.info=The account that will be used to decorate Pull Requests needs 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.table.title=Pull Request decoration configurations
settings.pr_decoration.table.create=Create configuration
settings.pr_decoration.form.url.github=GitHub Enterprise URL
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.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.save=Save configuration
settings.pr_decoration.form.cancel=Cancel