common-ui/src/lib/utils/functions.ts
2022-03-22 00:33:37 +02:00

116 lines
3.8 KiB
TypeScript

import { ITrackable } from '../listing/models/trackable';
import { FormGroup } from '@angular/forms';
import { forOwn, has, isEqual, isPlainObject, transform } from 'lodash-es';
import dayjs, { Dayjs } from 'dayjs';
export function capitalize(value: string): string {
if (!value) {
return '';
}
return value.charAt(0).toUpperCase() + value.slice(1);
}
export function humanize(value: string, lowercase = true): string {
if (!value) {
return '';
}
const words = (lowercase ? value.toLowerCase() : value).split(/[ \-_]+/);
return words.map(capitalize).join(' ');
}
export function _log(value: unknown, message = '') {
console.log(`%c[${dayjs().format('HH:mm:ss.SSS')}] ${message}`, 'color: yellow;', value);
}
export function toNumber(str: string): number {
try {
return parseInt(`${str}`.replace(/\D/g, ''), 10);
} catch (e) {
return 0;
}
}
export function trackByFactory<T extends ITrackable>() {
return (index: number, item: T): string => item.id;
}
export function hasFormChanged(form: FormGroup, initialFormValue: Record<string, string>): boolean {
if (form && initialFormValue) {
for (const key of Object.keys(form.getRawValue())) {
const initialValue = initialFormValue[key];
const updatedValue = form.get(key)?.value;
if (initialValue == null && updatedValue != null) {
const updatedValueType = typeof updatedValue;
if (updatedValueType !== 'string' && updatedValueType !== 'boolean') {
return true;
} else if (updatedValueType === 'string' && updatedValue.length > 0) {
return true;
} else if (updatedValueType === 'boolean' && updatedValue === true) {
return true;
}
} else if (initialValue !== updatedValue) {
if (Array.isArray(updatedValue)) {
if (JSON.stringify(initialValue) !== JSON.stringify(updatedValue)) {
return true;
}
} else if (updatedValue instanceof dayjs) {
if (!(updatedValue as Dayjs).isSame(dayjs(initialValue), 'day')) {
return true;
}
} else {
return true;
}
}
}
}
return false;
}
const HOURS_IN_A_DAY = 24;
const MINUTES_IN_AN_HOUR = 60;
export function getLeftDateTime(ISOString: string) {
const date = dayjs(ISOString);
const now = new Date(Date.now());
const daysLeft = date.diff(now, 'days');
const hoursFromNow = date.diff(now, 'hours');
const hoursLeft = hoursFromNow - HOURS_IN_A_DAY * daysLeft;
const minutesFromNow = date.diff(now, 'minutes');
const minutesLeft = minutesFromNow - HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR * daysLeft;
return { daysLeft, hoursLeft, minutesLeft };
}
export function deepDiffObj(base: Record<string, unknown>, object: Record<string, unknown>) {
if (!object) {
throw new Error(`The object compared should be an object: ${object}`);
}
if (!base) {
return object;
}
const res = transform(object, (result: Record<string, unknown>, value, key) => {
if (!has(base, key)) {
result[key] = value;
} // fix edge case: not defined to explicitly defined as undefined
if (!isEqual(value, base[key])) {
result[key] =
isPlainObject(value) && isPlainObject(base[key])
? deepDiffObj(base[key] as Record<string, unknown>, value as Record<string, unknown>)
: value;
}
});
// map removed fields to undefined
forOwn(base, (value, key) => {
if (!has(object, key)) {
res[key] = undefined;
}
});
return res;
}