Showing
12 changed files
with
193 additions
and
60 deletions
@@ -498,7 +498,7 @@ export function safeExecute(func: Function, params = []) { | @@ -498,7 +498,7 @@ export function safeExecute(func: Function, params = []) { | ||
498 | res = func(...params); | 498 | res = func(...params); |
499 | } | 499 | } |
500 | catch (err) { | 500 | catch (err) { |
501 | - console.log(err); | 501 | + console.log('error in external function:', err); |
502 | res = null; | 502 | res = null; |
503 | } | 503 | } |
504 | } | 504 | } |
@@ -519,7 +519,7 @@ export function parseFunction(source: string, params: string[] = []): Function { | @@ -519,7 +519,7 @@ export function parseFunction(source: string, params: string[] = []): Function { | ||
519 | return res; | 519 | return res; |
520 | } | 520 | } |
521 | 521 | ||
522 | -export function parseTemplate(template, data) { | 522 | +export function parseTemplate(template: string, data: object) { |
523 | let res = ''; | 523 | let res = ''; |
524 | try { | 524 | try { |
525 | let variables = ''; | 525 | let variables = ''; |
@@ -27,7 +27,6 @@ import { Observable, of, BehaviorSubject, Subject } from 'rxjs'; | @@ -27,7 +27,6 @@ import { Observable, of, BehaviorSubject, Subject } from 'rxjs'; | ||
27 | import { filter } from 'rxjs/operators'; | 27 | import { filter } from 'rxjs/operators'; |
28 | import { Polyline } from './polyline'; | 28 | import { Polyline } from './polyline'; |
29 | import { Polygon } from './polygon'; | 29 | import { Polygon } from './polygon'; |
30 | -import { string } from 'prop-types'; | ||
31 | 30 | ||
32 | export default abstract class LeafletMap { | 31 | export default abstract class LeafletMap { |
33 | 32 | ||
@@ -43,7 +42,6 @@ export default abstract class LeafletMap { | @@ -43,7 +42,6 @@ export default abstract class LeafletMap { | ||
43 | isMarketCluster; | 42 | isMarketCluster; |
44 | bounds: L.LatLngBounds; | 43 | bounds: L.LatLngBounds; |
45 | 44 | ||
46 | - | ||
47 | constructor($container: HTMLElement, options: MapOptions) { | 45 | constructor($container: HTMLElement, options: MapOptions) { |
48 | this.options = options; | 46 | this.options = options; |
49 | } | 47 | } |
@@ -138,7 +136,7 @@ export default abstract class LeafletMap { | @@ -138,7 +136,7 @@ export default abstract class LeafletMap { | ||
138 | } | 136 | } |
139 | 137 | ||
140 | invalidateSize() { | 138 | invalidateSize() { |
141 | - this.map.invalidateSize(true); | 139 | + this.map?.invalidateSize(true); |
142 | } | 140 | } |
143 | 141 | ||
144 | onResize() { | 142 | onResize() { |
@@ -160,7 +158,7 @@ export default abstract class LeafletMap { | @@ -160,7 +158,7 @@ export default abstract class LeafletMap { | ||
160 | } | 158 | } |
161 | } | 159 | } |
162 | 160 | ||
163 | - ////Markers | 161 | + //Markers |
164 | updateMarkers(markersData) { | 162 | updateMarkers(markersData) { |
165 | markersData.forEach(data => { | 163 | markersData.forEach(data => { |
166 | if (data.rotationAngle) { | 164 | if (data.rotationAngle) { |
@@ -259,7 +257,6 @@ export default abstract class LeafletMap { | @@ -259,7 +257,6 @@ export default abstract class LeafletMap { | ||
259 | 257 | ||
260 | createPolygon(data, dataSources, settings) { | 258 | createPolygon(data, dataSources, settings) { |
261 | this.ready$.subscribe(() => { | 259 | this.ready$.subscribe(() => { |
262 | - //public map, coordinates, dataSources, settings, onClickListener? | ||
263 | this.polygon = new Polygon(this.map, data, dataSources, settings); | 260 | this.polygon = new Polygon(this.map, data, dataSources, settings); |
264 | const bounds = this.bounds.extend(this.polygon.leafletPoly.getBounds()); | 261 | const bounds = this.bounds.extend(this.polygon.leafletPoly.getBounds()); |
265 | if (bounds.isValid()) { | 262 | if (bounds.isValid()) { |
@@ -91,6 +91,15 @@ export class MapWidgetController implements MapWidgetInterface { | @@ -91,6 +91,15 @@ export class MapWidgetController implements MapWidgetInterface { | ||
91 | initSettings(settings: any) { | 91 | initSettings(settings: any) { |
92 | const functionParams = ['data', 'dsData', 'dsIndex']; | 92 | const functionParams = ['data', 'dsData', 'dsIndex']; |
93 | this.provider = settings.provider ? settings.provider : this.mapProvider; | 93 | this.provider = settings.provider ? settings.provider : this.mapProvider; |
94 | + | ||
95 | + function getDefCenterPosition(position) { | ||
96 | + if (typeof (position) === 'string') | ||
97 | + return position.split(','); | ||
98 | + if (typeof (position) === 'object') | ||
99 | + return position; | ||
100 | + return [0, 0]; | ||
101 | + } | ||
102 | + | ||
94 | const customOptions = { | 103 | const customOptions = { |
95 | provider: this.provider, | 104 | provider: this.provider, |
96 | mapUrl: settings?.mapImageUrl, | 105 | mapUrl: settings?.mapImageUrl, |
@@ -102,7 +111,7 @@ export class MapWidgetController implements MapWidgetInterface { | @@ -102,7 +111,7 @@ export class MapWidgetController implements MapWidgetInterface { | ||
102 | labelColor: this.ctx.widgetConfig.color, | 111 | labelColor: this.ctx.widgetConfig.color, |
103 | tooltipPattern: settings.tooltipPattern || | 112 | tooltipPattern: settings.tooltipPattern || |
104 | "<b>${entityName}</b><br/><br/><b>Latitude:</b> ${" + settings.latKeyName + ":7}<br/><b>Longitude:</b> ${" + settings.lngKeyName + ":7}", | 113 | "<b>${entityName}</b><br/><br/><b>Latitude:</b> ${" + settings.latKeyName + ":7}<br/><b>Longitude:</b> ${" + settings.lngKeyName + ":7}", |
105 | - defaultCenterPosition: settings?.defaultCenterPosition?.split(',') || [0, 0], | 114 | + defaultCenterPosition: getDefCenterPosition(settings?.defaultCenterPosition), |
106 | useDraggableMarker: true, | 115 | useDraggableMarker: true, |
107 | currentImage: (settings.useMarkerImage && settings.markerImage?.length) ? { | 116 | currentImage: (settings.useMarkerImage && settings.markerImage?.length) ? { |
108 | url: settings.markerImage, | 117 | url: settings.markerImage, |
@@ -137,7 +146,7 @@ export class MapWidgetController implements MapWidgetInterface { | @@ -137,7 +146,7 @@ export class MapWidgetController implements MapWidgetInterface { | ||
137 | return {}; | 146 | return {}; |
138 | } | 147 | } |
139 | 148 | ||
140 | - public static getProvidersSchema() { | 149 | + public static getProvidersSchema() { |
141 | return mergeSchemes([mapProviderSchema, | 150 | return mergeSchemes([mapProviderSchema, |
142 | ...Object.values(providerSets)?.map( | 151 | ...Object.values(providerSets)?.map( |
143 | setting => addCondition(setting?.schema, `model.provider === '${setting.name}'`))]); | 152 | setting => addCondition(setting?.schema, `model.provider === '${setting.name}'`))]); |
@@ -246,5 +255,5 @@ const defaultSettings = { | @@ -246,5 +255,5 @@ const defaultSettings = { | ||
246 | minZoomLevel: 16, | 255 | minZoomLevel: 16, |
247 | credentials: '', | 256 | credentials: '', |
248 | markerClusteringSetting: null, | 257 | markerClusteringSetting: null, |
249 | - draggebleMarker: true | 258 | + draggebleMarker: false |
250 | } | 259 | } |
@@ -15,7 +15,6 @@ | @@ -15,7 +15,6 @@ | ||
15 | /// | 15 | /// |
16 | 16 | ||
17 | import L from 'leaflet'; | 17 | import L from 'leaflet'; |
18 | -import { interpolateOnPointSegment } from 'leaflet-geometryutil'; | ||
19 | import _ from 'lodash'; | 18 | import _ from 'lodash'; |
20 | 19 | ||
21 | export function createTooltip(target, settings) { | 20 | export function createTooltip(target, settings) { |
@@ -34,38 +33,3 @@ export function createTooltip(target, settings) { | @@ -34,38 +33,3 @@ export function createTooltip(target, settings) { | ||
34 | return popup; | 33 | return popup; |
35 | } | 34 | } |
36 | 35 | ||
37 | - | ||
38 | -export function interpolateArray(originData, interpolatedIntervals) { | ||
39 | - | ||
40 | - const getRatio = (firsMoment, secondMoment, intermediateMoment) => { | ||
41 | - return (intermediateMoment - firsMoment) / (secondMoment - firsMoment); | ||
42 | - }; | ||
43 | - | ||
44 | - function findAngle(startPoint, endPoint) { | ||
45 | - let angle = -Math.atan2(endPoint.latitude - startPoint.latitude, endPoint.longitude - startPoint.longitude); | ||
46 | - angle = angle * 180 / Math.PI; | ||
47 | - return parseInt(angle.toFixed(2)); | ||
48 | - } | ||
49 | - | ||
50 | - const result = {}; | ||
51 | - | ||
52 | - for (let i = 1, j = 0; i < originData.length, j < interpolatedIntervals.length;) { | ||
53 | - const currentTime = interpolatedIntervals[j]; | ||
54 | - while (originData[i].time < currentTime) i++; | ||
55 | - const before = originData[i - 1]; | ||
56 | - const after = originData[i]; | ||
57 | - const interpolation = interpolateOnPointSegment( | ||
58 | - new L.Point(before.latitude, before.longitude), | ||
59 | - new L.Point(after.latitude, after.longitude), | ||
60 | - getRatio(before.time, after.time, currentTime)); | ||
61 | - result[currentTime] = ({ | ||
62 | - ...originData[i], | ||
63 | - rotationAngle: findAngle(before, after), | ||
64 | - latitude: interpolation.x, | ||
65 | - longitude: interpolation.y | ||
66 | - }); | ||
67 | - j++; | ||
68 | - } | ||
69 | - | ||
70 | - return result; | ||
71 | -}; |
@@ -56,7 +56,6 @@ export class Marker { | @@ -56,7 +56,6 @@ export class Marker { | ||
56 | if (onDragendListener) { | 56 | if (onDragendListener) { |
57 | this.leafletMarker.on('dragend', onDragendListener); | 57 | this.leafletMarker.on('dragend', onDragendListener); |
58 | } | 58 | } |
59 | - | ||
60 | } | 59 | } |
61 | 60 | ||
62 | setDataSources(data, dataSources) { | 61 | setDataSources(data, dataSources) { |
@@ -24,7 +24,6 @@ export class Polyline { | @@ -24,7 +24,6 @@ export class Polyline { | ||
24 | data; | 24 | data; |
25 | 25 | ||
26 | constructor(private map: L.Map, locations, data, dataSources, settings) { | 26 | constructor(private map: L.Map, locations, data, dataSources, settings) { |
27 | - console.log("Polyline -> constructor -> data", data) | ||
28 | this.dataSources = dataSources; | 27 | this.dataSources = dataSources; |
29 | this.data = data; | 28 | this.data = data; |
30 | this.leafletPoly = L.polyline(locations, | 29 | this.leafletPoly = L.polyline(locations, |
@@ -34,7 +33,6 @@ export class Polyline { | @@ -34,7 +33,6 @@ export class Polyline { | ||
34 | 33 | ||
35 | updatePolyline(settings, data, dataSources) { | 34 | updatePolyline(settings, data, dataSources) { |
36 | this.leafletPoly.setStyle(this.getPolyStyle(settings, data, dataSources)); | 35 | this.leafletPoly.setStyle(this.getPolyStyle(settings, data, dataSources)); |
37 | - | ||
38 | } | 36 | } |
39 | 37 | ||
40 | getPolyStyle(settings, data, dataSources): L.PolylineOptions { | 38 | getPolyStyle(settings, data, dataSources): L.PolylineOptions { |
@@ -15,6 +15,23 @@ | @@ -15,6 +15,23 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<div class="map" #map ></div> | ||
19 | -<tb-history-selector *ngIf="historicalData" [settings]="settings" [intervals]="intervals" | ||
20 | - (onTimeUpdated)="timeUpdated($event)"></tb-history-selector> | 18 | +<div class="trip-animation-widget"> |
19 | + <div class="trip-animation-label-container" *ngIf="settings.showLabel"> | ||
20 | + {{settings.label | tbParseTemplate: activeTrip}} | ||
21 | + </div> | ||
22 | + <div class="trip-animation-container" layout="column"> | ||
23 | + <div class="map" #map></div> | ||
24 | + <div class="trip-animation-info-panel" layout="row"> | ||
25 | + <button class="tooltip-button" mat-mini-fab color="primary" aria-label="tooltip" | ||
26 | + *ngIf="settings.showTooltip" (click)="showHideTooltip()"> | ||
27 | + <mat-icon>info_outline</mat-icon> | ||
28 | + </button> | ||
29 | + </div> | ||
30 | + <div class="trip-animation-tooltip md-whiteframe-z4" layout="column" | ||
31 | + [ngClass]="{ 'trip-animation-tooltip-hidden':!settings.showTooltip}" [innerHTML]="mainTooltip" | ||
32 | + [ngStyle]="{'background-color': settings.tooltipColor, 'opacity': settings.tooltipOpacity, 'color': settings.tooltipFontColor}"> | ||
33 | + </div> | ||
34 | + </div> | ||
35 | + <tb-history-selector *ngIf="historicalData" [settings]="settings" [intervals]="intervals" | ||
36 | + (onTimeUpdated)="timeUpdated($event)"></tb-history-selector> | ||
37 | +</div> |
@@ -14,8 +14,76 @@ | @@ -14,8 +14,76 @@ | ||
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | +.trip-animation-widget { | ||
18 | + position: relative; | ||
19 | + width: 100%; | ||
20 | + height: 100%; | ||
21 | + font-size: 16px; | ||
22 | + line-height: 24px; | ||
23 | + display: flex; | ||
24 | + flex-direction: column; | ||
17 | 25 | ||
18 | -.map{ | 26 | + .trip-animation-label-container { |
27 | + height: 24px; | ||
28 | + } | ||
29 | + | ||
30 | + .trip-animation-container { | ||
31 | + position: relative; | ||
32 | + z-index: 1; | ||
33 | + flex: 1; | ||
19 | width: 100%; | 34 | width: 100%; |
20 | - height: calc(100% - 100px); | ||
21 | -} | ||
35 | + | ||
36 | + .map { | ||
37 | + width: 100%; | ||
38 | + height: 100%; | ||
39 | + } | ||
40 | + | ||
41 | + .trip-animation-info-panel { | ||
42 | + position: absolute; | ||
43 | + top: 0; | ||
44 | + right: 0; | ||
45 | + pointer-events: none; | ||
46 | + | ||
47 | + .tooltip-button { | ||
48 | + top: 0; | ||
49 | + left: 0; | ||
50 | + width: 32px; | ||
51 | + min-width: 32px; | ||
52 | + height: 32px; | ||
53 | + min-height: 32px; | ||
54 | + padding: 0 0 2px; | ||
55 | + margin: 2px; | ||
56 | + line-height: 24px; | ||
57 | + z-index: 999; | ||
58 | + | ||
59 | + &::ng-deep .mat-button-wrapper { | ||
60 | + padding: 0; | ||
61 | + } | ||
62 | + | ||
63 | + mat-icon { | ||
64 | + width: 24px; | ||
65 | + height: 24px; | ||
66 | + | ||
67 | + svg { | ||
68 | + width: inherit; | ||
69 | + height: inherit; | ||
70 | + } | ||
71 | + } | ||
72 | + } | ||
73 | + } | ||
74 | + | ||
75 | + .trip-animation-tooltip { | ||
76 | + position: absolute; | ||
77 | + top: 38px; | ||
78 | + right: 0; | ||
79 | + z-index: 2; | ||
80 | + padding: 10px; | ||
81 | + background-color: #fff; | ||
82 | + transition: 0.3s ease-in-out; | ||
83 | + | ||
84 | + &-hidden { | ||
85 | + transform: translateX(110%); | ||
86 | + } | ||
87 | + } | ||
88 | + } | ||
89 | +} |
@@ -14,15 +14,19 @@ | @@ -14,15 +14,19 @@ | ||
14 | /// limitations under the License. | 14 | /// limitations under the License. |
15 | /// | 15 | /// |
16 | 16 | ||
17 | +import L from 'leaflet'; | ||
18 | +import _ from 'lodash'; | ||
19 | +import tinycolor from "tinycolor2"; | ||
20 | +import { interpolateOnPointSegment } from 'leaflet-geometryutil'; | ||
21 | + | ||
17 | import { Component, OnInit, Input, ViewChild, AfterViewInit, ChangeDetectorRef } from '@angular/core'; | 22 | import { Component, OnInit, Input, ViewChild, AfterViewInit, ChangeDetectorRef } from '@angular/core'; |
18 | import { MapWidgetController, TbMapWidgetV2 } from '../lib/maps/map-widget2'; | 23 | import { MapWidgetController, TbMapWidgetV2 } from '../lib/maps/map-widget2'; |
19 | import { MapProviders } from '../lib/maps/map-models'; | 24 | import { MapProviders } from '../lib/maps/map-models'; |
20 | import { parseArray } from '@app/core/utils'; | 25 | import { parseArray } from '@app/core/utils'; |
21 | -import { interpolateArray } from '../lib/maps/maps-utils'; | ||
22 | -import tinycolor from "tinycolor2"; | ||
23 | import { initSchema, addToSchema, addGroupInfo } from '@app/core/schema-utils'; | 26 | import { initSchema, addToSchema, addGroupInfo } from '@app/core/schema-utils'; |
24 | import { tripAnimationSchema } from '../lib/maps/schemes'; | 27 | import { tripAnimationSchema } from '../lib/maps/schemes'; |
25 | 28 | ||
29 | + | ||
26 | @Component({ | 30 | @Component({ |
27 | selector: 'trip-animation', | 31 | selector: 'trip-animation', |
28 | templateUrl: './trip-animation.component.html', | 32 | templateUrl: './trip-animation.component.html', |
@@ -41,6 +45,8 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { | @@ -41,6 +45,8 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { | ||
41 | interpolatedData = []; | 45 | interpolatedData = []; |
42 | widgetConfig; | 46 | widgetConfig; |
43 | settings; | 47 | settings; |
48 | + mainTooltip; | ||
49 | + activeTrip; | ||
44 | 50 | ||
45 | constructor(private cd: ChangeDetectorRef) { } | 51 | constructor(private cd: ChangeDetectorRef) { } |
46 | 52 | ||
@@ -57,19 +63,27 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { | @@ -57,19 +63,27 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { | ||
57 | let subscription = this.ctx.subscriptions[Object.keys(this.ctx.subscriptions)[0]]; | 63 | let subscription = this.ctx.subscriptions[Object.keys(this.ctx.subscriptions)[0]]; |
58 | if (subscription) subscription.callbacks.onDataUpdated = (updated) => { | 64 | if (subscription) subscription.callbacks.onDataUpdated = (updated) => { |
59 | this.historicalData = parseArray(this.ctx.data); | 65 | this.historicalData = parseArray(this.ctx.data); |
66 | + this.activeTrip = this.historicalData[0][0]; | ||
60 | this.calculateIntervals(); | 67 | this.calculateIntervals(); |
61 | this.timeUpdated(this.intervals[0]); | 68 | this.timeUpdated(this.intervals[0]); |
62 | - this.mapWidget.map.map.invalidateSize(); | 69 | + this.mapWidget.map.map?.invalidateSize(); |
63 | this.cd.detectChanges(); | 70 | this.cd.detectChanges(); |
64 | } | 71 | } |
65 | } | 72 | } |
66 | 73 | ||
67 | ngAfterViewInit() { | 74 | ngAfterViewInit() { |
68 | - this.mapWidget = new MapWidgetController(MapProviders.openstreet, false, this.ctx, this.mapContainer.nativeElement); | 75 | + let ctxCopy = _.cloneDeep(this.ctx); |
76 | + ctxCopy.settings.showLabel = false; | ||
77 | + this.mapWidget = new MapWidgetController(MapProviders.openstreet, false, ctxCopy, this.mapContainer.nativeElement); | ||
69 | } | 78 | } |
70 | 79 | ||
71 | timeUpdated(time) { | 80 | timeUpdated(time) { |
72 | const currentPosition = this.interpolatedData.map(dataSource => dataSource[time]); | 81 | const currentPosition = this.interpolatedData.map(dataSource => dataSource[time]); |
82 | + this.activeTrip = currentPosition[0]; | ||
83 | + this.mapWidget.map.updatePolylines(this.interpolatedData); | ||
84 | + if (this.settings.showPolygon) { | ||
85 | + this.mapWidget.map.updatePolygons(this.interpolatedData); | ||
86 | + } | ||
73 | this.mapWidget.map.updateMarkers(currentPosition); | 87 | this.mapWidget.map.updateMarkers(currentPosition); |
74 | } | 88 | } |
75 | 89 | ||
@@ -80,10 +94,47 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { | @@ -80,10 +94,47 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { | ||
80 | this.intervals.push(time); | 94 | this.intervals.push(time); |
81 | } | 95 | } |
82 | this.intervals.push(dataSource[dataSource.length - 1]?.time); | 96 | this.intervals.push(dataSource[dataSource.length - 1]?.time); |
83 | - this.interpolatedData[index] = interpolateArray(dataSource, this.intervals); | 97 | + this.interpolatedData[index] = this.interpolateArray(dataSource, this.intervals); |
84 | }); | 98 | }); |
85 | } | 99 | } |
86 | 100 | ||
101 | + showHideTooltip() { | ||
102 | + } | ||
103 | + | ||
104 | + interpolateArray(originData, interpolatedIntervals) { | ||
105 | + | ||
106 | + const getRatio = (firsMoment, secondMoment, intermediateMoment) => { | ||
107 | + return (intermediateMoment - firsMoment) / (secondMoment - firsMoment); | ||
108 | + }; | ||
109 | + | ||
110 | + function findAngle(startPoint, endPoint) { | ||
111 | + let angle = -Math.atan2(endPoint.latitude - startPoint.latitude, endPoint.longitude - startPoint.longitude); | ||
112 | + angle = angle * 180 / Math.PI; | ||
113 | + return parseInt(angle.toFixed(2)); | ||
114 | + } | ||
115 | + | ||
116 | + const result = {}; | ||
117 | + | ||
118 | + for (let i = 1, j = 0; i < originData.length, j < interpolatedIntervals.length;) { | ||
119 | + const currentTime = interpolatedIntervals[j]; | ||
120 | + while (originData[i].time < currentTime) i++; | ||
121 | + const before = originData[i - 1]; | ||
122 | + const after = originData[i]; | ||
123 | + const interpolation = interpolateOnPointSegment( | ||
124 | + new L.Point(before.latitude, before.longitude), | ||
125 | + new L.Point(after.latitude, after.longitude), | ||
126 | + getRatio(before.time, after.time, currentTime)); | ||
127 | + result[currentTime] = ({ | ||
128 | + ...originData[i], | ||
129 | + rotationAngle: findAngle(before, after) + this.settings.rotationAngle, | ||
130 | + latitude: interpolation.x, | ||
131 | + longitude: interpolation.y | ||
132 | + }); | ||
133 | + j++; | ||
134 | + } | ||
135 | + return result; | ||
136 | + }; | ||
137 | + | ||
87 | static getSettingsSchema() { | 138 | static getSettingsSchema() { |
88 | let schema = initSchema(); | 139 | let schema = initSchema(); |
89 | addToSchema(schema, TbMapWidgetV2.getProvidersSchema()); | 140 | addToSchema(schema, TbMapWidgetV2.getProvidersSchema()); |
@@ -20,3 +20,4 @@ export * from './keyboard-shortcut.pipe'; | @@ -20,3 +20,4 @@ export * from './keyboard-shortcut.pipe'; | ||
20 | export * from './milliseconds-to-time-string.pipe'; | 20 | export * from './milliseconds-to-time-string.pipe'; |
21 | export * from './nospace.pipe'; | 21 | export * from './nospace.pipe'; |
22 | export * from './truncate.pipe'; | 22 | export * from './truncate.pipe'; |
23 | +export * from './template.pipe'; |
ui-ngx/src/app/shared/pipe/template.pipe.ts
0 → 100644
1 | +/// | ||
2 | +/// Copyright © 2016-2020 The Thingsboard Authors | ||
3 | +/// | ||
4 | +/// Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +/// you may not use this file except in compliance with the License. | ||
6 | +/// You may obtain a copy of the License at | ||
7 | +/// | ||
8 | +/// http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +/// | ||
10 | +/// Unless required by applicable law or agreed to in writing, software | ||
11 | +/// distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +/// See the License for the specific language governing permissions and | ||
14 | +/// limitations under the License. | ||
15 | +/// | ||
16 | + | ||
17 | +import { Pipe, PipeTransform } from '@angular/core'; | ||
18 | +import { parseTemplate } from '@app/core/utils'; | ||
19 | + | ||
20 | +@Pipe({ name: 'tbParseTemplate' }) | ||
21 | +export class TbTemplatePipe implements PipeTransform { | ||
22 | + transform(template, data): string { | ||
23 | + console.log("TbTemplatePipe -> transform -> template, data", template, data) | ||
24 | + return parseTemplate(template, data); | ||
25 | + } | ||
26 | +} |
@@ -128,6 +128,7 @@ import { LedLightComponent } from '@shared/components/led-light.component'; | @@ -128,6 +128,7 @@ import { LedLightComponent } from '@shared/components/led-light.component'; | ||
128 | import { TbJsonToStringDirective } from "@shared/components/directives/tb-json-to-string.directive"; | 128 | import { TbJsonToStringDirective } from "@shared/components/directives/tb-json-to-string.directive"; |
129 | import { JsonObjectEditDialogComponent } from "@shared/components/dialog/json-object-edit-dialog.component"; | 129 | import { JsonObjectEditDialogComponent } from "@shared/components/dialog/json-object-edit-dialog.component"; |
130 | import { HistorySelectorComponent } from './components/time/history-selector/history-selector.component'; | 130 | import { HistorySelectorComponent } from './components/time/history-selector/history-selector.component'; |
131 | +import { TbTemplatePipe } from './pipe/public-api'; | ||
131 | 132 | ||
132 | @NgModule({ | 133 | @NgModule({ |
133 | providers: [ | 134 | providers: [ |
@@ -208,6 +209,7 @@ import { HistorySelectorComponent } from './components/time/history-selector/his | @@ -208,6 +209,7 @@ import { HistorySelectorComponent } from './components/time/history-selector/his | ||
208 | HighlightPipe, | 209 | HighlightPipe, |
209 | TruncatePipe, | 210 | TruncatePipe, |
210 | TbJsonPipe, | 211 | TbJsonPipe, |
212 | + TbTemplatePipe, | ||
211 | KeyboardShortcutPipe, | 213 | KeyboardShortcutPipe, |
212 | TbJsonToStringDirective, | 214 | TbJsonToStringDirective, |
213 | JsonObjectEditDialogComponent, | 215 | JsonObjectEditDialogComponent, |
@@ -367,6 +369,7 @@ import { HistorySelectorComponent } from './components/time/history-selector/his | @@ -367,6 +369,7 @@ import { HistorySelectorComponent } from './components/time/history-selector/his | ||
367 | HighlightPipe, | 369 | HighlightPipe, |
368 | TruncatePipe, | 370 | TruncatePipe, |
369 | TbJsonPipe, | 371 | TbJsonPipe, |
372 | + TbTemplatePipe, | ||
370 | KeyboardShortcutPipe, | 373 | KeyboardShortcutPipe, |
371 | TranslateModule, | 374 | TranslateModule, |
372 | JsonObjectEditDialogComponent, | 375 | JsonObjectEditDialogComponent, |