fix(dashboard): stabilize four-column widget placement
This commit is contained in:
@@ -2,13 +2,18 @@ import assert from "node:assert/strict";
|
||||
import {
|
||||
appendPlacement,
|
||||
dashboardMasonryRowSpan,
|
||||
dashboardWidgetColumnSpan,
|
||||
defaultDashboardLayout,
|
||||
layoutUpdatePayload,
|
||||
normalizeDashboardColumnStart,
|
||||
reconcileDashboardLayout,
|
||||
removePlacement,
|
||||
reorderPlacement
|
||||
} from "../src/features/dashboard/dashboardLayout.ts";
|
||||
import { dashboardGridPreview } from "../src/features/dashboard/dashboardEditorTypes.ts";
|
||||
import {
|
||||
dashboardColumnStartFromPointer,
|
||||
dashboardGridPreview
|
||||
} from "../src/features/dashboard/dashboardEditorTypes.ts";
|
||||
|
||||
const widgets = [
|
||||
{
|
||||
@@ -36,6 +41,7 @@ const defaults = defaultDashboardLayout(widgets);
|
||||
assert.deepEqual(defaults.knownWidgetIds, ["one", "two"]);
|
||||
assert.equal(defaults.placements.length, 1);
|
||||
assert.equal(defaults.placements[0].widgetId, "one");
|
||||
assert.equal(defaults.placements[0].columnStart, 1);
|
||||
assert.deepEqual(defaults.placements[0].configuration, { count: 3 });
|
||||
|
||||
const withTwo = appendPlacement(defaults, widgets[1]);
|
||||
@@ -43,6 +49,11 @@ assert.deepEqual(
|
||||
withTwo.placements.map((placement) => placement.widgetId),
|
||||
["one", "two"]
|
||||
);
|
||||
assert.equal(
|
||||
withTwo.placements[1].columnStart,
|
||||
2,
|
||||
"new widgets should use the next available horizontal position"
|
||||
);
|
||||
assert.equal(
|
||||
appendPlacement(withTwo, widgets[1]).placements.length,
|
||||
2,
|
||||
@@ -53,12 +64,19 @@ const reordered = reorderPlacement(
|
||||
withTwo,
|
||||
withTwo.placements[1].instanceId,
|
||||
withTwo.placements[0].instanceId,
|
||||
"before"
|
||||
"before",
|
||||
3
|
||||
);
|
||||
assert.deepEqual(
|
||||
reordered.placements.map((placement) => placement.widgetId),
|
||||
["two", "one"]
|
||||
);
|
||||
assert.equal(
|
||||
reordered.placements[0].columnStart,
|
||||
3,
|
||||
"moving a widget must change its column without moving other columns"
|
||||
);
|
||||
assert.equal(reordered.placements[1].columnStart, 1);
|
||||
|
||||
const removed = removePlacement(reordered, reordered.placements[0].instanceId);
|
||||
assert.deepEqual(
|
||||
@@ -75,7 +93,8 @@ const placementPreview = dashboardGridPreview(
|
||||
{
|
||||
kind: "placement",
|
||||
instanceId: withTwo.placements[1].instanceId,
|
||||
edge: "after"
|
||||
edge: "after",
|
||||
columnStart: 3
|
||||
}
|
||||
);
|
||||
assert.deepEqual(
|
||||
@@ -87,6 +106,13 @@ assert.deepEqual(
|
||||
["two:false", "one:true"],
|
||||
"placement previews must show the prospective order"
|
||||
);
|
||||
assert.equal(
|
||||
placementPreview[1].kind === "placement"
|
||||
? placementPreview[1].placement.columnStart
|
||||
: null,
|
||||
3,
|
||||
"placement previews must show the prospective column"
|
||||
);
|
||||
|
||||
const cataloguePreview = dashboardGridPreview(
|
||||
withTwo.placements,
|
||||
@@ -94,7 +120,8 @@ const cataloguePreview = dashboardGridPreview(
|
||||
{
|
||||
kind: "placement",
|
||||
instanceId: withTwo.placements[0].instanceId,
|
||||
edge: "after"
|
||||
edge: "after",
|
||||
columnStart: 2
|
||||
},
|
||||
"wide"
|
||||
);
|
||||
@@ -107,11 +134,19 @@ assert.deepEqual(
|
||||
["one", "three:wide", "two"],
|
||||
"catalogue previews must reserve the prospective widget size"
|
||||
);
|
||||
assert.equal(
|
||||
cataloguePreview[1].kind === "catalogue"
|
||||
? cataloguePreview[1].columnStart
|
||||
: null,
|
||||
2,
|
||||
"catalogue previews must reserve the selected horizontal position"
|
||||
);
|
||||
|
||||
const unavailablePlacement = {
|
||||
instanceId: "unavailable-instance",
|
||||
widgetId: "temporarily-disabled",
|
||||
size: "wide" as const,
|
||||
columnStart: 2,
|
||||
configuration: { mode: "summary" }
|
||||
};
|
||||
const reconciled = reconcileDashboardLayout(
|
||||
@@ -124,8 +159,8 @@ const reconciled = reconcileDashboardLayout(
|
||||
widgets
|
||||
);
|
||||
assert.equal(
|
||||
reconciled.placements[0],
|
||||
unavailablePlacement,
|
||||
reconciled.placements[0].columnStart,
|
||||
2,
|
||||
"temporarily unavailable contributions must retain their placement"
|
||||
);
|
||||
assert.equal(
|
||||
@@ -138,8 +173,29 @@ assert.equal(reconciled.revision, 4);
|
||||
const payload = layoutUpdatePayload(reconciled);
|
||||
assert.equal(payload.expected_revision, 4);
|
||||
assert.equal(payload.placements[0].instance_id, "unavailable-instance");
|
||||
assert.equal(payload.placements[0].column_start, 2);
|
||||
assert.equal(payload.placements[0].configuration.mode, "summary");
|
||||
|
||||
assert.equal(dashboardWidgetColumnSpan("small"), 1);
|
||||
assert.equal(dashboardWidgetColumnSpan("medium"), 2);
|
||||
assert.equal(dashboardWidgetColumnSpan("wide"), 3);
|
||||
assert.equal(dashboardWidgetColumnSpan("full"), 4);
|
||||
assert.equal(
|
||||
normalizeDashboardColumnStart("medium", 4),
|
||||
3,
|
||||
"column starts must be clamped so the widget stays in the four-column grid"
|
||||
);
|
||||
assert.equal(
|
||||
dashboardColumnStartFromPointer(500, 0, 1000, 20, 2, 4),
|
||||
2,
|
||||
"a two-column widget must be placeable in the middle columns"
|
||||
);
|
||||
assert.equal(
|
||||
dashboardColumnStartFromPointer(950, 0, 1000, 20, 3, 4),
|
||||
2,
|
||||
"a three-column widget must be placeable from column two"
|
||||
);
|
||||
|
||||
const repeatingWidget = {
|
||||
...widgets[0],
|
||||
id: "repeating",
|
||||
|
||||
Reference in New Issue
Block a user