Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { WandPromptBar } from '@/app/workspace/[workspaceId]/w/[workflowId]/comp
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value'
import { useWand } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-wand'
import type { GenerationType } from '@/blocks/types'
import { useTagSelection } from '@/hooks/use-tag-selection'
import { useSubBlockStore } from '@/stores/workflows/subblock/store'

const logger = createLogger('Code')
Expand Down Expand Up @@ -164,6 +165,8 @@ export function Code({
},
})

const emitTagSelection = useTagSelection(blockId, subBlockId)

// Use preview value when in preview mode, otherwise use store value or prop value
const value = isPreview ? previewValue : propValue !== undefined ? propValue : storeValue

Expand Down Expand Up @@ -306,7 +309,7 @@ export function Code({
const handleTagSelect = (newValue: string) => {
if (!isPreview) {
setCode(newValue)
setStoreValue(newValue)
emitTagSelection(newValue)
}
setShowTags(false)
setActiveSourceBlockId(null)
Expand All @@ -319,7 +322,7 @@ export function Code({
const handleEnvVarSelect = (newValue: string) => {
if (!isPreview) {
setCode(newValue)
setStoreValue(newValue)
emitTagSelection(newValue)
}
setShowEnvVars(false)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value'
import type { SubBlockConfig } from '@/blocks/types'
import { useTagSelection } from '@/hooks/use-tag-selection'

const logger = createLogger('ComboBox')

Expand Down Expand Up @@ -53,6 +54,8 @@ export function ComboBox({
const [activeSourceBlockId, setActiveSourceBlockId] = useState<string | null>(null)
const [highlightedIndex, setHighlightedIndex] = useState(-1)

const emitTagSelection = useTagSelection(blockId, subBlockId)

const inputRef = useRef<HTMLInputElement>(null)
const overlayRef = useRef<HTMLDivElement>(null)
const dropdownRef = useRef<HTMLDivElement>(null)
Expand Down Expand Up @@ -330,7 +333,7 @@ export function ComboBox({
// Environment variable and tag selection handler
const handleEnvVarSelect = (newValue: string) => {
if (!isPreview) {
setStoreValue(newValue)
emitTagSelection(newValue)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value'
import { useTagSelection } from '@/hooks/use-tag-selection'
import { useWorkflowStore } from '@/stores/workflows/workflow/store'

const logger = createLogger('ConditionInput')
Expand Down Expand Up @@ -52,6 +53,9 @@ export function ConditionInput({
disabled = false,
}: ConditionInputProps) {
const [storeValue, setStoreValue] = useSubBlockValue(blockId, subBlockId)

const emitTagSelection = useTagSelection(blockId, subBlockId)

const containerRef = useRef<HTMLDivElement>(null)
const [visualLineHeights, setVisualLineHeights] = useState<{
[key: string]: number[]
Expand Down Expand Up @@ -400,6 +404,64 @@ export function ConditionInput({
)
}

const handleTagSelectImmediate = (blockId: string, newValue: string) => {
if (isPreview || disabled) return

setConditionalBlocks((blocks) =>
blocks.map((block) =>
block.id === blockId
? {
...block,
value: newValue,
showTags: false,
activeSourceBlockId: null,
}
: block
)
)

const updatedBlocks = conditionalBlocks.map((block) =>
block.id === blockId
? {
...block,
value: newValue,
showTags: false,
activeSourceBlockId: null,
}
: block
)
emitTagSelection(JSON.stringify(updatedBlocks))
}

const handleEnvVarSelectImmediate = (blockId: string, newValue: string) => {
if (isPreview || disabled) return

setConditionalBlocks((blocks) =>
blocks.map((block) =>
block.id === blockId
? {
...block,
value: newValue,
showEnvVars: false,
searchTerm: '',
}
: block
)
)

const updatedBlocks = conditionalBlocks.map((block) =>
block.id === blockId
? {
...block,
value: newValue,
showEnvVars: false,
searchTerm: '',
}
: block
)
emitTagSelection(JSON.stringify(updatedBlocks))
}

// Update block titles based on position
const updateBlockTitles = (blocks: ConditionalBlock[]): ConditionalBlock[] => {
return blocks.map((block, index) => ({
Expand Down Expand Up @@ -706,7 +768,7 @@ export function ConditionInput({
{block.showEnvVars && (
<EnvVarDropdown
visible={block.showEnvVars}
onSelect={(newValue) => handleEnvVarSelect(block.id, newValue)}
onSelect={(newValue) => handleEnvVarSelectImmediate(block.id, newValue)}
searchTerm={block.searchTerm}
inputValue={block.value}
cursorPosition={block.cursorPosition}
Expand All @@ -723,7 +785,7 @@ export function ConditionInput({
{block.showTags && (
<TagDropdown
visible={block.showTags}
onSelect={(newValue) => handleTagSelect(block.id, newValue)}
onSelect={(newValue) => handleTagSelectImmediate(block.id, newValue)}
blockId={blockId}
activeSourceBlockId={block.activeSourceBlockId}
inputValue={block.value}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { cn } from '@/lib/utils'
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value'
import type { SubBlockConfig } from '@/blocks/types'
import { useKnowledgeBaseTagDefinitions } from '@/hooks/use-knowledge-base-tag-definitions'
import { useTagSelection } from '@/hooks/use-tag-selection'

interface DocumentTagRow {
id: string
Expand Down Expand Up @@ -47,6 +48,8 @@ export function DocumentTagEntry({
// Use KB tag definitions hook to get available tags
const { tagDefinitions, isLoading } = useKnowledgeBaseTagDefinitions(knowledgeBaseId)

const emitTagSelection = useTagSelection(blockId, subBlock.id)

// State for dropdown visibility - one for each row
const [dropdownStates, setDropdownStates] = useState<Record<number, boolean>>({})
// State for type dropdown visibility - one for each row
Expand Down Expand Up @@ -128,33 +131,8 @@ export function DocumentTagEntry({
setStoreValue(jsonString)
}

const handleCellChange = (rowIndex: number, column: string, value: string) => {
if (isPreview || disabled) return

// Check if this is a new tag name that would exceed the limit
if (column === 'tagName' && value.trim()) {
const isExistingTag = tagDefinitions.some(
(def) => def.displayName.toLowerCase() === value.toLowerCase()
)

if (!isExistingTag) {
// Count current new tags being created (excluding the current row)
const currentNewTags = rows.filter(
(row, idx) =>
idx !== rowIndex &&
row.cells.tagName?.trim() &&
!tagDefinitions.some(
(def) => def.displayName.toLowerCase() === row.cells.tagName.toLowerCase()
)
).length

if (tagDefinitions.length + currentNewTags >= MAX_TAG_SLOTS) {
// Don't allow creating new tags if we've reached the limit
return
}
}
}

// Shared helper function for updating rows and generating JSON
const updateRowsAndGenerateJson = (rowIndex: number, column: string, value: string) => {
const updatedRows = [...rows].map((row, idx) => {
if (idx === rowIndex) {
const newCells = { ...row.cells, [column]: value }
Expand All @@ -177,8 +155,6 @@ export function DocumentTagEntry({
return row
})

// No auto-add rows - user will manually add them with plus button

// Store all rows including empty ones - don't auto-remove
const dataToStore = updatedRows.map((row) => ({
id: row.id,
Expand All @@ -187,10 +163,47 @@ export function DocumentTagEntry({
value: row.cells.value || '',
}))

const jsonString = dataToStore.length > 0 ? JSON.stringify(dataToStore) : ''
return dataToStore.length > 0 ? JSON.stringify(dataToStore) : ''
}

const handleCellChange = (rowIndex: number, column: string, value: string) => {
if (isPreview || disabled) return

// Check if this is a new tag name that would exceed the limit
if (column === 'tagName' && value.trim()) {
const isExistingTag = tagDefinitions.some(
(def) => def.displayName.toLowerCase() === value.toLowerCase()
)

if (!isExistingTag) {
// Count current new tags being created (excluding the current row)
const currentNewTags = rows.filter(
(row, idx) =>
idx !== rowIndex &&
row.cells.tagName?.trim() &&
!tagDefinitions.some(
(def) => def.displayName.toLowerCase() === row.cells.tagName.toLowerCase()
)
).length

if (tagDefinitions.length + currentNewTags >= MAX_TAG_SLOTS) {
// Don't allow creating new tags if we've reached the limit
return
}
}
}

const jsonString = updateRowsAndGenerateJson(rowIndex, column, value)
setStoreValue(jsonString)
}

const handleTagDropdownSelection = (rowIndex: number, column: string, value: string) => {
if (isPreview || disabled) return

const jsonString = updateRowsAndGenerateJson(rowIndex, column, value)
emitTagSelection(jsonString)
}

const handleAddRow = () => {
if (isPreview || disabled) return

Expand Down Expand Up @@ -520,7 +533,8 @@ export function DocumentTagEntry({
<TagDropdown
visible={activeTagDropdown.showTags}
onSelect={(newValue) => {
handleCellChange(activeTagDropdown.rowIndex, 'value', newValue)
// Use immediate emission for tag dropdown selections
handleTagDropdownSelection(activeTagDropdown.rowIndex, 'value', newValue)
setActiveTagDropdown(null)
}}
blockId={blockId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Label } from '@/components/ui/label'
import { checkTagTrigger, TagDropdown } from '@/components/ui/tag-dropdown'
import type { SubBlockConfig } from '@/blocks/types'
import { useKnowledgeBaseTagDefinitions } from '@/hooks/use-knowledge-base-tag-definitions'
import { useTagSelection } from '@/hooks/use-tag-selection'
import { useSubBlockValue } from '../../hooks/use-sub-block-value'

interface TagFilter {
Expand Down Expand Up @@ -44,6 +45,9 @@ export function KnowledgeTagFilters({
}: KnowledgeTagFiltersProps) {
const [storeValue, setStoreValue] = useSubBlockValue<string | null>(blockId, subBlock.id)

// Hook for immediate tag/dropdown selections
const emitTagSelection = useTagSelection(blockId, subBlock.id)

// Get the knowledge base ID from other sub-blocks
const [knowledgeBaseIdValue] = useSubBlockValue(blockId, 'knowledgeBaseId')
const knowledgeBaseId = knowledgeBaseIdValue || null
Expand Down Expand Up @@ -122,6 +126,30 @@ export function KnowledgeTagFilters({
updateFilters(updatedFilters)
}

const handleTagDropdownSelection = (rowIndex: number, column: string, value: string) => {
if (isPreview || disabled) return

const updatedRows = [...rows].map((row, idx) => {
if (idx === rowIndex) {
return {
...row,
cells: { ...row.cells, [column]: value },
}
}
return row
})

// Convert back to TagFilter format - keep all rows, even empty ones
const updatedFilters = updatedRows.map((row) => ({
id: row.id,
tagName: row.cells.tagName || '',
tagValue: row.cells.value || '',
}))

const jsonValue = updatedFilters.length > 0 ? JSON.stringify(updatedFilters) : null
emitTagSelection(jsonValue)
}

const handleAddRow = () => {
if (isPreview || disabled) return

Expand Down Expand Up @@ -336,7 +364,8 @@ export function KnowledgeTagFilters({
<TagDropdown
visible={activeTagDropdown.showTags}
onSelect={(newValue) => {
handleCellChange(activeTagDropdown.rowIndex, 'value', newValue)
// Use immediate emission for tag dropdown selections
handleTagDropdownSelection(activeTagDropdown.rowIndex, 'value', newValue)
setActiveTagDropdown(null)
}}
blockId={blockId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { WandPromptBar } from '@/app/workspace/[workspaceId]/w/[workflowId]/comp
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value'
import { useWand } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-wand'
import type { SubBlockConfig } from '@/blocks/types'
import { useTagSelection } from '@/hooks/use-tag-selection'

const logger = createLogger('LongInput')

Expand Down Expand Up @@ -79,6 +80,8 @@ export function LongInput({
},
})

const emitTagSelection = useTagSelection(blockId, subBlockId)

const [showEnvVars, setShowEnvVars] = useState(false)
const [showTags, setShowTags] = useState(false)
const [searchTerm, setSearchTerm] = useState('')
Expand Down Expand Up @@ -428,7 +431,7 @@ export function LongInput({
if (onChange) {
onChange(newValue)
} else if (!isPreview) {
setStoreValue(newValue)
emitTagSelection(newValue)
}
}}
searchTerm={searchTerm}
Expand All @@ -445,7 +448,7 @@ export function LongInput({
if (onChange) {
onChange(newValue)
} else if (!isPreview) {
setStoreValue(newValue)
emitTagSelection(newValue)
}
}}
blockId={blockId}
Expand Down
Loading