upgrade and migrate
This commit is contained in:
parent
edecc344e7
commit
92a74e72f9
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -9,5 +9,6 @@
|
||||
"latex",
|
||||
"plaintext",
|
||||
"json"
|
||||
]
|
||||
],
|
||||
"angular.enable-strict-mode-prompt": false
|
||||
}
|
7941
package-lock.json
generated
7941
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
49
package.json
49
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "we-bstly-angular",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
@ -11,39 +11,38 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular-material-components/datetime-picker": "^8.0.0",
|
||||
"@angular-material-components/moment-adapter": "^8.0.0",
|
||||
"@angular/animations": "^14.2.9",
|
||||
"@angular/cdk": "^14.2.6",
|
||||
"@angular/common": "^14.2.9",
|
||||
"@angular/compiler": "^14.2.9",
|
||||
"@angular/core": "^14.2.9",
|
||||
"@angular/forms": "^14.2.9",
|
||||
"@angular/material": "^14.2.7",
|
||||
"@angular/material-moment-adapter": "^14.2.7",
|
||||
"@angular/platform-browser": "^14.2.9",
|
||||
"@angular/platform-browser-dynamic": "^14.2.9",
|
||||
"@angular/router": "^14.2.9",
|
||||
"@angular-material-components/datetime-picker": "^9.0.0",
|
||||
"@angular-material-components/moment-adapter": "^9.0.0",
|
||||
"@angular/animations": "^15.0.3",
|
||||
"@angular/cdk": "^15.0.2",
|
||||
"@angular/common": "^15.0.3",
|
||||
"@angular/compiler": "^15.0.3",
|
||||
"@angular/core": "^15.0.3",
|
||||
"@angular/forms": "^15.0.3",
|
||||
"@angular/material": "^15.0.2",
|
||||
"@angular/material-moment-adapter": "^15.0.2",
|
||||
"@angular/platform-browser": "^15.0.3",
|
||||
"@angular/platform-browser-dynamic": "^15.0.3",
|
||||
"@angular/router": "^15.0.3",
|
||||
"moment": "^2.29.4",
|
||||
"ng-qrcode": "^7.0.0",
|
||||
"ngx-mat-timepicker": "^14.0.6",
|
||||
"ng-qrcode": "^8.0.1",
|
||||
"ngx-mat-timepicker": "^15.1.2",
|
||||
"openpgp": "^5.5.0",
|
||||
"qr-scanner": "^1.4.2",
|
||||
"rxjs": "~7.5.7",
|
||||
"rxjs": "~7.6.0",
|
||||
"tslib": "^2.4.1",
|
||||
"unique-names-generator": "^4.7.1",
|
||||
"zone.js": "~0.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^14.2.8",
|
||||
"@angular/cli": "^14.2.8",
|
||||
"@angular/compiler-cli": "^14.2.9",
|
||||
"@angular/localize": "^14.2.9",
|
||||
"@types/jasmine": "^4.3.0",
|
||||
"@angular-devkit/build-angular": "^15.0.3",
|
||||
"@angular/cli": "^15.0.3",
|
||||
"@angular/compiler-cli": "^15.0.3",
|
||||
"@angular/localize": "^15.0.3",
|
||||
"@types/jasmine": "^4.3.1",
|
||||
"@types/jasminewd2": "^2.0.10",
|
||||
"@types/node": "^18.11.9",
|
||||
"@types/node": "^18.11.12",
|
||||
"@types/openpgp": "^4.4.18",
|
||||
"codelyzer": "^6.0.2",
|
||||
"jasmine-core": "~4.5.0",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"karma": "^6.4.1",
|
||||
@ -54,6 +53,6 @@
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~10.9.1",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~4.8.3"
|
||||
"typescript": "~4.8.4"
|
||||
}
|
||||
}
|
||||
|
@ -33,61 +33,63 @@ import { BorrowRequestsComponent } from './pages/borrow/requests/requests.compon
|
||||
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';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: 'profile/:username', component: UserComponent, canActivate: [ AuthUpdateGuard ] },
|
||||
{ path: 'edit-profile', component: ProfileComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'jukebox', component: JukeboxComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'partey/manage', component: ParteyComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'profile/:username', component: UserComponent, canActivate: [AuthUpdateGuard] },
|
||||
{ path: 'edit-profile', component: ProfileComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'jukebox', component: JukeboxComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'partey/manage', component: ParteyComponent, canActivate: [AuthenticatedGuard] },
|
||||
{
|
||||
path: '', component: MainComponent, children: [
|
||||
{ path: '', redirectTo: "/services", pathMatch: 'full' },
|
||||
{ path: 'login', component: FormLoginComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'login/2fa', component: FormLogin2FAComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'service-login', component: FormLoginComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'service-login/2fa', component: FormLogin2FAComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'password', component: PasswordComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'password-reset', component: PasswordResetComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'services', component: ServicesComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'login', component: FormLoginComponent, canActivate: [AnonymousGuard] },
|
||||
{ path: 'login/2fa', component: FormLogin2FAComponent, canActivate: [AnonymousGuard] },
|
||||
{ path: 'login/oidc', component: FormLoginOidcComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'service-login', component: FormLoginComponent, canActivate: [AnonymousGuard] },
|
||||
{ path: 'service-login/2fa', component: FormLogin2FAComponent, canActivate: [AnonymousGuard] },
|
||||
{ path: 'password', component: PasswordComponent, canActivate: [AnonymousGuard] },
|
||||
{ path: 'password-reset', component: PasswordResetComponent, canActivate: [AnonymousGuard] },
|
||||
{ path: 'services', component: ServicesComponent, canActivate: [AuthenticatedGuard] },
|
||||
{
|
||||
path: 'account', component: AccountComponent, canActivate: [ AuthenticatedGuard ], children: [
|
||||
path: 'account', component: AccountComponent, canActivate: [AuthenticatedGuard], children: [
|
||||
{ path: '', redirectTo: "/account/info", pathMatch: 'full' },
|
||||
{ path: 'info', component: InfoComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'profile', component: ProfileComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ 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: 'info', component: InfoComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'profile', component: ProfileComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ 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: 'borrow', component: BorrowComponent, canActivate: [ AuthenticatedGuard ], children: [
|
||||
path: 'borrow', component: BorrowComponent, canActivate: [AuthenticatedGuard], children: [
|
||||
{ path: '', redirectTo: "/borrow/items", pathMatch: 'full' },
|
||||
{ path: 'items', component: BorrowItemsComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'requests', component: BorrowRequestsComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'proving', component: BorrowProvingComponent, canActivate: [ AuthenticatedGuard ] }
|
||||
{ path: 'items', component: BorrowItemsComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'requests', component: BorrowRequestsComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'proving', component: BorrowProvingComponent, canActivate: [AuthenticatedGuard] }
|
||||
]
|
||||
},
|
||||
{ path: 'register', component: RegisterComponent, canActivate: [ AnonymousGuard ] },
|
||||
{ path: 'tokens', component: TokensComponent, canActivate: [ AuthGuard ] },
|
||||
{ path: 'jitsi', component: JitsiComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'partey', component: ParteyComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'partey/timeslots', component: ParteyTimeslotsComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'partey/jukebox', component: JukeboxComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'minetest/accounts', component: MinetestAccountsComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'register', component: RegisterComponent, canActivate: [AnonymousGuard] },
|
||||
{ path: 'tokens', component: TokensComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'jitsi', component: JitsiComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'partey', component: ParteyComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'partey/timeslots', component: ParteyTimeslotsComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'partey/jukebox', component: JukeboxComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'minetest/accounts', component: MinetestAccountsComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'dividertest', component: DividertestComponent },
|
||||
{ path: 'urlshortener', component: UrlShortenerComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'urlshortener/:code', component: UrlShortenerPasswordComponent, canActivate: [ AuthUpdateGuard ] },
|
||||
{ path: 'invites/:quota', component: InvitesComponent, canActivate: [ AuthenticatedGuard ] },
|
||||
{ path: 'invite/:code', component: InviteCodeComponent, canActivate: [ AuthGuard ] },
|
||||
{ path: 'urlshortener', component: UrlShortenerComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'urlshortener/:code', component: UrlShortenerPasswordComponent, canActivate: [AuthUpdateGuard] },
|
||||
{ path: 'invites/:quota', component: InvitesComponent, canActivate: [AuthenticatedGuard] },
|
||||
{ path: 'invite/:code', component: InviteCodeComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'unavailable', component: UnavailableComponent },
|
||||
{ path: 'p/:username', component: UserComponent, canActivate: [ AuthUpdateGuard ] },
|
||||
{ path: '**', component: NotfoundComponent, pathMatch: 'full', canActivate: [ AuthUpdateGuard ] }, ]
|
||||
{ path: 'p/:username', component: UserComponent, canActivate: [AuthUpdateGuard] },
|
||||
{ path: '**', component: NotfoundComponent, pathMatch: 'full', canActivate: [AuthUpdateGuard] },]
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload', relativeLinkResolution: 'legacy' }) ],
|
||||
exports: [ RouterModule ]
|
||||
imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
|
@ -63,9 +63,9 @@ 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 { MAT_DATE_LOCALE } from '@angular/material/core';
|
||||
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';
|
||||
|
||||
|
||||
export function init_app(i18n: I18nService) {
|
||||
@ -94,6 +94,7 @@ export class XhrInterceptor implements HttpInterceptor {
|
||||
LoginComponent,
|
||||
FormLoginComponent,
|
||||
FormLogin2FAComponent,
|
||||
FormLoginOidcComponent,
|
||||
TokensComponent,
|
||||
InvitesComponent, InviteCodeComponent, InviteEditComponent,
|
||||
ServicesComponent,
|
||||
@ -140,21 +141,21 @@ export class XhrInterceptor implements HttpInterceptor {
|
||||
QrCodeModule,
|
||||
|
||||
],
|
||||
exports: [ MaterialModule ],
|
||||
providers: [ { provide: APP_INITIALIZER, useFactory: init_app, deps: [ I18nService ], multi: true }, { provide: HTTP_INTERCEPTORS, useClass: XhrInterceptor, multi: true }, DatePipe,
|
||||
exports: [MaterialModule],
|
||||
providers: [{ provide: APP_INITIALIZER, useFactory: init_app, deps: [I18nService], multi: true }, { provide: HTTP_INTERCEPTORS, useClass: XhrInterceptor, multi: true }, DatePipe,
|
||||
{
|
||||
provide: MatPaginatorIntl, useFactory: (i18n) => {
|
||||
const service = new I18nPaginatorIntl();
|
||||
service.injectI18n(i18n)
|
||||
return service;
|
||||
}, deps: [ I18nService ]
|
||||
}, deps: [I18nService]
|
||||
},
|
||||
{
|
||||
provide: NgxMatDateAdapter,
|
||||
useClass: NgxMatMomentAdapter,
|
||||
useFactory: (i18n: I18nService) => {
|
||||
return new NgxMatMomentAdapter(i18n.getLocale(), { strict: true });
|
||||
}, deps: [ I18nService ]
|
||||
}, deps: [I18nService]
|
||||
}, {
|
||||
provide: NGX_MAT_DATE_FORMATS, useFactory: (i18n: I18nService) => {
|
||||
const datetimeformat = i18n.get('format.datetime', []);
|
||||
@ -169,9 +170,9 @@ export class XhrInterceptor implements HttpInterceptor {
|
||||
monthYearA11yLabel: "MMMM YYYY"
|
||||
}
|
||||
};
|
||||
}, deps: [ I18nService ]
|
||||
} ],
|
||||
bootstrap: [ AppComponent ],
|
||||
}, deps: [I18nService]
|
||||
}],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<h2>{{'greet' | i18n:auth.name}} <mat-icon>sentiment_satisfied_alt</mat-icon>
|
||||
</h2>
|
||||
|
||||
<nav mat-tab-nav-bar>
|
||||
<nav mat-tab-nav-bar [tabPanel]="tabPanel">
|
||||
<a mat-tab-link routerLink="info" routerLinkActive #rlainfo="routerLinkActive" [active]="rlainfo.isActive">{{'info'
|
||||
| i18n}}</a>
|
||||
<a mat-tab-link routerLink="profile" routerLinkActive #rlaprofile="routerLinkActive"
|
||||
@ -14,11 +14,12 @@
|
||||
[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 mat-tab-link>
|
||||
<a style="align-self: center;">
|
||||
<mat-slide-toggle [(ngModel)]="advancedView">
|
||||
<span *ngIf="!advancedView">{{'account.advanced' | i18n}}</span>
|
||||
</mat-slide-toggle>
|
||||
</a>
|
||||
</nav>
|
||||
<mat-tab-nav-panel #tabPanel></mat-tab-nav-panel>
|
||||
|
||||
<router-outlet></router-outlet>
|
@ -10,8 +10,7 @@
|
||||
<ng-container matColumnDef="visibility">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="visibility"> {{'visibility' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let alias">
|
||||
<mat-select [(ngModel)]="alias.visibility" (selectionChange)="updateAlias(alias)"
|
||||
placeholder="{{'visibility' | i18n}}">
|
||||
<mat-select [(ngModel)]="alias.visibility" (selectionChange)="updateAlias(alias)">
|
||||
<mat-option *ngFor="let visibility of visibilities" [value]="visibility">
|
||||
<mat-icon inline="true">{{'visibility.' + visibility + '.icon' | i18n}}</mat-icon> {{'visibility.' +
|
||||
visibility | i18n}}
|
||||
@ -28,8 +27,8 @@
|
||||
<ng-container matColumnDef="delete">
|
||||
<th mat-header-cell *matHeaderCellDef class="align-right"> {{'user.aliases.delete' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let alias" class="text-right">
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="confirmDelete(alias)">delete</mat-icon>
|
||||
<a mat-icon-button (click)="confirmDelete(alias)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -46,14 +45,15 @@
|
||||
<div *ngIf="aliasCreation">
|
||||
<p>{{'user.aliases.left' | i18n:aliasCreation}}</p>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'user.aliases.alias' | i18n}}" formControlName="alias"
|
||||
[(ngModel)]="alias.alias" required>
|
||||
<mat-label>{{'user.aliases.alias' | i18n}}</mat-label>
|
||||
<input matInput formControlName="alias" [(ngModel)]="alias.alias" required>
|
||||
<mat-error>
|
||||
{{'user.aliases.error' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-select [(ngModel)]="alias.visibility" formControlName="visibility" placeholder="{{'visibility' | i18n}}">
|
||||
<mat-label>{{'visibility' | i18n}}</mat-label>
|
||||
<mat-select [(ngModel)]="alias.visibility" formControlName="visibility">
|
||||
<mat-option *ngFor="let visibility of visibilities" [value]="visibility">
|
||||
<mat-icon inline="true">{{'visibility.' + visibility + '.icon' | i18n}}</mat-icon> {{'visibility.' +
|
||||
visibility | i18n}}
|
||||
@ -68,7 +68,8 @@
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="aliasCreation && !working" mat-raised-button color="primary" [disabled]="form.invalid">
|
||||
<button type="submit" *ngIf="aliasCreation && !working" mat-raised-button color="primary"
|
||||
[disabled]="form.invalid">
|
||||
{{'user.aliases.create' | i18n}}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
|
@ -2,15 +2,9 @@ mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mat-header-cell,
|
||||
.mat-cell {
|
||||
.mat-mdc-header-cell,
|
||||
.mat-mdc-cell {
|
||||
&.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.align-right{
|
||||
display: flex;
|
||||
padding: 21px 0;
|
||||
justify-content: flex-end;
|
||||
}
|
@ -27,8 +27,8 @@
|
||||
<ng-container matColumnDef="delete">
|
||||
<th mat-header-cell *matHeaderCellDef class="align-right"> {{'user.domains.delete' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let domain" class="text-right">
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="confirmDelete(domain)">delete</mat-icon>
|
||||
<a mat-icon-button (click)="confirmDelete(domain)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -37,20 +37,20 @@
|
||||
<tr mat-row *matRowDef="let myRowData; columns: domainsColumns"></tr>
|
||||
</table>
|
||||
|
||||
<form [formGroup]="form" (ngSubmit)="create()" #formDirective="ngForm">
|
||||
<form [formGroup]="form" (ngSubmit)="create()" #formDirective="ngForm" #domainForm>
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<p>{{'user.domains.info' | i18n}}</p>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'user.domains.domain' | i18n}}" formControlName="domain"
|
||||
[(ngModel)]="domain.domain" required>
|
||||
<mat-label>{{'user.domains.domain' | i18n}}</mat-label>
|
||||
<input matInput formControlName="domain" [(ngModel)]="domain.domain" required>
|
||||
<mat-error>
|
||||
{{'user.domains.error' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="!working" mat-raised-button color="primary" [disabled]="form.invalid">
|
||||
<button type="submit" *ngIf="!working" mat-raised-button color="primary" [disabled]="form.invalid">
|
||||
{{'user.domains.create' | i18n}}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
|
@ -2,19 +2,6 @@ mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mat-header-cell,
|
||||
.mat-cell {
|
||||
&.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.align-right {
|
||||
display: flex;
|
||||
padding: 21px 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.secret {
|
||||
width: 200px;
|
||||
max-width: 200px;
|
||||
|
@ -3,6 +3,6 @@ table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td.mat-cell {
|
||||
td.mat-mdc-cell {
|
||||
padding: 12px;
|
||||
}
|
@ -3,14 +3,17 @@
|
||||
|
||||
{{'security.2fa.totp.hint' | i18n}}
|
||||
|
||||
<qr-code *ngIf="data.qrData" [value]="data.qrData" size="400" errorCorrectionLevel="'M'" title="{{data.qrData}}"></qr-code>
|
||||
<qr-code *ngIf="data.qrData" [value]="data.qrData" size="400" errorCorrectionLevel="'M'"
|
||||
title="{{data.qrData}}"></qr-code>
|
||||
|
||||
{{'security.2fa.totp.activate' | i18n}}
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'security.2fa.totp.code' | i18n}}" [formControl]="code" required>
|
||||
<mat-label>{{'security.2fa.totp.code' | i18n}}</mat-label>
|
||||
<input matInput [formControl]="code" required>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
||||
<button [disabled]="code.invalid" mat-raised-button [mat-dialog-close]="code.value" color="accent">{{'security.2fa.totp.enable' | i18n}}</button>
|
||||
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
|
||||
<a [disabled]="code.invalid" mat-raised-button [mat-dialog-close]="code.value"
|
||||
color="accent">{{'security.2fa.totp.enable' | i18n}}</a>
|
||||
</div>
|
@ -3,8 +3,8 @@
|
||||
<mat-card-content>
|
||||
<h2>{{'password.change' | i18n}}</h2>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" placeholder="{{'password.current' | i18n}}"
|
||||
formControlName="oldPassword" [(ngModel)]="model.old">
|
||||
<mat-label>{{'password.current' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="oldPassword" [(ngModel)]="model.old">
|
||||
<mat-error *ngFor="let error of passwordForm.get('oldPassword').errors | keyvalue">
|
||||
{{error.key}}
|
||||
</mat-error>
|
||||
@ -13,15 +13,15 @@
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" placeholder="{{'password' | i18n}}" formControlName="password"
|
||||
[(ngModel)]="model.password">
|
||||
<mat-label>{{'password' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="password" [(ngModel)]="model.password">
|
||||
<mat-error *ngFor="let error of passwordForm.get('password').errors | keyvalue">
|
||||
{{error.key}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" length="6" placeholder="{{'password.confirm' | i18n}}"
|
||||
formControlName="password2" [(ngModel)]="model.password2">
|
||||
<mat-label>{{'password.confirm' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="password2" [(ngModel)]="model.password2">
|
||||
<mat-error>
|
||||
{{'password.not-match' | i18n}}
|
||||
</mat-error>
|
||||
@ -29,7 +29,7 @@
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<mat-progress-bar *ngIf="working" mode="indeterminate"></mat-progress-bar>
|
||||
<button *ngIf="!working" mat-raised-button color="primary" [disabled]="passwordForm.invalid">
|
||||
<button type="submit" *ngIf="!working" mat-raised-button color="primary" [disabled]="passwordForm.invalid">
|
||||
{{'password.change' | i18n}}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
@ -42,8 +42,8 @@
|
||||
<h2>{{'security.status' | i18n}}</h2>
|
||||
<p> {{'security.status.hint' | i18n}}</p>
|
||||
<mat-form-field>
|
||||
<mat-select [(ngModel)]="model.status" formControlName="status"
|
||||
placeholder="{{'security.status' | i18n}}">
|
||||
<mat-label>{{'security.status' | i18n}}</mat-label>
|
||||
<mat-select [(ngModel)]="model.status" formControlName="status">
|
||||
<mat-option *ngFor="let status of statuses" [value]="status">
|
||||
{{'security.status.' + status | i18n}}
|
||||
</mat-option>
|
||||
@ -56,13 +56,13 @@
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<mat-progress-bar *ngIf="working" mode="indeterminate"></mat-progress-bar>
|
||||
<button *ngIf="!working" mat-raised-button color="primary" [disabled]="statusForm.invalid">
|
||||
<button type="submit" *ngIf="!working" mat-raised-button color="primary" [disabled]="statusForm.invalid">
|
||||
{{'security.status.change' | i18n}}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
<mat-card-footer>
|
||||
<a href="https://wiki.bstly.de/services/webstly#status" class="help-button" matTooltip="{{'help-button' | i18n}}"
|
||||
matTooltipPosition="above" target="_blank" mat-fab color="accent">
|
||||
<a href="https://wiki.bstly.de/services/webstly#status" 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>
|
||||
@ -75,10 +75,10 @@
|
||||
<p>{{'security.2fa.info' | i18n}}</p>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="!totp" (click)="createTotp()" mat-raised-button color="accent">{{'security.2fa.totp.create' |
|
||||
i18n}}</button>
|
||||
<button *ngIf="totp" (click)="removeTotp()" mat-raised-button color="warn">{{'security.2fa.totp.remove' |
|
||||
i18n}}</button>
|
||||
<a *ngIf="!totp" (click)="createTotp()" mat-raised-button color="accent">{{'security.2fa.totp.create' |
|
||||
i18n}}</a>
|
||||
<a *ngIf="totp" (click)="removeTotp()" mat-raised-button color="warn">{{'security.2fa.totp.remove' |
|
||||
i18n}}</a>
|
||||
</mat-card-actions>
|
||||
<mat-card-footer>
|
||||
<a href="https://wiki.bstly.de/services/webstly#2fa" class="help-button" matTooltip="{{'help-button' | i18n}}"
|
||||
|
@ -3,9 +3,9 @@
|
||||
<p>{{'vouchers.info' | i18n}}</p>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngFor="let name of available" mat-raised-button (click)="create(name)" matTooltip="{{'vouchers.' + name + '.text' | i18n}}">
|
||||
<a *ngFor="let name of available" mat-raised-button (click)="create(name)" matTooltip="{{'vouchers.' + name + '.text' | i18n}}">
|
||||
{{'vouchers.' + name | i18n}}
|
||||
</button>
|
||||
</a>
|
||||
</mat-card-actions>
|
||||
<mat-card-footer>
|
||||
<a href="https://wiki.bstly.de/services/webstly#voucher" class="help-button" matTooltip="{{'help-button' | i18n}}"
|
||||
|
@ -8,5 +8,5 @@
|
||||
{{'vouchers.stored-safely.confirm' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
|
||||
<button mat-button (click)="onOkClick()" [disabled]="!data.confirmClose">{{'ok' | i18n}}</button>
|
||||
<a mat-button (click)="onOkClick()" [disabled]="!data.confirmClose">{{'ok' | i18n}}</a>
|
||||
</div>
|
@ -1,6 +1,6 @@
|
||||
<h2>{{'borrow' | i18n}}</h2>
|
||||
|
||||
<nav mat-tab-nav-bar>
|
||||
<nav mat-tab-nav-bar [tabPanel]="tabPanel">
|
||||
<a mat-tab-link routerLink="items" routerLinkActive="active-tab" #rlaitems="routerLinkActive"
|
||||
[active]="rlaitems.isActive">{{'borrow.items'
|
||||
| i18n}}</a>
|
||||
@ -11,5 +11,6 @@
|
||||
[active]="rlaproving.isActive">{{'borrow.proving'
|
||||
| i18n}}</a>
|
||||
</nav>
|
||||
<mat-tab-nav-panel #tabPanel></mat-tab-nav-panel>
|
||||
|
||||
<router-outlet></router-outlet>
|
@ -2,28 +2,31 @@
|
||||
<mat-dialog-content>
|
||||
<form [formGroup]="form">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'borrow.items.name' | i18n}}" formControlName="name">
|
||||
<mat-label>{{'borrow.items.name' | i18n}}</mat-label>
|
||||
<input matInput formControlName="name">
|
||||
<mat-error>
|
||||
{{'borrow.items.error.name' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<textarea matInput placeholder="{{'borrow.items.description' | i18n}}" formControlName="description"></textarea>
|
||||
<mat-label>{{'borrow.items.description' | i18n}}</mat-label>
|
||||
<textarea matInput formControlName="description"></textarea>
|
||||
<mat-error>
|
||||
{{'borrow.items.error.description' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'borrow.items.url' | i18n}}" formControlName="url">
|
||||
<mat-label>{{'borrow.items.url' | i18n}}</mat-label>
|
||||
<input matInput formControlName="url">
|
||||
<mat-error>
|
||||
{{'borrow.items.error.url' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutGap="24px grid">
|
||||
<mat-form-field floatLabel="always" appearance="none" fxFlex="50%" fxFlex.sm="100%" fxFlex.xs="100%">
|
||||
<div class="flex wrap" fxLayoutGap="24px grid">
|
||||
<mat-form-field floatLabel="always" fxFlex="50%" fxFlex.sm="100%" fxFlex.xs="100%">
|
||||
<input matInput hidden formControlName="minDuration" />
|
||||
<label>{{'borrow.items.minDuration' | i18n}}</label>
|
||||
<app-durationpicker formControlName="minDuration"></app-durationpicker>
|
||||
@ -32,7 +35,7 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field floatLabel="always" appearance="none" fxFlex="50%" fxFlex.sm="100%" fxFlex.xs="100%">
|
||||
<mat-form-field floatLabel="always" fxFlex="50%" fxFlex.sm="100%" fxFlex.xs="100%">
|
||||
<input matInput hidden formControlName="maxDuration" />
|
||||
<label>{{'borrow.items.maxDuration' | i18n}}</label>
|
||||
<app-durationpicker formControlName="maxDuration"></app-durationpicker>
|
||||
@ -42,9 +45,10 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutAlign="start stretch" fxLayoutGap="24px grid">
|
||||
<div class="flex align-center wrap" fxLayoutAlign="start stretch" fxLayoutGap="24px grid">
|
||||
<mat-form-field>
|
||||
<mat-select formControlName="availability" placeholder="{{'borrow.items.availability' | i18n}}">
|
||||
<mat-label>{{'borrow.items.availability' | i18n}}</mat-label>
|
||||
<mat-select formControlName="availability">
|
||||
<mat-option value="ALWAYS">
|
||||
{{'borrow.items.availability.ALWAYS' | i18n}}
|
||||
</mat-option>
|
||||
@ -60,21 +64,16 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field floatLabel="always" appearance="none">
|
||||
<mat-slide-toggle formControlName="autoAccept">{{'borrow.items.autoAccept' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
<input matInput hidden />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field floatLabel="always" appearance="none">
|
||||
<mat-slide-toggle formControlName="emailNotification">
|
||||
{{'borrow.items.emailNotification' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
<input matInput hidden />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field *ngIf="form.get('emailNotification').value" fxFlex="1 1 0%">
|
||||
<input matInput type="email" placeholder="{{'borrow.items.email' | i18n}}" formControlName="email">
|
||||
<mat-label>{{'borrow.items.email' | i18n}}</mat-label>
|
||||
<input matInput type="email" formControlName="email">
|
||||
<mat-error>
|
||||
{{'borrow.items.error.email' | i18n}}
|
||||
</mat-error>
|
||||
@ -84,14 +83,14 @@
|
||||
<ng-container *ngIf="form.get('availability').value == 'MANUAL'">
|
||||
<mat-divider></mat-divider><br>
|
||||
<label>{{'borrow.items.slot.MANUAL' | i18n}}</label>
|
||||
<button mat-icon-button (click)="addManualSlot('','','')" title="{{'borrow.items.slot.add' | i18n}}">
|
||||
<a mat-icon-button (click)="addManualSlot('','','')" title="{{'borrow.items.slot.add' | i18n}}">
|
||||
<mat-icon>control_point_duplicate</mat-icon>
|
||||
</button>
|
||||
</a>
|
||||
<ng-container *ngFor="let slotForm of slots.controls; let i = index">
|
||||
<div [formGroup]="slotForm" fxLayout="row wrap" fxLayoutAlign="start stretch" fxLayoutGap="24px grid">
|
||||
<div [formGroup]="slotForm" class="flex wrap" fxLayoutAlign="start stretch" fxLayoutGap="24px grid">
|
||||
<mat-form-field>
|
||||
<input matInput [ngxMatDatetimePicker]="slotStartPicker" formControlName="start"
|
||||
placeholder="{{'borrow.items.slot.start' | i18n}}">
|
||||
<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>
|
||||
<mat-error>
|
||||
@ -100,8 +99,8 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput [ngxMatDatetimePicker]="slotEndPicker" formControlName="end"
|
||||
placeholder="{{'borrow.items.slot.end' | i18n}}">
|
||||
<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>
|
||||
<mat-error>
|
||||
@ -110,12 +109,12 @@
|
||||
</mat-form-field>
|
||||
|
||||
<div>
|
||||
<button mat-icon-button (click)="dublicateSlot(i)" title="{{'borrow.items.slot.dublicate' | i18n}}">
|
||||
<a mat-icon-button (click)="dublicateSlot(i)" title="{{'borrow.items.slot.dublicate' | i18n}}">
|
||||
<mat-icon>control_point_duplicate</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="deleteSlot(i)" title="{{'borrow.items.slot.delete' | i18n}}">
|
||||
</a>
|
||||
<a mat-icon-button (click)="deleteSlot(i)" title="{{'borrow.items.slot.delete' | i18n}}">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
@ -124,13 +123,14 @@
|
||||
<ng-container *ngIf="form.get('availability').value == 'PERIOD'">
|
||||
<mat-divider></mat-divider><br>
|
||||
<label>{{'borrow.items.slot.PERIOD' | i18n}}</label>
|
||||
<button mat-icon-button (click)="addPeriodSlot('','','','','')" title="{{'borrow.items.slot.add' | i18n}}">
|
||||
<a mat-icon-button (click)="addPeriodSlot('','','','','')" title="{{'borrow.items.slot.add' | i18n}}">
|
||||
<mat-icon>control_point_duplicate</mat-icon>
|
||||
</button>
|
||||
</a>
|
||||
<ng-container *ngFor="let slotForm of slots.controls; let i = index">
|
||||
<div [formGroup]="slotForm" fxLayout="row wrap" fxLayoutAlign="start stretch" fxLayoutGap="12px grid">
|
||||
<div [formGroup]="slotForm" class="flex wrap" fxLayoutAlign="start stretch" fxLayoutGap="12px grid">
|
||||
<mat-form-field>
|
||||
<mat-select formControlName="startDay" placeholder="{{'borrow.items.slot.startDay' | i18n}}">
|
||||
<mat-label>{{'borrow.items.slot.startDay' | i18n}}</mat-label>
|
||||
<mat-select formControlName="startDay">
|
||||
<mat-option *ngFor="let day of weekdays" [value]="day">
|
||||
{{'borrow.items.slot.day.' + day | i18n}}
|
||||
</mat-option>
|
||||
@ -141,8 +141,8 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput format="24" [ngxMatTimepicker]="startTimePicker" formControlName="startTime"
|
||||
placeholder="{{'borrow.items.slot.startTime' | i18n}}">
|
||||
<mat-label>{{'borrow.items.slot.startTime' | i18n}}</mat-label>
|
||||
<input matInput format="24" [ngxMatTimepicker]="startTimePicker" formControlName="startTime">
|
||||
<mat-icon matSuffix (click)="startTimePicker.open()">
|
||||
watch_later
|
||||
</mat-icon>
|
||||
@ -153,7 +153,8 @@
|
||||
<ngx-mat-timepicker #startTimePicker></ngx-mat-timepicker>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select formControlName="endDay" placeholder="{{'borrow.items.slot.endDay' | i18n}}">
|
||||
<mat-label>{{'borrow.items.slot.endDay' | i18n}}</mat-label>
|
||||
<mat-select formControlName="endDay">
|
||||
<mat-option *ngFor="let day of weekdays" [value]="day">
|
||||
{{'borrow.items.slot.day.' + day | i18n}}
|
||||
</mat-option>
|
||||
@ -164,8 +165,8 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput format="24" [ngxMatTimepicker]="endTimePicker" formControlName="endTime"
|
||||
placeholder="{{'borrow.items.slot.endTime' | i18n}}">
|
||||
<mat-label>{{'borrow.items.slot.endTime' | i18n}}</mat-label>
|
||||
<input matInput format="24" [ngxMatTimepicker]="endTimePicker" formControlName="endTime">
|
||||
<mat-icon matSuffix (click)="endTimePicker.open()">
|
||||
watch_later
|
||||
</mat-icon>
|
||||
@ -176,12 +177,12 @@
|
||||
<ngx-mat-timepicker #endTimePicker></ngx-mat-timepicker>
|
||||
|
||||
<div>
|
||||
<button mat-icon-button (click)="dublicateSlot(i)" title="{{'borrow.items.slot.dublicate' | i18n}}">
|
||||
<a mat-icon-button (click)="dublicateSlot(i)" title="{{'borrow.items.slot.dublicate' | i18n}}">
|
||||
<mat-icon>control_point_duplicate</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="deleteSlot(i)" title="{{'borrow.items.slot.delete' | i18n}}">
|
||||
</a>
|
||||
<a mat-icon-button (click)="deleteSlot(i)" title="{{'borrow.items.slot.delete' | i18n}}">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
@ -189,16 +190,16 @@
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<div fxLayout="row" fxLayoutAlign="space-between start">
|
||||
<div class="flex" fxLayoutAlign="space-between start">
|
||||
<div>
|
||||
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">
|
||||
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
|
||||
<a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">
|
||||
<mat-icon>save</mat-icon>{{(create ? 'borrow.items.create' : 'borrow.items.save') | i18n}}
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<button *ngIf="borrowItemId" mat-button color="warn" (click)="confirmDelete()">
|
||||
<a *ngIf="borrowItemId" mat-button color="warn" (click)="confirmDelete()">
|
||||
<mat-icon>delete</mat-icon> {{ 'borrow.items.delete' |
|
||||
i18n}}
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</mat-dialog-actions>
|
@ -1,16 +1,12 @@
|
||||
<h3>{{'borrow.items' | i18n}}</h3>
|
||||
<div *ngIf="borrowItems">
|
||||
<div fxLayout="row" fxLayoutAlign="space-between start">
|
||||
<form>
|
||||
<div class="flex justify-between">
|
||||
<mat-form-field>
|
||||
<input matInput [formControl]="searchFormControl" placeholder="{{'borrow.items.search' | i18n}}">
|
||||
<mat-label>{{'borrow.items.search' | i18n}}</mat-label>
|
||||
<input matInput [formControl]="searchFormControl">
|
||||
</mat-form-field>
|
||||
<mat-form-field floatLabel="always" appearance="none">
|
||||
<mat-slide-toggle [formControl]="ownerFormControl">{{'borrow.items.mine' | i18n}}</mat-slide-toggle>
|
||||
<input matInput hidden />
|
||||
</mat-form-field>
|
||||
</form>
|
||||
<button mat-raised-button (click)="create()" color="accent">{{'borrow.items.create' | i18n}}</button>
|
||||
<a mat-raised-button (click)="create()" color="accent">{{'borrow.items.create' | i18n}}</a>
|
||||
</div>
|
||||
<table mat-table matSort [dataSource]="borrowItems.content" (matSortChange)="updateSort($event)">
|
||||
<ng-container matColumnDef="name">
|
||||
@ -42,17 +38,17 @@
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef class="align-right"> {{'borrow.items.actions' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let borrowItem" class="text-right">
|
||||
<a mat-icon-button *ngIf="borrowItem.owner == userId">
|
||||
<mat-icon (click)="request(borrowItem)">pending_actions</mat-icon>
|
||||
<a mat-icon-button *ngIf="borrowItem.owner == userId" (click)="request(borrowItem)">
|
||||
<mat-icon>pending_actions</mat-icon>
|
||||
</a>
|
||||
<a mat-icon-button *ngIf="borrowItem.owner == userId">
|
||||
<mat-icon (click)="edit(borrowItem)">edit</mat-icon>
|
||||
<a mat-icon-button *ngIf="borrowItem.owner == userId" (click)="edit(borrowItem)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
<a mat-icon-button *ngIf="borrowItem.owner == userId">
|
||||
<mat-icon (click)="confirmDelete(borrowItem)">delete</mat-icon>
|
||||
<a mat-icon-button *ngIf="borrowItem.owner == userId" (click)="confirmDelete(borrowItem)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</a>
|
||||
<a mat-icon-button *ngIf="borrowItem.owner != userId">
|
||||
<mat-icon (click)="request(borrowItem)">pending_actions</mat-icon>
|
||||
<a mat-icon-button *ngIf="borrowItem.owner != userId" (click)="request(borrowItem)">
|
||||
<mat-icon>pending_actions</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
@ -1,21 +1,8 @@
|
||||
.mat-form-field+.mat-form-field, .mat-form-field+.mat-slide-toggle {
|
||||
mat-form-field+*, mat-slide-toggle+* {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.mat-header-cell,
|
||||
.mat-cell {
|
||||
&.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-cell .mat-button {
|
||||
.mat-mdc-cell .mat-mdc-button {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.align-right{
|
||||
display: flex;
|
||||
padding: 21px 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
<video #qrCam></video>
|
||||
|
||||
<form fxLayout="row wrap" fxLayoutGap="24px grid">
|
||||
<form class="flex wrap" fxLayoutGap="24px grid">
|
||||
<mat-form-field>
|
||||
<mat-select [formControl]="camera" name="camera" placeholder="{{'borrow.proving.camera' | i18n}}">
|
||||
<mat-label>{{'borrow.proving.camera' | i18n}}</mat-label>
|
||||
<mat-select [formControl]="camera" name="camera">
|
||||
<mat-option *ngFor="let camera of cameras" [value]="camera.id">
|
||||
{{camera.label || camera.id}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field floatLabel="always" appearance="none">
|
||||
<mat-form-field floatLabel="always">
|
||||
<mat-slide-toggle [formControl]="toggleFlash" disabled>{{'borrow.proving.flash' | i18n}}</mat-slide-toggle>
|
||||
<input matInput hidden name="toggleFlash" />
|
||||
</mat-form-field>
|
||||
|
@ -49,7 +49,7 @@
|
||||
</table>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-raised-button [mat-dialog-close]="false">{{'ok' | i18n}}</button>
|
||||
<a mat-raised-button [mat-dialog-close]="false">{{'ok' | i18n}}</a>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</mat-dialog-content>
|
@ -14,17 +14,17 @@
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<ng-container *ngIf="borrowRequest.id">
|
||||
<mat-chip-list *ngSwitch="borrowRequest.status">
|
||||
<mat-chip-listbox *ngSwitch="borrowRequest.status">
|
||||
<mat-chip *ngSwtichCase="'PENDING'" color="primary" selected></mat-chip>
|
||||
<mat-chip color="accent" selected>Accent fish</mat-chip>
|
||||
</mat-chip-list>
|
||||
</mat-chip-listbox>
|
||||
|
||||
</ng-container>
|
||||
|
||||
<form [formGroup]="form">
|
||||
<mat-form-field>
|
||||
<input matInput [ngxMatDatetimePicker]="startPicker" formControlName="start"
|
||||
placeholder="{{'borrow.request.start' | i18n}}">
|
||||
<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>
|
||||
<mat-error>
|
||||
@ -33,8 +33,8 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput [ngxMatDatetimePicker]="endPicker" formControlName="end"
|
||||
placeholder="{{'borrow.request.end' | i18n}}">
|
||||
<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>
|
||||
<mat-error>
|
||||
@ -43,7 +43,8 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<textarea matInput placeholder="{{'borrow.request.comment' | i18n}}" formControlName="comment"></textarea>
|
||||
<mat-label>{{'borrow.request.comment' | i18n}}</mat-label>
|
||||
<textarea matInput formControlName="comment"></textarea>
|
||||
<mat-error>
|
||||
{{'borrow.request.error.comment' | i18n}}
|
||||
</mat-error>
|
||||
@ -51,16 +52,16 @@
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<div fxLayout="row" fxLayoutAlign="space-between start">
|
||||
<div class="flex" fxLayoutAlign="space-between start">
|
||||
<div>
|
||||
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">
|
||||
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
|
||||
<a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">
|
||||
<mat-icon>save</mat-icon>{{(create ? 'borrow.request.create' : 'borrow.request.save') | i18n}}
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<button *ngIf="borrowRequest.id" mat-button color="warn" (click)="confirmDelete()">
|
||||
<a *ngIf="borrowRequest.id" mat-button color="warn" (click)="confirmDelete()">
|
||||
<mat-icon>delete</mat-icon> {{ 'borrow.request.delete' |
|
||||
i18n}}
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</mat-dialog-actions>
|
@ -1,12 +1,7 @@
|
||||
<h3>{{'borrow.requests' | i18n}}</h3>
|
||||
<div *ngIf="borrowRequests">
|
||||
<div fxLayout="row" fxLayoutAlign="space-between start">
|
||||
<form>
|
||||
<mat-form-field floatLabel="always" appearance="none">
|
||||
<div class="flex justify-between">
|
||||
<mat-slide-toggle [formControl]="ownerFormControl">{{'borrow.requests.mine' | i18n}}</mat-slide-toggle>
|
||||
<input matInput hidden />
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</div>
|
||||
<table mat-table matSort [dataSource]="borrowRequests.content" (matSortChange)="updateSort($event)">
|
||||
<ng-container matColumnDef="name">
|
||||
@ -35,14 +30,14 @@
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef class="align-right"> {{'borrow.requests.actions' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let borrowRequest" class="text-right">
|
||||
<a mat-icon-button *ngIf="borrowRequest.user == userId">
|
||||
<mat-icon (click)="edit(borrowRequest)">edit</mat-icon>
|
||||
<a mat-icon-button *ngIf="borrowRequest.user == userId" (click)="edit(borrowRequest)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
<a mat-icon-button *ngIf="borrowRequest.user == userId">
|
||||
<mat-icon (click)="confirmDelete(borrowRequest)">delete</mat-icon>
|
||||
<a mat-icon-button *ngIf="borrowRequest.user == userId" (click)="confirmDelete(borrowRequest)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</a>
|
||||
<a mat-icon-button *ngIf="borrowRequest.item.owner != userId">
|
||||
<mat-icon (click)="updateStatus(borrowRequest)">pending_actions</mat-icon>
|
||||
<a mat-icon-button *ngIf="borrowRequest.item.owner != userId" (click)="updateStatus(borrowRequest)">
|
||||
<mat-icon>pending_actions</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
@ -1,21 +1,8 @@
|
||||
.mat-form-field+.mat-form-field, .mat-form-field+.mat-slide-toggle {
|
||||
mat-form-field+mat-form-field, mat-form-field+mat-slide-toggle {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.mat-header-cell,
|
||||
.mat-cell {
|
||||
&.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-cell .mat-button {
|
||||
.mat-mdc-cell .mat-mdc-button {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.align-right{
|
||||
display: flex;
|
||||
padding: 21px 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
@ -8,19 +8,21 @@
|
||||
{{'security.2fa.invalid' | i18n}}
|
||||
</mat-error>
|
||||
<input id="provider" name="provider" matInput hidden [value]="selectedProvider.id">
|
||||
<mat-select [(ngModel)]="selectedProvider" placeholder="{{'security.2fa.provider' | i18n}}"
|
||||
[ngModelOptions]="{standalone: true}">
|
||||
<mat-form-field>
|
||||
<mat-label>{{'security.2fa.provider' | i18n}}</mat-label>
|
||||
<mat-select [(ngModel)]="selectedProvider" [ngModelOptions]="{standalone: true}">
|
||||
<mat-option *ngFor="let provider of providers" [value]="provider">
|
||||
{{'security.2fa.' + provider.id | i18n}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<a mat-raised-button (click)="request()"
|
||||
*ngIf="selectedProvider && selectedProvider.request">{{'security.2fa.' + selectedProvider.id +
|
||||
'.request'
|
||||
| i18n}}</a>
|
||||
<mat-form-field>
|
||||
<input id="code" name="code" matInput placeholder="{{'security.2fa.code' | i18n}}" required
|
||||
matAutofocus>
|
||||
<mat-label>{{'security.2fa.code' | i18n}}</mat-label>
|
||||
<input id="code" name="code" matInput required matAutofocus>
|
||||
<mat-error>
|
||||
{{'security.2fa.missing' | i18n}}
|
||||
</mat-error>
|
||||
@ -30,10 +32,10 @@
|
||||
</mat-slide-toggle>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button type="submit" mat-raised-button color="primary" (click)="form2FA.submit()"
|
||||
<a type="submit" mat-raised-button color="primary" (click)="form2FA.submit()"
|
||||
[disabled]="form2FA.invalid">{{'security.2fa.login' | i18n}}<mat-icon style="font-size: 1em;">
|
||||
open_in_new
|
||||
</mat-icon></button>
|
||||
</mat-icon></a>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</form>
|
31
src/app/pages/form-login-oidc/form-login-oidc.component.html
Normal file
31
src/app/pages/form-login-oidc/form-login-oidc.component.html
Normal file
@ -0,0 +1,31 @@
|
||||
<form [formGroup]="form" action="{{apiUrl}}/oidc/authorize" method="POST">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<h2>{{'security.oidc.login' | i18n}}</h2>
|
||||
<mat-error *ngIf="loginInvalid">
|
||||
{{'security.oidc.login.invalid' | i18n}}
|
||||
</mat-error>
|
||||
<input id="code" name="code" type="hidden" formControlName="code" required>
|
||||
<input id="state" name="state" type="hidden" formControlName="state" required>
|
||||
<input id="client_id" name="client_id" type="hidden" formControlName="client_id" required>
|
||||
<input id="responseType" name="responseType" type="hidden" formControlName="responseType" required>
|
||||
<input id="redirectUri" name="redirectUri" type="hidden" formControlName="redirectUri" required>
|
||||
<input id="scope" name="scope" type="hidden" formControlName="scope" required>
|
||||
<input id="nonce" name="nonce" type="hidden" formControlName="nonce">
|
||||
<input id="prompt" name="prompt" type="hidden" formControlName="prompt">
|
||||
<input id="login_hint" name="login_hint" type="hidden" formControlName="login_hint">
|
||||
|
||||
|
||||
<mat-list>
|
||||
<mat-list-item (click)="setAlias('')">{{'username'}}</mat-list-item>
|
||||
<mat-list-item *ngFor="let userAlias of aliases" (click)="setAlias(userAlias.alias)"
|
||||
[activated]="userAlias.alias == selectedAlias">{{userAlias.alias}}</mat-list-item>
|
||||
</mat-list>
|
||||
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<a type="submit" mat-raised-button color="primary" [disabled]="form.invalid">{{'security.oidc.login' |
|
||||
i18n}}</a>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</form>
|
@ -0,0 +1,3 @@
|
||||
mat-form-field {
|
||||
display: block;
|
||||
}
|
95
src/app/pages/form-login-oidc/form-login-oidc.component.ts
Normal file
95
src/app/pages/form-login-oidc/form-login-oidc.component.ts
Normal file
@ -0,0 +1,95 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Auth2FAService } from '../../services/auth.2fa.service';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { Location } from '@angular/common';
|
||||
import { UserAliasService } from 'src/app/services/useralias.service';
|
||||
import { AuthService } from 'src/app/services/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login-oidc',
|
||||
templateUrl: './form-login-oidc.component.html',
|
||||
styleUrls: ['./form-login-oidc.component.scss']
|
||||
})
|
||||
export class FormLoginOidcComponent implements OnInit {
|
||||
|
||||
form: FormGroup;
|
||||
public loginInvalid: boolean;
|
||||
public apiUrl = environment.apiUrl;
|
||||
|
||||
authorize: boolean = false;
|
||||
alias: boolean = false;
|
||||
aliases: any[] = [];
|
||||
selectedAlias: any;
|
||||
|
||||
constructor(private formBuilder: FormBuilder, private authService: AuthService, private userAliasService: UserAliasService, private router: Router, private route: ActivatedRoute, private location: Location) { }
|
||||
|
||||
|
||||
ngOnInit() {
|
||||
this.form = this.formBuilder.group({
|
||||
code: ['', Validators.required],
|
||||
state: ['', Validators.required],
|
||||
client_id: ['', Validators.required],
|
||||
responseType: ['', Validators.required],
|
||||
redirectUri: ['', Validators.required],
|
||||
scope: ['', Validators.required],
|
||||
nonce: [''],
|
||||
prompt: [''],
|
||||
login_hint: ['']
|
||||
});
|
||||
|
||||
this.route.queryParams.subscribe({
|
||||
next: (params) => {
|
||||
if (params['code']) {
|
||||
this.form.get('code').setValue(params['code']);
|
||||
// this.location.replaceState('/login/oidc')
|
||||
}
|
||||
if (params['state']) {
|
||||
this.form.get('state').setValue(params['state']);
|
||||
}
|
||||
if (params['client_id']) {
|
||||
this.form.get('client_id').setValue(params['client_id']);
|
||||
}
|
||||
if (params['responseType']) {
|
||||
this.form.get('responseType').setValue(params['responseType']);
|
||||
}
|
||||
if (params['redirectUri']) {
|
||||
this.form.get('redirectUri').setValue(params['redirectUri']);
|
||||
}
|
||||
if (params['scope']) {
|
||||
this.form.get('scope').setValue(params['scope']);
|
||||
}
|
||||
if (params['nonce']) {
|
||||
this.form.get('nonce').setValue(params['nonce']);
|
||||
}
|
||||
if (params['prompt']) {
|
||||
this.form.get('prompt').setValue(params['prompt']);
|
||||
}
|
||||
if (params['login_hint']) {
|
||||
this.form.get('login_hint').setValue(params['login_hint']);
|
||||
}
|
||||
if (params['authorize']) {
|
||||
this.authorize = params['authorize'] === 'true';
|
||||
}
|
||||
if (params['alias']) {
|
||||
this.alias = params['alias'] === 'true';
|
||||
this.userAliasService.get().subscribe({
|
||||
next: (data: any) => {
|
||||
this.aliases = data;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setAlias(alias) {
|
||||
this.authService.setAlias(alias).subscribe({
|
||||
next: () => {
|
||||
this.selectedAlias = alias;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -8,14 +8,15 @@
|
||||
{{'login.invalid' | i18n}}
|
||||
</mat-error>
|
||||
<mat-form-field>
|
||||
<input id="username" name="username" matInput placeholder="{{'username' | i18n}}" required matAutofocus>
|
||||
<mat-label>{{'username' | i18n}}</mat-label>
|
||||
<input id="username" name="username" matInput required matAutofocus>
|
||||
<mat-error>
|
||||
{{'username.missing' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input id="password" name="password" matInput type="password" placeholder="{{'password' | i18n}}"
|
||||
required>
|
||||
<mat-label>{{'password' | i18n}}</mat-label>
|
||||
<input id="password" name="password" matInput type="password" required>
|
||||
<mat-error>
|
||||
{{'password.invalid.hint' | i18n}}
|
||||
</mat-error>
|
||||
@ -25,7 +26,8 @@
|
||||
</mat-slide-toggle>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button type="submit" (click)="loginForm.submit()" mat-raised-button color="primary" [disabled]="loginForm.invalid">{{'login.external' |
|
||||
<button type="submit" (click)="loginForm.submit()" mat-raised-button color="primary"
|
||||
[disabled]="loginForm.invalid">{{'login.external' |
|
||||
i18n}}<mat-icon style="font-size: 1em;">open_in_new
|
||||
</mat-icon></button>
|
||||
<a routerLink="/password" mat-raised-button color="warn">{{'password.forgot' | i18n}}</a>
|
||||
|
@ -5,7 +5,8 @@
|
||||
<mat-card-content>
|
||||
<ng-container *ngIf="invite">
|
||||
<h3>
|
||||
<mat-icon inline=true>{{'invites.quota.' + invite.quota + ".icon" | i18n}}</mat-icon> {{'invites.quota.'
|
||||
<mat-icon inline="true">{{'invites.quota.' + invite.quota + ".icon" | i18n}}</mat-icon>
|
||||
{{'invites.quota.'
|
||||
+
|
||||
invite.quota
|
||||
| i18n}}
|
||||
@ -26,18 +27,18 @@
|
||||
<form [formGroup]="form" *ngIf="!error">
|
||||
<ng-container *ngIf="!auth.authenticated">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'username' | i18n}}" formControlName="username" matAutofocus
|
||||
tabindex="1">
|
||||
<mat-label>{{'username' | i18n}}</mat-label>
|
||||
<input matInput formControlName="username" matAutofocus tabindex="1">
|
||||
<mat-error>
|
||||
{{'username.error' | i18n}}
|
||||
</mat-error>
|
||||
<a mat-button matSuffix mat-icon-button (click)="genUsername()" tabindex="5">
|
||||
<a mat-icon-button matSuffix (click)="genUsername()" tabindex="5">
|
||||
<mat-icon>autorenew</mat-icon>
|
||||
</a>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" placeholder="{{'password' | i18n}}"
|
||||
formControlName="password" tabindex="2">
|
||||
<mat-label>{{'password' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="password" tabindex="2">
|
||||
<mat-error>
|
||||
<div *ngFor="let error of form.get('password').errors | keyvalue">
|
||||
{{'password.error.' + error.key | i18n}}<br>
|
||||
@ -45,8 +46,8 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" placeholder="{{'password.confirm' | i18n}}"
|
||||
formControlName="password2" tabindex="3">
|
||||
<mat-label>{{'password.confirm' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="password2" tabindex="3">
|
||||
<mat-error>
|
||||
{{'password.not-match' | i18n}}
|
||||
</mat-error>
|
||||
@ -54,14 +55,15 @@
|
||||
</ng-container>
|
||||
<ng-container *ngIf="auth.principal.userId == invite.owner">
|
||||
<mat-form-field>
|
||||
<textarea matInput placeholder="{{'invite.message' | i18n}}"
|
||||
formControlName="message"></textarea>
|
||||
<mat-label>{{'invite.message' | i18n}}</mat-label>
|
||||
<textarea matInput formControlName="message"></textarea>
|
||||
<mat-error>
|
||||
{{'invite.errors.message' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<textarea matInput placeholder="{{'invite.note' | i18n}}" formControlName="note"></textarea>
|
||||
<mat-label>{{'invite.note' | i18n}}</mat-label>
|
||||
<textarea matInput formControlName="note"></textarea>
|
||||
<mat-error>
|
||||
{{'invites.error.note' | i18n}}
|
||||
</mat-error>
|
||||
@ -82,15 +84,15 @@
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<ng-container *ngIf="!success && invite">
|
||||
<button *ngIf="!working && !auth.authenticated && !error" mat-raised-button color="primary"
|
||||
<a *ngIf="!working && !auth.authenticated && !error" mat-raised-button color="primary"
|
||||
[disabled]="form.invalid" (click)="register()" tabindex="4">
|
||||
{{'invites.register' | i18n}}
|
||||
</button>
|
||||
</a>
|
||||
|
||||
<button *ngIf="auth.principal.userId == invite.owner && !error" mat-raised-button color="primary"
|
||||
<a *ngIf="auth.principal.userId == invite.owner && !error" mat-raised-button color="primary"
|
||||
(click)="save()" tabindex="4">
|
||||
{{'invites.edit.save' | i18n}}
|
||||
</button>
|
||||
</a>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="success">
|
||||
<a routerLink="/login" mat-raised-button color="primary">
|
||||
|
@ -5,13 +5,15 @@
|
||||
{{'invites.register.error.' + error | i18n}}
|
||||
</mat-error>
|
||||
<mat-form-field>
|
||||
<textarea matInput placeholder="{{'invite.message' | i18n}}" formControlName="message"></textarea>
|
||||
<mat-label>{{'invite.message' | i18n}}</mat-label>
|
||||
<textarea matInput formControlName="message"></textarea>
|
||||
<mat-error>
|
||||
{{'invite.errors.message' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<textarea matInput placeholder="{{'invite.note' | i18n}}" formControlName="note" ></textarea>
|
||||
<mat-label>{{'invite.note' | i18n}}</mat-label>
|
||||
<textarea matInput formControlName="note"></textarea>
|
||||
<mat-error>
|
||||
{{'invites.error.note' | i18n}}
|
||||
</mat-error>
|
||||
@ -19,8 +21,8 @@
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
||||
<button mat-raised-button color="primary" [disabled]="form.invalid || working" (click)="save()">
|
||||
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
|
||||
<a mat-raised-button color="primary" [disabled]="form.invalid || working" (click)="save()">
|
||||
{{'invites.edit.save' | i18n}}
|
||||
</button>
|
||||
</a>
|
||||
</mat-dialog-actions>
|
@ -1,8 +1,10 @@
|
||||
<h3>{{'invites' | i18n}}</h3>
|
||||
|
||||
<div *ngIf="invites">
|
||||
<div class="flex">
|
||||
<mat-form-field>
|
||||
<input matInput [formControl]="searchFormControl" placeholder="{{'invites.search' | i18n}}">
|
||||
<mat-label>{{'invites.search' | i18n}}</mat-label>
|
||||
<input matInput [formControl]="searchFormControl">
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>{{'invites.redeemed.filter' | i18n}}</mat-label>
|
||||
@ -25,6 +27,7 @@
|
||||
</mat-select-trigger>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<table mat-table matSort [dataSource]="invites.content">
|
||||
|
||||
<ng-container matColumnDef="starts">
|
||||
@ -68,8 +71,8 @@
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'invite.actions' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let invite">
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="edit(invite)">edit</mat-icon>
|
||||
<a mat-icon-button (click)="edit(invite)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -90,17 +93,19 @@
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="inviteQuota && !working" mat-raised-button color="primary" (click)="create()">
|
||||
<a *ngIf="inviteQuota && !working" mat-raised-button color="primary" (click)="create()">
|
||||
{{'invite.create' | i18n}}
|
||||
</button>
|
||||
</a>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
|
||||
<div *ngIf="others && others.content">
|
||||
<h4>{{'invites.others' | i18n}}</h4>
|
||||
|
||||
<div class="flex">
|
||||
<mat-form-field>
|
||||
<input matInput [formControl]="searchOthersFormControl" placeholder="{{'invites.search' | i18n}}">
|
||||
<mat-label>{{'invites.search' | i18n}}</mat-label>
|
||||
<input matInput [formControl]="searchOthersFormControl">
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>{{'invites.redeemed.filter' | i18n}}</mat-label>
|
||||
@ -123,7 +128,7 @@
|
||||
</mat-select-trigger>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
<table mat-table matSort [dataSource]="others.content">
|
||||
<ng-container matColumnDef="note">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'invite.note' | i18n}} </th>
|
||||
|
@ -1,3 +1,3 @@
|
||||
.mat-form-field+.mat-form-field {
|
||||
mat-form-field+mat-form-field {
|
||||
margin-left: 8px;
|
||||
}
|
@ -6,22 +6,23 @@
|
||||
<ng-container matColumnDef="share">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'jitsi.share' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let jitsiRoom">
|
||||
<button mat-icon-button (click)="share(jitsiRoom)">
|
||||
<a mat-icon-button (click)="share(jitsiRoom)">
|
||||
<mat-icon>share</mat-icon>
|
||||
</button>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="room">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="room"> {{'jitsi.rooms.room' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let jitsiRoom">
|
||||
<div class="flex align-center">
|
||||
<a *ngIf="open(jitsiRoom, false)" mat-button color="accent" href="{{ jitsiRoom.url }}" target="_blank">
|
||||
{{ jitsiRoom.room }}
|
||||
<mat-icon style="font-size: 1em;">open_in_new
|
||||
</mat-icon>
|
||||
<mat-icon style="font-size: 1em;">open_in_new</mat-icon>
|
||||
</a>
|
||||
|
||||
<a *ngIf="!open(jitsiRoom, false)" mat-button matTooltip="{{'jitsi.rooms.notStarted' | i18n}}" (click)="copyRoomUrlToClipboard(jitsiRoom)">
|
||||
<a *ngIf="!open(jitsiRoom, false)" mat-button matTooltip="{{'jitsi.rooms.notStarted' | i18n}}"
|
||||
(click)="copyRoomUrlToClipboard(jitsiRoom)">
|
||||
{{ jitsiRoom.room }}
|
||||
</a>
|
||||
|
||||
@ -29,6 +30,7 @@
|
||||
matTooltip="{{'urlshortener.create' | i18n}}">
|
||||
<mat-icon>add_link</mat-icon>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
@ -68,8 +70,8 @@
|
||||
<ng-container matColumnDef="edit">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'jitsi.rooms.edit' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let jitsiRoom" class="text-right">
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="edit(jitsiRoom)">edit</mat-icon>
|
||||
<a mat-icon-button (click)="edit(jitsiRoom)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -77,8 +79,8 @@
|
||||
<ng-container matColumnDef="delete">
|
||||
<th mat-header-cell *matHeaderCellDef class="align-right"> {{'jitsi.rooms.delete' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let jitsiRoom" class="text-right">
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="confirmDelete(jitsiRoom)">delete</mat-icon>
|
||||
<a mat-icon-button (click)="confirmDelete(jitsiRoom)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -99,16 +101,17 @@
|
||||
<div *ngIf="jitsiRoomsQuota">
|
||||
<p>{{'jitsi.rooms.left' | i18n:jitsiRoomsQuota}}</p>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'jitsi.rooms.room' | i18n}}" formControlName="room"
|
||||
[(ngModel)]="jitsiRoom.room" required pattern="[a-zA-Z0-9]+">
|
||||
<mat-label>{{'jitsi.rooms.room' | i18n}}</mat-label>
|
||||
<input matInput formControlName="room" [(ngModel)]="jitsiRoom.room" required pattern="[a-zA-Z0-9]+">
|
||||
<mat-error>
|
||||
{{'jitsi.rooms.error.room' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{'jitsi.rooms.starts' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="startsPicker" [(ngModel)]="jitsiRoom.starts" formControlName="starts"
|
||||
placeholder="{{'jitsi.rooms.starts' | i18n}}" (dateChange)="clearModeration(jitsiRoom)">
|
||||
(dateChange)="clearModeration(jitsiRoom)">
|
||||
<mat-datepicker-toggle matSuffix [for]="startsPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #startsPicker></ngx-mat-datetime-picker>
|
||||
<mat-error>
|
||||
@ -118,7 +121,8 @@
|
||||
|
||||
<mat-form-field *ngIf="jitsiRoom.starts">
|
||||
<input matInput [ngxMatDatetimePicker]="moderationStartsPicker" [(ngModel)]="jitsiRoom.moderationStarts"
|
||||
formControlName="moderationStarts" placeholder="{{'jitsi.rooms.moderationStarts' | i18n}}">
|
||||
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>
|
||||
<mat-error>
|
||||
@ -128,7 +132,8 @@
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput [ngxMatDatetimePicker]="expiresPicker" [(ngModel)]="jitsiRoom.expires"
|
||||
formControlName="expires" placeholder="{{'jitsi.rooms.expires' | i18n}}">
|
||||
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>
|
||||
<mat-error>
|
||||
@ -139,13 +144,14 @@
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="jitsiRoomsQuota && !working" mat-raised-button color="primary" [disabled]="form.invalid">
|
||||
<button type="submit" *ngIf="jitsiRoomsQuota && !working" mat-raised-button color="primary"
|
||||
[disabled]="form.invalid">
|
||||
{{'jitsi.rooms.create' | i18n}}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
<mat-card-footer>
|
||||
<a href="https://wiki.bstly.de/services/jitsi#rooms" class="help-button"
|
||||
matTooltip="{{'help-button' | i18n}}" matTooltipPosition="above" target="_blank" mat-fab color="accent">
|
||||
<a href="https://wiki.bstly.de/services/jitsi#rooms" 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>
|
||||
|
@ -2,24 +2,10 @@ mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mat-header-cell,
|
||||
.mat-cell {
|
||||
&.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-cell .mat-button {
|
||||
.mat-mdc-cell .mat-mdc-button {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.align-right{
|
||||
display: flex;
|
||||
padding: 21px 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.url {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
|
@ -4,16 +4,17 @@
|
||||
<mat-dialog-content>
|
||||
<form [formGroup]="form">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'jitsi.rooms.room' | i18n}}" formControlName="room" [(ngModel)]="jitsiRoom.room"
|
||||
required pattern="[a-zA-Z0-9]+">
|
||||
<mat-label>{{'jitsi.rooms.room' | i18n}}</mat-label>
|
||||
<input matInput formControlName="room" [(ngModel)]="jitsiRoom.room" required pattern="[a-zA-Z0-9]+">
|
||||
<mat-error>
|
||||
{{'jitsi.rooms.error.room' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{'jitsi.rooms.starts' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="startsPicker" [(ngModel)]="jitsiRoom.starts" formControlName="starts"
|
||||
placeholder="{{'jitsi.rooms.starts' | i18n}}" (dateChange)="clearModeration(jitsiRoom)">
|
||||
(dateChange)="clearModeration(jitsiRoom)">
|
||||
<mat-datepicker-toggle matSuffix [for]="startsPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #startsPicker></ngx-mat-datetime-picker>
|
||||
<mat-error>
|
||||
@ -23,7 +24,8 @@
|
||||
|
||||
<mat-form-field *ngIf="jitsiRoom.starts">
|
||||
<input matInput [ngxMatDatetimePicker]="moderationStartsPicker" [(ngModel)]="jitsiRoom.moderationStarts"
|
||||
formControlName="moderationStarts" placeholder="{{'jitsi.rooms.moderationStarts' | i18n}}">
|
||||
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>
|
||||
<mat-error>
|
||||
@ -32,8 +34,8 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput [ngxMatDatetimePicker]="expiresPicker" [(ngModel)]="jitsiRoom.expires" formControlName="expires"
|
||||
placeholder="{{'jitsi.rooms.expires' | i18n}}">
|
||||
<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>
|
||||
<mat-error>
|
||||
@ -43,7 +45,7 @@
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">{{ 'jitsi.rooms.save' |
|
||||
i18n}}</button>
|
||||
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
|
||||
<a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">{{ 'jitsi.rooms.save' |
|
||||
i18n}}</a>
|
||||
</mat-dialog-actions>
|
@ -29,5 +29,5 @@
|
||||
</mat-list>
|
||||
</div>
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button mat-dialog-close>{{'close' | i18n}}</button>
|
||||
<a mat-button mat-dialog-close>{{'close' | i18n}}</a>
|
||||
</div>
|
@ -19,15 +19,16 @@
|
||||
<mat-divider></mat-divider>
|
||||
<br />
|
||||
<mat-form-field>
|
||||
<input matInput [formControl]="searchFormControl" placeholder="{{'jukebox.search' | i18n}}">
|
||||
<mat-label>{{'jukebox.search' | i18n}}</mat-label>
|
||||
<input matInput [formControl]="searchFormControl" >
|
||||
</mat-form-field>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-raised-button type="submit"
|
||||
<a mat-raised-button type="submit"
|
||||
[disabled]="!searchFormControl.value || timeout > 0 || searchDisabled">
|
||||
<mat-icon inline="true">{{'jukebox.search.icon' | i18n}}</mat-icon>
|
||||
{{'jukebox.search.submit' | i18n}}
|
||||
</button>
|
||||
</a>
|
||||
</mat-card-actions>
|
||||
<mat-card-footer>
|
||||
<a (click)="check()" class="help-button" mat-fab color="accent">
|
||||
@ -62,7 +63,7 @@
|
||||
|
||||
<mat-card *ngIf="searchResult && ((searchResult.offset + searchResult.limit) < searchResult.total)">
|
||||
<mat-card-actions>
|
||||
<button mat-button (click)="searchMore()"> {{'jukebox.search.more' | i18n}}</button>
|
||||
<a mat-button (click)="searchMore()"> {{'jukebox.search.more' | i18n}}</a>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
@ -6,7 +6,8 @@
|
||||
{{'security.2fa.totp.invalid' | i18n}}
|
||||
</mat-error>
|
||||
<mat-form-field>
|
||||
<input id="code" name="code" matInput placeholder="{{'security.2fa.totp.code' | i18n}}" formControlName="code"
|
||||
<mat-label>{{'security.2fa.totp.code' | i18n}}</mat-label>
|
||||
<input id="code" name="code" matInput formControlName="code"
|
||||
required matAutofocus>
|
||||
<mat-error>
|
||||
{{'security.2fa.totp.missing' | i18n}}
|
||||
@ -17,8 +18,8 @@
|
||||
</mat-slide-toggle>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button type="submit" mat-raised-button color="primary"
|
||||
[disabled]="form.invalid">{{'security.2fa.totp.login' | i18n}}</button>
|
||||
<a type="submit" mat-raised-button color="primary"
|
||||
[disabled]="form.invalid">{{'security.2fa.totp.login' | i18n}}</a>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</form>
|
@ -6,7 +6,7 @@ import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { environment } from '../../../environments/environment';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
selector: 'app-login-totp',
|
||||
templateUrl: './login-totp.component.html',
|
||||
styleUrls: [ './login-totp.component.scss' ]
|
||||
})
|
||||
|
@ -6,14 +6,16 @@
|
||||
{{'login.invalid' | i18n}}
|
||||
</mat-error>
|
||||
<mat-form-field>
|
||||
<input id="username" name="username" matInput placeholder="{{'username' | i18n}}"
|
||||
<mat-label>{{'username' | i18n}}</mat-label>
|
||||
<input id="username" name="username" matInput
|
||||
formControlName="username" required matAutofocus>
|
||||
<mat-error>
|
||||
{{'username.missing' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input id="password" name="password" matInput type="password" placeholder="{{'password' | i18n}}"
|
||||
<mat-label>{{'password' | i18n}}</mat-label>
|
||||
<input id="password" name="password" matInput type="password"
|
||||
formControlName="password" required>
|
||||
<mat-error>
|
||||
{{'password.invalid.hint' | i18n}}
|
||||
@ -24,7 +26,7 @@
|
||||
</mat-slide-toggle>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button type="submit" mat-raised-button color="primary"
|
||||
<button type="submit" type="submit" mat-raised-button color="primary"
|
||||
[disabled]="form.invalid">{{'login' | i18n}}</button>
|
||||
<a routerLink="/password" mat-raised-button color="warn">{{'password.forgot' | i18n}}</a>
|
||||
</mat-card-actions>
|
||||
|
@ -12,11 +12,11 @@
|
||||
<ng-container matColumnDef="delete">
|
||||
<th mat-header-cell *matHeaderCellDef class="align-right"> {{'minetest.accounts.delete' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let minetestAccount" class="text-right">
|
||||
<a mat-icon-button color="warn">
|
||||
<mat-icon matTooltip="{{'minetest.accounts.deletion' | i18n}}">warning</mat-icon>
|
||||
<a mat-icon-button color="warn" matTooltip="{{'minetest.accounts.deletion' | i18n}}">
|
||||
<mat-icon>warning</mat-icon>
|
||||
</a>
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="confirmDelete(minetestAccount.name)">delete</mat-icon>
|
||||
<a mat-icon-button (click)="confirmDelete(minetestAccount.name)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -33,7 +33,8 @@
|
||||
<div *ngIf="minetestAccountsQuota">
|
||||
<p>{{'minetest.accounts.left' | i18n:minetestAccountsQuota}}</p>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'minetest.accounts.name' | i18n}}" formControlName="name"
|
||||
<mat-label>{{'minetest.accounts.name' | i18n}}</mat-label>
|
||||
<input matInput formControlName="name"
|
||||
[(ngModel)]="minetestAccount.name" required pattern="[-_a-zA-Z0-9]+">
|
||||
<mat-error>
|
||||
{{'minetest.accounts.error.name' | i18n}}
|
||||
@ -42,7 +43,7 @@
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="minetestAccountsQuota && !working" mat-raised-button color="primary" [disabled]="form.invalid">
|
||||
<button type="submit" *ngIf="minetestAccountsQuota && !working" mat-raised-button color="primary" [disabled]="form.invalid">
|
||||
{{'minetest.accounts.create' | i18n}}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
|
@ -2,24 +2,11 @@ mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mat-header-cell,
|
||||
.mat-cell {
|
||||
&.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-cell .mat-button {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.align-right{
|
||||
display: flex;
|
||||
padding: 21px 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.url {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<p *ngIf="!tags || tags.length == 0">{{'partey.tags.none' | i18n}}</p>
|
||||
|
||||
<mat-chip-list>
|
||||
<mat-chip-listbox>
|
||||
<ng-container *ngFor="let tag of tags">
|
||||
<mat-chip *ngIf="activeTag(tag)" color="accent" selected matTooltip="{{ 'partey.tag.' + tag.tag + '.hint' | i18nEmpty}}">
|
||||
{{ 'partey.tag.' + tag.tag | i18nEmpty}}</mat-chip>
|
||||
@ -12,7 +12,7 @@
|
||||
matTooltip="{{'partey.tags.expires' | i18n:(tag.expires | datef)}}" selected>
|
||||
{{ 'partey.tag.' + tag.tag | i18nEmpty}}</mat-chip>
|
||||
</ng-container>
|
||||
</mat-chip-list>
|
||||
</mat-chip-listbox>
|
||||
|
||||
|
||||
<app-partey-timeslots></app-partey-timeslots>
|
@ -1,24 +1,26 @@
|
||||
<h1 mat-dialog-title>
|
||||
<mat-icon inline="true">{{'partey.timeslots.type.' + timeslot.type + '.icon' | i18n}}</mat-icon> {{(timeslot.id ? 'partey.timeslots.edit' : 'partey.timeslots.create.' +
|
||||
<mat-icon inline="true">{{'partey.timeslots.type.' + timeslot.type + '.icon' | i18n}}</mat-icon> {{(timeslot.id ?
|
||||
'partey.timeslots.edit' : 'partey.timeslots.create.' +
|
||||
timeslot.type) | i18n}}
|
||||
</h1>
|
||||
<mat-dialog-content>
|
||||
<h3 *ngIf="timeslot.id">{{'partey.timeslots.type.' + timeslot.type | i18n}}</h3>
|
||||
<form [formGroup]="form">
|
||||
<mat-form-field *ngIf="timeslot.type == 'VIDEO' || timeslot.type == 'AUDIO'">
|
||||
<input matInput [(ngModel)]="timeslot.share" formControlName="share"
|
||||
placeholder="{{'partey.timeslots.share.placeholder' | i18n}}">
|
||||
<mat-label>{{'partey.timeslots.share.placeholder' | i18n}}</mat-label>
|
||||
<input matInput [(ngModel)]="timeslot.share" formControlName="share">
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngIf="timeslot.type == 'VIDEO_STREAM'">
|
||||
<input matInput [(ngModel)]="timeslot.stream" formControlName="stream"
|
||||
placeholder="{{'partey.timeslots.stream' | i18n}}">
|
||||
<mat-label>{{'partey.timeslots.stream' | i18n}}</mat-label>
|
||||
<input matInput [(ngModel)]="timeslot.stream" formControlName="stream">
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngIf="timeslot.type == 'AUDIO_STREAM' && timeslot.secret">
|
||||
<textarea [mat-autosize] matInput [value]="timeslot.secret" readonly placeholder="{{'partey.timeslots.secret' | i18n}}"></textarea>
|
||||
<mat-label>{{'partey.timeslots.secret' | i18n}}</mat-label>
|
||||
<textarea [mat-autosize] matInput [value]="timeslot.secret" readonly></textarea>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput [ngxMatDatetimePicker]="startsPicker" [(ngModel)]="timeslot.starts" formControlName="starts"
|
||||
placeholder="{{'partey.timeslots.starts' | i18n}}">
|
||||
<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>
|
||||
<mat-error>
|
||||
@ -26,8 +28,8 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput [ngxMatDatetimePicker]="endsPicker" [(ngModel)]="timeslot.ends" formControlName="ends"
|
||||
placeholder="{{'partey.timeslots.ends' | i18n}}">
|
||||
<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>
|
||||
<mat-error>
|
||||
@ -35,18 +37,18 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput [(ngModel)]="timeslot.title" formControlName="title"
|
||||
placeholder="{{'partey.timeslots.title' | i18n}}">
|
||||
<mat-label>{{'partey.timeslots.title' | i18n}}</mat-label>
|
||||
<input matInput [(ngModel)]="timeslot.title" formControlName="title">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<textarea matInput [(ngModel)]="timeslot.description" formControlName="description"
|
||||
placeholder="{{'partey.timeslots.description' | i18n}}"></textarea>
|
||||
<mat-label>{{'partey.timeslots.description' | i18n}}</mat-label>
|
||||
<textarea matInput [(ngModel)]="timeslot.description" formControlName="description"></textarea>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button (click)="timeslot.id ? save(timeslot) : create(timeslot)"
|
||||
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
|
||||
<a [disabled]="form.invalid" mat-raised-button (click)="timeslot.id ? save(timeslot) : create(timeslot)"
|
||||
color="accent">{{ (timeslot.id ? 'partey.timeslots.save' : 'partey.timeslots.create') |
|
||||
i18n}}</button>
|
||||
i18n}}</a>
|
||||
</mat-dialog-actions>
|
@ -1,8 +1,10 @@
|
||||
<h3>{{'partey.timeslots' | i18n}}</h3>
|
||||
|
||||
<div *ngIf="timeslots">
|
||||
<div class="flex">
|
||||
<mat-form-field>
|
||||
<input matInput [formControl]="searchFormControl" placeholder="{{'partey.timeslots.filter.search' | i18n}}">
|
||||
<mat-label>{{'partey.timeslots.filter.search' | i18n}}</mat-label>
|
||||
<input matInput [formControl]="searchFormControl">
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>{{'partey.timeslots.filter.owner' | i18n}}</mat-label>
|
||||
@ -22,18 +24,19 @@
|
||||
</mat-option>
|
||||
<mat-select-trigger>
|
||||
<mat-icon inline="true" *ngIf="typeFormControl.value ">{{'partey.timeslots.type.' + typeFormControl.value +
|
||||
'.icon' | i18n}}</mat-icon> {{'partey.timeslots.filter.type.' + (typeFormControl.value ? typeFormControl.value
|
||||
'.icon' | i18n}}</mat-icon> {{'partey.timeslots.filter.type.' + (typeFormControl.value ?
|
||||
typeFormControl.value
|
||||
: 'all') | i18n}}
|
||||
</mat-select-trigger>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput [ngxMatDatetimePicker]="afterPicker" [formControl]="afterFormControl"
|
||||
placeholder="{{'partey.timeslots.filter.after' | i18n}}">
|
||||
<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>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
<table mat-table matSort [dataSource]="timeslots.content" (matSortChange)="updateSort($event)">
|
||||
<ng-container matColumnDef="starts">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="starts"> {{'partey.timeslots.starts' | i18n}} </th>
|
||||
@ -79,8 +82,8 @@
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let timeslot">
|
||||
<div *ngIf="timeslot.owner == userId">
|
||||
<button *ngIf="timeslot.type == 'AUDIO_STREAM'" mat-raised-button
|
||||
(click)="copySecretToClipboard(timeslot.secret)">{{'partey.timeslots.secret.copy' | i18n}}</button>
|
||||
<a *ngIf="timeslot.type == 'AUDIO_STREAM'" mat-raised-button
|
||||
(click)="copySecretToClipboard(timeslot.secret)">{{'partey.timeslots.secret.copy' | i18n}}</a>
|
||||
<span *ngIf="timeslot.type == 'VIDEO_STREAM'"> {{ timeslot.stream }} </span>
|
||||
</div>
|
||||
</td>
|
||||
@ -89,8 +92,8 @@
|
||||
<ng-container matColumnDef="edit">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'partey.timeslots.edit' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let timeslot" class="text-right">
|
||||
<a *ngIf="timeslot.owner == userId" mat-icon-button>
|
||||
<mat-icon (click)="openEdit(timeslot)">edit</mat-icon>
|
||||
<a *ngIf="timeslot.owner == userId" mat-icon-button (click)="openEdit(timeslot)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -98,8 +101,8 @@
|
||||
<ng-container matColumnDef="delete">
|
||||
<th mat-header-cell *matHeaderCellDef class="align-right"> {{'partey.timeslots.delete' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let timeslot" class="text-right">
|
||||
<a *ngIf="timeslot.owner == userId" mat-icon-button>
|
||||
<mat-icon (click)="confirmDelete(timeslot)">delete</mat-icon>
|
||||
<a *ngIf="timeslot.owner == userId" mat-icon-button (click)="confirmDelete(timeslot)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -120,12 +123,12 @@
|
||||
<p>{{'partey.timeslots.left' | i18n:timeslotsQuota}}</p>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions *ngIf="timeslotsQuota">
|
||||
<mat-card-actions *ngIf="timeslotsQuota" class="flex wrap">
|
||||
<div *ngFor="let type of types">
|
||||
<button mat-raised-button (click)="openCreate(type)">
|
||||
<a mat-raised-button (click)="openCreate(type)">
|
||||
<mat-icon inline="true">{{'partey.timeslots.type.' + type + '.icon' | i18n}}</mat-icon>
|
||||
{{'partey.timeslots.create.' + type | i18n}}
|
||||
</button>
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
</div>
|
||||
|
@ -1,21 +1,7 @@
|
||||
.mat-header-cell,
|
||||
.mat-cell {
|
||||
&.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-cell .mat-button {
|
||||
mat-cell mat-button {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.align-right{
|
||||
display: flex;
|
||||
padding: 21px 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.mat-form-field+.mat-form-field {
|
||||
mat-form-field+mat-form-field {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
@ -6,14 +6,16 @@
|
||||
{{'password.reset.tokenInvalid' | i18n}}
|
||||
</mat-error>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" placeholder="{{'password' | i18n}}" formControlName="password"
|
||||
<mat-label>{{'password' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="password"
|
||||
[(ngModel)]="model.password">
|
||||
<mat-error *ngFor="let error of form.get('password').errors | keyvalue">
|
||||
{{error.key}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" length="6" placeholder="{{'password.confirm' | i18n}}"
|
||||
<mat-label>{{'password.confirm' | i18n}}</mat-label>
|
||||
<input matInput type="password" length="6"
|
||||
formControlName="password2" [(ngModel)]="model.password2">
|
||||
<mat-error>
|
||||
{{'password.not-match' | i18n}}
|
||||
@ -21,7 +23,7 @@
|
||||
</mat-form-field>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="!working" mat-raised-button color="primary" [disabled]="form.invalid">
|
||||
<button type="submit" *ngIf="!working" mat-raised-button color="primary" [disabled]="form.invalid">
|
||||
{{'password.reset' | i18n}}
|
||||
</button>
|
||||
|
||||
|
@ -3,7 +3,8 @@
|
||||
<mat-card-content>
|
||||
<h2>{{'password.request' | i18n}}</h2>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'username' | i18n}}" formControlName="username" [(ngModel)]="model.username">
|
||||
<mat-label>{{'username' | i18n}}</mat-label>
|
||||
<input matInput formControlName="username" [(ngModel)]="model.username">
|
||||
<mat-error>
|
||||
{{'username.missing' | i18n}}
|
||||
</mat-error>
|
||||
@ -11,12 +12,13 @@
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{'pgp.privateKey' | i18n}}</mat-label>
|
||||
<textarea matInput formControlName="privateKey" placeholder="Private Key"
|
||||
<mat-label>Private Key</mat-label>
|
||||
<textarea matInput formControlName="privateKey"
|
||||
[(ngModel)]="model.privateKey"></textarea>
|
||||
</mat-form-field>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="!working" mat-raised-button color="primary" [disabled]="form.invalid">
|
||||
<button type="submit" *ngIf="!working" mat-raised-button color="primary" [disabled]="form.invalid">
|
||||
{{'password.request' | i18n}}
|
||||
</button>
|
||||
|
||||
|
@ -18,17 +18,19 @@
|
||||
color="warn">{{'register.token.locked.action' | i18n}}</a>
|
||||
</mat-error>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'username' | i18n}}" formControlName="username"
|
||||
<mat-label>{{'username' | i18n}}</mat-label>
|
||||
<input matInput formControlName="username"
|
||||
[(ngModel)]="model.username" required matAutofocus tabindex="1">
|
||||
<mat-error>
|
||||
{{'username.error' | i18n}}
|
||||
</mat-error>
|
||||
<a mat-button matSuffix mat-icon-button (click)="genUsername()" tabindex="8">
|
||||
<a mat-icon-button matSuffix (click)="genUsername()" tabindex="8">
|
||||
<mat-icon>autorenew</mat-icon>
|
||||
</a>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" placeholder="{{'password' | i18n}}" formControlName="password"
|
||||
<mat-label>{{'password' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="password"
|
||||
[(ngModel)]="model.password" required tabindex="2">
|
||||
<mat-error>
|
||||
<div *ngFor="let error of form.get('password').errors | keyvalue">
|
||||
@ -37,7 +39,8 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" placeholder="{{'password.confirm' | i18n}}" formControlName="password2"
|
||||
<mat-label>{{'password.confirm' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="password2"
|
||||
[(ngModel)]="model.password2" required tabindex="3">
|
||||
<mat-error>
|
||||
{{'password.not-match' | i18n}}
|
||||
@ -52,7 +55,8 @@
|
||||
matTooltip="{{'email.primary.hint' | i18n:model.username}}">info</mat-icon>
|
||||
|
||||
<mat-form-field *ngIf="model.primaryEmail">
|
||||
<input matInput type="email" placeholder="{{'email' | i18n}}" formControlName="email"
|
||||
<mat-label>{{'email' | i18n}}</mat-label>
|
||||
<input matInput type="email" formControlName="email"
|
||||
[(ngModel)]="model.email" required tabindex="5">
|
||||
<mat-error>
|
||||
{{'email.invalid' | i18n}}
|
||||
@ -69,7 +73,7 @@
|
||||
<mat-divider></mat-divider>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="!working" mat-raised-button color="primary" [disabled]="form.invalid" tabindex="6">
|
||||
<button type="submit" *ngIf="!working" mat-raised-button color="primary" [disabled]="form.invalid" tabindex="6">
|
||||
{{'register' | i18n}}
|
||||
</button>
|
||||
|
||||
|
@ -16,9 +16,9 @@
|
||||
i18n}}</a>
|
||||
<a mat-raised-button (click)="copyKey(privkey)">{{'pgp.privateKey.copyKey' |
|
||||
i18n}}</a>
|
||||
<button mat-icon-button #privateKeyHelp="matTooltip" (click)="privateKeyHelp.toggle()" [matTooltip]="'pgp.privateKey.help' | i18n" matTooltipPosition="after">
|
||||
<a mat-icon-button #privateKeyHelp="matTooltip" (click)="privateKeyHelp.toggle()" [matTooltip]="'pgp.privateKey.help' | i18n" matTooltipPosition="after">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
</a>
|
||||
</mat-dialog-actions>
|
||||
<br />
|
||||
<mat-dialog-actions>
|
||||
@ -26,5 +26,5 @@
|
||||
<mat-slide-toggle [(ngModel)]="data.confirmClose" [disabled]="!downloaded">
|
||||
{{'pgp.privateKey.confirmStore' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
<button mat-button [disabled]="!data.confirmClose" [mat-dialog-close]="true">{{'ok' | i18n}}</button>
|
||||
<a mat-button [disabled]="!data.confirmClose" [mat-dialog-close]="true">{{'ok' | i18n}}</a>
|
||||
</mat-dialog-actions>
|
@ -3,15 +3,15 @@
|
||||
|
||||
|
||||
<mat-form-field>
|
||||
<mat-chip-list #chipList [multiple]="true" [selectable]="true" cdkDropList cdkDropListOrientation="horizontal"
|
||||
<mat-chip-listbox #chipList [multiple]="true" [selectable]="true" cdkDropList cdkDropListOrientation="horizontal"
|
||||
(cdkDropListDropped)="drop($event)">
|
||||
<mat-chip *ngFor="let dict of dicts" cdkDrag [selected]="dict.selected" (click)="toggle(dict)">
|
||||
{{dict.name}}
|
||||
</mat-chip>
|
||||
</mat-chip-list>
|
||||
</mat-chip-listbox>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button (click)="onOkClick()">Ok</button>
|
||||
<a mat-button (click)="onOkClick()">Ok</a>
|
||||
</div>
|
@ -6,9 +6,9 @@
|
||||
<mat-list-item *ngFor="let item of items">
|
||||
<mat-icon mat-list-icon>plus_one</mat-icon>
|
||||
{{ item.name[currentLocale] || 'missing' }}
|
||||
<button mat-icon-button (click)="removeSecret(item.secret)">
|
||||
<a mat-icon-button (click)="removeSecret(item.secret)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</a>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
|
||||
@ -16,9 +16,9 @@
|
||||
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="auth.authenticated" mat-raised-button color="accent" (click)="redeem()">
|
||||
<a *ngIf="auth.authenticated" mat-raised-button color="accent" (click)="redeem()">
|
||||
<mat-icon>redeem</mat-icon> {{'tokens.redeem' | i18n}}
|
||||
</button>
|
||||
</a>
|
||||
|
||||
<ng-container *ngIf="!auth.authenticated">
|
||||
<p>{{'tokens.register' | i18n}}</p>
|
||||
@ -65,14 +65,16 @@
|
||||
{{'tokens.redeemed' | i18n}}
|
||||
</mat-error>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'token' | i18n}}" formControlName="token" matAutofocus>
|
||||
<mat-label>{{'token' | i18n}}</mat-label>
|
||||
<input matInput formControlName="token" matAutofocus>
|
||||
<mat-error>
|
||||
{{'tokens.provide-valid' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-raised-button color="primary" [disabled]="form.invalid">{{ (items && items[0] ? 'tokens.validate.other' : 'tokens.validate') | i18n}}</button>
|
||||
<button type="submit" mat-raised-button color="primary" [disabled]="form.invalid">{{ (items && items[0] ?
|
||||
'tokens.validate.other' : 'tokens.validate') | i18n}}</button>
|
||||
</mat-card-actions>
|
||||
<mat-card-footer>
|
||||
<a href="https://wiki.bstly.de/services/webstly#token" class="help-button"
|
||||
|
@ -1,17 +1,20 @@
|
||||
<h3>{{'urlshortener' | i18n}}</h3>
|
||||
|
||||
<div *ngIf="shortenedUrls">
|
||||
<div class="flex">
|
||||
<mat-form-field>
|
||||
<input matInput [formControl]="searchFormControl" placeholder="{{'urlshortener.search' | i18n}}">
|
||||
<mat-label>{{'urlshortener.search' | i18n}}</mat-label>
|
||||
<input matInput [formControl]="searchFormControl">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<table mat-table matSort [dataSource]="shortenedUrls.content" (matSortChange)="updateSort($event)">
|
||||
|
||||
<ng-container matColumnDef="share">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'urlshortener.share' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let shortenedUrl">
|
||||
<button mat-icon-button (click)="share(shortenedUrl)">
|
||||
<a mat-icon-button (click)="share(shortenedUrl)">
|
||||
<mat-icon>share</mat-icon>
|
||||
</button>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
@ -52,8 +55,8 @@
|
||||
<ng-container matColumnDef="edit">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'urlshortener.edit' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let shortenedUrl" class="text-right">
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="edit(shortenedUrl)">edit</mat-icon>
|
||||
<a mat-icon-button (click)="edit(shortenedUrl)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -61,8 +64,8 @@
|
||||
<ng-container matColumnDef="delete">
|
||||
<th mat-header-cell *matHeaderCellDef class="align-right"> {{'urlshortener.delete' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let shortenedUrl" class="text-right">
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="confirmDelete(shortenedUrl)">delete</mat-icon>
|
||||
<a mat-icon-button (click)="confirmDelete(shortenedUrl)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -84,16 +87,16 @@
|
||||
<p>{{'urlshortener.left' | i18n:shortenedUrlQuota}}</p>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'urlshortener.url' | i18n}}" formControlName="url"
|
||||
[(ngModel)]="shortenedUrl.url" type="url">
|
||||
<mat-label>{{'urlshortener.url' | i18n}}</mat-label>
|
||||
<input matInput formControlName="url" [(ngModel)]="shortenedUrl.url" type="url">
|
||||
<mat-error>
|
||||
{{'urlshortener.error.url' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<textarea matInput type="note" placeholder="{{'urlshortener.note' | i18n}}" formControlName="note"
|
||||
[(ngModel)]="shortenedUrl.note"></textarea>
|
||||
<mat-label>{{'urlshortener.note' | i18n}}</mat-label>
|
||||
<textarea matInput type="note" formControlName="note" [(ngModel)]="shortenedUrl.note"></textarea>
|
||||
<mat-error>
|
||||
{{'urlshortener.error.note' | i18n}}
|
||||
</mat-error>
|
||||
@ -106,8 +109,8 @@
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" placeholder="{{'password' | i18n}}" formControlName="password"
|
||||
[(ngModel)]="shortenedUrl.password">
|
||||
<mat-label>{{'password' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="password" [(ngModel)]="shortenedUrl.password">
|
||||
<mat-error>
|
||||
<div *ngFor="let error of form.get('password').errors | keyvalue">
|
||||
{{'password.error.' + error.key | i18n}}<br>
|
||||
@ -116,16 +119,17 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput type="password" placeholder="{{'password.confirm' | i18n}}" formControlName="password2"
|
||||
[(ngModel)]="shortenedUrl.password2">
|
||||
<mat-label>{{'password.confirm' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="password2" [(ngModel)]="shortenedUrl.password2">
|
||||
<mat-error>
|
||||
{{'password.not-match' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{'urlshortener.expires' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="expiresPicker" [(ngModel)]="shortenedUrl.expires"
|
||||
formControlName="expires" placeholder="{{'urlshortener.expires' | i18n}}">
|
||||
formControlName="expires">
|
||||
<mat-datepicker-toggle matSuffix [for]="expiresPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #expiresPicker></ngx-mat-datetime-picker>
|
||||
<mat-error>
|
||||
@ -139,8 +143,8 @@
|
||||
</mat-slide-toggle>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'urlshortener.code' | i18n}}" formControlName="code"
|
||||
[(ngModel)]="shortenedUrl.code">
|
||||
<mat-label>{{'urlshortener.code' | i18n}}</mat-label>
|
||||
<input matInput formControlName="code" [(ngModel)]="shortenedUrl.code">
|
||||
<mat-error>
|
||||
{{'urlshortener.error.code' | i18n}}
|
||||
</mat-error>
|
||||
@ -149,7 +153,8 @@
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="shortenedUrlQuota && !working" mat-raised-button color="primary" [disabled]="form.invalid">
|
||||
<button type="submit" *ngIf="shortenedUrlQuota && !working" mat-raised-button color="primary"
|
||||
[disabled]="form.invalid">
|
||||
{{'urlshortener.create' | i18n}}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
|
@ -2,24 +2,11 @@ mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mat-header-cell,
|
||||
.mat-cell {
|
||||
&.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-cell .mat-button {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.align-right{
|
||||
display: flex;
|
||||
padding: 21px 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.url {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
|
@ -4,16 +4,16 @@
|
||||
<mat-dialog-content>
|
||||
<form [formGroup]="form">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'urlshortener.url' | i18n}}" formControlName="url"
|
||||
[(ngModel)]="shortenedUrlModel.url" type="url">
|
||||
<mat-label>{{'urlshortener.url' | i18n}}</mat-label>
|
||||
<input matInput formControlName="url" [(ngModel)]="shortenedUrlModel.url" type="url">
|
||||
<mat-error>
|
||||
{{'urlshortener.error.url' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<textarea matInput type="note" placeholder="{{'urlshortener.note' | i18n}}" formControlName="note"
|
||||
[(ngModel)]="shortenedUrlModel.note"></textarea>
|
||||
<mat-label>{{'urlshortener.note' | i18n}}</mat-label>
|
||||
<textarea matInput formControlName="note" [(ngModel)]="shortenedUrlModel.note"></textarea>
|
||||
<mat-error>
|
||||
{{'urlshortener.error.note' | i18n}}
|
||||
</mat-error>
|
||||
@ -31,8 +31,8 @@
|
||||
</mat-slide-toggle>
|
||||
|
||||
<mat-form-field *ngIf="shortenedUrlModel.newPassword">
|
||||
<input matInput type="password" placeholder="{{'password' | i18n}}" formControlName="password"
|
||||
[(ngModel)]="shortenedUrlModel.password">
|
||||
<mat-label>{{'password' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="password" [(ngModel)]="shortenedUrlModel.password">
|
||||
<mat-error>
|
||||
<div *ngFor="let error of form.get('password').errors | keyvalue">
|
||||
{{'password.error.' + error.key | i18n}}<br>
|
||||
@ -41,16 +41,17 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field *ngIf="shortenedUrlModel.newPassword">
|
||||
<input matInput type="password" placeholder="{{'password.confirm' | i18n}}" formControlName="password2"
|
||||
[(ngModel)]="shortenedUrlModel.password2">
|
||||
<mat-label>{{'password.confirm' | i18n}}</mat-label>
|
||||
<input matInput type="password" formControlName="password2" [(ngModel)]="shortenedUrlModel.password2">
|
||||
<mat-error>
|
||||
{{'password.not-match' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{'urlshortener.expires' | i18n}}</mat-label>
|
||||
<input matInput [ngxMatDatetimePicker]="expiresPicker" [(ngModel)]="shortenedUrlModel.expires"
|
||||
formControlName="expires" placeholder="{{'urlshortener.expires' | i18n}}">
|
||||
formControlName="expires">
|
||||
<mat-datepicker-toggle matSuffix [for]="expiresPicker"></mat-datepicker-toggle>
|
||||
<ngx-mat-datetime-picker #expiresPicker></ngx-mat-datetime-picker>
|
||||
<mat-error>
|
||||
@ -64,8 +65,8 @@
|
||||
</mat-slide-toggle>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'urlshortener.code' | i18n}}" formControlName="code"
|
||||
[(ngModel)]="shortenedUrlModel.newCode">
|
||||
<mat-label>{{'urlshortener.code' | i18n}}</mat-label>
|
||||
<input matInput formControlName="code" [(ngModel)]="shortenedUrlModel.newCode">
|
||||
<mat-error>
|
||||
{{'urlshortener.error.code' | i18n}}
|
||||
</mat-error>
|
||||
@ -74,8 +75,8 @@
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">{{
|
||||
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
|
||||
<a [disabled]="form.invalid" mat-raised-button (click)="save()" color="accent">{{
|
||||
'urlshortener.save'
|
||||
| i18n}}</button>
|
||||
| i18n}}</a>
|
||||
</mat-dialog-actions>
|
@ -4,17 +4,18 @@
|
||||
<h2>{{'urlshortener.password' | i18n}}
|
||||
</h2>
|
||||
<mat-form-field>
|
||||
<input id="password" name="password" matInput type="password" placeholder="{{'password' | i18n}}" required matAutofocus>
|
||||
<mat-label>{{'password' | i18n}}</mat-label>
|
||||
<input id="password" name="password" matInput type="password" required matAutofocus>
|
||||
</mat-form-field>
|
||||
<mat-error *ngIf="invalidPassword">
|
||||
{{'urlshortener.password.invalid' | i18n}}
|
||||
</mat-error>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button type="submit" (click)="loginForm.submit()" mat-raised-button color="primary"
|
||||
<a type="submit" (click)="loginForm.submit()" mat-raised-button color="primary"
|
||||
[disabled]="loginForm.invalid">{{'urlshortener.password.submit' |
|
||||
i18n}}<mat-icon style="font-size: 1em;">open_in_new
|
||||
</mat-icon></button>
|
||||
</mat-icon></a>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</form>
|
@ -33,5 +33,5 @@
|
||||
</mat-list>
|
||||
</div>
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button mat-dialog-close>{{'close' | i18n}}</button>
|
||||
<a mat-button mat-dialog-close>{{'close' | i18n}}</a>
|
||||
</div>
|
@ -3,9 +3,9 @@
|
||||
|
||||
<div *ngIf="success">
|
||||
<h3>{{model.username}}
|
||||
<button *ngIf="isMe" mat-icon-button color="accent">
|
||||
<a *ngIf="isMe" mat-icon-button color="accent">
|
||||
<mat-icon>star</mat-icon>
|
||||
</button>
|
||||
</a>
|
||||
</h3>
|
||||
<app-profilefields [username]="model.username"></app-profilefields>
|
||||
<div *ngIf="model.aliases && model.aliases.length > 0">
|
||||
|
@ -1,8 +1,8 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ReplaySubject, of} from 'rxjs';
|
||||
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ReplaySubject, of } from 'rxjs';
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
|
||||
import {environment} from './../../environments/environment';
|
||||
import { environment } from './../../environments/environment';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@ -27,6 +27,7 @@ export class AuthService {
|
||||
return this.http.get(environment.apiUrl + "/auth/me");
|
||||
}
|
||||
|
||||
|
||||
login(loginModel) {
|
||||
return this.http.post(environment.apiUrl + "/auth/login", loginModel);
|
||||
}
|
||||
@ -37,11 +38,15 @@ export class AuthService {
|
||||
|
||||
passwordRequest(username) {
|
||||
const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');
|
||||
return this.http.post(environment.apiUrl + "/auth/password/request", username, {headers, responseType: 'text'});
|
||||
return this.http.post(environment.apiUrl + "/auth/password/request", username, { headers, responseType: 'text' });
|
||||
}
|
||||
|
||||
passwordReset(model) {
|
||||
const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');
|
||||
return this.http.post(environment.apiUrl + "/auth/password/reset", model);
|
||||
}
|
||||
|
||||
setAlias(alias) {
|
||||
return this.http.post(environment.apiUrl + "/auth/alias", alias);
|
||||
}
|
||||
}
|
@ -2,6 +2,6 @@
|
||||
{{text}}
|
||||
</mat-dialog-content>
|
||||
<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>
|
||||
<a mat-raised-button [mat-dialog-close]="true" color="accent" matAutofocus>{{'confirm' | i18n}}</a>
|
||||
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
|
||||
</mat-dialog-actions>
|
@ -1,18 +1,21 @@
|
||||
<div fxLayout="row wrap" fxLayoutAlign="start stretch">
|
||||
<div fxFlex="33%">
|
||||
<div class="flex wrap" fxLayoutAlign="start stretch">
|
||||
<div [style.flex-basis]="'33%'">
|
||||
<mat-form-field>
|
||||
<input matInput type="number" min="0" placeholder="{{'durationpicker.days' | i18n}}" [formControl]="days">
|
||||
<mat-label>{{'durationpicker.days' | i18n}}</mat-label>
|
||||
<input matInput type="number" min="0" [formControl]="days">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxFlex="33%">
|
||||
<div [style.flex-basis]="'33%'">
|
||||
<mat-form-field>
|
||||
<input matInput type="number" min="0" max="23" placeholder="{{'durationpicker.hours' | i18n}}"
|
||||
<mat-label>{{'durationpicker.hours' | i18n}}</mat-label>
|
||||
<input matInput type="number" min="0" max="23"
|
||||
[formControl]="hours">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxFlex="33%">
|
||||
<div [style.flex-basis]="'33%'">
|
||||
<mat-form-field>
|
||||
<input matInput type="number" min="0" max="59" placeholder="{{'durationpicker.minutes' | i18n}}"
|
||||
<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>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<mat-toolbar color="primary">
|
||||
<a href="javascript:" mat-icon-button>
|
||||
<mat-icon (click)="sidenav.toggle()">menu</mat-icon>
|
||||
<a href="javascript:" mat-icon-button (click)="sidenav.toggle()">
|
||||
<mat-icon>menu</mat-icon>
|
||||
</a>
|
||||
<mat-icon svgIcon="logo"></mat-icon>
|
||||
<span>
|
||||
@ -9,17 +9,17 @@
|
||||
<span class="spacer"></span>
|
||||
<ng-container>
|
||||
|
||||
<button mat-button [matMenuTriggerFor]="menu">
|
||||
<a mat-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>settings</mat-icon>
|
||||
<mat-icon>arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
</a>
|
||||
<mat-menu #menu="matMenu">
|
||||
<a *ngIf="!auth || auth && !auth.authenticated" routerLink="/login" routerLinkActive="active" mat-menu-item>
|
||||
<mat-icon>login</mat-icon> {{'login' | i18n}}
|
||||
</a>
|
||||
<mat-divider *ngIf="!auth || auth && !auth.authenticated"></mat-divider>
|
||||
<a *ngFor="let locale of locales" mat-menu-item (click)="setLocale(locale)">{{'locale.' + locale + '.long' |
|
||||
i18n}} <mat-icon inline=true *ngIf="locale == currentLocale">done</mat-icon></a>
|
||||
i18n}} <mat-icon *ngIf="locale == currentLocale">done</mat-icon></a>
|
||||
<a mat-menu-item>
|
||||
<mat-slide-toggle (change)="darkThemeChange($event)" [checked]="darkTheme == 'true'">
|
||||
{{'profileField.name.darkTheme' | i18n}}
|
||||
|
@ -3,9 +3,9 @@
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="name"> {{'permissions.name' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let permission">
|
||||
<mat-icon inline=true>{{'services.' + permission.name + '.icon' | i18n}}</mat-icon>
|
||||
<mat-icon inline="true">{{'services.' + permission.name + '.icon' | i18n}}</mat-icon>
|
||||
{{'services.' + permission.name + '.title' | i18n}}
|
||||
<mat-icon inline=true *ngIf="permission.addon">add_circle</mat-icon>
|
||||
<mat-icon inline="true" *ngIf="permission.addon">add_circle</mat-icon>
|
||||
<br>
|
||||
<small>{{'services.' + permission.name + '.subtitle' | i18n}}</small>
|
||||
</td>
|
||||
|
@ -13,9 +13,9 @@
|
||||
i18n}}</a>
|
||||
<a mat-raised-button (click)="copyKey(privkey)">{{'pgp.privateKey.copyKey' |
|
||||
i18n}}</a>
|
||||
<button mat-icon-button #privateKeyHelp="matTooltip" (click)="privateKeyHelp.toggle()" [matTooltip]="'pgp.privateKey.help' | i18n" matTooltipPosition="after">
|
||||
<a mat-icon-button #privateKeyHelp="matTooltip" (click)="privateKeyHelp.toggle()" [matTooltip]="'pgp.privateKey.help' | i18n" matTooltipPosition="after">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
</a>
|
||||
</mat-dialog-actions>
|
||||
<br />
|
||||
<mat-dialog-actions>
|
||||
@ -23,6 +23,6 @@
|
||||
<mat-slide-toggle [(ngModel)]="data.confirmClose" [disabled]="!downloaded">
|
||||
{{'pgp.privateKey.confirmStore' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
||||
<button mat-button color="accent" [disabled]="!data.confirmClose" [mat-dialog-close]="data.publicKey">{{'ok' | i18n}}</button>
|
||||
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
|
||||
<a mat-button color="accent" [disabled]="!data.confirmClose" [mat-dialog-close]="data.publicKey">{{'ok' | i18n}}</a>
|
||||
</mat-dialog-actions>
|
@ -5,5 +5,5 @@
|
||||
</pre>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button mat-dialog-close>{{'close' | i18n}}</button>
|
||||
<a mat-button mat-dialog-close>{{'close' | i18n}}</a>
|
||||
</mat-dialog-actions>
|
@ -2,15 +2,16 @@
|
||||
<mat-dialog-content>
|
||||
<form [formGroup]="form">
|
||||
<mat-form-field>
|
||||
<input matInput type="text" min="3" [(ngModel)]="profileField.name" formControlName="name"
|
||||
placeholder="{{'profileField.name' | i18n}}">
|
||||
<mat-label>{{'profileField.name' | i18n}}</mat-label>
|
||||
<input matInput type="text" min="3" [(ngModel)]="profileField.name" formControlName="name">
|
||||
<mat-error>
|
||||
{{'profileField.error.name' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select [(ngModel)]="profileField.type" formControlName="type" placeholder="{{'profileField.type' | i18n}}">
|
||||
<mat-label>{{'profileField.type' | i18n}}</mat-label>
|
||||
<mat-select [(ngModel)]="profileField.type" formControlName="type">
|
||||
<mat-option *ngFor="let type of types" [value]="type">
|
||||
{{'profileField.type.' + type | i18n}}
|
||||
</mat-option>
|
||||
@ -22,15 +23,15 @@
|
||||
|
||||
<div [ngSwitch]="profileField.type">
|
||||
<mat-form-field *ngSwitchCase="'TEXT'">
|
||||
<input matInput type="text" max="255" [(ngModel)]="profileField.value" formControlName="value"
|
||||
placeholder="{{'profileField.value' | i18n}}">
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<input matInput type="text" max="255" [(ngModel)]="profileField.value" formControlName="value">
|
||||
<mat-error>
|
||||
{{'profileField.error.TEXT' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngSwitchCase="'DATE'">
|
||||
<input matInput [matDatepicker]="datePicker" [(ngModel)]="profileField.value" formControlName="value"
|
||||
placeholder="{{'profileField.value' | i18n}}">
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<input matInput [matDatepicker]="datePicker" [(ngModel)]="profileField.value" formControlName="value">
|
||||
<mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #datePicker></mat-datepicker>
|
||||
<mat-error>
|
||||
@ -38,8 +39,9 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngSwitchCase="'DATETIME'">
|
||||
<input matInput [ngxMatDatetimePicker]="datetimePicker" [(ngModel)]="profileField.value" formControlName="value"
|
||||
placeholder="{{'profileField.value' | i18n}}">
|
||||
<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>
|
||||
<mat-error>
|
||||
@ -47,15 +49,15 @@
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngSwitchCase="'URL'">
|
||||
<input matInput type="url" [(ngModel)]="profileField.value" formControlName="value"
|
||||
placeholder="{{'profileField.value' | i18n}}">
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<input matInput type="url" [(ngModel)]="profileField.value" formControlName="value">
|
||||
<mat-error>
|
||||
{{'profileField.error.URL' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngSwitchCase="'EMAIL'">
|
||||
<input matInput type="email" [(ngModel)]="profileField.value" formControlName="value"
|
||||
placeholder="{{'profileField.value' | i18n}}">
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<input matInput type="email" [(ngModel)]="profileField.value" formControlName="value">
|
||||
<mat-error>
|
||||
{{'profileField.error.EMAIL' | i18n}}
|
||||
</mat-error>
|
||||
@ -65,16 +67,16 @@
|
||||
{{'profileField.value' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
<mat-form-field *ngSwitchCase="'NUMBER'">
|
||||
<input matInput type="number" [(ngModel)]="profileField.value" formControlName="value"
|
||||
placeholder="{{'profileField.value' | i18n}}">
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="profileField.value" formControlName="value">
|
||||
<mat-error>
|
||||
{{'profileField.error.NUMBER' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<div *ngSwitchCase="'BLOB'">
|
||||
<mat-form-field>
|
||||
<textarea matInput [(ngModel)]="profileField.blob" formControlName="blob"
|
||||
placeholder="{{'profileField.value' | i18n}}"></textarea>
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<textarea matInput [(ngModel)]="profileField.blob" formControlName="blob"></textarea>
|
||||
<mat-error>
|
||||
{{'profileField.error.BLOB' | i18n}}
|
||||
</mat-error>
|
||||
@ -85,8 +87,8 @@
|
||||
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select [(ngModel)]="profileField.visibility" formControlName="visibility"
|
||||
placeholder="{{'visibility' | i18n}}">
|
||||
<mat-label>{{'visibility' | i18n}}</mat-label>
|
||||
<mat-select [(ngModel)]="profileField.visibility" formControlName="visibility">
|
||||
<mat-option *ngFor="let visibility of visibilities" [value]="visibility">
|
||||
<mat-icon inline="true">{{'visibility.' + visibility + '.icon' | i18n}}</mat-icon> {{'visibility.' +
|
||||
visibility | i18n}}
|
||||
@ -104,8 +106,8 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput type="number" min="0" [(ngModel)]="profileField.index" formControlName="index"
|
||||
placeholder="{{'profileField.index' | i18n}}">
|
||||
<input matInput type="number" min="0" [(ngModel)]="profileField.index" formControlName="index">
|
||||
<mat-label>{{'profileField.index' | i18n}}</mat-label>
|
||||
<mat-error>
|
||||
{{'profileField.error.index' | i18n}}
|
||||
</mat-error>
|
||||
@ -113,7 +115,7 @@
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button (click)="save(profileField)" color="accent">{{'save' |
|
||||
i18n}}</button>
|
||||
<a mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</a>
|
||||
<a [disabled]="form.invalid" mat-raised-button (click)="save(profileField)" color="accent">{{'save' |
|
||||
i18n}}</a>
|
||||
</mat-dialog-actions>
|
@ -16,7 +16,7 @@
|
||||
<a *ngSwitchCase="'URL'" class="accent" href="{{profileField.value}}">{{profileField.value}}</a>
|
||||
<a *ngSwitchCase="'EMAIL'" class="accent" href="mailto:{{profileField.value}}">{{profileField.value}}</a>
|
||||
<span *ngSwitchCase="'NUMBER'">{{profileField.value}}</span>
|
||||
<button *ngSwitchCase="'BLOB'" mat-raised-button (click)="openBlob(profileField)">{{'profileField.openBlob' | i18n}}</button>
|
||||
<a *ngSwitchCase="'BLOB'" mat-raised-button (click)="openBlob(profileField)">{{'profileField.openBlob' | i18n}}</a>
|
||||
<mat-slide-toggle *ngSwitchCase="'BOOL'" [checked]="profileField.value == 'true'" disabled>
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
@ -34,8 +34,8 @@
|
||||
<ng-container matColumnDef="edit" *ngIf="edit">
|
||||
<th mat-header-cell *matHeaderCellDef class="text-right"> {{'profileField.edit' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let profileField" class="text-right">
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="openEdit(profileField)">edit</mat-icon>
|
||||
<a mat-icon-button (click)="openEdit(profileField)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -43,8 +43,8 @@
|
||||
<ng-container matColumnDef="delete" *ngIf="edit">
|
||||
<th mat-header-cell *matHeaderCellDef class="align-right"> {{'profileField.delete' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let profileField" class="text-right">
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="confirmDelete(profileField)">delete</mat-icon>
|
||||
<a mat-icon-button (click)="confirmDelete(profileField)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
@ -54,6 +54,6 @@
|
||||
</table>
|
||||
<br>
|
||||
<div *ngIf="edit" class="text-center">
|
||||
<button mat-raised-button color="primary" (click)="openCreate()">{{'profileField.create' |
|
||||
i18n}}</button>
|
||||
<a mat-raised-button color="primary" (click)="openCreate()">{{'profileField.create' |
|
||||
i18n}}</a>
|
||||
</div>
|
@ -1,16 +1,3 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-header-cell,
|
||||
.mat-cell {
|
||||
&.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.align-right {
|
||||
display: flex;
|
||||
padding: 21px 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="name"> {{'quotas.name' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let quota">
|
||||
<mat-icon inline=true>{{'services.' + quota.name + '.icon' | i18n}}</mat-icon>
|
||||
<mat-icon inline="true">{{'services.' + quota.name + '.icon' | i18n}}</mat-icon>
|
||||
{{'services.' + quota.name + '.title' | i18n}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
@ -1,10 +1,12 @@
|
||||
<div fxLayout="row wrap" fxLayoutGap="24px grid">
|
||||
<div fxFlex="33%" fxFlex.sm="50%" fxFlex.xs="100%" *ngFor="let service of services">
|
||||
<div class="service-grid" fxLayoutGap="24px grid">
|
||||
<div *ngFor="let service of services">
|
||||
<mat-card>
|
||||
<a *ngIf="service.url" href="{{service.url}}" [target]="service.sameSite ? '_self' : '_blank'"
|
||||
color="accent">
|
||||
<mat-card-header>
|
||||
<mat-icon mat-card-avatar>{{'services.' + service.name + '.icon' | i18n}}</mat-icon>
|
||||
<div class="icon" mat-card-avatar>
|
||||
<mat-icon>{{'services.' + service.name + '.icon' | i18n}}</mat-icon>
|
||||
</div>
|
||||
<mat-card-title> <strong>{{'services.' + service.name + '.title' | i18n}}</strong>
|
||||
<mat-icon *ngIf="!service.sameSite" inline="true">
|
||||
open_in_new</mat-icon>
|
||||
@ -14,7 +16,9 @@
|
||||
</a>
|
||||
|
||||
<mat-card-header *ngIf="!service.url">
|
||||
<mat-icon mat-card-avatar>{{'services.' + service.name + '.icon' | i18n}}</mat-icon>
|
||||
<div class="icon" mat-card-avatar>
|
||||
<mat-icon>{{'services.' + service.name + '.icon' | i18n}}</mat-icon>
|
||||
</div>
|
||||
<mat-card-title> <strong>{{'services.' + service.name + '.title' | i18n}}</strong>
|
||||
</mat-card-title>
|
||||
<mat-card-subtitle>{{'services.' + service.name + '.subtitle' | i18n}}</mat-card-subtitle>
|
||||
|
@ -1,6 +1,24 @@
|
||||
@import '../../../variables.scss';
|
||||
|
||||
mat-card {
|
||||
.service-grid {
|
||||
|
||||
display: grid;
|
||||
column-gap: 24px;
|
||||
row-gap: 24px;
|
||||
|
||||
@media (min-width: 576px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
}
|
||||
|
||||
mat-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
@ -14,9 +32,19 @@ mat-card {
|
||||
}
|
||||
}
|
||||
|
||||
mat-card-header {
|
||||
.icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
mat-card-content {
|
||||
flex-grow: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Custom Theming for Angular Material
|
||||
@use '@angular/material'as mat;
|
||||
@use '@angular/material' as mat;
|
||||
// For more information: https://material.angular.io/guide/theming
|
||||
// Plus imports for other components in your app.
|
||||
|
||||
@ -83,6 +83,14 @@ body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
app-root,
|
||||
app-main {
|
||||
height: 100%;
|
||||
@ -107,6 +115,12 @@ app-main {
|
||||
mat-card {
|
||||
max-width: 400px;
|
||||
margin: 2em auto;
|
||||
|
||||
mat-card-actions {
|
||||
&>* {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
@ -156,6 +170,31 @@ qr-code canvas {
|
||||
max-width: 400px !important;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
|
||||
&.wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&.column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&.justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&.justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&.align-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
@ -182,33 +221,33 @@ mat-sidenav-container {
|
||||
margin-left: auto;
|
||||
margin-bottom: 15px;
|
||||
|
||||
@media screen and (min-width: 576px) {
|
||||
@media (min-width: 576px) {
|
||||
width: 540px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
@media (min-width: 768px) {
|
||||
width: 580px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 992px) {
|
||||
@media (min-width: 992px) {
|
||||
width: 820px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1200px) {
|
||||
@media (min-width: 1200px) {
|
||||
width: 1000px;
|
||||
}
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.text-justify {
|
||||
text-align: justify;
|
||||
text-align: justify !important;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
@ -217,7 +256,7 @@ mat-sidenav-container {
|
||||
|
||||
.align-right {
|
||||
display: flex;
|
||||
padding: 21px 0;
|
||||
padding: 21px !important;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@ -322,11 +361,16 @@ table {
|
||||
}
|
||||
}
|
||||
|
||||
.help-button {
|
||||
float: right;
|
||||
mat-card-footer,
|
||||
footer {
|
||||
position: relative;
|
||||
|
||||
.help-button {
|
||||
float: right;
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
mat-card.success {
|
||||
|
@ -10,10 +10,10 @@
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "es2015",
|
||||
"module": "es2020",
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"lib": [
|
||||
"es2018",
|
||||
"ES2022",
|
||||
"dom"
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user