mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(knowledge base): selector infinite render
This commit is contained in:
+20
-84
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { Check, ChevronDown, FileText } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
} from '@/components/ui/command'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
|
||||
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
|
||||
import { useSubBlockValue } from '../../hooks/use-sub-block-value'
|
||||
|
||||
interface DocumentData {
|
||||
id: string
|
||||
@@ -52,38 +52,23 @@ export function DocumentSelector({
|
||||
previewValue,
|
||||
}: DocumentSelectorProps) {
|
||||
const { getValue } = useSubBlockStore()
|
||||
const { collaborativeSetSubblockValue } = useCollaborativeWorkflow()
|
||||
|
||||
const [documents, setDocuments] = useState<DocumentData[]>([])
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [open, setOpen] = useState(false)
|
||||
const [selectedDocument, setSelectedDocument] = useState<DocumentData | null>(null)
|
||||
const [initialFetchDone, setInitialFetchDone] = useState(false)
|
||||
const [selectedId, setSelectedId] = useState('')
|
||||
|
||||
// Get the current value from the store
|
||||
const storeValue = getValue(blockId, subBlock.id)
|
||||
// Use the proper hook to get the current value and setter
|
||||
const [storeValue, setStoreValue] = useSubBlockValue(blockId, subBlock.id)
|
||||
|
||||
// Get the knowledge base ID from the same block's knowledgeBaseId subblock
|
||||
const knowledgeBaseId = getValue(blockId, 'knowledgeBaseId')
|
||||
// Get the knowledge base ID from the same block's knowledgeBaseId subblock - memoize to prevent re-renders
|
||||
const knowledgeBaseId = useMemo(() => getValue(blockId, 'knowledgeBaseId'), [getValue, blockId])
|
||||
|
||||
// Use preview value when in preview mode, otherwise use store value
|
||||
const value = isPreview ? previewValue : storeValue
|
||||
|
||||
// Initialize selectedId with the effective value
|
||||
useEffect(() => {
|
||||
if (isPreview && previewValue !== undefined) {
|
||||
setSelectedId(previewValue || '')
|
||||
} else {
|
||||
setSelectedId(value || '')
|
||||
}
|
||||
}, [value, isPreview, previewValue])
|
||||
|
||||
// Update local state when external value changes
|
||||
useEffect(() => {
|
||||
const currentValue = isPreview ? previewValue : value
|
||||
setSelectedId(currentValue || '')
|
||||
}, [value, isPreview, previewValue])
|
||||
|
||||
// Fetch documents for the selected knowledge base
|
||||
const fetchDocuments = useCallback(async () => {
|
||||
@@ -112,46 +97,12 @@ export function DocumentSelector({
|
||||
const fetchedDocuments = result.data || []
|
||||
setDocuments(fetchedDocuments)
|
||||
setInitialFetchDone(true)
|
||||
|
||||
// Auto-selection logic: if we have a valid selection, keep it
|
||||
// If there's only one document, select it
|
||||
// If we have a value but it's not in the documents, reset it
|
||||
if (selectedId && !fetchedDocuments.some((doc: DocumentData) => doc.id === selectedId)) {
|
||||
setSelectedId('')
|
||||
if (!isPreview) {
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, '')
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(!selectedId || !fetchedDocuments.some((doc: DocumentData) => doc.id === selectedId)) &&
|
||||
fetchedDocuments.length > 0
|
||||
) {
|
||||
if (fetchedDocuments.length === 1) {
|
||||
// If only one document, auto-select it
|
||||
const singleDoc = fetchedDocuments[0]
|
||||
setSelectedId(singleDoc.id)
|
||||
setSelectedDocument(singleDoc)
|
||||
if (!isPreview) {
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, singleDoc.id)
|
||||
}
|
||||
onDocumentSelect?.(singleDoc.id)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
if ((err as Error).name === 'AbortError') return
|
||||
setError((err as Error).message)
|
||||
setDocuments([])
|
||||
}
|
||||
}, [
|
||||
knowledgeBaseId,
|
||||
selectedId,
|
||||
collaborativeSetSubblockValue,
|
||||
blockId,
|
||||
subBlock.id,
|
||||
isPreview,
|
||||
onDocumentSelect,
|
||||
])
|
||||
}, [knowledgeBaseId])
|
||||
|
||||
// Handle dropdown open/close - fetch documents when opening
|
||||
const handleOpenChange = (isOpen: boolean) => {
|
||||
@@ -170,50 +121,35 @@ export function DocumentSelector({
|
||||
if (isPreview) return
|
||||
|
||||
setSelectedDocument(document)
|
||||
setSelectedId(document.id)
|
||||
|
||||
if (!isPreview) {
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, document.id)
|
||||
}
|
||||
|
||||
setStoreValue(document.id)
|
||||
onDocumentSelect?.(document.id)
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
// Sync selected document with value prop
|
||||
useEffect(() => {
|
||||
if (selectedId && documents.length > 0) {
|
||||
const docInfo = documents.find((doc) => doc.id === selectedId)
|
||||
if (docInfo) {
|
||||
setSelectedDocument(docInfo)
|
||||
} else {
|
||||
setSelectedDocument(null)
|
||||
}
|
||||
} else if (!selectedId) {
|
||||
if (value && documents.length > 0) {
|
||||
const docInfo = documents.find((doc) => doc.id === value)
|
||||
setSelectedDocument(docInfo || null)
|
||||
} else {
|
||||
setSelectedDocument(null)
|
||||
}
|
||||
}, [selectedId, documents])
|
||||
}, [value, documents])
|
||||
|
||||
// Reset documents when knowledge base changes
|
||||
useEffect(() => {
|
||||
if (knowledgeBaseId) {
|
||||
setDocuments([])
|
||||
setSelectedDocument(null)
|
||||
setSelectedId('')
|
||||
setInitialFetchDone(false)
|
||||
setError(null)
|
||||
if (!isPreview) {
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, '')
|
||||
}
|
||||
}
|
||||
}, [knowledgeBaseId, blockId, subBlock.id, collaborativeSetSubblockValue, isPreview])
|
||||
setDocuments([])
|
||||
setSelectedDocument(null)
|
||||
setInitialFetchDone(false)
|
||||
setError(null)
|
||||
}, [knowledgeBaseId])
|
||||
|
||||
// Fetch documents when knowledge base is available and we haven't fetched yet
|
||||
useEffect(() => {
|
||||
if (knowledgeBaseId && !initialFetchDone && !isPreview) {
|
||||
fetchDocuments()
|
||||
}
|
||||
}, [knowledgeBaseId, initialFetchDone, fetchDocuments, isPreview])
|
||||
}, [knowledgeBaseId, initialFetchDone, isPreview])
|
||||
|
||||
const formatDocumentName = (document: DocumentData) => {
|
||||
return document.filename
|
||||
@@ -307,7 +243,7 @@ export function DocumentSelector({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{document.id === selectedId && <Check className='ml-auto h-4 w-4' />}
|
||||
{document.id === value && <Check className='ml-auto h-4 w-4' />}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
|
||||
+9
-5
@@ -7,6 +7,7 @@ import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
|
||||
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
|
||||
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
|
||||
import { useSubBlockValue } from '../../hooks/use-sub-block-value'
|
||||
import type { ConfluenceFileInfo } from './components/confluence-file-selector'
|
||||
import { ConfluenceFileSelector } from './components/confluence-file-selector'
|
||||
import type { DiscordChannelInfo } from './components/discord-channel-selector'
|
||||
@@ -40,6 +41,9 @@ export function FileSelectorInput({
|
||||
const { getValue } = useSubBlockStore()
|
||||
const { collaborativeSetSubblockValue } = useCollaborativeWorkflow()
|
||||
const { activeWorkflowId } = useWorkflowRegistry()
|
||||
|
||||
// Use the proper hook to get the current value and setter
|
||||
const [storeValue, setStoreValue] = useSubBlockValue(blockId, subBlock.id)
|
||||
const [selectedFileId, setSelectedFileId] = useState<string>('')
|
||||
const [_fileInfo, setFileInfo] = useState<FileInfo | ConfluenceFileInfo | null>(null)
|
||||
const [selectedIssueId, setSelectedIssueId] = useState<string>('')
|
||||
@@ -66,7 +70,7 @@ export function FileSelectorInput({
|
||||
const serverId = isDiscord ? (getValue(blockId, 'serverId') as string) || '' : ''
|
||||
|
||||
// Use preview value when in preview mode, otherwise use store value
|
||||
const value = isPreview ? previewValue : getValue(blockId, subBlock.id)
|
||||
const value = isPreview ? previewValue : storeValue
|
||||
|
||||
// Get the current value from the store or prop value if in preview mode
|
||||
useEffect(() => {
|
||||
@@ -117,14 +121,14 @@ export function FileSelectorInput({
|
||||
const handleFileChange = (fileId: string, info?: any) => {
|
||||
setSelectedFileId(fileId)
|
||||
setFileInfo(info || null)
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, fileId)
|
||||
setStoreValue(fileId)
|
||||
}
|
||||
|
||||
// Handle issue selection
|
||||
const handleIssueChange = (issueKey: string, info?: JiraIssueInfo) => {
|
||||
setSelectedIssueId(issueKey)
|
||||
setIssueInfo(info || null)
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, issueKey)
|
||||
setStoreValue(issueKey)
|
||||
|
||||
// Clear the fields when a new issue is selected
|
||||
if (isJira) {
|
||||
@@ -137,14 +141,14 @@ export function FileSelectorInput({
|
||||
const handleChannelChange = (channelId: string, info?: DiscordChannelInfo) => {
|
||||
setSelectedChannelId(channelId)
|
||||
setChannelInfo(info || null)
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, channelId)
|
||||
setStoreValue(channelId)
|
||||
}
|
||||
|
||||
// Handle calendar selection
|
||||
const handleCalendarChange = (calendarId: string, info?: GoogleCalendarInfo) => {
|
||||
setSelectedCalendarId(calendarId)
|
||||
setCalendarInfo(info || null)
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, calendarId)
|
||||
setStoreValue(calendarId)
|
||||
}
|
||||
|
||||
// For Google Drive
|
||||
|
||||
-19
@@ -4,7 +4,6 @@ import { useRef, useState } from 'react'
|
||||
import { X } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Progress } from '@/components/ui/progress'
|
||||
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
|
||||
import { useNotificationStore } from '@/stores/notifications/store'
|
||||
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
|
||||
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
|
||||
@@ -58,7 +57,6 @@ export function FileUpload({
|
||||
// Stores
|
||||
const { addNotification } = useNotificationStore()
|
||||
const { activeWorkflowId } = useWorkflowRegistry()
|
||||
const { collaborativeSetSubblockValue } = useCollaborativeWorkflow()
|
||||
|
||||
// Use preview value when in preview mode, otherwise use store value
|
||||
const value = isPreview ? previewValue : storeValue
|
||||
@@ -298,16 +296,10 @@ export function FileUpload({
|
||||
const newFiles = Array.from(uniqueFiles.values())
|
||||
|
||||
setStoreValue(newFiles)
|
||||
|
||||
// Use collaborative update for persistence
|
||||
collaborativeSetSubblockValue(blockId, subBlockId, newFiles)
|
||||
useWorkflowStore.getState().triggerUpdate()
|
||||
} else {
|
||||
// For single file: Replace with last uploaded file
|
||||
setStoreValue(uploadedFiles[0] || null)
|
||||
|
||||
// Use collaborative update for persistence
|
||||
collaborativeSetSubblockValue(blockId, subBlockId, uploadedFiles[0] || null)
|
||||
useWorkflowStore.getState().triggerUpdate()
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -363,19 +355,9 @@ export function FileUpload({
|
||||
const filesArray = Array.isArray(value) ? value : value ? [value] : []
|
||||
const updatedFiles = filesArray.filter((f) => f.path !== file.path)
|
||||
setStoreValue(updatedFiles.length > 0 ? updatedFiles : null)
|
||||
|
||||
// Use collaborative update for persistence
|
||||
collaborativeSetSubblockValue(
|
||||
blockId,
|
||||
subBlockId,
|
||||
updatedFiles.length > 0 ? updatedFiles : null
|
||||
)
|
||||
} else {
|
||||
// For single file: Clear the value
|
||||
setStoreValue(null)
|
||||
|
||||
// Use collaborative update for persistence
|
||||
collaborativeSetSubblockValue(blockId, subBlockId, null)
|
||||
}
|
||||
|
||||
useWorkflowStore.getState().triggerUpdate()
|
||||
@@ -416,7 +398,6 @@ export function FileUpload({
|
||||
|
||||
// Clear input state immediately for better UX
|
||||
setStoreValue(null)
|
||||
collaborativeSetSubblockValue(blockId, subBlockId, null)
|
||||
useWorkflowStore.getState().triggerUpdate()
|
||||
|
||||
if (fileInputRef.current) {
|
||||
|
||||
+36
-48
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { Check, ChevronDown, RefreshCw, X } from 'lucide-react'
|
||||
import { PackageSearchIcon } from '@/components/icons'
|
||||
import { Button } from '@/components/ui/button'
|
||||
@@ -14,9 +14,8 @@ import {
|
||||
} from '@/components/ui/command'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
|
||||
import { type KnowledgeBaseData, useKnowledgeStore } from '@/stores/knowledge/store'
|
||||
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
|
||||
import { useSubBlockValue } from '../../../sub-block/hooks/use-sub-block-value'
|
||||
|
||||
interface KnowledgeBaseSelectorProps {
|
||||
blockId: string
|
||||
@@ -37,24 +36,39 @@ export function KnowledgeBaseSelector({
|
||||
}: KnowledgeBaseSelectorProps) {
|
||||
const { getKnowledgeBasesList, knowledgeBasesList, loadingKnowledgeBasesList } =
|
||||
useKnowledgeStore()
|
||||
const { getValue } = useSubBlockStore()
|
||||
const { collaborativeSetSubblockValue } = useCollaborativeWorkflow()
|
||||
|
||||
const [knowledgeBases, setKnowledgeBases] = useState<KnowledgeBaseData[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [open, setOpen] = useState(false)
|
||||
const [selectedKnowledgeBases, setSelectedKnowledgeBases] = useState<KnowledgeBaseData[]>([])
|
||||
const [initialFetchDone, setInitialFetchDone] = useState(false)
|
||||
|
||||
// Get the current value from the store
|
||||
const storeValue = getValue(blockId, subBlock.id)
|
||||
// Use the proper hook to get the current value and setter - this prevents infinite loops
|
||||
const [storeValue, setStoreValue] = useSubBlockValue(blockId, subBlock.id)
|
||||
|
||||
// Use preview value when in preview mode, otherwise use store value
|
||||
const value = isPreview ? previewValue : storeValue
|
||||
|
||||
const isMultiSelect = subBlock.multiSelect === true
|
||||
|
||||
// Compute selected knowledge bases directly from value - no local state to avoid loops
|
||||
const selectedKnowledgeBases = useMemo(() => {
|
||||
if (value && knowledgeBases.length > 0) {
|
||||
const selectedIds =
|
||||
typeof value === 'string'
|
||||
? value.includes(',')
|
||||
? value
|
||||
.split(',')
|
||||
.map((id) => id.trim())
|
||||
.filter((id) => id.length > 0)
|
||||
: [value]
|
||||
: []
|
||||
|
||||
return knowledgeBases.filter((kb) => selectedIds.includes(kb.id))
|
||||
}
|
||||
return []
|
||||
}, [value, knowledgeBases])
|
||||
|
||||
// Fetch knowledge bases
|
||||
const fetchKnowledgeBases = useCallback(async () => {
|
||||
setLoading(true)
|
||||
@@ -89,12 +103,8 @@ export function KnowledgeBaseSelector({
|
||||
const handleSelectSingleKnowledgeBase = (knowledgeBase: KnowledgeBaseData) => {
|
||||
if (isPreview) return
|
||||
|
||||
setSelectedKnowledgeBases([knowledgeBase])
|
||||
|
||||
if (!isPreview) {
|
||||
// Use collaborative update for both local store and persistence
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, knowledgeBase.id)
|
||||
}
|
||||
// Use the hook's setter which handles collaborative updates
|
||||
setStoreValue(knowledgeBase.id)
|
||||
|
||||
onKnowledgeBaseSelect?.(knowledgeBase.id)
|
||||
setOpen(false)
|
||||
@@ -115,16 +125,13 @@ export function KnowledgeBaseSelector({
|
||||
newSelected = [...selectedKnowledgeBases, knowledgeBase]
|
||||
}
|
||||
|
||||
setSelectedKnowledgeBases(newSelected)
|
||||
const selectedIds = newSelected.map((kb) => kb.id)
|
||||
const valueToStore = selectedIds.length === 1 ? selectedIds[0] : selectedIds.join(',')
|
||||
|
||||
if (!isPreview) {
|
||||
const selectedIds = newSelected.map((kb) => kb.id)
|
||||
const valueToStore = selectedIds.length === 1 ? selectedIds[0] : selectedIds.join(',')
|
||||
// Use collaborative update for both local store and persistence
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, valueToStore)
|
||||
}
|
||||
// Use the hook's setter which handles collaborative updates
|
||||
setStoreValue(valueToStore)
|
||||
|
||||
onKnowledgeBaseSelect?.(newSelected.map((kb) => kb.id))
|
||||
onKnowledgeBaseSelect?.(selectedIds)
|
||||
}
|
||||
|
||||
// Remove selected knowledge base (for multi-select tags)
|
||||
@@ -132,37 +139,16 @@ export function KnowledgeBaseSelector({
|
||||
if (isPreview) return
|
||||
|
||||
const newSelected = selectedKnowledgeBases.filter((kb) => kb.id !== knowledgeBaseId)
|
||||
setSelectedKnowledgeBases(newSelected)
|
||||
const selectedIds = newSelected.map((kb) => kb.id)
|
||||
const valueToStore = selectedIds.length === 1 ? selectedIds[0] : selectedIds.join(',')
|
||||
|
||||
if (!isPreview) {
|
||||
const selectedIds = newSelected.map((kb) => kb.id)
|
||||
const valueToStore = selectedIds.length === 1 ? selectedIds[0] : selectedIds.join(',')
|
||||
// Use collaborative update for both local store and persistence
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, valueToStore)
|
||||
}
|
||||
// Use the hook's setter which handles collaborative updates
|
||||
setStoreValue(valueToStore)
|
||||
|
||||
onKnowledgeBaseSelect?.(newSelected.map((kb) => kb.id))
|
||||
onKnowledgeBaseSelect?.(selectedIds)
|
||||
}
|
||||
|
||||
// Sync selected knowledge bases with value prop
|
||||
useEffect(() => {
|
||||
if (value && knowledgeBases.length > 0) {
|
||||
const selectedIds =
|
||||
typeof value === 'string'
|
||||
? value.includes(',')
|
||||
? value
|
||||
.split(',')
|
||||
.map((id) => id.trim())
|
||||
.filter((id) => id.length > 0)
|
||||
: [value]
|
||||
: []
|
||||
|
||||
const selectedKbs = knowledgeBases.filter((kb) => selectedIds.includes(kb.id))
|
||||
setSelectedKnowledgeBases(selectedKbs)
|
||||
} else if (!value) {
|
||||
setSelectedKnowledgeBases([])
|
||||
}
|
||||
}, [value, knowledgeBases])
|
||||
|
||||
// Use cached data if available
|
||||
useEffect(() => {
|
||||
@@ -177,6 +163,7 @@ export function KnowledgeBaseSelector({
|
||||
if (
|
||||
value &&
|
||||
selectedKnowledgeBases.length === 0 &&
|
||||
knowledgeBases.length === 0 &&
|
||||
!loading &&
|
||||
!initialFetchDone &&
|
||||
!isPreview
|
||||
@@ -186,6 +173,7 @@ export function KnowledgeBaseSelector({
|
||||
}, [
|
||||
value,
|
||||
selectedKnowledgeBases.length,
|
||||
knowledgeBases.length,
|
||||
loading,
|
||||
initialFetchDone,
|
||||
fetchKnowledgeBases,
|
||||
|
||||
+5
-1
@@ -5,6 +5,7 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/comp
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
|
||||
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
|
||||
import { useSubBlockValue } from '../../hooks/use-sub-block-value'
|
||||
import { type DiscordServerInfo, DiscordServerSelector } from './components/discord-server-selector'
|
||||
import { type JiraProjectInfo, JiraProjectSelector } from './components/jira-project-selector'
|
||||
import { type LinearProjectInfo, LinearProjectSelector } from './components/linear-project-selector'
|
||||
@@ -32,6 +33,9 @@ export function ProjectSelectorInput({
|
||||
const [selectedProjectId, setSelectedProjectId] = useState<string>('')
|
||||
const [_projectInfo, setProjectInfo] = useState<JiraProjectInfo | DiscordServerInfo | null>(null)
|
||||
|
||||
// Use the proper hook to get the current value and setter
|
||||
const [storeValue, setStoreValue] = useSubBlockValue(blockId, subBlock.id)
|
||||
|
||||
// Get provider-specific values
|
||||
const provider = subBlock.provider || 'jira'
|
||||
const isDiscord = provider === 'discord'
|
||||
@@ -60,7 +64,7 @@ export function ProjectSelectorInput({
|
||||
) => {
|
||||
setSelectedProjectId(projectId)
|
||||
setProjectInfo(info || null)
|
||||
collaborativeSetSubblockValue(blockId, subBlock.id, projectId)
|
||||
setStoreValue(projectId)
|
||||
|
||||
// Clear the issue-related fields when a new project is selected
|
||||
if (provider === 'jira') {
|
||||
|
||||
+6
-13
@@ -4,6 +4,7 @@ import { getProviderFromModel } from '@/providers/utils'
|
||||
import { useGeneralStore } from '@/stores/settings/general/store'
|
||||
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
|
||||
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
|
||||
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
|
||||
|
||||
// Helper function to dispatch collaborative subblock updates
|
||||
const dispatchSubblockUpdate = (blockId: string, subBlockId: string, value: any) => {
|
||||
@@ -167,6 +168,8 @@ export function useSubBlockValue<T = any>(
|
||||
subBlockId: string,
|
||||
triggerWorkflowUpdate = false
|
||||
): readonly [T | null, (value: T) => void] {
|
||||
const { collaborativeSetSubblockValue } = useCollaborativeWorkflow()
|
||||
|
||||
const blockType = useWorkflowStore(
|
||||
useCallback((state) => state.blocks?.[blockId]?.type, [blockId])
|
||||
)
|
||||
@@ -228,25 +231,15 @@ export function useSubBlockValue<T = any>(
|
||||
storeApiKeyValue(blockId, blockType, modelValue, newValue, storeValue)
|
||||
}
|
||||
|
||||
// Update the subblock store directly
|
||||
useSubBlockStore.getState().setValue(blockId, subBlockId, valueCopy)
|
||||
|
||||
// Dispatch event to trigger socket emission only (not store update)
|
||||
const event = new CustomEvent('update-subblock-value', {
|
||||
detail: {
|
||||
blockId,
|
||||
subBlockId,
|
||||
value: valueCopy,
|
||||
},
|
||||
})
|
||||
window.dispatchEvent(event)
|
||||
// Use collaborative function which handles both local store update and socket emission
|
||||
collaborativeSetSubblockValue(blockId, subBlockId, valueCopy)
|
||||
|
||||
if (triggerWorkflowUpdate) {
|
||||
useWorkflowStore.getState().triggerUpdate()
|
||||
}
|
||||
}
|
||||
},
|
||||
[blockId, subBlockId, blockType, isApiKey, storeValue, triggerWorkflowUpdate, modelValue]
|
||||
[blockId, subBlockId, blockType, isApiKey, storeValue, triggerWorkflowUpdate, modelValue, collaborativeSetSubblockValue]
|
||||
)
|
||||
|
||||
// Initialize valueRef on first render
|
||||
|
||||
Reference in New Issue
Block a user