icons
parent
c5de24cc08
commit
51da9cd359
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 652 B |
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
|
|
@ -152,17 +152,17 @@
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.protocol-icon {
|
||||
vertical-align: middle;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
.protocol-icon img {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.connection-link {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
flex-grow: 1;
|
||||
margin-right: 8px; /* Отступ перед иконками */
|
||||
margin-right: 8px;
|
||||
}
|
||||
.connection-link.dark-theme {
|
||||
color: #66b0ff;
|
||||
|
|
@ -172,23 +172,41 @@
|
|||
padding: 2px 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.action-buttons.dark-theme button {
|
||||
background-color: #555;
|
||||
color: #fff;
|
||||
border: 1px solid #777;
|
||||
}
|
||||
.edit-button, .copy-button, .note-button {
|
||||
margin-left: 8px; /* Отступ слева от текста */
|
||||
background: none;
|
||||
.custom-icon {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s, transform 0.2s;
|
||||
}
|
||||
.edit-button.dark-theme, .copy-button.dark-theme, .note-button.dark-theme {
|
||||
color: #fff; /* Темные иконки становятся белыми на темной теме */
|
||||
.custom-icon:hover {
|
||||
background-color: #e0e0e0; /* Светлый фон при наведении */
|
||||
transform: scale(1.1); /* Небольшое увеличение */
|
||||
}
|
||||
.custom-icon.dark-theme:hover {
|
||||
background-color: #444; /* Темный фон при наведении на темной теме */
|
||||
}
|
||||
.edit-icon { background-image: url('/icons/edit.png'); }
|
||||
.copy-icon { background-image: url('/icons/copy.png'); }
|
||||
.note-icon { background-image: url('/icons/note.png'); }
|
||||
.delete-icon { background-image: url('/icons/delete.png'); }
|
||||
.folder-edit-icon { background-image: url('/icons/edit.png'); }
|
||||
.folder-delete-icon { background-image: url('/icons/delete.png'); }
|
||||
.edit-icon.dark-theme, .copy-icon.dark-theme, .note-icon.dark-theme, .delete-icon.dark-theme, .folder-edit-icon.dark-theme, .folder-delete-icon.dark-theme {
|
||||
filter: brightness(0) invert(1); /* Инверсия для темной темы */
|
||||
}
|
||||
#notes-content {
|
||||
padding: 10px;
|
||||
|
|
@ -377,7 +395,6 @@
|
|||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// Восстановление ширины окна с папками из localStorage
|
||||
const savedWidth = localStorage.getItem('treeContainerWidth');
|
||||
if (savedWidth) {
|
||||
document.getElementById('tree-container').style.width = savedWidth + 'px';
|
||||
|
|
@ -407,7 +424,7 @@
|
|||
}
|
||||
localStorage.setItem('theme', defaultTheme);
|
||||
|
||||
$('#installs-list').on('click', '.action-buttons button:nth-child(2)', function () {
|
||||
$('#installs-list').on('click', '.note-icon', function () {
|
||||
const installId = $(this).closest('.install-item').data('id');
|
||||
const install = allInstalls.find(i => i.id === installId);
|
||||
openNoteModal(installId, install?.note || '');
|
||||
|
|
@ -440,7 +457,6 @@
|
|||
document.addEventListener('mouseup', () => {
|
||||
isResizing = false;
|
||||
document.body.style.cursor = 'default';
|
||||
// Сохраняем ширину в localStorage
|
||||
const width = treeContainer.offsetWidth;
|
||||
localStorage.setItem('treeContainerWidth', width);
|
||||
});
|
||||
|
|
@ -532,7 +548,6 @@
|
|||
'core': {
|
||||
'data': function (node, cb) {
|
||||
$.getJSON(`${API_URL}/folders`, function (data) {
|
||||
console.log("Loaded folders:", data);
|
||||
allFolders = data;
|
||||
const sortedFolders = [...data].sort((a, b) => a.name.localeCompare(b.name));
|
||||
const treeData = [
|
||||
|
|
@ -540,8 +555,8 @@
|
|||
].concat(sortedFolders.map(folder => ({
|
||||
id: folder.id,
|
||||
text: `${folder.name} <span class="folder-actions">` +
|
||||
`<button onclick="editFolder(${folder.id}, '${folder.name}')">✏️</button>` +
|
||||
`<button onclick="deleteFolder(${folder.id})">🗑️</button></span>`,
|
||||
`<button class="custom-icon folder-edit-icon" onclick="editFolder(${folder.id}, '${folder.name}')"></button>` +
|
||||
`<button class="custom-icon folder-delete-icon" onclick="deleteFolder(${folder.id})"></button></span>`,
|
||||
parent: folder.parent_id ? folder.parent_id : "root"
|
||||
})));
|
||||
cb(treeData);
|
||||
|
|
@ -608,20 +623,15 @@
|
|||
});
|
||||
|
||||
$('#installs-list').on('dragstart', '.install-item', function (e) {
|
||||
console.log('Drag start:', $(this).data('id'));
|
||||
e.originalEvent.dataTransfer.setData('text/plain', $(this).data('id'));
|
||||
});
|
||||
|
||||
$('#folder-tree').on('dragover', function (e) {
|
||||
e.preventDefault();
|
||||
console.log('Drag over');
|
||||
}).on('drop', function (e) {
|
||||
e.preventDefault();
|
||||
console.log('Drop event triggered');
|
||||
const installId = e.originalEvent.dataTransfer.getData('text');
|
||||
console.log('Dropped installId:', installId);
|
||||
let targetFolderId = $(e.target).closest('.jstree-node').attr('id');
|
||||
console.log('Target folderId:', targetFolderId);
|
||||
if (installId && targetFolderId) {
|
||||
targetFolderId = targetFolderId === "root" ? null : targetFolderId;
|
||||
moveInstallToFolder(installId, targetFolderId);
|
||||
|
|
@ -653,8 +663,8 @@
|
|||
};
|
||||
ws.onclose = function() {
|
||||
console.log('WebSocket disconnected, retrying...');
|
||||
let retryDelay = 1000; // Начальная задержка 1 секунда
|
||||
const maxDelay = 30000; // Максимальная задержка 30 секунд
|
||||
let retryDelay = 1000;
|
||||
const maxDelay = 30000;
|
||||
const maxAttempts = 10;
|
||||
let attempts = 0;
|
||||
|
||||
|
|
@ -684,7 +694,6 @@
|
|||
|
||||
function loadInstalls(folderId) {
|
||||
$.getJSON(`${API_URL}/installs`, function (data) {
|
||||
console.log("Loaded installs:", data);
|
||||
allInstalls = data;
|
||||
let filtered = folderId ? data.filter(i => i.folder_id == folderId && i.folder_id !== null) : data;
|
||||
displayInstalls(filtered);
|
||||
|
|
@ -703,8 +712,6 @@
|
|||
const query = $('#search-input').val().toLowerCase().trim();
|
||||
const folderId = $('#folder-select').val() || '';
|
||||
|
||||
console.log("Search query:", query, "Folder ID:", folderId);
|
||||
|
||||
let filteredInstalls = [...allInstalls];
|
||||
|
||||
if (folderId) {
|
||||
|
|
@ -725,21 +732,20 @@
|
|||
}
|
||||
|
||||
function displayInstalls(installs) {
|
||||
console.log("Displaying installs:", installs);
|
||||
const isDarkTheme = document.body.classList.contains('dark-theme');
|
||||
if (installs.length === 0) {
|
||||
$('#installs-list').html('<p>Нет результатов</p>');
|
||||
} else {
|
||||
$('#installs-list').html(installs.map(item => {
|
||||
const lastSeen = new Date(item.last_seen || '1970-01-01');
|
||||
const isOnline = (new Date() - lastSeen) < 60000; // Онлайн, если менее 1 минуты
|
||||
const isOnline = (new Date() - lastSeen) < 60000;
|
||||
const statusClass = isOnline ? 'status-online' : 'status-offline';
|
||||
return `
|
||||
<div class="install-item ${isDarkTheme ? 'dark-theme' : ''}" data-id="${item.id}" draggable="true">
|
||||
<div class="computer-name">${item.computer_name} <button class="edit-button ${isDarkTheme ? 'dark-theme' : ''}" onclick="editField(${item.id}, 'computer_name', '${item.computer_name}')">✏️</button></div>
|
||||
<div class="connection-id"><span class="protocol-icon">${protocolIcons[item.protocol]}</span><a href="${protocolLinks[item.protocol]}${item.rust_id}" class="connection-link ${isDarkTheme ? 'dark-theme' : ''}" target="_blank">${item.rust_id}</a><span class="${statusClass}"></span> <button class="copy-button ${isDarkTheme ? 'dark-theme' : ''}" onclick="copyToClipboard('${item.rust_id}')">📋</button> <button class="edit-button ${isDarkTheme ? 'dark-theme' : ''}" onclick="editField(${item.id}, 'rust_id', '${item.rust_id}')">✏️</button></div>
|
||||
<div class="install-time">${item.install_time} <button class="edit-button ${isDarkTheme ? 'dark-theme' : ''}" onclick="editField(${item.id}, 'install_time', '${item.install_time}')">✏️</button></div>
|
||||
<div class="actions"><span class="action-buttons"><button onclick="deleteInstall(${item.id})">Удалить</button> <button class="note-button ${isDarkTheme ? 'dark-theme' : ''}">Заметка</button></span></div>
|
||||
<div class="computer-name">${item.computer_name} <button class="custom-icon edit-icon" onclick="editField(${item.id}, 'computer_name', '${item.computer_name}')"></button></div>
|
||||
<div class="connection-id"><span class="protocol-icon">${protocolIcons[item.protocol]}</span><a href="${protocolLinks[item.protocol]}${item.rust_id}" class="connection-link ${isDarkTheme ? 'dark-theme' : ''}" target="_blank">${item.rust_id}</a><span class="${statusClass}"></span> <button class="custom-icon copy-icon" onclick="copyToClipboard('${item.rust_id}')"></button> <button class="custom-icon edit-icon" onclick="editField(${item.id}, 'rust_id', '${item.rust_id}')"></button></div>
|
||||
<div class="install-time">${item.install_time} <button class="custom-icon edit-icon" onclick="editField(${item.id}, 'install_time', '${item.install_time}')"></button></div>
|
||||
<div class="actions"><span class="action-buttons"><button class="custom-icon delete-icon" onclick="deleteInstall(${item.id})"></button> <button class="custom-icon note-icon"></button></span></div>
|
||||
</div>
|
||||
`;
|
||||
}).join(''));
|
||||
|
|
@ -951,7 +957,6 @@
|
|||
}
|
||||
|
||||
function moveInstallToFolder(installId, folderId) {
|
||||
console.log('Moving installId:', installId, 'to folderId:', folderId);
|
||||
const install = allInstalls.find(i => i.id === parseInt(installId));
|
||||
if (!install) {
|
||||
console.error('Install not found:', installId);
|
||||
|
|
@ -970,7 +975,6 @@
|
|||
note: install.note
|
||||
}),
|
||||
success: function () {
|
||||
console.log('Move successful');
|
||||
loadInstalls(selectedFolderId);
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
|
|
@ -1016,7 +1020,6 @@
|
|||
}
|
||||
|
||||
function openNoteModal(installId, currentNote) {
|
||||
console.log('Opening note modal for installId:', installId, 'with note:', currentNote);
|
||||
selectedInstallId = installId;
|
||||
$('#note-textarea').val(currentNote || '');
|
||||
$('#note-modal').show();
|
||||
|
|
@ -1043,7 +1046,6 @@
|
|||
processData: false,
|
||||
contentType: false,
|
||||
success: function (response) {
|
||||
console.log('Image uploaded:', response);
|
||||
const imageUrl = response.url;
|
||||
const textarea = $('#note-textarea');
|
||||
const cursorPos = textarea[0].selectionStart;
|
||||
|
|
@ -1062,9 +1064,7 @@
|
|||
}
|
||||
|
||||
function saveNote() {
|
||||
console.log('Saving note for installId:', selectedInstallId);
|
||||
if (!selectedInstallId) {
|
||||
console.error('No install selected');
|
||||
alert('Выберите запись для редактирования заметки.');
|
||||
return;
|
||||
}
|
||||
|
|
@ -1086,7 +1086,6 @@
|
|||
note: note
|
||||
}),
|
||||
success: function () {
|
||||
console.log('Note saved successfully');
|
||||
loadInstalls(selectedFolderId);
|
||||
selectedInstallId = currentSelectedId;
|
||||
closeNoteModal();
|
||||
|
|
@ -1164,7 +1163,7 @@
|
|||
function formatItalic() {
|
||||
const textarea = $('#note-textarea');
|
||||
const start = textarea[0].selectionStart;
|
||||
end = textarea[0].selectionEnd;
|
||||
const end = textarea[0].selectionEnd;
|
||||
const text = textarea.val();
|
||||
const selected = text.substring(start, end);
|
||||
const newText = `*${selected}*`;
|
||||
|
|
@ -1207,7 +1206,6 @@
|
|||
contentType: 'application/json',
|
||||
data: JSON.stringify({ name: folder.name, parent_id: newParentId }),
|
||||
success: function () {
|
||||
console.log(`Folder ${folderId} moved to parent ${newParentId}`);
|
||||
loadFolders();
|
||||
$('#folder-tree').jstree(true).refresh();
|
||||
},
|
||||
|
|
@ -1228,7 +1226,7 @@
|
|||
}).fail(function(jqxhr, textStatus, error) {
|
||||
console.error("Error syncing installs:", textStatus, error);
|
||||
});
|
||||
}, 60000); // Каждые 60 секунд
|
||||
}, 60000);
|
||||
}
|
||||
|
||||
startPeriodicSync();
|
||||
|
|
|
|||
Loading…
Reference in New Issue