fix(editor): Styling/UX improvements on the new logs view (#14789)

This commit is contained in:
Suguru Inoue
2025-04-23 15:31:12 +02:00
committed by GitHub
parent 6c9c720ae9
commit 454e5c77ad
28 changed files with 472 additions and 228 deletions

View File

@@ -0,0 +1,55 @@
import { ref } from 'vue';
import { useViewportAutoAdjust } from './useViewportAutoAdjust';
import { waitFor } from '@testing-library/vue';
vi.mock('@/stores/settings.store', () => ({
useSettingsStore: vi.fn(() => ({ isNewLogsEnabled: true })),
}));
describe(useViewportAutoAdjust, () => {
afterAll(() => {
vi.clearAllMocks();
});
it('should set viewport when canvas is resized', async () => {
let resizeHandler: ResizeObserverCallback = () => {};
vi.spyOn(window, 'ResizeObserver').mockImplementation((handler) => {
resizeHandler = handler;
return { observe() {}, disconnect() {}, unobserve() {} } as ResizeObserver;
});
const container = document.createElement('div');
Object.defineProperty(container, 'offsetWidth', {
configurable: true,
get() {
return 1000;
},
});
Object.defineProperty(container, 'offsetHeight', {
configurable: true,
get() {
return 800;
},
});
const viewportRef = ref(container);
const viewport = ref({ x: 30, y: 40, zoom: 0.5 });
const setViewport = vi.fn();
useViewportAutoAdjust(viewportRef, viewport, setViewport);
resizeHandler(
[{ contentRect: { x: 0, y: 0, width: 900, height: 1000 } } as ResizeObserverEntry],
{} as ResizeObserver,
);
await waitFor(() =>
expect(setViewport).toHaveBeenLastCalledWith({
x: -20, // 30 + (900 - 1000) / 2
y: 140, // 40 + (1000 - 800) / 2
zoom: 0.5, // unchanged
}),
);
});
});

View File

@@ -0,0 +1,57 @@
import { useSettingsStore } from '@/stores/settings.store';
import type { Rect, SetViewport, ViewportTransform } from '@vue-flow/core';
import { type Ref, ref, watch } from 'vue';
/**
* When canvas is resized (via window resize or toggling logs panel), adjust viewport to maintain center
*/
export function useViewportAutoAdjust(
viewportRef: Ref<HTMLElement | null>,
viewport: Ref<ViewportTransform>,
setViewport: SetViewport,
) {
const settingsStore = useSettingsStore();
if (settingsStore.isNewLogsEnabled) {
const canvasRect = ref<Rect>();
watch(
viewportRef,
(vp, _, onCleanUp) => {
if (!vp) {
return;
}
const resizeObserver = new ResizeObserver((entries) => {
const entry = entries[0];
if (entry) {
canvasRect.value = entry.contentRect;
}
});
canvasRect.value = {
x: vp.offsetLeft,
y: vp.offsetTop,
width: vp.offsetWidth,
height: vp.offsetHeight,
};
resizeObserver.observe(vp);
onCleanUp(() => resizeObserver.disconnect());
},
{ immediate: true },
);
watch(canvasRect, async (newRect, oldRect) => {
if (!newRect || !oldRect) {
return;
}
await setViewport({
x: viewport.value.x + (newRect.width - oldRect.width) / 2,
y: viewport.value.y + (newRect.height - oldRect.height) / 2,
zoom: viewport.value.zoom,
});
});
}
}