#39: Playlist Editor #81
										
											Binary file not shown.
										
									
								
							@ -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
											
										
									
								
							@ -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>
 | 
			
		||||
 | 
			
		||||
@ -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>
 | 
			
		||||
 | 
			
		||||
@ -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()})
 | 
			
		||||
 | 
			
		||||
@ -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}) {
 | 
			
		||||
 | 
			
		||||
@ -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');
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user