1+ import { Editor as MonacoEditor } from "@monaco-editor/react" ;
2+ import {
3+ CheckIcon ,
4+ ChevronDownIcon ,
5+ CopyIcon ,
6+ FileJsonIcon ,
7+ SettingsIcon ,
8+ ZapIcon ,
9+ } from "lucide-react" ;
10+ import { type FC , useEffect , useState } from "react" ;
111import { Button } from "@/client/components/Button" ;
212import {
313 DropdownMenu ,
@@ -13,71 +23,50 @@ import {
1323 TooltipContent ,
1424 TooltipTrigger ,
1525} from "@/client/components/Tooltip" ;
26+ import { useEditor } from "@/client/contexts/editor" ;
1627import { useTheme } from "@/client/contexts/theme" ;
17- import { multiSelect , radio , switchInput , textInput } from "@/client/snippets" ;
18- import type { ParameterFormType } from "@/gen/types" ;
28+ import { type SnippetFunc , snippets } from "@/client/snippets" ;
29+ import type { ParameterWithSource } from "@/gen/types" ;
1930import { cn } from "@/utils/cn" ;
20- import { Editor as MonacoEditor } from "@monaco-editor/react" ;
21- import {
22- CheckIcon ,
23- ChevronDownIcon ,
24- CopyIcon ,
25- FileJsonIcon ,
26- RadioIcon ,
27- SettingsIcon ,
28- SquareMousePointerIcon ,
29- TextCursorInputIcon ,
30- ToggleLeftIcon ,
31- ZapIcon ,
32- } from "lucide-react" ;
33- import { type FC , useEffect , useRef , useState } from "react" ;
34- import { useEditor } from "@/client/contexts/editor" ;
3531
3632type EditorProps = {
3733 code : string ;
3834 setCode : React . Dispatch < React . SetStateAction < string > > ;
35+ parameters : ParameterWithSource [ ] ;
3936} ;
4037
41- export const Editor : FC < EditorProps > = ( { code, setCode } ) => {
38+ export const Editor : FC < EditorProps > = ( { code, setCode, parameters } ) => {
4239 const { appliedTheme } = useTheme ( ) ;
4340 const editorRef = useEditor ( ) ;
4441
45- const [ codeCopied , setCodeCopied ] = useState ( ( ) => false ) ;
46- const copyTimeoutId = useRef < ReturnType < typeof setTimeout > | undefined > (
47- undefined ,
48- ) ;
49-
5042 const [ tab , setTab ] = useState ( ( ) => "code" ) ;
5143
44+ const [ codeCopied , setCodeCopied ] = useState ( ( ) => false ) ;
45+
5246 const onCopy = ( ) => {
5347 navigator . clipboard . writeText ( code ) ;
5448 setCodeCopied ( ( ) => true ) ;
5549 } ;
5650
57- const onAddSnippet = ( formType : ParameterFormType ) => {
58- if ( formType === "input" ) {
59- setCode ( `${ code . trimEnd ( ) } \n\n${ textInput } \n` ) ;
60- } else if ( formType === "radio" ) {
61- setCode ( `${ code . trimEnd ( ) } \n\n${ radio } \n` ) ;
62- } else if ( formType === "multi-select" ) {
63- setCode ( `${ code . trimEnd ( ) } \n\n${ multiSelect } \n` ) ;
64- } else if ( formType === "switch" ) {
65- setCode ( `${ code . trimEnd ( ) } \n\n${ switchInput } \n` ) ;
66- }
51+ const onAddSnippet = ( name : string , snippet : SnippetFunc ) => {
52+ const nameCount = parameters . filter ( ( p ) => p . name . startsWith ( name ) ) . length ;
53+
54+ const nextInOrder = 1 + Math . max ( 0 , ...parameters . map ( ( p ) => p . order ) ) ;
55+ const newName = nameCount > 0 ? `${ name } -${ nameCount } ` : name ;
56+ const newSnippet = snippet ( newName , nextInOrder ) ;
57+ setCode ( `${ code . trimEnd ( ) } \n\n${ newSnippet } \n` ) ;
6758 } ;
6859
6960 useEffect ( ( ) => {
7061 if ( ! codeCopied ) {
7162 return ;
7263 }
7364
74- clearTimeout ( copyTimeoutId . current ) ;
75-
76- copyTimeoutId . current = setTimeout ( ( ) => {
65+ const copyTimeoutId = setTimeout ( ( ) => {
7766 setCodeCopied ( ( ) => false ) ;
7867 } , 1000 ) ;
7968
80- return ( ) => clearTimeout ( copyTimeoutId . current ) ;
69+ return ( ) => clearTimeout ( copyTimeoutId ) ;
8170 } , [ codeCopied ] ) ;
8271
8372 return (
@@ -116,23 +105,17 @@ export const Editor: FC<EditorProps> = ({ code, setCode }) => {
116105
117106 < DropdownMenuPortal >
118107 < DropdownMenuContent align = "start" >
119- < DropdownMenuItem onClick = { ( ) => onAddSnippet ( "input" ) } >
120- < TextCursorInputIcon width = { 24 } height = { 24 } />
121- Text input
122- </ DropdownMenuItem >
123- < DropdownMenuItem
124- onClick = { ( ) => onAddSnippet ( "multi-select" ) }
125- >
126- < SquareMousePointerIcon width = { 24 } height = { 24 } />
127- Multi-select
128- </ DropdownMenuItem >
129- < DropdownMenuItem onClick = { ( ) => onAddSnippet ( "radio" ) } >
130- < RadioIcon width = { 24 } height = { 24 } />
131- Radio
132- </ DropdownMenuItem >
133- < DropdownMenuItem onClick = { ( ) => onAddSnippet ( "switch" ) } >
134- < ToggleLeftIcon width = { 24 } height = { 24 } /> Switches
135- </ DropdownMenuItem >
108+ { snippets . map (
109+ ( { name, label, icon : Icon , snippet } , index ) => (
110+ < DropdownMenuItem
111+ key = { index }
112+ onClick = { ( ) => onAddSnippet ( name , snippet ) }
113+ >
114+ < Icon size = { 24 } />
115+ { label }
116+ </ DropdownMenuItem >
117+ ) ,
118+ ) }
136119 </ DropdownMenuContent >
137120 </ DropdownMenuPortal >
138121 </ DropdownMenu >
0 commit comments