saleor-dashboard/src/misc.ts

463 lines
12 KiB
TypeScript
Raw Normal View History

2019-08-09 11:14:35 +00:00
import moment from "moment-timezone";
2019-08-12 11:47:38 +00:00
import { MutationFunction, MutationResult } from "react-apollo";
2019-10-17 11:47:11 +00:00
import { defineMessages, IntlShape } from "react-intl";
2019-08-09 10:26:22 +00:00
import urlJoin from "url-join";
2019-06-19 14:40:52 +00:00
Use MacawUI (#1229) * Replace withStyleswith useStyles (#1100) * Replace withStyleswith useStyles * Update messages * Use rem as a spacing unit (#1101) * Use rems as spacing units * Fix visual bugs * Update stories * Use macaw-ui as theme provider (#1108) * Use macaw ui as a theme provider * Add react-dom to aliases * Fix jest module resolution * Update useTheme hook usage * Fix test wrapper * Use macaw from git repo * Fix CI * Update stories * Fix aliasing * Extract savebar to macaw ui (#1146) * wip * Use savebar from macaw * Use confirm button from macaw * Improve file structure * Use sidebar context from macaw * Update macaw * Update macaw version * Remove savebar from storybook * Update stories * Use alerts and notifications from macaw (#1166) * Use alerts from macaw * Add notifications from macaw * Update stories * Pin macaw version * Encapsulate limit reached in one component * Remove unused imports * Use backlinks from macaw (#1183) * Use backlink from macaw * Update macaw version * Use macaw sidebar (#1148) * Use sidebar from macaw * Use shipped logo * Use lowercase * Update stories * Use user chip from macaw (#1191) * Use user chip from macaw * Use dedicated components for menu items * Simplify code * Bump version and fix types (#1210) * Rename onBack to onClick * Rename UserChip to UserChipMenu * Rename IMenuItem to SidebarMenuItem * Update macaw version * Fix tables after changes in macaw (#1220) * Update macaw version * Update changelog * Update stories * Fix after rebase * Update to macaw 0.2.0 * Lint files * Update macaw to 0.2.2
2021-07-21 08:59:52 +00:00
import { ConfirmButtonTransitionState } from "./components/ConfirmButton";
import { StatusType } from "./components/StatusChip/types";
import { StatusLabelProps } from "./components/StatusLabel";
2019-06-19 14:40:52 +00:00
import { APP_MOUNT_URI } from "./config";
2019-10-25 12:18:52 +00:00
import { AddressType, AddressTypeInput } from "./customers/types";
2019-12-06 17:14:19 +00:00
import {
MutationResultAdditionalProps,
2019-12-06 17:14:19 +00:00
PartialMutationProviderOutput,
UserError
2019-12-06 17:14:19 +00:00
} from "./types";
2019-06-19 14:40:52 +00:00
import {
2019-10-25 12:18:52 +00:00
AddressInput,
CountryCode,
DateRangeInput,
2019-06-19 14:40:52 +00:00
OrderStatus,
2019-10-17 11:47:11 +00:00
PaymentChargeStatusEnum
2019-06-19 14:40:52 +00:00
} from "./types/globalTypes";
export type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<
T,
Exclude<keyof T, Keys>
> &
{ [K in Keys]-?: Required<Pick<T, K>> }[Keys];
export type RequireOnlyOne<T, Keys extends keyof T = keyof T> = Pick<
T,
Exclude<keyof T, Keys>
> &
{
[K in Keys]-?: Required<Pick<T, K>> &
2019-08-29 10:55:56 +00:00
Partial<Record<Exclude<Keys, K>, undefined>>;
2019-06-19 14:40:52 +00:00
}[Keys];
export function renderCollection<T>(
collection: T[],
renderItem: (
item: T | undefined,
index: number | undefined,
collection: T[]
) => any,
renderEmpty?: (collection: T[]) => any
) {
if (collection === undefined) {
return renderItem(undefined, undefined, collection);
}
if (collection.length === 0) {
return !!renderEmpty ? renderEmpty(collection) : null;
}
return collection.map(renderItem);
}
export function decimal(value: string | number) {
if (typeof value === "string") {
return value === "" ? null : value;
}
return value;
}
2020-07-13 16:51:05 +00:00
export function weight(value: string) {
return value === "" ? null : parseFloat(value);
}
2019-06-19 14:40:52 +00:00
export const removeDoubleSlashes = (url: string) =>
url.replace(/([^:]\/)\/+/g, "$1");
2019-08-29 10:55:56 +00:00
const paymentStatusMessages = defineMessages({
paid: {
defaultMessage: "Fully paid",
description: "payment status"
},
partiallyPaid: {
defaultMessage: "Partially paid",
description: "payment status"
},
partiallyRefunded: {
defaultMessage: "Partially refunded",
description: "payment status"
},
refunded: {
defaultMessage: "Fully refunded",
description: "payment status"
},
unpaid: {
defaultMessage: "Unpaid",
description: "payment status"
}
});
export const transformPaymentStatus = (
status: string,
intl: IntlShape
): { localized: string; status: StatusLabelProps["status"] } => {
2019-06-19 14:40:52 +00:00
switch (status) {
case PaymentChargeStatusEnum.PARTIALLY_CHARGED:
2019-08-29 10:55:56 +00:00
return {
localized: intl.formatMessage(paymentStatusMessages.partiallyPaid),
status: "error"
};
2019-06-19 14:40:52 +00:00
case PaymentChargeStatusEnum.FULLY_CHARGED:
2019-08-29 10:55:56 +00:00
return {
localized: intl.formatMessage(paymentStatusMessages.paid),
status: "success"
};
2019-06-19 14:40:52 +00:00
case PaymentChargeStatusEnum.PARTIALLY_REFUNDED:
2019-08-29 10:55:56 +00:00
return {
localized: intl.formatMessage(paymentStatusMessages.partiallyRefunded),
status: "error"
};
2019-06-19 14:40:52 +00:00
case PaymentChargeStatusEnum.FULLY_REFUNDED:
2019-08-29 10:55:56 +00:00
return {
localized: intl.formatMessage(paymentStatusMessages.refunded),
status: "success"
};
2019-06-19 14:40:52 +00:00
default:
2019-08-29 10:55:56 +00:00
return {
localized: intl.formatMessage(paymentStatusMessages.unpaid),
status: "error"
};
2019-06-19 14:40:52 +00:00
}
};
2019-12-20 10:44:41 +00:00
export const orderStatusMessages = defineMessages({
2019-08-29 10:55:56 +00:00
cancelled: {
defaultMessage: "Cancelled",
description: "order status"
},
draft: {
defaultMessage: "Draft",
description: "order status"
},
fulfilled: {
defaultMessage: "Fulfilled",
description: "order status"
},
partiallyFulfilled: {
defaultMessage: "Partially fulfilled",
description: "order status"
},
Feature/order reissue (#910) * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Add change to changelog * Remove console.log * Update tests * Extract messages * Add utils functions for selecting only ulfulfilled order lines * Add optional value selection for line item * Update tests * Add optional rendering of unfulfilled items card and refactor a bit * Update displaying of items card title when refunded card * UUpdate utils, form data etc. not to include refunded items when calculating replaced items amount * Uppdate return items card not to display replace buttons for refunded items * Refactor and small fixes after review * Update extracted messages * Fix card title when no fullfilemtn id * wip * Initially stitch returns page. Update types, add mutation * remove unnecessary component display names * Add loading status from form submission & refactor * Add errors from response * Add errors from response and refactor * Remove comments * Add optional error adding when no data from return create request * Update messages * wip * Update snapshots * Remove unnecessary console.log * Add better typing for getParsedLineData function * Update & refactor card title to match cards both in return and order details * Add handling of new statuses to order details cards. Also refactor, and devide order fulfillment card into couple of smaller components * Update messages * Update schema to match api * Update types * Update status label component to match colors with new designs and order details cards * RUpdate and refactor order fulfillment card components to be reusable. Also add replaced status handling * Updayte card title component to handle all cases and statuses * Update oorder unfulfilled items card and order details page, reduce some of the boilerplate * Fix card title types and adjust returns card to match * Update messages * Update snapshots * RUpdate order fulfillment card with subtitles and buttons for returned status * Add onRefund to order fulfillment card * Fix typo and wrong message in card title * Add missing condition in return form submission utils to decice if to refund products * Update fulfillment subtitles row and tests * Update messages * Change naming and locations of OrderFulfillment and items card components * Update messages * U[pdate names of components again to even better ones * Update messages * changelog * Update schema and types so that order history event also includes user first and last name * Add extended timeline event and event header components. Move some of the logic to utils and add way to display links in the event header. * FFix types * Update messages * Change naming of isOfType -> isTimelineEventOfType and refactor extended timeline event messages selection to be less complicated * Add ids and update messages * Add ids and update messages some more * Update storybook decorator to work with react router context in components and tests * Refactor after review * Update messages * Add rredirecting to draft order * Add handling draft creation from replacement * Add related order to order event fragment and update lots and lots of types * Update extended timeline event to match related order type on order history event * Update fixtures * Refactor ExtendedTimelineEvent Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com> * Fix typing * Update messages * Fix missing history event for replacement draft created for replaced products * Update messages * Handle new statuses for returned and partially returned orders * Update messages * update snapshots * BBump empty line to rebuild ci * Change status to proper color * Change replaceable items in return for replace to be auto off instead of on * Add utils functions and make order details menu not show option to return items when there are returnable items in the order * Fix replace checkbox showing when previously hidden and clicked set maximal quantities * Fix return form invalid money values * Add default values to avoid returning of NaN in utils for return amount and refactor * Add ggeneral error alerts * Add eproduct error box component and style. style a lot. * Fixes * Fix lint * Add cannot refund error title + description * Extract messages * Refactor after review * Add better, nicer and fancier imports to product error cell * Use error color from palette in product error cell * Fix max refund when 0 for return * Add ddisable ability to refund products button so it's disabled when 0 products selected * Add class for order return form data parsing and add condition to not do refund when total captured on order is 0 * Update snapshots * Add condition for order lines quantity in order products table row * Fix return amount submit button * Add change to changelog Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com>
2021-01-20 16:16:43 +00:00
partiallyReturned: {
defaultMessage: "Partially returned",
description: "order status"
},
2020-03-04 16:15:55 +00:00
readyToCapture: {
defaultMessage: "Ready to capture",
description: "order status"
},
readyToFulfill: {
defaultMessage: "Ready to fulfill",
description: "order status"
},
Feature/order reissue (#910) * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Add change to changelog * Remove console.log * Update tests * Extract messages * Add utils functions for selecting only ulfulfilled order lines * Add optional value selection for line item * Update tests * Add optional rendering of unfulfilled items card and refactor a bit * Update displaying of items card title when refunded card * UUpdate utils, form data etc. not to include refunded items when calculating replaced items amount * Uppdate return items card not to display replace buttons for refunded items * Refactor and small fixes after review * Update extracted messages * Fix card title when no fullfilemtn id * wip * Initially stitch returns page. Update types, add mutation * remove unnecessary component display names * Add loading status from form submission & refactor * Add errors from response * Add errors from response and refactor * Remove comments * Add optional error adding when no data from return create request * Update messages * wip * Update snapshots * Remove unnecessary console.log * Add better typing for getParsedLineData function * Update & refactor card title to match cards both in return and order details * Add handling of new statuses to order details cards. Also refactor, and devide order fulfillment card into couple of smaller components * Update messages * Update schema to match api * Update types * Update status label component to match colors with new designs and order details cards * RUpdate and refactor order fulfillment card components to be reusable. Also add replaced status handling * Updayte card title component to handle all cases and statuses * Update oorder unfulfilled items card and order details page, reduce some of the boilerplate * Fix card title types and adjust returns card to match * Update messages * Update snapshots * RUpdate order fulfillment card with subtitles and buttons for returned status * Add onRefund to order fulfillment card * Fix typo and wrong message in card title * Add missing condition in return form submission utils to decice if to refund products * Update fulfillment subtitles row and tests * Update messages * Change naming and locations of OrderFulfillment and items card components * Update messages * U[pdate names of components again to even better ones * Update messages * changelog * Update schema and types so that order history event also includes user first and last name * Add extended timeline event and event header components. Move some of the logic to utils and add way to display links in the event header. * FFix types * Update messages * Change naming of isOfType -> isTimelineEventOfType and refactor extended timeline event messages selection to be less complicated * Add ids and update messages * Add ids and update messages some more * Update storybook decorator to work with react router context in components and tests * Refactor after review * Update messages * Add rredirecting to draft order * Add handling draft creation from replacement * Add related order to order event fragment and update lots and lots of types * Update extended timeline event to match related order type on order history event * Update fixtures * Refactor ExtendedTimelineEvent Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com> * Fix typing * Update messages * Fix missing history event for replacement draft created for replaced products * Update messages * Handle new statuses for returned and partially returned orders * Update messages * update snapshots * BBump empty line to rebuild ci * Change status to proper color * Change replaceable items in return for replace to be auto off instead of on * Add utils functions and make order details menu not show option to return items when there are returnable items in the order * Fix replace checkbox showing when previously hidden and clicked set maximal quantities * Fix return form invalid money values * Add default values to avoid returning of NaN in utils for return amount and refactor * Add ggeneral error alerts * Add eproduct error box component and style. style a lot. * Fixes * Fix lint * Add cannot refund error title + description * Extract messages * Refactor after review * Add better, nicer and fancier imports to product error cell * Use error color from palette in product error cell * Fix max refund when 0 for return * Add ddisable ability to refund products button so it's disabled when 0 products selected * Add class for order return form data parsing and add condition to not do refund when total captured on order is 0 * Update snapshots * Add condition for order lines quantity in order products table row * Fix return amount submit button * Add change to changelog Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com>
2021-01-20 16:16:43 +00:00
returned: {
defaultMessage: "Returned",
description: "order status"
},
unconfirmed: {
defaultMessage: "Unconfirmed",
description: "order status"
},
2019-08-29 10:55:56 +00:00
unfulfilled: {
defaultMessage: "Unfulfilled",
description: "order status"
}
});
export const transformOrderStatus = (
status: string,
intl: IntlShape
): { localized: string; status: StatusType } => {
2019-06-19 14:40:52 +00:00
switch (status) {
case OrderStatus.FULFILLED:
2019-08-29 10:55:56 +00:00
return {
localized: intl.formatMessage(orderStatusMessages.fulfilled),
status: StatusType.SUCCESS
2019-08-29 10:55:56 +00:00
};
2019-06-19 14:40:52 +00:00
case OrderStatus.PARTIALLY_FULFILLED:
2019-08-29 10:55:56 +00:00
return {
localized: intl.formatMessage(orderStatusMessages.partiallyFulfilled),
status: StatusType.NEUTRAL
2019-08-29 10:55:56 +00:00
};
2019-06-19 14:40:52 +00:00
case OrderStatus.UNFULFILLED:
2019-08-29 10:55:56 +00:00
return {
localized: intl.formatMessage(orderStatusMessages.unfulfilled),
status: StatusType.ERROR
2019-08-29 10:55:56 +00:00
};
2019-06-19 14:40:52 +00:00
case OrderStatus.CANCELED:
2019-08-29 10:55:56 +00:00
return {
localized: intl.formatMessage(orderStatusMessages.cancelled),
status: StatusType.ERROR
2019-08-29 10:55:56 +00:00
};
2019-06-19 14:40:52 +00:00
case OrderStatus.DRAFT:
2019-08-29 10:55:56 +00:00
return {
localized: intl.formatMessage(orderStatusMessages.draft),
status: StatusType.ERROR
};
case OrderStatus.UNCONFIRMED:
return {
localized: intl.formatMessage(orderStatusMessages.unconfirmed),
status: StatusType.NEUTRAL
2019-08-29 10:55:56 +00:00
};
Feature/order reissue (#910) * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Add change to changelog * Remove console.log * Update tests * Extract messages * Add utils functions for selecting only ulfulfilled order lines * Add optional value selection for line item * Update tests * Add optional rendering of unfulfilled items card and refactor a bit * Update displaying of items card title when refunded card * UUpdate utils, form data etc. not to include refunded items when calculating replaced items amount * Uppdate return items card not to display replace buttons for refunded items * Refactor and small fixes after review * Update extracted messages * Fix card title when no fullfilemtn id * wip * Initially stitch returns page. Update types, add mutation * remove unnecessary component display names * Add loading status from form submission & refactor * Add errors from response * Add errors from response and refactor * Remove comments * Add optional error adding when no data from return create request * Update messages * wip * Update snapshots * Remove unnecessary console.log * Add better typing for getParsedLineData function * Update & refactor card title to match cards both in return and order details * Add handling of new statuses to order details cards. Also refactor, and devide order fulfillment card into couple of smaller components * Update messages * Update schema to match api * Update types * Update status label component to match colors with new designs and order details cards * RUpdate and refactor order fulfillment card components to be reusable. Also add replaced status handling * Updayte card title component to handle all cases and statuses * Update oorder unfulfilled items card and order details page, reduce some of the boilerplate * Fix card title types and adjust returns card to match * Update messages * Update snapshots * RUpdate order fulfillment card with subtitles and buttons for returned status * Add onRefund to order fulfillment card * Fix typo and wrong message in card title * Add missing condition in return form submission utils to decice if to refund products * Update fulfillment subtitles row and tests * Update messages * Change naming and locations of OrderFulfillment and items card components * Update messages * U[pdate names of components again to even better ones * Update messages * changelog * Update schema and types so that order history event also includes user first and last name * Add extended timeline event and event header components. Move some of the logic to utils and add way to display links in the event header. * FFix types * Update messages * Change naming of isOfType -> isTimelineEventOfType and refactor extended timeline event messages selection to be less complicated * Add ids and update messages * Add ids and update messages some more * Update storybook decorator to work with react router context in components and tests * Refactor after review * Update messages * Add rredirecting to draft order * Add handling draft creation from replacement * Add related order to order event fragment and update lots and lots of types * Update extended timeline event to match related order type on order history event * Update fixtures * Refactor ExtendedTimelineEvent Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com> * Fix typing * Update messages * Fix missing history event for replacement draft created for replaced products * Update messages * Handle new statuses for returned and partially returned orders * Update messages * update snapshots * BBump empty line to rebuild ci * Change status to proper color * Change replaceable items in return for replace to be auto off instead of on * Add utils functions and make order details menu not show option to return items when there are returnable items in the order * Fix replace checkbox showing when previously hidden and clicked set maximal quantities * Fix return form invalid money values * Add default values to avoid returning of NaN in utils for return amount and refactor * Add ggeneral error alerts * Add eproduct error box component and style. style a lot. * Fixes * Fix lint * Add cannot refund error title + description * Extract messages * Refactor after review * Add better, nicer and fancier imports to product error cell * Use error color from palette in product error cell * Fix max refund when 0 for return * Add ddisable ability to refund products button so it's disabled when 0 products selected * Add class for order return form data parsing and add condition to not do refund when total captured on order is 0 * Update snapshots * Add condition for order lines quantity in order products table row * Fix return amount submit button * Add change to changelog Co-authored-by: Jakub Majorek <majorek.jakub@gmail.com>
2021-01-20 16:16:43 +00:00
case OrderStatus.PARTIALLY_RETURNED:
return {
localized: intl.formatMessage(orderStatusMessages.partiallyReturned),
status: StatusType.NEUTRAL
};
case OrderStatus.RETURNED:
return {
localized: intl.formatMessage(orderStatusMessages.returned),
status: StatusType.NEUTRAL
};
2019-06-19 14:40:52 +00:00
}
return {
localized: status,
status: StatusType.ERROR
2019-06-19 14:40:52 +00:00
};
};
export const transformAddressToForm = (data?: AddressType) => ({
city: data?.city || "",
cityArea: data?.cityArea || "",
companyName: data?.companyName || "",
country: data?.country?.code || "",
countryArea: data?.countryArea || "",
firstName: data?.firstName || "",
lastName: data?.lastName || "",
phone: data?.phone || "",
postalCode: data?.postalCode || "",
streetAddress1: data?.streetAddress1 || "",
streetAddress2: data?.streetAddress2 || ""
2019-06-19 14:40:52 +00:00
});
2019-08-09 11:14:35 +00:00
export function maybe<T>(exp: () => T): T | undefined;
export function maybe<T>(exp: () => T, d: T): T;
export function maybe(exp: any, d?: any) {
2019-06-19 14:40:52 +00:00
try {
const result = exp();
return result === undefined ? d : result;
} catch {
return d;
}
}
export function only<T>(obj: T, key: keyof T): boolean {
return Object.keys(obj).every(objKey =>
objKey === key ? obj[key] !== undefined : obj[key] === undefined
);
}
export function empty(obj: {}): boolean {
2019-06-19 14:40:52 +00:00
return Object.keys(obj).every(key => obj[key] === undefined);
}
export function hasErrors(errorList: UserError[] | null): boolean {
return !(
errorList === undefined ||
errorList === null ||
errorList.length === 0
);
}
export function getMutationState(
called: boolean,
loading: boolean,
2020-09-01 16:22:54 +00:00
...errorList: any[][]
2019-06-19 14:40:52 +00:00
): ConfirmButtonTransitionState {
if (loading) {
return "loading";
}
if (called) {
return errorList.map(hasErrors).reduce((acc, curr) => acc || curr, false)
? "error"
: "success";
}
return "default";
}
2019-12-06 17:11:28 +00:00
interface SaleorMutationResult {
errors?: UserError[];
}
export function getMutationErrors<
TData extends Record<string, SaleorMutationResult>
>(data: TData): UserError[] {
return Object.values(data).reduce(
(acc: UserError[], mut) => [...acc, ...maybe(() => mut.errors, [])],
[]
);
}
2019-12-06 17:11:28 +00:00
export function getMutationStatus<
TData extends Record<string, SaleorMutationResult | any>
>(opts: MutationResult<TData>): ConfirmButtonTransitionState {
const errors = opts.data ? getMutationErrors(opts.data) : [];
2019-12-06 17:11:28 +00:00
return getMutationState(opts.called, opts.loading, errors);
}
2019-06-19 14:40:52 +00:00
export function getMutationProviderData<TData, TVariables>(
2019-08-12 11:47:38 +00:00
mutateFn: MutationFunction<TData, TVariables>,
2019-12-06 17:14:19 +00:00
opts: MutationResult<TData> & MutationResultAdditionalProps
2019-06-19 14:40:52 +00:00
): PartialMutationProviderOutput<TData, TVariables> {
return {
mutate: variables => mutateFn({ variables }),
opts
};
}
interface User {
email: string;
firstName?: string;
lastName?: string;
}
export function getUserName(user?: User, returnEmail?: boolean) {
return user && (user.email || (user.firstName && user.lastName))
? user.firstName && user.lastName
? [user.firstName, user.lastName].join(" ")
: returnEmail
? user.email
: user.email.split("@")[0]
: undefined;
}
export function getUserInitials(user?: User) {
return user && (user.email || (user.firstName && user.lastName))
? (user.firstName && user.lastName
? user.firstName[0] + user.lastName[0]
: user.email.slice(0, 2)
).toUpperCase()
: undefined;
}
export function createHref(url: string) {
return urlJoin(APP_MOUNT_URI, url);
}
interface AnyEvent {
stopPropagation: () => void;
}
2020-08-17 14:44:40 +00:00
export function stopPropagation(cb: (event?: AnyEvent) => void) {
2019-06-19 14:40:52 +00:00
return (event: AnyEvent) => {
event.stopPropagation();
2020-08-17 14:44:40 +00:00
cb(event);
2019-06-19 14:40:52 +00:00
};
}
2019-08-09 11:14:35 +00:00
export interface DateTime {
date: string;
time: string;
}
2019-08-09 11:14:35 +00:00
export function joinDateTime(date: string, time?: string) {
if (!date) {
return null;
}
const setTime = time || "00:00";
const dateTime = moment(date + " " + setTime).format();
return dateTime;
}
export function splitDateTime(dateTime: string) {
if (!dateTime) {
return {
date: "",
time: ""
};
}
// Default html input format YYYY-MM-DD HH:mm
const splitDateTime = moment(dateTime)
.format("YYYY-MM-DD HH:mm")
.split(" ");
return {
date: splitDateTime[0],
time: splitDateTime[1]
};
}
export function generateCode(charNum: number) {
let result = "";
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for (let i = 0; i < charNum; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}
2019-09-05 13:05:12 +00:00
export function findInEnum<TEnum extends {}>(needle: string, haystack: TEnum) {
2019-09-05 13:05:12 +00:00
const match = Object.keys(haystack).find(key => key === needle);
if (!!match) {
return haystack[needle as keyof TEnum];
}
throw new Error(`Key ${needle} not found in enum`);
}
2019-09-13 11:33:42 +00:00
export function findValueInEnum<TEnum extends {}>(
2019-12-17 17:13:56 +00:00
needle: string,
haystack: TEnum
2019-12-20 15:53:03 +00:00
): TEnum[keyof TEnum] {
2019-12-17 17:13:56 +00:00
const match = Object.entries(haystack).find(([_, value]) => value === needle);
2019-12-20 15:53:03 +00:00
if (!match) {
throw new Error(`Value ${needle} not found in enum`);
2019-12-17 17:13:56 +00:00
}
2019-12-20 15:53:03 +00:00
return (needle as unknown) as TEnum[keyof TEnum];
2019-12-17 17:13:56 +00:00
}
export function parseBoolean(a: string, defaultValue: boolean): boolean {
2019-09-26 10:14:07 +00:00
if (a === undefined) {
2019-12-17 17:13:56 +00:00
return defaultValue;
2019-09-26 10:14:07 +00:00
}
2019-09-13 11:33:42 +00:00
return a === "true";
}
2019-10-18 12:29:01 +00:00
export function capitalize(s: string) {
return s.charAt(0).toLocaleUpperCase() + s.slice(1);
}
2019-10-25 12:18:52 +00:00
export function transformFormToAddressInput<T>(
2019-11-13 13:50:38 +00:00
address: T & AddressTypeInput
): T & AddressInput {
2019-10-25 12:18:52 +00:00
return {
...address,
country: findInEnum(address.country, CountryCode)
};
}
2020-02-20 14:18:22 +00:00
export function getStringOrPlaceholder(s: string | undefined): string {
return s || "...";
}
export const getDatePeriod = (days: number): DateRangeInput => {
if (days < 1) {
return {};
}
const end = moment().startOf("day");
const start = end.subtract(days - 1);
const format = "YYYY-MM-DD";
return {
gte: start.format(format),
lte: end.format(format)
};
};
export const transformAddressToAddressInput = (data?: AddressType) => ({
city: data?.city || "",
cityArea: data?.cityArea || "",
companyName: data?.companyName || "",
country: findInEnum(data?.country?.code || "", CountryCode),
countryArea: data?.countryArea || "",
firstName: data?.firstName || "",
lastName: data?.lastName || "",
phone: data?.phone || "",
postalCode: data?.postalCode || "",
streetAddress1: data?.streetAddress1 || "",
streetAddress2: data?.streetAddress2 || ""
});