various fixes

This commit is contained in:
bkfox 2022-12-12 12:29:05 +01:00
parent a53a37021c
commit d2a65bd1fe
9 changed files with 282 additions and 200 deletions

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Aircox 0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-08 11:44+0000\n"
"POT-Creation-Date: 2022-12-12 10:15+0000\n"
"PO-Revision-Date: 2016-10-10 16:00+02\n"
"Last-Translator: Aarys\n"
"Language-Team: Aircox's translators team\n"
@ -18,13 +18,13 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: aircox/admin/episode.py:29 aircox/models/episode.py:183
#: aircox/admin/episode.py:27 aircox/models/episode.py:183
#: aircox/models/log.py:82
msgid "start"
msgstr "début"
#: aircox/admin/episode.py:33 aircox/models/episode.py:184
#: aircox/models/program.py:473
#: aircox/admin/episode.py:31 aircox/models/episode.py:184
#: aircox/models/program.py:469
msgid "end"
msgstr "fin"
@ -52,7 +52,7 @@ msgstr "Tout"
msgid "Publication Settings"
msgstr "Paramètre de la publication"
#: aircox/admin/program.py:40 aircox/models/program.py:286
#: aircox/admin/program.py:40 aircox/models/program.py:282
msgid "Schedule"
msgstr "Horaire"
@ -60,7 +60,7 @@ msgstr "Horaire"
msgid "Program Settings"
msgstr "Paramètres de l'émission"
#: aircox/admin/program.py:64 aircox/models/program.py:122
#: aircox/admin/program.py:64 aircox/models/program.py:118
msgid "Program"
msgstr "Émission"
@ -68,23 +68,25 @@ msgstr "Émission"
msgid "Day"
msgstr "Jour"
#: aircox/admin/sound.py:35 aircox/admin/sound.py:67
#: aircox/admin/sound.py:37 aircox/admin/sound.py:71
msgid "Audio"
msgstr "Audio"
#: aircox/admin/sound.py:63
#: aircox/admin/sound.py:65
msgid "Program / Episode"
msgstr "Émission / Épisode"
#: aircox/admin/sound.py:81 aircox/templates/aircox/episode_detail.html:36
#: aircox/admin/sound.py:100
#: aircox/templates/admin/aircox/playlist_inline.html:20
#: aircox/templates/aircox/episode_detail.html:36
msgid "Playlist"
msgstr "Playlist"
#: aircox/admin/sound.py:82
#: aircox/admin/sound.py:102
msgid "Info"
msgstr "Info"
#: aircox/admin/sound.py:96 aircox/models/sound.py:243
#: aircox/admin/sound.py:116 aircox/models/sound.py:240
msgid "timestamp"
msgstr "temps"
@ -92,8 +94,8 @@ msgstr "temps"
msgid "Statistics"
msgstr "Statistiques"
#: aircox/filters.py:8 aircox/templates/admin/base.html:81
#: aircox/templates/admin/base.html:95 aircox/templates/admin/base.html:109
#: aircox/filters.py:8 aircox/templates/admin/base.html:84
#: aircox/templates/admin/base.html:98 aircox/templates/admin/base.html:112
#: aircox/templates/aircox/base.html:78
#: aircox/templates/aircox/page_list.html:15
msgid "Search"
@ -103,24 +105,24 @@ msgstr "Chercher"
msgid "Podcast"
msgstr "Podcast"
#: aircox/management/commands/sounds_monitor.py:204
#: aircox/management/commands/sounds_monitor.py:205
msgid "unknown"
msgstr "inconnu"
#: aircox/models/article.py:14
#: aircox/models/article.py:16
msgid "Article"
msgstr "Article"
#: aircox/models/article.py:15 aircox/templates/admin/base.html:92
#: aircox/models/article.py:17 aircox/templates/admin/base.html:95
#: aircox/templates/aircox/program_detail.html:19
msgid "Articles"
msgstr "Articles"
#: aircox/models/episode.py:52
#: aircox/models/episode.py:52 aircox/templates/admin/aircox/statistics.html:23
msgid "Episode"
msgstr "Épisode"
#: aircox/models/episode.py:53 aircox/templates/admin/base.html:106
#: aircox/models/episode.py:53 aircox/templates/admin/base.html:109
msgid "Episodes"
msgstr "Épisodes"
@ -136,8 +138,8 @@ msgstr "non confirmé"
msgid "cancelled"
msgstr "annulé"
#: aircox/models/episode.py:174 aircox/models/sound.py:102
#: aircox/models/sound.py:233 aircox/templates/admin/aircox/statistics.html:23
#: aircox/models/episode.py:174 aircox/models/sound.py:99
#: aircox/models/sound.py:230
msgid "episode"
msgstr "épisode"
@ -146,7 +148,7 @@ msgid "schedule"
msgstr "horaire"
#: aircox/models/episode.py:181 aircox/models/log.py:91
#: aircox/models/sound.py:105 aircox/models/station.py:142
#: aircox/models/sound.py:102 aircox/models/station.py:142
msgid "type"
msgstr "type"
@ -171,12 +173,12 @@ msgstr "rediffusion"
msgid "stop"
msgstr "stop"
#: aircox/models/log.py:84 aircox/models/sound.py:89
#: aircox/models/log.py:84 aircox/models/sound.py:86
msgid "other"
msgstr "autre"
#: aircox/models/log.py:89 aircox/models/page.py:248
#: aircox/models/program.py:55 aircox/models/station.py:139
#: aircox/models/program.py:54 aircox/models/station.py:139
msgid "station"
msgstr "station"
@ -184,7 +186,7 @@ msgstr "station"
msgid "related station"
msgstr "station relative"
#: aircox/models/log.py:92 aircox/models/program.py:254
#: aircox/models/log.py:92 aircox/models/program.py:250
msgid "date"
msgstr "date"
@ -200,11 +202,12 @@ msgstr "identifiant de la source relative à ce log"
msgid "comment"
msgstr "commentaire"
#: aircox/models/log.py:107 aircox/models/sound.py:146
#: aircox/models/log.py:107 aircox/models/sound.py:143
msgid "Sound"
msgstr "Son"
#: aircox/models/log.py:112 aircox/models/sound.py:259
#: aircox/templates/admin/aircox/statistics.html:24
msgid "Track"
msgstr "Morceau"
@ -217,7 +220,7 @@ msgid "Logs"
msgstr "Logs"
#: aircox/models/page.py:30 aircox/models/page.py:251
#: aircox/models/sound.py:247
#: aircox/models/sound.py:244
msgid "title"
msgstr "titre"
@ -338,8 +341,8 @@ msgstr "Commentaires"
msgid "menu"
msgstr "menu"
#: aircox/models/page.py:250 aircox/models/sound.py:107
#: aircox/models/sound.py:240
#: aircox/models/page.py:250 aircox/models/sound.py:104
#: aircox/models/sound.py:237
msgid "order"
msgstr "ordre"
@ -359,234 +362,239 @@ msgstr "Élément du menu"
msgid "Menu items"
msgstr "Éléments de menu"
#: aircox/models/program.py:57 aircox/models/station.py:52
#: aircox/models/program.py:56 aircox/models/station.py:52
#: aircox/models/station.py:144
msgid "active"
msgstr "actif"
#: aircox/models/program.py:59
#: aircox/models/program.py:58
msgid "if not checked this program is no longer active"
msgstr "si selectionné, cette émission n'est plus active"
#: aircox/models/program.py:62
#: aircox/models/program.py:61
msgid "syncronise"
msgstr "synchroniser"
#: aircox/models/program.py:64
#: aircox/models/program.py:63
msgid "update later diffusions according to schedule changes"
msgstr "met à jour les dates de diffusion à venir lorsque l'horaire change"
#: aircox/models/program.py:123 aircox/templates/admin/base.html:78
#: aircox/models/program.py:119 aircox/templates/admin/base.html:81
msgid "Programs"
msgstr "Émissions"
#: aircox/models/program.py:178 aircox/models/program.py:461
#: aircox/models/program.py:174 aircox/models/program.py:457
msgid "related program"
msgstr "émission apparentée"
#: aircox/models/program.py:182
#: aircox/models/program.py:178
msgid "rerun of"
msgstr "rediffusion de"
#: aircox/models/program.py:226
#: aircox/models/program.py:222
msgid "rerun must happen after original"
msgstr "la rediffusion doit être après l'original"
#: aircox/models/program.py:254
#: aircox/models/program.py:250
msgid "date of the first diffusion"
msgstr "date de la première diffusion"
#: aircox/models/program.py:257
#: aircox/templates/admin/aircox/statistics.html:22
#: aircox/models/program.py:253
msgid "time"
msgstr "heure"
#: aircox/models/program.py:257
#: aircox/models/program.py:253
msgid "start time"
msgstr "heure de début"
#: aircox/models/program.py:260
#: aircox/models/program.py:256
msgid "timezone"
msgstr "zone horaire"
#: aircox/models/program.py:263
#: aircox/models/program.py:259
msgid "timezone used for the date"
msgstr "zone horaire utilisée pour la date"
#: aircox/models/program.py:266 aircox/models/sound.py:120
#: aircox/models/program.py:262 aircox/models/sound.py:117
msgid "duration"
msgstr "durée"
#: aircox/models/program.py:267
#: aircox/models/program.py:263
msgid "regular duration"
msgstr "durée normale"
#: aircox/models/program.py:270
#: aircox/models/program.py:266
msgid "frequency"
msgstr "fréquence"
#: aircox/models/program.py:272
#: aircox/models/program.py:268
msgid "ponctual"
msgstr "ponctuel"
#: aircox/models/program.py:273
#: aircox/models/program.py:269
#, python-brace-format
msgid "1st {day} of the month"
msgstr "1er {day} du mois"
#: aircox/models/program.py:274
#: aircox/models/program.py:270
#, python-brace-format
msgid "2nd {day} of the month"
msgstr "2ème {day} du mois"
#: aircox/models/program.py:275
#: aircox/models/program.py:271
#, python-brace-format
msgid "3rd {day} of the month"
msgstr "3ème {day} du mois"
#: aircox/models/program.py:276
#: aircox/models/program.py:272
#, python-brace-format
msgid "4th {day} of the month"
msgstr "4ème {day} du mois"
#: aircox/models/program.py:277
#: aircox/models/program.py:273
#, python-brace-format
msgid "last {day} of the month"
msgstr "dernier {day} du mois"
#: aircox/models/program.py:278
#: aircox/models/program.py:274
#, python-brace-format
msgid "1st and 3rd {day} of the month"
msgstr "1er et 3ème {day} du mois"
#: aircox/models/program.py:279
#: aircox/models/program.py:275
#, python-brace-format
msgid "2nd and 4th {day} of the month"
msgstr "2ème et 4ème {day} du mois"
#: aircox/models/program.py:280
#, fuzzy, python-brace-format
#| msgid "every {day}"
#: aircox/models/program.py:276
msgid "{day}"
msgstr "{day}"
#: aircox/models/program.py:281
#: aircox/models/program.py:277
#, python-brace-format
msgid "one {day} on two"
msgstr "un {day} sur deux"
#: aircox/models/program.py:287
#: aircox/models/program.py:283
msgid "Schedules"
msgstr "Horaires"
#: aircox/models/program.py:464
#: aircox/models/program.py:460
msgid "delay"
msgstr "délai"
#: aircox/models/program.py:465
#: aircox/models/program.py:461
msgid "minimal delay between two sound plays"
msgstr "délai minimum entre deux sons joués"
#: aircox/models/program.py:468
#: aircox/models/program.py:464
msgid "begin"
msgstr "début"
#: aircox/models/program.py:469 aircox/models/program.py:475
#: aircox/models/program.py:465 aircox/models/program.py:471
msgid "used to define a time range this stream is played"
msgstr ""
"utilisé pour définir un intervalle de temps pendant lequel ce stream est joué"
#: aircox/models/sound.py:89
#: aircox/models/sound.py:86
msgid "archive"
msgstr "archive"
#: aircox/models/sound.py:90
#: aircox/models/sound.py:87
msgid "excerpt"
msgstr "extrait"
#: aircox/models/sound.py:90
#: aircox/models/sound.py:87
msgid "removed"
msgstr "supprimé"
#: aircox/models/sound.py:93 aircox/models/station.py:37
#: aircox/models/sound.py:90 aircox/models/station.py:37
msgid "name"
msgstr "nom"
#: aircox/models/sound.py:96
#: aircox/models/sound.py:93
msgid "program"
msgstr "émission"
#: aircox/models/sound.py:97
#: aircox/models/sound.py:94
msgid "program related to it"
msgstr "émission apparentée à celui-ci"
#: aircox/models/sound.py:107 aircox/models/sound.py:240
#: aircox/models/sound.py:104 aircox/models/sound.py:237
msgid "position in the playlist"
msgstr "position dans la playlist"
#: aircox/models/sound.py:116 aircox/models/station.py:135
#: aircox/models/sound.py:113 aircox/models/station.py:135
msgid "file"
msgstr "fichier"
#: aircox/models/sound.py:122
#: aircox/models/sound.py:119
msgid "duration of the sound"
msgstr "durée du son"
#: aircox/models/sound.py:125
#: aircox/models/sound.py:122
msgid "modification time"
msgstr "dernière modification"
#: aircox/models/sound.py:127
#: aircox/models/sound.py:124
msgid "last modification date and time"
msgstr "date et heure de la dernière modification"
#: aircox/models/sound.py:130
#: aircox/models/sound.py:127
msgid "good quality"
msgstr "bonne qualité"
#: aircox/models/sound.py:130
#: aircox/models/sound.py:127
msgid "sound meets quality requirements"
msgstr "le son rencontre les exigences de qualité"
#: aircox/models/sound.py:134
#: aircox/models/sound.py:131
msgid "public"
msgstr "publique"
#: aircox/models/sound.py:134
#: aircox/models/sound.py:131
msgid "whether it is publicly available as podcast"
msgstr "coché pour rendre le podcast public"
#: aircox/models/sound.py:138
#: aircox/models/sound.py:135
msgid "downloadable"
msgstr "téléchargeable"
#: aircox/models/sound.py:139
#: aircox/models/sound.py:136
msgid ""
"whether it can be publicly downloaded by visitors (sound must be public)"
msgstr ""
"coché pour permettre le téléchargement public (le podcast doit être "
"disponible publiquement)"
#: aircox/models/sound.py:147
#: aircox/models/sound.py:144
msgid "Sounds"
msgstr "Sons"
#: aircox/models/sound.py:237
#: aircox/models/sound.py:234
msgid "sound"
msgstr "son"
#: aircox/models/sound.py:245
#: aircox/models/sound.py:242
msgid "position (in seconds)"
msgstr "position (en secondes)"
#: aircox/models/sound.py:248
#: aircox/models/sound.py:245
msgid "artist"
msgstr "artiste"
#: aircox/models/sound.py:249 aircox/templates/admin/aircox/statistics.html:25
#: aircox/models/sound.py:246
msgid "album"
msgstr "album"
#: aircox/models/sound.py:247
msgid "tags"
msgstr "tags"
#: aircox/models/sound.py:248
msgid "year"
msgstr "année"
#: aircox/models/sound.py:251
msgid "information"
msgstr "information"
@ -677,6 +685,18 @@ msgstr ""
"liste des paramètres disponibles séparés par des virgules; placé dans le "
"fichier de configuration en tant que code brut; relatif au plugin utilisé"
#: aircox/models/user_settings.py:11
msgid "User"
msgstr "Utilisateur"
#: aircox/models/user_settings.py:14
msgid "Playlist Editor Columns"
msgstr "Colonnes de l'éditeur de playlist"
#: aircox/models/user_settings.py:16
msgid "Playlist Editor Separator"
msgstr "Séparateur de l'éditeur de playlist"
#: aircox/templates/admin/aircox/filters/filter.html:2
#, python-format
msgid " By %(filter_title)s "
@ -684,7 +704,7 @@ msgstr "Par %(filter_title)s "
#: aircox/templates/admin/aircox/page_change_form.html:9
#: aircox/templates/admin/aircox/page_change_list.html:7
#: aircox/templates/admin/base.html:163
#: aircox/templates/admin/base.html:166
#: aircox/templates/admin/change_list.html:30
#: aircox/templates/aircox/base.html:54
msgid "Home"
@ -715,36 +735,46 @@ msgstr "Sauvegarder et continuer"
msgid "Publish"
msgstr "Publier"
#: aircox/templates/admin/aircox/statistics.html:24
msgid "track"
msgstr "piste"
#: aircox/templates/admin/aircox/playlist_inline.html:33
#: aircox/templates/admin/aircox/playlist_inline.html:34
msgid "Track Position"
msgstr "Position dans la playlist"
#: aircox/templates/admin/aircox/statistics.html:22
msgid "Time"
msgstr "Heure"
#: aircox/templates/admin/aircox/statistics.html:25
#: aircox/templatetags/aircox_admin.py:52
msgid "Tags"
msgstr "Étiquettes"
#: aircox/templates/admin/aircox/statistics.html:67
msgid "Total"
msgstr "Total"
#: aircox/templates/admin/base.html:65 aircox/templates/admin/index.html:11
#: aircox/templates/admin/base.html:68 aircox/templates/admin/index.html:11
#: aircox/templates/aircox/home.html:47
msgid "Today"
msgstr "Aujourd'hui"
#: aircox/templates/admin/base.html:121
#: aircox/templates/admin/base.html:124
msgid "Tools"
msgstr "Outils"
#: aircox/templates/admin/base.html:137
#: aircox/templates/admin/base.html:140
msgid "View site"
msgstr "Voir le site"
#: aircox/templates/admin/base.html:142
#: aircox/templates/admin/base.html:145
msgid "Documentation"
msgstr "Documentation"
#: aircox/templates/admin/base.html:146
#: aircox/templates/admin/base.html:149
msgid "Change password"
msgstr "Changer le mot de passe"
#: aircox/templates/admin/base.html:149
#: aircox/templates/admin/base.html:152
msgid "Log out"
msgstr "Se déconnecter"
@ -958,67 +988,108 @@ msgstr "Épisode en ce moment sur les ondes"
msgid "Currently playing"
msgstr "En ce moment"
#: aircox/urls.py:40
#: aircox/templatetags/aircox_admin.py:51
msgid "Artist"
msgstr "Artiste"
#: aircox/templatetags/aircox_admin.py:51
msgid "Album"
msgstr "Album"
#: aircox/templatetags/aircox_admin.py:51
msgid "Title"
msgstr "Titre"
#: aircox/templatetags/aircox_admin.py:52
msgid "Year"
msgstr "Année"
#: aircox/templatetags/aircox_admin.py:53
msgid "Save Settings"
msgstr "Enregistrer la configuration"
#: aircox/templatetags/aircox_admin.py:54
msgid "Discard changes"
msgstr "Annuler les changements"
#: aircox/templatetags/aircox_admin.py:55
msgid "Columns"
msgstr "Colonnes"
#: aircox/templatetags/aircox_admin.py:56
msgid "Add a track"
msgstr "Ajouter un morceau"
#: aircox/templatetags/aircox_admin.py:57
msgid "Remove"
msgstr "Supprimer"
#: aircox/templatetags/aircox_admin.py:58
#| msgid "timestamp"
msgid "Timestamp"
msgstr "Temps"
#: aircox/urls.py:44
msgid "articles/"
msgstr "articles/"
#: aircox/urls.py:43
#: aircox/urls.py:47
msgid "articles/<slug:slug>/"
msgstr "articles/<slug:slug>/"
#: aircox/urls.py:47
#: aircox/urls.py:51
msgid "episodes/"
msgstr "episodes/"
#: aircox/urls.py:49
#: aircox/urls.py:53
msgid "episodes/<slug:slug>/"
msgstr "episodes/<slug:slug>/"
#: aircox/urls.py:51
#: aircox/urls.py:55
msgid "week/"
msgstr "semaine/"
#: aircox/urls.py:53
#: aircox/urls.py:57
msgid "week/<date:date>/"
msgstr "semaine/<date:date>/"
#: aircox/urls.py:56
#: aircox/urls.py:60
msgid "logs/"
msgstr "logs/"
#: aircox/urls.py:57
#: aircox/urls.py:61
msgid "logs/<date:date>/"
msgstr "logs/<date:date>/"
#: aircox/urls.py:60
#: aircox/urls.py:64
msgid "publications/"
msgstr "publications/"
#: aircox/urls.py:63
#: aircox/urls.py:67
msgid "pages/"
msgstr "pages/"
#: aircox/urls.py:69
#: aircox/urls.py:73
msgid "pages/<slug:slug>/"
msgstr "pages/<slug:slug>/"
#: aircox/urls.py:76
#: aircox/urls.py:80
msgid "programs/"
msgstr "emissions/"
#: aircox/urls.py:78
#: aircox/urls.py:82
msgid "programs/<slug:slug>/"
msgstr "emissions/<slug:slug>/"
#: aircox/urls.py:80
#: aircox/urls.py:84
msgid "programs/<slug:parent_slug>/episodes/"
msgstr "emissions/<slug:parent_slug>/episodes/"
#: aircox/urls.py:82
#: aircox/urls.py:86
msgid "programs/<slug:parent_slug>/articles/"
msgstr "emissions/<slug:parent_slug>/articles/"
#: aircox/urls.py:84
#: aircox/urls.py:88
msgid "programs/<slug:parent_slug>/publications/"
msgstr "emissions/<slug:parent_slug>/publications/"
@ -1026,6 +1097,9 @@ msgstr "emissions/<slug:parent_slug>/publications/"
msgid "comments are not allowed"
msgstr "les commentaires ne sont pas autorisés"
#~ msgid "track"
#~ msgstr "morceau"
#~ msgid "if it can be podcasted from the server"
#~ msgstr "s'il peut être podcasté depuis le serveur"

File diff suppressed because one or more lines are too long

View File

@ -10,9 +10,6 @@
<a-playlist-editor
:labels="{% track_inline_labels %}"
:init-data="{% track_inline_data formset=formset %}"
{% if not track_timestamp %}
:hide-columns="['timestamp']"
{% endif %}
settings-url="{% url "api:user-settings" %}"
data-prefix="{{ formset.prefix }}-">
<template #title>
@ -70,6 +67,7 @@
{% endif %}
:name="'{{ formset.prefix }}-' + cell.row + '-{{ field.name }}'"
v-model="item.data[attr]"
title="{{ field.help }}"
@change="emit('change', col)"/>
{% if field.name not in 'artist,title,album' %}
</div>

View File

@ -18,10 +18,10 @@
<table class="table is-hoverable is-fullwidth">
<thead>
<tr>
<th>{% translate "time" %}</th>
<th>{% translate "episode" %}</th>
<th>{% translate "track" %}</th>
<th>{% translate "tags" %}</th>
<th>{% translate "Time" %}</th>
<th>{% translate "Episode" %}</th>
<th>{% translate "Track" %}</th>
<th>{% translate "Tags" %}</th>
</tr>
</thead>
<tbody>

View File

@ -2,7 +2,7 @@ import json
from django import template
from django.contrib import admin
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _, gettext as __
from django.utils.translation import gettext_lazy as _
from aircox.serializers.admin import UserSettingsSerializer
@ -47,17 +47,19 @@ def do_track_inline_data(context, formset, safe_string=False):
return safe_string and mark_safe(source) or source
track_inline_labels_ = {
'artist': _('Artist'), 'album': _('Album'), 'title': _('Title'),
'tags': _('Tags'), 'year': _('Year'),
'save_settings': _('Save Settings'),
'discard_changes': _('Discard changes'),
'columns': _('Columns'),
'add_track': _('Add a track'),
'remove_track': _('Remove'),
'timestamp': _('Timestamp'),
}
@register.simple_tag(name='track_inline_labels')
def do_track_inline_labels():
""" Return labels for columns in playlist editor as dict """
return json.dumps({
'artist': __('Artist'), 'album': __('Album'), 'title': __('Title'),
'tags': __('Tags'), 'year': __('Year'),
'save_settings': __('Save Settings'),
'discard_changes': __('Discard changes'),
'columns': __('Columns'),
'add_track': __('Add a track'),
'remove_track': __('Remove'),
'timestamp': __('Timestamp'),
})
return json.dumps({k: str(v) for k, v in track_inline_labels_.items()})

View File

@ -59,6 +59,18 @@
</section>
<div class="mt-2">
<div class="float-right">
<a class="button is-warning p-2 ml-2"
@click="loadData({items: this.initData.items},true)">
<span class="icon"><i class="fa fa-rotate" /></span>
<span>{{ labels.discard_changes }}</span>
</a>
<a class="button is-primary p-2 ml-2" t-if="page == page.List"
@click="this.set.push(new this.set.model())">
<span class="icon"><i class="fa fa-plus"/></span>
<span>{{ labels.add_track }}</span>
</a>
</div>
<div class="field is-inline-block is-vcentered mr-3">
<label class="label is-inline mr-2"
style="vertical-align: middle">
@ -101,18 +113,6 @@
{{ labels.save_settings }}
</a-action-button>
</div>
<div class="float-right">
<a class="button is-warning p-2 ml-2"
@click="loadData({items: this.initData.items},true)">
<span class="icon"><i class="fa fa-rotate" /></span>
<span>{{ labels.discard_changes }}</span>
</a>
<a class="button is-primary p-2 ml-2" t-if="page == page.List"
@click="this.set.push(new this.set.model())">
<span class="icon"><i class="fa fa-plus"/></span>
<span>{{ labels.add_track }}</span>
</a>
</div>
</div>
<slot name="bottom" :set="set" :columns="columns" :items="items"/>
</div>
@ -181,7 +181,9 @@ export default {
value = cols.concat(left)
this.settings.playlist_editor_columns = value
},
get() { return this.settings.playlist_editor_columns }
get() {
return this.settings.playlist_editor_columns
}
},
items() {
@ -205,12 +207,12 @@ export default {
formatMove({from, to}) {
const value = this.columns[from]
this.columns.splice(from, 1)
this.columns.splice(to, 0, value)
this.settings.playlist_editor_columns.splice(from, 1)
this.settings.playlist_editor_columns.splice(to, 0, value)
if(this.page == Page.Text)
this.updateList()
else
this.updateText()
this.updateInput()
},
columnMove({from, to}) {

View File

@ -30,20 +30,34 @@ export default {
emit: ['move', 'cell'],
props: {
//! Item to display in row
item: Object,
//! Columns to display, as items' attributes
columns: Array,
//! Default cell's info
cell: {type: Object, default() { return {row: 0}}},
//! Cell component tag
cellTag: {type: String, default: 'td'},
//! If true, can reorder cell by drag & drop
orderable: {type: Boolean, default: false},
},
computed: {
row() { return this.cell && this.cell.row },
/**
* Row index
*/
row() { return this.cell && this.cell.row || 0 },
/**
* Item's data if model instance, otherwise item
*/
itemData() {
return this.item instanceof Model ? this.item.data : this.item;
},
/**
* Computed cell infos
*/
cells() {
const cell = isReactive(this.cell) && toRefs(this.cell) || this.cell || {}
const cells = []
@ -51,19 +65,16 @@ export default {
cells.push({...cell, col: Number(col)})
return cells
},
cellEls() {
return [...this.$el.querySelectorAll(self.cellTag)].filter(x => x.dataset.col)
},
},
methods: {
/// Emit a 'cell' event.
/// Event data: `{name, data, item, attr}`
///
/// @param {Number} col: cell column's index
/// @param {String} name: cell's event name
/// @param {} data: cell's event data
/**
* Emit a 'cell' event.
* Event data: `{name, cell, data, item}`
* @param {Number} col: cell column's index
* @param {String} name: cell's event name
* @param {} data: cell's event data
*/
cellEmit(name, cell, data) {
this.$emit('cell', {
name, cell, data,
@ -83,6 +94,9 @@ export default {
ev.dataTransfer.dropEffect = 'move'
},
/**
* Handle drop event, emit `'move': { from, to }`.
*/
onDrop(ev) {
const data = ev.dataTransfer.getData("text/cell")
if(!data || !data.startsWith('cell:'))
@ -95,14 +109,28 @@ export default {
})
},
/**
* Return DOM node for cells at provided position `col`
*/
getCellEl(col) {
const els = this.$el.querySelectorAll(this.cellTag)
for(var el of els)
if(col == Number(el.dataset.col))
return el;
return null
},
/**
* Focus cell's form input. If from is provided, related focus
*/
focus(col, from) {
if(from)
col += from.col
const target = this.cellEls[col]
const target = this.getCellEl(col)
if(!target)
return
const control = target.querySelector('input') ||
const control = target.querySelector('input:not([type="hidden"])') ||
target.querySelector('button') ||
target.querySelector('select') ||
target.querySelector('a');

View File

@ -16,6 +16,7 @@
<template v-for="(item,row) in items" :key="row">
<!-- data-index comes from AList component drag & drop -->
<a-row :item="item" :cell="{row}" :columns="columns" :data-index="row"
:data-row="row"
:draggable="orderable"
@dragstart="onDragStart" @dragover="onDragOver" @drop="onDrop"
@cell="onCellEvent(row, $event)">
@ -24,7 +25,7 @@
<slot :name="name" v-bind="data"/>
</template>
<template v-else>
<div @keydown.ctrl="onControlKey($event, data.cell)">
<div>
<slot :name="name" v-bind="data"/>
</div>
</template>
@ -64,12 +65,7 @@ const Component = {
for(var row in this.items)
cells.push({row})
},
rows() {
return [...this.$el.querySelectorAll('tr')].filter(x => x.__row)
.map(x => x.__row)
},
rowSlots() {
return Object.keys(this.$slots).filter(x => x.startsWith('row-'))
.map(x => [x, x.slice(4)])
@ -77,27 +73,6 @@ const Component = {
},
methods: {
onControlKey(event, cell) {
switch(event.key) {
case "ArrowUp": this.focus(-1, 0, cell)
event.stopPropagation()
event.preventDefault()
break;
case "ArrowDown": this.focus(1, 0, cell)
event.stopPropagation()
event.preventDefault()
break;
case "ArrowLeft": this.focus(0, -1, cell)
event.stopPropagation()
event.preventDefault()
break;
case "ArrowRight": this.focus(0, 1, cell)
event.stopPropagation()
event.preventDefault()
break;
}
},
/**
* React on 'cell' event, re-emitting it with additional values:
* - `set`: data set
@ -108,27 +83,30 @@ const Component = {
*/
onCellEvent(row, event) {
if(event.name == 'focus')
this.cellFocus(event.data, event.cell)
this.focus(event.data, event.cell)
this.$emit('cell', {
...event, row,
set: this.set
})
},
getCellNode(row, col) {
const el = this.$refs[row]
return el && el.cellEls(col)
/**
* Return row component at provided index
*/
getRow(row) {
const els = this.$el.querySelectorAll('tr')
for(var el of els)
if(el.__row && row == Number(el.dataset.row))
return el.__row
},
/**
/**
* Focus on a cell
*/
focus(row, col, from=null) {
if(from)
row += from.row
row = this.rows[row]
row = this.getRow(row)
row && row.focus(col, from)
},
},