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

150 lines
4.5 KiB
TypeScript

import * as React from 'react';
import { Dimmer, Loader } from 'semantic-ui-react';
import * as XML from 'xml2js';
import * as _ from 'lodash';
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;
}
};
}
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: 'text', ...simpleAccessor('image[0]'), },
relations: { type: 'text', ...simpleAccessor('relations[0]'), },
frame: { type: 'select', ...simpleAccessor('syntacticprops[0].property[0]._'), },
morphclass: {
type: 'select',
get: (li: any) => {
let lens = 'lexprops[0].morphology[0].morph';
let def = [{ _: '', $: { form: 'morphclass' } }];
let morphProps = _.get<any>(li, lens, def);
let prop = _.filter<any>(morphProps, (m) => {
return m.$.form === 'morphclass';
});
let mcls = _.get<any>(prop, '[0]._', '');
return mcls;
},
set: (li: any, value: string) => {
let lexItem = _.cloneDeep(li);
let lens = 'lexprops[0].morphology[0].morph';
let morphProps = _.get<any>(lexItem, lens, []);
if (morphProps.length > 0) {
let prop = _.filter<any>(morphProps, (m) => {
return m.$.form === 'morphclass';
});
if (prop.length > 0) {
_.set(prop[0], '_', value);
} else {
let def = { _: value, $: { form: 'morphclass' } };
morphProps.push(def);
}
} else {
let def = [{ _: value, $: { form: 'morphclass' } }];
_.set(lexItem, lens, def);
}
return lexItem;
}
},
morphexceptions: {
type: 'list',
get: (li: any) => {
let lens = 'lexprops[0].morphology[0].morph';
let def = [{ _: 'M0', $: { form: 'morphclass' } }];
let morphProps = _.get<any>(li, lens, def);
let morphExps = _.filter<any>(morphProps, (m) => {
return m.$.form !== 'morphclass';
});
return morphExps;
}
},
stats: { type: 'text', ...simpleAccessor('stats[0].property[0]._'), },
lang: { type: 'select', options: ['en', 'es'], ...simpleAccessor('$.id', 'en'), },
};
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 fieldMetaMap[s].type === 'select';
}).map((s) => {
let entries = _.get<any>(langEntries, lang, 'en');
let selectOptions = _.uniq(entries.map((q: any) => {
return fieldMetaMap[s].get(q);
}));
return [s, selectOptions];
}));
return [lang, langOpts];
}));
return ({
allEntries, selectFields, fieldMetaMap
});
};
export class LexSetup extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = { xmlLoaded: false };
}
public componentDidMount() {
fetch(this.props.fileName)
.then((response) => response.text())
.then((xmlString) => {
XML.parseString(xmlString, (err, xmlData) => {
this.props.addXmlData(xmlData);
this.setState({ xmlLoaded: true });
});
})
.catch((e) => {
console.log('errored :', e);
});
}
render() {
let dimmer = (
<Dimmer active={true} inverted={true}>
<Loader inverted={true}>Loading</Loader>
</Dimmer>
);
let xmlEntries = xmlToEntries(this.props.xmlData);
let editor = (
<LexEditor {...xmlEntries} {...this.props} />
);
return this.state.xmlLoaded ? editor : dimmer;
}
}