This commit is contained in:
jr-k 2024-07-15 23:43:18 +02:00
parent e2ba157fdc
commit d3ef3c16a2
56 changed files with 1949 additions and 1610 deletions

File diff suppressed because one or more lines are too long

BIN
data/www/img/logo3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -105,7 +105,7 @@ jQuery(function ($) {
route = $(this).attr('data-entity-route') + '?id=' + $item.attr('data-id'); route = $(this).attr('data-entity-route') + '?id=' + $item.attr('data-id');
} }
if (confirm(l.common_are_you_sure)) { if (confirm(l.js_common_are_you_sure)) {
document.location.href = route; document.location.href = route;
} }
}); });
@ -134,7 +134,13 @@ jQuery(function ($) {
selectEpxlrLink(verticalNeighbors.above.find('.explr-link')); selectEpxlrLink(verticalNeighbors.above.find('.explr-link'));
} else if (e.key === "ArrowDown" && verticalNeighbors.below) { } else if (e.key === "ArrowDown" && verticalNeighbors.below) {
selectEpxlrLink(verticalNeighbors.below.find('.explr-link')); selectEpxlrLink(verticalNeighbors.below.find('.explr-link'));
} else if (e.key === "Backspace") {
if ($('.explr-item-delete:visible').length) {
$('.explr-item-delete:visible').click();
}
} }
} else if (e.key.indexOf('Arrow') === 0) {
selectEpxlrLink($('.explr-dirview li:visible:eq(0)').find('.explr-link'));
} }
}); });

View File

@ -18,7 +18,7 @@ const hideDropdowns = function () {
const explrSidebarOpenFromFolder = function (folderId) { const explrSidebarOpenFromFolder = function (folderId) {
const $leaf = $('.li-explr-folder-' + folderId); const $leaf = $('.li-explr-folder-' + folderId);
let $parent = $leaf; let $parent = $leaf;
while($parent.length > 0) { while ($parent.length > 0) {
const $toggler = $parent.find('.explr-toggler:eq(0)'); const $toggler = $parent.find('.explr-toggler:eq(0)');
if ($toggler.hasClass('explr-plus')) { if ($toggler.hasClass('explr-plus')) {
$parent.find('.explr-toggler:eq(0)').trigger('click'); $parent.find('.explr-toggler:eq(0)').trigger('click');
@ -112,7 +112,7 @@ jQuery(document).ready(function ($) {
$('#entity-utrack-updated-at').val(prettyTimestamp(entity.updated_at * 1000)); $('#entity-utrack-updated-at').val(prettyTimestamp(entity.updated_at * 1000));
}); });
setTimeout(function() { setTimeout(function () {
$('.alert-timeout').remove(); $('.alert-timeout').remove();
}, 3000); }, 3000);
@ -122,5 +122,17 @@ jQuery(document).ready(function ($) {
$firstInputText.focus(); $firstInputText.focus();
} }
} }
$(document).on('click', '.copy-link', function (e) {
e.preventDefault();
const $input = $('#' + $(this).attr('data-target-id'));
$input.select();
$input[0].setSelectionRange(0, 99999);
document.execCommand("copy");
if (navigator.clipboard) {
navigator.clipboard.writeText($input.val());
}
});
}); });

View File

@ -159,10 +159,8 @@
.find('ul') // hide every ul .find('ul') // hide every ul
.hide() .hide()
.end() .end()
.find('.explr-expand') // unless explicitly set to expand .find('.explr-toggler')
.show() .addClass('explr-plus '+opts.classesPlus);
.siblings('.explr-toggler')
.addClass('explr-minus '+opts.classesMinus);
} else { } else {
$tree $tree
.find('.explr-collapse') // hide every element set to collapse .find('.explr-collapse') // hide every element set to collapse

1
data/www/js/lib/qrcode.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,76 +1,24 @@
jQuery(document).ready(function ($) { jQuery(document).ready(function ($) {
const $tableActive = $('table.active-playlists');
const $tableInactive = $('table.inactive-playlists');
const getId = function ($el) {
return $el.is('tr') ? $el.attr('data-level') : $el.parents('tr:eq(0)').attr('data-level');
};
const updateTable = function () {
$('table').each(function () {
if ($(this).find('tbody tr.playlist-item:visible').length === 0) {
$(this).find('tr.empty-tr').removeClass('hidden');
} else {
$(this).find('tr.empty-tr').addClass('hidden');
}
});
};
const main = function () { const main = function () {
const qrcodeElement = document.getElementById('qrcode');
}; if (qrcodeElement) {
new QRCode(qrcodeElement, {
$(document).on('change', 'input[type=checkbox]', function () { text: qrcodeElement.attributes['data-qrcode-payload'].value,
$.ajax({ width: 128,
url: '/playlist/toggle', height: 128,
headers: {'Content-Type': 'application/json'}, colorDark: '#222',
data: JSON.stringify({id: getId($(this)), enabled: $(this).is(':checked')}), colorLight: '#fff',
method: 'POST', correctLevel: QRCode.CorrectLevel.H
}); });
const $tr = $(this).parents('tr:eq(0)').remove().clone();
if ($(this).is(':checked')) {
$tableActive.append($tr);
} else {
$tableInactive.append($tr);
} }
};
updateTable();
});
$(document).on('click', '.playlist-add', function () { $(document).on('click', '.playlist-add', function () {
showModal('modal-playlist-add'); showModal('modal-playlist-add');
$('.modal-playlist-add input:eq(0)').focus().select(); $('.modal-playlist-add input:eq(0)').focus().select();
}); });
$(document).on('click', '.playlist-edit', function () {
const playlist = JSON.parse($(this).parents('tr:eq(0)').attr('data-entity'));
showModal('modal-playlist-edit');
$('.modal-playlist-edit input:visible:eq(0)').focus().select();
$('#playlist-edit-name').val(playlist.name);
$('#playlist-edit-time-sync').val(playlist.time_sync ? '1' : '0');
$('#playlist-edit-id').val(playlist.id);
});
$(document).on('click', '.playlist-delete', function () {
if (confirm(l.js_playlist_delete_confirmation)) {
const $tr = $(this).parents('tr:eq(0)');
$.ajax({
method: 'DELETE',
url: '/playlist/delete',
headers: {'Content-Type': 'application/json'},
data: JSON.stringify({id: getId($(this))}),
success: function(data) {
$tr.remove();
updateTable();
},
error: function(data) {
$('.alert-error').html(data.responseJSON.message).removeClass('hidden');
}
});
}
});
main(); main();
}); });

View File

@ -36,7 +36,7 @@ main {
margin-right: 20px; margin-right: 20px;
.trigger { .trigger {
color: white; color: $white;
.avatar { .avatar {
width: 32px; width: 32px;

View File

@ -28,6 +28,15 @@ body, html {
align-self: stretch; align-self: stretch;
} }
.vertical {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
flex: 1;
align-self: stretch;
}
main { main {
flex: 1; flex: 1;
display: flex; display: flex;
@ -51,7 +60,7 @@ main {
border-bottom: $layoutBorder; border-bottom: $layoutBorder;
h1 { h1 {
color: white; color: $white;
font-weight: 600; font-weight: 600;
font-size: 24px; font-size: 24px;
} }
@ -63,16 +72,13 @@ main {
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
.btn,
button { button {
margin-left: 10px; margin-left: 10px;
} }
} }
} }
.alert {
}
.bottom-content { .bottom-content {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@ -103,7 +103,7 @@ menu {
padding-left: 10px; padding-left: 10px;
i { i {
color: white; color: $white;
opacity: .2; opacity: .2;
background: transparent; background: transparent;
display: flex; display: flex;
@ -119,7 +119,7 @@ menu {
} }
&:after { &:after {
background: white; background: $white;
content: ""; content: "";
height: 195px; height: 195px;
left: -200px; left: -200px;
@ -156,11 +156,11 @@ menu {
} }
a { a {
color: white; color: $white;
font-weight: bold; font-weight: bold;
i { i {
color: white; color: $white;
opacity: 1; opacity: 1;
} }
} }

View File

@ -1,29 +1,36 @@
.alert { .alert {
padding: 20px 20px; padding: 20px 20px;
align-self: stretch; align-self: stretch;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
border-radius: 4px; border-radius: 4px;
a {
color: inherit;
margin-left: 4px;
margin-right: 4px;
text-decoration: underline;
}
} }
.alert-info { .alert-info {
color: $info; color: $info;
background: rgba($info, .2); background: rgba($info, .2);
} }
.alert-success { .alert-success {
color: $success; color: $success;
background: rgba($success, .2); background: rgba($success, .2);
} }
.alert-danger, .alert-danger,
.alert-error { .alert-error {
color: $danger; color: $danger;
background: rgba($danger, .2); background: rgba($danger, .2);
} }
.alert i { .alert i {
margin-right: 13px; margin-right: 13px;
} }

View File

@ -38,7 +38,7 @@
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
color: white; color: $white;
text-align: center; text-align: center;
padding: 0 3px; padding: 0 3px;

View File

@ -4,7 +4,7 @@ button,
$shadowOffset: 2px; $shadowOffset: 2px;
position: relative; position: relative;
padding: 10px 13px 8px 10px; padding: 10px 10px 8px 10px;
font-size: 14px; font-size: 14px;
color: #fff; color: #fff;
cursor: pointer; cursor: pointer;
@ -35,15 +35,48 @@ button,
color: #AAA; color: #AAA;
background: $neutralGrey; background: $neutralGrey;
box-shadow: 0 $shadowOffset 0 0 darken($neutralGrey, 10%); box-shadow: 0 $shadowOffset 0 0 darken($neutralGrey, 10%);
&:hover { box-shadow: 0 $shadowOffset 0 1px #222 inset; background: darken($neutralGrey, 10%); }
&:focus { background: darken($neutralGrey, 20%); } &:hover {
box-shadow: 0 $shadowOffset 0 1px #222 inset;
background: darken($neutralGrey, 10%);
}
&:focus {
background: darken($neutralGrey, 20%);
}
}
.btn-wire-neutral {
background: transparent;
border: 2px solid $neutralGrey;
color: rgba($white, .8);
box-shadow: none;
&:hover {
background: rgba($neutralGrey, 0.05);
border-color: darken($neutralGrey, 10%);
color: darken($neutralGrey, 10%);
box-shadow: none;
}
&:focus {
border-color: darken($neutralGrey, 20%);
background: transparent;
}
} }
&.btn-naked { &.btn-naked {
background: transparent; background: transparent;
box-shadow: none; box-shadow: none;
&:hover { box-shadow: 0 $shadowOffset 0 1px #222 inset; background: darken($neutralGrey, 10%); }
&:focus { background: darken($neutralGrey, 20%); } &:hover {
box-shadow: 0 $shadowOffset 0 1px #222 inset;
background: darken($neutralGrey, 10%);
}
&:focus {
background: darken($neutralGrey, 20%);
}
} }
} }

View File

@ -52,7 +52,7 @@
a { a {
padding: 8px 16px 8px 8px; padding: 8px 16px 8px 8px;
color: white; color: $white;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;

View File

@ -7,3 +7,18 @@ span.empty {
padding: 2px 4px; padding: 2px 4px;
font-weight: bold; font-weight: bold;
} }
.inner-empty {
display: flex;
flex: 1;
align-self: stretch;
justify-content: center;
align-items: center;
i {
font-size: 90px;
opacity: 0.3;
text-shadow: 0 -1px #333, 0 0px .5px #444;
}
}

View File

@ -19,11 +19,11 @@ ul.explr-tree {
} }
a { a {
color: white; color: $white;
padding-right: 80px; padding-right: 80px;
&:hover { &:hover {
color: white; color: $white;
} }
&.active { &.active {

View File

@ -22,7 +22,7 @@
background: $layoutBackground; background: $layoutBackground;
border-radius: 10px; border-radius: 10px;
color: lighten($black, 20%); color: lighten($black, 20%);
padding: 40px; padding: 40px;
box-shadow: 0 2px #222; box-shadow: 0 2px #222;
border: 1px solid #222; border: 1px solid #222;
@ -30,15 +30,27 @@
h2 { h2 {
padding: 0; padding: 0;
margin: 0 0 30px 0; margin: 0 0 30px 0;
font-weight: normal; font-weight: normal;
color: #999; color: #999;
} }
h3 { h3 {
align-self: stretch; align-self: stretch;
border-bottom: 1px solid $lightGrey;
padding: 15px 15px;
margin: 0; margin: 0;
font-size: 14px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
color: white;
padding-bottom: 10px;
text-decoration: none;
&.divide {
border-top: 1px solid #222;
margin-top: 20px;
padding-top: 20px;
}
} }
} }
} }

View File

@ -118,16 +118,16 @@ table.panes {
td { td {
font-weight: bold; font-weight: bold;
color: white; color: $white;
i.icon-legend { i.icon-legend {
color: white; color: $white;
} }
span, span,
i.icon-value { i.icon-value {
background-color: rgba($white, .3); background-color: rgba($white, .3);
color: white; color: $white;
} }
&.description { &.description {

View File

@ -31,7 +31,7 @@ ul.pills {
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
color: white; color: $white;
overflow: hidden; overflow: hidden;
padding-right: 30px; padding-right: 30px;
text-align: center; text-align: center;

View File

@ -1,116 +1,66 @@
.pure-material-switch { $toggleActiveColor: $limeGreen;
z-index: 0; $containerWidth: 42px;
position: relative; $containerHeight: 26px;
display: inline-block; $containerRadius: 15px;
} $containerShadowActive: 0 2px 2px #222 inset;
$containerShadowInactive: 0 2px 2px #111 inset;
$backgroundColorInactive: #222;
$backgroundColorActive: darken($toggleActiveColor, 30%);
$thumbColorActive: $toggleActiveColor;
$thumbColorInactive: #777;
$thumbWidth: 18px;
$thumbHeight: $thumbWidth;
$borderSize: 1px;
$animationSpeed: 0.2s;
.pure-material-switch > input { .toggle {
appearance: none; position: relative;
-moz-appearance: none; display: flex;
-webkit-appearance: none; flex-direction: row;
z-index: -1; justify-content: flex-start;
position: absolute; align-items: center;
right: 6px;
top: -8px;
display: block;
margin: 0;
border-radius: 50%;
width: 40px;
height: 40px;
background-color: rgba($black, 0.38);
outline: none;
opacity: 0;
transform: scale(1);
pointer-events: none;
transition: opacity 0.3s 0.1s, transform 0.2s 0.1s;
}
.pure-material-switch > span { input {
display: inline-block; display: none;
width: 100%;
cursor: pointer;
}
.pure-material-switch > span::before { &:checked + label {
content: ""; background: darken($thumbColorActive, 30%);
float: right; border: $borderSize solid rgba($white, .1);
display: inline-block; box-shadow: $containerShadowActive;
margin: 5px 0 5px 10px;
border-radius: 7px;
width: 36px;
height: 14px;
background-color: rgba($black, 0.38);
vertical-align: top;
transition: background-color 0.2s, opacity 0.2s;
}
.pure-material-switch > span::after { &::after {
content: ""; content: "";
position: absolute; display: block;
top: 2px; border-radius: 50%;
right: 16px; margin-left: calc($containerWidth - 21px);
border-radius: 50%; width: $thumbWidth;
width: 20px; height: $thumbHeight;
height: 20px; transition: $animationSpeed;
background-color: $white; background: $thumbColorActive;
box-shadow: 0 3px 1px -2px rgba($black, 0.2), 0 2px 2px 0 rgba($black, 0.14), 0 1px 5px 0 rgba($black, 0.12); box-shadow: 0 2px darken($thumbColorActive, 40%);
transition: background-color 0.2s, transform 0.2s; }
} }
}
.pure-material-switch > input:checked { label {
right: -10px; width: $containerWidth + ($borderSize * 2);
background-color: $limeGreen; height: $containerHeight;
} border-radius: $containerRadius;
background: $backgroundColorInactive;
cursor: pointer;
border: $borderSize solid rgba($white, .1);
box-shadow: $containerShadowInactive;
.pure-material-switch > input:checked + span::before { &::after {
background-color: rgba($limeGreen, 0.6); content: "";
} display: block;
border-radius: 50%;
.pure-material-switch > input:checked + span::after { width: $thumbWidth;
background-color: $limeGreen; height: $thumbHeight;
transform: translateX(16px); margin: 3px;
} background: $thumbColorInactive;
box-shadow: 0 2px rgba(0,0,0,0.9);
.pure-material-switch:hover > input { transition: $animationSpeed;
opacity: 0.04; }
} }
.pure-material-switch > input:focus {
opacity: 0.12;
}
.pure-material-switch:hover > input:focus {
opacity: 0.16;
}
.pure-material-switch > input:active {
opacity: 1;
transform: scale(0);
transition: transform 0s, opacity 0s;
}
.pure-material-switch > input:active + span::before {
background-color: rgba($limeGreen, 0.6);
}
.pure-material-switch > input:checked:active + span::before {
background-color: rgba($black, 0.38);
}
.pure-material-switch > input:disabled {
opacity: 0;
}
.pure-material-switch > input:disabled + span {
color: $black;
opacity: 0.38;
cursor: default;
}
.pure-material-switch > input:disabled + span::before {
background-color: rgba($black, 0.38);
}
.pure-material-switch > input:checked:disabled + span::before {
background-color: rgba($limeGreen, 0.6);
} }

View File

@ -0,0 +1,117 @@
.tiles {
flex: 1;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
align-self: stretch;
.tiles-inner {
display: flex;
flex: 1;
flex-direction: column;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: flex-start;
align-self: stretch;
padding: 2px;
.tiles-empty {
}
.tile-item {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
background: #222;
align-self: stretch;
color: $white;
margin: 1px;
padding: 15px;
&:hover,
&.active {
background: #111;
&:hover {
opacity: 1;
}
}
&.disabled {
.tile-header {
.head-icon {
i {
color: #222;
}
}
}
}
.tile-header {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
align-self: stretch;
.head-icon {
flex: 1;
i {
font-size: 6px;
color: white;
opacity: .8;
display: flex;
}
}
.status-icons {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
i {
font-size: 16px;
margin-left: 10px;
}
}
}
.tile-body {
flex: 1;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
font-size: 15px;
font-weight: normal;
letter-spacing: 0.8px;
line-height: 22px;
margin: 0 0 0 10px;
flex-wrap: nowrap;
}
.tile-footer {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
margin: 0;
.foot-span {
opacity: .8;
font-size: 13px;
font-family: "Courier New";
}
}
}
}
}

View File

@ -1,10 +1,10 @@
.form-holder { .form-holder {
min-width: 686px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
align-items: flex-start; align-items: flex-start;
align-self: stretch; align-self: stretch;
flex: 1;
form { form {
max-width: 434px; max-width: 434px;
@ -24,172 +24,196 @@ form {
font-size: 14px; font-size: 14px;
margin: 0 0 25px 0; margin: 0 0 25px 0;
} }
}
.form-group { .form-group {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
align-items: flex-start; align-items: flex-start;
align-self: stretch; align-self: stretch;
width: 100%; width: 100%;
flex: 1;
margin-bottom: 20px;
label {
flex: 1; flex: 1;
margin-bottom: 20px; font-size: 12px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
align-self: stretch;
color: #666666;
&.btn-upload {
color: $white;
font-size: 14px;
flex: 0;
flex-basis: auto;
margin-top: 5px;
input[type=file] {
display: none;
}
input[type=text] {
margin-bottom: 2px;
padding-left: 0;
margin-left: 10px;
}
i {
margin-left: 3px;
margin-right: 10px;
}
}
}
.widget {
margin-top: 10px;
align-self: stretch;
display: flex;
flex-direction: row;
label { div {
color: rgba($white, .7);
font-size: 14px;
}
select,
input,
textarea {
outline: none;
padding: 8px 0 5px 8px;
border-radius: 2px;
border: 1px solid rgba($white, .05);
flex: 1; flex: 1;
font-size: 12px; background: #555;
box-shadow: 0 2px 1px #444, 0 4px 2px #333 inset;
color: #DDD;
font-size: 14px;
&[disabled] {
color: #555;
background: none;
box-shadow: none;
border: none;
border-bottom: 1px solid #333;
border-radius: 0;
}
}
}
&.tab-select {
border-bottom: 1px solid #444;
display: flex;
flex-direction: row;
position: relative;
height: 48px;
padding: 48px 0 0 0;
flex: 0;
flex-basis: auto;
.widget {
height: 49px;
margin-top: 0;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
align-self: stretch; position: absolute;
color: #666666; top: 0;
left: 0;
border-bottom: 2px solid $seaBlue;
color: $seaBlue;
&.btn-upload { select {
color: white; border: none;
font-size: 14px; background: none;
flex: 0; box-shadow: none;
flex-basis: auto; padding: 10px 35px 10px 10px;
margin-top: 5px; margin: 0;
color: inherit;
input[type=file] { appearance: none;
display: none; -moz-appearance: none;
} -webkit-appearance: none;
text-align: left;
input[type=text] { font-weight: bold;
margin-bottom: 2px; cursor: pointer;
padding-left: 0; border-top-left-radius: 4px;
margin-left: 10px; border-top-right-radius: 4px;
} border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
i { white-space: nowrap;
margin-left: 3px; overflow: hidden;
margin-right: 10px; text-overflow: ellipsis;
} max-width: 200px;
} z-index: 2;
}
.widget {
margin-top: 10px;
align-self: stretch;
display: flex;
flex-direction: row;
div {
color: rgba($white, .7);
font-size: 14px;
} }
select, i {
input, margin-left: 10px;
textarea { margin-right: 0;
outline: none;
padding: 8px 0 5px 8px;
border-radius: 2px;
border: 1px solid rgba($white, .05);
flex: 1;
background: #555;
box-shadow: 0 2px 1px #444, 0 4px 2px #333 inset;
color: #DDD;
font-size: 14px;
&[disabled] { &.triangle {
color: #555; margin-top: -4px;
background: none; margin-left: 0;
box-shadow: none; position: absolute;
border: none; right: 10px;
border-bottom: 1px solid #333;
border-radius: 0;
}
}
}
&.tab-select {
border-bottom: 1px solid #444;
display: flex;
flex-direction: row;
position: relative;
height: 48px;
padding: 48px 0 0 0;
flex: 0;
flex-basis: auto;
.widget {
height: 49px;
margin-top: 0;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
position: absolute;
top: 0;
left: 0;
border-bottom: 2px solid $seaBlue;
color: $seaBlue;
select {
border: none;
background: none;
box-shadow: none;
padding: 10px 35px 10px 10px;
margin: 0;
color: inherit;
appearance: none;
-moz-appearance: none;
-webkit-appearance: none;
text-align: left;
font-weight: bold;
cursor: pointer;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200px;
z-index: 2;
}
i {
margin-left: 10px;
margin-right: 0;
&.triangle {
margin-top: -4px;
margin-left: 0;
position: absolute;
right: 10px;
}
} }
} }
} }
} }
.actions { &.form-group-horizontal {
display: flex; margin: 10px 0 20px 0;
flex-direction: row; flex-direction: row;
justify-content: flex-end; justify-content: flex-start;
align-items: center; align-items: center;
align-self: stretch;
margin: 20px 0 0 0;
button { .widget {
margin-left: 25px; margin: 0;
} display: flex;
flex-direction: row;
&.actions-left {
justify-content: flex-start; justify-content: flex-start;
align-items: center;
button { }
margin-left: 0; }
margin-right: 25px; }
}
.actions {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
align-self: stretch;
margin: 20px 0 0 0;
button {
margin-left: 25px;
}
&.actions-left {
justify-content: flex-start;
button {
margin-left: 0;
margin-right: 25px;
}
}
&.actions-center {
justify-content: center;
button {
margin-left: 0;
margin-right: 0;
} }
} }
} }

View File

@ -84,5 +84,5 @@ header nav ul li a {
header nav ul li a:hover, header nav ul li a:hover,
header nav ul li.active a { header nav ul li.active a {
color: white; color: $white;
} }

View File

@ -23,8 +23,9 @@
// Legacy // Legacy
@import 'components/panes'; @import 'components/panes';
@import 'components/tiles';
@import 'components/empty'; @import 'components/empty';
//@import 'components/switches'; @import 'components/switches';
//@import 'components/cards'; //@import 'components/cards';
//@import 'components/badges'; //@import 'components/badges';

View File

@ -19,7 +19,7 @@
} }
.page-panel.right-panel { .page-panel.right-panel {
flex: 1; flex: 2;
align-self: stretch; align-self: stretch;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -29,7 +29,7 @@
padding: 20px; padding: 20px;
h3 { h3 {
color: white; color: $white;
padding: 10px 10px 10px 0; padding: 10px 10px 10px 0;
margin-bottom: 20px; margin-bottom: 20px;
font-size: 16px; font-size: 16px;

View File

@ -1,28 +1,155 @@
.view-playlist-list main .main-container { .view-playlist-list main .main-container {
.modal-playlist-qrcode {
h2 {
text-align: center;
}
.qrcode-pic {
text-align: center;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
} img {
border: 4px solid #555;
border-radius: $baseRadius;
}
}
.view-playlist-edit main .main-container { }
.bottom-content { .bottom-content {
.page-content { .page-content {
flex: 1; flex: 1;
.form-holder { &.with-right-panel {
margin: 20px 20px 20px 10px; flex: 0.5;
}
.inner {
padding: 0;
h3 {
font-size: 16px;
font-weight: 500;
color: #DDD;
text-decoration: none;
margin: 0 0 20px 0;
}
.form-holder {
margin: 20px 10px 20px 20px;
border-right: 1px solid #222;
padding-right: 20px;
flex: 1.3;
form {
max-width: initial;
}
.form-group {
flex-grow: 0;
}
}
.preview-holder {
margin: 20px 20px 20px 10px;
flex: 1;
.form-group {
flex-grow: 0;
margin-bottom: 0;
.widget {
a,
.btn {
margin-left: 10px;
}
input[type=text] {
border: none;
background: #000;
border-radius: $baseRadius;
}
}
}
h4 {
font-size: 14px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
align-self: stretch;
color: white;
padding-bottom: 10px;
text-decoration: none;
&.divide {
border-top: 1px solid #222;
margin-top: 20px;
padding-top: 20px;
}
}
p {
font-size: 12px;
line-height: 18px;
display: flex;
margin-bottom: 5px;
flex-direction: row;
justify-content: flex-start;
align-items: center;
align-self: stretch;
color: #666666;
}
.qrcode-pic {
margin-top: 10px;
img {
border: 1px dashed #555;
padding: 5px;
border-radius: $baseRadius;
}
}
.preview {
background: black;
border: 1px solid rgba($white, .3);
border-radius: $baseRadius;
justify-content: center;
align-items: center;
align-self: stretch;
display: flex;
margin: 10px 0 20px 0;
height: 300px;
iframe {
flex: 1;
align-self: stretch;
}
}
}
.slides-holder {
margin-top: 40px;
border-top: 1px solid #222;
align-self: stretch;
padding-top: 20px;
}
} }
} }
.page-panel.right-panel { .page-panel.left-panel {
flex: 0.3;
max-width: initial;
justify-content: center;
align-items: center;
display: flex;
} }
} }
} }

View File

@ -58,6 +58,29 @@
background: darken($color, 20%); background: darken($color, 20%);
} }
} }
&.btn-wire-#{"#{$name}"} {
background: transparent;
box-shadow: none;
border: 2px solid $color;
color: rgba($white, .8);
i.btn-match {
color: $color;
}
&:hover {
background: rgba($color, 0.05);
border-color: darken($color, 10%);
color: darken($color, 10%);
box-shadow: none;
}
&:focus {
border-color: darken($color, 20%);
background: transparent;
}
}
} }
} }
} }

View File

@ -68,8 +68,12 @@
"js_slideshow_content_delete_confirmation": "Are you sure?", "js_slideshow_content_delete_confirmation": "Are you sure?",
"playlist_page_title": "Playlists", "playlist_page_title": "Playlists",
"playlist_button_add": "Add a playlist", "playlist_button_add": "Add Playlist",
"playlist_panel_active": "Active playlists", "playlist_button_delete": "Delete Playlist",
"playlist_panel_about_playlist": "About playlist",
"playlist_panel_content_management": "Content management",
"playlist_panel_preview": "Playlist preview",
"playlist_panel_preview_action": "Preview",
"playlist_panel_inactive": "Inactive playlists", "playlist_panel_inactive": "Inactive playlists",
"playlist_panel_empty": "Currently, there are no playlists. %link% now.", "playlist_panel_empty": "Currently, there are no playlists. %link% now.",
"playlist_panel_th_name": "Name", "playlist_panel_th_name": "Name",
@ -78,10 +82,12 @@
"playlist_panel_th_activity": "Options", "playlist_panel_th_activity": "Options",
"playlist_form_add_title": "Add Playlist", "playlist_form_add_title": "Add Playlist",
"playlist_form_add_submit": "Add", "playlist_form_add_submit": "Add",
"playlist_form_edit_title": "Edit Playlist", "playlist_form_preview_url_desc": "You can use this link to play this playlist on any browser you want. Use copy button to get that in your clipboard.",
"playlist_form_edit_submit": "Save", "playlist_form_preview_qrcode_desc": "You can easily access your playlist using a tablet or phone. Just scan the QR code to begin.",
"playlist_form_preview_iframe_desc": "You can view the playlist without leaving this screen by starting the preview from here.",
"playlist_form_label_name": "Enter playlist name", "playlist_form_label_name": "Enter playlist name",
"playlist_form_label_time_sync": "Sync slides across players", "playlist_form_label_time_sync": "Sync slides across players",
"playlist_form_label_enabled": "Enable/Disable playlist",
"playlist_form_button_cancel": "Cancel", "playlist_form_button_cancel": "Cancel",
"js_playlist_delete_confirmation": "Are you sure?", "js_playlist_delete_confirmation": "Are you sure?",
"playlist_delete_has_slides": "Playlist has slides, please remove them before and retry", "playlist_delete_has_slides": "Playlist has slides, please remove them before and retry",
@ -165,7 +171,7 @@
"settings_variable_desc_edition_auth_enabled": "Default user credentials will be admin/admin", "settings_variable_desc_edition_auth_enabled": "Default user credentials will be admin/admin",
"settings_variable_desc_external_url": "External url (i.e: https://studio-01.company.com or http://10.10.3.100)", "settings_variable_desc_external_url": "External url (i.e: https://studio-01.company.com or http://10.10.3.100)",
"settings_variable_desc_slide_upload_limit": "Slide upload limit (in megabytes)", "settings_variable_desc_slide_upload_limit": "Slide upload limit (in megabytes)",
"settings_variable_desc_default_slide_duration": "Introduction slide duration (in seconds)", "settings_variable_desc_intro_slide_duration": "Introduction slide duration (in seconds)",
"settings_variable_desc_default_slide_time_with_seconds": "Show the seconds on the clock in the introduction slide", "settings_variable_desc_default_slide_time_with_seconds": "Show the seconds on the clock in the introduction slide",
"settings_variable_desc_polling_interval": "Refresh interval applied for settings to the player (in seconds)", "settings_variable_desc_polling_interval": "Refresh interval applied for settings to the player (in seconds)",
"settings_variable_desc_playlist_default_time_sync": "Sync slides across players for default playlist", "settings_variable_desc_playlist_default_time_sync": "Sync slides across players for default playlist",
@ -175,6 +181,7 @@
"settings_variable_desc_slide_animation_exit_effect": "Slide animation exit effect (generally better off without it)", "settings_variable_desc_slide_animation_exit_effect": "Slide animation exit effect (generally better off without it)",
"settings_variable_desc_slide_animation_speed": "Slide animation speed", "settings_variable_desc_slide_animation_speed": "Slide animation speed",
"settings_variable_desc_ro_start_counter": "Start counter",
"settings_variable_desc_ro_last_folder_content": "Current folder in content explorer", "settings_variable_desc_ro_last_folder_content": "Current folder in content explorer",
"settings_variable_desc_ro_last_folder_node_player": "Current folder in player explorer", "settings_variable_desc_ro_last_folder_node_player": "Current folder in player explorer",
"settings_variable_desc_ro_editable": "Last application reboot datetime", "settings_variable_desc_ro_editable": "Last application reboot datetime",
@ -214,6 +221,7 @@
"basic_month_11": "November", "basic_month_11": "November",
"basic_month_12": "December", "basic_month_12": "December",
"common_untitled": "<untitled>",
"common_loading": "Loading...", "common_loading": "Loading...",
"common_default_node_player_group": "Default Playgroup", "common_default_node_player_group": "Default Playgroup",
"common_default_playlist": "Default Playlist", "common_default_playlist": "Default Playlist",

View File

@ -1,294 +1,287 @@
{ {
"dynmenu_content": "Contenido", "dynmenu_content": "Contenido",
"slideshow_slide_page_title": "Descripción General del Programa",
"slideshow_slide_page_title": "Descripción General del Programa", "slideshow_slide_goto_player": "Ir al reproductor",
"slideshow_slide_goto_player": "Ir al reproductor", "slideshow_slide_refresh_player": "Actualizar reproductor",
"slideshow_slide_refresh_player": "Actualizar reproductor", "slideshow_slide_refresh_player_success": "La señal de actualización del reproductor ha sido enviada, debería suceder pronto (%time% segundos máximo)",
"slideshow_slide_refresh_player_success": "La señal de actualización del reproductor ha sido enviada, debería suceder pronto (%time% segundos máximo)", "slideshow_slide_button_add": "Agregar una diapositiva",
"slideshow_slide_button_add": "Agregar una diapositiva", "slideshow_slide_panel_active": "Diapositivas activas",
"slideshow_slide_panel_active": "Diapositivas activas", "slideshow_slide_panel_inactive": "Diapositivas inactivas",
"slideshow_slide_panel_inactive": "Diapositivas inactivas", "slideshow_slide_panel_empty": "Actualmente, no hay diapositivas. %link% ahora.",
"slideshow_slide_panel_empty": "Actualmente, no hay diapositivas. %link% ahora.", "slideshow_slide_panel_th_content": "Contenido",
"slideshow_slide_panel_th_content": "Contenido", "slideshow_slide_panel_th_duration": "Termina después",
"slideshow_slide_panel_th_duration": "Termina después", "slideshow_slide_panel_th_duration_unit": "seg",
"slideshow_slide_panel_th_duration_unit": "seg", "slideshow_slide_panel_th_enabled": "Habilitado",
"slideshow_slide_panel_th_enabled": "Habilitado", "slideshow_slide_panel_th_cron_scheduled": "Inicio Programado",
"slideshow_slide_panel_th_cron_scheduled": "Inicio Programado", "slideshow_slide_panel_th_activity": "Opciones",
"slideshow_slide_panel_th_activity": "Opciones", "slideshow_slide_panel_td_cron_scheduled_loop": "Bucle",
"slideshow_slide_panel_td_cron_scheduled_loop": "Bucle", "slideshow_slide_panel_td_cron_scheduled_notify": "Notificar",
"slideshow_slide_panel_td_cron_scheduled_notify": "Notificar", "slideshow_slide_panel_td_cron_scheduled_bad_cron": "Valor de cron incorrecto",
"slideshow_slide_panel_td_cron_scheduled_bad_cron": "Valor de cron incorrecto", "slideshow_slide_form_add_title": "Agregar Diapositiva",
"slideshow_slide_form_add_title": "Agregar Diapositiva", "slideshow_slide_form_add_submit": "Agregar",
"slideshow_slide_form_add_submit": "Agregar", "slideshow_slide_form_edit_title": "Editar Diapositiva",
"slideshow_slide_form_edit_title": "Editar Diapositiva", "slideshow_slide_form_edit_submit": "Guardar",
"slideshow_slide_form_edit_submit": "Guardar", "slideshow_slide_form_section_content": "Medios",
"slideshow_slide_form_section_content": "Medios", "slideshow_slide_form_section_scheduling": "Programación",
"slideshow_slide_form_section_scheduling": "Programación", "slideshow_slide_form_label_name": "Nombre",
"slideshow_slide_form_label_name": "Nombre", "slideshow_slide_form_label_add_content": "Agregar a la biblioteca",
"slideshow_slide_form_label_add_content": "Agregar a la biblioteca", "slideshow_slide_form_label_from_library": "Dalla biblioteca",
"slideshow_slide_form_label_from_library": "Dalla biblioteca", "slideshow_slide_form_label_content_id": "Contenido",
"slideshow_slide_form_label_content_id": "Contenido", "slideshow_slide_form_label_location": "Ubicación",
"slideshow_slide_form_label_location": "Ubicación", "slideshow_slide_form_label_type": "Tipo",
"slideshow_slide_form_label_type": "Tipo", "slideshow_slide_form_label_object": "Objeto",
"slideshow_slide_form_label_object": "Objeto", "slideshow_slide_form_label_duration": "Duración",
"slideshow_slide_form_label_duration": "Duración", "slideshow_slide_form_label_duration_unit": "segundos",
"slideshow_slide_form_label_duration_unit": "segundos", "slideshow_slide_form_label_is_notification": "Actuar como notificación",
"slideshow_slide_form_label_is_notification": "Actuar como notificación", "slideshow_slide_form_label_cron_scheduled": "Inicio",
"slideshow_slide_form_label_cron_scheduled": "Inicio", "slideshow_slide_form_label_cron_scheduled_end": "Fin",
"slideshow_slide_form_label_cron_scheduled_end": "Fin", "slideshow_slide_form_label_cron_scheduled_loop": "Siempre en bucle",
"slideshow_slide_form_label_cron_scheduled_loop": "Siempre en bucle", "slideshow_slide_form_label_cron_scheduled_duration": "Duración",
"slideshow_slide_form_label_cron_scheduled_duration": "Duración", "slideshow_slide_form_label_cron_scheduled_stayloop": "Seguir el bucle",
"slideshow_slide_form_label_cron_scheduled_stayloop": "Seguir el bucle", "slideshow_slide_form_label_cron_scheduled_duration_unit": "segundos",
"slideshow_slide_form_label_cron_scheduled_duration_unit": "segundos", "slideshow_slide_form_label_cron_scheduled_datetime": "Fecha y Hora",
"slideshow_slide_form_label_cron_scheduled_datetime": "Fecha y Hora", "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Establecer una fecha y hora",
"slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Establecer una fecha y hora", "slideshow_slide_form_label_cron_scheduled_cron": "Cron",
"slideshow_slide_form_label_cron_scheduled_cron": "Cron", "slideshow_slide_form_widget_cron_scheduled_placeholder": "Usar formato crontab: * * * * *",
"slideshow_slide_form_widget_cron_scheduled_placeholder": "Usar formato crontab: * * * * *", "slideshow_slide_form_button_cancel": "Cancelar",
"slideshow_slide_form_button_cancel": "Cancelar", "js_slideshow_slide_delete_confirmation": "¿Estás seguro?",
"js_slideshow_slide_delete_confirmation": "¿Estás seguro?", "slideshow_content_page_title": "Biblioteca de contenidos",
"slideshow_content_button_add": "Nuevo Contenido",
"slideshow_content_page_title": "Biblioteca de contenidos", "slideshow_content_referenced_in_slide_error": "Se hace referencia al contenido en una diapositiva; elimine la diapositiva primero",
"slideshow_content_button_add": "Nuevo Contenido", "slideshow_content_panel_active": "Contenido",
"slideshow_content_referenced_in_slide_error": "Se hace referencia al contenido en una diapositiva; elimine la diapositiva primero", "slideshow_content_panel_empty": "Actualmente, no hay contenido. %link% ahora.",
"slideshow_content_panel_active": "Contenido", "slideshow_content_panel_th_name": "Nombre",
"slideshow_content_panel_empty": "Actualmente, no hay contenido. %link% ahora.", "slideshow_content_panel_th_activity": "Opciones",
"slideshow_content_panel_th_name": "Nombre", "slideshow_content_form_add_title": "Agregar Contenido",
"slideshow_content_panel_th_activity": "Opciones", "slideshow_content_form_add_submit": "Agregar",
"slideshow_content_form_add_title": "Agregar Contenido", "slideshow_content_form_edit_title": "Editar Contenido",
"slideshow_content_form_add_submit": "Agregar", "slideshow_content_form_edit_submit": "Guardar",
"slideshow_content_form_edit_title": "Editar Contenido", "slideshow_content_form_label_name": "Nombre",
"slideshow_content_form_edit_submit": "Guardar", "slideshow_content_form_label_location": "Ubicación",
"slideshow_content_form_label_name": "Nombre", "slideshow_content_form_label_type": "Tipo",
"slideshow_content_form_label_location": "Ubicación", "slideshow_content_form_label_object": "Objeto",
"slideshow_content_form_label_type": "Tipo", "slideshow_content_form_button_cancel": "Cancelar",
"slideshow_content_form_label_object": "Objeto", "slideshow_content_form_button_upload": "Subir un archivo",
"slideshow_content_form_button_cancel": "Cancelar", "slideshow_content_form_button_upload_choosen": "No hay archivos seleccionados",
"slideshow_content_form_button_upload": "Subir un archivo", "js_slideshow_content_delete_confirmation": "¿Estás seguro?",
"slideshow_content_form_button_upload_choosen": "No hay archivos seleccionados", "playlist_page_title": "Playlists",
"js_slideshow_content_delete_confirmation": "¿Estás seguro?", "playlist_button_add": "Agregar Playlist",
"playlist_button_delete": "Eliminar Playlist",
"playlist_page_title": "Playlist", "playlist_panel_about_playlist": "Acerca de la playlist",
"playlist_button_add": "Agregar una lista de reproducción", "playlist_panel_content_management": "Gestión de contenido",
"playlist_panel_active": "Playlist activas", "playlist_panel_preview": "Vista previa de la playlist",
"playlist_panel_inactive": "Playlist inactivas", "playlist_panel_preview_action": "Avance",
"playlist_panel_empty": "Actualmente, no hay playlist. %link% ahora.", "playlist_panel_inactive": "Playlist inactivas",
"playlist_panel_th_name": "Nombre", "playlist_panel_empty": "Actualmente, no hay playlist. %link% ahora.",
"playlist_panel_th_duration": "Duración", "playlist_panel_th_name": "Nombre",
"playlist_panel_th_enabled": "Habilitado", "playlist_panel_th_duration": "Duración",
"playlist_panel_th_activity": "Opciones", "playlist_panel_th_enabled": "Habilitado",
"playlist_form_add_title": "Agregar Playlist", "playlist_panel_th_activity": "Opciones",
"playlist_form_add_submit": "Agregar", "playlist_form_add_title": "Agregar Playlist",
"playlist_form_edit_title": "Editar Playlist", "playlist_form_add_submit": "Agregar",
"playlist_form_edit_submit": "Guardar", "playlist_form_preview_url_desc": "Puedes usar este enlace para reproducir esta playlist en cualquier navegador que desees. Usa el botón Copiar para guardarla en tu portapapeles.",
"playlist_form_label_name": "Introduce el nombre de la playlist", "playlist_form_preview_qrcode_desc": "Puedes acceder fácilmente a tu playlist usando una tableta o un teléfono. Simplemente escanea el código QR para comenzar.",
"playlist_form_label_time_sync": "Sincronizar diapositivas entre reproductores", "playlist_form_preview_iframe_desc": "Puedes ver la playlist sin salir de esta pantalla iniciando la vista previa desde aquí.",
"playlist_form_button_cancel": "Cancelar", "playlist_form_label_name": "Introduce el nombre de la playlist",
"js_playlist_delete_confirmation": "¿Estás seguro?", "playlist_form_label_time_sync": "Sincronizar diapositivas entre reproductores",
"playlist_delete_has_slides": "La lista de reproducción tiene diapositivas, por favor elimínelas antes y reintente", "playlist_form_label_enabled": "Activar/Desactivar playlist",
"playlist_delete_has_node_player_groups": "La lista de reproducción está asignada a un playgroup", "playlist_form_button_cancel": "Cancelar",
"js_playlist_delete_confirmation": "¿Estás seguro?",
"fleet_node_player_page_title": "Reproductores", "playlist_delete_has_slides": "La playlist tiene diapositivas, por favor elimínelas antes y reintente",
"fleet_node_player_button_add": "Agregar un reproductor", "playlist_delete_has_node_player_groups": "La playlist está asignada a un playgroup",
"fleet_node_player_panel_active": "Reproductores activos", "fleet_node_player_page_title": "Reproductores",
"fleet_node_player_panel_inactive": "Reproductores inactivos", "fleet_node_player_button_add": "Agregar un reproductor",
"fleet_node_player_panel_empty": "Actualmente, no hay reproductores. %link% ahora.", "fleet_node_player_panel_active": "Reproductores activos",
"fleet_node_player_panel_th_name": "Nombre", "fleet_node_player_panel_inactive": "Reproductores inactivos",
"fleet_node_player_panel_th_host": "Host", "fleet_node_player_panel_empty": "Actualmente, no hay reproductores. %link% ahora.",
"fleet_node_player_panel_th_group_id": "Grupo", "fleet_node_player_panel_th_name": "Nombre",
"fleet_node_player_panel_th_enabled": "Habilitado", "fleet_node_player_panel_th_host": "Host",
"fleet_node_player_panel_th_activity": "Opciones", "fleet_node_player_panel_th_group_id": "Grupo",
"fleet_node_player_form_add_title": "Agregar Reproductor", "fleet_node_player_panel_th_enabled": "Habilitado",
"fleet_node_player_form_add_submit": "Agregar", "fleet_node_player_panel_th_activity": "Opciones",
"fleet_node_player_form_edit_title": "Editar Reproductor", "fleet_node_player_form_add_title": "Agregar Reproductor",
"fleet_node_player_form_edit_submit": "Guardar", "fleet_node_player_form_add_submit": "Agregar",
"fleet_node_player_form_label_name": "Nombre", "fleet_node_player_form_edit_title": "Editar Reproductor",
"fleet_node_player_form_label_group_id": "Grupo", "fleet_node_player_form_edit_submit": "Guardar",
"fleet_node_player_form_label_host": "Host", "fleet_node_player_form_label_name": "Nombre",
"fleet_node_player_form_label_operating_system": "OS", "fleet_node_player_form_label_group_id": "Grupo",
"fleet_node_player_form_button_cancel": "Cancelar", "fleet_node_player_form_label_host": "Host",
"js_fleet_node_player_delete_confirmation": "¿Estás seguro?", "fleet_node_player_form_label_operating_system": "OS",
"fleet_node_player_form_button_cancel": "Cancelar",
"fleet_node_player_group_page_title": "Playgroups", "js_fleet_node_player_delete_confirmation": "¿Estás seguro?",
"fleet_node_player_group_button_add": "Agregar Playgroup", "fleet_node_player_group_page_title": "Playgroups",
"fleet_node_player_group_panel_active": "Playgroup activos", "fleet_node_player_group_button_add": "Agregar Playgroup",
"fleet_node_player_group_panel_empty": "Actualmente, no hay playgroup. %link% ahora.", "fleet_node_player_group_panel_active": "Playgroup activos",
"fleet_node_player_group_panel_th_name": "Nombre", "fleet_node_player_group_panel_empty": "Actualmente, no hay playgroup. %link% ahora.",
"fleet_node_player_group_panel_th_playlist": "Lista de reproducción", "fleet_node_player_group_panel_th_name": "Nombre",
"fleet_node_player_group_panel_th_activity": "Opciones", "fleet_node_player_group_panel_th_playlist": "Lista de reproducción",
"fleet_node_player_group_form_add_title": "Agregar Playgroup", "fleet_node_player_group_panel_th_activity": "Opciones",
"fleet_node_player_group_form_add_submit": "Agregar", "fleet_node_player_group_form_add_title": "Agregar Playgroup",
"fleet_node_player_group_form_edit_title": "Editar Playgroup", "fleet_node_player_group_form_add_submit": "Agregar",
"fleet_node_player_group_form_edit_submit": "Guardar", "fleet_node_player_group_form_edit_title": "Editar Playgroup",
"fleet_node_player_group_form_label_name": "Nombre", "fleet_node_player_group_form_edit_submit": "Guardar",
"fleet_node_player_group_form_label_playlist_id": "Lista de reproducción", "fleet_node_player_group_form_label_name": "Nombre",
"fleet_node_player_group_form_button_cancel": "Cancelar", "fleet_node_player_group_form_label_playlist_id": "Lista de reproducción",
"js_fleet_node_player_group_delete_confirmation": "¿Estás seguro?", "fleet_node_player_group_form_button_cancel": "Cancelar",
"node_player_group_delete_has_node_player": "El playgroup tiene reproductores, por favor elimínelos o desasígnelos antes y reintente", "js_fleet_node_player_group_delete_confirmation": "¿Estás seguro?",
"node_player_group_delete_has_node_player": "El playgroup tiene reproductores, por favor elimínelos o desasígnelos antes y reintente",
"login_page_title": "Iniciar Sesión", "login_page_title": "Iniciar Sesión",
"auth_page_title": "Usuarios", "auth_page_title": "Usuarios",
"auth_user_button_add": "Agregar un usuario", "auth_user_button_add": "Agregar un usuario",
"auth_user_panel_active": "Usuarios activos", "auth_user_panel_active": "Usuarios activos",
"auth_user_panel_inactive": "Usuarios inactivos", "auth_user_panel_inactive": "Usuarios inactivos",
"auth_user_panel_empty": "Actualmente, no hay usuarios. %link% ahora.", "auth_user_panel_empty": "Actualmente, no hay usuarios. %link% ahora.",
"auth_user_panel_th_username": "Nombre de usuario", "auth_user_panel_th_username": "Nombre de usuario",
"auth_user_panel_th_enabled": "Habilitado", "auth_user_panel_th_enabled": "Habilitado",
"auth_user_panel_th_activity": "Opciones", "auth_user_panel_th_activity": "Opciones",
"auth_user_form_add_title": "Agregar Usuario", "auth_user_form_add_title": "Agregar Usuario",
"auth_user_form_add_submit": "Agregar", "auth_user_form_add_submit": "Agregar",
"auth_user_form_edit_title": "Editar Usuario", "auth_user_form_edit_title": "Editar Usuario",
"auth_user_form_edit_submit": "Guardar", "auth_user_form_edit_submit": "Guardar",
"auth_user_form_label_username": "Nombre de usuario", "auth_user_form_label_username": "Nombre de usuario",
"auth_user_form_label_password": "Contraseña", "auth_user_form_label_password": "Contraseña",
"auth_user_form_button_cancel": "Cancelar", "auth_user_form_button_cancel": "Cancelar",
"auth_user_delete_at_least_one_account": "Debe tener al menos un usuario activo mientras usa la función de autenticación", "auth_user_delete_at_least_one_account": "Debe tener al menos un usuario activo mientras usa la función de autenticación",
"js_auth_user_delete_confirmation": "¿Estás seguro?", "js_auth_user_delete_confirmation": "¿Estás seguro?",
"settings_page_title": "Configuración",
"settings_page_title": "Configuración", "settings_plugin_page_title": "Plugins",
"settings_plugin_page_title": "Plugins", "settings_variable_panel_system_variables": "Configuración general",
"settings_variable_panel_system_variables": "Configuración general", "settings_variable_panel_plugin_variables": "Configuración de plugins",
"settings_variable_panel_plugin_variables": "Configuración de plugins", "settings_variable_panel_th_description": "Descripción",
"settings_variable_panel_th_description": "Descripción", "settings_variable_panel_th_value": "Valor",
"settings_variable_panel_th_value": "Valor", "settings_variable_panel_th_activity": "Opciones",
"settings_variable_panel_th_activity": "Opciones", "settings_variable_form_edit_title": "Editar Configuración",
"settings_variable_form_edit_title": "Editar Configuración", "settings_variable_form_edit_submit": "Guardar",
"settings_variable_form_edit_submit": "Guardar", "settings_variable_form_label_name": "Nombre",
"settings_variable_form_label_name": "Nombre", "settings_variable_form_label_value": "Valor",
"settings_variable_form_label_value": "Valor", "settings_variable_form_button_cancel": "Cancelar",
"settings_variable_form_button_cancel": "Cancelar", "settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "No puede deshabilitar playlist mientras la gestión de reproductores de flota está activada",
"settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "No puede deshabilitar playlist mientras la gestión de reproductores de flota está activada", "settings_variable_desc_lang": "Idioma del servidor",
"settings_variable_desc_lang": "Idioma del servidor", "settings_variable_desc_playlist_enabled": "Habilitar gestión de playlist",
"settings_variable_desc_playlist_enabled": "Habilitar gestión de playlist", "settings_variable_desc_fleet_player_enabled": "Habilitar gestión de reproductores de flota",
"settings_variable_desc_fleet_player_enabled": "Habilitar gestión de reproductores de flota", "settings_variable_desc_edition_fleet_player_enabled": "La gestión de playlist también se habilitará",
"settings_variable_desc_edition_fleet_player_enabled": "La gestión de playlist también se habilitará", "settings_variable_desc_auth_enabled": "Habilitar gestión de autenticación",
"settings_variable_desc_auth_enabled": "Habilitar gestión de autenticación", "settings_variable_desc_edition_auth_enabled": "Las credenciales predeterminadas del usuario serán admin/admin",
"settings_variable_desc_edition_auth_enabled": "Las credenciales predeterminadas del usuario serán admin/admin", "settings_variable_desc_external_url": "URL externa (ej.: https://studio-01.company.com o http://10.10.3.100)",
"settings_variable_desc_external_url": "URL externa (ej.: https://studio-01.company.com o http://10.10.3.100)", "settings_variable_desc_slide_upload_limit": "Límite de carga de diapositivas (en megabytes)",
"settings_variable_desc_slide_upload_limit": "Límite de carga de diapositivas (en megabytes)", "settings_variable_desc_intro_slide_duration": "Duración de la diapositiva de introducción (en segundos)",
"settings_variable_desc_default_slide_duration": "Duración de la diapositiva de introducción (en segundos)", "settings_variable_desc_default_slide_time_with_seconds": "Mostrar los segundos en el reloj de la diapositiva de introducción",
"settings_variable_desc_default_slide_time_with_seconds": "Mostrar los segundos en el reloj de la diapositiva de introducción", "settings_variable_desc_polling_interval": "Intervalo de actualización aplicado para configuraciones del reproductor (en segundos)",
"settings_variable_desc_polling_interval": "Intervalo de actualización aplicado para configuraciones del reproductor (en segundos)", "settings_variable_desc_playlist_default_time_sync": "Sincronizar diapositivas entre reproductores para la playlist predeterminada",
"settings_variable_desc_playlist_default_time_sync": "Sincronizar diapositivas entre reproductores para la lista de reproducción predeterminada", "settings_variable_desc_slide_animation_enabled": "Habilitar efecto de animación entre diapositivas",
"settings_variable_desc_slide_animation_entrance_effect": "Efecto de entrada de animación de diapositiva",
"settings_variable_desc_slide_animation_enabled": "Habilitar efecto de animación entre diapositivas", "settings_variable_desc_slide_animation_exit_effect": "Efecto de salida de animación de diapositiva (generalmente mejor sin él)",
"settings_variable_desc_slide_animation_entrance_effect": "Efecto de entrada de animación de diapositiva", "settings_variable_desc_slide_animation_speed": "Velocidad de animación de diapositiva",
"settings_variable_desc_slide_animation_exit_effect": "Efecto de salida de animación de diapositiva (generalmente mejor sin él)", "settings_variable_desc_ro_start_counter": "Contador de inicio",
"settings_variable_desc_slide_animation_speed": "Velocidad de animación de diapositiva", "settings_variable_desc_ro_last_folder_content": "Carpeta actual en el explorador de contenidos",
"settings_variable_desc_ro_last_folder_node_player": "Carpeta actual en el explorador del reproductor",
"settings_variable_desc_ro_last_folder_content": "Carpeta actual en el explorador de contenidos", "settings_variable_desc_ro_editable": "Fecha y hora del último reinicio de la aplicación",
"settings_variable_desc_ro_last_folder_node_player": "Carpeta actual en el explorador del reproductor", "settings_variable_desc_ro_last_slide_update": "Fecha y hora de la última actualización de diapositiva",
"settings_variable_desc_ro_editable": "Fecha y hora del último reinicio de la aplicación", "settings_variable_desc_ro_refresh_player_request": "Fecha y hora de la última solicitud de actualización del reproductor",
"settings_variable_desc_ro_last_slide_update": "Fecha y hora de la última actualización de diapositiva", "sysinfo_page_title": "Información del sistema",
"settings_variable_desc_ro_refresh_player_request": "Fecha y hora de la última solicitud de actualización del reproductor", "sysinfo_panel_button_restart": "Reiniciar",
"sysinfo_panel_table_section_system": "Sistema",
"sysinfo_page_title": "Información del sistema", "sysinfo_panel_table_section_application": "Aplicación",
"sysinfo_panel_button_restart": "Reiniciar", "sysinfo_panel_title": "Información",
"sysinfo_panel_table_section_system": "Sistema", "sysinfo_panel_th_attribute": "Atributo",
"sysinfo_panel_table_section_application": "Aplicación", "sysinfo_panel_th_value": "Valor",
"sysinfo_panel_title": "Información", "sysinfo_panel_td_ipaddr": "Dirección IP",
"sysinfo_panel_th_attribute": "Atributo", "logs_page_title": "Logs",
"sysinfo_panel_th_value": "Valor", "logs_panel_last_logs": "Registros (últimas 100 líneas)",
"sysinfo_panel_td_ipaddr": "Dirección IP", "js_sysinfo_restart_confirmation": "¿Estás seguro?",
"logs_page_title": "Logs", "js_sysinfo_restart_loading": "Reiniciando, por favor espera...",
"logs_panel_last_logs": "Registros (últimas 100 líneas)", "basic_day_1": "Lunes",
"js_sysinfo_restart_confirmation": "¿Estás seguro?", "basic_day_2": "Martes",
"js_sysinfo_restart_loading": "Reiniciando, por favor espera...", "basic_day_3": "Miércoles",
"basic_day_4": "Jueves",
"basic_day_1": "Lunes", "basic_day_5": "Viernes",
"basic_day_2": "Martes", "basic_day_6": "Sábado",
"basic_day_3": "Miércoles", "basic_day_7": "Domingo",
"basic_day_4": "Jueves", "basic_month_1": "Enero",
"basic_day_5": "Viernes", "basic_month_2": "Febrero",
"basic_day_6": "Sábado", "basic_month_3": "Marzo",
"basic_day_7": "Domingo", "basic_month_4": "Abril",
"basic_month_1": "Enero", "basic_month_5": "Mayo",
"basic_month_2": "Febrero", "basic_month_6": "Junio",
"basic_month_3": "Marzo", "basic_month_7": "Julio",
"basic_month_4": "Abril", "basic_month_8": "Agosto",
"basic_month_5": "Mayo", "basic_month_9": "Septiembre",
"basic_month_6": "Junio", "basic_month_10": "Octubre",
"basic_month_7": "Julio", "basic_month_11": "Noviembre",
"basic_month_8": "Agosto", "basic_month_12": "Diciembre",
"basic_month_9": "Septiembre", "common_untitled": "<sin-título>",
"basic_month_10": "Octubre", "common_loading": "Cargando...",
"basic_month_11": "Noviembre", "common_default_node_player_group": "Playgroup predeterminado",
"basic_month_12": "Diciembre", "common_default_playlist": "Lista de reproducción predeterminada",
"common_unknown_ipaddr": "Dirección IP desconocida",
"common_loading": "Cargando...", "common_empty": "[Vacío]",
"common_default_node_player_group": "Playgroup predeterminado", "common_are_you_sure": "¿Estás seguro?",
"common_default_playlist": "Lista de reproducción predeterminada", "common_enable_plugin": "Habilitar este plugin",
"common_unknown_ipaddr": "Dirección IP desconocida", "common_save": "Guardar",
"common_empty": "[Vacío]", "common_cancel": "Cancelar",
"common_are_you_sure": "¿Estás seguro?", "common_close": "Cerrar",
"common_enable_plugin": "Habilitar este plugin", "common_confirm": "Confirmar",
"common_save": "Guardar", "common_submit": "Enviar",
"common_cancel": "Cancelar", "common_validate": "Validar",
"common_close": "Cerrar", "common_apply": "Aplicar",
"common_confirm": "Confirmar", "common_saved": "Los cambios se han guardado",
"common_submit": "Enviar", "common_new_folder": "Nuevo Carpeta",
"common_validate": "Validar", "common_folder_not_empty_error": "La carpeta no está vacía, primero debes eliminar su contenido",
"common_apply": "Aplicar", "logout": "Cerrar sesión",
"common_saved": "Los cambios se han guardado", "login_error_not_found": "Credenciales incorrectas",
"common_new_folder": "Nuevo Carpeta", "login_error_bad_credentials": "Credenciales incorrectas",
"common_folder_not_empty_error": "La carpeta no está vacía, primero debes eliminar su contenido", "login_form_title": "Iniciar sesión",
"logout": "Cerrar sesión", "login_form_username": "Nombre de usuario",
"login_error_not_found": "Credenciales incorrectas", "login_form_password": "Contraseña",
"login_error_bad_credentials": "Credenciales incorrectas", "login_form_submit": "Conectar",
"login_form_title": "Iniciar sesión", "utrack_title": "Acerca de los usuarios",
"login_form_username": "Nombre de usuario", "created_at": "Creado el",
"login_form_password": "Contraseña", "updated_at": "Modificado el",
"login_form_submit": "Conectar", "created_by": "Creado por",
"utrack_title": "Acerca de los usuarios", "updated_by": "Última actualización por",
"created_at": "Creado el", "close": "Cerrar",
"updated_at": "Modificado el", "anonymous": "Anónimo",
"created_by": "Creado por", "enum_animation_speed_slower": "Más lento",
"updated_by": "Última actualización por", "enum_animation_speed_slow": "Lento",
"close": "Cerrar", "enum_animation_speed_normal": "Normal",
"anonymous": "Anónimo", "enum_animation_speed_fast": "Rápido",
"enum_animation_speed_faster": "Más rápido",
"enum_animation_speed_slower": "Más lento", "enum_variable_section_general": "1. General",
"enum_animation_speed_slow": "Lento", "enum_variable_section_player_options": "2. Opciones del reproductor",
"enum_animation_speed_normal": "Normal", "enum_variable_section_player_animation": "3. Animación del reproductor",
"enum_animation_speed_fast": "Rápido", "enum_variable_section_playlist": "4. Playlist",
"enum_animation_speed_faster": "Más rápido", "enum_variable_section_fleet": "5. Gestión de flota",
"enum_variable_section_general": "1. General", "enum_variable_section_security": "6. Seguridad",
"enum_variable_section_player_options": "2. Opciones del reproductor", "enum_application_language_english": "Inglés",
"enum_variable_section_player_animation": "3. Animación del reproductor", "enum_application_language_french": "Francés",
"enum_variable_section_playlist": "4. Playlist", "enum_application_language_italian": "Italiano",
"enum_variable_section_fleet": "5. Gestión de flota", "enum_application_language_spanish": "Español",
"enum_variable_section_security": "6. Seguridad", "enum_content_type_url": "URL",
"enum_application_language_english": "Inglés", "enum_content_type_video": "Video",
"enum_application_language_french": "Francés", "enum_content_type_picture": "Imagen",
"enum_application_language_italian": "Italiano", "enum_content_type_youtube": "Youtube",
"enum_application_language_spanish": "Español", "enum_content_type_url_object_label": "Ingrese el enlace URL",
"enum_content_type_url": "URL", "enum_content_type_video_object_label": "Sube tu vídeo (solo MP4)",
"enum_content_type_video": "Video", "enum_content_type_picture_object_label": "Sube tu imagen",
"enum_content_type_picture": "Imagen", "enum_content_type_youtube_object_label": "Ingrese la URL del vídeo de Youtube",
"enum_content_type_youtube": "Youtube", "enum_operating_system_raspbian": "Raspbian",
"enum_content_type_url_object_label": "Ingrese el enlace URL", "enum_operating_system_debian": "Debian",
"enum_content_type_video_object_label": "Sube tu vídeo (solo MP4)", "enum_operating_system_windows": "Windows",
"enum_content_type_picture_object_label": "Sube tu imagen", "enum_operating_system_macos": "MacOS",
"enum_content_type_youtube_object_label": "Ingrese la URL del vídeo de Youtube", "enum_operating_system_fedora": "Fedora",
"enum_operating_system_raspbian": "Raspbian", "enum_operating_system_ubuntu": "Ubuntu",
"enum_operating_system_debian": "Debian", "enum_operating_system_suse": "Suse",
"enum_operating_system_windows": "Windows", "enum_operating_system_redhat": "RedHat",
"enum_operating_system_macos": "MacOS", "enum_operating_system_centos": "CentOS",
"enum_operating_system_fedora": "Fedora", "enum_operating_system_other": "Otro",
"enum_operating_system_ubuntu": "Ubuntu", "sysinfo_rpi_model": "Modelo de Raspberry Pi",
"enum_operating_system_suse": "Suse", "sysinfo_rpi_model_unknown": "No es una Raspberry Pi o la información del modelo no está disponible",
"enum_operating_system_redhat": "RedHat", "sysinfo_storage_free_space": "Espacio de almacenamiento libre",
"enum_operating_system_centos": "CentOS", "sysinfo_memory_usage": "Uso de memoria",
"enum_operating_system_other": "Otro", "sysinfo_os_version": "Versión del SO",
"sysinfo_install_directory": "Directorio de instalación",
"sysinfo_rpi_model": "Modelo de Raspberry Pi", "sysinfo_network_interface": "Interfaz de red",
"sysinfo_rpi_model_unknown": "No es una Raspberry Pi o la información del modelo no está disponible", "sysinfo_mac_address": "Dirección MAC",
"sysinfo_storage_free_space": "Espacio de almacenamiento libre", "sysinfo_ip_address": "Dirección IP",
"sysinfo_memory_usage": "Uso de memoria", "player_default_welcome_message": "Para gestionar este reproductor, ve a un navegador en %link%"
"sysinfo_os_version": "Versión del SO",
"sysinfo_install_directory": "Directorio de instalación",
"sysinfo_network_interface": "Interfaz de red",
"sysinfo_mac_address": "Dirección MAC",
"sysinfo_ip_address": "Dirección IP",
"player_default_welcome_message": "Para gestionar este reproductor, ve a un navegador en %link%"
} }

View File

@ -1,294 +1,288 @@
{ {
"dynmenu_content": "Contenu", "dynmenu_content": "Contenu",
"slideshow_slide_page_title": "Vue Planning",
"slideshow_slide_page_title": "Vue Planning", "slideshow_slide_goto_player": "Voir le lecteur",
"slideshow_slide_goto_player": "Voir le lecteur", "slideshow_slide_refresh_player": "Rafraîchir le lecteur",
"slideshow_slide_refresh_player": "Rafraîchir le lecteur", "slideshow_slide_refresh_player_success": "Un rafraîchissement du lecteur a été programmé, il devrait avoir lieu sous peu (%time% secondes maximum)",
"slideshow_slide_refresh_player_success": "Un rafraîchissement du lecteur a été programmé, il devrait avoir lieu sous peu (%time% secondes maximum)", "slideshow_slide_button_add": "Ajouter une slide",
"slideshow_slide_button_add": "Ajouter une slide", "slideshow_slide_panel_active": "Slides actives",
"slideshow_slide_panel_active": "Slides actives", "slideshow_slide_panel_inactive": "Slides inactives",
"slideshow_slide_panel_inactive": "Slides inactives", "slideshow_slide_panel_empty": "Actuellement, il n'y a aucune slide. %link% maintenant.",
"slideshow_slide_panel_empty": "Actuellement, il n'y a aucune slide. %link% maintenant.", "slideshow_slide_panel_th_content": "Contenu",
"slideshow_slide_panel_th_content": "Contenu", "slideshow_slide_panel_th_duration": "Fin après",
"slideshow_slide_panel_th_duration": "Fin après", "slideshow_slide_panel_th_duration_unit": "sec",
"slideshow_slide_panel_th_duration_unit": "sec", "slideshow_slide_panel_th_enabled": "Activé",
"slideshow_slide_panel_th_enabled": "Activé", "slideshow_slide_panel_th_cron_scheduled": "Programmation",
"slideshow_slide_panel_th_cron_scheduled": "Programmation", "slideshow_slide_panel_th_activity": "Options",
"slideshow_slide_panel_th_activity": "Options", "slideshow_slide_panel_td_cron_scheduled_loop": "En boucle",
"slideshow_slide_panel_td_cron_scheduled_loop": "En boucle", "slideshow_slide_panel_td_cron_scheduled_notify": "Notifie",
"slideshow_slide_panel_td_cron_scheduled_notify": "Notifie", "slideshow_slide_panel_td_cron_scheduled_bad_cron": "Mauvaise valeur cron",
"slideshow_slide_panel_td_cron_scheduled_bad_cron": "Mauvaise valeur cron", "slideshow_slide_form_add_title": "Ajout d'une slide",
"slideshow_slide_form_add_title": "Ajout d'une slide", "slideshow_slide_form_add_submit": "Ajouter",
"slideshow_slide_form_add_submit": "Ajouter", "slideshow_slide_form_edit_title": "Modification d'une slide",
"slideshow_slide_form_edit_title": "Modification d'une slide", "slideshow_slide_form_edit_submit": "Enregistrer",
"slideshow_slide_form_edit_submit": "Enregistrer", "slideshow_slide_form_section_content": "Media",
"slideshow_slide_form_section_content": "Media", "slideshow_slide_form_section_scheduling": "Programmation",
"slideshow_slide_form_section_scheduling": "Programmation", "slideshow_slide_form_label_name": "Nom",
"slideshow_slide_form_label_name": "Nom", "slideshow_slide_form_label_add_content": "Ajouter à la bibliothèque",
"slideshow_slide_form_label_add_content": "Ajouter à la bibliothèque", "slideshow_slide_form_label_from_library": "Depuis la bibliothèque",
"slideshow_slide_form_label_from_library": "Depuis la bibliothèque", "slideshow_slide_form_label_content_id": "Contenu",
"slideshow_slide_form_label_content_id": "Contenu", "slideshow_slide_form_label_location": "Chemin",
"slideshow_slide_form_label_location": "Chemin", "slideshow_slide_form_label_type": "Type",
"slideshow_slide_form_label_type": "Type", "slideshow_slide_form_label_object": "Objet",
"slideshow_slide_form_label_object": "Objet", "slideshow_slide_form_label_duration": "Durée",
"slideshow_slide_form_label_duration": "Durée", "slideshow_slide_form_label_duration_unit": "secondes",
"slideshow_slide_form_label_duration_unit": "secondes", "slideshow_slide_form_label_is_notification": "Agit comme une notification",
"slideshow_slide_form_label_is_notification": "Agit comme une notification", "slideshow_slide_form_label_cron_scheduled": "Début",
"slideshow_slide_form_label_cron_scheduled": "Début", "slideshow_slide_form_label_cron_scheduled_end": "Fin",
"slideshow_slide_form_label_cron_scheduled_end": "Fin", "slideshow_slide_form_label_cron_scheduled_loop": "Toujours en boucle",
"slideshow_slide_form_label_cron_scheduled_loop": "Toujours en boucle", "slideshow_slide_form_label_cron_scheduled_duration": "Durée",
"slideshow_slide_form_label_cron_scheduled_duration": "Durée", "slideshow_slide_form_label_cron_scheduled_stayloop": "Suit la boucle",
"slideshow_slide_form_label_cron_scheduled_stayloop": "Suit la boucle", "slideshow_slide_form_label_cron_scheduled_duration_unit": "secondes",
"slideshow_slide_form_label_cron_scheduled_duration_unit": "secondes", "slideshow_slide_form_label_cron_scheduled_datetime": "Date & Heure",
"slideshow_slide_form_label_cron_scheduled_datetime": "Date & Heure", "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Choisir une date et une heure",
"slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Choisir une date et une heure", "slideshow_slide_form_label_cron_scheduled_cron": "Cron",
"slideshow_slide_form_label_cron_scheduled_cron": "Cron", "slideshow_slide_form_widget_cron_scheduled_placeholder": "Utiliser le format crontab: * * * * *",
"slideshow_slide_form_widget_cron_scheduled_placeholder": "Utiliser le format crontab: * * * * *", "slideshow_slide_form_button_cancel": "Annuler",
"slideshow_slide_form_button_cancel": "Annuler", "js_slideshow_slide_delete_confirmation": "Êtes-vous sûr ?",
"js_slideshow_slide_delete_confirmation": "Êtes-vous sûr ?", "slideshow_content_page_title": "Bibliothèque de contenus",
"slideshow_content_button_add": "Nouveau Contenu",
"slideshow_content_page_title": "Bibliothèque de contenus", "slideshow_content_referenced_in_slide_error": "Le contenu est référencé dans une slide, supprimez d'abord la slide",
"slideshow_content_button_add": "Nouveau Contenu", "slideshow_content_panel_active": "Contenus",
"slideshow_content_referenced_in_slide_error": "Le contenu est référencé dans une slide, supprimez d'abord la slide", "slideshow_content_panel_empty": "Actuellement, il n'y a aucun contenu. %link% maintenant.",
"slideshow_content_panel_active": "Contenus", "slideshow_content_panel_th_name": "Nom",
"slideshow_content_panel_empty": "Actuellement, il n'y a aucun contenu. %link% maintenant.", "slideshow_content_panel_th_activity": "Options",
"slideshow_content_panel_th_name": "Nom", "slideshow_content_form_add_title": "Ajout d'un contenu",
"slideshow_content_panel_th_activity": "Options", "slideshow_content_form_add_submit": "Ajouter",
"slideshow_content_form_add_title": "Ajout d'un contenu", "slideshow_content_form_edit_title": "Modification d'un contenu",
"slideshow_content_form_add_submit": "Ajouter", "slideshow_content_form_edit_submit": "Enregistrer",
"slideshow_content_form_edit_title": "Modification d'un contenu", "slideshow_content_form_label_name": "Nom de l'élément",
"slideshow_content_form_edit_submit": "Enregistrer", "slideshow_content_form_label_location": "Chemin",
"slideshow_content_form_label_name": "Nom de l'élément", "slideshow_content_form_label_type": "Type",
"slideshow_content_form_label_location": "Chemin", "slideshow_content_form_label_object": "Objet",
"slideshow_content_form_label_type": "Type", "slideshow_content_form_button_cancel": "Annuler",
"slideshow_content_form_label_object": "Objet", "slideshow_content_form_button_upload": "Uploader un fichier",
"slideshow_content_form_button_cancel": "Annuler", "slideshow_content_form_button_upload_choosen": "Aucun fichier sélectionné",
"slideshow_content_form_button_upload": "Uploader un fichier", "js_slideshow_content_delete_confirmation": "Êtes-vous sûr ?",
"slideshow_content_form_button_upload_choosen": "Aucun fichier sélectionné", "playlist_page_title": "Playlists",
"js_slideshow_content_delete_confirmation": "Êtes-vous sûr ?", "playlist_button_add": "Ajouter Playlist",
"playlist_button_delete": "Supprimer Playlist",
"playlist_page_title": "Playlist", "playlist_panel_about_playlist": "À propos de la playlist",
"playlist_button_add": "Ajouter une playlist", "playlist_panel_content_management": "Elements de la playlist",
"playlist_panel_active": "Playlist actives", "playlist_panel_preview": "Playlist preview",
"playlist_panel_inactive": "Playlist inactives", "playlist_panel_preview_action": "Prévisualiser",
"playlist_panel_empty": "Actuellement, il n'y a pas de playlist. %link% maintenant.", "playlist_panel_inactive": "Playlist inactives",
"playlist_panel_th_name": "Nom", "playlist_panel_empty": "Actuellement, il n'y a pas de playlist. %link% maintenant.",
"playlist_panel_th_duration": "Durée", "playlist_panel_th_name": "Nom",
"playlist_panel_th_enabled": "Activé", "playlist_panel_th_duration": "Durée",
"playlist_panel_th_activity": "Options", "playlist_panel_th_enabled": "Activé",
"playlist_form_add_title": "Ajout d'une Playlist", "playlist_panel_th_activity": "Options",
"playlist_form_add_submit": "Ajouter", "playlist_form_add_title": "Ajout d'une Playlist",
"playlist_form_edit_title": "Modification d'une Playlist", "playlist_form_add_submit": "Ajouter",
"playlist_form_edit_submit": "Enregistrer", "playlist_form_preview_url_desc": "Vous pouvez utiliser ce lien pour lire cette playlist sur n'importe quel navigateur de votre choix. Utilisez le bouton Copier pour l'obtenir dans votre presse-papiers.",
"playlist_form_label_name": "Entrez le nom de la playlist", "playlist_form_preview_qrcode_desc": "Vous pouvez facilement accéder à votre playlist à l'aide d'une tablette ou d'un téléphone. Scannez simplement le code QR pour commencer.",
"playlist_form_label_time_sync": "Synchroniser les slides des lecteurs", "playlist_form_preview_iframe_desc": "Vous pouvez visualiser la playlist sans quitter cet écran en démarrant l'aperçu à partir d'ici.",
"playlist_form_button_cancel": "Annuler", "playlist_form_edit_submit": "Enregistrer",
"js_playlist_delete_confirmation": "Êtes-vous sûr ?", "playlist_form_label_name": "Entrez le nom de la playlist",
"playlist_delete_has_slides": "La playlist contient des slides, supprimez-les avant et réessayez", "playlist_form_label_time_sync": "Synchroniser les slides des lecteurs",
"playlist_delete_has_node_player_groups": "La playlist est attribuée à un playgroup", "playlist_form_label_enabled": "Activer/Désactiver la playlist",
"playlist_form_button_cancel": "Annuler",
"fleet_node_player_page_title": "Lecteurs", "js_playlist_delete_confirmation": "Êtes-vous sûr ?",
"fleet_node_player_button_add": "Ajouter un lecteur", "playlist_delete_has_slides": "La playlist contient des slides, supprimez-les avant et réessayez",
"fleet_node_player_panel_active": "Players actifs", "playlist_delete_has_node_player_groups": "La playlist est attribuée à un playgroup",
"fleet_node_player_panel_inactive": "Players inactifs", "fleet_node_player_page_title": "Lecteurs",
"fleet_node_player_panel_empty": "Actuellement, il n'y a pas de lecteurs. %link% maintenant.", "fleet_node_player_button_add": "Ajouter un lecteur",
"fleet_node_player_panel_th_name": "Nom", "fleet_node_player_panel_active": "Players actifs",
"fleet_node_player_panel_th_host": "Hôte", "fleet_node_player_panel_inactive": "Players inactifs",
"fleet_node_player_panel_th_group_id": "Groupe", "fleet_node_player_panel_empty": "Actuellement, il n'y a pas de lecteurs. %link% maintenant.",
"fleet_node_player_panel_th_enabled": "Activé", "fleet_node_player_panel_th_name": "Nom",
"fleet_node_player_panel_th_activity": "Options", "fleet_node_player_panel_th_host": "Hôte",
"fleet_node_player_form_add_title": "Ajout d'un lecteur", "fleet_node_player_panel_th_group_id": "Groupe",
"fleet_node_player_form_add_submit": "Ajouter", "fleet_node_player_panel_th_enabled": "Activé",
"fleet_node_player_form_edit_title": "Modification d'un lecteur", "fleet_node_player_panel_th_activity": "Options",
"fleet_node_player_form_edit_submit": "Enregistrer", "fleet_node_player_form_add_title": "Ajout d'un lecteur",
"fleet_node_player_form_label_name": "Nom", "fleet_node_player_form_add_submit": "Ajouter",
"fleet_node_player_form_label_group_id": "Groupe", "fleet_node_player_form_edit_title": "Modification d'un lecteur",
"fleet_node_player_form_label_host": "Hôte", "fleet_node_player_form_edit_submit": "Enregistrer",
"fleet_node_player_form_label_operating_system": "OS", "fleet_node_player_form_label_name": "Nom",
"fleet_node_player_form_button_cancel": "Annuler", "fleet_node_player_form_label_group_id": "Groupe",
"js_fleet_node_player_delete_confirmation": "Êtes-vous sûr ?", "fleet_node_player_form_label_host": "Hôte",
"fleet_node_player_form_label_operating_system": "OS",
"fleet_node_player_group_page_title": "Playgroups", "fleet_node_player_form_button_cancel": "Annuler",
"fleet_node_player_group_button_add": "Ajouter un Playgroup", "js_fleet_node_player_delete_confirmation": "Êtes-vous sûr ?",
"fleet_node_player_group_panel_active": "Playgroups", "fleet_node_player_group_page_title": "Playgroups",
"fleet_node_player_group_panel_empty": "Actuellement, il n'y a pas de playgroup. %link% maintenant.", "fleet_node_player_group_button_add": "Ajouter un Playgroup",
"fleet_node_player_group_panel_th_name": "Nom", "fleet_node_player_group_panel_active": "Playgroups",
"fleet_node_player_group_panel_th_playlist": "Liste de lecture", "fleet_node_player_group_panel_empty": "Actuellement, il n'y a pas de playgroup. %link% maintenant.",
"fleet_node_player_group_panel_th_activity": "Options", "fleet_node_player_group_panel_th_name": "Nom",
"fleet_node_player_group_form_add_title": "Ajout d'un playgroup", "fleet_node_player_group_panel_th_playlist": "Liste de lecture",
"fleet_node_player_group_form_add_submit": "Ajouter", "fleet_node_player_group_panel_th_activity": "Options",
"fleet_node_player_group_form_edit_title": "Modification d'un playgroup", "fleet_node_player_group_form_add_title": "Ajout d'un playgroup",
"fleet_node_player_group_form_edit_submit": "Enregistrer", "fleet_node_player_group_form_add_submit": "Ajouter",
"fleet_node_player_group_form_label_name": "Nom", "fleet_node_player_group_form_edit_title": "Modification d'un playgroup",
"fleet_node_player_group_form_label_playlist_id": "Liste de lecture", "fleet_node_player_group_form_edit_submit": "Enregistrer",
"fleet_node_player_group_form_button_cancel": "Annuler", "fleet_node_player_group_form_label_name": "Nom",
"js_fleet_node_player_group_delete_confirmation": "Êtes-vous sûr ?", "fleet_node_player_group_form_label_playlist_id": "Liste de lecture",
"node_player_group_delete_has_node_player": "Le playgroup a des lecteurs, supprimez-les ou réassignez-les avant de le supprimer", "fleet_node_player_group_form_button_cancel": "Annuler",
"js_fleet_node_player_group_delete_confirmation": "Êtes-vous sûr ?",
"login_page_title": "Connexion", "node_player_group_delete_has_node_player": "Le playgroup a des lecteurs, supprimez-les ou réassignez-les avant de le supprimer",
"auth_page_title": "Utilisateurs", "login_page_title": "Connexion",
"auth_user_button_add": "Ajouter un utilisateur", "auth_page_title": "Utilisateurs",
"auth_user_panel_active": "Utilisateurs actifs", "auth_user_button_add": "Ajouter un utilisateur",
"auth_user_panel_inactive": "Utilisateurs inactifs", "auth_user_panel_active": "Utilisateurs actifs",
"auth_user_panel_empty": "Actuellement, il n'y a pas d'utilisateurs. %link% maintenant.", "auth_user_panel_inactive": "Utilisateurs inactifs",
"auth_user_panel_th_username": "Nom d'utilisateur", "auth_user_panel_empty": "Actuellement, il n'y a pas d'utilisateurs. %link% maintenant.",
"auth_user_panel_th_enabled": "Activé", "auth_user_panel_th_username": "Nom d'utilisateur",
"auth_user_panel_th_activity": "Options", "auth_user_panel_th_enabled": "Activé",
"auth_user_form_add_title": "Ajout d'un utilisateur", "auth_user_panel_th_activity": "Options",
"auth_user_form_add_submit": "Ajouter", "auth_user_form_add_title": "Ajout d'un utilisateur",
"auth_user_form_edit_title": "Modification d'un utilisateur", "auth_user_form_add_submit": "Ajouter",
"auth_user_form_edit_submit": "Enregistrer", "auth_user_form_edit_title": "Modification d'un utilisateur",
"auth_user_form_label_username": "Nom d'utilisateur", "auth_user_form_edit_submit": "Enregistrer",
"auth_user_form_label_password": "Mot de passe", "auth_user_form_label_username": "Nom d'utilisateur",
"auth_user_form_button_cancel": "Annuler", "auth_user_form_label_password": "Mot de passe",
"auth_user_delete_at_least_one_account": "Vous devez avoir au moins un utilisateur actif lorsque vous activez la gestion de l'authentification", "auth_user_form_button_cancel": "Annuler",
"js_auth_user_delete_confirmation": "Êtes-vous sûr ?", "auth_user_delete_at_least_one_account": "Vous devez avoir au moins un utilisateur actif lorsque vous activez la gestion de l'authentification",
"js_auth_user_delete_confirmation": "Êtes-vous sûr ?",
"settings_page_title": "Paramètres", "settings_page_title": "Paramètres",
"settings_plugin_page_title": "Plugins", "settings_plugin_page_title": "Plugins",
"settings_variable_panel_system_variables": "Paramètres généraux", "settings_variable_panel_system_variables": "Paramètres généraux",
"settings_variable_panel_plugin_variables": "Paramètres des plugins", "settings_variable_panel_plugin_variables": "Paramètres des plugins",
"settings_variable_panel_th_description": "Description", "settings_variable_panel_th_description": "Description",
"settings_variable_panel_th_value": "Valeur", "settings_variable_panel_th_value": "Valeur",
"settings_variable_panel_th_activity": "Options", "settings_variable_panel_th_activity": "Options",
"settings_variable_form_edit_title": "Modification du paramètre", "settings_variable_form_edit_title": "Modification du paramètre",
"settings_variable_form_edit_submit": "Enregistrer", "settings_variable_form_edit_submit": "Enregistrer",
"settings_variable_form_label_name": "Nom", "settings_variable_form_label_name": "Nom",
"settings_variable_form_label_value": "Valeur", "settings_variable_form_label_value": "Valeur",
"settings_variable_form_button_cancel": "Annuler", "settings_variable_form_button_cancel": "Annuler",
"settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "Vous ne pouvez pas désactiver les playlists tant que la gestion de flotte de lecteurs est activée", "settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "Vous ne pouvez pas désactiver les playlists tant que la gestion de flotte de lecteurs est activée",
"settings_variable_desc_lang": "Langage de l'application", "settings_variable_desc_lang": "Langage de l'application",
"settings_variable_desc_playlist_enabled": "Activer la gestion des playlists", "settings_variable_desc_playlist_enabled": "Activer la gestion des playlists",
"settings_variable_desc_fleet_player_enabled": "Activer la gestion de flotte des players", "settings_variable_desc_fleet_player_enabled": "Activer la gestion de flotte des players",
"settings_variable_desc_edition_fleet_player_enabled": "Les playlists seront également activées", "settings_variable_desc_edition_fleet_player_enabled": "Les playlists seront également activées",
"settings_variable_desc_auth_enabled": "Activer la gestion de l'authentification", "settings_variable_desc_auth_enabled": "Activer la gestion de l'authentification",
"settings_variable_desc_edition_auth_enabled": "Les identifiants de l'utilisateur par défaut seront admin/admin", "settings_variable_desc_edition_auth_enabled": "Les identifiants de l'utilisateur par défaut seront admin/admin",
"settings_variable_desc_external_url": "URL externe (i.e: https://studio-01.company.com or http://10.10.3.100)", "settings_variable_desc_external_url": "URL externe (i.e: https://studio-01.company.com or http://10.10.3.100)",
"settings_variable_desc_slide_upload_limit": "Limite d'upload du fichier d'une slide (en mégaoctets)", "settings_variable_desc_slide_upload_limit": "Limite d'upload du fichier d'une slide (en mégaoctets)",
"settings_variable_desc_default_slide_duration": "Durée de la slide d'introduction (en secondes)", "settings_variable_desc_intro_slide_duration": "Durée de la slide d'introduction (en secondes)",
"settings_variable_desc_default_slide_time_with_seconds": "Afficher les secondes de l'horloge de la slide d'introduction", "settings_variable_desc_default_slide_time_with_seconds": "Afficher les secondes de l'horloge de la slide d'introduction",
"settings_variable_desc_polling_interval": "Intervalle de rafraîchissement des paramètres à appliquer au lecteur (en secondes)", "settings_variable_desc_polling_interval": "Intervalle de rafraîchissement des paramètres à appliquer au lecteur (en secondes)",
"settings_variable_desc_playlist_default_time_sync": "Synchroniser les slides des lecteurs pour la playlist par défaut", "settings_variable_desc_playlist_default_time_sync": "Synchroniser les slides des lecteurs pour la playlist par défaut",
"settings_variable_desc_slide_animation_enabled": "Activer les effets d'animation entre les slides",
"settings_variable_desc_slide_animation_enabled": "Activer les effets d'animation entre les slides", "settings_variable_desc_slide_animation_entrance_effect": "Effet d'animation d'arrivée de la slide",
"settings_variable_desc_slide_animation_entrance_effect": "Effet d'animation d'arrivée de la slide", "settings_variable_desc_slide_animation_exit_effect": "Effet d'animation de sortie de la slide (généralement mieux sans)",
"settings_variable_desc_slide_animation_exit_effect": "Effet d'animation de sortie de la slide (généralement mieux sans)", "settings_variable_desc_slide_animation_speed": "Vitesse de l'animation de la slide",
"settings_variable_desc_slide_animation_speed": "Vitesse de l'animation de la slide", "settings_variable_desc_ro_start_counter": "Compteur de démarrage",
"settings_variable_desc_ro_last_folder_content": "Dossier courant dans l'explorateur de contenu",
"settings_variable_desc_ro_last_folder_content": "Dossier courant dans l'explorateur de contenu", "settings_variable_desc_ro_last_folder_node_player": "Dossier courant dans l'explorateur du lecteur",
"settings_variable_desc_ro_last_folder_node_player": "Dossier courant dans l'explorateur du lecteur", "settings_variable_desc_ro_editable": "Date de dernier redémarrage de l'application",
"settings_variable_desc_ro_editable": "Date de dernier redémarrage de l'application", "settings_variable_desc_ro_last_slide_update": "Date de dernière modification d'une slide",
"settings_variable_desc_ro_last_slide_update": "Date de dernière modification d'une slide", "settings_variable_desc_ro_refresh_player_request": "Date de dernière demande de rafraîchissement du lecteur",
"settings_variable_desc_ro_refresh_player_request": "Date de dernière demande de rafraîchissement du lecteur", "sysinfo_page_title": "Système",
"sysinfo_panel_button_restart": "Redémarrer",
"sysinfo_page_title": "Système", "sysinfo_panel_table_section_system": "Système",
"sysinfo_panel_button_restart": "Redémarrer", "sysinfo_panel_table_section_application": "Application",
"sysinfo_panel_table_section_system": "Système", "sysinfo_panel_title": "Informations",
"sysinfo_panel_table_section_application": "Application", "sysinfo_panel_th_attribute": "Attribut",
"sysinfo_panel_title": "Informations", "sysinfo_panel_th_value": "Valeur",
"sysinfo_panel_th_attribute": "Attribut", "sysinfo_panel_td_ipaddr": "Adresse IP",
"sysinfo_panel_th_value": "Valeur", "logs_page_title": "Logs",
"sysinfo_panel_td_ipaddr": "Adresse IP", "logs_panel_last_logs": "Journaux (100 dernières lignes)",
"logs_page_title": "Logs", "js_sysinfo_restart_confirmation": "Êtes-vous sûr ?",
"logs_panel_last_logs": "Journaux (100 dernières lignes)", "js_sysinfo_restart_loading": "Redémarrage en cours, veuillez patienter...",
"js_sysinfo_restart_confirmation": "Êtes-vous sûr ?", "basic_day_1": "Lundi",
"js_sysinfo_restart_loading": "Redémarrage en cours, veuillez patienter...", "basic_day_2": "Mardi",
"basic_day_3": "Mercredi",
"basic_day_1": "Lundi", "basic_day_4": "Jeudi",
"basic_day_2": "Mardi", "basic_day_5": "Vendredi",
"basic_day_3": "Mercredi", "basic_day_6": "Samedi",
"basic_day_4": "Jeudi", "basic_day_7": "Dimanche",
"basic_day_5": "Vendredi", "basic_month_1": "Janvier",
"basic_day_6": "Samedi", "basic_month_2": "Février",
"basic_day_7": "Dimanche", "basic_month_3": "Mars",
"basic_month_1": "Janvier", "basic_month_4": "Avril",
"basic_month_2": "Février", "basic_month_5": "Mai",
"basic_month_3": "Mars", "basic_month_6": "Juin",
"basic_month_4": "Avril", "basic_month_7": "Juillet",
"basic_month_5": "Mai", "basic_month_8": "Août",
"basic_month_6": "Juin", "basic_month_9": "Septembre",
"basic_month_7": "Juillet", "basic_month_10": "Octobre",
"basic_month_8": "Août", "basic_month_11": "Novembre",
"basic_month_9": "Septembre", "basic_month_12": "Décembre",
"basic_month_10": "Octobre", "common_untitled": "<sans-titre>",
"basic_month_11": "Novembre", "common_loading": "Chargement...",
"basic_month_12": "Décembre", "common_default_node_player_group": "Playgroup par défaut",
"common_default_playlist": "Playlist par défaut",
"common_loading": "Chargement...", "common_unknown_ipaddr": "Adresse IP inconnue",
"common_default_node_player_group": "Playgroup par défaut", "common_empty": "[Vide]",
"common_default_playlist": "Playlist par défaut", "common_are_you_sure": "Êtes-vous sûr ?",
"common_unknown_ipaddr": "Adresse IP inconnue", "common_enable_plugin": "Activer ce plugin",
"common_empty": "[Vide]", "common_save": "Enregistrer",
"common_are_you_sure": "Êtes-vous sûr ?", "common_cancel": "Annuler",
"common_enable_plugin": "Activer ce plugin", "common_close": "Fermer",
"common_save": "Enregistrer", "common_confirm": "Confirmer",
"common_cancel": "Annuler", "common_submit": "Envoyer",
"common_close": "Fermer", "common_validate": "Valider",
"common_confirm": "Confirmer", "common_apply": "Appliquer",
"common_submit": "Envoyer", "common_saved": "Les modifications ont été enregistrées",
"common_validate": "Valider", "common_new_folder": "Nouveau Dossier",
"common_apply": "Appliquer", "common_folder_not_empty_error": "Le dossier n'est pas vide, vous devez d'abord supprimer son contenu",
"common_saved": "Les modifications ont été enregistrées", "logout": "Déconnexion",
"common_new_folder": "Nouveau Dossier", "login_error_not_found": "Identifiants invalides",
"common_folder_not_empty_error": "Le dossier n'est pas vide, vous devez d'abord supprimer son contenu", "login_error_bad_credentials": "Identifiants invalides",
"logout": "Déconnexion", "login_form_title": "Connexion",
"login_error_not_found": "Identifiants invalides", "login_form_username": "Identifiant",
"login_error_bad_credentials": "Identifiants invalides", "login_form_password": "Mot de passe",
"login_form_title": "Connexion", "login_form_submit": "Valider",
"login_form_username": "Identifiant", "utrack_title": "À propos des utilisateurs",
"login_form_password": "Mot de passe", "created_at": "Création le",
"login_form_submit": "Valider", "updated_at": "Modification le",
"utrack_title": "À propos des utilisateurs", "created_by": "Création par",
"created_at": "Création le", "updated_by": "Dernière modification par",
"updated_at": "Modification le", "close": "Fermer",
"created_by": "Création par", "anonymous": "Anon",
"updated_by": "Dernière modification par", "enum_animation_speed_slower": "Très lent",
"close": "Fermer", "enum_animation_speed_slow": "Lent",
"anonymous": "Anon", "enum_animation_speed_normal": "Normal",
"enum_animation_speed_fast": "Rapide",
"enum_animation_speed_slower": "Très lent", "enum_animation_speed_faster": "Très rapide",
"enum_animation_speed_slow": "Lent", "enum_variable_section_general": "1. Général",
"enum_animation_speed_normal": "Normal", "enum_variable_section_player_options": "2. Options du lecteur",
"enum_animation_speed_fast": "Rapide", "enum_variable_section_player_animation": "3. Animation du lecteur",
"enum_animation_speed_faster": "Très rapide", "enum_variable_section_playlist": "4. Playlists",
"enum_variable_section_general": "1. Général", "enum_variable_section_fleet": "5. Gestion de flotte",
"enum_variable_section_player_options": "2. Options du lecteur", "enum_variable_section_security": "6. Sécurité",
"enum_variable_section_player_animation": "3. Animation du lecteur", "enum_application_language_english": "Anglais",
"enum_variable_section_playlist": "4. Playlists", "enum_application_language_french": "Français",
"enum_variable_section_fleet": "5. Gestion de flotte", "enum_application_language_italian": "Italien",
"enum_variable_section_security": "6. Sécurité", "enum_application_language_spanish": "Espagnol",
"enum_application_language_english": "Anglais", "enum_content_type_url": "URL",
"enum_application_language_french": "Français", "enum_content_type_video": "Vidéo",
"enum_application_language_italian": "Italien", "enum_content_type_picture": "Image",
"enum_application_language_spanish": "Espagnol", "enum_content_type_youtube": "Youtube",
"enum_content_type_url": "URL", "enum_content_type_url_object_label": "Entrez l'URL de la page",
"enum_content_type_video": "Vidéo", "enum_content_type_video_object_label": "Uploadez votre vidéo (MP4 seulement)",
"enum_content_type_picture": "Image", "enum_content_type_picture_object_label": "Uploadez votre image",
"enum_content_type_youtube": "Youtube", "enum_content_type_youtube_object_label": "Enrez l'URL de la vidéo Youtube",
"enum_content_type_url_object_label": "Entrez l'URL de la page", "enum_operating_system_raspbian": "Raspbian",
"enum_content_type_video_object_label": "Uploadez votre vidéo (MP4 seulement)", "enum_operating_system_debian": "Debian",
"enum_content_type_picture_object_label": "Uploadez votre image", "enum_operating_system_windows": "Windows",
"enum_content_type_youtube_object_label": "Enrez l'URL de la vidéo Youtube", "enum_operating_system_macos": "MacOS",
"enum_operating_system_raspbian": "Raspbian", "enum_operating_system_fedora": "Fedora",
"enum_operating_system_debian": "Debian", "enum_operating_system_ubuntu": "Ubuntu",
"enum_operating_system_windows": "Windows", "enum_operating_system_suse": "Suse",
"enum_operating_system_macos": "MacOS", "enum_operating_system_redhat": "RedHat",
"enum_operating_system_fedora": "Fedora", "enum_operating_system_centos": "CentOS",
"enum_operating_system_ubuntu": "Ubuntu", "enum_operating_system_other": "Autre",
"enum_operating_system_suse": "Suse", "sysinfo_rpi_model": "Modèle du Raspberry Pi",
"enum_operating_system_redhat": "RedHat", "sysinfo_rpi_model_unknown": "Le modèle n'est pas un Raspberry Pi",
"enum_operating_system_centos": "CentOS", "sysinfo_storage_free_space": "Stockage Disponible",
"enum_operating_system_other": "Autre", "sysinfo_memory_usage": "Utilisation Mémoire",
"sysinfo_os_version": "Version SE",
"sysinfo_rpi_model": "Modèle du Raspberry Pi", "sysinfo_install_directory": "Dossier Racine",
"sysinfo_rpi_model_unknown": "Le modèle n'est pas un Raspberry Pi", "sysinfo_network_interface": "Interface Réseau",
"sysinfo_storage_free_space": "Stockage Disponible", "sysinfo_mac_address": "Addresse MAC",
"sysinfo_memory_usage": "Utilisation Mémoire", "sysinfo_ip_address": "Addresse IP",
"sysinfo_os_version": "Version SE", "player_default_welcome_message": "Pour gérer ce lecteur, allez sur un navigateur à l'adresse %link%"
"sysinfo_install_directory": "Dossier Racine",
"sysinfo_network_interface": "Interface Réseau",
"sysinfo_mac_address": "Addresse MAC",
"sysinfo_ip_address": "Addresse IP",
"player_default_welcome_message": "Pour gérer ce lecteur, allez sur un navigateur à l'adresse %link%"
} }

View File

@ -1,294 +1,287 @@
{ {
"dynmenu_content": "Contenuti", "dynmenu_content": "Contenuti",
"slideshow_slide_page_title": "Programmazione",
"slideshow_slide_page_title": "Programmazione", "slideshow_slide_goto_player": "Vai al player",
"slideshow_slide_goto_player": "Vai al player", "slideshow_slide_refresh_player": "Aggiorna player",
"slideshow_slide_refresh_player": "Aggiorna player", "slideshow_slide_refresh_player_success": "L' aggiornamento è stato richiesto, sarà applicato in (%time% secondi)",
"slideshow_slide_refresh_player_success": "L' aggiornamento è stato richiesto, sarà applicato in (%time% secondi)", "slideshow_slide_button_add": "Aggiungi slide",
"slideshow_slide_button_add": "Aggiungi slide", "slideshow_slide_panel_active": "Attiva slide",
"slideshow_slide_panel_active": "Attiva slide", "slideshow_slide_panel_inactive": "Slide inattive",
"slideshow_slide_panel_inactive": "Slide inattive", "slideshow_slide_panel_empty": "Attualmente, non ci sono slide. %link% adesso.",
"slideshow_slide_panel_empty": "Attualmente, non ci sono slide. %link% adesso.", "slideshow_slide_panel_th_content": "Contenuti",
"slideshow_slide_panel_th_content": "Contenuti", "slideshow_slide_panel_th_duration": "Finito in",
"slideshow_slide_panel_th_duration": "Finito in", "slideshow_slide_panel_th_duration_unit": "sec",
"slideshow_slide_panel_th_duration_unit": "sec", "slideshow_slide_panel_th_enabled": "Abilitato",
"slideshow_slide_panel_th_enabled": "Abilitato", "slideshow_slide_panel_th_cron_scheduled": "Avvia programmazione",
"slideshow_slide_panel_th_cron_scheduled": "Avvia programmazione", "slideshow_slide_panel_th_activity": "Opzioni",
"slideshow_slide_panel_th_activity": "Opzioni", "slideshow_slide_panel_td_cron_scheduled_loop": "Loop",
"slideshow_slide_panel_td_cron_scheduled_loop": "Loop", "slideshow_slide_panel_td_cron_scheduled_notify": "Notificare",
"slideshow_slide_panel_td_cron_scheduled_notify": "Notificare", "slideshow_slide_panel_td_cron_scheduled_bad_cron": "Valore cron errato",
"slideshow_slide_panel_td_cron_scheduled_bad_cron": "Valore cron errato", "slideshow_slide_form_add_title": "Aggiungi Slide",
"slideshow_slide_form_add_title": "Aggiungi Slide", "slideshow_slide_form_add_submit": "Aggiungi",
"slideshow_slide_form_add_submit": "Aggiungi", "slideshow_slide_form_edit_title": "Modifica Slide",
"slideshow_slide_form_edit_title": "Modifica Slide", "slideshow_slide_form_edit_submit": "Salva",
"slideshow_slide_form_edit_submit": "Salva", "slideshow_slide_form_section_content": "Media",
"slideshow_slide_form_section_content": "Media", "slideshow_slide_form_section_scheduling": "Programmazione",
"slideshow_slide_form_section_scheduling": "Programmazione", "slideshow_slide_form_label_name": "Nome",
"slideshow_slide_form_label_name": "Nome", "slideshow_slide_form_label_add_content": "Aggiunta alla biblioteca",
"slideshow_slide_form_label_add_content": "Aggiunta alla biblioteca", "slideshow_slide_form_label_from_library": "Dalla biblioteca",
"slideshow_slide_form_label_from_library": "Dalla biblioteca", "slideshow_slide_form_label_content_id": "Contenuti",
"slideshow_slide_form_label_content_id": "Contenuti", "slideshow_slide_form_label_location": "Posizione",
"slideshow_slide_form_label_location": "Posizione", "slideshow_slide_form_label_type": "Tipo",
"slideshow_slide_form_label_type": "Tipo", "slideshow_slide_form_label_object": "Oggetto",
"slideshow_slide_form_label_object": "Oggetto", "slideshow_slide_form_label_duration": "Durata",
"slideshow_slide_form_label_duration": "Durata", "slideshow_slide_form_label_duration_unit": "Secondi",
"slideshow_slide_form_label_duration_unit": "Secondi", "slideshow_slide_form_label_is_notification": "Agisce come una notifica",
"slideshow_slide_form_label_is_notification": "Agisce come una notifica", "slideshow_slide_form_label_cron_scheduled": "Inizio",
"slideshow_slide_form_label_cron_scheduled": "Inizio", "slideshow_slide_form_label_cron_scheduled_end": "Fine",
"slideshow_slide_form_label_cron_scheduled_end": "Fine", "slideshow_slide_form_label_cron_scheduled_loop": "Sempre in loop",
"slideshow_slide_form_label_cron_scheduled_loop": "Sempre in loop", "slideshow_slide_form_label_cron_scheduled_duration": "Durata",
"slideshow_slide_form_label_cron_scheduled_duration": "Durata", "slideshow_slide_form_label_cron_scheduled_stayloop": "Seguire il ciclo",
"slideshow_slide_form_label_cron_scheduled_stayloop": "Seguire il ciclo", "slideshow_slide_form_label_cron_scheduled_duration_unit": "secondi",
"slideshow_slide_form_label_cron_scheduled_duration_unit": "secondi", "slideshow_slide_form_label_cron_scheduled_datetime": "Data e ora",
"slideshow_slide_form_label_cron_scheduled_datetime": "Data e ora", "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Imposta Data e ora",
"slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Imposta Data e ora", "slideshow_slide_form_label_cron_scheduled_cron": "Cron",
"slideshow_slide_form_label_cron_scheduled_cron": "Cron", "slideshow_slide_form_widget_cron_scheduled_placeholder": "Utilizza formato crontab: * * * * *",
"slideshow_slide_form_widget_cron_scheduled_placeholder": "Utilizza formato crontab: * * * * *", "slideshow_slide_form_button_cancel": "Annulla",
"slideshow_slide_form_button_cancel": "Annulla", "js_slideshow_slide_delete_confirmation": "Sei sicuro?",
"js_slideshow_slide_delete_confirmation": "Sei sicuro?", "slideshow_content_page_title": "Libreria dei contenuti",
"slideshow_content_button_add": "Nuovo Contenuto",
"slideshow_content_page_title": "Libreria dei contenuti", "slideshow_content_referenced_in_slide_error": "Si fa riferimento al contenuto in una diapositiva, rimuovere prima la diapositiva",
"slideshow_content_button_add": "Nuovo Contenuto", "slideshow_content_panel_active": "Contenuti",
"slideshow_content_referenced_in_slide_error": "Si fa riferimento al contenuto in una diapositiva, rimuovere prima la diapositiva", "slideshow_content_panel_empty": "Attualmente non ci sono contenuti. %link% adesso.",
"slideshow_content_panel_active": "Contenuti", "slideshow_content_panel_th_name": "Nome",
"slideshow_content_panel_empty": "Attualmente non ci sono contenuti. %link% adesso.", "slideshow_content_panel_th_activity": "Opzioni",
"slideshow_content_panel_th_name": "Nome", "slideshow_content_form_add_title": "Aggiunta di un contenuto",
"slideshow_content_panel_th_activity": "Opzioni", "slideshow_content_form_add_submit": "Aggiungi",
"slideshow_content_form_add_title": "Aggiunta di un contenuto", "slideshow_content_form_edit_title": "Modifica di un contenuto",
"slideshow_content_form_add_submit": "Aggiungi", "slideshow_content_form_edit_submit": "Salva",
"slideshow_content_form_edit_title": "Modifica di un contenuto", "slideshow_content_form_label_name": "Nome",
"slideshow_content_form_edit_submit": "Salva", "slideshow_content_form_label_location": "Posizione",
"slideshow_content_form_label_name": "Nome", "slideshow_content_form_label_type": "Tipo",
"slideshow_content_form_label_location": "Posizione", "slideshow_content_form_label_object": "Oggetto",
"slideshow_content_form_label_type": "Tipo", "slideshow_content_form_button_cancel": "Annulla",
"slideshow_content_form_label_object": "Oggetto", "slideshow_content_form_button_upload": "Carica un file",
"slideshow_content_form_button_cancel": "Annulla", "slideshow_content_form_button_upload_choosen": "Nessun file selezionato",
"slideshow_content_form_button_upload": "Carica un file", "js_slideshow_content_delete_confirmation": "Sei sicuro?",
"slideshow_content_form_button_upload_choosen": "Nessun file selezionato", "playlist_page_title": "Playlists",
"js_slideshow_content_delete_confirmation": "Sei sicuro?", "playlist_button_add": "Aggiungi Playlist",
"playlist_button_delete": "Elimina Playlist",
"playlist_page_title": "Playlist", "playlist_panel_about_playlist": "Informazioni sulla playlist",
"playlist_button_add": "Aggiungi alla playlist", "playlist_panel_content_management": "Gestione dei contenuti",
"playlist_panel_active": "Attiva playlist", "playlist_panel_preview": "Anteprima della playlist",
"playlist_panel_inactive": "Playlist inattive", "playlist_panel_preview_action": "Anteprima",
"playlist_panel_empty": "Attualmente, non ci sono playlist. %link% adesso.", "playlist_panel_inactive": "Playlist inattive",
"playlist_panel_th_name": "Nome", "playlist_panel_empty": "Attualmente, non ci sono playlist. %link% adesso.",
"playlist_panel_th_duration": "Durata", "playlist_panel_th_name": "Nome",
"playlist_panel_th_enabled": "Abilitata", "playlist_panel_th_duration": "Durata",
"playlist_panel_th_activity": "Opzioni", "playlist_panel_th_enabled": "Abilitata",
"playlist_form_add_title": "Aggiungi Playlist", "playlist_panel_th_activity": "Opzioni",
"playlist_form_add_submit": "Aggiungi", "playlist_form_add_title": "Aggiungi Playlist",
"playlist_form_edit_title": "Modifica Playlist", "playlist_form_add_submit": "Aggiungi",
"playlist_form_edit_submit": "Salva", "playlist_form_preview_url_desc": "Puoi utilizzare questo collegamento per riprodurre questa playlist su qualsiasi browser desideri. Utilizza il pulsante Copia per inserirla negli appunti.",
"playlist_form_label_name": "Inserisci il nome della playlist", "playlist_form_preview_qrcode_desc": "Puoi accedere facilmente alla tua playlist utilizzando un tablet o un telefono. Basta scansionare il codice QR per iniziare.",
"playlist_form_label_time_sync": "Sincronizza le slide tra gli schermi", "playlist_form_preview_iframe_desc": "Puoi visualizzare la playlist senza uscire da questa schermata avviando l'anteprima da qui.",
"playlist_form_button_cancel": "Cancella", "playlist_form_label_name": "Inserisci il nome della playlist",
"js_playlist_delete_confirmation": "Sei sicuro?", "playlist_form_label_time_sync": "Sincronizza le slide tra gli schermi",
"playlist_delete_has_slides": "Sono presenti slide nella playlist, annullale e riprova", "playlist_form_label_enabled": "Abilita/Disabilita playlist",
"playlist_delete_has_node_player_groups": "La playlist è collegata ad un playgroup", "playlist_form_button_cancel": "Cancella",
"js_playlist_delete_confirmation": "Sei sicuro?",
"fleet_node_player_page_title": "Schermi", "playlist_delete_has_slides": "Sono presenti slide nella playlist, annullale e riprova",
"fleet_node_player_button_add": "Aggiungi allo schermo", "playlist_delete_has_node_player_groups": "La playlist è collegata ad un playgroup",
"fleet_node_player_panel_active": "Schermi attivi", "fleet_node_player_page_title": "Schermi",
"fleet_node_player_panel_inactive": "Schermi disattivi", "fleet_node_player_button_add": "Aggiungi allo schermo",
"fleet_node_player_panel_empty": "Attualmente, non ci sono schermi. %link% adesso.", "fleet_node_player_panel_active": "Schermi attivi",
"fleet_node_player_panel_th_name": "Nome", "fleet_node_player_panel_inactive": "Schermi disattivi",
"fleet_node_player_panel_th_host": "Host", "fleet_node_player_panel_empty": "Attualmente, non ci sono schermi. %link% adesso.",
"fleet_node_player_panel_th_group_id": "Gruppo", "fleet_node_player_panel_th_name": "Nome",
"fleet_node_player_panel_th_enabled": "Abilitato", "fleet_node_player_panel_th_host": "Host",
"fleet_node_player_panel_th_activity": "Opzioni", "fleet_node_player_panel_th_group_id": "Gruppo",
"fleet_node_player_form_add_title": "Aggiungi schermo", "fleet_node_player_panel_th_enabled": "Abilitato",
"fleet_node_player_form_add_submit": "Aggiungi", "fleet_node_player_panel_th_activity": "Opzioni",
"fleet_node_player_form_edit_title": "Modifica schermo", "fleet_node_player_form_add_title": "Aggiungi schermo",
"fleet_node_player_form_edit_submit": "Salva", "fleet_node_player_form_add_submit": "Aggiungi",
"fleet_node_player_form_label_name": "Nome", "fleet_node_player_form_edit_title": "Modifica schermo",
"fleet_node_player_form_label_group_id": "Group", "fleet_node_player_form_edit_submit": "Salva",
"fleet_node_player_form_label_host": "Host", "fleet_node_player_form_label_name": "Nome",
"fleet_node_player_form_label_operating_system": "OS", "fleet_node_player_form_label_group_id": "Group",
"fleet_node_player_form_button_cancel": "Cancella", "fleet_node_player_form_label_host": "Host",
"js_fleet_node_player_delete_confirmation": "Sei sicuro?", "fleet_node_player_form_label_operating_system": "OS",
"fleet_node_player_form_button_cancel": "Cancella",
"fleet_node_player_group_page_title": "Playgroups", "js_fleet_node_player_delete_confirmation": "Sei sicuro?",
"fleet_node_player_group_button_add": "Aggiungi Playgroup", "fleet_node_player_group_page_title": "Playgroups",
"fleet_node_player_group_panel_active": "Playgroup attivi", "fleet_node_player_group_button_add": "Aggiungi Playgroup",
"fleet_node_player_group_panel_empty": "Attualmente, non ci sono playgroup. %link% adesso.", "fleet_node_player_group_panel_active": "Playgroup attivi",
"fleet_node_player_group_panel_th_name": "Nome", "fleet_node_player_group_panel_empty": "Attualmente, non ci sono playgroup. %link% adesso.",
"fleet_node_player_group_panel_th_playlist": "Playlist", "fleet_node_player_group_panel_th_name": "Nome",
"fleet_node_player_group_panel_th_activity": "Opzioni", "fleet_node_player_group_panel_th_playlist": "Playlist",
"fleet_node_player_group_form_add_title": "Aggiungi Playgroup", "fleet_node_player_group_panel_th_activity": "Opzioni",
"fleet_node_player_group_form_add_submit": "Aggiungi", "fleet_node_player_group_form_add_title": "Aggiungi Playgroup",
"fleet_node_player_group_form_edit_title": "Modifica Playgroup", "fleet_node_player_group_form_add_submit": "Aggiungi",
"fleet_node_player_group_form_edit_submit": "Salva", "fleet_node_player_group_form_edit_title": "Modifica Playgroup",
"fleet_node_player_group_form_label_name": "Nome", "fleet_node_player_group_form_edit_submit": "Salva",
"fleet_node_player_group_form_label_playlist_id": "Playlist", "fleet_node_player_group_form_label_name": "Nome",
"fleet_node_player_group_form_button_cancel": "Cancella", "fleet_node_player_group_form_label_playlist_id": "Playlist",
"js_fleet_node_player_group_delete_confirmation": "Sei sicuro?", "fleet_node_player_group_form_button_cancel": "Cancella",
"node_player_group_delete_has_node_player": "Lo playgroup ha una playlist, rumuovila o riassegnala e riprova", "js_fleet_node_player_group_delete_confirmation": "Sei sicuro?",
"node_player_group_delete_has_node_player": "Lo playgroup ha una playlist, rumuovila o riassegnala e riprova",
"login_page_title": "Login", "login_page_title": "Login",
"auth_page_title": "Utente", "auth_page_title": "Utente",
"auth_user_button_add": "Aggiungi utente", "auth_user_button_add": "Aggiungi utente",
"auth_user_panel_active": "Utenti attivi", "auth_user_panel_active": "Utenti attivi",
"auth_user_panel_inactive": "Utenti inattivi", "auth_user_panel_inactive": "Utenti inattivi",
"auth_user_panel_empty": "Attualmente, non ci sono utenti. %link% adesso.", "auth_user_panel_empty": "Attualmente, non ci sono utenti. %link% adesso.",
"auth_user_panel_th_username": "Username", "auth_user_panel_th_username": "Username",
"auth_user_panel_th_enabled": "Abilitato", "auth_user_panel_th_enabled": "Abilitato",
"auth_user_panel_th_activity": "Opzioni", "auth_user_panel_th_activity": "Opzioni",
"auth_user_form_add_title": "Aggiungi utente", "auth_user_form_add_title": "Aggiungi utente",
"auth_user_form_add_submit": "Aggiungi", "auth_user_form_add_submit": "Aggiungi",
"auth_user_form_edit_title": "Modifica utente", "auth_user_form_edit_title": "Modifica utente",
"auth_user_form_edit_submit": "Salva", "auth_user_form_edit_submit": "Salva",
"auth_user_form_label_username": "Username", "auth_user_form_label_username": "Username",
"auth_user_form_label_password": "Password", "auth_user_form_label_password": "Password",
"auth_user_form_button_cancel": "Cancella", "auth_user_form_button_cancel": "Cancella",
"auth_user_delete_at_least_one_account": "È necessario avere almeno un utente attivo durante l'utilizzo della funzione di autenticazione", "auth_user_delete_at_least_one_account": "È necessario avere almeno un utente attivo durante l'utilizzo della funzione di autenticazione",
"js_auth_user_delete_confirmation": "Sei sicuro?", "js_auth_user_delete_confirmation": "Sei sicuro?",
"settings_page_title": "Impostazioni",
"settings_page_title": "Impostazioni", "settings_plugin_page_title": "Plugins",
"settings_plugin_page_title": "Plugins", "settings_variable_panel_system_variables": "Impostazioni generali",
"settings_variable_panel_system_variables": "Impostazioni generali", "settings_variable_panel_plugin_variables": "Impostazioni Plugin",
"settings_variable_panel_plugin_variables": "Impostazioni Plugin", "settings_variable_panel_th_description": "Descrizione",
"settings_variable_panel_th_description": "Descrizione", "settings_variable_panel_th_value": "Valore",
"settings_variable_panel_th_value": "Valore", "settings_variable_panel_th_activity": "Opzioni",
"settings_variable_panel_th_activity": "Opzioni", "settings_variable_form_edit_title": "Modifica impostazioni",
"settings_variable_form_edit_title": "Modifica impostazioni", "settings_variable_form_edit_submit": "Salva",
"settings_variable_form_edit_submit": "Salva", "settings_variable_form_label_name": "Nome",
"settings_variable_form_label_name": "Nome", "settings_variable_form_label_value": "Valore",
"settings_variable_form_label_value": "Valore", "settings_variable_form_button_cancel": "Cancella",
"settings_variable_form_button_cancel": "Cancella", "settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "Non puoi disattivare le playlist mentre è attiva la gestione degli schermi nella panoramica",
"settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "Non puoi disattivare le playlist mentre è attiva la gestione degli schermi nella panoramica", "settings_variable_desc_lang": "Lingua server",
"settings_variable_desc_lang": "Lingua server", "settings_variable_desc_playlist_enabled": "Abilita gestione playlist",
"settings_variable_desc_playlist_enabled": "Abilita gestione playlist", "settings_variable_desc_fleet_player_enabled": "Abilita panoramica gestione monitor",
"settings_variable_desc_fleet_player_enabled": "Abilita panoramica gestione monitor", "settings_variable_desc_edition_fleet_player_enabled": "Verrà abilitata anche la gestione delle playlist",
"settings_variable_desc_edition_fleet_player_enabled": "Verrà abilitata anche la gestione delle playlist", "settings_variable_desc_auth_enabled": "Abilita la gestione autenticazione",
"settings_variable_desc_auth_enabled": "Abilita la gestione autenticazione", "settings_variable_desc_edition_auth_enabled": "Le credenziali utente predefinite sono admin/admin",
"settings_variable_desc_edition_auth_enabled": "Le credenziali utente predefinite sono admin/admin", "settings_variable_desc_external_url": "Url esterno (esempio: https://studio-01.company.com or http://10.10.3.100)",
"settings_variable_desc_external_url": "Url esterno (esempio: https://studio-01.company.com or http://10.10.3.100)", "settings_variable_desc_slide_upload_limit": "Limite upload slide (in megabytes)",
"settings_variable_desc_slide_upload_limit": "Limite upload slide (in megabytes)", "settings_variable_desc_intro_slide_duration": "Durata introduzione slide (in secondi)",
"settings_variable_desc_default_slide_duration": "Durata introduzione slide (in secondi)", "settings_variable_desc_default_slide_time_with_seconds": "Mostra secondi introduzione slide",
"settings_variable_desc_default_slide_time_with_seconds": "Mostra secondi introduzione slide", "settings_variable_desc_polling_interval": "Intervallo di aggiornamento applicato per le impostazioni del monitor (in secondi)",
"settings_variable_desc_polling_interval": "Intervallo di aggiornamento applicato per le impostazioni del monitor (in secondi)", "settings_variable_desc_playlist_default_time_sync": "Sincronizza le diapositive tra i lettori per la playlist predefinita",
"settings_variable_desc_playlist_default_time_sync": "Sincronizza le diapositive tra i lettori per la playlist predefinita", "settings_variable_desc_slide_animation_enabled": "Abilita l'effetto di animazione tra le diapositive",
"settings_variable_desc_slide_animation_entrance_effect": "Effetto ingresso diapositiva",
"settings_variable_desc_slide_animation_enabled": "Abilita l'effetto di animazione tra le diapositive", "settings_variable_desc_slide_animation_exit_effect": "Effetto di uscita della diapositiva (meglio senza)",
"settings_variable_desc_slide_animation_entrance_effect": "Effetto ingresso diapositiva", "settings_variable_desc_slide_animation_speed": "Velicita animazione slide",
"settings_variable_desc_slide_animation_exit_effect": "Effetto di uscita della diapositiva (meglio senza)", "settings_variable_desc_ro_start_counter": "Avvia contatore",
"settings_variable_desc_slide_animation_speed": "Velicita animazione slide", "settings_variable_desc_ro_last_folder_content": "Cartella corrente in Esplora contenuti",
"settings_variable_desc_ro_last_folder_node_player": "Cartella corrente in Player Explorer",
"settings_variable_desc_ro_last_folder_content": "Cartella corrente in Esplora contenuti", "settings_variable_desc_ro_editable": "Data/ora dell'ultimo riavvio dell'applicazione",
"settings_variable_desc_ro_last_folder_node_player": "Cartella corrente in Player Explorer", "settings_variable_desc_ro_last_slide_update": "Data e ora dell'ultimo aggiornamento della diapositiva",
"settings_variable_desc_ro_editable": "Data/ora dell'ultimo riavvio dell'applicazione", "settings_variable_desc_ro_refresh_player_request": "Data e ora della richiesta di aggiornamento dell monitor",
"settings_variable_desc_ro_last_slide_update": "Data e ora dell'ultimo aggiornamento della diapositiva", "sysinfo_page_title": "Informazione sistema",
"settings_variable_desc_ro_refresh_player_request": "Data e ora della richiesta di aggiornamento dell monitor", "sysinfo_panel_button_restart": "Riavvia",
"sysinfo_panel_table_section_system": "Sistema",
"sysinfo_page_title": "Informazione sistema", "sysinfo_panel_table_section_application": "Applicazione",
"sysinfo_panel_button_restart": "Riavvia", "sysinfo_panel_title": "Informazioni",
"sysinfo_panel_table_section_system": "Sistema", "sysinfo_panel_th_attribute": "Attributi",
"sysinfo_panel_table_section_application": "Applicazione", "sysinfo_panel_th_value": "Valore",
"sysinfo_panel_title": "Informazioni", "sysinfo_panel_td_ipaddr": "Indirizzo ip",
"sysinfo_panel_th_attribute": "Attributi", "logs_page_title": "Logs",
"sysinfo_panel_th_value": "Valore", "logs_panel_last_logs": "Logs (ultime 100 righe)",
"sysinfo_panel_td_ipaddr": "Indirizzo ip", "js_sysinfo_restart_confirmation": "Sei sicuro?",
"logs_page_title": "Logs", "js_sysinfo_restart_loading": "Riavvio in corso, attendi...",
"logs_panel_last_logs": "Logs (ultime 100 righe)", "basic_day_1": "Lunedi",
"js_sysinfo_restart_confirmation": "Sei sicuro?", "basic_day_2": "Martedi",
"js_sysinfo_restart_loading": "Riavvio in corso, attendi...", "basic_day_3": "Mercoledi",
"basic_day_4": "Giovedi",
"basic_day_1": "Lunedi", "basic_day_5": "Venerdi",
"basic_day_2": "Martedi", "basic_day_6": "Sabato",
"basic_day_3": "Mercoledi", "basic_day_7": "Domenica",
"basic_day_4": "Giovedi", "basic_month_1": "Gennaio",
"basic_day_5": "Venerdi", "basic_month_2": "Febbrazio",
"basic_day_6": "Sabato", "basic_month_3": "Marzo",
"basic_day_7": "Domenica", "basic_month_4": "Aprile",
"basic_month_1": "Gennaio", "basic_month_5": "Maggio",
"basic_month_2": "Febbrazio", "basic_month_6": "Giugno",
"basic_month_3": "Marzo", "basic_month_7": "Luglio",
"basic_month_4": "Aprile", "basic_month_8": "Agosto",
"basic_month_5": "Maggio", "basic_month_9": "Settembre",
"basic_month_6": "Giugno", "basic_month_10": "Ottobre",
"basic_month_7": "Luglio", "basic_month_11": "Novembre",
"basic_month_8": "Agosto", "basic_month_12": "Dicembre",
"basic_month_9": "Settembre", "common_untitled": "<senza-titolo>",
"basic_month_10": "Ottobre", "common_loading": "Caricamento...",
"basic_month_11": "Novembre", "common_default_node_player_group": "Playgroup di default",
"basic_month_12": "Dicembre", "common_default_playlist": "Default playlist",
"common_unknown_ipaddr": "IP sconosciuto",
"common_loading": "Caricamento...", "common_empty": "[Empty]",
"common_default_node_player_group": "Playgroup di default", "common_are_you_sure": "Sei sicuro?",
"common_default_playlist": "Default playlist", "common_enable_plugin": "Attiva questo plugin",
"common_unknown_ipaddr": "IP sconosciuto", "common_save": "Salva",
"common_empty": "[Empty]", "common_cancel": "Annulla",
"common_are_you_sure": "Sei sicuro?", "common_close": "Chiudi",
"common_enable_plugin": "Attiva questo plugin", "common_confirm": "Conferma",
"common_save": "Salva", "common_submit": "Invia",
"common_cancel": "Annulla", "common_validate": "Convalida",
"common_close": "Chiudi", "common_apply": "Applica",
"common_confirm": "Conferma", "common_saved": "Le modifiche sono state salvate",
"common_submit": "Invia", "common_new_folder": "Nuovo Cartella",
"common_validate": "Convalida", "common_folder_not_empty_error": "La cartella non è vuota, devi prima eliminarne il contenuto",
"common_apply": "Applica", "logout": "Logout",
"common_saved": "Le modifiche sono state salvate", "login_error_not_found": "Credenziali errate",
"common_new_folder": "Nuovo Cartella", "login_error_bad_credentials": "Credenziali errate",
"common_folder_not_empty_error": "La cartella non è vuota, devi prima eliminarne il contenuto", "login_form_title": "Accedi",
"logout": "Logout", "login_form_username": "Username",
"login_error_not_found": "Credenziali errate", "login_form_password": "Password",
"login_error_bad_credentials": "Credenziali errate", "login_form_submit": "Connetti",
"login_form_title": "Accedi", "utrack_title": "Utente",
"login_form_username": "Username", "created_at": "Creato il",
"login_form_password": "Password", "updated_at": "Modificato il",
"login_form_submit": "Connetti", "created_by": "Creato da",
"utrack_title": "Utente", "updated_by": "Aggiornato da",
"created_at": "Creato il", "close": "Chiuso",
"updated_at": "Modificato il", "anonymous": "Anonimo",
"created_by": "Creato da", "enum_animation_speed_slower": "Lentamente",
"updated_by": "Aggiornato da", "enum_animation_speed_slow": "Lento",
"close": "Chiuso", "enum_animation_speed_normal": "Normale",
"anonymous": "Anonimo", "enum_animation_speed_fast": "Veloce",
"enum_animation_speed_faster": "Velocemente",
"enum_animation_speed_slower": "Lentamente", "enum_variable_section_general": "1. Generale",
"enum_animation_speed_slow": "Lento", "enum_variable_section_player_options": "2. Opzioni monitor",
"enum_animation_speed_normal": "Normale", "enum_variable_section_player_animation": "3. Animazioni monitor",
"enum_animation_speed_fast": "Veloce", "enum_variable_section_playlist": "4. Playlist",
"enum_animation_speed_faster": "Velocemente", "enum_variable_section_fleet": "5. Gestione panoramica",
"enum_variable_section_general": "1. Generale", "enum_variable_section_security": "6. Sicurezza",
"enum_variable_section_player_options": "2. Opzioni monitor", "enum_application_language_english": "Inglese",
"enum_variable_section_player_animation": "3. Animazioni monitor", "enum_application_language_french": "Francese",
"enum_variable_section_playlist": "4. Playlist", "enum_application_language_italian": "Italiano",
"enum_variable_section_fleet": "5. Gestione panoramica", "enum_application_language_spanish": "Spagnolo",
"enum_variable_section_security": "6. Sicurezza", "enum_content_type_url": "URL",
"enum_application_language_english": "Inglese", "enum_content_type_video": "Video",
"enum_application_language_french": "Francese", "enum_content_type_picture": "Immagine",
"enum_application_language_italian": "Italiano", "enum_content_type_youtube": "Youtube",
"enum_application_language_spanish": "Spagnolo", "enum_content_type_url_object_label": "Inserisci il collegamento URL",
"enum_content_type_url": "URL", "enum_content_type_video_object_label": "Carica il tuo video (solo MP4)",
"enum_content_type_video": "Video", "enum_content_type_picture_object_label": "Carica la tua immagine",
"enum_content_type_picture": "Immagine", "enum_content_type_youtube_object_label": "Inserisci l'URL del video Youtube",
"enum_content_type_youtube": "Youtube", "enum_operating_system_raspbian": "Raspbian",
"enum_content_type_url_object_label": "Inserisci il collegamento URL", "enum_operating_system_debian": "Debian",
"enum_content_type_video_object_label": "Carica il tuo video (solo MP4)", "enum_operating_system_windows": "Windows",
"enum_content_type_picture_object_label": "Carica la tua immagine", "enum_operating_system_macos": "MacOS",
"enum_content_type_youtube_object_label": "Inserisci l'URL del video Youtube", "enum_operating_system_fedora": "Fedora",
"enum_operating_system_raspbian": "Raspbian", "enum_operating_system_ubuntu": "Ubuntu",
"enum_operating_system_debian": "Debian", "enum_operating_system_suse": "Suse",
"enum_operating_system_windows": "Windows", "enum_operating_system_redhat": "RedHat",
"enum_operating_system_macos": "MacOS", "enum_operating_system_centos": "CentOS",
"enum_operating_system_fedora": "Fedora", "enum_operating_system_other": "Altro",
"enum_operating_system_ubuntu": "Ubuntu", "sysinfo_rpi_model": "Raspberry Pi Model",
"enum_operating_system_suse": "Suse", "sysinfo_rpi_model_unknown": "Informazioni Raspberry Pi non disponibili",
"enum_operating_system_redhat": "RedHat", "sysinfo_storage_free_space": "Spazio libero",
"enum_operating_system_centos": "CentOS", "sysinfo_memory_usage": "Memoria usata",
"enum_operating_system_other": "Altro", "sysinfo_os_version": "OS Version",
"sysinfo_install_directory": "Percorso installazione",
"sysinfo_rpi_model": "Raspberry Pi Model", "sysinfo_network_interface": "interfaccia di rete",
"sysinfo_rpi_model_unknown": "Informazioni Raspberry Pi non disponibili", "sysinfo_mac_address": "Indirizzo MAC",
"sysinfo_storage_free_space": "Spazio libero", "sysinfo_ip_address": "indirizzo IP",
"sysinfo_memory_usage": "Memoria usata", "player_default_welcome_message": "Per gestire questo lettore, vai al browser all'indirizzo %link%"
"sysinfo_os_version": "OS Version",
"sysinfo_install_directory": "Percorso installazione",
"sysinfo_network_interface": "interfaccia di rete",
"sysinfo_mac_address": "Indirizzo MAC",
"sysinfo_ip_address": "indirizzo IP",
"player_default_welcome_message": "Per gestire questo lettore, vai al browser all'indirizzo %link%"
} }

View File

@ -24,6 +24,11 @@ class Application:
signal.signal(signal.SIGINT, self.signal_handler) signal.signal(signal.SIGINT, self.signal_handler)
def start(self) -> None: def start(self) -> None:
variable = self._model_store.variable().get_one_by_name('start_counter')
if variable:
self._model_store.variable().update_by_name(variable.name, variable.as_int() + 1)
self._web_server.run() self._web_server.run()
def signal_handler(self, signal, frame) -> None: def signal_handler(self, signal, frame) -> None:

View File

@ -30,17 +30,17 @@ class AuthController(ObController):
login_error = None login_error = None
if current_user.is_authenticated: if current_user.is_authenticated:
return redirect(url_for('slideshow_slide_list')) return redirect(url_for('playlist'))
if not self._model_store.variable().map().get('auth_enabled').as_bool(): if not self._model_store.variable().map().get('auth_enabled').as_bool():
return redirect(url_for('slideshow_slide_list')) return redirect(url_for('playlist'))
if len(request.form): if len(request.form):
user = self._model_store.user().get_one_by_username(request.form['username'], enabled=True) user = self._model_store.user().get_one_by_username(request.form['username'], enabled=True)
if user: if user:
if user.password == self._model_store.user().encode_password(request.form['password']): if user.password == self._model_store.user().encode_password(request.form['password']):
login_user(user) login_user(user)
return redirect(url_for('slideshow_slide_list')) return redirect(url_for('playlist'))
else: else:
login_error = 'bad_credentials' login_error = 'bad_credentials'
else: else:

View File

@ -37,13 +37,22 @@ class PlayerController(ObController):
playlist_id = current_playlist.id if current_playlist else None playlist_id = current_playlist.id if current_playlist else None
items = self._get_playlist(playlist_id=playlist_id, preview_content_id=preview_content_id) items = self._get_playlist(playlist_id=playlist_id, preview_content_id=preview_content_id)
intro_slide_duration = self._model_store.variable().get_one_by_name('intro_slide_duration').eval()
if items['preview_mode'] or request.args.get('intro', '1') == '0':
intro_slide_duration = 0
animation_enabled = self._model_store.variable().get_one_by_name('slide_animation_enabled').eval()
if request.args.get('animation', '1') == '0':
animation_enabled = False
return render_template( return render_template(
'player/player.jinja.html', 'player/player.jinja.html',
items=items, items=items,
default_slide_duration=0 if items['preview_mode'] else self._model_store.variable().get_one_by_name('default_slide_duration').eval(), intro_slide_duration=intro_slide_duration,
polling_interval=self._model_store.variable().get_one_by_name('polling_interval'), polling_interval=self._model_store.variable().get_one_by_name('polling_interval'),
slide_animation_enabled=self._model_store.variable().get_one_by_name('slide_animation_enabled'), slide_animation_enabled=animation_enabled,
slide_animation_entrance_effect=self._model_store.variable().get_one_by_name('slide_animation_entrance_effect'), slide_animation_entrance_effect=self._model_store.variable().get_one_by_name('slide_animation_entrance_effect'),
slide_animation_exit_effect=self._model_store.variable().get_one_by_name('slide_animation_exit_effect'), slide_animation_exit_effect=self._model_store.variable().get_one_by_name('slide_animation_exit_effect'),
slide_animation_speed=self._model_store.variable().get_one_by_name('slide_animation_speed'), slide_animation_speed=self._model_store.variable().get_one_by_name('slide_animation_speed'),

View File

@ -1,6 +1,7 @@
import json import json
from flask import Flask, render_template, redirect, request, url_for, jsonify from flask import Flask, render_template, redirect, request, url_for, jsonify, abort
from src.exceptions.PlaylistSlugAlreadyExist import PlaylistSlugAlreadyExist
from src.service.ModelStore import ModelStore from src.service.ModelStore import ModelStore
from src.model.entity.Playlist import Playlist from src.model.entity.Playlist import Playlist
from src.interface.ObController import ObController from src.interface.ObController import ObController
@ -17,20 +18,31 @@ class PlaylistController(ObController):
return decorated_function return decorated_function
def register(self): def register(self):
self._app.add_url_rule('/playlist/list', 'playlist_list', self.guard_playlist(self._auth(self.playlist_list)), methods=['GET']) self._app.add_url_rule('/playlist', 'playlist', self.guard_playlist(self._auth(self.playlist)), methods=['GET'])
self._app.add_url_rule('/playlist/list/<playlist_id>', 'playlist_list', self.guard_playlist(self._auth(self.playlist_list)), methods=['GET'])
self._app.add_url_rule('/playlist/add', 'playlist_add', self.guard_playlist(self._auth(self.playlist_add)), methods=['POST']) self._app.add_url_rule('/playlist/add', 'playlist_add', self.guard_playlist(self._auth(self.playlist_add)), methods=['POST'])
self._app.add_url_rule('/playlist/edit', 'playlist_edit', self.guard_playlist(self._auth(self.playlist_edit)), methods=['POST']) self._app.add_url_rule('/playlist/save', 'playlist_save', self.guard_playlist(self._auth(self.playlist_save)), methods=['POST'])
self._app.add_url_rule('/playlist/toggle', 'playlist_toggle', self.guard_playlist(self._auth(self.playlist_toggle)), methods=['POST']) self._app.add_url_rule('/playlist/delete/<playlist_id>', 'playlist_delete', self.guard_playlist(self._auth(self.playlist_delete)), methods=['GET'])
self._app.add_url_rule('/playlist/delete', 'playlist_delete', self.guard_playlist(self._auth(self.playlist_delete)), methods=['DELETE'])
def playlist_list(self): def playlist(self):
return redirect(url_for('playlist_list', playlist_id=0))
def playlist_list(self, playlist_id: int = 0):
current_playlist = self._model_store.playlist().get(playlist_id)
playlists = self._model_store.playlist().get_all(sort="created_at", ascending=False)
durations = self._model_store.playlist().get_durations_by_playlists() durations = self._model_store.playlist().get_durations_by_playlists()
if not current_playlist and len(playlists) > 0:
current_playlist = playlists[0]
return render_template( return render_template(
'playlist/list.jinja.html', 'playlist/list.jinja.html',
playlists=self._model_store.playlist().get_all(ascending=True), error=request.args.get('error', None),
enabled_playlists=self._model_store.playlist().get_enabled_playlists(with_default=True), current_playlist=current_playlist,
disabled_playlists=self._model_store.playlist().get_disabled_playlists(), playlists=playlists,
durations=durations durations=durations,
slides=self._model_store.slide().get_slides(playlist_id=current_playlist.id),
contents={content.id: content for content in self._model_store.content().get_contents()},
) )
def playlist_add(self): def playlist_add(self):
@ -40,32 +52,28 @@ class PlaylistController(ObController):
time_sync=False time_sync=False
) )
self._model_store.playlist().add_form(playlist) try:
playlist = self._model_store.playlist().add_form(playlist)
except PlaylistSlugAlreadyExist as e:
abort(409)
return redirect(url_for('playlist_list')) return redirect(url_for('playlist_list', playlist_id=playlist.id))
def playlist_edit(self): def playlist_save(self):
self._model_store.playlist().update_form( self._model_store.playlist().update_form(
id=request.form['id'], id=request.form['id'],
name=request.form['name'], name=request.form['name'],
time_sync=request.form['time_sync'], time_sync=True if 'time_sync' in request.form else False,
enabled=True if 'enabled' in request.form else False
) )
return redirect(url_for('playlist_list')) return redirect(url_for('playlist_list', playlist_id=request.form['id']))
def playlist_toggle(self): def playlist_delete(self, playlist_id: int):
data = request.get_json() if self._model_store.slide().count_slides_for_playlist(playlist_id) > 0:
self._model_store.playlist().update_enabled(data.get('id'), data.get('enabled')) return redirect(url_for('playlist_list', playlist_id=playlist_id, error='playlist_delete_has_slides'))
return jsonify({'status': 'ok'})
def playlist_delete(self): if self._model_store.node_player_group().count_node_player_groups_for_playlist(playlist_id) > 0:
data = request.get_json() return redirect(url_for('playlist_list', playlist_id=playlist_id, error='playlist_delete_has_node_player_groups'))
id = data.get('id')
if self._model_store.slide().count_slides_for_playlist(id) > 0: self._model_store.playlist().delete(playlist_id)
return jsonify({'status': 'error', 'message': self.t('playlist_delete_has_slides')}), 400 return redirect(url_for('playlist'))
if self._model_store.node_player_group().count_node_player_groups_for_playlist(id) > 0:
return jsonify({'status': 'error', 'message': self.t('playlist_delete_has_node_player_groups')}), 400
self._model_store.playlist().delete(id)
return jsonify({'status': 'ok'})

View File

@ -16,31 +16,14 @@ class SlideController(ObController):
def register(self): def register(self):
self._app.add_url_rule('/manage', 'manage', self.manage, methods=['GET']) self._app.add_url_rule('/manage', 'manage', self.manage, methods=['GET'])
self._app.add_url_rule('/slideshow', 'slideshow_slide_list', self._auth(self.slideshow), methods=['GET'])
self._app.add_url_rule('/slideshow/playlist/set/<playlist_id>', 'slideshow_slide_list_playlist_use', self._auth(self.slideshow), methods=['GET'])
self._app.add_url_rule('/slideshow/slide/add', 'slideshow_slide_add', self._auth(self.slideshow_slide_add), methods=['POST']) self._app.add_url_rule('/slideshow/slide/add', 'slideshow_slide_add', self._auth(self.slideshow_slide_add), methods=['POST'])
self._app.add_url_rule('/slideshow/slide/edit', 'slideshow_slide_edit', self._auth(self.slideshow_slide_edit), methods=['POST']) self._app.add_url_rule('/slideshow/slide/edit', 'slideshow_slide_edit', self._auth(self.slideshow_slide_edit), methods=['POST'])
self._app.add_url_rule('/slideshow/slide/toggle', 'slideshow_slide_toggle', self._auth(self.slideshow_slide_toggle), methods=['POST'])
self._app.add_url_rule('/slideshow/slide/delete', 'slideshow_slide_delete', self._auth(self.slideshow_slide_delete), methods=['DELETE']) self._app.add_url_rule('/slideshow/slide/delete', 'slideshow_slide_delete', self._auth(self.slideshow_slide_delete), methods=['DELETE'])
self._app.add_url_rule('/slideshow/slide/position', 'slideshow_slide_position', self._auth(self.slideshow_slide_position), methods=['POST']) self._app.add_url_rule('/slideshow/slide/position', 'slideshow_slide_position', self._auth(self.slideshow_slide_position), methods=['POST'])
self._app.add_url_rule('/slideshow/player-refresh', 'slideshow_player_refresh', self._auth(self.slideshow_player_refresh), methods=['GET']) self._app.add_url_rule('/slideshow/player-refresh', 'slideshow_player_refresh/<playlist_id>', self._auth(self.slideshow_player_refresh), methods=['GET'])
def manage(self): def manage(self):
return redirect(url_for('slideshow_slide_list')) return redirect(url_for('playlist'))
def slideshow(self, playlist_id: int = 0):
current_playlist = self._model_store.playlist().get(playlist_id)
playlist_id = current_playlist.id if current_playlist else None
return render_template(
'slideshow/slides/list.jinja.html',
current_playlist=current_playlist,
playlists=self._model_store.playlist().get_enabled_playlists(),
enabled_slides=self._model_store.slide().get_slides(playlist_id=playlist_id, enabled=True),
disabled_slides=self._model_store.slide().get_slides(playlist_id=playlist_id, enabled=False),
var_last_restart=self._model_store.variable().get_one_by_name('last_restart'),
contents={content.id: content.name for content in self._model_store.content().get_contents()},
enum_content_type=ContentType
)
def slideshow_slide_add(self): def slideshow_slide_add(self):
content = None content = None
@ -67,9 +50,9 @@ class SlideController(ObController):
self._post_update() self._post_update()
if slide.playlist_id: if slide.playlist_id:
return redirect(url_for('slideshow_slide_list_playlist_use', playlist_id=slide.playlist_id)) return redirect(url_for('playlist_list', playlist_id=slide.playlist_id))
return redirect(url_for('slideshow_slide_list')) return redirect(url_for('playlist'))
def slideshow_slide_edit(self): def slideshow_slide_edit(self):
slide = self._model_store.slide().update_form( slide = self._model_store.slide().update_form(
@ -83,15 +66,9 @@ class SlideController(ObController):
self._post_update() self._post_update()
if slide.playlist_id: if slide.playlist_id:
return redirect(url_for('slideshow_slide_list_playlist_use', playlist_id=slide.playlist_id)) return redirect(url_for('playlist_list', playlist_id=slide.playlist_id))
return redirect(url_for('slideshow_slide_list')) return redirect(url_for('playlist'))
def slideshow_slide_toggle(self):
data = request.get_json()
self._model_store.slide().update_enabled(data.get('id'), data.get('enabled'))
self._post_update()
return jsonify({'status': 'ok'})
def slideshow_slide_delete(self): def slideshow_slide_delete(self):
data = request.get_json() data = request.get_json()
@ -105,11 +82,12 @@ class SlideController(ObController):
self._post_update() self._post_update()
return jsonify({'status': 'ok'}) return jsonify({'status': 'ok'})
def slideshow_player_refresh(self): def slideshow_player_refresh(self, playlist_id: int):
self._model_store.variable().update_by_name("refresh_player_request", time.time()) self._model_store.variable().update_by_name("refresh_player_request", time.time())
return redirect( return redirect(
url_for( url_for(
'slideshow_slide_list', 'playlist_list',
playlist_id=playlist_id,
refresh_player=self._model_store.variable().get_one_by_name('polling_interval').as_int() refresh_player=self._model_store.variable().get_one_by_name('polling_interval').as_int()
) )
) )

View File

@ -0,0 +1,2 @@
class PlaylistSlugAlreadyExist(Exception):
pass

View File

@ -120,8 +120,13 @@ class DatabaseManager:
params=tuple(v for v in values.values()) params=tuple(v for v in values.values())
) )
def get_one_by_query(self, table_name: str, query: str = "1=1", sort: Optional[str] = None, ascending=True, values: dict = {}) -> list: def get_one_by_query(self, table_name: str, query: str = "1=1", values: dict = {}, sort: Optional[str] = None, ascending=True, limit: Optional[int] = None) -> list:
query = "select * from {} where {} {}".format(table_name, query, "ORDER BY {} {}".format(sort, "ASC" if ascending else "DESC") if sort else "") query = "select * from {} where {} {} {}".format(
table_name,
query,
"ORDER BY {} {}".format(sort, "ASC" if ascending else "DESC") if sort else "",
"LIMIT {}".format(limit) if limit else ""
)
lines = self.execute_read_query(query=query, params=tuple(v for v in values.values())) lines = self.execute_read_query(query=query, params=tuple(v for v in values.values()))
count = len(lines) count = len(lines)
@ -216,6 +221,7 @@ class DatabaseManager:
"DROP TABLE IF EXISTS fleet_studio", "DROP TABLE IF EXISTS fleet_studio",
"ALTER TABLE slideshow RENAME TO slides", "ALTER TABLE slideshow RENAME TO slides",
"DELETE FROM settings WHERE name = 'fleet_studio_enabled'", "DELETE FROM settings WHERE name = 'fleet_studio_enabled'",
"DELETE FROM settings WHERE name = 'default_slide_duration'",
"UPDATE content SET uuid = id WHERE uuid = '' or uuid is null", "UPDATE content SET uuid = id WHERE uuid = '' or uuid is null",
] ]

View File

@ -72,10 +72,9 @@ class NodePlayerGroupManager(ModelManager):
def get_node_players_groups(self, playlist_id: Optional[int] = None) -> List[NodePlayerGroup]: def get_node_players_groups(self, playlist_id: Optional[int] = None) -> List[NodePlayerGroup]:
query = " 1=1 " query = " 1=1 "
if playlist_id: if playlist_id:
query = "{} {}".format(query, "AND playlist_id = {}".format(playlist_id)) query = "{} {}".format(query, "AND playlist_id = {}".format(playlist_id))
else:
query = "{} {}".format(query, "AND playlist_id is NULL")
return self.get_by(query=query, sort="name") return self.get_by(query=query, sort="name")

View File

@ -3,7 +3,8 @@ import os
from typing import Dict, Optional, List, Tuple, Union from typing import Dict, Optional, List, Tuple, Union
from src.model.entity.Playlist import Playlist from src.model.entity.Playlist import Playlist
from src.util.utils import get_optional_string, get_yt_video_id, slugify from src.util.utils import get_optional_string, get_yt_video_id, slugify, slugify_next
from src.exceptions.PlaylistSlugAlreadyExist import PlaylistSlugAlreadyExist
from src.manager.DatabaseManager import DatabaseManager from src.manager.DatabaseManager import DatabaseManager
from src.manager.SlideManager import SlideManager from src.manager.SlideManager import SlideManager
from src.manager.LangManager import LangManager from src.manager.LangManager import LangManager
@ -54,8 +55,8 @@ class PlaylistManager(ModelManager):
def get_by(self, query, sort: Optional[str] = None, values: dict = {}) -> List[Playlist]: def get_by(self, query, sort: Optional[str] = None, values: dict = {}) -> List[Playlist]:
return self.hydrate_list(self._db.get_by_query(self.TABLE_NAME, query=query, sort=sort, values=values)) return self.hydrate_list(self._db.get_by_query(self.TABLE_NAME, query=query, sort=sort, values=values))
def get_one_by(self, query, values: dict = {}) -> Optional[Playlist]: def get_one_by(self, query, values: dict = {}, sort: Optional[str] = None, ascending=True, limit: Optional[int] = None) -> Optional[Playlist]:
object = self._db.get_one_by_query(self.TABLE_NAME, query=query, values=values) object = self._db.get_one_by_query(self.TABLE_NAME, query=query, values=values, sort=sort, ascending=ascending, limit=limit)
if not object: if not object:
return None return None
@ -105,8 +106,25 @@ class PlaylistManager(ModelManager):
for playlist_id, edits in edits_playlists.items(): for playlist_id, edits in edits_playlists.items():
self._db.update_by_id(self.TABLE_NAME, playlist_id, edits) self._db.update_by_id(self.TABLE_NAME, playlist_id, edits)
def get_available_slug(self, slug) -> str:
known_playlist = {"slug": slug}
next_slug = slug
while known_playlist is not None:
next_slug = slugify_next(next_slug)
known_playlist = self.get_one_by(query="slug = ?", values={"slug": next_slug}, sort="created_at", ascending=False, limit=1)
return next_slug
def pre_add(self, playlist: Dict) -> Dict: def pre_add(self, playlist: Dict) -> Dict:
playlist["slug"] = slugify(playlist["name"]) playlist["slug"] = slugify(playlist["name"])
known_playlist = self.get_one_by(query="slug = ?", values={
"slug": playlist["slug"]
}, sort="created_at", ascending=False, limit=1)
if known_playlist:
playlist["slug"] = self.get_available_slug(playlist["slug"])
self.user_manager.track_user_on_create(playlist) self.user_manager.track_user_on_create(playlist)
self.user_manager.track_user_on_update(playlist) self.user_manager.track_user_on_update(playlist)
return playlist return playlist
@ -131,7 +149,7 @@ class PlaylistManager(ModelManager):
def post_delete(self, playlist_id: str) -> str: def post_delete(self, playlist_id: str) -> str:
return playlist_id return playlist_id
def update_form(self, id: int, name: str, time_sync: bool) -> None: def update_form(self, id: int, name: str, time_sync: bool, enabled: bool) -> None:
playlist = self.get(id) playlist = self.get(id)
if not playlist: if not playlist:
@ -139,13 +157,14 @@ class PlaylistManager(ModelManager):
form = { form = {
"name": name, "name": name,
"time_sync": time_sync "time_sync": time_sync,
"enabled": enabled
} }
self._db.update_by_id(self.TABLE_NAME, id, self.pre_update(form)) self._db.update_by_id(self.TABLE_NAME, id, self.pre_update(form))
self.post_update(id) self.post_update(id)
def add_form(self, playlist: Union[Playlist, Dict]) -> None: def add_form(self, playlist: Union[Playlist, Dict]) -> Playlist:
form = playlist form = playlist
if not isinstance(playlist, dict): if not isinstance(playlist, dict):
@ -153,7 +172,11 @@ class PlaylistManager(ModelManager):
del form['id'] del form['id']
self._db.add(self.TABLE_NAME, self.pre_add(form)) self._db.add(self.TABLE_NAME, self.pre_add(form))
playlist = self.get_one_by(query="slug = ?", values={
"slug": form["slug"]
})
self.post_add(playlist.id) self.post_add(playlist.id)
return playlist
def delete(self, id: int) -> None: def delete(self, id: int) -> None:
playlist = self.get(id) playlist = self.get(id)

View File

@ -73,13 +73,14 @@ class SlideManager(ModelManager):
for slide_id, edits in edits_slides.items(): for slide_id, edits in edits_slides.items():
self._db.update_by_id(self.TABLE_NAME, slide_id, edits) self._db.update_by_id(self.TABLE_NAME, slide_id, edits)
def get_slides(self, playlist_id: Optional[int] = None, content_id: Optional[int] = None, enabled: bool = True) -> List[Slide]: def get_slides(self, playlist_id: Optional[int] = None, content_id: Optional[int] = None, enabled: Optional[bool] = None) -> List[Slide]:
query = "enabled = {}".format("1" if enabled else "0") query = " 1=1 "
if enabled is not None:
query = "{} AND enabled = {} ".format(query, "1" if enabled else "0")
if playlist_id: if playlist_id:
query = "{} {}".format(query, "AND playlist_id = {}".format(playlist_id)) query = "{} {}".format(query, "AND playlist_id = {}".format(playlist_id))
else:
query = "{} {}".format(query, "AND playlist_id is NULL")
if content_id: if content_id:
query = "{} {}".format(query, "AND content_id = {}".format(content_id)) query = "{} {}".format(query, "AND content_id = {}".format(content_id))

View File

@ -1,5 +1,6 @@
import json import json
import time import time
import math
from typing import Dict, Optional, List, Tuple, Union from typing import Dict, Optional, List, Tuple, Union
from src.manager.DatabaseManager import DatabaseManager from src.manager.DatabaseManager import DatabaseManager
@ -111,7 +112,7 @@ class VariableManager:
{"name": "slide_upload_limit", "section": self.t(VariableSection.GENERAL), "value": 32, "unit": VariableUnit.MEGABYTE, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_slide_upload_limit'), "refresh_player": False}, {"name": "slide_upload_limit", "section": self.t(VariableSection.GENERAL), "value": 32, "unit": VariableUnit.MEGABYTE, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_slide_upload_limit'), "refresh_player": False},
### Player Options ### Player Options
{"name": "default_slide_duration", "section": self.t(VariableSection.PLAYER_OPTIONS), "value": 3, "unit": VariableUnit.SECOND, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_default_slide_duration'), "refresh_player": False}, {"name": "intro_slide_duration", "section": self.t(VariableSection.PLAYER_OPTIONS), "value": 3, "unit": VariableUnit.SECOND, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_intro_slide_duration'), "refresh_player": False},
{"name": "default_slide_time_with_seconds", "section": self.t(VariableSection.PLAYER_OPTIONS), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_default_slide_time_with_seconds'), "refresh_player": False}, {"name": "default_slide_time_with_seconds", "section": self.t(VariableSection.PLAYER_OPTIONS), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_default_slide_time_with_seconds'), "refresh_player": False},
{"name": "polling_interval", "section": self.t(VariableSection.PLAYER_OPTIONS), "value": 5, "unit": VariableUnit.SECOND, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_polling_interval'), "refresh_player": True}, {"name": "polling_interval", "section": self.t(VariableSection.PLAYER_OPTIONS), "value": 5, "unit": VariableUnit.SECOND, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_polling_interval'), "refresh_player": True},
@ -132,6 +133,7 @@ class VariableManager:
{"name": "auth_enabled", "section": self.t(VariableSection.SECURITY), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_auth_enabled'), "description_edition": self.t('settings_variable_desc_edition_auth_enabled'), "refresh_player": False}, {"name": "auth_enabled", "section": self.t(VariableSection.SECURITY), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_auth_enabled'), "description_edition": self.t('settings_variable_desc_edition_auth_enabled'), "refresh_player": False},
# Not editable (System information) # Not editable (System information)
{"name": "start_counter", "value": 0, "type": VariableType.INT, "editable": False, "description": self.t('settings_variable_desc_ro_start_counter')},
{"name": "last_folder_content", "value": FOLDER_ROOT_PATH, "type": VariableType.STRING, "editable": False, "description": self.t('settings_variable_desc_ro_last_folder_content')}, {"name": "last_folder_content", "value": FOLDER_ROOT_PATH, "type": VariableType.STRING, "editable": False, "description": self.t('settings_variable_desc_ro_last_folder_content')},
{"name": "last_folder_node_player", "value": FOLDER_ROOT_PATH, "type": VariableType.STRING, "editable": False, "description": self.t('settings_variable_desc_ro_last_folder_node_player')}, {"name": "last_folder_node_player", "value": FOLDER_ROOT_PATH, "type": VariableType.STRING, "editable": False, "description": self.t('settings_variable_desc_ro_last_folder_node_player')},
{"name": "last_restart", "value": time.time(), "type": VariableType.TIMESTAMP, "editable": False, "description": self.t('settings_variable_desc_ro_editable')}, {"name": "last_restart", "value": time.time(), "type": VariableType.TIMESTAMP, "editable": False, "description": self.t('settings_variable_desc_ro_editable')},

View File

@ -89,7 +89,7 @@ class Playlist:
return f"Playlist(" \ return f"Playlist(" \
f"id='{self.id}',\n" \ f"id='{self.id}',\n" \
f"name='{self.name}',\n" \ f"name='{self.name}',\n" \
f"nameslug='{self.slug}',\n" \ f"slug='{self.slug}',\n" \
f"enabled='{self.enabled}',\n" \ f"enabled='{self.enabled}',\n" \
f"time_sync='{self.time_sync}',\n" \ f"time_sync='{self.time_sync}',\n" \
f"created_by='{self.created_by}',\n" \ f"created_by='{self.created_by}',\n" \

View File

@ -3,11 +3,6 @@ from enum import Enum
class HookType(Enum): class HookType(Enum):
H_SLIDESHOW_SLIDES_TOOLBAR_ACTIONS_START = 'h_slideshow_slides_toolbar_actions_start'
H_SLIDESHOW_SLIDES_TOOLBAR_ACTIONS_END = 'h_slideshow_slides_toolbar_actions_end'
H_SLIDESHOW_SLIDES_CSS = 'h_slideshow_slides_css'
H_SLIDESHOW_SLIDES_JAVASCRIPT = 'h_slideshow_slides_javascript'
H_SLIDESHOW_CONTENT_TOOLBAR_ACTIONS_START = 'h_slideshow_toolbar_actions_start' H_SLIDESHOW_CONTENT_TOOLBAR_ACTIONS_START = 'h_slideshow_toolbar_actions_start'
H_SLIDESHOW_CONTENT_TOOLBAR_ACTIONS_END = 'h_slideshow_toolbar_actions_end' H_SLIDESHOW_CONTENT_TOOLBAR_ACTIONS_END = 'h_slideshow_toolbar_actions_end'
H_SLIDESHOW_CONTENT_CSS = 'h_slideshow_css' H_SLIDESHOW_CONTENT_CSS = 'h_slideshow_css'

View File

@ -255,3 +255,13 @@ def merge_dicts(dict1, dict2):
def dictsort(dict1, attribute="position"): def dictsort(dict1, attribute="position"):
return dict(sorted(dict1.items(), key=lambda item: item[1][attribute])) return dict(sorted(dict1.items(), key=lambda item: item[1][attribute]))
def slugify_next(slug: str) -> str:
parts = slug.rsplit('-', 1)
if len(parts) > 1 and parts[-1].isdigit():
next_number = int(parts[-1]) + 1
return f"{parts[0]}-{next_number}"
else:
return f"{slug}-1"

View File

@ -59,7 +59,7 @@
"position": 0, "position": 0,
"pills": [ "pills": [
{"name": "Bibliothèque", "route": "slideshow_content_list", "icon": "fa-image"}, {"name": "Bibliothèque", "route": "slideshow_content_list", "icon": "fa-image"},
{"name": "Playlists", "route": "playlist_list", "icon": "fa-play"}, {"name": "Playlists", "route": "playlist", "icon": "fa-play"},
] ]
}, },
"configuration": { "configuration": {
@ -115,7 +115,7 @@
{% block header %} {% block header %}
<menu> <menu>
<h1 class="logo"> <h1 class="logo">
<a href="{{ url_for('slideshow_slide_list') }}"> <a href="{{ url_for('playlist') }}">
<img src="{{ STATIC_PREFIX }}img/logo2.png" class="before"/> <img src="{{ STATIC_PREFIX }}img/logo2.png" class="before"/>
<img src="{{ STATIC_PREFIX }}img/logo2white.png" class="after"/> <img src="{{ STATIC_PREFIX }}img/logo2white.png" class="after"/>
Obscreen Obscreen
@ -164,7 +164,8 @@
<ul class="pills"> <ul class="pills">
{% for menu in current_dynmenu.pills %} {% for menu in current_dynmenu.pills %}
<li class="{{ 'active' if active_route == menu.route }}"> <li class="{{ 'active' if active_route == menu.route }}">
<a href="{{ url_for(menu.route) }}"> {% set href = menu.url_for if menu.url_for else url_for(menu.route) %}
<a href="{{ href }}">
<span class="icon"> <span class="icon">
<i class="fa {{ menu.icon }}"></i> <i class="fa {{ menu.icon }}"></i>
</span> </span>

View File

@ -6,7 +6,7 @@
{% block add_css %} {% block add_css %}
<link rel="stylesheet" href="{{ STATIC_PREFIX }}css/lib/jquery-explr-1.4.css"/> <link rel="stylesheet" href="{{ STATIC_PREFIX }}css/lib/jquery-explr-1.4.css"/>
{{ HOOK(H_SLIDESHOW_CONTENT_CSS) }} {{ HOOK(H_FLEET_NODE_PLAYER_CSS) }}
{% endblock %} {% endblock %}
{% block add_js %} {% block add_js %}
@ -14,8 +14,7 @@
<script src="{{ STATIC_PREFIX }}js/explorer.js"></script> <script src="{{ STATIC_PREFIX }}js/explorer.js"></script>
<script src="{{ STATIC_PREFIX }}js/fleet/node-players.js"></script> <script src="{{ STATIC_PREFIX }}js/fleet/node-players.js"></script>
<script src="{{ STATIC_PREFIX }}js/lib/jquery-ui.min.js"></script> <script src="{{ STATIC_PREFIX }}js/lib/jquery-ui.min.js"></script>
{{ HOOK(H_FLEET_NODE_PLAYER_JAVASCRIPT) }}
{{ HOOK(H_SLIDESHOW_CONTENT_JAVASCRIPT) }}
{% endblock %} {% endblock %}
{% block body_class %}view-node-player-list{% endblock %} {% block body_class %}view-node-player-list{% endblock %}
@ -27,7 +26,7 @@
</h1> </h1>
<div class="top-actions"> <div class="top-actions">
{{ HOOK(H_SLIDESHOW_CONTENT_TOOLBAR_ACTIONS_START) }} {{ HOOK(H_FLEET_NODE_PLAYER_TOOLBAR_ACTIONS_START) }}
<div class="explr-selection-actions"> <div class="explr-selection-actions">
<button class="explr-item-edit explr-selection-entity btn-info" data-entity-route="{{ url_for('fleet_node_player_edit', node_player_id='!c!') }}"> <button class="explr-item-edit explr-selection-entity btn-info" data-entity-route="{{ url_for('fleet_node_player_edit', node_player_id='!c!') }}">
@ -49,7 +48,7 @@
<i class="fa fa-folder-plus icon-left"></i> <i class="fa fa-folder-plus icon-left"></i>
{{ l.common_new_folder }} {{ l.common_new_folder }}
</button> </button>
{{ HOOK(H_SLIDESHOW_CONTENT_TOOLBAR_ACTIONS_END) }} {{ HOOK(H_FLEET_NODE_PLAYER_TOOLBAR_ACTIONS_END) }}
</div> </div>
</div> </div>
@ -74,7 +73,7 @@
{% set node_player_children = node_players[folder.id]|default([]) %} {% set node_player_children = node_players[folder.id]|default([]) %}
{% set has_children = folder.children or node_player_children %} {% set has_children = folder.children or node_player_children %}
<li class="icon-folder li-explr-folder li-explr-folder-{{ folder.id }}"> <li class="icon-folder li-explr-folder li-explr-folder-{{ folder.id if folder.id else 0 }}">
<a href="{{ url_for('fleet_node_player_cd') }}?path={{ folder.path }}" class="{% if folder.path == working_folder_path %}active{% endif %}"> <a href="{{ url_for('fleet_node_player_cd') }}?path={{ folder.path }}" class="{% if folder.path == working_folder_path %}active{% endif %}">
{{ folder.name }} {{ folder.name }}
</a> </a>

View File

@ -5,7 +5,7 @@
<meta name="robots" content="noindex, nofollow"> <meta name="robots" content="noindex, nofollow">
<meta name="google" content="notranslate"> <meta name="google" content="notranslate">
<link rel="shortcut icon" href="{{ STATIC_PREFIX }}/favicon.ico"> <link rel="shortcut icon" href="{{ STATIC_PREFIX }}/favicon.ico">
{% if slide_animation_enabled.eval() %} {% if slide_animation_enabled %}
<link rel="stylesheet" href="{{ STATIC_PREFIX }}css/lib/animate.min.css" /> <link rel="stylesheet" href="{{ STATIC_PREFIX }}css/lib/animate.min.css" />
{% endif %} {% endif %}
<style> <style>
@ -20,7 +20,7 @@
</head> </head>
<body> <body>
<div id="IntroSlide" class="slide" style="z-index: 10000;"> <div id="IntroSlide" class="slide" style="z-index: 10000;">
{% if default_slide_duration > 0 %} {% if intro_slide_duration > 0 %}
<iframe src="/player/default"></iframe> <iframe src="/player/default"></iframe>
{% endif %} {% endif %}
</div> </div>
@ -37,7 +37,7 @@
<script type="text/javascript"> <script type="text/javascript">
// Backend config // Backend config
let items = {{ json_dumps(items) | safe}}; let items = {{ json_dumps(items) | safe}};
const introDuration = {{ default_slide_duration * 1000 }}; const introDuration = {{ intro_slide_duration * 1000 }};
const playlistCheckResolutionMs = {{ polling_interval.eval() * 1000 }}; const playlistCheckResolutionMs = {{ polling_interval.eval() * 1000 }};
// Backend flag updates // Backend flag updates
@ -59,9 +59,9 @@
let pauseClockValue = null; let pauseClockValue = null;
// Animations // Animations
const animate = {{ 'true' if slide_animation_enabled.eval() and not items.preview_mode else 'false' }}; const animate = {{ 'true' if slide_animation_enabled and not items.preview_mode else 'false' }};
const animate_speed = "animate__{{ slide_animation_speed.eval()|default("normal") }}"; const animate_speed = "animate__{{ slide_animation_speed.eval()|default("normal") }}";
const animation_speed_duration = {{ animation_speed_duration[slide_animation_speed.eval()] if slide_animation_enabled.eval() else 0 }}; const animation_speed_duration = {{ animation_speed_duration[slide_animation_speed.eval()] if slide_animation_enabled else 0 }};
const animate_transitions = [ const animate_transitions = [
"animate__{{ slide_animation_entrance_effect.eval()|default("fadeIn") }}", "animate__{{ slide_animation_entrance_effect.eval()|default("fadeIn") }}",
"animate__{{ slide_animation_exit_effect.eval()|default("none") }}" "animate__{{ slide_animation_exit_effect.eval()|default("none") }}"

View File

@ -0,0 +1,113 @@
<div class="horizontal">
<div class="form-holder vertical">
<h3>
{{ l.playlist_panel_about_playlist }}
</h3>
<form class="form" action="{{ url_for('playlist_save') }}" method="POST">
<input type="hidden" name="id" id="playlist-edit-id" value="{{ current_playlist.id }}"/>
<div class="form-group">
<label for="playlist-edit-name">{{ l.playlist_form_label_name }}</label>
<div class="widget">
<input type="text" name="name" id="playlist-edit-name" required="required"
value="{{ current_playlist.name }}"/>
</div>
</div>
<div class="form-group form-group-horizontal">
<label for="playlist-edit-enabled">{{ l.playlist_form_label_enabled }}</label>
<div class="widget">
<div class="toggle">
<input type="checkbox" id="playlist-edit-enabled" name="enabled"
{% if current_playlist.enabled %}checked="checked"{% endif %}>
<label for="playlist-edit-enabled"></label>
</div>
</div>
</div>
<div class="form-group form-group-horizontal">
<label for="playlist-edit-time-sync">{{ l.playlist_form_label_time_sync }}</label>
<div class="widget">
<div class="toggle">
<input type="checkbox" id="playlist-edit-time-sync" name="time_sync"
{% if current_playlist.time_sync %}checked="checked"{% endif %}>
<label for="playlist-edit-time-sync"></label>
</div>
</div>
</div>
<div class="actions actions-right">
<button type="submit" class="btn-success-alt">
<i class="fa fa-save icon-left"></i>
{{ l.common_save }}
</button>
</div>
</form>
<div class="slides-holder">
<h3>
{{ l.playlist_panel_content_management }}
<div>
<button class="btn btn-info slide-add">
<i class="fa fa-plus"></i>
</button>
</div>
</h3>
{% with slides=slides %}
{% include 'slideshow/slides/component/table.jinja.html' %}
{% endwith %}
</div>
</div>
<div class="preview-holder vertical">
<div class="form-group">
<h4>
URL
</h4>
<p>
{{ l.playlist_form_preview_url_desc }}
</p>
{% set preview_url = request.scheme ~ '://' ~ request.headers.get('host') ~ url_for('player_use', playlist_slug_or_id=current_playlist.slug) %}
<div class="widget">
<input type="text" name="name" id="playlist-preview-url" required="required" value="{{ preview_url }}"
class="disabled" disabled="disabled"/>
<button class="btn btn-naked copy-link" data-target-id="playlist-preview-url">
<i class="fa fa-copy"></i>
</button>
<a href="{{ preview_url }}" class="btn btn-neutral" target="_blank">
<i class="fa-solid fa-up-right-from-square"></i>
</a>
</div>
<h4 class="divide">
QR Code
</h4>
<p>
{{ l.playlist_form_preview_qrcode_desc }}
</p>
<div id="qrcode" class="qrcode-pic" data-qrcode-payload="{{ preview_url }}"></div>
</div>
<h4 class="divide">
Iframe
</h4>
<p>
{{ l.playlist_form_preview_iframe_desc }}
</p>
<div class="preview">
<button class="btn btn-info btn-naked"
onclick="$(this).parent().find('iframe').removeClass('hidden');$(this).addClass('hidden');">
<i class="fa fa-eye icon-left"></i> {{ l.playlist_panel_preview_action }}
</button>
<iframe src="{{ preview_url }}?intro=0&animation=0" frameborder="0" class="hidden"></iframe>
</div>
</div>
</div>

View File

@ -1,86 +1,46 @@
<table class="{{ tclass }}-playlists"> <div class="tiles playlists">
<thead> <div class="tiles-inner">
<tr> {% for playlist in playlists %}
<th>{{ l.playlist_panel_th_name }}</th> {% set active = current_playlist and ''~playlist.id == ''~current_playlist.id %}
{% if AUTH_ENABLED %} <a href="{{ url_for('playlist_list', playlist_id=playlist.id) }}"
<th class="tac"> class="{% if active %}active{% endif %} tile-item {% if not playlist.enabled %}disabled{% endif %} playlist-item"
<i class="fa fa-user"></i> data-level="{{ playlist.id }}"
</th> data-entity="{{ playlist.to_json({"created_by": track_created(playlist).username, "updated_by": track_updated(playlist).username}) }}">
{% endif %} <div class="tile-header">
<th class="tac"><i class="fa fa-compass"></i></th> <div class="head-icon">
<th class="tac">{{ l.playlist_panel_th_enabled }}</th> <i class="fa {{ 'fa fa-circle' if active else 'fa fa-circle' }}"></i>
<th class="tac">{{ l.playlist_panel_th_duration }}</th> </div>
<th class="tac">{{ l.playlist_panel_th_activity }}</th>
</tr>
</thead>
<tbody>
<tr class="empty-tr {% if playlists|length != 0 %}hidden{% endif %}">
<td colspan="4">
{{ l.playlist_panel_empty|replace(
'%link%',
('<a href="javascript:void(0);" class="item-add playlist-add">'~l.playlist_button_add~'</a>')|safe
) }}
</td>
</tr>
{% for playlist in playlists %}
<tr class="playlist-item" data-level="{{ playlist.id }}" data-entity="{{ playlist.to_json({"created_by": track_created(playlist).username, "updated_by": track_updated(playlist).username}) }}">
<td class="infos">
<div class="inner">
{% if playlist.id %}
<div class="badge"><i class="fa fa-key icon-left"></i> {{ playlist.id }}</div>
{% else %}
<div class="badge"><i class="fa fa-lock"></i></div>
{% endif %}
<i class="fa fa-bars-staggered icon-left"></i>
{{ playlist.name }}
</div> </div>
</td> <div class="tile-body">
{% if AUTH_ENABLED %} {% set title = playlist.name|trim %}
<td class="tac"> {% set title = title if title|length > 0 %}
{% if playlist.id %} {{ truncate((title)|default(l.common_untitled), 35, '...') }}
{% set creator = track_created(playlist) %} </div>
{% if creator.username %} <div class="tile-footer">
<a href="javascript:void(0);" class="badge item-utrack playlist-utrack {% if not creator.enabled %}anonymous{% endif %}"> <div class="foot-span">
{{ creator.username }} {% set total_duration = seconds_to_hhmmss(durations[playlist.id]) %}
</a> {% if total_duration %}
{{ total_duration }}
{% else %}
{{ l.common_empty }}
{% endif %}
</div>
{% if AUTH_ENABLED %}
{% if playlist.id %}
{% set creator = track_created(playlist) %}
{% if creator.username %}
<div class="foot-span {% if not creator.enabled %}anonymous{% endif %}">
{{ creator.username }}
</div>
{% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}
</td> </div>
{% endif %} </a>
<td class="tac"> {% endfor %}
{% if playlist.time_sync %}
<i class="fa fa-check"></i> <div class="inner-empty empty-flag {% if playlists|length != 0 %}hidden{% endif %}">
{% else %} <i class="fa fa-play"></i>
<i class="fa fa-times"></i> </div>
{% endif %} </div>
</td> </div>
<td class="tac">
{% if playlist.id %}
<label class="pure-material-switch">
<input type="checkbox" {% if playlist.enabled %}checked="checked"{% endif %}><span></span>
</label>
{% endif %}
</td>
<td class="tac">
{% set total_duration = seconds_to_hhmmss(durations[playlist.id]) %}
{% if total_duration %}
{{ total_duration }}
{% else %}
{{ l.common_empty }}
{% endif %}
</td>
<td class="actions tac">
{% if playlist.id %}
<a href="javascript:void(0);" class="item-edit playlist-edit">
<i class="fa fa-pencil"></i>
</a>
<a href="javascript:void(0);" class="item-delete playlist-delete">
<i class="fa fa-trash"></i>
</a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@ -6,13 +6,34 @@
{% block add_css %} {% block add_css %}
{{ HOOK(H_PLAYLIST_CSS) }} {{ HOOK(H_PLAYLIST_CSS) }}
<link rel="stylesheet" href="{{ STATIC_PREFIX }}css/lib/flatpickr.min.css" />
{% endblock %} {% endblock %}
{% block add_js %} {% block add_js %}
<script type="text/javascript">
var schedule_start_choices = {
'loop': '{{ l.slideshow_slide_form_label_cron_scheduled_loop }}',
'datetime': '{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}',
'cron': '{{ l.slideshow_slide_form_label_cron_scheduled_cron }}',
};
var schedule_end_choices = {
'stayloop': '{{ l.slideshow_slide_form_label_cron_scheduled_stayloop }}',
'datetime': '{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}',
'duration': '{{ l.slideshow_slide_form_label_cron_scheduled_duration }}',
};
var contents = {{ json_dumps(contents) | safe }}
</script>
<script src="{{ STATIC_PREFIX }}js/lib/flatpickr.min.js"></script>
<script src="{{ STATIC_PREFIX }}js/lib/tablednd-fixed.js"></script>
<script src="{{ STATIC_PREFIX }}js/lib/qrcode.min.js"></script>
<script src="{{ STATIC_PREFIX }}js/slideshow/slides.js"></script>
<script src="{{ STATIC_PREFIX }}js/playlist/playlists.js"></script> <script src="{{ STATIC_PREFIX }}js/playlist/playlists.js"></script>
<script src="{{ STATIC_PREFIX }}js/restart.js"></script>
{{ HOOK(H_PLAYLIST_JAVASCRIPT) }} {{ HOOK(H_PLAYLIST_JAVASCRIPT) }}
{% endblock %} {% endblock %}
{% block body_class %}view-playlist-list{% endblock %}
{% block page %} {% block page %}
<div class="top-content"> <div class="top-content">
@ -26,21 +47,49 @@
<i class="fa fa-play icon-left"></i> <i class="fa fa-play icon-left"></i>
{{ l.playlist_button_add }} {{ l.playlist_button_add }}
</button> </button>
{% if current_playlist %}
<a href="{{ url_for('playlist_delete', playlist_id=current_playlist.id) }}" class="btn btn-danger-alt protected">
<i class="fa fa-trash"></i>
</a>
{% endif %}
{{ HOOK(H_PLAYLIST_TOOLBAR_ACTIONS_END) }} {{ HOOK(H_PLAYLIST_TOOLBAR_ACTIONS_END) }}
</div> </div>
</div> </div>
<div class="alert alert-info tiles-empty empty-flag {% if playlists|length != 0 %}hidden{% endif %}">
{{ l.playlist_panel_empty|replace(
'%link%',
('<a href="javascript:void(0);" class="item-add playlist-add">'~l.playlist_button_add~'</a>')|safe
) }}
</div>
{% if request.args.get('refresh_player') %}
<div class="alert alert-success">
<i class="fa fa-refresh icon-left"></i>
{{ l.slideshow_slide_refresh_player_success|replace('%time%', request.args.get('refresh_player')) }}
</div>
{% endif %}
{% if error %}
<div class="alert alert-danger">
{{ l[error] }}
</div>
{% endif %}
<div class="bottom-content"> <div class="bottom-content">
<div class="page-panel left-panel">
{% with playlists=playlists %}
{% include 'playlist/component/table.jinja.html' %}
{% endwith %}
</div>
<div class="page-content"> <div class="page-content">
<div class="inner"> <div class="inner">
<div class="panel"> {% with playlists=playlists %}
<div class="panel-body"> {% include 'playlist/component/edit.jinja.html' %}
<h3>{{ l.sysinfo_panel_title }}</h3> {% endwith %}
{% with playlists=playlists %}
{% include 'playlist/component/table.jinja.html' %}
{% endwith %}
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -49,6 +98,9 @@
<div class="modals-outer"> <div class="modals-outer">
<div class="modals-inner"> <div class="modals-inner">
{% include 'playlist/modal/add.jinja.html' %} {% include 'playlist/modal/add.jinja.html' %}
{% include 'playlist/modal/qrcode.jinja.html' %}
{% include 'slideshow/slides/modal/add.jinja.html' %}
{% include 'slideshow/slides/modal/edit.jinja.html' %}
{% include 'core/utrack.jinja.html' %} {% include 'core/utrack.jinja.html' %}
</div> </div>
</div> </div>

View File

@ -1,37 +0,0 @@
<div class="modal modal-playlist-edit modal-playlist hidden">
<h2>
{{ l.playlist_form_edit_title }}
</h2>
<form class="form" action="/playlist/edit" method="POST">
<input type="hidden" name="id" id="playlist-edit-id" />
<div class="form-group">
<label for="playlist-edit-name">{{ l.playlist_form_label_name }}</label>
<div class="widget">
<input type="text" name="name" id="playlist-edit-name" required="required" />
</div>
</div>
<div class="form-group">
<label for="playlist-edit-time-sync">{{ l.playlist_form_label_time_sync }}</label>
<div class="widget">
<select name="time_sync" type="text" id="playlist-edit-time-sync" required="required">
<option value="1"></option>
<option value="0"></option>
</select>
</div>
</div>
<div class="actions">
<button type="button" class="btn-normal modal-close">
{{ l.playlist_form_button_cancel }}
</button>
<button type="submit" class="green">
<i class="fa fa-save icon-left"></i>{{ l.playlist_form_edit_submit }}
</button>
</div>
</form>
</div>

View File

@ -0,0 +1,13 @@
<div class="modal modal-playlist-qrcode modal-playlist">
<h2>
{{ l.playlist_form_show_qrcode }}
</h2>
<div id="qrcode" class="qrcode-pic"></div>
<div class="actions actions-center">
<button type="button" class="btn btn-naked modal-close">
<i class="fa fa-close icon-left"></i>{{ l.common_close }}
</button>
</div>
</div>

View File

@ -1,77 +1,15 @@
{% extends 'base.jinja.html' %}
{% block page_title %}
{{ l.slideshow_slide_page_title }}
{% endblock %}
{% block add_css %}
<link rel="stylesheet" href="{{ STATIC_PREFIX }}css/lib/flatpickr.min.css" />
{{ HOOK(H_SLIDESHOW_SLIDES_CSS) }}
{% endblock %}
{% block add_js %}
<script type="text/javascript">
var schedule_start_choices = {
'loop': '{{ l.slideshow_slide_form_label_cron_scheduled_loop }}',
'datetime': '{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}',
'cron': '{{ l.slideshow_slide_form_label_cron_scheduled_cron }}',
};
var schedule_end_choices = {
'stayloop': '{{ l.slideshow_slide_form_label_cron_scheduled_stayloop }}',
'datetime': '{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}',
'duration': '{{ l.slideshow_slide_form_label_cron_scheduled_duration }}',
};
var contents = {{ json_dumps(contents) | safe }}
</script>
<script src="{{ STATIC_PREFIX }}js/lib/flatpickr.min.js"></script>
<script src="{{ STATIC_PREFIX }}js/lib/tablednd-fixed.js"></script>
<script src="{{ STATIC_PREFIX }}js/slideshow/slides.js"></script>
<script src="{{ STATIC_PREFIX }}js/restart.js"></script>
{{ HOOK(H_SLIDESHOW_SLIDES_JAVASCRIPT) }}
{% endblock %}
{% block page %} {% block page %}
<div class="toolbar"> <div class="toolbar">
<h2><i class="fa-regular fa-clock icon-left"></i>{{ l.slideshow_slide_page_title }}</h2>
<div class="toolbar-actions"> <div class="toolbar-actions">
{{ HOOK(H_SLIDESHOW_SLIDES_TOOLBAR_ACTIONS_START) }}
<a href="{% if current_playlist %}{{ url_for('player_use', playlist_slug_or_id=current_playlist.slug) }}{% else %}{{ url_for('player') }}{% endif %}" target="_blank" class="btn" title="{{ l.slideshow_slide_goto_player }}">
<i class="fa fa-eye"></i>
</a>
<a href="{{ url_for('slideshow_player_refresh') }}" class="btn" title="{{ l.slideshow_slide_refresh_player }}"> <a href="{{ url_for('slideshow_player_refresh') }}" class="btn" title="{{ l.slideshow_slide_refresh_player }}">
<i class="fa fa-refresh"></i> <i class="fa fa-refresh"></i>
</a> </a>
<button class="purple slide-add item-add"><i class="fa fa-plus icon-left"></i>{{ l.slideshow_slide_button_add }}</button> <button class="purple slide-add item-add"><i class="fa fa-plus icon-left"></i>{{ l.slideshow_slide_button_add }}</button>
{% if PLAYLIST_ENABLED %}
<select class="select-item-picker playlist-picker">
<option value="{{ url_for('slideshow_slide_list') }}" {% if not current_playlist %}selected="selected"{% endif %}>
{{ l.common_default_playlist }}
</option>
{% for playlist in playlists %}
{% set is_active_playlist = str(current_playlist.id) == str(playlist.id) %}
<option value="{{ url_for('slideshow_slide_list_playlist_use', playlist_id=playlist.id) }}" {% if is_active_playlist %}selected="selected"{% endif %}>
{{ playlist.name }}
</option>
{% endfor %}
</select>
{% endif %}
{{ HOOK(H_SLIDESHOW_SLIDES_TOOLBAR_ACTIONS_END) }}
</div> </div>
</div> </div>
{% if request.args.get('refresh_player') %}
<div class="alert alert-success">
<i class="fa fa-refresh icon-left"></i>
{{ l.slideshow_slide_refresh_player_success|replace('%time%', request.args.get('refresh_player')) }}
</div>
{% endif %}
<div class="panel {% if PLAYLIST_ENABLED %}panel-active{% endif %}"> <div class="panel {% if PLAYLIST_ENABLED %}panel-active{% endif %}">
<div class="panel-body"> <div class="panel-body">
@ -82,26 +20,5 @@
{% endwith %} {% endwith %}
</div> </div>
</div> </div>
<div class="panel panel-inactive">
<div class="panel-body">
<h3>{{ l.slideshow_slide_panel_inactive }}</h3>
{% with tclass='inactive', slides=disabled_slides %}
{% include 'slideshow/slides/component/table.jinja.html' %}
{% endwith %}
</div>
</div>
<div class="modals hidden">
<div class="modals-outer">
<a href="javascript:void(0);" class="modal-close">
<i class="fa fa-close"></i>
</a>
<div class="modals-inner">
{% include 'slideshow/slides/modal/add.jinja.html' %}
{% include 'slideshow/slides/modal/edit.jinja.html' %}
{% include 'core/utrack.jinja.html' %}
</div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -3,7 +3,7 @@
{{ l.slideshow_slide_form_add_title }} {{ l.slideshow_slide_form_add_title }}
</h2> </h2>
<form class="form" action="/slideshow/slide/add" method="POST" enctype="multipart/form-data"> <form class="form" action="{{ url_for('slideshow_slide_add') }}" method="POST" enctype="multipart/form-data">
<h3> <h3>
{{ l.slideshow_slide_form_section_content }} {{ l.slideshow_slide_form_section_content }}
@ -14,7 +14,7 @@
{% endif %} {% endif %}
<div class="picker col"> <div class="picker col">
<div class="form-group slide-content-id-group"> <div class="form-group slide-content-id-group">
<label for="slide-add-content-id">{{ l.slideshow_slide_form_label_content_id }}</label> <label for="slide-add-content-id">{{ l.slideshow_slide_form_label_content_id }}</label>
<div class="widget"> <div class="widget">
<select name="content_id" type="text" id="slide-add-content-id" required="required"></select> <select name="content_id" type="text" id="slide-add-content-id" required="required"></select>
@ -24,9 +24,9 @@
<div class="form-group content-new-group"> <div class="form-group content-new-group">
<label for=""></label> <label for=""></label>
<div class="widget"> <div class="widget">
<button class="btn purple" style="margin:0;"> <button class="btn purple" style="margin:0;">
<i class="fa fa-plus icon-left"></i>{{ l.slideshow_slide_form_label_add_content }} <i class="fa fa-plus icon-left"></i>{{ l.slideshow_slide_form_label_add_content }}
</button> </button>
</div> </div>
</div> </div>
</div> </div>
@ -36,7 +36,7 @@
<div class="form-group"> <div class="form-group">
<label for="slide-add-name">{{ l.slideshow_slide_form_label_name }}</label> <label for="slide-add-name">{{ l.slideshow_slide_form_label_name }}</label>
<div class="widget"> <div class="widget">
<input name="name" type="text" id="slide-add-name" required="required" disabled="disabled" /> <input name="name" type="text" id="slide-add-name" required="required" disabled="disabled"/>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -56,26 +56,28 @@
<div class="form-group object-input"> <div class="form-group object-input">
<label for="slide-add-duration">{{ l.slideshow_slide_form_label_object }}</label> <label for="slide-add-duration">{{ l.slideshow_slide_form_label_object }}</label>
<div class="widget"> <div class="widget">
<input type="text" name="object" id="slide-add-object-input-text" class="slide-add-object-input" disabled="disabled" /> <input type="text" name="object" id="slide-add-object-input-text" class="slide-add-object-input"
<input type="file" name="object" id="slide-add-object-input-upload" class="slide-add-object-input hidden" disabled="disabled" /> disabled="disabled"/>
<input type="file" name="object" id="slide-add-object-input-upload"
class="slide-add-object-input hidden" disabled="disabled"/>
</div> </div>
</div> </div>
</div> </div>
<h3> <h3 class="divide">
{{ l.slideshow_slide_form_section_scheduling }} {{ l.slideshow_slide_form_section_scheduling }}
</h3> </h3>
<div class="form-group slide-notification-group"> <div class="form-group slide-notification-group">
<label for="slide-add-is-notification">{{ l.slideshow_slide_form_label_is_notification }}</label> <label for="slide-add-is-notification">{{ l.slideshow_slide_form_label_is_notification }}</label>
<div class="widget"> <div class="widget">
<input type="checkbox" class="trigger slide-is-notification" name="is_notification" id="slide-add-is-notification" /> <input type="checkbox" class="trigger slide-is-notification" name="is_notification"
id="slide-add-is-notification"/>
</div> </div>
</div> </div>
<div class="form-group slide-schedule-group">
<div class="form-group slide-schedule-group">
<label for="slide-add-cron-schedule">{{ l.slideshow_slide_form_label_cron_scheduled }}</label> <label for="slide-add-cron-schedule">{{ l.slideshow_slide_form_label_cron_scheduled }}</label>
<div class="widget"> <div class="widget">
<select id="slide-add-cron-schedule-trigger" class="trigger"> <select id="slide-add-cron-schedule-trigger" class="trigger">
@ -83,8 +85,10 @@
<option value="datetime">{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}</option> <option value="datetime">{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}</option>
<option value="cron">{{ l.slideshow_slide_form_label_cron_scheduled_cron }}</option> <option value="cron">{{ l.slideshow_slide_form_label_cron_scheduled_cron }}</option>
</select> </select>
<input type="text" id="slide-add-cron-schedule-datetimepicker" class="datetimepicker" value="" placeholder="{{ l.slideshow_slide_form_label_cron_scheduled_datetime_placeholder }}" /> <input type="text" id="slide-add-cron-schedule-datetimepicker" class="datetimepicker" value=""
<input type="text" name="cron_schedule" id="slide-add-cron-schedule" class="target hidden" placeholder="{{ l.slideshow_slide_form_widget_cron_scheduled_placeholder }}" /> placeholder="{{ l.slideshow_slide_form_label_cron_scheduled_datetime_placeholder }}"/>
<input type="text" name="cron_schedule" id="slide-add-cron-schedule" class="target hidden"
placeholder="{{ l.slideshow_slide_form_widget_cron_scheduled_placeholder }}"/>
</div> </div>
</div> </div>
@ -96,29 +100,32 @@
<option value="datetime">{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}</option> <option value="datetime">{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}</option>
<option value="cron">{{ l.slideshow_slide_form_label_cron_scheduled_cron }}</option> <option value="cron">{{ l.slideshow_slide_form_label_cron_scheduled_cron }}</option>
</select> </select>
<input type="text" id="slide-add-cron-schedule-end-datetimepicker" class="datetimepicker" value="" placeholder="{{ l.slideshow_slide_form_label_cron_scheduled_datetime_placeholder }}" /> <input type="text" id="slide-add-cron-schedule-end-datetimepicker" class="datetimepicker" value=""
<input type="text" name="cron_schedule_end" id="slide-add-cron-schedule-end" class="target hidden" placeholder="{{ l.slideshow_slide_form_widget_cron_scheduled_placeholder }}" /> placeholder="{{ l.slideshow_slide_form_label_cron_scheduled_datetime_placeholder }}"/>
<input type="text" name="cron_schedule_end" id="slide-add-cron-schedule-end" class="target hidden"
placeholder="{{ l.slideshow_slide_form_widget_cron_scheduled_placeholder }}"/>
</div> </div>
</div> </div>
<div class="form-group slide-duration-group"> <div class="form-group slide-duration-group">
<label for="slide-add-duration">{{ l.slideshow_slide_form_label_duration }}</label> <label for="slide-add-duration">{{ l.slideshow_slide_form_label_duration }}</label>
<div class="widget"> <div class="widget">
<input type="number" name="duration" id="slide-add-duration" required="required" /> <input type="number" name="duration" id="slide-add-duration" required="required"/>
<span>{{ l.slideshow_slide_form_label_duration_unit }}</span> <span>{{ l.slideshow_slide_form_label_duration_unit }}</span>
</div> </div>
</div> </div>
<div class="actions"> <div class="actions">
<button type="button" class="btn-normal modal-close"> <button type="button" class="btn btn-naked modal-close">
{{ l.slideshow_slide_form_button_cancel }} {{ l.common_close }}
</button> </button>
<button type="submit" class="green"> <button type="submit" class="btn btn-info">
<i class="fa fa-plus icon-left"></i> {{ l.slideshow_slide_form_add_submit }} <i class="fa fa-save icon-left"></i>{{ l.common_save }}
</button> </button>
<button type="button" disabled="disabled" class="green hidden btn-loading"> <button type="button" disabled="disabled" class="btn btn-naked hidden btn-loading">
{{ l.common_loading }} {{ l.common_loading }}
</button> </button>
</div> </div>
</form> </form>
</div> </div>

View File

@ -4,14 +4,14 @@
</h2> </h2>
<form class="form" action="/slideshow/slide/edit" method="POST"> <form class="form" action="{{ url_for('slideshow_slide_edit') }}" method="POST">
<h3> <h3>
{{ l.slideshow_slide_form_section_content }} {{ l.slideshow_slide_form_section_content }}
</h3> </h3>
<input type="hidden" name="id" id="slide-edit-id" /> <input type="hidden" name="id" id="slide-edit-id"/>
<div class="form-group slide-content-id-group"> <div class="form-group slide-content-id-group">
@ -22,14 +22,15 @@
</div> </div>
<h3> <h3 class="divide">
{{ l.slideshow_slide_form_section_scheduling }} {{ l.slideshow_slide_form_section_scheduling }}
</h3> </h3>
<div class="form-group slide-notification-group"> <div class="form-group slide-notification-group">
<label for="slide-edit-is-notification">{{ l.slideshow_slide_form_label_is_notification }}</label> <label for="slide-edit-is-notification">{{ l.slideshow_slide_form_label_is_notification }}</label>
<div class="widget"> <div class="widget">
<input type="checkbox" class="trigger slide-is-notification" name="is_notification" id="slide-edit-is-notification" /> <input type="checkbox" class="trigger slide-is-notification" name="is_notification"
id="slide-edit-is-notification"/>
</div> </div>
</div> </div>
@ -41,8 +42,10 @@
<option value="datetime">{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}</option> <option value="datetime">{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}</option>
<option value="cron">{{ l.slideshow_slide_form_label_cron_scheduled_cron }}</option> <option value="cron">{{ l.slideshow_slide_form_label_cron_scheduled_cron }}</option>
</select> </select>
<input type="text" id="slide-edit-cron-schedule-datetimepicker" class="datetimepicker" value="" placeholder="{{ l.slideshow_slide_form_label_cron_scheduled_datetime_placeholder }}" /> <input type="text" id="slide-edit-cron-schedule-datetimepicker" class="datetimepicker" value=""
<input type="text" name="cron_schedule" id="slide-edit-cron-schedule" class="target hidden" placeholder="{{ l.slideshow_slide_form_widget_cron_scheduled_placeholder }}" /> placeholder="{{ l.slideshow_slide_form_label_cron_scheduled_datetime_placeholder }}"/>
<input type="text" name="cron_schedule" id="slide-edit-cron-schedule" class="target hidden"
placeholder="{{ l.slideshow_slide_form_widget_cron_scheduled_placeholder }}"/>
</div> </div>
</div> </div>
@ -53,25 +56,30 @@
<option value="duration">{{ l.slideshow_slide_form_label_cron_scheduled_duration }}</option> <option value="duration">{{ l.slideshow_slide_form_label_cron_scheduled_duration }}</option>
<option value="datetime">{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}</option> <option value="datetime">{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}</option>
</select> </select>
<input type="text" id="slide-edit-cron-schedule-end-datetimepicker" class="datetimepicker" value="" placeholder="{{ l.slideshow_slide_form_label_cron_scheduled_datetime_placeholder }}" /> <input type="text" id="slide-edit-cron-schedule-end-datetimepicker" class="datetimepicker" value=""
<input type="text" name="cron_schedule_end" id="slide-edit-cron-schedule-end" class="target hidden" placeholder="{{ l.slideshow_slide_form_widget_cron_scheduled_placeholder }}" /> placeholder="{{ l.slideshow_slide_form_label_cron_scheduled_datetime_placeholder }}"/>
<input type="text" name="cron_schedule_end" id="slide-edit-cron-schedule-end" class="target hidden"
placeholder="{{ l.slideshow_slide_form_widget_cron_scheduled_placeholder }}"/>
</div> </div>
</div> </div>
<div class="form-group slide-duration-group"> <div class="form-group slide-duration-group">
<label for="slide-edit-duration">{{ l.slideshow_slide_form_label_duration }}</label> <label for="slide-edit-duration">{{ l.slideshow_slide_form_label_duration }}</label>
<div class="widget"> <div class="widget">
<input type="number" name="duration" id="slide-edit-duration" required="required" /> <input type="number" name="duration" id="slide-edit-duration" required="required"/>
<span>{{ l.slideshow_slide_form_label_duration_unit }}</span> <span>{{ l.slideshow_slide_form_label_duration_unit }}</span>
</div> </div>
</div> </div>
<div class="actions"> <div class="actions">
<button type="button" class="btn-normal modal-close"> <button type="button" class="btn btn-naked modal-close">
{{ l.slideshow_slide_form_button_cancel }} {{ l.common_close }}
</button> </button>
<button type="submit" class="green"> <button type="submit" class="btn btn-info">
<i class="fa fa-save icon-left"></i>{{ l.slideshow_slide_form_edit_submit }} <i class="fa fa-save icon-left"></i>{{ l.common_save }}
</button>
<button type="button" disabled="disabled" class="btn btn-naked hidden btn-loading">
{{ l.common_loading }}
</button> </button>
</div> </div>
</form> </form>