feat: component om een groep aan te maken
This commit is contained in:
parent
35faf7a80c
commit
05fa69f0c7
2 changed files with 81 additions and 12 deletions
41
frontend/src/components/GroupSelector.vue
Normal file
41
frontend/src/components/GroupSelector.vue
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, defineProps, defineEmits } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
students: Array,
|
||||||
|
});
|
||||||
|
const emit = defineEmits(['groupCreated']);
|
||||||
|
const { t } = useI18n();
|
||||||
|
const selectedStudents = ref([]);
|
||||||
|
|
||||||
|
const createGroup = () => {
|
||||||
|
if (selectedStudents.value.length) {
|
||||||
|
emit('groupCreated', selectedStudents.value);
|
||||||
|
selectedStudents.value = []; // Reset selection after creating group
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<v-card-text>
|
||||||
|
<v-combobox
|
||||||
|
v-model="selectedStudents"
|
||||||
|
:items="props.students"
|
||||||
|
:label="t('choose-groups')"
|
||||||
|
variant="solo"
|
||||||
|
clearable
|
||||||
|
multiple
|
||||||
|
hide-details
|
||||||
|
chips
|
||||||
|
append-inner-icon="mdi-magnify"
|
||||||
|
item-title="title"
|
||||||
|
item-value="value"
|
||||||
|
></v-combobox>
|
||||||
|
<v-btn @click="createGroup" color="primary" class="mt-2" size="small">{{ t('create-group') }}</v-btn>
|
||||||
|
</v-card-text>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,25 +1,21 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {useI18n} from "vue-i18n";
|
import {useI18n} from "vue-i18n";
|
||||||
import {computed, onMounted, ref, watch} from "vue";
|
import {computed, onMounted, ref, watch} from "vue";
|
||||||
|
import GroupSelector from "@/components/GroupSelector.vue";
|
||||||
|
|
||||||
const {t, locale} = useI18n();
|
const {t, locale} = useI18n();
|
||||||
|
|
||||||
const language = ref(locale.value);
|
const language = ref(locale.value);
|
||||||
|
|
||||||
// If this value is set to true, the search bar will display a "loading" animation
|
|
||||||
const loading = ref(false);
|
|
||||||
const searchQuery = ref("");
|
const searchQuery = ref("");
|
||||||
|
|
||||||
// Store all learning paths
|
|
||||||
const allLearningPaths = ref([]);
|
const allLearningPaths = ref([]);
|
||||||
|
|
||||||
// Filtered learning paths that will be displayed in the search bar dropdown
|
|
||||||
const filteredLearningPaths = ref([]);
|
const filteredLearningPaths = ref([]);
|
||||||
|
|
||||||
// The hruid and title of the currently selected learning path(TODO: use for post req)
|
|
||||||
const selectedLearningPath = ref(null);
|
const selectedLearningPath = ref(null);
|
||||||
|
const allClasses = ref(["f", "r"]);
|
||||||
const selectedClasses = ref([]);
|
const selectedClasses = ref([]);
|
||||||
|
const allStudents = ref([]); // Fetched students from each selected class
|
||||||
|
const groups = ref<string[][]>([]); // Each group is a list of student {names, id's}
|
||||||
|
|
||||||
// Fetch all learning paths initially
|
// Fetch all learning paths initially
|
||||||
async function fetchAllLearningPaths() {
|
async function fetchAllLearningPaths() {
|
||||||
|
@ -63,11 +59,21 @@
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const classes = computed(() => ["f", "r"]);
|
|
||||||
|
|
||||||
// Fetch all learning paths on mount
|
// Fetch all learning paths on mount
|
||||||
onMounted(fetchAllLearningPaths);
|
onMounted(fetchAllLearningPaths);
|
||||||
|
|
||||||
|
// All students that aren't already in a group
|
||||||
|
const availableStudents = computed(() => {
|
||||||
|
const groupedStudents = new Set(groups.value.flat());
|
||||||
|
return allStudents.value.filter(student => !groupedStudents.has(student));
|
||||||
|
});
|
||||||
|
|
||||||
|
const addGroupToList = (students: string[]) => {
|
||||||
|
if (students.length) {
|
||||||
|
groups.value.push(students);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -85,7 +91,6 @@
|
||||||
clearable
|
clearable
|
||||||
hide-details
|
hide-details
|
||||||
density="compact"
|
density="compact"
|
||||||
:loading="loading"
|
|
||||||
append-inner-icon="mdi-magnify"
|
append-inner-icon="mdi-magnify"
|
||||||
item-title="title"
|
item-title="title"
|
||||||
item-value="value"
|
item-value="value"
|
||||||
|
@ -96,7 +101,7 @@
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-combobox
|
<v-combobox
|
||||||
v-model="selectedClasses"
|
v-model="selectedClasses"
|
||||||
:items="classes"
|
:items="allClasses"
|
||||||
:label="t('choose-classes')"
|
:label="t('choose-classes')"
|
||||||
variant="solo"
|
variant="solo"
|
||||||
clearable
|
clearable
|
||||||
|
@ -109,6 +114,29 @@
|
||||||
></v-combobox>
|
></v-combobox>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-container>
|
||||||
|
<h3>{{ t('create-groups') }}</h3>
|
||||||
|
|
||||||
|
<GroupSelector
|
||||||
|
:students="availableStudents"
|
||||||
|
@groupCreated="addGroupToList"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Counter for created groups -->
|
||||||
|
<v-card-text v-if="groups.length">
|
||||||
|
<strong>{{ t('created-groups') }}: {{ groups.length }}</strong>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<!-- Display created groups -->
|
||||||
|
<v-card-text v-if="groups.length">
|
||||||
|
<ul>
|
||||||
|
<li v-for="(group, index) in groups" :key="index">
|
||||||
|
{{ group.join(', ') }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</v-card-text>
|
||||||
|
</v-container>
|
||||||
|
|
||||||
</v-container>
|
</v-container>
|
||||||
<v-btn class="mt-2" type="submit" block>Submit</v-btn>
|
<v-btn class="mt-2" type="submit" block>Submit</v-btn>
|
||||||
</v-form>
|
</v-form>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue