From 138b49a7b0bf5a18e5c10ba428c6dda19ab779f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96zt=C3=BCrk?= Date: Mon, 19 Jan 2026 03:00:17 +0300 Subject: [PATCH] =?UTF-8?q?CardView=20d=C3=BCzenlemeleri?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/views/list/CardView.tsx | 177 +++++++++++++++------------------ 1 file changed, 78 insertions(+), 99 deletions(-) diff --git a/ui/src/views/list/CardView.tsx b/ui/src/views/list/CardView.tsx index 485da116..c461277f 100644 --- a/ui/src/views/list/CardView.tsx +++ b/ui/src/views/list/CardView.tsx @@ -79,22 +79,6 @@ interface CardViewProps { const statedGridPanelColor = 'rgba(50, 200, 200, 0.5)' -// Lookup cache (module scope) -const __lookupCache = new Map>() - -const cachedLoader = (key: string, loader: () => Promise) => { - 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 { listFormCode, searchParams, isSubForm, gridDto: extGridDto, refreshGridDto } = props const { translate } = useLocalization() @@ -138,11 +122,6 @@ const CardView = (props: CardViewProps) => { } }, [searchParams]) - // Clear lookup cache when listFormCode changes - useEffect(() => { - __lookupCache.clear() - }, [listFormCode]) - const layout = layoutTypes.cardView const { createSelectDataSource } = useListFormCustomDataSource({ gridRef: cardViewRef as any }) @@ -161,7 +140,7 @@ const CardView = (props: CardViewProps) => { key, loadMode: 'raw', load: async () => { - return cachedLoader(`static:${key}`, () => Promise.resolve(load())) + return Promise.resolve(load()).then((res) => res ?? []) }, }), paginate: false, @@ -178,21 +157,18 @@ const CardView = (props: CardViewProps) => { loadMode: 'raw', load: async () => { try { - const cacheKey = `query:${listFormCode}:${listFormFieldName}:${JSON.stringify(filters ?? null)}` - return cachedLoader(cacheKey, async () => { - const response = await dynamicFetch('list-form-select/lookup', 'POST', null, { - listFormCode, - listFormFieldName, - filters, - }) - - return (response.data ?? []).map((a: any) => ({ - key: a.Key, - name: a.Name, - group: a.Group, - ...a, - })) + const response = await dynamicFetch('list-form-select/lookup', 'POST', null, { + listFormCode, + listFormFieldName, + filters, }) + + return (response.data ?? []).map((a: any) => ({ + key: a.Key, + name: a.Name, + group: a.Group, + ...a, + })) } catch (error: any) { return [] } @@ -227,19 +203,16 @@ const CardView = (props: CardViewProps) => { } try { - const cacheKey = `api:${lookupQuery}:${JSON.stringify(filters ?? null)}` - return cachedLoader(cacheKey, async () => { - const response = await dynamicFetch(url, method, null, resolvedBody) - let { data } = response - if (!data) return [] - if (!Array.isArray(data)) data = [data] - return data.map((a: any) => ({ - key: eval(keySelector), - name: eval(nameSelector), - group: eval(groupSelector), - ...a, - })) - }) + const response = await dynamicFetch(url, method, null, resolvedBody) + let { data } = response + if (!data) return [] + if (!Array.isArray(data)) data = [data] + return data.map((a: any) => ({ + key: eval(keySelector), + name: eval(nameSelector), + group: eval(groupSelector), + ...a, + })) } catch { return [] } @@ -519,20 +492,6 @@ const CardView = (props: CardViewProps) => { // Lookup desteği ekle - dataSourceType > 0 olmalı (0 = None) 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) ;(col as any).isLookup = true ;(col as any).lookupInfo = { @@ -619,6 +578,62 @@ const CardView = (props: CardViewProps) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [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> = [] + + 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) const cardViewDataSource = useMemo(() => { if (!gridDto) return null @@ -1128,42 +1143,6 @@ const CardView = (props: CardViewProps) => { 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> = [] - - 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() - 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 */}