Skip to content
Draft
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
18 changes: 18 additions & 0 deletions packages/api/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -2011,6 +2011,12 @@
"maxLength": 1024,
"example": "Service Overview"
},
"description": {
"type": "string",
"description": "Optional description of the dashboard",
"maxLength": 40000,
"example": "Monitors key service health metrics including latency and error rates"
},
"tiles": {
"type": "array",
"description": "List of tiles/charts in the dashboard",
Expand Down Expand Up @@ -2073,6 +2079,12 @@
"description": "Dashboard name.",
"example": "New Dashboard"
},
"description": {
"type": "string",
"maxLength": 40000,
"description": "Optional description of the dashboard.",
"example": "Monitors key service health metrics"
},
"tiles": {
"type": "array",
"description": "List of tiles/charts to include in the dashboard.",
Expand Down Expand Up @@ -2134,6 +2146,12 @@
"description": "Dashboard name.",
"example": "Updated Dashboard Name"
},
"description": {
"type": "string",
"maxLength": 40000,
"description": "Optional description of the dashboard.",
"example": "Updated description for this dashboard"
},
"tiles": {
"type": "array",
"items": {
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/mcp/tools/dashboards/getDashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function registerGetDashboard(
const output = dashboards.map(d => ({
id: d._id.toString(),
name: d.name,
...(d.description ? { description: d.description } : {}),
tags: d.tags,
...(frontendUrl ? { url: `${frontendUrl}/dashboards/${d._id}` } : {}),
}));
Expand Down
28 changes: 27 additions & 1 deletion packages/api/src/mcp/tools/dashboards/saveDashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,31 @@ export function registerSaveDashboard(
'Dashboard ID. Omit to create a new dashboard, provide to update an existing one.',
),
name: z.string().describe('Dashboard name'),
description: z
.string()
.max(40000)
.optional()
.describe('Optional description of the dashboard'),
tiles: mcpTilesParam,
tags: z.array(z.string()).optional().describe('Dashboard tags'),
}),
},
withToolTracing(
'hyperdx_save_dashboard',
context,
async ({ id: dashboardId, name, tiles: inputTiles, tags }) => {
async ({
id: dashboardId,
name,
description,
tiles: inputTiles,
tags,
}) => {
if (!dashboardId) {
return createDashboard({
teamId,
frontendUrl,
name,
description,
inputTiles,
tags,
});
Expand All @@ -69,6 +81,7 @@ export function registerSaveDashboard(
frontendUrl,
dashboardId,
name,
description,
inputTiles,
tags,
});
Expand All @@ -83,17 +96,20 @@ async function createDashboard({
teamId,
frontendUrl,
name,
description,
inputTiles,
tags,
}: {
teamId: string;
frontendUrl: string | undefined;
name: string;
description: string | undefined;
inputTiles: unknown[];
tags: string[] | undefined;
}) {
const parsed = createDashboardBodySchema.safeParse({
name,
description,
tiles: inputTiles,
tags,
});
Expand Down Expand Up @@ -149,6 +165,9 @@ async function createDashboard({

const newDashboard = await new Dashboard({
name: parsed.data.name,
...(parsed.data.description !== undefined
? { description: parsed.data.description }
: {}),
tiles: internalTiles,
tags: tags && uniq(tags),
filters: filtersWithIds,
Expand Down Expand Up @@ -184,13 +203,15 @@ async function updateDashboard({
frontendUrl,
dashboardId,
name,
description,
inputTiles,
tags,
}: {
teamId: string;
frontendUrl: string | undefined;
dashboardId: string;
name: string;
description: string | undefined;
inputTiles: unknown[];
tags: string[] | undefined;
}) {
Expand All @@ -203,6 +224,7 @@ async function updateDashboard({

const parsed = updateDashboardBodySchema.safeParse({
name,
description,
tiles: inputTiles,
tags,
});
Expand Down Expand Up @@ -278,6 +300,10 @@ async function updateDashboard({
tags: tags && uniq(tags),
};

if (description !== undefined) {
setPayload.description = description;
}

if (filters !== undefined) {
setPayload.filters = convertExternalFiltersToInternal(
filters,
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/models/dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export default mongoose.model<IDashboard>(
type: String,
required: true,
},
description: { type: String, required: false },
tiles: { type: mongoose.Schema.Types.Mixed, required: true },
team: { type: mongoose.Schema.Types.ObjectId, ref: 'Team' },
tags: {
Expand Down
23 changes: 23 additions & 0 deletions packages/api/src/routers/external-api/v2/dashboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,11 @@ async function getSourceConnectionMismatches(
* description: Dashboard name
* maxLength: 1024
* example: "Service Overview"
* description:
* type: string
* description: Optional description of the dashboard
* maxLength: 40000
* example: "Monitors key service health metrics including latency and error rates"
* tiles:
* type: array
* description: List of tiles/charts in the dashboard
Expand Down Expand Up @@ -1119,6 +1124,11 @@ async function getSourceConnectionMismatches(
* maxLength: 1024
* description: Dashboard name.
* example: "New Dashboard"
* description:
* type: string
* maxLength: 40000
* description: Optional description of the dashboard.
* example: "Monitors key service health metrics"
* tiles:
* type: array
* description: List of tiles/charts to include in the dashboard.
Expand Down Expand Up @@ -1165,6 +1175,11 @@ async function getSourceConnectionMismatches(
* maxLength: 1024
* description: Dashboard name.
* example: "Updated Dashboard Name"
* description:
* type: string
* maxLength: 40000
* description: Optional description of the dashboard.
* example: "Updated description for this dashboard"
* tiles:
* type: array
* items:
Expand Down Expand Up @@ -1305,6 +1320,7 @@ router.get('/', async (req, res, next) => {
{
_id: 1,
name: 1,
description: 1,
tiles: 1,
tags: 1,
filters: 1,
Expand Down Expand Up @@ -1422,6 +1438,7 @@ router.get(
{
_id: 1,
name: 1,
description: 1,
tiles: 1,
tags: 1,
filters: 1,
Expand Down Expand Up @@ -1589,6 +1606,7 @@ router.post(

const {
name,
description,
tiles,
tags,
filters,
Expand Down Expand Up @@ -1635,6 +1653,7 @@ router.post(

const newDashboard = await new Dashboard({
name,
...(description !== undefined ? { description } : {}),
tiles: internalTiles,
tags: tags && uniq(tags),
filters: filtersWithIds,
Expand Down Expand Up @@ -1812,6 +1831,7 @@ router.put(

const {
name,
description,
tiles,
tags,
filters,
Expand Down Expand Up @@ -1869,6 +1889,9 @@ router.put(
tiles: internalTiles,
tags: tags && uniq(tags),
};
if (description !== undefined) {
setPayload.description = description;
}
if (filters !== undefined) {
setPayload.filters = convertExternalFiltersToInternal(
filters,
Expand Down
3 changes: 3 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 @@ -71,6 +71,7 @@ export function isConfigTile(
export type ExternalDashboard = {
id: string;
name: string;
description?: string;
tiles: ExternalDashboardTileWithId[];
tags?: string[];
filters?: ExternalDashboardFilterWithId[];
Expand Down Expand Up @@ -310,6 +311,7 @@ export function convertToExternalDashboard(
return {
id: dashboard._id.toString(),
name: dashboard.name,
...(dashboard.description ? { description: dashboard.description } : {}),
tiles: dashboard.tiles
.map(convertTileToExternalChart)
.filter(t => t !== undefined),
Expand Down Expand Up @@ -576,6 +578,7 @@ export function resolveSavedQueryLanguage(params: {

const dashboardBodyBaseShape = {
name: z.string().max(1024),
description: z.string().max(40000).optional(),
tiles: externalDashboardTileListSchema,
tags: tagsSchema,
savedQuery: z.string().nullable().optional(),
Expand Down
14 changes: 14 additions & 0 deletions packages/app/src/DBDashboardImportPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ function FileSelection({

const MappingForm = z.object({
dashboardName: z.string().min(1),
dashboardDescription: z.string().max(40000).optional().default(''),
tags: z.array(z.string()),
sourceMappings: z.array(z.string()),
connectionMappings: z.array(z.string()),
Expand All @@ -221,6 +222,7 @@ function Mapping({ input }: { input: DashboardTemplate }) {
resolver: zodResolver(MappingForm),
defaultValues: {
dashboardName: input.name,
dashboardDescription: input.description ?? '',
tags: input.tags ?? [],
sourceMappings: input.tiles.map(() => ''),
connectionMappings: input.tiles.map(() => ''),
Expand Down Expand Up @@ -397,6 +399,7 @@ function Mapping({ input }: { input: DashboardTemplate }) {
tiles: zippedTiles,
filters: zippedFilters,
name: data.dashboardName,
description: data.dashboardDescription || undefined,
tags: data.tags,
});
let _dashboardId = dashboardId;
Expand Down Expand Up @@ -440,6 +443,17 @@ function Mapping({ input }: { input: DashboardTemplate }) {
/>
)}
/>
<Controller
name="dashboardDescription"
control={control}
render={({ field }) => (
<TextInput
label="Description"
placeholder="Optional description"
{...field}
/>
)}
/>
<Controller
name="tags"
control={control}
Expand Down
Loading
Loading