mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
refactor(editor): Overhaul workflow level executions list (#5089)
* fix(editor): update texts and styles * fix(editor): update texts and styles * fix(editor): move 'No execution found' to sidebar * fix(editor): change empty state title in executions * fix(editor): workflow execution list delete item * fix(editor): workflow execution always show sidebar * fix(editor): workflow execution unify date display mode * fix(editor): workflow execution empty list
This commit is contained in:
parent
62d06b1e6e
commit
3c109ffab1
|
@ -238,6 +238,7 @@ import { externalHooks } from '@/mixins/externalHooks';
|
||||||
import { VIEWS } from '@/constants';
|
import { VIEWS } from '@/constants';
|
||||||
import { restApi } from '@/mixins/restApi';
|
import { restApi } from '@/mixins/restApi';
|
||||||
import { genericHelpers } from '@/mixins/genericHelpers';
|
import { genericHelpers } from '@/mixins/genericHelpers';
|
||||||
|
import { executionHelpers } from '@/mixins/executionsHelpers';
|
||||||
import { showMessage } from '@/mixins/showMessage';
|
import { showMessage } from '@/mixins/showMessage';
|
||||||
import {
|
import {
|
||||||
IExecutionsCurrentSummaryExtended,
|
IExecutionsCurrentSummaryExtended,
|
||||||
|
@ -253,7 +254,8 @@ import { mapStores } from 'pinia';
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
import { useWorkflowsStore } from '@/stores/workflows';
|
import { useWorkflowsStore } from '@/stores/workflows';
|
||||||
|
|
||||||
export default mixins(externalHooks, genericHelpers, restApi, showMessage).extend({
|
export default mixins(externalHooks, genericHelpers, executionHelpers, restApi, showMessage).extend(
|
||||||
|
{
|
||||||
name: 'ExecutionsList',
|
name: 'ExecutionsList',
|
||||||
components: {
|
components: {
|
||||||
ExecutionTime,
|
ExecutionTime,
|
||||||
|
@ -382,10 +384,6 @@ export default mixins(externalHooks, genericHelpers, restApi, showMessage).exten
|
||||||
closeDialog() {
|
closeDialog() {
|
||||||
this.$emit('closeModal');
|
this.$emit('closeModal');
|
||||||
},
|
},
|
||||||
formatDate(epochTime: number) {
|
|
||||||
const { date, time } = this.convertToDisplayDate(epochTime);
|
|
||||||
return this.$locale.baseText('executionsList.started', { interpolate: { time, date } });
|
|
||||||
},
|
|
||||||
displayExecution(execution: IExecutionsSummary) {
|
displayExecution(execution: IExecutionsSummary) {
|
||||||
const route = this.$router.resolve({
|
const route = this.$router.resolve({
|
||||||
name: VIEWS.EXECUTION_PREVIEW,
|
name: VIEWS.EXECUTION_PREVIEW,
|
||||||
|
@ -691,7 +689,11 @@ export default mixins(externalHooks, genericHelpers, restApi, showMessage).exten
|
||||||
|
|
||||||
let data: IExecutionsListResponse;
|
let data: IExecutionsListResponse;
|
||||||
try {
|
try {
|
||||||
data = await this.restApi().getPastExecutions(filter, this.requestItemsPerRequest, lastId);
|
data = await this.restApi().getPastExecutions(
|
||||||
|
filter,
|
||||||
|
this.requestItemsPerRequest,
|
||||||
|
lastId,
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.isDataLoading = false;
|
this.isDataLoading = false;
|
||||||
this.$showError(error, this.$locale.baseText('executionsList.showError.loadMore.title'));
|
this.$showError(error, this.$locale.baseText('executionsList.showError.loadMore.title'));
|
||||||
|
@ -774,7 +776,10 @@ export default mixins(externalHooks, genericHelpers, restApi, showMessage).exten
|
||||||
const finishedExecutionsPromise = this.loadFinishedExecutions();
|
const finishedExecutionsPromise = this.loadFinishedExecutions();
|
||||||
await Promise.all([activeExecutionsPromise, finishedExecutionsPromise]);
|
await Promise.all([activeExecutionsPromise, finishedExecutionsPromise]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$showError(error, this.$locale.baseText('executionsList.showError.refreshData.title'));
|
this.$showError(
|
||||||
|
error,
|
||||||
|
this.$locale.baseText('executionsList.showError.refreshData.title'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isDataLoading = false;
|
this.isDataLoading = false;
|
||||||
|
@ -864,7 +869,8 @@ export default mixins(externalHooks, genericHelpers, restApi, showMessage).exten
|
||||||
this.isDataLoading = true;
|
this.isDataLoading = true;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
},
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style module lang="scss">
|
<style module lang="scss">
|
||||||
|
|
|
@ -135,10 +135,9 @@ export default mixins(executionHelpers, showMessage, restApi).extend({
|
||||||
<style module lang="scss">
|
<style module lang="scss">
|
||||||
.executionCard {
|
.executionCard {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-right: var(--spacing-2xs);
|
padding-right: var(--spacing-m);
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
padding: 0 var(--spacing-2xs) var(--spacing-2xs) 0;
|
|
||||||
border-left: var(--spacing-4xs) var(--border-style-base) transparent !important;
|
border-left: var(--spacing-4xs) var(--border-style-base) transparent !important;
|
||||||
|
|
||||||
.executionStatus {
|
.executionStatus {
|
||||||
|
@ -146,14 +145,10 @@ export default mixins(executionHelpers, showMessage, restApi).extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& + &.active {
|
|
||||||
padding-top: var(--spacing-2xs);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&.active {
|
&.active {
|
||||||
.executionLink {
|
.executionLink {
|
||||||
background-color: var(--color-foreground-base);
|
background-color: var(--color-foreground-light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +212,6 @@ export default mixins(executionHelpers, showMessage, restApi).extend({
|
||||||
font-size: var(--font-size-xs);
|
font-size: var(--font-size-xs);
|
||||||
padding: var(--spacing-xs);
|
padding: var(--spacing-xs);
|
||||||
padding-right: var(--spacing-s);
|
padding-right: var(--spacing-s);
|
||||||
border-radius: var(--border-radius-base);
|
|
||||||
position: relative;
|
position: relative;
|
||||||
left: calc(
|
left: calc(
|
||||||
-1 * var(--spacing-4xs)
|
-1 * var(--spacing-4xs)
|
||||||
|
|
|
@ -49,7 +49,7 @@ import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||||
interface IWorkflowSaveSettings {
|
interface IWorkflowSaveSettings {
|
||||||
saveFailedExecutions: boolean;
|
saveFailedExecutions: boolean;
|
||||||
saveSuccessfulExecutions: boolean;
|
saveSuccessfulExecutions: boolean;
|
||||||
saveManualExecutions: boolean;
|
saveTestExecutions: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default mixins(workflowHelpers).extend({
|
export default mixins(workflowHelpers).extend({
|
||||||
|
@ -70,7 +70,7 @@ export default mixins(workflowHelpers).extend({
|
||||||
workflowSaveSettings: {
|
workflowSaveSettings: {
|
||||||
saveFailedExecutions: false,
|
saveFailedExecutions: false,
|
||||||
saveSuccessfulExecutions: false,
|
saveSuccessfulExecutions: false,
|
||||||
saveManualExecutions: false,
|
saveTestExecutions: false,
|
||||||
} as IWorkflowSaveSettings,
|
} as IWorkflowSaveSettings,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -105,11 +105,9 @@ export default mixins(workflowHelpers).extend({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'manualExecutions',
|
id: 'manualExecutions',
|
||||||
label: this.$locale.baseText(
|
label: this.$locale.baseText('executionsLandingPage.emptyState.accordion.testExecutions'),
|
||||||
'executionsLandingPage.emptyState.accordion.manualExecutions',
|
icon: this.workflowSaveSettings.saveTestExecutions ? 'check' : 'times',
|
||||||
),
|
iconColor: this.workflowSaveSettings.saveTestExecutions ? 'success' : 'danger',
|
||||||
icon: this.workflowSaveSettings.saveManualExecutions ? 'check' : 'times',
|
|
||||||
iconColor: this.workflowSaveSettings.saveManualExecutions ? 'success' : 'danger',
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
@ -118,9 +116,9 @@ export default mixins(workflowHelpers).extend({
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
this.workflowSaveSettings.saveFailedExecutions === false ||
|
!this.workflowSaveSettings.saveFailedExecutions ||
|
||||||
this.workflowSaveSettings.saveSuccessfulExecutions === false ||
|
!this.workflowSaveSettings.saveSuccessfulExecutions ||
|
||||||
this.workflowSaveSettings.saveManualExecutions === false
|
!this.workflowSaveSettings.saveTestExecutions
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
productionExecutionsIcon(): { icon: string; color: string } {
|
productionExecutionsIcon(): { icon: string; color: string } {
|
||||||
|
@ -136,7 +134,7 @@ export default mixins(workflowHelpers).extend({
|
||||||
this.workflowSaveSettings.saveSuccessfulExecutions ===
|
this.workflowSaveSettings.saveSuccessfulExecutions ===
|
||||||
this.workflowSaveSettings.saveFailedExecutions
|
this.workflowSaveSettings.saveFailedExecutions
|
||||||
) {
|
) {
|
||||||
if (this.workflowSaveSettings.saveSuccessfulExecutions === true) {
|
if (this.workflowSaveSettings.saveSuccessfulExecutions) {
|
||||||
return 'saving';
|
return 'saving';
|
||||||
}
|
}
|
||||||
return 'not-saving';
|
return 'not-saving';
|
||||||
|
@ -150,7 +148,7 @@ export default mixins(workflowHelpers).extend({
|
||||||
},
|
},
|
||||||
accordionIcon(): { icon: string; color: string } | null {
|
accordionIcon(): { icon: string; color: string } | null {
|
||||||
if (
|
if (
|
||||||
this.workflowSaveSettings.saveManualExecutions !== true ||
|
!this.workflowSaveSettings.saveTestExecutions ||
|
||||||
this.productionExecutionsStatus !== 'saving'
|
this.productionExecutionsStatus !== 'saving'
|
||||||
) {
|
) {
|
||||||
return { icon: 'exclamation-triangle', color: 'warning' };
|
return { icon: 'exclamation-triangle', color: 'warning' };
|
||||||
|
@ -184,7 +182,7 @@ export default mixins(workflowHelpers).extend({
|
||||||
workflowSettings.saveDataSuccessExecution === undefined
|
workflowSettings.saveDataSuccessExecution === undefined
|
||||||
? this.defaultValues.saveSuccessfulExecutions === 'all'
|
? this.defaultValues.saveSuccessfulExecutions === 'all'
|
||||||
: workflowSettings.saveDataSuccessExecution === 'all';
|
: workflowSettings.saveDataSuccessExecution === 'all';
|
||||||
this.workflowSaveSettings.saveManualExecutions =
|
this.workflowSaveSettings.saveTestExecutions =
|
||||||
workflowSettings.saveManualExecutions === undefined
|
workflowSettings.saveManualExecutions === undefined
|
||||||
? this.defaultValues.saveManualExecutions
|
? this.defaultValues.saveManualExecutions
|
||||||
: (workflowSettings.saveManualExecutions as boolean);
|
: (workflowSettings.saveManualExecutions as boolean);
|
||||||
|
|
|
@ -16,9 +16,6 @@
|
||||||
<n8n-heading tag="h2" size="xlarge" color="text-dark" class="mb-2xs">
|
<n8n-heading tag="h2" size="xlarge" color="text-dark" class="mb-2xs">
|
||||||
{{ $locale.baseText('executionsLandingPage.emptyState.heading') }}
|
{{ $locale.baseText('executionsLandingPage.emptyState.heading') }}
|
||||||
</n8n-heading>
|
</n8n-heading>
|
||||||
<n8n-text size="medium">
|
|
||||||
{{ $locale.baseText('executionsLandingPage.emptyState.message') }}
|
|
||||||
</n8n-text>
|
|
||||||
<executions-info-accordion />
|
<executions-info-accordion />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="$style.container" v-if="!loading">
|
<div :class="$style.container" v-if="!loading">
|
||||||
<executions-sidebar
|
<executions-sidebar
|
||||||
v-if="showSidebar"
|
|
||||||
:executions="executions"
|
:executions="executions"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:loadingMore="loadingMore"
|
:loadingMore="loadingMore"
|
||||||
|
@ -19,11 +18,6 @@
|
||||||
@stopExecution="onStopExecution"
|
@stopExecution="onStopExecution"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="executions.length === 0 && filterApplied" :class="$style.noResultsContainer">
|
|
||||||
<n8n-text color="text-base" size="medium" align="center">
|
|
||||||
{{ $locale.baseText('executionsLandingPage.noResults') }}
|
|
||||||
</n8n-text>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -76,7 +70,7 @@ export default mixins(
|
||||||
debounceHelper,
|
debounceHelper,
|
||||||
workflowHelpers,
|
workflowHelpers,
|
||||||
).extend({
|
).extend({
|
||||||
name: 'executions-list',
|
name: 'executions-view',
|
||||||
components: {
|
components: {
|
||||||
ExecutionsSidebar,
|
ExecutionsSidebar,
|
||||||
},
|
},
|
||||||
|
@ -98,12 +92,6 @@ export default mixins(
|
||||||
) === undefined;
|
) === undefined;
|
||||||
return this.loading || nothingToShow || activeNotPresent;
|
return this.loading || nothingToShow || activeNotPresent;
|
||||||
},
|
},
|
||||||
showSidebar(): boolean {
|
|
||||||
if (this.executions.length === 0) {
|
|
||||||
return this.filterApplied;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
filterApplied(): boolean {
|
filterApplied(): boolean {
|
||||||
return this.filter.status !== '';
|
return this.filter.status !== '';
|
||||||
},
|
},
|
||||||
|
@ -256,22 +244,32 @@ export default mixins(
|
||||||
async onDeleteCurrentExecution(): Promise<void> {
|
async onDeleteCurrentExecution(): Promise<void> {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
try {
|
try {
|
||||||
|
const executionIndex = this.executions.findIndex(
|
||||||
|
(execution: IExecutionsSummary) => execution.id === this.$route.params.executionId,
|
||||||
|
);
|
||||||
|
const nextExecution =
|
||||||
|
this.executions[executionIndex + 1] ||
|
||||||
|
this.executions[executionIndex - 1] ||
|
||||||
|
this.executions[0];
|
||||||
|
|
||||||
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) {
|
if (this.executions.length > 0) {
|
||||||
this.workflowsStore.activeWorkflowExecution = this.executions[0];
|
await this.$router
|
||||||
this.$router
|
|
||||||
.push({
|
.push({
|
||||||
name: VIEWS.EXECUTION_PREVIEW,
|
name: VIEWS.EXECUTION_PREVIEW,
|
||||||
params: { name: this.currentWorkflow, executionId: this.executions[0].id },
|
params: { name: this.currentWorkflow, executionId: nextExecution.id },
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
|
this.workflowsStore.activeWorkflowExecution = nextExecution;
|
||||||
} else {
|
} else {
|
||||||
// If there are no executions left, show empty state and clear active execution from the store
|
// If there are no executions left, show empty state and clear active execution from the store
|
||||||
this.workflowsStore.activeWorkflowExecution = null;
|
this.workflowsStore.activeWorkflowExecution = null;
|
||||||
this.$router.push({ name: VIEWS.EXECUTION_HOME, params: { name: this.currentWorkflow } });
|
await this.$router.push({
|
||||||
|
name: VIEWS.EXECUTION_HOME,
|
||||||
|
params: { name: this.currentWorkflow },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
await this.setExecutions();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.$showError(
|
this.$showError(
|
||||||
|
@ -314,8 +312,7 @@ export default mixins(
|
||||||
this.setExecutions();
|
this.setExecutions();
|
||||||
},
|
},
|
||||||
async setExecutions(): Promise<void> {
|
async setExecutions(): Promise<void> {
|
||||||
const workflowExecutions = await this.loadExecutions();
|
this.workflowsStore.currentWorkflowExecutions = await this.loadExecutions();
|
||||||
this.workflowsStore.currentWorkflowExecutions = workflowExecutions;
|
|
||||||
await this.setActiveExecution();
|
await this.setActiveExecution();
|
||||||
},
|
},
|
||||||
async loadAutoRefresh(): Promise<void> {
|
async loadAutoRefresh(): Promise<void> {
|
||||||
|
@ -667,10 +664,4 @@ export default mixins(
|
||||||
.content {
|
.content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.noResultsContainer {
|
|
||||||
width: 100%;
|
|
||||||
margin-top: var(--spacing-2xl);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -66,6 +66,11 @@
|
||||||
<n8n-loading :class="$style.loader" variant="p" :rows="1" />
|
<n8n-loading :class="$style.loader" variant="p" :rows="1" />
|
||||||
<n8n-loading :class="$style.loader" variant="p" :rows="1" />
|
<n8n-loading :class="$style.loader" variant="p" :rows="1" />
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="executions.length === 0 && statusFilterApplied" :class="$style.noResultsContainer">
|
||||||
|
<n8n-text color="text-base" size="medium" align="center">
|
||||||
|
{{ $locale.baseText('executionsLandingPage.noResults') }}
|
||||||
|
</n8n-text>
|
||||||
|
</div>
|
||||||
<execution-card
|
<execution-card
|
||||||
v-else
|
v-else
|
||||||
v-for="execution in executions"
|
v-for="execution in executions"
|
||||||
|
@ -224,7 +229,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
// Find out how many execution card can fit into list
|
// Find out how many execution card can fit into list
|
||||||
// and load more if needed
|
// and load more if needed
|
||||||
if (sidebarContainer && currentExecutionCard) {
|
if (sidebarContainer && currentExecutionCard?.length) {
|
||||||
const cardElement = currentExecutionCard[0].$el as HTMLElement;
|
const cardElement = currentExecutionCard[0].$el as HTMLElement;
|
||||||
const listCapacity = Math.ceil(sidebarContainer.clientHeight / cardElement.clientHeight);
|
const listCapacity = Math.ceil(sidebarContainer.clientHeight / cardElement.clientHeight);
|
||||||
|
|
||||||
|
@ -239,7 +244,11 @@ export default Vue.extend({
|
||||||
`execution-${this.workflowsStore.activeWorkflowExecution?.id}`
|
`execution-${this.workflowsStore.activeWorkflowExecution?.id}`
|
||||||
] as Vue[];
|
] as Vue[];
|
||||||
|
|
||||||
if (executionsList && currentExecutionCard && this.workflowsStore.activeWorkflowExecution) {
|
if (
|
||||||
|
executionsList &&
|
||||||
|
currentExecutionCard?.length &&
|
||||||
|
this.workflowsStore.activeWorkflowExecution
|
||||||
|
) {
|
||||||
const cardElement = currentExecutionCard[0].$el as HTMLElement;
|
const cardElement = currentExecutionCard[0].$el as HTMLElement;
|
||||||
const cardRect = cardElement.getBoundingClientRect();
|
const cardRect = cardElement.getBoundingClientRect();
|
||||||
const LIST_HEADER_OFFSET = 200;
|
const LIST_HEADER_OFFSET = 200;
|
||||||
|
@ -316,4 +325,10 @@ export default Vue.extend({
|
||||||
margin-top: 0 !important;
|
margin-top: 0 !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.noResultsContainer {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: var(--spacing-2xl);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -52,7 +52,7 @@ export default mixins(pushConnection, workflowHelpers).extend({
|
||||||
...mapStores(useNDVStore, useUIStore),
|
...mapStores(useNDVStore, useUIStore),
|
||||||
tabBarItems(): ITabBarItem[] {
|
tabBarItems(): ITabBarItem[] {
|
||||||
return [
|
return [
|
||||||
{ value: MAIN_HEADER_TABS.WORKFLOW, label: this.$locale.baseText('generic.workflow') },
|
{ value: MAIN_HEADER_TABS.WORKFLOW, label: this.$locale.baseText('generic.editor') },
|
||||||
{ value: MAIN_HEADER_TABS.EXECUTIONS, label: this.$locale.baseText('generic.executions') },
|
{ value: MAIN_HEADER_TABS.EXECUTIONS, label: this.$locale.baseText('generic.executions') },
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { IExecutionsSummary } from '@/Interface';
|
import { IExecutionsSummary } from '@/Interface';
|
||||||
import { useWorkflowsStore } from '@/stores/workflows';
|
import { useWorkflowsStore } from '@/stores/workflows';
|
||||||
import dateFormat from 'dateformat';
|
import { i18n as locale } from '@/plugins/i18n';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import mixins from 'vue-typed-mixins';
|
import mixins from 'vue-typed-mixins';
|
||||||
import { genericHelpers } from './genericHelpers';
|
import { genericHelpers } from './genericHelpers';
|
||||||
|
@ -35,7 +35,7 @@ export const executionHelpers = mixins(genericHelpers).extend({
|
||||||
getExecutionUIDetails(execution: IExecutionsSummary): IExecutionUIData {
|
getExecutionUIDetails(execution: IExecutionsSummary): IExecutionUIData {
|
||||||
const status = {
|
const status = {
|
||||||
name: 'unknown',
|
name: 'unknown',
|
||||||
startTime: this.formatDate(new Date(execution.startedAt)),
|
startTime: this.formatDate(execution.startedAt),
|
||||||
label: 'Status unknown',
|
label: 'Status unknown',
|
||||||
runningTime: '',
|
runningTime: '',
|
||||||
};
|
};
|
||||||
|
@ -72,11 +72,9 @@ export const executionHelpers = mixins(genericHelpers).extend({
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
formatDate(date: Date) {
|
formatDate(fullDate: Date | string | number) {
|
||||||
if (date.getFullYear() === new Date().getFullYear()) {
|
const { date, time } = this.convertToDisplayDate(fullDate);
|
||||||
return dateFormat(date.getTime(), 'HH:MM:ss "on" d mmm');
|
return locale.baseText('executionsList.started', { interpolate: { time, date } });
|
||||||
}
|
|
||||||
return dateFormat(date.getTime(), 'HH:MM:ss "on" d mmm yyyy');
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,8 +36,11 @@ export const genericHelpers = mixins(showMessage).extend({
|
||||||
|
|
||||||
return `${minutesPassed}:${secondsLeft}${this.$locale.baseText('genericHelpers.minShort')}`;
|
return `${minutesPassed}:${secondsLeft}${this.$locale.baseText('genericHelpers.minShort')}`;
|
||||||
},
|
},
|
||||||
convertToDisplayDate(epochTime: number): { date: string; time: string } {
|
convertToDisplayDate(fullDate: Date | string | number): { date: string; time: string } {
|
||||||
const formattedDate = dateformat(epochTime, 'd mmm, yyyy#HH:MM:ss');
|
const mask = `d mmm${
|
||||||
|
new Date(fullDate).getFullYear() === new Date().getFullYear() ? '' : ', yyyy'
|
||||||
|
}#HH:MM:ss`;
|
||||||
|
const formattedDate = dateformat(fullDate, mask);
|
||||||
const [date, time] = formattedDate.split('#');
|
const [date, time] = formattedDate.split('#');
|
||||||
return { date, time };
|
return { date, time };
|
||||||
},
|
},
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
"generic.unsavedWork.confirmMessage.confirmButtonText": "Save",
|
"generic.unsavedWork.confirmMessage.confirmButtonText": "Save",
|
||||||
"generic.unsavedWork.confirmMessage.cancelButtonText": "Leave without saving",
|
"generic.unsavedWork.confirmMessage.cancelButtonText": "Leave without saving",
|
||||||
"generic.workflow": "Workflow",
|
"generic.workflow": "Workflow",
|
||||||
|
"generic.editor": "Editor",
|
||||||
"about.aboutN8n": "About n8n",
|
"about.aboutN8n": "About n8n",
|
||||||
"about.close": "Close",
|
"about.close": "Close",
|
||||||
"about.license": "License",
|
"about.license": "License",
|
||||||
|
@ -412,11 +413,12 @@
|
||||||
"executionsLandingPage.emptyState.noTrigger.heading": "Set up the first step. Then execute your workflow",
|
"executionsLandingPage.emptyState.noTrigger.heading": "Set up the first step. Then execute your workflow",
|
||||||
"executionsLandingPage.emptyState.noTrigger.buttonText": "Add first step...",
|
"executionsLandingPage.emptyState.noTrigger.buttonText": "Add first step...",
|
||||||
"executionsLandingPage.clickExecutionMessage": "Click on an execution from the list to view it",
|
"executionsLandingPage.clickExecutionMessage": "Click on an execution from the list to view it",
|
||||||
"executionsLandingPage.emptyState.heading": " No executions yet",
|
"executionsLandingPage.emptyState.heading": "Nothing here yet",
|
||||||
"executionsLandingPage.emptyState.message": "New workflow executions will show here",
|
"executionsLandingPage.emptyState.message": "New workflow executions will show here",
|
||||||
"executionsLandingPage.emptyState.accordion.title": "Which executions is this workflow saving?",
|
"executionsLandingPage.emptyState.accordion.title": "Which executions is this workflow saving?",
|
||||||
|
"executionsLandingPage.emptyState.accordion.titleWarning": "Some executions won’t be saved",
|
||||||
"executionsLandingPage.emptyState.accordion.productionExecutions": "Production executions",
|
"executionsLandingPage.emptyState.accordion.productionExecutions": "Production executions",
|
||||||
"executionsLandingPage.emptyState.accordion.manualExecutions": "Manual executions",
|
"executionsLandingPage.emptyState.accordion.testExecutions": "Test executions",
|
||||||
"executionsLandingPage.emptyState.accordion.productionExecutionsWarningTooltip": "Not all production executions are being saved. Change this in the workflow's <a href=\"#\">settings</a>",
|
"executionsLandingPage.emptyState.accordion.productionExecutionsWarningTooltip": "Not all production executions are being saved. Change this in the workflow's <a href=\"#\">settings</a>",
|
||||||
"executionsLandingPage.emptyState.accordion.footer": "You can change this in",
|
"executionsLandingPage.emptyState.accordion.footer": "You can change this in",
|
||||||
"executionsLandingPage.emptyState.accordion.footer.settingsLink": "Workflow settings",
|
"executionsLandingPage.emptyState.accordion.footer.settingsLink": "Workflow settings",
|
||||||
|
|
Loading…
Reference in a new issue