underlight
parent
7a1dff3ac1
commit
7affc521d9
|
|
@ -3,9 +3,9 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Органайзер АйТи-Депо</title>
|
<title>Органайзер АйТи-Депо</title>
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js" defer></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.12/jstree.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.12/jstree.min.js" defer></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> <!-- Библиотека для Markdown -->
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js" defer></script>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.12/themes/default/style.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.12/themes/default/style.min.css">
|
||||||
<style>
|
<style>
|
||||||
body { display: flex; font-family: Arial, sans-serif; margin: 0; }
|
body { display: flex; font-family: Arial, sans-serif; margin: 0; }
|
||||||
|
|
@ -15,10 +15,11 @@
|
||||||
.install-item.selected { background-color: #e6f7ff; } /* Подсветка выбранного пункта */
|
.install-item.selected { background-color: #e6f7ff; } /* Подсветка выбранного пункта */
|
||||||
.form-container { margin-bottom: 20px; }
|
.form-container { margin-bottom: 20px; }
|
||||||
.jstree-node { position: relative; }
|
.jstree-node { position: relative; }
|
||||||
.folder-actions { display: none; position: absolute; right: 5px; top: 50%; transform: translateY(-50%); margin-left: 0; } /* Сдвигаем кнопки вправо и центрируем по вертикали */
|
.folder-actions { display: none; position: absolute; right: 5px; top: 50%; transform: translateY(-50%); margin-left: 0; }
|
||||||
|
.jstree-node.drag-over { background-color: #d4edda; border: 2px dashed #28a745; } /* Подсветка при перетаскивании */
|
||||||
#search-container { position: absolute; top: 10px; right: 10px; text-align: right; }
|
#search-container { position: absolute; top: 10px; right: 10px; text-align: right; }
|
||||||
#search-input { width: 200px; margin-bottom: 5px; }
|
#search-input { width: 200px; margin-bottom: 5px; }
|
||||||
#installs-list { margin-top: 0; } /* Убираем верхний отступ, чтобы таблица начиналась сразу после заголовка */
|
#installs-list { margin-top: 0; }
|
||||||
.header { display: flex; justify-content: space-between; font-weight: bold; padding: 5px; background: #f0f0f0; cursor: pointer; }
|
.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 { flex: 1; text-align: center; }
|
||||||
.header div:hover { background: #e0e0e0; }
|
.header div:hover { background: #e0e0e0; }
|
||||||
|
|
@ -36,7 +37,7 @@
|
||||||
#import-label:hover { background: #0056b3; }
|
#import-label:hover { background: #0056b3; }
|
||||||
.folder-select { margin-bottom: 5px; width: 150px; }
|
.folder-select { margin-bottom: 5px; width: 150px; }
|
||||||
.time-hint { font-size: 12px; color: #666; margin-top: 5px; }
|
.time-hint { font-size: 12px; color: #666; margin-top: 5px; }
|
||||||
#notes-panel { width: 30%; padding: 10px; border-left: 1px solid #ccc; background: #f9f9f9; min-height: 200px; margin-top: 240px; } /* Смещаем ниже, чтобы начиналось на уровне заголовка таблицы */
|
#notes-panel { width: 30%; padding: 10px; border-left: 1px solid #ccc; background: #f9f9f9; min-height: 200px; margin-top: 240px; }
|
||||||
#notes-content { margin-top: 10px; }
|
#notes-content { margin-top: 10px; }
|
||||||
#note-modal { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border: 1px solid #ccc; box-shadow: 0 0 10px rgba(0,0,0,0.3); z-index: 1000; width: 500px; }
|
#note-modal { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border: 1px solid #ccc; box-shadow: 0 0 10px rgba(0,0,0,0.3); z-index: 1000; width: 500px; }
|
||||||
#note-modal .markdown-buttons { margin-bottom: 10px; }
|
#note-modal .markdown-buttons { margin-bottom: 10px; }
|
||||||
|
|
@ -45,7 +46,7 @@
|
||||||
#note-modal button { margin-right: 10px; }
|
#note-modal button { margin-right: 10px; }
|
||||||
#modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 999; }
|
#modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 999; }
|
||||||
.header-logo { display: flex; align-items: center; }
|
.header-logo { display: flex; align-items: center; }
|
||||||
.header-logo img { height: 50px; margin-right: 10px; } /* Логотип 50x50 пикселей */
|
.header-logo img { height: 50px; margin-right: 10px; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -56,7 +57,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="installs-container">
|
<div id="installs-container">
|
||||||
<h1 class="header-logo">
|
<h1 class="header-logo">
|
||||||
<img src="/icons/it-depo-logo.png" alt="АйТи-Депо логотип"> <!-- Логотип -->
|
<img src="/icons/it-depo-logo.png" alt="АйТи-Депо логотип">
|
||||||
Органайзер АйТи-Депо
|
Органайзер АйТи-Депо
|
||||||
</h1>
|
</h1>
|
||||||
<div id="search-container">
|
<div id="search-container">
|
||||||
|
|
@ -114,11 +115,11 @@
|
||||||
<button onclick="closeNoteModal()">Закрыть</button>
|
<button onclick="closeNoteModal()">Закрыть</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script defer>
|
||||||
const API_URL = "http://10.0.0.10:8002/api"; // Замени <server-ip> на IP или домен сервера
|
const API_URL = "http://<server-ip>:8002/api"; // Замени <server-ip> на IP или домен сервера
|
||||||
let selectedFolderId = null;
|
let selectedFolderId = null;
|
||||||
let allInstalls = [];
|
let allInstalls = [];
|
||||||
let allFolders = []; // Добавляем для отслеживания папок
|
let allFolders = [];
|
||||||
let selectedInstallId = null;
|
let selectedInstallId = null;
|
||||||
let sortField = null;
|
let sortField = null;
|
||||||
let sortDirection = 'asc';
|
let sortDirection = 'asc';
|
||||||
|
|
@ -151,7 +152,7 @@
|
||||||
'core': {
|
'core': {
|
||||||
'data': function (node, cb) {
|
'data': function (node, cb) {
|
||||||
$.getJSON(`${API_URL}/folders`, function (data) {
|
$.getJSON(`${API_URL}/folders`, function (data) {
|
||||||
allFolders = data; // Сохраняем все папки
|
allFolders = data;
|
||||||
const treeData = [
|
const treeData = [
|
||||||
{ id: "root", text: "Корень", parent: "#" }
|
{ id: "root", text: "Корень", parent: "#" }
|
||||||
].concat(data.map(folder => ({
|
].concat(data.map(folder => ({
|
||||||
|
|
@ -162,6 +163,16 @@
|
||||||
parent: folder.parent_id ? folder.parent_id : "root"
|
parent: folder.parent_id ? folder.parent_id : "root"
|
||||||
})));
|
})));
|
||||||
cb(treeData);
|
cb(treeData);
|
||||||
|
|
||||||
|
// Автоматически выбираем папку "Несортированные" после загрузки дерева
|
||||||
|
const unsortedFolder = data.find(f => f.name === 'Несортированные');
|
||||||
|
if (unsortedFolder) {
|
||||||
|
setTimeout(() => {
|
||||||
|
$('#folder-tree').jstree('select_node', unsortedFolder.id);
|
||||||
|
loadInstalls(unsortedFolder.id);
|
||||||
|
updateFolderActions();
|
||||||
|
}, 100); // Задержка для инициализации jstree
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'check_callback': true
|
'check_callback': true
|
||||||
|
|
@ -187,10 +198,16 @@
|
||||||
e.originalEvent.dataTransfer.setData('text/plain', $(this).data('id'));
|
e.originalEvent.dataTransfer.setData('text/plain', $(this).data('id'));
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#folder-tree').on('dragover', function (e) {
|
// Подсветка папки при перетаскивании
|
||||||
|
$('#folder-tree').on('dragover', '.jstree-node', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
$(this).addClass('drag-over'); // Добавляем класс для подсветки
|
||||||
|
}).on('dragleave', '.jstree-node', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
$(this).removeClass('drag-over'); // Убираем подсветку при покидании
|
||||||
}).on('drop', function (e) {
|
}).on('drop', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
$(this).removeClass('drag-over'); // Убираем подсветку после дропа
|
||||||
const installId = e.originalEvent.dataTransfer.getData('text');
|
const installId = e.originalEvent.dataTransfer.getData('text');
|
||||||
let targetFolderId = $(e.target).closest('.jstree-node').attr('id');
|
let targetFolderId = $(e.target).closest('.jstree-node').attr('id');
|
||||||
if (installId && targetFolderId) {
|
if (installId && targetFolderId) {
|
||||||
|
|
@ -202,14 +219,16 @@
|
||||||
|
|
||||||
function loadFolders() {
|
function loadFolders() {
|
||||||
$.getJSON(`${API_URL}/folders`, function (data) {
|
$.getJSON(`${API_URL}/folders`, function (data) {
|
||||||
allFolders = data; // Обновляем список папок
|
allFolders = data;
|
||||||
updateFolderSelect(); // Обновляем выпадающий список
|
updateFolderSelect();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadInstalls(folderId) {
|
function loadInstalls(folderId) {
|
||||||
$.getJSON(`${API_URL}/installs`, function (data) {
|
const url = `${API_URL}/installs`;
|
||||||
console.log("Loaded installs:", data); // Логируем данные для отладки
|
console.log("Requesting URL:", url);
|
||||||
|
$.getJSON(url, function (data) {
|
||||||
|
console.log("Loaded installs:", data);
|
||||||
allInstalls = data;
|
allInstalls = data;
|
||||||
let filtered = folderId ? data.filter(i => i.folder_id == folderId && i.folder_id !== null) : data;
|
let filtered = folderId ? data.filter(i => i.folder_id == folderId && i.folder_id !== null) : data;
|
||||||
displayInstalls(filtered);
|
displayInstalls(filtered);
|
||||||
|
|
@ -224,19 +243,17 @@
|
||||||
const query = $('#search-input').val().toLowerCase().trim();
|
const query = $('#search-input').val().toLowerCase().trim();
|
||||||
const folderId = $('#folder-select').val() || '';
|
const folderId = $('#folder-select').val() || '';
|
||||||
|
|
||||||
console.log("Search query:", query, "Folder ID:", folderId); // Логируем для отладки
|
console.log("Search query:", query, "Folder ID:", folderId);
|
||||||
|
|
||||||
let filteredInstalls = [...allInstalls]; // Копируем массив, чтобы не изменять оригинал
|
let filteredInstalls = [...allInstalls];
|
||||||
|
|
||||||
// Фильтрация по папке, исключая удаленные или несуществующие папки
|
|
||||||
if (folderId) {
|
if (folderId) {
|
||||||
filteredInstalls = filteredInstalls.filter(i =>
|
filteredInstalls = filteredInstalls.filter(i =>
|
||||||
i.folder_id == folderId &&
|
i.folder_id == folderId &&
|
||||||
allFolders.some(f => f.id === i.folder_id) // Проверяем, существует ли папка
|
allFolders.some(f => f.id === i.folder_id)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Фильтрация по запросу (по rust_id и computer_name)
|
|
||||||
if (query) {
|
if (query) {
|
||||||
filteredInstalls = filteredInstalls.filter(i =>
|
filteredInstalls = filteredInstalls.filter(i =>
|
||||||
i.rust_id.toLowerCase().trim().includes(query) ||
|
i.rust_id.toLowerCase().trim().includes(query) ||
|
||||||
|
|
@ -244,11 +261,11 @@
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
sortInstalls(null, filteredInstalls); // Сортируем и отображаем результаты
|
sortInstalls(null, filteredInstalls);
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayInstalls(installs) {
|
function displayInstalls(installs) {
|
||||||
console.log("Displaying installs:", installs); // Логируем для отладки
|
console.log("Displaying installs:", installs);
|
||||||
if (installs.length === 0) {
|
if (installs.length === 0) {
|
||||||
$('#installs-list').html('<p>Нет результатов</p>');
|
$('#installs-list').html('<p>Нет результатов</p>');
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -331,7 +348,7 @@
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
data: JSON.stringify({ name, parent_id: selectedFolderId }),
|
data: JSON.stringify({ name, parent_id: selectedFolderId }),
|
||||||
success: function () {
|
success: function () {
|
||||||
loadFolders(); // Обновляем список папок
|
loadFolders();
|
||||||
$('#folder-tree').jstree(true).refresh();
|
$('#folder-tree').jstree(true).refresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -347,7 +364,7 @@
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
data: JSON.stringify({ name: newName }),
|
data: JSON.stringify({ name: newName }),
|
||||||
success: function () {
|
success: function () {
|
||||||
loadFolders(); // Обновляем список папок
|
loadFolders();
|
||||||
$('#folder-tree').jstree(true).refresh();
|
$('#folder-tree').jstree(true).refresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -366,7 +383,7 @@
|
||||||
moveInstallToFolder(item.id, null);
|
moveInstallToFolder(item.id, null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
loadFolders(); // Обновляем список папок
|
loadFolders();
|
||||||
$('#folder-tree').jstree(true).refresh();
|
$('#folder-tree').jstree(true).refresh();
|
||||||
loadInstalls(selectedFolderId);
|
loadInstalls(selectedFolderId);
|
||||||
},
|
},
|
||||||
|
|
@ -608,7 +625,7 @@
|
||||||
function formatLink() {
|
function formatLink() {
|
||||||
const textarea = $('#note-textarea');
|
const textarea = $('#note-textarea');
|
||||||
const start = textarea[0].selectionStart;
|
const start = textarea[0].selectionStart;
|
||||||
const end = textarea[0].selectionEnd;
|
end = textarea[0].selectionEnd;
|
||||||
const text = textarea.val();
|
const text = textarea.val();
|
||||||
const selected = text.substring(start, end) || 'текст';
|
const selected = text.substring(start, end) || 'текст';
|
||||||
const url = prompt('Введите URL ссылки:', 'https://example.com');
|
const url = prompt('Введите URL ссылки:', 'https://example.com');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue