Skip to content

Commit 36c32ce

Browse files
committed
Updated env var page search field
1 parent 3ce3c17 commit 36c32ce

1 file changed

Lines changed: 61 additions & 53 deletions

File tree

  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.environment-variables

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.environment-variables/route.tsx

Lines changed: 61 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@ import {
44
BookOpenIcon,
55
InformationCircleIcon,
66
LockClosedIcon,
7-
MagnifyingGlassIcon,
87
PencilSquareIcon,
98
PlusIcon,
109
TrashIcon,
1110
} from "@heroicons/react/20/solid";
12-
import { Form, type MetaFunction, Outlet, useActionData, useFetcher, useNavigation, useRevalidator } from "@remix-run/react";
1311
import {
14-
type ActionFunctionArgs,
15-
type LoaderFunctionArgs,
16-
json,
17-
} from "@remix-run/server-runtime";
12+
Form,
13+
type MetaFunction,
14+
Outlet,
15+
useActionData,
16+
useFetcher,
17+
useNavigation,
18+
useRevalidator,
19+
} from "@remix-run/react";
20+
import { type ActionFunctionArgs, type LoaderFunctionArgs, json } from "@remix-run/server-runtime";
1821
import { useEffect, useMemo, useState } from "react";
1922
import { typedjson, useTypedLoaderData } from "remix-typedjson";
2023
import { z } from "zod";
@@ -30,9 +33,9 @@ import { Fieldset } from "~/components/primitives/Fieldset";
3033
import { FormButtons } from "~/components/primitives/FormButtons";
3134
import { FormError } from "~/components/primitives/FormError";
3235
import { Header2 } from "~/components/primitives/Headers";
33-
import { InfoPanel } from "~/components/primitives/InfoPanel";
3436
import { Input } from "~/components/primitives/Input";
3537
import { InputGroup } from "~/components/primitives/InputGroup";
38+
import { SearchInput } from "~/components/primitives/SearchInput";
3639
import { Label } from "~/components/primitives/Label";
3740
import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader";
3841
import { Paragraph } from "~/components/primitives/Paragraph";
@@ -50,6 +53,7 @@ import { SimpleTooltip } from "~/components/primitives/Tooltip";
5053
import { prisma } from "~/db.server";
5154
import { useEnvironment } from "~/hooks/useEnvironment";
5255
import { useFuzzyFilter } from "~/hooks/useFuzzyFilter";
56+
import { useSearchParams } from "~/hooks/useSearchParam";
5357
import { useOrganization } from "~/hooks/useOrganizations";
5458
import { useProject } from "~/hooks/useProject";
5559
import { redirectWithSuccessMessage } from "~/models/message.server";
@@ -76,7 +80,11 @@ import { UserAvatar } from "~/components/UserProfilePhoto";
7680
import { VercelIntegrationService } from "~/services/vercelIntegration.server";
7781
import { fromPromise } from "neverthrow";
7882
import { logger } from "~/services/logger.server";
79-
import { shouldSyncEnvVar, isPullEnvVarsEnabledForEnvironment, type TriggerEnvironmentType } from "~/v3/vercel/vercelProjectIntegrationSchema";
83+
import {
84+
shouldSyncEnvVar,
85+
isPullEnvVarsEnabledForEnvironment,
86+
type TriggerEnvironmentType,
87+
} from "~/v3/vercel/vercelProjectIntegrationSchema";
8088

8189
export const meta: MetaFunction = () => {
8290
return [
@@ -92,10 +100,11 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
92100

93101
try {
94102
const presenter = new EnvironmentVariablesPresenter();
95-
const { environmentVariables, environments, hasStaging, vercelIntegration } = await presenter.call({
96-
userId,
97-
projectSlug: projectParam,
98-
});
103+
const { environmentVariables, environments, hasStaging, vercelIntegration } =
104+
await presenter.call({
105+
userId,
106+
projectSlug: projectParam,
107+
});
99108

100109
return typedjson({
101110
environmentVariables,
@@ -123,7 +132,9 @@ const schema = z.discriminatedUnion("action", [
123132
action: z.literal("update-vercel-sync"),
124133
key: z.string(),
125134
environmentType: z.enum(["PRODUCTION", "STAGING", "PREVIEW", "DEVELOPMENT"]),
126-
syncEnabled: z.union([z.literal("true"), z.literal("false")]).transform((val) => val === "true"),
135+
syncEnabled: z
136+
.union([z.literal("true"), z.literal("false")])
137+
.transform((val) => val === "true"),
127138
}),
128139
]);
129140

@@ -249,15 +260,21 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
249260

250261
export default function Page() {
251262
const [revealAll, setRevealAll] = useState(false);
252-
const { environmentVariables, environments, vercelIntegration } = useTypedLoaderData<typeof loader>();
263+
const { environmentVariables, environments, vercelIntegration } =
264+
useTypedLoaderData<typeof loader>();
253265
const organization = useOrganization();
254266
const project = useProject();
255267
const environment = useEnvironment();
256-
const { filterText, setFilterText, filteredItems } =
257-
useFuzzyFilter<EnvironmentVariableWithSetValues>({
258-
items: environmentVariables,
259-
keys: ["key", "value", "environment.type", "environment.branchName"],
260-
});
268+
const { value } = useSearchParams();
269+
const urlSearch = value("search") ?? "";
270+
const { setFilterText, filteredItems } = useFuzzyFilter<EnvironmentVariableWithSetValues>({
271+
items: environmentVariables,
272+
keys: ["key", "value", "environment.type", "environment.branchName"],
273+
});
274+
275+
useEffect(() => {
276+
setFilterText(urlSearch);
277+
}, [urlSearch, setFilterText]);
261278

262279
// Add isFirst and isLast to each environment variable
263280
// They're set based on if they're the first or last time that `key` has been seen in the list
@@ -314,18 +331,10 @@ export default function Page() {
314331
<div className={cn("flex h-full flex-col")}>
315332
{environmentVariables.length > 0 && (
316333
<div className="flex items-center justify-between gap-2 px-2 py-2">
317-
<Input
318-
placeholder="Search variables"
319-
variant="tertiary"
320-
icon={MagnifyingGlassIcon}
321-
fullWidth={true}
322-
value={filterText}
323-
onChange={(e) => setFilterText(e.target.value)}
324-
autoFocus
325-
/>
326-
<div className="flex items-center justify-end gap-2">
334+
<SearchInput placeholder="Search variables…" autoFocus />
335+
<div className="flex items-center justify-end gap-1.5">
327336
<Switch
328-
variant="small"
337+
variant="secondary/small"
329338
label="Reveal values"
330339
checked={revealAll}
331340
onCheckedChange={(e) => setRevealAll(e.valueOf())}
@@ -351,7 +360,16 @@ export default function Page() {
351360
Value
352361
</TableHeaderCell>
353362
<TableHeaderCell className={vercelIntegration?.enabled ? "w-[13%]" : "w-[15%]"}>
354-
Environment
363+
<SimpleTooltip
364+
button={
365+
<span className="flex items-center gap-1">
366+
Environment
367+
<InformationCircleIcon className="size-4 text-text-dimmed" />
368+
</span>
369+
}
370+
content="Dev environment variables specified here will be overridden by ones in your .env file when running locally."
371+
className="max-w-60"
372+
/>
355373
</TableHeaderCell>
356374
{vercelIntegration?.enabled && (
357375
<TableHeaderCell className="w-[8%]">
@@ -458,10 +476,11 @@ export default function Page() {
458476
/>
459477
<span className="text-sm">{variable.updatedByUser.name}</span>
460478
</div>
461-
) : (variable.lastUpdatedBy?.type === "integration" && variable.lastUpdatedBy?.integration === 'vercel' ) ? (
479+
) : variable.lastUpdatedBy?.type === "integration" &&
480+
variable.lastUpdatedBy?.integration === "vercel" ? (
462481
<div className="flex items-center gap-2">
463-
<VercelLogo className="size-4 text-text-dimmed group-hover/table-row:text-text-bright transition-colors" />
464-
<span className="text-sm text-text-dimmed group-hover/table-row:text-text-bright capitalize transition-colors">
482+
<VercelLogo className="size-4 text-text-dimmed transition-colors group-hover/table-row:text-text-bright" />
483+
<span className="text-sm capitalize text-text-dimmed transition-colors group-hover/table-row:text-text-bright">
465484
{variable.lastUpdatedBy.integration}
466485
</span>
467486
</div>
@@ -475,7 +494,7 @@ export default function Page() {
475494
</TableCell>
476495
<TableCellMenu
477496
isSticky
478-
className="w-0 [&:has(.group-hover/table-row:block)]:w-auto"
497+
className="[&:has(.group-hover/table-row:block)]:w-auto w-0"
479498
hiddenButtons={
480499
<>
481500
<EditEnvironmentVariablePanel
@@ -514,13 +533,6 @@ export default function Page() {
514533
)}
515534
</TableBody>
516535
</Table>
517-
518-
<div className="-mt-px w-full border-t border-grid-dimmed">
519-
<InfoPanel icon={InformationCircleIcon} variant="minimal" panelClassName="max-w-fit">
520-
Dev environment variables specified here will be overridden by ones in your .env file
521-
when running locally.
522-
</InfoPanel>
523-
</div>
524536
</div>
525537
<Outlet />
526538
</PageBody>
@@ -561,9 +573,12 @@ function EditEnvironmentVariablePanel({
561573
return (
562574
<Dialog open={isOpen} onOpenChange={setIsOpen}>
563575
<DialogTrigger asChild>
564-
<Button variant="small-menu-item" LeadingIcon={PencilSquareIcon} fullWidth textAlignLeft>
565-
566-
</Button>
576+
<Button
577+
variant="small-menu-item"
578+
LeadingIcon={PencilSquareIcon}
579+
fullWidth
580+
textAlignLeft
581+
></Button>
567582
</DialogTrigger>
568583
<DialogContent>
569584
<DialogHeader>Edit environment variable</DialogHeader>
@@ -715,14 +730,7 @@ function VercelSyncCheckbox({
715730
if (!pullEnvVarsEnabledForEnv) {
716731
return (
717732
<SimpleTooltip
718-
button={
719-
<Switch
720-
variant="small"
721-
checked={false}
722-
disabled
723-
onCheckedChange={() => {}}
724-
/>
725-
}
733+
button={<Switch variant="small" checked={false} disabled onCheckedChange={() => {}} />}
726734
content="Enable 'Pull env vars before build' for this environment in Vercel settings."
727735
/>
728736
);

0 commit comments

Comments
 (0)