Improved ESLint configuration, integrated spellcheck and error fixes ()

* integrate cspell with eslint, improved configuration

* core: fix linting errors

* core: fix lint warnings

* content: lint fixes

* process service lint fixes

* lint: process services cloud

* lint: insights

* lint: extensions

* [ci:force] lint: cli fixes

* [ci:force] comment out dead code

* [ci:force] exclude dead code

* fix code and tests

* rollback some changes

* fix testing lib

* fix demo shell

* minor lint warning fixes

* minor lint fixes

* fix process services
This commit is contained in:
Denys Vuika 2023-09-26 13:46:53 +01:00 committed by GitHub
parent 8370a3de66
commit ef551a9c71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
134 changed files with 2436 additions and 2269 deletions
.eslintrc.jsangular.jsoncspell.json
demo-shell/src/app/components
lib
cli/scripts
content-services/src/lib
core
extensions/src/lib
insights/src/lib
process-services-cloud/src/lib/form/components

@ -1,4 +1,3 @@
path = require('path');
module.exports = {
root: true,
ignorePatterns: [
@ -11,20 +10,36 @@ module.exports = {
'**/scripts',
'**/docs'
],
plugins: ['@nrwl/nx'],
overrides: [
{
files: ['*.ts'],
parserOptions: {
project: [path.join(__dirname, 'tsconfig.json'), path.join(__dirname, 'e2e/tsconfig.e2e.json')],
project: ['tsconfig.json', 'e2e/tsconfig.e2e.json'],
createDefaultProgram: true
},
extends: [
'plugin:@nrwl/nx/typescript',
'plugin:@nrwl/nx/angular',
'plugin:@cspell/recommended',
'plugin:@angular-eslint/ng-cli-compat',
'plugin:@angular-eslint/ng-cli-compat--formatting-add-on',
'plugin:@angular-eslint/template/process-inline-templates'
],
plugins: ['eslint-plugin-unicorn', 'eslint-plugin-rxjs', 'ban', 'license-header'],
plugins: [
'eslint-plugin-unicorn',
'eslint-plugin-rxjs',
'prettier',
'ban',
'license-header',
'@cspell',
'eslint-plugin-import',
'@angular-eslint/eslint-plugin',
'@typescript-eslint'
],
rules: {
// Uncomment this to enable prettier checks as part of the ESLint
// 'prettier/prettier': 'error',
'ban/ban': [
'error',
{ name: 'eval', message: 'Calls to eval is not allowed.' },

@ -210,16 +210,6 @@
"demo-shell/**/*.html"
]
}
},
"spellcheck": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "npx cspell 'demo-shell/**/*.ts'"
}
]
}
}
}
},
@ -346,16 +336,6 @@
}
}
},
"spellcheck": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "npx cspell 'lib/core/**/*.ts'"
}
]
}
},
"stylelint": {
"executor": "nx:run-commands",
"options": {
@ -484,16 +464,6 @@
}
}
},
"spellcheck": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "npx cspell 'lib/content-services/**/*.ts'"
}
]
}
},
"stylelint": {
"executor": "nx:run-commands",
"options": {
@ -560,26 +530,6 @@
]
}
},
"spellcheck": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "npx cspell 'lib/process-services/**/*.ts'"
}
]
},
"stylelint": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "npx stylelint lib/process-services/**/*.scss --config stylelint-config.json"
}
]
}
}
},
"stylelint": {
"executor": "nx:run-commands",
"options": {
@ -699,16 +649,6 @@
]
}
},
"spellcheck": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "npx cspell 'lib/process-services-cloud/**/*.ts'"
}
]
}
},
"stylelint": {
"executor": "nx:run-commands",
"options": {
@ -775,16 +715,6 @@
]
}
},
"spellcheck": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "npx cspell 'lib/insights/**/*.ts'"
}
]
}
},
"stylelint": {
"executor": "nx:run-commands",
"options": {
@ -848,17 +778,6 @@
"lib/extensions/**/*.ts",
"lib/extensions/**/*.html"
]
},
"dependsOn": ["spellcheck"]
},
"spellcheck": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "npx cspell 'lib/extensions/**/*.ts'"
}
]
}
},
"npm-publish": {

@ -139,7 +139,8 @@
"webscript",
"Whitespaces",
"xdescribe",
"xsrf"
"xsrf",
"Undeployed"
],
"dictionaries": [
"html",

@ -53,7 +53,7 @@ export class CloudFiltersDemoComponent implements OnInit {
this.currentProcessFilter$ = this.cloudLayoutService.processFilter$;
let root = '';
if (this.route.snapshot && this.route.snapshot.firstChild) {
if (this.route.snapshot?.firstChild) {
root = this.route.snapshot.firstChild.url[0].path;
if (root === 'tasks') {
this.expandTaskFilter = true;

@ -41,7 +41,7 @@ export class CloudLayoutComponent implements OnInit {
this.appName = params.appName;
});
if (this.route.snapshot && this.route.snapshot.firstChild) {
if (this.route.snapshot?.firstChild) {
root = this.route.snapshot.firstChild.url[0].path;
}

@ -185,7 +185,7 @@ export class ProcessesCloudDemoComponent implements OnInit, OnDestroy {
}
private loadFilter(model: ProcessFilterCloudModel) {
if (model && model.appName && model.id) {
if (model?.appName && model.id) {
this.editedFilter = model;
}
}

@ -84,7 +84,7 @@ export class FileViewComponent implements OnInit {
if (id) {
this.nodeApiService.getNode(id).subscribe(
(node) => {
if (node && node.isFile) {
if (node?.isFile) {
this.isCommentEnabled = this.contentServices.hasPermissions(node, PermissionsEnum.NOT_CONSUMER) ||
this.contentServices.hasAllowableOperations(node, AllowableOperationsEnum.UPDATE);
this.nodeId = id;

@ -231,7 +231,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
showFile(event) {
const entry = event.value.entry;
if (entry && entry.isFile) {
if (entry?.isFile) {
this.preview.showResource(entry.id);
}
}
@ -296,7 +296,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
}
ngOnChanges(changes: SimpleChanges) {
if (changes.nodeResult && changes.nodeResult.currentValue) {
if (changes.nodeResult?.currentValue) {
this.nodeResult = changes.nodeResult.currentValue;
this.pagination = this.nodeResult.list.pagination;
}
@ -468,7 +468,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
if (selection && selection.length === 1) {
const entry = selection[0].entry;
if (entry && entry.isFolder) {
if (entry?.isFolder) {
return this.contentService.hasAllowableOperations(entry, 'update');
}
}
@ -570,7 +570,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
}
searchResultsHighlight(search: SearchEntry): string {
if (search && search.highlight) {
if (search?.highlight) {
return search.highlight.map((currentHighlight) => currentHighlight.snippets).join(', ');
}
return '';
@ -588,7 +588,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
const objectFromMap = {};
activeFilters.forEach((filter: FilterSearch) => {
let paramValue = null;
if (filter.value && filter.value.from && filter.value.to) {
if (filter.value?.from && filter.value.to) {
paramValue = `${filter.value.from}||${filter.value.to}`;
} else {
paramValue = filter.value;

@ -41,9 +41,9 @@ export class VersionManagerDialogAdapterComponent {
private containingDialog?: MatDialogRef<VersionManagerDialogAdapterComponent>
) {
this.contentEntry = data.contentEntry;
this.newFileVersion = data.hasOwnProperty('newFileVersion') ? data.newFileVersion : this.newFileVersion;
this.showComments = data.hasOwnProperty('showComments') ? data.showComments : this.showComments;
this.allowDownload = data.hasOwnProperty('allowDownload') ? data.allowDownload : this.allowDownload;
this.newFileVersion = Object.prototype.hasOwnProperty.call(data, 'newFileVersion') ? data.newFileVersion : this.newFileVersion;
this.showComments = Object.prototype.hasOwnProperty.call(data, 'showComments') ? data.showComments : this.showComments;
this.allowDownload = Object.prototype.hasOwnProperty.call(data, 'allowDownload') ? data.allowDownload : this.allowDownload;
}
uploadError(event: FileUploadErrorEvent) {

@ -124,7 +124,7 @@ export class ProcessListDemoComponent implements OnInit, OnDestroy {
}
isFormValid() {
return this.processListForm && this.processListForm.dirty && this.processListForm.valid;
return this.processListForm?.dirty && this.processListForm.valid;
}
resetProcessForm() {

@ -93,7 +93,7 @@ export class ProcessAttachmentsComponent implements OnInit, OnChanges, OnDestroy
}
isCompletedProcess(): boolean {
return this.processInstance && this.processInstance.ended !== undefined && this.processInstance.ended !== null;
return this.processInstance?.ended != null;
}
}

@ -180,7 +180,7 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
.subscribe(
(validateDynamicTableRowEvent: ValidateDynamicTableRowEvent) => {
const row: DynamicTableRow = validateDynamicTableRowEvent.row;
if (row && row.value && row.value.name === 'admin') {
if (row?.value && row.value.name === 'admin') {
validateDynamicTableRowEvent.summary.isValid = false;
validateDynamicTableRowEvent.summary.message = 'Sorry, wrong value. You cannot use "admin".';
validateDynamicTableRowEvent.preventDefault();

@ -92,7 +92,7 @@ export class TaskAttachmentsComponent implements OnInit, OnChanges, OnDestroy {
}
isCompletedTask(): boolean {
return this.taskDetails && this.taskDetails.endDate !== undefined && this.taskDetails.endDate !== null;
return this.taskDetails?.endDate != null;
}
}

@ -51,7 +51,7 @@ export class SearchFilterChipsComponent implements OnInit, OnDestroy {
.pipe(takeUntil(this.onDestroy$))
.subscribe(([params, searchConfig]) => {
this.updateSearchSetting(searchConfig);
this.searchedWord = params.hasOwnProperty(this.queryParamName) ? params[this.queryParamName] : null;
this.searchedWord = Object.prototype.hasOwnProperty.call(params, this.queryParamName) ? params[this.queryParamName] : null;
const query = this.formatSearchQuery(this.searchedWord, searchConfig['app:fields']);
if (query) {
this.queryBuilder.userQuery = query;
@ -87,7 +87,7 @@ export class SearchFilterChipsComponent implements OnInit, OnDestroy {
if (this.route) {
this.route.params.forEach((params: Params) => {
this.searchedWord = params.hasOwnProperty(this.queryParamName) ? params[this.queryParamName] : null;
this.searchedWord = Object.prototype.hasOwnProperty.call(params, this.queryParamName) ? params[this.queryParamName] : null;
if (this.searchedWord) {
this.queryBuilder.update();
} else {

@ -50,7 +50,7 @@ export class SearchResultComponent implements OnInit, OnDestroy {
combineLatest([this.route.params, this.queryBuilder.configUpdated])
.pipe(takeUntil(this.onDestroy$))
.subscribe(([params, searchConfig]) => {
this.searchedWord = params.hasOwnProperty(this.queryParamName) ? params[this.queryParamName] : null;
this.searchedWord = Object.prototype.hasOwnProperty.call(params, this.queryParamName) ? params[this.queryParamName] : null;
const query = this.formatSearchQuery(this.searchedWord, searchConfig['app:fields']);
if (query) {
this.queryBuilder.userQuery = query;
@ -86,7 +86,7 @@ export class SearchResultComponent implements OnInit, OnDestroy {
if (this.route) {
this.route.params.forEach((params: Params) => {
this.searchedWord = params.hasOwnProperty(this.queryParamName) ? params[this.queryParamName] : null;
this.searchedWord = Object.prototype.hasOwnProperty.call(params, this.queryParamName) ? params[this.queryParamName] : null;
if (this.searchedWord) {
this.queryBuilder.update();
} else {

@ -21,7 +21,7 @@ import { AppConfigService, AppConfigValues, StorageService, AlfrescoApiService,
import { ENTER } from '@angular/cdk/keycodes';
import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
export const HOST_REGEX = '^(http|https):\/\/.*[^/]$';
export const HOST_REGEX = '^(http|https)://.*[^/]$';
@Component({
providers: [{ provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: { floatLabel: 'always' } }],

@ -190,7 +190,7 @@ export class TaskListDemoComponent implements OnInit, OnDestroy {
}
isFormValid() {
return this.taskListForm && this.taskListForm.dirty && this.taskListForm.valid;
return this.taskListForm?.dirty && this.taskListForm.valid;
}
private getControl<T extends AbstractControl>(key: string): T {

@ -15,9 +15,9 @@
* limitations under the License.
*/
import { AlfrescoApi, NodesApi, UploadApi } from '@alfresco/js-api';
import { AlfrescoApi /*, NodesApi, UploadApi*/ } from '@alfresco/js-api';
import { argv, exit } from 'node:process';
import { Buffer } from 'node:buffer';
// import { Buffer } from 'node:buffer';
const program = require('commander');
import { logger } from './logger';
const MAX_RETRY = 3;
@ -71,7 +71,8 @@ async function checkEnv() {
}
}
// @ts-ignore
// TODO: https://alfresco.atlassian.net/browse/ACS-5873
/*
async function checkDiskSpaceFullEnv() {
logger.info(`Start Check disk full space`);
@ -108,6 +109,7 @@ async function checkDiskSpaceFullEnv() {
}
}
}
*/
function sleep(delay: number) {
const start = new Date().getTime();

@ -497,7 +497,7 @@ async function checkDescriptorExist(name: string): Promise<boolean> {
logger.info(`Check descriptor ${name} exist in the list `);
const descriptorList = await getDescriptors();
if (descriptorList && descriptorList.list && descriptorList.entries) {
if (descriptorList?.list && descriptorList.entries) {
for (const descriptor of descriptorList.list.entries) {
if (descriptor.entry.name === name) {
if (descriptor.entry.deployed === false) {

@ -56,24 +56,29 @@ async function initializeDefaultFiles() {
for (let j = 0; j < ACS_DEFAULT.files.length; j++) {
const fileInfo = ACS_DEFAULT.files[j];
switch (fileInfo.action) {
case 'UPLOAD':
case 'UPLOAD': {
await uploadFile(fileInfo.name, parentFolderId);
break;
case 'LOCK':
}
case 'LOCK': {
const fileToLock = await uploadFile(fileInfo.name, parentFolderId);
await lockFile(fileToLock.entry.id);
break;
case 'SHARE':
}
case 'SHARE': {
const fileToShare = await uploadFile(fileInfo.name, parentFolderId);
await shareFile(fileToShare.entry.id);
break;
case 'FAVORITE':
}
case 'FAVORITE': {
const fileToFav = await uploadFile(fileInfo.name, parentFolderId);
await favoriteFile(fileToFav.entry.id);
break;
default:
}
default: {
logger.error('No action found for file ', fileInfo.name, parentFolderId);
break;
}
}
}
}

@ -117,8 +117,8 @@ async function main() {
async function initializeDefaultApps() {
for (let x = 0; x < ACTIVITI_APPS.apps.length; x++) {
const appInfo = ACTIVITI_APPS.apps[x];
const isDefaultAppDepl = await isDefaultAppDeployed(appInfo.name);
if (isDefaultAppDepl !== undefined && !isDefaultAppDepl) {
const isDeployed = await isDefaultAppDeployed(appInfo.name);
if (isDeployed !== undefined && !isDeployed) {
const appDefinition = await importPublishApp(`${appInfo.name}`);
await deployApp(appDefinition.appDefinition.id);
} else {
@ -248,7 +248,7 @@ async function isDefaultAppDeployed(appName: string) {
try {
const runtimeAppDefinitionsApi = new RuntimeAppDefinitionsApi(alfrescoJsApi);
const availableApps = await runtimeAppDefinitionsApi.getAppDefinitions();
const defaultApp = availableApps.data && availableApps.data.filter(app => app.name && app.name.includes(appName));
const defaultApp = availableApps.data?.filter(app => app.name?.includes(appName));
return defaultApp && defaultApp.length > 0;
} catch (error) {
logger.error(`Aps app failed to import/Publish!`);
@ -262,8 +262,8 @@ async function importPublishApp(appName: string) {
const fileContent = createReadStream(pathFile);
try {
const appdefinitionsApi = new AppDefinitionsApi(alfrescoJsApi);
const result = await appdefinitionsApi.importAndPublishApp(fileContent, {renewIdmEntries: true});
const appDefinitionsApi = new AppDefinitionsApi(alfrescoJsApi);
const result = await appDefinitionsApi.importAndPublishApp(fileContent, {renewIdmEntries: true});
logger.info(`Aps app imported and published!`);
return result;
} catch (error) {
@ -398,7 +398,7 @@ async function authorizeUserToContentRepo(user: any) {
['application/json'],
['application/json']
);
logger.info(`Found ${content.data && content.data.length} contents`);
logger.info(`Found ${content.data?.length} contents`);
if (content.data) {
for (let i = 0; i < content.data.length; i++) {
if (content.data[i].authenticationType === 'basic') {

@ -63,6 +63,7 @@ export const deletePod = (args: KubeArgs) => {
export const getNamespaces = (): string[] => {
logger.info('Perform get namespaces name...');
const result = exec('kubectl', [`get`, `namespaces`, `-l`, `type=application`, `-o`, `name`], {});
// eslint-disable-next-line no-useless-escape
const namespaces = result.replace(/namespace[\/]+/g, '').split(/\r?\n/);
logger.info(`namespaces found: ${namespaces}`);
return namespaces;

@ -51,12 +51,12 @@ const missingRepositories = {
function licenseWithMDLinks(licenseExp: string): string {
let licenseUrl = '';
if (licenseList[licenseExp] && licenseList[licenseExp]['url']) {
if (licenseList[licenseExp]?.['url']) {
licenseUrl = licenseList[licenseExp]['url'];
} else {
const substituteLicString = nonStandardLicenses[licenseExp.toLowerCase()];
if (licenseList[substituteLicString] && licenseList[substituteLicString]['url']) {
if (licenseList[substituteLicString]?.['url']) {
licenseUrl = licenseList[substituteLicString]['url'];
}
}
@ -125,7 +125,7 @@ export default function main(_args: string[], workingDir: string) {
const pack = packages[packageName];
pack['licenseExp'] = pack['licenses'].toString()
.replace(/\*/, '')
.replace(/[a-zA-Z0-9\-\.]+/g, (match: string) => {
.replace(/[a-zA-Z0-9\-.]+/g, (match: string) => {
const lowerMatch = match.toLowerCase();
if ((lowerMatch !== 'and') && (lowerMatch !== 'or') && (lowerMatch !== 'with')) {

@ -32,7 +32,7 @@ export class ProcessAutomationHealth {
const url = `${this.plugInInfo.host}/${this.plugInInfo.appName}/ui/${this.plugInInfo.uiName}/app.config.json`;
const appConfig = await this.config.getAppConfig(url);
let isEnabled = true;
if (appConfig && appConfig.plugins && appConfig.plugins[this.plugInInfo.name]) {
if (appConfig?.plugins?.[this.plugInInfo.name]) {
logger.info(`The plugin ${this.plugInInfo.name} has been correctly configured in app.config.json`);
} else {
this.logConfigurationError();

@ -32,7 +32,7 @@ export class ProcessServiceHealth {
const url = `${this.plugInInfo.host}/app.config.json`;
const appConfig = await this.config.getAppConfig(url);
let isEnabled = true;
if (appConfig && appConfig.plugins && appConfig.plugins[this.plugInInfo.name]) {
if (appConfig?.plugins?.[this.plugInInfo.name]) {
logger.info(`The plugin ${this.plugInInfo.name} has been correctly configured in app.config.json`);
} else {
this.logConfigurationError();

@ -38,6 +38,7 @@ function getSha(args: CommitArgs): string {
function replacePerform(args: CommitArgs, sha: string) {
logger.info(`Replace commit ${sha} in package...`);
// eslint-disable-next-line no-useless-escape
const sedRule = `s/\"commit\": \".*\"/\"commit\": \"${sha}\"/g`;
if (args.skipGnu) {

@ -129,9 +129,9 @@ describe('AspectListComponent', () => {
});
it('should show the loading spinner when result is loading', () => {
const delayReusult = of(null).pipe(delay(0));
spyOn(nodeService, 'getNode').and.returnValue(delayReusult);
spyOn(aspectListService, 'getAspects').and.returnValue(delayReusult);
const delayResult = of(null).pipe(delay(0));
spyOn(nodeService, 'getNode').and.returnValue(delayResult);
spyOn(aspectListService, 'getAspects').and.returnValue(delayResult);
fixture.detectChanges();
const spinner = fixture.nativeElement.querySelector('#adf-aspect-spinner');
expect(spinner).toBeDefined();

@ -140,9 +140,9 @@ describe('CategoriesManagementComponent', () => {
});
it('should unassign/remove specific category after clicking at remove icon and emit categories change', () => {
const removeBtns = getRemoveCategoryButtons();
const removeButtons = getRemoveCategoryButtons();
const categoriesChangeSpy = spyOn(component.categoriesChange, 'emit');
removeBtns[0].click();
removeButtons[0].click();
fixture.detectChanges();
@ -156,9 +156,9 @@ describe('CategoriesManagementComponent', () => {
it('should disable unassigning/removing categories when disableRemoval is set', () => {
component.disableRemoval = true;
fixture.detectChanges();
const removeBtns = getRemoveCategoryButtons();
const allBtnsDisabled = removeBtns.every((removeBtn) => removeBtn.disabled);
expect(allBtnsDisabled).toBeTrue();
const removeButtons = getRemoveCategoryButtons();
const allButtonsDisabled = removeButtons.every((removeBtn) => removeBtn.disabled);
expect(allButtonsDisabled).toBeTrue();
});
});
@ -269,8 +269,8 @@ describe('CategoriesManagementComponent', () => {
});
it('should have correct remove category title', () => {
const removeBtns = getRemoveCategoryButtons();
const isTitleCorrect = removeBtns.every((removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.UNASSIGN_CATEGORY');
const removeButtons = getRemoveCategoryButtons();
const isTitleCorrect = removeButtons.every((removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.UNASSIGN_CATEGORY');
expect(isTitleCorrect).toBeTrue();
});
@ -329,8 +329,8 @@ describe('CategoriesManagementComponent', () => {
fixture.detectChanges();
const categoriesChangeSpy = spyOn(component.categoriesChange, 'emit').and.callThrough();
const removeCategoryBtns = getRemoveCategoryButtons();
removeCategoryBtns[2].click();
const removeCategoryButtons = getRemoveCategoryButtons();
removeCategoryButtons[2].click();
fixture.detectChanges();
expect(component.categories.length).toBe(2);
@ -345,8 +345,8 @@ describe('CategoriesManagementComponent', () => {
typeCategory('test');
expect(component.existingCategories.length).toBe(2);
const categoriesChangeSpy = spyOn(component.categoriesChange, 'emit').and.callThrough();
const removeCategoryBtns = getRemoveCategoryButtons();
removeCategoryBtns[0].click();
const removeCategoryButtons = getRemoveCategoryButtons();
removeCategoryButtons[0].click();
fixture.detectChanges();
expect(component.categories.length).toBe(1);
@ -375,8 +375,8 @@ describe('CategoriesManagementComponent', () => {
});
it('should have correct remove category title', () => {
const removeBtns = getRemoveCategoryButtons();
const isTitleCorrect = removeBtns.every((removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.DELETE_CATEGORY');
const removeButtons = getRemoveCategoryButtons();
const isTitleCorrect = removeButtons.every((removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.DELETE_CATEGORY');
expect(isTitleCorrect).toBeTrue();
});
@ -434,8 +434,8 @@ describe('CategoriesManagementComponent', () => {
createCategory('test');
const categoriesChangeSpy = spyOn(component.categoriesChange, 'emit');
const removeCategoryBtns = getRemoveCategoryButtons();
removeCategoryBtns[2].click();
const removeCategoryButtons = getRemoveCategoryButtons();
removeCategoryButtons[2].click();
fixture.detectChanges();
expect(component.categories.length).toBe(2);

@ -64,17 +64,15 @@ export class CategoryTreeDatasourceService extends TreeService<CategoryNode> {
.join(pathSeparator);
return this.categoryService.getCategory(category.entry.id).pipe(
map((res) => {
return {
id: category.entry.id,
nodeName: path ? `${path}/${category.entry.name}` : category.entry.name,
parentId: category.entry.parentId,
level: 0,
nodeType: TreeNodeType.RegularNode,
hasChildren: res.entry.hasChildren,
isLoading: false
};
})
map((res) => ({
id: category.entry.id,
nodeName: path ? `${path}/${category.entry.name}` : category.entry.name,
parentId: category.entry.parentId,
level: 0,
nodeType: TreeNodeType.RegularNode,
hasChildren: res.entry.hasChildren,
isLoading: false
}))
);
}),
toArray(),

@ -610,7 +610,7 @@ describe('ContentMetadataComponent', () => {
let classesApi: ClassesApi;
let expectedNode: Node;
const versionableResponse: PropertyGroup = {
const verResponse: PropertyGroup = {
name: 'cm:versionable',
title: 'Versionable',
properties: {
@ -705,7 +705,7 @@ describe('ContentMetadataComponent', () => {
'cm:versionable': '*'
});
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse));
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
fixture.detectChanges();
@ -713,9 +713,9 @@ describe('ContentMetadataComponent', () => {
await component.groupedProperties$.toPromise();
fixture.detectChanges();
const versionableProp = queryDom(fixture, 'Versionable');
const verProp = queryDom(fixture, 'Versionable');
expect(versionableProp).toBeTruthy();
expect(verProp).toBeTruthy();
expect(classesApi.getClass).toHaveBeenCalledWith('cm_versionable');
});
@ -725,7 +725,7 @@ describe('ContentMetadataComponent', () => {
'cm:versionable': '*'
});
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse));
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
fixture.detectChanges();
@ -733,9 +733,9 @@ describe('ContentMetadataComponent', () => {
await component.groupedProperties$.toPromise();
fixture.detectChanges();
const versionableProps = fixture.debugElement.queryAll(By.css('[data-automation-id="adf-metadata-group-Versionable"]'));
const verProps = fixture.debugElement.queryAll(By.css('[data-automation-id="adf-metadata-group-Versionable"]'));
expect(versionableProps.length).toEqual(2);
expect(verProps.length).toEqual(2);
expect(classesApi.getClass).toHaveBeenCalledWith('cm_versionable');
});
@ -745,7 +745,7 @@ describe('ContentMetadataComponent', () => {
exclude: 'cm:versionable'
});
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse));
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
fixture.detectChanges();
@ -753,9 +753,9 @@ describe('ContentMetadataComponent', () => {
await component.groupedProperties$.toPromise();
fixture.detectChanges();
const versionableProp = queryDom(fixture, 'Versionable');
const verProp = queryDom(fixture, 'Versionable');
expect(versionableProp).toBeNull();
expect(verProp).toBeNull();
expect(classesApi.getClass).toHaveBeenCalledWith('cm_versionable');
});
@ -766,7 +766,7 @@ describe('ContentMetadataComponent', () => {
'cm:versionable': '*'
});
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse));
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
fixture.detectChanges();
@ -774,9 +774,9 @@ describe('ContentMetadataComponent', () => {
await component.groupedProperties$.toPromise();
fixture.detectChanges();
const versionableProp = queryDom(fixture, 'Versionable');
const verProp = queryDom(fixture, 'Versionable');
expect(versionableProp).toBeTruthy();
expect(verProp).toBeTruthy();
expect(classesApi.getClass).toHaveBeenCalledWith('cm_versionable');
});
@ -786,7 +786,7 @@ describe('ContentMetadataComponent', () => {
exclude: ['cm:versionable', 'cm:auditable']
});
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse));
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
fixture.detectChanges();
@ -794,8 +794,8 @@ describe('ContentMetadataComponent', () => {
await component.groupedProperties$.toPromise();
fixture.detectChanges();
const versionableProp = queryDom(fixture, 'Versionable');
expect(versionableProp).toBeNull();
const verProp = queryDom(fixture, 'Versionable');
expect(verProp).toBeNull();
const auditableProp = queryDom(fixture, 'Auditable');
expect(auditableProp).toBeNull();
@ -825,17 +825,17 @@ describe('ContentMetadataComponent', () => {
exifProp.nativeElement.click();
const pixelXDimentionElement = fixture.debugElement.query(
const pixelXDimensionElement = fixture.debugElement.query(
By.css('[data-automation-id="card-textitem-label-properties.exif:pixelXDimension"]')
);
expect(pixelXDimentionElement).toBeTruthy();
expect(pixelXDimentionElement.nativeElement.textContent.trim()).toEqual('Image Width');
expect(pixelXDimensionElement).toBeTruthy();
expect(pixelXDimensionElement.nativeElement.textContent.trim()).toEqual('Image Width');
const pixelYDimentionElement = fixture.debugElement.query(
const pixelYDimensionElement = fixture.debugElement.query(
By.css('[data-automation-id="card-textitem-label-properties.exif:pixelYDimension"]')
);
expect(pixelYDimentionElement).toBeTruthy();
expect(pixelYDimentionElement.nativeElement.textContent.trim()).toEqual('Image Height');
expect(pixelYDimensionElement).toBeTruthy();
expect(pixelYDimensionElement.nativeElement.textContent.trim()).toEqual('Image Height');
});
it('should show Exif twice when includeAll is set to true', async () => {

@ -330,7 +330,7 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
this.loadTagsForNode(this.node.id);
}
if (this.displayCategories && !!result.LinkingCategories) {
this.assignedCategories = !!result.LinkingCategories.list ?
this.assignedCategories = result.LinkingCategories.list ?
result.LinkingCategories.list.entries.map((entry: CategoryEntry) => entry.entry) :
[result.LinkingCategories.entry];
}

@ -110,7 +110,7 @@ describe('ContentMetaDataService', () => {
}
};
const versionableResponse: PropertyGroup = {
const verResponse: PropertyGroup = {
name: 'cm:versionable',
title: 'Versionable',
properties: {
@ -232,7 +232,7 @@ describe('ContentMetaDataService', () => {
'cm:versionable': '*'
});
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse));
const groupedProperties = await service.getGroupedProperties(fakeContentNode).toPromise();
@ -249,7 +249,7 @@ describe('ContentMetaDataService', () => {
'cm:versionable': '*'
});
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse));
const groupedProperties = await service.getGroupedProperties(fakeContentNode).toPromise();
@ -267,7 +267,7 @@ describe('ContentMetaDataService', () => {
exclude: 'cm:versionable'
});
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse));
const groupedProperties = await service.getGroupedProperties(fakeContentNode).toPromise();
expect(groupedProperties.length).toEqual(0);
@ -283,7 +283,7 @@ describe('ContentMetaDataService', () => {
'cm:versionable': '*'
});
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse));
const groupedProperties = await service.getGroupedProperties(fakeContentNode).toPromise();
expect(groupedProperties.length).toEqual(1);
@ -299,7 +299,7 @@ describe('ContentMetaDataService', () => {
exclude: ['cm:versionable', 'cm:auditable']
});
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse));
const groupedProperties = await service.getGroupedProperties(fakeContentNode).toPromise();
expect(groupedProperties.length).toEqual(0);

@ -147,9 +147,9 @@ describe('Content Type Dialog Component', () => {
});
it('should show the property with the aspect prefix not the inherited ones', async () => {
const showPropertyAccordon: HTMLButtonElement = fixture.nativeElement.querySelector('.adf-content-type-accordion .mat-expansion-panel-header');
expect(showPropertyAccordon).toBeDefined();
showPropertyAccordon.click();
const showPropertyAccordion: HTMLButtonElement = fixture.nativeElement.querySelector('.adf-content-type-accordion .mat-expansion-panel-header');
expect(showPropertyAccordion).toBeDefined();
showPropertyAccordion.click();
fixture.detectChanges();
await fixture.whenStable();
const propertyShowed: NodeList = fixture.nativeElement.querySelectorAll('.adf-content-type-table .mat-row');

@ -20,6 +20,7 @@ import { UntypedFormControl } from '@angular/forms';
const I18N_ERRORS_PATH = 'CORE.FOLDER_DIALOG.FOLDER_NAME.ERRORS';
export const forbidSpecialCharacters = ({ value }: UntypedFormControl) => {
// eslint-disable-next-line no-useless-escape
const specialCharacters: RegExp = /([\*\"\<\>\\\/\?\:\|])/;
const isValid: boolean = !specialCharacters.test(value);

@ -59,7 +59,7 @@ export class NodeLockDialogComponent implements OnInit {
isLocked: node.isLocked || false,
allowOwner: node.properties['cm:lockType'] === 'WRITE_LOCK',
isTimeLock: !!node.properties['cm:expiryDate'],
time: !!node.properties['cm:expiryDate'] ? moment(node.properties['cm:expiryDate']) : moment()
time: node.properties['cm:expiryDate'] ? moment(node.properties['cm:expiryDate']) : moment()
});
}

@ -24,10 +24,10 @@ import { TranslateModule } from '@ngx-translate/core';
@Component({
template: `<div tabindex="0" adf-auto-focus> Test</div>`
})
class AutoFoucsTestComponent {}
class AutoFocusTestComponent {}
describe('AutoFocusDirective', () => {
let fixture: ComponentFixture<AutoFoucsTestComponent>;
let fixture: ComponentFixture<AutoFocusTestComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
@ -36,10 +36,10 @@ describe('AutoFocusDirective', () => {
],
declarations: [
AutoFocusDirective,
AutoFoucsTestComponent
AutoFocusTestComponent
]
});
fixture = TestBed.createComponent(AutoFoucsTestComponent);
fixture = TestBed.createComponent(AutoFocusTestComponent);
});
it('should focus the element after content is initialized', fakeAsync(() => {

@ -118,7 +118,7 @@ export class NodeDeleteDirective implements OnChanges {
let promise: Promise<any>;
if (node.entry.hasOwnProperty('archivedAt') && node.entry['archivedAt']) {
if (Object.prototype.hasOwnProperty.call(node.entry, 'archivedAt') && node.entry['archivedAt']) {
promise = this.trashcanApi.deleteDeletedNode(id);
} else {
promise = this.nodesApi.deleteNode(id, { permanent: this.permanent });

@ -130,7 +130,7 @@ export class NodeFavoriteDirective implements OnChanges {
const node: Node | SharedLink = selected.entry;
// ACS 6.x with 'isFavorite' include
if (node?.hasOwnProperty('isFavorite')) {
if (node && Object.prototype.hasOwnProperty.call(node, 'isFavorite')) {
return of(selected);
}

@ -39,11 +39,11 @@ export class ContentActionModel {
this.permission = obj.permission;
this.disableWithNoPermission = obj.disableWithNoPermission;
if (obj.hasOwnProperty('disabled')) {
if (Object.prototype.hasOwnProperty.call(obj, 'disabled')) {
this.disabled = obj.disabled;
}
if (obj.hasOwnProperty('visible')) {
if (Object.prototype.hasOwnProperty.call(obj, 'visible')) {
this.visible = obj.visible;
}
}

@ -56,7 +56,7 @@ export class AddPermissionDialogComponent {
this.selectedMembers.forEach((member) => {
const existingMember = this.existingMembers.find(({authorityId}) => authorityId === member.id);
if (!!existingMember) {
if (existingMember) {
member.role = existingMember.name;
member.accessStatus = existingMember.accessStatus;
member.readonly = true; // make role non editable
@ -66,7 +66,7 @@ export class AddPermissionDialogComponent {
}
canCloseDialog() {
if (!!this.selectedMembers.length) {
if (this.selectedMembers.length) {
this.disableSearch();
} else {
this.dialogRef.close();

@ -54,7 +54,7 @@ export class SearchPermissionConfigurationService implements SearchConfiguration
if (this.queryProvider?.query) {
query = this.queryProvider.query.replace(new RegExp(/\${([^}]+)}/g), searchTerm);
} else {
query = `(email:*${searchTerm}* OR firstName:*${searchTerm}* OR lastName:*${searchTerm}* OR displayName:*${searchTerm}* OR authorityName:*${searchTerm}* OR authorityDisplayName:*${searchTerm}*) AND ANAME:(\"0/APP.DEFAULT\")`;
query = `(email:*${searchTerm}* OR firstName:*${searchTerm}* OR lastName:*${searchTerm}* OR displayName:*${searchTerm}* OR authorityName:*${searchTerm}* OR authorityDisplayName:*${searchTerm}*) AND ANAME:("0/APP.DEFAULT")`;
}
return query;
}

@ -65,6 +65,7 @@ export class NodePermissionService {
/**
* Get permissions for a given node
*
* @param node Node to check permissions for
*/
getNodePermissions(node: Node): PermissionDisplayModel[] {

@ -89,7 +89,7 @@ export class SearchLogicalFilterComponent implements SearchWidget, OnInit {
fieldQuery += field + '"' + this.searchCondition[key].trim() + '"';
} else {
this.searchCondition[key].split(' ').filter((condition: string) => condition !== '').forEach((phrase: string) => {
const refinedPhrase = '\"' + phrase + '\"';
const refinedPhrase = '"' + phrase + '"';
fieldQuery += fieldQuery === '(' ?
`${key === LogicalSearchFields.EXCLUDE ? 'NOT ' : ''}${field}${refinedPhrase}` :
` ${connector} ${field}${refinedPhrase}`;

@ -49,15 +49,15 @@ export class SearchSliderComponent implements SearchWidget, OnInit {
ngOnInit() {
if (this.settings) {
if (this.settings.hasOwnProperty('min')) {
if (Object.prototype.hasOwnProperty.call(this.settings, 'min')) {
this.min = this.settings['min'];
}
if (this.settings.hasOwnProperty('max')) {
if (Object.prototype.hasOwnProperty.call(this.settings, 'max')) {
this.max = this.settings['max'];
}
if (this.settings.hasOwnProperty('step')) {
if (Object.prototype.hasOwnProperty.call(this.settings, 'step')) {
this.step = this.settings['step'];
}

@ -150,7 +150,7 @@ export abstract class BaseQueryBuilderService {
default: configuration.default || false,
selected: this.selectedConfiguration !== undefined ? index === this.selectedConfiguration : configuration.default
}));
} else if (!!configurations) {
} else if (configurations) {
return [
{
index: 0,

@ -103,7 +103,7 @@ export abstract class UploadBase implements OnInit, OnDestroy {
*/
uploadFiles(files: File[]): void {
const filteredFiles: FileModel[] = files
.map<FileModel>((file: File) => this.createFileModel(file, this.rootFolderId, ((file as any).webkitRelativePath || '').replace(/\/[^\/]*$/, '')));
.map<FileModel>((file: File) => this.createFileModel(file, this.rootFolderId, ((file as any).webkitRelativePath || '').replace(/\/[^/]*$/, '')));
this.uploadQueue(filteredFiles);
}

@ -306,7 +306,7 @@ describe('UploadDragAreaComponent', () => {
});
it('should upload a file to a specific target folder when dropped onto one', () => {
const fakePippoItem = {
const fakePngItem = {
fullPath: '/folder-fake/file-fake.png',
isDirectory: false,
isFile: true,
@ -321,7 +321,7 @@ describe('UploadDragAreaComponent', () => {
const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', {
detail: {
data: getFakeShareDataRow(),
files: [fakePippoItem]
files: [fakePngItem]
}
});

@ -39,7 +39,7 @@ export class UploadVersionButtonComponent extends UploadButtonComponent implemen
node: Node;
protected createFileModel(file: File): FileModel {
const fileModel = super.createFileModel(file, this.rootFolderId, ((file as any).webkitRelativePath || '').replace(/\/[^\/]*$/, ''), this.node.id);
const fileModel = super.createFileModel(file, this.rootFolderId, ((file as any).webkitRelativePath || '').replace(/\/[^/]*$/, ''), this.node.id);
if (!this.isFileAcceptable(fileModel)) {
const message = this.translationService.instant('FILE_UPLOAD.VERSION.MESSAGES.INCOMPATIBLE_VERSION');

@ -52,7 +52,7 @@ describe('VersionCompatibilityDirective', () => {
let fixture: ComponentFixture<TestComponent>;
let versionCompatibilityService: VersionCompatibilityService;
const acsResponceMock = new VersionInfo({
const acsResponseMock = new VersionInfo({
display: '7.0.1',
major: '7',
minor: '0',
@ -70,7 +70,7 @@ describe('VersionCompatibilityDirective', () => {
});
fixture = TestBed.createComponent(TestComponent);
versionCompatibilityService = TestBed.inject(VersionCompatibilityService);
spyOn(versionCompatibilityService, 'getAcsVersion').and.returnValue(acsResponceMock);
spyOn(versionCompatibilityService, 'getAcsVersion').and.returnValue(acsResponseMock);
});
it('should display component when the version is supported', () => {

@ -28,7 +28,7 @@ describe('VersionCompatibilityService', () => {
let discoveryApiService: DiscoveryApiService;
const mockProductInfo = new BehaviorSubject<RepositoryInfo>(null);
const acsResponceMock = {
const acsResponseMock = {
version: {
display: '7.0.1',
major: '7',
@ -54,7 +54,7 @@ describe('VersionCompatibilityService', () => {
});
discoveryApiService = TestBed.inject(DiscoveryApiService);
versionCompatibilityService = TestBed.inject(VersionCompatibilityService);
mockProductInfo.next(acsResponceMock as RepositoryInfo);
mockProductInfo.next(acsResponseMock as RepositoryInfo);
versionCompatibilityService = new VersionCompatibilityService(discoveryApiService);
});

@ -151,18 +151,22 @@ export class AdfHttpClient implements ee.Emitter,JsApiHttpClient {
private addPromiseListeners<T = any>(promise: Promise<T>, eventEmitter: any) {
const eventPromise = Object.assign(promise, {
on() {
// eslint-disable-next-line prefer-spread, prefer-rest-params
eventEmitter.on.apply(eventEmitter, arguments);
return this;
},
once() {
// eslint-disable-next-line prefer-spread, prefer-rest-params
eventEmitter.once.apply(eventEmitter, arguments);
return this;
},
emit() {
// eslint-disable-next-line prefer-spread, prefer-rest-params
eventEmitter.emit.apply(eventEmitter, arguments);
return this;
},
off() {
// eslint-disable-next-line prefer-spread, prefer-rest-params
eventEmitter.off.apply(eventEmitter, arguments);
return this;
}

@ -52,8 +52,8 @@ describe('AppLayoutComponent', () => {
hideSidenavConditions: [],
minimizeSidenavConditions: [],
preferencesService: {
get: (_key: string) => 'true',
set: (_key: string, _value: any) => {}
get: () => 'true',
set: () => {}
}
};

@ -27,10 +27,7 @@ describe('AboutGithubLinkComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule]
});
fixture = TestBed.createComponent(AboutGithubLinkComponent);
component = fixture.componentInstance;
@ -62,7 +59,7 @@ describe('AboutGithubLinkComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const githubUrl = fixture.nativeElement.querySelector('[data-automation-id="adf-github-url"]');
expect(githubUrl.innerText).toEqual(aboutGithubDetails.defualrUrl);
expect(githubUrl.innerText).toEqual(aboutGithubDetails.defaultUrl);
});
it('should display the github link', async () => {

@ -43,7 +43,7 @@ export const mockPlugins = [
export const aboutGithubDetails = {
url: 'https://github.com/componany/repository/commits/',
defualrUrl: 'https://github.com/Alfresco/alfresco-ng2-components/commits/',
defaultUrl: 'https://github.com/Alfresco/alfresco-ng2-components/commits/',
version: '0.0.7',
ecmHost: 'https://mock.ecmhost.com',
bpmHost: 'https://mock.bpmhost.com',
@ -56,65 +56,65 @@ export const aboutAPSMockDetails = {
type: 'bpmSuite',
majorVersion: '1',
minorVersion: '10'
};
};
export const mockModules: any = {
edition: 'Enterprise',
version: {
major: '6',
minor: '2',
patch: '0',
hotfix: '0',
schema: 13001,
label: 'ra498a911-b5',
display: '6.2.0.0'
},
license: {
issuedAt: '2018-12-20T12:07:31.276+0000',
expiresAt: '2019-05-31T23:00:00.000+0000',
remainingDays: 100,
holder: 'CompanyQA',
mode: 'ENTERPRISE',
entitlements: {
isClusterEnabled: true,
isCryptodocEnabled: true
}
},
status: {
isReadOnly: false,
isAuditEnabled: true,
isQuickShareEnabled: true,
isThumbnailGenerationEnabled: true
},
modules: [
{
id: 'mock-id',
title: 'ABC Repo',
description: 'ABC Repository Extension',
version: '3.2.0',
installState: 'UNKNOWN',
versionMin: '6.1',
versionMax: '999'
},
{
id: 'aos-module-id',
title: 'AOFS Module',
description: 'Allows applications that can talk to a SharePoint server to talk to your Alfresco installation',
version: '1.3.0',
installDate: '2019-02-07T12:26:13.271+0000',
installState: 'INSTALLED',
versionMin: '6.0',
versionMax: '999'
},
{
id: 'mock-saml-repo',
title: 'SAML Repository Module',
description: 'The Repository piece of the Alfresco SAML Module',
version: '1.1.1',
installDate: '2019-02-07T12:26:12.565+0000',
installState: 'INSTALLED',
versionMin: '6.0',
versionMax: '6.99'
}
]
edition: 'Enterprise',
version: {
major: '6',
minor: '2',
patch: '0',
hotfix: '0',
schema: 13001,
label: 'ra498a911-b5',
display: '6.2.0.0'
},
license: {
issuedAt: '2018-12-20T12:07:31.276+0000',
expiresAt: '2019-05-31T23:00:00.000+0000',
remainingDays: 100,
holder: 'CompanyQA',
mode: 'ENTERPRISE',
entitlements: {
isClusterEnabled: true,
isCryptodocEnabled: true
}
},
status: {
isReadOnly: false,
isAuditEnabled: true,
isQuickShareEnabled: true,
isThumbnailGenerationEnabled: true
},
modules: [
{
id: 'mock-id',
title: 'ABC Repo',
description: 'ABC Repository Extension',
version: '3.2.0',
installState: 'UNKNOWN',
versionMin: '6.1',
versionMax: '999'
},
{
id: 'aos-module-id',
title: 'AOFS Module',
description: 'Allows applications that can talk to a SharePoint server to talk to your Alfresco installation',
version: '1.3.0',
installDate: '2019-02-07T12:26:13.271+0000',
installState: 'INSTALLED',
versionMin: '6.0',
versionMax: '999'
},
{
id: 'mock-saml-repo',
title: 'SAML Repository Module',
description: 'The Repository piece of the Alfresco SAML Module',
version: '1.1.1',
installDate: '2019-02-07T12:26:12.565+0000',
installState: 'INSTALLED',
versionMin: '6.0',
versionMax: '6.99'
}
]
};

@ -185,7 +185,7 @@ export class AppConfigService {
* @returns Notification when loading is complete
*/
load(): Promise<any> {
return new Promise(async (resolve) => {
return new Promise((resolve) => {
const configUrl = `app.config.json?v=${Date.now()}`;
if (this.status === Status.INIT) {
@ -218,7 +218,7 @@ export class AppConfigService {
* @returns Discovery configuration
*/
loadWellKnown(hostIdp: string): Promise<OpenidConfiguration> {
return new Promise(async (resolve, reject) => {
return new Promise((resolve, reject) => {
this.http
.get<OpenidConfiguration>(`${hostIdp}/.well-known/openid-configuration`)
.subscribe({

@ -40,7 +40,7 @@ export class AuthBearerInterceptor implements HttpInterceptor {
this.authService = this.injector.get(AuthenticationService);
if (!this.authService || !this.authService.getBearerExcludedUrls()) {
if (!this.authService?.getBearerExcludedUrls()) {
return next.handle(req);
}

@ -97,10 +97,10 @@ describe('JwtHelperService', () => {
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
{
resource_access: { fakeapp: { roles: ['role1'] } }
resource_access: { fakeApp: { roles: ['role1'] } }
});
const result = jwtHelperService.hasRealmRolesForClientRole('fakeapp', ['role1']);
const result = jwtHelperService.hasRealmRolesForClientRole('fakeApp', ['role1']);
expect(result).toBeTruthy();
});
@ -109,10 +109,10 @@ describe('JwtHelperService', () => {
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
{
resource_access: { fakeapp: { roles: ['role1'] } }
resource_access: { fakeApp: { roles: ['role1'] } }
});
const result = jwtHelperService.hasRealmRolesForClientRole('fakeapp', ['role1', 'role2']);
const result = jwtHelperService.hasRealmRolesForClientRole('fakeApp', ['role1', 'role2']);
expect(result).toBeTruthy();
});
@ -120,9 +120,9 @@ describe('JwtHelperService', () => {
spyOn(jwtHelperService, 'getAccessToken').and.returnValue('my-access_token');
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
{
resource_access: { fakeapp: { roles: ['role3'] } }
resource_access: { fakeApp: { roles: ['role3'] } }
});
const result = jwtHelperService.hasRealmRolesForClientRole('fakeapp', ['role1', 'role2']);
const result = jwtHelperService.hasRealmRolesForClientRole('fakeApp', ['role1', 'role2']);
expect(result).toBeFalsy();
});
@ -130,9 +130,9 @@ describe('JwtHelperService', () => {
spyOn(jwtHelperService, 'getAccessToken').and.returnValue('my-access_token');
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
{
resource_access: { anotherfakeapp: { roles: ['role1'] } }
resource_access: { anotherFakeApp: { roles: ['role1'] } }
});
const result = jwtHelperService.hasRealmRolesForClientRole('fakeapp', ['role1', 'role2']);
const result = jwtHelperService.hasRealmRolesForClientRole('fakeApp', ['role1', 'role2']);
expect(result).toBeFalsy();
});
});

@ -46,10 +46,7 @@ describe('CardViewArrayItemComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule]
});
fixture = TestBed.createComponent(CardViewArrayItemComponent);
service = TestBed.inject(CardViewUpdateService);
@ -87,8 +84,8 @@ describe('CardViewArrayItemComponent', () => {
});
it('should NOT call service on chip list container click', () => {
const chiplistContainer: HTMLElement = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-list-container"]');
chiplistContainer.dispatchEvent(new Event('click'));
const chipListContainer: HTMLElement = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-list-container"]');
chipListContainer.dispatchEvent(new Event('click'));
expect(serviceSpy).not.toHaveBeenCalled();
});
@ -110,11 +107,11 @@ describe('CardViewArrayItemComponent', () => {
});
fixture.detectChanges();
const chiplistContainer = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-chip-list-container"]'));
const chipListContainer = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-chip-list-container"]'));
const chip1 = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-Zlatan"] span');
const chip2 = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-Lionel Messi"] span');
expect(chiplistContainer).not.toBeNull();
expect(chipListContainer).not.toBeNull();
expect(chip1.innerText).toEqual('Zlatan');
expect(chip2.innerText).toEqual('Lionel Messi');
});
@ -126,13 +123,13 @@ describe('CardViewArrayItemComponent', () => {
});
fixture.detectChanges();
const chiplistContainer = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-chip-list-container"]'));
const chipListContainer = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-chip-list-container"]'));
const chip1 = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-Zlatan"] span');
const chip1Icon = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-Zlatan"] mat-icon');
const chip2 = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-Lionel Messi"] span');
const chip2Icon = fixture.nativeElement.querySelector('[data-automation-id="card-arrayitem-chip-Lionel Messi"] mat-icon');
expect(chiplistContainer).not.toBeNull();
expect(chipListContainer).not.toBeNull();
expect(chip1.innerText).toEqual('Zlatan');
expect(chip1Icon.innerText).toEqual('person');
expect(chip2.innerText).toEqual('Lionel Messi');
@ -145,9 +142,9 @@ describe('CardViewArrayItemComponent', () => {
clickable: true
});
fixture.detectChanges();
const editicon = fixture.nativeElement.querySelector('[data-automation-id="card-array-item-clickable-icon-array"]');
expect(editicon).toBeDefined();
expect(editicon.innerText).toBe('edit');
const editIcon = fixture.nativeElement.querySelector('[data-automation-id="card-array-item-clickable-icon-array"]');
expect(editIcon).toBeDefined();
expect(editIcon.innerText).toBe('edit');
});
it('should not render defined icon if clickable set to false', () => {
@ -156,18 +153,18 @@ describe('CardViewArrayItemComponent', () => {
clickable: false
});
fixture.detectChanges();
const editicon = fixture.nativeElement.querySelector('[data-automation-id="card-array-item-clickable-icon-array"]');
expect(editicon).toBeNull();
const editIcon = fixture.nativeElement.querySelector('[data-automation-id="card-array-item-clickable-icon-array"]');
expect(editIcon).toBeNull();
});
it('should render all values if noOfItemsToDisplay is not defined', () => {
fixture.detectChanges();
const chiplistContainer = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-chip-list-container"]'));
const chipListContainer = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-chip-list-container"]'));
const moreElement = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-more-chip"]'));
const chip = fixture.nativeElement.querySelectorAll('mat-chip');
expect(chiplistContainer).not.toBeNull();
expect(chipListContainer).not.toBeNull();
expect(moreElement).toBeNull();
expect(chip.length).toBe(4);
});
@ -179,10 +176,10 @@ describe('CardViewArrayItemComponent', () => {
});
fixture.detectChanges();
const chiplistContainer = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-chip-list-container"]'));
const chipListContainer = fixture.debugElement.query(By.css('[data-automation-id="card-arrayitem-chip-list-container"]'));
const chip = fixture.debugElement.queryAll(By.css('mat-chip'));
expect(chiplistContainer).not.toBeNull();
expect(chipListContainer).not.toBeNull();
expect(chip.length).toBe(3);
expect(chip[2].nativeElement.innerText).toBe('2 CORE.CARDVIEW.MORE');
});

@ -41,7 +41,7 @@ describe('CardViewBoolItemComponent', () => {
component.property = new CardViewBoolItemModel({
label: 'Boolean label',
value: true,
key: 'boolkey',
key: 'boolKey',
default: false,
editable: false
});
@ -207,7 +207,7 @@ describe('CardViewBoolItemComponent', () => {
const disposableUpdate = cardViewUpdateService.itemUpdated$.subscribe(
(updateNotification) => {
expect(updateNotification.target).toEqual(property);
expect(updateNotification.changed).toEqual({ boolkey: true });
expect(updateNotification.changed).toEqual({ boolKey: true });
disposableUpdate.unsubscribe();
done();
}

@ -118,6 +118,7 @@ export class CardViewItemDispatcherComponent implements OnChanges {
private proxy(methodName, ...args) {
if (this.componentReference.instance[methodName]) {
// eslint-disable-next-line prefer-spread
this.componentReference.instance[methodName].apply(this.componentReference.instance, args);
}
}

@ -45,7 +45,7 @@ describe('CardViewBaseItemModel', () => {
expect(itemModel.data).toBe(properties.data);
});
it('should persist the params\' properties as own properties', () => {
it('should persist the params properties as own properties', () => {
const allProperties = {
...properties,
default: 'default-value',

@ -40,6 +40,7 @@ export class HighlightTransformService {
let result = text;
if (search && text) {
// eslint-disable-next-line no-useless-escape
let pattern = search.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
pattern = pattern.split(' ').filter((t) => t.length > 0).join('|');

@ -24,12 +24,7 @@ interface TestSortableByCategoryItem extends SortableByCategoryItem {
describe('SortByCategoryMapperService', () => {
let mapper: SortByCategoryMapperService<TestSortableByCategoryItem>;
const DEFAULT_CATEGORIES = [
'',
'DefaultCategory1',
'DefaultCategory2',
'DefaultCategory3'
];
const DEFAULT_CATEGORIES = ['', 'DefaultCategory1', 'DefaultCategory2', 'DefaultCategory3'];
beforeEach(() => {
mapper = new SortByCategoryMapperService();
@ -57,25 +52,29 @@ describe('SortByCategoryMapperService', () => {
});
it('should set all items under default category', () => {
const defaulValues: TestSortableByCategoryItem[] = [{
name: 'name-a',
id: 'id',
category: DEFAULT_CATEGORIES[1]
}, {
name: 'name-b',
id: 'id2',
category: DEFAULT_CATEGORIES[2]
}, {
name: 'name-c',
id: 'id3',
category: DEFAULT_CATEGORIES[0]
}];
const defaultValues: TestSortableByCategoryItem[] = [
{
name: 'name-a',
id: 'id',
category: DEFAULT_CATEGORIES[1]
},
{
name: 'name-b',
id: 'id2',
category: DEFAULT_CATEGORIES[2]
},
{
name: 'name-c',
id: 'id3',
category: DEFAULT_CATEGORIES[0]
}
];
const result = mapper.mapItems(defaulValues, DEFAULT_CATEGORIES);
const result = mapper.mapItems(defaultValues, DEFAULT_CATEGORIES);
expect(result.length).toBe(1);
expect(result[0].category).toBe('');
expect(result[0].items.length).toBe(defaulValues.length);
expect(result[0].items.length).toBe(defaultValues.length);
});
it('should work if no items are present', () => {
@ -85,7 +84,7 @@ describe('SortByCategoryMapperService', () => {
});
it('should work if the default categories are empty', () => {
const result = mapper.mapItems([{id: 'id', name: 'name', category: ''}], []);
const result = mapper.mapItems([{ id: 'id', name: 'name', category: '' }], []);
expect(result.length).toBe(1);
expect(result[0].category).toBe('');

@ -21,7 +21,6 @@ import { Injectable } from '@angular/core';
providedIn: 'root'
})
export class StorageService {
private memoryStore: { [key: string]: any } = {};
private readonly useLocalStorage: boolean = false;
private _prefix: string = '';
@ -48,7 +47,7 @@ export class StorageService {
if (this.useLocalStorage) {
return localStorage.getItem(this.prefix + key);
} else {
return this.memoryStore.hasOwnProperty(this.prefix + key) ? this.memoryStore[this.prefix + key] : null;
return Object.prototype.hasOwnProperty.call(this.memoryStore, this.prefix + key) ? this.memoryStore[this.prefix + key] : null;
}
}
@ -96,9 +95,9 @@ export class StorageService {
*/
hasItem(key: string): boolean {
if (this.useLocalStorage) {
return localStorage.getItem(this.prefix + key) ? true : false;
return !!localStorage.getItem(this.prefix + key);
} else {
return this.memoryStore.hasOwnProperty(key);
return Object.prototype.hasOwnProperty.call(this.memoryStore, key);
}
}

@ -41,7 +41,7 @@ export class FileUtils {
files.push({
entry,
file,
relativeFolder: entry.fullPath.replace(/\/[^\/]*$/, '')
relativeFolder: entry.fullPath.replace(/\/[^/]*$/, '')
});
resolveFile();
});

@ -40,7 +40,7 @@ export class ObjectDataTableAdapter implements DataTableAdapter {
if (typeof rowToExamine === 'object') {
for (const key in rowToExamine) {
if (rowToExamine.hasOwnProperty(key)) {
if (Object.prototype.hasOwnProperty.call(rowToExamine, key)) {
schema.push({
type: 'text',
key,

@ -51,26 +51,24 @@ export class ResizableDirective implements OnInit, OnDestroy {
mousemove = new Subject<IResizeMouseEvent>();
private pointerDown: Observable<IResizeMouseEvent>;
private pointerMove: Observable<IResizeMouseEvent>;
private pointerUp: Observable<IResizeMouseEvent>;
private readonly pointerDown: Observable<IResizeMouseEvent>;
private readonly pointerMove: Observable<IResizeMouseEvent>;
private readonly pointerUp: Observable<IResizeMouseEvent>;
private startingRect: BoundingRectangle;
private currentRect: BoundingRectangle;
private unlistenMouseDown?: () => void;
private unlistenMouseMove?: () => void;
private unlistenMouseUp?: () => void;
private unsubscribeMouseDown?: () => void;
private unsubscribeMouseMove?: () => void;
private unsubscribeMouseUp?: () => void;
private destroy$ = new Subject<void>();
constructor(private readonly renderer: Renderer2, private readonly element: ElementRef<HTMLElement>, private readonly zone: NgZone) {
this.pointerDown = new Observable((observer: Observer<IResizeMouseEvent>) => {
zone.runOutsideAngular(() => {
this.unlistenMouseDown = renderer.listen('document', 'mousedown', (event: MouseEvent) => {
this.unsubscribeMouseDown = renderer.listen('document', 'mousedown', (event: MouseEvent) => {
observer.next(event);
});
});
@ -78,7 +76,7 @@ export class ResizableDirective implements OnInit, OnDestroy {
this.pointerMove = new Observable((observer: Observer<IResizeMouseEvent>) => {
zone.runOutsideAngular(() => {
this.unlistenMouseMove = renderer.listen('document', 'mousemove', (event: MouseEvent) => {
this.unsubscribeMouseMove = renderer.listen('document', 'mousemove', (event: MouseEvent) => {
observer.next(event);
});
});
@ -86,7 +84,7 @@ export class ResizableDirective implements OnInit, OnDestroy {
this.pointerUp = new Observable((observer: Observer<IResizeMouseEvent>) => {
zone.runOutsideAngular(() => {
this.unlistenMouseUp = renderer.listen('document', 'mouseup', (event: MouseEvent) => {
this.unsubscribeMouseUp = renderer.listen('document', 'mouseup', (event: MouseEvent) => {
observer.next(event);
});
});
@ -101,7 +99,7 @@ export class ResizableDirective implements OnInit, OnDestroy {
const mouseDrag: Observable<IResizeMouseEvent | ICoordinateX> = mousedown$
.pipe(
mergeMap(({ clientX = 0 }) =>
merge(mousemove$.pipe(take(1)).pipe(map((coords) => [, coords])), mousemove$.pipe(pairwise()))
merge(mousemove$.pipe(take(1)).pipe(map((coords) => [undefined, coords])), mousemove$.pipe(pairwise()))
.pipe(
map(([previousCoords = {}, newCoords = {}]) => [
{ clientX: previousCoords.clientX - clientX },
@ -170,9 +168,9 @@ export class ResizableDirective implements OnInit, OnDestroy {
this.mousedown.complete();
this.mousemove.complete();
this.mouseup.complete();
this.unlistenMouseDown?.();
this.unlistenMouseMove?.();
this.unlistenMouseUp?.();
this.unsubscribeMouseDown?.();
this.unsubscribeMouseMove?.();
this.unsubscribeMouseUp?.();
this.destroy$.next();
}

@ -30,7 +30,7 @@ import {
numberMinMaxForm,
textWidgetVisibility,
numberWidgetVisibilityForm,
radioWidgetVisibiltyForm,
radioWidgetVisibilityForm,
customWidgetForm,
formDateVisibility,
customWidgetFormWithVisibility,
@ -86,7 +86,6 @@ const expectElementToBeValid = (fieldId: string, fixture: ComponentFixture<FormR
};
describe('Form Renderer Component', () => {
let formRendererComponent: FormRendererComponent<any>;
let fixture: ComponentFixture<FormRendererComponent<any>>;
let formService: FormService;
@ -95,11 +94,7 @@ describe('Form Renderer Component', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
FormBaseModule
]
imports: [TranslateModule.forRoot(), CoreTestingModule, FormBaseModule]
});
fixture = TestBed.createComponent(FormRendererComponent);
formRendererComponent = fixture.componentInstance;
@ -287,7 +282,6 @@ describe('Form Renderer Component', () => {
});
describe('Number widget', () => {
it('[C315169] - Should be able to complete a task with a form with number widgets', async () => {
formRendererComponent.formDefinition = formService.parseForm(formNumberWidgetVisibility.formRepresentation.formDefinition);
fixture.detectChanges();
@ -364,8 +358,8 @@ describe('Form Renderer Component', () => {
await fixture.whenStable();
numberContainerElement = fixture.nativeElement.querySelector('#field-Number2-container');
expectElementToBeHidden(numberContainerElement);
const errorWidetText: HTMLDivElement = fixture.nativeElement.querySelector('#field-Number1-container error-widget .adf-error-text');
expect(errorWidetText.textContent).toBe(`FORM.FIELD.VALIDATOR.NOT_GREATER_THAN`);
const errorWidgetText: HTMLDivElement = fixture.nativeElement.querySelector('#field-Number1-container error-widget .adf-error-text');
expect(errorWidgetText.textContent).toBe(`FORM.FIELD.VALIDATOR.NOT_GREATER_THAN`);
expect(formRendererComponent.formDefinition.isValid).toBe(false, 'Form should not be valid without mandatory field');
});
@ -397,12 +391,16 @@ describe('Form Renderer Component', () => {
await fixture.whenStable();
const formSizedElement = fixture.nativeElement.querySelector('#field-2bc275fb-e113-4d7d-885f-6e74a7332d40-container div.adf-grid-list');
expectElementToBeVisible(formSizedElement);
const sectionGridElement: HTMLElement[] = fixture.nativeElement.querySelectorAll('#field-2bc275fb-e113-4d7d-885f-6e74a7332d40-container div .adf-grid-list-item');
const sectionGridElement: HTMLElement[] = fixture.nativeElement.querySelectorAll(
'#field-2bc275fb-e113-4d7d-885f-6e74a7332d40-container div .adf-grid-list-item'
);
sectionGridElement.forEach((element) => {
expect(element.style['grid-area']).toBe('auto / auto / span 1 / span 1', 'Elemens is wrong sized for this section');
});
const fullWidthElement = fixture.nativeElement.querySelector('#field-d52ada4e-cbdc-4f0c-a480-5b85fa00e4f8-container div.adf-grid-list .adf-grid-list-item');
const fullWidthElement = fixture.nativeElement.querySelector(
'#field-d52ada4e-cbdc-4f0c-a480-5b85fa00e4f8-container div.adf-grid-list .adf-grid-list-item'
);
expect(fullWidthElement.style['grid-area']).toBe('auto / auto / span 1 / span 2');
});
@ -410,13 +408,19 @@ describe('Form Renderer Component', () => {
formRendererComponent.formDefinition = formService.parseForm(colspanForm.formRepresentation.formDefinition, null, false, false);
fixture.detectChanges();
await fixture.whenStable();
const formSizedElement = fixture.nativeElement.querySelector('#field-2bc275fb-e113-4d7d-885f-6e74a7332d40-container section.adf-grid-list-column-view');
const formSizedElement = fixture.nativeElement.querySelector(
'#field-2bc275fb-e113-4d7d-885f-6e74a7332d40-container section.adf-grid-list-column-view'
);
expectElementToBeVisible(formSizedElement);
const sectionGridElement: HTMLElement[] = fixture.nativeElement.querySelectorAll('#field-2bc275fb-e113-4d7d-885f-6e74a7332d40-container section .adf-grid-list-single-column');
const sectionGridElement: HTMLElement[] = fixture.nativeElement.querySelectorAll(
'#field-2bc275fb-e113-4d7d-885f-6e74a7332d40-container section .adf-grid-list-single-column'
);
sectionGridElement.forEach((element) => {
expect(element.style['width']).toBe('50%', 'Elemens is wrong sized for this section');
});
const fullWidthElement = fixture.nativeElement.querySelector('#field-d52ada4e-cbdc-4f0c-a480-5b85fa00e4f8-container section.adf-grid-list-column-view .adf-grid-list-single-column');
const fullWidthElement = fixture.nativeElement.querySelector(
'#field-d52ada4e-cbdc-4f0c-a480-5b85fa00e4f8-container section.adf-grid-list-column-view .adf-grid-list-single-column'
);
expect(fullWidthElement.style['width']).toBe('100%');
});
@ -587,11 +591,9 @@ describe('Form Renderer Component', () => {
expectInputElementValueIs(testTwoInput, 'aaa');
expectElementToBeHidden(numberFieldContainer);
});
});
describe('Text widget', () => {
it('[C309669] - Should be able to set visibility conditions for Text widget', async () => {
formRendererComponent.formDefinition = formService.parseForm(textWidgetVisibility.formRepresentation.formDefinition);
fixture.detectChanges();
@ -630,13 +632,11 @@ describe('Form Renderer Component', () => {
expectElementToBeVisible(elementFourContainer);
expectElementToBeHidden(elementThreeContainer);
});
});
describe('Radio widget', () => {
it('[C310352] - Should be able to set visibility conditions for Radio Button widget', async () => {
formRendererComponent.formDefinition = formService.parseForm(radioWidgetVisibiltyForm.formRepresentation.formDefinition);
formRendererComponent.formDefinition = formService.parseForm(radioWidgetVisibilityForm.formRepresentation.formDefinition);
fixture.detectChanges();
await fixture.whenStable();
const textInputElement = fixture.nativeElement.querySelector('#Text0cee7g');
@ -651,11 +651,9 @@ describe('Form Renderer Component', () => {
radioButtonContainer = fixture.nativeElement.querySelector('#field-Radiobuttons03rkbo-container');
expectElementToBeVisible(radioButtonContainer);
});
});
describe('Custom Widget', () => {
it('Should be able to correctly display a custom process cloud widget', async () => {
formRenderingService.register({ bananaforevah: () => TextWidgetComponent }, true);
formRendererComponent.formDefinition = formService.parseForm(customWidgetForm.formRepresentation.formDefinition);
@ -681,7 +679,6 @@ describe('Form Renderer Component', () => {
customWidgetElementContainer = fixture.nativeElement.querySelector('#field-bananaforevah0k8gui-container');
expectElementToBeVisible(customWidgetElementContainer);
});
});
describe('Form rules', () => {

@ -84,7 +84,7 @@ export class FormRendererComponent<T> implements OnChanges, OnDestroy {
const maxColumnFieldsSize = this.getMaxColumnFieldSize(content);
for (let rowIndex = 0; rowIndex < maxColumnFieldsSize; rowIndex++) {
content?.columns.flatMap((currentColumn) => {
if (!!currentColumn?.fields[rowIndex]) {
if (currentColumn?.fields[rowIndex]) {
serialisedFormFields.push(currentColumn?.fields[rowIndex]);
} else {
const firstRowElementColSpan = currentColumn?.fields[0]?.colspan;

File diff suppressed because it is too large Load Diff

@ -38,13 +38,11 @@ import { FormModel } from './form.model';
declare let moment: any;
describe('FormFieldValidator', () => {
describe('RequiredFieldValidator', () => {
let validator: RequiredFieldValidator;
beforeEach(() => {
validator = new RequiredFieldValidator();
validator = new RequiredFieldValidator();
});
it('should require [required] setting', () => {
@ -71,9 +69,7 @@ describe('FormFieldValidator', () => {
const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DROPDOWN,
value: '<empty>',
options: [
{id: 'empty', name: 'Choose option...'}
],
options: [{ id: 'empty', name: 'Choose option...' }],
hasEmptyValue: true,
required: true
});
@ -241,10 +237,9 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBeFalsy();
});
});
});
describe('NumberFieldValidator', () => {
let validator: NumberFieldValidator;
beforeEach(() => {
@ -305,10 +300,9 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBeFalsy();
expect(field.validationSummary).not.toBeNull();
});
});
});
describe('MinLengthFieldValidator', () => {
let validator: MinLengthFieldValidator;
beforeEach(() => {
@ -357,10 +351,9 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBeFalsy();
expect(field.validationSummary).not.toBeNull();
});
});
});
describe('MaxLengthFieldValidator', () => {
let validator: MaxLengthFieldValidator;
beforeEach(() => {
@ -412,7 +405,6 @@ describe('FormFieldValidator', () => {
});
describe('MinValueFieldValidator', () => {
let validator: MinValueFieldValidator;
beforeEach(() => {
@ -480,10 +472,9 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBeFalsy();
expect(field.validationSummary).not.toBeNull();
});
});
});
describe('MaxValueFieldValidator', () => {
let validator: MaxValueFieldValidator;
beforeEach(() => {
@ -551,10 +542,9 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBeFalsy();
expect(field.validationSummary).not.toBeNull();
});
});
});
describe('RegExFieldValidator', () => {
let validator: RegExFieldValidator;
beforeEach(() => {
@ -610,10 +600,9 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBeFalsy();
});
});
});
describe('FixedValueFieldValidator', () => {
let validator: FixedValueFieldValidator;
beforeEach(() => {
@ -647,7 +636,10 @@ describe('FormFieldValidator', () => {
const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.TYPEAHEAD,
value: '1',
options: [{id: '1', name: 'Leanne Graham'}, {id: '2', name: 'Ervin Howell'}]
options: [
{ id: '1', name: 'Leanne Graham' },
{ id: '2', name: 'Ervin Howell' }
]
});
expect(validator.validate(field)).toBeTruthy();
@ -657,15 +649,17 @@ describe('FormFieldValidator', () => {
const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.TYPEAHEAD,
value: 'Lean',
options: [{id: '1', name: 'Leanne Graham'}, {id: '2', name: 'Ervin Howell'}]
options: [
{ id: '1', name: 'Leanne Graham' },
{ id: '2', name: 'Ervin Howell' }
]
});
expect(validator.validate(field)).toBeFalsy();
});
});
});
describe('MaxDateTimeFieldValidator', () => {
let validator: MaxDateTimeFieldValidator;
beforeEach(() => {
@ -788,10 +782,9 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBeFalsy();
expect(field.validationSummary).not.toBeNull();
});
});
});
describe('MinDateTimeFieldValidator', () => {
let validator: MinDateTimeFieldValidator;
beforeEach(() => {
@ -914,10 +907,9 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBeFalsy();
expect(field.validationSummary).not.toBeNull();
});
});
});
describe('MaxDateFieldValidator', () => {
let validator: MaxDateFieldValidator;
beforeEach(() => {
@ -1007,10 +999,9 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBeFalsy();
expect(field.validationSummary).not.toBeNull();
});
});
});
describe('MinDateFieldValidator', () => {
let validator: MinDateFieldValidator;
beforeEach(() => {
@ -1100,10 +1091,9 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBeFalsy();
expect(field.validationSummary).not.toBeNull();
});
});
});
describe('DateTimeFieldValidator', () => {
let validator: DateTimeFieldValidator;
beforeEach(() => {
@ -1114,7 +1104,7 @@ describe('FormFieldValidator', () => {
const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATETIME,
value: '2021-06-09 14:10',
dateDisplayFormay: 'YYYY-MM-DD HH:mm'
dateDisplayFormat: 'YYYY-MM-DD HH:mm'
});
expect(validator.validate(field)).toBeTruthy();

@ -272,11 +272,10 @@ export class FormFieldModel extends FormWidgetModel {
if (json.fields) {
for (const currentField in json.fields) {
if (json.fields.hasOwnProperty(currentField)) {
if (Object.prototype.hasOwnProperty.call(json.fields, currentField)) {
const col = new ContainerColumnModel();
const fields: FormFieldModel[] = (json.fields[currentField] || []).map((field) => new FormFieldModel(form, field));
col.fields = fields;
col.fields = (json.fields[currentField] || []).map((field) => new FormFieldModel(form, field));
col.rowspan = json.fields[currentField].length;
col.fields.forEach((colFields: any) => {
@ -291,7 +290,7 @@ export class FormFieldModel extends FormWidgetModel {
}
parseValue(json: any): any {
let value = json.hasOwnProperty('value') && json.value !== undefined ? json.value : null;
let value = Object.prototype.hasOwnProperty.call(json, 'value') && json.value !== undefined ? json.value : null;
/*
This is needed due to Activiti issue related to reading dropdown values as value string
@ -363,7 +362,7 @@ export class FormFieldModel extends FormWidgetModel {
}
switch (this.type) {
case FormFieldTypes.DROPDOWN:
case FormFieldTypes.DROPDOWN: {
if (!this.value) {
this.form.values[this.id] = null;
break;
@ -390,13 +389,15 @@ export class FormFieldModel extends FormWidgetModel {
}
}
break;
case FormFieldTypes.RADIO_BUTTONS:
}
case FormFieldTypes.RADIO_BUTTONS: {
const radioButton: FormFieldOption[] = this.options.filter((opt) => opt.id === this.value);
if (radioButton.length > 0) {
this.form.values[this.id] = radioButton[0];
}
break;
case FormFieldTypes.UPLOAD:
}
case FormFieldTypes.UPLOAD: {
this.form.hasUpload = true;
if (this.value && this.value.length > 0) {
this.form.values[this.id] = Array.isArray(this.value) ? this.value.map((elem) => elem.id).join(',') : [this.value];
@ -404,7 +405,8 @@ export class FormFieldModel extends FormWidgetModel {
this.form.values[this.id] = null;
}
break;
case FormFieldTypes.TYPEAHEAD:
}
case FormFieldTypes.TYPEAHEAD: {
const typeAheadEntry: FormFieldOption[] = this.options.filter((opt) => opt.id === this.value || opt.name === this.value);
if (typeAheadEntry.length > 0) {
this.form.values[this.id] = typeAheadEntry[0];
@ -412,7 +414,8 @@ export class FormFieldModel extends FormWidgetModel {
this.form.values[this.id] = null;
}
break;
case FormFieldTypes.DATE:
}
case FormFieldTypes.DATE: {
if (typeof this.value === 'string' && this.value === 'today') {
this.value = moment(new Date()).format(this.dateDisplayFormat);
}
@ -425,7 +428,8 @@ export class FormFieldModel extends FormWidgetModel {
this._value = this.value;
}
break;
case FormFieldTypes.DATETIME:
}
case FormFieldTypes.DATETIME: {
if (typeof this.value === 'string' && this.value === 'now') {
this.value = moment(new Date()).utc().format(this.dateDisplayFormat);
}
@ -439,21 +443,27 @@ export class FormFieldModel extends FormWidgetModel {
this._value = this.value;
}
break;
case FormFieldTypes.NUMBER:
}
case FormFieldTypes.NUMBER: {
this.form.values[this.id] = this.enableFractions ? parseFloat(this.value) : parseInt(this.value, 10);
break;
case FormFieldTypes.AMOUNT:
}
case FormFieldTypes.AMOUNT: {
this.form.values[this.id] = this.enableFractions ? parseFloat(this.value) : parseInt(this.value, 10);
break;
case FormFieldTypes.BOOLEAN:
}
case FormFieldTypes.BOOLEAN: {
this.form.values[this.id] = this.value !== null && this.value !== undefined ? this.value : false;
break;
case FormFieldTypes.PEOPLE:
}
case FormFieldTypes.PEOPLE: {
this.form.values[this.id] = this.value ? this.value : null;
break;
case FormFieldTypes.FUNCTIONAL_GROUP:
}
case FormFieldTypes.FUNCTIONAL_GROUP: {
this.form.values[this.id] = this.value ? this.value : null;
break;
}
default:
if (!FormFieldTypes.isReadOnlyType(this.type) && !this.isInvalidFieldType(this.type)) {
this.form.values[this.id] = this.value;

@ -265,7 +265,7 @@ export class FormModel implements ProcessFormModel {
getDefaultFormVariableValue(identifier: string): any {
const variable = this.getFormVariable(identifier);
if (variable?.hasOwnProperty('value')) {
if (variable && Object.prototype.hasOwnProperty.call(variable, 'value')) {
return this.parseValue(variable.type, variable.value);
}
@ -420,7 +420,7 @@ export class FormModel implements ProcessFormModel {
const visibilityRule: WidgetVisibilityModel = new WidgetVisibilityModel();
const field = this.getFieldById(fieldId);
if (!!field) {
if (field) {
visibilityRule.operator = visibility ? 'empty' : '!empty';
visibilityRule.leftType = WidgetTypeEnum.field;
field.visibilityCondition = visibilityRule;
@ -430,28 +430,28 @@ export class FormModel implements ProcessFormModel {
changeFieldDisabled(fieldId: string, disabled: boolean): void {
const field = this.getFieldById(fieldId);
if (!!field) {
if (field) {
field.readOnly = this.readOnly || disabled;
}
}
changeFieldRequired(fieldId: string, required: boolean): void {
const field = this.getFieldById(fieldId);
if (!!field) {
if (field) {
field.required = required;
}
}
changeFieldValue(fieldId: string, value: any): void {
const field = this.getFieldById(fieldId);
if (!!field) {
if (field) {
field.value = value;
}
}
changeVariableValue(variableId: string, value: any): void {
const variable = this.getFormVariable(variableId);
if (!!variable) {
if (variable) {
variable.value = value;
}
}

@ -33,7 +33,7 @@ export function formRulesManagerFactory<T>(injector: Injector): FormRulesManager
}
export abstract class FormRulesManager<T> {
constructor(private formService: FormService) { }
constructor(private formService: FormService) {}
protected formModel: FormModel;
private onDestroy$ = new Subject<boolean>();
@ -50,12 +50,13 @@ export abstract class FormRulesManager<T> {
if (!this.formModel.readOnly) {
const rules = this.getRules();
if (!!rules) {
if (rules) {
this.formService.formRulesEvent
.pipe(
filter(event => !!event?.form?.id && event.form.id === formModel?.id),
filter((event) => !!event?.form?.id && event.form.id === formModel?.id),
takeUntil(this.onDestroy$)
).subscribe(event => {
)
.subscribe((event) => {
this.handleRuleEvent(event, rules);
});
@ -76,7 +77,6 @@ export abstract class FormRulesManager<T> {
}
export class ByPassFormRuleManager<T> extends FormRulesManager<T> {
protected getRules(): T {
return null;
}

@ -43,7 +43,7 @@ export class WidgetVisibilityModel {
return WidgetTypeEnum.field;
} else if (this.leftRestResponseId) {
return WidgetTypeEnum.variable;
} else if (!!this.json.leftType) {
} else if (this.json.leftType) {
return this.json.leftType;
}
return null;
@ -68,7 +68,7 @@ export class WidgetVisibilityModel {
}
get rightType(): string {
if (!!this.json.rightType) {
if (this.json.rightType) {
return this.json.rightType;
} else if (this.json.rightValue) {
return WidgetTypeEnum.value;

@ -68,7 +68,7 @@ export class WidgetVisibilityService {
}
}
public isFieldVisible(form: FormModel, visibilityObj: WidgetVisibilityModel, accumulator: any[] = [], result: boolean = false): boolean {
public isFieldVisible(form: FormModel, visibilityObj: WidgetVisibilityModel, accumulator: any[] = [], result?: boolean): boolean {
const leftValue = this.getLeftValue(form, visibilityObj);
const rightValue = this.getRightValue(form, visibilityObj);
const actualResult = this.evaluateCondition(leftValue, rightValue, visibilityObj.operator);
@ -88,7 +88,7 @@ export class WidgetVisibilityService {
}
private transformToLiteralExpression(currentExpression: any): string {
const currentTransformedValue = !!currentExpression.value ? 'true' : 'false';
const currentTransformedValue = currentExpression.value ? 'true' : 'false';
return currentTransformedValue.concat(this.transformToLiteralOperator(currentExpression.operator));
}
@ -206,9 +206,9 @@ export class WidgetVisibilityService {
const containers = this.getFormTabContainers(form);
let isVisible: boolean = true;
containers.map((container: ContainerModel) => {
if (!!this.getCurrentFieldFromTabById(container, currentFormField.id)) {
if (this.getCurrentFieldFromTabById(container, currentFormField.id)) {
const currentTab = form.tabs.find((tab: TabModel) => tab.id === container.tab);
if (!!currentTab) {
if (currentTab) {
isVisible = currentTab.isVisible;
}
}
@ -230,7 +230,7 @@ export class WidgetVisibilityService {
}
private getFormTabContainers(form: FormModel): ContainerModel[] {
if (!!form) {
if (form) {
return form.fields.filter((field) => field.type === 'container' && field.tab) as ContainerModel[];
}
return [];

@ -15,6 +15,8 @@
* limitations under the License.
*/
/* eslint-disable @cspell/spellchecker */
export const mockTabText = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam urna odio, sagittis vel nulla vel, condimentum egestas dolor.
Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris eu hendrerit lectus. Aliquam et ex imperdiet, sodales tellus finibus, malesuada eros.
Vestibulum aliquet eros sed diam euismod tincidunt.

@ -38,7 +38,7 @@ export class CookieServiceMock extends CookieService {
/** @override */
clear() {
Object.keys(this).forEach((key) => {
if (this.hasOwnProperty(key) && typeof this[key] !== 'function') {
if (Object.prototype.hasOwnProperty.call(this, key) && typeof this[key] !== 'function') {
this[key] = undefined;
}
});

@ -16,7 +16,6 @@
*/
export class DemoForm {
easyForm: any = {
formRepresentation: {
id: 1001,
@ -1859,10 +1858,10 @@ export class DemoForm {
id: 'my1r7YmMOs',
type: 'paragraph',
data: {
text: `<font color="#000000">Is simply a redonly</font><mark class="cdx-marker">
text: `<font color="#000000">Is simply a readonly</font><mark class="cdx-marker">
<font color="#000000">dummy </font><b>text</b></mark><b></b><font color="#000000">
of the </font><i>printing and typesetting</i><font color="#000000"> industry.\n
</font><b><i>Lorem</i></b><font color="#000000"> Ipsum has been the industry\'s standard du</font><b>
</font><b><i>Lorem</i></b><font color="#000000"> Ipsum has been the industry's standard du</font><b>
<i>mmy text ever since the 1500s,\n when an unknown printer took a galley of type
and scrambled it to make a type specime</i></b><font color="#000000">n book. </font><font color="#ff1300">
It has survived not only five centuries</font><font color="#000000">,\n
@ -1880,10 +1879,7 @@ export class DemoForm {
type: 'list',
data: {
style: 'unordered',
items: [
'Unordered list example',
'Unordered list example'
]
items: ['Unordered list example', 'Unordered list example']
}
},
{
@ -1954,5 +1950,4 @@ export class DemoForm {
getFormCloudDefinition(): any {
return this.cloudFormDefinition;
}
}

@ -15,7 +15,7 @@
* limitations under the License.
*/
export const formDefVisibilitiFieldDependsOnNextOne: any = {
export const formDefVisibilityFieldDependsOnNextOne: any = {
id: 19,
processDefinitionId: 'visibility:1:148',
processDefinitionName: 'visibility',

@ -173,13 +173,12 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
const urlFile = changes['urlFile'];
if (urlFile?.currentValue) {
const pdfOptions = {
const pdfOptions: any = {
...this.pdfjsDefaultOptions,
url: urlFile.currentValue,
withCredentials: this.appConfigService.get<boolean>('auth.withCredentials', undefined)
};
if (this.cacheType) {
// @ts-ignore
pdfOptions.httpHeaders = {
'Cache-Control': this.cacheType
};

@ -24,7 +24,6 @@ import { Injectable } from '@angular/core';
*/
@Injectable()
export class RenderingQueueServices {
renderingStates = {
INITIAL: 0,
RUNNING: 1,
@ -149,22 +148,27 @@ export class RenderingQueueServices {
renderView(view: any) {
const state = view.renderingState;
switch (state) {
case this.renderingStates.FINISHED:
case this.renderingStates.FINISHED: {
return false;
case this.renderingStates.PAUSED:
}
case this.renderingStates.PAUSED: {
this.highestPriorityPage = view.renderingId;
view.resume();
break;
case this.renderingStates.RUNNING:
}
case this.renderingStates.RUNNING: {
this.highestPriorityPage = view.renderingId;
break;
case this.renderingStates.INITIAL:
}
case this.renderingStates.INITIAL: {
this.highestPriorityPage = view.renderingId;
const continueRendering = function() {
// eslint-disable-next-line space-before-function-paren
const continueRendering = function () {
this.renderHighestPriority();
}.bind(this);
view.draw().then(continueRendering, continueRendering);
break;
}
default:
break;
}

@ -22,7 +22,6 @@ import { AppExtensionService, ViewerExtensionRef } from '@alfresco/adf-extension
providedIn: 'root'
})
export class ViewUtilService {
// Extensions that are supported by the Viewer without conversion
private extensions = {
image: ['png', 'jpg', 'jpeg', 'gif', 'bpm', 'svg'],
@ -50,11 +49,10 @@ export class ViewUtilService {
* Provides a list of file extensions supported by external plugins.
*/
get externalExtensions(): string[] {
return this.viewerExtensions.map(ext => ext.fileExtension);
return this.viewerExtensions.map((ext) => ext.fileExtension);
}
constructor(private extensionService: AppExtensionService) {
}
constructor(private extensionService: AppExtensionService) {}
/**
* get File name from url
@ -64,9 +62,7 @@ export class ViewUtilService {
getFilenameFromUrl(url: string): string {
const anchor = url.indexOf('#');
const query = url.indexOf('?');
const end = Math.min(
anchor > 0 ? anchor : url.length,
query > 0 ? query : url.length);
const end = Math.min(anchor > 0 ? anchor : url.length, query > 0 ? query : url.length);
return url.substring(url.lastIndexOf('/', end) + 1, end);
}
@ -80,13 +76,13 @@ export class ViewUtilService {
*/
getFileExtension(fileName: string): string {
if (fileName) {
const match = fileName.match(/\.([^\./\?\#]+)($|\?|\#)/);
const match = fileName.match(/\.([^./?#]+)($|\?|#)/);
return match ? match[1] : null;
}
return null;
}
getViewerType(extension: string, mimeType: string): string {
getViewerType(extension: string, mimeType: string): string {
let viewerType = this.getViewerTypeByExtension(extension);
if (viewerType === 'unknown') {
@ -143,7 +139,7 @@ export class ViewUtilService {
}
private isExternalViewer(): boolean {
return !!this.viewerExtensions.find(ext => ext.fileExtension === '*');
return !!this.viewerExtensions.find((ext) => ext.fileExtension === '*');
}
isCustomViewerExtension(extension: string): boolean {
@ -156,5 +152,4 @@ export class ViewUtilService {
return false;
}
}

@ -94,7 +94,7 @@ export class DynamicColumnComponent implements OnInit, OnChanges, OnDestroy {
}
private updateInstance() {
if (this.componentRef && this.componentRef.instance) {
if (this.componentRef?.instance) {
this.componentRef.instance.context = this.context;
}
}

@ -89,8 +89,9 @@ export class DynamicExtensionComponent implements OnChanges, OnDestroy {
}
}
private proxy(lifecycleMethod, ...args) {
private proxy(lifecycleMethod: string, ...args: any[]) {
if (this.componentCreated() && this.lifecycleHookIsImplemented(lifecycleMethod)) {
// eslint-disable-next-line prefer-spread
this.componentRef.instance[lifecycleMethod].apply(this.componentRef.instance, args);
}
}

@ -80,7 +80,7 @@ export class DynamicTabComponent implements OnInit, OnChanges, OnDestroy {
}
private updateInstance() {
if (this.componentRef && this.componentRef.instance) {
if (this.componentRef?.instance) {
this.componentRef.instance.node = this.node;
}
}

@ -87,7 +87,7 @@ export class PreviewExtensionComponent implements OnInit, OnChanges, OnDestroy {
}
private updateInstance() {
if (this.componentRef && this.componentRef.instance) {
if (this.componentRef?.instance) {
const instance = this.componentRef.instance;
instance.url = this.url;

@ -135,7 +135,7 @@ export const mergeArrays = (left: any[], right: any[]): any[] => {
(left || []).forEach((entry) => {
const element = entry;
if (element && element.hasOwnProperty('id')) {
if (element && Object.prototype.hasOwnProperty.call(element, 'id')) {
map[element.id] = element;
} else {
result.push(element);
@ -144,7 +144,7 @@ export const mergeArrays = (left: any[], right: any[]): any[] => {
(right || []).forEach((entry) => {
const element = entry;
if (element && element.hasOwnProperty('id') && map[element.id]) {
if (element && Object.prototype.hasOwnProperty.call(element, 'id') && map[element.id]) {
const merged = mergeObjects(map[element.id], element);
map[element.id] = merged;
} else {

@ -79,7 +79,7 @@ export class AppExtensionService {
return true;
}
if (extension.rules && extension.rules.disabled) {
if (extension.rules?.disabled) {
return this.extensionService.evaluateRule(extension.rules.disabled);
}
}

@ -42,7 +42,7 @@ export class ExtensionLoaderService {
config = JSON.parse(override);
}
if (!config.$references || !config.$references.length) {
if (!config.$references?.length) {
config.$references = this.filterIgnoredExtensions(extensions || [], config.$ignoreReferenceList);
} else {
config.$references = this.filterIgnoredExtensions(config.$references, config.$ignoreReferenceList);
@ -102,7 +102,7 @@ export class ExtensionLoaderService {
}
getRules(config: ExtensionConfig): Array<RuleRef> {
if (config && config.rules) {
if (config?.rules) {
return config.rules;
}
return [];
@ -170,10 +170,10 @@ export class ExtensionLoaderService {
}
private filterIgnoredExtensions(extensions: Array<string | ExtensionRef>, ignoreReferenceList: string[]): Array<string | ExtensionRef> {
if (!ignoreReferenceList || !ignoreReferenceList.length) {
if (!ignoreReferenceList?.length) {
return extensions;
}
return extensions.map((file: string) => file.match('(?!.*\/).+')[0]).filter((fileName: string) => !ignoreReferenceList.includes(fileName));
return extensions.map((file: string) => file.match('(?!.*/).+')[0]).filter((fileName: string) => !ignoreReferenceList.includes(fileName));
}
}

@ -68,8 +68,8 @@ describe('ExtensionService', () => {
}
});
const requestedFeatue = service.getFeature('searchedArrayFeature');
expect(requestedFeatue).toEqual(searchedArrayFeature);
const requestedFeature = service.getFeature('searchedArrayFeature');
expect(requestedFeature).toEqual(searchedArrayFeature);
});
it('should return object if seached feature is an object', async () => {
@ -81,16 +81,16 @@ describe('ExtensionService', () => {
}
});
const requestedFeatue = service.getFeature<{ test: string }>('searchedObjectFeature');
expect(requestedFeatue).toEqual(searchedObjectFeature);
const requestedFeature = service.getFeature<{ test: string }>('searchedObjectFeature');
expect(requestedFeature).toEqual(searchedObjectFeature);
});
it('should return default value if feature is not found', async () => {
const defaultValue = {};
service.setup(blankConfig);
const requestedFeatue = service.getFeature<{ test: string }>('searchedFeature', defaultValue);
expect(requestedFeatue).toEqual(defaultValue);
const requestedFeature = service.getFeature<{ test: string }>('searchedFeature', defaultValue);
expect(requestedFeature).toEqual(defaultValue);
});
});

@ -123,7 +123,7 @@ export class ExtensionService {
*/
getFeature<T = any[]>(key: string | string[], defaultValue: any = []): T {
const properties: string[] = Array.isArray(key) ? key : key.split('.');
return properties.reduce((prev, curr) => prev && prev[curr], this.features) || defaultValue;
return properties.reduce((prev, curr) => prev?.[curr], this.features) || defaultValue;
}
getElements<T extends ExtensionElement>(key: string, fallback: Array<T> = []): Array<T> {

@ -62,7 +62,7 @@ export class RuleService {
* @returns RuleEvaluator or null if not found
*/
getEvaluator(key: string): RuleEvaluator {
if (key && key.startsWith('!')) {
if (key?.startsWith('!')) {
const fn = this.evaluators[key.substring(1)];
return (context: RuleContext, ...args: RuleParameter[]): boolean => !fn(context, ...args);
}

@ -175,7 +175,7 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On
onValueChanged(values: any) {
this.formValueChanged.emit(values);
if (this.reportForm && this.reportForm.valid) {
if (this.reportForm?.valid) {
this.submit(values);
}
}
@ -306,7 +306,7 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On
}
ngAfterContentChecked() {
if (this.reportForm && this.reportForm.valid) {
if (this.reportForm?.valid) {
this.reportForm.markAsDirty();
}
}
@ -320,7 +320,7 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On
}
isFormValid() {
return this.reportForm && this.reportForm.dirty && this.reportForm.valid;
return this.reportForm?.dirty && this.reportForm.valid;
}
get taskGroup(): UntypedFormGroup {

@ -117,7 +117,7 @@ export class DiagramComponent implements OnChanges {
setMetricValueToDiagramElement(diagram: DiagramModel, metrics: any, metricType: string) {
for (const key in metrics) {
if (metrics.hasOwnProperty(key)) {
if (Object.prototype.hasOwnProperty.call(metrics, key)) {
const foundElement: DiagramElementModel = diagram.elements.find(
(element: DiagramElementModel) => element.id === key);
if (foundElement) {

@ -40,8 +40,8 @@ export class BarChart extends Chart {
constructor(obj?: any) {
super(obj);
this.xAxisType = obj && obj.xAxisType || null;
this.yAxisType = obj && obj.yAxisType || null;
this.xAxisType = obj?.xAxisType || null;
this.yAxisType = obj?.yAxisType || null;
this.options.scales.xAxes[0].ticks.callback = this.xAxisTickFormatFunction(this.xAxisType);
this.options.scales.yAxes[0].ticks.callback = this.yAxisTickFormatFunction(this.yAxisType);
if (obj.values) {

@ -34,7 +34,7 @@ export class DiagramColorService {
}
getFillColour(key: string) {
if (this.totalColors?.hasOwnProperty(key)) {
if (this.totalColors && Object.prototype.hasOwnProperty.call(this.totalColors, key)) {
const colorPercentage = this.totalColors[key];
return this.convertColorToHsb(colorPercentage);
} else {

@ -578,7 +578,7 @@ describe('FormCloudComponent', () => {
spyOn(formComponent, 'handleError').and.stub();
spyOn(formCloudService, 'getTaskForm').and.callFake(() => throwError(error));
formComponent.getFormByTaskId('test-app', '123').then((_) => {
formComponent.getFormByTaskId('test-app', '123').then(() => {
expect(formComponent.handleError).toHaveBeenCalledWith(error);
done();
});
@ -1049,7 +1049,7 @@ describe('FormCloudComponent', () => {
pfx_property_five: 'orange',
pfx_property_none: 'no_form_field'
}, 'Complete', 123).subscribe({
next: _ => done.fail('expected an error, not data'),
next: () => done.fail('expected an error, not data'),
error: error => {
expect(error).toBe(errorMessage);
expect(formComponent.disableSaveButton).toBeFalse();

@ -94,7 +94,7 @@ export class AttachFileCloudWidgetComponent extends UploadCloudWidgetComponent i
this.contentModelFormFileHandler(files[0]);
}
this.field.params.displayableCMProperties = this.field.params.displayableCMProperties ?? [];
this.displayedColumns.splice(2, 0, ...this.field.params.displayableCMProperties?.map(property => property?.name));
this.displayedColumns.splice(2, 0, ...(this.field.params.displayableCMProperties?.map(property => property?.name) || []));
}
isPathStaticType(): boolean {

Some files were not shown because too many files have changed in this diff Show More