refactor: Fix node versioning again (#3819)

* 📘 Update state interface

*  Adjust store module to interface

* 🔥 Remove excess check

* 🐛 Fix filtering

* 🐛 Ensure default to latest version

*  Add `allLatestNodeTypes` getter

* 🔥 Remove excess checks

*  Simplify expression

*  Add check

* 🐛 Account for unknown node type name
This commit is contained in:
Iván Ovejero 2022-08-03 13:11:25 +02:00 committed by GitHub
parent 679a443a0c
commit 6e1aaa10e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 49 deletions

View file

@ -978,7 +978,11 @@ export interface ISettingsState {
}
export interface INodeTypesState {
nodeTypes: { [nodeType: string]: INodeTypeDescription };
nodeTypes: {
[nodeType: string]: {
[version: number]: INodeTypeDescription;
}
};
}
export interface ITemplateState {

View file

@ -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;
}
},
},

View file

@ -104,9 +104,9 @@ const module: Module<ICredentialsState, IRootState> = {
},
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;
}

View file

@ -26,25 +26,53 @@ const module: Module<INodeTypesState, IRootState> = {
},
getters: {
allNodeTypes: (state): INodeTypeDescription[] => {
return Object.values(state.nodeTypes);
return Object.values(state.nodeTypes).reduce<INodeTypeDescription[]>((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<INodeTypeDescription[]>((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<INodeTypesState, IRootState> = {
nodesToBeFetched,
);
context.commit('updateNodeTypes', nodesInformation);
context.commit('setNodeTypes', nodesInformation);
},
async getNodeTypes(context: ActionContext<INodeTypesState, IRootState>) {
const nodeTypes = await getNodeTypes(context.rootGetters.getRestApiContext);
@ -99,7 +127,7 @@ const module: Module<INodeTypesState, IRootState> = {
}
});
context.commit('updateNodeTypes', nodesInformation);
context.commit('setNodeTypes', nodesInformation);
},
async getNodeParameterOptions(
context: ActionContext<INodeTypesState, IRootState>,
@ -117,20 +145,8 @@ const module: Module<INodeTypesState, IRootState> = {
},
};
function toNodeTypesState(nodeTypes: INodeTypeDescription[]) {
return nodeTypes.reduce<INodeTypesState['nodeTypes']>((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;