update
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<h1 mat-dialog-title></h1>
|
||||
<mat-dialog-content>
|
||||
<pre>
|
||||
{{profileField.blob}}
|
||||
</pre>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button mat-dialog-close>{{'close' | i18n}}</button>
|
||||
</mat-dialog-actions>
|
||||
@@ -0,0 +1,3 @@
|
||||
mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<h1 mat-dialog-title></h1>
|
||||
<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-form-field>
|
||||
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select [(ngModel)]="profileField.type" formControlName="type" placeholder="{{'profileField.type' | i18n}}">
|
||||
<mat-option *ngFor="let type of types" [value]="type">
|
||||
{{'profileField.type.' + type | i18n}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<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-form-field>
|
||||
<mat-form-field *ngSwitchCase="'DATE'">
|
||||
<input matInput [matDatepicker]="picker" [(ngModel)]="profileField.value" formControlName="value"
|
||||
placeholder="{{'profileField.value' | i18n}}">
|
||||
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #picker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngSwitchCase="'URL'">
|
||||
<input matInput type="url" [(ngModel)]="profileField.value" formControlName="value"
|
||||
placeholder="{{'profileField.value' | i18n}}">
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngSwitchCase="'EMAIL'">
|
||||
<input matInput type="email" [(ngModel)]="profileField.value" formControlName="value"
|
||||
placeholder="{{'profileField.value' | i18n}}">
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngSwitchCase="'NUMBER'">
|
||||
<input matInput type="number" [(ngModel)]="profileField.value" formControlName="value"
|
||||
placeholder="{{'profileField.value' | i18n}}">
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngSwitchCase="'BLOB'">
|
||||
<textarea matInput [(ngModel)]="profileField.blob" formControlName="blob"
|
||||
placeholder="{{'profileField.value' | i18n}}"></textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select [(ngModel)]="profileField.visibility" formControlName="visibility"
|
||||
placeholder="{{'profileField.visibility' | i18n}}">
|
||||
<mat-option *ngFor="let visibility of visibilities" [value]="visibility">
|
||||
{{'profileField.visibility.' + visibility | i18n}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput type="number" min="0" [(ngModel)]="profileField.index" formControlName="index"
|
||||
placeholder="{{'profileField.index' | i18n}}">
|
||||
</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 [mat-dialog-close]="profileField" color="accent">{{'save' | i18n}}</button>
|
||||
</mat-dialog-actions>
|
||||
@@ -0,0 +1,3 @@
|
||||
mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<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 | i18n}} </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 | date:datetimeformat}}</span>
|
||||
<a *ngSwitchCase="'URL'" href="{{profileField.value}}">{{profileField.value}}</a>
|
||||
<a *ngSwitchCase="'EMAIL'" 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>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="visibility" *ngIf="edit">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="visibility"> {{'profileField.visibility' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let profileField"> {{'profileField.visibility.' + profileField.visibility | i18n}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="edit" *ngIf="edit">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'profileField.edit' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let profileField">
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="openEdit(profileField)">edit</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="delete" *ngIf="edit">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'profileField.delete' | i18n}} </th>
|
||||
<td mat-cell *matCellDef="let profileField">
|
||||
<a mat-icon-button>
|
||||
<mat-icon (click)="confirmDelete(profileField)">delete</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="profileFieldColumns"></tr>
|
||||
<tr mat-row *matRowDef="let myRowData; columns: profileFieldColumns"></tr>
|
||||
</table>
|
||||
<br>
|
||||
<div *ngIf="edit" class="text-center">
|
||||
<button mat-raised-button color="primary" (click)="openCreate()">{{'profileField.create' |
|
||||
i18n}}</button>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {ProfileFieldsComponent} from './profilefields.component';
|
||||
|
||||
describe('ProfileFieldsComponent', () => {
|
||||
let component: ProfileFieldsComponent;
|
||||
let fixture: ComponentFixture<ProfileFieldsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ProfileFieldsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ProfileFieldsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,159 @@
|
||||
import {Component, OnInit, Inject, Input} from '@angular/core';
|
||||
import {Sort} from '@angular/material/sort';
|
||||
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
|
||||
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
|
||||
import {I18nService} from '../../services/i18n.service';
|
||||
import {ProfileService} from '../../services/profile.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-profilefields',
|
||||
templateUrl: './profilefields.component.html',
|
||||
styleUrls: ['./profilefields.component.scss']
|
||||
})
|
||||
export class ProfileFieldsComponent implements OnInit {
|
||||
|
||||
@Input() profileFields: Array<any>;
|
||||
@Input() edit;
|
||||
profileFieldColumns = ["name", "value"];
|
||||
|
||||
constructor(private i18n: I18nService, private profileService: ProfileService, public dialog: MatDialog) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
if(this.edit) {
|
||||
this.profileFieldColumns.push("visibility");
|
||||
this.profileFieldColumns.push("edit");
|
||||
this.profileFieldColumns.push("delete");
|
||||
}
|
||||
}
|
||||
|
||||
sortData(sort: Sort) {
|
||||
const data = this.profileFields.slice();
|
||||
if(!sort.active || sort.direction === '') {
|
||||
this.profileFields = data;
|
||||
return;
|
||||
}
|
||||
|
||||
this.profileFields = data.sort((a, b) => {
|
||||
const isAsc = sort.direction === 'asc';
|
||||
switch(sort.active) {
|
||||
case 'name': return this.compare(this.i18n.get('profileField.name.' + a.name, []), this.i18n.get('profileField.name.' + b.name, []), isAsc);
|
||||
case 'value': return this.compare(a.value, b.value, isAsc);
|
||||
case 'index': return this.compare(a.index, b.index, isAsc);
|
||||
default: return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
compare(a: number | string | String, b: number | string | String, isAsc: boolean) {
|
||||
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
|
||||
}
|
||||
|
||||
|
||||
openEdit(profileField) {
|
||||
|
||||
const resetProfileField = JSON.parse(JSON.stringify(profileField));
|
||||
|
||||
const dialogRef = this.dialog.open(ProfileFieldDialog, {
|
||||
data: profileField,
|
||||
minWidth : '400px'
|
||||
});
|
||||
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if(result) {
|
||||
this.profileService.createOrUpdate(result).subscribe();
|
||||
} else {
|
||||
profileField.name = resetProfileField.name;
|
||||
profileField.value = resetProfileField.value;
|
||||
profileField.type = resetProfileField.type;
|
||||
profileField.visibility = resetProfileField.visibility;
|
||||
profileField.index = resetProfileField.index;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
confirmDelete(profileField) {
|
||||
this.profileService.delete(profileField.name).subscribe((result: any) => {
|
||||
this.profileFields.splice(this.profileFields.indexOf(profileField), 1);
|
||||
this.profileFields = [...this.profileFields];
|
||||
})
|
||||
}
|
||||
|
||||
openCreate() {
|
||||
const dialogRef = this.dialog.open(ProfileFieldDialog, {
|
||||
data: {"type": "TEXT", "visibility": "PRIVATE"},
|
||||
minWidth : '400px'
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if(result) {
|
||||
this.profileService.createOrUpdate(result).subscribe((result: any) => {
|
||||
this.profileFields.push(result);
|
||||
this.profileFields = [...this.profileFields];
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
openBlob(profileField) {
|
||||
this.dialog.open(ProfileFieldBlob, {
|
||||
data: profileField,
|
||||
minWidth : '400px'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-profilefield-dialog',
|
||||
templateUrl: 'profilefield.dialog.html',
|
||||
styleUrls: ['./profilefield.dialog.scss']
|
||||
})
|
||||
export class ProfileFieldDialog {
|
||||
|
||||
form: FormGroup;
|
||||
profileField;
|
||||
|
||||
types = ["TEXT", "NUMBER", "DATE", "URL", "EMAIL", "BOOL", "BLOB"];
|
||||
visibilities = ["PRIVATE", "PROTECTED", "PUBLIC"];
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
public dialogRef: MatDialogRef<ProfileFieldDialog>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any) {
|
||||
this.profileField = data;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.form = this.formBuilder.group({
|
||||
name: ['', Validators.required],
|
||||
type: ['', Validators.required],
|
||||
value: [''],
|
||||
blob: [''],
|
||||
visibility: ['', Validators.required],
|
||||
index: ['']
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-profilefield-blob',
|
||||
templateUrl: 'profilefield.blob.html',
|
||||
styleUrls: ['./profilefield.blob.scss']
|
||||
})
|
||||
export class ProfileFieldBlob {
|
||||
|
||||
profileField;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<ProfileFieldDialog>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any) {
|
||||
this.profileField = data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user