add invites
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
<h3>{{'invites' | i18n}}</h3>
|
||||
|
||||
<table mat-table matSort [dataSource]="invites">
|
||||
|
||||
<ng-container matColumnDef="starts">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'invite.starts' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let invite"> {{ invite.starts | date:datetimeformat}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="expires">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'invite.expires' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let invite"> {{ invite.expires | date:datetimeformat}} </td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<ng-container matColumnDef="link">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'invite.link' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let invite"> <a href="{{ invite.codeLink}}" target="_blank" mat-button color="accent">
|
||||
{{
|
||||
invite.code}}</a> </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="note">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'invite.note' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let invite"> {{ invite.note}} </td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="inviteColumns"></tr>
|
||||
<tr mat-row *matRowDef="let myRowData; columns: inviteColumns"></tr>
|
||||
</table>
|
||||
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<p>{{'invites.info' | i18n}}</p>
|
||||
<p *ngIf="!inviteQuota">{{'invites.noQuota' | i18n}}</p>
|
||||
<div *ngIf="inviteQuota">
|
||||
<p>{{'invites.left' | i18n:inviteQuota}}</p>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="inviteQuota && !working" mat-raised-button color="primary" (click)="create()">
|
||||
{{'invite.create' | i18n}}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
|
||||
<div *ngIf="others && others.content">
|
||||
<h4>{{'invites.others' | i18n}}</h4>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput [formControl]="searchFormControl" placeholder="{{'invites.search' | i18n}}">
|
||||
</mat-form-field>
|
||||
|
||||
<table mat-table matSort [dataSource]="others.content">
|
||||
<ng-container matColumnDef="note">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'invite.note' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let invite"> {{ invite.note}} </td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="otherColumns"></tr>
|
||||
<tr mat-row *matRowDef="let myRowData; columns: otherColumns"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSizeOptions]="pageSizeOptions" [length]="others.totalElements" [pageSize]="others.size" (page)="updateOthers($event)" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { InvitesComponent } from './invites.component';
|
||||
|
||||
describe('InvitesComponent', () => {
|
||||
let component: InvitesComponent;
|
||||
let fixture: ComponentFixture<InvitesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ InvitesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(InvitesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,99 @@
|
||||
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {PageEvent} from '@angular/material/paginator';
|
||||
|
||||
import {AuthService} from '../../services/auth.service';
|
||||
import {I18nService} from '../../services/i18n.service';
|
||||
import {QuotaService} from '../../services/quota.service';
|
||||
import {InviteService} from '../../services/invites.service';
|
||||
import {FormControl} from '@angular/forms';
|
||||
import {debounceTime} from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-invites',
|
||||
templateUrl: './invites.component.html',
|
||||
styleUrls: ['./invites.component.scss']
|
||||
})
|
||||
export class InvitesComponent implements OnInit {
|
||||
|
||||
quota: string;
|
||||
invites: any[];
|
||||
others: any;
|
||||
inviteQuota: number = 0;
|
||||
success: boolean;
|
||||
working: boolean;
|
||||
datetimeformat: string;
|
||||
pageSizeOptions: number[] = [5, 10, 25, 50];
|
||||
searchFormControl = new FormControl();
|
||||
|
||||
inviteColumns = ["starts", "expires", "link", "note"];
|
||||
otherColumns = ["note"];
|
||||
|
||||
constructor(
|
||||
private authService: AuthService,
|
||||
private inviteService: InviteService,
|
||||
private i18n: I18nService,
|
||||
private quotaService: QuotaService,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute) {
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.datetimeformat = this.i18n.get('format.datetime', []);
|
||||
this.quota = this.route.snapshot.paramMap.get('quota');
|
||||
this.searchFormControl.valueChanges.pipe(debounceTime(500)).subscribe(value => {
|
||||
|
||||
this.inviteService.getOthersPages(this.quota, 0, this.others.size, value).subscribe((data: any) => {
|
||||
this.others = data;
|
||||
}, (error) => {})
|
||||
})
|
||||
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
update(): void {
|
||||
this.inviteQuota = 0;
|
||||
this.quotaService.quotas().subscribe((data: any) => {
|
||||
for(let quota of data) {
|
||||
if(quota.name == "invite_" + this.quota) {
|
||||
this.inviteQuota = quota.value;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
this.inviteService.get(this.quota).subscribe((data: any) => {
|
||||
this.invites = data;
|
||||
})
|
||||
|
||||
this.inviteService.getOthers(this.quota).subscribe((data: any) => {
|
||||
this.others = data;
|
||||
}, (error) => {})
|
||||
}
|
||||
|
||||
create(): void {
|
||||
this.working = true;
|
||||
|
||||
|
||||
this.inviteService.create(this.quota, {}).subscribe(response => {
|
||||
this.update();
|
||||
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;
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
updateOthers(event: PageEvent) {
|
||||
this.inviteService.getOthersPages(this.quota, event.pageIndex, event.pageSize, "").subscribe((data: any) => {
|
||||
this.others = data;
|
||||
}, (error) => {})
|
||||
}
|
||||
}
|
||||
@@ -2,24 +2,34 @@
|
||||
|
||||
<p *ngIf="!services || services.length == 0">{{'services.empty' | i18n}}</p>
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutGap="16px grid">
|
||||
<div fxFlex="33.33%" fxFlex.sm="50%" fxFlex.xs="100%" *ngFor="let service of services">
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-icon>{{'services.' + service.name + '.icon' | i18n}}</mat-icon>
|
||||
<mat-card-title>{{'services.' + service.name + '.title' | i18n}}</mat-card-title>
|
||||
<mat-card-subtitle>{{'services.' + service.name + '.subtitle' | i18n}}</mat-card-subtitle>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<p>
|
||||
{{ 'services.' + service.name + '.text' | i18n}}
|
||||
</p>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<a href="{{service.url}}" [target]="service.sameSite ? '_self' : '_blank'" mat-raised-button
|
||||
color="accent">{{'services.goto' | i18n}} <mat-icon *ngIf="!service.sameSite" inline="true">
|
||||
open_in_new</mat-icon></a>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table *ngIf="services && services.length > 0" mat-table matSort [dataSource]="services" (matSortChange)="sortData($event)" matSortActive="name" matSortDirection="desc">
|
||||
|
||||
<ng-container matColumnDef="icon">
|
||||
<th mat-header-cell *matHeaderCellDef> </th>
|
||||
<td mat-cell *matCellDef="let service">
|
||||
<mat-icon>{{'services.' + service.name + '.icon' | i18n}}</mat-icon>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="name"> {{'service.name' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let service" class="text-center">
|
||||
<a href="{{service.url}}" [target]="service.sameSite ? '_self' : '_blank'" mat-button color="accent">
|
||||
<strong>{{'services.' + service.name + '.title' | i18n}}</strong>
|
||||
<mat-icon *ngIf="!service.sameSite" inline="true">
|
||||
open_in_new</mat-icon>
|
||||
</a>
|
||||
<div><small>{{'services.' + service.name + '.subtitle' | i18n}}</small></div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="text">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'service.text' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let service">{{ 'services.' + service.name + '.text' | i18n}}</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="serviceColumns"></tr>
|
||||
<tr mat-row *matRowDef="let myRowData; columns: serviceColumns"></tr>
|
||||
</table>
|
||||
@@ -1,5 +1,7 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { ServiceService } from '../../services/service.service';
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Sort} from '@angular/material/sort';
|
||||
import {ServiceService} from '../../services/service.service';
|
||||
import {I18nService} from '../../services/i18n.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-services',
|
||||
@@ -9,13 +11,34 @@ import { ServiceService } from '../../services/service.service';
|
||||
export class ServicesComponent implements OnInit {
|
||||
|
||||
services = [];
|
||||
serviceColumns = ["icon", "name", "text"];
|
||||
|
||||
constructor(private serviceService: ServiceService) { }
|
||||
constructor(private serviceService: ServiceService, private i18n: I18nService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.serviceService.services().subscribe((data: any) => {
|
||||
this.services = data;
|
||||
this.sortData({"active": "name", "direction": "desc"});
|
||||
})
|
||||
}
|
||||
|
||||
sortData(sort: Sort) {
|
||||
const data = this.services.slice();
|
||||
if(!sort.active || sort.direction === '') {
|
||||
this.services = data;
|
||||
return;
|
||||
}
|
||||
|
||||
this.services = data.sort((a, b) => {
|
||||
const isAsc = sort.direction === 'asc';
|
||||
switch(sort.active) {
|
||||
case 'name': return this.compare(this.i18n.get('services.' + a.name + '.title', []), this.i18n.get('services.' + b.name + '.title', []), isAsc);
|
||||
default: return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
compare(a: number | string | String, b: number | string | String, isAsc: boolean) {
|
||||
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user