mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-24 13:44:54 +00:00
92 lines
2.5 KiB
TypeScript
92 lines
2.5 KiB
TypeScript
/// <reference path="../../global.d.ts" />
|
|
|
|
import { useState, useEffect, useMemo, useCallback } from 'react'
|
|
import { DataSource } from '@/types/json-ui'
|
|
import { evaluateBindingExpression } from '@/lib/json-ui/expression-helpers'
|
|
import { evaluateTemplate } from '@/lib/json-ui/expression-evaluator'
|
|
|
|
export function useDataSources(dataSources: DataSource[]) {
|
|
const [data, setData] = useState<Record<string, any>>({})
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
const staticSources = useMemo(
|
|
() => dataSources.filter((ds) => ds.type === 'static'),
|
|
[dataSources]
|
|
)
|
|
|
|
const derivedSources = useMemo(
|
|
() => dataSources.filter((ds) => ds.expression || ds.valueTemplate),
|
|
[dataSources]
|
|
)
|
|
|
|
useEffect(() => {
|
|
const loadData = async () => {
|
|
const initialData: Record<string, any> = {}
|
|
|
|
for (const ds of dataSources) {
|
|
if (ds.type === 'kv' && ds.key) {
|
|
try {
|
|
const value = await window.spark.kv.get(ds.key)
|
|
initialData[ds.id] = value !== undefined ? value : ds.defaultValue
|
|
} catch {
|
|
initialData[ds.id] = ds.defaultValue
|
|
}
|
|
} else if (ds.type === 'static' && !ds.expression && !ds.valueTemplate) {
|
|
initialData[ds.id] = ds.defaultValue
|
|
}
|
|
}
|
|
|
|
setData(initialData)
|
|
setLoading(false)
|
|
}
|
|
|
|
loadData()
|
|
}, [dataSources])
|
|
|
|
const updateDataSource = useCallback(async (id: string, value: any) => {
|
|
setData((prev) => ({ ...prev, [id]: value }))
|
|
|
|
const kvSource = dataSources.find((ds) => ds.id === id && ds.type === 'kv')
|
|
if (kvSource && kvSource.key) {
|
|
await window.spark.kv.set(kvSource.key, value)
|
|
}
|
|
}, [dataSources])
|
|
|
|
const computedData = useMemo(() => {
|
|
const result: Record<string, any> = {}
|
|
const context = { ...data }
|
|
|
|
derivedSources.forEach((ds) => {
|
|
let value: any
|
|
if (ds.expression) {
|
|
value = evaluateBindingExpression(ds.expression, context, {
|
|
fallback: undefined,
|
|
label: `data source (${ds.id})`,
|
|
})
|
|
} else if (ds.valueTemplate) {
|
|
value = evaluateTemplate(ds.valueTemplate, { data: context })
|
|
}
|
|
|
|
if (value === undefined && ds.defaultValue !== undefined) {
|
|
value = ds.defaultValue
|
|
}
|
|
|
|
result[ds.id] = value
|
|
context[ds.id] = value
|
|
})
|
|
|
|
return result
|
|
}, [derivedSources, data])
|
|
|
|
const allData = useMemo(
|
|
() => ({ ...data, ...computedData }),
|
|
[data, computedData]
|
|
)
|
|
|
|
return {
|
|
data: allData,
|
|
loading,
|
|
updateDataSource,
|
|
}
|
|
}
|