fix(web): render the create-bot modal outside the side panel; tidy Shell leftovers
The centered Create new Bot modal was rendered inside the side panel's condition, so the empty states that open it (nothing selected, or a project without bots) only showed it while a panel happened to be open. It is a portal to the document body, so it now renders after the panel. - The project drag grip's accessible name goes through Lingui (German "Ziehen zum Umsortieren") instead of a hard-coded English label. - Drop the project drag state that was set but never read, and imports Shell.tsx no longer uses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u
This commit is contained in:
parent
f395ed9a23
commit
8c15a18565
@ -4,6 +4,7 @@
|
||||
*/
|
||||
import { useSortable } from "@dnd-kit/sortable";
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import { useLingui } from "@lingui/react/macro";
|
||||
import { createContext, memo, useContext, useMemo } from "react";
|
||||
|
||||
interface SortableGroupProps {
|
||||
@ -30,13 +31,14 @@ export const ProjectDragGrip = memo(function ProjectDragGrip({
|
||||
className?: string;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const { t } = useLingui();
|
||||
const handle = useSortableGroupHandle();
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
ref={handle?.setActivatorNodeRef}
|
||||
className={className}
|
||||
aria-label="Drag to reorder"
|
||||
aria-label={t`Drag to reorder`}
|
||||
{...handle?.attributes}
|
||||
{...handle?.listeners}
|
||||
>
|
||||
|
||||
@ -2100,6 +2100,10 @@ msgstr "Skill-Entwurf"
|
||||
msgid "Drafting the spec…"
|
||||
msgstr "Entwerfe die Spezifikation…"
|
||||
|
||||
#: src/components/SortableGroup.tsx
|
||||
msgid "Drag to reorder"
|
||||
msgstr "Ziehen zum Umsortieren"
|
||||
|
||||
#: src/pages/shell/avatar-studio-popover.tsx
|
||||
msgid "Drag, drop, or paste an image"
|
||||
msgstr "Bild ziehen, ablegen oder einfügen"
|
||||
|
||||
@ -2100,6 +2100,10 @@ msgstr "Draft skill"
|
||||
msgid "Drafting the spec…"
|
||||
msgstr "Drafting the spec…"
|
||||
|
||||
#: src/components/SortableGroup.tsx
|
||||
msgid "Drag to reorder"
|
||||
msgstr "Drag to reorder"
|
||||
|
||||
#: src/pages/shell/avatar-studio-popover.tsx
|
||||
msgid "Drag, drop, or paste an image"
|
||||
msgstr "Drag, drop, or paste an image"
|
||||
|
||||
@ -2100,6 +2100,10 @@ msgstr "Habilidad en borrador"
|
||||
msgid "Drafting the spec…"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/SortableGroup.tsx
|
||||
msgid "Drag to reorder"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/shell/avatar-studio-popover.tsx
|
||||
msgid "Drag, drop, or paste an image"
|
||||
msgstr "Arrastra, suelta o pega una imagen"
|
||||
|
||||
@ -2100,6 +2100,10 @@ msgstr "ड्राफ़्ट स्किल"
|
||||
msgid "Drafting the spec…"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/SortableGroup.tsx
|
||||
msgid "Drag to reorder"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/shell/avatar-studio-popover.tsx
|
||||
msgid "Drag, drop, or paste an image"
|
||||
msgstr "छवि खींचें, छोड़ें या पेस्ट करें"
|
||||
|
||||
@ -2100,6 +2100,10 @@ msgstr "작업 기술 초안"
|
||||
msgid "Drafting the spec…"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/SortableGroup.tsx
|
||||
msgid "Drag to reorder"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/shell/avatar-studio-popover.tsx
|
||||
msgid "Drag, drop, or paste an image"
|
||||
msgstr "이미지를 끌어다 놓거나 붙여넣으세요"
|
||||
|
||||
@ -2100,6 +2100,10 @@ msgstr "Habilidade de rascunho"
|
||||
msgid "Drafting the spec…"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/SortableGroup.tsx
|
||||
msgid "Drag to reorder"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/shell/avatar-studio-popover.tsx
|
||||
msgid "Drag, drop, or paste an image"
|
||||
msgstr "Arraste, solte ou cole uma imagem"
|
||||
|
||||
@ -2100,6 +2100,10 @@ msgstr "Черновик навыка"
|
||||
msgid "Drafting the spec…"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/SortableGroup.tsx
|
||||
msgid "Drag to reorder"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/shell/avatar-studio-popover.tsx
|
||||
msgid "Drag, drop, or paste an image"
|
||||
msgstr "Перетащите или вставьте изображение"
|
||||
|
||||
@ -2100,6 +2100,10 @@ msgstr "Taslak beceri"
|
||||
msgid "Drafting the spec…"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/SortableGroup.tsx
|
||||
msgid "Drag to reorder"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/shell/avatar-studio-popover.tsx
|
||||
msgid "Drag, drop, or paste an image"
|
||||
msgstr "Görüntüyü sürükleyip bırakın veya yapıştırın"
|
||||
|
||||
@ -2100,6 +2100,10 @@ msgstr "技能草稿"
|
||||
msgid "Drafting the spec…"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/SortableGroup.tsx
|
||||
msgid "Drag to reorder"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/shell/avatar-studio-popover.tsx
|
||||
msgid "Drag, drop, or paste an image"
|
||||
msgstr "拖放或粘贴图片"
|
||||
|
||||
@ -1,10 +1,5 @@
|
||||
import { closestCenter, DndContext, DragOverlay } from "@dnd-kit/core";
|
||||
import {
|
||||
SortableContext,
|
||||
sortableKeyboardCoordinates,
|
||||
verticalListSortingStrategy,
|
||||
} from "@dnd-kit/sortable";
|
||||
import { CSS as DndCSS } from "@dnd-kit/utilities";
|
||||
import { closestCenter, DndContext } from "@dnd-kit/core";
|
||||
import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
||||
import { Trans, useLingui } from "@lingui/react/macro";
|
||||
import type {
|
||||
Bot,
|
||||
@ -72,13 +67,10 @@ import {
|
||||
ArrowLeft,
|
||||
Calendar,
|
||||
Globe,
|
||||
LayoutGrid,
|
||||
PanelRight,
|
||||
Pencil,
|
||||
Plus,
|
||||
RefreshCw,
|
||||
Search,
|
||||
Settings,
|
||||
Trash2,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
@ -1320,9 +1312,7 @@ export function ShellPage() {
|
||||
mainConversationEntry,
|
||||
projectSidebarGroups,
|
||||
sensors,
|
||||
setDraggedProjectId,
|
||||
handleProjectDragEnd,
|
||||
handleProjectDragStart,
|
||||
} = useSidebarModel({
|
||||
query,
|
||||
spaces,
|
||||
@ -2943,8 +2933,6 @@ export function ShellPage() {
|
||||
sensors={sensors}
|
||||
collisionDetection={closestCenter}
|
||||
onDragEnd={handleProjectDragEnd}
|
||||
onDragStart={handleProjectDragStart}
|
||||
onDragCancel={() => setDraggedProjectId(null)}
|
||||
>
|
||||
<SortableContext
|
||||
items={projectSidebarGroups.filter((g) => g.title).map((g) => g.spaceId)}
|
||||
@ -3544,44 +3532,6 @@ export function ShellPage() {
|
||||
onImport={(manifest) => importBot(manifest)}
|
||||
/>
|
||||
) : null}
|
||||
{/* Centered Create Bot Modal */}
|
||||
{showCreateBotModal &&
|
||||
createPortal(
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<button
|
||||
type="button"
|
||||
className="absolute inset-0 bg-overlay"
|
||||
aria-label={t`Close`}
|
||||
onClick={() => setShowCreateBotModal(false)}
|
||||
/>
|
||||
<div className="relative z-10 max-h-[90vh] w-[480px] overflow-y-auto rounded-2xl border border-border bg-popover p-6 text-popover-foreground shadow-2xl">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h2 className="text-lg font-semibold text-foreground">
|
||||
<Trans>Create new Bot</Trans>
|
||||
</h2>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowCreateBotModal(false)}
|
||||
className="text-muted-foreground hover:text-foreground"
|
||||
aria-label={t`Close`}
|
||||
>
|
||||
<X strokeWidth={1.8} className="size-icon-md" />
|
||||
</button>
|
||||
</div>
|
||||
<CreateBotForm
|
||||
onCancel={() => setShowCreateBotModal(false)}
|
||||
onCreate={async (input) => {
|
||||
await createBot(input);
|
||||
}}
|
||||
onImport={async (manifest) => {
|
||||
await importBot(manifest);
|
||||
setShowCreateBotModal(false);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>,
|
||||
document.body,
|
||||
)}
|
||||
{panel === "settings" && active ? (
|
||||
<BotSettings
|
||||
key={active.id}
|
||||
@ -3773,6 +3723,44 @@ export function ShellPage() {
|
||||
</div>
|
||||
) : null}
|
||||
</aside>
|
||||
{/* Centered Create Bot Modal */}
|
||||
{showCreateBotModal &&
|
||||
createPortal(
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<button
|
||||
type="button"
|
||||
className="absolute inset-0 bg-overlay"
|
||||
aria-label={t`Close`}
|
||||
onClick={() => setShowCreateBotModal(false)}
|
||||
/>
|
||||
<div className="relative z-10 max-h-[90vh] w-[480px] overflow-y-auto rounded-2xl border border-border bg-popover p-6 text-popover-foreground shadow-2xl">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h2 className="text-lg font-semibold text-foreground">
|
||||
<Trans>Create new Bot</Trans>
|
||||
</h2>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowCreateBotModal(false)}
|
||||
className="text-muted-foreground hover:text-foreground"
|
||||
aria-label={t`Close`}
|
||||
>
|
||||
<X strokeWidth={1.8} className="size-icon-md" />
|
||||
</button>
|
||||
</div>
|
||||
<CreateBotForm
|
||||
onCancel={() => setShowCreateBotModal(false)}
|
||||
onCreate={async (input) => {
|
||||
await createBot(input);
|
||||
}}
|
||||
onImport={async (manifest) => {
|
||||
await importBot(manifest);
|
||||
setShowCreateBotModal(false);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>,
|
||||
document.body,
|
||||
)}
|
||||
|
||||
<Suspense fallback={null}>
|
||||
{contextChat && botMenu ? (
|
||||
|
||||
@ -32,7 +32,6 @@ export function useSidebarModel({
|
||||
setProjectOrder(orderedIds);
|
||||
writeProjectSidebarOrder(orderedIds);
|
||||
}, []);
|
||||
const [draggedProjectId, setDraggedProjectId] = useState<string | null>(null);
|
||||
const sensors = useSensors(
|
||||
useSensor(MouseSensor, { activationConstraint: { distance: 8 } }),
|
||||
useSensor(TouchSensor, { activationConstraint: { distance: 8 } }),
|
||||
@ -242,9 +241,6 @@ export function useSidebarModel({
|
||||
},
|
||||
[projectSidebarGroups, handleReorderProjects],
|
||||
);
|
||||
const handleProjectDragStart = useCallback((event: { active: { id: string | number } }) => {
|
||||
setDraggedProjectId(String(event.active.id));
|
||||
}, []);
|
||||
|
||||
return {
|
||||
homeSpaceBots,
|
||||
@ -252,8 +248,6 @@ export function useSidebarModel({
|
||||
mainConversationEntry,
|
||||
projectSidebarGroups,
|
||||
sensors,
|
||||
setDraggedProjectId,
|
||||
handleProjectDragEnd,
|
||||
handleProjectDragStart,
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user