mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 20:54:07 -08:00
fix(editor): Fix for executions preview scroll load and wrong execution displayed (#4994)
* 🐛 Only add current workflow executions to to store when loading executions from global list * 🐛 Fixing infinite scroll on executions list * 🐛 Fixing global and current executions list sync * ⚡ Resetting executions list when opening new workflow * 🐛 Handling opening execution from global list before opening a workflow * ⚡ Scrolling to active execution card if out of view, keeping selected execution after workflow load
This commit is contained in:
parent
75a974987d
commit
bd0c2afaac
|
@ -273,7 +273,7 @@ import WorkflowActivator from '@/components/WorkflowActivator.vue';
|
||||||
import Modal from '@/components/Modal.vue';
|
import Modal from '@/components/Modal.vue';
|
||||||
|
|
||||||
import { externalHooks } from '@/mixins/externalHooks';
|
import { externalHooks } from '@/mixins/externalHooks';
|
||||||
import { WAIT_TIME_UNLIMITED, EXECUTIONS_MODAL_KEY, VIEWS } from '@/constants';
|
import { WAIT_TIME_UNLIMITED, EXECUTIONS_MODAL_KEY, VIEWS, PLACEHOLDER_EMPTY_WORKFLOW_ID } from '@/constants';
|
||||||
|
|
||||||
import { restApi } from '@/mixins/restApi';
|
import { restApi } from '@/mixins/restApi';
|
||||||
import { genericHelpers } from '@/mixins/genericHelpers';
|
import { genericHelpers } from '@/mixins/genericHelpers';
|
||||||
|
@ -434,7 +434,13 @@ export default mixins(externalHooks, genericHelpers, restApi, showMessage).exten
|
||||||
this.modalBus.$emit('close');
|
this.modalBus.$emit('close');
|
||||||
},
|
},
|
||||||
convertToDisplayDate,
|
convertToDisplayDate,
|
||||||
displayExecution(execution: IExecutionShortResponse, e: PointerEvent) {
|
displayExecution(execution: IExecutionsSummary, e: PointerEvent) {
|
||||||
|
if (!this.workflowsStore.workflowId || this.workflowsStore.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID || execution.workflowId !== this.workflowsStore.workflowId) {
|
||||||
|
const workflowExecutions: IExecutionsSummary[] = this.combinedExecutions.filter(ex => ex.workflowId === execution.workflowId);
|
||||||
|
this.workflowsStore.currentWorkflowExecutions = workflowExecutions;
|
||||||
|
this.workflowsStore.activeWorkflowExecution = execution;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.metaKey || e.ctrlKey) {
|
if (e.metaKey || e.ctrlKey) {
|
||||||
const route = this.$router.resolve({
|
const route = this.$router.resolve({
|
||||||
name: VIEWS.EXECUTION_PREVIEW,
|
name: VIEWS.EXECUTION_PREVIEW,
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
v-for="execution in executions"
|
v-for="execution in executions"
|
||||||
:key="execution.id"
|
:key="execution.id"
|
||||||
:execution="execution"
|
:execution="execution"
|
||||||
|
:ref="`execution-${execution.id}`"
|
||||||
@refresh="onRefresh"
|
@refresh="onRefresh"
|
||||||
@retryExecution="onRetryExecution"
|
@retryExecution="onRetryExecution"
|
||||||
/>
|
/>
|
||||||
|
@ -95,6 +96,7 @@ import Vue from 'vue';
|
||||||
import { PropType } from 'vue';
|
import { PropType } from 'vue';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
|
import { useWorkflowsStore } from '@/stores/workflows';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'executions-sidebar',
|
name: 'executions-sidebar',
|
||||||
|
@ -127,7 +129,7 @@ export default Vue.extend({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapStores(useUIStore),
|
...mapStores(useUIStore, useWorkflowsStore),
|
||||||
statusFilterApplied(): boolean {
|
statusFilterApplied(): boolean {
|
||||||
return this.filter.status !== '';
|
return this.filter.status !== '';
|
||||||
},
|
},
|
||||||
|
@ -153,6 +155,7 @@ export default Vue.extend({
|
||||||
if (this.autoRefresh) {
|
if (this.autoRefresh) {
|
||||||
this.autoRefreshInterval = setInterval(() => this.onRefresh(), 4000);
|
this.autoRefreshInterval = setInterval(() => this.onRefresh(), 4000);
|
||||||
}
|
}
|
||||||
|
this.scrollToActiveCard();
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (this.autoRefreshInterval) {
|
if (this.autoRefreshInterval) {
|
||||||
|
@ -206,6 +209,18 @@ export default Vue.extend({
|
||||||
status: this.filter.status,
|
status: this.filter.status,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
scrollToActiveCard(): void {
|
||||||
|
const executionsList = this.$refs.executionList as HTMLElement;
|
||||||
|
const currentExecutionCard = this.$refs[`execution-${this.workflowsStore.activeWorkflowExecution?.id}`] as Vue[];
|
||||||
|
|
||||||
|
if (executionsList && currentExecutionCard && this.workflowsStore.activeWorkflowExecution) {
|
||||||
|
const cardElement = currentExecutionCard[0].$el as HTMLElement;
|
||||||
|
const cardRect = cardElement.getBoundingClientRect();
|
||||||
|
if (cardRect.top > executionsList.offsetHeight) {
|
||||||
|
executionsList.scrollTo({ top: cardRect.top });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -174,7 +174,13 @@ export default mixins(
|
||||||
const shouldUpdate = workflowUpdated && !onNewWorkflow;
|
const shouldUpdate = workflowUpdated && !onNewWorkflow;
|
||||||
await this.initView(shouldUpdate);
|
await this.initView(shouldUpdate);
|
||||||
if (!shouldUpdate) {
|
if (!shouldUpdate) {
|
||||||
await this.setExecutions();
|
if (this.workflowsStore.currentWorkflowExecutions.length > 0) {
|
||||||
|
const workflowExecutions = await this.loadExecutions();
|
||||||
|
this.workflowsStore.addToCurrentExecutions(workflowExecutions);
|
||||||
|
this.setActiveExecution();
|
||||||
|
} else {
|
||||||
|
await this.setExecutions();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
},
|
},
|
||||||
|
@ -186,7 +192,9 @@ export default mixins(
|
||||||
}
|
}
|
||||||
await this.openWorkflow(this.$route.params.name);
|
await this.openWorkflow(this.$route.params.name);
|
||||||
this.uiStore.nodeViewInitialized = false;
|
this.uiStore.nodeViewInitialized = false;
|
||||||
this.setExecutions();
|
if(this.workflowsStore.currentWorkflowExecutions.length === 0) {
|
||||||
|
this.setExecutions();
|
||||||
|
}
|
||||||
if (this.activeExecution) {
|
if (this.activeExecution) {
|
||||||
this.$router
|
this.$router
|
||||||
.push({
|
.push({
|
||||||
|
|
|
@ -935,7 +935,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, {
|
||||||
requestFilter,
|
requestFilter,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// context.commit('setTotalFinishedExecutionsCount', finishedExecutions.count);
|
this.finishedExecutionsCount = finishedExecutions.count;
|
||||||
return [...activeExecutions, ...(finishedExecutions.results || [])];
|
return [...activeExecutions, ...(finishedExecutions.results || [])];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
|
@ -947,7 +947,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, {
|
||||||
addToCurrentExecutions(executions: IExecutionsSummary[]): void {
|
addToCurrentExecutions(executions: IExecutionsSummary[]): void {
|
||||||
executions.forEach(execution => {
|
executions.forEach(execution => {
|
||||||
const exists = this.currentWorkflowExecutions.find(ex => ex.id === execution.id);
|
const exists = this.currentWorkflowExecutions.find(ex => ex.id === execution.id);
|
||||||
if (!exists) {
|
if (!exists && execution.workflowId === this.workflowId) {
|
||||||
this.currentWorkflowExecutions.push(execution);
|
this.currentWorkflowExecutions.push(execution);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -884,6 +884,9 @@ export default mixins(
|
||||||
},
|
},
|
||||||
async openWorkflow(workflowId: string) {
|
async openWorkflow(workflowId: string) {
|
||||||
this.startLoading();
|
this.startLoading();
|
||||||
|
|
||||||
|
const selectedExecution = this.workflowsStore.activeWorkflowExecution;
|
||||||
|
|
||||||
this.resetWorkspace();
|
this.resetWorkspace();
|
||||||
let data: IWorkflowDb | undefined;
|
let data: IWorkflowDb | undefined;
|
||||||
try {
|
try {
|
||||||
|
@ -939,7 +942,12 @@ export default mixins(
|
||||||
}
|
}
|
||||||
this.canvasStore.zoomToFit();
|
this.canvasStore.zoomToFit();
|
||||||
this.$externalHooks().run('workflow.open', { workflowId, workflowName: data.name });
|
this.$externalHooks().run('workflow.open', { workflowId, workflowName: data.name });
|
||||||
this.workflowsStore.activeWorkflowExecution = null;
|
if (selectedExecution?.workflowId !== workflowId) {
|
||||||
|
this.workflowsStore.activeWorkflowExecution = null;
|
||||||
|
this.workflowsStore.currentWorkflowExecutions = [];
|
||||||
|
} else {
|
||||||
|
this.workflowsStore.activeWorkflowExecution = selectedExecution;
|
||||||
|
}
|
||||||
this.stopLoading();
|
this.stopLoading();
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue