diff --git a/src/components/charts/Chart.tsx b/src/components/charts/Chart.tsx index 0285cf943..d3775bf40 100644 --- a/src/components/charts/Chart.tsx +++ b/src/components/charts/Chart.tsx @@ -13,7 +13,7 @@ ChartJS.defaults.font.family = 'Inter'; export interface ChartProps extends BoxProps { type?: 'bar' | 'bubble' | 'doughnut' | 'pie' | 'line' | 'polarArea' | 'radar' | 'scatter'; - chartData?: ChartData & { focusLabel?: string }; + chartData?: ChartData & { focusLabel?: string }; chartOptions?: ChartOptions; updateMode?: UpdateMode; animationDuration?: number; @@ -66,8 +66,6 @@ export function Chart({ const handleLegendClick = (item: LegendItem) => { if (onLegendClick && type === 'bar') { - // Controlled mode: caller owns the hidden state. We report the click - // and let the parent push a new hiddenLabels set on the next render. const { datasetIndex } = item; const ds = chart.current.data.datasets[datasetIndex]; onLegendClick(ds.label, !hiddenLabels?.has(ds.label)); @@ -124,16 +122,11 @@ export function Chart({ }); } - // Re-apply caller-driven hidden flags after focusLabel handling so a - // dataset stays hidden across data changes (e.g. date-range switches) - // even though Chart.js regenerates dataset meta on every replace. if (hiddenLabels) { chart.current.data.datasets.forEach((ds: { hidden: boolean; label: any }) => { if (hiddenLabels.has(ds.label)) { ds.hidden = true; } else if (!chartData.focusLabel) { - // Explicitly reset so un-hiding a label is always reflected, - // regardless of whether the focusLabel pass ran above. ds.hidden = false; } }); diff --git a/src/components/charts/PieChart.tsx b/src/components/charts/PieChart.tsx index 2470fe77e..736e39c19 100644 --- a/src/components/charts/PieChart.tsx +++ b/src/components/charts/PieChart.tsx @@ -6,7 +6,7 @@ export interface PieChartProps extends ChartProps { type?: 'doughnut' | 'pie'; } -export function PieChart({ type = 'pie', ...props }: PieChartProps) { +export function PieChart({ type = 'pie', height = '300px', ...props }: PieChartProps) { const [tooltip, setTooltip] = useState(null); const handleTooltip = ({ tooltip }) => { @@ -24,7 +24,7 @@ export function PieChart({ type = 'pie', ...props }: PieChartProps) { return ( <> - + {tooltip && } ); diff --git a/src/components/common/DataGrid.tsx b/src/components/common/DataGrid.tsx index 1ed872e9e..508f5a402 100644 --- a/src/components/common/DataGrid.tsx +++ b/src/components/common/DataGrid.tsx @@ -58,16 +58,11 @@ export function DataGrid({ const showPager = allowPaging && data && data.count > 0; const { isMobile } = useMobile(); const [userDisplayMode, setUserDisplayMode] = useState(() => { - // localStorage can hold anything (extensions, manual edits, schema drift), - // so accept only the two values we know how to render and otherwise fall - // back to the useMobile-driven default. const stored = getItem(DISPLAY_MODE_STORAGE_KEY); return stored === 'table' || stored === 'cards' ? stored : null; }); - // Effective mode: explicit user choice wins, otherwise fall back to the - // mobile-driven default (cards on small viewports, table elsewhere). - const displayMode: DisplayMode | undefined = userDisplayMode ?? (isMobile ? 'cards' : undefined); + const displayMode: DisplayMode | undefined = isMobile ? 'cards' : userDisplayMode ?? undefined; const handleToggleDisplayMode = () => { const next: DisplayMode = displayMode === 'cards' ? 'table' : 'cards'; @@ -116,7 +111,7 @@ export function DataGrid({ )} {renderActions?.()} - {viewToggleButton} + {!isMobile && viewToggleButton} = {}; const used = new Set(); const hashOf = Object.fromEntries( diff --git a/src/lib/ip.ts b/src/lib/ip.ts index 08e77c65e..075a481f5 100644 --- a/src/lib/ip.ts +++ b/src/lib/ip.ts @@ -16,11 +16,6 @@ export const IP_ADDRESS_HEADERS = [ 'x-forwarded', ]; -/** - * Normalize IP strings to a canonical form: - * - strips IPv4-mapped IPv6 (e.g. ::ffff:192.0.2.1 -> 192.0.2.1) - * - keeps valid IPv4/IPv6 as-is (canonically formatted by ipaddr.js) - */ function normalizeIp(ip?: string | null) { if (!ip) return ip; diff --git a/src/queries/prisma/user.ts b/src/queries/prisma/user.ts index 56706be80..905c3f6b2 100644 --- a/src/queries/prisma/user.ts +++ b/src/queries/prisma/user.ts @@ -130,9 +130,6 @@ export async function deleteUser(userId: string) { const teamIds = teams.map(a => a.id); - // Cloud mode keeps owned teams (and their team-owned content), so cleanup - // only covers user-direct rows. Non-cloud hard-deletes owned teams below, - // so we must also clean up team-owned content. const ownedFilter = cloudMode ? { userId } : { OR: [{ userId }, { teamId: { in: teamIds } }] };