feat: add PlatformSettings for pagination and vendor filter improvements
Platform Settings: - Add PlatformSettings utility in init-alpine.js with 5-min cache - Add Display tab in /admin/settings for rows_per_page config - Integrate PlatformSettings.getRowsPerPage() in all paginated pages - Standardize default per_page to 20 across all admin pages - Add documentation at docs/frontend/shared/platform-settings.md Architecture Rules: - Add JS-010: enforce PlatformSettings usage for pagination - Add JS-011: enforce standard pagination structure - Add JS-012: detect double /api/v1 prefix in apiClient calls - Implement all rules in validate_architecture.py Vendor Filter (Tom Select): - Add vendor filter to marketplace-products, vendor-products, customers, inventory, and vendor-themes pages - Add selectedVendor display panel with clear button - Add localStorage persistence for vendor selection - Fix double /api/v1 prefix in vendor-selector.js Bug Fixes: - Remove duplicate PlatformSettings from utils.js - Fix customers.js pagination structure (page_size → per_page) - Fix code-quality-violations.js pagination structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -187,83 +187,8 @@ const Utils = {
|
||||
// ============================================================================
|
||||
// Platform Settings
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Platform settings cache and loader
|
||||
*/
|
||||
const PlatformSettings = {
|
||||
_settings: null,
|
||||
_loading: false,
|
||||
_loadPromise: null,
|
||||
|
||||
/**
|
||||
* Load platform display settings from API
|
||||
* @returns {Promise<Object>} Platform settings
|
||||
*/
|
||||
async load() {
|
||||
// Return cached settings if available
|
||||
if (this._settings) {
|
||||
return this._settings;
|
||||
}
|
||||
|
||||
// Return existing promise if already loading
|
||||
if (this._loadPromise) {
|
||||
return this._loadPromise;
|
||||
}
|
||||
|
||||
this._loading = true;
|
||||
this._loadPromise = (async () => {
|
||||
try {
|
||||
const response = await fetch('/api/v1/admin/settings/display/public');
|
||||
if (response.ok) {
|
||||
this._settings = await response.json();
|
||||
} else {
|
||||
// Default settings
|
||||
this._settings = { rows_per_page: 20 };
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to load platform settings, using defaults:', error);
|
||||
this._settings = { rows_per_page: 20 };
|
||||
}
|
||||
this._loading = false;
|
||||
return this._settings;
|
||||
})();
|
||||
|
||||
return this._loadPromise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get rows per page setting
|
||||
* @returns {number} Rows per page (default: 20)
|
||||
*/
|
||||
getRowsPerPage() {
|
||||
return this._settings?.rows_per_page || 20;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get rows per page synchronously (returns cached or default)
|
||||
* @returns {number} Rows per page
|
||||
*/
|
||||
get rowsPerPage() {
|
||||
return this._settings?.rows_per_page || 20;
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset cached settings (call after updating settings)
|
||||
*/
|
||||
reset() {
|
||||
this._settings = null;
|
||||
this._loadPromise = null;
|
||||
}
|
||||
};
|
||||
|
||||
// Load settings on page load
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
PlatformSettings.load();
|
||||
});
|
||||
|
||||
// Make available globally
|
||||
window.PlatformSettings = PlatformSettings;
|
||||
// Note: PlatformSettings is defined in init-alpine.js for admin pages
|
||||
window.Utils = Utils;
|
||||
|
||||
// Export for modules
|
||||
|
||||
@@ -66,7 +66,7 @@ function waitForTomSelect(callback, maxRetries = 20, retryDelay = 100) {
|
||||
* @param {number} options.minChars - Minimum characters before search (default: 2)
|
||||
* @param {number} options.maxOptions - Maximum options to show (default: 50)
|
||||
* @param {string} options.placeholder - Placeholder text
|
||||
* @param {string} options.apiEndpoint - API endpoint for search (default: '/api/v1/admin/vendors')
|
||||
* @param {string} options.apiEndpoint - API endpoint for search (default: '/admin/vendors')
|
||||
* @returns {Object} Controller object with setValue() and clear() methods
|
||||
*/
|
||||
function initVendorSelector(selectElement, options = {}) {
|
||||
@@ -79,7 +79,7 @@ function initVendorSelector(selectElement, options = {}) {
|
||||
minChars: options.minChars || 2,
|
||||
maxOptions: options.maxOptions || 50,
|
||||
placeholder: options.placeholder || selectElement.getAttribute('placeholder') || 'Search vendor by name or code...',
|
||||
apiEndpoint: options.apiEndpoint || '/api/v1/admin/vendors',
|
||||
apiEndpoint: options.apiEndpoint || '/admin/vendors', // Note: apiClient adds /api/v1 prefix
|
||||
onSelect: options.onSelect || (() => {}),
|
||||
onClear: options.onClear || (() => {})
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user