0byt3m1n1
Path:
/
home
/
mgatv524
/
pmj.mgaplay.com.br
/
views
/
[
Home
]
File: playlist-page.twig
{# * Copyright (C) 2021 Xibo Signage Ltd * * Xibo - Digital Signage - http://www.xibo.org.uk * * This file is part of Xibo. * * Xibo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Xibo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Xibo. If not, see <http://www.gnu.org/licenses/>. #} {% extends "authed.twig" %} {% import "inline.twig" as inline %} {% block title %}{{ "Playlists"|trans }} | {% endblock %} {% block actionMenu %} {% if currentUser.featureEnabled("playlist.add") %} <div class="widget-action-menu pull-right"> <button class="btn btn-success XiboFormButton btns" href="{{ url_for("playlist.add.form") }}"><i class="fa fa-plus-circle" aria-hidden="true"></i> {% trans "Add Playlist" %}</button> </div> {% endif %} {% endblock %} {% block pageContent %} <div class="widget"> <div class="widget-title">{% trans "Playlists" %}</div> <div class="widget-body"> <div class="XiboGrid" id="{{ random() }}" data-grid-name="playlistView"> <div class="XiboFilter card mb-3 bg-light"> <div class="FilterDiv card-body" id="Filter"> <ul class="nav nav-tabs" role="tablist"> <li class="nav-item"><a class="nav-link active" href="#general-filter" role="tab" data-toggle="tab"><span>{% trans "General" %}</span></a></li> <li class="nav-item"><a class="nav-link" href="#advanced-filter" role="tab" data-toggle="tab"><span>{% trans "Advanced" %}</span></a></li> </ul> <form class="form-inline"> <div class="tab-content"> <div class="tab-pane active" id="general-filter"> {% set title %}{% trans "Name" %}{% endset %} {{ inline.inputNameGrid('name', title) }} {% if currentUser.featureEnabled("tag.tagging") %} {% set title %}{% trans "Tags" %}{% endset %} {% set exactTagTitle %}{% trans "Exact match?" %}{% endset %} {% set logicalOperatorTitle %}{% trans "When filtering by multiple Tags, which logical operator should be used?" %}{% endset %} {% set helpText %}{% trans "A comma separated list of tags to filter by. Enter a Tag value preceded with | to filter by Tag values. Enter --no-tag to see items without tags." %}{% endset %} {{ inline.inputWithTags("tags", title, null, helpText, null, null, null, "exactTags", exactTagTitle, logicalOperatorTitle) }} {% endif %} {% set attributes = [ { name: "data-live-search", value: "true" }, { name: "data-selected-text-format", value: "count > 4" } ] %} {% set title %}{% trans "Owner" %}{% endset %} {% set helpText %}{% trans "Show items owned by the selected User." %}{% endset %} {{ inline.dropdown("userId", "single", title, "", [{userId:null, userName:""}]|merge(users), "userId", "userName", helpText, "selectPicker", "", "", "", attributes) }} {% set title %}{% trans "Owner User Group" %}{% endset %} {% set helpText %}{% trans "Show items owned by users in the selected User Group." %}{% endset %} {{ inline.dropdown("ownerUserGroupId", "single", title, "", [{groupId:null, group:""}]|merge(groups), "groupId", "group", helpText, "selectPicker", "", "", "", attributes) }} {{ inline.hidden("folderId") }} {% set title %}{% trans "Layout ID" %}{% endset %} {{ inline.number("layoutId", title, layoutId) }} </div> <div class="tab-pane" id="advanced-filter"> {% set title %}{% trans "Show" %}{% endset %} {% set values = [{id: 1, value: "All"}, {id: 2, value: "Only Used"}, {id: 3, value: "Only Unused"}] %} {{ inline.dropdown("playlistStatusId", "single", title, 1, values, "id", "value") }} {% if currentUser.featureEnabled("library.view") %} {% set title %}{% trans "Media" %}{% endset %} {{ inline.input("mediaLike", title) }} {% endif %} </div> </div> </form> </div> </div> <div class="row"> <div class="col-sm-2 p-3 bg-light" id="grid-folder-filter"> <div class="form-check"> <input type="checkbox" class="form-check-input" id="folder-tree-clear-selection-button"> <label class="form-check-label" for="folder-tree-clear-selection-button" title="{% trans "Search in all folders" %}">{% trans "All Folders" %}</label> </div> <div id="container-folder-tree"></div> </div> <div class="folder-controller d-none"> <button type="button" id="folder-tree-select-folder-button" class="btn btn-outline-secondary" title="{% trans "Open / Close Folder Search options" %}"><i class="fas fa-folder fa-1x"></i></button> <div id="breadcrumbs" class="mt-2 pl-2"></div> </div> <div id="datatable-container" class="card col-sm-10 pt-4 px-2"> <div class="XiboData"> <table id="playlists" class="table table-striped" data-content-type="playlist" data-content-id-name="playlistId" data-state-preference-name="playlistGrid" style="width: 100%;"> <thead> <tr> <th>{% trans "ID" %}</th> <th>{% trans "Name" %}</th> <th>{% trans "Duration" %}</th> {% if currentUser.featureEnabled("tag.tagging") %}<th>{% trans "Tags" %}</th>{% endif %} <th>{% trans "Dynamic?" %}</th> <th>{% trans "Owner" %}</th> <th>{% trans "Sharing" %}</th> <th>{% trans "Created" %}</th> <th>{% trans "Modified" %}</th> <th>{% trans "Stats?" %}</th> <th class="rowMenu"></th> </tr> </thead> <tbody> </tbody> </table> </div> </div> </div> </div> </div> </div> <div id="dummyLayout" style="display:none"></div> <div id="editor-container"></div> <div class="loading-overlay"> <i class="fa fa-spinner fa-spin loading-icon"></i> </div> {% endblock %} {% block javaScript %} {# Add common file #} {% include "common.twig" %} <script src="{{ theme.rootUri() }}dist/playlistEditor.bundle.min.js?v={{ version }}&rev={{ revision }}"></script> <script type="text/javascript"> {# Custom translations #} {% autoescape "js" %} {# Insert custom translations here #} {% endautoescape %} var table; $(document).ready(function () { {% if not currentUser.featureEnabled("folder.view") %} disableFolders(); {% endif %} // Create ourselves a little hidden layout for preview sizing, etc $("#dummyLayout").html('<div id="layout" data-background-color="#000000" style="background-color: #000000" designer_scale="1"><div id="region_-1" zindex="1" tip_scale="1" designer_scale="1" width="800" height="450"></div></div>'); // Configure the DataTable table = $("#playlists").DataTable({ "language": dataTablesLanguage, dom: dataTablesTemplate, "lengthMenu": [10, 25, 50, 100, 250, 500], serverSide: true, stateSave: true, responsive: true, stateLoadCallback: dataTableStateLoadCallback, stateSaveCallback: dataTableStateSaveCallback, filter: false, searchDelay: 3000, "order": [[1, "asc"]], ajax: { url: "{{ url_for("playlist.search") }}", "data": function (d) { $.extend(d, $("#playlists").closest(".XiboGrid").find(".FilterDiv form").serializeObject()); } }, "columns": [ {"data": "playlistId", responsivePriority: 2}, { "data": "name", responsivePriority: 3, "render": dataTableSpacingPreformatted }, { "data": "duration", responsivePriority: 3, "render": function (data, type, row) { if (type !== "display" && type !== "export") return data; if (row.requiresDurationUpdate === 1) { return '<span class="fa fa-clock-o" title="{{ "Changes have been made and we are recalculating this Playlists duration" }}"></span>'; } else if (row.requiresDurationUpdate !== 0) { return moment().startOf("day").seconds(data).format("H:mm:ss") + ' <span class="fa fa-clock-o" title="{{ "This duration will be updated at " }}' + moment(row.requiresDurationUpdate, "X").format(jsDateFormat) + '"></span>'; } return dataTableTimeFromSeconds(data, type, row); } }, {% if currentUser.featureEnabled("tag.tagging") %}{ "sortable": false, "visible": false, responsivePriority: 4, "data": dataTableCreateTags },{% endif %} {"data": "isDynamic", "render": dataTableTickCrossColumn, responsivePriority: 4}, {"data": "owner", responsivePriority: 4}, { "data": "groupsWithPermissions", responsivePriority: 5, "render": dataTableCreatePermissions }, { "data": "createdDt", responsivePriority: 6, "render": dataTableDateFromIso, "visible": false }, { "data": "modifiedDt", responsivePriority: 6, "render": dataTableDateFromIso, "visible": false }, { "name": "enableStat", responsivePriority: 6, "data": function (data) { var icon = ""; if (data.enableStat == 'On') icon = "fa-check"; else if (data.enableStat == 'Off') icon = "fa-times"; else icon = "fa-level-down"; return '<span class="fa ' + icon + '" title="' + (data.enableStatDescription) + '"></span>'; } }, { "orderable": false, responsivePriority: 1, "data": dataTableButtonsColumn } ] }); table.on('draw', dataTableDraw); table.on('draw', {form: $("#playlists").closest(".XiboGrid").find(".FilterDiv form")}, dataTableCreateTagEvents); table.on('processing.dt', dataTableProcessing); dataTableAddButtons(table, $('#playlists_wrapper').find('.dataTables_buttons')); }); // Playlist Add Form // contains a grid on the populate tab // hook up the grid var mediaTable; var nameFilter; var tagFilter; var exactTags; var logicalOperator; var logicalOperatorName; function playlistEditorFormOpen(formData) { // Clear container $('#editor-container').empty(); // Append form $('#editor-container').append(formData.message); } function playlistFormOpen(dialog) { mediaTable = null; $(dialog).find("input[name=filterMediaName]").on("keyup", _.debounce(function () { playlistFormPopulateMediaTable(dialog); }, 500)); $(dialog).find("input[name=filterMediaTag], input[name=exactTags], select[name=logicalOperator], select[name=logicalOperatorName]").on("change", function () { playlistFormPopulateMediaTable(dialog); }); // First time in there playlistFormPopulateMediaTable(dialog); // Run function to set the form submit behaviour playlistAddFormOpen(); } /// /// Playlist Usage Form /// function usageFormOpen(dialog) { // Displays tab var usageTable = $("#usageReportTable").DataTable({ "language": dataTablesLanguage, serverSide: true, stateSave: true, stateDuration: 0, filter: false, searchDelay: 3000, responsive: true, "order": [[1, "asc"]], ajax: { "url": "{{ url_for("playlist.usage", {id:':id'}) }}".replace(":id", $("#usageReportTable").data().playlistId), "data": function (dataDisplay) { $.extend(dataDisplay, $(dialog).find("#usageReportForm").serializeObject()); return dataDisplay; } }, "columns": [ {"data": "displayId"}, {"data": "display"}, {"data": "description"} ] }); usageTable.on('draw', dataTableDraw); usageTable.on('processing.dt', dataTableProcessing); // Layouts tab var usageTableLayouts = $("#usageReportLayoutsTable").DataTable({ "language": dataTablesLanguage, serverSide: true, stateSave: true, stateDuration: 0, filter: false, searchDelay: 3000, responsive: true, "order": [[1, "asc"]], ajax: { "url": "{{ url_for("playlist.usage.layouts", {id:':id'}) }}".replace(":id", $("#usageReportLayoutsTable").data().playlistId) }, "columns": [ {"data": "layoutId"}, {"data": "layout"}, {"data": "description"}, { "orderable": false, "data": dataTableButtonsColumn } ] }); usageTableLayouts.on('draw', dataTableDraw); usageTableLayouts.on('processing.dt', dataTableProcessing); } function playlistFormPopulateMediaTable(dialog) { nameFilter = $(dialog).find("input[name=filterMediaName]").val(); tagFilter = $(dialog).find("input[name=filterMediaTag]").val(); exactTags = $(dialog).find("input[name=exactTags]").is(':checked') logicalOperator = $(dialog).find("select[name=logicalOperator]").val(); logicalOperatorName = $(dialog).find("select[name=logicalOperatorName]").val(); if (nameFilter === "" && tagFilter === "") { if (mediaTable != null) { mediaTable.destroy(); mediaTable = null; $("#playlistLibraryMedia tbody").empty(); } return; } if (mediaTable != null) { mediaTable.ajax.reload(); } else { mediaTable = $("#playlistLibraryMedia").DataTable({ "language": dataTablesLanguage, serverSide: true, stateSave: true, stateDuration: 0, filter: false, responsive: true, searchDelay: 3000, "order": [[1, "asc"]], ajax: { "url": "{{ url_for("library.search") }}", "data": function (d) { $.extend( d, { media: nameFilter, tags: tagFilter, assignable: 1, exactTags: exactTags, logicalOperator: logicalOperator, logicalOperatorName: logicalOperatorName } ); } }, "columns": [ {"data": "mediaId"}, {"data": "name"}, {"data": "mediaType"}, {% if currentUser.featureEnabled("tag.tagging") %}{"data": dataTableCreateTags},{% endif %} { "name": "duration", "data": function (data, type) { if (type !== "display") return data.duration; return moment().startOf("day").seconds(data.duration).format("H:mm:ss"); } } ] }); mediaTable.on('processing.dt', dataTableProcessing); mediaTable.on('draw', {form: $(".playlistForm")}, dataTableCreateTagEvents); } } function setEnableStatMultiSelectFormOpen(dialog) { var $select = $('<select id="enableStat" name="enableStat" class="form-control">' + '<option value="Off">{% trans %} Off {% endtrans %}</option>' + '<option value="On">{% trans %} On {% endtrans %}</option>' + '<option value="Inherit">{% trans %} Inherit {% endtrans %}</option>' + '</select>'); $select.on('change', function () { dialog.data().commitData = {enableStat: $(this).val()}; }).trigger('change'); $(dialog).find('.modal-body').append($select); } function playlistAddFormOpen() { $("#playlistAddForm").off("submit").submit(function (e) { e.preventDefault(); var form = $(this); $.ajax({ type: $(this).attr("method"), url: $(this).attr("action"), data: $(this).serialize(), cache: false, dataType: "json", success: function (xhr, textStatus, error) { XiboSubmitResponse(xhr, form); if (xhr.success && xhr.data.isDynamic == 0) { // Open the editor openPlaylistEditorForm(xhr.id); } } }); }); } function openPlaylistEditorForm(playlistId) { var requestPath = playlistEditorUrl; // replace id if necessary/exists requestPath = requestPath.replace(':id', playlistId); $.ajax({ url: requestPath, type: 'GET' }).done(function (res) { if (!res.success) { // Login Form needed? if (res.login) { window.location.href = window.location.href; location.reload(); } else { // Just an error we dont know about if (res.message == undefined) { console.error(res); } else { console.error(res.message); } } } else { // Clear container $('#editor-container').empty(); // Append form $('#editor-container').append(res.html); } }).fail(function (jqXHR, textStatus, errorThrown) { // Output error to console console.error(jqXHR, textStatus, errorThrown); }); } </script> {% for module in modules %} {% if module.layoutDesignerJavaScript() != "" %} {% include module.layoutDesignerJavaScript() ~ ".twig" %} {% endif %} {% endfor %} {% endblock %}