upgrade and migrate to angular 20
This commit is contained in:
@@ -2,12 +2,16 @@
|
||||
|
||||
|
||||
<mat-select [(ngModel)]="unit">
|
||||
<mat-option *ngFor="let item of dividerModel.units" [value]="item">{{item.name}}</mat-option>
|
||||
@for (item of dividerModel.units; track item) {
|
||||
<mat-option [value]="item">{{item.name}}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
|
||||
<div *ngFor="let item of dividerModel.items">
|
||||
@for (item of dividerModel.items; track item) {
|
||||
<div>
|
||||
<label>{{item.name}}: {{toCurrentUnit(item.value)}}{{unit.name}}</label>
|
||||
<mat-slider [max]="toCurrentUnit(dividerModel.free + item.value)" min=0 [step]="unit.steps" [value]="toCurrentUnit(item.value)" thumbLabel
|
||||
tickInterval="5" (change)="updateValue($event, item)">
|
||||
tickInterval="5" (change)="updateValue($event, item)">
|
||||
</mat-slider>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -14,21 +14,33 @@
|
||||
<mat-icon>arrow_drop_down</mat-icon>
|
||||
</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 *ngIf="locale == currentLocale">done</mat-icon></a>
|
||||
@if (!auth || auth && !auth.authenticated) {
|
||||
<a routerLink="/login" routerLinkActive="active" mat-menu-item>
|
||||
<mat-icon>login</mat-icon> {{'login' | i18n}}
|
||||
</a>
|
||||
}
|
||||
@if (!auth || auth && !auth.authenticated) {
|
||||
<mat-divider></mat-divider>
|
||||
}
|
||||
@for (locale of locales; track locale) {
|
||||
<a mat-menu-item (click)="setLocale(locale)">{{'locale.' + locale + '.long' |
|
||||
i18n}} @if (locale == currentLocale) {
|
||||
<mat-icon>done</mat-icon>
|
||||
}</a>
|
||||
}
|
||||
<a mat-menu-item>
|
||||
<mat-slide-toggle (change)="darkThemeChange($event)" [checked]="darkTheme == 'true'">
|
||||
{{'profileField.name.darkTheme' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
</a>
|
||||
<mat-divider *ngIf="auth && auth.authenticated"></mat-divider>
|
||||
<a *ngIf="auth && auth.authenticated" (click)="logout()" mat-menu-item>
|
||||
<mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}}
|
||||
</a>
|
||||
@if (auth && auth.authenticated) {
|
||||
<mat-divider></mat-divider>
|
||||
}
|
||||
@if (auth && auth.authenticated) {
|
||||
<a (click)="logout()" mat-menu-item>
|
||||
<mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}}
|
||||
</a>
|
||||
}
|
||||
</mat-menu>
|
||||
</ng-container>
|
||||
</mat-toolbar>
|
||||
@@ -37,50 +49,58 @@
|
||||
<mat-sidenav #sidenav [mode]="isBiggerScreen() ? 'side' : 'over'" [(opened)]="opened"
|
||||
(click)="!isBiggerScreen() && opened=false">
|
||||
<mat-nav-list>
|
||||
<a *ngIf="!auth || auth && !auth.authenticated" routerLink="/login" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>login</mat-icon> {{'login' | i18n}}
|
||||
</a>
|
||||
<a *ngIf="auth && auth.authenticated" routerLink="/account/info" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>account_circle</mat-icon> {{'account' | i18n}}
|
||||
</a>
|
||||
<a *ngIf="auth && auth.authenticated" routerLink="/services" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>widgets</mat-icon> {{'services' | i18n}}
|
||||
</a>
|
||||
@if (!auth || auth && !auth.authenticated) {
|
||||
<a routerLink="/login" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>login</mat-icon> {{'login' | i18n}}
|
||||
</a>
|
||||
}
|
||||
@if (auth && auth.authenticated) {
|
||||
<a routerLink="/account/info" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>account_circle</mat-icon> {{'account' | i18n}}
|
||||
</a>
|
||||
}
|
||||
@if (auth && auth.authenticated) {
|
||||
<a routerLink="/services" routerLinkActive="active" mat-list-item>
|
||||
<mat-icon>widgets</mat-icon> {{'services' | i18n}}
|
||||
</a>
|
||||
}
|
||||
<a routerLink="/tokens" mat-list-item>
|
||||
<mat-icon>card_giftcard</mat-icon> {{'tokens.redeem' | i18n}}
|
||||
</a>
|
||||
<a (click)="openExternal('https://wiki.bstly.de/services/webstly','_blank')" mat-list-item>
|
||||
<mat-icon>help</mat-icon> {{'help' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
|
||||
</mat-icon>
|
||||
</a>
|
||||
<a (click)="openExternal('https://membership.bstly.de','_blank')" mat-list-item>
|
||||
<mat-icon>shopping_cart</mat-icon> {{'tokens.get' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
|
||||
</mat-icon>
|
||||
</a>
|
||||
<a *ngIf="auth && auth.authenticated" (click)="logout()" mat-list-item>
|
||||
<mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}}
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
</mat-icon>
|
||||
</a>
|
||||
<a (click)="openExternal('https://membership.bstly.de','_blank')" mat-list-item>
|
||||
<mat-icon>shopping_cart</mat-icon> {{'tokens.get' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
|
||||
</mat-icon>
|
||||
</a>
|
||||
@if (auth && auth.authenticated) {
|
||||
<a (click)="logout()" mat-list-item>
|
||||
<mat-icon>exit_to_app</mat-icon> {{'logout' | i18n}}
|
||||
</a>
|
||||
}
|
||||
</mat-nav-list>
|
||||
|
||||
<span class="spacer"></span>
|
||||
<span class="spacer"></span>
|
||||
|
||||
<mat-nav-list>
|
||||
<a (click)="openExternal('https://www.bstly.de/imprint/')" mat-list-item style="font-size: 0.7em;">
|
||||
{{'imprint' | i18n}}
|
||||
</a>
|
||||
<a (click)="openExternal('https://www.bstly.de/privacy-policy/#we.bstly')" mat-list-item style="font-size: 0.7em;">
|
||||
{{'privacy-policy' | i18n}}
|
||||
</a>
|
||||
<a (click)="openExternal('https://www.bstly.de')" mat-list-item style="font-size: 0.7em;">
|
||||
Bastelei e. V.
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
</mat-sidenav>
|
||||
<mat-nav-list>
|
||||
<a (click)="openExternal('https://www.bstly.de/imprint/')" mat-list-item style="font-size: 0.7em;">
|
||||
{{'imprint' | i18n}}
|
||||
</a>
|
||||
<a (click)="openExternal('https://www.bstly.de/privacy-policy/#we.bstly')" mat-list-item style="font-size: 0.7em;">
|
||||
{{'privacy-policy' | i18n}}
|
||||
</a>
|
||||
<a (click)="openExternal('https://www.bstly.de')" mat-list-item style="font-size: 0.7em;">
|
||||
Bastelei e. V.
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
</mat-sidenav>
|
||||
|
||||
<!-- Main content -->
|
||||
<mat-sidenav-content>
|
||||
<div class="container">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</mat-sidenav-content>
|
||||
<!-- Main content -->
|
||||
<mat-sidenav-content>
|
||||
<div class="container">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
@@ -5,23 +5,25 @@
|
||||
<td mat-cell *matCellDef="let permission">
|
||||
<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>
|
||||
@if (permission.addon) {
|
||||
<mat-icon inline="true">add_circle</mat-icon>
|
||||
}
|
||||
<br>
|
||||
<small>{{'services.' + permission.name + '.subtitle' | i18n}}</small>
|
||||
</td>
|
||||
</ng-container>
|
||||
<small>{{'services.' + permission.name + '.subtitle' | i18n}}</small>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="starts">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="starts"> {{'permissions.starts' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let permission">{{ startsVisible ? (permission.starts | datef:datetimeformat) : '-'}}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="starts">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="starts"> {{'permissions.starts' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let permission">{{ startsVisible ? (permission.starts | datef:datetimeformat) : '-'}}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="expires">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="expires"> {{'permissions.expires' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let permission">{{ expiresVisible ? (permission.expires | datef:datetimeformat) : '-'}}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="expires">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="expires"> {{'permissions.expires' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let permission">{{ expiresVisible ? (permission.expires | datef:datetimeformat) : '-'}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="permissionColumns"></tr>
|
||||
<tr mat-row *matRowDef="let myRowData; columns: permissionColumns"></tr>
|
||||
</table>
|
||||
<tr mat-header-row *matHeaderRowDef="permissionColumns"></tr>
|
||||
<tr mat-row *matRowDef="let myRowData; columns: permissionColumns"></tr>
|
||||
</table>
|
||||
@@ -12,84 +12,106 @@
|
||||
<mat-form-field>
|
||||
<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>
|
||||
@for (type of types; track type) {
|
||||
<mat-option [value]="type">
|
||||
{{'profileField.type.' + type | i18n}}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
{{'profileField.error.type' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<div [ngSwitch]="profileField.type">
|
||||
<mat-form-field *ngSwitchCase="'TEXT'">
|
||||
<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'">
|
||||
<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>
|
||||
{{'profileField.error.DATE' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngSwitchCase="'DATETIME'">
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<input matInput type="datetime-local" [(ngModel)]="profileField.value" formControlName="value">
|
||||
<mat-error>
|
||||
{{'profileField.error.DATETIME' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngSwitchCase="'URL'">
|
||||
<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'">
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<input matInput type="email" [(ngModel)]="profileField.value" formControlName="value">
|
||||
<mat-error>
|
||||
{{'profileField.error.EMAIL' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-slide-toggle *ngSwitchCase="'BOOL'" (change)="booleanChange(profileField)"
|
||||
[checked]="profileField.value == 'true'">
|
||||
{{'profileField.value' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
<mat-form-field *ngSwitchCase="'NUMBER'">
|
||||
<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>
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<textarea matInput [(ngModel)]="profileField.blob" formControlName="blob"></textarea>
|
||||
<mat-error>
|
||||
{{'profileField.error.BLOB' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<a mat-button (click)="pgpBlob(profileField)">{{'profileField.blob.pgp' | i18n}}</a>
|
||||
</div>
|
||||
<div>
|
||||
@switch (profileField.type) {
|
||||
@case ('TEXT') {
|
||||
<mat-form-field>
|
||||
<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>
|
||||
}
|
||||
@case ('DATE') {
|
||||
<mat-form-field>
|
||||
<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>
|
||||
{{'profileField.error.DATE' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
}
|
||||
@case ('DATETIME') {
|
||||
<mat-form-field>
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<input matInput type="datetime-local" [(ngModel)]="profileField.value" formControlName="value">
|
||||
<mat-error>
|
||||
{{'profileField.error.DATETIME' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
}
|
||||
@case ('URL') {
|
||||
<mat-form-field>
|
||||
<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>
|
||||
}
|
||||
@case ('EMAIL') {
|
||||
<mat-form-field>
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<input matInput type="email" [(ngModel)]="profileField.value" formControlName="value">
|
||||
<mat-error>
|
||||
{{'profileField.error.EMAIL' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
}
|
||||
@case ('BOOL') {
|
||||
<mat-slide-toggle (change)="booleanChange(profileField)"
|
||||
[checked]="profileField.value == 'true'">
|
||||
{{'profileField.value' | i18n}}
|
||||
</mat-slide-toggle>
|
||||
}
|
||||
@case ('NUMBER') {
|
||||
<mat-form-field>
|
||||
<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>
|
||||
}
|
||||
@case ('BLOB') {
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<mat-label>{{'profileField.value' | i18n}}</mat-label>
|
||||
<textarea matInput [(ngModel)]="profileField.blob" formControlName="blob"></textarea>
|
||||
<mat-error>
|
||||
{{'profileField.error.BLOB' | i18n}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<a mat-button (click)="pgpBlob(profileField)">{{'profileField.blob.pgp' | i18n}}</a>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
<mat-form-field>
|
||||
<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}}
|
||||
</mat-option>
|
||||
@for (visibility of visibilities; track visibility) {
|
||||
<mat-option [value]="visibility">
|
||||
<mat-icon inline="true">{{'visibility.' + visibility + '.icon' | i18n}}</mat-icon> {{'visibility.' +
|
||||
visibility | i18n}}
|
||||
</mat-option>
|
||||
}
|
||||
|
||||
<mat-select-trigger>
|
||||
<mat-icon inline="true">{{'visibility.' + profileField.visibility + '.icon' | i18n}}</mat-icon>
|
||||
@@ -114,5 +136,5 @@
|
||||
<mat-dialog-actions>
|
||||
<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>
|
||||
i18n}}</a>
|
||||
</mat-dialog-actions>
|
||||
@@ -1,59 +1,87 @@
|
||||
<table mat-table matSort [dataSource]="profileFields" (matSortChange)="sortData($event)" matSortActive="index" matSortDirection="asc">
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="name"> {{'profileField.name' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let profileField"> {{'profileField.name.' + profileField.name | i18nEmpty}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="name"> {{'profileField.name' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let profileField"> {{'profileField.name.' + profileField.name | i18nEmpty}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="value">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="value"> {{'profileField.value' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let profileField">
|
||||
<div [ngSwitch]="profileField.type">
|
||||
<span *ngSwitchCase="'TEXT'">{{profileField.value}}</span>
|
||||
<span *ngSwitchCase="'DATE'">{{profileField.value | datef:dateformat}}</span>
|
||||
<span *ngSwitchCase="'DATETIME'">{{profileField.value | datef:datetimeformat}}</span>
|
||||
<span *ngSwitchCase="'TIME'">{{profileField.value | datef:timeformat}}</span>
|
||||
<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>
|
||||
<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>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="value">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="value"> {{'profileField.value' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let profileField">
|
||||
<div>
|
||||
@switch (profileField.type) {
|
||||
@case ('TEXT') {
|
||||
<span>{{profileField.value}}</span>
|
||||
}
|
||||
@case ('DATE') {
|
||||
<span>{{profileField.value | datef:dateformat}}</span>
|
||||
}
|
||||
@case ('DATETIME') {
|
||||
<span>{{profileField.value | datef:datetimeformat}}</span>
|
||||
}
|
||||
@case ('TIME') {
|
||||
<span>{{profileField.value | datef:timeformat}}</span>
|
||||
}
|
||||
@case ('URL') {
|
||||
<a class="accent" href="{{profileField.value}}">{{profileField.value}}</a>
|
||||
}
|
||||
@case ('EMAIL') {
|
||||
<a class="accent" href="mailto:{{profileField.value}}">{{profileField.value}}</a>
|
||||
}
|
||||
@case ('NUMBER') {
|
||||
<span>{{profileField.value}}</span>
|
||||
}
|
||||
@case ('BLOB') {
|
||||
<a mat-raised-button (click)="openBlob(profileField)">{{'profileField.openBlob' | i18n}}</a>
|
||||
}
|
||||
@case ('BOOL') {
|
||||
<mat-slide-toggle [checked]="profileField.value == 'true'" disabled>
|
||||
</mat-slide-toggle>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="visibility" *ngIf="edit">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="visibility"> {{'visibility' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let profileField">
|
||||
<mat-icon inline="true">{{'visibility.' + profileField.visibility + '.icon' | i18n}}</mat-icon>
|
||||
{{'visibility.' + profileField.visibility | i18n}}
|
||||
</td>
|
||||
@if (edit) {
|
||||
<ng-container matColumnDef="visibility">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="visibility"> {{'visibility' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let profileField">
|
||||
<mat-icon inline="true">{{'visibility.' + profileField.visibility + '.icon' | i18n}}</mat-icon>
|
||||
{{'visibility.' + profileField.visibility | i18n}}
|
||||
</td>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<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 (click)="openEdit(profileField)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
@if (edit) {
|
||||
<ng-container matColumnDef="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 (click)="openEdit(profileField)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<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 (click)="confirmDelete(profileField)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
@if (edit) {
|
||||
<ng-container matColumnDef="delete">
|
||||
<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 (click)="confirmDelete(profileField)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="profileFieldColumns"></tr>
|
||||
<tr mat-row *matRowDef="let myRowData; columns: profileFieldColumns"></tr>
|
||||
<tr mat-header-row *matHeaderRowDef="profileFieldColumns"></tr>
|
||||
<tr mat-row *matRowDef="let myRowData; columns: profileFieldColumns"></tr>
|
||||
</table>
|
||||
<br>
|
||||
<div *ngIf="edit" class="text-center">
|
||||
<a mat-raised-button color="primary" (click)="openCreate()">{{'profileField.create' |
|
||||
i18n}}</a>
|
||||
</div>
|
||||
@if (edit) {
|
||||
<div class="text-center">
|
||||
<a mat-raised-button color="primary" (click)="openCreate()">{{'profileField.create' |
|
||||
i18n}}</a>
|
||||
</div>
|
||||
}
|
||||
@@ -10,24 +10,32 @@
|
||||
|
||||
<ng-container matColumnDef="value">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="value"> {{'quotas.value' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let quota"><span *ngIf="quota.disposable">{{quota.value}}</span> </td>
|
||||
<td mat-cell *matCellDef="let quota">@if (quota.disposable) {
|
||||
<span>{{quota.value}}</span>
|
||||
} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="fixed_value">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'quotas.fixed_value' | i18n}} <mat-icon #primaryHint="matTooltip" inline
|
||||
matTooltip="{{'quotas.fixed_value.hint' | i18n}}">info</mat-icon>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let quota"><span *ngIf="!quota.disposable">{{quota.value}}</span> </td>
|
||||
</ng-container>
|
||||
matTooltip="{{'quotas.fixed_value.hint' | i18n}}">info</mat-icon>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let quota">@if (!quota.disposable) {
|
||||
<span>{{quota.value}}</span>
|
||||
} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="quotaUnit">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'quotas.unit' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let quota">
|
||||
<span *ngIf="quota.unit">{{'quotas.unit.' + quota.unit | i18n}}</span>
|
||||
<span *ngIf="!quota.unit">#</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="quotaUnit">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'quotas.unit' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let quota">
|
||||
@if (quota.unit) {
|
||||
<span>{{'quotas.unit.' + quota.unit | i18n}}</span>
|
||||
}
|
||||
@if (!quota.unit) {
|
||||
<span>#</span>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="quotaColumns"></tr>
|
||||
<tr mat-row *matRowDef="let myRowData; columns: quotaColumns"></tr>
|
||||
<tr mat-header-row *matHeaderRowDef="quotaColumns"></tr>
|
||||
<tr mat-row *matRowDef="let myRowData; columns: quotaColumns"></tr>
|
||||
</table>
|
||||
|
||||
@@ -1,35 +1,42 @@
|
||||
<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>
|
||||
<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>
|
||||
</mat-card-title>
|
||||
<mat-card-subtitle>{{'services.' + service.name + '.subtitle' | i18n}}</mat-card-subtitle>
|
||||
</mat-card-header>
|
||||
</a>
|
||||
|
||||
<mat-card-header *ngIf="!service.url">
|
||||
<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>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<p>
|
||||
{{ 'services.' + service.name + '.text' | i18n}}
|
||||
</p>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</div>
|
||||
@for (service of services; track service) {
|
||||
<div>
|
||||
<mat-card>
|
||||
@if (service.url) {
|
||||
<a href="{{service.url}}" [target]="service.sameSite ? '_self' : '_blank'"
|
||||
color="accent">
|
||||
<mat-card-header>
|
||||
<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>
|
||||
@if (!service.sameSite) {
|
||||
<mat-icon inline="true">
|
||||
open_in_new</mat-icon>
|
||||
}
|
||||
</mat-card-title>
|
||||
<mat-card-subtitle>{{'services.' + service.name + '.subtitle' | i18n}}</mat-card-subtitle>
|
||||
</mat-card-header>
|
||||
</a>
|
||||
}
|
||||
@if (!service.url) {
|
||||
<mat-card-header>
|
||||
<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>
|
||||
</mat-card-header>
|
||||
}
|
||||
<mat-card-content>
|
||||
<p>
|
||||
{{ 'services.' + service.name + '.text' | i18n}}
|
||||
</p>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -1,4 +1,4 @@
|
||||
@import '../../../variables.scss';
|
||||
@use '../../../variables.scss' as vars;
|
||||
|
||||
.service-grid {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
color: inherit;
|
||||
|
||||
mat-card-title {
|
||||
color: $accent;
|
||||
color: vars.$accent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,34 +1,38 @@
|
||||
<table *ngIf="services && services.length > 0" mat-table matSort [dataSource]="services"
|
||||
@if (services && services.length > 0) {
|
||||
<table mat-table matSort [dataSource]="services"
|
||||
(matSortChange)="sortData($event)" matSortActive="name" matSortDirection="asc">
|
||||
|
||||
<ng-container matColumnDef="icon">
|
||||
<th mat-header-cell *matHeaderCellDef> </th>
|
||||
<td mat-cell *matCellDef="let service">
|
||||
<mat-icon>{{'services.' + service.name + '.icon' | i18n}}</mat-icon>
|
||||
</td>
|
||||
<th mat-header-cell *matHeaderCellDef> </th>
|
||||
<td mat-cell *matCellDef="let service">
|
||||
<mat-icon>{{'services.' + service.name + '.icon' | i18n}}</mat-icon>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="name"> {{'service.name' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let service" class="text-center">
|
||||
<a *ngIf="service.url" href="{{service.url}}" [target]="service.sameSite ? '_self' : '_blank'" mat-button
|
||||
color="accent">
|
||||
<strong>{{'services.' + service.name + '.title' | i18n}}</strong>
|
||||
<mat-icon *ngIf="!service.sameSite" inline="true">
|
||||
open_in_new</mat-icon>
|
||||
</a>
|
||||
<a *ngIf="!service.url" mat-button disabled>
|
||||
<strong>{{'services.' + service.name + '.title' | i18n}}</strong>
|
||||
</a>
|
||||
<div><small>{{'services.' + service.name + '.subtitle' | i18n}}</small></div>
|
||||
</td>
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="name"> {{'service.name' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let service" class="text-center">
|
||||
@if (service.url) {
|
||||
<a href="{{service.url}}" [target]="service.sameSite ? '_self' : '_blank'" mat-button
|
||||
color="accent">
|
||||
<strong>{{'services.' + service.name + '.title' | i18n}}</strong>
|
||||
@if (!service.sameSite) {
|
||||
<mat-icon inline="true">
|
||||
open_in_new</mat-icon>
|
||||
}
|
||||
</a>
|
||||
}
|
||||
@if (!service.url) {
|
||||
<a mat-button disabled>
|
||||
<strong>{{'services.' + service.name + '.title' | i18n}}</strong>
|
||||
</a>
|
||||
}
|
||||
<div><small>{{'services.' + service.name + '.subtitle' | i18n}}</small></div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="text">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'service.text' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let service">{{ 'services.' + service.name + '.text' | i18n}}</td>
|
||||
<th mat-header-cell *matHeaderCellDef> {{'service.text' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let service">{{ 'services.' + service.name + '.text' | i18n}}</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="serviceColumns"></tr>
|
||||
<tr mat-row *matRowDef="let myRowData; columns: serviceColumns"></tr>
|
||||
</table>
|
||||
</table>
|
||||
}
|
||||
Reference in New Issue
Block a user