♻️ Label table cell optimization

This commit is contained in:
Fred KISSIE
2026-06-03 19:15:44 +02:00
parent 6c1798a8c5
commit 97aeee541a
8 changed files with 191 additions and 189 deletions

View File

@@ -21,29 +21,32 @@ const MAX_VISIBLE_BEFORE_OVERFLOW = MAX_VISIBLE_LABELS - 1;
type TableLabelsCellProps = {
orgId: string;
localLabels: SelectedLabel[];
toggleLabel: (label: SelectedLabel, action: "attach" | "detach") => void;
selectedLabels: SelectedLabel[];
onToggleLabel: (label: SelectedLabel, action: "attach" | "detach") => void;
onClosePopover: () => void;
};
export function TableLabelsCell({
export function LabelsTableCell({
orgId,
localLabels,
toggleLabel
selectedLabels,
onToggleLabel,
onClosePopover
}: TableLabelsCellProps) {
const t = useTranslations();
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const triggerRef = useRef<HTMLButtonElement>(null);
const frozenAnchorRef = useRef<Measurable>({
getBoundingClientRect: () => new DOMRect()
});
const hasOverflow = localLabels.length > MAX_VISIBLE_LABELS;
const visibleLabels = localLabels.slice(
const hasOverflow = selectedLabels.length > MAX_VISIBLE_LABELS;
const visibleLabels = selectedLabels.slice(
0,
hasOverflow ? MAX_VISIBLE_BEFORE_OVERFLOW : MAX_VISIBLE_LABELS
);
const overflowLabels = hasOverflow
? localLabels.slice(MAX_VISIBLE_BEFORE_OVERFLOW)
? selectedLabels.slice(MAX_VISIBLE_BEFORE_OVERFLOW)
: [];
function handleOpenChange(open: boolean) {
@@ -54,10 +57,14 @@ export function TableLabelsCell({
};
}
setIsPopoverOpen(open);
if (!open) {
onClosePopover();
}
}
return (
<div className="grid w-full min-w-0 grid-cols-[auto_minmax(0,1fr)] items-center gap-1">
<div className="flex items-center gap-1">
<Popover open={isPopoverOpen} onOpenChange={handleOpenChange}>
<PopoverAnchor virtualRef={frozenAnchorRef} />
<PopoverTrigger asChild>
@@ -80,9 +87,8 @@ export function TableLabelsCell({
>
<LabelsSelector
orgId={orgId}
selectedLabels={localLabels}
toggleLabel={toggleLabel}
onClose={() => handleOpenChange(false)}
selectedLabels={selectedLabels}
toggleLabel={onToggleLabel}
/>
</PopoverContent>
</Popover>

View File

@@ -34,7 +34,7 @@ import { useDebouncedCallback } from "use-debounce";
import z from "zod";
import { ColumnFilterButton } from "./ColumnFilterButton";
import { type SelectedLabel } from "./labels-selector";
import { TableLabelsCell } from "./TableLabelsCell";
import { LabelsTableCell } from "./LabelsTableCell";
import { Badge } from "./ui/badge";
import { ControlledDataTable } from "./ui/controlled-data-table";
import { LabelColumnFilterButton } from "./LabelColumnFilterButton";
@@ -651,7 +651,7 @@ function MachineClientLabelCell({
}
return (
<TableLabelsCell
<LabelsTableCell
orgId={orgId}
localLabels={localLabels}
toggleLabel={toggleClientLabel}

View File

@@ -61,9 +61,10 @@ import { build } from "@server/build";
import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
import { type SelectedLabel } from "./labels-selector";
import { TableLabelsCell } from "./TableLabelsCell";
import { LabelsTableCell } from "./LabelsTableCell";
import { LabelColumnFilterButton } from "./LabelColumnFilterButton";
import { useLocalLabels } from "@app/hooks/useLocalLabels";
import { useOptimisticLabels } from "@app/hooks/useOptimisticLabels";
export type InternalResourceSiteRow = ResourceSiteRow;
@@ -705,54 +706,19 @@ function ClientResourceLabelCell({
resource,
orgId
}: ClientResourceLabelCellProps) {
const t = useTranslations();
const api = createApiClient(useEnvContext());
const [localLabels, setLocalLabels] = useLocalLabels(
resource.labels,
resource.id
);
function toggleResourceLabel(
label: SelectedLabel,
action: "attach" | "detach"
) {
const previousLabels = localLabels;
void (async () => {
try {
if (action === "attach") {
setLocalLabels([...previousLabels, label]);
await api.put(
`/org/${orgId}/label/${label.labelId}/attach`,
{ siteResourceId: resource.id }
);
} else {
setLocalLabels(
previousLabels.filter(
(lb) => lb.labelId !== label.labelId
)
);
await api.put(
`/org/${orgId}/label/${label.labelId}/detach`,
{ siteResourceId: resource.id }
);
}
} catch (e) {
setLocalLabels(previousLabels);
toast({
title: t("error"),
description: formatAxiosError(e, t("errorOccurred")),
variant: "destructive"
});
}
})();
}
const { localLabels, refresh, toggleLabel } = useOptimisticLabels({
serverLabels: resource.labels,
orgId,
entityId: resource.id,
entityIdField: "siteResourceId"
});
return (
<TableLabelsCell
<LabelsTableCell
orgId={orgId}
localLabels={localLabels}
toggleLabel={toggleResourceLabel}
onClosePopover={() => startTransition(refresh)}
onToggleLabel={toggleLabel}
selectedLabels={localLabels}
/>
);
}

View File

@@ -73,7 +73,9 @@ import UptimeMiniBar from "./UptimeMiniBar";
import { type SelectedLabel } from "./labels-selector";
import { LabelColumnFilterButton } from "./LabelColumnFilterButton";
import { useLocalLabels } from "@app/hooks/useLocalLabels";
import { TableLabelsCell } from "./TableLabelsCell";
import { LabelsTableCell } from "./LabelsTableCell";
import { useOptimisticLabels } from "@app/hooks/useOptimisticLabels";
import { refresh } from "next/cache";
export type TargetHealth = {
targetId: number;
@@ -772,57 +774,19 @@ type ResourceLabelCellProps = {
};
function ResourceLabelCell({ resource, orgId }: ResourceLabelCellProps) {
const t = useTranslations();
const api = createApiClient(useEnvContext());
const [localLabels, setLocalLabels] = useLocalLabels(
resource.labels,
resource.id
);
function toggleSiteLabel(
label: SelectedLabel,
action: "attach" | "detach"
) {
const previousLabels = localLabels;
void (async () => {
try {
if (action === "attach") {
setLocalLabels([...previousLabels, label]);
await api.put(
`/org/${orgId}/label/${label.labelId}/attach`,
{ resourceId: resource.id }
);
} else {
setLocalLabels(
previousLabels.filter(
(lb) => lb.labelId !== label.labelId
)
);
await api.put(
`/org/${orgId}/label/${label.labelId}/detach`,
{ resourceId: resource.id }
);
}
} catch (e) {
setLocalLabels(previousLabels);
toast({
title: t("error"),
description: formatAxiosError(e, t("errorOccurred")),
variant: "destructive"
});
}
})();
}
const { localLabels, refresh, toggleLabel } = useOptimisticLabels({
serverLabels: resource.labels,
orgId,
entityId: resource.id,
entityIdField: "resourceId"
});
return (
<TableLabelsCell
<LabelsTableCell
orgId={orgId}
localLabels={localLabels}
toggleLabel={toggleSiteLabel}
selectedLabels={localLabels}
onToggleLabel={toggleLabel}
onClosePopover={() => startTransition(refresh)}
/>
);
}

View File

@@ -41,13 +41,7 @@ import {
import { useTranslations } from "next-intl";
import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import {
startTransition,
useEffect,
useMemo,
useState,
useTransition
} from "react";
import { startTransition, useMemo, useState, useTransition } from "react";
import { useDebouncedCallback } from "use-debounce";
import z from "zod";
import { ColumnFilterButton } from "./ColumnFilterButton";
@@ -56,13 +50,11 @@ import {
type ExtendedColumnDef
} from "./ui/controlled-data-table";
import { useOptimisticLabels } from "@app/hooks/useOptimisticLabels";
import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { cn } from "@app/lib/cn";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
import { type SelectedLabel } from "./labels-selector";
import { LabelColumnFilterButton } from "./LabelColumnFilterButton";
import { useLocalLabels } from "@app/hooks/useLocalLabels";
import { TableLabelsCell } from "./TableLabelsCell";
import { LabelsTableCell } from "./LabelsTableCell";
export type SiteRow = {
id: number;
@@ -686,54 +678,19 @@ type SiteLabelCellProps = {
};
function SiteLabelCell({ site, orgId }: SiteLabelCellProps) {
const t = useTranslations();
const api = createApiClient(useEnvContext());
const [localLabels, setLocalLabels] = useLocalLabels(site.labels, site.id);
function toggleSiteLabel(
label: SelectedLabel,
action: "attach" | "detach"
) {
const previousLabels = localLabels;
void (async () => {
try {
if (action === "attach") {
setLocalLabels([...previousLabels, label]);
await api.put(
`/org/${orgId}/label/${label.labelId}/attach`,
{ siteId: site.id }
);
} else {
setLocalLabels(
previousLabels.filter(
(lb) => lb.labelId !== label.labelId
)
);
await api.put(
`/org/${orgId}/label/${label.labelId}/detach`,
{ siteId: site.id }
);
}
} catch (e) {
setLocalLabels(previousLabels);
toast({
title: t("error"),
description: formatAxiosError(e, t("errorOccurred")),
variant: "destructive"
});
}
})();
}
const { localLabels, refresh, toggleLabel } = useOptimisticLabels({
serverLabels: site.labels,
orgId,
entityId: site.id,
entityIdField: "siteId"
});
return (
<TableLabelsCell
<LabelsTableCell
orgId={orgId}
localLabels={localLabels}
toggleLabel={toggleSiteLabel}
selectedLabels={localLabels}
onToggleLabel={toggleLabel}
onClosePopover={() => startTransition(refresh)}
/>
);
}

View File

@@ -36,7 +36,6 @@ export type LabelsSelectorProps = {
orgId: string;
selectedLabels: SelectedLabel[];
toggleLabel: (newlabel: SelectedLabel, action: "detach" | "attach") => void;
onClose?: () => void;
};
export const LABEL_COLORS = {
@@ -52,8 +51,7 @@ export const LABEL_COLORS = {
export function LabelsSelector({
orgId,
selectedLabels,
toggleLabel,
onClose
toggleLabel
}: LabelsSelectorProps) {
const t = useTranslations();
const [labelSearchQuery, setlabelsSearchQuery] = useState("");
@@ -202,7 +200,6 @@ export function LabelsSelector({
? "detach"
: "attach"
);
onClose?.();
}}
>
<Checkbox