diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-builder/filter-builder.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-builder/filter-builder.tsx index 492f2f09844..f7ef31ad5cc 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-builder/filter-builder.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/filter-builder/filter-builder.tsx @@ -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(blockId, subBlockId) - const [tableIdValue] = useSubBlockValue(blockId, tableIdSubBlockId) + const tableIdValue = useCanonicalSubBlockValue(blockId, tableIdSubBlockId) const dynamicColumns = useTableColumns({ tableId: tableIdValue }) const columns = useMemo(() => { diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/sort-builder/sort-builder.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/sort-builder/sort-builder.tsx index 12213e0b63a..b202c4a2a93 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/sort-builder/sort-builder.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/sort-builder/sort-builder.tsx @@ -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(blockId, subBlockId) - const [tableIdValue] = useSubBlockValue(blockId, tableIdSubBlockId) + const tableIdValue = useCanonicalSubBlockValue(blockId, tableIdSubBlockId) const dynamicColumns = useTableColumns({ tableId: tableIdValue, includeBuiltIn: true }) const columns = useMemo(() => { diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-canonical-sub-block-value.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-canonical-sub-block-value.ts new file mode 100644 index 00000000000..3cb5fc25bfc --- /dev/null +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-canonical-sub-block-value.ts @@ -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( + 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) + ) +}