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
);