From ff4b76ce357dd20e155af61949fcb2bc97971939 Mon Sep 17 00:00:00 2001
From: Annabel Dunstone Gray <annabel.dunstone@gmail.com>
Date: Fri, 15 Nov 2024 12:20:26 +0000
Subject: [PATCH] Small visual updates to glql UI

Changelog: changed
---
 .../glql/components/presenters/list.vue       | 30 +++++++++++++++----
 .../glql/components/presenters/table.vue      | 25 ++++++++++++++--
 locale/gitlab.pot                             |  2 +-
 .../glql/components/presenters/list_spec.js   |  4 +--
 4 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/app/assets/javascripts/glql/components/presenters/list.vue b/app/assets/javascripts/glql/components/presenters/list.vue
index 84d5603ac5307..ed52e1200a8c2 100644
--- a/app/assets/javascripts/glql/components/presenters/list.vue
+++ b/app/assets/javascripts/glql/components/presenters/list.vue
@@ -1,10 +1,15 @@
 <script>
-import { GlIntersperse } from '@gitlab/ui';
+import { GlIcon, GlIntersperse, GlLink, GlSprintf } from '@gitlab/ui';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import { __ } from '~/locale';
 
 export default {
   name: 'ListPresenter',
   components: {
+    GlIcon,
     GlIntersperse,
+    GlLink,
+    GlSprintf,
   },
   inject: ['presenter'],
   props: {
@@ -32,6 +37,12 @@ export default {
     fields() {
       return this.config.fields;
     },
+    docsPath() {
+      return helpPagePath('user/glql');
+    },
+  },
+  i18n: {
+    generatedMessage: __('Generated by %{linkStart}GLQL%{linkEnd}'),
   },
 };
 </script>
@@ -43,16 +54,23 @@ export default {
         :key="itemIndex"
         :data-testid="`list-item-${itemIndex}`"
       >
-        <gl-intersperse separator=" - ">
+        <gl-intersperse separator=" · ">
           <span v-for="field in fields" :key="field.key">
             <component :is="presenter.forField(item, field.key)" />
           </span>
         </gl-intersperse>
       </li>
-      <li v-if="!items.length">
-        <em>{{ __('No data found for this query') }}</em>
-      </li>
+      <div v-if="!items.length" :dismissible="false" variant="tip" class="!gl-my-2">
+        {{ __('No data found for this query') }}
+      </div>
     </component>
-    <small>{{ __('Generated by GLQL') }}</small>
+    <div class="gl-mt-3 gl-flex gl-items-center gl-gap-1 gl-text-sm gl-text-subtle">
+      <gl-icon class="gl-mb-1 gl-mr-1" :size="12" name="tanuki" />
+      <gl-sprintf :message="$options.i18n.generatedMessage">
+        <template #link="{ content }">
+          <gl-link :href="docsPath" target="_blank">{{ content }}</gl-link>
+        </template>
+      </gl-sprintf>
+    </div>
   </div>
 </template>
diff --git a/app/assets/javascripts/glql/components/presenters/table.vue b/app/assets/javascripts/glql/components/presenters/table.vue
index 326455c7cb1b3..bfb941b5d2f96 100644
--- a/app/assets/javascripts/glql/components/presenters/table.vue
+++ b/app/assets/javascripts/glql/components/presenters/table.vue
@@ -1,5 +1,7 @@
 <script>
-import { GlIcon } from '@gitlab/ui';
+import { GlIcon, GlLink, GlSprintf } from '@gitlab/ui';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import { __ } from '~/locale';
 import Sorter from '../../core/sorter';
 import ThResizable from '../common/th_resizable.vue';
 
@@ -7,6 +9,8 @@ export default {
   name: 'TablePresenter',
   components: {
     GlIcon,
+    GlLink,
+    GlSprintf,
     ThResizable,
   },
   inject: ['presenter'],
@@ -33,11 +37,19 @@ export default {
       table: null,
     };
   },
+  computed: {
+    docsPath() {
+      return helpPagePath('user/glql');
+    },
+  },
   async mounted() {
     await this.$nextTick();
 
     this.table = this.$refs.table;
   },
+  i18n: {
+    generatedMessage: __('Generated by %{linkStart}GLQL%{linkEnd}'),
+  },
 };
 </script>
 <template>
@@ -72,11 +84,18 @@ export default {
         </tr>
         <tr v-if="!items.length">
           <td :colspan="fields.length" class="gl-text-center">
-            <em>{{ __('No data found for this query') }}</em>
+            {{ __('No data found for this query') }}
           </td>
         </tr>
       </tbody>
     </table>
-    <small>{{ __('Generated by GLQL') }}</small>
+    <div class="gl-mt-3 gl-flex gl-items-center gl-gap-1 gl-text-sm gl-text-subtle">
+      <gl-icon class="gl-mb-1 gl-mr-1" :size="12" name="tanuki" />
+      <gl-sprintf :message="$options.i18n.generatedMessage">
+        <template #link="{ content }">
+          <gl-link :href="docsPath" target="_blank">{{ content }}</gl-link>
+        </template>
+      </gl-sprintf>
+    </div>
   </div>
 </template>
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index f7ef924c749b1..858c66695a6c1 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -24224,7 +24224,7 @@ msgstr ""
 msgid "Generate site and private keys at"
 msgstr ""
 
-msgid "Generated by GLQL"
+msgid "Generated by %{linkStart}GLQL%{linkEnd}"
 msgstr ""
 
 msgid "Generated files are collapsed by default. To change this behavior, edit the %{tagStart}.gitattributes%{tagEnd} file. %{linkStart}Learn more.%{linkEnd}"
diff --git a/spec/frontend/glql/components/presenters/list_spec.js b/spec/frontend/glql/components/presenters/list_spec.js
index b7390b4c5d5ee..c64cd2bcf8018 100644
--- a/spec/frontend/glql/components/presenters/list_spec.js
+++ b/spec/frontend/glql/components/presenters/list_spec.js
@@ -50,9 +50,9 @@ describe('ListPresenter', () => {
     expect(htmlPresenter1.props('data')).toBe(MOCK_ISSUES.nodes[0].description);
     expect(htmlPresenter2.props('data')).toBe(MOCK_ISSUES.nodes[1].description);
 
-    expect(listItem1.text()).toEqual('Issue 1 (#1) - @foobar -  Open - This is a description');
+    expect(listItem1.text()).toEqual('Issue 1 (#1) · @foobar ·  Open · This is a description');
     expect(listItem2.text()).toEqual(
-      'Issue 2 (#2 - closed) - @janedoe -  Closed - This is another description',
+      'Issue 2 (#2 - closed) · @janedoe ·  Closed · This is another description',
     );
   });
 
-- 
GitLab