Skip to content
Draft
33 changes: 26 additions & 7 deletions static/app/views/explore/metrics/hooks/useStableLabels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,35 @@ function parseEquationIndex(label: string): number {
*/
export function useStableLabels(queries: BaseMetricQuery[]) {
const labelsRef = useRef<string[]>([]);
const rowIdsRef = useRef<string[]>([]);

// oxlint-disable-next-line react/refs
if (labelsRef.current.length !== queries.length) {
// oxlint-disable-next-line react/refs
labelsRef.current = assignSequentialLabels(queries);
// oxlint-disable-next-line react/refs
rowIdsRef.current = createRowIds(queries.length);
}

return useMemo(
() => ({
getLabel(i: number): string {
return labelsRef.current[i] ?? getFunctionLabel(i);
},
/**
* Unique per row and moved along with its label, unlike labels, which
* can repeat after an external navigation that keeps the row count.
*/
getRowIds(): readonly string[] {
return rowIdsRef.current;
},
insert(position: number, label: string) {
labelsRef.current = labelsRef.current.toSpliced(position, 0, label);
rowIdsRef.current = rowIdsRef.current.toSpliced(position, 0, ...createRowIds(1));
},
remove(position: number) {
labelsRef.current = labelsRef.current.filter((_, j) => j !== position);
rowIdsRef.current = rowIdsRef.current.filter((_, j) => j !== position);
},
move(from: number, to: number) {
if (
Expand All @@ -106,15 +118,22 @@ export function useStableLabels(queries: BaseMetricQuery[]) {
return;
}

const next = [...labelsRef.current];
const [label] = next.splice(from, 1);
if (!label) {
return;
}
next.splice(to, 0, label);
labelsRef.current = next;
labelsRef.current = moveItem(labelsRef.current, from, to);
rowIdsRef.current = moveItem(rowIdsRef.current, from, to);
},
}),
[]
);
}

function moveItem<T>(items: readonly T[], from: number, to: number): T[] {
const next = [...items];
next.splice(to, 0, ...next.splice(from, 1));
return next;
}

let nextRowId = 0;

function createRowIds(count: number): string[] {
return Array.from({length: count}, () => String(nextRowId++));
}
Loading
Loading