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'
|
2025-09-24 17:46:03 +00:00
|
|
|
|
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'
|
2025-08-12 08:39:06 +00:00
|
|
|
|
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
|
2025-09-21 15:11:12 +00:00
|
|
|
|
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
|
|
|
|
|
2025-09-24 17:46:03 +00:00
|
|
|
|
const formDataRef = useRef(formData)
|
2025-11-11 12:00:52 +00:00
|
|
|
|
const formItemsRef = useRef(formItems)
|
|
|
|
|
|
|
2025-09-24 17:46:03 +00:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
formDataRef.current = formData
|
|
|
|
|
|
}, [formData])
|
|
|
|
|
|
|
2025-11-11 12:00:52 +00:00
|
|
|
|
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}
|
2025-09-24 17:46:03 +00:00
|
|
|
|
onFieldDataChanged={async (e: FieldDataChangedEvent) => {
|
2025-11-11 12:00:52 +00:00
|
|
|
|
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-09-24 17:46:03 +00:00
|
|
|
|
|
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)
|
|
|
|
|
|
|
2025-09-24 17:46:03 +00:00
|
|
|
|
//Dinamik script
|
2025-11-11 12:00:52 +00:00
|
|
|
|
const changeItem = formItemsRef.current
|
2025-09-24 17:46:03 +00:00
|
|
|
|
.flatMap((group) => (group.items as SimpleItemWithColData[]) || [])
|
|
|
|
|
|
.find((i: SimpleItemWithColData) => i.dataField === e.dataField)
|
|
|
|
|
|
|
2025-10-22 14:58:27 +00:00
|
|
|
|
if (changeItem?.editorScript) {
|
2025-09-24 17:46:03 +00:00
|
|
|
|
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)
|
2025-09-24 17:46:03 +00:00
|
|
|
|
} 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) => {
|
2025-09-24 17:46:03 +00:00
|
|
|
|
const groupItems = e.component.option('items') as any[]
|
|
|
|
|
|
const firstItem = groupItems?.[0]?.items?.[0]
|
2025-09-19 14:06:48 +00:00
|
|
|
|
|
2025-09-24 17:46:03 +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
|
2025-09-24 17:46:03 +00:00
|
|
|
|
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 }),
|
2025-11-18 13:02:01 +00:00
|
|
|
|
...(formItem.editorType === 'dxDateBox' ? {
|
|
|
|
|
|
useMaskBehavior: true,
|
|
|
|
|
|
openOnFieldClick: true,
|
|
|
|
|
|
showClearButton: true,
|
|
|
|
|
|
} : {}),
|
2025-09-24 17:46:03 +00:00
|
|
|
|
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,
|
2025-09-24 17:46:03 +00:00
|
|
|
|
fieldName: formItem.dataField,
|
2025-09-29 07:08:24 +00:00
|
|
|
|
mode,
|
2025-09-24 17:46:03 +00:00
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return btn
|
|
|
|
|
|
}),
|
2025-05-06 06:45:49 +00:00
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)
|
|
|
|
|
|
})}
|
|
|
|
|
|
</GroupItemDx>
|
|
|
|
|
|
)
|
|
|
|
|
|
})}
|
|
|
|
|
|
</FormDx>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default FormDevExpress
|