/* * 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 { csvEscape } from 'sonar-ui-common/helpers/csv'; import { latinize } from 'sonar-ui-common/helpers/strings'; import { translate } from 'sonar-ui-common/helpers/l10n'; import { SubmitButton, ResetButtonLink } from 'sonar-ui-common/components/controls/buttons'; import Modal from 'sonar-ui-common/components/controls/Modal'; import { Alert } from 'sonar-ui-common/components/ui/Alert'; import Select from 'sonar-ui-common/components/controls/Select'; import MarkdownTips from '../../../components/common/MarkdownTips'; import SeverityHelper from '../../../components/shared/SeverityHelper'; import TypeHelper from '../../../components/shared/TypeHelper'; import { createRule, updateRule } from '../../../api/rules'; import { SEVERITIES, RULE_TYPES, RULE_STATUSES } from '../../../helpers/constants'; interface Props { customRule?: T.RuleDetails; onClose: () => void; onDone: (newRuleDetails: T.RuleDetails) => void; organization: string | undefined; templateRule: T.RuleDetails; } interface State { description: string; key: string; keyModifiedByUser: boolean; name: string; params: T.Dict; reactivating: boolean; severity: string; status: string; submitting: boolean; type: string; } export default class CustomRuleFormModal extends React.PureComponent { mounted = false; constructor(props: Props) { super(props); const params: T.Dict = {}; if (props.customRule && props.customRule.params) { for (const param of props.customRule.params) { params[param.key] = param.defaultValue || ''; } } this.state = { description: (props.customRule && props.customRule.mdDesc) || '', key: '', keyModifiedByUser: false, name: (props.customRule && props.customRule.name) || '', params, reactivating: false, severity: (props.customRule && props.customRule.severity) || props.templateRule.severity, status: (props.customRule && props.customRule.status) || props.templateRule.status, submitting: false, type: (props.customRule && props.customRule.type) || props.templateRule.type }; } componentDidMount() { this.mounted = true; } componentWillUnmount() { this.mounted = false; } prepareRequest = () => { const { customRule, organization, templateRule } = this.props; const params = Object.keys(this.state.params) .map(key => `${key}=${csvEscape(this.state.params[key])}`) .join(';'); const ruleData = { markdown_description: this.state.description, name: this.state.name, organization, params, severity: this.state.severity, status: this.state.status }; return customRule ? updateRule({ ...ruleData, key: customRule.key }) : createRule({ ...ruleData, custom_key: this.state.key, prevent_reactivation: !this.state.reactivating, template_key: templateRule.key, type: this.state.type }); }; handleFormSubmit = (event: React.SyntheticEvent) => { event.preventDefault(); this.setState({ submitting: true }); this.prepareRequest().then( newRuleDetails => { if (this.mounted) { this.setState({ submitting: false }); this.props.onDone(newRuleDetails); } }, (response: Response) => { if (this.mounted) { this.setState({ reactivating: response.status === 409, submitting: false }); } } ); }; handleNameChange = (event: React.SyntheticEvent) => { const { value: name } = event.currentTarget; this.setState(state => ({ name, key: state.keyModifiedByUser ? state.key : latinize(name).replace(/[^A-Za-z0-9]/g, '_') })); }; handleKeyChange = (event: React.SyntheticEvent) => this.setState({ key: event.currentTarget.value, keyModifiedByUser: true }); handleDescriptionChange = (event: React.SyntheticEvent) => this.setState({ description: event.currentTarget.value }); handleTypeChange = ({ value }: { value: string }) => this.setState({ type: value }); handleSeverityChange = ({ value }: { value: string }) => this.setState({ severity: value }); handleStatusChange = ({ value }: { value: string }) => this.setState({ status: value }); handleParameterChange = (event: React.SyntheticEvent) => { const { name, value } = event.currentTarget; this.setState((state: State) => ({ params: { ...state.params, [name]: value } })); }; renderNameField = () => (
); renderKeyField = () => (
{this.props.customRule ? ( {this.props.customRule.key} ) : ( )}
); renderDescriptionField = () => (