add error messaging for improper rules

This commit is contained in:
Sorrel Bri 2020-02-28 11:13:32 -08:00
parent d1e1d8e1c6
commit a74d387834
8 changed files with 29 additions and 14 deletions

View file

@ -3,4 +3,5 @@ $colors: (
"main": #d5bfbf, "main": #d5bfbf,
"text-input": #e8e22e, "text-input": #e8e22e,
"text-input--bg": #1d191a, "text-input--bg": #1d191a,
"error": #ff0000
); );

View file

@ -16,13 +16,13 @@ const PhonoChangeApplier = () => {
{}, {},
initState initState
) )
const { lexicon, phones, phonemes, epochs, options, features, results } = state; const { lexicon, phones, phonemes, epochs, options, features, results, errors } = state;
return ( return (
<div className="PhonoChangeApplier" data-testid="PhonoChangeApplier"> <div className="PhonoChangeApplier" data-testid="PhonoChangeApplier">
<ProtoLang lexicon={lexicon} dispatch={dispatch}/> <ProtoLang lexicon={lexicon} dispatch={dispatch}/>
<Features phones={phones} features={features} dispatch={dispatch}/> <Features phones={phones} features={features} dispatch={dispatch}/>
<Epochs epochs={epochs} dispatch={dispatch} /> <Epochs epochs={epochs} errors={errors} dispatch={dispatch} />
<Options options={options} dispatch={dispatch}/> <Options options={options} dispatch={dispatch}/>
<Output results={results} options={options} dispatch={dispatch}/> <Output results={results} options={options} dispatch={dispatch}/>
</div> </div>

View file

@ -6,7 +6,7 @@ import { render } from 'react-dom';
const Epochs = ({epochs, dispatch}) => { const Epochs = ({epochs, errors, dispatch}) => {
const addEpoch = e => { const addEpoch = e => {
e.preventDefault() e.preventDefault()
@ -29,8 +29,7 @@ const Epochs = ({epochs, dispatch}) => {
const dispatchValue = { const dispatchValue = {
name: epoch.name, name: epoch.name,
index: epochIndex, index: epochIndex,
changes: epoch.changes, changes: epoch.changes
parent: epoch.parent
} }
dispatch({ dispatch({
type: "SET_EPOCH", type: "SET_EPOCH",
@ -48,7 +47,9 @@ const Epochs = ({epochs, dispatch}) => {
} }
const renderEpochs = () => { const renderEpochs = () => {
if (epochs.length) return epochs.map((epoch, index) => ( if (epochs.length) return epochs.map((epoch, index) => {
const epochError = errors.epoch ? errors.error : null
return (
<div <div
className="SoundChangeSuite" className="SoundChangeSuite"
data-testid={`${epoch.name}_SoundChangeSuite`} data-testid={`${epoch.name}_SoundChangeSuite`}
@ -58,11 +59,11 @@ const Epochs = ({epochs, dispatch}) => {
epochIndex={index} epoch={epoch} epochIndex={index} epoch={epoch}
updateEpoch={updateEpoch} removeEpoch={removeEpoch} updateEpoch={updateEpoch} removeEpoch={removeEpoch}
epochs={epochs} epochs={epochs}
// error={errors[epoch.name]} error={epochError}
/> />
{renderAddEpochButton(index)} {renderAddEpochButton(index)}
</div> </div>
)); )});
return renderAddEpochButton(-1) return renderAddEpochButton(-1)
} }

View file

@ -2,7 +2,7 @@ import React from 'react';
import './Output.scss'; import './Output.scss';
const Output = props => { const Output = props => {
const { results, options } = props; const { results, options, errors } = props;
const renderResults = () => { const renderResults = () => {
switch(options.output) { switch(options.output) {
case 'default': case 'default':
@ -23,10 +23,10 @@ const Output = props => {
) )
}) })
} }
return ( return (
<div className="Output" data-testid="Output"> <div className="Output" data-testid="Output">
<h3>Results of Run</h3> <h3>Results of Run</h3>
<div data-testid="Output-lexicon" className="Output__container"> <div data-testid="Output-lexicon" className="Output__container">
{results && results.length ? renderResults() : <></>} {results && results.length ? renderResults() : <></>}
</div> </div>

View file

@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import './SoundChangeSuite.scss'; import './SoundChangeSuite.scss';
const SoundChangeSuite = props => { const SoundChangeSuite = props => {
const { epochIndex, removeEpoch, epochs } = props; const { epochIndex, error, removeEpoch, epochs } = props;
const [ epoch, setEpoch ] = useState(props.epoch ? props.epoch : {name:'', changes:[''], parent:'none'}); const [ epoch, setEpoch ] = useState(props.epoch ? props.epoch : {name:'', changes:[''], parent:'none'});
const changeHandler = (e,cb) => { const changeHandler = (e,cb) => {
@ -60,9 +60,17 @@ const SoundChangeSuite = props => {
return <></> return <></>
} }
const renderError = () => {
if (error) return (
<p className="error">{error}</p>
)
return <></>
}
return ( return (
<> <>
<h4>{epoch.name}</h4> <h4>{epoch.name}</h4>
{renderError()}
<form className="SoundChangeSuite__form" data-testid={`${epoch.name}_SoundChangeSuite_changes`}> <form className="SoundChangeSuite__form" data-testid={`${epoch.name}_SoundChangeSuite_changes`}>
<label htmlFor={`${epoch.name}-name`}> <label htmlFor={`${epoch.name}-name`}>
Name: Name:

View file

@ -17,4 +17,8 @@ body {
font-family: 'Fira Code', monospace; font-family: 'Fira Code', monospace;
} }
p.error {
color: map-get($colors, 'error');
}
} }

View file

@ -7,12 +7,12 @@ export type epochAction = {
index?: number, index?: number,
name: string, name: string,
changes?: Array<string>, changes?: Array<string>,
parent: string parent?: string
} }
} }
export const addEpoch = (state: stateType, action: epochAction): stateType => { export const addEpoch = (state: stateType, action: epochAction): stateType => {
const newEpoch = { name: action.value.name, changes: action.value.changes || [''] }; const newEpoch = { name: action.value.name, changes: action.value.changes || [''], parent: null};
return {...state, epochs: [...state.epochs, newEpoch]} return {...state, epochs: [...state.epochs, newEpoch]}
} }

View file

@ -170,7 +170,8 @@ export const decomposeRules = (epoch: epochType, phones: {[key: string]: phoneTy
.map(decomposeRule) .map(decomposeRule)
.map(mapRuleBundleToFeatureBundle(phones)); .map(mapRuleBundleToFeatureBundle(phones));
} catch (err) { } catch (err) {
return err; const ruleError = {epoch: epoch.name, error: err}
throw ruleError;
} }
} }