mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-08 20:57:08 +08:00
refactor(editor): use extension level config (#12110)
Closes: BS-3396 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced structured and validated configuration options for database and linked document views, allowing for more flexible and reliable customization. - Enhanced view manager to conditionally enable AI-related paragraph placeholders and database/linked document extensions based on configuration. - **Chores** - Updated dependencies to include the latest version of the Zod validation library. - Simplified and consolidated internal configuration and registration logic for AI and widget-related extensions. - **Refactor** - Streamlined configuration types and removed unused or redundant configuration utilities to improve maintainability. - Improved robustness of linked widget configuration retrieval to handle optional service availability gracefully. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,10 +1,6 @@
|
|||||||
import type { MenuOptions } from '@blocksuite/affine-components/context-menu';
|
|
||||||
import { type DatabaseBlockModel } from '@blocksuite/affine-model';
|
|
||||||
import { ConfigExtensionFactory } from '@blocksuite/std';
|
import { ConfigExtensionFactory } from '@blocksuite/std';
|
||||||
|
|
||||||
export interface DatabaseOptionsConfig {
|
import type { DatabaseViewExtensionOptions } from './view';
|
||||||
configure: (model: DatabaseBlockModel, options: MenuOptions) => MenuOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DatabaseConfigExtension =
|
export const DatabaseConfigExtension =
|
||||||
ConfigExtensionFactory<DatabaseOptionsConfig>('affine:database');
|
ConfigExtensionFactory<DatabaseViewExtensionOptions>('affine:database');
|
||||||
|
|||||||
@@ -46,10 +46,7 @@ import { computed, signal } from '@preact/signals-core';
|
|||||||
import { css, html, nothing, unsafeCSS } from 'lit';
|
import { css, html, nothing, unsafeCSS } from 'lit';
|
||||||
|
|
||||||
import { popSideDetail } from './components/layout.js';
|
import { popSideDetail } from './components/layout.js';
|
||||||
import {
|
import { DatabaseConfigExtension } from './config.js';
|
||||||
DatabaseConfigExtension,
|
|
||||||
type DatabaseOptionsConfig,
|
|
||||||
} from './config.js';
|
|
||||||
import { HostContextKey } from './context/host-context.js';
|
import { HostContextKey } from './context/host-context.js';
|
||||||
import { DatabaseBlockDataSource } from './data-source.js';
|
import { DatabaseBlockDataSource } from './data-source.js';
|
||||||
import { BlockRenderer } from './detail-panel/block-renderer.js';
|
import { BlockRenderer } from './detail-panel/block-renderer.js';
|
||||||
@@ -57,6 +54,7 @@ import { NoteRenderer } from './detail-panel/note-renderer.js';
|
|||||||
import { DatabaseSelection } from './selection.js';
|
import { DatabaseSelection } from './selection.js';
|
||||||
import { currentViewStorage } from './utils/current-view.js';
|
import { currentViewStorage } from './utils/current-view.js';
|
||||||
import { getSingleDocIdFromText } from './utils/title-doc.js';
|
import { getSingleDocIdFromText } from './utils/title-doc.js';
|
||||||
|
import type { DatabaseViewExtensionOptions } from './view';
|
||||||
|
|
||||||
export class DatabaseBlockComponent extends CaptionedBlockComponent<DatabaseBlockModel> {
|
export class DatabaseBlockComponent extends CaptionedBlockComponent<DatabaseBlockModel> {
|
||||||
static override styles = css`
|
static override styles = css`
|
||||||
@@ -345,7 +343,7 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent<DatabaseBloc
|
|||||||
return this._dataSource;
|
return this._dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
get optionsConfig(): DatabaseOptionsConfig {
|
get optionsConfig(): DatabaseViewExtensionOptions {
|
||||||
return {
|
return {
|
||||||
configure: (_model, options) => options,
|
configure: (_model, options) => options,
|
||||||
...this.std.getOptional(DatabaseConfigExtension.identifier),
|
...this.std.getOptional(DatabaseConfigExtension.identifier),
|
||||||
|
|||||||
@@ -1,28 +1,51 @@
|
|||||||
|
import type { MenuOptions } from '@blocksuite/affine-components/context-menu';
|
||||||
import {
|
import {
|
||||||
type ViewExtensionContext,
|
type ViewExtensionContext,
|
||||||
ViewExtensionProvider,
|
ViewExtensionProvider,
|
||||||
} from '@blocksuite/affine-ext-loader';
|
} from '@blocksuite/affine-ext-loader';
|
||||||
|
import { DatabaseBlockModel } from '@blocksuite/affine-model';
|
||||||
import { SlashMenuConfigExtension } from '@blocksuite/affine-widget-slash-menu';
|
import { SlashMenuConfigExtension } from '@blocksuite/affine-widget-slash-menu';
|
||||||
import { BlockViewExtension, FlavourExtension } from '@blocksuite/std';
|
import { BlockViewExtension, FlavourExtension } from '@blocksuite/std';
|
||||||
import { literal } from 'lit/static-html.js';
|
import { literal } from 'lit/static-html.js';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { DatabaseConfigExtension } from './config';
|
||||||
import { databaseSlashMenuConfig } from './configs/slash-menu.js';
|
import { databaseSlashMenuConfig } from './configs/slash-menu.js';
|
||||||
import { effects } from './effects';
|
import { effects } from './effects';
|
||||||
|
|
||||||
export class DatabaseViewExtension extends ViewExtensionProvider {
|
const optionsSchema = z.object({
|
||||||
|
configure: z
|
||||||
|
.function()
|
||||||
|
.args(z.instanceof(DatabaseBlockModel), z.custom<MenuOptions>())
|
||||||
|
.returns(z.custom<MenuOptions>()),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type DatabaseViewExtensionOptions = z.infer<typeof optionsSchema>;
|
||||||
|
|
||||||
|
export class DatabaseViewExtension extends ViewExtensionProvider<DatabaseViewExtensionOptions> {
|
||||||
override name = 'affine-database-block';
|
override name = 'affine-database-block';
|
||||||
|
|
||||||
|
override schema = optionsSchema;
|
||||||
|
|
||||||
override effect() {
|
override effect() {
|
||||||
super.effect();
|
super.effect();
|
||||||
effects();
|
effects();
|
||||||
}
|
}
|
||||||
|
|
||||||
override setup(context: ViewExtensionContext) {
|
override setup(
|
||||||
|
context: ViewExtensionContext,
|
||||||
|
options?: DatabaseViewExtensionOptions
|
||||||
|
) {
|
||||||
super.setup(context);
|
super.setup(context);
|
||||||
context.register([
|
context.register([
|
||||||
FlavourExtension('affine:database'),
|
FlavourExtension('affine:database'),
|
||||||
BlockViewExtension('affine:database', literal`affine-database`),
|
BlockViewExtension('affine:database', literal`affine-database`),
|
||||||
SlashMenuConfigExtension('affine:database', databaseSlashMenuConfig),
|
SlashMenuConfigExtension('affine:database', databaseSlashMenuConfig),
|
||||||
]);
|
]);
|
||||||
|
if (options) {
|
||||||
|
context.register(
|
||||||
|
DatabaseConfigExtension({ configure: options.configure })
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,8 @@
|
|||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
"lit": "^3.2.0",
|
"lit": "^3.2.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"rxjs": "^7.8.1"
|
"rxjs": "^7.8.1",
|
||||||
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./src/index.ts",
|
".": "./src/index.ts",
|
||||||
|
|||||||
@@ -27,62 +27,12 @@ import type { InlineRange } from '@blocksuite/std/inline';
|
|||||||
import type { TemplateResult } from 'lit';
|
import type { TemplateResult } from 'lit';
|
||||||
|
|
||||||
import { showImportModal } from './import-doc/index.js';
|
import { showImportModal } from './import-doc/index.js';
|
||||||
|
import type { LinkedDocViewExtensionOptions } from './view';
|
||||||
|
|
||||||
export interface LinkedWidgetConfig {
|
export type LinkedWidgetConfig = Required<
|
||||||
/**
|
Omit<LinkedDocViewExtensionOptions, 'autoFocusedItemKey'>
|
||||||
* The first item of the trigger keys will be the primary key
|
> &
|
||||||
* e.g. @, [[
|
Pick<LinkedDocViewExtensionOptions, 'autoFocusedItemKey'>;
|
||||||
*/
|
|
||||||
triggerKeys: [string, ...string[]];
|
|
||||||
/**
|
|
||||||
* Convert trigger key to primary key (the first item of the trigger keys)
|
|
||||||
* [[ -> @
|
|
||||||
*/
|
|
||||||
convertTriggerKey: boolean;
|
|
||||||
ignoreBlockTypes: string[];
|
|
||||||
ignoreSelector: string;
|
|
||||||
getMenus: (
|
|
||||||
query: string,
|
|
||||||
abort: () => void,
|
|
||||||
editorHost: EditorHost,
|
|
||||||
inlineEditor: AffineInlineEditor,
|
|
||||||
abortSignal: AbortSignal
|
|
||||||
) => Promise<LinkedMenuGroup[]> | LinkedMenuGroup[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Auto focused item
|
|
||||||
*
|
|
||||||
* Will be called when the menu is
|
|
||||||
* - opened
|
|
||||||
* - query changed
|
|
||||||
* - menu group or its items changed
|
|
||||||
*
|
|
||||||
* If the return value is not null, no action will be taken.
|
|
||||||
*/
|
|
||||||
autoFocusedItemKey?: (
|
|
||||||
menus: LinkedMenuGroup[],
|
|
||||||
query: string,
|
|
||||||
currentActiveKey: string | null,
|
|
||||||
editorHost: EditorHost,
|
|
||||||
inlineEditor: AffineInlineEditor
|
|
||||||
) => string | null;
|
|
||||||
|
|
||||||
mobile: {
|
|
||||||
/**
|
|
||||||
* The linked doc menu widget will scroll the container to make sure the input cursor is visible in viewport.
|
|
||||||
* It accepts a selector string, HTMLElement or Window
|
|
||||||
*
|
|
||||||
* @default getViewportElement(editorHost) this is the scrollable container in playground
|
|
||||||
*/
|
|
||||||
scrollContainer?: string | HTMLElement | Window;
|
|
||||||
/**
|
|
||||||
* The offset between the top of viewport and the input cursor
|
|
||||||
*
|
|
||||||
* @default 46 The height of header in playground
|
|
||||||
*/
|
|
||||||
scrollTopOffset?: number | (() => number);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export type LinkedMenuItem = {
|
export type LinkedMenuItem = {
|
||||||
key: string;
|
key: string;
|
||||||
@@ -269,7 +219,6 @@ export function getMenus(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const LinkedWidgetUtils = {
|
export const LinkedWidgetUtils = {
|
||||||
createLinkedDocMenuGroup,
|
|
||||||
createNewDocMenuGroup,
|
createNewDocMenuGroup,
|
||||||
insertLinkedNode,
|
insertLinkedNode,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,20 +2,82 @@ import {
|
|||||||
type ViewExtensionContext,
|
type ViewExtensionContext,
|
||||||
ViewExtensionProvider,
|
ViewExtensionProvider,
|
||||||
} from '@blocksuite/affine-ext-loader';
|
} from '@blocksuite/affine-ext-loader';
|
||||||
|
import type { AffineInlineEditor } from '@blocksuite/affine-shared/types';
|
||||||
|
import type { EditorHost } from '@blocksuite/std';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { type LinkedMenuGroup, LinkedWidgetConfigExtension } from './config';
|
||||||
import { effects } from './effects';
|
import { effects } from './effects';
|
||||||
import { linkedDocWidget } from './widget';
|
import { linkedDocWidget } from './widget';
|
||||||
|
|
||||||
export class LinkedDocViewExtension extends ViewExtensionProvider {
|
const optionsSchema = z.object({
|
||||||
|
triggerKeys: z.optional(z.tuple([z.string()]).rest(z.string())),
|
||||||
|
convertTriggerKey: z.boolean().optional(),
|
||||||
|
ignoreBlockTypes: z.array(z.string()).optional(),
|
||||||
|
ignoreSelector: z.string().optional(),
|
||||||
|
getMenus: z.optional(
|
||||||
|
z
|
||||||
|
.function()
|
||||||
|
.args(
|
||||||
|
z.string(),
|
||||||
|
z.function().returns(z.void()),
|
||||||
|
z.custom<EditorHost>(),
|
||||||
|
z.custom<AffineInlineEditor>(),
|
||||||
|
z.instanceof(AbortSignal)
|
||||||
|
)
|
||||||
|
.returns(
|
||||||
|
z.union([
|
||||||
|
z.promise(z.array(z.custom<LinkedMenuGroup>())),
|
||||||
|
z.array(z.custom<LinkedMenuGroup>()),
|
||||||
|
])
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
autoFocusedItemKey: z.optional(
|
||||||
|
z
|
||||||
|
.function()
|
||||||
|
.args(
|
||||||
|
z.array(z.custom<LinkedMenuGroup>()),
|
||||||
|
z.string(),
|
||||||
|
z.string().nullable(),
|
||||||
|
z.custom<EditorHost>(),
|
||||||
|
z.custom<AffineInlineEditor>()
|
||||||
|
)
|
||||||
|
.returns(z.string().nullable())
|
||||||
|
),
|
||||||
|
|
||||||
|
mobile: z
|
||||||
|
.object({
|
||||||
|
scrollContainer: z.optional(
|
||||||
|
z.union([z.string(), z.instanceof(HTMLElement), z.custom<Window>()])
|
||||||
|
),
|
||||||
|
scrollTopOffset: z.optional(
|
||||||
|
z.union([z.number(), z.function().returns(z.number())])
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type LinkedDocViewExtensionOptions = z.infer<typeof optionsSchema>;
|
||||||
|
|
||||||
|
export class LinkedDocViewExtension extends ViewExtensionProvider<LinkedDocViewExtensionOptions> {
|
||||||
override name = 'affine-linked-doc-widget';
|
override name = 'affine-linked-doc-widget';
|
||||||
|
|
||||||
|
override schema = optionsSchema;
|
||||||
|
|
||||||
override effect() {
|
override effect() {
|
||||||
super.effect();
|
super.effect();
|
||||||
effects();
|
effects();
|
||||||
}
|
}
|
||||||
|
|
||||||
override setup(context: ViewExtensionContext) {
|
override setup(
|
||||||
|
context: ViewExtensionContext,
|
||||||
|
options?: LinkedDocViewExtensionOptions
|
||||||
|
) {
|
||||||
super.setup(context);
|
super.setup(context);
|
||||||
context.register(linkedDocWidget);
|
context.register(linkedDocWidget);
|
||||||
|
if (options) {
|
||||||
|
context.register(LinkedWidgetConfigExtension(options));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
import { WorkspaceServerService } from '@affine/core/modules/cloud';
|
import { WorkspaceServerService } from '@affine/core/modules/cloud';
|
||||||
import { EditorSettingService } from '@affine/core/modules/editor-setting';
|
import { EditorSettingService } from '@affine/core/modules/editor-setting';
|
||||||
import { DatabaseConfigExtension } from '@blocksuite/affine/blocks/database';
|
|
||||||
import { ToolbarMoreMenuConfigExtension } from '@blocksuite/affine/components/toolbar';
|
import { ToolbarMoreMenuConfigExtension } from '@blocksuite/affine/components/toolbar';
|
||||||
import { EditorSettingExtension } from '@blocksuite/affine/shared/services';
|
import { EditorSettingExtension } from '@blocksuite/affine/shared/services';
|
||||||
import type { ExtensionType } from '@blocksuite/affine/store';
|
import type { ExtensionType } from '@blocksuite/affine/store';
|
||||||
import { LinkedWidgetConfigExtension } from '@blocksuite/affine/widgets/linked-doc';
|
|
||||||
import type { FrameworkProvider } from '@toeverything/infra';
|
import type { FrameworkProvider } from '@toeverything/infra';
|
||||||
|
|
||||||
import { createDatabaseOptionsConfig } from './database';
|
|
||||||
import { createLinkedWidgetConfig } from './linked';
|
|
||||||
import {
|
import {
|
||||||
createCustomToolbarExtension,
|
createCustomToolbarExtension,
|
||||||
createToolbarMoreMenuConfig,
|
createToolbarMoreMenuConfig,
|
||||||
@@ -27,8 +23,6 @@ export function getEditorConfigExtension(
|
|||||||
setting$: editorSettingService.editorSetting.settingSignal,
|
setting$: editorSettingService.editorSetting.settingSignal,
|
||||||
set: (k, v) => editorSettingService.editorSetting.set(k, v),
|
set: (k, v) => editorSettingService.editorSetting.set(k, v),
|
||||||
}),
|
}),
|
||||||
DatabaseConfigExtension(createDatabaseOptionsConfig(framework)),
|
|
||||||
LinkedWidgetConfigExtension(createLinkedWidgetConfig(framework)),
|
|
||||||
ToolbarMoreMenuConfigExtension(createToolbarMoreMenuConfig(framework)),
|
ToolbarMoreMenuConfigExtension(createToolbarMoreMenuConfig(framework)),
|
||||||
|
|
||||||
createCustomToolbarExtension(editorSettingService.editorSetting, baseUrl),
|
createCustomToolbarExtension(editorSettingService.editorSetting, baseUrl),
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { type FrameworkProvider } from '@toeverything/infra';
|
|||||||
|
|
||||||
export function createLinkedWidgetConfig(
|
export function createLinkedWidgetConfig(
|
||||||
framework: FrameworkProvider
|
framework: FrameworkProvider
|
||||||
): Partial<LinkedWidgetConfig> {
|
): Partial<LinkedWidgetConfig> | undefined {
|
||||||
return framework.get(AtMenuConfigService).getConfig();
|
const service = framework.getOptional(AtMenuConfigService);
|
||||||
|
if (!service) return;
|
||||||
|
return service.getConfig();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import {
|
|||||||
getThemeExtension,
|
getThemeExtension,
|
||||||
} from '@affine/core/blocksuite/extensions/theme';
|
} from '@affine/core/blocksuite/extensions/theme';
|
||||||
import { PeekViewService } from '@affine/core/modules/peek-view';
|
import { PeekViewService } from '@affine/core/modules/peek-view';
|
||||||
import { ParagraphBlockConfigExtension } from '@blocksuite/affine/blocks/paragraph';
|
|
||||||
import {
|
import {
|
||||||
type ViewExtensionContext,
|
type ViewExtensionContext,
|
||||||
ViewExtensionProvider,
|
ViewExtensionProvider,
|
||||||
@@ -60,58 +59,37 @@ export class AffineCommonViewExtension extends ViewExtensionProvider<
|
|||||||
) {
|
) {
|
||||||
context.register(AIChatBlockSpec);
|
context.register(AIChatBlockSpec);
|
||||||
context.register(AITranscriptionBlockSpec);
|
context.register(AITranscriptionBlockSpec);
|
||||||
context.register(
|
context.register([
|
||||||
[
|
AICodeBlockWatcher,
|
||||||
AICodeBlockWatcher,
|
ToolbarModuleExtension({
|
||||||
|
id: BlockFlavourIdentifier('custom:affine:image'),
|
||||||
|
config: imageToolbarAIEntryConfig(),
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
if (context.scope === 'edgeless' || context.scope === 'page') {
|
||||||
|
context.register([
|
||||||
|
aiPanelWidget,
|
||||||
|
AiSlashMenuConfigExtension(),
|
||||||
ToolbarModuleExtension({
|
ToolbarModuleExtension({
|
||||||
id: BlockFlavourIdentifier('custom:affine:image'),
|
id: BlockFlavourIdentifier('custom:affine:note'),
|
||||||
config: imageToolbarAIEntryConfig(),
|
config: toolbarAIEntryConfig(),
|
||||||
}),
|
}),
|
||||||
ParagraphBlockConfigExtension({
|
]);
|
||||||
getPlaceholder: model => {
|
}
|
||||||
const placeholders = {
|
|
||||||
text: "Type '/' for commands, 'space' for AI",
|
|
||||||
h1: 'Heading 1',
|
|
||||||
h2: 'Heading 2',
|
|
||||||
h3: 'Heading 3',
|
|
||||||
h4: 'Heading 4',
|
|
||||||
h5: 'Heading 5',
|
|
||||||
h6: 'Heading 6',
|
|
||||||
quote: '',
|
|
||||||
};
|
|
||||||
return placeholders[model.props.type];
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
].flat()
|
|
||||||
);
|
|
||||||
if (context.scope === 'edgeless') {
|
if (context.scope === 'edgeless') {
|
||||||
context.register([
|
context.register([
|
||||||
CopilotTool,
|
CopilotTool,
|
||||||
aiPanelWidget,
|
|
||||||
edgelessCopilotWidget,
|
edgelessCopilotWidget,
|
||||||
getAIEdgelessRootWatcher(framework),
|
getAIEdgelessRootWatcher(framework),
|
||||||
// In note
|
// In note
|
||||||
ToolbarModuleExtension({
|
|
||||||
id: BlockFlavourIdentifier('custom:affine:note'),
|
|
||||||
config: toolbarAIEntryConfig(),
|
|
||||||
}),
|
|
||||||
ToolbarModuleExtension({
|
ToolbarModuleExtension({
|
||||||
id: BlockFlavourIdentifier('custom:affine:surface:*'),
|
id: BlockFlavourIdentifier('custom:affine:surface:*'),
|
||||||
config: edgelessToolbarAIEntryConfig(),
|
config: edgelessToolbarAIEntryConfig(),
|
||||||
}),
|
}),
|
||||||
AiSlashMenuConfigExtension(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
if (context.scope === 'page') {
|
if (context.scope === 'page') {
|
||||||
context.register([
|
context.register(getAIPageRootWatcher(framework));
|
||||||
aiPanelWidget,
|
|
||||||
getAIPageRootWatcher(framework),
|
|
||||||
ToolbarModuleExtension({
|
|
||||||
id: BlockFlavourIdentifier('custom:affine:note'),
|
|
||||||
config: toolbarAIEntryConfig(),
|
|
||||||
}),
|
|
||||||
AiSlashMenuConfigExtension(),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
|
import { createDatabaseOptionsConfig } from '@affine/core/blocksuite/extensions/editor-config/database';
|
||||||
|
import { createLinkedWidgetConfig } from '@affine/core/blocksuite/extensions/editor-config/linked';
|
||||||
import { AffineCommonViewExtension } from '@affine/core/blocksuite/manager/common-view';
|
import { AffineCommonViewExtension } from '@affine/core/blocksuite/manager/common-view';
|
||||||
import {
|
import {
|
||||||
AffineEditorViewExtension,
|
AffineEditorViewExtension,
|
||||||
type AffineEditorViewOptions,
|
type AffineEditorViewOptions,
|
||||||
} from '@affine/core/blocksuite/manager/editor-view';
|
} from '@affine/core/blocksuite/manager/editor-view';
|
||||||
|
import { DatabaseViewExtension } from '@blocksuite/affine/blocks/database/view';
|
||||||
|
import { ParagraphViewExtension } from '@blocksuite/affine/blocks/paragraph/view';
|
||||||
import { ViewExtensionManager } from '@blocksuite/affine/ext-loader';
|
import { ViewExtensionManager } from '@blocksuite/affine/ext-loader';
|
||||||
import { getInternalViewExtensions } from '@blocksuite/affine/extensions/view';
|
import { getInternalViewExtensions } from '@blocksuite/affine/extensions/view';
|
||||||
|
import { LinkedDocViewExtension } from '@blocksuite/affine/widgets/linked-doc/view';
|
||||||
import type { FrameworkProvider } from '@toeverything/infra';
|
import type { FrameworkProvider } from '@toeverything/infra';
|
||||||
|
|
||||||
const manager = new ViewExtensionManager([
|
const manager = new ViewExtensionManager([
|
||||||
@@ -24,5 +29,34 @@ export function getViewManager(
|
|||||||
enableAI,
|
enableAI,
|
||||||
});
|
});
|
||||||
manager.configure(AffineEditorViewExtension, options);
|
manager.configure(AffineEditorViewExtension, options);
|
||||||
|
|
||||||
|
if (framework) {
|
||||||
|
manager.configure(
|
||||||
|
DatabaseViewExtension,
|
||||||
|
createDatabaseOptionsConfig(framework)
|
||||||
|
);
|
||||||
|
manager.configure(
|
||||||
|
LinkedDocViewExtension,
|
||||||
|
createLinkedWidgetConfig(framework)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enableAI) {
|
||||||
|
manager.configure(ParagraphViewExtension, {
|
||||||
|
getPlaceholder: model => {
|
||||||
|
const placeholders = {
|
||||||
|
text: "Type '/' for commands, 'space' for AI",
|
||||||
|
h1: 'Heading 1',
|
||||||
|
h2: 'Heading 2',
|
||||||
|
h3: 'Heading 3',
|
||||||
|
h4: 'Heading 4',
|
||||||
|
h5: 'Heading 5',
|
||||||
|
h6: 'Heading 6',
|
||||||
|
quote: '',
|
||||||
|
};
|
||||||
|
return placeholders[model.props.type] ?? '';
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user