sozsoft-platform/ui/src/views/form/FormNew.tsx

216 lines
6.3 KiB
TypeScript
Raw Normal View History

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'
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'))
export const FormNewContent = (props: FormProps = { isSubForm: false }) => {
2026-02-24 20:44:16 +00:00
const mode = 'new'
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()
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,
fieldOrder,
previewFieldOrder,
saveFieldOrder,
canStoreFieldOrder,
2026-02-24 20:44:16 +00:00
} = useGridData({
mode,
listFormCode,
level,
isSubForm,
onSubmitAction: onActionView,
2026-02-24 20:44:16 +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 ?? []),
}),
[searchParams, sParams],
)
2026-02-24 20:44:16 +00:00
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])
2026-02-24 20:44:16 +00:00
/** URL parametrelerinden gelen alanları forma yazar. */
2026-02-24 20:44:16 +00:00
useEffect(() => {
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) {
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
}
}
if (hasChanges) setFormData(updatedData)
}, [newParams, formData, gridDto?.columnFormats])
2026-02-24 20:44:16 +00:00
/** URL'den gelen alanlar kullanıcı tarafından değiştirilemez. */
2026-02-24 20:44:16 +00:00
useEffect(() => {
if (!formItems?.length || !gridDto?.columnFormats) return
2026-02-24 20:44:16 +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
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])
2026-02-24 20:44:16 +00:00
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 && (
2026-02-24 20:44:16 +00:00
<FormButtons
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={() => []}
onActionView={onActionView}
2026-02-24 20:44:16 +00:00
/>
)
}
/>
2026-02-24 20:44:16 +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(() => {
if (!listFormCode || props.isSubForm) {
2026-07-14 20:25:04 +00:00
setLoading(false)
return
2026-07-14 20:25:04 +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