add search + note
This commit is contained in:
parent
a69647ffde
commit
57d2bf97fb
@ -1,15 +1,18 @@
|
|||||||
import { Directive, OnInit } from '@angular/core';
|
import { Directive, ElementRef, OnInit } from '@angular/core';
|
||||||
import { MatInput } from '@angular/material/input';
|
import { MatInput } from '@angular/material/input';
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[matInputAutofocus]',
|
selector: '[matAutofocus]',
|
||||||
})
|
})
|
||||||
export class AutofocusDirective implements OnInit {
|
export class AutofocusDirective implements OnInit {
|
||||||
|
|
||||||
constructor(private matInput: MatInput) { }
|
constructor(private element: ElementRef) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
setTimeout(() => this.matInput.focus());
|
setTimeout(() => {
|
||||||
|
this.element.nativeElement.focus();
|
||||||
|
this.element.nativeElement.scrollIntoView();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -8,7 +8,7 @@
|
|||||||
{{'security.2fa.totp.invalid' | i18n}}
|
{{'security.2fa.totp.invalid' | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input id="code" name="code" matInput placeholder="{{'security.2fa.totp.code' | i18n}}" required matInputAutofocus>
|
<input id="code" name="code" matInput placeholder="{{'security.2fa.totp.code' | i18n}}" required matAutofocus>
|
||||||
<mat-error>
|
<mat-error>
|
||||||
{{'security.2fa.totp.missing' | i18n}}
|
{{'security.2fa.totp.missing' | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
{{'login.invalid' | i18n}}
|
{{'login.invalid' | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input id="username" name="username" matInput placeholder="{{'username' | i18n}}" required matInputAutofocus>
|
<input id="username" name="username" matInput placeholder="{{'username' | i18n}}" required matAutofocus>
|
||||||
<mat-error>
|
<mat-error>
|
||||||
{{'username.missing' | i18n}}
|
{{'username.missing' | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input id="code" name="code" matInput placeholder="{{'security.2fa.totp.code' | i18n}}" formControlName="code"
|
<input id="code" name="code" matInput placeholder="{{'security.2fa.totp.code' | i18n}}" formControlName="code"
|
||||||
required matInputAutofocus>
|
required matAutofocus>
|
||||||
<mat-error>
|
<mat-error>
|
||||||
{{'security.2fa.totp.missing' | i18n}}
|
{{'security.2fa.totp.missing' | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input id="username" name="username" matInput placeholder="{{'username' | i18n}}"
|
<input id="username" name="username" matInput placeholder="{{'username' | i18n}}"
|
||||||
formControlName="username" required matInputAutofocus>
|
formControlName="username" required matAutofocus>
|
||||||
<mat-error>
|
<mat-error>
|
||||||
{{'username.missing' | i18n}}
|
{{'username.missing' | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input matInput placeholder="{{'username' | i18n}}" formControlName="username"
|
<input matInput placeholder="{{'username' | i18n}}" formControlName="username"
|
||||||
[(ngModel)]="model.username" required matInputAutofocus>
|
[(ngModel)]="model.username" required matAutofocus>
|
||||||
<mat-error>
|
<mat-error>
|
||||||
{{'username.error' | i18n}}
|
{{'username.error' | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
<h3>{{'services' | i18n}}</h3>
|
<h3>{{'services' | i18n}}</h3>
|
||||||
|
|
||||||
<p *ngIf="!services || services.length == 0">{{'services.empty' | i18n}}</p>
|
<mat-progress-bar *ngIf="!services" mode="indeterminate"></mat-progress-bar>
|
||||||
|
|
||||||
|
<p *ngIf="services && services.length == 0">{{'services.empty' | i18n}}</p>
|
||||||
|
|
||||||
<table *ngIf="services && services.length > 0" mat-table matSort [dataSource]="services" (matSortChange)="sortData($event)" matSortActive="name" matSortDirection="asc">
|
<table *ngIf="services && services.length > 0" mat-table matSort [dataSource]="services" (matSortChange)="sortData($event)" matSortActive="name" matSortDirection="asc">
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import {I18nService} from '../../services/i18n.service';
|
|||||||
})
|
})
|
||||||
export class ServicesComponent implements OnInit {
|
export class ServicesComponent implements OnInit {
|
||||||
|
|
||||||
services = [];
|
services;
|
||||||
serviceColumns = ["icon", "name", "text"];
|
serviceColumns = ["icon", "name", "text"];
|
||||||
|
|
||||||
constructor(private serviceService: ServiceService, private i18n: I18nService) {}
|
constructor(private serviceService: ServiceService, private i18n: I18nService) {}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
{{'tokens.redeemed' | i18n}}
|
{{'tokens.redeemed' | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input matInput placeholder="{{'token' | i18n}}" formControlName="token" matInputAutofocus>
|
<input matInput placeholder="{{'token' | i18n}}" formControlName="token" matAutofocus>
|
||||||
<mat-error>
|
<mat-error>
|
||||||
{{'tokens.provide-valid' | i18n}}
|
{{'tokens.provide-valid' | i18n}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
<h3>{{'urlshortener' | i18n}}</h3>
|
<h3>{{'urlshortener' | i18n}}</h3>
|
||||||
|
|
||||||
<div *ngIf="shortenedUrls">
|
<div *ngIf="shortenedUrls">
|
||||||
|
<mat-form-field>
|
||||||
|
<input matInput [formControl]="searchFormControl" placeholder="{{'urlshortener.search' | i18n}}">
|
||||||
|
</mat-form-field>
|
||||||
<table mat-table matSort [dataSource]="shortenedUrls.content" (matSortChange)="updateSort($event)">
|
<table mat-table matSort [dataSource]="shortenedUrls.content" (matSortChange)="updateSort($event)">
|
||||||
|
|
||||||
<ng-container matColumnDef="share">
|
<ng-container matColumnDef="share">
|
||||||
@ -80,6 +83,14 @@
|
|||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field>
|
||||||
|
<textarea matInput type="note" placeholder="{{'urlshortener.note' | i18n}}" formControlName="note"
|
||||||
|
[(ngModel)]="shortenedUrl.note"></textarea>
|
||||||
|
<mat-error>
|
||||||
|
{{'urlshortener.error.note' | i18n}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-expansion-panel>
|
<mat-expansion-panel>
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>
|
<mat-panel-title>
|
||||||
@ -95,6 +106,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input matInput type="password" placeholder="{{'password.confirm' | i18n}}" formControlName="password2"
|
<input matInput type="password" placeholder="{{'password.confirm' | i18n}}" formControlName="password2"
|
||||||
[(ngModel)]="shortenedUrl.password2">
|
[(ngModel)]="shortenedUrl.password2">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {Component, OnInit, ViewChild, Inject} from '@angular/core';
|
import {Component, OnInit, ViewChild, Inject} from '@angular/core';
|
||||||
import {MatSnackBar} from '@angular/material/snack-bar';
|
import {MatSnackBar} from '@angular/material/snack-bar';
|
||||||
import {Sort} from '@angular/material/sort';
|
import {Sort} from '@angular/material/sort';
|
||||||
import {FormBuilder, FormGroup, Validators, NgForm} from '@angular/forms';
|
import {FormBuilder, FormGroup, Validators, NgForm, FormControl} from '@angular/forms';
|
||||||
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
|
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
|
||||||
import {PageEvent} from '@angular/material/paginator';
|
import {PageEvent} from '@angular/material/paginator';
|
||||||
import {ActivatedRoute} from '@angular/router';
|
import {ActivatedRoute} from '@angular/router';
|
||||||
@ -12,6 +12,7 @@ import {UrlShortenerService} from '../../services/urlshortener.service';
|
|||||||
import {ConfirmDialog} from '../../ui/confirm/confirm.component';
|
import {ConfirmDialog} from '../../ui/confirm/confirm.component';
|
||||||
import {I18nService} from '../../services/i18n.service';
|
import {I18nService} from '../../services/i18n.service';
|
||||||
import {environment} from '../../../environments/environment';
|
import {environment} from '../../../environments/environment';
|
||||||
|
import {debounceTime} from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-urlshortener',
|
selector: 'app-urlshortener',
|
||||||
@ -22,13 +23,14 @@ export class UrlShortenerComponent implements OnInit {
|
|||||||
|
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
@ViewChild('formDirective') private formDirective: NgForm;
|
@ViewChild('formDirective') private formDirective: NgForm;
|
||||||
|
searchFormControl = new FormControl();
|
||||||
shortenedUrlQuota: number = 0;
|
shortenedUrlQuota: number = 0;
|
||||||
shortenedUrls: any;
|
shortenedUrls: any;
|
||||||
shortenedUrl: any = {};
|
shortenedUrl: any = {};
|
||||||
success: boolean;
|
success: boolean;
|
||||||
working: boolean;
|
working: boolean;
|
||||||
datetimeformat: String;
|
datetimeformat: String;
|
||||||
page: any = {page: 0, size: 10, sort: "code", desc: false};
|
page: any = {page: 0, size: 10, sort: "code", desc: false, search: ""};
|
||||||
pageSizeOptions: number[] = [5, 10, 25, 50];
|
pageSizeOptions: number[] = [5, 10, 25, 50];
|
||||||
|
|
||||||
shortenedUrlColumns = ["share", "link", "note", "url", "expires", "delete"];
|
shortenedUrlColumns = ["share", "link", "note", "url", "expires", "delete"];
|
||||||
@ -45,6 +47,7 @@ export class UrlShortenerComponent implements OnInit {
|
|||||||
|
|
||||||
this.form = this.formBuilder.group({
|
this.form = this.formBuilder.group({
|
||||||
url: ['', Validators.required],
|
url: ['', Validators.required],
|
||||||
|
note: ['', Validators.nullValidator],
|
||||||
code: ['', Validators.nullValidator],
|
code: ['', Validators.nullValidator],
|
||||||
password: ['', Validators.nullValidator],
|
password: ['', Validators.nullValidator],
|
||||||
password2: ['', Validators.nullValidator],
|
password2: ['', Validators.nullValidator],
|
||||||
@ -53,6 +56,14 @@ export class UrlShortenerComponent implements OnInit {
|
|||||||
validator: MatchingValidator('password', 'password2')
|
validator: MatchingValidator('password', 'password2')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
this.searchFormControl.valueChanges.pipe(debounceTime(500)).subscribe(value => {
|
||||||
|
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;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,15 +101,25 @@ export class UrlShortenerComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.urlShortenerService.get(this.page.page, this.page.size, this.page.sort, this.page.desc).subscribe((data: any) => {
|
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;
|
this.shortenedUrls = data;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateSearch() {
|
||||||
|
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) => {})
|
||||||
|
}
|
||||||
|
|
||||||
updatePages(event: PageEvent) {
|
updatePages(event: PageEvent) {
|
||||||
this.page.page = event.pageIndex;
|
this.page.page = event.pageIndex;
|
||||||
this.page.size = event.pageSize;
|
this.page.size = event.pageSize;
|
||||||
this.urlShortenerService.get(this.page.page, this.page.size, this.page.sort, this.page.desc).subscribe((data: any) => {
|
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;
|
this.shortenedUrls = data;
|
||||||
}, (error) => {})
|
}, (error) => {})
|
||||||
}
|
}
|
||||||
@ -111,7 +132,8 @@ export class UrlShortenerComponent implements OnInit {
|
|||||||
this.page.sort = sort.active;
|
this.page.sort = sort.active;
|
||||||
this.page.desc = sort.direction == "desc";
|
this.page.desc = sort.direction == "desc";
|
||||||
}
|
}
|
||||||
this.urlShortenerService.get(this.page.page, this.page.size, this.page.sort, this.page.desc).subscribe((data: any) => {
|
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;
|
this.shortenedUrls = data;
|
||||||
}, (error) => {})
|
}, (error) => {})
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<h2>{{'urlshortener.password' | i18n}}
|
<h2>{{'urlshortener.password' | i18n}}
|
||||||
</h2>
|
</h2>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input id="password" name="password" matInput type="password" placeholder="{{'password' | i18n}}" required matInputAutofocus>
|
<input id="password" name="password" matInput type="password" placeholder="{{'password' | i18n}}" required matAutofocus>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-error *ngIf="invalidPassword">
|
<mat-error *ngIf="invalidPassword">
|
||||||
{{'urlshortener.password.invalid' | i18n}}
|
{{'urlshortener.password.invalid' | i18n}}
|
||||||
|
@ -11,8 +11,8 @@ export class UrlShortenerService {
|
|||||||
constructor(private http: HttpClient) {
|
constructor(private http: HttpClient) {
|
||||||
}
|
}
|
||||||
|
|
||||||
get(page: number, size: number, sort: string, desc: boolean) {
|
get(page: number, size: number, sort: string, desc: boolean, search: string) {
|
||||||
const httpParams = new HttpParams().set("page", "" + page).set("size", "" + size).set("sort", sort).set("desc", "" + desc);
|
const httpParams = new HttpParams().set("page", "" + page).set("size", "" + size).set("sort", sort).set("desc", "" + desc).set("search", search);
|
||||||
return this.http.get(environment.apiUrl + "/url/shortener", {params: httpParams});
|
return this.http.get(environment.apiUrl + "/url/shortener", {params: httpParams});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
{{text}}
|
{{text}}
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
<mat-dialog-actions>
|
<mat-dialog-actions>
|
||||||
|
<button mat-raised-button [mat-dialog-close]="true" color="accent" matAutofocus>{{'confirm' | i18n}}</button>
|
||||||
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
||||||
<button mat-raised-button [mat-dialog-close]="true" color="accent">{{'confirm' | i18n}}</button>
|
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
Loading…
Reference in New Issue
Block a user