diff --git a/docs/widgets/services/customapi.md b/docs/widgets/services/customapi.md index 7f26f80fb..c392d942c 100644 --- a/docs/widgets/services/customapi.md +++ b/docs/widgets/services/customapi.md @@ -54,12 +54,20 @@ widget: time: other key color: theme # optional - defaults to "". Allowed values: `["theme", "adaptive", "black", "white"]`. format: date # optional + - field: key + label: Number of things in array + format: size + # This (no field) will take the root of the API response, e.g. when APIs return an array: + - label: Number of items + format: size ``` -Supported formats for the values are `text`, `number`, `float`, `percent`, `bytes`, `bitrate`, `date` and `relativeDate`. +Supported formats for the values are `text`, `number`, `float`, `percent`, `bytes`, `bitrate`, `size`, `date` and `relativeDate`. The `dateStyle` and `timeStyle` options of the `date` format are passed directly to [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat) and the `style` and `numeric` options of `relativeDate` are passed to [Intl.RelativeTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat). +The `size` format will return the length of the array or string, or the number of keys in an object. This is then formatted as `number`. + ## Example For the following JSON object from the API: diff --git a/src/widgets/customapi/component.jsx b/src/widgets/customapi/component.jsx index 726dcb602..3f1825b25 100644 --- a/src/widgets/customapi/component.jsx +++ b/src/widgets/customapi/component.jsx @@ -9,6 +9,11 @@ function getValue(field, data) { let lastField = field; let key = ""; + // Support APIs that return arrays or scalars directly. + if (typeof field === "undefined") { + return value; + } + while (typeof lastField === "object") { key = Object.keys(lastField)[0] ?? null; @@ -27,6 +32,16 @@ function getValue(field, data) { 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; @@ -85,6 +100,9 @@ function formatValue(t, mapping, rawValue) { numeric: mapping?.numeric, }); break; + case "size": + value = t("common.number", { value: getSize(value) }); + break; case "text": default: // nothing