Skip to content

Instantly share code, notes, and snippets.

@firdausramlan
Forked from ferdinandsalis/form.js
Created November 25, 2017 01:55
Show Gist options
  • Save firdausramlan/678f87ba9192ce9181f2d118d07158b8 to your computer and use it in GitHub Desktop.
Save firdausramlan/678f87ba9192ce9181f2d118d07158b8 to your computer and use it in GitHub Desktop.
import React from 'react'
import revalidation from 'revalidation'
import gql from 'graphql-tag.macro'
import { filter } from 'graphql-anywhere'
import { curry } from 'ramda'
import { compose, withProps, withHandlers } from 'recompose'
import { graphql } from 'react-apollo'
import { Button } from '../common/styled'
import { getValue } from '../form/utils'
import { isRequired } from '../../utils/validation'
import { connectionQuery } from './connection'
import Field from '../form/field'
import Fieldset from '../form/fieldset'
import Input from '../form/input'
const Form = ({
revalidation: {
form,
onChange,
valid,
onSubmit,
submitted,
updateValueAndValidate,
errors = []
},
onSubmit: submitCb
}) => (
<form>
<Field
required
name="name"
label="Name des Standortes"
onChange={updateValueAndValidate}
value={form.name}
errors={errors.name}
control={Input}
placeholder="Lager"
/>
<Fieldset heading="Adresse">
<Field
required
name="street"
label="Straße"
value={form.address.street}
errors={errors.address.street}
onChange={e => onChange(['address', 'street'], getValue(e))}
control={Input}
placeholder="Parkring 18/4"
/>
<Field
required
name="postalcode"
label="Postleitzahl"
value={form.address.postalcode}
errors={errors.postalcode}
onChange={e => onChange(['address', 'postalcode'], getValue(e))}
control={Input}
placeholder="1010"
/>
<Field
required
name="locality"
label="Ort"
value={form.address.locality}
errors={errors.address.locality}
onChange={e => onChange(['address', 'locality'], getValue(e))}
control={Input}
placeholder="Wien"
/>
<Field
required
name="country"
label="Land"
value={form.address.country}
errors={errors.address.country}
onChange={e => onChange(['address', 'country'], getValue(e))}
control={Input}
placeholder="AT"
/>
</Fieldset>
<Button
children="Speichern"
disabled={!valid}
onClick={e => {
e.preventDefault()
onSubmit(({ valid, form }) => {
if (valid) {
return submitCb(form)
} else {
return null
}
})
}}
/>
</form>
)
const model = {
name: '',
address: {
street: '',
postalcode: '',
locality: '',
country: ''
}
}
const rules = {
name: [[isRequired, 'Name darf nicht leer sein']],
address: {
street: [[isRequired, 'Straße darf nicht leer sein']],
postalcode: [[isRequired, 'Postleitzahl darf nicht leer sein']],
locality: [[isRequired, 'Ort darf nicht leer sein']],
country: [[isRequired, 'Land darf nicht leer sein']]
}
}
export const formFragment = gql`
fragment LocationForm on Location {
name
address {
street
postalcode
locality
country
}
}
`
const BaseForm = revalidation(Form)
// # Create Form
export const createMutation = gql`
mutation createLocation($input: CreateLocationInput!) {
createLocation(input: $input) {
location {
id
locationId
...LocationForm
}
}
}
${formFragment}
`
const withCreateMutation = graphql(createMutation, { name: 'createLocation' })
const handleCreate = curry(async ({ onSuccess, createLocation }, values) => {
try {
const result = await createLocation({
variables: { input: { location: values } },
refetchQueries: [
{
query: connectionQuery,
variables: {
limit: 25,
offset: 0,
condition: null,
orderBy: { attribute: 'CREATED_AT', descending: true }
}
}
]
})
typeof onSuccess === 'function' && onSuccess(result)
} catch (error) {
console.log(error)
}
})
export const CreateForm = compose(
withCreateMutation,
withHandlers({ handleCreate }),
withProps(({ handleCreate }) => ({
initialState: model,
rules: rules,
onSubmit: handleCreate,
validateSingle: true,
validateOnChange: true
}))
)(BaseForm)
// # Update Form
export const initialDataQuery = gql`
query showLocation($id: ID!) {
location(id: $id) {
id
...LocationForm
}
}
${formFragment}
`
const withInitialData = graphql(initialDataQuery, {
options: ({ id }) => ({ variables: { id } })
})
export const updateMutation = gql`
mutation updateLocation($input: UpdateLocationInput!) {
updateLocation(input: $input) {
location {
id
locationId
...LocationForm
}
}
}
${formFragment}
`
const withUpdateMutation = graphql(updateMutation, { name: 'updateLocation' })
const handleUpdate = curry(
async ({ onSuccess, id, updateLocation }, values) => {
try {
const result = await updateLocation({
variables: { input: { id, locationPatch: values } }
})
typeof onSuccess === 'function' && onSuccess(result)
} catch (error) {
console.log(error)
}
}
)
export const UpdateForm = compose(
withInitialData,
withUpdateMutation,
withHandlers({ handleUpdate }),
withProps(({ data, handleUpdate }) => ({
initialState: model,
updateForm: data.loading ? null : filter(formFragment, data.location),
rules: rules,
onSubmit: handleUpdate,
validateSingle: true,
validateOnChange: true
}))
)(BaseForm)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment