aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web
diff options
context:
space:
mode:
authorStas Vilchik <stas.vilchik@sonarsource.com>2018-02-21 14:24:05 +0100
committerStas Vilchik <stas.vilchik@sonarsource.com>2018-02-27 13:14:54 +0100
commit36969ad381fb8ff7f93daf9c40d801b69e3a1bac (patch)
tree48e752209e71a5c407421325797e5e828516b282 /server/sonar-web
parent87ecef1b3768eaa980083c466a5adf25e5748d44 (diff)
downloadsonarqube-36969ad381fb8ff7f93daf9c40d801b69e3a1bac.tar.gz
sonarqube-36969ad381fb8ff7f93daf9c40d801b69e3a1bac.zip
rewrite remaining backbone modals in react
Diffstat (limited to 'server/sonar-web')
-rw-r--r--server/sonar-web/src/main/js/api/projectLinks.ts29
-rw-r--r--server/sonar-web/src/main/js/app/types.ts7
-rw-r--r--server/sonar-web/src/main/js/app/utils/exposeLibraries.ts5
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/MetaLink.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/MetaLinks.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/Key.js61
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js87
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.tsx85
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyConfirm.tsx65
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js89
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.tsx75
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.hbs30
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js41
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/links/CreationModal.tsx111
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/links/Header.js51
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/links/Header.tsx73
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/links/LinkRow.tsx (renamed from server/sonar-web/src/main/js/apps/project-admin/links/LinkRow.js)59
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/links/Links.js20
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/links/Table.js8
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModal.js42
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModalTemplate.hbs22
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModal.js46
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModalTemplate.hbs13
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/store/actions.js35
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js65
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js73
-rw-r--r--server/sonar-web/src/main/js/components/RestartModal/index.js47
-rw-r--r--server/sonar-web/src/main/js/components/RestartModal/templates/restarting.hbs14
-rw-r--r--server/sonar-web/src/main/js/components/RestartModal/templates/template.hbs15
-rw-r--r--server/sonar-web/src/main/js/components/common/modal-form.js99
-rw-r--r--server/sonar-web/src/main/js/components/common/modals.js92
-rw-r--r--server/sonar-web/src/main/js/components/common/selectable-collection-view.js82
-rw-r--r--server/sonar-web/src/main/js/components/controls/ConfirmButton.tsx19
33 files changed, 581 insertions, 985 deletions
diff --git a/server/sonar-web/src/main/js/api/projectLinks.ts b/server/sonar-web/src/main/js/api/projectLinks.ts
index e91b200c4fe..22c5fba17fd 100644
--- a/server/sonar-web/src/main/js/api/projectLinks.ts
+++ b/server/sonar-web/src/main/js/api/projectLinks.ts
@@ -17,30 +17,21 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { getJSON, post, postJSON } from '../helpers/request';
+import { ProjectLink } from '../app/types';
import throwGlobalError from '../app/utils/throwGlobalError';
-
-export interface ProjectLink {
- id: string;
- name: string;
- type: string;
- url: string;
-}
+import { getJSON, post, postJSON } from '../helpers/request';
export function getProjectLinks(projectKey: string): Promise<ProjectLink[]> {
- const url = '/api/project_links/search';
- const data = { projectKey };
- return getJSON(url, data).then(r => r.links, throwGlobalError);
+ return getJSON('/api/project_links/search', { projectKey }).then(r => r.links, throwGlobalError);
}
-export function deleteLink(linkId: string): Promise<void> {
- const url = '/api/project_links/delete';
- const data = { id: linkId };
- return post(url, data);
+export function deleteLink(linkId: string) {
+ return post('/api/project_links/delete', { id: linkId }).catch(throwGlobalError);
}
-export function createLink(projectKey: string, name: string, url: string): Promise<any> {
- const apiURL = '/api/project_links/create';
- const data = { projectKey, name, url };
- return postJSON(apiURL, data).then(r => r.link);
+export function createLink(projectKey: string, name: string, url: string): Promise<ProjectLink> {
+ return postJSON('/api/project_links/create', { projectKey, name, url }).then(
+ r => r.link,
+ throwGlobalError
+ );
}
diff --git a/server/sonar-web/src/main/js/app/types.ts b/server/sonar-web/src/main/js/app/types.ts
index dddeec8424e..13b8bac9f66 100644
--- a/server/sonar-web/src/main/js/app/types.ts
+++ b/server/sonar-web/src/main/js/app/types.ts
@@ -245,6 +245,13 @@ export interface PermissionTemplate {
}>;
}
+export interface ProjectLink {
+ id: string;
+ name: string;
+ type: string;
+ url: string;
+}
+
export interface Rule {
isTemplate?: boolean;
key: string;
diff --git a/server/sonar-web/src/main/js/app/utils/exposeLibraries.ts b/server/sonar-web/src/main/js/app/utils/exposeLibraries.ts
index b19336572b0..4e853881db2 100644
--- a/server/sonar-web/src/main/js/app/utils/exposeLibraries.ts
+++ b/server/sonar-web/src/main/js/app/utils/exposeLibraries.ts
@@ -33,7 +33,6 @@ import Modal from '../../components/controls/Modal';
import SearchBox from '../../components/controls/SearchBox';
import Select from '../../components/controls/Select';
import Tooltip from '../../components/controls/Tooltip';
-import ModalForm from '../../components/common/modal-form';
import SelectList from '../../components/SelectList';
import CoverageRating from '../../components/ui/CoverageRating';
import DuplicationsRating from '../../components/ui/DuplicationsRating';
@@ -63,9 +62,7 @@ const exposeLibraries = () => {
Tooltip,
Select,
SelectList,
- SearchBox,
- // deprecated, used in Governance
- ModalForm_deprecated: ModalForm
+ SearchBox
};
};
diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.tsx b/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.tsx
index e4c9a697009..d909bc0faff 100644
--- a/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.tsx
@@ -19,8 +19,8 @@
*/
import * as React from 'react';
import { isProvided, getLinkName } from '../../project-admin/links/utils';
+import { ProjectLink } from '../../../app/types';
import BugTrackerIcon from '../../../components/ui/BugTrackerIcon';
-import { ProjectLink } from '../../../api/projectLinks';
interface Props {
link: ProjectLink;
diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaLinks.tsx b/server/sonar-web/src/main/js/apps/overview/meta/MetaLinks.tsx
index ed778b4cef7..d9db8d5b150 100644
--- a/server/sonar-web/src/main/js/apps/overview/meta/MetaLinks.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaLinks.tsx
@@ -19,9 +19,9 @@
*/
import * as React from 'react';
import MetaLink from './MetaLink';
-import { getProjectLinks, ProjectLink } from '../../../api/projectLinks';
+import { getProjectLinks } from '../../../api/projectLinks';
import { orderLinks } from '../../project-admin/links/utils';
-import { LightComponent } from '../../../app/types';
+import { LightComponent, ProjectLink } from '../../../app/types';
import { translate } from '../../../helpers/l10n';
interface Props {
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/Key.js b/server/sonar-web/src/main/js/apps/project-admin/key/Key.js
index 52faac1bdc0..d1688ed106e 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/key/Key.js
+++ b/server/sonar-web/src/main/js/apps/project-admin/key/Key.js
@@ -26,14 +26,13 @@ import UpdateForm from './UpdateForm';
import BulkUpdate from './BulkUpdate';
import FineGrainedUpdate from './FineGrainedUpdate';
import { reloadUpdateKeyPage } from './utils';
-import { fetchProjectModules, changeKey } from '../store/actions';
+import { changeKey, fetchProjectModules } from '../store/actions';
import { translate } from '../../../helpers/l10n';
import {
addGlobalErrorMessage,
- closeAllGlobalMessages,
- addGlobalSuccessMessage
+ addGlobalSuccessMessage,
+ closeAllGlobalMessages
} from '../../../store/globalMessages/duck';
-import { parseError } from '../../../helpers/request';
import RecentHistory from '../../../app/components/RecentHistory';
import { getProjectAdminProjectModules } from '../../../store/rootReducer';
@@ -55,29 +54,25 @@ class Key extends React.PureComponent {
this.props.fetchProjectModules(this.props.component.key);
}
- handleChangeKey(key, newKey) {
- return this.props
- .changeKey(key, newKey)
- .then(() => {
- if (key === this.props.component.key) {
- this.props.addGlobalSuccessMessage(translate('update_key.key_updated.reload'));
- RecentHistory.remove(key);
- reloadUpdateKeyPage(newKey);
- } else {
- this.props.addGlobalSuccessMessage(translate('update_key.key_updated'));
- }
- })
- .catch(e => {
- parseError(e).then(this.props.addGlobalErrorMessage);
- });
- }
+ handleChangeKey = (key, newKey) => {
+ return this.props.changeKey(key, newKey).then(() => {
+ if (key === this.props.component.key) {
+ this.props.addGlobalSuccessMessage(translate('update_key.key_updated.reload'));
+ RecentHistory.remove(key);
+ reloadUpdateKeyPage(newKey);
+ } else {
+ this.props.addGlobalSuccessMessage(translate('update_key.key_updated'));
+ }
+ });
+ };
- handleChangeTab(tab, e) {
- e.preventDefault();
- e.target.blur();
+ handleChangeTab = event => {
+ event.preventDefault();
+ event.currentTarget.blur();
+ const { tab } = event.currentTarget.dataset;
this.setState({ tab });
this.props.closeAllGlobalMessages();
- }
+ };
render() {
const { component, modules } = this.props;
@@ -88,7 +83,7 @@ class Key extends React.PureComponent {
const { tab } = this.state;
return (
- <div id="project-key" className="page page-limited">
+ <div className="page page-limited" id="project-key">
<Helmet title={translate('update_key.page')} />
<Header />
@@ -96,7 +91,7 @@ class Key extends React.PureComponent {
{noModules && (
<div>
- <UpdateForm component={component} onKeyChange={this.handleChangeKey.bind(this)} />
+ <UpdateForm component={component} onKeyChange={this.handleChangeKey} />
</div>
)}
@@ -106,19 +101,21 @@ class Key extends React.PureComponent {
<ul className="tabs">
<li>
<a
- id="update-key-tab-bulk"
className={tab === 'bulk' ? 'selected' : ''}
+ data-tab="bulk"
href="#"
- onClick={this.handleChangeTab.bind(this, 'bulk')}>
+ id="update-key-tab-bulk"
+ onClick={this.handleChangeTab}>
{translate('update_key.bulk_update')}
</a>
</li>
<li>
<a
- id="update-key-tab-fine"
className={tab === 'fine' ? 'selected' : ''}
+ data-tab="fine"
href="#"
- onClick={this.handleChangeTab.bind(this, 'fine')}>
+ id="update-key-tab-fine"
+ onClick={this.handleChangeTab}>
{translate('update_key.fine_grained_key_update')}
</a>
</li>
@@ -131,9 +128,9 @@ class Key extends React.PureComponent {
<FineGrainedUpdate
component={component}
modules={modules}
- onKeyChange={this.handleChangeKey.bind(this)}
- onSuccess={this.props.closeAllGlobalMessages}
onError={this.props.addGlobalErrorMessage}
+ onKeyChange={this.handleChangeKey}
+ onSuccess={this.props.closeAllGlobalMessages}
/>
)}
</div>
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js
deleted file mode 100644
index 54564f82c27..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 React from 'react';
-import PropTypes from 'prop-types';
-import UpdateKeyConfirmation from './views/UpdateKeyConfirmation';
-import { translate } from '../../../helpers/l10n';
-
-export default class UpdateForm extends React.PureComponent {
- static propTypes = {
- component: PropTypes.object.isRequired,
- onKeyChange: PropTypes.func.isRequired
- };
-
- state = { newKey: null };
-
- handleSubmit(e) {
- e.preventDefault();
-
- const newKey = this.refs.newKey.value;
-
- new UpdateKeyConfirmation({
- newKey,
- component: this.props.component,
- onChange: this.props.onKeyChange
- }).render();
- }
-
- handleChange(e) {
- const newKey = e.target.value;
- this.setState({ newKey });
- }
-
- handleReset(e) {
- e.preventDefault();
- this.setState({ newKey: null });
- }
-
- render() {
- const value = this.state.newKey != null ? this.state.newKey : this.props.component.key;
-
- const hasChanged = value !== this.props.component.key;
-
- return (
- <form onSubmit={this.handleSubmit.bind(this)}>
- <input
- ref="newKey"
- id="update-key-new-key"
- className="input-super-large"
- value={value}
- type="text"
- placeholder={translate('update_key.new_key')}
- required={true}
- onChange={this.handleChange.bind(this)}
- />
-
- <div className="spacer-top">
- <button id="update-key-submit" disabled={!hasChanged}>
- {translate('update_verb')}
- </button>{' '}
- <button
- id="update-key-reset"
- disabled={!hasChanged}
- onClick={this.handleReset.bind(this)}>
- {translate('reset_verb')}
- </button>
- </div>
- </form>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.tsx b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.tsx
new file mode 100644
index 00000000000..99dc58c1208
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.tsx
@@ -0,0 +1,85 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 UpdateKeyConfirm from './UpdateKeyConfirm';
+import { Button, SubmitButton } from '../../../components/ui/buttons';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+ component: { key: string; name: string };
+ onKeyChange: (oldKey: string, newKey: string) => Promise<void>;
+}
+
+interface State {
+ newKey?: string;
+}
+
+export default class UpdateForm extends React.PureComponent<Props, State> {
+ state: State = {};
+
+ handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+ const newKey = event.currentTarget.value;
+ this.setState({ newKey });
+ };
+
+ handleReset = () => {
+ this.setState({ newKey: undefined });
+ };
+
+ render() {
+ const { component } = this.props;
+ const { newKey } = this.state;
+ const value = newKey != null ? newKey : component.key;
+ const hasChanged = value !== component.key;
+
+ return (
+ <UpdateKeyConfirm component={component} newKey={newKey} onConfirm={this.props.onKeyChange}>
+ {({ onFormSubmit }) => (
+ <form onSubmit={onFormSubmit}>
+ <input
+ className="input-super-large"
+ id="update-key-new-key"
+ onChange={this.handleChange}
+ placeholder={translate('update_key.new_key')}
+ required={true}
+ type="text"
+ value={value}
+ />
+
+ <div className="spacer-top">
+ <SubmitButton disabled={!hasChanged} id="update-key-submit">
+ {translate('update_verb')}
+ </SubmitButton>
+
+ <Button
+ className="spacer-left"
+ disabled={!hasChanged}
+ id="update-key-reset"
+ onClick={this.handleReset}
+ type="reset">
+ {translate('reset_verb')}
+ </Button>
+ </div>
+ </form>
+ )}
+ </UpdateKeyConfirm>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyConfirm.tsx b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyConfirm.tsx
new file mode 100644
index 00000000000..6bb2bcc7990
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyConfirm.tsx
@@ -0,0 +1,65 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 ConfirmButton, { ChildrenProps } from '../../../components/controls/ConfirmButton';
+import { translate, translateWithParameters } from '../../../helpers/l10n';
+
+interface Props {
+ children: (props: ChildrenProps) => React.ReactNode;
+ component: { key: string; name: string };
+ newKey: string | undefined;
+ onConfirm: (oldKey: string, newKey: string) => Promise<void>;
+}
+
+export default class UpdateKeyConfirm extends React.PureComponent<Props> {
+ handleConfirm = () => {
+ return this.props.newKey
+ ? this.props.onConfirm(this.props.component.key, this.props.newKey)
+ : Promise.reject(undefined);
+ };
+
+ render() {
+ const { children, component, newKey } = this.props;
+
+ return (
+ <ConfirmButton
+ confirmButtonText={translate('update_verb')}
+ modalBody={
+ <>
+ {translateWithParameters('update_key.are_you_sure_to_change_key', component.name)}
+ <div className="spacer-top">
+ {translate('update_key.old_key')}
+ {': '}
+ <strong>{component.key}</strong>
+ </div>
+ <div className="spacer-top">
+ {translate('update_key.new_key')}
+ {': '}
+ <strong>{newKey}</strong>
+ </div>
+ </>
+ }
+ modalHeader={translate('update_key.page')}
+ onConfirm={this.handleConfirm}>
+ {children}
+ </ConfirmButton>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js
deleted file mode 100644
index 4f4cf8ec976..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 React from 'react';
-import PropTypes from 'prop-types';
-import UpdateKeyConfirmation from './views/UpdateKeyConfirmation';
-import { translate } from '../../../helpers/l10n';
-
-export default class UpdateKeyForm extends React.PureComponent {
- static propTypes = {
- component: PropTypes.object.isRequired
- };
-
- state = {};
-
- componentWillMount() {
- this.handleInputChange = this.handleInputChange.bind(this);
- this.handleUpdateClick = this.handleUpdateClick.bind(this);
- this.handleResetClick = this.handleResetClick.bind(this);
- }
-
- handleInputChange(e) {
- const key = e.target.value;
- this.setState({ key });
- }
-
- handleUpdateClick(e) {
- e.preventDefault();
- e.target.blur();
-
- const newKey = this.refs.newKey.value;
-
- new UpdateKeyConfirmation({
- newKey,
- component: this.props.component,
- onChange: this.props.onKeyChange
- }).render();
- }
-
- handleResetClick(e) {
- e.preventDefault();
- e.target.blur();
- this.setState({ key: null });
- }
-
- render() {
- const { component } = this.props;
-
- const value = this.state.key != null ? this.state.key : component.key;
-
- const hasChanged = this.state.key != null && this.state.key !== component.key;
-
- return (
- <div className="js-fine-grained-update" data-key={component.key}>
- <input
- ref="newKey"
- className="input-super-large big-spacer-right"
- type="text"
- value={value}
- onChange={this.handleInputChange}
- />
-
- <button disabled={!hasChanged} onClick={this.handleUpdateClick}>
- {translate('update_verb')}
- </button>
-
- <button className="spacer-left" disabled={!hasChanged} onClick={this.handleResetClick}>
- {translate('reset_verb')}
- </button>
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.tsx b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.tsx
new file mode 100644
index 00000000000..48345dfaaff
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.tsx
@@ -0,0 +1,75 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 UpdateKeyConfirm from './UpdateKeyConfirm';
+import { Button } from '../../../components/ui/buttons';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+ component: { key: string; name: string };
+ onKeyChange: (oldKey: string, newKey: string) => Promise<void>;
+}
+
+interface State {
+ newKey?: string;
+}
+
+export default class UpdateKeyForm extends React.PureComponent<Props, State> {
+ state: State = {};
+
+ handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+ const newKey = event.currentTarget.value;
+ this.setState({ newKey });
+ };
+
+ handleResetClick = () => {
+ this.setState({ newKey: undefined });
+ };
+
+ render() {
+ const { component } = this.props;
+ const { newKey } = this.state;
+ const value = newKey !== undefined ? newKey : component.key;
+ const hasChanged = newKey !== undefined && newKey !== component.key;
+
+ return (
+ <div className="js-fine-grained-update" data-key={component.key}>
+ <input
+ className="input-super-large big-spacer-right"
+ onChange={this.handleInputChange}
+ type="text"
+ value={value}
+ />
+
+ <UpdateKeyConfirm component={component} newKey={newKey} onConfirm={this.props.onKeyChange}>
+ {({ onClick }) => (
+ <Button disabled={!hasChanged} onClick={onClick}>
+ {translate('update_verb')}
+ </Button>
+ )}
+ </UpdateKeyConfirm>
+
+ <Button className="spacer-left" disabled={!hasChanged} onClick={this.handleResetClick}>
+ {translate('reset_verb')}
+ </Button>
+ </div>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.hbs b/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.hbs
deleted file mode 100644
index bec83b7693e..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.hbs
+++ /dev/null
@@ -1,30 +0,0 @@
-<form id="update-key-confirmation-form" autocomplete="off">
- <div class="modal-head">
- <h2>{{t 'update_key.page'}}</h2>
- </div>
- <div class="modal-body">
- <div class="js-modal-messages"></div>
- {{tp 'update_key.are_you_sure_to_change_key' component.name}}
- <div class="spacer-top">
- <div class="display-inline-block text-right" style="width: 80px;">
- {{t 'update_key.old_key'}}:
- </div>
- <div class="display-inline-block">
- {{component.key}}
- </div>
- </div>
- <div class="spacer-top">
- <div class="display-inline-block text-right" style="width: 80px;">
- {{t 'update_key.new_key'}}:
- </div>
- <div class="display-inline-block">
- {{newKey}}
- </div>
- </div>
- </div>
- <div class="modal-foot">
- <i class="js-modal-spinner spinner spacer-right hidden"></i>
- <button id="update-key-confirm">{{t 'update_verb'}}</button>
- <a href="#" class="js-modal-close">{{t 'cancel'}}</a>
- </div>
-</form>
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js b/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js
deleted file mode 100644
index afdc1ccf3d7..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 Template from './UpdateKeyConfirmation.hbs';
-import ModalForm from '../../../../components/common/modal-form';
-
-export default ModalForm.extend({
- template: Template,
-
- onFormSubmit() {
- ModalForm.prototype.onFormSubmit.apply(this, arguments);
- this.disableForm();
- this.showSpinner();
-
- this.options.onChange(this.options.component.key, this.options.newKey);
- this.destroy();
- },
-
- serializeData() {
- return {
- component: this.options.component,
- newKey: this.options.newKey
- };
- }
-});
diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/CreationModal.tsx b/server/sonar-web/src/main/js/apps/project-admin/links/CreationModal.tsx
new file mode 100644
index 00000000000..c87ae12e438
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-admin/links/CreationModal.tsx
@@ -0,0 +1,111 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 DeferredSpinner from '../../../components/common/DeferredSpinner';
+import SimpleModal from '../../../components/controls/SimpleModal';
+import { SubmitButton, ResetButtonLink } from '../../../components/ui/buttons';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+ onClose: () => void;
+ onSubmit: (name: string, url: string) => Promise<void>;
+}
+
+interface State {
+ name: string;
+ url: string;
+}
+
+export default class CreationModal extends React.PureComponent<Props, State> {
+ state: State = { name: '', url: '' };
+
+ handleSubmit = () => {
+ return this.props.onSubmit(this.state.name, this.state.url).then(this.props.onClose);
+ };
+
+ handleNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+ this.setState({ name: event.currentTarget.value });
+ };
+
+ handleUrlChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+ this.setState({ url: event.currentTarget.value });
+ };
+
+ render() {
+ const header = translate('project_links.create_new_project_link');
+
+ return (
+ <SimpleModal header={header} onClose={this.props.onClose} onSubmit={this.handleSubmit}>
+ {({ onCloseClick, onFormSubmit, submitting }) => (
+ <form onSubmit={onFormSubmit}>
+ <header className="modal-head">
+ <h2>{header}</h2>
+ </header>
+
+ <div className="modal-body">
+ <div className="modal-field">
+ <label htmlFor="create-link-name">
+ {translate('project_links.name')}
+ <em className="mandatory">*</em>
+ </label>
+ <input
+ autoFocus={true}
+ id="create-link-name"
+ maxLength={128}
+ name="name"
+ onChange={this.handleNameChange}
+ required={true}
+ type="text"
+ value={this.state.name}
+ />
+ </div>
+
+ <div className="modal-field">
+ <label htmlFor="create-link-url">
+ {translate('project_links.url')}
+ <em className="mandatory">*</em>
+ </label>
+ <input
+ id="create-link-url"
+ maxLength={128}
+ name="url"
+ onChange={this.handleUrlChange}
+ required={true}
+ type="text"
+ value={this.state.url}
+ />
+ </div>
+ </div>
+
+ <footer className="modal-foot">
+ <DeferredSpinner className="spacer-right" loading={submitting} />
+ <SubmitButton disabled={submitting} id="create-link-confirm">
+ {translate('create')}
+ </SubmitButton>
+ <ResetButtonLink disabled={submitting} onClick={onCloseClick}>
+ {translate('cancel')}
+ </ResetButtonLink>
+ </footer>
+ </form>
+ )}
+ </SimpleModal>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/Header.js b/server/sonar-web/src/main/js/apps/project-admin/links/Header.js
deleted file mode 100644
index 4ed55a4bb2d..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/links/Header.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 React from 'react';
-import PropTypes from 'prop-types';
-import CreationModal from './views/CreationModal';
-import { translate } from '../../../helpers/l10n';
-
-export default class Header extends React.PureComponent {
- static propTypes = {
- onCreate: PropTypes.func.isRequired
- };
-
- handleCreateClick(e) {
- e.preventDefault();
- e.target.blur();
- new CreationModal({
- onCreate: this.props.onCreate
- }).render();
- }
-
- render() {
- return (
- <header className="page-header">
- <h1 className="page-title">{translate('project_links.page')}</h1>
- <div className="page-actions">
- <button id="create-project-link" onClick={this.handleCreateClick.bind(this)}>
- {translate('create')}
- </button>
- </div>
- <div className="page-description">{translate('project_links.page.description')}</div>
- </header>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/Header.tsx b/server/sonar-web/src/main/js/apps/project-admin/links/Header.tsx
new file mode 100644
index 00000000000..b8e07c56fbb
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/project-admin/links/Header.tsx
@@ -0,0 +1,73 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 CreationModal from './CreationModal';
+import { Button } from '../../../components/ui/buttons';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+ onCreate: (name: string, url: string) => Promise<void>;
+}
+
+interface State {
+ creationModal: boolean;
+}
+
+export default class Header extends React.PureComponent<Props, State> {
+ mounted = false;
+ state: State = { creationModal: false };
+
+ componentDidMount() {
+ this.mounted = true;
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ handleCreateClick = () => {
+ this.setState({ creationModal: true });
+ };
+
+ handleCreationModalClose = () => {
+ if (this.mounted) {
+ this.setState({ creationModal: false });
+ }
+ };
+
+ render() {
+ return (
+ <>
+ <header className="page-header">
+ <h1 className="page-title">{translate('project_links.page')}</h1>
+ <div className="page-actions">
+ <Button id="create-project-link" onClick={this.handleCreateClick}>
+ {translate('create')}
+ </Button>
+ </div>
+ <div className="page-description">{translate('project_links.page.description')}</div>
+ </header>
+ {this.state.creationModal && (
+ <CreationModal onClose={this.handleCreationModalClose} onSubmit={this.props.onCreate} />
+ )}
+ </>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/LinkRow.js b/server/sonar-web/src/main/js/apps/project-admin/links/LinkRow.tsx
index 3124fb9c8af..74ea4df05ee 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/links/LinkRow.js
+++ b/server/sonar-web/src/main/js/apps/project-admin/links/LinkRow.tsx
@@ -17,25 +17,21 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import React from 'react';
-import PropTypes from 'prop-types';
+import * as React from 'react';
import { isProvided, getLinkName } from './utils';
-import { translate } from '../../../helpers/l10n';
+import { ProjectLink } from '../../../app/types';
+import ConfirmButton from '../../../components/controls/ConfirmButton';
import BugTrackerIcon from '../../../components/ui/BugTrackerIcon';
+import { Button } from '../../../components/ui/buttons';
+import { translate, translateWithParameters } from '../../../helpers/l10n';
-export default class LinkRow extends React.PureComponent {
- static propTypes = {
- link: PropTypes.object.isRequired,
- onDelete: PropTypes.func.isRequired
- };
-
- handleDeleteClick(e) {
- e.preventDefault();
- e.target.blur();
- this.props.onDelete();
- }
+interface Props {
+ link: ProjectLink;
+ onDelete: (linkId: string) => Promise<void>;
+}
- renderIcon(iconClassName) {
+export default class LinkRow extends React.PureComponent<Props> {
+ renderIcon = (iconClassName: string) => {
if (iconClassName === 'icon-issue') {
return (
<div className="display-inline-block text-top spacer-right">
@@ -49,9 +45,9 @@ export default class LinkRow extends React.PureComponent {
<i className={iconClassName} />
</div>
);
- }
+ };
- renderNameForProvided(link) {
+ renderNameForProvided = (link: ProjectLink) => {
return (
<div>
{this.renderIcon(`icon-${link.type}`)}
@@ -65,9 +61,9 @@ export default class LinkRow extends React.PureComponent {
</div>
</div>
);
- }
+ };
- renderName(link) {
+ renderName = (link: ProjectLink) => {
if (isProvided(link)) {
return this.renderNameForProvided(link);
}
@@ -80,19 +76,32 @@ export default class LinkRow extends React.PureComponent {
</div>
</div>
);
- }
+ };
- renderDeleteButton(link) {
+ renderDeleteButton = (link: ProjectLink) => {
if (isProvided(link)) {
return null;
}
return (
- <button className="button-red js-delete-button" onClick={this.handleDeleteClick.bind(this)}>
- {translate('delete')}
- </button>
+ <ConfirmButton
+ confirmButtonText={translate('delete')}
+ confirmData={link.id}
+ isDestructive={true}
+ modalBody={translateWithParameters(
+ 'project_links.are_you_sure_to_delete_x_link',
+ link.name
+ )}
+ modalHeader={translate('project_links.delete_project_link')}
+ onConfirm={this.props.onDelete}>
+ {({ onClick }) => (
+ <Button className="button-red js-delete-button" onClick={onClick}>
+ {translate('delete')}
+ </Button>
+ )}
+ </ConfirmButton>
);
- }
+ };
render() {
const { link } = this.props;
diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/Links.js b/server/sonar-web/src/main/js/apps/project-admin/links/Links.js
index e8a5318ba99..fa77e03c6b8 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/links/Links.js
+++ b/server/sonar-web/src/main/js/apps/project-admin/links/Links.js
@@ -23,7 +23,6 @@ import Helmet from 'react-helmet';
import { connect } from 'react-redux';
import Header from './Header';
import Table from './Table';
-import DeletionModal from './views/DeletionModal';
import { fetchProjectLinks, deleteProjectLink, createProjectLink } from '../store/actions';
import { getProjectAdminProjectLinks } from '../../../store/rootReducer';
import { translate } from '../../../helpers/l10n';
@@ -34,26 +33,17 @@ class Links extends React.PureComponent {
links: PropTypes.array
};
- componentWillMount() {
- this.handleCreateLink = this.handleCreateLink.bind(this);
- this.handleDeleteLink = this.handleDeleteLink.bind(this);
- }
-
componentDidMount() {
this.props.fetchProjectLinks(this.props.component.key);
}
- handleCreateLink(name, url) {
+ handleCreateLink = (name, url) => {
return this.props.createProjectLink(this.props.component.key, name, url);
- }
+ };
- handleDeleteLink(link) {
- new DeletionModal({ link })
- .on('done', () => {
- this.props.deleteProjectLink(this.props.component.key, link.id);
- })
- .render();
- }
+ handleDeleteLink = linkId => {
+ return this.props.deleteProjectLink(this.props.component.key, linkId);
+ };
render() {
return (
diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/Table.js b/server/sonar-web/src/main/js/apps/project-admin/links/Table.js
index ad5ea09f9ba..8c8c80788fb 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/links/Table.js
+++ b/server/sonar-web/src/main/js/apps/project-admin/links/Table.js
@@ -29,10 +29,6 @@ export default class Table extends React.PureComponent {
onDelete: PropTypes.func.isRequired
};
- handleDeleteLink(link) {
- this.props.onDelete(link);
- }
-
renderHeader() {
// keep empty cell for actions
return (
@@ -50,12 +46,12 @@ export default class Table extends React.PureComponent {
const orderedLinks = orderLinks(this.props.links);
const linkRows = orderedLinks.map(link => (
- <LinkRow key={link.id} link={link} onDelete={this.handleDeleteLink.bind(this, link)} />
+ <LinkRow key={link.id} link={link} onDelete={this.props.onDelete} />
));
return (
<div className="boxed-group boxed-group-inner">
- <table id="project-links" className="data zebra">
+ <table className="data zebra" id="project-links">
{this.renderHeader()}
<tbody>{linkRows}</tbody>
</table>
diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModal.js b/server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModal.js
deleted file mode 100644
index d00cb68e3be..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModal.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 Template from './CreationModalTemplate.hbs';
-import ModalForm from '../../../../components/common/modal-form';
-import { parseError } from '../../../../helpers/request';
-
-export default ModalForm.extend({
- template: Template,
-
- onFormSubmit() {
- ModalForm.prototype.onFormSubmit.apply(this, arguments);
- this.disableForm();
-
- const name = this.$('#create-link-name').val();
- const url = this.$('#create-link-url').val();
-
- this.options
- .onCreate(name, url)
- .then(() => this.destroy())
- .catch(e => {
- parseError(e).then(msg => this.showSingleError(msg));
- this.enableForm();
- });
- }
-});
diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModalTemplate.hbs b/server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModalTemplate.hbs
deleted file mode 100644
index 6d7f25084b5..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModalTemplate.hbs
+++ /dev/null
@@ -1,22 +0,0 @@
-<form>
- <div class="modal-head">
- <h2>{{t 'project_links.create_new_project_link'}}</h2>
- </div>
- <div class="modal-body">
- <div class="js-modal-messages"></div>
-
- <div class="modal-field">
- <label for="create-link-name">{{t 'project_links.name'}}<em class="mandatory">*</em></label>
- <input id="create-link-name" name="name" type="text" maxlength="128" required>
- </div>
-
- <div class="modal-field">
- <label for="create-link-url">{{t 'project_links.url'}}<em class="mandatory">*</em></label>
- <input id="create-link-url" name="url" type="text" maxlength="2048" required>
- </div>
- </div>
- <div class="modal-foot">
- <button id="create-link-confirm">{{t 'create'}}</button>
- <a href="#" class="js-modal-close">{{t 'cancel'}}</a>
- </div>
-</form>
diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModal.js b/server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModal.js
deleted file mode 100644
index 7b12ab08d84..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModal.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 Template from './DeletionModalTemplate.hbs';
-import ModalForm from '../../../../components/common/modal-form';
-import { deleteLink } from '../../../../api/projectLinks';
-import { parseError } from '../../../../helpers/request';
-
-export default ModalForm.extend({
- template: Template,
-
- onFormSubmit() {
- ModalForm.prototype.onFormSubmit.apply(this, arguments);
- this.disableForm();
-
- deleteLink(this.options.link.id)
- .then(() => {
- this.trigger('done');
- this.destroy();
- })
- .catch(e => {
- parseError(e).then(msg => this.showSingleError(msg));
- this.enableForm();
- });
- },
-
- serializeData() {
- return { link: this.options.link };
- }
-});
diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModalTemplate.hbs b/server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModalTemplate.hbs
deleted file mode 100644
index b8d744c83d9..00000000000
--- a/server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModalTemplate.hbs
+++ /dev/null
@@ -1,13 +0,0 @@
-<form>
- <div class="modal-head">
- <h2>{{t 'project_links.delete_project_link'}}</h2>
- </div>
- <div class="modal-body">
- <div class="js-modal-messages"></div>
- {{tp 'project_links.are_you_sure_to_delete_x_link' link.name}}
- </div>
- <div class="modal-foot">
- <button id="delete-link-confirm" class="button-red">{{t 'delete'}}</button>
- <a href="#" class="js-modal-close">{{t 'cancel'}}</a>
- </div>
-</form>
diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/actions.js b/server/sonar-web/src/main/js/apps/project-admin/store/actions.js
index 11c64002edc..189832011e1 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/store/actions.js
+++ b/server/sonar-web/src/main/js/apps/project-admin/store/actions.js
@@ -17,8 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { getProjectLinks, createLink } from '../../../api/projectLinks';
+import { getProjectLinks, createLink, deleteLink } from '../../../api/projectLinks';
import { getTree, changeKey as changeKeyApi } from '../../../api/components';
+import throwGlobalError from '../../../app/utils/throwGlobalError';
export const RECEIVE_PROJECT_LINKS = 'projectAdmin/RECEIVE_PROJECT_LINKS';
export const receiveProjectLinks = (projectKey, links) => ({
@@ -28,9 +29,12 @@ export const receiveProjectLinks = (projectKey, links) => ({
});
export const fetchProjectLinks = projectKey => dispatch => {
- getProjectLinks(projectKey).then(links => {
- dispatch(receiveProjectLinks(projectKey, links));
- });
+ getProjectLinks(projectKey).then(
+ links => {
+ dispatch(receiveProjectLinks(projectKey, links));
+ },
+ () => {}
+ );
};
export const ADD_PROJECT_LINK = 'projectAdmin/ADD_PROJECT_LINK';
@@ -47,12 +51,19 @@ export const createProjectLink = (projectKey, name, url) => dispatch => {
};
export const DELETE_PROJECT_LINK = 'projectAdmin/DELETE_PROJECT_LINK';
-export const deleteProjectLink = (projectKey, linkId) => ({
+export const deleteProjectLinkAction = (projectKey, linkId) => ({
type: DELETE_PROJECT_LINK,
projectKey,
linkId
});
+export function deleteProjectLink(projectKey, linkId) {
+ return dispatch =>
+ deleteLink(linkId).then(() => {
+ dispatch(deleteProjectLinkAction(projectKey, linkId));
+ });
+}
+
export const RECEIVE_PROJECT_MODULES = 'projectAdmin/RECEIVE_PROJECT_MODULES';
const receiveProjectModules = (projectKey, modules) => ({
type: RECEIVE_PROJECT_MODULES,
@@ -62,9 +73,12 @@ const receiveProjectModules = (projectKey, modules) => ({
export const fetchProjectModules = projectKey => dispatch => {
const options = { qualifiers: 'BRC', s: 'name', ps: 500 };
- getTree(projectKey, options).then(r => {
- dispatch(receiveProjectModules(projectKey, r.components));
- });
+ getTree(projectKey, options).then(
+ r => {
+ dispatch(receiveProjectModules(projectKey, r.components));
+ },
+ () => {}
+ );
};
export const CHANGE_KEY = 'projectAdmin/CHANGE_KEY';
@@ -75,5 +89,8 @@ const changeKeyAction = (key, newKey) => ({
});
export const changeKey = (key, newKey) => dispatch => {
- return changeKeyApi(key, newKey).then(() => dispatch(changeKeyAction(key, newKey)));
+ return changeKeyApi(key, newKey).then(
+ () => dispatch(changeKeyAction(key, newKey)),
+ throwGlobalError
+ );
};
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js
index de38009e128..09d8baf401d 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js
@@ -18,44 +18,55 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
-import ProjectsView from '../views/gate-projects-view';
+import escapeHtml from 'escape-html';
+import SelectList from '../../../components/SelectList';
+import { translate } from '../../../helpers/l10n';
+import { getBaseUrl } from '../../../helpers/urls';
export default class Projects extends React.PureComponent {
componentDidMount() {
- this.renderView();
+ this.renderSelectList();
}
- componentWillUpdate() {
- this.destroyView();
- }
-
- componentDidUpdate() {
- this.renderView();
- }
+ renderSelectList = () => {
+ if (!this.container) return;
- componentWillUnmount() {
- this.destroyView();
- }
+ const { qualityGate, edit, organization } = this.props;
- destroyView() {
- if (this.projectsView) {
- this.projectsView.destroy();
+ const extra = { gateId: qualityGate.id };
+ let orgQuery = '';
+ if (organization) {
+ extra.organization = organization;
+ orgQuery = '&organization=' + organization;
}
- }
-
- renderView() {
- const { qualityGate, edit, organization } = this.props;
- this.projectsView = new ProjectsView({
- qualityGate,
- edit,
- container: this.refs.container,
- organization
+ // eslint-disable-next-line no-new
+ new SelectList({
+ el: this.container,
+ width: '100%',
+ readOnly: !edit,
+ focusSearch: false,
+ dangerouslyUnescapedHtmlFormat: item => escapeHtml(item.name),
+ searchUrl: getBaseUrl() + `/api/qualitygates/search?gateId=${qualityGate.id}${orgQuery}`,
+ selectUrl: getBaseUrl() + '/api/qualitygates/select',
+ deselectUrl: getBaseUrl() + '/api/qualitygates/deselect',
+ extra,
+ selectParameter: 'projectId',
+ selectParameterValue: 'id',
+ labels: {
+ selected: translate('quality_gates.projects.with'),
+ deselected: translate('quality_gates.projects.without'),
+ all: translate('quality_gates.projects.all'),
+ noResults: translate('quality_gates.projects.noResults')
+ },
+ tooltips: {
+ select: translate('quality_gates.projects.select_hint'),
+ deselect: translate('quality_gates.projects.deselect_hint')
+ }
});
- this.projectsView.render();
- }
+ };
render() {
- return <div ref="container" />;
+ return <div ref={node => (this.container = node)} />;
}
}
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js b/server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js
deleted file mode 100644
index 85ab920f067..00000000000
--- a/server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 Marionette from 'backbone.marionette';
-import escapeHtml from 'escape-html';
-import SelectList from '../../../components/SelectList';
-import { translate } from '../../../helpers/l10n';
-
-export default Marionette.ItemView.extend({
- template: () => {},
-
- onRender() {
- const { qualityGate, organization } = this.options;
-
- const extra = {
- gateId: qualityGate.id
- };
- let orgQuery = '';
- if (organization) {
- extra.organization = organization;
- orgQuery = '&organization=' + organization;
- }
-
- new SelectList({
- el: this.options.container,
- width: '100%',
- readOnly: !this.options.edit,
- focusSearch: false,
- dangerouslyUnescapedHtmlFormat(item) {
- return escapeHtml(item.name);
- },
- searchUrl: `${window.baseUrl}/api/qualitygates/search?gateId=${qualityGate.id}${orgQuery}`,
- selectUrl: window.baseUrl + '/api/qualitygates/select',
- deselectUrl: window.baseUrl + '/api/qualitygates/deselect',
- extra,
- selectParameter: 'projectId',
- selectParameterValue: 'id',
- labels: {
- selected: translate('quality_gates.projects.with'),
- deselected: translate('quality_gates.projects.without'),
- all: translate('quality_gates.projects.all'),
- noResults: translate('quality_gates.projects.noResults')
- },
- tooltips: {
- select: translate('quality_gates.projects.select_hint'),
- deselect: translate('quality_gates.projects.deselect_hint')
- }
- });
- },
-
- serializeData() {
- return {
- ...Marionette.ItemView.prototype.serializeData.apply(this, arguments),
- canEdit: this.options.edit
- };
- }
-});
diff --git a/server/sonar-web/src/main/js/components/RestartModal/index.js b/server/sonar-web/src/main/js/components/RestartModal/index.js
deleted file mode 100644
index c3d3f2669a4..00000000000
--- a/server/sonar-web/src/main/js/components/RestartModal/index.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 Template from './templates/template.hbs';
-import RestartingTemplate from './templates/restarting.hbs';
-import ModalForm from '../common/modal-form';
-import { restartAndWait } from '../../api/system';
-
-const RestartModal = ModalForm.extend({
- template: Template,
- restartingTemplate: RestartingTemplate,
-
- initialize() {
- this.restarting = false;
- },
-
- getTemplate() {
- return this.restarting ? this.restartingTemplate : this.template;
- },
-
- onFormSubmit() {
- ModalForm.prototype.onFormSubmit.apply(this, arguments);
- this.restarting = true;
- this.render();
- restartAndWait().then(() => {
- document.location.reload();
- });
- }
-});
-
-export default RestartModal;
diff --git a/server/sonar-web/src/main/js/components/RestartModal/templates/restarting.hbs b/server/sonar-web/src/main/js/components/RestartModal/templates/restarting.hbs
deleted file mode 100644
index bab7b505ab7..00000000000
--- a/server/sonar-web/src/main/js/components/RestartModal/templates/restarting.hbs
+++ /dev/null
@@ -1,14 +0,0 @@
-<form id="restart-server-form">
- <div class="modal-head">
- <h2>Restart Server</h2>
- </div>
- <div class="modal-body">
- <div class="js-modal-messages"></div>
- <p class="spacer-top spacer-bottom text-center">
- Server is restarting. This page will be automatically refreshed.
- </p>
- <p class="big-spacer-top spacer-bottom text-center">
- <i class="spinner"></i>
- </p>
- </div>
-</form>
diff --git a/server/sonar-web/src/main/js/components/RestartModal/templates/template.hbs b/server/sonar-web/src/main/js/components/RestartModal/templates/template.hbs
deleted file mode 100644
index 6058532191c..00000000000
--- a/server/sonar-web/src/main/js/components/RestartModal/templates/template.hbs
+++ /dev/null
@@ -1,15 +0,0 @@
-<form id="restart-server-form">
- <div class="modal-head">
- <h2>Restart Server</h2>
- </div>
- <div class="modal-body">
- <div class="js-modal-messages"></div>
- <p class="spacer-top spacer-bottom">
- Are you sure you want to restart the server?
- </p>
- </div>
- <div class="modal-foot">
- <button id="restart-server-submit">Restart</button>
- <a href="#" class="js-modal-close" id="restart-server-cancel">Cancel</a>
- </div>
-</form>
diff --git a/server/sonar-web/src/main/js/components/common/modal-form.js b/server/sonar-web/src/main/js/components/common/modal-form.js
deleted file mode 100644
index b201fbf7f1f..00000000000
--- a/server/sonar-web/src/main/js/components/common/modal-form.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 ModalView from './modals';
-
-export default ModalView.extend({
- ui() {
- return {
- messagesContainer: '.js-modal-messages'
- };
- },
-
- events() {
- return {
- ...ModalView.prototype.events.apply(this, arguments),
- 'keydown input,textarea,select': 'onInputKeydown',
- 'submit form': 'onFormSubmit'
- };
- },
-
- onRender() {
- ModalView.prototype.onRender.apply(this, arguments);
- const that = this;
- setTimeout(() => {
- that
- .$(':tabbable')
- .first()
- .focus();
- }, 0);
- },
-
- onInputKeydown(e) {
- if (e.keyCode === 27) {
- // escape
- this.destroy();
- }
- },
-
- onFormSubmit(e) {
- e.preventDefault();
- },
-
- showErrors(errors, warnings) {
- const container = this.ui.messagesContainer.empty();
- if (Array.isArray(errors)) {
- errors.forEach(error => {
- const html = `<div class="alert alert-danger">${error.msg}</div>`;
- container.append(html);
- });
- }
- if (Array.isArray(warnings)) {
- warnings.forEach(warn => {
- const html = `<div class="alert alert-warning">${warn.msg}</div>`;
- container.append(html);
- });
- }
- this.ui.messagesContainer.scrollParent().scrollTop(0);
- },
-
- showSingleError(msg) {
- this.showErrors([{ msg }], []);
- },
-
- disableForm() {
- const form = this.$('form');
- this.disabledFields = form.find(':input:not(:disabled)');
- this.disabledFields.prop('disabled', true);
- },
-
- enableForm() {
- if (this.disabledFields != null) {
- this.disabledFields.prop('disabled', false);
- }
- },
-
- showSpinner() {
- this.$('.js-modal-spinner').removeClass('hidden');
- },
-
- hideSpinner() {
- this.$('.js-modal-spinner').addClass('hidden');
- }
-});
diff --git a/server/sonar-web/src/main/js/components/common/modals.js b/server/sonar-web/src/main/js/components/common/modals.js
deleted file mode 100644
index 6251b772ed0..00000000000
--- a/server/sonar-web/src/main/js/components/common/modals.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 $ from 'jquery';
-import Marionette from 'backbone.marionette';
-import key from 'keymaster';
-
-const EVENT_SCOPE = 'modal';
-
-export default Marionette.ItemView.extend({
- className: 'modal',
- overlayClassName: 'modal-overlay',
- htmlClassName: 'modal-open',
-
- events() {
- return {
- 'click .js-modal-close': 'onCloseClick'
- };
- },
-
- onRender() {
- const that = this;
- this.$el.detach().appendTo($('body'));
- $('html').addClass(this.htmlClassName);
- this.renderOverlay();
- this.keyScope = key.getScope();
- key.setScope('modal');
- key('escape', 'modal', () => {
- that.destroy();
- return false;
- });
- this.show();
- if (this.options.large) {
- this.$el.addClass('modal-large');
- }
- },
-
- show() {
- const that = this;
- setTimeout(() => {
- that.$el.addClass('in');
- $('.' + that.overlayClassName).addClass('in');
- }, 0);
- },
-
- onDestroy() {
- $('html').removeClass(this.htmlClassName);
- this.removeOverlay();
- key.deleteScope('modal');
- key.setScope(this.keyScope);
- },
-
- onCloseClick(e) {
- e.preventDefault();
- this.destroy();
- },
-
- renderOverlay() {
- const overlay = $('.' + this.overlayClassName);
- if (overlay.length === 0) {
- $(`<div class="${this.overlayClassName}"></div>`).appendTo($('body'));
- }
- },
-
- removeOverlay() {
- $('.' + this.overlayClassName).remove();
- },
-
- attachCloseEvents() {
- const that = this;
- $('body').on('click.' + EVENT_SCOPE, () => {
- $('body').off('click.' + EVENT_SCOPE);
- that.destroy();
- });
- }
-});
diff --git a/server/sonar-web/src/main/js/components/common/selectable-collection-view.js b/server/sonar-web/src/main/js/components/common/selectable-collection-view.js
deleted file mode 100644
index 41ce5d2f13b..00000000000
--- a/server/sonar-web/src/main/js/components/common/selectable-collection-view.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 Marionette from 'backbone.marionette';
-
-export default Marionette.CollectionView.extend({
- initialize() {
- this.resetSelectedIndex();
- this.listenTo(this.collection, 'reset', this.resetSelectedIndex);
- },
-
- childViewOptions(model, index) {
- return { index };
- },
-
- resetSelectedIndex() {
- this.selectedIndex = 0;
- },
-
- onRender() {
- this.selectCurrent();
- },
-
- submitCurrent() {
- const view = this.children.findByIndex(this.selectedIndex);
- if (view != null) {
- view.submit();
- }
- },
-
- selectCurrent() {
- this.selectItem(this.selectedIndex);
- },
-
- selectNext() {
- if (this.selectedIndex < this.collection.length - 1) {
- this.deselectItem(this.selectedIndex);
- this.selectedIndex++;
- this.selectItem(this.selectedIndex);
- }
- },
-
- selectPrev() {
- if (this.selectedIndex > 0) {
- this.deselectItem(this.selectedIndex);
- this.selectedIndex--;
- this.selectItem(this.selectedIndex);
- }
- },
-
- selectItem(index) {
- if (index >= 0 && index < this.collection.length) {
- const view = this.children.findByIndex(index);
- if (view != null) {
- view.select();
- }
- }
- },
-
- deselectItem(index) {
- const view = this.children.findByIndex(index);
- if (view != null) {
- view.deselect();
- }
- }
-});
diff --git a/server/sonar-web/src/main/js/components/controls/ConfirmButton.tsx b/server/sonar-web/src/main/js/components/controls/ConfirmButton.tsx
index 0f05db2ac90..ab766a9eed6 100644
--- a/server/sonar-web/src/main/js/components/controls/ConfirmButton.tsx
+++ b/server/sonar-web/src/main/js/components/controls/ConfirmButton.tsx
@@ -23,8 +23,13 @@ import DeferredSpinner from '../common/DeferredSpinner';
import { translate } from '../../helpers/l10n';
import { SubmitButton, ResetButtonLink } from '../ui/buttons';
+export interface ChildrenProps {
+ onClick: () => void;
+ onFormSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
+}
+
interface Props {
- children: (props: { onClick: () => void }) => React.ReactNode;
+ children: (props: ChildrenProps) => React.ReactNode;
confirmButtonText: string;
confirmData?: string;
isDestructive?: boolean;
@@ -53,6 +58,13 @@ export default class ConfirmButton extends React.PureComponent<Props, State> {
this.setState({ modal: true });
};
+ handleFormSubmit = (event?: React.FormEvent<HTMLFormElement>) => {
+ if (event) {
+ event.preventDefault();
+ }
+ this.setState({ modal: true });
+ };
+
handleSubmit = () => {
const result = this.props.onConfirm(this.props.confirmData);
if (result) {
@@ -74,7 +86,10 @@ export default class ConfirmButton extends React.PureComponent<Props, State> {
return (
<>
- {this.props.children({ onClick: this.handleButtonClick })}
+ {this.props.children({
+ onClick: this.handleButtonClick,
+ onFormSubmit: this.handleFormSubmit
+ })}
{this.state.modal && (
<SimpleModal
header={modalHeader}