AAE-36664 additional linting rules, cleanup (#11084)

This commit is contained in:
Denys Vuika
2025-08-13 08:01:09 -04:00
committed by GitHub
parent e83c8f7fd7
commit b16e326ac3
71 changed files with 235 additions and 2994 deletions
@@ -20,7 +20,6 @@ import { ContentService } from './content.service';
import { AppConfigService, AuthenticationService, RedirectAuthService, StorageService } from '@alfresco/adf-core';
import { Node, PermissionsInfo } from '@alfresco/js-api';
import { EMPTY, of } from 'rxjs';
import { HttpClientTestingModule } from '@angular/common/http/testing';
describe('ContentService', () => {
let contentService: ContentService;
@@ -29,7 +28,6 @@ describe('ContentService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [ContentService, AuthenticationService, { provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } }]
});
authService = TestBed.inject(AuthenticationService);
@@ -73,7 +73,11 @@ export class RenditionService {
return this._versionsApi;
}
constructor(private apiService: AlfrescoApiService, private translateService: TranslationService, private viewUtilsService: ViewUtilService) {}
constructor(
private readonly apiService: AlfrescoApiService,
private readonly translateService: TranslationService,
private readonly viewUtilsService: ViewUtilService
) {}
getRenditionUrl(nodeId: string, type: string, renditionExists: boolean): string {
return renditionExists && type !== RenditionService.ContentGroup.IMAGE
@@ -167,7 +171,7 @@ export class RenditionService {
}
try {
return versionId ? await this.waitNodeRendition(nodeId, renditionId, versionId) : await this.waitNodeRendition(nodeId, renditionId);
} catch (e) {
} catch {
return null;
}
} catch {
@@ -54,7 +54,7 @@ const customSiteList = {
describe('DropdownSitesComponent', () => {
let loader: HarnessLoader;
let component: any;
let component: DropdownSitesComponent;
let fixture: ComponentFixture<DropdownSitesComponent>;
let element: HTMLElement;
let siteService: SitesService;
@@ -167,7 +167,7 @@ describe('DropdownSitesComponent', () => {
});
it('should load custom sites when the "siteList" input property is given a value', async () => {
component.siteList = customSiteList;
component.siteList = customSiteList as any;
fixture.detectChanges();
await fixture.whenStable();
@@ -246,7 +246,7 @@ describe('DropdownSitesComponent', () => {
fixture.whenStable().then(() => {
expect(component.selected).toBeUndefined();
expect(component.loading).toBeFalsy();
expect(component.isLoading).toBeFalsy();
done();
});
});
@@ -290,7 +290,7 @@ describe('DropdownSitesComponent', () => {
describe('No relations', () => {
beforeEach(() => {
component.relations = [];
component.relations = '';
authService = TestBed.inject(AuthenticationService);
});
@@ -89,6 +89,10 @@ export class DropdownSitesComponent implements OnInit {
selected: SiteEntry = null;
MY_FILES_VALUE = '-my-';
get isLoading(): boolean {
return this.loading;
}
constructor(
private authService: AuthenticationService,
private sitesService: SitesService,
@@ -161,7 +161,7 @@ export class FolderDialogComponent implements OnInit {
if (statusCode === 409) {
errorMessage = 'CORE.MESSAGES.ERRORS.EXISTENT_FOLDER';
}
} catch (err) {
} catch {
/* Do nothing, keep the original message */
}
@@ -20,7 +20,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { NodeDeleteDirective } from './node-delete.directive';
import { RedirectAuthService } from '@alfresco/adf-core';
import { EMPTY, of } from 'rxjs';
import { EMPTY, of, Subscription } from 'rxjs';
import { CheckAllowableOperationDirective } from './check-allowable-operation.directive';
@Component({
@@ -73,10 +73,10 @@ describe('NodeDeleteDirective', () => {
let elementWithPermanentDelete: DebugElement;
let component: TestComponent;
let componentWithPermanentDelete: TestDeletePermanentComponent;
let deleteNodeSpy: any;
let disposableDelete: any;
let deleteNodePermanentSpy: any;
let purgeDeletedNodePermanentSpy: any;
let deleteNodeSpy: jasmine.Spy;
let disposableDelete: Subscription;
let deleteNodePermanentSpy: jasmine.Spy;
let purgeDeletedNodePermanentSpy: jasmine.Spy;
beforeEach(() => {
TestBed.configureTestingModule({
@@ -38,7 +38,7 @@ describe('NodeRestoreDirective', () => {
let component: TestComponent;
let trashcanApi: TrashcanApi;
let directiveInstance: NodeRestoreDirective;
let restoreNodeSpy: any;
let restoreNodeSpy: jasmine.Spy;
let translationService: TranslationService;
beforeEach(() => {
@@ -131,7 +131,7 @@ describe('NodeRestoreDirective', () => {
it('should notify on multiple fails', (done) => {
const error = { message: '{ "error": {} }' };
directiveInstance.restore.subscribe((event: any) => {
directiveInstance.restore.subscribe((event) => {
expect(event.message).toEqual('CORE.RESTORE_NODE.PARTIAL_PLURAL');
done();
});
@@ -193,7 +193,7 @@ describe('NodeRestoreDirective', () => {
restoreNodeSpy.and.returnValue(Promise.reject(error));
directiveInstance.restore.subscribe((event: any) => {
directiveInstance.restore.subscribe((event) => {
expect(event.message).toEqual('CORE.RESTORE_NODE.LOCATION_MISSING');
done();
});
@@ -205,7 +205,7 @@ describe('NodeRestoreDirective', () => {
});
it('should notify success when restore multiple nodes', (done) => {
directiveInstance.restore.subscribe((event: any) => {
directiveInstance.restore.subscribe((event) => {
expect(event.message).toEqual('CORE.RESTORE_NODE.PLURAL');
done();
@@ -52,7 +52,6 @@ import {
} from '../../mock';
import { ContentTestingModule } from '../../testing/content.testing.module';
import { domSanitizerMock } from '../../testing/dom-sanitizer-mock';
import { matIconRegistryMock } from '../../testing/mat-icon-registry-mock';
import { ImageResolver } from '../data/image-resolver.model';
import { RowFilter } from '../data/row-filter.model';
import { ShareDataRow } from '../data/share-data-row.model';
@@ -64,11 +63,16 @@ import { FileAutoDownloadComponent } from './file-auto-download/file-auto-downlo
import { DocumentListComponent } from './document-list.component';
import { CustomResourcesService, DocumentListService } from '../public-api';
import { CommonModule } from '@angular/common';
import { MatIconRegistry } from '@angular/material/icon';
const mockDialog = {
open: jasmine.createSpy('open')
};
export const matIconRegistryMock = {
addSvgIconInNamespace: () => {}
} as any as MatIconRegistry;
describe('DocumentList', () => {
let loader: HarnessLoader;
let documentList: DocumentListComponent;
@@ -430,7 +430,7 @@ export class DocumentListComponent extends DataTableSchema implements OnInit, On
dataTable: DataTableComponent;
actions: ContentActionModel[] = [];
contextActionHandler: Subject<any> = new Subject();
contextActionHandler = new Subject();
data: ShareDataTableAdapter;
noPermission: boolean = false;
selection = new Array<NodeEntry>();
@@ -1051,7 +1051,7 @@ export class DocumentListComponent extends DataTableSchema implements OnInit, On
if (JSON.parse(err.message).error.statusCode === 403) {
this.noPermission = true;
}
} catch (error) {
} catch {
/* empty */
}
}
@@ -57,17 +57,3 @@ export enum ContentActionTarget {
}
export type ContentActionHandler = (obj: any, target?: any, permission?: string) => any;
export class DocumentActionModel extends ContentActionModel {
constructor(json?: any) {
super(json);
this.target = 'document';
}
}
export class FolderActionModel extends ContentActionModel {
constructor(json?: any) {
super(json);
this.target = 'folder';
}
}
@@ -95,7 +95,7 @@ describe('FolderActionsService', () => {
it('should delete the folder node if there is the delete permission', () => {
spyOn(documentListService, 'deleteNode').and.callFake(
() =>
new Observable<any>((observer) => {
new Observable((observer) => {
observer.next(undefined);
observer.complete();
})
@@ -156,7 +156,7 @@ describe('FolderActionsService', () => {
it('should delete the folder node if there is the delete and others permission ', () => {
spyOn(documentListService, 'deleteNode').and.callFake(
() =>
new Observable<any>((observer) => {
new Observable((observer) => {
observer.next(undefined);
observer.complete();
})
@@ -174,7 +174,7 @@ describe('FolderActionsService', () => {
it('should support deletion only folder node', () => {
spyOn(documentListService, 'deleteNode').and.callFake(
() =>
new Observable<any>((observer) => {
new Observable((observer) => {
observer.next(undefined);
observer.complete();
})
@@ -195,7 +195,7 @@ describe('FolderActionsService', () => {
it('should require node id to delete', () => {
spyOn(documentListService, 'deleteNode').and.callFake(
() =>
new Observable<any>((observer) => {
new Observable((observer) => {
observer.next(undefined);
observer.complete();
})
@@ -211,7 +211,7 @@ describe('FolderActionsService', () => {
it('should reload target upon node deletion', async () => {
spyOn(documentListService, 'deleteNode').and.callFake(
() =>
new Observable<any>((observer) => {
new Observable((observer) => {
observer.next(undefined);
observer.complete();
})
@@ -25,14 +25,13 @@ import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
import { ReplaySubject } from 'rxjs';
import { UnitTestingUtils } from '@alfresco/adf-core';
import { MatCheckbox } from '@angular/material/checkbox';
import { By } from '@angular/platform-browser';
describe('SearchCheckListComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<SearchCheckListComponent>;
let component: SearchCheckListComponent;
let unitTestingUtils: UnitTestingUtils;
beforeEach(() => {
TestBed.configureTestingModule({
@@ -41,7 +40,6 @@ describe('SearchCheckListComponent', () => {
fixture = TestBed.createComponent(SearchCheckListComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
unitTestingUtils = new UnitTestingUtils(fixture.debugElement);
component.context = {
queryFragments: {},
@@ -149,7 +147,7 @@ describe('SearchCheckListComponent', () => {
]);
fixture.detectChanges();
const checkboxes = unitTestingUtils.getAllByDirective(MatCheckbox);
const checkboxes = fixture.debugElement.queryAll(By.directive(MatCheckbox));
expect(checkboxes.length).toBe(2);
expect(checkboxes.every((checkbox) => checkbox.componentInstance.labelPosition === 'after')).toBeTrue();
});
@@ -43,7 +43,7 @@ describe('TagActionsComponent', () => {
}
};
let component: any;
let component: TagActionsComponent;
let fixture: ComponentFixture<TagActionsComponent>;
let element: HTMLElement;
let tagService: TagService;
@@ -90,7 +90,7 @@ describe('TagActionsComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const deleteButton: any = element.querySelector('#tag_delete_test1');
const deleteButton = element.querySelector<HTMLButtonElement>('#tag_delete_test1');
deleteButton.click();
expect(tagService.removeTag).toHaveBeenCalledWith('fake-node-id', '0ee933fa-57fc-4587-8a77-b787e814f1d2');
});
@@ -102,7 +102,7 @@ describe('TagActionsComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const addButton: any = element.querySelector('#add-tag');
const addButton = element.querySelector<HTMLButtonElement>('#add-tag');
expect(addButton.disabled).toEqual(true);
});
@@ -110,7 +110,7 @@ describe('TagActionsComponent', () => {
component.nodeId = 'fake-node-id';
component.newTagName = 'test1';
await component.error.subscribe((res) => {
component.error.subscribe((res) => {
expect(res).toEqual('TAG.MESSAGES.EXIST');
});
@@ -118,7 +118,7 @@ describe('TagActionsComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const addButton: any = element.querySelector('#add-tag');
const addButton = element.querySelector<HTMLButtonElement>('#add-tag');
addButton.click();
});
@@ -130,7 +130,7 @@ describe('TagActionsComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
const addButton: any = element.querySelector('#add-tag');
const addButton = element.querySelector<HTMLButtonElement>('#add-tag');
expect(addButton.disabled).toEqual(false);
});
});
@@ -790,7 +790,7 @@ describe('AlfrescoViewerComponent', () => {
});
it('should Click on close button hide the viewer', (done) => {
const closeButton: any = element.querySelector('.adf-viewer-close-button');
const closeButton = element.querySelector<HTMLButtonElement>('.adf-viewer-close-button');
closeButton.click();
fixture.detectChanges();
@@ -300,7 +300,7 @@ export class AlfrescoViewerComponent implements OnChanges, OnInit {
try {
const sharedLinkEntry = await this.sharedLinksApi.getSharedLink(this.sharedLinkId);
await this.setUpSharedLinkFile(sharedLinkEntry);
} catch (error) {
} catch {
this.invalidSharedLink.next(undefined);
this.mimeType = 'invalid-link';
this.urlFileContent = 'invalid-file';
@@ -317,7 +317,7 @@ export class AlfrescoViewerComponent implements OnChanges, OnInit {
await this.setUpNodeFile(this.nodeEntry.entry);
this.cdr.detectChanges();
}
} catch (error) {
} catch {
this.urlFileContent = 'invalid-node';
}
}
@@ -392,14 +392,14 @@ export class AlfrescoViewerComponent implements OnChanges, OnInit {
const urlFileContent = this.contentApi.getSharedLinkRenditionUrl(sharedId, 'pdf');
return { url: urlFileContent, mimeType: 'application/pdf' };
}
} catch (error) {
} catch {
try {
const rendition: RenditionEntry = await this.sharedLinksApi.getSharedLinkRendition(sharedId, 'imgpreview');
if (rendition.entry.status.toString() === 'CREATED') {
const urlFileContent = this.contentApi.getSharedLinkRenditionUrl(sharedId, 'imgpreview');
return { url: urlFileContent, mimeType: 'image/png' };
}
} catch (renditionError) {
} catch {
return null;
}
}
@@ -313,7 +313,7 @@ export class AdfHttpClient implements ee.Emitter, JsApiHttpClient {
try {
document.cookie = 'CSRF-TOKEN=' + token + ';path=/';
} catch (err) {
} catch {
/* continue regardless of error */
}
}
@@ -58,7 +58,7 @@ describe('FlagsComponent', () => {
});
it('should update inputValue$ when onInputChange is called', (done) => {
(component as any).onInputChange('test');
component.onInputChange('test');
component.inputValue$.subscribe((value) => {
expect(value).toBe('test');
done();
@@ -67,12 +67,12 @@ describe('FlagsComponent', () => {
it('should clear inputValue when onClearInput is called', () => {
component.inputValue = 'test';
(component as any).onClearInput();
component.onClearInput();
expect(component.inputValue).toBe('');
});
it('should filter flags when when onClearInput is called', (done) => {
(component as any).onInputChange('feature1');
component.onInputChange('feature1');
component.flags$.subscribe((flags) => {
expect(flags).toEqual([{ fictive: false, flag: 'feature1', value: true }]);
done();
@@ -123,11 +123,11 @@ export class FlagsComponent {
this.featuresService.enable(value);
}
protected onInputChange(text: string) {
onInputChange(text: string) {
this.inputValue$.next(text);
}
protected onClearInput() {
onClearInput() {
this.inputValue = '';
this.inputValue$.next('');
}
@@ -1,37 +0,0 @@
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { StorageService } from '../common/services/storage.service';
import { AppConfigService, AppConfigValues } from './app-config.service';
@Injectable()
export class DebugAppConfigService extends AppConfigService {
constructor(private storage: StorageService) {
super();
}
get<T>(key: string, defaultValue?: T): T {
if (key === AppConfigValues.OAUTHCONFIG) {
return JSON.parse(this.storage.getItem(key)) || super.get<T>(key, defaultValue);
} else if (key === AppConfigValues.APPLICATION) {
return undefined;
} else {
return (this.storage.getItem(key) as any) || super.get<T>(key, defaultValue);
}
}
}
@@ -16,7 +16,6 @@
*/
export * from './app-config.service';
export * from './debug-app-config.service';
export * from './app-config.pipe';
export * from './app-config-storage-prefix.factory';
@@ -76,20 +76,6 @@ export const clientRoles: IdentityRoleModel[] = [
export const mockJoinGroupRequest: IdentityJoinGroupRequestModel = { userId: 'mock-hser-id', groupId: 'mock-group-id', realm: 'mock-realm-name' };
export const mockGroup1 = {
id: 'mock-group-id-1',
name: 'Mock Group 1',
path: '/mock',
subGroups: []
} as IdentityGroupModel;
export const mockGroup2 = {
id: 'mock-group-id-2',
name: 'Mock Group 2',
path: '',
subGroups: []
} as IdentityGroupModel;
export const mockGroups = [
{ id: 'mock-group-id-1', name: 'Mock Group 1', path: '/mock', subGroups: [] } as IdentityGroupModel,
{ id: 'mock-group-id-2', name: 'Mock Group 2', path: '', subGroups: [] } as IdentityGroupModel
@@ -1,142 +0,0 @@
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { mockIdentityGroups, mockIdentityGroupsCount, mockIdentityRoles } from './identity-group.mock';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { IdentityGroupServiceInterface } from '../interfaces/identity-group.interface';
import {
IdentityGroupModel,
IdentityGroupQueryResponse,
IdentityGroupQueryCloudRequestModel,
IdentityGroupSearchParam,
IdentityGroupCountModel
} from '../models/identity-group.model';
import { IdentityRoleModel } from '../models/identity-role.model';
Injectable({ providedIn: 'root' });
export class IdentityGroupServiceMock implements IdentityGroupServiceInterface {
getGroups(): Observable<IdentityGroupModel[]> {
return of(mockIdentityGroups);
}
getAvailableRoles(_groupId: string): Observable<IdentityRoleModel[]> {
return of(mockIdentityRoles);
}
getAssignedRoles(_groupId: string): Observable<IdentityRoleModel[]> {
return of(mockIdentityRoles);
}
assignRoles(_groupId: string, _roles: IdentityRoleModel[]): Observable<any> {
return of();
}
removeRoles(_groupId: string, _roles: IdentityRoleModel[]): Observable<any> {
return of();
}
getEffectiveRoles(_groupId: string): Observable<IdentityRoleModel[]> {
return of(mockIdentityRoles);
}
queryGroups(_requestQuery: IdentityGroupQueryCloudRequestModel): Observable<IdentityGroupQueryResponse> {
return of();
}
getTotalGroupsCount(): Observable<IdentityGroupCountModel> {
return of(mockIdentityGroupsCount);
}
createGroup(_newGroup: IdentityGroupModel): Observable<any> {
return of();
}
updateGroup(_groupId: string, _updatedGroup: IdentityGroupModel): Observable<any> {
return of();
}
deleteGroup(_groupId: string): Observable<any> {
return of();
}
findGroupsByName(searchParams: IdentityGroupSearchParam): Observable<IdentityGroupModel[]> {
if (searchParams.name === '') {
return of([]);
}
return of(mockIdentityGroups.filter((group) => group.name.toUpperCase().includes(searchParams.name.toUpperCase())));
}
getGroupRoles(_groupId: string): Observable<IdentityRoleModel[]> {
return of(mockIdentityRoles);
}
checkGroupHasRole(groupId: string, roleNames: string[]): Observable<boolean> {
return this.getGroupRoles(groupId).pipe(
map((groupRoles) => {
let hasRole = false;
if (groupRoles?.length > 0) {
roleNames.forEach((roleName: string) => {
const role = groupRoles.find(({ name }) => roleName === name);
if (role) {
hasRole = true;
return;
}
});
}
return hasRole;
})
);
}
getClientIdByApplicationName(_applicationName: string): Observable<string> {
return of('fake-client-id');
}
getClientRoles(groupId: string, _clientId: string): Observable<IdentityRoleModel[]> {
if (['mock-group-id-1', 'mock-group-id-2'].includes(groupId)) {
return of([{ id: 'mock-role-id', name: 'MOCK-ADMIN-ROLE' }]);
}
return of([{ id: 'mock-role-id', name: 'MOCK-USER-ROLE' }]);
}
checkGroupHasClientApp(groupId: string, clientId: string): Observable<boolean> {
return this.getClientRoles(groupId, clientId).pipe(map((response) => response && response.length > 0));
}
checkGroupHasAnyClientAppRole(groupId: string, clientId: string, roleNames: string[]): Observable<boolean> {
return this.getClientRoles(groupId, clientId).pipe(
map((clientRoles: any[]) => {
let hasRole = false;
if (clientRoles.length > 0) {
roleNames.forEach((roleName) => {
const role = clientRoles.find(({ name }) => name === roleName);
if (role) {
hasRole = true;
return;
}
});
}
return hasRole;
})
);
}
}
@@ -1,133 +0,0 @@
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { mockGroups, mockIdentityGroups, roleMappingMock } from './identity-group.mock';
import { mockAssignedRoles, mockAvailableRoles, mockEffectiveRoles, mockIdentityUsers } from './identity-user.mock';
export const queryUsersMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve(mockIdentityUsers)
}
};
export const createUserMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
}
};
export const updateUserMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
}
};
export const deleteUserMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
}
};
export const getInvolvedGroupsMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve(mockGroups)
}
};
export const joinGroupMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
}
};
export const leaveGroupMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
}
};
export const getAvailableRolesMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve(mockAvailableRoles)
}
};
export const getAssignedRolesMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve(mockAssignedRoles)
}
};
export const getEffectiveRolesMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve(mockEffectiveRoles)
}
};
export const assignRolesMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
}
};
export const removeRolesMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
}
};
export const roleMappingApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve(roleMappingMock)
}
};
export const noRoleMappingApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve([])
}
};
export const groupsMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve(mockIdentityGroups)
}
};
export const createGroupMappingApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
}
};
export const updateGroupMappingApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
}
};
export const deleteGroupMappingApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
}
};
export const applicationDetailsMockApi: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve([{ id: 'mock-app-id', name: 'mock-app-name' }])
}
};
@@ -60,10 +60,9 @@ describe('OidcAuthGuard', () => {
try {
await TestBed.runInInjectionContext(() => OidcAuthGuard(route, state));
expect(routerSpy.navigateByUrl).toHaveBeenCalledWith('/', { replaceUrl: true });
} catch (error) {
} catch {
fail('Expected no error to be thrown');
}
});
it('should throw an error if loginCallback fails and logout event is emitted', async () => {
@@ -89,7 +88,7 @@ describe('OidcAuthGuard', () => {
fakeLogoutSubject.next();
await runInInjectionContext;
expect(routerSpy.navigateByUrl).toHaveBeenCalledWith('/test-route', { replaceUrl: true });
} catch (error) {
} catch {
fail('Expected no error to be thrown');
}
});
@@ -211,7 +211,7 @@ describe('RedirectAuthService', () => {
try {
await service.loginCallback();
fail('Expected to throw an error');
} catch (error) {
} catch {
expect(oauthServiceSpy.logOut).toHaveBeenCalledTimes(1);
}
});
@@ -281,7 +281,7 @@ describe('RedirectAuthService', () => {
try {
await service.loginCallback();
expect(oauthServiceSpy.logOut).not.toHaveBeenCalled();
} catch (error) {
} catch {
fail('Expected not to throw an error');
}
});
@@ -135,7 +135,7 @@ export class StorageService {
storage.setItem(key, key);
storage.removeItem(key, key);
return true;
} catch (e) {
} catch {
return false;
}
}
File diff suppressed because it is too large Load Diff
@@ -2188,37 +2188,6 @@ export const mockSectionWithFields = {
colspan: 1
};
export const mockFormWithSimpleSection = {
id: 'form-363114eb-35f6-40d0-9908-8bbbe776c3e6',
name: 'simplest section',
key: 'simplest-section-uzvc7',
description: '',
version: 0,
formDefinition: {
tabs: [],
fields: [
{
id: 'Group0wuwv7',
name: 'Group',
type: 'group',
tab: null,
params: {
hideHeader: false,
allowCollapse: false,
collapseByDefault: false
},
numberOfColumns: 1,
fields: {
1: [mockSectionWithFields]
}
}
],
outcomes: [],
metadata: {},
variables: []
}
};
export const mockSectionVisibilityForm = {
id: 'form-65e9f07c-44d9-4469-8f5d-74aba3bd7326',
name: 'section visibility',
File diff suppressed because it is too large Load Diff
@@ -488,7 +488,7 @@ export class FormFieldModel extends FormWidgetModel {
let dateValue;
try {
dateValue = DateFnsUtils.parseDate(this.value, this.dateDisplayFormat);
} catch (e) {
} catch {
dateValue = new Date('error');
}
@@ -24,11 +24,11 @@ import { FormService } from '../services/form.service';
import { ByPassFormRuleManager, FORM_RULES_MANAGER, FormRulesManager, formRulesManagerFactory } from './form-rules.model';
class CustomRuleManager extends FormRulesManager<any> {
protected getRules() {
getRules(): any {
return null;
}
protected handleRuleEvent(): void {
handleRuleEvent(): void {
return;
}
}
@@ -67,8 +67,8 @@ describe('Form Rules', () => {
it('should send the form loaded event when initialized', () => {
const rulesManager = new CustomRuleManager(formService);
const getRulesSpy = spyOn<any>(rulesManager, 'getRules').and.returnValue({});
const handleRuleEventSpy = spyOn<any>(rulesManager, 'handleRuleEvent');
const getRulesSpy = spyOn(rulesManager, 'getRules').and.returnValue({});
const handleRuleEventSpy = spyOn(rulesManager, 'handleRuleEvent');
const formModel = new FormModel({ id: 'mock' }, {}, false);
const formEvent = new FormEvent(formModel);
const event = new FormRulesEvent('formLoaded', formEvent);
@@ -82,8 +82,8 @@ describe('Form Rules', () => {
it('should not receive the form event when event has no form', () => {
const rulesManager = new CustomRuleManager(formService);
spyOn<any>(rulesManager, 'getRules').and.returnValue({});
const handleRuleEventSpy = spyOn<any>(rulesManager, 'handleRuleEvent');
spyOn(rulesManager, 'getRules').and.returnValue({});
const handleRuleEventSpy = spyOn(rulesManager, 'handleRuleEvent');
const formModel = new FormModel({ id: 'mock' }, {}, false);
const formEvent = new FormEvent(new FormModel(null));
const event = new FormRulesEvent('formLoaded', formEvent);
@@ -105,8 +105,8 @@ describe('Form Rules', () => {
beforeEach(() => {
injector = TestBed.inject(Injector);
rulesManager = formRulesManagerFactory<any>(injector);
getRulesSpy = spyOn<any>(rulesManager, 'getRules');
rulesManager = formRulesManagerFactory(injector);
getRulesSpy = spyOn(rulesManager as any, 'getRules');
});
it('factory function should return bypass service', () => {
-23
View File
@@ -15,31 +15,8 @@
* limitations under the License.
*/
import { DataColumn } from '../datatable/data/data-column.model';
import { mockPathInfos } from '../datatable/components/mocks/datatable.mock';
export const getDataColumnMock = <T = unknown>(column: Partial<DataColumn<T>> = {}): DataColumn<T> => ({
id: 'columnId',
key: 'key',
type: 'text',
format: 'format',
sortable: false,
title: 'title',
srTitle: 'srTitle',
cssClass: 'cssClass',
template: undefined,
copyContent: false,
editable: false,
focus: false,
sortingKey: 'sortingKey',
header: undefined,
draggable: false,
resizable: true,
isHidden: false,
customData: undefined,
...column
});
export const textColumnRows = [{ firstname: 'John' }, { firstname: 'Henry' }, { firstname: 'David' }, { firstname: 'Thomas' }];
export const dateColumnRows = [
@@ -19,12 +19,6 @@ import { FormModel, FormValues } from '../../form/components/widgets/core';
export const formTest = new FormModel({});
export const fakeTaskProcessVariableModels = [
{ id: 'TEST_VAR_1', type: 'string', value: 'test_value_1' },
{ id: 'TEST_VAR_2', type: 'string', value: 'test_value_2' },
{ id: 'TEST_VAR_3', type: 'string', value: 'test_value_3' }
];
export const formValues: FormValues = {
test_1: 'value_1',
test_2: 'value_2',
-4
View File
@@ -19,10 +19,6 @@ export * from './cookie.service.mock';
export * from './event.mock';
export * from './translation.service.mock';
export * from './form/form.component.mock';
export * from './form/form-definition.mock';
export * from './form/form-definition-readonly.mock';
export * from './form/form-definition-visibility.mock';
export * from './form/form.service.mock';
export * from './form/widget-visibility.service.mock';
+5 -42
View File
@@ -24,7 +24,7 @@ import { MatChipGridHarness, MatChipHarness, MatChipListboxHarness } from '@angu
import { MatButtonHarness } from '@angular/material/button/testing';
import { MatIconHarness } from '@angular/material/icon/testing';
import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
import { MatErrorHarness, MatFormFieldHarness } from '@angular/material/form-field/testing';
import { MatFormFieldHarness } from '@angular/material/form-field/testing';
import { MatInputHarness } from '@angular/material/input/testing';
import { MatAutocompleteHarness } from '@angular/material/autocomplete/testing';
import { ComponentFixture } from '@angular/core/testing';
@@ -34,7 +34,10 @@ import { MatSnackBarHarness } from '@angular/material/snack-bar/testing';
import { MatProgressBarHarness } from '@angular/material/progress-bar/testing';
export class UnitTestingUtils {
constructor(private debugElement?: DebugElement, private loader?: HarnessLoader) {
constructor(
private debugElement?: DebugElement,
private loader?: HarnessLoader
) {
this.debugElement = debugElement;
this.loader = loader;
}
@@ -75,10 +78,6 @@ export class UnitTestingUtils {
return this.debugElement.query(By.directive(directive));
}
getAllByDirective(directive: Type<any>): DebugElement[] {
return this.debugElement.queryAll(By.directive(directive));
}
/** Perform actions */
clickByCSS(selector: string): void {
@@ -243,10 +242,6 @@ export class UnitTestingUtils {
return this.loader.getHarness(MatIconHarness.with({ ancestor: selector }));
}
async getMatIconWithAncestorByCSSAndName(selector: string, name: string): Promise<MatIconHarness> {
return this.loader.getHarness(MatIconHarness.with({ ancestor: selector, name }));
}
async checkIfMatIconExistsWithAncestorByDataAutomationId(dataAutomationId: string): Promise<boolean> {
return this.loader.hasHarness(MatIconHarness.with({ ancestor: `[data-automation-id="${dataAutomationId}"]` }));
}
@@ -339,10 +334,6 @@ export class UnitTestingUtils {
return this.loader.getHarness(MatInputHarness);
}
async getMatInputByCSS(selector: string): Promise<MatInputHarness> {
return this.loader.getHarness(MatInputHarness.with({ selector }));
}
async getMatInputByDataAutomationId(dataAutomationId: string): Promise<MatInputHarness> {
return this.loader.getHarness(MatInputHarness.with({ selector: `[data-automation-id="${dataAutomationId}"]` }));
}
@@ -360,14 +351,6 @@ export class UnitTestingUtils {
return this.loader.hasHarness(MatInputHarness);
}
async checkIfMatInputExistsWithCSS(selector: string): Promise<boolean> {
return this.loader.hasHarness(MatInputHarness.with({ selector }));
}
async checkIfMatInputExistsWithDataAutomationId(dataAutomationId: string): Promise<boolean> {
return this.loader.hasHarness(MatInputHarness.with({ selector: `[data-automation-id="${dataAutomationId}"]` }));
}
async checkIfMatInputExistsWithPlaceholder(placeholder: string): Promise<boolean> {
return this.loader.hasHarness(MatInputHarness.with({ placeholder }));
}
@@ -383,11 +366,6 @@ export class UnitTestingUtils {
await input.setValue(value);
}
async fillMatInputByCSS(selector: string, value: string): Promise<void> {
const input = await this.getMatInputByCSS(selector);
await input.setValue(value);
}
async fillMatInputByDataAutomationId(dataAutomationId: string, value: string): Promise<void> {
const input = await this.getMatInputByDataAutomationId(dataAutomationId);
await input.setValue(value);
@@ -409,11 +387,6 @@ export class UnitTestingUtils {
return input.getValue();
}
async getMatInputValueByDataAutomationId(dataAutomationId: string): Promise<string> {
const input = await this.getMatInputByDataAutomationId(dataAutomationId);
return input.getValue();
}
async sendKeysToMatInput(keys: (string | TestKey)[]): Promise<void> {
const input = await this.getMatInput();
const host = await input.host();
@@ -430,16 +403,6 @@ export class UnitTestingUtils {
return autocomplete.getOptions();
}
/** MatError related methods */
async getMatErrorByCSS(selector: string): Promise<MatErrorHarness> {
return this.loader.getHarness(MatErrorHarness.with({ selector }));
}
async getMatErrorByDataAutomationId(dataAutomationId: string): Promise<MatErrorHarness> {
return this.loader.getHarness(MatErrorHarness.with({ selector: `[data-automation-id="${dataAutomationId}"]` }));
}
/** MatTabGroup related methods */
async getSelectedTabFromMatTabGroup(): Promise<MatTabHarness> {
@@ -54,7 +54,7 @@ export class TranslateLoaderService implements TranslateLoader {
}
providerRegistered(name: string): boolean {
return !!this.providers.find((x) => x.name === name);
return this.providers.some((x) => x.name === name);
}
fetchLanguageFile(lang: string, component: ComponentTranslationModel, fallbackUrl?: string): Observable<void> {
@@ -75,7 +75,7 @@ export class TranslateLoaderService implements TranslateLoader {
return this.fetchLanguageFile(lang, component, url);
}
}
return throwError(`Failed to load ${translationUrl}`);
return throwError(() => new Error(`Failed to load ${translationUrl}`));
})
);
}
@@ -85,13 +85,13 @@ export class TranslateLoaderService implements TranslateLoader {
if (!this.queue[lang]) {
this.queue[lang] = [];
}
this.providers.forEach((component) => {
for (const component of this.providers) {
if (!this.isComponentInQueue(lang, component.name)) {
this.queue[lang].push(component.name);
observableBatch.push(this.fetchLanguageFile(lang, component));
}
});
}
return observableBatch;
}
@@ -102,8 +102,8 @@ export class TranslateLoaderService implements TranslateLoader {
}
}
isComponentInQueue(lang: string, name: string) {
return !!(this.queue[lang] || []).find((x) => x === name);
isComponentInQueue(lang: string, name: string): boolean {
return (this.queue[lang] || []).some((x) => x === name);
}
getFullTranslationJSON(lang: string): any {
@@ -144,8 +144,8 @@ export class TranslateLoaderService implements TranslateLoader {
return new Observable((observer) => {
if (batch.length > 0) {
forkJoin(batch).subscribe(
() => {
forkJoin(batch).subscribe({
next: () => {
const fullTranslation = this.getFullTranslationJSON(lang);
if (fullTranslation) {
observer.next(fullTranslation);
@@ -156,10 +156,10 @@ export class TranslateLoaderService implements TranslateLoader {
observer.complete();
}
},
() => {
error: () => {
observer.error('Failed to load some resources');
}
);
});
} else {
const fullTranslation = this.getFullTranslationJSON(lang);
if (fullTranslation) {
@@ -88,31 +88,38 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy {
@HostListener('document:keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
switch (event.key) {
case 'ArrowLeft':
case 'ArrowLeft': {
event.preventDefault();
this.cropper.move(-3, 0);
break;
case 'ArrowUp':
}
case 'ArrowUp': {
event.preventDefault();
this.cropper.move(0, -3);
break;
case 'ArrowRight':
}
case 'ArrowRight': {
event.preventDefault();
this.cropper.move(3, 0);
break;
case 'ArrowDown':
}
case 'ArrowDown': {
event.preventDefault();
this.cropper.move(0, 3);
break;
case 'i':
}
case 'i': {
this.zoomIn();
break;
case 'o':
}
case 'o': {
this.zoomOut();
break;
case 'r':
}
case 'r': {
this.rotateImage();
break;
}
default:
}
}
@@ -132,7 +139,10 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy {
return Math.round(this.scale * 100) + '%';
}
constructor(private appConfigService: AppConfigService, private urlService: UrlService) {
constructor(
private readonly appConfigService: AppConfigService,
private readonly urlService: UrlService
) {
this.initializeScaling();
}
@@ -222,7 +232,7 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy {
this.cropper.clear();
this.cropper.reset();
this.cropper.setDragMode('move');
this.scale = 1.0;
this.scale = 1;
this.updateCanvasContainer();
}
@@ -27,7 +27,7 @@ import { UnitTestingUtils, provideCoreAuthTesting } from '../../../testing';
import { RenderingQueueServices } from '../../services/rendering-queue.services';
import { PdfThumbListComponent } from '../pdf-viewer-thumbnails/pdf-viewer-thumbnails.component';
import { PDFJS_MODULE, PDFJS_VIEWER_MODULE, PdfViewerComponent } from './pdf-viewer.component';
import pdfjsLibMock from '../mock/pdfjs-lib.mock';
import pdfjsLibraryMock from '../mock/pdfjs-lib.mock';
declare const pdfjsLib: any;
@@ -441,7 +441,7 @@ describe('Test PdfViewer - User interaction', () => {
},
RenderingQueueServices,
{ provide: PDFJS_VIEWER_MODULE, useValue: pdfViewerSpy },
{ provide: PDFJS_MODULE, useValue: pdfjsLibMock }
{ provide: PDFJS_MODULE, useValue: pdfjsLibraryMock }
]
});
@@ -545,9 +545,9 @@ describe('ViewerComponent', () => {
keyCode: 27
} as KeyboardEventInit);
const dialogRef = dialog.open(DummyDialogComponent);
const dialogReference = dialog.open(DummyDialogComponent);
dialogRef.afterClosed().subscribe(() => {
dialogReference.afterClosed().subscribe(() => {
EventMock.keyDown(27);
fixture.detectChanges();
expect(testingUtils.getByCSS('.adf-viewer-content')).toBeNull();
@@ -245,7 +245,7 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
@Input()
nodeId: string = null;
/** Original node mime type, should be provided when renditiona mime type is different. */
/** Original node mime type, should be provided when renditions mime type is different. */
@Input()
nodeMimeType: string = undefined;
@@ -60,7 +60,7 @@ export class ViewerExtensionDirective implements AfterContentInit {
isVisible(fileExtension: string): boolean {
let supportedExtension: string;
if (this.supportedExtensions && this.supportedExtensions instanceof Array) {
if (Array.isArray(this.supportedExtensions)) {
supportedExtension = this.supportedExtensions.find((extension) => extension.toLowerCase() === fileExtension);
}
@@ -31,16 +31,16 @@ export class RenderingQueueServices {
FINISHED: 3
};
CLEANUP_TIMEOUT: number = 30000;
CLEANUP_TIMEOUT: number = 30_000;
pdfViewer: any = null;
pdfThumbnailViewer: any = null;
onIdle: any = null;
highestPriorityPage: any = null;
highestPriorityPage: string | null = null;
idleTimeout: any = null;
printing: any = false;
isThumbnailViewEnabled: any = false;
isThumbnailViewEnabled = false;
/**
* Set the instance of the PDF Viewer
@@ -81,10 +81,8 @@ export class RenderingQueueServices {
return;
}
// No pages needed rendering so check thumbnails.
if (this.pdfThumbnailViewer && this.isThumbnailViewEnabled) {
if (this.pdfThumbnailViewer.forceRendering()) {
return;
}
if (this.pdfThumbnailViewer && this.isThumbnailViewEnabled && this.pdfThumbnailViewer.forceRendering()) {
return;
}
if (this.printing) {
@@ -106,11 +104,11 @@ export class RenderingQueueServices {
// 2 if last scrolled up page before the visible pages
const visibleViews = visible.views;
const numVisible = visibleViews.length;
if (numVisible === 0) {
const numberVisible = visibleViews.length;
if (numberVisible === 0) {
return false;
}
for (let i = 0; i < numVisible; ++i) {
for (let i = 0; i < numberVisible; ++i) {
const view = visibleViews[i].view;
if (!this.isViewFinished(view)) {
return view;
@@ -180,8 +178,9 @@ export class RenderingQueueServices {
view.draw().then(continueRendering, continueRendering);
break;
}
default:
default: {
break;
}
}
return true;
}
@@ -53,7 +53,7 @@ export class ViewUtilService {
* @returns list of extensions
*/
get externalExtensions(): string[] {
return this.viewerExtensions.map((ext) => ext.fileExtension);
return this.viewerExtensions.map((extension) => extension.fileExtension);
}
constructor(private extensionService: AppExtensionService) {}
@@ -85,7 +85,7 @@ export class ViewUtilService {
const match = fileName.match(/\.([^./?#]+)($|\?|#)/);
return match ? match[1] : null;
}
return null;
return undefined;
}
getViewerType(extension: string, mimeType: string, extensionsSupportedByTemplates?: string[]): string {
@@ -104,7 +104,7 @@ export class ViewUtilService {
const editorTypes = Object.keys(this.mimeTypes);
for (const type of editorTypes) {
if (this.mimeTypes[type].indexOf(mimeType) >= 0) {
if (this.mimeTypes[type].includes(mimeType)) {
return type;
}
}
@@ -125,19 +125,19 @@ export class ViewUtilService {
return 'custom';
}
if (this.extensions.image.indexOf(extension) >= 0) {
if (this.extensions.image.includes(extension)) {
return 'image';
}
if (this.extensions.media.indexOf(extension) >= 0) {
if (this.extensions.media.includes(extension)) {
return 'media';
}
if (this.extensions.text.indexOf(extension) >= 0) {
if (this.extensions.text.includes(extension)) {
return 'text';
}
if (this.extensions.pdf.indexOf(extension) >= 0) {
if (this.extensions.pdf.includes(extension)) {
return 'pdf';
}
@@ -145,7 +145,7 @@ export class ViewUtilService {
}
private isExternalViewer(): boolean {
return !!this.viewerExtensions.find((ext) => ext.fileExtension === '*');
return this.viewerExtensions.some((extension) => extension.fileExtension === '*');
}
isCustomViewerExtension(extension: string, extensionsSupportedByTemplates?: string[]): boolean {
@@ -156,7 +156,7 @@ export class ViewUtilService {
if (extension && extensions.length > 0) {
extension = extension.toLowerCase();
return extensions.flat().indexOf(extension) >= 0;
return extensions.flat().includes(extension);
}
return false;
+2 -2
View File
@@ -19,11 +19,11 @@ import 'zone.js';
import 'zone.js/testing';
import { TestBed } from '@angular/core/testing';
import { platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import pdfjsLibMock from './src/lib/viewer/components/mock/pdfjs-lib.mock';
import pdfjsLibraryMock from './src/lib/viewer/components/mock/pdfjs-lib.mock';
import { GlobalTestingModule } from './src/lib/testing/global-testing.module';
TestBed.initTestEnvironment(GlobalTestingModule, platformBrowserDynamicTesting(), {
teardown: { destroyAfterEach: true }
});
(window as any).pdfjsLib = pdfjsLibMock;
(window as any).pdfjsLib = pdfjsLibraryMock;
+9 -1
View File
@@ -20,7 +20,15 @@ import { provideTranslations } from '@alfresco/adf-core';
import { ANALYTICS_PROCESS_DIRECTIVES } from './analytics-process/public-api';
import { DIAGRAM_DIRECTIVES } from './diagram/public-api';
/** @deprecated This module is deprecated and will be removed in a future release. */
/**
* @deprecated This module is deprecated and will be removed in a future release.
* Example:
* ```
* providers: [
* provideTranslations('adf-insights', 'assets/adf-insights')
* ]
* ```
*/
@NgModule({
imports: [...ANALYTICS_PROCESS_DIRECTIVES, ...DIAGRAM_DIRECTIVES],
exports: [...ANALYTICS_PROCESS_DIRECTIVES, ...DIAGRAM_DIRECTIVES]
@@ -213,7 +213,7 @@ describe('AppListCloudComponent', () => {
customFixture.detectChanges();
await customFixture.whenStable();
const title: any = customFixture.nativeElement.querySelector('#custom-id');
const title = customFixture.nativeElement.querySelector('#custom-id');
expect(title.innerText).toBe('No Apps Found');
});
});
@@ -28,7 +28,10 @@ import { RequestOptions } from '@alfresco/js-api';
export class AppsProcessCloudService {
deployedApps: ApplicationInstanceModel[];
constructor(private adfHttpClient: AdfHttpClient, private appConfigService: AppConfigService) {
constructor(
private readonly adfHttpClient: AdfHttpClient,
private readonly appConfigService: AppConfigService
) {
this.loadApps();
}
@@ -48,11 +51,12 @@ export class AppsProcessCloudService {
}
loadApps() {
const apps = this.appConfigService.get<any>('alfresco-deployed-apps', []);
apps.map((app) => {
app.theme = app.theme ? app.theme : 'theme-1';
app.icon = app.icon ? app.icon : 'favorite';
});
const apps = this.appConfigService.get<{ theme: string; icon: string }[]>('alfresco-deployed-apps', []);
for (const app of apps) {
app.theme = app.theme ?? 'theme-1';
app.icon = app.icon ?? 'favorite';
}
this.deployedApps = apps;
}
@@ -363,8 +363,8 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
}),
takeUntilDestroyed(this.destroyRef)
)
.subscribe(
(form) => {
.subscribe({
next: (form) => {
this.formCloudRepresentationJSON = form;
this.formCloudRepresentationJSON.processVariables = this.data || [];
const parsedForm = this.parseForm(form);
@@ -374,10 +374,10 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
this.form.nodeId = '-my-';
this.onFormLoaded(this.form);
},
(error) => {
error: (error) => {
this.handleError(error);
}
);
});
}
saveTaskForm() {
@@ -385,12 +385,12 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
this.formCloudService
.saveTaskForm(this.appName, this.taskId, this.processInstanceId, `${this.form.id}`, this.form.values)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(
() => {
.subscribe({
next: () => {
this.onTaskSaved(this.form);
},
(error) => this.onTaskSavedError(error)
);
error: (error) => this.onTaskSavedError(error)
});
this.displayModeService.onSaveTask(this.id, this.displayMode, this.displayModeConfigurations);
}
}
@@ -420,12 +420,12 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
this.formCloudService
.completeTaskForm(this.appName, this.taskId, this.processInstanceId, `${this.form.id}`, this.form.values, outcome, this.appVersion)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(
() => {
.subscribe({
next: () => {
this.onTaskCompleted(this.form);
},
(error) => this.onTaskCompletedError(error)
);
error: (error) => this.onTaskCompletedError(error)
});
}
}
@@ -531,7 +531,7 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
}
loadInjectedFieldValidators(injectedFieldValidators: FormFieldValidator[]): void {
if (injectedFieldValidators && injectedFieldValidators?.length) {
if (Array.isArray(injectedFieldValidators) && injectedFieldValidators.length) {
this.fieldValidators = [...this.fieldValidators, ...injectedFieldValidators];
}
}
@@ -268,7 +268,7 @@ export class GroupCloudComponent implements OnInit, OnChanges {
if (this.isPreselectedGroupInvalid(group, validationResult)) {
this.invalidGroups.push(group);
}
} catch (error) {
} catch {
this.invalidGroups.push(group);
}
}
@@ -376,7 +376,7 @@ export class PeopleCloudComponent implements OnInit, OnChanges, AfterViewInit {
if (!this.equalsUsers(user, validationResult)) {
this.invalidUsers.push(user);
}
} catch (error) {
} catch {
this.invalidUsers.push(user);
}
}
@@ -39,13 +39,14 @@ export const PROCESS_SERVICES_CLOUD_DIRECTIVES = [
* @deprecated this module is deprecated and will be removed in the future versions
*
* Instead, import the standalone components directly, or use the following provider API to replicate the behaviour:
*
* ```
* providers: [
* provideTranslations('adf-process-services-cloud', 'assets/adf-process-services-cloud')
* provideCloudPreferences()
* provideCloudFormRenderer(),
* { provide: TASK_LIST_CLOUD_TOKEN, useClass: TaskListCloudService }
* ]
* ```
*/
@NgModule({
imports: [ProcessCloudModule, TaskCloudModule, GroupCloudComponent, ...PROCESS_SERVICES_CLOUD_DIRECTIVES],
@@ -26,7 +26,6 @@ import {
DataColumnComponent,
DataColumnListComponent,
DataRowEvent,
getDataColumnMock,
ObjectDataColumn,
ObjectDataRow,
User,
@@ -46,6 +45,7 @@ import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
import { provideCloudPreferences } from '../../../providers';
import { getDataColumnMock } from '../../../testing/data-column.mock';
const fakeCustomSchema = [
new ObjectDataColumn<ProcessListDataColumnCustomData>({
@@ -15,11 +15,12 @@
* limitations under the License.
*/
import { DataColumn, DataRow, getDataColumnMock } from '@alfresco/adf-core';
import { DataColumn, DataRow } from '@alfresco/adf-core';
import { getProcessInstanceVariableMock } from '../../../mock/process-instance-variable.mock';
import { ProcessListDataColumnCustomData, PROCESS_LIST_CUSTOM_VARIABLE_COLUMN } from '../../../models/data-column-custom-data';
import { ProcessInstanceCloudListViewModel } from '../models/perocess-instance-cloud-view.model';
import { ProcessListDatatableAdapter } from './process-list-datatable-adapter';
import { getDataColumnMock } from '../../../testing/data-column.mock';
describe('ProcessListDatatableAdapter', () => {
it('should get proepr type for column', () => {
@@ -15,21 +15,10 @@
* limitations under the License.
*/
import { FormFieldModel, FormFieldValidator } from '@alfresco/adf-core';
import { ProcessDefinitionCloud } from '../../../models/process-definition-cloud.model';
import { ProcessInstanceCloud } from '../models/process-instance-cloud.model';
import { ProcessPayloadCloud } from '../models/process-payload-cloud.model';
export class MockFormFieldValidator implements FormFieldValidator {
isSupported(_field: FormFieldModel): boolean {
return true;
}
validate(_field: FormFieldModel): boolean {
return true;
}
}
export const fakeProcessInstance: ProcessInstanceCloud = {
appName: 'simple-app',
appVersion: '1',
@@ -16,11 +16,11 @@
*/
import { getProcessInstanceVariableMock } from '../mock/process-instance-variable.mock';
import { ProcessListDataColumnCustomData } from '../models/data-column-custom-data';
import { ProcessInstanceVariable } from '../models/process-instance-variable.model';
import { VariableMapperService } from './variable-mapper.sevice';
import { DataColumn, getDataColumnMock } from '@alfresco/adf-core';
import { DataColumn } from '@alfresco/adf-core';
import { getDataColumnMock } from '../testing/data-column.mock';
describe('VariableMapperService', () => {
let service: VariableMapperService;
@@ -15,7 +15,8 @@
* limitations under the License.
*/
import { DataColumn, DataRow, getDataColumnMock } from '@alfresco/adf-core';
import { DataColumn, DataRow } from '@alfresco/adf-core';
import { getDataColumnMock } from '../../../../../testing/data-column.mock';
import { ProcessListDataColumnCustomData, PROCESS_LIST_CUSTOM_VARIABLE_COLUMN } from '../../../../../models/data-column-custom-data';
import { TasksListDatatableAdapter } from './task-list-datatable-adapter';
import { TaskInstanceCloudListViewModel } from '../../../models/task-cloud-view.model';
@@ -15,8 +15,26 @@
* limitations under the License.
*/
import { MatIconRegistry } from '@angular/material/icon';
import { DataColumn } from '@alfresco/adf-core';
export const matIconRegistryMock = {
addSvgIconInNamespace: () => {}
} as any as MatIconRegistry;
export const getDataColumnMock = <T = unknown>(column: Partial<DataColumn<T>> = {}): DataColumn<T> => ({
id: 'columnId',
key: 'key',
type: 'text',
format: 'format',
sortable: false,
title: 'title',
srTitle: 'srTitle',
cssClass: 'cssClass',
template: undefined,
copyContent: false,
editable: false,
focus: false,
sortingKey: 'sortingKey',
header: undefined,
draggable: false,
resizable: true,
isHidden: false,
customData: undefined,
...column
});
@@ -269,7 +269,7 @@ describe('AppsListComponent', () => {
customFixture.detectChanges();
await customFixture.whenStable();
const title: any = customFixture.debugElement.queryAll(By.css('#custom-id'));
const title = customFixture.debugElement.queryAll(By.css('#custom-id'));
expect(title.length).toBe(1);
expect(title[0].nativeElement.innerText).toBe('No Apps');
});
@@ -29,9 +29,9 @@ import {
FormService,
WidgetVisibilityService,
ContainerModel,
fakeForm,
NoopAuthModule
} from '@alfresco/adf-core';
import { fakeForm } from './form.component.mock';
import { NodeMetadata, NodesApiService } from '@alfresco/adf-content-services';
import { FormComponent } from './form.component';
import { ProcessFormRenderingService } from './process-form-rendering.service';
@@ -19,15 +19,10 @@ import { SimpleChange } from '@angular/core';
import { of } from 'rxjs';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import {
formDefinitionDropdownField,
formDefinitionTwoTextFields,
formDefinitionRequiredField,
formDefVisibilityFieldDependsOnNextOne,
formDefVisibilitiFieldDependsOnPreviousOne,
formReadonlyTwoTextFields,
FormRenderingService
} from '@alfresco/adf-core';
import { formDefinitionDropdownField, formDefinitionTwoTextFields, formDefinitionRequiredField } from './form-definition.mock';
import { formDefVisibilityFieldDependsOnNextOne, formDefVisibilitiFieldDependsOnPreviousOne } from './form-definition-visibility.mock';
import { formReadonlyTwoTextFields } from './form-definition-readonly.mock';
import { FormRenderingService } from '@alfresco/adf-core';
import { FormComponent } from './form.component';
import { TaskService } from './services/task.service';
import { TaskFormService } from './services/task-form.service';
@@ -32,6 +32,12 @@ import { TextEditorComponent } from '../text/text.editor';
import { ErrorWidgetComponent } from '@alfresco/adf-core';
import { MatButtonModule } from '@angular/material/button';
export interface RowEditorReturnType {
table: DynamicTableModel;
row: DynamicTableRow;
column: DynamicTableColumn;
}
@Component({
selector: 'row-editor',
imports: [
@@ -59,10 +65,10 @@ export class RowEditorComponent {
column: DynamicTableColumn;
@Output()
save: EventEmitter<any> = new EventEmitter<any>();
save = new EventEmitter<RowEditorReturnType>();
@Output()
cancel: EventEmitter<any> = new EventEmitter<any>();
cancel = new EventEmitter<RowEditorReturnType>();
validationSummary: DynamicRowValidationSummary;
@@ -74,7 +74,7 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
groupId: number;
searchTerm = new UntypedFormControl();
searchTerms$: Observable<any> = this.searchTerm.valueChanges;
searchTerms$ = this.searchTerm.valueChanges;
users$: Observable<LightUserRepresentation[]> = this.searchTerms$.pipe(
distinctUntilChanged(),
@@ -92,7 +92,10 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
})
);
constructor(public formService: FormService, public peopleProcessService: PeopleProcessService) {
constructor(
public formService: FormService,
public peopleProcessService: PeopleProcessService
) {
super(formService);
}
@@ -307,7 +307,7 @@ export class ProcessService {
try {
return datePipe.transform(value, dateFormat);
} catch (err) {
} catch {
return '';
}
}
@@ -28,6 +28,17 @@ import { FORM_DIRECTIVES } from './form';
import { TASK_COMMENTS_DIRECTIVES } from './task-comments';
import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
/**
* @deprecated use provider api instead, for example:
* ```
* providers: [
* provideTranslations('adf-process-services', 'assets/adf-process-services'),
* { provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: { floatLabel: 'never' } }
* FormRenderingService,
* { provide: FormRenderingService, useClass: ProcessFormRenderingService }
* ]
* ```
*/
@NgModule({
imports: [
...PROCESS_COMMENTS_DIRECTIVES,
@@ -759,7 +759,7 @@ describe('TaskFormComponent', () => {
component.taskId = 'mock-task-id';
component.error.subscribe((error: any) => {
component.error.subscribe((error) => {
expect(error).toEqual(mockError);
done();
});
@@ -184,7 +184,7 @@ describe('TaskHeaderComponent', () => {
await fixture.whenStable();
const datePicker = fixture.debugElement.query(By.css(`[data-automation-id="datepicker-dueDate"]`));
expect(datePicker).toBeNull('Datepicker should NOT be in DOM');
expect(datePicker).toBeNull();
});
it('should set editable to true if the task has not completed yet', async () => {