erp-platform/ui/src/views/form/FormDevExpress.tsx

233 lines
8.9 KiB
TypeScript
Raw Normal View History

2025-05-06 06:45:49 +00:00
import { DX_CLASSNAMES } from '@/constants/app.constant'
import {
Form as FormDx,
GroupItem as GroupItemDx,
Label as LabelDx,
SimpleItem as SimpleItemDx,
} from 'devextreme-react/form'
import { FieldDataChangedEvent, GroupItem } from 'devextreme/ui/form'
import { Dispatch, RefObject, useEffect, useRef } from 'react'
2025-05-06 06:45:49 +00:00
import { GridBoxEditorComponent } from './editors/GridBoxEditorComponent'
import { TagBoxEditorComponent } from './editors/TagBoxEditorComponent'
import { RowMode, SimpleItemWithColData } from './types'
import { PlatformEditorTypes } from '@/proxy/form/models'
2025-05-06 06:45:49 +00:00
const FormDevExpress = (props: {
2025-09-21 20:05:13 +00:00
listFormCode: string
isSubForm?: boolean
2025-05-06 06:45:49 +00:00
mode: RowMode
refForm: RefObject<FormDx>
formData: any
formItems: GroupItem[]
setFormData: Dispatch<any>
}) => {
2025-09-21 20:05:13 +00:00
const { listFormCode, isSubForm, mode, refForm, formData, formItems, setFormData } = props
2025-05-06 06:45:49 +00:00
const formDataRef = useRef(formData)
const formItemsRef = useRef(formItems)
useEffect(() => {
formDataRef.current = formData
}, [formData])
useEffect(() => {
formItemsRef.current = formItems
}, [formItems])
// formItems değiştiğinde (özellikle cascading alanlar için) editörlerin dataSource'larını güncelle
useEffect(() => {
if (!refForm.current?.instance) return
const allItems = formItems.flatMap((group) => (group.items as SimpleItemWithColData[]) || [])
allItems.forEach((item) => {
if (item.colData?.lookupDto?.dataSourceType && item.editorOptions?.dataSource) {
try {
const editor = refForm.current?.instance.getEditor(item.dataField!)
if (editor) {
editor.option('dataSource', item.editorOptions.dataSource)
}
} catch (err) {
// Editor henüz oluşmamış olabilir, sessizce devam et
console.debug('Editor update skipped for', item.dataField, err)
}
}
})
}, [formItems])
2025-11-14 12:44:59 +00:00
// Cascade fieldlerin disabled durumunu güncelle
const updateCascadeDisabledStates = () => {
if (!refForm.current?.instance) return
const allItems = formItemsRef.current.flatMap((group) => (group.items as SimpleItemWithColData[]) || [])
allItems.forEach((item) => {
const cascadeParentFields = item.colData?.lookupDto?.cascadeParentFields
if (cascadeParentFields) {
const parentFields = cascadeParentFields.split(',').map((f: string) => f.trim())
try {
const editor = refForm.current?.instance.getEditor(item.dataField!)
if (editor && mode !== 'view') {
// Parent fieldlerden en az biri boşsa disabled olmalı
const shouldDisable = parentFields.some((parentField: string) => {
return !formDataRef.current || !formDataRef.current[parentField]
})
editor.option('disabled', shouldDisable)
}
} catch (err) {
console.debug('Cascade disabled update skipped for', item.dataField, err)
}
}
})
}
// formData değiştiğinde cascade disabled durumlarını güncelle
useEffect(() => {
updateCascadeDisabledStates()
}, [formData, mode])
2025-05-06 06:45:49 +00:00
return (
2025-09-23 19:52:08 +00:00
<form className={`${DX_CLASSNAMES} ${!isSubForm ? 'px-2' : ''} pb-2`}>
2025-05-06 06:45:49 +00:00
<FormDx
ref={refForm}
formData={formData}
onFieldDataChanged={async (e: FieldDataChangedEvent) => {
const newFormData = { ...formData, [e.dataField!]: e.value }
// Cascading child field'leri temizle (parent field değiştiğinde)
const allItems = formItemsRef.current.flatMap((group) => (group.items as SimpleItemWithColData[]) || [])
const cascadingChildren = allItems.filter((item) => {
const parentFields = item.colData?.lookupDto?.cascadeParentFields?.split(',') || []
return parentFields.some(field => field.trim() === e.dataField)
})
// Parent field değiştiğinde child field'leri temizle
cascadingChildren.forEach((child) => {
newFormData[child.dataField!] = null
})
setFormData(newFormData)
2025-11-14 12:44:59 +00:00
// Cascade disabled durumlarını güncelle (setTimeout ile editor güncellemesinden sonra çalışsın)
setTimeout(() => {
updateCascadeDisabledStates()
}, 0)
//Dinamik script
const changeItem = formItemsRef.current
.flatMap((group) => (group.items as SimpleItemWithColData[]) || [])
.find((i: SimpleItemWithColData) => i.dataField === e.dataField)
2025-10-22 14:58:27 +00:00
if (changeItem?.editorScript) {
try {
//setFormData({...formData, Path: e.value});
//UiEvalService.ApiGenerateBackgroundWorkers();
//setFormData({ ...formData, Path: (v => v === '1' ? '1-deneme' : v === '0' ? '0-deneme' : '')(e.value) })
2025-10-22 14:58:27 +00:00
eval(changeItem.editorScript)
} catch (err) {
console.error('Script execution failed for', changeItem.name, err)
}
}
2025-05-06 06:45:49 +00:00
}}
2025-09-19 14:06:48 +00:00
onContentReady={(e) => {
const groupItems = e.component.option('items') as any[]
const firstItem = groupItems?.[0]?.items?.[0]
2025-09-19 14:06:48 +00:00
if (firstItem?.dataField) {
const editor = e.component.getEditor(firstItem.dataField)
2025-09-29 07:08:24 +00:00
mode !== 'view' && editor?.focus()
2025-09-19 14:06:48 +00:00
}
}}
2025-05-06 06:45:49 +00:00
>
{formItems.map((formGroupItem, i) => {
return (
<GroupItemDx
key={'formGroupItem-' + i}
colCount={formGroupItem.colCount}
colSpan={formGroupItem.colSpan}
caption={formGroupItem.caption}
>
{(formGroupItem.items as SimpleItemWithColData[])?.map((formItem, i) => {
return formItem.editorType2 === PlatformEditorTypes.dxTagBox ? (
<SimpleItemDx
key={'formItem-' + i}
{...formItem}
render={() => (
<TagBoxEditorComponent
value={formData[formItem.dataField!] || []}
setDefaultValue={false}
values={formData}
options={formItem.tagBoxOptions}
col={formItem.colData}
onValueChanged={(e: any) => {
setFormData({ ...formData, [formItem.dataField!]: e })
}}
editorOptions={{
...formItem.editorOptions,
...(mode === 'view' ? { readOnly: true } : {}),
}}
></TagBoxEditorComponent>
)}
>
<LabelDx text={formItem.name} />
</SimpleItemDx>
) : formItem.editorType2 === PlatformEditorTypes.dxGridBox ? (
<SimpleItemDx
key={'formItem-' + i}
{...formItem}
render={() => (
<GridBoxEditorComponent
value={formData[formItem.dataField!] || []}
values={formData}
options={formItem.gridBoxOptions}
col={formItem.colData}
onValueChanged={(e: any) => {
setFormData({ ...formData, [formItem.dataField!]: e })
}}
editorOptions={{
...formItem.editorOptions,
...(mode === 'view' ? { readOnly: true } : {}),
}}
></GridBoxEditorComponent>
)}
>
<LabelDx text={formItem.name} />
</SimpleItemDx>
) : (
<SimpleItemDx
cssClass="font-semibold"
2025-05-06 06:45:49 +00:00
key={'formItem-' + i}
{...formItem}
editorOptions={{
...formItem.editorOptions,
2025-09-19 14:06:48 +00:00
...(mode === 'view' ? { readOnly: true } : { autoFocus: i === 1 }),
buttons: (formItem.editorOptions?.buttons || []).map((btn: any) => {
if (btn?.options?.onClick && typeof btn.options.onClick === 'string') {
const origClick = eval(`(${btn.options.onClick})`)
btn.options.onClick = (e: any) => {
origClick({
...e,
2025-09-29 07:08:24 +00:00
formData: formDataRef.current,
fieldName: formItem.dataField,
2025-09-29 07:08:24 +00:00
mode,
})
}
}
return btn
}),
2025-05-06 06:45:49 +00:00
}}
/>
)
})}
</GroupItemDx>
)
})}
</FormDx>
</form>
)
}
export default FormDevExpress