diff --git a/editors/demo/src/Editoria/Editoria.js b/editors/demo/src/Editoria/Editoria.js index 3e85568eaea88403be4213b9ad9291685b3f3d73..0129e84837dde6261da807ccc69d20fd00407e9e 100644 --- a/editors/demo/src/Editoria/Editoria.js +++ b/editors/demo/src/Editoria/Editoria.js @@ -6,6 +6,7 @@ import { EditoriaLayout, EditoriaMobileLayout } from './layout'; import { config, configMobile } from './config'; import { demo } from './demo'; import { debounce } from 'lodash'; +import { TablesService } from 'wax-table-service'; const renderImage = file => { const reader = new FileReader(); @@ -32,6 +33,7 @@ const user = { // }]; const Editoria = () => { + const [myConfig, setMyConfig] = useState(config); const [width] = useWindowSize(); let layout = EditoriaLayout; @@ -48,10 +50,22 @@ const Editoria = () => { const EditoriaComponent = useMemo( () => ( <> + <button + onClick={() => { + console.log(myConfig); + myConfig.PmPlugins = []; + myConfig.services = [...myConfig.services, new TablesService()]; + setMyConfig({ ...myConfig }); + }} + > + {' '} + change config + </button> + <Wax ref={editorRef} key={key} - config={finalConfig} + config={myConfig} autoFocus placeholder="Type Something..." fileUpload={file => renderImage(file)} @@ -68,7 +82,7 @@ const Editoria = () => { </> ), // eslint-disable-next-line react-hooks/exhaustive-deps - [layout, finalConfig], + [layout, myConfig], ); return <>{EditoriaComponent}</>; }; diff --git a/editors/demo/src/Editoria/config/config.js b/editors/demo/src/Editoria/config/config.js index 2ffcdec386b92913dbbd896d2ef54a24c77060c7..8e2042e7afb62ac9bd41f2cbfd694e7ee22eeb0a 100644 --- a/editors/demo/src/Editoria/config/config.js +++ b/editors/demo/src/Editoria/config/config.js @@ -52,8 +52,7 @@ async function DummyPromise(userInput, { askKb }) { } else { // JSON response test const json = JSON.stringify({ - content: - askKb ? 'KB will be queried' : 'Just a normal call', + content: askKb ? 'KB will be queried' : 'Just a normal call', citations: ['citation 1', 'citation 2', 'citation 3'], links: ['https://coko.foundation/', 'https://waxjs.net/about/'], }); @@ -234,7 +233,7 @@ export default { 'SpecialCharacters', 'CodeBlock', 'ToggleAi', - 'Tables', + // 'Tables', 'TrackingAndEditing', 'FullScreen', ], @@ -306,13 +305,13 @@ export default { ], updateTags: saveTags, }, - YjsService: { - // eslint-disable-next-line no-restricted-globals - connectionUrl: 'ws://localhost:5010', - // connectionUrl: 'ws://0.tcp.ap.ngrok.io:17607', - docIdentifier: 'prosemirror-r5dw4q2fe2eedreeeeeweewwewerc', - YjsType: 'prosemirror', - }, + // YjsService: { + // // eslint-disable-next-line no-restricted-globals + // connectionUrl: 'ws://localhost:5010', + // // connectionUrl: 'ws://0.tcp.ap.ngrok.io:17607', + // docIdentifier: 'prosemirror-r5dw4q2fe2eedreeeeeweewwewerc', + // YjsType: 'prosemirror', + // }, AskAiContentService: { AskAiContentTransformation: DummyPromise, @@ -325,7 +324,7 @@ export default { }, services: [ - new YjsService(), + // new YjsService(), new BlockDropDownToolGroupService(), new AskAiContentService(), new CustomTagService(), @@ -337,7 +336,7 @@ export default { new TrackChangeService(), new CommentsService(), new ImageService(), - new TablesService(), + // new TablesService(), new BaseService(), // new NoteService(), new CodeBlockService(), diff --git a/wax-prosemirror-core/src/Application.js b/wax-prosemirror-core/src/Application.js index 33d89fade7127e2d947b0524e4f32bfbc06b0997..4f5853b1e9aa8e0c692f91c60642eeea6b238a91 100644 --- a/wax-prosemirror-core/src/Application.js +++ b/wax-prosemirror-core/src/Application.js @@ -1,12 +1,15 @@ import { Container } from 'inversify'; import 'reflect-metadata'; import deepmerge from 'deepmerge'; + +import { v4 as uuidv4 } from 'uuid'; import Config from './config/Config'; import defaultConfig from './config/defaultConfig'; import PmPlugins from './PmPlugins'; export default class Application { constructor(container) { + this.id = uuidv4(); this.container = container; this.PmPlugins = container.get('PmPlugins'); } @@ -101,12 +104,12 @@ export default class Application { Set base bindings for the App to work */ - container.bind('PmPlugins').to(PmPlugins).inSingletonScope(); + container.bind('PmPlugins').to(PmPlugins); container.bind('Wax').toFactory(() => new Application(container)); - container.bind('config').toConstantValue(appConfig); - container.bind('Config').to(Config).inSingletonScope(); + container.bind('config').toFactory(() => appConfig); + container.bind('Config').to(Config); /* Start the App diff --git a/wax-prosemirror-core/src/Wax.js b/wax-prosemirror-core/src/Wax.js index 391808400ef129c36671508277603b8b1e6e3639..2a6e5221c185c59f1b5d80c75fae03fd9207b0c2 100644 --- a/wax-prosemirror-core/src/Wax.js +++ b/wax-prosemirror-core/src/Wax.js @@ -35,6 +35,7 @@ const Wax = forwardRef((props, ref) => { autoFocus, browserSpellCheck, className, + config, customValues, fileUpload, layout, @@ -49,6 +50,11 @@ const Wax = forwardRef((props, ref) => { scrollThreshold, } = props; + useEffect(() => { + const newApplication = createApplication(props); + setApplication(newApplication); + }, [config.PmPlugins.length]); + if (!application) return null; const finalOnChange = content => { diff --git a/wax-prosemirror-core/src/WaxContext.js b/wax-prosemirror-core/src/WaxContext.js index d97ec379c28c616b9f6b18945d31ae29ab0c433d..94c3087716ee325cf83efee2aea06c0612b12d36 100644 --- a/wax-prosemirror-core/src/WaxContext.js +++ b/wax-prosemirror-core/src/WaxContext.js @@ -1,6 +1,6 @@ /* eslint react/prop-types: 0 */ /* eslint react/destructuring-assignment: 0 */ -import React, { useContext, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; export const WaxContext = React.createContext({ pmViews: {}, @@ -41,14 +41,17 @@ export default props => { }, }); - return ( - <WaxContext.Provider - value={{ + useEffect(() => { + if (props.app.config.get('config.PmPlugins').length === 0) { + setContext({ ...context, - }} - > - {props.children} - </WaxContext.Provider> + app: props.app, + }); + } + }, [props.app.id]); + + return ( + <WaxContext.Provider value={context}>{props.children}</WaxContext.Provider> ); }; diff --git a/wax-prosemirror-core/src/WaxView.js b/wax-prosemirror-core/src/WaxView.js index 4ddeacd5cff2f629c21c4bbe31af7ae29a63c19f..af7f86d464e2acd1baf124768b0588d185899f4e 100644 --- a/wax-prosemirror-core/src/WaxView.js +++ b/wax-prosemirror-core/src/WaxView.js @@ -7,7 +7,6 @@ import React, { useEffect, forwardRef, useImperativeHandle, - useState, } from 'react'; import styled from 'styled-components'; import { EditorState } from 'prosemirror-state'; @@ -40,7 +39,6 @@ const WaxView = forwardRef((props, ref) => { customValues, readonly, autoFocus, - reconfigureState, user, placeholder, targetFormat, @@ -51,18 +49,19 @@ const WaxView = forwardRef((props, ref) => { const context = useContext(WaxContext); const { createPortal } = useContext(PortalContext); - const [mounted, setMounted] = useState(false); + // const [mounted, setMounted] = useState(false); + context.app.setContext({ ...context, createPortal }); const schema = context.app.getSchema(); const setEditorRef = useCallback( node => { if (node) { - if (!mounted) { - context.app.bootServices(); - context.app.getShortCuts(); - context.app.getRules(); - } + // if (!mounted) { + context.app.bootServices(); + context.app.getShortCuts(); + context.app.getRules(); + // } const options = WaxOptions({ ...props, schema, @@ -86,7 +85,7 @@ const WaxView = forwardRef((props, ref) => { }, ); - setMounted(true); + // setMounted(true); context.updateView( { @@ -104,7 +103,7 @@ const WaxView = forwardRef((props, ref) => { } return node; }, - [readonly, customValues], + [readonly, customValues, context.app.id], ); useEffect(() => { @@ -112,52 +111,36 @@ const WaxView = forwardRef((props, ref) => { }, []); useEffect(() => { - console.log('in reconfigure'); // const parse = parser(schema); - if (!reconfigureState) return; + if (context.app.config.get('config.PmPlugins').length === 0) { + let finalPlugins = []; + + const createPlaceholder = () => { + return Placeholder({ content: placeholder }); + }; + + finalPlugins = defaultPlugins.concat([ + createPlaceholder(placeholder), + ...context.app.getPlugins(), + ]); - (reconfigureState?.plugins || []).forEach(plugin => { - const pluginKey = Object.keys(plugin)[0]; - const pluginValue = plugin[pluginKey]; + const reconfigureOptions = { + // doc: parse(value), + schema, + plugins: finalPlugins, + }; - if (context.app.PmPlugins.get(pluginKey)) { - context.app.PmPlugins.replace(pluginKey, pluginValue); - } else { - context.app.PmPlugins.add(pluginKey, pluginValue); + context.pmViews.main.updateState(EditorState.create(reconfigureOptions)); + + if (context.pmViews.main.dispatch) { + context.pmViews.main.dispatch( + context.pmViews?.main.state.tr.setMeta('addToHistory', false), + ); } - }); - console.log( - 'in reconfigure down', - reconfigureState, - context.app.getPlugins(), - ); - - let finalPlugins = []; - - const createPlaceholder = () => { - return Placeholder({ content: placeholder }); - }; - - finalPlugins = defaultPlugins.concat([ - createPlaceholder(placeholder), - ...context.app.getPlugins(), - ]); - - const reconfigureOptions = { - // doc: parse(value), - schema, - plugins: finalPlugins, - }; - - context.pmViews.main.updateState(EditorState.create(reconfigureOptions)); - - if (context.pmViews.main.dispatch) { - context.pmViews.main.dispatch( - context.pmViews?.main.state.tr.setMeta('addToHistory', false), - ); } + return true; - }, [JSON.stringify(reconfigureState)]); + }, [context.app.id]); useImperativeHandle(ref, () => ({ getContent() {