fs-walle-react-ts/src/LexInputContainer.tsx

266 lines
6.6 KiB
TypeScript
Raw Normal View History

2017-07-31 11:49:56 +00:00
import * as React from 'react';
import * as _ from 'lodash';
import { Label, Form } from 'semantic-ui-react';
const { Flex, Box } = require('reflexbox');
import {
Input,
Dropdown,
Image,
Modal,
Button,
} from 'semantic-ui-react';
class LexInputContainer extends React.Component<any, any> {
public render() {
return (
<div>
<Form>
<Form.Group as={Flex} inline={true} style={{ margin: '0 0 5px 5px' }}>
<Form.Field as={Box} w={2 / 5} style={{ textAlign: 'right' }}>
{this.props.label}
</Form.Field>
<Form.Field as={Box} w={3 / 5} >
{this.props.children}
</Form.Field>
</Form.Group>
</Form>
</div>
);
}
}
function changedLabel(changed: boolean, text: string) {
let labelClass = changed ? 'olive' : '';
return (
<Label
pointing="right"
className={labelClass}
>
{text}
</Label>
);
}
function textInput(params: any) {
let { field, sh, value, changed } = params;
return (
<LexInputContainer
label={changedLabel(changed, field)}
key={field}
>
<Input
onChange={(e, d) => { sh(d.value); }}
value={value}
placeholder={field}
type="text"
dir="auto"
style={{ width: '10em' }}
/>
</LexInputContainer>
);
}
function selectInput(params: any) {
let { field, sh, value, options, langSelOpts, changed } = params;
let staticOpts = options;
let fieldOpts = _.get<any>(langSelOpts, field, []);
let selOpts = staticOpts ? staticOpts : fieldOpts;
let dropOptions = selOpts.map((k: any, i: any, c: any) => {
return { key: i, value: k, text: k };
});
return (
<LexInputContainer key={field} label={changedLabel(changed, field)}>
<Dropdown
options={dropOptions}
onChange={(e, d) => { sh(d.value); }}
value={value}
compact={true}
selection={true}
search={true}
style={{ width: '10em' }}
/>
</LexInputContainer>
);
}
function imagePreview(params: any) {
let { field, value, changed } = params;
let imageSrc = '/png/' + value;
return value !== '' ? (
<LexInputContainer key={field} label={changedLabel(changed, field)}>
<Image src={imageSrc} size="large" bordered={true} />
</LexInputContainer>
) : textInput(params);
}
function listInput(params: any) {
let { field, sh, langSelOpts, value, changed } = params;
let fieldOpts = _.get<any>(langSelOpts, field, []);
let renderLabel = (label: any) => ({
content: `${label.value}`,
});
let dropOptions = fieldOpts.map((k: any, i: any, c: any) => {
return {
key: i,
value: k,
text: k,
};
});
return (
<LexInputContainer key={field} label={changedLabel(changed, field)}>
<Dropdown
options={dropOptions}
onChange={(e, d) => {
sh(d.value);
}}
value={value}
compact={true}
selection={true}
search={true}
multiple={true}
fluid={true}
style={{ width: '10em' }}
renderLabel={renderLabel}
/>
</LexInputContainer>
);
}
function propListInput(params: any) {
let { field, changed } = params;
return (
<LexInputContainer key={field} label={changedLabel(changed, field)}>
<PropListInput params={params} />
</LexInputContainer>
);
}
class PropListInput extends React.Component<any, any> {
constructor(props: any) {
super(props);
let { value } = this.props.params;
let dropOptions = this.dropOptsForVal(value);
this.state = { value, dropOptions, modalOpen: false, exKey: '', exVal: '' };
}
dropOptsForVal(value: any) {
let { field, langSelOpts } = this.props.params;
let fieldOpts = _.get<any>(langSelOpts, field, []);
function valueForKey(key: string) {
let match = _.find(value, (v: any) => _.isEqual(v.key, key));
if (match) {
return match;
} else {
return { key, value: '' };
}
}
return fieldOpts.map((k: any, i: any) => {
return {
key: i,
value: valueForKey(k),
text: k,
};
});
}
public render() {
let { sh } = this.props.params;
let renderLabel = (label: any) => ({
content: `${label.value.key}-${label.value.value}`,
});
let value = _.filter(this.state.dropOptions, (o: any) => {
return _.some(this.state.value, (v: any) => {
return _.isEqual(v.key, o.value.key);
});
}).map((so) => so.value);
let onCloseModal = (e: any) => {
let except = { key: this.state.exKey, value: this.state.exVal };
let ns = _.concat(this.state.value, except);
this.setState({
dropOptions: this.dropOptsForVal(ns),
value: ns,
modalOpen: false,
exKey: '',
exVal: ''
});
sh(ns);
};
let dropDownComp = (
<Dropdown
options={this.state.dropOptions}
onChange={(e, d) => {
let newValue = d.value as any;
let addedValue = _.difference(newValue, this.state.value) as any;
console.log('added: ', addedValue);
let didAdd = _.size(addedValue) > 0;
let newState = didAdd ? {
exKey: addedValue[0].key,
} : {
exKey: '',
value: newValue
} as any;
this.setState({ ...newState, modalOpen: didAdd });
if (!didAdd) {
sh(newValue);
}
}}
value={value}
compact={true}
selection={true}
search={true}
multiple={true}
fluid={true}
style={{ width: '10em' }}
renderLabel={renderLabel}
/>
);
return (
<Modal
open={this.state.modalOpen}
onClose={onCloseModal}
size="mini"
trigger={dropDownComp}
>
<Modal.Content>
Enter the exception for {this.state.exKey}
</Modal.Content>
<Modal.Actions>
<Input
focus={true}
onChange={(e, d: any) => {
this.setState({ exVal: d.value });
}}
/>
<Button onClick={onCloseModal}>
Done
</Button>
</Modal.Actions>
</Modal>
);
}
}
export function componentForType(type: string, params: any) {
switch (type) {
case 'text': {
return textInput(params);
}
case 'select': {
return selectInput(params);
}
case 'preview': {
return imagePreview(params);
}
case 'list': {
return listInput(params);
}
case 'proplist': {
return propListInput(params);
}
default: {
console.log('type discarded :', type);
return null;
}
}
}