Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions apps/start/src/components/report-chart/bar/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function Chart({ data }: Props) {
const [sortBy, setSortBy] = useState<SortOption>('count-desc');
const {
isEditMode,
report: { metric, limit, previous },
report: { metric, limit, previous, options },
options: { onClick, dropdownMenuContent },
} = useReportChartContext();
const number = useNumber();
Expand Down Expand Up @@ -106,14 +106,16 @@ export function Chart({ data }: Props) {
});

// Apply limit if not in edit mode
return isEditMode ? sorted : sorted.slice(0, limit || 10);
const displayLimit = options?.type === 'bar' ? options.displayLimit : limit || 10;
return isEditMode ? sorted : sorted.slice(0, displayLimit);
}, [
seriesWithOriginalRank,
searchQuery,
sortBy,
totalSum,
isEditMode,
limit,
options,
]);

return (
Expand Down
35 changes: 35 additions & 0 deletions apps/start/src/components/report/sidebar/ReportSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
changeFunnelGroup,
changeFunnelWindow,
changeMetric,
changeOptions,
changePrevious,
changeSankeyExclude,
changeSankeyInclude,
Expand Down Expand Up @@ -68,6 +69,10 @@ export function ReportSettings() {
fields.push('sankeyInclude');
}

if (chartType === 'bar') {
fields.push('displayLimit');
}

if (chartType === 'histogram') {
fields.push('stacked');
}
Expand Down Expand Up @@ -99,6 +104,36 @@ export function ReportSettings() {
/>
</Label>
)}
{fields.includes('displayLimit') && (
<div className="flex items-center justify-between gap-4">
<Label
className="mb-0 whitespace-nowrap"
htmlFor="bar-display-limit"
>
Rows to display
</Label>
<InputEnter
id="bar-display-limit"
max={500}
min={1}
onChangeValue={(value) => {
const displayLimit = Number(value);
if (
Number.isInteger(displayLimit) &&
displayLimit >= 1 &&
displayLimit <= 500
) {
dispatch(changeOptions({ type: 'bar', displayLimit }));
}
}}
step={1}
type="number"
value={String(
options?.type === 'bar' ? options.displayLimit : 10
)}
/>
</div>
)}
{fields.includes('criteria') && (
<div className="flex items-center justify-between gap-4">
<Label className="whitespace-nowrap font-medium mb-0">
Expand Down
6 changes: 6 additions & 0 deletions packages/validation/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,17 @@ export const zHistogramOptions = z.object({
stacked: z.boolean().default(false),
});

export const zBarOptions = z.object({
type: z.literal('bar'),
displayLimit: z.number().int().min(1).max(500).default(10),
});

export const zReportOptions = z.discriminatedUnion('type', [
zFunnelOptions,
zRetentionOptions,
zSankeyOptions,
zHistogramOptions,
zBarOptions,
]);

export type IReportOptions = z.infer<typeof zReportOptions>;
Expand Down
31 changes: 31 additions & 0 deletions packages/validation/src/report-options.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { describe, expect, it } from 'vitest';
import { zReportOptions } from './index';

describe('bar report display options', () => {
it('retains the configured row count when validating a saved report', () => {
expect(zReportOptions.parse({ type: 'bar', displayLimit: 25 })).toEqual({
type: 'bar',
displayLimit: 25,
});
});

it('defaults to ten rows', () => {
expect(zReportOptions.parse({ type: 'bar' })).toEqual({
type: 'bar',
displayLimit: 10,
});
});

it.each([
0,
-1,
1.5,
501,
Number.POSITIVE_INFINITY,
Number.NaN,
])('rejects invalid row count %s', (displayLimit) => {
expect(
zReportOptions.safeParse({ type: 'bar', displayLimit }).success
).toBe(false);
});
});