116 lines
3.8 KiB
TypeScript
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;
|
|
}
|