ngx-hana-nameserver-history-viewer 21.1.1 → 21.1.2

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.
package/README.md CHANGED
@@ -22,7 +22,7 @@ npm install ngx-hana-nameserver-history-viewer --save
22
22
 
23
23
  ### Requirements
24
24
 
25
- The library depends on [ngx-selection-table](https://github.com/ckyycc/ngx-selection-table), [ngx-dropdown-list](https://github.com/ckyycc/ngx-dropdown-list), [moment-timezone](https://github.com/moment/moment-timezone), [papaparse](https://github.com/mholt/PapaParse), [nshviewer-angular-datetime-picker](https://github.com/ckyycc/date-time-picker), [chart.js](https://github.com/chartjs/Chart.js).
25
+ The library depends on [ngx-selection-table](https://github.com/ckyycc/ngx-selection-table), [ngx-dropdown-list](https://github.com/ckyycc/ngx-dropdown-list), [date-fns](https://github.com/date-fns/date-fns), [papaparse](https://github.com/mholt/PapaParse), [nshviewer-angular-datetime-picker](https://github.com/ckyycc/date-time-picker), [chart.js](https://github.com/chartjs/Chart.js).
26
26
 
27
27
  The only file required is the ng-pick-datetime `picker.min.css` file:
28
28
 
@@ -1,9 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { isDevMode, Injectable, EventEmitter, Output, Input, Component, ChangeDetectionStrategy, ElementRef, ViewChild } from '@angular/core';
3
3
  import { SelectionModel } from '@angular/cdk/collections';
4
- import moment from 'moment-timezone';
4
+ import { format } from 'date-fns';
5
+ import { TZDateMini } from '@date-fns/tz';
5
6
  import { Chart, registerables, TimeScale, LinearScale, CategoryScale, PointElement, LineElement, Title, Tooltip, Legend, Filler, Decimation } from 'chart.js';
6
- import 'chartjs-adapter-moment';
7
+ import 'chartjs-adapter-date-fns';
7
8
  import zoomPlugin from 'chartjs-plugin-zoom';
8
9
  import { parse } from 'papaparse';
9
10
  import * as i2 from 'nshviewer-angular-datetime-picker';
@@ -128,6 +129,25 @@ const _IGNORED_LINE_FROM_TAIL = 1;
128
129
  * 06: web dispatcher; 07: xsengine; 10 compileserver; 11 dpserver; 12 esserver; 29 xscontroller
129
130
  */
130
131
  const _NON_INDEX_SERVER_PORTS = ['01', '02', '04', '05', '06', '07', '10', '11', '12', '29'];
132
+ const _HANA_SERVICES = {
133
+ indexserver: 'Index Server',
134
+ nameserver: 'Name Server',
135
+ compileserver: 'Compile Server',
136
+ preprocessor: 'Preprocessor Server',
137
+ webdispatcher: 'SAP Web Dispatcher',
138
+ scriptserver: 'Script Server',
139
+ docstore: 'Document Store Server',
140
+ diserver: 'HDI Server',
141
+ xsengine: 'XS Classic Server',
142
+ esserver: 'Extended Store Server',
143
+ dpserver: 'Data Provisioning Server',
144
+ streamingserver: 'Streaming Cluster',
145
+ etsserver: 'Accelerator for SAP ASE',
146
+ xscontroller: 'SAP HANA XS Controller',
147
+ xsexecagent: 'SAP HANA XS Execution Agent',
148
+ xsuaaserver: 'SAP HANA XS UAA'
149
+ };
150
+ const getHANAServiceDisplayName = (s) => (s ? (_HANA_SERVICES[s] ?? s) : "");
131
151
  /**
132
152
  * Get the ignored line number from tail (For some reason, hana studio will abandon the last line of nameserver history trace file).
133
153
  */
@@ -313,11 +333,37 @@ function _getTimeRange(time) {
313
333
  }
314
334
  return { startTime: 0, endTime: 0 };
315
335
  }
336
+ function getEtcTimezones() {
337
+ // Add Etc timezones manually since Intl doesn't include them
338
+ const etcTimezones = [
339
+ 'Etc/GMT+0', 'Etc/GMT+1', 'Etc/GMT+2', 'Etc/GMT+3', 'Etc/GMT+4', 'Etc/GMT+5', 'Etc/GMT+6',
340
+ 'Etc/GMT+7', 'Etc/GMT+8', 'Etc/GMT+9', 'Etc/GMT+10', 'Etc/GMT+11', 'Etc/GMT+12', 'Etc/GMT-0',
341
+ 'Etc/GMT-1', 'Etc/GMT-2', 'Etc/GMT-3', 'Etc/GMT-4', 'Etc/GMT-5', 'Etc/GMT-6',
342
+ 'Etc/GMT-7', 'Etc/GMT-8', 'Etc/GMT-9', 'Etc/GMT-10', 'Etc/GMT-11', 'Etc/GMT-12',
343
+ 'Etc/GMT-13', 'Etc/GMT-14'
344
+ ];
345
+ return [...etcTimezones, ...getZeroOffsetEtcZones()];
346
+ }
347
+ /**
348
+ * etc zones with 0 offset
349
+ */
350
+ function getZeroOffsetEtcZones() {
351
+ return ['Etc/GMT', 'Etc/GMT0', 'Etc/Greenwich', 'Etc/UTC', 'Etc/UCT', 'Etc/Universal', 'Etc/Zulu'];
352
+ }
316
353
  /**
317
354
  * get default local time zone
318
355
  */
319
- function getDefaultTimezone() {
320
- return moment.tz.guess();
356
+ function defaultTimezone() {
357
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
358
+ }
359
+ /**
360
+ *
361
+ * @returns get supported timezones from intl
362
+ */
363
+ function supportedTimezones() {
364
+ const zones = Intl.supportedValuesOf('timeZone');
365
+ // Combine Intl zones with Etc zones
366
+ return [...zones, ...getEtcTimezones()];
321
367
  }
322
368
  /**
323
369
  * Get time from provided timezone, using this only because chart.js doesn't support timezone.
@@ -327,19 +373,48 @@ function getDefaultTimezone() {
327
373
  */
328
374
  function getTimeFromTimeZone(time, timezone) {
329
375
  if (timezone == null || timezone.length === 0) {
330
- timezone = getDefaultTimezone();
376
+ timezone = defaultTimezone();
331
377
  console.warn(`getTimeFromTimeZone - Input timezone is null, returning the local (${timezone}) time. `);
332
378
  }
333
- const utcOffset = moment.tz.zone(timezone).utcOffset(time * 1000);
334
- const currentOffset = moment.tz.zone(getDefaultTimezone()).utcOffset(time * 1000);
379
+ // Get timezone offsets in milliseconds
380
+ const utcOffset = getOffset(timezone, time * 1000);
381
+ const currentOffset = getOffset(defaultTimezone(), time * 1000); // seconds
335
382
  // convert to utc and then to selected timezone
336
- return time + currentOffset * 60 - utcOffset * 60;
383
+ return time + utcOffset - currentOffset;
384
+ }
385
+ /**
386
+ * get timezone offsests in seconds
387
+ */
388
+ function getOffset(timezone, time) {
389
+ const date = new Date(time);
390
+ let offset;
391
+ // Handle Etc timezones specially since getTimezoneOffset doesn't support them
392
+ if (getZeroOffsetEtcZones().includes(timezone)) {
393
+ offset = 0;
394
+ }
395
+ else if (timezone.startsWith('Etc/GMT')) {
396
+ // Extract the offset from the zone name
397
+ // Note: Etc/GMT+X means UTC-X (opposite sign)
398
+ const match = timezone.match(/Etc\/GMT([+-])(\d+)/);
399
+ if (match) {
400
+ const sign = match[1];
401
+ const hours = parseInt(match[2], 10);
402
+ offset = (sign === '+' ? -hours : +hours) * 60 * 60;
403
+ }
404
+ else {
405
+ offset = 0;
406
+ }
407
+ }
408
+ else {
409
+ offset = (new TZDateMini(date, timezone)).getTimezoneOffset() * -60;
410
+ }
411
+ return offset;
337
412
  }
338
413
  /**
339
414
  * Get time formatted with the provided timezone
340
415
  */
341
416
  function getTimeString(time) {
342
- return moment(time).format('YYYY-MM-DD HH:mm:ss');
417
+ return format(new Date(time), 'yyyy-MM-dd HH:mm:ss');
343
418
  }
344
419
  /**
345
420
  * Get the time range string by time array, eg: 2018-10-25 10:10:00 ~ 2018-10-25 12:12:00
@@ -673,13 +748,13 @@ class UIService {
673
748
  const networkOut = infoItem([Item.kpi, 'Network Out'], [Item.yScale, 0,], [Item.yScaleGroup, ScaleGroup.Network], [Item.unit, Unit.MBPerSec], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Bytes written to network by all processes']);
674
749
  const swapIn = infoItem([Item.kpi, 'Swap In'], [Item.yScale, 100], [Item.yScaleGroup, ScaleGroup.Swap], [Item.unit, Unit.MBPerSec], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Bytes read from swap by all processes (pswpin line in /proc/vmstat * sysconf(_SC_PAGESIZE))']);
675
750
  const swapOut = infoItem([Item.kpi, 'Swap Out'], [Item.yScale, 100], [Item.yScaleGroup, ScaleGroup.Swap], [Item.unit, Unit.MBPerSec], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Bytes written To swap by all processes (pswpout line in /proc/vmstat * sysconf(_SC_PAGESIZE))']);
676
- const indexserverCpu = infoItem([Item.kpi, 'Index Server CPU'], [Item.yScale, 0,], [Item.yScaleGroup, ScaleGroup.CPU], [Item.unit, Unit.PCT], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'CPU used by Service']);
751
+ const indexserverCpu = infoItem([Item.kpi, 'Service CPU'], [Item.yScale, 0,], [Item.yScaleGroup, ScaleGroup.CPU], [Item.unit, Unit.PCT], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'CPU used by Service']);
677
752
  const indexserverCpuSys = infoItem([Item.kpi, 'System CPU'], [Item.yScale, 0,], [Item.yScaleGroup, ScaleGroup.CPU], [Item.unit, Unit.PCT], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'OS Kernel/System CPU used by Service']);
678
753
  const indexserverMemUsed = infoItem([Item.kpi, 'Memory Used'], [Item.yScale, 0,], [Item.yScaleGroup, ScaleGroup.Memory], [Item.unit, Unit.MB], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Memory used by Service']);
679
754
  const indexserverMemLimit = infoItem([Item.kpi, 'Memory Allocation Limit'], [Item.yScale, 0,], [Item.yScaleGroup, ScaleGroup.Memory], [Item.unit, Unit.MB], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Memory allocation limit for Service']);
680
755
  const indexserverHandles = infoItem([Item.kpi, 'Handles'], [Item.yScale, 0,], [Item.yScaleGroup, ScaleGroup.Unknown], [Item.unit, Unit.Empty], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Number of open handles']);
681
756
  const indexserverPingtime = infoItem([Item.kpi, 'Ping Time'], [Item.yScale, 0,], [Item.yScaleGroup, ScaleGroup.Unknown], [Item.unit, Unit.MS], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Duration of Service ping request (THREAD_METHOD=\'__nsWatchdog\'). This request includes the collection of service specific KPI\'s']);
682
- const indexserverSwapIn = infoItem([Item.kpi, 'Index Server Swap In'], [Item.yScale, 100], [Item.yScaleGroup, ScaleGroup.Swap], [Item.unit, Unit.MBPerSec], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Bytes read from swap by Service (column 12(majflt) in /proc/<pid>/stat * sysconf(_SC_PAGESIZE))']);
757
+ const indexserverSwapIn = infoItem([Item.kpi, 'Service Swap In'], [Item.yScale, 100], [Item.yScaleGroup, ScaleGroup.Swap], [Item.unit, Unit.MBPerSec], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Bytes read from swap by Service (column 12(majflt) in /proc/<pid>/stat * sysconf(_SC_PAGESIZE))']);
683
758
  const sqlConnections = infoItem([Item.kpi, 'Open Connections'], [Item.yScale, 0,], [Item.yScaleGroup, ScaleGroup.Conn], [Item.unit, Unit.Empty], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Number of open SQL connections']);
684
759
  const internalConnections = infoItem([Item.kpi, 'Internal Connections'], [Item.yScale, 0,], [Item.yScaleGroup, ScaleGroup.Conn], [Item.unit, Unit.Empty], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Number of open SQL internal connections']);
685
760
  const externalConnections = infoItem([Item.kpi, 'External Connections'], [Item.yScale, 0,], [Item.yScaleGroup, ScaleGroup.Conn], [Item.unit, Unit.Empty], [Item.max, -1], [Item.average, -1], [Item.sum, -1], [Item.last, -1], [Item.description, 'Number of open SQL external connections']);
@@ -823,7 +898,7 @@ class UIService {
823
898
  };
824
899
  return {
825
900
  'Host': loadHistoryInfoHost,
826
- 'Index Server': loadHistoryInfoIndexServer,
901
+ 'Service': loadHistoryInfoIndexServer,
827
902
  'SQL': loadHistoryInfoSQL,
828
903
  'Row Store': loadHistoryInfoRowStore,
829
904
  'Column Store': loadHistoryInfoColumnStore,
@@ -1145,18 +1220,33 @@ class ChartService {
1145
1220
  /**
1146
1221
  * Generate DataSets by the data and header information
1147
1222
  */
1148
- static _generateDataSets(data, header, headerKey, defaultItems) {
1223
+ static _generateDataSets(data, header, headerKey, defaultItems, yScale) {
1149
1224
  const alpha = 0.5;
1150
1225
  const colors = UIService.getColors(alpha);
1151
1226
  return data.map((item, i) => {
1152
1227
  const color = colors[headerKey[i]] ? getColorString(colors[headerKey[i]]) : randomColor(alpha);
1228
+ // only cap 100 which is percentage
1229
+ if (yScale[i] === 100) {
1230
+ // to save some memory, change the value directly
1231
+ // cappedData = item.map(dp =>
1232
+ // dp.y > 100 ? { ...dp, y: 100, originalY: dp.y } : dp
1233
+ // );
1234
+ // }
1235
+ for (let j = 0, len = item.length; j < len; j++) {
1236
+ const dp = item[j];
1237
+ if (dp.y > 100) {
1238
+ dp.originalY = dp.y;
1239
+ dp.y = 100;
1240
+ }
1241
+ }
1242
+ }
1153
1243
  return {
1154
1244
  borderColor: color,
1155
1245
  backgroundColor: color,
1156
1246
  borderWidth: 1,
1157
1247
  spanGaps: false,
1158
1248
  label: header[i],
1159
- data: data[i],
1249
+ data: item,
1160
1250
  fill: false,
1161
1251
  yAxisID: `y-axis-${i}`,
1162
1252
  hidden: !defaultItems.includes(header[i]),
@@ -1177,17 +1267,17 @@ class ChartService {
1177
1267
  type: 'time',
1178
1268
  time: {
1179
1269
  displayFormats: {
1180
- 'millisecond': 'MMMDD HH:mm:ss',
1181
- 'second': 'MMMDD HH:mm:ss',
1182
- 'minute': 'MMMDD HH:mm',
1183
- 'hour': 'MMMDD HH',
1184
- 'day': 'MMMDD',
1185
- 'week': 'MMMDD',
1186
- 'month': 'MMM YYYY',
1187
- 'quarter': 'MMM YYYY',
1188
- 'year': 'MMM YYYY',
1270
+ 'millisecond': 'MMMdd HH:mm:ss',
1271
+ 'second': 'MMMdd HH:mm:ss',
1272
+ 'minute': 'MMMdd HH:mm',
1273
+ 'hour': 'MMMdd HH',
1274
+ 'day': 'MMMdd',
1275
+ 'week': 'MMMdd',
1276
+ 'month': 'MMM yyyy',
1277
+ 'quarter': 'MMM yyyy',
1278
+ 'year': 'MMM yyyy',
1189
1279
  },
1190
- tooltipFormat: 'll HH:mm:ss'
1280
+ tooltipFormat: 'MMM dd, yyyy HH:mm:ss'
1191
1281
  },
1192
1282
  min: timeArray[0],
1193
1283
  max: timeArray[timeArray.length - 1],
@@ -1195,10 +1285,7 @@ class ChartService {
1195
1285
  source: 'auto',
1196
1286
  maxRotation: 0,
1197
1287
  autoSkip: true,
1198
- // callback: function(val, index) {
1199
- // // Hide every 2nd tick label
1200
- // return index % 2 === 0? this.getLabelForValue(val) : '';
1201
- // },
1288
+ autoSkipPadding: 40, // label space
1202
1289
  },
1203
1290
  reverse: false
1204
1291
  }
@@ -1225,7 +1312,7 @@ class ChartService {
1225
1312
  return {
1226
1313
  type: 'line',
1227
1314
  data: {
1228
- datasets: ChartService._generateDataSets(data, header, headerKey, defaultItems)
1315
+ datasets: ChartService._generateDataSets(data, header, headerKey, defaultItems, yScale)
1229
1316
  },
1230
1317
  options: {
1231
1318
  layout: {
@@ -1234,9 +1321,9 @@ class ChartService {
1234
1321
  }
1235
1322
  },
1236
1323
  interaction: {
1237
- intersect: true, // true means not a range hit
1324
+ intersect: true, // true means must actually hover over a point
1238
1325
  axis: 'x',
1239
- mode: 'nearest'
1326
+ mode: 'index' // when intersecting, show all datasets at the same index/x position
1240
1327
  },
1241
1328
  responsive: true,
1242
1329
  animation: false, // must disable it otherwise zoomin will hang
@@ -1268,6 +1355,8 @@ class ChartService {
1268
1355
  text: title
1269
1356
  },
1270
1357
  tooltip: {
1358
+ mode: 'nearest',
1359
+ intersect: true, // true means only show tooltip for the closest point
1271
1360
  callbacks: {
1272
1361
  label: function (context) {
1273
1362
  // format numbers with commas and add unit information
@@ -1276,10 +1365,14 @@ class ChartService {
1276
1365
  // get unit (eg: MB, GB, MB/s, % and so on)
1277
1366
  const rowItem = tableSource.find(controlTableRow => label === controlTableRow.KPI) || '';
1278
1367
  const unit = rowItem[Item.unit] && rowItem[Item.unit] !== Unit.PCT ? ` ${rowItem[Item.unit]}` : rowItem[Item.unit] || '';
1279
- return `${label}: ${getNumberWithCommas(context.parsed.y)}${unit}`;
1368
+ // Use original value if available, otherwise use displayed value
1369
+ const valueToShow = context.raw?.originalY ?? context.parsed.y;
1370
+ return `${label}: ${getNumberWithCommas(valueToShow)}${unit}`;
1280
1371
  }
1281
1372
  else {
1282
- return getNumberWithCommas(context.parsed.y);
1373
+ // Use original value if available, otherwise use displayed value
1374
+ const valueToShow = context.raw?.originalY ?? context.parsed.y;
1375
+ return getNumberWithCommas(valueToShow);
1283
1376
  }
1284
1377
  }
1285
1378
  }
@@ -1288,7 +1381,7 @@ class ChartService {
1288
1381
  decimation: {
1289
1382
  enabled: true,
1290
1383
  algorithm: 'lttb', // Largest-Triangle-Three-Buckets algorithm
1291
- samples: 500, // Increased samples for better quality
1384
+ samples: 600, // Increased samples for better quality
1292
1385
  threshold: 1 // increase it may hang the ui due to swith of using/not using downsampling, disable it (set it to 0), will slowdown average zoom in.
1293
1386
  },
1294
1387
  zoom: {
@@ -2265,15 +2358,15 @@ class TimezoneSelectorService {
2265
2358
  /**
2266
2359
  * get the default timezone
2267
2360
  */
2268
- getDefaultTimezone() {
2269
- return getDefaultTimezone();
2361
+ get defaultTimezone() {
2362
+ return defaultTimezone();
2270
2363
  }
2271
2364
  /**
2272
2365
  * Get all the timezones for each region
2273
2366
  */
2274
2367
  getZones() {
2275
2368
  const timezones = [];
2276
- const zones = moment.tz.names();
2369
+ const zones = supportedTimezones();
2277
2370
  zones.forEach(zone => {
2278
2371
  // get region
2279
2372
  let region;
@@ -2284,6 +2377,16 @@ class TimezoneSelectorService {
2284
2377
  });
2285
2378
  return timezones;
2286
2379
  }
2380
+ getFormattedZone(region, zone) {
2381
+ return `${region} - ${this._formatTimezone(zone)} ${this._getOffset(zone)}`;
2382
+ }
2383
+ _getOffset(zone) {
2384
+ const offsetMinutes = getOffset(zone, Date.now()) / 60;
2385
+ const absOffset = Math.abs(offsetMinutes);
2386
+ const hours = Math.floor(absOffset / 60);
2387
+ const minutes = absOffset % 60;
2388
+ return `(GMT${offsetMinutes < 0 ? '-' : '+'}${this._formatNumber(hours)}:${this._formatNumber(minutes)})`;
2389
+ }
2287
2390
  /**
2288
2391
  * build timezone lists
2289
2392
  */
@@ -2297,6 +2400,13 @@ class TimezoneSelectorService {
2297
2400
  timezoneRegion.zones.push(zone);
2298
2401
  }
2299
2402
  }
2403
+ _formatTimezone(zone) {
2404
+ const tz = zone.split('/');
2405
+ return tz[tz.length - 1].replace('_', ' ');
2406
+ }
2407
+ _formatNumber(number) {
2408
+ return number < 10 || !number ? `0${number}` : `${number}`;
2409
+ }
2300
2410
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TimezoneSelectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2301
2411
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TimezoneSelectorService }); }
2302
2412
  }
@@ -2305,40 +2415,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
2305
2415
  }] });
2306
2416
 
2307
2417
  class TimezoneSelectorComponent {
2308
- static _formatNumber(number) {
2309
- return number < 10 || !number ? `0${number}` : `${number}`;
2310
- }
2311
2418
  constructor(service) {
2312
2419
  this.service = service;
2313
2420
  this.disabled = false;
2314
2421
  this.timezoneChange = new EventEmitter();
2315
- const defaultTZ = this.service.getDefaultTimezone();
2316
- this.timezones = this.service.getZones().map(tz => ({ group: tz.region, items: tz.zones.map(zone => ({ id: zone, value: zone, text: this._getFormattedZone(tz.region, zone), selected: zone === defaultTZ })) }));
2422
+ const defaultTZ = this.service.defaultTimezone;
2423
+ this.timezones = this.service.getZones().map(tz => ({ group: tz.region, items: tz.zones.map(zone => ({ id: zone, value: zone, text: this.service.getFormattedZone(tz.region, zone), selected: zone === defaultTZ })) }));
2317
2424
  }
2318
2425
  ngOnChanges(changes) {
2319
2426
  if (changes['timezone'] && changes['timezone'].currentValue) {
2320
2427
  if (this.timezones) {
2321
- this.timezones = this.service.getZones().map(tz => ({ group: tz.region, items: tz.zones.map(zone => ({ id: zone, value: zone, text: this._getFormattedZone(tz.region, zone), selected: zone === changes['timezone'].currentValue })) }));
2428
+ this.timezones = this.service.getZones().map(tz => ({ group: tz.region, items: tz.zones.map(zone => ({ id: zone, value: zone, text: this.service.getFormattedZone(tz.region, zone), selected: zone === changes['timezone'].currentValue })) }));
2322
2429
  }
2323
2430
  }
2324
2431
  }
2325
- _getFormattedZone(region, zone) {
2326
- return `${region} - ${this._formatTimezone(zone)} ${this._getOffset(zone)}`;
2327
- }
2328
- _formatTimezone(zone) {
2329
- const tz = zone.split('/');
2330
- return tz[tz.length - 1].replace('_', ' ');
2331
- }
2332
- _getOffset(zone) {
2333
- let offset = moment.tz(zone).utcOffset();
2334
- const neg = offset < 0;
2335
- if (neg) {
2336
- offset = -1 * offset;
2337
- }
2338
- const hours = Math.floor(offset / 60);
2339
- const minutes = (offset / 60 - hours) * 60;
2340
- return `(GMT${neg ? '-' : '+'}${TimezoneSelectorComponent._formatNumber(hours)}:${TimezoneSelectorComponent._formatNumber(minutes)})`;
2341
- }
2342
2432
  /**
2343
2433
  * onChange function called by the "ngx-select" element
2344
2434
  * @param selectedTimezone The timezone string selected
@@ -2470,6 +2560,10 @@ class NameServerHistoryComponent {
2470
2560
  * Input (optional) bind to [showInstruction]
2471
2561
  */
2472
2562
  this.showInstruction = true;
2563
+ /**
2564
+ * update timezone value
2565
+ */
2566
+ this.timezoneChange = new EventEmitter();
2473
2567
  /**
2474
2568
  * time info of the name server history file
2475
2569
  */
@@ -2634,6 +2728,14 @@ class NameServerHistoryComponent {
2634
2728
  const nameserverHistoryContentElement = this.nameserverHistoryContentRef ? this.nameserverHistoryContentRef.nativeElement : null;
2635
2729
  setChartHeight(nameserverHistoryAllElement, nameserverHistoryContentElement);
2636
2730
  }
2731
+ /**
2732
+ * Handle timezone change from timezone-selector
2733
+ * @param newTimezone the new timezone value
2734
+ */
2735
+ onTimezoneChange(newTimezone) {
2736
+ this.timezone = newTimezone;
2737
+ this.timezoneChange.emit(newTimezone);
2738
+ }
2637
2739
  /**
2638
2740
  * Switch port and reinitialize chart, triggered by changing the port
2639
2741
  * @param port the selected port
@@ -2659,7 +2761,7 @@ class NameServerHistoryComponent {
2659
2761
  ]);
2660
2762
  // init the environment with switch flag
2661
2763
  this._initChartEnv(true).then(() => {
2662
- return this._buildChart(port, null, true);
2764
+ return this._buildChart(port, null, this.servicePortInfo?.[this.host]?.[port], true);
2663
2765
  }).catch(e => this._showMessage(Alert.error, e));
2664
2766
  }
2665
2767
  }
@@ -2673,7 +2775,7 @@ class NameServerHistoryComponent {
2673
2775
  * get default timezone
2674
2776
  */
2675
2777
  get defaultTimezone() {
2676
- return getDefaultTimezone();
2778
+ return defaultTimezone();
2677
2779
  }
2678
2780
  /**
2679
2781
  * get the key column (KPI)
@@ -2783,7 +2885,7 @@ class NameServerHistoryComponent {
2783
2885
  }
2784
2886
  }
2785
2887
  return sleep(100).then(() => {
2786
- return this._buildChart(port, ports);
2888
+ return this._buildChart(port, ports, this.servicePortInfo?.[this.host]?.[port]);
2787
2889
  });
2788
2890
  });
2789
2891
  });
@@ -2819,12 +2921,13 @@ class NameServerHistoryComponent {
2819
2921
  * build and display the chart on page
2820
2922
  * @param port the selected port
2821
2923
  * @param ports all available ports
2924
+ * @param service service name
2822
2925
  * @param switchFlag indicates whether this function is triggered from switching ports (no init port selector needed)
2823
2926
  */
2824
- _buildChart(port, ports, switchFlag = false) {
2927
+ _buildChart(port, ports, service, switchFlag = false) {
2825
2928
  const beginTime = new Date();
2826
2929
  if (port) {
2827
- return Promise.resolve(this._loadSettingsForSelectionsTable(port))
2930
+ return Promise.resolve(this._loadSettingsForSelectionsTable(port, service))
2828
2931
  .then(() => {
2829
2932
  // get the config
2830
2933
  return this.chartService.buildChart(this.time[port], this.data[port], this.uiService.getYScale(this._headerKey, port), this._headerText, this._headerKey, this._selection, this.tableSource, this._getHostTitle(port), this.uiService.getDisplayItems(this._headerKey, port, this.defaultSelectedItems), this._onZoom.bind(this))
@@ -2911,8 +3014,9 @@ class NameServerHistoryComponent {
2911
3014
  * Load settings for the selection table (the right part of the chart)
2912
3015
  * @param port the selected port
2913
3016
  */
2914
- _loadSettingsForSelectionsTable(port) {
3017
+ _loadSettingsForSelectionsTable(port, service) {
2915
3018
  this.tableSource = this.uiService.getSelectionTableRows(this._headerKey, port, this.defaultSelectedItems);
3019
+ this._updateServiceHeader(port, service);
2916
3020
  this._selection = new SelectionModel(true, []);
2917
3021
  this.tableSource.forEach(row => {
2918
3022
  if (this.uiService.getDisplayItems(this._headerKey, port, this.defaultSelectedItems).includes(row.KPI)) {
@@ -2920,6 +3024,17 @@ class NameServerHistoryComponent {
2920
3024
  }
2921
3025
  });
2922
3026
  }
3027
+ /**
3028
+ * Replace confusing service type, issue: https://github.com/ckyycc/ngx-hana-nameserver-history-viewer/issues/14
3029
+ * by default will replaced it with Service (port), eg: Service (30015)
3030
+ *if topology is imported, it will be: Name Server (30001) or Index Server (30040), and so on...
3031
+ */
3032
+ _updateServiceHeader(port, service) {
3033
+ const serviceHeader = this.tableSource.find(ts => ts[this.kpiColumn] === 'Service' && ts.header);
3034
+ if (serviceHeader) {
3035
+ serviceHeader[this.kpiColumn] = `${getHANAServiceDisplayName(service) || 'Service'} (${port})`;
3036
+ }
3037
+ }
2923
3038
  /**
2924
3039
  * Show messages
2925
3040
  * @param type type of the message
@@ -2969,11 +3084,11 @@ class NameServerHistoryComponent {
2969
3084
  }
2970
3085
  }
2971
3086
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: NameServerHistoryComponent, deps: [{ token: FileService }, { token: ChartService }, { token: UIService }], target: i0.ɵɵFactoryTarget.Component }); }
2972
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.1", type: NameServerHistoryComponent, isStandalone: true, selector: "ngx-hana-nameserver-history-viewer", inputs: { defaultSelectedItems: "defaultSelectedItems", hideMeasureColumns: "hideMeasureColumns", maxRowsLimitation: "maxRowsLimitation", showInstruction: "showInstruction", timezone: "timezone", fileBuffer: "fileBuffer", streamModeFileName: "streamModeFileName", autoDisplay: "autoDisplay" }, providers: [FileService, ChartService, UIService], viewQueries: [{ propertyName: "nameserverHistoryAllRef", first: true, predicate: ["nameserverHistoryAll"], descendants: true, read: ElementRef }, { propertyName: "nameserverHistoryContentRef", first: true, predicate: ["nameserverHistoryContent"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<div #nameserverHistoryAll class=\"nameserver-history-all\" (window:resize)=\"onResize()\">\r\n <div class=\"toolbar-chart\">\r\n <div class=\"upload-box-content\">\r\n <div *ngIf=\"!showReadFileProgress\">\r\n <file-drop-input (fileDrop)=\"fileDropped($event)\" (fileInput)=\"fileSelected($event)\"\r\n [dropAreaText]= \"abbreviatedFileName\"\r\n [inputAreaText]=\"'Browse'\"\r\n [title]=\"file?.name? file.name:'Select a name server history file from your local disk.'\"\r\n *ngIf=\"!fileBuffer\">\r\n </file-drop-input>\r\n <p *ngIf=\"fileBuffer\" class=\"box-stream-mode-text\">{{streamModeFileName || 'nameserver_history.trc (stream mode)'}}</p>\r\n </div>\r\n <div *ngIf=\"showReadFileProgress\">\r\n <progress-bar [progress]=\"readProgress\"></progress-bar>\r\n </div>\r\n </div>\r\n <div class=\"input-time\">\r\n <div class=\"input-time-range\">\r\n <time-range-selector [disabled]=\"showReadFileProgress\" [(dateTimeRange)]=\"dateTimeRange\"></time-range-selector>\r\n </div>\r\n <div class=\"timezone-selector\">\r\n <timezone-selector [(timezone)]=\"timezone\" [disabled]=\"showReadFileProgress\"></timezone-selector>\r\n </div>\r\n </div>\r\n\r\n <div class=\"port-selection\">\r\n <div class=\"port-selector\">\r\n <port-selector (portChange)=\"switchPortForChart($event)\" [(port)]=\"port\" [ports]=\"ports\" [disabled]=\"showReadFileProgress\"></port-selector>\r\n </div>\r\n <div class=\"port-load-button\">\r\n <button (click)=\"loadPorts()\" title=\"Load all ports from name server history trace file.\" [disabled]=\"!enableShowChartButton || port || !enableLoadPortsButton\">{{showReadFileProgress? \"Loading...\" : \"Load\"}}</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chart-operation\">\r\n <div class=\"left\">\r\n <button (click)=\"showChart()\" title=\"Load and display all data from name server history trace file.\" [disabled]=\"!enableShowChartButton\">{{showReadFileProgress? \"Loading...\" : \"Show\"}}</button>\r\n </div>\r\n <div class=\"right\">\r\n <button (click)=\"resetChart()\" title=\"Reset zoom of chart.\" [disabled]=\"showReadFileProgress || !enableResetChartButton\">Reset Chart</button>\r\n </div>\r\n </div>\r\n </div>\r\n <div #nameserverHistoryContent class=\"nameserver-history-content\">\r\n <div class=\"nameserver-history-content-chart\">\r\n <instruction [(show)]=\"showInstruction\" *ngIf=\"!showChartFlag && showInstruction\"\r\n [step1Finished]=\"!!file\"\r\n [step2Finished]=\"dateTimeRange && (!!dateTimeRange[0] || !!dateTimeRange[1]) || timezone != defaultTimezone\"\r\n [step3Finished]=\"!!port\"\r\n [step4Finished]=\"stepShowChart && !enableShowChartButton\"\r\n [step5Finished]=\"false\">\r\n </instruction>\r\n <canvas id=\"chartNameServerHistory\" ></canvas>\r\n </div>\r\n <div class=\"nameserver-history-content-controller\" >\r\n <ngx-selection-table (change)=\"selectItem($event)\" *ngIf=\"showChartFlag\"\r\n [filter]=\"true\"\r\n [checkbox]=\"true\"\r\n [tableSource]=\"tableSource\"\r\n [keyColumn]=\"kpiColumn\"\r\n [hiddenColumns]=\"hiddenColumns\"\r\n [tooltipColumn]=\"descColumn\"\r\n [searchStyle]=\"searchType\"\r\n [searchColumn]=\"kpiColumn\"\r\n [multiSelection]=\"true\">\r\n </ngx-selection-table>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"message-container\" *ngIf=\"alertMessage\">\r\n <alert [(alertMessage)]=\"alertMessage\" [alertType]=\"alertType\" [alertTimeout]=\"30000\"></alert>\r\n</div>\r\n", styles: [":host *,:host *:before,:host *:after{box-sizing:inherit;display:inherit;font-size:inherit;font-weight:inherit;font-family:inherit}:host .hover-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{outline:0;box-shadow:0 0 6px #23adff}:host .dashed-box,:host .nameserver-history-all .toolbar-chart .chart-operation button,:host .nameserver-history-all .toolbar-chart .port-selection,:host .nameserver-history-all .toolbar-chart .input-time,:host .nameserver-history-all .toolbar-chart .upload-box-content{background:#f8f8f8;box-shadow:inset 0 20px 20px -20px #0009;border:1px dashed #0782d0}:host .solid-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{background:#fff none;border:1px solid #ccc;border-radius:4px;line-height:1.42857143}:host .nameserver-history-all{width:98%;min-width:1314px;height:auto;border:1px none #0782d0;border-bottom-style:dashed;margin:3px 1%;box-sizing:border-box;display:inline-block;font-size:14px;font-weight:400;font-family:Helvetica,Arial,sans-serif}:host .nameserver-history-all .toolbar-chart{width:100%;height:48px}:host .nameserver-history-all .toolbar-chart button{text-align:center;white-space:nowrap;vertical-align:middle}:host .nameserver-history-all .toolbar-chart button:hover{text-shadow:1px 1px 3px royalblue;cursor:pointer;font-weight:600}:host .nameserver-history-all .toolbar-chart button:disabled{text-shadow:none;opacity:.65;cursor:default;color:#a9a9a9;font-weight:400}:host .nameserver-history-all .toolbar-chart .upload-box-content{width:20%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .upload-box-content .box-stream-mode-text{text-align:center;color:#00008b}:host .nameserver-history-all .toolbar-chart .input-time{margin-left:1%;margin-right:1%;width:43%;height:100%}:host .nameserver-history-all .toolbar-chart .input-time .input-time-range{height:100%;width:57%;float:left}:host .nameserver-history-all .toolbar-chart .input-time .timezone-selector{margin-top:6px;height:100%;width:42.5%;margin-right:.5%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection{width:14%;margin-right:1%;height:48px}:host .nameserver-history-all .toolbar-chart .port-selection .port-selector{margin-top:6px;margin-left:2%;margin-right:1%;width:47%;float:left}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button{margin-top:6px;margin-left:1%;margin-right:2%;width:47%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{color:#333;width:100%;padding:6px 12px;margin-bottom:0}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{text-shadow:None;font-weight:400}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:disabled{box-shadow:none}:host .nameserver-history-all .toolbar-chart .chart-operation{width:20%;height:48px;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation .left{margin-right:1%;width:49%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .chart-operation .right{width:50%;height:100%;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation button{width:100%;height:100%;color:#00008b}:host .nameserver-history-all .nameserver-history-content{width:100%;height:730px;margin:5px 5px 5px 0}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-chart{width:75%;height:100%;position:relative;float:left}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-controller{width:25%;height:100%;float:right;overflow:auto}:host .message-container{width:98%;margin:0 1%;box-sizing:border-box;display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: AlertComponent, selector: "alert", inputs: ["alertMessage", "alertType", "alertTimeout"], outputs: ["alertMessageChange"] }, { kind: "component", type: TimezoneSelectorComponent, selector: "timezone-selector", inputs: ["disabled", "timezone"], outputs: ["timezoneChange"] }, { kind: "component", type: TimeRangeSelectorComponent, selector: "time-range-selector", inputs: ["disabled", "dateTimeRange"], outputs: ["dateTimeRangeChange"] }, { kind: "component", type: ProgressBarComponent, selector: "progress-bar", inputs: ["progress"] }, { kind: "component", type: PortSelectorComponent, selector: "port-selector", inputs: ["disabled", "port", "ports"], outputs: ["portChange"] }, { kind: "component", type: InstructionComponent, selector: "instruction", inputs: ["step1Finished", "step2Finished", "step3Finished", "step4Finished", "step5Finished", "show"], outputs: ["showChange"] }, { kind: "component", type: FileDropInputComponent, selector: "file-drop-input", inputs: ["dropAreaText", "inputAreaText"], outputs: ["fileDrop", "fileInput"] }, { kind: "component", type: SelectionTableComponent, selector: "ngx-selection-table", inputs: ["filter", "keyColumn", "tableSource", "checkbox", "multiSelection", "clickToSelect", "hiddenColumns", "tooltipColumn", "searchStyle", "searchColumn"], outputs: ["change"] }, { kind: "ngmodule", type: OwlDateTimeModule }, { kind: "ngmodule", type: OwlNativeDateTimeModule }] }); }
3087
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.1", type: NameServerHistoryComponent, isStandalone: true, selector: "ngx-hana-nameserver-history-viewer", inputs: { defaultSelectedItems: "defaultSelectedItems", hideMeasureColumns: "hideMeasureColumns", maxRowsLimitation: "maxRowsLimitation", showInstruction: "showInstruction", timezone: "timezone", fileBuffer: "fileBuffer", streamModeFileName: "streamModeFileName", autoDisplay: "autoDisplay", servicePortInfo: "servicePortInfo" }, outputs: { timezoneChange: "timezoneChange" }, providers: [FileService, ChartService, UIService], viewQueries: [{ propertyName: "nameserverHistoryAllRef", first: true, predicate: ["nameserverHistoryAll"], descendants: true, read: ElementRef }, { propertyName: "nameserverHistoryContentRef", first: true, predicate: ["nameserverHistoryContent"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<div #nameserverHistoryAll class=\"nameserver-history-all\" (window:resize)=\"onResize()\">\r\n <div class=\"toolbar-chart\">\r\n <div class=\"upload-box-content\">\r\n <div *ngIf=\"!showReadFileProgress\">\r\n <file-drop-input (fileDrop)=\"fileDropped($event)\" (fileInput)=\"fileSelected($event)\"\r\n [dropAreaText]= \"abbreviatedFileName\"\r\n [inputAreaText]=\"'Browse'\"\r\n [title]=\"file?.name? file.name:'Select a name server history file from your local disk.'\"\r\n *ngIf=\"!fileBuffer\">\r\n </file-drop-input>\r\n <p *ngIf=\"fileBuffer\" class=\"box-stream-mode-text\">{{streamModeFileName || 'nameserver_history.trc (stream mode)'}}</p>\r\n </div>\r\n <div *ngIf=\"showReadFileProgress\">\r\n <progress-bar [progress]=\"readProgress\"></progress-bar>\r\n </div>\r\n </div>\r\n <div class=\"input-time\">\r\n <div class=\"input-time-range\">\r\n <time-range-selector [disabled]=\"showReadFileProgress\" [(dateTimeRange)]=\"dateTimeRange\"></time-range-selector>\r\n </div>\r\n <div class=\"timezone-selector\">\r\n <timezone-selector [(timezone)]=\"timezone\" (timezoneChange)=\"onTimezoneChange($event)\" [disabled]=\"showReadFileProgress\"></timezone-selector>\r\n </div>\r\n </div>\r\n\r\n <div class=\"port-selection\">\r\n <div class=\"port-selector\">\r\n <port-selector (portChange)=\"switchPortForChart($event)\" [(port)]=\"port\" [ports]=\"ports\" [disabled]=\"showReadFileProgress\"></port-selector>\r\n </div>\r\n <div class=\"port-load-button\">\r\n <button (click)=\"loadPorts()\" title=\"Load all ports from name server history trace file.\" [disabled]=\"!enableShowChartButton || port || !enableLoadPortsButton\">{{showReadFileProgress? \"Loading...\" : \"Load\"}}</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chart-operation\">\r\n <div class=\"left\">\r\n <button (click)=\"showChart()\" title=\"Load and display all data from name server history trace file.\" [disabled]=\"!enableShowChartButton\">{{showReadFileProgress? \"Loading...\" : \"Show\"}}</button>\r\n </div>\r\n <div class=\"right\">\r\n <button (click)=\"resetChart()\" title=\"Reset zoom of chart.\" [disabled]=\"showReadFileProgress || !enableResetChartButton\">Reset Chart</button>\r\n </div>\r\n </div>\r\n </div>\r\n <div #nameserverHistoryContent class=\"nameserver-history-content\">\r\n <div class=\"nameserver-history-content-chart\">\r\n <instruction [(show)]=\"showInstruction\" *ngIf=\"!showChartFlag && showInstruction\"\r\n [step1Finished]=\"!!file\"\r\n [step2Finished]=\"dateTimeRange && (!!dateTimeRange[0] || !!dateTimeRange[1]) || timezone != defaultTimezone\"\r\n [step3Finished]=\"!!port\"\r\n [step4Finished]=\"stepShowChart && !enableShowChartButton\"\r\n [step5Finished]=\"false\">\r\n </instruction>\r\n <canvas id=\"chartNameServerHistory\" ></canvas>\r\n </div>\r\n <div class=\"nameserver-history-content-controller\" >\r\n <ngx-selection-table (change)=\"selectItem($event)\" *ngIf=\"showChartFlag\"\r\n [filter]=\"true\"\r\n [checkbox]=\"true\"\r\n [tableSource]=\"tableSource\"\r\n [keyColumn]=\"kpiColumn\"\r\n [hiddenColumns]=\"hiddenColumns\"\r\n [tooltipColumn]=\"descColumn\"\r\n [searchStyle]=\"searchType\"\r\n [searchColumn]=\"kpiColumn\"\r\n [multiSelection]=\"true\">\r\n </ngx-selection-table>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"message-container\" *ngIf=\"alertMessage\">\r\n <alert [(alertMessage)]=\"alertMessage\" [alertType]=\"alertType\" [alertTimeout]=\"30000\"></alert>\r\n</div>\r\n", styles: [":host *,:host *:before,:host *:after{box-sizing:inherit;display:inherit;font-size:inherit;font-weight:inherit;font-family:inherit}:host .hover-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{outline:0;box-shadow:0 0 6px #23adff}:host .dashed-box,:host .nameserver-history-all .toolbar-chart .chart-operation button,:host .nameserver-history-all .toolbar-chart .port-selection,:host .nameserver-history-all .toolbar-chart .input-time,:host .nameserver-history-all .toolbar-chart .upload-box-content{background:#f8f8f8;box-shadow:inset 0 20px 20px -20px #0009;border:1px dashed #0782d0}:host .solid-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{background:#fff none;border:1px solid #ccc;border-radius:4px;line-height:1.42857143}:host .nameserver-history-all{width:98%;min-width:1314px;height:auto;border:1px none #0782d0;border-bottom-style:dashed;margin:3px 1%;box-sizing:border-box;display:inline-block;font-size:14px;font-weight:400;font-family:Helvetica,Arial,sans-serif}:host .nameserver-history-all .toolbar-chart{width:100%;height:48px}:host .nameserver-history-all .toolbar-chart button{text-align:center;white-space:nowrap;vertical-align:middle}:host .nameserver-history-all .toolbar-chart button:hover{text-shadow:1px 1px 3px royalblue;cursor:pointer;font-weight:600}:host .nameserver-history-all .toolbar-chart button:disabled{text-shadow:none;opacity:.65;cursor:default;color:#a9a9a9;font-weight:400}:host .nameserver-history-all .toolbar-chart .upload-box-content{width:20%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .upload-box-content .box-stream-mode-text{text-align:center;color:#00008b}:host .nameserver-history-all .toolbar-chart .input-time{margin-left:1%;margin-right:1%;width:43%;height:100%}:host .nameserver-history-all .toolbar-chart .input-time .input-time-range{height:100%;width:57%;float:left}:host .nameserver-history-all .toolbar-chart .input-time .timezone-selector{margin-top:6px;height:100%;width:42.5%;margin-right:.5%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection{width:14%;margin-right:1%;height:48px}:host .nameserver-history-all .toolbar-chart .port-selection .port-selector{margin-top:6px;margin-left:2%;margin-right:1%;width:47%;float:left}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button{margin-top:6px;margin-left:1%;margin-right:2%;width:47%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{color:#333;width:100%;padding:6px 12px;margin-bottom:0}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{text-shadow:None;font-weight:400}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:disabled{box-shadow:none}:host .nameserver-history-all .toolbar-chart .chart-operation{width:20%;height:48px;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation .left{margin-right:1%;width:49%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .chart-operation .right{width:50%;height:100%;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation button{width:100%;height:100%;color:#00008b}:host .nameserver-history-all .nameserver-history-content{width:100%;height:730px;margin:5px 5px 5px 0}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-chart{width:75%;height:100%;position:relative;float:left}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-controller{width:25%;height:100%;float:right;overflow:auto}:host .message-container{width:98%;margin:0 1%;box-sizing:border-box;display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: AlertComponent, selector: "alert", inputs: ["alertMessage", "alertType", "alertTimeout"], outputs: ["alertMessageChange"] }, { kind: "component", type: TimezoneSelectorComponent, selector: "timezone-selector", inputs: ["disabled", "timezone"], outputs: ["timezoneChange"] }, { kind: "component", type: TimeRangeSelectorComponent, selector: "time-range-selector", inputs: ["disabled", "dateTimeRange"], outputs: ["dateTimeRangeChange"] }, { kind: "component", type: ProgressBarComponent, selector: "progress-bar", inputs: ["progress"] }, { kind: "component", type: PortSelectorComponent, selector: "port-selector", inputs: ["disabled", "port", "ports"], outputs: ["portChange"] }, { kind: "component", type: InstructionComponent, selector: "instruction", inputs: ["step1Finished", "step2Finished", "step3Finished", "step4Finished", "step5Finished", "show"], outputs: ["showChange"] }, { kind: "component", type: FileDropInputComponent, selector: "file-drop-input", inputs: ["dropAreaText", "inputAreaText"], outputs: ["fileDrop", "fileInput"] }, { kind: "component", type: SelectionTableComponent, selector: "ngx-selection-table", inputs: ["filter", "keyColumn", "tableSource", "checkbox", "multiSelection", "clickToSelect", "hiddenColumns", "tooltipColumn", "searchStyle", "searchColumn"], outputs: ["change"] }, { kind: "ngmodule", type: OwlDateTimeModule }, { kind: "ngmodule", type: OwlNativeDateTimeModule }] }); }
2973
3088
  }
2974
3089
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: NameServerHistoryComponent, decorators: [{
2975
3090
  type: Component,
2976
- args: [{ selector: 'ngx-hana-nameserver-history-viewer', providers: [FileService, ChartService, UIService], standalone: true, imports: [CommonModule, AlertComponent, TimezoneSelectorComponent, TimeRangeSelectorComponent, ProgressBarComponent, PortSelectorComponent, InstructionComponent, FileDropInputComponent, SelectionTableComponent, OwlDateTimeModule, OwlNativeDateTimeModule], template: "<div #nameserverHistoryAll class=\"nameserver-history-all\" (window:resize)=\"onResize()\">\r\n <div class=\"toolbar-chart\">\r\n <div class=\"upload-box-content\">\r\n <div *ngIf=\"!showReadFileProgress\">\r\n <file-drop-input (fileDrop)=\"fileDropped($event)\" (fileInput)=\"fileSelected($event)\"\r\n [dropAreaText]= \"abbreviatedFileName\"\r\n [inputAreaText]=\"'Browse'\"\r\n [title]=\"file?.name? file.name:'Select a name server history file from your local disk.'\"\r\n *ngIf=\"!fileBuffer\">\r\n </file-drop-input>\r\n <p *ngIf=\"fileBuffer\" class=\"box-stream-mode-text\">{{streamModeFileName || 'nameserver_history.trc (stream mode)'}}</p>\r\n </div>\r\n <div *ngIf=\"showReadFileProgress\">\r\n <progress-bar [progress]=\"readProgress\"></progress-bar>\r\n </div>\r\n </div>\r\n <div class=\"input-time\">\r\n <div class=\"input-time-range\">\r\n <time-range-selector [disabled]=\"showReadFileProgress\" [(dateTimeRange)]=\"dateTimeRange\"></time-range-selector>\r\n </div>\r\n <div class=\"timezone-selector\">\r\n <timezone-selector [(timezone)]=\"timezone\" [disabled]=\"showReadFileProgress\"></timezone-selector>\r\n </div>\r\n </div>\r\n\r\n <div class=\"port-selection\">\r\n <div class=\"port-selector\">\r\n <port-selector (portChange)=\"switchPortForChart($event)\" [(port)]=\"port\" [ports]=\"ports\" [disabled]=\"showReadFileProgress\"></port-selector>\r\n </div>\r\n <div class=\"port-load-button\">\r\n <button (click)=\"loadPorts()\" title=\"Load all ports from name server history trace file.\" [disabled]=\"!enableShowChartButton || port || !enableLoadPortsButton\">{{showReadFileProgress? \"Loading...\" : \"Load\"}}</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chart-operation\">\r\n <div class=\"left\">\r\n <button (click)=\"showChart()\" title=\"Load and display all data from name server history trace file.\" [disabled]=\"!enableShowChartButton\">{{showReadFileProgress? \"Loading...\" : \"Show\"}}</button>\r\n </div>\r\n <div class=\"right\">\r\n <button (click)=\"resetChart()\" title=\"Reset zoom of chart.\" [disabled]=\"showReadFileProgress || !enableResetChartButton\">Reset Chart</button>\r\n </div>\r\n </div>\r\n </div>\r\n <div #nameserverHistoryContent class=\"nameserver-history-content\">\r\n <div class=\"nameserver-history-content-chart\">\r\n <instruction [(show)]=\"showInstruction\" *ngIf=\"!showChartFlag && showInstruction\"\r\n [step1Finished]=\"!!file\"\r\n [step2Finished]=\"dateTimeRange && (!!dateTimeRange[0] || !!dateTimeRange[1]) || timezone != defaultTimezone\"\r\n [step3Finished]=\"!!port\"\r\n [step4Finished]=\"stepShowChart && !enableShowChartButton\"\r\n [step5Finished]=\"false\">\r\n </instruction>\r\n <canvas id=\"chartNameServerHistory\" ></canvas>\r\n </div>\r\n <div class=\"nameserver-history-content-controller\" >\r\n <ngx-selection-table (change)=\"selectItem($event)\" *ngIf=\"showChartFlag\"\r\n [filter]=\"true\"\r\n [checkbox]=\"true\"\r\n [tableSource]=\"tableSource\"\r\n [keyColumn]=\"kpiColumn\"\r\n [hiddenColumns]=\"hiddenColumns\"\r\n [tooltipColumn]=\"descColumn\"\r\n [searchStyle]=\"searchType\"\r\n [searchColumn]=\"kpiColumn\"\r\n [multiSelection]=\"true\">\r\n </ngx-selection-table>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"message-container\" *ngIf=\"alertMessage\">\r\n <alert [(alertMessage)]=\"alertMessage\" [alertType]=\"alertType\" [alertTimeout]=\"30000\"></alert>\r\n</div>\r\n", styles: [":host *,:host *:before,:host *:after{box-sizing:inherit;display:inherit;font-size:inherit;font-weight:inherit;font-family:inherit}:host .hover-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{outline:0;box-shadow:0 0 6px #23adff}:host .dashed-box,:host .nameserver-history-all .toolbar-chart .chart-operation button,:host .nameserver-history-all .toolbar-chart .port-selection,:host .nameserver-history-all .toolbar-chart .input-time,:host .nameserver-history-all .toolbar-chart .upload-box-content{background:#f8f8f8;box-shadow:inset 0 20px 20px -20px #0009;border:1px dashed #0782d0}:host .solid-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{background:#fff none;border:1px solid #ccc;border-radius:4px;line-height:1.42857143}:host .nameserver-history-all{width:98%;min-width:1314px;height:auto;border:1px none #0782d0;border-bottom-style:dashed;margin:3px 1%;box-sizing:border-box;display:inline-block;font-size:14px;font-weight:400;font-family:Helvetica,Arial,sans-serif}:host .nameserver-history-all .toolbar-chart{width:100%;height:48px}:host .nameserver-history-all .toolbar-chart button{text-align:center;white-space:nowrap;vertical-align:middle}:host .nameserver-history-all .toolbar-chart button:hover{text-shadow:1px 1px 3px royalblue;cursor:pointer;font-weight:600}:host .nameserver-history-all .toolbar-chart button:disabled{text-shadow:none;opacity:.65;cursor:default;color:#a9a9a9;font-weight:400}:host .nameserver-history-all .toolbar-chart .upload-box-content{width:20%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .upload-box-content .box-stream-mode-text{text-align:center;color:#00008b}:host .nameserver-history-all .toolbar-chart .input-time{margin-left:1%;margin-right:1%;width:43%;height:100%}:host .nameserver-history-all .toolbar-chart .input-time .input-time-range{height:100%;width:57%;float:left}:host .nameserver-history-all .toolbar-chart .input-time .timezone-selector{margin-top:6px;height:100%;width:42.5%;margin-right:.5%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection{width:14%;margin-right:1%;height:48px}:host .nameserver-history-all .toolbar-chart .port-selection .port-selector{margin-top:6px;margin-left:2%;margin-right:1%;width:47%;float:left}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button{margin-top:6px;margin-left:1%;margin-right:2%;width:47%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{color:#333;width:100%;padding:6px 12px;margin-bottom:0}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{text-shadow:None;font-weight:400}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:disabled{box-shadow:none}:host .nameserver-history-all .toolbar-chart .chart-operation{width:20%;height:48px;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation .left{margin-right:1%;width:49%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .chart-operation .right{width:50%;height:100%;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation button{width:100%;height:100%;color:#00008b}:host .nameserver-history-all .nameserver-history-content{width:100%;height:730px;margin:5px 5px 5px 0}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-chart{width:75%;height:100%;position:relative;float:left}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-controller{width:25%;height:100%;float:right;overflow:auto}:host .message-container{width:98%;margin:0 1%;box-sizing:border-box;display:inline-block}\n"] }]
3091
+ args: [{ selector: 'ngx-hana-nameserver-history-viewer', providers: [FileService, ChartService, UIService], standalone: true, imports: [CommonModule, AlertComponent, TimezoneSelectorComponent, TimeRangeSelectorComponent, ProgressBarComponent, PortSelectorComponent, InstructionComponent, FileDropInputComponent, SelectionTableComponent, OwlDateTimeModule, OwlNativeDateTimeModule], template: "<div #nameserverHistoryAll class=\"nameserver-history-all\" (window:resize)=\"onResize()\">\r\n <div class=\"toolbar-chart\">\r\n <div class=\"upload-box-content\">\r\n <div *ngIf=\"!showReadFileProgress\">\r\n <file-drop-input (fileDrop)=\"fileDropped($event)\" (fileInput)=\"fileSelected($event)\"\r\n [dropAreaText]= \"abbreviatedFileName\"\r\n [inputAreaText]=\"'Browse'\"\r\n [title]=\"file?.name? file.name:'Select a name server history file from your local disk.'\"\r\n *ngIf=\"!fileBuffer\">\r\n </file-drop-input>\r\n <p *ngIf=\"fileBuffer\" class=\"box-stream-mode-text\">{{streamModeFileName || 'nameserver_history.trc (stream mode)'}}</p>\r\n </div>\r\n <div *ngIf=\"showReadFileProgress\">\r\n <progress-bar [progress]=\"readProgress\"></progress-bar>\r\n </div>\r\n </div>\r\n <div class=\"input-time\">\r\n <div class=\"input-time-range\">\r\n <time-range-selector [disabled]=\"showReadFileProgress\" [(dateTimeRange)]=\"dateTimeRange\"></time-range-selector>\r\n </div>\r\n <div class=\"timezone-selector\">\r\n <timezone-selector [(timezone)]=\"timezone\" (timezoneChange)=\"onTimezoneChange($event)\" [disabled]=\"showReadFileProgress\"></timezone-selector>\r\n </div>\r\n </div>\r\n\r\n <div class=\"port-selection\">\r\n <div class=\"port-selector\">\r\n <port-selector (portChange)=\"switchPortForChart($event)\" [(port)]=\"port\" [ports]=\"ports\" [disabled]=\"showReadFileProgress\"></port-selector>\r\n </div>\r\n <div class=\"port-load-button\">\r\n <button (click)=\"loadPorts()\" title=\"Load all ports from name server history trace file.\" [disabled]=\"!enableShowChartButton || port || !enableLoadPortsButton\">{{showReadFileProgress? \"Loading...\" : \"Load\"}}</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chart-operation\">\r\n <div class=\"left\">\r\n <button (click)=\"showChart()\" title=\"Load and display all data from name server history trace file.\" [disabled]=\"!enableShowChartButton\">{{showReadFileProgress? \"Loading...\" : \"Show\"}}</button>\r\n </div>\r\n <div class=\"right\">\r\n <button (click)=\"resetChart()\" title=\"Reset zoom of chart.\" [disabled]=\"showReadFileProgress || !enableResetChartButton\">Reset Chart</button>\r\n </div>\r\n </div>\r\n </div>\r\n <div #nameserverHistoryContent class=\"nameserver-history-content\">\r\n <div class=\"nameserver-history-content-chart\">\r\n <instruction [(show)]=\"showInstruction\" *ngIf=\"!showChartFlag && showInstruction\"\r\n [step1Finished]=\"!!file\"\r\n [step2Finished]=\"dateTimeRange && (!!dateTimeRange[0] || !!dateTimeRange[1]) || timezone != defaultTimezone\"\r\n [step3Finished]=\"!!port\"\r\n [step4Finished]=\"stepShowChart && !enableShowChartButton\"\r\n [step5Finished]=\"false\">\r\n </instruction>\r\n <canvas id=\"chartNameServerHistory\" ></canvas>\r\n </div>\r\n <div class=\"nameserver-history-content-controller\" >\r\n <ngx-selection-table (change)=\"selectItem($event)\" *ngIf=\"showChartFlag\"\r\n [filter]=\"true\"\r\n [checkbox]=\"true\"\r\n [tableSource]=\"tableSource\"\r\n [keyColumn]=\"kpiColumn\"\r\n [hiddenColumns]=\"hiddenColumns\"\r\n [tooltipColumn]=\"descColumn\"\r\n [searchStyle]=\"searchType\"\r\n [searchColumn]=\"kpiColumn\"\r\n [multiSelection]=\"true\">\r\n </ngx-selection-table>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"message-container\" *ngIf=\"alertMessage\">\r\n <alert [(alertMessage)]=\"alertMessage\" [alertType]=\"alertType\" [alertTimeout]=\"30000\"></alert>\r\n</div>\r\n", styles: [":host *,:host *:before,:host *:after{box-sizing:inherit;display:inherit;font-size:inherit;font-weight:inherit;font-family:inherit}:host .hover-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{outline:0;box-shadow:0 0 6px #23adff}:host .dashed-box,:host .nameserver-history-all .toolbar-chart .chart-operation button,:host .nameserver-history-all .toolbar-chart .port-selection,:host .nameserver-history-all .toolbar-chart .input-time,:host .nameserver-history-all .toolbar-chart .upload-box-content{background:#f8f8f8;box-shadow:inset 0 20px 20px -20px #0009;border:1px dashed #0782d0}:host .solid-box,:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{background:#fff none;border:1px solid #ccc;border-radius:4px;line-height:1.42857143}:host .nameserver-history-all{width:98%;min-width:1314px;height:auto;border:1px none #0782d0;border-bottom-style:dashed;margin:3px 1%;box-sizing:border-box;display:inline-block;font-size:14px;font-weight:400;font-family:Helvetica,Arial,sans-serif}:host .nameserver-history-all .toolbar-chart{width:100%;height:48px}:host .nameserver-history-all .toolbar-chart button{text-align:center;white-space:nowrap;vertical-align:middle}:host .nameserver-history-all .toolbar-chart button:hover{text-shadow:1px 1px 3px royalblue;cursor:pointer;font-weight:600}:host .nameserver-history-all .toolbar-chart button:disabled{text-shadow:none;opacity:.65;cursor:default;color:#a9a9a9;font-weight:400}:host .nameserver-history-all .toolbar-chart .upload-box-content{width:20%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .upload-box-content .box-stream-mode-text{text-align:center;color:#00008b}:host .nameserver-history-all .toolbar-chart .input-time{margin-left:1%;margin-right:1%;width:43%;height:100%}:host .nameserver-history-all .toolbar-chart .input-time .input-time-range{height:100%;width:57%;float:left}:host .nameserver-history-all .toolbar-chart .input-time .timezone-selector{margin-top:6px;height:100%;width:42.5%;margin-right:.5%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection{width:14%;margin-right:1%;height:48px}:host .nameserver-history-all .toolbar-chart .port-selection .port-selector{margin-top:6px;margin-left:2%;margin-right:1%;width:47%;float:left}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button{margin-top:6px;margin-left:1%;margin-right:2%;width:47%;float:right}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button{color:#333;width:100%;padding:6px 12px;margin-bottom:0}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:hover{text-shadow:None;font-weight:400}:host .nameserver-history-all .toolbar-chart .port-selection .port-load-button button:disabled{box-shadow:none}:host .nameserver-history-all .toolbar-chart .chart-operation{width:20%;height:48px;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation .left{margin-right:1%;width:49%;height:100%;float:left}:host .nameserver-history-all .toolbar-chart .chart-operation .right{width:50%;height:100%;float:right}:host .nameserver-history-all .toolbar-chart .chart-operation button{width:100%;height:100%;color:#00008b}:host .nameserver-history-all .nameserver-history-content{width:100%;height:730px;margin:5px 5px 5px 0}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-chart{width:75%;height:100%;position:relative;float:left}:host .nameserver-history-all .nameserver-history-content .nameserver-history-content-controller{width:25%;height:100%;float:right;overflow:auto}:host .message-container{width:98%;margin:0 1%;box-sizing:border-box;display:inline-block}\n"] }]
2977
3092
  }], ctorParameters: () => [{ type: FileService }, { type: ChartService }, { type: UIService }], propDecorators: { nameserverHistoryAllRef: [{
2978
3093
  type: ViewChild,
2979
3094
  args: ['nameserverHistoryAll', { read: ElementRef }]
@@ -2996,11 +3111,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
2996
3111
  type: Input
2997
3112
  }], autoDisplay: [{
2998
3113
  type: Input
3114
+ }], servicePortInfo: [{
3115
+ type: Input
3116
+ }], timezoneChange: [{
3117
+ type: Output
2999
3118
  }] } });
3000
3119
 
3001
3120
  /**
3002
3121
  * Generated bundle index. Do not edit.
3003
3122
  */
3004
3123
 
3005
- export { NameServerHistoryComponent };
3124
+ export { NameServerHistoryComponent, supportedTimezones };
3006
3125
  //# sourceMappingURL=ngx-hana-nameserver-history-viewer.mjs.map