diff --git a/frontend/src/api.ts b/frontend/src/api.ts index 9933c8bfc9819bd3581d559ccd0d54631ac832f5..2197ebe9d8f5bb4f10c1dd74584b85fd5334dd0e 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -213,6 +213,10 @@ export async function changeActiveForUser (userPk: string, active: boolean): Pro return (await ax.patch(`/api/user/${userPk}/change_active/`, { 'is_active': active })).data } +export async function fetchUsers (): Promise<UserAccount[]> { + return (await ax.get('api/user/')).data +} + export async function getLabels (): Promise<FeedbackLabel[]> { return (await ax.get('/api/label/')).data } diff --git a/frontend/src/components/student_list/StudentList.vue b/frontend/src/components/student_list/StudentList.vue index 6d01d081bfd697f3a5fc2c808f183b162de3733f..f558aed92d23d5461206adbb194372c15c16e93c 100644 --- a/frontend/src/components/student_list/StudentList.vue +++ b/frontend/src/components/student_list/StudentList.vue @@ -6,6 +6,18 @@ </v-toolbar-title> <v-spacer /> <v-toolbar-items /> + <v-select + v-model="selectedGroup" + :items="groups" + item-text="name" + label="Group" + single-line + return-object + hide-details + clearable + flat + class="mr-6" + /> <v-text-field v-model="search" append-icon="search" @@ -129,9 +141,11 @@ import { mapActions, mapState } from 'vuex' import StudentListMenu from '@/components/student_list/StudentListMenu' import StudentListReverseMapper from '@/components/student_list/StudentListReverseMapper' -import { changeActiveForUser } from '@/api' +import { changeActiveForUser, fetchUser } from '@/api' import { getters } from '@/store/getters' import { Authentication } from '@/store/modules/authentication' +import { Assignments } from '@/store/modules/assignments' +import * as api from '@/api' export default { name: 'StudentList', @@ -142,6 +156,9 @@ export default { return { loading: true, search: '', + selectedGroup: null, + userData: [], + userMap: null } }, computed: { @@ -186,7 +203,14 @@ export default { }, studentListItems () { if (!this.loading) { - return Object.values(this.students).map(student => { + let filteredStudents = this.students + if (this.selectedGroup !== null) { + filteredStudents = Object.values(filteredStudents).filter(student => { + let userGroups = this.userMap.get(student.userPk) + return userGroups.some(group => group.pk === this.selectedGroup.pk) + }) + } + return Object.values(filteredStudents).map(student => { return { pk: student.pk, user: student.user, @@ -202,10 +226,27 @@ export default { } return [] - } + }, + groups () { + return Assignments.state.groups.slice().sort((a, b) => { + const matches_a = a.name.match(/(\d+)/) + const number_a = Number(matches_a === null ? 0 : matches_a[1]) + + const matches_b = b.name.match(/(\d+)/) + const number_b = Number(matches_b === null ? 0 : matches_b[1]) + + return (number_a<number_b?-1:(number_a>number_b?1:0)) + }) + }, }, created () { + this.getUserData() this.getStudents().then(() => { this.loading = false }) + const ownGroup = Authentication.state.user.exerciseGroups[0] + if (ownGroup !== undefined) { + this.selectedGroup = ownGroup + } + const groups = Assignments.getGroups() }, methods: { ...mapActions([ @@ -245,6 +286,14 @@ export default { }, showSubmissionDetails () { this.$emit('detail-click') + }, + async getUserData() { + this.userData = await api.fetchUsers() + this.userMap = new Map() + var that = this // javascript this is not the same in forEach + this.userData.forEach(user => { + that.userMap.set(user.pk, user.exerciseGroups) + }) } }, }