From d17bbc2dc442fc3b3ca0c98402087f053daf92f7 Mon Sep 17 00:00:00 2001
From: chapoi <101828855+chapoi@users.noreply.github.com>
Date: Mon, 5 Aug 2024 17:39:08 +0200
Subject: [PATCH] UX: summary fixed positioning (#740)

Co-authored-by: Rafael Silva <xfalcox@gmail.com>
---
 .../ai-summary-box.gjs                        | 30 ++++++++++++-
 .../summarization/desktop/ai-summary.scss     | 45 +++++++++++++++++++
 config/locales/client.en.yml                  |  3 ++
 plugin.rb                                     |  1 +
 4 files changed, 77 insertions(+), 2 deletions(-)
 create mode 100644 assets/stylesheets/modules/summarization/desktop/ai-summary.scss

diff --git a/assets/javascripts/discourse/connectors/topic-map-expanded-after/ai-summary-box.gjs b/assets/javascripts/discourse/connectors/topic-map-expanded-after/ai-summary-box.gjs
index 69b2ac3e..878f27cd 100644
--- a/assets/javascripts/discourse/connectors/topic-map-expanded-after/ai-summary-box.gjs
+++ b/assets/javascripts/discourse/connectors/topic-map-expanded-after/ai-summary-box.gjs
@@ -21,6 +21,7 @@ export default class AiSummaryBox extends Component {
   @service siteSettings;
   @service messageBus;
   @service currentUser;
+  @service site;
 
   @tracked text = "";
   @tracked summarizedOn = null;
@@ -123,7 +124,9 @@ export default class AiSummaryBox extends Component {
       })
       .then(() => {
         if (update.done) {
-          this.summarizedOn = shortDateNoYear(topicSummary.updated_at);
+          this.summarizedOn = shortDateNoYear(
+            moment(topicSummary.updated_at, "YYYY-MM-DD HH:mm:ss Z")
+          );
           this.summarizedBy = topicSummary.algorithm;
           this.newPostsSinceSummary = topicSummary.new_posts_since_summary;
           this.outdated = topicSummary.outdated;
@@ -134,6 +137,17 @@ export default class AiSummaryBox extends Component {
       });
   }
 
+  @action
+  onRegisterApi(api) {
+    this.dMenu = api;
+  }
+
+  @action
+  async onClose() {
+    await this.dMenu.close();
+    this.unsubscribe();
+  }
+
   <template>
     {{#if @outletArgs.topic.summarizable}}
       <div
@@ -145,6 +159,7 @@ export default class AiSummaryBox extends Component {
           @onShow={{this.generateSummary}}
           @arrow={{true}}
           @identifier="topic-map__ai-summary"
+          @onRegisterApi={{this.onRegisterApi}}
           @interactive={{true}}
           @triggers="click"
           @placement="left"
@@ -158,7 +173,18 @@ export default class AiSummaryBox extends Component {
         >
           <:content>
             <div class="ai-summary-container">
-              <h3>Topic Summary</h3>
+              <header class="ai-summary__header">
+                <h3>{{i18n "discourse_ai.summarization.topic.title"}}</h3>
+                {{#if this.site.desktopView}}
+                  <DButton
+                    @title="discourse_ai.summarization.topic.close"
+                    @action={{this.onClose}}
+                    @icon="times"
+                    @class="btn-transparent ai-summary__close"
+                  />
+                {{/if}}
+              </header>
+
               <article class="ai-summary-box">
                 {{#if this.loading}}
                   <AiSummarySkeleton />
diff --git a/assets/stylesheets/modules/summarization/desktop/ai-summary.scss b/assets/stylesheets/modules/summarization/desktop/ai-summary.scss
new file mode 100644
index 00000000..245abc91
--- /dev/null
+++ b/assets/stylesheets/modules/summarization/desktop/ai-summary.scss
@@ -0,0 +1,45 @@
+.topic-map {
+  .ai-summarization-button {
+    .fk-d-menu {
+      position: fixed;
+      top: calc(var(--header-offset) + 1rem) !important;
+      left: unset !important;
+      right: 1rem !important;
+      width: 470px;
+      max-width: 470px !important; //overruling JS
+      max-height: calc(100vh - var(--header-offset) - 3rem);
+
+      &__inner-content {
+        max-height: unset;
+        padding: 0;
+      }
+
+      .ai-summary__header,
+      .ai-summary-box {
+        padding-inline: 1.5rem;
+        box-sizing: border-box;
+      }
+
+      .ai-summary {
+        &__header {
+          position: sticky;
+          top: 0;
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          padding-block: 0.5rem;
+          padding-right: 0.5rem;
+          background: var(--secondary);
+          border-bottom: 1px solid var(--primary-low);
+
+          h3 {
+            margin: 0;
+          }
+        }
+        &-box {
+          padding-bottom: 1rem;
+        }
+      }
+    }
+  }
+}
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 97ce1efa..5f4a9117 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -404,6 +404,9 @@ en:
           since:
             one: "Last hour"
             other: "Last %{count} hours"
+        topic:
+          title: "Topic summary"
+          close: "Close summary panel"
     review:
       types:
         reviewable_ai_post:
diff --git a/plugin.rb b/plugin.rb
index 9a587f0c..e6dd14f8 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -16,6 +16,7 @@ enabled_site_setting :discourse_ai_enabled
 register_asset "stylesheets/modules/ai-helper/common/ai-helper.scss"
 
 register_asset "stylesheets/modules/summarization/common/ai-summary.scss"
+register_asset "stylesheets/modules/summarization/desktop/ai-summary.scss", :desktop
 
 register_asset "stylesheets/modules/ai-bot/common/bot-replies.scss"
 register_asset "stylesheets/modules/ai-bot/common/ai-persona.scss"