fix(core): Handle insights by workflow table for deleted workflows (#18496)

This commit is contained in:
Guillaume Jacquart
2025-08-18 17:49:21 +02:00
committed by GitHub
parent 9d48a44958
commit 741dd693a4
4 changed files with 47 additions and 22 deletions

View File

@@ -69,24 +69,40 @@ describe('insightsSummarySchema', () => {
}); });
describe('insightsByWorkflowSchema', () => { describe('insightsByWorkflowSchema', () => {
const validInsightsByWorkflow = {
count: 2,
data: [
{
workflowId: 'w1',
workflowName: 'Test Workflow',
projectId: 'p1',
projectName: 'Test Project',
total: 100,
succeeded: 90,
failed: 10,
failureRate: 0.56,
runTime: 300,
averageRunTime: 30.5,
timeSaved: 50,
},
],
};
test.each([ test.each([
{ {
name: 'valid workflow insights', name: 'valid workflow insights',
value: validInsightsByWorkflow,
expected: true,
},
{
name: 'workflow insights with nullable workflow id and project id',
value: { value: {
count: 2, ...validInsightsByWorkflow,
data: [ data: [
{ {
workflowId: 'w1', ...validInsightsByWorkflow.data[0],
workflowName: 'Test Workflow', workflowId: null,
projectId: 'p1', projectId: null,
projectName: 'Test Project',
total: 100,
succeeded: 90,
failed: 10,
failureRate: 0.56,
runTime: 300,
averageRunTime: 30.5,
timeSaved: 50,
}, },
], ],
}, },

View File

@@ -48,9 +48,11 @@ export const insightsByWorkflowDataSchemas = {
data: z.array( data: z.array(
z z
.object({ .object({
workflowId: z.string(), // Workflow id will be null if the workflow has been deleted
workflowId: z.string().nullable(),
workflowName: z.string(), workflowName: z.string(),
projectId: z.string(), // Project id will be null if the project has been deleted
projectId: z.string().nullable(),
projectName: z.string(), projectName: z.string(),
total: z.number(), total: z.number(),
succeeded: z.number(), succeeded: z.number(),

View File

@@ -30,9 +30,9 @@ const summaryParser = z
const aggregatedInsightsByWorkflowParser = z const aggregatedInsightsByWorkflowParser = z
.object({ .object({
workflowId: z.string(), workflowId: z.string().nullable(),
workflowName: z.string(), workflowName: z.string(),
projectId: z.string(), projectId: z.string().nullable(),
projectName: z.string(), projectName: z.string(),
total: z.union([z.number(), z.string()]).transform((value) => Number(value)), total: z.union([z.number(), z.string()]).transform((value) => Number(value)),
succeeded: z.union([z.number(), z.string()]).transform((value) => Number(value)), succeeded: z.union([z.number(), z.string()]).transform((value) => Number(value)),

View File

@@ -168,21 +168,28 @@ watch(sortBy, (newValue) => {
@update:options="emit('update:options', $event)" @update:options="emit('update:options', $event)"
> >
<template #[`item.workflowName`]="{ item }"> <template #[`item.workflowName`]="{ item }">
<router-link <component
:to="getWorkflowLink(item)" :is="item.workflowId ? 'router-link' : 'div'"
:class="$style.link" v-bind="
@click="trackWorkflowClick(item)" item.workflowId
? {
to: getWorkflowLink(item),
class: $style.link,
onClick: () => trackWorkflowClick(item),
}
: {}
"
> >
<N8nTooltip :content="item.workflowName" placement="top"> <N8nTooltip :content="item.workflowName" placement="top">
<div :class="$style.ellipsis"> <div :class="$style.ellipsis">
{{ item.workflowName }} {{ item.workflowName }}
</div> </div>
</N8nTooltip> </N8nTooltip>
</router-link> </component>
</template> </template>
<template #[`item.timeSaved`]="{ item, value }"> <template #[`item.timeSaved`]="{ item, value }">
<router-link <router-link
v-if="!item.timeSaved" v-if="!item.timeSaved && item.workflowId"
:to="getWorkflowLink(item, { settings: 'true' })" :to="getWorkflowLink(item, { settings: 'true' })"
:class="$style.link" :class="$style.link"
> >