Skip to content

Commit d8c3095

Browse files
cursoragentbetegon
andcommitted
fix(dashboard): rename x/y flags to col/row so Stricli can parse them (Sentry CLI-RN)
Stricli FLAG_NAME_PATTERN requires 2+ characters after "--", so flags named "x" and "y" (producing --x and --y) were silently treated as positional arguments. Users passing "--x 0 --y 0" got "too many positional arguments" errors. Rename to --col/--row (matching grid terminology) and add -x/-y as short aliases which Stricli handles via its alias mechanism. Co-authored-by: Miguel Betegón <miguelbetegongarcia@gmail.com>
1 parent 6b4fda7 commit d8c3095

5 files changed

Lines changed: 50 additions & 46 deletions

File tree

src/commands/dashboard/widget/add.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export const addCommand = buildCommand({
9696
"Sort shorthand (--sort flag):\n" +
9797
" count → count() (ascending)\n" +
9898
" -count → -count() (descending)\n\n" +
99-
"Layout flags (--x, --y, --width, --height) control widget position\n" +
99+
"Layout flags (--col/-x, --row/-y, --width, --height) control widget position\n" +
100100
"and size in the 6-column dashboard grid. Omitted values use auto-layout.",
101101
},
102102
output: {
@@ -156,13 +156,13 @@ export const addCommand = buildCommand({
156156
brief: "Result limit",
157157
optional: true,
158158
},
159-
x: {
159+
col: {
160160
kind: "parsed",
161161
parse: numberParser,
162162
brief: "Grid column position (0-based, 0–5)",
163163
optional: true,
164164
},
165-
y: {
165+
row: {
166166
kind: "parsed",
167167
parse: numberParser,
168168
brief: "Grid row position (0-based)",
@@ -195,6 +195,8 @@ export const addCommand = buildCommand({
195195
s: "sort",
196196
n: "limit",
197197
l: "layout",
198+
x: "col",
199+
y: "row",
198200
},
199201
},
200202
async *func(this: SentryContext, flags: AddFlags, ...args: string[]) {
@@ -256,8 +258,8 @@ export const addCommand = buildCommand({
256258
newWidget = assignDefaultLayout(newWidget, updateBody.widgets, layoutMode);
257259

258260
const hasExplicitLayout =
259-
flags.x !== undefined ||
260-
flags.y !== undefined ||
261+
flags.col !== undefined ||
262+
flags.row !== undefined ||
261263
flags.width !== undefined ||
262264
flags.height !== undefined;
263265

@@ -267,8 +269,8 @@ export const addCommand = buildCommand({
267269
...newWidget,
268270
layout: {
269271
...baseLayout,
270-
...(flags.x !== undefined && { x: flags.x }),
271-
...(flags.y !== undefined && { y: flags.y }),
272+
...(flags.col !== undefined && { x: flags.col }),
273+
...(flags.row !== undefined && { y: flags.row }),
272274
...(flags.width !== undefined && { w: flags.width }),
273275
...(flags.height !== undefined && { h: flags.height }),
274276
},
@@ -277,7 +279,7 @@ export const addCommand = buildCommand({
277279
// (e.g., --x 5 on a table widget with auto-width 6 → 5+6=11 > 6)
278280
const finalLayout = newWidget.layout ?? baseLayout;
279281
validateWidgetLayout(
280-
{ x: finalLayout.x, width: finalLayout.w },
282+
{ col: finalLayout.x, width: finalLayout.w },
281283
finalLayout
282284
);
283285
}

src/commands/dashboard/widget/edit.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ function mergeLayout(
8585
existing: DashboardWidget
8686
): DashboardWidget["layout"] {
8787
const hasChange =
88-
flags.x !== undefined ||
89-
flags.y !== undefined ||
88+
flags.col !== undefined ||
89+
flags.row !== undefined ||
9090
flags.width !== undefined ||
9191
flags.height !== undefined;
9292

@@ -96,8 +96,8 @@ function mergeLayout(
9696

9797
return {
9898
...(existing.layout ?? FALLBACK_LAYOUT),
99-
...(flags.x !== undefined && { x: flags.x }),
100-
...(flags.y !== undefined && { y: flags.y }),
99+
...(flags.col !== undefined && { x: flags.col }),
100+
...(flags.row !== undefined && { y: flags.row }),
101101
...(flags.width !== undefined && { w: flags.width }),
102102
...(flags.height !== undefined && { h: flags.height }),
103103
};
@@ -198,7 +198,7 @@ export const editCommand = buildCommand({
198198
"The dashboard can be specified by numeric ID or title.\n" +
199199
"Identify the widget by --index (0-based) or --title.\n" +
200200
"Only provided flags are changed — omitted values are preserved.\n\n" +
201-
"Layout flags (--x, --y, --width, --height) control widget position\n" +
201+
"Layout flags (--col/-x, --row/-y, --width, --height) control widget position\n" +
202202
"and size in the 6-column dashboard grid.\n\n" +
203203
"Examples:\n" +
204204
" sentry dashboard widget edit 12345 --title 'Error Rate' --display bar\n" +
@@ -282,13 +282,13 @@ export const editCommand = buildCommand({
282282
brief: "Result limit",
283283
optional: true,
284284
},
285-
x: {
285+
col: {
286286
kind: "parsed",
287287
parse: numberParser,
288288
brief: "Grid column position (0-based, 0–5)",
289289
optional: true,
290290
},
291-
y: {
291+
row: {
292292
kind: "parsed",
293293
parse: numberParser,
294294
brief: "Grid row position (0-based)",
@@ -316,6 +316,8 @@ export const editCommand = buildCommand({
316316
g: "group-by",
317317
s: "sort",
318318
n: "limit",
319+
x: "col",
320+
y: "row",
319321
},
320322
},
321323
async *func(this: SentryContext, flags: EditFlags, ...args: string[]) {

src/types/dashboard.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -710,8 +710,8 @@ export function assignDefaultLayout(
710710

711711
/** Shared layout flags accepted by widget add and edit commands */
712712
export type WidgetLayoutFlags = {
713-
readonly x?: number;
714-
readonly y?: number;
713+
readonly col?: number;
714+
readonly row?: number;
715715
readonly width?: number;
716716
readonly height?: number;
717717
};
@@ -751,11 +751,11 @@ export function validateWidgetLayout(
751751
flags: WidgetLayoutFlags,
752752
existing?: DashboardWidgetLayout
753753
): void {
754-
if (flags.x !== undefined) {
755-
assertLayoutInt(flags.x, "x", 0, GRID_COLUMNS - 1);
754+
if (flags.col !== undefined) {
755+
assertLayoutInt(flags.col, "col", 0, GRID_COLUMNS - 1);
756756
}
757-
if (flags.y !== undefined) {
758-
assertLayoutInt(flags.y, "y", 0);
757+
if (flags.row !== undefined) {
758+
assertLayoutInt(flags.row, "row", 0);
759759
}
760760
if (flags.width !== undefined) {
761761
assertLayoutInt(flags.width, "width", 1, GRID_COLUMNS);
@@ -764,17 +764,17 @@ export function validateWidgetLayout(
764764
assertLayoutInt(flags.height, "height", 1);
765765
}
766766

767-
// Cross-validate x + width doesn't overflow the grid
768-
const effectiveX = flags.x ?? existing?.x;
767+
// Cross-validate col + width doesn't overflow the grid
768+
const effectiveX = flags.col ?? existing?.x;
769769
const effectiveW = flags.width ?? existing?.w;
770770
if (
771771
effectiveX !== undefined &&
772772
effectiveW !== undefined &&
773773
effectiveX + effectiveW > GRID_COLUMNS
774774
) {
775775
throw new ValidationError(
776-
`Widget overflows the grid: x(${effectiveX}) + width(${effectiveW}) = ${effectiveX + effectiveW}, but the grid is ${GRID_COLUMNS} columns wide.`,
777-
"x"
776+
`Widget overflows the grid: col(${effectiveX}) + width(${effectiveW}) = ${effectiveX + effectiveW}, but the grid is ${GRID_COLUMNS} columns wide.`,
777+
"col"
778778
);
779779
}
780780
}

test/commands/dashboard/widget/add.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ describe("dashboard widget add", () => {
269269
// Layout flag tests
270270
// -------------------------------------------------------------------------
271271

272-
test("uses explicit layout when --x --y --width --height provided", async () => {
272+
test("uses explicit layout when --col --row --width --height provided", async () => {
273273
const { context } = createMockContext();
274274
const func = await addCommand.loader();
275275
await func.call(
@@ -278,8 +278,8 @@ describe("dashboard widget add", () => {
278278
json: false,
279279
display: "line",
280280
query: ["count"],
281-
x: 0,
282-
y: 5,
281+
col: 0,
282+
row: 5,
283283
width: 6,
284284
height: 3,
285285
},
@@ -304,7 +304,7 @@ describe("dashboard widget add", () => {
304304
json: false,
305305
display: "big_number",
306306
query: ["count"],
307-
x: 4,
307+
col: 4,
308308
},
309309
"123",
310310
"Positioned Counter"
@@ -333,14 +333,14 @@ describe("dashboard widget add", () => {
333333
expect(err.message).toContain("--width");
334334
});
335335

336-
test("throws ValidationError when --x overflows with auto-layout default width", async () => {
337-
// table display defaults to w=6, so --x 1 would produce x=1 + w=6 = 7 > 6
336+
test("throws ValidationError when --col overflows with auto-layout default width", async () => {
337+
// table display defaults to w=6, so --col 1 would produce x=1 + w=6 = 7 > 6
338338
const { context } = createMockContext();
339339
const func = await addCommand.loader();
340340
const err = await func
341341
.call(
342342
context,
343-
{ json: false, display: "table", query: ["count"], x: 1 },
343+
{ json: false, display: "table", query: ["count"], col: 1 },
344344
"123",
345345
"Wide Table"
346346
)
@@ -349,19 +349,19 @@ describe("dashboard widget add", () => {
349349
expect(err.message).toContain("overflows the grid");
350350
});
351351

352-
test("throws ValidationError for negative y", async () => {
352+
test("throws ValidationError for negative row", async () => {
353353
const { context } = createMockContext();
354354
const func = await addCommand.loader();
355355
const err = await func
356356
.call(
357357
context,
358-
{ json: false, display: "line", query: ["count"], y: -1 },
358+
{ json: false, display: "line", query: ["count"], row: -1 },
359359
"123",
360360
"Bad Y"
361361
)
362362
.catch((e: Error) => e);
363363
expect(err).toBeInstanceOf(ValidationError);
364-
expect(err.message).toContain("--y");
364+
expect(err.message).toContain("--row");
365365
});
366366

367367
test("auto-defaults orderby when group-by + limit provided", async () => {

test/commands/dashboard/widget/edit.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,10 @@ describe("dashboard widget edit", () => {
291291
// Layout flag tests
292292
// -------------------------------------------------------------------------
293293

294-
test("applies --x and --y layout flags to existing widget", async () => {
294+
test("applies --col and --row layout flags to existing widget", async () => {
295295
const { context } = createMockContext();
296296
const func = await editCommand.loader();
297-
await func.call(context, { json: false, index: 0, x: 4, y: 3 }, "123");
297+
await func.call(context, { json: false, index: 0, col: 4, row: 3 }, "123");
298298

299299
const body = updateDashboardSpy.mock.calls[0]?.[2];
300300
const edited = body.widgets[0];
@@ -310,7 +310,7 @@ describe("dashboard widget edit", () => {
310310
const func = await editCommand.loader();
311311
await func.call(
312312
context,
313-
{ json: false, index: 1, x: 0, width: 6, height: 4 },
313+
{ json: false, index: 1, col: 0, width: 6, height: 4 },
314314
"123"
315315
);
316316

@@ -332,14 +332,14 @@ describe("dashboard widget edit", () => {
332332
expect(edited.layout).toEqual({ x: 0, y: 0, w: 2, h: 1 });
333333
});
334334

335-
test("throws ValidationError for x out of range", async () => {
335+
test("throws ValidationError for col out of range", async () => {
336336
const { context } = createMockContext();
337337
const func = await editCommand.loader();
338338
const err = await func
339-
.call(context, { json: false, index: 0, x: 6 }, "123")
339+
.call(context, { json: false, index: 0, col: 6 }, "123")
340340
.catch((e: Error) => e);
341341
expect(err).toBeInstanceOf(ValidationError);
342-
expect(err.message).toContain("--x");
342+
expect(err.message).toContain("--col");
343343
});
344344

345345
test("throws ValidationError for negative width", async () => {
@@ -352,8 +352,8 @@ describe("dashboard widget edit", () => {
352352
expect(err.message).toContain("--width");
353353
});
354354

355-
test("throws ValidationError when --x overflows with fallback width on layoutless widget", async () => {
356-
// Widget without layout uses FALLBACK_LAYOUT (w=3), so --x 4 → 4+3=7 > 6
355+
test("throws ValidationError when --col overflows with fallback width on layoutless widget", async () => {
356+
// Widget without layout uses FALLBACK_LAYOUT (w=3), so --col 4 → 4+3=7 > 6
357357
getDashboardSpy.mockResolvedValueOnce({
358358
...sampleDashboard,
359359
widgets: [
@@ -377,17 +377,17 @@ describe("dashboard widget edit", () => {
377377
const { context } = createMockContext();
378378
const func = await editCommand.loader();
379379
const err = await func
380-
.call(context, { json: false, index: 0, x: 4 }, "123")
380+
.call(context, { json: false, index: 0, col: 4 }, "123")
381381
.catch((e: Error) => e);
382382
expect(err).toBeInstanceOf(ValidationError);
383383
expect(err.message).toContain("overflows the grid");
384384
});
385385

386-
test("throws ValidationError when x + width overflows grid", async () => {
386+
test("throws ValidationError when col + width overflows grid", async () => {
387387
const { context } = createMockContext();
388388
const func = await editCommand.loader();
389389
const err = await func
390-
.call(context, { json: false, index: 0, x: 4, width: 4 }, "123")
390+
.call(context, { json: false, index: 0, col: 4, width: 4 }, "123")
391391
.catch((e: Error) => e);
392392
expect(err).toBeInstanceOf(ValidationError);
393393
expect(err.message).toContain("overflows the grid");

0 commit comments

Comments
 (0)