import { __decorate } from "tslib";
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewChild, } from '@angular/core';
import { ReplaySubject, combineLatest } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { ObservableInput } from '../../../../utils/public-api';
import { ConfigurableField, } from '../../types';
export class ResourceDataGridComponent {
    constructor() {
        this.context = 'page';
        this.data = [];
        this.type = 'namespace';
        this.fields = [ConfigurableField.Time];
        this.loading = true;
        this.selectItem = new EventEmitter();
        this.filter = new EventEmitter();
        this.reload = new EventEmitter();
        this.keyword = '';
        this.fieldsDef = ConfigurableField;
        this.displayMode = 'row';
        this.filter$ = new ReplaySubject(1);
        this.displayModeKey = 'acl_display_mode';
        this.scrollInitialized = false;
        this.statusIcon = {
            normal: 'check_circle_s',
            abnormal: 'exclamation_triangle_s',
            enabled: 'check_circle_s',
            disabled: 'basic:minus_circle_s',
        };
        this.getHighlightedNameStrs = (item) => {
            if (!this.keyword) {
                return [
                    {
                        text: item.name,
                    },
                ];
            }
            const original = item.name;
            const strs = item.name.toLowerCase().split(this.keyword.toLowerCase());
            const ret = [];
            let pos = 0;
            for (const [i, str] of strs.entries()) {
                const end = pos + str.length;
                ret.push({
                    text: original.slice(pos, end),
                });
                if (i !== strs.length - 1) {
                    ret.push({
                        text: original.slice(end, end + this.keyword.length),
                        isHighlighted: true,
                    });
                }
                pos = end + this.keyword.length;
            }
            return ret;
        };
    }
    set grid(grid) {
        if (grid) {
            this.initScroll(grid.nativeElement);
        }
    }
    ngOnInit() {
        const displayMode = window.localStorage.getItem(this.displayModeKey);
        this.displayMode =
            this.context === 'popup'
                ? 'row'
                : ['row', 'card'].includes(displayMode)
                    ? displayMode
                    : 'row';
        this.displayData$ = combineLatest([
            this.data$,
            this.filter$.pipe(startWith('')),
        ]).pipe(map(([data, keyword]) => data.filter(item => item.name.toLowerCase().includes(keyword.toLowerCase()))));
    }
    initScroll(scrollEl) {
        var _a;
        if (this.context === 'page' ||
            this.scrollInitialized ||
            !((_a = this.data) === null || _a === void 0 ? void 0 : _a.length)) {
            return;
        }
        const currentIndex = this.data.findIndex(item => item.__origin.metadata.uid === this.selectedUid);
        const rowHeight = scrollEl.scrollHeight / this.data.length;
        if (currentIndex > -1 &&
            rowHeight * (currentIndex + 1) > scrollEl.offsetHeight) {
            scrollEl.scrollTo({
                top: rowHeight * currentIndex,
            });
        }
        this.scrollInitialized = true;
    }
    onSelect(item) {
        var _a;
        if (((_a = item.state) === null || _a === void 0 ? void 0 : _a.disabled) ||
            this.selectedUid === item.__origin.metadata.uid) {
            return;
        }
        this.selectedUid = item.name;
        this.selectItem.emit(item);
    }
    setDisplayMode(mode) {
        this.displayMode = mode;
        window.localStorage.setItem(this.displayModeKey, mode);
    }
    keywordChange(keyword) {
        this.keyword = keyword;
        this.filter$.next(keyword);
    }
    filterDisabledData(data, context) {
        // workaround for typings in template
        return (context === 'page' ? data : data.filter(item => { var _a; return !((_a = item.state) === null || _a === void 0 ? void 0 : _a.disabled); }));
    }
}
ResourceDataGridComponent.decorators = [
    { type: Component, args: [{
                selector: 'acl-resource-data-grid',
                template: "<div class=\"header\">\n  <span class=\"header__title\">\n    <span>{{ type | translate }}</span\n    >\uFF08{{ (displayData$ | async)?.length || 0 }}\uFF09\n  </span>\n  <div class=\"header__custom\">\n    <ng-content select=\"[aclResourceGridHeader]\"></ng-content>\n  </div>\n  <aui-search\n    [searchButton]=\"false\"\n    [placeholder]=\"'filter_by_name' | translate\"\n    [keyword]=\"keyword\"\n    (keywordChange)=\"keywordChange($event)\"\n    [clearable]=\"true\"\n  ></aui-search>\n  <span class=\"header__display-mode\" *ngIf=\"context === 'page'\">\n    <span\n      class=\"switch-btn\"\n      [ngClass]=\"{ 'switch-btn--selected': displayMode !== 'card' }\"\n      (click)=\"setDisplayMode('row')\"\n    >\n      <img src=\"icons/icon-list.svg\" *ngIf=\"displayMode === 'card'\" alt=\"\" />\n      <img\n        src=\"icons/icon-list-blue.svg\"\n        *ngIf=\"displayMode !== 'card'\"\n        alt=\"\"\n      />\n    </span>\n    <span\n      class=\"switch-btn\"\n      [ngClass]=\"{ 'switch-btn--selected': displayMode === 'card' }\"\n      (click)=\"setDisplayMode('card')\"\n    >\n      <img src=\"icons/icon-card.svg\" *ngIf=\"displayMode !== 'card'\" alt=\"\" />\n      <img\n        src=\"icons/icon-card-blue.svg\"\n        *ngIf=\"displayMode === 'card'\"\n        alt=\"\"\n      />\n    </span>\n  </span>\n</div>\n<ng-container\n  *ngIf=\"\n    !loading &&\n    (displayData$ | async | pure: filterDisabledData:context) as displayData\n  \"\n>\n  <div\n    class=\"grid\"\n    *ngIf=\"displayData.length\"\n    #grid\n    [ngClass]=\"{\n      'grid--card': displayMode === 'card' && context !== 'popup',\n      'grid--popup': context === 'popup'\n    }\"\n  >\n    <div\n      class=\"grid__item\"\n      *ngFor=\"let item of displayData\"\n      [ngClass]=\"{\n        'grid__item--selected':\n          context === 'popup' && selectedUid === item.__origin.metadata.uid,\n        'grid__item--disabled': item.state?.disabled\n      }\"\n      (click)=\"onSelect(item)\"\n      [auiTooltip]=\"item.state?.tooltip\"\n      [auiTooltipDisabled]=\"!item.state?.disabled || !item.state?.tooltip\"\n    >\n      <aui-icon\n        icon=\"check_triangle_s\"\n        class=\"grid__item-selected-icon\"\n      ></aui-icon>\n      <!-- icon -->\n      <div class=\"grid__field grid__field-icon\">\n        <acl-resource-icon\n          [type]=\"type\"\n          [color]=\"\n            context === 'popup' && selectedUid === item.__origin.metadata.uid\n              ? 'white'\n              : 'blue'\n          \"\n          [size]=\"displayMode === 'card' ? 40 : 30\"\n        ></acl-resource-icon>\n      </div>\n      <!-- name -->\n      <div class=\"grid__field grid__field-name\">\n        <div class=\"name\">\n          <ng-container *ngFor=\"let str of getHighlightedNameStrs(item)\">\n            <span [ngClass]=\"{ highlighted: str.isHighlighted }\">{{\n              str.text\n            }}</span>\n          </ng-container>\n          <!-- for cluster -->\n          <ng-container *ngIf=\"type === 'cluster'\">\n            <aui-icon\n              *ngIf=\"item.isHA\"\n              icon=\"basic:high_availability\"\n              [auiTooltip]=\"'high_availability_cluster' | translate\"\n            ></aui-icon>\n            <aui-icon\n              *ngIf=\"item.isFederal\"\n              icon=\"basic:federation_cluster\"\n              [auiTooltip]=\"item.fedTooltip\"\n              color=\"#1cb6cc\"\n            ></aui-icon>\n          </ng-container>\n        </div>\n        <div class=\"des\" *ngIf=\"item.displayName\">{{ item.displayName }}</div>\n      </div>\n      <!-- ns: cluster -->\n      <div class=\"grid__field flex\" *ngIf=\"fields.includes(fieldsDef.Cluster)\">\n        <span\n          class=\"text-truncate\"\n          auiTooltip=\"{{\n            ('belonged_cluster' | translate) + ': ' + item.cluster\n          }}\"\n        >\n          <span class=\"with-colon\">{{ 'belonged_cluster' | translate }}</span>\n          {{ item.cluster }}\n        </span>\n      </div>\n      <!-- project: status -->\n      <div\n        class=\"grid__field grid__field-status {{\n          'grid__field-status--' + item.status\n        }}\"\n        *ngIf=\"fields.includes(fieldsDef.Status)\"\n      >\n        <aui-icon\n          [icon]=\"statusIcon[item.status]\"\n          class=\"{{ 'icon-' + item.status }}\"\n        ></aui-icon>\n        {{ item.status | translate }}\n      </div>\n      <!-- asm: service mesh -->\n      <div\n        class=\"grid__field grid__field-servicemesh\"\n        *ngIf=\"fields.includes(fieldsDef.ServiceMesh)\"\n      >\n        <div>\n          <span class=\"with-colon\">{{\n            'belonged_servicemesh' | translate\n          }}</span>\n          <span class=\"servicemesh-status\">\n            {{ item.serviceMeshName }}\n          </span>\n        </div>\n        <div *ngIf=\"item.serviceMeshIstioVersion\">\n          Istio {{ item.serviceMeshIstioVersion }}\n        </div>\n      </div>\n\n      <!-- asm: service mesh clusters -->\n      <div\n        class=\"grid__field grid__field-servicemeshClusters\"\n        *ngIf=\"fields.includes(fieldsDef.ServiceMeshClusters)\"\n      >\n        <div class=\"with-colon\">{{ 'cluster' | translate }}</div>\n        <div>\n          <div\n            *ngFor=\"let cluster of item.serviceMeshClusters; first as isFirst\"\n          >\n            {{ cluster }}\n            <ng-container *ngIf=\"isFirst && item.serviceMeshClusters.length > 1\"\n              >({{ 'master' | translate }})</ng-container\n            >\n          </div>\n        </div>\n      </div>\n\n      <!-- admin -->\n      <div class=\"grid__field flex\" *ngIf=\"fields.includes(fieldsDef.Admin)\">\n        <span\n          class=\"text-truncate\"\n          auiTooltip=\"{{ ('administrator' | translate) + ': ' + item.admin }}\"\n          [auiTooltipDisabled]=\"!item.admin\"\n        >\n          <span class=\"with-colon\">{{ 'administrator' | translate }}</span>\n          {{ item.admin | aclFieldNotAvailable }}\n        </span>\n      </div>\n      <!-- node number -->\n      <div class=\"grid__field\" *ngIf=\"fields.includes(fieldsDef.Nodes)\">\n        <span class=\"with-colon\">{{ 'node_number' | translate }}</span>\n        {{ item.nodeNumber | aclFieldNotAvailable }}\n      </div>\n      <!-- time -->\n      <div\n        class=\"grid__field grid__field-time\"\n        *ngIf=\"fields.includes(fieldsDef.Time)\"\n      >\n        <span class=\"with-colon\">{{ 'created_time' | translate }}</span>\n        {{ item.timestamp | aclRelativeTime }}\n      </div>\n      <!-- action -->\n      <div\n        class=\"grid__field grid__field-action\"\n        (click)=\"$event.stopPropagation()\"\n        *ngIf=\"\n          fields.includes(fieldsDef.Action) &&\n          actionTemplateRef &&\n          context !== 'popup'\n        \"\n      >\n        <ng-container\n          [ngTemplateOutlet]=\"actionTemplateRef\"\n          [ngTemplateOutletContext]=\"{\n            $implicit: item.__origin\n          }\"\n        ></ng-container>\n      </div>\n    </div>\n  </div>\n  <acl-resource-no-data\n    *ngIf=\"!(displayData$ | async)?.length\"\n    [isFiltered]=\"!!keyword\"\n    [type]=\"type\"\n    (refresh)=\"reload.emit()\"\n    (clear)=\"keywordChange('')\"\n  ></acl-resource-no-data>\n</ng-container>\n<div class=\"loading\" *ngIf=\"loading\">\n  <acl-loading-mask [loading]=\"loading\" type=\"content\"></acl-loading-mask>\n</div>\n",
                changeDetection: ChangeDetectionStrategy.OnPush,
                styles: [":host{padding-bottom:20px;display:flex;flex-direction:column;flex:1;overflow:hidden}.header{display:flex;align-items:center;padding:16px 0}.header aui-search{width:260px}.header__title{font-size:18px}.header__custom{flex:1;padding:0 36px}.header__display-mode{display:flex;border:1px solid #ccc;margin-left:16px}.switch-btn{cursor:pointer;width:30px;height:30px;border:1px solid #e5e5e5;color:#999;display:inline-flex;align-items:center;justify-content:center;background-color:#e5e5e5}.switch-btn--selected{background-color:#fff;color:var(--aui-color-primary)}.grid{overflow-y:auto}.grid__item{display:flex;position:relative;flex-direction:row;border:.9px solid #ccc;padding:20px 25px;height:80px;color:#666;align-items:center;cursor:pointer}.grid__item:not(:last-child){margin-bottom:8px}.grid__item:not(.grid__item--disabled):hover{border-color:var(--aui-color-primary);box-shadow:0 4px 16px #0000003d}.grid__item--disabled{cursor:default}.grid__item--disabled,.grid__item--disabled:hover{background-color:#f4f4f4}.grid__item--disabled .grid__field{opacity:.3}.grid__item--disabled .grid__field-servicemesh,.grid__item--disabled .grid__field-action{opacity:1}.grid__field{flex:2}.grid__field:not(.grid__field-status){white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.grid__field:not(:last-child){margin-right:16px}.grid__field-servicemesh{display:flex;flex-direction:column}.grid__field-servicemeshClusters{display:flex}.grid__field-status{display:flex;align-items:center}.grid__field-status aui-icon{border-radius:50%;background-color:#fff;display:inline-flex;margin-right:4px}.grid__field-icon{max-width:30px;display:inline-flex}.grid__field-name{flex:3;flex-direction:column;max-width:280px}.grid__field-name .name,.grid__field-name .des{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.grid__field-name .name{font-size:18px;color:#333}.grid__field-name .name aui-icon{margin-left:4px}.grid__field-name .des{font-size:12px;color:#999}.grid__field-action{max-width:30px}.grid__item-selected-icon{position:absolute;right:0;bottom:0;color:#fff;display:none;font-size:23px}.grid--popup .grid__field-name .name{font-size:16px}.grid--popup .grid__item{padding:15px 20px;height:60px;font-size:12px}.grid--popup .grid__item--selected{background-image:linear-gradient(94deg,#4392ff,#45acff);border-color:#4392ff;color:#fff;cursor:default}.grid--popup .grid__item--selected:hover{box-shadow:none}.grid--popup .grid__item--selected .grid__item-selected-icon{display:inline-flex}.grid--popup .grid__item--selected .grid__field-name .name,.grid--popup .grid__item--selected .grid__field-name .des{color:#fff}.grid--popup .grid__item--selected .highlighted{color:#4392ff;background-color:#fff}.grid--card{display:grid;grid-template-columns:repeat(auto-fill,minmax(208px,1fr));grid-gap:20px 20px;gap:20px 20px}.grid--card .grid__item{margin-bottom:0;height:auto;display:block;text-align:center;padding-left:36px;padding-right:36px}.grid--card .grid__field{margin-right:0}.grid--card .grid__field-icon{max-width:100%}.grid--card .grid__field-name{margin:8px 0 12px}.grid--card .grid__field-name .name,.grid--card .grid__field-name .des{justify-content:center}.grid--card .grid__field-name~.grid__field:not(.grid__field-status){line-height:20px;font-size:12px;text-align:left}.grid--card .grid__field-status{position:absolute;right:0;top:0;padding:4px}.grid--card .grid__field-status:after{content:\"\";position:absolute;width:0;height:0;border-width:13px 10px 13px 0;border-color:transparent;border-style:solid;top:0;left:-10px}.grid--card .grid__field-status--normal{background-color:#006dff0d}.grid--card .grid__field-status--normal:after{border-right-color:#006dff0d}.grid--card .grid__field-status--abnormal{background-color:#e545450d}.grid--card .grid__field-status--abnormal:after{border-right-color:#e545450d}.grid--card .grid__field-action{position:absolute;right:10px;top:10px}.flex{display:flex}.highlighted{background-color:#f7e8ac}.with-colon:after{content:\":\";margin-right:8px}.icon-normal,.icon-enabled{color:var(--aui-color-success)}.icon-abnormal{color:var(--aui-color-error)}.icon-disabled{color:#ccc}.text-truncate{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.loading{display:flex;height:343px;align-items:center;justify-content:center}acl-resource-no-data{flex:1}\n"]
            },] }
];
ResourceDataGridComponent.propDecorators = {
    grid: [{ type: ViewChild, args: ['grid',] }],
    context: [{ type: Input }],
    data: [{ type: Input }],
    type: [{ type: Input }],
    fields: [{ type: Input }],
    actionTemplateRef: [{ type: Input }],
    selectedUid: [{ type: Input }],
    loading: [{ type: Input }],
    selectItem: [{ type: Output }],
    filter: [{ type: Output }],
    reload: [{ type: Output }]
};
__decorate([
    ObservableInput()
], ResourceDataGridComponent.prototype, "data$", void 0);
//# sourceMappingURL=data:application/json;base64, 