From 88424ca107be06cba4adc84b927924b08876272e Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Thu, 11 May 2023 17:49:35 +0000 Subject: [PATCH 1/5] added user initials --- .../about/assets/about.plugin.json | 24 +-- .../aca-content/assets/app.extensions.json | 65 ++++---- .../aca-content/src/lib/aca-content.module.ts | 4 +- .../common/user-info/user-info.component.html | 13 +- .../common/user-info/user-info.component.scss | 25 +++ .../user-info/user-info.component.spec.ts | 89 +++++++---- .../common/user-info/user-info.component.ts | 24 ++- .../lib/components/sidenav/sidenav.module.ts | 4 +- .../user-menu/user-menu.component.html | 9 ++ .../user-menu/user-menu.component.scss | 14 ++ .../user-menu/user-menu.component.spec.ts | 148 ++++++++++++++++++ .../sidenav/user-menu/user-menu.component.ts | 99 ++++++++++++ .../src/lib/ui/variables/variables.scss | 6 +- 13 files changed, 439 insertions(+), 85 deletions(-) create mode 100644 projects/aca-content/src/lib/components/common/user-info/user-info.component.scss create mode 100644 projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html create mode 100644 projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.scss create mode 100644 projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.spec.ts create mode 100644 projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.ts diff --git a/projects/aca-content/about/assets/about.plugin.json b/projects/aca-content/about/assets/about.plugin.json index eb236cd91e..35ffac1497 100644 --- a/projects/aca-content/about/assets/about.plugin.json +++ b/projects/aca-content/about/assets/about.plugin.json @@ -27,18 +27,20 @@ "header": [ { "id": "app.header.more", - "children": [ - { - "id": "app.header.about", - "order": 100, - "title": "APP.BROWSE.ABOUT.TITLE", - "description": "APP.BROWSE.ABOUT.TITLE", - "icon": "info", - "actions": { - "click": "app.actions.about" + "data": { + "items": [ + { + "id": "app.header.about", + "order": 100, + "title": "APP.BROWSE.ABOUT.TITLE", + "description": "APP.BROWSE.ABOUT.TITLE", + "icon": "info", + "actions": { + "click": "app.actions.about" + } } - } - ] + ] + } } ] } diff --git a/projects/aca-content/assets/app.extensions.json b/projects/aca-content/assets/app.extensions.json index 5065c62a31..a39d329755 100644 --- a/projects/aca-content/assets/app.extensions.json +++ b/projects/aca-content/assets/app.extensions.json @@ -87,38 +87,45 @@ }, { "id": "app.header.more", - "type": "menu", + "type": "custom", "order": 10000, - "icon": "apps", + "component": "app.user.menu", "title": "APP.ACTIONS.MORE", - "children": [ - { - "id": "app.header.user", - "type": "custom", - "component": "app.user", - "order": 100 - }, - { - "id": "app.languagePicker", - "order": 100, - "type": "custom", - "component": "app.languagePicker" - }, - { - "id": "logout.separator", - "type": "separator", - "order": 199 - }, - { - "id": "app.logout", - "order": 200, - "type": "custom", - "component": "app.logout", - "rules": { - "visible": "app.canShowLogout" + "data": { + "items": [ + { + "id": "app.header.user", + "type": "custom", + "component": "app.user", + "order": 100 + }, + { + "id": "user.separator", + "type": "separator", + "order": 100 + }, + { + "id": "app.languagePicker", + "order": 100, + "type": "custom", + "component": "app.languagePicker" + }, + { + "id": "logout.separator", + "type": "separator", + "order": 199 + }, + { + "id": "app.logout", + "order": 200, + "type": "custom", + "component": "app.logout", + "rules": { + "visible": "app.canShowLogout" + } } - } - ] + ] + } } ], "icons": [ diff --git a/projects/aca-content/src/lib/aca-content.module.ts b/projects/aca-content/src/lib/aca-content.module.ts index ada701a0e1..54a9d082f4 100644 --- a/projects/aca-content/src/lib/aca-content.module.ts +++ b/projects/aca-content/src/lib/aca-content.module.ts @@ -118,6 +118,7 @@ import { UserInfoComponent } from './components/common/user-info/user-info.compo import { SidenavComponent } from './components/sidenav/sidenav.component'; import { ContentManagementService } from './services/content-management.service'; import { ShellLayoutComponent, SHELL_NAVBAR_MIN_WIDTH } from '@alfresco/adf-core/shell'; +import { UserMenuComponent } from './components/sidenav/user-menu/user-menu.component'; registerLocaleData(localeFr); registerLocaleData(localeDe); @@ -229,7 +230,8 @@ export class ContentServiceExtensionModule { 'app.languagePicker': LanguagePickerComponent, 'app.logout': LogoutComponent, 'app.user': UserInfoComponent, - 'app.notification-center': NotificationHistoryComponent + 'app.notification-center': NotificationHistoryComponent, + 'app.user.menu': UserMenuComponent }); extensions.setEvaluators({ diff --git a/projects/aca-content/src/lib/components/common/user-info/user-info.component.html b/projects/aca-content/src/lib/components/common/user-info/user-info.component.html index 7017c6af68..d3e115f5a8 100644 --- a/projects/aca-content/src/lib/components/common/user-info/user-info.component.html +++ b/projects/aca-content/src/lib/components/common/user-info/user-info.component.html @@ -1,4 +1,9 @@ - +
+ + +
diff --git a/projects/aca-content/src/lib/components/common/user-info/user-info.component.scss b/projects/aca-content/src/lib/components/common/user-info/user-info.component.scss new file mode 100644 index 0000000000..1d168b2ece --- /dev/null +++ b/projects/aca-content/src/lib/components/common/user-info/user-info.component.scss @@ -0,0 +1,25 @@ +.aca-user-info { + display: flex; + height: 66px; + align-items: center; + + &-button { + border-radius: 90%; + height: 32px; + margin-right: 0; + min-width: 32px; + padding: 0; + font-weight: 700; + line-height: 32px; + text-align: center; + vertical-align: middle; + background: var(--theme-user-initials-background-color); + color: var(--theme-user-intials-text-color); + border: none; + } + + &-name-email { + line-height: 24px; + margin-left: 10px; + } +} diff --git a/projects/aca-content/src/lib/components/common/user-info/user-info.component.spec.ts b/projects/aca-content/src/lib/components/common/user-info/user-info.component.spec.ts index 2df6b9ec9e..11543c9863 100644 --- a/projects/aca-content/src/lib/components/common/user-info/user-info.component.spec.ts +++ b/projects/aca-content/src/lib/components/common/user-info/user-info.component.spec.ts @@ -23,18 +23,18 @@ */ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { AuthenticationService } from '@alfresco/adf-core'; +import { AuthenticationService, IdentityUserService } from '@alfresco/adf-core'; import { PeopleContentService } from '@alfresco/adf-content-services'; import { UserInfoComponent } from './user-info.component'; import { AppTestingModule } from '../../../testing/app-testing.module'; import { of } from 'rxjs'; -describe('UserInfoComponent', () => { +describe('parseDisplayName', () => { let component: UserInfoComponent; let fixture: ComponentFixture; let authServiceStub: Partial; let peopleContentServiceStub: Partial; - let identityUserServiceStub: Partial; + let identityUserServiceStub: Partial; beforeEach(() => { authServiceStub = { @@ -67,24 +67,23 @@ describe('UserInfoComponent', () => { }; identityUserServiceStub = { - getCurrentUserInfo: () => - of({ - firstName: 'John', - email: 'john@example.com', - id: 'johnDoe1', - enabled: true, - company: { - organization: 'ABC Organization', - address1: 'XYZ Road', - address2: 'Ohio', - address3: 'Westlake', - postcode: '44145', - telephone: '456876', - fax: '323984', - email: 'contact.us@abc.com' - }, - isAdmin: () => true - }) + getCurrentUserInfo: () => ({ + firstName: 'John', + email: 'john@example.com', + id: 'johnDoe1', + enabled: true, + company: { + organization: 'ABC Organization', + address1: 'XYZ Road', + address2: 'Ohio', + address3: 'Westlake', + postcode: '44145', + telephone: '456876', + fax: '323984', + email: 'contact.us@abc.com' + }, + isAdmin: () => true + }) }; TestBed.configureTestingModule({ @@ -93,7 +92,7 @@ describe('UserInfoComponent', () => { providers: [ { provide: AuthenticationService, useValue: authServiceStub }, { provide: PeopleContentService, useValue: peopleContentServiceStub }, - { provide: identityUserServiceStub, useValue: identityUserServiceStub } + { provide: IdentityUserService, useValue: identityUserServiceStub } ] }).compileComponents(); @@ -107,15 +106,45 @@ describe('UserInfoComponent', () => { expect(loggedIn).toBeTrue(); }); - it('should parse display name without email', async () => { - const model = { firstName: 'John' }; - const displayName = component['parseDisplayName'](model); - expect(displayName).toBe('John'); + it('should return an object with empty strings for all properties when the input model is empty', () => { + const result = component.parseDisplayName({}); + expect(result.firstName).toEqual(''); + expect(result.initials).toEqual(''); + expect(result.email).toEqual(''); + }); + + it('should return an object with the correct firstName and initials when the input model has only the firstName property', () => { + const result = component.parseDisplayName({ firstName: 'John' }); + expect(result.firstName).toEqual('John'); + expect(result.initials).toEqual('J'); + expect(result.email).toEqual(''); + }); + + it('should return an object with the correct firstName and initials when the input model has only the lastName property', () => { + const result = component.parseDisplayName({ lastName: 'Doe' }); + expect(result.firstName).toEqual(' Doe'); + expect(result.initials).toEqual('D'); + expect(result.email).toEqual(''); + }); + + it('should return an object with the correct email property when the input model has only the email property', () => { + const result = component.parseDisplayName({ email: 'john.doe@example.com' }); + expect(result.firstName).toEqual(''); + expect(result.initials).toEqual(''); + expect(result.email).toEqual('john.doe@example.com'); + }); + + it('should return an object with the correct firstName, initials, and lastName concatenated when the input model has both firstName and lastName properties', () => { + const result = component.parseDisplayName({ firstName: 'John', lastName: 'Doe' }); + expect(result.firstName).toEqual('John Doe'); + expect(result.initials).toEqual('JD'); + expect(result.email).toEqual(''); }); - it('should parse display name with email', async () => { - const model = { firstName: 'John', email: 'john@example.com' }; - const displayName = component['parseDisplayName'](model); - expect(displayName).toBe('John (john@example.com)'); + it('should return an object with all properties correctly parsed when the input model has all three properties', () => { + const result = component.parseDisplayName({ firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' }); + expect(result.firstName).toEqual('John Doe'); + expect(result.initials).toEqual('JD'); + expect(result.email).toEqual('john.doe@example.com'); }); }); diff --git a/projects/aca-content/src/lib/components/common/user-info/user-info.component.ts b/projects/aca-content/src/lib/components/common/user-info/user-info.component.ts index afacbf7097..43f3ce806d 100644 --- a/projects/aca-content/src/lib/components/common/user-info/user-info.component.ts +++ b/projects/aca-content/src/lib/components/common/user-info/user-info.component.ts @@ -23,17 +23,19 @@ */ import { IdentityUserService, AuthenticationService } from '@alfresco/adf-core'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { Observable, of } from 'rxjs'; import { PeopleContentService } from '@alfresco/adf-content-services'; import { map } from 'rxjs/operators'; @Component({ selector: 'app-user-info', - templateUrl: './user-info.component.html' + templateUrl: './user-info.component.html', + styleUrls: ['./user-info.component.scss'], + encapsulation: ViewEncapsulation.None }) export class UserInfoComponent implements OnInit { - displayName$: Observable; + displayName$: Observable<{ firstName: string; initials: string; email: string }>; constructor( private peopleContentService: PeopleContentService, @@ -72,13 +74,19 @@ export class UserInfoComponent implements OnInit { this.displayName$ = of(this.identityUserService.getCurrentUserInfo()).pipe(map((model) => this.parseDisplayName(model))); } - private parseDisplayName(model: { firstName?: string; email?: string }): string { - let result = model.firstName; - + parseDisplayName(model: { firstName?: string; lastName?: string; email?: string }): { firstName: string; initials: string; email: string } { + const result = { firstName: '', initials: '', email: '' }; + if (model.firstName) { + result.firstName = model.firstName; + result.initials = model.firstName.charAt(0).toUpperCase(); + } + if (model.lastName) { + result.firstName += ' ' + model.lastName; + result.initials += model.lastName.charAt(0).toUpperCase(); + } if (model.email) { - result = `${model.firstName} (${model.email})`; + result.email = `${model.email}`; } - return result; } diff --git a/projects/aca-content/src/lib/components/sidenav/sidenav.module.ts b/projects/aca-content/src/lib/components/sidenav/sidenav.module.ts index 00b4b9f07f..218e71a80d 100644 --- a/projects/aca-content/src/lib/components/sidenav/sidenav.module.ts +++ b/projects/aca-content/src/lib/components/sidenav/sidenav.module.ts @@ -36,6 +36,7 @@ import { ButtonMenuComponent } from './components/button-menu.component'; import { ActionDirective } from './directives/action.directive'; import { SidenavHeaderComponent } from './components/sidenav-header.component'; import { SharedToolbarModule } from '@alfresco/aca-shared'; +import { UserMenuComponent } from './user-menu/user-menu.component'; @NgModule({ imports: [CoreModule.forChild(), ExtensionsModule.forChild(), RouterModule, AppCreateMenuModule, SharedToolbarModule], @@ -47,7 +48,8 @@ import { SharedToolbarModule } from '@alfresco/aca-shared'; ExpandMenuComponent, ButtonMenuComponent, SidenavComponent, - SidenavHeaderComponent + SidenavHeaderComponent, + UserMenuComponent ], exports: [ MenuPanelDirective, diff --git a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html new file mode 100644 index 0000000000..67c4e9d644 --- /dev/null +++ b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html @@ -0,0 +1,9 @@ + + + + + + + diff --git a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.scss b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.scss new file mode 100644 index 0000000000..01066a8eac --- /dev/null +++ b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.scss @@ -0,0 +1,14 @@ +.aca-user-menu-button { + border-radius: 90%; + height: 32px; + margin-right: 0; + min-width: 32px; + padding: 0; + font-weight: 700; + line-height: 32px; + text-align: center; + vertical-align: middle; + background: var(--theme-user-initials-background-color); + color: var(--theme-user-intials-text-color); + border: none; +} diff --git a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.spec.ts b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.spec.ts new file mode 100644 index 0000000000..9213d0f9c8 --- /dev/null +++ b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.spec.ts @@ -0,0 +1,148 @@ +/*! + * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Alfresco Example Content Application + * + * 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 + * from Hyland Software. If not, see . + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AuthenticationService, IdentityUserService } from '@alfresco/adf-core'; +import { PeopleContentService } from '@alfresco/adf-content-services'; +import { AppTestingModule } from '../../../testing/app-testing.module'; +import { UserMenuComponent } from './user-menu.component'; +import { of } from 'rxjs'; + +describe('UserMenuComponent', () => { + let component: UserMenuComponent; + let fixture: ComponentFixture; + let authServiceStub: Partial; + let peopleContentServiceStub: Partial; + let identityUserServiceStub: Partial; + + const menuItems = [ + { + id: 'menu1', + title: 'Menu Item 1', + icon: 'icon1', + actions: { + click: 'action1' + } + }, + { + id: 'menu2', + title: 'Menu Item 2', + icon: 'icon2', + actions: { + click: 'action2' + } + } + ]; + + beforeEach(() => { + authServiceStub = { + isOauth: () => true, + isECMProvider: () => true, + isEcmLoggedIn: () => true, + isKerberosEnabled: () => false, + isLoggedIn: () => true + }; + + peopleContentServiceStub = { + getCurrentUserInfo: () => + of({ + firstName: 'John', + email: 'john@example.com', + id: 'johnDoe1', + enabled: true, + company: { + organization: 'ABC Organization', + address1: 'XYZ Road', + address2: 'Ohio', + address3: 'Westlake', + postcode: '44145', + telephone: '456876', + fax: '323984', + email: 'contact.us@abc.com' + }, + isAdmin: () => true + }) + }; + + identityUserServiceStub = { + getCurrentUserInfo: () => ({ + firstName: 'John', + email: 'john@example.com', + id: 'johnDoe1', + enabled: true, + company: { + organization: 'ABC Organization', + address1: 'XYZ Road', + address2: 'Ohio', + address3: 'Westlake', + postcode: '44145', + telephone: '456876', + fax: '323984', + email: 'contact.us@abc.com' + }, + isAdmin: () => true + }) + }; + + TestBed.configureTestingModule({ + imports: [AppTestingModule], + declarations: [UserMenuComponent], + providers: [ + { provide: AuthenticationService, useValue: authServiceStub }, + { provide: PeopleContentService, useValue: peopleContentServiceStub }, + { provide: identityUserServiceStub, useValue: identityUserServiceStub } + ] + }).compileComponents(); + + fixture = TestBed.createComponent(UserMenuComponent); + component = fixture.componentInstance; + component.data = { items: menuItems }; + fixture.detectChanges(); + }); + + it('should return an object with empty strings for all properties when the input model is empty', () => { + const result = component.parseDisplayName({}); + expect(result.initials).toEqual(''); + }); + + it('should return an object with the correct firstName and initials when the input model has only the firstName property', () => { + const result = component.parseDisplayName({ firstName: 'John' }); + expect(result.initials).toEqual('J'); + }); + + it('should return an object with the correct firstName and initials when the input model has only the lastName property', () => { + const result = component.parseDisplayName({ lastName: 'Doe' }); + expect(result.initials).toEqual('D'); + }); + + it('should return an object with the correct firstName, initials, and lastName concatenated when the input model has both firstName and lastName properties', () => { + const result = component.parseDisplayName({ firstName: 'John', lastName: 'Doe' }); + expect(result.initials).toEqual('JD'); + }); + + it('should return an object with all properties correctly parsed when the input model has all three properties', () => { + const result = component.parseDisplayName({ firstName: 'John', lastName: 'Doe' }); + expect(result.initials).toEqual('JD'); + }); +}); diff --git a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.ts b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.ts new file mode 100644 index 0000000000..f4e6167c7d --- /dev/null +++ b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.ts @@ -0,0 +1,99 @@ +/*! + * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Alfresco Example Content Application + * + * 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 + * from Hyland Software. If not, see . + */ + +import { PeopleContentService } from '@alfresco/adf-content-services'; +import { AuthenticationService, IdentityUserService } from '@alfresco/adf-core'; +import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { Observable, of } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { ContentActionRef } from '@alfresco/adf-extensions'; + +@Component({ + selector: 'aca-user-menu', + templateUrl: './user-menu.component.html', + styleUrls: ['./user-menu.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class UserMenuComponent implements OnInit { + displayName$: Observable<{ firstName: string; initials: string }>; + @Input() + actionRef: ContentActionRef; + @Input() + data: { items: any[] }; + + constructor( + private peopleContentService: PeopleContentService, + private identityUserService: IdentityUserService, + private authService: AuthenticationService + ) {} + + ngOnInit() { + this.getUserInfo(); + if (this.data && this.data.items) { + this.data.items.sort((a, b) => a.order - b.order); + } + } + + getUserInfo() { + if (this.authService.isOauth()) { + this.loadIdentityUserInfo(); + + if (this.authService.isECMProvider() && this.authService.isEcmLoggedIn()) { + this.loadEcmUserInfo(); + } + } else if (this.isEcmLoggedIn()) { + this.loadEcmUserInfo(); + } + } + + get isLoggedIn(): boolean { + if (this.authService.isKerberosEnabled()) { + return true; + } + return this.authService.isLoggedIn(); + } + + private loadEcmUserInfo(): void { + this.displayName$ = this.peopleContentService.getCurrentUserInfo().pipe(map((model) => this.parseDisplayName(model))); + } + + private loadIdentityUserInfo() { + this.displayName$ = of(this.identityUserService.getCurrentUserInfo()).pipe(map((model) => this.parseDisplayName(model))); + } + + parseDisplayName(model: { firstName?: string; lastName?: string }): { firstName: string; initials: string } { + const result = { firstName: '', initials: '' }; + if (model.firstName) { + result.initials = model.firstName.charAt(0).toUpperCase(); + } + if (model.lastName) { + result.initials += model.lastName.charAt(0).toUpperCase(); + } + return result; + } + + private isEcmLoggedIn() { + return this.authService.isEcmLoggedIn() || (this.authService.isECMProvider() && this.authService.isKerberosEnabled()); + } +} diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss index 8489d71da3..8205b50c6f 100644 --- a/projects/aca-content/src/lib/ui/variables/variables.scss +++ b/projects/aca-content/src/lib/ui/variables/variables.scss @@ -37,6 +37,8 @@ $selected-background-color: rgba(31, 116, 219, 0.24); $action-button-text-color: rgba(33, 35, 40, 0.7); $page-layout-header-background-color: #fff; $aca-toolbar-button-background-color: rgba(33, 33, 33, 0.05); +$aca-user-initials-background: rgba(33, 33, 33, 0.12); +$aca-user-initials-text-color: #212121; // CSS Variables $defaults: ( @@ -81,7 +83,9 @@ $defaults: ( --theme-action-button-text-color: $action-button-text-color, --theme-header-border-color: $grey-background, --theme-page-layout-header-background-color: $page-layout-header-background-color, - --theme-app-toolbar-button-background-color: $aca-toolbar-button-background-color + --theme-app-toolbar-button-background-color: $aca-toolbar-button-background-color, + --theme-user-initials-background-color: $aca-user-initials-background, + --theme-user-intials-text-color: $aca-user-initials-text-color ); // propagates SCSS variables into the CSS variables scope From 0a78eeed57271bcb7f52ae10237a89cb5ee1958e Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Thu, 11 May 2023 18:04:49 +0000 Subject: [PATCH 2/5] modified spec file --- .../sidenav/user-menu/user-menu.component.spec.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.spec.ts b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.spec.ts index 9213d0f9c8..4b6c00ff34 100644 --- a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.spec.ts +++ b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.spec.ts @@ -126,22 +126,17 @@ describe('UserMenuComponent', () => { expect(result.initials).toEqual(''); }); - it('should return an object with the correct firstName and initials when the input model has only the firstName property', () => { + it('should return an object with the correct initials when the input model has only the firstName property', () => { const result = component.parseDisplayName({ firstName: 'John' }); expect(result.initials).toEqual('J'); }); - it('should return an object with the correct firstName and initials when the input model has only the lastName property', () => { + it('should return an object with the correct initials when the input model has only the lastName property', () => { const result = component.parseDisplayName({ lastName: 'Doe' }); expect(result.initials).toEqual('D'); }); - it('should return an object with the correct firstName, initials, and lastName concatenated when the input model has both firstName and lastName properties', () => { - const result = component.parseDisplayName({ firstName: 'John', lastName: 'Doe' }); - expect(result.initials).toEqual('JD'); - }); - - it('should return an object with all properties correctly parsed when the input model has all three properties', () => { + it('should return an object with the correct initials concatenated when the input model has both firstName and lastName properties', () => { const result = component.parseDisplayName({ firstName: 'John', lastName: 'Doe' }); expect(result.initials).toEqual('JD'); }); From f8ac71aab6e8ab81fa35603201cb37614caf44a3 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 12 May 2023 05:03:38 +0000 Subject: [PATCH 3/5] changes for config files --- .../context-submenus-ext.json | 65 ++++++---- .../document-presets-ext.json | 65 ++++++---- .../extensibility-configs/header-ext.json | 115 ++++++++++-------- .../info-drawer-ext.json | 65 ++++++---- .../info-drawer-no-tabs-ext.json | 65 ++++++---- .../extensibility-configs/metadata-ext.json | 65 ++++++---- .../extensibility-configs/viewer-ext.json | 65 ++++++---- .../src/components/header/header.ts | 2 +- 8 files changed, 299 insertions(+), 208 deletions(-) diff --git a/e2e/resources/extensibility-configs/context-submenus-ext.json b/e2e/resources/extensibility-configs/context-submenus-ext.json index 9c7df193fd..94bb45d022 100644 --- a/e2e/resources/extensibility-configs/context-submenus-ext.json +++ b/e2e/resources/extensibility-configs/context-submenus-ext.json @@ -46,39 +46,52 @@ "features": { "header": [ { - "id": "app.header.user", + "id": "app.header.notification-center", "type": "custom", - "component": "app.user", - "order": 100 + "component": "app.notification-center", + "order": 50 }, { "id": "app.header.more", - "type": "menu", + "type": "custom", "order": 10000, - "icon": "more_vert", + "component": "app.user.menu", "title": "APP.ACTIONS.MORE", - "children": [ - { - "id": "app.languagePicker", - "order": 100, - "type": "custom", - "component": "app.languagePicker" - }, - { - "id": "logout.separator", - "type": "separator", - "order": 199 - }, - { - "id": "app.logout", - "order": 200, - "type": "custom", - "component": "app.logout", - "rules": { - "visible": "app.canShowLogout" + "data": { + "items": [ + { + "id": "app.header.user", + "type": "custom", + "component": "app.user", + "order": 100 + }, + { + "id": "user.separator", + "type": "separator", + "order": 100 + }, + { + "id": "app.languagePicker", + "order": 100, + "type": "custom", + "component": "app.languagePicker" + }, + { + "id": "logout.separator", + "type": "separator", + "order": 199 + }, + { + "id": "app.logout", + "order": 200, + "type": "custom", + "component": "app.logout", + "rules": { + "visible": "app.canShowLogout" + } } - } - ] + ] + } } ], "icons": [ diff --git a/e2e/resources/extensibility-configs/document-presets-ext.json b/e2e/resources/extensibility-configs/document-presets-ext.json index 3dcb666764..fc3ab4bbce 100644 --- a/e2e/resources/extensibility-configs/document-presets-ext.json +++ b/e2e/resources/extensibility-configs/document-presets-ext.json @@ -46,39 +46,52 @@ "features": { "header": [ { - "id": "app.header.user", + "id": "app.header.notification-center", "type": "custom", - "component": "app.user", - "order": 100 + "component": "app.notification-center", + "order": 50 }, { "id": "app.header.more", - "type": "menu", + "type": "custom", "order": 10000, - "icon": "more_vert", + "component": "app.user.menu", "title": "APP.ACTIONS.MORE", - "children": [ - { - "id": "app.languagePicker", - "order": 100, - "type": "custom", - "component": "app.languagePicker" - }, - { - "id": "logout.separator", - "type": "separator", - "order": 199 - }, - { - "id": "app.logout", - "order": 200, - "type": "custom", - "component": "app.logout", - "rules": { - "visible": "app.canShowLogout" + "data": { + "items": [ + { + "id": "app.header.user", + "type": "custom", + "component": "app.user", + "order": 100 + }, + { + "id": "user.separator", + "type": "separator", + "order": 100 + }, + { + "id": "app.languagePicker", + "order": 100, + "type": "custom", + "component": "app.languagePicker" + }, + { + "id": "logout.separator", + "type": "separator", + "order": 199 + }, + { + "id": "app.logout", + "order": 200, + "type": "custom", + "component": "app.logout", + "rules": { + "visible": "app.canShowLogout" + } } - } - ] + ] + } } ], "icons": [ diff --git a/e2e/resources/extensibility-configs/header-ext.json b/e2e/resources/extensibility-configs/header-ext.json index fb9aa267ba..5b5ea0efa7 100644 --- a/e2e/resources/extensibility-configs/header-ext.json +++ b/e2e/resources/extensibility-configs/header-ext.json @@ -46,66 +46,79 @@ "features": { "header": [ { - "id": "app.header.user", + "id": "app.header.notification-center", "type": "custom", - "component": "app.user", - "order": 100 + "component": "app.notification-center", + "order": 50 }, { "id": "app.header.more", - "type": "menu", + "type": "custom", "order": 10000, - "icon": "more_vert", + "component": "app.user.menu", "title": "APP.ACTIONS.MORE", - "children": [ - { - "id": "app.languagePicker", - "order": 100, - "type": "custom", - "component": "app.languagePicker" - }, - { - "id": "logout.separator", - "type": "separator", - "order": 199 - }, - { - "id": "settings", - "title": "App settings", - "description": "Application settings", - "icon": "settings", - "disabled": true, - "order": 10, - "actions": { - "click": "app.actions.settings" + "data": { + "items": [ + { + "id": "app.header.user", + "type": "custom", + "component": "app.user", + "order": 100 }, - "rules": { - "visible": "app.navigation.isNotTrashcan" - } - }, - { - "id": "button", - "title": "New Button", - "description": "new button description", - "icon": "alarm_on", - "order": 20, - "actions": { - "click": "app.actions.settings" + { + "id": "user.separator", + "type": "separator", + "order": 100 }, - "rules": { - "visible": "app.navigation.isNotTrashcan" - } - }, - { - "id": "app.logout", - "order": 200, - "type": "custom", - "component": "app.logout", - "rules": { - "visible": "app.canShowLogout" + { + "id": "app.languagePicker", + "order": 100, + "type": "custom", + "component": "app.languagePicker" + }, + { + "id": "settings", + "title": "App settings", + "description": "Application settings", + "icon": "settings", + "disabled": true, + "order": 10, + "actions": { + "click": "app.actions.settings" + }, + "rules": { + "visible": "app.navigation.isNotTrashcan" + } + }, + { + "id": "button", + "title": "New Button", + "description": "new button description", + "icon": "alarm_on", + "order": 20, + "actions": { + "click": "app.actions.settings" + }, + "rules": { + "visible": "app.navigation.isNotTrashcan" + } + }, + { + "id": "logout.separator", + "type": "separator", + "order": 199 + }, + { + "id": "app.logout", + "order": 200, + "type": "custom", + "component": "app.logout", + "rules": { + "visible": "app.canShowLogout" + } } - } - ] + ] + } } ], "icons": [ diff --git a/e2e/resources/extensibility-configs/info-drawer-ext.json b/e2e/resources/extensibility-configs/info-drawer-ext.json index 89da3b859a..f032057213 100644 --- a/e2e/resources/extensibility-configs/info-drawer-ext.json +++ b/e2e/resources/extensibility-configs/info-drawer-ext.json @@ -46,39 +46,52 @@ "features": { "header": [ { - "id": "app.header.user", + "id": "app.header.notification-center", "type": "custom", - "component": "app.user", - "order": 100 + "component": "app.notification-center", + "order": 50 }, { "id": "app.header.more", - "type": "menu", + "type": "custom", "order": 10000, - "icon": "more_vert", + "component": "app.user.menu", "title": "APP.ACTIONS.MORE", - "children": [ - { - "id": "app.languagePicker", - "order": 100, - "type": "custom", - "component": "app.languagePicker" - }, - { - "id": "logout.separator", - "type": "separator", - "order": 199 - }, - { - "id": "app.logout", - "order": 200, - "type": "custom", - "component": "app.logout", - "rules": { - "visible": "app.canShowLogout" + "data": { + "items": [ + { + "id": "app.header.user", + "type": "custom", + "component": "app.user", + "order": 100 + }, + { + "id": "user.separator", + "type": "separator", + "order": 100 + }, + { + "id": "app.languagePicker", + "order": 100, + "type": "custom", + "component": "app.languagePicker" + }, + { + "id": "logout.separator", + "type": "separator", + "order": 199 + }, + { + "id": "app.logout", + "order": 200, + "type": "custom", + "component": "app.logout", + "rules": { + "visible": "app.canShowLogout" + } } - } - ] + ] + } } ], "icons": [ diff --git a/e2e/resources/extensibility-configs/info-drawer-no-tabs-ext.json b/e2e/resources/extensibility-configs/info-drawer-no-tabs-ext.json index 0cd68e1216..d50b8d7840 100644 --- a/e2e/resources/extensibility-configs/info-drawer-no-tabs-ext.json +++ b/e2e/resources/extensibility-configs/info-drawer-no-tabs-ext.json @@ -46,39 +46,52 @@ "features": { "header": [ { - "id": "app.header.user", + "id": "app.header.notification-center", "type": "custom", - "component": "app.user", - "order": 100 + "component": "app.notification-center", + "order": 50 }, { "id": "app.header.more", - "type": "menu", + "type": "custom", "order": 10000, - "icon": "more_vert", + "component": "app.user.menu", "title": "APP.ACTIONS.MORE", - "children": [ - { - "id": "app.languagePicker", - "order": 100, - "type": "custom", - "component": "app.languagePicker" - }, - { - "id": "logout.separator", - "type": "separator", - "order": 199 - }, - { - "id": "app.logout", - "order": 200, - "type": "custom", - "component": "app.logout", - "rules": { - "visible": "app.canShowLogout" + "data": { + "items": [ + { + "id": "app.header.user", + "type": "custom", + "component": "app.user", + "order": 100 + }, + { + "id": "user.separator", + "type": "separator", + "order": 100 + }, + { + "id": "app.languagePicker", + "order": 100, + "type": "custom", + "component": "app.languagePicker" + }, + { + "id": "logout.separator", + "type": "separator", + "order": 199 + }, + { + "id": "app.logout", + "order": 200, + "type": "custom", + "component": "app.logout", + "rules": { + "visible": "app.canShowLogout" + } } - } - ] + ] + } } ], "icons": [ diff --git a/e2e/resources/extensibility-configs/metadata-ext.json b/e2e/resources/extensibility-configs/metadata-ext.json index 31b94c3ec3..ea508fdd50 100644 --- a/e2e/resources/extensibility-configs/metadata-ext.json +++ b/e2e/resources/extensibility-configs/metadata-ext.json @@ -46,39 +46,52 @@ "features": { "header": [ { - "id": "app.header.user", + "id": "app.header.notification-center", "type": "custom", - "component": "app.user", - "order": 100 + "component": "app.notification-center", + "order": 50 }, { "id": "app.header.more", - "type": "menu", + "type": "custom", "order": 10000, - "icon": "more_vert", + "component": "app.user.menu", "title": "APP.ACTIONS.MORE", - "children": [ - { - "id": "app.languagePicker", - "order": 100, - "type": "custom", - "component": "app.languagePicker" - }, - { - "id": "logout.separator", - "type": "separator", - "order": 199 - }, - { - "id": "app.logout", - "order": 200, - "type": "custom", - "component": "app.logout", - "rules": { - "visible": "app.canShowLogout" + "data": { + "items": [ + { + "id": "app.header.user", + "type": "custom", + "component": "app.user", + "order": 100 + }, + { + "id": "user.separator", + "type": "separator", + "order": 100 + }, + { + "id": "app.languagePicker", + "order": 100, + "type": "custom", + "component": "app.languagePicker" + }, + { + "id": "logout.separator", + "type": "separator", + "order": 199 + }, + { + "id": "app.logout", + "order": 200, + "type": "custom", + "component": "app.logout", + "rules": { + "visible": "app.canShowLogout" + } } - } - ] + ] + } } ], "icons": [ diff --git a/e2e/resources/extensibility-configs/viewer-ext.json b/e2e/resources/extensibility-configs/viewer-ext.json index 0dc53e075c..be6702d8ec 100644 --- a/e2e/resources/extensibility-configs/viewer-ext.json +++ b/e2e/resources/extensibility-configs/viewer-ext.json @@ -46,39 +46,52 @@ "features": { "header": [ { - "id": "app.header.user", + "id": "app.header.notification-center", "type": "custom", - "component": "app.user", - "order": 100 + "component": "app.notification-center", + "order": 50 }, { "id": "app.header.more", - "type": "menu", + "type": "custom", "order": 10000, - "icon": "more_vert", + "component": "app.user.menu", "title": "APP.ACTIONS.MORE", - "children": [ - { - "id": "app.languagePicker", - "order": 100, - "type": "custom", - "component": "app.languagePicker" - }, - { - "id": "logout.separator", - "type": "separator", - "order": 199 - }, - { - "id": "app.logout", - "order": 200, - "type": "custom", - "component": "app.logout", - "rules": { - "visible": "app.canShowLogout" + "data": { + "items": [ + { + "id": "app.header.user", + "type": "custom", + "component": "app.user", + "order": 100 + }, + { + "id": "user.separator", + "type": "separator", + "order": 100 + }, + { + "id": "app.languagePicker", + "order": 100, + "type": "custom", + "component": "app.languagePicker" + }, + { + "id": "logout.separator", + "type": "separator", + "order": 199 + }, + { + "id": "app.logout", + "order": 200, + "type": "custom", + "component": "app.logout", + "rules": { + "visible": "app.canShowLogout" + } } - } - ] + ] + } } ], "icons": [ diff --git a/projects/aca-testing-shared/src/components/header/header.ts b/projects/aca-testing-shared/src/components/header/header.ts index bd98cd1690..da2a2e422a 100755 --- a/projects/aca-testing-shared/src/components/header/header.ts +++ b/projects/aca-testing-shared/src/components/header/header.ts @@ -33,7 +33,7 @@ import { BrowserActions } from '@alfresco/adf-testing'; export class Header extends Component { logoLink = this.byCss('.app-menu__title'); - moreActions = browser.element(by.id('app.header.more')); + moreActions = this.byCss(`.aca-user-menu-button`); sidenavToggle = this.byCss(`.sidenav-header-title-logo`); userInfo = new UserInfo(); From 2b4ae0ff10e2781c5b9be53b70206df0b322fabd Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 12 May 2023 12:27:44 +0000 Subject: [PATCH 4/5] class name renamed --- .../lib/components/sidenav/user-menu/user-menu.component.html | 2 +- projects/aca-testing-shared/src/components/header/header.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html index 67c4e9d644..801d986846 100644 --- a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html +++ b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html @@ -1,4 +1,4 @@ - diff --git a/projects/aca-testing-shared/src/components/header/header.ts b/projects/aca-testing-shared/src/components/header/header.ts index da2a2e422a..dbc0f6e377 100755 --- a/projects/aca-testing-shared/src/components/header/header.ts +++ b/projects/aca-testing-shared/src/components/header/header.ts @@ -33,7 +33,7 @@ import { BrowserActions } from '@alfresco/adf-testing'; export class Header extends Component { logoLink = this.byCss('.app-menu__title'); - moreActions = this.byCss(`.aca-user-menu-button`); + moreActions = this.byCss(`.userMenuButton`); sidenavToggle = this.byCss(`.sidenav-header-title-logo`); userInfo = new UserInfo(); From c596c1b7cf01f526e9fc0af0a7c53ec7f440b1ab Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Mon, 15 May 2023 04:45:53 +0000 Subject: [PATCH 5/5] implemented the review comments --- .../components/common/user-info/user-info.component.spec.ts | 2 +- .../components/sidenav/user-menu/user-menu.component.html | 2 +- projects/aca-testing-shared/src/components/header/header.ts | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/projects/aca-content/src/lib/components/common/user-info/user-info.component.spec.ts b/projects/aca-content/src/lib/components/common/user-info/user-info.component.spec.ts index 11543c9863..73e33247b9 100644 --- a/projects/aca-content/src/lib/components/common/user-info/user-info.component.spec.ts +++ b/projects/aca-content/src/lib/components/common/user-info/user-info.component.spec.ts @@ -29,7 +29,7 @@ import { UserInfoComponent } from './user-info.component'; import { AppTestingModule } from '../../../testing/app-testing.module'; import { of } from 'rxjs'; -describe('parseDisplayName', () => { +describe('UserInfoComponent', () => { let component: UserInfoComponent; let fixture: ComponentFixture; let authServiceStub: Partial; diff --git a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html index 801d986846..67c4e9d644 100644 --- a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html +++ b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.html @@ -1,4 +1,4 @@ - diff --git a/projects/aca-testing-shared/src/components/header/header.ts b/projects/aca-testing-shared/src/components/header/header.ts index dbc0f6e377..b7394da566 100755 --- a/projects/aca-testing-shared/src/components/header/header.ts +++ b/projects/aca-testing-shared/src/components/header/header.ts @@ -33,7 +33,7 @@ import { BrowserActions } from '@alfresco/adf-testing'; export class Header extends Component { logoLink = this.byCss('.app-menu__title'); - moreActions = this.byCss(`.userMenuButton`); + userMenuButton = this.byCss(`.aca-user-menu-button`); sidenavToggle = this.byCss(`.sidenav-header-title-logo`); userInfo = new UserInfo(); @@ -46,12 +46,12 @@ export class Header extends Component { } async openMoreMenu(): Promise { - await BrowserActions.click(this.moreActions); + await BrowserActions.click(this.userMenuButton); await this.menu.waitForMenuToOpen(); } async closeMoreMenu(): Promise { - await BrowserActions.click(this.moreActions); + await BrowserActions.click(this.userMenuButton); await this.menu.waitForMenuToClose(); }