search and sort

main
Satur@it-depot.ru 2025-03-05 09:35:23 +03:00
parent 813bead6e5
commit 715961b425
1 changed files with 65 additions and 42 deletions

View File

@ -9,12 +9,18 @@
<style>
body { display: flex; font-family: Arial, sans-serif; }
#tree-container { width: 30%; padding: 10px; border-right: 1px solid #ccc; }
#installs-container { width: 70%; padding: 10px; }
#installs-container { width: 70%; padding: 10px; position: relative; }
.install-item { padding: 5px; margin: 2px; border: 1px solid #ddd; cursor: move; }
.form-container { margin-bottom: 20px; }
.jstree-node { position: relative; }
.folder-actions { display: inline; margin-left: 10px; }
#search-input, #sort-select { margin-bottom: 10px; width: 200px; }
#search-container { position: absolute; top: 10px; right: 10px; text-align: right; }
#search-input { width: 200px; }
#installs-list { margin-top: 20px; }
.header { display: flex; justify-content: space-between; font-weight: bold; padding: 5px; background: #f0f0f0; cursor: pointer; }
.header div { flex: 1; text-align: center; }
.header div:hover { background: #e0e0e0; }
.sort-arrow { font-size: 12px; margin-left: 5px; }
</style>
</head>
<body>
@ -25,6 +31,15 @@
</div>
<div id="installs-container">
<h1>Органайзер RustDesk</h1>
<div id="search-container">
<input type="text" id="search-input" placeholder="Поиск по ID или имени" onkeyup="filterInstalls()">
<div>
<input type="radio" id="search-current" name="search-scope" value="current" checked>
<label for="search-current">Текущая папка</label>
<input type="radio" id="search-all" name="search-scope" value="all">
<label for="search-all">Все папки</label>
</div>
</div>
<div class="form-container">
<h2>Добавить запись</h2>
<input type="text" id="rustId" placeholder="Rust ID" required>
@ -32,36 +47,29 @@
<input type="text" id="installTime" placeholder="Время (опционально)">
<button onclick="addInstall()">Добавить</button>
</div>
<input type="text" id="search-input" placeholder="Поиск по ID или имени" onkeyup="filterInstalls()">
<select id="sort-select" onchange="sortInstalls()">
<option value="">Без сортировки</option>
<option value="rust_id_asc">Rust ID (А-Я)</option>
<option value="rust_id_desc">Rust ID (Я-А)</option>
<option value="computer_name_asc">Имя (А-Я)</option>
<option value="computer_name_desc">Имя (Я-А)</option>
<option value="install_time_asc">Время (ранее-позже)</option>
<option value="install_time_desc">Время (позже-ранее)</option>
</select>
<div class="header">
<div onclick="sortInstalls('rust_id')">Rust ID<span class="sort-arrow"></span></div>
<div onclick="sortInstalls('computer_name')">Имя компьютера<span class="sort-arrow"></span></div>
<div onclick="sortInstalls('install_time')">Время установки<span class="sort-arrow"></span></div>
<div>Действия</div>
</div>
<div id="installs-list"></div>
</div>
<script>
const API_URL = "/api";
let selectedFolderId = null;
let allInstalls = []; // Храним все записи для поиска и сортировки
let allInstalls = [];
let sortField = null;
let sortDirection = 'asc';
$(document).ready(function () {
// Инициализация дерева папок
$('#folder-tree').jstree({
'core': {
'data': function (node, cb) {
$.getJSON(`${API_URL}/folders`, function (data) {
const treeData = [
{
id: "root",
text: "Корень",
parent: "#"
}
{ id: "root", text: "Корень", parent: "#" }
].concat(data.map(folder => ({
id: folder.id,
text: `${folder.name} <span class="folder-actions">` +
@ -80,13 +88,12 @@
loadInstalls(selectedFolderId);
});
// Drag-and-drop для записей
$('#installs-list').on('dragstart', '.install-item', function (e) {
e.originalEvent.dataTransfer.setData('text/plain', $(this).data('id'));
});
$('#folder-tree').on('dragover', function (e) {
e.preventDefault(); // Разрешаем drop
e.preventDefault();
}).on('drop', function (e) {
e.preventDefault();
const installId = e.originalEvent.dataTransfer.getData('text');
@ -97,64 +104,80 @@
}
});
// Загрузка всех записей при старте
loadInstalls(null);
$('#folder-tree').jstree('select_node', 'root'); // Выбираем корень по умолчанию
$('#folder-tree').jstree('select_node', 'root');
});
function loadInstalls(folderId) {
$.getJSON(`${API_URL}/installs`, function (data) {
allInstalls = data; // Сохраняем все записи
allInstalls = data;
let filtered = folderId ? data.filter(i => i.folder_id == folderId) : data.filter(i => i.folder_id === null);
displayInstalls(filtered);
});
selectedFolderId = folderId; // Обновляем текущую папку
selectedFolderId = folderId;
}
function displayInstalls(installs) {
$('#installs-list').html(installs.map(item => `
<div class="install-item" data-id="${item.id}" draggable="true">
<a href="rustdesk://${item.rust_id}" onclick="openRustDesk('${item.rust_id}'); return false;">${item.rust_id}</a>
- ${item.computer_name} (${item.install_time})
<button onclick="editInstall(${item.id}, '${item.rust_id}', '${item.computer_name}', '${item.install_time}')">Редактировать</button>
<button onclick="deleteInstall(${item.id})">Удалить</button>
<div class="install-item" data-id="${item.id}" draggable="true" style="display: flex; justify-content: space-between;">
<div style="flex: 1; text-align: center;">${item.rust_id}</div>
<div style="flex: 1; text-align: center;">${item.computer_name}</div>
<div style="flex: 1; text-align: center;">${item.install_time}</div>
<div style="flex: 1; text-align: center;">
<a href="rustdesk://${item.rust_id}" onclick="openRustDesk('${item.rust_id}'); return false;">Подключиться</a>
<button onclick="editInstall(${item.id}, '${item.rust_id}', '${item.computer_name}', '${item.install_time}')">Редактировать</button>
<button onclick="deleteInstall(${item.id})">Удалить</button>
</div>
</div>
`).join(''));
updateSortArrows();
}
function filterInstalls() {
const query = $('#search-input').val().toLowerCase();
let filtered = selectedFolderId
? allInstalls.filter(i => i.folder_id == selectedFolderId)
: allInstalls.filter(i => i.folder_id === null);
const scope = $('input[name="search-scope"]:checked').val();
let filtered = scope === 'current'
? (selectedFolderId ? allInstalls.filter(i => i.folder_id == selectedFolderId) : allInstalls.filter(i => i.folder_id === null))
: allInstalls;
filtered = filtered.filter(i =>
i.rust_id.toLowerCase().includes(query) ||
i.computer_name.toLowerCase().includes(query)
);
sortInstalls(filtered);
sortInstalls(null, filtered);
}
function sortInstalls(filteredInstalls = null) {
function sortInstalls(field, filteredInstalls = null) {
let installs = filteredInstalls || (selectedFolderId
? allInstalls.filter(i => i.folder_id == selectedFolderId)
: allInstalls.filter(i => i.folder_id === null));
const sortBy = $('#sort-select').val();
if (sortBy) {
const [field, direction] = sortBy.split('_');
if (field) {
if (sortField === field) {
sortDirection = sortDirection === 'asc' ? 'desc' : 'asc';
} else {
sortField = field;
sortDirection = 'asc';
}
installs.sort((a, b) => {
let valA = a[field], valB = b[field];
if (field === 'install_time') {
valA = new Date(valA);
valB = new Date(valB);
}
if (direction === 'asc') return valA > valB ? 1 : -1;
return valA < valB ? 1 : -1;
return sortDirection === 'asc' ? (valA > valB ? 1 : -1) : (valA < valB ? 1 : -1);
});
}
displayInstalls(installs);
}
function updateSortArrows() {
$('.sort-arrow').text('');
if (sortField) {
$(`.header div:contains("${sortField === 'rust_id' ? 'Rust ID' : sortField === 'computer_name' ? 'Имя компьютера' : 'Время установки'}") .sort-arrow`)
.text(sortDirection === 'asc' ? '↑' : '↓');
}
}
function addFolder() {
const name = prompt("Введите имя папки:");
if (name) {
@ -255,7 +278,7 @@
contentType: 'application/json',
data: JSON.stringify({ folder_id: folderId }),
success: function () {
loadInstalls(selectedFolderId); // Обновляем текущую папку
loadInstalls(selectedFolderId);
},
error: function (xhr, status, error) {
console.error("Ошибка переноса:", status, error);