496 lines
20 KiB
Twig
496 lines
20 KiB
Twig
|
|
{#
|
||
|
|
/**
|
||
|
|
* Copyright (C) 2022 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/>.
|
||
|
|
*/
|
||
|
|
#}
|
||
|
|
{% import "forms.twig" as forms %}
|
||
|
|
<script type="text/javascript" nonce="{{ cspNonce }}">
|
||
|
|
{% autoescape "js" %}
|
||
|
|
window.audienceDaysOfWeek = {
|
||
|
|
1: "{{ "Monday"|trans }}",
|
||
|
|
2: "{{ "Tuesday"|trans }}",
|
||
|
|
3: "{{ "Wednesday"|trans }}",
|
||
|
|
4: "{{ "Thursday"|trans }}",
|
||
|
|
5: "{{ "Friday"|trans }}",
|
||
|
|
6: "{{ "Saturday"|trans }}",
|
||
|
|
7: "{{ "Sunday"|trans }}",
|
||
|
|
};
|
||
|
|
{% endautoescape %}
|
||
|
|
|
||
|
|
window.audienceFormOpen = function($audienceConnector) {
|
||
|
|
// Make a datatable
|
||
|
|
var dialog = $audienceConnector.closest('.modal');
|
||
|
|
var $table = $('#audience-dma');
|
||
|
|
var audienceDmaTable;
|
||
|
|
audienceDmaTable = $table.DataTable({
|
||
|
|
language: dataTablesLanguage,
|
||
|
|
dom: dataTablesTemplate,
|
||
|
|
serverSide: false,
|
||
|
|
stateSave: false,
|
||
|
|
responsive: true,
|
||
|
|
filter: true,
|
||
|
|
searchDelay: 3000,
|
||
|
|
order: [[ 0, 'asc']],
|
||
|
|
ajax: {
|
||
|
|
url: $table.data('proxyUrl').replace(':method', 'dmaSearch'),
|
||
|
|
data: function (d) {
|
||
|
|
$.extend(d, $table.closest('.XiboGrid').find('.FilterDiv form').serializeObject());
|
||
|
|
}
|
||
|
|
},
|
||
|
|
columns: [
|
||
|
|
{ data: 'name', responsivePriority: 1 },
|
||
|
|
{ data: 'costPerPlay', responsivePriority: 1 },
|
||
|
|
{ data: 'impressionsPerPlay', responsivePriority: 1 },
|
||
|
|
{ data: 'impressionSource', responsivePriority: 10 },
|
||
|
|
{
|
||
|
|
data: 'startDate',
|
||
|
|
responsivePriority: 2,
|
||
|
|
render: function(data, type) {
|
||
|
|
if (type !== 'display' && type !== 'export' || data == null) {
|
||
|
|
return data;
|
||
|
|
}
|
||
|
|
|
||
|
|
return moment(data, systemDateFormat).format(jsDateOnlyFormat);
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
data: 'endDate',
|
||
|
|
responsivePriority: 2,
|
||
|
|
render: function(data, type) {
|
||
|
|
if (type !== 'display' && type !== 'export' || data == null) {
|
||
|
|
return data;
|
||
|
|
}
|
||
|
|
|
||
|
|
return moment(data, systemDateFormat).format(jsDateOnlyFormat);
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
data: 'daysOfWeek',
|
||
|
|
responsivePriority: 2,
|
||
|
|
render: function(data) {
|
||
|
|
let daysOfWeek = [];
|
||
|
|
$.each(data, function(index, el) {
|
||
|
|
daysOfWeek.push(audienceDaysOfWeek[el]);
|
||
|
|
});
|
||
|
|
return daysOfWeek.join(', ');
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{ data: 'startTime', responsivePriority: 2 },
|
||
|
|
{ data: 'endTime', responsivePriority: 2 },
|
||
|
|
{
|
||
|
|
data: 'geoFence',
|
||
|
|
responsivePriority: 3,
|
||
|
|
render: function(data) {
|
||
|
|
let icon;
|
||
|
|
if (data && data.length > 0)
|
||
|
|
icon = "fa-check";
|
||
|
|
else
|
||
|
|
icon = "fa-times";
|
||
|
|
|
||
|
|
return '<span class="fa ' + icon + '"></span>';
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{ data: 'priority', responsivePriority: 2 },
|
||
|
|
{
|
||
|
|
data: function(data) {
|
||
|
|
if (data.displays) {
|
||
|
|
return data.displays.length;
|
||
|
|
} else {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
},
|
||
|
|
responsivePriority: 1,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
data: function(data, type, set, meta) {
|
||
|
|
if (type !== 'display') {
|
||
|
|
return '';
|
||
|
|
}
|
||
|
|
return '<a class="btn btn-sm" href="#" id="addDmaBtn"><span class="fa fa-pencil" title="{% trans %}Edit{% endtrans %}"></span></a>'
|
||
|
|
+ '<a class="btn btn-sm" href="#" id="delDmaBtn"><span class="fa fa-trash" title="{% trans %}Delete{% endtrans %}"></span></a>';
|
||
|
|
},
|
||
|
|
responsivePriority: 1,
|
||
|
|
}
|
||
|
|
],
|
||
|
|
});
|
||
|
|
|
||
|
|
table.on('draw', dataTableDraw);
|
||
|
|
table.on('processing.dt', dataTableProcessing);
|
||
|
|
|
||
|
|
// Add button
|
||
|
|
new $.fn.dataTable.Buttons(audienceDmaTable, {
|
||
|
|
buttons: [
|
||
|
|
{
|
||
|
|
text: '{{ "Add DMA"|trans }}',
|
||
|
|
action: function (e, dt, node, config) {
|
||
|
|
openDmaForm();
|
||
|
|
},
|
||
|
|
},
|
||
|
|
]
|
||
|
|
});
|
||
|
|
|
||
|
|
audienceDmaTable.buttons().container().css('margin-bottom', '10px').appendTo('#audience-dma_wrapper .dataTables_folder');
|
||
|
|
|
||
|
|
setTimeout(function() {
|
||
|
|
audienceDmaTable.columns.adjust()
|
||
|
|
}, 500);
|
||
|
|
|
||
|
|
// Handle btn click
|
||
|
|
$('#ssp-activity tbody').on('click', 'a', function (e) {
|
||
|
|
let btnType = $(this).attr('id');
|
||
|
|
let id = table.row(e.target.closest('tr')).index();
|
||
|
|
|
||
|
|
if (btnType === 'addDmaBtn') {
|
||
|
|
openDmaForm(id);
|
||
|
|
} else if (btnType === 'delDmaBtn') {
|
||
|
|
deleteDmaForm(id);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// Add an add button.
|
||
|
|
var dmaTemplate = Handlebars.compile($('#xibo-audience-connector-dma-form').html());
|
||
|
|
window.openDmaForm = function(id = null) {
|
||
|
|
let title;
|
||
|
|
let method;
|
||
|
|
let dma;
|
||
|
|
if (id !== null) {
|
||
|
|
dma = audienceDmaTable.rows(id).data()[0];
|
||
|
|
title = '{{ "Edit DMA"|trans }}';
|
||
|
|
method = 'dmaEdit';
|
||
|
|
} else {
|
||
|
|
title = '{{ "Add DMA"|trans }}';
|
||
|
|
method = 'dmaAdd';
|
||
|
|
}
|
||
|
|
|
||
|
|
bootbox.hideAll();
|
||
|
|
const $dialog = bootbox.dialog({
|
||
|
|
message: dmaTemplate({
|
||
|
|
connectorId: $table.data('connectorId'),
|
||
|
|
method: method,
|
||
|
|
dma: dma,
|
||
|
|
impressionSources: $table.data('impressionSources'),
|
||
|
|
}),
|
||
|
|
title: title,
|
||
|
|
animate: false,
|
||
|
|
size: 'large',
|
||
|
|
buttons: {
|
||
|
|
back: {
|
||
|
|
label: '{{ "Back"|trans }}',
|
||
|
|
className: 'btn-white',
|
||
|
|
callback: function() {
|
||
|
|
// Open up the connector config form.
|
||
|
|
bootbox.hideAll();
|
||
|
|
$('[data-connector-class-name-last="XiboAudienceReportingConnector"]').find('.btn-primary').click();
|
||
|
|
}
|
||
|
|
},
|
||
|
|
save: {
|
||
|
|
label: '{{ "Save"|trans }}',
|
||
|
|
className: 'btn-success',
|
||
|
|
callback: function() {
|
||
|
|
// Submit the form in the usual way, and then open up the connector config form.
|
||
|
|
const $form = $dialog.find('form');
|
||
|
|
const button = $dialog.find('.btn-success');
|
||
|
|
button.addClass('disabled').append('<span class="saving fa fa-cog fa-spin p-1"></span>');
|
||
|
|
|
||
|
|
XiboFormSubmit($form, null, function(xhr) {
|
||
|
|
if (xhr.success === false) {
|
||
|
|
button.removeClass('disabled').find('.saving').remove();
|
||
|
|
} else {
|
||
|
|
bootbox.hideAll();
|
||
|
|
$('[data-connector-class-name-last="XiboAudienceReportingConnector"]').find('.btn-primary').click();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
},
|
||
|
|
},
|
||
|
|
onShown: function(e) {
|
||
|
|
const $form = $(e.target).find('form');
|
||
|
|
|
||
|
|
// Before we initialise we work out if we need to set the initial key/value on the displayGroupId
|
||
|
|
// select list.
|
||
|
|
const $displayGroupId = $form.find('select[name=displayGroupId]');
|
||
|
|
if (dma && dma.displayGroupId) {
|
||
|
|
$displayGroupId.attr('data-initial-key', 'displayGroupId');
|
||
|
|
$displayGroupId.attr('data-initial-value', dma.displayGroupId);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Initialise general fields.
|
||
|
|
XiboInitialise('#' + $form.attr('id'));
|
||
|
|
|
||
|
|
const $daysOfWeek = $form.find('select[name="daysOfWeek[]"]');
|
||
|
|
if (dma && dma.daysOfWeek) {
|
||
|
|
$.each(dma.daysOfWeek, function(index, element) {
|
||
|
|
$daysOfWeek.find('option[value=' + element + ']')
|
||
|
|
.attr('selected', 'selected');
|
||
|
|
});
|
||
|
|
}
|
||
|
|
$daysOfWeek.select2({width: '100%'}).val();
|
||
|
|
|
||
|
|
// Map
|
||
|
|
// ---
|
||
|
|
const getDataProperty = function($element, property, defaultValue = null) {
|
||
|
|
const value = $element.data(property);
|
||
|
|
if (value) {
|
||
|
|
return value;
|
||
|
|
} else {
|
||
|
|
return defaultValue;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
const $containerSelector = $form.find('#audience-dma-map');
|
||
|
|
const $geoFenceField = $form.find('input[name="geoFence"]');
|
||
|
|
if (dma && dma.geoFence) {
|
||
|
|
$geoFenceField.val(JSON.stringify(dma.geoFence));
|
||
|
|
}
|
||
|
|
|
||
|
|
let map = null;
|
||
|
|
$(e.target).find('a[data-toggle="tab"]').on('shown.bs.tab', function (event) {
|
||
|
|
if ($(event.target).attr('href') === '#tab-geo' && map === null) {
|
||
|
|
map = L.map('audience-dma-map').setView(
|
||
|
|
[
|
||
|
|
getDataProperty($containerSelector, 'mapLat', '51'),
|
||
|
|
getDataProperty($containerSelector, 'mapLong', '0.4'),
|
||
|
|
],
|
||
|
|
getDataProperty($containerSelector, 'mapZoom', 13),
|
||
|
|
);
|
||
|
|
|
||
|
|
L.tileLayer(getDataProperty($containerSelector, 'mapTileServer'), {
|
||
|
|
attribution: getDataProperty(
|
||
|
|
$containerSelector,
|
||
|
|
'mapAttribution',
|
||
|
|
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
||
|
|
),
|
||
|
|
subdomains: ['a', 'b', 'c'],
|
||
|
|
}).addTo(map);
|
||
|
|
|
||
|
|
// Add a layer for drawn items
|
||
|
|
const drawnItems = new L.FeatureGroup();
|
||
|
|
map.addLayer(drawnItems);
|
||
|
|
|
||
|
|
// Add draw control (toolbar)
|
||
|
|
const drawControl = new L.Control.Draw({
|
||
|
|
position: 'topright',
|
||
|
|
draw: {
|
||
|
|
polyline: false,
|
||
|
|
circle: false,
|
||
|
|
marker: false,
|
||
|
|
circlemarker: false,
|
||
|
|
},
|
||
|
|
edit: {
|
||
|
|
featureGroup: drawnItems,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
map.addControl(drawControl);
|
||
|
|
|
||
|
|
// add search Control - allows searching by country/city and automatically
|
||
|
|
// moves map to that location
|
||
|
|
const searchControl = new L.Control.Search({
|
||
|
|
url: 'https://nominatim.openstreetmap.org/search?format=json&q={s}',
|
||
|
|
jsonpParam: 'json_callback',
|
||
|
|
propertyName: 'display_name',
|
||
|
|
propertyLoc: ['lat', 'lon'],
|
||
|
|
marker: L.circleMarker([0, 0], {radius: 30}),
|
||
|
|
autoCollapse: true,
|
||
|
|
autoType: false,
|
||
|
|
minLength: 2,
|
||
|
|
hideMarkerOnCollapse: true,
|
||
|
|
firstTipSubmit: true,
|
||
|
|
});
|
||
|
|
|
||
|
|
map.addControl(searchControl);
|
||
|
|
|
||
|
|
// Draw events
|
||
|
|
map.on('draw:created', function(e) {
|
||
|
|
drawnItems.addLayer(e.layer);
|
||
|
|
$geoFenceField.val(JSON.stringify(drawnItems.toGeoJSON()));
|
||
|
|
});
|
||
|
|
map.on('draw:edited', function(e) {
|
||
|
|
$geoFenceField.val(JSON.stringify(drawnItems.toGeoJSON()));
|
||
|
|
});
|
||
|
|
map.on('draw:deleted', function(e) {
|
||
|
|
e.layers.eachLayer(function(layer) {
|
||
|
|
drawnItems.removeLayer(layer);
|
||
|
|
});
|
||
|
|
$geoFenceField.val(JSON.stringify(drawnItems.toGeoJSON()));
|
||
|
|
});
|
||
|
|
|
||
|
|
// Load existing geoJSON
|
||
|
|
if (dma && dma.geoFence) {
|
||
|
|
L.geoJSON(dma.geoFence, {
|
||
|
|
onEachFeature: function(feature, layer) {
|
||
|
|
drawnItems.addLayer(layer);
|
||
|
|
map.fitBounds(drawnItems.getBounds());
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
window.deleteDmaForm = function(id) {
|
||
|
|
const dma = audienceDmaTable.rows(id).data()[0];
|
||
|
|
bootbox.hideAll();
|
||
|
|
bootbox.confirm({
|
||
|
|
message: '{{ "Are you sure you want to delete this DMA?"|trans }}',
|
||
|
|
buttons: {
|
||
|
|
confirm: {
|
||
|
|
label: '{{ "Yes"|trans }}',
|
||
|
|
className: 'btn-success',
|
||
|
|
},
|
||
|
|
cancel: {
|
||
|
|
label: '{{ "No"|trans }}',
|
||
|
|
className: 'btn-danger',
|
||
|
|
},
|
||
|
|
},
|
||
|
|
callback: function (result) {
|
||
|
|
if (result) {
|
||
|
|
$.ajax({
|
||
|
|
method: 'POST',
|
||
|
|
url: $table.data('proxyUrl').replace(':method', 'dmaDelete') + '?_id=' + dma._id,
|
||
|
|
success: function(xhr) {
|
||
|
|
if (xhr && !xhr.success) {
|
||
|
|
toastr.error(xhr.message);
|
||
|
|
} else {
|
||
|
|
SystemMessage('{{ "DMA deleted"|trans }}', true);
|
||
|
|
}
|
||
|
|
},
|
||
|
|
error: function(xhr, textStatus, errorThrown) {
|
||
|
|
toastr.error(xhr.message);
|
||
|
|
},
|
||
|
|
complete: function() {
|
||
|
|
$('[data-connector-class-name-last="XiboAudienceReportingConnector"]').find('.btn-primary').click();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
$('[data-connector-class-name-last="XiboAudienceReportingConnector"]').find('.btn-primary').click();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
<script type="text/x-handlebars-template" id="xibo-audience-connector-dma-form">
|
||
|
|
<div class="row">
|
||
|
|
<div class="col-md-12">
|
||
|
|
<ul class="nav nav-tabs" role="tablist">
|
||
|
|
<li class="nav-item"><a class="nav-link active" href="#tab-general" role="tab" data-toggle="tab"><span>{% trans "General" %}</span></a></li>
|
||
|
|
<li class="nav-item"><a class="nav-link" href="#tab-dates" role="tab" data-toggle="tab"><span>{% trans "Date/Time" %}</span></a></li>
|
||
|
|
<li class="nav-item"><a class="nav-link" href="#tab-geo" role="tab" data-toggle="tab"><span>{% trans "Geofence" %}</span></a></li>
|
||
|
|
</ul>
|
||
|
|
<form id="{{ random() }}" class="form-horizontal" action="{{ url_for("connector.edit.form.proxy", {id: "{{connectorId}}", method: "{{method}}"}) }}" method="POST">
|
||
|
|
<input type="hidden" name="_id" value="{% verbatim %}{{ dma._id }}{% endverbatim %}">
|
||
|
|
<div class="tab-content">
|
||
|
|
<div class="tab-pane active" id="tab-general">
|
||
|
|
{% set title %}{% trans "Name" %}{% endset %}
|
||
|
|
{% set helpText %}{% trans "The Name of this DMA - (1 - 50 characters)" %}{% endset %}
|
||
|
|
{{ forms.input("name", title, "{{dma.name}}", helpText) }}
|
||
|
|
|
||
|
|
{% set title %}{% trans "Priority" %}{% endset %}
|
||
|
|
{% set helpText %}{% trans "Set a priority for this DMA. Higher priorities take precedence." %}{% endset %}
|
||
|
|
{{ forms.number("priority", title, "{{dma.priority}}", helpText) }}
|
||
|
|
|
||
|
|
{% set title %}{% trans "Display Group" %}{% endset %}
|
||
|
|
{% set helpText %}{% trans "Which displays would you like this DMA to apply to?" %}{% endset %}
|
||
|
|
{% set attributes = [
|
||
|
|
{ name: "data-width", value: "200px" },
|
||
|
|
{ name: "data-allow-clear", value: "true" },
|
||
|
|
{ name: "data-placeholder--id", value: null },
|
||
|
|
{ name: "data-placeholder--value", value: "" },
|
||
|
|
{ name: "data-search-url", value: url_for("displayGroup.search") },
|
||
|
|
{ name: "data-search-term", value: "displayGroup" },
|
||
|
|
{ name: "data-search-term-tags", value: "tags" },
|
||
|
|
{ name: "data-id-property", value: "displayGroupId" },
|
||
|
|
{ name: "data-text-property", value: "displayGroup" },
|
||
|
|
] %}
|
||
|
|
{{ forms.dropdown("displayGroupId", "single", title, null, null, "displayGroupId", "displayGroup", helpText, "pagedSelect", "", "d", "", attributes) }}
|
||
|
|
|
||
|
|
{% set title %}{% trans "Cost per Play" %}{% endset %}
|
||
|
|
{% set helpText %}{% trans "The cost per play" %}{% endset %}
|
||
|
|
{{ forms.input("costPerPlay", title, "{{dma.costPerPlay}}", helpText) }}
|
||
|
|
|
||
|
|
<div class="form-group row">
|
||
|
|
<label class="col-sm-2 control-label" for="field-impression-source">
|
||
|
|
{{ "Impression Source"|trans }}
|
||
|
|
</label>
|
||
|
|
<div class="col-sm-10">
|
||
|
|
<select class="form-control" name="impressionSource" id="field-impression-source">{% verbatim %}
|
||
|
|
{{#each impressionSources}}
|
||
|
|
<option name="{{value}}"{{#eq value dma.impressionSource }} selected{{/eq}}>{{name}}</option>
|
||
|
|
{{/each}}
|
||
|
|
{% endverbatim %}</select>
|
||
|
|
<small class="form-text text-muted">{{ "What is the source of this impression figure?"|trans }}</small>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{% set title %}{% trans "Impressions per play" %}{% endset %}
|
||
|
|
{% set helpText %}{% trans "The impressions per play" %}{% endset %}
|
||
|
|
{{ forms.number("impressionsPerPlay", title, "{{dma.impressionsPerPlay}}", helpText) }}
|
||
|
|
</div>
|
||
|
|
<div class="tab-pane" id="tab-dates">
|
||
|
|
{% set title %}{% trans "Start Date" %}{% endset %}
|
||
|
|
{% set helpText %}{% trans "Select the start date for this DMA" %}{% endset %}
|
||
|
|
{{ forms.date("startDate", title, "{{dma.startDate}}", helpText, "starttime-control", "", "") }}
|
||
|
|
|
||
|
|
{% set title %}{% trans "End Date" %}{% endset %}
|
||
|
|
{% set helpText %}{% trans "Select the end date for this DMA" %}{% endset %}
|
||
|
|
{{ forms.date("endDate", title, "{{dma.endDate}}", helpText, "endtime-control", "", "") }}
|
||
|
|
|
||
|
|
{% set title %}{% trans "Days of the week" %}{% endset %}
|
||
|
|
{% set helpText %}{% trans "Which days of the week should the DMA be active?" %}{% endset %}
|
||
|
|
{% set options = [
|
||
|
|
{ id: 1, name: "Monday"|trans },
|
||
|
|
{ id: 2, name: "Tuesday"|trans },
|
||
|
|
{ id: 3, name: "Wednesday"|trans },
|
||
|
|
{ id: 4, name: "Thursday"|trans },
|
||
|
|
{ id: 5, name: "Friday"|trans },
|
||
|
|
{ id: 6, name: "Saturday"|trans },
|
||
|
|
{ id: 7, name: "Sunday"|trans },
|
||
|
|
] %}
|
||
|
|
{{ forms.dropdown("daysOfWeek[]", "dropdownmulti", title, null, options, "id", "name", helpText) }}
|
||
|
|
|
||
|
|
{% set title %}{% trans "Start Time" %}{% endset %}
|
||
|
|
{% set helpText %}{% trans "Select the start time for this DMA" %}{% endset %}
|
||
|
|
{{ forms.time("startTime", title, "{{dma.startTime}}", helpText, "starttime-control", "", "") }}
|
||
|
|
|
||
|
|
{% set title %}{% trans "End Time" %}{% endset %}
|
||
|
|
{% set helpText %}{% trans "Select the end time for this DMA" %}{% endset %}
|
||
|
|
{{ forms.time("endTime", title, "{{dma.endTime}}", helpText, "endtime-control", "", "") }}
|
||
|
|
</div>
|
||
|
|
<div class="tab-pane" id="tab-geo">
|
||
|
|
{{ forms.hidden("geoFence", "{{dma.geoFence}}") }}
|
||
|
|
|
||
|
|
{{ forms.message("Draw areas on the map where you want this DMA to be active."|trans) }}
|
||
|
|
|
||
|
|
<div id="audience-dma-map"
|
||
|
|
data-map-tile-server="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||
|
|
data-map-lat="{{ settings.DEFAULT_LAT }}"
|
||
|
|
data-map-long="{{ settings.DEFAULT_LONG }}"
|
||
|
|
data-map-zoom="13"
|
||
|
|
style="height: 500px; width: 100%"></div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</form>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</script>
|