// Copyright 2017-2019 @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/primitive/StorageKey'; import { I18nProps } from '@polkadot/ui-app/types'; import { QueryTypes, StorageModuleQuery } from './types'; import React from 'react'; import { Compact } from '@polkadot/types'; import { Button, Labelled } from '@polkadot/ui-app'; import valueToText from '@polkadot/ui-params/valueToText'; import { withCallDiv } from '@polkadot/ui-api'; import { isU8a, u8aToHex, u8aToString } from '@polkadot/util'; import translate from './translate'; import { RenderFn, DefaultProps, ComponentRenderer } from '@polkadot/ui-api/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 renderHelper = withCallDiv('subscribe', { paramName: 'params', paramValid: true, params: [key, ...values] }); const Component = renderHelper( // 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.createComponent(type, Component, defaultProps, renderHelper); } return cache[id]; } static createComponent (type: string, Component: React.ComponentType, defaultProps: DefaultProps, renderHelper: ComponentRenderer) { return { Component, // In order to replace the default component during runtime we can provide a RenderFn to create a new 'plugged' component render: (createComponent: RenderFn) => { return renderHelper(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 renderHelper( (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; const type = isU8a(key) ? 'Data' : ( key.meta.modifier.isOptional ? `Option<${key.meta.type}>` : key.meta.type.toString() ); return (
{this.keyToName(key)}: {type}
} >
{this.renderButtons()}
); } private renderButtons () { const { id, key } = this.props.value as StorageModuleQuery; const buttons = [