erp-platform/ui/src/views/form/useLookupDataSource.ts
2025-11-28 16:04:49 +03:00

182 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<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 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)
}