ghost-portal/packages/ui-app/src/CodeRow.tsx
Thibaut Sardan d868adae88 Redo staking process and overview (#1268)
* remove filtering on actions tab

* remove unused balances on actions

* remove unused balances on actions

* only show stash

* show stashed including validators and nominators

* some buttons

* new stake button

* bond edit init

* BondEdit button

* combined session and validating button

* remove comments

* remove css hack

* phrasing

* validator prefs

* can edit validator prefs

* fix validatorPrefs undifined and nits

* validate unstakeThreshold (<11)

* with setting button noautoclose

* fix nominee styling

* change session and process feeling

* lint

* change nominees without defaultValue

* display and change reward destination

* change controller

* add balances on bond and unbond

* available balance, setting button right, nameOrAddress

* back to the old flow with set session key, cleanup logs

* balance off on chrome

* fix comments + a design hickup on chrome

* fix conflicts

* nits

* Various small UI fixes

* Types for getAddress defaults

* use name

* type props for Row

* lint
2019-06-13 06:04:01 +02:00

217 lines
4.7 KiB
TypeScript

// Copyright 2017-2019 @polkadot/ui-app authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { I18nProps } from '@polkadot/ui-app/types';
import { Hash } from '@polkadot/types';
import { CodeStored } from '@polkadot/app-contracts/types';
import React from 'react';
import styled from 'styled-components';
import { withMulti } from '@polkadot/ui-api';
import { classes, toShortAddress } from '@polkadot/ui-app/util';
import contracts from '@polkadot/app-contracts/store';
import CopyButton from './CopyButton';
import Icon from './Icon';
import Messages from './Messages';
import Row, { RowProps, RowState, styles } from './Row';
import translate from './translate';
type Props = I18nProps & RowProps & {
code: CodeStored,
withMessages?: boolean
};
type State = RowState & {
codeHash: string
};
const DEFAULT_HASH = '0x';
const DEFAULT_NAME = '<unknown>';
const CodeIcon = styled.div`
& {
margin-right: 1em;
background: #eee;
color: #666;
width: 4rem;
height: 5rem;
padding: 0.5rem;
display: flex;
justify-content: flex-end;
align-items: flex-end;
}
`;
const DEFAULT_ADDR = '5'.padEnd(16, 'x');
class CodeRow extends Row<Props, State> {
state: State;
constructor (props: Props) {
super(props);
this.state = this.createState();
}
static getDerivedStateFromProps ({ code: { json }, accounts_idAndIndex = [] }: Props, prevState: State): State | null {
const codeHash = json.codeHash || DEFAULT_HASH;
const name = json.name || DEFAULT_NAME;
const tags = json.tags || [];
const [_accountId] = accounts_idAndIndex;
const accountId = _accountId;
const address = accountId
? accountId.toString()
: DEFAULT_ADDR;
const state = { tags } as State;
let hasChanged = false;
if (codeHash !== prevState.codeHash) {
state.codeHash = codeHash;
hasChanged = true;
}
if (!prevState.isEditingName && name !== prevState.name) {
state.name = name;
hasChanged = true;
}
if (address !== prevState.address) {
state.address = address;
hasChanged = true;
}
return hasChanged
? state
: null;
}
render () {
const { className, isInline, style } = this.props;
return (
<div
className={classes('ui--Row', isInline && 'inline', className)}
style={style}
>
<div className='ui--Row-base'>
{this.renderIcon()}
<div className='ui--Row-details'>
{this.renderName()}
{this.renderCodeHash()}
{this.renderTags()}
</div>
{this.renderButtons()}
</div>
{this.renderMessages()}
{this.renderChildren()}
</div>
);
}
private createState () {
const { code: { json: { codeHash = DEFAULT_HASH, name = DEFAULT_NAME, tags = [] } } } = this.props;
return {
address: DEFAULT_ADDR,
codeHash,
isEditingName: false,
isEditingTags: false,
name,
tags
};
}
protected renderCodeHash () {
const { codeHash } = this.state;
return (
<>
<div className='ui--Row-name'>
{name}
</div>
<div className='ui--Row-accountId'>
<CopyButton
isAddress
value={codeHash}
>
<span>{toShortAddress(codeHash)}</span>
</CopyButton>
</div>
</>
);
}
protected renderButtons () {
const { buttons } = this.props;
if (!buttons) {
return null;
}
return (
<div className='ui--Row-buttons'>
{buttons}
</div>
);
}
protected renderIcon () {
return (
<CodeIcon>
<Icon
name='code'
size='large'
/>
</CodeIcon>
);
}
protected renderMessages () {
const { code: { contractAbi }, withMessages } = this.props;
if (!withMessages || !contractAbi) {
return null;
}
return (
<Messages
contractAbi={contractAbi}
isRemovable
/>
);
}
protected saveName = async () => {
const { codeHash, name } = this.state;
const trimmedName = name.trim();
// Save only if the name was changed or if it's no empty.
if (trimmedName && codeHash) {
await contracts.saveCode(new Hash(codeHash), { name });
this.setState({ isEditingName: false });
}
}
protected saveTags = async () => {
const { codeHash, tags } = this.state;
if (codeHash) {
await contracts.saveCode(new Hash(codeHash), { tags });
this.setState({ isEditingTags: false });
}
}
}
export default withMulti(
styled(CodeRow as React.ComponentClass<Props>)`
${styles}
`,
translate
);