import { Notification, toast } from '@/components/ui' import { getList } from '@/services/form.service' import { useListFormColumns } from '@/shared/useListFormColumns' import { useListFormCustomDataSource } from '@/shared/useListFormCustomDataSource' import { useLocalization } from '@/utils/hooks/useLocalization' import { usePermission } from '@/utils/hooks/usePermission' import { Form as FormDx } from 'devextreme-react/form' import { captionize } from 'devextreme/core/utils/inflector' import CustomStore from 'devextreme/data/custom_store' import { GroupItem } from 'devextreme/ui/form' import { useEffect, useRef, useState } from 'react' import { useNavigate, useSearchParams } from 'react-router-dom' import { GridColumnData } from '../list/GridColumnData' import { addCss, addJs } from '../list/Utils' import { PermissionResults, RowMode, SimpleItemWithColData } from './types' import { EditingFormItemDto, GridDto, PlatformEditorTypes } from '@/proxy/form/models' import { getAccessDeniedPath } from '@/utils/routing' const useGridData = (props: { mode: RowMode listFormCode: string id?: string level?: number isSubForm?: boolean onSubmitAction?: () => void }) => { const { mode, listFormCode, id, isSubForm } = props const [gridReady, setGridReady] = useState(false) const [loading, setLoading] = useState(false) const [filter, setFilter] = useState([]) const [gridDto, setGridDto] = useState() const [dataSource, setDataSource] = useState>() const [commandColumnData, setCommandColumnData] = useState() const [formDataOld, setFormDataOld] = useState() const [formData, setFormData] = useState() const [formItems, setFormItems] = useState([]) const [permissionResults, setPermissionResults] = useState() const refForm = useRef(null) const [searchParams] = useSearchParams() const navigate = useNavigate() const { translate } = useLocalization() const { checkPermission } = usePermission() const { getBandedColumns } = useListFormColumns({ gridDto, listFormCode, isSubForm, }) const { createSelectDataSource } = useListFormCustomDataSource({}) const fetchData = async () => { setLoading(true) try { const response: any = await dataSource?.load({ filter, skip: 0, take: 1, }) if (response?.data?.length) { setFormData(response.data[0]) setFormDataOld({ ...response.data[0] }) } else { setFormData(undefined) setFormDataOld(undefined) } } catch (error: any) { toast.push(, { placement: 'top-center', }) } finally { setLoading(false) } } const handleSubmit = async (e: any) => { e.preventDefault() if (!dataSource) { return } const validationResult = refForm.current?.instance.validate() if (!validationResult?.isValid) { return } setLoading(true) try { const formValues = { ...formData } if (mode === 'new') { const result = await dataSource.insert(formValues) if (result.data) { if (!isSubForm) { navigate(result.data) } else if (props.onSubmitAction) { props.onSubmitAction() } toast.push( {translate('::ListForms.FormBilgileriKaydedildi')} , { placement: 'top-center', }, ) } else { throw new Error(translate('::ListForms.FormBilgileriKaydedilemedi')) } } else if (mode === 'edit') { let data: any = {} if (gridDto?.gridOptions.editingOptionDto?.sendOnlyChangedFormValuesUpdate) { Object.keys(formValues).forEach((key) => { if (formValues[key] !== formDataOld[key]) { data[key] = formValues[key] } }) } else { data = { ...formValues } } if (gridDto?.gridOptions.keyFieldName) { delete data[gridDto?.gridOptions.keyFieldName] } var result = await dataSource.update(id, data) if (result.data > 0) { if (!isSubForm) { navigate(`/form/${listFormCode}/${id}`) } else if (props.onSubmitAction) { props.onSubmitAction() } toast.push( {translate('::ListForms.FormBilgileriKaydedildi')} , { placement: 'top-center', }, ) } else { throw new Error(translate('::ListForms.FormBilgileriKaydedilemedi')) } } } catch (error: any) { toast.push(, { placement: 'top-center', }) } finally { setLoading(false) } } useEffect(() => { setGridReady(false) const initializeGrid = async () => { const response = await getList({ listFormCode }) setGridDto(response.data) } initializeGrid() }, [listFormCode]) useEffect(() => { setGridReady(false) if (!gridDto) { return } setPermissionResults({ c: gridDto?.gridOptions.editingOptionDto.allowAdding === true && checkPermission(gridDto?.gridOptions.permissionDto.c), r: checkPermission(gridDto?.gridOptions.permissionDto.r), u: gridDto?.gridOptions.editingOptionDto.allowUpdating === true && checkPermission(gridDto?.gridOptions.permissionDto.u), d: gridDto?.gridOptions.editingOptionDto.allowDeleting === true && checkPermission(gridDto?.gridOptions.permissionDto.d), e: checkPermission(gridDto?.gridOptions.permissionDto.e), }) // Set js and css const grdOpt = gridDto.gridOptions grdOpt.customJsSources.forEach(addJs) grdOpt.customStyleSources.forEach(addCss) // Set columns const cols = getBandedColumns() setCommandColumnData(cols?.find((a) => a.type == 'buttons')) // Set data source const dataSource: CustomStore = createSelectDataSource( gridDto.gridOptions, listFormCode, searchParams, cols, ) setDataSource(dataSource) const items = gridDto?.gridOptions.editingFormDto ?.sort((a: any, b: any) => { return a.order >= b.order ? 1 : -1 }) .map((e: any) => { return { itemType: e.itemType, colCount: e.colCount, colSpan: e.colSpan, caption: e.caption, items: e.items ?.sort((a: any, b: any) => { return a.order >= b.order ? 1 : -1 }) .map((i: EditingFormItemDto) => { let editorOptions = {} try { editorOptions = i.editorOptions && JSON.parse(i.editorOptions) } catch {} const item: SimpleItemWithColData = { canRead: gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)?.canRead ?? false, canUpdate: gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)?.canUpdate ?? false, canCreate: gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)?.canCreate ?? false, canExport: gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)?.canExport ?? false, dataField: i.dataField, name: i.dataField, editorType2: i.editorType2, editorType: i.editorType2 == PlatformEditorTypes.dxGridBox ? 'dxDropDownBox' : i.editorType2, colSpan: i.colSpan, isRequired: i.isRequired, editorOptions, colData: cols?.find((x) => x.dataField === i.dataField), tagBoxOptions: i.tagBoxOptions, gridBoxOptions: i.gridBoxOptions, } if (i.dataField.indexOf(':') >= 0) { item.label = { text: captionize(i.dataField.split(':')[1]) } } if ((mode == 'edit' && !item.canUpdate) || (mode == 'new' && !item.canCreate)) { item.editorOptions = { ...item.editorOptions, readOnly: true, } } return item }) .filter((a: any) => { if (mode === 'view') { return a.canRead } else if (mode === 'new') { return a.canCreate || a.canRead } else if (mode === 'edit') { return a.canUpdate || a.canRead } else { return false } }), } as GroupItem }) setFormItems(items) setGridReady(true) }, [gridDto]) useEffect(() => { if (!gridReady) { return } if (mode !== 'new') { setFilter([gridDto?.gridOptions.keyFieldName ?? 'Id', '=', id]) } }, [id, gridReady]) useEffect(() => { if (filter?.length) { fetchData() } }, [filter]) // Auth check useEffect(() => { if (!permissionResults) return const noCreate = mode === 'new' && !permissionResults.c const noUpdate = mode === 'edit' && !permissionResults.u const noRead = mode === 'view' && !permissionResults.r if (noCreate || noUpdate || noRead) { navigate(getAccessDeniedPath(location.pathname), { replace: true, state: { from: location } }) } }, [permissionResults]) return { loading, gridDto, dataSource, commandColumnData, filter, formItems, formData, refForm, permissionResults, fetchData, setFormData, handleSubmit, } } export { useGridData }