Skip to content

Commit ebb8cf8

Browse files
fix(slack): set depends on for slack channel channel subblock (#1177)
* fix(slack): set depends on for slack channel * use foreign credential check * fix * fix clearing of block
1 parent cadfcdb commit ebb8cf8

File tree

4 files changed

+50
-55
lines changed

4 files changed

+50
-55
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/channel-selector/channel-selector-input.tsx

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
'use client'
22

3-
import { useEffect, useState } from 'react'
3+
import { useEffect, useRef, useState } from 'react'
4+
import { useParams } from 'next/navigation'
45
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
56
import {
67
type SlackChannelInfo,
78
SlackChannelSelector,
89
} from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/channel-selector/components/slack-channel-selector'
910
import { useDependsOnGate } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-depends-on-gate'
11+
import { useForeignCredential } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-foreign-credential'
1012
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/hooks/use-sub-block-value'
1113
import type { SubBlockConfig } from '@/blocks/types'
1214

@@ -15,7 +17,6 @@ interface ChannelSelectorInputProps {
1517
subBlock: SubBlockConfig
1618
disabled?: boolean
1719
onChannelSelect?: (channelId: string) => void
18-
credential?: string
1920
isPreview?: boolean
2021
previewValue?: any | null
2122
}
@@ -25,10 +26,11 @@ export function ChannelSelectorInput({
2526
subBlock,
2627
disabled = false,
2728
onChannelSelect,
28-
credential: providedCredential,
2929
isPreview = false,
3030
previewValue,
3131
}: ChannelSelectorInputProps) {
32+
const params = useParams()
33+
const workflowIdFromUrl = (params?.workflowId as string) || ''
3234
// Use the proper hook to get the current value and setter (same as file-selector)
3335
const [storeValue, setStoreValue] = useSubBlockValue(blockId, subBlock.id)
3436
// Reactive upstream fields
@@ -42,20 +44,22 @@ export function ChannelSelectorInput({
4244
const provider = subBlock.provider || 'slack'
4345
const isSlack = provider === 'slack'
4446
// Central dependsOn gating
45-
const { finalDisabled } = useDependsOnGate(blockId, subBlock, { disabled, isPreview })
47+
const { finalDisabled, dependsOn, dependencyValues } = useDependsOnGate(blockId, subBlock, {
48+
disabled,
49+
isPreview,
50+
})
4651

47-
// Get the credential for the provider - use provided credential or fall back to reactive values
48-
let credential: string
49-
if (providedCredential) {
50-
credential = providedCredential
51-
} else if ((authMethod as string) === 'bot_token' && (botToken as string)) {
52-
credential = botToken as string
53-
} else {
54-
credential = (connectedCredential as string) || ''
55-
}
52+
// Choose credential strictly based on auth method
53+
const credential: string =
54+
(authMethod as string) === 'bot_token'
55+
? (botToken as string) || ''
56+
: (connectedCredential as string) || ''
5657

57-
// Use preview value when in preview mode, otherwise use store value
58-
const value = isPreview ? previewValue : storeValue
58+
// Determine if connected OAuth credential is foreign (not applicable for bot tokens)
59+
const { isForeignCredential } = useForeignCredential(
60+
'slack',
61+
(authMethod as string) === 'bot_token' ? '' : (connectedCredential as string) || ''
62+
)
5963

6064
// Get the current value from the store or prop value if in preview mode (same pattern as file-selector)
6165
useEffect(() => {
@@ -65,6 +69,21 @@ export function ChannelSelectorInput({
6569
}
6670
}, [isPreview, previewValue, storeValue])
6771

72+
// Clear channel when any declared dependency changes (e.g., authMethod/credential)
73+
const prevDepsSigRef = useRef<string>('')
74+
useEffect(() => {
75+
if (dependsOn.length === 0) return
76+
const currentSig = JSON.stringify(dependencyValues)
77+
if (prevDepsSigRef.current && prevDepsSigRef.current !== currentSig) {
78+
if (!isPreview) {
79+
setSelectedChannelId('')
80+
setChannelInfo(null)
81+
setStoreValue('')
82+
}
83+
}
84+
prevDepsSigRef.current = currentSig
85+
}, [dependsOn, dependencyValues, isPreview, setStoreValue])
86+
6887
// Handle channel selection (same pattern as file-selector)
6988
const handleChannelChange = (channelId: string, info?: SlackChannelInfo) => {
7089
setSelectedChannelId(channelId)
@@ -90,6 +109,8 @@ export function ChannelSelectorInput({
90109
credential={credential}
91110
label={subBlock.placeholder || 'Select Slack channel'}
92111
disabled={finalDisabled}
112+
workflowId={workflowIdFromUrl}
113+
isForeignCredential={isForeignCredential}
93114
/>
94115
</div>
95116
</TooltipTrigger>

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/channel-selector/components/slack-channel-selector.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ interface SlackChannelSelectorProps {
2424
credential: string
2525
label?: string
2626
disabled?: boolean
27+
workflowId?: string
28+
isForeignCredential?: boolean
2729
}
2830

2931
export function SlackChannelSelector({
@@ -32,6 +34,8 @@ export function SlackChannelSelector({
3234
credential,
3335
label = 'Select Slack channel',
3436
disabled = false,
37+
workflowId,
38+
isForeignCredential = false,
3539
}: SlackChannelSelectorProps) {
3640
const [channels, setChannels] = useState<SlackChannelInfo[]>([])
3741
const [loading, setLoading] = useState(false)
@@ -51,7 +55,7 @@ export function SlackChannelSelector({
5155
const res = await fetch('/api/tools/slack/channels', {
5256
method: 'POST',
5357
headers: { 'Content-Type': 'application/json' },
54-
body: JSON.stringify({ credential }),
58+
body: JSON.stringify({ credential, workflowId }),
5559
})
5660

5761
if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`)
@@ -125,6 +129,7 @@ export function SlackChannelSelector({
125129
aria-expanded={open}
126130
className='relative w-full justify-between'
127131
disabled={disabled || !credential}
132+
title={isForeignCredential ? 'Using a shared account' : undefined}
128133
>
129134
<div className='flex max-w-[calc(100%-20px)] items-center gap-2 overflow-hidden'>
130135
<SlackIcon className='h-4 w-4 text-[#611f69]' />
@@ -133,6 +138,11 @@ export function SlackChannelSelector({
133138
{getChannelIcon(selectedChannel)}
134139
<span className='truncate font-normal'>{formatChannelName(selectedChannel)}</span>
135140
</>
141+
) : value ? (
142+
<>
143+
<Hash className='h-1.5 w-1.5' />
144+
<span className='truncate font-normal'>{value}</span>
145+
</>
136146
) : (
137147
<span className='truncate text-muted-foreground'>{label}</span>
138148
)}

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/tool-input/tool-input.tsx

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -876,44 +876,6 @@ export function ToolInput({
876876
return result
877877
}
878878

879-
// Helper function to get credential for channel selector
880-
const getCredentialForChannelSelector = (paramId: string): string => {
881-
// Look for the tool that contains this parameter
882-
const currentToolIndex = selectedTools.findIndex((tool) => {
883-
const toolParams = getToolParametersConfig(tool.toolId)
884-
return toolParams?.userInputParameters.some((p) => p.id === paramId)
885-
})
886-
887-
if (currentToolIndex === -1) return ''
888-
889-
const currentTool = selectedTools[currentToolIndex]
890-
891-
// Enhanced credential detection logic from legacy implementation
892-
// Check for bot token first, then OAuth credential
893-
const botToken =
894-
currentTool.params.botToken || (subBlockStore.getValue(blockId, 'botToken') as string)
895-
const oauthCredential =
896-
currentTool.params.credential || (subBlockStore.getValue(blockId, 'credential') as string)
897-
898-
if (botToken?.trim()) {
899-
return botToken
900-
}
901-
if (oauthCredential?.trim()) {
902-
return oauthCredential
903-
}
904-
905-
// Fallback: check for other common credential parameter names
906-
const credentialKeys = ['accessToken', 'token', 'apiKey', 'authToken']
907-
for (const key of credentialKeys) {
908-
const value = currentTool.params[key] || (subBlockStore.getValue(blockId, key) as string)
909-
if (value?.trim()) {
910-
return value
911-
}
912-
}
913-
914-
return ''
915-
}
916-
917879
// Render the appropriate UI component based on parameter configuration
918880
const renderParameterInput = (
919881
param: ToolParameterConfig,
@@ -1023,8 +985,9 @@ export function ToolInput({
1023985
placeholder: uiComponent.placeholder,
1024986
}}
1025987
onChannelSelect={onChange}
1026-
credential={getCredentialForChannelSelector(param.id)}
1027988
disabled={disabled}
989+
isPreview={true}
990+
previewValue={value}
1028991
/>
1029992
)
1030993

apps/sim/blocks/blocks/slack.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export const SlackBlock: BlockConfig<SlackResponse> = {
8181
provider: 'slack',
8282
placeholder: 'Select Slack channel',
8383
mode: 'basic',
84+
dependsOn: ['credential', 'authMethod'],
8485
},
8586
// Manual channel ID input (advanced mode)
8687
{

0 commit comments

Comments
 (0)