From 184fdc8fde404b3af91bf24475658dc4b25ccb9a Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Wed, 11 Sep 2019 11:01:10 +0200 Subject: [PATCH 1/3] [DDW-754] Use new numeric input (#1511) * [DDW-754] integrate new numeric input into Daedalus * [DDW-800] speedup storybook compilation * [DDW-800] fix stylelint issue * [DDW-800] try auto dll plugin for storybook * [DDW-800] configure auto dll plugin for storybook * [DDW-800] reactivate all stories * fix unrelated stylelint issue * [DDW-754] update to react-polymorph@0.9.0-rc.2 * [DDW-754] Add changelog entry * [DDW-754] update to react-polymorph@0.9.0-rc.3 * [DDW-754] update to react-polymorph@0.9.0-rc.4 * [DDW-754] Update CHANGELOG * [DDW-754] update to react-polymorph@0.9.0-rc.5 * [DDW-754] fix send money acceptance test * [DDW-754] Update to react-polymorph@0.9.0-rc.7 * [DDW-754] update to react-polymorph@0.9.0-rc.8 * [DDW-754] fix stylelint issue * [DDW-754] update to react-polymorph@0.9.0-rc.9 * [DDW-754] Update to react-polymorph@0.9.0-rc.10 * [DDW-754] Disallow signs for amount input * [DDW-754] Update to react-polymorph@0.9.0-rc.15 * [DDW-754] Fix failing acceptance tests, Run translation manager --- CHANGELOG.md | 1 + features/send-money-to-receiver.feature | 10 ++-- .../tests/e2e/steps/select-language-steps.js | 2 +- features/tests/e2e/steps/settings-steps.js | 2 +- package.json | 2 +- .../AutomaticUpdateNotification.scss | 2 +- .../app/components/wallet/WalletSendForm.js | 21 ++++---- source/renderer/app/i18n/locales/de-DE.json | 2 +- .../app/i18n/locales/defaultMessages.json | 48 +++++++++---------- source/renderer/app/i18n/locales/en-US.json | 2 +- source/renderer/app/i18n/locales/hr-HR.json | 2 +- source/renderer/app/i18n/locales/ko-KR.json | 2 +- source/renderer/app/i18n/locales/zh-CN.json | 2 +- yarn.lock | 6 +-- 14 files changed, 53 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f54823afe..2cf09f9881 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ Changelog ### Chores +- Use improved `NumericInput` component of `React-Polymorph` v0.9.0 ([1511](https://github.com/input-output-hk/daedalus/pull/1511)) - Added minimum heights of main app window for different environments (Windows, Linux, MacOS) ([1485](https://github.com/input-output-hk/daedalus/pull/1485)) - Removed "Ada Redemption" feature ([PR 1510](https://github.com/input-output-hk/daedalus/pull/1510)) - Changed `themes:check` to `themes:check:createTheme` and added a 4 part "Theme Management in Daedalus" tutorial series to a README document in the themes directory ([PR 1525](https://github.com/input-output-hk/daedalus/pull/1525)) diff --git a/features/send-money-to-receiver.feature b/features/send-money-to-receiver.feature index 08f54e5970..0b4d12a004 100644 --- a/features/send-money-to-receiver.feature +++ b/features/send-money-to-receiver.feature @@ -61,10 +61,10 @@ Feature: Send Money to Receiver | title | amount | | my transaction | | Then I should see the following error messages on the wallet send form: - | message | - | wallet.send.form.errors.invalidAmount | + | message | + | | Examples: - | WRONG_AMOUNT | - | 45000000001 | - | 0 | + | WRONG_AMOUNT | ERROR | + | 99999999 | api.errors.NotEnoughFundsForTransactionError | + | 0 | wallet.send.form.errors.invalidAmount | diff --git a/features/tests/e2e/steps/select-language-steps.js b/features/tests/e2e/steps/select-language-steps.js index eef7355cf0..ad55213a70 100644 --- a/features/tests/e2e/steps/select-language-steps.js +++ b/features/tests/e2e/steps/select-language-steps.js @@ -28,7 +28,7 @@ When(/^I open language selection dropdown$/, function() { When(/^I select Japanese language$/, function() { return this.waitAndClick( - '//*[@class="SimpleOptions_label"][contains(text(), "Japanese")]' + '//*[@class="SimpleOptions_option"]//*[contains(text(), "Japanese")]' ); }); diff --git a/features/tests/e2e/steps/settings-steps.js b/features/tests/e2e/steps/settings-steps.js index e2723c5a2a..324b65d81d 100644 --- a/features/tests/e2e/steps/settings-steps.js +++ b/features/tests/e2e/steps/settings-steps.js @@ -103,7 +103,7 @@ When( When(/^I select "Strict" assurance level$/, function() { return this.waitAndClick( - '//*[@class="SimpleOptions_label"][contains(text(), "Strict")]' + '//*[@class="SimpleOptions_option"]//*[contains(text(), "Strict")]' ); }); diff --git a/package.json b/package.json index e561314399..06f1f845f6 100644 --- a/package.json +++ b/package.json @@ -176,7 +176,7 @@ "react-lottie": "1.2.3", "react-markdown": "3.1.0", "react-number-format": "3.0.3", - "react-polymorph": "0.8.7", + "react-polymorph": "0.9.0-rc.15", "react-router": "3.2.1", "react-svg-inline": "2.1.0", "react-virtualized": "9.21.0", diff --git a/source/renderer/app/components/notifications/AutomaticUpdateNotification.scss b/source/renderer/app/components/notifications/AutomaticUpdateNotification.scss index 41de3d1a1a..9fd4454679 100644 --- a/source/renderer/app/components/notifications/AutomaticUpdateNotification.scss +++ b/source/renderer/app/components/notifications/AutomaticUpdateNotification.scss @@ -87,9 +87,9 @@ font-size: 14px; margin: 20px auto 0; &:hover { - color: var(--theme-automatic-update-overlay-button-label-color); border-bottom: 1px solid var(--theme-automatic-update-overlay-button-label-color); + color: var(--theme-automatic-update-overlay-button-label-color); } } } diff --git a/source/renderer/app/components/wallet/WalletSendForm.js b/source/renderer/app/components/wallet/WalletSendForm.js index be31856313..37b070accd 100755 --- a/source/renderer/app/components/wallet/WalletSendForm.js +++ b/source/renderer/app/components/wallet/WalletSendForm.js @@ -20,7 +20,6 @@ import globalMessages from '../../i18n/global-messages'; import WalletSendConfirmationDialog from './WalletSendConfirmationDialog'; import WalletSendConfirmationDialogContainer from '../../containers/wallet/dialogs/WalletSendConfirmationDialogContainer'; import { - formattedAmountToBigNumber, formattedAmountToNaturalUnits, formattedAmountToLovelace, } from '../../utils/formatters'; @@ -207,17 +206,17 @@ export default class WalletSendForm extends Component { placeholder: `0.${'0'.repeat( this.props.currencyMaxFractionalDigits )}`, - value: '', + value: null, validators: [ async ({ field, form }) => { - const amountValue = field.value; - if (amountValue === '') { + if (field.value === null) { this._resetTransactionFee(); return [ false, this.context.intl.formatMessage(messages.fieldIsRequired), ]; } + const amountValue = field.value.toString(); const isValid = await this.props.validateAmount( formattedAmountToNaturalUnits(amountValue) ); @@ -252,7 +251,6 @@ export default class WalletSendForm extends Component { const { intl } = this.context; const { currencyUnit, - currencyMaxIntegerDigits, currencyMaxFractionalDigits, isDialogOpen, isRestoreActive, @@ -267,7 +265,8 @@ export default class WalletSendForm extends Component { const receiverField = form.$('receiver'); const receiverFieldProps = receiverField.bind(); const amountFieldProps = amountField.bind(); - const amount = formattedAmountToBigNumber(amountFieldProps.value); + + const amount = new BigNumber(amountFieldProps.value || 0); let fees = null; let total = null; @@ -310,12 +309,13 @@ export default class WalletSendForm extends Component { {...amountFieldProps} className="amount" label={intl.formatMessage(messages.amountLabel)} - maxBeforeDot={currencyMaxIntegerDigits} - maxAfterDot={currencyMaxFractionalDigits} + numberLocaleOptions={{ + minimumFractionDigits: currencyMaxFractionalDigits, + }} error={transactionFeeError || amountField.error} onChange={value => { this._isCalculatingFee = true; - amountField.onChange(value || ''); + amountField.onChange(value); }} // AmountInputSkin props currency={currencyUnit} @@ -323,6 +323,7 @@ export default class WalletSendForm extends Component { total={total} skin={AmountInputSkin} onKeyPress={this.handleSubmitOnEnter} + allowSigns={false} /> @@ -339,7 +340,7 @@ export default class WalletSendForm extends Component { {isDialogOpen(WalletSendConfirmationDialog) ? ( Date: Wed, 11 Sep 2019 12:29:58 +0200 Subject: [PATCH 2/3] [DDW-861] V2 API error handlers (#1551) * [DDW-860] Introduce improvements for already integrated wallets API v2 endpoint * [DDW-860] Wallets endpoint flow code cleanup and removing unnecessary assurance declarations * [DDW-860] Introduce improvements for already integrated getAddresses API v2 endpoint * [DDW-680] Fix broken transactions screen * [DDW-860] Types improvements regarding to requested changes * [DDW-861] Introduce new error handling logic related to api v2 responsees * [DDW-861] Fix flow issue * [DDW-861] Shortens .map callback functions * [DDW-861] Fixes ESLint error * [DDW-861] Run translation manager * [DDW-861] Improve variable names * [DDW-861] Improve HTTP options --- CHANGELOG.md | 2 +- source/renderer/app/api/api.js | 7 +- source/renderer/app/api/utils/request.js | 87 ++++++++----------- .../AutomaticUpdateNotification.scss | 2 +- .../wallet/transactions/Transaction.js | 1 + .../renderer/app/containers/wallet/Wallet.js | 6 +- source/renderer/app/i18n/locales/de-DE.json | 2 +- source/renderer/app/i18n/locales/en-US.json | 2 +- source/renderer/app/i18n/locales/hr-HR.json | 2 +- source/renderer/app/i18n/locales/ko-KR.json | 2 +- source/renderer/app/i18n/locales/zh-CN.json | 2 +- 11 files changed, 51 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eb99ddfdf..28ffb11571 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Changelog ### Features +- Integrated Cardano V2 API endpoints ([PR 1548](https://github.com/input-output-hk/daedalus/pull/1548), [PR 1551](https://github.com/input-output-hk/daedalus/pull/1551)) - Removed select dropdown arrow ([PR 1550](https://github.com/input-output-hk/daedalus/pull/1550)) - Implemented automated and manual update flows unification ([PR 1491](https://github.com/input-output-hk/daedalus/pull/1491)) - Updated behavior of system dialogs ([PR 1494](https://github.com/input-output-hk/daedalus/pull/1494)) @@ -31,7 +32,6 @@ Changelog ### Chores -- Integrated Cardano V2 API endpoints ([PR 1548](https://github.com/input-output-hk/daedalus/pull/1548)) - Added minimum heights of main app window for different environments (Windows, Linux, MacOS) ([1485](https://github.com/input-output-hk/daedalus/pull/1485)) - Removed "Ada Redemption" feature ([PR 1510](https://github.com/input-output-hk/daedalus/pull/1510)) - Changed `themes:check` to `themes:check:createTheme` and added a 4 part "Theme Management in Daedalus" tutorial series to a README document in the themes directory ([PR 1525](https://github.com/input-output-hk/daedalus/pull/1525)) diff --git a/source/renderer/app/api/api.js b/source/renderer/app/api/api.js index 2f778a8519..252839afb9 100644 --- a/source/renderer/app/api/api.js +++ b/source/renderer/app/api/api.js @@ -174,7 +174,7 @@ export default class AdaApi { try { const response: AdaWallets = await getWallets(this.config); Logger.debug('AdaApi::getWallets success', { wallets: response }); - return response.map(wallet => _createWalletFromServerData(wallet)); + return response.map(_createWalletFromServerData); } catch (error) { Logger.error('AdaApi::getWallets error', { error }); throw new GenericApiError(); @@ -196,10 +196,7 @@ export default class AdaApi { ); Logger.debug('AdaApi::getAddresses success', { addresses: response }); - const addresses = response.map(data => - _createAddressFromServerData(data) - ); - + const addresses = response.map(_createAddressFromServerData); return new Promise(resolve => resolve({ accountIndex: 0, addresses })); } catch (error) { Logger.error('AdaApi::getAddresses error', { error }); diff --git a/source/renderer/app/api/utils/request.js b/source/renderer/app/api/utils/request.js index e0cf02cfd1..69fd238c07 100644 --- a/source/renderer/app/api/utils/request.js +++ b/source/renderer/app/api/utils/request.js @@ -1,5 +1,5 @@ // @flow -import { size, has, get, omit } from 'lodash'; +import { size, has, get, omit, includes } from 'lodash'; import querystring from 'querystring'; import { encryptPassphrase, getContentLength } from '.'; @@ -17,6 +17,10 @@ export type RequestOptions = { }, }; +const ALLOWED_ERROR_EXCEPTION_PATHS = [ + '/api/internal/next-update', // when nextAdaUpdate receives a 404, it isn't an error +]; + function typedRequest( httpOptions: RequestOptions, queryParams?: {}, @@ -65,18 +69,13 @@ function typedRequest( }; } - // TODO: Delete once HTTPS is supported by the new API - const httpOnlyOptions = { - hostname: options.hostname, - method: options.method, - path: options.path, - port: options.port, - }; + // @API TODO: Delete once HTTPS is supported by the new API + const httpOnlyOptions = omit(options, ['ca', 'cert', 'key']); + // @API TODO: Uncomment / switch once HTTPS is supported by the new API + // const httpsRequest = global.https.request(options); const httpsRequest = global.http.request(httpOnlyOptions); - // TODO: Uncomment once HTTPS is supported by the new API - // const httpsRequest = global.https.request(options); if (hasRequestBody) { httpsRequest.write(requestBody); } @@ -91,48 +90,38 @@ function typedRequest( // Resolve JSON results and handle backend errors response.on('end', () => { try { - // When deleting a wallet, the API does not return any data in body - // even if it was successful const { statusCode, statusMessage } = response; + const isSuccessResponse = + (statusCode >= 200 && statusCode <= 206) || + (statusCode === 404 && + includes(ALLOWED_ERROR_EXCEPTION_PATHS, options.path)); - if (!body && statusCode >= 200 && statusCode <= 206) { - // adds status and data properties so JSON.parse doesn't throw an error - body = `{ - "status": "success", - "data": "statusCode: ${statusCode} -- statusMessage: ${statusMessage}" - }`; - } else if ( - options.path === '/api/internal/next-update' && - statusCode === 404 - ) { - // when nextAdaUpdate receives a 404, it isn't an error - // it means no updates are available - body = `{ - "status": "success", - "data": null - }`; + if (isSuccessResponse) { + const data = + statusCode === 404 + ? 'null' + : `"statusCode: ${statusCode} -- statusMessage: ${statusMessage}"`; + // When deleting a wallet, the API does not return any data in body + // even if it was successful + if (!body) { + body = `{ + "status": ${statusCode}, + "data": ${data} + }`; + } + resolve(JSON.parse(body)); + } else if (body) { + // Error response with a body + const parsedBody = JSON.parse(body); + if (parsedBody.code && parsedBody.message) { + reject(parsedBody); + } else { + reject(new Error('Unknown API response')); + } + } else { + // Error response without a body + reject(new Error('Unknown API response')); } - - resolve(JSON.parse(body)); - // Note: The V2 API does not have the status field. - // Is this not re-creating HTTP status codes? I don't think this - // should be required. We should rely on status codes now we have - // the shiny new API - // - // const status = get(parsedBody, 'status', false); - // if (status) { - // if (status === 'success') { - // resolve(returnMeta ? parsedBody : parsedBody.data); - // } else if (status === 'error' || status === 'fail') { - // reject(parsedBody); - // } else { - // // TODO: find a way to record this case and report to the backend team - // reject(new Error('Unknown response from backend.')); - // } - // } else { - // // TODO: find a way to record this case and report to the backend team - // reject(new Error('Unknown response from backend.')); - // } } catch (error) { // Handle internal server errors (e.g. HTTP 500 - 'Something went wrong') reject(new Error(error)); diff --git a/source/renderer/app/components/notifications/AutomaticUpdateNotification.scss b/source/renderer/app/components/notifications/AutomaticUpdateNotification.scss index 41de3d1a1a..9fd4454679 100644 --- a/source/renderer/app/components/notifications/AutomaticUpdateNotification.scss +++ b/source/renderer/app/components/notifications/AutomaticUpdateNotification.scss @@ -87,9 +87,9 @@ font-size: 14px; margin: 20px auto 0; &:hover { - color: var(--theme-automatic-update-overlay-button-label-color); border-bottom: 1px solid var(--theme-automatic-update-overlay-button-label-color); + color: var(--theme-automatic-update-overlay-button-label-color); } } } diff --git a/source/renderer/app/components/wallet/transactions/Transaction.js b/source/renderer/app/components/wallet/transactions/Transaction.js index b95032419c..9c9e20d78c 100644 --- a/source/renderer/app/components/wallet/transactions/Transaction.js +++ b/source/renderer/app/components/wallet/transactions/Transaction.js @@ -202,6 +202,7 @@ export default class Transaction extends Component { const transactionStateTag = () => { if (isRestoreActive) return; + return (
{intl.formatMessage(stateTranslations[transactionState])} diff --git a/source/renderer/app/containers/wallet/Wallet.js b/source/renderer/app/containers/wallet/Wallet.js index 9338ded9e8..2d6b62b030 100644 --- a/source/renderer/app/containers/wallet/Wallet.js +++ b/source/renderer/app/containers/wallet/Wallet.js @@ -60,11 +60,11 @@ export default class Wallet extends Component { ); const isRestoreActive = - get(wallets.active, ['syncState', 'status']) === + get(wallets, ['active', 'syncState', 'status']) === WalletSyncStateStatuses.RESTORING; const restoreProgress = get( - wallets.active, - 'syncState.progress.quantity', + wallets, + ['active', 'syncState', 'progress', 'quantity'], 0 ); diff --git a/source/renderer/app/i18n/locales/de-DE.json b/source/renderer/app/i18n/locales/de-DE.json index 9d84b66b6a..52d9d81114 100644 --- a/source/renderer/app/i18n/locales/de-DE.json +++ b/source/renderer/app/i18n/locales/de-DE.json @@ -579,4 +579,4 @@ "wallet.transaction.type.exchange": "!!!Währungsumtausch", "wallet.transactions.no.transactions": "!!!Keine Transaktionen vorhanden", "wallet.transactions.no.transactions.found": "!!!Keine Transaktionen gefunden" -} +} \ No newline at end of file diff --git a/source/renderer/app/i18n/locales/en-US.json b/source/renderer/app/i18n/locales/en-US.json index 02668b1a76..ca7f635d7e 100644 --- a/source/renderer/app/i18n/locales/en-US.json +++ b/source/renderer/app/i18n/locales/en-US.json @@ -579,4 +579,4 @@ "wallet.transaction.type.exchange": "Exchange", "wallet.transactions.no.transactions": "No transactions", "wallet.transactions.no.transactions.found": "No transactions found" -} +} \ No newline at end of file diff --git a/source/renderer/app/i18n/locales/hr-HR.json b/source/renderer/app/i18n/locales/hr-HR.json index a58821009b..064d06933f 100644 --- a/source/renderer/app/i18n/locales/hr-HR.json +++ b/source/renderer/app/i18n/locales/hr-HR.json @@ -579,4 +579,4 @@ "wallet.transaction.type.exchange": "!!!Konverzija", "wallet.transactions.no.transactions": "!!!Nema transakcija", "wallet.transactions.no.transactions.found": "!!!Ne postoje transakcije koje zadovoljavaju uvjete pretraživanja" -} +} \ No newline at end of file diff --git a/source/renderer/app/i18n/locales/ko-KR.json b/source/renderer/app/i18n/locales/ko-KR.json index f09552db8e..365abe49fc 100644 --- a/source/renderer/app/i18n/locales/ko-KR.json +++ b/source/renderer/app/i18n/locales/ko-KR.json @@ -579,4 +579,4 @@ "wallet.transaction.type.exchange": "!!!Exchange", "wallet.transactions.no.transactions": "!!!No transactions", "wallet.transactions.no.transactions.found": "!!!No transactions found" -} +} \ No newline at end of file diff --git a/source/renderer/app/i18n/locales/zh-CN.json b/source/renderer/app/i18n/locales/zh-CN.json index ec6d4bb1fc..ded63c9309 100644 --- a/source/renderer/app/i18n/locales/zh-CN.json +++ b/source/renderer/app/i18n/locales/zh-CN.json @@ -579,4 +579,4 @@ "wallet.transaction.type.exchange": "!!!Exchange", "wallet.transactions.no.transactions": "!!!No transactions", "wallet.transactions.no.transactions.found": "!!!No transactions found" -} +} \ No newline at end of file From 1b15d2d5d964c1570b44c78ad1d921114c129081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Hora=C4=8Dek?= Date: Wed, 11 Sep 2019 14:17:37 +0200 Subject: [PATCH 3/3] [DDW-871] Eslint fix --- source/renderer/app/api/utils/request.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/renderer/app/api/utils/request.js b/source/renderer/app/api/utils/request.js index 5cecaf87f5..69fd238c07 100644 --- a/source/renderer/app/api/utils/request.js +++ b/source/renderer/app/api/utils/request.js @@ -28,9 +28,6 @@ function typedRequest( // requestOptions?: { returnMeta: boolean } ): Promise { return new Promise((resolve, reject) => { - const allowedErrorExceptionPaths = [ - '/api/internal/next-update', // when nextAdaUpdate receives a 404, it isn't an error - ]; const options: RequestOptions = Object.assign({}, httpOptions); // const { returnMeta } = Object.assign({}, requestOptions); let hasRequestBody = false;