Better deduplication
This commit is contained in:
@ -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') {
|
||||||
|
|||||||
@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user