mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 10:02:05 +00:00
feat(editor): Enhance Node Creator actions view (#5954)
* WIP * WIP * Extract actions into composable * WIP: Preserve categories when searching * WIP * WIP: Tweak styles * WIP: Refactor node creator * WIP: Finish Node Creator node view/subcategories refactor * WIP: Finished actions refactor * Cleanup & Lintfix * WIP: Improve memory managment * Fix interactions * WIP * WIP: Keyboard navigation * Improve keyboard navigation and memory managment * Finished view refactor * FIx custom api calls and activation callouts * Fix actions tracking and cleanup * Product review fixes * Telemetry fixes * Fix node creator e2es * Set action name font size and actionsEmpty font weight * Fix failing credentials spec * Make sure to select first action item when switching from nodes panel to actions panel * Add actions panel e2e tests * Cleanup * Fix actions generation and cleanup * Add correct Learn More link and adjust displaying of trigger icon * Change trigger icon condition to use nodeType group * Cleanup nodeTypesUtils and snapshots and lintfixes * Lint fixes * Refine logic to show trigger icon in node creator * Add unit tests & clean up * Add `003_auto_insert_action` experiment, hide empty sections for opposite root view * Lintfix * Do not show empty category tooltips and only show activation callout in triger root view * Fix no-results node creator view * Spacings tweaks and root rendering logic adjustment * Add unit tests * Lint and e2e fixes * Revert CLI changes, fix unit tests * Remove useless comments * Sync master, replace $externalHooks mixin * Lint fix * Focus first action when panel slides in, not category * Address PR comments * Lint fix * Remove `setAddedNodeActionParameters` optional track param * Further simplify setAddedNodeActionParameters * Fix pnpn lock file * Fix types imports * Fix 13-pinning spec
This commit is contained in:
73
packages/editor-ui/src/components/Node/NodeCreator/utils.ts
Normal file
73
packages/editor-ui/src/components/Node/NodeCreator/utils.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import type {
|
||||
NodeCreateElement,
|
||||
ActionCreateElement,
|
||||
SubcategorizedNodeTypes,
|
||||
SimplifiedNodeType,
|
||||
INodeCreateElement,
|
||||
} from '@/Interface';
|
||||
import { CORE_NODES_CATEGORY, DEFAULT_SUBCATEGORY } from '@/constants';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { sublimeSearch } from '@/utils';
|
||||
|
||||
export function transformNodeType(
|
||||
node: SimplifiedNodeType,
|
||||
subcategory?: string,
|
||||
type: 'node' | 'action' = 'node',
|
||||
): NodeCreateElement | ActionCreateElement {
|
||||
const createElement = {
|
||||
uuid: uuidv4(),
|
||||
key: node.name,
|
||||
subcategory:
|
||||
subcategory ?? node.codex?.subcategories?.[CORE_NODES_CATEGORY]?.[0] ?? DEFAULT_SUBCATEGORY,
|
||||
properties: {
|
||||
...node,
|
||||
},
|
||||
type,
|
||||
};
|
||||
|
||||
return type === 'action'
|
||||
? (createElement as ActionCreateElement)
|
||||
: (createElement as NodeCreateElement);
|
||||
}
|
||||
|
||||
export function subcategorizeItems(items: SimplifiedNodeType[]) {
|
||||
return items.reduce((acc: SubcategorizedNodeTypes, item) => {
|
||||
// Only Core Nodes subcategories are valid, others are uncategorized
|
||||
const isCoreNodesCategory = item.codex?.categories?.includes(CORE_NODES_CATEGORY);
|
||||
const subcategories = isCoreNodesCategory
|
||||
? item?.codex?.subcategories?.[CORE_NODES_CATEGORY] ?? []
|
||||
: [DEFAULT_SUBCATEGORY];
|
||||
|
||||
subcategories.forEach((subcategory: string) => {
|
||||
if (!acc[subcategory]) {
|
||||
acc[subcategory] = [];
|
||||
}
|
||||
acc[subcategory].push(transformNodeType(item, subcategory));
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
export function sortNodeCreateElements(nodes: INodeCreateElement[]) {
|
||||
return nodes.sort((a, b) => {
|
||||
if (a.type !== 'node' || b.type !== 'node') return -1;
|
||||
const displayNameA = a.properties?.displayName?.toLowerCase() || a.key;
|
||||
const displayNameB = b.properties?.displayName?.toLowerCase() || b.key;
|
||||
|
||||
return displayNameA.localeCompare(displayNameB, undefined, { sensitivity: 'base' });
|
||||
});
|
||||
}
|
||||
|
||||
export function searchNodes(searchFilter: string, items: INodeCreateElement[]) {
|
||||
// In order to support the old search we need to remove the 'trigger' part
|
||||
const trimmedFilter = searchFilter.toLowerCase().replace('trigger', '').trimEnd();
|
||||
const result = (
|
||||
sublimeSearch<INodeCreateElement>(trimmedFilter, items, [
|
||||
{ key: 'properties.displayName', weight: 2 },
|
||||
{ key: 'properties.codex.alias', weight: 1 },
|
||||
]) || []
|
||||
).map(({ item }) => item);
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user