mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
fix(editor): Styling/UX improvements on the new logs view (#14789)
This commit is contained in:
@@ -50,6 +50,7 @@ import CanvasBackground from './elements/background/CanvasBackground.vue';
|
||||
import CanvasArrowHeadMarker from './elements/edges/CanvasArrowHeadMarker.vue';
|
||||
import Edge from './elements/edges/CanvasEdge.vue';
|
||||
import Node from './elements/nodes/CanvasNode.vue';
|
||||
import { useViewportAutoAdjust } from '@/components/canvas/composables/useViewportAutoAdjust';
|
||||
|
||||
const $style = useCssModule();
|
||||
|
||||
@@ -141,6 +142,7 @@ const {
|
||||
findNode,
|
||||
viewport,
|
||||
nodesSelectionActive,
|
||||
setViewport,
|
||||
onEdgeMouseLeave,
|
||||
onEdgeMouseEnter,
|
||||
onEdgeMouseMove,
|
||||
@@ -536,6 +538,8 @@ function emitWithLastSelectedNode(emitFn: (id: string) => void) {
|
||||
const defaultZoom = 1;
|
||||
const isPaneMoving = ref(false);
|
||||
|
||||
useViewportAutoAdjust(viewportRef, viewport, setViewport);
|
||||
|
||||
function getProjectedPosition(event?: Pick<MouseEvent, 'clientX' | 'clientY'>) {
|
||||
const bounds = viewportRef.value?.getBoundingClientRect() ?? { left: 0, top: 0 };
|
||||
const offsetX = event?.clientX ?? 0;
|
||||
|
||||
@@ -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
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -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,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user