* Rename ui-* -> react-* * Rename actual folders * react-app -> react-components * CSS links
150 lines
4.0 KiB
TypeScript
150 lines
4.0 KiB
TypeScript
// Copyright 2017-2019 @polkadot/app-contracts 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 { AppProps, I18nProps } from '@polkadot/react-components/types';
|
|
import { TabItem } from '@polkadot/react-components/Tabs';
|
|
import { ComponentProps, LocationProps } from './types';
|
|
|
|
import React from 'react';
|
|
import { Route, RouteComponentProps, Switch } from 'react-router';
|
|
import { withRouter } from 'react-router-dom';
|
|
import { HelpOverlay, Tabs } from '@polkadot/react-components';
|
|
import { withMulti, withObservable } from '@polkadot/react-api';
|
|
import keyring from '@polkadot/ui-keyring';
|
|
import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
|
|
|
|
import introMd from './md/intro.md';
|
|
import store from './store';
|
|
import translate from './translate';
|
|
import Contracts from './Contracts';
|
|
import Codes from './Codes';
|
|
import Deploy from './Deploy';
|
|
|
|
type Props = AppProps & I18nProps & RouteComponentProps & {
|
|
accounts: SubjectInfo[];
|
|
contracts: SubjectInfo[];
|
|
};
|
|
|
|
interface State {
|
|
codeHash?: string;
|
|
hasContracts: boolean;
|
|
isDeployOpen: boolean;
|
|
updated: number;
|
|
}
|
|
|
|
class App extends React.PureComponent<Props, State> {
|
|
public state: State = {
|
|
hasContracts: false,
|
|
isDeployOpen: false,
|
|
updated: 0
|
|
};
|
|
|
|
public constructor (props: Props) {
|
|
super(props);
|
|
|
|
store.on('new-code', this.triggerUpdate);
|
|
store.on('removed-code', this.triggerUpdate);
|
|
|
|
// since we have a dep on the async API, we load here
|
|
store.loadAll().catch((): void => {
|
|
// noop, handled internally
|
|
});
|
|
}
|
|
|
|
public static getDerivedStateFromProps ({ contracts }: Props): Pick<State, never> {
|
|
const hasContracts = !!contracts && Object.keys(contracts).length >= 1;
|
|
|
|
return {
|
|
hasContracts
|
|
};
|
|
}
|
|
|
|
public render (): React.ReactNode {
|
|
const { basePath, t } = this.props;
|
|
const { codeHash, isDeployOpen } = this.state;
|
|
const hidden: string[] = [];
|
|
|
|
return (
|
|
<main className='contracts--App'>
|
|
<HelpOverlay md={introMd} />
|
|
<header>
|
|
<Tabs
|
|
basePath={basePath}
|
|
hidden={hidden}
|
|
items={[
|
|
{
|
|
name: 'code',
|
|
text: 'Code'
|
|
},
|
|
{
|
|
isRoot: true,
|
|
name: 'contracts',
|
|
text: 'Contracts'
|
|
}
|
|
].map((tab): TabItem => ({ ...tab, text: t(tab.text) }))
|
|
}
|
|
/>
|
|
</header>
|
|
<Switch>
|
|
<Route path={`${basePath}/code`} render={this.renderComponent(Codes)} />
|
|
<Route render={this.renderComponent(Contracts)} exact />
|
|
</Switch>
|
|
<Deploy
|
|
basePath={basePath}
|
|
codeHash={codeHash}
|
|
isOpen={isDeployOpen}
|
|
onClose={this.hideDeploy}
|
|
/>
|
|
</main>
|
|
);
|
|
}
|
|
|
|
private renderComponent (Component: React.ComponentType<ComponentProps>): (p: LocationProps) => React.ReactNode {
|
|
return ({ match }: LocationProps): React.ReactNode => {
|
|
const { accounts, basePath, contracts, location, onStatusChange } = this.props;
|
|
|
|
if (!contracts) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Component
|
|
accounts={accounts}
|
|
basePath={basePath}
|
|
contracts={contracts}
|
|
hasCode={store.hasCode}
|
|
location={location}
|
|
match={match}
|
|
onStatusChange={onStatusChange}
|
|
showDeploy={this.showDeploy}
|
|
/>
|
|
);
|
|
};
|
|
}
|
|
|
|
private showDeploy = (codeHash?: string): () => void =>
|
|
(): void => {
|
|
this.setState({
|
|
codeHash: codeHash || undefined,
|
|
isDeployOpen: true
|
|
});
|
|
}
|
|
|
|
private hideDeploy = (): void => {
|
|
this.setState({ isDeployOpen: false });
|
|
}
|
|
|
|
private triggerUpdate = (): void => {
|
|
this.setState({ updated: Date.now() });
|
|
}
|
|
}
|
|
|
|
export default withMulti(
|
|
App,
|
|
translate,
|
|
withObservable(keyring.accounts.subject, { propName: 'accounts' }),
|
|
withObservable(keyring.contracts.subject, { propName: 'contracts' }),
|
|
withRouter
|
|
);
|