MDL-66365 mod_forum: Add a modal to show a selected post in context
authorMathew May <mathewm@hotmail.co.nz>
Fri, 27 Sep 2019 02:39:02 +0000 (10:39 +0800)
committerMathew May <mathewm@hotmail.co.nz>
Wed, 30 Oct 2019 02:23:41 +0000 (10:23 +0800)
Part of MDL-66074

14 files changed:
mod/forum/amd/build/grades/expandconversation.min.js [new file with mode: 0644]
mod/forum/amd/build/grades/expandconversation.min.js.map [new file with mode: 0644]
mod/forum/amd/build/grades/grader/selectors.min.js
mod/forum/amd/build/grades/grader/selectors.min.js.map
mod/forum/amd/build/repository.min.js
mod/forum/amd/build/repository.min.js.map
mod/forum/amd/src/grades/expandconversation.js [new file with mode: 0644]
mod/forum/amd/src/grades/grader/selectors.js
mod/forum/amd/src/repository.js
mod/forum/db/services.php
mod/forum/externallib.php
mod/forum/templates/grades/grader/discussion/post_modal.mustache [new file with mode: 0644]
mod/forum/templates/grades/grader/discussion/posts.mustache
mod/forum/version.php

diff --git a/mod/forum/amd/build/grades/expandconversation.min.js b/mod/forum/amd/build/grades/expandconversation.min.js
new file mode 100644 (file)
index 0000000..2e6fe41
Binary files /dev/null and b/mod/forum/amd/build/grades/expandconversation.min.js differ
diff --git a/mod/forum/amd/build/grades/expandconversation.min.js.map b/mod/forum/amd/build/grades/expandconversation.min.js.map
new file mode 100644 (file)
index 0000000..6006f1a
Binary files /dev/null and b/mod/forum/amd/build/grades/expandconversation.min.js.map differ
index 0dd37e9..791d1c9 100644 (file)
Binary files a/mod/forum/amd/build/grades/grader/selectors.min.js and b/mod/forum/amd/build/grades/grader/selectors.min.js differ
index 9e75125..ec64fb3 100644 (file)
Binary files a/mod/forum/amd/build/grades/grader/selectors.min.js.map and b/mod/forum/amd/build/grades/grader/selectors.min.js.map differ
index 4518127..cea397e 100644 (file)
Binary files a/mod/forum/amd/build/repository.min.js and b/mod/forum/amd/build/repository.min.js differ
index 299b2ef..4fe16e3 100644 (file)
Binary files a/mod/forum/amd/build/repository.min.js.map and b/mod/forum/amd/build/repository.min.js.map differ
diff --git a/mod/forum/amd/src/grades/expandconversation.js b/mod/forum/amd/src/grades/expandconversation.js
new file mode 100644 (file)
index 0000000..c6cbcc5
--- /dev/null
@@ -0,0 +1,102 @@
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This module will tie together all of the different calls the gradable module will make.
+ *
+ * @module     mod_forum/grades/expandconversation
+ * @package    mod_forum
+ * @copyright  2019 Mathew May <mathew.solutions>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+import * as ForumSelectors from './grader/selectors';
+import Repository from 'mod_forum/repository';
+import {exception as showException} from "core/notification";
+import Templates from 'core/templates';
+import * as Modal from 'core/modal_factory';
+import * as ModalEvents from 'core/modal_events';
+
+/**
+ * Find the Node containing the gradable details from the provided node by searching up the tree.
+ *
+ * @param {HTMLElement} node
+ * @returns {HTMLElement}
+ */
+const findGradableNode = node => node.closest(ForumSelectors.expandConversation);
+
+/**
+ * Show the post in context in a modal.
+ *
+ * @param {HTMLElement} rootNode The button thas clicked
+ */
+const showPostInContext = async rootNode => {
+    const postId = rootNode.dataset.postid;
+    const discussionId = rootNode.dataset.discussionid;
+    const discussionName = rootNode.dataset.name;
+
+    const [
+        allPosts,
+        modal,
+    ] = await Promise.all([
+        Repository.getDiscussionPosts(parseInt(discussionId)),
+        Modal.create({
+            title: discussionName,
+            large: true,
+            type: Modal.types.CANCEL
+        }),
+    ]);
+
+    // Handle hidden event.
+    modal.getRoot().on(ModalEvents.hidden, function() {
+        // Destroy when hidden.
+        modal.destroy();
+    });
+
+    modal.show();
+
+    // Note: We do not use await here because it messes with the Modal transitions.
+    const templatePromise = Templates.render('mod_forum/grades/grader/discussion/post_modal', allPosts);
+    modal.setBody(templatePromise);
+    // eslint-disable-next-line promise/catch-or-return
+    templatePromise.then(() => {
+        const relevantPost = modal.getRoot()[0].querySelector(`#p${postId}`);
+        if (relevantPost) {
+            relevantPost.scrollIntoView({behavior: "smooth"});
+        }
+
+        return;
+    });
+};
+
+/**
+ * Register event listeners for the expand conversations button.
+ *
+ * @param {HTMLElement} rootNode The root to listen to.
+ */
+export const registerEventListeners = rootNode => {
+    rootNode.addEventListener('click', e => {
+        const rootNode = findGradableNode(e.target);
+
+        if (rootNode) {
+            e.preventDefault();
+
+            try {
+                showPostInContext(rootNode);
+            } catch (err) {
+                showException(err);
+            }
+        }
+    });
+};
index 5a4ed49..65e87d2 100644 (file)
@@ -27,4 +27,6 @@ export default {
     gradableItems: {
         wholeForum: '[data-gradable-itemtype="forum"]',
     },
+    expandConversation: '[data-action="view-context"]',
+    posts: '[data-region="posts"]',
 };
index 5cb8cd0..fceeef7 100644 (file)
@@ -134,12 +134,29 @@ define(['core/ajax'], function(Ajax) {
         return Ajax.call([request])[0];
     };
 
+    /**
+     * Get the posts for the discussion ID provided.
+     *
+     * @param {number} discussionId
+     * @return {*|Promise}
+     */
+    var getDiscussionPosts = function(discussionId) {
+        var request = {
+            methodname: 'mod_forum_get_discussion_posts',
+            args: {
+                discussionid: discussionId,
+            },
+        };
+        return Ajax.call([request])[0];
+    };
+
     return {
         setDiscussionSubscriptionState: setDiscussionSubscriptionState,
         addDiscussionPost: addDiscussionPost,
         setDiscussionLockState: setDiscussionLockState,
         setFavouriteDiscussionState: setFavouriteDiscussionState,
         setPinDiscussionState: setPinDiscussionState,
-        getDiscussionByUserID: getDiscussionByUserID
+        getDiscussionByUserID: getDiscussionByUserID,
+        getDiscussionPosts: getDiscussionPosts,
     };
 });
index 78c4e9f..fba90c7 100644 (file)
@@ -43,6 +43,7 @@ $functions = array(
         'classpath' => 'mod/forum/externallib.php',
         'description' => 'Returns a list of forum posts for a discussion.',
         'type' => 'read',
+        'ajax' => true,
         'capabilities' => 'mod/forum:viewdiscussion, mod/forum:viewqandawithoutposting',
         'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
     ),
index b692db4..47f5bc3 100644 (file)
@@ -188,6 +188,8 @@ class mod_forum_external extends external_api {
 
         $forumvault = $vaultfactory->get_forum_vault();
         $forum = $forumvault->get_from_id($discussion->get_forum_id());
+        $context = $forum->get_context();
+        self::validate_context($context);
 
         $sortby = $params['sortby'];
         $sortdirection = $params['sortdirection'];
diff --git a/mod/forum/templates/grades/grader/discussion/post_modal.mustache b/mod/forum/templates/grades/grader/discussion/post_modal.mustache
new file mode 100644 (file)
index 0000000..ab2b4ff
--- /dev/null
@@ -0,0 +1,36 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template mod_forum/forum_discussion_post_modal
+
+    Template to render a single post from a discussion.
+
+    Classes required for JS:
+    * none
+
+    Data attributes required for JS:
+    * none
+
+    Example context (json):
+    {
+    }
+}}
+<div data-region="posts-modal">
+    {{#posts}}
+        {{> mod_forum/forum_discussion_modern_post_reply }}
+    {{/posts}}
+</div>
index 3fd5d9d..05f9d39 100644 (file)
@@ -29,7 +29,7 @@
     {
     }
 }}
-<div data-region="posts">
+<div data-region="posts" id="post-region-{{uniqid}}">
     {{#discussions}}
         <div class="hr-sect mt-0">{{name}}</div>
         {{#posts}}
@@ -66,7 +66,6 @@
                     </div>
                 </div>
             {{/starter}}
-
             <hr>
         {{/posts}}
     {{/discussions}}
@@ -76,6 +75,6 @@
 </div>
 {{#js}}
     require(['mod_forum/grades/expandconversation'], function(Conversation) {
-    Conversation.registerEventListeners();
+        Conversation.registerEventListeners(document.querySelector('#post-region-{{uniqid}}'));
     });
 {{/js}}
index ed070d4..e8b21ff 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2019100104;       // The current module version (Date: YYYYMMDDXX)
+$plugin->version   = 2019100105;       // The current module version (Date: YYYYMMDDXX)
 $plugin->requires  = 2019051100;       // Requires this Moodle version
 $plugin->component = 'mod_forum';      // Full name of the plugin (used for diagnostics)