374 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			374 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | ||
| <html lang="en">
 | ||
| <head>
 | ||
|     <meta charset="UTF-8">
 | ||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | ||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | ||
|     <title>Отчёты</title>
 | ||
|     <link rel="stylesheet" href="../styles/main.css" />
 | ||
| </head>
 | ||
| <body>
 | ||
| 
 | ||
|     <header>
 | ||
|         <img src="../img/argus.png">
 | ||
|         <h1>Аргус</h1>
 | ||
|         <h2><span>/</span> {{Organisation}}</h2>
 | ||
|     </header>
 | ||
| 
 | ||
|     <section class="account-info">
 | ||
|       <div id="account-main">
 | ||
|           <img id="person" src="../img/person.svg">
 | ||
|           <span>{{User}}</span>
 | ||
|           <img id="down" src="../img/down.svg">
 | ||
|           <img id="up" src="../img/up.svg">
 | ||
|       </div>
 | ||
|       <a href="/logout"><div id="account-additional" class="additional">Выйти</div></a>
 | ||
|   </section>
 | ||
| 
 | ||
|     
 | ||
| 
 | ||
| 
 | ||
|     <section class="navigation">
 | ||
|         <a href="/">
 | ||
|             <div><img src="../img/chart.svg">Главная</div>
 | ||
|         </a>
 | ||
|         <a href="/devices">
 | ||
|             <div><img src="../img/cloud.svg">Устройства</div>
 | ||
|         </a>
 | ||
|         <a href="/reports">
 | ||
|             <div class="selected"><img src="../img/bubble.svg">Отчёты</div>
 | ||
|         </a>
 | ||
|         <a href="/live">
 | ||
|             <div><img src="../img/waves.svg">Трансляция</div>
 | ||
|         </a>
 | ||
|         <a href="/videos">
 | ||
|             <div><img src="../img/play.svg">Записи</div>
 | ||
|         </a>
 | ||
|         <a href="https://forms.yandex.ru/cloud/6515ecda3e9d08f17262c332/" target="_blank">
 | ||
|           <div><img src="../img/bug.svg">Собщить об ошибке</div>
 | ||
|       </a>
 | ||
|         {{#if isAdmin}}
 | ||
|         <a class="admin-panel" href="/admin">
 | ||
|             <div><img src="../img/keyboard.svg">Админка</div>
 | ||
|         </a>
 | ||
|         {{/if}}
 | ||
|         <a class="settings" href="/settings">
 | ||
|             <div><img src="../img/gear.svg">Настройки</div>
 | ||
|         </a>
 | ||
|     </section>
 | ||
| 
 | ||
|     <section class="main">
 | ||
|       {{#if ifDBError}}
 | ||
|       <section class="dberror">
 | ||
|         <div class="erorr-container">
 | ||
|           <img src="../img/warning.svg"> <br>
 | ||
|           <h1>Ошибка </h1> <br>
 | ||
|           <span>Не удалось получить данные из БД</span>
 | ||
|           <button type="button" onclick="location.reload();">Повторить попытку</button>
 | ||
|         </div>
 | ||
|       </section>
 | ||
|       {{/if}}
 | ||
|         <nav>
 | ||
|             <a class="selected" href="/reports">Предупреждения</a>
 | ||
|         </nav>
 | ||
|         <section class="bg">
 | ||
|             <section class="content">
 | ||
| 
 | ||
|                 <section style="height: 945px !important;" class="for-table">
 | ||
| 
 | ||
|                     <section class="organisation">
 | ||
|                         <h1>Организация</h1>
 | ||
| 
 | ||
|                         <ul class="area">
 | ||
|                           {{#each Groups}}
 | ||
|                           <li class="area-name"><img src="../img/ul.svg"><input autocomplete="off" type="checkbox" id="{{name}}" class="checkbox-input" onchange="requestUpdate()" hidden checked><label for="{{name}}" class="checkbox-label checkbox-name"><span class="text">{{name}}</span></label>
 | ||
|                               <ul class="area-devices" id="devices-1">
 | ||
|                                   {{#each serials}}
 | ||
|                                   <li class="device"><img><input autocomplete="off" type="checkbox" id="{{this}}" class="checkbox-input device-filter" value="{{this}}" onchange="requestUpdate()" hidden checked><label for="{{this}}" class="checkbox-label">
 | ||
|                                       {{#if ../numbers}}
 | ||
|                                           {{#if (lookup ../numbers @index)}}
 | ||
|                                               <div class="checkmark"></div>{{lookup ../numbers @index}}
 | ||
|                                           {{else}}
 | ||
|                                               <div class="checkmark"></div>{{this}}
 | ||
|                                           {{/if}}
 | ||
|                                       {{else}}
 | ||
|                                           <div class="checkmark"></div>{{this}}
 | ||
|                                       {{/if}}
 | ||
|                                   </label></li>
 | ||
|                                   {{/each}}
 | ||
|                               </ul>
 | ||
|                           </li>
 | ||
|                           {{/each}}
 | ||
|                           </ul>
 | ||
| 
 | ||
|                         <div class="area-time-range">
 | ||
|                           <div class="time-range"><label for="timeRangeStart">с</label><input autocomplete="off" id="timeRangeStart" name="timeRangeStart" onblur="requestUpdate()" type="datetime-local"></div>
 | ||
|                           <div class="time-range"><label for="timeRangeEnd">до</label><input autocomplete="off" id="timeRangeEnd" name="timeRangeEnd" onblur="requestUpdate()" type="datetime-local"></div>
 | ||
|                         </div>
 | ||
|                           
 | ||
|                     </section>
 | ||
| 
 | ||
|                 
 | ||
| 
 | ||
|                     <section id="table-area" class="table">
 | ||
|                         <h1>Список предупреждений</h1>
 | ||
|                         <input autocomplete="off" id="table-search" class="search" type="text" onblur="requestUpdate()" placeholder="Поиск">
 | ||
| 
 | ||
| 
 | ||
|                           <table id="deviceTable">
 | ||
|                             <thead>
 | ||
|                               <tr>
 | ||
|                                 <th>Наименование</th>
 | ||
|                                 <th>ID</th>
 | ||
|                                 <th>Номерной знак</th>
 | ||
|                                 <th>Серийный номер</th>
 | ||
|                                 <th>Время</th>
 | ||
|                                 <th>Местоположение</th>
 | ||
|                                 <th></th>
 | ||
|                               </tr>
 | ||
|                             </thead>
 | ||
|                             <tbody>
 | ||
|                               <!-- Сюда будут добавляться строки таблицы -->
 | ||
|                             </tbody>
 | ||
|                           </table>
 | ||
| 
 | ||
| 
 | ||
|                     </section>
 | ||
| 
 | ||
|                       <div id="count">Всего результатов: <span id="count-value">{{Count}}</span></div>
 | ||
|                     <div id="pagination">
 | ||
|                       <svg id="left-slider" xmlns="http://www.w3.org/2000/svg" width="11" height="19" fill="none" viewBox="0 0 11 19" onclick="decrementPage()">
 | ||
|                         <path fill="#000" fill-opacity=".75" d="M0 9.495c0 .273.101.514.315.722l8.92 8.477a.981.981 0 0 0 .73.295c.585 0 1.035-.427 1.035-.995 0-.285-.124-.525-.304-.711L2.508 9.495l8.188-7.789c.18-.186.304-.437.304-.71C11 .425 10.55 0 9.965 0c-.292 0-.54.098-.73.284L.314 8.773A.955.955 0 0 0 0 9.495Z"/>
 | ||
|                       </svg>
 | ||
|                       <input autocomplete="off" id="page-number" type="number" onblur="requestUpdate()" value="1">
 | ||
|                       <svg id="right-slider" xmlns="http://www.w3.org/2000/svg" width="11" height="19" fill="none" viewBox="0 0 11 19" onclick="incrementPage()">
 | ||
|                         <path fill="#000" fill-opacity=".75" d="M11 9.495a.967.967 0 0 0-.326-.722L1.766.284A1.062 1.062 0 0 0 1.024 0C.45 0 0 .427 0 .995c0 .274.112.525.292.711l8.189 7.789-8.189 7.788c-.18.186-.292.426-.292.71 0 .57.45.996 1.024.996.292 0 .54-.098.742-.295l8.908-8.477c.213-.208.326-.449.326-.722Z"/>
 | ||
|                       </svg>
 | ||
|                       </div>
 | ||
| 
 | ||
|                       <script>
 | ||
|                         var pageNumberInput = document.getElementById('page-number');
 | ||
|                         var countMax = Math.ceil({{Count}} / 14); 
 | ||
|                     
 | ||
|                         function decrementPage() {
 | ||
|                             var currentPage = parseInt(pageNumberInput.value, 10);
 | ||
|                             if (currentPage > 1) {
 | ||
|                                 pageNumberInput.value = currentPage - 1;
 | ||
|                                 requestUpdate();
 | ||
|                             }
 | ||
|                         }
 | ||
|                     
 | ||
|                         function incrementPage() {
 | ||
|                             var currentPage = parseInt(pageNumberInput.value, 10);
 | ||
|                             if (currentPage === countMax || currentPage > countMax) {
 | ||
|                                 pageNumberInput.value = countMax;
 | ||
|                                 requestUpdate();
 | ||
|                             }
 | ||
|                             if (currentPage < countMax) {
 | ||
|                                 pageNumberInput.value = currentPage + 1;
 | ||
|                                 requestUpdate();
 | ||
|                             }
 | ||
|                         }
 | ||
|                     </script>
 | ||
| 
 | ||
|                       <!-- <br>
 | ||
|                       <br>
 | ||
|                       <span style="opacity:50%">Временное ограничение: 100 последних предупреждений</span> -->
 | ||
|                       
 | ||
|                       
 | ||
| 
 | ||
|                 </section>
 | ||
| 
 | ||
|             </section>
 | ||
|         </section>
 | ||
|     </section>
 | ||
| 
 | ||
|     <script>
 | ||
|       let devices = [
 | ||
|   {{#each Alarms}}
 | ||
|   {
 | ||
|     id: "{{this.id}}",
 | ||
|     cmdno: "{{this.cmdno}}",
 | ||
|     number: "{{this.number}}",
 | ||
|     time: "{{this.time}}",
 | ||
|     serial: "{{this.serial}}",
 | ||
|     type: "{{this.type}}",
 | ||
|     geo: "{{this.geo}}",
 | ||
|     plate: "{{this.plate}}",
 | ||
|   },
 | ||
|   {{/each}}
 | ||
| ];
 | ||
|     </script>
 | ||
| 
 | ||
|     <script src="../scripts/table-reports.js"></script>
 | ||
|     <script src="../scripts/jquery.min.js"></script>
 | ||
| 
 | ||
|     <script>
 | ||
| 
 | ||
|   document.addEventListener('DOMContentLoaded', function () {
 | ||
|           var containers = document.querySelectorAll('.checkbox-name');
 | ||
|   
 | ||
|           containers.forEach(function (container) {
 | ||
|               var text = container.querySelector('.text');
 | ||
|   
 | ||
|               if (text.clientWidth > container.clientWidth) {
 | ||
|                   text.classList.add('animated');
 | ||
|               }
 | ||
|           });
 | ||
|       });
 | ||
| 
 | ||
|       document.addEventListener('DOMContentLoaded', function () {
 | ||
|             var checkboxLabels = document.querySelectorAll('.checkbox-label');
 | ||
| 
 | ||
|             checkboxLabels.forEach(function (label) {
 | ||
|                 var labelText = label.textContent.trim();
 | ||
| 
 | ||
|                 if (labelText.length > 10) {
 | ||
|                     var checkmarkDiv = document.createElement('div');
 | ||
|                     checkmarkDiv.className = 'checkmark';
 | ||
| 
 | ||
|                     label.textContent = '';
 | ||
|                     label.appendChild(checkmarkDiv);
 | ||
|                     label.appendChild(document.createTextNode(labelText.slice(0, 9) + '...'));
 | ||
|                 }
 | ||
|             });
 | ||
|         });
 | ||
|       
 | ||
|         </script>
 | ||
| 
 | ||
|         <script>
 | ||
| 
 | ||
|           function requestUpdate() {
 | ||
| 
 | ||
|             document.getElementById("deviceTable").style.filter = "brightness(0.85)";
 | ||
| 
 | ||
|                   const requestData = {
 | ||
|                     page: parseInt(document.getElementById("page-number").value),
 | ||
|                     timeRangeStart: document.getElementById("timeRangeStart").value, 
 | ||
|                     timeRangeEnd: document.getElementById("timeRangeEnd").value, 
 | ||
|                     serials: Array.from(
 | ||
|                               document.querySelectorAll('input[type="checkbox"].device-filter:checked')
 | ||
|                             ).map((checkbox) => checkbox.value),
 | ||
|                     searchText: document.getElementById("table-search").value,
 | ||
|                   };
 | ||
| 
 | ||
|                   console.log(requestData);
 | ||
| 
 | ||
|                   
 | ||
| 
 | ||
|           fetch("/getreports", {
 | ||
|                     method: "POST",
 | ||
|                     headers: {
 | ||
|                       "Content-Type": "application/json",
 | ||
|                     },
 | ||
|                     body: JSON.stringify(requestData),
 | ||
|                   })
 | ||
|                     .then((response) => response.json())
 | ||
|                     .then((data) => {
 | ||
| 
 | ||
| 
 | ||
|                       console.log(data);
 | ||
|                       console.log(devices);
 | ||
| 
 | ||
|                       devices.splice(0, devices.length);
 | ||
| 
 | ||
|                       devices.push(...data.data.map(item => ({
 | ||
|                         id: item.id,
 | ||
|                         cmdno: item.cmdno,
 | ||
|                         number: item.number,
 | ||
|                         time: item.time,
 | ||
|                         serial: item.serial,
 | ||
|                         type: item.type,
 | ||
|                         geo: item.geo,
 | ||
|                         plate: item.plate,
 | ||
|                       })));
 | ||
| 
 | ||
|                       console.log(devices);
 | ||
|                       createTable();
 | ||
| 
 | ||
|                       document.getElementById("count-value").innerHTML = data.total;
 | ||
| 
 | ||
|                       countMax = Math.ceil(data.total / 14);
 | ||
| 
 | ||
|                       var currentPage = parseInt(pageNumberInput.value, 10);
 | ||
|                       if (currentPage > countMax) {
 | ||
|                         pageNumberInput.value = countMax;
 | ||
|                         requestUpdate();
 | ||
|                       }
 | ||
| 
 | ||
|                       document.getElementById("deviceTable").style.filter = "brightness(1)";
 | ||
|                       
 | ||
| 
 | ||
|                     })
 | ||
|                     .catch((error) => {
 | ||
|                       document.getElementById("dataLoading").style.display = 'none';
 | ||
|                         h1Element.textContent = 'Ошибка отправки запроса.';
 | ||
|                       console.error("Ошибка при отправке запроса:", error);
 | ||
|                     });
 | ||
|           };
 | ||
|         </script>
 | ||
|     <script>
 | ||
|         // Скрытие/Показ дополнительных меню аккаунта
 | ||
|         const accountMain = document.getElementById('account-main');
 | ||
|         const accountAdditional = document.getElementById('account-additional');
 | ||
|         const accountUp = document.getElementById('up');
 | ||
|         const accountDown = document.getElementById('down');
 | ||
|         accountAdditional.style.display = 'none';
 | ||
|         accountUp.style.display = 'none';
 | ||
|         
 | ||
|         accountMain.addEventListener('click', () => {
 | ||
|           if (accountAdditional.style.display === 'none') {
 | ||
|             accountAdditional.style.display = 'flex';
 | ||
|             accountUp.style.display = 'unset';
 | ||
|             accountDown.style.display = 'none';
 | ||
|           } else {
 | ||
|             accountAdditional.style.display = 'none';
 | ||
|             accountUp.style.display = 'none';
 | ||
|             accountDown.style.display = 'unset';
 | ||
|           }
 | ||
|         });
 | ||
|       </script>
 | ||
| 
 | ||
|       <script>
 | ||
|         const checkboxes = document.querySelectorAll('.organisation .checkbox-input');
 | ||
| 
 | ||
| checkboxes.forEach((checkbox) => {
 | ||
|   checkbox.addEventListener('change', function() {
 | ||
|     
 | ||
|     const areaDevices = this.parentNode.querySelector('.area-devices');
 | ||
|     if (this.checked) {
 | ||
|       areaDevices.style.display = 'block';
 | ||
| 
 | ||
|       // Активируем дочерние чекбоксы
 | ||
|       const childCheckboxes = areaDevices.querySelectorAll('.device-filter');
 | ||
|       childCheckboxes.forEach((childCheckbox) => {
 | ||
|         childCheckbox.checked = true;
 | ||
|       });
 | ||
|     } else {
 | ||
|       areaDevices.style.display = 'none';
 | ||
| 
 | ||
|       // Деактивируем дочерние чекбоксы
 | ||
|       const childCheckboxes = areaDevices.querySelectorAll('.device-filter');
 | ||
|       childCheckboxes.forEach((childCheckbox) => {
 | ||
|         childCheckbox.checked = false;
 | ||
|       });
 | ||
|     }
 | ||
| 
 | ||
|     // Деактивируем дочерние чекбоксы, если родительский чекбокс не выбран
 | ||
|     if (!this.checked) {
 | ||
|       const childCheckboxes = areaDevices.querySelectorAll('.device-filter');
 | ||
|       childCheckboxes.forEach((childCheckbox) => {
 | ||
|         childCheckbox.checked = false;
 | ||
|       });
 | ||
|       areaDevices.style.display = 'none';
 | ||
|     }
 | ||
| 
 | ||
|     requestUpdate();
 | ||
|   });
 | ||
| });
 | ||
| 
 | ||
|       </script>
 | ||
|       
 | ||
|     
 | ||
| </body>
 | ||
| </html> |