import { Clipboard } from '@angular/cdk/clipboard'; import { DatePipe } from '@angular/common'; import { Component, Inject, OnInit, ViewChild } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, NgForm, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { PageEvent } from '@angular/material/paginator'; import { MatSnackBar } from '@angular/material/snack-bar'; import { Sort } from '@angular/material/sort'; import { debounceTime } from 'rxjs/operators'; import * as moment from 'moment'; import { ParteyTimeslotsService } from '../../../services/partey.service'; import { ConfirmDialog } from '../../../ui/confirm/confirm.component'; import { AuthService } from './../../../services/auth.service'; import { I18nService } from './../../../services/i18n.service'; @Component({ standalone: false, 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", "AUDIO_STREAM", "VIDEO_STREAM"]; userId: any; timeslotsColumns = ["type", "starts", "ends", "title", "description", "share", "stream", "edit", "delete"]; searchFormControl = new FormControl(); ownerFormControl = new FormControl(); afterFormControl = new FormControl(); typeFormControl = new FormControl(); constructor( private formBuilder: FormBuilder, private parteyTimeslotsService: ParteyTimeslotsService, private authService: AuthService, private i18n: I18nService, private datePipe: DatePipe, private snackBar: MatSnackBar, public dialog: MatDialog, private clipboard: Clipboard) { } ngOnInit(): void { this.authService.auth.subscribe({ next: (auth: any) => { if (auth.principal && auth.principal.userId) { this.userId = auth.principal.userId; } } }); 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 = moment.utc().format(); this.afterFormControl.setValue(new Date()); this.searchFormControl.valueChanges.pipe(debounceTime(500)).subscribe({ next: (value) => { this.filter.search = value; this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe({ next: (data: any) => { this.timeslots = data; }, error: (error) => { } }) } }) this.ownerFormControl.valueChanges.subscribe({ next: (value) => { this.filter.owner = value; this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe({ next: (data: any) => { this.timeslots = data; }, error: (error) => { } }) } }) this.typeFormControl.valueChanges.subscribe({ next: (value) => { this.filter.type = value; this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe({ next: (data: any) => { this.timeslots = data; }, error: (error) => { } }) } }) this.afterFormControl.valueChanges.subscribe({ next: (value: Date) => { this.filter.after = value && moment.utc(value).format() || undefined; this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe({ next: (data: any) => { this.timeslots = data; }, error: (error) => { } }) } }) this.refresh(); } refresh() { this.timeslotsQuota = 0; this.parteyTimeslotsService.quota().subscribe({ next: (data: number) => { this.timeslotsQuota = data; } }) this.parteyTimeslotsService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.filter).subscribe({ next: (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({ next: (data: any) => { this.timeslots = data; }, error: (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({ next: (data: any) => { this.timeslots = data; }, error: (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({ next: (result) => { if (result) { this.parteyTimeslotsService.delete(timeslot.id).subscribe({ next: (result: any) => { this.refresh(); } }) } } }); } openCreate(type) { const dialogRef = this.dialog.open(ParteyTimeslotDialog, { data: { "type": type ? type : "VIDEO", "visibility": "PROTECTED" }, minWidth: '400px' }); dialogRef.afterClosed().subscribe({ next: (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({ next: (result) => { if (result) { this.refresh(); } } }); } copySecretToClipboard(secret) { this.clipboard.copy(secret); this.snackBar.open(this.i18n.get("partey.timeslots.secret.copied", []), this.i18n.get("close", []), { duration: 3000 }); } } @Component({ standalone: false, 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", "AUDIO_STREAM", "VIDEO_STREAM"]; 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_STREAM' ? Validators.required : Validators.nullValidator], share: ['', (this.timeslot.type == 'VIDEO' || this.timeslot.type == 'AUDIO') ? Validators.required : Validators.nullValidator], }); } create(timeslot) { this.parteyTimeslotsService.create(timeslot).subscribe({ next: (result: any) => { this.dialogRef.close(timeslot); }, error: (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({ next: (result: any) => { this.dialogRef.close(timeslot); }, error: (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]); } } } }); } }