Skip to content
Open
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
86 changes: 42 additions & 44 deletions src/renderer/components/shared/settings/SettingsModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
Expand Down Expand Up @@ -67,65 +66,64 @@ export const SettingsModal = () => {
<FiSettings className="ml-2 text-xl" />
</DialogTrigger>

<DialogContent className="flex h-[80vh] max-w-4xl flex-col p-0 lg:max-w-5xl">
<div className="flex h-full flex-col">
<DialogContent className="flex h-[82vh] max-w-5xl flex-col overflow-hidden rounded-2xl border border-[#2a2a2a] bg-[#1a1a1a] p-0 text-white shadow-[0_20px_80px_rgba(0,0,0,0.65)]">
<Tabs defaultValue="variables" className="flex min-h-0 flex-1 flex-col">
{/* Header - Fixed */}
<div className="shrink-0 px-4 pt-4">
<div className="shrink-0 border-b border-[#2a2a2a] bg-[#222222] px-6 pt-5 pb-3">
<DialogHeader>
<DialogTitle className="font-bold">Collection Settings</DialogTitle>
<DialogTitle className="text-[20px] font-bold text-white">
Collection Settings
</DialogTitle>
</DialogHeader>
<TabsList className="mt-5 flex gap-3 bg-transparent p-0">
<TabsTrigger
value="variables"
className="rounded-full px-5 py-[8px] text-[14px] font-medium text-[#999999] transition-all data-[state=active]:bg-[#163840] data-[state=active]:text-[#50daf0] data-[state=active]:shadow-none"
>
Variables
</TabsTrigger>
<TabsTrigger
value="environments"
className="rounded-full px-5 py-[8px] text-[14px] font-medium text-[#999999] transition-all data-[state=active]:bg-[#163840] data-[state=active]:text-[#50daf0] data-[state=active]:shadow-none"
>
Environments
</TabsTrigger>
</TabsList>
</div>

{/* Tabs - Takes remaining space */}
<Tabs defaultValue="variables" className="flex min-h-0 flex-1 flex-col">
<div className="shrink-0 px-4 py-4">
<TabsList className="bg-background">
<TabsTrigger value="variables" className="font-light!">
Variables
</TabsTrigger>
<TabsTrigger value="environments" className="font-light!">
Environments
</TabsTrigger>
</TabsList>
</div>

<TabsContent value="variables" className="m-0 min-h-0 flex-1 p-0">
<div className="h-full overflow-y-auto p-4">
<VariableEditor
variables={editorVariables}
onValidChange={setValid}
onVariablesChange={setEditorVariables}
/>
</div>
</TabsContent>
<TabsContent value="variables" className="m-0 min-h-0 flex-1 p-0">
<div className="h-full overflow-y-auto bg-[#111111] pt-4 pb-6">
<VariableEditor
variables={editorVariables}
onValidChange={setValid}
onVariablesChange={setEditorVariables}
/>
</div>
</TabsContent>

<TabsContent value="environments" className="m-0 min-h-0 flex-1 p-0">
<TabsContent value="environments" className="m-0 min-h-0 flex-1 p-0">
<div className="h-full overflow-y-auto bg-[#111111] pt-4 pb-6">
<EnvironmentEditor
environments={editorEnvironments}
selectedEnvironment={editorSelectedEnvironment}
onEnvironmentsChange={setEditorEnvironments}
onEnvironmentSelect={setEditorSelectedEnvironment}
onValidChange={setEnvironmentValid}
/>
</TabsContent>
</Tabs>

{/* Footer - Fixed */}
<DialogFooter className="shrink-0 p-4">
<div className="flex gap-2">
<Button onClick={() => setOpen(false)} variant="outline">
<span className="leading-4 font-bold">Cancel</span>
</Button>
<Button
onClick={save}
disabled={!isOverallValid}
variant={isOverallValid ? 'default' : 'defaultDisable'}
>
<span className="leading-4 font-bold">Save</span>
</Button>
</div>
</DialogFooter>
</div>
</TabsContent>
<div className="flex shrink-0 justify-end bg-[#111111] px-6 pt-4 pb-6">
<Button
onClick={save}
disabled={!isOverallValid}
className="h-[50px] rounded-full bg-[#7cc8df] px-5 text-[14px] font-semibold text-black shadow-sm transition-all hover:bg-[#8fd5ea] active:scale-[0.98] disabled:bg-[#2a2a2a] disabled:text-[#666]"
>
Save
</Button>
</div>
</Tabs>
</DialogContent>
</Dialog>
);
Expand Down
148 changes: 82 additions & 66 deletions src/renderer/components/shared/settings/VariableTab/VariableEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,80 +78,96 @@ export const VariableEditor = memo<VariableEditorProps>(
return (
<>
<Button
className="h-fit gap-1 pl-0 hover:bg-transparent"
className="mx-6 flex h-9 items-center gap-2 text-[#e8e8e8] hover:bg-transparent hover:text-white"
size="sm"
variant="ghost"
onClick={add}
>
<AddIcon /> Add Variable
<AddIcon className="h-4 w-4" />
<span className="text-[15px] font-medium">Add Variable</span>
</Button>

<Divider className="mb-4" />
<div className="mx-6 mt-1 border-b border-[#2a2a2a]" />

<Table className="w-full table-auto">
<TableHeader>
<TableRow>
<TableHead className="w-1/5">Key</TableHead>
<TableHead className="w-1/4">Value</TableHead>
<TableHead className="w-auto">Description</TableHead>
<TableHead className="w-20">Secret</TableHead>
<TableHead className="w-16">{/* Action Column */}</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{variables.map((variable, index) => (
<TableRow key={index}>
<TableCell className="break-all">
<input
type="text"
value={variable.key}
className={cn('w-full bg-transparent outline-hidden', {
'text-danger': invalidVariableKeys.has(variable.key),
})}
placeholder="Enter variable key"
onChange={(e) => update(index, { key: e.target.value })}
/>
</TableCell>
<TableCell className="break-all">
<SecretInput
secret={variable.secret}
value={variable.value}
className={cn('w-full border-none bg-transparent outline-hidden', {
'text-danger': invalidVariableKeys.has(variable.key),
})}
placeholder="Enter variable value"
onChange={(e) => update(index, { value: e.target.value })}
/>
</TableCell>
<TableCell className="break-all">
<input
type="text"
value={variable.description}
className="w-full bg-transparent outline-hidden"
placeholder="Enter variable description"
onChange={(e) => update(index, { description: e.target.value })}
/>
</TableCell>
<TableCell className="text-center">
<Checkbox
checked={variable.secret}
onCheckedChange={(checked) => update(index, { secret: Boolean(checked) })}
/>
</TableCell>
<TableCell className="py-2 text-center">
<Button
variant="ghost"
size="icon"
className="hover:text-accent-primary active:text-accent-secondary w-5 hover:bg-transparent"
onClick={() => remove(index)}
>
<Trash2 />
</Button>
</TableCell>
<div className="mx-6 mt-4 overflow-hidden rounded-xl border border-[#2a2a2a] bg-[#111111]">
<Table className="w-full table-auto border-separate border-spacing-0 border-none">
<TableHeader className="bg-[#161616] [&_tr]:border-0">
<TableRow className="hover:bg-transparent">
<TableHead className="w-1/5 rounded-tl-xl border-r border-b border-[#2a2a2a] py-3 text-[14px] font-medium text-[#ffffff]">
Key
</TableHead>
<TableHead className="w-1/4 border-r border-b border-[#2a2a2a] text-[14px] font-medium text-[#ffffff]">
Value
</TableHead>
<TableHead className="w-auto border-r border-b border-[#2a2a2a] text-[14px] font-medium text-[#ffffff]">
Description
</TableHead>
<TableHead className="w-24 border-r border-b border-[#2a2a2a] text-center text-[14px] font-medium text-[#ffffff]">
Secret
</TableHead>
<TableHead className="w-14 rounded-tr-xl border-b border-[#2a2a2a]">
{/* Action Column */}
</TableHead>
</TableRow>
))}
</TableBody>
</Table>
</TableHeader>
<TableBody>
{variables.map((variable, index) => (
<TableRow
key={index}
className="border-b border-[#2a2a2a] transition-colors last:border-0 hover:bg-[#1a1a1a]"
>
<TableCell className="border-r border-[#2a2a2a] px-4 py-3">
<input
type="text"
value={variable.key}
className={cn(
'w-full bg-transparent text-[14px] text-[#e8e8e8] outline-none placeholder:text-[#9a9a9a]',
invalidVariableKeys.has(variable.key) && 'text-red-500'
)}
placeholder="Enter variable key"
onChange={(e) => update(index, { key: e.target.value })}
/>
</TableCell>
<TableCell className="border-r border-[#2a2a2a] px-4">
<SecretInput
secret={variable.secret}
value={variable.value}
className="w-full border-none bg-transparent text-[14px] text-[#e8e8e8] outline-none placeholder:text-[#9a9a9a]"
placeholder="Enter variable value"
onChange={(e) => update(index, { value: e.target.value })}
/>
</TableCell>
<TableCell className="border-r border-[#2a2a2a] px-4">
<input
type="text"
value={variable.description}
className="w-full bg-transparent text-[14px] text-[#a8a8a8] outline-none placeholder:text-[#9a9a9a]"
placeholder="Enter variable description"
onChange={(e) => update(index, { description: e.target.value })}
/>
</TableCell>
<TableCell className="border-r border-[#2a2a2a] text-center">
<Checkbox
className="cursor-pointer border-[#6a6a6a] transition-colors hover:border-white data-[state=checked]:border-white data-[state=checked]:bg-white"
checked={variable.secret}
onCheckedChange={(checked) => update(index, { secret: Boolean(checked) })}
/>
</TableCell>
<TableCell className="text-center">
<Button
variant="ghost"
size="icon"
className="text-[#cfcfcf] transition-colors hover:bg-transparent hover:text-[#ff6b6b]"
onClick={() => remove(index)}
>
<Trash2 size={18} />
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</>
);
}
Expand Down
24 changes: 16 additions & 8 deletions src/renderer/components/ui/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import { cn } from '@/lib/utils';

const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(
({ className, ...props }, ref) => (
<div className={`relative rounded-(--radius) border`}>
<table ref={ref} className={cn('w-full caption-bottom text-sm', className)} {...props} />
<div className="relative w-full overflow-auto">
<table
ref={ref}
className={cn('w-full caption-bottom border-collapse text-sm', className)}
{...props}
/>
</div>
)
);
Expand All @@ -15,15 +19,19 @@ const TableHeader = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} />
<thead ref={ref} className={cn('[&_tr]:border-none', className)} {...props} />
));
TableHeader.displayName = 'TableHeader';

const TableBody = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tbody ref={ref} className={cn('[&_tr:last-child]:border-0', className)} {...props} />
<tbody
ref={ref}
className={cn('bg-[#111111] [&_tr:last-child]:border-0', className)}
{...props}
/>
));
TableBody.displayName = 'TableBody';

Expand All @@ -33,7 +41,7 @@ const TableFooter = React.forwardRef<
>(({ className, ...props }, ref) => (
<tfoot
ref={ref}
className={cn('bg-muted/50 border-t font-medium last:[&>tr]:border-b-0', className)}
className={cn('border-t bg-[#111111] font-medium last:[&>tr]:border-b-0', className)}
{...props}
/>
));
Expand All @@ -44,7 +52,7 @@ const TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTML
<tr
ref={ref}
className={cn(
'hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors',
'bg-[#111111] transition-colors duration-100 hover:bg-[#151515] data-[state=selected]:bg-[#191919]',
className
)}
{...props}
Expand All @@ -60,7 +68,7 @@ const TableHead = React.forwardRef<
<th
ref={ref}
className={cn(
'border-border text-muted-foreground h-12 px-4 text-left align-middle font-medium not-last:border-r [&:has([role=checkbox])]:pr-0',
'h-11 border-b bg-[#111111] px-4 text-left align-middle font-semibold text-[#e6e6e6]',
className
)}
{...props}
Expand All @@ -75,7 +83,7 @@ const TableCell = React.forwardRef<
<td
ref={ref}
className={cn(
'overflow-wrap break-word border-border p-4 align-middle break-all not-last:border-r',
'border-b border-[#2a2a2a] bg-[#111111] px-4 py-3 align-middle break-all text-[#e8e8e8] [&:not(:last-child)]:border-r',
className
)}
{...props}
Expand Down