feat: Data transformation nodes and actions in Nodes Panel (#7760)

- Split Items List node into separate nodes per action
- Review node descriptions
- New icons
- New sections in subcategories

---------

Co-authored-by: Giulio Andreini <andreini@netseven.it>
Co-authored-by: Deborah <deborah@starfallprojects.co.uk>
Co-authored-by: Michael Kret <michael.k@radency.com>
This commit is contained in:
Elias Meire
2023-12-08 11:40:05 +01:00
committed by GitHub
parent 90824b50ed
commit 675ec21d33
78 changed files with 4353 additions and 74 deletions

View File

@@ -162,7 +162,7 @@ function subcategoriesMapper(item: INodeCreateElement) {
}
function baseSubcategoriesFilter(item: INodeCreateElement): boolean {
if (item.type === 'section') return item.children.every(baseSubcategoriesFilter);
if (item.type === 'section') return true;
if (item.type !== 'node') return false;
const hasTriggerGroup = item.properties.group.includes('trigger');

View File

@@ -1,6 +1,6 @@
import type { SectionCreateElement } from '@/Interface';
import { groupItemsInSections } from '../utils';
import { mockNodeCreateElement } from './utils';
import { groupItemsInSections, sortNodeCreateElements } from '../utils';
import { mockActionCreateElement, mockNodeCreateElement, mockSectionCreateElement } from './utils';
describe('NodeCreator - utils', () => {
describe('groupItemsInSections', () => {
@@ -46,4 +46,20 @@ describe('NodeCreator - utils', () => {
expect(result).toEqual([node1, node2, node3]);
});
});
describe('sortNodeCreateElements', () => {
it('should sort nodes alphabetically by displayName', () => {
const node1 = mockNodeCreateElement({ key: 'newNode' }, { displayName: 'xyz' });
const node2 = mockNodeCreateElement({ key: 'popularNode' }, { displayName: 'abc' });
const node3 = mockNodeCreateElement({ key: 'otherNode' }, { displayName: 'ABC' });
expect(sortNodeCreateElements([node1, node2, node3])).toEqual([node2, node3, node1]);
});
it('should not change order for other types (sections, actions)', () => {
const node1 = mockSectionCreateElement();
const node2 = mockActionCreateElement();
const node3 = mockSectionCreateElement();
expect(sortNodeCreateElements([node1, node2, node3])).toEqual([node1, node2, node3]);
});
});
});

View File

@@ -222,7 +222,7 @@ export const useViewStacks = defineStore('nodeCreatorViewStacks', () => {
// Sort only if non-root view
if (!stack.items) {
sortNodeCreateElements(stackItems);
stackItems = sortNodeCreateElements(stackItems);
}
updateCurrentViewStack({ baselineItems: stackItems });

View File

@@ -59,7 +59,7 @@ export function subcategorizeItems(items: SimplifiedNodeType[]) {
export function sortNodeCreateElements(nodes: INodeCreateElement[]) {
return nodes.sort((a, b) => {
if (a.type !== 'node' || b.type !== 'node') return -1;
if (a.type !== 'node' || b.type !== 'node') return 0;
const displayNameA = a.properties?.displayName?.toLowerCase() || a.key;
const displayNameB = b.properties?.displayName?.toLowerCase() || b.key;
@@ -101,16 +101,16 @@ export function groupItemsInSections(
type: 'section',
key: section.key,
title: section.title,
children: itemsBySection[section.key],
children: sortNodeCreateElements(itemsBySection[section.key] ?? []),
}),
)
.concat({
type: 'section',
key: 'other',
title: i18n.baseText('nodeCreator.sectionNames.other'),
children: itemsBySection.other,
children: sortNodeCreateElements(itemsBySection.other ?? []),
})
.filter((section) => section.children);
.filter((section) => section.children.length > 0);
if (result.length <= 1) {
return items;

View File

@@ -10,7 +10,6 @@ import {
TRANSFORM_DATA_SUBCATEGORY,
FILES_SUBCATEGORY,
FLOWS_CONTROL_SUBCATEGORY,
HELPERS_SUBCATEGORY,
TRIGGER_NODE_CREATOR_VIEW,
EMAIL_IMAP_NODE_TYPE,
DEFAULT_SUBCATEGORY,
@@ -29,6 +28,26 @@ import {
AI_CATEGORY_EMBEDDING,
AI_OTHERS_NODE_CREATOR_VIEW,
AI_UNCATEGORIZED_CATEGORY,
SET_NODE_TYPE,
CODE_NODE_TYPE,
DATETIME_NODE_TYPE,
FILTER_NODE_TYPE,
REMOVE_DUPLICATES_NODE_TYPE,
SPLIT_OUT_NODE_TYPE,
LIMIT_NODE_TYPE,
SUMMARIZE_NODE_TYPE,
AGGREGATE_NODE_TYPE,
MERGE_NODE_TYPE,
HTML_NODE_TYPE,
MARKDOWN_NODE_TYPE,
XML_NODE_TYPE,
CRYPTO_NODE_TYPE,
IF_NODE_TYPE,
SPLIT_IN_BATCHES_NODE_TYPE,
HTTP_REQUEST_NODE_TYPE,
HELPERS_SUBCATEGORY,
RSS_READ_NODE_TYPE,
EMAIL_SEND_NODE_TYPE,
} from '@/constants';
import { useI18n } from '@/composables/useI18n';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
@@ -340,6 +359,7 @@ export function RegularView(nodes: SimplifiedNodeType[]) {
properties: {
title: 'App Regular Nodes',
icon: 'globe',
forceIncludeNodes: [RSS_READ_NODE_TYPE, EMAIL_SEND_NODE_TYPE],
},
},
{
@@ -353,20 +373,31 @@ export function RegularView(nodes: SimplifiedNodeType[]) {
{
key: 'popular',
title: i18n.baseText('nodeCreator.sectionNames.popular'),
items: [],
items: [SET_NODE_TYPE, CODE_NODE_TYPE, DATETIME_NODE_TYPE],
},
{
key: 'addOrRemove',
title: i18n.baseText('nodeCreator.sectionNames.transform.addOrRemove'),
items: [
FILTER_NODE_TYPE,
REMOVE_DUPLICATES_NODE_TYPE,
SPLIT_OUT_NODE_TYPE,
LIMIT_NODE_TYPE,
],
},
{
key: 'combine',
title: i18n.baseText('nodeCreator.sectionNames.transform.combine'),
items: [SUMMARIZE_NODE_TYPE, AGGREGATE_NODE_TYPE, MERGE_NODE_TYPE],
},
{
key: 'convert',
title: i18n.baseText('nodeCreator.sectionNames.transform.convert'),
items: [HTML_NODE_TYPE, MARKDOWN_NODE_TYPE, XML_NODE_TYPE, CRYPTO_NODE_TYPE],
},
],
},
},
{
type: 'subcategory',
key: HELPERS_SUBCATEGORY,
category: CORE_NODES_CATEGORY,
properties: {
title: HELPERS_SUBCATEGORY,
icon: 'toolbox',
},
},
{
type: 'subcategory',
key: FLOWS_CONTROL_SUBCATEGORY,
@@ -374,6 +405,13 @@ export function RegularView(nodes: SimplifiedNodeType[]) {
properties: {
title: FLOWS_CONTROL_SUBCATEGORY,
icon: 'code-branch',
sections: [
{
key: 'popular',
title: i18n.baseText('nodeCreator.sectionNames.popular'),
items: [FILTER_NODE_TYPE, IF_NODE_TYPE, SPLIT_IN_BATCHES_NODE_TYPE, MERGE_NODE_TYPE],
},
],
},
},
{
@@ -385,6 +423,22 @@ export function RegularView(nodes: SimplifiedNodeType[]) {
icon: 'file-alt',
},
},
{
type: 'subcategory',
key: HELPERS_SUBCATEGORY,
category: CORE_NODES_CATEGORY,
properties: {
title: HELPERS_SUBCATEGORY,
icon: 'toolbox',
sections: [
{
key: 'popular',
title: i18n.baseText('nodeCreator.sectionNames.popular'),
items: [HTTP_REQUEST_NODE_TYPE, WEBHOOK_NODE_TYPE, CODE_NODE_TYPE],
},
],
},
},
],
};