import { ProseEditor, Toolbar } from 'substance' import ContainerEditor from '../ContainerEditor' import Comments from '../panes/Comments/CommentBoxList' import CommentsProvider from '../panes/Comments/CommentsProvider' import TrackChangesProvider from '../elements/track_change/TrackChangesProvider' import SimpleExporter from '../SimpleEditorExporter' import { find, pickBy, isEmpty, values } from 'lodash' class NotesEditor extends ProseEditor { didMount () { const provider = this.getProvider() this.editorSession.onUpdate('document', this.findNote, this) provider.on('noteSelected', this.scrollTo, this) } render ($$) { const el = $$('div').addClass('sc-notes-editor') let editor = this._renderEditor($$) let SplitPane = this.componentRegistry.get('split-pane') let ScrollPane = this.componentRegistry.get('scroll-pane') let Overlay = this.componentRegistry.get('overlay') var commentsPane = $$(Comments, { comments: this.props.comments, fragment: this.props.fragment, update: this.props.update, user: this.props.user }).addClass('sc-comments-pane') const editorWithComments = $$(SplitPane, { sizeA: '80%', splitType: 'vertical' }) .append( editor, commentsPane ) const contentPanel = $$(ScrollPane, { name: 'notesEditorContentPanel', scrollbarPosition: 'right' }) .append(editorWithComments, $$(Overlay)) .attr('id', 'notes-editor-content-panel') .ref('notesEditorContentPanel') el.append(contentPanel) return el } _renderEditor ($$) { const hasIsolatedNotes = this.getIsolatedNodes() const disabled = (isEmpty(hasIsolatedNotes)) return $$(ContainerEditor, { book: this.props.book, comments: this.props.comments, containerId: this.props.containerId, configurator: this.props.configurator, editorSession: this.editorSession, disabled: disabled, history: this.props.history, fragment: this.props.fragment, spellcheck: 'native', trackChanges: this.props.trackChanges, trackChangesView: this.props.trackChangesView, user: this.props.user }).ref('notes_body') } scrollTo (nodeId) { const nodes = this.getIsolatedNodes() const note = find(nodes, function (c) { return c.calloutId === nodeId }) if (note) this.refs.notesEditorContentPanel.scrollTo(note.id) } saveNote (isolatedNote) { const exporter = new SimpleExporter(this.props.configurator.config) const convertedNode = exporter.convertNode(isolatedNote) this.context.editorSession.transaction(function (tx, args) { const path = [isolatedNote.calloutId, 'note-content'] tx.set(path, convertedNode.innerHTML.trim()) }) } findNote () { const selection = this.editorSession.getSelection() if (!selection.end) return const isolatedNoteId = selection.end.path[0] const isolatedNote = this.editorSession.document.get(isolatedNoteId) return this.saveNote(isolatedNote) } getIsolatedNodes () { const doc = this.editorSession.document const nodes = doc.getNodes() const entries = pickBy(nodes, function (value, key) { return value.type === 'isolated-note' }) return values(entries) } getProvider () { return this.context.notesProvider } getInitialState () { return { trackChangesView: this.props.trackChangesView } } getChildContext () { const oldContext = super.getChildContext() const doc = this.doc // comments provider const commentsProvider = new CommentsProvider(doc, { commandManager: this.commandManager, comments: this.props.fragment.comments, containerId: this.props.containerId, controller: this, editorSession: this.editorSession, fragment: this.props.fragment, surfaceManager: this.surfaceManager, update: this.props.update }) const trackChangesProvider = new TrackChangesProvider(doc, { commandManager: this.commandManager, containerId: this.props.containerId, controller: this, editorSession: this.editorSession, surfaceManager: this.surfaceManager, user: this.props.user }) // attach all to context return { ...oldContext, commentsProvider, trackChangesProvider } } } export default NotesEditor