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
7 changes: 7 additions & 0 deletions .changeset/table-tile-alternate-row-external-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@hyperdx/api": patch
---

feat(api): expose table tile alternate row background in the external Dashboards API

Add the optional `alternateRowBackground` boolean to the external REST Dashboards API for both builder and raw SQL table charts, matching the display setting available in the app. When true, the table tile renders alternating row background colors (zebra striping) for easier scanning on wide tables; it defaults to false.
12 changes: 12 additions & 0 deletions packages/api/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1767,6 +1767,12 @@
"default": false,
"example": false
},
"alternateRowBackground": {
"type": "boolean",
"description": "When true, apply alternating row background colors (zebra striping) to improve readability of wide tables. Defaults to false.\n",
"default": false,
"example": false
},
"onClick": {
"$ref": "#/components/schemas/OnClick",
"description": "Optional link-out configuration applied when a user clicks a row."
Expand Down Expand Up @@ -2259,6 +2265,12 @@
"description": "Display as a table chart.",
"example": "table"
},
"alternateRowBackground": {
"type": "boolean",
"description": "When true, apply alternating row background colors (zebra striping) to improve readability of wide tables. Defaults to false.\n",
"default": false,
"example": false
},
"onClick": {
"$ref": "#/components/schemas/OnClick",
"description": "Optional link-out configuration applied when a user clicks a row."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2355,6 +2355,7 @@ describe('External API v2 Dashboards - new format', () => {
average: true,
},
groupByColumnsOnLeft: true,
alternateRowBackground: true,
onClick: {
type: 'search',
target: {
Expand Down Expand Up @@ -2625,6 +2626,65 @@ describe('External API v2 Dashboards - new format', () => {
expect(response.body.data.tiles[0].config).not.toHaveProperty('orderBy');
});

it('omits alternateRowBackground on a table tile when not provided, and persists explicit false', async () => {
const tableNoStripe: ExternalDashboardTile = {
name: 'Table without stripe setting',
x: 0,
y: 0,
w: 6,
h: 3,
config: {
displayType: 'table',
sourceId: traceSource._id.toString(),
select: [
{
aggFn: 'count',
alias: 'Count',
where: '',
whereLanguage: 'sql',
},
],
groupBy: 'ServiceName',
},
};

const tableStripeOff: ExternalDashboardTile = {
name: 'Table with stripe explicitly off',
x: 6,
y: 0,
w: 6,
h: 3,
config: {
displayType: 'table',
sourceId: traceSource._id.toString(),
select: [
{
aggFn: 'count',
alias: 'Count',
where: '',
whereLanguage: 'sql',
},
],
groupBy: 'ServiceName',
alternateRowBackground: false,
},
};

const response = await authRequest('post', BASE_URL)
.send({
name: 'Dashboard table stripe defaults',
tiles: [tableNoStripe, tableStripeOff],
})
.expect(200);

expect(response.body.data.tiles[0].config).not.toHaveProperty(
'alternateRowBackground',
);
expect(response.body.data.tiles[1].config.alternateRowBackground).toBe(
false,
);
});

// Schema-level rejections that exercise pure Zod constraints
// (discriminated-union absence, `min(1)` on valueExpression, and
// `length(1)` on the select array). The non-Trace-source case
Expand Down Expand Up @@ -2945,6 +3005,7 @@ describe('External API v2 Dashboards - new format', () => {
sqlTemplate,
sourceId,
numberFormat: { output: 'percent', mantissa: 1 },
alternateRowBackground: true,
onClick: {
type: 'search',
target: {
Expand Down Expand Up @@ -4080,6 +4141,7 @@ describe('External API v2 Dashboards - new format', () => {
average: true,
},
groupByColumnsOnLeft: true,
alternateRowBackground: true,
onClick: {
type: 'search',
target: {
Expand Down Expand Up @@ -4308,6 +4370,7 @@ describe('External API v2 Dashboards - new format', () => {
sqlTemplate,
sourceId,
numberFormat: { output: 'percent', mantissa: 1 },
alternateRowBackground: true,
onClick: {
type: 'dashboard',
target: {
Expand Down
14 changes: 14 additions & 0 deletions packages/api/src/routers/external-api/v2/dashboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,13 @@ const EXTERNAL_DASHBOARD_PROJECTION = {
* in the table. Defaults to false (Group By columns on the right).
* default: false
* example: false
* alternateRowBackground:
* type: boolean
* description: >
* When true, apply alternating row background colors (zebra striping)
* to improve readability of wide tables. Defaults to false.
* default: false
* example: false
* onClick:
* $ref: '#/components/schemas/OnClick'
* description: Optional link-out configuration applied when a user clicks a row.
Expand Down Expand Up @@ -1139,6 +1146,13 @@ const EXTERNAL_DASHBOARD_PROJECTION = {
* enum: [table]
* description: Display as a table chart.
* example: "table"
* alternateRowBackground:
* type: boolean
* description: >
* When true, apply alternating row background colors (zebra
* striping) to improve readability of wide tables. Defaults to false.
* default: false
* example: false
* onClick:
* $ref: '#/components/schemas/OnClick'
* description: Optional link-out configuration applied when a user clicks a row.
Expand Down
10 changes: 10 additions & 0 deletions packages/api/src/routers/external-api/v2/utils/dashboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ const convertToExternalTileChartConfig = (
sqlTemplate: config.sqlTemplate,
sourceId: config.source,
numberFormat: config.numberFormat,
alternateRowBackground: config.alternateRowBackground,
onClick: config.onClick,
};
case DisplayType.Number:
Expand Down Expand Up @@ -372,6 +373,7 @@ const convertToExternalTileChartConfig = (
'having',
'numberFormat',
'groupByColumnsOnLeft',
'alternateRowBackground',
'onClick',
]),
displayType: config.displayType,
Expand Down Expand Up @@ -666,6 +668,13 @@ export function convertToInternalTileConfig(
externalConfig.displayType === 'table'
? externalConfig.onClick
: undefined,
// Zebra striping is a table-only presentational flag that lives on
// the shared raw SQL config; only table tiles honor it, mirroring
// onClick above. `_.omitBy(_.isNil)` below drops it for other types.
alternateRowBackground:
externalConfig.displayType === 'table'
? externalConfig.alternateRowBackground
: undefined,
// Only the raw SQL number variant carries `color`; table and pie
// do not expose it. `_.omitBy(_.isNil)` below drops it when absent.
color:
Expand Down Expand Up @@ -714,6 +723,7 @@ export function convertToInternalTileConfig(
'having',
'orderBy',
'groupByColumnsOnLeft',
'alternateRowBackground',
'onClick',
]),
displayType: DisplayType.Table,
Expand Down
2 changes: 2 additions & 0 deletions packages/api/src/utils/zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,14 @@ const externalDashboardTableChartConfigSchema = z.object({
asRatio: z.boolean().optional(),
numberFormat: NumberFormatSchema.optional(),
groupByColumnsOnLeft: z.boolean().optional(),
alternateRowBackground: z.boolean().optional(),
onClick: externalOnClickSchema.optional(),
});

const externalDashboardTableRawSqlChartConfigSchema =
externalDashboardRawSqlChartConfigBaseSchema.extend({
displayType: z.literal('table'),
alternateRowBackground: z.boolean().optional(),
onClick: externalOnClickSchema.optional(),
});

Expand Down
Loading