fix: refactor more

This commit is contained in:
Mutasem Aldmour 2024-11-11 17:53:14 +01:00
parent ad990236eb
commit 785b30e675
No known key found for this signature in database
GPG key ID: 3DFA8122BB7FD6B8
7 changed files with 50 additions and 96 deletions

View file

@ -202,17 +202,13 @@ export interface IStartRunData {
runData?: IRunData; runData?: IRunData;
} }
export interface SubworkflowExecutionInfo {
executionId: string;
workflowId?: string;
}
export interface ITableData { export interface ITableData {
columns: string[]; columns: string[];
data: GenericValue[][]; data: GenericValue[][];
hasJson: { [key: string]: boolean }; hasJson: { [key: string]: boolean };
metadata: { metadata: {
hasExecutionIds: boolean; hasExecutionIds: boolean;
data: Array<SubworkflowExecutionInfo | undefined>; data: Array<INodeExecutionData['metadata'] | undefined>;
}; };
} }

View file

@ -182,7 +182,7 @@ const nodeHelpers = useNodeHelpers();
const externalHooks = useExternalHooks(); const externalHooks = useExternalHooks();
const telemetry = useTelemetry(); const telemetry = useTelemetry();
const i18n = useI18n(); const i18n = useI18n();
const { openExecutionInNewTab } = useExecutionHelpers(); const { openRelatedExecution } = useExecutionHelpers();
const node = toRef(props, 'node'); const node = toRef(props, 'node');
@ -514,7 +514,6 @@ const subWorkflowData = computed((): ITaskMetadata | null => {
return null; return null;
} }
const metadata = get(workflowRunData.value, [node.value.name, props.runIndex, 'metadata'], null); const metadata = get(workflowRunData.value, [node.value.name, props.runIndex, 'metadata'], null);
console.log('yo', metadata);
if (!metadata?.parentExecution && !metadata?.subExecution) { if (!metadata?.parentExecution && !metadata?.subExecution) {
return null; return null;
} }
@ -1210,22 +1209,6 @@ function onSearchClear() {
document.dispatchEvent(new KeyboardEvent('keyup', { key: '/' })); document.dispatchEvent(new KeyboardEvent('keyup', { key: '/' }));
} }
function onOpenRelatedExecution({ parentExecution, subExecution }: ITaskMetadata) {
const info = parentExecution || subExecution;
if (!info) {
return;
}
openExecutionInNewTab(info.executionId, info.workflowId);
telemetry.track(
parentExecution ? 'User clicked parent execution button' : 'User clicked inspect sub-workflow',
{
view: displayMode.value,
},
);
}
defineExpose({ enterEditMode }); defineExpose({ enterEditMode });
</script> </script>
@ -1454,7 +1437,7 @@ defineExpose({ enterEditMode });
v-if="subWorkflowData && !(paneType === 'input' && hasInputOverwrite)" v-if="subWorkflowData && !(paneType === 'input' && hasInputOverwrite)"
:class="$style.parentExecutionInfo" :class="$style.parentExecutionInfo"
> >
<a @click.stop="onOpenRelatedExecution(subWorkflowData)"> <a @click.stop="openRelatedExecution(subWorkflowData, displayMode)">
<N8nIcon icon="external-link-alt" size="xsmall" /> <N8nIcon icon="external-link-alt" size="xsmall" />
{{ {{
subWorkflowData.parentExecution subWorkflowData.parentExecution

View file

@ -12,7 +12,6 @@ import { computed } from 'vue';
import NodeIcon from '@/components/NodeIcon.vue'; import NodeIcon from '@/components/NodeIcon.vue';
import AiRunContentBlock from './AiRunContentBlock.vue'; import AiRunContentBlock from './AiRunContentBlock.vue';
import { useExecutionHelpers } from '@/composables/useExecutionHelpers'; import { useExecutionHelpers } from '@/composables/useExecutionHelpers';
import { useTelemetry } from '@/composables/useTelemetry';
interface RunMeta { interface RunMeta {
startTimeMs: number; startTimeMs: number;
@ -33,9 +32,7 @@ const props = defineProps<{
const nodeTypesStore = useNodeTypesStore(); const nodeTypesStore = useNodeTypesStore();
const workflowsStore = useWorkflowsStore(); const workflowsStore = useWorkflowsStore();
const telemetry = useTelemetry(); const { openRelatedExecution } = useExecutionHelpers();
const { openExecutionInNewTab } = useExecutionHelpers();
type TokenUsageData = { type TokenUsageData = {
completionTokens: number; completionTokens: number;
@ -111,15 +108,6 @@ const outputError = computed(() => {
| NodeError | NodeError
| undefined; | undefined;
}); });
// todo unify function across components
function openExecution({ executionId, workflowId }: { workflowId: string; executionId: string }) {
openExecutionInNewTab(executionId, workflowId);
telemetry.track('User clicked inspect sub-workflow', {
view: 'ai',
});
}
</script> </script>
<template> <template>
@ -152,7 +140,7 @@ function openExecution({ executionId, workflowId }: { workflowId: string; execut
</n8n-tooltip> </n8n-tooltip>
</li> </li>
<li v-if="runMeta?.subExecution"> <li v-if="runMeta?.subExecution">
<a @click.stop="openExecution(runMeta.subExecution)"> <a @click.stop="openRelatedExecution(runMeta, 'ai')">
<N8nIcon icon="external-link-alt" size="xsmall" /> <N8nIcon icon="external-link-alt" size="xsmall" />
{{ $locale.baseText('runData.openSubExecution') }} {{ $locale.baseText('runData.openSubExecution') }}
</a> </a>

View file

@ -1,11 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { useExternalHooks } from '@/composables/useExternalHooks'; import { useExternalHooks } from '@/composables/useExternalHooks';
import type { import type { INodeUi, IRunDataDisplayMode, ITableData } from '@/Interface';
INodeUi,
IRunDataDisplayMode,
ITableData,
SubworkflowExecutionInfo,
} from '@/Interface';
import { useNDVStore } from '@/stores/ndv.store'; import { useNDVStore } from '@/stores/ndv.store';
import { useWorkflowsStore } from '@/stores/workflows.store'; import { useWorkflowsStore } from '@/stores/workflows.store';
import { getMappedExpression } from '@/utils/mappingUtils'; import { getMappedExpression } from '@/utils/mappingUtils';
@ -69,7 +64,7 @@ const workflowsStore = useWorkflowsStore();
const i18n = useI18n(); const i18n = useI18n();
const telemetry = useTelemetry(); const telemetry = useTelemetry();
const { openExecutionInNewTab } = useExecutionHelpers(); const { openRelatedExecution } = useExecutionHelpers();
const { const {
hoveringItem, hoveringItem,
@ -346,11 +341,8 @@ function convertToTable(inputData: INodeExecutionData[]): ITableData {
leftEntryColumns = entryColumns; leftEntryColumns = entryColumns;
} }
if (data.metadata?.executionId) { if (data.metadata?.subExecution) {
metadata.data.push({ metadata.data.push(data.metadata);
executionId: data.metadata.executionId,
workflowId: data.metadata?.workflowId,
});
metadata.hasExecutionIds = true; metadata.hasExecutionIds = true;
} else { } else {
metadata.data.push(undefined); metadata.data.push(undefined);
@ -410,14 +402,6 @@ function switchToJsonView() {
emit('displayModeChange', 'json'); emit('displayModeChange', 'json');
} }
function openExecution({ executionId, workflowId }: SubworkflowExecutionInfo) {
openExecutionInNewTab(executionId, workflowId);
telemetry.track('User clicked inspect sub-workflow', {
view: 'table',
});
}
watch(focusedMappableInput, (curr) => { watch(focusedMappableInput, (curr) => {
setTimeout( setTimeout(
() => { () => {
@ -562,7 +546,7 @@ watch(focusedMappableInput, (curr) => {
icon="external-link-alt" icon="external-link-alt"
data-test-id="debug-sub-execution" data-test-id="debug-sub-execution"
size="mini" size="mini"
@click="openExecution(tableData.metadata.data[index1])" @click="openRelatedExecution(tableData.metadata.data[index1], 'table')"
/> />
</td> </td>
<td <td

View file

@ -1,10 +1,10 @@
import type { ExecutionSummary } from 'n8n-workflow'; import type { ExecutionSummary, RelatedExecution } from 'n8n-workflow';
import { convertToDisplayDate } from '@/utils/formatters/dateFormatter'; import { convertToDisplayDate } from '@/utils/formatters/dateFormatter';
import { useI18n } from '@/composables/useI18n'; import { useI18n } from '@/composables/useI18n';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { VIEWS } from '@/constants'; import { VIEWS } from '@/constants';
import { useExecutionsStore } from '@/stores/executions.store'; import { useTelemetry } from './useTelemetry';
import { useToast } from './useToast'; import type { IRunDataDisplayMode } from '@/Interface';
export interface IExecutionUIData { export interface IExecutionUIData {
name: string; name: string;
@ -19,8 +19,7 @@ export interface IExecutionUIData {
export function useExecutionHelpers() { export function useExecutionHelpers() {
const i18n = useI18n(); const i18n = useI18n();
const router = useRouter(); const router = useRouter();
const executionsStore = useExecutionsStore(); const telemetry = useTelemetry();
const toast = useToast();
function getUIDetails(execution: ExecutionSummary): IExecutionUIData { function getUIDetails(execution: ExecutionSummary): IExecutionUIData {
const status = { const status = {
@ -76,35 +75,34 @@ export function useExecutionHelpers() {
return ['crashed', 'error'].includes(execution.status) && !execution.retrySuccessId; return ['crashed', 'error'].includes(execution.status) && !execution.retrySuccessId;
} }
function openInNewTab(executionId: string, workflowId: string) { function openExecutionInNewTab(executionId: string, workflowId: string): void {
const route = router.resolve({ const route = router.resolve({
name: VIEWS.EXECUTION_PREVIEW, name: VIEWS.EXECUTION_PREVIEW,
params: { name: workflowId, executionId }, params: { name: workflowId, executionId },
}); });
window.open(route.href, '_blank'); window.open(route.href, '_blank');
} }
async function openExecutionById(executionId: string): Promise<void> { function openRelatedExecution(
try { metadata: { parentExecution?: RelatedExecution; subExecution?: RelatedExecution },
const execution = (await executionsStore.fetchExecution(executionId)) as ExecutionSummary; view: IRunDataDisplayMode,
) {
openInNewTab(executionId, execution.workflowId); const info = metadata.parentExecution || metadata.subExecution;
} catch (e) { if (!info) {
toast.showMessage({
type: 'error',
message: i18n.baseText('nodeView.showError.openExecution.title'),
});
}
}
function openExecutionInNewTab(executionId: string, workflowId?: string): void {
// todo this does not work when workflowId is not set
if (!workflowId) {
void openExecutionById(executionId);
return; return;
} }
openInNewTab(executionId, workflowId); openExecutionInNewTab(info.executionId, info.workflowId);
telemetry.track(
metadata.parentExecution
? 'User clicked parent execution button'
: 'User clicked inspect sub-workflow',
{
view,
},
);
} }
return { return {
@ -112,5 +110,6 @@ export function useExecutionHelpers() {
formatDate, formatDate,
isExecutionRetriable, isExecutionRetriable,
openExecutionInNewTab, openExecutionInNewTab,
openRelatedExecution,
}; };
} }

View file

@ -211,6 +211,7 @@ export class ExecuteWorkflow implements INodeType {
const items = this.getInputData(); const items = this.getInputData();
const workflowProxy = this.getWorkflowDataProxy(0); const workflowProxy = this.getWorkflowDataProxy(0);
const currentWorkflowId = workflowProxy.$workflow.id as string;
if (mode === 'each') { if (mode === 'each') {
const returnData: INodeExecutionData[][] = []; const returnData: INodeExecutionData[][] = [];
@ -244,8 +245,10 @@ export class ExecuteWorkflow implements INodeType {
for (const item of outputData) { for (const item of outputData) {
item.pairedItem = { item: i }; item.pairedItem = { item: i };
item.metadata = { item.metadata = {
executionId: executionResult.executionId, subExecution: {
workflowId: workflowInfo.id, executionId: executionResult.executionId,
workflowId: workflowInfo.id ?? currentWorkflowId,
},
}; };
} }
@ -278,7 +281,10 @@ export class ExecuteWorkflow implements INodeType {
returnData[0].push({ returnData[0].push({
...items[i], ...items[i],
metadata: { metadata: {
executionId: executionResult.executionId, subExecution: {
workflowId: workflowInfo.id ?? currentWorkflowId,
executionId: executionResult.executionId,
},
}, },
}); });
} }

View file

@ -1215,8 +1215,7 @@ export interface INodeExecutionData {
error?: NodeApiError | NodeOperationError; error?: NodeApiError | NodeOperationError;
pairedItem?: IPairedItemData | IPairedItemData[] | number; pairedItem?: IPairedItemData | IPairedItemData[] | number;
metadata?: { metadata?: {
executionId?: string; subExecution: RelatedExecution;
workflowId?: string;
}; };
index?: number; index?: number;
} }
@ -2142,16 +2141,15 @@ export interface ITaskSubRunMetadata {
runIndex: number; runIndex: number;
} }
export interface RelatedExecution {
executionId: string;
workflowId: string;
}
export interface ITaskMetadata { export interface ITaskMetadata {
parentExecution?: {
executionId: string;
workflowId: string;
};
subExecution?: {
executionId: string;
workflowId: string;
};
subRun?: ITaskSubRunMetadata[]; subRun?: ITaskSubRunMetadata[];
parentExecution?: RelatedExecution;
subExecution?: RelatedExecution;
} }
// The data that gets returned when a node runs // The data that gets returned when a node runs