refactored setup and added save button
parent
a959b8a0a1
commit
707f151bdc
|
|
@ -0,0 +1,229 @@
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
function simpleAccessor(lens: string, def: string = '') {
|
||||||
|
return {
|
||||||
|
get: (li: any) => {
|
||||||
|
let val = _.get<any>(li, lens, def);
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
set: (li: any, value: string) => {
|
||||||
|
let lexItem = _.cloneDeep(li);
|
||||||
|
let ret = _.set<any>(lexItem, lens, value);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function simpleAttrAccessor(attrPred: any) {
|
||||||
|
let { attribVal, attribKey, pred, lens } = attrPred;
|
||||||
|
let def = (value: any) => ({ _: value, $: { [attribKey]: attribVal } });
|
||||||
|
return {
|
||||||
|
get: (li: any) => {
|
||||||
|
let allProps = _.get<any>(li, lens, def(''));
|
||||||
|
let prop = _.filter<any>(allProps, (m) => {
|
||||||
|
return pred(m);
|
||||||
|
});
|
||||||
|
let mcls = _.get<any>(prop, '[0]._', '');
|
||||||
|
return mcls;
|
||||||
|
},
|
||||||
|
set: (li: any, value: string) => {
|
||||||
|
let lexItem = _.cloneDeep(li);
|
||||||
|
let allProps = _.get<any>(lexItem, lens, []);
|
||||||
|
if (allProps.length > 0) {
|
||||||
|
let prop = _.filter<any>(allProps, (m) => {
|
||||||
|
return pred(m);
|
||||||
|
});
|
||||||
|
_.set(prop, '[0]._', value);
|
||||||
|
} else {
|
||||||
|
_.set(lexItem, lens, [def(value)]);
|
||||||
|
}
|
||||||
|
return lexItem;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function listAttrAccessor(attrPred: any) {
|
||||||
|
let { pred, lens } = attrPred;
|
||||||
|
return {
|
||||||
|
get: (li: any) => {
|
||||||
|
let def: any = [];
|
||||||
|
let morphProps = _.get<any>(li, lens, def);
|
||||||
|
let morphExps = _.filter<any>(morphProps, (m) => {
|
||||||
|
return pred(m);
|
||||||
|
});
|
||||||
|
let mEs = morphExps.map((me) => {
|
||||||
|
return _.get<any>(me, '_', me);
|
||||||
|
});
|
||||||
|
return mEs;
|
||||||
|
},
|
||||||
|
set: (li: any, value: any) => {
|
||||||
|
let lexItem = _.cloneDeep(li);
|
||||||
|
let allProps = _.get<any>(lexItem, lens, []);
|
||||||
|
if (allProps.length > 0) {
|
||||||
|
let keepProps = _.filter<any>(allProps, (m) => {
|
||||||
|
return !pred(m);
|
||||||
|
});
|
||||||
|
_.set(lexItem, lens, _.concat(keepProps, value));
|
||||||
|
} else {
|
||||||
|
_.set(lexItem, lens, value);
|
||||||
|
}
|
||||||
|
return lexItem;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function propListAttrAccessor(attrPred: any) {
|
||||||
|
let { attribKey, pred, lens } = attrPred;
|
||||||
|
return {
|
||||||
|
get: (li: any) => {
|
||||||
|
let def: any = [];
|
||||||
|
let morphProps = _.get<any>(li, lens, def);
|
||||||
|
let morphExps = _.filter<any>(morphProps, (m) => {
|
||||||
|
return pred(m);
|
||||||
|
});
|
||||||
|
let mEs = morphExps.map((me) => {
|
||||||
|
let value = _.get<any>(me, '_', me);
|
||||||
|
let key = _.get<any>(me, '$.' + attribKey, '');
|
||||||
|
return { value, key };
|
||||||
|
});
|
||||||
|
return mEs;
|
||||||
|
},
|
||||||
|
set: (li: any, value: any) => {
|
||||||
|
let lexItem = _.cloneDeep(li);
|
||||||
|
let allProps = _.get<any>(lexItem, lens, []);
|
||||||
|
if (allProps.length > 0) {
|
||||||
|
let keepProps = _.filter<any>(allProps, (m) => {
|
||||||
|
return !pred(m);
|
||||||
|
});
|
||||||
|
_.set(lexItem, lens, _.concat(keepProps, value));
|
||||||
|
} else {
|
||||||
|
_.set(lexItem, lens, value);
|
||||||
|
}
|
||||||
|
return lexItem;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const attrPredGen = (lens: string, key: string, val: string, comp: any) => {
|
||||||
|
const pred = (m: any) => comp(_.get<any>(m, '$.' + key, ''), val);
|
||||||
|
return { lens, attribKey: key, attribVal: val, pred };
|
||||||
|
};
|
||||||
|
|
||||||
|
const fieldMetaMap = {
|
||||||
|
label: {
|
||||||
|
type: 'text',
|
||||||
|
...simpleAccessor('label[0]'),
|
||||||
|
},
|
||||||
|
unl: { type: 'text', ...simpleAccessor('unl[0]'), },
|
||||||
|
synset: { type: 'text', ...simpleAccessor('lexprops[0].wnsynset[0]'), },
|
||||||
|
guid: { type: 'text', ...simpleAccessor('guid[0]'), },
|
||||||
|
pos: { type: 'select', ...simpleAccessor('pos[0]'), },
|
||||||
|
image: { type: 'preview', ...simpleAccessor('image[0]'), },
|
||||||
|
relations: { type: 'text', ...simpleAccessor('relations[0]'), },
|
||||||
|
frame: {
|
||||||
|
type: 'select',
|
||||||
|
...simpleAttrAccessor(attrPredGen(
|
||||||
|
'syntacticprops[0].property',
|
||||||
|
'id',
|
||||||
|
'frame',
|
||||||
|
_.isEqual
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
cat: {
|
||||||
|
type: 'select',
|
||||||
|
...simpleAttrAccessor(attrPredGen(
|
||||||
|
'uiprops[0].property',
|
||||||
|
'id',
|
||||||
|
'cat',
|
||||||
|
_.isEqual
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
subcat: {
|
||||||
|
type: 'select',
|
||||||
|
...simpleAttrAccessor(attrPredGen(
|
||||||
|
'uiprops[0].property',
|
||||||
|
'id',
|
||||||
|
'subcat',
|
||||||
|
_.isEqual
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
morphclass: {
|
||||||
|
type: 'select',
|
||||||
|
...simpleAttrAccessor(attrPredGen(
|
||||||
|
'lexprops[0].morphology[0].morph',
|
||||||
|
'form',
|
||||||
|
'morphclass',
|
||||||
|
_.isEqual
|
||||||
|
))
|
||||||
|
},
|
||||||
|
morphexceptions: {
|
||||||
|
type: 'proplist',
|
||||||
|
...propListAttrAccessor(attrPredGen(
|
||||||
|
'lexprops[0].morphology[0].morph',
|
||||||
|
'form',
|
||||||
|
'morphclass',
|
||||||
|
_.negate(_.isEqual)
|
||||||
|
))
|
||||||
|
},
|
||||||
|
stats: { type: 'text', ...simpleAccessor('stats[0].property[0]._'), },
|
||||||
|
lang: {
|
||||||
|
type: 'select',
|
||||||
|
options: ['en', 'es'], ...simpleAccessor('$.id', 'en'),
|
||||||
|
},
|
||||||
|
syntacticprops: {
|
||||||
|
type: 'list',
|
||||||
|
...listAttrAccessor(attrPredGen(
|
||||||
|
'syntacticprops[0].property',
|
||||||
|
'id',
|
||||||
|
'frame',
|
||||||
|
_.negate(_.isEqual)
|
||||||
|
))
|
||||||
|
},
|
||||||
|
groups: {
|
||||||
|
type: 'list',
|
||||||
|
...listAttrAccessor(attrPredGen(
|
||||||
|
'groups[0].property',
|
||||||
|
'id',
|
||||||
|
'frame',
|
||||||
|
_.negate(_.isEqual)
|
||||||
|
))
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const xmlToEntries = (xmlData: any) => {
|
||||||
|
let allEntries = _.chain(xmlData)
|
||||||
|
.get<any>('document.lexicon[0].item')
|
||||||
|
.flatMap((o: any) => _.chain(o)
|
||||||
|
.get<any>('entry')
|
||||||
|
.map((p: any) => _.chain(p)
|
||||||
|
.get<any>('lang[0]')
|
||||||
|
.set('guid[0]', o.$.guid)
|
||||||
|
.value())
|
||||||
|
.value()
|
||||||
|
)
|
||||||
|
.value();
|
||||||
|
let langReducer = ((result: any, q: any) => {
|
||||||
|
let lang = fieldMetaMap.lang.get(q);
|
||||||
|
(result[lang] || (result[lang] = [])).push(q);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
let langEntries = _.reduce(allEntries, langReducer, {});
|
||||||
|
let langs = _.keys(langEntries);
|
||||||
|
let selectFields = _.fromPairs(langs.map((lang) => {
|
||||||
|
let langOpts = _.fromPairs(_.keys(fieldMetaMap).filter((s) => {
|
||||||
|
return _.includes(['select', 'list'], fieldMetaMap[s].type);
|
||||||
|
}).map((s) => {
|
||||||
|
let entries = _.get<any>(langEntries, lang, 'en');
|
||||||
|
let allOpts = entries.map((q: any) => {
|
||||||
|
return fieldMetaMap[s].get(q);
|
||||||
|
});
|
||||||
|
let select = _.isEqual(fieldMetaMap[s].type, 'select');
|
||||||
|
let selectOptions = select ? _.uniq(allOpts) : _.uniq(_.flatten(allOpts));
|
||||||
|
return [s, selectOptions];
|
||||||
|
}));
|
||||||
|
return [lang, langOpts];
|
||||||
|
}));
|
||||||
|
return ({
|
||||||
|
allEntries, selectFields, fieldMetaMap
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -114,6 +114,8 @@ export class LexEdit extends React.Component<any, any> {
|
||||||
|
|
||||||
private handleOnSave(event: any) {
|
private handleOnSave(event: any) {
|
||||||
this.props.save(this.state.lexItem, this.props.fieldMetaMap);
|
this.props.save(this.state.lexItem, this.props.fieldMetaMap);
|
||||||
this.props.saveXMLBackend();
|
if (!_.isEqual(this.state.lexItem, this.props.lexItem)) {
|
||||||
|
this.props.markDirty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ import { LexEdit } from './LexEdit';
|
||||||
import {
|
import {
|
||||||
Input,
|
Input,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
|
Container,
|
||||||
|
Header
|
||||||
} from 'semantic-ui-react';
|
} from 'semantic-ui-react';
|
||||||
const { Flex } = require('reflexbox');
|
const { Flex } = require('reflexbox');
|
||||||
|
|
||||||
|
|
@ -16,14 +18,14 @@ export class LexEditor extends React.Component<any, any> {
|
||||||
.filter((q: any) => searchMeta.get(q) === searchText)
|
.filter((q: any) => searchMeta.get(q) === searchText)
|
||||||
.take(10)
|
.take(10)
|
||||||
.value();
|
.value();
|
||||||
let { fieldMetaMap, save, saveXMLBackend } = this.props;
|
let { fieldMetaMap, save, markDirty } = this.props;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<LexSearch
|
<LexSearch
|
||||||
{...this.props}
|
{...this.props}
|
||||||
/>
|
/>
|
||||||
<LexMatches
|
<LexMatches
|
||||||
{...{ fieldMetaMap, save, saveXMLBackend }}
|
{...{ fieldMetaMap, save, markDirty }}
|
||||||
matchedEntries={matchedEntries}
|
matchedEntries={matchedEntries}
|
||||||
selectionMeta={this.props.selectFields}
|
selectionMeta={this.props.selectFields}
|
||||||
searchText={searchText}
|
searchText={searchText}
|
||||||
|
|
@ -40,13 +42,14 @@ class LexSearch extends React.Component<any, any> {
|
||||||
return { key: i, value: k, text: _.capitalize(k) };
|
return { key: i, value: k, text: _.capitalize(k) };
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<div>
|
<Container textAlign="center">
|
||||||
<Dropdown
|
<Dropdown
|
||||||
options={dropOptions}
|
options={dropOptions}
|
||||||
onChange={(e, d) => this.handleChange(d, true)}
|
onChange={(e, d) => this.handleChange(d, true)}
|
||||||
value={this.props.searchState.searchType}
|
value={this.props.searchState.searchType}
|
||||||
compact={true}
|
compact={true}
|
||||||
selection={true}
|
selection={true}
|
||||||
|
style={{ width: '10em' }}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
@ -56,7 +59,7 @@ class LexSearch extends React.Component<any, any> {
|
||||||
icon="filter"
|
icon="filter"
|
||||||
onChange={(e, d) => this.handleChange(d, false)}
|
onChange={(e, d) => this.handleChange(d, false)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,10 +76,10 @@ function LexMatches(params: any) {
|
||||||
const selectMode = (props: any) => {
|
const selectMode = (props: any) => {
|
||||||
if (props.searchText === '') {
|
if (props.searchText === '') {
|
||||||
return (
|
return (
|
||||||
<div>
|
<Container>
|
||||||
<h4>Empty</h4>
|
<Header size="mini">Empty</Header>
|
||||||
Type something in the searchbar.
|
Type something in the searchbar.
|
||||||
</div>
|
</Container>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let editEntries = props.matchedEntries.map((mObj: any) => {
|
let editEntries = props.matchedEntries.map((mObj: any) => {
|
||||||
|
|
|
||||||
291
src/LexSetup.tsx
291
src/LexSetup.tsx
|
|
@ -1,251 +1,26 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Dimmer, Loader, Header, Icon, Segment } from 'semantic-ui-react';
|
import {
|
||||||
|
Dimmer, Loader, Header, Icon, Segment, Button
|
||||||
|
} from 'semantic-ui-react';
|
||||||
import * as XML from 'xml2js';
|
import * as XML from 'xml2js';
|
||||||
import * as _ from 'lodash';
|
// import * as _ from 'lodash';
|
||||||
|
import { xmlToEntries } from './LexAccessors';
|
||||||
import { LexEditor } from './LexEditor';
|
import { LexEditor } from './LexEditor';
|
||||||
|
|
||||||
function simpleAccessor(lens: string, def: string = '') {
|
|
||||||
return {
|
|
||||||
get: (li: any) => {
|
|
||||||
let val = _.get<any>(li, lens, def);
|
|
||||||
return val;
|
|
||||||
},
|
|
||||||
set: (li: any, value: string) => {
|
|
||||||
let lexItem = _.cloneDeep(li);
|
|
||||||
let ret = _.set<any>(lexItem, lens, value);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function simpleAttrAccessor(attrPred: any) {
|
|
||||||
let { attribVal, attribKey, pred, lens } = attrPred;
|
|
||||||
let def = (value: any) => ({ _: value, $: { [attribKey]: attribVal } });
|
|
||||||
return {
|
|
||||||
get: (li: any) => {
|
|
||||||
let allProps = _.get<any>(li, lens, def(''));
|
|
||||||
let prop = _.filter<any>(allProps, (m) => {
|
|
||||||
return pred(m);
|
|
||||||
});
|
|
||||||
let mcls = _.get<any>(prop, '[0]._', '');
|
|
||||||
return mcls;
|
|
||||||
},
|
|
||||||
set: (li: any, value: string) => {
|
|
||||||
let lexItem = _.cloneDeep(li);
|
|
||||||
let allProps = _.get<any>(lexItem, lens, []);
|
|
||||||
if (allProps.length > 0) {
|
|
||||||
let prop = _.filter<any>(allProps, (m) => {
|
|
||||||
return pred(m);
|
|
||||||
});
|
|
||||||
_.set(prop, '[0]._', value);
|
|
||||||
} else {
|
|
||||||
_.set(lexItem, lens, [def(value)]);
|
|
||||||
}
|
|
||||||
return lexItem;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function listAttrAccessor(attrPred: any) {
|
|
||||||
let { pred, lens } = attrPred;
|
|
||||||
return {
|
|
||||||
get: (li: any) => {
|
|
||||||
let def: any = [];
|
|
||||||
let morphProps = _.get<any>(li, lens, def);
|
|
||||||
let morphExps = _.filter<any>(morphProps, (m) => {
|
|
||||||
return pred(m);
|
|
||||||
});
|
|
||||||
let mEs = morphExps.map((me) => {
|
|
||||||
return _.get<any>(me, '_', me);
|
|
||||||
});
|
|
||||||
return mEs;
|
|
||||||
},
|
|
||||||
set: (li: any, value: any) => {
|
|
||||||
let lexItem = _.cloneDeep(li);
|
|
||||||
let allProps = _.get<any>(lexItem, lens, []);
|
|
||||||
if (allProps.length > 0) {
|
|
||||||
let keepProps = _.filter<any>(allProps, (m) => {
|
|
||||||
return !pred(m);
|
|
||||||
});
|
|
||||||
_.set(lexItem, lens, _.concat(keepProps, value));
|
|
||||||
} else {
|
|
||||||
_.set(lexItem, lens, value);
|
|
||||||
}
|
|
||||||
return lexItem;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function propListAttrAccessor(attrPred: any) {
|
|
||||||
let { attribKey, pred, lens } = attrPred;
|
|
||||||
return {
|
|
||||||
get: (li: any) => {
|
|
||||||
let def: any = [];
|
|
||||||
let morphProps = _.get<any>(li, lens, def);
|
|
||||||
let morphExps = _.filter<any>(morphProps, (m) => {
|
|
||||||
return pred(m);
|
|
||||||
});
|
|
||||||
let mEs = morphExps.map((me) => {
|
|
||||||
let value = _.get<any>(me, '_', me);
|
|
||||||
let key = _.get<any>(me, '$.' + attribKey, '');
|
|
||||||
return { value, key };
|
|
||||||
});
|
|
||||||
return mEs;
|
|
||||||
},
|
|
||||||
set: (li: any, value: any) => {
|
|
||||||
let lexItem = _.cloneDeep(li);
|
|
||||||
let allProps = _.get<any>(lexItem, lens, []);
|
|
||||||
if (allProps.length > 0) {
|
|
||||||
let keepProps = _.filter<any>(allProps, (m) => {
|
|
||||||
return !pred(m);
|
|
||||||
});
|
|
||||||
_.set(lexItem, lens, _.concat(keepProps, value));
|
|
||||||
} else {
|
|
||||||
_.set(lexItem, lens, value);
|
|
||||||
}
|
|
||||||
return lexItem;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const attrPredGen = (lens: string, key: string, val: string, comp: any) => {
|
|
||||||
const pred = (m: any) => comp(_.get<any>(m, '$.' + key, ''), val);
|
|
||||||
return { lens, attribKey: key, attribVal: val, pred };
|
|
||||||
};
|
|
||||||
|
|
||||||
const fieldMetaMap = {
|
|
||||||
label: {
|
|
||||||
type: 'text',
|
|
||||||
...simpleAccessor('label[0]'),
|
|
||||||
},
|
|
||||||
unl: { type: 'text', ...simpleAccessor('unl[0]'), },
|
|
||||||
synset: { type: 'text', ...simpleAccessor('lexprops[0].wnsynset[0]'), },
|
|
||||||
guid: { type: 'text', ...simpleAccessor('guid[0]'), },
|
|
||||||
pos: { type: 'select', ...simpleAccessor('pos[0]'), },
|
|
||||||
image: { type: 'preview', ...simpleAccessor('image[0]'), },
|
|
||||||
relations: { type: 'text', ...simpleAccessor('relations[0]'), },
|
|
||||||
frame: {
|
|
||||||
type: 'select',
|
|
||||||
...simpleAttrAccessor(attrPredGen(
|
|
||||||
'syntacticprops[0].property',
|
|
||||||
'id',
|
|
||||||
'frame',
|
|
||||||
_.isEqual
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
cat: {
|
|
||||||
type: 'select',
|
|
||||||
...simpleAttrAccessor(attrPredGen(
|
|
||||||
'uiprops[0].property',
|
|
||||||
'id',
|
|
||||||
'cat',
|
|
||||||
_.isEqual
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
subcat: {
|
|
||||||
type: 'select',
|
|
||||||
...simpleAttrAccessor(attrPredGen(
|
|
||||||
'uiprops[0].property',
|
|
||||||
'id',
|
|
||||||
'subcat',
|
|
||||||
_.isEqual
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
morphclass: {
|
|
||||||
type: 'select',
|
|
||||||
...simpleAttrAccessor(attrPredGen(
|
|
||||||
'lexprops[0].morphology[0].morph',
|
|
||||||
'form',
|
|
||||||
'morphclass',
|
|
||||||
_.isEqual
|
|
||||||
))
|
|
||||||
},
|
|
||||||
morphexceptions: {
|
|
||||||
type: 'proplist',
|
|
||||||
...propListAttrAccessor(attrPredGen(
|
|
||||||
'lexprops[0].morphology[0].morph',
|
|
||||||
'form',
|
|
||||||
'morphclass',
|
|
||||||
_.negate(_.isEqual)
|
|
||||||
))
|
|
||||||
},
|
|
||||||
stats: { type: 'text', ...simpleAccessor('stats[0].property[0]._'), },
|
|
||||||
lang: {
|
|
||||||
type: 'select',
|
|
||||||
options: ['en', 'es'], ...simpleAccessor('$.id', 'en'),
|
|
||||||
},
|
|
||||||
syntacticprops: {
|
|
||||||
type: 'list',
|
|
||||||
...listAttrAccessor(attrPredGen(
|
|
||||||
'syntacticprops[0].property',
|
|
||||||
'id',
|
|
||||||
'frame',
|
|
||||||
_.negate(_.isEqual)
|
|
||||||
))
|
|
||||||
},
|
|
||||||
groups: {
|
|
||||||
type: 'list',
|
|
||||||
...listAttrAccessor(attrPredGen(
|
|
||||||
'groups[0].property',
|
|
||||||
'id',
|
|
||||||
'frame',
|
|
||||||
_.negate(_.isEqual)
|
|
||||||
))
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const xmlToEntries = (xmlData: any) => {
|
|
||||||
let allEntries = _.chain(xmlData)
|
|
||||||
.get<any>('document.lexicon[0].item')
|
|
||||||
.flatMap((o: any) => _.chain(o)
|
|
||||||
.get<any>('entry')
|
|
||||||
.map((p: any) => _.chain(p)
|
|
||||||
.get<any>('lang[0]')
|
|
||||||
.set('guid[0]', o.$.guid)
|
|
||||||
.value())
|
|
||||||
.value()
|
|
||||||
)
|
|
||||||
.value();
|
|
||||||
let langReducer = ((result: any, q: any) => {
|
|
||||||
let lang = fieldMetaMap.lang.get(q);
|
|
||||||
(result[lang] || (result[lang] = [])).push(q);
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
let langEntries = _.reduce(allEntries, langReducer, {});
|
|
||||||
let langs = _.keys(langEntries);
|
|
||||||
let selectFields = _.fromPairs(langs.map((lang) => {
|
|
||||||
let langOpts = _.fromPairs(_.keys(fieldMetaMap).filter((s) => {
|
|
||||||
return _.includes(['select', 'list'], fieldMetaMap[s].type);
|
|
||||||
}).map((s) => {
|
|
||||||
let entries = _.get<any>(langEntries, lang, 'en');
|
|
||||||
let allOpts = entries.map((q: any) => {
|
|
||||||
return fieldMetaMap[s].get(q);
|
|
||||||
});
|
|
||||||
let select = _.isEqual(fieldMetaMap[s].type, 'select');
|
|
||||||
let selectOptions = select ? _.uniq(allOpts) : _.uniq(_.flatten(allOpts));
|
|
||||||
return [s, selectOptions];
|
|
||||||
}));
|
|
||||||
return [lang, langOpts];
|
|
||||||
}));
|
|
||||||
return ({
|
|
||||||
allEntries, selectFields, fieldMetaMap
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export class LexSetup extends React.Component<any, any> {
|
export class LexSetup extends React.Component<any, any> {
|
||||||
xmlBuilder = new XML.Builder();
|
xmlBuilder = new XML.Builder();
|
||||||
|
fileName = 'new_es_orig.xml';
|
||||||
constructor(props: any) {
|
constructor(props: any) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { xmlLoaded: false };
|
this.state = { xmlLoaded: false, dirty: false };
|
||||||
}
|
}
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
let fileName = '/new_es_orig.xml';
|
fetch(this.fileName)
|
||||||
fetch(fileName)
|
|
||||||
.then((response) => response.text())
|
.then((response) => response.text())
|
||||||
.then((xmlString) => {
|
.then((xmlString) => {
|
||||||
XML.parseString(xmlString, (err, xmlData) => {
|
XML.parseString(xmlString, (err, xmlData) => {
|
||||||
let props = this.props;
|
// let props = this.props;
|
||||||
_.noop(props);
|
// _.noop(props);
|
||||||
this.props.addXmlData(xmlData);
|
this.props.addXmlData(xmlData);
|
||||||
this.setState({ xmlLoaded: true });
|
this.setState({ xmlLoaded: true });
|
||||||
});
|
});
|
||||||
|
|
@ -261,28 +36,38 @@ export class LexSetup extends React.Component<any, any> {
|
||||||
<Loader inverted={true}>Loading</Loader>
|
<Loader inverted={true}>Loading</Loader>
|
||||||
</Dimmer>
|
</Dimmer>
|
||||||
);
|
);
|
||||||
|
let saveButton = this.state.dirty ?
|
||||||
|
(<Button floated="right" size="mini">Save</Button>) : null;
|
||||||
let xmlEntries = xmlToEntries(this.props.xmlData);
|
let xmlEntries = xmlToEntries(this.props.xmlData);
|
||||||
let saveXMLBackend = () => {
|
// let saveXMLBackend = () => {
|
||||||
this.setState({ xmlLoaded: false });
|
// this.setState({ xmlLoaded: false });
|
||||||
let xmlText = this.xmlBuilder.buildObject(this.props.xmlData);
|
// let xmlText = this.xmlBuilder.buildObject(this.props.xmlData);
|
||||||
fetch('/api/save', {
|
// let data = new FormData();
|
||||||
method: 'POST',
|
// data.append('file', xmlText);
|
||||||
body: xmlText
|
// data.append('name', 'new_es_s.xml'); // this.fileName
|
||||||
})
|
// fetch('/api/save', {
|
||||||
.then((response) => response.text())
|
// method: 'POST',
|
||||||
.then((rsptext) => {
|
// body: data
|
||||||
console.log('response', rsptext);
|
// })
|
||||||
this.setState({ xmlLoaded: true });
|
// .then((response) => response.text())
|
||||||
})
|
// .then((rsptext) => {
|
||||||
.catch((e) => {
|
// console.log('response', rsptext);
|
||||||
// console.log('errored :', e);
|
// this.setState({ xmlLoaded: true });
|
||||||
this.setState({ xmlLoaded: true });
|
// })
|
||||||
});
|
// .catch((e) => {
|
||||||
|
// // console.log('errored :', e);
|
||||||
|
// this.setState({ xmlLoaded: true });
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
// _.noop(saveXMLBackend);
|
||||||
|
let markDirty = () => {
|
||||||
|
this.setState({ dirty: true });
|
||||||
};
|
};
|
||||||
let editor = (
|
let editor = (
|
||||||
<div>
|
<div>
|
||||||
<Segment inverted={true} size="tiny" attached={true}>
|
<Segment inverted={true} size="tiny" attached={true}>
|
||||||
<Header inverted={true} color="teal" size="mini">
|
<Header color="teal" size="mini">
|
||||||
|
{saveButton}
|
||||||
<Icon name="edit" size="small" />
|
<Icon name="edit" size="small" />
|
||||||
<Header.Content>
|
<Header.Content>
|
||||||
Freespeech Lexicon Editor
|
Freespeech Lexicon Editor
|
||||||
|
|
@ -292,7 +77,7 @@ export class LexSetup extends React.Component<any, any> {
|
||||||
<LexEditor
|
<LexEditor
|
||||||
{...xmlEntries}
|
{...xmlEntries}
|
||||||
{...this.props}
|
{...this.props}
|
||||||
saveXMLBackend={saveXMLBackend}
|
markDirty={markDirty}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ app = Flask(__name__,static_url_path='',static_folder='build')
|
||||||
from freespeech_walle.get_morph_rule import get_morph
|
from freespeech_walle.get_morph_rule import get_morph
|
||||||
# from freespeech_walle.wizard_helpers import get_morph_rule,get_frequency
|
# from freespeech_walle.wizard_helpers import get_morph_rule,get_frequency
|
||||||
import json
|
import json
|
||||||
|
import codecs
|
||||||
# from flask_cors import CORS, cross_origin
|
# from flask_cors import CORS, cross_origin
|
||||||
# CORS(app)
|
# CORS(app)
|
||||||
|
|
||||||
|
|
@ -25,7 +25,11 @@ def walle_morph():
|
||||||
|
|
||||||
@app.route('/api/save',methods=['POST'])
|
@app.route('/api/save',methods=['POST'])
|
||||||
def walle_save():
|
def walle_save():
|
||||||
print request.form
|
xmlData = request.form.get('file',None);
|
||||||
|
xmlFileName = request.form.get('name','new_es_saved.xml');
|
||||||
|
if xmlData:
|
||||||
|
with codecs.open('build/'+xmlFileName,'wb','utf-8') as xmlF:
|
||||||
|
xmlF.write(xmlData);
|
||||||
return 'ok'
|
return 'ok'
|
||||||
|
|
||||||
# hmr streaming
|
# hmr streaming
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue