diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts index 024123b56b..27f81463ec 100644 --- a/packages/editor-ui/src/Interface.ts +++ b/packages/editor-ui/src/Interface.ts @@ -978,7 +978,11 @@ export interface ISettingsState { } export interface INodeTypesState { - nodeTypes: { [nodeType: string]: INodeTypeDescription }; + nodeTypes: { + [nodeType: string]: { + [version: number]: INodeTypeDescription; + } + }; } export interface ITemplateState { diff --git a/packages/editor-ui/src/components/NodeCreator/NodeCreator.vue b/packages/editor-ui/src/components/NodeCreator/NodeCreator.vue index edc8b643d3..bd534eb205 100644 --- a/packages/editor-ui/src/components/NodeCreator/NodeCreator.vue +++ b/packages/editor-ui/src/components/NodeCreator/NodeCreator.vue @@ -44,31 +44,16 @@ export default Vue.extend({ ], data() { return { - allNodeTypes: [], + allLatestNodeTypes: [] as INodeTypeDescription[], }; }, computed: { ...mapGetters('users', ['personalizedNodeTypes']), nodeTypes(): INodeTypeDescription[] { - return this.$store.getters['nodeTypes/allNodeTypes']; + return this.$store.getters['nodeTypes/allLatestNodeTypes']; }, visibleNodeTypes(): INodeTypeDescription[] { - return this.allNodeTypes - .filter((nodeType: INodeTypeDescription) => { - return !HIDDEN_NODES.includes(nodeType.name); - }).reduce((accumulator: INodeTypeDescription[], currentValue: INodeTypeDescription) => { - // keep only latest version of the nodes - // accumulator starts as an empty array. - const exists = accumulator.findIndex(nodes => nodes.name === currentValue.name); - if (exists >= 0 && accumulator[exists].version < currentValue.version) { - // This must be a versioned node and we've found a newer version. - // Replace the previous one with this one. - accumulator[exists] = currentValue; - } else { - accumulator.push(currentValue); - } - return accumulator; - }, []); + return this.allLatestNodeTypes.filter((nodeType) => !HIDDEN_NODES.includes(nodeType.name)); }, categoriesWithNodes(): ICategoriesWithNodes { return getCategoriesWithNodes(this.visibleNodeTypes, this.personalizedNodeTypes as string[]); @@ -125,8 +110,8 @@ export default Vue.extend({ }, watch: { nodeTypes(newList) { - if (newList.length !== this.allNodeTypes.length) { - this.allNodeTypes = newList; + if (newList.length !== this.allLatestNodeTypes.length) { + this.allLatestNodeTypes = newList; } }, }, diff --git a/packages/editor-ui/src/modules/credentials.ts b/packages/editor-ui/src/modules/credentials.ts index 64720ae3c5..b8e043c758 100644 --- a/packages/editor-ui/src/modules/credentials.ts +++ b/packages/editor-ui/src/modules/credentials.ts @@ -104,9 +104,9 @@ const module: Module = { }, getNodesWithAccess (state: ICredentialsState, getters: any, rootState: IRootState, rootGetters: any) { // tslint:disable-line:no-any return (credentialTypeName: string) => { - const nodeTypes: INodeTypeDescription[] = rootGetters['nodeTypes/allNodeTypes']; + const allLatestNodeTypes: INodeTypeDescription[] = rootGetters['nodeTypes/allLatestNodeTypes']; - return nodeTypes.filter((nodeType: INodeTypeDescription) => { + return allLatestNodeTypes.filter((nodeType: INodeTypeDescription) => { if (!nodeType.credentials) { return false; } diff --git a/packages/editor-ui/src/modules/nodeTypes.ts b/packages/editor-ui/src/modules/nodeTypes.ts index e84820b0ec..79f4a4838d 100644 --- a/packages/editor-ui/src/modules/nodeTypes.ts +++ b/packages/editor-ui/src/modules/nodeTypes.ts @@ -26,25 +26,53 @@ const module: Module = { }, getters: { allNodeTypes: (state): INodeTypeDescription[] => { - return Object.values(state.nodeTypes); + return Object.values(state.nodeTypes).reduce((allNodeTypes, nodeType) => { + const versionNumbers = Object.keys(nodeType).map(Number); + const allNodeVersions = versionNumbers.map(version => nodeType[version]); + + return [...allNodeTypes, ...allNodeVersions]; + }, []); + }, + allLatestNodeTypes: (state): INodeTypeDescription[] => { + return Object.values(state.nodeTypes).reduce((allLatestNodeTypes, nodeVersions) => { + const versionNumbers = Object.keys(nodeVersions).map(Number); + const latestNodeVersion = nodeVersions[Math.max(...versionNumbers)]; + + if (!latestNodeVersion) return allLatestNodeTypes; + + return [...allLatestNodeTypes, latestNodeVersion]; + }, []); }, getNodeType: (state) => (nodeTypeName: string, version?: number): INodeTypeDescription | null => { - const nodeType = state.nodeTypes[nodeTypeName]; + const nodeVersions = state.nodeTypes[nodeTypeName]; - if (!nodeType || !hasValidVersion(nodeType, version)) return null; + if (!nodeVersions) return null; - return nodeType; + const versionNumbers = Object.keys(nodeVersions).map(Number); + const nodeType = nodeVersions[version || Math.max(...versionNumbers)]; + + return nodeType || null; }, }, mutations: { - setNodeTypes(state, nodeTypesArray: INodeTypeDescription[]) { - state.nodeTypes = toNodeTypesState(nodeTypesArray); - }, + setNodeTypes(state, newNodeTypes: INodeTypeDescription[]) { + newNodeTypes.forEach((newNodeType) => { + const newNodeVersions = getNodeVersions(newNodeType); - updateNodeTypes(state, newNodeTypes: INodeTypeDescription[]) { - newNodeTypes.forEach((node) => Vue.set(state.nodeTypes, node.name, node)); - }, + if (newNodeVersions.length === 0) { + const singleVersion = { [DEFAULT_NODETYPE_VERSION]: newNodeType }; + Vue.set(state.nodeTypes, newNodeType.name, singleVersion); + return; + } + for (const version of newNodeVersions) { + state.nodeTypes[newNodeType.name] + ? Vue.set(state.nodeTypes[newNodeType.name], version, newNodeType) + : Vue.set(state.nodeTypes, newNodeType.name, { [version]: newNodeType }); + + } + }); + }, removeNodeTypes(state, nodeTypesToRemove: INodeTypeDescription[]) { state.nodeTypes = nodeTypesToRemove.reduce( (oldNodes, newNodeType) => omit(newNodeType.name, oldNodes), @@ -64,7 +92,7 @@ const module: Module = { nodesToBeFetched, ); - context.commit('updateNodeTypes', nodesInformation); + context.commit('setNodeTypes', nodesInformation); }, async getNodeTypes(context: ActionContext) { const nodeTypes = await getNodeTypes(context.rootGetters.getRestApiContext); @@ -99,7 +127,7 @@ const module: Module = { } }); - context.commit('updateNodeTypes', nodesInformation); + context.commit('setNodeTypes', nodesInformation); }, async getNodeParameterOptions( context: ActionContext, @@ -117,20 +145,8 @@ const module: Module = { }, }; -function toNodeTypesState(nodeTypes: INodeTypeDescription[]) { - return nodeTypes.reduce((acc, cur) => { - acc[cur.name] = cur; - - return acc; - }, {}); -} - -function hasValidVersion(nodeType: INodeTypeDescription, version?: number) { - const nodeTypeVersion = Array.isArray(nodeType.version) - ? nodeType.version - : [nodeType.version]; - - return nodeTypeVersion.includes(version || nodeType.defaultVersion || DEFAULT_NODETYPE_VERSION); +function getNodeVersions(nodeType: INodeTypeDescription) { + return Array.isArray(nodeType.version) ? nodeType.version : [nodeType.version]; } export default module;