fix(ai-chat): restore workspace AI chat enable toggle for self-hosted

The EE-frontend removal (a88b3f77) deleted enable-ai-chat.tsx, the only UI
that set the workspace flag settings.ai.chat. The backend gates remained:
the header assistant icon (page-header-menu) and the /ai-chat/stream endpoint
both require settings.ai.chat === true, and the flag is auto-enabled only in
cloud mode. As a result, self-hosted community builds could configure an AI
provider but had no way to turn the chat on, so the assistant icon never
appeared.

Restore a single admin toggle wired to the already-existing backend `aiChat`
field, modeled on the adjacent MCP settings switch:
- add aiChat?: boolean to the client IWorkspace type
- add AiChatSettings component (optimistic update, revert-on-error,
  workspaceAtom sync so the icon updates without reload)
- render it (admin-only) in workspace settings between AI / Models and
  AI / External tools (MCP)

Generative AI and AI search toggles, removed in the same commit, are left
out of scope.
This commit is contained in:
vvzvlad
2026-06-18 01:17:07 +03:00
parent 4f6b667cf7
commit 060c14cc27
3 changed files with 68 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts";
import { useAtom } from "jotai";
import { useState } from "react";
import { updateWorkspace } from "@/features/workspace/services/workspace-service.ts";
import { Switch, Stack } from "@mantine/core";
import { notifications } from "@mantine/notifications";
import useUserRole from "@/hooks/use-user-role.tsx";
import { useTranslation } from "react-i18next";
export default function AiChatSettings() {
const { t } = useTranslation();
const [workspace, setWorkspace] = useAtom(workspaceAtom);
const { isAdmin } = useUserRole();
const [checked, setChecked] = useState<boolean>(
workspace?.settings?.ai?.chat ?? false,
);
const [isLoading, setIsLoading] = useState(false);
async function handleToggle(value: boolean) {
setIsLoading(true);
const previous = checked;
setChecked(value); // optimistic update
try {
const updated = await updateWorkspace({ aiChat: value });
// Force settings.ai.chat to the new value so the atom is consistent
// even if the response shape omits it.
setWorkspace({
...updated,
settings: {
...updated.settings,
ai: { ...updated.settings?.ai, chat: value },
},
});
notifications.show({ message: t("Updated successfully") });
} catch (err) {
console.log(err);
setChecked(previous); // revert on failure
notifications.show({
message: t("Failed to update data"),
color: "red",
});
} finally {
setIsLoading(false);
}
}
return (
<Stack mt="sm">
<Switch
label={t("AI chat")}
description={t(
"Enable the AI chat assistant so users can have multi-turn conversations with AI about your workspace content.",
)}
checked={checked}
disabled={!isAdmin || isLoading}
onChange={(event) => handleToggle(event.currentTarget.checked)}
/>
</Stack>
);
}

View File

@@ -23,6 +23,7 @@ export interface IWorkspace {
generativeAi?: boolean;
disablePublicSharing?: boolean;
mcpEnabled?: boolean;
aiChat?: boolean;
trashRetentionDays?: number;
restrictApiToAdmins?: boolean;
allowMemberTemplates?: boolean;

View File

@@ -3,6 +3,7 @@ import WorkspaceNameForm from "@/features/workspace/components/settings/componen
import WorkspaceIcon from "@/features/workspace/components/settings/components/workspace-icon.tsx";
import McpSettings from "@/features/workspace/components/settings/components/mcp-settings.tsx";
import AiProviderSettings from "@/features/workspace/components/settings/components/ai-provider-settings.tsx";
import AiChatSettings from "@/features/workspace/components/settings/components/ai-chat-settings.tsx";
import AiMcpServers from "@/features/workspace/components/settings/components/ai-mcp-servers.tsx";
import { useTranslation } from "react-i18next";
import { getAppName } from "@/lib/config.ts";
@@ -36,6 +37,11 @@ export default function WorkspaceSettings() {
<Divider my="lg" />
<SettingsTitle title={t("AI / Chat")} />
<AiChatSettings />
<Divider my="lg" />
<SettingsTitle title={t("AI / External tools (MCP)")} />
<AiMcpServers />
</>