aboutsummaryrefslogtreecommitdiff
path: root/resources/vue/components/courseware/CoursewareBlockCommentsOverview.vue
blob: 6d108d41cb94a91cd28d17bacf46af1d4319285c (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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
<template>
    <div class="cw-block-comments-overview-wrapper">
        <table class="default">
            <caption>
                {{ $gettext('Blöcke') }}
            </caption>
            <colgroup>
                <col style="width: 16em">
                <col style="width: 16em">
                <col style="width: 8em">
                <col class="responsive-hidden" style="width: 8em">
                <col class="responsive-hidden" style="width: 8em">
                <col style="width: 2em">
            </colgroup>
            <thead>
                <tr class="sortable">
                    <th :class="getSortClass('units')" @click="sort('units')">
                        <a href="#">{{ $gettext('Lernmaterial') }}</a>
                    </th>
                    <th :class="getSortClass('structural-elements')" @click="sort('structural-elements')">
                        <a href="#">{{ $gettext('Seite') }}</a>
                    </th>
                    <th :class="getSortClass('blocks')" @click="sort('blocks')">
                        <a href="#">{{ $gettext('Blocktyp') }}</a>
                    </th>
                    <th class="responsive-hidden" :class="getSortClass('comments')" @click="sort('comments')">
                        <a href="#">{{ $gettext('Kommentare') }}</a>
                    </th>
                    <th class="responsive-hidden" :class="getSortClass('feedback')" @click="sort('feedback')">
                        <a href="#">{{ $gettext('Anmerkungen') }}</a>
                    </th>
                    <th class="actions">
                        {{ $gettext('Aktionen') }}
                    </th>
                </tr>
            </thead>
            <tbody v-if="filteredBlocks.length > 0">
                <tr v-for="block in filteredBlocks" :key="block.id">
                    <td>{{ block.unitName }}</td>
                    <td>
                        <a :href="block.elementURL">
                            {{ block.element.attributes.title }}
                        </a>
                    </td>
                    <td>{{ block.attributes.title }}</td>
                    <td class="responsive-hidden">
                        <a
                            href="#"
                            @click.prevent="enableCommentsDialog(block)">
                            {{ $ngettext(
                                '%{length} Kommentar',
                                '%{length} Kommentare',
                                block.comments.length,
                                { length: block.comments.length }
                            ) }}
                        </a>
                    </td>
                    <td class="responsive-hidden">
                        <a
                            v-if="block.element.attributes['can-edit']"
                            href="#"
                            @click.prevent="enableFeedbackDialog(block)"
                            >
                            {{ $ngettext(
                                '%{length} Anmerkung',
                                '%{length} Anmerkungen',
                                block.feedbacks.length,
                                { length: block.feedbacks.length }
                            ) }}
                        </a>
                        <template v-else>
                            -
                        </template>
                    </td>
                    <td class="actions">
                        <studip-action-menu
                            :items="getMenuItems(block)"
                            :context="$gettext('Blöcke')"
                            @showComments="enableCommentsDialog(block)"
                            @showFeedback="enableFeedbackDialog(block)"
                        />
                    </td>
                </tr>
            </tbody>
            <tbody v-else>
                <tr class="empty">
                    <td colspan="6">
                        {{ $gettext('Es wurden keine Kommentare oder Anmerkungen gefunden') }}
                    </td>
                </tr>
            </tbody>
        </table>
        <courseware-comments-overview-dialog
            v-if="showCommentsDialog"
            item-type="block"
            com-type="comment"
            :item="currentDialogBlock"
            @close="closeCommentsDialog"
        />
        <courseware-comments-overview-dialog
            v-if="showFeedbackDialog"
            item-type="block"
            com-type="feedback"
            :item="currentDialogBlock"
            @close="closeFeedbackDialog"
        />
    </div>
</template>

<script>
import CoursewareCommentsOverviewDialog from './CoursewareCommentsOverviewDialog.vue';
import commentsOverviewMixin from '@/vue/mixins/courseware/comments-overview-helper.js';
import { mapGetters } from 'vuex';

export default {
    name: 'courseware-block-comments-overview',
    components: {
        CoursewareCommentsOverviewDialog
    },
    mixins: [commentsOverviewMixin],
    data() {
        return {
            blocksWithRelations: [],
            currentDialogBlock: null,
            showCommentsDialog: false,
            showFeedbackDialog: false,
            sortBy: 'units',
            sortASC: true,
        }
    },
    computed: {
        ...mapGetters({
            units: 'courseware-units/all',
            elements: 'courseware-structural-elements/all',
            containers: 'courseware-containers/all',
            blocks: 'courseware-blocks/all',
            blockComments: 'courseware-block-comments/all',
            blockFeedbacks: 'courseware-block-feedback/all',
            elementComments: 'courseware-structural-element-comments/all',
            elementFeedbacks: 'courseware-structural-element-feedback/all',
            containerById: 'courseware-containers/byId',
            elementById: 'courseware-structural-elements/byId',
            unitById: 'courseware-units/byId',
            context: 'context',
            createdFilter: 'createdFilter',
            unitFilter: 'unitFilter'
        }),

        filteredBlocks() {
            let filteredBlocks = this.blocksWithRelations;
            if (this.unitFilter !== 'all') {
                filteredBlocks = filteredBlocks.filter(block => block.unit.id === this.unitFilter);
            }
            if (this.createdFilter !== 'all') {
                filteredBlocks = filteredBlocks.filter(block => block.comments[this.createdFilter] > 0);
            }

            return this.sortBlocks(filteredBlocks);
        },
    },
    methods: {
        collectBlockRelations() {
            this.blocksWithRelations = _.cloneDeep(this.blocks);
            this.blocksWithRelations.forEach(block => {
                block.container = this.containerById({ id:block.relationships.container.data.id });
                block.element = this.elementById({ id: block.container.relationships['structural-element'].data.id });
                block.unit = this.unitById({ id: block.element.relationships.unit.data.id });
                const unitRoot = this.elementById({ id: block.unit.relationships['structural-element'].data.id});
                block.unitName = unitRoot.attributes.title;
                block.elementURL = STUDIP.URLHelper.getURL(`dispatch.php/course/courseware/courseware/${block.unit.id}?cid=${this.context.id}#/structural_element/${block.element.id}`);
                block.comments = this.blockComments.filter(comment => comment.relationships.block.data.id === block.id);
                block.comments.oneDay = 0;
                block.comments.oneWeek = 0;
                block.comments.forEach(comment => {
                    comment.created = this.calcCreated(comment.attributes.mkdate);
                    if (comment.created.oneDay) {
                        block.comments.oneDay++;
                    }
                    if (comment.created.oneWeek) {
                        block.comments.oneWeek++;
                    }
                });
                block.feedbacks = this.blockFeedbacks.filter(feedback => feedback.relationships.block.data.id === block.id);
                block.feedbacks.forEach(feedback => {
                    feedback.created = this.calcCreated(feedback.attributes.mkdate);
                });
            });
        },
        enableCommentsDialog(block) {
            this.currentDialogBlock = block;
            this.showCommentsDialog = true;
        },
        closeCommentsDialog() {
            this.collectBlockRelations();
            this.showCommentsDialog = false;
            this.currentDialogBlock = null;
        },
        enableFeedbackDialog(block) {
            this.currentDialogBlock = block;
            this.showFeedbackDialog = true;
        },
        closeFeedbackDialog() {
            this.collectBlockRelations();
            this.showFeedbackDialog = false;
            this.currentDialogBlock = null;
        },
        getMenuItems(block) {
            let menuItems = [];
            menuItems.push({ id: 1, label: this.$gettext('Kommentare anzeigen'), icon: 'comment2', emit: 'showComments' });
            if (block.element.attributes['can-edit']) {
                menuItems.push({ id: 2, label: this.$gettext('Anmerkungen anzeigen'), icon: 'comment2', emit: 'showFeedback' });
            }

            return menuItems;
        },
        sort(sortBy) {
            if (this.sortBy === sortBy) {
                this.sortASC = !this.sortASC;
            } else {
                this.sortBy = sortBy;
            }
        },
        getSortClass(col) {
            if (col === this.sortBy) {
                return this.sortASC ? 'sortasc' : 'sortdesc';
            }
        },
        sortBlocks(blocks) {
            switch (this.sortBy) {
                case 'units':
                    blocks = blocks.sort((a, b) => {
                        if (this.sortASC) {
                            return a.unitName < b.unitName ? -1 : 1;
                        } else {
                            return a.unitName > b.unitName ? -1 : 1;
                        }
                    });
                    break;
                case 'structural-elements':
                    blocks = blocks.sort((a, b) => {
                        if (this.sortASC) {
                            return a.element.attributes.title < b.element.attributes.title ? -1 : 1;
                        } else {
                            return a.element.attributes.title > b.element.attributes.title ? -1 : 1;
                        }
                    });
                    break;
                case 'blocks':
                    blocks = blocks.sort((a, b) => {
                        if (this.sortASC) {
                            return a.attributes.title < b.attributes.title ? -1 : 1;
                        } else {
                            return a.attributes.title > b.attributes.title ? -1 : 1;
                        }
                    });
                    break;
                case 'comments':
                    blocks = blocks.sort((a, b) => {
                        if (this.sortASC) {
                            return a.comments.length - b.comments.length;
                        } else {
                            return  b.comments.length - a.comments.length;
                        }
                    });
                    break;
                case 'feedback':
                        blocks = blocks.sort((a, b) => {
                            if (this.sortASC) {
                                return a.feedbacks.length - b.feedbacks.length;
                            } else {
                                return  b.feedbacks.length - a.feedbacks.length;
                            }
                        });
                    break;
            }

            return blocks;
        },
    },
    mounted() {
        this.$nextTick(() => {
            this.collectBlockRelations();
        });
    }
}
</script>