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