Better deduplication

This commit is contained in:
2025-05-15 08:33:13 -04:00
parent d40d6c2844
commit 1fe7bc0f93
2 changed files with 61 additions and 15 deletions

View File

@ -408,24 +408,59 @@ document.addEventListener('DOMContentLoaded', function() {
}); });
}); });
function saveTicket() {
const editables = document.querySelectorAll('.editable');
const data = {};
const ticketId = window.location.href.split('id=')[1];
editables.forEach(field => {
if (field.dataset.field) {
data[field.dataset.field] = field.value;
}
});
fetch('update_ticket.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
ticket_id: ticketId,
...data
})
})
.then(response => response.json())
.then(data => {
if(data.success) {
const statusDisplay = document.getElementById('statusDisplay');
statusDisplay.className = `status-${data.status}`;
statusDisplay.textContent = data.status;
}
});
}
function toggleHamburgerEditMode() { function toggleHamburgerEditMode() {
const editButton = document.getElementById('hamburgerEditButton'); const editButton = document.getElementById('hamburgerEditButton');
const editables = document.querySelectorAll('.hamburger-content .editable'); const editables = document.querySelectorAll('.hamburger-content .editable');
const isEditing = editButton.classList.contains('editing'); // Use a dedicated class const cancelButton = document.getElementById('hamburgerCancelButton'); // Get cancel button
const isEditing = editButton.classList.contains('editing');
if (!isEditing) { if (!isEditing) {
editButton.textContent = 'Save Changes'; editButton.textContent = 'Save Changes';
editButton.classList.add('editing'); // Add the class editButton.classList.add('editing');
editables.forEach(field => field.disabled = false); editables.forEach(field => field.disabled = false);
const cancelButton = document.createElement('button'); // Create and append cancel button only if it doesn't exist
cancelButton.id = 'hamburgerCancelButton'; if (!cancelButton) {
cancelButton.className = 'btn'; const newCancelButton = document.createElement('button');
cancelButton.textContent = 'Cancel'; newCancelButton.id = 'hamburgerCancelButton';
cancelButton.onclick = cancelHamburgerEdit; newCancelButton.className = 'btn';
editButton.parentNode.appendChild(cancelButton); newCancelButton.textContent = 'Cancel';
newCancelButton.onclick = cancelHamburgerEdit;
editButton.parentNode.appendChild(newCancelButton);
}
} else { } else {
saveHamburgerChanges(); // Directly call save on second click saveHamburgerChanges();
} }
} }
@ -517,6 +552,12 @@ function createHamburgerMenu() {
</div> </div>
</div> </div>
`; `;
const hamburgerEditButton = hamburgerMenu.querySelector('#hamburgerEditButton');
if (hamburgerEditButton) {
hamburgerEditButton.addEventListener('click', toggleHamburgerEditMode);
} else {
console.error("Error: #hamburgerEditButton not found!");
}
// Add event listener for Escape key press // Add event listener for Escape key press
document.addEventListener('keydown', (event) => { document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') { if (event.key === 'Escape') {

View File

@ -67,14 +67,18 @@ function generateTicketHash($data) {
preg_match('/\[([\w\d-]+)\]/', $data['title'], $hostMatches); preg_match('/\[([\w\d-]+)\]/', $data['title'], $hostMatches);
$hostname = $hostMatches[1] ?? ''; $hostname = $hostMatches[1] ?? '';
// Extract error types from title // Extract SMART attribute types without their values
preg_match_all('/Critical ([^:,]+)/', $data['title'], $errorMatches); preg_match_all('/Warning ([^:]+)/', $data['title'], $smartMatches);
$errorTypes = $errorMatches[1] ?? []; $smartAttributes = $smartMatches[1] ?? [];
// Build stable components with only static data
$stableComponents = [ $stableComponents = [
'hostname' => $hostname, 'hostname' => $hostname,
'error_types' => $errorTypes, 'smart_attributes' => $smartAttributes,
'title_base' => preg_replace('/\[\w+\]/', '', $data['title']), // Strip tags for base title 'environment_tags' => array_filter(
explode('][', $data['title']),
fn($tag) => in_array($tag, ['production', 'development', 'staging', 'single-node'])
)
]; ];
// Only include device info for drive-specific tickets // Only include device info for drive-specific tickets
@ -83,7 +87,8 @@ function generateTicketHash($data) {
} }
// Sort arrays for consistent hashing // Sort arrays for consistent hashing
sort($stableComponents['error_types']); sort($stableComponents['smart_attributes']);
sort($stableComponents['environment_tags']);
return hash('sha256', json_encode($stableComponents, JSON_UNESCAPED_SLASHES)); return hash('sha256', json_encode($stableComponents, JSON_UNESCAPED_SLASHES));
} }