fix(ui): Projection ref params now filter objects by matching type

- RefCombobox infers object_type from param name when not explicitly set
- e.g. param 'agent' automatically shows only agent-type objects
- Also fixed engine type signature to preserve object_type in params

小橘 🍊(NEKO Team)
This commit is contained in:
小橘 2026-04-13 09:13:38 +00:00
parent 0c22885f4a
commit bd4b79bd7b
3 changed files with 35 additions and 22 deletions

View File

@ -478,7 +478,7 @@ export async function createProjectionDef(
db: D1Database, db: D1Database,
name: string, name: string,
sources: Array<{ event_def: string; bindings: Record<string, string>; expression: string }>, sources: Array<{ event_def: string; bindings: Record<string, string>; expression: string }>,
params: Record<string, { type: 'ref' }>, params: Record<string, { type: 'ref'; object_type?: string }>,
valueSchema: { type: string }, valueSchema: { type: string },
initialValue: any, initialValue: any,
): Promise<{ name: string; hash: string }> { ): Promise<{ name: string; hash: string }> {

File diff suppressed because one or more lines are too long

View File

@ -150,6 +150,7 @@ export default function Projections() {
objects={objects} objects={objects}
objectsByType={objectsByType} objectsByType={objectsByType}
objectType={schema.object_type} objectType={schema.object_type}
paramName={key}
/> />
) : ( ) : (
<input <input
@ -232,29 +233,41 @@ function RefCombobox({
objects, objects,
objectsByType, objectsByType,
objectType, objectType,
paramName,
}: { }: {
value: string value: string
onChange: (v: string) => void onChange: (v: string) => void
objects: Array<{ id: string; type: string }> objects: Array<{ id: string; type: string }>
objectsByType: Record<string, string[]> objectsByType: Record<string, string[]>
objectType?: string objectType?: string
paramName?: string
}) { }) {
const [query, setQuery] = useState('') const [query, setQuery] = useState('')
// Filter objects by object_type if specified // Filter objects by object_type if specified, or infer from param name
// Convention: param name often matches the object type (e.g. param "agent" → type "agent")
const effectiveObjectType = useMemo(() => {
if (objectType) return objectType
if (paramName) {
const types = new Set(objects.map(o => o.type))
if (types.has(paramName)) return paramName
}
return undefined
}, [objectType, paramName, objects])
const relevantObjects = useMemo(() => { const relevantObjects = useMemo(() => {
if (!objectType) return objects if (!effectiveObjectType) return objects
return objects.filter((o) => o.type === objectType) return objects.filter((o) => o.type === effectiveObjectType)
}, [objects, objectType]) }, [objects, effectiveObjectType])
const relevantByType = useMemo(() => { const relevantByType = useMemo(() => {
if (!objectType) return objectsByType if (!effectiveObjectType) return objectsByType
const filtered: Record<string, string[]> = {} const filtered: Record<string, string[]> = {}
if (objectsByType[objectType]) { if (objectsByType[effectiveObjectType]) {
filtered[objectType] = objectsByType[objectType] filtered[effectiveObjectType] = objectsByType[effectiveObjectType]
} }
return filtered return filtered
}, [objectsByType, objectType]) }, [objectsByType, effectiveObjectType])
const filtered = useMemo(() => { const filtered = useMemo(() => {
if (!query) return relevantObjects if (!query) return relevantObjects