import { Mixin, Subscription } from "@rails/actioncable"; import Dayjs from "dayjs"; import { utc as utcPlugin } from 'dayjs/plugin/utc'; import { tz as tzPlugin } from 'dayjs/plugin/timezone'; import { duration as durationPlugin } from 'dayjs/plugin/duration'; import { isDayjs as isDayjsPlugin } from 'dayjs'; import { updateLocale as updateLocalePlugin } from 'dayjs/plugin/updateLocale'; import React from "react"; import { StringSchema } from "yup"; export function resetAuthTokens(): void; /** * * The withEventTargetValue function is a curried function that accepts a * * function as its first parameter and an event object as its second parameter. It * * executes the given function with the event.target.value as an argument, making * * it easier to extract and work with the value of form inputs or other elements * * that trigger events. * * @example * * const onChange = val => console.log(`Value = ${val}`); * * ; * * // For example, in this case when user types "1" in the input field, "Value = 1" will be printed in the console. * @endexample */ export function withEventTargetValue(func: (value: string) => void, event: React.ChangeEvent): void; /** * * The withEventTargetValue function is a curried function that accepts a * * function as its first parameter and an event object as its second parameter. It * * executes the given function with the event.target.value as an argument, making * * it easier to extract and work with the value of form inputs or other elements * * that trigger events. * * @example * * const onChange = val => console.log(`Value = ${val}`); * * ; * * // For example, in this case when user types "1" in the input field, "Value = 1" will be printed in the console. * @endexample */ export function withEventTargetValue(func: (value: string) => void): React.ChangeEventHandler; /** * * The getSubdomain function retrieves the subdomain of the current URL and * * returns it as a string. A subdomain is a prefix that appears before the main * * domain name in a URL. * * @example * * // Let the current url be "https://spinkart.example.com". * getSubdomain(); * * // output: spinkart * @endexample */ export function getSubdomain(): string; /** * * The simulateApiCall function simulates an API call and returns a response * * object with a specified delay. This function is useful during frontend * * development when you need to mock API calls before the backend is fully * * implemented. * * @example * * simulateApiCall(hardCodedResponseData, hardCodedErrorResponse); * @endexample */ export function simulateApiCall(result: T, error?: any, errorProbability?: number, delayMs?: number): Promise; /** * * The copyToClipboard function copies the given string to the clipboard and * * displays a success message, typically a toaster notification, to indicate that * * the operation was successful. * * @example * * copyToClipboard("https://spinkart.example.com", { * showToastr: true, * message: "URL copied successfully!", * }); * * // If the URL is copied to the clipboard, a toaster message will be shown with the message "URL copied successfully!" * @endexample */ export function copyToClipboard(text: string, configs?: { showToastr?: boolean; message?: string; }): void; type buildUrlOptions = { toSnakeCase?: boolean; }; /** * * The buildUrl function builds a URL by inflating a route-like template string * * (e.g., /products/:productId/variants/:id) using the provided parameters. It * * allows you to create URLs dynamically based on a template and replace * * placeholders with actual values. Any additional properties in the parameters * * will be transformed to snake case and attached as query parameters to the URL. * * @example * * buildUrl("/products/:id", { id: "123" }); // output "/products/123" * buildUrl("/products", { search: "abc" }); // output "/products?search=abc" * buildUrl("/products/:productId/variants/:variantId/attributes", { * productId: "123", * variantId: "456", * search: "abc", * page: 1, * per_page: 10, * }); // output "/products/123/variants/456/attributes?page=1&per_page=10&search=abc" * buildUrl("/products", { searchTerm: "abc" }); // output "/products?search_term=abc" * buildUrl("/products", { searchTerm: "abc" }, { toSnakeCase: false }); // output "/products?searchTerm=abc" * @endexample */ export function buildUrl(route: string, params: object, options?: buildUrlOptions): string; type DateTimeType = string | number | Dayjs.Dayjs | Date | null | undefined; export const timeFormat: { fromNow: (time: DateTimeType) => string; time: (time: DateTimeType) => string; timeWithSeconds: (time: DateTimeType) => string; date: (time: DateTimeType) => string; dateWeek: (time: DateTimeType) => string; dateWeekDayExtended: (time: DateTimeType) => string; dateWeekWithoutYear: (time: DateTimeType) => string; dateWeekWithoutYearDayExtended: (time: DateTimeType) => string; dateTime: (time: DateTimeType) => string; dateTimeWithSeconds: (time: DateTimeType) => string; dateWeekTime: (time: DateTimeType) => string; dateWeekTimeDayExtended: (time: DateTimeType) => string; extended: (time: DateTimeType) => string; default: (time: DateTimeType) => string; defaultWithTime: (time: DateTimeType) => string; }; /** * * The dateFormat and timeFormat functions are aliases of each other, and they * * are used for formatting dates and times in various ways. These functions provide * * a convenient way to format date and time values according to specific patterns * * and display them in a human-readable format. * * @example * * const sourceDate = "2020-01-01T00:00:00.000Z"; // can be anything that dayjs can parse * * dateFormat.fromNow(date); // "3 years ago" * timeFormat.fromNow(date); // "3 years ago" * * dateFormat.time(date); // "12:00 AM" * timeFormat.time(date); // "12:00 AM" * * dateFormat.timeWithSeconds(date); // "12:00:00 AM" * timeFormat.timeWithSeconds(date); // "12:00:00 AM" * * dateFormat.date(date); // "Jan 1, 2020" * timeFormat.date(date); // "Jan 1, 2020" * * dateFormat.dateWeek(date); // "Jan 1, 2020 Wed" * timeFormat.dateWeek(date); // "Jan 1, 2020 Wed" * * dateFormat.dateWeekDayExtended(date); // "Jan 1, 2020 Wednesday" * timeFormat.dateWeekDayExtended(date); // "Jan 1, 2020 Wednesday" * * dateFormat.dateWeekWithoutYear(date); // "Jan 1, Wed" * timeFormat.dateWeekWithoutYear(date); // "Jan 1, Wed" * * dateFormat.dateWeekWithoutYearDayExtended(date); // "Jan 1, Wednesday" * timeFormat.dateWeekWithoutYearDayExtended(date); // "Jan 1, Wednesday" * * dateFormat.dateTime(date); // "Jan 1, 2020 12:00 AM" * timeFormat.dateTime(date); // "Jan 1, 2020 12:00 AM" * * dateFormat.dateTimeWithSeconds(date); // "Jan 1, 2020 12:00:00 AM" * timeFormat.dateTimeWithSeconds(date); // "Jan 1, 2020 12:00:00 AM" * * dateFormat.dateWeekTime(date); // "Jan 1, 2020 Wed 12:00 AM" * timeFormat.dateWeekTime(date); // "Jan 1, 2020 Wed 12:00 AM" * * dateFormat.dateWeekTimeDayExtended(date); // "Jan 1, 2020 Wednesday 12:00 AM" * timeFormat.dateWeekTimeDayExtended(date); // "Jan 1, 2020 Wednesday 12:00 AM" * * dateFormat.extended(date); // "Wednesday January 1, 2020 12:00 AM (3 years ago)" * timeFormat.extended(date); // "Wednesday January 1, 2020 12:00 AM (3 years ago)" * * dateFormat.default(date); // This will return date in user date format in globalProps * timeFormat.default(date); // This will return date in user date format in globalProps * * dateFormat.defaultWithTime(date); // This will return date time in user date format in globalProps * timeFormat.defaultWithTime(date); // This will return date time in user date format in globalProps * @endexample * All neeto-applications should be using any one of these styles (according to the * * space available) to display date and time unless if the case is too specific to * * the project. * */ export const dateFormat: typeof timeFormat; export interface DayjsStatic { (arg?: string | number | Date | Dayjs): Dayjs; utc: typeof utcPlugin; tz: typeof tzPlugin; duration: typeof durationPlugin; isDayjs: typeof isDayjsPlugin; updateLocale: typeof updateLocalePlugin; locale: (preset?: string | { name: string; [key: string]: any; }) => string; } /** * * The dayjs wrapper provides an extended version of the dayjs library with additional support for various features such as custom date parsing, localized formatting, and time zone management. * * The wrapper automatically sets the default time zone based on the globalProps.user.timeZone if it is defined. Ensure that globalProps and the user.timeZone are correctly initialized in your application. * * @example * * // import dayjs from "@bigninary/neeto-commons-frontend/utils"; * import { dayjs } from "@bigninary/neeto-commons-frontend/utils"; * * * // Get the current date and time * dayjs().format("dddd, MMMM D, YYYY h:mm A"); // "Wednesday, January 1, 2020 12:00 AM" (current date and time based on the user's time zone) * @endexample */ export const dayjs: DayjsStatic; /** * * The toLocale function converts a given number to a locale-specific string * * representation, formatting it with commas as thousands separators and respecting * * the appropriate decimal separator for the locale. It automatically detects the * * appropriate locale using globalProps and falls back to the user's browser * * locale if necessary. * * @example * * toLocale(1000000); // "1,000,000" when locale is "en-US" * toLocale(1000000); // "10,00,000" when locale is "en-IN" * toLocale(1000000.987, { maximumFractionDigits: 2 }); // "1,000,000.99" * toLocale(1000000.987, { * currencyDisplay: "narrowSymbol", * style: "currency", * currency: "INR", * }); // "₹1,000,000.99" * @endexample */ export function toLocale(number: string | number, options?: Intl.NumberFormatOptions): string; export type qsOptionsType = { comma?: boolean | undefined; delimiter?: string | RegExp | undefined; depth?: number | false | undefined; decoder?: ((str: string, defaultDecoder: any, charset: string, type: "key" | "value") => any) | undefined; arrayLimit?: number | undefined; parseArrays?: boolean | undefined; allowDots?: boolean | undefined; plainObjects?: boolean | undefined; allowPrototypes?: boolean | undefined; parameterLimit?: number | undefined; strictNullHandling?: boolean | undefined; ignoreQueryPrefix?: boolean | undefined; charset?: "utf-8" | "iso-8859-1" | undefined; charsetSentinel?: boolean | undefined; interpretNumericEntities?: boolean | undefined; toCamelCase?: boolean | undefined; }; export type QueryParamsType = { [key: string]: any; }; /** * * The getQueryParams function retrieves all the query parameters from the * * current URL and returns them as an object. Query parameters are typically found * * in the URL following a "?" character and are used to pass data to a web page or * * API. * * This function will return an object containing all the query parameters in camel * * case. It will return an empty object if no query parameters are present. * * You can set toCamelCase to false if you don't want to apply any transformation to the keys. * * to false. * * More details on working: * * https://www.loom.com/share/4f369cff56e845428d5ef7451759469c * * @example * * // Let the current url be "https://example.com?search=something&sort_by=date&order_by=desc". * getQueryParams(); * // output: { search: "something", sort_by: "date", order_by: "desc" } * * const { search, sortBy, orderBy } = getQueryParams(); * * const { search, sort_by, order_by } = getQueryParams({ toCamelCase: false }); * @endexample */ export function getQueryParams(options?: qsOptionsType): QueryParamsType; /** * * The joinHyphenCase function joins an array of strings using hyphens as the * * delimiter and returns the resulting string. * * Any number of string arguments. * * @example * * joinHyphenCase("hello", "world"); // output: "hello-world" * @endexample */ export function joinHyphenCase(...args: string[]): string; /** * * The hyphenize function converts strings that contain underscores, spaces, and * * camelCase strings into hyphenized strings * * @example * * hyphenize("hello_world", ""); // output: "hello-world" * @endexample */ export function hyphenize(value: string, fallbackString?: string): string; /** * * The debounce function is used to create a debounced function that delays the * * execution of a given function until a specified wait time, in milliseconds, has * * elapsed since the last time it was invoked. * * @example * * const searchForProducts = debounce(async key => { * // this function will be triggered once after user stops typing for 300ms * const products = await productsApi.fetch(key); * // do something with the products * }, 300); * searchForProducts(e.target.value)} />; * @endexample */ export function debounce(func: F, delay?: number): F; /** * * The hasPermission function checks whether the current user has a specific * * permission. It returns true if the user has the specified permission and * * false if they do not. Permissions are typically used to control access to * * various features or actions within an application. The permissions corresponding * * to a particular user is taken from the globalProps. * * @example * * hasPermission("user.view_settings"); * @endexample */ export function hasPermission(permission: string): boolean; /** * * The hasAnyPermission function checks whether the current user has any of the * * specified permissions. It returns true if the user has at least one of the * * permissions and false if the user has none of them. The permissions * * corresponding to a particular user is taken from the globalProps. * * permissions: Any number of permission strings. * * @example * * hasAnyPermission("user.view_settings", "user.edit_settings"); * @endexample */ export function hasAnyPermission(...permissions: string[]): boolean; /** * * The hasAllPermissions function checks whether the current user has all of the * * specified permissions. It returns true if the user has all the permissions and * * false otherwise. The permissions corresponding to a particular user is taken * * from the globalProps. * * permissions: Any number of permission strings. * * @example * * hasAllPermissions("user.view_settings", "user.edit_settings"); * @endexample */ export function hasAllPermissions(...permissions: string[]): boolean; type ChannelNameWithParams = { channel: string; [key: string]: any; }; /** * * The createSubscription function is used to create a subscription in a web * * application where a consumer subscribes to a Rails * * Action Cable * * channel. This function facilitates the creation of subscriptions on the client * * side to listen for updates and events broadcasted on a specific channel. * * @example * * const subscription = createSubscription( * { * channel: "testChannel", * deployment_id: "deploymentId", * }, * { received: value => handleValue(value) } * ); * @endexample */ export function createSubscription(channelName: string | ChannelNameWithParams, callbacks: Mixin): Subscription; /** * * The getFromLocalStorage function retrieves a JSON-parsed value from the * * browser's localStorage for the specified key. If the stored value is not valid * * JSON or if the key does not exist in localStorage, the function returns * * null. * * @example * * localStorage.setItem("key", JSON.stringify({ a: 1 })); * getFromLocalStorage("key"); //returns { a: 1 } * @endexample */ export function getFromLocalStorage(key: string): T | null; /** * * The setToLocalStorage function takes a key and a value as its parameters * * and save the stringified representation of the value under the specified key * * within local storage. * * @example * * setToLocalStorage("token", "1234-5678-9101-1213"); * @endexample */ export function setToLocalStorage(key: string, value: any): void; /** * * The removeFromLocalStorage function takes a key as its parameter, and will * * remove that key from the given Storage object if it exists. * * @example * * removeFromLocalStorage("token"); * @endexample */ export function removeFromLocalStorage(key: string): void; type CurrencyFormatterFunction = (amount: number | string, currency: string, options?: Intl.NumberFormatOptions) => string; /** * * currencyFormat is a utility which provides functions which formats a given * * number in currency formats based on the current user locale. Current user locale * * is based on dayjs.locale(). * * withAmount accepts two arguments: * * All other functions accept three arguments: * * @example * * import { currencyFormat } from "neetocommons/utils"; * * currencyFormat.withAmount(1000); // In `en` locale, returns "1,000.00" * currencyFormat.withAmount(125, { maximumFractionDigits: 1 }); // In `en` locale, returns "125.0" * * currencyFormat.withSymbol(1000, "USD"); // In `en` locale, returns "$1,000.00" * currencyFormat.withSymbol(125, "USD", { maximumFractionDigits: 1 }); // In `en` locale, returns "$125.0" * * currencyFormat.withCode(1000, "USD"); // In `en` locale, returns "1,000.00 USD" * currencyFormat.withCode(125, "USD", { maximumFractionDigits: 1 }); // In `en` locale, returns "125.0 USD" * * currencyFormat.withSymbolAndCode(1000, "INR"); // In `en` locale, returns "₹1,000.00 INR" * currencyFormat.withSymbolAndCode(125, "INR", { * maximumFractionDigits: 1, * }); // In `en` locale, returns "₹125.0 INR" * * // `fr` * currencyFormat.withSymbolAndCode(1000, "EUR"); // In `fr` locale, returns "1 000 € EUR" * currencyFormat.withSymbolAndCode(125, "INR", { * maximumFractionDigits: 1, * }); // In `fr` locale, returns "125,00 ₹ INR"" * @endexample */ export const currencyFormat: { withAmount: (amount: number | string, options?: Intl.NumberFormatOptions) => string; withSymbol: CurrencyFormatterFunction; withCode: CurrencyFormatterFunction; withSymbolAndCode: CurrencyFormatterFunction; }; /** * * The showThumbsUpToastr function displays a toastr notification with a thumbs-up icon, * * indicating a successful operation. * * @example * * showThumbsUpToastr(); * @endexample */ export function showThumbsUpToastr(): void; /** * * Ensure a given string is a valid slug, containing only lowercase letters, * * numbers, and hyphens. * * @example * * slugValidator("Slug").isValid("valid-slug"); // output true * slugValidator("Slug").isValid("invalid slug"); // output false * * const schema = yup.object().shape({ * slug: slugValidator("Slug"), * }); * @endexample */ export function slugValidator(label: string): StringSchema; /** * * The captureAnalyticsEvent is a utility function which facilitates logging user * * events to Mixpanel. * * @example * * import { captureAnalyticsEvent } from "@bigbinary/neeto-commons-frontend/utils"; * // ... * * captureAnalyticsEvent("event_name", { subdomain: "spinkart" }); * * // The second argument is optional, containing additional data to log as part of the event. * @endexample */ export function captureAnalyticsEvent(name: string, properties?: { [key: string]: any; }): void; /** * * The captureAnalyticsPageView is a utility function which facilitates logging user page views to Mixpanel. * * @example * * import { captureAnalyticsPageView } from "@bigbinary/neeto-commons-frontend/utils"; * // ... * * captureAnalyticsPageView("page_name", { additional: "information" }); * * // The second argument is optional, containing additional data to log as part of the page. * @endexample */ export function captureAnalyticsPageView(page: string, properties?: { [key: string]: string; }): void; /** * * The buildNestedAttributesPayload function is a utility designed to * * create payloads for Rails' Active Record Nested Attributes. This function * * simplifies the process of handling nested forms by generating the correct * * payload structure, which includes the necessary attributes for creating and * * destroying nested records. * * @example * * import { buildNestedAttributesPayload } from "@bigbinary/neeto-commons-frontend/utils"; * * // Example initial and modified values * const initialValues = { * emails: [ * { id: 1, email: "test1@example.com" }, * { id: 2, email: "test2@example.com" }, * ], * }; * * const modifiedValues = { * emails: [{ value: "test2@example.com" }, { value: "test3@example.com" }], * }; * * const payload = buildNestedAttributesPayload({ * initialValues, * modifiedValues, * nestedKeyToModify: "emails", * nestedAttributeKeyInPayload: "email", * nestedAttributesForArrayKey: "whitelistedEmailsAttributes", * }); * * console.log(payload); * // Output: * // { * // whitelistedEmailsAttributes: [ * // { email: "test3@example.com" }, * // { id: 1, email: "test1@example.com", _destroy: true } * // ] * // } * @endexample */ export function buildNestedAttributesPayload(modifiedValues: { [key: string]: any; }, initialValues: { [key: string]: any; }, nestedKeyToModify: string, nestedAttributeKeyInPayload: string, nestedAttributesForArrayKey: string): { [key: string]: any; }; /** * * The loadGoogleFonts is a utility function which facilitates loading multiple Google Fonts dynamically by injecting link elements into the document head. * * @example * * import { useEffect } from "react"; * * import { loadGoogleFonts } from "@bigbinary/neeto-commons-frontend/utils"; * * useEffect(() => { * const fontFamilies = ['Roboto', 'Open Sans', 'Lato']; * loadGoogleFonts(fontFamilies); * }, []); * @endexample */ export function loadGoogleFonts(fontFamilies: string[]): void;