Adding property validators

This commit is contained in:
Jesús Espino 2021-04-08 12:40:55 +02:00
parent b7a14ac838
commit 6383d79ecf
4 changed files with 51 additions and 5 deletions

View file

@ -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)}
/>
)
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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()
}
}}