chore(repo): checkpoint current capakraken implementation state
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { trpc } from "~/lib/trpc/client.js";
|
||||
import type { WidgetProps } from "~/components/dashboard/widget-registry.js";
|
||||
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";
|
||||
import { useWidgetFilterOptions } from "~/hooks/useWidgetFilterOptions.js";
|
||||
|
||||
interface ResourceRow {
|
||||
id: string;
|
||||
@@ -29,8 +30,7 @@ export function ResourceTableWidget({ config, onConfigChange }: WidgetProps) {
|
||||
{ staleTime: 60_000 },
|
||||
);
|
||||
|
||||
const { data: chapterData } = trpc.resource.chapters.useQuery(undefined, { staleTime: 120_000 });
|
||||
const chapters = chapterData ?? [];
|
||||
const { chapters } = useWidgetFilterOptions({ chapters: true });
|
||||
|
||||
type SortKey = "eid" | "name" | "chapter" | "bookings" | "utilization" | "target";
|
||||
const [sortKey, setSortKey] = useState<SortKey>("name");
|
||||
@@ -44,6 +44,32 @@ export function ResourceTableWidget({ config, onConfigChange }: WidgetProps) {
|
||||
}
|
||||
}
|
||||
|
||||
const list = useMemo(() => (resources ?? []) as unknown as ResourceRow[], [resources]);
|
||||
|
||||
const sorted = useMemo(() => {
|
||||
const next = [...list];
|
||||
next.sort((a, b) => {
|
||||
const mult = sortDir === "asc" ? 1 : -1;
|
||||
switch (sortKey) {
|
||||
case "eid":
|
||||
return mult * a.eid.localeCompare(b.eid);
|
||||
case "name":
|
||||
return mult * a.displayName.localeCompare(b.displayName);
|
||||
case "chapter":
|
||||
return mult * (a.chapter ?? "").localeCompare(b.chapter ?? "");
|
||||
case "bookings":
|
||||
return mult * (a.bookingCount - b.bookingCount);
|
||||
case "utilization":
|
||||
return mult * (a.utilizationPercent - b.utilizationPercent);
|
||||
case "target":
|
||||
return mult * (a.chargeabilityTarget - b.chargeabilityTarget);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
return next;
|
||||
}, [list, sortDir, sortKey]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex flex-col gap-2 pt-1">
|
||||
@@ -74,28 +100,6 @@ export function ResourceTableWidget({ config, onConfigChange }: WidgetProps) {
|
||||
);
|
||||
}
|
||||
|
||||
const list = (resources ?? []) as unknown as ResourceRow[];
|
||||
|
||||
const sorted = [...list].sort((a, b) => {
|
||||
const mult = sortDir === "asc" ? 1 : -1;
|
||||
switch (sortKey) {
|
||||
case "eid":
|
||||
return mult * a.eid.localeCompare(b.eid);
|
||||
case "name":
|
||||
return mult * a.displayName.localeCompare(b.displayName);
|
||||
case "chapter":
|
||||
return mult * (a.chapter ?? "").localeCompare(b.chapter ?? "");
|
||||
case "bookings":
|
||||
return mult * (a.bookingCount - b.bookingCount);
|
||||
case "utilization":
|
||||
return mult * (a.utilizationPercent - b.utilizationPercent);
|
||||
case "target":
|
||||
return mult * (a.chargeabilityTarget - b.chargeabilityTarget);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full gap-3">
|
||||
{/* Filter */}
|
||||
@@ -107,9 +111,9 @@ export function ResourceTableWidget({ config, onConfigChange }: WidgetProps) {
|
||||
className="app-select w-44 text-xs"
|
||||
>
|
||||
<option value="">All Chapters</option>
|
||||
{chapters.map((c) => (
|
||||
<option key={c} value={c}>
|
||||
{c}
|
||||
{chapters.map((chapterOption) => (
|
||||
<option key={chapterOption.value} value={chapterOption.value}>
|
||||
{chapterOption.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
Reference in New Issue
Block a user