[ADF-3456] DocumentList - context menu (#3694)

* refactor context menu

* prune log

* remove fdescribe

* remove undescore from private

* fix e2e action buttons

* fix trailing space

* remove fdescribe
This commit is contained in:
Cilibiu Bogdan
2018-08-14 09:59:04 +03:00
committed by Eugenio Romano
parent 62f0804205
commit 4404b724fa
16 changed files with 569 additions and 113 deletions

View File

@@ -21,7 +21,7 @@ import TestConfig = require('../test.config');
import path = require('path'); import path = require('path');
import fs = require('fs'); import fs = require('fs');
import remote = require('selenium-webdriver/remote'); import remote = require('selenium-webdriver/remote');
import { browser } from "protractor"; import { browser } from 'protractor';
export class UsersActions { export class UsersActions {

View File

@@ -319,11 +319,11 @@ var ContentList = function () {
this.rightClickOnRowNamed = function(rowName) { this.rightClickOnRowNamed = function(rowName) {
let row = this.getRowByRowName(rowName); let row = this.getRowByRowName(rowName);
browser.actions().click(row, protractor.Button.RIGHT).perform(); browser.actions().click(row, protractor.Button.RIGHT).perform();
Util.waitUntilElementIsVisible(element(by.css('div.context-menu'))); Util.waitUntilElementIsVisible(element(by.id('adf-context-menu-content')));
} }
this.checkContextActionIsVisible = function(actionName) { this.checkContextActionIsVisible = function(actionName) {
let actionButton = element(by.css(`div.context-menu button[data-automation-id="context-${actionName}"`)); let actionButton = element(by.css(`button[data-automation-id="context-${actionName}"`));
Util.waitUntilElementIsVisible(actionButton); Util.waitUntilElementIsVisible(actionButton);
Util.waitUntilElementIsClickable(actionButton); Util.waitUntilElementIsClickable(actionButton);
return actionButton; return actionButton;

View File

@@ -17,23 +17,23 @@
import { browser } from 'protractor'; import { browser } from 'protractor';
import LoginPage = require('./pages/adf/loginPage'); import LoginPage = require('../pages/adf/loginPage');
import ProcessServicesPage = require('./pages/adf/process_services/processServicesPage'); import ProcessServicesPage = require('../pages/adf/process_services/processServicesPage');
import TasksPage = require('./pages/adf/process_services/tasksPage'); import TasksPage = require('../pages/adf/process_services/tasksPage');
import CONSTANTS = require('./util/constants'); import CONSTANTS = require('../util/constants');
import Tenant = require('./models/APS/Tenant'); import Tenant = require('../models/APS/Tenant');
import Task = require('./models/APS/Task'); import Task = require('../models/APS/Task');
import TestConfig = require('./test.config'); import TestConfig = require('../test.config');
import resources = require('./util/resources'); import resources = require('../util/resources');
import AlfrescoApi = require('alfresco-js-api-node'); import AlfrescoApi = require('.alfresco-js-api-node');
import { UsersActions } from './actions/users.actions'; import { UsersActions } from '../actions/users.actions';
import fs = require('fs'); import fs = require('fs');
import path = require('path'); import path = require('path');
import Util = require('./util/util'); import Util = require('..ro/util/util');
describe('Start Task - Task App', () => { describe('Start Task - Task App', () => {

View File

@@ -15,20 +15,20 @@
* limitations under the License. * limitations under the License.
*/ */
import LoginPage = require('./pages/adf/loginPage'); import LoginPage = require('../pages/adf/loginPage');
import ProcessServicesPage = require('./pages/adf/process_services/processServicesPage'); import ProcessServicesPage = require('../pages/adf/process_services/processServicesPage');
import TasksPage = require('./pages/adf/process_services/tasksPage'); import TasksPage = require('../pages/adf/process_services/tasksPage');
import CONSTANTS = require('./util/constants'); import CONSTANTS = require('../util/constants');
import Tenant = require('./models/APS/Tenant'); import Tenant = require('../models/APS/Tenant');
import TestConfig = require('./test.config'); import TestConfig = require('../test.config');
import resources = require('./util/resources'); import resources = require('../util/resources');
import AlfrescoApi = require('alfresco-js-api-node'); import AlfrescoApi = require('alfresco-js-api-node');
import { UsersActions } from './actions/users.actions'; import { UsersActions } from '../actions/users.actions';
import { AppsActions } from './actions/APS/apps.actions'; import { AppsActions } from '../actions/APS/apps.actions';
import path = require('path'); import path = require('path');
import Util = require('./util/util'); import Util = require('./util/util');

View File

@@ -15,19 +15,19 @@
* limitations under the License. * limitations under the License.
*/ */
import TestConfig = require('./test.config'); import TestConfig = require('../test.config');
import resources = require('./util/resources'); import resources = require('../util/resources');
import LoginPage = require('./pages/adf/loginPage'); import LoginPage = require('../pages/adf/loginPage');
import NavigationBarPage = require('./pages/adf/navigationBarPage'); import NavigationBarPage = require('../pages/adf/navigationBarPage');
import ProcessServicesPage = require('./pages/adf/process_services/processServicesPage'); import ProcessServicesPage = require('../pages/adf/process_services/processServicesPage');
import TasksPage = require('./pages/adf/process_services/tasksPage'); import TasksPage = require('../pages/adf/process_services/tasksPage');
import TasksListPage = require('./pages/adf/process_services/tasksListPage'); import TasksListPage = require('../pages/adf/process_services/tasksListPage');
import TaskFiltersPage = require('./pages/adf/process_services/taskFiltersPage'); import TaskFiltersPage = require('../pages/adf/process_services/taskFiltersPage');
import TaskDetailsPage = require('./pages/adf/process_services/taskDetailsPage'); import TaskDetailsPage = require('../pages/adf/process_services/taskDetailsPage');
import AlfrescoApi = require('alfresco-js-api-node'); import AlfrescoApi = require('alfresco-js-api-node');
import { AppsActions } from './actions/APS/apps.actions'; import { AppsActions } from '../actions/APS/apps.actions';
import { UsersActions } from './actions/users.actions'; import { UsersActions } from '../actions/users.actions';
describe('Task Filters Test', () => { describe('Task Filters Test', () => {

View File

@@ -0,0 +1,46 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
state,
style,
animate,
transition,
query,
group,
sequence,
AnimationStateMetadata,
AnimationTransitionMetadata
} from '@angular/animations';
export const contextMenuAnimation: ( AnimationStateMetadata | AnimationTransitionMetadata)[] = [
state('void', style({
opacity: 0,
transform: 'scale(0.01, 0.01)'
})),
transition('void => *', sequence([
query('.mat-menu-content', style({ opacity: 0 })),
animate('100ms linear', style({ opacity: 1, transform: 'scale(1, 0.5)' })),
group([
query('.mat-menu-content', animate('400ms cubic-bezier(0.55, 0, 0.55, 0.2)',
style({ opacity: 1 })
)),
animate('300ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({ transform: 'scale(1, 1)' }))
])
])),
transition('* => void', animate('150ms 50ms linear', style({ opacity: 0 })))
];

View File

@@ -0,0 +1,101 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
Component, ViewEncapsulation, HostListener, AfterViewInit,
Optional, Inject, QueryList, ViewChildren
} from '@angular/core';
import { trigger } from '@angular/animations';
import { DOWN_ARROW, UP_ARROW } from '@angular/cdk/keycodes';
import { FocusKeyManager } from '@angular/cdk/a11y';
import { MatMenuItem } from '@angular/material';
import { ContextMenuOverlayRef } from './context-menu-overlay';
import { contextMenuAnimation } from './animations';
import { CONTEXT_MENU_DATA } from './context-menu.tokens';
@Component({
selector: 'adf-context-menu',
template: `
<div mat-menu class="mat-menu-panel" @panelAnimation>
<div id="adf-context-menu-content" class="mat-menu-content">
<ng-container *ngFor="let link of links">
<button *ngIf="link.model?.visible"
[attr.data-automation-id]="'context-'+((link.title || link.model?.title) | translate)"
mat-menu-item
[disabled]="link.model?.disabled"
(click)="onMenuItemClick($event, link)">
<mat-icon *ngIf="link.model?.icon">{{ link.model.icon }}</mat-icon>
<span>{{ (link.title || link.model?.title) | translate }}</span>
</button>
</ng-container>
</div>
</div>
`,
host: {
role: 'menu',
class: 'adf-context-menu'
},
encapsulation: ViewEncapsulation.None,
animations: [
trigger('panelAnimation', contextMenuAnimation)
]
})
export class ContextMenuListComponent implements AfterViewInit {
private keyManager: FocusKeyManager<MatMenuItem>;
@ViewChildren(MatMenuItem) items: QueryList<MatMenuItem>;
links: any[];
@HostListener('document:keydown.Escape', ['$event'])
handleKeydownEscape(event: KeyboardEvent) {
if (event) {
this.contextMenuOverlayRef.close();
}
}
@HostListener('document:keydown', ['$event'])
handleKeydownEvent(event: KeyboardEvent) {
if (event) {
const keyCode = event.keyCode;
if (keyCode === UP_ARROW || keyCode === DOWN_ARROW) {
this.keyManager.onKeydown(event);
}
}
}
constructor(
@Inject(ContextMenuOverlayRef) private contextMenuOverlayRef: ContextMenuOverlayRef,
@Optional() @Inject(CONTEXT_MENU_DATA) private data: any
) {
this.links = this.data;
}
onMenuItemClick(event: Event, menuItem: any) {
if (menuItem && menuItem.model && menuItem.model.disabled) {
event.preventDefault();
event.stopImmediatePropagation();
return;
}
menuItem.subject.next(menuItem);
this.contextMenuOverlayRef.close();
}
ngAfterViewInit() {
this.keyManager = new FocusKeyManager<MatMenuItem>(this.items);
this.keyManager.setFirstItemActive();
}
}

View File

@@ -0,0 +1,129 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Injectable, Injector, ElementRef, ComponentRef } from '@angular/core';
import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
import { PortalInjector, ComponentPortal } from '@angular/cdk/portal';
import { ContextMenuOverlayRef } from './context-menu-overlay';
import { ContextMenuOverlayConfig } from './interfaces';
import { CONTEXT_MENU_DATA } from './context-menu.tokens';
import { ContextMenuListComponent } from './context-menu-list.component';
const DEFAULT_CONFIG: ContextMenuOverlayConfig = {
panelClass: 'cdk-overlay-pane',
backdropClass: 'cdk-overlay-transparent-backdrop',
hasBackdrop: true
};
@Injectable()
export class ContextMenuOverlayService {
constructor( private injector: Injector, private overlay: Overlay) { }
open(config: ContextMenuOverlayConfig): ContextMenuOverlayRef {
const overlayConfig = { ...DEFAULT_CONFIG, ...config };
const overlay = this.createOverlay(overlayConfig);
const overlayRef = new ContextMenuOverlayRef(overlay);
this.attachDialogContainer(overlay, config, overlayRef);
overlay.backdropClick().subscribe(() => overlayRef.close());
// prevent native contextmenu on overlay element if config.hasBackdrop is true
if (overlayConfig.hasBackdrop) {
(<any> overlay)._backdropElement
.addEventListener('contextmenu', (event) => {
event.preventDefault();
(<any> overlay)._backdropClick.next(null);
}, true);
}
return overlayRef;
}
private createOverlay(config: ContextMenuOverlayConfig): OverlayRef {
const overlayConfig = this.getOverlayConfig(config);
return this.overlay.create(overlayConfig);
}
private attachDialogContainer(overlay: OverlayRef, config: ContextMenuOverlayConfig, contextMenuOverlayRef: ContextMenuOverlayRef) {
const injector = this.createInjector(config, contextMenuOverlayRef);
const containerPortal = new ComponentPortal(ContextMenuListComponent, null, injector);
const containerRef: ComponentRef<ContextMenuListComponent> = overlay.attach(containerPortal);
return containerRef.instance;
}
private createInjector(config: ContextMenuOverlayConfig, contextMenuOverlayRef: ContextMenuOverlayRef): PortalInjector {
const injectionTokens = new WeakMap();
injectionTokens.set(ContextMenuOverlayRef, contextMenuOverlayRef);
injectionTokens.set(CONTEXT_MENU_DATA, config.data);
return new PortalInjector(this.injector, injectionTokens);
}
private getOverlayConfig(config: ContextMenuOverlayConfig): OverlayConfig {
const { clientY, clientX } = config.source;
const fakeElement: any = {
getBoundingClientRect: (): ClientRect => ({
bottom: clientY,
height: 0,
left: clientX,
right: clientX,
top: clientY,
width: 0
})
};
const positionStrategy = this.overlay.position()
.connectedTo(
new ElementRef(fakeElement),
{ originX: 'start', originY: 'bottom' },
{ overlayX: 'start', overlayY: 'top' })
.withFallbackPosition(
{ originX: 'start', originY: 'top' },
{ overlayX: 'start', overlayY: 'bottom' })
.withFallbackPosition(
{ originX: 'end', originY: 'top' },
{ overlayX: 'start', overlayY: 'top' })
.withFallbackPosition(
{ originX: 'start', originY: 'top' },
{ overlayX: 'end', overlayY: 'top' })
.withFallbackPosition(
{ originX: 'end', originY: 'center' },
{ overlayX: 'start', overlayY: 'center' })
.withFallbackPosition(
{ originX: 'start', originY: 'center' },
{ overlayX: 'end', overlayY: 'center' }
);
const overlayConfig = new OverlayConfig({
hasBackdrop: config.hasBackdrop,
backdropClass: config.backdropClass,
panelClass: config.panelClass,
scrollStrategy: this.overlay.scrollStrategies.close(),
positionStrategy
});
return overlayConfig;
}
}

View File

@@ -0,0 +1,27 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { OverlayRef } from '@angular/cdk/overlay';
export class ContextMenuOverlayRef {
constructor(private overlayRef: OverlayRef) { }
close(): void {
this.overlayRef.dispose();
}
}

View File

@@ -1,72 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ContextMenuDirective } from './context-menu.directive';
import { ContextMenuService } from './context-menu.service';
describe('ContextMenuDirective', () => {
let contextMenuService;
let directive;
beforeEach(() => {
contextMenuService = new ContextMenuService();
directive = new ContextMenuDirective(contextMenuService);
directive.enabled = true;
});
it('should show menu via service', (done) => {
contextMenuService.show.subscribe(() => {
done();
});
directive.links = [{}];
directive.onShowContextMenu(null);
});
it('should prevent default behavior', () => {
let event = new MouseEvent('click');
spyOn(event, 'preventDefault').and.callThrough();
directive.onShowContextMenu(event);
expect(event.preventDefault).toHaveBeenCalled();
});
it('should forward event to service', () => {
let event = new MouseEvent('click');
contextMenuService.show.subscribe(e => {
expect(e.event).toBeDefined();
expect(e.event).toBe(event);
});
directive.onShowContextMenu(event);
});
it('should forward menu items to service', () => {
let links = [{}, {}];
directive.links = links;
contextMenuService.show.subscribe(e => {
expect(e.obj).toBeDefined();
expect(e.obj).toBe(links);
});
directive.onShowContextMenu(null);
});
});

View File

@@ -18,7 +18,7 @@
/* tslint:disable:no-input-rename */ /* tslint:disable:no-input-rename */
import { Directive, HostListener, Input } from '@angular/core'; import { Directive, HostListener, Input } from '@angular/core';
import { ContextMenuService } from './context-menu.service'; import { ContextMenuOverlayService } from './context-menu-overlay.service';
// @deprecated 2.3.0 context-menu tag removed // @deprecated 2.3.0 context-menu tag removed
@Directive({ @Directive({
@@ -33,8 +33,7 @@ export class ContextMenuDirective {
@Input('context-menu-enabled') @Input('context-menu-enabled')
enabled: boolean = false; enabled: boolean = false;
constructor(private _contextMenuService: ContextMenuService) { constructor(private contextMenuService: ContextMenuOverlayService) {}
}
@HostListener('contextmenu', ['$event']) @HostListener('contextmenu', ['$event'])
onShowContextMenu(event?: MouseEvent) { onShowContextMenu(event?: MouseEvent) {
@@ -44,9 +43,10 @@ export class ContextMenuDirective {
} }
if (this.links && this.links.length > 0) { if (this.links && this.links.length > 0) {
if (this._contextMenuService) { this.contextMenuService.open({
this._contextMenuService.show.next({event: event, obj: this.links}); source: event,
} data: this.links
});
} }
} }
} }

View File

@@ -22,6 +22,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { ContextMenuHolderComponent } from './context-menu-holder.component'; import { ContextMenuHolderComponent } from './context-menu-holder.component';
import { ContextMenuDirective } from './context-menu.directive'; import { ContextMenuDirective } from './context-menu.directive';
import { ContextMenuListComponent } from './context-menu-list.component';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -31,11 +32,15 @@ import { ContextMenuDirective } from './context-menu.directive';
], ],
declarations: [ declarations: [
ContextMenuHolderComponent, ContextMenuHolderComponent,
ContextMenuDirective ContextMenuDirective,
ContextMenuListComponent
], ],
exports: [ exports: [
ContextMenuHolderComponent, ContextMenuHolderComponent,
ContextMenuDirective ContextMenuDirective
],
entryComponents: [
ContextMenuListComponent
] ]
}) })
export class ContextMenuModule {} export class ContextMenuModule {}

View File

@@ -0,0 +1,174 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component } from '@angular/core';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { ContextMenuModule } from './context-menu.module';
import { CoreModule } from '../core.module';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
@Component({
selector: 'adf-test-component',
template: `
<div id="target" [context-menu]="actions" [context-menu-enabled]="true"></div>
`
})
class TestComponent {
actions;
}
describe('ContextMenuDirective', () => {
let fixture: ComponentFixture<TestComponent>;
const actions = [
{
model: {
visible: false,
title: 'Action 1'
},
subject: {
next: jasmine.createSpy('next')
}
},
{
model: {
visible: true,
disabled: true,
title: 'Action 2',
icon: null
},
subject: {
next: jasmine.createSpy('next')
}
},
{
model: {
visible: true,
disabled: false,
title: 'Action 3',
icon: 'action-icon-3'
},
subject: {
next: jasmine.createSpy('next')
}
},
{
model: {
visible: true,
disabled: false,
title: 'Action 4',
icon: 'action-icon-4'
},
subject: {
next: jasmine.createSpy('next')
}
}
];
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
CoreModule.forRoot(),
ContextMenuModule,
NoopAnimationsModule
],
declarations: [
TestComponent
]
});
fixture = TestBed.createComponent(TestComponent);
fixture.componentInstance.actions = actions;
fixture.detectChanges();
});
it('should not render contextmenu when action was not performed', () => {
const containerElement = fixture.debugElement.nativeElement.parentElement;
expect(containerElement.querySelector('.adf-context-menu button')).toBe(null);
});
describe('Events', () => {
let targetElement: HTMLElement;
let contextMenu: HTMLElement;
beforeEach(() => {
targetElement = fixture.debugElement.nativeElement.querySelector('#target');
targetElement.dispatchEvent(new CustomEvent('contextmenu'));
fixture.detectChanges();
contextMenu = document.querySelector('.adf-context-menu');
});
it('should show menu on mouse contextmenu event', () => {
expect(contextMenu).not.toBe(null);
});
it('should set DOM element reference on menu open event', () => {
expect(contextMenu.className).toContain('adf-context-menu');
});
it('should reset DOM element reference on Escape event', () => {
const event = new KeyboardEvent('keydown', {
bubbles : true, cancelable : true, key : 'Escape'
});
document.querySelector('.cdk-overlay-backdrop').dispatchEvent(event);
fixture.detectChanges();
expect(document.querySelector('.adf-context-menu')).toBe(null);
});
});
describe('Contextmenu list', () => {
let targetElement: HTMLElement;
let contextMenu: HTMLElement;
beforeEach(() => {
targetElement = fixture.debugElement.nativeElement.querySelector('#target');
targetElement.dispatchEvent(new CustomEvent('contextmenu'));
fixture.detectChanges();
contextMenu = document.querySelector('.adf-context-menu');
});
it('should not render item with visibility property set to false', () => {
expect(contextMenu.querySelectorAll('button').length).toBe(3);
});
it('should render item as disabled when `disabled` property is set to true', () => {
expect(contextMenu.querySelectorAll('button')[0].disabled).toBe(true);
});
it('should set first not disabled item as active', () => {
expect(document.activeElement.querySelector('mat-icon').innerHTML).toContain('action-icon-3');
});
it('should not allow action event when item is disabled', () => {
contextMenu.querySelectorAll('button')[0].click();
fixture.detectChanges();
expect(fixture.componentInstance.actions[1].subject.next).not.toHaveBeenCalled();
});
it('should perform action when item is not disabled', () => {
contextMenu.querySelectorAll('button')[1].click();
fixture.detectChanges();
expect(fixture.componentInstance.actions[2].subject.next).toHaveBeenCalled();
});
it('should not render item icon if not set', () => {
expect(contextMenu.querySelectorAll('button')[0].querySelector('mat-icon')).toBe(null);
});
});
});

View File

@@ -0,0 +1,20 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { InjectionToken } from '@angular/core';
export const CONTEXT_MENU_DATA = new InjectionToken<any>('CONTEXT_MENU_DATA');

View File

@@ -0,0 +1,24 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export interface ContextMenuOverlayConfig {
panelClass?: string;
hasBackdrop?: boolean;
backdropClass?: string;
source?: MouseEvent;
data?: any;
}

View File

@@ -85,6 +85,7 @@ import { startupServiceFactory } from './services/startup-service-factory';
import { SortingPickerModule } from './sorting-picker/sorting-picker.module'; import { SortingPickerModule } from './sorting-picker/sorting-picker.module';
import { AppConfigService } from './app-config/app-config.service'; import { AppConfigService } from './app-config/app-config.service';
import { ContextMenuService } from './context-menu/context-menu.service'; import { ContextMenuService } from './context-menu/context-menu.service';
import { ContextMenuOverlayService } from './context-menu/context-menu-overlay.service';
import { ActivitiContentService } from './form/services/activiti-alfresco.service'; import { ActivitiContentService } from './form/services/activiti-alfresco.service';
import { EcmModelService } from './form/services/ecm-model.service'; import { EcmModelService } from './form/services/ecm-model.service';
import { FormRenderingService } from './form/services/form-rendering.service'; import { FormRenderingService } from './form/services/form-rendering.service';
@@ -138,6 +139,7 @@ export function providers() {
DatePipe, DatePipe,
AppConfigService, AppConfigService,
ContextMenuService, ContextMenuService,
ContextMenuOverlayService,
ActivitiContentService, ActivitiContentService,
EcmModelService, EcmModelService,
FormRenderingService, FormRenderingService,