mirror of
https://github.com/IT4Change/ohmyform-ui.git
synced 2025-12-13 09:45:50 +00:00
add translations for field validation and number validation
This commit is contained in:
parent
f617f94f0f
commit
6f58cc5fd0
@ -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
|
||||
|
||||
|
||||
19
components/form/page.module.scss
Normal file
19
components/form/page.module.scss
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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}
|
||||
>
|
||||
|
||||
@ -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}
|
||||
>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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)}
|
||||
|
||||
@ -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 />
|
||||
|
||||
@ -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'} />
|
||||
|
||||
@ -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 />
|
||||
|
||||
@ -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' : '')}
|
||||
|
||||
@ -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",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user