Skip to content

Commit 54bccff

Browse files
committed
Unordered list component
1 parent 91ab04b commit 54bccff

File tree

5 files changed

+229
-16
lines changed

5 files changed

+229
-16
lines changed

apps/webapp/app/components/errors/ConfigureErrorAlerts.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { Input } from "~/components/primitives/Input";
2222
import { InputGroup } from "~/components/primitives/InputGroup";
2323
import { Paragraph } from "~/components/primitives/Paragraph";
2424
import { Select, SelectItem } from "~/components/primitives/Select";
25+
import { UnorderedList } from "~/components/primitives/UnorderedList";
2526
import type { ErrorAlertChannelData } from "~/presenters/v3/ErrorAlertChannelPresenter.server";
2627
import { useOptimisticLocation } from "~/hooks/useOptimisticLocation";
2728
import { cn } from "~/utils/cn";
@@ -100,7 +101,7 @@ export function ConfigureErrorAlerts({
100101
const webhookFields = useFieldList(form.ref, webhooks);
101102

102103
return (
103-
<div className="flex h-full flex-col overflow-hidden border-l border-grid-bright">
104+
<div className="grid h-full grid-rows-[auto_1fr_auto] overflow-hidden">
104105
<div className="flex items-center justify-between border-b border-grid-bright px-4 py-3">
105106
<Header2>Configure alerts</Header2>
106107
<LinkButton
@@ -113,20 +114,20 @@ export function ConfigureErrorAlerts({
113114
/>
114115
</div>
115116

116-
<div className="flex-1 overflow-y-auto">
117+
<div className="flex-1 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
117118
<fetcher.Form method="post" {...form.props}>
118-
<Fieldset className="p-4">
119-
<Paragraph variant="small" className="text-text-dimmed">
120-
You'll receive alerts when:
121-
</Paragraph>
122-
<ul className="list-disc space-y-1 pl-5 text-xs text-text-dimmed">
123-
<li>A new issue is seen for the first time</li>
124-
<li>A resolved issue re-occurs</li>
125-
<li>An ignored issue re-occurs depending on the settings you configured</li>
126-
</ul>
119+
<Fieldset className="flex flex-col gap-3 p-4">
120+
<div className="flex flex-col">
121+
<Paragraph variant="small/dimmed">You'll receive alerts when</Paragraph>
122+
<UnorderedList variant="small/dimmed" className="mt-1">
123+
<li>An error is seen for the first time</li>
124+
<li>A resolved error re-occurs</li>
125+
<li>An ignored error re-occurs based on settings you configured</li>
126+
</UnorderedList>
127+
</div>
127128

128129
{/* Email section */}
129-
<div className="mt-6">
130+
<div>
130131
<Header3 className="mb-3 flex items-center gap-1.5">
131132
<EnvelopeIcon className="size-4 text-text-dimmed" />
132133
Email
@@ -162,7 +163,7 @@ export function ConfigureErrorAlerts({
162163
</div>
163164

164165
{/* Slack section */}
165-
<div className="mt-6">
166+
<div>
166167
<Header3 className="mb-3 flex items-center gap-1.5">
167168
<SlackIcon className="size-4" />
168169
Slack
@@ -270,7 +271,7 @@ export function ConfigureErrorAlerts({
270271
</div>
271272

272273
{/* Webhook section */}
273-
<div className="mt-6">
274+
<div>
274275
<Header3 className="mb-3 flex items-center gap-1.5">
275276
<GlobeAltIcon className="size-4 text-text-dimmed" />
276277
Webhook
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import { cn } from "~/utils/cn";
2+
import { type ParagraphVariant } from "./Paragraph";
3+
4+
const listVariants: Record<
5+
ParagraphVariant,
6+
{ text: string; spacing: string; items: string }
7+
> = {
8+
base: {
9+
text: "font-sans text-base font-normal text-text-dimmed",
10+
spacing: "mb-3",
11+
items: "space-y-1 [&>li]:gap-1.5",
12+
},
13+
"base/bright": {
14+
text: "font-sans text-base font-normal text-text-bright",
15+
spacing: "mb-3",
16+
items: "space-y-1 [&>li]:gap-1.5",
17+
},
18+
small: {
19+
text: "font-sans text-sm font-normal text-text-dimmed",
20+
spacing: "mb-2",
21+
items: "space-y-0.5 [&>li]:gap-1",
22+
},
23+
"small/bright": {
24+
text: "font-sans text-sm font-normal text-text-bright",
25+
spacing: "mb-2",
26+
items: "space-y-0.5 [&>li]:gap-1",
27+
},
28+
"small/dimmed": {
29+
text: "font-sans text-sm font-normal text-text-dimmed",
30+
spacing: "mb-2",
31+
items: "space-y-0.5 [&>li]:gap-1",
32+
},
33+
"extra-small": {
34+
text: "font-sans text-xs font-normal text-text-dimmed",
35+
spacing: "mb-1.5",
36+
items: "space-y-0.5 [&>li]:gap-1",
37+
},
38+
"extra-small/bright": {
39+
text: "font-sans text-xs font-normal text-text-bright",
40+
spacing: "mb-1.5",
41+
items: "space-y-0.5 [&>li]:gap-1",
42+
},
43+
"extra-small/dimmed": {
44+
text: "font-sans text-xs font-normal text-text-dimmed",
45+
spacing: "mb-1.5",
46+
items: "space-y-0.5 [&>li]:gap-1",
47+
},
48+
"extra-small/dimmed/mono": {
49+
text: "font-mono text-xs font-normal text-text-dimmed",
50+
spacing: "mb-1.5",
51+
items: "space-y-0.5 [&>li]:gap-1",
52+
},
53+
"extra-small/mono": {
54+
text: "font-mono text-xs font-normal text-text-dimmed",
55+
spacing: "mb-1.5",
56+
items: "space-y-0.5 [&>li]:gap-1",
57+
},
58+
"extra-small/bright/mono": {
59+
text: "font-mono text-xs text-text-bright",
60+
spacing: "mb-1.5",
61+
items: "space-y-0.5 [&>li]:gap-1",
62+
},
63+
"extra-small/caps": {
64+
text: "font-sans text-xs uppercase tracking-wider font-normal text-text-dimmed",
65+
spacing: "mb-1.5",
66+
items: "space-y-0.5 [&>li]:gap-1",
67+
},
68+
"extra-small/bright/caps": {
69+
text: "font-sans text-xs uppercase tracking-wider font-normal text-text-bright",
70+
spacing: "mb-1.5",
71+
items: "space-y-0.5 [&>li]:gap-1",
72+
},
73+
"extra-extra-small": {
74+
text: "font-sans text-xxs font-normal text-text-dimmed",
75+
spacing: "mb-1",
76+
items: "space-y-0.5 [&>li]:gap-0.5",
77+
},
78+
"extra-extra-small/bright": {
79+
text: "font-sans text-xxs font-normal text-text-bright",
80+
spacing: "mb-1",
81+
items: "space-y-0.5 [&>li]:gap-0.5",
82+
},
83+
"extra-extra-small/caps": {
84+
text: "font-sans text-xxs uppercase tracking-wider font-normal text-text-dimmed",
85+
spacing: "mb-1",
86+
items: "space-y-0.5 [&>li]:gap-0.5",
87+
},
88+
"extra-extra-small/bright/caps": {
89+
text: "font-sans text-xxs uppercase tracking-wider font-normal text-text-bright",
90+
spacing: "mb-1",
91+
items: "space-y-0.5 [&>li]:gap-0.5",
92+
},
93+
"extra-extra-small/dimmed/caps": {
94+
text: "font-sans text-xxs uppercase tracking-wider font-normal text-text-dimmed",
95+
spacing: "mb-1",
96+
items: "space-y-0.5 [&>li]:gap-0.5",
97+
},
98+
};
99+
100+
type UnorderedListProps = {
101+
variant?: ParagraphVariant;
102+
className?: string;
103+
spacing?: boolean;
104+
children: React.ReactNode;
105+
} & React.HTMLAttributes<HTMLUListElement>;
106+
107+
export function UnorderedList({
108+
variant = "base",
109+
className,
110+
spacing = false,
111+
children,
112+
...props
113+
}: UnorderedListProps) {
114+
const v = listVariants[variant];
115+
return (
116+
<ul
117+
className={cn(
118+
"list-none [&>li]:flex [&>li]:items-baseline [&>li]:before:shrink-0 [&>li]:before:content-['•']",
119+
v.text,
120+
v.items,
121+
spacing && v.spacing,
122+
className
123+
)}
124+
{...props}
125+
>
126+
{children}
127+
</ul>
128+
);
129+
}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors._index/route.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import * as Ariakit from "@ariakit/react";
22
import { BellAlertIcon, XMarkIcon } from "@heroicons/react/20/solid";
3-
import { Form, type MetaFunction } from "@remix-run/react";
3+
import { Form, type MetaFunction, useRevalidator } from "@remix-run/react";
44
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
55
import { type ErrorGroupStatus } from "@trigger.dev/database";
66
import { IconBugFilled } from "@tabler/icons-react";
77
import { ErrorId } from "@trigger.dev/core/v3/isomorphic";
8-
import { Suspense, useMemo, type ReactNode } from "react";
8+
import { Suspense, useCallback, useMemo, type ReactNode } from "react";
99
import {
1010
Bar,
1111
BarChart,
@@ -49,6 +49,7 @@ import {
4949
import TooltipPortal from "~/components/primitives/TooltipPortal";
5050
import { appliedSummary, FilterMenuProvider, TimeFilter } from "~/components/runs/v3/SharedFilters";
5151
import { $replica } from "~/db.server";
52+
import { useInterval } from "~/hooks/useInterval";
5253
import { useOptimisticLocation } from "~/hooks/useOptimisticLocation";
5354
import { useSearchParams } from "~/hooks/useSearchParam";
5455
import { findProjectBySlug } from "~/models/project.server";
@@ -175,6 +176,17 @@ export default function Page() {
175176
envParam,
176177
} = useTypedLoaderData<typeof loader>();
177178

179+
const revalidator = useRevalidator();
180+
useInterval({
181+
interval: 60_000,
182+
onLoad: false,
183+
callback: useCallback(() => {
184+
if (revalidator.state === "idle") {
185+
revalidator.revalidate();
186+
}
187+
}, [revalidator]),
188+
});
189+
178190
const location = useOptimisticLocation();
179191
const showAlerts = new URLSearchParams(location.search).has("alerts");
180192
const alertsHref = useMemo(() => {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { Header2 } from "~/components/primitives/Headers";
2+
import { Paragraph, type ParagraphVariant } from "~/components/primitives/Paragraph";
3+
import { UnorderedList } from "~/components/primitives/UnorderedList";
4+
5+
const sampleItems = [
6+
"A new issue is seen for the first time",
7+
"A resolved issue re-occurs",
8+
"An ignored issue re-occurs depending on the settings you configured",
9+
];
10+
11+
const variantGroups: { label: string; variants: ParagraphVariant[] }[] = [
12+
{
13+
label: "Base",
14+
variants: ["base", "base/bright"],
15+
},
16+
{
17+
label: "Small",
18+
variants: ["small", "small/bright", "small/dimmed"],
19+
},
20+
{
21+
label: "Extra small",
22+
variants: [
23+
"extra-small",
24+
"extra-small/bright",
25+
"extra-small/dimmed",
26+
"extra-small/mono",
27+
"extra-small/bright/mono",
28+
"extra-small/dimmed/mono",
29+
"extra-small/caps",
30+
"extra-small/bright/caps",
31+
],
32+
},
33+
{
34+
label: "Extra extra small",
35+
variants: [
36+
"extra-extra-small",
37+
"extra-extra-small/bright",
38+
"extra-extra-small/caps",
39+
"extra-extra-small/bright/caps",
40+
"extra-extra-small/dimmed/caps",
41+
],
42+
},
43+
];
44+
45+
export default function Story() {
46+
return (
47+
<div className="flex flex-col gap-12 p-8">
48+
{variantGroups.map((group) => (
49+
<div key={group.label} className="flex flex-col gap-6">
50+
<Header2>{group.label}</Header2>
51+
{group.variants.map((variant) => (
52+
<div key={variant} className="flex flex-col">
53+
<code className="mb-2 font-mono text-xs text-charcoal-400">{variant}</code>
54+
<Paragraph variant={variant}>This is a paragraph before the list.</Paragraph>
55+
<UnorderedList variant={variant}>
56+
{sampleItems.map((item) => (
57+
<li key={item}>{item}</li>
58+
))}
59+
</UnorderedList>
60+
<Paragraph variant={variant}>This is a paragraph after the list.</Paragraph>
61+
</div>
62+
))}
63+
</div>
64+
))}
65+
</div>
66+
);
67+
}

apps/webapp/app/routes/storybook/route.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ const stories: Story[] = [
136136
name: "Typography",
137137
slug: "typography",
138138
},
139+
{
140+
name: "Unordered list",
141+
slug: "unordered-list",
142+
},
139143
{
140144
name: "Usage",
141145
slug: "usage",

0 commit comments

Comments
 (0)