mirror of
https://github.com/sassanix/Warracker.git
synced 2026-01-06 05:29:39 -06:00
Fix global warranties view, add Model Number field, and enhance modal tab responsiveness
* **Fixed:** * Global view on Index page now correctly shows warranties from all users, including archived ones. * Added `GET /api/warranties/global/archived` and unified global queries with correlated subqueries to avoid missing or collapsed rows. * Updated frontend logic to merge archived warranties from the new endpoint when Global scope and Status = “All.” * Bumped `script.js` and service worker cache to ensure clients receive updated logic. * Updated files: `backend/warranties_routes.py`, `frontend/script.js`, `frontend/sw.js`, `frontend/index.html`, `frontend/status.html`. * **Added:** * Introduced **Model Number** field to warranties. * Backend: Added `model_number` column, integrated into GET/POST/PUT routes. * Frontend: Added Model Number input in New/Edit modals and display on warranty cards. * Updated files: `backend/migrations/047_add_model_number_to_warranties.sql`, `backend/warranties_routes.py`, `frontend/index.html`, `frontend/status.html`, `frontend/script.js`, `locales/en/translation.json`. * **Enhanced:** * Improved **Add Warranty modal** tab alignment for responsive layouts (≤740px). * Adjusted tab label size and spacing to prevent wrapping while keeping icons and labels visible. * Ensured consistent five-step progress indicator across all breakpoints. * Updated file: `frontend/style.css`.
This commit is contained in:
@@ -936,6 +936,9 @@ let formTabs = []; // Changed from const to let, initialized as empty
|
||||
if (notesModalWarrantyObj.warranty_type) {
|
||||
formData.append('warranty_type', notesModalWarrantyObj.warranty_type);
|
||||
}
|
||||
if (typeof notesModalWarrantyObj.model_number !== 'undefined' && notesModalWarrantyObj.model_number !== null) {
|
||||
formData.append('model_number', notesModalWarrantyObj.model_number);
|
||||
}
|
||||
if (notesModalWarrantyObj.serial_numbers && Array.isArray(notesModalWarrantyObj.serial_numbers)) {
|
||||
notesModalWarrantyObj.serial_numbers.forEach(sn => {
|
||||
if (sn && sn.trim() !== '') {
|
||||
@@ -953,6 +956,11 @@ let formTabs = []; // Changed from const to let, initialized as empty
|
||||
formData.append('tag_ids', JSON.stringify([]));
|
||||
}
|
||||
formData.append('notes', notesValue);
|
||||
// Also include model number value from edit input if present on DOM
|
||||
const editModelNumberInput = document.getElementById('editModelNumber');
|
||||
if (editModelNumberInput && editModelNumberInput.value.trim() !== '') {
|
||||
formData.set('model_number', editModelNumberInput.value.trim());
|
||||
}
|
||||
const response = await fetch(`/api/warranties/${warrantyId}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
@@ -2182,10 +2190,10 @@ async function loadWarranties(isAuthenticated) { // Added isAuthenticated parame
|
||||
|
||||
// Use the appropriate API endpoint based on saved preference
|
||||
const baseUrl = window.location.origin;
|
||||
// If status is 'archived', use archived endpoint (user-scoped only for now)
|
||||
// If status is 'archived', use archived endpoint (support global vs personal)
|
||||
const isArchivedView = currentFilters && currentFilters.status === 'archived';
|
||||
const apiUrl = isArchivedView
|
||||
? `${baseUrl}/api/warranties/archived`
|
||||
? (shouldUseGlobalView ? `${baseUrl}/api/warranties/global/archived` : `${baseUrl}/api/warranties/archived`)
|
||||
: (shouldUseGlobalView ? `${baseUrl}/api/warranties/global` : `${baseUrl}/api/warranties`);
|
||||
|
||||
console.log(`[DEBUG] Using API endpoint based on saved preference '${savedScope}', archivedView=${isArchivedView}: ${apiUrl}`);
|
||||
@@ -2235,9 +2243,9 @@ async function loadWarranties(isAuthenticated) { // Added isAuthenticated parame
|
||||
// Optionally merge archived items into the "All" view (only in personal scope)
|
||||
let combinedData = Array.isArray(data) ? data : [];
|
||||
lastLoadedIncludesArchived = false;
|
||||
if (!shouldUseGlobalView && !isArchivedView && currentFilters && currentFilters.status === 'all') {
|
||||
if (!isArchivedView && currentFilters && currentFilters.status === 'all') {
|
||||
try {
|
||||
const archivedUrl = `${baseUrl}/api/warranties/archived`;
|
||||
const archivedUrl = shouldUseGlobalView ? `${baseUrl}/api/warranties/global/archived` : `${baseUrl}/api/warranties/archived`;
|
||||
const archivedResp = await fetch(archivedUrl, options);
|
||||
if (archivedResp.ok) {
|
||||
const archivedData = await archivedResp.json();
|
||||
@@ -2709,6 +2717,7 @@ async function renderWarranties(warrantiesToRender) {
|
||||
</div>
|
||||
` : ''}
|
||||
` : ''}
|
||||
${warranty.model_number ? `<div><i class="fas fa-tag"></i> ${window.i18next ? window.i18next.t('warranties.model_number') : 'Model Number'}: <span>${warranty.model_number}</span></div>` : ''}
|
||||
${warranty.vendor ? `<div><i class="fas fa-store"></i> ${window.i18next ? window.i18next.t('warranties.vendor') : 'Vendor'}: <span>${warranty.vendor}</span></div>` : ''}
|
||||
${warranty.warranty_type ? `<div><i class="fas fa-shield-alt"></i> ${window.i18next ? window.i18next.t('warranties.type') : 'Type'}: <span>${warranty.warranty_type}</span></div>` : ''}
|
||||
</div>
|
||||
@@ -2771,6 +2780,7 @@ async function renderWarranties(warrantiesToRender) {
|
||||
</div>
|
||||
` : ''}
|
||||
` : ''}
|
||||
${warranty.model_number ? `<div><i class=\"fas fa-tag\"></i> ${window.i18next ? window.i18next.t('warranties.model_number') : 'Model Number'}: <span>${warranty.model_number}</span></div>` : ''}
|
||||
${warranty.vendor ? `<div><i class="fas fa-store"></i> ${window.i18next ? window.i18next.t('warranties.vendor') : 'Vendor'}: <span>${warranty.vendor}</span></div>` : ''}
|
||||
${warranty.warranty_type ? `<div><i class="fas fa-shield-alt"></i> ${window.i18next ? window.i18next.t('warranties.type') : 'Type'}: <span>${warranty.warranty_type}</span></div>` : ''}
|
||||
</div>
|
||||
@@ -2833,6 +2843,7 @@ async function renderWarranties(warrantiesToRender) {
|
||||
</div>
|
||||
` : ''}
|
||||
` : ''}
|
||||
${warranty.model_number ? `<div><i class=\"fas fa-tag\"></i> ${window.i18next ? window.i18next.t('warranties.model_number') : 'Model Number'}: <span>${warranty.model_number}</span></div>` : ''}
|
||||
${warranty.vendor ? `<div><i class="fas fa-store"></i> ${window.i18next ? window.i18next.t('warranties.vendor') : 'Vendor'}: <span>${warranty.vendor}</span></div>` : ''}
|
||||
${warranty.warranty_type ? `<div><i class="fas fa-shield-alt"></i> ${window.i18next ? window.i18next.t('warranties.type') : 'Type'}: <span>${warranty.warranty_type}</span></div>` : ''}
|
||||
</div>
|
||||
@@ -3205,6 +3216,10 @@ async function openEditModal(warranty) {
|
||||
// Populate form fields
|
||||
document.getElementById('editProductName').value = warranty.product_name;
|
||||
document.getElementById('editProductUrl').value = warranty.product_url || '';
|
||||
const editModelNumberInput = document.getElementById('editModelNumber');
|
||||
if (editModelNumberInput) {
|
||||
editModelNumberInput.value = warranty.model_number || '';
|
||||
}
|
||||
document.getElementById('editPurchaseDate').value = warranty.purchase_date.split('T')[0];
|
||||
// Populate new duration fields
|
||||
document.getElementById('editWarrantyDurationYears').value = warranty.warranty_duration_years || 0;
|
||||
@@ -3890,6 +3905,11 @@ async function handleFormSubmit(event) { // Made async to properly await paperle
|
||||
|
||||
// Create form data object
|
||||
const formData = new FormData(warrantyForm);
|
||||
// Ensure model_number is included if present
|
||||
const modelNumberInput = document.getElementById('modelNumber');
|
||||
if (modelNumberInput && modelNumberInput.value.trim() !== '') {
|
||||
formData.set('model_number', modelNumberInput.value.trim());
|
||||
}
|
||||
|
||||
// Handle warranty type - use custom value if "other" is selected
|
||||
const warrantyTypeSelect = document.getElementById('warrantyType');
|
||||
@@ -6359,6 +6379,15 @@ function saveWarranty() {
|
||||
formData.append('notes', '');
|
||||
}
|
||||
|
||||
// Add model number to form data (optional)
|
||||
const editModelNumber = document.getElementById('editModelNumber');
|
||||
if (editModelNumber && editModelNumber.value.trim() !== '') {
|
||||
formData.append('model_number', editModelNumber.value.trim());
|
||||
} else {
|
||||
// Explicitly clear if empty
|
||||
formData.append('model_number', '');
|
||||
}
|
||||
|
||||
// Add vendor/retailer to form data
|
||||
const editVendorInput = document.getElementById('editVendor'); // Use the correct ID
|
||||
formData.append('vendor', editVendorInput ? editVendorInput.value.trim() : ''); // Use the correct variable
|
||||
|
||||
Reference in New Issue
Block a user