diff --git a/packages/frontend/editor-ui/src/components/CredentialEdit/CredentialConfig.vue b/packages/frontend/editor-ui/src/components/CredentialEdit/CredentialConfig.vue index 8e1b1e930a..62173129b8 100644 --- a/packages/frontend/editor-ui/src/components/CredentialEdit/CredentialConfig.vue +++ b/packages/frontend/editor-ui/src/components/CredentialEdit/CredentialConfig.vue @@ -32,6 +32,7 @@ import GoogleAuthButton from './GoogleAuthButton.vue'; import OauthButton from './OauthButton.vue'; import { useAssistantStore } from '@/stores/assistant.store'; import InlineAskAssistantButton from '@n8n/design-system/components/InlineAskAssistantButton/InlineAskAssistantButton.vue'; +import FreeAiCreditsCallout from '@/components/FreeAiCreditsCallout.vue'; type Props = { mode: string; @@ -229,6 +230,7 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
+ { assertUserCannotClaimCredits(); }); + + describe('credentialTypeName prop (credentials page)', () => { + it('should not show claim callout when editing a non-openapi credential', async () => { + (useNDVStore as any).mockReturnValue({ + activeNode: null, + }); + + renderComponent(FreeAiCreditsCallout, { + props: { + credentialTypeName: 'googleSheetsOAuth2Api', + }, + }); + + assertUserCannotClaimCredits(); + }); + + it('should show claim callout editing openapi credential with no active node', async () => { + (useNDVStore as any).mockReturnValue({ + activeNode: null, + }); + + renderComponent(FreeAiCreditsCallout, { + props: { + credentialTypeName: 'openAiApi', + }, + }); + + assertUserCanClaimCredits(); + }); + + it('should not show claim callout when credential type is undefined and no valid active node', async () => { + (useNDVStore as any).mockReturnValue({ + activeNode: null, + }); + + renderComponent(FreeAiCreditsCallout, { + props: { + credentialTypeName: undefined, + }, + }); + + assertUserCannotClaimCredits(); + }); + }); }); diff --git a/packages/frontend/editor-ui/src/components/FreeAiCreditsCallout.vue b/packages/frontend/editor-ui/src/components/FreeAiCreditsCallout.vue index 3e8b1a2d7e..1ec5fdfac1 100644 --- a/packages/frontend/editor-ui/src/components/FreeAiCreditsCallout.vue +++ b/packages/frontend/editor-ui/src/components/FreeAiCreditsCallout.vue @@ -11,6 +11,12 @@ import { computed, ref } from 'vue'; import { OPEN_AI_API_CREDENTIAL_TYPE } from 'n8n-workflow'; import { N8nCallout, N8nText } from '@n8n/design-system'; +type Props = { + credentialTypeName?: string; +}; + +const props = defineProps(); + const LANGCHAIN_NODES_PREFIX = '@n8n/n8n-nodes-langchain.'; const N8N_NODES_PREFIX = '@n8n/n8n-nodes.'; @@ -42,6 +48,10 @@ const userHasOpenAiCredentialAlready = computed( ).length, ); +const isEditingOpenAiCredential = computed( + () => props.credentialTypeName && props.credentialTypeName === OPEN_AI_API_CREDENTIAL_TYPE, +); + const userHasClaimedAiCreditsAlready = computed( () => !!usersStore.currentUser?.settings?.userClaimedAiCredits, ); @@ -55,7 +65,7 @@ const activeNodeHasOpenAiApiCredential = computed( const userCanClaimOpenAiCredits = computed(() => { return ( settingsStore.isAiCreditsEnabled && - activeNodeHasOpenAiApiCredential.value && + (activeNodeHasOpenAiApiCredential.value || isEditingOpenAiCredential.value) && !userHasOpenAiCredentialAlready.value && !userHasClaimedAiCreditsAlready.value );