Adding property validators
This commit is contained in:
parent
b7a14ac838
commit
6383d79ecf
4 changed files with 51 additions and 5 deletions
|
@ -29,6 +29,24 @@ const PropertyValueElement = (props:Props): JSX.Element => {
|
|||
const displayValue = OctoUtils.propertyDisplayValue(card, propertyValue, propertyTemplate)
|
||||
const finalDisplayValue = displayValue || emptyDisplayValue
|
||||
|
||||
const validateProp = (propType: string, val: string): boolean => {
|
||||
if (val === '') {
|
||||
return true
|
||||
}
|
||||
switch (propType) {
|
||||
case 'number':
|
||||
return !isNaN(parseInt(val, 10))
|
||||
case 'email': {
|
||||
const emailRegexp = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
return emailRegexp.test(val.toLowerCase())
|
||||
}
|
||||
case 'text':
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (propertyTemplate.type === 'select') {
|
||||
let propertyColorCssClassName = ''
|
||||
const cardPropertyValue = propertyTemplate.options.find((o) => o.id === propertyValue)
|
||||
|
@ -85,6 +103,7 @@ const PropertyValueElement = (props:Props): JSX.Element => {
|
|||
onChange={setValue}
|
||||
onSave={() => mutator.changePropertyValue(card, propertyTemplate.id, value)}
|
||||
onCancel={() => setValue(propertyValue)}
|
||||
validator={(value) => validateProp(propertyTemplate.type, value)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
--button-bg: 22, 109, 204;
|
||||
--link-color: 35, 137, 215;
|
||||
--link-visited-color: #551a8b;
|
||||
--error-color: #ffa9a9;
|
||||
|
||||
// Label Colors
|
||||
--prop-default: #fff;
|
||||
|
@ -32,4 +33,4 @@
|
|||
// Radius
|
||||
--default-rad: 4px;
|
||||
--modal-rad: 8px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
border: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border: 1px solid transparent;
|
||||
&.active {
|
||||
min-width: 100px;
|
||||
}
|
||||
|
@ -10,4 +11,8 @@
|
|||
color: rgba(var(--body-color), 0.4);
|
||||
opacity: 1;
|
||||
}
|
||||
&.error {
|
||||
border: 1px solid var(--error-color);
|
||||
border-radius: var(--default-rad);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ type Props = {
|
|||
saveOnEsc?: boolean
|
||||
readonly?: boolean
|
||||
|
||||
validator?: (value: string) => boolean
|
||||
onCancel?: () => void
|
||||
onSave?: (saveType: 'onEnter'|'onEsc'|'onBlur') => void
|
||||
}
|
||||
|
@ -24,6 +25,22 @@ export default class Editable extends React.Component<Props> {
|
|||
return true
|
||||
}
|
||||
|
||||
save = (saveType: 'onEnter'|'onEsc'|'onBlur'): void => {
|
||||
if (this.props.validator && !this.props.validator(this.props.value || '')) {
|
||||
return
|
||||
}
|
||||
if (!this.props.onSave) {
|
||||
return
|
||||
}
|
||||
if (saveType === 'onBlur' && !this.saveOnBlur) {
|
||||
return
|
||||
}
|
||||
if (saveType === 'onEsc' && !this.props.saveOnEsc) {
|
||||
return
|
||||
}
|
||||
this.props.onSave(saveType)
|
||||
}
|
||||
|
||||
public focus(selectAll = false): void {
|
||||
if (this.elementRef.current) {
|
||||
const valueLength = this.elementRef.current.value.length
|
||||
|
@ -44,30 +61,34 @@ export default class Editable extends React.Component<Props> {
|
|||
|
||||
public render(): JSX.Element {
|
||||
const {value, onChange, className, placeholderText} = this.props
|
||||
let error = false
|
||||
if (this.props.validator) {
|
||||
error = !this.props.validator(value || '')
|
||||
}
|
||||
|
||||
return (
|
||||
<input
|
||||
ref={this.elementRef}
|
||||
className={'Editable ' + className}
|
||||
className={'Editable ' + (error ? 'error ' : '') + className}
|
||||
placeholder={placeholderText}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange(e.target.value)
|
||||
}}
|
||||
value={value}
|
||||
title={value}
|
||||
onBlur={() => this.saveOnBlur && this.props.onSave && this.props.onSave('onBlur')}
|
||||
onBlur={() => this.save('onBlur')}
|
||||
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>): void => {
|
||||
if (e.keyCode === 27 && !(e.metaKey || e.ctrlKey) && !e.shiftKey && !e.altKey) { // ESC
|
||||
e.stopPropagation()
|
||||
if (this.props.saveOnEsc) {
|
||||
this.props.onSave?.('onEsc')
|
||||
this.save('onEsc')
|
||||
} else {
|
||||
this.props.onCancel?.()
|
||||
}
|
||||
this.blur()
|
||||
} else if (e.keyCode === 13 && !(e.metaKey || e.ctrlKey) && !e.shiftKey && !e.altKey) { // Return
|
||||
e.stopPropagation()
|
||||
this.props.onSave?.('onEnter')
|
||||
this.save('onEnter')
|
||||
this.blur()
|
||||
}
|
||||
}}
|
||||
|
|
Loading…
Reference in a new issue