feat(ai-chat): move AI chat icon into the global top bar

Move the AI-chat toggle icon (IconSparkles) from the page header menu
into the global top bar, placed next to the notifications icon. The
"AI chat enabled" gate (workspace.settings.ai.chat) is preserved, and
the icon style is aligned with the neighbouring notifications icon
(subtle, size sm). As a result the entry point is now available on all
routes instead of only on page routes.

- app-header.tsx: render the gated AI-chat ActionIcon before
  NotificationPopover; wire it to aiChatWindowOpenAtom.
- page-header-menu.tsx: remove the old AI icon block and its now-unused
  imports/locals.
This commit is contained in:
vvzvlad
2026-06-18 17:50:42 +03:00
parent 3d9c9daf98
commit 8f5be58f9b
2 changed files with 24 additions and 20 deletions

View File

@@ -1,19 +1,23 @@
import {
ActionIcon,
Box,
Group,
Text,
Tooltip,
} from "@mantine/core";
import { IconSparkles } from "@tabler/icons-react";
import classes from "./app-header.module.css";
import { BrandLogo } from "@/components/ui/brand-logo";
import TopMenu from "@/components/layouts/global/top-menu.tsx";
import { Link } from "react-router-dom";
import APP_ROUTE from "@/lib/app-route.ts";
import { useAtom } from "jotai";
import { useAtom, useSetAtom } from "jotai";
import {
desktopSidebarAtom,
mobileSidebarAtom,
} from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts";
import { aiChatWindowOpenAtom } from "@/features/ai-chat/atoms/ai-chat-atom.ts";
import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts";
import { useToggleSidebar } from "@/components/layouts/global/hooks/hooks/use-toggle-sidebar.ts";
import SidebarToggle from "@/components/ui/sidebar-toggle-button.tsx";
import { useTranslation } from "react-i18next";
@@ -38,6 +42,11 @@ export function AppHeader() {
const [desktopOpened] = useAtom(desktopSidebarAtom);
const toggleDesktop = useToggleSidebar(desktopSidebarAtom);
const [workspace] = useAtom(workspaceAtom);
const setAiChatWindowOpen = useSetAtom(aiChatWindowOpenAtom);
// AI chat entry point: only shown when the workspace enables it (A7 gate).
const aiChatEnabled = workspace?.settings?.ai?.chat === true;
const items = links.map((link) => (
<Link key={link.label} to={link.link} className={classes.link}>
{t(link.label)}
@@ -105,6 +114,19 @@ export function AppHeader() {
</div>
<Group px={"xl"} wrap="nowrap">
{aiChatEnabled && (
<Tooltip label={t("AI chat")} withArrow>
<ActionIcon
variant="subtle"
color="dark"
size="sm"
aria-label={t("AI chat")}
onClick={() => setAiChatWindowOpen((v) => !v)}
>
<IconSparkles size={20} />
</ActionIcon>
</Tooltip>
)}
<NotificationPopover />
<TopMenu />
</Group>

View File

@@ -12,7 +12,6 @@ import {
IconMarkdown,
IconMessage,
IconPrinter,
IconSparkles,
IconStar,
IconStarFilled,
IconTrash,
@@ -20,8 +19,7 @@ import {
} from "@tabler/icons-react";
import React, { useEffect, useRef, useState } from "react";
import { useAsideTriggerProps } from "@/hooks/use-toggle-aside.tsx";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import { aiChatWindowOpenAtom } from "@/features/ai-chat/atoms/ai-chat-atom.ts";
import { useAtom, useAtomValue } from "jotai";
import { historyAtoms } from "@/features/page-history/atoms/history-atoms.ts";
import { useDisclosure, useHotkeys } from "@mantine/hooks";
import { useClipboard } from "@/hooks/use-clipboard";
@@ -65,7 +63,6 @@ export default function PageHeaderMenu({ readOnly }: PageHeaderMenuProps) {
const { t } = useTranslation();
const commentsTriggerProps = useAsideTriggerProps("comments");
const tocTriggerProps = useAsideTriggerProps("toc");
const setAiChatWindowOpen = useSetAtom(aiChatWindowOpenAtom);
const { pageSlug } = useParams();
const { data: page } = usePageQuery({
pageId: extractPageSlugId(pageSlug),
@@ -74,8 +71,6 @@ export default function PageHeaderMenu({ readOnly }: PageHeaderMenuProps) {
const [workspace] = useAtom(workspaceAtom);
// Community public-sharing entry point (replaces the removed EE PageShareModal)
const workspaceSharingDisabled = workspace?.settings?.sharing?.disabled === true;
// AI chat entry point: only shown when the workspace enables it (A7 gate).
const aiChatEnabled = workspace?.settings?.ai?.chat === true;
useHotkeys(
[
@@ -132,19 +127,6 @@ export default function PageHeaderMenu({ readOnly }: PageHeaderMenuProps) {
</ActionIcon>
</Tooltip>
{aiChatEnabled && (
<Tooltip label={t("AI chat")} openDelay={250} withArrow>
<ActionIcon
variant="subtle"
color="dark"
aria-label={t("AI chat")}
onClick={() => setAiChatWindowOpen((v) => !v)}
>
<IconSparkles size={20} stroke={2} />
</ActionIcon>
</Tooltip>
)}
<PageActionMenu readOnly={readOnly} />
</>
);