From 9c83f0b8797e2c6271b9b09b31d5e868b9f04a6b Mon Sep 17 00:00:00 2001
From: Julian Leucker <leuckerj@gmail.com>
Date: Tue, 21 Mar 2023 17:25:52 +0100
Subject: [PATCH] Import UpdateIndicator from AlekSIS-App-Alsijil

---
 CHANGELOG.rst                                 |  2 +
 .../components/generic/UpdateIndicator.vue    | 85 +++++++++++++++++++
 aleksis/core/frontend/messages/en.json        |  6 ++
 3 files changed, 93 insertions(+)
 create mode 100644 aleksis/core/frontend/components/generic/UpdateIndicator.vue

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 75e69afe5..4f114a3f4 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -13,6 +13,8 @@ Added
 ~~~~~
 
 * GraphQL schema for Rooms
+* [Dev] UpdateIndicator Vue Component to display the status of interactive pages
+
 
 Fixed
 ~~~~~
diff --git a/aleksis/core/frontend/components/generic/UpdateIndicator.vue b/aleksis/core/frontend/components/generic/UpdateIndicator.vue
new file mode 100644
index 000000000..0d23a2cab
--- /dev/null
+++ b/aleksis/core/frontend/components/generic/UpdateIndicator.vue
@@ -0,0 +1,85 @@
+<template>
+  <v-tooltip bottom>
+    <template #activator="{ on, attrs }">
+      <v-btn
+        right
+        icon
+        v-bind="attrs"
+        v-on="on"
+        @click="handleClick"
+        :loading="status === $options.UPDATING"
+      >
+        <v-icon v-if="status !== $options.UPDATING" :color="color">
+          {{ icon }}
+        </v-icon>
+      </v-btn>
+    </template>
+    <span>{{ text }}</span>
+  </v-tooltip>
+</template>
+
+<script>
+export default {
+  ERROR: "ERROR", // Something went wrong
+  SAVED: "SAVED", // Everything alright
+  UPDATING: "UPDATING", // We are sending something to the server
+  CHANGES: "CHANGES", // the user changed something, but it has not been saved yet
+  name: "UpdateIndicator",
+  emits: ["manual-update"],
+  props: {
+    status: {
+      type: String,
+      required: true,
+    },
+  },
+  computed: {
+    text() {
+      switch (this.status) {
+        case this.$options.SAVED:
+          return this.$t("status.saved");
+        case this.$options.UPDATING:
+          return this.$t("status.updating");
+        case this.$options.CHANGES:
+          return this.$t("status.changes");
+        default:
+          return this.$t("status.error");
+      }
+    },
+    color() {
+      switch (this.status) {
+        case this.$options.SAVED:
+          return "success";
+        case this.$options.CHANGES:
+          return "secondary";
+        case this.$options.UPDATING:
+          return "secondary";
+        default:
+          return "error";
+      }
+    },
+    icon() {
+      switch (this.status) {
+        case this.$options.SAVED:
+          return "$success";
+        case this.$options.CHANGES:
+          return "mdi-dots-horizontal";
+        default:
+          return "$warning";
+      }
+    },
+    isAbleToClick() {
+      return (
+        this.status === this.$options.CHANGES ||
+        this.status === this.$options.ERROR
+      );
+    },
+  },
+  methods: {
+    handleClick() {
+      if (this.isAbleToClick) {
+        emit('manual-update');
+      }
+    }
+  }
+};
+</script>
diff --git a/aleksis/core/frontend/messages/en.json b/aleksis/core/frontend/messages/en.json
index 3adabc47b..ff9693d36 100644
--- a/aleksis/core/frontend/messages/en.json
+++ b/aleksis/core/frontend/messages/en.json
@@ -224,5 +224,11 @@
   },
   "graphql": {
     "snackbar_error_message": "There was an error retrieving the page data. Please try again."
+  },
+  "status": {
+    "saved": "All changes are saved.",
+    "updating": "Changes are being synced.",
+    "changes": "You have unsaved changes.",
+    "error": "There has been an error while saving the latest changes."
   }
 }
-- 
GitLab