提交 2129a2d5 authored 作者: 王鹏飞's avatar 王鹏飞

refactor(admin): route AI menus through editor dialogs

上级 c16dd116
import { defineEditorFeature } from '../../core/define-editor-feature' import { defineEditorFeature } from '../../core/define-editor-feature'
import { createElement } from 'react'
import AIDigitalHuman from './digital-human-menu' import AIDigitalHuman from './digital-human-menu'
import AIImage from './image-menu' import AIImage from './image-menu'
import AIVideo from './video-menu' import AIVideo from './video-menu'
import DigitalHumanDialog from './DigitalHumanDialog'
import AiImageDialog from './AiImageDialog'
import AiVideoDialog from './AiVideoDialog'
const dialog = Component => props => createElement(Component, { editor: props.runtime.editor })
export default defineEditorFeature({ export default defineEditorFeature({
id: 'ai-media', id: 'ai-media',
...@@ -10,4 +16,9 @@ export default defineEditorFeature({ ...@@ -10,4 +16,9 @@ export default defineEditorFeature({
{ order: 320, config: AIImage }, { order: 320, config: AIImage },
{ order: 330, config: AIVideo }, { order: 330, config: AIVideo },
], ],
dialogs: [
{ id: 'ai-media.digital-human', component: dialog(DigitalHumanDialog) },
{ id: 'ai-media.image', component: dialog(AiImageDialog) },
{ id: 'ai-media.video', component: dialog(AiVideoDialog) },
],
}) })
import { defineEditorFeature } from '../../core/define-editor-feature' import { defineEditorFeature } from '../../core/define-editor-feature'
import { createElement } from 'react'
import AIQuestionGapFill from './gap-fill-menu' import AIQuestionGapFill from './gap-fill-menu'
import AIQuestionJudge from './judge-menu' import AIQuestionJudge from './judge-menu'
import AIQuestionMultiple from './multiple-menu' import AIQuestionMultiple from './multiple-menu'
import AIQuestionOpenEnded from './open-ended-menu' import AIQuestionOpenEnded from './open-ended-menu'
import AIQuestionSingle from './single-menu' import AIQuestionSingle from './single-menu'
import AiQuestionDialog from './AiQuestionDialog'
const dialog = props => createElement(AiQuestionDialog, { editor: props.runtime.editor, action: props.payload.action })
export default defineEditorFeature({ export default defineEditorFeature({
id: 'ai-question', id: 'ai-question',
...@@ -14,4 +18,5 @@ export default defineEditorFeature({ ...@@ -14,4 +18,5 @@ export default defineEditorFeature({
{ order: 260, config: AIQuestionGapFill }, { order: 260, config: AIQuestionGapFill },
{ order: 270, config: AIQuestionOpenEnded }, { order: 270, config: AIQuestionOpenEnded },
], ],
dialogs: [{ id: 'ai-question.generate', component: dialog }],
}) })
import { defineEditorFeature } from '../../core/define-editor-feature' import { defineEditorFeature } from '../../core/define-editor-feature'
import { createElement } from 'react'
import AIBaiduSearch from './baidu-search-menu' import AIBaiduSearch from './baidu-search-menu'
import AISearch from './search-menu' import AISearch from './search-menu'
import AIWrite from './write-menu' import AIWrite from './write-menu'
import SearchDialog from './SearchDialog'
import BaiduSearchDialog from './BaiduSearchDialog'
import AiWriteDialog from './AiWriteDialog'
const searchDialog = props => {
const Component = props.payload.provider === 'baidu' ? BaiduSearchDialog : SearchDialog
return createElement(Component, { editor: props.runtime.editor })
}
const writeDialog = props => createElement(AiWriteDialog, { editor: props.runtime.editor })
export default defineEditorFeature({ export default defineEditorFeature({
id: 'ai-research', id: 'ai-research',
...@@ -10,4 +20,8 @@ export default defineEditorFeature({ ...@@ -10,4 +20,8 @@ export default defineEditorFeature({
{ order: 310, config: AIWrite }, { order: 310, config: AIWrite },
{ order: 340, config: AIBaiduSearch }, { order: 340, config: AIBaiduSearch },
], ],
dialogs: [
{ id: 'ai-research.search', component: searchDialog },
{ id: 'ai-research.write', component: writeDialog },
],
}) })
import { defineEditorFeature } from '../../core/define-editor-feature' import { defineEditorFeature } from '../../core/define-editor-feature'
import { createElement } from 'react'
import AIChat from './chat-menu' import AIChat from './chat-menu'
import AIContentInspect from './content-inspect-menu' import AIContentInspect from './content-inspect-menu'
import AIExpand from './expand-menu' import AIExpand from './expand-menu'
...@@ -7,6 +8,10 @@ import AIPunctuation from './punctuation-menu' ...@@ -7,6 +8,10 @@ import AIPunctuation from './punctuation-menu'
import AIRewrite from './rewrite-menu' import AIRewrite from './rewrite-menu'
import AISummary from './summary-menu' import AISummary from './summary-menu'
import AITranslate from './translate-menu' import AITranslate from './translate-menu'
import AiChatDialog from './AiChatDialog'
import AiTextDialog from './AiTextDialog'
const dialog = Component => props => createElement(Component, { editor: props.runtime.editor, action: props.payload.action })
export default defineEditorFeature({ export default defineEditorFeature({
id: 'ai-text', id: 'ai-text',
...@@ -20,4 +25,8 @@ export default defineEditorFeature({ ...@@ -20,4 +25,8 @@ export default defineEditorFeature({
{ order: 220, config: AIContentInspect }, { order: 220, config: AIContentInspect },
{ order: 290, config: AITranslate }, { order: 290, config: AITranslate },
], ],
dialogs: [
{ id: 'ai-text.chat', component: dialog(AiChatDialog) },
{ id: 'ai-text.action', component: dialog(AiTextDialog) },
],
}) })
import { defineEditorFeature } from '../../core/define-editor-feature' import { defineEditorFeature } from '../../core/define-editor-feature'
import { createElement } from 'react'
import menu from './menu' import menu from './menu'
import IconDialog from './IconDialog'
export default defineEditorFeature({ id: 'icon', menus: [{ order: 360, config: menu }] }) const dialog = props => createElement(IconDialog, { editor: props.runtime.editor })
export default defineEditorFeature({
id: 'icon',
menus: [{ order: 360, config: menu }],
dialogs: [{ id: 'icon.insert', component: dialog }],
})
...@@ -10,6 +10,8 @@ import { setPracticeRandom } from "@/store/modules/editor"; ...@@ -10,6 +10,8 @@ import { setPracticeRandom } from "@/store/modules/editor";
import "./utils/jax.less"; import "./utils/jax.less";
import { Boot } from "@wangeditor/editor"; import { Boot } from "@wangeditor/editor";
import { registerEditorFeatures } from "./core/register-editor-features"; import { registerEditorFeatures } from "./core/register-editor-features";
import { EditorDialogHost } from "./core/EditorDialogHost";
import { editorFeatureRegistry } from "./features";
import { SlateEditor, DomEditor, SlateElement, SlateTransforms } from "@wangeditor/editor"; import { SlateEditor, DomEditor, SlateElement, SlateTransforms } from "@wangeditor/editor";
import { Editor, Toolbar } from "@wangeditor/editor-for-react"; import { Editor, Toolbar } from "@wangeditor/editor-for-react";
...@@ -991,6 +993,11 @@ const WangEditorCustomer = (props, ref) => { ...@@ -991,6 +993,11 @@ const WangEditorCustomer = (props, ref) => {
setContent={setContent} setContent={setContent}
/> />
</Modal> </Modal>
<EditorDialogHost
editor={editor}
registry={editorFeatureRegistry}
runtime={{ editor, chapterId, bookId, gData, nowTitle, saveContent, setContent }}
/>
</div> </div>
); );
}; };
......
import ReactDOM from "react-dom/client"; import { openEditorDialog } from "../../core/editor-dialog";
import { ConfigProvider, App } from "antd"; const dialogByMenu = {
import zhCN from "antd/locale/zh_CN"; AIChat: ['ai-text.chat', {}],
AIRewrite: ['ai-text.action', { action: 'rewrite' }],
AIExpand: ['ai-text.action', { action: 'expand' }],
AISummary: ['ai-text.action', { action: 'summary' }],
AIPolishing: ['ai-text.action', { action: 'abbreviate' }],
AIPunctuation: ['ai-text.action', { action: 'punctuation' }],
AIContentInspect: ['ai-text.action', { action: 'contentInspect' }],
AITranslate: ['ai-text.action', { action: 'translate' }],
AIQuestionSingle: ['ai-question.generate', { action: '1' }],
AIQuestionMultiple: ['ai-question.generate', { action: '2' }],
AIQuestionJudge: ['ai-question.generate', { action: '3' }],
AIQuestionGapFill: ['ai-question.generate', { action: '4' }],
AIQuestionOpenEnded: ['ai-question.generate', { action: '5' }],
AIDigitalHuman: ['ai-media.digital-human', {}],
AIImage: ['ai-media.image', {}],
AIVideo: ['ai-media.video', {}],
AISearch: ['ai-research.search', { provider: 'search' }],
AIBaiduSearch: ['ai-research.search', { provider: 'baidu' }],
AIWrite: ['ai-research.write', {}],
Icon: ['icon.insert', {}],
};
export default class BaseModalMenu { export default class BaseModalMenu {
constructor() { constructor() {
this.tag = "button"; this.tag = "button";
this.$el = document.createElement("div");
document.body.appendChild(this.$el);
this.$root = ReactDOM.createRoot(this.$el);
} }
isActive() { isActive() {
return false; // or true return false; // or true
...@@ -16,11 +33,9 @@ export default class BaseModalMenu { ...@@ -16,11 +33,9 @@ export default class BaseModalMenu {
isDisabled() { isDisabled() {
return false; // or true return false; // or true
} }
exec(editor, value) { exec(editor) {
this.$root.render( const request = dialogByMenu[this.constructor.name];
<ConfigProvider locale={zhCN} theme={{ token: { colorPrimary: "#aa1941" } }}> if (!request) return;
<App>{value}</App> openEditorDialog(editor, request[0], request[1]);
</ConfigProvider>,
);
} }
} }
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论