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

347 lines
9.2 KiB
TypeScript
Raw Normal View History

2026-02-24 20:44:16 +00:00
import { Container, Loading } from '@/components/shared'
import { useLocalization } from '@/utils/hooks/useLocalization'
2026-07-13 08:39:13 +00:00
import type { DataType } from 'devextreme/common'
import type { SimpleItem } from 'devextreme/ui/form'
2026-07-14 20:25:04 +00:00
import { lazy, useEffect, useRef, useState } from 'react'
2026-02-24 20:44:16 +00:00
import { Helmet } from 'react-helmet'
2026-07-06 09:44:26 +00:00
import { useParams, useSearchParams } from 'react-router-dom'
2026-02-24 20:44:16 +00:00
import FormButtons from './FormButtons'
import FormDevExpress from './FormDevExpress'
import { FormProps } from './types'
import { useGridData } from './useFormData'
import { useCurrentMenuIcon } from '@/utils/hooks/useCurrentMenuIcon'
import { Badge } from '@/components/ui'
import { APP_NAME } from '@/constants/app.constant'
import { FieldCustomValueTypeEnum } from '@/proxy/form/models'
2026-07-14 20:25:04 +00:00
import { getList, getNextSequenceValue } from '@/services/form.service'
import { autoNumber } from '../list/Utils'
2026-02-24 20:44:16 +00:00
2026-07-14 20:25:04 +00:00
const FormView = lazy(() => import('./FormView'))
export const FormNewContent = (
2026-02-24 20:44:16 +00:00
props: FormProps = {
isSubForm: false,
},
) => {
const mode = 'new'
const { isSubForm, level, sParams } = props
const params = useParams()
const listFormCode = props?.listFormCode ?? params?.listFormCode ?? ''
const [searchParams] = useSearchParams()
const { translate } = useLocalization()
const MenuIcon = useCurrentMenuIcon('w-5 h-5')
const initializedListFormCodeRef = useRef<string>()
2026-02-24 20:44:16 +00:00
const {
setFormData,
loading,
handleSubmit,
gridDto,
dataSource,
commandColumnData,
formData,
formItems,
refForm,
permissionResults,
} = useGridData({
mode,
listFormCode,
level,
isSubForm,
onSubmitAction: (props?.onActionView),
})
const [newParams, setNewParams] = useState<URLSearchParams>(new URLSearchParams())
useEffect(() => {
setNewParams(
new URLSearchParams({
...Object.fromEntries(searchParams),
...Object.fromEntries(sParams ?? []),
}),
)
}, [searchParams, sParams])
useEffect(() => {
initializedListFormCodeRef.current = undefined
}, [listFormCode])
useEffect(() => {
if (!formItems?.length || !gridDto?.columnFormats) {
2026-02-24 20:44:16 +00:00
return
}
if (initializedListFormCodeRef.current === listFormCode) {
return
2026-02-24 20:44:16 +00:00
}
initializedListFormCodeRef.current = listFormCode
let isActive = true
const initializeFormData = async () => {
const initialFormData = await createInitialFormData()
if (isActive) {
setFormData(initialFormData)
}
}
initializeFormData()
return () => {
isActive = false
}
}, [listFormCode, formItems?.length, gridDto?.columnFormats])
2026-02-24 20:44:16 +00:00
// newParams değiştiğinde sadece newParams'tan gelen alanları güncelle
useEffect(() => {
if (!formItems || !formData || !gridDto?.columnFormats) {
return
}
const updatedData = { ...formData }
let hasChanges = false
for (const colFormat of gridDto.columnFormats) {
if (!colFormat.fieldName || !newParams.has(colFormat.fieldName)) {
continue
}
const dType = colFormat.dataType as DataType
let newValue: any
switch (dType) {
case 'date':
case 'datetime':
newValue = new Date(newParams.get(colFormat.fieldName)!)
break
case 'number':
newValue = Number(newParams.get(colFormat.fieldName))
break
case 'boolean':
if (newParams.get(colFormat.fieldName) === 'true') {
newValue = true
} else if (newParams.get(colFormat.fieldName) === 'false') {
newValue = false
}
break
case 'object':
try {
newValue = JSON.parse(newParams.get(colFormat.fieldName) as string)
2026-07-06 09:44:26 +00:00
} catch {
2026-02-24 20:44:16 +00:00
newValue = updatedData[colFormat.fieldName]
}
break
default:
newValue = newParams.get(colFormat.fieldName)
break
}
if (updatedData[colFormat.fieldName] !== newValue) {
updatedData[colFormat.fieldName] = newValue
hasChanges = true
}
}
if (hasChanges) {
setFormData(updatedData)
}
}, [newParams, gridDto?.columnFormats])
// newParams'tan gelen alanları readonly yap
useEffect(() => {
if (!formItems || !gridDto?.columnFormats || !newParams) {
return
}
for (const colFormat of gridDto.columnFormats) {
if (!colFormat.fieldName || !newParams.has(colFormat.fieldName)) {
continue
}
// Eğer URL'den değer geliyorsa, bu editörü readonly yapıyoruz
formItems.forEach((form) => {
form?.items?.forEach((item: SimpleItem) => {
if (item.dataField === colFormat.fieldName) {
item.editorOptions = { ...item.editorOptions, readOnly: true }
}
})
})
}
}, [formItems, newParams, gridDto?.columnFormats])
async function createInitialFormData() {
2026-02-24 20:44:16 +00:00
const data: any = {}
if (!formItems?.length) {
return data
}
// Default tüm alanlar undefined olsun
for (const formGroupItem of formItems) {
if (formGroupItem.items) {
//SimpleItem
for (const formItem of formGroupItem.items) {
const f = formItem as SimpleItem
data[f.dataField!] = undefined
}
}
}
if (!gridDto?.columnFormats) {
return data
}
// Grid'den gelen columnFormat'ları kullanarak default değerleri set et
2026-07-06 09:44:26 +00:00
for (const colFormat of gridDto?.columnFormats || []) {
2026-02-24 20:44:16 +00:00
if (!colFormat.fieldName) {
continue
}
if (colFormat.defaultValue !== null && colFormat.defaultValue !== undefined) {
if (
typeof colFormat.defaultValue === 'string' &&
colFormat.defaultValue === '@AUTONUMBER'
) {
data[colFormat.fieldName] = autoNumber()
continue
}
if (colFormat.defaultValueType === FieldCustomValueTypeEnum.Sequence) {
try {
const response = await getNextSequenceValue(String(colFormat.defaultValue))
data[colFormat.fieldName] = response.data
} catch (error) {
console.error('Sequence default value alınamadı:', {
fieldName: colFormat.fieldName,
defaultValue: colFormat.defaultValue,
error,
})
}
continue
}
2026-02-24 20:44:16 +00:00
data[colFormat.fieldName] = colFormat.defaultValue
}
}
return data
}
if (!listFormCode) {
return <></>
}
if (loading) {
return <Loading type="default" loading={loading}></Loading>
}
if (!formData) {
return <>{translate('::App.NoResults')}</>
}
return (
<Container>
{!isSubForm && (
<Helmet
titleTemplate={`%s | ${APP_NAME}`}
title={translate('::' + gridDto?.gridOptions.title)}
defaultTitle={APP_NAME}
></Helmet>
)}
<div
className={`flex items-center pb-2 px-2 ${isSubForm ? 'justify-end' : 'justify-between'}`}
>
<div className="flex items-center gap-2">
{MenuIcon}
{!isSubForm && (
<>
<h4 className="text-slate-700 text-sm font-medium leading-none">
{translate('::' + gridDto?.gridOptions?.title)}
</h4>
<Badge content={mode} />
</>
)}
</div>
{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={props?.onActionView}
/>
)}
</div>
<div className="px-2">
<FormDevExpress
mode={mode}
refForm={refForm}
formData={formData}
formItems={formItems}
setFormData={setFormData}
listFormCode={listFormCode}
/>
</div>
</Container>
)
}
2026-07-14 20:25:04 +00:00
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(() => {
let isActive = true
const resolveFormType = async () => {
setLoading(true)
try {
const response = await getList({ listFormCode })
if (isActive) {
setListFormType(response?.data?.gridOptions?.listFormType)
}
} finally {
if (isActive) {
setLoading(false)
}
}
}
if (listFormCode && !props.isSubForm) {
resolveFormType()
} else {
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} />
}
2026-02-24 20:44:16 +00:00
export default FormNew