ydennisy / kg1

KG1 is a social knowledge management application, infused with AI.
https://kg1.io
MIT License
6 stars 0 forks source link

Show a "nothing indexed" banner when first arriving at index page. #38

Closed ydennisy closed 4 months ago

ydennisy commented 4 months ago

We have a page which allows users to index new URLs, this is in frontend/pages/index.vue, this page contains a table which is hidden until the server returns data.

We poll for this data whilst on the page.

To improve the UX, this we must add:

sweep-ai[bot] commented 4 months ago

🚀 Here's the PR! #39

💎 Sweep Pro: You have unlimited Sweep issues

Actions

Relevant files (click to expand). Mentioned files will always appear here. https://github.com/ydennisy/kg1/blob/20f4be797599860cada2909a7f7d72c536e86d4c/frontend/pages/index.vue#L1-L167 https://github.com/ydennisy/kg1/blob/20f4be797599860cada2909a7f7d72c536e86d4c/frontend/pages/search.vue#L1-L125

Step 2: ⌨️ Coding

frontend/pages/index.vue

Add reactive variables for table loading, empty state, and refreshing.
--- 
+++ 
@@ -1,4 +1,7 @@
 const indexFeedResults = ref<IndexFeedResult[]>([]);
+const isTableLoading = ref(true);
+const isTableEmpty = ref(false);
+const isTableRefreshing = ref(false);

 const config = useRuntimeConfig();
 const apiBase = config.public.apiBase;

frontend/pages/index.vue

Update `fetchIndexedPages` to handle table loading and empty state.
--- 
+++ 
@@ -13,7 +13,10 @@
   );
   if (data.value) {
     indexFeedResults.value = data.value;
+    isTableEmpty.value = data.value.length === 0;
   } else {
     indexFeedResults.value = [];
+    isTableEmpty.value = true;
   }
+  isTableLoading.value = false;
 };

frontend/pages/index.vue

Update `fetchIndexedPagesIfTabInFocus` to handle table refreshing state.
--- 
+++ 
@@ -1,5 +1,7 @@
 const fetchIndexedPagesIfTabInFocus = async () => {
   if (document.hasFocus()) {
+    isTableRefreshing.value = true;
     await fetchIndexedPages();
+    isTableRefreshing.value = false;
   }
 };

frontend/pages/index.vue

Update the template to display loading indicator, empty state banner, and refreshing icon.
--- 
+++ 
@@ -1,14 +1,39 @@
+<!-- Loading Indicator -->
+<div v-if="isTableLoading" class="mt-4 text-center">
+  <span class="text-gray-500">Loading...</span>
+</div>
+
+<!-- Empty State Banner -->
+<div
+  v-else-if="isTableEmpty"
+  class="bg-blue-100 border border-blue-300 text-blue-600 mt-4 px-4 py-2 rounded-md relative"
+  role="alert"
+>
+  <strong class="font-bold text-xs">Nothing indexed yet.</strong>
+  <span class="block sm:inline text-xs">
+    Please <NuxtLink class="font-bold text-blue-600 underline" to="/index">index</NuxtLink> some relevant documents.
+  </span>
+</div>
+
 <!-- URL Index Feed Table -->
 <table
+  v-else
   class="rounded-md mt-2 border-collapse table-auto w-full"
-  v-if="indexFeedResults.length"
 >
   <thead class="bg-gray-200">
     <tr>
       <th class="rounded-tl-md py-2 px-4 text-left">URL</th>
       <th class="py-2 px-4 text-left">Submitted</th>
       <th class="py-2 px-4 text-left">Source</th>
-      <th class="rounded-tr-md py-2 px-4 text-left">Status</th>
+      <th class="rounded-tr-md py-2 px-4 text-left">
+        Status
+        <span v-if="isTableRefreshing" class="ml-2 text-gray-500">
+          <svg class="animate-spin h-4 w-4 inline-block" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
+            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
+            <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
+          </svg>
+        </span>
+      </th>
     </tr>
   </thead>
   <tbody>

Step 3: 🔄️ Validating

Your changes have been successfully made to the branch sweep/show_a_nothing_indexed_banner_when_first. I have validated these changes using a syntax checker and a linter.


[!TIP] To recreate the pull request, edit the issue title or description.

This is an automated message generated by Sweep AI.