Skip to content

Commit dc24731

Browse files
samejrmatt-aitken
authored andcommitted
UI improvements to the Configure alerts feature
1 parent dcd9b4c commit dc24731

File tree

3 files changed

+59
-50
lines changed
  • apps/webapp/app
    • components/errors
    • routes
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors._index
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors

3 files changed

+59
-50
lines changed

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

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import type { ErrorAlertChannelData } from "~/presenters/v3/ErrorAlertChannelPre
2828
import { useOptimisticLocation } from "~/hooks/useOptimisticLocation";
2929
import { cn } from "~/utils/cn";
3030
import { ExitIcon } from "~/assets/icons/ExitIcon";
31+
import { BellAlertIcon } from "@heroicons/react/24/solid";
3132

3233
export const ErrorAlertsFormSchema = z.object({
3334
emails: z.preprocess((i) => {
@@ -115,7 +116,9 @@ export function ConfigureErrorAlerts({
115116
return (
116117
<div className="grid h-full grid-rows-[auto_1fr_auto] overflow-hidden">
117118
<div className="flex items-center justify-between border-b border-grid-bright px-3 py-2">
118-
<Header2>Configure alerts</Header2>
119+
<Header2 className="flex items-center gap-2">
120+
<BellAlertIcon className="size-5 text-alerts" /> Configure alerts
121+
</Header2>
119122
<LinkButton
120123
to={closeHref}
121124
variant="minimal/small"
@@ -128,9 +131,9 @@ export function ConfigureErrorAlerts({
128131

129132
<div className="flex-1 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
130133
<fetcher.Form method="post" action={formAction} {...form.props}>
131-
<Fieldset className="flex flex-col gap-3 p-4">
134+
<Fieldset className="flex flex-col gap-4 p-4">
132135
<div className="flex flex-col">
133-
<Paragraph variant="small/dimmed">You'll receive alerts when</Paragraph>
136+
<Header3>Receive alerts when</Header3>
134137
<UnorderedList variant="small/dimmed" className="mt-1">
135138
<li>An error is seen for the first time</li>
136139
<li>A resolved error re-occurs</li>
@@ -140,10 +143,7 @@ export function ConfigureErrorAlerts({
140143

141144
{/* Email section */}
142145
<div>
143-
<Header3 className="mb-3 flex items-center gap-1.5">
144-
<EnvelopeIcon className="size-4 text-text-dimmed" />
145-
Email
146-
</Header3>
146+
<Header3 className="mb-1">Email</Header3>
147147
{emailAlertsEnabled ? (
148148
<InputGroup>
149149
{emailFields.map((emailField, index) => (
@@ -176,10 +176,7 @@ export function ConfigureErrorAlerts({
176176

177177
{/* Slack section */}
178178
<div>
179-
<Header3 className="mb-3 flex items-center gap-1.5">
180-
<SlackIcon className="size-4" />
181-
Slack
182-
</Header3>
179+
<Header3 className="mb-1">Slack</Header3>
183180
<InputGroup fullWidth>
184181
{slack.status === "READY" ? (
185182
<>
@@ -284,10 +281,7 @@ export function ConfigureErrorAlerts({
284281

285282
{/* Webhook section */}
286283
<div>
287-
<Header3 className="mb-3 flex items-center gap-1.5">
288-
<GlobeAltIcon className="size-4 text-text-dimmed" />
289-
Webhook
290-
</Header3>
284+
<Header3 className="mb-1">Webhook</Header3>
291285
<InputGroup>
292286
{webhookFields.map((webhookField, index) => (
293287
<Fragment key={webhookField.key}>

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

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { Button, LinkButton } from "~/components/primitives/Buttons";
2525
import { Callout } from "~/components/primitives/Callout";
2626
import { formatDateTime, RelativeDateTime } from "~/components/primitives/DateTime";
2727
import { Header3 } from "~/components/primitives/Headers";
28-
import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader";
28+
import { NavBar, PageTitle } from "~/components/primitives/PageHeader";
2929
import { Paragraph } from "~/components/primitives/Paragraph";
3030
import {
3131
ComboBox,
@@ -188,7 +188,6 @@ export default function Page() {
188188
});
189189

190190
const location = useOptimisticLocation();
191-
const showAlerts = new URLSearchParams(location.search).has("alerts");
192191
const alertsHref = useMemo(() => {
193192
const params = new URLSearchParams(location.search);
194193
params.set("alerts", "true");
@@ -199,13 +198,6 @@ export default function Page() {
199198
<div className="grid h-full grid-rows-[auto_1fr] overflow-hidden">
200199
<NavBar>
201200
<PageTitle title="Errors" />
202-
<PageAccessories>
203-
{!showAlerts && (
204-
<LinkButton to={alertsHref} variant="primary/small" LeadingIcon={BellAlertIcon}>
205-
Configure alerts
206-
</LinkButton>
207-
)}
208-
</PageAccessories>
209201
</NavBar>
210202

211203
<PageBody scrollable={false}>
@@ -226,7 +218,11 @@ export default function Page() {
226218
resolve={data}
227219
errorElement={
228220
<div className="grid h-full max-h-full grid-rows-[2.5rem_auto_1fr] overflow-hidden">
229-
<FiltersBar defaultPeriod={defaultPeriod} retentionLimitDays={retentionLimitDays} />
221+
<FiltersBar
222+
defaultPeriod={defaultPeriod}
223+
retentionLimitDays={retentionLimitDays}
224+
alertsHref={alertsHref}
225+
/>
230226
<div className="flex items-center justify-center px-3 py-12">
231227
<Callout variant="error" className="max-w-fit">
232228
Unable to load errors. Please refresh the page or try again in a moment.
@@ -242,6 +238,7 @@ export default function Page() {
242238
<FiltersBar
243239
defaultPeriod={defaultPeriod}
244240
retentionLimitDays={retentionLimitDays}
241+
alertsHref={alertsHref}
245242
/>
246243
<div className="flex items-center justify-center px-3 py-12">
247244
<Callout variant="error" className="max-w-fit">
@@ -257,6 +254,7 @@ export default function Page() {
257254
list={result}
258255
defaultPeriod={defaultPeriod}
259256
retentionLimitDays={retentionLimitDays}
257+
alertsHref={alertsHref}
260258
/>
261259
<ErrorsList
262260
errorGroups={result.errorGroups}
@@ -397,10 +395,12 @@ function FiltersBar({
397395
list,
398396
defaultPeriod,
399397
retentionLimitDays,
398+
alertsHref,
400399
}: {
401400
list?: ErrorsListData;
402401
defaultPeriod?: string;
403402
retentionLimitDays: number;
403+
alertsHref: string;
404404
}) {
405405
const location = useOptimisticLocation();
406406
const searchParams = new URLSearchParams(location.search);
@@ -453,7 +453,17 @@ function FiltersBar({
453453
</>
454454
)}
455455
</div>
456-
{list && <ListPagination list={list} />}
456+
<div className="flex shrink-0 items-center gap-2">
457+
<LinkButton
458+
to={alertsHref}
459+
variant="secondary/small"
460+
LeadingIcon={BellAlertIcon}
461+
leadingIconClassName="text-alerts"
462+
>
463+
Configure alerts
464+
</LinkButton>
465+
{list && <ListPagination list={list} />}
466+
</div>
457467
</div>
458468
);
459469
}

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

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
import { parse } from "@conform-to/zod";
2-
import { Outlet } from "@remix-run/react";
2+
import { Outlet, useNavigate } from "@remix-run/react";
33
import { type ActionFunctionArgs, type LoaderFunctionArgs, json } from "@remix-run/server-runtime";
4+
import { useCallback } from "react";
45
import { typedjson, useTypedLoaderData } from "remix-typedjson";
56
import { PageContainer } from "~/components/layout/AppLayout";
67
import {
78
ConfigureErrorAlerts,
89
ErrorAlertsFormSchema,
910
} from "~/components/errors/ConfigureErrorAlerts";
10-
import {
11-
ResizableHandle,
12-
ResizablePanel,
13-
ResizablePanelGroup,
14-
} from "~/components/primitives/Resizable";
11+
import { Sheet, SheetContent } from "~/components/primitives/SheetV3";
1512
import { prisma } from "~/db.server";
1613
import { ErrorAlertChannelPresenter } from "~/presenters/v3/ErrorAlertChannelPresenter.server";
1714
import { findProjectBySlug } from "~/models/project.server";
@@ -27,6 +24,7 @@ import {
2724
type CreateAlertChannelOptions,
2825
CreateAlertChannelService,
2926
} from "~/v3/services/alerts/createAlertChannel.server";
27+
import { useOptimisticLocation } from "~/hooks/useOptimisticLocation";
3028
import { useSearchParams } from "~/hooks/useSearchParam";
3129

3230
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
@@ -172,26 +170,33 @@ export default function Page() {
172170
const { alertData, connectToSlackHref, errorsPath } = useTypedLoaderData<typeof loader>();
173171
const { has } = useSearchParams();
174172
const showAlerts = has("alerts") ?? false;
173+
const navigate = useNavigate();
174+
const location = useOptimisticLocation();
175+
176+
const closeAlerts = useCallback(() => {
177+
const params = new URLSearchParams(location.search);
178+
params.delete("alerts");
179+
const qs = params.toString();
180+
navigate(qs ? `?${qs}` : location.pathname, { replace: true });
181+
}, [location.search, location.pathname, navigate]);
175182

176183
return (
177-
<PageContainer className="grid-rows-[1fr]">
178-
<ResizablePanelGroup orientation="horizontal" className="h-full max-h-full overflow-hidden">
179-
<ResizablePanel id="errors-main" min="300px">
180-
<Outlet />
181-
</ResizablePanel>
182-
{showAlerts && (
183-
<>
184-
<ResizableHandle id="errors-alerts-handle" />
185-
<ResizablePanel id="errors-alerts" min="320px" default="420px" max="560px">
186-
<ConfigureErrorAlerts
187-
{...alertData}
188-
connectToSlackHref={connectToSlackHref}
189-
formAction={errorsPath}
190-
/>
191-
</ResizablePanel>
192-
</>
193-
)}
194-
</ResizablePanelGroup>
184+
<PageContainer>
185+
<Outlet />
186+
187+
<Sheet open={showAlerts} onOpenChange={(open) => !open && closeAlerts()}>
188+
<SheetContent
189+
side="right"
190+
className="w-[420px] min-w-[320px] max-w-[560px] p-0 sm:max-w-[560px]"
191+
onOpenAutoFocus={(e) => e.preventDefault()}
192+
>
193+
<ConfigureErrorAlerts
194+
{...alertData}
195+
connectToSlackHref={connectToSlackHref}
196+
formAction={errorsPath}
197+
/>
198+
</SheetContent>
199+
</Sheet>
195200
</PageContainer>
196201
);
197202
}

0 commit comments

Comments
 (0)