Dashboard: Summenzeile unterhalb der gefilterten Liste ergänzen
Fügt eine optisch abgesetzte Summenzeile unter der Dashboard-Tabelle hinzu, die die Beträge der aktuell sichtbaren (per Spaltenfilter gefilterten) Einträge summiert und live aktualisiert. Schließt #6 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
5830fd85cb
commit
cd9477dc7c
3 changed files with 38 additions and 1 deletions
|
|
@ -8,6 +8,10 @@ Dokumentiere Ausgaben on-the-go als Webapp
|
||||||
- [ ] Zusammenfassen von mehreren Einträgen zu einer Aktie
|
- [ ] Zusammenfassen von mehreren Einträgen zu einer Aktie
|
||||||
- [ ] Prüfen ob APIKEYS leer sind und ggfs die Aktualisierung ausblenden
|
- [ ] Prüfen ob APIKEYS leer sind und ggfs die Aktualisierung ausblenden
|
||||||
|
|
||||||
|
## V.2.3
|
||||||
|
|
||||||
|
- [X] Listen mit Spaltenfiltern (Dashboard) zeigen unterhalb eine optisch abgesetzte Summenzeile, die die Beträge der aktuell sichtbaren (gefilterten) Einträge in der Spalte "Betrag" aufsummiert.
|
||||||
|
|
||||||
## V.2.2
|
## V.2.2
|
||||||
|
|
||||||
- [X] Unit-Tests (PHPUnit) für die wichtigsten Funktionen, gebündelt in `html/lib/fscash.php`: Monatsnavigation, Admin-/Aktien-Rollenprüfung, Aktien-GuV-Berechnung, OpenFIGI-/Alpha-Vantage-Antwortauswertung, Eingabevalidierung, CSV-Export und Migrations-Logik (siehe Abschnitt "Tests" unten).
|
- [X] Unit-Tests (PHPUnit) für die wichtigsten Funktionen, gebündelt in `html/lib/fscash.php`: Monatsnavigation, Admin-/Aktien-Rollenprüfung, Aktien-GuV-Berechnung, OpenFIGI-/Alpha-Vantage-Antwortauswertung, Eingabevalidierung, CSV-Export und Migrations-Logik (siehe Abschnitt "Tests" unten).
|
||||||
|
|
|
||||||
|
|
@ -351,6 +351,14 @@ tr.filter-row th {
|
||||||
border-color: var(--primary-color);
|
border-color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Summenzeile unterhalb gefilterter Listen */
|
||||||
|
tr.sum-row td {
|
||||||
|
background: #eef3f8;
|
||||||
|
font-weight: 700;
|
||||||
|
border-top: 2px solid var(--primary-color);
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Button */
|
/* Button */
|
||||||
.btn-xr {
|
.btn-xr {
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@ sort($filterZahlweise, SORT_STRING | SORT_FLAG_CASE);
|
||||||
<td class="hide-on-mobile"><?= htmlspecialchars($entry['kategorie'] ?? '') ?></td>
|
<td class="hide-on-mobile"><?= htmlspecialchars($entry['kategorie'] ?? '') ?></td>
|
||||||
<td><?= htmlspecialchars($entry['zahlweise'] ?? '') ?></td>
|
<td><?= htmlspecialchars($entry['zahlweise'] ?? '') ?></td>
|
||||||
<td><?= htmlspecialchars($entry['subject']) ?></td>
|
<td><?= htmlspecialchars($entry['subject']) ?></td>
|
||||||
<td class="align-right"><?= htmlspecialchars( number_format($entry['amount'], 2, ',', '.')) ?></td>
|
<td class="align-right" data-amount="<?= htmlspecialchars($entry['amount']) ?>"><?= htmlspecialchars( number_format($entry['amount'], 2, ',', '.')) ?></td>
|
||||||
<td class="hide-on-mobile"><?= htmlspecialchars($entry['note']) ?></td>
|
<td class="hide-on-mobile"><?= htmlspecialchars($entry['note']) ?></td>
|
||||||
<td class="hide-on-mobile">
|
<td class="hide-on-mobile">
|
||||||
<a href="edit_entry.php?id=<?= $entry['id'] ?>">
|
<a href="edit_entry.php?id=<?= $entry['id'] ?>">
|
||||||
|
|
@ -208,6 +208,19 @@ sort($filterZahlweise, SORT_STRING | SORT_FLAG_CASE);
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr class="sum-row">
|
||||||
|
<td>Summe</td>
|
||||||
|
<td class="hide-on-mobile"></td>
|
||||||
|
<td class="hide-on-mobile"></td>
|
||||||
|
<td class="hide-on-mobile"></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td class="align-right" id="sum-value">0,00</td>
|
||||||
|
<td class="hide-on-mobile"></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<!-- Neu-Button -->
|
<!-- Neu-Button -->
|
||||||
|
|
@ -224,6 +237,7 @@ document.querySelector('.hamburger').addEventListener('click', function() {
|
||||||
(function() {
|
(function() {
|
||||||
const filters = document.querySelectorAll('.column-filter');
|
const filters = document.querySelectorAll('.column-filter');
|
||||||
const rows = document.querySelectorAll('#entries-body tr');
|
const rows = document.querySelectorAll('#entries-body tr');
|
||||||
|
const sumValue = document.getElementById('sum-value');
|
||||||
// Mehrfach-Kategorie-Vorauswahl, z. B. per Link aus dem Personenreport (Kategorie-Select kann nur einen Wert anzeigen)
|
// Mehrfach-Kategorie-Vorauswahl, z. B. per Link aus dem Personenreport (Kategorie-Select kann nur einen Wert anzeigen)
|
||||||
const presetKategorien = <?= json_encode(array_map('strtolower', $presetKategorien)) ?>;
|
const presetKategorien = <?= json_encode(array_map('strtolower', $presetKategorien)) ?>;
|
||||||
|
|
||||||
|
|
@ -232,6 +246,7 @@ document.querySelector('.hamburger').addEventListener('click', function() {
|
||||||
.map(f => ({ col: parseInt(f.dataset.col, 10), value: f.value.trim().toLowerCase() }))
|
.map(f => ({ col: parseInt(f.dataset.col, 10), value: f.value.trim().toLowerCase() }))
|
||||||
.filter(f => f.value !== '');
|
.filter(f => f.value !== '');
|
||||||
|
|
||||||
|
let sum = 0;
|
||||||
rows.forEach(row => {
|
rows.forEach(row => {
|
||||||
const cells = row.children;
|
const cells = row.children;
|
||||||
const visible = activeFilters.every(f => {
|
const visible = activeFilters.every(f => {
|
||||||
|
|
@ -240,7 +255,17 @@ document.querySelector('.hamburger').addEventListener('click', function() {
|
||||||
return cell.textContent.trim().toLowerCase().includes(f.value);
|
return cell.textContent.trim().toLowerCase().includes(f.value);
|
||||||
}) && (presetKategorien.length === 0 || (cells[3] && presetKategorien.includes(cells[3].textContent.trim().toLowerCase())));
|
}) && (presetKategorien.length === 0 || (cells[3] && presetKategorien.includes(cells[3].textContent.trim().toLowerCase())));
|
||||||
row.style.display = visible ? '' : 'none';
|
row.style.display = visible ? '' : 'none';
|
||||||
|
if (visible) {
|
||||||
|
const amountCell = cells[6];
|
||||||
|
if (amountCell) {
|
||||||
|
sum += parseFloat(amountCell.dataset.amount) || 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (sumValue) {
|
||||||
|
sumValue.textContent = sum.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filters.forEach(f => {
|
filters.forEach(f => {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue