From e0b123ac6abb86ed90426638e3f617a02925c156 Mon Sep 17 00:00:00 2001 From: Thomas Hackl <hackl@data-quest.de> Date: Tue, 23 Apr 2024 09:44:40 +0000 Subject: [PATCH] =?UTF-8?q?Resolve=20"Fehlende=20textuelle=20Beschreibunge?= =?UTF-8?q?n=20f=C3=BCr=20Icons=20im=20Dateibereich"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #4037 Merge request studip/studip!2893 --- resources/assets/stylesheets/scss/tables.scss | 8 +- resources/vue/components/FilesTable.vue | 132 +++++++++++++++--- 2 files changed, 117 insertions(+), 23 deletions(-) diff --git a/resources/assets/stylesheets/scss/tables.scss b/resources/assets/stylesheets/scss/tables.scss index 9e05f014fdb..058569fa0c5 100644 --- a/resources/assets/stylesheets/scss/tables.scss +++ b/resources/assets/stylesheets/scss/tables.scss @@ -271,11 +271,15 @@ tr.sortable { } th.sortasc { - @include icon('after', 'arr_1up', 'clickable'); + span[role=img] { + @include icon('after', 'arr_1up', 'clickable'); + } } th.sortdesc { - @include icon('after', 'arr_1down', 'clickable'); + span[role=img] { + @include icon('after', 'arr_1down', 'clickable'); + } } } diff --git a/resources/vue/components/FilesTable.vue b/resources/vue/components/FilesTable.vue index 646e9146f73..389e5d12e28 100644 --- a/resources/vue/components/FilesTable.vue +++ b/resources/vue/components/FilesTable.vue @@ -42,52 +42,127 @@ </colgroup> <thead> <tr class="sortable"> - <th v-if="show_bulk_actions" data-sort="false" :aria-label="$gettext('Ordner und Dateien auswählen')"> + <th v-if="show_bulk_actions" + data-sort="false" + :aria-label="$gettext('Ordner und Dateien auswählen')"> <studip-proxy-checkbox v-model="selectedIds" :total="allIds" :title="$gettext('Alle Ordner und Dateien auswählen')" ></studip-proxy-checkbox> </th> - <th @click="sort('mime_type')" :class="sortClasses('mime_type')"> - <a href="#" @click.prevent> + <th @click="sort('mime_type')" + :class="sortClasses('mime_type')"> + <a href="#" + @click.prevent + :title="$gettext('Nach Typ sortieren')"> {{ $gettext('Typ') }} </a> + <span v-if="sortedBy === 'mime_type'" + role="img" + :aria-sort="sortDirection === 'asc' ? 'ascending' : 'descending'" + :aria-label="sortDirection === 'asc' + ? $gettext('Es wird aufsteigend nach dieser Spalte sortiert.') + : $gettext('Es wird abfsteigend nach dieser Spalte sortiert.')"> + </span> </th> - <th @click="sort('name')" :class="sortClasses('name')"> - <a href="#" @click.prevent> + <th @click="sort('name')" + :class="sortClasses('name')"> + <a href="#" + @click.prevent + :title="$gettext('Nach Name sortieren')"> {{ $gettext('Name') }} </a> + <span v-if="sortedBy === 'name'" + role="img" + :aria-sort="sortDirection === 'asc' ? 'ascending' : 'descending'" + :aria-label="sortDirection === 'asc' + ? $gettext('Es wird aufsteigend nach dieser Spalte sortiert.') + : $gettext('Es wird absteigend nach dieser Spalte sortiert.')"> + </span> </th> - <th @click="sort('size')" class="responsive-hidden" :class="sortClasses('size')"> - <a href="#" @click.prevent> + <th @click="sort('size')" + class="responsive-hidden" + :class="sortClasses('size')"> + <a href="#" + @click.prevent + :title="$gettext('Nach Größe sortieren')"> {{ $gettext('Größe') }} </a> + <span v-if="sortedBy === 'size'" + role="img" + :aria-sort="sortDirection === 'asc' ? 'ascending' : 'descending'" + :aria-label="sortDirection === 'asc' + ? $gettext('Es wird aufsteigend nach dieser Spalte sortiert.') + : $gettext('Es wird absteigend nach dieser Spalte sortiert.')"> + </span> </th> - <th v-if="showdownloads" @click="sort('downloads')" class="responsive-hidden" :class="sortClasses('downloads')"> - <a href="#" @click.prevent> + <th v-if="showdownloads" + @click="sort('downloads')" + class="responsive-hidden" + :class="sortClasses('downloads')"> + <a href="#" + @click.prevent + :title="$gettext('Nach Downloads sortieren')"> {{ $gettext('Downloads') }} </a> + <span v-if="sortedBy === 'downloads'" + role="img" + :aria-sort="sortDirection === 'asc' ? 'ascending' : 'descending'" + :aria-label="sortDirection === 'asc' + ? $gettext('Es wird aufsteigend nach dieser Spalte sortiert.') + : $gettext('Es wird absteigend nach dieser Spalte sortiert.')"> + </span> </th> - <th class="responsive-hidden" @click="sort('author_name')" :class="sortClasses('author_name')"> - <a href="#" @click.prevent> + <th class="responsive-hidden" + @click="sort('author_name')" + :class="sortClasses('author_name')"> + <a href="#" + @click.prevent + :title="$gettext('Nach Autor/-in sortieren')"> {{ $gettext('Autor/-in') }} </a> + <span v-if="sortedBy === 'author_name'" + role="img" + :aria-sort="sortDirection === 'asc' ? 'ascending' : 'descending'" + :aria-label="sortDirection === 'asc' + ? $gettext('Es wird aufsteigend nach dieser Spalte sortiert.') + : $gettext('Es wird absteigend nach dieser Spalte sortiert.')"> + </span> </th> - <th class="responsive-hidden" @click="sort('chdate')" :class="sortClasses('chdate')"> - <a href="#" @click.prevent> + <th class="responsive-hidden" + @click="sort('chdate')" + :class="sortClasses('chdate')"> + <a href="#" + @click.prevent + :title="$gettext('Nach Datum sortieren')"> {{ $gettext('Datum') }} </a> + <span v-if="sortedBy === 'chdate'" + role="img" + :aria-sort="sortDirection === 'asc' ? 'ascending' : 'descending'" + :aria-label="sortDirection === 'asc' + ? $gettext('Es wird aufsteigend nach dieser Spalte sortiert.') + : $gettext('Es wird absteigend nach dieser Spalte sortiert.')"> + </span> </th> <th v-for="(name, index) in additionalColumns" :key="index" @click="sort(index)" class="responsive-hidden" :class="sortClasses(index)"> - <a href="#" @click.prevent> + <a href="#" + @click.prevent + :title="$gettextInterpolate($gettext('Nach %{ colName } sortieren'), {colName: name})"> {{name}} </a> - + <span v-if="sortedBy === name" + role="img" + :aria-sort="sortDirection === 'asc' ? 'ascending' : 'descending'" + :aria-label="sortDirection === 'asc' + ? $gettext('Es wird aufsteigend nach dieser Spalte sortiert.') + : $gettext('Es wird absteigend nach dieser Spalte sortiert.')"> + </span> </th> <th class="actions" data-sort="false">{{ $gettext('Aktionen') }}</th> </tr> @@ -120,12 +195,17 @@ ></studip-proxied-checkbox> </td> <td class="document-icon"> - <a :href="folder.url" :id="`folder-${folder.id}`"> - <studip-icon :shape="folder.icon" :size="26" class="text-bottom"></studip-icon> + <a :href="folder.url" + :id="`folder-${folder.id}`" + :title="$gettextInterpolate($gettext('Ordner %{foldername} öffnen'), + { foldername: folder.name})"> + <studip-icon :shape="folder.icon" :size="26" class="text-bottom" alt=""></studip-icon> </a> </td> <td :class="{'filter-match': valueMatchesFilter(folder.name)}"> - <a :href="folder.url"> + <a :href="folder.url" + :title="$gettextInterpolate($gettext('Ordner %{foldername} öffnen'), + { foldername: folder.name})"> <span v-html="highlightString(folder.name)"></span> </a> </td> @@ -172,7 +252,11 @@ ></studip-proxied-checkbox> </td> <td class="document-icon"> - <a v-if="file.download_url" :href="file.download_url" target="_blank" rel="noopener noreferrer"> + <a v-if="file.download_url" + :href="file.download_url" + target="_blank" rel="noopener noreferrer" + :title="$gettextInterpolate($gettext('Datei %{filename} herunterladen'), + { filename: file.name })"> <studip-icon :shape="file.icon" :size="24" class="text-bottom"></studip-icon> </a> <studip-icon v-else :shape="file.icon" :size="24"></studip-icon> @@ -180,10 +264,16 @@ <a :href="file.download_url" v-if="file.download_url && file.mime_type.indexOf('image/') === 0" class="lightbox-image" - data-lightbox="gallery"></a> + data-lightbox="gallery" + :title="$gettextInterpolate($gettext('Datei %{filename} anzeigen'), + { filename: file.name })"></a> </td> <td :class="{'filter-match': valueMatchesFilter(file.name)}"> - <a :href="file.details_url" data-dialog :id="`file-${file.id}`"> + <a :href="file.details_url" + data-dialog + :id="`file-${file.id}`" + :title="$gettextInterpolate($gettext('Details zur Datei %{filename} anzeigen'), + { filename: file.name })"> <span v-html="highlightString(file.name)"></span> <studip-icon v-if="file.isAccessible" shape="accessibility" -- GitLab