FEATURE: display indirect assignments in the first post (#227)

FEATURE: display indirect assignments in the first post (#227)

A link in the first post will allow going to a specific post assigned to a user or group.

diff --git a/assets/javascripts/discourse-assign/initializers/extend-for-assigns.js.es6 b/assets/javascripts/discourse-assign/initializers/extend-for-assigns.js.es6
index f88ec09..c99d567 100644
--- a/assets/javascripts/discourse-assign/initializers/extend-for-assigns.js.es6
+++ b/assets/javascripts/discourse-assign/initializers/extend-for-assigns.js.es6
@@ -13,7 +13,7 @@ import TopicButtonAction, {
 } from "discourse/controllers/topic-bulk-actions";
 import { inject } from "@ember/controller";
 import I18n from "I18n";
-import { get } from "@ember/object";
+import { isEmpty } from "@ember/utils";
 
 const PLUGIN_ID = "discourse-assign";
 
@@ -336,6 +336,77 @@ function initialize(api) {
     },
   });
 
+  api.createWidget("assigned-to-first-post", {
+    html(attrs) {
+      const topic = attrs.topic;
+      const [assignedToUser, assignedToGroup, indirectlyAssignedTo] = [
+        topic.assigned_to_user,
+        topic.assigned_to_group,
+        topic.indirectly_assigned_to,
+      ];
+      const assigneeElements = [];
+
+      if (assignedToUser) {
+        assigneeElements.push(
+          h("span.assignee", [
+            h(
+              "a",
+              {
+                attributes: {
+                  class: "assigned-to-username",
+                  href: assignedToUserPath(assignedToUser),
+                },
+              },
+              assignedToUser.username
+            ),
+          ])
+        );
+      }
+      if (assignedToGroup) {
+        assigneeElements.push(
+          h("span.assignee", [
+            h(
+              "a",
+              {
+                attributes: {
+                  class: "assigned-to-group",
+                  href: assignedToGroupPath(assignedToGroup),
+                },
+              },
+              assignedToGroup.name
+            ),
+          ])
+        );
+      }
+      if (indirectlyAssignedTo) {
+        Object.keys(indirectlyAssignedTo).map((postNumber) => {
+          const assignee = indirectlyAssignedTo[postNumber];
+          assigneeElements.push(
+            h("span.assignee", [
+              h(
+                "a",
+                {
+                  attributes: {
+                    class: "assigned-indirectly",
+                    href: `${topic.url}/${postNumber}`,
+                  },
+                },
+                `#${postNumber} ${assignee.username || assignee.name}`
+              ),
+            ])
+          );
+        });
+      }
+      if (!isEmpty(assigneeElements)) {
+        return h("p.assigned-to", [
+          assignedToUser ? iconNode("user-plus") : iconNode("group-plus"),
+          h("span.assign-text", I18n.t("discourse_assign.assigned_to")),
+          assigneeElements,
+        ]);
+      }
+    },
+  });
+
   api.modifyClass("model:group", {
     pluginId: PLUGIN_ID,
 
@@ -404,10 +475,12 @@ function initialize(api) {
     if (postModel) {
       let assignedToUser, assignedToGroup, postAssignment, href;
       if (dec.attrs.post_number === 1) {
-        assignedToUser = get(postModel, "topic.assigned_to_user");
-        assignedToGroup = get(postModel, "topic.assigned_to_group");
+        return dec.widget.attach("assigned-to-first-post", {
+          topic: postModel.topic,
+        });
       } else {
-        postAssignment = postModel.topic.indirectly_assigned_to?.[postModel.id];
+        postAssignment =
+          postModel.topic.indirectly_assigned_to?.[postModel.post_number];
         if (postAssignment?.username) {
           assignedToUser = postAssignment;
         }
diff --git a/assets/stylesheets/assigns.scss b/assets/stylesheets/assigns.scss
index caf5a1c..c7cd505 100644
--- a/assets/stylesheets/assigns.scss
+++ b/assets/stylesheets/assigns.scss
@@ -23,6 +23,9 @@
   .composer-popup & {
     margin-left: 0.5em;
   }
+  .assignee:not(:last-child):after {
+    content: ", ";
+  }
 }
 
 .topic-body {
diff --git a/plugin.rb b/plugin.rb
index 1d581c0..fff1419 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -413,7 +413,7 @@ after_initialize do
   add_to_class(:topic, :indirectly_assigned_to) do
     return @indirectly_assigned_to if defined?(@indirectly_assigned_to)
     @indirectly_assigned_to = Assignment.where(topic_id: id, target_type: "Post").inject({}) do |acc, assignment|
-      acc[assignment.target_id] = assignment.assigned_to
+      acc[assignment.target.post_number] = assignment.assigned_to
       acc
     end
   end
diff --git a/test/javascripts/acceptance/assigned-topic-test.js.es6 b/test/javascripts/acceptance/assigned-topic-test.js.es6
index 2877035..e320ed8 100644
--- a/test/javascripts/acceptance/assigned-topic-test.js.es6
+++ b/test/javascripts/acceptance/assigned-topic-test.js.es6
@@ -26,6 +26,11 @@ acceptance("Discourse Assign | Assigned topic", function (needs) {
         avatar_template:
           "/letter_avatar/eviltrout/{size}/3_f9720745f5ce6dfc2b5641fca999d934.png",
       };
+      topic["indirectly_assigned_to"] = {
+        2: {
+          name: "Developers",
+        },
+      };
       return helper.response(topic);
     });
 
@@ -48,9 +53,9 @@ acceptance("Discourse Assign | Assigned topic", function (needs) {
       "shows assignment in the header"
     );
     assert.equal(
-      query("#post_1 .assigned-to-username").innerText.trim(),
-      "eviltrout",
-      "shows assignment in the first post"
+      query("#post_1 .assigned-to").innerText,
+      "Assigned toeviltrout#2 Developers",
+      "shows assignment and indirect assignments in the first post"
     );
     assert.ok(exists("#post_1 .assigned-to svg.d-icon-user-plus"));
     assert.ok(
@@ -69,7 +74,7 @@ acceptance("Discourse Assign | Assigned topic", function (needs) {
       "shows assignment in the header"
     );
     assert.equal(
-      query("#post_1 .assigned-to-username").innerText.trim(),
+      query("#post_1 .assigned-to-group").innerText.trim(),
       "Developers",
       "shows assignment in the first post"
     );

GitHub sha: a4b1847eff1aa8f5ab7267645bb7e1c6c89eb190

This commit appears in #227 which was approved by eviltrout. It was merged by lis2.