Grid Performans çalışmaları

This commit is contained in:
Sedat Öztürk 2026-02-04 00:30:51 +03:00
parent 0a5df92812
commit ff3344b3ae
4 changed files with 89 additions and 78 deletions

View file

@ -15,6 +15,6 @@ public class StateStoringDto
/// <summary> Bir kullanıcının bir değişiklik yapması ile bu değişikliğin kaydedilmesi arasındaki gecikmeyi milisaniye cinsinden belirtir. /// <summary> Bir kullanıcının bir değişiklik yapması ile bu değişikliğin kaydedilmesi arasındaki gecikmeyi milisaniye cinsinden belirtir.
/// </summary> /// </summary>
[Range(1500, 5000)] [Range(1500, 5000)]
public int SavingTimeout { get; set; } = 2000; public int SavingTimeout { get; set; } = 5000;
} }

View file

@ -553,6 +553,11 @@ const Grid = (props: GridProps) => {
[gridDto, cascadeFieldsMap], [gridDto, cascadeFieldsMap],
) )
// StateStoring için storageKey'i memoize et
const storageKey = useMemo(() => {
return gridDto?.gridOptions.stateStoringDto?.storageKey ?? ''
}, [gridDto?.gridOptions.stateStoringDto?.storageKey])
const customSaveState = useCallback( const customSaveState = useCallback(
(state: any) => { (state: any) => {
if (isEditingRef.current) { if (isEditingRef.current) {
@ -561,27 +566,29 @@ const Grid = (props: GridProps) => {
return postListFormCustomization({ return postListFormCustomization({
listFormCode: listFormCode, listFormCode: listFormCode,
customizationType: ListFormCustomizationTypeEnum.GridState, customizationType: ListFormCustomizationTypeEnum.GridState,
filterName: `list-${gridRef.current?.instance()?.option('stateStoring')?.storageKey ?? ''}`, filterName: `list-${storageKey}`,
customizationData: JSON.stringify(state), customizationData: JSON.stringify(state),
}).then(() => { }).then(() => {
setGridPanelColor(statedGridPanelColor) setGridPanelColor(statedGridPanelColor)
}) })
}, },
[listFormCode], [listFormCode, storageKey],
) )
const customLoadState = useCallback(() => { const customLoadState = useCallback(() => {
return getListFormCustomization( return getListFormCustomization(
listFormCode, listFormCode,
ListFormCustomizationTypeEnum.GridState, ListFormCustomizationTypeEnum.GridState,
`list-${gridRef.current?.instance()?.option('stateStoring')?.storageKey ?? ''}`, `list-${storageKey}`,
).then((response: any) => { ).then((response: any) => {
setGridPanelColor(statedGridPanelColor)
if (response.data?.length > 0) { if (response.data?.length > 0) {
setGridPanelColor(statedGridPanelColor)
return JSON.parse(response.data[0].customizationData) return JSON.parse(response.data[0].customizationData)
} }
// Veri yoksa null dön (DevExtreme bunu default state olarak algılar)
return null
}) })
}, [listFormCode]) }, [listFormCode, storageKey])
useEffect(() => { useEffect(() => {
if (gridRef?.current) { if (gridRef?.current) {
@ -778,12 +785,11 @@ const Grid = (props: GridProps) => {
const instance = gridRef?.current?.instance() const instance = gridRef?.current?.instance()
if (instance) { if (instance) {
instance.option('remoteOperations', { instance.option('remoteOperations', {
groupPaging: true, paging: true,
filtering: true, filtering: true,
sorting: true, sorting: true,
paging: true, grouping: false,
grouping: true, summary: false,
summary: true,
}) })
instance.option('dataSource', gridDataSource) instance.option('dataSource', gridDataSource)
} }
@ -824,9 +830,13 @@ const Grid = (props: GridProps) => {
stateStoring.customLoad = () => customLoadStateRef.current() stateStoring.customLoad = () => customLoadStateRef.current()
} }
instance.option('stateStoring', stateStoring) instance.option('stateStoring', stateStoring)
instance.state(null)
// State'i yükle - dataSource ve columns hazır olduğunda
if (gridDataSource && columnData) {
instance.state(undefined) // undefined = reload from storage
} }
}, [gridDto]) // Sadece gridDto'ya bağlı }
}, [gridDto, gridDataSource, columnData]) // dataSource ve columns hazır olduğunda state yükle
useEffect(() => { useEffect(() => {
refListFormCode.current = listFormCode refListFormCode.current = listFormCode
@ -1069,18 +1079,8 @@ const Grid = (props: GridProps) => {
<div className="p-1"> <div className="p-1">
<DataGrid <DataGrid
ref={gridRef as any} ref={gridRef as any}
key={`Grid-${listFormCode}-${gridDataSource ? 'loaded' : 'loading'}`} key={'Grid-' + listFormCode}
id={'Grid-' + listFormCode} id={'Grid-' + listFormCode}
// dataSource={gridDataSource}
// columns={columnData}
// remoteOperations={{
// groupPaging: true,
// filtering: true,
// sorting: true,
// paging: true,
// grouping: true,
// summary: true,
// }}
height={ height={
gridDto.gridOptions.height > 0 gridDto.gridOptions.height > 0
? gridDto.gridOptions.height ? gridDto.gridOptions.height
@ -1162,6 +1162,7 @@ const Grid = (props: GridProps) => {
} }
startEditAction={gridDto.gridOptions.editingOptionDto?.startEditAction} startEditAction={gridDto.gridOptions.editingOptionDto?.startEditAction}
popup={{ popup={{
deferRendering: true,
animation: {}, animation: {},
title: title:
(mode === 'new' ? '✚ ' : '🖊️ ') + (mode === 'new' ? '✚ ' : '🖊️ ') +

View file

@ -551,6 +551,11 @@ const Tree = (props: TreeProps) => {
} }
} }
// StateStoring için storageKey'i memoize et
const storageKey = useMemo(() => {
return gridDto?.gridOptions.stateStoringDto?.storageKey ?? ''
}, [gridDto?.gridOptions.stateStoringDto?.storageKey])
const customSaveState = useCallback( const customSaveState = useCallback(
(state: any) => { (state: any) => {
if (isEditingRef.current) { if (isEditingRef.current) {
@ -559,29 +564,29 @@ const Tree = (props: TreeProps) => {
return postListFormCustomization({ return postListFormCustomization({
listFormCode: listFormCode, listFormCode: listFormCode,
customizationType: ListFormCustomizationTypeEnum.GridState, customizationType: ListFormCustomizationTypeEnum.GridState,
filterName: `tree-${gridRef.current?.instance().option('stateStoring')?.storageKey ?? ''}`, filterName: `tree-${storageKey}`,
customizationData: JSON.stringify(state), customizationData: JSON.stringify(state),
}).then(() => { }).then(() => {
setGridPanelColor(statedGridPanelColor) setGridPanelColor(statedGridPanelColor)
}) })
}, },
[listFormCode], [listFormCode, storageKey],
) )
const customLoadState = useCallback( const customLoadState = useCallback(() => {
() => return getListFormCustomization(
getListFormCustomization(
listFormCode, listFormCode,
ListFormCustomizationTypeEnum.GridState, ListFormCustomizationTypeEnum.GridState,
`tree-${gridRef.current?.instance().option('stateStoring')?.storageKey ?? ''}`, `tree-${storageKey}`,
).then((response: any) => { ).then((response: any) => {
setGridPanelColor(statedGridPanelColor)
if (response.data?.length > 0) { if (response.data?.length > 0) {
setGridPanelColor(statedGridPanelColor)
return JSON.parse(response.data[0].customizationData) return JSON.parse(response.data[0].customizationData)
} }
}), // Veri yoksa null dön (DevExtreme bunu default state olarak algılar)
[listFormCode], return null
) })
}, [listFormCode, storageKey])
// StateStoring fonksiyonlarını ref'e kaydet - Grid'deki gibi // StateStoring fonksiyonlarını ref'e kaydet - Grid'deki gibi
const customSaveStateRef = useRef(customSaveState) const customSaveStateRef = useRef(customSaveState)
@ -754,7 +759,12 @@ const Tree = (props: TreeProps) => {
stateStoring.customLoad = () => customLoadStateRef.current() stateStoring.customLoad = () => customLoadStateRef.current()
} }
gridRef?.current?.instance().option('stateStoring', stateStoring) gridRef?.current?.instance().option('stateStoring', stateStoring)
}, [columnData])
// State'i yükle - dataSource ve columns hazır olduğunda
if (treeListDataSource && columnData) {
gridRef?.current?.instance().state(undefined) // undefined = reload from storage
}
}, [columnData, treeListDataSource, gridDto]) // dataSource ve columns hazır olduğunda state yükle
return ( return (
<> <>

View file

@ -275,50 +275,50 @@ const useListFormCustomDataSource = ({
return null return null
} }
}, },
totalCount: async (loadOptions) => { // totalCount: async (loadOptions) => {
const parameters = getLoadOptions(loadOptions, { // const parameters = getLoadOptions(loadOptions, {
listFormCode, // listFormCode,
filter: '', // filter: '',
createDeleteQuery: searchParams?.get('createDeleteQuery'), // createDeleteQuery: searchParams?.get('createDeleteQuery'),
group: '', // group: '',
}) // })
// 1. Default filter'ı al // // 1. Default filter'ı al
const defaultFilter = searchParams?.get('filter') // const defaultFilter = searchParams?.get('filter')
? JSON.parse(searchParams.get('filter')!) // ? JSON.parse(searchParams.get('filter')!)
: null // : null
let combinedFilter: any = parameters.filter // let combinedFilter: any = parameters.filter
// 2. Eğer hem default hem de grid filter varsa merge et // // 2. Eğer hem default hem de grid filter varsa merge et
if (defaultFilter && combinedFilter) { // if (defaultFilter && combinedFilter) {
combinedFilter = [defaultFilter, 'and', combinedFilter] // combinedFilter = [defaultFilter, 'and', combinedFilter]
} else if (defaultFilter) { // } else if (defaultFilter) {
combinedFilter = defaultFilter // combinedFilter = defaultFilter
} // }
if (combinedFilter && combinedFilter.length > 0) { // if (combinedFilter && combinedFilter.length > 0) {
parameters.filter = JSON.stringify(combinedFilter) // parameters.filter = JSON.stringify(combinedFilter)
} else { // } else {
delete parameters.filter // hiç göndermesin // delete parameters.filter // hiç göndermesin
} // }
try { // try {
const response = await dynamicFetch('list-form-select/select', 'GET', parameters) // const response = await dynamicFetch('list-form-select/select', 'GET', parameters)
return response.data.totalCount // return response.data.totalCount
} catch (error: any) { // } catch (error: any) {
// toast.push( // // toast.push(
// <Notification type="danger" duration={2000}> // // <Notification type="danger" duration={2000}>
// TotalCount error // // TotalCount error
// {error.toString()} // // {error.toString()}
// </Notification>, // // </Notification>,
// { // // {
// placement: 'top-end', // // placement: 'top-end',
// // },
// // )
// return null
// }
// }, // },
// )
return null
}
},
byKey: async (key) => { byKey: async (key) => {
const parameters = getLoadOptions( const parameters = getLoadOptions(
{ key }, { key },