aboutsummaryrefslogtreecommitdiff
path: root/resources/vue/components/my-courses/TableView.vue
blob: f8ffa8557e3beecbb0abad3c6b1177a39130d7a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<template>
    <div id="my_seminars">
        <table class="default collapsable mycourses" v-for="group in groups" :key="group.id">
            <caption> {{ group.name }}</caption>
            <colgroup>
                <col style="width: 7px">
                <col style="width: 25px">
                <col style="width: 70px" v-if="displaySemNumber">
                <col>
                <col v-if="!responsiveDisplay" :style="{width: (2 * 5 + numberOfNavElements * (iconSize + 2 * 3 + 3) - 3) + 'px'}">
                <col v-if="!responsiveDisplay" style="width: 24px">
            </colgroup>
            <thead>
                <tr class="sortable">
                    <th>
                        <span class="sr-only">
                            {{ $gettext('Zugeordnete Farbgruppe') }}
                        </span>
                    </th>
                    <th></th>
                    <th v-if="displaySemNumber" :class="getOrderClasses('number')">
                        <a href="#" @click.prevent="changeOrder('number')">
                            {{ $gettext('Nr.') }}
                        </a>
                    </th>
                    <th :class="getOrderClasses('name')">
                        <a href="#" @click.prevent="changeOrder('name')">
                            {{ $gettext('Name') }}
                        </a>
                    </th>
                    <th v-if="!responsiveDisplay" >{{ $gettext('Inhalt') }}</th>
                    <th v-if="!responsiveDisplay"></th>
                </tr>
            </thead>
            <tbody v-for="subgroup in group.data" :key="subgroup.id" :class="{collapsed: !isGroupOpen(subgroup)}">
                <tr class="header-row" v-if="subgroup.label !== false">
                    <th style="white-space: nowrap; text-align: left"></th>
                    <th class="toggle-indicator" :colspan="displaySemNumber ? 3 : 2">
                        <a href="#" @click.prevent.stop="toggleOpenGroup(subgroup)">{{ subgroup.label }}</a>
                    </th>
                    <th v-if="!responsiveDisplay" class="dont-hide" colspan="2"></th>
                </tr>
                <tr v-for="course in getOrderedCourses(subgroup.ids)" :data-course-id="course.id" :class="getCourseClasses(course)" :key="course.id">
                    <td :class="`gruppe${course.group}`">
                        <span class="sr-only">
                            {{ $gettext(
                                'Diese Veranstaltung gehört zur Farbgruppe %{group}',
                                course
                            ) }}
                        </span>
                    </td>
                    <td :class="{'subcourse-indented': isChild(course)}">
                        <span :style="{backgroundImage: `url(${course.avatar}`}" class="my-courses-avatar course-avatar-small" :title="course.name" alt=""></span>
                    </td>
                    <td v-if="displaySemNumber"  :class="{'subcourse-indented': isChild(course)}">
                        {{ course.number }}
                    </td>
                    <td :class="{'subcourse-indented': isChild(course)}">
                        <a :href="getCourseURL(course)">
                            {{ getCourseName(course) }}
                        </a>
                        <span v-if="course.is_hidden" class="course-hidden-info">
                            {{ $gettext('[versteckt]') }}
                            <studip-tooltip-icon :text="getHiddenTooltip(course)"></studip-tooltip-icon>
                        </span>
                        <div v-if="responsiveDisplay" class="mycourse_elements">
                            <div class="special_nav">
                                <studip-action-menu :items="getActionMenuForCourse(course)"
                                                    :collapseAt="false"
                                                    v-on:show-color-picker="shownColorPicker = course.id"
                                ></studip-action-menu>
                            </div>

                            <navigation :navigation="getNavigationForCourse(course)" :icon-size="iconSize"></navigation>
                        </div>
                    </td>
                    <td v-if="!responsiveDisplay" class="course-navigation">
                        <navigation :navigation="getNavigationForCourse(course, true)" :icon-size="iconSize"></navigation>
                    </td>
                    <td v-if="!responsiveDisplay" class="actions">
                        <studip-action-menu :items="getActionMenuForCourse(course)"></studip-action-menu>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

<script>
import MyCoursesMixin from '../../mixins/MyCoursesMixin.js';

const defaultIconSize = parseInt(
    getComputedStyle(document.body).getPropertyValue('--icon-size-default'),
    10
);

export default {
    name: 'TableView',
    mixins: [MyCoursesMixin],
    props: {
        iconSize: {
            type: Number,
            required: false,
            default: defaultIconSize
        }
    },
    data () {
        return {
            orderBy: 'group',
            orderDir: 'asc'
        }
    },
    methods: {
        changeOrder (by) {
            if (this.orderBy === by) {
                this.orderDir = this.orderDir === 'asc' ? 'desc' : 'asc';
            } else {
                this.orderBy = by;
                this.orderDir = 'asc';
            }
        },
        getCourseClasses (course) {
            return {
                'has-subcourses': this.isParent(course),
                subcourses: this.isChild(course),
            };
        },
        getOrderedCourses (ids) {
            const sorted = this.getCourses(ids);
            const dirFactor = this.orderDir === 'desc' ? -1 : 1;
            if (this.orderBy === 'name') {
                sorted.sort((a, b) => a.name.localeCompare(b.name) * dirFactor);
            } else if (this.orderBy === 'number') {
                sorted.sort((a, b) => a.number.localeCompare(b.number) * dirFactor);
            }

            // Ensure parent / child relation
            let courses = [];
            sorted.forEach(course => {
                if (!this.isChild(course)) {
                    courses.push(course);
                }
            });

            return courses;
        },
        getOrderClasses (by) {
            if (by !== this.orderBy) {
                return [];
            }
            return this.orderDir === 'asc' ? ['sortasc'] : ['sortdesc'];
        }
    }
}
</script>