mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-03-01 12:59:36 +00:00
Cleanup-Logik für Baugruppen und BOM-Einträge im Statistik-Bereich überarbeiten bzw. erweitern
This commit is contained in:
parent
d67e93064c
commit
b08df9b812
35 changed files with 864 additions and 233 deletions
|
|
@ -2,44 +2,154 @@ import { Controller } from '@hotwired/stimulus';
|
|||
|
||||
export default class extends Controller {
|
||||
static values = {
|
||||
url: String,
|
||||
confirmMsg: String,
|
||||
successMsg: String,
|
||||
errorMsg: String
|
||||
cleanupBomUrl: String,
|
||||
cleanupPreviewUrl: String
|
||||
}
|
||||
|
||||
static targets = ["count"]
|
||||
static targets = ["bomCount", "previewCount", "bomButton", "previewButton"]
|
||||
|
||||
async cleanup(event) {
|
||||
event.preventDefault();
|
||||
|
||||
if (!confirm(this.confirmMsgValue)) {
|
||||
return;
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
const button = event ? event.currentTarget : null;
|
||||
if (button) button.disabled = true;
|
||||
|
||||
try {
|
||||
const response = await fetch(this.urlValue, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
});
|
||||
const data = await this.fetchWithErrorHandling(this.cleanupBomUrlValue, { method: 'POST' });
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
alert(this.successMsgValue.replace('%count%', data.count));
|
||||
// Update the count displayed in the UI
|
||||
if (this.hasCountTarget) {
|
||||
this.countTarget.innerText = '0';
|
||||
if (data.success) {
|
||||
this.showSuccessMessage(data.message);
|
||||
if (this.hasBomCountTarget) {
|
||||
this.bomCountTarget.textContent = data.new_count;
|
||||
}
|
||||
if (data.new_count === 0 && this.hasBomButtonTarget) {
|
||||
this.bomButtonTarget.remove();
|
||||
}
|
||||
// Reload page to reflect changes if needed, or just let the user see 0
|
||||
window.location.reload();
|
||||
} else {
|
||||
alert(this.errorMsgValue);
|
||||
this.showErrorMessage(data.message || 'BOM cleanup failed');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Cleanup failed:', error);
|
||||
alert(this.errorMsgValue);
|
||||
this.showErrorMessage(error.message || 'An unexpected error occurred during BOM cleanup');
|
||||
} finally {
|
||||
if (button) button.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
async cleanupPreview(event) {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
const button = event ? event.currentTarget : null;
|
||||
if (button) button.disabled = true;
|
||||
|
||||
try {
|
||||
const data = await this.fetchWithErrorHandling(this.cleanupPreviewUrlValue, { method: 'POST' });
|
||||
|
||||
if (data.success) {
|
||||
this.showSuccessMessage(data.message);
|
||||
if (this.hasPreviewCountTarget) {
|
||||
this.previewCountTarget.textContent = data.new_count;
|
||||
}
|
||||
if (data.new_count === 0 && this.hasPreviewButtonTarget) {
|
||||
this.previewButtonTarget.remove();
|
||||
}
|
||||
} else {
|
||||
this.showErrorMessage(data.message || 'Preview cleanup failed');
|
||||
}
|
||||
} catch (error) {
|
||||
this.showErrorMessage(error.message || 'An unexpected error occurred during Preview cleanup');
|
||||
} finally {
|
||||
if (button) button.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
getHeaders() {
|
||||
return {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'Accept': 'application/json',
|
||||
}
|
||||
}
|
||||
|
||||
async fetchWithErrorHandling(url, options = {}, timeout = 30000) {
|
||||
const controller = new AbortController()
|
||||
const timeoutId = setTimeout(() => controller.abort(), timeout)
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
headers: { ...this.getHeaders(), ...options.headers },
|
||||
signal: controller.signal
|
||||
})
|
||||
|
||||
clearTimeout(timeoutId)
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text()
|
||||
let errorMessage = `Server error (${response.status})`;
|
||||
try {
|
||||
const errorJson = JSON.parse(errorText);
|
||||
if (errorJson && errorJson.message) {
|
||||
errorMessage = errorJson.message;
|
||||
}
|
||||
} catch (e) {
|
||||
// Not a JSON response, use status text
|
||||
errorMessage = `${errorMessage}: ${errorText}`;
|
||||
}
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
return await response.json()
|
||||
} catch (error) {
|
||||
clearTimeout(timeoutId)
|
||||
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error('Request timed out. Please try again.')
|
||||
} else if (error.message.includes('Failed to fetch')) {
|
||||
throw new Error('Network error. Please check your connection and try again.')
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showSuccessMessage(message) {
|
||||
this.showToast('success', message)
|
||||
}
|
||||
|
||||
showErrorMessage(message) {
|
||||
this.showToast('error', message)
|
||||
}
|
||||
|
||||
showToast(type, message) {
|
||||
// Create a simple alert that doesn't disrupt layout
|
||||
const alertId = 'alert-' + Date.now();
|
||||
const iconClass = type === 'success' ? 'fa-check-circle' : 'fa-exclamation-triangle';
|
||||
const alertClass = type === 'success' ? 'alert-success' : 'alert-danger';
|
||||
|
||||
const alertHTML = `
|
||||
<div class="alert ${alertClass} alert-dismissible fade show position-fixed"
|
||||
style="top: 20px; right: 20px; z-index: 9999; max-width: 400px;"
|
||||
id="${alertId}" role="alert">
|
||||
<i class="fas ${iconClass} me-2"></i>
|
||||
${message}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Add alert to body
|
||||
document.body.insertAdjacentHTML('beforeend', alertHTML);
|
||||
|
||||
// Auto-remove after 5 seconds if not closed manually
|
||||
setTimeout(() => {
|
||||
const elementToRemove = document.getElementById(alertId);
|
||||
if (elementToRemove) {
|
||||
elementToRemove.remove();
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue