Migrate BugReportDialog to TypeScript

pull/21833/head
Germain Souquet 2021-06-14 21:23:28 +01:00
parent f2250af565
commit be92226448
1 changed files with 49 additions and 47 deletions

View File

@ -18,7 +18,6 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import * as sdk from '../../../index'; import * as sdk from '../../../index';
import SdkConfig from '../../../SdkConfig'; import SdkConfig from '../../../SdkConfig';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
@ -27,8 +26,27 @@ import sendBugReport, {downloadBugReport} from '../../../rageshake/submit-ragesh
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton from "../elements/AccessibleButton";
import {replaceableComponent} from "../../../utils/replaceableComponent"; import {replaceableComponent} from "../../../utils/replaceableComponent";
interface IProps {
onFinished: (success: boolean) => void;
initialText?: string;
label?: string;
}
interface IState {
sendLogs: boolean;
busy: boolean;
err: string;
issueUrl: string;
text: string;
progress: string;
downloadBusy: boolean;
downloadProgress: string;
}
@replaceableComponent("views.dialogs.BugReportDialog") @replaceableComponent("views.dialogs.BugReportDialog")
export default class BugReportDialog extends React.Component { export default class BugReportDialog extends React.Component<IProps, IState> {
private unmounted: boolean;
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
@ -41,25 +59,18 @@ export default class BugReportDialog extends React.Component {
downloadBusy: false, downloadBusy: false,
downloadProgress: null, downloadProgress: null,
}; };
this._unmounted = false; this.unmounted = false;
this._onSubmit = this._onSubmit.bind(this);
this._onCancel = this._onCancel.bind(this);
this._onTextChange = this._onTextChange.bind(this);
this._onIssueUrlChange = this._onIssueUrlChange.bind(this);
this._onSendLogsChange = this._onSendLogsChange.bind(this);
this._sendProgressCallback = this._sendProgressCallback.bind(this);
this._downloadProgressCallback = this._downloadProgressCallback.bind(this);
} }
componentWillUnmount() { public componentWillUnmount() {
this._unmounted = true; this.unmounted = true;
} }
_onCancel(ev) { private onCancel = (): void => {
this.props.onFinished(false); this.props.onFinished(false);
} }
_onSubmit(ev) { private onSubmit = (): void => {
if ((!this.state.text || !this.state.text.trim()) && (!this.state.issueUrl || !this.state.issueUrl.trim())) { if ((!this.state.text || !this.state.text.trim()) && (!this.state.issueUrl || !this.state.issueUrl.trim())) {
this.setState({ this.setState({
err: _t("Please tell us what went wrong or, better, create a GitHub issue that describes the problem."), err: _t("Please tell us what went wrong or, better, create a GitHub issue that describes the problem."),
@ -72,15 +83,15 @@ export default class BugReportDialog extends React.Component {
(this.state.issueUrl.length > 0 ? this.state.issueUrl : 'No issue link given'); (this.state.issueUrl.length > 0 ? this.state.issueUrl : 'No issue link given');
this.setState({ busy: true, progress: null, err: null }); this.setState({ busy: true, progress: null, err: null });
this._sendProgressCallback(_t("Preparing to send logs")); this.sendProgressCallback(_t("Preparing to send logs"));
sendBugReport(SdkConfig.get().bug_report_endpoint_url, { sendBugReport(SdkConfig.get().bug_report_endpoint_url, {
userText, userText,
sendLogs: true, sendLogs: true,
progressCallback: this._sendProgressCallback, progressCallback: this.sendProgressCallback,
label: this.props.label, label: this.props.label,
}).then(() => { }).then(() => {
if (!this._unmounted) { if (!this.unmounted) {
this.props.onFinished(false); this.props.onFinished(false);
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
// N.B. first param is passed to piwik and so doesn't want i18n // N.B. first param is passed to piwik and so doesn't want i18n
@ -91,7 +102,7 @@ export default class BugReportDialog extends React.Component {
}); });
} }
}, (err) => { }, (err) => {
if (!this._unmounted) { if (!this.unmounted) {
this.setState({ this.setState({
busy: false, busy: false,
progress: null, progress: null,
@ -101,14 +112,14 @@ export default class BugReportDialog extends React.Component {
}); });
} }
_onDownload = async (ev) => { private onDownload = async (): Promise<void> => {
this.setState({ downloadBusy: true }); this.setState({ downloadBusy: true });
this._downloadProgressCallback(_t("Preparing to download logs")); this.downloadProgressCallback(_t("Preparing to download logs"));
try { try {
await downloadBugReport({ await downloadBugReport({
sendLogs: true, sendLogs: true,
progressCallback: this._downloadProgressCallback, progressCallback: this.downloadProgressCallback,
label: this.props.label, label: this.props.label,
}); });
@ -117,7 +128,7 @@ export default class BugReportDialog extends React.Component {
downloadProgress: null, downloadProgress: null,
}); });
} catch (err) { } catch (err) {
if (!this._unmounted) { if (!this.unmounted) {
this.setState({ this.setState({
downloadBusy: false, downloadBusy: false,
downloadProgress: _t("Failed to send logs: ") + `${err.message}`, downloadProgress: _t("Failed to send logs: ") + `${err.message}`,
@ -126,33 +137,29 @@ export default class BugReportDialog extends React.Component {
} }
}; };
_onTextChange(ev) { private onTextChange = (ev: React.FormEvent<HTMLTextAreaElement>): void => {
this.setState({ text: ev.target.value }); this.setState({ text: ev.currentTarget.value });
} }
_onIssueUrlChange(ev) { private onIssueUrlChange = (ev: React.FormEvent<HTMLInputElement>): void => {
this.setState({ issueUrl: ev.target.value }); this.setState({ issueUrl: ev.currentTarget.value });
} }
_onSendLogsChange(ev) { private sendProgressCallback = (progress: string): void => {
this.setState({ sendLogs: ev.target.checked }); if (this.unmounted) {
}
_sendProgressCallback(progress) {
if (this._unmounted) {
return; return;
} }
this.setState({progress: progress}); this.setState({ progress });
} }
_downloadProgressCallback(downloadProgress) { private downloadProgressCallback = (downloadProgress: string): void => {
if (this._unmounted) { if (this.unmounted) {
return; return;
} }
this.setState({ downloadProgress }); this.setState({ downloadProgress });
} }
render() { public render() {
const Loader = sdk.getComponent("elements.Spinner"); const Loader = sdk.getComponent("elements.Spinner");
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
@ -183,7 +190,7 @@ export default class BugReportDialog extends React.Component {
} }
return ( return (
<BaseDialog className="mx_BugReportDialog" onFinished={this._onCancel} <BaseDialog className="mx_BugReportDialog" onFinished={this.onCancel}
title={_t('Submit debug logs')} title={_t('Submit debug logs')}
contentId='mx_Dialog_content' contentId='mx_Dialog_content'
> >
@ -213,7 +220,7 @@ export default class BugReportDialog extends React.Component {
</b></p> </b></p>
<div className="mx_BugReportDialog_download"> <div className="mx_BugReportDialog_download">
<AccessibleButton onClick={this._onDownload} kind="link" disabled={this.state.downloadBusy}> <AccessibleButton onClick={this.onDownload} kind="link" disabled={this.state.downloadBusy}>
{ _t("Download logs") } { _t("Download logs") }
</AccessibleButton> </AccessibleButton>
{this.state.downloadProgress && <span>{this.state.downloadProgress} ...</span>} {this.state.downloadProgress && <span>{this.state.downloadProgress} ...</span>}
@ -223,7 +230,7 @@ export default class BugReportDialog extends React.Component {
type="text" type="text"
className="mx_BugReportDialog_field_input" className="mx_BugReportDialog_field_input"
label={_t("GitHub issue")} label={_t("GitHub issue")}
onChange={this._onIssueUrlChange} onChange={this.onIssueUrlChange}
value={this.state.issueUrl} value={this.state.issueUrl}
placeholder="https://github.com/vector-im/element-web/issues/..." placeholder="https://github.com/vector-im/element-web/issues/..."
/> />
@ -232,7 +239,7 @@ export default class BugReportDialog extends React.Component {
element="textarea" element="textarea"
label={_t("Notes")} label={_t("Notes")}
rows={5} rows={5}
onChange={this._onTextChange} onChange={this.onTextChange}
value={this.state.text} value={this.state.text}
placeholder={_t( placeholder={_t(
"If there is additional context that would help in " + "If there is additional context that would help in " +
@ -245,17 +252,12 @@ export default class BugReportDialog extends React.Component {
{error} {error}
</div> </div>
<DialogButtons primaryButton={_t("Send logs")} <DialogButtons primaryButton={_t("Send logs")}
onPrimaryButtonClick={this._onSubmit} onPrimaryButtonClick={this.onSubmit}
focus={true} focus={true}
onCancel={this._onCancel} onCancel={this.onCancel}
disabled={this.state.busy} disabled={this.state.busy}
/> />
</BaseDialog> </BaseDialog>
); );
} }
} }
BugReportDialog.propTypes = {
onFinished: PropTypes.func.isRequired,
initialText: PropTypes.string,
};