refactor components for code cleanliness

This commit is contained in:
Sorrel Bri 2020-02-26 14:06:04 -08:00
parent 936e09d00a
commit 86c4d3698d
6 changed files with 58 additions and 69 deletions

View file

@ -2,15 +2,16 @@ import React from 'react';
import './Epochs.scss';
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()
let index = props.epochs.length + 1;
props.dispatch({
let index = epochs.length + 1;
dispatch({
type: 'ADD_EPOCH',
value: {name: `Epoch ${index}`}
})
@ -18,7 +19,7 @@ const Epochs = props => {
const removeEpoch = (e, epochName) => {
e.preventDefault()
props.dispatch({
dispatch({
type: 'REMOVE_EPOCH',
value: {name: epochName}
});
@ -30,24 +31,25 @@ const Epochs = props => {
index: epochIndex,
changes: epoch.changes
}
props.dispatch({
dispatch({
type: "SET_EPOCH",
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 (
<div className="Epochs" data-testid="Epochs">
<h3>Sound Change Epochs</h3>
{props.epochs
? props.epochs.map((epoch, idx) => {
return <SoundChangeSuite
key={`epochname-${idx}`} epochIndex={idx} epoch={epoch}
updateEpoch={updateEpoch} removeEpoch={removeEpoch}
// error={props.errors[epoch.name]}
/>})
: <></>}
<form onSubmit={e=>addEpoch(e, props)}>
{ epochs ? renderEpochs() : <></> }
<form onSubmit={e=>addEpoch(e)}>
<input type="submit" name="add-epoch" value="Add Epoch" ></input>
</form>
</div>

View file

@ -5,24 +5,24 @@ import './Features.scss';
import type { featureAction } from '../reducers/reducer.features';
const parsePhonesFromFeatureObject = featureObject => {
const getProperty = property => object => object[property]
const getFeatureMap = (featureObject) => {
return Object.keys(featureObject).map(feature => {
const plusPhones = featureObject[feature].positive.map(phone => phone.grapheme).join('|');
const minusPhones = featureObject[feature].negative.map(phone => phone.grapheme).join('|');
const plusPhones = featureObject[feature].positive.map(getProperty('grapheme')).join(' / ');
const minusPhones = featureObject[feature].negative.map(getProperty('grapheme')).join(' / ');
return {[feature]: {plus: plusPhones, minus: minusPhones}}
})
}
const getFeatureMapJSX = (featureMap) => {
return featureMap.map((feature, index) => {
const featureName = Object.keys(feature)
const plusPhones = feature[featureName].plus;
const minusPhones = feature[featureName].minus;
const featureName = Object.keys(feature);
const { plus, minus } = feature[featureName];
return (
<li key={`feature__${featureName}`}>
<span className="plus-phones">{`[+ ${featureName}] = ${plusPhones}`}</span>
<span className="minus-phones">{`[- ${featureName}] = ${minusPhones}`}</span>
<span className="plus-phones">{`[+ ${featureName}] = ${plus}`}</span>
<span className="minus-phones">{`[- ${featureName}] = ${minus}`}</span>
</li>
)
})
@ -33,51 +33,34 @@ const parsePhonesFromFeatureObject = featureObject => {
return featureMapJSX;
}
const buildReducerAction = (e, newPositivePhones, newNegativePhones, feature): featureAction => {
e.preventDefault();
const positivePhones = []
newPositivePhones !== ''
? newPositivePhones.split('/').forEach(phone => positivePhones.push(phone.trim()))
: positivePhones.push('')
const negativePhones = []
newNegativePhones !== ''
? newNegativePhones.split('/').forEach(phone => negativePhones.push(phone.trim()))
: negativePhones.push('')
const parseNewPhones = somePhones => {
if (somePhones === '') return [''];
return somePhones.split('/').map(phone => phone.trim());
}
return {
const handleClickDispatch = e => dispatchFunction => actionBuilder => actionParameters => {
e.preventDefault();
return dispatchFunction(actionBuilder(actionParameters));
}
const buildAddFeatureAction = ([newPositivePhones, newNegativePhones, feature]): featureAction => (
{
type: "ADD_FEATURE",
value: {
positivePhones,
negativePhones,
positivePhones: parseNewPhones(newPositivePhones),
negativePhones: parseNewPhones(newNegativePhones),
feature
}
}
}
)
const getPhonemesFromFeatureSubmission = (props, newPhonemes, feature) => {
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 Features = ({ phones, features, dispatch }) => {
const [feature, setFeature] = useState('aspirated')
const [ newPositivePhones, setNewPositivePhones ] = useState('tʰ / pʰ / kʰ');
const [ newNegativePhones, setNewNegativePhones ] = useState('t / p / k');
const newFeaturesSubmit = e => {
e.preventDefault();
// let newPhonemeObject = getPhonemesFromFeatureSubmission(props, newPhonemes, feature);
// props.setPhonemes(newPhonemeObject);
// if (!props.features || !props.features.includes(feature)) props.setFeatures([...props.features, feature])
setFeature('');
setNewPositivePhones('');
setNewNegativePhones('');
@ -89,7 +72,7 @@ const Features = (props) => {
<h3>Phonetic Features</h3>
<ul className="Features__list" data-testid="Features-list">
{props.phones ? <>{parsePhonesFromFeatureObject(props.features)}</> : <></>}
{phones ? <>{parsePhonesFromFeatureObject(features)}</> : <></>}
</ul>
<form className="Features__form" data-testid="Features-form">
@ -116,7 +99,7 @@ const Features = (props) => {
<input
type="submit"
onClick={e => props.dispatch(buildReducerAction(e, newPositivePhones, newNegativePhones, feature))}
onClick={e => handleClickDispatch(e)(dispatch)(buildAddFeatureAction)([newPositivePhones, newNegativePhones, feature])}
value="Add feature"
></input>
</form>

View file

@ -6,13 +6,12 @@ const Options = ({ options, dispatch }) => {
const [ load, setLoad ] = useState('');
const handleRadioChange = e => {
const option = e.target.name;
const setValue = e.target.id;
const { name, id } = e.target.name;
dispatch({
type: 'SET_OPTIONS',
value: {
option,
setValue
option: name,
setValue: id
}
});
}

View file

@ -1,7 +1,16 @@
import React from 'react';
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 (
<div className="ProtoLang" data-testid="ProtoLang">
<h3>Proto Language Lexicon</h3>
@ -10,14 +19,14 @@ const ProtoLang = (props) => {
<textarea
name="lexicon"
data-testid="ProtoLang-Lexicon__textarea"
value={props.lexicon ? props.lexicon.map(lexeme => `${lexeme.lexeme} \t#${lexeme.epoch.name}`).join('\n'): ''}
value={renderLexicon()}
onChange={e=> {
console.log(e.target.value.split(/\n/).map(line => {
const lexeme = line.split('#')[0].trim();
const epoch = line.split('#')[1] || '';
return { lexeme, epoch }
}))
props.dispatch({
dispatch({
type: 'SET_LEXICON',
value: e.target.value.split(/\n/).map(line => {
const lexeme = line.split('#')[0].trim();

View file

@ -1,5 +0,0 @@
.ProtoLang {
width: 100%;
height: 100%;
color: black;
}

View file

@ -235,7 +235,7 @@ export const transformLexeme = (lexemeBundle, rule, features) => {
if (!isEnvironmentBoundByRule(lexemeBundle.slice(index, index + post.length), post)) return [...newLexeme, phoneme];
const newPhoneme = transformPhoneme(phoneme, rule.newFeatures[0], features);
// if deletion occurs
if (!newPhoneme.grapheme) return [ ...newLexeme] ;
if (!newPhoneme || !newPhoneme.grapheme) return [ ...newLexeme] ;
return [...newLexeme, newPhoneme];
}, [])
return newLexeme;
@ -278,6 +278,7 @@ export const run = (state: stateType, action: resultsAction): stateType => {
const results = passResults.map(stringifyResults);
return {...state, results }
} catch (err) {
console.log(err)
return {...state, errors: err };
}
}