import { Component, ChangeDetectionStrategy, ViewEncapsulation, HostBinding, Input, HostListener, Directive, ContentChildren, TemplateRef, ViewChild, forwardRef, NgModule } from '@angular/core';
import { tap, map, catchError, debounceTime, distinctUntilChanged, startWith, switchMap, share } from 'rxjs/operators';
import { DataSourceRequest } from '@bravobit/bb-foundation/api';
import { BehaviorSubject, of, combineLatest } from 'rxjs';
import { FormControl, NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ElementsModule } from '@bravobit/bb-foundation/elements';
import { mixinDisabled } from '@bravobit/bb-foundation';
import { LocalizeModule } from '@bravobit/bb-foundation/localize';
import { CommonModule } from '@angular/common';

/**
 * @fileoverview added by tsickle
 * Generated from: lib/table-header-cell/table-header-cell.component.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class BbTableHeaderCell {
    constructor() {
        // Styling.
        this.disabled = false;
        // Constants.
        this._name = null;
        this._sort = 'none';
        this._sortDirections = ['asc', 'desc', 'none'];
        // State.
        this.state = new BehaviorSubject(null);
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set name(value) {
        this._name = value;
        this.setState();
    }
    /**
     * @return {?}
     */
    get name() {
        return this._name;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set sort(value) {
        this._sort = value;
        this.setState();
    }
    /**
     * @return {?}
     */
    get sort() {
        return this._sort;
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.setState();
    }
    /**
     * @return {?}
     */
    onClick() {
        // Check if the header cell is disabled.
        if (this.disabled) {
            return;
        }
        // Find the index of the current sort.
        /** @type {?} */
        const index = this._sortDirections.findIndex((/**
         * @param {?} item
         * @return {?}
         */
        item => item === this.sort));
        // Increase the current index.
        /** @type {?} */
        let newIndex = index + 1;
        // If the sort is out of bounds set it to null.
        if (newIndex >= this._sortDirections.length) {
            newIndex = 0;
        }
        // Set the new sort.
        this.sort = this._sortDirections[newIndex];
    }
    /**
     * @return {?}
     */
    setState() {
        this.state.next({
            name: this.name,
            direction: this.sort
        });
    }
}
BbTableHeaderCell.decorators = [
    { type: Component, args: [{
                selector: 'bb-table-header-cell',
                template: "<ng-content></ng-content>\r\n\r\n<!-- The indicator for the sort direction. -->\r\n<button *ngIf=\"!disabled\"\r\n        [class.asc]=\"sort === 'asc'\"\r\n        [class.desc]=\"sort === 'desc'\"\r\n        class=\"bb-table-header-cell-toggle\"\r\n        type=\"button\"></button>\r\n",
                changeDetection: ChangeDetectionStrategy.OnPush,
                host: { 'class': 'bb-table-header-cell' },
                encapsulation: ViewEncapsulation.None,
                preserveWhitespaces: false,
                styles: [".bb-table-header-cell{height:50px;color:#212529;cursor:pointer;font-size:16px;font-weight:500;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:10px 20px;position:relative;display:table-cell;vertical-align:middle;border-bottom:1px solid #d8d8d8}.bb-table-header-cell:active>.bb-table-header-cell-toggle{background-color:rgba(0,0,0,.08)}.bb-table-header-cell:not(.disabled){padding-right:52px}.bb-table-header-cell.fit{width:1%;white-space:nowrap}.bb-table-header-cell.left{text-align:left}.bb-table-header-cell.center{text-align:center}.bb-table-header-cell.right{text-align:right}.bb-table-header-cell.disabled{cursor:default;pointer-events:none}.bb-table-header-cell-toggle{top:50%;right:14px;width:22px;border:none;height:22px;margin-left:auto;position:absolute;border-radius:4px;-ms-transform:translateY(-50%);transform:translateY(-50%);background-position:center;background-repeat:no-repeat;background-color:transparent;transition:background-color .2s cubic-bezier(0,0,.2,1);background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 9 15\" width=\"9\" height=\"15\"%3E%3Cpath fill=\"%23dcdcdc\" d=\"M4.5 0L0 7h9z\"%3E%3C/path%3E%3Cpath fill=\"%23dcdcdc\" d=\"M4.5 15L9 8H0z\"%3E%3C/path%3E%3C/svg%3E')}.bb-table-header-cell-toggle.desc{background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 9 15\" width=\"9\" height=\"15\"%3E%3Cpath fill=\"%23dcdcdc\" d=\"M4.5 0L0 7h9z\"%3E%3C/path%3E%3Cpath fill=\"black\" d=\"M4.5 15L9 8H0z\"%3E%3C/path%3E%3C/svg%3E')}.bb-table-header-cell-toggle.asc{background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 9 15\" width=\"9\" height=\"15\"%3E%3Cpath fill=\"black\" d=\"M4.5 0L0 7h9z\"%3E%3C/path%3E%3Cpath fill=\"%23dcdcdc\" d=\"M4.5 15L9 8H0z\"%3E%3C/path%3E%3C/svg%3E')}"]
            }] }
];
BbTableHeaderCell.propDecorators = {
    disabled: [{ type: HostBinding, args: ['class.disabled',] }, { type: Input }],
    name: [{ type: Input }],
    sort: [{ type: Input }],
    onClick: [{ type: HostListener, args: ['click',] }]
};
if (false) {
    /** @type {?} */
    BbTableHeaderCell.prototype.disabled;
    /**
     * @type {?}
     * @private
     */
    BbTableHeaderCell.prototype._name;
    /**
     * @type {?}
     * @private
     */
    BbTableHeaderCell.prototype._sort;
    /**
     * @type {?}
     * @private
     */
    BbTableHeaderCell.prototype._sortDirections;
    /** @type {?} */
    BbTableHeaderCell.prototype.state;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/table/table.component.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class BbTableColumnDef {
}
BbTableColumnDef.decorators = [
    { type: Directive, args: [{
                selector: '[bbTableColumnDef]'
            },] }
];
class BbTable {
    constructor() {
        // Inputs.
        this.identifier = null;
        this.queryFields = [];
        // Sizes.
        this._sizes = [25, 50, 75, 100];
        // Templates.
        this._header = true;
        this._footer = true;
        // Optimizations.
        this.trackByFn = (/**
         * @param {?} index
         * @param {?} item
         * @return {?}
         */
        (index, item) => this.identifier ? item[this.identifier] : index);
        this.trackByValue = (/**
         * @param {?} index
         * @param {?} item
         * @return {?}
         */
        (index, item) => item);
        // State.
        this.queryControl = new FormControl('');
        this.sizeControl = new FormControl(this._sizes[0]);
        this.pageControl = new FormControl(1);
    }
    /**
     * @return {?}
     */
    get sizes() {
        return this._sizes;
    }
    /**
     * @param {?} newValue
     * @return {?}
     */
    set sizes(newValue) {
        this.updateSizes(newValue);
    }
    /**
     * @return {?}
     */
    get header() {
        // If the header equals false just return null.
        if (!this._header) {
            return null;
        }
        // If the header is true use the default header.
        if (this._header === true) {
            return this.headerTemplate;
        }
        // It must be a custom header, use this.
        return this._header;
    }
    /**
     * @param {?} newValue
     * @return {?}
     */
    set header(newValue) {
        this._header = newValue;
    }
    /**
     * @return {?}
     */
    get footer() {
        // If the footer equals false just return null.
        if (!this._footer) {
            return null;
        }
        // If the footer is true use the default header.
        if (this._footer === true) {
            return this.footerTemplate;
        }
        // It must be a custom footer, use this.
        return this._footer;
    }
    /**
     * @param {?} newValue
     * @return {?}
     */
    set footer(newValue) {
        this._footer = newValue;
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        // Validate the data source exists.
        if (!this.dataSource) {
            throw new Error('The data source was not passed properly.');
        }
        // Create a new request.
        this.request = new DataSourceRequest();
        this.isLoading$ = this.request.loading;
        // Pass the request to the data source.
        this.data$ = this.dataSource.handle(this.request).pipe(tap((/**
         * @return {?}
         */
        () => this.request.stopLoading())), map((/**
         * @param {?} result
         * @return {?}
         */
        result => {
            /** @type {?} */
            const count = (result && result.data && result.data.length) || 0;
            if (count <= 0) {
                return { state: 'success-empty', result };
            }
            return { state: 'success-all', result };
        })), catchError((/**
         * @param {?} error
         * @return {?}
         */
        (error) => {
            this.request.stopLoading();
            if (error.status === 404) {
                return of({ state: 'error-not-found' });
            }
            if (error.status === 500) {
                return of({ state: 'error-server' });
            }
            return of({ state: 'error-unknown' });
        })));
    }
    /**
     * @return {?}
     */
    ngAfterViewInit() {
        /** @type {?} */
        const queryChanges$ = this.queryControl.valueChanges.pipe(debounceTime(400), distinctUntilChanged(), startWith([this.queryControl.value]));
        /** @type {?} */
        const sortChanges$ = this.headerCells.changes.pipe(startWith(this.headerCells.toArray()), switchMap((/**
         * @param {?} headerCells
         * @return {?}
         */
        headerCells => combineLatest(headerCells.map((/**
         * @param {?} cell
         * @return {?}
         */
        cell => cell.state))))), map((/**
         * @param {?} cells
         * @return {?}
         */
        cells => cells.filter((/**
         * @param {?} cell
         * @return {?}
         */
        cell => !!cell['name'] && cell['direction'] !== 'none')))));
        /** @type {?} */
        const sizeChanges$ = this.sizeControl.valueChanges.pipe(startWith([this.sizeControl.value]));
        /** @type {?} */
        const pageChanges$ = this.pageControl.valueChanges.pipe(startWith([this.pageControl.value]));
        this._subscription = combineLatest([
            queryChanges$,
            sortChanges$,
            sizeChanges$,
            pageChanges$
        ]).subscribe((/**
         * @param {?} __0
         * @return {?}
         */
        ([query, sort, pageSize, pageNumber]) => {
            this.request.startLoading();
            return this.request.update({
                query,
                pageSize,
                pageNumber,
                queryFields: this.queryFields,
                sort: (/** @type {?} */ (sort))
            });
        }));
    }
    /**
     * @return {?}
     */
    ngOnDestroy() {
        this._subscription && this._subscription.unsubscribe();
    }
    /**
     * @return {?}
     */
    refresh() {
        return this.request.update();
    }
    /**
     * @private
     * @param {?} newValue
     * @return {?}
     */
    updateSizes(newValue) {
        // Validate the sizes has at least one value.
        if (newValue.length <= 0) {
            throw new Error('Cannot set an empty array as the sizes.');
        }
        // Set the new size.
        this._sizes = newValue;
        // Check if the current selected value is
        // in the new sizes array.
        if (this._sizes.includes(this.sizeControl.value)) {
            return;
        }
        // Set the first value in the array as
        // the new value.
        /** @type {?} */
        const firstValue = this._sizes[0];
        this.sizeControl.setValue(firstValue);
    }
}
BbTable.decorators = [
    { type: Component, args: [{
                selector: 'bb-table',
                template: "<!--\r\n    This is the header of the table. It can be a user\r\n    defined custom header or just the default header.\r\n-->\r\n\r\n<header *ngIf=\"header as headerTemplate\"\r\n        class=\"bb-table-top-actions\">\r\n    <ng-container *ngTemplateOutlet=\"headerTemplate\"></ng-container>\r\n</header>\r\n\r\n<!--\r\n    This is the table that contains the\r\n    rows and columns.\r\n-->\r\n\r\n<div class=\"bb-table-wrapper\">\r\n    <div *ngIf=\"isLoading$ | async\"\r\n         class=\"bb-table-progress\">\r\n        <div class=\"bb-table-indeterminate\"></div>\r\n    </div>\r\n    <table class=\"bb-table-container\">\r\n        <thead>\r\n            <tr>\r\n                <ng-content select=\"bb-table-header-cell\"></ng-content>\r\n            </tr>\r\n        </thead>\r\n        <tbody *ngIf=\"data$ | async as data; else isLoadingTemplate\"\r\n               [ngSwitch]=\"data?.state\">\r\n            <ng-container *ngSwitchCase=\"'success-all'\">\r\n                <tr *ngFor=\"let item of data?.result?.data; trackBy: trackByFn\">\r\n                    <ng-container *ngFor=\"let template of tableColumnTemplates\">\r\n                        <ng-container *ngTemplateOutlet=\"template; context: {item: item}\"></ng-container>\r\n                    </ng-container>\r\n                </tr>\r\n            </ng-container>\r\n\r\n            <ng-container *ngSwitchCase=\"'success-empty'\">\r\n                <ng-container\r\n                    *ngTemplateOutlet=\"errorTemplate; context: {content: 'tables.empty'}\"></ng-container>\r\n            </ng-container>\r\n\r\n            <ng-container *ngSwitchCase=\"'error-not-found'\">\r\n                <ng-container\r\n                    *ngTemplateOutlet=\"errorTemplate; context: {content: 'tables.error_not_found'}\"></ng-container>\r\n            </ng-container>\r\n\r\n            <ng-container *ngSwitchCase=\"'error-server'\">\r\n                <ng-container\r\n                    *ngTemplateOutlet=\"errorTemplate; context: {content: 'tables.error_server'}\"></ng-container>\r\n            </ng-container>\r\n\r\n            <ng-container *ngSwitchDefault>\r\n                <ng-container\r\n                    *ngTemplateOutlet=\"errorTemplate; context: {content: 'tables.error_unknown'}\"></ng-container>\r\n            </ng-container>\r\n        </tbody>\r\n    </table>\r\n</div>\r\n\r\n<footer *ngIf=\"footer as footerTemplate\"\r\n        class=\"bb-table-bottom-actions\">\r\n    <ng-container *ngTemplateOutlet=\"footerTemplate\"></ng-container>\r\n</footer>\r\n\r\n<ng-template #isLoadingTemplate>\r\n    <tr>\r\n        <td [attr.colspan]=\"tableColumnTemplates?.length\"\r\n            class=\"bb-table-template\">\r\n            <div class=\"bb-table-template-content\">\r\n                {{ 'tables.loading' | bbLocalize }}\r\n            </div>\r\n        </td>\r\n    </tr>\r\n</ng-template>\r\n\r\n<!--\r\n    This is the template that will be used when the user has not\r\n    supplied a custom header template.\r\n-->\r\n\r\n<ng-template #headerTemplate>\r\n    <ng-content></ng-content>\r\n    <bb-form-control>\r\n        <input [formControl]=\"queryControl\"\r\n               [placeholder]=\"'tables.search' | bbLocalize\"\r\n               bbInput\r\n               autocomplete=\"off\">\r\n        <bb-icon *ngIf=\"queryControl?.value?.length <= 0; else closeButtonTemplate\"\r\n                 bbSuffix\r\n                 src=\"material:search\">\r\n        </bb-icon>\r\n    </bb-form-control>\r\n</ng-template>\r\n\r\n<!--\r\n    This is the template that will be used when the user has not\r\n    supplied a custom footer template.\r\n-->\r\n\r\n<ng-template #footerTemplate>\r\n    <bb-form-control *ngIf=\"sizes?.length > 1\">\r\n        <select [formControl]=\"sizeControl\"\r\n                bbInput\r\n                title=\"Sizes\">\r\n            <option *ngFor=\"let item of sizes; trackBy: trackByValue\"\r\n                    [ngValue]=\"item\">\r\n                {{ item }} / {{ 'tables.page' | bbLocalize }}\r\n            </option>\r\n        </select>\r\n    </bb-form-control>\r\n\r\n    <bb-table-pager [totalPages]=\"(data$ | async)?.result?.totalPages\"\r\n                    [formControl]=\"pageControl\">\r\n    </bb-table-pager>\r\n</ng-template>\r\n\r\n<!--\r\n    This the template that will be used when the user\r\n    has filled in some data in the query control.\r\n-->\r\n\r\n<ng-template #closeButtonTemplate>\r\n    <button bbSuffix\r\n            (click)=\"queryControl?.patchValue('')\"\r\n            type=\"button\"\r\n            class=\"bb-table-progress-close-query\">\r\n        <bb-icon src=\"material:close\"></bb-icon>\r\n    </button>\r\n</ng-template>\r\n\r\n<ng-template #errorTemplate let-content=\"content\">\r\n    <tr>\r\n        <td [attr.colspan]=\"tableColumnTemplates?.length\"\r\n            class=\"bb-table-template\">\r\n            <div class=\"bb-table-template-content\">\r\n                <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"64\" height=\"41\">\r\n                    <g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(0 1)\">\r\n                        <ellipse cx=\"32\" cy=\"33\" fill=\"#F5F5F5\" rx=\"32\" ry=\"7\"></ellipse>\r\n                        <g fill-rule=\"nonzero\" stroke=\"#D9D9D9\">\r\n                            <path\r\n                                d=\"M55 12.7605604L44.8543047 1.25739633C44.3674414.47382661 43.6558789 0 42.9067617 0H21.0932383c-.7491172 0-1.4606797.47395025-1.947543 1.25739633L9 12.7605604V22h46v-9.2394396z\"></path>\r\n                            <path fill=\"#FAFAFA\"\r\n                                  d=\"M41.6132813 15.9315c0-1.6056489.9936718-2.931266 2.2264179-2.9315H55v18.1371277C55 33.2589574 53.6793867 35 52.0504297 35H11.94957031C10.32052344 35 9 33.2588404 9 31.1371277V13h11.1603008c1.2327461 0 2.226418 1.3228085 2.226418 2.9284574v.0211809c0 1.6056489 1.0049921 2.9015426 2.2377382 2.9015426h14.751086c1.2327461 0 2.2377383-1.3078298 2.2377383-2.9134788V15.9315z\"></path>\r\n                        </g>\r\n                    </g>\r\n                </svg>\r\n                {{ content | bbLocalize }}\r\n            </div>\r\n        </td>\r\n    </tr>\r\n</ng-template>\r\n",
                host: { 'class': 'bb-table' },
                changeDetection: ChangeDetectionStrategy.OnPush,
                encapsulation: ViewEncapsulation.None,
                preserveWhitespaces: false,
                styles: [".bb-table{width:100%;display:block;box-shadow:0 6px 6px -6px rgba(0,0,0,.1)}.bb-table.plain{box-shadow:none}.bb-table.plain>.bb-table-wrapper{border-top-left-radius:0;border-top-right-radius:0}.bb-table-wrapper{overflow-x:auto;position:relative;background-color:#fff;border-top-left-radius:4px;border-top-right-radius:4px}.bb-table-container{width:100%}.bb-table-container td{border-bottom:1px solid #d8d8d8}.bb-table-top-actions{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-direction:column;flex-direction:column;padding:20px 20px 10px;background-color:#fff;-ms-flex-pack:end;justify-content:flex-end;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom:1px solid #d8d8d8}.bb-table-top-actions>*{margin-left:0;margin-bottom:10px}.bb-table-top-actions+.bb-table-wrapper{border-radius:0}.bb-table-bottom-actions{height:60px;display:-ms-flexbox;display:flex;padding:0 20px;overflow-x:auto;-ms-flex-align:center;align-items:center;background-color:#fff;border-bottom-left-radius:4px;border-bottom-right-radius:4px}.bb-table-template{border:none;background-color:#f5f5f5;border-bottom:1px solid #d8d8d8}.bb-table-template-content{padding:20px;display:-ms-flexbox;display:flex;color:#3d464d;font-size:16px;line-height:1.2;font-weight:500;min-height:140px;text-align:center;-ms-flex-align:center;align-items:center;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.bb-table-template-content>svg{margin-bottom:12px}.bb-table-progress{top:0;left:0;right:0;opacity:0;width:100%;height:4px;display:block;overflow:hidden;position:absolute;background-color:rgba(47,64,139,.3);-webkit-animation:250ms cubic-bezier(0,0,.2,1) .1s forwards fadeIn;animation:250ms cubic-bezier(0,0,.2,1) .1s forwards fadeIn}.bb-table-progress .bb-table-indeterminate{background-color:#2f408b}.bb-table-progress .bb-table-indeterminate:before{top:0;left:0;bottom:0;content:\"\";position:absolute;will-change:left,right;background-color:inherit;-webkit-animation:2.1s cubic-bezier(.65,.815,.735,.395) infinite indeterminate;animation:2.1s cubic-bezier(.65,.815,.735,.395) infinite indeterminate}.bb-table-progress .bb-table-indeterminate:after{top:0;left:0;bottom:0;content:\"\";position:absolute;-webkit-animation-delay:1.15s;animation-delay:1.15s;will-change:left,right;background-color:inherit;-webkit-animation:2.1s cubic-bezier(.165,.84,.44,1) infinite indeterminate-short;animation:2.1s cubic-bezier(.165,.84,.44,1) infinite indeterminate-short}.bb-table-progress-close-query{padding:0;border:none;border-radius:4px;background-color:transparent;transition:background-color 250ms cubic-bezier(0,0,.2,1)}.bb-table-progress-close-query:hover{background-color:rgba(0,0,0,.08)}.bb-table-progress-close-query:focus{background-color:rgba(0,0,0,.12)}.bb-table-progress-close-query:active{background-color:rgba(0,0,0,.16)}@-webkit-keyframes fadeIn{from{opacity:0}to{opacity:1}}@keyframes fadeIn{from{opacity:0}to{opacity:1}}@-webkit-keyframes indeterminate{0%{left:-35%;right:100%}100%,60%{left:100%;right:-90%}}@keyframes indeterminate{0%{left:-35%;right:100%}100%,60%{left:100%;right:-90%}}@-webkit-keyframes indeterminate-short{0%{left:-200%;right:100%}100%,60%{left:107%;right:-8%}}@keyframes indeterminate-short{0%{left:-200%;right:100%}100%,60%{left:107%;right:-8%}}@media only screen and (min-width:768px){.bb-table-top-actions{-ms-flex-direction:row;flex-direction:row}.bb-table-top-actions>:not(:first-child){margin-left:10px;margin-bottom:10px}}"]
            }] }
];
BbTable.propDecorators = {
    headerCells: [{ type: ContentChildren, args: [BbTableHeaderCell,] }],
    tableColumnTemplates: [{ type: ContentChildren, args: [BbTableColumnDef, { read: TemplateRef },] }],
    headerTemplate: [{ type: ViewChild, args: ['headerTemplate', { static: true, read: TemplateRef },] }],
    footerTemplate: [{ type: ViewChild, args: ['footerTemplate', { static: true, read: TemplateRef },] }],
    identifier: [{ type: Input }],
    dataSource: [{ type: Input }],
    queryFields: [{ type: Input }],
    sizes: [{ type: Input }],
    header: [{ type: Input }],
    footer: [{ type: Input }]
};
if (false) {
    /** @type {?} */
    BbTable.prototype.headerCells;
    /** @type {?} */
    BbTable.prototype.tableColumnTemplates;
    /** @type {?} */
    BbTable.prototype.headerTemplate;
    /** @type {?} */
    BbTable.prototype.footerTemplate;
    /** @type {?} */
    BbTable.prototype.identifier;
    /** @type {?} */
    BbTable.prototype.dataSource;
    /** @type {?} */
    BbTable.prototype.queryFields;
    /**
     * @type {?}
     * @private
     */
    BbTable.prototype._sizes;
    /**
     * @type {?}
     * @private
     */
    BbTable.prototype._header;
    /**
     * @type {?}
     * @private
     */
    BbTable.prototype._footer;
    /** @type {?} */
    BbTable.prototype.trackByFn;
    /** @type {?} */
    BbTable.prototype.trackByValue;
    /** @type {?} */
    BbTable.prototype.request;
    /** @type {?} */
    BbTable.prototype.data$;
    /** @type {?} */
    BbTable.prototype.isLoading$;
    /** @type {?} */
    BbTable.prototype.queryControl;
    /** @type {?} */
    BbTable.prototype.sizeControl;
    /** @type {?} */
    BbTable.prototype.pageControl;
    /**
     * @type {?}
     * @private
     */
    BbTable.prototype._subscription;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/table-cell/table-cell.component.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class BbTableCell {
}
BbTableCell.decorators = [
    { type: Component, args: [{
                selector: 'bb-table-cell',
                template: "<div>\r\n    <ng-content></ng-content>\r\n</div>",
                changeDetection: ChangeDetectionStrategy.OnPush,
                host: { 'class': 'bb-table-cell' },
                encapsulation: ViewEncapsulation.None,
                preserveWhitespaces: false,
                styles: [".bb-table-cell{color:#848f99;font-size:14px;text-align:left;line-height:1.2;font-weight:400;padding:12px 20px;display:table-cell;word-wrap:break-word;vertical-align:middle;background-color:#f5f5f5;border-bottom:1px solid #d8d8d8}.bb-table-cell:not(:last-child){border-right:1px solid #d8d8d8}.bb-table-cell.fit{width:1%;white-space:nowrap}.bb-table-cell.left{text-align:left}.bb-table-cell.center{text-align:center}.bb-table-cell.right{text-align:right}"]
            }] }
];

/**
 * @fileoverview added by tsickle
 * Generated from: lib/table-pager/table-pager.component.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class BbTablePagerBase {
}
/** @type {?} */
const BbTablePagerMixinBase = mixinDisabled(BbTablePagerBase);
class BbTablePager extends BbTablePagerMixinBase {
    constructor() {
        super(...arguments);
        // Inputs.
        this.amountOfButtons = 5;
        this.showArrowButtons = true;
        // Methods.
        this.onChange = (/**
         * @return {?}
         */
        () => ({}));
        this.onTouched = (/**
         * @return {?}
         */
        () => ({}));
        this.trackByIndex = (/**
         * @param {?} index
         * @param {?} item
         * @return {?}
         */
        (index, item) => item.page);
        // Data.
        this._totalPages$ = new BehaviorSubject(1);
        this._pageNumber$ = new BehaviorSubject(1);
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        // Validate the previous button is disabled.
        this.isPreviousDisabled$ = this._pageNumber$.pipe(map((/**
         * @param {?} pageNumber
         * @return {?}
         */
        pageNumber => pageNumber === 1)));
        // Validate the next button is disabled.
        this.isNextDisabled$ = combineLatest([this._pageNumber$, this._totalPages$]).pipe(map((/**
         * @param {?} __0
         * @return {?}
         */
        ([pageNumber, totalPages]) => pageNumber === totalPages)));
        // Create the list with page numbers.
        this.list$ = combineLatest([this._pageNumber$, this._totalPages$]).pipe(map((/**
         * @param {?} __0
         * @return {?}
         */
        ([pageNumber, totalPages]) => this.filterActivePages(pageNumber, totalPages))), share());
    }
    /**
     * @return {?}
     */
    get pageNumber() {
        return this._pageNumber$.getValue();
    }
    /**
     * @param {?} newValue
     * @return {?}
     */
    set pageNumber(newValue) {
        this.update(newValue);
    }
    /**
     * @return {?}
     */
    get totalPages() {
        return this._totalPages$.getValue();
    }
    /**
     * @param {?} newValue
     * @return {?}
     */
    set totalPages(newValue) {
        /** @type {?} */
        const newTotalPages = Math.max(1, newValue);
        this._totalPages$.next(newTotalPages);
    }
    /**
     * @param {?} fn
     * @return {?}
     */
    registerOnChange(fn) {
        this.onChange = fn;
    }
    /**
     * @param {?} fn
     * @return {?}
     */
    registerOnTouched(fn) {
        this.onTouched = fn;
    }
    /**
     * @param {?} isDisabled
     * @return {?}
     */
    setDisabledState(isDisabled) {
        this.disabled = isDisabled;
    }
    /**
     * @param {?} newValue
     * @return {?}
     */
    writeValue(newValue) {
        this.update(newValue, false);
    }
    /**
     * @return {?}
     */
    goToPrevious() {
        /** @type {?} */
        const newValue = this._pageNumber$.getValue() - 1;
        return this.update(newValue);
    }
    /**
     * @return {?}
     */
    goToNext() {
        /** @type {?} */
        const newValue = this._pageNumber$.getValue() + 1;
        return this.update(newValue);
    }
    /**
     * @param {?} index
     * @return {?}
     */
    goToIndex(index) {
        return this.update(index);
    }
    /**
     * @private
     * @param {?} pageNumber
     * @param {?=} notify
     * @return {?}
     */
    update(pageNumber, notify = true) {
        // You can only update when not disabled.
        if (this.disabled) {
            return;
        }
        // Calculate the new value.
        /** @type {?} */
        const newValue = Math.min(this.totalPages, Math.max(1, pageNumber));
        // Don't do anything if the page number is the same.
        if (this._pageNumber$.getValue() === newValue) {
            return;
        }
        // Push the new value.
        this._pageNumber$.next(newValue);
        if (notify) {
            return this.onChange(pageNumber);
        }
    }
    /**
     * @private
     * @param {?} pageNumber
     * @return {?}
     */
    calculatePages(pageNumber) {
        /** @type {?} */
        const min = 1;
        /** @type {?} */
        const max = this.totalPages;
        /** @type {?} */
        const amount = Math.max(1, this.amountOfButtons);
        /** @type {?} */
        const data = Array(amount)
            .fill(0)
            .map((/**
         * @param {?} _
         * @param {?} index
         * @return {?}
         */
        (_, index) => pageNumber + (index - 1)));
        // Validate if the minimum value less than
        // the first value.
        if (data[0] < min) {
            return data.map((/**
             * @param {?} item
             * @return {?}
             */
            item => item + 1));
        }
        // Calculate the difference with the max
        // if this value is higher than 0 we should minus it.
        /** @type {?} */
        const lastValueInArray = data[data.length - 1];
        /** @type {?} */
        const differenceWithMax = lastValueInArray - max;
        if (differenceWithMax > 0) {
            return data.map((/**
             * @param {?} item
             * @return {?}
             */
            item => item - differenceWithMax));
        }
        // Just return the default data.
        return data;
    }
    /**
     * @private
     * @param {?} pageNumber
     * @param {?} totalPages
     * @return {?}
     */
    filterActivePages(pageNumber, totalPages) {
        return this.calculatePages(pageNumber)
            .filter((/**
         * @param {?} page
         * @return {?}
         */
        page => page > 0 && page <= totalPages))
            .map((/**
         * @param {?} page
         * @return {?}
         */
        page => ({ page, active: pageNumber === page })));
    }
}
BbTablePager.decorators = [
    { type: Component, args: [{
                selector: 'bb-table-pager',
                template: "<ul class=\"bb-pager-list\">\r\n    <!-- The previous page arrow button. -->\r\n    <li *ngIf=\"showArrowButtons\"\r\n        class=\"bb-pager-list-item\"\r\n        title=\"Previous page\">\r\n        <button [disabled]=\"isPreviousDisabled$ | async\"\r\n                (click)=\"goToPrevious()\"\r\n                class=\"bb-pager-list-button\"\r\n                type=\"button\">\r\n            <bb-icon src=\"material:keyboard_arrow_left\"></bb-icon>\r\n        </button>\r\n    </li>\r\n\r\n    <!-- The list of number buttons to navigate through the list. -->\r\n    <ng-container *ngIf=\"list$ | async as list\">\r\n        <li *ngFor=\"let item of list; trackBy: trackByIndex\"\r\n            [title]=\"'Page ' + item?.page\"\r\n            class=\"bb-pager-list-item\">\r\n            <button (click)=\"goToIndex(item?.page)\"\r\n                    [class.active]=\"item?.active\"\r\n                    class=\"bb-pager-list-button\"\r\n                    type=\"button\">\r\n                {{ item?.page }}\r\n            </button>\r\n        </li>\r\n    </ng-container>\r\n\r\n    <!-- The next page arrow button. -->\r\n    <li *ngIf=\"showArrowButtons\"\r\n        class=\"bb-pager-list-item\"\r\n        title=\"Next page\">\r\n        <button [disabled]=\"isNextDisabled$ | async\"\r\n                (click)=\"goToNext()\"\r\n                class=\"bb-pager-list-button\"\r\n                type=\"button\">\r\n            <bb-icon src=\"material:keyboard_arrow_right\"></bb-icon>\r\n        </button>\r\n    </li>\r\n</ul>\r\n",
                changeDetection: ChangeDetectionStrategy.OnPush,
                host: {
                    'class': 'bb-table-pager',
                    '[class.disabled]': 'disabled'
                },
                inputs: ['disabled'],
                encapsulation: ViewEncapsulation.None,
                preserveWhitespaces: false,
                providers: [
                    { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/**
                         * @return {?}
                         */
                        () => BbTablePager)), multi: true }
                ],
                styles: [".bb-table-pager{-ms-flex:1;flex:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end}.bb-table-pager.disabled{opacity:.5;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none}.bb-pager-list{display:-ms-flexbox;display:flex}.bb-pager-list-item{margin-left:8px}.bb-pager-list-button{padding:0;color:#3d464d;line-height:1;min-width:32px;font-size:16px;-webkit-appearance:none;-moz-appearance:none;appearance:none;font-weight:500;min-height:32px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:4px;-ms-flex-align:center;align-items:center;display:-ms-inline-flexbox;display:inline-flex;-ms-flex-pack:center;justify-content:center;border:1px solid #b6bbc1;transition-duration:.2s;background-color:transparent;transition-timing-function:cubic-bezier(0,0,.2,1);transition-property:color,border-color,opacity,background-color;box-shadow:inset 0 3px 0 0 rgba(183,188,194,.2),0 6px 6px -6px rgba(0,0,0,.1)}.bb-pager-list-button:focus,.bb-pager-list-button:hover{background-color:rgba(0,0,0,.04)}.bb-pager-list-button.active,.bb-pager-list-button.active:hover{color:#2196f3;cursor:default;border-color:#2196f3;background-color:transparent}.bb-pager-list-button:disabled{opacity:.35;cursor:default;pointer-events:none}"]
            }] }
];
BbTablePager.propDecorators = {
    amountOfButtons: [{ type: Input }],
    showArrowButtons: [{ type: Input }],
    pageNumber: [{ type: Input }],
    totalPages: [{ type: Input }]
};
if (false) {
    /** @type {?} */
    BbTablePager.prototype.amountOfButtons;
    /** @type {?} */
    BbTablePager.prototype.showArrowButtons;
    /** @type {?} */
    BbTablePager.prototype.isPreviousDisabled$;
    /** @type {?} */
    BbTablePager.prototype.isNextDisabled$;
    /** @type {?} */
    BbTablePager.prototype.list$;
    /** @type {?} */
    BbTablePager.prototype.onChange;
    /** @type {?} */
    BbTablePager.prototype.onTouched;
    /** @type {?} */
    BbTablePager.prototype.trackByIndex;
    /**
     * @type {?}
     * @private
     */
    BbTablePager.prototype._totalPages$;
    /**
     * @type {?}
     * @private
     */
    BbTablePager.prototype._pageNumber$;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/table.module.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/** @type {?} */
const DECLARATIONS_EXPORTS = [
    BbTable,
    BbTableColumnDef,
    BbTableHeaderCell,
    BbTableCell
];
class TableModule {
}
TableModule.decorators = [
    { type: NgModule, args: [{
                imports: [CommonModule, FormsModule, ReactiveFormsModule, ElementsModule, LocalizeModule],
                declarations: [BbTablePager, ...DECLARATIONS_EXPORTS],
                exports: [...DECLARATIONS_EXPORTS]
            },] }
];

/**
 * @fileoverview added by tsickle
 * Generated from: public_api.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * Generated from: bravobit-bb-foundation-table.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

export { BbTable, BbTableCell, BbTableColumnDef, BbTableHeaderCell, TableModule, BbTablePager as ɵa };
//# sourceMappingURL=bravobit-bb-foundation-table.js.map
