UX: Improve route hierarchy in for user-invites (#14583)

UX: Improve route hierarchy in for user-invites (#14583)

Previously the sidebar was being rendered in the -show routes, which meant that it disappeared and re-appeared when each tab was loading. This commit creates a parent user-invited route with the sidebar, and then renders the -show view in an outlet.

To avoid an extra HTTP request, the invite counts for the sidebar are fetched by the -show routes, and then applied to the parent controller. This means that there can be a very slight delay before the counts are displayed, but it is almost unnoticeable in normal use.

diff --git a/app/assets/javascripts/discourse/app/controllers/user-invited-show.js b/app/assets/javascripts/discourse/app/controllers/user-invited-show.js
index 3028bd2..f7f9851 100644
--- a/app/assets/javascripts/discourse/app/controllers/user-invited-show.js
+++ b/app/assets/javascripts/discourse/app/controllers/user-invited-show.js
@@ -62,39 +62,6 @@ export default Controller.extend({
     return invitesCountTotal > 0;
   },
 
-  @discourseComputed("invitesCount.total", "invitesCount.pending")
-  pendingLabel(invitesCountTotal, invitesCountPending) {
-    if (invitesCountTotal > 0) {
-      return I18n.t("user.invited.pending_tab_with_count", {
-        count: invitesCountPending,
-      });
-    } else {
-      return I18n.t("user.invited.pending_tab");
-    }
-  },
-
-  @discourseComputed("invitesCount.total", "invitesCount.expired")
-  expiredLabel(invitesCountTotal, invitesCountExpired) {
-    if (invitesCountTotal > 0) {
-      return I18n.t("user.invited.expired_tab_with_count", {
-        count: invitesCountExpired,
-      });
-    } else {
-      return I18n.t("user.invited.expired_tab");
-    }
-  },
-
-  @discourseComputed("invitesCount.total", "invitesCount.redeemed")
-  redeemedLabel(invitesCountTotal, invitesCountRedeemed) {
-    if (invitesCountTotal > 0) {
-      return I18n.t("user.invited.redeemed_tab_with_count", {
-        count: invitesCountRedeemed,
-      });
-    } else {
-      return I18n.t("user.invited.redeemed_tab");
-    }
-  },
-
   @action
   createInvite() {
     const controller = showModal("create-invite");
diff --git a/app/assets/javascripts/discourse/app/controllers/user-invited.js b/app/assets/javascripts/discourse/app/controllers/user-invited.js
new file mode 100644
index 0000000..0297849
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/controllers/user-invited.js
@@ -0,0 +1,38 @@
+import Controller from "@ember/controller";
+import discourseComputed from "discourse-common/utils/decorators";
+import I18n from "I18n";
+
+export default Controller.extend({
+  @discourseComputed("invitesCount.total", "invitesCount.pending")
+  pendingLabel(invitesCountTotal, invitesCountPending) {
+    if (invitesCountTotal > 0) {
+      return I18n.t("user.invited.pending_tab_with_count", {
+        count: invitesCountPending,
+      });
+    } else {
+      return I18n.t("user.invited.pending_tab");
+    }
+  },
+
+  @discourseComputed("invitesCount.total", "invitesCount.expired")
+  expiredLabel(invitesCountTotal, invitesCountExpired) {
+    if (invitesCountTotal > 0) {
+      return I18n.t("user.invited.expired_tab_with_count", {
+        count: invitesCountExpired,
+      });
+    } else {
+      return I18n.t("user.invited.expired_tab");
+    }
+  },
+
+  @discourseComputed("invitesCount.total", "invitesCount.redeemed")
+  redeemedLabel(invitesCountTotal, invitesCountRedeemed) {
+    if (invitesCountTotal > 0) {
+      return I18n.t("user.invited.redeemed_tab_with_count", {
+        count: invitesCountRedeemed,
+      });
+    } else {
+      return I18n.t("user.invited.redeemed_tab");
+    }
+  },
+});
diff --git a/app/assets/javascripts/discourse/app/routes/user-invited-show.js b/app/assets/javascripts/discourse/app/routes/user-invited-show.js
index fbc6925..81a4c03 100644
--- a/app/assets/javascripts/discourse/app/routes/user-invited-show.js
+++ b/app/assets/javascripts/discourse/app/routes/user-invited-show.js
@@ -11,6 +11,9 @@ export default DiscourseRoute.extend({
     if (!model.can_see_invite_details) {
       this.replaceWith("userInvited.show", "redeemed");
     }
+    this.controllerFor("user.invited").setProperties({
+      invitesCount: model.counts,
+    });
   },
 
   setupController(controller, model) {
diff --git a/app/assets/javascripts/discourse/app/routes/user-invited.js b/app/assets/javascripts/discourse/app/routes/user-invited.js
new file mode 100644
index 0000000..ae432d3
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/routes/user-invited.js
@@ -0,0 +1,13 @@
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
+  setupController(controller) {
+    const can_see_invite_details =
+      this.currentUser.staff ||
+      this.controllerFor("user").id === this.currentUser?.id;
+
+    controller.setProperties({
+      can_see_invite_details,
+    });
+  },
+});
diff --git a/app/assets/javascripts/discourse/app/templates/user-invited-show.hbs b/app/assets/javascripts/discourse/app/templates/user-invited-show.hbs
index 1872e0e..a3b616b 100644
--- a/app/assets/javascripts/discourse/app/templates/user-invited-show.hbs
+++ b/app/assets/javascripts/discourse/app/templates/user-invited-show.hbs
@@ -1,13 +1,3 @@
-{{#if model.can_see_invite_details}}
-  {{#d-section class="user-secondary-navigation" pageClass="user-invites"}}
-    {{#mobile-nav class="invites-nav" desktopClass="nav-stacked action-list"}}
-      {{nav-item route="userInvited.show" routeParam="pending" i18nLabel=pendingLabel}}
-      {{nav-item route="userInvited.show" routeParam="expired" i18nLabel=expiredLabel}}
-      {{nav-item route="userInvited.show" routeParam="redeemed" i18nLabel=redeemedLabel}}
-    {{/mobile-nav}}
-  {{/d-section}}
-{{/if}}
-
 {{#d-section pageClass="user-invites" tagName=""}}
   {{#if canInviteToForum}}
     {{#load-more class="user-content" selector=".user-invite-list tr" action=(action "loadMore")}}
diff --git a/app/assets/javascripts/discourse/app/templates/user-invited.hbs b/app/assets/javascripts/discourse/app/templates/user-invited.hbs
new file mode 100644
index 0000000..f038f94
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/templates/user-invited.hbs
@@ -0,0 +1,11 @@
+{{#if can_see_invite_details}}
+  {{#d-section class="user-secondary-navigation" pageClass="user-invites"}}
+    {{#mobile-nav class="invites-nav" desktopClass="nav-stacked action-list"}}
+      {{nav-item route="userInvited.show" routeParam="pending" i18nLabel=pendingLabel}}
+      {{nav-item route="userInvited.show" routeParam="expired" i18nLabel=expiredLabel}}
+      {{nav-item route="userInvited.show" routeParam="redeemed" i18nLabel=redeemedLabel}}
+    {{/mobile-nav}}
+  {{/d-section}}
+{{/if}}
+
+{{outlet}}

GitHub sha: 100095af50fa874df5b47da835ee5f80127f9478

This commit appears in #14583 which was approved by pmusaraj. It was merged by davidtaylorhq.