@@ -4,14 +4,10 @@ import {
44ChevronDownIcon ,
55CopyIcon ,
66FileJsonIcon ,
7- RadioIcon ,
8- SquareMousePointerIcon ,
9- TextCursorInputIcon ,
10- ToggleLeftIcon ,
117UsersIcon ,
128ZapIcon ,
139} from "lucide-react" ;
14- import { type FC , useEffect , useRef , useState } from "react" ;
10+ import { type FC , useEffect , useState } from "react" ;
1511import { Button } from "@/client/components/Button" ;
1612import {
1713DropdownMenu ,
@@ -25,8 +21,8 @@ import * as Tabs from "@/client/components/Tabs";
2521import { useEditor } from "@/client/contexts/editor" ;
2622import { useTheme } from "@/client/contexts/theme" ;
2723import { Users } from "@/client/editor/Users" ;
28- import { multiSelect , radio , switchInput , textInput } from "@/client/snippets" ;
29- import type { ParameterFormType } from "@/gen/types" ;
24+ import { type SnippetFunc , snippets } from "@/client/snippets" ;
25+ import type { ParameterWithSource } from "@/gen/types" ;
3026import type { User } from "@/user" ;
3127import { cn } from "@/utils/cn" ;
3228
@@ -35,53 +31,47 @@ type EditorProps = {
3531setCode : React . Dispatch < React . SetStateAction < string > > ;
3632users : User [ ] ;
3733setUsers : ( owners : User [ ] ) => void ;
34+ parameters : ParameterWithSource [ ] ;
3835} ;
3936
4037export const Editor : FC < EditorProps > = ( {
4138code,
4239setCode,
43- users : owners ,
44- setUsers : setOwners ,
40+ users,
41+ setUsers,
42+ parameters,
4543} ) => {
4644const { appliedTheme } = useTheme ( ) ;
4745const editorRef = useEditor ( ) ;
4846
49- const [ codeCopied , setCodeCopied ] = useState ( ( ) => false ) ;
50- const copyTimeoutId = useRef < ReturnType < typeof setTimeout > | undefined > (
51- undefined ,
52- ) ;
53-
5447const [ tab , setTab ] = useState ( ( ) => "code" ) ;
5548
49+ const [ codeCopied , setCodeCopied ] = useState ( ( ) => false ) ;
50+
5651const onCopy = ( ) => {
5752navigator . clipboard . writeText ( code ) ;
5853setCodeCopied ( ( ) => true ) ;
5954} ;
6055
61- const onAddSnippet = ( formType : ParameterFormType ) => {
62- if ( formType === "input" ) {
63- setCode ( `${ code . trimEnd ( ) } \n\n${ textInput } \n` ) ;
64- } else if ( formType === "radio" ) {
65- setCode ( `${ code . trimEnd ( ) } \n\n${ radio } \n` ) ;
66- } else if ( formType === "multi-select" ) {
67- setCode ( `${ code . trimEnd ( ) } \n\n${ multiSelect } \n` ) ;
68- } else if ( formType === "switch" ) {
69- setCode ( `${ code . trimEnd ( ) } \n\n${ switchInput } \n` ) ;
70- }
56+ const onAddSnippet = ( name : string , snippet : SnippetFunc ) => {
57+ const nameCount = parameters . filter ( ( p ) => p . name . startsWith ( name ) ) . length ;
58+
59+ const nextInOrder = 1 + Math . max ( 0 , ...parameters . map ( ( p ) => p . order ) ) ;
60+ const newName = nameCount > 0 ? `${ name } -${ nameCount } ` : name ;
61+ const newSnippet = snippet ( newName , nextInOrder ) ;
62+ setCode ( `${ code . trimEnd ( ) } \n\n${ newSnippet } \n` ) ;
7163} ;
7264
7365useEffect ( ( ) => {
7466if ( ! codeCopied ) {
7567return ;
7668}
7769
78- clearTimeout ( copyTimeoutId . current ) ;
79-
80- copyTimeoutId . current = setTimeout ( ( ) => {
70+ const copyTimeoutId = setTimeout ( ( ) => {
8171setCodeCopied ( ( ) => false ) ;
8272} , 1000 ) ;
8373
84- return ( ) => clearTimeout ( copyTimeoutId . current ) ;
74+ return ( ) => clearTimeout ( copyTimeoutId ) ;
8575} , [ codeCopied ] ) ;
8676
8777return (
@@ -110,23 +100,17 @@ export const Editor: FC<EditorProps> = ({
110100
111101< DropdownMenuPortal >
112102< DropdownMenuContent align = "start" >
113- < DropdownMenuItem onClick = { ( ) => onAddSnippet ( "input" ) } >
114- < TextCursorInputIcon width = { 24 } height = { 24 } />
115- Text input
116- </ DropdownMenuItem >
117- < DropdownMenuItem
118- onClick = { ( ) => onAddSnippet ( "multi-select" ) }
119- >
120- < SquareMousePointerIcon width = { 24 } height = { 24 } />
121- Multi-select
122- </ DropdownMenuItem >
123- < DropdownMenuItem onClick = { ( ) => onAddSnippet ( "radio" ) } >
124- < RadioIcon width = { 24 } height = { 24 } />
125- Radio
126- </ DropdownMenuItem >
127- < DropdownMenuItem onClick = { ( ) => onAddSnippet ( "switch" ) } >
128- < ToggleLeftIcon width = { 24 } height = { 24 } /> Switches
129- </ DropdownMenuItem >
103+ { snippets . map (
104+ ( { name, label, icon : Icon , snippet } , index ) => (
105+ < DropdownMenuItem
106+ key = { index }
107+ onClick = { ( ) => onAddSnippet ( name , snippet ) }
108+ >
109+ < Icon size = { 24 } />
110+ { label }
111+ </ DropdownMenuItem >
112+ ) ,
113+ ) }
130114</ DropdownMenuContent >
131115</ DropdownMenuPortal >
132116</ DropdownMenu >
@@ -183,7 +167,7 @@ export const Editor: FC<EditorProps> = ({
183167</ Tabs . Content >
184168
185169< Tabs . Content value = "users" asChild = { true } >
186- < Users setUsers = { setOwners } users = { owners } />
170+ < Users setUsers = { setUsers } users = { users } />
187171</ Tabs . Content >
188172</ ResizablePanel >
189173</ Tabs . Root >
0 commit comments