0byt3m1n1
Path:
/
home
/
mgatv524
/
novabrasil.mgaplay.com.br
/
views
/
[
Home
]
File: campaign-page.twig
{# /** * Copyright (C) 2020 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 %}{{ "Campaigns"|trans }} | {% endblock %} {% block actionMenu %} {% if currentUser.featureEnabled("campaign.add") %} <div class="widget-action-menu pull-right"> <button class="btn btn-success XiboFormButton" title="{% trans "Add a new Campaign" %}" href="{{ url_for("campaign.add.form") }}"> <i class="fa fa-plus-circle" aria-hidden="true"></i> {% trans "Add Campaign" %}</button> </div> {% endif %} {% endblock %} {% block pageContent %} <div class="widget"> <div class="widget-title">{% trans "Campaigns" %}</div> <div class="widget-body"> <div class="XiboGrid" id="{{ random() }}" data-grid-name="campaignView"> <div class="XiboFilter card mb-3 bg-light"> <div class="FilterDiv card-body" id="Filter"> <form class="form-inline"> {% 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 title %}{% trans "Layouts" %}{% endset %} {% set values = [{id: 0, value: ""}, {id: 2, value: "Yes"}, {id: 1, value: "No"}] %} {{ inline.dropdown("hasLayouts", "single", title, 0, values, "id", "value") }} {{ inline.hidden("folderId") }} {% set title %}{% trans "Layout ID" %}{% endset %} {{ inline.number("layoutId", title, layoutId) }} {% if currentUser.featureEnabled('ad.campaign') %} {% set title %}{% trans "Type" %}{% endset %} {% set options = [ { id: null, name: "" }, { id: "list", name: "Layout list"|trans }, { id: "ad", name: "Ad Campaign"|trans } ] %} {{ inline.dropdown("type", "single", title, "both", options, "id", "name", helpText) }} {% endif %} {% set title %}{% trans "Cycle Based Playback" %}{% endset %} {% set enabled %}{% trans "Enabled" %}{% endset %} {% set disabled %}{% trans "Disabled" %}{% endset %} {% set options = [ { optionid: "", option: "" }, { optionid: 0, option: disabled}, { optionid: 1, option: enabled} ] %} {{ inline.dropdown("cyclePlaybackEnabled", "single", title, "", options, "optionid", "option") }} </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="campaigns" class="table table-striped" data-content-type="campaign" data-content-id-name="campaignId" data-state-preference-name="campaignGrid" style="width: 100%;"> <thead> <tr> <th>{% trans "Name" %}</th> {% if currentUser.featureEnabled('ad.campaign') %} <th>{% trans "Type" %}</th> <th>{% trans "Start Date" %}</th> <th>{% trans "End Date" %}</th> {% endif %} <th>{% trans "# Layouts" %}</th> {% if currentUser.featureEnabled("tag.tagging") %}<th>{% trans "Tags" %}</th>{% endif %} <th>{% trans "Duration" %}</th> <th>{% trans "Cycle based Playback" %}</th> <th>{% trans "Play Count" %}</th> {% if currentUser.featureEnabled('ad.campaign') %} <th>{% trans "Target Type" %}</th> <th>{% trans "Target" %}</th> <th>{% trans "Plays" %}</th> <th>{% trans "Spend" %}</th> <th>{% trans "Impressions" %}</th> {% endif %} <th>{% trans "Ref 1" %}</th> <th>{% trans "Ref 2" %}</th> <th>{% trans "Ref 3" %}</th> <th>{% trans "Ref 4" %}</th> <th>{% trans "Ref 5" %}</th> <th>{% trans "Created At" %}</th> <th>{% trans "Modified At" %}</th> <th>{% trans "Modified By" %}</th> <th class="rowMenu"></th> </tr> </thead> <tbody> </tbody> </table> </div> </div> </div> </div> </div> </div> {% endblock %} {% block javaScript %} <script type="text/javascript"> var table; // Configure the DataTable $(document).ready(function() { {% if not currentUser.featureEnabled("folder.view") %} disableFolders(); {% endif %} table = $("#campaigns").DataTable({"language": dataTablesLanguage, serverSide: true, stateSave: true, stateDuration: 0, responsive: true, dom: dataTablesTemplate, stateLoadCallback: dataTableStateLoadCallback, stateSaveCallback: dataTableStateSaveCallback, "filter": false, searchDelay: 3000, "order": [[ 0, "asc"]], ajax: { url: "{{ url_for("campaign.search") }}", "data": function(d) { $.extend(d, $("#campaigns").closest(".XiboGrid").find(".FilterDiv form").serializeObject()); } }, "columns": [ { "data": "campaign" , responsivePriority: 2, "render": dataTableSpacingPreformatted }, {% if currentUser.featureEnabled('ad.campaign') %} { data: 'type', responsivePriority: 2, render: function(data, type) { if (type !== 'display') { return data; } else if (data === 'list') { return '{{ "List"|trans }}'; } else if (data === 'ad') { return '{{ "Ad"|trans }}'; } return data; } }, { data: 'startDt', responsivePriority: 2, render: dataTableDateFromUnix, }, { data: 'endDt', responsivePriority: 2, render: dataTableDateFromUnix, }, {% endif %} { "data": "numberLayouts", responsivePriority: 2 }, {% if currentUser.featureEnabled("tag.tagging") %} { "sortable": false, responsivePriority: 2, "data": dataTableCreateTags },{% endif %} { "data": "totalDuration", responsivePriority: 2, "render": dataTableTimeFromSeconds }, { "name": "cyclePlaybackEnabled", responsivePriority: 3, "data": function (data, type) { if (type != "display") { return data.cyclePlaybackEnabled; } var icon = ""; if (data.cyclePlaybackEnabled == 1) { icon = "fa-check"; } else { icon = "fa-times"; } return '<span class="fa ' + icon + '"></span>'; }, }, { "name": "playCount", responsivePriority: 3, "data": function (data, type) { if (type !== 'display') { return data.playCount; } if (!data.playCount) { return ""; } else { return data.playCount; } } }, {% if currentUser.featureEnabled('ad.campaign') %} { data: 'targetType', responsivePriority: 3, render: function(data, type) { if (data === 'plays') { return '{{ "Plays"|trans }}'; } else if (data === 'budget') { return '{{ "Budget"|trans }}'; } return data; }, }, { data: 'target', responsivePriority: 3, }, { data: 'plays', responsivePriority: 6, }, { data: 'spend', responsivePriority: 6, }, { data: 'impressions', responsivePriority: 6, }, {% endif %} { data: 'ref1', responsivePriority: 10, visible: false, }, { data: 'ref2', responsivePriority: 10, visible: false, }, { data: 'ref3', responsivePriority: 10, visible: false, }, { data: 'ref4', responsivePriority: 10, visible: false, }, { data: 'ref5', responsivePriority: 10, visible: false, }, { data: 'createdAt', responsivePriority: 5, render: dataTableDateFromIso, visible: false, }, { data: 'modifiedAt', responsivePriority: 5, render: dataTableDateFromIso, visible: false, }, { data: 'modifiedByName', responsivePriority: 5, visible: false, }, { "orderable": false, responsivePriority: 1, "data": dataTableButtonsColumn } ] }); // Data Table events table.on('draw', dataTableDraw); table.on('draw', { form: $("#campaigns").closest(".XiboGrid").find(".FilterDiv form") }, dataTableCreateTagEvents); table.on('processing.dt', dataTableProcessing); dataTableAddButtons(table, $('#campaigns_wrapper').find('.dataTables_buttons')); }); // Callback for the media form // Fired when the media form opens function campaignAssignLayoutsFormOpen(dialog) { // setup checkbox behaviour for cycle based playback formHelpers.setupCheckboxInputFields($(dialog).find('form:not(.form-inline)'), 'input[name="cyclePlaybackEnabled"]', '.cycle-based-playback'); // Layout element template var layoutElementTemplate = Handlebars.compile($("#campaign-assign-layout").html()); // Convert our filter form tags inputs into actual tag inputs $(dialog).find("#tags").tagsinput(); // Hold a container for the layouts we have assigned already var container = $("#LayoutAssign"); // Assignment table var $layoutAssignments = $("#layoutAssignments"); var $layoutAssignSortable = $("#LayoutAssignSortable"); // Update all the layout element positions var updateSortablePositions = function() { dialog.find('input[name="manageLayouts"]').val(1); $layoutAssignSortable.find('li').each(function(idx, el) { $(el).find('.layout-order').html(idx+1); }); }; // Populate layouts var layoutsArray = $layoutAssignSortable.data('layouts'); for (layoutIndex = 0; layoutIndex < layoutsArray.length; layoutIndex++) { var layout = layoutsArray[layoutIndex]; // Append to our layouts list var newItem = layoutElementTemplate({ index: (layoutIndex + 1), layoutId: layout.layoutId, layoutName: layout.layout, locked: layout.locked }); $(newItem).appendTo("#LayoutAssignSortable"); } // Layout DataTable var layoutTable = $layoutAssignments.DataTable({ language: dataTablesLanguage, serverSide: true, stateSave: true, stateDuration: 0, pageLength: 5, lengthMenu: [5, 10, 25, 50], stateLoadCallback: dataTableStateLoadCallback, stateSaveCallback: dataTableStateSaveCallback, searchDelay: 3000, "order": [[ 0, "asc"]], "filter": false, ajax: { url: "{{ url_for("layout.search") }}?retired=0", data: function(d) { $.extend(d, $layoutAssignments.closest('.XiboGrid') .find('.layoutAssignFilterOptions') .find('input, select') .serializeObject()); } }, "columns": [ { "data": "layoutId" }, { "data": "layout", "render": dataTableSpacingPreformatted }, { "name": "status", "data": function (data, type) { if (type != "display") return data.status; var icon = ""; if (data.status == 1) icon = "fa-check"; else if (data.status == 2) icon = "fa-exclamation"; else if (data.status == 3) icon = "fa-cogs"; else icon = "fa-times"; return "<span class='fa " + icon + "' title='" + (data.statusDescription) + ((data.statusMessage == null) ? "" : " - " + (data.statusMessage)) + "'></span>"; } }, { "sortable": false, "data": function(data, type, row, meta) { if (type !== "display") return ""; // Create a click-able span return "<a href=\"#\" class=\"assignItem\"><span class=\"fa fa-plus\"></a>"; } } ] }); layoutTable.on('draw', { form: $layoutAssignments.closest(".XiboGrid").find("form") }, function(e, settings) { dataTableDraw(e, settings); dataTableCreateTagEvents(e, settings); // Bind a click event to each table rows + button (span) $layoutAssignments.find(".assignItem").on("click", function() { // Get the row that this is in. var data = layoutTable.row($(this).closest("tr")).data(); // Append to our layouts list var newItem = layoutElementTemplate({ index: ($("#LayoutAssignSortable").find('li').length + 1), layoutId: data.layoutId, layoutName: data.layout, locked: false }); $(newItem).appendTo("#LayoutAssignSortable"); dialog.find('input[name="manageLayouts"]').val(1); }); }); layoutTable.on('processing.dt', dataTableProcessing); // Make our little list sortable $layoutAssignSortable.sortable({ cancel: ".ui-state-disabled", update: function( event, ui ) { updateSortablePositions(); } }); // Bind to the existing items in the list $layoutAssignSortable.on('click', '.layout-remove', function () { $(this).parent().remove(); updateSortablePositions(); }); // Bind the filter form $(".layoutAssignFilterOptions").find("input, select").change(function() { layoutTable.ajax.reload(); }); // Adjust the datatable width once we've activated the tab $(dialog).find('.nav-tabs a').on('shown.bs.tab', function(event) { if ($(event.target).attr('href') === '#tab-layouts') { layoutTable.columns.adjust().draw(); } }); } function campaignFormSubmit($form) { // Process layouts to add layoutAssignSubmit($form); // Submit form $form.submit(); } function layoutAssignSubmit($form) { if (parseInt($form.find('input[name="manageLayouts"]').val()) === 1) { // Get the final sortable positions const finalLayoutPositions = []; $('#LayoutAssignSortable').find('li').each(function() { finalLayoutPositions.push($(this).data('layoutId')); }); // Build the array of layouts for (let i = 0; i < finalLayoutPositions.length; i++) { $('<input>').attr({ type: 'hidden', name: 'layoutIds[' + i + ']' }).val(finalLayoutPositions[i]).appendTo($form.find('#assignLayouts')); } } } /** * Called when the campaign add form is opened * @param dialog */ function campaignAddFormOpen(dialog) { // setup checkbox behaviour for cycle based playback formHelpers.setupCheckboxInputFields($(dialog).find('form'), 'input[name="cyclePlaybackEnabled"]', '.cycle-based-playback'); const $type = $(dialog).find('select[name=type]'); const $cycleBased = $('input[name="cyclePlaybackEnabled"]'); $(dialog).find('.campaign-type-ad').toggle($type.val() === 'ad'); $type.on('change', function () { $(dialog).find('.campaign-type-list').toggle($type.val() !== 'ad'); $(dialog).find('.campaign-type-ad').toggle($type.val() === 'ad'); $(dialog).find('.cycle-based-playback').toggle($cycleBased.is(':checked') && $type.val() !== 'ad'); }); } /** * Called when the campaign add form is submitted. * @param xhr * @param form */ function campaignAddFormSubmitCallback(xhr, form) { if (xhr.success) { if (xhr.data.type === 'ad') { // Navigate to the campaign builder } else { // Open the edit form. XiboFormRender($(form).data("editFormUrl").replace(':id', xhr.data.campaignId)); } } } </script> {% verbatim %} <script type="text/x-handlebars-template" id="campaign-assign-layout"> <li data-layout-id="{{ layoutId }}" class="btn btn-sm btn-white {{#if locked}}ui-state-disabled{{/if}}"> <div class="float-left text-left layout-order">{{index}}</div> <div class="layout-name float-left" title="{{ layoutName }}">{{ layoutName }}</div> <div class="layout-icon fa {{#if locked}}fa-lock{{else}}fa-minus layout-remove{{/if}}"></div> </li> </script> {% endverbatim %} {% endblock %}