upgrade angualr, fix keep session attribute
This commit is contained in:
parent
0b3d658b10
commit
5dc98a3151
16517
package-lock.json
generated
16517
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
63
package.json
63
package.json
@ -11,48 +11,45 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular-material-components/datetime-picker": "^9.0.0",
|
||||
"@angular-material-components/moment-adapter": "^9.0.0",
|
||||
"@angular/animations": "^15.0.4",
|
||||
"@angular/cdk": "^15.0.3",
|
||||
"@angular/common": "^15.0.4",
|
||||
"@angular/compiler": "^15.0.4",
|
||||
"@angular/core": "^15.0.4",
|
||||
"@angular/forms": "^15.0.4",
|
||||
"@angular/material": "^15.0.3",
|
||||
"@angular/material-moment-adapter": "^15.0.3",
|
||||
"@angular/platform-browser": "^15.0.4",
|
||||
"@angular/platform-browser-dynamic": "^15.0.4",
|
||||
"@angular/router": "^15.0.4",
|
||||
"@angular/animations": "^17.0.6",
|
||||
"@angular/cdk": "^17.0.3",
|
||||
"@angular/common": "^17.0.6",
|
||||
"@angular/compiler": "^17.0.6",
|
||||
"@angular/core": "^17.0.6",
|
||||
"@angular/forms": "^17.0.6",
|
||||
"@angular/material": "^17.0.3",
|
||||
"@angular/material-moment-adapter": "^17.0.3",
|
||||
"@angular/platform-browser": "^17.0.6",
|
||||
"@angular/platform-browser-dynamic": "^17.0.6",
|
||||
"@angular/router": "^17.0.6",
|
||||
"moment": "^2.29.4",
|
||||
"ng-qrcode": "^8.0.1",
|
||||
"ngx-mat-timepicker": "^15.1.2",
|
||||
"openpgp": "^5.5.0",
|
||||
"ng-qrcode": "^17.0.0",
|
||||
"openpgp": "^5.11.0",
|
||||
"qr-scanner": "^1.4.2",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.4.1",
|
||||
"rxjs": "~7.8.1",
|
||||
"tslib": "^2.6.2",
|
||||
"unique-names-generator": "^4.7.1",
|
||||
"zone.js": "~0.12.0"
|
||||
"zone.js": "~0.14.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^15.0.4",
|
||||
"@angular/cli": "^15.0.4",
|
||||
"@angular/compiler-cli": "^15.0.4",
|
||||
"@angular/localize": "^15.0.4",
|
||||
"@types/jasmine": "^4.3.1",
|
||||
"@types/jasminewd2": "^2.0.10",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/openpgp": "^4.4.18",
|
||||
"jasmine-core": "~4.5.0",
|
||||
"@angular-devkit/build-angular": "^17.0.6",
|
||||
"@angular/cli": "^17.0.6",
|
||||
"@angular/compiler-cli": "^17.0.6",
|
||||
"@angular/localize": "^17.0.6",
|
||||
"@types/jasmine": "^5.1.4",
|
||||
"@types/jasminewd2": "^2.0.13",
|
||||
"@types/node": "^20.10.4",
|
||||
"@types/openpgp": "^4.4.22",
|
||||
"jasmine-core": "~5.1.1",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"karma": "^6.4.1",
|
||||
"karma-chrome-launcher": "~3.1.1",
|
||||
"karma": "^6.4.2",
|
||||
"karma-chrome-launcher": "~3.2.0",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.3",
|
||||
"karma-jasmine": "~5.1.0",
|
||||
"karma-jasmine-html-reporter": "^2.0.0",
|
||||
"karma-jasmine-html-reporter": "^2.1.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~10.9.1",
|
||||
"ts-node": "~10.9.2",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~4.8.4"
|
||||
"typescript": "~5.2.2"
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import { BorrowComponent } from './pages/borrow/borrow.component';
|
||||
import { InviteCodeComponent } from './pages/invites/code/code.component';
|
||||
import { JukeboxComponent } from './pages/jukebox/jukebox.compontent';
|
||||
import { FormLoginOidcComponent } from './pages/form-login-oidc/form-login-oidc.component';
|
||||
import { DyndnsComponent } from './pages/account/dyndns/dyndns.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: 'profile/:username', component: UserComponent, canActivate: [AuthUpdateGuard] },
|
||||
@ -59,7 +60,8 @@ const routes: Routes = [
|
||||
{ path: 'security', component: SecurityComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'voucher', component: VoucherComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'aliases', component: AliasesComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'domains', component: DomainsComponent, canActivate: [AuthenticatedGuard] }
|
||||
{ path: 'domains', component: DomainsComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'dyndns', component: DyndnsComponent, canActivate: [AuthenticatedGuard] }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ import { VoucherDialog } from './pages/account/voucher/voucher.component';
|
||||
import { InfoComponent } from './pages/account/info/info.component';
|
||||
import { AliasesComponent } from './pages/account/aliases/aliases.component';
|
||||
import { DomainsComponent } from './pages/account/domains/domains.component';
|
||||
import { DyndnsComponent } from './pages/account/dyndns/dyndns.component';
|
||||
import { ProfileComponent } from './pages/account/profile/profile.component';
|
||||
import { PasswordComponent } from './pages/password/password.component';
|
||||
import { PasswordResetComponent } from './pages/password-reset/password-reset.component';
|
||||
@ -62,10 +63,12 @@ import { DurationpickerComponent } from './ui/durationpicker/durationpicker.comp
|
||||
import { InviteCodeComponent } from './pages/invites/code/code.component';
|
||||
import { InviteEditComponent } from './pages/invites/edit/invite.edit';
|
||||
import { MatPaginatorIntl } from '@angular/material/paginator';
|
||||
import { NgxMatDateAdapter, NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker';
|
||||
import { NgxMatMomentAdapter } from '@angular-material-components/moment-adapter';
|
||||
import { JukeboxComponent } from './pages/jukebox/jukebox.compontent';
|
||||
import { FormLoginOidcComponent } from './pages/form-login-oidc/form-login-oidc.component';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MomentDateModule } from '@angular/material-moment-adapter';
|
||||
import { MAT_DATE_FORMATS } from '@angular/material/core';
|
||||
import { DatetimepickerComponent } from './ui/datetimepicker/datetimepicker.component';
|
||||
|
||||
|
||||
export function init_app(i18n: I18nService) {
|
||||
@ -109,6 +112,7 @@ export class XhrInterceptor implements HttpInterceptor {
|
||||
InfoComponent,
|
||||
AliasesComponent,
|
||||
DomainsComponent,
|
||||
DyndnsComponent,
|
||||
ProfileComponent,
|
||||
PasswordComponent,
|
||||
PasswordResetComponent,
|
||||
@ -126,6 +130,7 @@ export class XhrInterceptor implements HttpInterceptor {
|
||||
UrlShortenerComponent, UrlShortenerShareDialog, UrlShortenerEditDialog, UrlShortenerPasswordComponent,
|
||||
BorrowComponent, BorrowItemsComponent, BorrowItemEditComponent, BorrowRequestsComponent, BorrowRequestEditComponent, BorrowProvingComponent, BorrowProvingResultDialog,
|
||||
DividerComponent, DividertestComponent,
|
||||
DatetimepickerComponent,
|
||||
DurationpickerComponent,
|
||||
JukeboxComponent
|
||||
],
|
||||
@ -139,7 +144,8 @@ export class XhrInterceptor implements HttpInterceptor {
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
QrCodeModule,
|
||||
|
||||
MatDatepickerModule,
|
||||
MomentDateModule
|
||||
],
|
||||
exports: [MaterialModule],
|
||||
providers: [{ provide: APP_INITIALIZER, useFactory: init_app, deps: [I18nService], multi: true }, { provide: HTTP_INTERCEPTORS, useClass: XhrInterceptor, multi: true }, DatePipe,
|
||||
@ -149,15 +155,8 @@ export class XhrInterceptor implements HttpInterceptor {
|
||||
service.injectI18n(i18n)
|
||||
return service;
|
||||
}, deps: [I18nService]
|
||||
},
|
||||
{
|
||||
provide: NgxMatDateAdapter,
|
||||
useClass: NgxMatMomentAdapter,
|
||||
useFactory: (i18n: I18nService) => {
|
||||
return new NgxMatMomentAdapter(i18n.getLocale(), { strict: true });
|
||||
}, deps: [I18nService]
|
||||
}, {
|
||||
provide: NGX_MAT_DATE_FORMATS, useFactory: (i18n: I18nService) => {
|
||||
provide: MAT_DATE_FORMATS, useFactory: (i18n: I18nService) => {
|
||||
const datetimeformat = i18n.get('format.datetime', []);
|
||||
return {
|
||||
parse: {
|
||||
@ -165,9 +164,9 @@ export class XhrInterceptor implements HttpInterceptor {
|
||||
},
|
||||
display: {
|
||||
dateInput: datetimeformat,
|
||||
monthYearLabel: "MMM YYYY",
|
||||
dateA11yLabel: "LL",
|
||||
monthYearA11yLabel: "MMMM YYYY"
|
||||
monthYearLabel: 'MMM YYYY',
|
||||
dateA11yLabel: 'LL',
|
||||
monthYearA11yLabel: 'MMMM YYYY'
|
||||
}
|
||||
};
|
||||
}, deps: [I18nService]
|
||||
|
@ -44,15 +44,6 @@ import {MatSortModule} from '@angular/material/sort';
|
||||
import {MatTableModule} from '@angular/material/table';
|
||||
import {MatMomentDateModule} from '@angular/material-moment-adapter';
|
||||
|
||||
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
|
||||
|
||||
import {
|
||||
NgxMatDatetimePickerModule,
|
||||
NgxMatNativeDateModule
|
||||
} from '@angular-material-components/datetime-picker';
|
||||
|
||||
import { NgxMatTimepickerModule } from 'ngx-mat-timepicker';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [
|
||||
@ -92,11 +83,7 @@ import { NgxMatTimepickerModule } from 'ngx-mat-timepicker';
|
||||
MatPaginatorModule,
|
||||
MatSortModule,
|
||||
MatTableModule,
|
||||
MatMomentDateModule,
|
||||
NgxMatMomentModule,
|
||||
NgxMatDatetimePickerModule,
|
||||
NgxMatNativeDateModule,
|
||||
NgxMatTimepickerModule
|
||||
MatMomentDateModule
|
||||
],
|
||||
exports: [
|
||||
MatAutocompleteModule,
|
||||
@ -133,10 +120,7 @@ import { NgxMatTimepickerModule } from 'ngx-mat-timepicker';
|
||||
MatTooltipModule,
|
||||
MatPaginatorModule,
|
||||
MatSortModule,
|
||||
MatTableModule,
|
||||
NgxMatDatetimePickerModule,
|
||||
NgxMatNativeDateModule,
|
||||
NgxMatTimepickerModule
|
||||
MatTableModule
|
||||
]
|
||||
})
|
||||
export class MaterialModule {}
|
||||
|
@ -14,6 +14,8 @@
|
||||
[active]="rlaaliases.isActive">{{'user.aliases' | i18n}}</a>
|
||||
<a *ngIf="advancedView" mat-tab-link routerLink="domains" #rladomains="routerLinkActive" routerLinkActive
|
||||
[active]="rladomains.isActive">{{'user.domains' | i18n}}</a>
|
||||
<a *ngIf="advancedView" mat-tab-link routerLink="dyndns" #rladyndns="routerLinkActive" routerLinkActive
|
||||
[active]="rladyndns.isActive">{{'user.dyndns' | i18n}}</a>
|
||||
<a style="align-self: center;">
|
||||
<mat-slide-toggle [(ngModel)]="advancedView">
|
||||
<span *ngIf="!advancedView">{{'account.advanced' | i18n}}</span>
|
||||
|
@ -1,18 +1,24 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
|
||||
import { AuthService } from './../../services/auth.service';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { MatTabNavPanel } from '@angular/material/tabs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-account',
|
||||
templateUrl: './account.component.html',
|
||||
styleUrls: [ './account.component.scss' ]
|
||||
styleUrls: ['./account.component.scss']
|
||||
})
|
||||
export class AccountComponent implements OnInit {
|
||||
|
||||
advancedViews: string[] = ["aliases", "domains", "dyndns"]
|
||||
|
||||
advancedView: boolean = false;
|
||||
auth;
|
||||
|
||||
constructor(private authService: AuthService) {
|
||||
@ViewChild('tabPanel') tabPanel: MatTabNavPanel;
|
||||
|
||||
constructor(private authService: AuthService, private router: Router) {
|
||||
this.authService.auth.subscribe({
|
||||
next: (data) => {
|
||||
this.auth = data;
|
||||
@ -21,6 +27,7 @@ export class AccountComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.advancedView = this.advancedViews.indexOf(this.router.url.replace("/account/", "")) != -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
24
src/app/pages/account/dyndns/dyndns.component.html
Normal file
24
src/app/pages/account/dyndns/dyndns.component.html
Normal file
@ -0,0 +1,24 @@
|
||||
<h3>{{'user.dyndns' | i18n}}</h3>
|
||||
|
||||
<form (ngSubmit)="create()" #formDirective="ngForm" #dyndnsForm>
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<p *ngIf="dyndnsToken && !dyndnsToken.token">{{'user.dyndns.token.exists' | i18n}}</p>
|
||||
<a *ngIf="dyndnsToken && dyndnsToken.token" mat-button (click)="copySecret()"
|
||||
matTooltip="{{'user.dyndns.token.copy' | i18n}}" matTooltipPosition="above">{{ dyndnsToken.token}}</a>
|
||||
<p *ngIf="dyndnsToken && dyndnsToken.token">{{'user.dyndns.token.store' | i18n}}</p>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button type="submit" *ngIf="!working" mat-raised-button color="primary">
|
||||
{{(dyndnsToken ? 'user.dyndns.new' : 'user.dyndns.create') | i18n}}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
<mat-card-footer>
|
||||
<a href="https://wiki.bstly.de/services/webstly#dyndns" class="help-button" matTooltip="{{'help-button' | i18n}}"
|
||||
matTooltipPosition="above" target="_blank" mat-fab color="accent">
|
||||
<mat-icon>contact_support</mat-icon>
|
||||
</a>
|
||||
</mat-card-footer>
|
||||
</mat-card>
|
||||
|
||||
</form>
|
0
src/app/pages/account/dyndns/dyndns.component.scss
Normal file
0
src/app/pages/account/dyndns/dyndns.component.scss
Normal file
88
src/app/pages/account/dyndns/dyndns.component.ts
Normal file
88
src/app/pages/account/dyndns/dyndns.component.ts
Normal file
@ -0,0 +1,88 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { I18nService } from '../../../services/i18n.service';
|
||||
import { Sort } from '@angular/material/sort';
|
||||
import { UserDomainService } from '../../../services/userdomain.service';
|
||||
import { FormBuilder, FormGroup, Validators, NgForm } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ConfirmDialog } from '../../../ui/confirm/confirm.component';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { Clipboard } from '@angular/cdk/clipboard';
|
||||
import { DyndnsTokenService } from 'src/app/services/dyndnstoken.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-account-dyndns',
|
||||
templateUrl: './dyndns.component.html',
|
||||
styleUrls: ['./dyndns.component.scss']
|
||||
})
|
||||
export class DyndnsComponent implements OnInit {
|
||||
|
||||
dyndnsToken: any;
|
||||
working: boolean;
|
||||
|
||||
domainsColumns = ["domain", "secret", "validated", "delete"];
|
||||
visibilities = ["PRIVATE", "PROTECTED", "PUBLIC"];
|
||||
|
||||
constructor(
|
||||
private dyndnsTokenService: DyndnsTokenService,
|
||||
private i18n: I18nService,
|
||||
private snackBar: MatSnackBar,
|
||||
public dialog: MatDialog,
|
||||
private clipboard: Clipboard) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.working = true;
|
||||
this.dyndnsTokenService.get().subscribe({
|
||||
next: (result: any) => {
|
||||
this.dyndnsToken = result;
|
||||
this.working = false;
|
||||
},
|
||||
error: (error) => {
|
||||
this.working = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
create(): void {
|
||||
this.working = true;
|
||||
this.dyndnsTokenService.create().subscribe({
|
||||
next: (result: any) => {
|
||||
this.dyndnsToken = result;
|
||||
this.working = false;
|
||||
},
|
||||
error: (error) => {
|
||||
this.working = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
confirmDelete() {
|
||||
const dialogRef = this.dialog.open(ConfirmDialog, {
|
||||
data: {
|
||||
'label': 'user.dyndns.confirmDelete',
|
||||
}
|
||||
})
|
||||
|
||||
dialogRef.afterClosed().subscribe({
|
||||
next: (result) => {
|
||||
if (result) {
|
||||
this.dyndnsTokenService.delete().subscribe({
|
||||
next: (result: any) => {
|
||||
this.dyndnsToken = undefined;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
copySecret() {
|
||||
if (this.dyndnsToken && this.dyndnsToken.token) {
|
||||
this.clipboard.copy(this.dyndnsToken.token);
|
||||
this.snackBar.open(this.i18n.get("user.dyndns.token.copied", []), this.i18n.get("close", []), {
|
||||
duration: 3000
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -90,9 +90,7 @@
|
||||
<div [formGroup]="slotForm" class="flex wrap" fxLayoutAlign="start stretch" fxLayoutGap="24px grid">
|
||||
<mat-form-field>
|
||||
<mat-label>{{'borrow.items.slot.start' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="slotStartPicker" formControlName="start">
|
||||
<mat-datepicker-toggle matSuffix [for]="slotStartPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #slotStartPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" formControlName="start">
|
||||
<mat-error>
|
||||
{{'borrow.items.error.slot.start' | i18n}}
|
||||
</mat-error>
|
||||
@ -100,9 +98,7 @@
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{'borrow.items.slot.end' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="slotEndPicker" formControlName="end">
|
||||
<mat-datepicker-toggle matSuffix [for]="slotEndPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #slotEndPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" formControlName="end">
|
||||
<mat-error>
|
||||
{{'borrow.items.error.slot.end' | i18n}}
|
||||
</mat-error>
|
||||
|
@ -24,9 +24,7 @@
|
||||
<form [formGroup]="form">
|
||||
<mat-form-field>
|
||||
<mat-label>{{'borrow.request.start' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="startPicker" formControlName="start">
|
||||
<mat-datepicker-toggle matSuffix [for]="startPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #startPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" formControlName="start">
|
||||
<mat-error>
|
||||
{{'borrow.request.error.start' | i18n}}
|
||||
</mat-error>
|
||||
@ -34,9 +32,7 @@
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{'borrow.request.end' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="endPicker" formControlName="end">
|
||||
<mat-datepicker-toggle matSuffix [for]="endPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #endPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" formControlName="end">
|
||||
<mat-error>
|
||||
{{'borrow.request.error.end' | i18n}}
|
||||
</mat-error>
|
||||
|
@ -27,9 +27,10 @@
|
||||
{{'security.2fa.missing' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-slide-toggle id="keep" name="keep" [checked]="keep">
|
||||
<mat-slide-toggle #toggle [checked]="keep">
|
||||
{{'login.keepSession' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
<input class="hidden" type="checkbox" id="keep" name="keep" [checked]="toggle.checked">
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<a type="submit" mat-raised-button color="primary" (click)="form2FA.submit()"
|
||||
|
@ -1,3 +1,7 @@
|
||||
mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input#keep {
|
||||
display: none;
|
||||
}
|
||||
|
@ -21,9 +21,10 @@
|
||||
{{'password.invalid.hint' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-slide-toggle id="keep" name="keep">
|
||||
<mat-slide-toggle #toggle>
|
||||
{{'login.keepSession' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
<input class="hidden" type="checkbox" id="keep" name="keep" [checked]="toggle.checked">
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button type="submit" (click)="loginForm.submit()" mat-raised-button color="primary"
|
||||
|
@ -1,3 +1,7 @@
|
||||
mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input#keep {
|
||||
display: none;
|
||||
}
|
||||
|
@ -110,32 +110,23 @@
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{'jitsi.rooms.starts' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="startsPicker" [(ngModel)]="jitsiRoom.starts" formControlName="starts"
|
||||
(dateChange)="clearModeration(jitsiRoom)">
|
||||
<mat-datepicker-toggle matSuffix [for]="startsPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #startsPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [(ngModel)]="jitsiRoom.starts" formControlName="starts">
|
||||
<mat-error>
|
||||
{{'jitsi.rooms.error.starts' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field *ngIf="jitsiRoom.starts">
|
||||
<input matInput [ngxMatDatetimePicker]="moderationStartsPicker" [(ngModel)]="jitsiRoom.moderationStarts"
|
||||
formControlName="moderationStarts">
|
||||
<mat-label>{{'jitsi.rooms.moderationStarts' | i18n}}</mat-label>
|
||||
<mat-datepicker-toggle matSuffix [for]="moderationStartsPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #moderationStartsPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [(ngModel)]="jitsiRoom.moderationStarts" formControlName="moderationStarts">
|
||||
<mat-error>
|
||||
{{'jitsi.rooms.error.moderationStarts' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput [ngxMatDatetimePicker]="expiresPicker" [(ngModel)]="jitsiRoom.expires"
|
||||
formControlName="expires">
|
||||
<mat-label>{{'jitsi.rooms.expires' | i18n}}</mat-label>
|
||||
<mat-datepicker-toggle matSuffix [for]="expiresPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #expiresPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [(ngModel)]="jitsiRoom.expires" formControlName="expires">
|
||||
<mat-error>
|
||||
{{'jitsi.rooms.error.expires' | i18n}}
|
||||
</mat-error>
|
||||
|
@ -13,31 +13,23 @@
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{'jitsi.rooms.starts' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="startsPicker" [(ngModel)]="jitsiRoom.starts" formControlName="starts"
|
||||
(dateChange)="clearModeration(jitsiRoom)">
|
||||
<mat-datepicker-toggle matSuffix [for]="startsPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #startsPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [(ngModel)]="jitsiRoom.starts" formControlName="starts" (change)="clearModeration(jitsiRoom)">
|
||||
<mat-error>
|
||||
{{'jitsi.rooms.error.starts' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field *ngIf="jitsiRoom.starts">
|
||||
<input matInput [ngxMatDatetimePicker]="moderationStartsPicker" [(ngModel)]="jitsiRoom.moderationStarts"
|
||||
formControlName="moderationStarts">
|
||||
<mat-label>{{'jitsi.rooms.moderationStarts' | i18n}}</mat-label>
|
||||
<mat-datepicker-toggle matSuffix [for]="moderationStartsPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #moderationStartsPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [(ngModel)]="jitsiRoom.moderationStarts" formControlName="moderationStarts">
|
||||
<mat-error>
|
||||
{{'jitsi.rooms.error.moderationStarts' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput [ngxMatDatetimePicker]="expiresPicker" [(ngModel)]="jitsiRoom.expires" formControlName="expires">
|
||||
<mat-label>{{'jitsi.rooms.expires' | i18n}}</mat-label>
|
||||
<mat-datepicker-toggle matSuffix [for]="expiresPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #expiresPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [(ngModel)]="jitsiRoom.expires" formControlName="expires">
|
||||
<mat-error>
|
||||
{{'jitsi.rooms.error.expires' | i18n}}
|
||||
</mat-error>
|
||||
|
@ -20,18 +20,14 @@
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-label>{{'partey.timeslots.starts' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="startsPicker" [(ngModel)]="timeslot.starts" formControlName="starts">
|
||||
<mat-datepicker-toggle matSuffix [for]="startsPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #startsPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [(ngModel)]="timeslot.starts" formControlName="starts">
|
||||
<mat-error>
|
||||
{{'partey.timeslots.error.starts' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-label>{{'partey.timeslots.ends' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="endsPicker" [(ngModel)]="timeslot.ends" formControlName="ends">
|
||||
<mat-datepicker-toggle matSuffix [for]="endsPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #endsPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [(ngModel)]="timeslot.ends" formControlName="ends">
|
||||
<mat-error>
|
||||
{{'partey.timeslots.error.ends' | i18n}}
|
||||
</mat-error>
|
||||
|
@ -32,9 +32,7 @@
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-label>{{'partey.timeslots.filter.after' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="afterPicker" [formControl]="afterFormControl">
|
||||
<mat-datepicker-toggle matSuffix [for]="afterPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #afterPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [formControl]="afterFormControl">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<table mat-table matSort [dataSource]="timeslots.content" (matSortChange)="updateSort($event)">
|
||||
|
@ -128,10 +128,7 @@
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{'urlshortener.expires' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="expiresPicker" [(ngModel)]="shortenedUrl.expires"
|
||||
formControlName="expires">
|
||||
<mat-datepicker-toggle matSuffix [for]="expiresPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #expiresPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [(ngModel)]="shortenedUrl.expires" formControlName="expires">
|
||||
<mat-error>
|
||||
{{'urlshortener.error.expires' | i18n}}
|
||||
</mat-error>
|
||||
|
@ -50,10 +50,7 @@
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{'urlshortener.expires' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="expiresPicker" [(ngModel)]="shortenedUrlModel.expires"
|
||||
formControlName="expires">
|
||||
<mat-datepicker-toggle matSuffix [for]="expiresPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #expiresPicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [(ngModel)]="shortenedUrlModel.expires" formControlName="expires">
|
||||
<mat-error>
|
||||
{{'urlshortener.error.expires' | i18n}}
|
||||
</mat-error>
|
||||
|
26
src/app/services/dyndnstoken.service.ts
Normal file
26
src/app/services/dyndnstoken.service.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
|
||||
import {environment} from '../../environments/environment';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class DyndnsTokenService {
|
||||
|
||||
constructor(private http: HttpClient) {
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.http.get(environment.apiUrl + "/dyndns/token");
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.http.post(environment.apiUrl + "/dyndns/token", undefined);
|
||||
}
|
||||
|
||||
delete() {
|
||||
return this.http.delete(environment.apiUrl + "/dyndns/token");
|
||||
}
|
||||
|
||||
}
|
23
src/app/ui/datetimepicker/datetimepicker.component.html
Normal file
23
src/app/ui/datetimepicker/datetimepicker.component.html
Normal file
@ -0,0 +1,23 @@
|
||||
<div class="flex wrap" fxLayoutAlign="start stretch">
|
||||
<div [style.flex-basis]="'33%'">
|
||||
<mat-form-field>
|
||||
<mat-label>{{'durationpicker.days' | i18n}}</mat-label>
|
||||
<input matInput type="number" min="0" [formControl]="days">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div [style.flex-basis]="'33%'">
|
||||
<mat-form-field>
|
||||
<mat-label>{{'durationpicker.hours' | i18n}}</mat-label>
|
||||
<input matInput type="number" min="0" max="23"
|
||||
[formControl]="hours">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div [style.flex-basis]="'33%'">
|
||||
<mat-form-field>
|
||||
<mat-label>{{'durationpicker.minutes' | i18n}}</mat-label>
|
||||
<input matInput type="number" min="0" max="59"
|
||||
[formControl]="minutes">
|
||||
<mat-hint align="end">{{duration}}</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
4
src/app/ui/datetimepicker/datetimepicker.component.scss
Normal file
4
src/app/ui/datetimepicker/datetimepicker.component.scss
Normal file
@ -0,0 +1,4 @@
|
||||
mat-form-field {
|
||||
display: block;
|
||||
padding-right: 8px;
|
||||
}
|
104
src/app/ui/datetimepicker/datetimepicker.component.ts
Normal file
104
src/app/ui/datetimepicker/datetimepicker.component.ts
Normal file
@ -0,0 +1,104 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import * as moment from 'moment';
|
||||
|
||||
@Component({
|
||||
selector: 'app-datetimepicker',
|
||||
templateUrl: './datetimepicker.component.html',
|
||||
styleUrls: [ './datetimepicker.component.scss' ],
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
multi: true,
|
||||
useExisting: DatetimepickerComponent
|
||||
}
|
||||
]
|
||||
})
|
||||
export class DatetimepickerComponent implements OnInit, ControlValueAccessor {
|
||||
|
||||
days = new FormControl();
|
||||
hours = new FormControl();
|
||||
minutes = new FormControl();
|
||||
|
||||
duration: string;
|
||||
model: moment.Duration;
|
||||
onChange = (duration) => { };
|
||||
onTouched = () => { };
|
||||
isDisabled = false;
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.days.valueChanges.subscribe({
|
||||
next: (value) => {
|
||||
if (value < this.model.days()) {
|
||||
this.model.subtract((this.model.days() - value), "days");
|
||||
} else {
|
||||
this.model.add((value - this.model.days()), "days");
|
||||
}
|
||||
this.checkValue();
|
||||
}
|
||||
})
|
||||
|
||||
this.hours.valueChanges.subscribe({
|
||||
next: (value) => {
|
||||
if (value < this.model.hours()) {
|
||||
this.model.subtract((this.model.hours() - value), "hours");
|
||||
} else {
|
||||
this.model.add((value - this.model.hours()), "hours");
|
||||
}
|
||||
this.checkValue();
|
||||
}
|
||||
})
|
||||
|
||||
this.minutes.valueChanges.subscribe({
|
||||
next: (value) => {
|
||||
if (value < this.model.minutes()) {
|
||||
this.model.subtract((this.model.minutes() - value), "minutes");
|
||||
} else {
|
||||
this.model.add((value - this.model.minutes()), "minutes");
|
||||
}
|
||||
this.checkValue();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
checkValue() {
|
||||
if (this.model.asMinutes() <= 0) {
|
||||
this.days.setValue(0, { emitEvent: false });
|
||||
this.hours.setValue(0, { emitEvent: false });
|
||||
this.minutes.setValue(0, { emitEvent: false });
|
||||
this.duration = null;
|
||||
} else {
|
||||
this.duration = this.model.toISOString();
|
||||
}
|
||||
|
||||
this.onChange(this.duration);
|
||||
this.onTouched();
|
||||
}
|
||||
|
||||
|
||||
|
||||
writeValue(duration: string): void {
|
||||
this.duration = duration;
|
||||
this.model = moment.duration(this.duration);
|
||||
this.days.setValue(this.model.days(), { emitEvent: false });
|
||||
this.hours.setValue(this.model.hours()), { emitEvent: false };
|
||||
this.minutes.setValue(this.model.minutes(), { emitEvent: false });
|
||||
this.onTouched();
|
||||
}
|
||||
|
||||
registerOnChange(onChange: any): void {
|
||||
this.onChange = onChange;
|
||||
}
|
||||
|
||||
registerOnTouched(onTouched: any): void {
|
||||
this.onTouched = onTouched;
|
||||
}
|
||||
|
||||
setDisabledState?(isDisabled: boolean): void {
|
||||
this.isDisabled = isDisabled;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -40,10 +40,7 @@
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngSwitchCase="'DATETIME'">
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="datetimePicker" [(ngModel)]="profileField.value"
|
||||
formControlName="value">
|
||||
<mat-datepicker-toggle matSuffix [for]="datetimePicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #datetimePicker></ngx-mat-datetime-picker>
|
||||
<input matInput type="datetime-local" [(ngModel)]="profileField.value" formControlName="value">
|
||||
<mat-error>
|
||||
{{'profileField.error.DATETIME' | i18n}}
|
||||
</mat-error>
|
||||
|
@ -8,6 +8,7 @@
|
||||
// Be sure that you only ever include this mixin once!
|
||||
@include mat.core();
|
||||
|
||||
@import "@danielmoncada/angular-datetime-picker/assets/style/picker.min.css";
|
||||
|
||||
@import './variables.scss';
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user