mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
refactor(editor): extract ai item component (#9283)
This commit is contained in:
@@ -1,150 +0,0 @@
|
||||
import { createLitPortal } from '@blocksuite/affine-components/portal';
|
||||
import {
|
||||
EditorHost,
|
||||
PropTypes,
|
||||
requiredProperties,
|
||||
} from '@blocksuite/block-std';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import { flip, offset } from '@floating-ui/dom';
|
||||
import { baseTheme } from '@toeverything/theme';
|
||||
import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
|
||||
import type { AIItem } from './ai-item.js';
|
||||
import {
|
||||
SUBMENU_OFFSET_CROSS_AXIS,
|
||||
SUBMENU_OFFSET_MAIN_AXIS,
|
||||
} from './const.js';
|
||||
import type { AIItemConfig, AIItemGroupConfig } from './types.js';
|
||||
|
||||
@requiredProperties({ host: PropTypes.instanceOf(EditorHost) })
|
||||
export class AIItemList extends WithDisposable(LitElement) {
|
||||
static override styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
width: 100%;
|
||||
font-family: ${unsafeCSS(baseTheme.fontSansFamily)};
|
||||
user-select: none;
|
||||
}
|
||||
.group-name {
|
||||
display: flex;
|
||||
padding: 4px calc(var(--item-padding, 8px) + 4px);
|
||||
align-items: center;
|
||||
color: var(--affine-text-secondary-color);
|
||||
text-align: justify;
|
||||
font-size: var(--affine-font-xs);
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
`;
|
||||
|
||||
private _abortController: AbortController | null = null;
|
||||
|
||||
private _activeSubMenuItem: AIItemConfig | null = null;
|
||||
|
||||
private readonly _closeSubMenu = () => {
|
||||
if (this._abortController) {
|
||||
this._abortController.abort();
|
||||
this._abortController = null;
|
||||
}
|
||||
this._activeSubMenuItem = null;
|
||||
};
|
||||
|
||||
private readonly _itemClassName = (item: AIItemConfig) => {
|
||||
return 'ai-item-' + item.name.split(' ').join('-').toLocaleLowerCase();
|
||||
};
|
||||
|
||||
private readonly _openSubMenu = (item: AIItemConfig) => {
|
||||
if (!item.subItem || item.subItem.length === 0) {
|
||||
this._closeSubMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
if (item === this._activeSubMenuItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
const aiItem = this.shadowRoot?.querySelector(
|
||||
`.${this._itemClassName(item)}`
|
||||
) as AIItem | null;
|
||||
if (!aiItem || !aiItem.menuItem) return;
|
||||
|
||||
this._closeSubMenu();
|
||||
this._activeSubMenuItem = item;
|
||||
this._abortController = new AbortController();
|
||||
this._abortController.signal.addEventListener('abort', () => {
|
||||
this._closeSubMenu();
|
||||
});
|
||||
|
||||
const aiItemContainer = aiItem.menuItem;
|
||||
const subMenuOffset = {
|
||||
mainAxis: item.subItemOffset?.[0] ?? SUBMENU_OFFSET_MAIN_AXIS,
|
||||
crossAxis: item.subItemOffset?.[1] ?? SUBMENU_OFFSET_CROSS_AXIS,
|
||||
};
|
||||
|
||||
createLitPortal({
|
||||
template: html`<ai-sub-item-list
|
||||
.item=${item}
|
||||
.host=${this.host}
|
||||
.onClick=${this.onClick}
|
||||
.abortController=${this._abortController}
|
||||
></ai-sub-item-list>`,
|
||||
container: aiItemContainer,
|
||||
positionStrategy: 'fixed',
|
||||
computePosition: {
|
||||
referenceElement: aiItemContainer,
|
||||
placement: 'right-start',
|
||||
middleware: [flip(), offset(subMenuOffset)],
|
||||
autoUpdate: true,
|
||||
},
|
||||
abortController: this._abortController,
|
||||
closeOnClickAway: true,
|
||||
});
|
||||
};
|
||||
|
||||
override render() {
|
||||
return html`${repeat(this.groups, group => {
|
||||
return html`
|
||||
${group.name
|
||||
? html`<div class="group-name">
|
||||
${group.name.toLocaleUpperCase()}
|
||||
</div>`
|
||||
: nothing}
|
||||
${repeat(
|
||||
group.items,
|
||||
item =>
|
||||
html`<ai-item
|
||||
.onClick=${this.onClick}
|
||||
.item=${item}
|
||||
.host=${this.host}
|
||||
class=${this._itemClassName(item)}
|
||||
@mouseover=${() => {
|
||||
this._openSubMenu(item);
|
||||
}}
|
||||
></ai-item>`
|
||||
)}
|
||||
`;
|
||||
})}`;
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor groups: AIItemGroupConfig[] = [];
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor host!: EditorHost;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onClick: (() => void) | undefined = undefined;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'ai-item-list': AIItemList;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
import { ArrowRightIcon, EnterIcon } from '@blocksuite/affine-components/icons';
|
||||
import {
|
||||
EditorHost,
|
||||
PropTypes,
|
||||
requiredProperties,
|
||||
} from '@blocksuite/block-std';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import { css, html, LitElement, nothing } from 'lit';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
|
||||
import { menuItemStyles } from './styles.js';
|
||||
import type { AIItemConfig } from './types.js';
|
||||
|
||||
@requiredProperties({
|
||||
host: PropTypes.instanceOf(EditorHost),
|
||||
item: PropTypes.object,
|
||||
})
|
||||
export class AIItem extends WithDisposable(LitElement) {
|
||||
static override styles = css`
|
||||
${menuItemStyles}
|
||||
`;
|
||||
|
||||
override render() {
|
||||
const { item } = this;
|
||||
const className = item.name.split(' ').join('-').toLocaleLowerCase();
|
||||
|
||||
return html`<div
|
||||
class="menu-item ${className}"
|
||||
@pointerdown=${(e: MouseEvent) => e.stopPropagation()}
|
||||
@click=${() => {
|
||||
this.onClick?.();
|
||||
if (typeof item.handler === 'function') {
|
||||
item.handler(this.host);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span class="item-icon">${item.icon}</span>
|
||||
<div class="item-name">
|
||||
${item.name}${item.beta
|
||||
? html`<div class="item-beta">(Beta)</div>`
|
||||
: nothing}
|
||||
</div>
|
||||
${item.subItem
|
||||
? html`<span class="arrow-right-icon">${ArrowRightIcon}</span>`
|
||||
: html`<span class="enter-icon">${EnterIcon}</span>`}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor host!: EditorHost;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor item!: AIItemConfig;
|
||||
|
||||
@query('.menu-item')
|
||||
accessor menuItem: HTMLDivElement | null = null;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onClick: (() => void) | undefined;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'ai-item': AIItem;
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
import { EnterIcon } from '@blocksuite/affine-components/icons';
|
||||
import {
|
||||
EditorHost,
|
||||
PropTypes,
|
||||
requiredProperties,
|
||||
} from '@blocksuite/block-std';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import { baseTheme } from '@toeverything/theme';
|
||||
import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
|
||||
import { menuItemStyles } from './styles.js';
|
||||
import type { AIItemConfig, AISubItemConfig } from './types.js';
|
||||
|
||||
@requiredProperties({
|
||||
host: PropTypes.instanceOf(EditorHost),
|
||||
item: PropTypes.object,
|
||||
})
|
||||
export class AISubItemList extends WithDisposable(LitElement) {
|
||||
static override styles = css`
|
||||
.ai-sub-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
padding: 8px;
|
||||
min-width: 240px;
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
background: var(--affine-background-overlay-panel-color);
|
||||
box-shadow: var(--affine-shadow-2);
|
||||
border-radius: 8px;
|
||||
z-index: var(--affine-z-index-popover);
|
||||
font-family: ${unsafeCSS(baseTheme.fontSansFamily)};
|
||||
color: var(--affine-text-primary-color);
|
||||
text-align: justify;
|
||||
font-feature-settings:
|
||||
'clig' off,
|
||||
'liga' off;
|
||||
font-size: var(--affine-font-sm);
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
user-select: none;
|
||||
}
|
||||
${menuItemStyles}
|
||||
`;
|
||||
|
||||
private readonly _handleClick = (subItem: AISubItemConfig) => {
|
||||
this.onClick?.();
|
||||
if (subItem.handler) {
|
||||
// TODO: add parameters to ai handler
|
||||
subItem.handler(this.host);
|
||||
}
|
||||
this.abortController.abort();
|
||||
};
|
||||
|
||||
override render() {
|
||||
if (!this.item.subItem || this.item.subItem.length <= 0) return nothing;
|
||||
return html`<div class="ai-sub-menu">
|
||||
${this.item.subItem?.map(
|
||||
subItem =>
|
||||
html`<div
|
||||
class="menu-item"
|
||||
@click=${() => this._handleClick(subItem)}
|
||||
>
|
||||
<div class="item-name">${subItem.type}</div>
|
||||
<span class="enter-icon">${EnterIcon}</span>
|
||||
</div>`
|
||||
)}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor abortController: AbortController = new AbortController();
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor host!: EditorHost;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor item!: AIItemConfig;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onClick: (() => void) | undefined;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'ai-sub-item-list': AISubItemList;
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
export const SUBMENU_OFFSET_MAIN_AXIS = 12;
|
||||
export const SUBMENU_OFFSET_CROSS_AXIS = -60;
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './ai-item-list.js';
|
||||
export * from './types.js';
|
||||
@@ -1,71 +0,0 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export const menuItemStyles = css`
|
||||
.menu-item {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 4px var(--item-padding, 12px);
|
||||
gap: 4px;
|
||||
align-self: stretch;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.menu-item:hover {
|
||||
background: var(--affine-hover-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
.item-icon {
|
||||
display: flex;
|
||||
color: var(--item-icon-color, var(--affine-brand-color));
|
||||
}
|
||||
.menu-item:hover .item-icon {
|
||||
color: var(--item-icon-hover-color, var(--affine-brand-color));
|
||||
}
|
||||
.menu-item.discard:hover {
|
||||
background: var(--affine-background-error-color);
|
||||
.item-name,
|
||||
.item-icon,
|
||||
.enter-icon {
|
||||
color: var(--affine-error-color);
|
||||
}
|
||||
}
|
||||
.item-name {
|
||||
display: flex;
|
||||
padding: 0px 4px;
|
||||
align-items: baseline;
|
||||
flex: 1 0 0;
|
||||
color: var(--affine-text-primary-color);
|
||||
text-align: start;
|
||||
white-space: nowrap;
|
||||
font-feature-settings:
|
||||
'clig' off,
|
||||
'liga' off;
|
||||
font-size: var(--affine-font-sm);
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.item-beta {
|
||||
color: var(--affine-text-secondary-color);
|
||||
font-size: var(--affine-font-xs);
|
||||
font-weight: 500;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.enter-icon,
|
||||
.arrow-right-icon {
|
||||
color: var(--affine-icon-color);
|
||||
display: flex;
|
||||
}
|
||||
.enter-icon {
|
||||
opacity: 0;
|
||||
}
|
||||
.arrow-right-icon,
|
||||
.menu-item:hover .enter-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
@@ -1,68 +0,0 @@
|
||||
import type { DocMode } from '@blocksuite/affine-model';
|
||||
import type { Chain, EditorHost, InitCommandCtx } from '@blocksuite/block-std';
|
||||
import type { TemplateResult } from 'lit';
|
||||
|
||||
export interface AIItemGroupConfig {
|
||||
name?: string;
|
||||
items: AIItemConfig[];
|
||||
}
|
||||
|
||||
export interface AIItemConfig {
|
||||
name: string;
|
||||
icon: TemplateResult | (() => HTMLElement);
|
||||
showWhen?: (
|
||||
chain: Chain<InitCommandCtx>,
|
||||
editorMode: DocMode,
|
||||
host: EditorHost
|
||||
) => boolean;
|
||||
subItem?: AISubItemConfig[];
|
||||
subItemOffset?: [number, number];
|
||||
handler?: (host: EditorHost) => void;
|
||||
beta?: boolean;
|
||||
}
|
||||
|
||||
export interface AISubItemConfig {
|
||||
type: string;
|
||||
handler?: (host: EditorHost) => void;
|
||||
}
|
||||
|
||||
abstract class BaseAIError extends Error {
|
||||
abstract readonly type: AIErrorType;
|
||||
}
|
||||
|
||||
export enum AIErrorType {
|
||||
GeneralNetworkError = 'GeneralNetworkError',
|
||||
PaymentRequired = 'PaymentRequired',
|
||||
Unauthorized = 'Unauthorized',
|
||||
}
|
||||
|
||||
export class UnauthorizedError extends BaseAIError {
|
||||
readonly type = AIErrorType.Unauthorized;
|
||||
|
||||
constructor() {
|
||||
super('Unauthorized');
|
||||
}
|
||||
}
|
||||
|
||||
// user has used up the quota
|
||||
export class PaymentRequiredError extends BaseAIError {
|
||||
readonly type = AIErrorType.PaymentRequired;
|
||||
|
||||
constructor() {
|
||||
super('Payment required');
|
||||
}
|
||||
}
|
||||
|
||||
// general 500x error
|
||||
export class GeneralNetworkError extends BaseAIError {
|
||||
readonly type = AIErrorType.GeneralNetworkError;
|
||||
|
||||
constructor(message: string = 'Network error') {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
export type AIError =
|
||||
| UnauthorizedError
|
||||
| PaymentRequiredError
|
||||
| GeneralNetworkError;
|
||||
@@ -1 +0,0 @@
|
||||
export * from './ai-item/index.js';
|
||||
@@ -2,6 +2,7 @@ import { effects as blockEmbedEffects } from '@blocksuite/affine-block-embed/eff
|
||||
import { effects as blockListEffects } from '@blocksuite/affine-block-list/effects';
|
||||
import { effects as blockParagraphEffects } from '@blocksuite/affine-block-paragraph/effects';
|
||||
import { effects as blockSurfaceEffects } from '@blocksuite/affine-block-surface/effects';
|
||||
import { effects as componentAiItemEffects } from '@blocksuite/affine-components/ai-item';
|
||||
import { BlockSelection } from '@blocksuite/affine-components/block-selection';
|
||||
import { BlockZeroWidth } from '@blocksuite/affine-components/block-zero-width';
|
||||
import { effects as componentCaptionEffects } from '@blocksuite/affine-components/caption';
|
||||
@@ -23,14 +24,11 @@ import { effects as dataViewEffects } from '@blocksuite/data-view/effects';
|
||||
import { effects as inlineEffects } from '@blocksuite/inline/effects';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
|
||||
import { AIItem } from './_common/components/ai-item/ai-item.js';
|
||||
import { AISubItemList } from './_common/components/ai-item/ai-sub-item-list.js';
|
||||
import { EmbedCardMoreMenu } from './_common/components/embed-card/embed-card-more-menu-popper.js';
|
||||
import { EmbedCardStyleMenu } from './_common/components/embed-card/embed-card-style-popper.js';
|
||||
import { EmbedCardEditCaptionEditModal } from './_common/components/embed-card/modal/embed-card-caption-edit-modal.js';
|
||||
import { EmbedCardCreateModal } from './_common/components/embed-card/modal/embed-card-create-modal.js';
|
||||
import { EmbedCardEditModal } from './_common/components/embed-card/modal/embed-card-edit-modal.js';
|
||||
import { AIItemList } from './_common/components/index.js';
|
||||
import { registerSpecs } from './_specs/register-specs.js';
|
||||
import { AttachmentEdgelessBlockComponent } from './attachment-block/attachment-edgeless-block.js';
|
||||
import {
|
||||
@@ -304,6 +302,7 @@ export function effects() {
|
||||
componentToolbarEffects();
|
||||
componentDragIndicatorEffects();
|
||||
componentToggleButtonEffects();
|
||||
componentAiItemEffects();
|
||||
|
||||
widgetScrollAnchoringEffects();
|
||||
widgetMobileToolbarEffects();
|
||||
@@ -421,7 +420,6 @@ export function effects() {
|
||||
customElements.define('smooth-corner', SmoothCorner);
|
||||
customElements.define('toggle-switch', ToggleSwitch);
|
||||
customElements.define('ai-panel-answer', AIPanelAnswer);
|
||||
customElements.define('ai-item-list', AIItemList);
|
||||
customElements.define(
|
||||
'edgeless-eraser-tool-button',
|
||||
EdgelessEraserToolButton
|
||||
@@ -430,8 +428,6 @@ export function effects() {
|
||||
customElements.define('edgeless-frame-tool-button', EdgelessFrameToolButton);
|
||||
customElements.define('ai-panel-input', AIPanelInput);
|
||||
customElements.define('ai-panel-generating', AIPanelGenerating);
|
||||
customElements.define('ai-item', AIItem);
|
||||
customElements.define('ai-sub-item-list', AISubItemList);
|
||||
customElements.define('edgeless-link-tool-button', EdgelessLinkToolButton);
|
||||
customElements.define('embed-card-more-menu', EmbedCardMoreMenu);
|
||||
customElements.define('edgeless-mindmap-menu', EdgelessMindmapMenu);
|
||||
|
||||
@@ -7,7 +7,6 @@ import { splitElements } from './root-block/edgeless/utils/clipboard-utils.js';
|
||||
import { isCanvasElement } from './root-block/edgeless/utils/query.js';
|
||||
|
||||
export * from './_common/adapters/index.js';
|
||||
export * from './_common/components/ai-item/index.js';
|
||||
export { type NavigatorMode } from './_common/edgeless/frame/consts.js';
|
||||
export {
|
||||
ExportManager,
|
||||
@@ -55,6 +54,16 @@ export * from '@blocksuite/affine-block-embed';
|
||||
export * from '@blocksuite/affine-block-list';
|
||||
export * from '@blocksuite/affine-block-paragraph';
|
||||
export * from '@blocksuite/affine-block-surface';
|
||||
export {
|
||||
type AIError,
|
||||
type AIItemConfig,
|
||||
type AIItemGroupConfig,
|
||||
AIItemList,
|
||||
type AISubItemConfig,
|
||||
GeneralNetworkError,
|
||||
PaymentRequiredError,
|
||||
UnauthorizedError,
|
||||
} from '@blocksuite/affine-components/ai-item';
|
||||
export { type MenuOptions } from '@blocksuite/affine-components/context-menu';
|
||||
export {
|
||||
HoverController,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { AIError } from '@blocksuite/affine-components/ai-item';
|
||||
import {
|
||||
NotificationProvider,
|
||||
ThemeProvider,
|
||||
@@ -23,7 +24,6 @@ import { css, html, nothing, type PropertyValues } from 'lit';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
import { choose } from 'lit/directives/choose.js';
|
||||
|
||||
import type { AIError } from '../../../_common/components/index.js';
|
||||
import type { EdgelessRootService } from '../../edgeless/edgeless-root-service.js';
|
||||
import { PageRootService } from '../../page/page-root-service.js';
|
||||
import { AFFINE_FORMAT_BAR_WIDGET } from '../format-bar/format-bar.js';
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
AIErrorType,
|
||||
type AIItemGroupConfig,
|
||||
} from '@blocksuite/affine-components/ai-item';
|
||||
import type { EditorHost } from '@blocksuite/block-std';
|
||||
import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import { baseTheme } from '@toeverything/theme';
|
||||
@@ -5,10 +9,6 @@ import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { choose } from 'lit/directives/choose.js';
|
||||
|
||||
import {
|
||||
AIErrorType,
|
||||
type AIItemGroupConfig,
|
||||
} from '../../../../../_common/components/index.js';
|
||||
import type { AIPanelErrorConfig, CopyConfig } from '../../type.js';
|
||||
import { filterAIItemGroup } from '../../utils.js';
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import type { nothing, TemplateResult } from 'lit';
|
||||
|
||||
import type {
|
||||
AIError,
|
||||
AIItemGroupConfig,
|
||||
} from '../../../_common/components/ai-item/types.js';
|
||||
} from '@blocksuite/affine-components/ai-item';
|
||||
import type { nothing, TemplateResult } from 'lit';
|
||||
|
||||
export interface CopyConfig {
|
||||
allowed: boolean;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import type { AIItemGroupConfig } from '@blocksuite/affine-components/ai-item';
|
||||
import { isInsidePageEditor } from '@blocksuite/affine-shared/utils';
|
||||
import type { EditorHost } from '@blocksuite/block-std';
|
||||
|
||||
import type { AIItemGroupConfig } from '../../../_common/components/ai-item/types.js';
|
||||
|
||||
export function filterAIItemGroup(
|
||||
host: EditorHost,
|
||||
configs: AIItemGroupConfig[]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { AIItemGroupConfig } from '@blocksuite/affine-components/ai-item';
|
||||
import { scrollbarStyle } from '@blocksuite/affine-shared/styles';
|
||||
import { on, stopPropagation } from '@blocksuite/affine-shared/utils';
|
||||
import type { EditorHost } from '@blocksuite/block-std';
|
||||
@@ -5,7 +6,6 @@ import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import { css, html, LitElement, nothing } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
|
||||
import type { AIItemGroupConfig } from '../../../_common/components/ai-item/types.js';
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||
|
||||
export class EdgelessCopilotPanel extends WithDisposable(LitElement) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { AIItemGroupConfig } from '@blocksuite/affine-components/ai-item';
|
||||
import { AIStarIcon } from '@blocksuite/affine-components/icons';
|
||||
import type { EditorHost } from '@blocksuite/block-std';
|
||||
import { isGfxGroupCompatibleModel } from '@blocksuite/block-std/gfx';
|
||||
@@ -5,7 +6,6 @@ import { WithDisposable } from '@blocksuite/global/utils';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
|
||||
import type { AIItemGroupConfig } from '../../../_common/components/ai-item/types.js';
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||
import type { CopilotTool } from '../../edgeless/gfx-tool/copilot-tool.js';
|
||||
import { sortEdgelessElements } from '../../edgeless/utils/clone-utils.js';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { AIItemGroupConfig } from '@blocksuite/affine-components/ai-item';
|
||||
import type { RootBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
MOUSE_BUTTON,
|
||||
@@ -18,7 +19,6 @@ import { css, html, nothing } from 'lit';
|
||||
import { query, state } from 'lit/decorators.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
|
||||
import type { AIItemGroupConfig } from '../../../_common/components/ai-item/types.js';
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||
import {
|
||||
AFFINE_AI_PANEL_WIDGET,
|
||||
|
||||
Reference in New Issue
Block a user