mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-07 16:19:09 +00:00
* feat(dashboard): refactor UI into Cursor-style sidebar layout
Replace the top-bar AppHeader with a left sidebar that holds the four
primary sections (My Settings, Cloud Agents, Open SWE Review,
Integrations) and the user account menu at the bottom. Admin remains a
hidden route reachable from the sidebar only when is_admin.
UI:
- AppShell + AppSidebar with bottom-anchored avatar/sign-out menu.
- My Settings: profile (first/last name) + PR destination preference.
- Cloud Agents: model/effort, default repo, base branch, branch prefix,
PR toggles (auto-fix CI, create PRs, allow artifacts), Slack
notifications.
- Open SWE Review: trigger mode, draft reviews, PR summaries, autofix
mode + severity threshold, plus the existing per-repo review-style
prompts (was /review-styles).
- Integrations: GitHub install status + Slack/Linear status rows.
- New Switch and Menu primitives.
Backend:
- Extend ProfileUpdate with first_name, last_name, base_branch,
branch_prefix, auto_fix_ci, create_prs, allow_artifacts,
slack_notifications, preferred_pr_destination.
- Add team_settings module + /team-settings GET (any session) / PUT
(admin only) for the reviewer configuration.
* fix(dashboard): replace base-ui Menu with plain dropdown, stabilise Selects
- base-ui's Menu hit an "Invalid hook call / Cannot read properties of
null (reading 'useRef')" crash inside fastComponent under Vite's dep
optimisation. The sidebar account menu is the only consumer, so swap
it for a useState-driven dropdown with click-outside + Esc handling
and drop the unused Menu wrapper.
- Initialise the Open SWE Review settings form with the same defaults
the server returns instead of `null`, so the Selects don't switch
from uncontrolled (`undefined`) to controlled on first data load.
* fix(dashboard): address review feedback on admin overwrite + form reset
- admin PUT /admin/profiles/{login} only sent model/effort/repo from the
admin form. ProfileUpdate's Pydantic defaults then wrote auto_fix_ci /
create_prs / slack_notifications etc back onto the target user's
profile, clobbering whatever they had configured. Switch to
model_dump(exclude_unset=True) and overlay the incoming fields on the
user's existing stored profile so only sent fields change.
- my-settings.tsx and cloud-agents.tsx initialised local state from
profile.data on every change. Because useSaveProfile updates the
cached profile on success, toggling any control would overwrite the
user's typed-but-unsaved input in another field. Guard the
initialisation effect with a ref so it runs once on first load.
---------
Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
45 lines
1.4 KiB
TypeScript
45 lines
1.4 KiB
TypeScript
import { Navigate, createFileRoute } from "@tanstack/react-router";
|
|
|
|
import { buttonVariants } from "@/components/ui/button";
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
import { loginUrl } from "@/lib/api";
|
|
import { useSession } from "@/lib/session";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
export const Route = createFileRoute("/login")({ component: Login });
|
|
|
|
function Login() {
|
|
const session = useSession();
|
|
|
|
if (session.isLoading) {
|
|
return (
|
|
<main className="flex min-h-svh items-center justify-center p-6">
|
|
<Skeleton className="h-40 w-80" />
|
|
</main>
|
|
);
|
|
}
|
|
|
|
if (session.data) {
|
|
return <Navigate to="/my-settings" />;
|
|
}
|
|
|
|
return (
|
|
<main className="flex min-h-svh items-center justify-center p-6">
|
|
<Card className="w-full max-w-md">
|
|
<CardHeader>
|
|
<CardTitle>Sign in to open-swe</CardTitle>
|
|
<CardDescription>
|
|
Use your GitHub account. We'll configure your default model, reasoning effort, and
|
|
default repo for Slack/Linear/GitHub triggered runs.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<a href={loginUrl()} className={cn(buttonVariants({ size: "lg" }), "w-full")}>
|
|
Continue with GitHub
|
|
</a>
|
|
</CardContent>
|
|
</Card>
|
|
</main>
|
|
);
|
|
}
|