-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fb13898
commit 2190ab7
Showing
1 changed file
with
389 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,389 @@ | ||
{% extends "layouts/base.html" %} | ||
|
||
{% block title %} CSV Explorer{% endblock %} | ||
|
||
<!-- Specific Page CSS goes HERE --> | ||
{% block stylesheets %} | ||
<style> | ||
.file-input-wrapper { | ||
display: flex; | ||
align-items: center; | ||
border: 2px solid #4c2588; | ||
border-radius: 0.25em; | ||
padding: 0.5em; | ||
background: linear-gradient(195deg, #6a4ca8 0%, #6a4eaa 100%); | ||
} | ||
|
||
.file-input-wrapper input[type="file"] { | ||
display: none; | ||
} | ||
|
||
.file-input-wrapper label { | ||
color: white; | ||
border: none; | ||
padding: 0.5em 1em; | ||
border-radius: 0.25em; | ||
margin-left: 10px; | ||
width: auto; | ||
white-space: nowrap; | ||
} | ||
|
||
.file-input-wrapper .file-name { | ||
flex-grow: 1; | ||
padding: 0.5em; | ||
background: #dcc4ff; | ||
border: 2px solid #4c2588; | ||
border-radius: 0.25em; | ||
color: #4c2588; | ||
width: calc(100% - 1em - 2px); | ||
} | ||
|
||
.table-wrapper.special-table { | ||
overflow-y: auto; | ||
max-height: 400px; /* Adjust as needed */ | ||
border: 2px solid #4c2588; | ||
border-radius: 0.25em; | ||
background: linear-gradient(195deg, #4c2588 0%, #4c278a 100%) !important; | ||
display: none; | ||
width: 98%; | ||
} | ||
|
||
.special-table table { | ||
width: 100%; | ||
border-collapse: collapse; | ||
} | ||
|
||
.special-table th, .special-table td { | ||
border: 1px solid #4c2588; | ||
padding: 8px; | ||
text-align: left; | ||
} | ||
|
||
.special-table th { | ||
background: linear-gradient(195deg, #4c2588 0%, #4c278a 100%); | ||
color: white; | ||
position: sticky; | ||
top: 0; | ||
z-index: 1; | ||
} | ||
|
||
.special-table tr { | ||
border: 1px solid #4c2588; | ||
} | ||
|
||
.special-table tr:nth-child(even) { | ||
background-color: #dcc4ff !important; | ||
} | ||
|
||
.special-table tr:nth-child(odd) { | ||
background-color: #f3e6ff !important; | ||
} | ||
|
||
.dark-version .file-input-wrapper { | ||
background: linear-gradient(195deg, #2c1a4a 0%, #2c1b4c 100%); | ||
border-color: #2c1a4a; | ||
} | ||
|
||
.dark-version .file-input-wrapper label { | ||
color: #ccc; | ||
} | ||
|
||
.dark-version .file-input-wrapper .file-name { | ||
background: #3c2a6a; | ||
border-color: #2c1a4a; | ||
color: #ccc; | ||
} | ||
|
||
.dark-version .special-table { | ||
background: linear-gradient(195deg, #2c1a4a 0%, #2c1b4c 100%) !important; | ||
border-color: #2c1a4a; | ||
} | ||
|
||
.dark-version .special-table th { | ||
background: linear-gradient(195deg, #2c1a4a 0%, #2c1b4c 100%); | ||
color: #ccc; | ||
} | ||
|
||
.dark-version .special-table tr:nth-child(even) { | ||
background-color: #2c1a4a !important; | ||
} | ||
|
||
.dark-version .special-table tr:nth-child(odd) { | ||
background-color: #3c2a6a !important; | ||
} | ||
|
||
.dark-version .special-table td { | ||
color: #ccc; | ||
} | ||
|
||
/* DataTables custom styles */ | ||
.special-table .dataTables_wrapper, | ||
.special-table .dataTables_scroll, | ||
.special-table .dataTables_scrollHead, | ||
.special-table .dataTables_scrollBody, | ||
.special-table .dataTables_scrollFoot { | ||
background: linear-gradient(195deg, #4c2588 0%, #4c278a 100%) !important; | ||
} | ||
|
||
.special-table .dataTables_length, | ||
.special-table .dataTables_filter, | ||
.special-table .dataTables_info, | ||
.special-table .dataTables_paginate { | ||
margin-top: 0.5em; | ||
margin-bottom: 0.5em; | ||
} | ||
|
||
.special-table .dataTables_length, | ||
.special-table .dataTables_info { | ||
margin-left: 0.5em; | ||
} | ||
|
||
.special-table .dataTables_filter, | ||
.special-table .dataTables_paginate { | ||
margin-right: 0.5em; | ||
} | ||
|
||
.special-table .dataTables_length label, | ||
.special-table .dataTables_filter label, | ||
.special-table .dataTables_info{ | ||
color: white !important; | ||
} | ||
|
||
.special-table .dataTables_length select, | ||
.special-table .dataTables_filter input { | ||
color: black; | ||
background-color: white !important; | ||
margin-left: 0.5em !important; | ||
margin-right: 0.5em !important; | ||
} | ||
|
||
.special-table .dataTables_wrapper .dataTables_paginate .paginate_button { | ||
color: white !important; | ||
} | ||
|
||
.dark-version .special-table .dataTables_wrapper, | ||
.dark-version .special-table .dataTables_scrollBody { | ||
background: linear-gradient(195deg, #2c1a4a 0%, #2c1b4c 100%) !important; | ||
} | ||
|
||
.dark-version .special-table .dataTables_paginate .paginate_button { | ||
color: white !important; | ||
} | ||
|
||
.image-cell { | ||
width: 80px; | ||
height: auto; | ||
float: center; | ||
margin-top: 10px; | ||
margin-bottom: 10px; | ||
} | ||
</style> | ||
{% endblock stylesheets %} | ||
|
||
{% block content %} | ||
|
||
<div class="container-fluid py-4"></div> | ||
<div class="row min-vh-80 h-100"> | ||
<div class="col-12"> | ||
<form method="POST" action="/tools_channelsclients" id="process-form"> | ||
<!-- List of Channels DCT Clients --> | ||
<table style="width: 95%;"> | ||
<tr> | ||
<td style="width: 20%;"> | ||
<h4 style="margin: 0;">List of Channels DVR Clients</h4> | ||
</td> | ||
<td style="width: 75%; text-align: center;"> | ||
<button class="btn bg-gradient-primary my-2 mb-2" type="button" data-bs-toggle="collapse" data-bs-target="#channelsclientsPanel" aria-expanded="true" aria-controls="channelsclientsPanel" style="width: 100%;"> | ||
Expand / Collapse | ||
</button> | ||
</td> | ||
</tr> | ||
</table> | ||
<div class="collapse" id="channelsclientsPanel"> | ||
<div class="content-placeholder"> | ||
{% if html_csv_channels_clients %} | ||
<div class="table-wrapper special-table"> | ||
<table id="myTable" class="display"> | ||
{{ html_csv_channels_clients|safe }} | ||
</table> | ||
</div> | ||
{% endif %} | ||
</div> | ||
</div> | ||
<hr> | ||
<!-- Select Local Client --> | ||
<div class="row min-vh-10 h-100 justify-content-center"> | ||
<div style="width: 95%;"> | ||
<div class="file-input-wrapper w-100 h-15 my-2 mb-2"> | ||
<label for="local_channels_client_selected" style="margin-top: 8px; width: calc(15%);"><b>Select Client (Local Only):</b></label> | ||
<select class="select2" name="local_channels_client_selected" id="local_channels_client_selected" style="width: calc(100%);"> | ||
{% for html_local_channels_client in html_local_channels_clients %} | ||
<option value="{{ html_local_channels_client['Client ID'] }}" {% if html_local_channels_client['Client ID'] == html_local_channels_client_selected %}selected{% endif %} style="width: auto; min-width: 100%;">{{ html_local_channels_client.Hostname }}</option> | ||
{% endfor %} | ||
</select> | ||
<button type="submit" name="action" value="client_non_api_get_log" class="btn bg-gradient-primary w-20 h-15 my-2 mb-2" style="margin-left: 10px;">View Log</button> | ||
<button type="submit" name="action" value="client_cancel" class="btn bg-gradient-primary w-20 h-15 my-2 mb-2" style="margin-left: 10px;">Clear / Cancel</button> | ||
</div> | ||
<div class="file-input-wrapper w-100 h-15 my-2 mb-2"> | ||
<label for="local_channels_client_notify_title" style="margin-top: 8px;"><b>Title:</b></label> | ||
<input type="text" id="local_channels_client_notify_title" name="local_channels_client_notify_title" placeholder="i.e., Arrived Home" value="{{ html_local_channels_client_notify_title }}" class="w-20"> | ||
<label for="local_channels_client_notify_message" style="margin-top: 8px;"><b>Message:</b></label> | ||
<input type="text" id="local_channels_client_notify_message" name="local_channels_client_notify_message" placeholder="i.e., Jon has arrived home" value="{{ html_local_channels_client_notify_message }}" class="w-50"> | ||
<label for="local_channels_client_notify_timeout" style="margin-top: 8px;"><b>Display For:</b></label> | ||
<input type="text" id="local_channels_client_notify_timeout" name="local_channels_client_notify_timeout" placeholder="In seconds, i.e., 30" value="{{ html_local_channels_client_notify_timeout }}" class="w-10"> | ||
<button type="submit" name="action" value="client_api_post_notify" class="btn bg-gradient-primary w-20 h-15 my-2 mb-2" style="margin-left: 10px;">Send Notification</button> | ||
</div> | ||
</div> | ||
</div> | ||
<!-- Messages --> | ||
{% if html_tools_channelsclients_message %} | ||
<hr> | ||
<div id="html_tools_channelsclients_message">{{ html_tools_channelsclients_message }}</div> | ||
{% endif %} | ||
<!-- Logs --> | ||
{% if html_client_log %} | ||
<hr> | ||
<pre style="white-space: pre; overflow-x: auto; border: 1px solid #ccc; padding: 10px; height: 400px; overflow-y: scroll; width: 98%;"> | ||
{%- for line in html_client_log %} | ||
{{ line }} | ||
{%- endfor %} | ||
</pre> | ||
{% endif %} | ||
</form> | ||
</div> | ||
</div> | ||
<div class="modal fade" id="loadingModal" tabindex="-1" aria-labelledby="loadingModalLabel" aria-hidden="true"> | ||
<div class="modal-dialog modal-dialog-centered"> | ||
<div class="modal-content"> | ||
<div class="modal-header"> | ||
<h5 class="modal-title" id="loadingModalLabel">Processing</h5> | ||
</div> | ||
<div class="modal-body"> | ||
Please wait while the process completes... | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
{% include 'includes/footer.html' %} | ||
|
||
</div> | ||
|
||
{% endblock content %} | ||
|
||
<!-- Specific Page JS goes HERE --> | ||
{% block javascripts %} | ||
<!-- Processing Box --> | ||
<script> | ||
document.addEventListener('DOMContentLoaded', function() { | ||
document.getElementById('process-form').addEventListener('submit', function(event) { | ||
console.log("Form submitted"); // Debugging | ||
|
||
// Wait for a short delay to ensure the form submission is not blocked | ||
setTimeout(() => { | ||
// Ensure the modal element exists | ||
const modalElement = document.getElementById('loadingModal'); | ||
if (!modalElement) { | ||
console.error('Modal element not found!'); | ||
return; | ||
} | ||
|
||
// Show the modal | ||
const loadingModal = new bootstrap.Modal(modalElement, { | ||
backdrop: 'static', | ||
keyboard: false | ||
}); | ||
console.log("Showing modal"); // Debugging | ||
loadingModal.show(); | ||
|
||
// Disable all navigation links | ||
document.querySelectorAll('a').forEach(element => { | ||
element.setAttribute('disabled', 'true'); | ||
element.addEventListener('click', function(event) { | ||
event.preventDefault(); | ||
}); | ||
}); | ||
}, 500); // Adjust the delay as needed | ||
}); | ||
}); | ||
</script> | ||
<!-- Build Table --> | ||
<script> | ||
$(document).ready(function() { | ||
console.log("Document ready"); | ||
|
||
// Extract column headers dynamically | ||
var columnHeaders = []; | ||
$('#myTable thead th').each(function() { | ||
columnHeaders.push({ "data": $(this).text().trim() }); | ||
}); | ||
|
||
console.log("Column headers:", columnHeaders); | ||
|
||
// Initialize DataTables with dynamic columns and disable sorting | ||
var table = $('#myTable').DataTable({ | ||
"columns": columnHeaders, | ||
"ordering": false, // Disable sorting | ||
"createdRow": function(row, data, dataIndex) { | ||
}, | ||
"initComplete": function(settings, json) { | ||
// Show the table once DataTables is initialized | ||
$('.table-wrapper').show(); | ||
} | ||
}); | ||
|
||
console.log("DataTable initialized"); | ||
|
||
// Apply the search | ||
$('#myTable thead').on('keyup change', '.filter-input', function() { | ||
var columnIndex = $(this).parent().index(); | ||
console.log("Filtering column: " + columnIndex + " with value: " + this.value); | ||
table.column(columnIndex).search(this.value).draw(); | ||
}); | ||
}); | ||
</script> | ||
<!-- Remember Expand / Collapsed Status--> | ||
<script> | ||
document.addEventListener("DOMContentLoaded", function() { | ||
function applyCollapseState(sectionId) { | ||
var section = document.getElementById(sectionId); | ||
var isExpanded = localStorage.getItem(sectionId + '_expanded') === 'true'; | ||
if (isExpanded) { | ||
section.classList.add('show'); | ||
loadContent(sectionId); // Load content if initially expanded | ||
} | ||
} | ||
|
||
function saveCollapseState(sectionId) { | ||
var section = document.getElementById(sectionId); | ||
var isExpanded = section.classList.contains('show'); | ||
localStorage.setItem(sectionId + '_expanded', isExpanded); | ||
} | ||
|
||
function loadContent(sectionId) { | ||
var contentElement = document.getElementById(sectionId); | ||
var contentPlaceholder = contentElement.querySelector('.content-placeholder'); | ||
|
||
if (contentPlaceholder && contentPlaceholder.innerHTML.trim() === '') { | ||
fetch('/get-content?section=' + sectionId) | ||
.then(response => response.text()) | ||
.then(data => { | ||
contentPlaceholder.innerHTML = data; | ||
}) | ||
.catch(error => console.error('Error loading content:', error)); | ||
} | ||
} | ||
|
||
applyCollapseState('channelsclientsPanel'); | ||
|
||
['shown.bs.collapse', 'hidden.bs.collapse'].forEach(eventName => { | ||
document.getElementById('channelsclientsPanel').addEventListener(eventName, function() { | ||
saveCollapseState('channelsclientsPanel'); | ||
if (eventName === 'shown.bs.collapse') { | ||
loadContent('channelsclientsPanel'); | ||
} | ||
}); | ||
}); | ||
}); | ||
</script> | ||
{% endblock javascripts %} |