From dbd8892d802a8125186b61accf9c15b74816cf74 Mon Sep 17 00:00:00 2001
From: chris <kokosias@yahoo.gr>
Date: Thu, 3 Mar 2022 16:12:15 +0200
Subject: [PATCH] new nodeView files

---
 .../FillTheGapContainerNodeView.js            |  3 +
 .../components/ContainerEditor.js             | 12 ---
 .../components/FeedbackComponent.js           | 75 +++++++++++++++++++
 .../FillTheGapContainerComponent.js           | 14 +++-
 .../MultipleChoiceContainerNodeView.js        | 55 ++++++++++++++
 .../MultipleChoiceQuestionService.js          |  7 ++
 ...pleChoiceSingleCorrectContainerNodeView.js | 55 ++++++++++++++
 ...tipleChoiceSingleCorrectQuestionService.js | 11 ++-
 .../TrueFalseContainerNodeView.js             | 55 ++++++++++++++
 .../TrueFalseQuestionService.js               |  7 ++
 ...TrueFalseSingleCorrectContainerNodeView.js | 55 ++++++++++++++
 .../TrueFalseSingleCorrectQuestionService.js  | 13 +++-
 12 files changed, 342 insertions(+), 20 deletions(-)
 create mode 100644 wax-prosemirror-services/src/FillTheGapQuestionService/components/FeedbackComponent.js
 create mode 100644 wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceContainerNodeView.js
 create mode 100644 wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectContainerNodeView.js
 create mode 100644 wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseContainerNodeView.js
 create mode 100644 wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectContainerNodeView.js

diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js b/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js
index dec3f753b..8fee80cf8 100644
--- a/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js
+++ b/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js
@@ -50,6 +50,9 @@ export default class FillTheGapContainerNodeView extends AbstractNodeView {
   }
 
   stopEvent(event) {
+    if (event.target.type === 'text') {
+      return true;
+    }
     return (
       this.context.view[this.node.attrs.id] !== undefined &&
       event.target !== undefined &&
diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js
index 29cbe00d8..b25b24aa2 100644
--- a/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js
+++ b/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js
@@ -13,18 +13,6 @@ import { WaxContext } from 'wax-prosemirror-core';
 
 const EditorWrapper = styled.span`
   > .ProseMirror {
-    // background: #a6a6a6 !important;
-    // border: 1px solid #a6a6a6;
-    // border-radius: 4px;
-    // box-shadow: none;
-    // color: #fff !important;
-    // display: inline;
-    // min-width: 50px;
-    // padding: 0px 2px 0px 2px !important;
-    // white-space: break-spaces;
-    // width: auto;
-    // word-wrap: break-word;
-
     &:focus {
       outline: none;
     }
diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/FeedbackComponent.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/FeedbackComponent.js
new file mode 100644
index 000000000..1c34fe93f
--- /dev/null
+++ b/wax-prosemirror-services/src/FillTheGapQuestionService/components/FeedbackComponent.js
@@ -0,0 +1,75 @@
+/* eslint-disable react/destructuring-assignment */
+/* eslint-disable react/prop-types */
+
+import React, { useContext, useRef, useState, useEffect } from 'react';
+import styled from 'styled-components';
+import { TextSelection } from 'prosemirror-state';
+import { WaxContext } from 'wax-prosemirror-core';
+import { DocumentHelpers } from 'wax-prosemirror-utilities';
+
+const FeedBack = styled.div`
+  color: black;
+  margin-top: 10px;
+`;
+
+const FeedBackLabel = styled.span`
+  font-weight: 700;
+`;
+
+const FeedBackInput = styled.input`
+  //   border: none;
+  display: flex;
+  width: 100%;
+`;
+
+export default ({ node, view, getPos }) => {
+  const context = useContext(WaxContext);
+  const [feedBack, setFeedBack] = useState(' ');
+  const [typing, setTyping] = useState(false);
+  const feedBackRef = useRef(null);
+
+  useEffect(() => {}, []);
+
+  const handleKeyDown = e => {
+    setTyping(true);
+    if (e.key === 'Backspace') {
+      context.view.main.dispatch(
+        context.view.main.state.tr.setSelection(
+          TextSelection.create(context.view.main.state.tr.doc, null),
+        ),
+      );
+    }
+  };
+
+  const feedBackInput = () => {
+    setFeedBack(feedBackRef.current.value);
+  };
+
+  const saveFeedBack = () => {
+    return false;
+  };
+
+  const onFocus = () => {
+    context.view.main.dispatch(
+      context.view.main.state.tr.setSelection(
+        TextSelection.create(context.view.main.state.tr.doc, null),
+      ),
+    );
+  };
+
+  return (
+    <FeedBack>
+      <FeedBackLabel>Feedback</FeedBackLabel>
+      <FeedBackInput
+        onBlur={saveFeedBack}
+        onChange={feedBackInput}
+        onFocus={onFocus}
+        onKeyDown={handleKeyDown}
+        placeholder="Insert feedback"
+        ref={feedBackRef}
+        type="text"
+        value={feedBack}
+      />
+    </FeedBack>
+  );
+};
diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js
index a776e8370..742e1fe26 100644
--- a/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js
+++ b/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js
@@ -1,12 +1,20 @@
 /* eslint-disable react/prop-types */
 import React from 'react';
+import styled from 'styled-components';
 import ContainerEditor from './ContainerEditor';
+import FeedbackComponent from './FeedbackComponent';
+
+const FillTheGapContainer = styled.div`
+  margin-bottom: 15px;
+  margin-top: 10px;
+`;
 
 export default ({ node, view, getPos }) => {
   return (
-    <>
+    <FillTheGapContainer>
+      <span>Fill The Gap</span>
       <ContainerEditor getPos={getPos} node={node} view={view} />
-      <div>feedback</div>
-    </>
+      <FeedbackComponent getPos={getPos} node={node} view={view} />
+    </FillTheGapContainer>
   );
 };
diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceContainerNodeView.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceContainerNodeView.js
new file mode 100644
index 000000000..c00da4041
--- /dev/null
+++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceContainerNodeView.js
@@ -0,0 +1,55 @@
+import AbstractNodeView from '../PortalService/AbstractNodeView';
+
+export default class MultipleChoiceContainerNodeView extends AbstractNodeView {
+  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 'multiple_choice_container';
+  }
+
+  update(node) {
+    this.node = node;
+    if (this.context.view[node.attrs.id]) {
+      const { state } = this.context.view[node.attrs.id];
+      const start = node.content.findDiffStart(state.doc.content);
+      if (start != null) {
+        let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content);
+        const overlap = start - Math.min(endA, endB);
+        if (overlap > 0) {
+          endA += overlap;
+          endB += overlap;
+        }
+        this.context.view[node.attrs.id].dispatch(
+          state.tr
+            .replace(start, endB, node.slice(start, endA))
+            .setMeta('fromOutside', true),
+        );
+      }
+    }
+
+    return true;
+  }
+
+  stopEvent(event) {
+    if (event.target.type === 'text') {
+      return true;
+    }
+    const innerView = this.context.view[this.node.attrs.id];
+    return innerView && innerView.dom.contains(event.target);
+  }
+}
diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestionService.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestionService.js
index 5227d4446..c2a28b8c6 100644
--- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestionService.js
+++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestionService.js
@@ -5,6 +5,7 @@ import multipleChoiceContainerNode from './schema/multipleChoiceContainerNode';
 import questionNode from './schema/questionNode';
 import AnswerComponent from './components/AnswerComponent';
 import QuestionComponent from './components/QuestionComponent';
+import MultipleChoiceContainerNodeView from './MultipleChoiceContainerNodeView';
 import MultipleChoiceNodeView from './MultipleChoiceNodeView';
 import QuestionNodeView from './QuestionNodeView';
 import MultipleChoiceSingleCorrectQuestionService from './MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestionService';
@@ -30,6 +31,12 @@ class MultipleChoiceQuestionService extends Service {
       question_node_multiple: questionNode,
     });
 
+    // addPortal({
+    //   nodeView: MultipleChoiceContainerNodeView,
+    //   component: QuestionComponent,
+    //   context: this.app,
+    // });
+
     addPortal({
       nodeView: QuestionNodeView,
       component: QuestionComponent,
diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectContainerNodeView.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectContainerNodeView.js
new file mode 100644
index 000000000..1e0db8862
--- /dev/null
+++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectContainerNodeView.js
@@ -0,0 +1,55 @@
+import AbstractNodeView from '../../PortalService/AbstractNodeView';
+
+export default class MultipleChoiceSingleCorrectContainerNodeView extends AbstractNodeView {
+  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 'multiple_choice_container';
+  }
+
+  update(node) {
+    this.node = node;
+    if (this.context.view[node.attrs.id]) {
+      const { state } = this.context.view[node.attrs.id];
+      const start = node.content.findDiffStart(state.doc.content);
+      if (start != null) {
+        let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content);
+        const overlap = start - Math.min(endA, endB);
+        if (overlap > 0) {
+          endA += overlap;
+          endB += overlap;
+        }
+        this.context.view[node.attrs.id].dispatch(
+          state.tr
+            .replace(start, endB, node.slice(start, endA))
+            .setMeta('fromOutside', true),
+        );
+      }
+    }
+
+    return true;
+  }
+
+  stopEvent(event) {
+    if (event.target.type === 'text') {
+      return true;
+    }
+    const innerView = this.context.view[this.node.attrs.id];
+    return innerView && innerView.dom.contains(event.target);
+  }
+}
diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestionService.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestionService.js
index 48e7ac31b..9f1901ab6 100644
--- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestionService.js
+++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestionService.js
@@ -4,6 +4,7 @@ import multipleChoiceSingleCorrectNode from './schema/multipleChoiceSingleCorrec
 import multipleChoiceSingleCorrectContainerNode from './schema/multipleChoiceSingleCorrectContainerNode';
 import questionSingleNode from './schema/questionSingleNode';
 import AnswerComponent from './components/AnswerComponent';
+import MultipleChoiceSingleCorrectContainerNodeView from './MultipleChoiceSingleCorrectContainerNodeView';
 import MultipleChoiceSingleCorrectNodeView from './MultipleChoiceSingleCorrectNodeView';
 import QuestionMultipleSingleNodeView from './QuestionMultipleSingleNodeView';
 import QuestionComponent from '../components/QuestionComponent';
@@ -17,17 +18,23 @@ class MultipleChoiceSingleCorrectQuestionService extends Service {
     const addPortal = this.container.get('AddPortal');
 
     createNode({
-      multiple_choice_single_correct: multipleChoiceSingleCorrectNode,
+      multiple_choice_single_correct_container: multipleChoiceSingleCorrectContainerNode,
     });
 
     createNode({
-      multiple_choice_single_correct_container: multipleChoiceSingleCorrectContainerNode,
+      multiple_choice_single_correct: multipleChoiceSingleCorrectNode,
     });
 
     createNode({
       question_node_multiple_single: questionSingleNode,
     });
 
+    // addPortal({
+    //   nodeView: MultipleChoiceSingleCorrectContainerNodeView,
+    //   component: QuestionComponent,
+    //   context: this.app,
+    // });
+
     addPortal({
       nodeView: QuestionMultipleSingleNodeView,
       component: QuestionComponent,
diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseContainerNodeView.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseContainerNodeView.js
new file mode 100644
index 000000000..f5f145d38
--- /dev/null
+++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseContainerNodeView.js
@@ -0,0 +1,55 @@
+import AbstractNodeView from '../../PortalService/AbstractNodeView';
+
+export default class TrueFalseContainerNodeView extends AbstractNodeView {
+  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 'true_false_container';
+  }
+
+  update(node) {
+    this.node = node;
+    if (this.context.view[node.attrs.id]) {
+      const { state } = this.context.view[node.attrs.id];
+      const start = node.content.findDiffStart(state.doc.content);
+      if (start != null) {
+        let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content);
+        const overlap = start - Math.min(endA, endB);
+        if (overlap > 0) {
+          endA += overlap;
+          endB += overlap;
+        }
+        this.context.view[node.attrs.id].dispatch(
+          state.tr
+            .replace(start, endB, node.slice(start, endA))
+            .setMeta('fromOutside', true),
+        );
+      }
+    }
+
+    return true;
+  }
+
+  stopEvent(event) {
+    if (event.target.type === 'text') {
+      return true;
+    }
+    const innerView = this.context.view[this.node.attrs.id];
+    return innerView && innerView.dom.contains(event.target);
+  }
+}
diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestionService.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestionService.js
index 1ee73119c..91aa037e7 100644
--- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestionService.js
+++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestionService.js
@@ -4,6 +4,7 @@ import trueFalseNode from './schema/trueFalseNode';
 import questionTrueFalseNode from './schema/questionTrueFalseNode';
 import trueFalseContainerNode from './schema/trueFalseContainerNode';
 import AnswerComponent from './components/AnswerComponent';
+import TrueFalseContainerNodeView from './TrueFalseContainerNodeView';
 import TrueFalseNodeView from './TrueFalseNodeView';
 import QuestionTrueFalseNodeView from './QuestionTrueFalseNodeView';
 import QuestionComponent from '../components/QuestionComponent';
@@ -26,6 +27,12 @@ class TrueFalseQuestionService extends Service {
       question_node_true_false: questionTrueFalseNode,
     });
 
+    //  addPortal({
+    //    nodeView: TrueFalseContainerNodeView,
+    //    component: QuestionComponent,
+    //    context: this.app,
+    //  });
+
     addPortal({
       nodeView: QuestionTrueFalseNodeView,
       component: QuestionComponent,
diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectContainerNodeView.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectContainerNodeView.js
new file mode 100644
index 000000000..d8a8ed1c1
--- /dev/null
+++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectContainerNodeView.js
@@ -0,0 +1,55 @@
+import AbstractNodeView from '../../PortalService/AbstractNodeView';
+
+export default class TrueFalseSingleCorrectContainerNodeView extends AbstractNodeView {
+  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 'true_false_single_correct_container';
+  }
+
+  update(node) {
+    this.node = node;
+    if (this.context.view[node.attrs.id]) {
+      const { state } = this.context.view[node.attrs.id];
+      const start = node.content.findDiffStart(state.doc.content);
+      if (start != null) {
+        let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content);
+        const overlap = start - Math.min(endA, endB);
+        if (overlap > 0) {
+          endA += overlap;
+          endB += overlap;
+        }
+        this.context.view[node.attrs.id].dispatch(
+          state.tr
+            .replace(start, endB, node.slice(start, endA))
+            .setMeta('fromOutside', true),
+        );
+      }
+    }
+
+    return true;
+  }
+
+  stopEvent(event) {
+    if (event.target.type === 'text') {
+      return true;
+    }
+    const innerView = this.context.view[this.node.attrs.id];
+    return innerView && innerView.dom.contains(event.target);
+  }
+}
diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestionService.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestionService.js
index 27d171056..4f38a73f3 100644
--- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestionService.js
+++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestionService.js
@@ -4,6 +4,7 @@ import trueFalseSingleCorrectNode from './schema/trueFalseSingleCorrectNode';
 import trueFalseSingleCorrectContainerNode from './schema/trueFalseSingleCorrectContainerNode';
 import questionTrueFalseSingleNode from './schema/questionTrueFalseSingleNode';
 import AnswerComponent from './components/AnswerComponent';
+import TrueFalseSingleCorrectContainerNodeView from './TrueFalseSingleCorrectContainerNodeView';
 import TrueFalseSingleCorrectNodeView from './TrueFalseSingleCorrectNodeView';
 import QuestionTrueFalseSingleNodeView from './QuestionTrueFalseSingleNodeView';
 import QuestionComponent from '../components/QuestionComponent';
@@ -17,17 +18,23 @@ class TrueFalseSingleCorrectQuestionService extends Service {
     const addPortal = this.container.get('AddPortal');
 
     createNode({
-      true_false_single_correct: trueFalseSingleCorrectNode,
+      true_false_single_correct_container: trueFalseSingleCorrectContainerNode,
     });
 
     createNode({
-      true_false_single_correct_container: trueFalseSingleCorrectContainerNode,
+      question_node_true_false_single: questionTrueFalseSingleNode,
     });
 
     createNode({
-      question_node_true_false_single: questionTrueFalseSingleNode,
+      true_false_single_correct: trueFalseSingleCorrectNode,
     });
 
+    // addPortal({
+    //   nodeView: TrueFalseSingleCorrectContainerNodeView,
+    //   component: QuestionComponent,
+    //   context: this.app,
+    // });
+
     addPortal({
       nodeView: QuestionTrueFalseSingleNodeView,
       component: QuestionComponent,
-- 
GitLab