From ffd61bd2c9a7c503fabaf08552d14b3ff3855a6a Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Tue, 26 Jun 2018 16:51:47 -0300 Subject: [PATCH 01/20] [DDW-248] Refactor compress/download logs handling --- .../containers/profile/dialogs/BugReportDialogContainer.js | 5 +++-- .../containers/settings/categories/SupportSettingsPage.js | 3 ++- source/renderer/app/utils/fileName.js | 5 +++++ 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 source/renderer/app/utils/fileName.js diff --git a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js index 78f7b106bb..aa58dc7036 100644 --- a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js +++ b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js @@ -5,6 +5,7 @@ import { get } from 'lodash'; import { observer, inject } from 'mobx-react'; import BugReportDialog from '../../../components/profile/bug-report/BugReportDialog'; import type { InjectedProps } from '../../../types/injectedPropsType'; +import { logWithTimestamp } from '../../../utils/fileName'; const shell = require('electron').shell; @@ -21,9 +22,9 @@ export default class BugReportDialogContainer extends Component { onDownload = () => { const destination = remote.dialog.showSaveDialog({ - defaultPath: 'logs.zip', + defaultPath: logWithTimestamp(), }); - if (destination) this.props.actions.profile.downloadLogs.trigger({ destination }); + if (destination) this.props.actions.profile.downloadLogs.trigger({ destination, fresh: true }); }; onSubmitManually = (link: string) => { diff --git a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js index bb699c2713..dc0f2a8f5f 100644 --- a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js +++ b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js @@ -5,6 +5,7 @@ import { remote } from 'electron'; import SupportSettings from '../../../components/settings/categories/SupportSettings'; import type { InjectedProps } from '../../../types/injectedPropsType'; import BugReportDialog from '../../../components/profile/bug-report/BugReportDialog'; +import { logWithTimestamp } from '../../../utils/fileName'; const shell = require('electron').shell; @@ -26,7 +27,7 @@ export default class SupportSettingsPage extends Component { handleDownloadLogs = () => { const destination = remote.dialog.showSaveDialog({ - defaultPath: 'logs.zip', + defaultPath: logWithTimestamp(), }); if (destination) this.props.actions.profile.downloadLogs.trigger({ destination, fresh: true }); }; diff --git a/source/renderer/app/utils/fileName.js b/source/renderer/app/utils/fileName.js new file mode 100644 index 0000000000..eceb7b6504 --- /dev/null +++ b/source/renderer/app/utils/fileName.js @@ -0,0 +1,5 @@ +// @flow +import moment from 'moment'; + +export const logWithTimestamp = (prefix: string = 'logs', filetype: string = 'zip') => + `${prefix}-${moment().format('YYYY-MM-DDTHHMMSS')}.${filetype}`; From 3f4af8c9a5b1f51b0fb5156b25be0018546687cc Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Wed, 27 Jun 2018 11:15:11 -0300 Subject: [PATCH 02/20] [DDW-248] Saving with the same timestamp --- source/main/ipc-api/compress-logs.js | 3 +-- source/renderer/app/actions/profile-actions.js | 2 +- .../profile/dialogs/BugReportDialogContainer.js | 7 ++++--- .../settings/categories/SupportSettingsPage.js | 7 ++++--- source/renderer/app/stores/ProfileStore.js | 10 ++++++---- source/renderer/app/utils/fileName.js | 5 ++--- 6 files changed, 18 insertions(+), 16 deletions(-) diff --git a/source/main/ipc-api/compress-logs.js b/source/main/ipc-api/compress-logs.js index d36a5236c0..cfa2cc5110 100644 --- a/source/main/ipc-api/compress-logs.js +++ b/source/main/ipc-api/compress-logs.js @@ -9,9 +9,8 @@ import { Logger, stringifyError } from '../../common/logging'; import { COMPRESS_LOGS } from '../../common/ipc-api'; export default () => { - ipcMain.on(COMPRESS_LOGS.REQUEST, (event, logs) => { + ipcMain.on(COMPRESS_LOGS.REQUEST, (event, logs, compressedFileName) => { const sender = event.sender; - const compressedFileName = 'logs.zip'; const outputPath = path.join(appLogsFolderPath, compressedFileName); const output = fs.createWriteStream(outputPath); diff --git a/source/renderer/app/actions/profile-actions.js b/source/renderer/app/actions/profile-actions.js index ca8e53fd3a..eddf55c617 100644 --- a/source/renderer/app/actions/profile-actions.js +++ b/source/renderer/app/actions/profile-actions.js @@ -7,7 +7,7 @@ export default class ProfileActions { acceptTermsOfUse: Action = new Action(); compressLogs: Action<{ logs: Object }> = new Action(); getLogs: Action = new Action(); - downloadLogs: Action<{ destination: string, fresh?: boolean }> = new Action(); + downloadLogs: Action<{ fileName: string, destination: string, fresh?: boolean }> = new Action(); deleteCompressedLogs: Action = new Action(); resetBugReportDialog: Action = new Action(); sendBugReport: Action<{ diff --git a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js index aa58dc7036..5d1084f679 100644 --- a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js +++ b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js @@ -5,7 +5,7 @@ import { get } from 'lodash'; import { observer, inject } from 'mobx-react'; import BugReportDialog from '../../../components/profile/bug-report/BugReportDialog'; import type { InjectedProps } from '../../../types/injectedPropsType'; -import { logWithTimestamp } from '../../../utils/fileName'; +import { filenameWithTimestamp } from '../../../utils/fileName'; const shell = require('electron').shell; @@ -21,10 +21,11 @@ export default class BugReportDialogContainer extends Component { }; onDownload = () => { + const fileName = filenameWithTimestamp(); const destination = remote.dialog.showSaveDialog({ - defaultPath: logWithTimestamp(), + defaultPath: fileName, }); - if (destination) this.props.actions.profile.downloadLogs.trigger({ destination, fresh: true }); + if (destination) this.props.actions.profile.downloadLogs.trigger({ fileName, destination, fresh: true }); }; onSubmitManually = (link: string) => { diff --git a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js index dc0f2a8f5f..a998845b6c 100644 --- a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js +++ b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js @@ -5,7 +5,7 @@ import { remote } from 'electron'; import SupportSettings from '../../../components/settings/categories/SupportSettings'; import type { InjectedProps } from '../../../types/injectedPropsType'; import BugReportDialog from '../../../components/profile/bug-report/BugReportDialog'; -import { logWithTimestamp } from '../../../utils/fileName'; +import { filenameWithTimestamp } from '../../../utils/fileName'; const shell = require('electron').shell; @@ -26,10 +26,11 @@ export default class SupportSettingsPage extends Component { }; handleDownloadLogs = () => { + const fileName = filenameWithTimestamp(); const destination = remote.dialog.showSaveDialog({ - defaultPath: logWithTimestamp(), + defaultPath: fileName, }); - if (destination) this.props.actions.profile.downloadLogs.trigger({ destination, fresh: true }); + if (destination) this.props.actions.profile.downloadLogs.trigger({ fileName, destination, fresh: true }); }; render() { diff --git a/source/renderer/app/stores/ProfileStore.js b/source/renderer/app/stores/ProfileStore.js index 5a07cd3892..5326c208ce 100644 --- a/source/renderer/app/stores/ProfileStore.js +++ b/source/renderer/app/stores/ProfileStore.js @@ -207,10 +207,11 @@ export default class SettingsStore extends Store { this.actions.dialogs.closeActiveDialog.trigger(); }; - _downloadLogs = action(({ destination, fresh }) => { + _downloadLogs = action(({ destination, fresh, fileName }) => { this.compressedFileDownload = { inProgress: true, destination, + fileName }; if (this.compressedLog && fresh !== true) { @@ -235,14 +236,15 @@ export default class SettingsStore extends Store { _compressLogs = action(({ logs }) => { this.isCompressing = true; - ipcRenderer.send(COMPRESS_LOGS.REQUEST, toJS(logs)); + ipcRenderer.send(COMPRESS_LOGS.REQUEST, toJS(logs), this.compressedFileDownload.fileName); }); _onCompressLogsSuccess = action((event, res) => { this.isCompressing = false; this.compressedLog = res; - if (this.compressedFileDownload.inProgress) { - this._downloadLogs({ destination: this.compressedFileDownload.destination }); + const {inProgress, destination, fileName} = this.compressedFileDownload; + if (inProgress) { + this._downloadLogs({ destination, fileName }); } }); diff --git a/source/renderer/app/utils/fileName.js b/source/renderer/app/utils/fileName.js index eceb7b6504..c92b1d6b28 100644 --- a/source/renderer/app/utils/fileName.js +++ b/source/renderer/app/utils/fileName.js @@ -1,5 +1,4 @@ -// @flow import moment from 'moment'; -export const logWithTimestamp = (prefix: string = 'logs', filetype: string = 'zip') => - `${prefix}-${moment().format('YYYY-MM-DDTHHMMSS')}.${filetype}`; +export const filenameWithTimestamp = (prefix = 'logs', filetype = 'zip') => + `${prefix}-${moment().format('YYYY-MM-DDThhmmss')}.${filetype}`; From 88b9c504ce33f6a2d23d486e345fe9fce59b8db1 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Wed, 27 Jun 2018 12:47:08 -0300 Subject: [PATCH 03/20] [DDW-248] Removing logs on init --- source/main/utils/setupLogging.js | 19 ++++++++++++++++++- .../dialogs/BugReportDialogContainer.js | 4 +++- .../categories/SupportSettingsPage.js | 4 +++- source/renderer/app/stores/ProfileStore.js | 4 ++-- source/renderer/app/types/LogTypes.js | 3 ++- source/renderer/app/utils/fileName.js | 3 +++ 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/source/main/utils/setupLogging.js b/source/main/utils/setupLogging.js index ab00008413..d15a98bf5c 100644 --- a/source/main/utils/setupLogging.js +++ b/source/main/utils/setupLogging.js @@ -1,8 +1,10 @@ +import fs from 'fs'; import path from 'path'; import log from 'electron-log'; import moment from 'moment'; import ensureDirectoryExists from './ensureDirectoryExists'; -import { pubLogsFolderPath, APP_NAME } from '../config'; +import { pubLogsFolderPath, appLogsFolderPath, APP_NAME } from '../config'; +import { getFilenameWithTimestamp } from '../../renderer/app/utils/fileName'; const isTest = process.env.NODE_ENV === 'test'; @@ -19,4 +21,19 @@ export const setupLogging = () => { const formattedDate = moment.utc(msg.date).format('YYYY-MM-DDTHH:mm:ss.0SSS'); return `[${formattedDate}Z] [${msg.level}] ${msg.data}`; }; + + // Removes existing logs + fs.readdir(appLogsFolderPath, (err, files) => { + files + .filter(getFilenameWithTimestamp()) + .forEach((logFileName) => { + const logFile = path.join(appLogsFolderPath, logFileName); + try { + fs.unlinkSync(logFile); + } catch (error) { + console.error(error); + } + }); + }); + }; diff --git a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js index 5d1084f679..2ced793a8a 100644 --- a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js +++ b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js @@ -25,7 +25,9 @@ export default class BugReportDialogContainer extends Component { const destination = remote.dialog.showSaveDialog({ defaultPath: fileName, }); - if (destination) this.props.actions.profile.downloadLogs.trigger({ fileName, destination, fresh: true }); + if (destination) { + this.props.actions.profile.downloadLogs.trigger({ fileName, destination, fresh: true }); + } }; onSubmitManually = (link: string) => { diff --git a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js index a998845b6c..d1dba3cdde 100644 --- a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js +++ b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js @@ -30,7 +30,9 @@ export default class SupportSettingsPage extends Component { const destination = remote.dialog.showSaveDialog({ defaultPath: fileName, }); - if (destination) this.props.actions.profile.downloadLogs.trigger({ fileName, destination, fresh: true }); + if (destination) { + this.props.actions.profile.downloadLogs.trigger({ fileName, destination, fresh: true }); + } }; render() { diff --git a/source/renderer/app/stores/ProfileStore.js b/source/renderer/app/stores/ProfileStore.js index 5326c208ce..537479b95d 100644 --- a/source/renderer/app/stores/ProfileStore.js +++ b/source/renderer/app/stores/ProfileStore.js @@ -207,7 +207,7 @@ export default class SettingsStore extends Store { this.actions.dialogs.closeActiveDialog.trigger(); }; - _downloadLogs = action(({ destination, fresh, fileName }) => { + _downloadLogs = action(({ fileName, destination, fresh }) => { this.compressedFileDownload = { inProgress: true, destination, @@ -242,7 +242,7 @@ export default class SettingsStore extends Store { _onCompressLogsSuccess = action((event, res) => { this.isCompressing = false; this.compressedLog = res; - const {inProgress, destination, fileName} = this.compressedFileDownload; + const { inProgress, destination, fileName } = this.compressedFileDownload; if (inProgress) { this._downloadLogs({ destination, fileName }); } diff --git a/source/renderer/app/types/LogTypes.js b/source/renderer/app/types/LogTypes.js index ecf57c167c..138ab2cc84 100644 --- a/source/renderer/app/types/LogTypes.js +++ b/source/renderer/app/types/LogTypes.js @@ -11,6 +11,7 @@ export type CompressedLogs = { } | {}; export type CompressedFileDownload = { - inProgress?: boolean, + fileName?: string, destination?: string, + inProgress?: boolean, }; diff --git a/source/renderer/app/utils/fileName.js b/source/renderer/app/utils/fileName.js index c92b1d6b28..c455895d2b 100644 --- a/source/renderer/app/utils/fileName.js +++ b/source/renderer/app/utils/fileName.js @@ -2,3 +2,6 @@ import moment from 'moment'; export const filenameWithTimestamp = (prefix = 'logs', filetype = 'zip') => `${prefix}-${moment().format('YYYY-MM-DDThhmmss')}.${filetype}`; + +export const getFilenameWithTimestamp = (prefix = 'logs', filetype = 'zip') => fileName => + fileName.match(RegExp(`(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6})(.${filetype})`)); From c8f2a81ec093a6856d709087cceabcb30b0e7f81 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Fri, 29 Jun 2018 09:54:44 -0300 Subject: [PATCH 04/20] [DDW-248] Get fresh logs when submitting a support request --- .../app/utils => common}/fileName.js | 0 source/main/utils/setupLogging.js | 2 +- .../renderer/app/actions/profile-actions.js | 1 + source/renderer/app/api/lib/reportRequest.js | 4 +- .../profile/bug-report/BugReportDialog.js | 53 ++++++++++++------- .../dialogs/BugReportDialogContainer.js | 8 +-- .../categories/SupportSettingsPage.js | 2 +- source/renderer/app/stores/ProfileStore.js | 21 ++++++-- 8 files changed, 61 insertions(+), 30 deletions(-) rename source/{renderer/app/utils => common}/fileName.js (100%) diff --git a/source/renderer/app/utils/fileName.js b/source/common/fileName.js similarity index 100% rename from source/renderer/app/utils/fileName.js rename to source/common/fileName.js diff --git a/source/main/utils/setupLogging.js b/source/main/utils/setupLogging.js index d15a98bf5c..5ea5a15800 100644 --- a/source/main/utils/setupLogging.js +++ b/source/main/utils/setupLogging.js @@ -4,7 +4,7 @@ import log from 'electron-log'; import moment from 'moment'; import ensureDirectoryExists from './ensureDirectoryExists'; import { pubLogsFolderPath, appLogsFolderPath, APP_NAME } from '../config'; -import { getFilenameWithTimestamp } from '../../renderer/app/utils/fileName'; +import { getFilenameWithTimestamp } from '../../common/fileName'; const isTest = process.env.NODE_ENV === 'test'; diff --git a/source/renderer/app/actions/profile-actions.js b/source/renderer/app/actions/profile-actions.js index eddf55c617..73deb6c821 100644 --- a/source/renderer/app/actions/profile-actions.js +++ b/source/renderer/app/actions/profile-actions.js @@ -10,6 +10,7 @@ export default class ProfileActions { downloadLogs: Action<{ fileName: string, destination: string, fresh?: boolean }> = new Action(); deleteCompressedLogs: Action = new Action(); resetBugReportDialog: Action = new Action(); + getFreshLogs: Action = new Action(); sendBugReport: Action<{ email: string, subject: string, problem: string, compressedLog: ?string, }> = new Action(); diff --git a/source/renderer/app/api/lib/reportRequest.js b/source/renderer/app/api/lib/reportRequest.js index abb91b0b9d..6c7f80335a 100644 --- a/source/renderer/app/api/lib/reportRequest.js +++ b/source/renderer/app/api/lib/reportRequest.js @@ -1,6 +1,7 @@ import http from 'http'; import FormData from 'form-data/lib/form_data'; import fs from 'fs'; +import { getFilenameWithTimestamp } from '../../../../common/fileName'; export type RequestOptions = { hostname: string, @@ -40,7 +41,8 @@ function typedHttpRequest( // prepare file stream (attachment) if (payload.compressedLog) { const stream = fs.createReadStream(payload.compressedLog); - formData.append('logs.zip', stream); + const [fileName] = getFilenameWithTimestamp()(payload.compressedLog); + formData.append(fileName, stream); } options.headers = formData.getHeaders(); diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.js b/source/renderer/app/components/profile/bug-report/BugReportDialog.js index f7a5abad7a..a0546fd660 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.js +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.js @@ -124,8 +124,7 @@ type Props = { onSubmitManually: Function, onDownload: Function, onGetLogs: Function, - onCompressLogs: Function, - onDeleteCompressedLogs: Function, + onGetFreshLogs: Function, isSubmitting: boolean, isCompressing: boolean, isDownloading?: boolean, @@ -134,6 +133,9 @@ type Props = { type State = { showLogs: boolean, + isReadyToSubmit: boolean, + wasSubmitted: boolean, + compressedLog: ?string, }; @observer @@ -145,18 +147,26 @@ export default class BugReportDialog extends Component { state = { showLogs: true, + isReadyToSubmit: false, + wasSubmitted: false, + compressedLog: null }; componentWillMount() { - this.props.onGetLogs(); - this.props.onDeleteCompressedLogs(); + this.props.onGetFreshLogs(); } componentWillReceiveProps(nextProps: Object) { + const commpressionFilesChanged = this.props.compressedLog !== nextProps.compressedLog; + const { compressedLog, wasSubmitted } = this.state; + if (nextProps.compressedLog && commpressionFilesChanged && !nextProps.isDownloading) { - // proceed to submit when ipc rendered successfully return compressed files - this.submit(nextProps.compressedLog); + this.setState({ compressedLog: nextProps.compressedLog }); + } + + if (compressedLog && !wasSubmitted) { + this.submit(); } } @@ -206,24 +216,29 @@ export default class BugReportDialog extends Component { }, }); - submit = (compressedLog: ?string) => { + markIsReadyToSubmit = () => { + this.setState({ isReadyToSubmit: true }, this.submit); + }; + + submit = () => { + + const { compressedLog, isReadyToSubmit } = this.state; + + if (!compressedLog || !isReadyToSubmit) { + return false; + } + + this.setState({ wasSubmitted: true }); + this.form.submit({ onSuccess: (form) => { - const { logFiles } = this.props; - const logsExist = get(logFiles, ['files'], []).length > 0; const { email, subject, problem } = form.values(); const data = { email, subject, problem, compressedLog }; - if (this.state.showLogs && logsExist && !compressedLog) { - // submit request with commpressed logs files - this.props.onCompressLogs(this.props.logFiles); - } else { - // regular submit - this.props.onSubmit(data); - } + this.props.onSubmit(data); }, onError: () => {}, }); @@ -273,7 +288,7 @@ export default class BugReportDialog extends Component { label: this.context.intl.formatMessage(messages.submitButtonLabel), primary: true, disabled: isSubmitting, - onClick: this.submit.bind(this, null), + onClick: this.markIsReadyToSubmit, }, ]; @@ -322,7 +337,7 @@ export default class BugReportDialog extends Component { {...emailField.bind()} error={emailField.error} skin={} - onKeyPress={submitOnEnter.bind(this, this.submit)} + onKeyPress={submitOnEnter.bind(this, this.markIsReadyToSubmit)} /> @@ -332,7 +347,7 @@ export default class BugReportDialog extends Component { {...subjectField.bind()} error={subjectField.error} skin={} - onKeyPress={submitOnEnter.bind(this, this.submit)} + onKeyPress={submitOnEnter.bind(this, this.markIsReadyToSubmit)} /> diff --git a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js index 2ced793a8a..c94dd900a3 100644 --- a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js +++ b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js @@ -5,7 +5,7 @@ import { get } from 'lodash'; import { observer, inject } from 'mobx-react'; import BugReportDialog from '../../../components/profile/bug-report/BugReportDialog'; import type { InjectedProps } from '../../../types/injectedPropsType'; -import { filenameWithTimestamp } from '../../../utils/fileName'; +import { filenameWithTimestamp } from '../../../../../common/fileName'; const shell = require('electron').shell; @@ -40,7 +40,7 @@ export default class BugReportDialogContainer extends Component { render() { const { actions, stores } = this.props; - const { getLogs, compressLogs, deleteCompressedLogs } = actions.profile; + const { getLogs, getFreshLogs, deleteCompressedLogs } = actions.profile; const { logFiles, compressedLog, @@ -65,8 +65,8 @@ export default class BugReportDialogContainer extends Component { onGetLogs={() => { getLogs.trigger(); }} - onCompressLogs={(logs) => { - compressLogs.trigger({ logs }); + onGetFreshLogs={(logs) => { + getFreshLogs.trigger({ logs }); }} onDeleteCompressedLogs={() => { deleteCompressedLogs.trigger(); diff --git a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js index d1dba3cdde..ae167a0c7e 100644 --- a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js +++ b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js @@ -5,7 +5,7 @@ import { remote } from 'electron'; import SupportSettings from '../../../components/settings/categories/SupportSettings'; import type { InjectedProps } from '../../../types/injectedPropsType'; import BugReportDialog from '../../../components/profile/bug-report/BugReportDialog'; -import { filenameWithTimestamp } from '../../../utils/fileName'; +import { filenameWithTimestamp } from '../../../../../common/fileName'; const shell = require('electron').shell; diff --git a/source/renderer/app/stores/ProfileStore.js b/source/renderer/app/stores/ProfileStore.js index 537479b95d..34dfa3f808 100644 --- a/source/renderer/app/stores/ProfileStore.js +++ b/source/renderer/app/stores/ProfileStore.js @@ -14,6 +14,7 @@ import LocalizableError from '../i18n/LocalizableError'; import globalMessages from '../i18n/global-messages'; import { WalletSupportRequestLogsCompressError } from '../i18n/errors'; import type { LogFiles, CompressedFileDownload } from '../types/LogTypes'; +import { filenameWithTimestamp } from '../../../common/fileName'; export default class SettingsStore extends Store { @@ -57,6 +58,7 @@ export default class SettingsStore extends Store { this.actions.profile.getLogs.listen(this._getLogs); this.actions.profile.resetBugReportDialog.listen(this._resetBugReportDialog); this.actions.profile.downloadLogs.listen(this._downloadLogs); + this.actions.profile.getFreshLogs.listen(this._getFreshLogs); this.actions.profile.compressLogs.listen(this._compressLogs); this.actions.profile.deleteCompressedLogs.listen(this._deleteCompressedFiles); this.actions.profile.sendBugReport.listen(this._sendBugReport); @@ -225,18 +227,27 @@ export default class SettingsStore extends Store { _onGetLogsSuccess = action((event, res) => { this.logFiles = res; - if (this.compressedFileDownload.inProgress) { - this._compressLogs({ logs: res }); - } + this._compressLogs({ logs: res }); }); _onDownloadLogsSuccess = action(() => { this.compressedFileDownload = {}; }); + _getFreshLogs = action(() => { + this.compressedFileDownload = { + fileName: filenameWithTimestamp() + }; + this.isCompressing = true; + + this._getLogs(); + }); + _compressLogs = action(({ logs }) => { this.isCompressing = true; - ipcRenderer.send(COMPRESS_LOGS.REQUEST, toJS(logs), this.compressedFileDownload.fileName); + const { fileName = filenameWithTimestamp() } = this.compressedFileDownload; + + ipcRenderer.send(COMPRESS_LOGS.REQUEST, toJS(logs), fileName); }); _onCompressLogsSuccess = action((event, res) => { @@ -258,6 +269,7 @@ export default class SettingsStore extends Store { problem: string, compressedLog: ?string, }) => { + this.sendBugReport.execute({ email, subject, problem, compressedLog, }) @@ -267,6 +279,7 @@ export default class SettingsStore extends Store { .catch(action((error) => { this.error = error; })); + }); _deleteCompressedFiles = action(() => { From 15c2a1ecb6e1de6d18d5c368e6c36b92fcc10603 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Mon, 2 Jul 2018 09:41:11 -0300 Subject: [PATCH 05/20] [DDW-248] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cc686722f..ebe38abf7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ Changelog - Added acceptance tests for node update notification with apply and postpone update scenarios ([PR 977](https://github.com/input-output-hk/daedalus/pull/977)) - Added acceptance tests for maximum wallets limit ([PR 979](https://github.com/input-output-hk/daedalus/pull/979)) - Added acceptance tests for the About dialog ([PR 975](https://github.com/input-output-hk/daedalus/pull/975)) +- Refactored compress/download logs handling ([PR 995](https://github.com/input-output-hk/daedalus/pull/995)) ## 0.10.1 ======= From 5976494fe7d55fc14b5f8d0e84f39476a7ed9e55 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Wed, 4 Jul 2018 10:39:21 -0300 Subject: [PATCH 06/20] [DDW-248] UTC timestamp and FLOW --- source/common/fileName.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/common/fileName.js b/source/common/fileName.js index c455895d2b..7169812195 100644 --- a/source/common/fileName.js +++ b/source/common/fileName.js @@ -1,7 +1,8 @@ +// @flow import moment from 'moment'; -export const filenameWithTimestamp = (prefix = 'logs', filetype = 'zip') => - `${prefix}-${moment().format('YYYY-MM-DDThhmmss')}.${filetype}`; +export const filenameWithTimestamp = (prefix:string = 'logs', filetype:string = 'zip') => + `${prefix}-${moment.utc().format('YYYY-MM-DDThhmmss.0SSS')}.${filetype}`; -export const getFilenameWithTimestamp = (prefix = 'logs', filetype = 'zip') => fileName => - fileName.match(RegExp(`(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6})(.${filetype})`)); +export const getFilenameWithTimestamp = (prefix:string = 'logs', filetype:string = 'zip') => (fileName:string) => + fileName.match(RegExp(`(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}.0[0-9]{3})(.${filetype})`)); From e39f322e1a2d006ce160eefbc240b698c3001eb6 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Wed, 4 Jul 2018 10:39:42 -0300 Subject: [PATCH 07/20] [DDW-248] Requesting logs only upon form submition --- .../profile/bug-report/BugReportDialog.js | 62 ++++++++----------- .../dialogs/BugReportDialogContainer.js | 9 +-- 2 files changed, 28 insertions(+), 43 deletions(-) diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.js b/source/renderer/app/components/profile/bug-report/BugReportDialog.js index a0546fd660..4bc9590ee0 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.js +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.js @@ -118,24 +118,20 @@ const messages = defineMessages({ type Props = { logFiles: LogFiles, - compressedLog: ?string, onCancel: Function, onSubmit: Function, onSubmitManually: Function, onDownload: Function, onGetLogs: Function, onGetFreshLogs: Function, - isSubmitting: boolean, - isCompressing: boolean, isDownloading?: boolean, error: ?LocalizableError, }; type State = { showLogs: boolean, - isReadyToSubmit: boolean, - wasSubmitted: boolean, compressedLog: ?string, + isSubmitting: boolean }; @observer @@ -147,27 +143,23 @@ export default class BugReportDialog extends Component { state = { showLogs: true, - isReadyToSubmit: false, - wasSubmitted: false, - compressedLog: null + compressedLog: null, + isSubmitting: false, }; - componentWillMount() { - this.props.onGetFreshLogs(); - } - componentWillReceiveProps(nextProps: Object) { - const commpressionFilesChanged = this.props.compressedLog !== nextProps.compressedLog; - const { compressedLog, wasSubmitted } = this.state; + const commpressionFilesChanged = !this.props.compressedLog && !!nextProps.compressedLog; + const { compressedLog } = this.state; - if (nextProps.compressedLog && commpressionFilesChanged && !nextProps.isDownloading) { - this.setState({ compressedLog: nextProps.compressedLog }); + if (compressedLog) { + return false; } - if (compressedLog && !wasSubmitted) { - this.submit(); + if (nextProps.compressedLog && commpressionFilesChanged && !nextProps.isDownloading) { + this.setState({ compressedLog: nextProps.compressedLog }, this.submit); } + } form = new ReactToolboxMobxForm({ @@ -216,27 +208,27 @@ export default class BugReportDialog extends Component { }, }); - markIsReadyToSubmit = () => { - this.setState({ isReadyToSubmit: true }, this.submit); - }; - submit = () => { - const { compressedLog, isReadyToSubmit } = this.state; + this.setState({ isSubmitting: true }); - if (!compressedLog || !isReadyToSubmit) { + const { showLogs, compressedLog } = this.state; + + if (showLogs && !compressedLog) { + this.props.onGetFreshLogs(); return false; } - this.setState({ wasSubmitted: true }); - this.form.submit({ onSuccess: (form) => { const { email, subject, problem } = form.values(); - const data = { - email, subject, problem, compressedLog - }; + const data = Object.assign( + { + email, subject, problem + }, + showLogs && { compressedLog} + ); this.props.onSubmit(data); }, @@ -250,10 +242,10 @@ export default class BugReportDialog extends Component { render() { const { intl } = this.context; - const { showLogs } = this.state; + const { showLogs, isSubmitting } = this.state; const { form } = this; const { - onCancel, isSubmitting, isCompressing, + onCancel, logFiles, error, onDownload, isDownloading, } = this.props; @@ -270,7 +262,7 @@ export default class BugReportDialog extends Component { const submitButtonClasses = classnames([ 'submitButton', - (isSubmitting || isCompressing) ? styles.isSubmitting : null, + isSubmitting ? styles.isSubmitting : null, ]); const downloadButtonClasses = classnames([ @@ -288,7 +280,7 @@ export default class BugReportDialog extends Component { label: this.context.intl.formatMessage(messages.submitButtonLabel), primary: true, disabled: isSubmitting, - onClick: this.markIsReadyToSubmit, + onClick: this.submit, }, ]; @@ -337,7 +329,7 @@ export default class BugReportDialog extends Component { {...emailField.bind()} error={emailField.error} skin={} - onKeyPress={submitOnEnter.bind(this, this.markIsReadyToSubmit)} + onKeyPress={submitOnEnter.bind(this, this.submit)} /> @@ -347,7 +339,7 @@ export default class BugReportDialog extends Component { {...subjectField.bind()} error={subjectField.error} skin={} - onKeyPress={submitOnEnter.bind(this, this.markIsReadyToSubmit)} + onKeyPress={submitOnEnter.bind(this, this.submit)} /> diff --git a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js index c94dd900a3..df6db250b7 100644 --- a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js +++ b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js @@ -40,12 +40,10 @@ export default class BugReportDialogContainer extends Component { render() { const { actions, stores } = this.props; - const { getLogs, getFreshLogs, deleteCompressedLogs } = actions.profile; + const { getLogs, getFreshLogs } = actions.profile; const { logFiles, compressedLog, - isCompressing, - sendBugReport, compressedFileDownload, error, } = stores.profile; @@ -55,8 +53,6 @@ export default class BugReportDialogContainer extends Component { isDownloading={get(compressedFileDownload, 'inProgress', false)} logFiles={logFiles} compressedLog={compressedLog} - isCompressing={isCompressing} - isSubmitting={sendBugReport.isExecuting} error={error} onSubmit={this.onSubmit} onSubmitManually={this.onSubmitManually} @@ -68,9 +64,6 @@ export default class BugReportDialogContainer extends Component { onGetFreshLogs={(logs) => { getFreshLogs.trigger({ logs }); }} - onDeleteCompressedLogs={() => { - deleteCompressedLogs.trigger(); - }} /> ); } From 2d5a2512499194722d3e0a63f2aecd0174ca036b Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Wed, 4 Jul 2018 10:41:36 -0300 Subject: [PATCH 08/20] [DDW-248] Removes useless extra lines --- source/renderer/app/stores/ProfileStore.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/renderer/app/stores/ProfileStore.js b/source/renderer/app/stores/ProfileStore.js index 34dfa3f808..b6ce99f584 100644 --- a/source/renderer/app/stores/ProfileStore.js +++ b/source/renderer/app/stores/ProfileStore.js @@ -239,14 +239,12 @@ export default class SettingsStore extends Store { fileName: filenameWithTimestamp() }; this.isCompressing = true; - this._getLogs(); }); _compressLogs = action(({ logs }) => { this.isCompressing = true; const { fileName = filenameWithTimestamp() } = this.compressedFileDownload; - ipcRenderer.send(COMPRESS_LOGS.REQUEST, toJS(logs), fileName); }); From 7ab1f8fdc0bf97506903dab69914195e548d24fc Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Wed, 4 Jul 2018 10:45:33 -0300 Subject: [PATCH 09/20] [DDW-248] Renaming getFreshLogs to avoid confusion --- .../app/components/profile/bug-report/BugReportDialog.js | 5 ++--- .../profile/dialogs/BugReportDialogContainer.js | 9 +++------ source/renderer/app/stores/ProfileStore.js | 4 ++-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.js b/source/renderer/app/components/profile/bug-report/BugReportDialog.js index 4bc9590ee0..10953b3ea8 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.js +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.js @@ -122,8 +122,7 @@ type Props = { onSubmit: Function, onSubmitManually: Function, onDownload: Function, - onGetLogs: Function, - onGetFreshLogs: Function, + onRequestFreshCompressedLogs: Function, isDownloading?: boolean, error: ?LocalizableError, }; @@ -215,7 +214,7 @@ export default class BugReportDialog extends Component { const { showLogs, compressedLog } = this.state; if (showLogs && !compressedLog) { - this.props.onGetFreshLogs(); + this.props.onRequestFreshCompressedLogs(); return false; } diff --git a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js index df6db250b7..1086655a9c 100644 --- a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js +++ b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js @@ -40,7 +40,7 @@ export default class BugReportDialogContainer extends Component { render() { const { actions, stores } = this.props; - const { getLogs, getFreshLogs } = actions.profile; + const { getLogs, requestFreshCompressedLogs } = actions.profile; const { logFiles, compressedLog, @@ -58,11 +58,8 @@ export default class BugReportDialogContainer extends Component { onSubmitManually={this.onSubmitManually} onDownload={this.onDownload} onCancel={this.resetBugReportDialog} - onGetLogs={() => { - getLogs.trigger(); - }} - onGetFreshLogs={(logs) => { - getFreshLogs.trigger({ logs }); + onRequestFreshCompressedLogs={(logs) => { + requestFreshCompressedLogs.trigger({ logs }); }} /> ); diff --git a/source/renderer/app/stores/ProfileStore.js b/source/renderer/app/stores/ProfileStore.js index b6ce99f584..909b7fe20a 100644 --- a/source/renderer/app/stores/ProfileStore.js +++ b/source/renderer/app/stores/ProfileStore.js @@ -58,7 +58,7 @@ export default class SettingsStore extends Store { this.actions.profile.getLogs.listen(this._getLogs); this.actions.profile.resetBugReportDialog.listen(this._resetBugReportDialog); this.actions.profile.downloadLogs.listen(this._downloadLogs); - this.actions.profile.getFreshLogs.listen(this._getFreshLogs); + this.actions.profile.requestFreshCompressedLogs.listen(this._requestFreshCompressedLogs); this.actions.profile.compressLogs.listen(this._compressLogs); this.actions.profile.deleteCompressedLogs.listen(this._deleteCompressedFiles); this.actions.profile.sendBugReport.listen(this._sendBugReport); @@ -234,7 +234,7 @@ export default class SettingsStore extends Store { this.compressedFileDownload = {}; }); - _getFreshLogs = action(() => { + _requestFreshCompressedLogs = action(() => { this.compressedFileDownload = { fileName: filenameWithTimestamp() }; From 242710e6ca0033f15bfb78ab69f6fc497fc57457 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Wed, 4 Jul 2018 10:55:50 -0300 Subject: [PATCH 10/20] [DDW-248] Flow errors --- source/renderer/app/actions/profile-actions.js | 2 +- .../app/components/profile/bug-report/BugReportDialog.js | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/source/renderer/app/actions/profile-actions.js b/source/renderer/app/actions/profile-actions.js index 73deb6c821..6415374569 100644 --- a/source/renderer/app/actions/profile-actions.js +++ b/source/renderer/app/actions/profile-actions.js @@ -10,7 +10,7 @@ export default class ProfileActions { downloadLogs: Action<{ fileName: string, destination: string, fresh?: boolean }> = new Action(); deleteCompressedLogs: Action = new Action(); resetBugReportDialog: Action = new Action(); - getFreshLogs: Action = new Action(); + requestFreshCompressedLogs: Action = new Action(); sendBugReport: Action<{ email: string, subject: string, problem: string, compressedLog: ?string, }> = new Action(); diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.js b/source/renderer/app/components/profile/bug-report/BugReportDialog.js index 10953b3ea8..0547ee8c82 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.js +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.js @@ -222,12 +222,9 @@ export default class BugReportDialog extends Component { onSuccess: (form) => { const { email, subject, problem } = form.values(); - const data = Object.assign( - { - email, subject, problem - }, - showLogs && { compressedLog} - ); + const data = { + email, subject, problem, compressedLog + }; this.props.onSubmit(data); }, From 81a444d1f21f7e7255bdf47f21a851c9a7e94d51 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Wed, 4 Jul 2018 11:03:27 -0300 Subject: [PATCH 11/20] [DDW-248] lint error --- .../app/containers/profile/dialogs/BugReportDialogContainer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js index 1086655a9c..758921b09d 100644 --- a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js +++ b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js @@ -40,7 +40,7 @@ export default class BugReportDialogContainer extends Component { render() { const { actions, stores } = this.props; - const { getLogs, requestFreshCompressedLogs } = actions.profile; + const { requestFreshCompressedLogs } = actions.profile; const { logFiles, compressedLog, From 9a3a1231ff743a2a5dbb16c7e13a5361649db4d6 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Thu, 5 Jul 2018 10:38:37 -0300 Subject: [PATCH 12/20] [DDW-248] Adjustments --- source/common/fileName.js | 4 ++-- .../app/components/profile/bug-report/BugReportDialog.js | 9 +++++++-- .../renderer/app/components/widgets/DialogCloseButton.js | 5 +++-- .../app/components/widgets/DialogCloseButton.scss | 6 ++++++ source/renderer/app/stores/ProfileStore.js | 9 --------- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/source/common/fileName.js b/source/common/fileName.js index 7169812195..d130352be9 100644 --- a/source/common/fileName.js +++ b/source/common/fileName.js @@ -2,7 +2,7 @@ import moment from 'moment'; export const filenameWithTimestamp = (prefix:string = 'logs', filetype:string = 'zip') => - `${prefix}-${moment.utc().format('YYYY-MM-DDThhmmss.0SSS')}.${filetype}`; + `${prefix}-${moment.utc().format('YYYY-MM-DDTHHmmss.0SSS')}Z.${filetype}`; export const getFilenameWithTimestamp = (prefix:string = 'logs', filetype:string = 'zip') => (fileName:string) => - fileName.match(RegExp(`(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}.0[0-9]{3})(.${filetype})`)); + fileName.match(RegExp(`(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}.0[0-9]{3}Z)(.${filetype})`)); diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.js b/source/renderer/app/components/profile/bug-report/BugReportDialog.js index 0547ee8c82..827438230e 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.js +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.js @@ -236,6 +236,11 @@ export default class BugReportDialog extends Component { this.setState({ showLogs: value }); }; + onClose = () => { + const { error, onCancel } = this.props; + if (!this.state.isSubmitting || error) onCancel(); + } + render() { const { intl } = this.context; const { showLogs, isSubmitting } = this.state; @@ -302,8 +307,8 @@ export default class BugReportDialog extends Component { title={intl.formatMessage(messages.title)} actions={!error ? actions : alternativeActions} closeOnOverlayClick - onClose={onCancel} - closeButton={} + onClose={this.onClose} + closeButton={} > {error ? (
diff --git a/source/renderer/app/components/widgets/DialogCloseButton.js b/source/renderer/app/components/widgets/DialogCloseButton.js index 274ed22835..7929aa72ab 100644 --- a/source/renderer/app/components/widgets/DialogCloseButton.js +++ b/source/renderer/app/components/widgets/DialogCloseButton.js @@ -6,14 +6,15 @@ import styles from './DialogCloseButton.scss'; type Props = { onClose: Function, icon?: string, + disabled?: boolean }; export default class DialogCloseButton extends Component { render() { - const { onClose, icon } = this.props; + const { onClose, icon, disabled } = this.props; return ( - ); diff --git a/source/renderer/app/components/widgets/DialogCloseButton.scss b/source/renderer/app/components/widgets/DialogCloseButton.scss index cc238043f7..368dc8732a 100644 --- a/source/renderer/app/components/widgets/DialogCloseButton.scss +++ b/source/renderer/app/components/widgets/DialogCloseButton.scss @@ -11,3 +11,9 @@ } } } + +.disabled { + @extend .component; + opacity: .5; + cursor: default; +} diff --git a/source/renderer/app/stores/ProfileStore.js b/source/renderer/app/stores/ProfileStore.js index 909b7fe20a..4f0a0093f8 100644 --- a/source/renderer/app/stores/ProfileStore.js +++ b/source/renderer/app/stores/ProfileStore.js @@ -60,7 +60,6 @@ export default class SettingsStore extends Store { this.actions.profile.downloadLogs.listen(this._downloadLogs); this.actions.profile.requestFreshCompressedLogs.listen(this._requestFreshCompressedLogs); this.actions.profile.compressLogs.listen(this._compressLogs); - this.actions.profile.deleteCompressedLogs.listen(this._deleteCompressedFiles); this.actions.profile.sendBugReport.listen(this._sendBugReport); ipcRenderer.on(GET_LOGS.SUCCESS, this._onGetLogsSuccess); ipcRenderer.on(DOWNLOAD_LOGS.SUCCESS, this._onDownloadLogsSuccess); @@ -204,7 +203,6 @@ export default class SettingsStore extends Store { }; _resetBugReportDialog = () => { - this._deleteCompressedFiles(); this._reset(); this.actions.dialogs.closeActiveDialog.trigger(); }; @@ -280,13 +278,6 @@ export default class SettingsStore extends Store { }); - _deleteCompressedFiles = action(() => { - if (this.compressedLog) { - ipcRenderer.send(DELETE_COMPRESSED_LOGS.REQUEST, this.compressedLog); - this.compressedLog = null; - } - }); - @action _reset = () => { this.error = null; this.compressedLog = null; From 344d5d5052d4f6315269f85cbc168065dac57450 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Thu, 5 Jul 2018 10:46:13 -0300 Subject: [PATCH 13/20] [DDW-248] linting --- .../app/components/profile/bug-report/BugReportDialog.js | 1 - source/renderer/app/components/widgets/DialogCloseButton.js | 6 +++++- source/renderer/app/stores/ProfileStore.js | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.js b/source/renderer/app/components/profile/bug-report/BugReportDialog.js index 827438230e..3b9334ee3b 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.js +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.js @@ -246,7 +246,6 @@ export default class BugReportDialog extends Component { const { showLogs, isSubmitting } = this.state; const { form } = this; const { - onCancel, logFiles, error, onDownload, isDownloading, } = this.props; diff --git a/source/renderer/app/components/widgets/DialogCloseButton.js b/source/renderer/app/components/widgets/DialogCloseButton.js index 7929aa72ab..f532d53219 100644 --- a/source/renderer/app/components/widgets/DialogCloseButton.js +++ b/source/renderer/app/components/widgets/DialogCloseButton.js @@ -14,7 +14,11 @@ export default class DialogCloseButton extends Component { render() { const { onClose, icon, disabled } = this.props; return ( - ); diff --git a/source/renderer/app/stores/ProfileStore.js b/source/renderer/app/stores/ProfileStore.js index 4f0a0093f8..1a69efb7b5 100644 --- a/source/renderer/app/stores/ProfileStore.js +++ b/source/renderer/app/stores/ProfileStore.js @@ -9,7 +9,7 @@ import Request from './lib/LocalizedRequest'; import environment from '../../../common/environment'; import { THEMES } from '../themes/index'; import { ROUTES } from '../routes-config'; -import { GET_LOGS, DOWNLOAD_LOGS, COMPRESS_LOGS, DELETE_COMPRESSED_LOGS } from '../../../common/ipc-api'; +import { GET_LOGS, DOWNLOAD_LOGS, COMPRESS_LOGS } from '../../../common/ipc-api'; import LocalizableError from '../i18n/LocalizableError'; import globalMessages from '../i18n/global-messages'; import { WalletSupportRequestLogsCompressError } from '../i18n/errors'; From 37d9bf5c7fa2c80f3e57412306c02cfb3e4b6084 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Fri, 6 Jul 2018 10:42:03 -0300 Subject: [PATCH 14/20] [DDW-248] getting logs on dialog open --- .../components/profile/bug-report/BugReportDialog.js | 5 +++++ .../profile/dialogs/BugReportDialogContainer.js | 5 ++++- source/renderer/app/stores/ProfileStore.js | 10 +++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.js b/source/renderer/app/components/profile/bug-report/BugReportDialog.js index 3b9334ee3b..13c11f75fd 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.js +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.js @@ -122,6 +122,7 @@ type Props = { onSubmit: Function, onSubmitManually: Function, onDownload: Function, + onGetLogs: Function, onRequestFreshCompressedLogs: Function, isDownloading?: boolean, error: ?LocalizableError, @@ -146,6 +147,10 @@ export default class BugReportDialog extends Component { isSubmitting: false, }; + componentWillMount() { + this.props.onGetLogs(); + } + componentWillReceiveProps(nextProps: Object) { const commpressionFilesChanged = !this.props.compressedLog && !!nextProps.compressedLog; diff --git a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js index 758921b09d..3d8cd47d2a 100644 --- a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js +++ b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js @@ -40,7 +40,7 @@ export default class BugReportDialogContainer extends Component { render() { const { actions, stores } = this.props; - const { requestFreshCompressedLogs } = actions.profile; + const { getLogs, requestFreshCompressedLogs } = actions.profile; const { logFiles, compressedLog, @@ -61,6 +61,9 @@ export default class BugReportDialogContainer extends Component { onRequestFreshCompressedLogs={(logs) => { requestFreshCompressedLogs.trigger({ logs }); }} + onGetLogs={() => { + getLogs.trigger(); + }} /> ); } diff --git a/source/renderer/app/stores/ProfileStore.js b/source/renderer/app/stores/ProfileStore.js index 1a69efb7b5..d6fff74e69 100644 --- a/source/renderer/app/stores/ProfileStore.js +++ b/source/renderer/app/stores/ProfileStore.js @@ -225,7 +225,9 @@ export default class SettingsStore extends Store { _onGetLogsSuccess = action((event, res) => { this.logFiles = res; - this._compressLogs({ logs: res }); + if (this.compressedFileDownload.inProgress) { + this._compressLogs({ logs: res }); + } }); _onDownloadLogsSuccess = action(() => { @@ -233,11 +235,13 @@ export default class SettingsStore extends Store { }); _requestFreshCompressedLogs = action(() => { + if (!this.logFiles) { + return this._getLogs(); + } this.compressedFileDownload = { fileName: filenameWithTimestamp() }; - this.isCompressing = true; - this._getLogs(); + this._compressLogs({ logs: this.logFiles }); }); _compressLogs = action(({ logs }) => { From 0d42e244b65974916fb347684c80aad53f49e298 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Fri, 6 Jul 2018 12:00:02 -0300 Subject: [PATCH 15/20] [DDW-248] Adjustments --- .../components/profile/bug-report/BugReportDialog.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.js b/source/renderer/app/components/profile/bug-report/BugReportDialog.js index 13c11f75fd..253f9907a0 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.js +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.js @@ -153,6 +153,10 @@ export default class BugReportDialog extends Component { componentWillReceiveProps(nextProps: Object) { + if (!this.props.error && nextProps.error) { + this.setState({ isSubmitting: false }); + } + const commpressionFilesChanged = !this.props.compressedLog && !!nextProps.compressedLog; const { compressedLog } = this.state; @@ -241,10 +245,7 @@ export default class BugReportDialog extends Component { this.setState({ showLogs: value }); }; - onClose = () => { - const { error, onCancel } = this.props; - if (!this.state.isSubmitting || error) onCancel(); - } + onClose = () => !this.state.isSubmitting && this.props.onCancel(); render() { const { intl } = this.context; @@ -312,7 +313,7 @@ export default class BugReportDialog extends Component { actions={!error ? actions : alternativeActions} closeOnOverlayClick onClose={this.onClose} - closeButton={} + closeButton={} > {error ? (
From a7af4f1052c60e32448dfc4f0ea77d01f8502622 Mon Sep 17 00:00:00 2001 From: nikolaglumac Date: Tue, 10 Jul 2018 12:58:25 +0200 Subject: [PATCH 16/20] [DDW-248] Code style improvements --- CHANGELOG.md | 2 +- source/common/fileName.js | 8 ++++---- source/common/ipc-api.js | 7 ------- source/main/ipc-api/compress-logs.js | 1 - source/main/ipc-api/delete-compressed-logs.js | 19 ------------------- source/main/ipc-api/index.js | 2 -- source/main/utils/setupLogging.js | 9 ++++----- .../renderer/app/actions/profile-actions.js | 1 - source/renderer/app/api/lib/reportRequest.js | 4 ++-- .../profile/bug-report/BugReportDialog.js | 6 ------ .../components/widgets/DialogCloseButton.scss | 2 +- .../dialogs/BugReportDialogContainer.js | 4 ++-- .../categories/SupportSettingsPage.js | 4 ++-- source/renderer/app/stores/ProfileStore.js | 10 ++++------ 14 files changed, 20 insertions(+), 59 deletions(-) delete mode 100644 source/main/ipc-api/delete-compressed-logs.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 691b8fe7b0..3fe4507ef2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,7 +47,7 @@ Changelog - Added acceptance tests for node update notification with apply and postpone update scenarios ([PR 977](https://github.com/input-output-hk/daedalus/pull/977)) - Added acceptance tests for maximum wallets limit ([PR 979](https://github.com/input-output-hk/daedalus/pull/979)) - Added acceptance tests for the About dialog ([PR 975](https://github.com/input-output-hk/daedalus/pull/975)) -- Refactored compress/download logs handling ([PR 995](https://github.com/input-output-hk/daedalus/pull/995)) +- Improved compress/download logs handling ([PR 995](https://github.com/input-output-hk/daedalus/pull/995)) ## 0.10.1 ======= diff --git a/source/common/fileName.js b/source/common/fileName.js index d130352be9..163085b106 100644 --- a/source/common/fileName.js +++ b/source/common/fileName.js @@ -1,8 +1,8 @@ // @flow import moment from 'moment'; -export const filenameWithTimestamp = (prefix:string = 'logs', filetype:string = 'zip') => - `${prefix}-${moment.utc().format('YYYY-MM-DDTHHmmss.0SSS')}Z.${filetype}`; +export const generateFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') => + `${prefix}-${moment.utc().format('YYYY-MM-DDTHHmmss.0SSS')}Z.${fileType}`; -export const getFilenameWithTimestamp = (prefix:string = 'logs', filetype:string = 'zip') => (fileName:string) => - fileName.match(RegExp(`(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}.0[0-9]{3}Z)(.${filetype})`)); +export const getFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') => (fileName: string) => + fileName.match(RegExp(`(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}.0[0-9]{3}Z)(.${fileType})`)); diff --git a/source/common/ipc-api.js b/source/common/ipc-api.js index 23bc59f3e9..ef24dd1c4e 100644 --- a/source/common/ipc-api.js +++ b/source/common/ipc-api.js @@ -20,13 +20,6 @@ export const COMPRESS_LOGS = { ERROR: `${COMPRESS_LOGS_CHANNEL}-error`, }; -const DELETE_COMPRESSED_LOGS_CHANNEL = 'delete-compressed-logs'; -export const DELETE_COMPRESSED_LOGS = { - REQUEST: DELETE_COMPRESSED_LOGS_CHANNEL, - SUCCESS: `${DELETE_COMPRESSED_LOGS_CHANNEL}-success`, - ERROR: `${DELETE_COMPRESSED_LOGS_CHANNEL}-error`, -}; - const DOWNLOAD_LOGS_CHANNEL = 'download-logs'; export const DOWNLOAD_LOGS = { REQUEST: DOWNLOAD_LOGS_CHANNEL, diff --git a/source/main/ipc-api/compress-logs.js b/source/main/ipc-api/compress-logs.js index cfa2cc5110..eb40eb6e72 100644 --- a/source/main/ipc-api/compress-logs.js +++ b/source/main/ipc-api/compress-logs.js @@ -11,7 +11,6 @@ import { COMPRESS_LOGS } from '../../common/ipc-api'; export default () => { ipcMain.on(COMPRESS_LOGS.REQUEST, (event, logs, compressedFileName) => { const sender = event.sender; - const outputPath = path.join(appLogsFolderPath, compressedFileName); const output = fs.createWriteStream(outputPath); const archive = archiver('zip', { diff --git a/source/main/ipc-api/delete-compressed-logs.js b/source/main/ipc-api/delete-compressed-logs.js deleted file mode 100644 index deb19117c3..0000000000 --- a/source/main/ipc-api/delete-compressed-logs.js +++ /dev/null @@ -1,19 +0,0 @@ -// @flow -import { ipcMain } from 'electron'; -import fs from 'fs'; -import { Logger, stringifyError } from '../../common/logging'; -import { DELETE_COMPRESSED_LOGS } from '../../common/ipc-api'; - -export default () => { - ipcMain.on(DELETE_COMPRESSED_LOGS.REQUEST, (event, file) => { - const sender = event.sender; - try { - fs.unlinkSync(file); - Logger.info('DELETE_COMPRESSED_LOGS.SUCCESS'); - return sender.send(DELETE_COMPRESSED_LOGS.SUCCESS); - } catch (error) { - Logger.error('DELETE_COMPRESSED_LOGS.ERROR: ' + stringifyError(error)); - return sender.send(DELETE_COMPRESSED_LOGS.ERROR, error); - } - }); -}; diff --git a/source/main/ipc-api/index.js b/source/main/ipc-api/index.js index 7bf401e993..286fa1408c 100644 --- a/source/main/ipc-api/index.js +++ b/source/main/ipc-api/index.js @@ -1,6 +1,5 @@ // @flow import compressLogsApi from './compress-logs'; -import deleteCompressedLogsApi from './delete-compressed-logs'; import downloadLogsApi from './download-logs'; import getLogsApi from './get-logs'; import parseRedemptionCodeApi from './parse-redemption-code-from-pdf'; @@ -10,7 +9,6 @@ import loadAsset from './load-asset'; export default (params: any) => { compressLogsApi(); - deleteCompressedLogsApi(); downloadLogsApi(); getLogsApi(); parseRedemptionCodeApi(); diff --git a/source/main/utils/setupLogging.js b/source/main/utils/setupLogging.js index 5ea5a15800..437155a6e4 100644 --- a/source/main/utils/setupLogging.js +++ b/source/main/utils/setupLogging.js @@ -4,7 +4,7 @@ import log from 'electron-log'; import moment from 'moment'; import ensureDirectoryExists from './ensureDirectoryExists'; import { pubLogsFolderPath, appLogsFolderPath, APP_NAME } from '../config'; -import { getFilenameWithTimestamp } from '../../common/fileName'; +import { getFileNameWithTimestamp } from '../../common/fileName'; const isTest = process.env.NODE_ENV === 'test'; @@ -22,18 +22,17 @@ export const setupLogging = () => { return `[${formattedDate}Z] [${msg.level}] ${msg.data}`; }; - // Removes existing logs + // Removes existing compressed logs fs.readdir(appLogsFolderPath, (err, files) => { files - .filter(getFilenameWithTimestamp()) + .filter(getFileNameWithTimestamp()) .forEach((logFileName) => { const logFile = path.join(appLogsFolderPath, logFileName); try { fs.unlinkSync(logFile); } catch (error) { - console.error(error); + console.error(`Compressed log file "${logFile}" deletion failed: ${error}`); } }); }); - }; diff --git a/source/renderer/app/actions/profile-actions.js b/source/renderer/app/actions/profile-actions.js index 6415374569..5d2f87a1e6 100644 --- a/source/renderer/app/actions/profile-actions.js +++ b/source/renderer/app/actions/profile-actions.js @@ -8,7 +8,6 @@ export default class ProfileActions { compressLogs: Action<{ logs: Object }> = new Action(); getLogs: Action = new Action(); downloadLogs: Action<{ fileName: string, destination: string, fresh?: boolean }> = new Action(); - deleteCompressedLogs: Action = new Action(); resetBugReportDialog: Action = new Action(); requestFreshCompressedLogs: Action = new Action(); sendBugReport: Action<{ diff --git a/source/renderer/app/api/lib/reportRequest.js b/source/renderer/app/api/lib/reportRequest.js index 6c7f80335a..0d95c479fb 100644 --- a/source/renderer/app/api/lib/reportRequest.js +++ b/source/renderer/app/api/lib/reportRequest.js @@ -1,7 +1,7 @@ import http from 'http'; import FormData from 'form-data/lib/form_data'; import fs from 'fs'; -import { getFilenameWithTimestamp } from '../../../../common/fileName'; +import { getFileNameWithTimestamp } from '../../../../common/fileName'; export type RequestOptions = { hostname: string, @@ -41,7 +41,7 @@ function typedHttpRequest( // prepare file stream (attachment) if (payload.compressedLog) { const stream = fs.createReadStream(payload.compressedLog); - const [fileName] = getFilenameWithTimestamp()(payload.compressedLog); + const [fileName] = getFileNameWithTimestamp()(payload.compressedLog); formData.append(fileName, stream); } diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.js b/source/renderer/app/components/profile/bug-report/BugReportDialog.js index 253f9907a0..579f1c0b42 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.js +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.js @@ -152,7 +152,6 @@ export default class BugReportDialog extends Component { } componentWillReceiveProps(nextProps: Object) { - if (!this.props.error && nextProps.error) { this.setState({ isSubmitting: false }); } @@ -167,7 +166,6 @@ export default class BugReportDialog extends Component { if (nextProps.compressedLog && commpressionFilesChanged && !nextProps.isDownloading) { this.setState({ compressedLog: nextProps.compressedLog }, this.submit); } - } form = new ReactToolboxMobxForm({ @@ -217,11 +215,9 @@ export default class BugReportDialog extends Component { }); submit = () => { - this.setState({ isSubmitting: true }); const { showLogs, compressedLog } = this.state; - if (showLogs && !compressedLog) { this.props.onRequestFreshCompressedLogs(); return false; @@ -229,12 +225,10 @@ export default class BugReportDialog extends Component { this.form.submit({ onSuccess: (form) => { - const { email, subject, problem } = form.values(); const data = { email, subject, problem, compressedLog }; - this.props.onSubmit(data); }, onError: () => {}, diff --git a/source/renderer/app/components/widgets/DialogCloseButton.scss b/source/renderer/app/components/widgets/DialogCloseButton.scss index 368dc8732a..1bb5384482 100644 --- a/source/renderer/app/components/widgets/DialogCloseButton.scss +++ b/source/renderer/app/components/widgets/DialogCloseButton.scss @@ -14,6 +14,6 @@ .disabled { @extend .component; - opacity: .5; cursor: default; + opacity: .5; } diff --git a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js index 3d8cd47d2a..046617bb9a 100644 --- a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js +++ b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js @@ -5,7 +5,7 @@ import { get } from 'lodash'; import { observer, inject } from 'mobx-react'; import BugReportDialog from '../../../components/profile/bug-report/BugReportDialog'; import type { InjectedProps } from '../../../types/injectedPropsType'; -import { filenameWithTimestamp } from '../../../../../common/fileName'; +import { generateFileNameWithTimestamp } from '../../../../../common/fileName'; const shell = require('electron').shell; @@ -21,7 +21,7 @@ export default class BugReportDialogContainer extends Component { }; onDownload = () => { - const fileName = filenameWithTimestamp(); + const fileName = generateFileNameWithTimestamp(); const destination = remote.dialog.showSaveDialog({ defaultPath: fileName, }); diff --git a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js index ae167a0c7e..d695fb18ad 100644 --- a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js +++ b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js @@ -5,7 +5,7 @@ import { remote } from 'electron'; import SupportSettings from '../../../components/settings/categories/SupportSettings'; import type { InjectedProps } from '../../../types/injectedPropsType'; import BugReportDialog from '../../../components/profile/bug-report/BugReportDialog'; -import { filenameWithTimestamp } from '../../../../../common/fileName'; +import { generateFileNameWithTimestamp } from '../../../../../common/fileName'; const shell = require('electron').shell; @@ -26,7 +26,7 @@ export default class SupportSettingsPage extends Component { }; handleDownloadLogs = () => { - const fileName = filenameWithTimestamp(); + const fileName = generateFileNameWithTimestamp(); const destination = remote.dialog.showSaveDialog({ defaultPath: fileName, }); diff --git a/source/renderer/app/stores/ProfileStore.js b/source/renderer/app/stores/ProfileStore.js index d6fff74e69..5c261723aa 100644 --- a/source/renderer/app/stores/ProfileStore.js +++ b/source/renderer/app/stores/ProfileStore.js @@ -14,7 +14,7 @@ import LocalizableError from '../i18n/LocalizableError'; import globalMessages from '../i18n/global-messages'; import { WalletSupportRequestLogsCompressError } from '../i18n/errors'; import type { LogFiles, CompressedFileDownload } from '../types/LogTypes'; -import { filenameWithTimestamp } from '../../../common/fileName'; +import { generateFileNameWithTimestamp } from '../../../common/fileName'; export default class SettingsStore extends Store { @@ -211,7 +211,7 @@ export default class SettingsStore extends Store { this.compressedFileDownload = { inProgress: true, destination, - fileName + fileName, }; if (this.compressedLog && fresh !== true) { @@ -239,14 +239,14 @@ export default class SettingsStore extends Store { return this._getLogs(); } this.compressedFileDownload = { - fileName: filenameWithTimestamp() + fileName: generateFileNameWithTimestamp(), }; this._compressLogs({ logs: this.logFiles }); }); _compressLogs = action(({ logs }) => { this.isCompressing = true; - const { fileName = filenameWithTimestamp() } = this.compressedFileDownload; + const { fileName = generateFileNameWithTimestamp() } = this.compressedFileDownload; ipcRenderer.send(COMPRESS_LOGS.REQUEST, toJS(logs), fileName); }); @@ -269,7 +269,6 @@ export default class SettingsStore extends Store { problem: string, compressedLog: ?string, }) => { - this.sendBugReport.execute({ email, subject, problem, compressedLog, }) @@ -279,7 +278,6 @@ export default class SettingsStore extends Store { .catch(action((error) => { this.error = error; })); - }); @action _reset = () => { From af76c11a909d0bc422647c8b18a5334448cfb9cf Mon Sep 17 00:00:00 2001 From: nikolaglumac Date: Tue, 10 Jul 2018 13:38:46 +0200 Subject: [PATCH 17/20] [DDW-248] Code style improvements --- source/common/fileName.js | 2 +- source/main/utils/setupLogging.js | 4 ++-- source/renderer/app/api/lib/reportRequest.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/common/fileName.js b/source/common/fileName.js index 163085b106..a02a47550d 100644 --- a/source/common/fileName.js +++ b/source/common/fileName.js @@ -4,5 +4,5 @@ import moment from 'moment'; export const generateFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') => `${prefix}-${moment.utc().format('YYYY-MM-DDTHHmmss.0SSS')}Z.${fileType}`; -export const getFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') => (fileName: string) => +export const isFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') => (fileName: string) => fileName.match(RegExp(`(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}.0[0-9]{3}Z)(.${fileType})`)); diff --git a/source/main/utils/setupLogging.js b/source/main/utils/setupLogging.js index 437155a6e4..9433edaa31 100644 --- a/source/main/utils/setupLogging.js +++ b/source/main/utils/setupLogging.js @@ -4,7 +4,7 @@ import log from 'electron-log'; import moment from 'moment'; import ensureDirectoryExists from './ensureDirectoryExists'; import { pubLogsFolderPath, appLogsFolderPath, APP_NAME } from '../config'; -import { getFileNameWithTimestamp } from '../../common/fileName'; +import { isFileNameWithTimestamp } from '../../common/fileName'; const isTest = process.env.NODE_ENV === 'test'; @@ -25,7 +25,7 @@ export const setupLogging = () => { // Removes existing compressed logs fs.readdir(appLogsFolderPath, (err, files) => { files - .filter(getFileNameWithTimestamp()) + .filter(isFileNameWithTimestamp()) .forEach((logFileName) => { const logFile = path.join(appLogsFolderPath, logFileName); try { diff --git a/source/renderer/app/api/lib/reportRequest.js b/source/renderer/app/api/lib/reportRequest.js index 0d95c479fb..ebbd91f0ec 100644 --- a/source/renderer/app/api/lib/reportRequest.js +++ b/source/renderer/app/api/lib/reportRequest.js @@ -1,7 +1,7 @@ import http from 'http'; import FormData from 'form-data/lib/form_data'; import fs from 'fs'; -import { getFileNameWithTimestamp } from '../../../../common/fileName'; +import { isFileNameWithTimestamp } from '../../../../common/fileName'; export type RequestOptions = { hostname: string, @@ -41,7 +41,7 @@ function typedHttpRequest( // prepare file stream (attachment) if (payload.compressedLog) { const stream = fs.createReadStream(payload.compressedLog); - const [fileName] = getFileNameWithTimestamp()(payload.compressedLog); + const [fileName] = isFileNameWithTimestamp()(payload.compressedLog); formData.append(fileName, stream); } From 27fc61921d535b0c465c3fb8a2793a10d1c67b2d Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Tue, 10 Jul 2018 13:28:28 -0300 Subject: [PATCH 18/20] [DDW-248] Code improvements --- source/common/fileName.js | 7 ++- source/main/utils/setupLogging.js | 4 +- .../renderer/app/actions/profile-actions.js | 2 +- source/renderer/app/api/lib/reportRequest.js | 4 +- .../profile/bug-report/BugReportDialog.js | 41 +++++++--------- .../profile/bug-report/BugReportDialog.scss | 2 +- .../dialogs/BugReportDialogContainer.js | 12 +++-- source/renderer/app/stores/ProfileStore.js | 48 +++++++++++-------- source/renderer/app/types/LogTypes.js | 4 +- 9 files changed, 65 insertions(+), 59 deletions(-) diff --git a/source/common/fileName.js b/source/common/fileName.js index 163085b106..a6f8926414 100644 --- a/source/common/fileName.js +++ b/source/common/fileName.js @@ -4,5 +4,10 @@ import moment from 'moment'; export const generateFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') => `${prefix}-${moment.utc().format('YYYY-MM-DDTHHmmss.0SSS')}Z.${fileType}`; -export const getFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') => (fileName: string) => +export const isFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') => (fileName: string) => fileName.match(RegExp(`(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}.0[0-9]{3}Z)(.${fileType})`)); + +export const getPathSlash = (path: string) => ((path.indexOf('/') > -1) ? '/' : '\\'); + +export const extractFileNameFromPath = (path: string) => + path.substr(path.lastIndexOf(getPathSlash(path)) + 1); diff --git a/source/main/utils/setupLogging.js b/source/main/utils/setupLogging.js index 437155a6e4..9433edaa31 100644 --- a/source/main/utils/setupLogging.js +++ b/source/main/utils/setupLogging.js @@ -4,7 +4,7 @@ import log from 'electron-log'; import moment from 'moment'; import ensureDirectoryExists from './ensureDirectoryExists'; import { pubLogsFolderPath, appLogsFolderPath, APP_NAME } from '../config'; -import { getFileNameWithTimestamp } from '../../common/fileName'; +import { isFileNameWithTimestamp } from '../../common/fileName'; const isTest = process.env.NODE_ENV === 'test'; @@ -25,7 +25,7 @@ export const setupLogging = () => { // Removes existing compressed logs fs.readdir(appLogsFolderPath, (err, files) => { files - .filter(getFileNameWithTimestamp()) + .filter(isFileNameWithTimestamp()) .forEach((logFileName) => { const logFile = path.join(appLogsFolderPath, logFileName); try { diff --git a/source/renderer/app/actions/profile-actions.js b/source/renderer/app/actions/profile-actions.js index 5d2f87a1e6..566c76fd7b 100644 --- a/source/renderer/app/actions/profile-actions.js +++ b/source/renderer/app/actions/profile-actions.js @@ -9,7 +9,7 @@ export default class ProfileActions { getLogs: Action = new Action(); downloadLogs: Action<{ fileName: string, destination: string, fresh?: boolean }> = new Action(); resetBugReportDialog: Action = new Action(); - requestFreshCompressedLogs: Action = new Action(); + getLogsAndCompress: Action = new Action(); sendBugReport: Action<{ email: string, subject: string, problem: string, compressedLog: ?string, }> = new Action(); diff --git a/source/renderer/app/api/lib/reportRequest.js b/source/renderer/app/api/lib/reportRequest.js index 0d95c479fb..e652e10951 100644 --- a/source/renderer/app/api/lib/reportRequest.js +++ b/source/renderer/app/api/lib/reportRequest.js @@ -1,7 +1,7 @@ import http from 'http'; import FormData from 'form-data/lib/form_data'; import fs from 'fs'; -import { getFileNameWithTimestamp } from '../../../../common/fileName'; +import { extractFileNameFromPath } from '../../../../common/fileName'; export type RequestOptions = { hostname: string, @@ -41,7 +41,7 @@ function typedHttpRequest( // prepare file stream (attachment) if (payload.compressedLog) { const stream = fs.createReadStream(payload.compressedLog); - const [fileName] = getFileNameWithTimestamp()(payload.compressedLog); + const fileName = extractFileNameFromPath(payload.compressedLog); formData.append(fileName, stream); } diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.js b/source/renderer/app/components/profile/bug-report/BugReportDialog.js index 579f1c0b42..4380de2da6 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.js +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.js @@ -123,15 +123,15 @@ type Props = { onSubmitManually: Function, onDownload: Function, onGetLogs: Function, - onRequestFreshCompressedLogs: Function, - isDownloading?: boolean, + onGetLogsAndCompress: Function, + isDownloadInProgress?: boolean, + isReportSubmissionInProgress?: boolean, error: ?LocalizableError, }; type State = { showLogs: boolean, compressedLog: ?string, - isSubmitting: boolean }; @observer @@ -144,7 +144,6 @@ export default class BugReportDialog extends Component { state = { showLogs: true, compressedLog: null, - isSubmitting: false, }; componentWillMount() { @@ -152,10 +151,6 @@ export default class BugReportDialog extends Component { } componentWillReceiveProps(nextProps: Object) { - if (!this.props.error && nextProps.error) { - this.setState({ isSubmitting: false }); - } - const commpressionFilesChanged = !this.props.compressedLog && !!nextProps.compressedLog; const { compressedLog } = this.state; @@ -163,7 +158,7 @@ export default class BugReportDialog extends Component { return false; } - if (nextProps.compressedLog && commpressionFilesChanged && !nextProps.isDownloading) { + if (nextProps.compressedLog && commpressionFilesChanged && !nextProps.isDownloadInProgress) { this.setState({ compressedLog: nextProps.compressedLog }, this.submit); } } @@ -215,16 +210,14 @@ export default class BugReportDialog extends Component { }); submit = () => { - this.setState({ isSubmitting: true }); - - const { showLogs, compressedLog } = this.state; - if (showLogs && !compressedLog) { - this.props.onRequestFreshCompressedLogs(); - return false; - } this.form.submit({ onSuccess: (form) => { + const { showLogs, compressedLog } = this.state; + if (showLogs && !compressedLog) { + this.props.onGetLogsAndCompress(); + return false; + } const { email, subject, problem } = form.values(); const data = { email, subject, problem, compressedLog @@ -239,14 +232,14 @@ export default class BugReportDialog extends Component { this.setState({ showLogs: value }); }; - onClose = () => !this.state.isSubmitting && this.props.onCancel(); + onClose = () => !this.props.isReportSubmissionInProgress && this.props.onCancel(); render() { const { intl } = this.context; - const { showLogs, isSubmitting } = this.state; + const { showLogs } = this.state; const { form } = this; const { - logFiles, error, onDownload, isDownloading, + logFiles, error, onDownload, isDownloadInProgress, isReportSubmissionInProgress } = this.props; const submitManuallyLink = intl.formatMessage(messages.submitManuallyLink); @@ -262,12 +255,12 @@ export default class BugReportDialog extends Component { const submitButtonClasses = classnames([ 'submitButton', - isSubmitting ? styles.isSubmitting : null, + isReportSubmissionInProgress ? styles.isReportSubmissionInProgress : null, ]); const downloadButtonClasses = classnames([ 'downloadButton', - isDownloading ? styles.isSubmitting : null, + isDownloadInProgress ? styles.isReportSubmissionInProgress : null, ]); const emailField = form.$('email'); @@ -279,7 +272,7 @@ export default class BugReportDialog extends Component { className: submitButtonClasses, label: this.context.intl.formatMessage(messages.submitButtonLabel), primary: true, - disabled: isSubmitting, + disabled: isReportSubmissionInProgress, onClick: this.submit, }, ]; @@ -289,7 +282,7 @@ export default class BugReportDialog extends Component { className: downloadButtonClasses, label: this.context.intl.formatMessage(messages.downloadButtonLabel), primary: true, - disabled: isDownloading, + disabled: isDownloadInProgress, onClick: onDownload.bind(this), }, { @@ -307,7 +300,7 @@ export default class BugReportDialog extends Component { actions={!error ? actions : alternativeActions} closeOnOverlayClick onClose={this.onClose} - closeButton={} + closeButton={} > {error ? (
diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.scss b/source/renderer/app/components/profile/bug-report/BugReportDialog.scss index cb4fd6b7fd..0731033018 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.scss +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.scss @@ -97,6 +97,6 @@ text-align: left; } -.isSubmitting { +.isReportSubmissionInProgress { @include loading-spinner("../../../assets/images/spinner-light.svg"); } diff --git a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js index 046617bb9a..c5f37dbce5 100644 --- a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js +++ b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js @@ -40,17 +40,19 @@ export default class BugReportDialogContainer extends Component { render() { const { actions, stores } = this.props; - const { getLogs, requestFreshCompressedLogs } = actions.profile; + const { getLogs, getLogsAndCompress } = actions.profile; const { logFiles, compressedLog, - compressedFileDownload, + compressedLogsFile, + bugReportInProgress, error, } = stores.profile; return ( { onSubmitManually={this.onSubmitManually} onDownload={this.onDownload} onCancel={this.resetBugReportDialog} - onRequestFreshCompressedLogs={(logs) => { - requestFreshCompressedLogs.trigger({ logs }); + onGetLogsAndCompress={(logs) => { + getLogsAndCompress.trigger({ logs }); }} onGetLogs={() => { getLogs.trigger(); diff --git a/source/renderer/app/stores/ProfileStore.js b/source/renderer/app/stores/ProfileStore.js index 5c261723aa..c77fc42a2d 100644 --- a/source/renderer/app/stores/ProfileStore.js +++ b/source/renderer/app/stores/ProfileStore.js @@ -13,7 +13,7 @@ import { GET_LOGS, DOWNLOAD_LOGS, COMPRESS_LOGS } from '../../../common/ipc-api' import LocalizableError from '../i18n/LocalizableError'; import globalMessages from '../i18n/global-messages'; import { WalletSupportRequestLogsCompressError } from '../i18n/errors'; -import type { LogFiles, CompressedFileDownload } from '../types/LogTypes'; +import type { LogFiles, CompressedLogsFile } from '../types/LogTypes'; import { generateFileNameWithTimestamp } from '../../../common/fileName'; export default class SettingsStore extends Store { @@ -48,7 +48,8 @@ export default class SettingsStore extends Store { @observable logFiles: LogFiles = {}; @observable compressedLog: ?string = null; @observable isCompressing: boolean = false; - @observable compressedFileDownload: CompressedFileDownload = {}; + @observable compressedLogsFile: CompressedLogsFile = {}; + @observable bugReportInProgress: boolean = false; /* eslint-enable max-len */ setup() { @@ -58,7 +59,7 @@ export default class SettingsStore extends Store { this.actions.profile.getLogs.listen(this._getLogs); this.actions.profile.resetBugReportDialog.listen(this._resetBugReportDialog); this.actions.profile.downloadLogs.listen(this._downloadLogs); - this.actions.profile.requestFreshCompressedLogs.listen(this._requestFreshCompressedLogs); + this.actions.profile.getLogsAndCompress.listen(this._getLogsAndCompress); this.actions.profile.compressLogs.listen(this._compressLogs); this.actions.profile.sendBugReport.listen(this._sendBugReport); ipcRenderer.on(GET_LOGS.SUCCESS, this._onGetLogsSuccess); @@ -208,8 +209,8 @@ export default class SettingsStore extends Store { }; _downloadLogs = action(({ fileName, destination, fresh }) => { - this.compressedFileDownload = { - inProgress: true, + this.compressedLogsFile = { + downloadInProgress: true, destination, fileName, }; @@ -223,43 +224,45 @@ export default class SettingsStore extends Store { } }); + _getLogsAndCompress = action(() => { + this.compressedLogsFile = { + fileName: generateFileNameWithTimestamp(), + }; + + this.bugReportInProgress = true; + + this._getLogs(); + }); + _onGetLogsSuccess = action((event, res) => { this.logFiles = res; - if (this.compressedFileDownload.inProgress) { + const { downloadInProgress } = this.compressedLogsFile; + if (downloadInProgress || this.bugReportInProgress) { this._compressLogs({ logs: res }); } }); _onDownloadLogsSuccess = action(() => { - this.compressedFileDownload = {}; - }); - - _requestFreshCompressedLogs = action(() => { - if (!this.logFiles) { - return this._getLogs(); - } - this.compressedFileDownload = { - fileName: generateFileNameWithTimestamp(), - }; - this._compressLogs({ logs: this.logFiles }); + this.compressedLogsFile = {}; }); _compressLogs = action(({ logs }) => { this.isCompressing = true; - const { fileName = generateFileNameWithTimestamp() } = this.compressedFileDownload; + const { fileName = generateFileNameWithTimestamp() } = this.compressedLogsFile; ipcRenderer.send(COMPRESS_LOGS.REQUEST, toJS(logs), fileName); }); _onCompressLogsSuccess = action((event, res) => { this.isCompressing = false; this.compressedLog = res; - const { inProgress, destination, fileName } = this.compressedFileDownload; - if (inProgress) { + const { downloadInProgress, destination, fileName } = this.compressedLogsFile; + if (downloadInProgress) { this._downloadLogs({ destination, fileName }); } }); _onCompressLogsError = action(() => { + this.bugReportInProgress = false; this.error = new WalletSupportRequestLogsCompressError(); }); @@ -269,6 +272,7 @@ export default class SettingsStore extends Store { problem: string, compressedLog: ?string, }) => { + this.bugReportInProgress = true; this.sendBugReport.execute({ email, subject, problem, compressedLog, }) @@ -276,6 +280,7 @@ export default class SettingsStore extends Store { this._resetBugReportDialog(); })) .catch(action((error) => { + this.bugReportInProgress = false; this.error = error; })); }); @@ -283,6 +288,7 @@ export default class SettingsStore extends Store { @action _reset = () => { this.error = null; this.compressedLog = null; - this.compressedFileDownload = {}; + this.compressedLogsFile = {}; + this.bugReportInProgress = false; }; } diff --git a/source/renderer/app/types/LogTypes.js b/source/renderer/app/types/LogTypes.js index 138ab2cc84..86696be762 100644 --- a/source/renderer/app/types/LogTypes.js +++ b/source/renderer/app/types/LogTypes.js @@ -10,8 +10,8 @@ export type CompressedLogs = { originalFile: string, } | {}; -export type CompressedFileDownload = { +export type CompressedLogsFile = { fileName?: string, destination?: string, - inProgress?: boolean, + downloadInProgress?: boolean, }; From d68a72412eee76787df14fb90749004afbe1d648 Mon Sep 17 00:00:00 2001 From: nikolaglumac Date: Thu, 12 Jul 2018 12:14:15 +0200 Subject: [PATCH 19/20] [DDW-248] Code style improvements --- .../renderer/app/actions/profile-actions.js | 7 +- .../renderer/app/api/ada/sendAdaBugReport.js | 6 +- .../renderer/app/api/etc/sendEtcBugReport.js | 6 +- source/renderer/app/api/lib/reportRequest.js | 6 +- .../profile/bug-report/BugReportDialog.js | 58 ++++---- .../profile/bug-report/BugReportDialog.scss | 2 +- .../settings/categories/SupportSettings.scss | 1 - .../dialogs/BugReportDialogContainer.js | 12 +- source/renderer/app/stores/ProfileStore.js | 132 +++++++++--------- source/renderer/app/types/LogTypes.js | 4 +- 10 files changed, 118 insertions(+), 116 deletions(-) diff --git a/source/renderer/app/actions/profile-actions.js b/source/renderer/app/actions/profile-actions.js index 566c76fd7b..6d0b7a90c7 100644 --- a/source/renderer/app/actions/profile-actions.js +++ b/source/renderer/app/actions/profile-actions.js @@ -5,14 +5,13 @@ import Action from './lib/Action'; export default class ProfileActions { acceptTermsOfUse: Action = new Action(); - compressLogs: Action<{ logs: Object }> = new Action(); getLogs: Action = new Action(); - downloadLogs: Action<{ fileName: string, destination: string, fresh?: boolean }> = new Action(); - resetBugReportDialog: Action = new Action(); getLogsAndCompress: Action = new Action(); sendBugReport: Action<{ - email: string, subject: string, problem: string, compressedLog: ?string, + email: string, subject: string, problem: string, compressedLogsFile: ?string, }> = new Action(); + resetBugReportDialog: Action = new Action(); + downloadLogs: Action<{ fileName: string, destination: string, fresh?: boolean }> = new Action(); updateLocale: Action<{ locale: string }> = new Action(); updateTheme: Action<{ theme: string }> = new Action(); } diff --git a/source/renderer/app/api/ada/sendAdaBugReport.js b/source/renderer/app/api/ada/sendAdaBugReport.js index 0beac6b649..9c9590f4d8 100644 --- a/source/renderer/app/api/ada/sendAdaBugReport.js +++ b/source/renderer/app/api/ada/sendAdaBugReport.js @@ -9,7 +9,7 @@ export type SendAdaBugReportRequestParams = { email: string, subject: string, problem: string, - compressedLog: string, + compressedLogsFile: string, }, application: string, }; @@ -17,7 +17,7 @@ export type SendAdaBugReportRequestParams = { export const sendAdaBugReport = ( { requestFormData, application }: SendAdaBugReportRequestParams ): Promise<{}> => { - const { email, subject, problem, compressedLog } = requestFormData; + const { email, subject, problem, compressedLogsFile } = requestFormData; const reportUrl = url.parse(environment.REPORT_URL); let platform; @@ -45,7 +45,7 @@ export const sendAdaBugReport = ( version: environment.version, build: environment.build, os: platform, - compressedLog, + compressedLogsFile, date: moment().format('YYYY-MM-DDTHH:mm:ss'), magic: 2000000000, type: { diff --git a/source/renderer/app/api/etc/sendEtcBugReport.js b/source/renderer/app/api/etc/sendEtcBugReport.js index 1ebca02ee1..45b9652c3f 100644 --- a/source/renderer/app/api/etc/sendEtcBugReport.js +++ b/source/renderer/app/api/etc/sendEtcBugReport.js @@ -9,7 +9,7 @@ export type SendEtcBugReportRequestParams = { email: string, subject: string, problem: string, - compressedLog: string, + compressedLogsFile: string, }, application: string, }; @@ -17,7 +17,7 @@ export type SendEtcBugReportRequestParams = { export const sendEtcBugReport = ( { requestFormData, application }: SendEtcBugReportRequestParams ): Promise<{}> => { - const { email, subject, problem, compressedLog } = requestFormData; + const { email, subject, problem, compressedLogsFile } = requestFormData; const reportUrl = url.parse(environment.REPORT_URL); let platform; @@ -45,7 +45,7 @@ export const sendEtcBugReport = ( version: environment.version, build: environment.build, os: platform, - compressedLog, + compressedLogsFile, date: moment().format('YYYY-MM-DDTHH:mm:ss'), magic: 2000000000, type: { diff --git a/source/renderer/app/api/lib/reportRequest.js b/source/renderer/app/api/lib/reportRequest.js index e652e10951..405b55f5d8 100644 --- a/source/renderer/app/api/lib/reportRequest.js +++ b/source/renderer/app/api/lib/reportRequest.js @@ -39,9 +39,9 @@ function typedHttpRequest( formData.append('payload', JSON.stringify(payload)); // prepare file stream (attachment) - if (payload.compressedLog) { - const stream = fs.createReadStream(payload.compressedLog); - const fileName = extractFileNameFromPath(payload.compressedLog); + if (payload.compressedLogsFile) { + const stream = fs.createReadStream(payload.compressedLogsFile); + const fileName = extractFileNameFromPath(payload.compressedLogsFile); formData.append(fileName, stream); } diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.js b/source/renderer/app/components/profile/bug-report/BugReportDialog.js index f43db4d9f0..a370aa095e 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.js +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.js @@ -124,14 +124,14 @@ type Props = { onDownload: Function, onGetLogs: Function, onGetLogsAndCompress: Function, - isDownloadInProgress?: boolean, - isReportSubmissionInProgress?: boolean, + isDownloading?: boolean, + isSubmittingBugReport?: boolean, error: ?LocalizableError, }; type State = { - showLogs: boolean, - compressedLog: ?string, + attachLogs: boolean, + compressedLogsFile: ?string, }; @observer @@ -142,8 +142,8 @@ export default class BugReportDialog extends Component { }; state = { - showLogs: true, - compressedLog: null, + attachLogs: true, + compressedLogsFile: null, }; componentWillMount() { @@ -151,15 +151,14 @@ export default class BugReportDialog extends Component { } componentWillReceiveProps(nextProps: Object) { - const commpressionFilesChanged = !this.props.compressedLog && !!nextProps.compressedLog; - const { compressedLog } = this.state; - - if (compressedLog) { - return false; - } - - if (nextProps.compressedLog && commpressionFilesChanged && !nextProps.isDownloadInProgress) { - this.setState({ compressedLog: nextProps.compressedLog }, this.submit); + const compressedLogsFileChanged = ( + !this.props.compressedLogsFile && + !!nextProps.compressedLogsFile + ); + const { compressedLogsFile } = this.state; + if (compressedLogsFile) return false; + if (nextProps.compressedLogsFile && compressedLogsFileChanged && !nextProps.isDownloading) { + this.setState({ compressedLogsFile: nextProps.compressedLogsFile }, this.submit); } } @@ -210,17 +209,16 @@ export default class BugReportDialog extends Component { }); submit = () => { - this.form.submit({ onSuccess: (form) => { - const { showLogs, compressedLog } = this.state; - if (showLogs && !compressedLog) { + const { attachLogs, compressedLogsFile } = this.state; + if (attachLogs && !compressedLogsFile) { this.props.onGetLogsAndCompress(); return false; } const { email, subject, problem } = form.values(); const data = { - email, subject, problem, compressedLog + email, subject, problem, compressedLogsFile }; this.props.onSubmit(data); }, @@ -229,17 +227,17 @@ export default class BugReportDialog extends Component { }; handleLogsSwitchToggle = (value: boolean) => { - this.setState({ showLogs: value }); + this.setState({ attachLogs: value }); }; - onClose = () => !this.props.isReportSubmissionInProgress && this.props.onCancel(); + onClose = () => !this.props.isSubmittingBugReport && this.props.onCancel(); render() { const { intl } = this.context; - const { showLogs } = this.state; + const { attachLogs } = this.state; const { form } = this; const { - logFiles, error, onDownload, isDownloadInProgress, isReportSubmissionInProgress + logFiles, error, onDownload, isDownloading, isSubmittingBugReport } = this.props; const submitManuallyLink = intl.formatMessage(messages.submitManuallyLink); @@ -250,17 +248,17 @@ export default class BugReportDialog extends Component { const attachedLogsClasses = classnames([ styles.attachedLogs, - (showLogs && logFiles) ? styles.show : null, + (attachLogs && logFiles) ? styles.show : null, ]); const submitButtonClasses = classnames([ 'submitButton', - isReportSubmissionInProgress ? styles.isReportSubmissionInProgress : null, + isSubmittingBugReport ? styles.isSubmitting : null, ]); const downloadButtonClasses = classnames([ 'downloadButton', - isDownloadInProgress ? styles.isReportSubmissionInProgress : null, + isDownloading ? styles.isSubmitting : null, ]); const emailField = form.$('email'); @@ -272,7 +270,7 @@ export default class BugReportDialog extends Component { className: submitButtonClasses, label: this.context.intl.formatMessage(messages.submitButtonLabel), primary: true, - disabled: isReportSubmissionInProgress, + disabled: isSubmittingBugReport, onClick: this.submit, }, ]; @@ -282,7 +280,7 @@ export default class BugReportDialog extends Component { className: downloadButtonClasses, label: this.context.intl.formatMessage(messages.downloadButtonLabel), primary: true, - disabled: isDownloadInProgress, + disabled: isDownloading, onClick: onDownload.bind(this), }, { @@ -302,7 +300,7 @@ export default class BugReportDialog extends Component { onClose={this.onClose} closeButton={ } @@ -361,7 +359,7 @@ export default class BugReportDialog extends Component { } />
diff --git a/source/renderer/app/components/profile/bug-report/BugReportDialog.scss b/source/renderer/app/components/profile/bug-report/BugReportDialog.scss index 0731033018..cb4fd6b7fd 100644 --- a/source/renderer/app/components/profile/bug-report/BugReportDialog.scss +++ b/source/renderer/app/components/profile/bug-report/BugReportDialog.scss @@ -97,6 +97,6 @@ text-align: left; } -.isReportSubmissionInProgress { +.isSubmitting { @include loading-spinner("../../../assets/images/spinner-light.svg"); } diff --git a/source/renderer/app/components/settings/categories/SupportSettings.scss b/source/renderer/app/components/settings/categories/SupportSettings.scss index da570b777b..8111a3fa51 100644 --- a/source/renderer/app/components/settings/categories/SupportSettings.scss +++ b/source/renderer/app/components/settings/categories/SupportSettings.scss @@ -32,7 +32,6 @@ button { cursor: pointer; - letter-spacing: 1px; } p { diff --git a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js index c5f37dbce5..c2ccf713f6 100644 --- a/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js +++ b/source/renderer/app/containers/profile/dialogs/BugReportDialogContainer.js @@ -15,7 +15,7 @@ export default class BugReportDialogContainer extends Component { static defaultProps = { actions: null, stores: null }; onSubmit = (values: { - email: string, subject: string, problem: string, compressedLog: ?string + email: string, subject: string, problem: string, compressedLogsFile: ?string }) => { this.props.actions.profile.sendBugReport.trigger(values); }; @@ -43,18 +43,18 @@ export default class BugReportDialogContainer extends Component { const { getLogs, getLogsAndCompress } = actions.profile; const { logFiles, - compressedLog, compressedLogsFile, - bugReportInProgress, + compressedLogsStatus, + isSubmittingBugReport, error, } = stores.profile; return ( = new Request(this.api[environment.API].sendBugReport); @observable error: ?LocalizableError = null; @observable logFiles: LogFiles = {}; - @observable compressedLog: ?string = null; - @observable isCompressing: boolean = false; - @observable compressedLogsFile: CompressedLogsFile = {}; - @observable bugReportInProgress: boolean = false; + @observable compressedLogsFile: ?string = null; + @observable compressedLogsStatus: CompressedLogStatus = {}; + @observable isSubmittingBugReport: boolean = false; /* eslint-enable max-len */ setup() { @@ -57,11 +56,10 @@ export default class SettingsStore extends Store { this.actions.profile.acceptTermsOfUse.listen(this._acceptTermsOfUse); this.actions.profile.updateTheme.listen(this._updateTheme); this.actions.profile.getLogs.listen(this._getLogs); - this.actions.profile.resetBugReportDialog.listen(this._resetBugReportDialog); - this.actions.profile.downloadLogs.listen(this._downloadLogs); this.actions.profile.getLogsAndCompress.listen(this._getLogsAndCompress); - this.actions.profile.compressLogs.listen(this._compressLogs); this.actions.profile.sendBugReport.listen(this._sendBugReport); + this.actions.profile.resetBugReportDialog.listen(this._resetBugReportDialog); + this.actions.profile.downloadLogs.listen(this._downloadLogs); ipcRenderer.on(GET_LOGS.SUCCESS, this._onGetLogsSuccess); ipcRenderer.on(DOWNLOAD_LOGS.SUCCESS, this._onDownloadLogsSuccess); ipcRenderer.on(COMPRESS_LOGS.SUCCESS, this._onCompressLogsSuccess); @@ -97,12 +95,16 @@ export default class SettingsStore extends Store { @computed get hasLoadedCurrentLocale(): boolean { return ( - this.getProfileLocaleRequest.wasExecuted && this.getProfileLocaleRequest.result !== null + this.getProfileLocaleRequest.wasExecuted && + this.getProfileLocaleRequest.result !== null ); } @computed get isCurrentLocaleSet(): boolean { - return (this.getProfileLocaleRequest.result !== null && this.getProfileLocaleRequest.result !== ''); + return ( + this.getProfileLocaleRequest.result !== null && + this.getProfileLocaleRequest.result !== '' + ); } @computed get currentTheme(): string { @@ -115,11 +117,17 @@ export default class SettingsStore extends Store { } @computed get isCurrentThemeSet(): boolean { - return (this.getThemeRequest.result !== null && this.getThemeRequest.result !== ''); + return ( + this.getThemeRequest.result !== null && + this.getThemeRequest.result !== '' + ); } @computed get hasLoadedCurrentTheme(): boolean { - return (this.getThemeRequest.wasExecuted && this.getThemeRequest.result !== null); + return ( + this.getThemeRequest.wasExecuted && + this.getThemeRequest.result !== null + ); } @computed get termsOfUse(): string { @@ -140,7 +148,10 @@ export default class SettingsStore extends Store { @computed get isSettingsPage(): boolean { const { currentRoute } = this.stores.app; - return includes(ROUTES.PROFILE, currentRoute) || includes(ROUTES.SETTINGS, currentRoute); + return ( + includes(ROUTES.PROFILE, currentRoute) || + includes(ROUTES.SETTINGS, currentRoute) + ); } _updateLocale = async ({ locale }: { locale: string }) => { @@ -203,92 +214,87 @@ export default class SettingsStore extends Store { ipcRenderer.send(GET_LOGS.REQUEST); }; - _resetBugReportDialog = () => { - this._reset(); - this.actions.dialogs.closeActiveDialog.trigger(); - }; - - _downloadLogs = action(({ fileName, destination, fresh }) => { - this.compressedLogsFile = { - downloadInProgress: true, - destination, - fileName, - }; - - if (this.compressedLog && fresh !== true) { - // logs already compressed, trigger download - ipcRenderer.send(DOWNLOAD_LOGS.REQUEST, this.compressedLog, destination); - } else { - // start process: getLogs -> compressLogs -> downloadLogs (again) - this._getLogs(); + _onGetLogsSuccess = action((event, files) => { + this.logFiles = files; + const { isDownloading } = this.compressedLogsStatus; + if (isDownloading || this.isSubmittingBugReport) { + this._compressLogs({ logs: files }); } }); _getLogsAndCompress = action(() => { - this.compressedLogsFile = { + this.compressedLogsStatus = { fileName: generateFileNameWithTimestamp(), }; - - this.bugReportInProgress = true; - + this.isSubmittingBugReport = true; this._getLogs(); }); - _onGetLogsSuccess = action((event, res) => { - this.logFiles = res; - const { downloadInProgress } = this.compressedLogsFile; - if (downloadInProgress || this.bugReportInProgress) { - this._compressLogs({ logs: res }); - } - }); - - _onDownloadLogsSuccess = action(() => { - this.compressedLogsFile = {}; - }); - _compressLogs = action(({ logs }) => { - this.isCompressing = true; - const { fileName = generateFileNameWithTimestamp() } = this.compressedLogsFile; + const { fileName = generateFileNameWithTimestamp() } = this.compressedLogsStatus; ipcRenderer.send(COMPRESS_LOGS.REQUEST, toJS(logs), fileName); }); - _onCompressLogsSuccess = action((event, res) => { - this.isCompressing = false; - this.compressedLog = res; - const { downloadInProgress, destination, fileName } = this.compressedLogsFile; - if (downloadInProgress) { + _onCompressLogsSuccess = action((event, file) => { + this.compressedLogsFile = file; + const { isDownloading, destination, fileName } = this.compressedLogsStatus; + if (isDownloading) { this._downloadLogs({ destination, fileName }); } }); _onCompressLogsError = action(() => { - this.bugReportInProgress = false; + this.isSubmittingBugReport = false; this.error = new WalletSupportRequestLogsCompressError(); }); - _sendBugReport = action(({ email, subject, problem, compressedLog } : { + _sendBugReport = action(({ email, subject, problem, compressedLogsFile } : { email: string, subject: string, problem: string, - compressedLog: ?string, + compressedLogsFile: ?string, }) => { - this.bugReportInProgress = true; + this.isSubmittingBugReport = true; this.sendBugReport.execute({ - email, subject, problem, compressedLog, + email, subject, problem, compressedLogsFile, }) .then(action(() => { this._resetBugReportDialog(); })) .catch(action((error) => { - this.bugReportInProgress = false; + this.isSubmittingBugReport = false; this.error = error; })); }); + _resetBugReportDialog = () => { + this._reset(); + this.actions.dialogs.closeActiveDialog.trigger(); + }; + + _downloadLogs = action(({ fileName, destination, fresh }) => { + this.compressedLogsStatus = { + isDownloading: true, + destination, + fileName, + }; + if (this.compressedLogsFile && fresh !== true) { + // logs already compressed, trigger the download + ipcRenderer.send(DOWNLOAD_LOGS.REQUEST, this.compressedLogsFile, destination); + } else { + // start process: getLogs -> compressLogs -> downloadLogs (again) + this._getLogs(); + } + }); + + _onDownloadLogsSuccess = action(() => { + this.compressedLogsStatus = {}; + }); + @action _reset = () => { this.error = null; - this.compressedLog = null; - this.compressedLogsFile = {}; - this.bugReportInProgress = false; + this.compressedLogsFile = null; + this.compressedLogsStatus = {}; + this.isSubmittingBugReport = false; }; } diff --git a/source/renderer/app/types/LogTypes.js b/source/renderer/app/types/LogTypes.js index 86696be762..2e256dd61c 100644 --- a/source/renderer/app/types/LogTypes.js +++ b/source/renderer/app/types/LogTypes.js @@ -10,8 +10,8 @@ export type CompressedLogs = { originalFile: string, } | {}; -export type CompressedLogsFile = { +export type CompressedLogStatus = { fileName?: string, destination?: string, - downloadInProgress?: boolean, + isDownloading?: boolean, }; From 715dc6e08191049ecea235fc799218f1c55a8345 Mon Sep 17 00:00:00 2001 From: nikolaglumac Date: Thu, 12 Jul 2018 13:36:54 +0200 Subject: [PATCH 20/20] [DDW-245] Fix failing acceptance tests --- features/step_definitions/wallets-steps.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/step_definitions/wallets-steps.js b/features/step_definitions/wallets-steps.js index 2f10d0b906..7ec1b42daf 100644 --- a/features/step_definitions/wallets-steps.js +++ b/features/step_definitions/wallets-steps.js @@ -272,7 +272,7 @@ When(/^I see the create wallet recovery phrase entry dialog$/, function () { When(/^I click on recovery phrase mnemonics in correct order$/, async function () { for (let i = 0; i < this.recoveryPhrase.length; i++) { const recoveryPhraseMnemonic = this.recoveryPhrase[i]; - await this.waitAndClick(`//button[contains(text(), "${recoveryPhraseMnemonic}") and @class="flat MnemonicWord_component MnemonicWord_active SimpleButton_root"]`); + await this.waitAndClick(`//button[contains(text(), "${recoveryPhraseMnemonic}") and @class="flat SimpleButton_root MnemonicWord_root"]`); } });