UNPKG

246 kBJavaScriptView Raw
1import * as i0 from '@angular/core';
2import { Injectable, Inject, Directive, EventEmitter, HostBinding, Output, Input, HostListener, ContentChildren, Component, ChangeDetectionStrategy, TemplateRef, ContentChild, ViewContainerRef, ViewChild, SkipSelf, ViewEncapsulation, Optional, NgModule } from '@angular/core';
3import * as i1 from '@angular/common';
4import { DOCUMENT, CommonModule } from '@angular/common';
5import { Subject, fromEvent, BehaviorSubject } from 'rxjs';
6import { takeUntil } from 'rxjs/operators';
7import { __decorate } from 'tslib';
8
9/**
10 * Gets the width of the scrollbar. Nesc for windows
11 * http://stackoverflow.com/a/13382873/888165
12 */
13class ScrollbarHelper {
14 constructor(document) {
15 this.document = document;
16 this.width = this.getWidth();
17 }
18 getWidth() {
19 const outer = this.document.createElement('div');
20 outer.style.visibility = 'hidden';
21 outer.style.width = '100px';
22 outer.style.msOverflowStyle = 'scrollbar';
23 this.document.body.appendChild(outer);
24 const widthNoScroll = outer.offsetWidth;
25 outer.style.overflow = 'scroll';
26 const inner = this.document.createElement('div');
27 inner.style.width = '100%';
28 outer.appendChild(inner);
29 const widthWithScroll = inner.offsetWidth;
30 outer.parentNode.removeChild(outer);
31 return widthNoScroll - widthWithScroll;
32 }
33}
34ScrollbarHelper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ScrollbarHelper, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
35ScrollbarHelper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ScrollbarHelper });
36i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ScrollbarHelper, decorators: [{
37 type: Injectable
38 }], ctorParameters: function () {
39 return [{ type: undefined, decorators: [{
40 type: Inject,
41 args: [DOCUMENT]
42 }] }];
43 } });
44
45/**
46 * Gets the width of the scrollbar. Nesc for windows
47 * http://stackoverflow.com/a/13382873/888165
48 */
49class DimensionsHelper {
50 getDimensions(element) {
51 return element.getBoundingClientRect();
52 }
53}
54DimensionsHelper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DimensionsHelper, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
55DimensionsHelper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DimensionsHelper });
56i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DimensionsHelper, decorators: [{
57 type: Injectable
58 }] });
59
60/**
61 * service to make DatatableComponent aware of changes to
62 * input bindings of DataTableColumnDirective
63 */
64class ColumnChangesService {
65 constructor() {
66 this.columnInputChanges = new Subject();
67 }
68 get columnInputChanges$() {
69 return this.columnInputChanges.asObservable();
70 }
71 onInputChange() {
72 this.columnInputChanges.next();
73 }
74}
75ColumnChangesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ColumnChangesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
76ColumnChangesService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ColumnChangesService });
77i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ColumnChangesService, decorators: [{
78 type: Injectable
79 }] });
80
81class DataTableFooterTemplateDirective {
82 constructor(template) {
83 this.template = template;
84 }
85}
86DataTableFooterTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableFooterTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
87DataTableFooterTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DataTableFooterTemplateDirective, selector: "[ngx-datatable-footer-template]", ngImport: i0 });
88i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableFooterTemplateDirective, decorators: [{
89 type: Directive,
90 args: [{ selector: '[ngx-datatable-footer-template]' }]
91 }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
92
93/**
94 * Visibility Observer Directive
95 *
96 * Usage:
97 *
98 * <div
99 * visibilityObserver
100 * (visible)="onVisible($event)">
101 * </div>
102 *
103 */
104class VisibilityDirective {
105 constructor(element, zone) {
106 this.element = element;
107 this.zone = zone;
108 this.isVisible = false;
109 this.visible = new EventEmitter();
110 }
111 ngOnInit() {
112 this.runCheck();
113 }
114 ngOnDestroy() {
115 clearTimeout(this.timeout);
116 }
117 onVisibilityChange() {
118 // trigger zone recalc for columns
119 this.zone.run(() => {
120 this.isVisible = true;
121 this.visible.emit(true);
122 });
123 }
124 runCheck() {
125 const check = () => {
126 // https://davidwalsh.name/offsetheight-visibility
127 const { offsetHeight, offsetWidth } = this.element.nativeElement;
128 if (offsetHeight && offsetWidth) {
129 clearTimeout(this.timeout);
130 this.onVisibilityChange();
131 }
132 else {
133 clearTimeout(this.timeout);
134 this.zone.runOutsideAngular(() => {
135 this.timeout = setTimeout(() => check(), 50);
136 });
137 }
138 };
139 this.timeout = setTimeout(() => check());
140 }
141}
142VisibilityDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: VisibilityDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
143VisibilityDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: VisibilityDirective, selector: "[visibilityObserver]", outputs: { visible: "visible" }, host: { properties: { "class.visible": "this.isVisible" } }, ngImport: i0 });
144i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: VisibilityDirective, decorators: [{
145 type: Directive,
146 args: [{ selector: '[visibilityObserver]' }]
147 }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { isVisible: [{
148 type: HostBinding,
149 args: ['class.visible']
150 }], visible: [{
151 type: Output
152 }] } });
153
154/**
155 * Draggable Directive for Angular2
156 *
157 * Inspiration:
158 * https://github.com/AngularClass/angular2-examples/blob/master/rx-draggable/directives/draggable.ts
159 * http://stackoverflow.com/questions/35662530/how-to-implement-drag-and-drop-in-angular2
160 *
161 */
162class DraggableDirective {
163 constructor(element) {
164 this.dragX = true;
165 this.dragY = true;
166 this.dragStart = new EventEmitter();
167 this.dragging = new EventEmitter();
168 this.dragEnd = new EventEmitter();
169 this.isDragging = false;
170 this.element = element.nativeElement;
171 }
172 ngOnChanges(changes) {
173 if (changes['dragEventTarget'] && changes['dragEventTarget'].currentValue && this.dragModel.dragging) {
174 this.onMousedown(changes['dragEventTarget'].currentValue);
175 }
176 }
177 ngOnDestroy() {
178 this._destroySubscription();
179 }
180 onMouseup(event) {
181 if (!this.isDragging)
182 return;
183 this.isDragging = false;
184 this.element.classList.remove('dragging');
185 if (this.subscription) {
186 this._destroySubscription();
187 this.dragEnd.emit({
188 event,
189 element: this.element,
190 model: this.dragModel
191 });
192 }
193 }
194 onMousedown(event) {
195 // we only want to drag the inner header text
196 const isDragElm = event.target.classList.contains('draggable');
197 if (isDragElm && (this.dragX || this.dragY)) {
198 event.preventDefault();
199 this.isDragging = true;
200 const mouseDownPos = { x: event.clientX, y: event.clientY };
201 const mouseup = fromEvent(document, 'mouseup');
202 this.subscription = mouseup.subscribe((ev) => this.onMouseup(ev));
203 const mouseMoveSub = fromEvent(document, 'mousemove')
204 .pipe(takeUntil(mouseup))
205 .subscribe((ev) => this.move(ev, mouseDownPos));
206 this.subscription.add(mouseMoveSub);
207 this.dragStart.emit({
208 event,
209 element: this.element,
210 model: this.dragModel
211 });
212 }
213 }
214 move(event, mouseDownPos) {
215 if (!this.isDragging)
216 return;
217 const x = event.clientX - mouseDownPos.x;
218 const y = event.clientY - mouseDownPos.y;
219 if (this.dragX)
220 this.element.style.left = `${x}px`;
221 if (this.dragY)
222 this.element.style.top = `${y}px`;
223 this.element.classList.add('dragging');
224 this.dragging.emit({
225 event,
226 element: this.element,
227 model: this.dragModel
228 });
229 }
230 _destroySubscription() {
231 if (this.subscription) {
232 this.subscription.unsubscribe();
233 this.subscription = undefined;
234 }
235 }
236}
237DraggableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DraggableDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
238DraggableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DraggableDirective, selector: "[draggable]", inputs: { dragEventTarget: "dragEventTarget", dragModel: "dragModel", dragX: "dragX", dragY: "dragY" }, outputs: { dragStart: "dragStart", dragging: "dragging", dragEnd: "dragEnd" }, usesOnChanges: true, ngImport: i0 });
239i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DraggableDirective, decorators: [{
240 type: Directive,
241 args: [{ selector: '[draggable]' }]
242 }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { dragEventTarget: [{
243 type: Input
244 }], dragModel: [{
245 type: Input
246 }], dragX: [{
247 type: Input
248 }], dragY: [{
249 type: Input
250 }], dragStart: [{
251 type: Output
252 }], dragging: [{
253 type: Output
254 }], dragEnd: [{
255 type: Output
256 }] } });
257
258class ResizeableDirective {
259 constructor(element, renderer) {
260 this.renderer = renderer;
261 this.resizeEnabled = true;
262 this.resize = new EventEmitter();
263 this.resizing = false;
264 this.element = element.nativeElement;
265 }
266 ngAfterViewInit() {
267 const renderer2 = this.renderer;
268 this.resizeHandle = renderer2.createElement('span');
269 if (this.resizeEnabled) {
270 renderer2.addClass(this.resizeHandle, 'resize-handle');
271 }
272 else {
273 renderer2.addClass(this.resizeHandle, 'resize-handle--not-resizable');
274 }
275 renderer2.appendChild(this.element, this.resizeHandle);
276 }
277 ngOnDestroy() {
278 this._destroySubscription();
279 if (this.renderer.destroyNode) {
280 this.renderer.destroyNode(this.resizeHandle);
281 }
282 else if (this.resizeHandle) {
283 this.renderer.removeChild(this.renderer.parentNode(this.resizeHandle), this.resizeHandle);
284 }
285 }
286 onMouseup() {
287 this.resizing = false;
288 if (this.subscription && !this.subscription.closed) {
289 this._destroySubscription();
290 this.resize.emit(this.element.clientWidth);
291 }
292 }
293 onMousedown(event) {
294 const isHandle = event.target.classList.contains('resize-handle');
295 const initialWidth = this.element.clientWidth;
296 const mouseDownScreenX = event.screenX;
297 if (isHandle) {
298 event.stopPropagation();
299 this.resizing = true;
300 const mouseup = fromEvent(document, 'mouseup');
301 this.subscription = mouseup.subscribe((ev) => this.onMouseup());
302 const mouseMoveSub = fromEvent(document, 'mousemove')
303 .pipe(takeUntil(mouseup))
304 .subscribe((e) => this.move(e, initialWidth, mouseDownScreenX));
305 this.subscription.add(mouseMoveSub);
306 }
307 }
308 move(event, initialWidth, mouseDownScreenX) {
309 const movementX = event.screenX - mouseDownScreenX;
310 const newWidth = initialWidth + movementX;
311 const overMinWidth = !this.minWidth || newWidth >= this.minWidth;
312 const underMaxWidth = !this.maxWidth || newWidth <= this.maxWidth;
313 if (overMinWidth && underMaxWidth) {
314 this.element.style.width = `${newWidth}px`;
315 }
316 }
317 _destroySubscription() {
318 if (this.subscription) {
319 this.subscription.unsubscribe();
320 this.subscription = undefined;
321 }
322 }
323}
324ResizeableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ResizeableDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
325ResizeableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: ResizeableDirective, selector: "[resizeable]", inputs: { resizeEnabled: "resizeEnabled", minWidth: "minWidth", maxWidth: "maxWidth" }, outputs: { resize: "resize" }, host: { listeners: { "mousedown": "onMousedown($event)" }, properties: { "class.resizeable": "resizeEnabled" } }, ngImport: i0 });
326i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ResizeableDirective, decorators: [{
327 type: Directive,
328 args: [{
329 selector: '[resizeable]',
330 host: {
331 '[class.resizeable]': 'resizeEnabled'
332 }
333 }]
334 }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { resizeEnabled: [{
335 type: Input
336 }], minWidth: [{
337 type: Input
338 }], maxWidth: [{
339 type: Input
340 }], resize: [{
341 type: Output
342 }], onMousedown: [{
343 type: HostListener,
344 args: ['mousedown', ['$event']]
345 }] } });
346
347class OrderableDirective {
348 constructor(differs, document) {
349 this.document = document;
350 this.reorder = new EventEmitter();
351 this.targetChanged = new EventEmitter();
352 this.differ = differs.find({}).create();
353 }
354 ngAfterContentInit() {
355 // HACK: Investigate Better Way
356 this.updateSubscriptions();
357 this.draggables.changes.subscribe(this.updateSubscriptions.bind(this));
358 }
359 ngOnDestroy() {
360 this.draggables.forEach(d => {
361 d.dragStart.unsubscribe();
362 d.dragging.unsubscribe();
363 d.dragEnd.unsubscribe();
364 });
365 }
366 updateSubscriptions() {
367 const diffs = this.differ.diff(this.createMapDiffs());
368 if (diffs) {
369 const subscribe = ({ currentValue, previousValue }) => {
370 unsubscribe({ previousValue });
371 if (currentValue) {
372 currentValue.dragStart.subscribe(this.onDragStart.bind(this));
373 currentValue.dragging.subscribe(this.onDragging.bind(this));
374 currentValue.dragEnd.subscribe(this.onDragEnd.bind(this));
375 }
376 };
377 const unsubscribe = ({ previousValue }) => {
378 if (previousValue) {
379 previousValue.dragStart.unsubscribe();
380 previousValue.dragging.unsubscribe();
381 previousValue.dragEnd.unsubscribe();
382 }
383 };
384 diffs.forEachAddedItem(subscribe);
385 // diffs.forEachChangedItem(subscribe.bind(this));
386 diffs.forEachRemovedItem(unsubscribe);
387 }
388 }
389 onDragStart() {
390 this.positions = {};
391 let i = 0;
392 for (const dragger of this.draggables.toArray()) {
393 const elm = dragger.element;
394 const left = parseInt(elm.offsetLeft.toString(), 0);
395 this.positions[dragger.dragModel.prop] = {
396 left,
397 right: left + parseInt(elm.offsetWidth.toString(), 0),
398 index: i++,
399 element: elm
400 };
401 }
402 }
403 onDragging({ element, model, event }) {
404 const prevPos = this.positions[model.prop];
405 const target = this.isTarget(model, event);
406 if (target) {
407 if (this.lastDraggingIndex !== target.i) {
408 this.targetChanged.emit({
409 prevIndex: this.lastDraggingIndex,
410 newIndex: target.i,
411 initialIndex: prevPos.index
412 });
413 this.lastDraggingIndex = target.i;
414 }
415 }
416 else if (this.lastDraggingIndex !== prevPos.index) {
417 this.targetChanged.emit({
418 prevIndex: this.lastDraggingIndex,
419 initialIndex: prevPos.index
420 });
421 this.lastDraggingIndex = prevPos.index;
422 }
423 }
424 onDragEnd({ element, model, event }) {
425 const prevPos = this.positions[model.prop];
426 const target = this.isTarget(model, event);
427 if (target) {
428 this.reorder.emit({
429 prevIndex: prevPos.index,
430 newIndex: target.i,
431 model
432 });
433 }
434 this.lastDraggingIndex = undefined;
435 element.style.left = 'auto';
436 }
437 isTarget(model, event) {
438 let i = 0;
439 const x = event.x || event.clientX;
440 const y = event.y || event.clientY;
441 const targets = this.document.elementsFromPoint(x, y);
442 for (const prop in this.positions) {
443 // current column position which throws event.
444 const pos = this.positions[prop];
445 // since we drag the inner span, we need to find it in the elements at the cursor
446 if (model.prop !== prop && targets.find((el) => el === pos.element)) {
447 return {
448 pos,
449 i
450 };
451 }
452 i++;
453 }
454 }
455 createMapDiffs() {
456 return this.draggables.toArray().reduce((acc, curr) => {
457 acc[curr.dragModel.$$id] = curr;
458 return acc;
459 }, {});
460 }
461}
462OrderableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: OrderableDirective, deps: [{ token: i0.KeyValueDiffers }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive });
463OrderableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: OrderableDirective, selector: "[orderable]", outputs: { reorder: "reorder", targetChanged: "targetChanged" }, queries: [{ propertyName: "draggables", predicate: DraggableDirective, descendants: true }], ngImport: i0 });
464i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: OrderableDirective, decorators: [{
465 type: Directive,
466 args: [{ selector: '[orderable]' }]
467 }], ctorParameters: function () {
468 return [{ type: i0.KeyValueDiffers }, { type: undefined, decorators: [{
469 type: Inject,
470 args: [DOCUMENT]
471 }] }];
472 }, propDecorators: { reorder: [{
473 type: Output
474 }], targetChanged: [{
475 type: Output
476 }], draggables: [{
477 type: ContentChildren,
478 args: [DraggableDirective, { descendants: true }]
479 }] } });
480
481class LongPressDirective {
482 constructor() {
483 this.pressEnabled = true;
484 this.duration = 500;
485 this.longPressStart = new EventEmitter();
486 this.longPressing = new EventEmitter();
487 this.longPressEnd = new EventEmitter();
488 this.mouseX = 0;
489 this.mouseY = 0;
490 }
491 get press() {
492 return this.pressing;
493 }
494 get isLongPress() {
495 return this.isLongPressing;
496 }
497 onMouseDown(event) {
498 // don't do right/middle clicks
499 if (event.which !== 1 || !this.pressEnabled)
500 return;
501 // don't start drag if its on resize handle
502 const target = event.target;
503 if (target.classList.contains('resize-handle'))
504 return;
505 this.mouseX = event.clientX;
506 this.mouseY = event.clientY;
507 this.pressing = true;
508 this.isLongPressing = false;
509 const mouseup = fromEvent(document, 'mouseup');
510 this.subscription = mouseup.subscribe((ev) => this.onMouseup());
511 this.timeout = setTimeout(() => {
512 this.isLongPressing = true;
513 this.longPressStart.emit({
514 event,
515 model: this.pressModel
516 });
517 this.subscription.add(fromEvent(document, 'mousemove')
518 .pipe(takeUntil(mouseup))
519 .subscribe((mouseEvent) => this.onMouseMove(mouseEvent)));
520 this.loop(event);
521 }, this.duration);
522 this.loop(event);
523 }
524 onMouseMove(event) {
525 if (this.pressing && !this.isLongPressing) {
526 const xThres = Math.abs(event.clientX - this.mouseX) > 10;
527 const yThres = Math.abs(event.clientY - this.mouseY) > 10;
528 if (xThres || yThres) {
529 this.endPress();
530 }
531 }
532 }
533 loop(event) {
534 if (this.isLongPressing) {
535 this.timeout = setTimeout(() => {
536 this.longPressing.emit({
537 event,
538 model: this.pressModel
539 });
540 this.loop(event);
541 }, 50);
542 }
543 }
544 endPress() {
545 clearTimeout(this.timeout);
546 this.isLongPressing = false;
547 this.pressing = false;
548 this._destroySubscription();
549 this.longPressEnd.emit({
550 model: this.pressModel
551 });
552 }
553 onMouseup() {
554 this.endPress();
555 }
556 ngOnDestroy() {
557 this._destroySubscription();
558 }
559 _destroySubscription() {
560 if (this.subscription) {
561 this.subscription.unsubscribe();
562 this.subscription = undefined;
563 }
564 }
565}
566LongPressDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: LongPressDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
567LongPressDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: LongPressDirective, selector: "[long-press]", inputs: { pressEnabled: "pressEnabled", pressModel: "pressModel", duration: "duration" }, outputs: { longPressStart: "longPressStart", longPressing: "longPressing", longPressEnd: "longPressEnd" }, host: { listeners: { "mousedown": "onMouseDown($event)" }, properties: { "class.press": "this.press", "class.longpress": "this.isLongPress" } }, ngImport: i0 });
568i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: LongPressDirective, decorators: [{
569 type: Directive,
570 args: [{ selector: '[long-press]' }]
571 }], propDecorators: { pressEnabled: [{
572 type: Input
573 }], pressModel: [{
574 type: Input
575 }], duration: [{
576 type: Input
577 }], longPressStart: [{
578 type: Output
579 }], longPressing: [{
580 type: Output
581 }], longPressEnd: [{
582 type: Output
583 }], press: [{
584 type: HostBinding,
585 args: ['class.press']
586 }], isLongPress: [{
587 type: HostBinding,
588 args: ['class.longpress']
589 }], onMouseDown: [{
590 type: HostListener,
591 args: ['mousedown', ['$event']]
592 }] } });
593
594class ScrollerComponent {
595 constructor(ngZone, element, renderer) {
596 this.ngZone = ngZone;
597 this.renderer = renderer;
598 this.scrollbarV = false;
599 this.scrollbarH = false;
600 this.scroll = new EventEmitter();
601 this.scrollYPos = 0;
602 this.scrollXPos = 0;
603 this.prevScrollYPos = 0;
604 this.prevScrollXPos = 0;
605 this._scrollEventListener = null;
606 this.element = element.nativeElement;
607 }
608 ngOnInit() {
609 // manual bind so we don't always listen
610 if (this.scrollbarV || this.scrollbarH) {
611 const renderer = this.renderer;
612 this.parentElement = renderer.parentNode(renderer.parentNode(this.element));
613 this._scrollEventListener = this.onScrolled.bind(this);
614 this.parentElement.addEventListener('scroll', this._scrollEventListener);
615 }
616 }
617 ngOnDestroy() {
618 if (this._scrollEventListener) {
619 this.parentElement.removeEventListener('scroll', this._scrollEventListener);
620 this._scrollEventListener = null;
621 }
622 }
623 setOffset(offsetY) {
624 if (this.parentElement) {
625 this.parentElement.scrollTop = offsetY;
626 }
627 }
628 onScrolled(event) {
629 const dom = event.currentTarget;
630 requestAnimationFrame(() => {
631 this.scrollYPos = dom.scrollTop;
632 this.scrollXPos = dom.scrollLeft;
633 this.updateOffset();
634 });
635 }
636 updateOffset() {
637 let direction;
638 if (this.scrollYPos < this.prevScrollYPos) {
639 direction = 'down';
640 }
641 else if (this.scrollYPos > this.prevScrollYPos) {
642 direction = 'up';
643 }
644 this.scroll.emit({
645 direction,
646 scrollYPos: this.scrollYPos,
647 scrollXPos: this.scrollXPos
648 });
649 this.prevScrollYPos = this.scrollYPos;
650 this.prevScrollXPos = this.scrollXPos;
651 }
652}
653ScrollerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ScrollerComponent, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
654ScrollerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ScrollerComponent, selector: "datatable-scroller", inputs: { scrollbarV: "scrollbarV", scrollbarH: "scrollbarH", scrollHeight: "scrollHeight", scrollWidth: "scrollWidth" }, outputs: { scroll: "scroll" }, host: { properties: { "style.height.px": "this.scrollHeight", "style.width.px": "this.scrollWidth" }, classAttribute: "datatable-scroll" }, ngImport: i0, template: ` <ng-content></ng-content> `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
655i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ScrollerComponent, decorators: [{
656 type: Component,
657 args: [{
658 selector: 'datatable-scroller',
659 template: ` <ng-content></ng-content> `,
660 host: {
661 class: 'datatable-scroll'
662 },
663 changeDetection: ChangeDetectionStrategy.OnPush
664 }]
665 }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { scrollbarV: [{
666 type: Input
667 }], scrollbarH: [{
668 type: Input
669 }], scrollHeight: [{
670 type: HostBinding,
671 args: ['style.height.px']
672 }, {
673 type: Input
674 }], scrollWidth: [{
675 type: HostBinding,
676 args: ['style.width.px']
677 }, {
678 type: Input
679 }], scroll: [{
680 type: Output
681 }] } });
682
683class DatatableGroupHeaderTemplateDirective {
684 constructor(template) {
685 this.template = template;
686 }
687}
688DatatableGroupHeaderTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableGroupHeaderTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
689DatatableGroupHeaderTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DatatableGroupHeaderTemplateDirective, selector: "[ngx-datatable-group-header-template]", ngImport: i0 });
690i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableGroupHeaderTemplateDirective, decorators: [{
691 type: Directive,
692 args: [{
693 selector: '[ngx-datatable-group-header-template]'
694 }]
695 }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
696
697class DatatableGroupHeaderDirective {
698 constructor() {
699 /**
700 * Row height is required when virtual scroll is enabled.
701 */
702 this.rowHeight = 0;
703 /**
704 * Track toggling of group visibility
705 */
706 this.toggle = new EventEmitter();
707 }
708 get template() {
709 return this._templateInput || this._templateQuery;
710 }
711 /**
712 * Toggle the expansion of a group
713 */
714 toggleExpandGroup(group) {
715 this.toggle.emit({
716 type: 'group',
717 value: group
718 });
719 }
720 /**
721 * Expand all groups
722 */
723 expandAllGroups() {
724 this.toggle.emit({
725 type: 'all',
726 value: true
727 });
728 }
729 /**
730 * Collapse all groups
731 */
732 collapseAllGroups() {
733 this.toggle.emit({
734 type: 'all',
735 value: false
736 });
737 }
738}
739DatatableGroupHeaderDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableGroupHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
740DatatableGroupHeaderDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DatatableGroupHeaderDirective, selector: "ngx-datatable-group-header", inputs: { rowHeight: "rowHeight", _templateInput: ["template", "_templateInput"] }, outputs: { toggle: "toggle" }, queries: [{ propertyName: "_templateQuery", first: true, predicate: DatatableGroupHeaderTemplateDirective, descendants: true, read: TemplateRef, static: true }], ngImport: i0 });
741i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableGroupHeaderDirective, decorators: [{
742 type: Directive,
743 args: [{ selector: 'ngx-datatable-group-header' }]
744 }], propDecorators: { rowHeight: [{
745 type: Input
746 }], _templateInput: [{
747 type: Input,
748 args: ['template']
749 }], _templateQuery: [{
750 type: ContentChild,
751 args: [DatatableGroupHeaderTemplateDirective, { read: TemplateRef, static: true }]
752 }], toggle: [{
753 type: Output
754 }] } });
755
756/**
757 * Always returns the empty string ''
758 */
759function emptyStringGetter() {
760 return '';
761}
762/**
763 * Returns the appropriate getter function for this kind of prop.
764 * If prop == null, returns the emptyStringGetter.
765 */
766function getterForProp(prop) {
767 if (prop == null) {
768 return emptyStringGetter;
769 }
770 if (typeof prop === 'number') {
771 return numericIndexGetter;
772 }
773 else {
774 // deep or simple
775 if (prop.indexOf('.') !== -1) {
776 return deepValueGetter;
777 }
778 else {
779 return shallowValueGetter;
780 }
781 }
782}
783/**
784 * Returns the value at this numeric index.
785 * @param row array of values
786 * @param index numeric index
787 * @returns any or '' if invalid index
788 */
789function numericIndexGetter(row, index) {
790 if (row == null) {
791 return '';
792 }
793 // mimic behavior of deepValueGetter
794 if (!row || index == null) {
795 return row;
796 }
797 const value = row[index];
798 if (value == null) {
799 return '';
800 }
801 return value;
802}
803/**
804 * Returns the value of a field.
805 * (more efficient than deepValueGetter)
806 * @param obj object containing the field
807 * @param fieldName field name string
808 */
809function shallowValueGetter(obj, fieldName) {
810 if (obj == null) {
811 return '';
812 }
813 if (!obj || !fieldName) {
814 return obj;
815 }
816 const value = obj[fieldName];
817 if (value == null) {
818 return '';
819 }
820 return value;
821}
822/**
823 * Returns a deep object given a string. zoo['animal.type']
824 */
825function deepValueGetter(obj, path) {
826 if (obj == null) {
827 return '';
828 }
829 if (!obj || !path) {
830 return obj;
831 }
832 // check if path matches a root-level field
833 // { "a.b.c": 123 }
834 let current = obj[path];
835 if (current !== undefined) {
836 return current;
837 }
838 current = obj;
839 const split = path.split('.');
840 if (split.length) {
841 for (let i = 0; i < split.length; i++) {
842 current = current[split[i]];
843 // if found undefined, return empty string
844 if (current === undefined || current === null) {
845 return '';
846 }
847 }
848 }
849 return current;
850}
851
852function optionalGetterForProp(prop) {
853 return prop && (row => getterForProp(prop)(row, prop));
854}
855/**
856 * This functions rearrange items by their parents
857 * Also sets the level value to each of the items
858 *
859 * Note: Expecting each item has a property called parentId
860 * Note: This algorithm will fail if a list has two or more items with same ID
861 * NOTE: This algorithm will fail if there is a deadlock of relationship
862 *
863 * For example,
864 *
865 * Input
866 *
867 * id -> parent
868 * 1 -> 0
869 * 2 -> 0
870 * 3 -> 1
871 * 4 -> 1
872 * 5 -> 2
873 * 7 -> 8
874 * 6 -> 3
875 *
876 *
877 * Output
878 * id -> level
879 * 1 -> 0
880 * --3 -> 1
881 * ----6 -> 2
882 * --4 -> 1
883 * 2 -> 0
884 * --5 -> 1
885 * 7 -> 8
886 *
887 *
888 * @param rows
889 *
890 */
891function groupRowsByParents(rows, from, to) {
892 if (from && to) {
893 const nodeById = {};
894 const l = rows.length;
895 let node = null;
896 nodeById[0] = new TreeNode(); // that's the root node
897 const uniqIDs = rows.reduce((arr, item) => {
898 const toValue = to(item);
899 if (arr.indexOf(toValue) === -1) {
900 arr.push(toValue);
901 }
902 return arr;
903 }, []);
904 for (let i = 0; i < l; i++) {
905 // make TreeNode objects for each item
906 nodeById[to(rows[i])] = new TreeNode(rows[i]);
907 }
908 for (let i = 0; i < l; i++) {
909 // link all TreeNode objects
910 node = nodeById[to(rows[i])];
911 let parent = 0;
912 const fromValue = from(node.row);
913 if (!!fromValue && uniqIDs.indexOf(fromValue) > -1) {
914 parent = fromValue;
915 }
916 node.parent = nodeById[parent];
917 node.row['level'] = node.parent.row['level'] + 1;
918 node.parent.children.push(node);
919 }
920 let resolvedRows = [];
921 nodeById[0].flatten(function () {
922 resolvedRows = [...resolvedRows, this.row];
923 }, true);
924 return resolvedRows;
925 }
926 else {
927 return rows;
928 }
929}
930class TreeNode {
931 constructor(row = null) {
932 if (!row) {
933 row = {
934 level: -1,
935 treeStatus: 'expanded'
936 };
937 }
938 this.row = row;
939 this.parent = null;
940 this.children = [];
941 }
942 flatten(f, recursive) {
943 if (this.row['treeStatus'] === 'expanded') {
944 for (let i = 0, l = this.children.length; i < l; i++) {
945 const child = this.children[i];
946 f.apply(child, Array.prototype.slice.call(arguments, 2));
947 if (recursive)
948 child.flatten.apply(child, arguments);
949 }
950 }
951 }
952}
953
954/**
955 * Converts strings from something to camel case
956 * http://stackoverflow.com/questions/10425287/convert-dash-separated-string-to-camelcase
957 */
958function camelCase(str) {
959 // Replace special characters with a space
960 str = str.replace(/[^a-zA-Z0-9 ]/g, ' ');
961 // put a space before an uppercase letter
962 str = str.replace(/([a-z](?=[A-Z]))/g, '$1 ');
963 // Lower case first character and some other stuff
964 str = str
965 .replace(/([^a-zA-Z0-9 ])|^[0-9]+/g, '')
966 .trim()
967 .toLowerCase();
968 // uppercase characters preceded by a space or number
969 str = str.replace(/([ 0-9]+)([a-zA-Z])/g, function (a, b, c) {
970 return b.trim() + c.toUpperCase();
971 });
972 return str;
973}
974/**
975 * Converts strings from camel case to words
976 * http://stackoverflow.com/questions/7225407/convert-camelcasetext-to-camel-case-text
977 */
978function deCamelCase(str) {
979 return str.replace(/([A-Z])/g, match => ` ${match}`).replace(/^./, match => match.toUpperCase());
980}
981
982/**
983 * Creates a unique object id.
984 * http://stackoverflow.com/questions/6248666/how-to-generate-short-uid-like-ax4j9z-in-js
985 */
986function id() {
987 return ('0000' + ((Math.random() * Math.pow(36, 4)) << 0).toString(36)).slice(-4);
988}
989
990/**
991 * Sets the column defaults
992 */
993function setColumnDefaults(columns) {
994 if (!columns)
995 return;
996 // Only one column should hold the tree view
997 // Thus if multiple columns are provided with
998 // isTreeColumn as true we take only the first one
999 let treeColumnFound = false;
1000 for (const column of columns) {
1001 if (!column.$$id) {
1002 column.$$id = id();
1003 }
1004 // prop can be numeric; zero is valid not a missing prop
1005 // translate name => prop
1006 if (isNullOrUndefined(column.prop) && column.name) {
1007 column.prop = camelCase(column.name);
1008 }
1009 if (!column.$$valueGetter) {
1010 column.$$valueGetter = getterForProp(column.prop);
1011 }
1012 // format props if no name passed
1013 if (!isNullOrUndefined(column.prop) && isNullOrUndefined(column.name)) {
1014 column.name = deCamelCase(String(column.prop));
1015 }
1016 if (isNullOrUndefined(column.prop) && isNullOrUndefined(column.name)) {
1017 column.name = ''; // Fixes IE and Edge displaying `null`
1018 }
1019 if (!column.hasOwnProperty('resizeable')) {
1020 column.resizeable = true;
1021 }
1022 if (!column.hasOwnProperty('sortable')) {
1023 column.sortable = true;
1024 }
1025 if (!column.hasOwnProperty('draggable')) {
1026 column.draggable = true;
1027 }
1028 if (!column.hasOwnProperty('canAutoResize')) {
1029 column.canAutoResize = true;
1030 }
1031 if (!column.hasOwnProperty('width')) {
1032 column.width = 150;
1033 }
1034 if (!column.hasOwnProperty('isTreeColumn')) {
1035 column.isTreeColumn = false;
1036 }
1037 else {
1038 if (column.isTreeColumn && !treeColumnFound) {
1039 // If the first column with isTreeColumn is true found
1040 // we mark that treeCoulmn is found
1041 treeColumnFound = true;
1042 }
1043 else {
1044 // After that isTreeColumn property for any other column
1045 // will be set as false
1046 column.isTreeColumn = false;
1047 }
1048 }
1049 }
1050}
1051function isNullOrUndefined(value) {
1052 return value === null || value === undefined;
1053}
1054/**
1055 * Translates templates definitions to objects
1056 */
1057function translateTemplates(templates) {
1058 const result = [];
1059 for (const temp of templates) {
1060 const col = {};
1061 const props = Object.getOwnPropertyNames(temp);
1062 for (const prop of props) {
1063 col[prop] = temp[prop];
1064 }
1065 if (temp.headerTemplate) {
1066 col.headerTemplate = temp.headerTemplate;
1067 }
1068 if (temp.cellTemplate) {
1069 col.cellTemplate = temp.cellTemplate;
1070 }
1071 if (temp.summaryFunc) {
1072 col.summaryFunc = temp.summaryFunc;
1073 }
1074 if (temp.summaryTemplate) {
1075 col.summaryTemplate = temp.summaryTemplate;
1076 }
1077 result.push(col);
1078 }
1079 return result;
1080}
1081
1082var ColumnMode;
1083(function (ColumnMode) {
1084 ColumnMode["standard"] = "standard";
1085 ColumnMode["flex"] = "flex";
1086 ColumnMode["force"] = "force";
1087})(ColumnMode || (ColumnMode = {}));
1088
1089var SelectionType;
1090(function (SelectionType) {
1091 SelectionType["single"] = "single";
1092 SelectionType["multi"] = "multi";
1093 SelectionType["multiClick"] = "multiClick";
1094 SelectionType["cell"] = "cell";
1095 SelectionType["checkbox"] = "checkbox";
1096})(SelectionType || (SelectionType = {}));
1097
1098var SortType;
1099(function (SortType) {
1100 SortType["single"] = "single";
1101 SortType["multi"] = "multi";
1102})(SortType || (SortType = {}));
1103
1104var ContextmenuType;
1105(function (ContextmenuType) {
1106 ContextmenuType["header"] = "header";
1107 ContextmenuType["body"] = "body";
1108})(ContextmenuType || (ContextmenuType = {}));
1109
1110class DataTableColumnHeaderDirective {
1111 constructor(template) {
1112 this.template = template;
1113 }
1114}
1115DataTableColumnHeaderDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableColumnHeaderDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
1116DataTableColumnHeaderDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DataTableColumnHeaderDirective, selector: "[ngx-datatable-header-template]", ngImport: i0 });
1117i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableColumnHeaderDirective, decorators: [{
1118 type: Directive,
1119 args: [{ selector: '[ngx-datatable-header-template]' }]
1120 }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
1121
1122class DataTableColumnCellDirective {
1123 constructor(template) {
1124 this.template = template;
1125 }
1126}
1127DataTableColumnCellDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableColumnCellDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
1128DataTableColumnCellDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DataTableColumnCellDirective, selector: "[ngx-datatable-cell-template]", ngImport: i0 });
1129i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableColumnCellDirective, decorators: [{
1130 type: Directive,
1131 args: [{ selector: '[ngx-datatable-cell-template]' }]
1132 }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
1133
1134class DataTableColumnCellTreeToggle {
1135 constructor(template) {
1136 this.template = template;
1137 }
1138}
1139DataTableColumnCellTreeToggle.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableColumnCellTreeToggle, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
1140DataTableColumnCellTreeToggle.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DataTableColumnCellTreeToggle, selector: "[ngx-datatable-tree-toggle]", ngImport: i0 });
1141i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableColumnCellTreeToggle, decorators: [{
1142 type: Directive,
1143 args: [{ selector: '[ngx-datatable-tree-toggle]' }]
1144 }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
1145
1146class DataTableColumnDirective {
1147 constructor(columnChangesService) {
1148 this.columnChangesService = columnChangesService;
1149 this.isFirstChange = true;
1150 }
1151 get cellTemplate() {
1152 return this._cellTemplateInput || this._cellTemplateQuery;
1153 }
1154 get headerTemplate() {
1155 return this._headerTemplateInput || this._headerTemplateQuery;
1156 }
1157 get treeToggleTemplate() {
1158 return this._treeToggleTemplateInput || this._treeToggleTemplateQuery;
1159 }
1160 ngOnChanges() {
1161 if (this.isFirstChange) {
1162 this.isFirstChange = false;
1163 }
1164 else {
1165 this.columnChangesService.onInputChange();
1166 }
1167 }
1168}
1169DataTableColumnDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableColumnDirective, deps: [{ token: ColumnChangesService }], target: i0.ɵɵFactoryTarget.Directive });
1170DataTableColumnDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DataTableColumnDirective, selector: "ngx-datatable-column", inputs: { name: "name", prop: "prop", frozenLeft: "frozenLeft", frozenRight: "frozenRight", flexGrow: "flexGrow", resizeable: "resizeable", comparator: "comparator", pipe: "pipe", sortable: "sortable", draggable: "draggable", canAutoResize: "canAutoResize", minWidth: "minWidth", width: "width", maxWidth: "maxWidth", checkboxable: "checkboxable", headerCheckboxable: "headerCheckboxable", headerClass: "headerClass", cellClass: "cellClass", isTreeColumn: "isTreeColumn", treeLevelIndent: "treeLevelIndent", summaryFunc: "summaryFunc", summaryTemplate: "summaryTemplate", _cellTemplateInput: ["cellTemplate", "_cellTemplateInput"], _headerTemplateInput: ["headerTemplate", "_headerTemplateInput"], _treeToggleTemplateInput: ["treeToggleTemplate", "_treeToggleTemplateInput"] }, queries: [{ propertyName: "_cellTemplateQuery", first: true, predicate: DataTableColumnCellDirective, descendants: true, read: TemplateRef, static: true }, { propertyName: "_headerTemplateQuery", first: true, predicate: DataTableColumnHeaderDirective, descendants: true, read: TemplateRef, static: true }, { propertyName: "_treeToggleTemplateQuery", first: true, predicate: DataTableColumnCellTreeToggle, descendants: true, read: TemplateRef, static: true }], usesOnChanges: true, ngImport: i0 });
1171i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableColumnDirective, decorators: [{
1172 type: Directive,
1173 args: [{ selector: 'ngx-datatable-column' }]
1174 }], ctorParameters: function () { return [{ type: ColumnChangesService }]; }, propDecorators: { name: [{
1175 type: Input
1176 }], prop: [{
1177 type: Input
1178 }], frozenLeft: [{
1179 type: Input
1180 }], frozenRight: [{
1181 type: Input
1182 }], flexGrow: [{
1183 type: Input
1184 }], resizeable: [{
1185 type: Input
1186 }], comparator: [{
1187 type: Input
1188 }], pipe: [{
1189 type: Input
1190 }], sortable: [{
1191 type: Input
1192 }], draggable: [{
1193 type: Input
1194 }], canAutoResize: [{
1195 type: Input
1196 }], minWidth: [{
1197 type: Input
1198 }], width: [{
1199 type: Input
1200 }], maxWidth: [{
1201 type: Input
1202 }], checkboxable: [{
1203 type: Input
1204 }], headerCheckboxable: [{
1205 type: Input
1206 }], headerClass: [{
1207 type: Input
1208 }], cellClass: [{
1209 type: Input
1210 }], isTreeColumn: [{
1211 type: Input
1212 }], treeLevelIndent: [{
1213 type: Input
1214 }], summaryFunc: [{
1215 type: Input
1216 }], summaryTemplate: [{
1217 type: Input
1218 }], _cellTemplateInput: [{
1219 type: Input,
1220 args: ['cellTemplate']
1221 }], _cellTemplateQuery: [{
1222 type: ContentChild,
1223 args: [DataTableColumnCellDirective, { read: TemplateRef, static: true }]
1224 }], _headerTemplateInput: [{
1225 type: Input,
1226 args: ['headerTemplate']
1227 }], _headerTemplateQuery: [{
1228 type: ContentChild,
1229 args: [DataTableColumnHeaderDirective, { read: TemplateRef, static: true }]
1230 }], _treeToggleTemplateInput: [{
1231 type: Input,
1232 args: ['treeToggleTemplate']
1233 }], _treeToggleTemplateQuery: [{
1234 type: ContentChild,
1235 args: [DataTableColumnCellTreeToggle, { read: TemplateRef, static: true }]
1236 }] } });
1237
1238class DatatableRowDetailTemplateDirective {
1239 constructor(template) {
1240 this.template = template;
1241 }
1242}
1243DatatableRowDetailTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableRowDetailTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
1244DatatableRowDetailTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DatatableRowDetailTemplateDirective, selector: "[ngx-datatable-row-detail-template]", ngImport: i0 });
1245i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableRowDetailTemplateDirective, decorators: [{
1246 type: Directive,
1247 args: [{
1248 selector: '[ngx-datatable-row-detail-template]'
1249 }]
1250 }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
1251
1252class DatatableRowDetailDirective {
1253 constructor() {
1254 /**
1255 * The detail row height is required especially
1256 * when virtual scroll is enabled.
1257 */
1258 this.rowHeight = 0;
1259 /**
1260 * Row detail row visbility was toggled.
1261 */
1262 this.toggle = new EventEmitter();
1263 }
1264 get template() {
1265 return this._templateInput || this._templateQuery;
1266 }
1267 /**
1268 * Toggle the expansion of the row
1269 */
1270 toggleExpandRow(row) {
1271 this.toggle.emit({
1272 type: 'row',
1273 value: row
1274 });
1275 }
1276 /**
1277 * API method to expand all the rows.
1278 */
1279 expandAllRows() {
1280 this.toggle.emit({
1281 type: 'all',
1282 value: true
1283 });
1284 }
1285 /**
1286 * API method to collapse all the rows.
1287 */
1288 collapseAllRows() {
1289 this.toggle.emit({
1290 type: 'all',
1291 value: false
1292 });
1293 }
1294}
1295DatatableRowDetailDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableRowDetailDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1296DatatableRowDetailDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DatatableRowDetailDirective, selector: "ngx-datatable-row-detail", inputs: { rowHeight: "rowHeight", _templateInput: ["template", "_templateInput"] }, outputs: { toggle: "toggle" }, queries: [{ propertyName: "_templateQuery", first: true, predicate: DatatableRowDetailTemplateDirective, descendants: true, read: TemplateRef, static: true }], ngImport: i0 });
1297i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableRowDetailDirective, decorators: [{
1298 type: Directive,
1299 args: [{ selector: 'ngx-datatable-row-detail' }]
1300 }], propDecorators: { rowHeight: [{
1301 type: Input
1302 }], _templateInput: [{
1303 type: Input,
1304 args: ['template']
1305 }], _templateQuery: [{
1306 type: ContentChild,
1307 args: [DatatableRowDetailTemplateDirective, { read: TemplateRef, static: true }]
1308 }], toggle: [{
1309 type: Output
1310 }] } });
1311
1312class DatatableFooterDirective {
1313 get template() {
1314 return this._templateInput || this._templateQuery;
1315 }
1316}
1317DatatableFooterDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1318DatatableFooterDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DatatableFooterDirective, selector: "ngx-datatable-footer", inputs: { footerHeight: "footerHeight", totalMessage: "totalMessage", selectedMessage: "selectedMessage", pagerLeftArrowIcon: "pagerLeftArrowIcon", pagerRightArrowIcon: "pagerRightArrowIcon", pagerPreviousIcon: "pagerPreviousIcon", pagerNextIcon: "pagerNextIcon", _templateInput: ["template", "_templateInput"] }, queries: [{ propertyName: "_templateQuery", first: true, predicate: DataTableFooterTemplateDirective, descendants: true, read: TemplateRef }], ngImport: i0 });
1319i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableFooterDirective, decorators: [{
1320 type: Directive,
1321 args: [{ selector: 'ngx-datatable-footer' }]
1322 }], propDecorators: { footerHeight: [{
1323 type: Input
1324 }], totalMessage: [{
1325 type: Input
1326 }], selectedMessage: [{
1327 type: Input
1328 }], pagerLeftArrowIcon: [{
1329 type: Input
1330 }], pagerRightArrowIcon: [{
1331 type: Input
1332 }], pagerPreviousIcon: [{
1333 type: Input
1334 }], pagerNextIcon: [{
1335 type: Input
1336 }], _templateInput: [{
1337 type: Input,
1338 args: ['template']
1339 }], _templateQuery: [{
1340 type: ContentChild,
1341 args: [DataTableFooterTemplateDirective, { read: TemplateRef }]
1342 }] } });
1343
1344/**
1345 * Returns the columns by pin.
1346 */
1347function columnsByPin(cols) {
1348 const ret = {
1349 left: [],
1350 center: [],
1351 right: []
1352 };
1353 if (cols) {
1354 for (const col of cols) {
1355 if (col.frozenLeft) {
1356 ret.left.push(col);
1357 }
1358 else if (col.frozenRight) {
1359 ret.right.push(col);
1360 }
1361 else {
1362 ret.center.push(col);
1363 }
1364 }
1365 }
1366 return ret;
1367}
1368/**
1369 * Returns the widths of all group sets of a column
1370 */
1371function columnGroupWidths(groups, all) {
1372 return {
1373 left: columnTotalWidth(groups.left),
1374 center: columnTotalWidth(groups.center),
1375 right: columnTotalWidth(groups.right),
1376 total: Math.floor(columnTotalWidth(all))
1377 };
1378}
1379/**
1380 * Calculates the total width of all columns and their groups
1381 */
1382function columnTotalWidth(columns, prop) {
1383 let totalWidth = 0;
1384 if (columns) {
1385 for (const c of columns) {
1386 const has = prop && c[prop];
1387 const width = has ? c[prop] : c.width;
1388 totalWidth = totalWidth + parseFloat(width);
1389 }
1390 }
1391 return totalWidth;
1392}
1393/**
1394 * Calculates the total width of all columns and their groups
1395 */
1396function columnsTotalWidth(columns, prop) {
1397 let totalWidth = 0;
1398 for (const column of columns) {
1399 const has = prop && column[prop];
1400 totalWidth = totalWidth + (has ? column[prop] : column.width);
1401 }
1402 return totalWidth;
1403}
1404function columnsByPinArr(val) {
1405 const colsByPinArr = [];
1406 const colsByPin = columnsByPin(val);
1407 colsByPinArr.push({ type: 'left', columns: colsByPin['left'] });
1408 colsByPinArr.push({ type: 'center', columns: colsByPin['center'] });
1409 colsByPinArr.push({ type: 'right', columns: colsByPin['right'] });
1410 return colsByPinArr;
1411}
1412
1413/**
1414 * This object contains the cache of the various row heights that are present inside
1415 * the data table. Its based on Fenwick tree data structure that helps with
1416 * querying sums that have time complexity of log n.
1417 *
1418 * Fenwick Tree Credits: http://petr-mitrichev.blogspot.com/2013/05/fenwick-tree-range-updates.html
1419 * https://github.com/mikolalysenko/fenwick-tree
1420 *
1421 */
1422class RowHeightCache {
1423 constructor() {
1424 /**
1425 * Tree Array stores the cumulative information of the row heights to perform efficient
1426 * range queries and updates. Currently the tree is initialized to the base row
1427 * height instead of the detail row height.
1428 */
1429 this.treeArray = [];
1430 }
1431 /**
1432 * Clear the Tree array.
1433 */
1434 clearCache() {
1435 this.treeArray = [];
1436 }
1437 /**
1438 * Initialize the Fenwick tree with row Heights.
1439 *
1440 * @param rows The array of rows which contain the expanded status.
1441 * @param rowHeight The row height.
1442 * @param detailRowHeight The detail row height.
1443 */
1444 initCache(details) {
1445 const { rows, rowHeight, detailRowHeight, externalVirtual, rowCount, rowIndexes, rowExpansions } = details;
1446 const isFn = typeof rowHeight === 'function';
1447 const isDetailFn = typeof detailRowHeight === 'function';
1448 if (!isFn && isNaN(rowHeight)) {
1449 throw new Error(`Row Height cache initialization failed. Please ensure that 'rowHeight' is a
1450 valid number or function value: (${rowHeight}) when 'scrollbarV' is enabled.`);
1451 }
1452 // Add this additional guard in case detailRowHeight is set to 'auto' as it wont work.
1453 if (!isDetailFn && isNaN(detailRowHeight)) {
1454 throw new Error(`Row Height cache initialization failed. Please ensure that 'detailRowHeight' is a
1455 valid number or function value: (${detailRowHeight}) when 'scrollbarV' is enabled.`);
1456 }
1457 const n = externalVirtual ? rowCount : rows.length;
1458 this.treeArray = new Array(n);
1459 for (let i = 0; i < n; ++i) {
1460 this.treeArray[i] = 0;
1461 }
1462 for (let i = 0; i < n; ++i) {
1463 const row = rows[i];
1464 let currentRowHeight = rowHeight;
1465 if (isFn) {
1466 currentRowHeight = rowHeight(row);
1467 }
1468 // Add the detail row height to the already expanded rows.
1469 // This is useful for the table that goes through a filter or sort.
1470 const expanded = rowExpansions.has(row);
1471 if (row && expanded) {
1472 if (isDetailFn) {
1473 const index = rowIndexes.get(row);
1474 currentRowHeight += detailRowHeight(row, index);
1475 }
1476 else {
1477 currentRowHeight += detailRowHeight;
1478 }
1479 }
1480 this.update(i, currentRowHeight);
1481 }
1482 }
1483 /**
1484 * Given the ScrollY position i.e. sum, provide the rowIndex
1485 * that is present in the current view port. Below handles edge cases.
1486 */
1487 getRowIndex(scrollY) {
1488 if (scrollY === 0)
1489 return 0;
1490 return this.calcRowIndex(scrollY);
1491 }
1492 /**
1493 * When a row is expanded or rowHeight is changed, update the height. This can
1494 * be utilized in future when Angular Data table supports dynamic row heights.
1495 */
1496 update(atRowIndex, byRowHeight) {
1497 if (!this.treeArray.length) {
1498 throw new Error(`Update at index ${atRowIndex} with value ${byRowHeight} failed:
1499 Row Height cache not initialized.`);
1500 }
1501 const n = this.treeArray.length;
1502 atRowIndex |= 0;
1503 while (atRowIndex < n) {
1504 this.treeArray[atRowIndex] += byRowHeight;
1505 atRowIndex |= atRowIndex + 1;
1506 }
1507 }
1508 /**
1509 * Range Sum query from 1 to the rowIndex
1510 */
1511 query(atIndex) {
1512 if (!this.treeArray.length) {
1513 throw new Error(`query at index ${atIndex} failed: Fenwick tree array not initialized.`);
1514 }
1515 let sum = 0;
1516 atIndex |= 0;
1517 while (atIndex >= 0) {
1518 sum += this.treeArray[atIndex];
1519 atIndex = (atIndex & (atIndex + 1)) - 1;
1520 }
1521 return sum;
1522 }
1523 /**
1524 * Find the total height between 2 row indexes
1525 */
1526 queryBetween(atIndexA, atIndexB) {
1527 return this.query(atIndexB) - this.query(atIndexA - 1);
1528 }
1529 /**
1530 * Given the ScrollY position i.e. sum, provide the rowIndex
1531 * that is present in the current view port.
1532 */
1533 calcRowIndex(sum) {
1534 if (!this.treeArray.length)
1535 return 0;
1536 let pos = -1;
1537 const dataLength = this.treeArray.length;
1538 // Get the highest bit for the block size.
1539 const highestBit = Math.pow(2, dataLength.toString(2).length - 1);
1540 for (let blockSize = highestBit; blockSize !== 0; blockSize >>= 1) {
1541 const nextPos = pos + blockSize;
1542 if (nextPos < dataLength && sum >= this.treeArray[nextPos]) {
1543 sum -= this.treeArray[nextPos];
1544 pos = nextPos;
1545 }
1546 }
1547 return pos + 1;
1548 }
1549}
1550
1551const cache = {};
1552const testStyle = typeof document !== 'undefined' ? document.createElement('div').style : undefined;
1553// Get Prefix
1554// http://davidwalsh.name/vendor-prefix
1555const prefix = (function () {
1556 const styles = typeof window !== 'undefined' ? window.getComputedStyle(document.documentElement, '') : undefined;
1557 const match = typeof styles !== 'undefined'
1558 ? Array.prototype.slice
1559 .call(styles)
1560 .join('')
1561 .match(/-(moz|webkit|ms)-/)
1562 : null;
1563 const pre = match !== null ? match[1] : undefined;
1564 // tslint:disable-next-line: tsr-detect-non-literal-regexp
1565 const dom = typeof pre !== 'undefined' ? 'WebKit|Moz|MS|O'.match(new RegExp('(' + pre + ')', 'i'))[1] : undefined;
1566 return dom
1567 ? {
1568 dom,
1569 lowercase: pre,
1570 css: `-${pre}-`,
1571 js: pre[0].toUpperCase() + pre.substr(1)
1572 }
1573 : undefined;
1574})();
1575function getVendorPrefixedName(property) {
1576 const name = camelCase(property);
1577 if (!cache[name]) {
1578 if (prefix !== undefined && testStyle[prefix.css + property] !== undefined) {
1579 cache[name] = prefix.css + property;
1580 }
1581 else if (testStyle[property] !== undefined) {
1582 cache[name] = property;
1583 }
1584 }
1585 return cache[name];
1586}
1587
1588// browser detection and prefixing tools
1589const transform = typeof window !== 'undefined' ? getVendorPrefixedName('transform') : undefined;
1590const backfaceVisibility = typeof window !== 'undefined' ? getVendorPrefixedName('backfaceVisibility') : undefined;
1591const hasCSSTransforms = typeof window !== 'undefined' ? !!getVendorPrefixedName('transform') : undefined;
1592const hasCSS3DTransforms = typeof window !== 'undefined' ? !!getVendorPrefixedName('perspective') : undefined;
1593const ua = typeof window !== 'undefined' ? window.navigator.userAgent : 'Chrome';
1594const isSafari = /Safari\//.test(ua) && !/Chrome\//.test(ua);
1595function translateXY(styles, x, y) {
1596 if (typeof transform !== 'undefined' && hasCSSTransforms) {
1597 if (!isSafari && hasCSS3DTransforms) {
1598 styles[transform] = `translate3d(${x}px, ${y}px, 0)`;
1599 styles[backfaceVisibility] = 'hidden';
1600 }
1601 else {
1602 styles[camelCase(transform)] = `translate(${x}px, ${y}px)`;
1603 }
1604 }
1605 else {
1606 styles.top = `${y}px`;
1607 styles.left = `${x}px`;
1608 }
1609}
1610
1611class ProgressBarComponent {
1612}
1613ProgressBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1614ProgressBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: ProgressBarComponent, selector: "datatable-progress", ngImport: i0, template: `
1615 <div class="progress-linear" role="progressbar">
1616 <div class="container">
1617 <div class="bar"></div>
1618 </div>
1619 </div>
1620 `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1621i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: ProgressBarComponent, decorators: [{
1622 type: Component,
1623 args: [{
1624 selector: 'datatable-progress',
1625 template: `
1626 <div class="progress-linear" role="progressbar">
1627 <div class="container">
1628 <div class="bar"></div>
1629 </div>
1630 </div>
1631 `,
1632 changeDetection: ChangeDetectionStrategy.OnPush
1633 }]
1634 }] });
1635
1636function selectRows(selected, row, comparefn) {
1637 const selectedIndex = comparefn(row, selected);
1638 if (selectedIndex > -1) {
1639 selected.splice(selectedIndex, 1);
1640 }
1641 else {
1642 selected.push(row);
1643 }
1644 return selected;
1645}
1646function selectRowsBetween(selected, rows, index, prevIndex, comparefn) {
1647 const reverse = index < prevIndex;
1648 for (let i = 0; i < rows.length; i++) {
1649 const row = rows[i];
1650 const greater = i >= prevIndex && i <= index;
1651 const lesser = i <= prevIndex && i >= index;
1652 let range = { start: 0, end: 0 };
1653 if (reverse) {
1654 range = {
1655 start: index,
1656 end: prevIndex
1657 };
1658 }
1659 else {
1660 range = {
1661 start: prevIndex,
1662 end: index + 1
1663 };
1664 }
1665 if ((reverse && lesser) || (!reverse && greater)) {
1666 // if in the positive range to be added to `selected`, and
1667 // not already in the selected array, add it
1668 if (i >= range.start && i <= range.end) {
1669 selected.push(row);
1670 }
1671 }
1672 }
1673 return selected;
1674}
1675
1676var Keys;
1677(function (Keys) {
1678 Keys[Keys["up"] = 38] = "up";
1679 Keys[Keys["down"] = 40] = "down";
1680 Keys[Keys["return"] = 13] = "return";
1681 Keys[Keys["escape"] = 27] = "escape";
1682 Keys[Keys["left"] = 37] = "left";
1683 Keys[Keys["right"] = 39] = "right";
1684})(Keys || (Keys = {}));
1685
1686class DataTableSelectionComponent {
1687 constructor() {
1688 this.activate = new EventEmitter();
1689 this.select = new EventEmitter();
1690 }
1691 selectRow(event, index, row) {
1692 if (!this.selectEnabled)
1693 return;
1694 const chkbox = this.selectionType === SelectionType.checkbox;
1695 const multi = this.selectionType === SelectionType.multi;
1696 const multiClick = this.selectionType === SelectionType.multiClick;
1697 let selected = [];
1698 if (multi || chkbox || multiClick) {
1699 if (event.shiftKey) {
1700 selected = selectRowsBetween([], this.rows, index, this.prevIndex, this.getRowSelectedIdx.bind(this));
1701 }
1702 else if (event.ctrlKey || event.metaKey || multiClick || chkbox) {
1703 selected = selectRows([...this.selected], row, this.getRowSelectedIdx.bind(this));
1704 }
1705 else {
1706 selected = selectRows([], row, this.getRowSelectedIdx.bind(this));
1707 }
1708 }
1709 else {
1710 selected = selectRows([], row, this.getRowSelectedIdx.bind(this));
1711 }
1712 if (typeof this.selectCheck === 'function') {
1713 selected = selected.filter(this.selectCheck.bind(this));
1714 }
1715 this.selected.splice(0, this.selected.length);
1716 this.selected.push(...selected);
1717 this.prevIndex = index;
1718 this.select.emit({
1719 selected
1720 });
1721 }
1722 onActivate(model, index) {
1723 const { type, event, row } = model;
1724 const chkbox = this.selectionType === SelectionType.checkbox;
1725 const select = (!chkbox && (type === 'click' || type === 'dblclick')) || (chkbox && type === 'checkbox');
1726 if (select) {
1727 this.selectRow(event, index, row);
1728 }
1729 else if (type === 'keydown') {
1730 if (event.keyCode === Keys.return) {
1731 this.selectRow(event, index, row);
1732 }
1733 else {
1734 this.onKeyboardFocus(model);
1735 }
1736 }
1737 this.activate.emit(model);
1738 }
1739 onKeyboardFocus(model) {
1740 const { keyCode } = model.event;
1741 const shouldFocus = keyCode === Keys.up || keyCode === Keys.down || keyCode === Keys.right || keyCode === Keys.left;
1742 if (shouldFocus) {
1743 const isCellSelection = this.selectionType === SelectionType.cell;
1744 if (!model.cellElement || !isCellSelection) {
1745 this.focusRow(model.rowElement, keyCode);
1746 }
1747 else if (isCellSelection) {
1748 this.focusCell(model.cellElement, model.rowElement, keyCode, model.cellIndex);
1749 }
1750 }
1751 }
1752 focusRow(rowElement, keyCode) {
1753 const nextRowElement = this.getPrevNextRow(rowElement, keyCode);
1754 if (nextRowElement)
1755 nextRowElement.focus();
1756 }
1757 getPrevNextRow(rowElement, keyCode) {
1758 const parentElement = rowElement.parentElement;
1759 if (parentElement) {
1760 let focusElement;
1761 if (keyCode === Keys.up) {
1762 focusElement = parentElement.previousElementSibling;
1763 }
1764 else if (keyCode === Keys.down) {
1765 focusElement = parentElement.nextElementSibling;
1766 }
1767 if (focusElement && focusElement.children.length) {
1768 return focusElement.children[0];
1769 }
1770 }
1771 }
1772 focusCell(cellElement, rowElement, keyCode, cellIndex) {
1773 let nextCellElement;
1774 if (keyCode === Keys.left) {
1775 nextCellElement = cellElement.previousElementSibling;
1776 }
1777 else if (keyCode === Keys.right) {
1778 nextCellElement = cellElement.nextElementSibling;
1779 }
1780 else if (keyCode === Keys.up || keyCode === Keys.down) {
1781 const nextRowElement = this.getPrevNextRow(rowElement, keyCode);
1782 if (nextRowElement) {
1783 const children = nextRowElement.getElementsByClassName('datatable-body-cell');
1784 if (children.length)
1785 nextCellElement = children[cellIndex];
1786 }
1787 }
1788 if (nextCellElement)
1789 nextCellElement.focus();
1790 }
1791 getRowSelected(row) {
1792 return this.getRowSelectedIdx(row, this.selected) > -1;
1793 }
1794 getRowSelectedIdx(row, selected) {
1795 if (!selected || !selected.length)
1796 return -1;
1797 const rowId = this.rowIdentity(row);
1798 return selected.findIndex(r => {
1799 const id = this.rowIdentity(r);
1800 return id === rowId;
1801 });
1802 }
1803}
1804DataTableSelectionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableSelectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1805DataTableSelectionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTableSelectionComponent, selector: "datatable-selection", inputs: { rows: "rows", selected: "selected", selectEnabled: "selectEnabled", selectionType: "selectionType", rowIdentity: "rowIdentity", selectCheck: "selectCheck" }, outputs: { activate: "activate", select: "select" }, ngImport: i0, template: ` <ng-content></ng-content> `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1806i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableSelectionComponent, decorators: [{
1807 type: Component,
1808 args: [{
1809 selector: 'datatable-selection',
1810 template: ` <ng-content></ng-content> `,
1811 changeDetection: ChangeDetectionStrategy.OnPush
1812 }]
1813 }], propDecorators: { rows: [{
1814 type: Input
1815 }], selected: [{
1816 type: Input
1817 }], selectEnabled: [{
1818 type: Input
1819 }], selectionType: [{
1820 type: Input
1821 }], rowIdentity: [{
1822 type: Input
1823 }], selectCheck: [{
1824 type: Input
1825 }], activate: [{
1826 type: Output
1827 }], select: [{
1828 type: Output
1829 }] } });
1830
1831var SortDirection;
1832(function (SortDirection) {
1833 SortDirection["asc"] = "asc";
1834 SortDirection["desc"] = "desc";
1835})(SortDirection || (SortDirection = {}));
1836
1837class DataTableBodyCellComponent {
1838 constructor(element, cd) {
1839 this.cd = cd;
1840 this.activate = new EventEmitter();
1841 this.treeAction = new EventEmitter();
1842 this.isFocused = false;
1843 this.onCheckboxChangeFn = this.onCheckboxChange.bind(this);
1844 this.activateFn = this.activate.emit.bind(this.activate);
1845 this.cellContext = {
1846 onCheckboxChangeFn: this.onCheckboxChangeFn,
1847 activateFn: this.activateFn,
1848 row: this.row,
1849 group: this.group,
1850 value: this.value,
1851 column: this.column,
1852 rowHeight: this.rowHeight,
1853 isSelected: this.isSelected,
1854 rowIndex: this.rowIndex,
1855 treeStatus: this.treeStatus,
1856 onTreeAction: this.onTreeAction.bind(this)
1857 };
1858 this._element = element.nativeElement;
1859 }
1860 set group(group) {
1861 this._group = group;
1862 this.cellContext.group = group;
1863 this.checkValueUpdates();
1864 this.cd.markForCheck();
1865 }
1866 get group() {
1867 return this._group;
1868 }
1869 set rowHeight(val) {
1870 this._rowHeight = val;
1871 this.cellContext.rowHeight = val;
1872 this.checkValueUpdates();
1873 this.cd.markForCheck();
1874 }
1875 get rowHeight() {
1876 return this._rowHeight;
1877 }
1878 set isSelected(val) {
1879 this._isSelected = val;
1880 this.cellContext.isSelected = val;
1881 this.cd.markForCheck();
1882 }
1883 get isSelected() {
1884 return this._isSelected;
1885 }
1886 set expanded(val) {
1887 this._expanded = val;
1888 this.cellContext.expanded = val;
1889 this.cd.markForCheck();
1890 }
1891 get expanded() {
1892 return this._expanded;
1893 }
1894 set rowIndex(val) {
1895 this._rowIndex = val;
1896 this.cellContext.rowIndex = val;
1897 this.checkValueUpdates();
1898 this.cd.markForCheck();
1899 }
1900 get rowIndex() {
1901 return this._rowIndex;
1902 }
1903 set column(column) {
1904 this._column = column;
1905 this.cellContext.column = column;
1906 this.checkValueUpdates();
1907 this.cd.markForCheck();
1908 }
1909 get column() {
1910 return this._column;
1911 }
1912 set row(row) {
1913 this._row = row;
1914 this.cellContext.row = row;
1915 this.checkValueUpdates();
1916 this.cd.markForCheck();
1917 }
1918 get row() {
1919 return this._row;
1920 }
1921 set sorts(val) {
1922 this._sorts = val;
1923 this.calcSortDir = this.calcSortDir(val);
1924 }
1925 get sorts() {
1926 return this._sorts;
1927 }
1928 set treeStatus(status) {
1929 if (status !== 'collapsed' && status !== 'expanded' && status !== 'loading' && status !== 'disabled') {
1930 this._treeStatus = 'collapsed';
1931 }
1932 else {
1933 this._treeStatus = status;
1934 }
1935 this.cellContext.treeStatus = this._treeStatus;
1936 this.checkValueUpdates();
1937 this.cd.markForCheck();
1938 }
1939 get treeStatus() {
1940 return this._treeStatus;
1941 }
1942 get columnCssClasses() {
1943 let cls = 'datatable-body-cell';
1944 if (this.column.cellClass) {
1945 if (typeof this.column.cellClass === 'string') {
1946 cls += ' ' + this.column.cellClass;
1947 }
1948 else if (typeof this.column.cellClass === 'function') {
1949 const res = this.column.cellClass({
1950 row: this.row,
1951 group: this.group,
1952 column: this.column,
1953 value: this.value,
1954 rowHeight: this.rowHeight
1955 });
1956 if (typeof res === 'string') {
1957 cls += ' ' + res;
1958 }
1959 else if (typeof res === 'object') {
1960 const keys = Object.keys(res);
1961 for (const k of keys) {
1962 if (res[k] === true) {
1963 cls += ` ${k}`;
1964 }
1965 }
1966 }
1967 }
1968 }
1969 if (!this.sortDir) {
1970 cls += ' sort-active';
1971 }
1972 if (this.isFocused) {
1973 cls += ' active';
1974 }
1975 if (this.sortDir === SortDirection.asc) {
1976 cls += ' sort-asc';
1977 }
1978 if (this.sortDir === SortDirection.desc) {
1979 cls += ' sort-desc';
1980 }
1981 return cls;
1982 }
1983 get width() {
1984 return this.column.width;
1985 }
1986 get minWidth() {
1987 return this.column.minWidth;
1988 }
1989 get maxWidth() {
1990 return this.column.maxWidth;
1991 }
1992 get height() {
1993 const height = this.rowHeight;
1994 if (isNaN(height)) {
1995 return height;
1996 }
1997 return height + 'px';
1998 }
1999 ngDoCheck() {
2000 this.checkValueUpdates();
2001 }
2002 ngOnDestroy() {
2003 if (this.cellTemplate) {
2004 this.cellTemplate.clear();
2005 }
2006 }
2007 checkValueUpdates() {
2008 let value = '';
2009 if (!this.row || !this.column) {
2010 value = '';
2011 }
2012 else {
2013 const val = this.column.$$valueGetter(this.row, this.column.prop);
2014 const userPipe = this.column.pipe;
2015 if (userPipe) {
2016 value = userPipe.transform(val);
2017 }
2018 else if (value !== undefined) {
2019 value = val;
2020 }
2021 }
2022 if (this.value !== value) {
2023 this.value = value;
2024 this.cellContext.value = value;
2025 this.sanitizedValue = value !== null && value !== undefined ? this.stripHtml(value) : value;
2026 this.cd.markForCheck();
2027 }
2028 }
2029 onFocus() {
2030 this.isFocused = true;
2031 }
2032 onBlur() {
2033 this.isFocused = false;
2034 }
2035 onClick(event) {
2036 this.activate.emit({
2037 type: 'click',
2038 event,
2039 row: this.row,
2040 group: this.group,
2041 rowHeight: this.rowHeight,
2042 column: this.column,
2043 value: this.value,
2044 cellElement: this._element
2045 });
2046 }
2047 onDblClick(event) {
2048 this.activate.emit({
2049 type: 'dblclick',
2050 event,
2051 row: this.row,
2052 group: this.group,
2053 rowHeight: this.rowHeight,
2054 column: this.column,
2055 value: this.value,
2056 cellElement: this._element
2057 });
2058 }
2059 onKeyDown(event) {
2060 const keyCode = event.keyCode;
2061 const isTargetCell = event.target === this._element;
2062 const isAction = keyCode === Keys.return ||
2063 keyCode === Keys.down ||
2064 keyCode === Keys.up ||
2065 keyCode === Keys.left ||
2066 keyCode === Keys.right;
2067 if (isAction && isTargetCell) {
2068 event.preventDefault();
2069 event.stopPropagation();
2070 this.activate.emit({
2071 type: 'keydown',
2072 event,
2073 row: this.row,
2074 group: this.group,
2075 rowHeight: this.rowHeight,
2076 column: this.column,
2077 value: this.value,
2078 cellElement: this._element
2079 });
2080 }
2081 }
2082 onCheckboxChange(event) {
2083 this.activate.emit({
2084 type: 'checkbox',
2085 event,
2086 row: this.row,
2087 group: this.group,
2088 rowHeight: this.rowHeight,
2089 column: this.column,
2090 value: this.value,
2091 cellElement: this._element,
2092 treeStatus: 'collapsed'
2093 });
2094 }
2095 calcSortDir(sorts) {
2096 if (!sorts) {
2097 return;
2098 }
2099 const sort = sorts.find((s) => {
2100 return s.prop === this.column.prop;
2101 });
2102 if (sort) {
2103 return sort.dir;
2104 }
2105 }
2106 stripHtml(html) {
2107 if (!html.replace) {
2108 return html;
2109 }
2110 return html.replace(/<\/?[^>]+(>|$)/g, '');
2111 }
2112 onTreeAction() {
2113 this.treeAction.emit(this.row);
2114 }
2115 calcLeftMargin(column, row) {
2116 const levelIndent = column.treeLevelIndent != null ? column.treeLevelIndent : 50;
2117 return column.isTreeColumn ? row.level * levelIndent : 0;
2118 }
2119}
2120DataTableBodyCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableBodyCellComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2121DataTableBodyCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTableBodyCellComponent, selector: "datatable-body-cell", inputs: { displayCheck: "displayCheck", group: "group", rowHeight: "rowHeight", isSelected: "isSelected", expanded: "expanded", rowIndex: "rowIndex", column: "column", row: "row", sorts: "sorts", treeStatus: "treeStatus" }, outputs: { activate: "activate", treeAction: "treeAction" }, host: { listeners: { "focus": "onFocus()", "blur": "onBlur()", "click": "onClick($event)", "dblclick": "onDblClick($event)", "keydown": "onKeyDown($event)" }, properties: { "class": "this.columnCssClasses", "style.width.px": "this.width", "style.minWidth.px": "this.minWidth", "style.maxWidth.px": "this.maxWidth", "style.height": "this.height" } }, viewQueries: [{ propertyName: "cellTemplate", first: true, predicate: ["cellTemplate"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: `
2122 <div class="datatable-body-cell-label" [style.margin-left.px]="calcLeftMargin(column, row)">
2123 <label
2124 *ngIf="column.checkboxable && (!displayCheck || displayCheck(row, column, value))"
2125 class="datatable-checkbox"
2126 >
2127 <input type="checkbox" [checked]="isSelected" (click)="onCheckboxChange($event)" />
2128 </label>
2129 <ng-container *ngIf="column.isTreeColumn">
2130 <button
2131 *ngIf="!column.treeToggleTemplate"
2132 class="datatable-tree-button"
2133 [disabled]="treeStatus === 'disabled'"
2134 (click)="onTreeAction()"
2135 >
2136 <span>
2137 <i *ngIf="treeStatus === 'loading'" class="icon datatable-icon-collapse"></i>
2138 <i *ngIf="treeStatus === 'collapsed'" class="icon datatable-icon-up"></i>
2139 <i *ngIf="treeStatus === 'expanded' || treeStatus === 'disabled'" class="icon datatable-icon-down"></i>
2140 </span>
2141 </button>
2142 <ng-template
2143 *ngIf="column.treeToggleTemplate"
2144 [ngTemplateOutlet]="column.treeToggleTemplate"
2145 [ngTemplateOutletContext]="{ cellContext: cellContext }"
2146 >
2147 </ng-template>
2148 </ng-container>
2149
2150 <span *ngIf="!column.cellTemplate" [title]="sanitizedValue" [innerHTML]="value"> </span>
2151 <ng-template
2152 #cellTemplate
2153 *ngIf="column.cellTemplate"
2154 [ngTemplateOutlet]="column.cellTemplate"
2155 [ngTemplateOutletContext]="cellContext"
2156 >
2157 </ng-template>
2158 </div>
2159 `, isInline: true, directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2160i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableBodyCellComponent, decorators: [{
2161 type: Component,
2162 args: [{
2163 selector: 'datatable-body-cell',
2164 changeDetection: ChangeDetectionStrategy.OnPush,
2165 template: `
2166 <div class="datatable-body-cell-label" [style.margin-left.px]="calcLeftMargin(column, row)">
2167 <label
2168 *ngIf="column.checkboxable && (!displayCheck || displayCheck(row, column, value))"
2169 class="datatable-checkbox"
2170 >
2171 <input type="checkbox" [checked]="isSelected" (click)="onCheckboxChange($event)" />
2172 </label>
2173 <ng-container *ngIf="column.isTreeColumn">
2174 <button
2175 *ngIf="!column.treeToggleTemplate"
2176 class="datatable-tree-button"
2177 [disabled]="treeStatus === 'disabled'"
2178 (click)="onTreeAction()"
2179 >
2180 <span>
2181 <i *ngIf="treeStatus === 'loading'" class="icon datatable-icon-collapse"></i>
2182 <i *ngIf="treeStatus === 'collapsed'" class="icon datatable-icon-up"></i>
2183 <i *ngIf="treeStatus === 'expanded' || treeStatus === 'disabled'" class="icon datatable-icon-down"></i>
2184 </span>
2185 </button>
2186 <ng-template
2187 *ngIf="column.treeToggleTemplate"
2188 [ngTemplateOutlet]="column.treeToggleTemplate"
2189 [ngTemplateOutletContext]="{ cellContext: cellContext }"
2190 >
2191 </ng-template>
2192 </ng-container>
2193
2194 <span *ngIf="!column.cellTemplate" [title]="sanitizedValue" [innerHTML]="value"> </span>
2195 <ng-template
2196 #cellTemplate
2197 *ngIf="column.cellTemplate"
2198 [ngTemplateOutlet]="column.cellTemplate"
2199 [ngTemplateOutletContext]="cellContext"
2200 >
2201 </ng-template>
2202 </div>
2203 `
2204 }]
2205 }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { displayCheck: [{
2206 type: Input
2207 }], group: [{
2208 type: Input
2209 }], rowHeight: [{
2210 type: Input
2211 }], isSelected: [{
2212 type: Input
2213 }], expanded: [{
2214 type: Input
2215 }], rowIndex: [{
2216 type: Input
2217 }], column: [{
2218 type: Input
2219 }], row: [{
2220 type: Input
2221 }], sorts: [{
2222 type: Input
2223 }], treeStatus: [{
2224 type: Input
2225 }], activate: [{
2226 type: Output
2227 }], treeAction: [{
2228 type: Output
2229 }], cellTemplate: [{
2230 type: ViewChild,
2231 args: ['cellTemplate', { read: ViewContainerRef, static: true }]
2232 }], columnCssClasses: [{
2233 type: HostBinding,
2234 args: ['class']
2235 }], width: [{
2236 type: HostBinding,
2237 args: ['style.width.px']
2238 }], minWidth: [{
2239 type: HostBinding,
2240 args: ['style.minWidth.px']
2241 }], maxWidth: [{
2242 type: HostBinding,
2243 args: ['style.maxWidth.px']
2244 }], height: [{
2245 type: HostBinding,
2246 args: ['style.height']
2247 }], onFocus: [{
2248 type: HostListener,
2249 args: ['focus']
2250 }], onBlur: [{
2251 type: HostListener,
2252 args: ['blur']
2253 }], onClick: [{
2254 type: HostListener,
2255 args: ['click', ['$event']]
2256 }], onDblClick: [{
2257 type: HostListener,
2258 args: ['dblclick', ['$event']]
2259 }], onKeyDown: [{
2260 type: HostListener,
2261 args: ['keydown', ['$event']]
2262 }] } });
2263
2264class DataTableBodyRowComponent {
2265 constructor(differs, scrollbarHelper, cd, element) {
2266 this.differs = differs;
2267 this.scrollbarHelper = scrollbarHelper;
2268 this.cd = cd;
2269 this.treeStatus = 'collapsed';
2270 this.activate = new EventEmitter();
2271 this.treeAction = new EventEmitter();
2272 this._groupStyles = {
2273 left: {},
2274 center: {},
2275 right: {}
2276 };
2277 this._element = element.nativeElement;
2278 this._rowDiffer = differs.find({}).create();
2279 }
2280 set columns(val) {
2281 this._columns = val;
2282 this.recalculateColumns(val);
2283 this.buildStylesByGroup();
2284 }
2285 get columns() {
2286 return this._columns;
2287 }
2288 set innerWidth(val) {
2289 if (this._columns) {
2290 const colByPin = columnsByPin(this._columns);
2291 this._columnGroupWidths = columnGroupWidths(colByPin, this._columns);
2292 }
2293 this._innerWidth = val;
2294 this.recalculateColumns();
2295 this.buildStylesByGroup();
2296 }
2297 get innerWidth() {
2298 return this._innerWidth;
2299 }
2300 set offsetX(val) {
2301 this._offsetX = val;
2302 this.buildStylesByGroup();
2303 }
2304 get offsetX() {
2305 return this._offsetX;
2306 }
2307 get cssClass() {
2308 let cls = 'datatable-body-row';
2309 if (this.isSelected) {
2310 cls += ' active';
2311 }
2312 if (this.rowIndex % 2 !== 0) {
2313 cls += ' datatable-row-odd';
2314 }
2315 if (this.rowIndex % 2 === 0) {
2316 cls += ' datatable-row-even';
2317 }
2318 if (this.rowClass) {
2319 const res = this.rowClass(this.row);
2320 if (typeof res === 'string') {
2321 cls += ` ${res}`;
2322 }
2323 else if (typeof res === 'object') {
2324 const keys = Object.keys(res);
2325 for (const k of keys) {
2326 if (res[k] === true) {
2327 cls += ` ${k}`;
2328 }
2329 }
2330 }
2331 }
2332 return cls;
2333 }
2334 get columnsTotalWidths() {
2335 return this._columnGroupWidths.total;
2336 }
2337 ngDoCheck() {
2338 if (this._rowDiffer.diff(this.row)) {
2339 this.cd.markForCheck();
2340 }
2341 }
2342 trackByGroups(index, colGroup) {
2343 return colGroup.type;
2344 }
2345 columnTrackingFn(index, column) {
2346 return column.$$id;
2347 }
2348 buildStylesByGroup() {
2349 this._groupStyles.left = this.calcStylesByGroup('left');
2350 this._groupStyles.center = this.calcStylesByGroup('center');
2351 this._groupStyles.right = this.calcStylesByGroup('right');
2352 this.cd.markForCheck();
2353 }
2354 calcStylesByGroup(group) {
2355 const widths = this._columnGroupWidths;
2356 const offsetX = this.offsetX;
2357 const styles = {
2358 width: `${widths[group]}px`
2359 };
2360 if (group === 'left') {
2361 translateXY(styles, offsetX, 0);
2362 }
2363 else if (group === 'right') {
2364 const bodyWidth = parseInt(this.innerWidth + '', 0);
2365 const totalDiff = widths.total - bodyWidth;
2366 const offsetDiff = totalDiff - offsetX;
2367 const offset = (offsetDiff + this.scrollbarHelper.width) * -1;
2368 translateXY(styles, offset, 0);
2369 }
2370 return styles;
2371 }
2372 onActivate(event, index) {
2373 event.cellIndex = index;
2374 event.rowElement = this._element;
2375 this.activate.emit(event);
2376 }
2377 onKeyDown(event) {
2378 const keyCode = event.keyCode;
2379 const isTargetRow = event.target === this._element;
2380 const isAction = keyCode === Keys.return ||
2381 keyCode === Keys.down ||
2382 keyCode === Keys.up ||
2383 keyCode === Keys.left ||
2384 keyCode === Keys.right;
2385 if (isAction && isTargetRow) {
2386 event.preventDefault();
2387 event.stopPropagation();
2388 this.activate.emit({
2389 type: 'keydown',
2390 event,
2391 row: this.row,
2392 rowElement: this._element
2393 });
2394 }
2395 }
2396 onMouseenter(event) {
2397 this.activate.emit({
2398 type: 'mouseenter',
2399 event,
2400 row: this.row,
2401 rowElement: this._element
2402 });
2403 }
2404 recalculateColumns(val = this.columns) {
2405 this._columns = val;
2406 const colsByPin = columnsByPin(this._columns);
2407 this._columnsByPin = columnsByPinArr(this._columns);
2408 this._columnGroupWidths = columnGroupWidths(colsByPin, this._columns);
2409 }
2410 onTreeAction() {
2411 this.treeAction.emit();
2412 }
2413}
2414DataTableBodyRowComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableBodyRowComponent, deps: [{ token: i0.KeyValueDiffers }, { token: ScrollbarHelper, skipSelf: true }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
2415DataTableBodyRowComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTableBodyRowComponent, selector: "datatable-body-row", inputs: { columns: "columns", innerWidth: "innerWidth", expanded: "expanded", rowClass: "rowClass", row: "row", group: "group", isSelected: "isSelected", rowIndex: "rowIndex", displayCheck: "displayCheck", treeStatus: "treeStatus", offsetX: "offsetX", rowHeight: "rowHeight" }, outputs: { activate: "activate", treeAction: "treeAction" }, host: { listeners: { "keydown": "onKeyDown($event)", "mouseenter": "onMouseenter($event)" }, properties: { "class": "this.cssClass", "style.height.px": "this.rowHeight", "style.width.px": "this.columnsTotalWidths" } }, ngImport: i0, template: `
2416 <div
2417 *ngFor="let colGroup of _columnsByPin; let i = index; trackBy: trackByGroups"
2418 class="datatable-row-{{ colGroup.type }} datatable-row-group"
2419 [ngStyle]="_groupStyles[colGroup.type]"
2420 >
2421 <datatable-body-cell
2422 role="cell"
2423 *ngFor="let column of colGroup.columns; let ii = index; trackBy: columnTrackingFn"
2424 tabindex="-1"
2425 [row]="row"
2426 [group]="group"
2427 [expanded]="expanded"
2428 [isSelected]="isSelected"
2429 [rowIndex]="rowIndex"
2430 [column]="column"
2431 [rowHeight]="rowHeight"
2432 [displayCheck]="displayCheck"
2433 [treeStatus]="treeStatus"
2434 (activate)="onActivate($event, ii)"
2435 (treeAction)="onTreeAction()"
2436 >
2437 </datatable-body-cell>
2438 </div>
2439 `, isInline: true, components: [{ type: DataTableBodyCellComponent, selector: "datatable-body-cell", inputs: ["displayCheck", "group", "rowHeight", "isSelected", "expanded", "rowIndex", "column", "row", "sorts", "treeStatus"], outputs: ["activate", "treeAction"] }], directives: [{ type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2440i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableBodyRowComponent, decorators: [{
2441 type: Component,
2442 args: [{
2443 selector: 'datatable-body-row',
2444 changeDetection: ChangeDetectionStrategy.OnPush,
2445 template: `
2446 <div
2447 *ngFor="let colGroup of _columnsByPin; let i = index; trackBy: trackByGroups"
2448 class="datatable-row-{{ colGroup.type }} datatable-row-group"
2449 [ngStyle]="_groupStyles[colGroup.type]"
2450 >
2451 <datatable-body-cell
2452 role="cell"
2453 *ngFor="let column of colGroup.columns; let ii = index; trackBy: columnTrackingFn"
2454 tabindex="-1"
2455 [row]="row"
2456 [group]="group"
2457 [expanded]="expanded"
2458 [isSelected]="isSelected"
2459 [rowIndex]="rowIndex"
2460 [column]="column"
2461 [rowHeight]="rowHeight"
2462 [displayCheck]="displayCheck"
2463 [treeStatus]="treeStatus"
2464 (activate)="onActivate($event, ii)"
2465 (treeAction)="onTreeAction()"
2466 >
2467 </datatable-body-cell>
2468 </div>
2469 `
2470 }]
2471 }], ctorParameters: function () {
2472 return [{ type: i0.KeyValueDiffers }, { type: ScrollbarHelper, decorators: [{
2473 type: SkipSelf
2474 }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }];
2475 }, propDecorators: { columns: [{
2476 type: Input
2477 }], innerWidth: [{
2478 type: Input
2479 }], expanded: [{
2480 type: Input
2481 }], rowClass: [{
2482 type: Input
2483 }], row: [{
2484 type: Input
2485 }], group: [{
2486 type: Input
2487 }], isSelected: [{
2488 type: Input
2489 }], rowIndex: [{
2490 type: Input
2491 }], displayCheck: [{
2492 type: Input
2493 }], treeStatus: [{
2494 type: Input
2495 }], offsetX: [{
2496 type: Input
2497 }], cssClass: [{
2498 type: HostBinding,
2499 args: ['class']
2500 }], rowHeight: [{
2501 type: HostBinding,
2502 args: ['style.height.px']
2503 }, {
2504 type: Input
2505 }], columnsTotalWidths: [{
2506 type: HostBinding,
2507 args: ['style.width.px']
2508 }], activate: [{
2509 type: Output
2510 }], treeAction: [{
2511 type: Output
2512 }], onKeyDown: [{
2513 type: HostListener,
2514 args: ['keydown', ['$event']]
2515 }], onMouseenter: [{
2516 type: HostListener,
2517 args: ['mouseenter', ['$event']]
2518 }] } });
2519
2520function defaultSumFunc(cells) {
2521 const cellsWithValues = cells.filter(cell => !!cell);
2522 if (!cellsWithValues.length) {
2523 return null;
2524 }
2525 if (cellsWithValues.some(cell => typeof cell !== 'number')) {
2526 return null;
2527 }
2528 return cellsWithValues.reduce((res, cell) => res + cell);
2529}
2530function noopSumFunc(cells) {
2531 return null;
2532}
2533class DataTableSummaryRowComponent {
2534 constructor() {
2535 this.summaryRow = {};
2536 }
2537 ngOnChanges() {
2538 if (!this.columns || !this.rows) {
2539 return;
2540 }
2541 this.updateInternalColumns();
2542 this.updateValues();
2543 }
2544 updateInternalColumns() {
2545 this._internalColumns = this.columns.map(col => (Object.assign(Object.assign({}, col), { cellTemplate: col.summaryTemplate })));
2546 }
2547 updateValues() {
2548 this.summaryRow = {};
2549 this.columns
2550 .filter(col => !col.summaryTemplate)
2551 .forEach(col => {
2552 const cellsFromSingleColumn = this.rows.map(row => row[col.prop]);
2553 const sumFunc = this.getSummaryFunction(col);
2554 this.summaryRow[col.prop] = col.pipe
2555 ? col.pipe.transform(sumFunc(cellsFromSingleColumn))
2556 : sumFunc(cellsFromSingleColumn);
2557 });
2558 }
2559 getSummaryFunction(column) {
2560 if (column.summaryFunc === undefined) {
2561 return defaultSumFunc;
2562 }
2563 else if (column.summaryFunc === null) {
2564 return noopSumFunc;
2565 }
2566 else {
2567 return column.summaryFunc;
2568 }
2569 }
2570}
2571DataTableSummaryRowComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableSummaryRowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2572DataTableSummaryRowComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTableSummaryRowComponent, selector: "datatable-summary-row", inputs: { rows: "rows", columns: "columns", rowHeight: "rowHeight", offsetX: "offsetX", innerWidth: "innerWidth" }, host: { classAttribute: "datatable-summary-row" }, usesOnChanges: true, ngImport: i0, template: `
2573 <datatable-body-row
2574 *ngIf="summaryRow && _internalColumns"
2575 tabindex="-1"
2576 [innerWidth]="innerWidth"
2577 [offsetX]="offsetX"
2578 [columns]="_internalColumns"
2579 [rowHeight]="rowHeight"
2580 [row]="summaryRow"
2581 [rowIndex]="-1"
2582 >
2583 </datatable-body-row>
2584 `, isInline: true, components: [{ type: DataTableBodyRowComponent, selector: "datatable-body-row", inputs: ["columns", "innerWidth", "expanded", "rowClass", "row", "group", "isSelected", "rowIndex", "displayCheck", "treeStatus", "offsetX", "rowHeight"], outputs: ["activate", "treeAction"] }], directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2585i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableSummaryRowComponent, decorators: [{
2586 type: Component,
2587 args: [{
2588 selector: 'datatable-summary-row',
2589 template: `
2590 <datatable-body-row
2591 *ngIf="summaryRow && _internalColumns"
2592 tabindex="-1"
2593 [innerWidth]="innerWidth"
2594 [offsetX]="offsetX"
2595 [columns]="_internalColumns"
2596 [rowHeight]="rowHeight"
2597 [row]="summaryRow"
2598 [rowIndex]="-1"
2599 >
2600 </datatable-body-row>
2601 `,
2602 host: {
2603 class: 'datatable-summary-row'
2604 }
2605 }]
2606 }], propDecorators: { rows: [{
2607 type: Input
2608 }], columns: [{
2609 type: Input
2610 }], rowHeight: [{
2611 type: Input
2612 }], offsetX: [{
2613 type: Input
2614 }], innerWidth: [{
2615 type: Input
2616 }] } });
2617
2618class DataTableRowWrapperComponent {
2619 constructor(cd, differs) {
2620 this.cd = cd;
2621 this.differs = differs;
2622 this.rowContextmenu = new EventEmitter(false);
2623 this._expanded = false;
2624 this.groupContext = {
2625 group: this.row,
2626 expanded: this.expanded,
2627 rowIndex: this.rowIndex
2628 };
2629 this.rowContext = {
2630 row: this.row,
2631 expanded: this.expanded,
2632 rowIndex: this.rowIndex
2633 };
2634 this.rowDiffer = differs.find({}).create();
2635 }
2636 set rowIndex(val) {
2637 this._rowIndex = val;
2638 this.rowContext.rowIndex = val;
2639 this.groupContext.rowIndex = val;
2640 this.cd.markForCheck();
2641 }
2642 get rowIndex() {
2643 return this._rowIndex;
2644 }
2645 set expanded(val) {
2646 this._expanded = val;
2647 this.groupContext.expanded = val;
2648 this.rowContext.expanded = val;
2649 this.cd.markForCheck();
2650 }
2651 get expanded() {
2652 return this._expanded;
2653 }
2654 ngDoCheck() {
2655 if (this.rowDiffer.diff(this.row)) {
2656 this.rowContext.row = this.row;
2657 this.groupContext.group = this.row;
2658 this.cd.markForCheck();
2659 }
2660 }
2661 onContextmenu($event) {
2662 this.rowContextmenu.emit({ event: $event, row: this.row });
2663 }
2664 getGroupHeaderStyle() {
2665 const styles = {};
2666 styles['transform'] = 'translate3d(' + this.offsetX + 'px, 0px, 0px)';
2667 styles['backface-visibility'] = 'hidden';
2668 styles['width'] = this.innerWidth;
2669 return styles;
2670 }
2671}
2672DataTableRowWrapperComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableRowWrapperComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.KeyValueDiffers }], target: i0.ɵɵFactoryTarget.Component });
2673DataTableRowWrapperComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTableRowWrapperComponent, selector: "datatable-row-wrapper", inputs: { innerWidth: "innerWidth", rowDetail: "rowDetail", groupHeader: "groupHeader", offsetX: "offsetX", detailRowHeight: "detailRowHeight", row: "row", groupedRows: "groupedRows", rowIndex: "rowIndex", expanded: "expanded" }, outputs: { rowContextmenu: "rowContextmenu" }, host: { listeners: { "contextmenu": "onContextmenu($event)" }, classAttribute: "datatable-row-wrapper" }, ngImport: i0, template: `
2674 <div *ngIf="groupHeader && groupHeader.template" class="datatable-group-header" [ngStyle]="getGroupHeaderStyle()">
2675 <ng-template
2676 *ngIf="groupHeader && groupHeader.template"
2677 [ngTemplateOutlet]="groupHeader.template"
2678 [ngTemplateOutletContext]="groupContext"
2679 >
2680 </ng-template>
2681 </div>
2682 <ng-content *ngIf="(groupHeader && groupHeader.template && expanded) || !groupHeader || !groupHeader.template">
2683 </ng-content>
2684 <div
2685 *ngIf="rowDetail && rowDetail.template && expanded"
2686 [style.height.px]="detailRowHeight"
2687 class="datatable-row-detail"
2688 >
2689 <ng-template
2690 *ngIf="rowDetail && rowDetail.template"
2691 [ngTemplateOutlet]="rowDetail.template"
2692 [ngTemplateOutletContext]="rowContext"
2693 >
2694 </ng-template>
2695 </div>
2696 `, isInline: true, directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2697i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableRowWrapperComponent, decorators: [{
2698 type: Component,
2699 args: [{
2700 selector: 'datatable-row-wrapper',
2701 changeDetection: ChangeDetectionStrategy.OnPush,
2702 template: `
2703 <div *ngIf="groupHeader && groupHeader.template" class="datatable-group-header" [ngStyle]="getGroupHeaderStyle()">
2704 <ng-template
2705 *ngIf="groupHeader && groupHeader.template"
2706 [ngTemplateOutlet]="groupHeader.template"
2707 [ngTemplateOutletContext]="groupContext"
2708 >
2709 </ng-template>
2710 </div>
2711 <ng-content *ngIf="(groupHeader && groupHeader.template && expanded) || !groupHeader || !groupHeader.template">
2712 </ng-content>
2713 <div
2714 *ngIf="rowDetail && rowDetail.template && expanded"
2715 [style.height.px]="detailRowHeight"
2716 class="datatable-row-detail"
2717 >
2718 <ng-template
2719 *ngIf="rowDetail && rowDetail.template"
2720 [ngTemplateOutlet]="rowDetail.template"
2721 [ngTemplateOutletContext]="rowContext"
2722 >
2723 </ng-template>
2724 </div>
2725 `,
2726 host: {
2727 class: 'datatable-row-wrapper'
2728 }
2729 }]
2730 }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.KeyValueDiffers }]; }, propDecorators: { innerWidth: [{
2731 type: Input
2732 }], rowDetail: [{
2733 type: Input
2734 }], groupHeader: [{
2735 type: Input
2736 }], offsetX: [{
2737 type: Input
2738 }], detailRowHeight: [{
2739 type: Input
2740 }], row: [{
2741 type: Input
2742 }], groupedRows: [{
2743 type: Input
2744 }], rowContextmenu: [{
2745 type: Output
2746 }], rowIndex: [{
2747 type: Input
2748 }], expanded: [{
2749 type: Input
2750 }], onContextmenu: [{
2751 type: HostListener,
2752 args: ['contextmenu', ['$event']]
2753 }] } });
2754
2755class DataTableBodyComponent {
2756 /**
2757 * Creates an instance of DataTableBodyComponent.
2758 */
2759 constructor(cd) {
2760 this.cd = cd;
2761 this.selected = [];
2762 this.scroll = new EventEmitter();
2763 this.page = new EventEmitter();
2764 this.activate = new EventEmitter();
2765 this.select = new EventEmitter();
2766 this.detailToggle = new EventEmitter();
2767 this.rowContextmenu = new EventEmitter(false);
2768 this.treeAction = new EventEmitter();
2769 this.rowHeightsCache = new RowHeightCache();
2770 this.temp = [];
2771 this.offsetY = 0;
2772 this.indexes = {};
2773 this.rowIndexes = new WeakMap();
2774 this.rowExpansions = [];
2775 /**
2776 * Get the height of the detail row.
2777 */
2778 this.getDetailRowHeight = (row, index) => {
2779 if (!this.rowDetail) {
2780 return 0;
2781 }
2782 const rowHeight = this.rowDetail.rowHeight;
2783 return typeof rowHeight === 'function' ? rowHeight(row, index) : rowHeight;
2784 };
2785 // declare fn here so we can get access to the `this` property
2786 this.rowTrackingFn = (index, row) => {
2787 const idx = this.getRowIndex(row);
2788 if (this.trackByProp) {
2789 return row[this.trackByProp];
2790 }
2791 else {
2792 return idx;
2793 }
2794 };
2795 }
2796 set pageSize(val) {
2797 this._pageSize = val;
2798 this.recalcLayout();
2799 }
2800 get pageSize() {
2801 return this._pageSize;
2802 }
2803 set rows(val) {
2804 this._rows = val;
2805 this.recalcLayout();
2806 }
2807 get rows() {
2808 return this._rows;
2809 }
2810 set columns(val) {
2811 this._columns = val;
2812 const colsByPin = columnsByPin(val);
2813 this.columnGroupWidths = columnGroupWidths(colsByPin, val);
2814 }
2815 get columns() {
2816 return this._columns;
2817 }
2818 set offset(val) {
2819 this._offset = val;
2820 if (!this.scrollbarV || (this.scrollbarV && !this.virtualization))
2821 this.recalcLayout();
2822 }
2823 get offset() {
2824 return this._offset;
2825 }
2826 set rowCount(val) {
2827 this._rowCount = val;
2828 this.recalcLayout();
2829 }
2830 get rowCount() {
2831 return this._rowCount;
2832 }
2833 get bodyWidth() {
2834 if (this.scrollbarH) {
2835 return this.innerWidth + 'px';
2836 }
2837 else {
2838 return '100%';
2839 }
2840 }
2841 set bodyHeight(val) {
2842 if (this.scrollbarV) {
2843 this._bodyHeight = val + 'px';
2844 }
2845 else {
2846 this._bodyHeight = 'auto';
2847 }
2848 this.recalcLayout();
2849 }
2850 get bodyHeight() {
2851 return this._bodyHeight;
2852 }
2853 /**
2854 * Returns if selection is enabled.
2855 */
2856 get selectEnabled() {
2857 return !!this.selectionType;
2858 }
2859 /**
2860 * Property that would calculate the height of scroll bar
2861 * based on the row heights cache for virtual scroll and virtualization. Other scenarios
2862 * calculate scroll height automatically (as height will be undefined).
2863 */
2864 get scrollHeight() {
2865 if (this.scrollbarV && this.virtualization && this.rowCount) {
2866 return this.rowHeightsCache.query(this.rowCount - 1);
2867 }
2868 // avoid TS7030: Not all code paths return a value.
2869 return undefined;
2870 }
2871 /**
2872 * Called after the constructor, initializing input properties
2873 */
2874 ngOnInit() {
2875 if (this.rowDetail) {
2876 this.listener = this.rowDetail.toggle.subscribe(({ type, value }) => {
2877 if (type === 'row') {
2878 this.toggleRowExpansion(value);
2879 }
2880 if (type === 'all') {
2881 this.toggleAllRows(value);
2882 }
2883 // Refresh rows after toggle
2884 // Fixes #883
2885 this.updateIndexes();
2886 this.updateRows();
2887 this.cd.markForCheck();
2888 });
2889 }
2890 if (this.groupHeader) {
2891 this.listener = this.groupHeader.toggle.subscribe(({ type, value }) => {
2892 if (type === 'group') {
2893 this.toggleRowExpansion(value);
2894 }
2895 if (type === 'all') {
2896 this.toggleAllRows(value);
2897 }
2898 // Refresh rows after toggle
2899 // Fixes #883
2900 this.updateIndexes();
2901 this.updateRows();
2902 this.cd.markForCheck();
2903 });
2904 }
2905 }
2906 /**
2907 * Called once, before the instance is destroyed.
2908 */
2909 ngOnDestroy() {
2910 if (this.rowDetail || this.groupHeader) {
2911 this.listener.unsubscribe();
2912 }
2913 }
2914 /**
2915 * Updates the Y offset given a new offset.
2916 */
2917 updateOffsetY(offset) {
2918 // scroller is missing on empty table
2919 if (!this.scroller) {
2920 return;
2921 }
2922 if (this.scrollbarV && this.virtualization && offset) {
2923 // First get the row Index that we need to move to.
2924 const rowIndex = this.pageSize * offset;
2925 offset = this.rowHeightsCache.query(rowIndex - 1);
2926 }
2927 else if (this.scrollbarV && !this.virtualization) {
2928 offset = 0;
2929 }
2930 this.scroller.setOffset(offset || 0);
2931 }
2932 /**
2933 * Body was scrolled, this is mainly useful for
2934 * when a user is server-side pagination via virtual scroll.
2935 */
2936 onBodyScroll(event) {
2937 const scrollYPos = event.scrollYPos;
2938 const scrollXPos = event.scrollXPos;
2939 // if scroll change, trigger update
2940 // this is mainly used for header cell positions
2941 if (this.offsetY !== scrollYPos || this.offsetX !== scrollXPos) {
2942 this.scroll.emit({
2943 offsetY: scrollYPos,
2944 offsetX: scrollXPos
2945 });
2946 }
2947 this.offsetY = scrollYPos;
2948 this.offsetX = scrollXPos;
2949 this.updateIndexes();
2950 this.updatePage(event.direction);
2951 this.updateRows();
2952 }
2953 /**
2954 * Updates the page given a direction.
2955 */
2956 updatePage(direction) {
2957 let offset = this.indexes.first / this.pageSize;
2958 if (direction === 'up') {
2959 offset = Math.ceil(offset);
2960 }
2961 else if (direction === 'down') {
2962 offset = Math.floor(offset);
2963 }
2964 if (direction !== undefined && !isNaN(offset)) {
2965 this.page.emit({ offset });
2966 }
2967 }
2968 /**
2969 * Updates the rows in the view port
2970 */
2971 updateRows() {
2972 const { first, last } = this.indexes;
2973 let rowIndex = first;
2974 let idx = 0;
2975 const temp = [];
2976 // if grouprowsby has been specified treat row paging
2977 // parameters as group paging parameters ie if limit 10 has been
2978 // specified treat it as 10 groups rather than 10 rows
2979 if (this.groupedRows) {
2980 let maxRowsPerGroup = 3;
2981 // if there is only one group set the maximum number of
2982 // rows per group the same as the total number of rows
2983 if (this.groupedRows.length === 1) {
2984 maxRowsPerGroup = this.groupedRows[0].value.length;
2985 }
2986 while (rowIndex < last && rowIndex < this.groupedRows.length) {
2987 // Add the groups into this page
2988 const group = this.groupedRows[rowIndex];
2989 this.rowIndexes.set(group, rowIndex);
2990 if (group.value) {
2991 // add indexes for each group item
2992 group.value.forEach((g, i) => {
2993 const _idx = `${rowIndex}-${i}`;
2994 this.rowIndexes.set(g, _idx);
2995 });
2996 }
2997 temp[idx] = group;
2998 idx++;
2999 // Group index in this context
3000 rowIndex++;
3001 }
3002 }
3003 else {
3004 while (rowIndex < last && rowIndex < this.rowCount) {
3005 const row = this.rows[rowIndex];
3006 if (row) {
3007 // add indexes for each row
3008 this.rowIndexes.set(row, rowIndex);
3009 temp[idx] = row;
3010 }
3011 idx++;
3012 rowIndex++;
3013 }
3014 }
3015 this.temp = temp;
3016 }
3017 /**
3018 * Get the row height
3019 */
3020 getRowHeight(row) {
3021 // if its a function return it
3022 if (typeof this.rowHeight === 'function') {
3023 return this.rowHeight(row);
3024 }
3025 return this.rowHeight;
3026 }
3027 /**
3028 * @param group the group with all rows
3029 */
3030 getGroupHeight(group) {
3031 let rowHeight = 0;
3032 if (group.value) {
3033 for (let index = 0; index < group.value.length; index++) {
3034 rowHeight += this.getRowAndDetailHeight(group.value[index]);
3035 }
3036 }
3037 return rowHeight;
3038 }
3039 /**
3040 * Calculate row height based on the expanded state of the row.
3041 */
3042 getRowAndDetailHeight(row) {
3043 let rowHeight = this.getRowHeight(row);
3044 const expanded = this.getRowExpanded(row);
3045 // Adding detail row height if its expanded.
3046 if (expanded) {
3047 rowHeight += this.getDetailRowHeight(row);
3048 }
3049 return rowHeight;
3050 }
3051 /**
3052 * Calculates the styles for the row so that the rows can be moved in 2D space
3053 * during virtual scroll inside the DOM. In the below case the Y position is
3054 * manipulated. As an example, if the height of row 0 is 30 px and row 1 is
3055 * 100 px then following styles are generated:
3056 *
3057 * transform: translate3d(0px, 0px, 0px); -> row0
3058 * transform: translate3d(0px, 30px, 0px); -> row1
3059 * transform: translate3d(0px, 130px, 0px); -> row2
3060 *
3061 * Row heights have to be calculated based on the row heights cache as we wont
3062 * be able to determine which row is of what height before hand. In the above
3063 * case the positionY of the translate3d for row2 would be the sum of all the
3064 * heights of the rows before it (i.e. row0 and row1).
3065 *
3066 * @param rows the row that needs to be placed in the 2D space.
3067 * @returns the CSS3 style to be applied
3068 *
3069 * @memberOf DataTableBodyComponent
3070 */
3071 getRowsStyles(rows) {
3072 const styles = {};
3073 // only add styles for the group if there is a group
3074 if (this.groupedRows) {
3075 styles.width = this.columnGroupWidths.total;
3076 }
3077 if (this.scrollbarV && this.virtualization) {
3078 let idx = 0;
3079 if (this.groupedRows) {
3080 // Get the latest row rowindex in a group
3081 const row = rows[rows.length - 1];
3082 idx = row ? this.getRowIndex(row) : 0;
3083 }
3084 else {
3085 idx = this.getRowIndex(rows);
3086 }
3087 // const pos = idx * rowHeight;
3088 // The position of this row would be the sum of all row heights
3089 // until the previous row position.
3090 const pos = this.rowHeightsCache.query(idx - 1);
3091 translateXY(styles, 0, pos);
3092 }
3093 return styles;
3094 }
3095 /**
3096 * Calculate bottom summary row offset for scrollbar mode.
3097 * For more information about cache and offset calculation
3098 * see description for `getRowsStyles` method
3099 *
3100 * @returns the CSS3 style to be applied
3101 *
3102 * @memberOf DataTableBodyComponent
3103 */
3104 getBottomSummaryRowStyles() {
3105 if (!this.scrollbarV || !this.rows || !this.rows.length) {
3106 return null;
3107 }
3108 const styles = { position: 'absolute' };
3109 const pos = this.rowHeightsCache.query(this.rows.length - 1);
3110 translateXY(styles, 0, pos);
3111 return styles;
3112 }
3113 /**
3114 * Hides the loading indicator
3115 */
3116 hideIndicator() {
3117 setTimeout(() => (this.loadingIndicator = false), 500);
3118 }
3119 /**
3120 * Updates the index of the rows in the viewport
3121 */
3122 updateIndexes() {
3123 let first = 0;
3124 let last = 0;
3125 if (this.scrollbarV) {
3126 if (this.virtualization) {
3127 // Calculation of the first and last indexes will be based on where the
3128 // scrollY position would be at. The last index would be the one
3129 // that shows up inside the view port the last.
3130 const height = parseInt(this.bodyHeight, 0);
3131 first = this.rowHeightsCache.getRowIndex(this.offsetY);
3132 last = this.rowHeightsCache.getRowIndex(height + this.offsetY) + 1;
3133 }
3134 else {
3135 // If virtual rows are not needed
3136 // We render all in one go
3137 first = 0;
3138 last = this.rowCount;
3139 }
3140 }
3141 else {
3142 // The server is handling paging and will pass an array that begins with the
3143 // element at a specified offset. first should always be 0 with external paging.
3144 if (!this.externalPaging) {
3145 first = Math.max(this.offset * this.pageSize, 0);
3146 }
3147 last = Math.min(first + this.pageSize, this.rowCount);
3148 }
3149 this.indexes = { first, last };
3150 }
3151 /**
3152 * Refreshes the full Row Height cache. Should be used
3153 * when the entire row array state has changed.
3154 */
3155 refreshRowHeightCache() {
3156 if (!this.scrollbarV || (this.scrollbarV && !this.virtualization)) {
3157 return;
3158 }
3159 // clear the previous row height cache if already present.
3160 // this is useful during sorts, filters where the state of the
3161 // rows array is changed.
3162 this.rowHeightsCache.clearCache();
3163 // Initialize the tree only if there are rows inside the tree.
3164 if (this.rows && this.rows.length) {
3165 const rowExpansions = new Set();
3166 for (const row of this.rows) {
3167 if (this.getRowExpanded(row)) {
3168 rowExpansions.add(row);
3169 }
3170 }
3171 this.rowHeightsCache.initCache({
3172 rows: this.rows,
3173 rowHeight: this.rowHeight,
3174 detailRowHeight: this.getDetailRowHeight,
3175 externalVirtual: this.scrollbarV && this.externalPaging,
3176 rowCount: this.rowCount,
3177 rowIndexes: this.rowIndexes,
3178 rowExpansions
3179 });
3180 }
3181 }
3182 /**
3183 * Gets the index for the view port
3184 */
3185 getAdjustedViewPortIndex() {
3186 // Capture the row index of the first row that is visible on the viewport.
3187 // If the scroll bar is just below the row which is highlighted then make that as the
3188 // first index.
3189 const viewPortFirstRowIndex = this.indexes.first;
3190 if (this.scrollbarV && this.virtualization) {
3191 const offsetScroll = this.rowHeightsCache.query(viewPortFirstRowIndex - 1);
3192 return offsetScroll <= this.offsetY ? viewPortFirstRowIndex - 1 : viewPortFirstRowIndex;
3193 }
3194 return viewPortFirstRowIndex;
3195 }
3196 /**
3197 * Toggle the Expansion of the row i.e. if the row is expanded then it will
3198 * collapse and vice versa. Note that the expanded status is stored as
3199 * a part of the row object itself as we have to preserve the expanded row
3200 * status in case of sorting and filtering of the row set.
3201 */
3202 toggleRowExpansion(row) {
3203 // Capture the row index of the first row that is visible on the viewport.
3204 const viewPortFirstRowIndex = this.getAdjustedViewPortIndex();
3205 const rowExpandedIdx = this.getRowExpandedIdx(row, this.rowExpansions);
3206 const expanded = rowExpandedIdx > -1;
3207 // If the detailRowHeight is auto --> only in case of non-virtualized scroll
3208 if (this.scrollbarV && this.virtualization) {
3209 const detailRowHeight = this.getDetailRowHeight(row) * (expanded ? -1 : 1);
3210 // const idx = this.rowIndexes.get(row) || 0;
3211 const idx = this.getRowIndex(row);
3212 this.rowHeightsCache.update(idx, detailRowHeight);
3213 }
3214 // Update the toggled row and update thive nevere heights in the cache.
3215 if (expanded) {
3216 this.rowExpansions.splice(rowExpandedIdx, 1);
3217 }
3218 else {
3219 this.rowExpansions.push(row);
3220 }
3221 this.detailToggle.emit({
3222 rows: [row],
3223 currentIndex: viewPortFirstRowIndex
3224 });
3225 }
3226 /**
3227 * Expand/Collapse all the rows no matter what their state is.
3228 */
3229 toggleAllRows(expanded) {
3230 // clear prev expansions
3231 this.rowExpansions = [];
3232 // Capture the row index of the first row that is visible on the viewport.
3233 const viewPortFirstRowIndex = this.getAdjustedViewPortIndex();
3234 if (expanded) {
3235 for (const row of this.rows) {
3236 this.rowExpansions.push(row);
3237 }
3238 }
3239 if (this.scrollbarV) {
3240 // Refresh the full row heights cache since every row was affected.
3241 this.recalcLayout();
3242 }
3243 // Emit all rows that have been expanded.
3244 this.detailToggle.emit({
3245 rows: this.rows,
3246 currentIndex: viewPortFirstRowIndex
3247 });
3248 }
3249 /**
3250 * Recalculates the table
3251 */
3252 recalcLayout() {
3253 this.refreshRowHeightCache();
3254 this.updateIndexes();
3255 this.updateRows();
3256 }
3257 /**
3258 * Tracks the column
3259 */
3260 columnTrackingFn(index, column) {
3261 return column.$$id;
3262 }
3263 /**
3264 * Gets the row pinning group styles
3265 */
3266 stylesByGroup(group) {
3267 const widths = this.columnGroupWidths;
3268 const offsetX = this.offsetX;
3269 const styles = {
3270 width: `${widths[group]}px`
3271 };
3272 if (group === 'left') {
3273 translateXY(styles, offsetX, 0);
3274 }
3275 else if (group === 'right') {
3276 const bodyWidth = parseInt(this.innerWidth + '', 0);
3277 const totalDiff = widths.total - bodyWidth;
3278 const offsetDiff = totalDiff - offsetX;
3279 const offset = offsetDiff * -1;
3280 translateXY(styles, offset, 0);
3281 }
3282 return styles;
3283 }
3284 /**
3285 * Returns if the row was expanded and set default row expansion when row expansion is empty
3286 */
3287 getRowExpanded(row) {
3288 if (this.rowExpansions.length === 0 && this.groupExpansionDefault) {
3289 for (const group of this.groupedRows) {
3290 this.rowExpansions.push(group);
3291 }
3292 }
3293 return this.getRowExpandedIdx(row, this.rowExpansions) > -1;
3294 }
3295 getRowExpandedIdx(row, expanded) {
3296 if (!expanded || !expanded.length)
3297 return -1;
3298 const rowId = this.rowIdentity(row);
3299 return expanded.findIndex(r => {
3300 const id = this.rowIdentity(r);
3301 return id === rowId;
3302 });
3303 }
3304 /**
3305 * Gets the row index given a row
3306 */
3307 getRowIndex(row) {
3308 return this.rowIndexes.get(row) || 0;
3309 }
3310 onTreeAction(row) {
3311 this.treeAction.emit({ row });
3312 }
3313}
3314DataTableBodyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableBodyComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3315DataTableBodyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTableBodyComponent, selector: "datatable-body", inputs: { scrollbarV: "scrollbarV", scrollbarH: "scrollbarH", loadingIndicator: "loadingIndicator", externalPaging: "externalPaging", rowHeight: "rowHeight", offsetX: "offsetX", emptyMessage: "emptyMessage", selectionType: "selectionType", selected: "selected", rowIdentity: "rowIdentity", rowDetail: "rowDetail", groupHeader: "groupHeader", selectCheck: "selectCheck", displayCheck: "displayCheck", trackByProp: "trackByProp", rowClass: "rowClass", groupedRows: "groupedRows", groupExpansionDefault: "groupExpansionDefault", innerWidth: "innerWidth", groupRowsBy: "groupRowsBy", virtualization: "virtualization", summaryRow: "summaryRow", summaryPosition: "summaryPosition", summaryHeight: "summaryHeight", pageSize: "pageSize", rows: "rows", columns: "columns", offset: "offset", rowCount: "rowCount", bodyHeight: "bodyHeight" }, outputs: { scroll: "scroll", page: "page", activate: "activate", select: "select", detailToggle: "detailToggle", rowContextmenu: "rowContextmenu", treeAction: "treeAction" }, host: { properties: { "style.width": "this.bodyWidth", "style.height": "this.bodyHeight" }, classAttribute: "datatable-body" }, viewQueries: [{ propertyName: "scroller", first: true, predicate: ScrollerComponent, descendants: true }], ngImport: i0, template: `
3316 <datatable-progress *ngIf="loadingIndicator"> </datatable-progress>
3317 <datatable-selection
3318 #selector
3319 [selected]="selected"
3320 [rows]="rows"
3321 [selectCheck]="selectCheck"
3322 [selectEnabled]="selectEnabled"
3323 [selectionType]="selectionType"
3324 [rowIdentity]="rowIdentity"
3325 (select)="select.emit($event)"
3326 (activate)="activate.emit($event)"
3327 >
3328 <datatable-scroller
3329 *ngIf="rows?.length"
3330 [scrollbarV]="scrollbarV"
3331 [scrollbarH]="scrollbarH"
3332 [scrollHeight]="scrollHeight"
3333 [scrollWidth]="columnGroupWidths?.total"
3334 (scroll)="onBodyScroll($event)"
3335 >
3336 <datatable-summary-row
3337 *ngIf="summaryRow && summaryPosition === 'top'"
3338 [rowHeight]="summaryHeight"
3339 [offsetX]="offsetX"
3340 [innerWidth]="innerWidth"
3341 [rows]="rows"
3342 [columns]="columns"
3343 >
3344 </datatable-summary-row>
3345 <datatable-row-wrapper
3346 [groupedRows]="groupedRows"
3347 *ngFor="let group of temp; let i = index; trackBy: rowTrackingFn"
3348 [innerWidth]="innerWidth"
3349 [ngStyle]="getRowsStyles(group)"
3350 [rowDetail]="rowDetail"
3351 [groupHeader]="groupHeader"
3352 [offsetX]="offsetX"
3353 [detailRowHeight]="getDetailRowHeight(group && group[i], i)"
3354 [row]="group"
3355 [expanded]="getRowExpanded(group)"
3356 [rowIndex]="getRowIndex(group && group[i])"
3357 (rowContextmenu)="rowContextmenu.emit($event)"
3358 >
3359 <datatable-body-row
3360 role="row"
3361 *ngIf="!groupedRows; else groupedRowsTemplate"
3362 tabindex="-1"
3363 [isSelected]="selector.getRowSelected(group)"
3364 [innerWidth]="innerWidth"
3365 [offsetX]="offsetX"
3366 [columns]="columns"
3367 [rowHeight]="getRowHeight(group)"
3368 [row]="group"
3369 [rowIndex]="getRowIndex(group)"
3370 [expanded]="getRowExpanded(group)"
3371 [rowClass]="rowClass"
3372 [displayCheck]="displayCheck"
3373 [treeStatus]="group && group.treeStatus"
3374 (treeAction)="onTreeAction(group)"
3375 (activate)="selector.onActivate($event, indexes.first + i)"
3376 >
3377 </datatable-body-row>
3378 <ng-template #groupedRowsTemplate>
3379 <datatable-body-row
3380 role="row"
3381 *ngFor="let row of group.value; let i = index; trackBy: rowTrackingFn"
3382 tabindex="-1"
3383 [isSelected]="selector.getRowSelected(row)"
3384 [innerWidth]="innerWidth"
3385 [offsetX]="offsetX"
3386 [columns]="columns"
3387 [rowHeight]="getRowHeight(row)"
3388 [row]="row"
3389 [group]="group.value"
3390 [rowIndex]="getRowIndex(row)"
3391 [expanded]="getRowExpanded(row)"
3392 [rowClass]="rowClass"
3393 (activate)="selector.onActivate($event, i)"
3394 >
3395 </datatable-body-row>
3396 </ng-template>
3397 </datatable-row-wrapper>
3398 <datatable-summary-row
3399 role="row"
3400 *ngIf="summaryRow && summaryPosition === 'bottom'"
3401 [ngStyle]="getBottomSummaryRowStyles()"
3402 [rowHeight]="summaryHeight"
3403 [offsetX]="offsetX"
3404 [innerWidth]="innerWidth"
3405 [rows]="rows"
3406 [columns]="columns"
3407 >
3408 </datatable-summary-row>
3409 </datatable-scroller>
3410 <div class="empty-row" *ngIf="!rows?.length && !loadingIndicator" [innerHTML]="emptyMessage"></div>
3411 </datatable-selection>
3412 `, isInline: true, components: [{ type: ProgressBarComponent, selector: "datatable-progress" }, { type: DataTableSelectionComponent, selector: "datatable-selection", inputs: ["rows", "selected", "selectEnabled", "selectionType", "rowIdentity", "selectCheck"], outputs: ["activate", "select"] }, { type: ScrollerComponent, selector: "datatable-scroller", inputs: ["scrollbarV", "scrollbarH", "scrollHeight", "scrollWidth"], outputs: ["scroll"] }, { type: DataTableSummaryRowComponent, selector: "datatable-summary-row", inputs: ["rows", "columns", "rowHeight", "offsetX", "innerWidth"] }, { type: DataTableRowWrapperComponent, selector: "datatable-row-wrapper", inputs: ["innerWidth", "rowDetail", "groupHeader", "offsetX", "detailRowHeight", "row", "groupedRows", "rowIndex", "expanded"], outputs: ["rowContextmenu"] }, { type: DataTableBodyRowComponent, selector: "datatable-body-row", inputs: ["columns", "innerWidth", "expanded", "rowClass", "row", "group", "isSelected", "rowIndex", "displayCheck", "treeStatus", "offsetX", "rowHeight"], outputs: ["activate", "treeAction"] }], directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3413i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableBodyComponent, decorators: [{
3414 type: Component,
3415 args: [{
3416 selector: 'datatable-body',
3417 template: `
3418 <datatable-progress *ngIf="loadingIndicator"> </datatable-progress>
3419 <datatable-selection
3420 #selector
3421 [selected]="selected"
3422 [rows]="rows"
3423 [selectCheck]="selectCheck"
3424 [selectEnabled]="selectEnabled"
3425 [selectionType]="selectionType"
3426 [rowIdentity]="rowIdentity"
3427 (select)="select.emit($event)"
3428 (activate)="activate.emit($event)"
3429 >
3430 <datatable-scroller
3431 *ngIf="rows?.length"
3432 [scrollbarV]="scrollbarV"
3433 [scrollbarH]="scrollbarH"
3434 [scrollHeight]="scrollHeight"
3435 [scrollWidth]="columnGroupWidths?.total"
3436 (scroll)="onBodyScroll($event)"
3437 >
3438 <datatable-summary-row
3439 *ngIf="summaryRow && summaryPosition === 'top'"
3440 [rowHeight]="summaryHeight"
3441 [offsetX]="offsetX"
3442 [innerWidth]="innerWidth"
3443 [rows]="rows"
3444 [columns]="columns"
3445 >
3446 </datatable-summary-row>
3447 <datatable-row-wrapper
3448 [groupedRows]="groupedRows"
3449 *ngFor="let group of temp; let i = index; trackBy: rowTrackingFn"
3450 [innerWidth]="innerWidth"
3451 [ngStyle]="getRowsStyles(group)"
3452 [rowDetail]="rowDetail"
3453 [groupHeader]="groupHeader"
3454 [offsetX]="offsetX"
3455 [detailRowHeight]="getDetailRowHeight(group && group[i], i)"
3456 [row]="group"
3457 [expanded]="getRowExpanded(group)"
3458 [rowIndex]="getRowIndex(group && group[i])"
3459 (rowContextmenu)="rowContextmenu.emit($event)"
3460 >
3461 <datatable-body-row
3462 role="row"
3463 *ngIf="!groupedRows; else groupedRowsTemplate"
3464 tabindex="-1"
3465 [isSelected]="selector.getRowSelected(group)"
3466 [innerWidth]="innerWidth"
3467 [offsetX]="offsetX"
3468 [columns]="columns"
3469 [rowHeight]="getRowHeight(group)"
3470 [row]="group"
3471 [rowIndex]="getRowIndex(group)"
3472 [expanded]="getRowExpanded(group)"
3473 [rowClass]="rowClass"
3474 [displayCheck]="displayCheck"
3475 [treeStatus]="group && group.treeStatus"
3476 (treeAction)="onTreeAction(group)"
3477 (activate)="selector.onActivate($event, indexes.first + i)"
3478 >
3479 </datatable-body-row>
3480 <ng-template #groupedRowsTemplate>
3481 <datatable-body-row
3482 role="row"
3483 *ngFor="let row of group.value; let i = index; trackBy: rowTrackingFn"
3484 tabindex="-1"
3485 [isSelected]="selector.getRowSelected(row)"
3486 [innerWidth]="innerWidth"
3487 [offsetX]="offsetX"
3488 [columns]="columns"
3489 [rowHeight]="getRowHeight(row)"
3490 [row]="row"
3491 [group]="group.value"
3492 [rowIndex]="getRowIndex(row)"
3493 [expanded]="getRowExpanded(row)"
3494 [rowClass]="rowClass"
3495 (activate)="selector.onActivate($event, i)"
3496 >
3497 </datatable-body-row>
3498 </ng-template>
3499 </datatable-row-wrapper>
3500 <datatable-summary-row
3501 role="row"
3502 *ngIf="summaryRow && summaryPosition === 'bottom'"
3503 [ngStyle]="getBottomSummaryRowStyles()"
3504 [rowHeight]="summaryHeight"
3505 [offsetX]="offsetX"
3506 [innerWidth]="innerWidth"
3507 [rows]="rows"
3508 [columns]="columns"
3509 >
3510 </datatable-summary-row>
3511 </datatable-scroller>
3512 <div class="empty-row" *ngIf="!rows?.length && !loadingIndicator" [innerHTML]="emptyMessage"></div>
3513 </datatable-selection>
3514 `,
3515 changeDetection: ChangeDetectionStrategy.OnPush,
3516 host: {
3517 class: 'datatable-body'
3518 }
3519 }]
3520 }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { scrollbarV: [{
3521 type: Input
3522 }], scrollbarH: [{
3523 type: Input
3524 }], loadingIndicator: [{
3525 type: Input
3526 }], externalPaging: [{
3527 type: Input
3528 }], rowHeight: [{
3529 type: Input
3530 }], offsetX: [{
3531 type: Input
3532 }], emptyMessage: [{
3533 type: Input
3534 }], selectionType: [{
3535 type: Input
3536 }], selected: [{
3537 type: Input
3538 }], rowIdentity: [{
3539 type: Input
3540 }], rowDetail: [{
3541 type: Input
3542 }], groupHeader: [{
3543 type: Input
3544 }], selectCheck: [{
3545 type: Input
3546 }], displayCheck: [{
3547 type: Input
3548 }], trackByProp: [{
3549 type: Input
3550 }], rowClass: [{
3551 type: Input
3552 }], groupedRows: [{
3553 type: Input
3554 }], groupExpansionDefault: [{
3555 type: Input
3556 }], innerWidth: [{
3557 type: Input
3558 }], groupRowsBy: [{
3559 type: Input
3560 }], virtualization: [{
3561 type: Input
3562 }], summaryRow: [{
3563 type: Input
3564 }], summaryPosition: [{
3565 type: Input
3566 }], summaryHeight: [{
3567 type: Input
3568 }], pageSize: [{
3569 type: Input
3570 }], rows: [{
3571 type: Input
3572 }], columns: [{
3573 type: Input
3574 }], offset: [{
3575 type: Input
3576 }], rowCount: [{
3577 type: Input
3578 }], bodyWidth: [{
3579 type: HostBinding,
3580 args: ['style.width']
3581 }], bodyHeight: [{
3582 type: Input
3583 }, {
3584 type: HostBinding,
3585 args: ['style.height']
3586 }], scroll: [{
3587 type: Output
3588 }], page: [{
3589 type: Output
3590 }], activate: [{
3591 type: Output
3592 }], select: [{
3593 type: Output
3594 }], detailToggle: [{
3595 type: Output
3596 }], rowContextmenu: [{
3597 type: Output
3598 }], treeAction: [{
3599 type: Output
3600 }], scroller: [{
3601 type: ViewChild,
3602 args: [ScrollerComponent]
3603 }] } });
3604
3605/**
3606 * Gets the next sort direction
3607 */
3608function nextSortDir(sortType, current) {
3609 if (sortType === SortType.single) {
3610 if (current === SortDirection.asc) {
3611 return SortDirection.desc;
3612 }
3613 else {
3614 return SortDirection.asc;
3615 }
3616 }
3617 else {
3618 if (!current) {
3619 return SortDirection.asc;
3620 }
3621 else if (current === SortDirection.asc) {
3622 return SortDirection.desc;
3623 }
3624 else if (current === SortDirection.desc) {
3625 return undefined;
3626 }
3627 // avoid TS7030: Not all code paths return a value.
3628 return undefined;
3629 }
3630}
3631/**
3632 * Adapted from fueld-ui on 6/216
3633 * https://github.com/FuelInteractive/fuel-ui/tree/master/src/pipes/OrderBy
3634 */
3635function orderByComparator(a, b) {
3636 if (a === null || typeof a === 'undefined')
3637 a = 0;
3638 if (b === null || typeof b === 'undefined')
3639 b = 0;
3640 if (a instanceof Date && b instanceof Date) {
3641 if (a < b)
3642 return -1;
3643 if (a > b)
3644 return 1;
3645 }
3646 else if (isNaN(parseFloat(a)) || !isFinite(a) || isNaN(parseFloat(b)) || !isFinite(b)) {
3647 // Convert to string in case of a=0 or b=0
3648 a = String(a);
3649 b = String(b);
3650 // Isn't a number so lowercase the string to properly compare
3651 if (a.toLowerCase() < b.toLowerCase())
3652 return -1;
3653 if (a.toLowerCase() > b.toLowerCase())
3654 return 1;
3655 }
3656 else {
3657 // Parse strings as numbers to compare properly
3658 if (parseFloat(a) < parseFloat(b))
3659 return -1;
3660 if (parseFloat(a) > parseFloat(b))
3661 return 1;
3662 }
3663 // equal each other
3664 return 0;
3665}
3666/**
3667 * creates a shallow copy of the `rows` input and returns the sorted copy. this function
3668 * does not sort the `rows` argument in place
3669 */
3670function sortRows(rows, columns, dirs) {
3671 if (!rows)
3672 return [];
3673 if (!dirs || !dirs.length || !columns)
3674 return [...rows];
3675 /**
3676 * record the row ordering of results from prior sort operations (if applicable)
3677 * this is necessary to guarantee stable sorting behavior
3678 */
3679 const rowToIndexMap = new Map();
3680 rows.forEach((row, index) => rowToIndexMap.set(row, index));
3681 const temp = [...rows];
3682 const cols = columns.reduce((obj, col) => {
3683 if (col.comparator && typeof col.comparator === 'function') {
3684 obj[col.prop] = col.comparator;
3685 }
3686 return obj;
3687 }, {});
3688 // cache valueGetter and compareFn so that they
3689 // do not need to be looked-up in the sort function body
3690 const cachedDirs = dirs.map(dir => {
3691 const prop = dir.prop;
3692 return {
3693 prop,
3694 dir: dir.dir,
3695 valueGetter: getterForProp(prop),
3696 compareFn: cols[prop] || orderByComparator
3697 };
3698 });
3699 return temp.sort(function (rowA, rowB) {
3700 for (const cachedDir of cachedDirs) {
3701 // Get property and valuegetters for column to be sorted
3702 const { prop, valueGetter } = cachedDir;
3703 // Get A and B cell values from rows based on properties of the columns
3704 const propA = valueGetter(rowA, prop);
3705 const propB = valueGetter(rowB, prop);
3706 // Compare function gets five parameters:
3707 // Two cell values to be compared as propA and propB
3708 // Two rows corresponding to the cells as rowA and rowB
3709 // Direction of the sort for this column as SortDirection
3710 // Compare can be a standard JS comparison function (a,b) => -1|0|1
3711 // as additional parameters are silently ignored. The whole row and sort
3712 // direction enable more complex sort logic.
3713 const comparison = cachedDir.dir !== SortDirection.desc
3714 ? cachedDir.compareFn(propA, propB, rowA, rowB, cachedDir.dir)
3715 : -cachedDir.compareFn(propA, propB, rowA, rowB, cachedDir.dir);
3716 // Don't return 0 yet in case of needing to sort by next property
3717 if (comparison !== 0)
3718 return comparison;
3719 }
3720 if (!(rowToIndexMap.has(rowA) && rowToIndexMap.has(rowB)))
3721 return 0;
3722 /**
3723 * all else being equal, preserve original order of the rows (stable sort)
3724 */
3725 return rowToIndexMap.get(rowA) < rowToIndexMap.get(rowB) ? -1 : 1;
3726 });
3727}
3728
3729class DataTableHeaderCellComponent {
3730 constructor(cd) {
3731 this.cd = cd;
3732 this.sort = new EventEmitter();
3733 this.select = new EventEmitter();
3734 this.columnContextmenu = new EventEmitter(false);
3735 this.sortFn = this.onSort.bind(this);
3736 this.selectFn = this.select.emit.bind(this.select);
3737 this.cellContext = {
3738 column: this.column,
3739 sortDir: this.sortDir,
3740 sortFn: this.sortFn,
3741 allRowsSelected: this.allRowsSelected,
3742 selectFn: this.selectFn
3743 };
3744 }
3745 set allRowsSelected(value) {
3746 this._allRowsSelected = value;
3747 this.cellContext.allRowsSelected = value;
3748 }
3749 get allRowsSelected() {
3750 return this._allRowsSelected;
3751 }
3752 set column(column) {
3753 this._column = column;
3754 this.cellContext.column = column;
3755 this.cd.markForCheck();
3756 }
3757 get column() {
3758 return this._column;
3759 }
3760 set sorts(val) {
3761 this._sorts = val;
3762 this.sortDir = this.calcSortDir(val);
3763 this.cellContext.sortDir = this.sortDir;
3764 this.sortClass = this.calcSortClass(this.sortDir);
3765 this.cd.markForCheck();
3766 }
3767 get sorts() {
3768 return this._sorts;
3769 }
3770 get columnCssClasses() {
3771 let cls = 'datatable-header-cell';
3772 if (this.column.sortable)
3773 cls += ' sortable';
3774 if (this.column.resizeable)
3775 cls += ' resizeable';
3776 if (this.column.headerClass) {
3777 if (typeof this.column.headerClass === 'string') {
3778 cls += ' ' + this.column.headerClass;
3779 }
3780 else if (typeof this.column.headerClass === 'function') {
3781 const res = this.column.headerClass({
3782 column: this.column
3783 });
3784 if (typeof res === 'string') {
3785 cls += res;
3786 }
3787 else if (typeof res === 'object') {
3788 const keys = Object.keys(res);
3789 for (const k of keys) {
3790 if (res[k] === true)
3791 cls += ` ${k}`;
3792 }
3793 }
3794 }
3795 }
3796 const sortDir = this.sortDir;
3797 if (sortDir) {
3798 cls += ` sort-active sort-${sortDir}`;
3799 }
3800 return cls;
3801 }
3802 get name() {
3803 // guaranteed to have a value by setColumnDefaults() in column-helper.ts
3804 return this.column.headerTemplate === undefined ? this.column.name : undefined;
3805 }
3806 get minWidth() {
3807 return this.column.minWidth;
3808 }
3809 get maxWidth() {
3810 return this.column.maxWidth;
3811 }
3812 get width() {
3813 return this.column.width;
3814 }
3815 get isCheckboxable() {
3816 return this.column.checkboxable && this.column.headerCheckboxable && this.selectionType === SelectionType.checkbox;
3817 }
3818 onContextmenu($event) {
3819 this.columnContextmenu.emit({ event: $event, column: this.column });
3820 }
3821 ngOnInit() {
3822 this.sortClass = this.calcSortClass(this.sortDir);
3823 }
3824 calcSortDir(sorts) {
3825 if (sorts && this.column) {
3826 const sort = sorts.find((s) => {
3827 return s.prop === this.column.prop;
3828 });
3829 if (sort)
3830 return sort.dir;
3831 }
3832 }
3833 onSort() {
3834 if (!this.column.sortable)
3835 return;
3836 const newValue = nextSortDir(this.sortType, this.sortDir);
3837 this.sort.emit({
3838 column: this.column,
3839 prevValue: this.sortDir,
3840 newValue
3841 });
3842 }
3843 calcSortClass(sortDir) {
3844 if (!this.cellContext.column.sortable)
3845 return;
3846 if (sortDir === SortDirection.asc) {
3847 return `sort-btn sort-asc ${this.sortAscendingIcon}`;
3848 }
3849 else if (sortDir === SortDirection.desc) {
3850 return `sort-btn sort-desc ${this.sortDescendingIcon}`;
3851 }
3852 else {
3853 return `sort-btn ${this.sortUnsetIcon}`;
3854 }
3855 }
3856}
3857DataTableHeaderCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableHeaderCellComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3858DataTableHeaderCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTableHeaderCellComponent, selector: "datatable-header-cell", inputs: { sortType: "sortType", sortAscendingIcon: "sortAscendingIcon", sortDescendingIcon: "sortDescendingIcon", sortUnsetIcon: "sortUnsetIcon", isTarget: "isTarget", targetMarkerTemplate: "targetMarkerTemplate", targetMarkerContext: "targetMarkerContext", allRowsSelected: "allRowsSelected", selectionType: "selectionType", column: "column", headerHeight: "headerHeight", sorts: "sorts" }, outputs: { sort: "sort", select: "select", columnContextmenu: "columnContextmenu" }, host: { listeners: { "contextmenu": "onContextmenu($event)" }, properties: { "style.height.px": "this.headerHeight", "class": "this.columnCssClasses", "attr.title": "this.name", "style.minWidth.px": "this.minWidth", "style.maxWidth.px": "this.maxWidth", "style.width.px": "this.width" }, classAttribute: "datatable-header-cell" }, ngImport: i0, template: `
3859 <div class="datatable-header-cell-template-wrap">
3860 <ng-template
3861 *ngIf="isTarget"
3862 [ngTemplateOutlet]="targetMarkerTemplate"
3863 [ngTemplateOutletContext]="targetMarkerContext"
3864 >
3865 </ng-template>
3866 <label *ngIf="isCheckboxable" class="datatable-checkbox">
3867 <input type="checkbox" [checked]="allRowsSelected" (change)="select.emit(!allRowsSelected)" />
3868 </label>
3869 <span *ngIf="!column.headerTemplate" class="datatable-header-cell-wrapper">
3870 <span class="datatable-header-cell-label draggable" (click)="onSort()" [innerHTML]="name"> </span>
3871 </span>
3872 <ng-template
3873 *ngIf="column.headerTemplate"
3874 [ngTemplateOutlet]="column.headerTemplate"
3875 [ngTemplateOutletContext]="cellContext"
3876 >
3877 </ng-template>
3878 <span (click)="onSort()" [class]="sortClass"> </span>
3879 </div>
3880 `, isInline: true, directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3881i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableHeaderCellComponent, decorators: [{
3882 type: Component,
3883 args: [{
3884 selector: 'datatable-header-cell',
3885 template: `
3886 <div class="datatable-header-cell-template-wrap">
3887 <ng-template
3888 *ngIf="isTarget"
3889 [ngTemplateOutlet]="targetMarkerTemplate"
3890 [ngTemplateOutletContext]="targetMarkerContext"
3891 >
3892 </ng-template>
3893 <label *ngIf="isCheckboxable" class="datatable-checkbox">
3894 <input type="checkbox" [checked]="allRowsSelected" (change)="select.emit(!allRowsSelected)" />
3895 </label>
3896 <span *ngIf="!column.headerTemplate" class="datatable-header-cell-wrapper">
3897 <span class="datatable-header-cell-label draggable" (click)="onSort()" [innerHTML]="name"> </span>
3898 </span>
3899 <ng-template
3900 *ngIf="column.headerTemplate"
3901 [ngTemplateOutlet]="column.headerTemplate"
3902 [ngTemplateOutletContext]="cellContext"
3903 >
3904 </ng-template>
3905 <span (click)="onSort()" [class]="sortClass"> </span>
3906 </div>
3907 `,
3908 host: {
3909 class: 'datatable-header-cell'
3910 },
3911 changeDetection: ChangeDetectionStrategy.OnPush
3912 }]
3913 }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { sortType: [{
3914 type: Input
3915 }], sortAscendingIcon: [{
3916 type: Input
3917 }], sortDescendingIcon: [{
3918 type: Input
3919 }], sortUnsetIcon: [{
3920 type: Input
3921 }], isTarget: [{
3922 type: Input
3923 }], targetMarkerTemplate: [{
3924 type: Input
3925 }], targetMarkerContext: [{
3926 type: Input
3927 }], allRowsSelected: [{
3928 type: Input
3929 }], selectionType: [{
3930 type: Input
3931 }], column: [{
3932 type: Input
3933 }], headerHeight: [{
3934 type: HostBinding,
3935 args: ['style.height.px']
3936 }, {
3937 type: Input
3938 }], sorts: [{
3939 type: Input
3940 }], sort: [{
3941 type: Output
3942 }], select: [{
3943 type: Output
3944 }], columnContextmenu: [{
3945 type: Output
3946 }], columnCssClasses: [{
3947 type: HostBinding,
3948 args: ['class']
3949 }], name: [{
3950 type: HostBinding,
3951 args: ['attr.title']
3952 }], minWidth: [{
3953 type: HostBinding,
3954 args: ['style.minWidth.px']
3955 }], maxWidth: [{
3956 type: HostBinding,
3957 args: ['style.maxWidth.px']
3958 }], width: [{
3959 type: HostBinding,
3960 args: ['style.width.px']
3961 }], onContextmenu: [{
3962 type: HostListener,
3963 args: ['contextmenu', ['$event']]
3964 }] } });
3965
3966class DataTableHeaderComponent {
3967 constructor(cd) {
3968 this.cd = cd;
3969 this.sort = new EventEmitter();
3970 this.reorder = new EventEmitter();
3971 this.resize = new EventEmitter();
3972 this.select = new EventEmitter();
3973 this.columnContextmenu = new EventEmitter(false);
3974 this._columnGroupWidths = {
3975 total: 100
3976 };
3977 this._styleByGroup = {
3978 left: {},
3979 center: {},
3980 right: {}
3981 };
3982 this.destroyed = false;
3983 }
3984 set innerWidth(val) {
3985 this._innerWidth = val;
3986 setTimeout(() => {
3987 if (this._columns) {
3988 const colByPin = columnsByPin(this._columns);
3989 this._columnGroupWidths = columnGroupWidths(colByPin, this._columns);
3990 this.setStylesByGroup();
3991 }
3992 });
3993 }
3994 get innerWidth() {
3995 return this._innerWidth;
3996 }
3997 set headerHeight(val) {
3998 if (val !== 'auto') {
3999 this._headerHeight = `${val}px`;
4000 }
4001 else {
4002 this._headerHeight = val;
4003 }
4004 }
4005 get headerHeight() {
4006 return this._headerHeight;
4007 }
4008 set columns(val) {
4009 this._columns = val;
4010 const colsByPin = columnsByPin(val);
4011 this._columnsByPin = columnsByPinArr(val);
4012 setTimeout(() => {
4013 this._columnGroupWidths = columnGroupWidths(colsByPin, val);
4014 this.setStylesByGroup();
4015 });
4016 }
4017 get columns() {
4018 return this._columns;
4019 }
4020 set offsetX(val) {
4021 this._offsetX = val;
4022 this.setStylesByGroup();
4023 }
4024 get offsetX() {
4025 return this._offsetX;
4026 }
4027 ngOnDestroy() {
4028 this.destroyed = true;
4029 }
4030 onLongPressStart({ event, model }) {
4031 model.dragging = true;
4032 this.dragEventTarget = event;
4033 }
4034 onLongPressEnd({ event, model }) {
4035 this.dragEventTarget = event;
4036 // delay resetting so sort can be
4037 // prevented if we were dragging
4038 setTimeout(() => {
4039 // datatable component creates copies from columns on reorder
4040 // set dragging to false on new objects
4041 const column = this._columns.find(c => c.$$id === model.$$id);
4042 if (column) {
4043 column.dragging = false;
4044 }
4045 }, 5);
4046 }
4047 get headerWidth() {
4048 if (this.scrollbarH) {
4049 return this.innerWidth + 'px';
4050 }
4051 return '100%';
4052 }
4053 trackByGroups(index, colGroup) {
4054 return colGroup.type;
4055 }
4056 columnTrackingFn(index, column) {
4057 return column.$$id;
4058 }
4059 onColumnResized(width, column) {
4060 if (width <= column.minWidth) {
4061 width = column.minWidth;
4062 }
4063 else if (width >= column.maxWidth) {
4064 width = column.maxWidth;
4065 }
4066 this.resize.emit({
4067 column,
4068 prevValue: column.width,
4069 newValue: width
4070 });
4071 }
4072 onColumnReordered({ prevIndex, newIndex, model }) {
4073 const column = this.getColumn(newIndex);
4074 column.isTarget = false;
4075 column.targetMarkerContext = undefined;
4076 this.reorder.emit({
4077 column: model,
4078 prevValue: prevIndex,
4079 newValue: newIndex
4080 });
4081 }
4082 onTargetChanged({ prevIndex, newIndex, initialIndex }) {
4083 if (prevIndex || prevIndex === 0) {
4084 const oldColumn = this.getColumn(prevIndex);
4085 oldColumn.isTarget = false;
4086 oldColumn.targetMarkerContext = undefined;
4087 }
4088 if (newIndex || newIndex === 0) {
4089 const newColumn = this.getColumn(newIndex);
4090 newColumn.isTarget = true;
4091 if (initialIndex !== newIndex) {
4092 newColumn.targetMarkerContext = {
4093 class: 'targetMarker '.concat(initialIndex > newIndex ? 'dragFromRight' : 'dragFromLeft')
4094 };
4095 }
4096 }
4097 }
4098 getColumn(index) {
4099 const leftColumnCount = this._columnsByPin[0].columns.length;
4100 if (index < leftColumnCount) {
4101 return this._columnsByPin[0].columns[index];
4102 }
4103 const centerColumnCount = this._columnsByPin[1].columns.length;
4104 if (index < leftColumnCount + centerColumnCount) {
4105 return this._columnsByPin[1].columns[index - leftColumnCount];
4106 }
4107 return this._columnsByPin[2].columns[index - leftColumnCount - centerColumnCount];
4108 }
4109 onSort({ column, prevValue, newValue }) {
4110 // if we are dragging don't sort!
4111 if (column.dragging) {
4112 return;
4113 }
4114 const sorts = this.calcNewSorts(column, prevValue, newValue);
4115 this.sort.emit({
4116 sorts,
4117 column,
4118 prevValue,
4119 newValue
4120 });
4121 }
4122 calcNewSorts(column, prevValue, newValue) {
4123 let idx = 0;
4124 if (!this.sorts) {
4125 this.sorts = [];
4126 }
4127 const sorts = this.sorts.map((s, i) => {
4128 s = Object.assign({}, s);
4129 if (s.prop === column.prop) {
4130 idx = i;
4131 }
4132 return s;
4133 });
4134 if (newValue === undefined) {
4135 sorts.splice(idx, 1);
4136 }
4137 else if (prevValue) {
4138 sorts[idx].dir = newValue;
4139 }
4140 else {
4141 if (this.sortType === SortType.single) {
4142 sorts.splice(0, this.sorts.length);
4143 }
4144 sorts.push({ dir: newValue, prop: column.prop });
4145 }
4146 return sorts;
4147 }
4148 setStylesByGroup() {
4149 this._styleByGroup.left = this.calcStylesByGroup('left');
4150 this._styleByGroup.center = this.calcStylesByGroup('center');
4151 this._styleByGroup.right = this.calcStylesByGroup('right');
4152 if (!this.destroyed) {
4153 this.cd.detectChanges();
4154 }
4155 }
4156 calcStylesByGroup(group) {
4157 const widths = this._columnGroupWidths;
4158 const offsetX = this.offsetX;
4159 const styles = {
4160 width: `${widths[group]}px`
4161 };
4162 if (group === 'center') {
4163 translateXY(styles, offsetX * -1, 0);
4164 }
4165 else if (group === 'right') {
4166 const totalDiff = widths.total - this.innerWidth;
4167 const offset = totalDiff * -1;
4168 translateXY(styles, offset, 0);
4169 }
4170 return styles;
4171 }
4172}
4173DataTableHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableHeaderComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4174DataTableHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTableHeaderComponent, selector: "datatable-header", inputs: { sortAscendingIcon: "sortAscendingIcon", sortDescendingIcon: "sortDescendingIcon", sortUnsetIcon: "sortUnsetIcon", scrollbarH: "scrollbarH", dealsWithGroup: "dealsWithGroup", targetMarkerTemplate: "targetMarkerTemplate", innerWidth: "innerWidth", sorts: "sorts", sortType: "sortType", allRowsSelected: "allRowsSelected", selectionType: "selectionType", reorderable: "reorderable", headerHeight: "headerHeight", columns: "columns", offsetX: "offsetX" }, outputs: { sort: "sort", reorder: "reorder", resize: "resize", select: "select", columnContextmenu: "columnContextmenu" }, host: { properties: { "style.height": "this.headerHeight", "style.width": "this.headerWidth" }, classAttribute: "datatable-header" }, ngImport: i0, template: `
4175 <div
4176 role="row"
4177 orderable
4178 (reorder)="onColumnReordered($event)"
4179 (targetChanged)="onTargetChanged($event)"
4180 [style.width.px]="_columnGroupWidths.total"
4181 class="datatable-header-inner"
4182 >
4183 <div
4184 *ngFor="let colGroup of _columnsByPin; trackBy: trackByGroups"
4185 [class]="'datatable-row-' + colGroup.type"
4186 [ngStyle]="_styleByGroup[colGroup.type]"
4187 >
4188 <datatable-header-cell
4189 role="columnheader"
4190 *ngFor="let column of colGroup.columns; trackBy: columnTrackingFn"
4191 resizeable
4192 [resizeEnabled]="column.resizeable"
4193 (resize)="onColumnResized($event, column)"
4194 long-press
4195 [pressModel]="column"
4196 [pressEnabled]="reorderable && column.draggable"
4197 (longPressStart)="onLongPressStart($event)"
4198 (longPressEnd)="onLongPressEnd($event)"
4199 draggable
4200 [dragX]="reorderable && column.draggable && column.dragging"
4201 [dragY]="false"
4202 [dragModel]="column"
4203 [dragEventTarget]="dragEventTarget"
4204 [headerHeight]="headerHeight"
4205 [isTarget]="column.isTarget"
4206 [targetMarkerTemplate]="targetMarkerTemplate"
4207 [targetMarkerContext]="column.targetMarkerContext"
4208 [column]="column"
4209 [sortType]="sortType"
4210 [sorts]="sorts"
4211 [selectionType]="selectionType"
4212 [sortAscendingIcon]="sortAscendingIcon"
4213 [sortDescendingIcon]="sortDescendingIcon"
4214 [sortUnsetIcon]="sortUnsetIcon"
4215 [allRowsSelected]="allRowsSelected"
4216 (sort)="onSort($event)"
4217 (select)="select.emit($event)"
4218 (columnContextmenu)="columnContextmenu.emit($event)"
4219 >
4220 </datatable-header-cell>
4221 </div>
4222 </div>
4223 `, isInline: true, components: [{ type: DataTableHeaderCellComponent, selector: "datatable-header-cell", inputs: ["sortType", "sortAscendingIcon", "sortDescendingIcon", "sortUnsetIcon", "isTarget", "targetMarkerTemplate", "targetMarkerContext", "allRowsSelected", "selectionType", "column", "headerHeight", "sorts"], outputs: ["sort", "select", "columnContextmenu"] }], directives: [{ type: OrderableDirective, selector: "[orderable]", outputs: ["reorder", "targetChanged"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: ResizeableDirective, selector: "[resizeable]", inputs: ["resizeEnabled", "minWidth", "maxWidth"], outputs: ["resize"] }, { type: LongPressDirective, selector: "[long-press]", inputs: ["pressEnabled", "pressModel", "duration"], outputs: ["longPressStart", "longPressing", "longPressEnd"] }, { type: DraggableDirective, selector: "[draggable]", inputs: ["dragEventTarget", "dragModel", "dragX", "dragY"], outputs: ["dragStart", "dragging", "dragEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4224i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableHeaderComponent, decorators: [{
4225 type: Component,
4226 args: [{
4227 selector: 'datatable-header',
4228 template: `
4229 <div
4230 role="row"
4231 orderable
4232 (reorder)="onColumnReordered($event)"
4233 (targetChanged)="onTargetChanged($event)"
4234 [style.width.px]="_columnGroupWidths.total"
4235 class="datatable-header-inner"
4236 >
4237 <div
4238 *ngFor="let colGroup of _columnsByPin; trackBy: trackByGroups"
4239 [class]="'datatable-row-' + colGroup.type"
4240 [ngStyle]="_styleByGroup[colGroup.type]"
4241 >
4242 <datatable-header-cell
4243 role="columnheader"
4244 *ngFor="let column of colGroup.columns; trackBy: columnTrackingFn"
4245 resizeable
4246 [resizeEnabled]="column.resizeable"
4247 (resize)="onColumnResized($event, column)"
4248 long-press
4249 [pressModel]="column"
4250 [pressEnabled]="reorderable && column.draggable"
4251 (longPressStart)="onLongPressStart($event)"
4252 (longPressEnd)="onLongPressEnd($event)"
4253 draggable
4254 [dragX]="reorderable && column.draggable && column.dragging"
4255 [dragY]="false"
4256 [dragModel]="column"
4257 [dragEventTarget]="dragEventTarget"
4258 [headerHeight]="headerHeight"
4259 [isTarget]="column.isTarget"
4260 [targetMarkerTemplate]="targetMarkerTemplate"
4261 [targetMarkerContext]="column.targetMarkerContext"
4262 [column]="column"
4263 [sortType]="sortType"
4264 [sorts]="sorts"
4265 [selectionType]="selectionType"
4266 [sortAscendingIcon]="sortAscendingIcon"
4267 [sortDescendingIcon]="sortDescendingIcon"
4268 [sortUnsetIcon]="sortUnsetIcon"
4269 [allRowsSelected]="allRowsSelected"
4270 (sort)="onSort($event)"
4271 (select)="select.emit($event)"
4272 (columnContextmenu)="columnContextmenu.emit($event)"
4273 >
4274 </datatable-header-cell>
4275 </div>
4276 </div>
4277 `,
4278 host: {
4279 class: 'datatable-header'
4280 },
4281 changeDetection: ChangeDetectionStrategy.OnPush
4282 }]
4283 }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { sortAscendingIcon: [{
4284 type: Input
4285 }], sortDescendingIcon: [{
4286 type: Input
4287 }], sortUnsetIcon: [{
4288 type: Input
4289 }], scrollbarH: [{
4290 type: Input
4291 }], dealsWithGroup: [{
4292 type: Input
4293 }], targetMarkerTemplate: [{
4294 type: Input
4295 }], innerWidth: [{
4296 type: Input
4297 }], sorts: [{
4298 type: Input
4299 }], sortType: [{
4300 type: Input
4301 }], allRowsSelected: [{
4302 type: Input
4303 }], selectionType: [{
4304 type: Input
4305 }], reorderable: [{
4306 type: Input
4307 }], headerHeight: [{
4308 type: HostBinding,
4309 args: ['style.height']
4310 }, {
4311 type: Input
4312 }], columns: [{
4313 type: Input
4314 }], offsetX: [{
4315 type: Input
4316 }], sort: [{
4317 type: Output
4318 }], reorder: [{
4319 type: Output
4320 }], resize: [{
4321 type: Output
4322 }], select: [{
4323 type: Output
4324 }], columnContextmenu: [{
4325 type: Output
4326 }], headerWidth: [{
4327 type: HostBinding,
4328 args: ['style.width']
4329 }] } });
4330
4331/**
4332 * Throttle a function
4333 */
4334function throttle(func, wait, options) {
4335 options = options || {};
4336 let context;
4337 let args;
4338 let result;
4339 let timeout = null;
4340 let previous = 0;
4341 function later() {
4342 previous = options.leading === false ? 0 : +new Date();
4343 timeout = null;
4344 result = func.apply(context, args);
4345 }
4346 return function () {
4347 const now = +new Date();
4348 if (!previous && options.leading === false) {
4349 previous = now;
4350 }
4351 const remaining = wait - (now - previous);
4352 context = this;
4353 args = arguments;
4354 if (remaining <= 0) {
4355 clearTimeout(timeout);
4356 timeout = null;
4357 previous = now;
4358 result = func.apply(context, args);
4359 }
4360 else if (!timeout && options.trailing !== false) {
4361 timeout = setTimeout(later, remaining);
4362 }
4363 return result;
4364 };
4365}
4366/**
4367 * Throttle decorator
4368 *
4369 * class MyClass {
4370 * throttleable(10)
4371 * myFn() { ... }
4372 * }
4373 */
4374function throttleable(duration, options) {
4375 return function innerDecorator(target, key, descriptor) {
4376 return {
4377 configurable: true,
4378 enumerable: descriptor.enumerable,
4379 get: function getter() {
4380 Object.defineProperty(this, key, {
4381 configurable: true,
4382 enumerable: descriptor.enumerable,
4383 value: throttle(descriptor.value, duration, options)
4384 });
4385 return this[key];
4386 }
4387 };
4388 };
4389}
4390
4391/**
4392 * Calculates the Total Flex Grow
4393 */
4394function getTotalFlexGrow(columns) {
4395 let totalFlexGrow = 0;
4396 for (const c of columns) {
4397 totalFlexGrow += c.flexGrow || 0;
4398 }
4399 return totalFlexGrow;
4400}
4401/**
4402 * Adjusts the column widths.
4403 * Inspired by: https://github.com/facebook/fixed-data-table/blob/master/src/FixedDataTableWidthHelper.js
4404 */
4405function adjustColumnWidths(allColumns, expectedWidth) {
4406 const columnsWidth = columnsTotalWidth(allColumns);
4407 const totalFlexGrow = getTotalFlexGrow(allColumns);
4408 const colsByGroup = columnsByPin(allColumns);
4409 if (columnsWidth !== expectedWidth) {
4410 scaleColumns(colsByGroup, expectedWidth, totalFlexGrow);
4411 }
4412}
4413/**
4414 * Resizes columns based on the flexGrow property, while respecting manually set widths
4415 */
4416function scaleColumns(colsByGroup, maxWidth, totalFlexGrow) {
4417 // calculate total width and flexgrow points for coulumns that can be resized
4418 for (const attr in colsByGroup) {
4419 for (const column of colsByGroup[attr]) {
4420 if (!column.canAutoResize) {
4421 maxWidth -= column.width;
4422 totalFlexGrow -= column.flexGrow ? column.flexGrow : 0;
4423 }
4424 else {
4425 column.width = 0;
4426 }
4427 }
4428 }
4429 const hasMinWidth = {};
4430 let remainingWidth = maxWidth;
4431 // resize columns until no width is left to be distributed
4432 do {
4433 const widthPerFlexPoint = remainingWidth / totalFlexGrow;
4434 remainingWidth = 0;
4435 for (const attr in colsByGroup) {
4436 for (const column of colsByGroup[attr]) {
4437 // if the column can be resize and it hasn't reached its minimum width yet
4438 if (column.canAutoResize && !hasMinWidth[column.prop]) {
4439 const newWidth = column.width + column.flexGrow * widthPerFlexPoint;
4440 if (column.minWidth !== undefined && newWidth < column.minWidth) {
4441 remainingWidth += newWidth - column.minWidth;
4442 column.width = column.minWidth;
4443 hasMinWidth[column.prop] = true;
4444 }
4445 else {
4446 column.width = newWidth;
4447 }
4448 }
4449 }
4450 }
4451 } while (remainingWidth !== 0);
4452}
4453/**
4454 * Forces the width of the columns to
4455 * distribute equally but overflowing when necessary
4456 *
4457 * Rules:
4458 *
4459 * - If combined withs are less than the total width of the grid,
4460 * proportion the widths given the min / max / normal widths to fill the width.
4461 *
4462 * - If the combined widths, exceed the total width of the grid,
4463 * use the standard widths.
4464 *
4465 * - If a column is resized, it should always use that width
4466 *
4467 * - The proportional widths should never fall below min size if specified.
4468 *
4469 * - If the grid starts off small but then becomes greater than the size ( + / - )
4470 * the width should use the original width; not the newly proportioned widths.
4471 */
4472function forceFillColumnWidths(allColumns, expectedWidth, startIdx, allowBleed, defaultColWidth = 300) {
4473 const columnsToResize = allColumns.slice(startIdx + 1, allColumns.length).filter(c => {
4474 return c.canAutoResize !== false;
4475 });
4476 for (const column of columnsToResize) {
4477 if (!column.$$oldWidth) {
4478 column.$$oldWidth = column.width;
4479 }
4480 }
4481 let additionWidthPerColumn = 0;
4482 let exceedsWindow = false;
4483 let contentWidth = getContentWidth(allColumns, defaultColWidth);
4484 let remainingWidth = expectedWidth - contentWidth;
4485 const columnsProcessed = [];
4486 const remainingWidthLimit = 1; // when to stop
4487 // This loop takes care of the
4488 do {
4489 additionWidthPerColumn = remainingWidth / columnsToResize.length;
4490 exceedsWindow = contentWidth >= expectedWidth;
4491 for (const column of columnsToResize) {
4492 if (exceedsWindow && allowBleed) {
4493 column.width = column.$$oldWidth || column.width || defaultColWidth;
4494 }
4495 else {
4496 const newSize = (column.width || defaultColWidth) + additionWidthPerColumn;
4497 if (column.minWidth && newSize < column.minWidth) {
4498 column.width = column.minWidth;
4499 columnsProcessed.push(column);
4500 }
4501 else if (column.maxWidth && newSize > column.maxWidth) {
4502 column.width = column.maxWidth;
4503 columnsProcessed.push(column);
4504 }
4505 else {
4506 column.width = newSize;
4507 }
4508 }
4509 column.width = Math.max(0, column.width);
4510 }
4511 contentWidth = getContentWidth(allColumns);
4512 remainingWidth = expectedWidth - contentWidth;
4513 removeProcessedColumns(columnsToResize, columnsProcessed);
4514 } while (remainingWidth > remainingWidthLimit && columnsToResize.length !== 0);
4515}
4516/**
4517 * Remove the processed columns from the current active columns.
4518 */
4519function removeProcessedColumns(columnsToResize, columnsProcessed) {
4520 for (const column of columnsProcessed) {
4521 const index = columnsToResize.indexOf(column);
4522 columnsToResize.splice(index, 1);
4523 }
4524}
4525/**
4526 * Gets the width of the columns
4527 */
4528function getContentWidth(allColumns, defaultColWidth = 300) {
4529 let contentWidth = 0;
4530 for (const column of allColumns) {
4531 contentWidth += column.width || defaultColWidth;
4532 }
4533 return contentWidth;
4534}
4535
4536class DataTablePagerComponent {
4537 constructor() {
4538 this.change = new EventEmitter();
4539 this._count = 0;
4540 this._page = 1;
4541 this._size = 0;
4542 }
4543 set size(val) {
4544 this._size = val;
4545 this.pages = this.calcPages();
4546 }
4547 get size() {
4548 return this._size;
4549 }
4550 set count(val) {
4551 this._count = val;
4552 this.pages = this.calcPages();
4553 }
4554 get count() {
4555 return this._count;
4556 }
4557 set page(val) {
4558 this._page = val;
4559 this.pages = this.calcPages();
4560 }
4561 get page() {
4562 return this._page;
4563 }
4564 get totalPages() {
4565 const count = this.size < 1 ? 1 : Math.ceil(this.count / this.size);
4566 return Math.max(count || 0, 1);
4567 }
4568 canPrevious() {
4569 return this.page > 1;
4570 }
4571 canNext() {
4572 return this.page < this.totalPages;
4573 }
4574 prevPage() {
4575 this.selectPage(this.page - 1);
4576 }
4577 nextPage() {
4578 this.selectPage(this.page + 1);
4579 }
4580 selectPage(page) {
4581 if (page > 0 && page <= this.totalPages && page !== this.page) {
4582 this.page = page;
4583 this.change.emit({
4584 page
4585 });
4586 }
4587 }
4588 calcPages(page) {
4589 const pages = [];
4590 let startPage = 1;
4591 let endPage = this.totalPages;
4592 const maxSize = 5;
4593 const isMaxSized = maxSize < this.totalPages;
4594 page = page || this.page;
4595 if (isMaxSized) {
4596 startPage = page - Math.floor(maxSize / 2);
4597 endPage = page + Math.floor(maxSize / 2);
4598 if (startPage < 1) {
4599 startPage = 1;
4600 endPage = Math.min(startPage + maxSize - 1, this.totalPages);
4601 }
4602 else if (endPage > this.totalPages) {
4603 startPage = Math.max(this.totalPages - maxSize + 1, 1);
4604 endPage = this.totalPages;
4605 }
4606 }
4607 for (let num = startPage; num <= endPage; num++) {
4608 pages.push({
4609 number: num,
4610 text: num
4611 });
4612 }
4613 return pages;
4614 }
4615}
4616DataTablePagerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTablePagerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4617DataTablePagerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTablePagerComponent, selector: "datatable-pager", inputs: { pagerLeftArrowIcon: "pagerLeftArrowIcon", pagerRightArrowIcon: "pagerRightArrowIcon", pagerPreviousIcon: "pagerPreviousIcon", pagerNextIcon: "pagerNextIcon", size: "size", count: "count", page: "page" }, outputs: { change: "change" }, host: { classAttribute: "datatable-pager" }, ngImport: i0, template: `
4618 <ul class="pager">
4619 <li [class.disabled]="!canPrevious()">
4620 <a role="button" aria-label="go to first page" href="javascript:void(0)" (click)="selectPage(1)">
4621 <i class="{{ pagerPreviousIcon }}"></i>
4622 </a>
4623 </li>
4624 <li [class.disabled]="!canPrevious()">
4625 <a role="button" aria-label="go to previous page" href="javascript:void(0)" (click)="prevPage()">
4626 <i class="{{ pagerLeftArrowIcon }}"></i>
4627 </a>
4628 </li>
4629 <li
4630 role="button"
4631 [attr.aria-label]="'page ' + pg.number"
4632 class="pages"
4633 *ngFor="let pg of pages"
4634 [class.active]="pg.number === page"
4635 >
4636 <a href="javascript:void(0)" (click)="selectPage(pg.number)">
4637 {{ pg.text }}
4638 </a>
4639 </li>
4640 <li [class.disabled]="!canNext()">
4641 <a role="button" aria-label="go to next page" href="javascript:void(0)" (click)="nextPage()">
4642 <i class="{{ pagerRightArrowIcon }}"></i>
4643 </a>
4644 </li>
4645 <li [class.disabled]="!canNext()">
4646 <a role="button" aria-label="go to last page" href="javascript:void(0)" (click)="selectPage(totalPages)">
4647 <i class="{{ pagerNextIcon }}"></i>
4648 </a>
4649 </li>
4650 </ul>
4651 `, isInline: true, directives: [{ type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4652i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTablePagerComponent, decorators: [{
4653 type: Component,
4654 args: [{
4655 selector: 'datatable-pager',
4656 template: `
4657 <ul class="pager">
4658 <li [class.disabled]="!canPrevious()">
4659 <a role="button" aria-label="go to first page" href="javascript:void(0)" (click)="selectPage(1)">
4660 <i class="{{ pagerPreviousIcon }}"></i>
4661 </a>
4662 </li>
4663 <li [class.disabled]="!canPrevious()">
4664 <a role="button" aria-label="go to previous page" href="javascript:void(0)" (click)="prevPage()">
4665 <i class="{{ pagerLeftArrowIcon }}"></i>
4666 </a>
4667 </li>
4668 <li
4669 role="button"
4670 [attr.aria-label]="'page ' + pg.number"
4671 class="pages"
4672 *ngFor="let pg of pages"
4673 [class.active]="pg.number === page"
4674 >
4675 <a href="javascript:void(0)" (click)="selectPage(pg.number)">
4676 {{ pg.text }}
4677 </a>
4678 </li>
4679 <li [class.disabled]="!canNext()">
4680 <a role="button" aria-label="go to next page" href="javascript:void(0)" (click)="nextPage()">
4681 <i class="{{ pagerRightArrowIcon }}"></i>
4682 </a>
4683 </li>
4684 <li [class.disabled]="!canNext()">
4685 <a role="button" aria-label="go to last page" href="javascript:void(0)" (click)="selectPage(totalPages)">
4686 <i class="{{ pagerNextIcon }}"></i>
4687 </a>
4688 </li>
4689 </ul>
4690 `,
4691 host: {
4692 class: 'datatable-pager'
4693 },
4694 changeDetection: ChangeDetectionStrategy.OnPush
4695 }]
4696 }], propDecorators: { pagerLeftArrowIcon: [{
4697 type: Input
4698 }], pagerRightArrowIcon: [{
4699 type: Input
4700 }], pagerPreviousIcon: [{
4701 type: Input
4702 }], pagerNextIcon: [{
4703 type: Input
4704 }], size: [{
4705 type: Input
4706 }], count: [{
4707 type: Input
4708 }], page: [{
4709 type: Input
4710 }], change: [{
4711 type: Output
4712 }] } });
4713
4714class DataTableFooterComponent {
4715 constructor() {
4716 this.selectedCount = 0;
4717 this.page = new EventEmitter();
4718 }
4719 get isVisible() {
4720 return this.rowCount / this.pageSize > 1;
4721 }
4722 get curPage() {
4723 return this.offset + 1;
4724 }
4725}
4726DataTableFooterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4727DataTableFooterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DataTableFooterComponent, selector: "datatable-footer", inputs: { footerHeight: "footerHeight", rowCount: "rowCount", pageSize: "pageSize", offset: "offset", pagerLeftArrowIcon: "pagerLeftArrowIcon", pagerRightArrowIcon: "pagerRightArrowIcon", pagerPreviousIcon: "pagerPreviousIcon", pagerNextIcon: "pagerNextIcon", totalMessage: "totalMessage", footerTemplate: "footerTemplate", selectedCount: "selectedCount", selectedMessage: "selectedMessage" }, outputs: { page: "page" }, host: { classAttribute: "datatable-footer" }, ngImport: i0, template: `
4728 <div
4729 class="datatable-footer-inner"
4730 [ngClass]="{ 'selected-count': selectedMessage }"
4731 [style.height.px]="footerHeight"
4732 >
4733 <ng-template
4734 *ngIf="footerTemplate"
4735 [ngTemplateOutlet]="footerTemplate.template"
4736 [ngTemplateOutletContext]="{
4737 rowCount: rowCount,
4738 pageSize: pageSize,
4739 selectedCount: selectedCount,
4740 curPage: curPage,
4741 offset: offset
4742 }"
4743 >
4744 </ng-template>
4745 <div class="page-count" *ngIf="!footerTemplate">
4746 <span *ngIf="selectedMessage"> {{ selectedCount?.toLocaleString() }} {{ selectedMessage }} / </span>
4747 {{ rowCount?.toLocaleString() }} {{ totalMessage }}
4748 </div>
4749 <datatable-pager
4750 *ngIf="!footerTemplate"
4751 [pagerLeftArrowIcon]="pagerLeftArrowIcon"
4752 [pagerRightArrowIcon]="pagerRightArrowIcon"
4753 [pagerPreviousIcon]="pagerPreviousIcon"
4754 [pagerNextIcon]="pagerNextIcon"
4755 [page]="curPage"
4756 [size]="pageSize"
4757 [count]="rowCount"
4758 [hidden]="!isVisible"
4759 (change)="page.emit($event)"
4760 >
4761 </datatable-pager>
4762 </div>
4763 `, isInline: true, components: [{ type: DataTablePagerComponent, selector: "datatable-pager", inputs: ["pagerLeftArrowIcon", "pagerRightArrowIcon", "pagerPreviousIcon", "pagerNextIcon", "size", "count", "page"], outputs: ["change"] }], directives: [{ type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4764i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DataTableFooterComponent, decorators: [{
4765 type: Component,
4766 args: [{
4767 selector: 'datatable-footer',
4768 template: `
4769 <div
4770 class="datatable-footer-inner"
4771 [ngClass]="{ 'selected-count': selectedMessage }"
4772 [style.height.px]="footerHeight"
4773 >
4774 <ng-template
4775 *ngIf="footerTemplate"
4776 [ngTemplateOutlet]="footerTemplate.template"
4777 [ngTemplateOutletContext]="{
4778 rowCount: rowCount,
4779 pageSize: pageSize,
4780 selectedCount: selectedCount,
4781 curPage: curPage,
4782 offset: offset
4783 }"
4784 >
4785 </ng-template>
4786 <div class="page-count" *ngIf="!footerTemplate">
4787 <span *ngIf="selectedMessage"> {{ selectedCount?.toLocaleString() }} {{ selectedMessage }} / </span>
4788 {{ rowCount?.toLocaleString() }} {{ totalMessage }}
4789 </div>
4790 <datatable-pager
4791 *ngIf="!footerTemplate"
4792 [pagerLeftArrowIcon]="pagerLeftArrowIcon"
4793 [pagerRightArrowIcon]="pagerRightArrowIcon"
4794 [pagerPreviousIcon]="pagerPreviousIcon"
4795 [pagerNextIcon]="pagerNextIcon"
4796 [page]="curPage"
4797 [size]="pageSize"
4798 [count]="rowCount"
4799 [hidden]="!isVisible"
4800 (change)="page.emit($event)"
4801 >
4802 </datatable-pager>
4803 </div>
4804 `,
4805 host: {
4806 class: 'datatable-footer'
4807 },
4808 changeDetection: ChangeDetectionStrategy.OnPush
4809 }]
4810 }], propDecorators: { footerHeight: [{
4811 type: Input
4812 }], rowCount: [{
4813 type: Input
4814 }], pageSize: [{
4815 type: Input
4816 }], offset: [{
4817 type: Input
4818 }], pagerLeftArrowIcon: [{
4819 type: Input
4820 }], pagerRightArrowIcon: [{
4821 type: Input
4822 }], pagerPreviousIcon: [{
4823 type: Input
4824 }], pagerNextIcon: [{
4825 type: Input
4826 }], totalMessage: [{
4827 type: Input
4828 }], footerTemplate: [{
4829 type: Input
4830 }], selectedCount: [{
4831 type: Input
4832 }], selectedMessage: [{
4833 type: Input
4834 }], page: [{
4835 type: Output
4836 }] } });
4837
4838class DatatableComponent {
4839 constructor(scrollbarHelper, dimensionsHelper, cd, element, differs, columnChangesService, configuration) {
4840 this.scrollbarHelper = scrollbarHelper;
4841 this.dimensionsHelper = dimensionsHelper;
4842 this.cd = cd;
4843 this.columnChangesService = columnChangesService;
4844 this.configuration = configuration;
4845 /**
4846 * List of row objects that should be
4847 * represented as selected in the grid.
4848 * Default value: `[]`
4849 */
4850 this.selected = [];
4851 /**
4852 * Enable vertical scrollbars
4853 */
4854 this.scrollbarV = false;
4855 /**
4856 * Enable horz scrollbars
4857 */
4858 this.scrollbarH = false;
4859 /**
4860 * The row height; which is necessary
4861 * to calculate the height for the lazy rendering.
4862 */
4863 this.rowHeight = 30;
4864 /**
4865 * Type of column width distribution formula.
4866 * Example: flex, force, standard
4867 */
4868 this.columnMode = ColumnMode.standard;
4869 /**
4870 * The minimum header height in pixels.
4871 * Pass a falsey for no header
4872 */
4873 this.headerHeight = 30;
4874 /**
4875 * The minimum footer height in pixels.
4876 * Pass falsey for no footer
4877 */
4878 this.footerHeight = 0;
4879 /**
4880 * If the table should use external paging
4881 * otherwise its assumed that all data is preloaded.
4882 */
4883 this.externalPaging = false;
4884 /**
4885 * If the table should use external sorting or
4886 * the built-in basic sorting.
4887 */
4888 this.externalSorting = false;
4889 /**
4890 * Show the linear loading bar.
4891 * Default value: `false`
4892 */
4893 this.loadingIndicator = false;
4894 /**
4895 * Enable/Disable ability to re-order columns
4896 * by dragging them.
4897 */
4898 this.reorderable = true;
4899 /**
4900 * Swap columns on re-order columns or
4901 * move them.
4902 */
4903 this.swapColumns = true;
4904 /**
4905 * The type of sorting
4906 */
4907 this.sortType = SortType.single;
4908 /**
4909 * Array of sorted columns by property and type.
4910 * Default value: `[]`
4911 */
4912 this.sorts = [];
4913 /**
4914 * Css class overrides
4915 */
4916 this.cssClasses = {
4917 sortAscending: 'datatable-icon-up',
4918 sortDescending: 'datatable-icon-down',
4919 sortUnset: 'datatable-icon-sort-unset',
4920 pagerLeftArrow: 'datatable-icon-left',
4921 pagerRightArrow: 'datatable-icon-right',
4922 pagerPrevious: 'datatable-icon-prev',
4923 pagerNext: 'datatable-icon-skip'
4924 };
4925 /**
4926 * Message overrides for localization
4927 *
4928 * emptyMessage [default] = 'No data to display'
4929 * totalMessage [default] = 'total'
4930 * selectedMessage [default] = 'selected'
4931 */
4932 this.messages = {
4933 // Message to show when array is presented
4934 // but contains no values
4935 emptyMessage: 'No data to display',
4936 // Footer total message
4937 totalMessage: 'total',
4938 // Footer selected message
4939 selectedMessage: 'selected'
4940 };
4941 /**
4942 * A boolean you can use to set the detault behaviour of rows and groups
4943 * whether they will start expanded or not. If ommited the default is NOT expanded.
4944 *
4945 */
4946 this.groupExpansionDefault = false;
4947 /**
4948 * Property to which you can use for determining select all
4949 * rows on current page or not.
4950 *
4951 * @memberOf DatatableComponent
4952 */
4953 this.selectAllRowsOnPage = false;
4954 /**
4955 * A flag for row virtualization on / off
4956 */
4957 this.virtualization = true;
4958 /**
4959 * A flag for switching summary row on / off
4960 */
4961 this.summaryRow = false;
4962 /**
4963 * A height of summary row
4964 */
4965 this.summaryHeight = 30;
4966 /**
4967 * A property holds a summary row position: top/bottom
4968 */
4969 this.summaryPosition = 'top';
4970 /**
4971 * Body was scrolled typically in a `scrollbarV:true` scenario.
4972 */
4973 this.scroll = new EventEmitter();
4974 /**
4975 * A cell or row was focused via keyboard or mouse click.
4976 */
4977 this.activate = new EventEmitter();
4978 /**
4979 * A cell or row was selected.
4980 */
4981 this.select = new EventEmitter();
4982 /**
4983 * Column sort was invoked.
4984 */
4985 this.sort = new EventEmitter();
4986 /**
4987 * The table was paged either triggered by the pager or the body scroll.
4988 */
4989 this.page = new EventEmitter();
4990 /**
4991 * Columns were re-ordered.
4992 */
4993 this.reorder = new EventEmitter();
4994 /**
4995 * Column was resized.
4996 */
4997 this.resize = new EventEmitter();
4998 /**
4999 * The context menu was invoked on the table.
5000 * type indicates whether the header or the body was clicked.
5001 * content contains either the column or the row that was clicked.
5002 */
5003 this.tableContextmenu = new EventEmitter(false);
5004 /**
5005 * A row was expanded ot collapsed for tree
5006 */
5007 this.treeAction = new EventEmitter();
5008 this.rowCount = 0;
5009 this._offsetX = new BehaviorSubject(0);
5010 this._count = 0;
5011 this._offset = 0;
5012 this._subscriptions = [];
5013 /**
5014 * This will be used when displaying or selecting rows.
5015 * when tracking/comparing them, we'll use the value of this fn,
5016 *
5017 * (`fn(x) === fn(y)` instead of `x === y`)
5018 */
5019 this.rowIdentity = (x) => {
5020 if (this._groupRowsBy) {
5021 // each group in groupedRows are stored as {key, value: [rows]},
5022 // where key is the groupRowsBy index
5023 return x.key;
5024 }
5025 else {
5026 return x;
5027 }
5028 };
5029 // get ref to elm for measuring
5030 this.element = element.nativeElement;
5031 this.rowDiffer = differs.find({}).create();
5032 // apply global settings from Module.forRoot
5033 if (this.configuration && this.configuration.messages) {
5034 this.messages = Object.assign({}, this.configuration.messages);
5035 }
5036 }
5037 /**
5038 * Rows that are displayed in the table.
5039 */
5040 set rows(val) {
5041 this._rows = val;
5042 if (val) {
5043 this._internalRows = [...val];
5044 }
5045 // auto sort on new updates
5046 if (!this.externalSorting) {
5047 this.sortInternalRows();
5048 }
5049 // auto group by parent on new update
5050 this._internalRows = groupRowsByParents(this._internalRows, optionalGetterForProp(this.treeFromRelation), optionalGetterForProp(this.treeToRelation));
5051 // recalculate sizes/etc
5052 this.recalculate();
5053 if (this._rows && this._groupRowsBy) {
5054 // If a column has been specified in _groupRowsBy created a new array with the data grouped by that row
5055 this.groupedRows = this.groupArrayBy(this._rows, this._groupRowsBy);
5056 }
5057 this.cd.markForCheck();
5058 }
5059 /**
5060 * Gets the rows.
5061 */
5062 get rows() {
5063 return this._rows;
5064 }
5065 /**
5066 * This attribute allows the user to set the name of the column to group the data with
5067 */
5068 set groupRowsBy(val) {
5069 if (val) {
5070 this._groupRowsBy = val;
5071 if (this._rows && this._groupRowsBy) {
5072 // cretes a new array with the data grouped
5073 this.groupedRows = this.groupArrayBy(this._rows, this._groupRowsBy);
5074 }
5075 }
5076 }
5077 get groupRowsBy() {
5078 return this._groupRowsBy;
5079 }
5080 /**
5081 * Columns to be displayed.
5082 */
5083 set columns(val) {
5084 if (val) {
5085 this._internalColumns = [...val];
5086 setColumnDefaults(this._internalColumns);
5087 this.recalculateColumns();
5088 }
5089 this._columns = val;
5090 }
5091 /**
5092 * Get the columns.
5093 */
5094 get columns() {
5095 return this._columns;
5096 }
5097 /**
5098 * The page size to be shown.
5099 * Default value: `undefined`
5100 */
5101 set limit(val) {
5102 this._limit = val;
5103 // recalculate sizes/etc
5104 this.recalculate();
5105 }
5106 /**
5107 * Gets the limit.
5108 */
5109 get limit() {
5110 return this._limit;
5111 }
5112 /**
5113 * The total count of all rows.
5114 * Default value: `0`
5115 */
5116 set count(val) {
5117 this._count = val;
5118 // recalculate sizes/etc
5119 this.recalculate();
5120 }
5121 /**
5122 * Gets the count.
5123 */
5124 get count() {
5125 return this._count;
5126 }
5127 /**
5128 * The current offset ( page - 1 ) shown.
5129 * Default value: `0`
5130 */
5131 set offset(val) {
5132 this._offset = val;
5133 }
5134 get offset() {
5135 return Math.max(Math.min(this._offset, Math.ceil(this.rowCount / this.pageSize) - 1), 0);
5136 }
5137 /**
5138 * CSS class applied if the header height if fixed height.
5139 */
5140 get isFixedHeader() {
5141 const headerHeight = this.headerHeight;
5142 return typeof headerHeight === 'string' ? headerHeight !== 'auto' : true;
5143 }
5144 /**
5145 * CSS class applied to the root element if
5146 * the row heights are fixed heights.
5147 */
5148 get isFixedRow() {
5149 return this.rowHeight !== 'auto';
5150 }
5151 /**
5152 * CSS class applied to root element if
5153 * vertical scrolling is enabled.
5154 */
5155 get isVertScroll() {
5156 return this.scrollbarV;
5157 }
5158 /**
5159 * CSS class applied to root element if
5160 * virtualization is enabled.
5161 */
5162 get isVirtualized() {
5163 return this.virtualization;
5164 }
5165 /**
5166 * CSS class applied to the root element
5167 * if the horziontal scrolling is enabled.
5168 */
5169 get isHorScroll() {
5170 return this.scrollbarH;
5171 }
5172 /**
5173 * CSS class applied to root element is selectable.
5174 */
5175 get isSelectable() {
5176 return this.selectionType !== undefined;
5177 }
5178 /**
5179 * CSS class applied to root is checkbox selection.
5180 */
5181 get isCheckboxSelection() {
5182 return this.selectionType === SelectionType.checkbox;
5183 }
5184 /**
5185 * CSS class applied to root if cell selection.
5186 */
5187 get isCellSelection() {
5188 return this.selectionType === SelectionType.cell;
5189 }
5190 /**
5191 * CSS class applied to root if single select.
5192 */
5193 get isSingleSelection() {
5194 return this.selectionType === SelectionType.single;
5195 }
5196 /**
5197 * CSS class added to root element if mulit select
5198 */
5199 get isMultiSelection() {
5200 return this.selectionType === SelectionType.multi;
5201 }
5202 /**
5203 * CSS class added to root element if mulit click select
5204 */
5205 get isMultiClickSelection() {
5206 return this.selectionType === SelectionType.multiClick;
5207 }
5208 /**
5209 * Column templates gathered from `ContentChildren`
5210 * if described in your markup.
5211 */
5212 set columnTemplates(val) {
5213 this._columnTemplates = val;
5214 this.translateColumns(val);
5215 }
5216 /**
5217 * Returns the column templates.
5218 */
5219 get columnTemplates() {
5220 return this._columnTemplates;
5221 }
5222 /**
5223 * Returns if all rows are selected.
5224 */
5225 get allRowsSelected() {
5226 let allRowsSelected = this.rows && this.selected && this.selected.length === this.rows.length;
5227 if (this.bodyComponent && this.selectAllRowsOnPage) {
5228 const indexes = this.bodyComponent.indexes;
5229 const rowsOnPage = indexes.last - indexes.first;
5230 allRowsSelected = this.selected.length === rowsOnPage;
5231 }
5232 return this.selected && this.rows && this.rows.length !== 0 && allRowsSelected;
5233 }
5234 /**
5235 * Lifecycle hook that is called after data-bound
5236 * properties of a directive are initialized.
5237 */
5238 ngOnInit() {
5239 // need to call this immediatly to size
5240 // if the table is hidden the visibility
5241 // listener will invoke this itself upon show
5242 this.recalculate();
5243 }
5244 /**
5245 * Lifecycle hook that is called after a component's
5246 * view has been fully initialized.
5247 */
5248 ngAfterViewInit() {
5249 if (!this.externalSorting) {
5250 this.sortInternalRows();
5251 }
5252 // this has to be done to prevent the change detection
5253 // tree from freaking out because we are readjusting
5254 if (typeof requestAnimationFrame === 'undefined') {
5255 return;
5256 }
5257 requestAnimationFrame(() => {
5258 this.recalculate();
5259 // emit page for virtual server-side kickoff
5260 if (this.externalPaging && this.scrollbarV) {
5261 this.page.emit({
5262 count: this.count,
5263 pageSize: this.pageSize,
5264 limit: this.limit,
5265 offset: 0
5266 });
5267 }
5268 });
5269 }
5270 /**
5271 * Lifecycle hook that is called after a component's
5272 * content has been fully initialized.
5273 */
5274 ngAfterContentInit() {
5275 this.columnTemplates.changes.subscribe(v => this.translateColumns(v));
5276 this.listenForColumnInputChanges();
5277 }
5278 /**
5279 * Translates the templates to the column objects
5280 */
5281 translateColumns(val) {
5282 if (val) {
5283 const arr = val.toArray();
5284 if (arr.length) {
5285 this._internalColumns = translateTemplates(arr);
5286 setColumnDefaults(this._internalColumns);
5287 this.recalculateColumns();
5288 this.sortInternalRows();
5289 this.cd.markForCheck();
5290 }
5291 }
5292 }
5293 /**
5294 * Creates a map with the data grouped by the user choice of grouping index
5295 *
5296 * @param originalArray the original array passed via parameter
5297 * @param groupByIndex the index of the column to group the data by
5298 */
5299 groupArrayBy(originalArray, groupBy) {
5300 // create a map to hold groups with their corresponding results
5301 const map = new Map();
5302 let i = 0;
5303 originalArray.forEach((item) => {
5304 const key = item[groupBy];
5305 if (!map.has(key)) {
5306 map.set(key, [item]);
5307 }
5308 else {
5309 map.get(key).push(item);
5310 }
5311 i++;
5312 });
5313 const addGroup = (key, value) => {
5314 return { key, value };
5315 };
5316 // convert map back to a simple array of objects
5317 return Array.from(map, x => addGroup(x[0], x[1]));
5318 }
5319 /*
5320 * Lifecycle hook that is called when Angular dirty checks a directive.
5321 */
5322 ngDoCheck() {
5323 if (this.rowDiffer.diff(this.rows)) {
5324 if (!this.externalSorting) {
5325 this.sortInternalRows();
5326 }
5327 else {
5328 this._internalRows = [...this.rows];
5329 }
5330 // auto group by parent on new update
5331 this._internalRows = groupRowsByParents(this._internalRows, optionalGetterForProp(this.treeFromRelation), optionalGetterForProp(this.treeToRelation));
5332 this.recalculatePages();
5333 this.cd.markForCheck();
5334 }
5335 }
5336 /**
5337 * Recalc's the sizes of the grid.
5338 *
5339 * Updated automatically on changes to:
5340 *
5341 * - Columns
5342 * - Rows
5343 * - Paging related
5344 *
5345 * Also can be manually invoked or upon window resize.
5346 */
5347 recalculate() {
5348 this.recalculateDims();
5349 this.recalculateColumns();
5350 this.cd.markForCheck();
5351 }
5352 /**
5353 * Window resize handler to update sizes.
5354 */
5355 onWindowResize() {
5356 this.recalculate();
5357 }
5358 /**
5359 * Recalulcates the column widths based on column width
5360 * distribution mode and scrollbar offsets.
5361 */
5362 recalculateColumns(columns = this._internalColumns, forceIdx = -1, allowBleed = this.scrollbarH) {
5363 if (!columns)
5364 return undefined;
5365 let width = this._innerWidth;
5366 if (this.scrollbarV) {
5367 width = width - this.scrollbarHelper.width;
5368 }
5369 if (this.columnMode === ColumnMode.force) {
5370 forceFillColumnWidths(columns, width, forceIdx, allowBleed);
5371 }
5372 else if (this.columnMode === ColumnMode.flex) {
5373 adjustColumnWidths(columns, width);
5374 }
5375 return columns;
5376 }
5377 /**
5378 * Recalculates the dimensions of the table size.
5379 * Internally calls the page size and row count calcs too.
5380 *
5381 */
5382 recalculateDims() {
5383 const dims = this.dimensionsHelper.getDimensions(this.element);
5384 this._innerWidth = Math.floor(dims.width);
5385 if (this.scrollbarV) {
5386 let height = dims.height;
5387 if (this.headerHeight)
5388 height = height - this.headerHeight;
5389 if (this.footerHeight)
5390 height = height - this.footerHeight;
5391 this.bodyHeight = height;
5392 }
5393 this.recalculatePages();
5394 }
5395 /**
5396 * Recalculates the pages after a update.
5397 */
5398 recalculatePages() {
5399 this.pageSize = this.calcPageSize();
5400 this.rowCount = this.calcRowCount();
5401 }
5402 /**
5403 * Body triggered a page event.
5404 */
5405 onBodyPage({ offset }) {
5406 // Avoid pagination caming from body events like scroll when the table
5407 // has no virtualization and the external paging is enable.
5408 // This means, let's the developer handle pagination by my him(her) self
5409 if (this.externalPaging && !this.virtualization) {
5410 return;
5411 }
5412 this.offset = offset;
5413 this.page.emit({
5414 count: this.count,
5415 pageSize: this.pageSize,
5416 limit: this.limit,
5417 offset: this.offset
5418 });
5419 }
5420 /**
5421 * The body triggered a scroll event.
5422 */
5423 onBodyScroll(event) {
5424 this._offsetX.next(event.offsetX);
5425 this.scroll.emit(event);
5426 this.cd.detectChanges();
5427 }
5428 /**
5429 * The footer triggered a page event.
5430 */
5431 onFooterPage(event) {
5432 this.offset = event.page - 1;
5433 this.bodyComponent.updateOffsetY(this.offset);
5434 this.page.emit({
5435 count: this.count,
5436 pageSize: this.pageSize,
5437 limit: this.limit,
5438 offset: this.offset
5439 });
5440 if (this.selectAllRowsOnPage) {
5441 this.selected = [];
5442 this.select.emit({
5443 selected: this.selected
5444 });
5445 }
5446 }
5447 /**
5448 * Recalculates the sizes of the page
5449 */
5450 calcPageSize(val = this.rows) {
5451 // Keep the page size constant even if the row has been expanded.
5452 // This is because an expanded row is still considered to be a child of
5453 // the original row. Hence calculation would use rowHeight only.
5454 if (this.scrollbarV && this.virtualization) {
5455 const size = Math.ceil(this.bodyHeight / this.rowHeight);
5456 return Math.max(size, 0);
5457 }
5458 // if limit is passed, we are paging
5459 if (this.limit !== undefined) {
5460 return this.limit;
5461 }
5462 // otherwise use row length
5463 if (val) {
5464 return val.length;
5465 }
5466 // other empty :(
5467 return 0;
5468 }
5469 /**
5470 * Calculates the row count.
5471 */
5472 calcRowCount(val = this.rows) {
5473 if (!this.externalPaging) {
5474 if (!val)
5475 return 0;
5476 if (this.groupedRows) {
5477 return this.groupedRows.length;
5478 }
5479 else if (this.treeFromRelation != null && this.treeToRelation != null) {
5480 return this._internalRows.length;
5481 }
5482 else {
5483 return val.length;
5484 }
5485 }
5486 return this.count;
5487 }
5488 /**
5489 * The header triggered a contextmenu event.
5490 */
5491 onColumnContextmenu({ event, column }) {
5492 this.tableContextmenu.emit({ event, type: ContextmenuType.header, content: column });
5493 }
5494 /**
5495 * The body triggered a contextmenu event.
5496 */
5497 onRowContextmenu({ event, row }) {
5498 this.tableContextmenu.emit({ event, type: ContextmenuType.body, content: row });
5499 }
5500 /**
5501 * The header triggered a column resize event.
5502 */
5503 onColumnResize({ column, newValue }) {
5504 /* Safari/iOS 10.2 workaround */
5505 if (column === undefined) {
5506 return;
5507 }
5508 let idx;
5509 const cols = this._internalColumns.map((c, i) => {
5510 c = Object.assign({}, c);
5511 if (c.$$id === column.$$id) {
5512 idx = i;
5513 c.width = newValue;
5514 // set this so we can force the column
5515 // width distribution to be to this value
5516 c.$$oldWidth = newValue;
5517 }
5518 return c;
5519 });
5520 this.recalculateColumns(cols, idx);
5521 this._internalColumns = cols;
5522 this.resize.emit({
5523 column,
5524 newValue
5525 });
5526 }
5527 /**
5528 * The header triggered a column re-order event.
5529 */
5530 onColumnReorder({ column, newValue, prevValue }) {
5531 const cols = this._internalColumns.map(c => {
5532 return Object.assign({}, c);
5533 });
5534 if (this.swapColumns) {
5535 const prevCol = cols[newValue];
5536 cols[newValue] = column;
5537 cols[prevValue] = prevCol;
5538 }
5539 else {
5540 if (newValue > prevValue) {
5541 const movedCol = cols[prevValue];
5542 for (let i = prevValue; i < newValue; i++) {
5543 cols[i] = cols[i + 1];
5544 }
5545 cols[newValue] = movedCol;
5546 }
5547 else {
5548 const movedCol = cols[prevValue];
5549 for (let i = prevValue; i > newValue; i--) {
5550 cols[i] = cols[i - 1];
5551 }
5552 cols[newValue] = movedCol;
5553 }
5554 }
5555 this._internalColumns = cols;
5556 this.reorder.emit({
5557 column,
5558 newValue,
5559 prevValue
5560 });
5561 }
5562 /**
5563 * The header triggered a column sort event.
5564 */
5565 onColumnSort(event) {
5566 // clean selected rows
5567 if (this.selectAllRowsOnPage) {
5568 this.selected = [];
5569 this.select.emit({
5570 selected: this.selected
5571 });
5572 }
5573 this.sorts = event.sorts;
5574 // this could be optimized better since it will resort
5575 // the rows again on the 'push' detection...
5576 if (this.externalSorting === false) {
5577 // don't use normal setter so we don't resort
5578 this.sortInternalRows();
5579 }
5580 // auto group by parent on new update
5581 this._internalRows = groupRowsByParents(this._internalRows, optionalGetterForProp(this.treeFromRelation), optionalGetterForProp(this.treeToRelation));
5582 // Always go to first page when sorting to see the newly sorted data
5583 this.offset = 0;
5584 this.bodyComponent.updateOffsetY(this.offset);
5585 this.sort.emit(event);
5586 }
5587 /**
5588 * Toggle all row selection
5589 */
5590 onHeaderSelect(event) {
5591 if (this.bodyComponent && this.selectAllRowsOnPage) {
5592 // before we splice, chk if we currently have all selected
5593 const first = this.bodyComponent.indexes.first;
5594 const last = this.bodyComponent.indexes.last;
5595 const allSelected = this.selected.length === last - first;
5596 // remove all existing either way
5597 this.selected = [];
5598 // do the opposite here
5599 if (!allSelected) {
5600 this.selected.push(...this._internalRows.slice(first, last));
5601 }
5602 }
5603 else {
5604 // before we splice, chk if we currently have all selected
5605 const allSelected = this.selected.length === this.rows.length;
5606 // remove all existing either way
5607 this.selected = [];
5608 // do the opposite here
5609 if (!allSelected) {
5610 this.selected.push(...this.rows);
5611 }
5612 }
5613 this.select.emit({
5614 selected: this.selected
5615 });
5616 }
5617 /**
5618 * A row was selected from body
5619 */
5620 onBodySelect(event) {
5621 this.select.emit(event);
5622 }
5623 /**
5624 * A row was expanded or collapsed for tree
5625 */
5626 onTreeAction(event) {
5627 const row = event.row;
5628 // TODO: For duplicated items this will not work
5629 const rowIndex = this._rows.findIndex(r => r[this.treeToRelation] === event.row[this.treeToRelation]);
5630 this.treeAction.emit({ row, rowIndex });
5631 }
5632 ngOnDestroy() {
5633 this._subscriptions.forEach(subscription => subscription.unsubscribe());
5634 }
5635 /**
5636 * listen for changes to input bindings of all DataTableColumnDirective and
5637 * trigger the columnTemplates.changes observable to emit
5638 */
5639 listenForColumnInputChanges() {
5640 this._subscriptions.push(this.columnChangesService.columnInputChanges$.subscribe(() => {
5641 if (this.columnTemplates) {
5642 this.columnTemplates.notifyOnChanges();
5643 }
5644 }));
5645 }
5646 sortInternalRows() {
5647 this._internalRows = sortRows(this._internalRows, this._internalColumns, this.sorts);
5648 }
5649}
5650DatatableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableComponent, deps: [{ token: ScrollbarHelper, skipSelf: true }, { token: DimensionsHelper, skipSelf: true }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.KeyValueDiffers }, { token: ColumnChangesService }, { token: 'configuration', optional: true }], target: i0.ɵɵFactoryTarget.Component });
5651DatatableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: DatatableComponent, selector: "ngx-datatable", inputs: { targetMarkerTemplate: "targetMarkerTemplate", rows: "rows", groupRowsBy: "groupRowsBy", groupedRows: "groupedRows", columns: "columns", selected: "selected", scrollbarV: "scrollbarV", scrollbarH: "scrollbarH", rowHeight: "rowHeight", columnMode: "columnMode", headerHeight: "headerHeight", footerHeight: "footerHeight", externalPaging: "externalPaging", externalSorting: "externalSorting", limit: "limit", count: "count", offset: "offset", loadingIndicator: "loadingIndicator", selectionType: "selectionType", reorderable: "reorderable", swapColumns: "swapColumns", sortType: "sortType", sorts: "sorts", cssClasses: "cssClasses", messages: "messages", rowClass: "rowClass", selectCheck: "selectCheck", displayCheck: "displayCheck", groupExpansionDefault: "groupExpansionDefault", trackByProp: "trackByProp", selectAllRowsOnPage: "selectAllRowsOnPage", virtualization: "virtualization", treeFromRelation: "treeFromRelation", treeToRelation: "treeToRelation", summaryRow: "summaryRow", summaryHeight: "summaryHeight", summaryPosition: "summaryPosition", rowIdentity: "rowIdentity" }, outputs: { scroll: "scroll", activate: "activate", select: "select", sort: "sort", page: "page", reorder: "reorder", resize: "resize", tableContextmenu: "tableContextmenu", treeAction: "treeAction" }, host: { listeners: { "window:resize": "onWindowResize()" }, properties: { "class.fixed-header": "this.isFixedHeader", "class.fixed-row": "this.isFixedRow", "class.scroll-vertical": "this.isVertScroll", "class.virtualized": "this.isVirtualized", "class.scroll-horz": "this.isHorScroll", "class.selectable": "this.isSelectable", "class.checkbox-selection": "this.isCheckboxSelection", "class.cell-selection": "this.isCellSelection", "class.single-selection": "this.isSingleSelection", "class.multi-selection": "this.isMultiSelection", "class.multi-click-selection": "this.isMultiClickSelection" }, classAttribute: "ngx-datatable" }, queries: [{ propertyName: "rowDetail", first: true, predicate: DatatableRowDetailDirective, descendants: true }, { propertyName: "groupHeader", first: true, predicate: DatatableGroupHeaderDirective, descendants: true }, { propertyName: "footer", first: true, predicate: DatatableFooterDirective, descendants: true }, { propertyName: "columnTemplates", predicate: DataTableColumnDirective }], viewQueries: [{ propertyName: "bodyComponent", first: true, predicate: DataTableBodyComponent, descendants: true }, { propertyName: "headerComponent", first: true, predicate: DataTableHeaderComponent, descendants: true }], ngImport: i0, template: "<div role=\"table\" visibilityObserver (visible)=\"recalculate()\">\n <datatable-header\n role=\"rowgroup\"\n *ngIf=\"headerHeight\"\n [sorts]=\"sorts\"\n [sortType]=\"sortType\"\n [scrollbarH]=\"scrollbarH\"\n [innerWidth]=\"_innerWidth\"\n [offsetX]=\"_offsetX | async\"\n [dealsWithGroup]=\"groupedRows !== undefined\"\n [columns]=\"_internalColumns\"\n [headerHeight]=\"headerHeight\"\n [reorderable]=\"reorderable\"\n [targetMarkerTemplate]=\"targetMarkerTemplate\"\n [sortAscendingIcon]=\"cssClasses.sortAscending\"\n [sortDescendingIcon]=\"cssClasses.sortDescending\"\n [sortUnsetIcon]=\"cssClasses.sortUnset\"\n [allRowsSelected]=\"allRowsSelected\"\n [selectionType]=\"selectionType\"\n (sort)=\"onColumnSort($event)\"\n (resize)=\"onColumnResize($event)\"\n (reorder)=\"onColumnReorder($event)\"\n (select)=\"onHeaderSelect($event)\"\n (columnContextmenu)=\"onColumnContextmenu($event)\"\n >\n </datatable-header>\n <datatable-body\n role=\"rowgroup\"\n [groupRowsBy]=\"groupRowsBy\"\n [groupedRows]=\"groupedRows\"\n [rows]=\"_internalRows\"\n [groupExpansionDefault]=\"groupExpansionDefault\"\n [scrollbarV]=\"scrollbarV\"\n [scrollbarH]=\"scrollbarH\"\n [virtualization]=\"virtualization\"\n [loadingIndicator]=\"loadingIndicator\"\n [externalPaging]=\"externalPaging\"\n [rowHeight]=\"rowHeight\"\n [rowCount]=\"rowCount\"\n [offset]=\"offset\"\n [trackByProp]=\"trackByProp\"\n [columns]=\"_internalColumns\"\n [pageSize]=\"pageSize\"\n [offsetX]=\"_offsetX | async\"\n [rowDetail]=\"rowDetail\"\n [groupHeader]=\"groupHeader\"\n [selected]=\"selected\"\n [innerWidth]=\"_innerWidth\"\n [bodyHeight]=\"bodyHeight\"\n [selectionType]=\"selectionType\"\n [emptyMessage]=\"messages.emptyMessage\"\n [rowIdentity]=\"rowIdentity\"\n [rowClass]=\"rowClass\"\n [selectCheck]=\"selectCheck\"\n [displayCheck]=\"displayCheck\"\n [summaryRow]=\"summaryRow\"\n [summaryHeight]=\"summaryHeight\"\n [summaryPosition]=\"summaryPosition\"\n (page)=\"onBodyPage($event)\"\n (activate)=\"activate.emit($event)\"\n (rowContextmenu)=\"onRowContextmenu($event)\"\n (select)=\"onBodySelect($event)\"\n (scroll)=\"onBodyScroll($event)\"\n (treeAction)=\"onTreeAction($event)\"\n >\n </datatable-body>\n <datatable-footer\n *ngIf=\"footerHeight\"\n [rowCount]=\"rowCount\"\n [pageSize]=\"pageSize\"\n [offset]=\"offset\"\n [footerHeight]=\"footerHeight\"\n [footerTemplate]=\"footer\"\n [totalMessage]=\"messages.totalMessage\"\n [pagerLeftArrowIcon]=\"cssClasses.pagerLeftArrow\"\n [pagerRightArrowIcon]=\"cssClasses.pagerRightArrow\"\n [pagerPreviousIcon]=\"cssClasses.pagerPrevious\"\n [selectedCount]=\"selected.length\"\n [selectedMessage]=\"!!selectionType && messages.selectedMessage\"\n [pagerNextIcon]=\"cssClasses.pagerNext\"\n (page)=\"onFooterPage($event)\"\n >\n </datatable-footer>\n</div>\n", styles: [".ngx-datatable{display:block;overflow:hidden;justify-content:center;position:relative;transform:translate(0)}.ngx-datatable [hidden]{display:none!important}.ngx-datatable *,.ngx-datatable *:before,.ngx-datatable *:after{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-row-center,.ngx-datatable .datatable-header-inner{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:none}.ngx-datatable .datatable-row-left,.ngx-datatable .datatable-row-right{z-index:9}.ngx-datatable .datatable-row-left,.ngx-datatable .datatable-row-center,.ngx-datatable .datatable-row-group,.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:none}.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:none}.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}\n"], components: [{ type: DataTableHeaderComponent, selector: "datatable-header", inputs: ["sortAscendingIcon", "sortDescendingIcon", "sortUnsetIcon", "scrollbarH", "dealsWithGroup", "targetMarkerTemplate", "innerWidth", "sorts", "sortType", "allRowsSelected", "selectionType", "reorderable", "headerHeight", "columns", "offsetX"], outputs: ["sort", "reorder", "resize", "select", "columnContextmenu"] }, { type: DataTableBodyComponent, selector: "datatable-body", inputs: ["scrollbarV", "scrollbarH", "loadingIndicator", "externalPaging", "rowHeight", "offsetX", "emptyMessage", "selectionType", "selected", "rowIdentity", "rowDetail", "groupHeader", "selectCheck", "displayCheck", "trackByProp", "rowClass", "groupedRows", "groupExpansionDefault", "innerWidth", "groupRowsBy", "virtualization", "summaryRow", "summaryPosition", "summaryHeight", "pageSize", "rows", "columns", "offset", "rowCount", "bodyHeight"], outputs: ["scroll", "page", "activate", "select", "detailToggle", "rowContextmenu", "treeAction"] }, { type: DataTableFooterComponent, selector: "datatable-footer", inputs: ["footerHeight", "rowCount", "pageSize", "offset", "pagerLeftArrowIcon", "pagerRightArrowIcon", "pagerPreviousIcon", "pagerNextIcon", "totalMessage", "footerTemplate", "selectedCount", "selectedMessage"], outputs: ["page"] }], directives: [{ type: VisibilityDirective, selector: "[visibilityObserver]", outputs: ["visible"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i1.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
5652__decorate([
5653 throttleable(5)
5654], DatatableComponent.prototype, "onWindowResize", null);
5655i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DatatableComponent, decorators: [{
5656 type: Component,
5657 args: [{ selector: 'ngx-datatable', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
5658 class: 'ngx-datatable'
5659 }, template: "<div role=\"table\" visibilityObserver (visible)=\"recalculate()\">\n <datatable-header\n role=\"rowgroup\"\n *ngIf=\"headerHeight\"\n [sorts]=\"sorts\"\n [sortType]=\"sortType\"\n [scrollbarH]=\"scrollbarH\"\n [innerWidth]=\"_innerWidth\"\n [offsetX]=\"_offsetX | async\"\n [dealsWithGroup]=\"groupedRows !== undefined\"\n [columns]=\"_internalColumns\"\n [headerHeight]=\"headerHeight\"\n [reorderable]=\"reorderable\"\n [targetMarkerTemplate]=\"targetMarkerTemplate\"\n [sortAscendingIcon]=\"cssClasses.sortAscending\"\n [sortDescendingIcon]=\"cssClasses.sortDescending\"\n [sortUnsetIcon]=\"cssClasses.sortUnset\"\n [allRowsSelected]=\"allRowsSelected\"\n [selectionType]=\"selectionType\"\n (sort)=\"onColumnSort($event)\"\n (resize)=\"onColumnResize($event)\"\n (reorder)=\"onColumnReorder($event)\"\n (select)=\"onHeaderSelect($event)\"\n (columnContextmenu)=\"onColumnContextmenu($event)\"\n >\n </datatable-header>\n <datatable-body\n role=\"rowgroup\"\n [groupRowsBy]=\"groupRowsBy\"\n [groupedRows]=\"groupedRows\"\n [rows]=\"_internalRows\"\n [groupExpansionDefault]=\"groupExpansionDefault\"\n [scrollbarV]=\"scrollbarV\"\n [scrollbarH]=\"scrollbarH\"\n [virtualization]=\"virtualization\"\n [loadingIndicator]=\"loadingIndicator\"\n [externalPaging]=\"externalPaging\"\n [rowHeight]=\"rowHeight\"\n [rowCount]=\"rowCount\"\n [offset]=\"offset\"\n [trackByProp]=\"trackByProp\"\n [columns]=\"_internalColumns\"\n [pageSize]=\"pageSize\"\n [offsetX]=\"_offsetX | async\"\n [rowDetail]=\"rowDetail\"\n [groupHeader]=\"groupHeader\"\n [selected]=\"selected\"\n [innerWidth]=\"_innerWidth\"\n [bodyHeight]=\"bodyHeight\"\n [selectionType]=\"selectionType\"\n [emptyMessage]=\"messages.emptyMessage\"\n [rowIdentity]=\"rowIdentity\"\n [rowClass]=\"rowClass\"\n [selectCheck]=\"selectCheck\"\n [displayCheck]=\"displayCheck\"\n [summaryRow]=\"summaryRow\"\n [summaryHeight]=\"summaryHeight\"\n [summaryPosition]=\"summaryPosition\"\n (page)=\"onBodyPage($event)\"\n (activate)=\"activate.emit($event)\"\n (rowContextmenu)=\"onRowContextmenu($event)\"\n (select)=\"onBodySelect($event)\"\n (scroll)=\"onBodyScroll($event)\"\n (treeAction)=\"onTreeAction($event)\"\n >\n </datatable-body>\n <datatable-footer\n *ngIf=\"footerHeight\"\n [rowCount]=\"rowCount\"\n [pageSize]=\"pageSize\"\n [offset]=\"offset\"\n [footerHeight]=\"footerHeight\"\n [footerTemplate]=\"footer\"\n [totalMessage]=\"messages.totalMessage\"\n [pagerLeftArrowIcon]=\"cssClasses.pagerLeftArrow\"\n [pagerRightArrowIcon]=\"cssClasses.pagerRightArrow\"\n [pagerPreviousIcon]=\"cssClasses.pagerPrevious\"\n [selectedCount]=\"selected.length\"\n [selectedMessage]=\"!!selectionType && messages.selectedMessage\"\n [pagerNextIcon]=\"cssClasses.pagerNext\"\n (page)=\"onFooterPage($event)\"\n >\n </datatable-footer>\n</div>\n", styles: [".ngx-datatable{display:block;overflow:hidden;justify-content:center;position:relative;transform:translate(0)}.ngx-datatable [hidden]{display:none!important}.ngx-datatable *,.ngx-datatable *:before,.ngx-datatable *:after{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-row-center,.ngx-datatable .datatable-header-inner{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:none}.ngx-datatable .datatable-row-left,.ngx-datatable .datatable-row-right{z-index:9}.ngx-datatable .datatable-row-left,.ngx-datatable .datatable-row-center,.ngx-datatable .datatable-row-group,.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:none}.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:none}.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}\n"] }]
5660 }], ctorParameters: function () {
5661 return [{ type: ScrollbarHelper, decorators: [{
5662 type: SkipSelf
5663 }] }, { type: DimensionsHelper, decorators: [{
5664 type: SkipSelf
5665 }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.KeyValueDiffers }, { type: ColumnChangesService }, { type: undefined, decorators: [{
5666 type: Optional
5667 }, {
5668 type: Inject,
5669 args: ['configuration']
5670 }] }];
5671 }, propDecorators: { targetMarkerTemplate: [{
5672 type: Input
5673 }], rows: [{
5674 type: Input
5675 }], groupRowsBy: [{
5676 type: Input
5677 }], groupedRows: [{
5678 type: Input
5679 }], columns: [{
5680 type: Input
5681 }], selected: [{
5682 type: Input
5683 }], scrollbarV: [{
5684 type: Input
5685 }], scrollbarH: [{
5686 type: Input
5687 }], rowHeight: [{
5688 type: Input
5689 }], columnMode: [{
5690 type: Input
5691 }], headerHeight: [{
5692 type: Input
5693 }], footerHeight: [{
5694 type: Input
5695 }], externalPaging: [{
5696 type: Input
5697 }], externalSorting: [{
5698 type: Input
5699 }], limit: [{
5700 type: Input
5701 }], count: [{
5702 type: Input
5703 }], offset: [{
5704 type: Input
5705 }], loadingIndicator: [{
5706 type: Input
5707 }], selectionType: [{
5708 type: Input
5709 }], reorderable: [{
5710 type: Input
5711 }], swapColumns: [{
5712 type: Input
5713 }], sortType: [{
5714 type: Input
5715 }], sorts: [{
5716 type: Input
5717 }], cssClasses: [{
5718 type: Input
5719 }], messages: [{
5720 type: Input
5721 }], rowClass: [{
5722 type: Input
5723 }], selectCheck: [{
5724 type: Input
5725 }], displayCheck: [{
5726 type: Input
5727 }], groupExpansionDefault: [{
5728 type: Input
5729 }], trackByProp: [{
5730 type: Input
5731 }], selectAllRowsOnPage: [{
5732 type: Input
5733 }], virtualization: [{
5734 type: Input
5735 }], treeFromRelation: [{
5736 type: Input
5737 }], treeToRelation: [{
5738 type: Input
5739 }], summaryRow: [{
5740 type: Input
5741 }], summaryHeight: [{
5742 type: Input
5743 }], summaryPosition: [{
5744 type: Input
5745 }], scroll: [{
5746 type: Output
5747 }], activate: [{
5748 type: Output
5749 }], select: [{
5750 type: Output
5751 }], sort: [{
5752 type: Output
5753 }], page: [{
5754 type: Output
5755 }], reorder: [{
5756 type: Output
5757 }], resize: [{
5758 type: Output
5759 }], tableContextmenu: [{
5760 type: Output
5761 }], treeAction: [{
5762 type: Output
5763 }], isFixedHeader: [{
5764 type: HostBinding,
5765 args: ['class.fixed-header']
5766 }], isFixedRow: [{
5767 type: HostBinding,
5768 args: ['class.fixed-row']
5769 }], isVertScroll: [{
5770 type: HostBinding,
5771 args: ['class.scroll-vertical']
5772 }], isVirtualized: [{
5773 type: HostBinding,
5774 args: ['class.virtualized']
5775 }], isHorScroll: [{
5776 type: HostBinding,
5777 args: ['class.scroll-horz']
5778 }], isSelectable: [{
5779 type: HostBinding,
5780 args: ['class.selectable']
5781 }], isCheckboxSelection: [{
5782 type: HostBinding,
5783 args: ['class.checkbox-selection']
5784 }], isCellSelection: [{
5785 type: HostBinding,
5786 args: ['class.cell-selection']
5787 }], isSingleSelection: [{
5788 type: HostBinding,
5789 args: ['class.single-selection']
5790 }], isMultiSelection: [{
5791 type: HostBinding,
5792 args: ['class.multi-selection']
5793 }], isMultiClickSelection: [{
5794 type: HostBinding,
5795 args: ['class.multi-click-selection']
5796 }], columnTemplates: [{
5797 type: ContentChildren,
5798 args: [DataTableColumnDirective]
5799 }], rowDetail: [{
5800 type: ContentChild,
5801 args: [DatatableRowDetailDirective]
5802 }], groupHeader: [{
5803 type: ContentChild,
5804 args: [DatatableGroupHeaderDirective]
5805 }], footer: [{
5806 type: ContentChild,
5807 args: [DatatableFooterDirective]
5808 }], bodyComponent: [{
5809 type: ViewChild,
5810 args: [DataTableBodyComponent]
5811 }], headerComponent: [{
5812 type: ViewChild,
5813 args: [DataTableHeaderComponent]
5814 }], rowIdentity: [{
5815 type: Input
5816 }], onWindowResize: [{
5817 type: HostListener,
5818 args: ['window:resize']
5819 }] } });
5820
5821class NgxDatatableModule {
5822 /**
5823 * Configure global configuration via INgxDatatableConfig
5824 * @param configuration
5825 */
5826 static forRoot(configuration) {
5827 return {
5828 ngModule: NgxDatatableModule,
5829 providers: [{ provide: 'configuration', useValue: configuration }]
5830 };
5831 }
5832}
5833NgxDatatableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxDatatableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
5834NgxDatatableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxDatatableModule, declarations: [DataTableFooterTemplateDirective,
5835 VisibilityDirective,
5836 DraggableDirective,
5837 ResizeableDirective,
5838 OrderableDirective,
5839 LongPressDirective,
5840 ScrollerComponent,
5841 DatatableComponent,
5842 DataTableColumnDirective,
5843 DataTableHeaderComponent,
5844 DataTableHeaderCellComponent,
5845 DataTableBodyComponent,
5846 DataTableFooterComponent,
5847 DataTablePagerComponent,
5848 ProgressBarComponent,
5849 DataTableBodyRowComponent,
5850 DataTableRowWrapperComponent,
5851 DatatableRowDetailDirective,
5852 DatatableGroupHeaderDirective,
5853 DatatableRowDetailTemplateDirective,
5854 DataTableBodyCellComponent,
5855 DataTableSelectionComponent,
5856 DataTableColumnHeaderDirective,
5857 DataTableColumnCellDirective,
5858 DataTableColumnCellTreeToggle,
5859 DatatableFooterDirective,
5860 DatatableGroupHeaderTemplateDirective,
5861 DataTableSummaryRowComponent], imports: [CommonModule], exports: [DatatableComponent,
5862 DatatableRowDetailDirective,
5863 DatatableGroupHeaderDirective,
5864 DatatableRowDetailTemplateDirective,
5865 DataTableColumnDirective,
5866 DataTableColumnHeaderDirective,
5867 DataTableColumnCellDirective,
5868 DataTableColumnCellTreeToggle,
5869 DataTableFooterTemplateDirective,
5870 DatatableFooterDirective,
5871 DataTablePagerComponent,
5872 DatatableGroupHeaderTemplateDirective] });
5873NgxDatatableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxDatatableModule, providers: [ScrollbarHelper, DimensionsHelper, ColumnChangesService], imports: [[CommonModule]] });
5874i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: NgxDatatableModule, decorators: [{
5875 type: NgModule,
5876 args: [{
5877 imports: [CommonModule],
5878 providers: [ScrollbarHelper, DimensionsHelper, ColumnChangesService],
5879 declarations: [
5880 DataTableFooterTemplateDirective,
5881 VisibilityDirective,
5882 DraggableDirective,
5883 ResizeableDirective,
5884 OrderableDirective,
5885 LongPressDirective,
5886 ScrollerComponent,
5887 DatatableComponent,
5888 DataTableColumnDirective,
5889 DataTableHeaderComponent,
5890 DataTableHeaderCellComponent,
5891 DataTableBodyComponent,
5892 DataTableFooterComponent,
5893 DataTablePagerComponent,
5894 ProgressBarComponent,
5895 DataTableBodyRowComponent,
5896 DataTableRowWrapperComponent,
5897 DatatableRowDetailDirective,
5898 DatatableGroupHeaderDirective,
5899 DatatableRowDetailTemplateDirective,
5900 DataTableBodyCellComponent,
5901 DataTableSelectionComponent,
5902 DataTableColumnHeaderDirective,
5903 DataTableColumnCellDirective,
5904 DataTableColumnCellTreeToggle,
5905 DatatableFooterDirective,
5906 DatatableGroupHeaderTemplateDirective,
5907 DataTableSummaryRowComponent
5908 ],
5909 exports: [
5910 DatatableComponent,
5911 DatatableRowDetailDirective,
5912 DatatableGroupHeaderDirective,
5913 DatatableRowDetailTemplateDirective,
5914 DataTableColumnDirective,
5915 DataTableColumnHeaderDirective,
5916 DataTableColumnCellDirective,
5917 DataTableColumnCellTreeToggle,
5918 DataTableFooterTemplateDirective,
5919 DatatableFooterDirective,
5920 DataTablePagerComponent,
5921 DatatableGroupHeaderTemplateDirective
5922 ]
5923 }]
5924 }] });
5925
5926var ClickType;
5927(function (ClickType) {
5928 ClickType["single"] = "single";
5929 ClickType["double"] = "double";
5930})(ClickType || (ClickType = {}));
5931
5932if (typeof document !== 'undefined' && !document.elementsFromPoint) {
5933 document.elementsFromPoint = elementsFromPoint;
5934}
5935/*tslint:disable*/
5936/**
5937 * Polyfill for `elementsFromPoint`
5938 *
5939 * https://developer.mozilla.org/en-US/docs/Web/API/Document/elementsFromPoint
5940 * https://gist.github.com/iddan/54d5d9e58311b0495a91bf06de661380
5941 * https://gist.github.com/oslego/7265412
5942 */
5943function elementsFromPoint(x, y) {
5944 const elements = [];
5945 const previousPointerEvents = [];
5946 let current; // TODO: window.getComputedStyle should be used with inferred type (Element)
5947 let i;
5948 let d;
5949 //if (document === undefined) return elements;
5950 // get all elements via elementFromPoint, and remove them from hit-testing in order
5951 while ((current = document.elementFromPoint(x, y)) && elements.indexOf(current) === -1 && current != null) {
5952 // push the element and its current style
5953 elements.push(current);
5954 previousPointerEvents.push({
5955 value: current.style.getPropertyValue('pointer-events'),
5956 priority: current.style.getPropertyPriority('pointer-events')
5957 });
5958 // add "pointer-events: none", to get to the underlying element
5959 current.style.setProperty('pointer-events', 'none', 'important');
5960 }
5961 // restore the previous pointer-events values
5962 for (i = previousPointerEvents.length; (d = previousPointerEvents[--i]);) {
5963 elements[i].style.setProperty('pointer-events', d.value ? d.value : '', d.priority);
5964 }
5965 // return our results
5966 return elements;
5967}
5968/*tslint:enable*/
5969
5970/*
5971 * Public API Surface of ngx-datatable
5972 */
5973
5974/**
5975 * Generated bundle index. Do not edit.
5976 */
5977
5978export { 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 };
5979//# sourceMappingURL=swimlane-ngx-datatable.mjs.map