From a11c74b91b838b2d0662ead9b15231c4147e9a83 Mon Sep 17 00:00:00 2001 From: _Bastler <_Bastler@bstly.de> Date: Thu, 29 Jul 2021 17:41:25 +0200 Subject: [PATCH] update partey timeslots + minetest --- src/app/app-routing.module.ts | 4 + src/app/app.module.ts | 8 +- .../minetest/accounts/accounts.component.html | 43 +++ .../minetest/accounts/accounts.component.scss | 30 ++ .../minetest/accounts/accounts.component.ts | 77 +++++ .../partey/timeslots/timeslot.dialog.html | 48 ++++ .../partey/timeslots/timeslot.dialog.scss | 7 + .../partey/timeslots/timeslots.component.html | 117 ++++++++ .../partey/timeslots/timeslots.component.scss | 21 ++ .../partey/timeslots/timeslots.compontent.ts | 263 ++++++++++++++++++ src/app/services/jitsi.service.ts | 17 +- src/app/services/minetest.accounts.service.ts | 22 ++ src/app/services/partey.timeslots.service.ts | 69 +++++ 13 files changed, 723 insertions(+), 3 deletions(-) create mode 100644 src/app/pages/minetest/accounts/accounts.component.html create mode 100644 src/app/pages/minetest/accounts/accounts.component.scss create mode 100644 src/app/pages/minetest/accounts/accounts.component.ts create mode 100644 src/app/pages/partey/timeslots/timeslot.dialog.html create mode 100644 src/app/pages/partey/timeslots/timeslot.dialog.scss create mode 100644 src/app/pages/partey/timeslots/timeslots.component.html create mode 100644 src/app/pages/partey/timeslots/timeslots.component.scss create mode 100644 src/app/pages/partey/timeslots/timeslots.compontent.ts create mode 100644 src/app/services/minetest.accounts.service.ts create mode 100644 src/app/services/partey.timeslots.service.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 99b7358..36b302e 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -19,10 +19,12 @@ import {UnavailableComponent} from './pages/unavailable/unavailable.component'; import {NotfoundComponent} from './pages/notfound/notfound.component'; import {UserComponent} from './pages/user/user.component' import {JitsiComponent} from './pages/jitsi/jitsi.component' +import {ParteyTimeslotsComponent} from './pages/partey/timeslots/timeslots.compontent' import {AliasesComponent} from './pages/account/aliases/aliases.component'; import {DomainsComponent} from './pages/account/domains/domains.component'; import {InvitesComponent} from './pages/invites/invites.component'; import {UrlShortenerComponent, UrlShortenerPasswordComponent} from './pages/urlshortener/urlshortener.component'; +import {MinetestAccountsComponent} from './pages/minetest/accounts/accounts.component'; const routes: Routes = [ {path: '', redirectTo: "/services", pathMatch: 'full'}, @@ -50,6 +52,8 @@ const routes: Routes = [ {path: 'register', component: RegisterComponent, canActivate: [AnonymousGuard]}, {path: 'tokens', component: TokensComponent, canActivate: [AuthGuard]}, {path: 'jitsi', component: JitsiComponent, canActivate: [AuthenticatedGuard]}, + {path: 'partey/timeslots', component: ParteyTimeslotsComponent, canActivate: [AuthenticatedGuard]}, + {path: 'minetest/accounts', component: MinetestAccountsComponent, canActivate: [AuthenticatedGuard]}, {path: 'urlshortener', component: UrlShortenerComponent, canActivate: [AuthenticatedGuard]}, {path: 'urlshortener/:code', component: UrlShortenerPasswordComponent, canActivate: [AuthUpdateGuard]}, {path: 'invites/:quota', component: InvitesComponent, canActivate: [AuthenticatedGuard]}, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 3ec8604..6a033dd 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -7,10 +7,10 @@ import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {HttpClientModule, HttpInterceptor, HttpHandler, HttpRequest, HTTP_INTERCEPTORS} from '@angular/common/http'; import {MaterialModule} from './material/material.module'; import {QRCodeModule} from 'angularx-qrcode'; -import { DatePipe } from '@angular/common'; +import {DatePipe} from '@angular/common'; -import { AutofocusDirective} from './material/autofocus'; +import {AutofocusDirective} from './material/autofocus'; import {I18nPipe} from './utils/i18n.pipe'; import {ImprintComponent, PrivacyPolicyComponent, TermsOfServiceComponent} from './pages/general/general.component'; @@ -43,10 +43,12 @@ import {HtmlComponent} from './utils/html/html.component'; import {ConfirmDialog} from './ui/confirm/confirm.component' import {UserComponent} from './pages/user/user.component' import {JitsiComponent, JitsiShareDialog} from './pages/jitsi/jitsi.component' +import {ParteyTimeslotsComponent, ParteyTimeslotDialog} from './pages/partey/timeslots/timeslots.compontent' import {UrlShortenerComponent, UrlShortenerPasswordComponent, UrlShortenerShareDialog} from './pages/urlshortener/urlshortener.component' import {I18nService} from './services/i18n.service'; +import {MinetestAccountsComponent} from './pages/minetest/accounts/accounts.component'; export function init_app(i18n: I18nService) { @@ -99,6 +101,8 @@ export class XhrInterceptor implements HttpInterceptor { ConfirmDialog, UserComponent, JitsiComponent, JitsiShareDialog, + ParteyTimeslotsComponent, ParteyTimeslotDialog, + MinetestAccountsComponent, UrlShortenerComponent, UrlShortenerShareDialog, UrlShortenerPasswordComponent ], imports: [ diff --git a/src/app/pages/minetest/accounts/accounts.component.html b/src/app/pages/minetest/accounts/accounts.component.html new file mode 100644 index 0000000..041874e --- /dev/null +++ b/src/app/pages/minetest/accounts/accounts.component.html @@ -0,0 +1,43 @@ +

{{'minetest.accounts' | i18n}}

+ + + + + + + + + +
{{'minetest.accounts.name' | i18n}} + {{minetestAccount.name}} +
+ +
+ + +

{{'minetest.accounts.info' | i18n}}

+

{{'minetest.accounts.noQuota' | i18n}}

+
+

{{'minetest.accounts.left' | i18n:minetestAccountsQuota}}

+ + + + {{'minetest.accounts.error.name' | i18n}} + + + + + {{'minetest.accounts.deletion' | i18n}} + + +
+
+ + + +
+ +
\ No newline at end of file diff --git a/src/app/pages/minetest/accounts/accounts.component.scss b/src/app/pages/minetest/accounts/accounts.component.scss new file mode 100644 index 0000000..bc6ceb6 --- /dev/null +++ b/src/app/pages/minetest/accounts/accounts.component.scss @@ -0,0 +1,30 @@ +mat-form-field { + display: block; +} + +.mat-header-cell, +.mat-cell { + &.text-right { + text-align: right; + } +} + +.mat-cell .mat-button { + padding-left: 0px; + padding-right: 0px; +} + +.align-right{ + display: flex; + padding: 21px 0; + justify-content: flex-end; +} + +.url { + display: inline-block; + width: 200px; + max-width: 200px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} \ No newline at end of file diff --git a/src/app/pages/minetest/accounts/accounts.component.ts b/src/app/pages/minetest/accounts/accounts.component.ts new file mode 100644 index 0000000..d63f8be --- /dev/null +++ b/src/app/pages/minetest/accounts/accounts.component.ts @@ -0,0 +1,77 @@ +import {Component, OnInit, ViewChild} from '@angular/core'; +import {FormBuilder, FormGroup, Validators, NgForm} from '@angular/forms'; + +import {QuotaService} from '../../../services/quota.service'; +import {MinetestAccountsService} from '../../../services/minetest.accounts.service'; + +@Component({ + selector: 'app-minetest-accounts', + templateUrl: './accounts.component.html', + styleUrls: ['./accounts.component.scss'] +}) +export class MinetestAccountsComponent implements OnInit { + + form: FormGroup; + @ViewChild('formDirective') private formDirective: NgForm; + minetestAccountsQuota: number = 0; + minetestAccounts: any; + minetestAccount: any = {}; + success: boolean; + working: boolean; + + minetestAccountsColumns = ["name"]; + + constructor( + private quotaService: QuotaService, + private formBuilder: FormBuilder, + private minetestAccountsService: MinetestAccountsService) {} + + ngOnInit(): void { + + this.form = this.formBuilder.group({ + name: ['', Validators.required], + }); + + this.update(); + } + + create(): void { + this.working = true; + + this.minetestAccountsService.create(this.minetestAccount).subscribe(response => { + this.update(); + this.formDirective.resetForm(); + this.minetestAccount = {}; + this.working = false; + }, (error) => { + this.working = false; + if(error.status == 409) { + let errors = {}; + for(let code of error.error) { + errors[code.field] = errors[code.field] || {}; + errors[code.field][code.code] = true; + } + + for(let code in errors) { + this.form.get(code).setErrors(errors[code]); + } + } + }) + } + + update() { + this.minetestAccountsQuota = 0; + this.quotaService.quotas().subscribe((data: any) => { + for(let quota of data) { + if(quota.name == "minetest_accounts") { + this.minetestAccountsQuota = quota.value; + } + } + }) + + this.minetestAccountsService.get().subscribe((data: any) => { + this.minetestAccounts = data; + }) + } + +} diff --git a/src/app/pages/partey/timeslots/timeslot.dialog.html b/src/app/pages/partey/timeslots/timeslot.dialog.html new file mode 100644 index 0000000..4a51820 --- /dev/null +++ b/src/app/pages/partey/timeslots/timeslot.dialog.html @@ -0,0 +1,48 @@ +

+ {{'partey.timeslots.type.' + timeslot.type + '.icon' | i18n}} {{(timeslot.id ? 'partey.timeslots.edit' : 'partey.timeslots.create.' + + timeslot.type) | i18n}} +

+ +

{{'partey.timeslots.type.' + timeslot.type | i18n}}

+
+ + + + + + + + + + + + {{'partey.timeslots.error.starts' | i18n}} + + + + + + + + {{'partey.timeslots.error.ends' | i18n}} + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/src/app/pages/partey/timeslots/timeslot.dialog.scss b/src/app/pages/partey/timeslots/timeslot.dialog.scss new file mode 100644 index 0000000..03bec19 --- /dev/null +++ b/src/app/pages/partey/timeslots/timeslot.dialog.scss @@ -0,0 +1,7 @@ +mat-form-field { + display: block; +} + +mat-slide-toggle { + margin-bottom: 24px; +} \ No newline at end of file diff --git a/src/app/pages/partey/timeslots/timeslots.component.html b/src/app/pages/partey/timeslots/timeslots.component.html new file mode 100644 index 0000000..1581527 --- /dev/null +++ b/src/app/pages/partey/timeslots/timeslots.component.html @@ -0,0 +1,117 @@ +

{{'partey.timeslots' | i18n}}

+ +
+ + + + + {{'partey.timeslots.filter.owner' | i18n}} + + {{'partey.timeslots.filter.owner.mine' | i18n}} + {{'partey.timeslots.filter.owner.others' | i18n}} + {{'partey.timeslots.filter.owner.all' | i18n}} + + + + {{'partey.timeslots.filter.type' | i18n}} + + {{'partey.timeslots.filter.type.all' | i18n}} + + {{'partey.timeslots.type.' + type + '.icon' | i18n}} + {{'partey.timeslots.filter.type.' + type | i18n}} + + + {{'partey.timeslots.type.' + typeFormControl.value + + '.icon' | i18n}} {{'partey.timeslots.filter.type.' + (typeFormControl.value ? typeFormControl.value + : 'all') | i18n}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{'partey.timeslots.starts' | i18n}} {{ timeslot.starts | date:datetimeformat}} {{'partey.timeslots.ends' | i18n}} {{ timeslot.ends | date:datetimeformat}} {{'partey.timeslots.title' | i18n}} {{ timeslot.title }} {{'partey.timeslots.description' | i18n}} + {{ timeslot.description }} {{'partey.timeslots.type' | i18n}} + + {{'partey.timeslots.type.' + timeslot.type + '.icon' | i18n}} + {{'partey.timeslots.stream' | i18n}} + + + {{ timeslot.stream }} + {{'partey.timeslots.edit' | i18n}} + + edit + + {{'partey.timeslots.delete' | i18n}} + + delete + +
+ + +
+ + + +

{{'partey.timeslots.info' | i18n}}

+

{{'partey.timeslots.noQuota' | i18n}}

+
+

{{'partey.timeslots.left' | i18n:timeslotsQuota}}

+
+
+ + + +
\ No newline at end of file diff --git a/src/app/pages/partey/timeslots/timeslots.component.scss b/src/app/pages/partey/timeslots/timeslots.component.scss new file mode 100644 index 0000000..dd47025 --- /dev/null +++ b/src/app/pages/partey/timeslots/timeslots.component.scss @@ -0,0 +1,21 @@ +.mat-header-cell, +.mat-cell { + &.text-right { + text-align: right; + } +} + +.mat-cell .mat-button { + padding-left: 0px; + padding-right: 0px; +} + +.align-right{ + display: flex; + padding: 21px 0; + justify-content: flex-end; +} + +.mat-form-field+.mat-form-field { + margin-left: 8px; +} diff --git a/src/app/pages/partey/timeslots/timeslots.compontent.ts b/src/app/pages/partey/timeslots/timeslots.compontent.ts new file mode 100644 index 0000000..84b1c1c --- /dev/null +++ b/src/app/pages/partey/timeslots/timeslots.compontent.ts @@ -0,0 +1,263 @@ +import {Component, OnInit, ViewChild, Inject} from '@angular/core'; +import {Sort} from '@angular/material/sort'; +import {MatSnackBar} from '@angular/material/snack-bar'; +import {FormBuilder, FormGroup, Validators, NgForm} from '@angular/forms'; +import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog'; +import {DatePipe} from '@angular/common'; +import {FormControl} from '@angular/forms'; +import {debounceTime} from 'rxjs/operators'; +import {PageEvent} from '@angular/material/paginator'; + +import {ParteyTimeslotsService} from '../../../services/partey.timeslots.service'; +import {ConfirmDialog} from '../../../ui/confirm/confirm.component'; +import {I18nService} from './../../../services/i18n.service'; + +@Component({ + selector: 'app-partey-timeslots', + templateUrl: './timeslots.component.html', + styleUrls: ['./timeslots.component.scss'] +}) +export class ParteyTimeslotsComponent implements OnInit { + + form: FormGroup; + @ViewChild('formDirective') private formDirective: NgForm; + timeslotsQuota: number = 0; + timeslots: any; + timeslot: any = {}; + success: boolean; + working: boolean; + datetimeformat: string; + page: any = {page: 0, size: 10, sort: "id", desc: false}; + filter: any = {}; + pageSizeOptions: number[] = [5, 10, 25, 50]; + visibilities = ["PRIVATE", "PROTECTED", "PUBLIC"]; + types = ["VIDEO", "AUDIO"]; + + timeslotsColumns = ["type", "starts", "ends", "title", "description", "stream", "edit", "delete"]; + + searchFormControl = new FormControl(); + ownerFormControl = new FormControl(); + afterFormControl = new FormControl(); + typeFormControl = new FormControl(); + + constructor( + private formBuilder: FormBuilder, + private parteyTimeslotsService: ParteyTimeslotsService, + private i18n: I18nService, + private datePipe: DatePipe, + private snackBar: MatSnackBar, + public dialog: MatDialog) {} + + ngOnInit(): void { + this.datetimeformat = this.i18n.get('format.datetime', []); + + this.form = this.formBuilder.group({ + room: ['', Validators.required], + starts: ['', Validators.nullValidator], + moderationStarts: ['', Validators.nullValidator], + expires: ['', Validators.nullValidator], + }); + + this.filter.owner = ""; + this.ownerFormControl.setValue(""); + this.filter.type = ""; + this.typeFormControl.setValue(""); + this.filter.after = new Date().toUTCString(); + this.afterFormControl.setValue(new Date()); + + this.searchFormControl.valueChanges.pipe(debounceTime(500)).subscribe(value => { + this.filter.search = value; + this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe((data: any) => { + this.timeslots = data; + }, (error) => {}) + }) + this.ownerFormControl.valueChanges.subscribe(value => { + this.filter.owner = value; + this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe((data: any) => { + this.timeslots = data; + }, (error) => {}) + }) + this.typeFormControl.valueChanges.subscribe(value => { + this.filter.type = value; + this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe((data: any) => { + this.timeslots = data; + }, (error) => {}) + }) + this.afterFormControl.valueChanges.subscribe((value: Date) => { + this.filter.after = value && value.toUTCString() || undefined; + this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe((data: any) => { + this.timeslots = data; + }, (error) => {}) + }) + + this.refresh(); + } + + refresh() { + this.timeslotsQuota = 0; + + this.parteyTimeslotsService.quota().subscribe((data: number) => { + this.timeslotsQuota = data; + }) + + this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe((data: any) => { + this.timeslots = data; + }) + } + + updatePages(event: PageEvent) { + this.page.page = event.pageIndex; + this.page.size = event.pageSize; + this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe((data: any) => { + this.timeslots = data; + }, (error) => {}) + } + + updateSort(sort: Sort) { + if(sort.direction == "") { + this.page.sort = "id"; + this.page.desc = false; + } else { + this.page.sort = sort.active; + this.page.desc = sort.direction == "desc"; + } + this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe((data: any) => { + this.timeslots = data; + }, (error) => {}) + } + + confirmDelete(timeslot) { + const dialogRef = this.dialog.open(ConfirmDialog, { + data: { + 'label': 'partey.timeslots.confirmDelete', + 'args': [timeslot.title, this.datePipe.transform(new Date(timeslot.starts), this.datetimeformat)] + } + }) + + dialogRef.afterClosed().subscribe(result => { + if(result) { + this.parteyTimeslotsService.delete(timeslot.id).subscribe((result: any) => { + this.refresh(); + }) + } + }); + } + + openCreate(type) { + const dialogRef = this.dialog.open(ParteyTimeslotDialog, { + data: {"type": type ? type : "VIDEO", "visibility": "PROTECTED"}, + minWidth: '400px' + }); + + dialogRef.afterClosed().subscribe(result => { + if(result) { + this.refresh(); + } + }); + } + + openEdit(timeslot) { + const timeslotClone = JSON.parse(JSON.stringify(timeslot)); + const dialogRef = this.dialog.open(ParteyTimeslotDialog, { + data: timeslotClone, + minWidth: '400px' + }); + + dialogRef.afterClosed().subscribe(result => { + if(result) { + this.refresh(); + } + }); + + } + + copySecretToClipboard(secret) { + const selBox = document.createElement('textarea'); + selBox.value = secret; + document.body.appendChild(selBox); + selBox.focus(); + selBox.select(); + document.execCommand('copy'); + document.body.removeChild(selBox); + this.snackBar.open(this.i18n.get("partey.timeslots.secret.copied", []), this.i18n.get("close", []), { + duration: 3000 + }); + } + +} + + + +@Component({ + selector: 'app-timeslot-dialog', + templateUrl: 'timeslot.dialog.html', + styleUrls: ['./timeslot.dialog.scss'] +}) +export class ParteyTimeslotDialog { + + form: FormGroup; + timeslot; + + visibilities = ["PRIVATE", "PROTECTED", "PUBLIC"]; + types = ["VIDEO", "AUDIO"]; + + constructor( + private parteyTimeslotsService: ParteyTimeslotsService, + private formBuilder: FormBuilder, + private dialog: MatDialog, + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any) { + this.timeslot = data; + } + + ngOnInit() { + this.form = this.formBuilder.group({ + starts: ['', Validators.required], + ends: ['', Validators.required], + title: ['', Validators.nullValidator], + description: ['', Validators.nullValidator], + stream: ['', this.timeslot.type == 'VIDEO' ? Validators.required : Validators.nullValidator], + }); + } + + + + create(timeslot) { + this.parteyTimeslotsService.create(timeslot).subscribe((result: any) => { + this.dialogRef.close(timeslot); + }, (error) => { + if(error.status == 409) { + let errors = {}; + for(let code of error.error) { + errors[code.field] = errors[code.field] || {}; + errors[code.field][code.code] = true; + } + + for(let code in errors) { + this.form.get(code).setErrors(errors[code]); + } + } + }); + } + + save(timeslot) { + this.parteyTimeslotsService.update(timeslot).subscribe((result: any) => { + this.dialogRef.close(timeslot); + }, (error) => { + if(error.status == 409) { + let errors = {}; + for(let code of error.error) { + errors[code.field] = errors[code.field] || {}; + errors[code.field][code.code] = true; + } + + for(let code in errors) { + this.form.get(code).setErrors(errors[code]); + } + } + }); + } + + + +} \ No newline at end of file diff --git a/src/app/services/jitsi.service.ts b/src/app/services/jitsi.service.ts index 0c820b8..ec1dda6 100644 --- a/src/app/services/jitsi.service.ts +++ b/src/app/services/jitsi.service.ts @@ -12,7 +12,22 @@ export class JitsiService { } get(page: number, size: number, sort: string, desc: boolean) { - const httpParams = new HttpParams().set("page", "" + page).set("size", "" + size).set("sort", sort).set("desc", "" + desc); + let httpParams = new HttpParams(); + if(page != undefined) { + httpParams = httpParams.set("page", "" + page); + } + if(size != undefined) { + httpParams = httpParams.set("size", "" + size); + } + + if(sort != undefined) { + httpParams = httpParams.set("sort", sort); + } + + if(desc != undefined) { + httpParams = httpParams.set("desc", "" + desc); + } + return this.http.get(environment.apiUrl + "/jitsi/rooms", {params: httpParams}); } diff --git a/src/app/services/minetest.accounts.service.ts b/src/app/services/minetest.accounts.service.ts new file mode 100644 index 0000000..bed477f --- /dev/null +++ b/src/app/services/minetest.accounts.service.ts @@ -0,0 +1,22 @@ +import {Injectable} from '@angular/core'; +import {HttpClient, HttpParams} from '@angular/common/http'; + +import {environment} from '../../environments/environment'; + +@Injectable({ + providedIn: 'root', +}) +export class MinetestAccountsService { + + constructor(private http: HttpClient) { + } + + get() { + return this.http.get(environment.apiUrl + "/minetest/accounts"); + } + + create(minetestAccount) { + return this.http.post(environment.apiUrl + "/minetest/accounts", minetestAccount); + } + +} \ No newline at end of file diff --git a/src/app/services/partey.timeslots.service.ts b/src/app/services/partey.timeslots.service.ts new file mode 100644 index 0000000..66e0cae --- /dev/null +++ b/src/app/services/partey.timeslots.service.ts @@ -0,0 +1,69 @@ +import {Injectable} from '@angular/core'; +import {HttpClient, HttpParams} from '@angular/common/http'; + +import {environment} from '../../environments/environment'; + +@Injectable({ + providedIn: 'root', +}) +export class ParteyTimeslotsService { + + constructor(private http: HttpClient) { + } + + get(page: number, size: number, sort: string, desc: boolean, filter : any) { + let httpParams = new HttpParams(); + if(page != undefined) { + httpParams = httpParams.set("page", "" + page); + } + if(size != undefined) { + httpParams = httpParams.set("size", "" + size); + } + + if(sort != undefined) { + httpParams = httpParams.set("sort", sort); + } + + if(desc != undefined) { + httpParams = httpParams.set("desc", "" + desc); + } + + if (filter) { + if(filter.owner != undefined && filter.owner != "") { + httpParams = httpParams.set("owner", "" + filter.owner); + } + if(filter.after != undefined && filter.after != "") { + httpParams = httpParams.set("after", "" + filter.after); + } + if(filter.type != undefined && filter.type != "") { + httpParams = httpParams.set("type", "" + filter.type); + } + if(filter.visibility != undefined && filter.visibility != "") { + httpParams = httpParams.set("visibility", "" + filter.visibility); + } + if(filter.search != undefined && filter.search != "") { + httpParams = httpParams.set("search", "" + filter.search); + } + } + + return this.http.get(environment.apiUrl + "/partey/timeslots", {params: httpParams}); + } + + + quota() { + return this.http.get(environment.apiUrl + "/partey/timeslots/quota"); + } + + create(timeslot) { + return this.http.post(environment.apiUrl + "/partey/timeslots", timeslot); + } + + update(timeslot) { + return this.http.patch(environment.apiUrl + "/partey/timeslots", timeslot); + } + + delete(id) { + return this.http.delete(environment.apiUrl + "/partey/timeslots/" + id); + } + +} \ No newline at end of file