mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-24 17:31:52 +00:00
Sonarcloud issues fixes (#3499)
* Sonarcloud issues fixes * Code smell fixes * Refactoring to remove new code duplications * Sonarcloud code smell fixes part I * Sonarcloud code smell fixes part II * Missing code smell fix * Add new ESLint rules to cover fixed SonarCloud issues * Add missing command * Add missing is existing check
This commit is contained in:
@@ -83,10 +83,10 @@ export class LocationLinkComponent implements OnInit {
|
||||
ngOnInit() {
|
||||
if (this.context) {
|
||||
const node: NodeEntry = this.context.row.node;
|
||||
if (node && node.entry && node.entry.path) {
|
||||
if (node?.entry && node?.entry?.path) {
|
||||
const path = node.entry.path;
|
||||
|
||||
if (path && path.name && path.elements) {
|
||||
if (path?.name && path?.elements) {
|
||||
if (this.showLocation) {
|
||||
this.displayText = of(path.name.substring(1).replace(/\//g, ' › '));
|
||||
} else {
|
||||
@@ -144,7 +144,9 @@ export class LocationLinkComponent implements OnInit {
|
||||
|
||||
let result: string = null;
|
||||
|
||||
const elements = path.elements.map((e) => Object.assign({}, e));
|
||||
const elements = path.elements.map((e) => {
|
||||
return { ...e };
|
||||
});
|
||||
const personalFiles = this.translationService.instant('APP.BROWSE.PERSONAL.TITLE');
|
||||
const fileLibraries = this.translationService.instant('APP.BROWSE.LIBRARIES.TITLE');
|
||||
|
||||
|
@@ -62,7 +62,7 @@ export class ToggleSharedComponent implements OnInit, OnDestroy {
|
||||
this.selectionState = selectionState;
|
||||
|
||||
this.isShared =
|
||||
(this.selectionState.first && this.selectionState.first.entry && (this.selectionState.first.entry as any).sharedByUser) ||
|
||||
(this.selectionState?.first?.entry && (this.selectionState.first.entry as any).sharedByUser) ||
|
||||
!!this.selectionState?.first?.entry?.properties?.['qshare:sharedId'];
|
||||
|
||||
this.selectionLabel = this.isShared ? 'APP.ACTIONS.SHARE_EDIT' : 'APP.ACTIONS.SHARE';
|
||||
|
@@ -52,7 +52,7 @@ export class ContextMenuItemComponent {
|
||||
}
|
||||
|
||||
private hasClickAction(actionRef: ContentActionRef): boolean {
|
||||
return !!(actionRef && actionRef.actions && actionRef.actions.click);
|
||||
return !!actionRef?.actions?.click;
|
||||
}
|
||||
|
||||
trackByActionId(_: number, obj: ContentActionRef): string {
|
||||
|
@@ -36,8 +36,6 @@ export class OutsideEventDirective implements OnInit, OnDestroy {
|
||||
@Output()
|
||||
clickOutside: EventEmitter<null> = new EventEmitter();
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {
|
||||
this.subscriptions = this.subscriptions.concat([
|
||||
fromEvent(document.body, 'click')
|
||||
@@ -54,11 +52,9 @@ export class OutsideEventDirective implements OnInit, OnDestroy {
|
||||
private findAncestor(el: Element): boolean {
|
||||
const className = 'aca-context-menu';
|
||||
|
||||
if (el.classList.contains(className)) {
|
||||
return true;
|
||||
while (el && !el.classList.contains(className)) {
|
||||
el = el.parentElement;
|
||||
}
|
||||
// eslint-disable-next-line curly
|
||||
while ((el = el.parentElement) && !el.classList.contains(className));
|
||||
return !!el;
|
||||
}
|
||||
}
|
||||
|
@@ -68,11 +68,6 @@ export class ContextMenuService {
|
||||
}
|
||||
|
||||
private createInjector(contextmenuOverlayRef: ContextMenuOverlayRef): Injector {
|
||||
const injectionTokens = new WeakMap();
|
||||
|
||||
injectionTokens.set(ContextMenuOverlayRef, contextmenuOverlayRef);
|
||||
injectionTokens.set(CONTEXT_MENU_DIRECTION, this.direction);
|
||||
|
||||
return Injector.create({
|
||||
parent: this.injector,
|
||||
providers: [
|
||||
|
@@ -95,7 +95,7 @@ export class FavoriteLibrariesComponent extends PageComponent implements OnInit
|
||||
}
|
||||
|
||||
navigateTo(node: SiteEntry) {
|
||||
if (node && node.entry && node.entry.guid) {
|
||||
if (node?.entry?.guid) {
|
||||
this.store.dispatch(new NavigateLibraryAction(node.entry.guid, 'favorite/libraries'));
|
||||
}
|
||||
}
|
||||
|
@@ -83,7 +83,7 @@ export class FavoritesComponent extends PageComponent implements OnInit {
|
||||
const { isFolder, id } = favorite;
|
||||
|
||||
// TODO: rework as it will fail on non-English setups
|
||||
const isSitePath = (path: PathInfo): boolean => path && path.elements && path.elements.some(({ name }: PathElement) => name === 'Sites');
|
||||
const isSitePath = (path: PathInfo): boolean => path?.elements?.some(({ name }: PathElement) => name === 'Sites');
|
||||
|
||||
if (isFolder) {
|
||||
this.contentApi
|
||||
@@ -97,7 +97,7 @@ export class FavoritesComponent extends PageComponent implements OnInit {
|
||||
}
|
||||
|
||||
onNodeDoubleClick(node: NodeEntry) {
|
||||
if (node && node.entry) {
|
||||
if (node?.entry) {
|
||||
if (node.entry.isFolder) {
|
||||
this.navigate(node.entry);
|
||||
}
|
||||
|
@@ -102,7 +102,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
(node) => {
|
||||
this.isValidPath = true;
|
||||
|
||||
if (node.entry && node.entry.isFolder) {
|
||||
if (node?.entry?.isFolder) {
|
||||
this.updateCurrentNode(node.entry);
|
||||
} else {
|
||||
this.router.navigate(['/personal-files', node.entry.parentId], {
|
||||
@@ -190,7 +190,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
navigateTo(node: NodeEntry) {
|
||||
if (node && node.entry) {
|
||||
if (node?.entry) {
|
||||
this.selectedNode = node;
|
||||
const { isFolder } = node.entry;
|
||||
|
||||
@@ -220,7 +220,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
this.documentList.resetNewFolderPagination();
|
||||
|
||||
// todo: review this approach once 5.2.3 is out
|
||||
if (this.nodePath && this.nodePath.length > 2) {
|
||||
if (this.nodePath && this.nodePath?.length > 2) {
|
||||
if (this.nodePath[1].name === 'Sites' && this.nodePath[2].id === route.id) {
|
||||
return this.navigate(this.nodePath[3].id);
|
||||
}
|
||||
@@ -232,31 +232,31 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
const node: NodeEntry = event.file.data;
|
||||
|
||||
// check root and child nodes
|
||||
if (node && node.entry && node.entry.parentId === this.getParentNodeId()) {
|
||||
if (node?.entry?.parentId === this.getParentNodeId()) {
|
||||
this.reload(this.selectedNode);
|
||||
return;
|
||||
}
|
||||
|
||||
// check the child nodes to show dropped folder
|
||||
if (event && event.file.options.parentId === this.getParentNodeId()) {
|
||||
this.displayFolderParent(event.file.options.path, 0);
|
||||
this.displayFolderParent(0, event.file.options.path);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event && event.file.options.parentId) {
|
||||
if (event?.file.options.parentId) {
|
||||
if (this.nodePath) {
|
||||
const correspondingNodePath = this.nodePath.find((pathItem) => pathItem.id === event.file.options.parentId);
|
||||
|
||||
// check if the current folder has the 'trigger-upload-folder' as one of its parents
|
||||
if (correspondingNodePath) {
|
||||
const correspondingIndex = this.nodePath.length - this.nodePath.indexOf(correspondingNodePath);
|
||||
this.displayFolderParent(event.file.options.path, correspondingIndex);
|
||||
this.displayFolderParent(correspondingIndex, event.file.options.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
displayFolderParent(filePath = '', index: number) {
|
||||
displayFolderParent(index: number, filePath = '') {
|
||||
const parentName = filePath.split('/')[index];
|
||||
const currentFoldersDisplayed = (this.documentList.data.getRows() as ShareDataRow[]) || [];
|
||||
|
||||
@@ -269,7 +269,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
onContentCopied(nodes: NodeEntry[]) {
|
||||
const newNode = nodes.find((node) => node && node.entry && node.entry.parentId === this.getParentNodeId());
|
||||
const newNode = nodes.find((node) => node?.entry?.parentId === this.getParentNodeId());
|
||||
if (newNode) {
|
||||
this.reload(this.selectedNode);
|
||||
}
|
||||
@@ -279,10 +279,12 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
private async updateCurrentNode(node: Node) {
|
||||
this.nodePath = null;
|
||||
|
||||
if (node && node.path && node.path.elements) {
|
||||
if (node?.path?.elements) {
|
||||
const elements = node.path.elements;
|
||||
|
||||
this.nodePath = elements.map((pathElement) => Object.assign({}, pathElement));
|
||||
this.nodePath = elements.map((pathElement) => {
|
||||
return { ...pathElement };
|
||||
});
|
||||
|
||||
if (elements.length > 1) {
|
||||
if (elements[1].name === 'User Homes') {
|
||||
@@ -329,14 +331,14 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
isSiteContainer(node: Node): boolean {
|
||||
if (node && node.aspectNames && node.aspectNames.length > 0) {
|
||||
if (node?.aspectNames?.length > 0) {
|
||||
return node.aspectNames.indexOf('st:siteContainer') >= 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
isRootNode(nodeId: string): boolean {
|
||||
if (this.node && this.node.path && this.node.path.elements && this.node.path.elements.length > 0) {
|
||||
if (this.node?.path?.elements?.length > 0) {
|
||||
return this.node.path.elements[0].id === nodeId;
|
||||
}
|
||||
return false;
|
||||
@@ -359,7 +361,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
const objectFromMap = {};
|
||||
activeFilters.forEach((filter: FilterSearch) => {
|
||||
let paramValue;
|
||||
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;
|
||||
|
@@ -60,8 +60,8 @@ import { Actions, ofType } from '@ngrx/effects';
|
||||
|
||||
export class InstantErrorStateMatcher implements ErrorStateMatcher {
|
||||
isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean {
|
||||
const isSubmitted = form && form.submitted;
|
||||
return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
|
||||
const isSubmitted = form?.submitted;
|
||||
return !!(control?.invalid && (control?.dirty || control?.touched || isSubmitted));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -81,7 +81,7 @@ export class LibrariesComponent extends PageComponent implements OnInit {
|
||||
}
|
||||
|
||||
navigateTo(node: SiteEntry) {
|
||||
if (node && node.entry && node.entry.guid) {
|
||||
if (node?.entry?.guid) {
|
||||
this.store.dispatch(new NavigateLibraryAction(node.entry.guid));
|
||||
}
|
||||
}
|
||||
|
@@ -63,10 +63,6 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
export class RecentFilesComponent extends PageComponent implements OnInit {
|
||||
columns: DocumentListPresetRef[] = [];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
|
||||
@@ -79,7 +75,7 @@ export class RecentFilesComponent extends PageComponent implements OnInit {
|
||||
}
|
||||
|
||||
onNodeDoubleClick(node: NodeEntry) {
|
||||
if (node && node.entry) {
|
||||
if (node?.entry) {
|
||||
this.showPreview(node, { location: this.router.url });
|
||||
}
|
||||
}
|
||||
|
@@ -42,39 +42,39 @@ describe('SearchInputControlComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should emit submit event on searchSubmit', async () => {
|
||||
it('should emit submit event on searchSubmit', () => {
|
||||
const keyboardEvent = { target: { value: 'a' } };
|
||||
|
||||
let eventArgs = null;
|
||||
component.submit.subscribe((args) => (eventArgs = args));
|
||||
|
||||
await component.searchSubmit(keyboardEvent);
|
||||
component.searchSubmit(keyboardEvent);
|
||||
expect(eventArgs).toBe(keyboardEvent);
|
||||
});
|
||||
|
||||
it('should emit searchChange event on inputChange', async () => {
|
||||
it('should emit searchChange event on inputChange', () => {
|
||||
const searchTerm = 'b';
|
||||
|
||||
let eventArgs = null;
|
||||
component.searchChange.subscribe((args) => (eventArgs = args));
|
||||
|
||||
await component.inputChange(searchTerm);
|
||||
component.inputChange(searchTerm);
|
||||
expect(eventArgs).toBe(searchTerm);
|
||||
});
|
||||
|
||||
it('should emit searchChange event on clear', async () => {
|
||||
it('should emit searchChange event on clear', () => {
|
||||
let eventArgs = null;
|
||||
component.searchChange.subscribe((args) => (eventArgs = args));
|
||||
|
||||
await component.clear();
|
||||
component.clear();
|
||||
expect(eventArgs).toBe('');
|
||||
});
|
||||
|
||||
it('should clear searchTerm', async () => {
|
||||
it('should clear searchTerm', () => {
|
||||
component.searchTerm = 'c';
|
||||
fixture.detectChanges();
|
||||
|
||||
await component.clear();
|
||||
component.clear();
|
||||
expect(component.searchTerm).toBe('');
|
||||
});
|
||||
|
||||
|
@@ -53,13 +53,13 @@ describe('SearchLibrariesQueryBuilderService', () => {
|
||||
expect(builder.userQuery).toEqual('something');
|
||||
});
|
||||
|
||||
it('should build query and raise an event on update', async () => {
|
||||
it('should build query and raise an event on update', () => {
|
||||
spyOn(builder, 'buildQuery').and.returnValue(query);
|
||||
|
||||
let eventArgs = null;
|
||||
builder.updated.subscribe((args) => (eventArgs = args));
|
||||
|
||||
await builder.update();
|
||||
builder.update();
|
||||
expect(eventArgs).toBe(query);
|
||||
});
|
||||
|
||||
|
@@ -80,12 +80,12 @@ export class SearchLibrariesQueryBuilderService {
|
||||
|
||||
buildQuery(): LibrarySearchQuery {
|
||||
const query = this.userQuery;
|
||||
if (query && query.length > 1) {
|
||||
if (query?.length > 1) {
|
||||
return {
|
||||
term: query,
|
||||
opts: {
|
||||
skipCount: this.paging && this.paging.skipCount,
|
||||
maxItems: this.paging && this.paging.maxItems
|
||||
skipCount: this.paging?.skipCount,
|
||||
maxItems: this.paging?.maxItems
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -158,7 +158,7 @@ export class SearchLibrariesResultsComponent extends PageComponent implements On
|
||||
}
|
||||
|
||||
getNumberOfResults() {
|
||||
if (this.data && this.data.list && this.data.list.pagination) {
|
||||
if (this.data?.list?.pagination) {
|
||||
return this.data.list.pagination.totalItems;
|
||||
}
|
||||
return 0;
|
||||
@@ -173,7 +173,7 @@ export class SearchLibrariesResultsComponent extends PageComponent implements On
|
||||
}
|
||||
|
||||
navigateTo(node: SiteEntry) {
|
||||
if (node && node.entry && node.entry.guid) {
|
||||
if (node?.entry?.guid) {
|
||||
this.store.dispatch(new NavigateLibraryAction(node.entry.guid));
|
||||
}
|
||||
}
|
||||
|
@@ -74,7 +74,7 @@ export class SearchResultsRowComponent implements OnInit, OnDestroy {
|
||||
|
||||
if (entry.id === node.id) {
|
||||
entry.name = node.name;
|
||||
entry.properties = Object.assign({}, node.properties);
|
||||
entry.properties = { ...node.properties };
|
||||
|
||||
this.updateValues();
|
||||
}
|
||||
|
@@ -95,11 +95,7 @@ describe('SearchComponent', () => {
|
||||
});
|
||||
|
||||
it('should raise an error if search fails', fakeAsync(() => {
|
||||
spyOn(queryBuilder['searchApi'], 'search').and.returnValue(
|
||||
Promise.reject({
|
||||
message: `{ "error": { "statusCode": 500 } } `
|
||||
})
|
||||
);
|
||||
spyOn(queryBuilder['searchApi'], 'search').and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 500 } }')));
|
||||
|
||||
spyOn(queryBuilder, 'buildQuery').and.returnValue(searchRequest);
|
||||
spyOn(store, 'dispatch').and.stub();
|
||||
@@ -118,11 +114,7 @@ describe('SearchComponent', () => {
|
||||
return key;
|
||||
});
|
||||
|
||||
spyOn(queryBuilder['searchApi'], 'search').and.returnValue(
|
||||
Promise.reject({
|
||||
message: `{ "error": { "statusCode": 401 } } `
|
||||
})
|
||||
);
|
||||
spyOn(queryBuilder['searchApi'], 'search').and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 401 } }')));
|
||||
|
||||
spyOn(queryBuilder, 'buildQuery').and.returnValue(searchRequest);
|
||||
spyOn(store, 'dispatch').and.stub();
|
||||
@@ -141,11 +133,7 @@ describe('SearchComponent', () => {
|
||||
return key;
|
||||
});
|
||||
|
||||
spyOn(queryBuilder['searchApi'], 'search').and.returnValue(
|
||||
Promise.reject({
|
||||
message: `{ "error": { "statusCode": 401 } } `
|
||||
})
|
||||
);
|
||||
spyOn(queryBuilder['searchApi'], 'search').and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 401 } }')));
|
||||
|
||||
spyOn(queryBuilder, 'buildQuery').and.returnValue(searchRequest);
|
||||
spyOn(store, 'dispatch').and.stub();
|
||||
@@ -191,7 +179,7 @@ describe('SearchComponent', () => {
|
||||
});
|
||||
|
||||
it('should format user input as cm:name if configuration not provided', () => {
|
||||
const query = component.formatSearchQuery('hello', undefined);
|
||||
const query = component.formatSearchQuery('hello');
|
||||
expect(query).toBe(`(cm:name:"hello*")`);
|
||||
});
|
||||
|
||||
|
@@ -266,7 +266,7 @@ export class SearchResultsComponent extends PageComponent implements OnInit {
|
||||
}
|
||||
|
||||
onNodeDoubleClick(node: NodeEntry) {
|
||||
if (node && node.entry) {
|
||||
if (node?.entry) {
|
||||
if (node.entry.isFolder) {
|
||||
this.store.dispatch(new NavigateToFolder(node));
|
||||
return;
|
||||
|
@@ -95,7 +95,7 @@ describe('SharedLinkViewComponent', () => {
|
||||
}));
|
||||
|
||||
it('should not update store on error', fakeAsync(() => {
|
||||
spyGetSharedLink.and.returnValue(Promise.reject('error'));
|
||||
spyGetSharedLink.and.returnValue(Promise.reject(new Error('error')));
|
||||
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
@@ -75,7 +75,6 @@ describe('ActionDirective', () => {
|
||||
it('should add active route class name', () => {
|
||||
fixture.detectChanges();
|
||||
router.navigateByUrl('/dummy');
|
||||
// fixture.detectChanges();
|
||||
expect(document.body.querySelector('#test-element').className.includes('active-link-class')).toBe(true);
|
||||
});
|
||||
|
||||
|
@@ -67,7 +67,7 @@ export class ActiveLinkDirective implements OnInit, AfterContentInit {
|
||||
}
|
||||
|
||||
private render(routerUrl: string, actionUrl: string) {
|
||||
if (routerUrl && routerUrl.substring(1).startsWith(actionUrl)) {
|
||||
if (routerUrl?.substring(1).startsWith(actionUrl)) {
|
||||
this.isLinkActive = true;
|
||||
this.renderer.addClass(this.element.nativeElement, this.acaActiveLink);
|
||||
} else {
|
||||
@@ -82,6 +82,6 @@ export class ActiveLinkDirective implements OnInit, AfterContentInit {
|
||||
}
|
||||
|
||||
private resolveUrl(item): string {
|
||||
return (item.action && item.action.click && item.action.click.payload) || item.action.route;
|
||||
return item.action?.click?.payload || item.action?.route;
|
||||
}
|
||||
}
|
||||
|
@@ -58,7 +58,7 @@ export class ExpansionPanelDirective implements OnInit, OnDestroy {
|
||||
constructor(private store: Store<any>, private router: Router, private expansionPanel: MatExpansionPanel) {}
|
||||
|
||||
hasActiveLinks() {
|
||||
if (this.acaExpansionPanel && this.acaExpansionPanel.children) {
|
||||
if (this.acaExpansionPanel?.children) {
|
||||
return this.acaExpansionPanel.children.some((child) => this.router.url.startsWith(child.url || child.action.payload));
|
||||
}
|
||||
return false;
|
||||
|
@@ -57,7 +57,7 @@ export class MenuPanelDirective implements OnInit, OnDestroy {
|
||||
constructor(private store: Store<any>, private router: Router) {}
|
||||
|
||||
hasActiveLinks() {
|
||||
if (this.acaMenuPanel && this.acaMenuPanel.children) {
|
||||
if (this.acaMenuPanel?.children) {
|
||||
return this.acaMenuPanel.children.some((child) => this.router.url.startsWith(child.url || child.action.payload));
|
||||
}
|
||||
return false;
|
||||
|
@@ -57,7 +57,7 @@ export class UserMenuComponent implements OnInit {
|
||||
|
||||
ngOnInit() {
|
||||
this.getUserInfo();
|
||||
if (this.data && this.data.items) {
|
||||
if (this.data?.items) {
|
||||
this.data.items.sort((a, b) => a.order - b.order);
|
||||
}
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@ describe('ToggleEditOfflineComponent', () => {
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.selection).toEqual(selection.file as any);
|
||||
expect(component.selection).toEqual(selection.file);
|
||||
});
|
||||
|
||||
it('should download content when node is locked', async () => {
|
||||
|
@@ -1503,7 +1503,7 @@ describe('ContentManagementService', () => {
|
||||
}));
|
||||
|
||||
it('should raise error when unlock node fails', fakeAsync(() => {
|
||||
spyOn(contentApi, 'unlockNode').and.callFake(() => new Promise((_resolve, reject) => reject('error')));
|
||||
spyOn(contentApi, 'unlockNode').and.callFake(() => new Promise((_resolve, reject) => reject(new Error('error'))));
|
||||
spyOn(store, 'dispatch').and.callThrough();
|
||||
store.dispatch(new UnlockWriteAction({ entry: { id: 'node-id', name: 'some-file' } }));
|
||||
tick();
|
||||
|
@@ -122,7 +122,7 @@ export class ContentManagementService {
|
||||
}
|
||||
|
||||
manageVersions(node: any, focusedElementOnCloseSelector?: string) {
|
||||
if (node && node.entry) {
|
||||
if (node?.entry) {
|
||||
// shared and favorite
|
||||
const id = node.entry.nodeId || (node as any).entry.guid;
|
||||
|
||||
@@ -137,7 +137,7 @@ export class ContentManagementService {
|
||||
}
|
||||
|
||||
manageAspects(node: any, focusedElementOnCloseSelector?: string) {
|
||||
if (node && node.entry) {
|
||||
if (node?.entry) {
|
||||
// shared and favorite
|
||||
const id = node.entry.nodeId || (node as any).entry.guid;
|
||||
|
||||
@@ -174,7 +174,7 @@ export class ContentManagementService {
|
||||
}
|
||||
|
||||
shareNode(node: any, focusedElementOnCloseSelector?: string): void {
|
||||
if (node && node.entry) {
|
||||
if (node?.entry) {
|
||||
// shared and favorite
|
||||
const id = node.entry.nodeId || (node as any).entry.guid;
|
||||
|
||||
@@ -276,7 +276,7 @@ export class ContentManagementService {
|
||||
this.focusAfterClose(this.createMenuButtonSelector);
|
||||
}),
|
||||
map((node: SiteEntry) => {
|
||||
if (node && node.entry && node.entry.guid) {
|
||||
if (node?.entry?.guid) {
|
||||
return node.entry.guid;
|
||||
}
|
||||
return null;
|
||||
@@ -557,7 +557,7 @@ export class ContentManagementService {
|
||||
errorJson = JSON.parse(error.message);
|
||||
} catch {}
|
||||
|
||||
if (errorJson && errorJson.error && errorJson.error.statusCode === 403) {
|
||||
if (errorJson?.error?.statusCode === 403) {
|
||||
i18nMessageString = 'APP.MESSAGES.ERRORS.PERMISSION';
|
||||
}
|
||||
|
||||
@@ -609,8 +609,8 @@ export class ContentManagementService {
|
||||
}
|
||||
|
||||
private undoMoveNodes(moveResponse, selectionParentId: string) {
|
||||
const movedNodes = moveResponse && moveResponse['succeeded'] ? moveResponse['succeeded'] : [];
|
||||
const partiallyMovedNodes = moveResponse && moveResponse['partiallySucceeded'] ? moveResponse['partiallySucceeded'] : [];
|
||||
const movedNodes = moveResponse?.['succeeded'] ?? [];
|
||||
const partiallyMovedNodes = moveResponse?.['partiallySucceeded'] ?? [];
|
||||
|
||||
const restoreDeletedNodesBatch = this.nodeActionsService.moveDeletedEntries.map((folderEntry) =>
|
||||
this.contentApi.restoreNode(folderEntry.nodeId || folderEntry.id).pipe(map((node) => node.entry))
|
||||
@@ -623,7 +623,7 @@ export class ContentManagementService {
|
||||
|
||||
const revertMoveBatch = this.nodeActionsService
|
||||
.flatten(nodesToBeMovedBack)
|
||||
.filter((node) => node.entry || (node.itemMoved && node.itemMoved.entry))
|
||||
.filter((node) => node.entry || node.itemMoved?.entry)
|
||||
.map((node) => {
|
||||
if (node.itemMoved) {
|
||||
return this.nodeActionsService.moveNodeAction(node.itemMoved.entry, node.initialParentId);
|
||||
@@ -647,7 +647,7 @@ export class ContentManagementService {
|
||||
errorJson = JSON.parse(error.message);
|
||||
} catch {}
|
||||
|
||||
if (errorJson && errorJson.error && errorJson.error.statusCode === 403) {
|
||||
if (errorJson?.error?.statusCode === 403) {
|
||||
message = 'APP.MESSAGES.ERRORS.PERMISSION';
|
||||
}
|
||||
|
||||
@@ -1009,9 +1009,9 @@ export class ContentManagementService {
|
||||
}
|
||||
|
||||
private showMoveMessage(nodes: Array<NodeEntry>, info: any, moveResponse?: any) {
|
||||
const succeeded = moveResponse && moveResponse['succeeded'] ? moveResponse['succeeded'].length : 0;
|
||||
const partiallySucceeded = moveResponse && moveResponse['partiallySucceeded'] ? moveResponse['partiallySucceeded'].length : 0;
|
||||
const failures = moveResponse && moveResponse['failed'] ? moveResponse['failed'].length : 0;
|
||||
const succeeded = moveResponse?.['succeeded'].length ?? 0;
|
||||
const partiallySucceeded = moveResponse?.['partiallySucceeded'].length ?? 0;
|
||||
const failures = moveResponse?.['failed'].length ?? 0;
|
||||
|
||||
let successMessage = '';
|
||||
let partialSuccessMessage = '';
|
||||
|
@@ -89,7 +89,7 @@ describe('NodeActionsService', () => {
|
||||
reject(permissionError);
|
||||
} else {
|
||||
const node = familyNodes.filter((familyNode) => familyNode.parentNodeId === parentId);
|
||||
resolve({ list: { entries: node[0].nodeChildren } } || emptyChildrenList);
|
||||
resolve(node.length > 0 ? { list: { entries: node[0].nodeChildren } } : emptyChildrenList);
|
||||
}
|
||||
})
|
||||
};
|
||||
|
@@ -143,8 +143,8 @@ export class NodeActionsService {
|
||||
}
|
||||
|
||||
isEntryEntitiesArray(contentEntities: any[]): boolean {
|
||||
if (contentEntities && contentEntities.length) {
|
||||
const nonEntryNode = contentEntities.find((node) => !node || !node.entry || !(node.entry.nodeId || node.entry.id));
|
||||
if (contentEntities?.length) {
|
||||
const nonEntryNode = contentEntities.find((node) => !(node?.entry?.nodeId || node?.entry?.id));
|
||||
return !nonEntryNode;
|
||||
}
|
||||
return false;
|
||||
@@ -160,7 +160,7 @@ export class NodeActionsService {
|
||||
|
||||
if (nodeEntry.parentId) {
|
||||
entryParentId = nodeEntry.parentId;
|
||||
} else if (nodeEntry.path && nodeEntry.path.elements && nodeEntry.path.elements.length) {
|
||||
} else if (nodeEntry.path?.elements?.length) {
|
||||
entryParentId = nodeEntry.path.elements[nodeEntry.path.elements.length - 1].id;
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ export class NodeActionsService {
|
||||
|
||||
// todo: review this approach once 5.2.3 is out
|
||||
private customizeBreadcrumb(node: Node) {
|
||||
if (node && node.path && node.path.elements) {
|
||||
if (node?.path?.elements) {
|
||||
const elements = node.path.elements;
|
||||
|
||||
if (elements.length > 1) {
|
||||
@@ -316,7 +316,7 @@ export class NodeActionsService {
|
||||
}
|
||||
|
||||
isSiteContainer(node: Node): boolean {
|
||||
if (node && node.aspectNames && node.aspectNames.length > 0) {
|
||||
if (node?.aspectNames?.length > 0) {
|
||||
return node.aspectNames.indexOf('st:siteContainer') >= 0;
|
||||
}
|
||||
return false;
|
||||
@@ -658,7 +658,7 @@ export class NodeActionsService {
|
||||
const folderMoveResponseData = this.flatten(next);
|
||||
const foundError = folderMoveResponseData.find((node) => node instanceof Error);
|
||||
// data might contain also items of form: { itemMoved, initialParentId }
|
||||
const foundEntry = folderMoveResponseData.find((node) => (node.itemMoved && node.itemMoved.entry) || (node && node.entry));
|
||||
const foundEntry = folderMoveResponseData.find((node) => node.itemMoved?.entry || node?.entry);
|
||||
|
||||
if (!foundError) {
|
||||
// consider success if NONE of the items from the folder move response is an error
|
||||
@@ -677,7 +677,7 @@ export class NodeActionsService {
|
||||
return acc;
|
||||
}, moveStatus);
|
||||
} else {
|
||||
if ((data.itemMoved && data.itemMoved.entry) || (data && data.entry)) {
|
||||
if (data.itemMoved?.entry || data?.entry) {
|
||||
moveStatus.succeeded.push(data);
|
||||
} else {
|
||||
moveStatus.failed.push(data);
|
||||
|
@@ -153,11 +153,7 @@ describe('NodeTemplateService', () => {
|
||||
}));
|
||||
|
||||
it('should raise an error when getNodeInfo fails', fakeAsync(() => {
|
||||
spyOn(nodeTemplateService['searchApi'], 'search').and.returnValue(
|
||||
Promise.reject({
|
||||
message: `{ "error": { "statusCode": 404 } } `
|
||||
})
|
||||
);
|
||||
spyOn(nodeTemplateService['searchApi'], 'search').and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 404 } }')));
|
||||
spyOn(store, 'dispatch');
|
||||
|
||||
nodeTemplateService.selectTemplateDialog(fileTemplateConfig);
|
||||
|
@@ -125,7 +125,7 @@ export class NodeTemplateService {
|
||||
}
|
||||
|
||||
private transformNode(node: Node): Node {
|
||||
if (node && node.path && node.path && node.path.elements instanceof Array) {
|
||||
if (node?.path?.elements instanceof Array) {
|
||||
node.path.elements = this.getPathElements(node);
|
||||
}
|
||||
return node;
|
||||
|
@@ -62,7 +62,7 @@ export class LibraryEffects {
|
||||
.select(getAppSelection)
|
||||
.pipe(take(1))
|
||||
.subscribe((selection) => {
|
||||
if (selection && selection.library) {
|
||||
if (selection?.library) {
|
||||
this.content.deleteLibrary(selection.library.entry.id);
|
||||
}
|
||||
});
|
||||
@@ -84,7 +84,7 @@ export class LibraryEffects {
|
||||
.select(getAppSelection)
|
||||
.pipe(take(1))
|
||||
.subscribe((selection) => {
|
||||
if (selection && selection.library) {
|
||||
if (selection?.library) {
|
||||
this.content.leaveLibrary(selection.library.entry.id, action.configuration?.focusedElementOnCloseSelector);
|
||||
}
|
||||
});
|
||||
@@ -138,7 +138,7 @@ export class LibraryEffects {
|
||||
.select(getAppSelection)
|
||||
.pipe(take(1))
|
||||
.subscribe((selection) => {
|
||||
if (selection && selection.library) {
|
||||
if (selection?.library) {
|
||||
const { id } = selection.library.entry;
|
||||
const { title, description, visibility } = action.payload;
|
||||
|
||||
|
@@ -78,7 +78,7 @@ export class NodeEffects {
|
||||
.select(getAppSelection)
|
||||
.pipe(take(1))
|
||||
.subscribe((selection) => {
|
||||
if (selection && selection.file) {
|
||||
if (selection?.file) {
|
||||
this.contentService.shareNode(selection.file, action.configuration?.focusedElementOnCloseSelector);
|
||||
}
|
||||
});
|
||||
@@ -93,7 +93,7 @@ export class NodeEffects {
|
||||
this.actions$.pipe(
|
||||
ofType<UnshareNodesAction>(NodeActionTypes.Unshare),
|
||||
map((action) => {
|
||||
if (action && action.payload && action.payload.length > 0) {
|
||||
if (action?.payload?.length > 0) {
|
||||
this.contentService.unshareNodes(action.payload);
|
||||
} else {
|
||||
this.store
|
||||
@@ -115,7 +115,7 @@ export class NodeEffects {
|
||||
this.actions$.pipe(
|
||||
ofType<PurgeDeletedNodesAction>(NodeActionTypes.PurgeDeleted),
|
||||
map((action) => {
|
||||
if (action && action.payload && action.payload.length > 0) {
|
||||
if (action?.payload?.length > 0) {
|
||||
this.contentService.purgeDeletedNodes(action.payload);
|
||||
} else {
|
||||
this.store
|
||||
@@ -137,7 +137,7 @@ export class NodeEffects {
|
||||
this.actions$.pipe(
|
||||
ofType<RestoreDeletedNodesAction>(NodeActionTypes.RestoreDeleted),
|
||||
map((action) => {
|
||||
if (action && action.payload && action.payload.length > 0) {
|
||||
if (action?.payload?.length > 0) {
|
||||
this.contentService.restoreDeletedNodes(action.payload);
|
||||
} else {
|
||||
this.store
|
||||
@@ -160,7 +160,7 @@ export class NodeEffects {
|
||||
ofType<DeleteNodesAction>(NodeActionTypes.Delete),
|
||||
map((action) => {
|
||||
this.store.dispatch(new ShowLoaderAction(true));
|
||||
if (action && action.payload && action.payload.length > 0) {
|
||||
if (action?.payload?.length > 0) {
|
||||
this.contentService.deleteNodes(action.payload);
|
||||
} else {
|
||||
this.store
|
||||
@@ -202,7 +202,7 @@ export class NodeEffects {
|
||||
.select(getCurrentFolder)
|
||||
.pipe(take(1))
|
||||
.subscribe((node) => {
|
||||
if (node && node.id) {
|
||||
if (node?.id) {
|
||||
this.contentService.createFolder(node.id);
|
||||
}
|
||||
});
|
||||
@@ -224,7 +224,7 @@ export class NodeEffects {
|
||||
.select(getAppSelection)
|
||||
.pipe(take(1))
|
||||
.subscribe((selection) => {
|
||||
if (selection && selection.folder) {
|
||||
if (selection?.folder) {
|
||||
this.contentService.editFolder(selection.folder, action.configuration?.focusedElementOnCloseSelector);
|
||||
}
|
||||
});
|
||||
@@ -347,7 +347,7 @@ export class NodeEffects {
|
||||
.select(getAppSelection)
|
||||
.pipe(take(1))
|
||||
.subscribe((selection) => {
|
||||
if (selection && selection.file) {
|
||||
if (selection?.file) {
|
||||
this.contentService.manageVersions(selection.file, action.configuration?.focusedElementOnCloseSelector);
|
||||
}
|
||||
});
|
||||
@@ -362,14 +362,14 @@ export class NodeEffects {
|
||||
this.actions$.pipe(
|
||||
ofType<PrintFileAction>(NodeActionTypes.PrintFile),
|
||||
map((action) => {
|
||||
if (action && action.payload) {
|
||||
if (action?.payload) {
|
||||
this.printFile(action.payload);
|
||||
} else {
|
||||
this.store
|
||||
.select(getAppSelection)
|
||||
.pipe(take(1))
|
||||
.subscribe((selection) => {
|
||||
if (selection && selection.file) {
|
||||
if (selection?.file) {
|
||||
this.printFile(selection.file);
|
||||
}
|
||||
});
|
||||
@@ -384,14 +384,14 @@ export class NodeEffects {
|
||||
this.actions$.pipe(
|
||||
ofType<UnlockWriteAction>(NodeActionTypes.UnlockForWriting),
|
||||
map((action) => {
|
||||
if (action && action.payload) {
|
||||
if (action?.payload) {
|
||||
this.contentService.unlockNode(action.payload);
|
||||
} else {
|
||||
this.store
|
||||
.select(getAppSelection)
|
||||
.pipe(take(1))
|
||||
.subscribe((selection) => {
|
||||
if (selection && selection.file) {
|
||||
if (selection?.file) {
|
||||
this.contentService.unlockNode(selection.file);
|
||||
}
|
||||
});
|
||||
@@ -424,7 +424,7 @@ export class NodeEffects {
|
||||
);
|
||||
|
||||
printFile(node: any) {
|
||||
if (node && node.entry) {
|
||||
if (node?.entry) {
|
||||
// shared and favorite
|
||||
const id = node.entry.nodeId || node.entry.guid || node.entry.id;
|
||||
const mimeType = node.entry.content.mimeType;
|
||||
|
@@ -156,11 +156,7 @@ describe('TemplateEffects', () => {
|
||||
}));
|
||||
|
||||
it('should raise generic error when copyNode api fails', fakeAsync(() => {
|
||||
copyNodeSpy.and.returnValue(
|
||||
Promise.reject({
|
||||
message: `{ "error": { "statusCode": 404 } } `
|
||||
})
|
||||
);
|
||||
copyNodeSpy.and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 404 } }')));
|
||||
|
||||
store.dispatch(new CreateFromTemplate(node));
|
||||
tick();
|
||||
@@ -170,11 +166,7 @@ describe('TemplateEffects', () => {
|
||||
}));
|
||||
|
||||
it('should raise name conflict error when copyNode api returns 409', fakeAsync(() => {
|
||||
copyNodeSpy.and.returnValue(
|
||||
Promise.reject({
|
||||
message: `{ "error": { "statusCode": 409 } } `
|
||||
})
|
||||
);
|
||||
copyNodeSpy.and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 409 } }')));
|
||||
|
||||
store.dispatch(new CreateFromTemplate(node));
|
||||
tick();
|
||||
@@ -195,11 +187,7 @@ describe('TemplateEffects', () => {
|
||||
} as NodeEntry;
|
||||
copyNodeSpy.and.returnValue(of(TEST_NODE));
|
||||
|
||||
updateNodeSpy.and.returnValue(
|
||||
Promise.reject({
|
||||
message: `{ "error": { "statusCode": 404 } } `
|
||||
})
|
||||
);
|
||||
updateNodeSpy.and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 404 } }')));
|
||||
|
||||
store.dispatch(new CreateFromTemplate(TEST_NODE.entry));
|
||||
tick();
|
||||
|
@@ -150,7 +150,7 @@ export class UploadEffects {
|
||||
.select(getCurrentFolder)
|
||||
.pipe(take(1))
|
||||
.subscribe((node) => {
|
||||
if (node && node.id) {
|
||||
if (node?.id) {
|
||||
const input = event.currentTarget as HTMLInputElement;
|
||||
const files = FileUtils.toFileArray(input.files).map(
|
||||
(file: any) =>
|
||||
@@ -186,13 +186,7 @@ export class UploadEffects {
|
||||
this.uploadService.uploadFilesInTheQueue();
|
||||
|
||||
const subscription = this.uploadService.fileUploadComplete.subscribe((completed) => {
|
||||
if (
|
||||
file.data &&
|
||||
file.data.entry &&
|
||||
file.data.entry.properties &&
|
||||
file.data.entry.properties['cm:lockType'] === 'WRITE_LOCK' &&
|
||||
file.data.entry.id === completed.data.entry.id
|
||||
) {
|
||||
if (file.data?.entry?.properties?.['cm:lockType'] === 'WRITE_LOCK' && file.data?.entry?.id === completed.data.entry.id) {
|
||||
this.store.dispatch(new UnlockWriteAction(completed.data));
|
||||
}
|
||||
|
||||
|
@@ -101,7 +101,7 @@ export class ViewerEffects {
|
||||
this.actions$.pipe(
|
||||
ofType<ViewFileAction>(ViewerActionTypes.ViewFile),
|
||||
map((action) => {
|
||||
if (action.payload && action.payload.entry) {
|
||||
if (action.payload?.entry) {
|
||||
const { id, nodeId, isFile } = action.payload.entry as any;
|
||||
|
||||
if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) {
|
||||
@@ -112,7 +112,7 @@ export class ViewerEffects {
|
||||
.select(fileToPreview)
|
||||
.pipe(take(1))
|
||||
.subscribe((result) => {
|
||||
if (result.selection && result.selection.file) {
|
||||
if (result.selection?.file) {
|
||||
const { id, nodeId, isFile } = result.selection.file.entry as any;
|
||||
|
||||
if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) {
|
||||
|
@@ -47,7 +47,7 @@ export function appReducer(state: AppState = INITIAL_APP_STATE, action: Action):
|
||||
|
||||
switch (action.type) {
|
||||
case AppActionTypes.SetInitialState:
|
||||
newState = Object.assign({}, (action as SetInitialStateAction).payload);
|
||||
newState = { ...(action as SetInitialStateAction).payload };
|
||||
break;
|
||||
case NodeActionTypes.SetSelection:
|
||||
newState = updateSelectedNodes(state, action as SetSelectedNodesAction);
|
||||
@@ -198,7 +198,7 @@ function updateSelectedNodes(state: AppState, action: SetSelectedNodesAction): A
|
||||
|
||||
const libraries: any[] = [...action.payload].filter((node: any) => node.isLibrary);
|
||||
if (libraries.length === 1) {
|
||||
library = libraries[0] as any;
|
||||
library = libraries[0];
|
||||
}
|
||||
|
||||
if (isEmpty) {
|
||||
|
Reference in New Issue
Block a user