Skip to content

Commit

Permalink
FE-#156: Mark left participants with a postfix in the name and a gray…
Browse files Browse the repository at this point in the history
…scale filter for the profile picture
  • Loading branch information
Drumber committed May 30, 2024
1 parent fc5321e commit a493f4d
Show file tree
Hide file tree
Showing 17 changed files with 100 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
width="35"
height="35"
[ngSrc]="user.profilePictureUrl"
[class.left-participant-profile-picture]="user.hasLeft"
referrerpolicy="no-referrer"
alt="Profilbild">

<span class="participant-name">
{{ user.firstName }} {{ user.lastName }}
{{ getUserNameForParticipant(user) }}
@if (isOwner) {
<br>
<span class="owner-hint">(Ersteller)</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Component, Input} from '@angular/core';
import {SimpleUser} from "../../../../model/user";
import {EventParticipant} from "../../../../model/user";
import {getUserNameForParticipant} from "../../../../utils/user.utils";

@Component({
selector: 'app-participant-card',
Expand All @@ -8,8 +9,9 @@ import {SimpleUser} from "../../../../model/user";
})
export class ParticipantCardComponent {
@Input()
user!: SimpleUser
user!: EventParticipant

@Input()
isOwner!: boolean;
protected readonly getUserNameForParticipant = getUserNameForParticipant;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Component, Input, OnInit} from '@angular/core';
import {Event} from "../../../model/event";
import {SimpleUser} from "../../../model/user";
import {EventParticipant} from "../../../model/user";

@Component({
selector: 'app-participants-sidenav',
Expand All @@ -11,13 +11,13 @@ export class ParticipantsSidenavComponent implements OnInit {
@Input()
eventData!: Event;

owner: SimpleUser | undefined;
owner: EventParticipant | undefined;

ngOnInit(): void {
this.owner = this.eventData.participants.find((user) => user.id === this.eventData.creatorId)
}

allParticipantsExceptOwner(): SimpleUser[] {
allParticipantsExceptOwner(): EventParticipant[] {
return this.eventData.participants.filter((user) => user.id !== this.eventData.creatorId)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,19 @@ <h2 mat-dialog-title>Ausgabe {{ isCreatingNewEntry ? 'erstellen' : 'bearbeiten'
<span matTextSuffix>&nbsp;€</span>
</mat-form-field>

@if (userService.user | async; as user) {
@if (creator | async; as creator) {
<p class="label">Zahlungsempfänger</p>
<div>
<img [ngSrc]="user.profilePictureUrl" width="32" height="32" alt="" class="user-profile-picture">
{{ user.firstName }} {{ user.lastName }}
<img
[ngSrc]="creator.profilePictureUrl"
[class.left-participant-profile-picture]="creator.hasLeft"
width="32"
height="32"
alt=""
referrerpolicy="no-referrer"
class="user-profile-picture"
>
{{ getUserNameForParticipant(creator) }}
</div>
}

Expand All @@ -29,8 +37,16 @@ <h2 mat-dialog-title>Ausgabe {{ isCreatingNewEntry ? 'erstellen' : 'bearbeiten'
<mat-select formControlName="involvedUsers" multiple placeholder="Keine Personen ausgewählt">
@for (user of users; track user.id) {
<mat-option [value]="user.id">
<img [ngSrc]="user.profilePictureUrl" width="24" height="24" alt="" class="user-profile-picture">
{{ user.firstName }} {{ user.lastName }}
<img
[ngSrc]="user.profilePictureUrl"
[class.left-participant-profile-picture]="user.hasLeft"
width="24"
height="24"
alt=""
referrerpolicy="no-referrer"
class="user-profile-picture"
>
{{ getUserNameForParticipant(user) }}
</mat-option>
}
</mat-select>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {SimpleUser} from "../../../../model/user";
import {EventParticipant} from "../../../../model/user";
import {ExpenseEntry, ExpenseEntryAddCommand, ExpenseEntryUpdateCommand} from "../../../../model/expense-split-widget";
import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
import {UserService} from "../../../../services/user.service";
import {getUserNameForParticipant} from "../../../../utils/user.utils";
import {filter, map, Observable, of} from "rxjs";

@Component({
selector: 'app-create-edit-expense-split-dialog',
Expand All @@ -12,13 +14,13 @@ import {UserService} from "../../../../services/user.service";
})
export class CreateEditExpenseEntryDialogComponent {

users: SimpleUser[];
users: EventParticipant[];
entry: ExpenseEntry | undefined;

formGroup: FormGroup;

constructor(
@Inject(MAT_DIALOG_DATA) data: { users: SimpleUser[], entry: ExpenseEntry | undefined },
@Inject(MAT_DIALOG_DATA) data: { users: EventParticipant[], entry: ExpenseEntry | undefined },
private dialogRef: MatDialogRef<CreateEditExpenseEntryDialogComponent>,
public userService: UserService,
fb: FormBuilder
Expand Down Expand Up @@ -51,8 +53,19 @@ export class CreateEditExpenseEntryDialogComponent {
this.dialogRef.close(data);
}

get creator(): Observable<EventParticipant | undefined> {
if (this.isCreatingNewEntry) {
return this.userService.user.asObservable().pipe(
filter(user => user != null),
map(user => this.users.find(p => p.id === user!.id))
);
}
return of(this.users.find(p => p.id === this.entry?.creatorId));
}

get isCreatingNewEntry(): boolean {
return !this.entry;
}

protected readonly getUserNameForParticipant = getUserNameForParticipant;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,16 @@
}
</span>
<span>
<img [ngSrc]="debt.user.profilePictureUrl" width="24" height="24" alt="" class="user-profile-picture">
{{ debt.user.firstName }} {{ debt.user.lastName }}
<img
[ngSrc]="debt.user.profilePictureUrl"
[class.left-participant-profile-picture]="debt.user.hasLeft"
width="24"
height="24"
alt=""
referrerpolicy="no-referrer"
class="user-profile-picture"
>
{{ getUserNameForParticipant(debt.user)}}
</span>
<span class="debt-amount" [class.negative]="debt.debtAmount < 0">
<strong>{{ Math.abs(debt.debtAmount) | currency: "EUR" }}</strong>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Component, Input} from '@angular/core';
import {Debt} from "../../../../model/expense-split-widget";
import {getUserNameForParticipant} from "../../../../utils/user.utils";

@Component({
selector: 'app-expense-debt-overview',
Expand All @@ -16,4 +17,5 @@ export class ExpenseDebtOverviewComponent {
}

protected readonly Math = Math;
protected readonly getUserNameForParticipant = getUserNameForParticipant;
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,16 @@

<div class="creator" matTooltip="Zahlungsempfänger">
@if (creator) {
<img [ngSrc]="creator.profilePictureUrl" width="24" height="24" alt="" class="user-profile-picture">
{{ creator.firstName }} {{ creator.lastName }}
<img
[ngSrc]="creator.profilePictureUrl"
[class.left-participant-profile-picture]="creator.hasLeft"
width="24"
height="24"
alt=""
referrerpolicy="no-referrer"
class="user-profile-picture"
>
{{ getUserNameForParticipant(creator) }}
} @else {
<p>Zahlungsempfänger konnte nicht ermittelt werden.</p>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {ExpenseEntry} from "../../../../model/expense-split-widget";
import {SimpleUser} from "../../../../model/user";
import {EventParticipant} from "../../../../model/user";
import {Event} from "../../../../model/event";
import {getUserNameForParticipant} from "../../../../utils/user.utils";

@Component({
selector: 'app-expense-entry-card',
Expand All @@ -23,7 +24,7 @@ export class ExpenseEntryCardComponent {
onEdit = new EventEmitter();

get getInvolvedUserNames(): string[] {
return this.entry.involvedUsers.map(u => [u.user.firstName, u.user.lastName].join(" "));
return this.entry.involvedUsers.map(u => getUserNameForParticipant(u.user));
}

get isEveryoneInvolved(): boolean {
Expand All @@ -33,8 +34,9 @@ export class ExpenseEntryCardComponent {
eventParticipantIds.every(id => involvedUserIds.includes(id));
}

get creator(): SimpleUser | undefined {
get creator(): EventParticipant | undefined {
return this.eventData.participants.find(p => p.id === this.entry.creatorId);
}

protected readonly getUserNameForParticipant = getUserNameForParticipant;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class ExpenseSplitWidgetComponent {
createNewExpenseEntry() {
const dialogRef = this.dialog.open(CreateEditExpenseEntryDialogComponent, {
width: "600px",
data: {users: this.eventData.participants}
data: {users: this.eventData.participants.filter(p => !p.hasLeft)}
});

dialogRef.afterClosed().subscribe(addCommand => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
@if (item.buyerId) {
<p class="einkaufliste-eintrag-card-content-buyerProfile" matTooltip="Käufer">
<mat-icon>person</mat-icon>
{{ buyer?.firstName }} {{ buyer?.lastName }}
{{ buyer ? getUserName(buyer) : '?' }}
</p>
}
<button mat-icon-button [matMenuTriggerFor]="menu">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {Entry} from "../../../../model/shoppinglist-widget";
import {Event} from "../../../../model/event";
import {SimpleUser} from "../../../../model/user";
import {EventParticipant} from "../../../../model/user";
import {getUserNameForParticipant} from "../../../../utils/user.utils";

@Component({
selector: 'app-einkaufliste-eintrag-list-item',
Expand All @@ -14,11 +15,12 @@ export class ShoppingListEntryListItemComponent {
@Output() onEdit = new EventEmitter();
@Output() onDelete = new EventEmitter();

get buyer(): SimpleUser | undefined {
get buyer(): EventParticipant | undefined {
if (!this.item.buyerId) {
return undefined;
}
return this.eventData.participants.find(p => p.id === this.item.buyerId);
}

protected readonly getUserName = getUserNameForParticipant;
}
4 changes: 2 additions & 2 deletions frontend/src/model/event.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {BaseWidget} from "./common-widget";
import {SimpleUser} from "./user";
import {EventParticipant} from "./user";

export type EventOverview = {
id: string;
Expand All @@ -14,7 +14,7 @@ export type Event = EventOverview & {
location: EventLocation;
invitationLink: string | undefined;
creatorId: string;
participants: SimpleUser[];
participants: EventParticipant[];
widgets: BaseWidget[];
}

Expand Down
6 changes: 3 additions & 3 deletions frontend/src/model/expense-split-widget.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {BaseWidget, WidgetType} from "./common-widget";
import {SimpleUser} from "./user";
import {EventParticipant} from "./user";

export type ExpenseSplitWidget = BaseWidget & {
widgetType: WidgetType.EXPENSE_SPLIT;
Expand All @@ -18,12 +18,12 @@ export type ExpenseEntry = {
}

export type UsersWithPercentage = {
user: SimpleUser;
user: EventParticipant;
percentage: number;
}

export type Debt = {
user: SimpleUser;
user: EventParticipant;
debtAmount: number;
}

Expand Down
3 changes: 2 additions & 1 deletion frontend/src/model/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ export type User = {
guest: true | undefined;
}

export type SimpleUser = {
export type EventParticipant = {
id: string;
firstName: string;
lastName: string;
profilePictureUrl: string;
hasLeft: boolean;
}

export type UserSettings = {
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ body {
margin: 0;
font-family: Mada, sans-serif;
}

.left-participant-profile-picture {
filter: grayscale(75%);
}
9 changes: 9 additions & 0 deletions frontend/src/utils/user.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {EventParticipant} from "../model/user";

export const getUserNameForParticipant = (participant: EventParticipant) => {
const userName = [participant.firstName, participant.lastName].join(" ");
if (participant.hasLeft) {
return userName + " (Verlassen)";
}
return userName;
}

0 comments on commit a493f4d

Please sign in to comment.