mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
137 lines
3.4 KiB
TypeScript
137 lines
3.4 KiB
TypeScript
import moment from 'moment';
|
|
import 'moment/locale/id';
|
|
import { twMerge } from 'tailwind-merge';
|
|
import clsx, { ClassValue } from 'clsx';
|
|
|
|
// set locale globally
|
|
moment.locale('id');
|
|
|
|
export const sleep = (ms: number = 1000) =>
|
|
new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
|
export const formatDate = (date: moment.MomentInput, format?: string) => {
|
|
if (!date) return '-';
|
|
|
|
return moment(date).format(format);
|
|
};
|
|
|
|
export const cn = (...inputs: ClassValue[]) => {
|
|
return twMerge(clsx(inputs));
|
|
};
|
|
|
|
export const formatNumber = (
|
|
value: number | bigint | Intl.StringNumericLiteral,
|
|
locale = 'id-ID',
|
|
minimumFractionDigits = 0,
|
|
maximumFractionDigits = 2
|
|
) => {
|
|
return new Intl.NumberFormat(locale, {
|
|
minimumFractionDigits,
|
|
maximumFractionDigits,
|
|
}).format(value);
|
|
};
|
|
|
|
export function formatVechicleNumber(value: string): string {
|
|
let result = '';
|
|
for (let i = 0; i < (value?.length ?? 0); i++) {
|
|
const curr = value[i];
|
|
const prev = value[i - 1];
|
|
|
|
// Cek apakah terjadi perpindahan dari huruf ke angka atau angka ke huruf
|
|
if (i > 0) {
|
|
const isCurrDigit = /\d/.test(curr);
|
|
const isPrevDigit = /\d/.test(prev);
|
|
|
|
if (isCurrDigit !== isPrevDigit) {
|
|
result += ' ';
|
|
}
|
|
}
|
|
|
|
result += curr;
|
|
}
|
|
|
|
return result.trim().replace(/\s+/g, ' ');
|
|
}
|
|
|
|
export const formatCurrency = (
|
|
value: number | bigint | Intl.StringNumericLiteral,
|
|
currency = 'IDR',
|
|
locale = 'id-ID',
|
|
minimumFractionDigits = 0,
|
|
maximumFractionDigits = 2
|
|
) => {
|
|
return new Intl.NumberFormat(locale, {
|
|
style: 'currency',
|
|
currency,
|
|
minimumFractionDigits,
|
|
maximumFractionDigits,
|
|
}).format(value);
|
|
};
|
|
|
|
/**
|
|
* Retrieves a nested value from an object using a dot-delimited key path.
|
|
* Supports array indexes (e.g., "users.0.name") and returns a default value
|
|
* if the path does not exist.
|
|
*
|
|
* @param obj - The source object to search.
|
|
* @param path - Dot-delimited key string (e.g., "user.address.city").
|
|
* @param defaultValue - Optional value to return if the key path is not found.
|
|
* @returns The value found at the specified path, or the default value.
|
|
*/
|
|
export function getByPath<T, D = undefined>(
|
|
obj: T,
|
|
path: string,
|
|
defaultValue?: D
|
|
): D {
|
|
if (obj == null) return defaultValue as D;
|
|
if (!path) return obj as D;
|
|
|
|
const segments = path.split('.').filter(Boolean);
|
|
let cur: { [key: string]: unknown } = obj;
|
|
|
|
for (const seg of segments) {
|
|
if (cur == null) return defaultValue as D;
|
|
const key: string | number =
|
|
Array.isArray(cur) && /^\d+$/.test(seg) ? Number(seg) : seg;
|
|
if (Object(cur) !== cur || !(key in cur)) {
|
|
return defaultValue as D;
|
|
}
|
|
cur = cur[key] as { [key: string]: unknown };
|
|
}
|
|
|
|
return cur as D;
|
|
}
|
|
|
|
export const convertRowSelectionArrToObj = (
|
|
rowSelectionArr: string[] | number[]
|
|
) => {
|
|
const result: Record<string | number, boolean> = {};
|
|
|
|
rowSelectionArr.forEach((item) => {
|
|
result[item] = true;
|
|
});
|
|
|
|
return result;
|
|
};
|
|
|
|
export const convertRowSelectionObjToArr = (
|
|
rowSelection: string[] | number[]
|
|
) => {
|
|
const result = Object.keys(rowSelection).map(Number);
|
|
|
|
return result;
|
|
};
|
|
|
|
export const isPathActive = (pathname: string, link?: string) => {
|
|
if (!link) return false;
|
|
|
|
const splittedPathname = pathname.split('/');
|
|
const splittedLink = link.split('/');
|
|
|
|
const isActiveLinkValid = splittedLink.every((linkChunk, idx) => {
|
|
return linkChunk === splittedPathname[idx];
|
|
});
|
|
|
|
return pathname.startsWith(link) && isActiveLinkValid;
|
|
};
|