Files
helpdesk/desk/src/utils.ts
T

208 lines
5.2 KiB
TypeScript

import { useClipboard, useDateFormat, useTimeAgo } from "@vueuse/core";
import dayjs from "dayjs";
import { toast } from "frappe-ui";
import { gemoji } from "gemoji";
import { h, markRaw, ref } from "vue";
import zod from "zod";
import TicketIcon from "./components/icons/TicketIcon.vue";
/**
* Wrapper to create toasts, supplied with default options.
* https://frappeui.com/components/toast.html
* @param options - `Toast` options
*/
export function createToast(options?: Record<string, string>) {
toast.create(...options);
}
/**
* Copy a string to clipboard, and create a toast
* @param s - String to copy
*/
export async function copy(s: string) {
const { copy: c } = useClipboard();
c(s).then(() => toast.success("Copied to clipboard"));
}
/**
* Get assigned user from `_assign` string. The return value is a `string`,
* not a `User` object.
* @param s - `_assign` string (JSON)
* @returns user id
*/
export function getAssign(s: string): string | undefined {
const assignJson = JSON.parse(s);
const arr = Array.isArray(assignJson) ? assignJson : [];
return arr.slice(-1).pop();
}
export function validateEmail(email) {
const regExp =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return regExp.test(email);
}
export function validateEmailWithZod(email: string) {
const success = zod.string().email().safeParse(email).success;
return success;
}
export function dateFormat(date, format) {
const _format = format || "DD-MM-YYYY HH:mm:ss";
return useDateFormat(date, _format).value;
}
export function timeAgo(date) {
return useTimeAgo(date).value;
}
export const dateTooltipFormat = "ddd, MMM D, YYYY h:mm A";
export function errorMessage(title, message) {
createToast({
title: title || "Error",
text: message,
icon: "x",
iconClasses: "text-red-600",
});
}
export function formatTime(seconds) {
const days = Math.floor(seconds / (3600 * 24));
const hours = Math.floor((seconds % (3600 * 24)) / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainingSeconds = Math.floor(seconds % 60);
let formattedTime = "";
if (days > 0) {
formattedTime += `${days}d `;
}
if (hours > 0 || days > 0) {
formattedTime += `${hours}h `;
}
if (minutes > 0 || hours > 0 || days > 0) {
formattedTime += `${minutes}m `;
}
formattedTime += `${remainingSeconds}s`;
return formattedTime.trim();
}
export const isCustomerPortal = ref(false);
export async function copyToClipboard() {
let text = "Copied to clipboard";
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(text);
} else {
let input = document.createElement("input");
let body = document.querySelector("body");
body.appendChild(input);
input.value = text;
input.select();
document.execCommand("copy");
input.remove();
}
toast.success(text);
}
export const textEditorMenuButtons = [
"Paragraph",
["Heading 2", "Heading 3", "Heading 4", "Heading 5", "Heading 6"],
"Separator",
"Bold",
"Italic",
"Separator",
"Bullet List",
"Numbered List",
"Separator",
"Align Left",
"Align Center",
"Align Right",
"FontColor",
"Separator",
"Image",
"Video",
"Link",
"Blockquote",
"Code",
"Horizontal Rule",
[
"InsertTable",
"AddColumnBefore",
"AddColumnAfter",
"DeleteColumn",
"AddRowBefore",
"AddRowAfter",
"DeleteRow",
"MergeCells",
"SplitCell",
"ToggleHeaderColumn",
"ToggleHeaderRow",
"ToggleHeaderCell",
"DeleteTable",
],
];
export function isContentEmpty(content: string) {
const parser = new DOMParser();
const doc = parser.parseFromString(content, "text/html");
return doc.body.textContent === "";
}
export function isTouchScreenDevice() {
return "ontouchstart" in document.documentElement;
}
export function isEmoji(str) {
const emojiList = gemoji.map((emoji) => emoji.emoji);
return emojiList.includes(str);
}
export function getIcon(icon) {
if (isEmoji(icon)) {
return h("div", icon);
}
return icon || markRaw(TicketIcon);
}
export function formatTimeShort(date: string) {
const now = dayjs();
const inputDate = dayjs.tz(date);
const diffSeconds = now.diff(inputDate, "second");
const diffMinutes = now.diff(inputDate, "minute");
const diffHours = now.diff(inputDate, "hour");
const diffDays = now.diff(inputDate, "day");
const diffWeeks = now.diff(inputDate, "week");
const diffMonths = now.diff(inputDate, "month");
const diffYears = now.diff(inputDate, "year");
if (diffSeconds < 60) return `${diffSeconds} s`;
if (diffMinutes < 60) return `${diffMinutes} m`;
if (diffHours < 24) return `${diffHours} h`;
if (diffDays < 7) return `${diffDays} d`;
if (diffWeeks < 4) return `${diffWeeks} w`;
if (diffMonths < 12) return `${diffMonths} M`;
return `${diffYears}Y`;
}
function hasArabicContent(content: string) {
const arabicRegex = /[\u0600-\u06FF]/;
return arabicRegex.test(content);
}
export function getFontFamily(content: string) {
const langMap = {
default: "!font-[InterVar]",
arabic: "!font-[system-ui]",
};
let lang = "default";
if (hasArabicContent(content)) {
lang = "arabic";
}
return langMap[lang];
}