diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts index 6c6e6d566c..150e84072b 100644 --- a/packages/editor-ui/src/Interface.ts +++ b/packages/editor-ui/src/Interface.ts @@ -746,6 +746,10 @@ export interface ITemplatesNode extends IVersionNode { categories?: ITemplatesCategory[]; } +export interface INodeMetadata { + parametersLastUpdatedAt?: number; +}; + export interface IRootState { activeExecutions: IExecutionsCurrentSummaryExtended[]; activeWorkflows: string[]; @@ -783,6 +787,7 @@ export interface IRootState { workflow: IWorkflowDb; sidebarMenuItems: IMenuItem[]; instanceId: string; + nodeMetadata: {[nodeName: string]: INodeMetadata}; } export interface ICredentialTypeMap { diff --git a/packages/editor-ui/src/components/RunData.vue b/packages/editor-ui/src/components/RunData.vue index 3e6cb36c8e..4dce254faf 100644 --- a/packages/editor-ui/src/components/RunData.vue +++ b/packages/editor-ui/src/components/RunData.vue @@ -270,7 +270,6 @@ export default mixins( MAX_DISPLAY_ITEMS_AUTO_ALL, currentPage: 1, pageSize: 10, - staleData: false, }; }, mounted() { @@ -312,7 +311,7 @@ export default mixins( node (): INodeUi | null { return this.$store.getters.activeNode; }, - runMetadata () { + runTaskData (): ITaskData | null { if (!this.node || this.workflowExecution === null) { return null; } @@ -327,12 +326,28 @@ export default mixins( return null; } - const taskData: ITaskData = runData[this.node.name][this.runIndex]; + return runData[this.node.name][this.runIndex]; + }, + runMetadata (): {executionTime: number, startTime: string} | null { + if (!this.runTaskData) { + return null; + } return { - executionTime: taskData.executionTime, - startTime: new Date(taskData.startTime).toLocaleString(), + executionTime: this.runTaskData.executionTime, + startTime: new Date(this.runTaskData.startTime).toLocaleString(), }; }, + staleData(): boolean { + if (!this.node) { + return false; + } + const updatedAt = this.$store.getters.getParametersLastUpdated(this.node.name); + if (!updatedAt || !this.runTaskData) { + return false; + } + const runAt = this.runTaskData.startTime; + return updatedAt > runAt; + }, dataCount (): number { return this.getDataCount(this.runIndex, this.outputIndex); }, diff --git a/packages/editor-ui/src/store.ts b/packages/editor-ui/src/store.ts index 418a22a33f..e0160357e6 100644 --- a/packages/editor-ui/src/store.ts +++ b/packages/editor-ui/src/store.ts @@ -90,6 +90,7 @@ const state: IRootState = { }, sidebarMenuItems: [], instanceId: '', + nodeMetadata: {}, }; const modules = { @@ -470,6 +471,11 @@ export const store = new Vuex.Store({ state.stateIsDirty = true; Vue.set(node, 'parameters', updateInformation.value); + + if (!state.nodeMetadata[node.name]) { + Vue.set(state.nodeMetadata, node.name, {}); + } + Vue.set(state.nodeMetadata[node.name], 'parametersLastUpdatedAt', new Date().getTime()); }, // Node-Index @@ -666,6 +672,10 @@ export const store = new Vuex.Store({ return state.activeExecutions; }, + getParametersLastUpdated: (state): ((name: string) => number | undefined) => { + return (nodeName: string) => state.nodeMetadata[nodeName] && state.nodeMetadata[nodeName].parametersLastUpdatedAt; + }, + getBaseUrl: (state): string => { return state.baseUrl; },