@bigbinary/neeto-commons-frontend 4.3.0 → 4.3.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/utils.d.ts CHANGED
@@ -2,44 +2,138 @@ import { Mixin, Subscription } from "@rails/actioncable";
2
2
  import dayjs from "dayjs";
3
3
  import React from "react";
4
4
  import { StringSchema } from "yup";
5
-
6
5
  export function resetAuthTokens(): void;
7
-
8
- export function withEventTargetValue(
9
- func: (value: string) => void,
10
- event: React.ChangeEvent
11
- ): void;
12
-
13
- export function withEventTargetValue(
14
- func: (value: string) => void
15
- ): React.ChangeEventHandler;
16
-
6
+ /**
7
+ *
8
+ * The withEventTargetValue function is a curried function that accepts a
9
+ *
10
+ * function as its first parameter and an event object as its second parameter. It
11
+ *
12
+ * executes the given function with the event.target.value as an argument, making
13
+ *
14
+ * it easier to extract and work with the value of form inputs or other elements
15
+ *
16
+ * that trigger events.
17
+ *
18
+ * @example
19
+ *
20
+ * const onChange = val => console.log(`Value = ${val}`);
21
+ *
22
+ * <input onChange={withEventTargetValue(onChange)} />;
23
+ *
24
+ * // For example, in this case when user types "1" in the input field, "Value = 1" will be printed in the console.
25
+ * @endexample
26
+ */
27
+ export function withEventTargetValue(func: (value: string) => void, event: React.ChangeEvent): void;
28
+ /**
29
+ *
30
+ * The withEventTargetValue function is a curried function that accepts a
31
+ *
32
+ * function as its first parameter and an event object as its second parameter. It
33
+ *
34
+ * executes the given function with the event.target.value as an argument, making
35
+ *
36
+ * it easier to extract and work with the value of form inputs or other elements
37
+ *
38
+ * that trigger events.
39
+ *
40
+ * @example
41
+ *
42
+ * const onChange = val => console.log(`Value = ${val}`);
43
+ *
44
+ * <input onChange={withEventTargetValue(onChange)} />;
45
+ *
46
+ * // For example, in this case when user types "1" in the input field, "Value = 1" will be printed in the console.
47
+ * @endexample
48
+ */
49
+ export function withEventTargetValue(func: (value: string) => void): React.ChangeEventHandler;
50
+ /**
51
+ *
52
+ * The getSubdomain function retrieves the subdomain of the current URL and
53
+ *
54
+ * returns it as a string. A subdomain is a prefix that appears before the main
55
+ *
56
+ * domain name in a URL.
57
+ *
58
+ * @example
59
+ *
60
+ * // Let the current url be "https://spinkart.example.com".
61
+ * getSubdomain();
62
+ *
63
+ * // output: spinkart
64
+ * @endexample
65
+ */
17
66
  export function getSubdomain(): string;
18
-
19
- export function simulateApiCall<T>(
20
- result: T,
21
- error?: any,
22
- errorProbability?: number,
23
- delayMs?: number
24
- ): Promise<T>;
25
-
26
- export function copyToClipboard(
27
- text: string,
28
- configs?: { showToastr?: boolean; message?: string }
29
- ): void;
30
-
67
+ /**
68
+ *
69
+ * The simulateApiCall function simulates an API call and returns a response
70
+ *
71
+ * object with a specified delay. This function is useful during frontend
72
+ *
73
+ * development when you need to mock API calls before the backend is fully
74
+ *
75
+ * implemented.
76
+ *
77
+ * @example
78
+ *
79
+ * simulateApiCall(hardCodedResponseData, hardCodedErrorResponse);
80
+ * @endexample
81
+ */
82
+ export function simulateApiCall<T>(result: T, error?: any, errorProbability?: number, delayMs?: number): Promise<T>;
83
+ /**
84
+ *
85
+ * The copyToClipboard function copies the given string to the clipboard and
86
+ *
87
+ * displays a success message, typically a toaster notification, to indicate that
88
+ *
89
+ * the operation was successful.
90
+ *
91
+ * @example
92
+ *
93
+ * copyToClipboard("https://spinkart.example.com", {
94
+ * showToastr: true,
95
+ * message: "URL copied successfully!",
96
+ * });
97
+ *
98
+ * // If the URL is copied to the clipboard, a toaster message will be shown with the message "URL copied successfully!"
99
+ * @endexample
100
+ */
101
+ export function copyToClipboard(text: string, configs?: {
102
+ showToastr?: boolean;
103
+ message?: string;
104
+ }): void;
31
105
  type buildUrlOptions = {
32
106
  toSnakeCase?: boolean;
33
107
  };
34
-
35
- export function buildUrl(
36
- route: string,
37
- params: object,
38
- options?: buildUrlOptions
39
- ): string;
40
-
108
+ /**
109
+ *
110
+ * The buildUrl function builds a URL by inflating a route-like template string
111
+ *
112
+ * (e.g., /products/:productId/variants/:id) using the provided parameters. It
113
+ *
114
+ * allows you to create URLs dynamically based on a template and replace
115
+ *
116
+ * placeholders with actual values. Any additional properties in the parameters
117
+ *
118
+ * will be transformed to snake case and attached as query parameters to the URL.
119
+ *
120
+ * @example
121
+ *
122
+ * buildUrl("/products/:id", { id: "123" }); // output "/products/123"
123
+ * buildUrl("/products", { search: "abc" }); // output "/products?search=abc"
124
+ * buildUrl("/products/:productId/variants/:variantId/attributes", {
125
+ * productId: "123",
126
+ * variantId: "456",
127
+ * search: "abc",
128
+ * page: 1,
129
+ * per_page: 10,
130
+ * }); // output "/products/123/variants/456/attributes?page=1&per_page=10&search=abc"
131
+ * buildUrl("/products", { searchTerm: "abc" }); // output "/products?search_term=abc"
132
+ * buildUrl("/products", { searchTerm: "abc" }, { toSnakeCase: false }); // output "/products?searchTerm=abc"
133
+ * @endexample
134
+ */
135
+ export function buildUrl(route: string, params: object, options?: buildUrlOptions): string;
41
136
  type DateTimeType = string | number | dayjs.Dayjs | Date | null | undefined;
42
-
43
137
  export const timeFormat: {
44
138
  fromNow: (time: DateTimeType) => string;
45
139
  time: (time: DateTimeType) => string;
@@ -57,26 +151,103 @@ export const timeFormat: {
57
151
  default: (time: DateTimeType) => string;
58
152
  defaultWithTime: (time: DateTimeType) => string;
59
153
  };
60
-
154
+ /**
155
+ *
156
+ * The dateFormat and timeFormat functions are aliases of each other, and they
157
+ *
158
+ * are used for formatting dates and times in various ways. These functions provide
159
+ *
160
+ * a convenient way to format date and time values according to specific patterns
161
+ *
162
+ * and display them in a human-readable format.
163
+ *
164
+ * @example
165
+ *
166
+ * const sourceDate = "2020-01-01T00:00:00.000Z"; // can be anything that dayjs can parse
167
+ *
168
+ * dateFormat.fromNow(date); // "3 years ago"
169
+ * timeFormat.fromNow(date); // "3 years ago"
170
+ *
171
+ * dateFormat.time(date); // "12:00 AM"
172
+ * timeFormat.time(date); // "12:00 AM"
173
+ *
174
+ * dateFormat.timeWithSeconds(date); // "12:00:00 AM"
175
+ * timeFormat.timeWithSeconds(date); // "12:00:00 AM"
176
+ *
177
+ * dateFormat.date(date); // "Jan 1, 2020"
178
+ * timeFormat.date(date); // "Jan 1, 2020"
179
+ *
180
+ * dateFormat.dateWeek(date); // "Jan 1, 2020 Wed"
181
+ * timeFormat.dateWeek(date); // "Jan 1, 2020 Wed"
182
+ *
183
+ * dateFormat.dateWeekDayExtended(date); // "Jan 1, 2020 Wednesday"
184
+ * timeFormat.dateWeekDayExtended(date); // "Jan 1, 2020 Wednesday"
185
+ *
186
+ * dateFormat.dateWeekWithoutYear(date); // "Jan 1, Wed"
187
+ * timeFormat.dateWeekWithoutYear(date); // "Jan 1, Wed"
188
+ *
189
+ * dateFormat.dateWeekWithoutYearDayExtended(date); // "Jan 1, Wednesday"
190
+ * timeFormat.dateWeekWithoutYearDayExtended(date); // "Jan 1, Wednesday"
191
+ *
192
+ * dateFormat.dateTime(date); // "Jan 1, 2020 12:00 AM"
193
+ * timeFormat.dateTime(date); // "Jan 1, 2020 12:00 AM"
194
+ *
195
+ * dateFormat.dateTimeWithSeconds(date); // "Jan 1, 2020 12:00:00 AM"
196
+ * timeFormat.dateTimeWithSeconds(date); // "Jan 1, 2020 12:00:00 AM"
197
+ *
198
+ * dateFormat.dateWeekTime(date); // "Jan 1, 2020 Wed 12:00 AM"
199
+ * timeFormat.dateWeekTime(date); // "Jan 1, 2020 Wed 12:00 AM"
200
+ *
201
+ * dateFormat.dateWeekTimeDayExtended(date); // "Jan 1, 2020 Wednesday 12:00 AM"
202
+ * timeFormat.dateWeekTimeDayExtended(date); // "Jan 1, 2020 Wednesday 12:00 AM"
203
+ *
204
+ * dateFormat.extended(date); // "Wednesday January 1, 2020 12:00 AM (3 years ago)"
205
+ * timeFormat.extended(date); // "Wednesday January 1, 2020 12:00 AM (3 years ago)"
206
+ *
207
+ * dateFormat.default(date); // This will return date in user date format in globalProps
208
+ * timeFormat.default(date); // This will return date in user date format in globalProps
209
+ *
210
+ * dateFormat.defaultWithTime(date); // This will return date time in user date format in globalProps
211
+ * timeFormat.defaultWithTime(date); // This will return date time in user date format in globalProps
212
+ * @endexample
213
+ * All neeto-applications should be using any one of these styles (according to the
214
+ *
215
+ * space available) to display date and time unless if the case is too specific to
216
+ *
217
+ * the project.
218
+ *
219
+ */
61
220
  export const dateFormat: typeof timeFormat;
62
-
63
- export function toLocale(
64
- number: string | number,
65
- options?: Intl.NumberFormatOptions
66
- ): string;
67
-
221
+ /**
222
+ *
223
+ * The toLocale function converts a given number to a locale-specific string
224
+ *
225
+ * representation, formatting it with commas as thousands separators and respecting
226
+ *
227
+ * the appropriate decimal separator for the locale. It automatically detects the
228
+ *
229
+ * appropriate locale using globalProps and falls back to the user's browser
230
+ *
231
+ * locale if necessary.
232
+ *
233
+ * @example
234
+ *
235
+ * toLocale(1000000); // "1,000,000" when locale is "en-US"
236
+ * toLocale(1000000); // "10,00,000" when locale is "en-IN"
237
+ * toLocale(1000000.987, { maximumFractionDigits: 2 }); // "1,000,000.99"
238
+ * toLocale(1000000.987, {
239
+ * currencyDisplay: "narrowSymbol",
240
+ * style: "currency",
241
+ * currency: "INR",
242
+ * }); // "₹1,000,000.99"
243
+ * @endexample
244
+ */
245
+ export function toLocale(number: string | number, options?: Intl.NumberFormatOptions): string;
68
246
  export type qsOptionsType = {
69
247
  comma?: boolean | undefined;
70
248
  delimiter?: string | RegExp | undefined;
71
249
  depth?: number | false | undefined;
72
- decoder?:
73
- | ((
74
- str: string,
75
- defaultDecoder: any,
76
- charset: string,
77
- type: "key" | "value"
78
- ) => any)
79
- | undefined;
250
+ decoder?: ((str: string, defaultDecoder: any, charset: string, type: "key" | "value") => any) | undefined;
80
251
  arrayLimit?: number | undefined;
81
252
  parseArrays?: boolean | undefined;
82
253
  allowDots?: boolean | undefined;
@@ -90,68 +261,372 @@ export type qsOptionsType = {
90
261
  interpretNumericEntities?: boolean | undefined;
91
262
  toCamelCase?: boolean | undefined;
92
263
  };
93
-
94
- export type QueryParamsType = { [key: string]: any };
95
-
264
+ export type QueryParamsType = {
265
+ [key: string]: any;
266
+ };
267
+ /**
268
+ *
269
+ * The getQueryParams function retrieves all the query parameters from the
270
+ *
271
+ * current URL and returns them as an object. Query parameters are typically found
272
+ *
273
+ * in the URL following a "?" character and are used to pass data to a web page or
274
+ *
275
+ * API.
276
+ *
277
+ * This function will return an object containing all the query parameters in camel
278
+ *
279
+ * case. It will return an empty object if no query parameters are present.
280
+ *
281
+ * You can set toCamelCase to false if you don't want to apply any transformation to the keys.
282
+ *
283
+ * to false.
284
+ *
285
+ * More details on working:
286
+ *
287
+ * https://www.loom.com/share/4f369cff56e845428d5ef7451759469c
288
+ *
289
+ * @example
290
+ *
291
+ * // Let the current url be "https://example.com?search=something&sort_by=date&order_by=desc".
292
+ * getQueryParams();
293
+ * // output: { search: "something", sort_by: "date", order_by: "desc" }
294
+ *
295
+ * const { search, sortBy, orderBy } = getQueryParams();
296
+ *
297
+ * const { search, sort_by, order_by } = getQueryParams({ toCamelCase: false });
298
+ * @endexample
299
+ */
96
300
  export function getQueryParams(options?: qsOptionsType): QueryParamsType;
97
-
301
+ /**
302
+ *
303
+ * The joinHyphenCase function joins an array of strings using hyphens as the
304
+ *
305
+ * delimiter and returns the resulting string.
306
+ *
307
+ * Any number of string arguments.
308
+ *
309
+ * @example
310
+ *
311
+ * joinHyphenCase("hello", "world"); // output: "hello-world"
312
+ * @endexample
313
+ */
98
314
  export function joinHyphenCase(...args: string[]): string;
99
-
315
+ /**
316
+ *
317
+ * The hyphenize function converts strings that contain underscores, spaces, and
318
+ *
319
+ * camelCase strings into hyphenized strings
320
+ *
321
+ * @example
322
+ *
323
+ * hyphenize("hello_world", ""); // output: "hello-world"
324
+ * @endexample
325
+ */
100
326
  export function hyphenize(value: string, fallbackString?: string): string;
101
-
327
+ /**
328
+ *
329
+ * The debounce function is used to create a debounced function that delays the
330
+ *
331
+ * execution of a given function until a specified wait time, in milliseconds, has
332
+ *
333
+ * elapsed since the last time it was invoked.
334
+ *
335
+ * @example
336
+ *
337
+ * const searchForProducts = debounce(async key => {
338
+ * // this function will be triggered once after user stops typing for 300ms
339
+ * const products = await productsApi.fetch(key);
340
+ * // do something with the products
341
+ * }, 300);
342
+ * <input onChange={e => searchForProducts(e.target.value)} />;
343
+ * @endexample
344
+ */
102
345
  export function debounce<F extends Function>(func: F, delay?: number): F;
103
-
346
+ /**
347
+ *
348
+ * The hasPermission function checks whether the current user has a specific
349
+ *
350
+ * permission. It returns true if the user has the specified permission and
351
+ *
352
+ * false if they do not. Permissions are typically used to control access to
353
+ *
354
+ * various features or actions within an application. The permissions corresponding
355
+ *
356
+ * to a particular user is taken from the globalProps.
357
+ *
358
+ * @example
359
+ *
360
+ * hasPermission("user.view_settings");
361
+ * @endexample
362
+ */
104
363
  export function hasPermission(permission: string): boolean;
364
+ /**
365
+ *
366
+ * The hasAnyPermission function checks whether the current user has any of the
367
+ *
368
+ * specified permissions. It returns true if the user has at least one of the
369
+ *
370
+ * permissions and false if the user has none of them. The permissions
371
+ *
372
+ * corresponding to a particular user is taken from the globalProps.
373
+ *
374
+ * permissions: Any number of permission strings.
375
+ *
376
+ * @example
377
+ *
378
+ * hasAnyPermission("user.view_settings", "user.edit_settings");
379
+ * @endexample
380
+ */
105
381
  export function hasAnyPermission(...permissions: string[]): boolean;
382
+ /**
383
+ *
384
+ * The hasAllPermissions function checks whether the current user has all of the
385
+ *
386
+ * specified permissions. It returns true if the user has all the permissions and
387
+ *
388
+ * false otherwise. The permissions corresponding to a particular user is taken
389
+ *
390
+ * from the globalProps.
391
+ *
392
+ * permissions: Any number of permission strings.
393
+ *
394
+ * @example
395
+ *
396
+ * hasAllPermissions("user.view_settings", "user.edit_settings");
397
+ * @endexample
398
+ */
106
399
  export function hasAllPermissions(...permissions: string[]): boolean;
107
-
108
- type ChannelNameWithParams = { channel: string;[key: string]: any };
109
-
110
- export function createSubscription(
111
- channelName: string | ChannelNameWithParams,
112
- callbacks: Mixin
113
- ): Subscription;
114
-
400
+ type ChannelNameWithParams = {
401
+ channel: string;
402
+ [key: string]: any;
403
+ };
404
+ /**
405
+ *
406
+ * The createSubscription function is used to create a subscription in a web
407
+ *
408
+ * application where a consumer subscribes to a Rails
409
+ *
410
+ * Action Cable
411
+ *
412
+ * channel. This function facilitates the creation of subscriptions on the client
413
+ *
414
+ * side to listen for updates and events broadcasted on a specific channel.
415
+ *
416
+ * @example
417
+ *
418
+ * const subscription = createSubscription(
419
+ * {
420
+ * channel: "testChannel",
421
+ * deployment_id: "deploymentId",
422
+ * },
423
+ * { received: value => handleValue(value) }
424
+ * );
425
+ * @endexample
426
+ */
427
+ export function createSubscription(channelName: string | ChannelNameWithParams, callbacks: Mixin): Subscription;
428
+ /**
429
+ *
430
+ * The getFromLocalStorage function retrieves a JSON-parsed value from the
431
+ *
432
+ * browser's localStorage for the specified key. If the stored value is not valid
433
+ *
434
+ * JSON or if the key does not exist in localStorage, the function returns
435
+ *
436
+ * null.
437
+ *
438
+ * @example
439
+ *
440
+ * localStorage.setItem("key", JSON.stringify({ a: 1 }));
441
+ * getFromLocalStorage("key"); //returns { a: 1 }
442
+ * @endexample
443
+ */
115
444
  export function getFromLocalStorage<T extends object>(key: string): T | null;
116
-
445
+ /**
446
+ *
447
+ * The setToLocalStorage function takes a key and a value as its parameters
448
+ *
449
+ * and save the stringified representation of the value under the specified key
450
+ *
451
+ * within local storage.
452
+ *
453
+ * @example
454
+ *
455
+ * setToLocalStorage("token", "1234-5678-9101-1213");
456
+ * @endexample
457
+ */
117
458
  export function setToLocalStorage(key: string, value: any): void;
118
-
459
+ /**
460
+ *
461
+ * The removeFromLocalStorage function takes a key as its parameter, and will
462
+ *
463
+ * remove that key from the given Storage object if it exists.
464
+ *
465
+ * @example
466
+ *
467
+ * removeFromLocalStorage("token");
468
+ * @endexample
469
+ */
119
470
  export function removeFromLocalStorage(key: string): void;
120
-
121
- type CurrencyFormatterFunction = (
122
- amount: number | string,
123
- currency: string,
124
- options?: Intl.NumberFormatOptions
125
- ) => string;
126
-
471
+ type CurrencyFormatterFunction = (amount: number | string, currency: string, options?: Intl.NumberFormatOptions) => string;
472
+ /**
473
+ *
474
+ * currencyFormat is a utility which provides functions which formats a given
475
+ *
476
+ * number in currency formats based on the current user locale. Current user locale
477
+ *
478
+ * is based on dayjs.locale().
479
+ *
480
+ * withAmount accepts two arguments:
481
+ *
482
+ * All other functions accept three arguments:
483
+ *
484
+ * @example
485
+ *
486
+ * import { currencyFormat } from "neetocommons/utils";
487
+ *
488
+ * currencyFormat.withAmount(1000); // In `en` locale, returns "1,000.00"
489
+ * currencyFormat.withAmount(125, { maximumFractionDigits: 1 }); // In `en` locale, returns "125.0"
490
+ *
491
+ * currencyFormat.withSymbol(1000, "USD"); // In `en` locale, returns "$1,000.00"
492
+ * currencyFormat.withSymbol(125, "USD", { maximumFractionDigits: 1 }); // In `en` locale, returns "$125.0"
493
+ *
494
+ * currencyFormat.withCode(1000, "USD"); // In `en` locale, returns "1,000.00 USD"
495
+ * currencyFormat.withCode(125, "USD", { maximumFractionDigits: 1 }); // In `en` locale, returns "125.0 USD"
496
+ *
497
+ * currencyFormat.withSymbolAndCode(1000, "INR"); // In `en` locale, returns "₹1,000.00 INR"
498
+ * currencyFormat.withSymbolAndCode(125, "INR", {
499
+ * maximumFractionDigits: 1,
500
+ * }); // In `en` locale, returns "₹125.0 INR"
501
+ *
502
+ * // `fr`
503
+ * currencyFormat.withSymbolAndCode(1000, "EUR"); // In `fr` locale, returns "1 000 € EUR"
504
+ * currencyFormat.withSymbolAndCode(125, "INR", {
505
+ * maximumFractionDigits: 1,
506
+ * }); // In `fr` locale, returns "125,00 ₹ INR""
507
+ * @endexample
508
+ */
127
509
  export const currencyFormat: {
128
- withAmount: (
129
- amount: number | string,
130
- options?: Intl.NumberFormatOptions
131
- ) => string;
510
+ withAmount: (amount: number | string, options?: Intl.NumberFormatOptions) => string;
132
511
  withSymbol: CurrencyFormatterFunction;
133
512
  withCode: CurrencyFormatterFunction;
134
513
  withSymbolAndCode: CurrencyFormatterFunction;
135
514
  };
136
-
515
+ /**
516
+ *
517
+ * The showThumbsUpToastr function displays a toastr notification with a thumbs-up icon,
518
+ *
519
+ * indicating a successful operation.
520
+ *
521
+ * @example
522
+ *
523
+ * showThumbsUpToastr();
524
+ * @endexample
525
+ */
137
526
  export function showThumbsUpToastr(): void;
138
-
527
+ /**
528
+ *
529
+ * Ensure a given string is a valid slug, containing only lowercase letters,
530
+ *
531
+ * numbers, and hyphens.
532
+ *
533
+ * @example
534
+ *
535
+ * slugValidator("Slug").isValid("valid-slug"); // output true
536
+ * slugValidator("Slug").isValid("invalid slug"); // output false
537
+ *
538
+ * const schema = yup.object().shape({
539
+ * slug: slugValidator("Slug"),
540
+ * });
541
+ * @endexample
542
+ */
139
543
  export function slugValidator(label: string): StringSchema;
140
-
141
- export function captureAnalyticsEvent(
142
- name: string,
143
- properties?: { [key: string]: any }
144
- ): void;
145
-
146
- export function captureAnalyticsPageView(
147
- page: string,
148
- properties?: { [key: string]: string }
149
- ): void;
150
-
151
- export function buildNestedAttributesPayload(
152
- modifiedValues: { [key: string]: any },
153
- initialValues: { [key: string]: any },
154
- nestedKeyToModify: string,
155
- nestedAttributeKeyInPayload: string,
156
- nestedAttributesForArrayKey: string
157
- ): { [key: string]: any };
544
+ /**
545
+ *
546
+ * The captureAnalyticsEvent is a utility function which facilitates logging user
547
+ *
548
+ * events to Mixpanel.
549
+ *
550
+ * @example
551
+ *
552
+ * import { captureAnalyticsEvent } from "@bigbinary/neeto-commons-frontend/utils";
553
+ * // ...
554
+ *
555
+ * captureAnalyticsEvent("event_name", { subdomain: "spinkart" });
556
+ *
557
+ * // The second argument is optional, containing additional data to log as part of the event.
558
+ * @endexample
559
+ */
560
+ export function captureAnalyticsEvent(name: string, properties?: {
561
+ [key: string]: any;
562
+ }): void;
563
+ /**
564
+ *
565
+ * The captureAnalyticsPageView is a utility function which facilitates logging user page views to Mixpanel.
566
+ *
567
+ * @example
568
+ *
569
+ * import { captureAnalyticsPageView } from "@bigbinary/neeto-commons-frontend/utils";
570
+ * // ...
571
+ *
572
+ * captureAnalyticsPageView("page_name", { additional: "information" });
573
+ *
574
+ * // The second argument is optional, containing additional data to log as part of the page.
575
+ * @endexample
576
+ */
577
+ export function captureAnalyticsPageView(page: string, properties?: {
578
+ [key: string]: string;
579
+ }): void;
580
+ /**
581
+ *
582
+ * The buildNestedAttributesPayload function is a utility designed to
583
+ *
584
+ * create payloads for Rails' Active Record Nested Attributes. This function
585
+ *
586
+ * simplifies the process of handling nested forms by generating the correct
587
+ *
588
+ * payload structure, which includes the necessary attributes for creating and
589
+ *
590
+ * destroying nested records.
591
+ *
592
+ * @example
593
+ *
594
+ * import { buildNestedAttributesPayload } from "@bigbinary/neeto-commons-frontend/utils";
595
+ *
596
+ * // Example initial and modified values
597
+ * const initialValues = {
598
+ * emails: [
599
+ * { id: 1, email: "test1@example.com" },
600
+ * { id: 2, email: "test2@example.com" },
601
+ * ],
602
+ * };
603
+ *
604
+ * const modifiedValues = {
605
+ * emails: [{ value: "test2@example.com" }, { value: "test3@example.com" }],
606
+ * };
607
+ *
608
+ * const payload = buildNestedAttributesPayload({
609
+ * initialValues,
610
+ * modifiedValues,
611
+ * nestedKeyToModify: "emails",
612
+ * nestedAttributeKeyInPayload: "email",
613
+ * nestedAttributesForArrayKey: "whitelistedEmailsAttributes",
614
+ * });
615
+ *
616
+ * console.log(payload);
617
+ * // Output:
618
+ * // {
619
+ * // whitelistedEmailsAttributes: [
620
+ * // { email: "test3@example.com" },
621
+ * // { id: 1, email: "test1@example.com", _destroy: true }
622
+ * // ]
623
+ * // }
624
+ * @endexample
625
+ */
626
+ export function buildNestedAttributesPayload(modifiedValues: {
627
+ [key: string]: any;
628
+ }, initialValues: {
629
+ [key: string]: any;
630
+ }, nestedKeyToModify: string, nestedAttributeKeyInPayload: string, nestedAttributesForArrayKey: string): {
631
+ [key: string]: any;
632
+ };