refactor(core): edgeless toolbar ai action config extension (#10884)
This commit is contained in:
@@ -51,12 +51,11 @@ import {
|
|||||||
import { html } from 'lit';
|
import { html } from 'lit';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
|
|
||||||
import { EdgelessRootBlockComponent } from '../..';
|
|
||||||
import { mountConnectorLabelEditor } from '../../utils/text';
|
import { mountConnectorLabelEditor } from '../../utils/text';
|
||||||
import { LINE_STYLE_LIST } from './consts';
|
import { LINE_STYLE_LIST } from './consts';
|
||||||
import { createTextActions } from './text-common';
|
import { createTextActions } from './text-common';
|
||||||
import type { MenuItem } from './types';
|
import type { MenuItem } from './types';
|
||||||
import { renderMenu } from './utils';
|
import { getEdgelessWith, renderMenu } from './utils';
|
||||||
|
|
||||||
const FRONT_ENDPOINT_STYLE_LIST = [
|
const FRONT_ENDPOINT_STYLE_LIST = [
|
||||||
{
|
{
|
||||||
@@ -336,12 +335,8 @@ export const builtinConnectorToolbarConfig = {
|
|||||||
const rootModel = ctx.store.root;
|
const rootModel = ctx.store.root;
|
||||||
if (!rootModel) return;
|
if (!rootModel) return;
|
||||||
|
|
||||||
// TODO(@fundon): it should be simple
|
const edgeless = getEdgelessWith(ctx);
|
||||||
const edgeless = ctx.view.getBlock(rootModel.id);
|
if (!edgeless) return;
|
||||||
if (!ctx.matchBlock(edgeless, EdgelessRootBlockComponent)) {
|
|
||||||
console.error('edgeless view is not found.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mountConnectorLabelEditor(model, edgeless);
|
mountConnectorLabelEditor(model, edgeless);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ import type {
|
|||||||
} from '@blocksuite/affine/blocks/root';
|
} from '@blocksuite/affine/blocks/root';
|
||||||
import { noop } from '@blocksuite/affine/global/utils';
|
import { noop } from '@blocksuite/affine/global/utils';
|
||||||
import type { DocMode } from '@blocksuite/affine/model';
|
import type { DocMode } from '@blocksuite/affine/model';
|
||||||
|
import {
|
||||||
|
ActionPlacement,
|
||||||
|
type ToolbarModuleConfig,
|
||||||
|
} from '@blocksuite/affine/shared/services';
|
||||||
import { html } from 'lit';
|
import { html } from 'lit';
|
||||||
|
|
||||||
import type { AIItemGroupConfig } from '../../components/ai-item/types';
|
import type { AIItemGroupConfig } from '../../components/ai-item/types';
|
||||||
@@ -78,3 +82,70 @@ export function setupEdgelessElementToolbarAIEntry(
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function edgelessToolbarAIEntryConfig(): ToolbarModuleConfig {
|
||||||
|
return {
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
placement: ActionPlacement.Start,
|
||||||
|
id: 'A.ai',
|
||||||
|
score: -1,
|
||||||
|
when(ctx) {
|
||||||
|
const models = ctx.getSurfaceModels();
|
||||||
|
return models.length > 0 && !models.some(model => model.isLocked());
|
||||||
|
},
|
||||||
|
content: ({ host, chain }) => {
|
||||||
|
const filteredGroups = edgelessAIGroups.reduce<AIItemGroupConfig[]>(
|
||||||
|
(pre, group) => {
|
||||||
|
const filtered = group.items.filter(item =>
|
||||||
|
item.showWhen?.(chain, 'edgeless' as DocMode, host)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (filtered.length > 0) pre.push({ ...group, items: filtered });
|
||||||
|
|
||||||
|
return pre;
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (filteredGroups.every(group => group.items.length === 0))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
const handler = () => {
|
||||||
|
const aiPanel = getAIPanelWidget(host);
|
||||||
|
if (aiPanel.config) {
|
||||||
|
aiPanel.config.generateAnswer = ({ finish, input }) => {
|
||||||
|
finish('success');
|
||||||
|
aiPanel.hide();
|
||||||
|
extractSelectedContent(host)
|
||||||
|
.then(context => {
|
||||||
|
AIProvider.slots.requestSendWithChat.next({
|
||||||
|
input,
|
||||||
|
context,
|
||||||
|
host,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
|
};
|
||||||
|
aiPanel.config.inputCallback = text => {
|
||||||
|
const copilotWidget = getEdgelessCopilotWidget(host);
|
||||||
|
const panel = copilotWidget.shadowRoot?.querySelector(
|
||||||
|
'edgeless-copilot-panel'
|
||||||
|
);
|
||||||
|
if (panel instanceof HTMLElement) {
|
||||||
|
panel.style.visibility = text ? 'hidden' : 'visible';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return html`<edgeless-copilot-toolbar-entry
|
||||||
|
.host=${host}
|
||||||
|
.groups=${edgelessAIGroups}
|
||||||
|
.onClick=${handler}
|
||||||
|
></edgeless-copilot-toolbar-entry>`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import type { FrameworkProvider } from '@toeverything/infra';
|
|||||||
import { buildAIPanelConfig } from '../ai-panel';
|
import { buildAIPanelConfig } from '../ai-panel';
|
||||||
import { toolbarAIEntryConfig } from '../entries';
|
import { toolbarAIEntryConfig } from '../entries';
|
||||||
import {
|
import {
|
||||||
|
edgelessToolbarAIEntryConfig,
|
||||||
setupEdgelessCopilot,
|
setupEdgelessCopilot,
|
||||||
setupEdgelessElementToolbarAIEntry,
|
setupEdgelessElementToolbarAIEntry,
|
||||||
} from '../entries/edgeless/index';
|
} from '../entries/edgeless/index';
|
||||||
@@ -37,10 +38,15 @@ export function createAIEdgelessRootBlockSpec(
|
|||||||
aiPanelWidget,
|
aiPanelWidget,
|
||||||
edgelessCopilotWidget,
|
edgelessCopilotWidget,
|
||||||
getAIEdgelessRootWatcher(framework),
|
getAIEdgelessRootWatcher(framework),
|
||||||
|
// In note
|
||||||
ToolbarModuleExtension({
|
ToolbarModuleExtension({
|
||||||
id: BlockFlavourIdentifier('custom:affine:note'),
|
id: BlockFlavourIdentifier('custom:affine:note'),
|
||||||
config: toolbarAIEntryConfig(),
|
config: toolbarAIEntryConfig(),
|
||||||
}),
|
}),
|
||||||
|
ToolbarModuleExtension({
|
||||||
|
id: BlockFlavourIdentifier('custom:affine:surface:*'),
|
||||||
|
config: edgelessToolbarAIEntryConfig(),
|
||||||
|
}),
|
||||||
AiSlashMenuConfigExtension(),
|
AiSlashMenuConfigExtension(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user