Source

src/App.vue

  1. <template>
  2. <div id="root" class="box" v-touch:swipe="swipeHandler">
  3. <nav-bar-comp id="top" class="topbar"/>
  4. <div id="app" class="main" v-if="mainData && !mainData.error">
  5. <div style="max-width: 800px;">
  6. <router-view/>
  7. </div>
  8. </div>
  9. <div v-else-if="!(mainData && mainData.error)" class="hider">
  10. <custom-spinner class="mt-2"/>
  11. </div>
  12. <div class="mt-5 w-75" v-else>
  13. <b-jumbotron bg-variant="danger" :text-variant="textVariant">
  14. <template #header>Fehler!</template>
  15. <template #lead>Bitte versuchen Sie es später erneut!</template>
  16. ({{ mainData.error }})
  17. </b-jumbotron>
  18. </div>
  19. <sidebar/>
  20. </div>
  21. </template>
  22. <script>
  23. import NavBarComp from "@/components/Navigation/NavBarComp";
  24. import {mapGetters} from "vuex";
  25. import CustomSpinner from "@/components/CustomSpinner";
  26. import Sidebar from "@/components/Navigation/Sidebar";
  27. import {TITLE, THEME_COLOR} from "../config"
  28. import {isLightColor, getCSSVariable} from "@/utilities/globals.mjs";
  29. /**
  30. * @module App
  31. * @description The App's entry point
  32. * @vue-computed {String} textVariant Determines, if text should be light or dark based on the 'danger' color
  33. */
  34. export default {
  35. name: 'App',
  36. components: {
  37. Sidebar,
  38. CustomSpinner,
  39. NavBarComp
  40. },
  41. mounted() {
  42. /**
  43. * This is used to enable File handling of .efa Files
  44. * If the Browser supports file handling API, then, if a User opens the file, the PWA will open and the file(s) it was opened with will be queued into the launchqueue.
  45. * The following reads the first file, and loads it into the referred service.
  46. */
  47. if ('launchQueue' in window) {
  48. window.launchQueue.setConsumer((launchParams) => {
  49. // Nothing to do when the queue is empty.
  50. if (!launchParams.files.length) {
  51. return;
  52. }
  53. const fileHandle = launchParams.files[0];
  54. fileHandle.getFile().then(res => {
  55. res.text().then(text => {
  56. this.$store.commit("load", JSON.parse(text));
  57. this.$router.push("/services/" + JSON.parse(text).name);
  58. })
  59. });
  60. });
  61. }
  62. },
  63. created() {
  64. //Loads the data from the ella-backend and sets title + theme color
  65. this.$store.commit("getMainData");
  66. document.title = TITLE;
  67. const metaThemeColor = document.querySelector("meta[name=theme-color]");
  68. metaThemeColor.setAttribute("content", THEME_COLOR);
  69. },
  70. computed: {
  71. textVariant() {
  72. return isLightColor(getCSSVariable("danger")) ? 'dark' : 'light';
  73. },
  74. ...mapGetters(["mainData"])
  75. },
  76. methods: {
  77. /**
  78. * Handles swipe events to open and close the sidebar
  79. * @param {String} evt The Swipe-Event
  80. */
  81. swipeHandler(evt) {
  82. if (evt === "left") {
  83. this.$store.commit('sidebar', true);
  84. }
  85. if (evt === "right") {
  86. this.$store.commit('sidebar', false);
  87. }
  88. }
  89. }
  90. }
  91. </script>
  92. <style lang="scss">
  93. @import "styles";
  94. .main, .topbar {
  95. width: 100%;
  96. }
  97. #top {
  98. position: sticky;
  99. left: 0;
  100. top: 0;
  101. }
  102. .box {
  103. display: flex;
  104. flex-flow: column;
  105. align-items: center;
  106. }
  107. .main {
  108. max-width: 900px;
  109. padding: 8px 12px;
  110. //text-align: center;
  111. }
  112. .hider {
  113. width: 100vw;
  114. }
  115. </style>