Skip to content

Commit

Permalink
Merge branch 'release/2.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Saurer committed Jul 26, 2019
2 parents e97c3c8 + 8279391 commit bc891ce
Show file tree
Hide file tree
Showing 61 changed files with 624 additions and 243 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "apla-front",
"version": "1.1.0",
"version": "2.0.0",
"author": {
"name": "apla-front"
},
Expand Down
5 changes: 5 additions & 0 deletions public/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"auth.wallet.remove": "Remove",
"auth.wallet.share": "Share",
"auth.wallet.share.long": "Share account data",
"auth.wallet.unregistered": "Unregistered account",
"auth.authentication": "Authentication",
"auth.create.success": "Account has been successfully created",
"auth.error.E_INVALID_KEY": "Provided key is corrupted or contains invalid data",
Expand Down Expand Up @@ -147,8 +148,10 @@
"general.password.repeat": "Repeat password",
"general.password.old": "Old password",
"general.password.new": "New password",
"general.print": "Print",
"general.title": "Apla",
"general.title.format": "{title} | Apla",
"general.save": "Save",
"general.security.warning": "Please use desktop version or mobile application for better security",
"history.newer": "Newer",
"history.older": "Older",
Expand Down Expand Up @@ -199,7 +202,9 @@
"process.confirm": "Confirm",
"process.continue": "Continue",
"undo": "Undo",
"tx.data.missing": "Data is missing",
"tx.param.value": "Value",
"tx.report": "Transaction report",
"tx.error.error": "Error",
"tx.error.error.desc": "{error}",
"tx.error.exception": "Runtime exception",
Expand Down
5 changes: 5 additions & 0 deletions public/locales/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"auth.wallet.remove": "Удалить",
"auth.wallet.share": "Копировать",
"auth.wallet.share.long": "Копировать данные аккаунта",
"auth.wallet.unregistered": "Незарегистрированный аккаунт",
"auth.authentication": "Аутентификация",
"auth.create.success": "Аккаунт успешно создан",
"auth.error.E_INVALID_KEY": "Указанный ключ содержит некорректные данные или повреждён",
Expand Down Expand Up @@ -147,8 +148,10 @@
"general.password.repeat": "Повторите пароль",
"general.password.old": "Старый пароль",
"general.password.new": "Новый пароль",
"general.print": "Печать",
"general.title": "Apla",
"general.title.format": "{title} | Apla",
"general.save": "Сохранить",
"general.security.warning": "Для большей безопасности используйте desktop или мобильное приложение",
"history.newer": "Новее",
"history.older": "Старше",
Expand Down Expand Up @@ -199,7 +202,9 @@
"process.confirm": "Подтвердить",
"process.continue": "Далее",
"undo": "Отмена",
"tx.data.missing": "Данные отсутствуют",
"tx.param.value": "Значение",
"tx.report": "Отчёт транзакции",
"tx.error.error": "Ошибка",
"tx.error.error.desc": "{error}",
"tx.error.exception": "Программное исключение",
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/Auth/Login/PasswordPrompt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const PasswordPrompt: React.SFC<IPasswordPromptProps & InjectedIntlProps> = prop
<div className="avatar-holder">
<Avatar
size={100}
keyID={props.wallet.wallet.id}
account={props.wallet.wallet.address}
ecosystem={props.wallet.access.ecosystem}
/>
</div>
Expand Down
21 changes: 14 additions & 7 deletions src/app/components/Auth/Login/WalletList/WalletButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import React from 'react';
import styled from 'styled-components';
import { FormattedMessage } from 'react-intl';
import { Button, Clearfix } from 'react-bootstrap';
import { IAccount, IKeyInfo, IRoleInfo } from 'apla/api';
import { IAccount, IRoleInfo, IEcosystemInfo } from 'apla/api';
import { INotificationsMessage } from 'apla/socket';

import Avatar from 'containers/Avatar';
Expand All @@ -19,11 +19,11 @@ export interface IWalletButtonProps {
notifications: INotificationsMessage[];
onCopy: () => void;
onRemove: () => void;
onSelect: (params: { access: IKeyInfo, role: IRoleInfo }) => void;
onSelect: (params: { access: IEcosystemInfo, role: IRoleInfo }) => void;
onRegister?: () => void;
}

const getNotificationsCount = (notifications: INotificationsMessage[], role: number, ecosystem: string) => {
const getNotificationsCount = (notifications: INotificationsMessage[], role: string, ecosystem: string) => {
const value = notifications.find(l => l.role === role && l.ecosystem === ecosystem);
return value ? value.count : 0;
};
Expand All @@ -35,7 +35,14 @@ const WalletButton: React.SFC<IWalletButtonProps> = (props) => (
</div>
<div className="wallet-head">
<h4 className="wallet-name">
{props.wallet.address}
{props.wallet.address ?
(
<span>{props.wallet.address}</span>
) :
(
<FormattedMessage id="auth.wallet.unregistered" defaultMessage="Unregistered account" />
)
}
</h4>
{0 === props.wallet.access.length && props.onRegister && (
<div className="text-danger">
Expand Down Expand Up @@ -63,7 +70,7 @@ const WalletButton: React.SFC<IWalletButtonProps> = (props) => (
<div className="pull-left">
<Avatar
size={44}
keyID={props.wallet.id}
account={props.wallet.address}
ecosystem={access.ecosystem}
/>
</div>
Expand All @@ -74,11 +81,11 @@ const WalletButton: React.SFC<IWalletButtonProps> = (props) => (
<span>
<FormattedMessage id="auth.login.as" defaultMessage="Login with role" />:
</span>
<RoleButton className="wallet-btn" badge={getNotificationsCount(props.notifications, 0, access.ecosystem)} onClick={() => props.onSelect({ access, role: null })}>
<RoleButton className="wallet-btn" badge={getNotificationsCount(props.notifications, '0', access.ecosystem)} onClick={() => props.onSelect({ access, role: null })}>
<FormattedMessage id="auth.role.guest" defaultMessage="Guest" />
</RoleButton>
{access.roles.map(role => (
<RoleButton key={role.id} className="wallet-btn" badge={getNotificationsCount(props.notifications, Number(role.id), access.ecosystem)} onClick={() => props.onSelect({ access, role })}>
<RoleButton key={role.id} className="wallet-btn" badge={getNotificationsCount(props.notifications, role.id, access.ecosystem)} onClick={() => props.onSelect({ access, role })}>
{role.name}
</RoleButton>
))}
Expand Down
10 changes: 5 additions & 5 deletions src/app/components/Main/Backup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import { Button, Panel } from 'react-bootstrap';
import { FormattedMessage } from 'react-intl';
import keyring from 'lib/keyring';
import { sendAttachment } from 'lib/fs';
import { IAccountContext } from 'apla/auth';
import { IAccount } from 'apla/api';
import CopyToClipboard from 'react-copy-to-clipboard';
import QRCode from 'qrcode.react';

import Wrapper from 'components/Wrapper';
import Validation from 'components/Validation';

export interface IBackupProps {
wallet: IAccountContext;
account: IAccount;
privateKey: string;
onError?: () => any;
onCopy?: () => any;
Expand All @@ -37,7 +37,7 @@ class Backup extends React.Component<IBackupProps, IBackupState> {
}

onSubmit = (values: { [key: string]: string }) => {
const privateKey = keyring.decryptAES(this.props.wallet.wallet.encKey, values.password);
const privateKey = keyring.decryptAES(this.props.account.encKey, values.password);

if (keyring.validatePrivateKey(privateKey)) {
const publicKey = keyring.generatePublicKey(privateKey);
Expand Down Expand Up @@ -125,7 +125,7 @@ class Backup extends React.Component<IBackupProps, IBackupState> {
<td>
<FormattedMessage id="general.address" defaultMessage="Address" />
</td>
<td>{this.props.wallet.wallet.address}</td>
<td>{this.props.account && this.props.account.address}</td>
</tr>
<tr>
<td>
Expand Down Expand Up @@ -163,7 +163,7 @@ class Backup extends React.Component<IBackupProps, IBackupState> {
<FormattedMessage id="general.wallet.backup" defaultMessage="This section is used to backup your account data. You will not be able to restore access to your account if you forget your password or lose the private key" />
}
>
{this.props.wallet && (
{this.props.account && (
<Validation.components.ValidatedForm onSubmitSuccess={this.onSubmit}>
{this.state.privateKey ? this.renderSecond() : this.renderFirst()}
</Validation.components.ValidatedForm>
Expand Down
6 changes: 3 additions & 3 deletions src/app/components/Main/UserMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import React from 'react';
import styled from 'styled-components';
import { FormattedMessage } from 'react-intl';
import { IAccountContext } from 'apla/auth';
import { IEcosystemInfo } from 'apla/api';

import { CloseDropdownButton } from 'components/DropdownButton';
import PageLink from 'containers/Routing/PageLink';
import SystemButton from './SystemButton';
import Avatar from 'containers/Avatar';
import { IKeyInfo } from 'apla/api';

const StyledUserMenu = styled.div`
-webkit-app-region: no-drag;
Expand Down Expand Up @@ -64,7 +64,7 @@ const StyledUserMenu = styled.div`
export interface IUserMenuProps {
isDefaultWallet: boolean;
wallet: IAccountContext;
walletEcosystems: IKeyInfo[];
walletEcosystems: IEcosystemInfo[];
onSwitchEcosystem: (ecosystem: string, defaultRole?: boolean) => void;
onLogout: () => void;
onChangePassword: () => void;
Expand Down Expand Up @@ -156,7 +156,7 @@ class UserMenu extends React.Component<IUserMenuProps> {
<Avatar
className="user-avatar"
size={32}
keyID={this.props.wallet.wallet.id}
account={this.props.wallet.wallet.address}
ecosystem={this.props.wallet.access.ecosystem}
/>
</StyledUserMenu>
Expand Down
8 changes: 1 addition & 7 deletions src/app/components/Modal/Auth/CopyWalletModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class CopyWalletModal extends Modal<ICopyWalletModalParams, void> {
}

getCopyPayload = () => {
return `${this.props.params.wallet.address}\n${this.props.params.wallet.publicKey}`;
return this.props.params.wallet.publicKey;
}

render() {
Expand All @@ -34,12 +34,6 @@ class CopyWalletModal extends Modal<ICopyWalletModalParams, void> {
<Modal.Body>
<table className="table table-striped table-bordered table-hover preline mb0" style={{ maxWidth: 500 }}>
<tbody>
<tr>
<td>
<FormattedMessage id="general.address" defaultMessage="Address" />
</td>
<td>{this.props.params.wallet.address}</td>
</tr>
<tr>
<td style={{ minWidth: 100 }}>
<FormattedMessage id="general.key.public" defaultMessage="Public key" />
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/Modal/RolePickerModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Modal, { ModalContainer, IModalProps } from './';
import Avatar from 'containers/Avatar';

export interface IRolePickerModalParams {
walletID: string;
account: string;
ecosystem: string;
ecosystemName: string;
roles: IRoleInfo[];
Expand All @@ -33,7 +33,7 @@ class RolePickerModal extends ModalContainer<IRolePickerModalProps> {
<div className="pull-left">
<Avatar
size={44}
keyID={this.props.params.walletID}
account={this.props.params.account}
ecosystem={this.props.params.ecosystem}
/>
</div>
Expand Down
87 changes: 87 additions & 0 deletions src/app/components/PrintZone/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) EGAAS S.A. All rights reserved.
* See LICENSE in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import React from 'react';
import Button from 'components/Button';
import { sendAttachment } from 'lib/fs';
import { FormattedMessage } from 'react-intl';

export interface IPrintZoneProps {
stylesheet: string;
}

class PrintZone extends React.Component<IPrintZoneProps> {
private _container: HTMLDivElement;
private _output: HTMLIFrameElement;

componentDidUpdate() {
this.onRepaint();
}

componentDidMount() {
this.onRepaint();
}

onRepaint = () => {
setTimeout(() => {
if (!this._output || !this._output.contentDocument.body) {
return;
}

this._output.style.height = '0px';
this._output.contentDocument.body.innerHTML = this._container.innerHTML;
const style = this._output.contentDocument.createElement('style');
style.innerText = this.props.stylesheet;
this._output.contentDocument.body.appendChild(style);
this._output.style.height = this._output.contentDocument.body.scrollHeight + 'px';
});
}

onSave = () => {
sendAttachment('Tx.html', this._output.contentDocument.body.innerHTML, 'text/html');
}

onPrint = () => {
this._output.contentWindow.focus();
this._output.contentWindow.print();
}

render() {
return (
<div>
<div ref={l => this._container = l} style={{ position: 'absolute', top: -50000, left: -50000 }}>
{this.props.children}
</div>
<iframe
ref={l => this._output = l}
scrolling="no"
style={{
background: '#fff',
width: '100%',
boxSizing: 'border-box',
border: 'dashed 1px #999',
outline: 0,
padding: 0,
margin: 0
}}
/>
<hr />
<span>
<Button className="btn btn-primary" onClick={this.onSave}>
<FormattedMessage id="general.save" defaultMessage="Save" />
</Button>
</span>
<span style={{ marginLeft: 15 }}>
<Button className="btn btn-primary" onClick={this.onPrint}>
<FormattedMessage id="general.print" defaultMessage="Print" />
</Button>
</span>

</div>
);
}
}

export default PrintZone;
Loading

0 comments on commit bc891ce

Please sign in to comment.