Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revamp error messages + UI fixes #2970

Merged
merged 12 commits into from
Aug 26, 2022
2 changes: 1 addition & 1 deletion packages/yoroi-extension/app/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class App extends Component<Props, State> {
getContent: void => ?Node = () => {
const { stores, actions, history } = this.props;
if (this.state.crashed === true) {
return <CrashPage stores={stores} actions={actions} />;
return <CrashPage />;
}
if (stores.serverConnectionStore.isMaintenance) {
return <MaintenancePage stores={stores} actions={actions} />;
Expand Down
2 changes: 1 addition & 1 deletion packages/yoroi-extension/app/api/common/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const messages = defineMessages({
},
cannotSendBelowMinimumValueError: {
id: 'api.errors.CannotSendBelowMinimumValueError',
defaultMessage: '!!!Minimum required is 1 ADA',
defaultMessage: '!!!A minimum of 1 ADA is required',
},
assetOverflowError: {
id: 'api.errors.assetOverflowError',
Expand Down
33 changes: 13 additions & 20 deletions packages/yoroi-extension/app/components/loading/Crashed.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import globalMessages from '../../i18n/global-messages';
import type { $npm$ReactIntl$IntlFormat } from 'react-intl';
import UnavailableDialog from '../widgets/UnavailableDialog';
import { defineMessages, intlShape, FormattedMessage } from 'react-intl';
import { Link, Typography } from '@mui/material';

const messages = defineMessages({
title: {
Expand All @@ -16,7 +17,6 @@ const messages = defineMessages({
});

type Props = {|
+onExternalLinkClick: MouseEvent => void,
+onDownloadLogs: void => void,
|};

Expand Down Expand Up @@ -50,38 +50,31 @@ export default class Crashed extends Component<Props> {
_getErrorMessageComponent: (void => Node) = () => {
const { intl } = this.context;
const {
onExternalLinkClick,
onDownloadLogs
} = this.props;

const downloadLogsLink = (
// eslint-disable-next-line jsx-a11y/anchor-is-valid
<a
className={styles.link}
href="#"
onClick={_event => onDownloadLogs()}
>
<Link href='#' onClick={_event => onDownloadLogs()}>
{intl.formatMessage(globalMessages.downloadLogsLink)}
</a>
</Link>
);

const supportRequestLink = (
<a
className={styles.link}
href='https://emurgohelpdesk.zendesk.com/hc/en-us/requests/new?ticket_form_id=360013330335'
onClick={event => onExternalLinkClick(event)}
target='_blank'
rel="noreferrer"
>
{intl.formatMessage(globalMessages.contactSupport)}
</a>
<Link href='https://emurgohelpdesk.zendesk.com/hc/en-us/requests/new?ticket_form_id=360013330335' target='_blank' rel="noreferrer">
{intl.formatMessage(globalMessages.here)}
</Link>
);

return (
<p>
<FormattedMessage {...globalMessages.logsContent} values={{ downloadLogsLink }} />
<br /><br />
<FormattedMessage {...globalMessages.forMoreHelp} values={{ supportRequestLink }} />
<Typography sx={{ textAlign: 'justify', mb: '15px' }}>
<FormattedMessage {...globalMessages.forMoreHelp} values={{ supportRequestLink }} />
</Typography>

<Typography variant='subtitle2' sx={{ textAlign: 'justify' }}>
<FormattedMessage {...globalMessages.logsContent} values={{ downloadLogsLink }} />
</Typography>
</p>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
font-weight: 500;
line-height: 23px;
margin-bottom: 6px;
word-break: break-all;
text-align: center;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const messages = defineMessages({
},
explanation: {
id: 'wallet.restore.dialog.walletExist.explanation',
defaultMessage: '!!!You are trying to restore existing wallet.',
defaultMessage: '!!!The wallet you are trying to restore already exists.',
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
.component {

& > div {
overflow: hidden;
}
.wrapper {
display: grid;
grid-template-columns: 1fr 4fr;
grid-gap: 8px;
overflow: hidden;
}

.explanation {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,7 @@ export default class WalletRestoreDialog extends Component<Props> {
];
},
({ field }) => ([
// TODO: Should we allow 0-length paper wallet passwords?
// Disable for now to avoid user accidentally forgetting
// to enter his password and pressing restore
field.value.length > 0,
field.value.length > 9,
this.context.intl.formatMessage(globalMessages.invalidPaperPassword)
]),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export default class ConfirmPinDialog extends Component<Props> {
<div className={classnames([styles.lineText, styles.firstItem])}>
<FormattedHTMLMessage {...messages.line1} />
</div>
<div className={classnames([styles.pinInputContainer])}>
<div className={styles.pinInputContainer}>
<PinInput
setForm={form => this.setPinForm(form)}
disabled={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import globalMessages from '../../../i18n/global-messages';
import config from '../../../config';
import TextField from '../../common/TextField';
import type { $npm$ReactIntl$IntlFormat } from 'react-intl';
import { Box } from '@mui/material';

type Props = {|
+setForm: ReactToolboxMobxForm => void,
Expand Down Expand Up @@ -90,7 +91,7 @@ export default class PinInput extends Component<Props> {
const pinField = form.$(this.props.fieldName);

return (
<div>
<Box sx={{ width: '100%'}}>
{this.props.disclaimer}
<TextField
className={this.props.fieldName}
Expand All @@ -99,7 +100,7 @@ export default class PinInput extends Component<Props> {
error={pinField.error}
done={this.props.done}
/>
</div>
</Box>
);
}
}
22 changes: 1 addition & 21 deletions packages/yoroi-extension/app/containers/CrashPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,17 @@
import type { Node } from 'react';
import { Component } from 'react';
import { observer } from 'mobx-react';
import { computed } from 'mobx';
import Crashed from '../components/loading/Crashed';
import type { JointInjectedOrGenerated } from '../types/injectedPropsType';
import { handleExternalLinkClick } from '../utils/routing';
import { downloadLogs } from '../utils/logging';

type GeneratedData = typeof CrashPage.prototype.generated;

@observer
export default class CrashPage extends Component<
JointInjectedOrGenerated<GeneratedData>
> {
export default class CrashPage extends Component<{||}> {

render(): Node {
return (
<Crashed
onExternalLinkClick={this.generated.handleExternalLinkClick}
onDownloadLogs={downloadLogs}
/>
);
}

@computed get generated(): {|handleExternalLinkClick: (event: MouseEvent) => void|} {
if (this.props.generated !== undefined) {
return this.props.generated;
}
if (this.props.stores == null || this.props.actions == null) {
throw new Error(`${nameof(CrashPage)} no way to generated props`);
}
return Object.freeze({
handleExternalLinkClick,
});
}
}
8 changes: 1 addition & 7 deletions packages/yoroi-extension/app/containers/CrashPage.stories.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// @flow

import type { Node } from 'react';

import { action } from '@storybook/addon-actions';
import CrashPage from './CrashPage';
import { withScreenshot } from 'storycap';

Expand All @@ -13,9 +11,5 @@ export default {
};

export const Generic = (): Node => (
<CrashPage
generated={{
handleExternalLinkClick: action('External link click'),
}}
/>
<CrashPage />
);
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,21 @@ export default class VotingPage extends Component<Props> {
registrationStart: nextFund?.registrationStart
})

const fund = {
'id': 8,
'name': 'Fund9',
'registrationStart': '2021-01-27T11:00:00Z',
'registrationEnd': '2023-08-04T11:00:00Z',
'votingStart': '2021-08-11T11:00:00Z',
'votingEnd': '2023-08-25T11:00:00Z',
'votingPowerThreshold': '450'
};
if (currentFund) {
const isLate = new Date() >= new Date(Date.parse(currentFund.registrationEnd))
const isEarly = new Date() <= new Date(Date.parse(currentFund.registrationStart))
const isBeforeVoting = new Date() <= new Date(Date.parse(currentFund.votingStart))
const isAfterVoting = new Date() >= new Date(Date.parse(currentFund.votingEnd))
console.log(JSON.parse(JSON.stringify(currentFund)))
const isLate = new Date() >= new Date(Date.parse(fund.registrationEnd))
const isEarly = new Date() <= new Date(Date.parse(fund.registrationStart))
const isBeforeVoting = new Date() <= new Date(Date.parse(fund.votingStart))
const isAfterVoting = new Date() >= new Date(Date.parse(fund.votingEnd))
const isBetweenVoting = !isBeforeVoting && !isAfterVoting;

if (isEarly) {
Expand Down
2 changes: 1 addition & 1 deletion packages/yoroi-extension/app/ergo-connector/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class App extends Component<Props, State> {
getContent: void => ?Node = () => {
const { stores, actions, history } = this.props;
if (this.state.crashed === true) {
return <CrashPage stores={stores} actions={actions} />;
return <CrashPage />;
}
return <Router history={history}>{Routes(stores, actions)}</Router>;
};
Expand Down
6 changes: 5 additions & 1 deletion packages/yoroi-extension/app/i18n/global-messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { defineMessages } from 'react-intl';
*/

const globalMessages: * = defineMessages({
here: {
id: 'global.util.here',
defaultMessage: '!!!here',
},
token: {
id: 'global.labels.token',
defaultMessage: '!!!Token',
Expand Down Expand Up @@ -427,7 +431,7 @@ const globalMessages: * = defineMessages({
},
forMoreHelp: {
id: 'loading.screen.error',
defaultMessage: '!!!For more help, you can {supportRequestLink}',
defaultMessage: '!!!Unexpected error occurred. We apologize for the inconvenience. If this error persists, please reach out to our support team {supportRequestLink}',
},
logsContent: {
id: 'settings.support.logs.content',
Expand Down
7 changes: 4 additions & 3 deletions packages/yoroi-extension/app/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"api.errors.ApiMethodNotYetImplementedError": "This API method is not yet implemented.",
"api.errors.CannotSendBelowMinimumValueError": "Minimum required is 1 ADA",
"api.errors.CannotSendBelowMinimumValueError": "A minimum of 1 ADA is required",
"api.errors.GenericApiError": "An error occurred. Please retry.",
"api.errors.IncorrectPasswordError": "Incorrect spending password. Please retype.",
"api.errors.NotEnoughMoneyToSendError": "Insufficient funds to complete this transaction.",
Expand Down Expand Up @@ -158,6 +158,7 @@
"global.labels.optionalMemo": "Memo (optional)",
"global.labels.nft": "NFTs",
"global.labels.token": "token",
"global.util.here": "here",
"wallet.send.form.memoWarning": "Memos are stored localy only",
"wallet.send.form.max": "MAX",
"wallet.send.form.dialog.add": "add",
Expand Down Expand Up @@ -216,7 +217,7 @@
"inline.editing.input.cancel.label": "cancel",
"inline.editing.input.change.label": "change",
"inline.editing.input.changesSaved": "Your changes have been saved",
"loading.screen.error": "For more help, you can {supportRequestLink}",
"loading.screen.error": "Unexpected error occurred. We apologize for the inconvenience. If this error persists, please reach out to our support team {supportRequestLink}",
"loading.screen.loading": "Loading components",
"maintenance.screen.explanation": "Yoroi is in maintenance mode. You can still access your funds through any other wallet software.",
"maintenance.screen.title": "Temporary Maintenance",
Expand Down Expand Up @@ -723,7 +724,7 @@
"wallet.restore.dialog.verify.wallet.button.label": "Verify wallet",
"wallet.restore.dialog.wallet.name.input.hint": "e.g: Shopping Wallet",
"wallet.restore.dialog.wallet.name.input.label": "Wallet name",
"wallet.restore.dialog.walletExist.explanation": "You are trying to restore existing wallet.",
"wallet.restore.dialog.walletExist.explanation": "The wallet you are trying to restore already exists.",
"wallet.restore.dialog.walletExist.openWallet": "Open Wallet",
"wallet.restore.dialog.walletExist.title": "Wallet Already Exist",
"wallet.send.confirmationDialog.addressToLabel": "To",
Expand Down