Files
Cloud-CMS/views/notification-page.twig

284 lines
10 KiB
Twig
Raw Permalink Normal View History

2025-12-02 10:32:59 -05:00
{#
/**
* Copyright (C) 2024 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
* 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 %}{{ "Notification Centre"|trans }} | {% endblock %}
{% block actionMenu %}
<div class="widget-action-menu pull-right">
{% if currentUser.featureEnabled("notification.add") %}
<button class="btn btn-success XiboFormButton" href="{{ url_for("notification.add.form") }}"><i class="fa fa-plus-circle" aria-hidden="true"></i> {% trans "Add Notification" %}</button>
{% endif %}
<button class="btn btn-primary" id="refreshGrid" title="{% trans "Refresh the Table" %}" href="#"><i class="fa fa-refresh" aria-hidden="true"></i></button>
</div>
{% endblock %}
{% block pageContent %}
<div class="widget">
<div class="widget-title">{% trans "Notification Centre" %}</div>
<div class="widget-body">
<div class="XiboGrid" id="{{ random() }}" data-grid-name="notificationView">
<div class="XiboFilter card mb-3 bg-light">
<div class="FilterDiv card-body" id="Filter">
<form class="form-inline">
{% set title %}{% trans "Status" %}{% endset %}
{% set option1 = "My Read"|trans %}
{% set option2 = "My Unread"|trans %}
{% set option3 = "All"|trans %}
{% set values = [{id: 1, value: option1}, {id: 0, value: option2}] %}
{% if currentUser.isSuperAdmin() %}
{% set values = values|merge([{id:null, value:option3}]) %}
{% endif %}
{{ inline.dropdown("read", "single", title, 0, values, "id", "value") }}
{% set options = [
{ optionid: "", option: "All" },
{ optionid: "custom", option: "Custom"|trans },
{ optionid: "dataset", option: "DataSet"|trans },
{ optionid: "display", option: "Display"|trans },
{ optionid: "layout", option: "Layout"|trans },
{ optionid: "library", option: "Library"|trans },
{ optionid: "report", option: "Report"|trans },
{ optionid: "schedule", option: "Schedule"|trans },
] %}
{% set title %}{% trans "Type" %}{% endset %}
{{ inline.dropdown("type", "single", title, "", options, "optionid", "option", helpText) }}
{% set title %}{% trans "Date" %}{% endset %}
{{ inline.dateTime("releaseDt", title, "", helpText, "", "") }}
</form>
</div>
</div>
<div class="XiboData card pt-3">
<table id="notifications" class="table table-striped" data-state-preference-name="notificationGrid">
<thead>
<tr>
<th>{% trans "Subject" %}</th>
<th>{% trans "Type" %}</th>
<th>{% trans "Date" %}</th>
<th>{% trans "Interrupt?" %}</th>
<th class="rowMenu"></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock %}
{% block javaScript %}
<script type="text/javascript" nonce="{{ cspNonce }}">
$(function() {
var table = $("#notifications").DataTable({
language: dataTablesLanguage,
dom: dataTablesTemplate,
serverSide: true,
stateSave: true,
stateDuration: 0,
responsive: true,
stateLoadCallback: dataTableStateLoadCallback,
stateSaveCallback: dataTableStateSaveCallback,
filter: false,
searchDelay: 3000,
order: [[ 1, 'desc']],
ajax: {
url: "{{ url_for('notification.search') }}",
data: function(d) {
$.extend(d, $('#notifications').closest('.XiboGrid').find('.FilterDiv form').serializeObject());
}
},
columns: [
{
data: 'subject',
responsivePriority: 2
},
{
data: 'type',
responsivePriority: 2
},
{
data: 'releaseDt',
responsivePriority: 2,
render: dataTableDateFromUnix
},
{
data: 'isInterrupt',
responsivePriority: 3,
render: dataTableTickCrossColumn
},
{
orderable: false,
responsivePriority : 1,
data: dataTableButtonsColumn
}
]
});
table.on('draw', dataTableDraw);
table.on('processing.dt', dataTableProcessing);
dataTableAddButtons(table, $('#notifications_wrapper').find('.dataTables_buttons'));
$("#refreshGrid").click(function () {
table.ajax.reload();
});
const notificationShow = _.debounce(function() {
const data = table.row($(this)).data();
let showUrl = "{{ url_for('notification.show', {id: ':rowId'}) }}".replace(':rowId', data.notificationId);
XiboFormRender(showUrl);
}, 500);
$("#notifications tbody").on('dblclick', 'tr', notificationShow);
});
var attachmentFormSubmit = function(dialog) {
var form = $(dialog);
// Update any text editor instances we have
for(var editor in formHelpers.ckEditorInstances) {
formHelpers.updateCKEditor(
formHelpers.ckEditorInstances[editor].id,
);
}
// Submit via ajax - change the attachment color on success
$.ajax({
type: form.attr("method"),
url: form.attr("action"),
cache: false,
dataType: "json",
data: $(form).serialize(),
success: function(xhr, textStatus, error) {
XiboSubmitResponse(xhr, form);
if (xhr.success) {
console.debug('success');
}
},
error: function(xhr, textStatus, errorThrown) {
SystemMessage(xhr.responseText, false);
}
});
}
var attachmentFormSetup = function(dialog) {
// Conjure up a text editor
formHelpers.createCKEditor('notificationMessage', $('#body')).then((editor) => {
// Update text area when unfocusing editor
editor.ui.focusTracker.on('change:isFocused', (evt, name, isFocused ) => {
if (!isFocused) {
// Update editor
formHelpers.updateCKEditor('notificationMessage');
}
});
});
// Make sure when we close the dialog we also destroy the editor
dialog.on("hide.bs.modal", function(event) {
if ($(event.target).hasClass('bootbox')) {
formHelpers.destroyCKEditor('notificationMessage');
}
});
var attachmentImageList = $('#attachmentImageId');
var attachmentChanged = false;
// Bind to the attachment add button click
$("#attachmentAddButton").on("click", function(e) {
notificationAddFormAttachmentButtonClicked(e, dialog);
});
// Validate form
forms.validateForm(
dialog.find('#notificationForm'), // form
dialog, // container
{
submitHandler: attachmentFormSubmit,
},
);
};
/**
* Add notification attachment add image button
* @param e the event
* @param dialog the dialog
*/
function notificationAddFormAttachmentButtonClicked(e, dialog) {
e.preventDefault();
// Open an upload form
var upload = openUploadForm({
url: "{{ url_for("notification.addattachment") }}",
title: "{% trans "Browse/Add attachment" %}",
videoImageCovers: false,
animateDialog: false,
className: "second-dialog",
buttons: {
main: {
label: "{% trans "Done" %}",
className: "btn-primary btn-bb-main",
callback: function () {
upload.modal('hide');
}
}
},
templateOptions: {
multi: false,
trans: {
addFiles: "{% trans "Browse/Add Attachment" %}",
startUpload: "{% trans "Start Upload" %}",
cancelUpload: "{% trans "Cancel Upload" %}"
},
upload: {
maxSize: {{ libraryUpload.maxSize }},
maxSizeMessage: "{{ libraryUpload.maxSizeMessage }}",
validExt: "jpg|jpeg|png|bmp|gif|zip|pdf"
},
folderSelector: false
},
uploadDoneEvent: function (data) {
// Get the attachment filename
var filename = data.result.files[0].name;
dialog.find("input[name='attachedFilename']").remove();
// Create a hidden field with the filename
$("#notificationForm").append($("<input type='hidden' name='attachedFilename' value='" + filename + "'/>"));
// Close
upload.modal('hide');
}
});
}
</script>
{# CKEDITOR #}
<script src="{{ theme.rootUri() }}dist/wysiwygEditor.bundle.min.js?v={{ version }}&rev={{revision}}" nonce="{{ cspNonce }}"></script>
{% endblock %}