fix #6 Date min and Max fields, with general support of Object keys in admin form fields

This commit is contained in:
Michael Schramm 2020-06-02 12:25:11 +02:00
parent 9f466b5c27
commit 6b554bb723
5 changed files with 81 additions and 17 deletions

View File

@ -17,26 +17,25 @@ export const DateType: React.FC<AdminFieldTypeProps> = ({field, form}) => {
format={'YYYY-MM-DD'}
/>
</Form.Item>
{/* TODO add options
<Form.Item
label={'Min Date'}
name={[field.name, 'min']}
name={[field.name, 'optionKeys', 'min']}
labelCol={{ span: 6 }}
getValueFromEvent={e => e.format('YYYY-MM-DD')}
getValueProps={e => ({value: e ? moment(e) : undefined})}
>
<DatePicker />
</Form.Item>
<Form.Item
label={'Max Date'}
name={[field.name, 'max']}
name={[field.name, 'optionKeys', 'max']}
labelCol={{ span: 6 }}
getValueFromEvent={e => e.format('YYYY-MM-DD')}
getValueProps={e => ({value: e ? moment(e) : undefined})}
>
<DatePicker />
</Form.Item>
*/}
</div>
)
}

View File

@ -1,12 +1,24 @@
import {Form} from 'antd'
import dayjs, {Dayjs} from 'dayjs'
import moment from 'moment'
import React from 'react'
import React, {useEffect, useState} from 'react'
import {StyledDateInput} from '../../styled/date.input'
import {FieldTypeProps} from './type.props'
export const DateType: React.FC<FieldTypeProps> = ({ field, design}) => {
// TODO check min and max
// TODO if default is passed, then the changing should not be required
const [min, setMin] = useState<Dayjs>()
const [max, setMax] = useState<Dayjs>()
useEffect(() => {
field.options.forEach(option => {
if (option.key === 'min') {
setMin(dayjs(option.value))
}
if (option.key === 'max') {
setMax(dayjs(option.value))
}
})
}, [field])
return (
<div>
@ -23,6 +35,15 @@ export const DateType: React.FC<FieldTypeProps> = ({ field, design}) => {
size={'large'}
design={design}
autoFocus
disabledDate={(d: any) => {
if (min && min.isAfter(d)) {
return true
}
if (max && max.isBefore(d)) {
return true
}
return false
}}
/>
</Form.Item>
</div>

View File

@ -15,11 +15,15 @@ export interface AdminFormPageFragment {
}
export interface AdminFormFieldOptionFragment {
key?: number
key?: string
title?: string
value: string
}
export interface AdminFormFieldOptionKeysFragment {
[key: string]: string
}
export interface AdminFormFieldLogicJumpFragment {
fieldA?: string
valueB?: string
@ -37,6 +41,7 @@ export interface AdminFormFieldFragment {
value: string
options: AdminFormFieldOptionFragment[]
optionKeys?: AdminFormFieldOptionKeysFragment
logicJump: AdminFormFieldLogicJumpFragment

View File

@ -16,7 +16,7 @@ export interface FormPageFragment {
}
export interface FormFieldOptionFragment {
key?: number
key?: string
title?: string
value: string
}

View File

@ -11,7 +11,11 @@ import {SelfNotificationsTab} from 'components/form/admin/self.notifications.tab
import {StartPageTab} from 'components/form/admin/start.page.tab'
import Structure from 'components/structure'
import {withAuth} from 'components/with.auth'
import {AdminFormFieldFragment} from 'graphql/fragment/admin.form.fragment'
import {
AdminFormFieldFragment,
AdminFormFieldOptionFragment,
AdminFormFieldOptionKeysFragment
} from 'graphql/fragment/admin.form.fragment'
import {
ADMIN_FORM_UPDATE_MUTATION,
AdminFormUpdateMutationData,
@ -32,11 +36,29 @@ const Index: NextPage = () => {
const [fields, setFields] = useState<AdminFormFieldFragment[]>([])
const [update] = useMutation<AdminFormUpdateMutationData, AdminFormUpdateMutationVariables>(ADMIN_FORM_UPDATE_MUTATION)
const processNext = (next: AdminFormQueryData): AdminFormQueryData => {
next.form.fields = next.form.fields.map(field => {
const keys: AdminFormFieldOptionKeysFragment = {}
field.options.forEach(option => {
if (option.key) {
keys[option.key] = option.value
}
})
field.optionKeys = keys
return field
})
return next
}
const {data, loading, error} = useQuery<AdminFormQueryData, AdminFormQueryVariables>(ADMIN_FORM_QUERY, {
variables: {
id: router.query.id as string
},
onCompleted: next => {
next = processNext(next)
form.setFieldsValue(next)
setFields(next.form.fields)
}
@ -45,12 +67,27 @@ const Index: NextPage = () => {
const save = async (formData: AdminFormQueryData) => {
setSaving(true)
formData.form.fields = formData.form.fields.filter(e => e && e.type)
formData.form.fields = formData.form.fields.filter(e => e && e.type).map(({optionKeys, ...field}) => {
if (optionKeys) {
//
return {
...field,
options: Object.keys(optionKeys).map((key): AdminFormFieldOptionFragment => {
return {
value: optionKeys[key],
key,
}
}).filter(e => !!e.value)
}
}
return field
})
try {
const next = (await update({
const next = processNext((await update({
variables: cleanInput(formData),
})).data
})).data)
form.setFieldsValue(next)
setFields(next.form.fields)
@ -76,10 +113,12 @@ const Index: NextPage = () => {
{ href: '/admin/forms', name: t('admin:forms') },
]}
extra={[
<Link href={'/admin/forms/[id]/submissions'} as={`/admin/forms/${router.query.id}/submissions`}>
<Button
key={'submissions'}
>
<Link
key={'submissions'}
href={'/admin/forms/[id]/submissions'}
as={`/admin/forms/${router.query.id}/submissions`}
>
<Button>
Submissions
</Button>
</Link>,