mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-04 00:28:33 +00:00
fix: chat session cannot delete (#14312)
fix #14309 #### PR Dependency Tree * **PR #14312** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added AI chat session deletion with confirmation dialogs and success/failure notifications. * Localized AI chat panel labels, loading messages, and session management text across multiple languages. * **Documentation** * Added internationalization support for chat panel titles, history loading states, and deletion confirmations. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
import type { CopilotChatHistoryFragment } from '@affine/graphql';
|
||||
import type { NotificationService } from '@blocksuite/affine/shared/services';
|
||||
|
||||
import type { DocDisplayConfig } from '../ai-chat-chips';
|
||||
import type { ChatStatus } from '../ai-chat-messages';
|
||||
import { AIChatToolbar } from './ai-chat-toolbar';
|
||||
|
||||
export type ConfigureAIChatToolbarOptions = {
|
||||
session: CopilotChatHistoryFragment | null | undefined;
|
||||
workspaceId: string;
|
||||
docId?: string;
|
||||
status: ChatStatus;
|
||||
docDisplayConfig: DocDisplayConfig;
|
||||
notificationService: NotificationService;
|
||||
onNewSession: () => void;
|
||||
onTogglePin: () => Promise<void>;
|
||||
onOpenSession: (sessionId: string) => void;
|
||||
onOpenDoc: (docId: string, sessionId: string) => void;
|
||||
onSessionDelete: (session: BlockSuitePresets.AIRecentSession) => void;
|
||||
};
|
||||
|
||||
export function getOrCreateAIChatToolbar(
|
||||
current: AIChatToolbar | null | undefined
|
||||
): AIChatToolbar {
|
||||
return current ?? new AIChatToolbar();
|
||||
}
|
||||
|
||||
export function configureAIChatToolbar(
|
||||
tool: AIChatToolbar,
|
||||
options: ConfigureAIChatToolbarOptions
|
||||
): AIChatToolbar {
|
||||
tool.session = options.session;
|
||||
tool.workspaceId = options.workspaceId;
|
||||
tool.docId = options.docId;
|
||||
tool.status = options.status;
|
||||
tool.docDisplayConfig = options.docDisplayConfig;
|
||||
tool.notificationService = options.notificationService;
|
||||
tool.onNewSession = options.onNewSession;
|
||||
tool.onTogglePin = options.onTogglePin;
|
||||
tool.onOpenSession = options.onOpenSession;
|
||||
tool.onOpenDoc = options.onOpenDoc;
|
||||
tool.onSessionDelete = options.onSessionDelete;
|
||||
return tool;
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './ai-chat-toolbar';
|
||||
export * from './ai-session-history';
|
||||
export * from './configure-ai-chat-toolbar';
|
||||
|
||||
@@ -89,6 +89,7 @@ const AllDocsButton = () => {
|
||||
};
|
||||
|
||||
const AIChatButton = () => {
|
||||
const t = useI18n();
|
||||
const featureFlagService = useService(FeatureFlagService);
|
||||
const serverService = useService(ServerService);
|
||||
const serverFeatures = useLiveData(serverService.server.features$);
|
||||
@@ -108,7 +109,9 @@ const AIChatButton = () => {
|
||||
|
||||
return (
|
||||
<MenuLinkItem icon={<AiOutlineIcon />} active={aiChatActive} to={'/chat'}>
|
||||
<span data-testid="ai-chat">Intelligence</span>
|
||||
<span data-testid="ai-chat">
|
||||
{t['com.affine.workspaceSubPath.chat']()}
|
||||
</span>
|
||||
</MenuLinkItem>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import type { I18nInstance } from '@affine/i18n';
|
||||
import type { NotificationService } from '@blocksuite/affine/shared/services';
|
||||
|
||||
export type SessionDeleteCleanupFn = (
|
||||
session: BlockSuitePresets.AIRecentSession
|
||||
) => Promise<void>;
|
||||
|
||||
export type CreateSessionDeleteHandlerOptions = {
|
||||
t: I18nInstance;
|
||||
notificationService: NotificationService;
|
||||
cleanupSession: SessionDeleteCleanupFn;
|
||||
canDeleteSession?: (session: BlockSuitePresets.AIRecentSession) => boolean;
|
||||
isActiveSession?: (session: BlockSuitePresets.AIRecentSession) => boolean;
|
||||
onActiveSessionDeleted?: () => void;
|
||||
};
|
||||
|
||||
export function createSessionDeleteHandler({
|
||||
t,
|
||||
notificationService,
|
||||
cleanupSession,
|
||||
canDeleteSession,
|
||||
isActiveSession,
|
||||
onActiveSessionDeleted,
|
||||
}: CreateSessionDeleteHandlerOptions) {
|
||||
return async (sessionToDelete: BlockSuitePresets.AIRecentSession) => {
|
||||
if (canDeleteSession && !canDeleteSession(sessionToDelete)) {
|
||||
notificationService.toast(
|
||||
t['com.affine.ai.chat-panel.session.delete.toast.failed']()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const confirm = await notificationService.confirm({
|
||||
title: t['com.affine.ai.chat-panel.session.delete.confirm.title'](),
|
||||
message: t['com.affine.ai.chat-panel.session.delete.confirm.message'](),
|
||||
confirmText: t['Delete'](),
|
||||
cancelText: t['Cancel'](),
|
||||
});
|
||||
|
||||
if (!confirm) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await cleanupSession(sessionToDelete);
|
||||
notificationService.toast(
|
||||
t['com.affine.ai.chat-panel.session.delete.toast.success']()
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
notificationService.toast(
|
||||
t['com.affine.ai.chat-panel.session.delete.toast.failed']()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isActiveSession?.(sessionToDelete)) {
|
||||
onActiveSessionDeleted?.();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -5,7 +5,11 @@ import {
|
||||
type ChatContextValue,
|
||||
} from '@affine/core/blocksuite/ai/components/ai-chat-content';
|
||||
import type { ChatStatus } from '@affine/core/blocksuite/ai/components/ai-chat-messages';
|
||||
import { AIChatToolbar } from '@affine/core/blocksuite/ai/components/ai-chat-toolbar';
|
||||
import {
|
||||
AIChatToolbar,
|
||||
configureAIChatToolbar,
|
||||
getOrCreateAIChatToolbar,
|
||||
} from '@affine/core/blocksuite/ai/components/ai-chat-toolbar';
|
||||
import type { PromptKey } from '@affine/core/blocksuite/ai/provider/prompt';
|
||||
import { getViewManager } from '@affine/core/blocksuite/manager/view';
|
||||
import { NotificationServiceImpl } from '@affine/core/blocksuite/view-extensions/editor-view/notification-service';
|
||||
@@ -37,6 +41,7 @@ import {
|
||||
WorkbenchService,
|
||||
} from '@affine/core/modules/workbench';
|
||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { RefNodeSlotsProvider } from '@blocksuite/affine/inlines/reference';
|
||||
import { BlockStdScope } from '@blocksuite/affine/std';
|
||||
import type { Workspace } from '@blocksuite/affine/store';
|
||||
@@ -45,6 +50,7 @@ import { useFramework, useService } from '@toeverything/infra';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import { createSessionDeleteHandler } from '../chat-panel-utils';
|
||||
import * as styles from './index.css';
|
||||
|
||||
type CopilotSession = Awaited<ReturnType<CopilotClient['getSession']>>;
|
||||
@@ -88,6 +94,7 @@ function useMockStd() {
|
||||
}
|
||||
|
||||
export const Component = () => {
|
||||
const t = useI18n();
|
||||
const framework = useFramework();
|
||||
const [isBodyProvided, setIsBodyProvided] = useState(false);
|
||||
const [isHeaderProvided, setIsHeaderProvided] = useState(false);
|
||||
@@ -193,10 +200,46 @@ export const Component = () => {
|
||||
);
|
||||
|
||||
const confirmModal = useConfirmModal();
|
||||
const notificationService = useMemo(
|
||||
() =>
|
||||
new NotificationServiceImpl(
|
||||
confirmModal.closeConfirmModal,
|
||||
confirmModal.openConfirmModal
|
||||
),
|
||||
[confirmModal.closeConfirmModal, confirmModal.openConfirmModal]
|
||||
);
|
||||
const specs = useAISpecs();
|
||||
const mockStd = useMockStd();
|
||||
const handleAISubscribe = useAISubscribe();
|
||||
|
||||
const deleteSession = useMemo(
|
||||
() =>
|
||||
createSessionDeleteHandler({
|
||||
t,
|
||||
notificationService,
|
||||
cleanupSession: async sessionToDelete => {
|
||||
await client.cleanupSessions({
|
||||
workspaceId: sessionToDelete.workspaceId,
|
||||
docId: sessionToDelete.docId || undefined,
|
||||
sessionIds: [sessionToDelete.sessionId],
|
||||
});
|
||||
},
|
||||
isActiveSession: sessionToDelete =>
|
||||
sessionToDelete.sessionId === currentSession?.sessionId,
|
||||
onActiveSessionDeleted: () => {
|
||||
setCurrentSession(null);
|
||||
reMountChatContent();
|
||||
},
|
||||
}),
|
||||
[
|
||||
client,
|
||||
currentSession?.sessionId,
|
||||
notificationService,
|
||||
reMountChatContent,
|
||||
t,
|
||||
]
|
||||
);
|
||||
|
||||
// init or update ai-chat-content
|
||||
useEffect(() => {
|
||||
if (!isBodyProvided) {
|
||||
@@ -223,10 +266,7 @@ export const Component = () => {
|
||||
);
|
||||
content.peekViewService = framework.get(PeekViewService);
|
||||
content.affineThemeService = framework.get(AppThemeService);
|
||||
content.notificationService = new NotificationServiceImpl(
|
||||
confirmModal.closeConfirmModal,
|
||||
confirmModal.openConfirmModal
|
||||
);
|
||||
content.notificationService = notificationService;
|
||||
content.aiDraftService = framework.get(AIDraftService);
|
||||
content.aiToolsConfigService = framework.get(AIToolsConfigService);
|
||||
content.serverService = framework.get(ServerService);
|
||||
@@ -258,6 +298,7 @@ export const Component = () => {
|
||||
workspaceId,
|
||||
confirmModal,
|
||||
onContextChange,
|
||||
notificationService,
|
||||
specs,
|
||||
onOpenDoc,
|
||||
handleAISubscribe,
|
||||
@@ -268,39 +309,31 @@ export const Component = () => {
|
||||
if (!isHeaderProvided || !chatToolContainerRef.current) {
|
||||
return;
|
||||
}
|
||||
let tool = chatTool;
|
||||
|
||||
if (!tool) {
|
||||
tool = new AIChatToolbar();
|
||||
}
|
||||
|
||||
tool.session = currentSession;
|
||||
tool.workspaceId = workspaceId;
|
||||
tool.status = status;
|
||||
tool.docDisplayConfig = docDisplayConfig;
|
||||
tool.onOpenSession = onOpenSession;
|
||||
tool.notificationService = new NotificationServiceImpl(
|
||||
confirmModal.closeConfirmModal,
|
||||
confirmModal.openConfirmModal
|
||||
);
|
||||
|
||||
tool.onNewSession = () => {
|
||||
if (!currentSession) return;
|
||||
setCurrentSession(null);
|
||||
reMountChatContent();
|
||||
};
|
||||
|
||||
tool.onTogglePin = async () => {
|
||||
await togglePin();
|
||||
};
|
||||
|
||||
tool.onOpenDoc = (docId: string, sessionId: string) => {
|
||||
const { workbench } = framework.get(WorkbenchService);
|
||||
const viewService = framework.get(ViewService);
|
||||
workbench.open(`/${docId}?sessionId=${sessionId}`, { at: 'active' });
|
||||
workbench.openSidebar();
|
||||
viewService.view.activeSidebarTab('chat');
|
||||
};
|
||||
const tool = getOrCreateAIChatToolbar(chatTool);
|
||||
configureAIChatToolbar(tool, {
|
||||
session: currentSession,
|
||||
workspaceId,
|
||||
status,
|
||||
docDisplayConfig,
|
||||
notificationService,
|
||||
onOpenSession,
|
||||
onNewSession: () => {
|
||||
if (!currentSession) return;
|
||||
setCurrentSession(null);
|
||||
reMountChatContent();
|
||||
},
|
||||
onTogglePin: togglePin,
|
||||
onOpenDoc: (docId: string, sessionId: string) => {
|
||||
const { workbench } = framework.get(WorkbenchService);
|
||||
const viewService = framework.get(ViewService);
|
||||
workbench.open(`/${docId}?sessionId=${sessionId}`, { at: 'active' });
|
||||
workbench.openSidebar();
|
||||
viewService.view.activeSidebarTab('chat');
|
||||
},
|
||||
onSessionDelete: (sessionToDelete: BlockSuitePresets.AIRecentSession) => {
|
||||
deleteSession(sessionToDelete).catch(console.error);
|
||||
},
|
||||
});
|
||||
|
||||
// initial props
|
||||
if (!chatTool) {
|
||||
@@ -318,8 +351,10 @@ export const Component = () => {
|
||||
workspaceId,
|
||||
confirmModal,
|
||||
framework,
|
||||
deleteSession,
|
||||
status,
|
||||
reMountChatContent,
|
||||
notificationService,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -390,7 +425,7 @@ export const Component = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewTitle title="Intelligence" />
|
||||
<ViewTitle title={t['com.affine.workspaceSubPath.chat']()} />
|
||||
<ViewIcon icon="ai" />
|
||||
<ViewHeader>
|
||||
<div className={styles.chatHeader}>
|
||||
|
||||
@@ -6,7 +6,11 @@ import {
|
||||
type ChatContextValue,
|
||||
} from '@affine/core/blocksuite/ai/components/ai-chat-content';
|
||||
import type { ChatStatus } from '@affine/core/blocksuite/ai/components/ai-chat-messages';
|
||||
import { AIChatToolbar } from '@affine/core/blocksuite/ai/components/ai-chat-toolbar';
|
||||
import {
|
||||
AIChatToolbar,
|
||||
configureAIChatToolbar,
|
||||
getOrCreateAIChatToolbar,
|
||||
} from '@affine/core/blocksuite/ai/components/ai-chat-toolbar';
|
||||
import { createPlaygroundModal } from '@affine/core/blocksuite/ai/components/playground/modal';
|
||||
import { registerAIAppEffects } from '@affine/core/blocksuite/ai/effects/app';
|
||||
import type { AffineEditorContainer } from '@affine/core/blocksuite/block-suite-editor';
|
||||
@@ -31,6 +35,7 @@ import type {
|
||||
CopilotChatHistoryFragment,
|
||||
UpdateChatSessionInput,
|
||||
} from '@affine/graphql';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { RefNodeSlotsProvider } from '@blocksuite/affine/inlines/reference';
|
||||
import { DocModeProvider } from '@blocksuite/affine/shared/services';
|
||||
import { createSignalFromObservable } from '@blocksuite/affine/shared/utils';
|
||||
@@ -40,6 +45,7 @@ import { useFramework, useService } from '@toeverything/infra';
|
||||
import { html } from 'lit';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import { createSessionDeleteHandler } from '../../chat-panel-utils';
|
||||
import * as styles from './chat.css';
|
||||
import {
|
||||
resolveInitialSession,
|
||||
@@ -56,6 +62,7 @@ export interface SidebarTabProps {
|
||||
export const EditorChatPanel = ({ editor, onLoad }: SidebarTabProps) => {
|
||||
const framework = useFramework();
|
||||
const workbench = useService(WorkbenchService).workbench;
|
||||
const t = useI18n();
|
||||
|
||||
const { closeConfirmModal, openConfirmModal } = useConfirmModal();
|
||||
const notificationService = useMemo(
|
||||
@@ -230,30 +237,24 @@ export const EditorChatPanel = ({ editor, onLoad }: SidebarTabProps) => {
|
||||
[doc, openSession, session?.pinned, session?.sessionId, workbench]
|
||||
);
|
||||
|
||||
const deleteSession = useCallback(
|
||||
async (sessionToDelete: BlockSuitePresets.AIRecentSession) => {
|
||||
if (!AIProvider.histories) {
|
||||
return;
|
||||
}
|
||||
const confirm = await notificationService.confirm({
|
||||
title: 'Delete this history?',
|
||||
message:
|
||||
'Do you want to delete this AI conversation history? Once deleted, it cannot be recovered.',
|
||||
confirmText: 'Delete',
|
||||
cancelText: 'Cancel',
|
||||
});
|
||||
if (confirm) {
|
||||
await AIProvider.histories.cleanup(
|
||||
sessionToDelete.workspaceId,
|
||||
sessionToDelete.docId || undefined,
|
||||
[sessionToDelete.sessionId]
|
||||
);
|
||||
if (sessionToDelete.sessionId === session?.sessionId) {
|
||||
newSession();
|
||||
}
|
||||
}
|
||||
},
|
||||
[newSession, notificationService, session?.sessionId]
|
||||
const deleteSession = useMemo(
|
||||
() =>
|
||||
createSessionDeleteHandler({
|
||||
t,
|
||||
notificationService,
|
||||
canDeleteSession: () => Boolean(AIProvider.histories),
|
||||
cleanupSession: async sessionToDelete => {
|
||||
await AIProvider.histories?.cleanup(
|
||||
sessionToDelete.workspaceId,
|
||||
sessionToDelete.docId || undefined,
|
||||
[sessionToDelete.sessionId]
|
||||
);
|
||||
},
|
||||
isActiveSession: sessionToDelete =>
|
||||
sessionToDelete.sessionId === session?.sessionId,
|
||||
onActiveSessionDeleted: newSession,
|
||||
}),
|
||||
[newSession, notificationService, session?.sessionId, t]
|
||||
);
|
||||
|
||||
const togglePin = useCallback(async () => {
|
||||
@@ -460,31 +461,26 @@ export const EditorChatPanel = ({ editor, onLoad }: SidebarTabProps) => {
|
||||
return;
|
||||
}
|
||||
|
||||
let tool = chatToolbar;
|
||||
|
||||
if (!tool) {
|
||||
tool = new AIChatToolbar();
|
||||
}
|
||||
|
||||
tool.session = session;
|
||||
tool.workspaceId = doc.workspace.id;
|
||||
tool.docId = doc.id;
|
||||
tool.status = status;
|
||||
tool.docDisplayConfig = docDisplayConfig;
|
||||
tool.notificationService = notificationService;
|
||||
tool.onNewSession = newSession;
|
||||
tool.onTogglePin = togglePin;
|
||||
tool.onOpenSession = (sessionId: string) => {
|
||||
openSession(sessionId).catch(console.error);
|
||||
};
|
||||
tool.onOpenDoc = (docId: string, sessionId: string) => {
|
||||
openDoc(docId, sessionId).catch(console.error);
|
||||
};
|
||||
tool.onSessionDelete = (
|
||||
sessionToDelete: BlockSuitePresets.AIRecentSession
|
||||
) => {
|
||||
deleteSession(sessionToDelete).catch(console.error);
|
||||
};
|
||||
const tool = getOrCreateAIChatToolbar(chatToolbar);
|
||||
configureAIChatToolbar(tool, {
|
||||
session,
|
||||
workspaceId: doc.workspace.id,
|
||||
docId: doc.id,
|
||||
status,
|
||||
docDisplayConfig,
|
||||
notificationService,
|
||||
onNewSession: newSession,
|
||||
onTogglePin: togglePin,
|
||||
onOpenSession: (sessionId: string) => {
|
||||
openSession(sessionId).catch(console.error);
|
||||
},
|
||||
onOpenDoc: (docId: string, sessionId: string) => {
|
||||
openDoc(docId, sessionId).catch(console.error);
|
||||
},
|
||||
onSessionDelete: (sessionToDelete: BlockSuitePresets.AIRecentSession) => {
|
||||
deleteSession(sessionToDelete).catch(console.error);
|
||||
},
|
||||
});
|
||||
|
||||
if (!chatToolbar) {
|
||||
chatToolbarContainerRef.current.append(tool);
|
||||
@@ -618,7 +614,7 @@ export const EditorChatPanel = ({ editor, onLoad }: SidebarTabProps) => {
|
||||
<div className={styles.loading}>
|
||||
<Logo1Icon className={styles.loadingIcon} />
|
||||
<div className={styles.loadingTitle}>
|
||||
AFFiNE AI is loading history...
|
||||
{t['com.affine.ai.chat-panel.loading-history']()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -628,10 +624,13 @@ export const EditorChatPanel = ({ editor, onLoad }: SidebarTabProps) => {
|
||||
<div className={styles.title}>
|
||||
{isEmbedding ? (
|
||||
<span data-testid="chat-panel-embedding-progress">
|
||||
Embedding {done}/{total}
|
||||
{t.t('com.affine.ai.chat-panel.embedding-progress', {
|
||||
done,
|
||||
total,
|
||||
})}
|
||||
</span>
|
||||
) : (
|
||||
'AFFiNE AI'
|
||||
t['com.affine.ai.chat-panel.title']()
|
||||
)}
|
||||
</div>
|
||||
{playgroundVisible ? (
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
{
|
||||
"ar": 99,
|
||||
"ar": 98,
|
||||
"ca": 100,
|
||||
"da": 4,
|
||||
"de": 100,
|
||||
"el-GR": 99,
|
||||
"de": 99,
|
||||
"el-GR": 98,
|
||||
"en": 100,
|
||||
"es-AR": 99,
|
||||
"es-AR": 98,
|
||||
"es-CL": 100,
|
||||
"es": 99,
|
||||
"fa": 99,
|
||||
"es": 98,
|
||||
"fa": 98,
|
||||
"fr": 100,
|
||||
"hi": 2,
|
||||
"it-IT": 100,
|
||||
"it": 1,
|
||||
"ja": 99,
|
||||
"ko": 100,
|
||||
"nb-NO": 49,
|
||||
"ja": 98,
|
||||
"ko": 99,
|
||||
"nb-NO": 48,
|
||||
"pl": 100,
|
||||
"pt-BR": 99,
|
||||
"pt-BR": 98,
|
||||
"ru": 100,
|
||||
"sv-SE": 99,
|
||||
"uk": 99,
|
||||
"uk": 98,
|
||||
"ur": 2,
|
||||
"zh-Hans": 100,
|
||||
"zh-Hant": 99
|
||||
|
||||
@@ -867,6 +867,37 @@ export function useAFFiNEI18N(): {
|
||||
* `Failed to insert template, please try again.`
|
||||
*/
|
||||
["com.affine.ai.template-insert.failed"](): string;
|
||||
/**
|
||||
* `AFFiNE AI`
|
||||
*/
|
||||
["com.affine.ai.chat-panel.title"](): string;
|
||||
/**
|
||||
* `AFFiNE AI is loading history...`
|
||||
*/
|
||||
["com.affine.ai.chat-panel.loading-history"](): string;
|
||||
/**
|
||||
* `Embedding {{done}}/{{total}}`
|
||||
*/
|
||||
["com.affine.ai.chat-panel.embedding-progress"](options: Readonly<{
|
||||
done: string;
|
||||
total: string;
|
||||
}>): string;
|
||||
/**
|
||||
* `Delete this history?`
|
||||
*/
|
||||
["com.affine.ai.chat-panel.session.delete.confirm.title"](): string;
|
||||
/**
|
||||
* `Do you want to delete this AI conversation history? Once deleted, it cannot be recovered.`
|
||||
*/
|
||||
["com.affine.ai.chat-panel.session.delete.confirm.message"](): string;
|
||||
/**
|
||||
* `History deleted`
|
||||
*/
|
||||
["com.affine.ai.chat-panel.session.delete.toast.success"](): string;
|
||||
/**
|
||||
* `Failed to delete history`
|
||||
*/
|
||||
["com.affine.ai.chat-panel.session.delete.toast.failed"](): string;
|
||||
/**
|
||||
* `All docs`
|
||||
*/
|
||||
@@ -7246,6 +7277,10 @@ export function useAFFiNEI18N(): {
|
||||
* `All docs`
|
||||
*/
|
||||
["com.affine.workspaceSubPath.all"](): string;
|
||||
/**
|
||||
* `Intelligence`
|
||||
*/
|
||||
["com.affine.workspaceSubPath.chat"](): string;
|
||||
/**
|
||||
* `Trash`
|
||||
*/
|
||||
|
||||
@@ -206,6 +206,13 @@
|
||||
"com.affine.ai.login-required.dialog-content": "To use AFFiNE AI, please sign in to your AFFiNE Cloud account.",
|
||||
"com.affine.ai.login-required.dialog-title": "Sign in to continue",
|
||||
"com.affine.ai.template-insert.failed": "Failed to insert template, please try again.",
|
||||
"com.affine.ai.chat-panel.title": "AFFiNE AI",
|
||||
"com.affine.ai.chat-panel.loading-history": "AFFiNE AI is loading history...",
|
||||
"com.affine.ai.chat-panel.embedding-progress": "Embedding {{done}}/{{total}}",
|
||||
"com.affine.ai.chat-panel.session.delete.confirm.title": "Delete this history?",
|
||||
"com.affine.ai.chat-panel.session.delete.confirm.message": "Do you want to delete this AI conversation history? Once deleted, it cannot be recovered.",
|
||||
"com.affine.ai.chat-panel.session.delete.toast.success": "History deleted",
|
||||
"com.affine.ai.chat-panel.session.delete.toast.failed": "Failed to delete history",
|
||||
"com.affine.all-pages.header": "All docs",
|
||||
"com.affine.app-sidebar.learn-more": "Learn more",
|
||||
"com.affine.app-sidebar.star-us": "Star us",
|
||||
@@ -1813,6 +1820,7 @@
|
||||
"com.affine.workspaceList.workspaceListType.local": "Local storage",
|
||||
"com.affine.workspaceList.addServer": "Add Server",
|
||||
"com.affine.workspaceSubPath.all": "All docs",
|
||||
"com.affine.workspaceSubPath.chat": "Intelligence",
|
||||
"com.affine.workspaceSubPath.trash": "Trash",
|
||||
"com.affine.workspaceSubPath.trash.empty-description": "Deleted docs will appear here.",
|
||||
"com.affine.write_with_a_blank_page": "Write with a blank page",
|
||||
|
||||
@@ -206,6 +206,13 @@
|
||||
"com.affine.ai.login-required.dialog-content": "要使用 AFFiNE AI,请先登录您的 AFFiNE Cloud 帐户。",
|
||||
"com.affine.ai.login-required.dialog-title": "登录以继续",
|
||||
"com.affine.ai.template-insert.failed": "插入模板失败,请重试。",
|
||||
"com.affine.ai.chat-panel.title": "AFFiNE AI",
|
||||
"com.affine.ai.chat-panel.loading-history": "AFFiNE AI 正在加载历史记录...",
|
||||
"com.affine.ai.chat-panel.embedding-progress": "嵌入 {{done}}/{{total}}",
|
||||
"com.affine.ai.chat-panel.session.delete.confirm.title": "删除此历史记录?",
|
||||
"com.affine.ai.chat-panel.session.delete.confirm.message": "确定要删除这段 AI 对话历史记录吗?删除后无法恢复。",
|
||||
"com.affine.ai.chat-panel.session.delete.toast.success": "已删除历史记录",
|
||||
"com.affine.ai.chat-panel.session.delete.toast.failed": "删除历史记录失败",
|
||||
"com.affine.all-pages.header": "所有文档",
|
||||
"com.affine.app-sidebar.learn-more": "了解更多",
|
||||
"com.affine.app-sidebar.star-us": "给我们点亮星标",
|
||||
@@ -1808,6 +1815,7 @@
|
||||
"com.affine.workspaceList.workspaceListType.local": "本地储存",
|
||||
"com.affine.workspaceList.addServer": "添加服务器",
|
||||
"com.affine.workspaceSubPath.all": "全部文档",
|
||||
"com.affine.workspaceSubPath.chat": "Intelligence",
|
||||
"com.affine.workspaceSubPath.trash": "回收站",
|
||||
"com.affine.workspaceSubPath.trash.empty-description": "已删除的文档将显示在此处。",
|
||||
"com.affine.write_with_a_blank_page": "在空白页面书写",
|
||||
|
||||
@@ -205,6 +205,13 @@
|
||||
"com.affine.ai.login-required.dialog-content": "要使用 AFFiNE AI,請先登入您的 AFFiNE Cloud 帳戶。",
|
||||
"com.affine.ai.login-required.dialog-title": "登入以繼續",
|
||||
"com.affine.ai.template-insert.failed": "插入模板失敗,請重試。",
|
||||
"com.affine.ai.chat-panel.title": "AFFiNE AI",
|
||||
"com.affine.ai.chat-panel.loading-history": "AFFiNE AI 正在載入歷史記錄...",
|
||||
"com.affine.ai.chat-panel.embedding-progress": "嵌入 {{done}}/{{total}}",
|
||||
"com.affine.ai.chat-panel.session.delete.confirm.title": "刪除此歷史記錄?",
|
||||
"com.affine.ai.chat-panel.session.delete.confirm.message": "確定要刪除這段 AI 對話歷史記錄嗎?刪除後無法復原。",
|
||||
"com.affine.ai.chat-panel.session.delete.toast.success": "已刪除歷史記錄",
|
||||
"com.affine.ai.chat-panel.session.delete.toast.failed": "刪除歷史記錄失敗",
|
||||
"com.affine.all-pages.header": "所有文件",
|
||||
"com.affine.app-sidebar.learn-more": "了解更多",
|
||||
"com.affine.app-sidebar.star-us": "給我們點亮星標",
|
||||
@@ -1785,6 +1792,7 @@
|
||||
"com.affine.workspaceList.workspaceListType.local": "本地儲存",
|
||||
"com.affine.workspaceList.addServer": "新增伺服器",
|
||||
"com.affine.workspaceSubPath.all": "所有頁面",
|
||||
"com.affine.workspaceSubPath.chat": "Intelligence",
|
||||
"com.affine.workspaceSubPath.trash": "廢紙簍",
|
||||
"com.affine.workspaceSubPath.trash.empty-description": "已刪除的文件將顯示在此處。",
|
||||
"com.affine.write_with_a_blank_page": "在空白頁書寫",
|
||||
|
||||
Reference in New Issue
Block a user