diff --git a/assets/css/courseware.scss b/assets/css/courseware.scss
index ee322ab3..c67b1215 100644
--- a/assets/css/courseware.scss
+++ b/assets/css/courseware.scss
@@ -28,6 +28,57 @@
white-space: nowrap;
}
+.oc-cw-searchbar .oc-cw-tokenselector {
+ position: absolute;
+ z-index: 10;
+ border: thin solid $content-color-40;
+ background-color: $white;
+ margin-top: 12px;
+ min-width: 130px;
+
+ @include arrow-top-border(9px, white, 1px, $content-color-40, 12px);
+
+ &::before, &::after {
+ right: 90%;
+ }
+
+ ul, li {
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+ }
+
+ li {
+ display: block;
+ padding: 0.5em;
+ cursor: pointer;
+
+ &:hover {
+ background-color: $light-gray-color-20;
+ }
+ }
+}
+
+.oc-cw-searchbar .oc-cw-searchbar-token {
+ margin: 3px;
+ padding: 5px;
+ border: solid thin $black;
+ background-color: $content-color-20;
+
+ display: inline;
+
+ span {
+ margin: 0 5px;
+ display: inline-block;
+ vertical-align: middle;
+ }
+
+ .oc-cw-remove-filter {
+ vertical-align: middle;
+ cursor: pointer;
+ }
+}
+
.oc-cw-searchbar .oc-cw-searchbar-container .oc-cw-searchbar-input {
padding: 8px;
width: 100%;
diff --git a/courseware/vueapp/components/CoursewareSearchBar.vue b/courseware/vueapp/components/CoursewareSearchBar.vue
index efc1180d..e81d0c10 100644
--- a/courseware/vueapp/components/CoursewareSearchBar.vue
+++ b/courseware/vueapp/components/CoursewareSearchBar.vue
@@ -1,12 +1,24 @@
+
+
+
+ -
+ {{ $gettext('Diese Veranstaltung') }}
+
+
+
@@ -26,19 +48,64 @@
export default {
name: "CoursewareSearchBar",
+ props: {
+ currentCourseSelectable: {
+ type: Boolean,
+ default: true,
+ },
+ showCurrentCourse: {
+ type: Boolean,
+ default: true,
+ },
+ },
+
+ emits: ['doSearch'],
+
data() {
return {
inputSearch: '',
+ showCourseSelector: false,
+ selectorPos: {
+ top: 0,
+ left: 0
+ },
timer: null,
delay: 800 //ms
}
},
methods: {
+ openCourseSelector() {
+ // filter needs to be selectable and not active
+ if (this.currentCourseSelectable && !this.showCurrentCourse) {
+ this.showCourseSelector = true;
+
+ this.selectorPos.top = this.$refs.searchbar.offsetTop + 30;
+ this.selectorPos.left = this.$refs.searchbar.offsetLeft;
+ }
+ },
+
+ // this is done in order to avoid hiding (and therefore deactivating the token selector)
+ // before the click-events of the token selector had a chance to fire
+ delayedHideCourseSelector() {
+ let view = this;
+
+ window.setTimeout(() => {
+ view.hideCourseSelector();
+ }, 200);
+ },
+
+ hideCourseSelector() {
+ this.showCourseSelector = false;
+ },
+
doSearch() {
clearTimeout(this.timer);
- this.$emit('doSearch', this.inputSearch);
+ this.$emit('doSearch', {
+ searchText: this.inputSearch,
+ showCurrentCourse: this.showCurrentCourse,
+ });
},
doLiveSearch() {
@@ -47,6 +114,23 @@ export default {
this.timer = setTimeout(() => {
this.doSearch();
}, this.delay);
+ },
+
+ selectCourse() {
+ this.showCurrentCourse = true;
+ this.hideCourseSelector();
+ this.doSearch();
+ },
+
+ removeCourse() {
+ this.showCurrentCourse = false;
+ this.doSearch();
+ }
+ },
+
+ updated() {
+ if (this.showCourseSelector) {
+ this.openCourseSelector();
}
},
}
diff --git a/courseware/vueapp/courseware-plugin-opencast-video.vue b/courseware/vueapp/courseware-plugin-opencast-video.vue
index 6ee17bdd..bded2317 100644
--- a/courseware/vueapp/courseware-plugin-opencast-video.vue
+++ b/courseware/vueapp/courseware-plugin-opencast-video.vue
@@ -36,6 +36,8 @@
Videos
video.token === this.currentVideoId);
},
@@ -168,8 +175,9 @@ export default {
};
},
- performSearch(searchText) {
+ performSearch({searchText, showCurrentCourse}) {
this.searchText = searchText;
+ this.showCurrentCourse = showCurrentCourse;
// this.resetPaging();
this.loadVideos();
},
@@ -217,6 +225,7 @@ export default {
},
initCurrentData() {
+ this.showCurrentCourse = this.isCourse;
this.currentVideoId = get(this.block, "attributes.payload.token", "");
this.currentEpisodeURL =STUDIP.ABSOLUTE_URI_STUDIP + 'plugins.php/opencastv3/redirect/perform/video/' + this.currentVideoId;
this.currentVisible = get(this.block, "attributes.payload.visible", "");
@@ -240,11 +249,24 @@ export default {
if (this.sortObj) {
params.append('order', this.sortObj.field + "_" + this.sortObj.order)
}
+
+ let filters = [];
if (this.searchText) {
- let filters = [{
+ filters.push({
type: 'text',
value: this.searchText
- }];
+ });
+ }
+
+ if (this.showCurrentCourse) {
+ filters.push({
+ type: 'course',
+ compare: '=',
+ value: this.context.id
+ });
+ }
+
+ if (filters.length > 0) {
params.append('filters', JSON.stringify(filters));
}
axios
diff --git a/lib/Models/Videos.php b/lib/Models/Videos.php
index 2d09b385..bc52a577 100644
--- a/lib/Models/Videos.php
+++ b/lib/Models/Videos.php
@@ -60,14 +60,14 @@ public static function getFilteredVideoIDs($user_id)
{
global $perm;
- if ($perm->have_perm('admin', $user_id)) {
+ if ($perm->have_perm('tutor', $user_id)) {
// get all courses and their playlists this user has access to. Only courses with activated OC plugin are included
$courses = Helpers::getMyCourses($user_id);
$stmt = \DBManager::get()->prepare($sql = 'SELECT oc_video.id FROM oc_video
JOIN oc_playlist_seminar ON (oc_playlist_seminar.seminar_id IN (:courses))
JOIN oc_playlist ON (oc_playlist_seminar.playlist_id = oc_playlist.id)
- JOIN oc_playlist_video ON (oc_playlist.id = oc_playlist_video.playlist_id)
+ JOIN oc_playlist_video ON (oc_playlist.id = oc_playlist_video.playlist_id AND oc_video.id = oc_playlist_video.video_id)
WHERE 1
');
@@ -190,8 +190,8 @@ public static function getUserVideos($filters, $user_id = null)
':user_id'=> $user_id
];
- if ($perm->have_perm('admin', $user_id)) {
- $where = ' WHERE oc_video.id IN (:video_ids) ';
+ if ($perm->have_perm('tutor', $user_id)) {
+ $where = ' WHERE oc_video.id IN (:video_ids) OR p.user_id = :user_id';
$params[':video_ids'] = self::getFilteredVideoIDs($user_id);
} else {
$sql = ' INNER JOIN oc_video_user_perms AS p ON (p.user_id = :user_id AND p.video_id = oc_video.id) ';