CardView düzenlemeleri

This commit is contained in:
Sedat Öztürk 2026-01-19 03:00:17 +03:00
parent 8793292932
commit 138b49a7b0

View file

@ -79,22 +79,6 @@ interface CardViewProps {
const statedGridPanelColor = 'rgba(50, 200, 200, 0.5)' const statedGridPanelColor = 'rgba(50, 200, 200, 0.5)'
// Lookup cache (module scope)
const __lookupCache = new Map<string, Promise<any[]>>()
const cachedLoader = (key: string, loader: () => Promise<any[]>) => {
if (__lookupCache.has(key)) return __lookupCache.get(key)!
const p = Promise.resolve()
.then(() => loader())
.then((res) => res ?? [])
.catch((err) => {
__lookupCache.delete(key)
throw err
})
__lookupCache.set(key, p)
return p
}
const CardView = (props: CardViewProps) => { const CardView = (props: CardViewProps) => {
const { listFormCode, searchParams, isSubForm, gridDto: extGridDto, refreshGridDto } = props const { listFormCode, searchParams, isSubForm, gridDto: extGridDto, refreshGridDto } = props
const { translate } = useLocalization() const { translate } = useLocalization()
@ -138,11 +122,6 @@ const CardView = (props: CardViewProps) => {
} }
}, [searchParams]) }, [searchParams])
// Clear lookup cache when listFormCode changes
useEffect(() => {
__lookupCache.clear()
}, [listFormCode])
const layout = layoutTypes.cardView const layout = layoutTypes.cardView
const { createSelectDataSource } = useListFormCustomDataSource({ gridRef: cardViewRef as any }) const { createSelectDataSource } = useListFormCustomDataSource({ gridRef: cardViewRef as any })
@ -161,7 +140,7 @@ const CardView = (props: CardViewProps) => {
key, key,
loadMode: 'raw', loadMode: 'raw',
load: async () => { load: async () => {
return cachedLoader(`static:${key}`, () => Promise.resolve(load())) return Promise.resolve(load()).then((res) => res ?? [])
}, },
}), }),
paginate: false, paginate: false,
@ -178,21 +157,18 @@ const CardView = (props: CardViewProps) => {
loadMode: 'raw', loadMode: 'raw',
load: async () => { load: async () => {
try { try {
const cacheKey = `query:${listFormCode}:${listFormFieldName}:${JSON.stringify(filters ?? null)}` const response = await dynamicFetch('list-form-select/lookup', 'POST', null, {
return cachedLoader(cacheKey, async () => { listFormCode,
const response = await dynamicFetch('list-form-select/lookup', 'POST', null, { listFormFieldName,
listFormCode, filters,
listFormFieldName,
filters,
})
return (response.data ?? []).map((a: any) => ({
key: a.Key,
name: a.Name,
group: a.Group,
...a,
}))
}) })
return (response.data ?? []).map((a: any) => ({
key: a.Key,
name: a.Name,
group: a.Group,
...a,
}))
} catch (error: any) { } catch (error: any) {
return [] return []
} }
@ -227,19 +203,16 @@ const CardView = (props: CardViewProps) => {
} }
try { try {
const cacheKey = `api:${lookupQuery}:${JSON.stringify(filters ?? null)}` const response = await dynamicFetch(url, method, null, resolvedBody)
return cachedLoader(cacheKey, async () => { let { data } = response
const response = await dynamicFetch(url, method, null, resolvedBody) if (!data) return []
let { data } = response if (!Array.isArray(data)) data = [data]
if (!data) return [] return data.map((a: any) => ({
if (!Array.isArray(data)) data = [data] key: eval(keySelector),
return data.map((a: any) => ({ name: eval(nameSelector),
key: eval(keySelector), group: eval(groupSelector),
name: eval(nameSelector), ...a,
group: eval(groupSelector), }))
...a,
}))
})
} catch { } catch {
return [] return []
} }
@ -519,20 +492,6 @@ const CardView = (props: CardViewProps) => {
// Lookup desteği ekle - dataSourceType > 0 olmalı (0 = None) // Lookup desteği ekle - dataSourceType > 0 olmalı (0 = None)
if (colData.lookupDto?.dataSourceType && colData.lookupDto.dataSourceType > 0) { if (colData.lookupDto?.dataSourceType && colData.lookupDto.dataSourceType > 0) {
// Cache'den al veya oluştur
const cacheKey = `${colData.fieldName}`
let lookupDs = lookupDataSourcesRef.current.get(cacheKey)
if (!lookupDs) {
lookupDs = lookupDataSource(null, colData)
lookupDataSourcesRef.current.set(cacheKey, lookupDs)
}
// NOT: Lookup için CardView'da editorType ve editorOptions KULLANMA
// DevExpress bunları görünce otomatik lookup resolution yapıp çift görünmeye sebep oluyor
// Sadece fieldValueRender ile lookup gösterimi yapılacak
// Edit popup'ta form item için lookup ayarları yapılacak
// Lookup olduğunu işaretle (renderColumns'da kullanılacak) // Lookup olduğunu işaretle (renderColumns'da kullanılacak)
;(col as any).isLookup = true ;(col as any).isLookup = true
;(col as any).lookupInfo = { ;(col as any).lookupInfo = {
@ -619,6 +578,62 @@ const CardView = (props: CardViewProps) => {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [gridDto, config]) // getBandedColumns ve lookupDataSource çıkarıldı - sonsuz döngüyü önlemek için }, [gridDto, config]) // getBandedColumns ve lookupDataSource çıkarıldı - sonsuz döngüyü önlemek için
// Lookup DataSource'ları oluştur ve ref'e ekle
useEffect(() => {
if (!columnsWithLookup || columnsWithLookup.length === 0) return
if (!gridDto) return
lookupDataSourcesRef.current.clear()
columnsWithLookup.forEach((col) => {
const colData = gridDto.columnFormats.find((c) => c.fieldName === col.dataField)
if (!colData) return
if (colData.lookupDto?.dataSourceType && colData.lookupDto.dataSourceType > 0) {
const cacheKey = `${colData.fieldName}`
const lookupDs = lookupDataSource(null, colData)
lookupDataSourcesRef.current.set(cacheKey, lookupDs)
}
})
}, [columnsWithLookup, gridDto, lookupDataSource])
// Lookup DataSource'ları sayfa açılırken yükle
useEffect(() => {
if (!columnsWithLookup || columnsWithLookup.length === 0) return
if (lookupDataSourcesRef.current.size === 0) return
const loadLookups = async () => {
const lookupPromises: Array<Promise<{ key: string; items: any[] }>> = []
lookupDataSourcesRef.current.forEach((ds, key) => {
if (ds && ds.store && typeof ds.store().load === 'function') {
// DataSource'ın store'unun load metodunu direkt çağır
lookupPromises.push(
ds.store().load().then((items: any[]) => ({
key,
items: items || [],
})),
)
}
})
if (lookupPromises.length > 0) {
try {
const results = await Promise.all(lookupPromises)
setLookupItemsCache((prev) => {
const newCache = new Map(prev)
results.forEach(({ key, items }) => {
newCache.set(key, items)
})
return newCache
})
} catch (error) {
// Hata durumunda sessizce devam et
}
}
}
loadLookups()
}, [columnsWithLookup])
// DataSource oluştur - sadece gridDto ve listFormCode değiştiğinde (useMemo ile cache'le) // DataSource oluştur - sadece gridDto ve listFormCode değiştiğinde (useMemo ile cache'le)
const cardViewDataSource = useMemo(() => { const cardViewDataSource = useMemo(() => {
if (!gridDto) return null if (!gridDto) return null
@ -1128,42 +1143,6 @@ const CardView = (props: CardViewProps) => {
setPageSize(e.value) setPageSize(e.value)
} }
}} }}
onContentReady={() => {
// Lookup DataSource'ları yükle ve state'e cache'le (sadece ilk yüklemede)
if (lookupItemsCache.size === 0 && lookupDataSourcesRef.current.size > 0) {
const lookupPromises: Array<Promise<{ key: string; items: any[] }>> = []
lookupDataSourcesRef.current.forEach((ds, key) => {
if (ds && typeof ds.load === 'function') {
lookupPromises.push(
ds.load().then(() => ({
key,
items: ds.items() || [],
})),
)
}
})
if (lookupPromises.length > 0) {
Promise.all(lookupPromises)
.then((results) => {
const newCache = new Map<string, any[]>()
results.forEach(({ key, items }) => {
newCache.set(key, items)
})
setLookupItemsCache(newCache)
const instance = cardViewRef.current?.instance()
if (instance) {
instance.repaint()
}
})
.catch(() => {
// Hata durumunda sessizce devam et
})
}
}
}}
> >
{/* Toolbar */} {/* Toolbar */}
<Toolbar items={toolbarItems} /> <Toolbar items={toolbarItems} />