fix: Standardize Trial Balance table styling and add export functionality

- Refactor table columns from grouped (Debit+Credit vertical) to separate columns for better scannability
- Replace custom HTML buttons with PrimeVue Button components (icon + label)
- Move filter action buttons to separate row below filters (matches InvoicesView pattern)
- Add Excel and PDF export functionality that fetches ALL data (not just current page)
- Update CSS_PATTERNS.md with unified table column structure and filter button patterns
- Update CLAUDE.md with table styling requirements and anti-patterns

This ensures visual consistency across all table views in the application.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-20 01:50:41 +02:00
parent fff430acf0
commit 86900d7750
3 changed files with 386 additions and 59 deletions

View File

@@ -461,6 +461,158 @@ Drag-and-drop file upload area.
- `.invoice-paid` - Light green for paid invoices
- `.invoice-overdue` - Light red for overdue invoices
### ⚠️ Important: Unified Table Column Structure
**All tables in the application MUST follow this structure for consistency:**
**DO: One value per column**
```html
<!-- CORRECT: Separate columns for related data -->
<DataTable :value="data">
<Column field="account" header="Account" sortable></Column>
<Column field="debit" header="Debit" sortable>
<template #body="slotProps">
{{ formatCurrency(slotProps.data.debit) }}
</template>
</Column>
<Column field="credit" header="Credit" sortable>
<template #body="slotProps">
{{ formatCurrency(slotProps.data.credit) }}
</template>
</Column>
</DataTable>
```
**DON'T: Multiple values stacked vertically in single column**
```html
<!-- WRONG: Grouping debit/credit in one column -->
<Column header="Balance">
<template #body="slotProps">
<div class="balance-group">
<div>D: {{ slotProps.data.debit }}</div>
<div>C: {{ slotProps.data.credit }}</div>
</div>
</template>
</Column>
```
**Rationale:**
- Maintains visual consistency across all views
- Improves scannability and data comparison
- Better for sorting and filtering
- Follows established patterns (see InvoicesView, MaturityAndDetailsCard)
### Table Filter and Action Buttons
**Standard pattern: PrimeVue buttons with icon + label, separate row below filters**
All filter-related buttons (clear filters, export, refresh) MUST be:
-**PrimeVue Button** components (not HTML `<button>`)
-**Icon + label** (both icon and text visible)
-**Separate row below filters** (not on same row with inputs)
-**Standard PrimeVue styling** (outlined buttons with contextual colors)
```vue
<div class="form">
<div class="form-row">
<!-- Filter inputs -->
<div class="form-col">
<div class="form-group">
<label class="form-label">Filter Name</label>
<InputText v-model="filter" placeholder="Filter..." class="w-full" />
</div>
</div>
<!-- More filter inputs... -->
</div>
<!-- Action Buttons (separate row below filters!) -->
<div class="filters-actions">
<Button
icon="pi pi-filter-slash"
label="Resetează Filtre"
class="p-button-outlined p-button-secondary"
@click="clearFilters"
/>
<Button
icon="pi pi-file-excel"
label="Export Excel"
class="p-button-outlined p-button-success"
@click="exportExcel"
:disabled="!hasData"
/>
<Button
icon="pi pi-file-pdf"
label="Export PDF"
class="p-button-outlined p-button-danger"
@click="exportPDF"
:disabled="!hasData"
/>
<Button
icon="pi pi-refresh"
label="Actualizează"
:loading="isLoading"
@click="refresh"
/>
</div>
</div>
```
**CSS Styles:**
```css
.filters-actions {
display: flex;
gap: 1rem;
justify-content: flex-end;
padding-top: 1rem;
border-top: 1px solid var(--surface-border);
}
/* Responsive */
@media (max-width: 768px) {
.filters-actions {
flex-direction: column;
}
}
```
**CRITICAL: Export ALL Data, Not Just Current Page**
Export functions MUST fetch ALL data from the backend, not just the current page:
```javascript
// ❌ WRONG: Only exports current page
const exportExcel = () => {
const data = store.currentPageData; // Only current page!
exportToExcel(data, 'filename');
};
// ✅ CORRECT: Exports ALL data
const exportExcel = async () => {
// Fetch ALL data with large page_size or no pagination
const params = {
...filters,
page: 1,
page_size: 999999 // Get all data
};
const response = await apiService.get('/endpoint', { params });
const allData = response.data.items;
exportToExcel(allData, 'filename');
toast.add({
summary: "Export reușit",
detail: `${allData.length} înregistrări exportate`
});
};
```
**Use Cases:**
- Financial reports (invoices, trial balance, etc.)
- Detailed data tables with multiple columns
- Any table with filters and pagination
---
## Dashboard Patterns