Skip to content

Commit 1916d68

Browse files
committed
helper mapValues and using max height for table
1 parent b862a21 commit 1916d68

File tree

2 files changed

+24
-26
lines changed

2 files changed

+24
-26
lines changed

components/SponsoredFeedsTable.tsx

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useState } from "react";
22
import CopyIcon from "./icons/CopyIcon";
3+
import { mapValues } from "../utils/ObjectHelpers";
34

45
interface SponsoredFeed {
56
name: string;
@@ -26,25 +27,16 @@ export const SponsoredFeedsTable = ({
2627
};
2728

2829
// Calculate parameter statistics
29-
const paramCounts = feeds.reduce((acc, feed) => {
30-
acc[feed.updateParameters] = (acc[feed.updateParameters] || 0) + 1;
31-
return acc;
32-
}, {} as Record<string, number>);
30+
const paramCounts = mapValues(
31+
Object.groupBy(feeds, (feed) => feed.updateParameters),
32+
(feeds: SponsoredFeed[]) => feeds.length
33+
);
3334

3435
const defaultParams = Object.entries(paramCounts).sort(
3536
([, a], [, b]) => b - a
3637
)[0][0];
3738

38-
// Calculate table height based on number of items
39-
// Each row is approximately 40px (py-2 = 8px top + 8px bottom + content height)
40-
// Header is approximately 48px (py-2 = 8px top + 8px bottom + font height)
41-
// Show 7 rows by default, then scroll - but maintain consistent minimum height
42-
const maxVisibleRows = 7;
43-
const shouldScroll = feeds.length > maxVisibleRows;
44-
const rowHeight = 56; // Increased row height to account for actual content height
45-
const headerHeight = 48; // Header height in pixels
46-
const exactTableHeight = `${headerHeight + maxVisibleRows * rowHeight}px`; // Exact height for 7 rows
47-
const tableHeight = shouldScroll ? exactTableHeight : "auto"; // Use exact height for scrollable tables
39+
// CSS max-h-96 will handle scrolling automatically
4840

4941
return (
5042
<div className="my-6">
@@ -88,10 +80,7 @@ export const SponsoredFeedsTable = ({
8880

8981
{/* Table */}
9082
<div className="overflow-x-auto">
91-
<div
92-
className={`${shouldScroll ? "overflow-y-auto" : ""}`}
93-
style={{ height: tableHeight }}
94-
>
83+
<div className="overflow-y-auto max-h-96">
9584
<table className="w-full text-sm min-w-full">
9685
<thead className="sticky top-0 bg-gray-50 dark:bg-gray-800 z-30">
9786
<tr>
@@ -181,14 +170,6 @@ export const SponsoredFeedsTable = ({
181170
</table>
182171
</div>
183172
</div>
184-
185-
{/* Show count indicator when scrolling is needed */}
186-
{shouldScroll && (
187-
<div className="px-3 py-1 bg-gray-50 dark:bg-gray-800 border-t border-gray-200 dark:border-gray-600 text-xs text-gray-500 text-center">
188-
Showing {maxVisibleRows} of {feeds.length} feeds • Scroll to see
189-
more
190-
</div>
191-
)}
192173
</div>
193174
</div>
194175
);

utils/ObjectHelpers.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Maps over object values while preserving keys, similar to Array.map but for objects.
3+
* Handles both regular objects and Partial objects (like Object.groupBy results).
4+
* Filters out undefined values automatically.
5+
*/
6+
export function mapValues<T, U>(
7+
obj: Record<string, T> | Partial<Record<string, T>>,
8+
fn: (value: T, key: string) => U
9+
): Record<string, U> {
10+
const result: Record<string, U> = {};
11+
for (const [key, value] of Object.entries(obj)) {
12+
if (value !== undefined) {
13+
result[key] = fn(value, key);
14+
}
15+
}
16+
return result;
17+
}

0 commit comments

Comments
 (0)