// 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 { KeyValue as Pair } from '@polkadot/types/interfaces'; import { Props as BaseProps, RawParam } from '../types'; import React from 'react'; import { WithTranslation } from 'react-i18next'; import { Vec } from '@polkadot/types'; import translate from '@polkadot/ui-app/translate'; import { assert, isHex, u8aToHex, u8aToString } from '@polkadot/util'; import Base from './Base'; import Bytes from './Bytes'; import File from './File'; import KeyValue from './KeyValue'; type Props = BaseProps & WithTranslation; interface State { placeholder?: string; } interface Parsed { isValid: boolean; value: { key: Uint8Array; value: Uint8Array; }[]; } const BYTES_TYPE = { type: 'Bytes', info: 0 }; class KeyValueArray extends React.PureComponent { private placeholderEmpty: string; public constructor (props: Props) { super(props); this.placeholderEmpty = props.t('click to select or drag and drop JSON key/value (hex-encoded) file'); this.state = { placeholder: this.placeholderEmpty }; } public render (): React.ReactNode { const { className, isDisabled, isError, label, style, withLabel } = this.props; const { placeholder } = this.state; if (isDisabled) { return this.renderReadOnly(); } return ( ); } private renderReadOnly (): React.ReactNode { const { className, defaultValue: { value }, label, onEnter, style } = this.props; const pairs = value as Vec; return ( <>
{pairs.map(([key, value]): React.ReactNode => { const keyHex = u8aToHex(key.toU8a(true)); return ( ); })}
); } private onChange = (raw: Uint8Array): void => { const { onChange, t } = this.props; let encoded: Parsed = { isValid: false, value: [] }; try { encoded = this.parseFile(raw); this.setState({ placeholder: t('{{count}} key/value pairs encoded for submission', { replace: { count: encoded.value.length } }) }); } catch (error) { console.error('Error converting json k/v', error); this.setState({ placeholder: this.placeholderEmpty }); } onChange && onChange(encoded); } private parseFile (raw: Uint8Array): Parsed { const json = JSON.parse(u8aToString(raw)); const keys = Object.keys(json); let isValid = keys.length !== 0; const value = keys.map((key): { key: Uint8Array; value: Uint8Array } => { const value = json[key]; assert(isHex(key) && isHex(value), `Non-hex key/value pair found in ${key.toString()} => ${value.toString()}`); const encKey = KeyValue.createParam(key); const encValue = KeyValue.createParam(value); isValid = isValid && encKey.isValid && encValue.isValid; return { key: encKey.u8a, value: encValue.u8a }; }); return { isValid, value }; } } export default translate(KeyValueArray);