mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 12:57:29 -08:00
refactor(editor): Migrate WorkflowExecutionsListView.vue
to composition API (no-changelog) (#10198)
This commit is contained in:
parent
3e96b29332
commit
8e960db16c
|
@ -5,10 +5,10 @@
|
|||
:loading="loading && !executions.length"
|
||||
:loading-more="loadingMore"
|
||||
:temporary-execution="temporaryExecution"
|
||||
@update:auto-refresh="$emit('update:auto-refresh', $event)"
|
||||
@reload-executions="$emit('reload')"
|
||||
@filter-updated="$emit('update:filters', $event)"
|
||||
@load-more="$emit('load-more')"
|
||||
@update:auto-refresh="emit('update:auto-refresh', $event)"
|
||||
@reload-executions="emit('reload')"
|
||||
@filter-updated="emit('update:filters', $event)"
|
||||
@load-more="emit('load-more')"
|
||||
@retry-execution="onRetryExecution"
|
||||
/>
|
||||
<div v-if="!hidePreview" :class="$style.content">
|
||||
|
@ -23,177 +23,98 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useRouter } from 'vue-router';
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { onBeforeRouteLeave, useRouter } from 'vue-router';
|
||||
import WorkflowExecutionsSidebar from '@/components/executions/workflow/WorkflowExecutionsSidebar.vue';
|
||||
import {
|
||||
MAIN_HEADER_TABS,
|
||||
MODAL_CANCEL,
|
||||
MODAL_CONFIRM,
|
||||
PLACEHOLDER_EMPTY_WORKFLOW_ID,
|
||||
VIEWS,
|
||||
} from '@/constants';
|
||||
import { MAIN_HEADER_TABS, VIEWS } from '@/constants';
|
||||
import type { ExecutionFilterType, IWorkflowDb } from '@/Interface';
|
||||
import type { ExecutionSummary, IDataObject } from 'n8n-workflow';
|
||||
import { useMessage } from '@/composables/useMessage';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import type { ExecutionSummary } from 'n8n-workflow';
|
||||
import { getNodeViewTab } from '@/utils/canvasUtils';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { useTagsStore } from '@/stores/tags.store';
|
||||
import { executionFilterToQueryFilter } from '@/utils/executionUtils';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
import { useDebounce } from '@/composables/useDebounce';
|
||||
import { useNpsSurveyStore } from '@/stores/npsSurvey.store';
|
||||
import { watch } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'WorkflowExecutionsList',
|
||||
components: {
|
||||
WorkflowExecutionsSidebar,
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
loading: boolean;
|
||||
workflow: IWorkflowDb;
|
||||
executions: ExecutionSummary[];
|
||||
execution?: ExecutionSummary;
|
||||
loadingMore: boolean;
|
||||
}>(),
|
||||
{
|
||||
loading: false,
|
||||
executions: () => [] as ExecutionSummary[],
|
||||
loadingMore: false,
|
||||
},
|
||||
async beforeRouteLeave(to, _, next) {
|
||||
if (getNodeViewTab(to) === MAIN_HEADER_TABS.WORKFLOW) {
|
||||
next();
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
'execution:delete': [value: string];
|
||||
'execution:stop': [value: string];
|
||||
'execution:retry': [value: { id: string; loadWorkflow: boolean }];
|
||||
'update:auto-refresh': [value: boolean];
|
||||
'update:filters': [value: ExecutionFilterType];
|
||||
'load-more': [];
|
||||
reload: [];
|
||||
}>();
|
||||
|
||||
const workflowHelpers = useWorkflowHelpers({ router: useRouter() });
|
||||
const router = useRouter();
|
||||
|
||||
const temporaryExecution = computed(() => {
|
||||
const isTemporary = !props.executions.find((execution) => execution.id === props.execution?.id);
|
||||
return isTemporary ? props.execution : undefined;
|
||||
});
|
||||
|
||||
const hidePreview = computed(() => {
|
||||
return props.loading || (!props.execution && props.executions.length);
|
||||
});
|
||||
|
||||
const onDeleteCurrentExecution = () => {
|
||||
if (!props.execution?.id) return;
|
||||
|
||||
emit('execution:delete', props.execution.id);
|
||||
};
|
||||
|
||||
const onStopExecution = () => {
|
||||
if (!props.execution?.id) return;
|
||||
|
||||
emit('execution:stop', props.execution.id);
|
||||
};
|
||||
|
||||
const onRetryExecution = (payload: { execution: ExecutionSummary; command: string }) => {
|
||||
const loadWorkflow = payload.command === 'current-workflow';
|
||||
|
||||
emit('execution:retry', {
|
||||
id: payload.execution.id,
|
||||
loadWorkflow,
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.execution,
|
||||
(value: ExecutionSummary | undefined) => {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.uiStore.stateIsDirty) {
|
||||
const confirmModal = await this.confirm(
|
||||
this.$locale.baseText('generic.unsavedWork.confirmMessage.message'),
|
||||
{
|
||||
title: this.$locale.baseText('generic.unsavedWork.confirmMessage.headline'),
|
||||
type: 'warning',
|
||||
confirmButtonText: this.$locale.baseText(
|
||||
'generic.unsavedWork.confirmMessage.confirmButtonText',
|
||||
),
|
||||
cancelButtonText: this.$locale.baseText(
|
||||
'generic.unsavedWork.confirmMessage.cancelButtonText',
|
||||
),
|
||||
showClose: true,
|
||||
},
|
||||
);
|
||||
router
|
||||
.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: props.workflow.id, executionId: value.id },
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
);
|
||||
|
||||
if (confirmModal === MODAL_CONFIRM) {
|
||||
const saved = await this.workflowHelpers.saveCurrentWorkflow({}, false);
|
||||
if (saved) {
|
||||
await this.npsSurveyStore.fetchPromptsData();
|
||||
}
|
||||
this.uiStore.stateIsDirty = false;
|
||||
next();
|
||||
} else if (confirmModal === MODAL_CANCEL) {
|
||||
this.uiStore.stateIsDirty = false;
|
||||
next();
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
},
|
||||
props: {
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
workflow: {
|
||||
type: Object as PropType<IWorkflowDb>,
|
||||
required: true,
|
||||
},
|
||||
executions: {
|
||||
type: Array as PropType<ExecutionSummary[]>,
|
||||
default: () => [],
|
||||
},
|
||||
filters: {
|
||||
type: Object as PropType<ExecutionFilterType>,
|
||||
default: () => ({}),
|
||||
},
|
||||
execution: {
|
||||
type: Object as PropType<ExecutionSummary> | null,
|
||||
default: null,
|
||||
},
|
||||
loadingMore: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: [
|
||||
'execution:delete',
|
||||
'execution:stop',
|
||||
'execution:retry',
|
||||
'update:auto-refresh',
|
||||
'update:filters',
|
||||
'load-more',
|
||||
'reload',
|
||||
],
|
||||
setup() {
|
||||
const externalHooks = useExternalHooks();
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers({ router });
|
||||
const { callDebounced } = useDebounce();
|
||||
onBeforeRouteLeave(async (to, _, next) => {
|
||||
if (getNodeViewTab(to) === MAIN_HEADER_TABS.WORKFLOW) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
externalHooks,
|
||||
workflowHelpers,
|
||||
callDebounced,
|
||||
...useToast(),
|
||||
...useMessage(),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useTagsStore, useNodeTypesStore, useSettingsStore, useUIStore, useNpsSurveyStore),
|
||||
temporaryExecution(): ExecutionSummary | undefined {
|
||||
const isTemporary = !this.executions.find((execution) => execution.id === this.execution?.id);
|
||||
return isTemporary ? this.execution : undefined;
|
||||
},
|
||||
hidePreview(): boolean {
|
||||
return this.loading || (!this.execution && this.executions.length);
|
||||
},
|
||||
filterApplied(): boolean {
|
||||
return this.filters.status !== 'all';
|
||||
},
|
||||
workflowDataNotLoaded(): boolean {
|
||||
return this.workflow.id === PLACEHOLDER_EMPTY_WORKFLOW_ID && this.workflow.name === '';
|
||||
},
|
||||
requestFilter(): IDataObject {
|
||||
return executionFilterToQueryFilter({
|
||||
...this.filters,
|
||||
workflowId: this.workflow.id,
|
||||
});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
execution(value: ExecutionSummary) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$router
|
||||
.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.workflow.id, executionId: value.id },
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async onDeleteCurrentExecution(): Promise<void> {
|
||||
this.$emit('execution:delete', this.execution?.id);
|
||||
},
|
||||
async onStopExecution(): Promise<void> {
|
||||
this.$emit('execution:stop', this.execution?.id);
|
||||
},
|
||||
async onRetryExecution(payload: { execution: ExecutionSummary; command: string }) {
|
||||
const loadWorkflow = payload.command === 'current-workflow';
|
||||
|
||||
this.$emit('execution:retry', {
|
||||
id: payload.execution.id,
|
||||
loadWorkflow,
|
||||
});
|
||||
},
|
||||
},
|
||||
await workflowHelpers.promptSaveUnsavedWorkflowChanges(next);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ import { PLACEHOLDER_EMPTY_WORKFLOW_ID, VIEWS } from '@/constants';
|
|||
import { useRoute, useRouter } from 'vue-router';
|
||||
import type { ExecutionSummary } from 'n8n-workflow';
|
||||
import { useDebounce } from '@/composables/useDebounce';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { useNodeHelpers } from '@/composables/useNodeHelpers';
|
||||
|
@ -29,8 +28,6 @@ const { callDebounced } = useDebounce();
|
|||
const workflowHelpers = useWorkflowHelpers({ router });
|
||||
const nodeHelpers = useNodeHelpers();
|
||||
|
||||
const { filters } = storeToRefs(executionsStore);
|
||||
|
||||
const loading = ref(false);
|
||||
const loadingMore = ref(false);
|
||||
|
||||
|
@ -311,7 +308,6 @@ async function loadMore(): Promise<void> {
|
|||
v-if="workflow"
|
||||
:executions="executions"
|
||||
:execution="execution"
|
||||
:filters="filters"
|
||||
:workflow="workflow"
|
||||
:loading="loading"
|
||||
:loading-more="loadingMore"
|
||||
|
|
Loading…
Reference in a new issue