From bd5d9304909db97e33f32c51112a207417aa587b Mon Sep 17 00:00:00 2001 From: akumatus Date: Thu, 20 Mar 2025 06:55:56 +0000 Subject: [PATCH] feat(core): document search shows up to three results (#11002) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close [BS-2828](https://linear.app/affine-design/issue/BS-2828). ![截屏2025-03-19 17.49.11.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/sJGviKxfE3Ap685cl5bj/9548afcc-5707-435f-93b2-25e42fddc97f.png) --- .../ai/chat-panel/components/add-popover.ts | 131 +++++++++++++----- 1 file changed, 93 insertions(+), 38 deletions(-) diff --git a/packages/frontend/core/src/blocksuite/ai/chat-panel/components/add-popover.ts b/packages/frontend/core/src/blocksuite/ai/chat-panel/components/add-popover.ts index a20a873291..d693d027d6 100644 --- a/packages/frontend/core/src/blocksuite/ai/chat-panel/components/add-popover.ts +++ b/packages/frontend/core/src/blocksuite/ai/chat-panel/components/add-popover.ts @@ -9,6 +9,7 @@ import { scrollbarStyle } from '@blocksuite/affine/shared/styles'; import { openFileOrFiles, type Signal } from '@blocksuite/affine/shared/utils'; import { CollectionsIcon, + MoreHorizontalIcon, SearchIcon, TagsIcon, UploadIcon, @@ -16,6 +17,7 @@ import { import type { DocMeta } from '@blocksuite/store'; import { css, html, type TemplateResult } from 'lit'; import { property, query, state } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; import type { SearchMenuConfig } from '../chat-config'; import type { ChatChip } from '../chat-context'; @@ -30,6 +32,7 @@ export type MenuGroup = { name: string; items: MenuItem[] | Signal; maxDisplay?: number; + overflowText?: string | Signal; }; export type MenuItem = { @@ -98,6 +101,9 @@ export class ChatPanelAddPopover extends SignalWatcher( font-size: var(--affine-font-sm); color: var(--affine-text-secondary-color); } + .menu-items icon-button { + outline: none; + } .item-suffix { margin-left: auto; font-size: var(--affine-font-xs); @@ -121,10 +127,14 @@ export class ChatPanelAddPopover extends SignalWatcher( this._activatedIndex = 0; this._query = ''; this._updateSearchGroup(); + this._focusSearchInput(); + }; + + private _focusSearchInput() { requestAnimationFrame(() => { this.searchInput.focus(); }); - }; + } private readonly tcGroup: MenuGroup = { name: 'Tag & Collection', @@ -175,17 +185,50 @@ export class ChatPanelAddPopover extends SignalWatcher( }; private get _menuGroup() { + let groups: MenuGroup[] = []; + switch (this._mode) { case AddPopoverMode.Tags: - return [this._searchGroup]; + groups = [this._searchGroup]; + break; case AddPopoverMode.Collections: - return [this._searchGroup]; + groups = [this._searchGroup]; + break; default: if (this._query) { - return [this._searchGroup, this.uploadGroup]; + groups = [this._searchGroup, this.uploadGroup]; + } else { + groups = [this._searchGroup, this.tcGroup, this.uploadGroup]; } - return [this._searchGroup, this.tcGroup, this.uploadGroup]; } + + // Process maxDisplay for each group + return groups.map(group => { + let items = Array.isArray(group.items) ? group.items : group.items.value; + const maxDisplay = group.maxDisplay ?? items.length; + const hasMore = items.length > maxDisplay; + if (!hasMore) { + return group; + } + return { + ...group, + items: [ + ...items.slice(0, maxDisplay), + { + key: `${group.name} More`, + name: + typeof group.overflowText === 'string' + ? group.overflowText + : (group.overflowText?.value ?? 'more'), + icon: MoreHorizontalIcon(), + action: () => { + this._resetMaxDisplay(group); + this._focusSearchInput(); + }, + }, + ], + }; + }); } private get _flattenMenuGroup() { @@ -215,18 +258,16 @@ export class ChatPanelAddPopover extends SignalWatcher( override connectedCallback() { super.connectedCallback(); this._updateSearchGroup(); - this.addEventListener('keydown', this._handleKeyDown); + document.addEventListener('keydown', this._handleKeyDown); } override firstUpdated() { - requestAnimationFrame(() => { - this.searchInput.focus(); - }); + this._focusSearchInput(); } override disconnectedCallback() { super.disconnectedCallback(); - this.removeEventListener('keydown', this._handleKeyDown); + document.removeEventListener('keydown', this._handleKeyDown); } override render() { @@ -266,38 +307,47 @@ export class ChatPanelAddPopover extends SignalWatcher( private _renderMenuGroup(groups: MenuGroup[]) { let startIndex = 0; - return groups.map((group, idx) => { - const items = Array.isArray(group.items) - ? group.items - : group.items.value; - const menuGroup = html``; - startIndex += items.length; - return menuGroup; - }); + return repeat( + groups, + group => group.name, + (group, idx) => { + const items = Array.isArray(group.items) + ? group.items + : group.items.value; + + const menuGroup = html``; + startIndex += items.length; + return menuGroup; + } + ); } private _renderMenuItems(items: MenuItem[], startIndex: number) { - return html`
+ return html``; } @@ -308,6 +358,11 @@ export class ChatPanelAddPopover extends SignalWatcher( this._updateSearchGroup(); } + private _resetMaxDisplay(group: MenuGroup) { + group.maxDisplay = undefined; + this.requestUpdate(); + } + private _updateSearchGroup() { switch (this._mode) { case AddPopoverMode.Tags: