add translations for field validation and number validation

This commit is contained in:
Michael Schramm 2020-06-11 09:12:19 +02:00
parent f617f94f0f
commit 6f58cc5fd0
14 changed files with 66 additions and 34 deletions

View File

@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- prev property error on div
- rating field default on admin
- number field defaults
- translations for field validation
- number validation
### Security

View File

@ -0,0 +1,19 @@
.main {
display: flex;
flex-direction: column;
.content {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
overflow: auto;
padding: 16px;
@media (max-width: 600px) {
display: block;
}
}
}

View File

@ -4,38 +4,26 @@ import { FormDesignFragment, FormPageFragment } from '../../graphql/fragment/for
import { StyledButton } from '../styled/button'
import { StyledH1 } from '../styled/h1'
import { StyledMarkdown } from '../styled/markdown'
import scss from './page.module.scss'
interface Props {
type: 'start' | 'end'
page: FormPageFragment
design: FormDesignFragment
className?: string
next: () => void
prev: () => void
}
export const FormPage: React.FC<Props> = ({ page, design, next, prev, ...props }) => {
export const FormPage: React.FC<Props> = ({ page, design, next, prev, className, ...props }) => {
if (!page.show) {
return null
}
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
}}
{...props}
>
<div
style={{
flex: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
}}
>
<div className={[scss.main, className].filter((c) => !!c).join(' ')} {...props}>
<div className={scss.content}>
<StyledH1 design={design} type={'question'}>
{page.title}
</StyledH1>

View File

@ -2,12 +2,14 @@ import { Form } from 'antd'
import dayjs, { Dayjs } from 'dayjs'
import moment, { Moment } from 'moment'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { StyledDateInput } from '../../styled/date.input'
import { FieldTypeProps } from './type.props'
export const DateType: React.FC<FieldTypeProps> = ({ field, design }) => {
const [min, setMin] = useState<Dayjs>()
const [max, setMax] = useState<Dayjs>()
const { t } = useTranslation()
useEffect(() => {
field.options.forEach((option) => {
@ -24,7 +26,7 @@ export const DateType: React.FC<FieldTypeProps> = ({ field, design }) => {
<div>
<Form.Item
name={[field.id, 'value']}
rules={[{ required: field.required, message: 'Please provide Information' }]}
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
getValueFromEvent={(e: Moment) => e.format('YYYY-MM-DD')}
getValueProps={(e: string) => ({ value: e ? moment(e) : undefined })}
initialValue={field.value ? moment(field.value) : undefined}

View File

@ -1,16 +1,18 @@
import { Form, Select } from 'antd'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { StyledSelect } from '../../styled/select'
import { FieldTypeProps } from './type.props'
export const DropdownType: React.FC<FieldTypeProps> = ({ field, design }) => {
const [open, setOpen] = useState(false)
const { t } = useTranslation()
return (
<div>
<Form.Item
name={[field.id, 'value']}
rules={[{ required: field.required, message: 'Please provide Information' }]}
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
initialValue={field.value || null}
>
<StyledSelect

View File

@ -1,16 +1,19 @@
import { Form } from 'antd'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { StyledInput } from '../../styled/input'
import { FieldTypeProps } from './type.props'
export const EmailType: React.FC<FieldTypeProps> = ({ field, design }) => {
const { t } = useTranslation()
return (
<div>
<Form.Item
name={[field.id, 'value']}
rules={[
{ required: field.required, message: 'Please provide Information' },
{ type: 'email', message: 'Must be a valid email' },
{ required: field.required, message: t('validation:valueRequired') },
{ type: 'email', message: t('validation:invalidEmail') },
]}
initialValue={field.value}
>

View File

@ -1,16 +1,19 @@
import { Form } from 'antd'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { StyledInput } from '../../styled/input'
import { FieldTypeProps } from './type.props'
export const LinkType: React.FC<FieldTypeProps> = ({ field, design }) => {
const { t } = useTranslation()
return (
<div>
<Form.Item
name={[field.id, 'value']}
rules={[
{ required: field.required, message: 'Please provide Information' },
{ type: 'url', message: 'Must be a valid URL' },
{ required: field.required, message: t('validation:valueRequired') },
{ type: 'url', message: t('validation:invalidUrl') },
]}
initialValue={field.value}
>

View File

@ -1,22 +1,21 @@
import { Form } from 'antd'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { StyledNumberInput } from '../../styled/number.input'
import { FieldTypeProps } from './type.props'
export const NumberType: React.FC<FieldTypeProps> = ({ field, design }) => {
const { t } = useTranslation()
return (
<div>
<Form.Item
name={[field.id, 'value']}
rules={[
{ type: 'number', message: 'Must be a valid URL' },
{ required: field.required, message: 'Please provide Information' },
{ type: 'number', message: t('validation:invalidNumber') },
{ required: field.required, message: t('validation:valueRequired') },
]}
initialValue={typeof field.value === 'number' ? parseFloat(field.value) : undefined}
getValueFromEvent={(value: number) =>
typeof value === 'number' ? value.toFixed(2) : value
}
getValueProps={(value: string) => ({ value: value ? parseFloat(value) : undefined })}
>
<StyledNumberInput design={design} size={'large'} />
</Form.Item>

View File

@ -1,14 +1,17 @@
import { Form, Radio } from 'antd'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { StyledRadio } from '../../styled/radio'
import { FieldTypeProps } from './type.props'
export const RadioType: React.FC<FieldTypeProps> = ({ field, design }) => {
const { t } = useTranslation()
return (
<div>
<Form.Item
name={[field.id, 'value']}
rules={[{ required: field.required, message: 'Please provide Information' }]}
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
initialValue={field.options
.map((option) => option.value)
.find((value) => value === field.value)}

View File

@ -1,15 +1,17 @@
import { Form, Rate } from 'antd'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { FieldTypeProps } from './type.props'
export const RatingType: React.FC<FieldTypeProps> = ({ field }) => {
const { t } = useTranslation()
// TODO add ratings
return (
<div>
<Form.Item
name={[field.id, 'value']}
rules={[{ required: field.required, message: 'Please provide Information' }]}
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
initialValue={parseFloat(field.value)}
>
<Rate allowHalf />

View File

@ -1,16 +1,18 @@
import { Form } from 'antd'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { StyledInput } from '../../styled/input'
import { FieldTypeProps } from './type.props'
export const TextType: React.FC<FieldTypeProps> = ({ field, design }) => {
const { t } = useTranslation()
// TODO focus when becomes visible
return (
<div>
<Form.Item
name={[field.id, 'value']}
rules={[{ required: field.required, message: 'Please provide Information' }]}
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
initialValue={field.value}
>
<StyledInput design={design} allowClear size={'large'} />

View File

@ -1,14 +1,17 @@
import { Form } from 'antd'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { StyledTextareaInput } from '../../styled/textarea.input'
import { FieldTypeProps } from './type.props'
export const TextareaType: React.FC<FieldTypeProps> = ({ field, design }) => {
const { t } = useTranslation()
return (
<div>
<Form.Item
name={[field.id, 'value']}
rules={[{ required: field.required, message: 'Please provide Information' }]}
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
initialValue={field.value}
>
<StyledTextareaInput design={design} allowClear autoSize />

View File

@ -1,13 +1,16 @@
import { Form, Switch } from 'antd'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { FieldTypeProps } from './type.props'
export const YesNoType: React.FC<FieldTypeProps> = ({ field }) => {
const { t } = useTranslation()
return (
<div>
<Form.Item
name={[field.id, 'value']}
rules={[{ required: field.required, message: 'Please provide Information' }]}
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
initialValue={!!field.value}
valuePropName={'checked'}
getValueFromEvent={(checked: boolean) => (checked ? '1' : '')}

View File

@ -2,6 +2,7 @@
"emailFieldRequired": "Please select an Email Field",
"emailRequired": "Please provide an Email",
"invalidEmail": "Must be a valid email!",
"invalidNumber": "Must be a valid number!",
"invalidUrl": "Must be a valid URL",
"languageRequired": "Please select a Language",
"mandatoryFieldsMissing": "Mandatory fields missing",