ag-grid-enterprise
Version:
ag-Grid Enterprise Features
244 lines (197 loc) • 8.22 kB
text/typescript
import {
PopupService,
Utils,
DragSourceType,
Component,
Autowired,
ColumnController,
Events,
Context,
EventService,
TouchListener,
DragAndDropService,
GridPanel,
GridOptionsWrapper,
DropTarget,
PostConstruct,
QuerySelector,
Column,
DragSource,
ColumnAggFuncChangeRequestEvent,
ColumnApi,
GridApi,
AgEvent,
TapEvent,
RefSelector,
_
} from "ag-grid-community";
import {AggFuncService} from "../../../../aggregation/aggFuncService";
import {VirtualList} from "../../../../rendering/virtualList";
export interface ColumnRemoveEvent extends AgEvent {}
export class DropZoneColumnComp extends Component {
public static EVENT_COLUMN_REMOVE = 'columnRemove';
private static TEMPLATE =
`<span class="ag-column-drop-cell">
<span class="ag-column-drag" ref="eDragHandle"></span>
<span class="ag-column-drop-cell-text"></span>
<span class="ag-column-drop-cell-button">✖</span>
</span>`;
dragAndDropService: DragAndDropService;
columnController: ColumnController;
context: Context;
popupService: PopupService;
aggFuncService: AggFuncService;
gridOptionsWrapper: GridOptionsWrapper;
eventService: EventService;
private columnApi: ColumnApi;
private gridApi: GridApi;
private eText: HTMLElement;
private btRemove: HTMLElement;
private eDragHandle: HTMLElement;
private column: Column;
private dragSourceDropTarget: DropTarget;
private ghost: boolean;
private displayName: string;
private valueColumn: boolean;
private popupShowing = false;
constructor(column: Column, dragSourceDropTarget: DropTarget, ghost: boolean, valueColumn: boolean) {
super();
this.valueColumn = valueColumn;
this.column = column;
this.dragSourceDropTarget = dragSourceDropTarget;
this.ghost = ghost;
}
public init(): void {
this.setTemplate(DropZoneColumnComp.TEMPLATE);
this.displayName = this.columnController.getDisplayNameForColumn(this.column, 'columnDrop');
this.setupComponents();
if (!this.ghost && !this.gridOptionsWrapper.isFunctionsReadOnly()) {
this.addDragSource();
}
}
private addDragSource(): void {
let dragSource: DragSource = {
type: DragSourceType.ToolPanel,
eElement: this.eDragHandle,
dragItemCallback: () => this.createDragItem(),
dragItemName: this.displayName,
dragSourceDropTarget: this.dragSourceDropTarget
};
this.dragAndDropService.addDragSource(dragSource, true);
this.addDestroyFunc( ()=> this.dragAndDropService.removeDragSource(dragSource) );
}
private createDragItem() {
let visibleState: { [key: string]: boolean } = {};
visibleState[this.column.getId()] = this.column.isVisible();
return {
columns: [this.column],
visibleState: visibleState
};
}
private setupComponents(): void {
this.setTextValue();
this.setupRemove();
if (this.ghost) {
Utils.addCssClass(this.getGui(), 'ag-column-drop-cell-ghost');
}
if (this.valueColumn && !this.gridOptionsWrapper.isFunctionsReadOnly()) {
this.addGuiEventListener('click', this.onShowAggFuncSelection.bind(this) );
}
}
private setupRemove(): void {
Utils.setVisible(this.btRemove, !this.gridOptionsWrapper.isFunctionsReadOnly());
this.addDestroyableEventListener(this.btRemove, 'click', (mouseEvent: MouseEvent)=> {
let agEvent: ColumnRemoveEvent = { type: DropZoneColumnComp.EVENT_COLUMN_REMOVE };
this.dispatchEvent(agEvent);
mouseEvent.stopPropagation();
});
let touchListener = new TouchListener(this.btRemove);
this.addDestroyableEventListener(touchListener, TouchListener.EVENT_TAP, (event: TapEvent)=> {
let agEvent: ColumnRemoveEvent = { type: DropZoneColumnComp.EVENT_COLUMN_REMOVE };
this.dispatchEvent(agEvent);
});
this.addDestroyFunc(touchListener.destroy.bind(touchListener));
}
private setTextValue(): void {
let displayValue: string;
if (this.valueColumn) {
let aggFunc = this.column.getAggFunc();
// if aggFunc is a string, we can use it, but if it's a function, then we swap with 'func'
let aggFuncString = (typeof aggFunc === 'string') ? <string> aggFunc : 'agg';
let localeTextFunc = this.gridOptionsWrapper.getLocaleTextFunc();
let aggFuncStringTranslated = localeTextFunc (aggFuncString, aggFuncString);
displayValue = `${aggFuncStringTranslated}(${this.displayName})`;
} else {
displayValue = this.displayName;
}
let displayValueSanitised = _.escape(displayValue);
this.eText.innerHTML = displayValueSanitised;
}
private onShowAggFuncSelection(): void {
if (this.popupShowing) { return; }
this.popupShowing = true;
let virtualList = new VirtualList();
let rows = this.aggFuncService.getFuncNames(this.column);
virtualList.setModel({
getRow: function(index: number) { return rows[index]; },
getRowCount: function() { return rows.length; }
});
this.context.wireBean(virtualList);
let ePopup = Utils.loadTemplate('<div class="ag-select-agg-func-popup"></div>');
ePopup.style.top = '0px';
ePopup.style.left = '0px';
ePopup.appendChild(virtualList.getGui());
// ePopup.style.height = this.gridOptionsWrapper.getAggFuncPopupHeight() + 'px';
ePopup.style.width = this.getGui().clientWidth + 'px';
let popupHiddenFunc = () => {
virtualList.destroy();
this.popupShowing = false;
};
let hidePopup = this.popupService.addAsModalPopup(
ePopup,
true,
popupHiddenFunc
);
virtualList.setComponentCreator(this.createAggSelect.bind(this, hidePopup));
this.popupService.positionPopupUnderComponent({
type: 'aggFuncSelect',
eventSource: this.getGui(),
ePopup: ePopup,
keepWithinBounds: true,
column: this.column
});
virtualList.refresh();
}
private createAggSelect(hidePopup: ()=>void, value: any): Component {
let itemSelected = ()=> {
hidePopup();
if (this.gridOptionsWrapper.isFunctionsPassive()) {
let event: ColumnAggFuncChangeRequestEvent = {
type: Events.EVENT_COLUMN_AGG_FUNC_CHANGE_REQUEST,
columns: [this.column],
aggFunc: value,
api: this.gridApi,
columnApi: this.columnApi
};
this.eventService.dispatchEvent(event);
} else {
this.columnController.setColumnAggFunc(this.column, value, "toolPanelDragAndDrop");
}
};
let localeTextFunc = this.gridOptionsWrapper.getLocaleTextFunc();
let aggFuncString = value.toString();
let aggFuncStringTranslated = localeTextFunc (aggFuncString, aggFuncString);
let comp = new AggItemComp(itemSelected, aggFuncStringTranslated);
return comp;
}
}
class AggItemComp extends Component {
private value: string;
constructor(itemSelected: ()=>void, value: string) {
super('<div class="ag-select-agg-func-item"/>');
this.getGui().innerText = value;
this.value = value;
this.addGuiEventListener('click', itemSelected);
}
}