From b02a2c65c49a8674203348e754993c1e419df480 Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Fri, 13 May 2022 13:57:22 +0000
Subject: [PATCH] Implement default Stud.IP store in vuex

Closes #1052

Merge request studip/studip!615
---
 resources/assets/javascripts/chunks/vue.js    | 35 ++++++++++++-------
 resources/vue/components/StudipActionMenu.vue | 10 +++---
 resources/vue/store/StudipStore.js            | 15 ++++++++
 templates/layouts/base.php                    |  7 +++-
 4 files changed, 50 insertions(+), 17 deletions(-)
 create mode 100644 resources/vue/store/StudipStore.js

diff --git a/resources/assets/javascripts/chunks/vue.js b/resources/assets/javascripts/chunks/vue.js
index bfcb39324e6..99a2e9fe306 100644
--- a/resources/assets/javascripts/chunks/vue.js
+++ b/resources/assets/javascripts/chunks/vue.js
@@ -7,38 +7,49 @@ import { getLocale, getVueConfig } from '../lib/gettext.js';
 import PortalVue from 'portal-vue';
 import BaseComponents from '../../../vue/base-components.js';
 import BaseDirectives from "../../../vue/base-directives.js";
+import StudipStore from "../../../vue/store/StudipStore.js";
 
-Vue.mixin({
-    methods: {
-        globalEmit(...args) {
-            eventBus.emit(...args);
-        },
-        globalOn(...args) {
-            eventBus.on(...args);
-        },
-    },
-});
-
+// Setup gettext
 Vue.use(GetTextPlugin, getVueConfig());
 eventBus.on('studip:set-locale', (locale) => {
     Vue.config.language = locale;
 })
 
+// Register global components and directives
 registerGlobalComponents();
 registerGlobalDirectives();
 
+// Setup store and default Stud.IP store
 Vue.use(Vuex);
 const store = new Vuex.Store({});
 
-Vue.use(Router);
+store.registerModule('studip', StudipStore);
 
+// Setup router and PortalVue
+Vue.use(Router);
 Vue.use(PortalVue);
 
+// Define our own global mixin for Vue
+Vue.mixin({
+    methods: {
+        globalEmit(...args) {
+            eventBus.emit(...args);
+        },
+        globalOn(...args) {
+            eventBus.on(...args);
+        },
+        getStudipConfig: store.getters['studip/getConfig']
+    },
+});
+
+
+// Define createApp function
 function createApp(options, ...args) {
     Vue.config.language = getLocale();
     return new Vue({ store, ...options }, ...args);
 }
 
+// Define global registration functions for components and directives
 function registerGlobalComponents() {
     for (const [name, component] of Object.entries(BaseComponents)) {
         Vue.component(name, component);
diff --git a/resources/vue/components/StudipActionMenu.vue b/resources/vue/components/StudipActionMenu.vue
index eec47bb9825..86963924723 100644
--- a/resources/vue/components/StudipActionMenu.vue
+++ b/resources/vue/components/StudipActionMenu.vue
@@ -34,7 +34,7 @@ export default {
     props: {
         items: Array,
         collapseAt: {
-            default: true,
+            default: null,
         },
         context: {
             type: String,
@@ -100,13 +100,15 @@ export default {
             });
         },
         shouldCollapse () {
-            if (this.collapseAt === false) {
+            const collapseAt = this.collapseAt ?? this.getStudipConfig('ACTIONMENU_THRESHOLD');
+
+            if (collapseAt === false) {
                 return false;
             }
-            if (this.collapseAt === true) {
+            if (collapseAt === true) {
                 return true;
             }
-            return Number.parseInt(this.collapseAt) <= this.items.length;
+            return Number.parseInt(collapseAt) <= this.items.length;
         },
         title () {
             return this.context ? this.$gettextInterpolate(this.$gettext('Aktionsmenü für %{context}'), {context: this.context}) : this.$gettext('Aktionsmenü');
diff --git a/resources/vue/store/StudipStore.js b/resources/vue/store/StudipStore.js
new file mode 100644
index 00000000000..7a733c08d40
--- /dev/null
+++ b/resources/vue/store/StudipStore.js
@@ -0,0 +1,15 @@
+export default {
+    namespaced: true,
+
+    state () {
+        return {...STUDIP.config};
+    },
+    getters: {
+        getConfig: (state) => (key) => {
+            if (state[key] === undefined) {
+                throw new Error(`Invalid access to unknown configuration item "${key}"`);
+            }
+            return state[key];
+        }
+    }
+}
diff --git a/templates/layouts/base.php b/templates/layouts/base.php
index af6ca563cb1..42f5b0dfb02 100644
--- a/templates/layouts/base.php
+++ b/templates/layouts/base.php
@@ -83,7 +83,12 @@ $getInstalledLanguages = function () {
                              $GLOBALS['perm']->have_perm('autor') &&
                              PersonalNotifications::isActivated()) ?>,
             wysiwyg_enabled: <?= json_encode((bool) Config::get()->WYSIWYG) ?>,
-            server_timestamp: <?= time() ?>
+            server_timestamp: <?= time() ?>,
+            config: <?= json_encode([
+                'ACTIONMENU_THRESHOLD' => Config::get()->ACTION_MENU_THRESHOLD,
+                'ENTRIES_PER_PAGE'     => Config::get()->ENTRIES_PER_PAGE,
+                'OPENGRAPH_ENABLE'     => Config::get()->OPENGRAPH_ENABLE,
+            ]) ?>,
         }
     </script>
 
-- 
GitLab