MDL-66893 mod_forum: update user content region in grader UI
authorRyan Wyllie <ryan@ryanwyllie.com>
Tue, 5 Nov 2019 05:29:36 +0000 (13:29 +0800)
committerRyan Wyllie <ryan@ryanwyllie.com>
Thu, 7 Nov 2019 06:53:37 +0000 (14:53 +0800)
15 files changed:
mod/forum/amd/build/grades/grader.min.js
mod/forum/amd/build/grades/grader.min.js.map
mod/forum/amd/src/grades/grader.js
mod/forum/externallib.php
mod/forum/lang/en/forum.php
mod/forum/pix/no-posts.png [new file with mode: 0644]
mod/forum/pix/no-posts.svg [new file with mode: 0644]
mod/forum/templates/forum_discussion_post.mustache
mod/forum/templates/grades/grader/discussion/posts.mustache
mod/forum/templates/local/grades/local/grader/content.mustache
mod/forum/templates/local/grades/local/grader/module_content_placeholder.mustache [new file with mode: 0644]
mod/forum/tests/externallib_test.php
theme/boost/scss/moodle/modules.scss
theme/boost/style/moodle.css
theme/classic/style/moodle.css

index 9cd1d41..7542c8c 100644 (file)
Binary files a/mod/forum/amd/build/grades/grader.min.js and b/mod/forum/amd/build/grades/grader.min.js differ
index eae5dd0..091d8fc 100644 (file)
Binary files a/mod/forum/amd/build/grades/grader.min.js.map and b/mod/forum/amd/build/grades/grader.min.js.map differ
index 78520fc..03236a2 100644 (file)
@@ -82,18 +82,25 @@ const discussionPostMapper = (discussion) => {
     const parentMap = new Map();
     discussion.posts.parentposts.forEach(post => parentMap.set(post.id, post));
     const userPosts = discussion.posts.userposts.map(post => {
-        post.subject = null;
         post.readonly = true;
-        post.starter = !post.parentid;
-        post.parent = parentMap.get(post.parentid);
-        post.html.rating = null;
+        post.hasreplies = false;
+        post.replies = [];
+
+        const parent = post.parentid ? parentMap.get(post.parentid) : null;
+        if (parent) {
+            parent.hasreplies = false;
+            parent.replies = [];
+            parent.readonly = true;
+        }
 
-        return post;
+        return {
+            parent,
+            post
+        };
     });
 
     return {
-        id: discussion.id,
-        name: discussion.name,
+        ...discussion,
         posts: userPosts,
     };
 };
index 1bbe252..b900e55 100644 (file)
@@ -2205,8 +2205,15 @@ class mod_forum_external extends external_api {
         $managerfactory = mod_forum\local\container::get_manager_factory();
         $capabilitymanager = $managerfactory->get_capability_manager($forum);
 
-        $discussionvault = $vaultfactory->get_discussion_vault();
-        $discussions = $discussionvault->get_all_discussions_in_forum($forum, 'timemodified ASC, id ASC');
+        $discussionsummariesvault = $vaultfactory->get_discussions_in_forum_vault();
+        $discussionsummaries = $discussionsummariesvault->get_from_forum_id(
+            $forum->get_id(),
+            true,
+            null,
+            $discussionsummariesvault::SORTORDER_CREATED_ASC,
+            0,
+            0
+        );
 
         $postvault = $vaultfactory->get_post_vault();
 
@@ -2214,7 +2221,8 @@ class mod_forum_external extends external_api {
         $postbuilder = $builderfactory->get_exported_posts_builder();
 
         $builtdiscussions = [];
-        foreach ($discussions as $id => $discussion) {
+        foreach ($discussionsummaries as $discussionsummary) {
+            $discussion = $discussionsummary->get_discussion();
             $posts = $postvault->get_posts_in_discussion_for_user_id(
                     $discussion->get_id(),
                     $user->id,
@@ -2239,9 +2247,14 @@ class mod_forum_external extends external_api {
                 );
             }
 
+            $discussionauthor = $discussionsummary->get_first_post_author();
+            $firstpost = $discussionsummary->get_first_post();
+
             $builtdiscussions[] = [
                 'name' => $discussion->get_name(),
                 'id' => $discussion->get_id(),
+                'timecreated' => $firstpost->get_time_created(),
+                'authorfullname' => $discussionauthor->get_full_name(),
                 'posts' => [
                     'userposts' => $postbuilder->build($user, [$forum], [$discussion], $posts),
                     'parentposts' => $parentposts,
@@ -2284,6 +2297,8 @@ class mod_forum_external extends external_api {
                     new external_single_structure([
                         'name' => new external_value(PARAM_RAW, 'Name of the discussion'),
                         'id' => new external_value(PARAM_INT, 'ID of the discussion'),
+                        'timecreated' => new external_value(PARAM_INT, 'Timestamp of the discussion start'),
+                        'authorfullname' => new external_value(PARAM_RAW, 'Full name of the user that started the discussion'),
                         'posts' => new external_single_structure([
                             'userposts' => new external_multiple_structure(\mod_forum\local\exporters\post::get_read_structure()),
                             'parentposts' => new external_multiple_structure(\mod_forum\local\exporters\post::get_read_structure()),
index f63ad22..f9772cb 100644 (file)
@@ -195,6 +195,7 @@ $string['discussionsubscription'] = 'Discussion subscription';
 $string['discussionsubscription_help'] = 'Subscribing to a discussion means you will receive notifications of new posts to that discussion.';
 $string['discussions'] = 'Discussions';
 $string['discussionsstartedby'] = 'Discussions started by {$a}';
+$string['discussionstartedby'] = 'Discussion started by {$a}';
 $string['discussionsstartedbyrecent'] = 'Discussions recently started by {$a}';
 $string['discussionsstartedbyuserincourse'] = 'Discussions started by {$a->fullname} in {$a->coursename}';
 $string['discussionunpin'] = 'Unpin';
@@ -710,6 +711,7 @@ $string['useexperimentalui'] = 'Use experimental nested discussion view';
 $string['usermarksread'] = 'Manual message read marking';
 $string['unpindiscussion'] = 'Unpin this discussion';
 $string['viewalldiscussions'] = 'View all discussions';
+$string['viewparentpost'] = 'View parent post';
 $string['viewthediscussion'] = 'View the discussion';
 $string['warnafter'] = 'Post threshold for warning';
 $string['warnafter_help'] = 'Students can be warned as they approach the maximum number of posts allowed in a given period. This setting specifies after how many posts they are warned. Users with the capability mod/forum:postwithoutthrottling are exempt from post limits.';
diff --git a/mod/forum/pix/no-posts.png b/mod/forum/pix/no-posts.png
new file mode 100644 (file)
index 0000000..1441259
Binary files /dev/null and b/mod/forum/pix/no-posts.png differ
diff --git a/mod/forum/pix/no-posts.svg b/mod/forum/pix/no-posts.svg
new file mode 100644 (file)
index 0000000..a5de6b5
--- /dev/null
@@ -0,0 +1 @@
+<svg id="f20e0c25-d928-42cc-98d1-13cc230663ea" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="820.16" height="780.81" viewBox="0 0 820.16 780.81"><defs><linearGradient id="07332201-7176-49c2-9908-6dc4a39c4716" x1="539.63" y1="734.6" x2="539.63" y2="151.19" gradientTransform="translate(-3.62 1.57)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="gray" stop-opacity="0.25"/><stop offset="0.54" stop-color="gray" stop-opacity="0.12"/><stop offset="1" stop-color="gray" stop-opacity="0.1"/></linearGradient><linearGradient id="0ee1ab3f-7ba2-4205-9d4a-9606ad702253" x1="540.17" y1="180.2" x2="540.17" y2="130.75" gradientTransform="translate(-63.92 7.85)" xlink:href="#07332201-7176-49c2-9908-6dc4a39c4716"/><linearGradient id="abca9755-bed1-4a97-b027-7f02ee3ffa09" x1="540.17" y1="140.86" x2="540.17" y2="82.43" gradientTransform="translate(-84.51 124.6) rotate(-12.11)" xlink:href="#07332201-7176-49c2-9908-6dc4a39c4716"/><linearGradient id="2632d424-e666-4ee4-9508-a494957e14ab" x1="476.4" y1="710.53" x2="476.4" y2="127.12" gradientTransform="matrix(1, 0, 0, 1, 0, 0)" xlink:href="#07332201-7176-49c2-9908-6dc4a39c4716"/><linearGradient id="97571ef7-1c83-4e06-b701-c2e47e77dca3" x1="476.94" y1="156.13" x2="476.94" y2="106.68" gradientTransform="matrix(1, 0, 0, 1, 0, 0)" xlink:href="#07332201-7176-49c2-9908-6dc4a39c4716"/><linearGradient id="7d32e13e-a0c7-49c4-af0e-066a2f8cb76e" x1="666.86" y1="176.39" x2="666.86" y2="117.95" gradientTransform="matrix(1, 0, 0, 1, 0, 0)" xlink:href="#07332201-7176-49c2-9908-6dc4a39c4716"/></defs><title>no data</title><rect x="317.5" y="142.55" width="437.02" height="603.82" transform="translate(-271.22 62.72) rotate(-12.11)" fill="#e0e0e0"/><g opacity="0.5"><rect x="324.89" y="152.76" width="422.25" height="583.41" transform="translate(-271.22 62.72) rotate(-12.11)" fill="url(#07332201-7176-49c2-9908-6dc4a39c4716)"/></g><rect x="329.81" y="157.1" width="411.5" height="570.52" transform="translate(-270.79 62.58) rotate(-12.11)" fill="#fafafa"/><rect x="374.18" y="138.6" width="204.14" height="49.45" transform="translate(-213.58 43.93) rotate(-12.11)" fill="url(#0ee1ab3f-7ba2-4205-9d4a-9606ad702253)"/><path d="M460.93,91.9c-15.41,3.31-25.16,18.78-21.77,34.55s18.62,25.89,34,22.58,25.16-18.78,21.77-34.55S476.34,88.59,460.93,91.9ZM470.6,137A16.86,16.86,0,1,1,483.16,117,16.66,16.66,0,0,1,470.6,137Z" transform="translate(-189.92 -59.59)" fill="url(#abca9755-bed1-4a97-b027-7f02ee3ffa09)"/><rect x="375.66" y="136.55" width="199.84" height="47.27" transform="translate(-212.94 43.72) rotate(-12.11)" fill="#e9ecef"/><path d="M460.93,91.9a27.93,27.93,0,1,0,33.17,21.45A27.93,27.93,0,0,0,460.93,91.9ZM470.17,135a16.12,16.12,0,1,1,12.38-19.14A16.12,16.12,0,0,1,470.17,135Z" transform="translate(-189.92 -59.59)" fill="#e9ecef"/><rect x="257.89" y="116.91" width="437.02" height="603.82" fill="#e0e0e0"/><g opacity="0.5"><rect x="265.28" y="127.12" width="422.25" height="583.41" fill="url(#2632d424-e666-4ee4-9508-a494957e14ab)"/></g><rect x="270.65" y="131.42" width="411.5" height="570.52" fill="#fff"/><rect x="374.87" y="106.68" width="204.14" height="49.45" fill="url(#97571ef7-1c83-4e06-b701-c2e47e77dca3)"/><path d="M666.86,118c-15.76,0-28.54,13.08-28.54,29.22s12.78,29.22,28.54,29.22,28.54-13.08,28.54-29.22S682.62,118,666.86,118Zm0,46.08a16.86,16.86,0,1,1,16.46-16.86A16.66,16.66,0,0,1,666.86,164Z" transform="translate(-189.92 -59.59)" fill="url(#7d32e13e-a0c7-49c4-af0e-066a2f8cb76e)"/><rect x="377.02" y="104.56" width="199.84" height="47.27" fill="#e9ecef"/><path d="M666.86,118a27.93,27.93,0,1,0,27.93,27.93A27.93,27.93,0,0,0,666.86,118Zm0,44.05A16.12,16.12,0,1,1,683,145.89,16.12,16.12,0,0,1,666.86,162Z" transform="translate(-189.92 -59.59)" fill="#e9ecef"/><g opacity="0.5"><rect x="15.27" y="737.05" width="3.76" height="21.33" fill="#47e6b1"/><rect x="205.19" y="796.65" width="3.76" height="21.33" transform="translate(824.47 540.65) rotate(90)" fill="#47e6b1"/></g><g opacity="0.5"><rect x="451.49" width="3.76" height="21.33" fill="#47e6b1"/><rect x="641.4" y="59.59" width="3.76" height="21.33" transform="translate(523.63 -632.62) rotate(90)" fill="#47e6b1"/></g><path d="M961,832.15a4.61,4.61,0,0,1-2.57-5.57,2.22,2.22,0,0,0,.1-.51h0a2.31,2.31,0,0,0-4.15-1.53h0a2.22,2.22,0,0,0-.26.45,4.61,4.61,0,0,1-5.57,2.57,2.22,2.22,0,0,0-.51-.1h0a2.31,2.31,0,0,0-1.53,4.15h0a2.22,2.22,0,0,0,.45.26,4.61,4.61,0,0,1,2.57,5.57,2.22,2.22,0,0,0-.1.51h0a2.31,2.31,0,0,0,4.15,1.53h0a2.22,2.22,0,0,0,.26-.45,4.61,4.61,0,0,1,5.57-2.57,2.22,2.22,0,0,0,.51.1h0a2.31,2.31,0,0,0,1.53-4.15h0A2.22,2.22,0,0,0,961,832.15Z" transform="translate(-189.92 -59.59)" fill="#4d8af0" opacity="0.5"/><path d="M326.59,627.09a4.61,4.61,0,0,1-2.57-5.57,2.22,2.22,0,0,0,.1-.51h0a2.31,2.31,0,0,0-4.15-1.53h0a2.22,2.22,0,0,0-.26.45,4.61,4.61,0,0,1-5.57,2.57,2.22,2.22,0,0,0-.51-.1h0a2.31,2.31,0,0,0-1.53,4.15h0a2.22,2.22,0,0,0,.45.26,4.61,4.61,0,0,1,2.57,5.57,2.22,2.22,0,0,0-.1.51h0a2.31,2.31,0,0,0,4.15,1.53h0a2.22,2.22,0,0,0,.26-.45A4.61,4.61,0,0,1,325,631.4a2.22,2.22,0,0,0,.51.1h0a2.31,2.31,0,0,0,1.53-4.15h0A2.22,2.22,0,0,0,326.59,627.09Z" transform="translate(-189.92 -59.59)" fill="#fdd835" opacity="0.5"/><path d="M855,127.77a4.61,4.61,0,0,1-2.57-5.57,2.22,2.22,0,0,0,.1-.51h0a2.31,2.31,0,0,0-4.15-1.53h0a2.22,2.22,0,0,0-.26.45,4.61,4.61,0,0,1-5.57,2.57,2.22,2.22,0,0,0-.51-.1h0a2.31,2.31,0,0,0-1.53,4.15h0a2.22,2.22,0,0,0,.45.26,4.61,4.61,0,0,1,2.57,5.57,2.22,2.22,0,0,0-.1.51h0a2.31,2.31,0,0,0,4.15,1.53h0a2.22,2.22,0,0,0,.26-.45,4.61,4.61,0,0,1,5.57-2.57,2.22,2.22,0,0,0,.51.1h0a2.31,2.31,0,0,0,1.53-4.15h0A2.22,2.22,0,0,0,855,127.77Z" transform="translate(-189.92 -59.59)" fill="#fdd835" opacity="0.5"/><circle cx="812.64" cy="314.47" r="7.53" fill="#f55f44" opacity="0.5"/><circle cx="230.73" cy="746.65" r="7.53" fill="#f55f44" opacity="0.5"/><circle cx="735.31" cy="477.23" r="7.53" fill="#f55f44" opacity="0.5"/><circle cx="87.14" cy="96.35" r="7.53" fill="#4d8af0" opacity="0.5"/><circle cx="7.53" cy="301.76" r="7.53" fill="#47e6b1" opacity="0.5"/></svg>
\ No newline at end of file
index fbc1f6b..1c030de 100644 (file)
                             {{/isimage}}
                         {{/attachments}}
 
-                        <div class="d-flex flex-wrap">
-                            {{#html.rating}}
-                                <div class="mt-2">{{{.}}}</div>
-                            {{/html.rating}}
-                            {{$actions}}
-                                {{^readonly}}
+                        {{^readonly}}
+                            <div class="d-flex flex-wrap">
+                                {{#html.rating}}
+                                    <div class="mt-2">{{{.}}}</div>
+                                {{/html.rating}}
+                                {{$actions}}
                                     <div
                                         class="post-actions d-flex align-self-end justify-content-end flex-wrap ml-auto"
                                         data-region="post-actions-container"
                                             {{/export}}
                                         {{/capabilities}}
                                     </div>
-                                {{/readonly}}
-                            {{/actions}}
-                        </div>
+                                {{/actions}}
+                            </div>
+                        {{/readonly}}
 
                         {{$footer}}{{/footer}}
                     {{/isdeleted}}
index 323e993..d45b6be 100644 (file)
 }}
 <div data-region="posts" id="post-region-{{uniqid}}">
     {{#discussions}}
-        <div class="hr-sect mt-0">{{name}}</div>
-        {{#posts}}
-            {{#parent}}
-                {{> mod_forum/forum_discussion_nested_v2_post_reply }}
-            {{/parent}}
-            {{#starter}}
-                {{> mod_forum/forum_discussion_nested_v2_first_post }}
-                <a class="btn btn-outline-dark"
-                   role="button"
-                   data-action="view-context"
-                   data-discussionid="{{discussionid}}"
-                   data-postid="{{id}}"
-                   data-name="{{name}}"
-                   href="#">
-                    {{#str}} viewconversation, forum {{/str}}
-                </a>
-            {{/starter}}
-            {{^starter}}
-                <div class="forum-post-container" data-region="replies-container">
-                    <div class="indent replies-container" data-region="replies-container">
-                        <div class="indent replies-container" data-region="replies-container">
-                            {{> mod_forum/forum_discussion_nested_v2_post_reply }}
-                            <a class="btn btn-outline-dark"
-                               role="button"
-                               data-action="view-context"
-                               data-discussionid="{{discussionid}}"
-                               data-postid="{{id}}"
-                               data-name="{{name}}"
-                               href="#">
+        <div class="discussion-container">
+            <div class="p-4">
+                <h3 class="d-inline-block m-0 h6 font-weight-bold">{{#str}} discussionstartedby, mod_forum, {{authorfullname}} {{/str}}</h3>
+                <p class="d-inline-block m-0 h6 font-weight-normal text-muted ml-1">
+                    {{#userdate}} {{timecreated}}, {{#str}} strftimedate, core_langconfig {{/str}} {{/userdate}}
+                </p>
+                <h2 class="mb-4 font-weight-bold">{{name}}</h2>
+
+                {{#posts}}
+                    <div class="posts-container">
+                        {{#parent}}
+                            <div class="parent-container">
+                                <button
+                                    class="btn btn-link show-content-button collapsed"
+                                    data-target="#parent-post-content-{{id}}"
+                                    aria-expanded="false"
+                                    aria-controls="parent-post-content-{{id}}"
+                                    data-toggle="collapse"
+                                >
+                                    {{#str}} viewparentpost, mod_forum {{/str}}
+                                </button>
+                                <div id="parent-post-content-{{id}}" class="content collapse">
+                                    {{> mod_forum/forum_discussion_nested_post }}
+                                </div>
+                            </div>
+                        {{/parent}}
+                        {{#post}}
+                            <div class="post-container">
+                                {{> mod_forum/forum_discussion_nested_post }}
+                            </div>
+                            <button
+                                class="btn btn-link border ml-auto"
+                                type="button"
+                                data-action="view-context"
+                                data-discussionid="{{discussionid}}"
+                                data-postid="{{id}}"
+                                data-name="{{name}}"
+                            >
                                 {{#str}} viewconversation, forum {{/str}}
-                            </a>
-                        </div>
+                            </button>
+                        {{/post}}
+                        <hr class="w-75 mx-auto my-5">
                     </div>
-                </div>
-            {{/starter}}
+                {{/posts}}
+            </div>
             <hr>
-        {{/posts}}
+        </div>
     {{/discussions}}
     {{^discussions}}
-        <h3>{{#str}} noposts, forum {{/str}}</h3>
+        <div class="no-post-container text-center p-5">
+            {{#pix}} no-posts, mod_forum {{/pix}}
+            <h2 class="mt-3 font-weight-bold">{{#str}} noposts, mod_forum {{/str}}</h2>
+        </div>
     {{/discussions}}
 </div>
 {{#js}}
index a31d5cf..6f24231 100644 (file)
@@ -30,6 +30,8 @@
     {
     }
 }}
-<div class="grader-module-content col-sm-12 col-md-8 mb-3">
-    <div data-region="module_content" class="grader-module-content-display col-sm-12"></div>
+<div class="grader-module-content w-100 h-100">
+    <div data-region="module_content" class="grader-module-content-display">
+        {{> mod_forum/local/grades/local/grader/module_content_placeholder }}
+    </div>
 </div>
diff --git a/mod/forum/templates/local/grades/local/grader/module_content_placeholder.mustache b/mod/forum/templates/local/grades/local/grader/module_content_placeholder.mustache
new file mode 100644 (file)
index 0000000..97244ed
--- /dev/null
@@ -0,0 +1,170 @@
+{{!
+    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/local/grades/local/grader/module_content_placeholder
+
+    Classes required for JS:
+    * none
+
+    Data attributes required for JS:
+    *
+
+    Context variables required for this template:
+    *
+
+    Example context (json):
+    {}
+}}
+<div class="p-4">
+    <div class="d-inline-block bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
+    <div class="d-inline-block bg-pulse-grey ml-1 mb-1" style="height: 18px; width: 100px"></div>
+    <div class="bg-pulse-grey mb-4" style="height: 36px; width: 500px"></div>
+
+    <div class="d-flex align-items-center mb-2 p-2" style="height: 63px">
+        <div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
+        <div class="bg-pulse-grey" style="height: 15px; width: 150px"></div>
+    </div>
+    <div class="mb-2 p-2">
+        <div class="d-flex mb-2">
+            <div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
+            <div class="mb-3">
+                <div class="bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 18px; width: 350px"></div>
+            </div>
+        </div>
+        <div class="d-flex w-100">
+            <div class="flex-shrink-0 mr-2" style="height: 45px; width: 45px"></div>
+            <div class="flex-grow-1">
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 95%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 97%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 93%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 75%"></div>
+            </div>
+        </div>
+    </div>
+    <div class="bg-pulse-grey" style="height: 36px; width: 150px"></div>
+    <hr class="w-75 mx-auto my-5">
+
+    <div class="d-flex align-items-center mb-2 p-2" style="height: 63px">
+        <div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
+        <div class="bg-pulse-grey" style="height: 15px; width: 150px"></div>
+    </div>
+    <div class="mb-2 p-2">
+        <div class="d-flex mb-2">
+            <div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
+            <div class="mb-3">
+                <div class="bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 18px; width: 350px"></div>
+            </div>
+        </div>
+        <div class="d-flex w-100">
+            <div class="flex-shrink-0 mr-2" style="height: 45px; width: 45px"></div>
+            <div class="flex-grow-1">
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 95%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 97%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 93%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 75%"></div>
+            </div>
+        </div>
+    </div>
+    <div class="bg-pulse-grey" style="height: 36px; width: 150px"></div>
+    <hr class="w-75 mx-auto my-5">
+
+    <div class="d-flex align-items-center mb-2 p-2" style="height: 63px">
+        <div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
+        <div class="bg-pulse-grey" style="height: 15px; width: 150px"></div>
+    </div>
+    <div class="mb-2 p-2">
+        <div class="d-flex mb-2">
+            <div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
+            <div class="mb-3">
+                <div class="bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 18px; width: 350px"></div>
+            </div>
+        </div>
+        <div class="d-flex w-100">
+            <div class="flex-shrink-0 mr-2" style="height: 45px; width: 45px"></div>
+            <div class="flex-grow-1">
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 95%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 97%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 93%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 75%"></div>
+            </div>
+        </div>
+    </div>
+    <div class="bg-pulse-grey" style="height: 36px; width: 150px"></div>
+    <hr class="w-75 mx-auto my-5">
+
+    <div class="d-flex align-items-center mb-2 p-2" style="height: 63px">
+        <div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
+        <div class="bg-pulse-grey" style="height: 15px; width: 150px"></div>
+    </div>
+    <div class="mb-2 p-2">
+        <div class="d-flex mb-2">
+            <div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
+            <div class="mb-3">
+                <div class="bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 18px; width: 350px"></div>
+            </div>
+        </div>
+        <div class="d-flex w-100">
+            <div class="flex-shrink-0 mr-2" style="height: 45px; width: 45px"></div>
+            <div class="flex-grow-1">
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 95%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 97%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 93%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 75%"></div>
+            </div>
+        </div>
+    </div>
+    <div class="bg-pulse-grey" style="height: 36px; width: 150px"></div>
+    <hr class="w-75 mx-auto my-5">
+
+    <div class="d-flex align-items-center mb-2 p-2" style="height: 63px">
+        <div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
+        <div class="bg-pulse-grey" style="height: 15px; width: 150px"></div>
+    </div>
+    <div class="mb-2 p-2">
+        <div class="d-flex mb-2">
+            <div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
+            <div class="mb-3">
+                <div class="bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 18px; width: 350px"></div>
+            </div>
+        </div>
+        <div class="d-flex w-100">
+            <div class="flex-shrink-0 mr-2" style="height: 45px; width: 45px"></div>
+            <div class="flex-grow-1">
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 95%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 97%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 93%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
+                <div class="bg-pulse-grey mb-1" style="height: 15px; width: 75%"></div>
+            </div>
+        </div>
+    </div>
+    <div class="bg-pulse-grey" style="height: 36px; width: 150px"></div>
+</div>
index d491679..1e3878d 100644 (file)
@@ -2664,17 +2664,21 @@ class mod_forum_external_testcase extends externallib_advanced_testcase {
         $record->course = $course1->id;
         $record->userid = $user1->id;
         $record->forum = $forum1->id;
+        $record->timemodified = 1;
         $discussion1 = $forumgenerator->create_discussion($record);
         $discussion1firstpost = $postvault->get_first_post_for_discussion_ids([$discussion1->id]);
-        $discussion1firstpostobject = $legacypostmapper->to_legacy_object($discussion1firstpost[$discussion1->firstpost]);
+        $discussion1firstpost = $discussion1firstpost[$discussion1->firstpost];
+        $discussion1firstpostobject = $legacypostmapper->to_legacy_object($discussion1firstpost);
 
         $record = new stdClass();
         $record->course = $course1->id;
         $record->userid = $user1->id;
         $record->forum = $forum1->id;
+        $record->timemodified = 2;
         $discussion2 = $forumgenerator->create_discussion($record);
         $discussion2firstpost = $postvault->get_first_post_for_discussion_ids([$discussion2->id]);
-        $discussion2firstpostobject = $legacypostmapper->to_legacy_object($discussion2firstpost[$discussion2->firstpost]);
+        $discussion2firstpost = $discussion2firstpost[$discussion2->firstpost];
+        $discussion2firstpostobject = $legacypostmapper->to_legacy_object($discussion2firstpost);
 
         // Add 1 reply to the discussion 1 from a different user.
         $record = new stdClass();
@@ -2733,6 +2737,8 @@ class mod_forum_external_testcase extends externallib_advanced_testcase {
         $expectedposts['discussions'][0] = [
             'name' => $discussion1->name,
             'id' => $discussion1->id,
+            'timecreated' => $discussion1firstpost->get_time_created(),
+            'authorfullname' => $user1entity->get_full_name(),
             'posts' => [
                 'userposts' => [
                     [
@@ -2864,6 +2870,8 @@ class mod_forum_external_testcase extends externallib_advanced_testcase {
         $expectedposts['discussions'][1] = [
             'name' => $discussion2->name,
             'id' => $discussion2->id,
+            'timecreated' => $discussion2firstpost->get_time_created(),
+            'authorfullname' => $user1entity->get_full_name(),
             'posts' => [
                 'userposts' => [
                     [
index 7d99de2..9a2bbc9 100644 (file)
@@ -432,6 +432,7 @@ $grading-search-button-padding-left: calc(#{map-get($spacers, 2)} + 8px) !defaul
 $grading-search-input-padding-left: calc(#{map-get($spacers, 2)} + #{map-get($spacers, 2)} + #{$grading-icon-button-size - ($input-border-width * 2)}) !default; /* stylelint-disable-line max-line-length */
 $grading-search-input-padding-right: calc(#{map-get($spacers, 2)} + #{$grading-icon-button-size}) !default;
 $grading-nav-bar-active-drawer-button-bottom: calc(#{map-get($spacers, 2) * -1} - 1px) !default;
+$grading-content-show-content-button-padding-left: calc(#{map-get($spacers, 2) * 2} + 45px) !default;
 
 @keyframes expandSearchButton {
     from {
@@ -710,6 +711,101 @@ $grading-nav-bar-active-drawer-button-bottom: calc(#{map-get($spacers, 2) * -1}
             width: 20px;
         }
     }
+
+    .grader-module-content-display {
+        .discussion-container {
+            &:last-of-type {
+                > hr {
+                    display: none;
+                }
+            }
+
+            .posts-container {
+                &:last-of-type {
+                    > hr {
+                        display: none;
+                    }
+                }
+
+                .parent-container {
+                    position: relative;
+
+                    .show-content-button {
+                        position: absolute;
+                        height: 100%;
+                        width: 100%;
+                        left: 0;
+                        top: 0;
+                        padding-left: $grading-content-show-content-button-padding-left;
+                        text-align: left;
+                        z-index: 1;
+
+                        &:not(.collapsed) {
+                            display: none;
+                        }
+                    }
+
+                    .content {
+                        display: block;
+                        height: auto !important; /* stylelint-disable-line declaration-no-important */
+
+                        .header {
+                            transition: margin-bottom $grading-animation-duration ease-in-out;
+
+                            div + div {
+                                opacity: 1;
+                                visibility: visible;
+                                max-height: none;
+                                transition:
+                                    opacity $grading-animation-duration linear,
+                                    visibility 0s linear;
+                            }
+                        }
+                        .body-content-container {
+                            opacity: 1;
+                            visibility: visible;
+                            max-height: none;
+                            transition:
+                                opacity $grading-animation-duration linear,
+                                visibility 0s linear;
+                        }
+                    }
+
+                    .show-content-button.collapsed + .content {
+                        opacity: .3;
+
+                        .header {
+                            margin-bottom: 0 !important; /* stylelint-disable-line declaration-no-important */
+
+                            div + div {
+                                opacity: 0;
+                                visibility: hidden;
+                                max-height: 0;
+                            }
+                        }
+                        .body-content-container {
+                            opacity: 0;
+                            visibility: hidden;
+                            max-height: 0;
+                        }
+                    }
+
+                    .show-content-button.collapsed:hover + .content,
+                    .show-content-button.collapsed:focus + .content {
+                        opacity: 1;
+                    }
+                }
+            }
+        }
+
+        .no-post-container {
+            .icon {
+                height: 250px;
+                width: 250px;
+                margin-right: 0;
+            }
+        }
+    }
 }
 
 @include media-breakpoint-down(xs) {
index f18e492..5a11954 100644 (file)
@@ -16637,6 +16637,63 @@ select {
     height: 20px;
     width: 20px; }
 
+.path-mod-forum .unified-grader .grader-module-content-display .discussion-container:last-of-type > hr {
+  display: none; }
+
+.path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container:last-of-type > hr {
+  display: none; }
+
+.path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container {
+  position: relative; }
+  .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button {
+    position: absolute;
+    height: 100%;
+    width: 100%;
+    left: 0;
+    top: 0;
+    padding-left: calc(1rem + 45px);
+    text-align: left;
+    z-index: 1; }
+    .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button:not(.collapsed) {
+      display: none; }
+  .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .content {
+    display: block;
+    height: auto !important;
+    /* stylelint-disable-line declaration-no-important */ }
+    .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .content .header {
+      transition: margin-bottom 0.3s ease-in-out; }
+      .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .content .header div + div {
+        opacity: 1;
+        visibility: visible;
+        max-height: none;
+        transition: opacity 0.3s linear, visibility 0s linear; }
+    .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .content .body-content-container {
+      opacity: 1;
+      visibility: visible;
+      max-height: none;
+      transition: opacity 0.3s linear, visibility 0s linear; }
+  .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed + .content {
+    opacity: .3; }
+    .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed + .content .header {
+      margin-bottom: 0 !important;
+      /* stylelint-disable-line declaration-no-important */ }
+      .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed + .content .header div + div {
+        opacity: 0;
+        visibility: hidden;
+        max-height: 0; }
+    .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed + .content .body-content-container {
+      opacity: 0;
+      visibility: hidden;
+      max-height: 0; }
+  .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed:hover + .content,
+  .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed:focus + .content {
+    opacity: 1; }
+
+.path-mod-forum .unified-grader .grader-module-content-display .no-post-container .icon {
+  height: 250px;
+  width: 250px;
+  margin-right: 0; }
+
 @media (max-width: 575.98px) {
   .path-mod-forum .unified-grader .grader-grading-panel {
     width: 100%; } }
index 92da122..fc46bca 100644 (file)
@@ -16909,6 +16909,63 @@ select {
     height: 20px;
     width: 20px; }
 
+.path-mod-forum .unified-grader .grader-module-content-display .discussion-container:last-of-type > hr {
+  display: none; }
+
+.path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container:last-of-type > hr {
+  display: none; }
+
+.path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container {
+  position: relative; }
+  .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button {
+    position: absolute;
+    height: 100%;
+    width: 100%;
+    left: 0;
+    top: 0;
+    padding-left: calc(1rem + 45px);
+    text-align: left;
+    z-index: 1; }
+    .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button:not(.collapsed) {
+      display: none; }
+  .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .content {
+    display: block;
+    height: auto !important;
+    /* stylelint-disable-line declaration-no-important */ }
+    .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .content .header {
+      transition: margin-bottom 0.3s ease-in-out; }
+      .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .content .header div + div {
+        opacity: 1;
+        visibility: visible;
+        max-height: none;
+        transition: opacity 0.3s linear, visibility 0s linear; }
+    .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .content .body-content-container {
+      opacity: 1;
+      visibility: visible;
+      max-height: none;
+      transition: opacity 0.3s linear, visibility 0s linear; }
+  .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed + .content {
+    opacity: .3; }
+    .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed + .content .header {
+      margin-bottom: 0 !important;
+      /* stylelint-disable-line declaration-no-important */ }
+      .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed + .content .header div + div {
+        opacity: 0;
+        visibility: hidden;
+        max-height: 0; }
+    .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed + .content .body-content-container {
+      opacity: 0;
+      visibility: hidden;
+      max-height: 0; }
+  .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed:hover + .content,
+  .path-mod-forum .unified-grader .grader-module-content-display .discussion-container .posts-container .parent-container .show-content-button.collapsed:focus + .content {
+    opacity: 1; }
+
+.path-mod-forum .unified-grader .grader-module-content-display .no-post-container .icon {
+  height: 250px;
+  width: 250px;
+  margin-right: 0; }
+
 @media (max-width: 575.98px) {
   .path-mod-forum .unified-grader .grader-grading-panel {
     width: 100%; } }