mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-28 03:00:29 -04:00
fix(table-block): resolve canonical tableId in filter/sort builders (#4294)
The visual filter/sort builders read the selected tableId from subBlock id 'tableId', but the Table block stores it under 'tableSelector' (basic) or 'manualTableId' (advanced) via canonicalParamId. The lookup always returned null, so useTable was disabled and the column picker always showed "no options available". Adds useCanonicalSubBlockValue that resolves by canonicalParamId through the canonical index, mirroring the pattern used by dropdown dependsOn.
This commit is contained in:
@@ -6,6 +6,7 @@ import type { ComboboxOption } from '@/components/emcn'
|
||||
import { useTableColumns } from '@/lib/table/hooks'
|
||||
import type { FilterRule } from '@/lib/table/query-builder/constants'
|
||||
import { useFilterBuilder } from '@/lib/table/query-builder/use-query-builder'
|
||||
import { useCanonicalSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-canonical-sub-block-value'
|
||||
import { useSubBlockInput } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-input'
|
||||
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
|
||||
import { FilterRuleRow } from './components/filter-rule-row'
|
||||
@@ -40,7 +41,7 @@ export function FilterBuilder({
|
||||
tableIdSubBlockId = 'tableId',
|
||||
}: FilterBuilderProps) {
|
||||
const [storeValue, setStoreValue] = useSubBlockValue<FilterRule[]>(blockId, subBlockId)
|
||||
const [tableIdValue] = useSubBlockValue<string>(blockId, tableIdSubBlockId)
|
||||
const tableIdValue = useCanonicalSubBlockValue<string>(blockId, tableIdSubBlockId)
|
||||
|
||||
const dynamicColumns = useTableColumns({ tableId: tableIdValue })
|
||||
const columns = useMemo(() => {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { generateId } from '@sim/utils/id'
|
||||
import type { ComboboxOption } from '@/components/emcn'
|
||||
import { useTableColumns } from '@/lib/table/hooks'
|
||||
import { SORT_DIRECTIONS, type SortRule } from '@/lib/table/query-builder/constants'
|
||||
import { useCanonicalSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-canonical-sub-block-value'
|
||||
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
|
||||
import { SortRuleRow } from './components/sort-rule-row'
|
||||
|
||||
@@ -36,7 +37,7 @@ export function SortBuilder({
|
||||
tableIdSubBlockId = 'tableId',
|
||||
}: SortBuilderProps) {
|
||||
const [storeValue, setStoreValue] = useSubBlockValue<SortRule[]>(blockId, subBlockId)
|
||||
const [tableIdValue] = useSubBlockValue<string>(blockId, tableIdSubBlockId)
|
||||
const tableIdValue = useCanonicalSubBlockValue<string>(blockId, tableIdSubBlockId)
|
||||
|
||||
const dynamicColumns = useTableColumns({ tableId: tableIdValue, includeBuiltIn: true })
|
||||
const columns = useMemo(() => {
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { isEqual } from 'es-toolkit'
|
||||
import { useStoreWithEqualityFn } from 'zustand/traditional'
|
||||
import { buildCanonicalIndex, resolveDependencyValue } from '@/lib/workflows/subblocks/visibility'
|
||||
import { getBlock } from '@/blocks/registry'
|
||||
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
|
||||
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
|
||||
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
|
||||
|
||||
/**
|
||||
* Read a sub-block value by either its raw subBlockId or its canonicalParamId.
|
||||
*
|
||||
* `useSubBlockValue` only looks up the raw subBlockId. For fields that use
|
||||
* `canonicalParamId` to unify basic/advanced inputs (e.g. `tableSelector` vs
|
||||
* `manualTableId` both mapping to `tableId`), this hook resolves to whichever
|
||||
* member of the canonical group currently holds the value.
|
||||
*/
|
||||
export function useCanonicalSubBlockValue<T = unknown>(
|
||||
blockId: string,
|
||||
canonicalOrSubBlockId: string
|
||||
): T | null {
|
||||
const activeWorkflowId = useWorkflowRegistry((s) => s.activeWorkflowId)
|
||||
const blockState = useWorkflowStore((state) => state.blocks[blockId])
|
||||
const blockConfig = blockState?.type ? getBlock(blockState.type) : null
|
||||
const canonicalIndex = useMemo(
|
||||
() => buildCanonicalIndex(blockConfig?.subBlocks || []),
|
||||
[blockConfig?.subBlocks]
|
||||
)
|
||||
const canonicalModeOverrides = blockState?.data?.canonicalModes
|
||||
|
||||
return useStoreWithEqualityFn(
|
||||
useSubBlockStore,
|
||||
useCallback(
|
||||
(state) => {
|
||||
if (!activeWorkflowId) return null
|
||||
const blockValues = state.workflowValues[activeWorkflowId]?.[blockId] || {}
|
||||
const resolved = resolveDependencyValue(
|
||||
canonicalOrSubBlockId,
|
||||
blockValues,
|
||||
canonicalIndex,
|
||||
canonicalModeOverrides
|
||||
)
|
||||
return (resolved ?? null) as T | null
|
||||
},
|
||||
[activeWorkflowId, blockId, canonicalOrSubBlockId, canonicalIndex, canonicalModeOverrides]
|
||||
),
|
||||
(a, b) => isEqual(a, b)
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user