feat: Kontenreihenfolge selbst bestimmen
Die Liste stand in der Anlegereihenfolge, die selten die gewuenschte ist.
Neuer Endpunkt PUT /accounts/order nimmt die IDs in der gewuenschten Folge
und schreibt die Position; er muss vor /{account_id} stehen, sonst faengt
die ID-Route den Pfad ab. Fremde IDs werden abgewiesen.
In der Kontenliste zwei Pfeile je Zeile, optimistisch sortiert, damit die
Liste beim Klicken nicht springt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -193,6 +193,22 @@ export default function Accounts() {
|
||||
}
|
||||
}
|
||||
|
||||
// Reihenfolge per Pfeil: die Liste stand sonst in der Anlegereihenfolge.
|
||||
// Optimistisch umsortieren, damit die Liste nicht bei jedem Klick springt.
|
||||
async function verschiebe(index, richtung) {
|
||||
const ziel = index + richtung;
|
||||
if (ziel < 0 || ziel >= accounts.length) return;
|
||||
const neu = [...accounts];
|
||||
[neu[index], neu[ziel]] = [neu[ziel], neu[index]];
|
||||
setAccounts(neu);
|
||||
try {
|
||||
await api.setAccountOrder(neu.map((a) => a.id));
|
||||
} catch (e) {
|
||||
toast(e.message, "error");
|
||||
laden();
|
||||
}
|
||||
}
|
||||
|
||||
async function loeschen(acc) {
|
||||
if (!(await confirm({ title: t("common.delete"), message: t("accounts.deleteConfirm"), danger: true, confirmLabel: t("common.delete") }))) return;
|
||||
try {
|
||||
@@ -223,7 +239,7 @@ export default function Accounts() {
|
||||
<strong>{formatMoney(total, baseCurrency)}</strong>
|
||||
</div>
|
||||
<div className="account-list">
|
||||
{accounts.map((a) => (
|
||||
{accounts.map((a, i) => (
|
||||
<div className="account-row" key={a.id}>
|
||||
<IconChip name={a.icon} color={a.color} />
|
||||
<div className="named-text grow">
|
||||
@@ -236,6 +252,14 @@ export default function Accounts() {
|
||||
<Money cents={a.balance_cents} currency={a.currency}
|
||||
baseCents={a.balance_base_cents} baseCurrency={baseCurrency} />
|
||||
<div className="row-actions">
|
||||
<button className="btn sm ghost" title={t("accounts.moveUp")}
|
||||
disabled={i === 0} onClick={() => verschiebe(i, -1)}>
|
||||
<Icon name="chevron-up" size={15} />
|
||||
</button>
|
||||
<button className="btn sm ghost" title={t("accounts.moveDown")}
|
||||
disabled={i === accounts.length - 1} onClick={() => verschiebe(i, 1)}>
|
||||
<Icon name="chevron-down" size={15} />
|
||||
</button>
|
||||
<button className="btn sm ghost" title={t("common.edit")} onClick={() => openEdit(a)}>
|
||||
<Icon name="edit" size={15} />
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user