diff --git a/app/src/app/app.module.ts b/app/src/app/app.module.ts index 411b246e7..c618cc762 100644 --- a/app/src/app/app.module.ts +++ b/app/src/app/app.module.ts @@ -38,6 +38,7 @@ import { APP_ROUTES } from './app.routes'; import { FilesComponent } from './components/files/files.component'; import { LibrariesComponent } from './components/libraries/libraries.component'; import { FavoriteLibrariesComponent } from './components/favorite-libraries/favorite-libraries.component'; +import { ViewProfileModule } from './components/view-profile/view-profile.module'; import { AppStoreModule } from './store/app-store.module'; import { MaterialModule } from './material.module'; @@ -135,7 +136,8 @@ registerLocaleData(localeSv); AppSearchResultsModule, AppHeaderModule, AppNodeVersionModule, - HammerModule + HammerModule, + ViewProfileModule ], declarations: [ AppComponent, diff --git a/app/src/app/app.routes.ts b/app/src/app/app.routes.ts index 42639daae..97a9b66fe 100644 --- a/app/src/app/app.routes.ts +++ b/app/src/app/app.routes.ts @@ -38,6 +38,7 @@ import { RecentFilesComponent } from './components/recent-files/recent-files.com import { SharedFilesComponent } from './components/shared-files/shared-files.component'; import { DetailsComponent } from './components/details/details.component'; import { HomeComponent } from './components/home/home.component'; +import { ViewProfileComponent } from './components/view-profile/view-profile.component'; export const APP_ROUTES: Routes = [ { @@ -76,6 +77,10 @@ export const APP_ROUTES: Routes = [ component: AppLayoutComponent, canActivate: [AuthGuard, ExtensionsDataLoaderGuard], children: [ + { + path: 'profile', + component: ViewProfileComponent + }, { path: '', component: HomeComponent diff --git a/app/src/app/components/view-profile/view-profile.component.html b/app/src/app/components/view-profile/view-profile.component.html new file mode 100644 index 000000000..5d69200c0 --- /dev/null +++ b/app/src/app/components/view-profile/view-profile.component.html @@ -0,0 +1,186 @@ +
+
+
+ arrow_back +

{{'APP.EDIT_PROFILE.MY_PROFILE' | translate}}

+
+ +
+
+
+
+ + {{ generalSectionDropdown ? 'expand_more' : 'chevron_right'}} +

{{'APP.EDIT_PROFILE.GENERAL' | translate}}

+
+
+ +
+
+ + +
+
+ +
+
+
+

{{'APP.EDIT_PROFILE.FIRST_NAME' | translate}}

+

{{personDetails?.firstName}}

+
+ +
+

{{'APP.EDIT_PROFILE.LAST_NAME' | translate}}

+

{{personDetails?.lastName}}

+
+ +
+

{{'APP.EDIT_PROFILE.JOB_TITLE' | translate}}

+

{{personDetails?.jobTitle}}

+ +
+ +
+

{{'APP.EDIT_PROFILE.LOCATION' | translate}}

+

{{personDetails?.location}}

+ +
+ +
+

{{'APP.EDIT_PROFILE.TELEPHONE' | translate}}

+

{{personDetails?.telephone}}

+ +
+ +
+

{{'APP.EDIT_PROFILE.MOBILE' | translate}}

+

{{personDetails?.mobile}}

+ +
+
+
+
+ +
+ + + +
+ +
+
+
+ + {{ contactSectionDropdown ? 'expand_more' : 'chevron_right'}} +

{{'APP.EDIT_PROFILE.COMPANY_DETAILS' | translate}}

+
+ +
+ +
+
+ + +
+
+ +
+
+
+

{{'APP.EDIT_PROFILE.NAME' | translate}}

+

{{personDetails?.company?.organization}}

+
+ +
+

{{'APP.EDIT_PROFILE.ADDRESS' | translate}}

+

{{personDetails?.company?.address1}}

+ +
+ +
+

{{'APP.EDIT_PROFILE.POST_CODE' | translate}}

+

{{personDetails?.company?.postcode}}

+ + +
+ +
+

{{'APP.EDIT_PROFILE.TELEPHONE' | translate}}

+

{{personDetails?.company?.telephone}}

+ + +
+ +
+

{{'APP.EDIT_PROFILE.EMAIL' | translate}}

+

{{personDetails?.company?.email}}

+ +
+
+
+
+
diff --git a/app/src/app/components/view-profile/view-profile.component.scss b/app/src/app/components/view-profile/view-profile.component.scss new file mode 100644 index 000000000..db59b801b --- /dev/null +++ b/app/src/app/components/view-profile/view-profile.component.scss @@ -0,0 +1,180 @@ +app-view-profile { + letter-spacing: .5px; + + .app-profile-container { + margin-top: 1rem; + overflow: scroll; + height:100%; + width: 100%; + } + + .app-profile-row { + width: 100%; + } + + .app-profile-title { + display: flex; + margin-left: 2rem; + } + + .app-profile { + cursor: pointer; + } + + .app-profile-general-row { + margin: 2rem 0 0 2rem; + width: 70%; + border: 1px solid var(--theme-grey-background-color); + border-radius: 1rem; + } + + .app-profile-icon { + margin-right: 1rem; + margin-top: 1rem; + cursor: pointer; + } + + .app-profile-general-icon { + cursor: pointer; + } + + .app-profile-text { + letter-spacing: .5px; + } + + .app-profile-general { + display: flex; + padding-left: 1rem; + } + + .app-profile-general-bottom-radius { + border-bottom-left-radius:0; + border-bottom-right-radius: 0; + } + + .app-profile-general-div { + display: flex; + width: 60%; + padding-top: 1rem; + cursor: pointer; + } + + .app-general-title { + margin-left: 0.6rem; + margin-top: 4px; + letter-spacing: .5px; + } + + .app-general-edit-btn { + width:60%; + text-align: end; + } + + .app-mat-divider { + border-top-width: 2px; + border-top-color: var(--theme-grey-background-color); + padding-left: -1px; + padding-right: 1px; + } + + .app-selected:focus { + border: 2px solid var(--theme-blue-button-color) !important; + border-radius: 6px; + outline : none !important; + box-shadow: 0 0 2px (--theme-blue-button-color); + } + + .app-profile-row { + width: 100%; + margin: 2rem 0 0 0; + } + + .app-general-edit { + margin: 0.7rem; + background: var(--theme-grey-text-background-color); + } + + .app-general-edit:hover { + background: var(--theme-grey-hover-background-color); + } + + .app-general-cancel-btn { + margin: 0.7rem; + background-color: var(--theme-grey-text-background-color); + } + + .app-general-save-btn { + margin: 0.7rem; + color: white; + background-color: var(--theme-blue-button-color); + } + + .app-general-dropdown-divider { + border-top-color: var(--theme-grey-divider-color); + } + + .app-general-dropdown { + padding: 0rem 1rem; + } + + .app-general-dropdown-details { + display: flex; + } + + .app-profile-general-dropdown-heading { + color: var(--theme-heading-color); + width: 20%; + font-weight: 400; + letter-spacing: .5px; + } + + .app-profile-general-dropdown-details { + margin-top: 1.3rem; + letter-spacing: .5px; + } + + .app-profile-general-dropdown-input-details { + width: 24%; + height: 25px; + border: none; + margin-top: 1.3rem; + background-color: var(--theme-dropdown-color); + } + + .app-profile-login-row { + margin: 2rem 0 0 2rem; + width: 70%; + border: 1px solid var(--theme-grey-background-color); + border-radius: 1rem; + } + + .app-profile-login { + display: flex; + padding-left: 1rem; + } + + .app-profile-login-dropdown-details { + width: 24%; + height: 25px; + border: none; + margin-top: 1.3rem; + background-color: var(--theme-dropdown-color) ; + } + + .app-profile-login-dropdown-heading-forgot { + margin-top: 1.3rem; + color: var(--theme-heading-color); + margin-left: 16rem; + } + + .app-profile-company-row { + margin-top: 2rem; + } + + .app-profile-contact-row { + margin: 2rem 0 5rem 2rem; + width: 70%; + border: 1px solid var(--theme-grey-background-color); + border-radius: 1rem; + } +} diff --git a/app/src/app/components/view-profile/view-profile.component.ts b/app/src/app/components/view-profile/view-profile.component.ts new file mode 100644 index 000000000..3dd831859 --- /dev/null +++ b/app/src/app/components/view-profile/view-profile.component.ts @@ -0,0 +1,169 @@ +/* + * Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved. + * + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + */ +import { AlfrescoApiService } from '@alfresco/adf-core'; +import { PeopleApi, Person } from '@alfresco/js-api'; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; +import { throwError } from 'rxjs'; + +@Component({ + selector: 'app-view-profile', + templateUrl: './view-profile.component.html', + styleUrls: ['./view-profile.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class ViewProfileComponent implements OnInit { + peopleApi: PeopleApi; + + profileForm: FormGroup; + personDetails: Person; + + generalSectionDropdown = true; + generalSectionButtonsToggle = true; + + loginSectionDropdown = false; + loginSectionButtonsToggle = true; + passwordSectionDropdown = false; + + contactSectionDropdown = false; + contactSectionButtonsToggle = true; + + constructor(private formBuilder: FormBuilder, private router: Router, apiService: AlfrescoApiService) { + this.peopleApi = new PeopleApi(apiService.getInstance()); + } + + ngOnInit() { + this.populateForm(this.personDetails); + + this.peopleApi + .getPerson('-me-') + .then((userInfo) => { + this.personDetails = userInfo?.entry; + this.populateForm(userInfo?.entry); + }) + .catch((error) => { + throwError(error); + }); + } + + populateForm(userInfo: Person) { + this.profileForm = this.formBuilder.group({ + jobTitle: [userInfo?.jobTitle || ''], + location: [userInfo?.location || ''], + telephone: [userInfo?.telephone || '', Validators.pattern('^[0-9]*$')], + mobile: [userInfo?.mobile || '', Validators.pattern('^[0-9]*$')], + oldPassword: [''], + newPassword: [''], + verifyPassword: [''], + companyPostCode: [userInfo?.company?.postcode || ''], + companyAddress: [userInfo?.company?.address1 || ''], + companyTelephone: [userInfo?.company?.telephone || '', Validators.pattern('^[0-9]*$')], + companyEmail: [userInfo?.company?.email || '', Validators.email] + }); + } + + navigateToPersonalFiles() { + this.router.navigate(['/personal-files'], { + replaceUrl: true + }); + } + + toggleGeneralDropdown() { + this.generalSectionDropdown = !this.generalSectionDropdown; + + if (!this.generalSectionDropdown) { + this.generalSectionButtonsToggle = true; + } + } + + toggleGeneralButtons() { + this.generalSectionButtonsToggle = !this.generalSectionButtonsToggle; + + if (!this.generalSectionButtonsToggle) { + this.generalSectionDropdown = true; + } + } + + onSaveGeneralData(event) { + this.generalSectionButtonsToggle = !this.generalSectionButtonsToggle; + this.updatePersonDetails(event); + } + + onSaveLoginData() { + this.passwordSectionDropdown = !this.passwordSectionDropdown; + this.loginSectionButtonsToggle = !this.loginSectionButtonsToggle; + } + + onSaveCompanyData(event) { + this.contactSectionButtonsToggle = !this.contactSectionButtonsToggle; + this.updatePersonDetails(event); + } + + toggleLoginDropdown() { + this.loginSectionDropdown = !this.loginSectionDropdown; + + if (!this.loginSectionDropdown) { + this.loginSectionButtonsToggle = true; + } + } + + toggleLoginButtons() { + this.loginSectionButtonsToggle = !this.loginSectionButtonsToggle; + this.passwordSectionDropdown = !this.passwordSectionDropdown; + + if (!this.loginSectionButtonsToggle) { + this.loginSectionDropdown = true; + this.passwordSectionDropdown = true; + } + } + + toggleContactDropdown() { + this.contactSectionDropdown = !this.contactSectionDropdown; + + if (!this.contactSectionDropdown) { + this.contactSectionButtonsToggle = true; + } + } + + toggleContactButtons() { + this.contactSectionButtonsToggle = !this.contactSectionButtonsToggle; + + if (!this.contactSectionButtonsToggle) { + this.contactSectionDropdown = true; + } + } + + updatePersonDetails(event) { + if (this.profileForm.valid) { + this.peopleApi + .updatePerson(this.personDetails.id, { + jobTitle: event.value.jobTitle, + location: event.value.location, + telephone: event.value.telephone, + mobile: event.value.mobile, + company: { + postcode: event.value.companyPostCode, + address1: event.value.companyAddress, + telephone: event.value.companyTelephone, + email: event.value.companyEmail + } + }) + .then((person) => { + this.personDetails = person?.entry; + this.populateForm(person?.entry); + }) + .catch((error) => { + this.populateForm(this.personDetails); + throwError(error); + }); + } else { + this.populateForm(this.personDetails); + } + } +} diff --git a/app/src/app/components/view-profile/view-profile.module.ts b/app/src/app/components/view-profile/view-profile.module.ts new file mode 100644 index 000000000..ff817f799 --- /dev/null +++ b/app/src/app/components/view-profile/view-profile.module.ts @@ -0,0 +1,35 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2020 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { NgModule } from '@angular/core'; +import { ViewProfileComponent } from './view-profile.component'; +import { CommonModule } from '@angular/common'; +import { CoreModule } from '@alfresco/adf-core'; + +@NgModule({ + imports: [CommonModule, CoreModule.forChild()], + declarations: [ViewProfileComponent] +}) +export class ViewProfileModule {} diff --git a/app/src/app/ui/variables/variables.scss b/app/src/app/ui/variables/variables.scss index 74eba063a..c25174bd9 100644 --- a/app/src/app/ui/variables/variables.scss +++ b/app/src/app/ui/variables/variables.scss @@ -33,6 +33,14 @@ $adf-upload-dragging-level1-border: none; $adf-permission-list-width: 100%; +$grey-background: rgba(33, 33, 33, 0.12); +$grey-text-background: rgba(33, 33, 33, 0.05); +$grey-hover-background: rgba(33, 33, 33, 0.24); +$blue-save-button-background: #1F74DB; +$black-heading: #4e4c4c; +$grey-dropdown-background: #eee; +$grey-divider: rgba(0,0,0,.22); + $defaults: ( --theme-primary-color: mat.get-color-from-palette($primary), --theme-primary-color-default-contrast: mat.get-color-from-palette($primary, default-contrast), @@ -53,6 +61,13 @@ $defaults: ( --theme-dialog-background-color: mat.get-color-from-palette($background, dialog), --new-button-font-size: 0.9rem, + --theme-grey-text-background-color: $grey-text-background, + --theme-grey-background-color: $grey-background, + --theme-grey-hover-background-color: $grey-hover-background, + --theme-blue-button-color: $blue-save-button-background, + --theme-heading-color: $black-heading, + --theme-dropdown-color: $grey-dropdown-background, + --theme-grey-divider-color: $grey-divider, ); // propagates SCSS variables into the CSS variables scope diff --git a/app/src/assets/i18n/en.json b/app/src/assets/i18n/en.json index 5617af1ef..9b2393e4c 100644 --- a/app/src/assets/i18n/en.json +++ b/app/src/assets/i18n/en.json @@ -47,6 +47,31 @@ "RESET": "Reset", "APPLY": "Apply" }, + "EDIT_PROFILE": { + "MY_PROFILE": "My Profile", + "GENERAL": "General", + "EDIT": "Edit", + "CANCEL": "Cancel", + "SAVE": "Save", + "FIRST_NAME": "First name", + "LAST_NAME": "Last name", + "JOB_TITLE": "Job title", + "LOCATION": "Location", + "TELEPHONE": "Telephone", + "MOBILE": "Mobile", + "LOGIN": "Login", + "USERNAME": "Username", + "EMAIL": "Email", + "PASSWORD": "Password", + "OLD_PASSWORD": "Old Password", + "FORGOT_PASSWORD": "Forgot Password", + "NEW_PASSWORD": "New Password", + "VERIFY_PASSWORD": "Verify Password", + "COMPANY_DETAILS": "Company details", + "NAME": "Name", + "ADDRESS": "Address", + "POST_CODE": "Post code" + }, "LOCKED_BY": "Locked by: ", "PREVIEW": { "TITLE": "Preview"