124 lines · 4.3 KB · TypeScript
RawDownload
import type { EnvironmentId, UsageLimitsReport } from "@t3tools/contracts";import { limitsNotice } from "@t3tools/shared/usageLimits";import { GaugeIcon } from "lucide-react"; import { getDriverOption } from "../settings/providerDriverMeta";import { RedactedSensitiveText } from "../settings/RedactedSensitiveText";import { LimitWindows, ResetCredits } from "../usage/UsageLimits";import { ComposerBanner } from "./ComposerBanner";import type { ComposerBannerStackItem } from "./ComposerBannerStack"; /** Driver name, then the instance when there could be more than one of that driver. */function accountLabel(account: UsageLimitsReport["accounts"][number]): string {  if (!account.instanceId) return account.label;  const driver = getDriverOption(account.driver)?.label ?? String(account.driver);  const instance =    account.displayName?.trim() ||    (String(account.instanceId) !== String(account.driver) ? account.instanceId : "");  // The default instance is often named after its driver; saying it twice adds nothing.  return instance && instance.toLowerCase() !== driver.toLowerCase()    ? `${driver} · ${instance}`    : driver;} function AccountSummary({ account }: { readonly account: UsageLimitsReport["accounts"][number] }) {  const label = accountLabel(account);  return (    <>      {label.includes("@") ? (        <RedactedSensitiveText          key={label}          value={label}          ariaLabel="Toggle account label visibility"          revealTooltip="Click to reveal account"          hideTooltip="Click to hide account"          className="max-w-full truncate align-bottom font-sans text-xs leading-normal"        />      ) : (        label      )}      {account.plan ? ` · ${account.plan}` : null}    </>  );} /** The /usage-limits result as a composer notice: it stacks under warnings and dismisses like one. */export function usageLimitsBannerItem(  id: string,  report: UsageLimitsReport,  environmentId: EnvironmentId,  onDismiss: () => void,): ComposerBannerStackItem {  const [first] = report.accounts;  const single = report.accounts.length === 1 && first ? first : null;  const summary = single ? (    <AccountSummary account={single} />  ) : (    `${report.accounts.length} accounts`  );  return {    id,    variant: "info",    priority: "notice",    icon: <GaugeIcon />,    title: "Usage limits",    description: summary,    dismissLabel: "Dismiss usage limits",    onDismiss,    children: <UsageLimitsBannerBody report={report} environmentId={environmentId} />,  };} function UsageLimitsBannerBody({  report,  environmentId,}: {  readonly report: UsageLimitsReport;  readonly environmentId: EnvironmentId;}) {  const now = Date.parse(report.createdAt);  return (    <ComposerBanner.Scroll>      <ComposerBanner.Body className="flex flex-col gap-2 pt-1 pb-1.5 pe-2">        {report.accounts.map((account) => {          const resetCreditInput =            account.resetCreditInput ??            (account.instanceId ? { instanceId: account.instanceId } : undefined);          const notice = limitsNotice(account.limits);          return (            <div key={account.id} className="flex min-w-0 flex-col gap-1">              {report.accounts.length > 1 ? (                <span className="truncate text-xs text-muted-foreground">                  <AccountSummary account={account} />                </span>              ) : null}              {notice ? (                <span className="text-xs text-muted-foreground">{notice}</span>              ) : (                <LimitWindows                  compact                  driver={account.driver}                  windows={account.limits.windows}                  now={now}                />              )}              {resetCreditInput && account.limits.resetCredits ? (                <ResetCredits                  environmentId={environmentId}                  input={resetCreditInput}                  credits={account.limits.resetCredits}                  now={now}                />              ) : null}            </div>          );        })}        {report.notices.map((notice) => (          <span key={notice} className="text-xs text-muted-foreground">            {notice}          </span>        ))}      </ComposerBanner.Body>    </ComposerBanner.Scroll>  );}