@c8y/ngx-components 1021.22.49 → 1021.22.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-tracking.mjs","sources":["../../tracking/tracking.service.ts","../../tracking/tracking-marker-popup.component.ts","../../tracking/tracking-marker-popup.component.html","../../tracking/tracking-tab.guard.ts","../../tracking/tracking.component.ts","../../tracking/tracking.component.html","../../tracking/tracking.feature.ts","../../tracking/c8y-ngx-components-tracking.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { EventService, IEvent, IResultList } from '@c8y/client';\nimport { ForOfFilterPipe, GeoService, TimeInterval } from '@c8y/ngx-components';\nimport { PositionManagedObject } from '@c8y/ngx-components/map';\nimport { first, identity, isEmpty, last } from 'lodash-es';\nimport { BehaviorSubject, Observable, Subject, combineLatest, pipe } from 'rxjs';\nimport { map, share, switchMap, tap } from 'rxjs/operators';\n\nconst LOCATION_UPDATE_EVENT_TYPE = 'c8y_LocationUpdate';\n\n@Injectable()\nexport class TrackingService {\n private static readonly BASE_FILTER = {\n pageSize: 1000,\n withTotalPages: true,\n type: LOCATION_UPDATE_EVENT_TYPE\n };\n\n events$: Observable<IResultList<IEvent>>;\n polyline$: Observable<L.LatLngExpression[]>;\n pipe: ForOfFilterPipe;\n trackVisible = true;\n hasEvents = false;\n\n private _polylineEventsSubject$ = new BehaviorSubject<IEvent[]>([]);\n\n private deviceId$: Subject<string | number> = new Subject();\n private timeInterval$: Subject<TimeInterval> = new Subject();\n private reload$: BehaviorSubject<void> = new BehaviorSubject(null);\n\n constructor(\n private eventService: EventService,\n private geo: GeoService\n ) {\n this.polyline$ = this._polylineEventsSubject$.asObservable().pipe(\n map(events => (events || []).map(event => this.geo.getLatLong(event)).filter(identity)),\n share()\n );\n\n this.events$ = combineLatest([this.deviceId$, this.timeInterval$, this.reload$]).pipe(\n switchMap(([source, interval]) => {\n const { dateFrom, dateTo } = interval;\n return this.eventService.list({\n ...TrackingService.BASE_FILTER,\n source,\n dateFrom: dateFrom.toISOString(),\n dateTo: dateTo.toISOString()\n });\n }),\n tap(() => this._polylineEventsSubject$.next([])),\n share()\n );\n\n this.pipe = pipe(\n tap(events => (this.hasEvents = !isEmpty(events))),\n map((events: IEvent[]) => (events || []).filter(event => this.isMatchingEvent(event))),\n tap((events: IEvent[]) => {\n const prepend =\n this.compareEvents(last(this._polylineEventsSubject$.value), first(events)) < 0;\n const polyline: IEvent[] = prepend\n ? [...events, ...this._polylineEventsSubject$.value]\n : [...this._polylineEventsSubject$.value, ...events];\n\n this._polylineEventsSubject$.next(polyline);\n })\n );\n }\n\n setDeviceId(deviceId: string | number) {\n this.deviceId$.next(deviceId);\n }\n\n setInterval(interval: TimeInterval) {\n this.timeInterval$.next(interval);\n }\n\n clearTrack() {\n this._polylineEventsSubject$.next([]);\n }\n\n reload() {\n this.reload$.next();\n }\n\n async latestPositionUpdate(mo: PositionManagedObject): Promise<Date> {\n const dateTo = new Date();\n dateTo.setDate(dateTo.getDate() + 1);\n\n const filters = {\n fragmentType: 'c8y_Position',\n dateFrom: new Date(0).toISOString(),\n dateTo: dateTo.toISOString(),\n pageSize: 1,\n source: mo.id\n };\n const events = await this.eventService.list(filters);\n return events?.data?.length ? new Date(events.data[0].time) : undefined;\n }\n\n toggleTrack() {\n if (this.trackVisible) {\n this.clearTrack();\n } else {\n this.reload();\n }\n this.trackVisible = !this.trackVisible;\n }\n\n isLocationUpdateEvent(event: IEvent): boolean {\n return event.type === LOCATION_UPDATE_EVENT_TYPE;\n }\n\n private isMatchingEvent(event: IEvent): boolean {\n return this.isLocationUpdateEvent(event);\n }\n\n private compareEvents(a: IEvent, b: IEvent): number {\n return Date.parse(a?.time) - Date.parse(b?.time);\n }\n}\n","import { Component, Input, OnInit } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { RouterModule } from '@angular/router';\nimport { IEvent } from '@c8y/client';\nimport { CoreModule } from '@c8y/ngx-components';\nimport { PositionManagedObject } from '@c8y/ngx-components/map';\nimport { TrackingService } from './tracking.service';\n\n@Component({\n standalone: true,\n selector: 'c8y-tracking-marker-popup',\n templateUrl: './tracking-marker-popup.component.html',\n imports: [CoreModule, RouterModule, FormsModule]\n})\nexport class TrackingMarkerPopupComponent implements OnInit {\n @Input()\n context: PositionManagedObject | IEvent;\n\n isDevice: boolean;\n date: Date;\n\n constructor(public trackingService: TrackingService) {}\n\n async ngOnInit() {\n this.isDevice = !this.trackingService.isLocationUpdateEvent(this.context as unknown as IEvent);\n if (this.isDevice) {\n this.date = await this.trackingService.latestPositionUpdate(\n this.context as PositionManagedObject\n );\n } else {\n this.date = this.context.time;\n }\n }\n}\n","<div class=\"map-marker\">\n <a\n class=\"text-truncate text-14 text-medium p-0 m-b-8 deviceLink\"\n [title]=\"context?.name\"\n *ngIf=\"isDevice\"\n [routerLink]=\"['/device/', context?.id]\"\n >\n {{ context?.name }}\n </a>\n <div\n class=\"m-b-8\"\n ng-if=\"lastUpdated\"\n >\n <p class=\"m-0\">{{ 'Position:' | translate }}</p>\n <span class=\"text-muted\">\n {{ context?.c8y_Position?.lat + ', ' + context?.c8y_Position?.lng }}\n </span>\n <p class=\"m-0 p-t-4\">{{ 'Date and time:' | translate }}</p>\n <span class=\"text-muted\">{{ date | c8yDate }}</span>\n </div>\n\n <ng-container *ngIf=\"isDevice\">\n <div class=\"d-flex a-i-center\">\n <label\n class=\"c8y-switch\"\n for=\"switch\"\n >\n <input\n id=\"switch\"\n type=\"checkbox\"\n [checked]=\"trackingService.trackVisible\"\n (change)=\"trackingService.toggleTrack()\"\n />\n <span></span>\n </label>\n <div class=\"description p-b-0\">\n {{ 'Show track' | translate }}\n </div>\n </div>\n </ng-container>\n</div>\n","import { Injectable } from '@angular/core';\nimport { ActivatedRouteSnapshot, CanActivate } from '@angular/router';\nimport { IManagedObject } from '@c8y/client';\nimport { ContextRouteService, GeoService, ViewContext } from '@c8y/ngx-components';\nimport { isEmpty } from 'lodash-es';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class TrackingTabFactory implements CanActivate {\n constructor(\n private contextRouteService: ContextRouteService,\n private geoService: GeoService\n ) {}\n\n canActivate(snapshot: ActivatedRouteSnapshot): boolean {\n const contextData = this.contextRouteService.getContextData(snapshot);\n return (\n contextData?.context === ViewContext.Device &&\n !isEmpty(this.geoService.getLatLong(contextData?.contextData as IManagedObject))\n );\n }\n}\n","import { AsyncPipe } from '@angular/common';\nimport { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ActivatedRoute } from '@angular/router';\nimport { IEvent } from '@c8y/client';\nimport {\n ActionBarModule,\n ContextRouteService,\n CoreModule,\n DateRangePickerConfig,\n EventRealtimeService,\n LoadMoreComponent,\n TimeInterval,\n TimeIntervalComponent\n} from '@c8y/ngx-components';\nimport { MapComponent, MapConfig, MapModule, PositionManagedObject } from '@c8y/ngx-components/map';\nimport { TrackingMarkerPopupComponent } from './tracking-marker-popup.component';\nimport { TrackingService } from './tracking.service';\n\n@Component({\n standalone: true,\n templateUrl: './tracking.component.html',\n imports: [\n MapModule,\n AsyncPipe,\n ActionBarModule,\n CoreModule,\n TimeIntervalComponent,\n FormsModule,\n TrackingMarkerPopupComponent\n ],\n providers: [TrackingService, EventRealtimeService],\n selector: 'c8y-tracking'\n})\nexport class TrackingComponent implements OnInit, AfterViewInit {\n @ViewChild(MapComponent)\n map: MapComponent;\n\n dateRangePickerConfig: DateRangePickerConfig = {\n adaptivePosition: true,\n showPreviousMonth: true,\n preventChangeToNextMonth: true\n };\n\n config: MapConfig = {\n realtime: false,\n follow: false,\n zoomLevel: 12,\n fitBoundsOptions: {\n padding: [50, 50]\n }\n };\n\n maxDate = new Date();\n activeMarkers: { [key: string]: boolean } = {};\n realtimeDisabled = false;\n device: PositionManagedObject;\n loadMoreComponent: LoadMoreComponent;\n\n constructor(\n public service: TrackingService,\n public realtime: EventRealtimeService,\n private contextRouteService: ContextRouteService,\n private activatedRoute: ActivatedRoute\n ) {}\n\n async ngOnInit() {\n const { contextData } = this.contextRouteService.getContextData(this.activatedRoute);\n this.device = contextData as PositionManagedObject;\n }\n\n async ngAfterViewInit() {\n this.service.setDeviceId(this.device.id);\n this.togglePositionRealtime(this.realtime.active);\n }\n\n toggleMarker(event: IEvent) {\n let marker = this.map.findMarker(event);\n\n if (marker) {\n this.map.removeMarker(marker);\n delete this.activeMarkers[`p${event.id}`];\n } else {\n marker = this.map.getTrackingMarker(event);\n this.map.addMarkerToMap(marker);\n this.activeMarkers[`p${event.id}`] = true;\n }\n }\n\n togglePositionRealtime(active: boolean) {\n this.config = { ...this.config, realtime: active };\n }\n\n toggleRealtime(interval: TimeInterval) {\n const currentTimeInRange = Date.now() <= interval?.dateTo?.getTime();\n this.togglePositionRealtime(currentTimeInRange);\n this.realtimeDisabled = !currentTimeInRange;\n\n if (currentTimeInRange) {\n this.realtime.start();\n } else {\n this.realtime.stop();\n }\n }\n}\n","<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"100\"\n>\n <c8y-realtime-btn\n [service]=\"realtime\"\n [disabled]=\"realtimeDisabled\"\n (onToggle)=\"togglePositionRealtime($event)\"\n ></c8y-realtime-btn>\n</c8y-action-bar-item>\n<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"60\"\n>\n <c8y-time-interval\n [maxCustomDate]=\"maxDate\"\n [dateRangePickerConfig]=\"dateRangePickerConfig\"\n (interval)=\"service.setInterval($event); toggleRealtime($event)\"\n ></c8y-time-interval>\n</c8y-action-bar-item>\n\n<div class=\"card card--grid content-fullpage d-grid grid__col--8-4--md\">\n <div class=\"bg-white p-relative\">\n <c8y-map\n [config]=\"config\"\n [assets]=\"device\"\n [polyline$]=\"service.polyline$\"\n [polylineOptions]=\"{ color: 'darkblue' }\"\n >\n <div *c8yMapPopup=\"let context\">\n <c8y-tracking-marker-popup [context]=\"context\"></c8y-tracking-marker-popup>\n </div>\n </c8y-map>\n </div>\n\n <div class=\"d-flex d-col bg-inherit content-fullpage bg-gray-white\">\n <div class=\"card-header large-padding separator sticky-top\">\n <span\n class=\"card-title\"\n translate\n >\n Tracking events\n </span>\n </div>\n <div class=\"inner-scroll\">\n <c8y-list-group class=\"c8y-list__group--strip\">\n <ng-template\n c8yFor\n let-event\n [c8yForOf]=\"service.events$\"\n [c8yForPipe]=\"service.pipe\"\n [c8yForRealtime]=\"realtime\"\n [c8yForRealtimeOptions]=\"{ entityOrId: device }\"\n [c8yForLoadMore]=\"'hidden'\"\n [c8yForNotFound]=\"empty\"\n (c8yForLoadMoreComponent)=\"\n loadMoreComponent = $event; loadMoreComponent.useIntersection = false\n \"\n >\n <c8y-li\n class=\"pointer\"\n [ngClass]=\"{ 'text-primary text-bold': activeMarkers['p' + event?.id] }\"\n (click)=\"toggleMarker(event)\"\n >\n <c8y-li-icon [ngClass]=\"{ 'text-primary': activeMarkers['p' + event?.id] }\">\n <i c8yIcon=\"c8y-location\"></i>\n </c8y-li-icon>\n <c8y-li-body>\n <div class=\"d-flex\">\n <span>\n {{ event.time | date: 'mediumDate' }}\n </span>\n <span class=\"m-l-auto\">\n {{ event.time | date: 'mediumTime' }}\n </span>\n </div>\n </c8y-li-body>\n </c8y-li>\n </ng-template>\n </c8y-list-group>\n </div>\n\n <!-- empty state -->\n <ng-template #empty>\n <c8y-ui-empty-state\n icon=\"c8y-location\"\n [title]=\"'No tracking events found.' | translate\"\n [subtitle]=\"'Select another time range.' | translate\"\n *ngIf=\"!service.hasEvents\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </ng-template>\n\n <div *ngIf=\"loadMoreComponent?.hasMore\">\n <button\n class=\"btn btn-link fit-w sticky-bottom separator-top\"\n [title]=\"'Load more' | translate\"\n type=\"button\"\n [disabled]=\"loadMoreComponent?.isLoading\"\n (click)=\"loadMoreComponent.loadMore()\"\n >\n {{ 'Load more' | translate }}\n </button>\n </div>\n\n <div class=\"card-footer separator\">\n <button\n class=\"btn btn-default\"\n [title]=\"'Deselect all markers' | translate\"\n type=\"button\"\n [disabled]=\"(activeMarkers | json) === '{}'\"\n (click)=\"map.clearMarkers('event'); activeMarkers = {}\"\n >\n {{ 'Deselect all markers' | translate }}\n </button>\n </div>\n </div>\n</div>\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { gettext, hookRoute, ViewContext } from '@c8y/ngx-components';\nimport { TrackingTabFactory } from './tracking-tab.guard';\nimport { TrackingComponent } from './tracking.component';\n\nexport const trackingFeatureProvider: EnvironmentProviders = makeEnvironmentProviders([\n TrackingTabFactory,\n hookRoute({\n path: 'tracking',\n component: TrackingComponent,\n context: ViewContext.Device,\n label: gettext('Tracking'),\n icon: 'crosshairs',\n canActivate: [TrackingTabFactory]\n })\n]);\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.TrackingService","i3","i1"],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-tracking.mjs","sources":["../../tracking/tracking.service.ts","../../tracking/tracking-marker-popup.component.ts","../../tracking/tracking-marker-popup.component.html","../../tracking/tracking-tab.guard.ts","../../tracking/tracking.component.ts","../../tracking/tracking.component.html","../../tracking/tracking.feature.ts","../../tracking/c8y-ngx-components-tracking.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { EventService, IEvent, IResultList } from '@c8y/client';\nimport { ForOfFilterPipe, GeoService, TimeInterval } from '@c8y/ngx-components';\nimport { PositionManagedObject } from '@c8y/ngx-components/map';\nimport { first, identity, isEmpty, last } from 'lodash-es';\nimport { BehaviorSubject, Observable, Subject, combineLatest, pipe } from 'rxjs';\nimport { distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators';\n\nconst LOCATION_UPDATE_EVENT_TYPE = 'c8y_LocationUpdate';\n\n@Injectable()\nexport class TrackingService {\n private static readonly BASE_FILTER = {\n pageSize: 1000,\n withTotalPages: true,\n type: LOCATION_UPDATE_EVENT_TYPE\n };\n\n events$: Observable<IResultList<IEvent>>;\n polyline$: Observable<L.LatLngExpression[]>;\n pipe: ForOfFilterPipe;\n trackVisible = true;\n hasEvents = false;\n\n private _polylineEventsSubject$ = new BehaviorSubject<IEvent[]>([]);\n\n private deviceId$: Subject<string | number> = new Subject();\n private timeInterval$: Subject<TimeInterval> = new Subject();\n private reload$: BehaviorSubject<void> = new BehaviorSubject(null);\n\n constructor(\n private eventService: EventService,\n private geo: GeoService\n ) {\n this.polyline$ = this._polylineEventsSubject$.asObservable().pipe(\n map(events => (events || []).map(event => this.geo.getLatLong(event)).filter(identity)),\n share()\n );\n\n this.events$ = combineLatest([\n this.deviceId$.pipe(distinctUntilChanged()),\n this.timeInterval$,\n this.reload$\n ]).pipe(\n switchMap(([source, interval]) => {\n const { dateFrom, dateTo } = interval;\n return this.eventService.list({\n ...TrackingService.BASE_FILTER,\n source,\n dateFrom: dateFrom.toISOString(),\n dateTo: dateTo.toISOString()\n });\n }),\n tap(() => this._polylineEventsSubject$.next([])),\n share()\n );\n\n this.pipe = pipe(\n tap(events => (this.hasEvents = !isEmpty(events))),\n map((events: IEvent[]) => (events || []).filter(event => this.isMatchingEvent(event))),\n tap((events: IEvent[]) => {\n const prepend =\n this.compareEvents(last(this._polylineEventsSubject$.value), first(events)) < 0;\n const polyline: IEvent[] = prepend\n ? [...events, ...this._polylineEventsSubject$.value]\n : [...this._polylineEventsSubject$.value, ...events];\n\n this._polylineEventsSubject$.next(polyline);\n })\n );\n }\n\n setDeviceId(deviceId: string | number) {\n this.deviceId$.next(deviceId);\n }\n\n setInterval(interval: TimeInterval) {\n this.timeInterval$.next(interval);\n }\n\n clearTrack() {\n this._polylineEventsSubject$.next([]);\n }\n\n reload() {\n this.reload$.next();\n }\n\n async latestPositionUpdate(mo: PositionManagedObject): Promise<Date> {\n const dateTo = new Date();\n dateTo.setDate(dateTo.getDate() + 1);\n\n const filters = {\n fragmentType: 'c8y_Position',\n dateFrom: new Date(0).toISOString(),\n dateTo: dateTo.toISOString(),\n pageSize: 1,\n source: mo.id\n };\n const events = await this.eventService.list(filters);\n return events?.data?.length ? new Date(events.data[0].time) : undefined;\n }\n\n toggleTrack() {\n if (this.trackVisible) {\n this.clearTrack();\n } else {\n this.reload();\n }\n this.trackVisible = !this.trackVisible;\n }\n\n isLocationUpdateEvent(event: IEvent): boolean {\n return event.type === LOCATION_UPDATE_EVENT_TYPE;\n }\n\n private isMatchingEvent(event: IEvent): boolean {\n return this.isLocationUpdateEvent(event);\n }\n\n private compareEvents(a: IEvent, b: IEvent): number {\n return Date.parse(a?.time) - Date.parse(b?.time);\n }\n}\n","import { Component, Input, OnInit } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { RouterModule } from '@angular/router';\nimport { IEvent } from '@c8y/client';\nimport { CoreModule } from '@c8y/ngx-components';\nimport { PositionManagedObject } from '@c8y/ngx-components/map';\nimport { TrackingService } from './tracking.service';\n\n@Component({\n standalone: true,\n selector: 'c8y-tracking-marker-popup',\n templateUrl: './tracking-marker-popup.component.html',\n imports: [CoreModule, RouterModule, FormsModule]\n})\nexport class TrackingMarkerPopupComponent implements OnInit {\n @Input()\n context: PositionManagedObject | IEvent;\n\n isDevice: boolean;\n date: Date;\n\n constructor(public trackingService: TrackingService) {}\n\n async ngOnInit() {\n this.isDevice = !this.trackingService.isLocationUpdateEvent(this.context as unknown as IEvent);\n if (this.isDevice) {\n this.date = await this.trackingService.latestPositionUpdate(\n this.context as PositionManagedObject\n );\n } else {\n this.date = this.context.time;\n }\n }\n}\n","<div class=\"map-marker\">\n <a\n class=\"text-truncate text-14 text-medium p-0 m-b-8 deviceLink\"\n [title]=\"context?.name\"\n *ngIf=\"isDevice\"\n [routerLink]=\"['/device/', context?.id]\"\n >\n {{ context?.name }}\n </a>\n <div\n class=\"m-b-8\"\n ng-if=\"lastUpdated\"\n >\n <p class=\"m-0\">{{ 'Position:' | translate }}</p>\n <span class=\"text-muted\">\n {{ context?.c8y_Position?.lat + ', ' + context?.c8y_Position?.lng }}\n </span>\n <p class=\"m-0 p-t-4\">{{ 'Date and time:' | translate }}</p>\n <span class=\"text-muted\">{{ date | c8yDate }}</span>\n </div>\n\n <ng-container *ngIf=\"isDevice\">\n <div class=\"d-flex a-i-center\">\n <label\n class=\"c8y-switch\"\n for=\"switch\"\n >\n <input\n id=\"switch\"\n type=\"checkbox\"\n [checked]=\"trackingService.trackVisible\"\n (change)=\"trackingService.toggleTrack()\"\n />\n <span></span>\n </label>\n <div class=\"description p-b-0\">\n {{ 'Show track' | translate }}\n </div>\n </div>\n </ng-container>\n</div>\n","import { Injectable } from '@angular/core';\nimport { ActivatedRouteSnapshot, CanActivate } from '@angular/router';\nimport { IManagedObject } from '@c8y/client';\nimport { ContextRouteService, GeoService, ViewContext } from '@c8y/ngx-components';\nimport { isEmpty } from 'lodash-es';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class TrackingTabFactory implements CanActivate {\n constructor(\n private contextRouteService: ContextRouteService,\n private geoService: GeoService\n ) {}\n\n canActivate(snapshot: ActivatedRouteSnapshot): boolean {\n const contextData = this.contextRouteService.getContextData(snapshot);\n return (\n contextData?.context === ViewContext.Device &&\n !isEmpty(this.geoService.getLatLong(contextData?.contextData as IManagedObject))\n );\n }\n}\n","import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ActivatedRoute } from '@angular/router';\nimport { IEvent } from '@c8y/client';\nimport {\n ActionBarModule,\n ContextRouteService,\n CoreModule,\n DateRangePickerConfig,\n EventRealtimeService,\n LoadMoreComponent,\n TimeInterval,\n TimeIntervalComponent\n} from '@c8y/ngx-components';\nimport { MapComponent, MapConfig, MapModule, PositionManagedObject } from '@c8y/ngx-components/map';\nimport { TrackingMarkerPopupComponent } from './tracking-marker-popup.component';\nimport { TrackingService } from './tracking.service';\n\n@Component({\n standalone: true,\n templateUrl: './tracking.component.html',\n imports: [\n MapModule,\n ActionBarModule,\n CoreModule,\n TimeIntervalComponent,\n FormsModule,\n TrackingMarkerPopupComponent\n ],\n providers: [TrackingService, EventRealtimeService],\n selector: 'c8y-tracking'\n})\nexport class TrackingComponent implements OnInit, AfterViewInit {\n @ViewChild(MapComponent)\n map: MapComponent;\n\n dateRangePickerConfig: DateRangePickerConfig = {\n adaptivePosition: true,\n showPreviousMonth: true,\n preventChangeToNextMonth: true\n };\n\n config: MapConfig = {\n realtime: true,\n follow: false,\n zoomLevel: 12,\n fitBoundsOptions: {\n padding: [50, 50]\n }\n };\n\n maxDate = new Date();\n activeMarkers: { [key: string]: boolean } = {};\n realtimeDisabled = false;\n device: PositionManagedObject;\n loadMoreComponent: LoadMoreComponent;\n\n constructor(\n public service: TrackingService,\n public realtime: EventRealtimeService,\n private contextRouteService: ContextRouteService,\n private activatedRoute: ActivatedRoute\n ) {}\n\n async ngOnInit() {\n const { contextData } = this.contextRouteService.getContextData(this.activatedRoute);\n this.device = contextData as PositionManagedObject;\n }\n\n async ngAfterViewInit() {\n this.service.setDeviceId(this.device.id);\n this.togglePositionRealtime(this.realtime.active);\n }\n\n toggleMarker(event: IEvent) {\n let marker = this.map.findMarker(event);\n\n if (marker) {\n this.map.removeMarker(marker);\n delete this.activeMarkers[`p${event.id}`];\n } else {\n marker = this.map.getTrackingMarker(event);\n this.map.addMarkerToMap(marker);\n this.activeMarkers[`p${event.id}`] = true;\n }\n }\n\n togglePositionRealtime(active: boolean) {\n this.config = { ...this.config, realtime: active };\n }\n\n toggleRealtime(interval: TimeInterval) {\n const currentTimeInRange = Date.now() <= interval?.dateTo?.getTime();\n this.togglePositionRealtime(currentTimeInRange);\n this.realtimeDisabled = !currentTimeInRange;\n\n if (currentTimeInRange) {\n this.realtime.start();\n } else {\n this.realtime.stop();\n }\n }\n}\n","<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"100\"\n>\n <c8y-realtime-btn\n [service]=\"realtime\"\n [disabled]=\"realtimeDisabled\"\n (onToggle)=\"togglePositionRealtime($event)\"\n ></c8y-realtime-btn>\n</c8y-action-bar-item>\n<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"60\"\n>\n <c8y-time-interval\n [maxCustomDate]=\"maxDate\"\n [dateRangePickerConfig]=\"dateRangePickerConfig\"\n (interval)=\"service.setInterval($event); toggleRealtime($event)\"\n ></c8y-time-interval>\n</c8y-action-bar-item>\n\n<div class=\"card card--grid content-fullpage d-grid grid__col--8-4--md\">\n <div class=\"bg-white p-relative\">\n <c8y-map\n [config]=\"config\"\n [assets]=\"device\"\n [polyline$]=\"service.polyline$\"\n [polylineOptions]=\"{ color: 'darkblue' }\"\n >\n <div *c8yMapPopup=\"let context\">\n <c8y-tracking-marker-popup [context]=\"context\"></c8y-tracking-marker-popup>\n </div>\n </c8y-map>\n </div>\n\n <div class=\"d-flex d-col bg-inherit content-fullpage bg-gray-white\">\n <div class=\"card-header large-padding separator sticky-top\">\n <span\n class=\"card-title\"\n translate\n >\n Tracking events\n </span>\n </div>\n <div class=\"inner-scroll\">\n <c8y-list-group class=\"c8y-list__group--strip\">\n <ng-template\n c8yFor\n let-event\n [c8yForOf]=\"service.events$\"\n [c8yForPipe]=\"service.pipe\"\n [c8yForRealtime]=\"realtime\"\n [c8yForRealtimeOptions]=\"{ entityOrId: device }\"\n [c8yForLoadMore]=\"'hidden'\"\n [c8yForNotFound]=\"empty\"\n (c8yForLoadMoreComponent)=\"\n loadMoreComponent = $event; loadMoreComponent.useIntersection = false\n \"\n >\n <c8y-li\n class=\"pointer\"\n [ngClass]=\"{ 'text-primary text-bold': activeMarkers['p' + event?.id] }\"\n (click)=\"toggleMarker(event)\"\n [attr.data-cy]=\"'c8y-tracking--tracking-event-item-' + event?.id\"\n >\n <c8y-li-icon [ngClass]=\"{ 'text-primary': activeMarkers['p' + event?.id] }\">\n <i c8yIcon=\"c8y-location\"></i>\n </c8y-li-icon>\n <c8y-li-body>\n <div class=\"d-flex\">\n <span>\n {{ event.time | date: 'mediumDate' }}\n </span>\n <span class=\"m-l-auto\">\n {{ event.time | date: 'mediumTime' }}\n </span>\n </div>\n </c8y-li-body>\n </c8y-li>\n </ng-template>\n </c8y-list-group>\n </div>\n\n <!-- empty state -->\n <ng-template #empty>\n <c8y-ui-empty-state\n icon=\"c8y-location\"\n [title]=\"'No tracking events found.' | translate\"\n [subtitle]=\"'Select another time range.' | translate\"\n *ngIf=\"!service.hasEvents\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </ng-template>\n\n <div *ngIf=\"loadMoreComponent?.hasMore\">\n <button\n class=\"btn btn-link fit-w sticky-bottom separator-top\"\n [title]=\"'Load more' | translate\"\n type=\"button\"\n [disabled]=\"loadMoreComponent?.isLoading\"\n (click)=\"loadMoreComponent.loadMore()\"\n data-cy=\"c8y-tracking--load-more\"\n >\n {{ 'Load more' | translate }}\n </button>\n </div>\n\n <div class=\"card-footer separator\">\n <button\n class=\"btn btn-default\"\n [title]=\"'Deselect all markers' | translate\"\n type=\"button\"\n [disabled]=\"(activeMarkers | json) === '{}'\"\n (click)=\"map.clearMarkers('event'); activeMarkers = {}\"\n >\n {{ 'Deselect all markers' | translate }}\n </button>\n </div>\n </div>\n</div>\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { gettext, hookRoute, ViewContext } from '@c8y/ngx-components';\nimport { TrackingTabFactory } from './tracking-tab.guard';\nimport { TrackingComponent } from './tracking.component';\n\nexport const trackingFeatureProvider: EnvironmentProviders = makeEnvironmentProviders([\n TrackingTabFactory,\n hookRoute({\n path: 'tracking',\n component: TrackingComponent,\n context: ViewContext.Device,\n label: gettext('Tracking'),\n icon: 'crosshairs',\n canActivate: [TrackingTabFactory]\n })\n]);\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.TrackingService","i3","i1"],"mappings":";;;;;;;;;;;;;;;AAQA,MAAM,0BAA0B,GAAG,oBAAoB,CAAC;MAG3C,eAAe,CAAA;AACF,IAAA,SAAA,IAAA,CAAA,WAAW,GAAG;AACpC,QAAA,QAAQ,EAAE,IAAI;AACd,QAAA,cAAc,EAAE,IAAI;AACpB,QAAA,IAAI,EAAE,0BAA0B;AACjC,KAJkC,CAIjC,EAAA;IAcF,WACU,CAAA,YAA0B,EAC1B,GAAe,EAAA;QADf,IAAY,CAAA,YAAA,GAAZ,YAAY,CAAc;QAC1B,IAAG,CAAA,GAAA,GAAH,GAAG,CAAY;QAXzB,IAAY,CAAA,YAAA,GAAG,IAAI,CAAC;QACpB,IAAS,CAAA,SAAA,GAAG,KAAK,CAAC;AAEV,QAAA,IAAA,CAAA,uBAAuB,GAAG,IAAI,eAAe,CAAW,EAAE,CAAC,CAAC;AAE5D,QAAA,IAAA,CAAA,SAAS,GAA6B,IAAI,OAAO,EAAE,CAAC;AACpD,QAAA,IAAA,CAAA,aAAa,GAA0B,IAAI,OAAO,EAAE,CAAC;AACrD,QAAA,IAAA,CAAA,OAAO,GAA0B,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;QAMjE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,uBAAuB,CAAC,YAAY,EAAE,CAAC,IAAI,CAC/D,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EACvF,KAAK,EAAE,CACR,CAAC;AAEF,QAAA,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC;AAC3B,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;AAC3C,YAAA,IAAI,CAAC,aAAa;AAClB,YAAA,IAAI,CAAC,OAAO;AACb,SAAA,CAAC,CAAC,IAAI,CACL,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAI;AAC/B,YAAA,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC;AACtC,YAAA,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;gBAC5B,GAAG,eAAe,CAAC,WAAW;gBAC9B,MAAM;AACN,gBAAA,QAAQ,EAAE,QAAQ,CAAC,WAAW,EAAE;AAChC,gBAAA,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE;AAC7B,aAAA,CAAC,CAAC;SACJ,CAAC,EACF,GAAG,CAAC,MAAM,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAChD,KAAK,EAAE,CACR,CAAC;QAEF,IAAI,CAAC,IAAI,GAAG,IAAI,CACd,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAClD,GAAG,CAAC,CAAC,MAAgB,KAAK,CAAC,MAAM,IAAI,EAAE,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,EACtF,GAAG,CAAC,CAAC,MAAgB,KAAI;YACvB,MAAM,OAAO,GACX,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;YAClF,MAAM,QAAQ,GAAa,OAAO;kBAC9B,CAAC,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC;AACpD,kBAAE,CAAC,GAAG,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC;AAEvD,YAAA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;SAC7C,CAAC,CACH,CAAC;KACH;AAED,IAAA,WAAW,CAAC,QAAyB,EAAA;AACnC,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;KAC/B;AAED,IAAA,WAAW,CAAC,QAAsB,EAAA;AAChC,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;KACnC;IAED,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;KACvC;IAED,MAAM,GAAA;AACJ,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;KACrB;IAED,MAAM,oBAAoB,CAAC,EAAyB,EAAA;AAClD,QAAA,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QAC1B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;AAErC,QAAA,MAAM,OAAO,GAAG;AACd,YAAA,YAAY,EAAE,cAAc;YAC5B,QAAQ,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;AACnC,YAAA,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE;AAC5B,YAAA,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,EAAE,CAAC,EAAE;SACd,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrD,OAAO,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;KACzE;IAED,WAAW,GAAA;AACT,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,IAAI,CAAC,UAAU,EAAE,CAAC;SACnB;aAAM;YACL,IAAI,CAAC,MAAM,EAAE,CAAC;SACf;AACD,QAAA,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC;KACxC;AAED,IAAA,qBAAqB,CAAC,KAAa,EAAA;AACjC,QAAA,OAAO,KAAK,CAAC,IAAI,KAAK,0BAA0B,CAAC;KAClD;AAEO,IAAA,eAAe,CAAC,KAAa,EAAA;AACnC,QAAA,OAAO,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;KAC1C;IAEO,aAAa,CAAC,CAAS,EAAE,CAAS,EAAA;AACxC,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;KAClD;8GA/GU,eAAe,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,YAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA,EAAA;kHAAf,eAAe,EAAA,CAAA,CAAA,EAAA;;2FAAf,eAAe,EAAA,UAAA,EAAA,CAAA;kBAD3B,UAAU;;;MCIE,4BAA4B,CAAA;AAOvC,IAAA,WAAA,CAAmB,eAAgC,EAAA;QAAhC,IAAe,CAAA,eAAA,GAAf,eAAe,CAAiB;KAAI;AAEvD,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,qBAAqB,CAAC,IAAI,CAAC,OAA4B,CAAC,CAAC;AAC/F,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,YAAA,IAAI,CAAC,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,oBAAoB,CACzD,IAAI,CAAC,OAAgC,CACtC,CAAC;SACH;aAAM;YACL,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;SAC/B;KACF;8GAlBU,4BAA4B,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,eAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA,EAAA;AAA5B,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,4BAA4B,qHCdzC,qnCAyCA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED7BY,UAAU,EAAE,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,IAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,QAAA,EAAA,IAAA,EAAA,SAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,+QAAE,WAAW,EAAA,CAAA,EAAA,CAAA,CAAA,EAAA;;2FAEpC,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBANxC,SAAS;iCACI,IAAI,EAAA,QAAA,EACN,2BAA2B,EAE5B,OAAA,EAAA,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,EAAA,QAAA,EAAA,qnCAAA,EAAA,CAAA;iFAIhD,OAAO,EAAA,CAAA;sBADN,KAAK;;;MENK,kBAAkB,CAAA;IAC7B,WACU,CAAA,mBAAwC,EACxC,UAAsB,EAAA;QADtB,IAAmB,CAAA,mBAAA,GAAnB,mBAAmB,CAAqB;QACxC,IAAU,CAAA,UAAA,GAAV,UAAU,CAAY;KAC5B;AAEJ,IAAA,WAAW,CAAC,QAAgC,EAAA;QAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;AACtE,QAAA,QACE,WAAW,EAAE,OAAO,KAAK,WAAW,CAAC,MAAM;AAC3C,YAAA,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,WAAW,EAAE,WAA6B,CAAC,CAAC,EAChF;KACH;8GAZU,kBAAkB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAC,EAAA,CAAA,mBAAA,EAAA,EAAA,EAAA,KAAA,EAAAA,EAAA,CAAA,UAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA,EAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,cAFjB,MAAM,EAAA,CAAA,CAAA,EAAA;;2FAEP,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAH9B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA,CAAA;;;MCwBY,iBAAiB,CAAA;AAyB5B,IAAA,WAAA,CACS,OAAwB,EACxB,QAA8B,EAC7B,mBAAwC,EACxC,cAA8B,EAAA;QAH/B,IAAO,CAAA,OAAA,GAAP,OAAO,CAAiB;QACxB,IAAQ,CAAA,QAAA,GAAR,QAAQ,CAAsB;QAC7B,IAAmB,CAAA,mBAAA,GAAnB,mBAAmB,CAAqB;QACxC,IAAc,CAAA,cAAA,GAAd,cAAc,CAAgB;AAzBxC,QAAA,IAAA,CAAA,qBAAqB,GAA0B;AAC7C,YAAA,gBAAgB,EAAE,IAAI;AACtB,YAAA,iBAAiB,EAAE,IAAI;AACvB,YAAA,wBAAwB,EAAE,IAAI;SAC/B,CAAC;AAEF,QAAA,IAAA,CAAA,MAAM,GAAc;AAClB,YAAA,QAAQ,EAAE,IAAI;AACd,YAAA,MAAM,EAAE,KAAK;AACb,YAAA,SAAS,EAAE,EAAE;AACb,YAAA,gBAAgB,EAAE;AAChB,gBAAA,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;AAClB,aAAA;SACF,CAAC;AAEF,QAAA,IAAA,CAAA,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,IAAa,CAAA,aAAA,GAA+B,EAAE,CAAC;QAC/C,IAAgB,CAAA,gBAAA,GAAG,KAAK,CAAC;KASrB;AAEJ,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AACrF,QAAA,IAAI,CAAC,MAAM,GAAG,WAAoC,CAAC;KACpD;AAED,IAAA,MAAM,eAAe,GAAA;QACnB,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;KACnD;AAED,IAAA,YAAY,CAAC,KAAa,EAAA;QACxB,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAExC,IAAI,MAAM,EAAE;AACV,YAAA,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC,aAAa,CAAC,CAAA,CAAA,EAAI,KAAK,CAAC,EAAE,CAAE,CAAA,CAAC,CAAC;SAC3C;aAAM;YACL,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;AAC3C,YAAA,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,CAAC,aAAa,CAAC,CAAI,CAAA,EAAA,KAAK,CAAC,EAAE,CAAE,CAAA,CAAC,GAAG,IAAI,CAAC;SAC3C;KACF;AAED,IAAA,sBAAsB,CAAC,MAAe,EAAA;AACpC,QAAA,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpD;AAED,IAAA,cAAc,CAAC,QAAsB,EAAA;AACnC,QAAA,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACrE,QAAA,IAAI,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,CAAC;AAChD,QAAA,IAAI,CAAC,gBAAgB,GAAG,CAAC,kBAAkB,CAAC;QAE5C,IAAI,kBAAkB,EAAE;AACtB,YAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;SACvB;aAAM;AACL,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;SACtB;KACF;8GArEU,iBAAiB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAF,eAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,cAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA,EAAA;AAAjB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,iBAAiB,2DAHjB,CAAC,eAAe,EAAE,oBAAoB,CAAC,+DAIvC,YAAY,EAAA,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECjCzB,u0HAwHA,EDlGI,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,SAAS,kVACT,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,UAAA,EAAA,SAAA,EAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACf,UAAU,EAEV,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,IAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,gBAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,qBAAA,EAAA,uBAAA,EAAA,qBAAA,EAAA,oBAAA,EAAA,gBAAA,EAAA,uBAAA,EAAA,kBAAA,EAAA,2BAAA,EAAA,gCAAA,EAAA,6BAAA,EAAA,oCAAA,CAAA,EAAA,OAAA,EAAA,CAAA,aAAA,EAAA,cAAA,EAAA,yBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,cAAA,EAAA,OAAA,EAAA,WAAA,EAAA,YAAA,CAAA,EAAA,OAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,iCAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,iCAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,EAAA,OAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,eAAA,EAAA,uBAAA,EAAA,kBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,WAAW,+BACX,4BAA4B,EAAA,QAAA,EAAA,2BAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,EAAA;;2FAKnB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAd7B,SAAS;AACI,YAAA,IAAA,EAAA,CAAA,EAAA,UAAA,EAAA,IAAI,EAEP,OAAA,EAAA;wBACP,SAAS;wBACT,eAAe;wBACf,UAAU;wBACV,qBAAqB;wBACrB,WAAW;wBACX,4BAA4B;AAC7B,qBAAA,EAAA,SAAA,EACU,CAAC,eAAe,EAAE,oBAAoB,CAAC,YACxC,cAAc,EAAA,QAAA,EAAA,u0HAAA,EAAA,CAAA;mLAIxB,GAAG,EAAA,CAAA;sBADF,SAAS;uBAAC,YAAY,CAAA;;;AE5BlB,MAAM,uBAAuB,GAAyB,wBAAwB,CAAC;IACpF,kBAAkB;AAClB,IAAA,SAAS,CAAC;AACR,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,SAAS,EAAE,iBAAiB;QAC5B,OAAO,EAAE,WAAW,CAAC,MAAM;AAC3B,QAAA,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC;AAC1B,QAAA,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,CAAC,kBAAkB,CAAC;KAClC,CAAC;AACH,CAAA;;ACfD;;AAEG;;;;"}
@@ -2,7 +2,7 @@ import { NgIf, NgForOf } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
3
  import { Component, Optional, ViewChild } from '@angular/core';
4
4
  import * as i3 from '@c8y/ngx-components';
5
- import { C8yTranslatePipe, IconDirective, ModalModule, MessagesComponent, MessageDirective, C8yTranslateDirective, FormGroupComponent, BuiltInActionType, gettext as gettext$1, TitleComponent, DataGridModule, LoadingComponent, ActionBarItemComponent } from '@c8y/ngx-components';
5
+ import { C8yTranslatePipe, IconDirective, ModalModule, MessagesComponent, MessageDirective, C8yTranslateDirective, FormGroupComponent, BuiltInActionType, gettext as gettext$1, TitleComponent, DataGridModule, LoadingComponent, ActionBarItemComponent, HelpModule } from '@c8y/ngx-components';
6
6
  import * as i1$1 from '@c8y/ngx-components/translation-editor/data';
7
7
  import * as i1 from '@angular/forms';
8
8
  import { FormsModule, Validators, ReactiveFormsModule } from '@angular/forms';
@@ -212,7 +212,7 @@ class TranslationEditorComponent {
212
212
  return columns;
213
213
  }
214
214
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TranslationEditorComponent, deps: [{ token: i1$1.TranslationStoreService }, { token: i2.BsModalService }, { token: i3.AlertService }, { token: i3.AppStateService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
215
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: TranslationEditorComponent, isStandalone: true, selector: "c8y-translation-editor", ngImport: i0, template: "<c8y-title translate>Localization</c8y-title>\n\n<ng-container *ngIf=\"!isLoading; else loading\">\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"addEntry()\"\n data-cy=\"c8y-translation-editor--add-translation\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n <span translate>Add translation</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"saveTranslations()\"\n data-cy=\"c8y-translation-editor--save-and-apply\"\n >\n <i c8yIcon=\"save\"></i>\n <span translate>Save & apply</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-data-grid\n class=\"content-fullpage d-flex d-col\"\n [title]=\"'Translations' | translate\"\n [columns]=\"columns\"\n [actionControls]=\"actionControls\"\n [pagination]=\"pagination\"\n [displayOptions]=\"displayOptions\"\n (onReload)=\"refresh()\"\n [rows]=\"items\"\n ></c8y-data-grid>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "ngmodule", type: DataGridModule }, { kind: "component", type: i3.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }] }); }
215
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: TranslationEditorComponent, isStandalone: true, selector: "c8y-translation-editor", ngImport: i0, template: "<c8y-title translate>Localization</c8y-title>\n\n<ng-container *ngIf=\"!isLoading; else loading\">\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"addEntry()\"\n data-cy=\"c8y-translation-editor--add-translation\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n <span translate>Add translation</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"saveTranslations()\"\n data-cy=\"c8y-translation-editor--save-and-apply\"\n >\n <i c8yIcon=\"save\"></i>\n <span translate>Save & apply</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-help src=\"/docs/standard-tenant/changing-settings/#localization\"></c8y-help>\n\n <c8y-data-grid\n class=\"content-fullpage d-flex d-col\"\n [title]=\"'Translations' | translate\"\n [columns]=\"columns\"\n [actionControls]=\"actionControls\"\n [pagination]=\"pagination\"\n [displayOptions]=\"displayOptions\"\n (onReload)=\"refresh()\"\n [rows]=\"items\"\n ></c8y-data-grid>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "ngmodule", type: DataGridModule }, { kind: "component", type: i3.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: HelpModule }, { kind: "component", type: i3.HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }] }); }
216
216
  }
217
217
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TranslationEditorComponent, decorators: [{
218
218
  type: Component,
@@ -224,8 +224,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
224
224
  C8yTranslatePipe,
225
225
  ActionBarItemComponent,
226
226
  IconDirective,
227
- C8yTranslateDirective
228
- ], template: "<c8y-title translate>Localization</c8y-title>\n\n<ng-container *ngIf=\"!isLoading; else loading\">\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"addEntry()\"\n data-cy=\"c8y-translation-editor--add-translation\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n <span translate>Add translation</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"saveTranslations()\"\n data-cy=\"c8y-translation-editor--save-and-apply\"\n >\n <i c8yIcon=\"save\"></i>\n <span translate>Save & apply</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-data-grid\n class=\"content-fullpage d-flex d-col\"\n [title]=\"'Translations' | translate\"\n [columns]=\"columns\"\n [actionControls]=\"actionControls\"\n [pagination]=\"pagination\"\n [displayOptions]=\"displayOptions\"\n (onReload)=\"refresh()\"\n [rows]=\"items\"\n ></c8y-data-grid>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n" }]
227
+ C8yTranslateDirective,
228
+ HelpModule
229
+ ], template: "<c8y-title translate>Localization</c8y-title>\n\n<ng-container *ngIf=\"!isLoading; else loading\">\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"addEntry()\"\n data-cy=\"c8y-translation-editor--add-translation\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n <span translate>Add translation</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"saveTranslations()\"\n data-cy=\"c8y-translation-editor--save-and-apply\"\n >\n <i c8yIcon=\"save\"></i>\n <span translate>Save & apply</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-help src=\"/docs/standard-tenant/changing-settings/#localization\"></c8y-help>\n\n <c8y-data-grid\n class=\"content-fullpage d-flex d-col\"\n [title]=\"'Translations' | translate\"\n [columns]=\"columns\"\n [actionControls]=\"actionControls\"\n [pagination]=\"pagination\"\n [displayOptions]=\"displayOptions\"\n (onReload)=\"refresh()\"\n [rows]=\"items\"\n ></c8y-data-grid>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n" }]
229
230
  }], ctorParameters: () => [{ type: i1$1.TranslationStoreService }, { type: i2.BsModalService }, { type: i3.AlertService }, { type: i3.AppStateService }, { type: i3.TranslateService }] });
230
231
 
231
232
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-translation-editor-lazy.mjs","sources":["../../translation-editor/lazy/manage-translation-cell-renderer/manage-translation-cell-renderer.component.ts","../../translation-editor/lazy/manage-translation-cell-renderer/manage-translation-cell-renderer.component.html","../../translation-editor/lazy/add-translation-modal/add-translation-modal.component.ts","../../translation-editor/lazy/add-translation-modal/add-translation-modal.component.html","../../translation-editor/lazy/translation-editor/translation-editor.component.ts","../../translation-editor/lazy/translation-editor/translation-editor.component.html","../../translation-editor/lazy/c8y-ngx-components-translation-editor-lazy.ts"],"sourcesContent":["import { NgIf } from '@angular/common';\nimport { Component, ElementRef, Optional, ViewChild } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport {\n CellRendererContext,\n Permissions,\n C8yTranslatePipe,\n IconDirective\n} from '@c8y/ngx-components';\nimport { TranslationEditorComponent } from '../translation-editor/translation-editor.component';\n\n@Component({\n selector: 'c8y-manage-translation-cell-renderer',\n templateUrl: 'manage-translation-cell-renderer.component.html',\n standalone: true,\n imports: [NgIf, C8yTranslatePipe, IconDirective, FormsModule]\n})\nexport class ManageTranslationCellRendererComponent {\n private readonly FOCUS_RENDER_WAIT_TIME_IN_MS = 100;\n isCellEditable = false;\n cellValue = '';\n @ViewChild('cellInput') cellInput: ElementRef;\n isCreateDisabled = false;\n\n constructor(\n public context: CellRendererContext,\n private permissions: Permissions,\n @Optional() private grid: TranslationEditorComponent\n ) {}\n\n ngOnInit() {\n this.isCreateDisabled = !this.permissions.hasRole('ROLE_APPLICATION_MANAGEMENT_ADMIN');\n }\n\n async save(): Promise<void> {\n this.isCellEditable = false;\n const cellValueTrimed = this.cellValue.trim();\n this.context.value = cellValueTrimed;\n this.context.item[this.context.property.path] = cellValueTrimed;\n this.grid?.valueChanged();\n }\n\n cancel(): void {\n this.isCellEditable = false;\n }\n\n editCell(): void {\n this.cellValue = this.context.value;\n this.isCellEditable = true;\n\n // Focuses the input box after the input text box is visible\n setTimeout(() => {\n this.cellInput.nativeElement.focus();\n }, this.FOCUS_RENDER_WAIT_TIME_IN_MS);\n }\n}\n","<div\n class=\"text-truncate pointer d-flex\"\n title=\"{{ context.value }}\"\n data-cy=\"c8y-manage-translation-cell-renderer--edit\"\n (click)=\"!isCreateDisabled ? editCell() : ''\"\n *ngIf=\"!isCellEditable\"\n>\n <span\n class=\"text-truncate\"\n *ngIf=\"!isCellEditable && context.value !== ''\"\n >\n {{ context.value }}\n </span>\n <span\n class=\"text-truncate\"\n title=\"{{ 'Add translation' | translate }}\"\n *ngIf=\"!isCellEditable && context.value === ''\"\n >\n <em class=\"text-muted\">{{ 'Add translation' | translate }}</em>\n </span>\n <i\n class=\"showOnHover text-primary m-l-4\"\n c8yIcon=\"pencil\"\n title=\"{{ 'Edit translation' | translate }}\"\n *ngIf=\"!isCreateDisabled\"\n ></i>\n</div>\n\n<div\n class=\"input-group input-group-sm\"\n *ngIf=\"isCellEditable && !isCreateDisabled\"\n>\n <input\n class=\"form-control\"\n placeholder=\"{{ 'Add translation' | translate }}\"\n type=\"text\"\n #cellInput\n data-cy=\"c8y-manage-translation-cell-renderer--input\"\n [(ngModel)]=\"cellValue\"\n />\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-clean\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n data-cy=\"c8y-manage-translation-cell-renderer--cancel\"\n >\n <i\n class=\"text-danger\"\n c8yIcon=\"times\"\n ></i>\n </button>\n <button\n class=\"btn btn-clean\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n (click)=\"save()\"\n data-cy=\"c8y-manage-translation-cell-renderer--save\"\n >\n <i\n class=\"text-primary\"\n c8yIcon=\"check\"\n ></i>\n </button>\n </div>\n</div>\n","import { NgForOf } from '@angular/common';\nimport { Component, OnInit } from '@angular/core';\nimport {\n AbstractControl,\n FormBuilder,\n ReactiveFormsModule,\n ValidatorFn,\n Validators\n} from '@angular/forms';\nimport {\n C8yTranslateDirective,\n C8yTranslatePipe,\n FormGroupComponent,\n IconDirective,\n MessageDirective,\n MessagesComponent,\n ModalModule\n} from '@c8y/ngx-components';\nimport { gettext } from '@c8y/ngx-components/gettext';\n\n@Component({\n selector: 'c8y-add-translation-modal',\n templateUrl: './add-translation-modal.component.html',\n standalone: true,\n imports: [\n ModalModule,\n IconDirective,\n MessagesComponent,\n MessageDirective,\n C8yTranslatePipe,\n C8yTranslateDirective,\n ReactiveFormsModule,\n NgForOf,\n FormGroupComponent\n ]\n})\nexport class AddTranslationModalComponent implements OnInit {\n readonly title = gettext('Add translation');\n form: ReturnType<typeof this.initForm>;\n\n result = new Promise<ReturnType<typeof this.initForm>['value']>((resolve, reject) => {\n this._resovle = resolve;\n this._reject = reject;\n });\n alreadyTakenMsg = gettext('The provided translation key has already been defined.');\n alreadyDefinedKeys: string[] = [];\n availableLangs: {\n lang: string;\n nativeLanguage: string;\n }[] = [];\n\n private _resovle: (value: ReturnType<typeof this.initForm>['value']) => void;\n private _reject: (reason?: any) => void;\n\n constructor(private formBuilder: FormBuilder) {}\n\n ngOnInit(): void {\n this.form = this.initForm();\n }\n\n initForm() {\n return this.formBuilder.group({\n key: ['', [Validators.required, this.ensureNotExistingKey()]],\n ...this.availableLangs\n .map(language => {\n return {\n [language.lang]: ['']\n };\n })\n .reduceRight((acc, curr) => ({ ...curr, ...acc }), {})\n });\n }\n\n cancel() {\n this._reject();\n }\n\n save() {\n this._resovle(this.form.value);\n }\n\n private ensureNotExistingKey(): ValidatorFn {\n return (control: AbstractControl) => {\n if (typeof control.value === 'string') {\n const keyAlreadyTaken = this.alreadyDefinedKeys.some(name => name === control.value);\n if (keyAlreadyTaken) {\n return { keyAlreadyTaken: {} };\n }\n }\n return null;\n };\n }\n}\n","<c8y-modal\n [title]=\"title\"\n [headerClasses]=\"'dialog-header'\"\n (onDismiss)=\"cancel()\"\n (onClose)=\"save()\"\n [disabled]=\"form.invalid\"\n [labels]=\"{ cancel: 'Cancel', ok: 'Add' }\"\n>\n<ng-container c8y-modal-title>\n <span [c8yIcon]=\"'language1'\"></span>\n</ng-container>\n <div [formGroup]=\"form\" class=\"p-24\">\n <c8y-form-group>\n <label\n for=\"label\"\n translate\n >\n Translation key\n </label>\n <input\n class=\"form-control\"\n name=\"key\"\n id=\"key\"\n type=\"text\"\n formControlName=\"key\"\n placeholder=\"{{'e.g. {{ example }}' | translate : { example: 'Home' } }}\"\n />\n <c8y-messages>\n <c8y-message\n name=\"keyAlreadyTaken\"\n [text]=\"alreadyTakenMsg | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group *ngFor=\"let language of availableLangs\">\n <label\n [for]=\"language.lang\"\n >\n {{ language.nativeLanguage }} ({{ language.lang }})\n </label>\n <input\n class=\"form-control\"\n [name]=\"language.lang\"\n [id]=\"language.lang\"\n type=\"text\"\n [formControlName]=\"language.lang\"\n />\n </c8y-form-group>\n </div>\n</c8y-modal>\n","import { NgIf } from '@angular/common';\nimport { Component, OnInit } from '@angular/core';\nimport {\n ActionBarItemComponent,\n ActionControl,\n AlertService,\n AppStateService,\n BuiltInActionType,\n C8yTranslateDirective,\n C8yTranslatePipe,\n Column,\n DataGridModule,\n DisplayOptions,\n gettext,\n IconDirective,\n LoadingComponent,\n Pagination,\n TitleComponent,\n TranslateService\n} from '@c8y/ngx-components';\nimport { TranslationStoreService } from '@c8y/ngx-components/translation-editor/data';\nimport { ManageTranslationCellRendererComponent } from '../manage-translation-cell-renderer/manage-translation-cell-renderer.component';\nimport { BsModalService } from 'ngx-bootstrap/modal';\nimport { AddTranslationModalComponent } from '../add-translation-modal/add-translation-modal.component';\n\n@Component({\n selector: 'c8y-translation-editor',\n templateUrl: './translation-editor.component.html',\n standalone: true,\n imports: [\n TitleComponent,\n DataGridModule,\n LoadingComponent,\n NgIf,\n C8yTranslatePipe,\n ActionBarItemComponent,\n IconDirective,\n C8yTranslateDirective\n ]\n})\nexport class TranslationEditorComponent implements OnInit {\n pagination: Pagination = {\n pageSize: 10,\n currentPage: 1\n };\n displayOptions: DisplayOptions = {\n bordered: false,\n striped: true,\n filter: true,\n gridHeader: true,\n hover: true\n };\n actionControls: ActionControl[] = [\n {\n type: BuiltInActionType.Delete,\n callback: item => {\n this.items = this.items.filter(i => i.key !== item.key);\n }\n }\n ];\n columns: Column[] = [];\n isLoading = true;\n items: Awaited<ReturnType<TranslationStoreService['getCombinedListOfTranslationsForPerKey']>> =\n new Array<any>();\n isHavingChanges = false;\n availableLangs: {\n lang: string;\n nativeLanguage: string;\n }[] = [];\n\n constructor(\n private translationStore: TranslationStoreService,\n private modalService: BsModalService,\n private alert: AlertService,\n private appState: AppStateService,\n private translate: TranslateService\n ) {\n this.availableLangs = (this.appState.state.langs as string[])\n .sort((a, b) => a.localeCompare(b))\n .map(l => ({\n lang: l,\n nativeLanguage: this.translate.getNativeLanguage(l)\n }));\n }\n\n async ngOnInit() {\n this.refresh();\n }\n\n async refresh() {\n this.isLoading = true;\n this.refreshColumns();\n\n const translations = await this.translationStore.getCombinedListOfTranslationsForPerKey(\n this.availableLangs.map(l => l.lang)\n );\n\n this.items = translations;\n\n this.isLoading = false;\n }\n\n async addEntry() {\n const currentKeys = this.items.map(item => item.key);\n const modalRef = this.modalService.show(AddTranslationModalComponent, {\n initialState: { alreadyDefinedKeys: currentKeys, availableLangs: this.availableLangs }\n });\n try {\n const result = await modalRef.content.result;\n this.items = [...this.items, result as any];\n } catch (e) {\n // do nothing, modal was closed.\n }\n }\n\n refreshColumns() {\n this.columns = this.getColumnsForLocales();\n }\n\n valueChanged() {\n this.isHavingChanges = true;\n }\n\n async saveTranslations() {\n try {\n await this.translationStore.updateTranslations(this.items);\n await this.refresh();\n this.alert.success(gettext('Translations saved'));\n } catch (e) {\n this.alert.danger(gettext('Failed to save translations'));\n this.alert.addServerFailure(e);\n }\n }\n\n private getColumnsForLocales() {\n const columns = new Array<Column>();\n columns.push({\n name: 'key',\n header: gettext('Translation key'),\n path: 'key',\n filterable: true\n });\n\n columns.push(\n ...this.availableLangs.map(\n (language, index) =>\n ({\n name: language.lang,\n header: `${language.nativeLanguage} (${language.lang})`,\n path: language.lang,\n filterable: false,\n visible: index < 5,\n cellRendererComponent: ManageTranslationCellRendererComponent\n }) as Column\n )\n );\n\n return columns;\n }\n}\n","<c8y-title translate>Localization</c8y-title>\n\n<ng-container *ngIf=\"!isLoading; else loading\">\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"addEntry()\"\n data-cy=\"c8y-translation-editor--add-translation\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n <span translate>Add translation</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"saveTranslations()\"\n data-cy=\"c8y-translation-editor--save-and-apply\"\n >\n <i c8yIcon=\"save\"></i>\n <span translate>Save & apply</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-data-grid\n class=\"content-fullpage d-flex d-col\"\n [title]=\"'Translations' | translate\"\n [columns]=\"columns\"\n [actionControls]=\"actionControls\"\n [pagination]=\"pagination\"\n [displayOptions]=\"displayOptions\"\n (onReload)=\"refresh()\"\n [rows]=\"items\"\n ></c8y-data-grid>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2.TranslationEditorComponent","i3","i2","gettext"],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-translation-editor-lazy.mjs","sources":["../../translation-editor/lazy/manage-translation-cell-renderer/manage-translation-cell-renderer.component.ts","../../translation-editor/lazy/manage-translation-cell-renderer/manage-translation-cell-renderer.component.html","../../translation-editor/lazy/add-translation-modal/add-translation-modal.component.ts","../../translation-editor/lazy/add-translation-modal/add-translation-modal.component.html","../../translation-editor/lazy/translation-editor/translation-editor.component.ts","../../translation-editor/lazy/translation-editor/translation-editor.component.html","../../translation-editor/lazy/c8y-ngx-components-translation-editor-lazy.ts"],"sourcesContent":["import { NgIf } from '@angular/common';\nimport { Component, ElementRef, Optional, ViewChild } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport {\n CellRendererContext,\n Permissions,\n C8yTranslatePipe,\n IconDirective\n} from '@c8y/ngx-components';\nimport { TranslationEditorComponent } from '../translation-editor/translation-editor.component';\n\n@Component({\n selector: 'c8y-manage-translation-cell-renderer',\n templateUrl: 'manage-translation-cell-renderer.component.html',\n standalone: true,\n imports: [NgIf, C8yTranslatePipe, IconDirective, FormsModule]\n})\nexport class ManageTranslationCellRendererComponent {\n private readonly FOCUS_RENDER_WAIT_TIME_IN_MS = 100;\n isCellEditable = false;\n cellValue = '';\n @ViewChild('cellInput') cellInput: ElementRef;\n isCreateDisabled = false;\n\n constructor(\n public context: CellRendererContext,\n private permissions: Permissions,\n @Optional() private grid: TranslationEditorComponent\n ) {}\n\n ngOnInit() {\n this.isCreateDisabled = !this.permissions.hasRole('ROLE_APPLICATION_MANAGEMENT_ADMIN');\n }\n\n async save(): Promise<void> {\n this.isCellEditable = false;\n const cellValueTrimed = this.cellValue.trim();\n this.context.value = cellValueTrimed;\n this.context.item[this.context.property.path] = cellValueTrimed;\n this.grid?.valueChanged();\n }\n\n cancel(): void {\n this.isCellEditable = false;\n }\n\n editCell(): void {\n this.cellValue = this.context.value;\n this.isCellEditable = true;\n\n // Focuses the input box after the input text box is visible\n setTimeout(() => {\n this.cellInput.nativeElement.focus();\n }, this.FOCUS_RENDER_WAIT_TIME_IN_MS);\n }\n}\n","<div\n class=\"text-truncate pointer d-flex\"\n title=\"{{ context.value }}\"\n data-cy=\"c8y-manage-translation-cell-renderer--edit\"\n (click)=\"!isCreateDisabled ? editCell() : ''\"\n *ngIf=\"!isCellEditable\"\n>\n <span\n class=\"text-truncate\"\n *ngIf=\"!isCellEditable && context.value !== ''\"\n >\n {{ context.value }}\n </span>\n <span\n class=\"text-truncate\"\n title=\"{{ 'Add translation' | translate }}\"\n *ngIf=\"!isCellEditable && context.value === ''\"\n >\n <em class=\"text-muted\">{{ 'Add translation' | translate }}</em>\n </span>\n <i\n class=\"showOnHover text-primary m-l-4\"\n c8yIcon=\"pencil\"\n title=\"{{ 'Edit translation' | translate }}\"\n *ngIf=\"!isCreateDisabled\"\n ></i>\n</div>\n\n<div\n class=\"input-group input-group-sm\"\n *ngIf=\"isCellEditable && !isCreateDisabled\"\n>\n <input\n class=\"form-control\"\n placeholder=\"{{ 'Add translation' | translate }}\"\n type=\"text\"\n #cellInput\n data-cy=\"c8y-manage-translation-cell-renderer--input\"\n [(ngModel)]=\"cellValue\"\n />\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-clean\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n data-cy=\"c8y-manage-translation-cell-renderer--cancel\"\n >\n <i\n class=\"text-danger\"\n c8yIcon=\"times\"\n ></i>\n </button>\n <button\n class=\"btn btn-clean\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n (click)=\"save()\"\n data-cy=\"c8y-manage-translation-cell-renderer--save\"\n >\n <i\n class=\"text-primary\"\n c8yIcon=\"check\"\n ></i>\n </button>\n </div>\n</div>\n","import { NgForOf } from '@angular/common';\nimport { Component, OnInit } from '@angular/core';\nimport {\n AbstractControl,\n FormBuilder,\n ReactiveFormsModule,\n ValidatorFn,\n Validators\n} from '@angular/forms';\nimport {\n C8yTranslateDirective,\n C8yTranslatePipe,\n FormGroupComponent,\n IconDirective,\n MessageDirective,\n MessagesComponent,\n ModalModule\n} from '@c8y/ngx-components';\nimport { gettext } from '@c8y/ngx-components/gettext';\n\n@Component({\n selector: 'c8y-add-translation-modal',\n templateUrl: './add-translation-modal.component.html',\n standalone: true,\n imports: [\n ModalModule,\n IconDirective,\n MessagesComponent,\n MessageDirective,\n C8yTranslatePipe,\n C8yTranslateDirective,\n ReactiveFormsModule,\n NgForOf,\n FormGroupComponent\n ]\n})\nexport class AddTranslationModalComponent implements OnInit {\n readonly title = gettext('Add translation');\n form: ReturnType<typeof this.initForm>;\n\n result = new Promise<ReturnType<typeof this.initForm>['value']>((resolve, reject) => {\n this._resovle = resolve;\n this._reject = reject;\n });\n alreadyTakenMsg = gettext('The provided translation key has already been defined.');\n alreadyDefinedKeys: string[] = [];\n availableLangs: {\n lang: string;\n nativeLanguage: string;\n }[] = [];\n\n private _resovle: (value: ReturnType<typeof this.initForm>['value']) => void;\n private _reject: (reason?: any) => void;\n\n constructor(private formBuilder: FormBuilder) {}\n\n ngOnInit(): void {\n this.form = this.initForm();\n }\n\n initForm() {\n return this.formBuilder.group({\n key: ['', [Validators.required, this.ensureNotExistingKey()]],\n ...this.availableLangs\n .map(language => {\n return {\n [language.lang]: ['']\n };\n })\n .reduceRight((acc, curr) => ({ ...curr, ...acc }), {})\n });\n }\n\n cancel() {\n this._reject();\n }\n\n save() {\n this._resovle(this.form.value);\n }\n\n private ensureNotExistingKey(): ValidatorFn {\n return (control: AbstractControl) => {\n if (typeof control.value === 'string') {\n const keyAlreadyTaken = this.alreadyDefinedKeys.some(name => name === control.value);\n if (keyAlreadyTaken) {\n return { keyAlreadyTaken: {} };\n }\n }\n return null;\n };\n }\n}\n","<c8y-modal\n [title]=\"title\"\n [headerClasses]=\"'dialog-header'\"\n (onDismiss)=\"cancel()\"\n (onClose)=\"save()\"\n [disabled]=\"form.invalid\"\n [labels]=\"{ cancel: 'Cancel', ok: 'Add' }\"\n>\n<ng-container c8y-modal-title>\n <span [c8yIcon]=\"'language1'\"></span>\n</ng-container>\n <div [formGroup]=\"form\" class=\"p-24\">\n <c8y-form-group>\n <label\n for=\"label\"\n translate\n >\n Translation key\n </label>\n <input\n class=\"form-control\"\n name=\"key\"\n id=\"key\"\n type=\"text\"\n formControlName=\"key\"\n placeholder=\"{{'e.g. {{ example }}' | translate : { example: 'Home' } }}\"\n />\n <c8y-messages>\n <c8y-message\n name=\"keyAlreadyTaken\"\n [text]=\"alreadyTakenMsg | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group *ngFor=\"let language of availableLangs\">\n <label\n [for]=\"language.lang\"\n >\n {{ language.nativeLanguage }} ({{ language.lang }})\n </label>\n <input\n class=\"form-control\"\n [name]=\"language.lang\"\n [id]=\"language.lang\"\n type=\"text\"\n [formControlName]=\"language.lang\"\n />\n </c8y-form-group>\n </div>\n</c8y-modal>\n","import { NgIf } from '@angular/common';\nimport { Component, OnInit } from '@angular/core';\nimport {\n ActionBarItemComponent,\n ActionControl,\n AlertService,\n AppStateService,\n BuiltInActionType,\n C8yTranslateDirective,\n C8yTranslatePipe,\n Column,\n DataGridModule,\n DisplayOptions,\n gettext,\n HelpModule,\n IconDirective,\n LoadingComponent,\n Pagination,\n TitleComponent,\n TranslateService\n} from '@c8y/ngx-components';\nimport { TranslationStoreService } from '@c8y/ngx-components/translation-editor/data';\nimport { ManageTranslationCellRendererComponent } from '../manage-translation-cell-renderer/manage-translation-cell-renderer.component';\nimport { BsModalService } from 'ngx-bootstrap/modal';\nimport { AddTranslationModalComponent } from '../add-translation-modal/add-translation-modal.component';\n\n@Component({\n selector: 'c8y-translation-editor',\n templateUrl: './translation-editor.component.html',\n standalone: true,\n imports: [\n TitleComponent,\n DataGridModule,\n LoadingComponent,\n NgIf,\n C8yTranslatePipe,\n ActionBarItemComponent,\n IconDirective,\n C8yTranslateDirective,\n HelpModule\n ]\n})\nexport class TranslationEditorComponent implements OnInit {\n pagination: Pagination = {\n pageSize: 10,\n currentPage: 1\n };\n displayOptions: DisplayOptions = {\n bordered: false,\n striped: true,\n filter: true,\n gridHeader: true,\n hover: true\n };\n actionControls: ActionControl[] = [\n {\n type: BuiltInActionType.Delete,\n callback: item => {\n this.items = this.items.filter(i => i.key !== item.key);\n }\n }\n ];\n columns: Column[] = [];\n isLoading = true;\n items: Awaited<ReturnType<TranslationStoreService['getCombinedListOfTranslationsForPerKey']>> =\n new Array<any>();\n isHavingChanges = false;\n availableLangs: {\n lang: string;\n nativeLanguage: string;\n }[] = [];\n\n constructor(\n private translationStore: TranslationStoreService,\n private modalService: BsModalService,\n private alert: AlertService,\n private appState: AppStateService,\n private translate: TranslateService\n ) {\n this.availableLangs = (this.appState.state.langs as string[])\n .sort((a, b) => a.localeCompare(b))\n .map(l => ({\n lang: l,\n nativeLanguage: this.translate.getNativeLanguage(l)\n }));\n }\n\n async ngOnInit() {\n this.refresh();\n }\n\n async refresh() {\n this.isLoading = true;\n this.refreshColumns();\n\n const translations = await this.translationStore.getCombinedListOfTranslationsForPerKey(\n this.availableLangs.map(l => l.lang)\n );\n\n this.items = translations;\n\n this.isLoading = false;\n }\n\n async addEntry() {\n const currentKeys = this.items.map(item => item.key);\n const modalRef = this.modalService.show(AddTranslationModalComponent, {\n initialState: { alreadyDefinedKeys: currentKeys, availableLangs: this.availableLangs }\n });\n try {\n const result = await modalRef.content.result;\n this.items = [...this.items, result as any];\n } catch (e) {\n // do nothing, modal was closed.\n }\n }\n\n refreshColumns() {\n this.columns = this.getColumnsForLocales();\n }\n\n valueChanged() {\n this.isHavingChanges = true;\n }\n\n async saveTranslations() {\n try {\n await this.translationStore.updateTranslations(this.items);\n await this.refresh();\n this.alert.success(gettext('Translations saved'));\n } catch (e) {\n this.alert.danger(gettext('Failed to save translations'));\n this.alert.addServerFailure(e);\n }\n }\n\n private getColumnsForLocales() {\n const columns = new Array<Column>();\n columns.push({\n name: 'key',\n header: gettext('Translation key'),\n path: 'key',\n filterable: true\n });\n\n columns.push(\n ...this.availableLangs.map(\n (language, index) =>\n ({\n name: language.lang,\n header: `${language.nativeLanguage} (${language.lang})`,\n path: language.lang,\n filterable: false,\n visible: index < 5,\n cellRendererComponent: ManageTranslationCellRendererComponent\n }) as Column\n )\n );\n\n return columns;\n }\n}\n","<c8y-title translate>Localization</c8y-title>\n\n<ng-container *ngIf=\"!isLoading; else loading\">\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"addEntry()\"\n data-cy=\"c8y-translation-editor--add-translation\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n <span translate>Add translation</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"saveTranslations()\"\n data-cy=\"c8y-translation-editor--save-and-apply\"\n >\n <i c8yIcon=\"save\"></i>\n <span translate>Save & apply</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-help src=\"/docs/standard-tenant/changing-settings/#localization\"></c8y-help>\n\n <c8y-data-grid\n class=\"content-fullpage d-flex d-col\"\n [title]=\"'Translations' | translate\"\n [columns]=\"columns\"\n [actionControls]=\"actionControls\"\n [pagination]=\"pagination\"\n [displayOptions]=\"displayOptions\"\n (onReload)=\"refresh()\"\n [rows]=\"items\"\n ></c8y-data-grid>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2.TranslationEditorComponent","i3","i2","gettext"],"mappings":";;;;;;;;;;;MAiBa,sCAAsC,CAAA;AAOjD,IAAA,WAAA,CACS,OAA4B,EAC3B,WAAwB,EACZ,IAAgC,EAAA;QAF7C,IAAO,CAAA,OAAA,GAAP,OAAO,CAAqB;QAC3B,IAAW,CAAA,WAAA,GAAX,WAAW,CAAa;QACZ,IAAI,CAAA,IAAA,GAAJ,IAAI,CAA4B;QATrC,IAA4B,CAAA,4BAAA,GAAG,GAAG,CAAC;QACpD,IAAc,CAAA,cAAA,GAAG,KAAK,CAAC;QACvB,IAAS,CAAA,SAAA,GAAG,EAAE,CAAC;QAEf,IAAgB,CAAA,gBAAA,GAAG,KAAK,CAAC;KAMrB;IAEJ,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,gBAAgB,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;KACxF;AAED,IAAA,MAAM,IAAI,GAAA;AACR,QAAA,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;AAC9C,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,eAAe,CAAC;AACrC,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC;AAChE,QAAA,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;KAC3B;IAED,MAAM,GAAA;AACJ,QAAA,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;KAC7B;IAED,QAAQ,GAAA;QACN,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;AACpC,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;;QAG3B,UAAU,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;AACvC,SAAC,EAAE,IAAI,CAAC,4BAA4B,CAAC,CAAC;KACvC;8GArCU,sCAAsC,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,EAAA,CAAA,mBAAA,EAAA,EAAA,EAAA,KAAA,EAAAA,EAAA,CAAA,WAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,0BAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA,EAAA;kGAAtC,sCAAsC,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sCAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,WAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,WAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECjBnD,2tDAmEA,EDpDY,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,IAAI,wFAAE,gBAAgB,EAAA,IAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,aAAa,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,EAAA;;2FAEjD,sCAAsC,EAAA,UAAA,EAAA,CAAA;kBANlD,SAAS;+BACE,sCAAsC,EAAA,UAAA,EAEpC,IAAI,EAAA,OAAA,EACP,CAAC,IAAI,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,CAAC,EAAA,QAAA,EAAA,2tDAAA,EAAA,CAAA;;0BAY1D,QAAQ;yCANa,SAAS,EAAA,CAAA;sBAAhC,SAAS;uBAAC,WAAW,CAAA;;;MEeX,4BAA4B,CAAA;AAkBvC,IAAA,WAAA,CAAoB,WAAwB,EAAA;QAAxB,IAAW,CAAA,WAAA,GAAX,WAAW,CAAa;AAjBnC,QAAA,IAAA,CAAA,KAAK,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAG5C,IAAM,CAAA,MAAA,GAAG,IAAI,OAAO,CAA4C,CAAC,OAAO,EAAE,MAAM,KAAI;AAClF,YAAA,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;AACxB,YAAA,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;AACxB,SAAC,CAAC,CAAC;AACH,QAAA,IAAA,CAAA,eAAe,GAAG,OAAO,CAAC,wDAAwD,CAAC,CAAC;QACpF,IAAkB,CAAA,kBAAA,GAAa,EAAE,CAAC;QAClC,IAAc,CAAA,cAAA,GAGR,EAAE,CAAC;KAKuC;IAEhD,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;KAC7B;IAED,QAAQ,GAAA;AACN,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAC5B,YAAA,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;YAC7D,GAAG,IAAI,CAAC,cAAc;iBACnB,GAAG,CAAC,QAAQ,IAAG;gBACd,OAAO;AACL,oBAAA,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;iBACtB,CAAC;AACJ,aAAC,CAAC;AACD,iBAAA,WAAW,CAAC,CAAC,GAAG,EAAE,IAAI,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AACzD,SAAA,CAAC,CAAC;KACJ;IAED,MAAM,GAAA;QACJ,IAAI,CAAC,OAAO,EAAE,CAAC;KAChB;IAED,IAAI,GAAA;QACF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KAChC;IAEO,oBAAoB,GAAA;QAC1B,OAAO,CAAC,OAAwB,KAAI;AAClC,YAAA,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE;AACrC,gBAAA,MAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;gBACrF,IAAI,eAAe,EAAE;AACnB,oBAAA,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;iBAChC;aACF;AACD,YAAA,OAAO,IAAI,CAAC;AACd,SAAC,CAAC;KACH;8GAvDU,4BAA4B,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,WAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA,EAAA;AAA5B,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,4BAA4B,qFCpCzC,q0CAmDA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED1BI,WAAW,EACX,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,OAAA,EAAA,SAAA,EAAA,OAAA,EAAA,MAAA,EAAA,cAAA,EAAA,eAAA,EAAA,QAAA,CAAA,EAAA,OAAA,EAAA,CAAA,WAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,aAAa,2EACb,iBAAiB,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACjB,gBAAgB,EAChB,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,gBAAgB,kDAChB,qBAAqB,EAAA,QAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACrB,mBAAmB,EACnB,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,0FAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,OAAO,mHACP,kBAAkB,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,YAAA,EAAA,YAAA,EAAA,cAAA,EAAA,QAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,EAAA;;2FAGT,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBAhBxC,SAAS;+BACE,2BAA2B,EAAA,UAAA,EAEzB,IAAI,EACP,OAAA,EAAA;wBACP,WAAW;wBACX,aAAa;wBACb,iBAAiB;wBACjB,gBAAgB;wBAChB,gBAAgB;wBAChB,qBAAqB;wBACrB,mBAAmB;wBACnB,OAAO;wBACP,kBAAkB;AACnB,qBAAA,EAAA,QAAA,EAAA,q0CAAA,EAAA,CAAA;;;MEQU,0BAA0B,CAAA;IA8BrC,WACU,CAAA,gBAAyC,EACzC,YAA4B,EAC5B,KAAmB,EACnB,QAAyB,EACzB,SAA2B,EAAA;QAJ3B,IAAgB,CAAA,gBAAA,GAAhB,gBAAgB,CAAyB;QACzC,IAAY,CAAA,YAAA,GAAZ,YAAY,CAAgB;QAC5B,IAAK,CAAA,KAAA,GAAL,KAAK,CAAc;QACnB,IAAQ,CAAA,QAAA,GAAR,QAAQ,CAAiB;QACzB,IAAS,CAAA,SAAA,GAAT,SAAS,CAAkB;AAlCrC,QAAA,IAAA,CAAA,UAAU,GAAe;AACvB,YAAA,QAAQ,EAAE,EAAE;AACZ,YAAA,WAAW,EAAE,CAAC;SACf,CAAC;AACF,QAAA,IAAA,CAAA,cAAc,GAAmB;AAC/B,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,OAAO,EAAE,IAAI;AACb,YAAA,MAAM,EAAE,IAAI;AACZ,YAAA,UAAU,EAAE,IAAI;AAChB,YAAA,KAAK,EAAE,IAAI;SACZ,CAAC;AACF,QAAA,IAAA,CAAA,cAAc,GAAoB;AAChC,YAAA;gBACE,IAAI,EAAE,iBAAiB,CAAC,MAAM;gBAC9B,QAAQ,EAAE,IAAI,IAAG;oBACf,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;iBACzD;AACF,aAAA;SACF,CAAC;QACF,IAAO,CAAA,OAAA,GAAa,EAAE,CAAC;QACvB,IAAS,CAAA,SAAA,GAAG,IAAI,CAAC;AACjB,QAAA,IAAA,CAAA,KAAK,GACH,IAAI,KAAK,EAAO,CAAC;QACnB,IAAe,CAAA,eAAA,GAAG,KAAK,CAAC;QACxB,IAAc,CAAA,cAAA,GAGR,EAAE,CAAC;QASP,IAAI,CAAC,cAAc,GAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAkB;AAC1D,aAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAClC,aAAA,GAAG,CAAC,CAAC,KAAK;AACT,YAAA,IAAI,EAAE,CAAC;YACP,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACpD,SAAA,CAAC,CAAC,CAAC;KACP;AAED,IAAA,MAAM,QAAQ,GAAA;QACZ,IAAI,CAAC,OAAO,EAAE,CAAC;KAChB;AAED,IAAA,MAAM,OAAO,GAAA;AACX,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,cAAc,EAAE,CAAC;QAEtB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,sCAAsC,CACrF,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CACrC,CAAC;AAEF,QAAA,IAAI,CAAC,KAAK,GAAG,YAAY,CAAC;AAE1B,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;KACxB;AAED,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,4BAA4B,EAAE;YACpE,YAAY,EAAE,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE;AACvF,SAAA,CAAC,CAAC;AACH,QAAA,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;YAC7C,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,MAAa,CAAC,CAAC;SAC7C;QAAC,OAAO,CAAC,EAAE;;SAEX;KACF;IAED,cAAc,GAAA;AACZ,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;KAC5C;IAED,YAAY,GAAA;AACV,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;KAC7B;AAED,IAAA,MAAM,gBAAgB,GAAA;AACpB,QAAA,IAAI;YACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3D,YAAA,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,KAAK,CAAC,OAAO,CAACC,SAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC;SACnD;QAAC,OAAO,CAAC,EAAE;YACV,IAAI,CAAC,KAAK,CAAC,MAAM,CAACA,SAAO,CAAC,6BAA6B,CAAC,CAAC,CAAC;AAC1D,YAAA,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;SAChC;KACF;IAEO,oBAAoB,GAAA;AAC1B,QAAA,MAAM,OAAO,GAAG,IAAI,KAAK,EAAU,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC;AACX,YAAA,IAAI,EAAE,KAAK;AACX,YAAA,MAAM,EAAEA,SAAO,CAAC,iBAAiB,CAAC;AAClC,YAAA,IAAI,EAAE,KAAK;AACX,YAAA,UAAU,EAAE,IAAI;AACjB,SAAA,CAAC,CAAC;AAEH,QAAA,OAAO,CAAC,IAAI,CACV,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CACxB,CAAC,QAAQ,EAAE,KAAK,MACb;YACC,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,MAAM,EAAE,GAAG,QAAQ,CAAC,cAAc,CAAK,EAAA,EAAA,QAAQ,CAAC,IAAI,CAAG,CAAA,CAAA;YACvD,IAAI,EAAE,QAAQ,CAAC,IAAI;AACnB,YAAA,UAAU,EAAE,KAAK;YACjB,OAAO,EAAE,KAAK,GAAG,CAAC;AAClB,YAAA,qBAAqB,EAAE,sCAAsC;SAC9D,CAAW,CACf,CACF,CAAC;AAEF,QAAA,OAAO,OAAO,CAAC;KAChB;8GAtHU,0BAA0B,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAJ,IAAA,CAAA,uBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,cAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,YAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,eAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA,EAAA;AAA1B,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,0BAA0B,kFC1CvC,wsCA0CA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDXI,cAAc,EACd,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,cAAc,uyBACd,gBAAgB,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAChB,IAAI,EACJ,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,gBAAgB,kDAChB,sBAAsB,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,UAAA,EAAA,SAAA,EAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACtB,aAAa,EACb,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,qBAAqB,uEACrB,UAAU,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,KAAA,EAAA,aAAA,EAAA,UAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,EAAA;;2FAGD,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBAhBtC,SAAS;+BACE,wBAAwB,EAAA,UAAA,EAEtB,IAAI,EACP,OAAA,EAAA;wBACP,cAAc;wBACd,cAAc;wBACd,gBAAgB;wBAChB,IAAI;wBACJ,gBAAgB;wBAChB,sBAAsB;wBACtB,aAAa;wBACb,qBAAqB;wBACrB,UAAU;AACX,qBAAA,EAAA,QAAA,EAAA,wsCAAA,EAAA,CAAA;;;AExCH;;AAEG;;;;"}
@@ -10238,8 +10238,7 @@ class AppIconComponent {
10238
10238
  'background-repeat': 'no-repeat',
10239
10239
  'background-size': 'contain',
10240
10240
  'background-position': 'center',
10241
- height: '36px',
10242
- width: '100%'
10241
+ 'aspect-ratio': '1'
10243
10242
  };
10244
10243
  this.faIconMatch = /fa-/;
10245
10244
  this.c8yMatch = /^c8y-/;
@@ -10289,7 +10288,8 @@ class AppIconComponent {
10289
10288
  this.model.iconClass = [
10290
10289
  'c8y-icon',
10291
10290
  this.mapFontAwesomeToDelightIcons(this.model.appIcon),
10292
- this.white ? 'c8y-icon-white' : 'c8y-icon-duocolor'
10291
+ this.white ? 'c8y-icon-white' : 'c8y-icon-duocolor',
10292
+ !isEmpty(this.model.iconStyle) ? 'app-img-icon' : ''
10293
10293
  ].filter(c => !!c);
10294
10294
  const name = this.name || this.app?.name || '';
10295
10295
  this.model.appNameAbbr = name.substring(0, 2);
@@ -33800,11 +33800,11 @@ class TimeIntervalComponent {
33800
33800
  }
33801
33801
  }
33802
33802
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TimeIntervalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33803
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: TimeIntervalComponent, isStandalone: true, selector: "c8y-time-interval", inputs: { minCustomDate: "minCustomDate", maxCustomDate: "maxCustomDate", dateRangePickerConfig: "dateRangePickerConfig", selectedInterval: "selectedInterval" }, outputs: { interval: "interval" }, ngImport: i0, template: "<form class=\"form-inline\">\n <div class=\"form-group\">\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n [attr.aria-label]=\"'Time interval' | translate\"\n name=\"interval\"\n [(ngModel)]=\"selectedInterval\"\n (ngModelChange)=\"changeInterval($event)\"\n >\n <option\n *ngFor=\"let interval of intvervals\"\n [ngValue]=\"interval\"\n >\n {{ interval.label | translate }}\n </option>\n </select>\n </div>\n </div>\n\n <div\n class=\"form-group datepicker\"\n *ngIf=\"selectedInterval === CUSTOM\"\n >\n <input\n class=\"form-control\"\n [placeholder]=\"'Select date range' | translate\"\n bsDaterangepicker\n [bsConfig]=\"dateRangePickerConfig\"\n [minDate]=\"minCustomDate\"\n [maxDate]=\"maxCustomDate\"\n [(bsValue)]=\"customRange\"\n (bsValueChange)=\"changeCustomRange($event)\"\n />\n </div>\n\n <button\n class=\"btn btn-link\"\n [title]=\"'Reload' | translate\"\n type=\"button\"\n [disabled]=\"selectedInterval === CUSTOM && (!customRange || customRange.length === 0)\"\n (click)=\"reload()\"\n >\n <i c8yIcon=\"refresh\"></i>\n {{ 'Reload' | translate }}\n </button>\n</form>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i3.BsDaterangepickerDirective, selector: "[bsDaterangepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isOpen", "bsValue", "bsConfig", "isDisabled", "minDate", "maxDate", "dateCustomClasses", "daysDisabled", "datesDisabled", "datesEnabled"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDaterangepicker"] }, { kind: "directive", type: i3.BsDaterangepickerInputDirective, selector: "input[bsDaterangepicker]" }] }); }
33803
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: TimeIntervalComponent, isStandalone: true, selector: "c8y-time-interval", inputs: { minCustomDate: "minCustomDate", maxCustomDate: "maxCustomDate", dateRangePickerConfig: "dateRangePickerConfig", selectedInterval: "selectedInterval" }, outputs: { interval: "interval" }, ngImport: i0, template: "<form class=\"form-inline\">\n <div class=\"form-group\">\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n [attr.aria-label]=\"'Time interval' | translate\"\n name=\"interval\"\n [(ngModel)]=\"selectedInterval\"\n (ngModelChange)=\"changeInterval($event)\"\n data-cy=\"c8y-time-interval--select\"\n >\n <option\n *ngFor=\"let interval of intvervals\"\n [ngValue]=\"interval\"\n >\n {{ interval.label | translate }}\n </option>\n </select>\n </div>\n </div>\n\n <div\n class=\"form-group datepicker\"\n *ngIf=\"selectedInterval === CUSTOM\"\n >\n <input\n class=\"form-control\"\n [placeholder]=\"'Select date range' | translate\"\n bsDaterangepicker\n [bsConfig]=\"dateRangePickerConfig\"\n [minDate]=\"minCustomDate\"\n [maxDate]=\"maxCustomDate\"\n [(bsValue)]=\"customRange\"\n (bsValueChange)=\"changeCustomRange($event)\"\n />\n </div>\n\n <button\n class=\"btn btn-link\"\n [title]=\"'Reload' | translate\"\n type=\"button\"\n [disabled]=\"selectedInterval === CUSTOM && (!customRange || customRange.length === 0)\"\n (click)=\"reload()\"\n >\n <i c8yIcon=\"refresh\"></i>\n {{ 'Reload' | translate }}\n </button>\n</form>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i3.BsDaterangepickerDirective, selector: "[bsDaterangepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isOpen", "bsValue", "bsConfig", "isDisabled", "minDate", "maxDate", "dateCustomClasses", "daysDisabled", "datesDisabled", "datesEnabled"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDaterangepicker"] }, { kind: "directive", type: i3.BsDaterangepickerInputDirective, selector: "input[bsDaterangepicker]" }] }); }
33804
33804
  }
33805
33805
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TimeIntervalComponent, decorators: [{
33806
33806
  type: Component,
33807
- args: [{ standalone: true, selector: 'c8y-time-interval', imports: [CommonModule, FormsModule$1, BsDatepickerModule], template: "<form class=\"form-inline\">\n <div class=\"form-group\">\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n [attr.aria-label]=\"'Time interval' | translate\"\n name=\"interval\"\n [(ngModel)]=\"selectedInterval\"\n (ngModelChange)=\"changeInterval($event)\"\n >\n <option\n *ngFor=\"let interval of intvervals\"\n [ngValue]=\"interval\"\n >\n {{ interval.label | translate }}\n </option>\n </select>\n </div>\n </div>\n\n <div\n class=\"form-group datepicker\"\n *ngIf=\"selectedInterval === CUSTOM\"\n >\n <input\n class=\"form-control\"\n [placeholder]=\"'Select date range' | translate\"\n bsDaterangepicker\n [bsConfig]=\"dateRangePickerConfig\"\n [minDate]=\"minCustomDate\"\n [maxDate]=\"maxCustomDate\"\n [(bsValue)]=\"customRange\"\n (bsValueChange)=\"changeCustomRange($event)\"\n />\n </div>\n\n <button\n class=\"btn btn-link\"\n [title]=\"'Reload' | translate\"\n type=\"button\"\n [disabled]=\"selectedInterval === CUSTOM && (!customRange || customRange.length === 0)\"\n (click)=\"reload()\"\n >\n <i c8yIcon=\"refresh\"></i>\n {{ 'Reload' | translate }}\n </button>\n</form>\n" }]
33807
+ args: [{ standalone: true, selector: 'c8y-time-interval', imports: [CommonModule, FormsModule$1, BsDatepickerModule], template: "<form class=\"form-inline\">\n <div class=\"form-group\">\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n [attr.aria-label]=\"'Time interval' | translate\"\n name=\"interval\"\n [(ngModel)]=\"selectedInterval\"\n (ngModelChange)=\"changeInterval($event)\"\n data-cy=\"c8y-time-interval--select\"\n >\n <option\n *ngFor=\"let interval of intvervals\"\n [ngValue]=\"interval\"\n >\n {{ interval.label | translate }}\n </option>\n </select>\n </div>\n </div>\n\n <div\n class=\"form-group datepicker\"\n *ngIf=\"selectedInterval === CUSTOM\"\n >\n <input\n class=\"form-control\"\n [placeholder]=\"'Select date range' | translate\"\n bsDaterangepicker\n [bsConfig]=\"dateRangePickerConfig\"\n [minDate]=\"minCustomDate\"\n [maxDate]=\"maxCustomDate\"\n [(bsValue)]=\"customRange\"\n (bsValueChange)=\"changeCustomRange($event)\"\n />\n </div>\n\n <button\n class=\"btn btn-link\"\n [title]=\"'Reload' | translate\"\n type=\"button\"\n [disabled]=\"selectedInterval === CUSTOM && (!customRange || customRange.length === 0)\"\n (click)=\"reload()\"\n >\n <i c8yIcon=\"refresh\"></i>\n {{ 'Reload' | translate }}\n </button>\n</form>\n" }]
33808
33808
  }], propDecorators: { minCustomDate: [{
33809
33809
  type: Input
33810
33810
  }], maxCustomDate: [{