Prettier upgrade and e2e type checks (#1522)

* upgrade prettier

* noImplicitAny rule

* fix type

* update tsconfig

* upgrade to 150 print width
This commit is contained in:
Denys Vuika
2020-07-14 10:03:23 +01:00
committed by GitHub
parent 32793ea7b0
commit ddc6f36ab4
339 changed files with 5170 additions and 8763 deletions

View File

@@ -38,11 +38,7 @@ export interface AcaRuleContext extends RuleContext {
* @param context Rule execution context
*/
export function canCopyNode(context: RuleContext): boolean {
return [
hasSelection(context),
navigation.isNotTrashcan(context),
navigation.isNotLibraries(context)
].every(Boolean);
return [hasSelection(context), navigation.isNotTrashcan(context), navigation.isNotLibraries(context)].every(Boolean);
}
/**
@@ -51,14 +47,10 @@ export function canCopyNode(context: RuleContext): boolean {
*/
export function canAddFavorite(context: RuleContext): boolean {
if (!context.selection.isEmpty) {
if (
navigation.isFavorites(context) ||
navigation.isLibraries(context) ||
navigation.isTrashcan(context)
) {
if (navigation.isFavorites(context) || navigation.isLibraries(context) || navigation.isTrashcan(context)) {
return false;
}
return context.selection.nodes.some(node => !node.entry.isFavorite);
return context.selection.nodes.some((node) => !node.entry.isFavorite);
}
return false;
}
@@ -72,7 +64,7 @@ export function canRemoveFavorite(context: RuleContext): boolean {
if (navigation.isFavorites(context)) {
return true;
}
return context.selection.nodes.every(node => node.entry.isFavorite);
return context.selection.nodes.every((node) => node.entry.isFavorite);
}
return false;
}
@@ -82,12 +74,7 @@ export function canRemoveFavorite(context: RuleContext): boolean {
* JSON ref: `app.selection.file.canShare`
*/
export function canShareFile(context: RuleContext): boolean {
return [
context.selection.file,
navigation.isNotTrashcan(context),
repository.hasQuickShareEnabled(context),
!isShared(context)
].every(Boolean);
return [context.selection.file, navigation.isNotTrashcan(context), repository.hasQuickShareEnabled(context), !isShared(context)].every(Boolean);
}
/**
@@ -95,11 +82,7 @@ export function canShareFile(context: RuleContext): boolean {
* JSON ref: `canToggleJoinLibrary`
*/
export function canToggleJoinLibrary(context: RuleContext): boolean {
return [
hasLibrarySelected(context),
!isPrivateLibrary(context),
hasNoLibraryRole(context)
].every(Boolean);
return [hasLibrarySelected(context), !isPrivateLibrary(context), hasNoLibraryRole(context)].every(Boolean);
}
/**
@@ -108,10 +91,7 @@ export function canToggleJoinLibrary(context: RuleContext): boolean {
* @param context Rule execution context
*/
export function canEditFolder(context: RuleContext): boolean {
return [
canUpdateSelectedFolder(context),
navigation.isNotTrashcan(context)
].every(Boolean);
return [canUpdateSelectedFolder(context), navigation.isNotTrashcan(context)].every(Boolean);
}
/**
@@ -123,15 +103,8 @@ export function isShared(context: RuleContext): boolean {
return true;
}
if (
(navigation.isNotTrashcan(context),
!context.selection.isEmpty && context.selection.file)
) {
return !!(
context.selection.file.entry &&
context.selection.file.entry.properties &&
context.selection.file.entry.properties['qshare:sharedId']
);
if ((navigation.isNotTrashcan(context), !context.selection.isEmpty && context.selection.file)) {
return !!(context.selection.file.entry && context.selection.file.entry.properties && context.selection.file.entry.properties['qshare:sharedId']);
}
return false;
@@ -225,10 +198,7 @@ export function canUpload(context: RuleContext): boolean {
export function canDownloadSelection(context: RuleContext): boolean {
if (!context.selection.isEmpty && navigation.isNotTrashcan(context)) {
return context.selection.nodes.every((node: any) => {
return (
node.entry &&
(node.entry.isFile || node.entry.isFolder || !!node.entry.nodeId)
);
return node.entry && (node.entry.isFile || node.entry.isFolder || !!node.entry.nodeId);
});
}
return false;
@@ -258,13 +228,7 @@ export function hasLibrarySelected(context: RuleContext): boolean {
*/
export function isPrivateLibrary(context: RuleContext): boolean {
const library = context.selection.library;
return library
? !!(
library.entry &&
library.entry.visibility &&
library.entry.visibility === 'PRIVATE'
)
: false;
return library ? !!(library.entry && library.entry.visibility && library.entry.visibility === 'PRIVATE') : false;
}
/**
@@ -321,8 +285,7 @@ export function canUpdateSelectedFolder(context: RuleContext): boolean {
if (folder) {
return (
// workaround for Favorites Api
navigation.isFavorites(context) ||
context.permissions.check(folder.entry, ['update'])
navigation.isFavorites(context) || context.permissions.check(folder.entry, ['update'])
);
}
return false;
@@ -334,16 +297,12 @@ export function canUpdateSelectedFolder(context: RuleContext): boolean {
*/
export function hasLockedFiles(context: RuleContext): boolean {
if (context && context.selection && context.selection.nodes) {
return context.selection.nodes.some(node => {
return context.selection.nodes.some((node) => {
if (!node.entry.isFile) {
return false;
}
return (
node.entry.isLocked ||
(node.entry.properties &&
node.entry.properties['cm:lockType'] === 'READ_ONLY_LOCK')
);
return node.entry.isLocked || (node.entry.properties && node.entry.properties['cm:lockType'] === 'READ_ONLY_LOCK');
});
}
@@ -362,8 +321,7 @@ export function isWriteLocked(context: RuleContext): boolean {
context.selection.file.entry &&
context.selection.file.entry.properties &&
(context.selection.file.entry.properties['cm:lockType'] === 'WRITE_LOCK' ||
context.selection.file.entry.properties['cm:lockType'] ===
'READ_ONLY_LOCK')
context.selection.file.entry.properties['cm:lockType'] === 'READ_ONLY_LOCK')
);
}
@@ -376,8 +334,7 @@ export function isUserWriteLockOwner(context: RuleContext): boolean {
return (
isWriteLocked(context) &&
context.selection.file.entry.properties['cm:lockOwner'] &&
context.selection.file.entry.properties['cm:lockOwner'].id ===
context.profile.id
context.selection.file.entry.properties['cm:lockOwner'].id === context.profile.id
);
}
@@ -395,11 +352,7 @@ export function canLockFile(context: RuleContext): boolean {
*/
export function canUnlockFile(context: RuleContext): boolean {
const { file } = context.selection;
return (
isWriteLocked(context) &&
(context.permissions.check(file.entry, ['delete']) ||
isUserWriteLockOwner(context))
);
return isWriteLocked(context) && (context.permissions.check(file.entry, ['delete']) || isUserWriteLockOwner(context));
}
/**
@@ -414,9 +367,7 @@ export function canUploadVersion(context: RuleContext): boolean {
return [
hasFileSelected(context),
navigation.isNotTrashcan(context),
isWriteLocked(context)
? isUserWriteLockOwner(context)
: canUpdateSelectedNode(context)
isWriteLocked(context) ? isUserWriteLockOwner(context) : canUpdateSelectedNode(context)
].every(Boolean);
}
@@ -435,9 +386,7 @@ export function isTrashcanItemSelected(context: RuleContext): boolean {
* @param context Rule execution context
*/
export function canViewFile(context: RuleContext): boolean {
return [hasFileSelected(context), navigation.isNotTrashcan(context)].every(
Boolean
);
return [hasFileSelected(context), navigation.isNotTrashcan(context)].every(Boolean);
}
/**
@@ -455,10 +404,7 @@ export function canLeaveLibrary(context: RuleContext): boolean {
* @param context Rule execution context
*/
export function canToggleSharedLink(context: RuleContext): boolean {
return [
hasFileSelected(context),
[canShareFile(context), isShared(context)].some(Boolean)
].every(Boolean);
return [hasFileSelected(context), [canShareFile(context), isShared(context)].some(Boolean)].every(Boolean);
}
/**
@@ -467,11 +413,7 @@ export function canToggleSharedLink(context: RuleContext): boolean {
* @param context Rule execution context
*/
export function canShowInfoDrawer(context: RuleContext): boolean {
return [
hasSelection(context),
navigation.isNotLibraries(context),
navigation.isNotTrashcan(context)
].every(Boolean);
return [hasSelection(context), navigation.isNotLibraries(context), navigation.isNotTrashcan(context)].every(Boolean);
}
/**
@@ -480,11 +422,7 @@ export function canShowInfoDrawer(context: RuleContext): boolean {
* @param context Rule execution context
*/
export function canManageFileVersions(context: RuleContext): boolean {
return [
hasFileSelected(context),
navigation.isNotTrashcan(context),
!hasLockedFiles(context)
].every(Boolean);
return [hasFileSelected(context), navigation.isNotTrashcan(context), !hasLockedFiles(context)].every(Boolean);
}
/**
@@ -493,10 +431,7 @@ export function canManageFileVersions(context: RuleContext): boolean {
* @param context Rule execution context
*/
export function canManagePermissions(context: RuleContext): boolean {
return [
canUpdateSelectedNode(context),
navigation.isNotTrashcan(context)
].every(Boolean);
return [canUpdateSelectedNode(context), navigation.isNotTrashcan(context)].every(Boolean);
}
/**
@@ -505,11 +440,7 @@ export function canManagePermissions(context: RuleContext): boolean {
* @param context Rule execution context
*/
export function canToggleEditOffline(context: RuleContext): boolean {
return [
hasFileSelected(context),
navigation.isNotTrashcan(context),
canLockFile(context) || canUnlockFile(context)
].every(Boolean);
return [hasFileSelected(context), navigation.isNotTrashcan(context), canLockFile(context) || canUnlockFile(context)].every(Boolean);
}
/**
@@ -520,12 +451,9 @@ export function canToggleEditOffline(context: RuleContext): boolean {
export function canToggleFavorite(context: RuleContext): boolean {
return [
[canAddFavorite(context), canRemoveFavorite(context)].some(Boolean),
[
navigation.isRecentFiles(context),
navigation.isSharedFiles(context),
navigation.isSearchResults(context),
navigation.isFavorites(context)
].some(Boolean)
[navigation.isRecentFiles(context), navigation.isSharedFiles(context), navigation.isSearchResults(context), navigation.isFavorites(context)].some(
Boolean
)
].every(Boolean);
}
@@ -553,9 +481,5 @@ export function canShowLogout(context: AcaRuleContext): boolean {
* @param context Rule execution context
*/
export function isLibraryManager(context: RuleContext): boolean {
return (
hasLibrarySelected(context) &&
context.selection.library.entry &&
context.selection.library.entry.role === 'SiteManager'
);
return hasLibrarySelected(context) && context.selection.library.entry && context.selection.library.entry.role === 'SiteManager';
}

View File

@@ -31,12 +31,7 @@ import { RuleContext } from '@alfresco/adf-extensions';
*/
export function isPreview(context: RuleContext): boolean {
const { url } = context.navigation;
return (
url &&
(url.includes('/preview/') ||
url.includes('viewer:view') ||
url.includes('/view/'))
);
return url && (url.includes('/preview/') || url.includes('viewer:view') || url.includes('/view/'));
}
/**
@@ -114,9 +109,7 @@ export function isLibraryFiles(context: RuleContext): boolean {
*/
export function isLibraries(context: RuleContext): boolean {
const { url } = context.navigation;
return (
url && (url.endsWith('/libraries') || url.startsWith('/search-libraries'))
);
return url && (url.endsWith('/libraries') || url.startsWith('/search-libraries'));
}
/**
@@ -148,10 +141,8 @@ export function isNotRecentFiles(context: RuleContext): boolean {
* Checks if a **Search Results** route is activated.
* JSON ref: `app.navigation.isSearchResults`
*/
export function isSearchResults(
context: RuleContext /*,
...args: RuleParameter[]*/
): boolean {
export function isSearchResults(context: RuleContext /*,
...args: RuleParameter[]*/): boolean {
const { url } = context.navigation;
return url && url.startsWith('/search');
}
@@ -170,11 +161,7 @@ export function isNotSearchResults(context: RuleContext): boolean {
*/
export function isSharedPreview(context: RuleContext): boolean {
const { url } = context.navigation;
return (
url &&
(url.startsWith('/shared/preview/') ||
(url.startsWith('/shared') && url.includes('viewer:view')))
);
return url && (url.startsWith('/shared/preview/') || (url.startsWith('/shared') && url.includes('viewer:view')));
}
/**
@@ -183,11 +170,7 @@ export function isSharedPreview(context: RuleContext): boolean {
*/
export function isFavoritesPreview(context: RuleContext): boolean {
const { url } = context.navigation;
return (
url &&
(url.startsWith('/favorites/preview/') ||
(url.startsWith('/favorites') && url.includes('viewer:view')))
);
return url && (url.startsWith('/favorites/preview/') || (url.startsWith('/favorites') && url.includes('viewer:view')));
}
/**

View File

@@ -52,9 +52,7 @@ describe('ExtensionsDataLoaderGuard', () => {
it('should emit true and complete in case of only one callback is present, completed', () => {
const subject = new Subject<true>();
const guard = new ExtensionsDataLoaderGuard([
() => subject.asObservable()
]);
const guard = new ExtensionsDataLoaderGuard([() => subject.asObservable()]);
guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
@@ -70,9 +68,7 @@ describe('ExtensionsDataLoaderGuard', () => {
});
it('should emit true and complete in case of only one callback is present, errored', () => {
const guard = new ExtensionsDataLoaderGuard([
() => throwError(new Error())
]);
const guard = new ExtensionsDataLoaderGuard([() => throwError(new Error())]);
guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
expect(emittedSpy).toHaveBeenCalledWith(true);
@@ -83,10 +79,7 @@ describe('ExtensionsDataLoaderGuard', () => {
it('should NOT complete in case of multiple callbacks are present and not all of them have been completed', () => {
const subject1 = new Subject<true>();
const subject2 = new Subject<true>();
const guard = new ExtensionsDataLoaderGuard([
() => subject1.asObservable(),
() => subject2.asObservable()
]);
const guard = new ExtensionsDataLoaderGuard([() => subject1.asObservable(), () => subject2.asObservable()]);
guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
@@ -101,10 +94,7 @@ describe('ExtensionsDataLoaderGuard', () => {
it('should emit true and complete in case of multiple callbacks are present and all of them have been completed', () => {
const subject1 = new Subject<true>();
const subject2 = new Subject<true>();
const guard = new ExtensionsDataLoaderGuard([
() => subject1.asObservable(),
() => subject2.asObservable()
]);
const guard = new ExtensionsDataLoaderGuard([() => subject1.asObservable(), () => subject2.asObservable()]);
guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
@@ -119,10 +109,7 @@ describe('ExtensionsDataLoaderGuard', () => {
it('should emit true and complete even if one of the observables are errored, to not block the application loading', () => {
const subject1 = new Subject<true>();
const guard = new ExtensionsDataLoaderGuard([
() => subject1.asObservable(),
() => throwError(new Error())
]);
const guard = new ExtensionsDataLoaderGuard([() => subject1.asObservable(), () => throwError(new Error())]);
guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
@@ -135,7 +122,7 @@ describe('ExtensionsDataLoaderGuard', () => {
it('should call canActivate only once', () => {
const subject1 = new Subject<true>();
const extensionLoaders = {
fct1: function() {
fct1: function () {
return subject1.asObservable();
}
};

View File

@@ -28,17 +28,13 @@ import { CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { Observable, forkJoin, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
export type ExtensionLoaderCallback = (
route: ActivatedRouteSnapshot
) => Observable<boolean>;
export type ExtensionLoaderCallback = (route: ActivatedRouteSnapshot) => Observable<boolean>;
export function DefaultExtensionLoaderFactory() {
return [];
}
export const EXTENSION_DATA_LOADERS = new InjectionToken<
ExtensionLoaderCallback[]
>('EXTENSION_DATA_LOADERS', {
export const EXTENSION_DATA_LOADERS = new InjectionToken<ExtensionLoaderCallback[]>('EXTENSION_DATA_LOADERS', {
providedIn: 'root',
factory: DefaultExtensionLoaderFactory
});
@@ -60,20 +56,16 @@ export class ExtensionsDataLoaderGuard implements CanActivate {
return of(true);
}
const dataLoaderCallbacks = this.extensionDataLoaders.map(callback =>
callback(route)
);
const dataLoaderCallbacks = this.extensionDataLoaders.map((callback) => callback(route));
// Undocumented forkJoin behaviour/bug:
// https://github.com/ReactiveX/rxjs/issues/3246
// So all callbacks need to emit before completion, otherwise forkJoin will short circuit
return forkJoin(...dataLoaderCallbacks).pipe(
map(() => true),
catchError(e => {
catchError((e) => {
// tslint:disable-next-line
console.error(
'Some of the extension data loader guards has been errored.'
);
console.error('Some of the extension data loader guards has been errored.');
// tslint:disable-next-line
console.error(e);
return of(true);

View File

@@ -23,12 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
Component,
ViewEncapsulation,
ChangeDetectionStrategy,
Input
} from '@angular/core';
import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input } from '@angular/core';
@Component({
selector: 'aca-generic-error',

View File

@@ -26,10 +26,7 @@ import { ContentActionRef } from '@alfresco/adf-extensions';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Store } from '@ngrx/store';
import {
SetInfoDrawerStateAction,
ToggleInfoDrawerAction
} from '@alfresco/aca-shared/store';
import { SetInfoDrawerStateAction, ToggleInfoDrawerAction } from '@alfresco/aca-shared/store';
import { of, Subject } from 'rxjs';
import { InfoDrawerComponent } from './info-drawer.component';
import { LibTestingModule } from '../../testing/lib-testing-module';
@@ -64,11 +61,7 @@ describe('InfoDrawerComponent', () => {
TestBed.configureTestingModule({
imports: [LibTestingModule, SharedToolbarModule],
declarations: [InfoDrawerComponent],
providers: [
ContentApiService,
{ provide: AppExtensionService, useValue: extensionServiceMock },
{ provide: Store, useValue: storeMock }
],
providers: [ContentApiService, { provide: AppExtensionService, useValue: extensionServiceMock }, { provide: Store, useValue: storeMock }],
schemas: [NO_ERRORS_SCHEMA]
});
@@ -95,9 +88,7 @@ describe('InfoDrawerComponent', () => {
fixture.detectChanges();
component.ngOnDestroy();
expect(storeMock.dispatch).toHaveBeenCalledWith(
new SetInfoDrawerStateAction(false)
);
expect(storeMock.dispatch).toHaveBeenCalledWith(new SetInfoDrawerStateAction(false));
});
it('should set displayNode when node is library', async(() => {
@@ -174,9 +165,7 @@ describe('InfoDrawerComponent', () => {
fixture.debugElement.nativeElement.dispatchEvent(event);
expect(storeMock.dispatch).toHaveBeenCalledWith(
new ToggleInfoDrawerAction()
);
expect(storeMock.dispatch).toHaveBeenCalledWith(new ToggleInfoDrawerAction());
});
it('should show the icons from extension', () => {

View File

@@ -23,26 +23,11 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
Component,
HostListener,
Input,
OnChanges,
OnDestroy,
OnInit
} from '@angular/core';
import {
MinimalNodeEntity,
MinimalNodeEntryEntity,
SiteEntry
} from '@alfresco/js-api';
import { Component, HostListener, Input, OnChanges, OnDestroy, OnInit } from '@angular/core';
import { MinimalNodeEntity, MinimalNodeEntryEntity, SiteEntry } from '@alfresco/js-api';
import { ContentActionRef, SidebarTabRef } from '@alfresco/adf-extensions';
import { Store } from '@ngrx/store';
import {
getAppSelection,
SetInfoDrawerStateAction,
ToggleInfoDrawerAction
} from '@alfresco/aca-shared/store';
import { getAppSelection, SetInfoDrawerStateAction, ToggleInfoDrawerAction } from '@alfresco/aca-shared/store';
import { AppExtensionService } from '../../services/app.extension.service';
import { ContentApiService } from '../../services/content-api.service';
import { takeUntil } from 'rxjs/operators';
@@ -69,11 +54,7 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy {
this.close();
}
constructor(
private store: Store<any>,
private contentApi: ContentApiService,
private extensions: AppExtensionService
) {}
constructor(private store: Store<any>, private contentApi: ContentApiService, private extensions: AppExtensionService) {}
ngOnInit() {
this.tabs = this.extensions.getSidebarTabs();
@@ -117,7 +98,7 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy {
this.isLoading = true;
this.contentApi.getNodeInfo(nodeId).subscribe(
entity => {
(entity) => {
this.setDisplayNode(entity);
this.isLoading = false;
},

View File

@@ -32,14 +32,7 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
import { SharedToolbarModule } from '../tool-bar/shared-toolbar.module';
@NgModule({
imports: [
CommonModule,
InfoDrawerModule,
MatProgressBarModule,
ExtensionsModule,
ToolbarModule,
SharedToolbarModule
],
imports: [CommonModule, InfoDrawerModule, MatProgressBarModule, ExtensionsModule, ToolbarModule, SharedToolbarModule],
declarations: [InfoDrawerComponent],
exports: [InfoDrawerComponent]
})

View File

@@ -23,13 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
Component,
Input,
OnInit,
ChangeDetectionStrategy,
ViewEncapsulation
} from '@angular/core';
import { Component, Input, OnInit, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
import { NodeEntry } from '@alfresco/js-api';
@@ -60,10 +54,7 @@ export class LockedByComponent implements OnInit {
writeLockedBy() {
return (
this.node &&
this.node.entry.properties &&
this.node.entry.properties['cm:lockOwner'] &&
this.node.entry.properties['cm:lockOwner'].displayName
this.node && this.node.entry.properties && this.node.entry.properties['cm:lockOwner'] && this.node.entry.properties['cm:lockOwner'].displayName
);
}
}

View File

@@ -23,19 +23,11 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
Component,
ViewEncapsulation,
ChangeDetectionStrategy,
Input,
HostBinding
} from '@angular/core';
import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input, HostBinding } from '@angular/core';
@Component({
selector: 'aca-page-layout-content',
template: `
<ng-content></ng-content>
`,
template: `<ng-content></ng-content>`,
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'aca-page-layout-content' }

View File

@@ -23,17 +23,11 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
Component,
ViewEncapsulation,
ChangeDetectionStrategy
} from '@angular/core';
import { Component, ViewEncapsulation, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'aca-page-layout-error',
template: `
<ng-content></ng-content>
`,
template: `<ng-content></ng-content>`,
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'aca-page-layout-error' }

View File

@@ -23,11 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
Component,
ViewEncapsulation,
ChangeDetectionStrategy
} from '@angular/core';
import { Component, ViewEncapsulation, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'aca-page-layout-header',

View File

@@ -23,12 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
Component,
ViewEncapsulation,
ChangeDetectionStrategy,
Input
} from '@angular/core';
import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input } from '@angular/core';
@Component({
selector: 'aca-page-layout',

View File

@@ -32,17 +32,7 @@ import { CommonModule } from '@angular/common';
@NgModule({
imports: [CommonModule],
declarations: [
PageLayoutContentComponent,
PageLayoutErrorComponent,
PageLayoutHeaderComponent,
PageLayoutComponent
],
exports: [
PageLayoutContentComponent,
PageLayoutErrorComponent,
PageLayoutHeaderComponent,
PageLayoutComponent
]
declarations: [PageLayoutContentComponent, PageLayoutErrorComponent, PageLayoutHeaderComponent, PageLayoutComponent],
exports: [PageLayoutContentComponent, PageLayoutErrorComponent, PageLayoutHeaderComponent, PageLayoutComponent]
})
export class PageLayoutModule {}

View File

@@ -34,17 +34,7 @@ import { ExtensionsModule } from '@alfresco/adf-extensions';
@NgModule({
imports: [CommonModule, CoreModule, ExtensionsModule],
declarations: [
ToolbarButtonComponent,
ToolbarActionComponent,
ToolbarMenuItemComponent,
ToolbarMenuComponent
],
exports: [
ToolbarButtonComponent,
ToolbarActionComponent,
ToolbarMenuItemComponent,
ToolbarMenuComponent
]
declarations: [ToolbarButtonComponent, ToolbarActionComponent, ToolbarMenuItemComponent, ToolbarMenuComponent],
exports: [ToolbarButtonComponent, ToolbarActionComponent, ToolbarMenuItemComponent, ToolbarMenuComponent]
})
export class SharedToolbarModule {}

View File

@@ -23,14 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
Component,
ViewEncapsulation,
ChangeDetectionStrategy,
Input,
DoCheck,
ChangeDetectorRef
} from '@angular/core';
import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input, DoCheck, ChangeDetectorRef } from '@angular/core';
import { ContentActionRef } from '@alfresco/adf-extensions';
@Component({

View File

@@ -40,11 +40,7 @@ export class ToolbarMenuComponent {
color = '';
get hasChildren(): boolean {
return (
this.actionRef &&
this.actionRef.children &&
this.actionRef.children.length > 0
);
return this.actionRef && this.actionRef.children && this.actionRef.children.length > 0;
}
trackById(_: number, obj: { id: string }) {

View File

@@ -48,8 +48,7 @@ describe('ContextActionsDirective', () => {
it('should call service to render context menu', fakeAsync(() => {
const el = document.createElement('div');
el.className =
'adf-datatable-cell adf-datatable-cell--text adf-datatable-row';
el.className = 'adf-datatable-cell adf-datatable-cell--text adf-datatable-row';
const fragment = document.createDocumentFragment();
fragment.appendChild(el);
@@ -62,8 +61,6 @@ describe('ContextActionsDirective', () => {
tick(500);
expect(storeMock.dispatch).toHaveBeenCalledWith(
new ContextMenu(mouseEventMock)
);
expect(storeMock.dispatch).toHaveBeenCalledWith(new ContextMenu(mouseEventMock));
}));
});

View File

@@ -23,13 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
Directive,
HostListener,
Input,
OnInit,
OnDestroy
} from '@angular/core';
import { Directive, HostListener, Input, OnInit, OnDestroy } from '@angular/core';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { Store } from '@ngrx/store';
@@ -64,11 +58,9 @@ export class ContextActionsDirective implements OnInit, OnDestroy {
constructor(private store: Store<AppStore>) {}
ngOnInit() {
this.execute$
.pipe(debounceTime(300), takeUntil(this.onDestroy$))
.subscribe((event: MouseEvent) => {
this.store.dispatch(new ContextMenu(event));
});
this.execute$.pipe(debounceTime(300), takeUntil(this.onDestroy$)).subscribe((event: MouseEvent) => {
this.store.dispatch(new ContextMenu(event));
});
}
ngOnDestroy() {
@@ -94,9 +86,7 @@ export class ContextActionsDirective implements OnInit, OnDestroy {
return false;
}
return this.findAncestor(target, 'adf-datatable-row').classList.contains(
'adf-is-selected'
);
return this.findAncestor(target, 'adf-datatable-row').classList.contains('adf-is-selected');
}
private findAncestor(el: Element, className: string): Element {

View File

@@ -47,15 +47,8 @@ describe('PaginationDirective', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
LibTestingModule,
SharedDirectivesModule,
CoreTestingModule
],
providers: [
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }
]
imports: [TranslateModule.forRoot(), LibTestingModule, SharedDirectivesModule, CoreTestingModule],
providers: [{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }]
});
preferences = TestBed.inject(UserPreferencesService);

View File

@@ -24,12 +24,7 @@
*/
import { Directive, OnInit, OnDestroy } from '@angular/core';
import {
PaginationComponent,
UserPreferencesService,
PaginationModel,
AppConfigService
} from '@alfresco/adf-core';
import { PaginationComponent, UserPreferencesService, PaginationModel, AppConfigService } from '@alfresco/adf-core';
import { Subscription } from 'rxjs';
@Directive({
@@ -38,16 +33,10 @@ import { Subscription } from 'rxjs';
export class PaginationDirective implements OnInit, OnDestroy {
private subscriptions: Subscription[] = [];
constructor(
private pagination: PaginationComponent,
private preferences: UserPreferencesService,
private config: AppConfigService
) {}
constructor(private pagination: PaginationComponent, private preferences: UserPreferencesService, private config: AppConfigService) {}
ngOnInit() {
this.pagination.supportedPageSizes = this.config.get(
'pagination.supportedPageSizes'
);
this.pagination.supportedPageSizes = this.config.get('pagination.supportedPageSizes');
this.subscriptions.push(
this.pagination.changePageSize.subscribe((event: PaginationModel) => {
@@ -57,7 +46,7 @@ export class PaginationDirective implements OnInit, OnDestroy {
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => subscription.unsubscribe());
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions = [];
}
}

View File

@@ -23,11 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
RouteReuseStrategy,
DetachedRouteHandle,
ActivatedRouteSnapshot
} from '@angular/router';
import { RouteReuseStrategy, DetachedRouteHandle, ActivatedRouteSnapshot } from '@angular/router';
import { ComponentRef, Injectable } from '@angular/core';
interface RouteData {
@@ -44,7 +40,7 @@ export class AppRouteReuseStrategy implements RouteReuseStrategy {
private routeCache = new Map<string, RouteInfo>();
resetCache() {
this.routeCache.forEach(value => {
this.routeCache.forEach((value) => {
this.deactivateComponent(value.handle);
});
this.routeCache.clear();
@@ -60,10 +56,7 @@ export class AppRouteReuseStrategy implements RouteReuseStrategy {
}
}
shouldReuseRoute(
future: ActivatedRouteSnapshot,
curr: ActivatedRouteSnapshot
): boolean {
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
const ret = future.routeConfig === curr.routeConfig;
if (ret) {
this.addRedirectsRecursively(future); // update redirects
@@ -91,9 +84,7 @@ export class AppRouteReuseStrategy implements RouteReuseStrategy {
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
const url = this.getFullRouteUrl(route);
const data = this.getRouteData(route);
return data && data.reuse && this.routeCache.has(url)
? this.routeCache.get(url).handle
: null;
return data && data.reuse && this.routeCache.has(url) ? this.routeCache.get(url).handle : null;
}
private addRedirectsRecursively(route: ActivatedRouteSnapshot): void {
@@ -101,40 +92,30 @@ export class AppRouteReuseStrategy implements RouteReuseStrategy {
if (config) {
if (!config.loadChildren) {
const routeFirstChild = route.firstChild;
const routeFirstChildUrl = routeFirstChild
? this.getRouteUrlPaths(routeFirstChild).join('/')
: '';
const routeFirstChildUrl = routeFirstChild ? this.getRouteUrlPaths(routeFirstChild).join('/') : '';
const childConfigs = config.children;
if (childConfigs) {
const childConfigWithRedirect = childConfigs.find(
c => c.path === '' && !!c.redirectTo
);
const childConfigWithRedirect = childConfigs.find((c) => c.path === '' && !!c.redirectTo);
if (childConfigWithRedirect) {
childConfigWithRedirect.redirectTo = routeFirstChildUrl;
}
}
}
route.children.forEach(childRoute =>
this.addRedirectsRecursively(childRoute)
);
route.children.forEach((childRoute) => this.addRedirectsRecursively(childRoute));
}
}
private getFullRouteUrl(route: ActivatedRouteSnapshot): string {
return this.getFullRouteUrlPaths(route)
.filter(Boolean)
.join('/');
return this.getFullRouteUrlPaths(route).filter(Boolean).join('/');
}
private getFullRouteUrlPaths(route: ActivatedRouteSnapshot): string[] {
const paths = this.getRouteUrlPaths(route);
return route.parent
? [...this.getFullRouteUrlPaths(route.parent), ...paths]
: paths;
return route.parent ? [...this.getFullRouteUrlPaths(route.parent), ...paths] : paths;
}
private getRouteUrlPaths(route: ActivatedRouteSnapshot): string[] {
return route.url.map(urlSegment => urlSegment.path);
return route.url.map((urlSegment) => urlSegment.path);
}
private getRouteData(route: ActivatedRouteSnapshot): RouteData {

View File

@@ -39,15 +39,11 @@ export class AppSharedRuleGuard implements CanActivate {
this.isQuickShareEnabled$ = store.select(isQuickShareEnabled);
}
canActivate(
_: ActivatedRouteSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
canActivate(_: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.isQuickShareEnabled$;
}
canActivateChild(
route: ActivatedRouteSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
canActivateChild(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.canActivate(route);
}
}

View File

@@ -567,9 +567,7 @@ describe('AppExtensionService', () => {
});
it('should use implicit order', () => {
const sorted = [{ id: '3' }, { id: '2' }, { id: '1', order: 1 }].sort(
sortByOrder
);
const sorted = [{ id: '3' }, { id: '2' }, { id: '1', order: 1 }].sort(sortByOrder);
expect(sorted[0].id).toBe('1');
expect(sorted[1].id).toBe('3');
@@ -579,11 +577,7 @@ describe('AppExtensionService', () => {
describe('filtering', () => {
it('should filter out disabled items', () => {
const items = [
{ id: 1, disabled: true },
{ id: 2 },
{ id: 3, disabled: true }
].filter(filterEnabled);
const items = [{ id: 1, disabled: true }, { id: 2 }, { id: 3, disabled: true }].filter(filterEnabled);
expect(items.length).toBe(1);
expect(items[0].id).toBe(2);
@@ -594,11 +588,7 @@ describe('AppExtensionService', () => {
{ id: '1', disabled: true },
{
id: '2',
someItems: [
{ id: '21', disabled: true },
{ id: '22', disabled: false },
{ id: '23' }
],
someItems: [{ id: '21', disabled: true }, { id: '22', disabled: false }, { id: '23' }],
someObjectProp: {
innerItems: [{ id: '24' }, { id: '25', disabled: true }]
}
@@ -700,10 +690,7 @@ describe('AppExtensionService', () => {
{ items: [{ children: [{ route: 'route3', disabled: true }] }] }
]);
expect(navigation).toEqual([
{ items: [{ route: 'route1', url: '/route1' }] },
{ items: [{ children: [] }] }
] as NavBarGroupRef[]);
expect(navigation).toEqual([{ items: [{ route: 'route1', url: '/route1' }] }, { items: [{ children: [] }] }] as NavBarGroupRef[]);
});
it('should filter out items based on rule', () => {

View File

@@ -27,11 +27,7 @@ import { Injectable, Type } from '@angular/core';
import { Store } from '@ngrx/store';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import {
AppStore,
getRuleContext,
getLanguagePickerState
} from '@alfresco/aca-shared/store';
import { AppStore, getRuleContext, getLanguagePickerState } from '@alfresco/aca-shared/store';
import {
SelectionState,
NavigationState,
@@ -53,11 +49,7 @@ import {
DocumentListPresetRef,
IconRef
} from '@alfresco/adf-extensions';
import {
AppConfigService,
AuthenticationService,
LogService
} from '@alfresco/adf-core';
import { AppConfigService, AuthenticationService, LogService } from '@alfresco/adf-core';
import { BehaviorSubject, Observable } from 'rxjs';
import { RepositoryInfo, NodeEntry } from '@alfresco/js-api';
import { ViewerRules } from '../models/viewer.rules';
@@ -132,14 +124,14 @@ export class AppExtensionService implements RuleContext {
) {
this.references$ = this._references.asObservable();
this.store.select(getRuleContext).subscribe(result => {
this.store.select(getRuleContext).subscribe((result) => {
this.selection = result.selection;
this.navigation = result.navigation;
this.profile = result.profile;
this.repository = result.repository;
});
this.store.select(getLanguagePickerState).subscribe(result => {
this.store.select(getLanguagePickerState).subscribe((result) => {
this.languagePicker = result;
});
}
@@ -155,62 +147,26 @@ export class AppExtensionService implements RuleContext {
return;
}
this.settingGroups = this.loader.getElements<SettingsGroupRef>(
config,
'settings'
);
this.settingGroups = this.loader.getElements<SettingsGroupRef>(config, 'settings');
this.headerActions = this.loader.getContentActions(
config,
'features.header'
);
this.sidebarActions = this.loader.getContentActions(
config,
'features.sidebar.toolbar'
);
this.toolbarActions = this.loader.getContentActions(
config,
'features.toolbar'
);
this.viewerToolbarActions = this.loader.getContentActions(
config,
'features.viewer.toolbarActions'
);
this.sharedLinkViewerToolbarActions = this.loader.getContentActions(
config,
'features.viewer.shared.toolbarActions'
);
this.headerActions = this.loader.getContentActions(config, 'features.header');
this.sidebarActions = this.loader.getContentActions(config, 'features.sidebar.toolbar');
this.toolbarActions = this.loader.getContentActions(config, 'features.toolbar');
this.viewerToolbarActions = this.loader.getContentActions(config, 'features.viewer.toolbarActions');
this.sharedLinkViewerToolbarActions = this.loader.getContentActions(config, 'features.viewer.shared.toolbarActions');
this.contextMenuActions = this.loader.getContentActions(
config,
'features.contextMenu'
);
this.openWithActions = this.loader.getContentActions(
config,
'features.viewer.openWith'
);
this.createActions = this.loader.getElements<ContentActionRef>(
config,
'features.create'
);
this.contextMenuActions = this.loader.getContentActions(config, 'features.contextMenu');
this.openWithActions = this.loader.getContentActions(config, 'features.viewer.openWith');
this.createActions = this.loader.getElements<ContentActionRef>(config, 'features.create');
this.navbar = this.loadNavBar(config);
this.sidebarTabs = this.loader.getElements<SidebarTabRef>(
config,
'features.sidebar.tabs'
);
this.userActions = this.loader.getContentActions(
config,
'features.userActions'
);
this.sidebarTabs = this.loader.getElements<SidebarTabRef>(config, 'features.sidebar.tabs');
this.userActions = this.loader.getContentActions(config, 'features.userActions');
this.contentMetadata = this.loadContentMetadata(config);
this.documentListPresets = {
files: this.getDocumentListPreset(config, 'files'),
libraries: this.getDocumentListPreset(config, 'libraries'),
favoriteLibraries: this.getDocumentListPreset(
config,
'favoriteLibraries'
),
favoriteLibraries: this.getDocumentListPreset(config, 'favoriteLibraries'),
shared: this.getDocumentListPreset(config, 'shared'),
recent: this.getDocumentListPreset(config, 'recent'),
favorites: this.getDocumentListPreset(config, 'favorites'),
@@ -218,10 +174,7 @@ export class AppExtensionService implements RuleContext {
searchLibraries: this.getDocumentListPreset(config, 'search-libraries')
};
this.withCredentials = this.appConfig.get<boolean>(
'auth.withCredentials',
false
);
this.withCredentials = this.appConfig.get<boolean>('auth.withCredentials', false);
if (config.features && config.features.viewer) {
this.viewerRules = (config.features.viewer['rules'] as ViewerRules) || {};
@@ -229,16 +182,12 @@ export class AppExtensionService implements RuleContext {
this.registerIcons(config);
const references = (config.$references || [])
.filter(entry => typeof entry === 'object')
.map(entry => entry as ExtensionRef);
const references = (config.$references || []).filter((entry) => typeof entry === 'object').map((entry) => entry as ExtensionRef);
this._references.next(references);
}
protected registerIcons(config: ExtensionConfig) {
const icons: Array<IconRef> = this.loader
.getElements<IconRef>(config, 'features.icons')
.filter(entry => !entry.disabled);
const icons: Array<IconRef> = this.loader.getElements<IconRef>(config, 'features.icons').filter((entry) => !entry.disabled);
for (const icon of icons) {
const [ns, id] = icon.id.split(':');
@@ -249,11 +198,7 @@ export class AppExtensionService implements RuleContext {
} else if (!ns || !id) {
console.warn(`Incorrect icon id format: "${icon.id}".`);
} else {
this.matIconRegistry.addSvgIconInNamespace(
ns,
id,
this.sanitizer.bypassSecurityTrustResourceUrl(value)
);
this.matIconRegistry.addSvgIconInNamespace(ns, id, this.sanitizer.bypassSecurityTrustResourceUrl(value));
}
}
}
@@ -263,31 +208,26 @@ export class AppExtensionService implements RuleContext {
}
protected getDocumentListPreset(config: ExtensionConfig, key: string) {
return this.loader
.getElements<DocumentListPresetRef>(
config,
`features.documentList.${key}`
)
.filter(entry => !entry.disabled);
return this.loader.getElements<DocumentListPresetRef>(config, `features.documentList.${key}`).filter((entry) => !entry.disabled);
}
getApplicationNavigation(elements): Array<NavBarGroupRef> {
return elements
.filter(group => this.filterVisible(group))
.map(group => {
.filter((group) => this.filterVisible(group))
.map((group) => {
return {
...group,
items: (group.items || [])
.filter(entry => !entry.disabled)
.filter(item => this.filterVisible(item))
.filter((entry) => !entry.disabled)
.filter((item) => this.filterVisible(item))
.sort(sortByOrder)
.map(item => {
.map((item) => {
if (item.children && item.children.length > 0) {
item.children = item.children
.filter(entry => !entry.disabled)
.filter(child => this.filterVisible(child))
.filter((entry) => !entry.disabled)
.filter((child) => this.filterVisible(child))
.sort(sortByOrder)
.map(child => {
.map((child) => {
if (child.component) {
return {
...child
@@ -295,12 +235,8 @@ export class AppExtensionService implements RuleContext {
}
if (!child.click) {
const childRouteRef = this.extensions.getRouteById(
child.route
);
const childUrl = `/${
childRouteRef ? childRouteRef.path : child.route
}`;
const childRouteRef = this.extensions.getRouteById(child.route);
const childUrl = `/${childRouteRef ? childRouteRef.path : child.route}`;
return {
...child,
url: childUrl
@@ -342,10 +278,7 @@ export class AppExtensionService implements RuleContext {
}
loadContentMetadata(config: ExtensionConfig): any {
const elements = this.loader.getElements<any>(
config,
'features.content-metadata-presets'
);
const elements = this.loader.getElements<any>(config, 'features.content-metadata-presets');
if (!elements.length) {
return null;
}
@@ -356,10 +289,7 @@ export class AppExtensionService implements RuleContext {
try {
this.appConfig.config['content-metadata'] = { presets };
} catch (error) {
this.logger.error(
error,
'- could not change content-metadata from app.config -'
);
this.logger.error(error, '- could not change content-metadata from app.config -');
}
return { presets };
@@ -367,12 +297,10 @@ export class AppExtensionService implements RuleContext {
filterDisabled(object: Array<{ disabled: boolean }> | { disabled: boolean }) {
if (Array.isArray(object)) {
return object
.filter(item => !item.disabled)
.map(item => this.filterDisabled(item));
return object.filter((item) => !item.disabled).map((item) => this.filterDisabled(item));
} else if (typeof object === 'object') {
if (!object.disabled) {
Object.keys(object).forEach(prop => {
Object.keys(object).forEach((prop) => {
object[prop] = this.filterDisabled(object[prop]);
});
return object;
@@ -387,7 +315,7 @@ export class AppExtensionService implements RuleContext {
}
getSidebarTabs(): Array<SidebarTabRef> {
return this.sidebarTabs.filter(action => this.filterVisible(action));
return this.sidebarTabs.filter((action) => this.filterVisible(action));
}
getComponentById(id: string): Type<{}> {
@@ -395,10 +323,8 @@ export class AppExtensionService implements RuleContext {
}
getApplicationRoutes(): Array<ExtensionRoute> {
return this.extensions.routes.map(route => {
const guards = this.extensions.getAuthGuards(
route.auth && route.auth.length > 0 ? route.auth : this.defaults.auth
);
return this.extensions.routes.map((route) => {
const guards = this.extensions.getAuthGuards(route.auth && route.auth.length > 0 ? route.auth : this.defaults.auth);
return {
path: route.path,
@@ -419,10 +345,10 @@ export class AppExtensionService implements RuleContext {
getCreateActions(): Array<ContentActionRef> {
return this.createActions
.filter(action => this.filterVisible(action))
.map(action => this.copyAction(action))
.map(action => this.buildMenu(action))
.map(action => {
.filter((action) => this.filterVisible(action))
.map((action) => this.copyAction(action))
.map((action) => this.buildMenu(action))
.map((action) => {
let disabled = false;
if (action.rules && action.rules.enabled) {
@@ -437,24 +363,15 @@ export class AppExtensionService implements RuleContext {
}
private buildMenu(actionRef: ContentActionRef): ContentActionRef {
if (
actionRef.type === ContentActionType.menu &&
actionRef.children &&
actionRef.children.length > 0
) {
const children = actionRef.children
.filter(action => this.filterVisible(action))
.map(action => this.buildMenu(action));
if (actionRef.type === ContentActionType.menu && actionRef.children && actionRef.children.length > 0) {
const children = actionRef.children.filter((action) => this.filterVisible(action)).map((action) => this.buildMenu(action));
actionRef.children = children
.map(action => {
.map((action) => {
let disabled = false;
if (action.rules && action.rules.enabled) {
disabled = !this.extensions.evaluateRule(
action.rules.enabled,
this
);
disabled = !this.extensions.evaluateRule(action.rules.enabled, this);
}
return {
@@ -472,14 +389,14 @@ export class AppExtensionService implements RuleContext {
private getAllowedActions(actions: ContentActionRef[]): ContentActionRef[] {
return (actions || [])
.filter(action => this.filterVisible(action))
.map(action => {
.filter((action) => this.filterVisible(action))
.map((action) => {
if (action.type === ContentActionType.menu) {
const copy = this.copyAction(action);
if (copy.children && copy.children.length > 0) {
copy.children = copy.children
.filter(entry => !entry.disabled)
.filter(childAction => this.filterVisible(childAction))
.filter((entry) => !entry.disabled)
.filter((childAction) => this.filterVisible(childAction))
.sort(sortByOrder)
.reduce(reduceSeparators, []);
}
@@ -509,13 +426,13 @@ export class AppExtensionService implements RuleContext {
getHeaderActions(): Array<ContentActionRef> {
return this.headerActions
.filter(action => this.filterVisible(action))
.map(action => {
.filter((action) => this.filterVisible(action))
.map((action) => {
if (action.type === ContentActionType.menu) {
const copy = this.copyAction(action);
if (copy.children && copy.children.length > 0) {
copy.children = copy.children
.filter(childAction => this.filterVisible(childAction))
.filter((childAction) => this.filterVisible(childAction))
.sort(sortByOrder)
.reduce(reduceEmptyMenus, [])
.reduce(reduceSeparators, []);
@@ -535,25 +452,21 @@ export class AppExtensionService implements RuleContext {
}
getUserActions(): Array<ContentActionRef> {
return this.userActions
.filter(action => this.filterVisible(action))
.sort(sortByOrder);
return this.userActions.filter((action) => this.filterVisible(action)).sort(sortByOrder);
}
getSettingsGroups(): Array<SettingsGroupRef> {
return this.settingGroups.filter(group => this.filterVisible(group));
return this.settingGroups.filter((group) => this.filterVisible(group));
}
copyAction(action: ContentActionRef): ContentActionRef {
return {
...action,
children: (action.children || []).map(child => this.copyAction(child))
children: (action.children || []).map((child) => this.copyAction(child))
};
}
filterVisible(
action: ContentActionRef | SettingsGroupRef | SidebarTabRef
): boolean {
filterVisible(action: ContentActionRef | SettingsGroupRef | SidebarTabRef): boolean {
if (action && action.rules && action.rules.visible) {
return this.extensions.evaluateRule(action.rules.visible, this);
}

View File

@@ -61,27 +61,17 @@ describe('AppService', () => {
spyOn(routeReuse, 'resetCache').and.stub();
service = new AppService(
auth,
appConfig,
searchQueryBuilderService,
routeReuse
);
service = new AppService(auth, appConfig, searchQueryBuilderService, routeReuse);
});
it('should be ready if [withCredentials] mode is used', done => {
it('should be ready if [withCredentials] mode is used', (done) => {
appConfig.config = {
auth: {
withCredentials: true
}
};
const instance = new AppService(
auth,
appConfig,
searchQueryBuilderService,
routeReuse
);
const instance = new AppService(auth, appConfig, searchQueryBuilderService, routeReuse);
expect(instance.withCredentials).toBeTruthy();
instance.ready$.subscribe(() => {
@@ -101,7 +91,7 @@ describe('AppService', () => {
it('should be ready after login', async () => {
let isReady = false;
service.ready$.subscribe(value => {
service.ready$.subscribe((value) => {
isReady = value;
});
auth.onLogin.next();

View File

@@ -49,10 +49,7 @@ import { map } from 'rxjs/operators';
providedIn: 'root'
})
export class ContentApiService {
constructor(
private api: AlfrescoApiService,
private preferences: UserPreferencesService
) {}
constructor(private api: AlfrescoApiService, private preferences: UserPreferencesService) {}
/**
* Moves a node to the trashcan.
@@ -60,10 +57,7 @@ export class ContentApiService {
* @param options Optional parameters supported by JS-API
* @returns Empty result that notifies when the deletion is complete
*/
deleteNode(
nodeId: string,
options: { permanent?: boolean } = {}
): Observable<void> {
deleteNode(nodeId: string, options: { permanent?: boolean } = {}): Observable<void> {
return from(this.api.nodesApi.deleteNode(nodeId, options));
}
@@ -101,13 +95,7 @@ export class ContentApiService {
const defaults = {
maxItems: this.preferences.paginationSize,
skipCount: 0,
include: [
'isLocked',
'path',
'properties',
'allowableOperations',
'permissions'
]
include: ['isLocked', 'path', 'properties', 'allowableOperations', 'permissions']
};
const queryOptions = Object.assign(defaults, options);
@@ -140,10 +128,7 @@ export class ContentApiService {
* @param personId ID of the target user
* @returns User information
*/
getPerson(
personId: string,
options?: { fields?: Array<string> }
): Observable<PersonEntry> {
getPerson(personId: string, options?: { fields?: Array<string> }): Observable<PersonEntry> {
return from(this.api.peopleApi.getPerson(personId, options));
}
@@ -154,15 +139,8 @@ export class ContentApiService {
* @param targetParentId The id of the folder-node where the node have to be copied to
* @param name The new name for the copy that would be added on the destination folder
*/
copyNode(
nodeId: string,
targetParentId: string,
name?: string,
opts?: { include?: Array<string>; fields?: Array<string> }
): Observable<NodeEntry> {
return from(
this.api.nodesApi.copyNode(nodeId, { targetParentId, name }, opts)
);
copyNode(nodeId: string, targetParentId: string, name?: string, opts?: { include?: Array<string>; fields?: Array<string> }): Observable<NodeEntry> {
return from(this.api.nodesApi.copyNode(nodeId, { targetParentId, name }, opts));
}
/**
@@ -170,9 +148,7 @@ export class ContentApiService {
* @returns ProductVersionModel containing product details
*/
getRepositoryInformation(): Observable<DiscoveryEntry> {
return from(
this.api.getInstance().discovery.discoveryApi.getRepositoryInformation()
);
return from(this.api.getInstance().discovery.discoveryApi.getRepositoryInformation());
}
getFavorites(
@@ -187,10 +163,7 @@ export class ContentApiService {
return from(this.api.favoritesApi.getFavorites(personId, opts));
}
getFavoriteLibraries(
personId: string = '-me-',
opts?: any
): Observable<FavoritePaging> {
getFavoriteLibraries(personId: string = '-me-', opts?: any): Observable<FavoritePaging> {
return this.getFavorites(personId, {
...opts,
where: '(EXISTS(target/site))'
@@ -246,10 +219,7 @@ export class ContentApiService {
return from(this.api.sitesApi.createSite(siteBody, opts));
}
getSite(
siteId?: string,
opts?: { relations?: Array<string>; fields?: Array<string> }
): Observable<SiteEntry> {
getSite(siteId?: string, opts?: { relations?: Array<string>; fields?: Array<string> }): Observable<SiteEntry> {
return from(this.api.sitesApi.getSite(siteId, opts));
}
@@ -258,7 +228,7 @@ export class ContentApiService {
}
addFavorite(nodes: Array<MinimalNodeEntity>): Observable<FavoriteEntry> {
const payload: FavoriteBody[] = nodes.map(node => {
const payload: FavoriteBody[] = nodes.map((node) => {
const { isFolder, nodeId, id } = node.entry as any;
const siteId = node.entry['guid'];
const type = siteId ? 'site' : isFolder ? 'folder' : 'file';

View File

@@ -112,9 +112,7 @@ describe('NodePermissionService', () => {
}
];
expect(
permission.check(source, ['update', 'other'], { operation: 'AND' })
).toBe(true);
expect(permission.check(source, ['update', 'other'], { operation: 'AND' })).toBe(true);
});
it('should return false when source has no `AND` allowableOperations permission', () => {
@@ -128,27 +126,17 @@ describe('NodePermissionService', () => {
}
];
expect(
permission.check(source, ['update', 'bogus'], { operation: 'AND' })
).toBe(false);
expect(permission.check(source, ['update', 'bogus'], { operation: 'AND' })).toBe(false);
});
it('should return false when source has no allowableOperations', () => {
const source = [
{ entry: { allowableOperations: [] } },
{ entry: { allowableOperations: [] } },
{ entry: { allowableOperations: ['update'] } }
];
const source = [{ entry: { allowableOperations: [] } }, { entry: { allowableOperations: [] } }, { entry: { allowableOperations: ['update'] } }];
expect(permission.check(source, ['update'])).toBe(false);
});
it('should return false when source has no allowableOperations property', () => {
const source = [
{ entry: {} },
{ entry: {} },
{ entry: { allowableOperations: ['update'] } }
];
const source = [{ entry: {} }, { entry: {} }, { entry: { allowableOperations: ['update'] } }];
expect(permission.check(source, ['update'])).toBe(false);
});
@@ -196,9 +184,7 @@ describe('NodePermissionService', () => {
it('should return true when source has `AND` allowableOperations permission', () => {
const source = { entry: { allowableOperations: ['update', 'other'] } };
expect(
permission.check(source, ['update', 'other'], { operation: 'AND' })
).toBe(true);
expect(permission.check(source, ['update', 'other'], { operation: 'AND' })).toBe(true);
});
it('should return false when source has no `AND` allowableOperations permission', () => {
@@ -206,9 +192,7 @@ describe('NodePermissionService', () => {
entry: { allowableOperations: ['update', 'updatePermissions', 'other'] }
};
expect(
permission.check(source, ['update', 'bogus'], { operation: 'AND' })
).toBe(false);
expect(permission.check(source, ['update', 'bogus'], { operation: 'AND' })).toBe(false);
});
it('should return false when source has no allowableOperations', () => {

View File

@@ -45,11 +45,7 @@ export class NodePermissionService implements NodePermissions {
target: null
};
check(
source: PermissionSource | PermissionSource[],
permissions: string[],
options?: PermissionOptions
): boolean {
check(source: PermissionSource | PermissionSource[], permissions: string[], options?: PermissionOptions): boolean {
const opts = Object.assign({}, this.defaultOptions, options || {});
if (!source) {
@@ -57,12 +53,10 @@ export class NodePermissionService implements NodePermissions {
}
if (Array.isArray(source)) {
source = source.filter(item => item);
source = source.filter((item) => item);
if (source.length > 0) {
return source.every(node =>
this.isOperationAllowed(node, permissions, opts)
);
return source.every((node) => this.isOperationAllowed(node, permissions, opts));
}
return false;
} else {
@@ -70,35 +64,21 @@ export class NodePermissionService implements NodePermissions {
}
}
private isOperationAllowed(
node: PermissionSource,
permissions: string[],
options: PermissionOptions
): boolean {
const allowableOperations = this.getAllowableOperations(
node,
options.target
);
private isOperationAllowed(node: PermissionSource, permissions: string[], options: PermissionOptions): boolean {
const allowableOperations = this.getAllowableOperations(node, options.target);
if (allowableOperations.length) {
if (options.operation === NodePermissionService.DEFAULT_OPERATION) {
return permissions.some(permission =>
allowableOperations.includes(permission)
);
return permissions.some((permission) => allowableOperations.includes(permission));
} else {
return permissions.every(permission =>
allowableOperations.includes(permission)
);
return permissions.every((permission) => allowableOperations.includes(permission));
}
}
return false;
}
private getAllowableOperations(
node: PermissionSource,
property?: string
): string[] {
private getAllowableOperations(node: PermissionSource, property?: string): string[] {
let entry: Node | SharedLink;
if ('entry' in node) {

View File

@@ -30,21 +30,12 @@ export function isLocked(node: { entry: Node }): boolean {
return (
(entry && entry.isLocked) ||
(entry.properties &&
(entry.properties['cm:lockType'] === 'READ_ONLY_LOCK' ||
entry.properties['cm:lockType'] === 'WRITE_LOCK'))
(entry.properties && (entry.properties['cm:lockType'] === 'READ_ONLY_LOCK' || entry.properties['cm:lockType'] === 'WRITE_LOCK'))
);
}
export function isLibrary(node: { entry: Node | any }): boolean {
const { entry } = node;
return (
(entry.guid &&
entry.id &&
entry.preset &&
entry.title &&
entry.visibility) ||
entry.nodeType === 'st:site'
);
return (entry.guid && entry.id && entry.preset && entry.title && entry.visibility) || entry.nodeType === 'st:site';
}

View File

@@ -25,8 +25,7 @@
import { Action } from '@ngrx/store';
export const SET_INFO_DRAWER_METADATA_ASPECT =
'SET_INFO_DRAWER_METADATA_ASPECT';
export const SET_INFO_DRAWER_METADATA_ASPECT = 'SET_INFO_DRAWER_METADATA_ASPECT';
export class SetInfoDrawerMetadataAspectAction implements Action {
readonly type = SET_INFO_DRAWER_METADATA_ASPECT;

View File

@@ -35,10 +35,7 @@ export enum SearchActionTypes {
export class SearchByTermAction implements Action {
readonly type = SearchActionTypes.SearchByTerm;
constructor(
public payload: string,
public searchOptions?: SearchOptionModel[]
) {}
constructor(public payload: string, public searchOptions?: SearchOptionModel[]) {}
}
export class ToggleSearchFilterAction implements Action {

View File

@@ -27,10 +27,7 @@ import { Effect, Actions, ofType } from '@ngrx/effects';
import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators';
import { MatDialog } from '@angular/material/dialog';
import {
CloseModalDialogsAction,
AppActionTypes
} from '../actions/app.actions';
import { CloseModalDialogsAction, AppActionTypes } from '../actions/app.actions';
@Injectable()
export class DialogEffects {

View File

@@ -30,27 +30,17 @@ import { MinimalNodeEntryEntity, PathInfoEntity } from '@alfresco/js-api';
import { map } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { AppStore } from '../states/app.state';
import {
NavigateUrlAction,
RouterActionTypes,
NavigateRouteAction,
NavigateToFolder,
NavigateToParentFolder
} from '../actions/router.actions';
import { NavigateUrlAction, RouterActionTypes, NavigateRouteAction, NavigateToFolder, NavigateToParentFolder } from '../actions/router.actions';
import { SnackbarErrorAction } from '../actions/snackbar.actions';
@Injectable()
export class RouterEffects {
constructor(
private store: Store<AppStore>,
private actions$: Actions,
private router: Router
) {}
constructor(private store: Store<AppStore>, private actions$: Actions, private router: Router) {}
@Effect({ dispatch: false })
navigateUrl$ = this.actions$.pipe(
ofType<NavigateUrlAction>(RouterActionTypes.NavigateUrl),
map(action => {
map((action) => {
if (action.payload) {
this.router.navigateByUrl(action.payload);
}
@@ -60,7 +50,7 @@ export class RouterEffects {
@Effect({ dispatch: false })
navigateRoute$ = this.actions$.pipe(
ofType<NavigateRouteAction>(RouterActionTypes.NavigateRoute),
map(action => {
map((action) => {
this.router.navigate(action.payload);
})
);
@@ -68,7 +58,7 @@ export class RouterEffects {
@Effect({ dispatch: false })
navigateToFolder$ = this.actions$.pipe(
ofType<NavigateToFolder>(RouterActionTypes.NavigateFolder),
map(action => {
map((action) => {
if (action.payload && action.payload.entry) {
this.navigateToFolder(action.payload.entry);
}
@@ -78,7 +68,7 @@ export class RouterEffects {
@Effect({ dispatch: false })
navigateToParentFolder$ = this.actions$.pipe(
ofType<NavigateToParentFolder>(RouterActionTypes.NavigateParentFolder),
map(action => {
map((action) => {
if (action.payload && action.payload.entry) {
this.navigateToParentFolder(action.payload.entry);
}
@@ -131,18 +121,12 @@ export class RouterEffects {
this.router.navigate(link);
}, 10);
} else {
this.store.dispatch(
new SnackbarErrorAction('APP.MESSAGES.ERRORS.CANNOT_NAVIGATE_LOCATION')
);
this.store.dispatch(new SnackbarErrorAction('APP.MESSAGES.ERRORS.CANNOT_NAVIGATE_LOCATION'));
}
}
private isLibraryContent(path: PathInfoEntity): boolean {
if (
path &&
path.elements.length >= 2 &&
path.elements[1].name === 'Sites'
) {
if (path && path.elements.length >= 2 && path.elements[1].name === 'Sites') {
return true;
}

View File

@@ -30,13 +30,7 @@ import { Actions, Effect, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { map } from 'rxjs/operators';
import { AppStore } from '../states/app.state';
import {
SnackbarInfoAction,
SnackbarActionTypes,
SnackbarWarningAction,
SnackbarErrorAction,
SnackbarAction
} from '../actions/snackbar.actions';
import { SnackbarInfoAction, SnackbarActionTypes, SnackbarWarningAction, SnackbarErrorAction, SnackbarAction } from '../actions/snackbar.actions';
@Injectable()
export class SnackbarEffects {

View File

@@ -28,80 +28,29 @@ import { createSelector } from '@ngrx/store';
export const selectApp = (state: AppStore) => state.app;
export const getHeaderColor = createSelector(
selectApp,
state => state.headerColor
);
export const getHeaderColor = createSelector(selectApp, (state) => state.headerColor);
export const getAppName = createSelector(selectApp, (state) => state.appName);
export const getLogoPath = createSelector(selectApp, (state) => state.logoPath);
export const getHeaderImagePath = createSelector(selectApp, (state) => state.headerImagePath);
export const getLanguagePickerState = createSelector(selectApp, (state) => state.languagePicker);
export const getUserProfile = createSelector(selectApp, (state) => state.user);
export const getCurrentFolder = createSelector(selectApp, (state) => state.navigation.currentFolder);
export const getAppSelection = createSelector(selectApp, (state) => state.selection);
export const getSharedUrl = createSelector(selectApp, (state) => state.sharedUrl);
export const getNavigationState = createSelector(selectApp, (state) => state.navigation);
export const isInfoDrawerOpened = createSelector(selectApp, (state) => state.infoDrawerOpened);
export const showFacetFilter = createSelector(selectApp, (state) => state.showFacetFilter);
export const getDocumentDisplayMode = createSelector(selectApp, (state) => state.documentDisplayMode);
export const getRepositoryStatus = createSelector(selectApp, (state) => state.repository);
export const isQuickShareEnabled = createSelector(getRepositoryStatus, (info) => info.status.isQuickShareEnabled);
export const isAdmin = createSelector(selectApp, (state) => state.user.isAdmin);
export const getAppName = createSelector(selectApp, state => state.appName);
export const getLogoPath = createSelector(selectApp, state => state.logoPath);
export const getHeaderImagePath = createSelector(
selectApp,
state => state.headerImagePath
);
export const getLanguagePickerState = createSelector(
selectApp,
state => state.languagePicker
);
export const getUserProfile = createSelector(selectApp, state => state.user);
export const getCurrentFolder = createSelector(
selectApp,
state => state.navigation.currentFolder
);
export const getAppSelection = createSelector(
selectApp,
state => state.selection
);
export const getSharedUrl = createSelector(selectApp, state => state.sharedUrl);
export const getNavigationState = createSelector(
selectApp,
state => state.navigation
);
export const isInfoDrawerOpened = createSelector(
selectApp,
state => state.infoDrawerOpened
);
export const showFacetFilter = createSelector(
selectApp,
state => state.showFacetFilter
);
export const getDocumentDisplayMode = createSelector(
selectApp,
state => state.documentDisplayMode
);
export const getRepositoryStatus = createSelector(
selectApp,
state => state.repository
);
export const isQuickShareEnabled = createSelector(
getRepositoryStatus,
info => info.status.isQuickShareEnabled
);
export const isAdmin = createSelector(selectApp, state => state.user.isAdmin);
export const getSideNavState = createSelector(
getAppSelection,
getNavigationState,
(selection, navigation) => {
return {
selection,
navigation
};
}
);
export const getSideNavState = createSelector(getAppSelection, getNavigationState, (selection, navigation) => {
return {
selection,
navigation
};
});
export const getRuleContext = createSelector(
getAppSelection,
@@ -118,7 +67,4 @@ export const getRuleContext = createSelector(
}
);
export const infoDrawerMetadataAspect = createSelector(
selectApp,
state => state.infoDrawerMetadataAspect
);
export const infoDrawerMetadataAspect = createSelector(selectApp, (state) => state.infoDrawerMetadataAspect);

View File

@@ -23,11 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
SelectionState,
ProfileState,
NavigationState
} from '@alfresco/adf-extensions';
import { SelectionState, ProfileState, NavigationState } from '@alfresco/adf-extensions';
import { RepositoryInfo } from '@alfresco/js-api';
export interface AppState {

View File

@@ -30,8 +30,6 @@ import { DialogEffects } from './effects/dialog.effects';
import { RouterEffects } from './effects/router.effects';
@NgModule({
imports: [
EffectsModule.forFeature([SnackbarEffects, DialogEffects, RouterEffects])
]
imports: [EffectsModule.forFeature([SnackbarEffects, DialogEffects, RouterEffects])]
})
export class SharedStoreModule {}

View File

@@ -28,18 +28,12 @@
import 'zone.js/dist/zone';
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
declare const require: any;
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.