feat: refresh workbench visual layout

This commit is contained in:
2026-07-27 11:50:29 +08:00
parent b9bc9c3d39
commit f0485ca86e
33 changed files with 1624 additions and 353 deletions
+36 -12
View File
@@ -1,10 +1,6 @@
import type { Map as MapLibreMap } from "maplibre-gl";
import { describe, expect, it, vi } from "vitest";
import {
fitNetworkBounds,
getResponsiveWorkbenchPadding,
getWorkbenchPadding
} from "./camera";
import { fitNetworkBounds, getResponsiveWorkbenchPadding, getWorkbenchPadding } from "./camera";
import { WATER_NETWORK_GLOBAL_VIEW } from "./sources";
function createMap(width = 1280, height = 720) {
@@ -19,12 +15,40 @@ function createMap(width = 1280, height = 720) {
describe("workbench camera padding", () => {
it.each([
{ agentOpen: false, conditionOpen: false, expected: { top: 72, right: 72, bottom: 32, left: 96 } },
{ agentOpen: true, conditionOpen: false, expected: { top: 72, right: 72, bottom: 32, left: 484 } },
{ agentOpen: false, conditionOpen: true, expected: { top: 72, right: 504, bottom: 32, left: 96 } },
{ agentOpen: true, conditionOpen: true, expected: { top: 72, right: 504, bottom: 32, left: 484 } }
])("covers agent=$agentOpen and condition=$conditionOpen", ({ agentOpen, conditionOpen, expected }) => {
expect(getWorkbenchPadding(agentOpen, conditionOpen)).toEqual(expected);
{
agentOpen: false,
conditionOpen: false,
expected: { top: 72, right: 72, bottom: 32, left: 96 }
},
{
agentOpen: true,
conditionOpen: false,
expected: { top: 72, right: 72, bottom: 32, left: 484 }
},
{
agentOpen: false,
conditionOpen: true,
expected: { top: 72, right: 504, bottom: 32, left: 96 }
},
{
agentOpen: true,
conditionOpen: true,
expected: { top: 72, right: 504, bottom: 32, left: 484 }
}
])(
"covers agent=$agentOpen and condition=$conditionOpen",
({ agentOpen, conditionOpen, expected }) => {
expect(getWorkbenchPadding(agentOpen, conditionOpen)).toEqual(expected);
}
);
it("uses a committed Agent width for camera-safe operations", () => {
expect(getWorkbenchPadding(true, false, false, 620)).toEqual({
top: 72,
right: 72,
bottom: 32,
left: 644
});
});
it("caps combined padding on constrained desktop widths", () => {
@@ -59,7 +83,7 @@ describe("fitNetworkBounds", () => {
const [bounds, options] = fitBounds.mock.calls[0] ?? [];
expect(bounds[0][0]).toBeCloseTo(121.351632, 6);
expect(bounds[0][1]).toBeCloseTo(30.810500, 6);
expect(bounds[0][1]).toBeCloseTo(30.8105, 6);
expect(bounds[1][0]).toBeCloseTo(121.772482, 6);
expect(bounds[1][1]).toBeCloseTo(31.007207, 6);
expect(options).toMatchObject({
+22 -19
View File
@@ -1,7 +1,5 @@
import type { Map as MapLibreMap, PaddingOptions } from "maplibre-gl";
import {
getWorkbenchCameraPadding
} from "../layout/workbench-layout";
import { getWorkbenchCameraPadding } from "../layout/workbench-layout";
import { WATER_NETWORK_GLOBAL_VIEW } from "./sources";
type LngLatBounds = [[number, number], [number, number]];
@@ -14,24 +12,35 @@ export type NetworkViewParams = {
const WEB_MERCATOR_RADIUS = 6378137;
const GLOBAL_VIEW_MAX_ZOOM = 13;
const GLOBAL_VIEW_PADDING: PaddingOptions = { top: 96, right: 48, bottom: 48, left: 48 };
export function getWorkbenchPadding(leftPanelOpen: boolean, rightPanelOpen: boolean): PaddingOptions {
export function getWorkbenchPadding(
leftPanelOpen: boolean,
rightPanelOpen: boolean,
conditionPanelExpanded = false,
agentPanelWidth?: number
): PaddingOptions {
return getWorkbenchCameraPadding(1280, {
agentOpen: leftPanelOpen,
conditionOpen: rightPanelOpen
agentWidth: agentPanelWidth,
conditionOpen: rightPanelOpen,
conditionExpanded: conditionPanelExpanded
});
}
export function getResponsiveWorkbenchPadding(
map: MapLibreMap,
leftPanelOpen: boolean,
rightPanelOpen: boolean
rightPanelOpen: boolean,
conditionPanelExpanded = false,
agentPanelWidth?: number
): PaddingOptions {
const width = getMapViewportSize(map).width;
return getResponsivePadding(
map,
getWorkbenchCameraPadding(width, {
agentOpen: leftPanelOpen,
conditionOpen: rightPanelOpen
agentWidth: agentPanelWidth,
conditionOpen: rightPanelOpen,
conditionExpanded: conditionPanelExpanded
})
);
}
@@ -41,14 +50,11 @@ export function fitNetworkBounds(
viewParams: NetworkViewParams = WATER_NETWORK_GLOBAL_VIEW,
padding: PaddingOptions = GLOBAL_VIEW_PADDING
) {
map.fitBounds(
getLngLatBoundsFromBbox3857(viewParams.bbox3857),
{
padding: getResponsivePadding(map, padding),
maxZoom: GLOBAL_VIEW_MAX_ZOOM,
duration: 600
}
);
map.fitBounds(getLngLatBoundsFromBbox3857(viewParams.bbox3857), {
padding: getResponsivePadding(map, padding),
maxZoom: GLOBAL_VIEW_MAX_ZOOM,
duration: 600
});
}
export function getResponsivePadding(map: MapLibreMap, padding: PaddingOptions): PaddingOptions {
@@ -84,10 +90,7 @@ function getMapViewportSize(map: MapLibreMap) {
function getLngLatBoundsFromBbox3857(bbox3857: WebMercatorBbox): LngLatBounds {
const [minX, minY, maxX, maxY] = bbox3857;
return [
webMercatorToLngLat(minX, minY),
webMercatorToLngLat(maxX, maxY)
];
return [webMercatorToLngLat(minX, minY), webMercatorToLngLat(maxX, maxY)];
}
function webMercatorToLngLat(x: number, y: number): [number, number] {
+2 -2
View File
@@ -185,8 +185,8 @@ export function createBaseStyle(mapboxToken?: string): StyleSpecification {
},
paint: {
"raster-opacity": 0.86,
"raster-saturation": -0.16,
"raster-contrast": 0.02
"raster-saturation": -0.3,
"raster-contrast": 0.1
}
});
}