Implemented framework for loading indicator. Resolves #8.
authorAdam Dullage <redacted>
Tue, 26 Jul 2022 11:55:44 +0000 (12:55 +0100)
committerAdam Dullage <redacted>
Tue, 26 Jul 2022 11:55:44 +0000 (12:55 +0100)
flatnotes/src/components/App.js
flatnotes/src/components/App.vue
flatnotes/src/components/LoadingIndicator.vue [new file with mode: 0644]
flatnotes/src/components/RecentlyModified.vue
flatnotes/src/constants.js

index 98d22f740571d1b8cb1740ff409602909e8c0163..dd955527be7e678c293b690b60e51a9e4d145de0 100644 (file)
@@ -2,6 +2,7 @@ import { Editor } from "@toast-ui/vue-editor";
 import { Viewer } from "@toast-ui/vue-editor";
 
 import RecentlyModified from "./RecentlyModified";
+import LoadingIndicator from "./LoadingIndicator.vue";
 
 import api from "../api";
 import * as constants from "../constants";
@@ -14,6 +15,7 @@ export default {
     Viewer,
     Editor,
     RecentlyModified,
+    LoadingIndicator,
   },
 
   data: function() {
@@ -100,7 +102,10 @@ export default {
         .catch(function(error) {
           if (error.handled) {
             return;
-          } else if ([400, 422].includes(error.response.status)) {
+          } else if (
+            typeof error.response !== "undefined" &&
+            [400, 422].includes(error.response.status)
+          ) {
             parent.$bvToast.toast("Incorrect Username or Password ✘", {
               variant: "danger",
               noCloseButton: true,
@@ -132,6 +137,7 @@ export default {
 
     getSearchResults: function() {
       let parent = this;
+      this.searchFailed = false;
       api
         .get("/api/search", { params: { term: this.searchTerm } })
         .then(function(response) {
@@ -149,6 +155,7 @@ export default {
         })
         .catch(function(error) {
           if (!error.handled) {
+            parent.searchFailed = true;
             parent.unhandledServerErrorToast();
           }
         });
@@ -168,6 +175,7 @@ export default {
 
     loadNote: function(filename) {
       let parent = this;
+      this.noteLoadFailed = false;
       api
         .get(`/api/notes/${filename}.${constants.markdownExt}`)
         .then(function(response) {
@@ -179,8 +187,17 @@ export default {
           parent.updateDocumentTitle();
         })
         .catch(function(error) {
-          if (!error.handled) {
+          if (error.handled) {
+            return;
+          } else if (
+            typeof error.response !== "undefined" &&
+            error.response.status == 404
+          ) {
+            parent.noteLoadFailedMessage = "Note not found 😞";
+            parent.noteLoadFailed = true;
+          } else {
             parent.unhandledServerErrorToast();
+            parent.noteLoadFailed = true;
           }
         });
     },
@@ -290,7 +307,10 @@ export default {
           .catch(function(error) {
             if (error.handled) {
               return;
-            } else if (error.response.status == 409) {
+            } else if (
+              typeof error.response !== "undefined" &&
+              error.response.status == 409
+            ) {
               parent.existingFilenameToast();
             } else {
               parent.unhandledServerErrorToast();
@@ -312,7 +332,10 @@ export default {
           .catch(function(error) {
             if (error.handled) {
               return;
-            } else if (error.response.status == 409) {
+            } else if (
+              typeof error.response !== "undefined" &&
+              error.response.status == 409
+            ) {
               parent.existingFilenameToast();
             } else {
               parent.unhandledServerErrorToast();
index 235bf613a8231b2f6c02396b3946f66d9e94ae57..141befe31be1b7c52b16452c4e2862b1a792e94e 100644 (file)
       <div v-if="currentView == views.note">
         <!-- Loading -->
         <div v-if="currentNote == null">
-          <p class="text-center">Loading...</p>
+          <loading-indicator
+            :failure-message="noteLoadFailedMessage"
+            :failed="noteLoadFailed"
+          />
         </div>
 
         <!-- Note Loaded -->
       <div v-if="currentView == views.search">
         <!-- Searching -->
         <div v-if="searchResults == null">
-          <p class="text-center">Searching...</p>
+          <loading-indicator
+            loading-message="Searching..."
+            failure-message="Search failed 😞"
+            :failed="searchFailed"
+          />
         </div>
 
         <!-- No Results -->
diff --git a/flatnotes/src/components/LoadingIndicator.vue b/flatnotes/src/components/LoadingIndicator.vue
new file mode 100644 (file)
index 0000000..e2d2c7f
--- /dev/null
@@ -0,0 +1,16 @@
+<template>
+  <div>
+    <p v-if="!failed" class="text-center">{{ loadingMessage }}</p>
+    <p v-else class="text-center">{{ failureMessage }}</p>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    loadingMessage: { type: String, default: "Loading..." },
+    failureMessage: { type: String, default: "Loading failed 😞" },
+    failed: Boolean,
+  },
+};
+</script>
index 230bf2e9190e0aa4c1e7e4a54a4bcdd6ea652955..17d1be8e3c00e67a9059a16484e7187a65b36133 100644 (file)
@@ -4,7 +4,7 @@
 
     <!-- Loading -->
     <div v-if="notes == null">
-      <p class="text-center">Loading...</p>
+      <loading-indicator :failed="loadingFailed"/>
     </div>
 
     <!-- No Notes -->
 import api from "../api";
 import { Note } from "../classes";
 import EventBus from "../eventBus";
+import LoadingIndicator from "./LoadingIndicator.vue";
 
 export default {
+  components: {
+    LoadingIndicator,
+  },
+
   data: function () {
     return {
       notes: null,
+      loadingFailed: false,
     };
   },
 
@@ -53,6 +59,7 @@ export default {
           });
         })
         .catch(function (error) {
+          parent.loadingFailed = true;
           if (!error.handled) {
             EventBus.$emit("unhandledServerError");
           }
index a4c4918ec3366a197dd70fba04fb7424c11527d9..4a53c8b4bd5477284610ced1752955639d176393 100644 (file)
@@ -29,12 +29,17 @@ export const dataDefaults = function() {
     passwordInput: null,
     rememberMeInput: false,
 
+    // Search Data
+    searchFailed: false,
+
     // Note Data
     searchTerm: null,
     searchResults: null,
     currentNote: null,
     titleInput: null,
     initialContent: null,
+    noteLoadFailed: false,
+    noteLoadFailedMessage: "Loading failed 😞",
 
     // Toast UI Plugins
     viewerOptions: { plugins: [codeSyntaxHighlight] },
git clone https://git.99rst.org/PROJECT