import { dynamicFetch } from '@/services/form.service' import { UiLookupDataSourceTypeEnum } from '@/proxy/form/models' import CustomStore from 'devextreme/data/custom_store' import { useCallback } from 'react' 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 createLookupStaticDataSource = ( load: () => any, filter: any = null, key: any = 'static', sort: any = 'name', ) => ({ store: new CustomStore({ key, loadMode: 'raw', load: async () => { const cacheKey = `static:${key}` return cachedLoader(cacheKey, async () => { const res = await Promise.resolve(load()) return Array.isArray(res) ? res : [res] }) }, }), sort, filter, }) const createLookupQueryDataSource = ( listFormCode?: string, listFormFieldName?: string, filters?: any[], isSubForm?: boolean, ) => { return new CustomStore({ loadMode: 'raw', load: async () => { if (!isSubForm && listFormCode && !window.location.pathname.includes(listFormCode)) { return } 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, }) const data = response?.data ?? [] return (Array.isArray(data) ? data : [data]).map((a: any) => ({ key: a.Key, name: a.Name, group: a.Group, })) }).catch(() => null as any) }, }) } const createLookupApiDataSource = ( listFormCode?: string, lookupQuery?: string, filters?: any[], keyName?: string, isSubForm?: boolean, ) => { return new CustomStore({ key: keyName, loadMode: 'raw', load: async () => { if (!isSubForm && listFormCode && !window.location.pathname.includes(listFormCode)) { return } if (!lookupQuery) { return } const parts = lookupQuery.split(';') const [ method = 'GET', url = '', bodyTemplate = '', keySelector = 'a=>a.id', nameSelector = 'a=>a.name', groupSelector = 'a=>a.group', ] = parts let resolvedBody = bodyTemplate ?? '' if (filters?.length) { for (let i = 0; i < filters.length; i++) { resolvedBody = resolvedBody.replace(new RegExp(`@param${i}`, 'g'), String(filters[i])) } } 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), })) }).catch(() => [] as any) }, }) } export const useLookupDataSource = ({ listFormCode, isSubForm, }: { listFormCode: string isSubForm?: boolean }) => { const getLookupDataSource = useCallback( (options: any, colData: any, data: any) => { const { lookupDto } = colData const filters: any[] = [] // Cascading field'ler için - data yoksa veya parent field değeri yoksa null parametreler ile API çağrısı yap if (lookupDto.cascadeParentFields) { if (lookupDto.dataSourceType == UiLookupDataSourceTypeEnum.StaticData) { filters.push([ lookupDto?.cascadeRelationField, lookupDto?.cascadeFilterOperator, options?.data?.[lookupDto?.cascadeParentField] ?? null, ]) } else { for (const cascadeParentField of lookupDto.cascadeParentFields.split(',')) { filters.push(data?.[cascadeParentField] ?? null) } } } if (lookupDto.dataSourceType == UiLookupDataSourceTypeEnum.StaticData) { const staticKey = `static:${listFormCode}:${colData.fieldName}` return createLookupStaticDataSource( () => JSON.parse(lookupDto?.lookupQuery), filters.length ? filters : null, staticKey, ) } else if (lookupDto.dataSourceType == UiLookupDataSourceTypeEnum.Query) { return createLookupQueryDataSource(listFormCode, colData.fieldName, filters, isSubForm) } else if (lookupDto.dataSourceType == UiLookupDataSourceTypeEnum.WebService) { return createLookupApiDataSource( listFormCode, lookupDto?.lookupQuery, filters, colData.lookupDto?.valueExpr?.toLowerCase(), isSubForm, ) } else { return { store: [] } } }, [listFormCode, isSubForm], ) return { getLookupDataSource } } /** Opsiyonel: dışarıdan cache temizlemek istersen export et */ export const clearLookupCache = (key?: string) => { if (!key) __lookupCache.clear() else __lookupCache.delete(key) }