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:
Milorad FIlipović 2022-12-22 12:40:33 +01:00 committed by GitHub
parent 75a974987d
commit bd0c2afaac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 8 deletions

View file

@ -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,

View file

@ -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>

View file

@ -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({

View file

@ -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);
} }
}); });

View file

@ -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;
}, },