// Copyright 2017-2018 @polkadot/app-storage 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 { StorageFunction } from '@polkadot/types/StorageKey'; import { I18nProps } from '@polkadot/ui-app/types'; import { QueryTypes, StorageModuleQuery } from './types'; import React from 'react'; import { Compact } from '@polkadot/types/codec'; import { Button, Labelled } from '@polkadot/ui-app/index'; import valueToText from '@polkadot/ui-app/Params/valueToText'; import { withObservableDiv } from '@polkadot/ui-react-rx/with/index'; import { isU8a, u8aToHex, u8aToString } from '@polkadot/util'; import translate from './translate'; import { RenderFn, DefaultProps, ComponentRenderer } from '@polkadot/ui-react-rx/with/types'; type Props = I18nProps & { onRemove: (id: number) => void, value: QueryTypes }; type ComponentProps = {}; type State = { inputs: Array, Component: React.ComponentType, spread: { [index: number]: boolean } }; type CacheInstance = { Component: React.ComponentType, render: RenderFn, refresh: (swallowErrors: boolean, contentShorten: boolean) => React.ComponentType }; const cache: Array = []; class Query extends React.PureComponent { state: State = { spread: {} } as State; static getCachedComponent (query: QueryTypes): CacheInstance { const { id, key, params = [] } = query as StorageModuleQuery; if (!cache[id]) { const values: Array = params.map(({ value }) => value); const type = key.meta ? key.meta.type.toString() : 'Data'; const defaultProps = { className: 'ui--output' }; // render function to create an element for the query results which is plugged to the api const fetchAndRenderHelper = withObservableDiv('rawStorage', { params: [key, ...values] }); const pluggedComponent = fetchAndRenderHelper( // By default we render a simple div node component with the query results in it (value: any) => valueToText(type, value, true, true), defaultProps ); cache[query.id] = Query.createComponentCacheInstance(type, pluggedComponent, defaultProps, fetchAndRenderHelper); } return cache[id]; } static createComponentCacheInstance (type: string, pluggedComponent: React.ComponentType, defaultProps: DefaultProps, fetchAndRenderHelper: ComponentRenderer) { return { Component: pluggedComponent, // In order to replace the default component during runtime we can provide a RenderFn to create a new 'plugged' component render: (createComponent: RenderFn) => { return fetchAndRenderHelper( createComponent, defaultProps ); }, // In order to modify the parameters which are used to render the default component, we can use this method refresh: (swallowErrors: boolean, contentShorten: boolean) => { return fetchAndRenderHelper( (value: any) => valueToText(type, value, swallowErrors, contentShorten), defaultProps ); } }; } static getDerivedStateFromProps ({ value }: Props, prevState: State): State | null { const Component = Query.getCachedComponent(value).Component; const inputs: Array = isU8a(value.key) ? [] // FIXME We need to render the actual key params // const { key, params } = value; // const inputs = key.params.map(({ name, type }, index) => ( // // {name}={valueToText(type, params[index].value)} // // )); : []; return { Component, inputs } as State; } render () { const { value } = this.props; const { Component } = this.state; const { key } = value; return (
{this.keyToName(key)}
{this.renderInputs()}
{ isU8a(key) ? 'Data' : key.meta.type.toString() }
} >
{this.renderButtons()}
); } private renderButtons () { const { id, key } = this.props.value as StorageModuleQuery; const buttons = [