,
- document.body,
+
+
+
);
}
diff --git a/crates/agent-ui/src/components/chat/ThinkingActivity.tsx b/crates/agent-ui/src/components/chat/ThinkingActivity.tsx
index 21f1e58cd..5572d227e 100644
--- a/crates/agent-ui/src/components/chat/ThinkingActivity.tsx
+++ b/crates/agent-ui/src/components/chat/ThinkingActivity.tsx
@@ -1,5 +1,6 @@
import { ChevronRight, Lightbulb } from "@liveagent/ui/components/IconSet";
import { useLocale } from "@liveagent/ui/i18n/index";
+import { cn } from "@liveagent/ui/lib/shared/utils";
import { useEffect, useRef, useState } from "react";
import type { ChatFileLink } from "../../lib/chat/chatFileLinks";
import { Markdown } from "../Markdown";
@@ -48,7 +49,10 @@ export function ThinkingActivity(props: {
>
)}
diff --git a/crates/agent-ui/src/components/chat/ToolSurfaces.tsx b/crates/agent-ui/src/components/chat/ToolSurfaces.tsx
index 21016c5c8..d357f49a4 100644
--- a/crates/agent-ui/src/components/chat/ToolSurfaces.tsx
+++ b/crates/agent-ui/src/components/chat/ToolSurfaces.tsx
@@ -119,7 +119,7 @@ export function ToolScrollablePre(props: { children: ReactNode; className?: stri
return (
diff --git a/crates/agent-ui/src/components/chat/UserAttachmentCards.tsx b/crates/agent-ui/src/components/chat/UserAttachmentCards.tsx
index 998a76dc4..485377535 100644
--- a/crates/agent-ui/src/components/chat/UserAttachmentCards.tsx
+++ b/crates/agent-ui/src/components/chat/UserAttachmentCards.tsx
@@ -75,16 +75,17 @@ function UserImageAttachmentCard(props: {
} | null>(null);
const labeledPreview = `${previewLabel}: ${file.fileName}`;
const FallbackIcon = getUploadedFileTypeIcon(file);
- const previewSlides = useMemo(
- () => {
- const slide = createUserAttachmentImagePreviewSlide(file, imageSrc, workspaceRoot);
- return slide ? [slide] : [];
- },
- [file, imageSrc, workspaceRoot],
- );
+ const previewSlides = useMemo(() => {
+ const slide = createUserAttachmentImagePreviewSlide(file, imageSrc, workspaceRoot);
+ return slide ? [slide] : [];
+ }, [file, imageSrc, workspaceRoot]);
const previewSlide = previewSlides[0];
- const imageLoadFailed = Boolean(imageSrc && imageLoadState?.src === imageSrc && imageLoadState.status === "error");
- const canPreview = Boolean(imageSrc && imageLoadState?.src === imageSrc && imageLoadState.status === "loaded");
+ const imageLoadFailed = Boolean(
+ imageSrc && imageLoadState?.src === imageSrc && imageLoadState.status === "error",
+ );
+ const canPreview = Boolean(
+ imageSrc && imageLoadState?.src === imageSrc && imageLoadState.status === "loaded",
+ );
return (
{
- function onKeyDown(event: KeyboardEvent) {
- // defaultPrevented: an open branch Select consumes Escape to close itself.
- if (event.key !== "Escape" || event.defaultPrevented || cloning) return;
- event.preventDefault();
- requestClose();
- }
- window.addEventListener("keydown", onKeyDown);
- return () => window.removeEventListener("keydown", onKeyDown);
- }, [cloning, requestClose]);
-
async function chooseParent() {
try {
const selected = await pickDirectory(parent);
@@ -144,7 +139,7 @@ export function WorkspaceCloneModal({
setError("");
try {
await onClone(remoteUrl.trim(), parent.trim(), name.trim(), branch);
- requestClose();
+ onClose();
} catch (reason) {
setError(errorMessage(reason));
} finally {
@@ -152,51 +147,41 @@ export function WorkspaceCloneModal({
}
}
- const modal = createPortal(
-
{
+ if (!open && !cloning) onClose();
+ }}
>
-
-
-
-
+
+
+
-
+
{t("chat.workspaceCreate")}
-
-
+
+
{t("chat.workspaceCreateDescription")}
-
+
-
-
+
-
+
-
-
,
- document.body,
+
+
+
);
return (
diff --git a/crates/agent-ui/src/components/chat/WorkspaceCloneTaskOverlay.tsx b/crates/agent-ui/src/components/chat/WorkspaceCloneTaskOverlay.tsx
index 2545bdf1a..47aaadba9 100644
--- a/crates/agent-ui/src/components/chat/WorkspaceCloneTaskOverlay.tsx
+++ b/crates/agent-ui/src/components/chat/WorkspaceCloneTaskOverlay.tsx
@@ -9,6 +9,7 @@ import {
} from "@liveagent/ui/components/IconSet";
import { Button } from "@liveagent/ui/components/ui/button";
import { useLocale } from "@liveagent/ui/i18n/index";
+import { cn } from "@liveagent/ui/lib/shared/utils";
export type WorkspaceCloneTask = {
id: string;
@@ -74,7 +75,10 @@ function CloneTaskCard({
{active ? t(`chat.workspaceCloneTaskPhase.${task.phase}`) : message}
@@ -142,7 +146,7 @@ function CloneTaskCard({
export function WorkspaceCloneTaskOverlay(props: WorkspaceCloneTaskOverlayProps) {
if (props.tasks.length === 0) return null;
return (
-
+
{props.tasks.map((task) => (
))}
diff --git a/crates/agent-ui/src/components/chat/WorkspaceProjectSettingsModal.tsx b/crates/agent-ui/src/components/chat/WorkspaceProjectSettingsModal.tsx
index e88c0ca82..3a7f47b93 100644
--- a/crates/agent-ui/src/components/chat/WorkspaceProjectSettingsModal.tsx
+++ b/crates/agent-ui/src/components/chat/WorkspaceProjectSettingsModal.tsx
@@ -1,4 +1,3 @@
-import { Dialog } from "@base-ui/react/dialog";
import { useDirectoryPicker } from "@liveagent/adapters/directoryPicker";
import {
type AppSettings,
@@ -13,13 +12,22 @@ import type {
WorkspaceProjectRootGrant,
} from "@liveagent/ui/contracts/workspaceProjectRoots";
import { useLocale } from "@liveagent/ui/i18n/index";
-import { useModalMotion } from "@liveagent/ui/lib/shared/modalMotion";
import { cn } from "@liveagent/ui/lib/shared/utils";
import { isAlwaysEnabledSkillName, type SkillSummary } from "@liveagent/ui/lib/skills/index";
import { useEffect, useMemo, useState } from "react";
import type { StoreCategoryValue } from "../../pages/skills-hub/SkillCategoryControls";
-import { Blend, FolderTree, Loader2, Settings, X } from "../IconSet";
+import { Blend, FolderTree, Loader2, Settings } from "../IconSet";
import { Button } from "../ui/button";
+import {
+ Dialog,
+ DialogActions,
+ DialogBody,
+ DialogClose,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "../ui/dialog";
import { WorkspaceDirectorySettingsPanel } from "./workspace-project-settings/WorkspaceDirectorySettingsPanel";
import { WorkspaceGeneralSettingsPanel } from "./workspace-project-settings/WorkspaceGeneralSettingsPanel";
import {
@@ -69,7 +77,8 @@ export function WorkspaceProjectSettingsModal(props: {
} = props;
const { t } = useLocale();
const { suspendsParentModal, pickDirectory, directoryPickerElement } = useDirectoryPicker();
- const { isClosing, modalState, requestClose } = useModalMotion(onClose);
+ const [dialogOpen, setDialogOpen] = useState(true);
+ const requestClose = () => setDialogOpen(false);
const pathKey = workspaceProjectPathKey(project.path);
const saved = settings.system.workspaceResourceSettings[pathKey];
const globalSkillNames = useMemo(
@@ -218,7 +227,7 @@ export function WorkspaceProjectSettingsModal(props: {
};
const handleSave = async () => {
- if (saving || isClosing) return;
+ if (saving || !dialogOpen) return;
if (projectNameInvalid) {
setActivePanel("general");
return;
@@ -271,13 +280,21 @@ export function WorkspaceProjectSettingsModal(props: {
`chat.workspaceSettingsKind${project.kind[0].toUpperCase()}${project.kind.slice(1)}`,
);
const navigation = [
- { id: "general" as const, icon: Settings, label: t("chat.workspaceSettingsGeneral") },
+ {
+ id: "general" as const,
+ icon: Settings,
+ label: t("chat.workspaceSettingsGeneral"),
+ },
{
id: "directories" as const,
icon: FolderTree,
label: t("chat.workspaceSettingsDirectories"),
},
- { id: "resources" as const, icon: Blend, label: t("chat.workspaceSettingsResources") },
+ {
+ id: "resources" as const,
+ icon: Blend,
+ label: t("chat.workspaceSettingsResources"),
+ },
];
if (directoryPickerActive) {
@@ -285,195 +302,177 @@ export function WorkspaceProjectSettingsModal(props: {
}
return (
-
{
if (!open && !saving) requestClose();
}}
+ onOpenChangeComplete={(open) => {
+ if (!open) onClose();
+ }}
>
-
-
-
-
-