refactor(editor): Apply Prettier (no-changelog) (#4920)
* ⚡ Adjust `format` script * 🔥 Remove exemption for `editor-ui` * 🎨 Prettify * 👕 Fix lint
This commit is contained in:
@@ -10,23 +10,48 @@
|
||||
>
|
||||
<router-link
|
||||
:class="$style.executionLink"
|
||||
:to="{ name: VIEWS.EXECUTION_PREVIEW, params: { workflowId: currentWorkflow, executionId: execution.id }}"
|
||||
:to="{
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { workflowId: currentWorkflow, executionId: execution.id },
|
||||
}"
|
||||
>
|
||||
<div :class="$style.description">
|
||||
<n8n-text color="text-dark" :bold="true" size="medium">{{ executionUIDetails.startTime }}</n8n-text>
|
||||
<n8n-text color="text-dark" :bold="true" size="medium">{{
|
||||
executionUIDetails.startTime
|
||||
}}</n8n-text>
|
||||
<div :class="$style.executionStatus">
|
||||
<n8n-spinner v-if="executionUIDetails.name === 'running'" size="small" :class="[$style.spinner, 'mr-4xs']"/>
|
||||
<n8n-text :class="$style.statusLabel" size="small">{{ executionUIDetails.label }}</n8n-text>
|
||||
<n8n-text v-if="executionUIDetails.name === 'running'" :color="isActive? 'text-dark' : 'text-base'" size="small">
|
||||
<n8n-spinner
|
||||
v-if="executionUIDetails.name === 'running'"
|
||||
size="small"
|
||||
:class="[$style.spinner, 'mr-4xs']"
|
||||
/>
|
||||
<n8n-text :class="$style.statusLabel" size="small">{{
|
||||
executionUIDetails.label
|
||||
}}</n8n-text>
|
||||
<n8n-text
|
||||
v-if="executionUIDetails.name === 'running'"
|
||||
:color="isActive ? 'text-dark' : 'text-base'"
|
||||
size="small"
|
||||
>
|
||||
{{ $locale.baseText('executionDetails.runningTimeRunning') }}
|
||||
<execution-time :start-time="execution.startedAt"/>
|
||||
<execution-time :start-time="execution.startedAt" />
|
||||
</n8n-text>
|
||||
<n8n-text v-else-if="executionUIDetails.name !== 'waiting' && executionUIDetails.name !== 'unknown'" :color="isActive? 'text-dark' : 'text-base'" size="small">
|
||||
{{ $locale.baseText('executionDetails.runningTimeFinished', { interpolate: { time: executionUIDetails.runningTime } }) }}
|
||||
<n8n-text
|
||||
v-else-if="
|
||||
executionUIDetails.name !== 'waiting' && executionUIDetails.name !== 'unknown'
|
||||
"
|
||||
:color="isActive ? 'text-dark' : 'text-base'"
|
||||
size="small"
|
||||
>
|
||||
{{
|
||||
$locale.baseText('executionDetails.runningTimeFinished', {
|
||||
interpolate: { time: executionUIDetails.runningTime },
|
||||
})
|
||||
}}
|
||||
</n8n-text>
|
||||
</div>
|
||||
<div v-if="execution.mode === 'retry'">
|
||||
<n8n-text :color="isActive? 'text-dark' : 'text-base'" size="small">
|
||||
<n8n-text :color="isActive ? 'text-dark' : 'text-base'" size="small">
|
||||
{{ $locale.baseText('executionDetails.retry') }} #{{ execution.retryOf }}
|
||||
</n8n-text>
|
||||
</div>
|
||||
@@ -44,7 +69,7 @@
|
||||
:class="[$style.icon, $style.manual]"
|
||||
:title="$locale.baseText('executionsList.manual')"
|
||||
icon="flask"
|
||||
/>
|
||||
/>
|
||||
</div>
|
||||
</router-link>
|
||||
</div>
|
||||
@@ -59,11 +84,7 @@ import { showMessage } from '@/mixins/showMessage';
|
||||
import { restApi } from '@/mixins/restApi';
|
||||
import ExecutionTime from '@/components/ExecutionTime.vue';
|
||||
|
||||
export default mixins(
|
||||
executionHelpers,
|
||||
showMessage,
|
||||
restApi,
|
||||
).extend({
|
||||
export default mixins(executionHelpers, showMessage, restApi).extend({
|
||||
name: 'execution-card',
|
||||
components: {
|
||||
ExecutionTime,
|
||||
@@ -86,8 +107,14 @@ export default mixins(
|
||||
computed: {
|
||||
retryExecutionActions(): object[] {
|
||||
return [
|
||||
{ id: 'current-workflow', label: this.$locale.baseText('executionsList.retryWithCurrentlySavedWorkflow') },
|
||||
{ id: 'original-workflow', label: this.$locale.baseText('executionsList.retryWithOriginalWorkflow') },
|
||||
{
|
||||
id: 'current-workflow',
|
||||
label: this.$locale.baseText('executionsList.retryWithCurrentlySavedWorkflow'),
|
||||
},
|
||||
{
|
||||
id: 'original-workflow',
|
||||
label: this.$locale.baseText('executionsList.retryWithOriginalWorkflow'),
|
||||
},
|
||||
];
|
||||
},
|
||||
executionUIDetails(): IExecutionUIData {
|
||||
@@ -119,9 +146,12 @@ export default mixins(
|
||||
}
|
||||
}
|
||||
|
||||
& + &.active { padding-top: var(--spacing-2xs); }
|
||||
& + &.active {
|
||||
padding-top: var(--spacing-2xs);
|
||||
}
|
||||
|
||||
&:hover, &.active {
|
||||
&:hover,
|
||||
&.active {
|
||||
.executionLink {
|
||||
background-color: var(--color-foreground-base);
|
||||
}
|
||||
@@ -132,34 +162,47 @@ export default mixins(
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
&, & .executionLink {
|
||||
&,
|
||||
& .executionLink {
|
||||
border-left: var(--spacing-4xs) var(--border-style-base) hsl(var(--color-warning-h), 94%, 80%);
|
||||
}
|
||||
.statusLabel, .spinner { color: var(--color-warning); }
|
||||
.statusLabel,
|
||||
.spinner {
|
||||
color: var(--color-warning);
|
||||
}
|
||||
}
|
||||
|
||||
&.success {
|
||||
&, & .executionLink {
|
||||
&,
|
||||
& .executionLink {
|
||||
border-left: var(--spacing-4xs) var(--border-style-base) hsl(var(--color-success-h), 60%, 70%);
|
||||
}
|
||||
}
|
||||
|
||||
&.waiting {
|
||||
&, & .executionLink {
|
||||
border-left: var(--spacing-4xs) var(--border-style-base) hsl(var(--color-secondary-h), 94%, 80%);
|
||||
&,
|
||||
& .executionLink {
|
||||
border-left: var(--spacing-4xs) var(--border-style-base)
|
||||
hsl(var(--color-secondary-h), 94%, 80%);
|
||||
}
|
||||
.statusLabel {
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
.statusLabel { color: var(--color-secondary); }
|
||||
}
|
||||
|
||||
&.error {
|
||||
&, & .executionLink {
|
||||
&,
|
||||
& .executionLink {
|
||||
border-left: var(--spacing-4xs) var(--border-style-base) hsl(var(--color-danger-h), 94%, 80%);
|
||||
}
|
||||
.statusLabel { color: var(--color-danger ); }
|
||||
.statusLabel {
|
||||
color: var(--color-danger);
|
||||
}
|
||||
}
|
||||
|
||||
&.unknown {
|
||||
&, & .executionLink {
|
||||
&,
|
||||
& .executionLink {
|
||||
border-left: var(--spacing-4xs) var(--border-style-base) var(--color-text-light);
|
||||
}
|
||||
}
|
||||
@@ -176,11 +219,14 @@ export default mixins(
|
||||
padding-right: var(--spacing-s);
|
||||
border-radius: var(--border-radius-base);
|
||||
position: relative;
|
||||
left: calc(-1 * var(--spacing-4xs)); // Hide link border under card border so it's not visible when not hovered
|
||||
left: calc(
|
||||
-1 * var(--spacing-4xs)
|
||||
); // Hide link border under card border so it's not visible when not hovered
|
||||
|
||||
&:active {
|
||||
.icon, .statusLabel {
|
||||
color: var(--color-text-base);;
|
||||
.icon,
|
||||
.statusLabel {
|
||||
color: var(--color-text-base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div v-if="executionUIDetails && executionUIDetails.name === 'running'" :class="$style.runningInfo">
|
||||
<div
|
||||
v-if="executionUIDetails && executionUIDetails.name === 'running'"
|
||||
:class="$style.runningInfo"
|
||||
>
|
||||
<div :class="$style.spinner">
|
||||
<n8n-spinner type="ring" />
|
||||
</div>
|
||||
@@ -11,32 +14,66 @@
|
||||
</n8n-button>
|
||||
</div>
|
||||
<div v-else :class="$style.previewContainer">
|
||||
<div :class="{[$style.executionDetails]: true, [$style.sidebarCollapsed]: sidebarCollapsed }" v-if="activeExecution">
|
||||
<div
|
||||
:class="{ [$style.executionDetails]: true, [$style.sidebarCollapsed]: sidebarCollapsed }"
|
||||
v-if="activeExecution"
|
||||
>
|
||||
<div>
|
||||
<n8n-text size="large" color="text-base" :bold="true">{{ executionUIDetails.startTime }}</n8n-text><br>
|
||||
<n8n-spinner v-if="executionUIDetails.name === 'running'" size="small" :class="[$style.spinner, 'mr-4xs']"/>
|
||||
<n8n-text size="medium" :class="[$style.status, $style[executionUIDetails.name]]">{{ executionUIDetails.label }}</n8n-text>
|
||||
<n8n-text size="large" color="text-base" :bold="true">{{
|
||||
executionUIDetails.startTime
|
||||
}}</n8n-text
|
||||
><br />
|
||||
<n8n-spinner
|
||||
v-if="executionUIDetails.name === 'running'"
|
||||
size="small"
|
||||
:class="[$style.spinner, 'mr-4xs']"
|
||||
/>
|
||||
<n8n-text size="medium" :class="[$style.status, $style[executionUIDetails.name]]">{{
|
||||
executionUIDetails.label
|
||||
}}</n8n-text>
|
||||
<n8n-text v-if="executionUIDetails.name === 'running'" color="text-base" size="medium">
|
||||
{{ $locale.baseText('executionDetails.runningTimeRunning', { interpolate: { time: executionUIDetails.runningTime } }) }} | ID#{{ activeExecution.id }}
|
||||
{{
|
||||
$locale.baseText('executionDetails.runningTimeRunning', {
|
||||
interpolate: { time: executionUIDetails.runningTime },
|
||||
})
|
||||
}}
|
||||
| ID#{{ activeExecution.id }}
|
||||
</n8n-text>
|
||||
<n8n-text v-else-if="executionUIDetails.name !== 'waiting'" color="text-base" size="medium">
|
||||
{{ $locale.baseText('executionDetails.runningTimeFinished', { interpolate: { time: executionUIDetails.runningTime } }) }} | ID#{{ activeExecution.id }}
|
||||
{{
|
||||
$locale.baseText('executionDetails.runningTimeFinished', {
|
||||
interpolate: { time: executionUIDetails.runningTime },
|
||||
})
|
||||
}}
|
||||
| ID#{{ activeExecution.id }}
|
||||
</n8n-text>
|
||||
<n8n-text v-else-if="executionUIDetails.name === 'waiting'" color="text-base" size="medium">
|
||||
| ID#{{ activeExecution.id }}
|
||||
</n8n-text>
|
||||
<br><n8n-text v-if="activeExecution.mode === 'retry'" color="text-base" size= "medium">
|
||||
<br /><n8n-text v-if="activeExecution.mode === 'retry'" color="text-base" size="medium">
|
||||
{{ $locale.baseText('executionDetails.retry') }}
|
||||
<router-link
|
||||
:class="$style.executionLink"
|
||||
:to="{ name: VIEWS.EXECUTION_PREVIEW, params: { workflowId: activeExecution.workflowId, executionId: activeExecution.retryOf }}"
|
||||
:to="{
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: {
|
||||
workflowId: activeExecution.workflowId,
|
||||
executionId: activeExecution.retryOf,
|
||||
},
|
||||
}"
|
||||
>
|
||||
#{{ activeExecution.retryOf }}
|
||||
</router-link>
|
||||
</n8n-text>
|
||||
</div>
|
||||
<div>
|
||||
<el-dropdown v-if="executionUIDetails.name === 'error'" trigger="click" class="mr-xs" @command="handleRetryClick" ref="retryDropdown">
|
||||
<el-dropdown
|
||||
v-if="executionUIDetails.name === 'error'"
|
||||
trigger="click"
|
||||
class="mr-xs"
|
||||
@command="handleRetryClick"
|
||||
ref="retryDropdown"
|
||||
>
|
||||
<span class="retry-button">
|
||||
<n8n-icon-button
|
||||
size="large"
|
||||
@@ -57,10 +94,21 @@
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<n8n-icon-button :title="$locale.baseText('executionDetails.deleteExecution')" icon="trash" size="large" type="tertiary" @click="onDeleteExecution" />
|
||||
<n8n-icon-button
|
||||
:title="$locale.baseText('executionDetails.deleteExecution')"
|
||||
icon="trash"
|
||||
size="large"
|
||||
type="tertiary"
|
||||
@click="onDeleteExecution"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<workflow-preview mode="execution" loaderType="spinner" :executionId="executionId" :executionMode="executionMode"/>
|
||||
<workflow-preview
|
||||
mode="execution"
|
||||
loaderType="spinner"
|
||||
:executionId="executionId"
|
||||
:executionMode="executionMode"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -87,9 +135,7 @@ export default mixins(restApi, showMessage, executionHelpers).extend({
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useUIStore,
|
||||
),
|
||||
...mapStores(useUIStore),
|
||||
executionUIDetails(): IExecutionUIData | null {
|
||||
return this.activeExecution ? this.getExecutionUIDetails(this.activeExecution) : null;
|
||||
},
|
||||
@@ -122,7 +168,7 @@ export default mixins(restApi, showMessage, executionHelpers).extend({
|
||||
},
|
||||
onRetryButtonBlur(event: FocusEvent): void {
|
||||
// Hide dropdown when clicking outside of current document
|
||||
const retryDropdown = this.$refs.retryDropdown as Vue & { hide: () => void } | undefined;
|
||||
const retryDropdown = this.$refs.retryDropdown as (Vue & { hide: () => void }) | undefined;
|
||||
if (retryDropdown && event.relatedTarget === null) {
|
||||
retryDropdown.hide();
|
||||
}
|
||||
@@ -132,7 +178,6 @@ export default mixins(restApi, showMessage, executionHelpers).extend({
|
||||
</script>
|
||||
|
||||
<style module lang="scss">
|
||||
|
||||
.previewContainer {
|
||||
height: calc(100% - $header-height);
|
||||
overflow: hidden;
|
||||
@@ -148,7 +193,9 @@ export default mixins(restApi, showMessage, executionHelpers).extend({
|
||||
transition: all 150ms ease-in-out;
|
||||
pointer-events: none;
|
||||
|
||||
& * { pointer-events: all; }
|
||||
& * {
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
&.sidebarCollapsed {
|
||||
width: calc(100% - 375px);
|
||||
@@ -163,10 +210,19 @@ export default mixins(restApi, showMessage, executionHelpers).extend({
|
||||
}
|
||||
}
|
||||
|
||||
.running, .spinner { color: var(--color-warning); }
|
||||
.waiting { color: var(--color-secondary); }
|
||||
.success { color: var(--color-success); }
|
||||
.error { color: var(--color-danger); }
|
||||
.running,
|
||||
.spinner {
|
||||
color: var(--color-warning);
|
||||
}
|
||||
.waiting {
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
.success {
|
||||
color: var(--color-success);
|
||||
}
|
||||
.error {
|
||||
color: var(--color-danger);
|
||||
}
|
||||
|
||||
.runningInfo {
|
||||
display: flex;
|
||||
|
||||
@@ -14,11 +14,19 @@
|
||||
<n8n-tooltip :disabled="!isNewWorkflow">
|
||||
<template #content>
|
||||
<div>
|
||||
<n8n-link @click.prevent="onSaveWorkflowClick">{{ $locale.baseText('executionsLandingPage.emptyState.accordion.footer.tooltipLink') }}</n8n-link>
|
||||
{{ $locale.baseText('executionsLandingPage.emptyState.accordion.footer.tooltipText') }}
|
||||
<n8n-link @click.prevent="onSaveWorkflowClick">{{
|
||||
$locale.baseText('executionsLandingPage.emptyState.accordion.footer.tooltipLink')
|
||||
}}</n8n-link>
|
||||
{{
|
||||
$locale.baseText('executionsLandingPage.emptyState.accordion.footer.tooltipText')
|
||||
}}
|
||||
</div>
|
||||
</template>
|
||||
<n8n-link @click.prevent="openWorkflowSettings" :class="{[$style.disabled]: isNewWorkflow}" size="small">
|
||||
<n8n-link
|
||||
@click.prevent="openWorkflowSettings"
|
||||
:class="{ [$style.disabled]: isNewWorkflow }"
|
||||
size="small"
|
||||
>
|
||||
{{ $locale.baseText('executionsLandingPage.emptyState.accordion.footer.settingsLink') }}
|
||||
</n8n-link>
|
||||
</n8n-tooltip>
|
||||
@@ -39,10 +47,10 @@ import mixins from 'vue-typed-mixins';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
|
||||
interface IWorkflowSaveSettings {
|
||||
saveFailedExecutions: boolean,
|
||||
saveSuccessfulExecutions: boolean,
|
||||
saveManualExecutions: boolean,
|
||||
};
|
||||
saveFailedExecutions: boolean;
|
||||
saveSuccessfulExecutions: boolean;
|
||||
saveManualExecutions: boolean;
|
||||
}
|
||||
|
||||
export default mixins(workflowHelpers).extend({
|
||||
name: 'executions-info-accordion',
|
||||
@@ -78,24 +86,28 @@ export default mixins(workflowHelpers).extend({
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useRootStore,
|
||||
useSettingsStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
...mapStores(useRootStore, useSettingsStore, useUIStore, useWorkflowsStore),
|
||||
accordionItems(): Object[] {
|
||||
return [
|
||||
{
|
||||
id: 'productionExecutions',
|
||||
label: this.$locale.baseText('executionsLandingPage.emptyState.accordion.productionExecutions'),
|
||||
label: this.$locale.baseText(
|
||||
'executionsLandingPage.emptyState.accordion.productionExecutions',
|
||||
),
|
||||
icon: this.productionExecutionsIcon.icon,
|
||||
iconColor: this.productionExecutionsIcon.color,
|
||||
tooltip: this.productionExecutionsStatus === 'unknown' ? this.$locale.baseText('executionsLandingPage.emptyState.accordion.productionExecutionsWarningTooltip') : null,
|
||||
tooltip:
|
||||
this.productionExecutionsStatus === 'unknown'
|
||||
? this.$locale.baseText(
|
||||
'executionsLandingPage.emptyState.accordion.productionExecutionsWarningTooltip',
|
||||
)
|
||||
: null,
|
||||
},
|
||||
{
|
||||
id: 'manualExecutions',
|
||||
label: this.$locale.baseText('executionsLandingPage.emptyState.accordion.manualExecutions'),
|
||||
label: this.$locale.baseText(
|
||||
'executionsLandingPage.emptyState.accordion.manualExecutions',
|
||||
),
|
||||
icon: this.workflowSaveSettings.saveManualExecutions ? 'check' : 'times',
|
||||
iconColor: this.workflowSaveSettings.saveManualExecutions ? 'success' : 'danger',
|
||||
},
|
||||
@@ -105,11 +117,13 @@ export default mixins(workflowHelpers).extend({
|
||||
if (this.initiallyExpanded === false) {
|
||||
return false;
|
||||
}
|
||||
return this.workflowSaveSettings.saveFailedExecutions === false ||
|
||||
return (
|
||||
this.workflowSaveSettings.saveFailedExecutions === false ||
|
||||
this.workflowSaveSettings.saveSuccessfulExecutions === false ||
|
||||
this.workflowSaveSettings.saveManualExecutions === false;
|
||||
this.workflowSaveSettings.saveManualExecutions === false
|
||||
);
|
||||
},
|
||||
productionExecutionsIcon(): { icon: string, color: string } {
|
||||
productionExecutionsIcon(): { icon: string; color: string } {
|
||||
if (this.productionExecutionsStatus === 'saving') {
|
||||
return { icon: 'check', color: 'success' };
|
||||
} else if (this.productionExecutionsStatus === 'not-saving') {
|
||||
@@ -118,7 +132,10 @@ export default mixins(workflowHelpers).extend({
|
||||
return { icon: 'exclamation-triangle', color: 'warning' };
|
||||
},
|
||||
productionExecutionsStatus(): string {
|
||||
if (this.workflowSaveSettings.saveSuccessfulExecutions === this.workflowSaveSettings.saveFailedExecutions) {
|
||||
if (
|
||||
this.workflowSaveSettings.saveSuccessfulExecutions ===
|
||||
this.workflowSaveSettings.saveFailedExecutions
|
||||
) {
|
||||
if (this.workflowSaveSettings.saveSuccessfulExecutions === true) {
|
||||
return 'saving';
|
||||
}
|
||||
@@ -131,8 +148,11 @@ export default mixins(workflowHelpers).extend({
|
||||
const workflowSettings = deepCopy(this.workflowsStore.workflowSettings);
|
||||
return workflowSettings;
|
||||
},
|
||||
accordionIcon(): { icon: string, color: string }|null {
|
||||
if (this.workflowSaveSettings.saveManualExecutions !== true || this.productionExecutionsStatus !== 'saving') {
|
||||
accordionIcon(): { icon: string; color: string } | null {
|
||||
if (
|
||||
this.workflowSaveSettings.saveManualExecutions !== true ||
|
||||
this.productionExecutionsStatus !== 'saving'
|
||||
) {
|
||||
return { icon: 'exclamation-triangle', color: 'warning' };
|
||||
}
|
||||
return null;
|
||||
@@ -141,7 +161,11 @@ export default mixins(workflowHelpers).extend({
|
||||
return this.workflowsStore.workflowId;
|
||||
},
|
||||
isNewWorkflow(): boolean {
|
||||
return !this.currentWorkflowId || (this.currentWorkflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID || this.currentWorkflowId === 'new');
|
||||
return (
|
||||
!this.currentWorkflowId ||
|
||||
this.currentWorkflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID ||
|
||||
this.currentWorkflowId === 'new'
|
||||
);
|
||||
},
|
||||
workflowName(): string {
|
||||
return this.workflowsStore.workflowName;
|
||||
@@ -152,9 +176,18 @@ export default mixins(workflowHelpers).extend({
|
||||
},
|
||||
methods: {
|
||||
updateSettings(workflowSettings: IWorkflowSettings): void {
|
||||
this.workflowSaveSettings.saveFailedExecutions = workflowSettings.saveDataErrorExecution === undefined ? this.defaultValues.saveFailedExecutions === 'all' : workflowSettings.saveDataErrorExecution === 'all';
|
||||
this.workflowSaveSettings.saveSuccessfulExecutions = workflowSettings.saveDataSuccessExecution === undefined ? this.defaultValues.saveSuccessfulExecutions === 'all' : workflowSettings.saveDataSuccessExecution === 'all';
|
||||
this.workflowSaveSettings.saveManualExecutions = workflowSettings.saveManualExecutions === undefined ? this.defaultValues.saveManualExecutions : workflowSettings.saveManualExecutions as boolean;
|
||||
this.workflowSaveSettings.saveFailedExecutions =
|
||||
workflowSettings.saveDataErrorExecution === undefined
|
||||
? this.defaultValues.saveFailedExecutions === 'all'
|
||||
: workflowSettings.saveDataErrorExecution === 'all';
|
||||
this.workflowSaveSettings.saveSuccessfulExecutions =
|
||||
workflowSettings.saveDataSuccessExecution === undefined
|
||||
? this.defaultValues.saveSuccessfulExecutions === 'all'
|
||||
: workflowSettings.saveDataSuccessExecution === 'all';
|
||||
this.workflowSaveSettings.saveManualExecutions =
|
||||
workflowSettings.saveManualExecutions === undefined
|
||||
? this.defaultValues.saveManualExecutions
|
||||
: (workflowSettings.saveManualExecutions as boolean);
|
||||
},
|
||||
onAccordionClick(event: MouseEvent): void {
|
||||
if (event.target instanceof HTMLAnchorElement) {
|
||||
@@ -178,7 +211,11 @@ export default mixins(workflowHelpers).extend({
|
||||
} else if (this.$route.params.name && this.$route.params.name !== 'new') {
|
||||
currentId = this.$route.params.name;
|
||||
}
|
||||
const saved = await this.saveCurrentWorkflow({ id: currentId, name: this.workflowName, tags: this.currentWorkflowTagIds });
|
||||
const saved = await this.saveCurrentWorkflow({
|
||||
id: currentId,
|
||||
name: this.workflowName,
|
||||
tags: this.currentWorkflowTagIds,
|
||||
});
|
||||
if (saved) this.settingsStore.fetchPromptsData();
|
||||
},
|
||||
},
|
||||
@@ -186,7 +223,6 @@ export default mixins(workflowHelpers).extend({
|
||||
</script>
|
||||
|
||||
<style module lang="scss">
|
||||
|
||||
.accordion {
|
||||
background: none;
|
||||
width: 320px;
|
||||
@@ -208,7 +244,9 @@ export default mixins(workflowHelpers).extend({
|
||||
width: 100%;
|
||||
padding: 0 var(--spacing-l) var(--spacing-s) !important;
|
||||
|
||||
span { width: 100%; }
|
||||
span {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
@@ -224,5 +262,4 @@ export default mixins(workflowHelpers).extend({
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -39,10 +39,7 @@ export default Vue.extend({
|
||||
ExecutionsInfoAccordion,
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
...mapStores(useUIStore, useWorkflowsStore),
|
||||
executionCount(): number {
|
||||
return this.workflowsStore.currentWorkflowExecutions.length;
|
||||
},
|
||||
@@ -56,7 +53,7 @@ export default Vue.extend({
|
||||
const workflowRoute = this.getWorkflowRoute();
|
||||
this.$router.push(workflowRoute);
|
||||
},
|
||||
getWorkflowRoute(): { name: string, params: {}} {
|
||||
getWorkflowRoute(): { name: string; params: {} } {
|
||||
const workflowId = this.workflowsStore.workflowId || this.$route.params.name;
|
||||
if (workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID) {
|
||||
return { name: VIEWS.NEW_WORKFLOW, params: {} };
|
||||
@@ -69,7 +66,6 @@ export default Vue.extend({
|
||||
</script>
|
||||
|
||||
<style module lang="scss">
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<template>
|
||||
<div :class="['executions-sidebar', $style.container]">
|
||||
<div :class="$style.heading">
|
||||
<n8n-heading tag="h2" size="medium" color="text-dark">
|
||||
<n8n-heading tag="h2" size="medium" color="text-dark">
|
||||
{{ $locale.baseText('generic.executions') }}
|
||||
</n8n-heading>
|
||||
</div>
|
||||
<div :class="$style.controls">
|
||||
<el-checkbox v-model="autoRefresh" @change="onAutoRefreshToggle">{{ $locale.baseText('executionsList.autoRefresh') }}</el-checkbox>
|
||||
<n8n-popover trigger="click" >
|
||||
<el-checkbox v-model="autoRefresh" @change="onAutoRefreshToggle">{{
|
||||
$locale.baseText('executionsList.autoRefresh')
|
||||
}}</el-checkbox>
|
||||
<n8n-popover trigger="click">
|
||||
<template #reference>
|
||||
<div :class="$style.filterButton">
|
||||
<n8n-button icon="filter" type="tertiary" size="medium" :active="statusFilterApplied">
|
||||
@@ -37,7 +39,8 @@
|
||||
v-for="item in executionStatuses"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id">
|
||||
:value="item.id"
|
||||
>
|
||||
</n8n-option>
|
||||
</n8n-select>
|
||||
</div>
|
||||
@@ -86,7 +89,7 @@ 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 { IExecutionsSummary } from "@/Interface";
|
||||
import { IExecutionsSummary } from '@/Interface';
|
||||
import { Route } from 'vue-router';
|
||||
import Vue from 'vue';
|
||||
import { PropType } from 'vue';
|
||||
@@ -124,13 +127,11 @@ export default Vue.extend({
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useUIStore,
|
||||
),
|
||||
...mapStores(useUIStore),
|
||||
statusFilterApplied(): boolean {
|
||||
return this.filter.status !== '';
|
||||
},
|
||||
executionStatuses(): Array<{ id: string, name: string }> {
|
||||
executionStatuses(): Array<{ id: string; name: string }> {
|
||||
return [
|
||||
{ id: 'error', name: this.$locale.baseText('executionsList.error') },
|
||||
{ id: 'running', name: this.$locale.baseText('executionsList.running') },
|
||||
@@ -140,12 +141,12 @@ export default Vue.extend({
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route (to: Route, from: Route) {
|
||||
$route(to: Route, from: Route) {
|
||||
if (from.name === VIEWS.EXECUTION_PREVIEW && to.name === VIEWS.EXECUTION_HOME) {
|
||||
// Skip parent route when navigating through executions with back button
|
||||
this.$router.go(-1);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.autoRefresh = this.uiStore.executionSidebarAutoRefresh === true;
|
||||
@@ -164,8 +165,9 @@ export default Vue.extend({
|
||||
if (!this.loading) {
|
||||
const executionsList = this.$refs.executionList as HTMLElement;
|
||||
if (executionsList) {
|
||||
const diff = executionsList.offsetHeight - (executionsList.scrollHeight - executionsList.scrollTop);
|
||||
if (diff > -10 && diff < 10) {
|
||||
const diff =
|
||||
executionsList.offsetHeight - (executionsList.scrollHeight - executionsList.scrollTop);
|
||||
if (diff > -10 && diff < 10) {
|
||||
this.$emit('loadMore');
|
||||
}
|
||||
}
|
||||
@@ -269,7 +271,7 @@ export default Vue.extend({
|
||||
& > div {
|
||||
width: 309px;
|
||||
background-color: var(--color-background-light);
|
||||
margin-top: 0 !important;
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -29,9 +29,29 @@
|
||||
|
||||
<script lang="ts">
|
||||
import ExecutionsSidebar from '@/components/ExecutionsView/ExecutionsSidebar.vue';
|
||||
import { MODAL_CANCEL, MODAL_CLOSE, MODAL_CONFIRMED, PLACEHOLDER_EMPTY_WORKFLOW_ID, VIEWS, WEBHOOK_NODE_TYPE } from '@/constants';
|
||||
import { IExecutionsListResponse, IExecutionsSummary, INodeUi, ITag, IWorkflowDb } from '@/Interface';
|
||||
import { IConnection, IConnections, IDataObject, INodeTypeDescription, INodeTypeNameVersion, NodeHelpers } from 'n8n-workflow';
|
||||
import {
|
||||
MODAL_CANCEL,
|
||||
MODAL_CLOSE,
|
||||
MODAL_CONFIRMED,
|
||||
PLACEHOLDER_EMPTY_WORKFLOW_ID,
|
||||
VIEWS,
|
||||
WEBHOOK_NODE_TYPE,
|
||||
} from '@/constants';
|
||||
import {
|
||||
IExecutionsListResponse,
|
||||
IExecutionsSummary,
|
||||
INodeUi,
|
||||
ITag,
|
||||
IWorkflowDb,
|
||||
} from '@/Interface';
|
||||
import {
|
||||
IConnection,
|
||||
IConnections,
|
||||
IDataObject,
|
||||
INodeTypeDescription,
|
||||
INodeTypeNameVersion,
|
||||
NodeHelpers,
|
||||
} from 'n8n-workflow';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { restApi } from '@/mixins/restApi';
|
||||
import { showMessage } from '@/mixins/showMessage';
|
||||
@@ -49,7 +69,13 @@ import { useSettingsStore } from '@/stores/settings';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||
import { useTagsStore } from '@/stores/tags';
|
||||
|
||||
export default mixins(restApi, showMessage, executionHelpers, debounceHelper, workflowHelpers).extend({
|
||||
export default mixins(
|
||||
restApi,
|
||||
showMessage,
|
||||
executionHelpers,
|
||||
debounceHelper,
|
||||
workflowHelpers,
|
||||
).extend({
|
||||
name: 'executions-page',
|
||||
components: {
|
||||
ExecutionsSidebar,
|
||||
@@ -62,16 +88,14 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(
|
||||
useTagsStore,
|
||||
useNodeTypesStore,
|
||||
useSettingsStore,
|
||||
useUIStore,
|
||||
useWorkflowsStore,
|
||||
),
|
||||
...mapStores(useTagsStore, useNodeTypesStore, useSettingsStore, useUIStore, useWorkflowsStore),
|
||||
hidePreview(): boolean {
|
||||
const nothingToShow = this.executions.length === 0 && this.filterApplied;
|
||||
const activeNotPresent = this.filterApplied && (this.executions as IExecutionsSummary[]).find(ex => ex.id === this.activeExecution.id) === undefined;
|
||||
const activeNotPresent =
|
||||
this.filterApplied &&
|
||||
(this.executions as IExecutionsSummary[]).find(
|
||||
(ex) => ex.id === this.activeExecution.id,
|
||||
) === undefined;
|
||||
return this.loading || nothingToShow || activeNotPresent;
|
||||
},
|
||||
showSidebar(): boolean {
|
||||
@@ -84,7 +108,10 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
return this.filter.status !== '';
|
||||
},
|
||||
workflowDataNotLoaded(): boolean {
|
||||
return this.workflowsStore.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID && this.workflowsStore.workflowName === '';
|
||||
return (
|
||||
this.workflowsStore.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID &&
|
||||
this.workflowsStore.workflowName === ''
|
||||
);
|
||||
},
|
||||
loadedFinishedExecutionsCount(): number {
|
||||
return this.workflowsStore.getAllLoadedFinishedExecutions.length;
|
||||
@@ -93,8 +120,8 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
return this.workflowsStore.getTotalFinishedExecutionsCount;
|
||||
},
|
||||
},
|
||||
watch:{
|
||||
$route (to: Route, from: Route) {
|
||||
watch: {
|
||||
$route(to: Route, from: Route) {
|
||||
const workflowChanged = from.params.name !== to.params.name;
|
||||
this.initView(workflowChanged);
|
||||
|
||||
@@ -141,7 +168,9 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
async mounted() {
|
||||
this.loading = true;
|
||||
const workflowUpdated = this.$route.params.name !== this.workflowsStore.workflowId;
|
||||
const onNewWorkflow = this.$route.params.name === 'new' && this.workflowsStore.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID;
|
||||
const onNewWorkflow =
|
||||
this.$route.params.name === 'new' &&
|
||||
this.workflowsStore.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID;
|
||||
const shouldUpdate = workflowUpdated && !onNewWorkflow;
|
||||
await this.initView(shouldUpdate);
|
||||
if (!shouldUpdate) {
|
||||
@@ -150,7 +179,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
this.loading = false;
|
||||
},
|
||||
methods: {
|
||||
async initView(loadWorkflow: boolean) : Promise<void> {
|
||||
async initView(loadWorkflow: boolean): Promise<void> {
|
||||
if (loadWorkflow) {
|
||||
if (this.nodeTypesStore.allNodeTypes.length === 0) {
|
||||
await this.nodeTypesStore.getNodeTypes();
|
||||
@@ -159,20 +188,25 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
this.uiStore.nodeViewInitialized = false;
|
||||
this.setExecutions();
|
||||
if (this.activeExecution) {
|
||||
this.$router.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.currentWorkflow, executionId: this.activeExecution.id },
|
||||
}).catch(()=>{});;
|
||||
this.$router
|
||||
.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.currentWorkflow, executionId: this.activeExecution.id },
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
}
|
||||
},
|
||||
async onLoadMore(): Promise<void> {
|
||||
if (!this.loadingMore) {
|
||||
this.callDebounced("loadMore", { debounceTime: 1000 });
|
||||
this.callDebounced('loadMore', { debounceTime: 1000 });
|
||||
}
|
||||
},
|
||||
async loadMore(): Promise<void> {
|
||||
if (this.filter.status === 'running' || this.loadedFinishedExecutionsCount >= this.totalFinishedExecutionsCount) {
|
||||
if (
|
||||
this.filter.status === 'running' ||
|
||||
this.loadedFinishedExecutionsCount >= this.totalFinishedExecutionsCount
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.loadingMore = true;
|
||||
@@ -186,7 +220,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
const requestFilter: IDataObject = { workflowId: this.currentWorkflow };
|
||||
if (this.filter.status === 'waiting') {
|
||||
requestFilter.waitTill = true;
|
||||
} else if (this.filter.status !== '') {
|
||||
} else if (this.filter.status !== '') {
|
||||
requestFilter.finished = this.filter.status === 'success';
|
||||
}
|
||||
let data: IExecutionsListResponse;
|
||||
@@ -194,10 +228,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
data = await this.restApi().getPastExecutions(requestFilter, 20, lastId);
|
||||
} catch (error) {
|
||||
this.loadingMore = false;
|
||||
this.$showError(
|
||||
error,
|
||||
this.$locale.baseText('executionsList.showError.loadMore.title'),
|
||||
);
|
||||
this.$showError(error, this.$locale.baseText('executionsList.showError.loadMore.title'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -205,9 +236,9 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
// @ts-ignore
|
||||
return { ...execution, mode: execution.mode };
|
||||
});
|
||||
const currentExecutions = [ ...this.executions ];
|
||||
const currentExecutions = [...this.executions];
|
||||
for (const newExecution of data.results) {
|
||||
if (currentExecutions.find(ex => ex.id === newExecution.id) === undefined) {
|
||||
if (currentExecutions.find((ex) => ex.id === newExecution.id) === undefined) {
|
||||
currentExecutions.push(newExecution);
|
||||
}
|
||||
}
|
||||
@@ -217,16 +248,19 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
async onDeleteCurrentExecution(): Promise<void> {
|
||||
this.loading = true;
|
||||
try {
|
||||
await this.restApi().deleteExecutions({ ids: [ this.$route.params.executionId ] });
|
||||
await this.restApi().deleteExecutions({ ids: [this.$route.params.executionId] });
|
||||
await this.setExecutions();
|
||||
// Select first execution in the list after deleting the current one
|
||||
if (this.executions.length > 0) {
|
||||
this.workflowsStore.activeWorkflowExecution = this.executions[0];
|
||||
this.$router.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.currentWorkflow, executionId: this.executions[0].id },
|
||||
}).catch(()=>{});;
|
||||
} else { // If there are no executions left, show empty state and clear active execution from the store
|
||||
this.$router
|
||||
.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.currentWorkflow, executionId: this.executions[0].id },
|
||||
})
|
||||
.catch(() => {});
|
||||
} else {
|
||||
// If there are no executions left, show empty state and clear active execution from the store
|
||||
this.workflowsStore.activeWorkflowExecution = null;
|
||||
this.$router.push({ name: VIEWS.EXECUTION_HOME, params: { name: this.currentWorkflow } });
|
||||
}
|
||||
@@ -253,10 +287,9 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
|
||||
this.$showMessage({
|
||||
title: this.$locale.baseText('executionsList.showMessage.stopExecution.title'),
|
||||
message: this.$locale.baseText(
|
||||
'executionsList.showMessage.stopExecution.message',
|
||||
{ interpolate: { activeExecutionId } },
|
||||
),
|
||||
message: this.$locale.baseText('executionsList.showMessage.stopExecution.message', {
|
||||
interpolate: { activeExecutionId },
|
||||
}),
|
||||
type: 'success',
|
||||
});
|
||||
|
||||
@@ -268,7 +301,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
);
|
||||
}
|
||||
},
|
||||
onFilterUpdated(newFilter: { finished: boolean, status: string }): void {
|
||||
onFilterUpdated(newFilter: { finished: boolean; status: string }): void {
|
||||
this.filter = newFilter;
|
||||
this.setExecutions();
|
||||
},
|
||||
@@ -280,13 +313,13 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
async loadAutoRefresh(): Promise<void> {
|
||||
// Most of the auto-refresh logic is taken from the `ExecutionsList` component
|
||||
const fetchedExecutions: IExecutionsSummary[] = await this.loadExecutions();
|
||||
let existingExecutions: IExecutionsSummary[] = [ ...this.executions ];
|
||||
const alreadyPresentExecutionIds = existingExecutions.map(exec => parseInt(exec.id, 10));
|
||||
let existingExecutions: IExecutionsSummary[] = [...this.executions];
|
||||
const alreadyPresentExecutionIds = existingExecutions.map((exec) => parseInt(exec.id, 10));
|
||||
let lastId = 0;
|
||||
const gaps = [] as number[];
|
||||
let updatedActiveExecution = null;
|
||||
|
||||
for(let i = fetchedExecutions.length - 1; i >= 0; i--) {
|
||||
for (let i = fetchedExecutions.length - 1; i >= 0; i--) {
|
||||
const currentItem = fetchedExecutions[i];
|
||||
const currentId = parseInt(currentItem.id, 10);
|
||||
if (lastId !== 0 && isNaN(currentId) === false) {
|
||||
@@ -299,9 +332,12 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
|
||||
const executionIndex = alreadyPresentExecutionIds.indexOf(currentId);
|
||||
if (executionIndex !== -1) {
|
||||
const existingExecution = existingExecutions.find(ex => ex.id === currentItem.id);
|
||||
const existingStillRunning = existingExecution && existingExecution.finished === false || existingExecution?.stoppedAt === undefined;
|
||||
const currentFinished = currentItem.finished === true || currentItem.stoppedAt !== undefined;
|
||||
const existingExecution = existingExecutions.find((ex) => ex.id === currentItem.id);
|
||||
const existingStillRunning =
|
||||
(existingExecution && existingExecution.finished === false) ||
|
||||
existingExecution?.stoppedAt === undefined;
|
||||
const currentFinished =
|
||||
currentItem.finished === true || currentItem.stoppedAt !== undefined;
|
||||
|
||||
if (existingStillRunning && currentFinished) {
|
||||
existingExecutions[executionIndex] = currentItem;
|
||||
@@ -324,19 +360,25 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
}
|
||||
}
|
||||
|
||||
existingExecutions = existingExecutions.filter(execution => !gaps.includes(parseInt(execution.id, 10)) && lastId >= parseInt(execution.id, 10));
|
||||
existingExecutions = existingExecutions.filter(
|
||||
(execution) =>
|
||||
!gaps.includes(parseInt(execution.id, 10)) && lastId >= parseInt(execution.id, 10),
|
||||
);
|
||||
this.workflowsStore.currentWorkflowExecutions = existingExecutions;
|
||||
if (updatedActiveExecution !== null) {
|
||||
this.workflowsStore.activeWorkflowExecution = updatedActiveExecution;
|
||||
} else {
|
||||
const activeNotInTheList = existingExecutions.find(ex => ex.id === this.activeExecution.id) === undefined;
|
||||
const activeNotInTheList =
|
||||
existingExecutions.find((ex) => ex.id === this.activeExecution.id) === undefined;
|
||||
if (activeNotInTheList && this.executions.length > 0) {
|
||||
this.$router.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.currentWorkflow, executionId: this.executions[0].id },
|
||||
}).catch(()=>{});
|
||||
this.$router
|
||||
.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.currentWorkflow, executionId: this.executions[0].id },
|
||||
})
|
||||
.catch(() => {});
|
||||
} else if (this.executions.length === 0) {
|
||||
this.$router.push({ name: VIEWS.EXECUTION_HOME }).catch(()=>{});
|
||||
this.$router.push({ name: VIEWS.EXECUTION_HOME }).catch(() => {});
|
||||
this.workflowsStore.activeWorkflowExecution = null;
|
||||
}
|
||||
}
|
||||
@@ -350,10 +392,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
await this.workflowsStore.loadCurrentWorkflowExecutions(this.filter);
|
||||
return executions;
|
||||
} catch (error) {
|
||||
this.$showError(
|
||||
error,
|
||||
this.$locale.baseText('executionsList.showError.refreshData.title'),
|
||||
);
|
||||
this.$showError(error, this.$locale.baseText('executionsList.showError.refreshData.title'));
|
||||
return [];
|
||||
}
|
||||
},
|
||||
@@ -368,56 +407,56 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
// If there is no execution in the route, select the first one
|
||||
if (this.workflowsStore.activeWorkflowExecution === null && this.executions.length > 0) {
|
||||
this.workflowsStore.activeWorkflowExecution = this.executions[0];
|
||||
this.$router.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.currentWorkflow, executionId: this.executions[0].id },
|
||||
}).catch(()=>{});;
|
||||
this.$router
|
||||
.push({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: this.currentWorkflow, executionId: this.executions[0].id },
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
},
|
||||
async openWorkflow(workflowId: string): Promise<void> {
|
||||
await this.loadActiveWorkflows();
|
||||
|
||||
let data: IWorkflowDb | undefined;
|
||||
try {
|
||||
data = await this.restApi().getWorkflow(workflowId);
|
||||
} catch (error) {
|
||||
this.$showError(
|
||||
error,
|
||||
this.$locale.baseText('nodeView.showError.openWorkflow.title'),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (data === undefined) {
|
||||
throw new Error(
|
||||
this.$locale.baseText(
|
||||
'nodeView.workflowWithIdCouldNotBeFound',
|
||||
{ interpolate: { workflowId } },
|
||||
),
|
||||
);
|
||||
}
|
||||
await this.addNodes(data.nodes, data.connections);
|
||||
try {
|
||||
data = await this.restApi().getWorkflow(workflowId);
|
||||
} catch (error) {
|
||||
this.$showError(error, this.$locale.baseText('nodeView.showError.openWorkflow.title'));
|
||||
return;
|
||||
}
|
||||
if (data === undefined) {
|
||||
throw new Error(
|
||||
this.$locale.baseText('nodeView.workflowWithIdCouldNotBeFound', {
|
||||
interpolate: { workflowId },
|
||||
}),
|
||||
);
|
||||
}
|
||||
await this.addNodes(data.nodes, data.connections);
|
||||
|
||||
this.workflowsStore.setActive(data.active || false);
|
||||
this.workflowsStore.setWorkflowId(workflowId);
|
||||
this.workflowsStore.setWorkflowName({ newName: data.name, setStateDirty: false });
|
||||
this.workflowsStore.setWorkflowSettings(data.settings || {});
|
||||
this.workflowsStore.setWorkflowPinData(data.pinData || {});
|
||||
const tags = (data.tags || []) as ITag[];
|
||||
const tagIds = tags.map((tag) => tag.id);
|
||||
this.workflowsStore.setWorkflowTagIds(tagIds || []);
|
||||
this.workflowsStore.setWorkflowVersionId(data.versionId);
|
||||
this.workflowsStore.setActive(data.active || false);
|
||||
this.workflowsStore.setWorkflowId(workflowId);
|
||||
this.workflowsStore.setWorkflowName({ newName: data.name, setStateDirty: false });
|
||||
this.workflowsStore.setWorkflowSettings(data.settings || {});
|
||||
this.workflowsStore.setWorkflowPinData(data.pinData || {});
|
||||
const tags = (data.tags || []) as ITag[];
|
||||
const tagIds = tags.map((tag) => tag.id);
|
||||
this.workflowsStore.setWorkflowTagIds(tagIds || []);
|
||||
this.workflowsStore.setWorkflowVersionId(data.versionId);
|
||||
|
||||
this.tagsStore.upsertTags(tags);
|
||||
this.tagsStore.upsertTags(tags);
|
||||
|
||||
this.$externalHooks().run('workflow.open', { workflowId, workflowName: data.name });
|
||||
this.uiStore.stateIsDirty = false;
|
||||
this.$externalHooks().run('workflow.open', { workflowId, workflowName: data.name });
|
||||
this.uiStore.stateIsDirty = false;
|
||||
},
|
||||
async addNodes(nodes: INodeUi[], connections?: IConnections) {
|
||||
if (!nodes || !nodes.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.loadNodesProperties(nodes.map(node => ({ name: node.type, version: node.typeVersion })));
|
||||
await this.loadNodesProperties(
|
||||
nodes.map((node) => ({ name: node.type, version: node.typeVersion })),
|
||||
);
|
||||
|
||||
let nodeType: INodeTypeDescription | null;
|
||||
nodes.forEach((node) => {
|
||||
@@ -441,9 +480,18 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
if (nodeType !== null) {
|
||||
let nodeParameters = null;
|
||||
try {
|
||||
nodeParameters = NodeHelpers.getNodeParameters(nodeType.properties, node.parameters, true, false, node);
|
||||
nodeParameters = NodeHelpers.getNodeParameters(
|
||||
nodeType.properties,
|
||||
node.parameters,
|
||||
true,
|
||||
false,
|
||||
node,
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(this.$locale.baseText('nodeView.thereWasAProblemLoadingTheNodeParametersOfNode') + `: "${node.name}"`); // eslint-disable-line no-console
|
||||
console.error(
|
||||
this.$locale.baseText('nodeView.thereWasAProblemLoadingTheNodeParametersOfNode') +
|
||||
`: "${node.name}"`,
|
||||
); // eslint-disable-line no-console
|
||||
console.error(e); // eslint-disable-line no-console
|
||||
}
|
||||
node.parameters = nodeParameters !== null ? nodeParameters : {};
|
||||
@@ -462,14 +510,16 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
let connectionData;
|
||||
for (const sourceNode of Object.keys(connections)) {
|
||||
for (const type of Object.keys(connections[sourceNode])) {
|
||||
for (let sourceIndex = 0; sourceIndex < connections[sourceNode][type].length; sourceIndex++) {
|
||||
for (
|
||||
let sourceIndex = 0;
|
||||
sourceIndex < connections[sourceNode][type].length;
|
||||
sourceIndex++
|
||||
) {
|
||||
const outwardConnections = connections[sourceNode][type][sourceIndex];
|
||||
if (!outwardConnections) {
|
||||
continue;
|
||||
}
|
||||
outwardConnections.forEach((
|
||||
targetData,
|
||||
) => {
|
||||
outwardConnections.forEach((targetData) => {
|
||||
connectionData = [
|
||||
{
|
||||
node: sourceNode,
|
||||
@@ -483,7 +533,10 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
},
|
||||
] as [IConnection, IConnection];
|
||||
|
||||
this.workflowsStore.addConnection({ connection: connectionData, setStateDirty: false });
|
||||
this.workflowsStore.addConnection({
|
||||
connection: connectionData,
|
||||
setStateDirty: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -494,14 +547,15 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
const allNodes: INodeTypeDescription[] = this.nodeTypesStore.allNodeTypes;
|
||||
|
||||
const nodesToBeFetched: INodeTypeNameVersion[] = [];
|
||||
allNodes.forEach(node => {
|
||||
allNodes.forEach((node) => {
|
||||
const nodeVersions = Array.isArray(node.version) ? node.version : [node.version];
|
||||
if (!!nodeInfos.find(n => n.name === node.name && nodeVersions.includes(n.version)) && !node.hasOwnProperty('properties')) {
|
||||
if (
|
||||
!!nodeInfos.find((n) => n.name === node.name && nodeVersions.includes(n.version)) &&
|
||||
!node.hasOwnProperty('properties')
|
||||
) {
|
||||
nodesToBeFetched.push({
|
||||
name: node.name,
|
||||
version: Array.isArray(node.version)
|
||||
? node.version.slice(-1)[0]
|
||||
: node.version,
|
||||
version: Array.isArray(node.version) ? node.version.slice(-1)[0] : node.version,
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -515,7 +569,7 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
const activeWorkflows = await this.restApi().getActiveWorkflows();
|
||||
this.workflowsStore.activeWorkflows = activeWorkflows;
|
||||
},
|
||||
async onRetryExecution(payload: { execution: IExecutionsSummary, command: string }) {
|
||||
async onRetryExecution(payload: { execution: IExecutionsSummary; command: string }) {
|
||||
const loadWorkflow = payload.command === 'current-workflow';
|
||||
|
||||
this.$showMessage({
|
||||
@@ -547,7 +601,6 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
this.$showError(
|
||||
error,
|
||||
@@ -560,7 +613,6 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
</script>
|
||||
|
||||
<style module lang="scss">
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
@@ -575,5 +627,4 @@ export default mixins(restApi, showMessage, executionHelpers, debounceHelper, wo
|
||||
margin-top: var(--spacing-2xl);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user