diff --git a/.claude/rules/sim-imports.md b/.claude/rules/sim-imports.md index 3aeafa0dd2e..6757ecc1d43 100644 --- a/.claude/rules/sim-imports.md +++ b/.claude/rules/sim-imports.md @@ -13,8 +13,8 @@ paths: ```typescript // ✓ Good +import { Chip } from '@sim/emcn' import { useWorkflowStore } from '@/stores/workflows/store' -import { Button } from '@/components/ui/button' // ✗ Bad import { useWorkflowStore } from '../../../stores/workflows/store' diff --git a/.cursor/rules/sim-imports.mdc b/.cursor/rules/sim-imports.mdc index 19da378bccf..95d111c7747 100644 --- a/.cursor/rules/sim-imports.mdc +++ b/.cursor/rules/sim-imports.mdc @@ -13,8 +13,8 @@ globs: ["apps/sim/**/*.ts","apps/sim/**/*.tsx"] ```typescript // ✓ Good +import { Chip } from '@sim/emcn' import { useWorkflowStore } from '@/stores/workflows/store' -import { Button } from '@/components/ui/button' // ✗ Bad import { useWorkflowStore } from '../../../stores/workflows/store' diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/code/code.test.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/code/code.test.tsx index fe74a0467e4..76a6ab1dc66 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/code/code.test.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/code/code.test.tsx @@ -20,6 +20,13 @@ const { SECRET, searchTargetRef } = vi.hoisted(() => ({ })) vi.mock('@sim/emcn', () => ({ + Chip: ({ + onClick, + disabled, + 'aria-label': label, + }: React.ButtonHTMLAttributes) => ( + , -})) - vi.mock('next/navigation', () => ({ useParams: () => ({ workspaceId: 'workspace-1' }), })) @@ -254,3 +257,25 @@ describe('Code password masking', () => { expect(highlighted()).toContain(SECRET_MATCH) }) }) + +describe('Code copy action', () => { + it('copies the current value through the shared chip action', () => { + const writeText = vi.fn().mockResolvedValue(undefined) + vi.stubGlobal('navigator', { clipboard: { writeText } }) + vi.useFakeTimers() + act(() => + root.render( + + ) + ) + act(() => container.querySelector('button[aria-label="Copy code"]')!.click()) + expect(writeText).toHaveBeenCalledExactlyOnceWith(SECRET) + act(() => vi.advanceTimersByTime(2000)) + vi.useRealTimers() + }) +}) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/code/code.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/code/code.tsx index e4fe0f53f44..191fa72fb71 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/code/code.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/code/code.tsx @@ -1,6 +1,7 @@ import type { ReactElement } from 'react' import { memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react' import { + Chip, CODE_LINE_HEIGHT_PX, Code as CodeEditor, calculateGutterWidth, @@ -10,11 +11,10 @@ import { highlight, languages, } from '@sim/emcn' -import { Check, Wand } from '@sim/emcn/icons' +import { Check } from '@sim/emcn/icons' import { createLogger } from '@sim/logger' import { useParams } from 'next/navigation' import Editor from 'react-simple-code-editor' -import { Button } from '@/components/ui/button' import { CodeLanguage } from '@/lib/execution/languages' import { isLikelyReferenceSegment, @@ -43,6 +43,7 @@ import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/c import type { WandControlHandlers } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block' import { useActiveSearchTarget } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/providers/active-search-target-provider' import { restoreCursorAfterInsertion } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/utils' +import { WandButton } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/wand-prompt-bar/wand-button' import { WandPromptBar } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/wand-prompt-bar/wand-prompt-bar' import { useAccessibleReferencePrefixes } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes' import { useWand } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-wand' @@ -906,22 +907,12 @@ export const Code = memo(function Code({ return ( <> {showCopyButton && code && ( - + /> )} {!hideInternalWand && ( - - + /> )} diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/long-input/long-input.test.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/long-input/long-input.test.tsx index 9585aa4c5d0..8f3b40f5cd8 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/long-input/long-input.test.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/long-input/long-input.test.tsx @@ -10,6 +10,13 @@ const { SECRET, searchTargetRef } = vi.hoisted(() => ({ })) vi.mock('@sim/emcn', () => ({ + Chip: ({ + onClick, + disabled, + 'aria-label': label, + }: React.ButtonHTMLAttributes) => ( +