import * as i0 from '@angular/core';
import { Component, Input, Inject, ViewChild, Optional } from '@angular/core';
import * as i4 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i1 from '@c8y/client';
import * as i2 from '@c8y/ngx-components';
import { C8yTranslateDirective, DatePipe, LoadingComponent, gettext, CommonModule as CommonModule$1, FormsModule as FormsModule$1, AssetLinkPipe, DismissAlertStrategy, DynamicComponentAlert } from '@c8y/ngx-components';
import * as i5 from '@angular/forms';
import { FormsModule, ControlContainer, NgForm } from '@angular/forms';
import * as i1$1 from '@c8y/ngx-components/map';
import { MAP_DEFAULT_CONFIG, MapComponent, MapModule, ClusterMapComponent } from '@c8y/ngx-components/map';
import * as i3 from '@ngx-translate/core';
import * as i8 from 'rxjs';
import { Subject } from 'rxjs';
import { takeUntil, filter } from 'rxjs/operators';
import * as i6 from '@c8y/ngx-components/icon-selector';
import { IconSelectorModule } from '@c8y/ngx-components/icon-selector';
import * as i7 from 'ngx-bootstrap/tooltip';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import * as i2$1 from '@c8y/ngx-components/context-dashboard';
import { RouterLink } from '@angular/router';

class MapEventInfoComponent {
    constructor(eventService) {
        this.eventService = eventService;
        this.loading = true;
    }
    async ngOnChanges() {
        this.loading = true;
        const { data } = await this.eventService.list({
            dateFrom: '1970-01-01',
            dateTo: new Date(Date.now()).toISOString(),
            fragmentType: 'c8y_Position',
            pageSize: 1,
            source: this.asset.id
        });
        this.event = data[0];
        this.loading = false;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MapEventInfoComponent, deps: [{ token: i1.EventService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MapEventInfoComponent, isStandalone: true, selector: "c8y-map-event-info", inputs: { asset: "asset" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"text-muted text-10 p-t-4 p-b-4\">\n  <span translate>Last position update:</span>\n  <br />\n  <c8y-loading *ngIf=\"loading\"></c8y-loading>\n  <ng-container *ngIf=\"!loading\">\n    <i *ngIf=\"!event\" translate>No information found</i>\n    <ng-container *ngIf=\"event\">\n      <i>{{ event.time | c8yDate }}</i>\n      <ng-content></ng-content>\n    </ng-container>\n  </ng-container>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MapEventInfoComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-map-event-info', standalone: true, imports: [CommonModule, C8yTranslateDirective, DatePipe, LoadingComponent], template: "<div class=\"text-muted text-10 p-t-4 p-b-4\">\n  <span translate>Last position update:</span>\n  <br />\n  <c8y-loading *ngIf=\"loading\"></c8y-loading>\n  <ng-container *ngIf=\"!loading\">\n    <i *ngIf=\"!event\" translate>No information found</i>\n    <ng-container *ngIf=\"event\">\n      <i>{{ event.time | c8yDate }}</i>\n      <ng-content></ng-content>\n    </ng-container>\n  </ng-container>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1.EventService }], propDecorators: { asset: [{
                type: Input
            }] } });

class MapWidgetConfigComponent {
    constructor(mapService, alertService, translateService, defaultMapConfig) {
        this.mapService = mapService;
        this.alertService = alertService;
        this.translateService = translateService;
        this.defaultMapConfig = defaultMapConfig;
        this.config = {
            mapConfig: undefined
        };
        this.canAutoCenter = true;
        this.isPositionedDevice = false;
        this.refreshOption = 'none';
        this.destroyed$ = new Subject();
        // JS precision for floating point number is 15 for 64-bit and because of this provided to leaflet are recalculated
        // to values almost-like provided (e.g. 0 is recalculated to 1.46e-14; for 180 it's 180.00000000000003).
        // To ensure provided value has no floating point error, number needs to be rounded to fixed point 13.
        this.FIXED_POINT_DIGITS = 13;
    }
    ngOnDestroy() {
        this.destroyed$.next();
    }
    ngOnInit() {
        this.defaultMapConfig.pipe(takeUntil(this.destroyed$)).subscribe(defaultConfig => {
            this.formConfig = {
                zoomLevel: defaultConfig.zoomLevel,
                center: defaultConfig.center
            };
            this.initForm();
        });
    }
    async initForm() {
        if (!this.config.mapConfig) {
            this.config.mapConfig = this.formConfig;
        }
        this.formConfig = {
            ...this.formConfig,
            ...this.config.mapConfig,
            disablePan: false
        };
        await this.updateAsset();
    }
    async ngOnChanges(changes) {
        if (changes.config.currentValue !== changes.config.previousValue &&
            !changes.config.firstChange) {
            await this.updateAsset();
        }
    }
    previewMapInit(leaflet) {
        this.leaflet = leaflet;
        this.addCenterIcon(this.formConfig.center[0], this.formConfig.center[1]);
    }
    onBeforeSave() {
        this.config.mapConfig = this.formConfig;
        return true;
    }
    zoomLevelChanged() {
        this.config.mapConfig = {
            ...this.config.mapConfig,
            zoomLevel: this.formConfig.zoomLevel
        };
    }
    changeCenter() {
        if (this.centerIcon) {
            this.centerIcon.remove();
        }
        this.config.mapConfig = { ...this.formConfig, center: [...this.formConfig.center] };
        this.addCenterIcon(this.formConfig.center[0], this.formConfig.center[1]);
    }
    changeCenterOnEnterKey(event) {
        event.preventDefault();
        this.changeCenter();
    }
    onPreviewZoomStart() {
        this.centerIcon.remove();
    }
    onPreviewZoomEnd(event) {
        this.formConfig.zoomLevel = Math.floor(event.target.getZoom());
    }
    onPreviewMapMove(event) {
        if (this.centerIcon) {
            this.centerIcon.remove();
        }
        const { lat, lng } = event.target.getCenter();
        const fixedLat = +lat.toFixed(this.FIXED_POINT_DIGITS);
        const fixedLng = +lng.toFixed(this.FIXED_POINT_DIGITS);
        this.addCenterIcon(fixedLat, fixedLng);
        this.formConfig.center = [fixedLat, fixedLng];
    }
    useOwnPosition() {
        navigator.geolocation.getCurrentPosition(({ coords }) => {
            this.formConfig.center = [coords.latitude, coords.longitude];
            this.changeCenter();
        });
    }
    centerToAsset() {
        this.formConfig.center = [
            this.config.device.c8y_Position.lat,
            this.config.device.c8y_Position.lng
        ];
        this.changeCenter();
    }
    updateRefreshOption() {
        this.formConfig.realtime = this.refreshOption === 'realtime';
        this.config.widgetInstanceGlobalAutoRefreshContext =
            this.refreshOption === 'dashboard-auto-refresh-context';
        this.formConfig.widgetInstanceGlobalAutoRefreshContext =
            this.refreshOption === 'dashboard-auto-refresh-context';
        if (this.refreshOption === 'interval') {
            this.formConfig.refreshInterval ??= 5000;
        }
        else {
            this.formConfig.refreshInterval = null;
        }
        if (!this.formConfig.realtime) {
            this.formConfig.follow = false;
        }
        this.config.widgetInstanceGlobalTimeContext =
            this.refreshOption === 'dashboard-realtime-context';
        if (this.config.widgetInstanceGlobalTimeContext) {
            this.formConfig.realtime = null;
        }
    }
    selectIcon(icon) {
        this.formConfig.icon = icon;
        this.config.mapConfig.icon = icon;
        this.previewMap.refreshMarkers();
    }
    async updateAsset() {
        this.canAutoCenter = this.mapService.hasPosition(this.config.device);
        this.isPositionedDevice = this.mapService.isPositionedDevice(this.config.device);
        this.refreshOption = this.getRefreshOption();
        this.updateRefreshOption();
        const { data, paging } = await this.mapService.getAllPositionMOs(this.config.device);
        this.assets = data;
        if (paging.totalPages > 1) {
            this.alertService.danger(gettext('It might be possible that assets are not shown in the preview, as the current selection has more than 500 assets and the preview only supports a maximum of 500 assets.'));
        }
    }
    getRefreshOption() {
        let option = 'none';
        if (this.formConfig.realtime) {
            option = 'realtime';
        }
        else if (this.formConfig.refreshInterval) {
            option = 'interval';
        }
        else if (this.config.widgetInstanceGlobalTimeContext) {
            option = 'dashboard-realtime-context';
        }
        else if (this.config.widgetInstanceGlobalAutoRefreshContext ||
            this.formConfig.widgetInstanceGlobalAutoRefreshContext) {
            option = 'dashboard-auto-refresh-context';
        }
        const isNotAllowedOption = (!this.isPositionedDevice && option === 'dashboard-realtime-context') ||
            (!this.isPositionedDevice && option === 'realtime') ||
            (this.isPositionedDevice && option === 'interval');
        option = isNotAllowedOption ? 'none' : option;
        return option;
    }
    addCenterIcon(lat, lng) {
        const titleText = this.translateService.instant(gettext('Map center'));
        const icon = this.leaflet.divIcon({
            html: `<i style="pointer-events: none" class="c8y-map-marker-icon text-muted dlt-c8y-icon-target icon-2x" title="${titleText}" />`
        });
        this.centerIcon = this.leaflet.marker([lat, lng], {
            icon
        });
        this.previewMap.addMarkerToMap(this.centerIcon);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MapWidgetConfigComponent, deps: [{ token: i1$1.MapService }, { token: i2.AlertService }, { token: i3.TranslateService }, { token: MAP_DEFAULT_CONFIG }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MapWidgetConfigComponent, isStandalone: true, selector: "c8y-map-widget-config", inputs: { config: "config" }, viewQueries: [{ propertyName: "previewMap", first: true, predicate: MapComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n  class=\"row p-t-16\"\n  *ngIf=\"formConfig\"\n>\n  <div class=\"col-xs-2\">\n    <c8y-form-group class=\"m-b-0 text-center form-group-sm\">\n      <label translate>Marker icon</label>\n      <c8y-icon-selector-wrapper\n        [canRemoveIcon]=\"true\"\n        [selectedIcon]=\"formConfig.icon\"\n        (onSelect)=\"selectIcon($event)\"\n      ></c8y-icon-selector-wrapper>\n    </c8y-form-group>\n  </div>\n  <div class=\"col-xs-10\">\n    <div class=\"row tight-grid separator-bottom\">\n      <div class=\"col-xs-4\">\n        <div class=\"form-group form-group-sm\">\n          <label translate>Zoom level</label>\n          <c8y-range\n            class=\"label-bottom\"\n            name=\"zoomLevel\"\n            #range\n            [(ngModel)]=\"formConfig.zoomLevel\"\n            (change)=\"zoomLevelChanged()\"\n          >\n            <input\n              type=\"range\"\n              min=\"2\"\n              max=\"18\"\n              step=\"1\"\n            />\n          </c8y-range>\n        </div>\n      </div>\n      <div class=\"col-xs-8\">\n        <c8y-form-group class=\"form-group-sm m-b-8\">\n          <label translate>Center bound</label>\n          <div class=\"input-group input-group-sm\">\n            <input\n              class=\"form-control\"\n              placeholder=\"{{ 'lat.`latitude`' | translate }}\"\n              name=\"centerLat\"\n              type=\"number\"\n              required\n              [(ngModel)]=\"formConfig.center[0]\"\n              (change)=\"changeCenter()\"\n              (keydown.enter)=\"changeCenterOnEnterKey($event)\"\n              min=\"-90\"\n              max=\"90\"\n              step=\"0.1\"\n            />\n            <input\n              class=\"form-control\"\n              placeholder=\"{{ 'lng.`longitude`' | translate }}\"\n              name=\"centerLng\"\n              type=\"number\"\n              required\n              min=\"-180\"\n              max=\"180\"\n              [(ngModel)]=\"formConfig.center[1]\"\n              (change)=\"changeCenter()\"\n              (keydown.enter)=\"changeCenterOnEnterKey($event)\"\n              min=\"-180\"\n              max=\"180\"\n              step=\"0.1\"\n            />\n            <div class=\"input-group-btn\">\n              <button\n                class=\"btn btn-default\"\n                [attr.aria-label]=\"'Use your location' | translate\"\n                [tooltip]=\"'Use your location' | translate\"\n                placement=\"top\"\n                container=\"body\"\n                (click)=\"useOwnPosition()\"\n              >\n                <i\n                  class=\"icon-14\"\n                  c8yIcon=\"location-arrow\"\n                ></i>\n              </button>\n            </div>\n            <div\n              class=\"input-group-btn\"\n              *ngIf=\"canAutoCenter\"\n            >\n              <button\n                class=\"btn btn-default\"\n                [attr.aria-label]=\"'Use selected asset location' | translate\"\n                [tooltip]=\"'Use selected asset location' | translate\"\n                placement=\"top\"\n                container=\"body\"\n                (click)=\"centerToAsset()\"\n              >\n                <i\n                  class=\"icon-14\"\n                  c8yIcon=\"location\"\n                ></i>\n              </button>\n            </div>\n          </div>\n          <c8y-messages\n            [helpMessage]=\"'Drag the map to the desired position' | translate\"\n          ></c8y-messages>\n        </c8y-form-group>\n      </div>\n    </div>\n\n    <div class=\"row tight-grid p-t-8 d-flex a-i-center\">\n      <div class=\"col-xs-6\">\n        <c8y-form-group class=\"m-b-0 form-group-sm\">\n          <div class=\"c8y-select-wrapper\">\n            <select\n              class=\"form-control\"\n              title=\"{{ 'Refresh options`options for refreshing a view`' | translate }}\"\n              id=\"selectExample\"\n              name=\"refreshSelection\"\n              [(ngModel)]=\"refreshOption\"\n              (change)=\"updateRefreshOption()\"\n            >\n              <option\n                [title]=\"'Only refreshing on interaction' | translate\"\n                value=\"none\"\n                translate\n              >\n                No automatic refresh\n              </option>\n              <option\n                [title]=\"'Refreshing after the given interval and on interaction' | translate\"\n                value=\"interval\"\n                *ngIf=\"!isPositionedDevice\"\n                translate\n              >\n                Use refresh interval\n              </option>\n              <option\n                [title]=\"\n                  'Refreshing after the given interval and on interaction, synchronized globally'\n                    | translate\n                \"\n                value=\"dashboard-auto-refresh-context\"\n                *ngIf=\"!isPositionedDevice\"\n                translate\n              >\n                Use global refresh interval\n              </option>\n              <option\n                [title]=\"'Live updating on each position change' | translate\"\n                value=\"realtime\"\n                *ngIf=\"isPositionedDevice\"\n                translate\n              >\n                Realtime\n              </option>\n              <option\n                [title]=\"'Bind widget to dashboard realtime context' | translate\"\n                value=\"dashboard-realtime-context\"\n                *ngIf=\"isPositionedDevice\"\n                translate\n              >\n                Dashboard realtime context\n              </option>\n            </select>\n          </div>\n        </c8y-form-group>\n      </div>\n      <div class=\"col-xs-8\">\n        <div class=\"form-group form-group-sm m-b-0\">\n          <c8y-range\n            class=\"label-bottom\"\n            name=\"refreshInterval\"\n            #intervalRange\n            *ngIf=\"refreshOption === 'interval'\"\n            [(ngModel)]=\"formConfig.refreshInterval\"\n          >\n            <ng-template #c8yRangeValue>\n              <div>\n                <span\n                  [translateParams]=\"{ intervalInSeconds: intervalRange.value * 0.001 }\"\n                  translate\n                  ngNonBindable\n                >\n                  {{ intervalInSeconds }} s\n                </span>\n              </div>\n            </ng-template>\n            <input\n              type=\"range\"\n              min=\"5000\"\n              max=\"100000\"\n              step=\"1000\"\n            />\n          </c8y-range>\n        </div>\n        <label\n          class=\"c8y-switch c8y-switch--inline\"\n          *ngIf=\"refreshOption === 'realtime' || refreshOption === 'dashboard-realtime-context'\"\n        >\n          <input\n            name=\"follow\"\n            type=\"checkbox\"\n            [(ngModel)]=\"formConfig.follow\"\n          />\n          <span></span>\n          <span\n            class=\"text-12\"\n            translate\n          >\n            Follow selected\n          </span>\n        </label>\n      </div>\n    </div>\n  </div>\n</div>\n\n<div\n  class=\"p-t-16 p-b-16\"\n  style=\"width: 100%; height: 240px\"\n>\n  <c8y-map\n    *ngIf=\"config.mapConfig\"\n    [assets]=\"assets\"\n    [config]=\"config.mapConfig\"\n    (onMove)=\"onPreviewMapMove($event)\"\n    (onZoomStart)=\"onPreviewZoomStart()\"\n    (onZoomEnd)=\"onPreviewZoomEnd($event)\"\n    (onInit)=\"previewMapInit($event)\"\n  ></c8y-map>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i5.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule$1 }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i2.MinValidationDirective, selector: "[min]", inputs: ["min"] }, { kind: "directive", type: i2.MaxValidationDirective, selector: "[max]", inputs: ["max"] }, { kind: "component", type: i2.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: i2.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i2.RangeDirective, selector: "input[type=\"range\"]" }, { kind: "component", type: i2.RangeComponent, selector: "c8y-range", inputs: ["valueDisplayMode"] }, { kind: "ngmodule", type: IconSelectorModule }, { kind: "component", type: i6.IconSelectorWrapperComponent, selector: "c8y-icon-selector-wrapper", inputs: ["canRemoveIcon", "selectedIcon", "iconSize"], outputs: ["onSelect"] }, { kind: "ngmodule", type: MapModule }, { kind: "component", type: i1$1.MapComponent, selector: "c8y-map", inputs: ["config", "assets", "polyline$", "polylineOptions"], outputs: ["onRealtimeUpdate", "onMove", "onMoveEnd", "onZoomStart", "onZoomEnd", "onMap", "onInit"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MapWidgetConfigComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-map-widget-config', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], standalone: true, imports: [
                        CommonModule,
                        FormsModule,
                        CommonModule$1,
                        FormsModule$1,
                        IconSelectorModule,
                        MapModule,
                        AssetLinkPipe,
                        TooltipModule
                    ], template: "<div\n  class=\"row p-t-16\"\n  *ngIf=\"formConfig\"\n>\n  <div class=\"col-xs-2\">\n    <c8y-form-group class=\"m-b-0 text-center form-group-sm\">\n      <label translate>Marker icon</label>\n      <c8y-icon-selector-wrapper\n        [canRemoveIcon]=\"true\"\n        [selectedIcon]=\"formConfig.icon\"\n        (onSelect)=\"selectIcon($event)\"\n      ></c8y-icon-selector-wrapper>\n    </c8y-form-group>\n  </div>\n  <div class=\"col-xs-10\">\n    <div class=\"row tight-grid separator-bottom\">\n      <div class=\"col-xs-4\">\n        <div class=\"form-group form-group-sm\">\n          <label translate>Zoom level</label>\n          <c8y-range\n            class=\"label-bottom\"\n            name=\"zoomLevel\"\n            #range\n            [(ngModel)]=\"formConfig.zoomLevel\"\n            (change)=\"zoomLevelChanged()\"\n          >\n            <input\n              type=\"range\"\n              min=\"2\"\n              max=\"18\"\n              step=\"1\"\n            />\n          </c8y-range>\n        </div>\n      </div>\n      <div class=\"col-xs-8\">\n        <c8y-form-group class=\"form-group-sm m-b-8\">\n          <label translate>Center bound</label>\n          <div class=\"input-group input-group-sm\">\n            <input\n              class=\"form-control\"\n              placeholder=\"{{ 'lat.`latitude`' | translate }}\"\n              name=\"centerLat\"\n              type=\"number\"\n              required\n              [(ngModel)]=\"formConfig.center[0]\"\n              (change)=\"changeCenter()\"\n              (keydown.enter)=\"changeCenterOnEnterKey($event)\"\n              min=\"-90\"\n              max=\"90\"\n              step=\"0.1\"\n            />\n            <input\n              class=\"form-control\"\n              placeholder=\"{{ 'lng.`longitude`' | translate }}\"\n              name=\"centerLng\"\n              type=\"number\"\n              required\n              min=\"-180\"\n              max=\"180\"\n              [(ngModel)]=\"formConfig.center[1]\"\n              (change)=\"changeCenter()\"\n              (keydown.enter)=\"changeCenterOnEnterKey($event)\"\n              min=\"-180\"\n              max=\"180\"\n              step=\"0.1\"\n            />\n            <div class=\"input-group-btn\">\n              <button\n                class=\"btn btn-default\"\n                [attr.aria-label]=\"'Use your location' | translate\"\n                [tooltip]=\"'Use your location' | translate\"\n                placement=\"top\"\n                container=\"body\"\n                (click)=\"useOwnPosition()\"\n              >\n                <i\n                  class=\"icon-14\"\n                  c8yIcon=\"location-arrow\"\n                ></i>\n              </button>\n            </div>\n            <div\n              class=\"input-group-btn\"\n              *ngIf=\"canAutoCenter\"\n            >\n              <button\n                class=\"btn btn-default\"\n                [attr.aria-label]=\"'Use selected asset location' | translate\"\n                [tooltip]=\"'Use selected asset location' | translate\"\n                placement=\"top\"\n                container=\"body\"\n                (click)=\"centerToAsset()\"\n              >\n                <i\n                  class=\"icon-14\"\n                  c8yIcon=\"location\"\n                ></i>\n              </button>\n            </div>\n          </div>\n          <c8y-messages\n            [helpMessage]=\"'Drag the map to the desired position' | translate\"\n          ></c8y-messages>\n        </c8y-form-group>\n      </div>\n    </div>\n\n    <div class=\"row tight-grid p-t-8 d-flex a-i-center\">\n      <div class=\"col-xs-6\">\n        <c8y-form-group class=\"m-b-0 form-group-sm\">\n          <div class=\"c8y-select-wrapper\">\n            <select\n              class=\"form-control\"\n              title=\"{{ 'Refresh options`options for refreshing a view`' | translate }}\"\n              id=\"selectExample\"\n              name=\"refreshSelection\"\n              [(ngModel)]=\"refreshOption\"\n              (change)=\"updateRefreshOption()\"\n            >\n              <option\n                [title]=\"'Only refreshing on interaction' | translate\"\n                value=\"none\"\n                translate\n              >\n                No automatic refresh\n              </option>\n              <option\n                [title]=\"'Refreshing after the given interval and on interaction' | translate\"\n                value=\"interval\"\n                *ngIf=\"!isPositionedDevice\"\n                translate\n              >\n                Use refresh interval\n              </option>\n              <option\n                [title]=\"\n                  'Refreshing after the given interval and on interaction, synchronized globally'\n                    | translate\n                \"\n                value=\"dashboard-auto-refresh-context\"\n                *ngIf=\"!isPositionedDevice\"\n                translate\n              >\n                Use global refresh interval\n              </option>\n              <option\n                [title]=\"'Live updating on each position change' | translate\"\n                value=\"realtime\"\n                *ngIf=\"isPositionedDevice\"\n                translate\n              >\n                Realtime\n              </option>\n              <option\n                [title]=\"'Bind widget to dashboard realtime context' | translate\"\n                value=\"dashboard-realtime-context\"\n                *ngIf=\"isPositionedDevice\"\n                translate\n              >\n                Dashboard realtime context\n              </option>\n            </select>\n          </div>\n        </c8y-form-group>\n      </div>\n      <div class=\"col-xs-8\">\n        <div class=\"form-group form-group-sm m-b-0\">\n          <c8y-range\n            class=\"label-bottom\"\n            name=\"refreshInterval\"\n            #intervalRange\n            *ngIf=\"refreshOption === 'interval'\"\n            [(ngModel)]=\"formConfig.refreshInterval\"\n          >\n            <ng-template #c8yRangeValue>\n              <div>\n                <span\n                  [translateParams]=\"{ intervalInSeconds: intervalRange.value * 0.001 }\"\n                  translate\n                  ngNonBindable\n                >\n                  {{ intervalInSeconds }} s\n                </span>\n              </div>\n            </ng-template>\n            <input\n              type=\"range\"\n              min=\"5000\"\n              max=\"100000\"\n              step=\"1000\"\n            />\n          </c8y-range>\n        </div>\n        <label\n          class=\"c8y-switch c8y-switch--inline\"\n          *ngIf=\"refreshOption === 'realtime' || refreshOption === 'dashboard-realtime-context'\"\n        >\n          <input\n            name=\"follow\"\n            type=\"checkbox\"\n            [(ngModel)]=\"formConfig.follow\"\n          />\n          <span></span>\n          <span\n            class=\"text-12\"\n            translate\n          >\n            Follow selected\n          </span>\n        </label>\n      </div>\n    </div>\n  </div>\n</div>\n\n<div\n  class=\"p-t-16 p-b-16\"\n  style=\"width: 100%; height: 240px\"\n>\n  <c8y-map\n    *ngIf=\"config.mapConfig\"\n    [assets]=\"assets\"\n    [config]=\"config.mapConfig\"\n    (onMove)=\"onPreviewMapMove($event)\"\n    (onZoomStart)=\"onPreviewZoomStart()\"\n    (onZoomEnd)=\"onPreviewZoomEnd($event)\"\n    (onInit)=\"previewMapInit($event)\"\n  ></c8y-map>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1$1.MapService }, { type: i2.AlertService }, { type: i3.TranslateService }, { type: i8.Observable, decorators: [{
                    type: Inject,
                    args: [MAP_DEFAULT_CONFIG]
                }] }], propDecorators: { config: [{
                type: Input
            }], previewMap: [{
                type: ViewChild,
                args: [MapComponent]
            }] } });

class MapWidgetComponent {
    constructor(dashboardChild, dashboardContextComponent, inventory) {
        this.dashboardContextComponent = dashboardContextComponent;
        this.inventory = inventory;
        this.mapConfig = { center: [0, 0] };
        this.TIMEOUT_ERROR_TEXT = gettext('The request is taking longer than usual. We apologize for the inconvenience.');
        this.SERVER_ERROR_TEXT = gettext('Server error occurred.');
        this.destroy$ = new Subject();
        this.listenToWidgetResizeEvent(dashboardChild);
    }
    async ngOnInit() {
        this.alerts.setAlertGroupDismissStrategy('warning', DismissAlertStrategy.TEMPORARY_OR_PERMANENT);
        if (this.dashboardContextComponent?.dashboard?.deviceType && !this.config.device) {
            const context = this.dashboardContextComponent.context;
            if (context?.id) {
                const { id } = context;
                this.config.device = (await this.inventory.detail(id)).data;
            }
        }
        if (this.config.device) {
            this.rootNode = this.config.device;
        }
        this.mapConfig = { ...this.config.mapConfig };
        if (this.config.widgetInstanceGlobalTimeContext) {
            this.updateMapConfigRealtime();
        }
        this.savedNode = this.rootNode;
    }
    ngOnChanges(changes) {
        if (changes.config?.currentValue?.widgetInstanceGlobalTimeContext) {
            this.updateMapConfigRealtime();
        }
    }
    ngAfterViewInit() {
        this.subscribeToErrorsOccurred();
    }
    startFollow(context) {
        if (context.id !== this.rootNode?.id) {
            this.rootNode = context;
        }
        this.mapConfig = {
            ...this.config.mapConfig,
            follow: true,
            realtime: true
        };
    }
    stopFollow() {
        this.mapConfig = {
            ...this.config.mapConfig,
            follow: false
        };
        if (this.config.widgetInstanceGlobalTimeContext) {
            this.updateMapConfigRealtime();
        }
        this.rootNode = this.savedNode;
    }
    ngOnDestroy() {
        this.destroy$.next();
    }
    listenToWidgetResizeEvent(dashboardChild) {
        dashboardChild.changeEnd
            .pipe(filter(child => child.lastChange === 'resize'), takeUntil(this.destroy$))
            .subscribe(() => {
            this.clusterMap.reset();
        });
    }
    subscribeToErrorsOccurred() {
        this.clusterMap.errorNotifier
            .pipe(filter(Boolean), takeUntil(this.destroy$))
            .subscribe(error => {
            this.alerts.addAlerts(new DynamicComponentAlert({
                type: 'warning',
                text: error?.name === 'TimeoutError'
                    ? this.TIMEOUT_ERROR_TEXT
                    : error?.message ?? this.SERVER_ERROR_TEXT
            }));
        });
    }
    updateMapConfigRealtime() {
        this.mapConfig.realtime = this.config.realtime || false;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MapWidgetComponent, deps: [{ token: i2.DashboardChildComponent }, { token: i2$1.ContextDashboardComponent, optional: true }, { token: i1.InventoryService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MapWidgetComponent, isStandalone: true, selector: "c8y-map-widget", inputs: { config: "config" }, viewQueries: [{ propertyName: "clusterMap", first: true, predicate: ClusterMapComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<c8y-map-status\n  [clusterMap]=\"mapWidget\"\n  [(config)]=\"mapConfig\"\n  (onUnfollow)=\"stopFollow()\"\n  [buttonsConfig]=\"config.widgetInstanceGlobalTimeContext ? { realtime: { show: false } } : null\"\n></c8y-map-status>\n<c8y-cluster-map\n  #mapWidget\n  [rootNode]=\"rootNode\"\n  [config]=\"mapConfig\"\n>\n  <div\n    class=\"map-marker\"\n    *c8yMapPopup=\"let context\"\n  >\n    <a\n      class=\"text-truncate deviceLink text-12\"\n      routerLink=\"{{ context | assetLink }}\"\n    >\n      <strong>{{ context.name }}</strong>\n    </a>\n    <c8y-map-event-info [asset]=\"context\">\n      <button\n        class=\"btn btn-default btn-xs btn-block m-t-8\"\n        [title]=\"'Activate realtime on this asset and follow it if it moves' | translate\"\n        type=\"button\"\n        (click)=\"startFollow(context)\"\n        *ngIf=\"!mapConfig.follow\"\n        translate\n      >\n        Follow\n      </button>\n      <button\n        class=\"btn btn-default btn-xs btn-block m-t-8\"\n        [title]=\"'Stop following this asset.' | translate\"\n        type=\"button\"\n        (click)=\"stopFollow()\"\n        *ngIf=\"mapConfig.follow\"\n        translate\n      >\n        Unfollow\n      </button>\n    </c8y-map-event-info>\n  </div>\n</c8y-cluster-map>\n", dependencies: [{ kind: "component", type: MapEventInfoComponent, selector: "c8y-map-event-info", inputs: ["asset"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule$1 }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "pipe", type: i2.AssetLinkPipe, name: "assetLink" }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "ngmodule", type: IconSelectorModule }, { kind: "ngmodule", type: MapModule }, { kind: "component", type: i1$1.MapStatusComponent, selector: "c8y-map-status", inputs: ["config", "clusterMap", "buttonsConfig"], outputs: ["configChange", "onUnfollow"] }, { kind: "component", type: i1$1.ClusterMapComponent, selector: "c8y-cluster-map", inputs: ["config", "rootNode", "asset", "showClusterColor"], outputs: ["mapChange"] }, { kind: "directive", type: i1$1.MapPopupDirective, selector: "[c8yMapPopup]" }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MapWidgetComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-map-widget', standalone: true, imports: [
                        MapEventInfoComponent,
                        CommonModule,
                        FormsModule,
                        CommonModule$1,
                        FormsModule$1,
                        IconSelectorModule,
                        MapModule,
                        AssetLinkPipe,
                        TooltipModule,
                        RouterLink
                    ], template: "<c8y-map-status\n  [clusterMap]=\"mapWidget\"\n  [(config)]=\"mapConfig\"\n  (onUnfollow)=\"stopFollow()\"\n  [buttonsConfig]=\"config.widgetInstanceGlobalTimeContext ? { realtime: { show: false } } : null\"\n></c8y-map-status>\n<c8y-cluster-map\n  #mapWidget\n  [rootNode]=\"rootNode\"\n  [config]=\"mapConfig\"\n>\n  <div\n    class=\"map-marker\"\n    *c8yMapPopup=\"let context\"\n  >\n    <a\n      class=\"text-truncate deviceLink text-12\"\n      routerLink=\"{{ context | assetLink }}\"\n    >\n      <strong>{{ context.name }}</strong>\n    </a>\n    <c8y-map-event-info [asset]=\"context\">\n      <button\n        class=\"btn btn-default btn-xs btn-block m-t-8\"\n        [title]=\"'Activate realtime on this asset and follow it if it moves' | translate\"\n        type=\"button\"\n        (click)=\"startFollow(context)\"\n        *ngIf=\"!mapConfig.follow\"\n        translate\n      >\n        Follow\n      </button>\n      <button\n        class=\"btn btn-default btn-xs btn-block m-t-8\"\n        [title]=\"'Stop following this asset.' | translate\"\n        type=\"button\"\n        (click)=\"stopFollow()\"\n        *ngIf=\"mapConfig.follow\"\n        translate\n      >\n        Unfollow\n      </button>\n    </c8y-map-event-info>\n  </div>\n</c8y-cluster-map>\n" }]
        }], ctorParameters: () => [{ type: i2.DashboardChildComponent }, { type: i2$1.ContextDashboardComponent, decorators: [{
                    type: Optional
                }] }, { type: i1.InventoryService }], propDecorators: { config: [{
                type: Input
            }], clusterMap: [{
                type: ViewChild,
                args: [ClusterMapComponent]
            }] } });

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

export { MapEventInfoComponent, MapWidgetComponent, MapWidgetConfigComponent };
//# sourceMappingURL=c8y-ngx-components-widgets-implementations-map.mjs.map
