Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into node-1511-google-sh…
Browse files Browse the repository at this point in the history
…eets-set-default-for-when-filter-has-multiple
  • Loading branch information
ShireenMissi committed Aug 16, 2024
2 parents 8a5891e + ce46bf5 commit 369b89c
Show file tree
Hide file tree
Showing 13 changed files with 250 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import { OpenAIAssistantRunnable } from 'langchain/experimental/openai_assistant
import type { OpenAIToolType } from 'langchain/dist/experimental/openai_assistant/schema';
import { OpenAI as OpenAIClient } from 'openai';

import { NodeConnectionType, NodeOperationError, updateDisplayOptions } from 'n8n-workflow';
import {
ApplicationError,
NodeConnectionType,
NodeOperationError,
updateDisplayOptions,
} from 'n8n-workflow';
import type {
IDataObject,
IExecuteFunctions,
Expand Down Expand Up @@ -228,25 +233,36 @@ export async function execute(this: IExecuteFunctions, i: number): Promise<INode
}
}

const response = await agentExecutor.withConfig(getTracingConfig(this)).invoke(chainValues);
if (memory) {
await memory.saveContext({ input }, { output: response.output });
let filteredResponse: IDataObject = {};
try {
const response = await agentExecutor.withConfig(getTracingConfig(this)).invoke(chainValues);
if (memory) {
await memory.saveContext({ input }, { output: response.output });

if (response.threadId && response.runId) {
const threadRun = await client.beta.threads.runs.retrieve(response.threadId, response.runId);
response.usage = threadRun.usage;
if (response.threadId && response.runId) {
const threadRun = await client.beta.threads.runs.retrieve(
response.threadId,
response.runId,
);
response.usage = threadRun.usage;
}
}
}

if (
options.preserveOriginalTools !== false &&
nodeVersion >= 1.3 &&
(assistantTools ?? [])?.length
) {
await client.beta.assistants.update(assistantId, {
tools: assistantTools,
});
if (
options.preserveOriginalTools !== false &&
nodeVersion >= 1.3 &&
(assistantTools ?? [])?.length
) {
await client.beta.assistants.update(assistantId, {
tools: assistantTools,
});
}
filteredResponse = omit(response, ['signal', 'timeout']) as IDataObject;
} catch (error) {
if (!(error instanceof ApplicationError)) {
throw new NodeOperationError(this.getNode(), error.message, { itemIndex: i });
}
}
const filteredResponse = omit(response, ['signal', 'timeout']);

return [{ json: filteredResponse, pairedItem: { item: i } }];
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ const fieldDescription = computed<string>(() => {
resourceMapperTypeOptions.value?.multiKeyMatch === true
? `${pluralFieldWord.value}`
: `${singularFieldWord.value}`,
nodeDisplayName: props.serviceName,
},
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,18 @@ describe('ResourceMapper.vue', () => {
},
{ merge: true },
);

await waitAllPromises();
expect(getByText('Set the value for each foo')).toBeInTheDocument();
expect(
getByText('Look for incoming data that matches the foos in the service'),
).toBeInTheDocument();
expect(getByText('Foos to Match On')).toBeInTheDocument();
expect(getByText('The foos that identify the row(s) to modify')).toBeInTheDocument();
expect(
getByText(
'The foos to use when matching rows in the service to the input items of this node. Usually an ID.',
),
).toBeInTheDocument();
});

it('should render correct fields based on saved schema', async () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/editor-ui/src/components/canvas/Canvas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ import { createCanvasConnection, createCanvasNodeElement } from '@/__tests__/dat
import { NodeConnectionType } from 'n8n-workflow';
import type { useDeviceSupport } from 'n8n-design-system';

const matchMedia = global.window.matchMedia;
// @ts-expect-error Initialize window object
global.window = jsdom.window as unknown as Window & typeof globalThis;
global.window.matchMedia = matchMedia;

vi.mock('n8n-design-system', async (importOriginal) => {
const actual = await importOriginal<typeof useDeviceSupport>();
return { ...actual, useDeviceSupport: vi.fn(() => ({ isCtrlKeyPressed: vi.fn() })) };
});

vi.mock('@/composables/useDeviceSupport');

let renderComponent: ReturnType<typeof createComponentRenderer>;
beforeEach(() => {
const pinia = createPinia();
Expand Down
90 changes: 47 additions & 43 deletions packages/editor-ui/src/components/canvas/Canvas.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
<script lang="ts" setup>
import type { CanvasConnection, CanvasNode, CanvasNodeMoveEvent, ConnectStartEvent } from '@/types';
import type { EdgeMouseEvent, NodeDragEvent, Connection, XYPosition } from '@vue-flow/core';
import type {
EdgeMouseEvent,
NodeDragEvent,
Connection,
XYPosition,
ViewportTransform,
} from '@vue-flow/core';
import { useVueFlow, VueFlow, PanelPosition } from '@vue-flow/core';
import { Background } from '@vue-flow/background';
import { Controls } from '@vue-flow/controls';
import { MiniMap } from '@vue-flow/minimap';
import Node from './elements/nodes/CanvasNode.vue';
import Edge from './elements/edges/CanvasEdge.vue';
Expand Down Expand Up @@ -77,6 +82,9 @@ const {
removeSelectedNodes,
viewportRef,
fitView,
zoomIn,
zoomOut,
zoomTo,
setInteractive,
elementsSelectable,
project,
Expand All @@ -100,6 +108,10 @@ useKeybindings({
ctrl_enter: () => emit('run:workflow'),
ctrl_s: () => emit('save:workflow'),
ctrl_a: () => addSelectedNodes(graphNodes.value),
'+|=': async () => await onZoomIn(),
'-|_': async () => await onZoomOut(),
0: async () => await onResetZoom(),
1: async () => await onFitView(),
// @TODO implement arrow key shortcuts to modify selection
});
Expand Down Expand Up @@ -257,6 +269,8 @@ function emitWithLastSelectedNode(emitFn: (id: string) => void) {
* View
*/
const zoom = ref(1);
function onClickPane(event: MouseEvent) {
const bounds = viewportRef.value?.getBoundingClientRect() ?? { left: 0, top: 0 };
const position = project({
Expand All @@ -268,7 +282,27 @@ function onClickPane(event: MouseEvent) {
}
async function onFitView() {
await fitView({ maxZoom: 1.2, padding: 0.1 });
await fitView({ maxZoom: 1.2, padding: 0.2 });
}
async function onZoomTo(zoomLevel: number) {
await zoomTo(zoomLevel);
}
async function onZoomIn() {
await zoomIn();
}
async function onZoomOut() {
await zoomOut();
}
async function onResetZoom() {
await onZoomTo(1);
}
function onViewportChange(viewport: ViewportTransform) {
zoom.value = viewport.zoom;
}
function setReadonly(value: boolean) {
Expand Down Expand Up @@ -382,6 +416,7 @@ watch(() => props.readOnly, setReadonly, {
@connect-end="onConnectEnd"
@pane-click="onClickPane"
@contextmenu="onOpenContextMenu"
@viewport-change="onViewportChange"
>
<template #node-canvas-node="canvasNodeProps">
<Node
Expand Down Expand Up @@ -424,15 +459,21 @@ watch(() => props.readOnly, setReadonly, {
pannable
zoomable
:node-class-name="minimapNodeClassnameFn"
mask-color="var(--color-background-base)"
:node-border-radius="16"
/>

<Controls
<CanvasControlButtons
data-test-id="canvas-controls"
:class="$style.canvasControls"
:position="controlsPosition"
:show-interactive="!readOnly"
:show-interactive="false"
:zoom="zoom"
@fit-view="onFitView"
></Controls>
@zoom-in="onZoomIn"
@zoom-out="onZoomOut"
@reset-zoom="onResetZoom"
/>

<Suspense>
<ContextMenu @action="onContextMenuAction" />
Expand All @@ -449,40 +490,3 @@ watch(() => props.readOnly, setReadonly, {
}
}
</style>

<style lang="scss">
.vue-flow__controls {
display: flex;
gap: var(--spacing-2xs);
box-shadow: none;
}
.vue-flow__controls-button {
width: 42px;
height: 42px;
border: var(--border-base);
border-radius: var(--border-radius-base);
padding: 0;
transition-property: transform, background, border, color;
transition-duration: 300ms;
transition-timing-function: ease;
&:hover {
border-color: var(--color-button-secondary-hover-active-border);
background-color: var(--color-button-secondary-active-background);
transform: scale(1.1);
svg {
fill: var(--color-primary);
}
}
svg {
max-height: 16px;
max-width: 16px;
transition-property: fill;
transition-duration: 300ms;
transition-timing-function: ease;
}
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { createComponentRenderer } from '@/__tests__/render';
import CanvasControlButtons from './CanvasControlButtons.vue';

const renderComponent = createComponentRenderer(CanvasControlButtons);

describe('CanvasChatButton', () => {
it('should render correctly', () => {
const wrapper = renderComponent();

expect(wrapper.getByTestId('zoom-in-button')).toBeVisible();
expect(wrapper.getByTestId('zoom-out-button')).toBeVisible();
expect(wrapper.getByTestId('zoom-to-fit')).toBeVisible();

expect(wrapper.html()).toMatchSnapshot();
});

it('should show reset zoom button when zoom is not equal to 1', () => {
const wrapper = renderComponent({
props: {
zoom: 1.5,
},
});

expect(wrapper.getByTestId('reset-zoom-button')).toBeVisible();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<script setup lang="ts">
import { Controls } from '@vue-flow/controls';
import KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';
import { computed } from 'vue';
const props = withDefaults(
defineProps<{
zoom?: number;
}>(),
{
zoom: 1,
},
);
const emit = defineEmits<{
'reset-zoom': [];
}>();
const isResetZoomVisible = computed(() => props.zoom !== 1);
function onResetZoom() {
emit('reset-zoom');
}
</script>
<template>
<Controls :show-zoom="false" :show-fit-view="false">
<KeyboardShortcutTooltip
:label="$locale.baseText('nodeView.zoomIn')"
:shortcut="{ keys: ['+'] }"
>
<N8nIconButton
type="tertiary"
size="large"
icon="search-plus"
data-test-id="zoom-in-button"
/>
</KeyboardShortcutTooltip>
<KeyboardShortcutTooltip
:label="$locale.baseText('nodeView.zoomOut')"
:shortcut="{ keys: ['-'] }"
>
<N8nIconButton
type="tertiary"
size="large"
icon="search-minus"
data-test-id="zoom-out-button"
/>
</KeyboardShortcutTooltip>
<KeyboardShortcutTooltip
:label="$locale.baseText('nodeView.zoomToFit')"
:shortcut="{ keys: ['1'] }"
>
<N8nIconButton type="tertiary" size="large" icon="expand" data-test-id="zoom-to-fit" />
</KeyboardShortcutTooltip>
<KeyboardShortcutTooltip
v-if="isResetZoomVisible"
:label="$locale.baseText('nodeView.resetZoom')"
:shortcut="{ keys: ['0'] }"
>
<N8nIconButton
type="tertiary"
size="large"
icon="undo"
data-test-id="reset-zoom-button"
@click="onResetZoom"
/>
</KeyboardShortcutTooltip>
</Controls>
</template>

<style lang="scss">
.vue-flow__controls {
display: flex;
gap: var(--spacing-xs);
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`CanvasChatButton > should render correctly 1`] = `
"<div class="vue-flow__panel bottom left vue-flow__controls" style="pointer-events: all;">
<!---->
<!----><button class="vue-flow__controls-button vue-flow__controls-interactive"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 32">
<path d="M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 0 0 0 13.714v15.238A3.056 3.056 0 0 0 3.048 32h18.285a3.056 3.056 0 0 0 3.048-3.048V13.714a3.056 3.056 0 0 0-3.048-3.047zM12.19 24.533a3.056 3.056 0 0 1-3.047-3.047 3.056 3.056 0 0 1 3.047-3.048 3.056 3.056 0 0 1 3.048 3.048 3.056 3.056 0 0 1-3.048 3.047z"></path>
</svg>
<!---->
</button><button class="button button tertiary large withIcon square el-tooltip__trigger el-tooltip__trigger" aria-live="polite" data-test-id="zoom-in-button"><span class="icon"><span class="n8n-text compact size-large regular n8n-icon n8n-icon"><svg class="svg-inline--fa fa-search-plus fa-w-16 large" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search-plus" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path class="" fill="currentColor" d="M304 192v32c0 6.6-5.4 12-12 12h-56v56c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-56h-56c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h56v-56c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v56h56c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z"></path></svg></span></span>
<!--v-if-->
</button>
<!--teleport start-->
<!--teleport end--><button class="button button tertiary large withIcon square el-tooltip__trigger el-tooltip__trigger" aria-live="polite" data-test-id="zoom-out-button"><span class="icon"><span class="n8n-text compact size-large regular n8n-icon n8n-icon"><svg class="svg-inline--fa fa-search-minus fa-w-16 large" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search-minus" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path class="" fill="currentColor" d="M304 192v32c0 6.6-5.4 12-12 12H124c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z"></path></svg></span></span>
<!--v-if-->
</button>
<!--teleport start-->
<!--teleport end--><button class="button button tertiary large withIcon square el-tooltip__trigger el-tooltip__trigger" aria-live="polite" data-test-id="zoom-to-fit"><span class="icon"><span class="n8n-text compact size-large regular n8n-icon n8n-icon"><svg class="svg-inline--fa fa-expand fa-w-14 large" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="expand" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path class="" fill="currentColor" d="M0 180V56c0-13.3 10.7-24 24-24h124c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H64v84c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12zM288 44v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V56c0-13.3-10.7-24-24-24H300c-6.6 0-12 5.4-12 12zm148 276h-40c-6.6 0-12 5.4-12 12v84h-84c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24V332c0-6.6-5.4-12-12-12zM160 468v-40c0-6.6-5.4-12-12-12H64v-84c0-6.6-5.4-12-12-12H12c-6.6 0-12 5.4-12 12v124c0 13.3 10.7 24 24 24h124c6.6 0 12-5.4 12-12z"></path></svg></span></span>
<!--v-if-->
</button>
<!--teleport start-->
<!--teleport end-->
<!--v-if-->
</div>"
`;
Loading

0 comments on commit 369b89c

Please sign in to comment.