From 323ce0e885fddf0095057b9b948082c1b231909b Mon Sep 17 00:00:00 2001 From: _Bastler <_Bastler@bstly.de> Date: Mon, 16 Aug 2021 19:06:12 +0200 Subject: [PATCH] make shortened urls editable --- src/app/app.module.ts | 4 +- .../urlshortener/urlshortener.component.html | 8 + .../urlshortener/urlshortener.component.ts | 174 +++++++++++++----- .../pages/urlshortener/urlshortener.edit.html | 76 ++++++++ .../pages/urlshortener/urlshortener.edit.scss | 7 + src/app/services/urlshortener.service.ts | 4 + 6 files changed, 225 insertions(+), 48 deletions(-) create mode 100644 src/app/pages/urlshortener/urlshortener.edit.html create mode 100644 src/app/pages/urlshortener/urlshortener.edit.scss diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 6a033dd..52d6064 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -44,7 +44,7 @@ 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 {UrlShortenerComponent, UrlShortenerPasswordComponent, UrlShortenerShareDialog, UrlShortenerEditDialog} from './pages/urlshortener/urlshortener.component' import {I18nService} from './services/i18n.service'; @@ -103,7 +103,7 @@ export class XhrInterceptor implements HttpInterceptor { JitsiComponent, JitsiShareDialog, ParteyTimeslotsComponent, ParteyTimeslotDialog, MinetestAccountsComponent, - UrlShortenerComponent, UrlShortenerShareDialog, UrlShortenerPasswordComponent + UrlShortenerComponent, UrlShortenerShareDialog, UrlShortenerEditDialog, UrlShortenerPasswordComponent ], imports: [ BrowserModule, diff --git a/src/app/pages/urlshortener/urlshortener.component.html b/src/app/pages/urlshortener/urlshortener.component.html index a02abea..134447c 100644 --- a/src/app/pages/urlshortener/urlshortener.component.html +++ b/src/app/pages/urlshortener/urlshortener.component.html @@ -49,6 +49,14 @@ {{ shortenedUrl.expires | date:datetimeformat}} + + {{'urlshortener.edit' | i18n}} + + + edit + + + {{'urlshortener.delete' | i18n}} diff --git a/src/app/pages/urlshortener/urlshortener.component.ts b/src/app/pages/urlshortener/urlshortener.component.ts index 4a34b34..310edd0 100644 --- a/src/app/pages/urlshortener/urlshortener.component.ts +++ b/src/app/pages/urlshortener/urlshortener.component.ts @@ -1,23 +1,23 @@ -import {Component, OnInit, ViewChild, Inject} from '@angular/core'; -import {MatSnackBar} from '@angular/material/snack-bar'; -import {Sort} from '@angular/material/sort'; -import {FormBuilder, FormGroup, Validators, NgForm, FormControl} from '@angular/forms'; -import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog'; -import {PageEvent} from '@angular/material/paginator'; -import {ActivatedRoute} from '@angular/router'; +import { Component, OnInit, ViewChild, Inject } from '@angular/core'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { Sort } from '@angular/material/sort'; +import { FormBuilder, FormGroup, Validators, NgForm, FormControl } from '@angular/forms'; +import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { PageEvent } from '@angular/material/paginator'; +import { ActivatedRoute } from '@angular/router'; -import {MatchingValidator} from './../../utils/matching.validator'; -import {QuotaService} from '../../services/quota.service'; -import {UrlShortenerService} from '../../services/urlshortener.service'; -import {ConfirmDialog} from '../../ui/confirm/confirm.component'; -import {I18nService} from '../../services/i18n.service'; -import {environment} from '../../../environments/environment'; -import {debounceTime} from 'rxjs/operators'; +import { MatchingValidator } from './../../utils/matching.validator'; +import { QuotaService } from '../../services/quota.service'; +import { UrlShortenerService } from '../../services/urlshortener.service'; +import { ConfirmDialog } from '../../ui/confirm/confirm.component'; +import { I18nService } from '../../services/i18n.service'; +import { environment } from '../../../environments/environment'; +import { debounceTime } from 'rxjs/operators'; @Component({ selector: 'app-urlshortener', templateUrl: './urlshortener.component.html', - styleUrls: ['./urlshortener.component.scss'] + styleUrls: [ './urlshortener.component.scss' ] }) export class UrlShortenerComponent implements OnInit { @@ -30,28 +30,28 @@ export class UrlShortenerComponent implements OnInit { success: boolean; working: boolean; datetimeformat: String; - page: any = {page: 0, size: 10, sort: "code", desc: false, search: ""}; - pageSizeOptions: number[] = [5, 10, 25, 50]; + page: any = { page: 0, size: 10, sort: "code", desc: false, search: "" }; + pageSizeOptions: number[] = [ 5, 10, 25, 50 ]; - shortenedUrlColumns = ["share", "link", "note", "url", "expires", "delete"]; + shortenedUrlColumns = [ "share", "link", "note", "url", "expires", "edit", "delete" ]; constructor( private quotaService: QuotaService, private formBuilder: FormBuilder, private urlShortenerService: UrlShortenerService, private i18n: I18nService, - public dialog: MatDialog) {} + public dialog: MatDialog) { } ngOnInit(): void { this.datetimeformat = this.i18n.get('format.datetime', []); this.form = this.formBuilder.group({ - url: ['', Validators.required], - note: ['', Validators.nullValidator], - code: ['', Validators.nullValidator], - password: ['', Validators.nullValidator], - password2: ['', Validators.nullValidator], - expires: ['', Validators.nullValidator], + url: [ '', Validators.required ], + note: [ '', Validators.nullValidator ], + code: [ '', Validators.nullValidator ], + password: [ '', Validators.nullValidator ], + password2: [ '', Validators.nullValidator ], + expires: [ '', Validators.nullValidator ], }, { validator: MatchingValidator('password', 'password2') }); @@ -77,15 +77,15 @@ export class UrlShortenerComponent implements OnInit { this.working = false; }, (error) => { this.working = false; - if(error.status == 409) { + 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 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]); + for (let code in errors) { + this.form.get(code).setErrors(errors[ code ]); } } }) @@ -94,8 +94,8 @@ export class UrlShortenerComponent implements OnInit { update() { this.shortenedUrlQuota = 0; this.quotaService.quotas().subscribe((data: any) => { - for(let quota of data) { - if(quota.name == "url_shortener") { + for (let quota of data) { + if (quota.name == "url_shortener") { this.shortenedUrlQuota = quota.value; } } @@ -112,7 +112,7 @@ export class UrlShortenerComponent implements OnInit { this.page.search = this.searchFormControl.value ? this.searchFormControl.value : ""; this.urlShortenerService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.page.search).subscribe((data: any) => { this.shortenedUrls = data; - }, (error) => {}) + }, (error) => { }) } updatePages(event: PageEvent) { @@ -121,11 +121,11 @@ export class UrlShortenerComponent implements OnInit { this.page.search = this.searchFormControl.value ? this.searchFormControl.value : ""; this.urlShortenerService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.page.search).subscribe((data: any) => { this.shortenedUrls = data; - }, (error) => {}) + }, (error) => { }) } updateSort(sort: Sort) { - if(sort.direction == "") { + if (sort.direction == "") { this.page.sort = "code"; this.page.desc = false; } else { @@ -135,19 +135,19 @@ export class UrlShortenerComponent implements OnInit { this.page.search = this.searchFormControl.value ? this.searchFormControl.value : ""; this.urlShortenerService.get(this.page.page, this.page.size, this.page.sort, this.page.desc, this.page.search).subscribe((data: any) => { this.shortenedUrls = data; - }, (error) => {}) + }, (error) => { }) } confirmDelete(shortenedUrl) { const dialogRef = this.dialog.open(ConfirmDialog, { data: { 'label': 'urlshortener.confirmDelete', - 'args': [shortenedUrl.url] + 'args': [ shortenedUrl.url ] } }) dialogRef.afterClosed().subscribe(result => { - if(result) { + if (result) { this.urlShortenerService.delete(shortenedUrl.code).subscribe((result: any) => { this.update(); }) @@ -162,15 +162,96 @@ export class UrlShortenerComponent implements OnInit { }); } - open(jitsiRoom: any, moderation: boolean) { - return (moderation && jitsiRoom.moderationStarts != null || !jitsiRoom.starts || Date.parse(jitsiRoom.starts) < new Date().getTime()) && (!moderation || jitsiRoom.moderationStarts == null || Date.parse(jitsiRoom.moderationStarts) < new Date().getTime()); + edit(shortenedUrl) { + const dialogRef = this.dialog.open(UrlShortenerEditDialog, { + data: shortenedUrl, + minWidth: '400px', + }); + + dialogRef.afterClosed().subscribe(result => { + console.log(result); + if (result) { + this.update(); + } + }); } } + +@Component({ + selector: 'app-urlshortener-edit-dialog', + templateUrl: 'urlshortener.edit.html', + styleUrls: [ './urlshortener.edit.scss' ] +}) +export class UrlShortenerEditDialog { + + form: FormGroup; + shortenedUrlModel: any; + datetimeformat: string; + + constructor( + private i18n: I18nService, + private urlShortenerService: UrlShortenerService, + private snackBar: MatSnackBar, + public dialogRef: MatDialogRef, + private formBuilder: FormBuilder, + @Inject(MAT_DIALOG_DATA) public data: any) { + this.shortenedUrlModel = {}; + this.shortenedUrlModel.code = data.code; + this.shortenedUrlModel.url = data.url; + this.shortenedUrlModel.newCode = data.code; + this.shortenedUrlModel.note = data.note; + this.shortenedUrlModel.expires = data.expires; + } + + ngOnInit(): void { + this.datetimeformat = this.i18n.get('format.datetime', []); + this.form = this.formBuilder.group({ + url: [ '', Validators.required ], + note: [ '', Validators.nullValidator ], + code: [ '', Validators.nullValidator ], + newPassword: [ '', Validators.nullValidator ], + password: [ '', Validators.nullValidator ], + password2: [ '', Validators.nullValidator ], + expires: [ '', Validators.nullValidator ], + }); + } + + newPassword(event) { + this.shortenedUrlModel.newPassword = event.checked; + if (!this.shortenedUrlModel.newPassword) { + this.shortenedUrlModel.password = ""; + this.shortenedUrlModel.password2 = ""; + this.form.get('password').setErrors(null); + this.form.get('password2').setErrors(null); + } + } + + save() { + this.urlShortenerService.update(this.shortenedUrlModel).subscribe((result: any) => { + this.dialogRef.close(result); + }, (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 ]); + } + } + }); + } + +} + + @Component({ selector: 'app-urlshortener-share-dialog', templateUrl: 'urlshortener.share.html', - styleUrls: ['./urlshortener.share.scss'] + styleUrls: [ './urlshortener.share.scss' ] }) export class UrlShortenerShareDialog { @@ -187,7 +268,7 @@ export class UrlShortenerShareDialog { ngOnInit(): void { this.datetimeformat = this.i18n.get('format.datetime', []); - this.shortenedUrl.shareText = this.i18n.get('urlshortener.share.text', [this.shortenedUrl.link]); + this.shortenedUrl.shareText = this.i18n.get('urlshortener.share.text', [ this.shortenedUrl.link ]); } copyToClipboard(text) { @@ -206,10 +287,11 @@ export class UrlShortenerShareDialog { } + @Component({ selector: 'app-urlshortener-password', templateUrl: './urlshortener.password.html', - styleUrls: ['./urlshortener.password.scss'] + styleUrls: [ './urlshortener.password.scss' ] }) export class UrlShortenerPasswordComponent implements OnInit { @@ -218,13 +300,13 @@ export class UrlShortenerPasswordComponent implements OnInit { invalidPassword: boolean = false; constructor( - private route: ActivatedRoute) {} + private route: ActivatedRoute) { } async ngOnInit() { this.code = this.route.snapshot.paramMap.get('code'); this.route.queryParams.subscribe(params => { - if(params['error'] || params['error'] == '') { + if (params[ 'error' ] || params[ 'error' ] == '') { this.invalidPassword = true; } }); diff --git a/src/app/pages/urlshortener/urlshortener.edit.html b/src/app/pages/urlshortener/urlshortener.edit.html new file mode 100644 index 0000000..213677c --- /dev/null +++ b/src/app/pages/urlshortener/urlshortener.edit.html @@ -0,0 +1,76 @@ +

+ edit {{'urlshortener.edit' | i18n}} +

+ +
+ + + + {{'urlshortener.error.url' | i18n}} + + + + + + + {{'urlshortener.error.note' | i18n}} + + + + + + + {{'urlshortener.advanced' | i18n}} + + + + + {{'urlshortener.newPassword' | i18n}} + + + + + +
+ {{'password.error.' + error.key | i18n}}
+
+
+
+ + + + + {{'password.not-match' | i18n}} + + + + + + + + + {{'urlshortener.error.expires' | i18n}} + + + + + + + {{'urlshortener.error.code' | i18n}} + + +
+
+
+ + + + \ No newline at end of file diff --git a/src/app/pages/urlshortener/urlshortener.edit.scss b/src/app/pages/urlshortener/urlshortener.edit.scss new file mode 100644 index 0000000..03bec19 --- /dev/null +++ b/src/app/pages/urlshortener/urlshortener.edit.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/services/urlshortener.service.ts b/src/app/services/urlshortener.service.ts index 6c1657c..b673ccb 100644 --- a/src/app/services/urlshortener.service.ts +++ b/src/app/services/urlshortener.service.ts @@ -24,6 +24,10 @@ export class UrlShortenerService { return this.http.post(environment.apiUrl + "/url/shortener", shortendUrlModel); } + update(shortendUrlModel) { + return this.http.patch(environment.apiUrl + "/url/shortener", shortendUrlModel); + } + delete(code) { return this.http.delete(environment.apiUrl + "/url/shortener/" + code); }