From 1c214c5f060b1075c8692cf6529d4813c634966f Mon Sep 17 00:00:00 2001 From: Bastian Wagner Date: Tue, 4 Aug 2026 08:53:05 +0200 Subject: [PATCH] feat: wire cashbox export and subscription dialogs into Cashbox page Adds an Export button (opens CashboxExportDialog directly) plus a secondary menu (opens CashboxExportSubscriptionDialog) to the journal toolbar, gated by the existing canBook permission signal. --- .../app/features/team/cashbox/cashbox.html | 19 ++++++++++++++ .../app/features/team/cashbox/cashbox.spec.ts | 25 +++++++++++++++++++ .../src/app/features/team/cashbox/cashbox.ts | 16 ++++++++++++ 3 files changed, 60 insertions(+) diff --git a/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox.html b/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox.html index d2a89b5..83715e3 100644 --- a/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox.html +++ b/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox.html @@ -178,6 +178,25 @@ } + @if (canBook()) { + + + + + + } { expect.objectContaining({ amount: 0, note: '', type: 11 }), ); }); + + it('opens the cashbox export dialog when the treasurer clicks Export', async () => { + const { fixture, dialog } = await setup(); + fixture.detectChanges(); + + const exportButton = [...(fixture.nativeElement as HTMLElement).querySelectorAll('button')].find( + (btn) => btn.textContent?.includes('Export'), + ); + exportButton?.click(); + + expect(dialog.open).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ data: { teamId: expect.any(Number) } }), + ); + }); + + it('hides the Export button from a member without booking rights', async () => { + const { fixture } = await setup(1); + fixture.detectChanges(); + + const exportButton = [...(fixture.nativeElement as HTMLElement).querySelectorAll('button')].find( + (btn) => btn.textContent?.includes('Export'), + ); + expect(exportButton).toBeUndefined(); + }); }); diff --git a/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox.ts b/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox.ts index dfcfbde..18a0947 100644 --- a/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox.ts +++ b/myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox.ts @@ -10,6 +10,7 @@ import { MatDialog } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; +import { MatMenuModule } from '@angular/material/menu'; import { MatSelectModule } from '@angular/material/select'; import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; import { AgGridAngular } from 'ag-grid-angular'; @@ -38,6 +39,8 @@ import { } from '../../../models/transaction.model'; import { ConfirmDialog, ConfirmDialogData } from '../../../shared/confirm-dialog/confirm-dialog'; import { ContextHelp } from '../../../shared/context-help/context-help'; +import { CashboxExportDialog } from './cashbox-export-dialog/cashbox-export-dialog'; +import { CashboxExportSubscriptionDialog } from './cashbox-export-subscription-dialog/cashbox-export-subscription-dialog'; import '../../../shared/ag-grid/ag-grid-modules'; import { teamwalletGridTheme } from '../../../shared/ag-grid/ag-grid-theme'; import { AmountCellRenderer } from '../../../shared/ag-grid/amount-cell-renderer'; @@ -72,6 +75,7 @@ const JOURNAL_TYPE_OPTIONS: { value: string; label: string }[] = [ MatFormFieldModule, MatIconModule, MatInputModule, + MatMenuModule, MatSelectModule, MatSnackBarModule, ContextHelp, @@ -396,6 +400,18 @@ export class Cashbox { }); } + protected openExportDialog(): void { + const teamId = this.team()?.id; + if (!teamId) return; + this.dialog.open(CashboxExportDialog, { data: { teamId } }); + } + + protected openExportSubscriptionDialog(): void { + const teamId = this.team()?.id; + if (!teamId) return; + this.dialog.open(CashboxExportSubscriptionDialog, { data: { teamId } }); + } + protected typeLabel(type: string): string { return ( {