-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4aaa397
commit 016e7ad
Showing
53 changed files
with
898 additions
and
722 deletions.
There are no files selected for viewing
29 changes: 29 additions & 0 deletions
29
frontend/src/app/modules/events/components/event-accounting/event-accounting.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<h3>Účtování</h3> | ||
<bo-event-expenses-chart></bo-event-expenses-chart> | ||
<ion-list> | ||
<ion-item-sliding #sliding *ngFor="let expense of expenses" (click)="toggleSliding(sliding)"> | ||
<ion-item [button]="true" [detail]="false"> | ||
<ion-label> | ||
<h2> | ||
<strong>{{ expense.id }}</strong> - {{ expense.description }} | ||
<!-- TODO: <ion-icon class="ms-1" *ngIf="expense.photo" name="camera-outline"></ion-icon> --> | ||
</h2> | ||
<p class="d-lg-none">{{ expense.amount | number: "1.2-2" : "cs" }} Kč</p> | ||
</ion-label> | ||
|
||
<ion-badge mode="ios" [color]="getExpenseColor(expense)">{{ expense.type }}</ion-badge> | ||
|
||
<ion-label class="d-none d-lg-block text-right me-3"> | ||
{{ expense.amount | number: "1.2-2" : "cs" }} Kč | ||
</ion-label> | ||
</ion-item> | ||
<ion-item-options side="end"> | ||
<ion-item-option color="primary" (click)="editExpenseModal(expense)"> | ||
<ion-icon slot="icon-only" name="create-outline"></ion-icon> | ||
</ion-item-option> | ||
<ion-item-option color="danger" (click)="removeExpense(expense)"> | ||
<ion-icon slot="icon-only" name="trash-outline"></ion-icon> | ||
</ion-item-option> | ||
</ion-item-options> | ||
</ion-item-sliding> | ||
</ion-list> |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
frontend/src/app/modules/events/components/event-attendees/event-attendees.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<h3>Účastníci</h3> | ||
|
||
<ion-list> | ||
<!-- ATTENDEES --> | ||
<p *ngIf="attendees && !attendees.length"><em>Žádní účastníci</em></p> | ||
|
||
<ion-item *ngFor="let attendee of attendees"> | ||
<ion-label> | ||
<h3>{{ attendee.member | member: "nickname" }}</h3> | ||
<p><bo-member-item-detail *ngIf="attendee.member" [member]="attendee.member"></bo-member-item-detail></p> | ||
</ion-label> | ||
<ion-badge | ||
slot="end" | ||
mode="ios" | ||
[style.background-color]="attendee.member?.groupId | group: 'color'" | ||
class="d-none d-xl-block" | ||
> | ||
{{ attendee.member?.groupId | group: "name" }} | ||
</ion-badge> | ||
<ion-button fill="clear" [routerLink]="'/databaze/' + attendee.memberId" slot="end"> | ||
<ion-icon name="information-circle-outline"></ion-icon> | ||
</ion-button> | ||
<ion-button fill="clear" color="danger" (click)="removeAttendee(attendee)" slot="end"> | ||
<ion-icon name="trash-outline"></ion-icon> | ||
</ion-button> | ||
</ion-item> | ||
|
||
<div class="text-center"> | ||
<bo-add-button (click)="addAttendee()">Přidat účastníka</bo-add-button> | ||
</div> | ||
</ion-list> |
File renamed without changes.
119 changes: 119 additions & 0 deletions
119
frontend/src/app/modules/events/components/event-attendees/event-attendees.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; | ||
import { UntilDestroy } from "@ngneat/until-destroy"; | ||
import { EventAttendeeResponse, EventResponseWithLinks } from "src/app/api"; | ||
import { MemberSelectorModalComponent } from "src/app/modules/events/components/member-selector-modal/member-selector-modal.component"; | ||
import { ApiService } from "src/app/services/api.service"; | ||
import { ModalService } from "src/app/services/modal.service"; | ||
import { ToastService } from "src/app/services/toast.service"; | ||
import { Action } from "src/app/shared/components/action-buttons/action-buttons.component"; | ||
|
||
@UntilDestroy() | ||
@Component({ | ||
selector: "bo-event-attendees", | ||
templateUrl: "./event-attendees.component.html", | ||
styleUrls: ["./event-attendees.component.scss"], | ||
}) | ||
export class EventAttendeesComponent implements OnInit, OnDestroy { | ||
@Input() event?: EventResponseWithLinks; | ||
@Output() change = new EventEmitter<void>(); | ||
|
||
attendees: EventAttendeeResponse[] = []; | ||
|
||
actions: Action[] = []; | ||
|
||
modal?: HTMLIonModalElement; | ||
|
||
constructor( | ||
private api: ApiService, | ||
private toastService: ToastService, | ||
private modalService: ModalService, | ||
) {} | ||
|
||
ngOnInit(): void {} | ||
|
||
ngOnDestroy() { | ||
this.modal?.dismiss(); | ||
} | ||
|
||
private sortAttendees() { | ||
this.attendees.sort((a, b) => { | ||
const aString = a.member?.nickname || a.member?.firstName || a.member?.lastName || ""; | ||
const bString = b.member?.nickname || b.member?.firstName || b.member?.lastName || ""; | ||
return aString.localeCompare(bString); | ||
}); | ||
} | ||
|
||
async addAttendee() { | ||
if (!this.event) return; | ||
|
||
const member = await this.modalService.componentModal(MemberSelectorModalComponent, {}); | ||
|
||
if (member) { | ||
const attendees = this.event.attendees || []; | ||
|
||
if (attendees.some((item) => item.member && item.member.id === member.id)) { | ||
this.toastService.toast("Účastník už v seznamu je."); | ||
return; | ||
} | ||
|
||
// optimistic update | ||
attendees.push({ | ||
memberId: member.id, | ||
member, | ||
eventId: this.event.id, | ||
type: "attendee", | ||
}); | ||
|
||
this.attendees = attendees; | ||
this.sortAttendees(); | ||
|
||
try { | ||
await this.api.events.addEventAttendee(this.event.id, member.id, {}); | ||
this.toastService.toast("Účastník přidán."); | ||
} catch (e) { | ||
this.toastService.toast("Nepodařilo se přidat účastníka."); | ||
} | ||
|
||
this.change.emit(); | ||
} | ||
} | ||
|
||
async removeAttendee(attendee: EventAttendeeResponse) { | ||
if (!this.event) return; | ||
|
||
let attendees = this.event.attendees || []; | ||
attendees = attendees.filter((item) => item.memberId !== attendee.memberId); | ||
|
||
this.attendees = attendees; // optimistic update | ||
|
||
await this.api.events.deleteEventAttendee(this.event.id, attendee.memberId); | ||
|
||
this.change.emit(); | ||
} | ||
|
||
toggleSliding(sliding: any) { | ||
sliding.getOpenAmount().then((open: number) => { | ||
if (open) sliding.close(); | ||
else sliding.open(); | ||
}); | ||
} | ||
|
||
private async exportExcel(event: EventResponseWithLinks) { | ||
// TODO: | ||
// if (event._links.["announcement-template"]) { | ||
// const url = environment.apiRoot + event._links.["announcement-template"].href; | ||
// window.open(url); | ||
// } | ||
} | ||
|
||
private setActions(event?: EventResponseWithLinks) { | ||
this.actions = [ | ||
{ | ||
text: "Stáhnout ohlášku", | ||
icon: "download-outline", | ||
// hidden: !event?._links.self.allowed.GET, // TODO: | ||
handler: () => this.exportExcel(event!), | ||
}, | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
frontend/src/app/modules/events/components/event-info/event-info.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<h3>Základní informace</h3> | ||
|
||
<ion-list> | ||
<bo-item label="Název" [loading]="!event" [editable]="!!event?._links?.updateEvent?.allowed" (edit)="editName()"> | ||
<p>{{ event?.name }}</p> | ||
</bo-item> | ||
|
||
<bo-item label="Termín" [loading]="!event" [editable]="!!event?._links?.updateEvent?.allowed" (edit)="editDate()"> | ||
<p>{{ [event?.dateFrom, event?.dateTill] | dateRange }}</p> | ||
</bo-item> | ||
|
||
<bo-item label="Typ" [loading]="!event"> | ||
<bo-event-type-selector | ||
*ngIf="event" | ||
[disabled]="!event._links.updateEvent.allowed" | ||
[ngModel]="event.type" | ||
(ngModelChange)="updateType($event)" | ||
slot="end" | ||
></bo-event-type-selector> | ||
</bo-item> | ||
</ion-list> | ||
|
||
<h3 class="mt-5">Popis</h3> | ||
<bo-card> | ||
<bo-card-content> | ||
<bo-item | ||
lines="none" | ||
[loading]="!event" | ||
[editable]="!!event?._links?.updateEvent?.allowed" | ||
(edit)="editDescription()" | ||
> | ||
<p *ngIf="event">{{ event.description }}</p> | ||
</bo-item> | ||
</bo-card-content> | ||
</bo-card> |
4 changes: 4 additions & 0 deletions
4
...view-info/events-view-info.component.scss → ...ents/event-info/event-info.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
:host { | ||
display: block; | ||
} | ||
|
||
.attendees { | ||
ion-chip { | ||
color: #fff; | ||
|
75 changes: 75 additions & 0 deletions
75
frontend/src/app/modules/events/components/event-info/event-info.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; | ||
import { UntilDestroy } from "@ngneat/until-destroy"; | ||
import { EventResponse, EventResponseWithLinks } from "src/app/api"; | ||
import { ModalService } from "src/app/services/modal.service"; | ||
|
||
@UntilDestroy() | ||
@Component({ | ||
selector: "bo-event-info", | ||
templateUrl: "./event-info.component.html", | ||
styleUrls: ["./event-info.component.scss"], | ||
}) | ||
export class EventInfoComponent implements OnInit, OnDestroy { | ||
@Input() event?: EventResponseWithLinks; | ||
@Output() update = new EventEmitter<Partial<EventResponse>>(); | ||
|
||
constructor(private modalService: ModalService) {} | ||
|
||
ngOnInit() {} | ||
|
||
ngOnDestroy() {} | ||
|
||
async editName() { | ||
const result = await this.modalService.inputModal({ | ||
header: "Název akce", | ||
inputs: { | ||
name: { | ||
placeholder: "Název", | ||
type: "text", | ||
value: this.event?.name, | ||
}, | ||
}, | ||
}); | ||
|
||
if (result) this.update.emit(result); | ||
} | ||
|
||
async editDate() { | ||
const result = await this.modalService.inputModal({ | ||
header: "Datum akce", | ||
inputs: { | ||
dateFrom: { | ||
placeholder: "Datum od", | ||
type: "date", | ||
value: this.event?.dateFrom, | ||
}, | ||
dateTill: { | ||
placeholder: "Datum do", | ||
type: "date", | ||
value: this.event?.dateTill, | ||
}, | ||
}, | ||
}); | ||
|
||
if (result) this.update.emit(result); | ||
} | ||
|
||
async editDescription() { | ||
const result = await this.modalService.inputModal({ | ||
header: "Popis akce", | ||
inputs: { | ||
description: { | ||
placeholder: "Popis", | ||
type: "text", | ||
value: this.event?.description, | ||
}, | ||
}, | ||
}); | ||
|
||
if (result) this.update.emit(result); | ||
} | ||
|
||
updateType(type: string) { | ||
this.update.emit({ type }); | ||
} | ||
} |
Oops, something went wrong.