Skip to content

Commit 68aaede

Browse files
authored
fix(dropdown): add dependsOn to dropdown component to dynamically fetch options predicated on another subblock (#1886)
1 parent ec70f6f commit 68aaede

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/components/sub-block/components/dropdown/dropdown.tsx

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { Badge } from '@/components/emcn'
33
import { Combobox, type ComboboxOption } from '@/components/emcn/components'
44
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/components/sub-block/hooks/use-sub-block-value'
55
import { ResponseBlockHandler } from '@/executor/handlers/response/response-handler'
6+
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
7+
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
68

79
/**
810
* Dropdown option type - can be a simple string or an object with label, id, and optional icon
@@ -40,6 +42,8 @@ interface DropdownProps {
4042
blockId: string,
4143
subBlockId: string
4244
) => Promise<Array<{ label: string; id: string }>>
45+
/** Field dependencies that trigger option refetch when changed */
46+
dependsOn?: string[]
4347
}
4448

4549
/**
@@ -63,18 +67,33 @@ export function Dropdown({
6367
placeholder = 'Select an option...',
6468
multiSelect = false,
6569
fetchOptions,
70+
dependsOn = [],
6671
}: DropdownProps) {
6772
const [storeValue, setStoreValue] = useSubBlockValue<string | string[]>(blockId, subBlockId) as [
6873
string | string[] | null | undefined,
6974
(value: string | string[]) => void,
7075
]
7176

77+
const activeWorkflowId = useWorkflowRegistry((s) => s.activeWorkflowId)
78+
const dependencyValues = useSubBlockStore(
79+
useCallback(
80+
(state) => {
81+
if (dependsOn.length === 0 || !activeWorkflowId) return []
82+
const workflowValues = state.workflowValues[activeWorkflowId] || {}
83+
const blockValues = workflowValues[blockId] || {}
84+
return dependsOn.map((depKey) => blockValues[depKey] ?? null)
85+
},
86+
[dependsOn, activeWorkflowId, blockId]
87+
)
88+
)
89+
7290
const [storeInitialized, setStoreInitialized] = useState(false)
7391
const [fetchedOptions, setFetchedOptions] = useState<Array<{ label: string; id: string }>>([])
7492
const [isLoadingOptions, setIsLoadingOptions] = useState(false)
7593
const [fetchError, setFetchError] = useState<string | null>(null)
7694

7795
const previousModeRef = useRef<string | null>(null)
96+
const previousDependencyValuesRef = useRef<string>('')
7897

7998
const [builderData, setBuilderData] = useSubBlockValue<any[]>(blockId, 'builderData')
8099
const [data, setData] = useSubBlockValue<string>(blockId, 'data')
@@ -278,7 +297,27 @@ export function Dropdown({
278297
)
279298

280299
/**
281-
* Effect to fetch options when needed (on mount or when enabled)
300+
* Effect to clear fetched options when dependencies actually change
301+
* This ensures options are refetched with new dependency values (e.g., new credentials)
302+
*/
303+
useEffect(() => {
304+
if (fetchOptions && dependsOn.length > 0) {
305+
const currentDependencyValuesStr = JSON.stringify(dependencyValues)
306+
const previousDependencyValuesStr = previousDependencyValuesRef.current
307+
308+
if (
309+
previousDependencyValuesStr &&
310+
currentDependencyValuesStr !== previousDependencyValuesStr
311+
) {
312+
setFetchedOptions([])
313+
}
314+
315+
previousDependencyValuesRef.current = currentDependencyValuesStr
316+
}
317+
}, [dependencyValues, fetchOptions, dependsOn.length])
318+
319+
/**
320+
* Effect to fetch options when needed (on mount, when enabled, or when dependencies change)
282321
*/
283322
useEffect(() => {
284323
if (
@@ -297,6 +336,7 @@ export function Dropdown({
297336
fetchedOptions.length,
298337
isLoadingOptions,
299338
fetchOptionsIfNeeded,
339+
dependencyValues, // Refetch when dependencies change
300340
])
301341

302342
/**

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/components/editor/components/sub-block/sub-block.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ function SubBlockComponent({
210210
disabled={isDisabled}
211211
multiSelect={config.multiSelect}
212212
fetchOptions={config.fetchOptions}
213+
dependsOn={config.dependsOn}
213214
/>
214215
</div>
215216
)

apps/sim/triggers/gmail/poller.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const gmailPollingTrigger: TriggerConfig = {
5858
return []
5959
}
6060
},
61+
dependsOn: ['triggerCredentials'],
6162
mode: 'trigger',
6263
},
6364
{

apps/sim/triggers/outlook/poller.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const outlookPollingTrigger: TriggerConfig = {
5858
return []
5959
}
6060
},
61+
dependsOn: ['triggerCredentials'],
6162
mode: 'trigger',
6263
},
6364
{

0 commit comments

Comments
 (0)