206 lines
6.1 KiB
TypeScript
206 lines
6.1 KiB
TypeScript
import { Loading } from '@/components/shared'
|
||
import { lazy, useEffect, useMemo, useRef, useState } from 'react'
|
||
import { useParams, useSearchParams } from 'react-router-dom'
|
||
import type { DataType } from 'devextreme/common'
|
||
import type { SimpleItem } from 'devextreme/ui/form'
|
||
import FormButtons from './FormButtons'
|
||
import { FormProps } from './types'
|
||
import { useGridData } from './useFormData'
|
||
import { getList } from '@/services/form.service'
|
||
import { applyNewRowDefaults, castValueByDataType } from '../list/shared/editingForm'
|
||
import { FormPageShell } from './shared/FormPageShell'
|
||
|
||
const FormView = lazy(() => import('./FormView'))
|
||
|
||
export const FormNewContent = (props: FormProps = { isSubForm: false }) => {
|
||
const mode = 'new'
|
||
const { isSubForm, level, sParams, onActionView } = props
|
||
const params = useParams()
|
||
const listFormCode = props?.listFormCode ?? params?.listFormCode ?? ''
|
||
const [searchParams] = useSearchParams()
|
||
const initializedListFormCodeRef = useRef<string | undefined>(undefined)
|
||
|
||
const {
|
||
setFormData,
|
||
loading,
|
||
handleSubmit,
|
||
gridDto,
|
||
dataSource,
|
||
commandColumnData,
|
||
formData,
|
||
formItems,
|
||
refForm,
|
||
permissionResults,
|
||
} = useGridData({
|
||
mode,
|
||
listFormCode,
|
||
level,
|
||
isSubForm,
|
||
onSubmitAction: onActionView,
|
||
})
|
||
|
||
// URL parametreleri + üst formdan gelen parametreler.
|
||
const newParams = useMemo(
|
||
() =>
|
||
new URLSearchParams({
|
||
...Object.fromEntries(searchParams),
|
||
...Object.fromEntries(sParams ?? []),
|
||
}),
|
||
[searchParams, sParams],
|
||
)
|
||
|
||
useEffect(() => {
|
||
initializedListFormCodeRef.current = undefined
|
||
}, [listFormCode])
|
||
|
||
/** Form ilk açıldığında varsayılan değerleri kurar. */
|
||
useEffect(() => {
|
||
if (!formItems?.length || !gridDto?.columnFormats) return
|
||
if (initializedListFormCodeRef.current === listFormCode) return
|
||
|
||
initializedListFormCodeRef.current = listFormCode
|
||
let isActive = true
|
||
|
||
// 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
|
||
}),
|
||
)
|
||
|
||
applyNewRowDefaults(gridDto, initialData).then((data) => {
|
||
if (isActive) setFormData(data)
|
||
})
|
||
|
||
return () => {
|
||
isActive = false
|
||
}
|
||
}, [listFormCode, formItems?.length, gridDto?.columnFormats])
|
||
|
||
/** URL parametrelerinden gelen alanları forma yazar. */
|
||
useEffect(() => {
|
||
if (!formItems?.length || !formData || !gridDto?.columnFormats) return
|
||
|
||
const updatedData = { ...formData }
|
||
let hasChanges = false
|
||
|
||
for (const colFormat of gridDto.columnFormats) {
|
||
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
|
||
hasChanges = true
|
||
}
|
||
}
|
||
|
||
if (hasChanges) setFormData(updatedData)
|
||
}, [newParams, formData, gridDto?.columnFormats])
|
||
|
||
/** URL'den gelen alanlar kullanıcı tarafından değiştirilemez. */
|
||
useEffect(() => {
|
||
if (!formItems?.length || !gridDto?.columnFormats) return
|
||
|
||
const lockedFields = new Set(
|
||
gridDto.columnFormats
|
||
.map((colFormat) => colFormat.fieldName)
|
||
.filter((fieldName): fieldName is string => !!fieldName && newParams.has(fieldName)),
|
||
)
|
||
if (!lockedFields.size) return
|
||
|
||
formItems.forEach((group) =>
|
||
(group.items as SimpleItem[] | undefined)?.forEach((item) => {
|
||
if (item.dataField && lockedFields.has(item.dataField)) {
|
||
item.editorOptions = { ...item.editorOptions, readOnly: true }
|
||
}
|
||
}),
|
||
)
|
||
}, [formItems, newParams, gridDto?.columnFormats])
|
||
|
||
return (
|
||
<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 && (
|
||
<FormButtons
|
||
isSubForm={isSubForm}
|
||
mode={mode}
|
||
listFormCode={listFormCode}
|
||
id={formData?.Id}
|
||
gridDto={gridDto!}
|
||
commandColumnData={commandColumnData!}
|
||
dataSource={dataSource!}
|
||
permissions={permissionResults}
|
||
handleSubmit={handleSubmit}
|
||
refreshData={() => {}}
|
||
getSelectedRowKeys={() => []}
|
||
getSelectedRowsData={() => [formData]}
|
||
getFilter={() => []}
|
||
onActionView={onActionView}
|
||
/>
|
||
)
|
||
}
|
||
/>
|
||
)
|
||
}
|
||
|
||
/**
|
||
* `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 }) => {
|
||
const params = useParams()
|
||
const listFormCode = props.listFormCode ?? params.listFormCode ?? ''
|
||
const [listFormType, setListFormType] = useState<string>()
|
||
const [loading, setLoading] = useState(true)
|
||
|
||
useEffect(() => {
|
||
if (!listFormCode || props.isSubForm) {
|
||
setLoading(false)
|
||
return
|
||
}
|
||
|
||
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)
|
||
})
|
||
|
||
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} />
|
||
}
|
||
|
||
export default FormNew
|