inviton-powerduck 0.0.154 → 0.0.156

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.
Files changed (60) hide show
  1. package/app/powerduck-initializer.ts +3 -3
  2. package/common/api-http.ts +20 -14
  3. package/common/css/ladda-themeless-zoomin.min.css +89 -89
  4. package/common/enum-translation/day-translator.ts +3 -2
  5. package/common/excel/excel-reader.ts +2 -9
  6. package/common/extensions/array-extensions.ts +116 -0
  7. package/common/extensions/string-extensions.ts +92 -0
  8. package/common/extensions/temporal-extensions.ts +115 -0
  9. package/common/scroll-utils.ts +2 -1
  10. package/common/temporal-helpers.ts +551 -0
  11. package/common/timezone-helper.ts +39 -29
  12. package/common/utils/cookie.ts +11 -8
  13. package/common/utils/date-localization-utils.ts +25 -19
  14. package/common/utils/date-utils.ts +37 -47
  15. package/common/utils/form-utils.ts +3 -1
  16. package/common/utils/language-utils.ts +21 -27
  17. package/common/utils/temporal-utils.ts +43 -0
  18. package/common/utils/upload-image-helper.ts +1 -1
  19. package/common/utils/utils.ts +14 -14
  20. package/common/validation.ts +17 -5
  21. package/components/chart-js/line-chart-flot.tsx +9 -9
  22. package/components/chart-js/thirdparty/flot/jquery.flot.categories.min.js +93 -93
  23. package/components/chart-js/thirdparty/flot/jquery.flot.crosshair.min.js +83 -83
  24. package/components/chart-js/thirdparty/flot/jquery.flot.navigate.min.js +270 -270
  25. package/components/chart-js/thirdparty/flot/jquery.flot.pie.min.js +507 -507
  26. package/components/chart-js/thirdparty/flot/jquery.flot.resize.js +7 -9
  27. package/components/chart-js/thirdparty/flot/jquery.flot.resize.min.js +9 -11
  28. package/components/chart-js/thirdparty/flot/jquery.flot.stack.min.js +104 -104
  29. package/components/chart-js/ts/line-chart-contracts.ts +2 -2
  30. package/components/container-with-breakpoints/ts/breakpoint-handler.ts +2 -2
  31. package/components/counter/testall.tsx +89 -75
  32. package/components/datatable/datatable.tsx +2379 -2375
  33. package/components/datatable/export-excel-modal.tsx +12 -14
  34. package/components/datatable/ts/reorder.ts +4 -2
  35. package/components/dropdown/index.tsx +48 -22
  36. package/components/dropdown/mobile/legacy_fdd.ts +10 -11
  37. package/components/dropzone/gallery-dropzone.tsx +394 -382
  38. package/components/fullcalendar/fullcalendar-draggable-event.tsx +8 -7
  39. package/components/fullcalendar/timegrid-calendar.tsx +60 -67
  40. package/components/image-crop/image-cropping-modal.tsx +9 -8
  41. package/components/image-crop/upload-and-crop.tsx +162 -162
  42. package/components/image-crop/vendor/jquery.Jcrop.min.css +344 -344
  43. package/components/import/import-mapper.tsx +2 -2
  44. package/components/input/daterange-picker.tsx +40 -59
  45. package/components/input/datetime-picker.tsx +45 -50
  46. package/components/input/plugins/daterangepicker/daterangepicker.min.css +400 -400
  47. package/components/input/plugins/daterangepicker/jquery.daterangepicker.min.js +346 -339
  48. package/components/input/plugins/daterangepicker/jquery.daterangepicker.ts +580 -402
  49. package/components/input/radio-button-group.tsx +2 -2
  50. package/components/input/ts/dateInputHelper.ts +1 -0
  51. package/components/input/wysiwig.tsx +12 -7
  52. package/components/svg/skilift-svg.tsx +6 -6
  53. package/package.json +2 -1
  54. package/common/date-wrapper.ts +0 -422
  55. package/common/utils/array-extend.ts +0 -215
  56. package/common/utils/array-remove.ts +0 -10
  57. package/common/utils/array-sort.ts +0 -56
  58. package/common/utils/capitalize-string.ts +0 -11
  59. package/common/utils/format-string.ts +0 -14
  60. package/common/utils/latinize-string.ts +0 -7
@@ -6,6 +6,7 @@ import moment from 'moment';
6
6
  import select2 from 'select2';
7
7
  import { isNullOrEmpty } from '../common/utils/is-null-or-empty';
8
8
  import { LanguageUtils } from '../common/utils/language-utils';
9
+ import TemporalUtils from '../common/utils/temporal-utils';
9
10
  import PowerduckState from './powerduck-state';
10
11
 
11
12
  export interface PoweduckInitFrameworkArgs {
@@ -25,8 +26,8 @@ export default class PowerduckInitializer {
25
26
  window.addEventListener('vite:preloadError', (event) => {
26
27
  const key = `${PowerduckState.getAppPrefix()}errLastReload`;
27
28
  const lastTry = Number(localStorage.getItem(key) || '0');
28
- if (new Date().getTime() - lastTry > 3000) {
29
- localStorage.setItem(key, new Date().getTime().toString());
29
+ if (TemporalUtils.dateNowMs() - lastTry > 3000) {
30
+ localStorage.setItem(key, TemporalUtils.dateNowMs().toString());
30
31
 
31
32
  if ((window as any).__routerNextTo != null && !isNullOrEmpty((window as any).__routerNextTo.path)) {
32
33
  location.href = (window as any).__routerNextTo.path;
@@ -39,7 +40,6 @@ export default class PowerduckInitializer {
39
40
 
40
41
  if (args != null) {
41
42
  if (args.supportedLanguages?.length as number > 0) {
42
- // @ts-ignore
43
43
  LanguageUtils.supportedLanguages = args.supportedLanguages as Language[];
44
44
  }
45
45
  }
@@ -1,6 +1,6 @@
1
1
  import PowerduckState from './../app/powerduck-state';
2
2
  import { AjaxProviderXhr } from './ajax-xhr';
3
- import { DateWrapper } from './date-wrapper';
3
+ import TemporalUtils from './utils/temporal-utils';
4
4
  import { PortalUtils } from './utils/utils';
5
5
 
6
6
  /**
@@ -262,9 +262,9 @@ export class AppHttpProvider {
262
262
  } else if (keyVal != null && typeof keyVal === 'object') {
263
263
  recIterate(keyVal);
264
264
  } else {
265
- if (keyVal != null && keyVal.indexOf && DateWrapper.isSerializedDate(keyVal)) {
265
+ if (keyVal != null && keyVal.indexOf && TemporalUtils.isSerializedDate(keyVal)) {
266
266
  try {
267
- obj[key] = DateWrapper.deserialize(keyVal);
267
+ obj[key] = TemporalUtils.fromString(keyVal);
268
268
  if (isNaN(obj[key].getTime())) {
269
269
  obj[key] = keyVal;
270
270
  }
@@ -281,10 +281,8 @@ export class AppHttpProvider {
281
281
  }
282
282
 
283
283
  private static performAjaxCall<T>(args: AjaxDefinition<T>, url: string): Promise<T> {
284
- const mySelf = this;
285
-
286
284
  return new (window as any).Promise((resolve, reject) => {
287
- function tryGetJSON(resp: any): any {
285
+ const tryGetJSON = (resp: any): any => {
288
286
  try {
289
287
  return JSON.parse(resp);
290
288
  } catch (e) {
@@ -294,12 +292,12 @@ export class AppHttpProvider {
294
292
  return null;
295
293
  }
296
294
  }
297
- }
295
+ };
298
296
 
299
297
  const method = (args.type || 'GET').toUpperCase();
300
298
  let data = <any>(args.data || {});
301
- const ajaxDefaults = mySelf.ajaxDefaults;
302
- const blockUiEnabled = false;
299
+ const ajaxDefaults = this.ajaxDefaults;
300
+ let blockUiEnabled = false;
303
301
  const query: string[] = [];
304
302
 
305
303
  if ((method == 'GET' || method == 'DELETE') && data != null) {
@@ -321,9 +319,17 @@ export class AppHttpProvider {
321
319
  }
322
320
 
323
321
  if (args.blockUi != null) {
324
- blockUiEnabled == args.blockUi.enabled;
322
+ if (typeof args.blockUi.enabled === 'string') {
323
+ blockUiEnabled = args.blockUi.enabled === 'true';
324
+ } else {
325
+ blockUiEnabled = args.blockUi.enabled;
326
+ }
325
327
  } else if (ajaxDefaults.blockUi != null) {
326
- blockUiEnabled == ajaxDefaults.blockUi.enabled;
328
+ if (typeof ajaxDefaults.blockUi.enabled === 'string') {
329
+ blockUiEnabled = ajaxDefaults.blockUi.enabled === 'true';
330
+ } else {
331
+ blockUiEnabled = ajaxDefaults.blockUi.enabled;
332
+ }
327
333
  }
328
334
 
329
335
  let customAuth = false;
@@ -388,7 +394,7 @@ export class AppHttpProvider {
388
394
  // Start request
389
395
  let retryCount = 0;
390
396
  const requestLoop = () => {
391
- const start = new Date().getTime();
397
+ const start = TemporalUtils.dateNowMs();
392
398
  AppHttpProvider.getRequestProvider()
393
399
  .sendRequest({
394
400
  data,
@@ -401,11 +407,11 @@ export class AppHttpProvider {
401
407
  .then((resp) => {
402
408
  if (blockUiEnabled) {
403
409
  try {
404
- mySelf.unblockUi(args);
410
+ this.unblockUi(args);
405
411
  } catch (e) { }
406
412
  }
407
413
 
408
- const stop = new Date().getTime();
414
+ const stop = TemporalUtils.dateNowMs();
409
415
  const jsonData = tryGetJSON(resp.responseText);
410
416
  if (jsonData != null) {
411
417
  AppHttpProvider.postProcessJsObject(jsonData, args.jsonAdapter);
@@ -1,89 +1,89 @@
1
- /*! Ladda http://lab.hakim.se/ladda MIT licensed Copyright (C) 2016 Hakim El Hattab, http://hakim.se ....Lightweight adaptation for Inviton API needs*/
2
- .ladda-button {
3
- position: relative;
4
- }
5
- .ladda-button .ladda-spinner {
6
- position: absolute;
7
- z-index: 2;
8
- display: inline-block;
9
- width: 32px;
10
- height: 32px;
11
- top: 50%;
12
- margin-top: 0;
13
- opacity: 0;
14
- pointer-events: none;
15
- }
16
- .ladda-button .ladda-label {
17
- position: relative;
18
- z-index: 3;
19
- }
20
- .ladda-button .ladda-progress {
21
- position: absolute;
22
- width: 0;
23
- height: 100%;
24
- left: 0;
25
- top: 0;
26
- background: rgba(0, 0, 0, 0.2);
27
- visibility: hidden;
28
- opacity: 0;
29
- -webkit-transition: 0.1s linear all !important;
30
- -moz-transition: 0.1s linear all !important;
31
- -ms-transition: 0.1s linear all !important;
32
- -o-transition: 0.1s linear all !important;
33
- transition: 0.1s linear all !important;
34
- }
35
- .ladda-button[data-loading] .ladda-progress {
36
- opacity: 1;
37
- visibility: visible;
38
- }
39
- .ladda-button,
40
- .ladda-button .ladda-label,
41
- .ladda-button .ladda-spinner {
42
- -webkit-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;
43
- -moz-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;
44
- -ms-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;
45
- -o-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;
46
- transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;
47
- }
48
- .ladda-button[data-style="zoom-in"],
49
- .ladda-button[data-style="zoom-in"] .ladda-label,
50
- .ladda-button[data-style="zoom-in"] .ladda-spinner {
51
- -webkit-transition: 0.3s ease all !important;
52
- -moz-transition: 0.3s ease all !important;
53
- -ms-transition: 0.3s ease all !important;
54
- -o-transition: 0.3s ease all !important;
55
- transition: 0.3s ease all !important;
56
- }
57
- .ladda-button[data-style="zoom-in"] {
58
- overflow: hidden;
59
- }
60
- .ladda-button[data-style="zoom-in"] .ladda-spinner {
61
- left: 50%;
62
- margin-left: -16px;
63
- -webkit-transform: scale(0.2);
64
- -moz-transform: scale(0.2);
65
- -ms-transform: scale(0.2);
66
- -o-transform: scale(0.2);
67
- transform: scale(0.2);
68
- }
69
- .ladda-button[data-style="zoom-in"] .ladda-label {
70
- position: relative;
71
- display: inline-block;
72
- }
73
- .ladda-button[data-style="zoom-in"][data-loading] .ladda-label {
74
- opacity: 0;
75
- -webkit-transform: scale(2.2);
76
- -moz-transform: scale(2.2);
77
- -ms-transform: scale(2.2);
78
- -o-transform: scale(2.2);
79
- transform: scale(2.2);
80
- }
81
- .ladda-button[data-style="zoom-in"][data-loading] .ladda-spinner {
82
- opacity: 1;
83
- margin-left: 0;
84
- -webkit-transform: none;
85
- -moz-transform: none;
86
- -ms-transform: none;
87
- -o-transform: none;
88
- transform: none;
89
- }
1
+ /*! Ladda http://lab.hakim.se/ladda MIT licensed Copyright (C) 2016 Hakim El Hattab, http://hakim.se ....Lightweight adaptation for Inviton API needs*/
2
+ .ladda-button {
3
+ position: relative;
4
+ }
5
+ .ladda-button .ladda-spinner {
6
+ position: absolute;
7
+ z-index: 2;
8
+ display: inline-block;
9
+ width: 32px;
10
+ height: 32px;
11
+ top: 50%;
12
+ margin-top: 0;
13
+ opacity: 0;
14
+ pointer-events: none;
15
+ }
16
+ .ladda-button .ladda-label {
17
+ position: relative;
18
+ z-index: 3;
19
+ }
20
+ .ladda-button .ladda-progress {
21
+ position: absolute;
22
+ width: 0;
23
+ height: 100%;
24
+ left: 0;
25
+ top: 0;
26
+ background: rgba(0, 0, 0, 0.2);
27
+ visibility: hidden;
28
+ opacity: 0;
29
+ -webkit-transition: 0.1s linear all !important;
30
+ -moz-transition: 0.1s linear all !important;
31
+ -ms-transition: 0.1s linear all !important;
32
+ -o-transition: 0.1s linear all !important;
33
+ transition: 0.1s linear all !important;
34
+ }
35
+ .ladda-button[data-loading] .ladda-progress {
36
+ opacity: 1;
37
+ visibility: visible;
38
+ }
39
+ .ladda-button,
40
+ .ladda-button .ladda-label,
41
+ .ladda-button .ladda-spinner {
42
+ -webkit-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;
43
+ -moz-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;
44
+ -ms-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;
45
+ -o-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;
46
+ transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;
47
+ }
48
+ .ladda-button[data-style="zoom-in"],
49
+ .ladda-button[data-style="zoom-in"] .ladda-label,
50
+ .ladda-button[data-style="zoom-in"] .ladda-spinner {
51
+ -webkit-transition: 0.3s ease all !important;
52
+ -moz-transition: 0.3s ease all !important;
53
+ -ms-transition: 0.3s ease all !important;
54
+ -o-transition: 0.3s ease all !important;
55
+ transition: 0.3s ease all !important;
56
+ }
57
+ .ladda-button[data-style="zoom-in"] {
58
+ overflow: hidden;
59
+ }
60
+ .ladda-button[data-style="zoom-in"] .ladda-spinner {
61
+ left: 50%;
62
+ margin-left: -16px;
63
+ -webkit-transform: scale(0.2);
64
+ -moz-transform: scale(0.2);
65
+ -ms-transform: scale(0.2);
66
+ -o-transform: scale(0.2);
67
+ transform: scale(0.2);
68
+ }
69
+ .ladda-button[data-style="zoom-in"] .ladda-label {
70
+ position: relative;
71
+ display: inline-block;
72
+ }
73
+ .ladda-button[data-style="zoom-in"][data-loading] .ladda-label {
74
+ opacity: 0;
75
+ -webkit-transform: scale(2.2);
76
+ -moz-transform: scale(2.2);
77
+ -ms-transform: scale(2.2);
78
+ -o-transform: scale(2.2);
79
+ transform: scale(2.2);
80
+ }
81
+ .ladda-button[data-style="zoom-in"][data-loading] .ladda-spinner {
82
+ opacity: 1;
83
+ margin-left: 0;
84
+ -webkit-transform: none;
85
+ -moz-transform: none;
86
+ -ms-transform: none;
87
+ -o-transform: none;
88
+ transform: none;
89
+ }
@@ -1,6 +1,6 @@
1
1
  import type { Day } from './../enums/day';
2
2
  import PowerduckState from './../../app/powerduck-state';
3
- import { capitalize } from './../utils/capitalize-string';
3
+ import { capitalize } from '../extensions/string-extensions';
4
4
 
5
5
  export default class DayTranslator {
6
6
  private static _dayMap: { [index: string]: string } = null as any;
@@ -18,12 +18,13 @@ export default class DayTranslator {
18
18
  this._dayMap = {};
19
19
  const locale = PowerduckState.getCurrentLanguage();
20
20
  for (let i = 7; i < 15; i++) {
21
+ // eslint-disable-next-line no-restricted-syntax
21
22
  const dayDate = new Date(Date.UTC(
22
23
  2015,
23
24
  5,
24
25
  i,
25
26
  ));
26
- const dayName = capitalize(dayDate.toLocaleDateString(locale, { weekday: 'long', timeZone: 'UTC' }));
27
+ const dayName = dayDate.toLocaleDateString(locale, { weekday: 'long', timeZone: 'UTC' })[capitalize]();
27
28
  const dayEnumName = dayDate.toLocaleDateString('en', { weekday: 'long', timeZone: 'UTC' }).toUpperCase();
28
29
  this._dayMap[dayEnumName] = dayName;
29
30
  }
@@ -1,7 +1,7 @@
1
1
  // var XLSX = require("xlsx");
2
2
  // import XLSX from "xlsx";
3
3
  import * as XLSX from 'xlsx/xlsx.mjs';
4
- import { DateWrapper } from '../date-wrapper';
4
+ import TemporalUtils from '../utils/temporal-utils';
5
5
  import { PortalUtils } from '../utils/utils';
6
6
 
7
7
  export class ExcelReader {
@@ -52,14 +52,7 @@ export class ExcelReader {
52
52
  let rowVal = sheetRow[i];
53
53
  if (rowVal != null) {
54
54
  if (rowVal != null && rowVal.getUTCFullYear) {
55
- rowVal = new DateWrapper(
56
- rowVal.getFullYear(),
57
- rowVal.getMonth(),
58
- rowVal.getDate(),
59
- rowVal.getHours(),
60
- rowVal.getMinutes(),
61
- rowVal.getSeconds(),
62
- );
55
+ rowVal = TemporalUtils.fromDate(rowVal);
63
56
  } else if (PortalUtils.isString(rowVal)) {
64
57
  rowVal = rowVal.trim();
65
58
  }
@@ -0,0 +1,116 @@
1
+ /* eslint-disable func-style */
2
+ export const distinct = Symbol('distinct');
3
+ function distinctImpl<T>(this: Array<T>): Array<T> {
4
+ return [...new Set(this)];
5
+ }
6
+
7
+ export const groupBy = Symbol('groupBy');
8
+ function groupByImpl<T, K>(this: Array<T>, keySelector: (item: T) => K): Map<K, T[]> {
9
+ const groups = new Map<K, T[]>();
10
+ for (const item of this) {
11
+ const key = keySelector(item);
12
+ const group = groups.get(key);
13
+ if (group) {
14
+ group.push(item);
15
+ } else {
16
+ groups.set(key, [item]);
17
+ }
18
+ }
19
+ return groups;
20
+ }
21
+
22
+ export const remove = Symbol('remove');
23
+ function removeImpl<T>(this: Array<T>, ...items: T[]) {
24
+ for (let i = 1, len = arguments.length; i < len; i++) {
25
+ // eslint-disable-next-line prefer-rest-params
26
+ const item = arguments[i];
27
+ const itemIndex = this.indexOf(item);
28
+
29
+ if (itemIndex > -1) {
30
+ this.splice(itemIndex, 1);
31
+ }
32
+ }
33
+ }
34
+
35
+ export const sortBy = Symbol('sortBy');
36
+ function sortByImpl<T>(this: T[], propName: string | ((item: T) => string | number)): Array<T> {
37
+ function dynamicSort(property) {
38
+ if (propName && {}.toString.call(propName) === '[object Function]') {
39
+ return function (a, b) {
40
+ let v1 = (<any>propName)(a);
41
+ let v2 = (<any>propName)(b);
42
+
43
+ if (v1.constructor && v1.call && v1.apply) {
44
+ v1 = v1();
45
+ }
46
+
47
+ if (v2.constructor && v2.call && v2.apply) {
48
+ v2 = v2();
49
+ }
50
+
51
+ return v1 < v2 ? -1 : v1 > v2 ? 1 : 0;
52
+ };
53
+ } else {
54
+ let propArr: string[] = property;
55
+ if (typeof property === 'string' || property instanceof String) {
56
+ propArr = <any>[property];
57
+ }
58
+
59
+ return function (a, b) {
60
+ for (let i = 0, len = propArr.length; i < len; i++) {
61
+ let currProp = propArr[i];
62
+ let sortOrder = 1;
63
+ if (currProp[0] === '-') {
64
+ sortOrder = -1;
65
+ currProp = currProp.substr(1);
66
+ }
67
+
68
+ let aVal = a[currProp];
69
+ let bVal = b[currProp];
70
+ if (aVal.constructor && aVal.call && aVal.apply) {
71
+ aVal = aVal();
72
+ }
73
+
74
+ if (bVal.constructor && bVal.call && bVal.apply) {
75
+ bVal = bVal();
76
+ }
77
+
78
+ const result = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
79
+ if (result != 0) {
80
+ return result * sortOrder;
81
+ }
82
+ }
83
+
84
+ return 0;
85
+ };
86
+ }
87
+ }
88
+
89
+ this.sort(dynamicSort(propName));
90
+ return this;
91
+ }
92
+
93
+
94
+ declare global {
95
+ export interface Array<T> {
96
+ [distinct]: typeof distinctImpl;
97
+ [groupBy]: typeof groupByImpl;
98
+ /**
99
+ * Removes given items from the Array
100
+ *
101
+ * @param items Items that should be removed from the Array
102
+ */
103
+ [remove]: typeof removeImpl;
104
+ /**
105
+ * Sorts array by given property
106
+ *
107
+ * @param propName Property name (or function returning the sort key), the array should be sorted by
108
+ */
109
+ [sortBy]: typeof sortByImpl
110
+ }
111
+ }
112
+
113
+ (Array as any).prototype[distinct] = distinctImpl;
114
+ (Array as any).prototype[groupBy] = groupByImpl;
115
+ (Array as any).prototype[remove] = removeImpl;
116
+ (Array as any).prototype[sortBy] = sortByImpl;
@@ -0,0 +1,92 @@
1
+ export const format = Symbol('format');
2
+ function formatImpl(this: string, ...replaceArgs: Array<string | number>) {
3
+ var args = arguments;
4
+ return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) {
5
+ if (m == "{{") { return "{"; }
6
+ if (m == "}}") { return "}"; }
7
+ return args[n];
8
+ });
9
+ };
10
+
11
+ export const startsWith = Symbol('startsWith');
12
+ function startsWithImpl(this: string, str: string) {
13
+ return this.indexOf(str) == 0;
14
+ };
15
+
16
+ export const endsWith = Symbol('endsWith');
17
+ function endsWithImpl(this: string, suffix: string) {
18
+ return this.indexOf(suffix, this.length - suffix.length) !== -1;
19
+ };
20
+
21
+
22
+ export const capitalize = Symbol('capitalize');
23
+ function capitalizeImpl(this: string) {
24
+ {
25
+ if (this != null) {
26
+ if (this.length > 1) {
27
+ return this.charAt(0).toUpperCase() + this.slice(1);
28
+ } else {
29
+ return this.toUpperCase();
30
+ }
31
+ } else {
32
+ return null;
33
+ }
34
+ }
35
+ }
36
+
37
+ export const latinize = Symbol('latinize');
38
+ function latinizeImpl(this: string) {
39
+ {
40
+ try {
41
+ return (<any>this).normalize('NFD').replace(/[\u0300-\u036f]/g, "");
42
+ } catch (e) {
43
+ return this as any;
44
+ }
45
+ };
46
+ }
47
+
48
+
49
+ declare global {
50
+ export interface String {
51
+ /**
52
+ * Replaces one or more format items in the string with the string specification of specified object
53
+ *
54
+ * @param replaceArgs Format objects
55
+ */
56
+ [format]: typeof formatImpl;
57
+
58
+ /**
59
+ * Determines if current string starts with given string
60
+ *
61
+ * @param str String that should be checked
62
+ */
63
+ [startsWith]: typeof startsWithImpl;
64
+
65
+ /**
66
+ * Determines if current string ends with given string
67
+ *
68
+ * @param str String that should be checked
69
+ */
70
+ [endsWith]: typeof endsWithImpl;
71
+
72
+ /**
73
+ * Returns capitalized string (with leading letter ensured in capitals)
74
+ *
75
+ * @param str String that should be capitalized
76
+ */
77
+ [capitalize]: typeof capitalizeImpl
78
+
79
+ /**
80
+ * Returns latinized string (with local accents replaced with ASCII ones)
81
+ *
82
+ * @param str String that should be latinized
83
+ */
84
+ [latinize]: typeof latinizeImpl
85
+ }
86
+ }
87
+
88
+ (String as any).prototype[format] = formatImpl;
89
+ (String as any).prototype[startsWith] = startsWithImpl;
90
+ (String as any).prototype[endsWith] = endsWithImpl;
91
+ (String as any).prototype[capitalize] = capitalizeImpl;
92
+ (String as any).prototype[latinize] = latinizeImpl;
@@ -0,0 +1,115 @@
1
+ /* eslint-disable func-style */
2
+ import { Temporal } from '@js-temporal/polyfill';
3
+ import PowerduckState from '../../app/powerduck-state';
4
+
5
+ export const toDisplayString = Symbol('toDisplayString');
6
+ function toDisplayStringImpl(
7
+ this: Temporal.PlainDateTime,
8
+ options?: {
9
+ showTime?: boolean;
10
+ showSeconds?: boolean;
11
+ monthLong?: boolean;
12
+ dayLong?: boolean;
13
+ hideDay?: boolean;
14
+ hideMonth?: boolean;
15
+ hideYear?: boolean;
16
+ language?: string;
17
+ } | boolean,
18
+ showTime?: boolean,
19
+ showSeconds?: boolean,
20
+ monthLong?: boolean,
21
+ ): string {
22
+ let opts: any = {};
23
+ if (typeof options === 'object') {
24
+ opts = options ?? {};
25
+ } else {
26
+ opts = {
27
+ showTime: options as any,
28
+ showSeconds: showTime as any,
29
+ monthLong: showSeconds,
30
+ };
31
+ }
32
+
33
+ const fmt: Intl.DateTimeFormatOptions = {
34
+ year: !opts.hideYear ? 'numeric' : undefined,
35
+ month: !opts.hideMonth ? (opts.monthLong ? 'long' : 'numeric') : undefined,
36
+ day: !opts.hideDay && !opts.dayLong ? 'numeric' : undefined,
37
+ weekday: opts.dayLong ? 'long' : undefined,
38
+ };
39
+
40
+ if (showTime || opts.showTime) {
41
+ fmt.hour = 'numeric';
42
+ fmt.minute = '2-digit';
43
+ }
44
+
45
+ if (showSeconds || opts.showSeconds) {
46
+ fmt.second = '2-digit';
47
+ }
48
+
49
+ try {
50
+ const locale = opts.language || PowerduckState.getCurrentLanguage?.() || undefined;
51
+ return this.toLocaleString(locale, fmt);
52
+ } catch {
53
+ return this.toString();
54
+ }
55
+ }
56
+
57
+ export const fromDate = Symbol('fromDate');
58
+ function fromDateImpl(this: typeof Temporal.PlainDateTime, date: Date): Temporal.PlainDateTime {
59
+ return Temporal.PlainDateTime.from({
60
+ year: date.getFullYear(),
61
+ month: date.getMonth() + 1, // JS Date months are 0-based
62
+ day: date.getDate(),
63
+ hour: date.getHours(),
64
+ minute: date.getMinutes(),
65
+ second: date.getSeconds(),
66
+ });
67
+ }
68
+
69
+ export const utcEpochMilliseconds = Symbol('utcEpochMilliseconds');
70
+ function utcEpochMillisecondsImpl(this: Temporal.PlainDateTime): number {
71
+ return this.toZonedDateTime('UTC').epochMilliseconds;
72
+ }
73
+
74
+ export const toJsDate = Symbol('toJsDate');
75
+ function toJsDateImpl(this: Temporal.PlainDateTime): Date {
76
+ // eslint-disable-next-line no-restricted-syntax
77
+ return new Date(this.toString());
78
+ }
79
+
80
+ export const toWire = Symbol('toWire');
81
+ function toWireImp(
82
+ this: Temporal.PlainDateTime,
83
+ includeTime?: boolean,
84
+ includeMs?: boolean,
85
+ ): string {
86
+ if (includeTime) {
87
+ if (includeMs) {
88
+ return this.toString();
89
+ } else {
90
+ return this.toString().split('.')[0];
91
+ }
92
+ } else {
93
+ return this.toPlainDate().toString();
94
+ }
95
+ }
96
+
97
+ declare module '@js-temporal/polyfill' {
98
+ // eslint-disable-next-line ts/no-namespace
99
+ namespace Temporal {
100
+ interface PlainDateConstructor {
101
+ [fromDate]: typeof fromDateImpl;
102
+ }
103
+ interface PlainDateTime {
104
+ [toJsDate]: typeof toJsDateImpl;
105
+ [toWire]: typeof toWireImp;
106
+ [toDisplayString]: typeof toDisplayStringImpl;
107
+ [utcEpochMilliseconds]: typeof utcEpochMillisecondsImpl;
108
+ }
109
+ }
110
+ }
111
+
112
+ (Temporal.PlainDateTime.prototype as any)[toJsDate] = toJsDateImpl;
113
+ (Temporal.PlainDateTime.prototype as any)[toWire] = toWireImp;
114
+ (Temporal.PlainDateTime.prototype as any)[toDisplayString] = toDisplayStringImpl;
115
+ (Temporal.PlainDateTime.prototype as any)[utcEpochMilliseconds] = utcEpochMillisecondsImpl;
@@ -1,5 +1,6 @@
1
1
  import type { Vue } from 'vue-facing-decorator';
2
2
  import PowerduckState from '../app/powerduck-state';
3
+ import TemporalUtils from './utils/temporal-utils';
3
4
 
4
5
  export default class ScrollUtils {
5
6
  static scrollToFirstPossibleError(context: JQuery) {
@@ -12,7 +13,7 @@ export default class ScrollUtils {
12
13
  if (scrollContext.length > 0) {
13
14
  // Prevents multiple scrolling in one run
14
15
  const lastScroll = (PowerduckState as any)._lastValidationScroll || 0;
15
- const now = new Date().getTime();
16
+ const now = TemporalUtils.dateNowMs();
16
17
  if (now - lastScroll < 800) {
17
18
  return;
18
19
  } else {