-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(ui): InputFilter and WorkflowTimeline components from class to functional #11899
Changes from all commits
3263cfa
7adb9e9
dd5b64d
9b7b7c7
f2f6973
debbd7b
25b644d
409c7ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import {Autocomplete} from 'argo-ui'; | ||
import * as React from 'react'; | ||
import React, {useState} from 'react'; | ||
|
||
interface InputProps { | ||
value: string; | ||
|
@@ -8,68 +8,60 @@ interface InputProps { | |
onChange: (input: string) => void; | ||
} | ||
|
||
interface InputState { | ||
value: string; | ||
localCache: string[]; | ||
error?: Error; | ||
} | ||
export function InputFilter(props: InputProps) { | ||
const [value, setValue] = useState(props.value); | ||
const [localCache, setLocalCache] = useState((localStorage.getItem(props.name + '_inputs') || '').split(',').filter(item => item !== '')); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ts infers the type of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yea same as your previous PR, I think when the inference is correct and straightforward ( I also have experience working in ML-family languages like OCaml, which are even stronger typed and where the compiler infers the types of the entire program (so there are no type annotations at all). On the other spectrum would be something like Java, which requires on type annotations on almost everything and feels very verbose as a result (despite having weaker guarantees than OCaml et al). For TS, I prefer to have strict typing on, which we'll be able to do in this codebase once there is some progress on decoupling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. unless it's a complex type, I'll try to omit the type annotations where TS correctly infers. thanks for detailed description.😄 and I had no idea about argo-ui! Thank you for letting me know. I'm really hopeful for the progress in decoupling. It sounds it could bring great improvements. |
||
|
||
export class InputFilter extends React.Component<InputProps, InputState> { | ||
constructor(props: Readonly<InputProps>) { | ||
super(props); | ||
this.state = { | ||
value: props.value, | ||
localCache: (localStorage.getItem(this.props.name + '_inputs') || '').split(',').filter(value => value !== '') | ||
}; | ||
function setValueAndCache(newValue: string) { | ||
setLocalCache(currentCache => { | ||
const updatedCache = [...currentCache]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice catch to make this an immutable operation! |
||
if (!updatedCache.includes(newValue)) { | ||
updatedCache.unshift(newValue); | ||
} | ||
while (updatedCache.length > 5) { | ||
updatedCache.pop(); | ||
} | ||
localStorage.setItem(props.name + '_inputs', updatedCache.join(',')); | ||
return updatedCache; | ||
}); | ||
setValue(newValue); | ||
} | ||
|
||
public render() { | ||
function renderInput(inputProps: React.HTMLProps<HTMLInputElement>) { | ||
return ( | ||
<> | ||
<Autocomplete | ||
items={this.state.localCache} | ||
value={this.state.value} | ||
onChange={(e, value) => this.setState({value})} | ||
onSelect={value => { | ||
this.setState({value}); | ||
this.props.onChange(value); | ||
}} | ||
renderInput={inputProps => ( | ||
<input | ||
{...inputProps} | ||
onKeyUp={event => { | ||
if (event.keyCode === 13) { | ||
this.setValueAndCache(event.currentTarget.value); | ||
this.props.onChange(this.state.value); | ||
} | ||
}} | ||
className='argo-field' | ||
placeholder={this.props.placeholder} | ||
/> | ||
)} | ||
/> | ||
<a | ||
onClick={() => { | ||
this.setState({value: ''}); | ||
this.props.onChange(''); | ||
}}> | ||
<i className='fa fa-times-circle' /> | ||
</a> | ||
</> | ||
<input | ||
{...inputProps} | ||
onKeyUp={event => { | ||
if (event.keyCode === 13) { | ||
setValueAndCache(event.currentTarget.value); | ||
props.onChange(value); | ||
} | ||
}} | ||
className='argo-field' | ||
placeholder={props.placeholder} | ||
/> | ||
); | ||
} | ||
|
||
private setValueAndCache(value: string) { | ||
this.setState(state => { | ||
const localCache = state.localCache; | ||
if (!state.localCache.includes(value)) { | ||
localCache.unshift(value); | ||
} | ||
while (localCache.length > 5) { | ||
localCache.pop(); | ||
} | ||
localStorage.setItem(this.props.name + '_inputs', localCache.join(',')); | ||
return {value, localCache}; | ||
}); | ||
} | ||
return ( | ||
<> | ||
<Autocomplete | ||
items={localCache} | ||
value={value} | ||
onChange={(e, newValue) => setValue(newValue)} | ||
onSelect={newValue => { | ||
setValue(newValue); | ||
props.onChange(newValue); | ||
}} | ||
renderInput={renderInput} | ||
/> | ||
<a | ||
onClick={() => { | ||
setValue(''); | ||
props.onChange(''); | ||
}}> | ||
<i className='fa fa-times-circle' /> | ||
</a> | ||
</> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error
state isn't used, so removed it.