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