mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-31 00:37:10 +02:00
fix(editor): Ready to run v2 p2 rework (no-changelog) (#22199)
This commit is contained in:
parent
ca84de8d56
commit
019cd8ed87
|
|
@ -1,66 +0,0 @@
|
|||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
import { useFoldersStore } from '@/features/core/folders/folders.store';
|
||||
import { useProjectPages } from '@/features/collaboration/projects/composables/useProjectPages';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
/**
|
||||
* Determines if the instance is truly empty and should show the simplified layout
|
||||
*/
|
||||
export function useEmptyStateDetection() {
|
||||
const foldersStore = useFoldersStore();
|
||||
const projectPages = useProjectPages();
|
||||
const route = useRoute();
|
||||
|
||||
/**
|
||||
* Checks if the current state qualifies as "truly empty"
|
||||
* - No workflows exist in the instance
|
||||
* - User is on the main workflows view (not in a specific folder)
|
||||
* - User is on overview page or personal project workflows
|
||||
* - No search filters are applied
|
||||
* - Not currently refreshing data
|
||||
*/
|
||||
const isTrulyEmpty = (currentRoute: RouteLocationNormalized = route) => {
|
||||
const hasNoWorkflows = foldersStore.totalWorkflowCount === 0;
|
||||
const isNotInSpecificFolder = !currentRoute.params?.folderId;
|
||||
const isMainWorkflowsPage = projectPages.isOverviewSubPage || !projectPages.isSharedSubPage;
|
||||
|
||||
// Check for any search or filter parameters that would indicate filtering is active
|
||||
const hasSearchQuery = !!currentRoute.query?.search;
|
||||
const hasFilters = !!(
|
||||
currentRoute.query?.status ||
|
||||
currentRoute.query?.tags ||
|
||||
currentRoute.query?.showArchived ||
|
||||
currentRoute.query?.homeProject
|
||||
);
|
||||
|
||||
return (
|
||||
hasNoWorkflows &&
|
||||
isNotInSpecificFolder &&
|
||||
isMainWorkflowsPage &&
|
||||
!hasSearchQuery &&
|
||||
!hasFilters
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if we're in a state where the simplified layout should be shown
|
||||
* This matches the logic from ResourcesListLayout's showEmptyState computed property
|
||||
*/
|
||||
const shouldShowSimplifiedLayout = (
|
||||
currentRoute: RouteLocationNormalized,
|
||||
isFeatureEnabled: boolean,
|
||||
loading: boolean,
|
||||
) => {
|
||||
// Don't show simplified layout if loading or feature is disabled
|
||||
if (loading || !isFeatureEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isTrulyEmpty(currentRoute);
|
||||
};
|
||||
|
||||
return {
|
||||
isTrulyEmpty,
|
||||
shouldShowSimplifiedLayout,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,218 +1,54 @@
|
|||
import { useTelemetry } from '@/app/composables/useTelemetry';
|
||||
import { useToast } from '@/app/composables/useToast';
|
||||
import { READY_TO_RUN_V2_PART2_EXPERIMENT, VIEWS } from '@/app/constants';
|
||||
import { useCredentialsStore } from '@/features/credentials/credentials.store';
|
||||
import { useUsersStore } from '@/features/settings/users/users.store';
|
||||
import { READY_TO_RUN_V2_PART2_EXPERIMENT } from '@/app/constants';
|
||||
import { useCloudPlanStore } from '@/app/stores/cloudPlan.store';
|
||||
import { usePostHog } from '@/app/stores/posthog.store';
|
||||
import { useSettingsStore } from '@/app/stores/settings.store';
|
||||
import { useWorkflowsStore } from '@/app/stores/workflows.store';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import type { WorkflowDataCreate } from '@n8n/rest-api-client';
|
||||
import { STORES } from '@n8n/stores';
|
||||
import { useLocalStorage } from '@vueuse/core';
|
||||
import { OPEN_AI_API_CREDENTIAL_TYPE, deepCopy } from 'n8n-workflow';
|
||||
import { defineStore } from 'pinia';
|
||||
import { computed, ref } from 'vue';
|
||||
import { useRouter, type RouteLocationNormalized } from 'vue-router';
|
||||
import { useEmptyStateDetection } from '../composables/useEmptyStateDetection';
|
||||
import { computed } from 'vue';
|
||||
import { READY_TO_RUN_WORKFLOW_V3 } from '../workflows/ai-workflow-v3';
|
||||
import { READY_TO_RUN_WORKFLOW_V4 } from '../workflows/ai-workflow-v4';
|
||||
|
||||
const LOCAL_STORAGE_CREDENTIAL_KEY = 'N8N_READY_TO_RUN_V2_OPENAI_CREDENTIAL_ID';
|
||||
|
||||
export const useReadyToRunWorkflowsV2Store = defineStore(
|
||||
STORES.EXPERIMENT_READY_TO_RUN_WORKFLOWS_V2,
|
||||
() => {
|
||||
const telemetry = useTelemetry();
|
||||
const i18n = useI18n();
|
||||
const toast = useToast();
|
||||
const router = useRouter();
|
||||
const credentialsStore = useCredentialsStore();
|
||||
const usersStore = useUsersStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
const posthogStore = usePostHog();
|
||||
const cloudPlanStore = useCloudPlanStore();
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
|
||||
const isFeatureEnabled = computed(() => {
|
||||
const variant = posthogStore.getVariant(READY_TO_RUN_V2_PART2_EXPERIMENT.name);
|
||||
return (
|
||||
(variant === READY_TO_RUN_V2_PART2_EXPERIMENT.variant3 ||
|
||||
variant === READY_TO_RUN_V2_PART2_EXPERIMENT.variant4) &&
|
||||
cloudPlanStore.userIsTrialing
|
||||
);
|
||||
});
|
||||
|
||||
const claimedCredentialIdRef = useLocalStorage(LOCAL_STORAGE_CREDENTIAL_KEY, '');
|
||||
|
||||
const claimingCredits = ref(false);
|
||||
|
||||
const userHasOpenAiCredentialAlready = computed(
|
||||
() =>
|
||||
!!credentialsStore.allCredentials.filter(
|
||||
(credential) => credential.type === OPEN_AI_API_CREDENTIAL_TYPE,
|
||||
).length,
|
||||
const currentVariant = computed(() =>
|
||||
posthogStore.getVariant(READY_TO_RUN_V2_PART2_EXPERIMENT.name),
|
||||
);
|
||||
|
||||
const userHasClaimedAiCreditsAlready = computed(
|
||||
() => !!usersStore.currentUser?.settings?.userClaimedAiCredits,
|
||||
const isVariant3 = computed(
|
||||
() => currentVariant.value === READY_TO_RUN_V2_PART2_EXPERIMENT.variant3,
|
||||
);
|
||||
const isVariant4 = computed(
|
||||
() => currentVariant.value === READY_TO_RUN_V2_PART2_EXPERIMENT.variant4,
|
||||
);
|
||||
|
||||
const userCanClaimOpenAiCredits = computed(() => {
|
||||
return (
|
||||
settingsStore.isAiCreditsEnabled &&
|
||||
!userHasOpenAiCredentialAlready.value &&
|
||||
!userHasClaimedAiCreditsAlready.value
|
||||
);
|
||||
});
|
||||
const isFeatureEnabled = computed(
|
||||
() => cloudPlanStore.userIsTrialing && (isVariant3.value || isVariant4.value),
|
||||
);
|
||||
|
||||
const getCurrentVariant = () => {
|
||||
return posthogStore.getVariant(READY_TO_RUN_V2_PART2_EXPERIMENT.name);
|
||||
};
|
||||
|
||||
const trackExecuteAiWorkflow = (status: string) => {
|
||||
const variant = getCurrentVariant();
|
||||
telemetry.track('User executed ready to run AI workflow', {
|
||||
status,
|
||||
variant,
|
||||
});
|
||||
};
|
||||
|
||||
const trackExecuteAiWorkflowSuccess = () => {
|
||||
const variant = getCurrentVariant();
|
||||
telemetry.track('User executed ready to run AI workflow successfully', {
|
||||
variant,
|
||||
});
|
||||
};
|
||||
|
||||
const claimFreeAiCredits = async (projectId?: string) => {
|
||||
claimingCredits.value = true;
|
||||
|
||||
try {
|
||||
const credential = await credentialsStore.claimFreeAiCredits(projectId);
|
||||
|
||||
claimedCredentialIdRef.value = credential.id;
|
||||
|
||||
telemetry.track('User claimed OpenAI credits');
|
||||
return credential;
|
||||
} catch (e) {
|
||||
toast.showError(
|
||||
e,
|
||||
i18n.baseText('freeAi.credits.showError.claim.title'),
|
||||
i18n.baseText('freeAi.credits.showError.claim.message'),
|
||||
);
|
||||
throw e;
|
||||
} finally {
|
||||
claimingCredits.value = false;
|
||||
const getWorkflowForVariant = (): WorkflowDataCreate | undefined => {
|
||||
if (!isFeatureEnabled.value) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const createAndOpenAiWorkflow = async (source: 'card' | 'button', parentFolderId?: string) => {
|
||||
const variant = getCurrentVariant();
|
||||
telemetry.track('User opened ready to run AI workflow', {
|
||||
source,
|
||||
variant,
|
||||
});
|
||||
|
||||
const workflowTemplate =
|
||||
variant === READY_TO_RUN_V2_PART2_EXPERIMENT.variant3
|
||||
? READY_TO_RUN_WORKFLOW_V3
|
||||
: READY_TO_RUN_WORKFLOW_V4;
|
||||
|
||||
try {
|
||||
let workflowToCreate: WorkflowDataCreate = {
|
||||
...workflowTemplate,
|
||||
parentFolderId,
|
||||
};
|
||||
|
||||
const credentialId = claimedCredentialIdRef.value;
|
||||
if (credentialId && workflowToCreate.nodes) {
|
||||
const clonedWorkflow = deepCopy(workflowToCreate);
|
||||
const openAiNode = clonedWorkflow.nodes?.find((node) => node.name === 'OpenAI Model');
|
||||
if (openAiNode) {
|
||||
openAiNode.credentials ??= {};
|
||||
openAiNode.credentials[OPEN_AI_API_CREDENTIAL_TYPE] = {
|
||||
id: credentialId,
|
||||
name: '',
|
||||
};
|
||||
}
|
||||
workflowToCreate = clonedWorkflow;
|
||||
}
|
||||
|
||||
const createdWorkflow = await workflowsStore.createNewWorkflow(workflowToCreate);
|
||||
|
||||
await router.push({
|
||||
name: VIEWS.WORKFLOW,
|
||||
params: { name: createdWorkflow.id },
|
||||
});
|
||||
|
||||
return createdWorkflow;
|
||||
} catch (error) {
|
||||
toast.showError(error, i18n.baseText('generic.error'));
|
||||
throw error;
|
||||
if (isVariant3.value) {
|
||||
return READY_TO_RUN_WORKFLOW_V3;
|
||||
}
|
||||
};
|
||||
|
||||
const claimCreditsAndOpenWorkflow = async (
|
||||
source: 'card' | 'button',
|
||||
parentFolderId?: string,
|
||||
projectId?: string,
|
||||
) => {
|
||||
await claimFreeAiCredits(projectId);
|
||||
await createAndOpenAiWorkflow(source, parentFolderId);
|
||||
|
||||
if (usersStore?.currentUser?.settings) {
|
||||
usersStore.currentUser.settings.userClaimedAiCredits = true;
|
||||
if (isVariant4.value) {
|
||||
return READY_TO_RUN_WORKFLOW_V4;
|
||||
}
|
||||
};
|
||||
|
||||
const getCardVisibility = (
|
||||
canCreate: boolean | undefined,
|
||||
readOnlyEnv: boolean,
|
||||
loading: boolean,
|
||||
) => {
|
||||
return (
|
||||
!loading &&
|
||||
isFeatureEnabled.value &&
|
||||
userCanClaimOpenAiCredits.value &&
|
||||
!readOnlyEnv &&
|
||||
canCreate
|
||||
);
|
||||
};
|
||||
|
||||
const getButtonVisibility = (
|
||||
hasWorkflows: boolean,
|
||||
canCreate: boolean | undefined,
|
||||
readOnlyEnv: boolean,
|
||||
) => {
|
||||
return (
|
||||
isFeatureEnabled.value &&
|
||||
userCanClaimOpenAiCredits.value &&
|
||||
!readOnlyEnv &&
|
||||
canCreate &&
|
||||
hasWorkflows
|
||||
);
|
||||
};
|
||||
|
||||
const { shouldShowSimplifiedLayout } = useEmptyStateDetection();
|
||||
|
||||
const getSimplifiedLayoutVisibility = (route: RouteLocationNormalized, loading: boolean) => {
|
||||
return shouldShowSimplifiedLayout(route, isFeatureEnabled.value, loading);
|
||||
return;
|
||||
};
|
||||
|
||||
return {
|
||||
currentVariant,
|
||||
getWorkflowForVariant,
|
||||
isFeatureEnabled,
|
||||
claimingCredits,
|
||||
userCanClaimOpenAiCredits,
|
||||
claimFreeAiCredits,
|
||||
createAndOpenAiWorkflow,
|
||||
claimCreditsAndOpenWorkflow,
|
||||
getCardVisibility,
|
||||
getButtonVisibility,
|
||||
getSimplifiedLayoutVisibility,
|
||||
trackExecuteAiWorkflow,
|
||||
trackExecuteAiWorkflowSuccess,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,253 +0,0 @@
|
|||
import type { WorkflowDataCreate } from '@n8n/rest-api-client';
|
||||
|
||||
export const READY_TO_RUN_WORKFLOW_V2: WorkflowDataCreate = {
|
||||
name: 'AI Agent workflow',
|
||||
meta: { templateId: 'ready-to-run-ai-workflow-v2' },
|
||||
nodes: [
|
||||
{
|
||||
parameters: {
|
||||
url: 'https://www.theverge.com/rss/index.xml',
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.rssFeedReadTool',
|
||||
typeVersion: 1.2,
|
||||
position: [-16, 768],
|
||||
id: '303e9b4e-cc4e-4d8a-8ede-7550f070d212',
|
||||
name: 'Get Tech News',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
toolDescription: 'Reads the news',
|
||||
url: '=https://feeds.bbci.co.uk/news/world/rss.xml',
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.rssFeedReadTool',
|
||||
typeVersion: 1.2,
|
||||
position: [112, 768],
|
||||
id: '4090a753-f131-40b1-87c3-cf74d5a7e325',
|
||||
name: 'Get World News',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
rule: {
|
||||
interval: [
|
||||
{
|
||||
triggerAtHour: 7,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
type: 'n8n-nodes-base.scheduleTrigger',
|
||||
typeVersion: 1.2,
|
||||
position: [-560, 752],
|
||||
id: '651543b5-0213-433f-8760-57d62b8d6d64',
|
||||
name: 'Run every day at 7AM',
|
||||
notesInFlow: true,
|
||||
notes: 'Double-click to open',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
assignments: {
|
||||
assignments: [
|
||||
{
|
||||
id: '85b5c530-2c13-4424-ab83-05979bc879a5',
|
||||
name: 'output',
|
||||
value: '={{ $json.output }}',
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.set',
|
||||
typeVersion: 3.4,
|
||||
position: [160, 544],
|
||||
id: '99f7bb9e-f8c0-43ca-a9a8-a76634ac9611',
|
||||
name: 'Output',
|
||||
notesInFlow: true,
|
||||
notes: 'Double-click to open',
|
||||
},
|
||||
{
|
||||
parameters: {},
|
||||
type: 'n8n-nodes-base.manualTrigger',
|
||||
typeVersion: 1,
|
||||
position: [-560, 544],
|
||||
id: 'a0390291-6794-4673-9a6a-5c3d3a5d9e4b',
|
||||
name: 'Click ‘Execute workflow’ to run',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
content: '## ⚡ Start here:',
|
||||
height: 224,
|
||||
width: 224,
|
||||
color: 7,
|
||||
},
|
||||
type: 'n8n-nodes-base.stickyNote',
|
||||
typeVersion: 1,
|
||||
position: [-624, 480],
|
||||
id: 'fac5929f-e065-4474-96b1-7bcc06834238',
|
||||
name: 'Sticky Note',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
model: {
|
||||
__rl: true,
|
||||
mode: 'list',
|
||||
value: 'gpt-4.1-mini',
|
||||
},
|
||||
options: {},
|
||||
},
|
||||
type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',
|
||||
typeVersion: 1.2,
|
||||
position: [-272, 768],
|
||||
id: 'b16482e8-0d48-4426-aa93-c3fee11dd3cd',
|
||||
name: 'OpenAI Model',
|
||||
notesInFlow: true,
|
||||
credentials: {},
|
||||
notes: 'Double-click to open',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
content: '@[youtube](cMyOkQ4N-5M)',
|
||||
height: 512,
|
||||
width: 902,
|
||||
color: 7,
|
||||
},
|
||||
type: 'n8n-nodes-base.stickyNote',
|
||||
typeVersion: 1,
|
||||
position: [-352, -96],
|
||||
id: 'ec65e69e-77fa-4912-a4af-49e0a248e2c8',
|
||||
name: 'Sticky Note3',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
promptType: 'define',
|
||||
text: '=Summarize world news and tech news from the last 24 hours. \nSkip your comments. \nThe titles should be "World news:" and "Tech news:" \nToday is {{ $today }}',
|
||||
options: {},
|
||||
},
|
||||
type: '@n8n/n8n-nodes-langchain.agent',
|
||||
typeVersion: 2.2,
|
||||
position: [-272, 544],
|
||||
id: '084d56aa-d157-4964-9073-b36d9d9589c5',
|
||||
name: 'AI Summary Agent',
|
||||
notesInFlow: true,
|
||||
notes: 'Double-click to open',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
content: '### Double click here to see the results:',
|
||||
height: 240,
|
||||
width: 192,
|
||||
color: 7,
|
||||
},
|
||||
type: 'n8n-nodes-base.stickyNote',
|
||||
typeVersion: 1,
|
||||
position: [112, 464],
|
||||
id: 'a4b7a69a-0db8-4b9b-a81d-fd83378043a3',
|
||||
name: 'Sticky Note1',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
content:
|
||||
'### 📰 Daily AI Summary\n\n\nThis workflow gets the latest news and asks AI to summarize it for you.\n\n⭐ Bonus: Send the summary via email by connecting your Gmail account\n\n▶ Watch the video to get started ',
|
||||
height: 272,
|
||||
width: 224,
|
||||
color: 5,
|
||||
},
|
||||
type: 'n8n-nodes-base.stickyNote',
|
||||
typeVersion: 1,
|
||||
position: [-624, 32],
|
||||
id: '74d80857-5e63-47a8-8e86-8ecd10fd5f9e',
|
||||
name: 'Sticky Note2',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
subject: 'Your news daily summary',
|
||||
emailType: 'text',
|
||||
message: '={{ $json.output }}',
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.gmail',
|
||||
typeVersion: 2.1,
|
||||
position: [432, 544],
|
||||
id: '45625d0d-bf26-4379-9eed-7bbc8e5d87a5',
|
||||
name: 'Send summary by email',
|
||||
webhookId: '093b04f1-5e78-4926-9863-1b100d6f2ead',
|
||||
notesInFlow: true,
|
||||
credentials: {},
|
||||
notes: 'Double-click to open',
|
||||
},
|
||||
],
|
||||
connections: {
|
||||
'Get Tech News': {
|
||||
ai_tool: [
|
||||
[
|
||||
{
|
||||
node: 'AI Summary Agent',
|
||||
type: 'ai_tool',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
'Get World News': {
|
||||
ai_tool: [
|
||||
[
|
||||
{
|
||||
node: 'AI Summary Agent',
|
||||
type: 'ai_tool',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
'Run every day at 7AM': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'AI Summary Agent',
|
||||
type: 'main',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
'Click ‘Execute workflow’ to run': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'AI Summary Agent',
|
||||
type: 'main',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
'OpenAI Model': {
|
||||
ai_languageModel: [
|
||||
[
|
||||
{
|
||||
node: 'AI Summary Agent',
|
||||
type: 'ai_languageModel',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
'AI Summary Agent': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'Output',
|
||||
type: 'main',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
Output: {
|
||||
main: [[]],
|
||||
},
|
||||
},
|
||||
pinData: {},
|
||||
};
|
||||
|
|
@ -1,240 +0,0 @@
|
|||
import type { WorkflowDataCreate } from '@n8n/rest-api-client';
|
||||
|
||||
export const READY_TO_RUN_WORKFLOW_V1: WorkflowDataCreate = {
|
||||
name: 'AI Agent workflow',
|
||||
meta: { templateId: 'ready-to-run-ai-workflow-v1' },
|
||||
nodes: [
|
||||
{
|
||||
parameters: {
|
||||
url: 'https://www.theverge.com/rss/index.xml',
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.rssFeedReadTool',
|
||||
typeVersion: 1.2,
|
||||
position: [-16, 768],
|
||||
id: '303e9b4e-cc4e-4d8a-8ede-7550f070d212',
|
||||
name: 'Get Tech News',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
toolDescription: 'Reads the news',
|
||||
url: '=https://feeds.bbci.co.uk/news/world/rss.xml',
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.rssFeedReadTool',
|
||||
typeVersion: 1.2,
|
||||
position: [112, 768],
|
||||
id: '4090a753-f131-40b1-87c3-cf74d5a7e325',
|
||||
name: 'Get World News',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
rule: {
|
||||
interval: [
|
||||
{
|
||||
triggerAtHour: 7,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
type: 'n8n-nodes-base.scheduleTrigger',
|
||||
typeVersion: 1.2,
|
||||
position: [-560, 752],
|
||||
id: '651543b5-0213-433f-8760-57d62b8d6d64',
|
||||
name: 'Run every day at 7AM',
|
||||
notesInFlow: true,
|
||||
notes: 'Double-click to open',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
assignments: {
|
||||
assignments: [
|
||||
{
|
||||
id: '85b5c530-2c13-4424-ab83-05979bc879a5',
|
||||
name: 'output',
|
||||
value: '={{ $json.output }}',
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.set',
|
||||
typeVersion: 3.4,
|
||||
position: [160, 544],
|
||||
id: '99f7bb9e-f8c0-43ca-a9a8-a76634ac9611',
|
||||
name: 'Output',
|
||||
notesInFlow: true,
|
||||
notes: 'Double-click to open',
|
||||
},
|
||||
{
|
||||
parameters: {},
|
||||
type: 'n8n-nodes-base.manualTrigger',
|
||||
typeVersion: 1,
|
||||
position: [-560, 544],
|
||||
id: 'a0390291-6794-4673-9a6a-5c3d3a5d9e4b',
|
||||
name: 'Click ‘Execute workflow’ to run',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
content: '## ⚡ Start here:',
|
||||
height: 240,
|
||||
width: 224,
|
||||
color: 7,
|
||||
},
|
||||
type: 'n8n-nodes-base.stickyNote',
|
||||
typeVersion: 1,
|
||||
position: [-624, 464],
|
||||
id: 'fac5929f-e065-4474-96b1-7bcc06834238',
|
||||
name: 'Sticky Note',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
model: {
|
||||
__rl: true,
|
||||
mode: 'list',
|
||||
value: 'gpt-4.1-mini',
|
||||
},
|
||||
options: {},
|
||||
},
|
||||
type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',
|
||||
typeVersion: 1.2,
|
||||
position: [-272, 768],
|
||||
id: 'b16482e8-0d48-4426-aa93-c3fee11dd3cd',
|
||||
name: 'OpenAI Model',
|
||||
notesInFlow: true,
|
||||
credentials: {},
|
||||
notes: 'Double-click to open',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
promptType: 'define',
|
||||
text: '=Summarize world news and tech news from the last 24 hours. \nSkip your comments. \nThe titles should be "World news:" and "Tech news:" \nToday is {{ $today }}',
|
||||
options: {},
|
||||
},
|
||||
type: '@n8n/n8n-nodes-langchain.agent',
|
||||
typeVersion: 2.2,
|
||||
position: [-272, 544],
|
||||
id: '084d56aa-d157-4964-9073-b36d9d9589c5',
|
||||
name: 'AI Summary Agent',
|
||||
notesInFlow: true,
|
||||
notes: 'Double-click to open',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
content: '### Double click here to see the results:',
|
||||
height: 240,
|
||||
width: 192,
|
||||
color: 7,
|
||||
},
|
||||
type: 'n8n-nodes-base.stickyNote',
|
||||
typeVersion: 1,
|
||||
position: [112, 464],
|
||||
id: 'a4b7a69a-0db8-4b9b-a81d-fd83378043a3',
|
||||
name: 'Sticky Note1',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
content:
|
||||
'### 📰 Daily AI Summary\n\n\nThis workflow gets the latest news and asks AI to summarize it for you.\n\n⭐ Bonus: Send the summary via email by connecting your Gmail account\n\n\n\n@[youtube](cMyOkQ4N-5M)',
|
||||
height: 432,
|
||||
width: 384,
|
||||
color: 5,
|
||||
},
|
||||
type: 'n8n-nodes-base.stickyNote',
|
||||
typeVersion: 1,
|
||||
position: [-1152, 464],
|
||||
id: '74d80857-5e63-47a8-8e86-8ecd10fd5f9e',
|
||||
name: 'Sticky Note2',
|
||||
},
|
||||
{
|
||||
parameters: {
|
||||
subject: 'Your news daily summary',
|
||||
emailType: 'text',
|
||||
message: '={{ $json.output }}',
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.gmail',
|
||||
typeVersion: 2.1,
|
||||
position: [432, 544],
|
||||
id: '45625d0d-bf26-4379-9eed-7bbc8e5d87a5',
|
||||
name: 'Send summary by email',
|
||||
webhookId: '093b04f1-5e78-4926-9863-1b100d6f2ead',
|
||||
notesInFlow: true,
|
||||
credentials: {},
|
||||
notes: 'Double-click to open',
|
||||
},
|
||||
],
|
||||
connections: {
|
||||
'Get Tech News': {
|
||||
ai_tool: [
|
||||
[
|
||||
{
|
||||
node: 'AI Summary Agent',
|
||||
type: 'ai_tool',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
'Get World News': {
|
||||
ai_tool: [
|
||||
[
|
||||
{
|
||||
node: 'AI Summary Agent',
|
||||
type: 'ai_tool',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
'Run every day at 7AM': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'AI Summary Agent',
|
||||
type: 'main',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
'Click ‘Execute workflow’ to run': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'AI Summary Agent',
|
||||
type: 'main',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
'OpenAI Model': {
|
||||
ai_languageModel: [
|
||||
[
|
||||
{
|
||||
node: 'AI Summary Agent',
|
||||
type: 'ai_languageModel',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
'AI Summary Agent': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'Output',
|
||||
type: 'main',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
Output: {
|
||||
main: [[]],
|
||||
},
|
||||
},
|
||||
pinData: {},
|
||||
};
|
||||
|
|
@ -15,6 +15,7 @@ import { VIEWS } from '@/app/constants';
|
|||
import { useSettingsStore } from '@/app/stores/settings.store';
|
||||
import { useWorkflowsStore } from '@/app/stores/workflows.store';
|
||||
import { useCredentialsStore } from '@/features/credentials/credentials.store';
|
||||
import { useReadyToRunWorkflowsV2Store } from '@/experiments/readyToRunWorkflowsV2/stores/readyToRunWorkflowsV2.store';
|
||||
|
||||
const LOCAL_STORAGE_CREDENTIAL_KEY = 'N8N_READY_TO_RUN_OPENAI_CREDENTIAL_ID';
|
||||
|
||||
|
|
@ -27,6 +28,7 @@ export const useReadyToRunStore = defineStore(STORES.READY_TO_RUN, () => {
|
|||
const usersStore = useUsersStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
const readyToRunWorkflowsV2Store = useReadyToRunWorkflowsV2Store();
|
||||
|
||||
const claimedCredentialIdRef = useLocalStorage(LOCAL_STORAGE_CREDENTIAL_KEY, '');
|
||||
|
||||
|
|
@ -83,6 +85,10 @@ export const useReadyToRunStore = defineStore(STORES.READY_TO_RUN, () => {
|
|||
}
|
||||
};
|
||||
|
||||
const getReadyToRunWorkflowTemplate = () => {
|
||||
return readyToRunWorkflowsV2Store.getWorkflowForVariant() ?? READY_TO_RUN_AI_WORKFLOW;
|
||||
};
|
||||
|
||||
const createAndOpenAiWorkflow = async (source: 'card' | 'button', parentFolderId?: string) => {
|
||||
telemetry.track('User opened ready to run AI workflow', {
|
||||
source,
|
||||
|
|
@ -90,7 +96,7 @@ export const useReadyToRunStore = defineStore(STORES.READY_TO_RUN, () => {
|
|||
|
||||
try {
|
||||
let workflowToCreate: WorkflowDataCreate = {
|
||||
...READY_TO_RUN_AI_WORKFLOW,
|
||||
...getReadyToRunWorkflowTemplate(),
|
||||
parentFolderId,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user