2026-08-06 22:54:50 +00:00
|
|
|
|
import { Loading } from '@/components/shared'
|
|
|
|
|
|
import { lazy, useEffect, useMemo, useRef, useState } from 'react'
|
|
|
|
|
|
import { useParams, useSearchParams } from 'react-router-dom'
|
2026-07-13 08:39:13 +00:00
|
|
|
|
import type { DataType } from 'devextreme/common'
|
|
|
|
|
|
import type { SimpleItem } from 'devextreme/ui/form'
|
2026-02-24 20:44:16 +00:00
|
|
|
|
import FormButtons from './FormButtons'
|
|
|
|
|
|
import { FormProps } from './types'
|
|
|
|
|
|
import { useGridData } from './useFormData'
|
2026-08-06 22:54:50 +00:00
|
|
|
|
import { getList } from '@/services/form.service'
|
|
|
|
|
|
import { applyNewRowDefaults, castValueByDataType } from '../list/shared/editingForm'
|
|
|
|
|
|
import { FormPageShell } from './shared/FormPageShell'
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
2026-07-14 20:25:04 +00:00
|
|
|
|
const FormView = lazy(() => import('./FormView'))
|
|
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
export const FormNewContent = (props: FormProps = { isSubForm: false }) => {
|
2026-02-24 20:44:16 +00:00
|
|
|
|
const mode = 'new'
|
2026-08-06 22:54:50 +00:00
|
|
|
|
const { isSubForm, level, sParams, onActionView } = props
|
2026-02-24 20:44:16 +00:00
|
|
|
|
const params = useParams()
|
|
|
|
|
|
const listFormCode = props?.listFormCode ?? params?.listFormCode ?? ''
|
|
|
|
|
|
const [searchParams] = useSearchParams()
|
2026-08-13 08:41:48 +00:00
|
|
|
|
const initializedListFormCodeRef = useRef<string | undefined>(undefined)
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
|
setFormData,
|
|
|
|
|
|
loading,
|
|
|
|
|
|
handleSubmit,
|
|
|
|
|
|
gridDto,
|
|
|
|
|
|
dataSource,
|
|
|
|
|
|
commandColumnData,
|
|
|
|
|
|
formData,
|
|
|
|
|
|
formItems,
|
|
|
|
|
|
refForm,
|
|
|
|
|
|
permissionResults,
|
2026-10-06 07:19:26 +00:00
|
|
|
|
fieldOrder,
|
|
|
|
|
|
previewFieldOrder,
|
|
|
|
|
|
saveFieldOrder,
|
|
|
|
|
|
canStoreFieldOrder,
|
2026-02-24 20:44:16 +00:00
|
|
|
|
} = useGridData({
|
|
|
|
|
|
mode,
|
|
|
|
|
|
listFormCode,
|
|
|
|
|
|
level,
|
|
|
|
|
|
isSubForm,
|
2026-08-06 22:54:50 +00:00
|
|
|
|
onSubmitAction: onActionView,
|
2026-02-24 20:44:16 +00:00
|
|
|
|
})
|
|
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
// URL parametreleri + üst formdan gelen parametreler.
|
|
|
|
|
|
const newParams = useMemo(
|
|
|
|
|
|
() =>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
new URLSearchParams({
|
|
|
|
|
|
...Object.fromEntries(searchParams),
|
|
|
|
|
|
...Object.fromEntries(sParams ?? []),
|
|
|
|
|
|
}),
|
2026-08-06 22:54:50 +00:00
|
|
|
|
[searchParams, sParams],
|
|
|
|
|
|
)
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2026-06-01 14:19:49 +00:00
|
|
|
|
initializedListFormCodeRef.current = undefined
|
|
|
|
|
|
}, [listFormCode])
|
|
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
/** Form ilk açıldığında varsayılan değerleri kurar. */
|
2026-06-01 14:19:49 +00:00
|
|
|
|
useEffect(() => {
|
2026-08-06 22:54:50 +00:00
|
|
|
|
if (!formItems?.length || !gridDto?.columnFormats) return
|
|
|
|
|
|
if (initializedListFormCodeRef.current === listFormCode) return
|
2026-06-01 14:19:49 +00:00
|
|
|
|
|
|
|
|
|
|
initializedListFormCodeRef.current = listFormCode
|
|
|
|
|
|
let isActive = true
|
|
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
// Tanımlı tüm alanlar önce boşaltılır, ardından kolon varsayılanları uygulanır.
|
|
|
|
|
|
const initialData: Record<string, any> = {}
|
|
|
|
|
|
formItems.forEach((group) =>
|
|
|
|
|
|
(group.items as SimpleItem[] | undefined)?.forEach((item) => {
|
|
|
|
|
|
if (item.dataField) initialData[item.dataField] = undefined
|
|
|
|
|
|
}),
|
|
|
|
|
|
)
|
2026-06-01 14:19:49 +00:00
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
applyNewRowDefaults(gridDto, initialData).then((data) => {
|
|
|
|
|
|
if (isActive) setFormData(data)
|
|
|
|
|
|
})
|
2026-06-01 14:19:49 +00:00
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
isActive = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [listFormCode, formItems?.length, gridDto?.columnFormats])
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
/** URL parametrelerinden gelen alanları forma yazar. */
|
2026-02-24 20:44:16 +00:00
|
|
|
|
useEffect(() => {
|
2026-08-06 22:54:50 +00:00
|
|
|
|
if (!formItems?.length || !formData || !gridDto?.columnFormats) return
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
|
|
const updatedData = { ...formData }
|
|
|
|
|
|
let hasChanges = false
|
|
|
|
|
|
|
|
|
|
|
|
for (const colFormat of gridDto.columnFormats) {
|
2026-08-06 22:54:50 +00:00
|
|
|
|
const fieldName = colFormat.fieldName
|
|
|
|
|
|
if (!fieldName || !newParams.has(fieldName)) continue
|
|
|
|
|
|
|
|
|
|
|
|
const nextValue = castValueByDataType(
|
|
|
|
|
|
newParams.get(fieldName),
|
|
|
|
|
|
colFormat.dataType as DataType,
|
|
|
|
|
|
)
|
|
|
|
|
|
if (updatedData[fieldName] !== nextValue) {
|
|
|
|
|
|
updatedData[fieldName] = nextValue
|
2026-02-24 20:44:16 +00:00
|
|
|
|
hasChanges = true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
if (hasChanges) setFormData(updatedData)
|
|
|
|
|
|
}, [newParams, formData, gridDto?.columnFormats])
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
/** URL'den gelen alanlar kullanıcı tarafından değiştirilemez. */
|
2026-02-24 20:44:16 +00:00
|
|
|
|
useEffect(() => {
|
2026-08-06 22:54:50 +00:00
|
|
|
|
if (!formItems?.length || !gridDto?.columnFormats) return
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
const lockedFields = new Set(
|
|
|
|
|
|
gridDto.columnFormats
|
|
|
|
|
|
.map((colFormat) => colFormat.fieldName)
|
|
|
|
|
|
.filter((fieldName): fieldName is string => !!fieldName && newParams.has(fieldName)),
|
|
|
|
|
|
)
|
|
|
|
|
|
if (!lockedFields.size) return
|
2026-06-01 14:19:49 +00:00
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
formItems.forEach((group) =>
|
|
|
|
|
|
(group.items as SimpleItem[] | undefined)?.forEach((item) => {
|
|
|
|
|
|
if (item.dataField && lockedFields.has(item.dataField)) {
|
|
|
|
|
|
item.editorOptions = { ...item.editorOptions, readOnly: true }
|
2026-06-01 14:19:49 +00:00
|
|
|
|
}
|
2026-08-06 22:54:50 +00:00
|
|
|
|
}),
|
|
|
|
|
|
)
|
|
|
|
|
|
}, [formItems, newParams, gridDto?.columnFormats])
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
|
|
return (
|
2026-08-06 22:54:50 +00:00
|
|
|
|
<FormPageShell
|
|
|
|
|
|
mode={mode}
|
|
|
|
|
|
listFormCode={listFormCode}
|
|
|
|
|
|
isSubForm={isSubForm}
|
|
|
|
|
|
level={level}
|
|
|
|
|
|
loading={loading}
|
|
|
|
|
|
gridDto={gridDto}
|
|
|
|
|
|
formData={formData}
|
|
|
|
|
|
formItems={formItems}
|
|
|
|
|
|
refForm={refForm}
|
|
|
|
|
|
setFormData={setFormData}
|
|
|
|
|
|
showSubForms={false}
|
|
|
|
|
|
actions={
|
|
|
|
|
|
permissionResults && (
|
2026-02-24 20:44:16 +00:00
|
|
|
|
<FormButtons
|
2026-10-06 07:19:26 +00:00
|
|
|
|
fieldOrder={
|
|
|
|
|
|
canStoreFieldOrder
|
|
|
|
|
|
? { value: fieldOrder, preview: previewFieldOrder, save: saveFieldOrder }
|
|
|
|
|
|
: undefined
|
|
|
|
|
|
}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
isSubForm={isSubForm}
|
|
|
|
|
|
mode={mode}
|
|
|
|
|
|
listFormCode={listFormCode}
|
|
|
|
|
|
id={formData?.Id}
|
|
|
|
|
|
gridDto={gridDto!}
|
|
|
|
|
|
commandColumnData={commandColumnData!}
|
|
|
|
|
|
dataSource={dataSource!}
|
|
|
|
|
|
permissions={permissionResults}
|
|
|
|
|
|
handleSubmit={handleSubmit}
|
|
|
|
|
|
refreshData={() => {}}
|
|
|
|
|
|
getSelectedRowKeys={() => []}
|
|
|
|
|
|
getSelectedRowsData={() => [formData]}
|
|
|
|
|
|
getFilter={() => []}
|
2026-08-06 22:54:50 +00:00
|
|
|
|
onActionView={onActionView}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
/>
|
2026-08-06 22:54:50 +00:00
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* `listFormType === 'Form'` olan liste formlarında "yeni kayıt" ekranı yerine
|
|
|
|
|
|
* doğrudan görüntüleme ekranı açılır (tekil kayıtlı formlar).
|
|
|
|
|
|
*/
|
|
|
|
|
|
const FormNew = (props: FormProps = { isSubForm: false }) => {
|
2026-07-14 20:25:04 +00:00
|
|
|
|
const params = useParams()
|
|
|
|
|
|
const listFormCode = props.listFormCode ?? params.listFormCode ?? ''
|
|
|
|
|
|
const [listFormType, setListFormType] = useState<string>()
|
|
|
|
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2026-08-06 22:54:50 +00:00
|
|
|
|
if (!listFormCode || props.isSubForm) {
|
2026-07-14 20:25:04 +00:00
|
|
|
|
setLoading(false)
|
2026-08-06 22:54:50 +00:00
|
|
|
|
return
|
2026-07-14 20:25:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-06 22:54:50 +00:00
|
|
|
|
let isActive = true
|
|
|
|
|
|
setLoading(true)
|
|
|
|
|
|
|
|
|
|
|
|
getList({ listFormCode })
|
|
|
|
|
|
.then((response: any) => {
|
|
|
|
|
|
if (isActive) setListFormType(response?.data?.gridOptions?.listFormType)
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch((error: unknown) => console.error('ListForm tipi alınamadı:', error))
|
|
|
|
|
|
.finally(() => {
|
|
|
|
|
|
if (isActive) setLoading(false)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-07-14 20:25:04 +00:00
|
|
|
|
return () => {
|
|
|
|
|
|
isActive = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [listFormCode, props.isSubForm])
|
|
|
|
|
|
|
|
|
|
|
|
if (loading) {
|
|
|
|
|
|
return <Loading loading type="default" />
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!props.isSubForm && listFormType === 'Form') {
|
|
|
|
|
|
return <FormView {...props} listFormCode={listFormCode} />
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return <FormNewContent {...props} listFormCode={listFormCode} />
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-24 20:44:16 +00:00
|
|
|
|
export default FormNew
|