From b17cefe6dcdab7eeb56b29442374636d2829b7ec Mon Sep 17 00:00:00 2001 From: Pablo Martinez Garcia Date: Wed, 9 Aug 2023 16:03:10 +0200 Subject: [PATCH] [AAE-15836] Include email in full name pipe if required --- docs/core/pipes/full-name.pipe.md | 16 ++ .../pipes/full-name-email-required.token.ts | 23 +++ lib/core/src/lib/pipes/full-name.pipe.spec.ts | 178 +++++++++++++++--- lib/core/src/lib/pipes/full-name.pipe.ts | 44 ++++- .../src/lib/pipes/multi-value.pipe.spec.ts | 2 +- lib/core/src/lib/pipes/public-api.ts | 1 + 6 files changed, 228 insertions(+), 36 deletions(-) create mode 100644 lib/core/src/lib/pipes/full-name-email-required.token.ts diff --git a/docs/core/pipes/full-name.pipe.md b/docs/core/pipes/full-name.pipe.md index 4e793c477b..d4cc7b9404 100644 --- a/docs/core/pipes/full-name.pipe.md +++ b/docs/core/pipes/full-name.pipe.md @@ -9,6 +9,8 @@ Last reviewed: 2018-11-12 Joins the first and last name properties from a [`UserProcessModel`](../../core/models/user-process.model.md) object into a single string. +Optionally it can include the email of the users (if available). + ## Basic Usage @@ -21,10 +23,24 @@ Joins the first and last name properties from a [`UserProcessModel`](../../core/ +## Include the email of the user + + + +```HTML +
+ Project Leader: {{ user | fullName: true }} +
+``` + + + ## Details The pipe offers a convenient way to extract the name from a [User process model](../models/user-process.model.md) object. +If you want to include also the email of the user (when available) by default for your whole application, then you need to provide the injection token `ADF_FULL_NAME_PIPE_INCLUDE_EMAIL` in your angular application module with `true` value. + ## See also - [User initial pipe](user-initial.pipe.md) diff --git a/lib/core/src/lib/pipes/full-name-email-required.token.ts b/lib/core/src/lib/pipes/full-name-email-required.token.ts new file mode 100644 index 0000000000..7b2ecedbce --- /dev/null +++ b/lib/core/src/lib/pipes/full-name-email-required.token.ts @@ -0,0 +1,23 @@ +/*! + * @license + * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* eslint-disable rxjs/no-subject-value */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import { InjectionToken } from '@angular/core'; + +export const ADF_FULL_NAME_PIPE_INCLUDE_EMAIL = new InjectionToken('ADF_FULL_NAME_PIPE_INCLUDE_EMAIL'); diff --git a/lib/core/src/lib/pipes/full-name.pipe.spec.ts b/lib/core/src/lib/pipes/full-name.pipe.spec.ts index cb45540138..9bd372107e 100644 --- a/lib/core/src/lib/pipes/full-name.pipe.spec.ts +++ b/lib/core/src/lib/pipes/full-name.pipe.spec.ts @@ -16,42 +16,168 @@ */ import { FullNamePipe } from './full-name.pipe'; +import { UserLike } from './user-like.interface'; + +interface TestCases { + [key: string]: { + title: string; + includeEmailToken: boolean | undefined; + includeEmailParameter: boolean | undefined; + testCases: TestCase[]; + }; +}; + +interface TestCase { + title: string; + user: UserLike; + result: string; +}; describe('FullNamePipe', () => { let pipe: FullNamePipe; - beforeEach(() => { - pipe = new FullNamePipe(); - }); + const cosntBaseTestCases: TestCase[] = [ + { + title: 'should return empty string when there is no name', + user: { firstName: '', lastName: '', username: '', email: '' }, + result: '' + }, + { + title: 'should return only firstName as fullName when there is no lastName', + user: { firstName: 'Abc', lastName: '', username: '', email: '' }, + result: 'Abc' + }, + { + title: 'should return only lastName as fullName when there is no firstName', + user: { firstName: '', lastName: 'Xyz', username: '', email: '' }, + result: 'Xyz' + }, + { + title: 'should return fullName when firstName and lastName are available', + user: { firstName: 'Abc', lastName: 'Xyz', username: '', email: '' }, + result: 'Abc Xyz' + }, + { + title: 'should return username when firstName and lastName are not available', + user: { firstName: '', lastName: '', username: 'username', email: '' }, + result: 'username' + }, + { + title: 'should return user email when firstName, lastName and username are not available', + user: { firstName: '', lastName: '', username: '', email: 'abcXyz@gmail.com' }, + result: 'abcXyz@gmail.com' + } + ]; - it('should return empty string when there is no name', () => { - const user = {}; - expect(pipe.transform(user)).toBe(''); - }); + function patchEmailAddress(testCase: TestCase): TestCase { + return { + ...testCase, + user: { ...testCase.user, email: 'abcXyz@gmail.com' } + }; + } - it('should return only firstName as fullName when there is no lastName ', () => { - const user = {firstName : 'Abc'}; - expect(pipe.transform(user)).toBe('Abc'); - }); + function patchEmailResult(testCase: TestCase): TestCase { + return { + ...testCase, + result: testCase.result + ' ' + }; + } - it('should return only lastName as fullName when there is no firstName ', () => { - const user = {lastName : 'Xyz'}; - expect(pipe.transform(user)).toBe('Xyz'); - }); + function patchEmail(testCase: TestCase): TestCase { + return patchEmailResult(patchEmailAddress(testCase)); + } - it('should return fullName when firstName and lastName are available', () => { - const user = {firstName : 'Abc', lastName : 'Xyz'}; - expect(pipe.transform(user)).toBe('Abc Xyz'); - }); + function getTestCasesWithEmailPatched(): TestCase[] { + return cosntBaseTestCases.slice(1, cosntBaseTestCases.length - 1).map(testCase => patchEmail(testCase)).concat([{ + title: 'should return user email when firstName, lastName and username are not available', + user: { firstName: '', lastName: '', username: '', email: 'abcXyz@gmail.com' }, + result: 'abcXyz@gmail.com' + }]); + } - it('should return username when firstName and lastName are not available', () => { - const user = {firstName : '', lastName : '', username: 'username'}; - expect(pipe.transform(user)).toBe('username'); - }); + const testCases: TestCases = { + undefinedIncludeEmailTokenUndefinedIncludeEmailParameter: { + title: 'and include email token is undefined and include email is undefined', + includeEmailToken: undefined, + includeEmailParameter: undefined, + testCases: cosntBaseTestCases + }, + undefinedIncludeEmailTokenFalseIncludeEmailParameter: { + title: 'and include email token is undefined and include email is false', + includeEmailToken: undefined, + includeEmailParameter: false, + testCases: cosntBaseTestCases + }, + undefinedIncludeEmailTokenFTrueIncludeEmailParameter: { + title: 'and include email token is undefined and include email is true', + includeEmailToken: undefined, + includeEmailParameter: true, + testCases: getTestCasesWithEmailPatched() + }, + falseIncludeEmailTokenUndefinedIncludeEmailParameter: { + title: 'and include email token is false and include email is undefined', + includeEmailToken: false, + includeEmailParameter: undefined, + testCases: cosntBaseTestCases + }, + falseIncludeEmailTokenFalseIncludeEmailParameter: { + title: 'and include email token is false and include email is false', + includeEmailToken: false, + includeEmailParameter: false, + testCases: cosntBaseTestCases + }, + falseIncludeEmailTokenTrueIncludeEmailParameter: { + title: 'and include email token is false and include email is true', + includeEmailToken: false, + includeEmailParameter: true, + testCases: getTestCasesWithEmailPatched() + }, + trueIncludeEmailTokennUndefinedIncludeEmailParameterButEmailAddressNotPresent: { + title: 'and include email token is true and include email is undefined but email is not provided', + includeEmailToken: true, + includeEmailParameter: undefined, + testCases: cosntBaseTestCases.slice(0, cosntBaseTestCases.length - 1) + }, + trueIncludeEmailTokennFalseIncludeEmailParameterButEmailAddressNotPresent: { + title: 'and include email token is true and include email is false but email is not provided', + includeEmailToken: true, + includeEmailParameter: false, + testCases: cosntBaseTestCases.slice(0, cosntBaseTestCases.length - 1) + }, + trueIncludeEmailTokennTrueIncludeEmailParameterButEmailAddressNotPresent: { + title: 'and include email token is true and include email is true but email is not provided', + includeEmailToken: true, + includeEmailParameter: true, + testCases: cosntBaseTestCases.slice(0, cosntBaseTestCases.length - 1) + }, + trueIncludeEmailTokenUndefinedIncludeEmailParameterAndEmailAddressPresent: { + title: 'and include email token is true and include email is undefined and email is provided', + includeEmailToken: true, + includeEmailParameter: undefined, + testCases: getTestCasesWithEmailPatched() + }, + trueIncludeEmailTokenFalseIncludeEmailParameterAndEmailAddressPresent: { + title: 'and include email token is true and include email is false and email is provided', + includeEmailToken: true, + includeEmailParameter: false, + testCases: cosntBaseTestCases.slice(1, cosntBaseTestCases.length - 1).map(testCase => patchEmailAddress(testCase)) + }, + trueIncludeEmailTokenTrueIncludeEmailParameterAndEmailAddressPresent: { + title: 'and include email token is true and include email is true and email is provided', + includeEmailToken: true, + includeEmailParameter: true, + testCases: getTestCasesWithEmailPatched() + } + }; - it('should return user eamil when firstName, lastName and username are not available', () => { - const user = {firstName : '', lastName : '', username: '', email: 'abcXyz@gmail.com'}; - expect(pipe.transform(user)).toBe('abcXyz@gmail.com'); + Object.keys(testCases).forEach(block => { + const testCasesToExecute = testCases[block].testCases; + testCasesToExecute.forEach(testCase => { + it(`${testCase.title} ${testCases[block].title}`, () => { + pipe = new FullNamePipe(testCases[block].includeEmailToken); + expect(pipe.transform(testCase.user, testCases[block].includeEmailParameter)).toBe(testCase.result); + }); + }); }); }); diff --git a/lib/core/src/lib/pipes/full-name.pipe.ts b/lib/core/src/lib/pipes/full-name.pipe.ts index d2af5a3e52..69e5833314 100644 --- a/lib/core/src/lib/pipes/full-name.pipe.ts +++ b/lib/core/src/lib/pipes/full-name.pipe.ts @@ -15,26 +15,52 @@ * limitations under the License. */ -import { Pipe, PipeTransform } from '@angular/core'; +import { Inject, Optional, Pipe, PipeTransform } from '@angular/core'; import { UserLike } from './user-like.interface'; +import { ADF_FULL_NAME_PIPE_INCLUDE_EMAIL } from './full-name-email-required.token'; @Pipe({ name: 'fullName' }) export class FullNamePipe implements PipeTransform { - transform(user: UserLike): string { - return this.buildFullName(user) ? this.buildFullName(user) : this.buildFromUsernameOrEmail(user); + constructor(@Optional() @Inject(ADF_FULL_NAME_PIPE_INCLUDE_EMAIL) private includeEmail = false) { } - buildFullName(user: UserLike): string { + transform(user: UserLike, includeEmail: boolean | undefined): string { + return this.buildFullName(user, includeEmail) ? this.buildFullName(user, includeEmail) : this.buildFromUsernameOrEmail(user, includeEmail); + } + + private includeEmailInFullName(includeEmail: boolean | undefined) { + return includeEmail === undefined ? this.includeEmail : includeEmail; + } + + private buildFullName(user: UserLike, includeEmail: boolean | undefined): string { const fullName: string[] = []; + let hasName = false; - fullName.push(user?.firstName); - fullName.push(user?.lastName); + if (user?.firstName) { + hasName = true; + fullName.push(user?.firstName); + } - return fullName.join(' ').trim(); + if (user?.lastName) { + hasName = true; + fullName.push(user?.lastName); + } + + if (this.includeEmailInFullName(includeEmail) && hasName && user?.email) { + fullName.push(`<${user.email}>`); + } + + return fullName.join(' '); } - buildFromUsernameOrEmail(user: UserLike): string { - return (user?.username || user?.email) ?? '' ; + private buildFromUsernameOrEmail(user: UserLike, includeEmail: boolean | undefined): string { + let fullName = (user?.username || user?.email) ?? ''; + + if (this.includeEmailInFullName(includeEmail) && user.username && user.email) { + fullName += ` <${user.email}>`; + } + + return fullName; } } diff --git a/lib/core/src/lib/pipes/multi-value.pipe.spec.ts b/lib/core/src/lib/pipes/multi-value.pipe.spec.ts index 5977cb180a..527cb0afff 100644 --- a/lib/core/src/lib/pipes/multi-value.pipe.spec.ts +++ b/lib/core/src/lib/pipes/multi-value.pipe.spec.ts @@ -20,7 +20,7 @@ import { TestBed } from '@angular/core/testing'; import { CoreTestingModule } from '../testing/core.testing.module'; import { TranslateModule } from '@ngx-translate/core'; -describe('FullNamePipe', () => { +describe('MultiValuePipe', () => { let pipe: MultiValuePipe; diff --git a/lib/core/src/lib/pipes/public-api.ts b/lib/core/src/lib/pipes/public-api.ts index 1769d448eb..96c5aba1ef 100644 --- a/lib/core/src/lib/pipes/public-api.ts +++ b/lib/core/src/lib/pipes/public-api.ts @@ -32,3 +32,4 @@ export * from './moment-date.pipe'; export * from './moment-datetime.pipe'; export * from './filter-string.pipe'; export * from './filter-out-every-object-by-prop.pipe'; +export * from './full-name-email-required.token';