diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 8981661..7084e4e 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -54,9 +54,9 @@ import {WidgetsBarComponent} from './eventpage/widgets-section/widgets-bar/widge import {MatTabsModule} from "@angular/material/tabs"; import { ParticipantsSidenavComponent } from './eventpage/participants-sidenav/participants-sidenav.component'; import { ParticipantCardComponent } from './eventpage/participants-sidenav/participant-card/participant-card.component'; -import { EinkaufslisteWidgetComponent } from './widgets/einkaufsliste-widget/einkaufsliste-widget.component'; -import { DefaultShoppingPageComponent } from './widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component'; -import { AddEintragDialogComponent } from './widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component'; +import { ShoppingListWidgetComponent } from './widgets/shopping-list-widget/shopping-list-widget.component'; +import { DefaultShoppingPageComponent } from './widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component'; +import { AddEntryDialogComponent } from './widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component'; import { MatDatepicker, MatDatepickerActions, MatDatepickerApply, MatDatepickerCancel, MatDatepickerToggle, @@ -69,9 +69,9 @@ import { CreateEditExpenseEntryDialogComponent } from './widgets/expense-split-w import {MatSelectModule} from "@angular/material/select"; import { ExpenseEntryCardComponent } from './widgets/expense-split-widget/expense-entry-card/expense-entry-card.component'; import { DeleteEntryConfirmationDialogComponent } from './widgets/expense-split-widget/delete-entry-confirmation-dialog/delete-entry-confirmation-dialog.component'; -import { EditEintragDialogComponent } from './widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component'; -import { EinkauflisteEintragListItemComponent } from './widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component'; -import {MatCheckbox} from "@angular/material/checkbox"; +import { EditEntryDialogComponent } from './widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component'; +import { ShoppingListEntryListItemComponent } from './widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component'; +import {MatCheckboxModule} from "@angular/material/checkbox"; registerLocaleData(localeDe); @@ -124,11 +124,11 @@ function loadMapApi(httpClient: HttpClient) { CreateEditExpenseEntryDialogComponent, ExpenseEntryCardComponent, DeleteEntryConfirmationDialogComponent, - EinkaufslisteWidgetComponent, + ShoppingListWidgetComponent, DefaultShoppingPageComponent, - AddEintragDialogComponent, - EditEintragDialogComponent, - EinkauflisteEintragListItemComponent, + AddEntryDialogComponent, + EditEntryDialogComponent, + ShoppingListEntryListItemComponent, ], imports: [ BrowserModule, @@ -172,7 +172,7 @@ function loadMapApi(httpClient: HttpClient) { ReactiveFormsModule, MatNativeDateModule, MatSelectModule, - MatCheckbox + MatCheckboxModule ], providers: [ { diff --git a/frontend/src/app/eventpage/widgets-section/widget-container/widget-container.component.html b/frontend/src/app/eventpage/widgets-section/widget-container/widget-container.component.html index 4878356..c9b27c9 100644 --- a/frontend/src/app/eventpage/widgets-section/widget-container/widget-container.component.html +++ b/frontend/src/app/eventpage/widgets-section/widget-container/widget-container.component.html @@ -9,7 +9,7 @@ @case (WidgetType.SHOPPING_LIST) { } diff --git a/frontend/src/app/widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component.html b/frontend/src/app/widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component.html deleted file mode 100644 index dfb966d..0000000 --- a/frontend/src/app/widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component.html +++ /dev/null @@ -1,14 +0,0 @@ -
- no Shopping-List Bild -

Kein Einkaufseintrag angelegt

-

Lege einen Einkaufseintrag über dieses - - an

-
diff --git a/frontend/src/app/widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component.scss b/frontend/src/app/widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component.scss deleted file mode 100644 index 3942853..0000000 --- a/frontend/src/app/widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component.scss +++ /dev/null @@ -1,8 +0,0 @@ -.page-container{ - display: flex; - flex-direction: column; - align-items: center; -} -img{ - margin-top: 10px; -} diff --git a/frontend/src/app/widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component.ts b/frontend/src/app/widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component.ts deleted file mode 100644 index a562438..0000000 --- a/frontend/src/app/widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component.ts +++ /dev/null @@ -1,37 +0,0 @@ -import {Component, EventEmitter, Input, Output} from '@angular/core'; -import {AddEintragDialogComponent} from "../add-eintrag-dialog/add-eintrag-dialog.component"; -import {MatDialog} from "@angular/material/dialog"; -import {EinkaufslisteWidgetComponent} from "../einkaufsliste-widget.component"; -import {ShoppingWidget} from "../../../../model/shoppinglist-widget"; -import {BaseWidget} from "../../../../model/common-widget"; - -@Component({ - selector: 'app-default-shopping-page', - templateUrl: './default-shopping-page.component.html', - styleUrl: './default-shopping-page.component.scss' -}) -export class DefaultShoppingPageComponent { - @Input() - eventId!: string; - - @Input({transform: (value: BaseWidget): ShoppingWidget => value as ShoppingWidget}) - widget!: ShoppingWidget; - - @Output() - onWidgetUpdated = new EventEmitter(); - - constructor( - private dialog: MatDialog, - private root: EinkaufslisteWidgetComponent - ) { - } - - openAddEntryDialog() { - const dialogRef = this.dialog.open(AddEintragDialogComponent, {width: "400px"}); - dialogRef.afterClosed().subscribe(addCommand => { - if (addCommand) { - this.root.addEntry(addCommand); - } - }); - } -} diff --git a/frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.html b/frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.html deleted file mode 100644 index 1bc1f32..0000000 --- a/frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.html +++ /dev/null @@ -1,25 +0,0 @@ -

Einkaufseintrag bearbeiten

- -
-

Beschreibung*

- - - -

Menge

- - - -
-
- - - - - - diff --git a/frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.ts b/frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.ts deleted file mode 100644 index 5dbefa1..0000000 --- a/frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.ts +++ /dev/null @@ -1,92 +0,0 @@ -import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core'; -import {Entry, ShoppingWidget} from "../../../../model/shoppinglist-widget"; -import {EditEintragDialogComponent} from "../edit-eintrag-dialog/edit-eintrag-dialog.component"; -import {MatDialog} from "@angular/material/dialog"; -import {UserService} from "../../../../services/user.service"; -import {EinkaufslisteWidgetService} from "../../../../services/widgets/einkaufsliste-widget.service"; -import {MatSnackBar} from "@angular/material/snack-bar"; - -@Component({ - selector: 'app-einkaufliste-eintrag-list-item', - templateUrl: './einkaufliste-eintrag-list-item.component.html', - styleUrl: './einkaufliste-eintrag-list-item.component.scss' -}) -export class EinkauflisteEintragListItemComponent implements OnInit, OnChanges{ - @Input() item!: Entry; - @Input() eventId!: string; - @Input() widgetId!: string; - @Output() onWidgetUpdated = new EventEmitter(); - - username: string | null = null; - - constructor( - private dialog: MatDialog, - private userService: UserService, - private service: EinkaufslisteWidgetService, - private _snackbar: MatSnackBar - ) { - } - - ngOnInit() { - this.loadUsername(); - } - - ngOnChanges(changes: SimpleChanges) { - if (changes['item'] && !changes['item'].firstChange) { - this.loadUsername(); - } - } - - loadUsername() { - if (!this.item.buyerId) { - this.username = null; // Falls kein buyerId vorhanden ist, Username zurücksetzen - return; - } - - this.userService.fetchUserById(this.item.buyerId).subscribe({ - next: user => { - this.username = [user.firstName, user.lastName].filter(x => x).join(" "); - }, - error: error => console.error(error) - }); - } - - editEntryDialog(){ - const dialogRef = this.dialog.open(EditEintragDialogComponent, { data: { entry: this.item},width: "400px"}); - dialogRef.afterClosed().subscribe(updateCommand => { - if (updateCommand) { - console.log(this.eventId); - this.service.editEntry(this.eventId, this.widgetId, this.item.id, updateCommand).subscribe({ - next: response => { - this.onWidgetUpdated.emit(response); - this.showMessage("Eintrag bearbeitet") - }, - error: error => { - console.error('Error:', error); - this.showMessage("Fehler beim Bearbeiten", "error") - } - }); - } - }); - } - - showMessage(messageToshow:string, snackBarClass:string="successfull"){ - this._snackbar.open(messageToshow, 'schließen',{ - duration: 5000, - panelClass:snackBarClass - }) - } - - deleteEntry() { - this.service.deleteEntry(this.eventId,this.widgetId,this.item.id).subscribe({ - next: response => { - this.onWidgetUpdated.emit(response); - this.showMessage("Eintrag gelöscht") - }, - error: error => { - console.error('Error:', error); - this.showMessage("Fehler beim Löschen", "error") - } - }); - } -} diff --git a/frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.html b/frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.html deleted file mode 100644 index 9500861..0000000 --- a/frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.html +++ /dev/null @@ -1,24 +0,0 @@ -
- -
    - @for (item of eintraege; track item.id) { -
  • - - -
  • - } -
-
- - - - - - - diff --git a/frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.ts b/frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.ts deleted file mode 100644 index 42a061e..0000000 --- a/frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.ts +++ /dev/null @@ -1,85 +0,0 @@ -import {Component, EventEmitter, Input, Output} from '@angular/core'; -import {BaseWidget} from "../../../model/common-widget"; -import {Entry, EntryCommand, EntryCheckCommand, ShoppingWidget} from "../../../model/shoppinglist-widget"; -import {AddEintragDialogComponent} from "./add-eintrag-dialog/add-eintrag-dialog.component"; -import {MatDialog} from "@angular/material/dialog"; -import {EinkaufslisteWidgetService} from "../../../services/widgets/einkaufsliste-widget.service"; -import {MatSnackBar} from "@angular/material/snack-bar"; -import {MatCheckboxChange} from "@angular/material/checkbox"; - -@Component({ - selector: 'app-einkaufsliste-widget', - templateUrl: './einkaufsliste-widget.component.html', - styleUrl: './einkaufsliste-widget.component.scss' -}) -export class EinkaufslisteWidgetComponent { - @Input() - eventId!: string; - - @Input({transform: (value: BaseWidget): ShoppingWidget => value as ShoppingWidget}) - widget!: ShoppingWidget; - - @Output() - onWidgetUpdated = new EventEmitter(); - - constructor( - private dialog: MatDialog, - private service: EinkaufslisteWidgetService, - private _snackbar: MatSnackBar - ) { - } - - openAddEntryDialog() { - const dialogRef = this.dialog.open(AddEintragDialogComponent, {width: "400px"}); - dialogRef.afterClosed().subscribe(addCommand => { - if (addCommand) { - this.addEntry(addCommand); - } - }); - } - - addEntry(addCommand: EntryCommand) { - if(addCommand) { - this.service.addEntry(this.eventId, this.widget.id, addCommand).subscribe({ - next: response => { - this.onWidgetUpdated.emit(response); - this.showMessage("Eintrag angelegt") - }, - error: error => { - console.error('Error:', error); - this.showMessage("Fehler beim Anlegen", "error") - } - }); - } - } - - get entries(): number { - return this.widget.entries.length; - } - - get eintraege() { - return this.widget.entries; - } - - showMessage(messageToshow:string, snackBarClass:string="successfull"){ - this._snackbar.open(messageToshow, 'schließen',{ - duration: 5000, - panelClass: snackBarClass - }) - } - - onCheckboxChange(item: Entry, event: MatCheckboxChange) { - const checkCommand: EntryCheckCommand = { - checked: event.checked - } - this.service.setBuyerId(this.eventId, this.widget.id, item, checkCommand).subscribe({ - next: response => { - console.log(response); - this.onWidgetUpdated.emit(response); - }, - error: error => { - console.error('Error:', error); - } - }); - } -} diff --git a/frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.html b/frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.html similarity index 78% rename from frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.html rename to frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.html index ecac6d1..4ed0fc6 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.html +++ b/frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.html @@ -6,7 +6,7 @@

Einkaufseintrag hinzufügen

Menge

- + @@ -14,12 +14,13 @@

Einkaufseintrag hinzufügen

- + diff --git a/frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.scss b/frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.scss similarity index 95% rename from frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.scss rename to frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.scss index 9e06500..385be78 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.scss +++ b/frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.scss @@ -8,6 +8,7 @@ .create-eintrag-container { display: flex; flex-direction: column; + gap: 0; } } diff --git a/frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.spec.ts b/frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.spec.ts similarity index 56% rename from frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.spec.ts rename to frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.spec.ts index af7e222..dd85d72 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.spec.ts +++ b/frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.spec.ts @@ -1,18 +1,18 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { AddEintragDialogComponent } from './add-eintrag-dialog.component'; +import { AddEntryDialogComponent } from './add-entry-dialog.component'; describe('AddEintragDialogComponent', () => { - let component: AddEintragDialogComponent; - let fixture: ComponentFixture; + let component: AddEntryDialogComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [AddEintragDialogComponent] + declarations: [AddEntryDialogComponent] }) .compileComponents(); - fixture = TestBed.createComponent(AddEintragDialogComponent); + fixture = TestBed.createComponent(AddEntryDialogComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.ts b/frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.ts similarity index 73% rename from frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.ts rename to frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.ts index c37add0..8df47dd 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.ts +++ b/frontend/src/app/widgets/shopping-list-widget/add-entry-dialog/add-entry-dialog.component.ts @@ -5,15 +5,15 @@ import {FormBuilder, FormGroup, Validators} from "@angular/forms"; @Component({ selector: 'app-add-eintrag-dialog', - templateUrl: './add-eintrag-dialog.component.html', - styleUrl: './add-eintrag-dialog.component.scss' + templateUrl: './add-entry-dialog.component.html', + styleUrl: './add-entry-dialog.component.scss' }) -export class AddEintragDialogComponent implements OnInit{ +export class AddEntryDialogComponent implements OnInit { form!: FormGroup; constructor( private fb: FormBuilder, - private dialogRef: MatDialogRef, + private dialogRef: MatDialogRef, ) { } @@ -22,11 +22,10 @@ export class AddEintragDialogComponent implements OnInit{ description: ['', Validators.required], amount: [null] }); - } closeDialog() { - if(this.form.valid) { + if (this.form.valid) { const addCommand: EntryCommand = { description: this.form.value.description, amount: this.form.value.amount diff --git a/frontend/src/app/widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component.html b/frontend/src/app/widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component.html new file mode 100644 index 0000000..08cb911 --- /dev/null +++ b/frontend/src/app/widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component.html @@ -0,0 +1,16 @@ +
+ no Shopping-List Bild +

Kein Einkaufseintrag angelegt

+

+ Lege einen Einkaufseintrag über dieses + + an +

+
diff --git a/frontend/src/app/widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component.scss b/frontend/src/app/widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component.scss new file mode 100644 index 0000000..40df952 --- /dev/null +++ b/frontend/src/app/widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component.scss @@ -0,0 +1,13 @@ +.page-container { + display: flex; + flex-direction: column; + align-items: center; + + p { + margin-top: 0; + } +} + +img { + margin-top: var(--size-12); +} diff --git a/frontend/src/app/widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component.spec.ts b/frontend/src/app/widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component.spec.ts similarity index 100% rename from frontend/src/app/widgets/einkaufsliste-widget/default-shopping-page/default-shopping-page.component.spec.ts rename to frontend/src/app/widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component.spec.ts diff --git a/frontend/src/app/widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component.ts b/frontend/src/app/widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component.ts new file mode 100644 index 0000000..33d2715 --- /dev/null +++ b/frontend/src/app/widgets/shopping-list-widget/default-shopping-page/default-shopping-page.component.ts @@ -0,0 +1,13 @@ +import {Component, EventEmitter, Output} from '@angular/core'; + +@Component({ + selector: 'app-default-shopping-page', + templateUrl: './default-shopping-page.component.html', + styleUrl: './default-shopping-page.component.scss' +}) +export class DefaultShoppingPageComponent { + + @Output() + onCreateEntryClicked = new EventEmitter(); + +} diff --git a/frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.html b/frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.html new file mode 100644 index 0000000..d037335 --- /dev/null +++ b/frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.html @@ -0,0 +1,26 @@ +

Einkaufseintrag bearbeiten

+ +
+

Beschreibung*

+ + + +

Menge

+ + + +
+
+ + + + + + diff --git a/frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.scss b/frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.scss similarity index 95% rename from frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.scss rename to frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.scss index 9e06500..385be78 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/add-eintrag-dialog/add-eintrag-dialog.component.scss +++ b/frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.scss @@ -8,6 +8,7 @@ .create-eintrag-container { display: flex; flex-direction: column; + gap: 0; } } diff --git a/frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.spec.ts b/frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.spec.ts similarity index 55% rename from frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.spec.ts rename to frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.spec.ts index 267d6c7..a5b3646 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.spec.ts +++ b/frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.spec.ts @@ -1,18 +1,18 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { EditEintragDialogComponent } from './edit-eintrag-dialog.component'; +import { EditEntryDialogComponent } from './edit-entry-dialog.component'; describe('EditEintragDialogComponent', () => { - let component: EditEintragDialogComponent; - let fixture: ComponentFixture; + let component: EditEntryDialogComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [EditEintragDialogComponent] + declarations: [EditEntryDialogComponent] }) .compileComponents(); - - fixture = TestBed.createComponent(EditEintragDialogComponent); + + fixture = TestBed.createComponent(EditEntryDialogComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.ts b/frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.ts similarity index 74% rename from frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.ts rename to frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.ts index b1fac98..48edc0f 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/edit-eintrag-dialog/edit-eintrag-dialog.component.ts +++ b/frontend/src/app/widgets/shopping-list-widget/edit-entry-dialog/edit-entry-dialog.component.ts @@ -1,21 +1,20 @@ import {Component, Inject, OnInit} from '@angular/core'; import {FormBuilder, FormGroup, Validators} from "@angular/forms"; -import {UserService} from "../../../../services/user.service"; import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog"; import {Entry, EntryCommand} from "../../../../model/shoppinglist-widget"; @Component({ selector: 'app-edit-eintrag-dialog', - templateUrl: './edit-eintrag-dialog.component.html', - styleUrl: './edit-eintrag-dialog.component.scss' + templateUrl: './edit-entry-dialog.component.html', + styleUrl: './edit-entry-dialog.component.scss' }) -export class EditEintragDialogComponent implements OnInit{ +export class EditEntryDialogComponent implements OnInit{ form!: FormGroup; entry: Entry; constructor( private fb: FormBuilder, - private dialogRef: MatDialogRef, + private dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: { entry:Entry} ) { this.entry = data.entry @@ -26,7 +25,6 @@ export class EditEintragDialogComponent implements OnInit{ description: [this.entry.description, Validators.required], amount: [this.entry.amount] }); - } closeDialog() { @@ -34,7 +32,7 @@ export class EditEintragDialogComponent implements OnInit{ const updateCommand: EntryCommand = { description: this.form.value.description, amount: this.form.value.amount - } + }; this.dialogRef.close(updateCommand); } } diff --git a/frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.html b/frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.html similarity index 55% rename from frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.html rename to frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.html index d151983..68a1345 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.html +++ b/frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.html @@ -1,23 +1,23 @@ -

{{item.description}}

-

{{item.amount}}

- @if(item.buyerId) { -

+

{{ item.description }}

+

{{ item.amount }}

+ @if (item.buyerId) { +

person - {{username}} -

- } + {{ buyer?.firstName }} {{ buyer?.lastName }} +

+ } - - diff --git a/frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.scss b/frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.scss similarity index 96% rename from frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.scss rename to frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.scss index 46a101e..6e05367 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.scss +++ b/frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.scss @@ -1,6 +1,5 @@ .einkaufliste-eintrag-card { display: flex; - flex-grow: 1; padding: 0; margin-right: var(--size-10); @@ -17,7 +16,6 @@ p { margin: 0; - flex: 1; text-align: left; } @@ -37,6 +35,7 @@ einkaufliste-eintrag-card-content-buyerProfile { display: flex; flex-direction: column; align-items: flex-start; + p { width: 100%; } @@ -50,6 +49,7 @@ einkaufliste-eintrag-card-content-buyerProfile { .einkaufliste-eintrag-card { padding: var(--size-10) 0; + button { position: absolute; top: var(--size-10); diff --git a/frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.spec.ts b/frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.spec.ts similarity index 51% rename from frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.spec.ts rename to frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.spec.ts index 214c562..022fb9c 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/einkaufliste-eintrag-list-item/einkaufliste-eintrag-list-item.component.spec.ts +++ b/frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.spec.ts @@ -1,18 +1,18 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { EinkauflisteEintragListItemComponent } from './einkaufliste-eintrag-list-item.component'; +import { ShoppingListEntryListItemComponent } from './shopping-list-entry-list-item.component'; describe('EinkauflisteEintragListItemComponent', () => { - let component: EinkauflisteEintragListItemComponent; - let fixture: ComponentFixture; + let component: ShoppingListEntryListItemComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [EinkauflisteEintragListItemComponent] + declarations: [ShoppingListEntryListItemComponent] }) .compileComponents(); - - fixture = TestBed.createComponent(EinkauflisteEintragListItemComponent); + + fixture = TestBed.createComponent(ShoppingListEntryListItemComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.ts b/frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.ts new file mode 100644 index 0000000..5e5fab3 --- /dev/null +++ b/frontend/src/app/widgets/shopping-list-widget/shopping-list-entry-list-item/shopping-list-entry-list-item.component.ts @@ -0,0 +1,24 @@ +import {Component, EventEmitter, Input, Output} from '@angular/core'; +import {Entry} from "../../../../model/shoppinglist-widget"; +import {Event} from "../../../../model/event"; +import {SimpleUser} from "../../../../model/user"; + +@Component({ + selector: 'app-einkaufliste-eintrag-list-item', + templateUrl: './shopping-list-entry-list-item.component.html', + styleUrl: './shopping-list-entry-list-item.component.scss' +}) +export class ShoppingListEntryListItemComponent { + @Input() item!: Entry; + @Input() eventData!: Event; + @Output() onEdit = new EventEmitter(); + @Output() onDelete = new EventEmitter(); + + get buyer(): SimpleUser | undefined { + if (!this.item.buyerId) { + return undefined; + } + return this.eventData.participants.find(p => p.id === this.item.buyerId); + } + +} diff --git a/frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.html b/frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.html new file mode 100644 index 0000000..634b412 --- /dev/null +++ b/frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.html @@ -0,0 +1,35 @@ +
+ +
    + @for (item of entries; track item.id) { +
  • + + +
  • + } +
+
+ + + + + + + diff --git a/frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.scss b/frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.scss similarity index 94% rename from frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.scss rename to frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.scss index 458c114..bdbc32d 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.scss +++ b/frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.scss @@ -9,7 +9,7 @@ button { border-radius: 12px; } -.einkaufliste-eintrag-liste{ +.einkaufliste-eintrag-liste { display: flex; flex-direction: column; gap: var(--size-10); diff --git a/frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.spec.ts b/frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.spec.ts similarity index 54% rename from frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.spec.ts rename to frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.spec.ts index 50a6120..162914f 100644 --- a/frontend/src/app/widgets/einkaufsliste-widget/einkaufsliste-widget.component.spec.ts +++ b/frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.spec.ts @@ -1,18 +1,18 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { EinkaufslisteWidgetComponent } from './einkaufsliste-widget.component'; +import { ShoppingListWidgetComponent } from './shopping-list-widget.component'; describe('EinkaufslisteWidgetComponent', () => { - let component: EinkaufslisteWidgetComponent; - let fixture: ComponentFixture; + let component: ShoppingListWidgetComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [EinkaufslisteWidgetComponent] + declarations: [ShoppingListWidgetComponent] }) .compileComponents(); - - fixture = TestBed.createComponent(EinkaufslisteWidgetComponent); + + fixture = TestBed.createComponent(ShoppingListWidgetComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.ts b/frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.ts new file mode 100644 index 0000000..03d2abe --- /dev/null +++ b/frontend/src/app/widgets/shopping-list-widget/shopping-list-widget.component.ts @@ -0,0 +1,120 @@ +import {Component, EventEmitter, Input, Output} from '@angular/core'; +import {BaseWidget} from "../../../model/common-widget"; +import {Entry, EntryCommand, EntryCheckCommand, ShoppingWidget} from "../../../model/shoppinglist-widget"; +import {AddEntryDialogComponent} from "./add-entry-dialog/add-entry-dialog.component"; +import {MatDialog} from "@angular/material/dialog"; +import {EinkaufslisteWidgetService} from "../../../services/widgets/einkaufsliste-widget.service"; +import {MatSnackBar} from "@angular/material/snack-bar"; +import {MatCheckboxChange} from "@angular/material/checkbox"; +import {Event} from "../../../model/event"; +import {EditEntryDialogComponent} from "./edit-entry-dialog/edit-entry-dialog.component"; + +@Component({ + selector: 'app-einkaufsliste-widget', + templateUrl: './shopping-list-widget.component.html', + styleUrl: './shopping-list-widget.component.scss' +}) +export class ShoppingListWidgetComponent { + @Input() + eventData!: Event; + + @Input({transform: (value: BaseWidget): ShoppingWidget => value as ShoppingWidget}) + widget!: ShoppingWidget; + + @Output() + onWidgetUpdated = new EventEmitter(); + + constructor( + private dialog: MatDialog, + private service: EinkaufslisteWidgetService, + private _snackbar: MatSnackBar + ) { + } + + openAddEntryDialog() { + const dialogRef = this.dialog.open(AddEntryDialogComponent, {width: "400px"}); + dialogRef.afterClosed().subscribe(addCommand => { + if (addCommand) { + this.addEntry(addCommand); + } + }); + } + + addEntry(addCommand: EntryCommand) { + if (addCommand) { + this.service.addEntry(this.eventData.id, this.widget.id, addCommand).subscribe({ + next: response => { + this.onWidgetUpdated.emit(response); + this.showMessage("Eintrag angelegt") + }, + error: error => { + console.error('Error:', error); + this.showMessage("Fehler beim Anlegen", "error") + } + }); + } + } + + openEditEntryDialog(entry: Entry) { + const dialogRef = this.dialog.open(EditEntryDialogComponent, { + data: {entry: entry}, + width: "400px" + }); + dialogRef.afterClosed().subscribe(updateCommand => { + if (updateCommand) { + this.service.editEntry(this.eventData.id, this.widget.id, entry.id, updateCommand).subscribe({ + next: response => { + this.onWidgetUpdated.emit(response); + this.showMessage("Eintrag bearbeitet") + }, + error: error => { + console.error('Error:', error); + this.showMessage("Fehler beim Bearbeiten", "error") + } + }); + } + }); + } + + onCheckboxChange(item: Entry, event: MatCheckboxChange) { + const checkCommand: EntryCheckCommand = { + checked: event.checked + }; + this.service.checkEntry(this.eventData.id, this.widget.id, item, checkCommand).subscribe({ + next: response => { + this.onWidgetUpdated.emit(response); + }, + error: error => { + console.error('Error:', error); + } + }); + } + + deleteEntry(entry: Entry) { + this.service.deleteEntry(this.eventData.id, this.widget.id, entry.id).subscribe({ + next: response => { + this.onWidgetUpdated.emit(response); + this.showMessage("Eintrag gelöscht") + }, + error: error => { + console.error('Error:', error); + this.showMessage("Fehler beim Löschen", "error") + } + }); + } + + get entriesCount(): number { + return this.widget.entries.length; + } + + get entries() { + return this.widget.entries; + } + + private showMessage(messageToShow: string, snackBarClass: string = "successfull") { + this._snackbar.open(messageToShow, 'schließen', { + duration: 5000, + panelClass: snackBarClass + }); + } +} diff --git a/frontend/src/services/user.service.ts b/frontend/src/services/user.service.ts index ffd0e97..5f6eda3 100644 --- a/frontend/src/services/user.service.ts +++ b/frontend/src/services/user.service.ts @@ -51,8 +51,4 @@ export class UserService { document.documentElement.setAttribute("theme", colorMode.toLowerCase()); } - fetchUserById(id: string):Observable { - return this.http.get(`${environment.api}/user/${id}`,{withCredentials: true}); - } - } diff --git a/frontend/src/services/widgets/einkaufsliste-widget.service.ts b/frontend/src/services/widgets/einkaufsliste-widget.service.ts index 30f724e..406e1d5 100644 --- a/frontend/src/services/widgets/einkaufsliste-widget.service.ts +++ b/frontend/src/services/widgets/einkaufsliste-widget.service.ts @@ -20,7 +20,7 @@ export class EinkaufslisteWidgetService { return this.http.put(`${environment.api}/event/${eventId}/widgets/shopping-list/${widgetId}/entries/update/${entryId}`, entry, {withCredentials: true}); } - setBuyerId(eventId: string, widgetId: string, entry: Entry, value: EntryCheckCommand) { + checkEntry(eventId: string, widgetId: string, entry: Entry, value: EntryCheckCommand) { return this.http.put(`${environment.api}/event/${eventId}/widgets/shopping-list/${widgetId}/entries/${entry.id}`, value, {withCredentials: true}); }