UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

928 lines 56.6 kB
import * as i0 from '@angular/core';
import { inject, Injectable, InjectionToken, EventEmitter, Output, Input, Component, ViewChild, NgModule } from '@angular/core';
import { QueriesUtil, SmartGroupsService } from '@c8y/client';
import * as i2 from '@c8y/ngx-components';
import { PreviewService, ContextRouteService, WILDCARD_SEARCH_FEATURE_KEY, SearchFilters, ViewContext, TabsOutletComponent, TabComponent, C8yTranslatePipe, RouterService, SearchInputComponent, getBasicInputArrayFormFieldConfig, BuiltInActionType, FilteringActionType, DataGridComponent, ColumnDirective, EmptyStateComponent, UserPreferencesConfigurationStrategy, DATA_GRID_CONFIGURATION_STRATEGY, DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, Status, TitleComponent, C8yTranslateDirective, CoreModule, CoreSearchModule, hookRoute, hookSearch } from '@c8y/ngx-components';
import { AssetNodeService } from '@c8y/ngx-components/assets-navigator';
import { DeviceGridService, NameDeviceGridColumn, ModelDeviceGridColumn, SerialNumberDeviceGridColumn, RegistrationDateDeviceGridColumn, SystemIdDeviceGridColumn, ImeiDeviceGridColumn, AlarmsDeviceGridColumn, DeviceGridModule } from '@c8y/ngx-components/device-grid';
import { BehaviorSubject, firstValueFrom, catchError, of, lastValueFrom, Subject } from 'rxjs';
import { AssetTypeGridColumn, AssetTypeCellRendererComponent } from '@c8y/ngx-components/data-grid-columns/asset-type';
import { AsyncPipe, NgIf, NgFor } from '@angular/common';
import * as i1$1 from '@angular/router';
import { Router, ActivationEnd } from '@angular/router';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import * as i1 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { gettext } from '@c8y/ngx-components/gettext';
import { filter, map, startWith, catchError as catchError$1, takeUntil } from 'rxjs/operators';
import { SubAssetsService, DeleteAssetsModalComponent } from '@c8y/ngx-components/sub-assets';
import { BsModalService } from 'ngx-bootstrap/modal';

class AssetSearchService {
    constructor() {
        this.GRID_CONFIG_STORAGE_KEY = 'search-grid-config';
        this.DEFAULT_PAGE_SIZE = 50;
        this.getGlobalSearchData = this.getSearchData.bind(this);
        this.appliedFilters$ = new BehaviorSubject({
            allFilters: true,
            onlyDevices: true,
            onlyGroupsAndAssets: true,
            currentHierarchy: false
        });
        this.previewService = inject(PreviewService);
        this.deviceGridService = inject(DeviceGridService);
        this.assetNodeService = inject(AssetNodeService);
        this.contextRouteService = inject(ContextRouteService);
        this.queriesUtil = new QueriesUtil();
    }
    /**
     * Resets the status of applied filters, used during the search.
     * Applies only to filters: 'All', 'Show only devices', 'Show only groups and assets'.
     */
    resetAppliedFilters() {
        this.appliedFilters$.next({
            allFilters: true,
            onlyDevices: true,
            onlyGroupsAndAssets: true,
            currentHierarchy: false
        });
    }
    buildCombinedRootQueryFilter(columns, pagination) {
        const rootQuery = {
            __filter: {
                __and: { __not: { __has: `c8y_IsBinary` } }
            }
        };
        const { onlyDevices, onlyGroupsAndAssets } = this.appliedFilters$.value;
        const searchQuery = this.buildSearchQuery({ onlyDevices, onlyGroupsAndAssets });
        const userQuery = this.deviceGridService.getQueryObj(columns, pagination);
        const queryPart = this.queriesUtil.addOrderbys(rootQuery, userQuery.__orderby, 'append');
        const fullQuery = this.queriesUtil.addAndFilter(queryPart, userQuery.__filter);
        const queryWithSearch = this.queriesUtil.addAndFilter(fullQuery, searchQuery);
        return queryWithSearch;
    }
    async getData(columns, pagination, text) {
        const query = this.buildCombinedRootQueryFilter(columns, pagination);
        if (await this.isWildcardSearchEnabled()) {
            const wildcardQuery = this.queriesUtil.addAndFilter(query, {
                name: `*${text.trim().replace(/\s+/g, '*')}*`
            });
            return this.assetNodeService.getAllInventories({
                ...pagination,
                query: this.queriesUtil.buildQuery(wildcardQuery)
            });
        }
        return this.assetNodeService.getAllInventories({
            ...pagination,
            query: this.queriesUtil.buildQuery(query),
            text
        });
    }
    getDefaultColumns() {
        const defaultColumns = [
            new NameDeviceGridColumn({ sortOrder: 'asc' }),
            new ModelDeviceGridColumn(),
            new SerialNumberDeviceGridColumn({ visible: false }),
            new RegistrationDateDeviceGridColumn({ visible: false }),
            new SystemIdDeviceGridColumn({ visible: false }),
            new ImeiDeviceGridColumn({ visible: false }),
            new AlarmsDeviceGridColumn()
        ];
        return defaultColumns;
    }
    getDefaultActionControls() {
        return [];
    }
    getDefaultBulkActionControls() {
        return [];
    }
    getDefaultPagination() {
        return {
            pageSize: 25,
            currentPage: 1
        };
    }
    async isWildcardSearchEnabled() {
        return firstValueFrom(this.previewService.getState$(WILDCARD_SEARCH_FEATURE_KEY).pipe(catchError(() => of(true))));
    }
    buildSearchQuery(model) {
        const filter = {};
        const ors = [];
        if (model.types?.length) {
            ors.push({ type: { __in: model.types } });
        }
        if (model.onlyDevices) {
            ors.push({ __has: 'c8y_IsDevice' });
        }
        if (model.onlyGroupsAndAssets) {
            ors.push({ __has: 'c8y_IsDynamicGroup' });
            ors.push({ __has: 'c8y_IsDeviceGroup' });
        }
        if (!model.onlyDevices && !model.onlyGroupsAndAssets) {
            ors.push([
                { __has: 'c8y_IsDeviceGroup' },
                { __has: 'c8y_IsDevice' },
                { __has: 'c8y_IsAsset' }
            ]);
        }
        if (ors.length) {
            filter.__or = ors;
        }
        if (model.currentHierarchy && this.contextRouteService.activatedContextData?.contextData?.id) {
            filter.__and = [
                { __isinhierarchyof: this.contextRouteService.activatedContextData.contextData.id }
            ];
        }
        return filter;
    }
    /**
     * Get search data based on the provided text and pagination.
     * @param text The search text.
     * @param pagination The pagination options.
     * @returns The search results.
     */
    async getSearchData(text, pagination = { currentPage: 1, pageSize: this.DEFAULT_PAGE_SIZE }) {
        const { onlyDevices, onlyGroupsAndAssets, currentHierarchy } = this.appliedFilters$.value;
        const query = this.buildSearchQuery({ onlyDevices, onlyGroupsAndAssets, currentHierarchy });
        const queryString = this.queriesUtil.buildQuery(query);
        if (await this.isWildcardSearchEnabled()) {
            const wildcardQuery = this.queriesUtil.addAndFilter(query, {
                name: `*${text.trim().replace(/\s+/g, '*')}*`
            });
            return this.assetNodeService.getAllInventories({
                ...pagination,
                query: this.queriesUtil.buildQuery(wildcardQuery)
            });
        }
        return this.assetNodeService.getAllInventories({ ...pagination, query: queryString, text });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AssetSearchService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AssetSearchService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AssetSearchService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [] });

const SEARCH_CONFIG = new InjectionToken('SearchConfig');

class SearchCustomFiltersComponent {
    constructor() {
        this.useTabs = false;
        this.customDataQuery = new EventEmitter();
        this.refresh = new EventEmitter();
        this.tabNames = {
            all: gettext('All'),
            devices: gettext('Devices'),
            groupsAndAssets: gettext('Groups and assets')
        };
        this.selectedTab = this.tabNames.all;
        this.checkboxesState = [
            {
                label: gettext('All'),
                name: SearchFilters.ALL_FILTERS,
                value: true,
                indeterminate: false,
                isDisabled: true
            },
            { label: gettext('Show only devices'), name: SearchFilters.ONLY_DEVICES, value: true },
            {
                label: gettext('Show only groups and assets'),
                name: SearchFilters.ONLY_GROUPS_AND_ASSETS,
                value: true
            }
        ];
        this.isOnlyHierarchyQuery = false;
        this.isOnlyHierarchyQueryChange = new EventEmitter();
        this.assetSearchService = inject(AssetSearchService);
        this.contextRouteService = inject(ContextRouteService);
        this.router = inject(Router);
        this.contextRouteData$ = this.router.events.pipe(filter(event => event instanceof ActivationEnd), map((routeData) => {
            const data = this.contextRouteService.getContextData(routeData.snapshot);
            if (data?.context === ViewContext.Group) {
                return data;
            }
            return null;
        }), takeUntilDestroyed());
        this.context$ = this.contextRouteData$.pipe(startWith(this.contextRouteService.activatedContextData), takeUntilDestroyed());
    }
    ngOnInit() {
        this.customDataQuery.next(this.assetSearchService.getGlobalSearchData);
    }
    onCheckboxChange(event, checkbox) {
        const { checked } = event.target;
        if (checked == undefined) {
            return;
        }
        switch (checkbox.name) {
            case SearchFilters.ALL_FILTERS:
                this.onSelectAll(checkbox, checked);
                break;
            case SearchFilters.ONLY_DEVICES:
                this.onAllDevices(checkbox, checked);
                break;
            case SearchFilters.ONLY_GROUPS_AND_ASSETS:
                this.onGroupsAndAssets(checkbox, checked);
                break;
        }
        // Handle allFilters checkbox when ONLY_GROUPS_AND_ASSETS and ONLY_DEVICES are selected
        if (this.getCheckbox(SearchFilters.ONLY_DEVICES).value &&
            this.getCheckbox(SearchFilters.ONLY_GROUPS_AND_ASSETS).value) {
            Object.assign(this.getCheckbox(SearchFilters.ALL_FILTERS), {
                indeterminate: false,
                isDisabled: true,
                value: true
            });
        }
        this.onSearchFilterChange(this.getCheckbox(SearchFilters.ALL_FILTERS).value, this.getCheckbox(SearchFilters.ONLY_DEVICES).value, this.getCheckbox(SearchFilters.ONLY_GROUPS_AND_ASSETS).value);
        this.refresh.next(null);
    }
    onTabChange(tabName = this.tabNames.all) {
        this.selectedTab = tabName;
        this.onSearchFilterChange(tabName === this.tabNames.all, tabName === this.tabNames.devices, tabName === this.tabNames.groupsAndAssets, this.isOnlyHierarchyQuery);
    }
    onHierarchyQueryChange(checked) {
        this.isOnlyHierarchyQuery = checked;
        this.isOnlyHierarchyQueryChange.next(checked);
        this.onSearchFilterChange(this.selectedTab === this.tabNames.all, this.selectedTab === this.tabNames.devices, this.selectedTab === this.tabNames.groupsAndAssets, checked);
    }
    onSearchFilterChange(all, devices, groupsAndAssets, currentHierarchy = false) {
        this.assetSearchService.appliedFilters$.next({
            [SearchFilters.ALL_FILTERS]: all,
            [SearchFilters.ONLY_DEVICES]: devices,
            [SearchFilters.ONLY_GROUPS_AND_ASSETS]: groupsAndAssets,
            [SearchFilters.CURRENT_HIERARCHY]: currentHierarchy
        });
        this.refresh.next(null);
    }
    saveCheckboxValue(checkbox, value) {
        checkbox.value = value;
    }
    onSelectAll(currentCheckbox, checked) {
        // Block unchecked state
        if (checked) {
            this.saveCheckboxValue(currentCheckbox, checked);
        }
        this.getCheckbox(SearchFilters.ALL_FILTERS).isDisabled = true;
        this.getCheckbox(SearchFilters.ONLY_DEVICES).value = true;
        this.getCheckbox(SearchFilters.ONLY_GROUPS_AND_ASSETS).value = true;
    }
    onAllDevices(currentCheckbox, checked) {
        this.saveCheckboxValue(currentCheckbox, checked);
        Object.assign(this.getCheckbox(SearchFilters.ALL_FILTERS), {
            indeterminate: true,
            isDisabled: false,
            value: null
        });
        this.getCheckbox(SearchFilters.ONLY_GROUPS_AND_ASSETS).value = true;
    }
    onGroupsAndAssets(currentCheckbox, checked) {
        this.saveCheckboxValue(currentCheckbox, checked);
        Object.assign(this.getCheckbox(SearchFilters.ALL_FILTERS), {
            indeterminate: true,
            isDisabled: false,
            value: null
        });
        this.getCheckbox(SearchFilters.ONLY_DEVICES).value = true;
    }
    getCheckbox(checkboxName) {
        return this.checkboxesState.find(checkbox => checkbox.name === checkboxName);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SearchCustomFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: SearchCustomFiltersComponent, isStandalone: true, selector: "c8y-search-custom-filters", inputs: { useTabs: "useTabs", isOnlyHierarchyQuery: "isOnlyHierarchyQuery" }, outputs: { customDataQuery: "customDataQuery", refresh: "refresh", isOnlyHierarchyQueryChange: "isOnlyHierarchyQueryChange" }, ngImport: i0, template: "<div class=\"d-flex gap-16 p-l-4 p-l-24 p-r-24\">\n  @if (!useTabs) {\n    <div class=\"p-b-8 separator-bottom sticky-top p-t-4\">\n      @for (checkbox of checkboxesState; track $index) {\n        <label class=\"c8y-checkbox\">\n          <input\n            type=\"checkbox\"\n            [checked]=\"checkbox.value\"\n            [indeterminate]=\"checkbox.indeterminate\"\n            (click)=\"onCheckboxChange($event, checkbox)\"\n            [attr.disabled]=\"checkbox.isDisabled ? true : null\"\n          />\n          <span></span>\n          <span>{{ checkbox.label | translate }}</span>\n        </label>\n      }\n    </div>\n  }\n</div>\n\n@if (useTabs) {\n  <c8y-tabs-outlet\n    class=\"elevation-none\"\n    outletName=\"searchTabs\"\n    orientation=\"horizontal\"\n  ></c8y-tabs-outlet>\n}\n\n<c8y-tab\n  [icon]=\"'asterisk-key'\"\n  [title]=\"'All devices, assets and groups' | translate\"\n  [isActive]=\"selectedTab === tabNames.all\"\n  [tabsOutlet]=\"'searchTabs'\"\n  [label]=\"tabNames.all | translate\"\n  [priority]=\"1000\"\n  (onSelect)=\"onTabChange(tabNames.all)\"\n></c8y-tab>\n<c8y-tab\n  [icon]=\"'exchange'\"\n  [title]=\"'Devices only' | translate\"\n  [isActive]=\"selectedTab === tabNames.devices\"\n  [tabsOutlet]=\"'searchTabs'\"\n  [label]=\"tabNames.devices | translate\"\n  [priority]=\"750\"\n  (onSelect)=\"onTabChange(tabNames.devices)\"\n></c8y-tab>\n<c8y-tab\n  [icon]=\"'c8y-modules'\"\n  [title]=\"'Assets and groups only' | translate\"\n  [isActive]=\"selectedTab === tabNames.groupsAndAssets\"\n  [tabsOutlet]=\"'searchTabs'\"\n  [label]=\"tabNames.groupsAndAssets | translate\"\n  [priority]=\"500\"\n  (onSelect)=\"onTabChange(tabNames.groupsAndAssets)\"\n></c8y-tab>\n\n@if (useTabs && (context$ | async)?.contextData?.name) {\n  <div class=\"p-l-48 p-t-8 d-flex a-i-center\">\n    <span translate>Search only in`specified group or asset`</span>\n    <span class=\"text-bold p-l-4\">{{ (context$ | async)?.contextData?.name }}</span>\n    <label\n      class=\"m-l-8 c8y-switch c8y-switch--inline\"\n      [title]=\"'Search only within the current group or asset hierarchy' | translate\"\n    >\n      <input\n        [attr.aria-label]=\"'Search only within the current group or asset hierarchy' | translate\"\n        type=\"checkbox\"\n        [ngModel]=\"isOnlyHierarchyQuery\"\n        (ngModelChange)=\"onHierarchyQueryChange($event)\"\n      />\n      <span></span>\n    </label>\n  </div>\n}\n", dependencies: [{ kind: "component", type: TabsOutletComponent, selector: "c8y-tabs-outlet,c8y-ui-tabs", inputs: ["tabs", "orientation", "navigatorOpen", "outletName", "context", "openFirstTab", "hasHeader"] }, { kind: "component", type: TabComponent, selector: "c8y-tab", inputs: ["path", "label", "icon", "priority", "orientation", "injector", "tabsOutlet", "isActive", "text", "showAlways"], outputs: ["onSelect"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SearchCustomFiltersComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-search-custom-filters', imports: [C8yTranslatePipe, TabsOutletComponent, TabComponent, AsyncPipe, FormsModule], template: "<div class=\"d-flex gap-16 p-l-4 p-l-24 p-r-24\">\n  @if (!useTabs) {\n    <div class=\"p-b-8 separator-bottom sticky-top p-t-4\">\n      @for (checkbox of checkboxesState; track $index) {\n        <label class=\"c8y-checkbox\">\n          <input\n            type=\"checkbox\"\n            [checked]=\"checkbox.value\"\n            [indeterminate]=\"checkbox.indeterminate\"\n            (click)=\"onCheckboxChange($event, checkbox)\"\n            [attr.disabled]=\"checkbox.isDisabled ? true : null\"\n          />\n          <span></span>\n          <span>{{ checkbox.label | translate }}</span>\n        </label>\n      }\n    </div>\n  }\n</div>\n\n@if (useTabs) {\n  <c8y-tabs-outlet\n    class=\"elevation-none\"\n    outletName=\"searchTabs\"\n    orientation=\"horizontal\"\n  ></c8y-tabs-outlet>\n}\n\n<c8y-tab\n  [icon]=\"'asterisk-key'\"\n  [title]=\"'All devices, assets and groups' | translate\"\n  [isActive]=\"selectedTab === tabNames.all\"\n  [tabsOutlet]=\"'searchTabs'\"\n  [label]=\"tabNames.all | translate\"\n  [priority]=\"1000\"\n  (onSelect)=\"onTabChange(tabNames.all)\"\n></c8y-tab>\n<c8y-tab\n  [icon]=\"'exchange'\"\n  [title]=\"'Devices only' | translate\"\n  [isActive]=\"selectedTab === tabNames.devices\"\n  [tabsOutlet]=\"'searchTabs'\"\n  [label]=\"tabNames.devices | translate\"\n  [priority]=\"750\"\n  (onSelect)=\"onTabChange(tabNames.devices)\"\n></c8y-tab>\n<c8y-tab\n  [icon]=\"'c8y-modules'\"\n  [title]=\"'Assets and groups only' | translate\"\n  [isActive]=\"selectedTab === tabNames.groupsAndAssets\"\n  [tabsOutlet]=\"'searchTabs'\"\n  [label]=\"tabNames.groupsAndAssets | translate\"\n  [priority]=\"500\"\n  (onSelect)=\"onTabChange(tabNames.groupsAndAssets)\"\n></c8y-tab>\n\n@if (useTabs && (context$ | async)?.contextData?.name) {\n  <div class=\"p-l-48 p-t-8 d-flex a-i-center\">\n    <span translate>Search only in`specified group or asset`</span>\n    <span class=\"text-bold p-l-4\">{{ (context$ | async)?.contextData?.name }}</span>\n    <label\n      class=\"m-l-8 c8y-switch c8y-switch--inline\"\n      [title]=\"'Search only within the current group or asset hierarchy' | translate\"\n    >\n      <input\n        [attr.aria-label]=\"'Search only within the current group or asset hierarchy' | translate\"\n        type=\"checkbox\"\n        [ngModel]=\"isOnlyHierarchyQuery\"\n        (ngModelChange)=\"onHierarchyQueryChange($event)\"\n      />\n      <span></span>\n    </label>\n  </div>\n}\n" }]
        }], propDecorators: { useTabs: [{
                type: Input
            }], customDataQuery: [{
                type: Output
            }], refresh: [{
                type: Output
            }], isOnlyHierarchyQuery: [{
                type: Input
            }], isOnlyHierarchyQueryChange: [{
                type: Output
            }] } });

class SearchActionComponent {
    constructor() {
        this.typeaheadReload = new EventEmitter();
        this.previewService = inject(PreviewService);
        this.isWildcardSearchEnabled$ = this.previewService
            .getState$(WILDCARD_SEARCH_FEATURE_KEY)
            .pipe(catchError(() => of(true)));
        this.c8yRouter = inject(RouterService);
        this.router = inject(Router);
        this.moduleConfig = inject(SEARCH_CONFIG, { optional: true });
        this.isOnlyHierarchyQuery = false;
        this.showAdvancedFilters = this.moduleConfig?.showAdvancedFilters ?? true;
        this.customPlaceholder = this.moduleConfig?.placeholder;
    }
    triggerDataLoad() {
        this.typeaheadReload.next(null);
    }
    onOpenChange(isOpen) {
        if (isOpen) {
            this.triggerDataLoad();
        }
    }
    async onSearch(on) {
        if (await lastValueFrom(this.isWildcardSearchEnabled$)) {
            return;
        }
        this.navigate(['/assetsearch'], {
            queryParams: { search: on },
            replaceUrl: true
        });
    }
    onFilter(on) {
        this.navigate(['/assetsearch'], {
            queryParams: { filter: on },
            replaceUrl: true
        });
    }
    onClick(mo) {
        this.router.navigateByUrl(this.c8yRouter.getHref(mo, '/'));
    }
    navigate(commands, extras) {
        this.router
            .navigateByUrl('/', { skipLocationChange: true })
            .then(() => this.router.navigate(commands, extras));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SearchActionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SearchActionComponent, isStandalone: true, selector: "c8y-search-action", ngImport: i0, template: "<c8y-search-input\n  #input\n  (filter)=\"onFilter($event)\"\n  (search)=\"onSearch($event)\"\n  (onClick)=\"onClick($event)\"\n  (onOpenToggle)=\"onOpenChange($event)\"\n  [enableCustomTemplatePlaceholder]=\"true\"\n  [customPlaceholder]=\"customPlaceholder\"\n  [customDataQuery]=\"customQuery\"\n  [externalTerm]=\"typeaheadReload\"\n  [mode]=\"(isWildcardSearchEnabled$ | async) ? 'wildcardsearch' : 'search'\"\n>\n  <c8y-search-custom-filters\n    *ngIf=\"showAdvancedFilters && input.term.length > 0\"\n    (refresh)=\"triggerDataLoad()\"\n    [useTabs]=\"isWildcardSearchEnabled$ | async\"\n    [(isOnlyHierarchyQuery)]=\"isOnlyHierarchyQuery\"\n    (customDataQuery)=\"customQuery = $event\"\n  ></c8y-search-custom-filters>\n</c8y-search-input>\n", dependencies: [{ kind: "component", type: SearchInputComponent, selector: "c8y-search-input", inputs: ["mode", "enableCustomTemplatePlaceholder", "customPlaceholder", "externalTerm", "customDataQuery", "container", "groupsOnly"], outputs: ["filter", "search", "reset", "onClick", "onOpenToggle"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: SearchCustomFiltersComponent, selector: "c8y-search-custom-filters", inputs: ["useTabs", "isOnlyHierarchyQuery"], outputs: ["customDataQuery", "refresh", "isOnlyHierarchyQueryChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SearchActionComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-search-action', imports: [SearchInputComponent, NgIf, SearchCustomFiltersComponent, AsyncPipe], template: "<c8y-search-input\n  #input\n  (filter)=\"onFilter($event)\"\n  (search)=\"onSearch($event)\"\n  (onClick)=\"onClick($event)\"\n  (onOpenToggle)=\"onOpenChange($event)\"\n  [enableCustomTemplatePlaceholder]=\"true\"\n  [customPlaceholder]=\"customPlaceholder\"\n  [customDataQuery]=\"customQuery\"\n  [externalTerm]=\"typeaheadReload\"\n  [mode]=\"(isWildcardSearchEnabled$ | async) ? 'wildcardsearch' : 'search'\"\n>\n  <c8y-search-custom-filters\n    *ngIf=\"showAdvancedFilters && input.term.length > 0\"\n    (refresh)=\"triggerDataLoad()\"\n    [useTabs]=\"isWildcardSearchEnabled$ | async\"\n    [(isOnlyHierarchyQuery)]=\"isOnlyHierarchyQuery\"\n    (customDataQuery)=\"customQuery = $event\"\n  ></c8y-search-custom-filters>\n</c8y-search-input>\n" }]
        }], ctorParameters: () => [] });

class AssetTypeSearchGridColumn extends AssetTypeGridColumn {
    constructor(hideExtendedFilters, initialColumnConfig, assetSearchService, customPlaceholder) {
        super(initialColumnConfig);
        this.filterable = true;
        this.filteringConfig = this.getFilteringConfig(hideExtendedFilters, assetSearchService, customPlaceholder);
    }
    getFilteringConfig(hideExtendedFilters, assetSearchService, customPlaceholder) {
        return {
            fields: [
                ...getBasicInputArrayFormFieldConfig({
                    key: 'types',
                    label: gettext('Show items with type'),
                    addText: gettext('Add next`type`'),
                    tooltip: gettext('Use * as a wildcard character'),
                    placeholder: customPlaceholder ? customPlaceholder : gettext('building`e.g. house`'),
                    optional: !hideExtendedFilters
                }),
                {
                    key: SearchFilters.ALL_FILTERS,
                    type: 'checkbox',
                    hide: hideExtendedFilters,
                    props: {
                        indeterminate: false,
                        disabled: false,
                        label: gettext('All'),
                        click: (field, clickEvent) => {
                            const { checked } = clickEvent.target;
                            // Handle checked state
                            if (checked) {
                                field.form.get(SearchFilters.ONLY_DEVICES).setValue(true);
                                field.form.get(SearchFilters.ONLY_GROUPS_AND_ASSETS).setValue(true);
                                // Emit new state
                                assetSearchService.appliedFilters$.next({
                                    [SearchFilters.ALL_FILTERS]: checked,
                                    [SearchFilters.ONLY_DEVICES]: true,
                                    [SearchFilters.ONLY_GROUPS_AND_ASSETS]: true,
                                    [SearchFilters.CURRENT_HIERARCHY]: null
                                });
                            }
                        }
                    },
                    expressionProperties: {
                        'props.indeterminate': (model, formState, field) => {
                            // Do nothing
                            if (field.form.get(SearchFilters.ALL_FILTERS).value === true) {
                                return;
                            }
                            // Set indeterminate state
                            if (!field.form.get(SearchFilters.ONLY_DEVICES).value ||
                                !field.form.get(SearchFilters.ONLY_GROUPS_AND_ASSETS).value) {
                                field.form.get(SearchFilters.ALL_FILTERS).setValue(null);
                                return true;
                            }
                            return false;
                        },
                        'props.disabled': (model, formState, field) => {
                            if (field.form.get(SearchFilters.ALL_FILTERS).value === true) {
                                return true;
                            }
                            return false;
                        }
                    },
                    hooks: {
                        onInit: field => {
                            // Get initial state
                            const { allFilters } = assetSearchService?.appliedFilters$?.value;
                            field.formControl.setValue(allFilters);
                        }
                    }
                },
                {
                    key: SearchFilters.ONLY_DEVICES,
                    type: 'checkbox',
                    hide: hideExtendedFilters,
                    props: {
                        indeterminate: false,
                        label: gettext('Show only devices'),
                        click: (field, clickEvent) => {
                            const oldFilterValue = assetSearchService.appliedFilters$.value;
                            const { checked } = clickEvent.target;
                            // Handle checked state
                            if (checked) {
                                field.form.get(SearchFilters.ALL_FILTERS).setValue(true);
                                // Emit new state
                                assetSearchService.appliedFilters$.next({
                                    ...oldFilterValue,
                                    [SearchFilters.ALL_FILTERS]: true,
                                    [SearchFilters.ONLY_DEVICES]: checked
                                });
                                return;
                            }
                            // Handle unchecked state
                            field.form.get(SearchFilters.ALL_FILTERS).setValue(null); // Trigger indeterminate state
                            field.form.get(SearchFilters.ONLY_GROUPS_AND_ASSETS).setValue(true);
                            // Emit new state
                            assetSearchService.appliedFilters$.next({
                                [SearchFilters.ALL_FILTERS]: null,
                                [SearchFilters.ONLY_GROUPS_AND_ASSETS]: true,
                                [SearchFilters.ONLY_DEVICES]: checked,
                                [SearchFilters.CURRENT_HIERARCHY]: null
                            });
                        }
                    },
                    hooks: {
                        onInit: field => {
                            // Get initial state
                            const { onlyDevices } = assetSearchService?.appliedFilters$?.value;
                            field.formControl.setValue(onlyDevices);
                        }
                    }
                },
                {
                    key: SearchFilters.ONLY_GROUPS_AND_ASSETS,
                    type: 'checkbox',
                    hide: hideExtendedFilters,
                    props: {
                        indeterminate: false,
                        label: gettext('Show only groups and assets'),
                        click: (field, clickEvent) => {
                            const oldFilterValue = assetSearchService.appliedFilters$.value;
                            const { checked } = clickEvent.target;
                            // Handle checked state
                            if (checked) {
                                field.form.get(SearchFilters.ALL_FILTERS).setValue(true);
                                // Emit new state
                                assetSearchService.appliedFilters$.next({
                                    ...oldFilterValue,
                                    [SearchFilters.ALL_FILTERS]: true,
                                    [SearchFilters.ONLY_GROUPS_AND_ASSETS]: checked
                                });
                                return;
                            }
                            // Handle unchecked state
                            field.form.get(SearchFilters.ALL_FILTERS).setValue(null); // Trigger indeterminate state
                            field.form.get(SearchFilters.ONLY_DEVICES).setValue(true);
                            // Emit new state
                            assetSearchService.appliedFilters$.next({
                                [SearchFilters.ALL_FILTERS]: null,
                                [SearchFilters.ONLY_GROUPS_AND_ASSETS]: checked,
                                [SearchFilters.ONLY_DEVICES]: true,
                                [SearchFilters.CURRENT_HIERARCHY]: false
                            });
                        }
                    },
                    hooks: {
                        onInit: field => {
                            // Get initial state
                            const { onlyGroupsAndAssets } = assetSearchService?.appliedFilters$?.value;
                            field.formControl.setValue(onlyGroupsAndAssets);
                        }
                    }
                }
            ],
            /**
             * Adding devices and groups to a filter is already handled in {@link AssetSearchService#buildSearchQuery}
             * */
            getFilter(model) {
                const filter = {};
                const ors = [];
                if (model.types?.length) {
                    ors.push({ type: { __in: model.types } });
                }
                if (ors.length) {
                    filter.__or = ors;
                }
                return filter;
            }
        };
    }
}

class SearchGridComponent {
    constructor() {
        this.title = '';
        this.loadingItemsLabel = gettext('Loading results…');
        this.selectable = false;
        this.onColumnsChange = new EventEmitter();
        this.searchText = '';
        this.moduleConfig = inject(SEARCH_CONFIG, { optional: true });
        this.showAdvancedFilters = this.moduleConfig?.showAdvancedFilters ?? false;
        this.customPlaceholder = this.moduleConfig?.placeholder ?? undefined;
        this.assetSearchService = inject(AssetSearchService);
        this.pagination = this.assetSearchService.getDefaultPagination();
        this.bulkActionControls = this.assetSearchService.getDefaultBulkActionControls();
        this.refresh = new EventEmitter();
        this.previewService = inject(PreviewService);
        this.isWildcardSearchEnabled$ = this.previewService
            .getState$(WILDCARD_SEARCH_FEATURE_KEY)
            .pipe(catchError(() => of(true)));
        this.wildcardSearchTitle = gettext('Asset data');
        this.fullTextSearchTitle = gettext('Search results');
        this.sizeCount = 0;
        this.bsModalService = inject(BsModalService);
        this.smartGroupsService = inject(SmartGroupsService);
        this.subAssetsGridService = inject(SubAssetsService);
    }
    set _columns(value) {
        if (value) {
            this.columns = value;
        }
        else {
            this.columns = this.assetSearchService.getDefaultColumns();
        }
    }
    set _pagination(value) {
        if (value) {
            this.pagination = value;
        }
    }
    set _actionControls(value) {
        if (value) {
            this.actionControls = value;
        }
        else {
            this.actionControls = this.assetSearchService.getDefaultActionControls();
        }
    }
    set _bulkActionControls(value) {
        if (value) {
            this.bulkActionControls = value;
        }
        else {
            this.bulkActionControls = this.assetSearchService.getDefaultBulkActionControls();
        }
    }
    getGridConfigContext() {
        return { key: this.columnsConfigKey || this.assetSearchService.GRID_CONFIG_STORAGE_KEY };
    }
    ngOnInit() {
        if (!this.filteringName) {
            this.columns = [
                new AssetTypeSearchGridColumn(this.showAdvancedFilters, { sortOrder: 'desc' }, this.assetSearchService, this.customPlaceholder),
                ...this.assetSearchService.getDefaultColumns()
            ];
        }
        else {
            this.columns = [
                new AssetTypeSearchGridColumn(this.showAdvancedFilters, { sortOrder: 'desc' }, this.assetSearchService),
                new NameDeviceGridColumn({
                    sortOrder: 'asc',
                    filter: { externalFilterQuery: { names: [this.filteringName] } }
                }),
                new ModelDeviceGridColumn(),
                new SerialNumberDeviceGridColumn({ visible: false }),
                new RegistrationDateDeviceGridColumn({ visible: false }),
                new SystemIdDeviceGridColumn({ visible: false }),
                new ImeiDeviceGridColumn({ visible: false }),
                new AlarmsDeviceGridColumn()
            ];
        }
        this.serverSideDataCallback = this.onDataSourceModifier.bind(this);
        this.setActionControls();
    }
    ngAfterViewInit() {
        this.setInitialFilterForTypeColumn();
    }
    trackByName(_index, column) {
        return column.name;
    }
    async onDataSourceModifier(dataSourceModifier) {
        const response = await this.assetSearchService.getData(dataSourceModifier.columns, dataSourceModifier.pagination, dataSourceModifier.searchText);
        const { res, data, paging } = response;
        if (paging.currentPage === 1) {
            this.sizeCount = 0;
        }
        this.sizeCount += data.length;
        this.onColumnsChange.emit(dataSourceModifier.columns);
        return {
            res,
            data,
            paging,
            filteredSize: this.sizeCount,
            size: undefined
        };
    }
    setActionControls() {
        const actionControls = [];
        const deleteAction = {
            type: BuiltInActionType.Delete,
            callback: (asset) => this.onDeleteAsset(asset, this.parentGroup)
        };
        actionControls.push(deleteAction);
        if (!this.actionControls) {
            this.actionControls = actionControls;
        }
    }
    updateFiltering(columnNames, action) {
        const { type } = action;
        if (type === FilteringActionType.ResetFilter) {
            this.dataGrid.clearFilters();
        }
        else {
            /**
             * TODO: find better solution. After new changes from DM team, we're running into race condition where
             * this.dataGrid.updateFiltering is executed before this.configurationStrategy.getConfig$() value is emitted.
             * Columns setter sets columns after this.dataGrid.updateFiltering executes its logic. Value of this.columns in
             * dataGrid.updateFiltering is just not yet set.
             */
            setTimeout(() => {
                this.dataGrid.updateFiltering(columnNames, action, false);
            }, 500);
        }
    }
    onColumnFilterReset(column) {
        if (column.name === 'type') {
            this.assetSearchService.resetAppliedFilters();
        }
    }
    onDeleteAsset(asset, parentRef) {
        const initialState = {
            showWithDeviceUserCheckbox: this.subAssetsGridService.shouldShowWithDeviceUserCheckbox(asset),
            asset,
            showWithCascadeCheckbox: !this.smartGroupsService.isSmartGroup(asset)
        };
        const modalRef = this.bsModalService.show(DeleteAssetsModalComponent, { initialState });
        modalRef.content.closeSubject.subscribe(async (result) => {
            if (result) {
                await this.subAssetsGridService.deleteAsset(asset, parentRef, result);
                this.refresh.emit();
            }
        });
    }
    setInitialFilterForTypeColumn() {
        const checkboxes = this.assetSearchService.appliedFilters$.value;
        // Set filter only when all checkboxes are not selected
        if (checkboxes[SearchFilters.ONLY_DEVICES] !== checkboxes[SearchFilters.ONLY_GROUPS_AND_ASSETS]) {
            const externalFilterQuery = {
                [SearchFilters.ONLY_DEVICES]: checkboxes[SearchFilters.ONLY_DEVICES],
                [SearchFilters.ONLY_GROUPS_AND_ASSETS]: checkboxes[SearchFilters.ONLY_GROUPS_AND_ASSETS]
            };
            this.updateFiltering(['type'], {
                type: FilteringActionType.ApplyFilter,
                payload: {
                    filteringModifier: {
                        externalFilterQuery
                    }
                }
            });
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SearchGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SearchGridComponent, isStandalone: true, selector: "c8y-search-grid", inputs: { parentGroup: ["parent-group", "parentGroup"], title: "title", loadingItemsLabel: "loadingItemsLabel", _columns: ["columns", "_columns"], _pagination: ["pagination", "_pagination"], _actionControls: ["actionControls", "_actionControls"], selectable: "selectable", _bulkActionControls: ["bulkActionControls", "_bulkActionControls"], searchText: "searchText", filteringName: "filteringName", columnsConfigKey: "columnsConfigKey" }, outputs: { onColumnsChange: "onColumnsChange" }, providers: [
            {
                provide: DATA_GRID_CONFIGURATION_STRATEGY,
                useClass: UserPreferencesConfigurationStrategy
            },
            {
                provide: DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER,
                useExisting: SearchGridComponent
            }
        ], viewQueries: [{ propertyName: "dataGrid", first: true, predicate: DataGridComponent, descendants: true, static: true }], ngImport: i0, template: "<div class=\"card--grid--fullpage border-top border-bottom\">\n  <c8y-data-grid\n    [title]=\"\n      ((isWildcardSearchEnabled$ | async) ? wildcardSearchTitle : fullTextSearchTitle) | translate\n    \"\n    [loadingItemsLabel]=\"loadingItemsLabel\"\n    [columns]=\"columns\"\n    [pagination]=\"pagination\"\n    [actionControls]=\"actionControls\"\n    [selectable]=\"selectable\"\n    [bulkActionControls]=\"bulkActionControls\"\n    [serverSideDataCallback]=\"serverSideDataCallback\"\n    [infiniteScroll]=\"'auto'\"\n    [showSearch]=\"true\"\n    [searchText]=\"searchText\"\n    [refresh]=\"refresh\"\n    (onColumnFilterReset)=\"onColumnFilterReset($event)\"\n  >\n    <ng-container *ngFor=\"let column of columns; trackBy: trackByName\">\n      <c8y-column [name]=\"column.name\"></c8y-column>\n    </ng-container>\n\n    <c8y-ui-empty-state\n      [icon]=\"'search'\"\n      [title]=\"'No results to display.' | translate\"\n      [subtitle]=\"'Refine your search terms or check your spelling.' | translate\"\n      [horizontal]=\"true\"\n    ></c8y-ui-empty-state>\n  </c8y-data-grid>\n</div>\n", dependencies: [{ kind: "component", type: DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "childNodePagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows", "treeGrid", "hideReload", "childNodesProperty", "parentNodeLabelProperty"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: ColumnDirective, selector: "c8y-column", inputs: ["name"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SearchGridComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-search-grid', providers: [
                        {
                            provide: DATA_GRID_CONFIGURATION_STRATEGY,
                            useClass: UserPreferencesConfigurationStrategy
                        },
                        {
                            provide: DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER,
                            useExisting: SearchGridComponent
                        }
                    ], imports: [
                        DataGridComponent,
                        NgFor,
                        ColumnDirective,
                        EmptyStateComponent,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<div class=\"card--grid--fullpage border-top border-bottom\">\n  <c8y-data-grid\n    [title]=\"\n      ((isWildcardSearchEnabled$ | async) ? wildcardSearchTitle : fullTextSearchTitle) | translate\n    \"\n    [loadingItemsLabel]=\"loadingItemsLabel\"\n    [columns]=\"columns\"\n    [pagination]=\"pagination\"\n    [actionControls]=\"actionControls\"\n    [selectable]=\"selectable\"\n    [bulkActionControls]=\"bulkActionControls\"\n    [serverSideDataCallback]=\"serverSideDataCallback\"\n    [infiniteScroll]=\"'auto'\"\n    [showSearch]=\"true\"\n    [searchText]=\"searchText\"\n    [refresh]=\"refresh\"\n    (onColumnFilterReset)=\"onColumnFilterReset($event)\"\n  >\n    <ng-container *ngFor=\"let column of columns; trackBy: trackByName\">\n      <c8y-column [name]=\"column.name\"></c8y-column>\n    </ng-container>\n\n    <c8y-ui-empty-state\n      [icon]=\"'search'\"\n      [title]=\"'No results to display.' | translate\"\n      [subtitle]=\"'Refine your search terms or check your spelling.' | translate\"\n      [horizontal]=\"true\"\n    ></c8y-ui-empty-state>\n  </c8y-data-grid>\n</div>\n" }]
        }], propDecorators: { parentGroup: [{
                type: Input,
                args: ['parent-group']
            }], title: [{
                type: Input
            }], loadingItemsLabel: [{
                type: Input
            }], _columns: [{
                type: Input,
                args: ['columns']
            }], _pagination: [{
                type: Input,
                args: ['pagination']
            }], _actionControls: [{
                type: Input,
                args: ['actionControls']
            }], selectable: [{
                type: Input
            }], _bulkActionControls: [{
                type: Input,
                args: ['bulkActionControls']
            }], onColumnsChange: [{
                type: Output
            }], searchText: [{
                type: Input
            }], filteringName: [{
                type: Input
            }], columnsConfigKey: [{
                type: Input
            }], dataGrid: [{
                type: ViewChild,
                args: [DataGridComponent, { static: true }]
            }] } });

class SearchResultsComponent {
    constructor(route, alert) {
        this.route = route;
        this.alert = alert;
        this.filter = '';
        this.searchText = '';
        this.previewService = inject(PreviewService);
        this.isWildcardSearchEnabled$ = this.previewService
            .getState$(WILDCARD_SEARCH_FEATURE_KEY)
            .pipe(catchError$1(() => of(true)));
        this.WARNING_TIMEOUT_TIME = 3000;
        this.unsubscribe$ = new Subject();
    }
    ngOnInit() {
        this.route.queryParams.pipe(takeUntil(this.unsubscribe$)).subscribe(params => {
            if (params.filter) {
                this.filteringName = params.filter;
            }
        });
    }
    ngAfterViewInit() {
        this.route.queryParams
            .pipe(takeUntil(this.unsubscribe$))
            .subscribe(({ filter, search }) => this.onQueryParamsChange(filter, search));
    }
    resetSearch() {
        if (this.searchGrid.dataGrid.searchText) {
            this.alert.add({
                text: gettext('Search reset. Full text search does not support filtering.'),
                type: Status.WARNING,
                timeout: this.WARNING_TIMEOUT_TIME
            });
            this.searchText = '';
            this.searchGrid.dataGrid.searchText = '';
        }
    }
    resetFilter() {
        this.filter = '';
        if (this.searchGrid.dataGrid.filteringApplied) {
            this.alert.add({
                text: gettext('Filter reset. Full text search does not support filtering.'),
                type: Status.WARNING,
                timeout: this.WARNING_TIMEOUT_TIME
            });
            this.searchGrid.dataGrid.clearFilters(false);
        }
    }
    ngOnDestroy() {
        this.unsubscribe$.next();
        this.unsubscribe$.complete();
    }
    onQueryParamsChange(filter, searchTerm) {
        if (!this.shouldFilter(filter) && searchTerm) {
            this.searchText = searchTerm || '';
        }
    }
    shouldFilter(filter) {
        if (!filter) {
            return false;
        }
        this.resetSearch();
        this.filter = filter || '';
        this.searchGrid.updateFiltering(['name'], {
            type: FilteringActionType.ApplyFilter,
            payload: {
                filteringModifier: {
                    externalFilterQuery: {
                        names: [this.filter]
                    }
                }
            }
        });
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SearchResultsComponent, deps: [{ token: i1$1.ActivatedRoute }, { token: i2.AlertService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SearchResultsComponent, isStandalone: true, selector: "c8y-search-results", viewQueries: [{ propertyName: "searchGrid", first: true, predicate: SearchGridComponent, descendants: true, static: true }], ngImport: i0, template: "<c8y-title *ngIf=\"isWildcardSearchEnabled$ | async\">\n  <span\n    class=\"p-r-4\"\n    translate\n  >\n    Search\n  </span>\n  <small\n    ngNonBindable\n    translate\n    *ngIf=\"searchText\"\n    [translateParams]=\"{\n      searchHint: searchText\n    }\"\n  >\n    searching \"{{ searchHint }}\"\n  </small>\n  <small\n    ngNonBindable\n    translate\n    *ngIf=\"filter\"\n    [translateParams]=\"{\n      filterHint: filter\n    }\"\n  >\n    filtered by \"{{ filterHint }}\"\n  </small>\n</c8y-title>\n\n<c8y-title\n  *ngIf=\"isWildcardSearchEnabled$ | async\"\n  translate\n>\n  Asset table\n</c8y-title>\n\n<c8y-search-grid\n  [searchText]=\"searchText\"\n  [filteringName]=\"filteringName\"\n></c8y-search-grid>\n", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: SearchGridComponent, selector: "c8y-search-grid", inputs: ["parent-group", "title", "loadingItemsLabel", "columns", "pagination", "actionControls", "selectable", "bulkActionControls", "searchText", "filteringName", "columnsConfigKey"], outputs: ["onColumnsChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SearchResultsComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-search-results', imports: [TitleComponent, C8yTranslateDirective, NgIf, SearchGridComponent, AsyncPipe], template: "<c8y-title *ngIf=\"isWildcardSearchEnabled$ | async\">\n  <span\n    class=\"p-r-4\"\n    translate\n  >\n    Search\n  </span>\n  <small\n    ngNonBindable\n    translate\n    *ngIf=\"searchText\"\n    [translateParams]=\"{\n      searchHint: searchText\n    }\"\n  >\n    searching \"{{ searchHint }}\"\n  </small>\n  <small\n    ngNonBindable\n    translate\n    *ngIf=\"filter\"\n    [translateParams]=\"{\n      filterHint: filter\n    }\"\n  >\n    filtered by \"{{ filterHint }}\"\n  </small>\n</c8y-title>\n\n<c8y-title\n  *ngIf=\"isWildcardSearchEnabled$ | async\"\n  translate\n>\n  Asset table\n</c8y-title>\n\n<c8y-search-grid\n  [searchText]=\"searchText\"\n  [filteringName]=\"filteringName\"\n></c8y-search-grid>\n" }]
        }], ctorParameters: () => [{ type: i1$1.ActivatedRoute }, { type: i2.AlertService }], propDecorators: { searchGrid: [{
                type: ViewChild,
                args: [SearchGridComponent, { static: true }]
            }] } });

class SearchModule {
    static config(config = {}) {
        return {
            ngModule: SearchModule,
            providers: [
                {
                    provide: SEARCH_CONFIG,
                    useValue: config
                }
            ]
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SearchModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: SearchModule, imports: [CoreModule,
            DeviceGridModule,
            CoreSearchModule,
            AssetTypeCellRendererComponent,
            SearchResultsComponent,
            SearchGridComponent,
            SearchActionComponent,
            SearchCustomFiltersComponent], exports: [SearchResultsComponent, SearchGridComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SearchModule, providers: [
            AssetSearchService,
            hookRoute({
                path: 'assetsearch',
                component: SearchResultsComponent
            }),
            hookSearch({
                template: SearchActionComponent,
                onSearch: undefined
            })
        ], imports: [CoreModule,
            DeviceGridModule,
            CoreSearchModule,
            AssetTypeCellRendererComponent,
            SearchResultsComponent,
            SearchGridComponent,
            SearchActionComponent,
            SearchCustomFiltersComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SearchModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        CoreModule,
                        DeviceGridModule,
                        CoreSearchModule,
                        AssetTypeCellRendererComponent,
                        SearchResultsComponent,
                        SearchGridComponent,
                        SearchActionComponent,
                        SearchCustomFiltersComponent
                    ],
                    exports: [SearchResultsComponent, SearchGridComponent],
                    providers: [
                        AssetSearchService,
                        hookRoute({
                            path: 'assetsearch',
                            component: SearchResultsComponent
                        }),
                        hookSearch({
                            template: SearchActionComponent,
                            onSearch: undefined
                        })
                    ]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { AssetSearchService, AssetTypeSearchGridColumn, SearchCustomFiltersComponent, SearchGridComponent, SearchModule, SearchResultsComponent };
//# sourceMappingURL=c8y-ngx-components-search.mjs.map