Skip to content

Commit

Permalink
FormGenerator update
Browse files Browse the repository at this point in the history
  • Loading branch information
PatrikMatiasko committed May 8, 2024
1 parent f2352eb commit 2e69e37
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 37 deletions.
2 changes: 2 additions & 0 deletions src/components/Atomic/Editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const Editor = forwardRef<EditorRefType, Props>((props, ref) => {
onChange,
onError,
onResize,
onValidation,
onViewChange,
schema,
style,
Expand Down Expand Up @@ -89,6 +90,7 @@ const Editor = forwardRef<EditorRefType, Props>((props, ref) => {
statusBar: false,
onChangeText,
onValidationError: onValidationError,
onValidate: onValidation,
schema,
}

Expand Down
1 change: 1 addition & 0 deletions src/components/Atomic/Editor/Editor.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type Props = {
onChange?: (json: any) => void
onError?: (error: any) => void
onResize?: (width: number, height: number, callback: () => void) => void
onValidation?: (data: any) => void
onViewChange?: (fullview: boolean) => void
schema?: [] | object
style?: CSSProperties
Expand Down
3 changes: 2 additions & 1 deletion src/components/Atomic/Headline/Headline.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode } from 'react'
import { CSSProperties, ReactNode } from 'react'

export type HeadlineType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'

Expand All @@ -7,6 +7,7 @@ export type Props = {
children: ReactNode
dataTestId?: string
id?: string
style?: CSSProperties
type?: HeadlineType
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/Atomic/Switch/Switch.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import styled from '@emotion/styled'
import { ThemeType, get } from '../_theme'

export const switchC = css`
display: flex;
display: inline-flex;
align-items: center;
`

Expand Down
2 changes: 1 addition & 1 deletion src/components/Atomic/Switch/Switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const Switch = forwardRef<HTMLInputElement, Props>((props, ref) => {
ref={ref}
type='checkbox'
/>
<Slider css={[(styles.sliderStyle(size || 'big'), disabled && styles.disabled)]} size={size} />
<Slider css={[styles.sliderStyle(size || 'big'), disabled && styles.disabled]} size={size} />
</div>
{label && <div css={[styles.label, labelBefore && styles.labelBeforeSwitch]}>{label}</div>}
</label>
Expand Down
26 changes: 22 additions & 4 deletions src/components/Atomic/Switch/__snapshots__/Switch.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
exports[`<Switch> render correctly - snapshot 1`] = `
<DocumentFragment>
.emotion-0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
Expand Down Expand Up @@ -45,6 +45,10 @@ exports[`<Switch> render correctly - snapshot 1`] = `
bottom: 0;
-webkit-transition: 0.4s;
transition: 0.4s;
width: 24px;
height: 16px;
border-radius: 20px;
overflow: hidden;
}
.emotion-3:before {
Expand All @@ -60,6 +64,11 @@ exports[`<Switch> render correctly - snapshot 1`] = `
height: 12px;
}
.emotion-3:before {
width: 12px;
height: 12px;
}
.emotion-6 {
width: 32px;
height: 20px;
Expand Down Expand Up @@ -92,6 +101,10 @@ exports[`<Switch> render correctly - snapshot 1`] = `
bottom: 0;
-webkit-transition: 0.4s;
transition: 0.4s;
width: 32px;
height: 20px;
border-radius: 26.6667px;
overflow: hidden;
}
.emotion-8:before {
Expand All @@ -107,6 +120,11 @@ exports[`<Switch> render correctly - snapshot 1`] = `
height: 16px;
}
.emotion-8:before {
width: 16px;
height: 16px;
}
.emotion-25 {
font-size: 14px;
padding-left: 8px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ exports[`<TileToggle> render correctly - snapshot 1`] = `
}
.emotion-2 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
Expand Down Expand Up @@ -77,6 +77,10 @@ exports[`<TileToggle> render correctly - snapshot 1`] = `
bottom: 0;
-webkit-transition: 0.4s;
transition: 0.4s;
width: 32px;
height: 20px;
border-radius: 26.6667px;
overflow: hidden;
}
.emotion-5:before {
Expand All @@ -92,6 +96,11 @@ exports[`<TileToggle> render correctly - snapshot 1`] = `
height: 16px;
}
.emotion-5:before {
width: 16px;
height: 16px;
}
<div>
<div
class="emotion-0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ const DevicesResourcesModal: FC<Props> = (props) => {
const dataForSend = typeof jsonData === 'string' && jsonData.startsWith('"') && jsonData.endsWith('"') ? jsonData.replace(/"/g, '') : jsonData

if (isUpdateModal) {
console.log('!!!')
console.log(dataForSend)
updateResource(params, dataForSend)
} else {
createResource(params, dataForSend)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Controller, useForm } from 'react-hook-form'
import get from 'lodash/get'
import isObject from 'lodash/isObject'
import isFunction from 'lodash/isFunction'
import set from 'lodash/set'

import { PropertiesType, Property } from '../GeneratedResourceForm.types'
import FormInput from '../../../Atomic/FormInput'
Expand All @@ -15,14 +16,24 @@ import { ModalStrippedLine } from '../../../Atomic/Modal'
import FormGroup from '../../../Atomic/FormGroup'
import { Props } from './FormGenerator.types'
import { knownResourceHref } from '../constants'
import Editor from '../../../Atomic/Editor'

export const sortProperties = (properties: PropertiesType) =>
properties
? Object.keys(properties).map((href: string) => {
// @ts-ignore
const property = properties[href] as Property
return { ...property, href }
})
? Object.keys(properties)
.map((href: string) => {
// @ts-ignore
const property = properties[href] as Property
return { ...property, href }
})
.sort((a, b) => (a.href || a.href).localeCompare(b.href || b.href))
.sort((a, b) =>
a.hasOwnProperty('properties') && !b.hasOwnProperty('properties')
? 1
: b.hasOwnProperty('properties') && !a.hasOwnProperty('properties')
? -1
: 0
)
: []

export const getHref = (parentHref: string, href: string) => `${parentHref !== '' ? parentHref + '/' : parentHref}${href}`
Expand All @@ -35,6 +46,7 @@ const FormGenerator: FC<Props> = (props) => {
const isSingleValueMode = useMemo(() => !isObject(values), [values])
const formDefaultValues = useMemo(() => (isSingleValueMode ? values : { [topHref]: values }), [isSingleValueMode, topHref, values])
const [hasError, setHasError] = useState(false)
const [editorErrors, setEditorErrors] = useState<string[]>([])

const {
control,
Expand All @@ -47,30 +59,49 @@ const FormGenerator: FC<Props> = (props) => {
}, [reset, resetFormKey])

const getDefaultValue = useCallback(
(href: string) => (isSingleValueMode ? values : get(values, href.replace(topHref, '').substring(1), '')),
(href: string) => (isSingleValueMode ? values : get(values, href.replace(topHref, '').substring(1).replace('/', '.'), '')),
[isSingleValueMode, topHref, values]
)

const handleValueChange = useCallback(
(value: any) => {
(value: any, href?: string) => {
if (isFunction(onChange)) {
if (isSingleValueMode) {
onChange(value === undefined ? '' : value)
} else if (href) {
onChange(set(values, href, value === undefined ? '' : value))
}
}
},
[onChange, isSingleValueMode]
[onChange, isSingleValueMode, values]
)

const handleEditorChange = useCallback(
(value: any, href: string) => {
try {
handleValueChange(JSON.parse(value), href)
setEditorErrors(editorErrors.filter((error) => error !== href))
} catch (e) {
setEditorErrors([...editorErrors, href])
}
},
[editorErrors, handleValueChange]
)

useEffect(() => {
if (isValid && hasError) {
setHasError(false)
isFunction(setFormError) && setFormError(false)
} else if (!isValid && !hasError) {
if (editorErrors.length > 0) {
setHasError(true)
isFunction(setFormError) && setFormError(true)
} else {
if (isValid && editorErrors.length === 0 && hasError) {
setHasError(false)
isFunction(setFormError) && setFormError(false)
} else if (!isValid && !hasError) {
setHasError(true)
isFunction(setFormError) && setFormError(true)
}
}
}, [hasError, isValid, setFormError])
}, [editorErrors, hasError, isValid, setFormError])

useEffect(() => {
const buildProperties: any = (properties: PropertiesType, parentHref = '', readOnly = false, depth = 1) =>
Expand Down Expand Up @@ -111,7 +142,7 @@ const FormGenerator: FC<Props> = (props) => {
name={field.name}
onChange={(e) => {
field.onChange(formatValue(e.target.value))
handleValueChange(formatValue(e.target.value))
handleValueChange(formatValue(e.target.value), property.href)
}}
readOnly={readOnlyP}
rightContent={property.unit}
Expand All @@ -138,33 +169,72 @@ const FormGenerator: FC<Props> = (props) => {
smallPadding
component={
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
<Switch checked={field.value} key={`${key}-input`} name={field.name} onChange={field.onChange} />
<Switch
checked={field.value}
key={`${key}-input`}
name={field.name}
onChange={(e) => {
field.onChange(e)
handleValueChange(e.target.checked, property.href)
}}
/>
</div>
}
label={property.title}
label={property.title || property.href}
/>
)}
/>
)
} else if (property.type === 'object' && property.properties) {
return (
<Spacer key={key} type='mb-5 mt-8'>
<Spacer type='mb-4'>
<Headline type='h5'>{property.title || property.href}</Headline>
} else if (property.type === 'object') {
if (property.properties) {
return (
<Spacer key={key} type='mb-5 mt-8'>
<Spacer type='mb-4'>
<Headline style={{ textTransform: 'capitalize' }} type='h5'>
{property.title || property.href}
</Headline>
</Spacer>
<Spacer type={`pl-${5 * depth}`}>{buildProperties(property.properties, href, readOnlyP, depth + 1)}</Spacer>
</Spacer>
<Spacer type={`pl-${5 * depth}`}>{buildProperties(property.properties, href, readOnlyP, depth + 1)}</Spacer>
</Spacer>
)
)
} else {
return (
<Controller
control={control}
defaultValue={defaultValue}
key={key}
name={href}
render={({ field }) => (
<ModalStrippedLine
smallPadding
component={
<Editor
height='200px'
i18n={{
viewText: 'view',
}}
json={field.value || {}}
onChange={(value) => {
field.onChange(value)
handleEditorChange(value, property.href)
}}
/>
}
label={property.title || property.href}
/>
)}
/>
)
}
} else {
return <div key={key} />
}
})

if (properties) {
console.log(properties)
setComponents(buildProperties(properties))
}
}, [control, errors, getDefaultValue, handleValueChange, properties])
}, [control, errors, getDefaultValue, handleEditorChange, handleValueChange, properties])

return <>{components}</>
}
Expand Down

0 comments on commit 2e69e37

Please sign in to comment.