import { ITrackable } from '../listing/models/trackable'; import { UntypedFormGroup } 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() { return (index: number, item: T): string => item.id; } export function hasFormChanged(form: UntypedFormGroup, initialFormValue: Record): 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, object: Record) { if (!object) { throw new Error(`The object compared should be an object: ${object}`); } if (!base) { return object; } const res = transform(object, (result: Record, value: any, key: string) => { 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, value as Record) : value; } }); // map removed fields to undefined forOwn(base, (value: any, key: string) => { if (!has(object, key)) { res[key] = undefined; } }); return res; } export function bool(value: unknown): boolean { if (typeof value !== 'string') { return Boolean(value); } const _value = value.toLowerCase().trim(); if (_value === 'true') { return true; } if (_value === 'false') { return false; } return Boolean(_value); }