refactor: move doc-title and ai-chat-block components (#10316)
### TL;DR Moved doc title and AI chat block components to more appropriate locations while removing unused backlink functionality. ### What changed? - Relocated doc title component from presets to affine-components - Moved AI chat block from presets/blocks to blocks directory - Removed unused backlink-related code and components - Updated imports across files to reference new component locations - Consolidated AI-related exports through a single entry point ### How to test? 1. Verify doc title still renders correctly in documents 2. Confirm AI chat functionality works as expected 3. Check that no backlink-related features are accessible 4. Ensure all AI features continue to work through the new import paths ### Why make this change? This reorganization improves code organization by: - Placing components closer to their related functionality - Removing dead/unused code around backlinks - Simplifying the import structure for AI-related features - Making the codebase more maintainable by consolidating related components
This commit is contained in:
@@ -22,6 +22,7 @@ import { effects as componentCaptionEffects } from '@blocksuite/affine-component
|
||||
import { effects as componentColorPickerEffects } from '@blocksuite/affine-components/color-picker';
|
||||
import { effects as componentContextMenuEffects } from '@blocksuite/affine-components/context-menu';
|
||||
import { effects as componentDatePickerEffects } from '@blocksuite/affine-components/date-picker';
|
||||
import { effects as componentDocTitleEffects } from '@blocksuite/affine-components/doc-title';
|
||||
import { effects as componentDropIndicatorEffects } from '@blocksuite/affine-components/drop-indicator';
|
||||
import { effects as componentEmbedCardModalEffects } from '@blocksuite/affine-components/embed-card-modal';
|
||||
import { FilterableListComponent } from '@blocksuite/affine-components/filterable-list';
|
||||
@@ -213,6 +214,7 @@ export function effects() {
|
||||
componentAiItemEffects();
|
||||
componentColorPickerEffects();
|
||||
componentEmbedCardModalEffects();
|
||||
componentDocTitleEffects();
|
||||
|
||||
widgetScrollAnchoringEffects();
|
||||
widgetMobileToolbarEffects();
|
||||
|
||||
@@ -58,6 +58,10 @@ export {
|
||||
type MenuOptions,
|
||||
onMenuOpen,
|
||||
} from '@blocksuite/affine-components/context-menu';
|
||||
export {
|
||||
DocTitle,
|
||||
getDocTitleByEditorHost,
|
||||
} from '@blocksuite/affine-components/doc-title';
|
||||
export {
|
||||
HoverController,
|
||||
whenHover,
|
||||
|
||||
@@ -7,8 +7,6 @@ import {
|
||||
PageEditor,
|
||||
} from './editors/index.js';
|
||||
import { CommentInput } from './fragments/comment/comment-input.js';
|
||||
import { BacklinkButton } from './fragments/doc-meta-tags/backlink-popover.js';
|
||||
import { effects as docTitleEffects } from './fragments/doc-title/index.js';
|
||||
import {
|
||||
AFFINE_FRAME_PANEL_BODY,
|
||||
FramePanelBody,
|
||||
@@ -70,8 +68,6 @@ import {
|
||||
} from './fragments/outline/header/outline-setting-menu.js';
|
||||
|
||||
export function effects() {
|
||||
docTitleEffects();
|
||||
|
||||
customElements.define('page-editor', PageEditor);
|
||||
customElements.define('comment-input', CommentInput);
|
||||
customElements.define(
|
||||
@@ -82,7 +78,6 @@ export function effects() {
|
||||
customElements.define(AFFINE_OUTLINE_NOTICE, OutlineNotice);
|
||||
customElements.define('comment-panel', CommentPanel);
|
||||
customElements.define(AFFINE_OUTLINE_PANEL, OutlinePanel);
|
||||
customElements.define('backlink-button', BacklinkButton);
|
||||
customElements.define(AFFINE_OUTLINE_PANEL_HEADER, OutlinePanelHeader);
|
||||
customElements.define('affine-editor-container', AffineEditorContainer);
|
||||
customElements.define(AFFINE_OUTLINE_NOTE_CARD, OutlineNoteCard);
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
import { DualLinkIcon16, scrollbarStyle } from '@blocksuite/blocks';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import { baseTheme } from '@toeverything/theme';
|
||||
import { css, html, LitElement, unsafeCSS } from 'lit';
|
||||
import { state } from 'lit/decorators.js';
|
||||
|
||||
import { type BacklinkData, DEFAULT_DOC_NAME } from './utils.js';
|
||||
|
||||
export class BacklinkButton extends WithDisposable(LitElement) {
|
||||
static override styles = css`
|
||||
:host {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 0 12px;
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border: none;
|
||||
height: 30px;
|
||||
border-radius: 8px;
|
||||
gap: 4px;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
|
||||
user-select: none;
|
||||
font-size: var(--affine-font-sm);
|
||||
font-family: ${unsafeCSS(baseTheme.fontSansFamily)};
|
||||
fill: var(--affine-text-secondary-color);
|
||||
color: var(--affine-text-secondary-color);
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.btn > span {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: var(--affine-hover-color);
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
background: var(--affine-hover-color);
|
||||
}
|
||||
|
||||
.backlink-popover {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
transform: translateY(100%);
|
||||
z-index: 1;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 8px 4px;
|
||||
background: var(--affine-white);
|
||||
box-shadow: var(--affine-menu-shadow);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.backlink-popover .group-title {
|
||||
color: var(--affine-text-secondary-color);
|
||||
margin: 8px 12px;
|
||||
}
|
||||
|
||||
.backlink-popover icon-button {
|
||||
padding: 8px;
|
||||
justify-content: flex-start;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
${scrollbarStyle('.backlink-popover .group')}
|
||||
`;
|
||||
|
||||
private readonly _backlinks: BacklinkData[];
|
||||
|
||||
// Handle click outside
|
||||
private readonly _onClickAway = (e: Event) => {
|
||||
if (e.target === this) return;
|
||||
if (!this._showPopover) return;
|
||||
this._showPopover = false;
|
||||
document.removeEventListener('mousedown', this._onClickAway);
|
||||
};
|
||||
|
||||
constructor(backlinks: BacklinkData[]) {
|
||||
super();
|
||||
|
||||
this._backlinks = backlinks;
|
||||
}
|
||||
|
||||
override connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
this.tabIndex = 0;
|
||||
}
|
||||
|
||||
onClick() {
|
||||
this._showPopover = !this._showPopover;
|
||||
document.addEventListener('mousedown', this._onClickAway);
|
||||
}
|
||||
|
||||
override render() {
|
||||
// Only show linked doc backlinks
|
||||
const backlinks = this._backlinks;
|
||||
if (!backlinks.length) return null;
|
||||
|
||||
return html`
|
||||
<div class="btn" @click="${this.onClick}">
|
||||
${DualLinkIcon16}<span>Backlinks (${backlinks.length})</span>
|
||||
${this._showPopover ? backlinkPopover(backlinks) : null}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@state()
|
||||
private accessor _showPopover = false;
|
||||
}
|
||||
|
||||
function backlinkPopover(backlinks: BacklinkData[]) {
|
||||
return html`<div
|
||||
class="backlink-popover"
|
||||
@click=${(e: MouseEvent) => e.stopPropagation()}
|
||||
>
|
||||
<div class="menu">
|
||||
<div class="group-title">Linked to this doc</div>
|
||||
<div class="group" style="overflow-y: scroll; max-height: 372px;">
|
||||
${backlinks.map(link => {
|
||||
const title = link.title || DEFAULT_DOC_NAME;
|
||||
return html`<icon-button
|
||||
width="248px"
|
||||
height="32px"
|
||||
text="${title}"
|
||||
@mousedown="${link.jump}"
|
||||
>
|
||||
${link.icon}
|
||||
</icon-button>`;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
||||
import type { DocMeta } from '@blocksuite/store';
|
||||
import type { TemplateResult } from 'lit';
|
||||
|
||||
export const DOC_BLOCK_CHILD_PADDING = 24;
|
||||
|
||||
export const DEFAULT_DOC_NAME = 'Untitled';
|
||||
|
||||
export type BackLink = {
|
||||
pageId: string;
|
||||
blockId: string;
|
||||
type: NonNullable<AffineTextAttributes['reference']>['type'];
|
||||
};
|
||||
|
||||
export type BacklinkData = BackLink &
|
||||
DocMeta & {
|
||||
jump: () => void;
|
||||
icon: TemplateResult;
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export * from '@blocksuite/affine-components/doc-title';
|
||||
@@ -1,4 +1,3 @@
|
||||
export * from './comment/index.js';
|
||||
export * from './doc-title/index.js';
|
||||
export * from './frame-panel/index.js';
|
||||
export * from './outline/index.js';
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import type { EditorHost } from '@blocksuite/block-std';
|
||||
import { NoteDisplayMode } from '@blocksuite/blocks';
|
||||
import { getDocTitleByEditorHost, NoteDisplayMode } from '@blocksuite/blocks';
|
||||
import { clamp, DisposableGroup } from '@blocksuite/global/utils';
|
||||
|
||||
import type { AffineEditorContainer } from '../../../editors/editor-container.js';
|
||||
import { getDocTitleByEditorHost } from '../../doc-title/index.js';
|
||||
import { getHeadingBlocksFromDoc } from './query.js';
|
||||
|
||||
export function scrollToBlock(editor: AffineEditorContainer, blockId: string) {
|
||||
|
||||
Reference in New Issue
Block a user