mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
fix(editor): Remove 'crashed' status from filter (#5524)
* fix(editor): remove 'crashed' status from filter * fix(editor): remove 'crashed' and 'new' status from filter * fix(editor): add 'status' to response * fix(editor): create request filter for workflow level execution filtering * fix(editor): update filters * fix(editor): simplify condition * fix(editor): update filters * fix(editor): optimizing data loading flow * fix(editor): always load past executions
This commit is contained in:
@@ -133,9 +133,9 @@ export interface IExternalHooks {
|
||||
export interface IRestApi {
|
||||
getActiveWorkflows(): Promise<string[]>;
|
||||
getActivationError(id: string): Promise<IActivationError | undefined>;
|
||||
getCurrentExecutions(filter: object): Promise<IExecutionsCurrentSummaryExtended[]>;
|
||||
getCurrentExecutions(filter: IDataObject): Promise<IExecutionsCurrentSummaryExtended[]>;
|
||||
getPastExecutions(
|
||||
filter: object,
|
||||
filter: IDataObject,
|
||||
limit: number,
|
||||
lastId?: string,
|
||||
firstId?: string,
|
||||
|
||||
@@ -335,14 +335,6 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, restApi,
|
||||
id: 'error',
|
||||
name: this.$locale.baseText('executionsList.error'),
|
||||
},
|
||||
{
|
||||
id: 'crashed',
|
||||
name: this.$locale.baseText('executionsList.error'),
|
||||
},
|
||||
{
|
||||
id: 'new',
|
||||
name: this.$locale.baseText('executionsList.new'),
|
||||
},
|
||||
{
|
||||
id: 'running',
|
||||
name: this.$locale.baseText('executionsList.running'),
|
||||
@@ -363,10 +355,10 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, restApi,
|
||||
combinedExecutions(): IExecutionsSummary[] {
|
||||
const returnData: IExecutionsSummary[] = [];
|
||||
|
||||
if (['ALL', 'running', 'new'].includes(this.filter.status)) {
|
||||
if (['ALL', 'running'].includes(this.filter.status)) {
|
||||
returnData.push(...this.activeExecutions);
|
||||
}
|
||||
if (['ALL', 'error', 'crashed', 'success', 'waiting'].includes(this.filter.status)) {
|
||||
if (['ALL', 'error', 'success', 'waiting'].includes(this.filter.status)) {
|
||||
returnData.push(...this.finishedExecutions);
|
||||
}
|
||||
return returnData;
|
||||
@@ -404,14 +396,8 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, restApi,
|
||||
case 'waiting':
|
||||
queryFilter.status = ['waiting'];
|
||||
break;
|
||||
case 'crashed':
|
||||
queryFilter.status = ['crashed'];
|
||||
break;
|
||||
case 'new':
|
||||
queryFilter.status = ['new'];
|
||||
break;
|
||||
case 'error':
|
||||
queryFilter.status = ['failed', 'crashed', 'error'];
|
||||
queryFilter.status = ['failed', 'crashed'];
|
||||
break;
|
||||
case 'success':
|
||||
queryFilter.status = ['success'];
|
||||
@@ -813,8 +799,9 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, restApi,
|
||||
this.isDataLoading = false;
|
||||
},
|
||||
getStatus(execution: IExecutionsSummary): ExecutionStatus {
|
||||
if (execution.status) return execution.status;
|
||||
else {
|
||||
if (execution.status) {
|
||||
return execution.status;
|
||||
} else {
|
||||
// this should not happen but just in case
|
||||
let status: ExecutionStatus = 'unknown';
|
||||
if (execution.waitTill) {
|
||||
@@ -843,7 +830,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, restApi,
|
||||
} else if (status === 'crashed') {
|
||||
text = this.$locale.baseText('executionsList.error');
|
||||
} else if (status === 'new') {
|
||||
text = this.$locale.baseText('executionsList.new');
|
||||
text = this.$locale.baseText('executionsList.running');
|
||||
} else if (status === 'running') {
|
||||
text = this.$locale.baseText('executionsList.running');
|
||||
} else if (status === 'success') {
|
||||
@@ -865,7 +852,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, restApi,
|
||||
} else if (status === 'crashed') {
|
||||
path = 'executionsList.statusText';
|
||||
} else if (status === 'new') {
|
||||
path = 'executionsList.statusNew';
|
||||
path = 'executionsList.statusRunning';
|
||||
} else if (status === 'running') {
|
||||
path = 'executionsList.statusRunning';
|
||||
} else if (status === 'success') {
|
||||
@@ -1018,14 +1005,11 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, restApi,
|
||||
font-size: var(--font-size-s);
|
||||
font-weight: var(--font-weight-bold);
|
||||
|
||||
.crashed &,
|
||||
.failed & {
|
||||
color: var(--color-danger);
|
||||
}
|
||||
|
||||
.crashed & {
|
||||
color: var(--color-danger);
|
||||
}
|
||||
|
||||
.waiting & {
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
@@ -1034,6 +1018,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, restApi,
|
||||
font-weight: var(--font-weight-normal);
|
||||
}
|
||||
|
||||
.new &,
|
||||
.running & {
|
||||
color: var(--color-warning);
|
||||
}
|
||||
@@ -1131,18 +1116,16 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, restApi,
|
||||
background: var(--color-primary-tint-3);
|
||||
}
|
||||
|
||||
&.crashed td:first-child::before,
|
||||
&.failed td:first-child::before {
|
||||
background: var(--color-danger);
|
||||
}
|
||||
|
||||
&.crashed td:first-child::before {
|
||||
background: var(--color-danger);
|
||||
}
|
||||
|
||||
&.success td:first-child::before {
|
||||
background: var(--color-success);
|
||||
}
|
||||
|
||||
&.new td:first-child::before,
|
||||
&.running td:first-child::before {
|
||||
background: var(--color-warning);
|
||||
}
|
||||
|
||||
@@ -191,8 +191,7 @@ export default mixins(executionHelpers, showMessage, restApi).extend({
|
||||
}
|
||||
}
|
||||
|
||||
&.error,
|
||||
&.crashed {
|
||||
&.error {
|
||||
&,
|
||||
& .executionLink {
|
||||
border-left: var(--spacing-4xs) var(--border-style-base) hsl(var(--color-danger-h), 94%, 80%);
|
||||
|
||||
@@ -26,20 +26,15 @@ import ExecutionsSidebar from '@/components/ExecutionsView/ExecutionsSidebar.vue
|
||||
import {
|
||||
MAIN_HEADER_TABS,
|
||||
MODAL_CANCEL,
|
||||
MODAL_CLOSE,
|
||||
MODAL_CONFIRMED,
|
||||
PLACEHOLDER_EMPTY_WORKFLOW_ID,
|
||||
VIEWS,
|
||||
WEBHOOK_NODE_TYPE,
|
||||
} from '@/constants';
|
||||
import { IExecutionsListResponse, INodeUi, ITag, IWorkflowDb } from '@/Interface';
|
||||
import {
|
||||
IExecutionsListResponse,
|
||||
ExecutionStatus,
|
||||
IExecutionsSummary,
|
||||
INodeUi,
|
||||
ITag,
|
||||
IWorkflowDb,
|
||||
} from '@/Interface';
|
||||
import {
|
||||
IConnection,
|
||||
IConnections,
|
||||
IDataObject,
|
||||
@@ -71,7 +66,7 @@ export default mixins(
|
||||
debounceHelper,
|
||||
workflowHelpers,
|
||||
).extend({
|
||||
name: 'executions-view',
|
||||
name: 'executions-list',
|
||||
components: {
|
||||
ExecutionsSidebar,
|
||||
},
|
||||
@@ -87,9 +82,7 @@ export default mixins(
|
||||
hidePreview(): boolean {
|
||||
const activeNotPresent =
|
||||
this.filterApplied &&
|
||||
(this.executions as IExecutionsSummary[]).find(
|
||||
(ex) => ex.id === this.activeExecution.id,
|
||||
) === undefined;
|
||||
!(this.executions as IExecutionsSummary[]).find((ex) => ex.id === this.activeExecution?.id);
|
||||
return this.loading || !this.executions.length || activeNotPresent;
|
||||
},
|
||||
filterApplied(): boolean {
|
||||
@@ -107,6 +100,31 @@ export default mixins(
|
||||
totalFinishedExecutionsCount(): number {
|
||||
return this.workflowsStore.getTotalFinishedExecutionsCount;
|
||||
},
|
||||
requestFilter(): IDataObject {
|
||||
const rFilter: IDataObject = { workflowId: this.currentWorkflow };
|
||||
if (this.filter.status === 'waiting') {
|
||||
rFilter.waitTill = true;
|
||||
} else if (this.filter.status !== '') {
|
||||
rFilter.finished = this.filter.status === 'success';
|
||||
}
|
||||
|
||||
switch (this.filter.status as ExecutionStatus) {
|
||||
case 'waiting':
|
||||
rFilter.status = ['waiting'];
|
||||
break;
|
||||
case 'error':
|
||||
rFilter.status = ['failed', 'crashed'];
|
||||
break;
|
||||
case 'success':
|
||||
rFilter.status = ['success'];
|
||||
break;
|
||||
case 'running':
|
||||
rFilter.status = ['running'];
|
||||
break;
|
||||
}
|
||||
|
||||
return rFilter;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route(to: Route, from: Route) {
|
||||
@@ -179,7 +197,7 @@ export default mixins(
|
||||
await this.openWorkflow(this.$route.params.name);
|
||||
this.uiStore.nodeViewInitialized = false;
|
||||
if (this.workflowsStore.currentWorkflowExecutions.length === 0) {
|
||||
this.setExecutions();
|
||||
await this.setExecutions();
|
||||
}
|
||||
if (this.activeExecution) {
|
||||
this.$router
|
||||
@@ -193,7 +211,7 @@ export default mixins(
|
||||
},
|
||||
async onLoadMore(): Promise<void> {
|
||||
if (!this.loadingMore) {
|
||||
this.callDebounced('loadMore', { debounceTime: 1000 });
|
||||
await this.callDebounced('loadMore', { debounceTime: 1000 });
|
||||
}
|
||||
},
|
||||
async loadMore(limit = 20): Promise<void> {
|
||||
@@ -211,15 +229,9 @@ export default mixins(
|
||||
lastId = lastItem.id;
|
||||
}
|
||||
|
||||
const requestFilter: IDataObject = { workflowId: this.currentWorkflow };
|
||||
if (this.filter.status === 'waiting') {
|
||||
requestFilter.waitTill = true;
|
||||
} else if (this.filter.status !== '') {
|
||||
requestFilter.finished = this.filter.status === 'success';
|
||||
}
|
||||
let data: IExecutionsListResponse;
|
||||
try {
|
||||
data = await this.restApi().getPastExecutions(requestFilter, limit, lastId);
|
||||
data = await this.restApi().getPastExecutions(this.requestFilter, limit, lastId);
|
||||
} catch (error) {
|
||||
this.loadingMore = false;
|
||||
this.$showError(error, this.$locale.baseText('executionsList.showError.loadMore.title'));
|
||||
@@ -344,7 +356,7 @@ export default mixins(
|
||||
|
||||
if (existingStillRunning && currentFinished) {
|
||||
existingExecutions[executionIndex] = currentItem;
|
||||
if (currentItem.id === this.activeExecution.id) {
|
||||
if (currentItem.id === this.activeExecution?.id) {
|
||||
updatedActiveExecution = currentItem;
|
||||
}
|
||||
}
|
||||
@@ -371,7 +383,7 @@ export default mixins(
|
||||
if (updatedActiveExecution !== null) {
|
||||
this.workflowsStore.activeWorkflowExecution = updatedActiveExecution;
|
||||
} else {
|
||||
const activeInList = existingExecutions.some((ex) => ex.id === this.activeExecution.id);
|
||||
const activeInList = existingExecutions.some((ex) => ex.id === this.activeExecution?.id);
|
||||
if (!activeInList && this.executions.length > 0) {
|
||||
this.$router
|
||||
.push({
|
||||
@@ -390,7 +402,7 @@ export default mixins(
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
return await this.workflowsStore.loadCurrentWorkflowExecutions(this.filter);
|
||||
return await this.workflowsStore.loadCurrentWorkflowExecutions(this.requestFilter);
|
||||
} catch (error) {
|
||||
if (error.errorCode === NO_NETWORK_ERROR_CODE) {
|
||||
this.$showMessage(
|
||||
@@ -452,7 +464,10 @@ export default mixins(
|
||||
}
|
||||
|
||||
// stop if the execution wasn't found in the first 1000 lookups
|
||||
if (attemptCount >= 10) return;
|
||||
if (attemptCount >= 10) {
|
||||
this.workflowsStore.activeWorkflowExecution = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch next batch of executions
|
||||
await this.loadMore(100);
|
||||
@@ -619,8 +634,7 @@ export default mixins(
|
||||
}
|
||||
},
|
||||
async loadActiveWorkflows(): Promise<void> {
|
||||
const activeWorkflows = await this.restApi().getActiveWorkflows();
|
||||
this.workflowsStore.activeWorkflows = activeWorkflows;
|
||||
this.workflowsStore.activeWorkflows = await this.restApi().getActiveWorkflows();
|
||||
},
|
||||
async onRetryExecution(payload: { execution: IExecutionsSummary; command: string }) {
|
||||
const loadWorkflow = payload.command === 'current-workflow';
|
||||
|
||||
@@ -115,8 +115,7 @@
|
||||
<script lang="ts">
|
||||
import ExecutionCard from '@/components/ExecutionsView/ExecutionCard.vue';
|
||||
import ExecutionsInfoAccordion from '@/components/ExecutionsView/ExecutionsInfoAccordion.vue';
|
||||
import { VIEWS } from '../../constants';
|
||||
import { range as _range } from 'lodash';
|
||||
import { VIEWS } from '@/constants';
|
||||
import { IExecutionsSummary } from '@/Interface';
|
||||
import { Route } from 'vue-router';
|
||||
import Vue from 'vue';
|
||||
@@ -162,8 +161,6 @@ export default Vue.extend({
|
||||
},
|
||||
executionStatuses(): Array<{ id: string; name: string }> {
|
||||
return [
|
||||
{ id: 'crashed', name: this.$locale.baseText('executionsList.error') },
|
||||
{ id: 'new', name: this.$locale.baseText('executionsList.new') },
|
||||
{ id: 'error', name: this.$locale.baseText('executionsList.error') },
|
||||
{ id: 'running', name: this.$locale.baseText('executionsList.running') },
|
||||
{ id: 'success', name: this.$locale.baseText('executionsList.success') },
|
||||
|
||||
@@ -43,13 +43,19 @@ export const executionHelpers = mixins(genericHelpers).extend({
|
||||
if (execution.status === 'waiting' || execution.waitTill) {
|
||||
status.name = 'waiting';
|
||||
status.label = this.$locale.baseText('executionsList.waiting');
|
||||
} else if (execution.status === 'running' || execution.stoppedAt === undefined) {
|
||||
} else if (
|
||||
execution.status === 'running' ||
|
||||
execution.status === 'new' ||
|
||||
execution.stoppedAt === undefined
|
||||
) {
|
||||
status.name = 'running';
|
||||
status.label = this.$locale.baseText('executionsList.running');
|
||||
status.runningTime = this.displayTimer(
|
||||
new Date().getTime() - new Date(execution.startedAt).getTime(),
|
||||
true,
|
||||
);
|
||||
if (execution.startedAt) {
|
||||
status.runningTime = this.displayTimer(
|
||||
new Date().getTime() - new Date(execution.startedAt).getTime(),
|
||||
true,
|
||||
);
|
||||
}
|
||||
} else if (execution.status === 'success' || execution.finished) {
|
||||
status.name = 'success';
|
||||
status.label = this.$locale.baseText('executionsList.succeeded');
|
||||
@@ -59,21 +65,9 @@ export const executionHelpers = mixins(genericHelpers).extend({
|
||||
true,
|
||||
);
|
||||
}
|
||||
} else if (execution.status === 'crashed') {
|
||||
status.name = 'crashed';
|
||||
status.label = this.$locale.baseText('executionsList.error');
|
||||
if (execution.stoppedAt) {
|
||||
status.runningTime = this.displayTimer(
|
||||
new Date(execution.stoppedAt).getTime() - new Date(execution.startedAt).getTime(),
|
||||
true,
|
||||
);
|
||||
}
|
||||
} else if (execution.status === 'new') {
|
||||
status.name = 'new';
|
||||
status.label = this.$locale.baseText('executionsList.new');
|
||||
} else if (
|
||||
execution.status === 'error' ||
|
||||
execution.status === 'failed' ||
|
||||
execution.status === 'crashed' ||
|
||||
execution.stoppedAt !== null
|
||||
) {
|
||||
status.name = 'error';
|
||||
|
||||
@@ -77,7 +77,9 @@ export const restApi = Vue.extend({
|
||||
getActivationError: (id: string): Promise<IActivationError | undefined> => {
|
||||
return self.restApi().makeRestApiRequest('GET', `/active/error/${id}`);
|
||||
},
|
||||
getCurrentExecutions: (filter: object): Promise<IExecutionsCurrentSummaryExtended[]> => {
|
||||
getCurrentExecutions: (
|
||||
filter: IDataObject,
|
||||
): Promise<IExecutionsCurrentSummaryExtended[]> => {
|
||||
let sendData = {};
|
||||
if (filter) {
|
||||
sendData = {
|
||||
@@ -179,7 +181,7 @@ export const restApi = Vue.extend({
|
||||
// Returns all saved executions
|
||||
// TODO: For sure needs some kind of default filter like last day, with max 10 results, ...
|
||||
getPastExecutions: (
|
||||
filter: object,
|
||||
filter: IDataObject,
|
||||
limit: number,
|
||||
lastId?: string,
|
||||
firstId?: string,
|
||||
|
||||
@@ -442,8 +442,6 @@
|
||||
"executionsList.confirmMessage.headline": "Delete Executions?",
|
||||
"executionsList.confirmMessage.message": "Are you sure that you want to delete the {numSelected} selected execution(s)?",
|
||||
"executionsList.clearSelection": "Clear selection",
|
||||
"executionsList.crashed": "Crashed",
|
||||
"executionsList.new": "New",
|
||||
"executionsList.error": "Failed",
|
||||
"executionsList.filters": "Filters",
|
||||
"executionsList.loadMore": "Load More",
|
||||
@@ -482,8 +480,6 @@
|
||||
"executionsList.id": "Execution ID",
|
||||
"executionsList.status": "Status",
|
||||
"executionsList.statusText": "{status} in {time}",
|
||||
"executionsList.statusCrashed": "{status}",
|
||||
"executionsList.statusNew": "{status}",
|
||||
"executionsList.statusRunning": "{status} for {time}",
|
||||
"executionsList.statusWaiting": "{status} until {time}",
|
||||
"executionsList.statusUnknown": "Could not complete",
|
||||
|
||||
@@ -938,33 +938,24 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, {
|
||||
Vue.set(this, 'activeExecutions', newActiveExecutions);
|
||||
},
|
||||
|
||||
async loadCurrentWorkflowExecutions(filter: {
|
||||
finished: boolean;
|
||||
status: string;
|
||||
}): Promise<IExecutionsSummary[]> {
|
||||
async loadCurrentWorkflowExecutions(requestFilter: IDataObject): Promise<IExecutionsSummary[]> {
|
||||
let activeExecutions = [];
|
||||
let finishedExecutions = [];
|
||||
const requestFilter: IDataObject = { workflowId: this.workflowId };
|
||||
|
||||
if (!this.workflowId) {
|
||||
if (!requestFilter.workflowId) {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
const rootStore = useRootStore();
|
||||
if (filter.status === '' || !filter.finished) {
|
||||
activeExecutions = await getCurrentExecutions(rootStore.getRestApiContext, requestFilter);
|
||||
}
|
||||
if (filter.status === '' || filter.finished) {
|
||||
if (filter.status === 'waiting') {
|
||||
requestFilter.waitTill = true;
|
||||
} else if (filter.status !== '') {
|
||||
requestFilter.finished = filter.status === 'success';
|
||||
}
|
||||
finishedExecutions = await getFinishedExecutions(
|
||||
rootStore.getRestApiContext,
|
||||
requestFilter,
|
||||
);
|
||||
if (!requestFilter.status || !requestFilter.finished) {
|
||||
activeExecutions = await getCurrentExecutions(rootStore.getRestApiContext, {
|
||||
workflowId: requestFilter.workflowId,
|
||||
});
|
||||
}
|
||||
finishedExecutions = await getFinishedExecutions(
|
||||
rootStore.getRestApiContext,
|
||||
requestFilter,
|
||||
);
|
||||
this.finishedExecutionsCount = finishedExecutions.count;
|
||||
return [...activeExecutions, ...(finishedExecutions.results || [])];
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user