Commit 0ebbee02db9a981715bc774f2d99b7aa10be4470

Authored by Vladyslav_Prykhodko
1 parent f1193c1d

UI: Added new timewindow type - realtime interval

... ... @@ -15,7 +15,12 @@
15 15 ///
16 16
17 17 import { SubscriptionData, SubscriptionDataHolder } from '@app/shared/models/telemetry/telemetry.models';
18   -import { AggregationType } from '@shared/models/time/time.models';
  18 +import {
  19 + AggregationType,
  20 + calculateIntervalEndTime,
  21 + calculateIntervalStartTime,
  22 + QuickTimeInterval
  23 +} from '@shared/models/time/time.models';
19 24 import { UtilsService } from '@core/services/utils.service';
20 25 import { deepClone } from '@core/utils';
21 26 import Timeout = NodeJS.Timeout;
... ... @@ -92,7 +97,8 @@ export class DataAggregator {
92 97 private interval: number,
93 98 private stateData: boolean,
94 99 private utils: UtilsService,
95   - private ignoreDataUpdateOnIntervalTick: boolean) {
  100 + private ignoreDataUpdateOnIntervalTick: boolean,
  101 + private quickInterval: QuickTimeInterval) {
96 102 this.tsKeyNames.forEach((key) => {
97 103 this.dataBuffer[key] = [];
98 104 });
... ... @@ -138,7 +144,8 @@ export class DataAggregator {
138 144 this.startTs = startTs;
139 145 this.timeWindow = timeWindow;
140 146 this.interval = interval;
141   - this.endTs = this.startTs + this.timeWindow;
  147 + const endTs = this.startTs + this.timeWindow;
  148 + this.endTs = calculateIntervalEndTime(this.quickInterval, endTs);
142 149 this.elapsed = 0;
143 150 this.aggregationTimeout = Math.max(this.interval, 1000);
144 151 this.resetPending = true;
... ... @@ -161,7 +168,8 @@ export class DataAggregator {
161 168 if (!this.dataReceived) {
162 169 this.elapsed = 0;
163 170 this.dataReceived = true;
164   - this.endTs = this.startTs + this.timeWindow;
  171 + const endTs = this.startTs + this.timeWindow;
  172 + this.endTs = calculateIntervalEndTime(this.quickInterval, endTs);
165 173 }
166 174 if (this.resetPending) {
167 175 this.resetPending = false;
... ... @@ -197,8 +205,11 @@ export class DataAggregator {
197 205 if (!history) {
198 206 const delta = Math.floor(this.elapsed / this.interval);
199 207 if (delta || !this.data) {
200   - this.startTs += delta * this.interval;
201   - this.endTs += delta * this.interval;
  208 + const tickTs = delta * this.interval;
  209 + const startTS = this.startTs + tickTs;
  210 + this.startTs = calculateIntervalStartTime(this.quickInterval, startTS);
  211 + const endTs = this.endTs + tickTs;
  212 + this.endTs = calculateIntervalEndTime(this.quickInterval, endTs);
202 213 this.data = this.updateData();
203 214 this.elapsed = this.elapsed - delta * this.interval;
204 215 }
... ...
... ... @@ -752,7 +752,8 @@ export class EntityDataSubscription {
752 752 subsTw.aggregation.interval,
753 753 subsTw.aggregation.stateData,
754 754 this.utils,
755   - this.entityDataSubscriptionOptions.ignoreDataUpdateOnIntervalTick
  755 + this.entityDataSubscriptionOptions.ignoreDataUpdateOnIntervalTick,
  756 + subsTw.quickInterval
756 757 );
757 758 }
758 759
... ...
... ... @@ -37,6 +37,8 @@ import {
37 37 } from '@app/shared/models/widget.models';
38 38 import { HttpErrorResponse } from '@angular/common/http';
39 39 import {
  40 + calculateIntervalEndTime,
  41 + calculateIntervalStartTime,
40 42 createSubscriptionTimewindow,
41 43 createTimewindowForComparison,
42 44 SubscriptionTimewindow,
... ... @@ -1081,8 +1083,10 @@ export class WidgetSubscription implements IWidgetSubscription {
1081 1083 private updateTimewindow() {
1082 1084 this.timeWindow.interval = this.subscriptionTimewindow.aggregation.interval || 1000;
1083 1085 if (this.subscriptionTimewindow.realtimeWindowMs) {
1084   - this.timeWindow.maxTime = moment().valueOf() + this.timeWindow.stDiff;
1085   - this.timeWindow.minTime = this.timeWindow.maxTime - this.subscriptionTimewindow.realtimeWindowMs;
  1086 + this.timeWindow.maxTime = calculateIntervalEndTime(
  1087 + this.subscriptionTimewindow.quickInterval, moment().valueOf() + this.timeWindow.stDiff);
  1088 + this.timeWindow.minTime = calculateIntervalStartTime(
  1089 + this.subscriptionTimewindow.quickInterval, this.timeWindow.maxTime - this.subscriptionTimewindow.realtimeWindowMs);
1086 1090 } else if (this.subscriptionTimewindow.fixedWindow) {
1087 1091 this.timeWindow.maxTime = this.subscriptionTimewindow.fixedWindow.endTimeMs;
1088 1092 this.timeWindow.minTime = this.subscriptionTimewindow.fixedWindow.startTimeMs;
... ... @@ -1105,7 +1109,7 @@ export class WidgetSubscription implements IWidgetSubscription {
1105 1109 this.comparisonTimeWindow.interval = this.timewindowForComparison.aggregation.interval || 1000;
1106 1110 if (this.timewindowForComparison.realtimeWindowMs) {
1107 1111 this.comparisonTimeWindow.maxTime = moment(this.timeWindow.maxTime).subtract(1, this.timeForComparison).valueOf();
1108   - this.comparisonTimeWindow.minTime = this.comparisonTimeWindow.maxTime - this.timewindowForComparison.realtimeWindowMs;
  1112 + this.comparisonTimeWindow.minTime = moment(this.timeWindow.minTime).subtract(1, this.timeForComparison).valueOf();
1109 1113 } else if (this.timewindowForComparison.fixedWindow) {
1110 1114 this.comparisonTimeWindow.maxTime = this.timewindowForComparison.fixedWindow.endTimeMs;
1111 1115 this.comparisonTimeWindow.minTime = this.timewindowForComparison.fixedWindow.startTimeMs;
... ...
... ... @@ -50,7 +50,7 @@ export class QuickTimeIntervalComponent implements OnInit, ControlValueAccessor
50 50
51 51 get intervals() {
52 52 if (this.onlyCurrentInterval) {
53   - return this.allIntervals.filter(interval => interval.startsWith('TODAY_') || interval.startsWith('CURRENT_'));
  53 + return this.allIntervals.filter(interval => interval.startsWith('TODAY') || interval.startsWith('CURRENT_'));
54 54 }
55 55 return this.allIntervals;
56 56 }
... ... @@ -71,7 +71,6 @@ export class QuickTimeIntervalComponent implements OnInit, ControlValueAccessor
71 71
72 72 writeValue(interval: QuickTimeInterval): void {
73 73 this.modelValue = interval;
74   - this.rendered = true;
75 74 }
76 75
77 76 onIntervalChange() {
... ...
... ... @@ -21,16 +21,43 @@
21 21 <mat-tab-group dynamicHeight [ngClass]="{'tb-headless': historyOnly}"
22 22 (selectedIndexChange)="timewindowForm.markAsDirty()" [(selectedIndex)]="timewindow.selectedTab">
23 23 <mat-tab label="{{ 'timewindow.realtime' | translate }}">
24   - <div formGroupName="realtime" class="mat-content mat-padding" fxLayout="column">
25   - <tb-timeinterval
26   - [(hideFlag)]="timewindow.hideInterval"
27   - (hideFlagChange)="onHideIntervalChanged()"
28   - [isEdit]="isEdit"
29   - formControlName="timewindowMs"
30   - predefinedName="timewindow.last"
31   - [required]="timewindow.selectedTab === timewindowTypes.REALTIME"
32   - style="padding-top: 8px;"></tb-timeinterval>
33   - </div>
  24 + <section fxLayout="row">
  25 + <section *ngIf="isEdit" fxLayout="column" style="padding-top: 8px; padding-left: 16px;">
  26 + <label class="tb-small hide-label" translate>timewindow.hide</label>
  27 + <mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideInterval"
  28 + (ngModelChange)="onHideIntervalChanged()"></mat-checkbox>
  29 + </section>
  30 + <section fxLayout="column" fxFlex [fxShow]="isEdit || !timewindow.hideInterval">
  31 + <div formGroupName="realtime" class="mat-content mat-padding" style="padding-top: 8px;">
  32 + <mat-radio-group formControlName="realtimeType">
  33 + <mat-radio-button [value]="realtimeTypes.LAST_INTERVAL" color="primary">
  34 + <section fxLayout="column">
  35 + <span translate>timewindow.last</span>
  36 + <tb-timeinterval
  37 + formControlName="timewindowMs"
  38 + predefinedName="timewindow.last"
  39 + [fxShow]="timewindowForm.get('realtime.realtimeType').value === realtimeTypes.LAST_INTERVAL"
  40 + [required]="timewindow.selectedTab === timewindowTypes.REALTIME &&
  41 + timewindowForm.get('realtime.realtimeType').value === realtimeTypes.LAST_INTERVAL"
  42 + style="padding-top: 8px;"></tb-timeinterval>
  43 + </section>
  44 + </mat-radio-button>
  45 + <mat-radio-button [value]="realtimeTypes.INTERVAL" color="primary">
  46 + <section fxLayout="column">
  47 + <span translate>timewindow.interval</span>
  48 + <tb-quick-time-interval
  49 + formControlName="quickInterval"
  50 + onlyCurrentInterval="true"
  51 + [fxShow]="timewindowForm.get('realtime.realtimeType').value === realtimeTypes.INTERVAL"
  52 + [required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
  53 + timewindowForm.get('realtime.realtimeType').value === realtimeTypes.INTERVAL"
  54 + style="padding-top: 8px; min-width: 364px"></tb-quick-time-interval>
  55 + </section>
  56 + </mat-radio-button>
  57 + </mat-radio-group>
  58 + </div>
  59 + </section>
  60 + </section>
34 61 </mat-tab>
35 62 <mat-tab label="{{ 'timewindow.history' | translate }}">
36 63 <section fxLayout="row">
... ...
... ... @@ -19,7 +19,9 @@ import {
19 19 aggregationTranslations,
20 20 AggregationType,
21 21 DAY,
22   - HistoryWindowType, quickTimeIntervalPeriod,
  22 + HistoryWindowType,
  23 + quickTimeIntervalPeriod,
  24 + RealtimeWindowType,
23 25 Timewindow,
24 26 TimewindowType
25 27 } from '@shared/models/time/time.models';
... ... @@ -60,6 +62,8 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
60 62
61 63 historyTypes = HistoryWindowType;
62 64
  65 + realtimeTypes = RealtimeWindowType;
  66 +
63 67 timewindowTypes = TimewindowType;
64 68
65 69 aggregationTypes = AggregationType;
... ... @@ -89,6 +93,11 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
89 93 this.timewindowForm = this.fb.group({
90 94 realtime: this.fb.group(
91 95 {
  96 + realtimeType: this.fb.control({
  97 + value: this.timewindow.realtime && typeof this.timewindow.realtime.realtimeType !== 'undefined'
  98 + ? this.timewindow.realtime.realtimeType : RealtimeWindowType.LAST_INTERVAL,
  99 + disabled: hideInterval
  100 + }),
92 101 timewindowMs: [
93 102 this.timewindow.realtime && typeof this.timewindow.realtime.timewindowMs !== 'undefined'
94 103 ? this.timewindow.realtime.timewindowMs : null
... ... @@ -96,7 +105,12 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
96 105 interval: [
97 106 this.timewindow.realtime && typeof this.timewindow.realtime.interval !== 'undefined'
98 107 ? this.timewindow.realtime.interval : null
99   - ]
  108 + ],
  109 + quickInterval: this.fb.control({
  110 + value: this.timewindow.realtime && typeof this.timewindow.realtime.quickInterval !== 'undefined'
  111 + ? this.timewindow.realtime.quickInterval : null,
  112 + disabled: hideInterval
  113 + })
100 114 }
101 115 ),
102 116 history: this.fb.group(
... ... @@ -124,7 +138,7 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
124 138 value: this.timewindow.history && typeof this.timewindow.history.quickInterval !== 'undefined'
125 139 ? this.timewindow.history.quickInterval : null,
126 140 disabled: hideInterval
127   - }),
  141 + })
128 142 }
129 143 ),
130 144 aggregation: this.fb.group(
... ... @@ -147,7 +161,9 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
147 161 update() {
148 162 const timewindowFormValue = this.timewindowForm.getRawValue();
149 163 this.timewindow.realtime = {
  164 + realtimeType: timewindowFormValue.realtime.realtimeType,
150 165 timewindowMs: timewindowFormValue.realtime.timewindowMs,
  166 + quickInterval: timewindowFormValue.realtime.quickInterval,
151 167 interval: timewindowFormValue.realtime.interval
152 168 };
153 169 this.timewindow.history = {
... ... @@ -180,11 +196,23 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
180 196 }
181 197
182 198 minRealtimeAggInterval() {
183   - return this.timeService.minIntervalLimit(this.timewindowForm.get('realtime.timewindowMs').value);
  199 + return this.timeService.minIntervalLimit(this.currentRealtimeTimewindow());
184 200 }
185 201
186 202 maxRealtimeAggInterval() {
187   - return this.timeService.maxIntervalLimit(this.timewindowForm.get('realtime.timewindowMs').value);
  203 + return this.timeService.maxIntervalLimit(this.currentRealtimeTimewindow());
  204 + }
  205 +
  206 + currentRealtimeTimewindow(): number {
  207 + const timeWindowFormValue = this.timewindowForm.getRawValue();
  208 + switch (timeWindowFormValue.realtime.realtimeType) {
  209 + case RealtimeWindowType.LAST_INTERVAL:
  210 + return timeWindowFormValue.realtime.timewindowMs;
  211 + case RealtimeWindowType.INTERVAL:
  212 + return quickTimeIntervalPeriod(timeWindowFormValue.realtime.quickInterval);
  213 + default:
  214 + return DAY;
  215 + }
188 216 }
189 217
190 218 minHistoryAggInterval() {
... ... @@ -215,11 +243,17 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
215 243 this.timewindowForm.get('history.timewindowMs').disable({emitEvent: false});
216 244 this.timewindowForm.get('history.fixedTimewindow').disable({emitEvent: false});
217 245 this.timewindowForm.get('history.quickInterval').disable({emitEvent: false});
  246 + this.timewindowForm.get('realtime.realtimeType').disable({emitEvent: false});
  247 + this.timewindowForm.get('realtime.timewindowMs').disable({emitEvent: false});
  248 + this.timewindowForm.get('realtime.quickInterval').disable({emitEvent: false});
218 249 } else {
219 250 this.timewindowForm.get('history.historyType').enable({emitEvent: false});
220 251 this.timewindowForm.get('history.timewindowMs').enable({emitEvent: false});
221 252 this.timewindowForm.get('history.fixedTimewindow').enable({emitEvent: false});
222 253 this.timewindowForm.get('history.quickInterval').enable({emitEvent: false});
  254 + this.timewindowForm.get('realtime.realtimeType').enable({emitEvent: false});
  255 + this.timewindowForm.get('realtime.timewindowMs').enable({emitEvent: false});
  256 + this.timewindowForm.get('realtime.quickInterval').enable({emitEvent: false});
223 257 }
224 258 this.timewindowForm.markAsDirty();
225 259 }
... ...
... ... @@ -34,6 +34,7 @@ import {
34 34 HistoryWindowType,
35 35 initModelFromDefaultTimewindow,
36 36 QuickTimeIntervalTranslationMap,
  37 + RealtimeWindowType,
37 38 Timewindow,
38 39 TimewindowType
39 40 } from '@shared/models/time/time.models';
... ... @@ -273,9 +274,13 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
273 274
274 275 updateDisplayValue() {
275 276 if (this.innerValue.selectedTab === TimewindowType.REALTIME && !this.historyOnly) {
276   - this.innerValue.displayValue = this.translate.instant('timewindow.realtime') + ' - ' +
277   - this.translate.instant('timewindow.last-prefix') + ' ' +
278   - this.millisecondsToTimeStringPipe.transform(this.innerValue.realtime.timewindowMs);
  277 + this.innerValue.displayValue = this.translate.instant('timewindow.realtime') + ' - ';
  278 + if (this.innerValue.realtime.realtimeType === RealtimeWindowType.INTERVAL) {
  279 + this.innerValue.displayValue += this.translate.instant(QuickTimeIntervalTranslationMap.get(this.innerValue.realtime.quickInterval));
  280 + } else {
  281 + this.innerValue.displayValue += this.translate.instant('timewindow.last-prefix') + ' ' +
  282 + this.millisecondsToTimeStringPipe.transform(this.innerValue.realtime.timewindowMs);
  283 + }
279 284 } else {
280 285 this.innerValue.displayValue = !this.historyOnly ? (this.translate.instant('timewindow.history') + ' - ') : '';
281 286 if (this.innerValue.history.historyType === HistoryWindowType.LAST_INTERVAL) {
... ...
... ... @@ -15,7 +15,7 @@
15 15 ///
16 16
17 17 import { TimeService } from '@core/services/time.service';
18   -import { deepClone, isDefined, isUndefined } from '@app/core/utils';
  18 +import { deepClone, isDefined, isDefinedAndNotNull, isUndefined } from '@app/core/utils';
19 19 import * as moment_ from 'moment';
20 20 import { Observable } from 'rxjs/internal/Observable';
21 21 import { from, of } from 'rxjs';
... ... @@ -35,6 +35,11 @@ export enum TimewindowType {
35 35 HISTORY
36 36 }
37 37
  38 +export enum RealtimeWindowType {
  39 + LAST_INTERVAL,
  40 + INTERVAL
  41 +}
  42 +
38 43 export enum HistoryWindowType {
39 44 LAST_INTERVAL,
40 45 FIXED,
... ... @@ -47,6 +52,10 @@ export interface IntervalWindow {
47 52 quickInterval?: QuickTimeInterval;
48 53 }
49 54
  55 +export interface RealtimeWindow extends IntervalWindow{
  56 + realtimeType?: RealtimeWindowType;
  57 +}
  58 +
50 59 export interface FixedWindow {
51 60 startTimeMs: number;
52 61 endTimeMs: number;
... ... @@ -89,7 +98,7 @@ export interface Timewindow {
89 98 hideAggregation?: boolean;
90 99 hideAggInterval?: boolean;
91 100 selectedTab?: TimewindowType;
92   - realtime?: IntervalWindow;
  101 + realtime?: RealtimeWindow;
93 102 history?: HistoryWindow;
94 103 aggregation?: Aggregation;
95 104 }
... ... @@ -102,6 +111,7 @@ export interface SubscriptionAggregation extends Aggregation {
102 111
103 112 export interface SubscriptionTimewindow {
104 113 startTs?: number;
  114 + quickInterval?: QuickTimeInterval;
105 115 realtimeWindowMs?: number;
106 116 fixedWindow?: FixedWindow;
107 117 aggregation?: SubscriptionAggregation;
... ... @@ -168,8 +178,10 @@ export function defaultTimewindow(timeService: TimeService): Timewindow {
168 178 hideAggInterval: false,
169 179 selectedTab: TimewindowType.REALTIME,
170 180 realtime: {
  181 + realtimeType: RealtimeWindowType.LAST_INTERVAL,
171 182 interval: SECOND,
172   - timewindowMs: MINUTE
  183 + timewindowMs: MINUTE,
  184 + quickInterval: QuickTimeInterval.TODAY
173 185 },
174 186 history: {
175 187 historyType: HistoryWindowType.LAST_INTERVAL,
... ... @@ -208,7 +220,20 @@ export function initModelFromDefaultTimewindow(value: Timewindow, timeService: T
208 220 if (isDefined(value.realtime.interval)) {
209 221 model.realtime.interval = value.realtime.interval;
210 222 }
211   - model.realtime.timewindowMs = value.realtime.timewindowMs;
  223 + if (isUndefined(value.realtime.realtimeType)) {
  224 + if (isDefined(value.realtime.quickInterval)) {
  225 + model.realtime.realtimeType = RealtimeWindowType.INTERVAL;
  226 + } else {
  227 + model.realtime.realtimeType = RealtimeWindowType.LAST_INTERVAL;
  228 + }
  229 + } else {
  230 + model.realtime.realtimeType = value.realtime.realtimeType;
  231 + }
  232 + if (model.realtime.realtimeType === RealtimeWindowType.INTERVAL) {
  233 + model.realtime.quickInterval = value.realtime.quickInterval;
  234 + } else {
  235 + model.realtime.timewindowMs = value.realtime.timewindowMs;
  236 + }
212 237 } else {
213 238 if (isDefined(value.history.interval)) {
214 239 model.history.interval = value.history.interval;
... ... @@ -309,14 +334,27 @@ export function createSubscriptionTimewindow(timewindow: Timewindow, stDiff: num
309 334 selectedTab = isDefined(timewindow.realtime) ? TimewindowType.REALTIME : TimewindowType.HISTORY;
310 335 }
311 336 if (selectedTab === TimewindowType.REALTIME) {
312   - subscriptionTimewindow.realtimeWindowMs = timewindow.realtime.timewindowMs;
  337 + let realtimeType = timewindow.realtime.realtimeType;
  338 + if (isUndefined(realtimeType)) {
  339 + if (isDefined(timewindow.realtime.quickInterval)) {
  340 + realtimeType = RealtimeWindowType.INTERVAL;
  341 + } else {
  342 + realtimeType = RealtimeWindowType.LAST_INTERVAL;
  343 + }
  344 + }
  345 + if (realtimeType === RealtimeWindowType.INTERVAL) {
  346 + subscriptionTimewindow.realtimeWindowMs = getSubscriptionRealtimeWindowFromTimeInterval(timewindow.realtime.quickInterval);
  347 + subscriptionTimewindow.quickInterval = timewindow.realtime.quickInterval;
  348 + } else {
  349 + subscriptionTimewindow.realtimeWindowMs = timewindow.realtime.timewindowMs;
  350 + }
313 351 subscriptionTimewindow.aggregation.interval =
314 352 timeService.boundIntervalToTimewindow(subscriptionTimewindow.realtimeWindowMs, timewindow.realtime.interval,
315 353 subscriptionTimewindow.aggregation.type);
316 354 subscriptionTimewindow.startTs = Date.now() + stDiff - subscriptionTimewindow.realtimeWindowMs;
317 355 const startDiff = subscriptionTimewindow.startTs % subscriptionTimewindow.aggregation.interval;
318 356 aggTimewindow = subscriptionTimewindow.realtimeWindowMs;
319   - if (startDiff) {
  357 + if (startDiff && realtimeType !== RealtimeWindowType.INTERVAL) {
320 358 subscriptionTimewindow.startTs -= startDiff;
321 359 aggTimewindow += subscriptionTimewindow.aggregation.interval;
322 360 }
... ... @@ -339,7 +377,11 @@ export function createSubscriptionTimewindow(timewindow: Timewindow, stDiff: num
339 377 };
340 378 aggTimewindow = timewindow.history.timewindowMs;
341 379 } else if (historyType === HistoryWindowType.INTERVAL) {
342   - subscriptionTimewindow.fixedWindow = createSubscriptionTimeWindowFromQuickKTimeInterval(timewindow.history.quickInterval);
  380 + const currentDate = moment();
  381 + subscriptionTimewindow.fixedWindow = {
  382 + startTimeMs: calculateIntervalStartTime(timewindow.history.quickInterval, null, currentDate),
  383 + endTimeMs: calculateIntervalEndTime(timewindow.history.quickInterval, null, currentDate)
  384 + };
343 385 aggTimewindow = subscriptionTimewindow.fixedWindow.endTimeMs - subscriptionTimewindow.fixedWindow.startTimeMs;
344 386 } else {
345 387 subscriptionTimewindow.fixedWindow = {
... ... @@ -360,77 +402,99 @@ export function createSubscriptionTimewindow(timewindow: Timewindow, stDiff: num
360 402 return subscriptionTimewindow;
361 403 }
362 404
363   -export function createSubscriptionTimeWindowFromQuickKTimeInterval(interval: QuickTimeInterval): FixedWindow {
  405 +function getSubscriptionRealtimeWindowFromTimeInterval(interval: QuickTimeInterval): number {
364 406 const currentDate = moment();
365   - const timeWindow = {
366   - startTimeMs: 0,
367   - endTimeMs: 0
368   - };
  407 + switch (interval) {
  408 + case QuickTimeInterval.TODAY:
  409 + case QuickTimeInterval.TODAY_SO_FAR:
  410 + return currentDate.diff(currentDate.clone().startOf('day'));
  411 + case QuickTimeInterval.CURRENT_WEEK:
  412 + case QuickTimeInterval.CURRENT_WEEK_SO_FAR:
  413 + return currentDate.diff(currentDate.clone().startOf('week'));
  414 + case QuickTimeInterval.CURRENT_MONTH:
  415 + case QuickTimeInterval.CURRENT_MONTH_SO_FAR:
  416 + return currentDate.diff(currentDate.clone().startOf('month'));
  417 + case QuickTimeInterval.CURRENT_YEAR:
  418 + case QuickTimeInterval.CURRENT_YEAR_SO_FAR:
  419 + return currentDate.diff(currentDate.clone().startOf('year'));
  420 + }
  421 +}
  422 +
  423 +export function calculateIntervalEndTime(interval: QuickTimeInterval, endTs = 0, nowDate?: moment_.Moment): number {
  424 + const currentDate = isDefinedAndNotNull(nowDate) ? nowDate.clone() : moment();
  425 + switch (interval) {
  426 + case QuickTimeInterval.YESTERDAY:
  427 + currentDate.subtract(1, 'days');
  428 + return currentDate.endOf('day').valueOf();
  429 + case QuickTimeInterval.DAY_BEFORE_YESTERDAY:
  430 + currentDate.subtract(2, 'days');
  431 + return currentDate.endOf('day').valueOf();
  432 + case QuickTimeInterval.THIS_DAY_LAST_WEEK:
  433 + currentDate.subtract(1, 'weeks');
  434 + return currentDate.endOf('day').valueOf();
  435 + case QuickTimeInterval.PREVIOUS_WEEK:
  436 + currentDate.subtract(1, 'weeks');
  437 + return currentDate.endOf('week').valueOf();
  438 + case QuickTimeInterval.PREVIOUS_MONTH:
  439 + currentDate.subtract(1, 'months');
  440 + return currentDate.endOf('month').valueOf();
  441 + case QuickTimeInterval.PREVIOUS_YEAR:
  442 + currentDate.subtract(1, 'years');
  443 + return currentDate.endOf('year').valueOf();
  444 + case QuickTimeInterval.TODAY:
  445 + return currentDate.endOf('day').valueOf();
  446 + case QuickTimeInterval.CURRENT_WEEK:
  447 + return currentDate.endOf('week').valueOf();
  448 + case QuickTimeInterval.CURRENT_MONTH:
  449 + return currentDate.endOf('month').valueOf();
  450 + case QuickTimeInterval.CURRENT_YEAR:
  451 + return currentDate.endOf('year').valueOf();
  452 + case QuickTimeInterval.TODAY_SO_FAR:
  453 + case QuickTimeInterval.CURRENT_WEEK_SO_FAR:
  454 + case QuickTimeInterval.CURRENT_MONTH_SO_FAR:
  455 + case QuickTimeInterval.CURRENT_YEAR_SO_FAR:
  456 + return currentDate.valueOf();
  457 + default:
  458 + return endTs;
  459 + }
  460 +}
  461 +
  462 +export function calculateIntervalStartTime(interval: QuickTimeInterval, startTS = 0, nowDate?: moment_.Moment): number {
  463 + const currentDate = isDefinedAndNotNull(nowDate) ? nowDate.clone() : moment();
369 464 switch (interval) {
370 465 case QuickTimeInterval.YESTERDAY:
371 466 currentDate.subtract(1, 'days');
372   - timeWindow.startTimeMs = currentDate.startOf('day').valueOf();
373   - timeWindow.endTimeMs = currentDate.endOf('day').valueOf();
374   - break;
  467 + return currentDate.startOf('day').valueOf();
375 468 case QuickTimeInterval.DAY_BEFORE_YESTERDAY:
376 469 currentDate.subtract(2, 'days');
377   - timeWindow.startTimeMs = currentDate.startOf('day').valueOf();
378   - timeWindow.endTimeMs = currentDate.endOf('day').valueOf();
379   - break;
  470 + return currentDate.startOf('day').valueOf();
380 471 case QuickTimeInterval.THIS_DAY_LAST_WEEK:
381 472 currentDate.subtract(1, 'weeks');
382   - timeWindow.startTimeMs = currentDate.startOf('day').valueOf();
383   - timeWindow.endTimeMs = currentDate.endOf('day').valueOf();
384   - break;
  473 + return currentDate.startOf('day').valueOf();
385 474 case QuickTimeInterval.PREVIOUS_WEEK:
386 475 currentDate.subtract(1, 'weeks');
387   - timeWindow.startTimeMs = currentDate.startOf('week').valueOf();
388   - timeWindow.endTimeMs = currentDate.endOf('week').valueOf();
389   - break;
  476 + return currentDate.startOf('week').valueOf();
390 477 case QuickTimeInterval.PREVIOUS_MONTH:
391 478 currentDate.subtract(1, 'months');
392   - timeWindow.startTimeMs = currentDate.startOf('month').valueOf();
393   - timeWindow.endTimeMs = currentDate.endOf('month').valueOf();
394   - break;
  479 + return currentDate.startOf('month').valueOf();
395 480 case QuickTimeInterval.PREVIOUS_YEAR:
396 481 currentDate.subtract(1, 'years');
397   - timeWindow.startTimeMs = currentDate.startOf('year').valueOf();
398   - timeWindow.endTimeMs = currentDate.endOf('year').valueOf();
399   - break;
  482 + return currentDate.startOf('year').valueOf();
400 483 case QuickTimeInterval.TODAY:
401   - timeWindow.startTimeMs = currentDate.startOf('day').valueOf();
402   - timeWindow.endTimeMs = currentDate.endOf('day').valueOf();
403   - break;
404 484 case QuickTimeInterval.TODAY_SO_FAR:
405   - timeWindow.endTimeMs = currentDate.valueOf();
406   - timeWindow.startTimeMs = currentDate.startOf('day').valueOf();
407   - break;
  485 + return currentDate.startOf('day').valueOf();
408 486 case QuickTimeInterval.CURRENT_WEEK:
409   - timeWindow.startTimeMs = currentDate.startOf('week').valueOf();
410   - timeWindow.endTimeMs = currentDate.endOf('week').valueOf();
411   - break;
412 487 case QuickTimeInterval.CURRENT_WEEK_SO_FAR:
413   - timeWindow.endTimeMs = currentDate.valueOf();
414   - timeWindow.startTimeMs = currentDate.startOf('week').valueOf();
415   - break;
  488 + return currentDate.startOf('week').valueOf();
416 489 case QuickTimeInterval.CURRENT_MONTH:
417   - timeWindow.startTimeMs = currentDate.startOf('month').valueOf();
418   - timeWindow.endTimeMs = currentDate.endOf('month').valueOf();
419   - break;
420 490 case QuickTimeInterval.CURRENT_MONTH_SO_FAR:
421   - timeWindow.endTimeMs = currentDate.valueOf();
422   - timeWindow.startTimeMs = currentDate.startOf('month').valueOf();
423   - break;
  491 + return currentDate.startOf('month').valueOf();
424 492 case QuickTimeInterval.CURRENT_YEAR:
425   - timeWindow.startTimeMs = currentDate.startOf('year').valueOf();
426   - timeWindow.endTimeMs = currentDate.endOf('year').valueOf();
427   - break;
428 493 case QuickTimeInterval.CURRENT_YEAR_SO_FAR:
429   - timeWindow.endTimeMs = currentDate.valueOf();
430   - timeWindow.startTimeMs = currentDate.startOf('year').valueOf();
431   - break;
  494 + return currentDate.startOf('year').valueOf();
  495 + default:
  496 + return startTS;
432 497 }
433   - return timeWindow;
434 498 }
435 499
436 500 export function quickTimeIntervalPeriod(interval: QuickTimeInterval): number {
... ...