- {{'profileField.edit' | i18n}} |
-
+ | {{'profileField.edit' | i18n}} |
+
edit
@@ -39,8 +39,8 @@
- {{'profileField.delete' | i18n}} |
-
+ | {{'profileField.delete' | i18n}} |
+
delete
diff --git a/src/app/ui/profilefields/profilefields.component.scss b/src/app/ui/profilefields/profilefields.component.scss
index ccd3994..d7b0876 100644
--- a/src/app/ui/profilefields/profilefields.component.scss
+++ b/src/app/ui/profilefields/profilefields.component.scss
@@ -1,3 +1,16 @@
table {
- width: 100%;
-}
\ No newline at end of file
+ width: 100%;
+}
+
+.mat-header-cell,
+.mat-cell {
+ &.text-right {
+ text-align: right;
+ }
+}
+
+.align-right {
+ display: flex;
+ padding: 21px 0;
+ justify-content: flex-end;
+}
diff --git a/src/app/ui/profilefields/profilefields.component.ts b/src/app/ui/profilefields/profilefields.component.ts
index 2a3b25b..b8e3d57 100644
--- a/src/app/ui/profilefields/profilefields.component.ts
+++ b/src/app/ui/profilefields/profilefields.component.ts
@@ -2,9 +2,9 @@ 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 {ConfirmDialog} from '../confirm/confirm.component';
import {I18nService} from '../../services/i18n.service';
import {ProfileService} from '../../services/profile.service';
-import {ConfirmDialog} from '../confirm/confirm.component';
@Component({
selector: 'app-profilefields',
@@ -13,9 +13,10 @@ import {ConfirmDialog} from '../confirm/confirm.component';
})
export class ProfileFieldsComponent implements OnInit {
- @Input() profileFields: Array;
+ @Input() username;
@Input() edit;
profileFieldColumns = ["name", "value"];
+ profileFields: Array = [];
constructor(private i18n: I18nService, private profileService: ProfileService, public dialog: MatDialog) {}
@@ -25,6 +26,20 @@ export class ProfileFieldsComponent implements OnInit {
this.profileFieldColumns.push("edit");
this.profileFieldColumns.push("delete");
}
+ this.update();
+ }
+
+
+ update() {
+ if(this.username) {
+ this.profileService.getAllForUser(this.username).subscribe((data: any) => {
+ this.profileFields = data.profileFields;
+ })
+ } else {
+ this.profileService.getAll().subscribe((data: any) => {
+ this.profileFields = data;
+ })
+ }
}
sortData(sort: Sort) {
@@ -40,6 +55,7 @@ export class ProfileFieldsComponent implements OnInit {
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);
+ case 'visibility': return this.compare(this.i18n.get('visibility.' + a.visibility, []), this.i18n.get('visibility.' + b.visibility, []), isAsc);
default: return 0;
}
});
@@ -85,8 +101,7 @@ export class ProfileFieldsComponent implements OnInit {
dialogRef.afterClosed().subscribe(result => {
if(result) {
this.profileService.delete(profileField.name).subscribe((result: any) => {
- this.profileFields.splice(this.profileFields.indexOf(profileField), 1);
- this.profileFields = [...this.profileFields];
+ this.update();
})
}
});
@@ -100,10 +115,7 @@ export class ProfileFieldsComponent implements OnInit {
dialogRef.afterClosed().subscribe(result => {
if(result) {
- this.profileService.createOrUpdate(result).subscribe((result: any) => {
- this.profileFields.push(result);
- this.profileFields = [...this.profileFields];
- });
+ this.update();
}
});
@@ -132,6 +144,7 @@ export class ProfileFieldDialog {
visibilities = ["PRIVATE", "PROTECTED", "PUBLIC"];
constructor(
+ private profileService: ProfileService,
private formBuilder: FormBuilder,
public dialogRef: MatDialogRef,
@Inject(MAT_DIALOG_DATA) public data: any) {
@@ -157,6 +170,25 @@ export class ProfileFieldDialog {
}
}
+
+ save(profileField) {
+ this.profileService.createOrUpdate(profileField).subscribe((result: any) => {
+ this.dialogRef.close(profileField);
+ }, (error) => {
+ if(error.status == 409) {
+ let errors = {};
+ for(let code of error.error) {
+ errors[code.field] = errors[code.field] || {};
+ errors[code.field][code.code] = true;
+ }
+
+ for(let code in errors) {
+ this.form.get(code).setErrors(errors[code]);
+ }
+ }
+ });
+ }
+
}
diff --git a/src/assets/i18n/de-informal.json b/src/assets/i18n/de-informal.json
index a162f86..d66526e 100644
--- a/src/assets/i18n/de-informal.json
+++ b/src/assets/i18n/de-informal.json
@@ -7,7 +7,10 @@
"email": {
".": "E-Mail Adresse",
"invalid": "ungültige E-Mail Adresse",
- "primary": "primäre E-Mail Adresse"
+ "primary": {
+ ".": "primäre E-Mail Adresse",
+ "hint": "Eine primäre E-Mail Adresse dient dazu eine andere Kontaktmöglichkeit als deine we.bstly Adresse anzugeben."
+ }
},
"greet": "Hallo {0}",
"help": "Hilfe",
@@ -91,12 +94,38 @@
"create": "Neues Profilfeld hinzufügen",
"delete": "Löschen",
"edit": "Bearbeiten",
+ "error": {
+ "BLOB": {
+ ".": "Kein gültiger Binärblob"
+ },
+ "BOOL": {
+ ".": "Kein gültiger Boolean"
+ },
+ "DATE": {
+ ".": "Kein gültiges Datum"
+ },
+ "EMAIL": {
+ ".": "Keine gültige E-Mail Adresse"
+ },
+ "name": "Name zu kurz oder ungültig",
+ "NUMBER": {
+ ".": "Keine gültige Nummer"
+ },
+ "TEXT": {
+ ".": "Textfeld zu lang"
+ },
+ "type": "Ungültiger Typ für dieses Profilfeld",
+ "URL": {
+ ".": "Keine gültige URL"
+ },
+ "visibility": "Keine gültige Sichtbarkeit für Profilfeld"
+ },
"index": "Index",
"name": {
".": "Key",
- "darkTheme" : "Dunkles Thema",
+ "darkTheme": "Dunkles Thema",
"email": "E-Mail Adresse",
- "locale" : "Sprache",
+ "locale": "Sprache",
"primaryEmail": "E-Mail Adresse primär verwenden",
"prtyMap": "Partey Karte",
"publicKey": "Öffentlicher PGP Schlüssel"
@@ -126,19 +155,7 @@
".": "URL"
}
},
- "value": "Wert",
- "visibility": {
- ".": "Sichtbarkeit",
- "PRIVATE": {
- ".": "Privat"
- },
- "PROTECTED": {
- ".": "Geschützt"
- },
- "PUBLIC": {
- ".": "Öffentlich"
- }
- }
+ "value": "Wert"
},
"quotas": {
".": "Quotas",
@@ -182,7 +199,7 @@
},
"status": {
".": "Status",
- "change" : "Status aktualisieren",
+ "change": "Status aktualisieren",
"hint": "Dein User Status gibt an, wie mit deinen Account Daten umgegangen wird wenn deine Berechtigungen ausgelaufen sind.",
"NORMAL": {
".": "Normal",
@@ -196,7 +213,7 @@
".": "Schlafen",
"hint": "Dein Account sowie alle gespeicherten Daten werden nicht(!) gelöscht. Du kannst deinen Account also jederzeit wieder reaktivieren."
},
- "success" : "Status erfolgreich geändert"
+ "success": "Status erfolgreich geändert"
}
},
"service-unavailable": {
@@ -207,6 +224,13 @@
},
"services": {
".": "Dienste",
+ "alias_creation": {
+ "icon": "alternate_email",
+ "subtitle": "Anlegen von alternativen Namen",
+ "text": "Du kannst zusätzlich zu deinem Usernamen noch alternative Namen anlegen.",
+ "title": "Alternative Namen"
+ },
+ "empty": "Du hast aktuell keine Berechtigungen zur Nutzung von Diensten.",
"gitea": {
"icon": "code",
"subtitle": "Git-Repositories",
@@ -284,6 +308,17 @@
},
"user": {
".": "User",
+ "aliases": {
+ ".": "Alternative Namen",
+ "alias": "Alternativer Name",
+ "confirmDelete": "Möchtest du wirklich den alternativen Namen '{0}' löschen?",
+ "create": "Alternativen Namen anlegen",
+ "delete": "Löschen",
+ "error": "Dieser alternative Name ist leider nicht zulässig.",
+ "info": "Du kannst hier alternative Namen erstellen. Die Anzahl wird über eine Quota begrenzt.",
+ "left": "Du kannst noch {0} alternative(n) Namen anlegen.",
+ "noQuota": "Deine Quota für alternative Namen ist leider aufgebraucht."
+ },
"unavailable": {
".": "Zugriff verweigert",
"text": "Dieser Benutzer existiert nicht oder du hast keine Berechtigungen, um auf das Profil zuzugreifen."
@@ -294,6 +329,21 @@
"error": "Bitte wähle einen anderen Usernamen aus.",
"missing": "Bitte gebe einen Usernamen an."
},
+ "visibility": {
+ ".": "Sichtbarkeit",
+ "PRIVATE": {
+ ".": "Privat",
+ "icon" : "lock"
+ },
+ "PROTECTED": {
+ ".": "Geschützt",
+ "icon" : "shield"
+ },
+ "PUBLIC": {
+ ".": "Öffentlich",
+ "icon" : "public"
+ }
+ },
"voucher": {
".": "Gutscheincode",
"code": "Code",
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index 8395f44..bcc4310 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -7,7 +7,10 @@
"email": {
".": "Email address",
"invalid": "invalid email address",
- "primary": "primary email address"
+ "primary": {
+ ".": "primary email address",
+ "hint": "A primary email address is used for contact you instead of you we.bstly address."
+ }
},
"greet": "Hello {0}",
"help": "Help",
@@ -91,12 +94,38 @@
"create": "Add new profile field",
"delete": "Delete",
"edit": "Edit",
+ "error": {
+ "BLOB": {
+ ".": "Invalid binary blob"
+ },
+ "BOOL": {
+ ".": "Invalid boolean"
+ },
+ "DATE": {
+ ".": "Invalid date"
+ },
+ "EMAIL": {
+ ".": "Invalid email address"
+ },
+ "name": "name invalid or too short",
+ "NUMBER": {
+ ".": "Invalid numeric"
+ },
+ "TEXT": {
+ ".": "Text too long"
+ },
+ "type": "Invalid type for this profile field",
+ "URL": {
+ ".": "Invalid URL"
+ },
+ "visibility": "Invalid visibility for profile field"
+ },
"index": "Index",
"name": {
".": "Key",
- "darkTheme" : "Dark Theme",
+ "darkTheme": "Dark Theme",
"email": "Email address",
- "locale" : "Locale",
+ "locale": "Locale",
"primaryEmail": "Use email address primary",
"prtyMap": "Partey map",
"publicKey": "Public PGP key"
@@ -126,19 +155,7 @@
".": "URL"
}
},
- "value": "Value",
- "visibility": {
- ".": "Visibility",
- "PRIVATE": {
- ".": "Private"
- },
- "PROTECTED": {
- ".": "Protected"
- },
- "PUBLIC": {
- ".": "Public"
- }
- }
+ "value": "Value"
},
"quotas": {
".": "Quotas",
@@ -182,7 +199,7 @@
},
"status": {
".": "Status",
- "change" : "Change status",
+ "change": "Change status",
"hint": "You Account Status controls the handling of your account data after all permissions expired.",
"NORMAL": {
".": "Normal",
@@ -196,7 +213,7 @@
".": "Sleep",
"hint": "Your account and all your data will not(!) be deleted. So you have reactivate your account anytime."
},
- "success" : "Status successfully changed"
+ "success": "Status successfully changed"
}
},
"service-unavailable": {
@@ -207,6 +224,13 @@
},
"services": {
".": "Services",
+ "alias_creation": {
+ "icon": "alternate_email",
+ "subtitle": "Creation of Aliases",
+ "text": "You can add additional aliases besides your username.",
+ "title": "Aliases"
+ },
+ "empty" : "You have insufficient permissions to use any services.",
"gitea": {
"icon": "code",
"subtitle": "Git-Repositories",
@@ -284,6 +308,17 @@
},
"user": {
".": "User",
+ "aliases": {
+ ".": "Aliases",
+ "alias": "Alias",
+ "confirmDelete": "Are you sure you want to delete your alias '{0}'?",
+ "create": "Add Alias",
+ "delete": "Delete",
+ "error": "This alias is invalid.",
+ "info": "You can add Aliases here. The number is limited due to a quota.",
+ "left": "You have {0} Alias(es) left.",
+ "noQuota": "Your quota for Aliases is depleted."
+ },
"unavailable": {
".": "Access denied",
"text": "The provided user does not exists or you have insufficient privileges to access profile."
@@ -294,6 +329,21 @@
"error": "Please choose a different username.",
"missing": "Please enter a valid username."
},
+ "visibility": {
+ ".": "Visibility",
+ "PRIVATE": {
+ ".": "Private",
+ "icon" : "lock"
+ },
+ "PROTECTED": {
+ ".": "Protected",
+ "icon" : "shield"
+ },
+ "PUBLIC": {
+ ".": "Public",
+ "icon" : "public"
+ }
+ },
"voucher": {
".": "Voucher",
"code": "Code",
diff --git a/src/styles.scss b/src/styles.scss
index 0ec1c2a..226218d 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -194,6 +194,16 @@ mat-sidenav-container {
color: $warn;
}
+.align-right{
+ display: flex;
+ padding: 21px 0;
+ justify-content: flex-end;
+}
+
+.mat-tooltip-trigger {
+ cursor: pointer;
+}
+
mat-card.warn,
mat-card.accent {
| |