Skip to content
Snippets Groups Projects
Commit 045839d4 authored by Thomas Hackl's avatar Thomas Hackl Committed by Jan-Hendrik Willms
Browse files

Resolve "Vorlesungsverzeichnis: Suche sucht nicht (nur) im ausgewählen Bereich"

Closes #3041

Merge request studip/studip!2169
parent d9fd6cb1
No related branches found
No related tags found
No related merge requests found
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<ul class="needles"> <ul class="needles">
<li> <li>
<div class="input-group files-search"> <div class="input-group files-search">
<input type="text" id="searchterm" name="searchterm" v-model="searchterm" <input type="text" id="searchterm" name="searchterm" v-model.trim="searchterm"
:placeholder="$gettext('Veranstaltung suchen')" :placeholder="$gettext('Veranstaltung suchen')"
:aria-label="$gettext('Veranstaltung suchen')"> :aria-label="$gettext('Veranstaltung suchen')">
<a v-if="isActive" @click.prevent="cancelSearch" class="reset-search"> <a v-if="isActive" @click.prevent="cancelSearch" class="reset-search">
...@@ -13,7 +13,10 @@ ...@@ -13,7 +13,10 @@
</a> </a>
<button type="submit" class="submit-search" :title="$gettext('Suchen')" <button type="submit" class="submit-search" :title="$gettext('Suchen')"
@click.prevent="doSearch"> @click.prevent="doSearch">
<studip-icon shape="search" :size="20"></studip-icon> <studip-icon shape="search"
:role="maySearch ? 'clickable' : 'inactive'"
:size="20"
></studip-icon>
</button> </button>
</div> </div>
</li> </li>
...@@ -33,17 +36,34 @@ export default { ...@@ -33,17 +36,34 @@ export default {
StudipIcon, StudipIcon,
SidebarWidget SidebarWidget
}, },
props: {
minLength: {
type: Number,
default: 0,
}
},
data() { data() {
return { return {
searchterm: '', searchterm: '',
isActive: false isActive: false
}; };
}, },
computed: {
maySearch() {
return this.searchterm.length >= this.minLength;
}
},
methods: { methods: {
doSearch() { doSearch() {
if (!this.maySearch) {
return;
}
if (this.searchterm !== '') { if (this.searchterm !== '') {
this.isActive = true; this.isActive = true;
STUDIP.eventBus.emit('do-search', this.searchterm); STUDIP.eventBus.emit('do-search', this.searchterm);
} else {
this.cancelSearch();
} }
}, },
cancelSearch() { cancelSearch() {
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
<tree-search-result :search-config="searchConfig"></tree-search-result> <tree-search-result :search-config="searchConfig"></tree-search-result>
</div> </div>
<MountingPortal v-if="withSearch" mountTo="#search-widget" name="sidebar-search"> <MountingPortal v-if="withSearch" mountTo="#search-widget" name="sidebar-search">
<search-widget></search-widget> <search-widget :min-length="3"></search-widget>
</MountingPortal> </MountingPortal>
</div> </div>
</template> </template>
...@@ -199,9 +199,12 @@ export default { ...@@ -199,9 +199,12 @@ export default {
axios.interceptors.request.eject(loadingIndicator); axios.interceptors.request.eject(loadingIndicator);
this.globalOn('do-search', searchterm => { this.globalOn('do-search', searchterm => {
this.searchConfig.searchterm = searchterm; this.searchConfig = {
this.searchConfig.semester = this.semester; searchterm,
this.searchConfig.classname = this.startNode.attributes.classname; semester: this.semester,
classname: this.startNode.attributes.classname,
startId: this.currentNode.id,
};
this.isSearching = true; this.isSearching = true;
}); });
......
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<MountingPortal v-if="withExport" mountTo="#export-widget" name="sidebar-export"> <MountingPortal v-if="showExport" mountTo="#export-widget" name="sidebar-export">
<tree-export-widget v-if="courses.length > 0" <tree-export-widget v-if="courses.length > 0"
:title="$gettext('Veranstaltungen exportieren')" :url="exportUrl()" :title="$gettext('Veranstaltungen exportieren')" :url="exportUrl()"
:export-data="courses"></tree-export-widget> :export-data="courses"></tree-export-widget>
...@@ -202,6 +202,11 @@ export default { ...@@ -202,6 +202,11 @@ export default {
showingAllCourses: false showingAllCourses: false
} }
}, },
computed: {
showExport() {
return this.withExport && document.getElementById('export-widget');
}
},
methods: { methods: {
openNode(node, pushState = true) { openNode(node, pushState = true) {
this.currentNode = node; this.currentNode = node;
......
...@@ -115,7 +115,7 @@ ...@@ -115,7 +115,7 @@
</tr> </tr>
</draggable> </draggable>
</table> </table>
<MountingPortal v-if="withExport" mountTo="#export-widget" name="sidebar-export"> <MountingPortal v-if="showExport" mountTo="#export-widget" name="sidebar-export">
<tree-export-widget v-if="courses.length > 0" :title="$gettext('Download des Ergebnisses')" :url="exportUrl()" <tree-export-widget v-if="courses.length > 0" :title="$gettext('Download des Ergebnisses')" :url="exportUrl()"
:export-data="courses"></tree-export-widget> :export-data="courses"></tree-export-widget>
</MountingPortal> </MountingPortal>
...@@ -218,6 +218,11 @@ export default { ...@@ -218,6 +218,11 @@ export default {
showingAllCourses: false showingAllCourses: false
} }
}, },
computed: {
showExport() {
return this.withExport && document.getElementById('export-widget');
}
},
methods: { methods: {
openNode(node, pushState = true) { openNode(node, pushState = true) {
this.currentNode = node; this.currentNode = node;
......
<template> <template>
<div v-if="isLoading"> <div v-if="isLoading">
<studip-progress-indicator></studip-progress-indicator> <studip-progress-indicator v-if="showLoadingAnimation"
:description="searchDescription"
></studip-progress-indicator>
</div> </div>
<article v-else class="studip-tree-table"> <article v-else class="studip-tree-table">
<table v-if="courses.length > 0" class="default studip-tree-table"> <table v-if="courses.length > 0" class="default studip-tree-table">
...@@ -45,6 +47,10 @@ ...@@ -45,6 +47,10 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<studip-message-box v-else type="info">
{{ $gettextInterpolate($gettext('Es wurden keine Ergebnisse zu Ihrem Suchbegriff "%{term}" gefunden.'),
{ term: searchConfig.searchterm }) }}
</studip-message-box>
</article> </article>
</template> </template>
...@@ -54,10 +60,11 @@ import StudipProgressIndicator from '../StudipProgressIndicator.vue'; ...@@ -54,10 +60,11 @@ import StudipProgressIndicator from '../StudipProgressIndicator.vue';
import StudipIcon from '../StudipIcon.vue'; import StudipIcon from '../StudipIcon.vue';
import TreeNodeCoursePath from './TreeNodeCoursePath.vue'; import TreeNodeCoursePath from './TreeNodeCoursePath.vue';
import TreeCourseDetails from './TreeCourseDetails.vue'; import TreeCourseDetails from './TreeCourseDetails.vue';
import StudipMessageBox from "../StudipMessageBox.vue";
export default { export default {
name: 'TreeSearchResult', name: 'TreeSearchResult',
components: { StudipIcon, StudipProgressIndicator, TreeNodeCoursePath, TreeCourseDetails }, components: {StudipMessageBox, StudipIcon, StudipProgressIndicator, TreeNodeCoursePath, TreeCourseDetails },
mixins: [ TreeMixin ], mixins: [ TreeMixin ],
props: { props: {
searchConfig: { searchConfig: {
...@@ -67,19 +74,47 @@ export default { ...@@ -67,19 +74,47 @@ export default {
}, },
data() { data() {
return { return {
courses: [],
isLoading: true,
node: null, node: null,
isLoading: false, showLoadingAnimation: false,
isLoaded: false, timeout: null,
courses: []
} }
}, },
mounted() { computed: {
this.getNode(this.searchConfig.classname + '_root').then(response => { searchDescription() {
this.getNodeCourses(response.data.data, this.searchConfig.semester,0, this.searchConfig.searchterm, true) return this.$gettextInterpolate(
.then(courses => { this.$gettext('Suche nach dem Begriff "%{ term }"'),
this.courses = courses.data.data; {term: this.searchConfig.searchterm}
}); );
}); }
},
watch: {
searchConfig: {
handler(current, previous) {
if (current.searchterm !== previous?.searchterm) {
this.isLoading = true;
this.timeout = setTimeout(
() => this.showLoadingAnimation = true,
this.showProgressIndicatorTimeout
);
this.getNode(this.searchConfig.startId).then(response => {
return this.getNodeCourses(response.data.data, this.searchConfig.semester, 0, this.searchConfig.searchterm, true);
}).then(courses => {
this.courses = courses.data.data;
clearTimeout(this.timeout);
this.isLoading = false;
this.showLoadingAnimation = false;
});
}
},
immediate: true,
deep: true
}
} }
} }
</script> </script>
...@@ -37,7 +37,7 @@ export const TreeMixin = { ...@@ -37,7 +37,7 @@ export const TreeMixin = {
parameters['filter[semclass]'] = semClass; parameters['filter[semclass]'] = semClass;
} }
if (recursive) { if (node.attributes['has-children'] && recursive) {
parameters['filter[recursive]'] = true; parameters['filter[recursive]'] = true;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment