1
1
"use client"
2
2
3
- import { useId } from "react"
3
+ import { useId , useState } from "react"
4
4
import { SelectApp , SelectComponent } from "@pipedream/connect-react"
5
5
import {
6
6
Tooltip ,
7
7
TooltipContent ,
8
8
TooltipProvider ,
9
9
TooltipTrigger ,
10
10
} from "@/components/ui/tooltip"
11
+ import {
12
+ Collapsible ,
13
+ CollapsibleContent ,
14
+ CollapsibleTrigger ,
15
+ } from "@/components/ui/collapsible"
11
16
import { useAppState } from "@/lib/app-state"
12
17
import { cn } from "@/lib/utils"
13
18
import Select from "react-select"
14
19
import { ScrollArea } from "@/components/ui/scroll-area"
15
20
import { enableDebugging } from "@/lib/query-params"
16
- import { IoCubeSharp , IoFlashOutline } from "react-icons/io5"
21
+ import { IoCubeSharp , IoFlashOutline , IoChevronDown , IoSettingsOutline } from "react-icons/io5"
17
22
18
23
function getTypeDescription ( prop : {
19
24
name : string
@@ -114,7 +119,7 @@ const PropertyItem = ({
114
119
} )
115
120
116
121
return (
117
- < div className = "grid grid-cols-[180px_1fr ] gap-4 items-center py-2 pl-4 pr-2 hover:bg-zinc-50/50" >
122
+ < div className = "grid grid-cols-[120px_1fr ] gap-3 items-center py-2 pl-4 pr-2 hover:bg-zinc-50/50" >
118
123
< div className = "flex items-center" >
119
124
< TooltipProvider delayDuration = { 0 } >
120
125
< Tooltip >
@@ -227,6 +232,7 @@ export const ConfigPanel = () => {
227
232
} = useAppState ( )
228
233
const id1 = useId ( ) ;
229
234
const id2 = useId ( ) ;
235
+ const [ showAdvanced , setShowAdvanced ] = useState ( false ) ;
230
236
231
237
const isValidWebhookUrl = ( ) => {
232
238
if ( ! webhookUrl ) {
@@ -242,7 +248,8 @@ export const ConfigPanel = () => {
242
248
}
243
249
244
250
245
- const formControls = (
251
+ // Basic configuration options (always visible)
252
+ const basicFormControls = (
246
253
< div className = "divide-y" >
247
254
< PropertyItem
248
255
name = "componentType"
@@ -279,15 +286,36 @@ export const ConfigPanel = () => {
279
286
</ div >
280
287
</ PropertyItem >
281
288
< PropertyItem
282
- name = "userId "
289
+ name = "app "
283
290
type = "string"
284
- description = "Authenticated user identifier "
291
+ description = "App to connect to "
285
292
required = { true }
286
293
>
287
- < input
288
- value = { userId || "" }
289
- className = "w-full px-3 py-1.5 text-sm font-mono border rounded bg-zinc-50/50"
290
- readOnly
294
+ < SelectApp
295
+ value = { selectedApp }
296
+ onChange = { ( app ) => {
297
+ app
298
+ ? setSelectedAppSlug ( app . name_slug )
299
+ : removeSelectedAppSlug ( )
300
+ } }
301
+ />
302
+ </ PropertyItem >
303
+ < PropertyItem
304
+ name = { selectedComponentType === "action" ? "actionId" : "triggerId" }
305
+ type = "string"
306
+ description = { `${ selectedComponentType === "action" ? "Action" : "Trigger" } to use` }
307
+ required = { true }
308
+ >
309
+ < SelectComponent
310
+ app = { selectedApp }
311
+ componentType = { selectedComponentType }
312
+ value = { selectedComponent }
313
+ onChange = { ( comp ) => {
314
+ comp
315
+ ? setSelectedComponentKey ( comp . key )
316
+ : removeSelectedComponentKey ( )
317
+
318
+ } }
291
319
/>
292
320
</ PropertyItem >
293
321
{ selectedComponentType === "trigger" && (
@@ -307,33 +335,23 @@ export const ConfigPanel = () => {
307
335
/>
308
336
</ PropertyItem >
309
337
) }
338
+ </ div >
339
+ )
340
+
341
+ // Advanced configuration options (collapsible)
342
+ const advancedFormControls = (
343
+ < div className = "divide-y" >
310
344
< PropertyItem
311
- name = "componentKey "
345
+ name = "userId "
312
346
type = "string"
313
- description = "Unique identifier for the component to be rendered "
347
+ description = "Authenticated user identifier "
314
348
required = { true }
315
349
>
316
- < div className = "grid grid-cols-2 gap-1" >
317
- < SelectApp
318
- value = { selectedApp }
319
- onChange = { ( app ) => {
320
- app
321
- ? setSelectedAppSlug ( app . name_slug )
322
- : removeSelectedAppSlug ( )
323
- } }
324
- />
325
- < SelectComponent
326
- app = { selectedApp }
327
- componentType = { selectedComponentType }
328
- value = { selectedComponent }
329
- onChange = { ( comp ) => {
330
- comp
331
- ? setSelectedComponentKey ( comp . key )
332
- : removeSelectedComponentKey ( )
333
-
334
- } }
335
- />
336
- </ div >
350
+ < input
351
+ value = { userId || "" }
352
+ className = "w-full px-3 py-1.5 text-sm font-mono border rounded bg-zinc-50/50"
353
+ readOnly
354
+ />
337
355
</ PropertyItem >
338
356
< PropertyItem
339
357
name = "hideOptionalProps"
@@ -442,7 +460,6 @@ export const ConfigPanel = () => {
442
460
onChange = { ( v ) => {
443
461
if ( v ) {
444
462
setCustomizationOption ( v )
445
- setFileCode ( undefined )
446
463
}
447
464
} }
448
465
getOptionValue = { ( o ) => o . name }
@@ -454,53 +471,79 @@ export const ConfigPanel = () => {
454
471
} }
455
472
/>
456
473
</ PropertyItem >
457
- { selectedComponentType === "trigger" && (
458
- < div className = "bg-sky-100/50 backdrop-blur-xl border rounded border-neutral-200/50 px-4 py-2 mb-10 m-4 shadow-sm" >
459
- < div className = "text-sm text-neutral-700 leading-relaxed" >
460
- < p className = "py-2 flex gap-2" >
461
- { /* <BsInfoCircleFill className="h-4 w-4 text-neutral-500 flex-shrink-0 mt-1" /> */ }
462
- < span >
463
- When you deploy a trigger via the Pipedream components API, we'll emit events to a{ ' ' }
464
- < code className = "font-mono mx-1" > webhookUrl</ code > that you define. To test your trigger:
465
- </ span >
466
- </ p >
467
- < ol className = "list-decimal list-outside ml-6 space-y-2" >
468
- < li className = "pl-2" >
469
- Configure the trigger and define a < code className = "font-mono text-sm" > webhookUrl</ code > to receive events (use a{ ' ' }
470
- < a
471
- href = "https://pipedream.com/new?h=tch_BXfkaA"
472
- target = "_blank"
473
- rel = "noopener noreferrer"
474
- className = "font-medium text-sky-800 hover:text-sky-900 hover:underline transition-colors"
475
- >
476
- RequestBin
477
- </ a >
478
- { ' ' } for example)
479
- </ li >
480
- < li className = "pl-2" >
481
- Click < span className = "font-semibold" > Submit</ span > on the right (may take up to a minute, but can happen asynchronously in your app)
482
- </ li >
483
- < li className = "pl-2" >
484
- Generate some actual events in the relevant app and check your webhook for emitted events.
485
- </ li >
486
- </ ol >
487
- </ div >
488
- </ div >
489
- ) }
474
+ </ div >
475
+ )
476
+
477
+ const triggerInfo = selectedComponentType === "trigger" && (
478
+ < div className = "bg-sky-100/50 backdrop-blur-xl border rounded border-neutral-200/50 px-4 py-2 mb-10 m-4 shadow-sm hidden md:block" >
479
+ < div className = "text-sm text-neutral-700 leading-relaxed" >
480
+ < p className = "py-2 flex gap-2" >
481
+ { /* <BsInfoCircleFill className="h-4 w-4 text-neutral-500 flex-shrink-0 mt-1" /> */ }
482
+ < span >
483
+ When you deploy a trigger via the Pipedream components API, we'll emit events to a{ ' ' }
484
+ < code className = "font-mono mx-1" > webhookUrl</ code > that you define. To test your trigger:
485
+ </ span >
486
+ </ p >
487
+ < ol className = "list-decimal list-outside ml-6 space-y-2" >
488
+ < li className = "pl-2" >
489
+ Configure the trigger and define a < code className = "font-mono text-sm" > webhookUrl</ code > to receive events (use a{ ' ' }
490
+ < a
491
+ href = "https://pipedream.com/new?h=tch_BXfkaA"
492
+ target = "_blank"
493
+ rel = "noopener noreferrer"
494
+ className = "font-medium text-sky-800 hover:text-sky-900 hover:underline transition-colors"
495
+ >
496
+ RequestBin
497
+ </ a >
498
+ { ' ' } for example)
499
+ </ li >
500
+ < li className = "pl-2" >
501
+ Click < span className = "font-semibold" > Submit</ span > on the right (may take up to a minute, but can happen asynchronously in your app)
502
+ </ li >
503
+ < li className = "pl-2" >
504
+ Generate some actual events in the relevant app and check your webhook for emitted events.
505
+ </ li >
506
+ </ ol >
507
+ </ div >
490
508
</ div >
491
509
)
492
510
493
511
return (
494
512
< div className = "flex flex-col min-h-0 h-full" >
495
- < div className = "px-6 py-4 border-b bg-white" >
513
+ < div className = "px-4 md:px- 6 py-4 border-b bg-white" >
496
514
< h2 className = "text-lg font-semibold text-gray-900" > Demo Configuration</ h2 >
497
515
< p className = "text-sm text-gray-500 mt-1" >
498
516
Configure the component demo settings
499
517
</ p >
500
518
</ div >
501
519
< ScrollArea className = "flex-1 min-h-0" >
502
- < div className = "px-6 py-4" >
503
- { formControls }
520
+ < div className = "px-4 md:px-6 py-4" >
521
+ { /* Basic configuration - always visible */ }
522
+ { basicFormControls }
523
+
524
+ { /* Advanced configuration - collapsible on mobile */ }
525
+ < div className = "mt-4" >
526
+ < Collapsible open = { showAdvanced } onOpenChange = { setShowAdvanced } >
527
+ < CollapsibleTrigger className = "flex items-center justify-between w-full py-2 px-3 text-xs font-medium text-neutral-500 hover:text-neutral-600 hover:bg-neutral-25 rounded border border-neutral-150 md:hidden" >
528
+ < div className = "flex items-center gap-2" >
529
+ < IoSettingsOutline className = "h-3 w-3" />
530
+ Advanced Configuration
531
+ </ div >
532
+ < IoChevronDown className = { cn ( "h-3 w-3 transition-transform" , showAdvanced && "rotate-180" ) } />
533
+ </ CollapsibleTrigger >
534
+
535
+ { /* Always show on desktop, collapsible on mobile */ }
536
+ < div className = "hidden md:block" >
537
+ { advancedFormControls }
538
+ </ div >
539
+
540
+ < CollapsibleContent className = "md:hidden" >
541
+ { advancedFormControls }
542
+ </ CollapsibleContent >
543
+ </ Collapsible >
544
+ </ div >
545
+
546
+ { triggerInfo }
504
547
</ div >
505
548
</ ScrollArea >
506
549
</ div >
0 commit comments