Skip to content

Commit dc5a2b1

Browse files
authored
fix(envvar): fix envvar dropdown positioning, remove dead code (#2196)
1 parent 3f84ed9 commit dc5a2b1

File tree

1 file changed

+18
-116
lines changed
  • apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/short-input

1 file changed

+18
-116
lines changed

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

Lines changed: 18 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -79,33 +79,29 @@ export function ShortInput({
7979
wandControlRef,
8080
hideInternalWand = false,
8181
}: ShortInputProps) {
82-
// Local state for immediate UI updates during streaming
8382
const [localContent, setLocalContent] = useState<string>('')
8483
const [isFocused, setIsFocused] = useState(false)
8584
const [copied, setCopied] = useState(false)
8685
const persistSubBlockValueRef = useRef<(value: string) => void>(() => {})
8786

88-
// Always call the hook - hooks must be called unconditionally
87+
const justPastedRef = useRef(false)
88+
8989
const webhookManagement = useWebhookManagement({
9090
blockId,
9191
triggerId: undefined,
9292
isPreview,
9393
})
9494

95-
// Wand functionality - always call the hook unconditionally
9695
const wandHook = useWand({
9796
wandConfig: config.wandConfig,
9897
currentValue: localContent,
9998
onStreamStart: () => {
100-
// Clear the content when streaming starts
10199
setLocalContent('')
102100
},
103101
onStreamChunk: (chunk) => {
104-
// Update local content with each chunk as it arrives
105102
setLocalContent((current) => current + chunk)
106103
},
107104
onGeneratedContent: (content) => {
108-
// Final content update
109105
setLocalContent(content)
110106
if (!isPreview && !disabled && !readOnly) {
111107
persistSubBlockValueRef.current(content)
@@ -123,23 +119,18 @@ export function ShortInput({
123119
}
124120
}, [setSubBlockValue])
125121

126-
// Check if wand is actually enabled
127122
const isWandEnabled = config.wandConfig?.enabled ?? false
128123

129-
const inputRef = useRef<HTMLInputElement>(null)
130124
const overlayRef = useRef<HTMLDivElement>(null)
131125

132-
// Get ReactFlow instance for zoom control
133126
const reactFlowInstance = useReactFlow()
134127

135128
const accessiblePrefixes = useAccessibleReferencePrefixes(blockId)
136129

137-
// Check if this input is API key related - memoized to prevent recalculation
138130
const isApiKeyField = useMemo(() => {
139131
const normalizedId = config?.id?.replace(/\s+/g, '').toLowerCase() || ''
140132
const normalizedTitle = config?.title?.replace(/\s+/g, '').toLowerCase() || ''
141133

142-
// Check for common API key naming patterns
143134
const apiKeyPatterns = [
144135
'apikey',
145136
'api_key',
@@ -173,11 +164,23 @@ export function ShortInput({
173164
event: 'change' | 'focus' | 'deleteAll'
174165
}) => {
175166
if (!isApiKeyField || isPreview || disabled || readOnly) return { show: false }
167+
168+
if (justPastedRef.current) {
169+
return { show: false }
170+
}
171+
176172
if (event === 'focus') {
173+
if (value.length > 20 && !value.includes('{{')) {
174+
return { show: false }
175+
}
177176
return { show: true, searchTerm: '' }
178177
}
179178
if (event === 'change') {
180-
// For API key fields, show env vars while typing without requiring '{{'
179+
const looksLikeRawApiKey =
180+
value.length > 30 && !value.includes('{{') && !value.match(/^[A-Z_][A-Z0-9_]*$/i)
181+
if (looksLikeRawApiKey) {
182+
return { show: false }
183+
}
181184
return { show: true, searchTerm: value }
182185
}
183186
if (event === 'deleteAll') {
@@ -188,17 +191,13 @@ export function ShortInput({
188191
[isApiKeyField, isPreview, disabled, readOnly]
189192
)
190193

191-
// Use preview value when in preview mode, otherwise use store value or prop value
192194
const baseValue = isPreview ? previewValue : propValue !== undefined ? propValue : undefined
193195

194-
// During streaming, use local content; otherwise use base value
195-
// Only use webhook URL when useWebhookUrl flag is true
196196
const effectiveValue =
197197
useWebhookUrl && webhookManagement.webhookUrl ? webhookManagement.webhookUrl : baseValue
198198

199199
const value = wandHook?.isStreaming ? localContent : effectiveValue
200200

201-
// Sync local content with base value when not streaming
202201
useEffect(() => {
203202
if (!wandHook.isStreaming) {
204203
const baseValueString = baseValue?.toString() ?? ''
@@ -208,108 +207,41 @@ export function ShortInput({
208207
}
209208
}, [baseValue, wandHook.isStreaming, localContent])
210209

211-
/**
212-
* Scrolls the input to show the cursor position
213-
* Uses canvas for efficient text width measurement instead of DOM manipulation
214-
*/
215-
const scrollToCursor = useCallback(() => {
216-
if (!inputRef.current) return
217-
218-
// Use requestAnimationFrame to ensure DOM has updated
219-
requestAnimationFrame(() => {
220-
if (!inputRef.current) return
221-
222-
const cursorPos = inputRef.current.selectionStart ?? 0
223-
const inputWidth = inputRef.current.offsetWidth
224-
const scrollWidth = inputRef.current.scrollWidth
225-
226-
// Get approximate cursor position in pixels using canvas (more efficient)
227-
const textBeforeCursor = inputRef.current.value.substring(0, cursorPos)
228-
const computedStyle = window.getComputedStyle(inputRef.current)
229-
230-
// Use canvas context for text measurement (more efficient than creating DOM elements)
231-
const canvas = document.createElement('canvas')
232-
const context = canvas.getContext('2d')
233-
if (context) {
234-
context.font = computedStyle.font
235-
const cursorPixelPos = context.measureText(textBeforeCursor).width
236-
237-
// Calculate optimal scroll position to center the cursor
238-
const targetScroll = Math.max(0, cursorPixelPos - inputWidth / 2)
239-
240-
// Only scroll if cursor is not visible
241-
if (
242-
cursorPixelPos < inputRef.current.scrollLeft ||
243-
cursorPixelPos > inputRef.current.scrollLeft + inputWidth
244-
) {
245-
inputRef.current.scrollLeft = Math.min(targetScroll, scrollWidth - inputWidth)
246-
}
247-
248-
// Sync overlay scroll
249-
if (overlayRef.current) {
250-
overlayRef.current.scrollLeft = inputRef.current.scrollLeft
251-
}
252-
}
253-
})
254-
}, [])
255-
256-
// Sync scroll position between input and overlay
257210
const handleScroll = useCallback((e: React.UIEvent<HTMLInputElement>) => {
258211
if (overlayRef.current) {
259212
overlayRef.current.scrollLeft = e.currentTarget.scrollLeft
260213
}
261214
}, [])
262215

263-
// Remove the auto-scroll effect that forces cursor position and replace with natural scrolling
264-
useEffect(() => {
265-
if (inputRef.current && overlayRef.current) {
266-
overlayRef.current.scrollLeft = inputRef.current.scrollLeft
267-
}
268-
}, [value])
269-
270-
// Handle paste events to ensure long values are handled correctly
271216
const handlePaste = useCallback((_e: React.ClipboardEvent<HTMLInputElement>) => {
272-
// Let the paste happen normally
273-
// Then ensure scroll positions are synced after the content is updated
217+
justPastedRef.current = true
274218
setTimeout(() => {
275-
if (inputRef.current && overlayRef.current) {
276-
overlayRef.current.scrollLeft = inputRef.current.scrollLeft
277-
}
278-
}, 0)
219+
justPastedRef.current = false
220+
}, 100)
279221
}, [])
280222

281-
// Handle wheel events to control ReactFlow zoom
282223
const handleWheel = useCallback(
283224
(e: React.WheelEvent<HTMLInputElement>) => {
284-
// Only handle zoom when Ctrl/Cmd key is pressed
285225
if (e.ctrlKey || e.metaKey) {
286226
e.preventDefault()
287227
e.stopPropagation()
288228

289-
// Get current zoom level and viewport
290229
const currentZoom = reactFlowInstance.getZoom()
291230
const { x: viewportX, y: viewportY } = reactFlowInstance.getViewport()
292231

293-
// Calculate zoom factor based on wheel delta
294-
// Use a smaller factor for smoother zooming that matches ReactFlow's native behavior
295232
const delta = e.deltaY > 0 ? 1 : -1
296-
// Using 0.98 instead of 0.95 makes the zoom much slower and more gradual
297233
const zoomFactor = 0.96 ** delta
298234

299-
// Calculate new zoom level with min/max constraints
300235
const newZoom = Math.min(Math.max(currentZoom * zoomFactor, 0.1), 1)
301236

302-
// Get the position of the cursor in the page
303237
const { x: pointerX, y: pointerY } = reactFlowInstance.screenToFlowPosition({
304238
x: e.clientX,
305239
y: e.clientY,
306240
})
307241

308-
// Calculate the new viewport position to keep the cursor position fixed
309242
const newViewportX = viewportX + (pointerX * currentZoom - pointerX * newZoom)
310243
const newViewportY = viewportY + (pointerY * currentZoom - pointerY * newZoom)
311244

312-
// Set the new viewport with the calculated position and zoom
313245
reactFlowInstance.setViewport(
314246
{
315247
x: newViewportX,
@@ -322,8 +254,6 @@ export function ShortInput({
322254
return false
323255
}
324256

325-
// For regular scrolling (without Ctrl/Cmd), let the default behavior happen
326-
// Don't interfere with normal scrolling
327257
return true
328258
},
329259
[reactFlowInstance]
@@ -341,33 +271,6 @@ export function ShortInput({
341271
}
342272
}, [useWebhookUrl, webhookManagement?.webhookUrl, value])
343273

344-
// Value display logic - memoize to avoid unnecessary string operations
345-
const displayValue = useMemo(
346-
() =>
347-
password && !isFocused
348-
? '•'.repeat(value?.toString().length ?? 0)
349-
: (value?.toString() ?? ''),
350-
[password, isFocused, value]
351-
)
352-
353-
// Memoize formatted text to avoid recalculation on every render
354-
const formattedText = useMemo(() => {
355-
const textValue = value?.toString() ?? ''
356-
if (password && !isFocused) {
357-
return '•'.repeat(textValue.length)
358-
}
359-
return formatDisplayText(textValue, {
360-
accessiblePrefixes,
361-
highlightAll: !accessiblePrefixes,
362-
})
363-
}, [value, password, isFocused, accessiblePrefixes])
364-
365-
// Memoize focus handler to prevent unnecessary re-renders
366-
const handleFocus = useCallback(() => {
367-
setIsFocused(true)
368-
}, [])
369-
370-
// Memoize blur handler to prevent unnecessary re-renders
371274
const handleBlur = useCallback(() => {
372275
setIsFocused(false)
373276
}, [])
@@ -422,7 +325,6 @@ export function ShortInput({
422325
onDragOver,
423326
onFocus,
424327
}) => {
425-
// Use controller's value for input, but apply local transformations
426328
const actualValue = wandHook.isStreaming
427329
? localContent
428330
: useWebhookUrl && webhookManagement.webhookUrl

0 commit comments

Comments
 (0)