Webhooks for the AT Protocol airglow.run
atproto atprotocol automation webhook
12
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: remove active badge in gallery

Hugo 9b27551c ad4fc420

+1 -63
-26
app/components/AutomationCard/index.tsx
··· 1 1 import { Copy } from "../../icons.ts"; 2 2 import type { Action } from "../../../lib/db/schema.ts"; 3 - import { Badge } from "../Badge/index.tsx"; 4 3 import { Button } from "../Button/index.tsx"; 5 4 import { LexiconFlow } from "../LexiconFlow/index.tsx"; 6 5 import * as s from "./styles.css.ts"; ··· 16 15 viewerAuthenticated: boolean; 17 16 isOwner?: boolean; 18 17 featured?: boolean; 19 - active?: boolean; 20 - dryRun?: boolean; 21 - disabledReason?: string | null; 22 18 }; 23 19 24 - function renderStatusBadge( 25 - active: boolean | undefined, 26 - dryRun: boolean | undefined, 27 - disabledReason: string | null | undefined, 28 - ) { 29 - if (active === false && disabledReason?.startsWith("rate_limit")) { 30 - return <Badge variant="error">Rate limited</Badge>; 31 - } 32 - if (active === false) { 33 - return <Badge variant="neutral">Inactive</Badge>; 34 - } 35 - if (dryRun) { 36 - return <Badge variant="warning">Dry Run</Badge>; 37 - } 38 - return null; 39 - } 40 - 41 20 export function AutomationCard({ 42 21 handle, 43 22 did, ··· 49 28 viewerAuthenticated, 50 29 isOwner, 51 30 featured, 52 - active, 53 - dryRun, 54 - disabledReason, 55 31 }: AutomationCardProps) { 56 32 const detailHref = `/u/${handle}/${rkey}`; 57 33 const useHref = isOwner 58 34 ? `/dashboard/automations/${rkey}` 59 35 : `/dashboard/automations/new?from=${encodeURIComponent(did)}&rkey=${encodeURIComponent(rkey)}`; 60 - const badge = renderStatusBadge(active, dryRun, disabledReason); 61 36 62 37 return ( 63 38 <article class={featured ? `${s.card} ${s.cardFeatured}` : s.card}> 64 - {badge && <div class={s.statusRow}>{badge}</div>} 65 39 <LexiconFlow lexicon={lexicon} actions={actions} /> 66 40 <h3 class={s.title} title={name}> 67 41 <a href={detailHref} class={s.titleLink}>
-8
app/components/AutomationCard/styles.css.ts
··· 87 87 position: "relative", 88 88 zIndex: 1, 89 89 }); 90 - 91 - export const statusRow = style({ 92 - position: "relative", 93 - zIndex: 1, 94 - display: "flex", 95 - justifyContent: "flex-end", 96 - marginBlockEnd: `calc(${space[2]} * -1)`, 97 - });
-6
app/components/AutomationGallery/index.tsx
··· 40 40 actions={a.actions} 41 41 viewerAuthenticated={viewerAuthenticated} 42 42 isOwner={viewerDid === a.did} 43 - active={a.active} 44 - dryRun={a.dryRun} 45 - disabledReason={a.disabledReason} 46 43 featured 47 44 /> 48 45 ))} ··· 65 62 actions={a.actions} 66 63 viewerAuthenticated={viewerAuthenticated} 67 64 isOwner={viewerDid === a.did} 68 - active={a.active} 69 - dryRun={a.dryRun} 70 - disabledReason={a.disabledReason} 71 65 /> 72 66 ))} 73 67 </div>
-3
lib/automations/featured.ts
··· 24 24 lexicon: automations.lexicon, 25 25 actions: automations.actions, 26 26 handle: users.handle, 27 - active: automations.active, 28 - dryRun: automations.dryRun, 29 - disabledReason: automations.disabledReason, 30 27 }) 31 28 .from(automations) 32 29 .innerJoin(users, eq(users.did, automations.did))
-7
lib/automations/search.test.ts
··· 116 116 name: "Inactive one", 117 117 lexicon: "run.airglow.automation", 118 118 active: false, 119 - disabledReason: "rate_limit:hour", 120 119 }); 121 120 122 121 const rows = await searchAutomations(db, { ··· 125 124 includeInactive: true, 126 125 }); 127 126 expect(rows.map((r) => r.rkey).sort()).toEqual(["a1", "a2"]); 128 - const inactive = rows.find((r) => r.rkey === "a2"); 129 - expect(inactive?.active).toBe(false); 130 - expect(inactive?.disabledReason).toBe("rate_limit:hour"); 131 - const active = rows.find((r) => r.rkey === "a1"); 132 - expect(active?.active).toBe(true); 133 - expect(active?.dryRun).toBe(false); 134 127 }); 135 128 136 129 it("excludes URIs listed in excludeUris", async () => {
+1 -12
lib/automations/search.ts
··· 16 16 lexicon: string; 17 17 handle: string; 18 18 actions: Action[]; 19 - active: boolean; 20 - dryRun: boolean; 21 - disabledReason: string | null; 22 19 }; 23 20 24 21 export type AutomationSearchParams = { ··· 57 54 conditions.push(notInArray(automations.uri, params.excludeUris)); 58 55 } 59 56 60 - const whereClause = 61 - conditions.length === 0 62 - ? undefined 63 - : conditions.length === 1 64 - ? conditions[0] 65 - : and(...conditions); 57 + const whereClause = conditions.length === 1 ? conditions[0] : and(...conditions); 66 58 67 59 return db 68 60 .select({ ··· 74 66 lexicon: automations.lexicon, 75 67 actions: automations.actions, 76 68 handle: users.handle, 77 - active: automations.active, 78 - dryRun: automations.dryRun, 79 - disabledReason: automations.disabledReason, 80 69 }) 81 70 .from(automations) 82 71 .innerJoin(users, eq(users.did, automations.did))
-1
lib/test/fixtures.ts
··· 26 26 wantedDids: string[]; 27 27 active: boolean; 28 28 dryRun: boolean; 29 - disabledReason?: string | null; 30 29 indexedAt: Date; 31 30 }; 32 31