feat(editor): NDV UI overhaul experiment (#14209)

Co-authored-by: jakeranallo <jake.ranallo@gmail.com>
This commit is contained in:
Elias Meire
2025-07-04 17:14:17 +02:00
committed by GitHub
parent 5db122be0d
commit 6ef38411d8
33 changed files with 2528 additions and 195 deletions

View File

@@ -1,10 +1,6 @@
<script setup lang="ts">
import type { ITab } from '@/Interface';
import {
BUILTIN_NODES_DOCS_URL,
COMMUNITY_NODES_INSTALLATION_DOCS_URL,
NPM_PACKAGE_DOCS_BASE_URL,
} from '@/constants';
import { COMMUNITY_NODES_INSTALLATION_DOCS_URL } from '@/constants';
import { useNDVStore } from '@/stores/ndv.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import type { INodeTypeDescription } from 'n8n-workflow';
@@ -15,12 +11,15 @@ import { useExternalHooks } from '@/composables/useExternalHooks';
import { useI18n } from '@n8n/i18n';
import { useTelemetry } from '@/composables/useTelemetry';
import { isCommunityPackageName } from '@/utils/nodeTypesUtils';
import { N8nTabs } from '@n8n/design-system';
import { useNodeDocsUrl } from '@/composables/useNodeDocsUrl';
type Tab = 'settings' | 'params';
export type Tab = 'settings' | 'params' | 'communityNode' | 'docs';
type Props = {
modelValue?: Tab;
nodeType?: INodeTypeDescription | null;
pushRef?: string;
hideDocs?: boolean;
};
const props = withDefaults(defineProps<Props>(), {
@@ -37,6 +36,7 @@ const ndvStore = useNDVStore();
const workflowsStore = useWorkflowsStore();
const i18n = useI18n();
const telemetry = useTelemetry();
const { docsUrl } = useNodeDocsUrl({ nodeType: () => props.nodeType });
const activeNode = computed(() => ndvStore.activeNode);
@@ -51,38 +51,15 @@ const isCommunityNode = computed(() => {
const packageName = computed(() => props.nodeType?.name.split('.')[0] ?? '');
const documentationUrl = computed(() => {
const nodeType = props.nodeType;
if (!nodeType) {
if (props.hideDocs) {
return '';
}
if (nodeType.documentationUrl?.startsWith('http')) {
return nodeType.documentationUrl;
}
const utmParams = new URLSearchParams({
utm_source: 'n8n_app',
utm_medium: 'node_settings_modal-credential_link',
utm_campaign: nodeType.name,
});
// Built-in node documentation available via its codex entry
const primaryDocUrl = nodeType.codex?.resources?.primaryDocumentation?.[0]?.url;
if (primaryDocUrl) {
return `${primaryDocUrl}?${utmParams.toString()}`;
}
if (isCommunityNode.value) {
return `${NPM_PACKAGE_DOCS_BASE_URL}${packageName.value}`;
}
// Fallback to the root of the node documentation
return `${BUILTIN_NODES_DOCS_URL}?${utmParams.toString()}`;
return docsUrl.value;
});
const options = computed<ITab[]>(() => {
const options: ITab[] = [
const options = computed(() => {
const options: Array<ITab<Tab>> = [
{
label: i18n.baseText('nodeSettings.parameters'),
value: 'params',