Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .oxlintrc.jsonc
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
{
"ignorePatterns": [".astro/"],
"plugins": ["react"],
"rules": {
"typescript/no-explicit-any": "error",
"react/forbid-elements": [
"error",
{
"forbid": [
{ "element": "button", "message": "Use <Button> from @executor/react" },
{ "element": "input", "message": "Use <Input> from @executor/react" },
{ "element": "textarea", "message": "Use <Textarea> from @executor/react" },
{ "element": "select", "message": "Use <Select> or <NativeSelect> from @executor/react" },
{ "element": "table", "message": "Use <Table> from @executor/react" },
{ "element": "label", "message": "Use <Label> from @executor/react" },
],
},
],
},
"ignorePatterns": [".astro/"],
}
6 changes: 4 additions & 2 deletions apps/cloud/src/routes/billing.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createFileRoute, Link } from "@tanstack/react-router";
import { useCustomer, useListPlans } from "autumn-js/react";
import { Button } from "@executor/react/components/button";

export const Route = createFileRoute("/billing")({
component: BillingPage,
Expand Down Expand Up @@ -87,13 +88,14 @@ function BillingPage() {
</div>
<div className="flex items-center gap-2">
{activePlan && !isCanceling && (
<button
<Button
variant="ghost"
type="button"
onClick={() => openCustomerPortal()}
className="rounded-md px-3 py-1.5 text-[0.75rem] font-medium text-destructive transition-colors hover:bg-destructive/10"
>
Cancel plan
</button>
</Button>
)}
<Link
to="/billing/plans"
Expand Down
9 changes: 5 additions & 4 deletions apps/cloud/src/routes/billing_.plans.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useState } from "react";
import { createFileRoute, Link } from "@tanstack/react-router";
import { useCustomer, useListPlans } from "autumn-js/react";
import { Button } from "@executor/react/components/button";

export const Route = createFileRoute("/billing_/plans")({
component: PlansPage,
Expand Down Expand Up @@ -149,16 +150,16 @@ function PlansPage() {
{isCurrent ? "Current plan" : "Scheduled"}
</div>
) : isCanceling ? (
<button
<Button
type="button"
disabled={loadingPlan !== null}
onClick={() => openCustomerPortal()}
className="flex h-9 w-full items-center justify-center rounded-md bg-primary text-[0.8125rem] font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-60"
>
Resume
</button>
</Button>
) : (
<button
<Button
type="button"
disabled={loadingPlan !== null}
onClick={async () => {
Expand All @@ -174,7 +175,7 @@ function PlansPage() {
].join(" ")}
>
{loadingPlan === plan.id ? "Loading…" : label}
</button>
</Button>
)}
</div>

Expand Down
27 changes: 17 additions & 10 deletions apps/cloud/src/web/shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from "react";
import { useAtomValue, Result } from "@effect-atom/atom-react";
import { sourcesAtom } from "@executor/react/api/atoms";
import { useScope } from "@executor/react/api/scope-context";

import { Button } from "@executor/react/components/button";
import { AUTH_PATHS } from "../auth/api";
import { useAuth } from "./auth";

Expand Down Expand Up @@ -109,9 +109,11 @@ function UserFooter() {
)}
</div>
<form action={AUTH_PATHS.logout} method="post">
<button
<Button
variant="ghost"
size="icon-xs"
type="submit"
className="shrink-0 rounded-md p-1 text-muted-foreground/50 transition-colors hover:bg-sidebar-active hover:text-foreground"
className="shrink-0 text-muted-foreground/50 hover:bg-sidebar-active hover:text-foreground"
title="Sign out"
>
<svg viewBox="0 0 16 16" fill="none" className="size-3.5">
Expand All @@ -123,7 +125,7 @@ function UserFooter() {
strokeLinejoin="round"
/>
</svg>
</button>
</Button>
</form>
</div>
</div>
Expand Down Expand Up @@ -196,6 +198,7 @@ export function Shell() {
{/* Mobile sidebar overlay */}
{mobileSidebarOpen && (
<div className="fixed inset-0 z-50 flex md:hidden">
{/* oxlint-disable-next-line react/forbid-elements */}
<button
type="button"
aria-label="Close navigation"
Expand All @@ -209,11 +212,13 @@ export function Shell() {
executor
</span>
</Link>
<button
<Button
variant="ghost"
size="icon-sm"
type="button"
aria-label="Close navigation"
onClick={() => setMobileSidebarOpen(false)}
className="size-8 flex items-center justify-center rounded-md text-sidebar-foreground hover:bg-sidebar-active hover:text-foreground"
className="text-sidebar-foreground hover:bg-sidebar-active hover:text-foreground"
>
<svg viewBox="0 0 16 16" className="size-3.5">
<path
Expand All @@ -223,7 +228,7 @@ export function Shell() {
strokeLinecap="round"
/>
</svg>
</button>
</Button>
</div>
<SidebarContent
pathname={pathname}
Expand All @@ -238,11 +243,13 @@ export function Shell() {
<main className="flex min-h-0 flex-1 flex-col min-w-0 overflow-hidden">
{/* Mobile top bar */}
<div className="flex h-12 shrink-0 items-center justify-between border-b border-border bg-background px-4 md:hidden">
<button
<Button
variant="outline"
size="icon-sm"
type="button"
aria-label="Open navigation"
onClick={() => setMobileSidebarOpen(true)}
className="size-8 flex items-center justify-center rounded-md border border-border bg-card hover:bg-accent/50"
className="bg-card hover:bg-accent/50"
>
<svg viewBox="0 0 16 16" className="size-4">
<path
Expand All @@ -252,7 +259,7 @@ export function Shell() {
strokeLinecap="round"
/>
</svg>
</button>
</Button>
<Link to="/" className="flex items-center gap-1.5">
<span className="font-display text-base tracking-tight text-foreground">executor</span>
</Link>
Expand Down
19 changes: 11 additions & 8 deletions apps/local/src/web/shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ export function Shell() {
{/* Mobile sidebar overlay */}
{mobileSidebarOpen && (
<div className="fixed inset-0 z-50 flex md:hidden">
{/* oxlint-disable-next-line react/forbid-elements */}
<button
type="button"
aria-label="Close navigation"
Expand All @@ -415,11 +416,12 @@ export function Shell() {
executor
</span>
</Link>
<button
type="button"
<Button
variant="ghost"
size="icon-sm"
aria-label="Close navigation"
onClick={() => setMobileSidebarOpen(false)}
className="size-8 flex items-center justify-center rounded-md text-sidebar-foreground hover:bg-sidebar-active hover:text-foreground"
className="text-sidebar-foreground hover:bg-sidebar-active hover:text-foreground"
>
<svg viewBox="0 0 16 16" className="size-3.5">
<path
Expand All @@ -429,7 +431,7 @@ export function Shell() {
strokeLinecap="round"
/>
</svg>
</button>
</Button>
</div>
<SidebarContent
pathname={pathname}
Expand All @@ -447,11 +449,12 @@ export function Shell() {
<main className="flex min-h-0 flex-1 flex-col min-w-0 overflow-hidden">
{/* Mobile top bar */}
<div className="flex h-12 shrink-0 items-center justify-between border-b border-border bg-background px-4 md:hidden">
<button
type="button"
<Button
variant="outline"
size="icon-sm"
aria-label="Open navigation"
onClick={() => setMobileSidebarOpen(true)}
className="size-8 flex items-center justify-center rounded-md border border-border bg-card hover:bg-accent/50"
className="bg-card hover:bg-accent/50"
>
<svg viewBox="0 0 16 16" className="size-4">
<path
Expand All @@ -461,7 +464,7 @@ export function Shell() {
strokeLinecap="round"
/>
</svg>
</button>
</Button>
<Link to="/" className="flex items-center gap-1.5">
<span className="font-display text-base tracking-tight text-foreground">executor</span>
</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ export default function AddGoogleDiscoverySource(props: {
} finally {
setLoadingProbe(false);
}
}, [discoveryUrl, doProbe, name]);
}, [discoveryUrl, doProbe, name, scopeId]);

const autoProbed = useRef(false);
useEffect(() => {
Expand Down Expand Up @@ -573,7 +573,7 @@ export default function AddGoogleDiscoverySource(props: {
setError(e instanceof Error ? e.message : "Failed to add source");
setAdding(false);
}
}, [probe, doAdd, name, discoveryUrl, authKind, oauthAuth, props]);
}, [probe, doAdd, name, discoveryUrl, authKind, oauthAuth, props, scopeId]);

const addDisabled =
!probe || adding || (authKind === "oauth2" && (!canUseOAuth || oauthAuth === null));
Expand All @@ -598,11 +598,12 @@ export default function AddGoogleDiscoverySource(props: {
{GOOGLE_DISCOVERY_TEMPLATES.map((template) => {
const selected = template.id === selectedTemplateId;
return (
<button
<Button
key={template.id}
variant="ghost"
type="button"
onClick={() => applyTemplate(template)}
className={`relative rounded-xl border px-4 py-3 text-left transition-colors ${
className={`relative h-auto rounded-xl border px-4 py-3 text-left transition-colors ${
selected
? "border-primary bg-primary/5 shadow-[0_0_0_1px_rgba(0,0,0,0.02)]"
: "border-border bg-card hover:border-primary/30 hover:bg-card/80"
Expand All @@ -628,7 +629,7 @@ export default function AddGoogleDiscoverySource(props: {
</p>
<div className="h-px flex-1 bg-border/70" />
</div>
</button>
</Button>
);
})}
</div>
Expand Down Expand Up @@ -737,12 +738,13 @@ export default function AddGoogleDiscoverySource(props: {
</p>
{canUseOAuth && (probe?.scopes.length ?? 0) > 0 && (
<CollapsibleTrigger asChild>
<button
<Button
variant="link"
type="button"
className="text-xs font-medium text-primary hover:underline"
className="h-auto p-0 text-xs font-medium text-primary hover:underline"
>
{showScopes ? "Hide scopes" : "View scopes"}
</button>
</Button>
</CollapsibleTrigger>
)}
</div>
Expand Down
Loading
Loading