build / deployment env variable / secret selectors

This commit is contained in:
mbecker20
2024-06-14 23:28:08 -07:00
parent cc96d80c6a
commit f926932181
4 changed files with 129 additions and 198 deletions

View File

@@ -639,3 +639,68 @@ const default_registry_config = (
return { type, params: "" };
}
};
export const SecretSelector = ({
keys,
onSelect,
type,
disabled,
}: {
keys: string[];
onSelect: (key: string) => void;
type: "Variable" | "Secret";
disabled: boolean;
}) => {
const [open, setOpen] = useState(false);
const [search, setSearch] = useState("");
const filtered = filterBySplit(keys, search, (item) => item).sort((a, b) => {
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
});
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button variant="secondary" className="flex gap-2" disabled={disabled}>
<PlusCircle className="w-4 h-4" />
<div>Add {type}</div>
</Button>
</PopoverTrigger>
<PopoverContent className="w-[300px] max-h-[300px] p-0" align="start">
<Command shouldFilter={false}>
<CommandInput
placeholder={`Search ${type}s`}
className="h-9"
value={search}
onValueChange={setSearch}
/>
<CommandList>
<CommandEmpty className="flex justify-evenly items-center pt-2">
{`No ${type}s Found`}
<SearchX className="w-3 h-3" />
</CommandEmpty>
<CommandGroup>
{filtered.map((key) => (
<CommandItem
key={key}
onSelect={() => {
onSelect(key);
setOpen(false);
}}
className="flex items-center justify-between cursor-pointer"
>
<div className="p-1">{key}</div>
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
};

View File

@@ -5,6 +5,7 @@ import {
ConfigItem,
ImageRegistryConfig,
InputList,
SecretSelector,
SystemCommand,
} from "@components/config/util";
import { useRead, useWrite } from "@lib/hooks";
@@ -15,7 +16,6 @@ import { Textarea } from "@ui/textarea";
import { PlusCircle } from "lucide-react";
import { ReactNode, RefObject, createRef, useState } from "react";
import { CopyGithubWebhook, LabelsConfig, ResourceSelector } from "../common";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@ui/tabs";
export const BuildConfig = ({
id,
@@ -324,102 +324,36 @@ const Secrets = ({
if (variables.length === 0 && secrets.length === 0) return;
if (variables.length === 0) {
// ONLY SECRETS
return (
<div className="flex flex-col gap-2 w-full">
<h2 className="text-muted-foreground">Secrets</h2>
<div className="flex gap-4 items-center flex-wrap w-full">
{secrets.map((secret) => (
<Button
variant="secondary"
key={secret}
onClick={() =>
setArgs(
_args.slice(0, argsRef.current?.selectionStart) +
`[[${secret}]]` +
_args.slice(argsRef.current?.selectionStart, undefined)
)
}
>
{secret}
</Button>
))}
</div>
</div>
);
}
if (secrets.length === 0) {
// ONLY VARIABLES
return (
<div className="flex flex-col gap-2 w-full">
<h2 className="text-muted-foreground">Variables</h2>
<div className="flex gap-4 items-center flex-wrap w-full">
{variables.map(({ name }) => (
<Button
variant="secondary"
key={name}
onClick={() =>
setArgs(
_args.slice(0, argsRef.current?.selectionStart) +
`[[${name}]]` +
_args.slice(argsRef.current?.selectionStart, undefined)
)
}
>
{name}
</Button>
))}
</div>
</div>
);
}
return (
<Tabs className="w-full" defaultValue="Variables">
<TabsList>
<TabsTrigger value="Variables">Variables</TabsTrigger>
<TabsTrigger value="Secrets">Secrets</TabsTrigger>
</TabsList>
<TabsContent value="Variables">
<div className="flex gap-4 items-center w-full flex-wrap pt-1">
{variables.map(({ name }) => (
<Button
variant="secondary"
key={name}
onClick={() =>
setArgs(
_args.slice(0, argsRef.current?.selectionStart) +
`[[${name}]]` +
_args.slice(argsRef.current?.selectionStart, undefined)
)
}
>
{name}
</Button>
))}
</div>
</TabsContent>
<TabsContent value="Secrets">
<div className="flex gap-4 items-center w-full flex-wrap pt-1">
{secrets.map((secret) => (
<Button
variant="secondary"
key={secret}
onClick={() =>
setArgs(
_args.slice(0, argsRef.current?.selectionStart) +
`[[${secret}]]` +
_args.slice(argsRef.current?.selectionStart, undefined)
)
}
>
{secret}
</Button>
))}
</div>
</TabsContent>
</Tabs>
<div className="flex items-center gap-2">
{variables.length > 0 && (
<SecretSelector
type="Variable"
keys={variables.map((v) => v.name)}
onSelect={(variable) =>
setArgs(
_args.slice(0, argsRef.current?.selectionStart) +
`[[${variable}]]` +
_args.slice(argsRef.current?.selectionStart, undefined)
)
}
disabled={false}
/>
)}
{secrets.length > 0 && (
<SecretSelector
type="Secret"
keys={secrets}
onSelect={(secret) =>
setArgs(
_args.slice(0, argsRef.current?.selectionStart) +
`[[${secret}]]` +
_args.slice(argsRef.current?.selectionStart, undefined)
)
}
disabled={false}
/>
)}
</div>
);
};

View File

@@ -402,4 +402,4 @@ export const ServerSelector = ({
align={align}
/>
</ConfigItem>
);
);

View File

@@ -1,8 +1,6 @@
import { ConfigItem } from "@components/config/util";
import { ConfigItem, SecretSelector } from "@components/config/util";
import { useRead } from "@lib/hooks";
import { Types } from "@monitor/client";
import { Button } from "@ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@ui/tabs";
import { Textarea } from "@ui/textarea";
import { RefObject, createRef } from "react";
@@ -22,7 +20,7 @@ export const EnvVars = ({
const setEnv = (environment: string) => set({ environment });
return (
<ConfigItem className="flex-col gap-4 items-start">
<ConfigItem className="flex-col gap-2 items-start">
{!disabled && server && (
<Secrets server={server} env={env} setEnv={setEnv} envRef={ref} />
)}
@@ -65,102 +63,36 @@ const Secrets = ({
if (variables.length === 0 && secrets.length === 0) return;
if (variables.length === 0) {
// ONLY SECRETS
return (
<div className="flex flex-col gap-2 w-full">
<h2 className="text-muted-foreground">Secrets</h2>
<div className="flex gap-4 items-center flex-wrap w-full">
{secrets.map((secret) => (
<Button
variant="secondary"
key={secret}
onClick={() =>
setEnv(
_env.slice(0, envRef.current?.selectionStart) +
`[[${secret}]]` +
_env.slice(envRef.current?.selectionStart, undefined)
)
}
>
{secret}
</Button>
))}
</div>
</div>
);
}
if (secrets.length === 0) {
// ONLY VARIABLES
return (
<div className="flex flex-col gap-2 w-full">
<h2 className="text-muted-foreground">Variables</h2>
<div className="flex gap-4 items-center flex-wrap w-full">
{variables.map(({ name }) => (
<Button
variant="secondary"
key={name}
onClick={() =>
setEnv(
_env.slice(0, envRef.current?.selectionStart) +
`[[${name}]]` +
_env.slice(envRef.current?.selectionStart, undefined)
)
}
>
{name}
</Button>
))}
</div>
</div>
);
}
return (
<Tabs className="w-full" defaultValue="Variables">
<TabsList>
<TabsTrigger value="Variables">Variables</TabsTrigger>
<TabsTrigger value="Secrets">Secrets</TabsTrigger>
</TabsList>
<TabsContent value="Variables">
<div className="flex gap-4 items-center w-full flex-wrap pt-1">
{variables.map(({ name }) => (
<Button
variant="secondary"
key={name}
onClick={() =>
setEnv(
_env.slice(0, envRef.current?.selectionStart) +
`[[${name}]]` +
_env.slice(envRef.current?.selectionStart, undefined)
)
}
>
{name}
</Button>
))}
</div>
</TabsContent>
<TabsContent value="Secrets">
<div className="flex gap-4 items-center w-full flex-wrap pt-1">
{secrets.map((secret) => (
<Button
variant="secondary"
key={secret}
onClick={() =>
setEnv(
_env.slice(0, envRef.current?.selectionStart) +
`[[${secret}]]` +
_env.slice(envRef.current?.selectionStart, undefined)
)
}
>
{secret}
</Button>
))}
</div>
</TabsContent>
</Tabs>
<div className="flex items-center gap-2">
{variables.length > 0 && (
<SecretSelector
type="Variable"
keys={variables.map((v) => v.name)}
onSelect={(variable) =>
setEnv(
_env.slice(0, envRef.current?.selectionStart) +
`[[${variable}]]` +
_env.slice(envRef.current?.selectionStart, undefined)
)
}
disabled={false}
/>
)}
{secrets.length > 0 && (
<SecretSelector
type="Secret"
keys={secrets}
onSelect={(secret) =>
setEnv(
_env.slice(0, envRef.current?.selectionStart) +
`[[${secret}]]` +
_env.slice(envRef.current?.selectionStart, undefined)
)
}
disabled={false}
/>
)}
</div>
);
};