refactor components for code cleanliness
This commit is contained in:
parent
936e09d00a
commit
86c4d3698d
6 changed files with 58 additions and 69 deletions
|
@ -2,15 +2,16 @@ import React from 'react';
|
||||||
import './Epochs.scss';
|
import './Epochs.scss';
|
||||||
|
|
||||||
import SoundChangeSuite from './SoundChangeSuite';
|
import SoundChangeSuite from './SoundChangeSuite';
|
||||||
|
import { render } from 'react-dom';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const Epochs = props => {
|
const Epochs = ({epochs, dispatch}) => {
|
||||||
|
|
||||||
const addEpoch = (e, props) => {
|
const addEpoch = e => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
let index = props.epochs.length + 1;
|
let index = epochs.length + 1;
|
||||||
props.dispatch({
|
dispatch({
|
||||||
type: 'ADD_EPOCH',
|
type: 'ADD_EPOCH',
|
||||||
value: {name: `Epoch ${index}`}
|
value: {name: `Epoch ${index}`}
|
||||||
})
|
})
|
||||||
|
@ -18,7 +19,7 @@ const Epochs = props => {
|
||||||
|
|
||||||
const removeEpoch = (e, epochName) => {
|
const removeEpoch = (e, epochName) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
props.dispatch({
|
dispatch({
|
||||||
type: 'REMOVE_EPOCH',
|
type: 'REMOVE_EPOCH',
|
||||||
value: {name: epochName}
|
value: {name: epochName}
|
||||||
});
|
});
|
||||||
|
@ -30,24 +31,25 @@ const Epochs = props => {
|
||||||
index: epochIndex,
|
index: epochIndex,
|
||||||
changes: epoch.changes
|
changes: epoch.changes
|
||||||
}
|
}
|
||||||
props.dispatch({
|
dispatch({
|
||||||
type: "SET_EPOCH",
|
type: "SET_EPOCH",
|
||||||
value: dispatchValue
|
value: dispatchValue
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const renderEpochs = () => epochs.map((epoch, index) => (
|
||||||
|
<SoundChangeSuite
|
||||||
|
key={`epochname-${index}`} epochIndex={index} epoch={epoch}
|
||||||
|
updateEpoch={updateEpoch} removeEpoch={removeEpoch}
|
||||||
|
// error={errors[epoch.name]}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="Epochs" data-testid="Epochs">
|
<div className="Epochs" data-testid="Epochs">
|
||||||
<h3>Sound Change Epochs</h3>
|
<h3>Sound Change Epochs</h3>
|
||||||
{props.epochs
|
{ epochs ? renderEpochs() : <></> }
|
||||||
? props.epochs.map((epoch, idx) => {
|
<form onSubmit={e=>addEpoch(e)}>
|
||||||
return <SoundChangeSuite
|
|
||||||
key={`epochname-${idx}`} epochIndex={idx} epoch={epoch}
|
|
||||||
updateEpoch={updateEpoch} removeEpoch={removeEpoch}
|
|
||||||
// error={props.errors[epoch.name]}
|
|
||||||
/>})
|
|
||||||
: <></>}
|
|
||||||
<form onSubmit={e=>addEpoch(e, props)}>
|
|
||||||
<input type="submit" name="add-epoch" value="Add Epoch" ></input>
|
<input type="submit" name="add-epoch" value="Add Epoch" ></input>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,24 +5,24 @@ import './Features.scss';
|
||||||
import type { featureAction } from '../reducers/reducer.features';
|
import type { featureAction } from '../reducers/reducer.features';
|
||||||
|
|
||||||
const parsePhonesFromFeatureObject = featureObject => {
|
const parsePhonesFromFeatureObject = featureObject => {
|
||||||
|
const getProperty = property => object => object[property]
|
||||||
|
|
||||||
const getFeatureMap = (featureObject) => {
|
const getFeatureMap = (featureObject) => {
|
||||||
return Object.keys(featureObject).map(feature => {
|
return Object.keys(featureObject).map(feature => {
|
||||||
const plusPhones = featureObject[feature].positive.map(phone => phone.grapheme).join('|');
|
const plusPhones = featureObject[feature].positive.map(getProperty('grapheme')).join(' / ');
|
||||||
const minusPhones = featureObject[feature].negative.map(phone => phone.grapheme).join('|');
|
const minusPhones = featureObject[feature].negative.map(getProperty('grapheme')).join(' / ');
|
||||||
return {[feature]: {plus: plusPhones, minus: minusPhones}}
|
return {[feature]: {plus: plusPhones, minus: minusPhones}}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFeatureMapJSX = (featureMap) => {
|
const getFeatureMapJSX = (featureMap) => {
|
||||||
return featureMap.map((feature, index) => {
|
return featureMap.map((feature, index) => {
|
||||||
const featureName = Object.keys(feature)
|
const featureName = Object.keys(feature);
|
||||||
const plusPhones = feature[featureName].plus;
|
const { plus, minus } = feature[featureName];
|
||||||
const minusPhones = feature[featureName].minus;
|
|
||||||
return (
|
return (
|
||||||
<li key={`feature__${featureName}`}>
|
<li key={`feature__${featureName}`}>
|
||||||
<span className="plus-phones">{`[+ ${featureName}] = ${plusPhones}`}</span>
|
<span className="plus-phones">{`[+ ${featureName}] = ${plus}`}</span>
|
||||||
<span className="minus-phones">{`[- ${featureName}] = ${minusPhones}`}</span>
|
<span className="minus-phones">{`[- ${featureName}] = ${minus}`}</span>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -33,51 +33,34 @@ const parsePhonesFromFeatureObject = featureObject => {
|
||||||
return featureMapJSX;
|
return featureMapJSX;
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildReducerAction = (e, newPositivePhones, newNegativePhones, feature): featureAction => {
|
const parseNewPhones = somePhones => {
|
||||||
e.preventDefault();
|
if (somePhones === '') return [''];
|
||||||
const positivePhones = []
|
return somePhones.split('/').map(phone => phone.trim());
|
||||||
newPositivePhones !== ''
|
}
|
||||||
? newPositivePhones.split('/').forEach(phone => positivePhones.push(phone.trim()))
|
|
||||||
: positivePhones.push('')
|
|
||||||
|
|
||||||
const negativePhones = []
|
|
||||||
newNegativePhones !== ''
|
|
||||||
? newNegativePhones.split('/').forEach(phone => negativePhones.push(phone.trim()))
|
|
||||||
: negativePhones.push('')
|
|
||||||
|
|
||||||
return {
|
const handleClickDispatch = e => dispatchFunction => actionBuilder => actionParameters => {
|
||||||
|
e.preventDefault();
|
||||||
|
return dispatchFunction(actionBuilder(actionParameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildAddFeatureAction = ([newPositivePhones, newNegativePhones, feature]): featureAction => (
|
||||||
|
{
|
||||||
type: "ADD_FEATURE",
|
type: "ADD_FEATURE",
|
||||||
value: {
|
value: {
|
||||||
positivePhones,
|
positivePhones: parseNewPhones(newPositivePhones),
|
||||||
negativePhones,
|
negativePhones: parseNewPhones(newNegativePhones),
|
||||||
feature
|
feature
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
|
|
||||||
const getPhonemesFromFeatureSubmission = (props, newPhonemes, feature) => {
|
const Features = ({ phones, features, dispatch }) => {
|
||||||
let newPhonemeObject = newPhonemes.split('/').reduce((phonemeObject, newPhoneme) => {
|
|
||||||
newPhoneme = newPhoneme.trim();
|
|
||||||
phonemeObject = phonemeObject[newPhoneme]
|
|
||||||
? {...phonemeObject, [newPhoneme]: [...phonemeObject[newPhoneme], feature]}
|
|
||||||
: {...phonemeObject, [newPhoneme]: [feature]}
|
|
||||||
return phonemeObject;
|
|
||||||
}, {...props.phonemes})
|
|
||||||
return newPhonemeObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Features = (props) => {
|
|
||||||
const [feature, setFeature] = useState('aspirated')
|
const [feature, setFeature] = useState('aspirated')
|
||||||
const [ newPositivePhones, setNewPositivePhones ] = useState('tʰ / pʰ / kʰ');
|
const [ newPositivePhones, setNewPositivePhones ] = useState('tʰ / pʰ / kʰ');
|
||||||
const [ newNegativePhones, setNewNegativePhones ] = useState('t / p / k');
|
const [ newNegativePhones, setNewNegativePhones ] = useState('t / p / k');
|
||||||
|
|
||||||
const newFeaturesSubmit = e => {
|
const newFeaturesSubmit = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
// let newPhonemeObject = getPhonemesFromFeatureSubmission(props, newPhonemes, feature);
|
|
||||||
// props.setPhonemes(newPhonemeObject);
|
|
||||||
// if (!props.features || !props.features.includes(feature)) props.setFeatures([...props.features, feature])
|
|
||||||
|
|
||||||
setFeature('');
|
setFeature('');
|
||||||
setNewPositivePhones('');
|
setNewPositivePhones('');
|
||||||
setNewNegativePhones('');
|
setNewNegativePhones('');
|
||||||
|
@ -89,7 +72,7 @@ const Features = (props) => {
|
||||||
<h3>Phonetic Features</h3>
|
<h3>Phonetic Features</h3>
|
||||||
|
|
||||||
<ul className="Features__list" data-testid="Features-list">
|
<ul className="Features__list" data-testid="Features-list">
|
||||||
{props.phones ? <>{parsePhonesFromFeatureObject(props.features)}</> : <></>}
|
{phones ? <>{parsePhonesFromFeatureObject(features)}</> : <></>}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<form className="Features__form" data-testid="Features-form">
|
<form className="Features__form" data-testid="Features-form">
|
||||||
|
@ -116,7 +99,7 @@ const Features = (props) => {
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="submit"
|
type="submit"
|
||||||
onClick={e => props.dispatch(buildReducerAction(e, newPositivePhones, newNegativePhones, feature))}
|
onClick={e => handleClickDispatch(e)(dispatch)(buildAddFeatureAction)([newPositivePhones, newNegativePhones, feature])}
|
||||||
value="Add feature"
|
value="Add feature"
|
||||||
></input>
|
></input>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -6,13 +6,12 @@ const Options = ({ options, dispatch }) => {
|
||||||
const [ load, setLoad ] = useState('');
|
const [ load, setLoad ] = useState('');
|
||||||
|
|
||||||
const handleRadioChange = e => {
|
const handleRadioChange = e => {
|
||||||
const option = e.target.name;
|
const { name, id } = e.target.name;
|
||||||
const setValue = e.target.id;
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'SET_OPTIONS',
|
type: 'SET_OPTIONS',
|
||||||
value: {
|
value: {
|
||||||
option,
|
option: name,
|
||||||
setValue
|
setValue: id
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './ProtoLang.scss';
|
import './ProtoLang.scss';
|
||||||
|
|
||||||
const ProtoLang = (props) => {
|
const ProtoLang = ({ lexicon, dispatch }) => {
|
||||||
|
const getProperty = property => object => object[property];
|
||||||
|
|
||||||
|
const renderLexicon = () => {
|
||||||
|
if (!lexicon) return '';
|
||||||
|
// Code for optionally rendering epoch name with lexeme
|
||||||
|
// `\t#${lexeme.epoch.name}`
|
||||||
|
lexicon.map(getProperty('lexeme')).join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ProtoLang" data-testid="ProtoLang">
|
<div className="ProtoLang" data-testid="ProtoLang">
|
||||||
<h3>Proto Language Lexicon</h3>
|
<h3>Proto Language Lexicon</h3>
|
||||||
|
@ -10,14 +19,14 @@ const ProtoLang = (props) => {
|
||||||
<textarea
|
<textarea
|
||||||
name="lexicon"
|
name="lexicon"
|
||||||
data-testid="ProtoLang-Lexicon__textarea"
|
data-testid="ProtoLang-Lexicon__textarea"
|
||||||
value={props.lexicon ? props.lexicon.map(lexeme => `${lexeme.lexeme} \t#${lexeme.epoch.name}`).join('\n'): ''}
|
value={renderLexicon()}
|
||||||
onChange={e=> {
|
onChange={e=> {
|
||||||
console.log(e.target.value.split(/\n/).map(line => {
|
console.log(e.target.value.split(/\n/).map(line => {
|
||||||
const lexeme = line.split('#')[0].trim();
|
const lexeme = line.split('#')[0].trim();
|
||||||
const epoch = line.split('#')[1] || '';
|
const epoch = line.split('#')[1] || '';
|
||||||
return { lexeme, epoch }
|
return { lexeme, epoch }
|
||||||
}))
|
}))
|
||||||
props.dispatch({
|
dispatch({
|
||||||
type: 'SET_LEXICON',
|
type: 'SET_LEXICON',
|
||||||
value: e.target.value.split(/\n/).map(line => {
|
value: e.target.value.split(/\n/).map(line => {
|
||||||
const lexeme = line.split('#')[0].trim();
|
const lexeme = line.split('#')[0].trim();
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
.ProtoLang {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
color: black;
|
|
||||||
}
|
|
|
@ -235,7 +235,7 @@ export const transformLexeme = (lexemeBundle, rule, features) => {
|
||||||
if (!isEnvironmentBoundByRule(lexemeBundle.slice(index, index + post.length), post)) return [...newLexeme, phoneme];
|
if (!isEnvironmentBoundByRule(lexemeBundle.slice(index, index + post.length), post)) return [...newLexeme, phoneme];
|
||||||
const newPhoneme = transformPhoneme(phoneme, rule.newFeatures[0], features);
|
const newPhoneme = transformPhoneme(phoneme, rule.newFeatures[0], features);
|
||||||
// if deletion occurs
|
// if deletion occurs
|
||||||
if (!newPhoneme.grapheme) return [ ...newLexeme] ;
|
if (!newPhoneme || !newPhoneme.grapheme) return [ ...newLexeme] ;
|
||||||
return [...newLexeme, newPhoneme];
|
return [...newLexeme, newPhoneme];
|
||||||
}, [])
|
}, [])
|
||||||
return newLexeme;
|
return newLexeme;
|
||||||
|
@ -278,6 +278,7 @@ export const run = (state: stateType, action: resultsAction): stateType => {
|
||||||
const results = passResults.map(stringifyResults);
|
const results = passResults.map(stringifyResults);
|
||||||
return {...state, results }
|
return {...state, results }
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
return {...state, errors: err };
|
return {...state, errors: err };
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue