refactor(core): open embedding settings when click check-status button (#12772)

> CLOSE BS-3582

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a "Check status" button in the AI chat interface that opens the
embedding settings panel for improved user access.

- **Refactor**
- Simplified the embedding status tooltip to display static information
and a direct link to settings, removing dynamic progress updates.
- Integrated workspace dialog service across AI chat components for
consistent dialog management.

- **Tests**
- Updated end-to-end tests to verify that clicking the "Check status"
button opens the embedding settings panel.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
德布劳外 · 贾贵
2025-06-30 15:00:17 +08:00
committed by GitHub
parent 29ae6afe71
commit c9aad0d55e
7 changed files with 51 additions and 23 deletions

View File

@@ -1,5 +1,6 @@
import './chat-panel-messages';
import type { WorkspaceDialogService } from '@affine/core/modules/dialogs';
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
import type { ContextEmbedStatus, CopilotSessionType } from '@affine/graphql';
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
@@ -241,6 +242,9 @@ export class ChatPanel extends SignalWatcher(
@property({ attribute: false })
accessor affineFeatureFlagService!: FeatureFlagService;
@property({ attribute: false })
accessor affineWorkspaceDialogService!: WorkspaceDialogService;
@state()
accessor isLoading = false;
@@ -481,6 +485,7 @@ export class ChatPanel extends SignalWatcher(
.playgroundConfig=${this.playgroundConfig}
.docDisplayConfig=${this.docDisplayConfig}
.searchMenuConfig=${this.searchMenuConfig}
.affineWorkspaceDialogService=${this.affineWorkspaceDialogService}
.trackOptions=${{
where: 'chat-panel',
control: 'chat-send',

View File

@@ -1,5 +1,6 @@
import './ai-chat-composer-tip';
import type { WorkspaceDialogService } from '@affine/core/modules/dialogs';
import type {
ContextEmbedStatus,
ContextWorkspaceEmbeddingStatus,
@@ -104,11 +105,11 @@ export class AIChatComposer extends SignalWatcher(
@property({ attribute: false })
accessor panelWidth: Signal<number | undefined> = signal(undefined);
@state()
accessor chips: ChatChip[] = [];
@property({ attribute: false })
accessor affineWorkspaceDialogService!: WorkspaceDialogService;
@state()
accessor embeddingProgressText = 'Loading embedding status...';
accessor chips: ChatChip[] = [];
@state()
accessor embeddingCompleted = false;
@@ -160,7 +161,8 @@ export class AIChatComposer extends SignalWatcher(
this.embeddingCompleted
? null
: html`<ai-chat-embedding-status-tooltip
.progressText=${this.embeddingProgressText}
.affineWorkspaceDialogService=${this
.affineWorkspaceDialogService}
/>`,
].filter(Boolean)}
.loop=${false}
@@ -348,24 +350,20 @@ export class AIChatComposer extends SignalWatcher(
this.host.std.workspace.id,
(status: ContextWorkspaceEmbeddingStatus) => {
if (!status) {
this.embeddingProgressText = 'Loading embedding status...';
this.embeddingCompleted = false;
return;
}
const completed = status.embedded === status.total;
this.embeddingCompleted = completed;
if (completed) {
this.embeddingProgressText =
'Embedding finished. You are getting the best results!';
this.embeddingCompleted = true;
} else {
this.embeddingProgressText =
'File not embedded yet. Results will improve after embedding.';
this.embeddingCompleted = false;
}
},
signal
);
} catch {
this.embeddingProgressText = 'Failed to load embedding status...';
this.embeddingCompleted = false;
}
};

View File

@@ -1,7 +1,9 @@
import type { WorkspaceDialogService } from '@affine/core/modules/dialogs';
import { SignalWatcher } from '@blocksuite/affine/global/lit';
import { unsafeCSSVar } from '@blocksuite/affine/shared/theme';
import { css, html, LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { debounce } from 'lodash-es';
export class AIChatEmbeddingStatusTooltip extends SignalWatcher(LitElement) {
static override styles = css`
@@ -34,7 +36,21 @@ export class AIChatEmbeddingStatusTooltip extends SignalWatcher(LitElement) {
`;
@property({ attribute: false })
accessor progressText = 'Loading embedding status...';
accessor affineWorkspaceDialogService!: WorkspaceDialogService;
override connectedCallback() {
super.connectedCallback();
}
private readonly _handleCheckStatusClick = debounce(
() => {
this.affineWorkspaceDialogService.open('setting', {
activeTab: 'workspace:embedding',
});
},
1000,
{ leading: true }
);
override render() {
return html`
@@ -48,11 +64,9 @@ export class AIChatEmbeddingStatusTooltip extends SignalWatcher(LitElement) {
<div
class="check-status"
data-testid="ai-chat-embedding-status-tooltip-check"
@click=${this._handleCheckStatusClick}
>
Check status
<affine-tooltip tip-position="top-start"
>${this.progressText}</affine-tooltip
>
</div>
</div>
`;

View File

@@ -1,3 +1,4 @@
import type { WorkspaceDialogService } from '@affine/core/modules/dialogs';
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
import type { ContextEmbedStatus } from '@affine/graphql';
import {
@@ -593,6 +594,7 @@ export class AIChatBlockPeekView extends LitElement {
.networkSearchConfig=${networkSearchConfig}
.docDisplayConfig=${this.docDisplayConfig}
.searchMenuConfig=${this.searchMenuConfig}
.affineWorkspaceDialogService=${this.affineWorkspaceDialogService}
.onChatSuccess=${this._onChatSuccess}
.trackOptions=${{
where: 'ai-chat-block',
@@ -628,6 +630,9 @@ export class AIChatBlockPeekView extends LitElement {
@property({ attribute: false })
accessor affineFeatureFlagService!: FeatureFlagService;
@property({ attribute: false })
accessor affineWorkspaceDialogService!: WorkspaceDialogService;
@state()
accessor _historyMessages: ChatMessage[] = [];
@@ -657,7 +662,8 @@ export const AIChatBlockPeekViewTemplate = (
searchMenuConfig: SearchMenuConfig,
networkSearchConfig: AINetworkSearchConfig,
reasoningConfig: AIReasoningConfig,
affineFeatureFlagService: FeatureFlagService
affineFeatureFlagService: FeatureFlagService,
affineWorkspaceDialogService: WorkspaceDialogService
) => {
return html`<ai-chat-block-peek-view
.blockModel=${blockModel}
@@ -667,5 +673,6 @@ export const AIChatBlockPeekViewTemplate = (
.searchMenuConfig=${searchMenuConfig}
.reasoningConfig=${reasoningConfig}
.affineFeatureFlagService=${affineFeatureFlagService}
.affineWorkspaceDialogService=${affineWorkspaceDialogService}
></ai-chat-block-peek-view>`;
};

View File

@@ -1,6 +1,7 @@
import { ChatPanel } from '@affine/core/blocksuite/ai';
import type { AffineEditorContainer } from '@affine/core/blocksuite/block-suite-editor';
import { useAIChatConfig } from '@affine/core/components/hooks/affine/use-ai-chat-config';
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
import { FeatureFlagService } from '@affine/core/modules/feature-flag';
import { WorkbenchService } from '@affine/core/modules/workbench';
import { ViewExtensionManagerIdentifier } from '@blocksuite/affine/ext-loader';
@@ -80,6 +81,9 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
.get('preview-page');
chatPanelRef.current.affineFeatureFlagService =
framework.get(FeatureFlagService);
chatPanelRef.current.affineWorkspaceDialogService = framework.get(
WorkspaceDialogService
);
containerRef.current?.append(chatPanelRef.current);
} else {

View File

@@ -2,6 +2,7 @@ import { toReactNode } from '@affine/component';
import { AIChatBlockPeekViewTemplate } from '@affine/core/blocksuite/ai';
import type { AIChatBlockModel } from '@affine/core/blocksuite/ai/blocks/ai-chat-block/model/ai-chat-model';
import { useAIChatConfig } from '@affine/core/components/hooks/affine/use-ai-chat-config';
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
import { FeatureFlagService } from '@affine/core/modules/feature-flag';
import type { EditorHost } from '@blocksuite/affine/std';
import { useFramework } from '@toeverything/infra';
@@ -25,6 +26,7 @@ export const AIChatBlockPeekView = ({
const framework = useFramework();
const affineFeatureFlagService = framework.get(FeatureFlagService);
const affineWorkspaceDialogService = framework.get(WorkspaceDialogService);
return useMemo(() => {
const template = AIChatBlockPeekViewTemplate(
@@ -34,7 +36,8 @@ export const AIChatBlockPeekView = ({
searchMenuConfig,
networkSearchConfig,
reasoningConfig,
affineFeatureFlagService
affineFeatureFlagService,
affineWorkspaceDialogService
);
return toReactNode(template);
}, [
@@ -45,5 +48,6 @@ export const AIChatBlockPeekView = ({
networkSearchConfig,
reasoningConfig,
affineFeatureFlagService,
affineWorkspaceDialogService,
]);
};