From cd7df3d6d4e7482ccaed1600f87caa634b279425 Mon Sep 17 00:00:00 2001 From: chris <kokosias@yahoo.gr> Date: Tue, 28 Nov 2023 16:49:07 +0200 Subject: [PATCH] essay question wrapper component --- .../ShortCutsService/ShortCuts.js | 7 +- .../EssayQuestionContainerNodeView.js | 40 +++++++++ .../src/EssayService/EssayService.js | 8 ++ .../EssayQuestionContainerComponent.js | 85 +++++++++++++++++++ .../FillTheGapContainerComponent.js | 1 - 5 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 wax-questions-service/src/EssayService/EssayQuestionContainerNodeView.js create mode 100644 wax-questions-service/src/EssayService/components/EssayQuestionContainerComponent.js diff --git a/wax-prosemirror-core/src/config/defaultServices/ShortCutsService/ShortCuts.js b/wax-prosemirror-core/src/config/defaultServices/ShortCutsService/ShortCuts.js index a2dfada7f..b6f5ad26d 100644 --- a/wax-prosemirror-core/src/config/defaultServices/ShortCutsService/ShortCuts.js +++ b/wax-prosemirror-core/src/config/defaultServices/ShortCutsService/ShortCuts.js @@ -36,9 +36,10 @@ const backSpaceShortCut = (state, dispatch, view) => { state.doc.nodesBetween($from.pos, $to.pos, (node, from) => { if (node.type.name === 'fill_the_gap_container') { - const index = $from.index($from.depth); - const $beforePos = state.doc.resolve($from.posAtIndex(index - 1)); - dispatch(state.tr.setSelection(new NodeSelection($beforePos))); + // dispatch(state.tr.delete(from, from + node.nodeSize)); + // const index = $from.index($from.depth); + // const $beforePos = state.doc.resolve($from.posAtIndex(index - 1)); + // dispatch(state.tr.setSelection(new NodeSelection($beforePos))); } }); diff --git a/wax-questions-service/src/EssayService/EssayQuestionContainerNodeView.js b/wax-questions-service/src/EssayService/EssayQuestionContainerNodeView.js new file mode 100644 index 000000000..711f8ba5b --- /dev/null +++ b/wax-questions-service/src/EssayService/EssayQuestionContainerNodeView.js @@ -0,0 +1,40 @@ +import { QuestionsNodeView } from 'wax-prosemirror-core'; + +export default class EssayQuestionContainerNodeView extends QuestionsNodeView { + constructor( + node, + view, + getPos, + decorations, + createPortal, + Component, + context, + ) { + super(node, view, getPos, decorations, createPortal, Component, context); + + this.node = node; + this.outerView = view; + this.getPos = getPos; + this.context = context; + } + + static name() { + return 'essay_container'; + } + + selectNode() { + this.context.pmViews[this.node.attrs.id].focus(); + } + + stopEvent(event) { + if (event.target.type === 'textarea' || !event.target.type) { + return true; + } + + return ( + this.context.pmViews[this.node.attrs.id] !== undefined && + event.target !== undefined && + this.context.pmViews[this.node.attrs.id].dom.contains(event.target) + ); + } +} diff --git a/wax-questions-service/src/EssayService/EssayService.js b/wax-questions-service/src/EssayService/EssayService.js index 583ce1dd0..0782fb9dd 100644 --- a/wax-questions-service/src/EssayService/EssayService.js +++ b/wax-questions-service/src/EssayService/EssayService.js @@ -1,5 +1,6 @@ import { Service } from 'wax-prosemirror-core'; import EssayQuestion from './EssayQuestion'; +import EssayQuestionContainerComponent from './components/EssayQuestionContainerComponent'; import essayContainerNode from './schema/essayContainerNode'; import essayPromptNode from './schema/essayPromptNode'; import essayQuestionNode from './schema/essayQuestionNode'; @@ -7,6 +8,7 @@ import essayAnswerNode from './schema/essayAnswerNode'; import EssayQuestionComponent from './components/EssayQuestionComponent'; import EssayPromptComponent from './components/EssayPromptComponent'; import EssayAnswerComponent from './components/EssayAnswerComponent'; +import EssayQuestionContainerNodeView from './EssayQuestionContainerNodeView'; import EssayQuestionNodeView from './EssayQuestionNodeView'; import EssayPromptNodeView from './EssayPromptNodeView'; import EssayAnswerNodeView from './EssayAnswerNodeView'; @@ -34,6 +36,12 @@ class EssayService extends Service { essay_answer: essayAnswerNode, }); + addPortal({ + nodeView: EssayQuestionContainerNodeView, + component: EssayQuestionContainerComponent, + context: this.app, + }); + addPortal({ nodeView: EssayQuestionNodeView, component: EssayQuestionComponent, diff --git a/wax-questions-service/src/EssayService/components/EssayQuestionContainerComponent.js b/wax-questions-service/src/EssayService/components/EssayQuestionContainerComponent.js new file mode 100644 index 000000000..7f8b8b5e5 --- /dev/null +++ b/wax-questions-service/src/EssayService/components/EssayQuestionContainerComponent.js @@ -0,0 +1,85 @@ +import React, { useContext, useRef, useState } from 'react'; +import { + WaxContext, + ComponentPlugin, + DocumentHelpers, + Icon, +} from 'wax-prosemirror-core'; +import { th } from '@pubsweet/ui-toolkit'; + +import styled from 'styled-components'; +import ContainerEditor from './ContainerEditor'; + +const EssayQuestionWrapper = styled.div` + margin: 0px 38px 15px 38px; + margin-top: 10px; +`; +const EssayQuestionContainerTool = styled.div` + border: 3px solid #f5f5f7; + border-bottom: none; + + span:first-of-type { + position: relative; + top: 3px; + } +`; + +const ActionButton = styled.button` + background: transparent; + cursor: pointer; + margin-top: 16px; + border: none; + position: relative; + bottom: 14px; + left: -11px; + float: right; +`; + +const StyledIconActionRemove = styled(Icon)` + height: 24px; + width: 24px; +`; + +const EssayQuestionContainer = styled.div` + border: 3px solid #f5f5f7; + margin-bottom: 30px; +`; + +export default ({ node, view, getPos }) => { + const context = useContext(WaxContext); + const { + pmViews: { main }, + } = context; + + const customProps = main.props.customValues; + const { testMode } = customProps; + + const isEditable = main.props.editable(editable => { + return editable; + }); + + const readOnly = !isEditable; + + const removeQuestion = () => {}; + + return ( + <EssayQuestionWrapper> + <div> + {!testMode && !readOnly && ( + <EssayQuestionContainerTool> + <ActionButton + aria-label="delete this question" + onClick={removeQuestion} + type="button" + > + <StyledIconActionRemove name="deleteOutlinedQuestion" /> + </ActionButton> + </EssayQuestionContainerTool> + )} + </div> + <EssayQuestionContainer className="essay-question"> + <ContainerEditor getPos={getPos} node={node} view={view} /> + </EssayQuestionContainer> + </EssayQuestionWrapper> + ); +}; diff --git a/wax-questions-service/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js b/wax-questions-service/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js index 0320b05d6..79ec1fcf8 100644 --- a/wax-questions-service/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js +++ b/wax-questions-service/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js @@ -119,7 +119,6 @@ export default ({ node, view, getPos }) => { return ( <FillTheGapWrapper> <div> - {/* <span> Fill The Gap</span> */} {!testMode && !readOnly && ( <FillTheGapContainerTool> <FillTheGapTool /> -- GitLab