Skip to content
Snippets Groups Projects
Commit c4a72c16 authored by Ron Lucke's avatar Ron Lucke Committed by David Siegfried
Browse files

Add aria-label to task wizard

Merge request studip/studip!1301
parent ec59a188
No related branches found
No related tags found
No related merge requests found
......@@ -22,8 +22,12 @@
:key="'radio-' + unit.id"
:aria-description="unit.element.attributes.title"
/>
<label @click="selectedSourceUnit = unit" :key="'label-' + unit.id" :for="'cw-task-dist-source-unit' + unit.id">
<div class="icon"><studip-icon shape="courseware" size="32"/></div>
<label
@click="selectedSourceUnit = unit"
:key="'label-' + unit.id"
:for="'cw-task-dist-source-unit' + unit.id"
>
<div class="icon"><studip-icon shape="courseware" size="32" /></div>
<div class="text">{{ unit.element.attributes.title }}</div>
<studip-icon shape="radiobutton-unchecked" size="24" class="unchecked" />
<studip-icon shape="check-circle" size="24" class="check" />
......@@ -40,32 +44,27 @@
<template v-slot:task>
<form v-if="selectedSourceUnit" class="default" @submit.prevent="">
<fieldset class="radiobutton-set">
<input id="cw-task-dist-task" type="radio" :checked="selectedTaskIsTask" :aria-description="selectedTaskTitle"/>
<label for="cw-task-dist-task" @click="e => e.preventDefault()">
<div class="icon"><studip-icon shape="content2" size="32"/></div>
<input
id="cw-task-dist-task"
type="radio"
:checked="selectedTaskIsTask"
:aria-description="selectedTaskTitle"
/>
<label for="cw-task-dist-task" @click="(e) => e.preventDefault()">
<div class="icon"><studip-icon shape="content2" size="32" /></div>
<div class="text">{{ selectedTaskTitle }}</div>
<studip-icon v-if="selectedTaskIsTask" shape="check-circle" size="24" class="check" />
<studip-icon v-else shape="decline-circle" size="24" class="unchecked" />
</label>
</fieldset>
<button
v-if="selectedTaskParent"
class="button"
@click="selectTask(selectedTaskParent.id)"
>
{{ $gettext('zurück zur übergeordneten Seite') }}
<button v-if="selectedTaskParent" class="button" @click="selectTask(selectedTaskParent.id)">
{{ $gettext('zurück zur übergeordneten Seite') }}
</button>
<fieldset>
<legend>{{ $gettext('Unterseiten') }}</legend>
<ul class="cw-element-selector-list">
<li
v-for="child in taskChildren"
:key="child.id"
>
<button
class="cw-element-selector-item"
@click="selectTask(child.id)"
>
<li v-for="child in taskChildren" :key="child.id">
<button class="cw-element-selector-item" @click="selectTask(child.id)">
{{ child.attributes.title }}
</button>
</li>
......@@ -76,19 +75,21 @@
</fieldset>
</form>
<courseware-companion-box
v-else
mood="pointing"
:msgCompanion="$gettext('Bitte wählen Sie ein Lernmaterial aus.')"
v-else
mood="pointing"
:msgCompanion="$gettext('Bitte wählen Sie ein Lernmaterial aus.')"
/>
</template>
<template v-slot:tasksettings>
<form v-if="selectedTaskIsTask" class="default" @submit.prevent="">
<label>
<span>{{ $gettext('Aufgabentitel') }}</span><span aria-hidden="true" class="wizard-required">*</span>
<input type="text" v-model="taskTitle" required/>
<span>{{ $gettext('Aufgabentitel') }}</span>
<span aria-hidden="true" class="wizard-required">*</span>
<input type="text" v-model="taskTitle" required />
</label>
<label>
<span>{{ $gettext('Abgabefrist') }}</span><span aria-hidden="true" class="wizard-required">*</span>
<span>{{ $gettext('Abgabefrist') }}</span>
<span aria-hidden="true" class="wizard-required">*</span>
<input type="date" v-model="submissionDate" />
</label>
<label>
......@@ -118,8 +119,12 @@
:key="'radio-' + unit.id"
:aria-description="unit.element.attributes.title"
/>
<label @click="selectedTargetUnit = unit" :key="'label-' + unit.id" :for="'cw-task-dist-target-unit' + unit.id">
<div class="icon"><studip-icon shape="courseware" size="32"/></div>
<label
@click="selectedTargetUnit = unit"
:key="'label-' + unit.id"
:for="'cw-task-dist-target-unit' + unit.id"
>
<div class="icon"><studip-icon shape="courseware" size="32" /></div>
<div class="text">{{ unit.element.attributes.title }}</div>
<studip-icon shape="radiobutton-unchecked" size="24" class="unchecked" />
<studip-icon shape="check-circle" size="24" class="check" />
......@@ -141,9 +146,14 @@
<template v-slot:targetelement>
<form v-if="selectedTargetUnit && selectedTaskIsTask" class="default" @submit.prevent="">
<fieldset class="radiobutton-set">
<input id="cw-task-dist-target-element" type="radio" checked :aria-description="selectedTargetElementTitle"/>
<label for="cw-task-dist-target-element" @click="e => e.preventDefault()">
<div class="icon"><studip-icon shape="content2" size="32"/></div>
<input
id="cw-task-dist-target-element"
type="radio"
checked
:aria-description="selectedTargetElementTitle"
/>
<label for="cw-task-dist-target-element" @click="(e) => e.preventDefault()">
<div class="icon"><studip-icon shape="content2" size="32" /></div>
<div class="text">{{ selectedTargetElementTitle }}</div>
<studip-icon shape="check-circle" size="24" class="check" />
</label>
......@@ -153,19 +163,13 @@
class="button"
@click="selectTargetElement(selectedTargetElementParent.id)"
>
{{ $gettext('zurück zur übergeordneten Seite') }}
{{ $gettext('zurück zur übergeordneten Seite') }}
</button>
<fieldset>
<legend>{{ $gettext('Unterseiten') }}</legend>
<ul class="cw-element-selector-list">
<li
v-for="child in targetChildren"
:key="child.id"
>
<button
class="cw-element-selector-item"
@click="selectTargetElement(child.id)"
>
<li v-for="child in targetChildren" :key="child.id">
<button class="cw-element-selector-item" @click="selectTargetElement(child.id)">
{{ child.attributes.title }}
</button>
</li>
......@@ -195,7 +199,7 @@
<option value="group">{{ $gettext('Gruppen') }}</option>
</select>
</label>
<template v-if="taskSolverType === 'autor'" >
<template v-if="taskSolverType === 'autor'">
<courseware-companion-box
v-show="autor_members.length === 0"
:msgCompanion="$gettext('Es wurden keine Studierenden in dieser Veranstaltung gefunden.')"
......@@ -204,13 +208,30 @@
<table v-show="autor_members.length > 0" class="default">
<thead>
<tr>
<th><input type="checkbox" v-model="bulkSelectAutors"/></th>
<th>
<input
type="checkbox"
v-model="bulkSelectAutors"
:aria-label="$gettext('Alle Studierende auswählen')"
/>
</th>
<th>{{ $gettext('Name') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="user in autor_members" :key="user.user_id">
<td><input type="checkbox" v-model="selectedAutors" :value="user.user_id" /></td>
<td>
<input
type="checkbox"
v-model="selectedAutors"
:value="user.user_id"
:aria-label="
$gettextInterpolate($gettext('%{userName} auswählen'), {
userName: user.formattedname,
})
"
/>
</td>
<td>{{ user.formattedname }}</td>
</tr>
</tbody>
......@@ -225,13 +246,30 @@
<table v-show="groups.length > 0" class="default">
<thead>
<tr>
<th><input type="checkbox" v-model="bulkSelectGroups"/></th>
<th>
<input
type="checkbox"
v-model="bulkSelectGroups"
:aria-label="$gettext('Alle Gruppen auswählen')"
/>
</th>
<th>{{ $gettext('Gruppenname') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="group in groups" :key="group.id">
<td><input type="checkbox" v-model="selectedGroups" :value="group.id" /></td>
<td>
<input
type="checkbox"
v-model="selectedGroups"
:value="group.id"
:aria-label="
$gettextInterpolate($gettext('%{groupName} auswählen'), {
groupName: group.name,
})
"
/>
</td>
<td>{{ group.name }}</td>
</tr>
</tbody>
......@@ -256,7 +294,7 @@
import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
import StudipWizardDialog from './../StudipWizardDialog.vue';
import { mapActions, mapGetters } from 'vuex'
import { mapActions, mapGetters } from 'vuex';
export default {
name: 'courseware-tasks-dialog-distribute',
......@@ -267,18 +305,66 @@ export default {
data() {
return {
wizardSlots: [
{ id: 1, valid: false, name: 'sourceunit', title: this.$gettext('Lernmaterial'), icon: 'courseware',
description: this.$gettext('Wählen Sie das Lernmaterial aus, in dem sich die Aufgabenvorlage befindet. Es sind nur Lernmaterialien aus Ihrem Arbeitsplatz aufgeführt.') },
{ id: 2, valid: false, name: 'task', title: this.$gettext('Aufgabenvorlage'), icon: 'category-task',
description: this.$gettext('Wählen Sie die zu verteilende Aufgabenvorlage aus. Vorausgewählt ist die oberste Seite des ausgewählten Lernmaterials. Unterseiten erreichen Sie über die Schaltflächen im Bereich "Unterseiten". Sie können über die "zurück zu" Schaltfläche das übergeordnete Element anwählen. Die ausgewählte Aufgabenvorlage ist mit einem Kontrollhaken markiert. Nur Seiten der Kategorie "Aufgabenvorlage" können verteilt werden.') },
{ id: 3, valid: false, name: 'tasksettings', title: this.$gettext('Aufgabeneinstellungen'), icon: 'settings',
description: this.$gettext('Wählen Sie hier die Einstellungen der Aufgabe. Es muss ein Aufgabentitel und eine Abgabenfrist gesetzt werden.') },
{ id: 4, valid: false, name: 'targetunit', title: this.$gettext('Ziel-Lernmaterial'), icon: 'courseware',
description: this.$gettext('Wählen Sie hier das Lernmaterial aus, in das die Aufgabe verteilt werden soll. Zum Bearbeiten der Aufgabe müssen Lernende Zugriff auf das Lernmaterial haben. Prüfen Sie gegebenenfalls die Leserechte und die Sichtbarkeit.') },
{ id: 5, valid: false, name: 'targetelement', title: this.$gettext('Zielseite'), icon: 'content2',
description: this.$gettext('Wählen Sie hier die Seite aus unterhalb der die Aufgabe verteilt werden soll. Zum bearbeiten der Aufgabe müssen Lernende Zugriff auf die Seite haben. Prüfen Sie ggf. die Leserechte und die Sichtbarkeit.') },
{ id: 6, valid: false, name: 'solver', title: this.$gettext('Aufgabe zuweisen'), icon: 'group3',
description: this.$gettext('Wählen Sie hier aus, an wen Sie die Aufgaben verteilen möchten. Aufgaben können entweder an Gruppen oder einzelne Teilnehmende verteilt werden. Über die Checkbox im Titel der Tabelle können Sie alles aus- bzw. abwählen.') },
{
id: 1,
valid: false,
name: 'sourceunit',
title: this.$gettext('Lernmaterial'),
icon: 'courseware',
description: this.$gettext(
'Wählen Sie das Lernmaterial aus, in dem sich die Aufgabenvorlage befindet. Es sind nur Lernmaterialien aus Ihrem Arbeitsplatz aufgeführt.'
),
},
{
id: 2,
valid: false,
name: 'task',
title: this.$gettext('Aufgabenvorlage'),
icon: 'category-task',
description: this.$gettext(
'Wählen Sie die zu verteilende Aufgabenvorlage aus. Vorausgewählt ist die oberste Seite des ausgewählten Lernmaterials. Unterseiten erreichen Sie über die Schaltflächen im Bereich "Unterseiten". Sie können über die "zurück zu" Schaltfläche das übergeordnete Element anwählen. Die ausgewählte Aufgabenvorlage ist mit einem Kontrollhaken markiert. Nur Seiten der Kategorie "Aufgabenvorlage" können verteilt werden.'
),
},
{
id: 3,
valid: false,
name: 'tasksettings',
title: this.$gettext('Aufgabeneinstellungen'),
icon: 'settings',
description: this.$gettext(
'Wählen Sie hier die Einstellungen der Aufgabe. Es muss ein Aufgabentitel und eine Abgabenfrist gesetzt werden.'
),
},
{
id: 4,
valid: false,
name: 'targetunit',
title: this.$gettext('Ziel-Lernmaterial'),
icon: 'courseware',
description: this.$gettext(
'Wählen Sie hier das Lernmaterial aus, in das die Aufgabe verteilt werden soll. Zum Bearbeiten der Aufgabe müssen Lernende Zugriff auf das Lernmaterial haben. Prüfen Sie gegebenenfalls die Leserechte und die Sichtbarkeit.'
),
},
{
id: 5,
valid: false,
name: 'targetelement',
title: this.$gettext('Zielseite'),
icon: 'content2',
description: this.$gettext(
'Wählen Sie hier die Seite aus unterhalb der die Aufgabe verteilt werden soll. Zum bearbeiten der Aufgabe müssen Lernende Zugriff auf die Seite haben. Prüfen Sie ggf. die Leserechte und die Sichtbarkeit.'
),
},
{
id: 6,
valid: false,
name: 'solver',
title: this.$gettext('Aufgabe zuweisen'),
icon: 'group3',
description: this.$gettext(
'Wählen Sie hier aus, an wen Sie die Aufgaben verteilen möchten. Aufgaben können entweder an Gruppen oder einzelne Teilnehmende verteilt werden. Über die Checkbox im Titel der Tabelle können Sie alles aus- bzw. abwählen.'
),
},
],
selectedSourceUnit: null,
taskTitle: '',
......@@ -293,7 +379,7 @@ export default {
selectedGroups: [],
bulkSelectGroups: false,
requirements: [],
}
};
},
computed: {
...mapGetters({
......@@ -314,8 +400,8 @@ export default {
return this.selectedSourceUnit?.relationships?.['structural-element']?.data?.id;
},
sourceUnits() {
let units = this.coursewareUnits.filter(unit => unit.relationships.range.data.id === this.userId);
units.forEach(unit => {
let units = this.coursewareUnits.filter((unit) => unit.relationships.range.data.id === this.userId);
units.forEach((unit) => {
unit.element = this.getUnitElement(unit);
});
......@@ -328,8 +414,8 @@ export default {
return this.selectedTargetUnit?.relationships?.['structural-element']?.data?.id;
},
targetUnits() {
let units = this.coursewareUnits.filter(unit => unit.relationships.range.data.id === this.context.id);
units.forEach(unit => {
let units = this.coursewareUnits.filter((unit) => unit.relationships.range.data.id === this.context.id);
units.forEach((unit) => {
unit.element = this.getUnitElement(unit);
});
......@@ -343,8 +429,8 @@ export default {
},
selectedTaskParent() {
let parentData = this.selectedTask?.relationships?.parent?.data;
if (parentData){
return this.structuralElementById({id: parentData.id});
if (parentData) {
return this.structuralElementById({ id: parentData.id });
}
return null;
......@@ -360,7 +446,7 @@ export default {
let children = [];
if (this.selectedTask) {
children = this.structuralElements.filter(
element => element.relationships.parent?.data?.id === this.selectedTask.id
(element) => element.relationships.parent?.data?.id === this.selectedTask.id
);
}
......@@ -371,8 +457,8 @@ export default {
},
selectedTargetElementParent() {
let parentData = this.selectedTargetElement?.relationships?.parent?.data;
if (parentData){
return this.structuralElementById({id: parentData.id});
if (parentData) {
return this.structuralElementById({ id: parentData.id });
}
return null;
......@@ -388,7 +474,7 @@ export default {
let children = [];
if (this.selectedTargetElement) {
children = this.structuralElements.filter(
element => element.relationships.parent?.data?.id === this.selectedTargetElement.id
(element) => element.relationships.parent?.data?.id === this.selectedTargetElement.id
);
}
......@@ -444,7 +530,11 @@ export default {
mounted() {
this.initWizardData();
const parent = { type: 'courses', id: this.context.id };
this.loadCourseMemberships({ parent, relationship: 'memberships', options: { include: 'user', 'page[offset]': 0, 'page[limit]': 10000, 'filter[permission]': 'autor' } });
this.loadCourseMemberships({
parent,
relationship: 'memberships',
options: { include: 'user', 'page[offset]': 0, 'page[limit]': 10000, 'filter[permission]': 'autor' },
});
this.loadCourseStatusGroups({ parent, relationship: 'status-groups' });
},
methods: {
......@@ -467,15 +557,15 @@ export default {
this.validate();
},
getUnitElement(unit) {
return this.structuralElementById({id: unit.relationships['structural-element'].data.id});
return this.structuralElementById({ id: unit.relationships['structural-element'].data.id });
},
selectTask(id) {
this.selectedTask = this.structuralElementById({id: id});
this.loadStructuralElement({id: id, options: {include: 'children'}});
this.selectedTask = this.structuralElementById({ id: id });
this.loadStructuralElement({ id: id, options: { include: 'children' } });
},
selectTargetElement(id) {
this.selectedTargetElement = this.structuralElementById({id: id});
this.loadStructuralElement({id: id, options: {include: 'children'}});
this.selectedTargetElement = this.structuralElementById({ id: id });
this.loadStructuralElement({ id: id, options: { include: 'children' } });
},
async distributeTask() {
this.setShowTasksDistributeDialog(false);
......@@ -515,7 +605,6 @@ export default {
await this.createTaskGroup({ taskGroup });
this.companionSuccess({ info: this.$gettext('Aufgaben wurden verteilt.') });
},
validateSolvers() {
if (
......@@ -558,15 +647,18 @@ export default {
if (!this.validateSolvers()) {
this.requirements.push({ slot: this.wizardSlots[5], text: this.$gettext('Aufgabe zuweisen') });
}
}
},
},
watch: {
async selectedSourceUnit(newUnit) {
this.validate();
if (newUnit !== null) {
this.wizardSlots[0].valid = true;
await this.loadStructuralElement({id: this.selectedSourceUnitRootId, options: {include: 'children'}});
this.selectedTask = this.structuralElementById({id: this.selectedSourceUnitRootId});
await this.loadStructuralElement({
id: this.selectedSourceUnitRootId,
options: { include: 'children' },
});
this.selectedTask = this.structuralElementById({ id: this.selectedSourceUnitRootId });
} else {
this.wizardSlots[0].valid = false;
}
......@@ -583,8 +675,11 @@ export default {
this.validate();
if (newUnit !== null) {
this.wizardSlots[3].valid = true;
await this.loadStructuralElement({id: this.selectedTargetUnitRootId, options: {include: 'children'}});
this.selectedTargetElement = this.structuralElementById({id: this.selectedTargetUnitRootId});
await this.loadStructuralElement({
id: this.selectedTargetUnitRootId,
options: { include: 'children' },
});
this.selectedTargetElement = this.structuralElementById({ id: this.selectedTargetUnitRootId });
} else {
this.wizardSlots[3].valid = false;
}
......@@ -597,14 +692,12 @@ export default {
this.wizardSlots[4].valid = false;
}
},
taskTitle() {
this.validate();
},
submissionDate() {
this.validate();
},
selectedAutors() {
this.validate();
},
......@@ -616,18 +709,18 @@ export default {
},
bulkSelectAutors(newState) {
if (newState) {
this.selectedAutors = this.autor_members.map( autor => autor.user_id);
this.selectedAutors = this.autor_members.map((autor) => autor.user_id);
} else {
this.selectedAutors = [];
}
},
bulkSelectGroups(newState) {
if (newState) {
this.selectedGroups = this.groups.map( group => group.id);
this.selectedGroups = this.groups.map((group) => group.id);
} else {
this.selectedGroups = [];
}
}
}
}
},
},
};
</script>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment