mirror of
https://github.com/gethomepage/homepage.git
synced 2026-09-27 06:21:18 -07:00
Extract helpers
This commit is contained in:
@@ -1,161 +1,13 @@
|
|||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { useTranslation } from "next-i18next/pages";
|
import { useTranslation } from "next-i18next/pages";
|
||||||
|
|
||||||
|
import { formatValue, getColor, getValue } from "./utils";
|
||||||
|
|
||||||
import Block from "components/services/widget/block";
|
import Block from "components/services/widget/block";
|
||||||
import Container from "components/services/widget/container";
|
import Container from "components/services/widget/container";
|
||||||
import * as shvl from "utils/config/shvl";
|
import * as shvl from "utils/config/shvl";
|
||||||
import useWidgetAPI from "utils/proxy/use-widget-api";
|
import useWidgetAPI from "utils/proxy/use-widget-api";
|
||||||
|
|
||||||
function getValue(field, data) {
|
|
||||||
let value = data;
|
|
||||||
let lastField = field;
|
|
||||||
let key = "";
|
|
||||||
|
|
||||||
// Support APIs that return arrays or scalars directly.
|
|
||||||
if (typeof field === "undefined") {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// shvl is easier, everything else is kept for backwards compatibility.
|
|
||||||
if (typeof field === "string") {
|
|
||||||
return shvl.get(data, field, null) ?? data[field] ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (typeof lastField === "object") {
|
|
||||||
key = Object.keys(lastField)[0] ?? null;
|
|
||||||
|
|
||||||
if (key === null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = value[key];
|
|
||||||
lastField = lastField[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof value === "undefined") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value[lastField] ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSize(data) {
|
|
||||||
if (Array.isArray(data) || typeof data === "string") {
|
|
||||||
return data.length;
|
|
||||||
} else if (typeof data === "object" && data !== null) {
|
|
||||||
return Object.keys(data).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NaN;
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatValue(t, mapping, rawValue) {
|
|
||||||
let value = rawValue;
|
|
||||||
|
|
||||||
// Remap the value.
|
|
||||||
const remaps = mapping?.remap ?? [];
|
|
||||||
for (let i = 0; i < remaps.length; i += 1) {
|
|
||||||
const remap = remaps[i];
|
|
||||||
if (remap?.any || remap?.value === value) {
|
|
||||||
value = remap.to;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scale the value. Accepts either a number to multiply by or a string
|
|
||||||
// like "12/345".
|
|
||||||
const scale = mapping?.scale;
|
|
||||||
if (typeof scale === "number") {
|
|
||||||
value *= scale;
|
|
||||||
} else if (typeof scale === "string") {
|
|
||||||
const parts = scale.split("/");
|
|
||||||
const numerator = parts[0] ? parseFloat(parts[0]) : 1;
|
|
||||||
const denominator = parts[1] ? parseFloat(parts[1]) : 1;
|
|
||||||
value = (value * numerator) / denominator;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format the value using a known type.
|
|
||||||
switch (mapping?.format) {
|
|
||||||
case "number":
|
|
||||||
value = t("common.number", { value: parseInt(value, 10) });
|
|
||||||
break;
|
|
||||||
case "float":
|
|
||||||
value = t("common.number", { value });
|
|
||||||
break;
|
|
||||||
case "percent":
|
|
||||||
value = t("common.percent", { value });
|
|
||||||
break;
|
|
||||||
case "duration":
|
|
||||||
value = t("common.duration", { value });
|
|
||||||
break;
|
|
||||||
case "bytes":
|
|
||||||
value = t("common.bytes", { value });
|
|
||||||
break;
|
|
||||||
case "bitrate":
|
|
||||||
value = t("common.bitrate", { value });
|
|
||||||
break;
|
|
||||||
case "date":
|
|
||||||
value = t("common.date", {
|
|
||||||
value,
|
|
||||||
lng: mapping?.locale,
|
|
||||||
dateStyle: mapping?.dateStyle ?? "long",
|
|
||||||
timeStyle: mapping?.timeStyle,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "relativeDate":
|
|
||||||
value = t("common.relativeDate", {
|
|
||||||
value,
|
|
||||||
lng: mapping?.locale,
|
|
||||||
style: mapping?.style,
|
|
||||||
numeric: mapping?.numeric,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "size":
|
|
||||||
value = t("common.number", { value: getSize(value) });
|
|
||||||
break;
|
|
||||||
case "text":
|
|
||||||
default:
|
|
||||||
// nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply fixed prefix.
|
|
||||||
const prefix = mapping?.prefix;
|
|
||||||
if (prefix) {
|
|
||||||
value = `${prefix} ${value}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply fixed suffix.
|
|
||||||
const suffix = mapping?.suffix;
|
|
||||||
if (suffix) {
|
|
||||||
value = `${value} ${suffix}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getColor(mapping, customData) {
|
|
||||||
const value = getValue(mapping.additionalField.field, customData);
|
|
||||||
const { color } = mapping.additionalField;
|
|
||||||
|
|
||||||
switch (color) {
|
|
||||||
case "adaptive":
|
|
||||||
try {
|
|
||||||
const number = parseFloat(value);
|
|
||||||
return number > 0 ? "text-emerald-300" : "text-rose-300";
|
|
||||||
} catch (e) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
case "black":
|
|
||||||
return `text-black`;
|
|
||||||
case "white":
|
|
||||||
return `text-white`;
|
|
||||||
case "theme":
|
|
||||||
return `text-theme-500`;
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Component({ service }) {
|
export default function Component({ service }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
import * as shvl from "utils/config/shvl";
|
||||||
|
|
||||||
|
export function getValue(field, data) {
|
||||||
|
let value = data;
|
||||||
|
let lastField = field;
|
||||||
|
let key = "";
|
||||||
|
|
||||||
|
// Support APIs that return arrays or scalars directly.
|
||||||
|
if (typeof field === "undefined") {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// shvl is easier, everything else is kept for backwards compatibility.
|
||||||
|
if (typeof field === "string") {
|
||||||
|
return shvl.get(data, field, null) ?? data[field] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (typeof lastField === "object") {
|
||||||
|
key = Object.keys(lastField)[0] ?? null;
|
||||||
|
|
||||||
|
if (key === null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = value[key];
|
||||||
|
lastField = lastField[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === "undefined") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value[lastField] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSize(data) {
|
||||||
|
if (Array.isArray(data) || typeof data === "string") {
|
||||||
|
return data.length;
|
||||||
|
} else if (typeof data === "object" && data !== null) {
|
||||||
|
return Object.keys(data).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NaN;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatValue(t, mapping, rawValue) {
|
||||||
|
let value = rawValue;
|
||||||
|
|
||||||
|
// Remap the value.
|
||||||
|
const remaps = mapping?.remap ?? [];
|
||||||
|
for (let i = 0; i < remaps.length; i += 1) {
|
||||||
|
const remap = remaps[i];
|
||||||
|
if (remap?.any || remap?.value === value) {
|
||||||
|
value = remap.to;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale the value. Accepts either a number to multiply by or a string
|
||||||
|
// like "12/345".
|
||||||
|
const scale = mapping?.scale;
|
||||||
|
if (typeof scale === "number") {
|
||||||
|
value *= scale;
|
||||||
|
} else if (typeof scale === "string") {
|
||||||
|
const parts = scale.split("/");
|
||||||
|
const numerator = parts[0] ? parseFloat(parts[0]) : 1;
|
||||||
|
const denominator = parts[1] ? parseFloat(parts[1]) : 1;
|
||||||
|
value = (value * numerator) / denominator;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the value using a known type.
|
||||||
|
switch (mapping?.format) {
|
||||||
|
case "number":
|
||||||
|
value = t("common.number", { value: parseInt(value, 10) });
|
||||||
|
break;
|
||||||
|
case "float":
|
||||||
|
value = t("common.number", { value });
|
||||||
|
break;
|
||||||
|
case "percent":
|
||||||
|
value = t("common.percent", { value });
|
||||||
|
break;
|
||||||
|
case "duration":
|
||||||
|
value = t("common.duration", { value });
|
||||||
|
break;
|
||||||
|
case "bytes":
|
||||||
|
value = t("common.bytes", { value });
|
||||||
|
break;
|
||||||
|
case "bitrate":
|
||||||
|
value = t("common.bitrate", { value });
|
||||||
|
break;
|
||||||
|
case "date":
|
||||||
|
value = t("common.date", {
|
||||||
|
value,
|
||||||
|
lng: mapping?.locale,
|
||||||
|
dateStyle: mapping?.dateStyle ?? "long",
|
||||||
|
timeStyle: mapping?.timeStyle,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "relativeDate":
|
||||||
|
value = t("common.relativeDate", {
|
||||||
|
value,
|
||||||
|
lng: mapping?.locale,
|
||||||
|
style: mapping?.style,
|
||||||
|
numeric: mapping?.numeric,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "size":
|
||||||
|
value = t("common.number", { value: getSize(value) });
|
||||||
|
break;
|
||||||
|
case "text":
|
||||||
|
default:
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply fixed prefix.
|
||||||
|
const prefix = mapping?.prefix;
|
||||||
|
if (prefix) {
|
||||||
|
value = `${prefix} ${value}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply fixed suffix.
|
||||||
|
const suffix = mapping?.suffix;
|
||||||
|
if (suffix) {
|
||||||
|
value = `${value} ${suffix}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getColor(mapping, customData) {
|
||||||
|
const value = getValue(mapping.additionalField.field, customData);
|
||||||
|
const { color } = mapping.additionalField;
|
||||||
|
|
||||||
|
switch (color) {
|
||||||
|
case "adaptive":
|
||||||
|
try {
|
||||||
|
const number = parseFloat(value);
|
||||||
|
return number > 0 ? "text-emerald-300" : "text-rose-300";
|
||||||
|
} catch (e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
case "black":
|
||||||
|
return `text-black`;
|
||||||
|
case "white":
|
||||||
|
return `text-white`;
|
||||||
|
case "theme":
|
||||||
|
return `text-theme-500`;
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user