From 8fcf1bd190159b71d201cdb41685c6fb22832f2e Mon Sep 17 00:00:00 2001
From: Thomas Hackl <hackl@data-quest.de>
Date: Thu, 4 Apr 2024 09:55:35 +0000
Subject: [PATCH] =?UTF-8?q?Resolve=20"Umschalten=20der=20Ansicht=20im=20Ve?=
 =?UTF-8?q?ranstaltungsverzeichnis=20springt=20wieder=20an=20den=20Anfang?=
 =?UTF-8?q?=20zur=C3=BCck"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #3867

Merge request studip/studip!2720
---
 app/controllers/search/courses.php            | 12 +---
 resources/vue/components/tree/StudipTree.vue  | 29 +++++++++-
 .../components/tree/StudipTreeViewWidget.vue  | 56 +++++++++++++++++++
 3 files changed, 84 insertions(+), 13 deletions(-)
 create mode 100644 resources/vue/components/tree/StudipTreeViewWidget.vue

diff --git a/app/controllers/search/courses.php b/app/controllers/search/courses.php
index 6ae9d6afeda..eaf660bea95 100644
--- a/app/controllers/search/courses.php
+++ b/app/controllers/search/courses.php
@@ -110,17 +110,7 @@ class Search_CoursesController extends AuthenticatedController
         }
 
         $sidebar->addWidget(new VueWidget('search-widget'));
+        $sidebar->addWidget(new VueWidget('views-widget'));
         $sidebar->addWidget(new VueWidget('export-widget'));
-
-        $views = new ViewsWidget();
-        $views->addLink(
-            _('Als Liste'),
-            $this->url_for('search/courses', array_merge($params, ['show_as' => 'list']))
-        )->setActive($this->show_as === 'list');
-        $views->addLink(
-            _('Als Tabelle'),
-            $this->url_for('search/courses', array_merge($params, ['show_as' => 'table']))
-        )->setActive($this->show_as === 'table');
-        $sidebar->addWidget($views);
     }
 }
diff --git a/resources/vue/components/tree/StudipTree.vue b/resources/vue/components/tree/StudipTree.vue
index 136fc954982..167822500cc 100644
--- a/resources/vue/components/tree/StudipTree.vue
+++ b/resources/vue/components/tree/StudipTree.vue
@@ -33,6 +33,11 @@
         <MountingPortal v-if="withSearch" mountTo="#search-widget" name="sidebar-search">
             <search-widget v-if="currentNode" :min-length="3" ref="searchWidget"></search-widget>
         </MountingPortal>
+        <MountingPortal v-if="!editable && !isSearching && !isLoading && currentNode"
+                        mountTo="#views-widget"
+                        name="sidebar-views">
+            <studip-tree-view-widget :config="viewConfig" />
+        </MountingPortal>
     </div>
 </template>
 
@@ -41,6 +46,7 @@ import axios from 'axios';
 import { TreeMixin } from '../../mixins/TreeMixin';
 import StudipProgressIndicator from '../StudipProgressIndicator.vue';
 import SearchWidget from '../SearchWidget.vue';
+import StudipTreeViewWidget from './StudipTreeViewWidget.vue';
 import StudipTreeList from './StudipTreeList.vue';
 import StudipTreeTable from './StudipTreeTable.vue';
 import StudipTreeNode from './StudipTreeNode.vue';
@@ -49,7 +55,13 @@ import TreeSearchResult from './TreeSearchResult.vue';
 export default {
     name: 'StudipTree',
     components: {
-        TreeSearchResult, SearchWidget, StudipProgressIndicator, StudipTreeList, StudipTreeTable, StudipTreeNode
+        TreeSearchResult,
+        SearchWidget,
+        StudipTreeViewWidget,
+        StudipProgressIndicator,
+        StudipTreeList,
+        StudipTreeTable,
+        StudipTreeNode
     },
     mixins: [ TreeMixin ],
     props: {
@@ -163,12 +175,19 @@ export default {
             isLoading: false,
             showStructuralNavigation: false,
             searchConfig: {},
-            isSearching: false
+            isSearching: false,
+            viewConfig: null
         }
     },
     methods: {
         changeCurrentNode(node) {
             this.currentNode = node;
+            this.viewConfig = {
+                view: this.viewType,
+                node: this.currentNode,
+                semester: this.semester,
+                semClass: this.semClass
+            };
             this.$nextTick(() => {
                 document.getElementById('tree-breadcrumb-' + node.attributes.id)?.focus();
             });
@@ -206,6 +225,12 @@ export default {
             this.currentNode = this.startNode;
             this.loaded = true;
             this.isLoading = false;
+            this.viewConfig = {
+                view: this.viewType,
+                node: this.currentNode,
+                semester: this.semester,
+                semClass: this.semClass
+            };
         });
 
         axios.interceptors.request.eject(loadingIndicator);
diff --git a/resources/vue/components/tree/StudipTreeViewWidget.vue b/resources/vue/components/tree/StudipTreeViewWidget.vue
new file mode 100644
index 00000000000..30e2d5c30d3
--- /dev/null
+++ b/resources/vue/components/tree/StudipTreeViewWidget.vue
@@ -0,0 +1,56 @@
+<template>
+    <sidebar-widget id="views-widget" class="sidebar-views" :title="$gettext('Ansicht')">
+        <template #content>
+            <ul class="widget-list widget-links sidebar-views">
+                <li :class="{ active: config.view === 'list' }">
+                    <a :href="getUrl('list')"
+                       :title="$gettext('Verzeichnis als Liste anzeigen')"
+                       tabindex="0">
+                        {{ $gettext('Als Liste anzeigen') }}
+                    </a>
+                </li>
+                <li :class="{ active: config.view === 'table' }">
+                    <a :href="getUrl('table')"
+                       :title="$gettext('Verzeichnis als Tabelle anzeigen')"
+                       tabindex="0">
+                        {{ $gettext('Als Tabelle anzeigen') }}
+                    </a>
+                </li>
+            </ul>
+        </template>
+    </sidebar-widget>
+</template>
+
+<script>
+import SidebarWidget from '../SidebarWidget.vue';
+
+export default {
+    name: 'StudipTreeViewWidget',
+    components: {
+        SidebarWidget
+    },
+    props: {
+        config: {
+            type: Object,
+            required: true
+        }
+    },
+    methods: {
+        getUrl(showAs) {
+            const url = new URL(window.location);
+            url.searchParams.set('show_as', showAs);
+            url.searchParams.set('node_id', this.config.node.id);
+
+            if (this.config.semester !== '') {
+                url.searchParams.set('semester', this.config.semester);
+            }
+
+            if (this.config.semClass !== 0) {
+                url.searchParams.set('semclass', this.config.semClass);
+            }
+
+            return url.toString();
+        }
+    }
+}
+</script>
-- 
GitLab