Skip to content

Commit

Permalink
feat(hub): actors and builds filters
Browse files Browse the repository at this point in the history
  • Loading branch information
jog1t committed Jan 18, 2025
1 parent 52b8aad commit 2c837f4
Show file tree
Hide file tree
Showing 24 changed files with 520 additions and 164 deletions.
8 changes: 6 additions & 2 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@
"sdks/api/**",
"*.lock",
"resources/**",
"packages/**",
"site/framer/**",
"**/out/**"
"**/out/**",
"packages/infra/**",
"packages/common/**",
"packages/api/**",
"packages/services/**",
"packages/toolchain/**"
],
"ignoreUnknown": true
},
Expand Down
1 change: 1 addition & 0 deletions externals/cloudflare-rs
Submodule cloudflare-rs added at f14720
1 change: 1 addition & 0 deletions externals/deno
Submodule deno added at bd9856
1 change: 1 addition & 0 deletions externals/nomad-client
Submodule nomad-client added at abb66b
1 change: 1 addition & 0 deletions externals/posthog-rs
Submodule posthog-rs added at ef4e80
1 change: 1 addition & 0 deletions externals/redis-rs
Submodule redis-rs added at ac3e27
1 change: 1 addition & 0 deletions externals/rivet-term
Submodule rivet-term added at d539a0
1 change: 1 addition & 0 deletions externals/serde_array_query
Submodule serde_array_query added at b9f8bf
1 change: 1 addition & 0 deletions externals/sqlx
Submodule sqlx added at e7120f
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import * as ActorsFiltersForm from "@/domains/project/forms/actors-filters-form";
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
SheetTrigger,
Skeleton,
} from "@rivet-gg/components";
import { type ReactNode, Suspense } from "react";

interface ActorsFiltersSheetProps {
title: string;
children?: ReactNode;
projectId: string;
environmentId: string;
onFiltersSubmitted: (values: ActorsFiltersForm.FormValues) => void;
tags: Record<string, string>;
showDestroyed: boolean;
}

export function ActorsFiltersSheet({
title,
children,
projectId,
environmentId,
tags,
showDestroyed,
onFiltersSubmitted,
}: ActorsFiltersSheetProps) {
return (
<Sheet>
<SheetTrigger asChild>{children}</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>{title}</SheetTitle>
<SheetDescription>
Filter actors by tags and status.
</SheetDescription>
<div className="flex gap-4 flex-col">
<Suspense
fallback={
<>
<Skeleton className="w-full h-8" />
<Skeleton className="w-full h-8" />
<Skeleton className="w-full h-8" />
<Skeleton className="w-full h-8" />
</>
}
>
<ActorsFiltersForm.Form
onSubmit={onFiltersSubmitted}
defaultValues={{
tags: {},
showDestroyed: false,
}}
values={{ tags, showDestroyed }}
>
<ActorsFiltersForm.Tags
projectId={projectId}
environmentId={environmentId}
/>
<ActorsFiltersForm.ShowDestroyed />
<div className="flex gap-2 mt-4 items-center justify-end">
<ActorsFiltersForm.Submit disablePristine>
Apply
</ActorsFiltersForm.Submit>

<ActorsFiltersForm.Reset
variant="outline"
type="button"
onClick={() => {
onFiltersSubmitted({
tags: {},
showDestroyed: false,
});
}}
>
Reset
</ActorsFiltersForm.Reset>
</div>
</ActorsFiltersForm.Form>
</Suspense>
</div>
</SheetHeader>
</SheetContent>
</Sheet>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,25 @@ interface ActorsListPanelProps {
projectNameId: string;
environmentNameId: string;
actorId: string | undefined;
tags: Record<string, string>;
showDestroyed: boolean;
}

export function ActorsListPanel({
actorId,
projectNameId,
environmentNameId,
tags,
showDestroyed,
}: ActorsListPanelProps) {
const { data, hasNextPage, isFetchingNextPage, fetchNextPage } =
useSuspenseInfiniteQuery(
projectActorsQueryOptions({ projectNameId, environmentNameId }),
projectActorsQueryOptions({
projectNameId,
environmentNameId,
includeDestroyed: showDestroyed,
tags,
}),
);
return (
<ScrollArea className="overflow-auto h-full truncate min-w-0">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ interface ActorsListPreview {
projectNameId: string;
environmentNameId: string;
actorId?: string;
tags: Record<string, string>;
showDestroyed: boolean;
}

export function ActorsListPreview({
projectNameId,
environmentNameId,
actorId,
tags,
showDestroyed,
}: ActorsListPreview) {
const isMd = useBreakpoint("md");

Expand All @@ -33,6 +37,8 @@ export function ActorsListPreview({
projectNameId={projectNameId}
environmentNameId={environmentNameId}
actorId={actorId}
tags={tags}
showDestroyed={showDestroyed}
/>
</div>
</ResizablePanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ interface TagsSelectProps {
environmentId: string;
value: Record<string, string>;
onValueChange: (value: Record<string, string>) => void;
showSelectedOptions?: number;
}

export function TagsSelect({
projectId,
environmentId,
value,
onValueChange,
showSelectedOptions,
}: TagsSelectProps) {
const { data } = useSuspenseQuery(
actorBuildTagsQueryOptions({ projectId, environmentId }),
Expand Down Expand Up @@ -60,7 +62,12 @@ export function TagsSelect({
options={tags}
value={val}
onValueChange={handleValueChange}
className="w-full"
showSelectedOptions={showSelectedOptions}
filter={(option, search) =>
option.tag.key.includes(search) ||
option.tag.value.includes(search)
}
className="w-full min-w-[20rem]"
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import {
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
createSchemaForm,
} from "@rivet-gg/components";
import { Switch } from "@rivet-gg/components";
import { type UseFormReturn, useFormContext } from "react-hook-form";
import z from "zod";
import { TagsSelect } from "../components/tags-select";

const allowedTypes = ["image/png", "image/jpeg"];

export const formSchema = z.object({
tags: z.record(z.string()),
showDestroyed: z.boolean().default(false),
});

export type FormValues = z.infer<typeof formSchema>;
export type SubmitHandler = (
values: FormValues,
form: UseFormReturn<FormValues>,
) => Promise<void>;

const { Form, Submit, Reset } = createSchemaForm(formSchema);
export { Form, Submit, Reset };

export const Tags = ({
projectId,
environmentId,
}: { projectId: string; environmentId: string }) => {
const { control } = useFormContext<FormValues>();
return (
<FormField
control={control}
name="tags"
render={({ field }) => (
<FormItem>
<FormLabel>Tags</FormLabel>
<FormControl>
<TagsSelect
value={field.value}
projectId={projectId}
environmentId={environmentId}
onValueChange={field.onChange}
showSelectedOptions={1}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
);
};

export function ShowDestroyed() {
const { control } = useFormContext<FormValues>();
return (
<FormField
control={control}
name="showDestroyed"
render={({ field }) => (
<FormItem className="space-y-0">
<div className="flex justify-between items-center">
<FormLabel>Show destroyed?</FormLabel>
<FormControl>
<Switch
className="mt-0"
{...field}
checked={field.value}
onCheckedChange={field.onChange}
value="show-destroyed"
/>
</FormControl>
</div>
<FormMessage />
</FormItem>
)}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,37 @@ import {
export const projectActorsQueryOptions = ({
projectNameId,
environmentNameId,
}: { projectNameId: string; environmentNameId: string }) => {
includeDestroyed,
tags,
}: {
projectNameId: string;
environmentNameId: string;
includeDestroyed?: boolean;
tags?: Record<string, string>;
}) => {
return infiniteQueryOptions({
queryKey: [
"project",
projectNameId,
"environment",
environmentNameId,
"actors",
],
{ includeDestroyed, tags },
] as const,
refetchInterval: 5000,
initialPageParam: "",
queryFn: ({
signal: abortSignal,
pageParam,
queryKey: [_, project, __, environment],
queryKey: [, project, , environment, , { includeDestroyed, tags }],
}) =>
rivetClient.actor.list(
{
project,
environment,
includeDestroyed: true,
includeDestroyed,
cursor: pageParam ? pageParam : undefined,
tagsJson: JSON.stringify(tags),
},
{ abortSignal },
),
Expand Down
Loading

0 comments on commit 2c837f4

Please sign in to comment.