) => {
+ if (newMetadata.hasOwnProperty(fieldModel.name) && newMetadata[fieldModel.name].length > 0) {
+ if (hasValue(fieldModel.value)) {
+ newMetadata[fieldModel.name][0].value = fieldModel.value;
+ } else {
+ newMetadata[fieldModel.name] = [];
+ }
+ } else if (hasValue(fieldModel.value)) {
+ newMetadata[fieldModel.name] = [{
+ value: fieldModel.value,
+ language: null
+ } as any];
+ }
+ });
+ this.epersonService.update(Object.assign(cloneDeep(this.user), { metadata: newMetadata })).pipe(
+ getSucceededRemoteData(),
+ getRemoteDataPayload()
+ ).subscribe((user) => {
+ this.user = user;
+ });
+ }
+}
diff --git a/src/app/profile-page/profile-page-routing.module.ts b/src/app/profile-page/profile-page-routing.module.ts
new file mode 100644
index 0000000000..4b9f2b7fff
--- /dev/null
+++ b/src/app/profile-page/profile-page-routing.module.ts
@@ -0,0 +1,15 @@
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
+import { ProfilePageComponent } from './profile-page.component';
+
+@NgModule({
+ imports: [
+ RouterModule.forChild([
+ { path: '', pathMatch: 'full', component: ProfilePageComponent, resolve: { breadcrumb: I18nBreadcrumbResolver }, data: { breadcrumbKey: 'profile', title: 'profile.title' } }
+ ])
+ ]
+})
+export class ProfilePageRoutingModule {
+
+}
diff --git a/src/app/profile-page/profile-page-security-form/profile-page-security-form.component.html b/src/app/profile-page/profile-page-security-form/profile-page-security-form.component.html
new file mode 100644
index 0000000000..59c6f5c248
--- /dev/null
+++ b/src/app/profile-page/profile-page-security-form/profile-page-security-form.component.html
@@ -0,0 +1,6 @@
+{{'profile.security.form.info' | translate}}
+
+
diff --git a/src/app/profile-page/profile-page-security-form/profile-page-security-form.component.ts b/src/app/profile-page/profile-page-security-form/profile-page-security-form.component.ts
new file mode 100644
index 0000000000..dd5ac478e2
--- /dev/null
+++ b/src/app/profile-page/profile-page-security-form/profile-page-security-form.component.ts
@@ -0,0 +1,56 @@
+import { Component, OnInit } from '@angular/core';
+import {
+ DynamicFormControlModel,
+ DynamicFormService,
+ DynamicInputModel
+} from '@ng-dynamic-forms/core';
+import { TranslateService } from '@ngx-translate/core';
+import { FormGroup } from '@angular/forms';
+
+@Component({
+ selector: 'ds-profile-page-security-form',
+ templateUrl: './profile-page-security-form.component.html'
+})
+export class ProfilePageSecurityFormComponent implements OnInit {
+
+ formModel: DynamicFormControlModel[] = [
+ new DynamicInputModel({
+ id: 'password',
+ name: 'password',
+ inputType: 'password'
+ }),
+ new DynamicInputModel({
+ id: 'passwordrepeat',
+ name: 'passwordrepeat',
+ inputType: 'password'
+ })
+ ];
+
+ /**
+ * The form group of this form
+ */
+ formGroup: FormGroup;
+
+ LABEL_PREFIX = 'profile.security.form.label.';
+
+ constructor(protected formService: DynamicFormService,
+ protected translate: TranslateService) {
+ }
+
+ ngOnInit(): void {
+ this.formGroup = this.formService.createFormGroup(this.formModel);
+ this.updateFieldTranslations();
+ this.translate.onLangChange
+ .subscribe(() => {
+ this.updateFieldTranslations();
+ });
+ }
+
+ updateFieldTranslations() {
+ this.formModel.forEach(
+ (fieldModel: DynamicInputModel) => {
+ fieldModel.label = this.translate.instant(this.LABEL_PREFIX + fieldModel.id);
+ }
+ );
+ }
+}
diff --git a/src/app/profile-page/profile-page.component.html b/src/app/profile-page/profile-page.component.html
new file mode 100644
index 0000000000..3b0b2d712b
--- /dev/null
+++ b/src/app/profile-page/profile-page.component.html
@@ -0,0 +1,18 @@
+
+
+
{{'profile.head' | translate}}
+
+
+
+
+
diff --git a/src/app/profile-page/profile-page.component.ts b/src/app/profile-page/profile-page.component.ts
new file mode 100644
index 0000000000..eb182aab4e
--- /dev/null
+++ b/src/app/profile-page/profile-page.component.ts
@@ -0,0 +1,35 @@
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { Observable } from 'rxjs/internal/Observable';
+import { EPerson } from '../core/eperson/models/eperson.model';
+import { select, Store } from '@ngrx/store';
+import { getAuthenticatedUser } from '../core/auth/selectors';
+import { AppState } from '../app.reducer';
+import { ProfilePageMetadataFormComponent } from './profile-page-metadata-form/profile-page-metadata-form.component';
+
+@Component({
+ selector: 'ds-profile-page',
+ templateUrl: './profile-page.component.html'
+})
+/**
+ * Component for a user to edit their profile information
+ */
+export class ProfilePageComponent implements OnInit {
+
+ @ViewChild(ProfilePageMetadataFormComponent, { static: false }) metadataForm: ProfilePageMetadataFormComponent;
+
+ /**
+ * The authenticated user
+ */
+ user$: Observable;
+
+ constructor(private store: Store) {
+ }
+
+ ngOnInit(): void {
+ this.user$ = this.store.pipe(select(getAuthenticatedUser));
+ }
+
+ updateProfile() {
+ this.metadataForm.updateProfile();
+ }
+}
diff --git a/src/app/profile-page/profile-page.module.ts b/src/app/profile-page/profile-page.module.ts
new file mode 100644
index 0000000000..f40c125ff8
--- /dev/null
+++ b/src/app/profile-page/profile-page.module.ts
@@ -0,0 +1,23 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { SharedModule } from '../shared/shared.module';
+import { ProfilePageRoutingModule } from './profile-page-routing.module';
+import { ProfilePageComponent } from './profile-page.component';
+import { ProfilePageMetadataFormComponent } from './profile-page-metadata-form/profile-page-metadata-form.component';
+import { ProfilePageSecurityFormComponent } from './profile-page-security-form/profile-page-security-form.component';
+
+@NgModule({
+ imports: [
+ ProfilePageRoutingModule,
+ CommonModule,
+ SharedModule
+ ],
+ declarations: [
+ ProfilePageComponent,
+ ProfilePageMetadataFormComponent,
+ ProfilePageSecurityFormComponent
+ ]
+})
+export class ProfilePageModule {
+
+}