mirror of
https://github.com/IT4Change/ohmyform-ui.git
synced 2025-12-13 09:45:50 +00:00
add slug and fix missing admin error
https://github.com/ohmyform/ohmyform/issues/100
This commit is contained in:
parent
3f5104bee5
commit
97a9e1dc60
@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
## UNRELEASED
|
## UNRELEASED
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- slug for fields to be able to set value by url parameter
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- minify containers to reduce layer size
|
- minify containers to reduce layer size
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DeleteOutlined } from '@ant-design/icons/lib'
|
import { DeleteOutlined } from '@ant-design/icons/lib'
|
||||||
import { Button, Card, Checkbox, Form, Input, Popconfirm, Tag } from 'antd'
|
import { Button, Card, Checkbox, Form, Input, Popconfirm, Popover, Tag } from 'antd'
|
||||||
import { FormInstance } from 'antd/lib/form'
|
import { FormInstance } from 'antd/lib/form'
|
||||||
import { FieldData } from 'rc-field-form/lib/interface'
|
import { FieldData } from 'rc-field-form/lib/interface'
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
@ -53,7 +53,27 @@ export const FieldCard: React.FC<Props> = (props) => {
|
|||||||
type={'inner'}
|
type={'inner'}
|
||||||
extra={
|
extra={
|
||||||
<div>
|
<div>
|
||||||
|
<Popover
|
||||||
|
placement={'left'}
|
||||||
|
content={
|
||||||
|
<Form.Item
|
||||||
|
name={[field.name as string, 'slug']}
|
||||||
|
label={false}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
pattern: /^[a-z0-9_]+$/,
|
||||||
|
message: t('validation:invalidSlug'),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
help={t('type:slugInfo')}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
}
|
||||||
|
title={t('type:slug')}
|
||||||
|
>
|
||||||
<Tag color={'blue'}>{t(`type:${type}.name`)}</Tag>
|
<Tag color={'blue'}>{t(`type:${type}.name`)}</Tag>
|
||||||
|
</Popover>
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
placement={'left'}
|
placement={'left'}
|
||||||
title={t('type:confirmDelete')}
|
title={t('type:confirmDelete')}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { Form, message } from 'antd'
|
import { Form, message } from 'antd'
|
||||||
import { useForm } from 'antd/lib/form/Form'
|
import { useForm } from 'antd/lib/form/Form'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { FormDesignFragment, FormFieldFragment } from '../../graphql/fragment/form.fragment'
|
import { FormDesignFragment, FormFieldFragment } from '../../graphql/fragment/form.fragment'
|
||||||
import { StyledButton } from '../styled/button'
|
import { StyledButton } from '../styled/button'
|
||||||
@ -21,6 +22,7 @@ interface Props {
|
|||||||
|
|
||||||
export const Field: React.FC<Props> = ({ field, save, design, next, prev, ...props }) => {
|
export const Field: React.FC<Props> = ({ field, save, design, next, prev, ...props }) => {
|
||||||
const [form] = useForm()
|
const [form] = useForm()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
const FieldInput: React.FC<FieldTypeProps> = fieldTypes[field.type] || TextType
|
const FieldInput: React.FC<FieldTypeProps> = fieldTypes[field.type] || TextType
|
||||||
|
|
||||||
@ -34,6 +36,18 @@ export const Field: React.FC<Props> = ({ field, save, design, next, prev, ...pro
|
|||||||
await message.error('Check inputs!')
|
await message.error('Check inputs!')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getUrlDefault = (): string => {
|
||||||
|
if (router.query[field.id]) {
|
||||||
|
return router.query[field.id] as string
|
||||||
|
}
|
||||||
|
|
||||||
|
if (router.query[field.slug]) {
|
||||||
|
return router.query[field.slug] as string
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
form={form}
|
form={form}
|
||||||
@ -61,7 +75,7 @@ export const Field: React.FC<Props> = ({ field, save, design, next, prev, ...pro
|
|||||||
<StyledMarkdown design={design} type={'question'} source={field.description} />
|
<StyledMarkdown design={design} type={'question'} source={field.description} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<FieldInput design={design} field={field} />
|
<FieldInput design={design} field={field} urlValue={getUrlDefault()} />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import { StyledDateInput } from '../../styled/date.input'
|
import { StyledDateInput } from '../../styled/date.input'
|
||||||
import { FieldTypeProps } from './type.props'
|
import { FieldTypeProps } from './type.props'
|
||||||
|
|
||||||
export const DateType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
export const DateType: React.FC<FieldTypeProps> = ({ field, design, urlValue }) => {
|
||||||
const [min, setMin] = useState<Dayjs>()
|
const [min, setMin] = useState<Dayjs>()
|
||||||
const [max, setMax] = useState<Dayjs>()
|
const [max, setMax] = useState<Dayjs>()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
@ -22,6 +22,16 @@ export const DateType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
|||||||
})
|
})
|
||||||
}, [field])
|
}, [field])
|
||||||
|
|
||||||
|
let initialValue: Moment = undefined
|
||||||
|
|
||||||
|
if (field.value) {
|
||||||
|
initialValue = moment(field.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlValue) {
|
||||||
|
initialValue = moment(field.value)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@ -29,7 +39,7 @@ export const DateType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
|||||||
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
||||||
getValueFromEvent={(e: Moment) => e.format('YYYY-MM-DD')}
|
getValueFromEvent={(e: Moment) => e.format('YYYY-MM-DD')}
|
||||||
getValueProps={(e: string) => ({ value: e ? moment(e) : undefined })}
|
getValueProps={(e: string) => ({ value: e ? moment(e) : undefined })}
|
||||||
initialValue={field.value ? moment(field.value) : undefined}
|
initialValue={initialValue}
|
||||||
>
|
>
|
||||||
<StyledDateInput
|
<StyledDateInput
|
||||||
size={'large'}
|
size={'large'}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import { StyledSelect } from '../../styled/select'
|
import { StyledSelect } from '../../styled/select'
|
||||||
import { FieldTypeProps } from './type.props'
|
import { FieldTypeProps } from './type.props'
|
||||||
|
|
||||||
export const DropdownType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
export const DropdownType: React.FC<FieldTypeProps> = ({ field, design, urlValue }) => {
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ export const DropdownType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
|||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.id, 'value']}
|
name={[field.id, 'value']}
|
||||||
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
||||||
initialValue={field.value || null}
|
initialValue={urlValue || field.value || null}
|
||||||
>
|
>
|
||||||
<StyledSelect
|
<StyledSelect
|
||||||
design={design}
|
design={design}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import { StyledInput } from '../../styled/input'
|
import { StyledInput } from '../../styled/input'
|
||||||
import { FieldTypeProps } from './type.props'
|
import { FieldTypeProps } from './type.props'
|
||||||
|
|
||||||
export const EmailType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
export const EmailType: React.FC<FieldTypeProps> = ({ field, design, urlValue }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -15,7 +15,7 @@ export const EmailType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
|||||||
{ required: field.required, message: t('validation:valueRequired') },
|
{ required: field.required, message: t('validation:valueRequired') },
|
||||||
{ type: 'email', message: t('validation:invalidEmail') },
|
{ type: 'email', message: t('validation:invalidEmail') },
|
||||||
]}
|
]}
|
||||||
initialValue={field.value}
|
initialValue={urlValue || field.value}
|
||||||
>
|
>
|
||||||
<StyledInput design={design} allowClear size={'large'} />
|
<StyledInput design={design} allowClear size={'large'} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import { StyledInput } from '../../styled/input'
|
import { StyledInput } from '../../styled/input'
|
||||||
import { FieldTypeProps } from './type.props'
|
import { FieldTypeProps } from './type.props'
|
||||||
|
|
||||||
export const LinkType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
export const LinkType: React.FC<FieldTypeProps> = ({ field, design, urlValue }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -15,7 +15,7 @@ export const LinkType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
|||||||
{ required: field.required, message: t('validation:valueRequired') },
|
{ required: field.required, message: t('validation:valueRequired') },
|
||||||
{ type: 'url', message: t('validation:invalidUrl') },
|
{ type: 'url', message: t('validation:invalidUrl') },
|
||||||
]}
|
]}
|
||||||
initialValue={field.value}
|
initialValue={urlValue || field.value}
|
||||||
>
|
>
|
||||||
<StyledInput design={design} allowClear size={'large'} />
|
<StyledInput design={design} allowClear size={'large'} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@ -4,9 +4,19 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import { StyledNumberInput } from '../../styled/number.input'
|
import { StyledNumberInput } from '../../styled/number.input'
|
||||||
import { FieldTypeProps } from './type.props'
|
import { FieldTypeProps } from './type.props'
|
||||||
|
|
||||||
export const NumberType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
export const NumberType: React.FC<FieldTypeProps> = ({ field, design, urlValue }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
let initialValue: number = undefined
|
||||||
|
|
||||||
|
if (field.value) {
|
||||||
|
initialValue = parseFloat(field.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlValue) {
|
||||||
|
initialValue = parseFloat(urlValue)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@ -15,7 +25,7 @@ export const NumberType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
|||||||
{ type: 'number', message: t('validation:invalidNumber') },
|
{ type: 'number', message: t('validation:invalidNumber') },
|
||||||
{ required: field.required, message: t('validation:valueRequired') },
|
{ required: field.required, message: t('validation:valueRequired') },
|
||||||
]}
|
]}
|
||||||
initialValue={typeof field.value === 'number' ? parseFloat(field.value) : undefined}
|
initialValue={initialValue}
|
||||||
>
|
>
|
||||||
<StyledNumberInput design={design} size={'large'} />
|
<StyledNumberInput design={design} size={'large'} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@ -4,9 +4,19 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import { StyledRadio } from '../../styled/radio'
|
import { StyledRadio } from '../../styled/radio'
|
||||||
import { FieldTypeProps } from './type.props'
|
import { FieldTypeProps } from './type.props'
|
||||||
|
|
||||||
export const RadioType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
export const RadioType: React.FC<FieldTypeProps> = ({ field, design, urlValue }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
let initialValue: string = undefined
|
||||||
|
|
||||||
|
if (field.value) {
|
||||||
|
initialValue = field.value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlValue) {
|
||||||
|
initialValue = urlValue
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@ -14,7 +24,7 @@ export const RadioType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
|||||||
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
||||||
initialValue={field.options
|
initialValue={field.options
|
||||||
.map((option) => option.value)
|
.map((option) => option.value)
|
||||||
.find((value) => value === field.value)}
|
.find((value) => value === initialValue)}
|
||||||
>
|
>
|
||||||
<Radio.Group>
|
<Radio.Group>
|
||||||
{field.options
|
{field.options
|
||||||
|
|||||||
@ -3,16 +3,26 @@ import React from 'react'
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { FieldTypeProps } from './type.props'
|
import { FieldTypeProps } from './type.props'
|
||||||
|
|
||||||
export const RatingType: React.FC<FieldTypeProps> = ({ field }) => {
|
export const RatingType: React.FC<FieldTypeProps> = ({ field, urlValue }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
// TODO add ratings
|
// TODO add ratings
|
||||||
|
|
||||||
|
let initialValue: number = undefined
|
||||||
|
|
||||||
|
if (field.value) {
|
||||||
|
initialValue = parseFloat(field.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlValue) {
|
||||||
|
initialValue = parseFloat(urlValue)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.id, 'value']}
|
name={[field.id, 'value']}
|
||||||
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
||||||
initialValue={parseFloat(field.value)}
|
initialValue={initialValue}
|
||||||
>
|
>
|
||||||
<Rate allowHalf />
|
<Rate allowHalf />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import { StyledInput } from '../../styled/input'
|
import { StyledInput } from '../../styled/input'
|
||||||
import { FieldTypeProps } from './type.props'
|
import { FieldTypeProps } from './type.props'
|
||||||
|
|
||||||
export const TextType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
export const TextType: React.FC<FieldTypeProps> = ({ field, design, urlValue }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
// TODO focus when becomes visible
|
// TODO focus when becomes visible
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ export const TextType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
|||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.id, 'value']}
|
name={[field.id, 'value']}
|
||||||
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
||||||
initialValue={field.value}
|
initialValue={urlValue || field.value}
|
||||||
>
|
>
|
||||||
<StyledInput design={design} allowClear size={'large'} />
|
<StyledInput design={design} allowClear size={'large'} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import { StyledTextareaInput } from '../../styled/textarea.input'
|
import { StyledTextareaInput } from '../../styled/textarea.input'
|
||||||
import { FieldTypeProps } from './type.props'
|
import { FieldTypeProps } from './type.props'
|
||||||
|
|
||||||
export const TextareaType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
export const TextareaType: React.FC<FieldTypeProps> = ({ field, design, urlValue }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -12,7 +12,7 @@ export const TextareaType: React.FC<FieldTypeProps> = ({ field, design }) => {
|
|||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.id, 'value']}
|
name={[field.id, 'value']}
|
||||||
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
||||||
initialValue={field.value}
|
initialValue={urlValue || field.value}
|
||||||
>
|
>
|
||||||
<StyledTextareaInput design={design} allowClear autoSize />
|
<StyledTextareaInput design={design} allowClear autoSize />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@ -3,4 +3,5 @@ import { FormDesignFragment, FormFieldFragment } from '../../../graphql/fragment
|
|||||||
export interface FieldTypeProps {
|
export interface FieldTypeProps {
|
||||||
field: FormFieldFragment
|
field: FormFieldFragment
|
||||||
design: FormDesignFragment
|
design: FormDesignFragment
|
||||||
|
urlValue?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,15 +3,21 @@ import React from 'react'
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { FieldTypeProps } from './type.props'
|
import { FieldTypeProps } from './type.props'
|
||||||
|
|
||||||
export const YesNoType: React.FC<FieldTypeProps> = ({ field }) => {
|
export const YesNoType: React.FC<FieldTypeProps> = ({ field, urlValue }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
let initialValue = !!field.value
|
||||||
|
|
||||||
|
if (urlValue !== undefined) {
|
||||||
|
initialValue = !!urlValue
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.id, 'value']}
|
name={[field.id, 'value']}
|
||||||
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
|
||||||
initialValue={!!field.value}
|
initialValue={initialValue}
|
||||||
valuePropName={'checked'}
|
valuePropName={'checked'}
|
||||||
getValueFromEvent={(checked: boolean) => (checked ? '1' : '')}
|
getValueFromEvent={(checked: boolean) => (checked ? '1' : '')}
|
||||||
getValueProps={(e: string) => ({ checked: !!e })}
|
getValueProps={(e: string) => ({ checked: !!e })}
|
||||||
|
|||||||
@ -35,6 +35,7 @@ export interface AdminFormFieldLogicJumpFragment {
|
|||||||
export interface AdminFormFieldFragment {
|
export interface AdminFormFieldFragment {
|
||||||
id: string
|
id: string
|
||||||
title: string
|
title: string
|
||||||
|
slug?: string
|
||||||
type: string
|
type: string
|
||||||
description: string
|
description: string
|
||||||
required: boolean
|
required: boolean
|
||||||
@ -106,6 +107,7 @@ export const ADMIN_FORM_FRAGMENT = gql`
|
|||||||
fields {
|
fields {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
|
slug
|
||||||
type
|
type
|
||||||
description
|
description
|
||||||
required
|
required
|
||||||
|
|||||||
@ -32,6 +32,7 @@ export interface FormFieldLogicJumpFragment {
|
|||||||
export interface FormFieldFragment {
|
export interface FormFieldFragment {
|
||||||
id: string
|
id: string
|
||||||
title: string
|
title: string
|
||||||
|
slug?: string
|
||||||
type: string
|
type: string
|
||||||
description: string
|
description: string
|
||||||
required: boolean
|
required: boolean
|
||||||
@ -81,6 +82,7 @@ export const FORM_FRAGMENT = gql`
|
|||||||
fields {
|
fields {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
|
slug
|
||||||
type
|
type
|
||||||
description
|
description
|
||||||
required
|
required
|
||||||
|
|||||||
@ -51,6 +51,8 @@
|
|||||||
},
|
},
|
||||||
"required": "Required",
|
"required": "Required",
|
||||||
"requiredInfo": "If required, default value must be set to enable users to submit form!",
|
"requiredInfo": "If required, default value must be set to enable users to submit form!",
|
||||||
|
"slug": "Slug",
|
||||||
|
"slugInfo": "Use slug to pass the default dynamic as url parameter ?slug=value",
|
||||||
"textarea": {
|
"textarea": {
|
||||||
"default": "Default Value",
|
"default": "Default Value",
|
||||||
"name": "Text Area"
|
"name": "Text Area"
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
"emailRequired": "Please provide an Email",
|
"emailRequired": "Please provide an Email",
|
||||||
"invalidEmail": "Must be a valid email!",
|
"invalidEmail": "Must be a valid email!",
|
||||||
"invalidNumber": "Must be a valid number!",
|
"invalidNumber": "Must be a valid number!",
|
||||||
|
"invalidSlug": "Slug can only contain lowercase a-z, 0-9 and _",
|
||||||
"invalidUrl": "Must be a valid URL",
|
"invalidUrl": "Must be a valid URL",
|
||||||
"languageRequired": "Please select a Language",
|
"languageRequired": "Please select a Language",
|
||||||
"mandatoryFieldsMissing": "Mandatory fields missing",
|
"mandatoryFieldsMissing": "Mandatory fields missing",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user