import React from "react";
import { __, sprintf } from "@wordpress/i18n";
import { useQuery } from "@tanstack/react-query";
import { getApps, getConnection, getHealth } from "../utils/api";
import { formatDate, relativeTime, toMillis } from "../utils/format";
import { APPS_KEY } from "./ConnectedApps";
import { CONNECTION_KEY } from "./ConnectionConfig";
import { HEALTH_KEY } from "./ConnectionHealth";
import { IconClock, IconCode, IconGrid, IconPlug } from "./Icons";
/**
* The four KPI tiles (ADR-062).
*
* Every value is read from a payload the page already fetches — the same three
* React Query keys the sections below use, so this row costs no extra request:
* an identical key and query function is served from the shared cache.
*
* **No sparklines and no delta chips.** The approved mock-up draws both, and
* they are decoration over data that does not exist: the server keeps one
* `last_used` stamp per credential and no history whatsoever, so a trend line
* here could only be invented.
*
* @since 4.9.0
*/
/**
* One tile. The accent arrives as custom properties so the stylesheet decides
* what happens to it in dark mode, the way the client cards do (ADR-054).
*/
const Tile = ({ label, Icon, accent, accentDark, value, valueSm, note }) => (
{label}
{value}
{note && {note}}
);
/**
* The analytics skeleton for a tile that is still waiting on its query
* (`KpiSkeleton` in Pro's `analytics/components/common/ui.js`), so the row
* arrives at its final height in one step instead of growing under the reader.
*/
const TileSkeleton = () => (
);
export default function KpiRow({ status }) {
const connection = useQuery({ queryKey: [CONNECTION_KEY], queryFn: getConnection });
const health = useQuery({ queryKey: [HEALTH_KEY], queryFn: getHealth });
const apps = useQuery({ queryKey: [APPS_KEY], queryFn: getApps });
const connectedAt = connection.data?.connected_at || null;
const toolCount = health.data?.abilities?.betterdocs;
const appRows = Array.isArray(apps.data?.oauth_apps) ? apps.data.oauth_apps : [];
// The newest stamp anything holds: the connection token's own last use, and
// each OAuth app's. There is no other record of activity on this server.
// Compared as milliseconds, but carried forward in the shape it arrived in —
// `relativeTime` does its own conversion, and handing it a value already in
// milliseconds would multiply it by a thousand a second time.
const lastActivity = [connection.data?.last_used, ...appRows.map((app) => app.last_used)]
.map((value) => ({ value, ms: toMillis(value) }))
.filter((stamp) => stamp.ms !== null)
.reduce((newest, stamp) => (newest === null || stamp.ms > newest.ms ? stamp : newest), null);
return (
{connection.isLoading ? (
) : (
)}
{health.isLoading || typeof toolCount !== "number" ? (
) : (
)}
{apps.isLoading ? (
) : (
)}
{connection.isLoading || apps.isLoading ? (
) : (
)}
);
}