import { Injectable, Inject, Directive, TemplateRef, EventEmitter, ElementRef, NgZone, HostBinding, Output, Input, Renderer2, HostListener, KeyValueDiffers, ContentChildren, Component, ChangeDetectionStrategy, ContentChild, ChangeDetectorRef, ViewChild, ViewEncapsulation, SkipSelf, Optional, ViewContainerRef, NgModule } from '@angular/core';
import { DOCUMENT, CommonModule } from '@angular/common';
import { Subject, fromEvent, BehaviorSubject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { __decorate, __metadata } from 'tslib';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Gets the width of the scrollbar. Nesc for windows
* http://stackoverflow.com/a/13382873/888165
*/
class ScrollbarHelper {
/**
* @param {?} document
*/
constructor(document) {
this.document = document;
this.width = this.getWidth();
}
/**
* @return {?}
*/
getWidth() {
/** @type {?} */
const outer = this.document.createElement('div');
outer.style.visibility = 'hidden';
outer.style.width = '100px';
outer.style.msOverflowStyle = 'scrollbar';
this.document.body.appendChild(outer);
/** @type {?} */
const widthNoScroll = outer.offsetWidth;
outer.style.overflow = 'scroll';
/** @type {?} */
const inner = this.document.createElement('div');
inner.style.width = '100%';
outer.appendChild(inner);
/** @type {?} */
const widthWithScroll = inner.offsetWidth;
outer.parentNode.removeChild(outer);
return widthNoScroll - widthWithScroll;
}
}
ScrollbarHelper.decorators = [
{ type: Injectable }
];
/** @nocollapse */
ScrollbarHelper.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
];
if (false) {
/** @type {?} */
ScrollbarHelper.prototype.width;
/**
* @type {?}
* @private
*/
ScrollbarHelper.prototype.document;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Gets the width of the scrollbar. Nesc for windows
* http://stackoverflow.com/a/13382873/888165
*/
class DimensionsHelper {
/**
* @param {?} element
* @return {?}
*/
getDimensions(element) {
return element.getBoundingClientRect();
}
}
DimensionsHelper.decorators = [
{ type: Injectable }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* service to make DatatableComponent aware of changes to
* input bindings of DataTableColumnDirective
*/
class ColumnChangesService {
constructor() {
this.columnInputChanges = new Subject();
}
/**
* @return {?}
*/
get columnInputChanges$() {
return this.columnInputChanges.asObservable();
}
/**
* @return {?}
*/
onInputChange() {
this.columnInputChanges.next();
}
}
ColumnChangesService.decorators = [
{ type: Injectable }
];
if (false) {
/**
* @type {?}
* @private
*/
ColumnChangesService.prototype.columnInputChanges;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableFooterTemplateDirective {
/**
* @param {?} template
*/
constructor(template) {
this.template = template;
}
}
DataTableFooterTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ngx-datatable-footer-template]' },] }
];
/** @nocollapse */
DataTableFooterTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
if (false) {
/** @type {?} */
DataTableFooterTemplateDirective.prototype.template;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Visibility Observer Directive
*
* Usage:
*
*
*
*
*/
class VisibilityDirective {
/**
* @param {?} element
* @param {?} zone
*/
constructor(element, zone) {
this.element = element;
this.zone = zone;
this.isVisible = false;
this.visible = new EventEmitter();
}
/**
* @return {?}
*/
ngOnInit() {
this.runCheck();
}
/**
* @return {?}
*/
ngOnDestroy() {
clearTimeout(this.timeout);
}
/**
* @return {?}
*/
onVisibilityChange() {
// trigger zone recalc for columns
this.zone.run((/**
* @return {?}
*/
() => {
this.isVisible = true;
this.visible.emit(true);
}));
}
/**
* @return {?}
*/
runCheck() {
/** @type {?} */
const check = (/**
* @return {?}
*/
() => {
// https://davidwalsh.name/offsetheight-visibility
const { offsetHeight, offsetWidth } = this.element.nativeElement;
if (offsetHeight && offsetWidth) {
clearTimeout(this.timeout);
this.onVisibilityChange();
}
else {
clearTimeout(this.timeout);
this.zone.runOutsideAngular((/**
* @return {?}
*/
() => {
this.timeout = setTimeout((/**
* @return {?}
*/
() => check()), 50);
}));
}
});
this.timeout = setTimeout((/**
* @return {?}
*/
() => check()));
}
}
VisibilityDirective.decorators = [
{ type: Directive, args: [{ selector: '[visibilityObserver]' },] }
];
/** @nocollapse */
VisibilityDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: NgZone }
];
VisibilityDirective.propDecorators = {
isVisible: [{ type: HostBinding, args: ['class.visible',] }],
visible: [{ type: Output }]
};
if (false) {
/** @type {?} */
VisibilityDirective.prototype.isVisible;
/** @type {?} */
VisibilityDirective.prototype.visible;
/** @type {?} */
VisibilityDirective.prototype.timeout;
/**
* @type {?}
* @private
*/
VisibilityDirective.prototype.element;
/**
* @type {?}
* @private
*/
VisibilityDirective.prototype.zone;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Draggable Directive for Angular2
*
* Inspiration:
* https://github.com/AngularClass/angular2-examples/blob/master/rx-draggable/directives/draggable.ts
* http://stackoverflow.com/questions/35662530/how-to-implement-drag-and-drop-in-angular2
*
*/
class DraggableDirective {
/**
* @param {?} element
*/
constructor(element) {
this.dragX = true;
this.dragY = true;
this.dragStart = new EventEmitter();
this.dragging = new EventEmitter();
this.dragEnd = new EventEmitter();
this.isDragging = false;
this.element = element.nativeElement;
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
if (changes['dragEventTarget'] && changes['dragEventTarget'].currentValue && this.dragModel.dragging) {
this.onMousedown(changes['dragEventTarget'].currentValue);
}
}
/**
* @return {?}
*/
ngOnDestroy() {
this._destroySubscription();
}
/**
* @param {?} event
* @return {?}
*/
onMouseup(event) {
if (!this.isDragging)
return;
this.isDragging = false;
this.element.classList.remove('dragging');
if (this.subscription) {
this._destroySubscription();
this.dragEnd.emit({
event,
element: this.element,
model: this.dragModel
});
}
}
/**
* @param {?} event
* @return {?}
*/
onMousedown(event) {
// we only want to drag the inner header text
/** @type {?} */
const isDragElm = ((/** @type {?} */ (event.target))).classList.contains('draggable');
if (isDragElm && (this.dragX || this.dragY)) {
event.preventDefault();
this.isDragging = true;
/** @type {?} */
const mouseDownPos = { x: event.clientX, y: event.clientY };
/** @type {?} */
const mouseup = fromEvent(document, 'mouseup');
this.subscription = mouseup.subscribe((/**
* @param {?} ev
* @return {?}
*/
(ev) => this.onMouseup(ev)));
/** @type {?} */
const mouseMoveSub = fromEvent(document, 'mousemove')
.pipe(takeUntil(mouseup))
.subscribe((/**
* @param {?} ev
* @return {?}
*/
(ev) => this.move(ev, mouseDownPos)));
this.subscription.add(mouseMoveSub);
this.dragStart.emit({
event,
element: this.element,
model: this.dragModel
});
}
}
/**
* @param {?} event
* @param {?} mouseDownPos
* @return {?}
*/
move(event, mouseDownPos) {
if (!this.isDragging)
return;
/** @type {?} */
const x = event.clientX - mouseDownPos.x;
/** @type {?} */
const y = event.clientY - mouseDownPos.y;
if (this.dragX)
this.element.style.left = `${x}px`;
if (this.dragY)
this.element.style.top = `${y}px`;
this.element.classList.add('dragging');
this.dragging.emit({
event,
element: this.element,
model: this.dragModel
});
}
/**
* @private
* @return {?}
*/
_destroySubscription() {
if (this.subscription) {
this.subscription.unsubscribe();
this.subscription = undefined;
}
}
}
DraggableDirective.decorators = [
{ type: Directive, args: [{ selector: '[draggable]' },] }
];
/** @nocollapse */
DraggableDirective.ctorParameters = () => [
{ type: ElementRef }
];
DraggableDirective.propDecorators = {
dragEventTarget: [{ type: Input }],
dragModel: [{ type: Input }],
dragX: [{ type: Input }],
dragY: [{ type: Input }],
dragStart: [{ type: Output }],
dragging: [{ type: Output }],
dragEnd: [{ type: Output }]
};
if (false) {
/** @type {?} */
DraggableDirective.prototype.dragEventTarget;
/** @type {?} */
DraggableDirective.prototype.dragModel;
/** @type {?} */
DraggableDirective.prototype.dragX;
/** @type {?} */
DraggableDirective.prototype.dragY;
/** @type {?} */
DraggableDirective.prototype.dragStart;
/** @type {?} */
DraggableDirective.prototype.dragging;
/** @type {?} */
DraggableDirective.prototype.dragEnd;
/** @type {?} */
DraggableDirective.prototype.element;
/** @type {?} */
DraggableDirective.prototype.isDragging;
/** @type {?} */
DraggableDirective.prototype.subscription;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/* tslint:disable */
/** @type {?} */
const MouseEvent = (/** @type {?} */ ((((/** @type {?} */ ((typeof window !== 'undefined' && window)))) || ((/** @type {?} */ (global))))
.MouseEvent));
/** @type {?} */
const KeyboardEvent = (/** @type {?} */ ((((/** @type {?} */ ((typeof window !== 'undefined' && window)))) || ((/** @type {?} */ (global))))
.KeyboardEvent));
/** @type {?} */
const Event = (/** @type {?} */ ((((/** @type {?} */ ((typeof window !== 'undefined' && window)))) || ((/** @type {?} */ (global)))).Event));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ResizeableDirective {
/**
* @param {?} element
* @param {?} renderer
*/
constructor(element, renderer) {
this.renderer = renderer;
this.resizeEnabled = true;
this.resize = new EventEmitter();
this.resizing = false;
this.element = element.nativeElement;
}
/**
* @return {?}
*/
ngAfterViewInit() {
/** @type {?} */
const renderer2 = this.renderer;
this.resizeHandle = renderer2.createElement('span');
if (this.resizeEnabled) {
renderer2.addClass(this.resizeHandle, 'resize-handle');
}
else {
renderer2.addClass(this.resizeHandle, 'resize-handle--not-resizable');
}
renderer2.appendChild(this.element, this.resizeHandle);
}
/**
* @return {?}
*/
ngOnDestroy() {
this._destroySubscription();
if (this.renderer.destroyNode) {
this.renderer.destroyNode(this.resizeHandle);
}
else {
this.renderer.removeChild(this.renderer.parentNode(this.resizeHandle), this.resizeHandle);
}
}
/**
* @return {?}
*/
onMouseup() {
this.resizing = false;
if (this.subscription && !this.subscription.closed) {
this._destroySubscription();
this.resize.emit(this.element.clientWidth);
}
}
/**
* @param {?} event
* @return {?}
*/
onMousedown(event) {
/** @type {?} */
const isHandle = ((/** @type {?} */ (event.target))).classList.contains('resize-handle');
/** @type {?} */
const initialWidth = this.element.clientWidth;
/** @type {?} */
const mouseDownScreenX = event.screenX;
if (isHandle) {
event.stopPropagation();
this.resizing = true;
/** @type {?} */
const mouseup = fromEvent(document, 'mouseup');
this.subscription = mouseup.subscribe((/**
* @param {?} ev
* @return {?}
*/
(ev) => this.onMouseup()));
/** @type {?} */
const mouseMoveSub = fromEvent(document, 'mousemove')
.pipe(takeUntil(mouseup))
.subscribe((/**
* @param {?} e
* @return {?}
*/
(e) => this.move(e, initialWidth, mouseDownScreenX)));
this.subscription.add(mouseMoveSub);
}
}
/**
* @param {?} event
* @param {?} initialWidth
* @param {?} mouseDownScreenX
* @return {?}
*/
move(event, initialWidth, mouseDownScreenX) {
/** @type {?} */
const movementX = event.screenX - mouseDownScreenX;
/** @type {?} */
const newWidth = initialWidth + movementX;
/** @type {?} */
const overMinWidth = !this.minWidth || newWidth >= this.minWidth;
/** @type {?} */
const underMaxWidth = !this.maxWidth || newWidth <= this.maxWidth;
if (overMinWidth && underMaxWidth) {
this.element.style.width = `${newWidth}px`;
}
}
/**
* @private
* @return {?}
*/
_destroySubscription() {
if (this.subscription) {
this.subscription.unsubscribe();
this.subscription = undefined;
}
}
}
ResizeableDirective.decorators = [
{ type: Directive, args: [{
selector: '[resizeable]',
host: {
'[class.resizeable]': 'resizeEnabled'
}
},] }
];
/** @nocollapse */
ResizeableDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: Renderer2 }
];
ResizeableDirective.propDecorators = {
resizeEnabled: [{ type: Input }],
minWidth: [{ type: Input }],
maxWidth: [{ type: Input }],
resize: [{ type: Output }],
onMousedown: [{ type: HostListener, args: ['mousedown', ['$event'],] }]
};
if (false) {
/** @type {?} */
ResizeableDirective.prototype.resizeEnabled;
/** @type {?} */
ResizeableDirective.prototype.minWidth;
/** @type {?} */
ResizeableDirective.prototype.maxWidth;
/** @type {?} */
ResizeableDirective.prototype.resize;
/** @type {?} */
ResizeableDirective.prototype.element;
/** @type {?} */
ResizeableDirective.prototype.subscription;
/** @type {?} */
ResizeableDirective.prototype.resizing;
/**
* @type {?}
* @private
*/
ResizeableDirective.prototype.resizeHandle;
/**
* @type {?}
* @private
*/
ResizeableDirective.prototype.renderer;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class OrderableDirective {
/**
* @param {?} differs
* @param {?} document
*/
constructor(differs, document) {
this.document = document;
this.reorder = new EventEmitter();
this.targetChanged = new EventEmitter();
this.differ = differs.find({}).create();
}
/**
* @return {?}
*/
ngAfterContentInit() {
// HACK: Investigate Better Way
this.updateSubscriptions();
this.draggables.changes.subscribe(this.updateSubscriptions.bind(this));
}
/**
* @return {?}
*/
ngOnDestroy() {
this.draggables.forEach((/**
* @param {?} d
* @return {?}
*/
d => {
d.dragStart.unsubscribe();
d.dragging.unsubscribe();
d.dragEnd.unsubscribe();
}));
}
/**
* @return {?}
*/
updateSubscriptions() {
/** @type {?} */
const diffs = this.differ.diff(this.createMapDiffs());
if (diffs) {
/** @type {?} */
const subscribe = (/**
* @param {?} __0
* @return {?}
*/
({ currentValue, previousValue }) => {
unsubscribe({ previousValue });
if (currentValue) {
currentValue.dragStart.subscribe(this.onDragStart.bind(this));
currentValue.dragging.subscribe(this.onDragging.bind(this));
currentValue.dragEnd.subscribe(this.onDragEnd.bind(this));
}
});
/** @type {?} */
const unsubscribe = (/**
* @param {?} __0
* @return {?}
*/
({ previousValue }) => {
if (previousValue) {
previousValue.dragStart.unsubscribe();
previousValue.dragging.unsubscribe();
previousValue.dragEnd.unsubscribe();
}
});
diffs.forEachAddedItem(subscribe);
// diffs.forEachChangedItem(subscribe.bind(this));
diffs.forEachRemovedItem(unsubscribe);
}
}
/**
* @return {?}
*/
onDragStart() {
this.positions = {};
/** @type {?} */
let i = 0;
for (const dragger of this.draggables.toArray()) {
/** @type {?} */
const elm = dragger.element;
/** @type {?} */
const left = parseInt(elm.offsetLeft.toString(), 0);
this.positions[dragger.dragModel.prop] = {
left,
right: left + parseInt(elm.offsetWidth.toString(), 0),
index: i++,
element: elm
};
}
}
/**
* @param {?} __0
* @return {?}
*/
onDragging({ element, model, event }) {
/** @type {?} */
const prevPos = this.positions[model.prop];
/** @type {?} */
const target = this.isTarget(model, event);
if (target) {
if (this.lastDraggingIndex !== target.i) {
this.targetChanged.emit({
prevIndex: this.lastDraggingIndex,
newIndex: target.i,
initialIndex: prevPos.index
});
this.lastDraggingIndex = target.i;
}
}
else if (this.lastDraggingIndex !== prevPos.index) {
this.targetChanged.emit({
prevIndex: this.lastDraggingIndex,
initialIndex: prevPos.index
});
this.lastDraggingIndex = prevPos.index;
}
}
/**
* @param {?} __0
* @return {?}
*/
onDragEnd({ element, model, event }) {
/** @type {?} */
const prevPos = this.positions[model.prop];
/** @type {?} */
const target = this.isTarget(model, event);
if (target) {
this.reorder.emit({
prevIndex: prevPos.index,
newIndex: target.i,
model
});
}
this.lastDraggingIndex = undefined;
element.style.left = 'auto';
}
/**
* @param {?} model
* @param {?} event
* @return {?}
*/
isTarget(model, event) {
/** @type {?} */
let i = 0;
/** @type {?} */
const x = event.x || event.clientX;
/** @type {?} */
const y = event.y || event.clientY;
/** @type {?} */
const targets = this.document.elementsFromPoint(x, y);
for (const prop in this.positions) {
// current column position which throws event.
/** @type {?} */
const pos = this.positions[prop];
// since we drag the inner span, we need to find it in the elements at the cursor
if (model.prop !== prop && targets.find((/**
* @param {?} el
* @return {?}
*/
(el) => el === pos.element))) {
return {
pos,
i
};
}
i++;
}
}
/**
* @private
* @return {?}
*/
createMapDiffs() {
return this.draggables.toArray().reduce((/**
* @param {?} acc
* @param {?} curr
* @return {?}
*/
(acc, curr) => {
acc[curr.dragModel.$$id] = curr;
return acc;
}), {});
}
}
OrderableDirective.decorators = [
{ type: Directive, args: [{ selector: '[orderable]' },] }
];
/** @nocollapse */
OrderableDirective.ctorParameters = () => [
{ type: KeyValueDiffers },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
];
OrderableDirective.propDecorators = {
reorder: [{ type: Output }],
targetChanged: [{ type: Output }],
draggables: [{ type: ContentChildren, args: [DraggableDirective, { descendants: true },] }]
};
if (false) {
/** @type {?} */
OrderableDirective.prototype.reorder;
/** @type {?} */
OrderableDirective.prototype.targetChanged;
/** @type {?} */
OrderableDirective.prototype.draggables;
/** @type {?} */
OrderableDirective.prototype.positions;
/** @type {?} */
OrderableDirective.prototype.differ;
/** @type {?} */
OrderableDirective.prototype.lastDraggingIndex;
/**
* @type {?}
* @private
*/
OrderableDirective.prototype.document;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class LongPressDirective {
constructor() {
this.pressEnabled = true;
this.duration = 500;
this.longPressStart = new EventEmitter();
this.longPressing = new EventEmitter();
this.longPressEnd = new EventEmitter();
this.mouseX = 0;
this.mouseY = 0;
}
/**
* @return {?}
*/
get press() {
return this.pressing;
}
/**
* @return {?}
*/
get isLongPress() {
return this.isLongPressing;
}
/**
* @param {?} event
* @return {?}
*/
onMouseDown(event) {
// don't do right/middle clicks
if (event.which !== 1 || !this.pressEnabled)
return;
// don't start drag if its on resize handle
/** @type {?} */
const target = (/** @type {?} */ (event.target));
if (target.classList.contains('resize-handle'))
return;
this.mouseX = event.clientX;
this.mouseY = event.clientY;
this.pressing = true;
this.isLongPressing = false;
/** @type {?} */
const mouseup = fromEvent(document, 'mouseup');
this.subscription = mouseup.subscribe((/**
* @param {?} ev
* @return {?}
*/
(ev) => this.onMouseup()));
this.timeout = setTimeout((/**
* @return {?}
*/
() => {
this.isLongPressing = true;
this.longPressStart.emit({
event,
model: this.pressModel
});
this.subscription.add(fromEvent(document, 'mousemove')
.pipe(takeUntil(mouseup))
.subscribe((/**
* @param {?} mouseEvent
* @return {?}
*/
(mouseEvent) => this.onMouseMove(mouseEvent))));
this.loop(event);
}), this.duration);
this.loop(event);
}
/**
* @param {?} event
* @return {?}
*/
onMouseMove(event) {
if (this.pressing && !this.isLongPressing) {
/** @type {?} */
const xThres = Math.abs(event.clientX - this.mouseX) > 10;
/** @type {?} */
const yThres = Math.abs(event.clientY - this.mouseY) > 10;
if (xThres || yThres) {
this.endPress();
}
}
}
/**
* @param {?} event
* @return {?}
*/
loop(event) {
if (this.isLongPressing) {
this.timeout = setTimeout((/**
* @return {?}
*/
() => {
this.longPressing.emit({
event,
model: this.pressModel
});
this.loop(event);
}), 50);
}
}
/**
* @return {?}
*/
endPress() {
clearTimeout(this.timeout);
this.isLongPressing = false;
this.pressing = false;
this._destroySubscription();
this.longPressEnd.emit({
model: this.pressModel
});
}
/**
* @return {?}
*/
onMouseup() {
this.endPress();
}
/**
* @return {?}
*/
ngOnDestroy() {
this._destroySubscription();
}
/**
* @private
* @return {?}
*/
_destroySubscription() {
if (this.subscription) {
this.subscription.unsubscribe();
this.subscription = undefined;
}
}
}
LongPressDirective.decorators = [
{ type: Directive, args: [{ selector: '[long-press]' },] }
];
LongPressDirective.propDecorators = {
pressEnabled: [{ type: Input }],
pressModel: [{ type: Input }],
duration: [{ type: Input }],
longPressStart: [{ type: Output }],
longPressing: [{ type: Output }],
longPressEnd: [{ type: Output }],
press: [{ type: HostBinding, args: ['class.press',] }],
isLongPress: [{ type: HostBinding, args: ['class.longpress',] }],
onMouseDown: [{ type: HostListener, args: ['mousedown', ['$event'],] }]
};
if (false) {
/** @type {?} */
LongPressDirective.prototype.pressEnabled;
/** @type {?} */
LongPressDirective.prototype.pressModel;
/** @type {?} */
LongPressDirective.prototype.duration;
/** @type {?} */
LongPressDirective.prototype.longPressStart;
/** @type {?} */
LongPressDirective.prototype.longPressing;
/** @type {?} */
LongPressDirective.prototype.longPressEnd;
/** @type {?} */
LongPressDirective.prototype.pressing;
/** @type {?} */
LongPressDirective.prototype.isLongPressing;
/** @type {?} */
LongPressDirective.prototype.timeout;
/** @type {?} */
LongPressDirective.prototype.mouseX;
/** @type {?} */
LongPressDirective.prototype.mouseY;
/** @type {?} */
LongPressDirective.prototype.subscription;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ScrollerComponent {
/**
* @param {?} ngZone
* @param {?} element
* @param {?} renderer
*/
constructor(ngZone, element, renderer) {
this.ngZone = ngZone;
this.renderer = renderer;
this.scrollbarV = false;
this.scrollbarH = false;
this.scroll = new EventEmitter();
this.scrollYPos = 0;
this.scrollXPos = 0;
this.prevScrollYPos = 0;
this.prevScrollXPos = 0;
this._scrollEventListener = null;
this.element = element.nativeElement;
}
/**
* @return {?}
*/
ngOnInit() {
// manual bind so we don't always listen
if (this.scrollbarV || this.scrollbarH) {
/** @type {?} */
const renderer = this.renderer;
this.parentElement = renderer.parentNode(renderer.parentNode(this.element));
this._scrollEventListener = this.onScrolled.bind(this);
this.parentElement.addEventListener('scroll', this._scrollEventListener);
}
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this._scrollEventListener) {
this.parentElement.removeEventListener('scroll', this._scrollEventListener);
this._scrollEventListener = null;
}
}
/**
* @param {?} offsetY
* @return {?}
*/
setOffset(offsetY) {
if (this.parentElement) {
this.parentElement.scrollTop = offsetY;
}
}
/**
* @param {?} event
* @return {?}
*/
onScrolled(event) {
/** @type {?} */
const dom = (/** @type {?} */ (event.currentTarget));
requestAnimationFrame((/**
* @return {?}
*/
() => {
this.scrollYPos = dom.scrollTop;
this.scrollXPos = dom.scrollLeft;
this.updateOffset();
}));
}
/**
* @return {?}
*/
updateOffset() {
/** @type {?} */
let direction;
if (this.scrollYPos < this.prevScrollYPos) {
direction = 'down';
}
else if (this.scrollYPos > this.prevScrollYPos) {
direction = 'up';
}
this.scroll.emit({
direction,
scrollYPos: this.scrollYPos,
scrollXPos: this.scrollXPos
});
this.prevScrollYPos = this.scrollYPos;
this.prevScrollXPos = this.scrollXPos;
}
}
ScrollerComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-scroller',
template: `
`,
host: {
class: 'datatable-scroll'
},
changeDetection: ChangeDetectionStrategy.OnPush
}] }
];
/** @nocollapse */
ScrollerComponent.ctorParameters = () => [
{ type: NgZone },
{ type: ElementRef },
{ type: Renderer2 }
];
ScrollerComponent.propDecorators = {
scrollbarV: [{ type: Input }],
scrollbarH: [{ type: Input }],
scrollHeight: [{ type: HostBinding, args: ['style.height.px',] }, { type: Input }],
scrollWidth: [{ type: HostBinding, args: ['style.width.px',] }, { type: Input }],
scroll: [{ type: Output }]
};
if (false) {
/** @type {?} */
ScrollerComponent.prototype.scrollbarV;
/** @type {?} */
ScrollerComponent.prototype.scrollbarH;
/** @type {?} */
ScrollerComponent.prototype.scrollHeight;
/** @type {?} */
ScrollerComponent.prototype.scrollWidth;
/** @type {?} */
ScrollerComponent.prototype.scroll;
/** @type {?} */
ScrollerComponent.prototype.scrollYPos;
/** @type {?} */
ScrollerComponent.prototype.scrollXPos;
/** @type {?} */
ScrollerComponent.prototype.prevScrollYPos;
/** @type {?} */
ScrollerComponent.prototype.prevScrollXPos;
/** @type {?} */
ScrollerComponent.prototype.element;
/** @type {?} */
ScrollerComponent.prototype.parentElement;
/** @type {?} */
ScrollerComponent.prototype.onScrollListener;
/**
* @type {?}
* @private
*/
ScrollerComponent.prototype._scrollEventListener;
/**
* @type {?}
* @private
*/
ScrollerComponent.prototype.ngZone;
/**
* @type {?}
* @private
*/
ScrollerComponent.prototype.renderer;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DatatableGroupHeaderTemplateDirective {
/**
* @param {?} template
*/
constructor(template) {
this.template = template;
}
}
DatatableGroupHeaderTemplateDirective.decorators = [
{ type: Directive, args: [{
selector: '[ngx-datatable-group-header-template]'
},] }
];
/** @nocollapse */
DatatableGroupHeaderTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
if (false) {
/** @type {?} */
DatatableGroupHeaderTemplateDirective.prototype.template;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DatatableGroupHeaderDirective {
constructor() {
/**
* Row height is required when virtual scroll is enabled.
*/
this.rowHeight = 0;
/**
* Track toggling of group visibility
*/
this.toggle = new EventEmitter();
}
/**
* @return {?}
*/
get template() {
return this._templateInput || this._templateQuery;
}
/**
* Toggle the expansion of a group
* @param {?} group
* @return {?}
*/
toggleExpandGroup(group) {
this.toggle.emit({
type: 'group',
value: group
});
}
/**
* Expand all groups
* @return {?}
*/
expandAllGroups() {
this.toggle.emit({
type: 'all',
value: true
});
}
/**
* Collapse all groups
* @return {?}
*/
collapseAllGroups() {
this.toggle.emit({
type: 'all',
value: false
});
}
}
DatatableGroupHeaderDirective.decorators = [
{ type: Directive, args: [{ selector: 'ngx-datatable-group-header' },] }
];
DatatableGroupHeaderDirective.propDecorators = {
rowHeight: [{ type: Input }],
_templateInput: [{ type: Input, args: ['template',] }],
_templateQuery: [{ type: ContentChild, args: [DatatableGroupHeaderTemplateDirective, { read: TemplateRef, static: true },] }],
toggle: [{ type: Output }]
};
if (false) {
/**
* Row height is required when virtual scroll is enabled.
* @type {?}
*/
DatatableGroupHeaderDirective.prototype.rowHeight;
/** @type {?} */
DatatableGroupHeaderDirective.prototype._templateInput;
/** @type {?} */
DatatableGroupHeaderDirective.prototype._templateQuery;
/**
* Track toggling of group visibility
* @type {?}
*/
DatatableGroupHeaderDirective.prototype.toggle;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Always returns the empty string ''
* @return {?}
*/
function emptyStringGetter() {
return '';
}
/**
* Returns the appropriate getter function for this kind of prop.
* If prop == null, returns the emptyStringGetter.
* @param {?} prop
* @return {?}
*/
function getterForProp(prop) {
if (prop == null) {
return emptyStringGetter;
}
if (typeof prop === 'number') {
return numericIndexGetter;
}
else {
// deep or simple
if (prop.indexOf('.') !== -1) {
return deepValueGetter;
}
else {
return shallowValueGetter;
}
}
}
/**
* Returns the value at this numeric index.
* @param {?} row array of values
* @param {?} index numeric index
* @return {?} any or '' if invalid index
*/
function numericIndexGetter(row, index) {
if (row == null) {
return '';
}
// mimic behavior of deepValueGetter
if (!row || index == null) {
return row;
}
/** @type {?} */
const value = row[index];
if (value == null) {
return '';
}
return value;
}
/**
* Returns the value of a field.
* (more efficient than deepValueGetter)
* @param {?} obj object containing the field
* @param {?} fieldName field name string
* @return {?}
*/
function shallowValueGetter(obj, fieldName) {
if (obj == null) {
return '';
}
if (!obj || !fieldName) {
return obj;
}
/** @type {?} */
const value = obj[fieldName];
if (value == null) {
return '';
}
return value;
}
/**
* Returns a deep object given a string. zoo['animal.type']
* @param {?} obj
* @param {?} path
* @return {?}
*/
function deepValueGetter(obj, path) {
if (obj == null) {
return '';
}
if (!obj || !path) {
return obj;
}
// check if path matches a root-level field
// { "a.b.c": 123 }
/** @type {?} */
let current = obj[path];
if (current !== undefined) {
return current;
}
current = obj;
/** @type {?} */
const split = path.split('.');
if (split.length) {
for (let i = 0; i < split.length; i++) {
current = current[split[i]];
// if found undefined, return empty string
if (current === undefined || current === null) {
return '';
}
}
}
return current;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} prop
* @return {?}
*/
function optionalGetterForProp(prop) {
return prop && ((/**
* @param {?} row
* @return {?}
*/
row => getterForProp(prop)(row, prop)));
}
/**
* This functions rearrange items by their parents
* Also sets the level value to each of the items
*
* Note: Expecting each item has a property called parentId
* Note: This algorithm will fail if a list has two or more items with same ID
* NOTE: This algorithm will fail if there is a deadlock of relationship
*
* For example,
*
* Input
*
* id -> parent
* 1 -> 0
* 2 -> 0
* 3 -> 1
* 4 -> 1
* 5 -> 2
* 7 -> 8
* 6 -> 3
*
*
* Output
* id -> level
* 1 -> 0
* --3 -> 1
* ----6 -> 2
* --4 -> 1
* 2 -> 0
* --5 -> 1
* 7 -> 8
*
*
* @param {?} rows
*
* @param {?=} from
* @param {?=} to
* @return {?}
*/
function groupRowsByParents(rows, from, to) {
if (from && to) {
/** @type {?} */
const nodeById = {};
/** @type {?} */
const l = rows.length;
/** @type {?} */
let node = null;
nodeById[0] = new TreeNode(); // that's the root node
// that's the root node
/** @type {?} */
const uniqIDs = rows.reduce((/**
* @param {?} arr
* @param {?} item
* @return {?}
*/
(arr, item) => {
/** @type {?} */
const toValue = to(item);
if (arr.indexOf(toValue) === -1) {
arr.push(toValue);
}
return arr;
}), []);
for (let i = 0; i < l; i++) {
// make TreeNode objects for each item
nodeById[to(rows[i])] = new TreeNode(rows[i]);
}
for (let i = 0; i < l; i++) {
// link all TreeNode objects
node = nodeById[to(rows[i])];
/** @type {?} */
let parent = 0;
/** @type {?} */
const fromValue = from(node.row);
if (!!fromValue && uniqIDs.indexOf(fromValue) > -1) {
parent = fromValue;
}
node.parent = nodeById[parent];
node.row['level'] = node.parent.row['level'] + 1;
node.parent.children.push(node);
}
/** @type {?} */
let resolvedRows = [];
nodeById[0].flatten((/**
* @return {?}
*/
function () {
resolvedRows = [...resolvedRows, this.row];
}), true);
return resolvedRows;
}
else {
return rows;
}
}
class TreeNode {
/**
* @param {?=} row
*/
constructor(row = null) {
if (!row) {
row = {
level: -1,
treeStatus: 'expanded'
};
}
this.row = row;
this.parent = null;
this.children = [];
}
/**
* @param {?} f
* @param {?} recursive
* @return {?}
*/
flatten(f, recursive) {
if (this.row['treeStatus'] === 'expanded') {
for (let i = 0, l = this.children.length; i < l; i++) {
/** @type {?} */
const child = this.children[i];
f.apply(child, Array.prototype.slice.call(arguments, 2));
if (recursive)
child.flatten.apply(child, arguments);
}
}
}
}
if (false) {
/** @type {?} */
TreeNode.prototype.row;
/** @type {?} */
TreeNode.prototype.parent;
/** @type {?} */
TreeNode.prototype.children;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Converts strings from something to camel case
* http://stackoverflow.com/questions/10425287/convert-dash-separated-string-to-camelcase
* @param {?} str
* @return {?}
*/
function camelCase(str) {
// Replace special characters with a space
str = str.replace(/[^a-zA-Z0-9 ]/g, ' ');
// put a space before an uppercase letter
str = str.replace(/([a-z](?=[A-Z]))/g, '$1 ');
// Lower case first character and some other stuff
str = str
.replace(/([^a-zA-Z0-9 ])|^[0-9]+/g, '')
.trim()
.toLowerCase();
// uppercase characters preceded by a space or number
str = str.replace(/([ 0-9]+)([a-zA-Z])/g, (/**
* @param {?} a
* @param {?} b
* @param {?} c
* @return {?}
*/
function (a, b, c) {
return b.trim() + c.toUpperCase();
}));
return str;
}
/**
* Converts strings from camel case to words
* http://stackoverflow.com/questions/7225407/convert-camelcasetext-to-camel-case-text
* @param {?} str
* @return {?}
*/
function deCamelCase(str) {
return str.replace(/([A-Z])/g, (/**
* @param {?} match
* @return {?}
*/
match => ` ${match}`)).replace(/^./, (/**
* @param {?} match
* @return {?}
*/
match => match.toUpperCase()));
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Creates a unique object id.
* http://stackoverflow.com/questions/6248666/how-to-generate-short-uid-like-ax4j9z-in-js
* @return {?}
*/
function id() {
return ('0000' + ((Math.random() * Math.pow(36, 4)) << 0).toString(36)).slice(-4);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Sets the column defaults
* @param {?} columns
* @return {?}
*/
function setColumnDefaults(columns) {
if (!columns)
return;
// Only one column should hold the tree view
// Thus if multiple columns are provided with
// isTreeColumn as true we take only the first one
/** @type {?} */
let treeColumnFound = false;
for (const column of columns) {
if (!column.$$id) {
column.$$id = id();
}
// prop can be numeric; zero is valid not a missing prop
// translate name => prop
if (isNullOrUndefined(column.prop) && column.name) {
column.prop = camelCase(column.name);
}
if (!column.$$valueGetter) {
column.$$valueGetter = getterForProp(column.prop);
}
// format props if no name passed
if (!isNullOrUndefined(column.prop) && isNullOrUndefined(column.name)) {
column.name = deCamelCase(String(column.prop));
}
if (isNullOrUndefined(column.prop) && isNullOrUndefined(column.name)) {
column.name = ''; // Fixes IE and Edge displaying `null`
}
if (!column.hasOwnProperty('resizeable')) {
column.resizeable = true;
}
if (!column.hasOwnProperty('sortable')) {
column.sortable = true;
}
if (!column.hasOwnProperty('draggable')) {
column.draggable = true;
}
if (!column.hasOwnProperty('canAutoResize')) {
column.canAutoResize = true;
}
if (!column.hasOwnProperty('width')) {
column.width = 150;
}
if (!column.hasOwnProperty('isTreeColumn')) {
column.isTreeColumn = false;
}
else {
if (column.isTreeColumn && !treeColumnFound) {
// If the first column with isTreeColumn is true found
// we mark that treeCoulmn is found
treeColumnFound = true;
}
else {
// After that isTreeColumn property for any other column
// will be set as false
column.isTreeColumn = false;
}
}
}
}
/**
* @template T
* @param {?} value
* @return {?}
*/
function isNullOrUndefined(value) {
return value === null || value === undefined;
}
/**
* Translates templates definitions to objects
* @param {?} templates
* @return {?}
*/
function translateTemplates(templates) {
/** @type {?} */
const result = [];
for (const temp of templates) {
/** @type {?} */
const col = {};
/** @type {?} */
const props = Object.getOwnPropertyNames(temp);
for (const prop of props) {
col[prop] = temp[prop];
}
if (temp.headerTemplate) {
col.headerTemplate = temp.headerTemplate;
}
if (temp.cellTemplate) {
col.cellTemplate = temp.cellTemplate;
}
if (temp.summaryFunc) {
col.summaryFunc = temp.summaryFunc;
}
if (temp.summaryTemplate) {
col.summaryTemplate = temp.summaryTemplate;
}
result.push(col);
}
return result;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {string} */
const ColumnMode = {
standard: 'standard',
flex: 'flex',
force: 'force',
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {string} */
const SelectionType = {
single: 'single',
multi: 'multi',
multiClick: 'multiClick',
cell: 'cell',
checkbox: 'checkbox',
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {string} */
const SortType = {
single: 'single',
multi: 'multi',
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {string} */
const ContextmenuType = {
header: 'header',
body: 'body',
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableColumnHeaderDirective {
/**
* @param {?} template
*/
constructor(template) {
this.template = template;
}
}
DataTableColumnHeaderDirective.decorators = [
{ type: Directive, args: [{ selector: '[ngx-datatable-header-template]' },] }
];
/** @nocollapse */
DataTableColumnHeaderDirective.ctorParameters = () => [
{ type: TemplateRef }
];
if (false) {
/** @type {?} */
DataTableColumnHeaderDirective.prototype.template;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableColumnCellDirective {
/**
* @param {?} template
*/
constructor(template) {
this.template = template;
}
}
DataTableColumnCellDirective.decorators = [
{ type: Directive, args: [{ selector: '[ngx-datatable-cell-template]' },] }
];
/** @nocollapse */
DataTableColumnCellDirective.ctorParameters = () => [
{ type: TemplateRef }
];
if (false) {
/** @type {?} */
DataTableColumnCellDirective.prototype.template;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableColumnCellTreeToggle {
/**
* @param {?} template
*/
constructor(template) {
this.template = template;
}
}
DataTableColumnCellTreeToggle.decorators = [
{ type: Directive, args: [{ selector: '[ngx-datatable-tree-toggle]' },] }
];
/** @nocollapse */
DataTableColumnCellTreeToggle.ctorParameters = () => [
{ type: TemplateRef }
];
if (false) {
/** @type {?} */
DataTableColumnCellTreeToggle.prototype.template;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableColumnDirective {
/**
* @param {?} columnChangesService
*/
constructor(columnChangesService) {
this.columnChangesService = columnChangesService;
this.isFirstChange = true;
}
/**
* @return {?}
*/
get cellTemplate() {
return this._cellTemplateInput || this._cellTemplateQuery;
}
/**
* @return {?}
*/
get headerTemplate() {
return this._headerTemplateInput || this._headerTemplateQuery;
}
/**
* @return {?}
*/
get treeToggleTemplate() {
return this._treeToggleTemplateInput || this._treeToggleTemplateQuery;
}
/**
* @return {?}
*/
ngOnChanges() {
if (this.isFirstChange) {
this.isFirstChange = false;
}
else {
this.columnChangesService.onInputChange();
}
}
}
DataTableColumnDirective.decorators = [
{ type: Directive, args: [{ selector: 'ngx-datatable-column' },] }
];
/** @nocollapse */
DataTableColumnDirective.ctorParameters = () => [
{ type: ColumnChangesService }
];
DataTableColumnDirective.propDecorators = {
name: [{ type: Input }],
prop: [{ type: Input }],
frozenLeft: [{ type: Input }],
frozenRight: [{ type: Input }],
flexGrow: [{ type: Input }],
resizeable: [{ type: Input }],
comparator: [{ type: Input }],
pipe: [{ type: Input }],
sortable: [{ type: Input }],
draggable: [{ type: Input }],
canAutoResize: [{ type: Input }],
minWidth: [{ type: Input }],
width: [{ type: Input }],
maxWidth: [{ type: Input }],
checkboxable: [{ type: Input }],
headerCheckboxable: [{ type: Input }],
headerClass: [{ type: Input }],
cellClass: [{ type: Input }],
isTreeColumn: [{ type: Input }],
treeLevelIndent: [{ type: Input }],
summaryFunc: [{ type: Input }],
summaryTemplate: [{ type: Input }],
_cellTemplateInput: [{ type: Input, args: ['cellTemplate',] }],
_cellTemplateQuery: [{ type: ContentChild, args: [DataTableColumnCellDirective, { read: TemplateRef, static: true },] }],
_headerTemplateInput: [{ type: Input, args: ['headerTemplate',] }],
_headerTemplateQuery: [{ type: ContentChild, args: [DataTableColumnHeaderDirective, { read: TemplateRef, static: true },] }],
_treeToggleTemplateInput: [{ type: Input, args: ['treeToggleTemplate',] }],
_treeToggleTemplateQuery: [{ type: ContentChild, args: [DataTableColumnCellTreeToggle, { read: TemplateRef, static: true },] }]
};
if (false) {
/** @type {?} */
DataTableColumnDirective.prototype.name;
/** @type {?} */
DataTableColumnDirective.prototype.prop;
/** @type {?} */
DataTableColumnDirective.prototype.frozenLeft;
/** @type {?} */
DataTableColumnDirective.prototype.frozenRight;
/** @type {?} */
DataTableColumnDirective.prototype.flexGrow;
/** @type {?} */
DataTableColumnDirective.prototype.resizeable;
/** @type {?} */
DataTableColumnDirective.prototype.comparator;
/** @type {?} */
DataTableColumnDirective.prototype.pipe;
/** @type {?} */
DataTableColumnDirective.prototype.sortable;
/** @type {?} */
DataTableColumnDirective.prototype.draggable;
/** @type {?} */
DataTableColumnDirective.prototype.canAutoResize;
/** @type {?} */
DataTableColumnDirective.prototype.minWidth;
/** @type {?} */
DataTableColumnDirective.prototype.width;
/** @type {?} */
DataTableColumnDirective.prototype.maxWidth;
/** @type {?} */
DataTableColumnDirective.prototype.checkboxable;
/** @type {?} */
DataTableColumnDirective.prototype.headerCheckboxable;
/** @type {?} */
DataTableColumnDirective.prototype.headerClass;
/** @type {?} */
DataTableColumnDirective.prototype.cellClass;
/** @type {?} */
DataTableColumnDirective.prototype.isTreeColumn;
/** @type {?} */
DataTableColumnDirective.prototype.treeLevelIndent;
/** @type {?} */
DataTableColumnDirective.prototype.summaryFunc;
/** @type {?} */
DataTableColumnDirective.prototype.summaryTemplate;
/** @type {?} */
DataTableColumnDirective.prototype._cellTemplateInput;
/** @type {?} */
DataTableColumnDirective.prototype._cellTemplateQuery;
/** @type {?} */
DataTableColumnDirective.prototype._headerTemplateInput;
/** @type {?} */
DataTableColumnDirective.prototype._headerTemplateQuery;
/** @type {?} */
DataTableColumnDirective.prototype._treeToggleTemplateInput;
/** @type {?} */
DataTableColumnDirective.prototype._treeToggleTemplateQuery;
/**
* @type {?}
* @private
*/
DataTableColumnDirective.prototype.isFirstChange;
/**
* @type {?}
* @private
*/
DataTableColumnDirective.prototype.columnChangesService;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DatatableRowDetailTemplateDirective {
/**
* @param {?} template
*/
constructor(template) {
this.template = template;
}
}
DatatableRowDetailTemplateDirective.decorators = [
{ type: Directive, args: [{
selector: '[ngx-datatable-row-detail-template]'
},] }
];
/** @nocollapse */
DatatableRowDetailTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
if (false) {
/** @type {?} */
DatatableRowDetailTemplateDirective.prototype.template;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DatatableRowDetailDirective {
constructor() {
/**
* The detail row height is required especially
* when virtual scroll is enabled.
*/
this.rowHeight = 0;
/**
* Row detail row visbility was toggled.
*/
this.toggle = new EventEmitter();
}
/**
* @return {?}
*/
get template() {
return this._templateInput || this._templateQuery;
}
/**
* Toggle the expansion of the row
* @param {?} row
* @return {?}
*/
toggleExpandRow(row) {
this.toggle.emit({
type: 'row',
value: row
});
}
/**
* API method to expand all the rows.
* @return {?}
*/
expandAllRows() {
this.toggle.emit({
type: 'all',
value: true
});
}
/**
* API method to collapse all the rows.
* @return {?}
*/
collapseAllRows() {
this.toggle.emit({
type: 'all',
value: false
});
}
}
DatatableRowDetailDirective.decorators = [
{ type: Directive, args: [{ selector: 'ngx-datatable-row-detail' },] }
];
DatatableRowDetailDirective.propDecorators = {
rowHeight: [{ type: Input }],
_templateInput: [{ type: Input, args: ['template',] }],
_templateQuery: [{ type: ContentChild, args: [DatatableRowDetailTemplateDirective, { read: TemplateRef, static: true },] }],
toggle: [{ type: Output }]
};
if (false) {
/**
* The detail row height is required especially
* when virtual scroll is enabled.
* @type {?}
*/
DatatableRowDetailDirective.prototype.rowHeight;
/** @type {?} */
DatatableRowDetailDirective.prototype._templateInput;
/** @type {?} */
DatatableRowDetailDirective.prototype._templateQuery;
/**
* Row detail row visbility was toggled.
* @type {?}
*/
DatatableRowDetailDirective.prototype.toggle;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DatatableFooterDirective {
/**
* @return {?}
*/
get template() {
return this._templateInput || this._templateQuery;
}
}
DatatableFooterDirective.decorators = [
{ type: Directive, args: [{ selector: 'ngx-datatable-footer' },] }
];
DatatableFooterDirective.propDecorators = {
footerHeight: [{ type: Input }],
totalMessage: [{ type: Input }],
selectedMessage: [{ type: Input }],
pagerLeftArrowIcon: [{ type: Input }],
pagerRightArrowIcon: [{ type: Input }],
pagerPreviousIcon: [{ type: Input }],
pagerNextIcon: [{ type: Input }],
_templateInput: [{ type: Input, args: ['template',] }],
_templateQuery: [{ type: ContentChild, args: [DataTableFooterTemplateDirective, { read: TemplateRef, static: false },] }]
};
if (false) {
/** @type {?} */
DatatableFooterDirective.prototype.footerHeight;
/** @type {?} */
DatatableFooterDirective.prototype.totalMessage;
/** @type {?} */
DatatableFooterDirective.prototype.selectedMessage;
/** @type {?} */
DatatableFooterDirective.prototype.pagerLeftArrowIcon;
/** @type {?} */
DatatableFooterDirective.prototype.pagerRightArrowIcon;
/** @type {?} */
DatatableFooterDirective.prototype.pagerPreviousIcon;
/** @type {?} */
DatatableFooterDirective.prototype.pagerNextIcon;
/** @type {?} */
DatatableFooterDirective.prototype._templateInput;
/** @type {?} */
DatatableFooterDirective.prototype._templateQuery;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Returns the columns by pin.
* @param {?} cols
* @return {?}
*/
function columnsByPin(cols) {
/** @type {?} */
const ret = {
left: [],
center: [],
right: []
};
if (cols) {
for (const col of cols) {
if (col.frozenLeft) {
ret.left.push(col);
}
else if (col.frozenRight) {
ret.right.push(col);
}
else {
ret.center.push(col);
}
}
}
return ret;
}
/**
* Returns the widths of all group sets of a column
* @param {?} groups
* @param {?} all
* @return {?}
*/
function columnGroupWidths(groups, all) {
return {
left: columnTotalWidth(groups.left),
center: columnTotalWidth(groups.center),
right: columnTotalWidth(groups.right),
total: Math.floor(columnTotalWidth(all))
};
}
/**
* Calculates the total width of all columns and their groups
* @param {?} columns
* @param {?=} prop
* @return {?}
*/
function columnTotalWidth(columns, prop) {
/** @type {?} */
let totalWidth = 0;
if (columns) {
for (const c of columns) {
/** @type {?} */
const has = prop && c[prop];
/** @type {?} */
const width = has ? c[prop] : c.width;
totalWidth = totalWidth + parseFloat(width);
}
}
return totalWidth;
}
/**
* Calculates the total width of all columns and their groups
* @param {?} columns
* @param {?=} prop
* @return {?}
*/
function columnsTotalWidth(columns, prop) {
/** @type {?} */
let totalWidth = 0;
for (const column of columns) {
/** @type {?} */
const has = prop && column[prop];
totalWidth = totalWidth + (has ? column[prop] : column.width);
}
return totalWidth;
}
/**
* @param {?} val
* @return {?}
*/
function columnsByPinArr(val) {
/** @type {?} */
const colsByPinArr = [];
/** @type {?} */
const colsByPin = columnsByPin(val);
colsByPinArr.push({ type: 'left', columns: colsByPin['left'] });
colsByPinArr.push({ type: 'center', columns: colsByPin['center'] });
colsByPinArr.push({ type: 'right', columns: colsByPin['right'] });
return colsByPinArr;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* This object contains the cache of the various row heights that are present inside
* the data table. Its based on Fenwick tree data structure that helps with
* querying sums that have time complexity of log n.
*
* Fenwick Tree Credits: http://petr-mitrichev.blogspot.com/2013/05/fenwick-tree-range-updates.html
* https://github.com/mikolalysenko/fenwick-tree
*
*/
class RowHeightCache {
constructor() {
/**
* Tree Array stores the cumulative information of the row heights to perform efficient
* range queries and updates. Currently the tree is initialized to the base row
* height instead of the detail row height.
*/
this.treeArray = [];
}
/**
* Clear the Tree array.
* @return {?}
*/
clearCache() {
this.treeArray = [];
}
/**
* Initialize the Fenwick tree with row Heights.
*
* @param {?} details
* @return {?}
*/
initCache(details) {
const { rows, rowHeight, detailRowHeight, externalVirtual, rowCount, rowIndexes, rowExpansions } = details;
/** @type {?} */
const isFn = typeof rowHeight === 'function';
/** @type {?} */
const isDetailFn = typeof detailRowHeight === 'function';
if (!isFn && isNaN(rowHeight)) {
throw new Error(`Row Height cache initialization failed. Please ensure that 'rowHeight' is a
valid number or function value: (${rowHeight}) when 'scrollbarV' is enabled.`);
}
// Add this additional guard in case detailRowHeight is set to 'auto' as it wont work.
if (!isDetailFn && isNaN(detailRowHeight)) {
throw new Error(`Row Height cache initialization failed. Please ensure that 'detailRowHeight' is a
valid number or function value: (${detailRowHeight}) when 'scrollbarV' is enabled.`);
}
/** @type {?} */
const n = externalVirtual ? rowCount : rows.length;
this.treeArray = new Array(n);
for (let i = 0; i < n; ++i) {
this.treeArray[i] = 0;
}
for (let i = 0; i < n; ++i) {
/** @type {?} */
const row = rows[i];
/** @type {?} */
let currentRowHeight = rowHeight;
if (isFn) {
currentRowHeight = rowHeight(row);
}
// Add the detail row height to the already expanded rows.
// This is useful for the table that goes through a filter or sort.
/** @type {?} */
const expanded = rowExpansions.has(row);
if (row && expanded) {
if (isDetailFn) {
/** @type {?} */
const index = rowIndexes.get(row);
currentRowHeight += detailRowHeight(row, index);
}
else {
currentRowHeight += detailRowHeight;
}
}
this.update(i, currentRowHeight);
}
}
/**
* Given the ScrollY position i.e. sum, provide the rowIndex
* that is present in the current view port. Below handles edge cases.
* @param {?} scrollY
* @return {?}
*/
getRowIndex(scrollY) {
if (scrollY === 0)
return 0;
return this.calcRowIndex(scrollY);
}
/**
* When a row is expanded or rowHeight is changed, update the height. This can
* be utilized in future when Angular Data table supports dynamic row heights.
* @param {?} atRowIndex
* @param {?} byRowHeight
* @return {?}
*/
update(atRowIndex, byRowHeight) {
if (!this.treeArray.length) {
throw new Error(`Update at index ${atRowIndex} with value ${byRowHeight} failed:
Row Height cache not initialized.`);
}
/** @type {?} */
const n = this.treeArray.length;
atRowIndex |= 0;
while (atRowIndex < n) {
this.treeArray[atRowIndex] += byRowHeight;
atRowIndex |= atRowIndex + 1;
}
}
/**
* Range Sum query from 1 to the rowIndex
* @param {?} atIndex
* @return {?}
*/
query(atIndex) {
if (!this.treeArray.length) {
throw new Error(`query at index ${atIndex} failed: Fenwick tree array not initialized.`);
}
/** @type {?} */
let sum = 0;
atIndex |= 0;
while (atIndex >= 0) {
sum += this.treeArray[atIndex];
atIndex = (atIndex & (atIndex + 1)) - 1;
}
return sum;
}
/**
* Find the total height between 2 row indexes
* @param {?} atIndexA
* @param {?} atIndexB
* @return {?}
*/
queryBetween(atIndexA, atIndexB) {
return this.query(atIndexB) - this.query(atIndexA - 1);
}
/**
* Given the ScrollY position i.e. sum, provide the rowIndex
* that is present in the current view port.
* @private
* @param {?} sum
* @return {?}
*/
calcRowIndex(sum) {
if (!this.treeArray.length)
return 0;
/** @type {?} */
let pos = -1;
/** @type {?} */
const dataLength = this.treeArray.length;
// Get the highest bit for the block size.
/** @type {?} */
const highestBit = Math.pow(2, dataLength.toString(2).length - 1);
for (let blockSize = highestBit; blockSize !== 0; blockSize >>= 1) {
/** @type {?} */
const nextPos = pos + blockSize;
if (nextPos < dataLength && sum >= this.treeArray[nextPos]) {
sum -= this.treeArray[nextPos];
pos = nextPos;
}
}
return pos + 1;
}
}
if (false) {
/**
* Tree Array stores the cumulative information of the row heights to perform efficient
* range queries and updates. Currently the tree is initialized to the base row
* height instead of the detail row height.
* @type {?}
* @private
*/
RowHeightCache.prototype.treeArray;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const cache = {};
/** @type {?} */
const testStyle = typeof document !== 'undefined' ? document.createElement('div').style : undefined;
// Get Prefix
// http://davidwalsh.name/vendor-prefix
const ɵ0 = /**
* @return {?}
*/
function () {
/** @type {?} */
const styles = typeof window !== 'undefined' ? window.getComputedStyle(document.documentElement, '') : undefined;
/** @type {?} */
const match = typeof styles !== 'undefined'
? Array.prototype.slice
.call(styles)
.join('')
.match(/-(moz|webkit|ms)-/)
: null;
/** @type {?} */
const pre = match !== null ? match[1] : undefined;
// tslint:disable-next-line: tsr-detect-non-literal-regexp
/** @type {?} */
const dom = typeof pre !== 'undefined' ? 'WebKit|Moz|MS|O'.match(new RegExp('(' + pre + ')', 'i'))[1] : undefined;
return dom
? {
dom,
lowercase: pre,
css: `-${pre}-`,
js: pre[0].toUpperCase() + pre.substr(1)
}
: undefined;
};
/** @type {?} */
const prefix = ((ɵ0))();
/**
* @param {?} property
* @return {?}
*/
function getVendorPrefixedName(property) {
/** @type {?} */
const name = camelCase(property);
if (!cache[name]) {
if (prefix !== undefined && testStyle[prefix.css + property] !== undefined) {
cache[name] = prefix.css + property;
}
else if (testStyle[property] !== undefined) {
cache[name] = property;
}
}
return cache[name];
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// browser detection and prefixing tools
/** @type {?} */
const transform = typeof window !== 'undefined' ? getVendorPrefixedName('transform') : undefined;
/** @type {?} */
const backfaceVisibility = typeof window !== 'undefined' ? getVendorPrefixedName('backfaceVisibility') : undefined;
/** @type {?} */
const hasCSSTransforms = typeof window !== 'undefined' ? !!getVendorPrefixedName('transform') : undefined;
/** @type {?} */
const hasCSS3DTransforms = typeof window !== 'undefined' ? !!getVendorPrefixedName('perspective') : undefined;
/** @type {?} */
const ua = typeof window !== 'undefined' ? window.navigator.userAgent : 'Chrome';
/** @type {?} */
const isSafari = /Safari\//.test(ua) && !/Chrome\//.test(ua);
/**
* @param {?} styles
* @param {?} x
* @param {?} y
* @return {?}
*/
function translateXY(styles, x, y) {
if (typeof transform !== 'undefined' && hasCSSTransforms) {
if (!isSafari && hasCSS3DTransforms) {
styles[transform] = `translate3d(${x}px, ${y}px, 0)`;
styles[backfaceVisibility] = 'hidden';
}
else {
styles[camelCase(transform)] = `translate(${x}px, ${y}px)`;
}
}
else {
styles.top = `${y}px`;
styles.left = `${x}px`;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableBodyComponent {
/**
* Creates an instance of DataTableBodyComponent.
* @param {?} cd
*/
constructor(cd) {
this.cd = cd;
this.selected = [];
this.scroll = new EventEmitter();
this.page = new EventEmitter();
this.activate = new EventEmitter();
this.select = new EventEmitter();
this.detailToggle = new EventEmitter();
this.rowContextmenu = new EventEmitter(false);
this.treeAction = new EventEmitter();
this.rowHeightsCache = new RowHeightCache();
this.temp = [];
this.offsetY = 0;
this.indexes = {};
this.rowIndexes = new Map();
this.rowExpansions = [];
/**
* Get the height of the detail row.
*/
this.getDetailRowHeight = (/**
* @param {?=} row
* @param {?=} index
* @return {?}
*/
(row, index) => {
if (!this.rowDetail) {
return 0;
}
/** @type {?} */
const rowHeight = this.rowDetail.rowHeight;
return typeof rowHeight === 'function' ? rowHeight(row, index) : ((/** @type {?} */ (rowHeight)));
});
// declare fn here so we can get access to the `this` property
this.rowTrackingFn = (/**
* @param {?} index
* @param {?} row
* @return {?}
*/
(index, row) => {
/** @type {?} */
const idx = this.getRowIndex(row);
if (this.trackByProp) {
return row[this.trackByProp];
}
else {
return idx;
}
});
}
/**
* @param {?} val
* @return {?}
*/
set pageSize(val) {
this._pageSize = val;
this.recalcLayout();
}
/**
* @return {?}
*/
get pageSize() {
return this._pageSize;
}
/**
* @param {?} val
* @return {?}
*/
set rows(val) {
this._rows = val;
this.recalcLayout();
}
/**
* @return {?}
*/
get rows() {
return this._rows;
}
/**
* @param {?} val
* @return {?}
*/
set columns(val) {
this._columns = val;
/** @type {?} */
const colsByPin = columnsByPin(val);
this.columnGroupWidths = columnGroupWidths(colsByPin, val);
}
/**
* @return {?}
*/
get columns() {
return this._columns;
}
/**
* @param {?} val
* @return {?}
*/
set offset(val) {
this._offset = val;
if (!this.scrollbarV || (this.scrollbarV && !this.virtualization))
this.recalcLayout();
}
/**
* @return {?}
*/
get offset() {
return this._offset;
}
/**
* @param {?} val
* @return {?}
*/
set rowCount(val) {
this._rowCount = val;
this.recalcLayout();
}
/**
* @return {?}
*/
get rowCount() {
return this._rowCount;
}
/**
* @return {?}
*/
get bodyWidth() {
if (this.scrollbarH) {
return this.innerWidth + 'px';
}
else {
return '100%';
}
}
/**
* @param {?} val
* @return {?}
*/
set bodyHeight(val) {
if (this.scrollbarV) {
this._bodyHeight = val + 'px';
}
else {
this._bodyHeight = 'auto';
}
this.recalcLayout();
}
/**
* @return {?}
*/
get bodyHeight() {
return this._bodyHeight;
}
/**
* Returns if selection is enabled.
* @return {?}
*/
get selectEnabled() {
return !!this.selectionType;
}
/**
* Property that would calculate the height of scroll bar
* based on the row heights cache for virtual scroll and virtualization. Other scenarios
* calculate scroll height automatically (as height will be undefined).
* @return {?}
*/
get scrollHeight() {
if (this.scrollbarV && this.virtualization && this.rowCount) {
return this.rowHeightsCache.query(this.rowCount - 1);
}
// avoid TS7030: Not all code paths return a value.
return undefined;
}
/**
* Called after the constructor, initializing input properties
* @return {?}
*/
ngOnInit() {
if (this.rowDetail) {
this.listener = this.rowDetail.toggle.subscribe((/**
* @param {?} __0
* @return {?}
*/
({ type, value }) => {
if (type === 'row') {
this.toggleRowExpansion(value);
}
if (type === 'all') {
this.toggleAllRows(value);
}
// Refresh rows after toggle
// Fixes #883
this.updateIndexes();
this.updateRows();
this.cd.markForCheck();
}));
}
if (this.groupHeader) {
this.listener = this.groupHeader.toggle.subscribe((/**
* @param {?} __0
* @return {?}
*/
({ type, value }) => {
if (type === 'group') {
this.toggleRowExpansion(value);
}
if (type === 'all') {
this.toggleAllRows(value);
}
// Refresh rows after toggle
// Fixes #883
this.updateIndexes();
this.updateRows();
this.cd.markForCheck();
}));
}
}
/**
* Called once, before the instance is destroyed.
* @return {?}
*/
ngOnDestroy() {
if (this.rowDetail || this.groupHeader) {
this.listener.unsubscribe();
}
}
/**
* Updates the Y offset given a new offset.
* @param {?=} offset
* @return {?}
*/
updateOffsetY(offset) {
// scroller is missing on empty table
if (!this.scroller) {
return;
}
if (this.scrollbarV && this.virtualization && offset) {
// First get the row Index that we need to move to.
/** @type {?} */
const rowIndex = this.pageSize * offset;
offset = this.rowHeightsCache.query(rowIndex - 1);
}
else if (this.scrollbarV && !this.virtualization) {
offset = 0;
}
this.scroller.setOffset(offset || 0);
}
/**
* Body was scrolled, this is mainly useful for
* when a user is server-side pagination via virtual scroll.
* @param {?} event
* @return {?}
*/
onBodyScroll(event) {
/** @type {?} */
const scrollYPos = event.scrollYPos;
/** @type {?} */
const scrollXPos = event.scrollXPos;
// if scroll change, trigger update
// this is mainly used for header cell positions
if (this.offsetY !== scrollYPos || this.offsetX !== scrollXPos) {
this.scroll.emit({
offsetY: scrollYPos,
offsetX: scrollXPos
});
}
this.offsetY = scrollYPos;
this.offsetX = scrollXPos;
this.updateIndexes();
this.updatePage(event.direction);
this.updateRows();
}
/**
* Updates the page given a direction.
* @param {?} direction
* @return {?}
*/
updatePage(direction) {
/** @type {?} */
let offset = this.indexes.first / this.pageSize;
if (direction === 'up') {
offset = Math.ceil(offset);
}
else if (direction === 'down') {
offset = Math.floor(offset);
}
if (direction !== undefined && !isNaN(offset)) {
this.page.emit({ offset });
}
}
/**
* Updates the rows in the view port
* @return {?}
*/
updateRows() {
const { first, last } = this.indexes;
/** @type {?} */
let rowIndex = first;
/** @type {?} */
let idx = 0;
/** @type {?} */
const temp = [];
this.rowIndexes.clear();
// if grouprowsby has been specified treat row paging
// parameters as group paging parameters ie if limit 10 has been
// specified treat it as 10 groups rather than 10 rows
if (this.groupedRows) {
/** @type {?} */
let maxRowsPerGroup = 3;
// if there is only one group set the maximum number of
// rows per group the same as the total number of rows
if (this.groupedRows.length === 1) {
maxRowsPerGroup = this.groupedRows[0].value.length;
}
while (rowIndex < last && rowIndex < this.groupedRows.length) {
// Add the groups into this page
/** @type {?} */
const group = this.groupedRows[rowIndex];
temp[idx] = group;
idx++;
// Group index in this context
rowIndex++;
}
}
else {
while (rowIndex < last && rowIndex < this.rowCount) {
/** @type {?} */
const row = this.rows[rowIndex];
if (row) {
this.rowIndexes.set(row, rowIndex);
temp[idx] = row;
}
idx++;
rowIndex++;
}
}
this.temp = temp;
}
/**
* Get the row height
* @param {?} row
* @return {?}
*/
getRowHeight(row) {
// if its a function return it
if (typeof this.rowHeight === 'function') {
return this.rowHeight(row);
}
return (/** @type {?} */ (this.rowHeight));
}
/**
* @param {?} group the group with all rows
* @return {?}
*/
getGroupHeight(group) {
/** @type {?} */
let rowHeight = 0;
if (group.value) {
for (let index = 0; index < group.value.length; index++) {
rowHeight += this.getRowAndDetailHeight(group.value[index]);
}
}
return rowHeight;
}
/**
* Calculate row height based on the expanded state of the row.
* @param {?} row
* @return {?}
*/
getRowAndDetailHeight(row) {
/** @type {?} */
let rowHeight = this.getRowHeight(row);
/** @type {?} */
const expanded = this.getRowExpanded(row);
// Adding detail row height if its expanded.
if (expanded) {
rowHeight += this.getDetailRowHeight(row);
}
return rowHeight;
}
/**
* Calculates the styles for the row so that the rows can be moved in 2D space
* during virtual scroll inside the DOM. In the below case the Y position is
* manipulated. As an example, if the height of row 0 is 30 px and row 1 is
* 100 px then following styles are generated:
*
* transform: translate3d(0px, 0px, 0px); -> row0
* transform: translate3d(0px, 30px, 0px); -> row1
* transform: translate3d(0px, 130px, 0px); -> row2
*
* Row heights have to be calculated based on the row heights cache as we wont
* be able to determine which row is of what height before hand. In the above
* case the positionY of the translate3d for row2 would be the sum of all the
* heights of the rows before it (i.e. row0 and row1).
*
* \@memberOf DataTableBodyComponent
* @param {?} rows the row that needs to be placed in the 2D space.
* @return {?} the CSS3 style to be applied
*
*/
getRowsStyles(rows) {
/** @type {?} */
const styles = {};
// only add styles for the group if there is a group
if (this.groupedRows) {
styles.width = this.columnGroupWidths.total;
}
if (this.scrollbarV && this.virtualization) {
/** @type {?} */
let idx = 0;
if (this.groupedRows) {
// Get the latest row rowindex in a group
/** @type {?} */
const row = rows[rows.length - 1];
idx = row ? this.getRowIndex(row) : 0;
}
else {
idx = this.getRowIndex(rows);
}
// const pos = idx * rowHeight;
// The position of this row would be the sum of all row heights
// until the previous row position.
/** @type {?} */
const pos = this.rowHeightsCache.query(idx - 1);
translateXY(styles, 0, pos);
}
return styles;
}
/**
* Calculate bottom summary row offset for scrollbar mode.
* For more information about cache and offset calculation
* see description for `getRowsStyles` method
*
* \@memberOf DataTableBodyComponent
* @return {?} the CSS3 style to be applied
*
*/
getBottomSummaryRowStyles() {
if (!this.scrollbarV || !this.rows || !this.rows.length) {
return null;
}
/** @type {?} */
const styles = { position: 'absolute' };
/** @type {?} */
const pos = this.rowHeightsCache.query(this.rows.length - 1);
translateXY(styles, 0, pos);
return styles;
}
/**
* Hides the loading indicator
* @return {?}
*/
hideIndicator() {
setTimeout((/**
* @return {?}
*/
() => (this.loadingIndicator = false)), 500);
}
/**
* Updates the index of the rows in the viewport
* @return {?}
*/
updateIndexes() {
/** @type {?} */
let first = 0;
/** @type {?} */
let last = 0;
if (this.scrollbarV) {
if (this.virtualization) {
// Calculation of the first and last indexes will be based on where the
// scrollY position would be at. The last index would be the one
// that shows up inside the view port the last.
/** @type {?} */
const height = parseInt(this.bodyHeight, 0);
first = this.rowHeightsCache.getRowIndex(this.offsetY);
last = this.rowHeightsCache.getRowIndex(height + this.offsetY) + 1;
}
else {
// If virtual rows are not needed
// We render all in one go
first = 0;
last = this.rowCount;
}
}
else {
// The server is handling paging and will pass an array that begins with the
// element at a specified offset. first should always be 0 with external paging.
if (!this.externalPaging) {
first = Math.max(this.offset * this.pageSize, 0);
}
last = Math.min(first + this.pageSize, this.rowCount);
}
this.indexes = { first, last };
}
/**
* Refreshes the full Row Height cache. Should be used
* when the entire row array state has changed.
* @return {?}
*/
refreshRowHeightCache() {
if (!this.scrollbarV || (this.scrollbarV && !this.virtualization)) {
return;
}
// clear the previous row height cache if already present.
// this is useful during sorts, filters where the state of the
// rows array is changed.
this.rowHeightsCache.clearCache();
// Initialize the tree only if there are rows inside the tree.
if (this.rows && this.rows.length) {
/** @type {?} */
const rowExpansions = new Set();
for (const row of this.rows) {
if (this.getRowExpanded(row)) {
rowExpansions.add(row);
}
}
this.rowHeightsCache.initCache({
rows: this.rows,
rowHeight: this.rowHeight,
detailRowHeight: this.getDetailRowHeight,
externalVirtual: this.scrollbarV && this.externalPaging,
rowCount: this.rowCount,
rowIndexes: this.rowIndexes,
rowExpansions
});
}
}
/**
* Gets the index for the view port
* @return {?}
*/
getAdjustedViewPortIndex() {
// Capture the row index of the first row that is visible on the viewport.
// If the scroll bar is just below the row which is highlighted then make that as the
// first index.
/** @type {?} */
const viewPortFirstRowIndex = this.indexes.first;
if (this.scrollbarV && this.virtualization) {
/** @type {?} */
const offsetScroll = this.rowHeightsCache.query(viewPortFirstRowIndex - 1);
return offsetScroll <= this.offsetY ? viewPortFirstRowIndex - 1 : viewPortFirstRowIndex;
}
return viewPortFirstRowIndex;
}
/**
* Toggle the Expansion of the row i.e. if the row is expanded then it will
* collapse and vice versa. Note that the expanded status is stored as
* a part of the row object itself as we have to preserve the expanded row
* status in case of sorting and filtering of the row set.
* @param {?} row
* @return {?}
*/
toggleRowExpansion(row) {
// Capture the row index of the first row that is visible on the viewport.
/** @type {?} */
const viewPortFirstRowIndex = this.getAdjustedViewPortIndex();
/** @type {?} */
const rowExpandedIdx = this.getRowExpandedIdx(row, this.rowExpansions);
/** @type {?} */
const expanded = rowExpandedIdx > -1;
// If the detailRowHeight is auto --> only in case of non-virtualized scroll
if (this.scrollbarV && this.virtualization) {
/** @type {?} */
const detailRowHeight = this.getDetailRowHeight(row) * (expanded ? -1 : 1);
// const idx = this.rowIndexes.get(row) || 0;
/** @type {?} */
const idx = this.getRowIndex(row);
this.rowHeightsCache.update(idx, detailRowHeight);
}
// Update the toggled row and update thive nevere heights in the cache.
if (expanded) {
this.rowExpansions.splice(rowExpandedIdx, 1);
}
else {
this.rowExpansions.push(row);
}
this.detailToggle.emit({
rows: [row],
currentIndex: viewPortFirstRowIndex
});
}
/**
* Expand/Collapse all the rows no matter what their state is.
* @param {?} expanded
* @return {?}
*/
toggleAllRows(expanded) {
// clear prev expansions
this.rowExpansions = [];
// Capture the row index of the first row that is visible on the viewport.
/** @type {?} */
const viewPortFirstRowIndex = this.getAdjustedViewPortIndex();
if (expanded) {
for (const row of this.rows) {
this.rowExpansions.push(row);
}
}
if (this.scrollbarV) {
// Refresh the full row heights cache since every row was affected.
this.recalcLayout();
}
// Emit all rows that have been expanded.
this.detailToggle.emit({
rows: this.rows,
currentIndex: viewPortFirstRowIndex
});
}
/**
* Recalculates the table
* @return {?}
*/
recalcLayout() {
this.refreshRowHeightCache();
this.updateIndexes();
this.updateRows();
}
/**
* Tracks the column
* @param {?} index
* @param {?} column
* @return {?}
*/
columnTrackingFn(index, column) {
return column.$$id;
}
/**
* Gets the row pinning group styles
* @param {?} group
* @return {?}
*/
stylesByGroup(group) {
/** @type {?} */
const widths = this.columnGroupWidths;
/** @type {?} */
const offsetX = this.offsetX;
/** @type {?} */
const styles = {
width: `${widths[group]}px`
};
if (group === 'left') {
translateXY(styles, offsetX, 0);
}
else if (group === 'right') {
/** @type {?} */
const bodyWidth = parseInt(this.innerWidth + '', 0);
/** @type {?} */
const totalDiff = widths.total - bodyWidth;
/** @type {?} */
const offsetDiff = totalDiff - offsetX;
/** @type {?} */
const offset = offsetDiff * -1;
translateXY(styles, offset, 0);
}
return styles;
}
/**
* Returns if the row was expanded and set default row expansion when row expansion is empty
* @param {?} row
* @return {?}
*/
getRowExpanded(row) {
if (this.rowExpansions.length === 0 && this.groupExpansionDefault) {
for (const group of this.groupedRows) {
this.rowExpansions.push(group);
}
}
return this.getRowExpandedIdx(row, this.rowExpansions) > -1;
}
/**
* @param {?} row
* @param {?} expanded
* @return {?}
*/
getRowExpandedIdx(row, expanded) {
if (!expanded || !expanded.length)
return -1;
/** @type {?} */
const rowId = this.rowIdentity(row);
return expanded.findIndex((/**
* @param {?} r
* @return {?}
*/
(r) => {
/** @type {?} */
const id = this.rowIdentity(r);
return id === rowId;
}));
}
/**
* Gets the row index given a row
* @param {?} row
* @return {?}
*/
getRowIndex(row) {
return this.rowIndexes.get(row) || 0;
}
/**
* @param {?} row
* @return {?}
*/
onTreeAction(row) {
this.treeAction.emit({ row });
}
}
DataTableBodyComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-body',
template: `
`,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: 'datatable-body'
}
}] }
];
/** @nocollapse */
DataTableBodyComponent.ctorParameters = () => [
{ type: ChangeDetectorRef }
];
DataTableBodyComponent.propDecorators = {
scrollbarV: [{ type: Input }],
scrollbarH: [{ type: Input }],
loadingIndicator: [{ type: Input }],
externalPaging: [{ type: Input }],
rowHeight: [{ type: Input }],
offsetX: [{ type: Input }],
emptyMessage: [{ type: Input }],
selectionType: [{ type: Input }],
selected: [{ type: Input }],
rowIdentity: [{ type: Input }],
rowDetail: [{ type: Input }],
groupHeader: [{ type: Input }],
selectCheck: [{ type: Input }],
displayCheck: [{ type: Input }],
trackByProp: [{ type: Input }],
rowClass: [{ type: Input }],
groupedRows: [{ type: Input }],
groupExpansionDefault: [{ type: Input }],
innerWidth: [{ type: Input }],
groupRowsBy: [{ type: Input }],
virtualization: [{ type: Input }],
summaryRow: [{ type: Input }],
summaryPosition: [{ type: Input }],
summaryHeight: [{ type: Input }],
pageSize: [{ type: Input }],
rows: [{ type: Input }],
columns: [{ type: Input }],
offset: [{ type: Input }],
rowCount: [{ type: Input }],
bodyWidth: [{ type: HostBinding, args: ['style.width',] }],
bodyHeight: [{ type: Input }, { type: HostBinding, args: ['style.height',] }],
scroll: [{ type: Output }],
page: [{ type: Output }],
activate: [{ type: Output }],
select: [{ type: Output }],
detailToggle: [{ type: Output }],
rowContextmenu: [{ type: Output }],
treeAction: [{ type: Output }],
scroller: [{ type: ViewChild, args: [ScrollerComponent, { static: false },] }]
};
if (false) {
/** @type {?} */
DataTableBodyComponent.prototype.scrollbarV;
/** @type {?} */
DataTableBodyComponent.prototype.scrollbarH;
/** @type {?} */
DataTableBodyComponent.prototype.loadingIndicator;
/** @type {?} */
DataTableBodyComponent.prototype.externalPaging;
/** @type {?} */
DataTableBodyComponent.prototype.rowHeight;
/** @type {?} */
DataTableBodyComponent.prototype.offsetX;
/** @type {?} */
DataTableBodyComponent.prototype.emptyMessage;
/** @type {?} */
DataTableBodyComponent.prototype.selectionType;
/** @type {?} */
DataTableBodyComponent.prototype.selected;
/** @type {?} */
DataTableBodyComponent.prototype.rowIdentity;
/** @type {?} */
DataTableBodyComponent.prototype.rowDetail;
/** @type {?} */
DataTableBodyComponent.prototype.groupHeader;
/** @type {?} */
DataTableBodyComponent.prototype.selectCheck;
/** @type {?} */
DataTableBodyComponent.prototype.displayCheck;
/** @type {?} */
DataTableBodyComponent.prototype.trackByProp;
/** @type {?} */
DataTableBodyComponent.prototype.rowClass;
/** @type {?} */
DataTableBodyComponent.prototype.groupedRows;
/** @type {?} */
DataTableBodyComponent.prototype.groupExpansionDefault;
/** @type {?} */
DataTableBodyComponent.prototype.innerWidth;
/** @type {?} */
DataTableBodyComponent.prototype.groupRowsBy;
/** @type {?} */
DataTableBodyComponent.prototype.virtualization;
/** @type {?} */
DataTableBodyComponent.prototype.summaryRow;
/** @type {?} */
DataTableBodyComponent.prototype.summaryPosition;
/** @type {?} */
DataTableBodyComponent.prototype.summaryHeight;
/** @type {?} */
DataTableBodyComponent.prototype.scroll;
/** @type {?} */
DataTableBodyComponent.prototype.page;
/** @type {?} */
DataTableBodyComponent.prototype.activate;
/** @type {?} */
DataTableBodyComponent.prototype.select;
/** @type {?} */
DataTableBodyComponent.prototype.detailToggle;
/** @type {?} */
DataTableBodyComponent.prototype.rowContextmenu;
/** @type {?} */
DataTableBodyComponent.prototype.treeAction;
/** @type {?} */
DataTableBodyComponent.prototype.scroller;
/** @type {?} */
DataTableBodyComponent.prototype.rowHeightsCache;
/** @type {?} */
DataTableBodyComponent.prototype.temp;
/** @type {?} */
DataTableBodyComponent.prototype.offsetY;
/** @type {?} */
DataTableBodyComponent.prototype.indexes;
/** @type {?} */
DataTableBodyComponent.prototype.columnGroupWidths;
/** @type {?} */
DataTableBodyComponent.prototype.columnGroupWidthsWithoutGroup;
/** @type {?} */
DataTableBodyComponent.prototype.rowTrackingFn;
/** @type {?} */
DataTableBodyComponent.prototype.listener;
/** @type {?} */
DataTableBodyComponent.prototype.rowIndexes;
/** @type {?} */
DataTableBodyComponent.prototype.rowExpansions;
/** @type {?} */
DataTableBodyComponent.prototype._rows;
/** @type {?} */
DataTableBodyComponent.prototype._bodyHeight;
/** @type {?} */
DataTableBodyComponent.prototype._columns;
/** @type {?} */
DataTableBodyComponent.prototype._rowCount;
/** @type {?} */
DataTableBodyComponent.prototype._offset;
/** @type {?} */
DataTableBodyComponent.prototype._pageSize;
/**
* Get the height of the detail row.
* @type {?}
*/
DataTableBodyComponent.prototype.getDetailRowHeight;
/**
* @type {?}
* @private
*/
DataTableBodyComponent.prototype.cd;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableHeaderComponent {
/**
* @param {?} cd
*/
constructor(cd) {
this.cd = cd;
this.sort = new EventEmitter();
this.reorder = new EventEmitter();
this.resize = new EventEmitter();
this.select = new EventEmitter();
this.columnContextmenu = new EventEmitter(false);
this._columnGroupWidths = {
total: 100
};
this._styleByGroup = {
left: {},
center: {},
right: {}
};
this.destroyed = false;
}
/**
* @param {?} val
* @return {?}
*/
set innerWidth(val) {
this._innerWidth = val;
setTimeout((/**
* @return {?}
*/
() => {
if (this._columns) {
/** @type {?} */
const colByPin = columnsByPin(this._columns);
this._columnGroupWidths = columnGroupWidths(colByPin, this._columns);
this.setStylesByGroup();
}
}));
}
/**
* @return {?}
*/
get innerWidth() {
return this._innerWidth;
}
/**
* @param {?} val
* @return {?}
*/
set headerHeight(val) {
if (val !== 'auto') {
this._headerHeight = `${val}px`;
}
else {
this._headerHeight = val;
}
}
/**
* @return {?}
*/
get headerHeight() {
return this._headerHeight;
}
/**
* @param {?} val
* @return {?}
*/
set columns(val) {
this._columns = val;
/** @type {?} */
const colsByPin = columnsByPin(val);
this._columnsByPin = columnsByPinArr(val);
setTimeout((/**
* @return {?}
*/
() => {
this._columnGroupWidths = columnGroupWidths(colsByPin, val);
this.setStylesByGroup();
}));
}
/**
* @return {?}
*/
get columns() {
return this._columns;
}
/**
* @param {?} val
* @return {?}
*/
set offsetX(val) {
this._offsetX = val;
this.setStylesByGroup();
}
/**
* @return {?}
*/
get offsetX() {
return this._offsetX;
}
/**
* @return {?}
*/
ngOnDestroy() {
this.destroyed = true;
}
/**
* @param {?} __0
* @return {?}
*/
onLongPressStart({ event, model }) {
model.dragging = true;
this.dragEventTarget = event;
}
/**
* @param {?} __0
* @return {?}
*/
onLongPressEnd({ event, model }) {
this.dragEventTarget = event;
// delay resetting so sort can be
// prevented if we were dragging
setTimeout((/**
* @return {?}
*/
() => {
// datatable component creates copies from columns on reorder
// set dragging to false on new objects
/** @type {?} */
const column = this._columns.find((/**
* @param {?} c
* @return {?}
*/
c => c.$$id === model.$$id));
if (column) {
column.dragging = false;
}
}), 5);
}
/**
* @return {?}
*/
get headerWidth() {
if (this.scrollbarH) {
return this.innerWidth + 'px';
}
return '100%';
}
/**
* @param {?} index
* @param {?} colGroup
* @return {?}
*/
trackByGroups(index, colGroup) {
return colGroup.type;
}
/**
* @param {?} index
* @param {?} column
* @return {?}
*/
columnTrackingFn(index, column) {
return column.$$id;
}
/**
* @param {?} width
* @param {?} column
* @return {?}
*/
onColumnResized(width, column) {
if (width <= column.minWidth) {
width = column.minWidth;
}
else if (width >= column.maxWidth) {
width = column.maxWidth;
}
this.resize.emit({
column,
prevValue: column.width,
newValue: width
});
}
/**
* @param {?} __0
* @return {?}
*/
onColumnReordered({ prevIndex, newIndex, model }) {
/** @type {?} */
const column = this.getColumn(newIndex);
column.isTarget = false;
column.targetMarkerContext = undefined;
this.reorder.emit({
column: model,
prevValue: prevIndex,
newValue: newIndex
});
}
/**
* @param {?} __0
* @return {?}
*/
onTargetChanged({ prevIndex, newIndex, initialIndex }) {
if (prevIndex || prevIndex === 0) {
/** @type {?} */
const oldColumn = this.getColumn(prevIndex);
oldColumn.isTarget = false;
oldColumn.targetMarkerContext = undefined;
}
if (newIndex || newIndex === 0) {
/** @type {?} */
const newColumn = this.getColumn(newIndex);
newColumn.isTarget = true;
if (initialIndex !== newIndex) {
newColumn.targetMarkerContext = {
class: 'targetMarker '.concat(initialIndex > newIndex ? 'dragFromRight' : 'dragFromLeft')
};
}
}
}
/**
* @param {?} index
* @return {?}
*/
getColumn(index) {
/** @type {?} */
const leftColumnCount = this._columnsByPin[0].columns.length;
if (index < leftColumnCount) {
return this._columnsByPin[0].columns[index];
}
/** @type {?} */
const centerColumnCount = this._columnsByPin[1].columns.length;
if (index < leftColumnCount + centerColumnCount) {
return this._columnsByPin[1].columns[index - leftColumnCount];
}
return this._columnsByPin[2].columns[index - leftColumnCount - centerColumnCount];
}
/**
* @param {?} __0
* @return {?}
*/
onSort({ column, prevValue, newValue }) {
// if we are dragging don't sort!
if (column.dragging) {
return;
}
/** @type {?} */
const sorts = this.calcNewSorts(column, prevValue, newValue);
this.sort.emit({
sorts,
column,
prevValue,
newValue
});
}
/**
* @param {?} column
* @param {?} prevValue
* @param {?} newValue
* @return {?}
*/
calcNewSorts(column, prevValue, newValue) {
/** @type {?} */
let idx = 0;
if (!this.sorts) {
this.sorts = [];
}
/** @type {?} */
const sorts = this.sorts.map((/**
* @param {?} s
* @param {?} i
* @return {?}
*/
(s, i) => {
s = Object.assign({}, s);
if (s.prop === column.prop) {
idx = i;
}
return s;
}));
if (newValue === undefined) {
sorts.splice(idx, 1);
}
else if (prevValue) {
sorts[idx].dir = newValue;
}
else {
if (this.sortType === SortType.single) {
sorts.splice(0, this.sorts.length);
}
sorts.push({ dir: newValue, prop: column.prop });
}
return sorts;
}
/**
* @return {?}
*/
setStylesByGroup() {
this._styleByGroup.left = this.calcStylesByGroup('left');
this._styleByGroup.center = this.calcStylesByGroup('center');
this._styleByGroup.right = this.calcStylesByGroup('right');
if (!this.destroyed) {
this.cd.detectChanges();
}
}
/**
* @param {?} group
* @return {?}
*/
calcStylesByGroup(group) {
/** @type {?} */
const widths = this._columnGroupWidths;
/** @type {?} */
const offsetX = this.offsetX;
/** @type {?} */
const styles = {
width: `${widths[group]}px`
};
if (group === 'center') {
translateXY(styles, offsetX * -1, 0);
}
else if (group === 'right') {
/** @type {?} */
const totalDiff = widths.total - this.innerWidth;
/** @type {?} */
const offset = totalDiff * -1;
translateXY(styles, offset, 0);
}
return styles;
}
}
DataTableHeaderComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-header',
template: `
`,
host: {
class: 'datatable-header'
},
changeDetection: ChangeDetectionStrategy.OnPush
}] }
];
/** @nocollapse */
DataTableHeaderComponent.ctorParameters = () => [
{ type: ChangeDetectorRef }
];
DataTableHeaderComponent.propDecorators = {
sortAscendingIcon: [{ type: Input }],
sortDescendingIcon: [{ type: Input }],
scrollbarH: [{ type: Input }],
dealsWithGroup: [{ type: Input }],
targetMarkerTemplate: [{ type: Input }],
innerWidth: [{ type: Input }],
sorts: [{ type: Input }],
sortType: [{ type: Input }],
allRowsSelected: [{ type: Input }],
selectionType: [{ type: Input }],
reorderable: [{ type: Input }],
headerHeight: [{ type: HostBinding, args: ['style.height',] }, { type: Input }],
columns: [{ type: Input }],
offsetX: [{ type: Input }],
sort: [{ type: Output }],
reorder: [{ type: Output }],
resize: [{ type: Output }],
select: [{ type: Output }],
columnContextmenu: [{ type: Output }],
headerWidth: [{ type: HostBinding, args: ['style.width',] }]
};
if (false) {
/** @type {?} */
DataTableHeaderComponent.prototype.sortAscendingIcon;
/** @type {?} */
DataTableHeaderComponent.prototype.sortDescendingIcon;
/** @type {?} */
DataTableHeaderComponent.prototype.scrollbarH;
/** @type {?} */
DataTableHeaderComponent.prototype.dealsWithGroup;
/** @type {?} */
DataTableHeaderComponent.prototype.targetMarkerTemplate;
/** @type {?} */
DataTableHeaderComponent.prototype.targetMarkerContext;
/** @type {?} */
DataTableHeaderComponent.prototype.sorts;
/** @type {?} */
DataTableHeaderComponent.prototype.sortType;
/** @type {?} */
DataTableHeaderComponent.prototype.allRowsSelected;
/** @type {?} */
DataTableHeaderComponent.prototype.selectionType;
/** @type {?} */
DataTableHeaderComponent.prototype.reorderable;
/** @type {?} */
DataTableHeaderComponent.prototype.dragEventTarget;
/** @type {?} */
DataTableHeaderComponent.prototype.sort;
/** @type {?} */
DataTableHeaderComponent.prototype.reorder;
/** @type {?} */
DataTableHeaderComponent.prototype.resize;
/** @type {?} */
DataTableHeaderComponent.prototype.select;
/** @type {?} */
DataTableHeaderComponent.prototype.columnContextmenu;
/** @type {?} */
DataTableHeaderComponent.prototype._columnsByPin;
/** @type {?} */
DataTableHeaderComponent.prototype._columnGroupWidths;
/** @type {?} */
DataTableHeaderComponent.prototype._innerWidth;
/** @type {?} */
DataTableHeaderComponent.prototype._offsetX;
/** @type {?} */
DataTableHeaderComponent.prototype._columns;
/** @type {?} */
DataTableHeaderComponent.prototype._headerHeight;
/** @type {?} */
DataTableHeaderComponent.prototype._styleByGroup;
/**
* @type {?}
* @private
*/
DataTableHeaderComponent.prototype.destroyed;
/**
* @type {?}
* @private
*/
DataTableHeaderComponent.prototype.cd;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Throttle a function
* @param {?} func
* @param {?} wait
* @param {?=} options
* @return {?}
*/
function throttle(func, wait, options) {
options = options || {};
/** @type {?} */
let context;
/** @type {?} */
let args;
/** @type {?} */
let result;
/** @type {?} */
let timeout = null;
/** @type {?} */
let previous = 0;
/**
* @return {?}
*/
function later() {
previous = options.leading === false ? 0 : +new Date();
timeout = null;
result = func.apply(context, args);
}
return (/**
* @this {?}
* @return {?}
*/
function () {
/** @type {?} */
const now = +new Date();
if (!previous && options.leading === false) {
previous = now;
}
/** @type {?} */
const remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
clearTimeout(timeout);
timeout = null;
previous = now;
result = func.apply(context, args);
}
else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
});
}
/**
* Throttle decorator
*
* class MyClass {
* throttleable(10)
* myFn() { ... }
* }
* @param {?} duration
* @param {?=} options
* @return {?}
*/
function throttleable(duration, options) {
return (/**
* @param {?} target
* @param {?} key
* @param {?} descriptor
* @return {?}
*/
function innerDecorator(target, key, descriptor) {
return {
configurable: true,
enumerable: descriptor.enumerable,
get: (/**
* @return {?}
*/
function getter() {
Object.defineProperty(this, key, {
configurable: true,
enumerable: descriptor.enumerable,
value: throttle(descriptor.value, duration, options)
});
return this[key];
})
};
});
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Calculates the Total Flex Grow
* @param {?} columns
* @return {?}
*/
function getTotalFlexGrow(columns) {
/** @type {?} */
let totalFlexGrow = 0;
for (const c of columns) {
totalFlexGrow += c.flexGrow || 0;
}
return totalFlexGrow;
}
/**
* Adjusts the column widths.
* Inspired by: https://github.com/facebook/fixed-data-table/blob/master/src/FixedDataTableWidthHelper.js
* @param {?} allColumns
* @param {?} expectedWidth
* @return {?}
*/
function adjustColumnWidths(allColumns, expectedWidth) {
/** @type {?} */
const columnsWidth = columnsTotalWidth(allColumns);
/** @type {?} */
const totalFlexGrow = getTotalFlexGrow(allColumns);
/** @type {?} */
const colsByGroup = columnsByPin(allColumns);
if (columnsWidth !== expectedWidth) {
scaleColumns(colsByGroup, expectedWidth, totalFlexGrow);
}
}
/**
* Resizes columns based on the flexGrow property, while respecting manually set widths
* @param {?} colsByGroup
* @param {?} maxWidth
* @param {?} totalFlexGrow
* @return {?}
*/
function scaleColumns(colsByGroup, maxWidth, totalFlexGrow) {
// calculate total width and flexgrow points for coulumns that can be resized
for (const attr in colsByGroup) {
for (const column of colsByGroup[attr]) {
if (!column.canAutoResize) {
maxWidth -= column.width;
totalFlexGrow -= column.flexGrow ? column.flexGrow : 0;
}
else {
column.width = 0;
}
}
}
/** @type {?} */
const hasMinWidth = {};
/** @type {?} */
let remainingWidth = maxWidth;
// resize columns until no width is left to be distributed
do {
/** @type {?} */
const widthPerFlexPoint = remainingWidth / totalFlexGrow;
remainingWidth = 0;
for (const attr in colsByGroup) {
for (const column of colsByGroup[attr]) {
// if the column can be resize and it hasn't reached its minimum width yet
if (column.canAutoResize && !hasMinWidth[column.prop]) {
/** @type {?} */
const newWidth = column.width + column.flexGrow * widthPerFlexPoint;
if (column.minWidth !== undefined && newWidth < column.minWidth) {
remainingWidth += newWidth - column.minWidth;
column.width = column.minWidth;
hasMinWidth[column.prop] = true;
}
else {
column.width = newWidth;
}
}
}
}
} while (remainingWidth !== 0);
}
/**
* Forces the width of the columns to
* distribute equally but overflowing when necessary
*
* Rules:
*
* - If combined withs are less than the total width of the grid,
* proportion the widths given the min / max / normal widths to fill the width.
*
* - If the combined widths, exceed the total width of the grid,
* use the standard widths.
*
* - If a column is resized, it should always use that width
*
* - The proportional widths should never fall below min size if specified.
*
* - If the grid starts off small but then becomes greater than the size ( + / - )
* the width should use the original width; not the newly proportioned widths.
* @param {?} allColumns
* @param {?} expectedWidth
* @param {?} startIdx
* @param {?} allowBleed
* @param {?=} defaultColWidth
* @return {?}
*/
function forceFillColumnWidths(allColumns, expectedWidth, startIdx, allowBleed, defaultColWidth = 300) {
/** @type {?} */
const columnsToResize = allColumns.slice(startIdx + 1, allColumns.length).filter((/**
* @param {?} c
* @return {?}
*/
c => {
return c.canAutoResize !== false;
}));
for (const column of columnsToResize) {
if (!column.$$oldWidth) {
column.$$oldWidth = column.width;
}
}
/** @type {?} */
let additionWidthPerColumn = 0;
/** @type {?} */
let exceedsWindow = false;
/** @type {?} */
let contentWidth = getContentWidth(allColumns, defaultColWidth);
/** @type {?} */
let remainingWidth = expectedWidth - contentWidth;
/** @type {?} */
const columnsProcessed = [];
/** @type {?} */
const remainingWidthLimit = 1;
// This loop takes care of the
do {
additionWidthPerColumn = remainingWidth / columnsToResize.length;
exceedsWindow = contentWidth >= expectedWidth;
for (const column of columnsToResize) {
if (exceedsWindow && allowBleed) {
column.width = column.$$oldWidth || column.width || defaultColWidth;
}
else {
/** @type {?} */
const newSize = (column.width || defaultColWidth) + additionWidthPerColumn;
if (column.minWidth && newSize < column.minWidth) {
column.width = column.minWidth;
columnsProcessed.push(column);
}
else if (column.maxWidth && newSize > column.maxWidth) {
column.width = column.maxWidth;
columnsProcessed.push(column);
}
else {
column.width = newSize;
}
}
column.width = Math.max(0, column.width);
}
contentWidth = getContentWidth(allColumns);
remainingWidth = expectedWidth - contentWidth;
removeProcessedColumns(columnsToResize, columnsProcessed);
} while (remainingWidth > remainingWidthLimit && columnsToResize.length !== 0);
}
/**
* Remove the processed columns from the current active columns.
* @param {?} columnsToResize
* @param {?} columnsProcessed
* @return {?}
*/
function removeProcessedColumns(columnsToResize, columnsProcessed) {
for (const column of columnsProcessed) {
/** @type {?} */
const index = columnsToResize.indexOf(column);
columnsToResize.splice(index, 1);
}
}
/**
* Gets the width of the columns
* @param {?} allColumns
* @param {?=} defaultColWidth
* @return {?}
*/
function getContentWidth(allColumns, defaultColWidth = 300) {
/** @type {?} */
let contentWidth = 0;
for (const column of allColumns) {
contentWidth += column.width || defaultColWidth;
}
return contentWidth;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {string} */
const SortDirection = {
asc: 'asc',
desc: 'desc',
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Gets the next sort direction
* @param {?} sortType
* @param {?} current
* @return {?}
*/
function nextSortDir(sortType, current) {
if (sortType === SortType.single) {
if (current === SortDirection.asc) {
return SortDirection.desc;
}
else {
return SortDirection.asc;
}
}
else {
if (!current) {
return SortDirection.asc;
}
else if (current === SortDirection.asc) {
return SortDirection.desc;
}
else if (current === SortDirection.desc) {
return undefined;
}
// avoid TS7030: Not all code paths return a value.
return undefined;
}
}
/**
* Adapted from fueld-ui on 6/216
* https://github.com/FuelInteractive/fuel-ui/tree/master/src/pipes/OrderBy
* @param {?} a
* @param {?} b
* @return {?}
*/
function orderByComparator(a, b) {
if (a === null || typeof a === 'undefined')
a = 0;
if (b === null || typeof b === 'undefined')
b = 0;
if (a instanceof Date && b instanceof Date) {
if (a < b)
return -1;
if (a > b)
return 1;
}
else if (isNaN(parseFloat(a)) || !isFinite(a) || (isNaN(parseFloat(b)) || !isFinite(b))) {
// Convert to string in case of a=0 or b=0
a = String(a);
b = String(b);
// Isn't a number so lowercase the string to properly compare
if (a.toLowerCase() < b.toLowerCase())
return -1;
if (a.toLowerCase() > b.toLowerCase())
return 1;
}
else {
// Parse strings as numbers to compare properly
if (parseFloat(a) < parseFloat(b))
return -1;
if (parseFloat(a) > parseFloat(b))
return 1;
}
// equal each other
return 0;
}
/**
* creates a shallow copy of the `rows` input and returns the sorted copy. this function
* does not sort the `rows` argument in place
* @param {?} rows
* @param {?} columns
* @param {?} dirs
* @return {?}
*/
function sortRows(rows, columns, dirs) {
if (!rows)
return [];
if (!dirs || !dirs.length || !columns)
return [...rows];
/**
* record the row ordering of results from prior sort operations (if applicable)
* this is necessary to guarantee stable sorting behavior
* @type {?}
*/
const rowToIndexMap = new Map();
rows.forEach((/**
* @param {?} row
* @param {?} index
* @return {?}
*/
(row, index) => rowToIndexMap.set(row, index)));
/** @type {?} */
const temp = [...rows];
/** @type {?} */
const cols = columns.reduce((/**
* @param {?} obj
* @param {?} col
* @return {?}
*/
(obj, col) => {
if (col.comparator && typeof col.comparator === 'function') {
obj[col.prop] = col.comparator;
}
return obj;
}), {});
// cache valueGetter and compareFn so that they
// do not need to be looked-up in the sort function body
/** @type {?} */
const cachedDirs = dirs.map((/**
* @param {?} dir
* @return {?}
*/
dir => {
/** @type {?} */
const prop = dir.prop;
return {
prop,
dir: dir.dir,
valueGetter: getterForProp(prop),
compareFn: cols[prop] || orderByComparator
};
}));
return temp.sort((/**
* @param {?} rowA
* @param {?} rowB
* @return {?}
*/
function (rowA, rowB) {
for (const cachedDir of cachedDirs) {
// Get property and valuegetters for column to be sorted
const { prop, valueGetter } = cachedDir;
// Get A and B cell values from rows based on properties of the columns
/** @type {?} */
const propA = valueGetter(rowA, prop);
/** @type {?} */
const propB = valueGetter(rowB, prop);
// Compare function gets five parameters:
// Two cell values to be compared as propA and propB
// Two rows corresponding to the cells as rowA and rowB
// Direction of the sort for this column as SortDirection
// Compare can be a standard JS comparison function (a,b) => -1|0|1
// as additional parameters are silently ignored. The whole row and sort
// direction enable more complex sort logic.
/** @type {?} */
const comparison = cachedDir.dir !== SortDirection.desc
? cachedDir.compareFn(propA, propB, rowA, rowB, cachedDir.dir)
: -cachedDir.compareFn(propA, propB, rowA, rowB, cachedDir.dir);
// Don't return 0 yet in case of needing to sort by next property
if (comparison !== 0)
return comparison;
}
if (!(rowToIndexMap.has(rowA) && rowToIndexMap.has(rowB)))
return 0;
/**
* all else being equal, preserve original order of the rows (stable sort)
*/
return rowToIndexMap.get(rowA) < rowToIndexMap.get(rowB) ? -1 : 1;
}));
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DatatableComponent {
/**
* @param {?} scrollbarHelper
* @param {?} dimensionsHelper
* @param {?} cd
* @param {?} element
* @param {?} differs
* @param {?} columnChangesService
* @param {?} configuration
*/
constructor(scrollbarHelper, dimensionsHelper, cd, element, differs, columnChangesService, configuration) {
this.scrollbarHelper = scrollbarHelper;
this.dimensionsHelper = dimensionsHelper;
this.cd = cd;
this.columnChangesService = columnChangesService;
this.configuration = configuration;
/**
* List of row objects that should be
* represented as selected in the grid.
* Default value: `[]`
*/
this.selected = [];
/**
* Enable vertical scrollbars
*/
this.scrollbarV = false;
/**
* Enable horz scrollbars
*/
this.scrollbarH = false;
/**
* The row height; which is necessary
* to calculate the height for the lazy rendering.
*/
this.rowHeight = 30;
/**
* Type of column width distribution formula.
* Example: flex, force, standard
*/
this.columnMode = ColumnMode.standard;
/**
* The minimum header height in pixels.
* Pass a falsey for no header
*/
this.headerHeight = 30;
/**
* The minimum footer height in pixels.
* Pass falsey for no footer
*/
this.footerHeight = 0;
/**
* If the table should use external paging
* otherwise its assumed that all data is preloaded.
*/
this.externalPaging = false;
/**
* If the table should use external sorting or
* the built-in basic sorting.
*/
this.externalSorting = false;
/**
* Show the linear loading bar.
* Default value: `false`
*/
this.loadingIndicator = false;
/**
* Enable/Disable ability to re-order columns
* by dragging them.
*/
this.reorderable = true;
/**
* Swap columns on re-order columns or
* move them.
*/
this.swapColumns = true;
/**
* The type of sorting
*/
this.sortType = SortType.single;
/**
* Array of sorted columns by property and type.
* Default value: `[]`
*/
this.sorts = [];
/**
* Css class overrides
*/
this.cssClasses = {
sortAscending: 'datatable-icon-up',
sortDescending: 'datatable-icon-down',
pagerLeftArrow: 'datatable-icon-left',
pagerRightArrow: 'datatable-icon-right',
pagerPrevious: 'datatable-icon-prev',
pagerNext: 'datatable-icon-skip'
};
/**
* Message overrides for localization
*
* emptyMessage [default] = 'No data to display'
* totalMessage [default] = 'total'
* selectedMessage [default] = 'selected'
*/
this.messages = {
// Message to show when array is presented
// but contains no values
emptyMessage: 'No data to display',
// Footer total message
totalMessage: 'total',
// Footer selected message
selectedMessage: 'selected'
};
/**
* A boolean you can use to set the detault behaviour of rows and groups
* whether they will start expanded or not. If ommited the default is NOT expanded.
*
*/
this.groupExpansionDefault = false;
/**
* Property to which you can use for determining select all
* rows on current page or not.
*
* \@memberOf DatatableComponent
*/
this.selectAllRowsOnPage = false;
/**
* A flag for row virtualization on / off
*/
this.virtualization = true;
/**
* A flag for switching summary row on / off
*/
this.summaryRow = false;
/**
* A height of summary row
*/
this.summaryHeight = 30;
/**
* A property holds a summary row position: top/bottom
*/
this.summaryPosition = 'top';
/**
* Body was scrolled typically in a `scrollbarV:true` scenario.
*/
this.scroll = new EventEmitter();
/**
* A cell or row was focused via keyboard or mouse click.
*/
this.activate = new EventEmitter();
/**
* A cell or row was selected.
*/
this.select = new EventEmitter();
/**
* Column sort was invoked.
*/
this.sort = new EventEmitter();
/**
* The table was paged either triggered by the pager or the body scroll.
*/
this.page = new EventEmitter();
/**
* Columns were re-ordered.
*/
this.reorder = new EventEmitter();
/**
* Column was resized.
*/
this.resize = new EventEmitter();
/**
* The context menu was invoked on the table.
* type indicates whether the header or the body was clicked.
* content contains either the column or the row that was clicked.
*/
this.tableContextmenu = new EventEmitter(false);
/**
* A row was expanded ot collapsed for tree
*/
this.treeAction = new EventEmitter();
this.rowCount = 0;
this._offsetX = new BehaviorSubject(0);
this._count = 0;
this._offset = 0;
this._subscriptions = [];
/**
* This will be used when displaying or selecting rows.
* when tracking/comparing them, we'll use the value of this fn,
*
* (`fn(x) === fn(y)` instead of `x === y`)
*/
this.rowIdentity = (/**
* @param {?} x
* @return {?}
*/
(x) => {
if (this._groupRowsBy) {
// each group in groupedRows are stored as {key, value: [rows]},
// where key is the groupRowsBy index
return x.key;
}
else {
return x;
}
});
// get ref to elm for measuring
this.element = element.nativeElement;
this.rowDiffer = differs.find({}).create();
// apply global settings from Module.forRoot
if (this.configuration && this.configuration.messages) {
this.messages = Object.assign({}, this.configuration.messages);
}
}
/**
* Rows that are displayed in the table.
* @param {?} val
* @return {?}
*/
set rows(val) {
this._rows = val;
if (val) {
this._internalRows = [...val];
}
// auto sort on new updates
if (!this.externalSorting) {
this.sortInternalRows();
}
// auto group by parent on new update
this._internalRows = groupRowsByParents(this._internalRows, optionalGetterForProp(this.treeFromRelation), optionalGetterForProp(this.treeToRelation));
// recalculate sizes/etc
this.recalculate();
if (this._rows && this._groupRowsBy) {
// If a column has been specified in _groupRowsBy created a new array with the data grouped by that row
this.groupedRows = this.groupArrayBy(this._rows, this._groupRowsBy);
}
this.cd.markForCheck();
}
/**
* Gets the rows.
* @return {?}
*/
get rows() {
return this._rows;
}
/**
* This attribute allows the user to set the name of the column to group the data with
* @param {?} val
* @return {?}
*/
set groupRowsBy(val) {
if (val) {
this._groupRowsBy = val;
if (this._rows && this._groupRowsBy) {
// cretes a new array with the data grouped
this.groupedRows = this.groupArrayBy(this._rows, this._groupRowsBy);
}
}
}
/**
* @return {?}
*/
get groupRowsBy() {
return this._groupRowsBy;
}
/**
* Columns to be displayed.
* @param {?} val
* @return {?}
*/
set columns(val) {
if (val) {
this._internalColumns = [...val];
setColumnDefaults(this._internalColumns);
this.recalculateColumns();
}
this._columns = val;
}
/**
* Get the columns.
* @return {?}
*/
get columns() {
return this._columns;
}
/**
* The page size to be shown.
* Default value: `undefined`
* @param {?} val
* @return {?}
*/
set limit(val) {
this._limit = val;
// recalculate sizes/etc
this.recalculate();
}
/**
* Gets the limit.
* @return {?}
*/
get limit() {
return this._limit;
}
/**
* The total count of all rows.
* Default value: `0`
* @param {?} val
* @return {?}
*/
set count(val) {
this._count = val;
// recalculate sizes/etc
this.recalculate();
}
/**
* Gets the count.
* @return {?}
*/
get count() {
return this._count;
}
/**
* The current offset ( page - 1 ) shown.
* Default value: `0`
* @param {?} val
* @return {?}
*/
set offset(val) {
this._offset = val;
}
/**
* @return {?}
*/
get offset() {
return Math.max(Math.min(this._offset, Math.ceil(this.rowCount / this.pageSize) - 1), 0);
}
/**
* CSS class applied if the header height if fixed height.
* @return {?}
*/
get isFixedHeader() {
/** @type {?} */
const headerHeight = this.headerHeight;
return typeof headerHeight === 'string' ? (/** @type {?} */ (headerHeight)) !== 'auto' : true;
}
/**
* CSS class applied to the root element if
* the row heights are fixed heights.
* @return {?}
*/
get isFixedRow() {
return this.rowHeight !== 'auto';
}
/**
* CSS class applied to root element if
* vertical scrolling is enabled.
* @return {?}
*/
get isVertScroll() {
return this.scrollbarV;
}
/**
* CSS class applied to root element if
* virtualization is enabled.
* @return {?}
*/
get isVirtualized() {
return this.virtualization;
}
/**
* CSS class applied to the root element
* if the horziontal scrolling is enabled.
* @return {?}
*/
get isHorScroll() {
return this.scrollbarH;
}
/**
* CSS class applied to root element is selectable.
* @return {?}
*/
get isSelectable() {
return this.selectionType !== undefined;
}
/**
* CSS class applied to root is checkbox selection.
* @return {?}
*/
get isCheckboxSelection() {
return this.selectionType === SelectionType.checkbox;
}
/**
* CSS class applied to root if cell selection.
* @return {?}
*/
get isCellSelection() {
return this.selectionType === SelectionType.cell;
}
/**
* CSS class applied to root if single select.
* @return {?}
*/
get isSingleSelection() {
return this.selectionType === SelectionType.single;
}
/**
* CSS class added to root element if mulit select
* @return {?}
*/
get isMultiSelection() {
return this.selectionType === SelectionType.multi;
}
/**
* CSS class added to root element if mulit click select
* @return {?}
*/
get isMultiClickSelection() {
return this.selectionType === SelectionType.multiClick;
}
/**
* Column templates gathered from `ContentChildren`
* if described in your markup.
* @param {?} val
* @return {?}
*/
set columnTemplates(val) {
this._columnTemplates = val;
this.translateColumns(val);
}
/**
* Returns the column templates.
* @return {?}
*/
get columnTemplates() {
return this._columnTemplates;
}
/**
* Returns if all rows are selected.
* @return {?}
*/
get allRowsSelected() {
/** @type {?} */
let allRowsSelected = this.rows && this.selected && this.selected.length === this.rows.length;
if (this.selectAllRowsOnPage) {
/** @type {?} */
const indexes = this.bodyComponent.indexes;
/** @type {?} */
const rowsOnPage = indexes.last - indexes.first;
allRowsSelected = this.selected.length === rowsOnPage;
}
return this.selected && this.rows && this.rows.length !== 0 && allRowsSelected;
}
/**
* Lifecycle hook that is called after data-bound
* properties of a directive are initialized.
* @return {?}
*/
ngOnInit() {
// need to call this immediatly to size
// if the table is hidden the visibility
// listener will invoke this itself upon show
this.recalculate();
}
/**
* Lifecycle hook that is called after a component's
* view has been fully initialized.
* @return {?}
*/
ngAfterViewInit() {
if (!this.externalSorting) {
this.sortInternalRows();
}
// this has to be done to prevent the change detection
// tree from freaking out because we are readjusting
if (typeof requestAnimationFrame === 'undefined') {
return;
}
requestAnimationFrame((/**
* @return {?}
*/
() => {
this.recalculate();
// emit page for virtual server-side kickoff
if (this.externalPaging && this.scrollbarV) {
this.page.emit({
count: this.count,
pageSize: this.pageSize,
limit: this.limit,
offset: 0
});
}
}));
}
/**
* Lifecycle hook that is called after a component's
* content has been fully initialized.
* @return {?}
*/
ngAfterContentInit() {
this.columnTemplates.changes.subscribe((/**
* @param {?} v
* @return {?}
*/
v => this.translateColumns(v)));
this.listenForColumnInputChanges();
}
/**
* Translates the templates to the column objects
* @param {?} val
* @return {?}
*/
translateColumns(val) {
if (val) {
/** @type {?} */
const arr = val.toArray();
if (arr.length) {
this._internalColumns = translateTemplates(arr);
setColumnDefaults(this._internalColumns);
this.recalculateColumns();
this.sortInternalRows();
this.cd.markForCheck();
}
}
}
/**
* Creates a map with the data grouped by the user choice of grouping index
*
* @param {?} originalArray the original array passed via parameter
* @param {?} groupBy
* @return {?}
*/
groupArrayBy(originalArray, groupBy) {
// create a map to hold groups with their corresponding results
/** @type {?} */
const map = new Map();
/** @type {?} */
let i = 0;
originalArray.forEach((/**
* @param {?} item
* @return {?}
*/
(item) => {
/** @type {?} */
const key = item[groupBy];
if (!map.has(key)) {
map.set(key, [item]);
}
else {
map.get(key).push(item);
}
i++;
}));
/** @type {?} */
const addGroup = (/**
* @param {?} key
* @param {?} value
* @return {?}
*/
(key, value) => {
return { key, value };
});
// convert map back to a simple array of objects
return Array.from(map, (/**
* @param {?} x
* @return {?}
*/
x => addGroup(x[0], x[1])));
}
/*
* Lifecycle hook that is called when Angular dirty checks a directive.
*/
/**
* @return {?}
*/
ngDoCheck() {
if (this.rowDiffer.diff(this.rows)) {
if (!this.externalSorting) {
this.sortInternalRows();
}
else {
this._internalRows = [...this.rows];
}
// auto group by parent on new update
this._internalRows = groupRowsByParents(this._internalRows, optionalGetterForProp(this.treeFromRelation), optionalGetterForProp(this.treeToRelation));
this.recalculatePages();
this.cd.markForCheck();
}
}
/**
* Recalc's the sizes of the grid.
*
* Updated automatically on changes to:
*
* - Columns
* - Rows
* - Paging related
*
* Also can be manually invoked or upon window resize.
* @return {?}
*/
recalculate() {
this.recalculateDims();
this.recalculateColumns();
}
/**
* Window resize handler to update sizes.
* @return {?}
*/
onWindowResize() {
this.recalculate();
}
/**
* Recalulcates the column widths based on column width
* distribution mode and scrollbar offsets.
* @param {?=} columns
* @param {?=} forceIdx
* @param {?=} allowBleed
* @return {?}
*/
recalculateColumns(columns = this._internalColumns, forceIdx = -1, allowBleed = this.scrollbarH) {
if (!columns)
return undefined;
/** @type {?} */
let width = this._innerWidth;
if (this.scrollbarV) {
width = width - this.scrollbarHelper.width;
}
if (this.columnMode === ColumnMode.force) {
forceFillColumnWidths(columns, width, forceIdx, allowBleed);
}
else if (this.columnMode === ColumnMode.flex) {
adjustColumnWidths(columns, width);
}
return columns;
}
/**
* Recalculates the dimensions of the table size.
* Internally calls the page size and row count calcs too.
*
* @return {?}
*/
recalculateDims() {
/** @type {?} */
const dims = this.dimensionsHelper.getDimensions(this.element);
this._innerWidth = Math.floor(dims.width);
if (this.scrollbarV) {
/** @type {?} */
let height = dims.height;
if (this.headerHeight)
height = height - this.headerHeight;
if (this.footerHeight)
height = height - this.footerHeight;
this.bodyHeight = height;
}
this.recalculatePages();
}
/**
* Recalculates the pages after a update.
* @return {?}
*/
recalculatePages() {
this.pageSize = this.calcPageSize();
this.rowCount = this.calcRowCount();
}
/**
* Body triggered a page event.
* @param {?} __0
* @return {?}
*/
onBodyPage({ offset }) {
// Avoid pagination caming from body events like scroll when the table
// has no virtualization and the external paging is enable.
// This means, let's the developer handle pagination by my him(her) self
if (this.externalPaging && !this.virtualization) {
return;
}
this.offset = offset;
this.page.emit({
count: this.count,
pageSize: this.pageSize,
limit: this.limit,
offset: this.offset
});
}
/**
* The body triggered a scroll event.
* @param {?} event
* @return {?}
*/
onBodyScroll(event) {
this._offsetX.next(event.offsetX);
this.scroll.emit(event);
this.cd.detectChanges();
}
/**
* The footer triggered a page event.
* @param {?} event
* @return {?}
*/
onFooterPage(event) {
this.offset = event.page - 1;
this.bodyComponent.updateOffsetY(this.offset);
this.page.emit({
count: this.count,
pageSize: this.pageSize,
limit: this.limit,
offset: this.offset
});
if (this.selectAllRowsOnPage) {
this.selected = [];
this.select.emit({
selected: this.selected
});
}
}
/**
* Recalculates the sizes of the page
* @param {?=} val
* @return {?}
*/
calcPageSize(val = this.rows) {
// Keep the page size constant even if the row has been expanded.
// This is because an expanded row is still considered to be a child of
// the original row. Hence calculation would use rowHeight only.
if (this.scrollbarV && this.virtualization) {
/** @type {?} */
const size = Math.ceil(this.bodyHeight / ((/** @type {?} */ (this.rowHeight))));
return Math.max(size, 0);
}
// if limit is passed, we are paging
if (this.limit !== undefined) {
return this.limit;
}
// otherwise use row length
if (val) {
return val.length;
}
// other empty :(
return 0;
}
/**
* Calculates the row count.
* @param {?=} val
* @return {?}
*/
calcRowCount(val = this.rows) {
if (!this.externalPaging) {
if (!val)
return 0;
if (this.groupedRows) {
return this.groupedRows.length;
}
else if (this.treeFromRelation != null && this.treeToRelation != null) {
return this._internalRows.length;
}
else {
return val.length;
}
}
return this.count;
}
/**
* The header triggered a contextmenu event.
* @param {?} __0
* @return {?}
*/
onColumnContextmenu({ event, column }) {
this.tableContextmenu.emit({ event, type: ContextmenuType.header, content: column });
}
/**
* The body triggered a contextmenu event.
* @param {?} __0
* @return {?}
*/
onRowContextmenu({ event, row }) {
this.tableContextmenu.emit({ event, type: ContextmenuType.body, content: row });
}
/**
* The header triggered a column resize event.
* @param {?} __0
* @return {?}
*/
onColumnResize({ column, newValue }) {
/* Safari/iOS 10.2 workaround */
if (column === undefined) {
return;
}
/** @type {?} */
let idx;
/** @type {?} */
const cols = this._internalColumns.map((/**
* @param {?} c
* @param {?} i
* @return {?}
*/
(c, i) => {
c = Object.assign({}, c);
if (c.$$id === column.$$id) {
idx = i;
c.width = newValue;
// set this so we can force the column
// width distribution to be to this value
c.$$oldWidth = newValue;
}
return c;
}));
this.recalculateColumns(cols, idx);
this._internalColumns = cols;
this.resize.emit({
column,
newValue
});
}
/**
* The header triggered a column re-order event.
* @param {?} __0
* @return {?}
*/
onColumnReorder({ column, newValue, prevValue }) {
/** @type {?} */
const cols = this._internalColumns.map((/**
* @param {?} c
* @return {?}
*/
c => {
return Object.assign({}, c);
}));
if (this.swapColumns) {
/** @type {?} */
const prevCol = cols[newValue];
cols[newValue] = column;
cols[prevValue] = prevCol;
}
else {
if (newValue > prevValue) {
/** @type {?} */
const movedCol = cols[prevValue];
for (let i = prevValue; i < newValue; i++) {
cols[i] = cols[i + 1];
}
cols[newValue] = movedCol;
}
else {
/** @type {?} */
const movedCol = cols[prevValue];
for (let i = prevValue; i > newValue; i--) {
cols[i] = cols[i - 1];
}
cols[newValue] = movedCol;
}
}
this._internalColumns = cols;
this.reorder.emit({
column,
newValue,
prevValue
});
}
/**
* The header triggered a column sort event.
* @param {?} event
* @return {?}
*/
onColumnSort(event) {
// clean selected rows
if (this.selectAllRowsOnPage) {
this.selected = [];
this.select.emit({
selected: this.selected
});
}
this.sorts = event.sorts;
// this could be optimized better since it will resort
// the rows again on the 'push' detection...
if (this.externalSorting === false) {
// don't use normal setter so we don't resort
this.sortInternalRows();
}
// auto group by parent on new update
this._internalRows = groupRowsByParents(this._internalRows, optionalGetterForProp(this.treeFromRelation), optionalGetterForProp(this.treeToRelation));
// Always go to first page when sorting to see the newly sorted data
this.offset = 0;
this.bodyComponent.updateOffsetY(this.offset);
this.sort.emit(event);
}
/**
* Toggle all row selection
* @param {?} event
* @return {?}
*/
onHeaderSelect(event) {
if (this.selectAllRowsOnPage) {
// before we splice, chk if we currently have all selected
/** @type {?} */
const first = this.bodyComponent.indexes.first;
/** @type {?} */
const last = this.bodyComponent.indexes.last;
/** @type {?} */
const allSelected = this.selected.length === last - first;
// remove all existing either way
this.selected = [];
// do the opposite here
if (!allSelected) {
this.selected.push(...this._internalRows.slice(first, last));
}
}
else {
// before we splice, chk if we currently have all selected
/** @type {?} */
const allSelected = this.selected.length === this.rows.length;
// remove all existing either way
this.selected = [];
// do the opposite here
if (!allSelected) {
this.selected.push(...this.rows);
}
}
this.select.emit({
selected: this.selected
});
}
/**
* A row was selected from body
* @param {?} event
* @return {?}
*/
onBodySelect(event) {
this.select.emit(event);
}
/**
* A row was expanded or collapsed for tree
* @param {?} event
* @return {?}
*/
onTreeAction(event) {
/** @type {?} */
const row = event.row;
// TODO: For duplicated items this will not work
/** @type {?} */
const rowIndex = this._rows.findIndex((/**
* @param {?} r
* @return {?}
*/
r => r[this.treeToRelation] === event.row[this.treeToRelation]));
this.treeAction.emit({ row, rowIndex });
}
/**
* @return {?}
*/
ngOnDestroy() {
this._subscriptions.forEach((/**
* @param {?} subscription
* @return {?}
*/
subscription => subscription.unsubscribe()));
}
/**
* listen for changes to input bindings of all DataTableColumnDirective and
* trigger the columnTemplates.changes observable to emit
* @private
* @return {?}
*/
listenForColumnInputChanges() {
this._subscriptions.push(this.columnChangesService.columnInputChanges$.subscribe((/**
* @return {?}
*/
() => {
if (this.columnTemplates) {
this.columnTemplates.notifyOnChanges();
}
})));
}
/**
* @private
* @return {?}
*/
sortInternalRows() {
this._internalRows = sortRows(this._internalRows, this._internalColumns, this.sorts);
}
}
DatatableComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-datatable',
template: "\n \n \n \n \n \n \n
\n",
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
class: 'ngx-datatable'
},
styles: [".ngx-datatable{display:block;overflow:hidden;justify-content:center;position:relative;-webkit-transform:translate3d(0,0,0)}.ngx-datatable [hidden]{display:none!important}.ngx-datatable *,.ngx-datatable :after,.ngx-datatable :before{box-sizing:border-box}.ngx-datatable.scroll-vertical .datatable-body{overflow-y:auto}.ngx-datatable.scroll-vertical.virtualized .datatable-body .datatable-row-wrapper{position:absolute}.ngx-datatable.scroll-horz .datatable-body{overflow-x:auto;-webkit-overflow-scrolling:touch}.ngx-datatable.fixed-header .datatable-header .datatable-header-inner{white-space:nowrap}.ngx-datatable.fixed-header .datatable-header .datatable-header-inner .datatable-header-cell{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ngx-datatable.fixed-row .datatable-scroll,.ngx-datatable.fixed-row .datatable-scroll .datatable-body-row{white-space:nowrap}.ngx-datatable.fixed-row .datatable-scroll .datatable-body-row .datatable-body-cell,.ngx-datatable.fixed-row .datatable-scroll .datatable-body-row .datatable-body-group-cell{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ngx-datatable .datatable-body-row,.ngx-datatable .datatable-header-inner,.ngx-datatable .datatable-row-center{display:flex;flex-direction:row;-o-flex-flow:row;flex-flow:row}.ngx-datatable .datatable-body-cell,.ngx-datatable .datatable-header-cell{overflow-x:hidden;vertical-align:top;display:inline-block;line-height:1.625}.ngx-datatable .datatable-body-cell:focus,.ngx-datatable .datatable-header-cell:focus{outline:0}.ngx-datatable .datatable-row-left,.ngx-datatable .datatable-row-right{z-index:9}.ngx-datatable .datatable-row-center,.ngx-datatable .datatable-row-group,.ngx-datatable .datatable-row-left,.ngx-datatable .datatable-row-right{position:relative}.ngx-datatable .datatable-header{display:block;overflow:hidden}.ngx-datatable .datatable-header .datatable-header-inner{align-items:stretch;-webkit-align-items:stretch}.ngx-datatable .datatable-header .datatable-header-cell{position:relative;display:inline-block}.ngx-datatable .datatable-header .datatable-header-cell.sortable .datatable-header-cell-wrapper{cursor:pointer}.ngx-datatable .datatable-header .datatable-header-cell.longpress .datatable-header-cell-wrapper{cursor:move}.ngx-datatable .datatable-header .datatable-header-cell .sort-btn{line-height:100%;vertical-align:middle;display:inline-block;cursor:pointer}.ngx-datatable .datatable-header .datatable-header-cell .resize-handle,.ngx-datatable .datatable-header .datatable-header-cell .resize-handle--not-resizable{display:inline-block;position:absolute;right:0;top:0;bottom:0;width:5px;padding:0 4px;visibility:hidden}.ngx-datatable .datatable-header .datatable-header-cell .resize-handle{cursor:ew-resize}.ngx-datatable .datatable-header .datatable-header-cell.resizeable:hover .resize-handle,.ngx-datatable .datatable-header .datatable-header-cell:hover .resize-handle--not-resizable{visibility:visible}.ngx-datatable .datatable-header .datatable-header-cell .targetMarker{position:absolute;top:0;bottom:0}.ngx-datatable .datatable-header .datatable-header-cell .targetMarker.dragFromLeft{right:0}.ngx-datatable .datatable-header .datatable-header-cell .targetMarker.dragFromRight{left:0}.ngx-datatable .datatable-header .datatable-header-cell .datatable-header-cell-template-wrap{height:inherit}.ngx-datatable .datatable-body{position:relative;z-index:10;display:block}.ngx-datatable .datatable-body .datatable-scroll{display:inline-block}.ngx-datatable .datatable-body .datatable-row-detail{overflow-y:hidden}.ngx-datatable .datatable-body .datatable-row-wrapper{display:flex;flex-direction:column}.ngx-datatable .datatable-body .datatable-body-row{outline:0}.ngx-datatable .datatable-body .datatable-body-row>div{display:flex}.ngx-datatable .datatable-footer{display:block;width:100%;overflow:auto}.ngx-datatable .datatable-footer .datatable-footer-inner{display:flex;align-items:center;width:100%}.ngx-datatable .datatable-footer .selected-count .page-count{flex:1 1 40%}.ngx-datatable .datatable-footer .selected-count .datatable-pager{flex:1 1 60%}.ngx-datatable .datatable-footer .page-count{flex:1 1 20%}.ngx-datatable .datatable-footer .datatable-pager{flex:1 1 80%;text-align:right}.ngx-datatable .datatable-footer .datatable-pager .pager,.ngx-datatable .datatable-footer .datatable-pager .pager li{padding:0;margin:0;display:inline-block;list-style:none}.ngx-datatable .datatable-footer .datatable-pager .pager li,.ngx-datatable .datatable-footer .datatable-pager .pager li a{outline:0}.ngx-datatable .datatable-footer .datatable-pager .pager li a{cursor:pointer;display:inline-block}.ngx-datatable .datatable-footer .datatable-pager .pager li.disabled a{cursor:not-allowed}"]
}] }
];
/** @nocollapse */
DatatableComponent.ctorParameters = () => [
{ type: ScrollbarHelper, decorators: [{ type: SkipSelf }] },
{ type: DimensionsHelper, decorators: [{ type: SkipSelf }] },
{ type: ChangeDetectorRef },
{ type: ElementRef },
{ type: KeyValueDiffers },
{ type: ColumnChangesService },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: ['configuration',] }] }
];
DatatableComponent.propDecorators = {
targetMarkerTemplate: [{ type: Input }],
rows: [{ type: Input }],
groupRowsBy: [{ type: Input }],
groupedRows: [{ type: Input }],
columns: [{ type: Input }],
selected: [{ type: Input }],
scrollbarV: [{ type: Input }],
scrollbarH: [{ type: Input }],
rowHeight: [{ type: Input }],
columnMode: [{ type: Input }],
headerHeight: [{ type: Input }],
footerHeight: [{ type: Input }],
externalPaging: [{ type: Input }],
externalSorting: [{ type: Input }],
limit: [{ type: Input }],
count: [{ type: Input }],
offset: [{ type: Input }],
loadingIndicator: [{ type: Input }],
selectionType: [{ type: Input }],
reorderable: [{ type: Input }],
swapColumns: [{ type: Input }],
sortType: [{ type: Input }],
sorts: [{ type: Input }],
cssClasses: [{ type: Input }],
messages: [{ type: Input }],
rowClass: [{ type: Input }],
selectCheck: [{ type: Input }],
displayCheck: [{ type: Input }],
groupExpansionDefault: [{ type: Input }],
trackByProp: [{ type: Input }],
selectAllRowsOnPage: [{ type: Input }],
virtualization: [{ type: Input }],
treeFromRelation: [{ type: Input }],
treeToRelation: [{ type: Input }],
summaryRow: [{ type: Input }],
summaryHeight: [{ type: Input }],
summaryPosition: [{ type: Input }],
scroll: [{ type: Output }],
activate: [{ type: Output }],
select: [{ type: Output }],
sort: [{ type: Output }],
page: [{ type: Output }],
reorder: [{ type: Output }],
resize: [{ type: Output }],
tableContextmenu: [{ type: Output }],
treeAction: [{ type: Output }],
isFixedHeader: [{ type: HostBinding, args: ['class.fixed-header',] }],
isFixedRow: [{ type: HostBinding, args: ['class.fixed-row',] }],
isVertScroll: [{ type: HostBinding, args: ['class.scroll-vertical',] }],
isVirtualized: [{ type: HostBinding, args: ['class.virtualized',] }],
isHorScroll: [{ type: HostBinding, args: ['class.scroll-horz',] }],
isSelectable: [{ type: HostBinding, args: ['class.selectable',] }],
isCheckboxSelection: [{ type: HostBinding, args: ['class.checkbox-selection',] }],
isCellSelection: [{ type: HostBinding, args: ['class.cell-selection',] }],
isSingleSelection: [{ type: HostBinding, args: ['class.single-selection',] }],
isMultiSelection: [{ type: HostBinding, args: ['class.multi-selection',] }],
isMultiClickSelection: [{ type: HostBinding, args: ['class.multi-click-selection',] }],
columnTemplates: [{ type: ContentChildren, args: [DataTableColumnDirective,] }],
rowDetail: [{ type: ContentChild, args: [DatatableRowDetailDirective, { static: false },] }],
groupHeader: [{ type: ContentChild, args: [DatatableGroupHeaderDirective, { static: false },] }],
footer: [{ type: ContentChild, args: [DatatableFooterDirective, { static: false },] }],
bodyComponent: [{ type: ViewChild, args: [DataTableBodyComponent, { static: false },] }],
headerComponent: [{ type: ViewChild, args: [DataTableHeaderComponent, { static: false },] }],
rowIdentity: [{ type: Input }],
onWindowResize: [{ type: HostListener, args: ['window:resize',] }]
};
__decorate([
throttleable(5),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], DatatableComponent.prototype, "onWindowResize", null);
if (false) {
/**
* Template for the target marker of drag target columns.
* @type {?}
*/
DatatableComponent.prototype.targetMarkerTemplate;
/**
* This attribute allows the user to set a grouped array in the following format:
* [
* {groupid=1} [
* {id=1 name="test1"},
* {id=2 name="test2"},
* {id=3 name="test3"}
* ]},
* {groupid=2>[
* {id=4 name="test4"},
* {id=5 name="test5"},
* {id=6 name="test6"}
* ]}
* ]
* @type {?}
*/
DatatableComponent.prototype.groupedRows;
/**
* List of row objects that should be
* represented as selected in the grid.
* Default value: `[]`
* @type {?}
*/
DatatableComponent.prototype.selected;
/**
* Enable vertical scrollbars
* @type {?}
*/
DatatableComponent.prototype.scrollbarV;
/**
* Enable horz scrollbars
* @type {?}
*/
DatatableComponent.prototype.scrollbarH;
/**
* The row height; which is necessary
* to calculate the height for the lazy rendering.
* @type {?}
*/
DatatableComponent.prototype.rowHeight;
/**
* Type of column width distribution formula.
* Example: flex, force, standard
* @type {?}
*/
DatatableComponent.prototype.columnMode;
/**
* The minimum header height in pixels.
* Pass a falsey for no header
* @type {?}
*/
DatatableComponent.prototype.headerHeight;
/**
* The minimum footer height in pixels.
* Pass falsey for no footer
* @type {?}
*/
DatatableComponent.prototype.footerHeight;
/**
* If the table should use external paging
* otherwise its assumed that all data is preloaded.
* @type {?}
*/
DatatableComponent.prototype.externalPaging;
/**
* If the table should use external sorting or
* the built-in basic sorting.
* @type {?}
*/
DatatableComponent.prototype.externalSorting;
/**
* Show the linear loading bar.
* Default value: `false`
* @type {?}
*/
DatatableComponent.prototype.loadingIndicator;
/**
* Type of row selection. Options are:
*
* - `single`
* - `multi`
* - `checkbox`
* - `multiClick`
* - `cell`
*
* For no selection pass a `falsey`.
* Default value: `undefined`
* @type {?}
*/
DatatableComponent.prototype.selectionType;
/**
* Enable/Disable ability to re-order columns
* by dragging them.
* @type {?}
*/
DatatableComponent.prototype.reorderable;
/**
* Swap columns on re-order columns or
* move them.
* @type {?}
*/
DatatableComponent.prototype.swapColumns;
/**
* The type of sorting
* @type {?}
*/
DatatableComponent.prototype.sortType;
/**
* Array of sorted columns by property and type.
* Default value: `[]`
* @type {?}
*/
DatatableComponent.prototype.sorts;
/**
* Css class overrides
* @type {?}
*/
DatatableComponent.prototype.cssClasses;
/**
* Message overrides for localization
*
* emptyMessage [default] = 'No data to display'
* totalMessage [default] = 'total'
* selectedMessage [default] = 'selected'
* @type {?}
*/
DatatableComponent.prototype.messages;
/**
* Row specific classes.
* Similar implementation to ngClass.
*
* [rowClass]="'first second'"
* [rowClass]="{ 'first': true, 'second': true, 'third': false }"
* @type {?}
*/
DatatableComponent.prototype.rowClass;
/**
* A boolean/function you can use to check whether you want
* to select a particular row based on a criteria. Example:
*
* (selection) => {
* return selection !== 'Ethel Price';
* }
* @type {?}
*/
DatatableComponent.prototype.selectCheck;
/**
* A function you can use to check whether you want
* to show the checkbox for a particular row based on a criteria. Example:
*
* (row, column, value) => {
* return row.name !== 'Ethel Price';
* }
* @type {?}
*/
DatatableComponent.prototype.displayCheck;
/**
* A boolean you can use to set the detault behaviour of rows and groups
* whether they will start expanded or not. If ommited the default is NOT expanded.
*
* @type {?}
*/
DatatableComponent.prototype.groupExpansionDefault;
/**
* Property to which you can use for custom tracking of rows.
* Example: 'name'
* @type {?}
*/
DatatableComponent.prototype.trackByProp;
/**
* Property to which you can use for determining select all
* rows on current page or not.
*
* \@memberOf DatatableComponent
* @type {?}
*/
DatatableComponent.prototype.selectAllRowsOnPage;
/**
* A flag for row virtualization on / off
* @type {?}
*/
DatatableComponent.prototype.virtualization;
/**
* Tree from relation
* @type {?}
*/
DatatableComponent.prototype.treeFromRelation;
/**
* Tree to relation
* @type {?}
*/
DatatableComponent.prototype.treeToRelation;
/**
* A flag for switching summary row on / off
* @type {?}
*/
DatatableComponent.prototype.summaryRow;
/**
* A height of summary row
* @type {?}
*/
DatatableComponent.prototype.summaryHeight;
/**
* A property holds a summary row position: top/bottom
* @type {?}
*/
DatatableComponent.prototype.summaryPosition;
/**
* Body was scrolled typically in a `scrollbarV:true` scenario.
* @type {?}
*/
DatatableComponent.prototype.scroll;
/**
* A cell or row was focused via keyboard or mouse click.
* @type {?}
*/
DatatableComponent.prototype.activate;
/**
* A cell or row was selected.
* @type {?}
*/
DatatableComponent.prototype.select;
/**
* Column sort was invoked.
* @type {?}
*/
DatatableComponent.prototype.sort;
/**
* The table was paged either triggered by the pager or the body scroll.
* @type {?}
*/
DatatableComponent.prototype.page;
/**
* Columns were re-ordered.
* @type {?}
*/
DatatableComponent.prototype.reorder;
/**
* Column was resized.
* @type {?}
*/
DatatableComponent.prototype.resize;
/**
* The context menu was invoked on the table.
* type indicates whether the header or the body was clicked.
* content contains either the column or the row that was clicked.
* @type {?}
*/
DatatableComponent.prototype.tableContextmenu;
/**
* A row was expanded ot collapsed for tree
* @type {?}
*/
DatatableComponent.prototype.treeAction;
/**
* Row Detail templates gathered from the ContentChild
* @type {?}
*/
DatatableComponent.prototype.rowDetail;
/**
* Group Header templates gathered from the ContentChild
* @type {?}
*/
DatatableComponent.prototype.groupHeader;
/**
* Footer template gathered from the ContentChild
* @type {?}
*/
DatatableComponent.prototype.footer;
/**
* Reference to the body component for manually
* invoking functions on the body.
* @type {?}
*/
DatatableComponent.prototype.bodyComponent;
/**
* Reference to the header component for manually
* invoking functions on the header.
*
* \@memberOf DatatableComponent
* @type {?}
*/
DatatableComponent.prototype.headerComponent;
/** @type {?} */
DatatableComponent.prototype.element;
/** @type {?} */
DatatableComponent.prototype._innerWidth;
/** @type {?} */
DatatableComponent.prototype.pageSize;
/** @type {?} */
DatatableComponent.prototype.bodyHeight;
/** @type {?} */
DatatableComponent.prototype.rowCount;
/** @type {?} */
DatatableComponent.prototype.rowDiffer;
/** @type {?} */
DatatableComponent.prototype._offsetX;
/** @type {?} */
DatatableComponent.prototype._limit;
/** @type {?} */
DatatableComponent.prototype._count;
/** @type {?} */
DatatableComponent.prototype._offset;
/** @type {?} */
DatatableComponent.prototype._rows;
/** @type {?} */
DatatableComponent.prototype._groupRowsBy;
/** @type {?} */
DatatableComponent.prototype._internalRows;
/** @type {?} */
DatatableComponent.prototype._internalColumns;
/** @type {?} */
DatatableComponent.prototype._columns;
/** @type {?} */
DatatableComponent.prototype._columnTemplates;
/** @type {?} */
DatatableComponent.prototype._subscriptions;
/**
* This will be used when displaying or selecting rows.
* when tracking/comparing them, we'll use the value of this fn,
*
* (`fn(x) === fn(y)` instead of `x === y`)
* @type {?}
*/
DatatableComponent.prototype.rowIdentity;
/**
* @type {?}
* @private
*/
DatatableComponent.prototype.scrollbarHelper;
/**
* @type {?}
* @private
*/
DatatableComponent.prototype.dimensionsHelper;
/**
* @type {?}
* @private
*/
DatatableComponent.prototype.cd;
/**
* @type {?}
* @private
*/
DatatableComponent.prototype.columnChangesService;
/**
* @type {?}
* @private
*/
DatatableComponent.prototype.configuration;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableHeaderCellComponent {
/**
* @param {?} cd
*/
constructor(cd) {
this.cd = cd;
this.sort = new EventEmitter();
this.select = new EventEmitter();
this.columnContextmenu = new EventEmitter(false);
this.sortFn = this.onSort.bind(this);
this.selectFn = this.select.emit.bind(this.select);
this.cellContext = {
column: this.column,
sortDir: this.sortDir,
sortFn: this.sortFn,
allRowsSelected: this.allRowsSelected,
selectFn: this.selectFn
};
}
/**
* @param {?} value
* @return {?}
*/
set allRowsSelected(value) {
this._allRowsSelected = value;
this.cellContext.allRowsSelected = value;
}
/**
* @return {?}
*/
get allRowsSelected() {
return this._allRowsSelected;
}
/**
* @param {?} column
* @return {?}
*/
set column(column) {
this._column = column;
this.cellContext.column = column;
this.cd.markForCheck();
}
/**
* @return {?}
*/
get column() {
return this._column;
}
/**
* @param {?} val
* @return {?}
*/
set sorts(val) {
this._sorts = val;
this.sortDir = this.calcSortDir(val);
this.cellContext.sortDir = this.sortDir;
this.sortClass = this.calcSortClass(this.sortDir);
this.cd.markForCheck();
}
/**
* @return {?}
*/
get sorts() {
return this._sorts;
}
/**
* @return {?}
*/
get columnCssClasses() {
/** @type {?} */
let cls = 'datatable-header-cell';
if (this.column.sortable)
cls += ' sortable';
if (this.column.resizeable)
cls += ' resizeable';
if (this.column.headerClass) {
if (typeof this.column.headerClass === 'string') {
cls += ' ' + this.column.headerClass;
}
else if (typeof this.column.headerClass === 'function') {
/** @type {?} */
const res = this.column.headerClass({
column: this.column
});
if (typeof res === 'string') {
cls += res;
}
else if (typeof res === 'object') {
/** @type {?} */
const keys = Object.keys(res);
for (const k of keys) {
if (res[k] === true)
cls += ` ${k}`;
}
}
}
}
/** @type {?} */
const sortDir = this.sortDir;
if (sortDir) {
cls += ` sort-active sort-${sortDir}`;
}
return cls;
}
/**
* @return {?}
*/
get name() {
// guaranteed to have a value by setColumnDefaults() in column-helper.ts
return this.column.headerTemplate === undefined ? this.column.name : undefined;
}
/**
* @return {?}
*/
get minWidth() {
return this.column.minWidth;
}
/**
* @return {?}
*/
get maxWidth() {
return this.column.maxWidth;
}
/**
* @return {?}
*/
get width() {
return this.column.width;
}
/**
* @return {?}
*/
get isCheckboxable() {
return this.column.checkboxable && this.column.headerCheckboxable && this.selectionType === SelectionType.checkbox;
}
/**
* @param {?} $event
* @return {?}
*/
onContextmenu($event) {
this.columnContextmenu.emit({ event: $event, column: this.column });
}
/**
* @param {?} sorts
* @return {?}
*/
calcSortDir(sorts) {
if (sorts && this.column) {
/** @type {?} */
const sort = sorts.find((/**
* @param {?} s
* @return {?}
*/
(s) => {
return s.prop === this.column.prop;
}));
if (sort)
return sort.dir;
}
}
/**
* @return {?}
*/
onSort() {
if (!this.column.sortable)
return;
/** @type {?} */
const newValue = nextSortDir(this.sortType, this.sortDir);
this.sort.emit({
column: this.column,
prevValue: this.sortDir,
newValue
});
}
/**
* @param {?} sortDir
* @return {?}
*/
calcSortClass(sortDir) {
if (sortDir === SortDirection.asc) {
return `sort-btn sort-asc ${this.sortAscendingIcon}`;
}
else if (sortDir === SortDirection.desc) {
return `sort-btn sort-desc ${this.sortDescendingIcon}`;
}
else {
return `sort-btn`;
}
}
}
DataTableHeaderCellComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-header-cell',
template: `
`,
host: {
class: 'datatable-header-cell'
},
changeDetection: ChangeDetectionStrategy.OnPush
}] }
];
/** @nocollapse */
DataTableHeaderCellComponent.ctorParameters = () => [
{ type: ChangeDetectorRef }
];
DataTableHeaderCellComponent.propDecorators = {
sortType: [{ type: Input }],
sortAscendingIcon: [{ type: Input }],
sortDescendingIcon: [{ type: Input }],
isTarget: [{ type: Input }],
targetMarkerTemplate: [{ type: Input }],
targetMarkerContext: [{ type: Input }],
allRowsSelected: [{ type: Input }],
selectionType: [{ type: Input }],
column: [{ type: Input }],
headerHeight: [{ type: HostBinding, args: ['style.height.px',] }, { type: Input }],
sorts: [{ type: Input }],
sort: [{ type: Output }],
select: [{ type: Output }],
columnContextmenu: [{ type: Output }],
columnCssClasses: [{ type: HostBinding, args: ['class',] }],
name: [{ type: HostBinding, args: ['attr.title',] }],
minWidth: [{ type: HostBinding, args: ['style.minWidth.px',] }],
maxWidth: [{ type: HostBinding, args: ['style.maxWidth.px',] }],
width: [{ type: HostBinding, args: ['style.width.px',] }],
onContextmenu: [{ type: HostListener, args: ['contextmenu', ['$event'],] }]
};
if (false) {
/** @type {?} */
DataTableHeaderCellComponent.prototype.sortType;
/** @type {?} */
DataTableHeaderCellComponent.prototype.sortAscendingIcon;
/** @type {?} */
DataTableHeaderCellComponent.prototype.sortDescendingIcon;
/** @type {?} */
DataTableHeaderCellComponent.prototype.isTarget;
/** @type {?} */
DataTableHeaderCellComponent.prototype.targetMarkerTemplate;
/** @type {?} */
DataTableHeaderCellComponent.prototype.targetMarkerContext;
/** @type {?} */
DataTableHeaderCellComponent.prototype._allRowsSelected;
/** @type {?} */
DataTableHeaderCellComponent.prototype.selectionType;
/** @type {?} */
DataTableHeaderCellComponent.prototype.headerHeight;
/** @type {?} */
DataTableHeaderCellComponent.prototype.sort;
/** @type {?} */
DataTableHeaderCellComponent.prototype.select;
/** @type {?} */
DataTableHeaderCellComponent.prototype.columnContextmenu;
/** @type {?} */
DataTableHeaderCellComponent.prototype.sortFn;
/** @type {?} */
DataTableHeaderCellComponent.prototype.sortClass;
/** @type {?} */
DataTableHeaderCellComponent.prototype.sortDir;
/** @type {?} */
DataTableHeaderCellComponent.prototype.selectFn;
/** @type {?} */
DataTableHeaderCellComponent.prototype.cellContext;
/**
* @type {?}
* @private
*/
DataTableHeaderCellComponent.prototype._column;
/**
* @type {?}
* @private
*/
DataTableHeaderCellComponent.prototype._sorts;
/**
* @type {?}
* @private
*/
DataTableHeaderCellComponent.prototype.cd;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableFooterComponent {
constructor() {
this.selectedCount = 0;
this.page = new EventEmitter();
}
/**
* @return {?}
*/
get isVisible() {
return this.rowCount / this.pageSize > 1;
}
/**
* @return {?}
*/
get curPage() {
return this.offset + 1;
}
}
DataTableFooterComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-footer',
template: `
`,
host: {
class: 'datatable-footer'
},
changeDetection: ChangeDetectionStrategy.OnPush
}] }
];
DataTableFooterComponent.propDecorators = {
footerHeight: [{ type: Input }],
rowCount: [{ type: Input }],
pageSize: [{ type: Input }],
offset: [{ type: Input }],
pagerLeftArrowIcon: [{ type: Input }],
pagerRightArrowIcon: [{ type: Input }],
pagerPreviousIcon: [{ type: Input }],
pagerNextIcon: [{ type: Input }],
totalMessage: [{ type: Input }],
footerTemplate: [{ type: Input }],
selectedCount: [{ type: Input }],
selectedMessage: [{ type: Input }],
page: [{ type: Output }]
};
if (false) {
/** @type {?} */
DataTableFooterComponent.prototype.footerHeight;
/** @type {?} */
DataTableFooterComponent.prototype.rowCount;
/** @type {?} */
DataTableFooterComponent.prototype.pageSize;
/** @type {?} */
DataTableFooterComponent.prototype.offset;
/** @type {?} */
DataTableFooterComponent.prototype.pagerLeftArrowIcon;
/** @type {?} */
DataTableFooterComponent.prototype.pagerRightArrowIcon;
/** @type {?} */
DataTableFooterComponent.prototype.pagerPreviousIcon;
/** @type {?} */
DataTableFooterComponent.prototype.pagerNextIcon;
/** @type {?} */
DataTableFooterComponent.prototype.totalMessage;
/** @type {?} */
DataTableFooterComponent.prototype.footerTemplate;
/** @type {?} */
DataTableFooterComponent.prototype.selectedCount;
/** @type {?} */
DataTableFooterComponent.prototype.selectedMessage;
/** @type {?} */
DataTableFooterComponent.prototype.page;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTablePagerComponent {
constructor() {
this.change = new EventEmitter();
this._count = 0;
this._page = 1;
this._size = 0;
}
/**
* @param {?} val
* @return {?}
*/
set size(val) {
this._size = val;
this.pages = this.calcPages();
}
/**
* @return {?}
*/
get size() {
return this._size;
}
/**
* @param {?} val
* @return {?}
*/
set count(val) {
this._count = val;
this.pages = this.calcPages();
}
/**
* @return {?}
*/
get count() {
return this._count;
}
/**
* @param {?} val
* @return {?}
*/
set page(val) {
this._page = val;
this.pages = this.calcPages();
}
/**
* @return {?}
*/
get page() {
return this._page;
}
/**
* @return {?}
*/
get totalPages() {
/** @type {?} */
const count = this.size < 1 ? 1 : Math.ceil(this.count / this.size);
return Math.max(count || 0, 1);
}
/**
* @return {?}
*/
canPrevious() {
return this.page > 1;
}
/**
* @return {?}
*/
canNext() {
return this.page < this.totalPages;
}
/**
* @return {?}
*/
prevPage() {
this.selectPage(this.page - 1);
}
/**
* @return {?}
*/
nextPage() {
this.selectPage(this.page + 1);
}
/**
* @param {?} page
* @return {?}
*/
selectPage(page) {
if (page > 0 && page <= this.totalPages && page !== this.page) {
this.page = page;
this.change.emit({
page
});
}
}
/**
* @param {?=} page
* @return {?}
*/
calcPages(page) {
/** @type {?} */
const pages = [];
/** @type {?} */
let startPage = 1;
/** @type {?} */
let endPage = this.totalPages;
/** @type {?} */
const maxSize = 5;
/** @type {?} */
const isMaxSized = maxSize < this.totalPages;
page = page || this.page;
if (isMaxSized) {
startPage = page - Math.floor(maxSize / 2);
endPage = page + Math.floor(maxSize / 2);
if (startPage < 1) {
startPage = 1;
endPage = Math.min(startPage + maxSize - 1, this.totalPages);
}
else if (endPage > this.totalPages) {
startPage = Math.max(this.totalPages - maxSize + 1, 1);
endPage = this.totalPages;
}
}
for (let num = startPage; num <= endPage; num++) {
pages.push({
number: num,
text: (/** @type {?} */ (((/** @type {?} */ (num)))))
});
}
return pages;
}
}
DataTablePagerComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-pager',
template: `
`,
host: {
class: 'datatable-pager'
},
changeDetection: ChangeDetectionStrategy.OnPush
}] }
];
DataTablePagerComponent.propDecorators = {
pagerLeftArrowIcon: [{ type: Input }],
pagerRightArrowIcon: [{ type: Input }],
pagerPreviousIcon: [{ type: Input }],
pagerNextIcon: [{ type: Input }],
size: [{ type: Input }],
count: [{ type: Input }],
page: [{ type: Input }],
change: [{ type: Output }]
};
if (false) {
/** @type {?} */
DataTablePagerComponent.prototype.pagerLeftArrowIcon;
/** @type {?} */
DataTablePagerComponent.prototype.pagerRightArrowIcon;
/** @type {?} */
DataTablePagerComponent.prototype.pagerPreviousIcon;
/** @type {?} */
DataTablePagerComponent.prototype.pagerNextIcon;
/** @type {?} */
DataTablePagerComponent.prototype.change;
/** @type {?} */
DataTablePagerComponent.prototype._count;
/** @type {?} */
DataTablePagerComponent.prototype._page;
/** @type {?} */
DataTablePagerComponent.prototype._size;
/** @type {?} */
DataTablePagerComponent.prototype.pages;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class ProgressBarComponent {
}
ProgressBarComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-progress',
template: `
`,
changeDetection: ChangeDetectionStrategy.OnPush
}] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {number} */
const Keys = {
up: 38,
down: 40,
return: 13,
escape: 27,
left: 37,
right: 39,
};
Keys[Keys.up] = 'up';
Keys[Keys.down] = 'down';
Keys[Keys.return] = 'return';
Keys[Keys.escape] = 'escape';
Keys[Keys.left] = 'left';
Keys[Keys.right] = 'right';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableBodyRowComponent {
/**
* @param {?} differs
* @param {?} scrollbarHelper
* @param {?} cd
* @param {?} element
*/
constructor(differs, scrollbarHelper, cd, element) {
this.differs = differs;
this.scrollbarHelper = scrollbarHelper;
this.cd = cd;
this.treeStatus = 'collapsed';
this.activate = new EventEmitter();
this.treeAction = new EventEmitter();
this._groupStyles = {
left: {},
center: {},
right: {}
};
this._element = element.nativeElement;
this._rowDiffer = differs.find({}).create();
}
/**
* @param {?} val
* @return {?}
*/
set columns(val) {
this._columns = val;
this.recalculateColumns(val);
this.buildStylesByGroup();
}
/**
* @return {?}
*/
get columns() {
return this._columns;
}
/**
* @param {?} val
* @return {?}
*/
set innerWidth(val) {
if (this._columns) {
/** @type {?} */
const colByPin = columnsByPin(this._columns);
this._columnGroupWidths = columnGroupWidths(colByPin, this._columns);
}
this._innerWidth = val;
this.recalculateColumns();
this.buildStylesByGroup();
}
/**
* @return {?}
*/
get innerWidth() {
return this._innerWidth;
}
/**
* @param {?} val
* @return {?}
*/
set offsetX(val) {
this._offsetX = val;
this.buildStylesByGroup();
}
/**
* @return {?}
*/
get offsetX() {
return this._offsetX;
}
/**
* @return {?}
*/
get cssClass() {
/** @type {?} */
let cls = 'datatable-body-row';
if (this.isSelected) {
cls += ' active';
}
if (this.rowIndex % 2 !== 0) {
cls += ' datatable-row-odd';
}
if (this.rowIndex % 2 === 0) {
cls += ' datatable-row-even';
}
if (this.rowClass) {
/** @type {?} */
const res = this.rowClass(this.row);
if (typeof res === 'string') {
cls += ` ${res}`;
}
else if (typeof res === 'object') {
/** @type {?} */
const keys = Object.keys(res);
for (const k of keys) {
if (res[k] === true) {
cls += ` ${k}`;
}
}
}
}
return cls;
}
/**
* @return {?}
*/
get columnsTotalWidths() {
return this._columnGroupWidths.total;
}
/**
* @return {?}
*/
ngDoCheck() {
if (this._rowDiffer.diff(this.row)) {
this.cd.markForCheck();
}
}
/**
* @param {?} index
* @param {?} colGroup
* @return {?}
*/
trackByGroups(index, colGroup) {
return colGroup.type;
}
/**
* @param {?} index
* @param {?} column
* @return {?}
*/
columnTrackingFn(index, column) {
return column.$$id;
}
/**
* @return {?}
*/
buildStylesByGroup() {
this._groupStyles.left = this.calcStylesByGroup('left');
this._groupStyles.center = this.calcStylesByGroup('center');
this._groupStyles.right = this.calcStylesByGroup('right');
this.cd.markForCheck();
}
/**
* @param {?} group
* @return {?}
*/
calcStylesByGroup(group) {
/** @type {?} */
const widths = this._columnGroupWidths;
/** @type {?} */
const offsetX = this.offsetX;
/** @type {?} */
const styles = {
width: `${widths[group]}px`
};
if (group === 'left') {
translateXY(styles, offsetX, 0);
}
else if (group === 'right') {
/** @type {?} */
const bodyWidth = parseInt(this.innerWidth + '', 0);
/** @type {?} */
const totalDiff = widths.total - bodyWidth;
/** @type {?} */
const offsetDiff = totalDiff - offsetX;
/** @type {?} */
const offset = (offsetDiff + this.scrollbarHelper.width) * -1;
translateXY(styles, offset, 0);
}
return styles;
}
/**
* @param {?} event
* @param {?} index
* @return {?}
*/
onActivate(event, index) {
event.cellIndex = index;
event.rowElement = this._element;
this.activate.emit(event);
}
/**
* @param {?} event
* @return {?}
*/
onKeyDown(event) {
/** @type {?} */
const keyCode = event.keyCode;
/** @type {?} */
const isTargetRow = event.target === this._element;
/** @type {?} */
const isAction = keyCode === Keys.return ||
keyCode === Keys.down ||
keyCode === Keys.up ||
keyCode === Keys.left ||
keyCode === Keys.right;
if (isAction && isTargetRow) {
event.preventDefault();
event.stopPropagation();
this.activate.emit({
type: 'keydown',
event,
row: this.row,
rowElement: this._element
});
}
}
/**
* @param {?} event
* @return {?}
*/
onMouseenter(event) {
this.activate.emit({
type: 'mouseenter',
event,
row: this.row,
rowElement: this._element
});
}
/**
* @param {?=} val
* @return {?}
*/
recalculateColumns(val = this.columns) {
this._columns = val;
/** @type {?} */
const colsByPin = columnsByPin(this._columns);
this._columnsByPin = columnsByPinArr(this._columns);
this._columnGroupWidths = columnGroupWidths(colsByPin, this._columns);
}
/**
* @return {?}
*/
onTreeAction() {
this.treeAction.emit();
}
}
DataTableBodyRowComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-body-row',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
`
}] }
];
/** @nocollapse */
DataTableBodyRowComponent.ctorParameters = () => [
{ type: KeyValueDiffers },
{ type: ScrollbarHelper, decorators: [{ type: SkipSelf }] },
{ type: ChangeDetectorRef },
{ type: ElementRef }
];
DataTableBodyRowComponent.propDecorators = {
columns: [{ type: Input }],
innerWidth: [{ type: Input }],
expanded: [{ type: Input }],
rowClass: [{ type: Input }],
row: [{ type: Input }],
group: [{ type: Input }],
isSelected: [{ type: Input }],
rowIndex: [{ type: Input }],
displayCheck: [{ type: Input }],
treeStatus: [{ type: Input }],
offsetX: [{ type: Input }],
cssClass: [{ type: HostBinding, args: ['class',] }],
rowHeight: [{ type: HostBinding, args: ['style.height.px',] }, { type: Input }],
columnsTotalWidths: [{ type: HostBinding, args: ['style.width.px',] }],
activate: [{ type: Output }],
treeAction: [{ type: Output }],
onKeyDown: [{ type: HostListener, args: ['keydown', ['$event'],] }],
onMouseenter: [{ type: HostListener, args: ['mouseenter', ['$event'],] }]
};
if (false) {
/** @type {?} */
DataTableBodyRowComponent.prototype.expanded;
/** @type {?} */
DataTableBodyRowComponent.prototype.rowClass;
/** @type {?} */
DataTableBodyRowComponent.prototype.row;
/** @type {?} */
DataTableBodyRowComponent.prototype.group;
/** @type {?} */
DataTableBodyRowComponent.prototype.isSelected;
/** @type {?} */
DataTableBodyRowComponent.prototype.rowIndex;
/** @type {?} */
DataTableBodyRowComponent.prototype.displayCheck;
/** @type {?} */
DataTableBodyRowComponent.prototype.treeStatus;
/** @type {?} */
DataTableBodyRowComponent.prototype.rowHeight;
/** @type {?} */
DataTableBodyRowComponent.prototype.activate;
/** @type {?} */
DataTableBodyRowComponent.prototype.treeAction;
/** @type {?} */
DataTableBodyRowComponent.prototype._element;
/** @type {?} */
DataTableBodyRowComponent.prototype._columnGroupWidths;
/** @type {?} */
DataTableBodyRowComponent.prototype._columnsByPin;
/** @type {?} */
DataTableBodyRowComponent.prototype._offsetX;
/** @type {?} */
DataTableBodyRowComponent.prototype._columns;
/** @type {?} */
DataTableBodyRowComponent.prototype._innerWidth;
/** @type {?} */
DataTableBodyRowComponent.prototype._groupStyles;
/**
* @type {?}
* @private
*/
DataTableBodyRowComponent.prototype._rowDiffer;
/**
* @type {?}
* @private
*/
DataTableBodyRowComponent.prototype.differs;
/**
* @type {?}
* @private
*/
DataTableBodyRowComponent.prototype.scrollbarHelper;
/**
* @type {?}
* @private
*/
DataTableBodyRowComponent.prototype.cd;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableRowWrapperComponent {
/**
* @param {?} cd
* @param {?} differs
*/
constructor(cd, differs) {
this.cd = cd;
this.differs = differs;
this.rowContextmenu = new EventEmitter(false);
this.groupContext = {
group: this.row,
expanded: this.expanded,
rowIndex: this.rowIndex
};
this.rowContext = {
row: this.row,
expanded: this.expanded,
rowIndex: this.rowIndex
};
this._expanded = false;
this.rowDiffer = differs.find({}).create();
}
/**
* @param {?} val
* @return {?}
*/
set rowIndex(val) {
this._rowIndex = val;
this.rowContext.rowIndex = val;
this.groupContext.rowIndex = val;
this.cd.markForCheck();
}
/**
* @return {?}
*/
get rowIndex() {
return this._rowIndex;
}
/**
* @param {?} val
* @return {?}
*/
set expanded(val) {
this._expanded = val;
this.groupContext.expanded = val;
this.rowContext.expanded = val;
this.cd.markForCheck();
}
/**
* @return {?}
*/
get expanded() {
return this._expanded;
}
/**
* @return {?}
*/
ngDoCheck() {
if (this.rowDiffer.diff(this.row)) {
this.rowContext.row = this.row;
this.groupContext.group = this.row;
this.cd.markForCheck();
}
}
/**
* @param {?} $event
* @return {?}
*/
onContextmenu($event) {
this.rowContextmenu.emit({ event: $event, row: this.row });
}
/**
* @return {?}
*/
getGroupHeaderStyle() {
/** @type {?} */
const styles = {};
styles['transform'] = 'translate3d(' + this.offsetX + 'px, 0px, 0px)';
styles['backface-visibility'] = 'hidden';
styles['width'] = this.innerWidth;
return styles;
}
}
DataTableRowWrapperComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-row-wrapper',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
`,
host: {
class: 'datatable-row-wrapper'
}
}] }
];
/** @nocollapse */
DataTableRowWrapperComponent.ctorParameters = () => [
{ type: ChangeDetectorRef },
{ type: KeyValueDiffers }
];
DataTableRowWrapperComponent.propDecorators = {
innerWidth: [{ type: Input }],
rowDetail: [{ type: Input }],
groupHeader: [{ type: Input }],
offsetX: [{ type: Input }],
detailRowHeight: [{ type: Input }],
row: [{ type: Input }],
groupedRows: [{ type: Input }],
rowContextmenu: [{ type: Output }],
rowIndex: [{ type: Input }],
expanded: [{ type: Input }],
onContextmenu: [{ type: HostListener, args: ['contextmenu', ['$event'],] }]
};
if (false) {
/** @type {?} */
DataTableRowWrapperComponent.prototype.innerWidth;
/** @type {?} */
DataTableRowWrapperComponent.prototype.rowDetail;
/** @type {?} */
DataTableRowWrapperComponent.prototype.groupHeader;
/** @type {?} */
DataTableRowWrapperComponent.prototype.offsetX;
/** @type {?} */
DataTableRowWrapperComponent.prototype.detailRowHeight;
/** @type {?} */
DataTableRowWrapperComponent.prototype.row;
/** @type {?} */
DataTableRowWrapperComponent.prototype.groupedRows;
/** @type {?} */
DataTableRowWrapperComponent.prototype.rowContextmenu;
/** @type {?} */
DataTableRowWrapperComponent.prototype.groupContext;
/** @type {?} */
DataTableRowWrapperComponent.prototype.rowContext;
/**
* @type {?}
* @private
*/
DataTableRowWrapperComponent.prototype.rowDiffer;
/**
* @type {?}
* @private
*/
DataTableRowWrapperComponent.prototype._expanded;
/**
* @type {?}
* @private
*/
DataTableRowWrapperComponent.prototype._rowIndex;
/**
* @type {?}
* @private
*/
DataTableRowWrapperComponent.prototype.cd;
/**
* @type {?}
* @private
*/
DataTableRowWrapperComponent.prototype.differs;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class DataTableBodyCellComponent {
/**
* @param {?} element
* @param {?} cd
*/
constructor(element, cd) {
this.cd = cd;
this.activate = new EventEmitter();
this.treeAction = new EventEmitter();
this.isFocused = false;
this.onCheckboxChangeFn = this.onCheckboxChange.bind(this);
this.activateFn = this.activate.emit.bind(this.activate);
this.cellContext = {
onCheckboxChangeFn: this.onCheckboxChangeFn,
activateFn: this.activateFn,
row: this.row,
group: this.group,
value: this.value,
column: this.column,
rowHeight: this.rowHeight,
isSelected: this.isSelected,
rowIndex: this.rowIndex,
treeStatus: this.treeStatus,
onTreeAction: this.onTreeAction.bind(this)
};
this._element = element.nativeElement;
}
/**
* @param {?} group
* @return {?}
*/
set group(group) {
this._group = group;
this.cellContext.group = group;
this.checkValueUpdates();
this.cd.markForCheck();
}
/**
* @return {?}
*/
get group() {
return this._group;
}
/**
* @param {?} val
* @return {?}
*/
set rowHeight(val) {
this._rowHeight = val;
this.cellContext.rowHeight = val;
this.checkValueUpdates();
this.cd.markForCheck();
}
/**
* @return {?}
*/
get rowHeight() {
return this._rowHeight;
}
/**
* @param {?} val
* @return {?}
*/
set isSelected(val) {
this._isSelected = val;
this.cellContext.isSelected = val;
this.cd.markForCheck();
}
/**
* @return {?}
*/
get isSelected() {
return this._isSelected;
}
/**
* @param {?} val
* @return {?}
*/
set expanded(val) {
this._expanded = val;
this.cellContext.expanded = val;
this.cd.markForCheck();
}
/**
* @return {?}
*/
get expanded() {
return this._expanded;
}
/**
* @param {?} val
* @return {?}
*/
set rowIndex(val) {
this._rowIndex = val;
this.cellContext.rowIndex = val;
this.checkValueUpdates();
this.cd.markForCheck();
}
/**
* @return {?}
*/
get rowIndex() {
return this._rowIndex;
}
/**
* @param {?} column
* @return {?}
*/
set column(column) {
this._column = column;
this.cellContext.column = column;
this.checkValueUpdates();
this.cd.markForCheck();
}
/**
* @return {?}
*/
get column() {
return this._column;
}
/**
* @param {?} row
* @return {?}
*/
set row(row) {
this._row = row;
this.cellContext.row = row;
this.checkValueUpdates();
this.cd.markForCheck();
}
/**
* @return {?}
*/
get row() {
return this._row;
}
/**
* @param {?} val
* @return {?}
*/
set sorts(val) {
this._sorts = val;
this.calcSortDir = this.calcSortDir(val);
}
/**
* @return {?}
*/
get sorts() {
return this._sorts;
}
/**
* @param {?} status
* @return {?}
*/
set treeStatus(status) {
if (status !== 'collapsed' && status !== 'expanded' && status !== 'loading' && status !== 'disabled') {
this._treeStatus = 'collapsed';
}
else {
this._treeStatus = status;
}
this.cellContext.treeStatus = this._treeStatus;
this.checkValueUpdates();
this.cd.markForCheck();
}
/**
* @return {?}
*/
get treeStatus() {
return this._treeStatus;
}
/**
* @return {?}
*/
get columnCssClasses() {
/** @type {?} */
let cls = 'datatable-body-cell';
if (this.column.cellClass) {
if (typeof this.column.cellClass === 'string') {
cls += ' ' + this.column.cellClass;
}
else if (typeof this.column.cellClass === 'function') {
/** @type {?} */
const res = this.column.cellClass({
row: this.row,
group: this.group,
column: this.column,
value: this.value,
rowHeight: this.rowHeight
});
if (typeof res === 'string') {
cls += res;
}
else if (typeof res === 'object') {
/** @type {?} */
const keys = Object.keys(res);
for (const k of keys) {
if (res[k] === true) {
cls += ` ${k}`;
}
}
}
}
}
if (!this.sortDir) {
cls += ' sort-active';
}
if (this.isFocused) {
cls += ' active';
}
if (this.sortDir === SortDirection.asc) {
cls += ' sort-asc';
}
if (this.sortDir === SortDirection.desc) {
cls += ' sort-desc';
}
return cls;
}
/**
* @return {?}
*/
get width() {
return this.column.width;
}
/**
* @return {?}
*/
get minWidth() {
return this.column.minWidth;
}
/**
* @return {?}
*/
get maxWidth() {
return this.column.maxWidth;
}
/**
* @return {?}
*/
get height() {
/** @type {?} */
const height = this.rowHeight;
if (isNaN(height)) {
return height;
}
return height + 'px';
}
/**
* @return {?}
*/
ngDoCheck() {
this.checkValueUpdates();
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this.cellTemplate) {
this.cellTemplate.clear();
}
}
/**
* @return {?}
*/
checkValueUpdates() {
/** @type {?} */
let value = '';
if (!this.row || !this.column) {
value = '';
}
else {
/** @type {?} */
const val = this.column.$$valueGetter(this.row, this.column.prop);
/** @type {?} */
const userPipe = this.column.pipe;
if (userPipe) {
value = userPipe.transform(val);
}
else if (value !== undefined) {
value = val;
}
}
if (this.value !== value) {
this.value = value;
this.cellContext.value = value;
this.sanitizedValue = value !== null && value !== undefined ? this.stripHtml(value) : value;
this.cd.markForCheck();
}
}
/**
* @return {?}
*/
onFocus() {
this.isFocused = true;
}
/**
* @return {?}
*/
onBlur() {
this.isFocused = false;
}
/**
* @param {?} event
* @return {?}
*/
onClick(event) {
this.activate.emit({
type: 'click',
event,
row: this.row,
group: this.group,
rowHeight: this.rowHeight,
column: this.column,
value: this.value,
cellElement: this._element
});
}
/**
* @param {?} event
* @return {?}
*/
onDblClick(event) {
this.activate.emit({
type: 'dblclick',
event,
row: this.row,
group: this.group,
rowHeight: this.rowHeight,
column: this.column,
value: this.value,
cellElement: this._element
});
}
/**
* @param {?} event
* @return {?}
*/
onKeyDown(event) {
/** @type {?} */
const keyCode = event.keyCode;
/** @type {?} */
const isTargetCell = event.target === this._element;
/** @type {?} */
const isAction = keyCode === Keys.return ||
keyCode === Keys.down ||
keyCode === Keys.up ||
keyCode === Keys.left ||
keyCode === Keys.right;
if (isAction && isTargetCell) {
event.preventDefault();
event.stopPropagation();
this.activate.emit({
type: 'keydown',
event,
row: this.row,
group: this.group,
rowHeight: this.rowHeight,
column: this.column,
value: this.value,
cellElement: this._element
});
}
}
/**
* @param {?} event
* @return {?}
*/
onCheckboxChange(event) {
this.activate.emit({
type: 'checkbox',
event,
row: this.row,
group: this.group,
rowHeight: this.rowHeight,
column: this.column,
value: this.value,
cellElement: this._element,
treeStatus: 'collapsed'
});
}
/**
* @param {?} sorts
* @return {?}
*/
calcSortDir(sorts) {
if (!sorts) {
return;
}
/** @type {?} */
const sort = sorts.find((/**
* @param {?} s
* @return {?}
*/
(s) => {
return s.prop === this.column.prop;
}));
if (sort) {
return sort.dir;
}
}
/**
* @param {?} html
* @return {?}
*/
stripHtml(html) {
if (!html.replace) {
return html;
}
return html.replace(/<\/?[^>]+(>|$)/g, '');
}
/**
* @return {?}
*/
onTreeAction() {
this.treeAction.emit(this.row);
}
/**
* @param {?} column
* @param {?} row
* @return {?}
*/
calcLeftMargin(column, row) {
/** @type {?} */
const levelIndent = column.treeLevelIndent != null ? column.treeLevelIndent : 50;
return column.isTreeColumn ? row.level * levelIndent : 0;
}
}
DataTableBodyCellComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-body-cell',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
`
}] }
];
/** @nocollapse */
DataTableBodyCellComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: ChangeDetectorRef }
];
DataTableBodyCellComponent.propDecorators = {
displayCheck: [{ type: Input }],
group: [{ type: Input }],
rowHeight: [{ type: Input }],
isSelected: [{ type: Input }],
expanded: [{ type: Input }],
rowIndex: [{ type: Input }],
column: [{ type: Input }],
row: [{ type: Input }],
sorts: [{ type: Input }],
treeStatus: [{ type: Input }],
activate: [{ type: Output }],
treeAction: [{ type: Output }],
cellTemplate: [{ type: ViewChild, args: ['cellTemplate', { read: ViewContainerRef, static: true },] }],
columnCssClasses: [{ type: HostBinding, args: ['class',] }],
width: [{ type: HostBinding, args: ['style.width.px',] }],
minWidth: [{ type: HostBinding, args: ['style.minWidth.px',] }],
maxWidth: [{ type: HostBinding, args: ['style.maxWidth.px',] }],
height: [{ type: HostBinding, args: ['style.height',] }],
onFocus: [{ type: HostListener, args: ['focus',] }],
onBlur: [{ type: HostListener, args: ['blur',] }],
onClick: [{ type: HostListener, args: ['click', ['$event'],] }],
onDblClick: [{ type: HostListener, args: ['dblclick', ['$event'],] }],
onKeyDown: [{ type: HostListener, args: ['keydown', ['$event'],] }]
};
if (false) {
/** @type {?} */
DataTableBodyCellComponent.prototype.displayCheck;
/** @type {?} */
DataTableBodyCellComponent.prototype.activate;
/** @type {?} */
DataTableBodyCellComponent.prototype.treeAction;
/** @type {?} */
DataTableBodyCellComponent.prototype.cellTemplate;
/** @type {?} */
DataTableBodyCellComponent.prototype.sanitizedValue;
/** @type {?} */
DataTableBodyCellComponent.prototype.value;
/** @type {?} */
DataTableBodyCellComponent.prototype.sortDir;
/** @type {?} */
DataTableBodyCellComponent.prototype.isFocused;
/** @type {?} */
DataTableBodyCellComponent.prototype.onCheckboxChangeFn;
/** @type {?} */
DataTableBodyCellComponent.prototype.activateFn;
/** @type {?} */
DataTableBodyCellComponent.prototype.cellContext;
/**
* @type {?}
* @private
*/
DataTableBodyCellComponent.prototype._isSelected;
/**
* @type {?}
* @private
*/
DataTableBodyCellComponent.prototype._sorts;
/**
* @type {?}
* @private
*/
DataTableBodyCellComponent.prototype._column;
/**
* @type {?}
* @private
*/
DataTableBodyCellComponent.prototype._row;
/**
* @type {?}
* @private
*/
DataTableBodyCellComponent.prototype._group;
/**
* @type {?}
* @private
*/
DataTableBodyCellComponent.prototype._rowHeight;
/**
* @type {?}
* @private
*/
DataTableBodyCellComponent.prototype._rowIndex;
/**
* @type {?}
* @private
*/
DataTableBodyCellComponent.prototype._expanded;
/**
* @type {?}
* @private
*/
DataTableBodyCellComponent.prototype._element;
/**
* @type {?}
* @private
*/
DataTableBodyCellComponent.prototype._treeStatus;
/**
* @type {?}
* @private
*/
DataTableBodyCellComponent.prototype.cd;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} selected
* @param {?} row
* @param {?} comparefn
* @return {?}
*/
function selectRows(selected, row, comparefn) {
/** @type {?} */
const selectedIndex = comparefn(row, selected);
if (selectedIndex > -1) {
selected.splice(selectedIndex, 1);
}
else {
selected.push(row);
}
return selected;
}
/**
* @param {?} selected
* @param {?} rows
* @param {?} index
* @param {?} prevIndex
* @param {?} comparefn
* @return {?}
*/
function selectRowsBetween(selected, rows, index, prevIndex, comparefn) {
/** @type {?} */
const reverse = index < prevIndex;
for (let i = 0; i < rows.length; i++) {
/** @type {?} */
const row = rows[i];
/** @type {?} */
const greater = i >= prevIndex && i <= index;
/** @type {?} */
const lesser = i <= prevIndex && i >= index;
/** @type {?} */
let range = { start: 0, end: 0 };
if (reverse) {
range = {
start: index,
end: prevIndex
};
}
else {
range = {
start: prevIndex,
end: index + 1
};
}
if ((reverse && lesser) || (!reverse && greater)) {
// if in the positive range to be added to `selected`, and
// not already in the selected array, add it
if (i >= range.start && i <= range.end) {
selected.push(row);
}
}
}
return selected;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @record
*/
function Model() { }
if (false) {
/** @type {?} */
Model.prototype.type;
/** @type {?} */
Model.prototype.event;
/** @type {?} */
Model.prototype.row;
/** @type {?} */
Model.prototype.rowElement;
/** @type {?} */
Model.prototype.cellElement;
/** @type {?} */
Model.prototype.cellIndex;
}
class DataTableSelectionComponent {
constructor() {
this.activate = new EventEmitter();
this.select = new EventEmitter();
}
/**
* @param {?} event
* @param {?} index
* @param {?} row
* @return {?}
*/
selectRow(event, index, row) {
if (!this.selectEnabled)
return;
/** @type {?} */
const chkbox = this.selectionType === SelectionType.checkbox;
/** @type {?} */
const multi = this.selectionType === SelectionType.multi;
/** @type {?} */
const multiClick = this.selectionType === SelectionType.multiClick;
/** @type {?} */
let selected = [];
if (multi || chkbox || multiClick) {
if (event.shiftKey) {
selected = selectRowsBetween([], this.rows, index, this.prevIndex, this.getRowSelectedIdx.bind(this));
}
else if (event.ctrlKey || event.metaKey || multiClick || chkbox) {
selected = selectRows([...this.selected], row, this.getRowSelectedIdx.bind(this));
}
else {
selected = selectRows([], row, this.getRowSelectedIdx.bind(this));
}
}
else {
selected = selectRows([], row, this.getRowSelectedIdx.bind(this));
}
if (typeof this.selectCheck === 'function') {
selected = selected.filter(this.selectCheck.bind(this));
}
this.selected.splice(0, this.selected.length);
this.selected.push(...selected);
this.prevIndex = index;
this.select.emit({
selected
});
}
/**
* @param {?} model
* @param {?} index
* @return {?}
*/
onActivate(model, index) {
const { type, event, row } = model;
/** @type {?} */
const chkbox = this.selectionType === SelectionType.checkbox;
/** @type {?} */
const select = (!chkbox && (type === 'click' || type === 'dblclick')) || (chkbox && type === 'checkbox');
if (select) {
this.selectRow(event, index, row);
}
else if (type === 'keydown') {
if (((/** @type {?} */ (event))).keyCode === Keys.return) {
this.selectRow(event, index, row);
}
else {
this.onKeyboardFocus(model);
}
}
this.activate.emit(model);
}
/**
* @param {?} model
* @return {?}
*/
onKeyboardFocus(model) {
const { keyCode } = (/** @type {?} */ (model.event));
/** @type {?} */
const shouldFocus = keyCode === Keys.up || keyCode === Keys.down || keyCode === Keys.right || keyCode === Keys.left;
if (shouldFocus) {
/** @type {?} */
const isCellSelection = this.selectionType === SelectionType.cell;
if (!model.cellElement || !isCellSelection) {
this.focusRow(model.rowElement, keyCode);
}
else if (isCellSelection) {
this.focusCell(model.cellElement, model.rowElement, keyCode, model.cellIndex);
}
}
}
/**
* @param {?} rowElement
* @param {?} keyCode
* @return {?}
*/
focusRow(rowElement, keyCode) {
/** @type {?} */
const nextRowElement = this.getPrevNextRow(rowElement, keyCode);
if (nextRowElement)
nextRowElement.focus();
}
/**
* @param {?} rowElement
* @param {?} keyCode
* @return {?}
*/
getPrevNextRow(rowElement, keyCode) {
/** @type {?} */
const parentElement = rowElement.parentElement;
if (parentElement) {
/** @type {?} */
let focusElement;
if (keyCode === Keys.up) {
focusElement = parentElement.previousElementSibling;
}
else if (keyCode === Keys.down) {
focusElement = parentElement.nextElementSibling;
}
if (focusElement && focusElement.children.length) {
return focusElement.children[0];
}
}
}
/**
* @param {?} cellElement
* @param {?} rowElement
* @param {?} keyCode
* @param {?} cellIndex
* @return {?}
*/
focusCell(cellElement, rowElement, keyCode, cellIndex) {
/** @type {?} */
let nextCellElement;
if (keyCode === Keys.left) {
nextCellElement = cellElement.previousElementSibling;
}
else if (keyCode === Keys.right) {
nextCellElement = cellElement.nextElementSibling;
}
else if (keyCode === Keys.up || keyCode === Keys.down) {
/** @type {?} */
const nextRowElement = this.getPrevNextRow(rowElement, keyCode);
if (nextRowElement) {
/** @type {?} */
const children = nextRowElement.getElementsByClassName('datatable-body-cell');
if (children.length)
nextCellElement = children[cellIndex];
}
}
if (nextCellElement)
nextCellElement.focus();
}
/**
* @param {?} row
* @return {?}
*/
getRowSelected(row) {
return this.getRowSelectedIdx(row, this.selected) > -1;
}
/**
* @param {?} row
* @param {?} selected
* @return {?}
*/
getRowSelectedIdx(row, selected) {
if (!selected || !selected.length)
return -1;
/** @type {?} */
const rowId = this.rowIdentity(row);
return selected.findIndex((/**
* @param {?} r
* @return {?}
*/
r => {
/** @type {?} */
const id = this.rowIdentity(r);
return id === rowId;
}));
}
}
DataTableSelectionComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-selection',
template: `
`,
changeDetection: ChangeDetectionStrategy.OnPush
}] }
];
DataTableSelectionComponent.propDecorators = {
rows: [{ type: Input }],
selected: [{ type: Input }],
selectEnabled: [{ type: Input }],
selectionType: [{ type: Input }],
rowIdentity: [{ type: Input }],
selectCheck: [{ type: Input }],
activate: [{ type: Output }],
select: [{ type: Output }]
};
if (false) {
/** @type {?} */
DataTableSelectionComponent.prototype.rows;
/** @type {?} */
DataTableSelectionComponent.prototype.selected;
/** @type {?} */
DataTableSelectionComponent.prototype.selectEnabled;
/** @type {?} */
DataTableSelectionComponent.prototype.selectionType;
/** @type {?} */
DataTableSelectionComponent.prototype.rowIdentity;
/** @type {?} */
DataTableSelectionComponent.prototype.selectCheck;
/** @type {?} */
DataTableSelectionComponent.prototype.activate;
/** @type {?} */
DataTableSelectionComponent.prototype.select;
/** @type {?} */
DataTableSelectionComponent.prototype.prevIndex;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @record
*/
function ISummaryColumn() { }
if (false) {
/** @type {?|undefined} */
ISummaryColumn.prototype.summaryFunc;
/** @type {?|undefined} */
ISummaryColumn.prototype.summaryTemplate;
/** @type {?} */
ISummaryColumn.prototype.prop;
/** @type {?|undefined} */
ISummaryColumn.prototype.pipe;
}
/**
* @param {?} cells
* @return {?}
*/
function defaultSumFunc(cells) {
/** @type {?} */
const cellsWithValues = cells.filter((/**
* @param {?} cell
* @return {?}
*/
cell => !!cell));
if (!cellsWithValues.length) {
return null;
}
if (cellsWithValues.some((/**
* @param {?} cell
* @return {?}
*/
cell => typeof cell !== 'number'))) {
return null;
}
return cellsWithValues.reduce((/**
* @param {?} res
* @param {?} cell
* @return {?}
*/
(res, cell) => res + cell));
}
/**
* @param {?} cells
* @return {?}
*/
function noopSumFunc(cells) {
return null;
}
class DataTableSummaryRowComponent {
constructor() {
this.summaryRow = {};
}
/**
* @return {?}
*/
ngOnChanges() {
if (!this.columns || !this.rows) {
return;
}
this.updateInternalColumns();
this.updateValues();
}
/**
* @private
* @return {?}
*/
updateInternalColumns() {
this._internalColumns = this.columns.map((/**
* @param {?} col
* @return {?}
*/
col => (Object.assign({}, col, { cellTemplate: col.summaryTemplate }))));
}
/**
* @private
* @return {?}
*/
updateValues() {
this.summaryRow = {};
this.columns
.filter((/**
* @param {?} col
* @return {?}
*/
col => !col.summaryTemplate))
.forEach((/**
* @param {?} col
* @return {?}
*/
col => {
/** @type {?} */
const cellsFromSingleColumn = this.rows.map((/**
* @param {?} row
* @return {?}
*/
row => row[col.prop]));
/** @type {?} */
const sumFunc = this.getSummaryFunction(col);
this.summaryRow[col.prop] = col.pipe
? col.pipe.transform(sumFunc(cellsFromSingleColumn))
: sumFunc(cellsFromSingleColumn);
}));
}
/**
* @private
* @param {?} column
* @return {?}
*/
getSummaryFunction(column) {
if (column.summaryFunc === undefined) {
return defaultSumFunc;
}
else if (column.summaryFunc === null) {
return noopSumFunc;
}
else {
return column.summaryFunc;
}
}
}
DataTableSummaryRowComponent.decorators = [
{ type: Component, args: [{
selector: 'datatable-summary-row',
template: `
`,
host: {
class: 'datatable-summary-row'
}
}] }
];
DataTableSummaryRowComponent.propDecorators = {
rows: [{ type: Input }],
columns: [{ type: Input }],
rowHeight: [{ type: Input }],
offsetX: [{ type: Input }],
innerWidth: [{ type: Input }]
};
if (false) {
/** @type {?} */
DataTableSummaryRowComponent.prototype.rows;
/** @type {?} */
DataTableSummaryRowComponent.prototype.columns;
/** @type {?} */
DataTableSummaryRowComponent.prototype.rowHeight;
/** @type {?} */
DataTableSummaryRowComponent.prototype.offsetX;
/** @type {?} */
DataTableSummaryRowComponent.prototype.innerWidth;
/** @type {?} */
DataTableSummaryRowComponent.prototype._internalColumns;
/** @type {?} */
DataTableSummaryRowComponent.prototype.summaryRow;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class NgxDatatableModule {
/**
* Configure global configuration via INgxDatatableConfig
* @param {?} configuration
* @return {?}
*/
static forRoot(configuration) {
return {
ngModule: NgxDatatableModule,
providers: [{ provide: 'configuration', useValue: configuration }]
};
}
}
NgxDatatableModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule],
providers: [ScrollbarHelper, DimensionsHelper, ColumnChangesService],
declarations: [
DataTableFooterTemplateDirective,
VisibilityDirective,
DraggableDirective,
ResizeableDirective,
OrderableDirective,
LongPressDirective,
ScrollerComponent,
DatatableComponent,
DataTableColumnDirective,
DataTableHeaderComponent,
DataTableHeaderCellComponent,
DataTableBodyComponent,
DataTableFooterComponent,
DataTablePagerComponent,
ProgressBarComponent,
DataTableBodyRowComponent,
DataTableRowWrapperComponent,
DatatableRowDetailDirective,
DatatableGroupHeaderDirective,
DatatableRowDetailTemplateDirective,
DataTableBodyCellComponent,
DataTableSelectionComponent,
DataTableColumnHeaderDirective,
DataTableColumnCellDirective,
DataTableColumnCellTreeToggle,
DatatableFooterDirective,
DatatableGroupHeaderTemplateDirective,
DataTableSummaryRowComponent
],
exports: [
DatatableComponent,
DatatableRowDetailDirective,
DatatableGroupHeaderDirective,
DatatableRowDetailTemplateDirective,
DataTableColumnDirective,
DataTableColumnHeaderDirective,
DataTableColumnCellDirective,
DataTableColumnCellTreeToggle,
DataTableFooterTemplateDirective,
DatatableFooterDirective,
DataTablePagerComponent,
DatatableGroupHeaderTemplateDirective
]
},] }
];
/**
* Interface definition for INgxDatatableConfig global configuration
* @record
*/
function INgxDatatableConfig() { }
if (false) {
/** @type {?} */
INgxDatatableConfig.prototype.messages;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {string} */
const ClickType = {
single: 'single',
double: 'double',
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Column Type
* @record
*/
function TableColumn() { }
if (false) {
/**
* Internal unique id
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.$$id;
/**
* Internal for column width distributions
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.$$oldWidth;
/**
* Internal for setColumnDefaults
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.$$valueGetter;
/**
* Determines if column is checkbox
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.checkboxable;
/**
* Determines if the column is frozen to the left
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.frozenLeft;
/**
* Determines if the column is frozen to the right
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.frozenRight;
/**
* The grow factor relative to other columns. Same as the flex-grow
* API from http =//www.w3.org/TR/css3-flexbox/. Basically;
* take any available extra width and distribute it proportionally
* according to all columns' flexGrow values.
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.flexGrow;
/**
* Min width of the column
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.minWidth;
/**
* Max width of the column
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.maxWidth;
/**
* The default width of the column, in pixels
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.width;
/**
* Can the column be resized
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.resizeable;
/**
* Custom sort comparator
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.comparator;
/**
* Custom pipe transforms
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.pipe;
/**
* Can the column be sorted
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.sortable;
/**
* Can the column be re-arranged by dragging
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.draggable;
/**
* Whether the column can automatically resize to fill space in the table.
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.canAutoResize;
/**
* Column name or label
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.name;
/**
* Property to bind to the row. Example:
*
* `someField` or `some.field.nested`, 0 (numeric)
*
* If left blank, will use the name as camel case conversion
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.prop;
/**
* Cell template ref
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.cellTemplate;
/**
* Header template ref
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.headerTemplate;
/**
* Tree toggle template ref
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.treeToggleTemplate;
/**
* CSS Classes for the cell
*
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.cellClass;
/**
* CSS classes for the header
*
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.headerClass;
/**
* Header checkbox enabled
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.headerCheckboxable;
/**
* Is tree displayed on this column
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.isTreeColumn;
/**
* Width of the tree level indent
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.treeLevelIndent;
/**
* Summary function
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.summaryFunc;
/**
* Summary cell template ref
*
* \@memberOf TableColumn
* @type {?|undefined}
*/
TableColumn.prototype.summaryTemplate;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @record
*/
function SortPropDir() { }
if (false) {
/** @type {?} */
SortPropDir.prototype.dir;
/** @type {?} */
SortPropDir.prototype.prop;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
if (typeof document !== 'undefined' && !document.elementsFromPoint) {
document.elementsFromPoint = elementsFromPoint;
}
/*tslint:disable*/
/**
* Polyfill for `elementsFromPoint`
*
* https://developer.mozilla.org/en-US/docs/Web/API/Document/elementsFromPoint
* https://gist.github.com/iddan/54d5d9e58311b0495a91bf06de661380
* https://gist.github.com/oslego/7265412
* @param {?} x
* @param {?} y
* @return {?}
*/
function elementsFromPoint(x, y) {
/** @type {?} */
const elements = [];
/** @type {?} */
const previousPointerEvents = [];
/** @type {?} */
let current;
// TODO: window.getComputedStyle should be used with inferred type (Element)
/** @type {?} */
let i;
/** @type {?} */
let d;
//if (document === undefined) return elements;
// get all elements via elementFromPoint, and remove them from hit-testing in order
while ((current = document.elementFromPoint(x, y)) && elements.indexOf(current) === -1 && current != null) {
// push the element and its current style
elements.push(current);
previousPointerEvents.push({
value: current.style.getPropertyValue('pointer-events'),
priority: current.style.getPropertyPriority('pointer-events')
});
// add "pointer-events: none", to get to the underlying element
current.style.setProperty('pointer-events', 'none', 'important');
}
// restore the previous pointer-events values
for (i = previousPointerEvents.length; (d = previousPointerEvents[--i]);) {
elements[i].style.setProperty('pointer-events', d.value ? d.value : '', d.priority);
}
// return our results
return elements;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { ClickType, ColumnChangesService, ColumnMode, ContextmenuType, DataTableBodyCellComponent, DataTableBodyComponent, DataTableBodyRowComponent, DataTableColumnCellDirective, DataTableColumnCellTreeToggle, DataTableColumnDirective, DataTableColumnHeaderDirective, DataTableFooterComponent, DataTableFooterTemplateDirective, DataTableHeaderCellComponent, DataTableHeaderComponent, DataTablePagerComponent, DataTableRowWrapperComponent, DataTableSelectionComponent, DataTableSummaryRowComponent, DatatableComponent, DatatableFooterDirective, DatatableGroupHeaderDirective, DatatableGroupHeaderTemplateDirective, DatatableRowDetailDirective, DatatableRowDetailTemplateDirective, DimensionsHelper, DraggableDirective, Keys, LongPressDirective, NgxDatatableModule, OrderableDirective, ProgressBarComponent, ResizeableDirective, RowHeightCache, ScrollbarHelper, ScrollerComponent, SelectionType, SortDirection, SortType, VisibilityDirective, adjustColumnWidths, camelCase, columnGroupWidths, columnTotalWidth, columnsByPin, columnsByPinArr, columnsTotalWidth, deCamelCase, deepValueGetter, elementsFromPoint, emptyStringGetter, forceFillColumnWidths, getTotalFlexGrow, getVendorPrefixedName, getterForProp, groupRowsByParents, id, isNullOrUndefined, nextSortDir, numericIndexGetter, optionalGetterForProp, orderByComparator, selectRows, selectRowsBetween, setColumnDefaults, shallowValueGetter, sortRows, throttle, throttleable, translateTemplates, translateXY };
//# sourceMappingURL=swimlane-ngx-datatable.js.map