n8n-editor-ui 1.75.1 → 1.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/assets/{AnnotationTagsDropdown.ee.vue_vue_type_script_setup_true_lang-BhRv3Xk0.js → AnnotationTagsDropdown.ee.vue_vue_type_script_setup_true_lang-DI9LKNPl.js} +1 -1
  2. package/dist/assets/{AuthView-vL9vjCvD.js → AuthView-DM7o3O4n.js} +2 -2
  3. package/dist/assets/{CanvasChat-B69VJDcA.js → CanvasChat-D_6gR76j.js} +19 -18
  4. package/dist/assets/{CanvasControls-DhhKk7yf.js → CanvasControls-Nhfb4Lvl.js} +1 -1
  5. package/dist/assets/{ChangePasswordView-D8y2rYLl.js → ChangePasswordView-BaAm4ZVG.js} +3 -3
  6. package/dist/assets/CollectionParameter-B6Y-W51v.js +4 -0
  7. package/dist/assets/{ConcurrentExecutionsHeader-Dv0s5rxY.js → ConcurrentExecutionsHeader-DIjBdza6.js} +2 -2
  8. package/dist/assets/{CredentialsView-Dp0fVbpZ.js → CredentialsView-Xu6hENWr.js} +4 -4
  9. package/dist/assets/{ErrorView-a6qq4rkt.js → ErrorView-DUTGEeMV.js} +1 -1
  10. package/dist/assets/{ExecutionsView-CpILe_1o.js → ExecutionsView-BUxJO71n.js} +17 -5
  11. package/dist/assets/{FileSaver.min-C1QTiJmy.js → FileSaver.min-BEdek61R.js} +1 -1
  12. package/dist/assets/{FixedCollectionParameter-DvdC-9QQ.css → FixedCollectionParameter-BReT5syB.css} +18 -18
  13. package/dist/assets/{FixedCollectionParameter-kphzKyyy.js → FixedCollectionParameter-C347CzJX.js} +27 -3
  14. package/dist/assets/{ForgotMyPasswordView-DzUekqel.js → ForgotMyPasswordView-COBAL4BR.js} +3 -3
  15. package/dist/assets/{Logo-B-pFOUGc.js → Logo-D0YIkpeq.js} +1 -1
  16. package/dist/assets/{MainHeader-C6S60KwG.js → MainHeader-C9fFpTj2.js} +15 -105
  17. package/dist/assets/{MainHeader-BIKp2Ncp.css → MainHeader-DC-g9NGP.css} +12 -11
  18. package/dist/assets/{MainSidebar-CJ-OKhK-.js → MainSidebar-DqTz49bY.js} +38 -81
  19. package/dist/assets/{NodeCreation-CNcty5fl.js → NodeCreation-BfPITu8g.js} +4 -4
  20. package/dist/assets/{NodeCreator-DAW2sX8p.js → NodeCreator-CK6kn0Jv.js} +4 -5
  21. package/dist/assets/{NodeViewSwitcher-mtWBt9cw.js → NodeViewSwitcher-Ccwulgc_.js} +164 -83
  22. package/dist/assets/{NodeViewSwitcher-CB1zkjni.css → NodeViewSwitcher-DApULbEt.css} +36 -39
  23. package/dist/assets/{ProjectCardBadge-DcWhzEr6.js → ProjectCardBadge-Dzk3JBiy.js} +2 -15
  24. package/dist/assets/{ProjectHeader-D2FCquSr.js → ProjectHeader-DScDlb97.js} +1 -1
  25. package/dist/assets/{ProjectSettings-CDg4IQw7.js → ProjectSettings-BKBT1ZQ3.js} +2 -2
  26. package/dist/assets/{PushConnectionTracker.vue_vue_type_script_setup_true_lang-BPBen7Li.js → PushConnectionTracker.vue_vue_type_script_setup_true_lang-vHkaCcgH.js} +1 -1
  27. package/dist/assets/{ResourcesListLayout-DWASP6Vp.js → ResourcesListLayout-Bm25PbPe.js} +21 -11
  28. package/dist/assets/{ResourcesListLayout-CJC-YvjD.css → ResourcesListLayout-d7mMNhOL.css} +6 -6
  29. package/dist/assets/{RunDataJson-CFNeORgR.js → RunDataJson-DdPA-vUg.js} +14 -15
  30. package/dist/assets/{RunDataJson-BXTLuo7i.css → RunDataJson-Txw0lqay.css} +1 -0
  31. package/dist/assets/{RunDataJsonActions-COFXneND.js → RunDataJsonActions-DQOpbX-O.js} +2 -2
  32. package/dist/assets/{RunDataSearch-D9UDSGjR.js → RunDataSearch-CouFZTIv.js} +1 -1
  33. package/dist/assets/{RunDataTable-C3flt0dy.js → RunDataTable-BTSlSsV8.js} +18 -20
  34. package/dist/assets/{SamlOnboarding-CWM-8qu7.js → SamlOnboarding-ByjacAW7.js} +3 -3
  35. package/dist/assets/{SettingsApiView-Bl6jvpWQ.js → SettingsApiView-Bcy_zE6E.js} +1 -1
  36. package/dist/assets/{SettingsCommunityNodesView-5Dl4EOzd.js → SettingsCommunityNodesView-Cjl8HKbz.js} +4 -4
  37. package/dist/assets/{SettingsExternalSecrets-DljwCjwW.js → SettingsExternalSecrets-BdjUgns5.js} +1 -1
  38. package/dist/assets/{SettingsLdapView-5kgLPxB7.js → SettingsLdapView-JZznK2gT.js} +1 -1
  39. package/dist/assets/{SettingsLogStreamingView-CsB-E4Kv.js → SettingsLogStreamingView-Dr-YFp2W.js} +1 -1
  40. package/dist/assets/{SettingsPersonalView-B0vJNuPt.js → SettingsPersonalView-inpY_nzK.js} +1 -1
  41. package/dist/assets/{SettingsSourceControl-B7SGpzBu.js → SettingsSourceControl-Cg7lS-SE.js} +1 -1
  42. package/dist/assets/{SettingsSso-pDsu2lsS.js → SettingsSso-NG13hUzi.js} +1 -1
  43. package/dist/assets/{SettingsUsageAndPlan-B83lunzH.js → SettingsUsageAndPlan-BgSLN2VF.js} +1 -1
  44. package/dist/assets/{SettingsUsersView-DPM5R_9p.js → SettingsUsersView-DUmnh2jo.js} +1 -1
  45. package/dist/assets/{SettingsView-NF_8zzqr.js → SettingsView-DdHGr_vR.js} +1 -1
  46. package/dist/assets/{SetupView-Dzehb2sC.js → SetupView-ByLBPzaO.js} +3 -3
  47. package/dist/assets/{SetupWorkflowCredentialsButton-Bhx7c9Lu.js → SetupWorkflowCredentialsButton-Dv3O2B1n.js} +3 -2
  48. package/dist/assets/{SetupWorkflowFromTemplateView-DaP6_l4S.js → SetupWorkflowFromTemplateView-DFn8kOzj.js} +3 -3
  49. package/dist/assets/{SigninView-BLyXzN0c.js → SigninView-DIJ4QhSe.js} +3 -3
  50. package/dist/assets/{SignoutView-BsaJctbQ.js → SignoutView-CzgpQ3SX.js} +1 -1
  51. package/dist/assets/{SignupView-m53hHk3y.js → SignupView-Ki2_QcUU.js} +3 -3
  52. package/dist/assets/{TemplateDetails-CWR4kXyf.js → TemplateDetails-BSeVX-wU.js} +1 -1
  53. package/dist/assets/{TemplateList-DLQxEmgt.js → TemplateList-CM9EZ6da.js} +1 -1
  54. package/dist/assets/{TemplatesCollectionView-CobxDh9v.js → TemplatesCollectionView-DQMG3Nx0.js} +5 -5
  55. package/dist/assets/{TemplatesSearchView-CDW7EH1p.js → TemplatesSearchView-BG5Bfpq9.js} +3 -3
  56. package/dist/assets/{TemplatesView-DJCodjB-.js → TemplatesView-D3vhmKK2.js} +1 -1
  57. package/dist/assets/{TemplatesWorkflowView-DOlLEzEa.js → TemplatesWorkflowView-BVZExmo-.js} +5 -5
  58. package/dist/assets/{TestDefinitionEditView-Cuphh86f.js → TestDefinitionEditView-DeYXSHuX.js} +837 -549
  59. package/dist/assets/{TestDefinitionEditView-FI1GVbhl.css → TestDefinitionEditView-d7yfvp9P.css} +601 -238
  60. package/dist/assets/{TestDefinitionListView-Dgq9dXJL.js → TestDefinitionListView-Dm0Wfpbk.js} +93 -68
  61. package/dist/assets/{TestDefinitionRootView-DU-JMBSH.js → TestDefinitionRootView-v_AUC4gJ.js} +1 -1
  62. package/dist/assets/VariablesView-BBjPCn4K.js +509 -0
  63. package/dist/assets/{VariablesView-D4pRzSuY.css → VariablesView-CIfrpJdg.css} +21 -54
  64. package/dist/assets/{WorkerView-CbqToUTB.js → WorkerView-wAx-DxZp.js} +5 -5
  65. package/dist/assets/{WorkflowActivator-BaM6Tydw.js → WorkflowActivator-KzTynbZM.js} +2 -2
  66. package/dist/assets/{WorkflowExecutionsInfoAccordion-6kKOPXK7.js → WorkflowExecutionsInfoAccordion-BWYv1FIv.js} +1 -1
  67. package/dist/assets/{WorkflowExecutionsLandingPage-Cqq5FeZE.js → WorkflowExecutionsLandingPage-LwIHX7rs.js} +2 -2
  68. package/dist/assets/{WorkflowExecutionsPreview-D1cSllVi.js → WorkflowExecutionsPreview-D68OCpWf.js} +8 -7
  69. package/dist/assets/{WorkflowExecutionsView-BUHtKz5M.css → WorkflowExecutionsView-BjdRnQOE.css} +32 -32
  70. package/dist/assets/{WorkflowExecutionsView-qTFEWbeC.js → WorkflowExecutionsView-C47WjaF2.js} +43 -29
  71. package/dist/assets/{WorkflowHistory-De54-QkN.js → WorkflowHistory-VBfitRhR.js} +3 -3
  72. package/dist/assets/{WorkflowOnboardingView-p6cAElRZ.js → WorkflowOnboardingView-X9Yz2kZe.js} +1 -31
  73. package/dist/assets/{WorkflowPreview-CKK96lnJ.js → WorkflowPreview-D0IqMbWq.js} +24 -6
  74. package/dist/assets/{WorkflowsView-D5G530AX.js → WorkflowsView-CXhmco5U.js} +7 -7
  75. package/dist/assets/{easyAiWorkflowUtils-eykvtlKm.js → easyAiWorkflowUtils-B7xBZAZO.js} +1 -1
  76. package/dist/assets/{index-CWcTt6jd.js → index-BW7gX0J2.js} +232838 -231981
  77. package/dist/assets/{index-DXFsvbJ_.css → index-Bs_8II2j.css} +257 -38
  78. package/dist/assets/{polyfills-BN5TIqPj.js → polyfills-DNwgos9f.js} +650 -0
  79. package/dist/assets/{pushConnection.store-CTrZ_kO6.js → pushConnection.store-C6PSl50Z.js} +1 -1
  80. package/dist/assets/{templateActions-B712CNo3.js → templateActions-BHlzMnfj.js} +1 -1
  81. package/dist/assets/useBeforeUnload-BudMrcxz.js +43 -0
  82. package/dist/assets/{useCanvasOperations-BSKKylIT.css → useCanvasOperations-CEWecDkR.css} +12 -12
  83. package/dist/assets/{useCanvasOperations-DTx4vbp_.js → useCanvasOperations-ZjLeZwpS.js} +62 -61
  84. package/dist/assets/{useExecutionDebugging-DjYGtT4w.js → useExecutionDebugging-C_Y6ee_L.js} +1 -1
  85. package/dist/assets/{useExecutionHelpers-DcyS3__o.js → useExecutionHelpers-MX6P-wr8.js} +1 -1
  86. package/dist/assets/{usePinnedData-C5NRkSpx.js → usePinnedData-CHMuwypo.js} +1 -1
  87. package/dist/assets/{usePushConnection-CGv57TM5.js → usePushConnection-3HzYJp1-.js} +3 -3
  88. package/dist/assets/{useRunWorkflow-C_vazd74.js → useRunWorkflow-DUK8ev8x.js} +19 -7
  89. package/dist/assets/{useWorkflowActivate-Dxi5zSSs.js → useWorkflowActivate-BjJ3P-qa.js} +1 -1
  90. package/dist/index.html +3 -3
  91. package/dist/static/n8n-logo.png +0 -0
  92. package/package.json +1 -1
  93. package/dist/assets/CollectionParameter-djLQ8MUO.js +0 -4
  94. package/dist/assets/VariablesView-CaGkZXjl.js +0 -599
  95. package/dist/assets/useBugReporting-BxDqzvRW.js +0 -38
  96. package/dist/assets/useNodeViewVersionSwitcher-CXU1PYlK.js +0 -93
@@ -1,184 +1,6 @@
1
- import { f as useCanvasOperations, d as useVueFlow, e as useCanvasMapping, _ as __unplugin_components_0 } from "./useCanvasOperations-DTx4vbp_.js";
2
- import { d as defineComponent, T as useWorkflowsStore, bp as useNodeTypesStore, U as useRoute, b as useRouter, r as ref, q as computed, o as onMounted, c as openBlock, h as createElementBlock, e as createBlock, n as normalizeClass, f as createCommentVNode, i as createVNode, w as withCtx, j as createBaseVNode, k as createTextVNode, t as toDisplayString, l as unref, aQ as N8nTooltip, g as useI18n, C as createEventBus, aa as useCssModule, m as resolveComponent, _ as _export_sfc, hM as useTestDefinitionStore, F as Fragment, s as renderSlot, ay as withDirectives, az as vShow, hN as ElCollapseTransition, y as nextTick, A as renderList, hG as _sfc_main$9, hO as __unplugin_components_0$1, J as useDebounce, a as useToast, hE as useAnnotationTagsStore, K as useUIStore, V as VIEWS, H as watch, hP as TestRunsTable, hQ as NODE_PINNING_MODAL_KEY, hR as Modal, hS as __unplugin_components_0$2 } from "./index-CWcTt6jd.js";
3
- import "./useBugReporting-BxDqzvRW.js";
4
- import "./usePinnedData-C5NRkSpx.js";
5
- const _sfc_main$8 = /* @__PURE__ */ defineComponent({
6
- __name: "NodesPinning",
7
- props: {
8
- modelValue: {}
9
- },
10
- emits: ["update:modelValue"],
11
- setup(__props, { emit: __emit }) {
12
- const workflowsStore = useWorkflowsStore();
13
- const nodeTypesStore = useNodeTypesStore();
14
- const route = useRoute();
15
- const router = useRouter();
16
- const locale = useI18n();
17
- const { resetWorkspace, initializeWorkspace } = useCanvasOperations({ router });
18
- const eventBus = createEventBus();
19
- const style = useCssModule();
20
- const uuid = crypto.randomUUID();
21
- const props = __props;
22
- const emit = __emit;
23
- const isLoading = ref(true);
24
- const workflowId = computed(() => route.params.name);
25
- const testId = computed(() => route.params.testId);
26
- const workflow = computed(() => workflowsStore.getWorkflowById(workflowId.value));
27
- const workflowObject = computed(() => workflowsStore.getCurrentWorkflow(true));
28
- const canvasId = computed(() => `${uuid}-${testId.value}`);
29
- const { onNodesInitialized, fitView, zoomTo } = useVueFlow({ id: canvasId.value });
30
- const nodes = computed(() => {
31
- return workflow.value.nodes ?? [];
32
- });
33
- const connections = computed(() => workflow.value.connections);
34
- const { nodes: mappedNodes, connections: mappedConnections } = useCanvasMapping({
35
- nodes,
36
- connections,
37
- workflowObject
38
- });
39
- async function loadData() {
40
- workflowsStore.resetState();
41
- resetWorkspace();
42
- const loadingPromise = Promise.all([
43
- nodeTypesStore.getNodeTypes(),
44
- workflowsStore.fetchWorkflow(workflowId.value)
45
- ]);
46
- await loadingPromise;
47
- initializeWorkspace(workflow.value);
48
- disableAllNodes();
49
- }
50
- function getNodeNameById(id) {
51
- return mappedNodes.value.find((node) => node.id === id)?.data?.name;
52
- }
53
- function updateNodeClasses(nodeIds, isPinned) {
54
- eventBus.emit("nodes:action", {
55
- ids: nodeIds,
56
- action: "update:node:class",
57
- payload: {
58
- className: style.pinnedNode,
59
- add: isPinned
60
- }
61
- });
62
- eventBus.emit("nodes:action", {
63
- ids: nodeIds,
64
- action: "update:node:class",
65
- payload: {
66
- className: style.notPinnedNode,
67
- add: !isPinned
68
- }
69
- });
70
- }
71
- function disableAllNodes() {
72
- const ids = mappedNodes.value.map((node) => node.id);
73
- updateNodeClasses(ids, false);
74
- const pinnedNodes = props.modelValue.map((node) => node.id).filter((id) => id !== null);
75
- if (pinnedNodes.length > 0) {
76
- updateNodeClasses(pinnedNodes, true);
77
- }
78
- }
79
- function onPinButtonClick(data) {
80
- const nodeName = getNodeNameById(data.id);
81
- if (!nodeName) return;
82
- const isPinned = props.modelValue.some((node) => node.id === data.id);
83
- const updatedNodes = isPinned ? props.modelValue.filter((node) => node.id !== data.id) : [...props.modelValue, { name: nodeName, id: data.id }];
84
- emit("update:modelValue", updatedNodes);
85
- updateNodeClasses([data.id], !isPinned);
86
- }
87
- function isPinButtonVisible(outputs) {
88
- return outputs.length === 1;
89
- }
90
- onNodesInitialized(async () => {
91
- await fitView();
92
- isLoading.value = false;
93
- await zoomTo(0.7, { duration: 400 });
94
- });
95
- onMounted(loadData);
96
- return (_ctx, _cache) => {
97
- const _component_N8nSpinner = resolveComponent("N8nSpinner");
98
- const _component_n8n_icon_button = resolveComponent("n8n-icon-button");
99
- const _component_Canvas = __unplugin_components_0;
100
- return openBlock(), createElementBlock("div", {
101
- class: normalizeClass(_ctx.$style.container)
102
- }, [
103
- isLoading.value ? (openBlock(), createBlock(_component_N8nSpinner, {
104
- key: 0,
105
- size: "xlarge",
106
- type: "dots",
107
- class: normalizeClass(_ctx.$style.spinner)
108
- }, null, 8, ["class"])) : createCommentVNode("", true),
109
- createVNode(_component_Canvas, {
110
- id: canvasId.value,
111
- loading: isLoading.value,
112
- class: normalizeClass({ [_ctx.$style.canvas]: true }),
113
- nodes: unref(mappedNodes),
114
- connections: unref(mappedConnections),
115
- "show-bug-reporting-button": false,
116
- "read-only": true,
117
- "event-bus": unref(eventBus)
118
- }, {
119
- nodeToolbar: withCtx(({ data, outputs }) => [
120
- createBaseVNode("div", {
121
- class: normalizeClass(_ctx.$style.pinButtonContainer)
122
- }, [
123
- isPinButtonVisible(outputs) ? (openBlock(), createBlock(unref(N8nTooltip), {
124
- key: 0,
125
- placement: "left"
126
- }, {
127
- content: withCtx(() => [
128
- createTextVNode(toDisplayString(unref(locale).baseText("testDefinition.edit.nodesPinning.pinButtonTooltip")), 1)
129
- ]),
130
- default: withCtx(() => [
131
- createVNode(_component_n8n_icon_button, {
132
- type: "tertiary",
133
- size: "large",
134
- icon: "thumbtack",
135
- class: normalizeClass(_ctx.$style.pinButton),
136
- "data-test-id": "node-pin-button",
137
- onClick: ($event) => onPinButtonClick(data)
138
- }, null, 8, ["class", "onClick"])
139
- ]),
140
- _: 2
141
- }, 1024)) : createCommentVNode("", true)
142
- ], 2)
143
- ]),
144
- _: 1
145
- }, 8, ["id", "loading", "class", "nodes", "connections", "event-bus"])
146
- ], 2);
147
- };
148
- }
149
- });
150
- const container$1 = "_container_1ogu0_123";
151
- const pinButtonContainer = "_pinButtonContainer_1ogu0_128";
152
- const pinButton = "_pinButton_1ogu0_128";
153
- const notPinnedNode = "_notPinnedNode_1ogu0_142";
154
- const pinnedNode = "_pinnedNode_1ogu0_143";
155
- const spinner = "_spinner_1ogu0_154";
156
- const style0$7 = {
157
- container: container$1,
158
- pinButtonContainer,
159
- pinButton,
160
- notPinnedNode,
161
- pinnedNode,
162
- spinner
163
- };
164
- const cssModules$7 = {
165
- "$style": style0$7
166
- };
167
- const __unplugin_components_2 = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__cssModules", cssModules$7]]);
168
- const arrowConnector = "_arrowConnector_1mi41_123";
169
- const style0$6 = {
170
- arrowConnector
171
- };
172
- const _sfc_main$7 = {};
173
- function _sfc_render(_ctx, _cache) {
174
- return openBlock(), createElementBlock("div", {
175
- class: normalizeClass(_ctx.$style.arrowConnector)
176
- }, null, 2);
177
- }
178
- const cssModules$6 = {
179
- "$style": style0$6
180
- };
181
- const __unplugin_components_1 = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render], ["__cssModules", cssModules$6]]);
1
+ import { hS as useTestDefinitionStore, r as ref, q as computed, d as defineComponent, c as openBlock, h as createElementBlock, F as Fragment, j as createBaseVNode, t as toDisplayString, n as normalizeClass, i as createVNode, e as createBlock, l as unref, g as useI18n, m as resolveComponent, _ as _export_sfc, f as createCommentVNode, w as withCtx, k as createTextVNode, hw as mergeModels, hx as useModel, s as renderSlot, hT as MetricsChart, hU as TestRunsTable, T as useWorkflowsStore, bo as useNodeTypesStore, U as useRoute, b as useRouter, o as onMounted, aP as N8nTooltip, C as createEventBus, aa as useCssModule, ax as withDirectives, ay as vShow, hV as ElCollapseTransition, y as nextTick, A as renderList, hK as _sfc_main$c, hW as __unplugin_components_0$2, hX as SAMPLE_EVALUATION_WORKFLOW, hY as NODE_PINNING_MODAL_KEY, hZ as __unplugin_components_2, J as useDebounce, a as useToast, hI as useAnnotationTagsStore, K as useUIStore, at as useExecutionsStore, V as VIEWS, H as watch } from "./index-BW7gX0J2.js";
2
+ import { f as useCanvasOperations, d as useVueFlow, e as useCanvasMapping, _ as __unplugin_components_0$1 } from "./useCanvasOperations-ZjLeZwpS.js";
3
+ import "./usePinnedData-CHMuwypo.js";
182
4
  function useTestDefinitionForm() {
183
5
  const evaluationsStore = useTestDefinitionStore();
184
6
  const state = ref({
@@ -206,7 +28,6 @@ function useTestDefinitionForm() {
206
28
  mockedNodes: []
207
29
  });
208
30
  const isSaving = ref(false);
209
- const fieldsIssues = ref([]);
210
31
  const fields = ref({});
211
32
  const editableFields = computed(() => ({
212
33
  name: state.value.name,
@@ -249,7 +70,6 @@ function useTestDefinitionForm() {
249
70
  const createTest = async (workflowId) => {
250
71
  if (isSaving.value) return;
251
72
  isSaving.value = true;
252
- fieldsIssues.value = [];
253
73
  try {
254
74
  const params = {
255
75
  name: state.value.name.value,
@@ -289,7 +109,6 @@ function useTestDefinitionForm() {
289
109
  const updateTest = async (testId) => {
290
110
  if (isSaving.value) return;
291
111
  isSaving.value = true;
292
- fieldsIssues.value = [];
293
112
  try {
294
113
  if (!testId) {
295
114
  throw new Error("Test ID is required for updating a test");
@@ -352,7 +171,6 @@ function useTestDefinitionForm() {
352
171
  state,
353
172
  fields,
354
173
  isSaving: computed(() => isSaving.value),
355
- fieldsIssues: computed(() => fieldsIssues.value),
356
174
  deleteMetric,
357
175
  updateMetrics,
358
176
  loadTestData,
@@ -364,8 +182,8 @@ function useTestDefinitionForm() {
364
182
  handleKeydown
365
183
  };
366
184
  }
367
- const _sfc_main$6 = /* @__PURE__ */ defineComponent({
368
- __name: "EvaluationHeader",
185
+ const _sfc_main$b = /* @__PURE__ */ defineComponent({
186
+ __name: "TestNameInput",
369
187
  props: {
370
188
  modelValue: {},
371
189
  startEditing: { type: Function },
@@ -378,62 +196,47 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
378
196
  return (_ctx, _cache) => {
379
197
  const _component_n8n_icon_button = resolveComponent("n8n-icon-button");
380
198
  const _component_N8nInput = resolveComponent("N8nInput");
381
- return openBlock(), createElementBlock("div", {
382
- class: normalizeClass(_ctx.$style.header)
199
+ return openBlock(), createElementBlock("h2", {
200
+ class: normalizeClass(_ctx.$style.title)
383
201
  }, [
384
- createVNode(_component_n8n_icon_button, {
385
- class: normalizeClass(_ctx.$style.backButton),
386
- icon: "arrow-left",
387
- type: "tertiary",
388
- title: unref(locale).baseText("testDefinition.edit.backButtonTitle"),
389
- onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$router.back())
390
- }, null, 8, ["class", "title"]),
391
- createBaseVNode("h2", {
392
- class: normalizeClass(_ctx.$style.title)
393
- }, [
394
- !_ctx.modelValue.isEditing ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
395
- createBaseVNode("span", {
396
- class: normalizeClass(_ctx.$style.titleText)
397
- }, toDisplayString(_ctx.modelValue.value), 3),
398
- createVNode(_component_n8n_icon_button, {
399
- class: normalizeClass(_ctx.$style.editInputButton),
400
- icon: "pen",
401
- type: "tertiary",
402
- onClick: _cache[1] || (_cache[1] = ($event) => _ctx.startEditing("name"))
403
- }, null, 8, ["class"])
404
- ], 64)) : (openBlock(), createBlock(_component_N8nInput, {
405
- key: 1,
406
- ref: "nameInput",
407
- "data-test-id": "evaluation-name-input",
408
- "model-value": _ctx.modelValue.tempValue,
409
- type: "text",
410
- placeholder: unref(locale).baseText("testDefinition.edit.namePlaceholder"),
411
- "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => _ctx.$emit("update:modelValue", { ..._ctx.modelValue, tempValue: $event })),
412
- onBlur: _cache[3] || (_cache[3] = () => _ctx.saveChanges("name")),
413
- onKeydown: _cache[4] || (_cache[4] = (e) => _ctx.handleKeydown(e, "name"))
414
- }, null, 8, ["model-value", "placeholder"]))
415
- ], 2)
202
+ !_ctx.modelValue.isEditing ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
203
+ createBaseVNode("span", {
204
+ class: normalizeClass(_ctx.$style.titleText)
205
+ }, toDisplayString(_ctx.modelValue.value), 3),
206
+ createVNode(_component_n8n_icon_button, {
207
+ class: normalizeClass(_ctx.$style.editInputButton),
208
+ icon: "pen",
209
+ type: "tertiary",
210
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.startEditing("name"))
211
+ }, null, 8, ["class"])
212
+ ], 64)) : (openBlock(), createBlock(_component_N8nInput, {
213
+ key: 1,
214
+ ref: "nameInput",
215
+ "data-test-id": "evaluation-name-input",
216
+ "model-value": _ctx.modelValue.tempValue,
217
+ type: "text",
218
+ placeholder: unref(locale).baseText("testDefinition.edit.namePlaceholder"),
219
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.$emit("update:modelValue", { ..._ctx.modelValue, tempValue: $event })),
220
+ onBlur: _cache[2] || (_cache[2] = () => _ctx.saveChanges("name")),
221
+ onKeydown: _cache[3] || (_cache[3] = (e) => _ctx.handleKeydown(e, "name"))
222
+ }, null, 8, ["model-value", "placeholder"]))
416
223
  ], 2);
417
224
  };
418
225
  }
419
226
  });
420
- const header$1 = "_header_qmfly_123";
421
- const editInputButton$2 = "_editInputButton_qmfly_127";
422
- const title$1 = "_title_qmfly_131";
423
- const titleText = "_titleText_qmfly_142";
424
- const backButton = "_backButton_qmfly_155";
425
- const style0$5 = {
426
- header: header$1,
427
- editInputButton: editInputButton$2,
227
+ const title$1 = "_title_1g2qi_123";
228
+ const titleText = "_titleText_1g2qi_133";
229
+ const editInputButton$2 = "_editInputButton_1g2qi_140";
230
+ const style0$a = {
428
231
  title: title$1,
429
232
  titleText,
430
- backButton
233
+ editInputButton: editInputButton$2
431
234
  };
432
- const cssModules$5 = {
433
- "$style": style0$5
235
+ const cssModules$a = {
236
+ "$style": style0$a
434
237
  };
435
- const EvaluationHeader = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__cssModules", cssModules$5]]);
436
- const _sfc_main$5 = /* @__PURE__ */ defineComponent({
238
+ const TestNameInput = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__cssModules", cssModules$a]]);
239
+ const _sfc_main$a = /* @__PURE__ */ defineComponent({
437
240
  __name: "DescriptionInput",
438
241
  props: {
439
242
  modelValue: {},
@@ -492,29 +295,413 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
492
295
  };
493
296
  }
494
297
  });
495
- const description$1 = "_description_f14k1_123";
496
- const editInputButton$1 = "_editInputButton_f14k1_129";
497
- const descriptionText = "_descriptionText_f14k1_133";
498
- const icon$1 = "_icon_f14k1_139";
499
- const style0$4 = {
500
- description: description$1,
501
- editInputButton: editInputButton$1,
502
- descriptionText,
503
- icon: icon$1
298
+ const description$1 = "_description_f14k1_123";
299
+ const editInputButton$1 = "_editInputButton_f14k1_129";
300
+ const descriptionText = "_descriptionText_f14k1_133";
301
+ const icon$1 = "_icon_f14k1_139";
302
+ const style0$9 = {
303
+ description: description$1,
304
+ editInputButton: editInputButton$1,
305
+ descriptionText,
306
+ icon: icon$1
307
+ };
308
+ const cssModules$9 = {
309
+ "$style": style0$9
310
+ };
311
+ const DescriptionInput = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__cssModules", cssModules$9]]);
312
+ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
313
+ __name: "HeaderSection",
314
+ props: /* @__PURE__ */ mergeModels({
315
+ hasRuns: { type: Boolean },
316
+ isSaving: { type: Boolean },
317
+ showConfig: { type: Boolean },
318
+ runTestEnabled: { type: Boolean },
319
+ startEditing: { type: Function },
320
+ saveChanges: { type: Function },
321
+ handleKeydown: { type: Function },
322
+ onSaveTest: { type: Function },
323
+ runTest: { type: Function },
324
+ toggleConfig: { type: Function },
325
+ getFieldIssues: { type: Function }
326
+ }, {
327
+ "name": { required: true },
328
+ "nameModifiers": {},
329
+ "description": { required: true },
330
+ "descriptionModifiers": {}
331
+ }),
332
+ emits: ["update:name", "update:description"],
333
+ setup(__props) {
334
+ const props = __props;
335
+ const name2 = useModel(__props, "name");
336
+ const description2 = useModel(__props, "description");
337
+ const locale = useI18n();
338
+ const showSavingIndicator = computed(() => {
339
+ return !name2.value.isEditing;
340
+ });
341
+ return (_ctx, _cache) => {
342
+ const _component_n8n_icon_button = resolveComponent("n8n-icon-button");
343
+ const _component_N8nButton = resolveComponent("N8nButton");
344
+ const _component_N8nTooltip = resolveComponent("N8nTooltip");
345
+ return openBlock(), createElementBlock("div", {
346
+ class: normalizeClass(_ctx.$style.headerSection)
347
+ }, [
348
+ createBaseVNode("div", {
349
+ class: normalizeClass(_ctx.$style.headerMeta)
350
+ }, [
351
+ createBaseVNode("div", {
352
+ class: normalizeClass(_ctx.$style.name)
353
+ }, [
354
+ createVNode(_component_n8n_icon_button, {
355
+ class: normalizeClass(_ctx.$style.backButton),
356
+ icon: "arrow-left",
357
+ type: "tertiary",
358
+ title: unref(locale).baseText("testDefinition.edit.backButtonTitle"),
359
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$router.back())
360
+ }, null, 8, ["class", "title"]),
361
+ createVNode(TestNameInput, {
362
+ modelValue: name2.value,
363
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => name2.value = $event),
364
+ class: normalizeClass({ "has-issues": _ctx.getFieldIssues("name").length > 0 }),
365
+ "start-editing": _ctx.startEditing,
366
+ "save-changes": _ctx.saveChanges,
367
+ "handle-keydown": _ctx.handleKeydown
368
+ }, null, 8, ["modelValue", "class", "start-editing", "save-changes", "handle-keydown"]),
369
+ showSavingIndicator.value ? (openBlock(), createElementBlock("div", {
370
+ key: 0,
371
+ class: normalizeClass(_ctx.$style.lastSaved)
372
+ }, [
373
+ _ctx.isSaving ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
374
+ createTextVNode(toDisplayString(unref(locale).baseText("testDefinition.edit.saving")), 1)
375
+ ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
376
+ createTextVNode(toDisplayString(unref(locale).baseText("testDefinition.edit.saved")), 1)
377
+ ], 64))
378
+ ], 2)) : createCommentVNode("", true)
379
+ ], 2),
380
+ createVNode(DescriptionInput, {
381
+ modelValue: description2.value,
382
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => description2.value = $event),
383
+ "start-editing": _ctx.startEditing,
384
+ "save-changes": _ctx.saveChanges,
385
+ "handle-keydown": _ctx.handleKeydown,
386
+ class: normalizeClass(_ctx.$style.descriptionInput)
387
+ }, null, 8, ["modelValue", "start-editing", "save-changes", "handle-keydown", "class"])
388
+ ], 2),
389
+ createBaseVNode("div", {
390
+ class: normalizeClass(_ctx.$style.controls)
391
+ }, [
392
+ props.hasRuns ? (openBlock(), createBlock(_component_N8nButton, {
393
+ key: 0,
394
+ size: "small",
395
+ icon: _ctx.showConfig ? "eye-slash" : "eye",
396
+ "data-test-id": "toggle-config-button",
397
+ label: _ctx.showConfig ? unref(locale).baseText("testDefinition.edit.hideConfig") : unref(locale).baseText("testDefinition.edit.showConfig"),
398
+ type: "tertiary",
399
+ onClick: _ctx.toggleConfig
400
+ }, null, 8, ["icon", "label", "onClick"])) : createCommentVNode("", true),
401
+ createVNode(_component_N8nTooltip, {
402
+ disabled: _ctx.runTestEnabled,
403
+ placement: "left"
404
+ }, {
405
+ content: withCtx(() => [
406
+ renderSlot(_ctx.$slots, "runTestTooltip")
407
+ ]),
408
+ default: withCtx(() => [
409
+ createVNode(_component_N8nButton, {
410
+ disabled: !_ctx.runTestEnabled,
411
+ class: normalizeClass(_ctx.$style.runTestButton),
412
+ size: "small",
413
+ "data-test-id": "run-test-button",
414
+ label: unref(locale).baseText("testDefinition.runTest"),
415
+ type: "primary",
416
+ onClick: _ctx.runTest
417
+ }, null, 8, ["disabled", "class", "label", "onClick"])
418
+ ]),
419
+ _: 3
420
+ }, 8, ["disabled"])
421
+ ], 2)
422
+ ], 2);
423
+ };
424
+ }
425
+ });
426
+ const headerSection = "_headerSection_28wt7_123";
427
+ const headerMeta = "_headerMeta_28wt7_131";
428
+ const name = "_name_28wt7_135";
429
+ const lastSaved = "_lastSaved_28wt7_140";
430
+ const descriptionInput = "_descriptionInput_28wt7_145";
431
+ const controls = "_controls_28wt7_149";
432
+ const backButton = "_backButton_28wt7_154";
433
+ const style0$8 = {
434
+ headerSection,
435
+ headerMeta,
436
+ name,
437
+ lastSaved,
438
+ descriptionInput,
439
+ controls,
440
+ backButton
441
+ };
442
+ const cssModules$8 = {
443
+ "$style": style0$8
444
+ };
445
+ const HeaderSection = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__cssModules", cssModules$8]]);
446
+ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
447
+ __name: "RunsSection",
448
+ props: /* @__PURE__ */ mergeModels({
449
+ runs: {},
450
+ testId: {},
451
+ appliedTheme: {}
452
+ }, {
453
+ "selectedMetric": { required: true },
454
+ "selectedMetricModifiers": {}
455
+ }),
456
+ emits: /* @__PURE__ */ mergeModels(["deleteRuns"], ["update:selectedMetric"]),
457
+ setup(__props, { emit: __emit }) {
458
+ const emit = __emit;
459
+ const selectedMetric = useModel(__props, "selectedMetric");
460
+ function onDeleteRuns(toDelete) {
461
+ emit("deleteRuns", toDelete);
462
+ }
463
+ return (_ctx, _cache) => {
464
+ return openBlock(), createElementBlock("div", {
465
+ class: normalizeClass(_ctx.$style.runs)
466
+ }, [
467
+ createVNode(MetricsChart, {
468
+ selectedMetric: selectedMetric.value,
469
+ "onUpdate:selectedMetric": _cache[0] || (_cache[0] = ($event) => selectedMetric.value = $event),
470
+ runs: _ctx.runs,
471
+ theme: _ctx.appliedTheme
472
+ }, null, 8, ["selectedMetric", "runs", "theme"]),
473
+ createVNode(TestRunsTable, {
474
+ class: normalizeClass(_ctx.$style.runsTable),
475
+ runs: _ctx.runs,
476
+ selectable: true,
477
+ "data-test-id": "past-runs-table",
478
+ onDeleteRuns
479
+ }, null, 8, ["class", "runs"])
480
+ ], 2);
481
+ };
482
+ }
483
+ });
484
+ const runs = "_runs_1llgd_123";
485
+ const style0$7 = {
486
+ runs
487
+ };
488
+ const cssModules$7 = {
489
+ "$style": style0$7
490
+ };
491
+ const RunsSection = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__cssModules", cssModules$7]]);
492
+ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
493
+ __name: "NodesPinning",
494
+ props: {
495
+ modelValue: {}
496
+ },
497
+ emits: ["update:modelValue"],
498
+ setup(__props, { emit: __emit }) {
499
+ const workflowsStore = useWorkflowsStore();
500
+ const nodeTypesStore = useNodeTypesStore();
501
+ const route = useRoute();
502
+ const router = useRouter();
503
+ const locale = useI18n();
504
+ const { resetWorkspace, initializeWorkspace } = useCanvasOperations({ router });
505
+ const eventBus = createEventBus();
506
+ const style = useCssModule();
507
+ const uuid = crypto.randomUUID();
508
+ const props = __props;
509
+ const emit = __emit;
510
+ const isLoading = ref(true);
511
+ const workflowId = computed(() => route.params.name);
512
+ const testId = computed(() => route.params.testId);
513
+ const workflow = computed(() => workflowsStore.getWorkflowById(workflowId.value));
514
+ const workflowObject = computed(() => workflowsStore.getCurrentWorkflow(true));
515
+ const canvasId = computed(() => `${uuid}-${testId.value}`);
516
+ const { onNodesInitialized, fitView, zoomTo } = useVueFlow({ id: canvasId.value });
517
+ const nodes = computed(() => {
518
+ return workflow.value.nodes ?? [];
519
+ });
520
+ const connections = computed(() => workflow.value.connections);
521
+ const { nodes: mappedNodes, connections: mappedConnections } = useCanvasMapping({
522
+ nodes,
523
+ connections,
524
+ workflowObject
525
+ });
526
+ async function loadData() {
527
+ workflowsStore.resetState();
528
+ resetWorkspace();
529
+ const loadingPromise = Promise.all([
530
+ nodeTypesStore.getNodeTypes(),
531
+ workflowsStore.fetchWorkflow(workflowId.value)
532
+ ]);
533
+ await loadingPromise;
534
+ initializeWorkspace(workflow.value);
535
+ disableAllNodes();
536
+ }
537
+ function getNodeNameById(id) {
538
+ return mappedNodes.value.find((node) => node.id === id)?.data?.name;
539
+ }
540
+ function updateNodeClasses(nodeIds, isPinned) {
541
+ eventBus.emit("nodes:action", {
542
+ ids: nodeIds,
543
+ action: "update:node:class",
544
+ payload: {
545
+ className: style.pinnedNode,
546
+ add: isPinned
547
+ }
548
+ });
549
+ eventBus.emit("nodes:action", {
550
+ ids: nodeIds,
551
+ action: "update:node:class",
552
+ payload: {
553
+ className: style.notPinnedNode,
554
+ add: !isPinned
555
+ }
556
+ });
557
+ }
558
+ function disableAllNodes() {
559
+ const ids = mappedNodes.value.map((node) => node.id);
560
+ updateNodeClasses(ids, false);
561
+ const pinnedNodes = props.modelValue.map((node) => node.id).filter((id) => id !== null);
562
+ if (pinnedNodes.length > 0) {
563
+ updateNodeClasses(pinnedNodes, true);
564
+ }
565
+ }
566
+ function onPinButtonClick(data) {
567
+ const nodeName = getNodeNameById(data.id);
568
+ if (!nodeName) return;
569
+ const isPinned = props.modelValue.some((node) => node.id === data.id);
570
+ const updatedNodes = isPinned ? props.modelValue.filter((node) => node.id !== data.id) : [...props.modelValue, { name: nodeName, id: data.id }];
571
+ emit("update:modelValue", updatedNodes);
572
+ updateNodeClasses([data.id], !isPinned);
573
+ }
574
+ function isPinButtonVisible(outputs) {
575
+ return outputs.length === 1;
576
+ }
577
+ onNodesInitialized(async () => {
578
+ await fitView();
579
+ isLoading.value = false;
580
+ await zoomTo(0.7, { duration: 400 });
581
+ });
582
+ onMounted(loadData);
583
+ return (_ctx, _cache) => {
584
+ const _component_N8nHeading = resolveComponent("N8nHeading");
585
+ const _component_N8nText = resolveComponent("N8nText");
586
+ const _component_N8nSpinner = resolveComponent("N8nSpinner");
587
+ const _component_n8n_icon_button = resolveComponent("n8n-icon-button");
588
+ const _component_Canvas = __unplugin_components_0$1;
589
+ return unref(mappedNodes).length === 0 ? (openBlock(), createElementBlock("div", {
590
+ key: 0,
591
+ class: normalizeClass(_ctx.$style.noNodes)
592
+ }, [
593
+ createVNode(_component_N8nHeading, {
594
+ size: "large",
595
+ bold: true,
596
+ class: normalizeClass(_ctx.$style.noNodesTitle)
597
+ }, {
598
+ default: withCtx(() => [
599
+ createTextVNode(toDisplayString(unref(locale).baseText("testDefinition.edit.pinNodes.noNodes.title")), 1)
600
+ ]),
601
+ _: 1
602
+ }, 8, ["class"]),
603
+ createVNode(_component_N8nText, null, {
604
+ default: withCtx(() => [
605
+ createTextVNode(toDisplayString(unref(locale).baseText("testDefinition.edit.pinNodes.noNodes.description")), 1)
606
+ ]),
607
+ _: 1
608
+ })
609
+ ], 2)) : (openBlock(), createElementBlock("div", {
610
+ key: 1,
611
+ class: normalizeClass(_ctx.$style.container)
612
+ }, [
613
+ isLoading.value ? (openBlock(), createBlock(_component_N8nSpinner, {
614
+ key: 0,
615
+ size: "xlarge",
616
+ type: "dots",
617
+ class: normalizeClass(_ctx.$style.spinner)
618
+ }, null, 8, ["class"])) : createCommentVNode("", true),
619
+ createVNode(_component_Canvas, {
620
+ id: canvasId.value,
621
+ loading: isLoading.value,
622
+ class: normalizeClass({ [_ctx.$style.canvas]: true }),
623
+ nodes: unref(mappedNodes),
624
+ connections: unref(mappedConnections),
625
+ "show-bug-reporting-button": false,
626
+ "read-only": true,
627
+ "event-bus": unref(eventBus)
628
+ }, {
629
+ nodeToolbar: withCtx(({ data, outputs }) => [
630
+ createBaseVNode("div", {
631
+ class: normalizeClass(_ctx.$style.pinButtonContainer)
632
+ }, [
633
+ isPinButtonVisible(outputs) ? (openBlock(), createBlock(unref(N8nTooltip), {
634
+ key: 0,
635
+ placement: "left"
636
+ }, {
637
+ content: withCtx(() => [
638
+ createTextVNode(toDisplayString(unref(locale).baseText("testDefinition.edit.nodesPinning.pinButtonTooltip")), 1)
639
+ ]),
640
+ default: withCtx(() => [
641
+ createVNode(_component_n8n_icon_button, {
642
+ type: "tertiary",
643
+ size: "large",
644
+ icon: "thumbtack",
645
+ class: normalizeClass(_ctx.$style.pinButton),
646
+ "data-test-id": "node-pin-button",
647
+ onClick: ($event) => onPinButtonClick(data)
648
+ }, null, 8, ["class", "onClick"])
649
+ ]),
650
+ _: 2
651
+ }, 1024)) : createCommentVNode("", true)
652
+ ], 2)
653
+ ]),
654
+ _: 1
655
+ }, 8, ["id", "loading", "class", "nodes", "connections", "event-bus"])
656
+ ], 2));
657
+ };
658
+ }
659
+ });
660
+ const container$1 = "_container_108jn_123";
661
+ const pinButtonContainer = "_pinButtonContainer_108jn_128";
662
+ const pinButton = "_pinButton_108jn_128";
663
+ const notPinnedNode = "_notPinnedNode_108jn_142";
664
+ const pinnedNode = "_pinnedNode_108jn_143";
665
+ const spinner = "_spinner_108jn_154";
666
+ const noNodes = "_noNodes_108jn_161";
667
+ const style0$6 = {
668
+ container: container$1,
669
+ pinButtonContainer,
670
+ pinButton,
671
+ notPinnedNode,
672
+ pinnedNode,
673
+ spinner,
674
+ noNodes
504
675
  };
505
- const cssModules$4 = {
506
- "$style": style0$4
676
+ const cssModules$6 = {
677
+ "$style": style0$6
678
+ };
679
+ const __unplugin_components_1 = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__cssModules", cssModules$6]]);
680
+ const arrowConnector = "_arrowConnector_1mi41_123";
681
+ const style0$5 = {
682
+ arrowConnector
683
+ };
684
+ const _sfc_main$6 = {};
685
+ function _sfc_render(_ctx, _cache) {
686
+ return openBlock(), createElementBlock("div", {
687
+ class: normalizeClass(_ctx.$style.arrowConnector)
688
+ }, null, 2);
689
+ }
690
+ const cssModules$5 = {
691
+ "$style": style0$5
507
692
  };
508
- const DescriptionInput = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__cssModules", cssModules$4]]);
693
+ const __unplugin_components_0 = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render], ["__cssModules", cssModules$5]]);
509
694
  const _hoisted_1$1 = ["aria-expanded", "aria-controls"];
510
- const _sfc_main$4 = /* @__PURE__ */ defineComponent({
695
+ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
511
696
  __name: "EvaluationStep",
512
697
  props: {
513
698
  title: {},
514
699
  warning: { type: Boolean, default: false },
515
700
  small: { type: Boolean, default: false },
516
701
  expanded: { type: Boolean, default: true },
517
- description: { default: "" }
702
+ description: { default: "" },
703
+ issues: { default: () => [] },
704
+ showIssues: { type: Boolean, default: true }
518
705
  },
519
706
  setup(__props) {
520
707
  const props = __props;
@@ -532,6 +719,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
532
719
  }
533
720
  };
534
721
  return (_ctx, _cache) => {
722
+ const _component_N8nInfoTip = resolveComponent("N8nInfoTip");
535
723
  const _component_font_awesome_icon = resolveComponent("font-awesome-icon");
536
724
  return openBlock(), createElementBlock("div", {
537
725
  ref_key: "containerRef",
@@ -553,10 +741,22 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
553
741
  createBaseVNode("h3", {
554
742
  class: normalizeClass(_ctx.$style.title)
555
743
  }, toDisplayString(_ctx.title), 3),
556
- _ctx.warning ? (openBlock(), createElementBlock("span", {
744
+ _ctx.issues.length > 0 && _ctx.showIssues ? (openBlock(), createElementBlock("span", {
557
745
  key: 0,
558
746
  class: normalizeClass(_ctx.$style.warningIcon)
559
- }, "⚠", 2)) : createCommentVNode("", true),
747
+ }, [
748
+ createVNode(_component_N8nInfoTip, {
749
+ bold: true,
750
+ type: "tooltip",
751
+ theme: "warning",
752
+ "tooltip-placement": "right"
753
+ }, {
754
+ default: withCtx(() => [
755
+ createTextVNode(toDisplayString(_ctx.issues.map((issue) => issue.message).join(", ")), 1)
756
+ ]),
757
+ _: 1
758
+ })
759
+ ], 2)) : createCommentVNode("", true),
560
760
  _ctx.$slots.cardContent ? (openBlock(), createElementBlock("button", {
561
761
  key: 1,
562
762
  class: normalizeClass(_ctx.$style.collapseButton),
@@ -612,7 +812,7 @@ const cardContent = "_cardContent_65xdl_174";
612
812
  const collapseButton = "_collapseButton_65xdl_179";
613
813
  const cardContentWrapper = "_cardContentWrapper_65xdl_192";
614
814
  const description = "_description_65xdl_196";
615
- const style0$3 = {
815
+ const style0$4 = {
616
816
  evaluationStep,
617
817
  small,
618
818
  icon,
@@ -626,12 +826,12 @@ const style0$3 = {
626
826
  cardContentWrapper,
627
827
  description
628
828
  };
629
- const cssModules$3 = {
630
- "$style": style0$3
829
+ const cssModules$4 = {
830
+ "$style": style0$4
631
831
  };
632
- const EvaluationStep = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__cssModules", cssModules$3]]);
832
+ const EvaluationStep = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__cssModules", cssModules$4]]);
633
833
  const _hoisted_1 = { "data-test-id": "workflow-tags-field" };
634
- const _sfc_main$3 = /* @__PURE__ */ defineComponent({
834
+ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
635
835
  __name: "TagsInput",
636
836
  props: {
637
837
  modelValue: { default: () => ({
@@ -666,7 +866,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
666
866
  const _component_n8n_text = resolveComponent("n8n-text");
667
867
  const _component_n8n_tag = resolveComponent("n8n-tag");
668
868
  const _component_n8n_icon_button = resolveComponent("n8n-icon-button");
669
- const _component_TagsDropdown = _sfc_main$9;
869
+ const _component_TagsDropdown = _sfc_main$c;
670
870
  const _component_n8n_input_label = resolveComponent("n8n-input-label");
671
871
  return openBlock(), createElementBlock("div", _hoisted_1, [
672
872
  createVNode(_component_n8n_input_label, {
@@ -729,28 +929,46 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
729
929
  });
730
930
  const tagsRead = "_tagsRead_z5pm4_123";
731
931
  const editInputButton = "_editInputButton_z5pm4_123";
732
- const style0$2 = {
932
+ const style0$3 = {
733
933
  tagsRead,
734
934
  editInputButton
735
935
  };
736
- const cssModules$2 = {
737
- "$style": style0$2
936
+ const cssModules$3 = {
937
+ "$style": style0$3
738
938
  };
739
- const TagsInput = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__cssModules", cssModules$2]]);
740
- const _sfc_main$2 = /* @__PURE__ */ defineComponent({
939
+ const TagsInput = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__cssModules", cssModules$3]]);
940
+ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
741
941
  __name: "WorkflowSelector",
742
942
  props: {
743
943
  modelValue: { default: () => ({
744
944
  mode: "id",
745
945
  value: "",
746
946
  __rl: true
747
- }) }
947
+ }) },
948
+ examplePinnedData: { default: () => ({}) },
949
+ sampleWorkflowName: { default: void 0 }
748
950
  },
749
951
  emits: ["update:modelValue"],
750
952
  setup(__props) {
953
+ const props = __props;
751
954
  const locale = useI18n();
955
+ const subworkflowName = computed(() => {
956
+ if (props.sampleWorkflowName) {
957
+ return locale.baseText("testDefinition.workflowInput.subworkflowName", {
958
+ interpolate: { name: props.sampleWorkflowName }
959
+ });
960
+ }
961
+ return locale.baseText("testDefinition.workflowInput.subworkflowName.default");
962
+ });
963
+ const sampleWorkflow = computed(() => {
964
+ return {
965
+ ...SAMPLE_EVALUATION_WORKFLOW,
966
+ name: subworkflowName.value,
967
+ pinData: props.examplePinnedData
968
+ };
969
+ });
752
970
  return (_ctx, _cache) => {
753
- const _component_WorkflowSelectorParameterInput = __unplugin_components_0$1;
971
+ const _component_WorkflowSelectorParameterInput = __unplugin_components_0$2;
754
972
  const _component_n8n_input_label = resolveComponent("n8n-input-label");
755
973
  return openBlock(), createElementBlock("div", null, [
756
974
  createVNode(_component_n8n_input_label, {
@@ -772,8 +990,9 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
772
990
  "expression-edit-dialog-visible": false,
773
991
  path: "workflows",
774
992
  "allow-new": "",
993
+ "sample-workflow": sampleWorkflow.value,
775
994
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:modelValue", $event))
776
- }, null, 8, ["parameter", "model-value", "display-title"])
995
+ }, null, 8, ["parameter", "model-value", "display-title", "sample-workflow"])
777
996
  ]),
778
997
  _: 1
779
998
  }, 8, ["label"])
@@ -781,7 +1000,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
781
1000
  };
782
1001
  }
783
1002
  });
784
- const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1003
+ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
785
1004
  __name: "MetricsInput",
786
1005
  props: {
787
1006
  modelValue: {}
@@ -858,17 +1077,266 @@ const metricItem = "_metricItem_1eaf8_129";
858
1077
  const metricField = "_metricField_1eaf8_134";
859
1078
  const metricsDivider = "_metricsDivider_1eaf8_139";
860
1079
  const newMetricButton = "_newMetricButton_1eaf8_144";
861
- const style0$1 = {
1080
+ const style0$2 = {
862
1081
  metricsContainer,
863
1082
  metricItem,
864
1083
  metricField,
865
1084
  metricsDivider,
866
1085
  newMetricButton
867
1086
  };
1087
+ const cssModules$2 = {
1088
+ "$style": style0$2
1089
+ };
1090
+ const MetricsInput = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__cssModules", cssModules$2]]);
1091
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1092
+ __name: "ConfigSection",
1093
+ props: /* @__PURE__ */ mergeModels({
1094
+ showConfig: { type: Boolean },
1095
+ tagUsageCount: {},
1096
+ allTags: {},
1097
+ tagsById: {},
1098
+ isLoading: { type: Boolean },
1099
+ examplePinnedData: {},
1100
+ sampleWorkflowName: {},
1101
+ getFieldIssues: { type: Function },
1102
+ startEditing: { type: Function },
1103
+ saveChanges: { type: Function },
1104
+ cancelEditing: { type: Function },
1105
+ createTag: { type: Function }
1106
+ }, {
1107
+ "tags": { required: true },
1108
+ "tagsModifiers": {},
1109
+ "evaluationWorkflow": { required: true },
1110
+ "evaluationWorkflowModifiers": {},
1111
+ "metrics": { required: true },
1112
+ "metricsModifiers": {},
1113
+ "mockedNodes": {
1114
+ required: true
1115
+ },
1116
+ "mockedNodesModifiers": {}
1117
+ }),
1118
+ emits: /* @__PURE__ */ mergeModels(["openPinningModal", "deleteMetric"], ["update:tags", "update:evaluationWorkflow", "update:metrics", "update:mockedNodes"]),
1119
+ setup(__props, { emit: __emit }) {
1120
+ const emit = __emit;
1121
+ const locale = useI18n();
1122
+ const changedFieldsKeys = ref([]);
1123
+ const tags = useModel(__props, "tags");
1124
+ const evaluationWorkflow = useModel(
1125
+ __props,
1126
+ "evaluationWorkflow"
1127
+ );
1128
+ const metrics = useModel(__props, "metrics");
1129
+ const mockedNodes = useModel(__props, "mockedNodes");
1130
+ const nodePinningModal = ref(null);
1131
+ function updateChangedFieldsKeys(key) {
1132
+ changedFieldsKeys.value.push(key);
1133
+ }
1134
+ function showFieldIssues(fieldKey) {
1135
+ return changedFieldsKeys.value.includes(fieldKey);
1136
+ }
1137
+ return (_ctx, _cache) => {
1138
+ const _component_BlockArrow = __unplugin_components_0;
1139
+ const _component_font_awesome_icon = resolveComponent("font-awesome-icon");
1140
+ const _component_n8n_button = resolveComponent("n8n-button");
1141
+ const _component_N8nHeading = resolveComponent("N8nHeading");
1142
+ const _component_NodesPinning = __unplugin_components_1;
1143
+ const _component_Modal = __unplugin_components_2;
1144
+ return openBlock(), createElementBlock("div", {
1145
+ class: normalizeClass([_ctx.$style.panelBlock, { [_ctx.$style.hidden]: !_ctx.showConfig }])
1146
+ }, [
1147
+ createBaseVNode("div", {
1148
+ class: normalizeClass(_ctx.$style.panelIntro)
1149
+ }, toDisplayString(unref(locale).baseText("testDefinition.edit.step.intro")), 3),
1150
+ createVNode(_component_BlockArrow, {
1151
+ class: normalizeClass(_ctx.$style.introArrow)
1152
+ }, null, 8, ["class"]),
1153
+ createVNode(EvaluationStep, {
1154
+ class: normalizeClass(_ctx.$style.step),
1155
+ title: unref(locale).baseText("testDefinition.edit.step.executions", {
1156
+ adjustToNumber: _ctx.tagUsageCount
1157
+ }),
1158
+ description: unref(locale).baseText("testDefinition.edit.step.executions.description"),
1159
+ issues: _ctx.getFieldIssues("tags"),
1160
+ "show-issues": showFieldIssues("tags")
1161
+ }, {
1162
+ icon: withCtx(() => [
1163
+ createVNode(_component_font_awesome_icon, {
1164
+ icon: "history",
1165
+ size: "lg"
1166
+ })
1167
+ ]),
1168
+ cardContent: withCtx(() => [
1169
+ createVNode(TagsInput, {
1170
+ modelValue: tags.value,
1171
+ "onUpdate:modelValue": [
1172
+ _cache[0] || (_cache[0] = ($event) => tags.value = $event),
1173
+ _cache[1] || (_cache[1] = ($event) => updateChangedFieldsKeys("tags"))
1174
+ ],
1175
+ class: normalizeClass({ "has-issues": _ctx.getFieldIssues("tags") }),
1176
+ "all-tags": _ctx.allTags,
1177
+ "tags-by-id": _ctx.tagsById,
1178
+ "is-loading": _ctx.isLoading,
1179
+ "start-editing": _ctx.startEditing,
1180
+ "save-changes": _ctx.saveChanges,
1181
+ "cancel-editing": _ctx.cancelEditing,
1182
+ "create-tag": _ctx.createTag
1183
+ }, null, 8, ["modelValue", "class", "all-tags", "tags-by-id", "is-loading", "start-editing", "save-changes", "cancel-editing", "create-tag"])
1184
+ ]),
1185
+ _: 1
1186
+ }, 8, ["class", "title", "description", "issues", "show-issues"]),
1187
+ createBaseVNode("div", {
1188
+ class: normalizeClass(_ctx.$style.evaluationArrows)
1189
+ }, [
1190
+ createVNode(_component_BlockArrow),
1191
+ createVNode(_component_BlockArrow)
1192
+ ], 2),
1193
+ createVNode(EvaluationStep, {
1194
+ class: normalizeClass(_ctx.$style.step),
1195
+ title: unref(locale).baseText("testDefinition.edit.step.mockedNodes", {
1196
+ adjustToNumber: mockedNodes.value?.length ?? 0
1197
+ }),
1198
+ small: true,
1199
+ expanded: true,
1200
+ description: unref(locale).baseText("testDefinition.edit.step.nodes.description"),
1201
+ issues: _ctx.getFieldIssues("mockedNodes"),
1202
+ "show-issues": showFieldIssues("mockedNodes")
1203
+ }, {
1204
+ icon: withCtx(() => [
1205
+ createVNode(_component_font_awesome_icon, {
1206
+ icon: "thumbtack",
1207
+ size: "lg"
1208
+ })
1209
+ ]),
1210
+ cardContent: withCtx(() => [
1211
+ createVNode(_component_n8n_button, {
1212
+ size: "small",
1213
+ "data-test-id": "select-nodes-button",
1214
+ label: unref(locale).baseText("testDefinition.edit.selectNodes"),
1215
+ type: "tertiary",
1216
+ onClick: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("openPinningModal"))
1217
+ }, null, 8, ["label"])
1218
+ ]),
1219
+ _: 1
1220
+ }, 8, ["class", "title", "description", "issues", "show-issues"]),
1221
+ createVNode(EvaluationStep, {
1222
+ class: normalizeClass(_ctx.$style.step),
1223
+ title: unref(locale).baseText("testDefinition.edit.step.reRunExecutions"),
1224
+ small: true,
1225
+ description: unref(locale).baseText("testDefinition.edit.step.reRunExecutions.description")
1226
+ }, {
1227
+ icon: withCtx(() => [
1228
+ createVNode(_component_font_awesome_icon, {
1229
+ icon: "redo",
1230
+ size: "lg"
1231
+ })
1232
+ ]),
1233
+ _: 1
1234
+ }, 8, ["class", "title", "description"]),
1235
+ createVNode(EvaluationStep, {
1236
+ class: normalizeClass(_ctx.$style.step),
1237
+ title: unref(locale).baseText("testDefinition.edit.step.compareExecutions"),
1238
+ description: unref(locale).baseText("testDefinition.edit.step.compareExecutions.description"),
1239
+ issues: _ctx.getFieldIssues("evaluationWorkflow"),
1240
+ "show-issues": showFieldIssues("evaluationWorkflow")
1241
+ }, {
1242
+ icon: withCtx(() => [
1243
+ createVNode(_component_font_awesome_icon, {
1244
+ icon: "equals",
1245
+ size: "lg"
1246
+ })
1247
+ ]),
1248
+ cardContent: withCtx(() => [
1249
+ createVNode(_sfc_main$3, {
1250
+ modelValue: evaluationWorkflow.value,
1251
+ "onUpdate:modelValue": [
1252
+ _cache[3] || (_cache[3] = ($event) => evaluationWorkflow.value = $event),
1253
+ _cache[4] || (_cache[4] = ($event) => updateChangedFieldsKeys("evaluationWorkflow"))
1254
+ ],
1255
+ "example-pinned-data": _ctx.examplePinnedData,
1256
+ class: normalizeClass({ "has-issues": _ctx.getFieldIssues("evaluationWorkflow").length > 0 }),
1257
+ "sample-workflow-name": _ctx.sampleWorkflowName
1258
+ }, null, 8, ["modelValue", "example-pinned-data", "class", "sample-workflow-name"])
1259
+ ]),
1260
+ _: 1
1261
+ }, 8, ["class", "title", "description", "issues", "show-issues"]),
1262
+ createVNode(EvaluationStep, {
1263
+ class: normalizeClass(_ctx.$style.step),
1264
+ title: unref(locale).baseText("testDefinition.edit.step.metrics"),
1265
+ description: unref(locale).baseText("testDefinition.edit.step.metrics.description"),
1266
+ issues: _ctx.getFieldIssues("metrics"),
1267
+ "show-issues": showFieldIssues("metrics")
1268
+ }, {
1269
+ icon: withCtx(() => [
1270
+ createVNode(_component_font_awesome_icon, {
1271
+ icon: "chart-bar",
1272
+ size: "lg"
1273
+ })
1274
+ ]),
1275
+ cardContent: withCtx(() => [
1276
+ createVNode(MetricsInput, {
1277
+ modelValue: metrics.value,
1278
+ "onUpdate:modelValue": [
1279
+ _cache[5] || (_cache[5] = ($event) => metrics.value = $event),
1280
+ _cache[7] || (_cache[7] = ($event) => updateChangedFieldsKeys("metrics"))
1281
+ ],
1282
+ class: normalizeClass({ "has-issues": _ctx.getFieldIssues("metrics").length > 0 }),
1283
+ onDeleteMetric: _cache[6] || (_cache[6] = (metric) => emit("deleteMetric", metric))
1284
+ }, null, 8, ["modelValue", "class"])
1285
+ ]),
1286
+ _: 1
1287
+ }, 8, ["class", "title", "description", "issues", "show-issues"]),
1288
+ createVNode(_component_Modal, {
1289
+ ref_key: "nodePinningModal",
1290
+ ref: nodePinningModal,
1291
+ width: "80vw",
1292
+ height: "85vh",
1293
+ name: unref(NODE_PINNING_MODAL_KEY)
1294
+ }, {
1295
+ header: withCtx(() => [
1296
+ createVNode(_component_N8nHeading, {
1297
+ size: "large",
1298
+ bold: true,
1299
+ class: normalizeClass(_ctx.$style.runsTableHeading)
1300
+ }, {
1301
+ default: withCtx(() => [
1302
+ createTextVNode(toDisplayString(unref(locale).baseText("testDefinition.edit.selectNodes")), 1)
1303
+ ]),
1304
+ _: 1
1305
+ }, 8, ["class"])
1306
+ ]),
1307
+ content: withCtx(() => [
1308
+ createVNode(_component_NodesPinning, {
1309
+ modelValue: mockedNodes.value,
1310
+ "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => mockedNodes.value = $event),
1311
+ "data-test-id": "nodes-pinning-modal"
1312
+ }, null, 8, ["modelValue"])
1313
+ ]),
1314
+ _: 1
1315
+ }, 8, ["name"])
1316
+ ], 2);
1317
+ };
1318
+ }
1319
+ });
1320
+ const panelBlock = "_panelBlock_1xhy8_123";
1321
+ const hidden = "_hidden_1xhy8_133";
1322
+ const noRuns$1 = "_noRuns_1xhy8_139";
1323
+ const panelIntro = "_panelIntro_1xhy8_143";
1324
+ const step = "_step_1xhy8_151";
1325
+ const introArrow = "_introArrow_1xhy8_158";
1326
+ const evaluationArrows = "_evaluationArrows_1xhy8_164";
1327
+ const style0$1 = {
1328
+ panelBlock,
1329
+ hidden,
1330
+ noRuns: noRuns$1,
1331
+ panelIntro,
1332
+ step,
1333
+ introArrow,
1334
+ evaluationArrows
1335
+ };
868
1336
  const cssModules$1 = {
869
1337
  "$style": style0$1
870
1338
  };
871
- const MetricsInput = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__cssModules", cssModules$1]]);
1339
+ const ConfigSection = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__cssModules", cssModules$1]]);
872
1340
  const _sfc_main = /* @__PURE__ */ defineComponent({
873
1341
  __name: "TestDefinitionEditView",
874
1342
  props: {
@@ -884,9 +1352,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
884
1352
  const testDefinitionStore = useTestDefinitionStore();
885
1353
  const tagsStore = useAnnotationTagsStore();
886
1354
  const uiStore = useUIStore();
1355
+ const executionsStore = useExecutionsStore();
1356
+ const workflowStore = useWorkflowsStore();
887
1357
  const {
888
1358
  state,
889
- fieldsIssues,
890
1359
  isSaving,
891
1360
  cancelEditing,
892
1361
  loadTestData,
@@ -907,11 +1376,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
907
1376
  const tagUsageCount = computed(
908
1377
  () => tagsStore.tagsById[state.value.tags.value[0]]?.usageCount ?? 0
909
1378
  );
1379
+ const workflowName = computed(() => workflowStore.workflow.name);
910
1380
  const hasRuns = computed(() => runs2.value.length > 0);
911
- const nodePinningModal = ref(null);
912
- const modalContentWidth = ref(0);
1381
+ const fieldsIssues = computed(() => testDefinitionStore.getFieldIssues(testId.value) ?? []);
913
1382
  const showConfig = ref(true);
914
1383
  const selectedMetric = ref("");
1384
+ const examplePinnedData = ref({});
915
1385
  onMounted(async () => {
916
1386
  if (!testDefinitionStore.isFeatureEnabled) {
917
1387
  toast.showMessage({
@@ -924,7 +1394,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
924
1394
  });
925
1395
  return;
926
1396
  }
927
- void tagsStore.fetchAll({ withUsageCount: true });
928
1397
  if (testId.value) {
929
1398
  await loadTestData(testId.value);
930
1399
  } else {
@@ -949,8 +1418,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
949
1418
  toast.showError(e, locale.baseText("testDefinition.edit.testSaveFailed"));
950
1419
  }
951
1420
  }
952
- function hasIssues(key) {
953
- return fieldsIssues.value.some((issue) => issue.field === key);
1421
+ function getFieldIssues(key) {
1422
+ return fieldsIssues.value.filter((issue) => issue.field === key);
954
1423
  }
955
1424
  async function onDeleteMetric(deletedMetric) {
956
1425
  if (deletedMetric.id) {
@@ -978,6 +1447,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
978
1447
  (run) => run.testDefinitionId === testId.value
979
1448
  )
980
1449
  );
1450
+ const isRunning = computed(() => runs2.value.some((run) => run.status === "running"));
1451
+ const isRunTestEnabled = computed(() => fieldsIssues.value.length === 0 && !isRunning.value);
981
1452
  async function onDeleteRuns(toDelete) {
982
1453
  await Promise.all(
983
1454
  toDelete.map(async (run) => {
@@ -988,11 +1459,33 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
988
1459
  function toggleConfig() {
989
1460
  showConfig.value = !showConfig.value;
990
1461
  }
1462
+ async function getExamplePinnedDataForTags() {
1463
+ const evaluationWorkflowExecutions = await executionsStore.fetchExecutions({
1464
+ workflowId: currentWorkflowId.value,
1465
+ annotationTags: state.value.tags.value
1466
+ });
1467
+ if (evaluationWorkflowExecutions.count > 0) {
1468
+ const firstExecution = evaluationWorkflowExecutions.results[0];
1469
+ const executionData = await executionsStore.fetchExecution(firstExecution.id);
1470
+ const resultData = executionData?.data?.resultData.runData;
1471
+ examplePinnedData.value = {
1472
+ "When called by a test run": [
1473
+ {
1474
+ json: {
1475
+ originalExecution: resultData,
1476
+ newExecution: resultData
1477
+ }
1478
+ }
1479
+ ]
1480
+ };
1481
+ }
1482
+ }
991
1483
  watch(
992
1484
  () => state.value.metrics,
993
1485
  debounce(async () => await updateMetrics(testId.value), { debounceTime: 400 }),
994
1486
  { deep: true }
995
1487
  );
1488
+ watch(() => state.value.tags, getExamplePinnedDataForTags);
996
1489
  watch(
997
1490
  () => [
998
1491
  state.value.description,
@@ -1005,296 +1498,91 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1005
1498
  { deep: true }
1006
1499
  );
1007
1500
  return (_ctx, _cache) => {
1008
- const _component_n8n_button = resolveComponent("n8n-button");
1009
- const _component_MetricsChart = __unplugin_components_0$2;
1010
- const _component_BlockArrow = __unplugin_components_1;
1011
- const _component_font_awesome_icon = resolveComponent("font-awesome-icon");
1012
- const _component_N8nHeading = resolveComponent("N8nHeading");
1013
- const _component_NodesPinning = __unplugin_components_2;
1014
1501
  return openBlock(), createElementBlock("div", {
1015
1502
  class: normalizeClass([_ctx.$style.container, { [_ctx.$style.noRuns]: !hasRuns.value }])
1016
1503
  }, [
1017
- createBaseVNode("div", {
1018
- class: normalizeClass(_ctx.$style.headerSection)
1019
- }, [
1020
- createBaseVNode("div", {
1021
- class: normalizeClass(_ctx.$style.headerMeta)
1022
- }, [
1023
- createBaseVNode("div", {
1024
- class: normalizeClass(_ctx.$style.name)
1025
- }, [
1026
- createVNode(EvaluationHeader, {
1027
- modelValue: unref(state).name,
1028
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(state).name = $event),
1029
- class: normalizeClass({ "has-issues": hasIssues("name") }),
1030
- "start-editing": unref(startEditing),
1031
- "save-changes": unref(saveChanges),
1032
- "handle-keydown": unref(handleKeydown)
1033
- }, null, 8, ["modelValue", "class", "start-editing", "save-changes", "handle-keydown"]),
1034
- createBaseVNode("div", {
1035
- class: normalizeClass(_ctx.$style.lastSaved)
1036
- }, [
1037
- unref(isSaving) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
1038
- createTextVNode(toDisplayString(unref(locale).baseText("testDefinition.edit.saving")), 1)
1039
- ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
1040
- createTextVNode(toDisplayString(unref(locale).baseText("testDefinition.edit.saved")), 1)
1041
- ], 64))
1042
- ], 2)
1043
- ], 2),
1044
- createVNode(DescriptionInput, {
1045
- modelValue: unref(state).description,
1046
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => unref(state).description = $event),
1047
- "start-editing": unref(startEditing),
1048
- "save-changes": unref(saveChanges),
1049
- "handle-keydown": unref(handleKeydown),
1050
- class: normalizeClass(_ctx.$style.descriptionInput)
1051
- }, null, 8, ["modelValue", "start-editing", "save-changes", "handle-keydown", "class"])
1052
- ], 2),
1053
- createBaseVNode("div", {
1054
- class: normalizeClass(_ctx.$style.controls)
1055
- }, [
1056
- runs2.value.length > 0 ? (openBlock(), createBlock(_component_n8n_button, {
1057
- key: 0,
1058
- size: "small",
1059
- icon: showConfig.value ? "eye-slash" : "eye",
1060
- "data-test-id": "toggle-config-button",
1061
- label: showConfig.value ? unref(locale).baseText("testDefinition.edit.hideConfig") : unref(locale).baseText("testDefinition.edit.showConfig"),
1062
- type: "tertiary",
1063
- onClick: toggleConfig
1064
- }, null, 8, ["icon", "label"])) : createCommentVNode("", true),
1065
- unref(state).evaluationWorkflow.value && unref(state).tags.value.length > 0 ? (openBlock(), createBlock(_component_n8n_button, {
1066
- key: 1,
1067
- class: normalizeClass(_ctx.$style.runTestButton),
1068
- size: "small",
1069
- "data-test-id": "run-test-button",
1070
- label: unref(locale).baseText("testDefinition.runTest"),
1071
- type: "primary",
1072
- onClick: runTest
1073
- }, null, 8, ["class", "label"])) : (openBlock(), createBlock(_component_n8n_button, {
1074
- key: 2,
1075
- class: normalizeClass(_ctx.$style.runTestButton),
1076
- size: "small",
1077
- "data-test-id": "run-test-button",
1078
- label: unref(locale).baseText("testDefinition.edit.saveTest"),
1079
- type: "primary",
1080
- onClick: onSaveTest
1081
- }, null, 8, ["class", "label"]))
1082
- ], 2)
1083
- ], 2),
1504
+ createVNode(HeaderSection, {
1505
+ name: unref(state).name,
1506
+ "onUpdate:name": _cache[0] || (_cache[0] = ($event) => unref(state).name = $event),
1507
+ description: unref(state).description,
1508
+ "onUpdate:description": _cache[1] || (_cache[1] = ($event) => unref(state).description = $event),
1509
+ tags: unref(state).tags,
1510
+ "onUpdate:tags": _cache[2] || (_cache[2] = ($event) => unref(state).tags = $event),
1511
+ "has-runs": hasRuns.value,
1512
+ "is-saving": unref(isSaving),
1513
+ "get-field-issues": getFieldIssues,
1514
+ "start-editing": unref(startEditing),
1515
+ "save-changes": unref(saveChanges),
1516
+ "handle-keydown": unref(handleKeydown),
1517
+ "on-save-test": onSaveTest,
1518
+ "run-test": runTest,
1519
+ "show-config": showConfig.value,
1520
+ "toggle-config": toggleConfig,
1521
+ "run-test-enabled": isRunTestEnabled.value
1522
+ }, {
1523
+ runTestTooltip: withCtx(() => [
1524
+ fieldsIssues.value.length > 0 ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
1525
+ createBaseVNode("div", null, toDisplayString(unref(locale).baseText("testDefinition.completeConfig")), 1),
1526
+ (openBlock(true), createElementBlock(Fragment, null, renderList(fieldsIssues.value, (issue) => {
1527
+ return openBlock(), createElementBlock("div", {
1528
+ key: issue.field
1529
+ }, "- " + toDisplayString(issue.message), 1);
1530
+ }), 128))
1531
+ ], 64)) : createCommentVNode("", true),
1532
+ isRunning.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
1533
+ createTextVNode(toDisplayString(unref(locale).baseText("testDefinition.testIsRunning")), 1)
1534
+ ], 64)) : createCommentVNode("", true)
1535
+ ]),
1536
+ _: 1
1537
+ }, 8, ["name", "description", "tags", "has-runs", "is-saving", "start-editing", "save-changes", "handle-keydown", "show-config", "run-test-enabled"]),
1084
1538
  createBaseVNode("div", {
1085
1539
  class: normalizeClass(_ctx.$style.content)
1086
1540
  }, [
1087
- runs2.value.length > 0 ? (openBlock(), createElementBlock("div", {
1541
+ runs2.value.length > 0 ? (openBlock(), createBlock(RunsSection, {
1088
1542
  key: 0,
1089
- class: normalizeClass(_ctx.$style.runs)
1090
- }, [
1091
- createVNode(_component_MetricsChart, {
1092
- selectedMetric: selectedMetric.value,
1093
- "onUpdate:selectedMetric": _cache[2] || (_cache[2] = ($event) => selectedMetric.value = $event),
1094
- runs: runs2.value,
1095
- theme: appliedTheme.value
1096
- }, null, 8, ["selectedMetric", "runs", "theme"]),
1097
- createVNode(TestRunsTable, {
1098
- class: normalizeClass(_ctx.$style.runsTable),
1099
- runs: runs2.value,
1100
- selectable: true,
1101
- "data-test-id": "past-runs-table",
1102
- onDeleteRuns
1103
- }, null, 8, ["class", "runs"])
1104
- ], 2)) : createCommentVNode("", true),
1105
- createBaseVNode("div", {
1106
- class: normalizeClass([_ctx.$style.panelBlock, { [_ctx.$style.hidden]: !showConfig.value }])
1107
- }, [
1108
- createBaseVNode("div", {
1109
- class: normalizeClass(_ctx.$style.panelIntro)
1110
- }, toDisplayString(unref(locale).baseText("testDefinition.edit.step.intro")), 3),
1111
- createVNode(_component_BlockArrow, {
1112
- class: normalizeClass(_ctx.$style.introArrow)
1113
- }, null, 8, ["class"]),
1114
- createVNode(EvaluationStep, {
1115
- class: normalizeClass(_ctx.$style.step),
1116
- title: unref(locale).baseText("testDefinition.edit.step.executions", {
1117
- adjustToNumber: tagUsageCount.value
1118
- }),
1119
- description: unref(locale).baseText("testDefinition.edit.step.executions.description")
1120
- }, {
1121
- icon: withCtx(() => [
1122
- createVNode(_component_font_awesome_icon, {
1123
- icon: "history",
1124
- size: "lg"
1125
- })
1126
- ]),
1127
- cardContent: withCtx(() => [
1128
- createVNode(TagsInput, {
1129
- modelValue: unref(state).tags,
1130
- "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => unref(state).tags = $event),
1131
- class: normalizeClass({ "has-issues": hasIssues("tags") }),
1132
- "all-tags": allTags.value,
1133
- "tags-by-id": tagsById.value,
1134
- "is-loading": isLoading.value,
1135
- "start-editing": unref(startEditing),
1136
- "save-changes": unref(saveChanges),
1137
- "cancel-editing": unref(cancelEditing),
1138
- "create-tag": handleCreateTag
1139
- }, null, 8, ["modelValue", "class", "all-tags", "tags-by-id", "is-loading", "start-editing", "save-changes", "cancel-editing"])
1140
- ]),
1141
- _: 1
1142
- }, 8, ["class", "title", "description"]),
1143
- createBaseVNode("div", {
1144
- class: normalizeClass(_ctx.$style.evaluationArrows)
1145
- }, [
1146
- createVNode(_component_BlockArrow),
1147
- createVNode(_component_BlockArrow)
1148
- ], 2),
1149
- createVNode(EvaluationStep, {
1150
- class: normalizeClass(_ctx.$style.step),
1151
- title: unref(locale).baseText("testDefinition.edit.step.mockedNodes", {
1152
- adjustToNumber: unref(state).mockedNodes?.length ?? 0
1153
- }),
1154
- small: true,
1155
- expanded: true,
1156
- description: unref(locale).baseText("testDefinition.edit.step.nodes.description")
1157
- }, {
1158
- icon: withCtx(() => [
1159
- createVNode(_component_font_awesome_icon, {
1160
- icon: "thumbtack",
1161
- size: "lg"
1162
- })
1163
- ]),
1164
- cardContent: withCtx(() => [
1165
- createVNode(_component_n8n_button, {
1166
- size: "small",
1167
- "data-test-id": "select-nodes-button",
1168
- label: unref(locale).baseText("testDefinition.edit.selectNodes"),
1169
- type: "tertiary",
1170
- onClick: openPinningModal
1171
- }, null, 8, ["label"])
1172
- ]),
1173
- _: 1
1174
- }, 8, ["class", "title", "description"]),
1175
- createVNode(EvaluationStep, {
1176
- class: normalizeClass(_ctx.$style.step),
1177
- title: unref(locale).baseText("testDefinition.edit.step.reRunExecutions"),
1178
- small: true,
1179
- description: unref(locale).baseText("testDefinition.edit.step.reRunExecutions.description")
1180
- }, {
1181
- icon: withCtx(() => [
1182
- createVNode(_component_font_awesome_icon, {
1183
- icon: "redo",
1184
- size: "lg"
1185
- })
1186
- ]),
1187
- _: 1
1188
- }, 8, ["class", "title", "description"]),
1189
- createVNode(EvaluationStep, {
1190
- class: normalizeClass(_ctx.$style.step),
1191
- title: unref(locale).baseText("testDefinition.edit.step.compareExecutions"),
1192
- description: unref(locale).baseText("testDefinition.edit.step.compareExecutions.description")
1193
- }, {
1194
- icon: withCtx(() => [
1195
- createVNode(_component_font_awesome_icon, {
1196
- icon: "equals",
1197
- size: "lg"
1198
- })
1199
- ]),
1200
- cardContent: withCtx(() => [
1201
- createVNode(_sfc_main$2, {
1202
- modelValue: unref(state).evaluationWorkflow,
1203
- "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => unref(state).evaluationWorkflow = $event),
1204
- class: normalizeClass({ "has-issues": hasIssues("evaluationWorkflow") })
1205
- }, null, 8, ["modelValue", "class"])
1206
- ]),
1207
- _: 1
1208
- }, 8, ["class", "title", "description"]),
1209
- createVNode(EvaluationStep, {
1210
- class: normalizeClass(_ctx.$style.step),
1211
- title: unref(locale).baseText("testDefinition.edit.step.metrics"),
1212
- description: unref(locale).baseText("testDefinition.edit.step.metrics.description")
1213
- }, {
1214
- icon: withCtx(() => [
1215
- createVNode(_component_font_awesome_icon, {
1216
- icon: "chart-bar",
1217
- size: "lg"
1218
- })
1219
- ]),
1220
- cardContent: withCtx(() => [
1221
- createVNode(MetricsInput, {
1222
- modelValue: unref(state).metrics,
1223
- "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => unref(state).metrics = $event),
1224
- class: normalizeClass({ "has-issues": hasIssues("metrics") }),
1225
- onDeleteMetric
1226
- }, null, 8, ["modelValue", "class"])
1227
- ]),
1228
- _: 1
1229
- }, 8, ["class", "title", "description"])
1230
- ], 2)
1231
- ], 2),
1232
- createVNode(Modal, {
1233
- ref_key: "nodePinningModal",
1234
- ref: nodePinningModal,
1235
- width: "80vw",
1236
- height: "85vh",
1237
- name: unref(NODE_PINNING_MODAL_KEY)
1238
- }, {
1239
- header: withCtx(() => [
1240
- createVNode(_component_N8nHeading, {
1241
- size: "large",
1242
- bold: true,
1243
- class: normalizeClass(_ctx.$style.runsTableHeading)
1244
- }, {
1245
- default: withCtx(() => [
1246
- createTextVNode(toDisplayString(unref(locale).baseText("testDefinition.edit.selectNodes")), 1)
1247
- ]),
1248
- _: 1
1249
- }, 8, ["class"])
1250
- ]),
1251
- content: withCtx(() => [
1252
- createVNode(_component_NodesPinning, {
1253
- modelValue: unref(state).mockedNodes,
1254
- "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => unref(state).mockedNodes = $event),
1255
- width: modalContentWidth.value,
1256
- "data-test-id": "nodes-pinning-modal"
1257
- }, null, 8, ["modelValue", "width"])
1258
- ]),
1259
- _: 1
1260
- }, 8, ["name"])
1543
+ selectedMetric: selectedMetric.value,
1544
+ "onUpdate:selectedMetric": _cache[3] || (_cache[3] = ($event) => selectedMetric.value = $event),
1545
+ runs: runs2.value,
1546
+ "test-id": testId.value,
1547
+ "applied-theme": appliedTheme.value,
1548
+ onDeleteRuns
1549
+ }, null, 8, ["selectedMetric", "runs", "test-id", "applied-theme"])) : createCommentVNode("", true),
1550
+ createVNode(ConfigSection, {
1551
+ tags: unref(state).tags,
1552
+ "onUpdate:tags": _cache[4] || (_cache[4] = ($event) => unref(state).tags = $event),
1553
+ evaluationWorkflow: unref(state).evaluationWorkflow,
1554
+ "onUpdate:evaluationWorkflow": _cache[5] || (_cache[5] = ($event) => unref(state).evaluationWorkflow = $event),
1555
+ metrics: unref(state).metrics,
1556
+ "onUpdate:metrics": _cache[6] || (_cache[6] = ($event) => unref(state).metrics = $event),
1557
+ mockedNodes: unref(state).mockedNodes,
1558
+ "onUpdate:mockedNodes": _cache[7] || (_cache[7] = ($event) => unref(state).mockedNodes = $event),
1559
+ "cancel-editing": unref(cancelEditing),
1560
+ "show-config": showConfig.value,
1561
+ "tag-usage-count": tagUsageCount.value,
1562
+ "all-tags": allTags.value,
1563
+ "tags-by-id": tagsById.value,
1564
+ "is-loading": isLoading.value,
1565
+ "get-field-issues": getFieldIssues,
1566
+ "start-editing": unref(startEditing),
1567
+ "save-changes": unref(saveChanges),
1568
+ "create-tag": handleCreateTag,
1569
+ "example-pinned-data": examplePinnedData.value,
1570
+ "sample-workflow-name": workflowName.value,
1571
+ onOpenPinningModal: openPinningModal,
1572
+ onDeleteMetric
1573
+ }, null, 8, ["tags", "evaluationWorkflow", "metrics", "mockedNodes", "cancel-editing", "show-config", "tag-usage-count", "all-tags", "tags-by-id", "is-loading", "start-editing", "save-changes", "example-pinned-data", "sample-workflow-name"])
1574
+ ], 2)
1261
1575
  ], 2);
1262
1576
  };
1263
1577
  }
1264
1578
  });
1265
- const container = "_container_y9ejv_123";
1266
- const content = "_content_y9ejv_141";
1267
- const noRuns = "_noRuns_y9ejv_146";
1268
- const headerSection = "_headerSection_y9ejv_151";
1269
- const headerMeta = "_headerMeta_y9ejv_159";
1270
- const name = "_name_y9ejv_163";
1271
- const lastSaved = "_lastSaved_y9ejv_167";
1272
- const descriptionInput = "_descriptionInput_y9ejv_172";
1273
- const runs = "_runs_y9ejv_176";
1274
- const panelBlock = "_panelBlock_y9ejv_190";
1275
- const hidden = "_hidden_y9ejv_200";
1276
- const panelIntro = "_panelIntro_y9ejv_210";
1277
- const step = "_step_y9ejv_218";
1278
- const introArrow = "_introArrow_y9ejv_225";
1279
- const evaluationArrows = "_evaluationArrows_y9ejv_231";
1280
- const controls = "_controls_y9ejv_242";
1579
+ const container = "_container_wdela_123";
1580
+ const content = "_content_wdela_141";
1581
+ const noRuns = "_noRuns_wdela_146";
1281
1582
  const style0 = {
1282
1583
  container,
1283
1584
  content,
1284
- noRuns,
1285
- headerSection,
1286
- headerMeta,
1287
- name,
1288
- lastSaved,
1289
- descriptionInput,
1290
- runs,
1291
- panelBlock,
1292
- hidden,
1293
- panelIntro,
1294
- step,
1295
- introArrow,
1296
- evaluationArrows,
1297
- controls
1585
+ noRuns
1298
1586
  };
1299
1587
  const cssModules = {
1300
1588
  "$style": style0