Skip to content

Commit

Permalink
Removes the magic in Input, reducing it to a styled TextField
Browse files Browse the repository at this point in the history
  • Loading branch information
rileyjbauer committed Nov 8, 2018
1 parent 332f19e commit e6da196
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 13,947 deletions.
20 changes: 8 additions & 12 deletions frontend/src/atoms/Input.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,25 @@ import Input from './Input';
import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';

const mockInstance = { state: {} } as any;

describe('Input', () => {
const handleChange = jest.fn();
const value = 'some input value';

it('renders with the right styles by default', () => {
const tree = shallow(<Input instance={mockInstance} field='fieldname' />);
const tree = shallow(<Input onChange={handleChange('fieldname')} value={value} />);
expect(toJson(tree)).toMatchSnapshot();
});

it('accepts height and width as prop overrides', () => {
const tree = shallow(<Input instance={mockInstance} height={123} width={456} field='fieldname' />);
expect(toJson(tree)).toMatchSnapshot();
});

it('gets its value from the instance state field', () => {
mockInstance.state.fieldname = 'field value';
const tree = shallow(<Input instance={mockInstance} field='fieldname' />);
const tree = shallow(<Input height={123} width={456} onChange={handleChange('fieldname')} value={value} />);
expect(toJson(tree)).toMatchSnapshot();
});

it('calls the instance handleChange function if defined', () => {
mockInstance.handleChange = jest.fn();
const tree = shallow(<Input instance={mockInstance} field='fieldname' />);
handleChange.mockClear();
const tree = shallow(<Input onChange={handleChange('fieldname')} value={value} />);
tree.simulate('change');
expect(mockInstance.handleChange).toHaveBeenCalledWith('fieldname');
expect(handleChange).toHaveBeenCalledWith('fieldname');
});
});
16 changes: 7 additions & 9 deletions frontend/src/atoms/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,16 @@ import TextField, { TextFieldProps } from '@material-ui/core/TextField';
import { commonCss } from '../Css';

interface InputProps extends TextFieldProps {
field: string;
height?: number | string;
instance: any;
width?: number;
}

export default (props: InputProps) => {
const { field, height, instance, width, ...rest } = props;
return <TextField variant='outlined' value={instance.state[field]}
className={commonCss.textField} spellCheck={false}
style={{ height: height || 40, maxWidth: 600, width: width || '100%' }}
onChange={instance.handleChange && instance.handleChange(field)} {...rest}>
{props.children}
</TextField>;
const { height, width, ...rest } = props;
return (
<TextField variant='outlined' className={commonCss.textField} spellCheck={false}
style={{ height: height || 40, maxWidth: 600, width: width || '100%' }} {...rest}>
{props.children}
</TextField>
);
};
20 changes: 2 additions & 18 deletions frontend/src/atoms/__snapshots__/Input.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,7 @@ exports[`Input accepts height and width as prop overrides 1`] = `
"width": 456,
}
}
variant="outlined"
/>
`;

exports[`Input gets its value from the instance state field 1`] = `
<TextField
className="textField"
required={false}
select={false}
spellCheck={false}
style={
Object {
"height": 40,
"maxWidth": 600,
"width": "100%",
}
}
value="field value"
value="some input value"
variant="outlined"
/>
`;
Expand All @@ -48,6 +31,7 @@ exports[`Input renders with the right styles by default 1`] = `
"width": "100%",
}
}
value="some input value"
variant="outlined"
/>
`;
35 changes: 20 additions & 15 deletions frontend/src/components/Trigger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,12 @@ export default class Trigger extends React.Component<TriggerProps, TriggerState>
}

public render() {
const { editCron, hasEndDate, hasStartDate, intervalCategory,
intervalValue, selectedDays, type } = this.state;
const { cron, editCron, endDate, endTime, hasEndDate, hasStartDate, intervalCategory,
intervalValue, maxConcurrentRuns, selectedDays, startDate, startTime, type } = this.state;

return <div>
<Input select={true} label='Trigger type' required={true} instance={this} field='type'>
<Input select={true} label='Trigger type' required={true} onChange={this.handleChange('type')}
value={type}>
{Array.from(triggers.entries()).map((trigger, i) => (
<MenuItem key={i} value={trigger[0]}>
{trigger[1].displayName}
Expand All @@ -97,17 +98,20 @@ export default class Trigger extends React.Component<TriggerProps, TriggerState>
</Input>

<div>
<Input label='Maximum concurrent runs' required={true} instance={this} field='maxConcurrentRuns' />
<Input label='Maximum concurrent runs' required={true}
onChange={this.handleChange('maxConcurrentRuns')} value={maxConcurrentRuns} />

<div className={commonCss.flex}>
<FormControlLabel control={
<Checkbox checked={hasStartDate} color='primary'
onClick={this.handleChange('hasStartDate')} />}
label='Has start date' />
<Input label='Start date' type='date' instance={this} field='startDate' width={160}
<Input label='Start date' type='date' onChange={this.handleChange('startDate')}
value={startDate} width={160}
style={{ visibility: hasStartDate ? 'visible' : 'hidden' }} />
<Separator />
<Input label='Start time' type='time' instance={this} field='startTime' width={120}
<Input label='Start time' type='time' onChange={this.handleChange('startTime')}
value={startTime} width={120}
style={{ visibility: hasStartDate ? 'visible' : 'hidden' }} />
</div>

Expand All @@ -116,25 +120,26 @@ export default class Trigger extends React.Component<TriggerProps, TriggerState>
<Checkbox checked={hasEndDate} color='primary'
onClick={this.handleChange('hasEndDate')} />}
label='Has end date' />
<Input label='End date' type='date' instance={this} field='endDate' width={160}
style={{ visibility: hasEndDate ? 'visible' : 'hidden' }} />
<Input label='End date' type='date' onChange={this.handleChange('endDate')}
value={endDate} width={160} style={{ visibility: hasEndDate ? 'visible' : 'hidden' }} />
<Separator />
<Input label='End time' type='time' instance={this} field='endTime' width={120}
style={{ visibility: hasEndDate ? 'visible' : 'hidden' }} />
<Input label='End time' type='time' onChange={this.handleChange('endTime')}
value={endTime} width={120} style={{ visibility: hasEndDate ? 'visible' : 'hidden' }} />
</div>

<span className={commonCss.flex}>
Run every
{type === TriggerType.INTERVALED && (
<div className={commonCss.flex}>
<Separator />
<Input required={true} type='number' instance={this} field='intervalValue'
height={30} width={65} error={intervalValue < 1} />
<Input required={true} type='number' onChange={this.handleChange('intervalValue')}
value={intervalValue} height={30} width={65} error={intervalValue < 1} />
</div>
)}

<Separator />
<Input required={true} select={true} instance={this} field='intervalCategory' height={30} width={95}>
<Input required={true} select={true} onChange={this.handleChange('intervalCategory')}
value={intervalCategory} height={30} width={95}>
{Object.keys(PeriodicInterval).map((interval: PeriodicInterval, i) => (
<MenuItem key={i} value={PeriodicInterval[interval]}>
{PeriodicInterval[interval] + (type === TriggerType.INTERVALED ? 's' : '')}
Expand Down Expand Up @@ -172,8 +177,8 @@ export default class Trigger extends React.Component<TriggerProps, TriggerState>
} />
</div>

<Input instance={this} label='cron expression' field='cron' width={300}
disabled={!editCron} onChange={this.handleChange('cron')} />
<Input label='cron expression' onChange={this.handleChange('cron')} value={cron}
width={300} disabled={!editCron} />

<div>Note: Start and end dates/times are handled outside of cron.</div>
</div>
Expand Down
13 changes: 7 additions & 6 deletions frontend/src/components/UploadPipelineDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class UploadPipelineDialog extends React.Component<UploadPipelineDialogProps, Up
}

public render() {
const { dropzoneActive, file, uploadPipelineName, busy } = this.state;
const { dropzoneActive, file, fileName, uploadPipelineName, busy } = this.state;
return (
<Dialog id='uploadDialog' onClose={() => this._uploadDialogClosed(false)}
open={this.props.open} classes={{ paper: css.root }}>
Expand All @@ -94,7 +94,7 @@ class UploadPipelineDialog extends React.Component<UploadPipelineDialogProps, Up
<br />
You can also drag and drop the file here.
</div>
<Input field='fileName' instance={this} required={true} label='File'
<Input onChange={this.handleChange('fileName')} value={fileName} required={true} label='File'
InputProps={{
endAdornment: (
<InputAdornment position='end'>
Expand All @@ -107,11 +107,12 @@ class UploadPipelineDialog extends React.Component<UploadPipelineDialogProps, Up
readOnly: true,
}} />

<Input id='uploadFileName' label='Pipeline name' instance={this} required={true}
field='uploadPipelineName' />
<Input id='uploadFileName' label='Pipeline name'
onChange={this.handleChange('uploadPipelineName')}
required={true} value={uploadPipelineName} />

{/* <Input label='Pipeline description' instance={this} field='uploadPipelineDescription'
multiline={true} height='auto' /> */}
{/* <Input label='Pipeline description' onChange={this.handleChange('uploadPipelineName')}
value={uploadPipelineDescription} multiline={true} height='auto' /> */}
</Dropzone>

<DialogActions>
Expand Down
Loading

0 comments on commit e6da196

Please sign in to comment.