ag-grid
Version:
Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
213 lines (169 loc) • 7.54 kB
text/typescript
import {Component} from "../widgets/component";
import {Autowired, PostConstruct} from "../context/context";
import {RowNode} from "../entities/rowNode";
import {DragAndDropService, DragItem, DragSource, DragSourceType} from "../dragAndDrop/dragAndDropService";
import {EventService} from "../eventService";
import {SortService} from "../rowNodes/sortService";
import {FilterManager} from "../filter/filterManager";
import {Events} from "../eventKeys";
import {SortController} from "../sortController";
import {_} from "../utils";
import {ColumnController} from "../columnController/columnController";
import {Beans} from "./beans";
import {BeanStub} from "../context/beanStub";
import {Column} from "../entities/column";
export class RowDragComp extends Component {
private readonly beans: Beans;
private readonly rowNode: RowNode;
private readonly column: Column;
private readonly cellValue: string;
constructor(rowNode: RowNode, column: Column, cellValue: string, beans: Beans) {
super(`<span class="ag-row-drag"></span>`);
this.rowNode = rowNode;
this.column = column;
this.cellValue = cellValue;
this.beans = beans;
}
private postConstruct(): void {
this.addDragSource();
this.checkCompatibility();
if (this.beans.gridOptionsWrapper.isRowDragManaged()) {
this.addFeature(this.beans.context,
new ManagedVisibilityStrategy(this, this.beans, this.rowNode, this.column) );
} else {
this.addFeature(this.beans.context,
new NonManagedVisibilityStrategy(this, this.beans, this.rowNode, this.column) );
}
}
// returns true if all compatibility items work out
private checkCompatibility(): void {
let managed = this.beans.gridOptionsWrapper.isRowDragManaged();
let treeData = this.beans.gridOptionsWrapper.isTreeData();
if (treeData && managed) {
_.doOnce( ()=>
console.warn('ag-Grid: If using row drag with tree data, you cannot have rowDragManaged=true'),
'RowDragComp.managedAndTreeData'
);
}
}
private addDragSource(): void {
let dragItem: DragItem = {
rowNode: this.rowNode
};
let dragSource: DragSource = {
type: DragSourceType.RowDrag,
eElement: this.getGui(),
dragItemName: this.cellValue,
dragItemCallback: () => dragItem,
dragStartPixels: 0
};
this.beans.dragAndDropService.addDragSource(dragSource, true);
this.addDestroyFunc( ()=> this.beans.dragAndDropService.removeDragSource(dragSource) );
}
}
// when non managed, the visibility depends on suppressRowDrag property only
class NonManagedVisibilityStrategy extends BeanStub {
private readonly parent: RowDragComp;
private readonly beans: Beans;
private readonly column: Column;
private readonly rowNode: RowNode;
constructor(parent: RowDragComp, beans: Beans, rowNode: RowNode, column: Column) {
super();
this.parent = parent;
this.beans = beans;
this.column = column;
this.rowNode = rowNode;
}
private postConstruct(): void {
this.addDestroyableEventListener(this.beans.gridOptionsWrapper, 'suppressRowDrag', this.onSuppressRowDrag.bind(this));
// in case data changes, then we need to update visibility of drag item
this.addDestroyableEventListener(this.rowNode, RowNode.EVENT_DATA_CHANGED, this.workOutVisibility.bind(this));
this.addDestroyableEventListener(this.rowNode, RowNode.EVENT_CELL_CHANGED, this.workOutVisibility.bind(this));
this.workOutVisibility();
}
private onSuppressRowDrag(): void {
this.workOutVisibility();
}
private workOutVisibility(): void {
// only show the drag if both sort and filter are not present
let suppressRowDrag = this.beans.gridOptionsWrapper.isSuppressRowDrag();
if (suppressRowDrag) {
this.parent.setVisible(false);
} else {
let visible = this.column.isRowDrag(this.rowNode);
this.parent.setVisible(visible);
}
}
}
// when managed, the visibility depends on sort, filter and row group, as well as suppressRowDrag property
class ManagedVisibilityStrategy extends BeanStub {
private readonly parent: RowDragComp;
private readonly column: Column;
private readonly rowNode: RowNode;
private readonly beans: Beans;
private sortActive: boolean;
private filterActive: boolean;
private rowGroupActive: boolean;
constructor(parent: RowDragComp, beans: Beans, rowNode: RowNode, column: Column) {
super();
this.parent = parent;
this.beans = beans;
this.column = column;
this.rowNode = rowNode;
}
private postConstruct(): void {
// we do not show the component if sort, filter or grouping is active
this.addDestroyableEventListener(this.beans.eventService, Events.EVENT_SORT_CHANGED, this.onSortChanged.bind(this));
this.addDestroyableEventListener(this.beans.eventService, Events.EVENT_FILTER_CHANGED, this.onFilterChanged.bind(this));
this.addDestroyableEventListener(this.beans.eventService, Events.EVENT_COLUMN_ROW_GROUP_CHANGED, this.onRowGroupChanged.bind(this));
// in case data changes, then we need to update visibility of drag item
this.addDestroyableEventListener(this.rowNode, RowNode.EVENT_DATA_CHANGED, this.workOutVisibility.bind(this));
this.addDestroyableEventListener(this.rowNode, RowNode.EVENT_CELL_CHANGED, this.workOutVisibility.bind(this));
this.addDestroyableEventListener(this.beans.gridOptionsWrapper, 'suppressRowDrag', this.onSuppressRowDrag.bind(this));
this.updateSortActive();
this.updateFilterActive();
this.updateRowGroupActive();
this.workOutVisibility();
}
private updateRowGroupActive(): void {
let rowGroups = this.beans.columnController.getRowGroupColumns();
this.rowGroupActive = !_.missingOrEmpty(rowGroups);
}
private onRowGroupChanged(): void {
this.updateRowGroupActive();
this.workOutVisibility();
}
private updateSortActive(): void {
let sortModel = this.beans.sortController.getSortModel();
this.sortActive = !_.missingOrEmpty(sortModel);
}
private onSortChanged(): void {
this.updateSortActive();
this.workOutVisibility();
}
private updateFilterActive(): void {
this.filterActive = this.beans.filterManager.isAnyFilterPresent();
}
private onFilterChanged(): void {
this.updateFilterActive();
this.workOutVisibility();
}
private onSuppressRowDrag(): void {
this.workOutVisibility();
}
private workOutVisibility(): void {
// only show the drag if both sort and filter are not present
let sortOrFilterOrGroupActive = this.sortActive || this.filterActive || this.rowGroupActive;
let suppressRowDrag = this.beans.gridOptionsWrapper.isSuppressRowDrag();
let alwaysHide = sortOrFilterOrGroupActive || suppressRowDrag;
if (alwaysHide) {
this.parent.setVisible(false);
} else {
let visible = this.column.isRowDrag(this.rowNode);
this.parent.setVisible(visible);
}
}
}