2025-11-28 13:31:53 +00:00
|
|
|
|
import { DataGridRef } from 'devextreme-react/data-grid'
|
|
|
|
|
|
import { PivotGridRef } from 'devextreme-react/pivot-grid'
|
2025-05-06 06:45:49 +00:00
|
|
|
|
import CustomStore from 'devextreme/data/custom_store'
|
2025-09-27 20:25:21 +00:00
|
|
|
|
import { MutableRefObject, useCallback } from 'react'
|
2025-11-08 20:22:50 +00:00
|
|
|
|
import { layoutTypes, ListViewLayoutType } from '@/views/admin/listForm/edit/types'
|
2025-11-09 10:30:15 +00:00
|
|
|
|
import { getLoadOptions, getServiceAddress, setGridPanelColor } from './Utils'
|
|
|
|
|
|
import { GridOptionsDto } from '@/proxy/form/models'
|
|
|
|
|
|
import { GridColumnData } from './GridColumnData'
|
|
|
|
|
|
import { dynamicFetch } from '@/services/form.service'
|
|
|
|
|
|
import { MULTIVALUE_DELIMITER } from '@/constants/app.constant'
|
2025-11-28 13:31:53 +00:00
|
|
|
|
import { TreeListRef } from 'devextreme-react/cjs/tree-list'
|
2025-05-06 06:45:49 +00:00
|
|
|
|
|
|
|
|
|
|
const filteredGridPanelColor = 'rgba(10, 200, 10, 0.5)' // kullanici tanimli filtre ile filtrelenmis gridin paneline ait renk
|
|
|
|
|
|
|
|
|
|
|
|
const useListFormCustomDataSource = ({
|
|
|
|
|
|
gridRef,
|
|
|
|
|
|
}: {
|
2025-11-07 23:00:51 +00:00
|
|
|
|
gridRef:
|
2025-11-28 13:31:53 +00:00
|
|
|
|
| MutableRefObject<DataGridRef<any, any> | undefined>
|
|
|
|
|
|
| MutableRefObject<PivotGridRef | undefined>
|
|
|
|
|
|
| MutableRefObject<TreeListRef<any, any> | undefined>
|
2025-05-06 06:45:49 +00:00
|
|
|
|
}) => {
|
|
|
|
|
|
const createSelectDataSource = useCallback(
|
|
|
|
|
|
(
|
|
|
|
|
|
gridOptions: GridOptionsDto,
|
|
|
|
|
|
listFormCode: string,
|
|
|
|
|
|
searchParams?: URLSearchParams,
|
2025-11-08 20:22:50 +00:00
|
|
|
|
layout?: ListViewLayoutType | string,
|
2025-11-11 11:50:54 +00:00
|
|
|
|
cols?: GridColumnData[],
|
2025-05-06 06:45:49 +00:00
|
|
|
|
) => {
|
2025-09-19 13:30:19 +00:00
|
|
|
|
const store: any = new CustomStore({
|
2025-11-08 20:22:50 +00:00
|
|
|
|
key:
|
|
|
|
|
|
layout === layoutTypes.tree
|
|
|
|
|
|
? gridOptions.treeOptionDto?.keyExpr
|
|
|
|
|
|
: gridOptions.keyFieldName,
|
2025-05-06 06:45:49 +00:00
|
|
|
|
useDefaultSearch: true,
|
|
|
|
|
|
load: async (loadOptions) => {
|
|
|
|
|
|
const parameters = getLoadOptions(loadOptions, {
|
|
|
|
|
|
listFormCode,
|
2025-09-17 14:13:48 +00:00
|
|
|
|
filter: '',
|
2025-05-06 06:45:49 +00:00
|
|
|
|
createDeleteQuery: searchParams?.get('createDeleteQuery'),
|
2025-11-08 20:22:50 +00:00
|
|
|
|
chart: layout === layoutTypes.chart,
|
2025-05-06 06:45:49 +00:00
|
|
|
|
})
|
2025-09-17 14:13:48 +00:00
|
|
|
|
// 1. Default filter'ı al
|
|
|
|
|
|
const defaultFilter = searchParams?.get('filter')
|
|
|
|
|
|
? JSON.parse(searchParams.get('filter')!)
|
|
|
|
|
|
: null
|
|
|
|
|
|
|
|
|
|
|
|
let combinedFilter: any = parameters.filter
|
|
|
|
|
|
|
|
|
|
|
|
// 2. Eğer hem default hem de grid filter varsa merge et
|
|
|
|
|
|
if (defaultFilter && combinedFilter) {
|
|
|
|
|
|
combinedFilter = [defaultFilter, 'and', combinedFilter]
|
|
|
|
|
|
} else if (defaultFilter) {
|
|
|
|
|
|
combinedFilter = defaultFilter
|
|
|
|
|
|
}
|
2025-05-06 06:45:49 +00:00
|
|
|
|
//editing asamasinda her bir field de yapilan degisiklik load istegi olarak buraya dusuyor.
|
|
|
|
|
|
//TODO: bu bug halen devam ediyor!!
|
|
|
|
|
|
//Bunu engellemek icin eklendi.
|
|
|
|
|
|
//if (!params.hasOwnProperty('requireTotalCount')) {
|
|
|
|
|
|
// return;
|
|
|
|
|
|
//}
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (gridRef?.current) {
|
|
|
|
|
|
//TODO:
|
|
|
|
|
|
}
|
2025-11-07 23:00:51 +00:00
|
|
|
|
// Type guard to handle union type for gridRef
|
|
|
|
|
|
let columns = cols
|
2025-11-28 13:31:53 +00:00
|
|
|
|
if (gridRef?.current?.instance()) {
|
|
|
|
|
|
const instance = gridRef?.current?.instance() as any
|
2025-11-07 23:00:51 +00:00
|
|
|
|
const instanceColumns = instance.option('columns')
|
|
|
|
|
|
if (instanceColumns) {
|
|
|
|
|
|
columns = instanceColumns as GridColumnData[]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-05-06 06:45:49 +00:00
|
|
|
|
// URL'deki filtreyi grid'in mevcut filtrelerinin üzerine uygula
|
|
|
|
|
|
if (columns?.length && searchParams) {
|
|
|
|
|
|
const filters: (string[] | string)[] = []
|
|
|
|
|
|
for (const col of columns) {
|
|
|
|
|
|
if (col.dataField) {
|
|
|
|
|
|
const sValue = searchParams.get(col.dataField)
|
|
|
|
|
|
if (sValue) {
|
|
|
|
|
|
filters.push([col.dataField, '=', sValue])
|
|
|
|
|
|
filters.push('and')
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (filters.length) {
|
|
|
|
|
|
filters.pop() // son and'i sil
|
|
|
|
|
|
if (parameters.filter) {
|
|
|
|
|
|
parameters.filter = [...parameters.filter, 'and', ...filters]
|
|
|
|
|
|
} else {
|
|
|
|
|
|
parameters.filter = filters
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-19 13:30:19 +00:00
|
|
|
|
|
2025-09-18 22:09:58 +00:00
|
|
|
|
if (combinedFilter && combinedFilter.length > 0) {
|
|
|
|
|
|
parameters.filter = JSON.stringify(combinedFilter)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
delete parameters.filter // hiç göndermesin
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-17 14:13:48 +00:00
|
|
|
|
//parameters.filter = JSON.stringify(parameters.filter)
|
2025-05-06 06:45:49 +00:00
|
|
|
|
const response = await dynamicFetch('list-form-select/select', 'GET', parameters)
|
|
|
|
|
|
|
|
|
|
|
|
// Column format multiValue ise, gelen stringi array yapmaliyiz
|
|
|
|
|
|
if (columns) {
|
|
|
|
|
|
columns.forEach((col: any) => {
|
|
|
|
|
|
// Column multiValue mu?
|
|
|
|
|
|
if (col.extras?.multiValue) {
|
|
|
|
|
|
//console.log('MultiValue:', col.dataField, col.extras?.multiValue)
|
|
|
|
|
|
// Multivalue column icin header filter acildiginda gonderilen group querysi sonuclari
|
|
|
|
|
|
// "key" field ile geliyor, bunu array yapmamiz lazim, bu group query'nin,
|
|
|
|
|
|
// bu field icin olup olmadigini anlayabiliriz
|
|
|
|
|
|
const isGroupQuery = parameters?.group?.includes(col.dataField)
|
|
|
|
|
|
response.data.data?.forEach((row: any) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (row[col.dataField]) {
|
|
|
|
|
|
// value'yu arraye cevir
|
|
|
|
|
|
row[col.dataField] = row[col.dataField]?.split(MULTIVALUE_DELIMITER)
|
|
|
|
|
|
}
|
|
|
|
|
|
if (isGroupQuery && row.key) {
|
|
|
|
|
|
// group query sonucunda gelen key'i arraye cevir
|
|
|
|
|
|
row.key = row.key.split(MULTIVALUE_DELIMITER)
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
// toast.push(
|
|
|
|
|
|
// <Notification type="danger" duration={2000}>
|
|
|
|
|
|
// {'multiValue Error'}
|
|
|
|
|
|
// </Notification>,
|
|
|
|
|
|
// {
|
2025-09-01 14:07:03 +00:00
|
|
|
|
// placement: 'top-end',
|
2025-05-06 06:45:49 +00:00
|
|
|
|
// },
|
|
|
|
|
|
// )
|
|
|
|
|
|
console.log('multiValue Error', e)
|
|
|
|
|
|
// JSON parse sirasinde hata olursa data gosterimi devam etsin
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
//TODO: Bu neden var? Eğer gerekli değilse kaldırılabilir.
|
|
|
|
|
|
searchParams?.set('createDeleteQuery', 'false')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// gride filtre uygulanmis ise renklendir
|
|
|
|
|
|
setGridPanelColor(
|
|
|
|
|
|
response.data.queryInfos?.isAppliedGridFilter
|
|
|
|
|
|
? filteredGridPanelColor
|
|
|
|
|
|
: 'transparent',
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
const retValue = {
|
|
|
|
|
|
data: response.data.data,
|
|
|
|
|
|
totalCount: response.data.totalCount,
|
|
|
|
|
|
summary: response.data.summary,
|
|
|
|
|
|
groupCount: response.data.groupCount,
|
|
|
|
|
|
}
|
2025-11-28 13:31:53 +00:00
|
|
|
|
|
2025-05-06 06:45:49 +00:00
|
|
|
|
return retValue
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
// toast.push(
|
|
|
|
|
|
// <Notification type="danger" duration={2000}>
|
|
|
|
|
|
// Select error
|
|
|
|
|
|
// {error.toString()}
|
|
|
|
|
|
// </Notification>,
|
|
|
|
|
|
// {
|
2025-09-01 14:07:03 +00:00
|
|
|
|
// placement: 'top-end',
|
2025-05-06 06:45:49 +00:00
|
|
|
|
// },
|
|
|
|
|
|
// )
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
totalCount: async (loadOptions) => {
|
|
|
|
|
|
const parameters = getLoadOptions(loadOptions, {
|
|
|
|
|
|
listFormCode,
|
2025-09-17 14:13:48 +00:00
|
|
|
|
filter: '',
|
2025-05-06 06:45:49 +00:00
|
|
|
|
createDeleteQuery: searchParams?.get('createDeleteQuery'),
|
|
|
|
|
|
group: '',
|
|
|
|
|
|
})
|
2025-09-17 14:13:48 +00:00
|
|
|
|
|
2025-09-18 22:09:58 +00:00
|
|
|
|
// 1. Default filter'ı al
|
2025-09-17 14:13:48 +00:00
|
|
|
|
const defaultFilter = searchParams?.get('filter')
|
|
|
|
|
|
? JSON.parse(searchParams.get('filter')!)
|
|
|
|
|
|
: null
|
|
|
|
|
|
|
|
|
|
|
|
let combinedFilter: any = parameters.filter
|
2025-09-18 22:09:58 +00:00
|
|
|
|
|
|
|
|
|
|
// 2. Eğer hem default hem de grid filter varsa merge et
|
2025-09-17 14:13:48 +00:00
|
|
|
|
if (defaultFilter && combinedFilter) {
|
|
|
|
|
|
combinedFilter = [defaultFilter, 'and', combinedFilter]
|
|
|
|
|
|
} else if (defaultFilter) {
|
|
|
|
|
|
combinedFilter = defaultFilter
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-18 22:09:58 +00:00
|
|
|
|
if (combinedFilter && combinedFilter.length > 0) {
|
2025-09-19 13:30:19 +00:00
|
|
|
|
parameters.filter = JSON.stringify(combinedFilter)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
delete parameters.filter // hiç göndermesin
|
|
|
|
|
|
}
|
2025-09-17 14:13:48 +00:00
|
|
|
|
|
2025-05-06 06:45:49 +00:00
|
|
|
|
try {
|
|
|
|
|
|
const response = await dynamicFetch('list-form-select/select', 'GET', parameters)
|
|
|
|
|
|
return response.data.totalCount
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
// toast.push(
|
|
|
|
|
|
// <Notification type="danger" duration={2000}>
|
|
|
|
|
|
// TotalCount error
|
|
|
|
|
|
// {error.toString()}
|
|
|
|
|
|
// </Notification>,
|
|
|
|
|
|
// {
|
2025-09-01 14:07:03 +00:00
|
|
|
|
// placement: 'top-end',
|
2025-05-06 06:45:49 +00:00
|
|
|
|
// },
|
|
|
|
|
|
// )
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-09-19 13:30:19 +00:00
|
|
|
|
byKey: async (key) => {
|
|
|
|
|
|
const parameters = getLoadOptions(
|
|
|
|
|
|
{ key },
|
|
|
|
|
|
{ listFormCode, filter: '', createDeleteQuery: '' },
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
parameters.filter = JSON.stringify(parameters.filter)
|
|
|
|
|
|
try {
|
|
|
|
|
|
const response = await dynamicFetch('list-form-select/select', 'GET', parameters)
|
|
|
|
|
|
return response.data.data[0]
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
// toast.push(
|
|
|
|
|
|
// <Notification type="danger" duration={2000}>
|
|
|
|
|
|
// ByKey error
|
|
|
|
|
|
// {error.toString()}
|
|
|
|
|
|
// </Notification>,
|
|
|
|
|
|
// {
|
|
|
|
|
|
// placement: 'top-end',
|
|
|
|
|
|
// },
|
|
|
|
|
|
// )
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-05-06 06:45:49 +00:00
|
|
|
|
remove: function (key) {
|
|
|
|
|
|
if (!gridOptions.deleteServiceAddress) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const deleteUrl = getServiceAddress(gridOptions.deleteServiceAddress)
|
|
|
|
|
|
|
|
|
|
|
|
return dynamicFetch(deleteUrl, 'POST', searchParams, {
|
|
|
|
|
|
keys: [key],
|
|
|
|
|
|
listFormCode,
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
update: function (key, values) {
|
|
|
|
|
|
if (!gridOptions.updateServiceAddress) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
const updateUrl = getServiceAddress(gridOptions.updateServiceAddress)
|
|
|
|
|
|
|
|
|
|
|
|
return dynamicFetch(updateUrl, 'POST', searchParams, {
|
|
|
|
|
|
keys: [key],
|
|
|
|
|
|
data: values,
|
|
|
|
|
|
listFormCode,
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
insert: function (values) {
|
|
|
|
|
|
if (!gridOptions.insertServiceAddress) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
const insertUrl = getServiceAddress(gridOptions.insertServiceAddress)
|
|
|
|
|
|
|
|
|
|
|
|
return dynamicFetch(insertUrl, 'POST', searchParams, { data: values, listFormCode })
|
|
|
|
|
|
},
|
|
|
|
|
|
errorHandler: (error: any) => {
|
|
|
|
|
|
console.log(error.message)
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
2025-09-19 13:30:19 +00:00
|
|
|
|
|
|
|
|
|
|
return store
|
2025-05-06 06:45:49 +00:00
|
|
|
|
},
|
|
|
|
|
|
[],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
createSelectDataSource,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export { useListFormCustomDataSource }
|