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:
@@ -145,6 +145,143 @@ javascript_rules:
|
||||
exceptions:
|
||||
- "utils.js"
|
||||
|
||||
- id: "JS-010"
|
||||
name: "Use PlatformSettings for pagination rows per page"
|
||||
severity: "error"
|
||||
description: |
|
||||
All pages with tables MUST use window.PlatformSettings.getRowsPerPage()
|
||||
to load the platform-configured rows per page setting. This ensures
|
||||
consistent pagination behavior across the entire admin and vendor interface.
|
||||
|
||||
The setting is configured at /admin/settings under the Display tab.
|
||||
Settings are cached client-side for 5 minutes to minimize API calls.
|
||||
|
||||
Required pattern in init() method:
|
||||
async init() {
|
||||
// Guard against multiple initialization
|
||||
if (window._pageNameInitialized) return;
|
||||
window._pageNameInitialized = true;
|
||||
|
||||
// REQUIRED: Load platform settings for pagination
|
||||
if (window.PlatformSettings) {
|
||||
this.pagination.per_page = await window.PlatformSettings.getRowsPerPage();
|
||||
}
|
||||
|
||||
await this.loadData();
|
||||
}
|
||||
|
||||
WRONG (hardcoded pagination):
|
||||
pagination: {
|
||||
page: 1,
|
||||
per_page: 50, // Hardcoded!
|
||||
total: 0
|
||||
}
|
||||
|
||||
RIGHT (platform settings):
|
||||
pagination: {
|
||||
page: 1,
|
||||
per_page: 20, // Default, overridden by PlatformSettings
|
||||
total: 0
|
||||
}
|
||||
|
||||
async init() {
|
||||
if (window.PlatformSettings) {
|
||||
this.pagination.per_page = await window.PlatformSettings.getRowsPerPage();
|
||||
}
|
||||
}
|
||||
|
||||
Documentation: docs/frontend/shared/platform-settings.md
|
||||
pattern:
|
||||
file_pattern: "static/admin/js/**/*.js"
|
||||
required_in_pages_with_pagination:
|
||||
- "PlatformSettings\\.getRowsPerPage"
|
||||
- "window\\.PlatformSettings"
|
||||
exceptions:
|
||||
- "init-alpine.js"
|
||||
- "init-api-client.js"
|
||||
- "settings.js"
|
||||
|
||||
- id: "JS-011"
|
||||
name: "Use standard pagination object structure"
|
||||
severity: "error"
|
||||
description: |
|
||||
All pages with tables MUST use the standard nested pagination object
|
||||
structure. This ensures compatibility with the pagination macro and
|
||||
consistent behavior across all pages.
|
||||
|
||||
REQUIRED structure:
|
||||
pagination: {
|
||||
page: 1,
|
||||
per_page: 20,
|
||||
total: 0,
|
||||
pages: 0
|
||||
}
|
||||
|
||||
WRONG (flat structure):
|
||||
page: 1,
|
||||
limit: 20,
|
||||
total: 0,
|
||||
skip: 0
|
||||
|
||||
WRONG (different property names):
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 20
|
||||
}
|
||||
|
||||
Required computed properties:
|
||||
- totalPages
|
||||
- startIndex
|
||||
- endIndex
|
||||
- pageNumbers
|
||||
|
||||
Required methods:
|
||||
- previousPage()
|
||||
- nextPage()
|
||||
- goToPage(pageNum)
|
||||
|
||||
Documentation: docs/frontend/shared/pagination.md
|
||||
pattern:
|
||||
file_pattern: "static/**/js/**/*.js"
|
||||
required_in_pages_with_pagination:
|
||||
- "pagination:"
|
||||
- "pagination\\.page"
|
||||
- "pagination\\.per_page"
|
||||
anti_patterns_in_pagination_pages:
|
||||
- "^\\s*page:\\s*\\d"
|
||||
- "^\\s*limit:\\s*\\d"
|
||||
- "^\\s*skip:\\s*"
|
||||
exceptions:
|
||||
- "init-alpine.js"
|
||||
|
||||
- id: "JS-012"
|
||||
name: "Do not include /api/v1 prefix in API endpoints"
|
||||
severity: "error"
|
||||
description: |
|
||||
When using apiClient.get(), apiClient.post(), etc., do NOT include
|
||||
the /api/v1 prefix in the endpoint path. The apiClient automatically
|
||||
prepends this prefix.
|
||||
|
||||
CORRECT:
|
||||
apiClient.get('/admin/vendors')
|
||||
apiClient.post('/admin/products')
|
||||
const apiEndpoint = '/admin/vendors'
|
||||
|
||||
WRONG (causes double prefix /api/v1/api/v1/...):
|
||||
apiClient.get('/api/v1/admin/vendors')
|
||||
const apiEndpoint = '/api/v1/admin/vendors'
|
||||
|
||||
Exception: Direct fetch() calls without apiClient should use full path.
|
||||
|
||||
Documentation: docs/frontend/shared/api-client.md
|
||||
pattern:
|
||||
file_pattern: "static/**/js/**/*.js"
|
||||
anti_patterns:
|
||||
- "apiClient\\.(get|post|put|delete|patch)\\s*\\(\\s*['\"`]/api/v1"
|
||||
- "apiEndpoint.*=.*['\"`]/api/v1"
|
||||
exceptions:
|
||||
- "init-api-client.js"
|
||||
|
||||
# ============================================================================
|
||||
# TEMPLATE RULES (Jinja2)
|
||||
# ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user