fix(editor): Fix loading executions in long execution list (#5843)

* fix(editor): Fix loading executions in long execution list
*  Added max number of attempts before displaying temporary execution card
*  Simplifying temp execution preview logic, handling current execution delete, updating style
* 💄 Renaming `executionWIthGap` -> `temporaryExecution`
This commit is contained in:
Milorad FIlipović 2023-03-31 18:48:30 +02:00 committed by कारतोफ्फेलस्क्रिप्ट™
parent 3be37e25a5
commit d5d9f58f17
3 changed files with 58 additions and 11 deletions

View file

@ -6,6 +6,7 @@
[$style.active]: isActive,
[$style[executionUIDetails.name]]: true,
[$style.highlight]: highlight,
[$style.showGap]: showGap,
}"
>
<router-link
@ -107,6 +108,10 @@ export default mixins(executionHelpers, showMessage, restApi).extend({
type: Boolean,
default: false,
},
showGap: {
type: Boolean,
default: false,
},
},
computed: {
retryExecutionActions(): object[] {
@ -139,6 +144,7 @@ export default mixins(executionHelpers, showMessage, restApi).extend({
<style module lang="scss">
.executionCard {
display: flex;
flex-direction: column;
padding-right: var(--spacing-m);
&.active {
@ -252,4 +258,10 @@ export default mixins(executionHelpers, showMessage, restApi).extend({
margin-left: var(--spacing-2xs);
}
}
.showGap {
margin-bottom: var(--spacing-2xs);
.executionLink {
border-bottom: 1px solid var(--color-foreground-dark);
}
}
</style>

View file

@ -4,9 +4,10 @@
:executions="executions"
:loading="loading"
:loadingMore="loadingMore"
:temporaryExecution="temporaryExecution"
@reloadExecutions="setExecutions"
@filterUpdated="onFilterUpdated"
@loadMore="loadMore"
@loadMore="onLoadMore"
@retryExecution="onRetryExecution"
@refresh="loadAutoRefresh"
/>
@ -55,7 +56,7 @@ import { Route } from 'vue-router';
import { executionHelpers } from '@/mixins/executionsHelpers';
import { range as _range } from 'lodash-es';
import { debounceHelper } from '@/mixins/debounce';
import { getNodeViewTab, isEmpty, NO_NETWORK_ERROR_CODE } from '@/utils';
import { getNodeViewTab, NO_NETWORK_ERROR_CODE } from '@/utils';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import { mapStores } from 'pinia';
import { useWorkflowsStore } from '@/stores/workflows';
@ -65,6 +66,11 @@ import { useNodeTypesStore } from '@/stores/nodeTypes';
import { useTagsStore } from '@/stores/tags';
import { executionFilterToQueryFilter } from '@/utils/executionUtils';
// Number of execution pages that are fetched before temporary execution card is shown
const MAX_LOADING_ATTEMPTS = 1;
// Number of executions fetched on each page
const LOAD_MORE_PAGE_SIZE = 10;
export default mixins(
restApi,
showMessage,
@ -81,6 +87,7 @@ export default mixins(
loading: false,
loadingMore: false,
filter: {} as ExecutionFilterType,
temporaryExecution: null as IExecutionsSummary | null,
};
},
computed: {
@ -234,6 +241,10 @@ export default mixins(
if (currentExecutions.find((ex) => ex.id === newExecution.id) === undefined) {
currentExecutions.push(newExecution);
}
// If we loaded temp execution, put it into it's place and remove from top of the list
if (newExecution.id === this.temporaryExecution?.id) {
this.temporaryExecution = null;
}
}
this.workflowsStore.currentWorkflowExecutions = currentExecutions;
this.loadingMore = false;
@ -250,6 +261,9 @@ export default mixins(
this.executions[0];
await this.restApi().deleteExecutions({ ids: [this.$route.params.executionId] });
if (this.temporaryExecution?.id === this.$route.params.executionId) {
this.temporaryExecution = null;
}
if (this.executions.length > 0) {
await this.$router
.push({
@ -371,7 +385,7 @@ export default mixins(
this.workflowsStore.activeWorkflowExecution = updatedActiveExecution;
} else {
const activeInList = existingExecutions.some((ex) => ex.id === this.activeExecution?.id);
if (!activeInList && this.executions.length > 0) {
if (!activeInList && this.executions.length > 0 && !this.temporaryExecution) {
this.$router
.push({
name: VIEWS.EXECUTION_PREVIEW,
@ -422,7 +436,11 @@ export default mixins(
}
// If there is no execution in the route, select the first one
if (this.workflowsStore.activeWorkflowExecution === null && this.executions.length > 0) {
if (
this.workflowsStore.activeWorkflowExecution === null &&
this.executions.length > 0 &&
!this.temporaryExecution
) {
this.workflowsStore.activeWorkflowExecution = this.executions[0];
this.$router
.push({
@ -435,8 +453,8 @@ export default mixins(
async tryToFindExecution(executionId: string, attemptCount = 0): Promise<void> {
// First check if executions exists in the DB at all
if (attemptCount === 0) {
const executionExists = await this.workflowsStore.fetchExecutionDataById(executionId);
if (!executionExists) {
const existingExecution = await this.workflowsStore.fetchExecutionDataById(executionId);
if (!existingExecution) {
this.workflowsStore.activeWorkflowExecution = null;
this.$showError(
new Error(
@ -447,17 +465,21 @@ export default mixins(
this.$locale.baseText('nodeView.showError.openExecution.title'),
);
return;
} else {
this.temporaryExecution = existingExecution as IExecutionsSummary;
}
}
// stop if the execution wasn't found in the first 1000 lookups
if (attemptCount >= 10) {
if (attemptCount >= MAX_LOADING_ATTEMPTS) {
if (this.temporaryExecution) {
this.workflowsStore.activeWorkflowExecution = this.temporaryExecution;
return;
}
this.workflowsStore.activeWorkflowExecution = null;
return;
}
// Fetch next batch of executions
await this.loadMore(100);
await this.loadMore(LOAD_MORE_PAGE_SIZE);
const execution = this.workflowsStore.getExecutionDataById(executionId);
if (!execution) {
// If it's not there load next until found
@ -467,6 +489,7 @@ export default mixins(
} else {
// When found set execution as active
this.workflowsStore.activeWorkflowExecution = execution;
this.temporaryExecution = null;
return;
}
},

View file

@ -36,7 +36,15 @@
</n8n-text>
</div>
<execution-card
v-else
v-else-if="temporaryExecution"
:execution="temporaryExecution"
:ref="`execution-${temporaryExecution.id}`"
:data-test-id="`execution-details-${temporaryExecution.id}`"
:showGap="true"
@refresh="onRefresh"
@retryExecution="onRetryExecution"
/>
<execution-card
v-for="execution in executions"
:key="execution.id"
:execution="execution"
@ -89,6 +97,10 @@ export default Vue.extend({
type: Boolean,
default: false,
},
temporaryExecution: {
type: Object as PropType<IExecutionsSummary>,
default: null,
},
},
data() {
return {