diff --git a/apps/webapp/app/components/billing/ConcurrentRunsChart.tsx b/apps/webapp/app/components/billing/ConcurrentRunsChart.tsx
index 5b9f335bf..060a85473 100644
--- a/apps/webapp/app/components/billing/ConcurrentRunsChart.tsx
+++ b/apps/webapp/app/components/billing/ConcurrentRunsChart.tsx
@@ -22,13 +22,20 @@ const tooltipStyle = {
color: "#E2E8F0",
};
+type DataItem = { date: Date; maxConcurrentRuns: number };
+
+const dateFormatter = new Intl.DateTimeFormat("en-US", {
+ month: "short",
+ day: "numeric",
+});
+
export function ConcurrentRunsChart({
concurrentRunsLimit,
data,
hasConcurrencyData,
}: {
concurrentRunsLimit?: number;
- data: { name: string; maxConcurrentRuns: number }[];
+ data: DataItem[];
hasConcurrencyData: boolean;
}) {
return (
@@ -54,13 +61,28 @@ export function ConcurrentRunsChart({
fontSize={12}
tickLine={false}
axisLine={false}
- dataKey="name"
+ dataKey={(item: DataItem) => {
+ if (item.date.getDate() === 1) {
+ return dateFormatter.format(item.date);
+ }
+ return `${item.date.getDate()}`;
+ }}
className="text-xs"
>
-
+ {
+ const date = data.at(0)?.payload.date;
+ if (!date) {
+ return "";
+ }
+ return dateFormatter.format(date);
+ }}
+ />
{concurrentRunsLimit && (
) {
- const outputData: Array<{ name: string; maxConcurrentRuns: number }> = [];
+ const outputData: Array<{ date: Date; maxConcurrentRuns: number }> = [];
for (let i = 0; i < days; i++) {
const date = new Date(startDate);
date.setDate(date.getDate() + i);
- let formattedDate = `${date.getDate()}`;
- if (date.getDate() === 1) {
- formattedDate = dateFormatter.format(date);
- }
-
const foundData = data.find((d) => d.day.toISOString() === date.toISOString());
if (!foundData) {
outputData.push({
- name: formattedDate,
+ date,
maxConcurrentRuns: 0,
});
} else {
outputData.push({
- name: formattedDate,
+ date,
maxConcurrentRuns: Number(foundData.max_concurrent_runs),
});
}
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.billing._index/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.billing._index/route.tsx
index f041f752a..552d3b67a 100644
--- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.billing._index/route.tsx
+++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.billing._index/route.tsx
@@ -1,6 +1,5 @@
import { ArrowRightIcon } from "@heroicons/react/20/solid";
import { ArrowUpCircleIcon } from "@heroicons/react/24/outline";
-import { SquaresPlusIcon, UsersIcon, WrenchScrewdriverIcon } from "@heroicons/react/24/solid";
import { LoaderFunctionArgs } from "@remix-run/server-runtime";
import { Bar, BarChart, ResponsiveContainer, Tooltip, TooltipProps, XAxis, YAxis } from "recharts";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
@@ -9,16 +8,13 @@ import { UsageBar } from "~/components/billing/UsageBar";
import { LinkButton } from "~/components/primitives/Buttons";
import { Callout } from "~/components/primitives/Callout";
import { Header2, Header3 } from "~/components/primitives/Headers";
-import { NamedIcon } from "~/components/primitives/NamedIcon";
import { Paragraph } from "~/components/primitives/Paragraph";
-import { TextLink } from "~/components/primitives/TextLink";
import { useOrganization } from "~/hooks/useOrganizations";
import { OrgUsagePresenter } from "~/presenters/OrgUsagePresenter.server";
import { requireUserId } from "~/services/session.server";
-import { OrganizationParamsSchema, plansPath, organizationTeamPath } from "~/utils/pathBuilder";
-import { useCurrentPlan } from "../_app.orgs.$organizationSlug/route";
-import { estimate } from "@trigger.dev/billing";
import { formatCurrency, formatNumberCompact } from "~/utils/numberFormatter";
+import { OrganizationParamsSchema, plansPath } from "~/utils/pathBuilder";
+import { useCurrentPlan } from "../_app.orgs.$organizationSlug/route";
export async function loader({ params, request }: LoaderFunctionArgs) {
const userId = await requireUserId(request);