@capsitech/react-utilities 0.1.4 → 0.1.6

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 (45) hide show
  1. package/lib/Components/SuspenseRoute.d.ts +7 -7
  2. package/lib/Components/SuspenseRoute.js +29 -29
  3. package/lib/Components/index.d.ts +1 -1
  4. package/lib/Components/index.js +1 -1
  5. package/lib/Hooks/index.d.ts +45 -45
  6. package/lib/Hooks/index.js +98 -98
  7. package/lib/Hooks/useInfiniteScroll.d.ts +7 -7
  8. package/lib/Hooks/useInfiniteScroll.js +22 -22
  9. package/lib/Hooks/useNetworkState.d.ts +67 -67
  10. package/lib/Hooks/useNetworkState.js +41 -41
  11. package/lib/Hooks/useShortcuts.d.ts +4 -4
  12. package/lib/Hooks/useShortcuts.js +91 -91
  13. package/lib/Utilities/ApiUtility.axios.d.ts +60 -60
  14. package/lib/Utilities/ApiUtility.axios.js +305 -305
  15. package/lib/Utilities/BrowserInfo.d.ts +74 -74
  16. package/lib/Utilities/BrowserInfo.js +153 -153
  17. package/lib/Utilities/Countries.d.ts +14 -14
  18. package/lib/Utilities/Countries.js +290 -290
  19. package/lib/Utilities/CustomEventEmitter.d.ts +12 -12
  20. package/lib/Utilities/CustomEventEmitter.js +30 -30
  21. package/lib/Utilities/FastCompare.d.ts +1 -1
  22. package/lib/Utilities/FastCompare.js +128 -128
  23. package/lib/Utilities/HideablePromise.d.ts +5 -5
  24. package/lib/Utilities/HideablePromise.js +10 -10
  25. package/lib/Utilities/LoadScripts.d.ts +9 -9
  26. package/lib/Utilities/LoadScripts.js +51 -51
  27. package/lib/Utilities/MTDFraudPrevention.d.ts +28 -28
  28. package/lib/Utilities/MTDFraudPrevention.js +157 -157
  29. package/lib/Utilities/Nationalities.d.ts +5 -5
  30. package/lib/Utilities/Nationalities.js +245 -245
  31. package/lib/Utilities/RouteUtils.d.ts +129 -120
  32. package/lib/Utilities/RouteUtils.js +223 -206
  33. package/lib/Utilities/TimeZones.d.ts +10 -10
  34. package/lib/Utilities/TimeZones.js +1069 -1069
  35. package/lib/Utilities/Types.d.ts +19 -19
  36. package/lib/Utilities/Types.js +1 -1
  37. package/lib/Utilities/Utils.d.ts +174 -174
  38. package/lib/Utilities/Utils.js +331 -331
  39. package/lib/Utilities/dayjs.d.ts +18 -18
  40. package/lib/Utilities/dayjs.js +56 -56
  41. package/lib/Utilities/index.d.ts +14 -14
  42. package/lib/Utilities/index.js +14 -14
  43. package/lib/index.d.ts +3 -3
  44. package/lib/index.js +3 -3
  45. package/package.json +12 -25
@@ -1,331 +1,331 @@
1
- import React from 'react';
2
- import { useLocation } from 'react-router-dom';
3
- import { dayjs } from '../Utilities/dayjs';
4
- export const StorageMessageKey = 'ao-message';
5
- class UtilsBase {
6
- DateRegEx = /(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)[0-9]{2}/;
7
- NiNoRegEx = /([ACEHJLMOPRSWXY][A-CEGHJ-NPR-TW-Z]|B[A-CEHJ-NPR-TW-Z]|G[ACEGHJ-NPR-TW-Z]|[KT][A-CEGHJ-MPR-TW-Z]|N[A-CEGHJL-NPR-SW-Z]|Z[A-CEGHJ-NPR-TW-Y])[0-9]{6}[A-D ]/;
8
- /**
9
- * Unique id for the tab (openned browser tab)
10
- */
11
- TabIdKey;
12
- constructor() {
13
- this.TabIdKey = Math.random().toString(36).substring(2, 8);
14
- }
15
- /**
16
- * Get number from any type/value
17
- * @param num Value to get number
18
- */
19
- getNumber = (num) => {
20
- if (!num || num === '')
21
- return 0;
22
- if (typeof num === 'number')
23
- return isNaN(num) ? 0 : num;
24
- return this.getNumber(parseFloat(num.replaceAll(',', '')));
25
- };
26
- /**
27
- * Get formatted date in DD/MM/YYYY hh:mm A or DD/MM/YYYY
28
- * @param date Date to be formatted
29
- * @param emptyValue Value to return if date is empty or null
30
- * @param withTime Return date with time
31
- */
32
- getFormattedDate = (date, emptyValue, withTime, timeZone = 'Europe/London') => {
33
- if (!date || date === '')
34
- return emptyValue;
35
- const dt = typeof date === 'string' &&
36
- /^([0]?[1-9]|[1|2][0-9]|[3][0|1])[./-]([0]?[1-9]|[1][0-2])[./-]([0-9]{4}|[0-9]{2})$/.test(date)
37
- ? dayjs(date, 'DD/MM/YYYY')
38
- : dayjs(date);
39
- return dt.isValid()
40
- ? withTime
41
- ? dt.tz(timeZone).format(`DD/MM/YYYY hh:mm A`)
42
- : dt.format(`DD/MM/YYYY`)
43
- : emptyValue;
44
- };
45
- /**
46
- * Get formatted number
47
- * @param number Number to format
48
- * @param decimalPlaces Number of decimal places
49
- * @param withComma Get number with separator
50
- * @param useDashForZero Use dash for zero
51
- * @param withCurrency Prepend £ before number
52
- */
53
- getFormattedNumber = (number, decimalPlaces = 2, withComma = true, useDashForZero = false, withCurrency = false) => {
54
- if (isNaN(number))
55
- number = 0;
56
- if (useDashForZero && (!number || number === '' || number === 0 || number === '0'))
57
- return '-';
58
- var isNegative = false;
59
- if (number < 0) {
60
- isNegative = true;
61
- number = Math.abs(number);
62
- }
63
- var t = parseFloat(number)
64
- .toFixed(decimalPlaces !== null && decimalPlaces !== undefined ? decimalPlaces : 2)
65
- .split('.');
66
- var str = number;
67
- if (t.length >= 1) {
68
- str = '';
69
- //var r = t[0].slice('');
70
- var r = t[0].slice(0);
71
- for (var i = r.length - 1, j = 1; i >= 0; i--, j++) {
72
- str = r[i] + str;
73
- if (withComma && j % 3 === 0 && i > 0)
74
- str = ',' + str;
75
- }
76
- if (t.length > 1)
77
- str += '.' + t[1];
78
- }
79
- return (withCurrency ? '£' : '') + (isNegative ? `(${str})` : str);
80
- };
81
- /**
82
- * Get formatted number
83
- * @param number Number to format
84
- * @param useDashForZero Use dash for zero
85
- */
86
- getFormattedCurrency = (number, useDashForZero = false) => this.getFormattedNumber(number, 2, true, useDashForZero, true);
87
- /**
88
- * Append zero if number is less then 10
89
- * @param num Number to check
90
- */
91
- appendZero = (num) => (num < 10 ? `0${num}` : num);
92
- /**
93
- * Get formatted time (MM:SS)
94
- * @param seconds Seconds - to get time
95
- * @param minutes Minutes - to get time
96
- */
97
- getFormattedTime = (seconds, minutes = 0) => {
98
- const dateTime = new Date(0, 0, 0, 0, minutes, seconds, 0), dateTimeM = this.appendZero(dateTime.getMinutes()), dateTimeS = this.appendZero(dateTime.getSeconds());
99
- return `${dateTimeM}:${dateTimeS}`;
100
- };
101
- /**
102
- * Get formatted time from total seconds
103
- * @param seconds Total seconds to calculate hours and minutes
104
- * @param ignoreSeconds Skip seconds in output string
105
- */
106
- getFormattedSeconds = (seconds, ignoreSeconds) => {
107
- if (seconds > 0) {
108
- var hours = Math.floor(seconds / 3600);
109
- seconds %= 3600;
110
- var minutes = Math.floor(seconds / 60);
111
- seconds = Math.floor(seconds % 60);
112
- return (`${this.appendZero(hours)}:${this.appendZero(minutes)}` +
113
- (ignoreSeconds ? '' : `:${this.appendZero(seconds)}`));
114
- }
115
- return '-';
116
- };
117
- /**
118
- * Get a property value from local storage
119
- * @param {string} Key name to find the value
120
- */
121
- getLocal = (key) => {
122
- const data = localStorage.getItem(key);
123
- if (data)
124
- return JSON.parse(data);
125
- return null;
126
- };
127
- /**
128
- * Set a property with value to local storage
129
- * @param {string} Key name to find the value
130
- * @param {any} data Data/value to be stored
131
- */
132
- setLocal = (key, data) => {
133
- localStorage.setItem(key, data ? JSON.stringify(data, this.jsonReplacer) : '');
134
- };
135
- /**
136
- * Remove a property with value from local storage
137
- * @param {string} Key name to find the value
138
- */
139
- removeLocal = (key) => {
140
- localStorage.removeItem(key);
141
- };
142
- /**
143
- * Get a property value from session storage
144
- * @param {string} Key name to find the value
145
- */
146
- getSession = (key) => {
147
- const data = sessionStorage.getItem(key);
148
- if (data)
149
- return JSON.parse(data);
150
- return null;
151
- };
152
- /**
153
- * Set a property with value to session storage
154
- * @param {string} Key name to find the value
155
- * @param {any} data Data/value to be stored
156
- */
157
- setSession = (key, data) => {
158
- sessionStorage.setItem(key, data ? JSON.stringify(data, this.jsonReplacer) : '');
159
- };
160
- jsonReplacer = (key, value) => {
161
- if (value === null)
162
- return undefined;
163
- if (value === false)
164
- return undefined;
165
- return value;
166
- };
167
- /**
168
- * Get file size in kb/mb/gb etc.
169
- * @param {number} size File lenth/size
170
- */
171
- getFileSize = (size) => {
172
- var selectedSize = 0;
173
- var selectedUnit = 'b';
174
- if (size > 0) {
175
- var units = ['tb', 'gb', 'mb', 'kb', 'b'];
176
- for (var i = 0; i < units.length; i++) {
177
- var unit = units[i];
178
- var cutoff = Math.pow(1000, 4 - i) / 10;
179
- if (size >= cutoff) {
180
- selectedSize = size / Math.pow(1000, 4 - i);
181
- selectedUnit = unit;
182
- break;
183
- }
184
- }
185
- selectedSize = Math.round(10 * selectedSize) / 10; // Cutting of digits
186
- }
187
- return `${selectedSize} ${selectedUnit.toUpperCase()}`;
188
- };
189
- /**
190
- * A custom hook that builds on useLocation to parse the query string for you.
191
- */
192
- useQuery = () => new URLSearchParams(useLocation().search);
193
- /**
194
- * Sum number array
195
- * @param {number[]} arr Number array
196
- */
197
- sumArray = (arr) => arr.reduce((a, b) => a + b);
198
- /**
199
- * Get sorted array by property
200
- * @param {any[]} arr Array of objects
201
- * @param {string} key Property/field name to sort
202
- * @returns {any[]}
203
- */
204
- sortArray(arr, key) {
205
- return arr.sort((a, b) => {
206
- if (a[key] < b[key]) {
207
- return -1;
208
- }
209
- if (a[key] > b[key]) {
210
- return 1;
211
- }
212
- return 0;
213
- });
214
- }
215
- /**
216
- * Replace an item in array with index
217
- * @param arr Array of objects
218
- * @param index Index where to replace the item
219
- * @param newValue New item to be replaced with
220
- * @returns Array of objects
221
- */
222
- replaceItemAtIndex(arr, index, newValue) {
223
- return [...arr.slice(0, index), newValue, ...arr.slice(index + 1)];
224
- }
225
- /**
226
- * Remove an item from array with index
227
- * @param arr Array of objects
228
- * @param index Index which item to be removed
229
- * @returns Array of object
230
- */
231
- removeItemAtIndex(arr, index) {
232
- return [...arr.slice(0, index), ...arr.slice(index + 1)];
233
- }
234
- /**
235
- * Capitalize the words of a string
236
- * @param {string} value String or value to be capitalized
237
- * @param {boolean} lower To lowercase other chars
238
- */
239
- capitalize = (value, lower = false) => value
240
- ? (lower ? value.toLowerCase() : value).replace(/(?:^|\s)\S/g, (a) => a.toUpperCase())
241
- : '';
242
- /**
243
- * Validate current MongoDB ObjectId
244
- * @param id Id to check for ObjectId
245
- */
246
- isValidObjectId = (id) => (id && /^[a-fA-F0-9]{24}$/i.test(id) ? true : false);
247
- /**
248
- * Set a property with value to local storage and then remove imidiatly, it is usefull to send message to all opened tabs
249
- * @param {string} Key name to find the value
250
- * @param {any} data Data/value to be stored
251
- */
252
- sendMessageToAllTabs = (type, data) => {
253
- const message = {
254
- type,
255
- t: this.TabIdKey,
256
- domain: window.location.hostname,
257
- ...data,
258
- };
259
- localStorage.setItem(StorageMessageKey, JSON.stringify(message));
260
- localStorage.removeItem(StorageMessageKey);
261
- };
262
- /**
263
- * Check and get new event message, from event object
264
- * @param {StorageEvent} event Event object received in storage event listener
265
- */
266
- getStorageMessage = (event) => {
267
- if (event.key === StorageMessageKey && event.newValue) {
268
- const message = JSON.parse(event.newValue);
269
- if (message && message.t !== Utils.TabIdKey && message.domain === window.location.hostname) {
270
- return message;
271
- }
272
- }
273
- return null;
274
- };
275
- /**
276
- * Assign value to an object by key/path name
277
- * @param obj Object to assign value to
278
- * @param path key full path
279
- * @param val value to be assigned
280
- * @param separator Path separator
281
- */
282
- setNestedKeyValue = (obj, path, val, separator = '.') => {
283
- const keys = path.split(separator);
284
- const lastKey = keys.pop();
285
- const lastObj = keys.reduce((obj, key) => (obj[key] = obj[key] || {}), obj);
286
- lastObj[lastKey] = val;
287
- };
288
- /**
289
- * Get comma separated address string
290
- * @param address address object to be converted
291
- */
292
- getAddressString = (address, emptyString = '') => {
293
- if (address) {
294
- return ([
295
- address.building,
296
- address.street,
297
- address.city,
298
- address.county,
299
- address.postcode,
300
- address.country,
301
- ]
302
- .filter((v) => v && v.length > 0)
303
- .join(', ') || emptyString);
304
- }
305
- return emptyString;
306
- };
307
- /**
308
- * Get new random UUID
309
- * @returns {string}
310
- */
311
- uuid = () => {
312
- let u = '', m = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', i = 0, rb = (Math.random() * 0xffffffff) | 0;
313
- while (i++ < 36) {
314
- var c = m[i - 1], r = rb & 0xf, v = c == 'x' ? r : (r & 0x3) | 0x8;
315
- u += c == '-' || c == '4' ? c : v.toString(16);
316
- rb = i % 8 == 0 ? (Math.random() * 0xffffffff) | 0 : rb >> 4;
317
- }
318
- return u;
319
- };
320
- }
321
- export const Utils = new UtilsBase();
322
- export function useIsMountedRef() {
323
- const isMountedRef = React.useRef(null);
324
- React.useEffect(() => {
325
- isMountedRef.current = true;
326
- return () => {
327
- isMountedRef.current = false;
328
- };
329
- });
330
- return isMountedRef;
331
- }
1
+ import React from 'react';
2
+ import { useLocation } from 'react-router-dom';
3
+ import { dayjs } from '../Utilities/dayjs';
4
+ export const StorageMessageKey = 'ao-message';
5
+ class UtilsBase {
6
+ DateRegEx = /(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)[0-9]{2}/;
7
+ NiNoRegEx = /([ACEHJLMOPRSWXY][A-CEGHJ-NPR-TW-Z]|B[A-CEHJ-NPR-TW-Z]|G[ACEGHJ-NPR-TW-Z]|[KT][A-CEGHJ-MPR-TW-Z]|N[A-CEGHJL-NPR-SW-Z]|Z[A-CEGHJ-NPR-TW-Y])[0-9]{6}[A-D ]/;
8
+ /**
9
+ * Unique id for the tab (openned browser tab)
10
+ */
11
+ TabIdKey;
12
+ constructor() {
13
+ this.TabIdKey = Math.random().toString(36).substring(2, 8);
14
+ }
15
+ /**
16
+ * Get number from any type/value
17
+ * @param num Value to get number
18
+ */
19
+ getNumber = (num) => {
20
+ if (!num || num === '')
21
+ return 0;
22
+ if (typeof num === 'number')
23
+ return isNaN(num) ? 0 : num;
24
+ return this.getNumber(parseFloat(num.replaceAll(',', '')));
25
+ };
26
+ /**
27
+ * Get formatted date in DD/MM/YYYY hh:mm A or DD/MM/YYYY
28
+ * @param date Date to be formatted
29
+ * @param emptyValue Value to return if date is empty or null
30
+ * @param withTime Return date with time
31
+ */
32
+ getFormattedDate = (date, emptyValue, withTime, timeZone = 'Europe/London') => {
33
+ if (!date || date === '')
34
+ return emptyValue;
35
+ const dt = typeof date === 'string' &&
36
+ /^([0]?[1-9]|[1|2][0-9]|[3][0|1])[./-]([0]?[1-9]|[1][0-2])[./-]([0-9]{4}|[0-9]{2})$/.test(date)
37
+ ? dayjs(date, 'DD/MM/YYYY')
38
+ : dayjs(date);
39
+ return dt.isValid()
40
+ ? withTime
41
+ ? dt.tz(timeZone).format(`DD/MM/YYYY hh:mm A`)
42
+ : dt.format(`DD/MM/YYYY`)
43
+ : emptyValue;
44
+ };
45
+ /**
46
+ * Get formatted number
47
+ * @param number Number to format
48
+ * @param decimalPlaces Number of decimal places
49
+ * @param withComma Get number with separator
50
+ * @param useDashForZero Use dash for zero
51
+ * @param withCurrency Prepend £ before number
52
+ */
53
+ getFormattedNumber = (number, decimalPlaces = 2, withComma = true, useDashForZero = false, withCurrency = false) => {
54
+ if (isNaN(number))
55
+ number = 0;
56
+ if (useDashForZero && (!number || number === '' || number === 0 || number === '0'))
57
+ return '-';
58
+ var isNegative = false;
59
+ if (number < 0) {
60
+ isNegative = true;
61
+ number = Math.abs(number);
62
+ }
63
+ var t = parseFloat(number)
64
+ .toFixed(decimalPlaces !== null && decimalPlaces !== undefined ? decimalPlaces : 2)
65
+ .split('.');
66
+ var str = number;
67
+ if (t.length >= 1) {
68
+ str = '';
69
+ //var r = t[0].slice('');
70
+ var r = t[0].slice(0);
71
+ for (var i = r.length - 1, j = 1; i >= 0; i--, j++) {
72
+ str = r[i] + str;
73
+ if (withComma && j % 3 === 0 && i > 0)
74
+ str = ',' + str;
75
+ }
76
+ if (t.length > 1)
77
+ str += '.' + t[1];
78
+ }
79
+ return (withCurrency ? '£' : '') + (isNegative ? `(${str})` : str);
80
+ };
81
+ /**
82
+ * Get formatted number
83
+ * @param number Number to format
84
+ * @param useDashForZero Use dash for zero
85
+ */
86
+ getFormattedCurrency = (number, useDashForZero = false) => this.getFormattedNumber(number, 2, true, useDashForZero, true);
87
+ /**
88
+ * Append zero if number is less then 10
89
+ * @param num Number to check
90
+ */
91
+ appendZero = (num) => (num < 10 ? `0${num}` : num);
92
+ /**
93
+ * Get formatted time (MM:SS)
94
+ * @param seconds Seconds - to get time
95
+ * @param minutes Minutes - to get time
96
+ */
97
+ getFormattedTime = (seconds, minutes = 0) => {
98
+ const dateTime = new Date(0, 0, 0, 0, minutes, seconds, 0), dateTimeM = this.appendZero(dateTime.getMinutes()), dateTimeS = this.appendZero(dateTime.getSeconds());
99
+ return `${dateTimeM}:${dateTimeS}`;
100
+ };
101
+ /**
102
+ * Get formatted time from total seconds
103
+ * @param seconds Total seconds to calculate hours and minutes
104
+ * @param ignoreSeconds Skip seconds in output string
105
+ */
106
+ getFormattedSeconds = (seconds, ignoreSeconds) => {
107
+ if (seconds > 0) {
108
+ var hours = Math.floor(seconds / 3600);
109
+ seconds %= 3600;
110
+ var minutes = Math.floor(seconds / 60);
111
+ seconds = Math.floor(seconds % 60);
112
+ return (`${this.appendZero(hours)}:${this.appendZero(minutes)}` +
113
+ (ignoreSeconds ? '' : `:${this.appendZero(seconds)}`));
114
+ }
115
+ return '-';
116
+ };
117
+ /**
118
+ * Get a property value from local storage
119
+ * @param {string} Key name to find the value
120
+ */
121
+ getLocal = (key) => {
122
+ const data = localStorage.getItem(key);
123
+ if (data)
124
+ return JSON.parse(data);
125
+ return null;
126
+ };
127
+ /**
128
+ * Set a property with value to local storage
129
+ * @param {string} Key name to find the value
130
+ * @param {any} data Data/value to be stored
131
+ */
132
+ setLocal = (key, data) => {
133
+ localStorage.setItem(key, data ? JSON.stringify(data, this.jsonReplacer) : '');
134
+ };
135
+ /**
136
+ * Remove a property with value from local storage
137
+ * @param {string} Key name to find the value
138
+ */
139
+ removeLocal = (key) => {
140
+ localStorage.removeItem(key);
141
+ };
142
+ /**
143
+ * Get a property value from session storage
144
+ * @param {string} Key name to find the value
145
+ */
146
+ getSession = (key) => {
147
+ const data = sessionStorage.getItem(key);
148
+ if (data)
149
+ return JSON.parse(data);
150
+ return null;
151
+ };
152
+ /**
153
+ * Set a property with value to session storage
154
+ * @param {string} Key name to find the value
155
+ * @param {any} data Data/value to be stored
156
+ */
157
+ setSession = (key, data) => {
158
+ sessionStorage.setItem(key, data ? JSON.stringify(data, this.jsonReplacer) : '');
159
+ };
160
+ jsonReplacer = (key, value) => {
161
+ if (value === null)
162
+ return undefined;
163
+ if (value === false)
164
+ return undefined;
165
+ return value;
166
+ };
167
+ /**
168
+ * Get file size in kb/mb/gb etc.
169
+ * @param {number} size File lenth/size
170
+ */
171
+ getFileSize = (size) => {
172
+ var selectedSize = 0;
173
+ var selectedUnit = 'b';
174
+ if (size > 0) {
175
+ var units = ['tb', 'gb', 'mb', 'kb', 'b'];
176
+ for (var i = 0; i < units.length; i++) {
177
+ var unit = units[i];
178
+ var cutoff = Math.pow(1000, 4 - i) / 10;
179
+ if (size >= cutoff) {
180
+ selectedSize = size / Math.pow(1000, 4 - i);
181
+ selectedUnit = unit;
182
+ break;
183
+ }
184
+ }
185
+ selectedSize = Math.round(10 * selectedSize) / 10; // Cutting of digits
186
+ }
187
+ return `${selectedSize} ${selectedUnit.toUpperCase()}`;
188
+ };
189
+ /**
190
+ * A custom hook that builds on useLocation to parse the query string for you.
191
+ */
192
+ useQuery = () => new URLSearchParams(useLocation().search);
193
+ /**
194
+ * Sum number array
195
+ * @param {number[]} arr Number array
196
+ */
197
+ sumArray = (arr) => arr.reduce((a, b) => a + b);
198
+ /**
199
+ * Get sorted array by property
200
+ * @param {any[]} arr Array of objects
201
+ * @param {string} key Property/field name to sort
202
+ * @returns {any[]}
203
+ */
204
+ sortArray(arr, key) {
205
+ return arr.sort((a, b) => {
206
+ if (a[key] < b[key]) {
207
+ return -1;
208
+ }
209
+ if (a[key] > b[key]) {
210
+ return 1;
211
+ }
212
+ return 0;
213
+ });
214
+ }
215
+ /**
216
+ * Replace an item in array with index
217
+ * @param arr Array of objects
218
+ * @param index Index where to replace the item
219
+ * @param newValue New item to be replaced with
220
+ * @returns Array of objects
221
+ */
222
+ replaceItemAtIndex(arr, index, newValue) {
223
+ return [...arr.slice(0, index), newValue, ...arr.slice(index + 1)];
224
+ }
225
+ /**
226
+ * Remove an item from array with index
227
+ * @param arr Array of objects
228
+ * @param index Index which item to be removed
229
+ * @returns Array of object
230
+ */
231
+ removeItemAtIndex(arr, index) {
232
+ return [...arr.slice(0, index), ...arr.slice(index + 1)];
233
+ }
234
+ /**
235
+ * Capitalize the words of a string
236
+ * @param {string} value String or value to be capitalized
237
+ * @param {boolean} lower To lowercase other chars
238
+ */
239
+ capitalize = (value, lower = false) => value
240
+ ? (lower ? value.toLowerCase() : value).replace(/(?:^|\s)\S/g, (a) => a.toUpperCase())
241
+ : '';
242
+ /**
243
+ * Validate current MongoDB ObjectId
244
+ * @param id Id to check for ObjectId
245
+ */
246
+ isValidObjectId = (id) => (id && /^[a-fA-F0-9]{24}$/i.test(id) ? true : false);
247
+ /**
248
+ * Set a property with value to local storage and then remove imidiatly, it is usefull to send message to all opened tabs
249
+ * @param {string} Key name to find the value
250
+ * @param {any} data Data/value to be stored
251
+ */
252
+ sendMessageToAllTabs = (type, data) => {
253
+ const message = {
254
+ type,
255
+ t: this.TabIdKey,
256
+ domain: window.location.hostname,
257
+ ...data,
258
+ };
259
+ localStorage.setItem(StorageMessageKey, JSON.stringify(message));
260
+ localStorage.removeItem(StorageMessageKey);
261
+ };
262
+ /**
263
+ * Check and get new event message, from event object
264
+ * @param {StorageEvent} event Event object received in storage event listener
265
+ */
266
+ getStorageMessage = (event) => {
267
+ if (event.key === StorageMessageKey && event.newValue) {
268
+ const message = JSON.parse(event.newValue);
269
+ if (message && message.t !== Utils.TabIdKey && message.domain === window.location.hostname) {
270
+ return message;
271
+ }
272
+ }
273
+ return null;
274
+ };
275
+ /**
276
+ * Assign value to an object by key/path name
277
+ * @param obj Object to assign value to
278
+ * @param path key full path
279
+ * @param val value to be assigned
280
+ * @param separator Path separator
281
+ */
282
+ setNestedKeyValue = (obj, path, val, separator = '.') => {
283
+ const keys = path.split(separator);
284
+ const lastKey = keys.pop();
285
+ const lastObj = keys.reduce((obj, key) => (obj[key] = obj[key] || {}), obj);
286
+ lastObj[lastKey] = val;
287
+ };
288
+ /**
289
+ * Get comma separated address string
290
+ * @param address address object to be converted
291
+ */
292
+ getAddressString = (address, emptyString = '') => {
293
+ if (address) {
294
+ return ([
295
+ address.building,
296
+ address.street,
297
+ address.city,
298
+ address.county,
299
+ address.postcode,
300
+ address.country,
301
+ ]
302
+ .filter((v) => v && v.length > 0)
303
+ .join(', ') || emptyString);
304
+ }
305
+ return emptyString;
306
+ };
307
+ /**
308
+ * Get new random UUID
309
+ * @returns {string}
310
+ */
311
+ uuid = () => {
312
+ let u = '', m = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', i = 0, rb = (Math.random() * 0xffffffff) | 0;
313
+ while (i++ < 36) {
314
+ var c = m[i - 1], r = rb & 0xf, v = c == 'x' ? r : (r & 0x3) | 0x8;
315
+ u += c == '-' || c == '4' ? c : v.toString(16);
316
+ rb = i % 8 == 0 ? (Math.random() * 0xffffffff) | 0 : rb >> 4;
317
+ }
318
+ return u;
319
+ };
320
+ }
321
+ export const Utils = new UtilsBase();
322
+ export function useIsMountedRef() {
323
+ const isMountedRef = React.useRef(null);
324
+ React.useEffect(() => {
325
+ isMountedRef.current = true;
326
+ return () => {
327
+ isMountedRef.current = false;
328
+ };
329
+ });
330
+ return isMountedRef;
331
+ }