mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 14:15:24 +00:00
fix: link server wizard always opens inline, onboarding card grows for it
This commit is contained in:
1 parent
6f4198cc83
commit
83cce344e8
3 files changed
+52
-51
No files matched your search
@@ -117,6 +117,7 @@ export function OnboardingStage({
|
||||
}, [allSteps, ctx]);
|
||||
|
||||
const [currentId, setCurrentId] = useState<string | null>(null);
|
||||
const [viewOpen, setViewOpen] = useState(false);
|
||||
const lastPosition = useRef(0);
|
||||
const [confirmed, setConfirmed] = useState<Set<string>>(() => new Set());
|
||||
const [canContinue, setCanContinueMap] = useState<Record<string, boolean>>(
|
||||
@@ -280,7 +281,10 @@ export function OnboardingStage({
|
||||
|
||||
<SurfaceScope
|
||||
kind="tab"
|
||||
className="relative flex flex-col border border-border bg-card"
|
||||
onEditingChange={(editing) => setViewOpen(!!editing)}
|
||||
className={`relative flex flex-col border border-border bg-card ${
|
||||
viewOpen ? "min-h-[70vh]" : ""
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-2 border-b border-border px-4 py-2.5">
|
||||
{Icon && <Icon size={14} className="text-muted-foreground" />}
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { InlineView, useSurfaceKind } from "@/components/surface/surface-scope";
|
||||
import { InlineView } from "@/components/surface/surface-scope";
|
||||
import { toast } from "sonner";
|
||||
import { AlertCircle, Loader2, X } from "lucide-react";
|
||||
import { Button } from "@/components/button";
|
||||
import { Input } from "@/components/input";
|
||||
import { Switch } from "@/components/switch";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/dialog";
|
||||
import { ElectronLoginForm } from "@/auth/ElectronLoginForm";
|
||||
import {
|
||||
completeLink,
|
||||
@@ -224,7 +217,6 @@ export function LinkServerDialog({
|
||||
0,
|
||||
);
|
||||
const wide = step === "signin";
|
||||
const inSurface = useSurfaceKind() !== null;
|
||||
|
||||
const title = relogin
|
||||
? t("sync.wizard.reloginTitle")
|
||||
@@ -443,47 +435,21 @@ export function LinkServerDialog({
|
||||
</>
|
||||
);
|
||||
|
||||
// From a sidebar panel the wizard takes over the panel. Outside one (the
|
||||
// first-run setup) it stays a dialog.
|
||||
if (inSurface) {
|
||||
return (
|
||||
<InlineView
|
||||
open={open}
|
||||
onOpenChange={onOpenChange}
|
||||
title={title}
|
||||
width="wide"
|
||||
scroll={!wide}
|
||||
>
|
||||
{!wide && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{description} {step === "server" && <DocsLink core="desktopSync" />}
|
||||
</p>
|
||||
)}
|
||||
{content}
|
||||
</InlineView>
|
||||
);
|
||||
}
|
||||
|
||||
// The wizard takes over the panel, tab or onboarding step it opens from.
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent
|
||||
className={`bg-card border border-border rounded-none ${
|
||||
wide ? "sm:max-w-4xl h-[80vh] flex flex-col p-0 gap-0" : "sm:max-w-lg"
|
||||
}`}
|
||||
// The sign-in step is a page from another origin in an iframe; clicks
|
||||
// inside it look like outside clicks to the dialog.
|
||||
onPointerDownOutside={(event) => wide && event.preventDefault()}
|
||||
onInteractOutside={(event) => wide && event.preventDefault()}
|
||||
>
|
||||
<DialogHeader className={wide ? "sr-only" : undefined}>
|
||||
<DialogTitle>{title}</DialogTitle>
|
||||
<DialogDescription>
|
||||
{description} {step === "server" && <DocsLink core="desktopSync" />}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
{content}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<InlineView
|
||||
open={open}
|
||||
onOpenChange={onOpenChange}
|
||||
title={title}
|
||||
width="wide"
|
||||
scroll={!wide}
|
||||
>
|
||||
{!wide && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{description} {step === "server" && <DocsLink core="desktopSync" />}
|
||||
</p>
|
||||
)}
|
||||
{content}
|
||||
</InlineView>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { cleanup, render, screen } from "@testing-library/react";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("@/api/sync-api", () => ({
|
||||
probeServer: vi.fn(),
|
||||
getLinkPreview: vi.fn(),
|
||||
completeLink: vi.fn(),
|
||||
reloginLink: vi.fn(),
|
||||
}));
|
||||
vi.mock("@/auth/ElectronLoginForm", () => ({ ElectronLoginForm: () => null }));
|
||||
vi.mock("sonner", () => ({ toast: { success: vi.fn(), error: vi.fn() } }));
|
||||
vi.mock("react-i18next", () => ({
|
||||
useTranslation: () => ({ t: (key: string) => key }),
|
||||
}));
|
||||
|
||||
const { SurfaceScope } = await import("@/components/surface/surface-scope");
|
||||
const { LinkServerDialog } = await import("@/settings/sync/LinkServerDialog");
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
describe("LinkServerDialog", () => {
|
||||
it("opens inline in the surface instead of a popup", () => {
|
||||
render(
|
||||
<SurfaceScope kind="tab">
|
||||
<LinkServerDialog open onOpenChange={() => {}} onLinked={() => {}} />
|
||||
</SurfaceScope>,
|
||||
);
|
||||
expect(screen.getByText("sync.wizard.title")).toBeTruthy();
|
||||
expect(screen.queryByRole("dialog")).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user