[AAE-10668] - Fix [object Object] for License entitlements in Admin App's About page (#7862)

* [AAE-10668] Fixed [object object] issue for the entitlements field of the license section in the about page

* Added string manipulation functionality

* Removed lock file from commit

* [AAE-10668] resolved changes requested

* [AAE-10668] changes to ObjectUtils booleanPrettify method

* [AAE-10668] Fixed import statements

* [AAE-10668] fixed lint problems

Co-authored-by: Diogo Bastos <Diogo.Bastos@apl-y6rr6vv7yk.home>
This commit is contained in:
Diogo Bastos
2022-09-28 10:33:03 +01:00
committed by GitHub
parent cff311897d
commit 1156a9f9b8
9 changed files with 326 additions and 5 deletions

View File

@@ -3,7 +3,7 @@
<mat-header-cell *matHeaderCellDef>
{{ column.header | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let row">{{ column.cell(row) }}</mat-cell>
<mat-cell *matCellDef="let row" [innerHTML]="column.cell(row)"></mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>

View File

@@ -0,0 +1,4 @@
mat-cell {
white-space: pre-line;
line-height: 30px;
}

View File

@@ -21,6 +21,7 @@ import { LicenseData } from '../interfaces';
@Component({
selector: 'adf-about-license-list',
templateUrl: './about-license-list.component.html',
styleUrls: ['./about-license-list.component.scss'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
})

View File

@@ -25,6 +25,8 @@ import { BpmProductVersionModel } from '../models/product-version.model';
import { AuthenticationService } from '../services/authentication.service';
import { DiscoveryApiService } from '../services/discovery-api.service';
import { LicenseData, PackageInfo, StatusData } from './interfaces';
import { ObjectUtils } from '../utils/object-utils';
import { StringUtils } from '../utils/string-utils';
@Component({
selector: 'adf-about',
@@ -101,10 +103,19 @@ export class AboutComponent implements OnInit {
}));
if (repository.license) {
this.licenseEntries = Object.keys(repository.license).map((key) => ({
this.licenseEntries = Object.keys(repository.license).map((key) => {
if (ObjectUtils.isObject(repository.license[key])) {
return {
property: key,
value: ObjectUtils.booleanPrettify(repository.license[key], StringUtils.prettifyBooleanEnabled)
};
};
return {
property: key,
value: repository.license[key]
}));
};
});
}
});
}

View File

@@ -130,4 +130,120 @@ describe('ObjectUtils', () => {
});
});
});
describe('isObject', () => {
it('should return false for null and undefined types', () => {
expect(ObjectUtils.isObject(null)).toBe(false);
expect(ObjectUtils.isObject(undefined)).toBe(false);
});
it('should return false for non object types', () => {
const numberTest = 1;
const stringTest = 'test';
expect(ObjectUtils.isObject(numberTest)).toBe(false);
expect(ObjectUtils.isObject(stringTest)).toBe(false);
});
it('should return true for object types', () => {
const obj = {
id: 1
};
const date = new Date();
expect(ObjectUtils.isObject(obj)).toBe(true);
expect(ObjectUtils.isObject(date)).toBe(true);
});
});
describe('isEmpty', () => {
it('should return true for empty objects', () => {
const emptyObj = {};
expect(ObjectUtils.isEmpty(emptyObj)).toBe(true);
});
it('should return false for non empty objects', () => {
const obj = {
id: 1
};
const date = new Date();
expect(ObjectUtils.isEmpty(obj)).toBe(false);
expect(ObjectUtils.isEmpty(date)).toBe(false);
});
});
describe('isBooleanObject', () => {
it('should return true for objects with all bollean values', () => {
const obj = {
testOne: true,
testTwo: false
};
expect(ObjectUtils.isBooleanObject(obj)).toBe(true);
});
it('should return false for objects with at least one non boolean value', () => {
const objOne = {
testOne: true,
testTwo: 1
};
const objTwo = {
testOne: 1,
testTwo: 2
};
expect(ObjectUtils.isBooleanObject(objOne)).toBe(false);
expect(ObjectUtils.isBooleanObject(objTwo)).toBe(false);
});
});
describe('booleanPrettify', () => {
it('should return empty string for empty types', () => {
expect(ObjectUtils.booleanPrettify(null)).toBe('');
expect(ObjectUtils.booleanPrettify(undefined)).toBe('');
});
it('should return string if not object', () => {
const numberTest = 1;
expect(ObjectUtils.booleanPrettify(numberTest)).toBe(numberTest.toString());
});
it('should return empty string for empty objects', () => {
const obj = {};
expect(ObjectUtils.booleanPrettify(obj)).toBe('');
});
it('should return string for objects with no keys', () => {
const date = new Date();
expect(ObjectUtils.booleanPrettify(date)).toBe(date.toString());
});
it('should return empty string for objects containing non boolean values', () => {
const nonBooleanObjOne = {
testOne: 1,
testTwo: 2
};
const nonBooleanObjTwo = {
testOne: 1,
testTwo: false
};
expect(ObjectUtils.booleanPrettify(nonBooleanObjOne)).toBe('');
expect(ObjectUtils.booleanPrettify(nonBooleanObjTwo)).toBe('');
});
it('should return string with either &#9989 or &#10060 symbols if object with boolean values', () => {
const obj = {
testOne: true,
testTwo: false
};
expect(ObjectUtils.booleanPrettify(obj)).toBe('&#9989 testOne\n&#10060 testTwo');
});
it('should return enhanced string with either &#9989 or &#10060 symbols if object with boolean values', () => {
const obj = {
testOne: true,
testTwo: false
};
const enhancer = (e: string) => e + 'test';
expect(ObjectUtils.booleanPrettify(obj, enhancer)).toBe('&#9989 testOnetest\n&#10060 testTwotest');
});
});
});

View File

@@ -65,4 +65,61 @@ export class ObjectUtils {
return result;
}
static isObject(target: any): boolean {
return target === Object(target);
}
static isEmpty(target: any): boolean {
return target && Object.keys(target).length === 0 && Object.getPrototypeOf(target) === Object.prototype;
}
static hasKeys(target: any): boolean {
return target && Object.keys(target).length > 0;
}
static isBooleanObject(target: any): boolean {
return Object.values(target).every(value => typeof value === 'boolean');
}
static booleanPrettify(target: any, enhancer?: (param: string) => string): string {
if (
!target ||
ObjectUtils.isEmpty(target) ||
!ObjectUtils.isBooleanObject(target)
) {
return '';
}
if (
!ObjectUtils.isObject(target) ||
!ObjectUtils.hasKeys(target)
) {
return target.toString();
}
const greenBorderWhiteCheckSymbol = '&#9989';
const redCrossSymbol = '&#10060';
target = Object.keys(target).map((key) => {
if (target[key]) {
if (enhancer) {
return `${greenBorderWhiteCheckSymbol} ${enhancer(key)}`;
} else {
return `${greenBorderWhiteCheckSymbol} ${key}`;
}
}
if (enhancer) {
return `${redCrossSymbol} ${enhancer(key)}`;
} else {
return `${redCrossSymbol} ${key}`;
}
}).join('\n');
return target;
}
}

View File

@@ -19,3 +19,4 @@ export * from './object-utils';
export * from './file-utils';
export * from './moment-date-formats.model';
export * from './moment-date-adapter';
export * from './string-utils';

View File

@@ -0,0 +1,75 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* 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.
*/
import { StringUtils } from './string-utils';
describe('StringUtils', () => {
describe('capitalize', () => {
it('should uppercase first letter of word and lowercase the rest', () => {
const lowercaseWord = 'test';
const uppercaseWord = 'TEST';
const mixedWord = 'tEsT';
expect(StringUtils.capitalize(lowercaseWord)).toBe('Test');
expect(StringUtils.capitalize(uppercaseWord)).toBe('Test');
expect(StringUtils.capitalize(mixedWord)).toBe('Test');
});
it('should uppercase first letter of first word in sentence and lowercase the rest', () => {
const sentence = 'this is a sentence';
expect(StringUtils.capitalize(sentence)).toBe('This is a sentence');
});
});
describe('replaceAll', () => {
it('should replace all instances provided in the delimiters obj', () => {
const test = 'isClusterEnabled';
const delimiters = {
is: 'are',
Enabled: 'Disabled'
};
expect(StringUtils.replaceAll(test, delimiters)).toBe('areClusterDisabled');
});
it('should return initial string if delimiters is not an oject', () => {
const test = 'isClusterEnabled';
const delimiters = 'test';
expect(StringUtils.replaceAll(test, delimiters)).toBe('isClusterEnabled');
});
});
describe('removeAll', () => {
it('should remove all instances described in demiliters arguments in string', () => {
const test = 'isClusterEnabled';
const delimiters = ['is', 'Enabled'];
expect(StringUtils.removeAll(test, ...delimiters)).toBe('Cluster');
});
});
describe('prettifyBooleanEnabled', () => {
it('should remove "is" and "enabled" from strings', () => {
const test = 'isClusterEnabled';
expect(StringUtils.prettifyBooleanEnabled(test)).toBe('Cluster');
});
});
});

View File

@@ -0,0 +1,56 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* 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.
*/
import { ObjectUtils } from './object-utils';
export class StringUtils {
static capitalize(target: string): string {
return target.charAt(0).toUpperCase() + target.slice(1).toLowerCase();
}
static replaceAll(target: string, delimiters: any): string {
if (!ObjectUtils.isObject(delimiters)) {
return target;
}
Object.keys(delimiters).forEach((key) => {
target = target.replace(key, delimiters[key]);
});
return target;
}
static removeAll(target: string, ...delimiters: string[]): string {
const delimiterObj = {};
delimiters.forEach(delimiter => {
delimiterObj[delimiter] = '';
});
return StringUtils.replaceAll(target, delimiterObj);
}
static prettifyBooleanEnabled(target: string): string {
const redactedTarget = StringUtils.removeAll(target.toLowerCase(), 'is', 'enabled');
const bagOfWords = redactedTarget.split(' ');
const capitalizedBagOfWords = bagOfWords.map((word) => StringUtils.capitalize(word));
return capitalizedBagOfWords.join(' ');
}
}