import { formatDistanceToNow, parseJSON, format, parse } from "date-fns"; export function friendlyDate(date) { return formatDistanceToNow(parseJSON(date), { addSuffix: true }); } export function readableDate(date) { if (!date) { return ""; } return format(parseJSON(date), "dd MMM yyyy"); } export function readableDatetime(date) { if (!date) { return ""; } return format(parseJSON(date), "dd MMM yyyy HH:mm"); } export function stripHtml(html = "") { let tmp = document.createElement("div"); tmp.innerHTML = html; return tmp.textContent || tmp.innerText || ""; } export function randomId(length = 10) { return Math.random() .toString(36) .substring(2, length + 2); } export function clickOutside(node) { const handleClick = (event) => { if (node && !node.contains(event.target) && !event.defaultPrevented) { node.dispatchEvent(new CustomEvent("click_outside", node)); } }; document.addEventListener("click", handleClick, true); return { destroy() { document.removeEventListener("click", handleClick, true); }, }; } export function arrayUnique(array) { return array.filter((value, index) => array.indexOf(value) === index); } export function arrayUniqueBy(items, uniqueBy) { const ids = new Set(items.map((item) => item[uniqueBy])); return [...ids].map((id) => items.find((i) => i[uniqueBy] === id)); } export function arrayMoveElement(array, from, to) { if (from === to) { return array; } const item = array.find((v, i) => i === from); const arrayWithout = array.filter((v, i) => i !== from); if (from > to) { return arrayWithout.reduce((c, v, i) => { if (i === to) { return [...c, item, v]; } return [...c, v]; }, []); } return arrayWithout.reduce((c, v, i) => { if (i + 1 === to) { return [...c, v, item]; } return [...c, v]; }, []); } export function isEqual(db, ed) { let isObject = (x) => typeof x === "object" && !Array.isArray(x) && x !== null; let isArray = (x) => x?.constructor === Array; let isEmpty = (x) => x === null || x === undefined || x == []; const db_value = db ?? null; const ed_value = ed ?? null; if (isObject(db_value)) { let keys = Object.keys(db_value); return keys.reduce((acc, k) => { if (acc === false) { return false; } return isEqual(db_value?.[k], ed_value?.[k]); }, true); } if (isArray(db_value)) { return db_value.reduce((c, v, i) => { if (c === false) { return false; } return isEqual(v, ed_value?.[i]); }, true); } if (isEmpty(db_value) && isEmpty(ed_value)) { return true; } if (db_value == ed_value) { return true; } return false; // const ok = Object.keys, // tx = typeof x, // ty = typeof y; // return x && y && tx === "object" && tx === ty // ? ok(x).length === ok(y).length && // ok(x).every((key) => isEqual(x[key], y[key])) // : x === y; }