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
46 changes: 1 addition & 45 deletions apps/sim/app/_styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/
:root {
--sidebar-width: 232px; /* SIDEBAR_WIDTH.DEFAULT */
--panel-width: 290px; /* PANEL_WIDTH.DEFAULT */
--panel-width: 320px; /* PANEL_WIDTH.DEFAULT */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Violates style guide to avoid editing globals.css. Consider moving the panel width update to a CSS variable set in the component or store instead of modifying this global file.

Context Used: Context from dashboard - Avoid editing the globals.css file unless absolutely necessary. Move style changes to local componen... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/app/_styles/globals.css
Line: 14:14

Comment:
**style:** Violates style guide to avoid editing `globals.css`. Consider moving the panel width update to a CSS variable set in the component or store instead of modifying this global file.

**Context Used:** Context from `dashboard` - Avoid editing the globals.css file unless absolutely necessary. Move style changes to local componen... ([source](https://app.greptile.com/review/custom-context?memory=c3b5e4b0-6580-4307-83aa-ba28f105b3c4))

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

--toolbar-triggers-height: 300px; /* TOOLBAR_TRIGGERS_HEIGHT.DEFAULT */
--editor-connections-height: 172px; /* EDITOR_CONNECTIONS_HEIGHT.DEFAULT */
--terminal-height: 155px; /* TERMINAL_HEIGHT.DEFAULT */
Expand Down Expand Up @@ -77,24 +77,6 @@
cursor: grabbing !important;
}

/**
* Selected node ring indicator
* Uses a pseudo-element overlay to match the original behavior (absolute inset-0 z-40)
*/
.react-flow__node.selected > div > div {
position: relative;
}

.react-flow__node.selected > div > div::after {
content: "";
position: absolute;
inset: 0;
z-index: 40;
border-radius: 8px;
box-shadow: 0 0 0 1.75px var(--brand-secondary);
pointer-events: none;
}

/**
* Color tokens - single source of truth for all colors
* Light mode: Warm theme
Expand Down Expand Up @@ -576,32 +558,6 @@ input[type="search"]::-ms-clear {
transition-duration: 300ms;
}

.streaming-effect {
@apply relative overflow-hidden;
}

.streaming-effect::after {
content: "";
@apply pointer-events-none absolute left-0 top-0 h-full w-full;
background: linear-gradient(
90deg,
rgba(128, 128, 128, 0) 0%,
rgba(128, 128, 128, 0.1) 50%,
rgba(128, 128, 128, 0) 100%
);
animation: code-shimmer 1.5s infinite;
z-index: 10;
}

.dark .streaming-effect::after {
background: linear-gradient(
90deg,
rgba(180, 180, 180, 0) 0%,
rgba(180, 180, 180, 0.1) 50%,
rgba(180, 180, 180, 0) 100%
);
}

.loading-placeholder::placeholder {
animation: placeholder-pulse 1.5s ease-in-out infinite;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,10 @@ export function Code({
setCode('')
}

handleStreamChunkRef.current = (chunk: string) => {
setCode((prev) => prev + chunk)
}

handleGeneratedContentRef.current = (generatedCode: string) => {
setCode(generatedCode)
if (!isPreview && !disabled) {
Expand Down Expand Up @@ -691,11 +695,7 @@ export function Code({
/>
)}

<CodeEditor.Container
onDragOver={(e) => e.preventDefault()}
onDrop={handleDrop}
isStreaming={isAiStreaming}
>
<CodeEditor.Container onDragOver={(e) => e.preventDefault()} onDrop={handleDrop}>
<div className='absolute top-2 right-3 z-10 flex items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100'>
{wandConfig?.enabled &&
!isAiStreaming &&
Expand Down Expand Up @@ -761,6 +761,11 @@ export function Code({
}}
onFocus={() => {
hasEditedSinceFocusRef.current = false
// Show tag dropdown on focus when code is empty
if (!isPreview && !disabled && !readOnly && code.trim() === '') {
setShowTags(true)
setCursorPosition(0)
}
}}
highlight={createHighlightFunction(effectiveLanguage, shouldHighlightReference)}
{...getCodeEditorProps({ isStreaming: isAiStreaming, isPreview, disabled })}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export function ConditionInput({
const accessiblePrefixes = useAccessibleReferencePrefixes(blockId)

const containerRef = useRef<HTMLDivElement>(null)
const inputRefs = useRef<Map<string, HTMLTextAreaElement>>(new Map())

/**
* Determines if a reference string should be highlighted in the editor.
Expand Down Expand Up @@ -728,6 +729,20 @@ export function ConditionInput({
})
}, [conditionalBlocks.length])

// Capture textarea refs from Editor components (condition mode)
useEffect(() => {
if (!isRouterMode && containerRef.current) {
conditionalBlocks.forEach((block) => {
const textarea = containerRef.current?.querySelector(
`[data-block-id="${block.id}"] textarea`
) as HTMLTextAreaElement | null
if (textarea) {
inputRefs.current.set(block.id, textarea)
}
})
}
}, [conditionalBlocks, isRouterMode])

// Show loading or empty state if not ready or no blocks
if (!isReady || conditionalBlocks.length === 0) {
return (
Expand Down Expand Up @@ -842,6 +857,9 @@ export function ConditionInput({
onDrop={(e) => handleDrop(block.id, e)}
>
<Textarea
ref={(el) => {
if (el) inputRefs.current.set(block.id, el)
}}
data-router-block-id={block.id}
value={block.value}
onChange={(e) => {
Expand Down Expand Up @@ -869,6 +887,15 @@ export function ConditionInput({
)
}
}}
onFocus={() => {
if (!isPreview && !disabled && block.value.trim() === '') {
setConditionalBlocks((blocks) =>
blocks.map((b) =>
b.id === block.id ? { ...b, showTags: true, cursorPosition: 0 } : b
)
)
}
}}
onBlur={() => {
setTimeout(() => {
setConditionalBlocks((blocks) =>
Expand Down Expand Up @@ -929,6 +956,11 @@ export function ConditionInput({
)
)
}}
inputRef={
{
current: inputRefs.current.get(block.id) || null,
} as React.RefObject<HTMLTextAreaElement>
}
/>
)}
</div>
Expand Down Expand Up @@ -1006,6 +1038,15 @@ export function ConditionInput({
)
}
}}
onFocus={() => {
if (!isPreview && !disabled && block.value.trim() === '') {
setConditionalBlocks((blocks) =>
blocks.map((b) =>
b.id === block.id ? { ...b, showTags: true, cursorPosition: 0 } : b
)
)
}
}}
highlight={(codeToHighlight) => {
const placeholders: {
placeholder: string
Expand Down Expand Up @@ -1113,6 +1154,11 @@ export function ConditionInput({
)
)
}}
inputRef={
{
current: inputRefs.current.get(block.id) || null,
} as React.RefObject<HTMLTextAreaElement>
}
/>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ export function DocumentTagEntry({
onKeyDown={handlers.onKeyDown}
onDrop={handlers.onDrop}
onDragOver={handlers.onDragOver}
onFocus={handlers.onFocus}
onScroll={(e) => syncOverlayScroll(cellKey, e.currentTarget.scrollLeft)}
onPaste={() =>
setTimeout(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ export function EvalInput({
onKeyDown={handlers.onKeyDown}
onDrop={handlers.onDrop}
onDragOver={handlers.onDragOver}
onFocus={handlers.onFocus}
placeholder='How accurate is the response?'
disabled={isPreview || disabled}
className={cn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ function InputMappingField({
onKeyDown={handlers.onKeyDown}
onDrop={handlers.onDrop}
onDragOver={handlers.onDragOver}
onFocus={handlers.onFocus}
onScroll={(e) => handleScroll(e)}
onPaste={() =>
setTimeout(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ export function KnowledgeTagFilters({
onKeyDown={handlers.onKeyDown}
onDrop={handlers.onDrop}
onDragOver={handlers.onDragOver}
onFocus={handlers.onFocus}
onScroll={(e) => syncOverlayScroll(cellKey, e.currentTarget.scrollLeft)}
onPaste={() =>
setTimeout(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type React from 'react'
import {
useCallback,
useEffect,
Expand Down Expand Up @@ -159,6 +160,27 @@ export function LongInput({

const accessiblePrefixes = useAccessibleReferencePrefixes(blockId)

/**
* Callback to show tag dropdown when input is empty and focused
*/
const shouldForceTagDropdown = useCallback(
({
value,
}: {
value: string
cursor: number
event: 'focus'
}): { show: boolean } | undefined => {
if (isPreview || disabled) return { show: false }
// Show tag dropdown on focus when input is empty
if (value.trim() === '') {
return { show: true }
}
return { show: false }
},
[isPreview, disabled]
)

// During streaming, use local content; otherwise use the controller value
const value = useMemo(() => {
if (wandHook.isStreaming) return localContent
Expand Down Expand Up @@ -294,6 +316,7 @@ export function LongInput({
disabled={disabled}
isStreaming={wandHook.isStreaming}
previewValue={previewValue}
shouldForceTagDropdown={shouldForceTagDropdown}
>
{({ ref, onChange: handleChange, onKeyDown, onDrop, onDragOver, onFocus }) => {
const setRefs = (el: HTMLTextAreaElement | null) => {
Expand All @@ -303,7 +326,7 @@ export function LongInput({
return (
<div
ref={containerRef}
className={cn('group relative w-full', wandHook.isStreaming && 'streaming-effect')}
className='group relative w-full'
style={{ height: `${height}px` }}
>
<Textarea
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { RefObject } from 'react'
import { useCallback, useMemo, useRef, useState } from 'react'
import { createLogger } from '@sim/logger'
import { useParams } from 'next/navigation'
Expand Down Expand Up @@ -111,7 +112,14 @@ function McpInputWithTags({
data-lpignore='true'
data-1p-ignore
readOnly
onFocus={(e) => e.currentTarget.removeAttribute('readOnly')}
onFocus={(e) => {
e.currentTarget.removeAttribute('readOnly')
// Show tag dropdown on focus when input is empty
if (!disabled && (value?.trim() === '' || !value)) {
setShowTags(true)
setCursorPosition(0)
}
}}
className={cn(!isPassword && 'text-transparent caret-foreground')}
/>
{!isPassword && (
Expand All @@ -136,6 +144,7 @@ function McpInputWithTags({
setShowTags(false)
setActiveSourceBlockId(null)
}}
inputRef={inputRef as RefObject<HTMLInputElement>}
/>
</div>
)
Expand Down Expand Up @@ -225,6 +234,13 @@ function McpTextareaWithTags({
onChange={handleChange}
onDrop={handleDrop}
onDragOver={handleDragOver}
onFocus={() => {
// Show tag dropdown on focus when input is empty
if (!disabled && (value?.trim() === '' || !value)) {
setShowTags(true)
setCursorPosition(0)
}
}}
placeholder={placeholder}
disabled={disabled}
rows={rows}
Expand Down Expand Up @@ -254,6 +270,7 @@ function McpTextareaWithTags({
setShowTags(false)
setActiveSourceBlockId(null)
}}
inputRef={textareaRef as RefObject<HTMLTextAreaElement>}
/>
</div>
)
Expand Down
Loading