@ai-stack/payloadcms 3.2.26 → 3.68.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{LICENSE.md → LICENSE} +1 -1
- package/README.md +218 -229
- package/dist/access/checkAccess.d.ts +4 -0
- package/dist/access/checkAccess.js +20 -0
- package/dist/access/checkAccess.js.map +1 -0
- package/dist/ai/core/generateObject.d.ts +7 -0
- package/dist/ai/core/generateObject.js +35 -0
- package/dist/ai/core/generateObject.js.map +1 -0
- package/dist/ai/core/generateText.d.ts +7 -0
- package/dist/ai/core/generateText.js +31 -0
- package/dist/ai/core/generateText.js.map +1 -0
- package/dist/ai/core/index.d.ts +11 -0
- package/dist/ai/core/index.js +10 -0
- package/dist/ai/core/index.js.map +1 -0
- package/dist/ai/core/media/generateMedia.d.ts +7 -0
- package/dist/ai/core/media/generateMedia.js +50 -0
- package/dist/ai/core/media/generateMedia.js.map +1 -0
- package/dist/ai/core/media/image/generateImage.d.ts +6 -0
- package/dist/ai/core/media/image/generateImage.js +41 -0
- package/dist/ai/core/media/image/generateImage.js.map +1 -0
- package/dist/ai/core/media/image/handlers/multimodal.d.ts +7 -0
- package/dist/ai/core/media/image/handlers/multimodal.js +100 -0
- package/dist/ai/core/media/image/handlers/multimodal.js.map +1 -0
- package/dist/ai/core/media/image/handlers/standard.d.ts +7 -0
- package/dist/ai/core/media/image/handlers/standard.js +28 -0
- package/dist/ai/core/media/image/handlers/standard.js.map +1 -0
- package/dist/ai/core/media/image/index.d.ts +2 -0
- package/dist/ai/core/media/image/index.js +3 -0
- package/dist/ai/core/media/image/index.js.map +1 -0
- package/dist/ai/core/media/index.d.ts +2 -0
- package/dist/ai/core/media/index.js +3 -0
- package/dist/ai/core/media/index.js.map +1 -0
- package/dist/ai/core/media/speech/generateSpeech.d.ts +5 -0
- package/dist/ai/core/media/speech/generateSpeech.js +55 -0
- package/dist/ai/core/media/speech/generateSpeech.js.map +1 -0
- package/dist/ai/core/media/speech/index.d.ts +2 -0
- package/dist/ai/core/media/speech/index.js +3 -0
- package/dist/ai/core/media/speech/index.js.map +1 -0
- package/dist/ai/core/media/types.d.ts +74 -0
- package/dist/ai/core/media/types.js +5 -0
- package/dist/ai/core/media/types.js.map +1 -0
- package/dist/ai/core/media/utils.d.ts +11 -0
- package/dist/ai/core/media/utils.js +34 -0
- package/dist/ai/core/media/utils.js.map +1 -0
- package/dist/ai/core/media/video/generateVideo.d.ts +6 -0
- package/dist/ai/core/media/video/generateVideo.js +32 -0
- package/dist/ai/core/media/video/generateVideo.js.map +1 -0
- package/dist/ai/core/media/video/index.d.ts +2 -0
- package/dist/ai/core/media/video/index.js +3 -0
- package/dist/ai/core/media/video/index.js.map +1 -0
- package/dist/ai/core/streamObject.d.ts +7 -0
- package/dist/ai/core/streamObject.js +54 -0
- package/dist/ai/core/streamObject.js.map +1 -0
- package/dist/ai/core/streamText.d.ts +7 -0
- package/dist/ai/core/streamText.js +30 -0
- package/dist/ai/core/streamText.js.map +1 -0
- package/dist/ai/core/types.d.ts +85 -0
- package/dist/ai/core/types.js +5 -0
- package/dist/ai/core/types.js.map +1 -0
- package/dist/ai/index.d.ts +11 -0
- package/dist/ai/index.js +25 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/providers/blocks/anthropic.d.ts +2 -0
- package/dist/ai/providers/blocks/anthropic.js +223 -0
- package/dist/ai/providers/blocks/anthropic.js.map +1 -0
- package/dist/ai/providers/blocks/elevenlabs.d.ts +2 -0
- package/dist/ai/providers/blocks/elevenlabs.js +449 -0
- package/dist/ai/providers/blocks/elevenlabs.js.map +1 -0
- package/dist/ai/providers/blocks/fal.d.ts +2 -0
- package/dist/ai/providers/blocks/fal.js +312 -0
- package/dist/ai/providers/blocks/fal.js.map +1 -0
- package/dist/ai/providers/blocks/google.d.ts +2 -0
- package/dist/ai/providers/blocks/google.js +623 -0
- package/dist/ai/providers/blocks/google.js.map +1 -0
- package/dist/ai/providers/blocks/index.d.ts +2 -0
- package/dist/ai/providers/blocks/index.js +18 -0
- package/dist/ai/providers/blocks/index.js.map +1 -0
- package/dist/ai/providers/blocks/openai-compatible.d.ts +2 -0
- package/dist/ai/providers/blocks/openai-compatible.js +308 -0
- package/dist/ai/providers/blocks/openai-compatible.js.map +1 -0
- package/dist/ai/providers/blocks/openai.d.ts +2 -0
- package/dist/ai/providers/blocks/openai.js +600 -0
- package/dist/ai/providers/blocks/openai.js.map +1 -0
- package/dist/ai/providers/blocks/xai.d.ts +2 -0
- package/dist/ai/providers/blocks/xai.js +247 -0
- package/dist/ai/providers/blocks/xai.js.map +1 -0
- package/dist/ai/providers/icons.d.ts +7 -0
- package/dist/ai/providers/icons.js +9 -0
- package/dist/ai/providers/icons.js.map +1 -0
- package/dist/ai/providers/index.d.ts +2 -0
- package/dist/ai/providers/index.js +6 -0
- package/dist/ai/providers/index.js.map +1 -0
- package/dist/ai/providers/registry.d.ts +40 -0
- package/dist/ai/providers/registry.js +267 -0
- package/dist/ai/providers/registry.js.map +1 -0
- package/dist/ai/providers/types.d.ts +115 -0
- package/dist/ai/providers/types.js +4 -0
- package/dist/ai/providers/types.js.map +1 -0
- package/dist/ai/utils/systemGenerate.d.ts +1 -1
- package/dist/ai/utils/systemGenerate.js +19 -19
- package/dist/ai/utils/systemGenerate.js.map +1 -1
- package/dist/collections/AIJobs.d.ts +2 -0
- package/dist/collections/AIJobs.js +81 -0
- package/dist/collections/AIJobs.js.map +1 -0
- package/dist/collections/AISettings.d.ts +2 -0
- package/dist/collections/AISettings.js +279 -0
- package/dist/collections/AISettings.js.map +1 -0
- package/dist/collections/Instructions.js +224 -50
- package/dist/collections/Instructions.js.map +1 -1
- package/dist/defaults.d.ts +3 -0
- package/dist/defaults.js +3 -0
- package/dist/defaults.js.map +1 -1
- package/dist/endpoints/buildPromptUtils.d.ts +19 -0
- package/dist/endpoints/buildPromptUtils.js +114 -0
- package/dist/endpoints/buildPromptUtils.js.map +1 -0
- package/dist/endpoints/chat.d.ts +4 -0
- package/dist/endpoints/fetchFields.js +0 -7
- package/dist/endpoints/fetchFields.js.map +1 -1
- package/dist/endpoints/fetchVoices.d.ts +2 -0
- package/dist/endpoints/fetchVoices.js +79 -0
- package/dist/endpoints/fetchVoices.js.map +1 -0
- package/dist/endpoints/index.js +339 -232
- package/dist/endpoints/index.js.map +1 -1
- package/dist/exports/client.d.ts +9 -0
- package/dist/exports/client.js +9 -0
- package/dist/exports/client.js.map +1 -1
- package/dist/exports/fields.d.ts +1 -0
- package/dist/exports/fields.js +1 -0
- package/dist/exports/fields.js.map +1 -1
- package/dist/fields/ArrayComposeField/ArrayComposeField.d.ts +15 -0
- package/dist/fields/ArrayComposeField/ArrayComposeField.js +87 -0
- package/dist/fields/ArrayComposeField/ArrayComposeField.js.map +1 -0
- package/dist/fields/ArrayComposeField/ArrayComposeField.jsx +73 -0
- package/dist/fields/ComposeField/ComposeField.js +2 -2
- package/dist/fields/ComposeField/ComposeField.js.map +1 -1
- package/dist/fields/ComposeField/ComposeField.jsx +2 -2
- package/dist/fields/PromptEditorField/PromptEditorField.js +162 -16
- package/dist/fields/PromptEditorField/PromptEditorField.js.map +1 -1
- package/dist/fields/PromptEditorField/PromptEditorField.jsx +123 -5
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init.js +63 -65
- package/dist/init.js.map +1 -1
- package/dist/payload-ai.d.ts +149 -0
- package/dist/plugin.js +94 -46
- package/dist/plugin.js.map +1 -1
- package/dist/providers/InstructionsProvider/InstructionsProvider.js +38 -7
- package/dist/providers/InstructionsProvider/InstructionsProvider.js.map +1 -1
- package/dist/providers/InstructionsProvider/InstructionsProvider.jsx +30 -4
- package/dist/providers/InstructionsProvider/context.d.ts +1 -0
- package/dist/providers/InstructionsProvider/context.js +1 -0
- package/dist/providers/InstructionsProvider/context.js.map +1 -1
- package/dist/providers/InstructionsProvider/useInstructions.js +30 -10
- package/dist/providers/InstructionsProvider/useInstructions.js.map +1 -1
- package/dist/styles.d.ts +11 -0
- package/dist/types/handlebars-async-helpers.d.ts +1 -0
- package/dist/types/handlebars-dist-handlebars.d.ts +1 -0
- package/dist/types/react-mentions.d.ts +1 -0
- package/dist/types.d.ts +6 -16
- package/dist/types.js.map +1 -1
- package/dist/ui/AIConfigDashboard/index.d.ts +2 -0
- package/dist/ui/AIConfigDashboard/index.js +46 -0
- package/dist/ui/AIConfigDashboard/index.js.map +1 -0
- package/dist/ui/AIConfigDashboard/index.jsx +24 -0
- package/dist/ui/ApiKeyStatusIndicator/index.d.ts +6 -0
- package/dist/ui/ApiKeyStatusIndicator/index.js +39 -0
- package/dist/ui/ApiKeyStatusIndicator/index.js.map +1 -0
- package/dist/ui/ApiKeyStatusIndicator/index.jsx +29 -0
- package/dist/ui/Compose/Compose.d.ts +2 -2
- package/dist/ui/Compose/Compose.js +118 -92
- package/dist/ui/Compose/Compose.js.map +1 -1
- package/dist/ui/Compose/Compose.jsx +113 -103
- package/dist/ui/Compose/ComposePlaceholder.d.ts +7 -0
- package/dist/ui/Compose/ComposePlaceholder.js +78 -0
- package/dist/ui/Compose/ComposePlaceholder.js.map +1 -0
- package/dist/ui/Compose/ComposePlaceholder.jsx +66 -0
- package/dist/ui/Compose/UndoRedoActions.d.ts +2 -2
- package/dist/ui/Compose/UndoRedoActions.js +11 -6
- package/dist/ui/Compose/UndoRedoActions.js.map +1 -1
- package/dist/ui/Compose/UndoRedoActions.jsx +8 -6
- package/dist/ui/Compose/compose.module.css +57 -17
- package/dist/ui/Compose/hooks/menu/itemsMap.js +13 -7
- package/dist/ui/Compose/hooks/menu/itemsMap.js.map +1 -1
- package/dist/ui/Compose/hooks/menu/useMenu.d.ts +2 -1
- package/dist/ui/Compose/hooks/menu/useMenu.js +28 -17
- package/dist/ui/Compose/hooks/menu/useMenu.js.map +1 -1
- package/dist/ui/Compose/hooks/menu/useMenu.jsx +27 -14
- package/dist/ui/Compose/hooks/useActiveFieldTracking.js +69 -10
- package/dist/ui/Compose/hooks/useActiveFieldTracking.js.map +1 -1
- package/dist/ui/Compose/hooks/useGenerate.d.ts +3 -0
- package/dist/ui/Compose/hooks/useGenerate.js +71 -11
- package/dist/ui/Compose/hooks/useGenerate.js.map +1 -1
- package/dist/ui/Compose/hooks/useHistory.d.ts +0 -1
- package/dist/ui/Compose/hooks/useHistory.js +113 -26
- package/dist/ui/Compose/hooks/useHistory.js.map +1 -1
- package/dist/ui/DynamicModelSelect/index.d.ts +7 -0
- package/dist/ui/DynamicModelSelect/index.js +231 -0
- package/dist/ui/DynamicModelSelect/index.js.map +1 -0
- package/dist/ui/DynamicModelSelect/index.jsx +207 -0
- package/dist/ui/DynamicProviderSelect/index.d.ts +7 -0
- package/dist/ui/DynamicProviderSelect/index.js +101 -0
- package/dist/ui/DynamicProviderSelect/index.js.map +1 -0
- package/dist/ui/DynamicProviderSelect/index.jsx +90 -0
- package/dist/ui/DynamicVoiceSelect/index.d.ts +7 -0
- package/dist/ui/DynamicVoiceSelect/index.js +156 -0
- package/dist/ui/DynamicVoiceSelect/index.js.map +1 -0
- package/dist/ui/DynamicVoiceSelect/index.jsx +102 -0
- package/dist/ui/EncryptedTextField/index.d.ts +8 -0
- package/dist/ui/EncryptedTextField/index.js +74 -0
- package/dist/ui/EncryptedTextField/index.js.map +1 -0
- package/dist/ui/EncryptedTextField/index.jsx +35 -0
- package/dist/ui/Icons/LottieAnimation.js +3 -1
- package/dist/ui/Icons/LottieAnimation.js.map +1 -1
- package/dist/ui/Icons/LottieAnimation.jsx +2 -1
- package/dist/ui/ModelRowLabel/index.d.ts +6 -0
- package/dist/ui/ModelRowLabel/index.js +41 -0
- package/dist/ui/ModelRowLabel/index.js.map +1 -0
- package/dist/ui/ModelRowLabel/index.jsx +26 -0
- package/dist/ui/ProviderOptionsEditor/index.d.ts +7 -0
- package/dist/ui/ProviderOptionsEditor/index.js +291 -0
- package/dist/ui/ProviderOptionsEditor/index.js.map +1 -0
- package/dist/ui/ProviderOptionsEditor/index.jsx +210 -0
- package/dist/ui/VoicesFetcher/index.d.ts +7 -0
- package/dist/ui/VoicesFetcher/index.js +118 -0
- package/dist/ui/VoicesFetcher/index.js.map +1 -0
- package/dist/ui/VoicesFetcher/index.jsx +79 -0
- package/dist/utilities/buildSmartPrompt.d.ts +22 -0
- package/dist/utilities/buildSmartPrompt.js +143 -0
- package/dist/utilities/buildSmartPrompt.js.map +1 -0
- package/dist/utilities/encryption.d.ts +2 -0
- package/dist/utilities/encryption.js +47 -0
- package/dist/utilities/encryption.js.map +1 -0
- package/dist/utilities/extractImageData.d.ts +9 -0
- package/dist/utilities/extractImageData.js +12 -2
- package/dist/utilities/extractImageData.js.map +1 -1
- package/dist/utilities/fetchImages.d.ts +14 -0
- package/dist/utilities/fetchImages.js +38 -0
- package/dist/utilities/fetchImages.js.map +1 -0
- package/dist/utilities/fieldToJsonSchema.d.ts +2 -1
- package/dist/utilities/fieldToJsonSchema.js +66 -3
- package/dist/utilities/fieldToJsonSchema.js.map +1 -1
- package/dist/utilities/getFieldBySchemaPath.d.ts +2 -2
- package/dist/utilities/getFieldBySchemaPath.js +15 -0
- package/dist/utilities/getFieldBySchemaPath.js.map +1 -1
- package/dist/utilities/getProviderOptionsFields.d.ts +16 -0
- package/dist/utilities/getProviderOptionsFields.js +80 -0
- package/dist/utilities/getProviderOptionsFields.js.map +1 -0
- package/dist/utilities/isPluginActivated.js +1 -2
- package/dist/utilities/isPluginActivated.js.map +1 -1
- package/dist/utilities/lexicalToHTML.js.map +1 -1
- package/dist/utilities/resolveImageReferences.d.ts +30 -0
- package/dist/utilities/resolveImageReferences.js +167 -0
- package/dist/utilities/resolveImageReferences.js.map +1 -0
- package/dist/utilities/schemaConverter.d.ts +3 -0
- package/dist/utilities/schemaConverter.js +93 -0
- package/dist/utilities/schemaConverter.js.map +1 -0
- package/dist/utilities/setSafeLexicalState.d.ts +1 -3
- package/dist/utilities/setSafeLexicalState.js +1 -1
- package/dist/utilities/setSafeLexicalState.js.map +1 -1
- package/dist/utilities/updateFieldsConfig.js +27 -43
- package/dist/utilities/updateFieldsConfig.js.map +1 -1
- package/package.json +23 -24
- package/dist/ai/models/anthropic/index.d.ts +0 -2
- package/dist/ai/models/anthropic/index.js +0 -129
- package/dist/ai/models/anthropic/index.js.map +0 -1
- package/dist/ai/models/elevenLabs/generateVoice.d.ts +0 -8
- package/dist/ai/models/elevenLabs/generateVoice.js +0 -20
- package/dist/ai/models/elevenLabs/generateVoice.js.map +0 -1
- package/dist/ai/models/elevenLabs/index.d.ts +0 -2
- package/dist/ai/models/elevenLabs/index.js +0 -133
- package/dist/ai/models/elevenLabs/index.js.map +0 -1
- package/dist/ai/models/elevenLabs/voices.d.ts +0 -8
- package/dist/ai/models/elevenLabs/voices.js +0 -24
- package/dist/ai/models/elevenLabs/voices.js.map +0 -1
- package/dist/ai/models/generateObject.d.ts +0 -11
- package/dist/ai/models/generateObject.js +0 -22
- package/dist/ai/models/generateObject.js.map +0 -1
- package/dist/ai/models/google/generateImage.d.ts +0 -9
- package/dist/ai/models/google/generateImage.js +0 -27
- package/dist/ai/models/google/generateImage.js.map +0 -1
- package/dist/ai/models/google/index.d.ts +0 -2
- package/dist/ai/models/google/index.js +0 -201
- package/dist/ai/models/google/index.js.map +0 -1
- package/dist/ai/models/index.d.ts +0 -2
- package/dist/ai/models/index.js +0 -13
- package/dist/ai/models/index.js.map +0 -1
- package/dist/ai/models/openai/generateImage.d.ts +0 -5
- package/dist/ai/models/openai/generateImage.js +0 -31
- package/dist/ai/models/openai/generateImage.js.map +0 -1
- package/dist/ai/models/openai/generateVoice.d.ts +0 -6
- package/dist/ai/models/openai/generateVoice.js +0 -19
- package/dist/ai/models/openai/generateVoice.js.map +0 -1
- package/dist/ai/models/openai/index.d.ts +0 -2
- package/dist/ai/models/openai/index.js +0 -428
- package/dist/ai/models/openai/index.js.map +0 -1
- package/dist/ai/models/openai/openai.d.ts +0 -1
- package/dist/ai/models/openai/openai.js +0 -8
- package/dist/ai/models/openai/openai.js.map +0 -1
- package/dist/ai/utils/editImagesWithOpenAI.d.ts +0 -10
- package/dist/ai/utils/editImagesWithOpenAI.js +0 -37
- package/dist/ai/utils/editImagesWithOpenAI.js.map +0 -1
- package/dist/styles.d.js +0 -2
- package/dist/styles.d.js.map +0 -1
- package/dist/types/handlebars-async-helpers.d.js +0 -2
- package/dist/types/handlebars-async-helpers.d.js.map +0 -1
- package/dist/types/handlebars-dist-handlebars.d.js +0 -2
- package/dist/types/handlebars-dist-handlebars.d.js.map +0 -1
- package/dist/types/react-mentions.d.js +0 -2
- package/dist/types/react-mentions.d.js.map +0 -1
- package/dist/utilities/getGenerationModels.d.ts +0 -2
- package/dist/utilities/getGenerationModels.js +0 -10
- package/dist/utilities/getGenerationModels.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/DynamicProviderSelect/index.tsx"],"sourcesContent":["'use client'\n\nimport { SelectInput, useField } from '@payloadcms/ui'\nimport React, { useEffect, useMemo, useState } from 'react'\n\nimport { allProviderBlocks } from '../../ai/providers/blocks/index.js'\n\ntype Props = {\n name: string\n path: string\n}\n\nexport const DynamicProviderSelect: React.FC<Props> = (props) => {\n const { name, path } = props\n\n const { setValue, value } = useField<string>({ path })\n\n // State to hold fetched providers data\n const [providersData, setProvidersData] = useState<any[]>([])\n\n // Fetch AI Settings global to get configured providers\n useEffect(() => {\n const fetchSettings = async () => {\n try {\n const response = await fetch('/api/globals/ai-settings?depth=1')\n if (response.ok) {\n const data = await response.json()\n if (data && data.providers) {\n setProvidersData(data.providers)\n }\n }\n } catch (error) {\n console.error('Error fetching AI settings:', error)\n }\n }\n\n void fetchSettings()\n }, [])\n\n const options = useMemo(() => {\n const optionsList: { label: string; value: string }[] = []\n const processedProviders = new Set<string>()\n\n // Iterate through fetched providers to find custom names\n providersData.forEach((provider: any) => {\n if (!provider.enabled) {\n return\n }\n\n const blockType = provider.blockType\n const customName = provider.providerName\n\n // Get static label as fallback\n const staticBlock = allProviderBlocks.find((b) => b.slug === blockType)\n const staticLabel = staticBlock?.labels?.singular\n ? typeof staticBlock.labels.singular === 'string'\n ? staticBlock.labels.singular\n : blockType\n : blockType\n\n const label = customName || staticLabel\n\n if (!processedProviders.has(blockType)) {\n optionsList.push({\n label,\n value: blockType,\n })\n processedProviders.add(blockType)\n } else if (customName) {\n // Update existing label if custom name is available\n const existingOpt = optionsList.find((o) => o.value === blockType)\n if (existingOpt && existingOpt.label === staticLabel) {\n existingOpt.label = customName\n }\n }\n })\n\n // Add any other available providers from blocks that might not be configured yet?\n // Usually we only want to show configured providers in the selection list.\n // But for standard providers (OpenAI, Google), they might not need much config other than API key.\n // If they are not in the list, user can't select them.\n // However, if they are not enabled in settings, maybe we shouldn't show them?\n // Let's stick to showing all available blocks, but prioritizing configured ones with custom names.\n\n allProviderBlocks.forEach((block) => {\n if (!processedProviders.has(block.slug)) {\n optionsList.push({\n label: typeof block.labels?.singular === 'string' ? block.labels.singular : block.slug,\n value: block.slug,\n })\n }\n })\n\n return optionsList\n }, [providersData])\n\n return (\n <div className=\"field-type select\">\n <label className=\"field-label\" htmlFor={path}>\n Provider\n </label>\n <SelectInput\n name={name}\n onChange={(option) => {\n if (option && typeof option === 'object' && 'value' in option) {\n setValue(option.value)\n } else {\n setValue(option)\n }\n }}\n options={options as any}\n path={path}\n value={value}\n />\n </div>\n )\n}\n"],"names":["SelectInput","useField","React","useEffect","useMemo","useState","allProviderBlocks","DynamicProviderSelect","props","name","path","setValue","value","providersData","setProvidersData","fetchSettings","response","fetch","ok","data","json","providers","error","console","options","optionsList","processedProviders","Set","forEach","provider","enabled","blockType","customName","providerName","staticBlock","find","b","slug","staticLabel","labels","singular","label","has","push","add","existingOpt","o","block","div","className","htmlFor","onChange","option"],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { SelectInput, useField } from '@payloadcms/ui';
|
|
3
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { allProviderBlocks } from '../../ai/providers/blocks/index.js';
|
|
5
|
+
export const DynamicProviderSelect = (props) => {
|
|
6
|
+
const { name, path } = props;
|
|
7
|
+
const { setValue, value } = useField({ path });
|
|
8
|
+
// State to hold fetched providers data
|
|
9
|
+
const [providersData, setProvidersData] = useState([]);
|
|
10
|
+
// Fetch AI Settings global to get configured providers
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const fetchSettings = async () => {
|
|
13
|
+
try {
|
|
14
|
+
const response = await fetch('/api/globals/ai-settings?depth=1');
|
|
15
|
+
if (response.ok) {
|
|
16
|
+
const data = await response.json();
|
|
17
|
+
if (data && data.providers) {
|
|
18
|
+
setProvidersData(data.providers);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error('Error fetching AI settings:', error);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
void fetchSettings();
|
|
27
|
+
}, []);
|
|
28
|
+
const options = useMemo(() => {
|
|
29
|
+
const optionsList = [];
|
|
30
|
+
const processedProviders = new Set();
|
|
31
|
+
// Iterate through fetched providers to find custom names
|
|
32
|
+
providersData.forEach((provider) => {
|
|
33
|
+
if (!provider.enabled) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const blockType = provider.blockType;
|
|
37
|
+
const customName = provider.providerName;
|
|
38
|
+
// Get static label as fallback
|
|
39
|
+
const staticBlock = allProviderBlocks.find((b) => b.slug === blockType);
|
|
40
|
+
const staticLabel = staticBlock?.labels?.singular
|
|
41
|
+
? typeof staticBlock.labels.singular === 'string'
|
|
42
|
+
? staticBlock.labels.singular
|
|
43
|
+
: blockType
|
|
44
|
+
: blockType;
|
|
45
|
+
const label = customName || staticLabel;
|
|
46
|
+
if (!processedProviders.has(blockType)) {
|
|
47
|
+
optionsList.push({
|
|
48
|
+
label,
|
|
49
|
+
value: blockType,
|
|
50
|
+
});
|
|
51
|
+
processedProviders.add(blockType);
|
|
52
|
+
}
|
|
53
|
+
else if (customName) {
|
|
54
|
+
// Update existing label if custom name is available
|
|
55
|
+
const existingOpt = optionsList.find((o) => o.value === blockType);
|
|
56
|
+
if (existingOpt && existingOpt.label === staticLabel) {
|
|
57
|
+
existingOpt.label = customName;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
// Add any other available providers from blocks that might not be configured yet?
|
|
62
|
+
// Usually we only want to show configured providers in the selection list.
|
|
63
|
+
// But for standard providers (OpenAI, Google), they might not need much config other than API key.
|
|
64
|
+
// If they are not in the list, user can't select them.
|
|
65
|
+
// However, if they are not enabled in settings, maybe we shouldn't show them?
|
|
66
|
+
// Let's stick to showing all available blocks, but prioritizing configured ones with custom names.
|
|
67
|
+
allProviderBlocks.forEach((block) => {
|
|
68
|
+
if (!processedProviders.has(block.slug)) {
|
|
69
|
+
optionsList.push({
|
|
70
|
+
label: typeof block.labels?.singular === 'string' ? block.labels.singular : block.slug,
|
|
71
|
+
value: block.slug,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return optionsList;
|
|
76
|
+
}, [providersData]);
|
|
77
|
+
return (<div className="field-type select">
|
|
78
|
+
<label className="field-label" htmlFor={path}>
|
|
79
|
+
Provider
|
|
80
|
+
</label>
|
|
81
|
+
<SelectInput name={name} onChange={(option) => {
|
|
82
|
+
if (option && typeof option === 'object' && 'value' in option) {
|
|
83
|
+
setValue(option.value);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
setValue(option);
|
|
87
|
+
}
|
|
88
|
+
}} options={options} path={path} value={value}/>
|
|
89
|
+
</div>);
|
|
90
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { SelectInput, useField, useFormFields } from '@payloadcms/ui';
|
|
4
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
5
|
+
export const DynamicVoiceSelect = (props)=>{
|
|
6
|
+
const { name, path } = props;
|
|
7
|
+
// Get provider from siblings
|
|
8
|
+
const parentPath = path.split('.').slice(0, -1).join('.');
|
|
9
|
+
const providerPath = `${parentPath}.provider`;
|
|
10
|
+
// Use useFormFields to get the provider field value - this will re-render when provider changes
|
|
11
|
+
const providerField = useFormFields(([fields])=>fields[providerPath]);
|
|
12
|
+
const provider = providerField?.value || '';
|
|
13
|
+
const { setValue, value } = useField({
|
|
14
|
+
path
|
|
15
|
+
});
|
|
16
|
+
const [aiSettings, setAiSettings] = useState(null);
|
|
17
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
18
|
+
// Fetch AI Settings - re-fetch when provider changes to ensure we have latest voices
|
|
19
|
+
useEffect(()=>{
|
|
20
|
+
const fetchSettings = async ()=>{
|
|
21
|
+
setIsLoading(true);
|
|
22
|
+
try {
|
|
23
|
+
const response = await fetch('/api/globals/ai-settings?depth=1');
|
|
24
|
+
if (response.ok) {
|
|
25
|
+
const data = await response.json();
|
|
26
|
+
setAiSettings(data);
|
|
27
|
+
}
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.error('Error fetching AI settings:', err);
|
|
30
|
+
} finally{
|
|
31
|
+
setIsLoading(false);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
void fetchSettings();
|
|
35
|
+
}, [
|
|
36
|
+
provider
|
|
37
|
+
]) // Re-fetch when provider changes to ensure we have the latest voices
|
|
38
|
+
;
|
|
39
|
+
const voices = useMemo(()=>{
|
|
40
|
+
if (!provider || !aiSettings?.providers) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
// Find the provider block matching the selected provider
|
|
44
|
+
const providerBlock = aiSettings.providers.find((p)=>p.blockType === provider && p.enabled !== false);
|
|
45
|
+
if (!providerBlock?.voices) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
// Get enabled voices from provider block
|
|
49
|
+
return providerBlock.voices.filter((v)=>v.enabled !== false).map((v)=>({
|
|
50
|
+
label: v.name || v.id,
|
|
51
|
+
value: v.id
|
|
52
|
+
}));
|
|
53
|
+
}, [
|
|
54
|
+
provider,
|
|
55
|
+
aiSettings
|
|
56
|
+
]);
|
|
57
|
+
// Clear voice selection when provider changes and current voice is not available
|
|
58
|
+
useEffect(()=>{
|
|
59
|
+
if (value && voices.length > 0) {
|
|
60
|
+
const voiceExists = voices.some((v)=>v.value === value);
|
|
61
|
+
if (!voiceExists) {
|
|
62
|
+
setValue('');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}, [
|
|
66
|
+
voices,
|
|
67
|
+
value,
|
|
68
|
+
setValue
|
|
69
|
+
]);
|
|
70
|
+
if (!provider) {
|
|
71
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
72
|
+
className: "field-type text",
|
|
73
|
+
children: [
|
|
74
|
+
/*#__PURE__*/ _jsx("label", {
|
|
75
|
+
className: "field-label",
|
|
76
|
+
htmlFor: path,
|
|
77
|
+
children: "Voice"
|
|
78
|
+
}),
|
|
79
|
+
/*#__PURE__*/ _jsx("p", {
|
|
80
|
+
style: {
|
|
81
|
+
color: 'var(--theme-elevation-600)',
|
|
82
|
+
fontSize: '13px'
|
|
83
|
+
},
|
|
84
|
+
children: "Please select a provider first."
|
|
85
|
+
})
|
|
86
|
+
]
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (isLoading) {
|
|
90
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
91
|
+
className: "field-type text",
|
|
92
|
+
children: [
|
|
93
|
+
/*#__PURE__*/ _jsx("label", {
|
|
94
|
+
className: "field-label",
|
|
95
|
+
htmlFor: path,
|
|
96
|
+
children: "Voice"
|
|
97
|
+
}),
|
|
98
|
+
/*#__PURE__*/ _jsx("p", {
|
|
99
|
+
style: {
|
|
100
|
+
color: 'var(--theme-elevation-600)',
|
|
101
|
+
fontSize: '13px'
|
|
102
|
+
},
|
|
103
|
+
children: "Loading voices..."
|
|
104
|
+
})
|
|
105
|
+
]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (voices.length === 0) {
|
|
109
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
110
|
+
className: "field-type text",
|
|
111
|
+
children: [
|
|
112
|
+
/*#__PURE__*/ _jsx("label", {
|
|
113
|
+
className: "field-label",
|
|
114
|
+
htmlFor: path,
|
|
115
|
+
children: "Voice"
|
|
116
|
+
}),
|
|
117
|
+
/*#__PURE__*/ _jsxs("p", {
|
|
118
|
+
style: {
|
|
119
|
+
color: 'var(--theme-elevation-600)',
|
|
120
|
+
fontSize: '13px'
|
|
121
|
+
},
|
|
122
|
+
children: [
|
|
123
|
+
"No voices available. Please configure voices in AI Settings for ",
|
|
124
|
+
provider,
|
|
125
|
+
"."
|
|
126
|
+
]
|
|
127
|
+
})
|
|
128
|
+
]
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
132
|
+
className: "field-type select",
|
|
133
|
+
children: [
|
|
134
|
+
/*#__PURE__*/ _jsx("label", {
|
|
135
|
+
className: "field-label",
|
|
136
|
+
htmlFor: path,
|
|
137
|
+
children: "Voice"
|
|
138
|
+
}),
|
|
139
|
+
/*#__PURE__*/ _jsx(SelectInput, {
|
|
140
|
+
name: name,
|
|
141
|
+
onChange: (option)=>{
|
|
142
|
+
if (option && typeof option === 'object' && 'value' in option) {
|
|
143
|
+
setValue(option.value);
|
|
144
|
+
} else {
|
|
145
|
+
setValue(option);
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
options: voices,
|
|
149
|
+
path: path,
|
|
150
|
+
value: value
|
|
151
|
+
})
|
|
152
|
+
]
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/DynamicVoiceSelect/index.tsx"],"sourcesContent":["'use client'\n\nimport { SelectInput, useField, useFormFields } from '@payloadcms/ui'\nimport React, { useEffect, useMemo, useState } from 'react'\n\ntype Props = {\n name: string\n path: string\n}\n\ninterface Voice {\n category?: string\n enabled?: boolean\n id: string\n labels?: Record<string, unknown>\n name: string\n preview_url?: string\n}\n\ninterface ProviderBlock {\n blockType: string\n enabled?: boolean\n voices?: Voice[]\n}\n\nexport const DynamicVoiceSelect: React.FC<Props> = (props) => {\n const { name, path } = props\n\n // Get provider from siblings\n const parentPath = path.split('.').slice(0, -1).join('.')\n const providerPath = `${parentPath}.provider`\n\n // Use useFormFields to get the provider field value - this will re-render when provider changes\n const providerField = useFormFields(([fields]) => fields[providerPath])\n const provider = (providerField?.value as string) || ''\n\n const { setValue, value } = useField<string>({ path })\n const [aiSettings, setAiSettings] = useState<{ providers?: ProviderBlock[] } | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n\n // Fetch AI Settings - re-fetch when provider changes to ensure we have latest voices\n useEffect(() => {\n const fetchSettings = async () => {\n setIsLoading(true)\n try {\n const response = await fetch('/api/globals/ai-settings?depth=1')\n if (response.ok) {\n const data = await response.json()\n setAiSettings(data)\n }\n } catch (err) {\n console.error('Error fetching AI settings:', err)\n } finally {\n setIsLoading(false)\n }\n }\n\n void fetchSettings()\n }, [provider]) // Re-fetch when provider changes to ensure we have the latest voices\n\n const voices = useMemo(() => {\n if (!provider || !aiSettings?.providers) {\n return []\n }\n\n // Find the provider block matching the selected provider\n const providerBlock = aiSettings.providers.find(\n (p: ProviderBlock) => p.blockType === provider && p.enabled !== false,\n )\n\n if (!providerBlock?.voices) {\n return []\n }\n\n // Get enabled voices from provider block\n return providerBlock.voices\n .filter((v: Voice) => v.enabled !== false)\n .map((v: Voice) => ({\n label: v.name || v.id,\n value: v.id,\n }))\n }, [provider, aiSettings])\n\n // Clear voice selection when provider changes and current voice is not available\n useEffect(() => {\n if (value && voices.length > 0) {\n const voiceExists = voices.some((v) => v.value === value)\n if (!voiceExists) {\n setValue('')\n }\n }\n }, [voices, value, setValue])\n\n if (!provider) {\n return (\n <div className=\"field-type text\">\n <label className=\"field-label\" htmlFor={path}>\n Voice\n </label>\n <p style={{ color: 'var(--theme-elevation-600)', fontSize: '13px' }}>\n Please select a provider first.\n </p>\n </div>\n )\n }\n\n if (isLoading) {\n return (\n <div className=\"field-type text\">\n <label className=\"field-label\" htmlFor={path}>\n Voice\n </label>\n <p style={{ color: 'var(--theme-elevation-600)', fontSize: '13px' }}>Loading voices...</p>\n </div>\n )\n }\n\n if (voices.length === 0) {\n return (\n <div className=\"field-type text\">\n <label className=\"field-label\" htmlFor={path}>\n Voice\n </label>\n <p style={{ color: 'var(--theme-elevation-600)', fontSize: '13px' }}>\n No voices available. Please configure voices in AI Settings for {provider}.\n </p>\n </div>\n )\n }\n\n return (\n <div className=\"field-type select\">\n <label className=\"field-label\" htmlFor={path}>\n Voice\n </label>\n <SelectInput\n name={name}\n onChange={(option) => {\n if (option && typeof option === 'object' && 'value' in option) {\n setValue(option.value as string)\n } else {\n setValue(option)\n }\n }}\n options={voices}\n path={path}\n value={value}\n />\n </div>\n )\n}\n\n"],"names":["SelectInput","useField","useFormFields","React","useEffect","useMemo","useState","DynamicVoiceSelect","props","name","path","parentPath","split","slice","join","providerPath","providerField","fields","provider","value","setValue","aiSettings","setAiSettings","isLoading","setIsLoading","fetchSettings","response","fetch","ok","data","json","err","console","error","voices","providers","providerBlock","find","p","blockType","enabled","filter","v","map","label","id","length","voiceExists","some","div","className","htmlFor","style","color","fontSize","onChange","option","options"],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { SelectInput, useField, useFormFields } from '@payloadcms/ui';
|
|
3
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
4
|
+
export const DynamicVoiceSelect = (props) => {
|
|
5
|
+
const { name, path } = props;
|
|
6
|
+
// Get provider from siblings
|
|
7
|
+
const parentPath = path.split('.').slice(0, -1).join('.');
|
|
8
|
+
const providerPath = `${parentPath}.provider`;
|
|
9
|
+
// Use useFormFields to get the provider field value - this will re-render when provider changes
|
|
10
|
+
const providerField = useFormFields(([fields]) => fields[providerPath]);
|
|
11
|
+
const provider = providerField?.value || '';
|
|
12
|
+
const { setValue, value } = useField({ path });
|
|
13
|
+
const [aiSettings, setAiSettings] = useState(null);
|
|
14
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
15
|
+
// Fetch AI Settings - re-fetch when provider changes to ensure we have latest voices
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
const fetchSettings = async () => {
|
|
18
|
+
setIsLoading(true);
|
|
19
|
+
try {
|
|
20
|
+
const response = await fetch('/api/globals/ai-settings?depth=1');
|
|
21
|
+
if (response.ok) {
|
|
22
|
+
const data = await response.json();
|
|
23
|
+
setAiSettings(data);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
console.error('Error fetching AI settings:', err);
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
setIsLoading(false);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
void fetchSettings();
|
|
34
|
+
}, [provider]); // Re-fetch when provider changes to ensure we have the latest voices
|
|
35
|
+
const voices = useMemo(() => {
|
|
36
|
+
if (!provider || !aiSettings?.providers) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
// Find the provider block matching the selected provider
|
|
40
|
+
const providerBlock = aiSettings.providers.find((p) => p.blockType === provider && p.enabled !== false);
|
|
41
|
+
if (!providerBlock?.voices) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
// Get enabled voices from provider block
|
|
45
|
+
return providerBlock.voices
|
|
46
|
+
.filter((v) => v.enabled !== false)
|
|
47
|
+
.map((v) => ({
|
|
48
|
+
label: v.name || v.id,
|
|
49
|
+
value: v.id,
|
|
50
|
+
}));
|
|
51
|
+
}, [provider, aiSettings]);
|
|
52
|
+
// Clear voice selection when provider changes and current voice is not available
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (value && voices.length > 0) {
|
|
55
|
+
const voiceExists = voices.some((v) => v.value === value);
|
|
56
|
+
if (!voiceExists) {
|
|
57
|
+
setValue('');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}, [voices, value, setValue]);
|
|
61
|
+
if (!provider) {
|
|
62
|
+
return (<div className="field-type text">
|
|
63
|
+
<label className="field-label" htmlFor={path}>
|
|
64
|
+
Voice
|
|
65
|
+
</label>
|
|
66
|
+
<p style={{ color: 'var(--theme-elevation-600)', fontSize: '13px' }}>
|
|
67
|
+
Please select a provider first.
|
|
68
|
+
</p>
|
|
69
|
+
</div>);
|
|
70
|
+
}
|
|
71
|
+
if (isLoading) {
|
|
72
|
+
return (<div className="field-type text">
|
|
73
|
+
<label className="field-label" htmlFor={path}>
|
|
74
|
+
Voice
|
|
75
|
+
</label>
|
|
76
|
+
<p style={{ color: 'var(--theme-elevation-600)', fontSize: '13px' }}>Loading voices...</p>
|
|
77
|
+
</div>);
|
|
78
|
+
}
|
|
79
|
+
if (voices.length === 0) {
|
|
80
|
+
return (<div className="field-type text">
|
|
81
|
+
<label className="field-label" htmlFor={path}>
|
|
82
|
+
Voice
|
|
83
|
+
</label>
|
|
84
|
+
<p style={{ color: 'var(--theme-elevation-600)', fontSize: '13px' }}>
|
|
85
|
+
No voices available. Please configure voices in AI Settings for {provider}.
|
|
86
|
+
</p>
|
|
87
|
+
</div>);
|
|
88
|
+
}
|
|
89
|
+
return (<div className="field-type select">
|
|
90
|
+
<label className="field-label" htmlFor={path}>
|
|
91
|
+
Voice
|
|
92
|
+
</label>
|
|
93
|
+
<SelectInput name={name} onChange={(option) => {
|
|
94
|
+
if (option && typeof option === 'object' && 'value' in option) {
|
|
95
|
+
setValue(option.value);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
setValue(option);
|
|
99
|
+
}
|
|
100
|
+
}} options={voices} path={path} value={value}/>
|
|
101
|
+
</div>);
|
|
102
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useField } from '@payloadcms/ui';
|
|
4
|
+
import React, { useState } from 'react';
|
|
5
|
+
export const EncryptedTextField = ({ label, path, required })=>{
|
|
6
|
+
const { setValue, value } = useField({
|
|
7
|
+
path
|
|
8
|
+
});
|
|
9
|
+
const [isEditing, setIsEditing] = useState(!value);
|
|
10
|
+
const isMasked = typeof value === 'string' && value.startsWith('sk-') && value.includes('****');
|
|
11
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
12
|
+
className: "field-type text",
|
|
13
|
+
children: [
|
|
14
|
+
/*#__PURE__*/ _jsxs("label", {
|
|
15
|
+
className: "field-label",
|
|
16
|
+
children: [
|
|
17
|
+
label || 'API Key',
|
|
18
|
+
required && /*#__PURE__*/ _jsx("span", {
|
|
19
|
+
className: "required",
|
|
20
|
+
children: "*"
|
|
21
|
+
})
|
|
22
|
+
]
|
|
23
|
+
}),
|
|
24
|
+
!isEditing && isMasked ? /*#__PURE__*/ _jsxs("div", {
|
|
25
|
+
style: {
|
|
26
|
+
alignItems: 'center',
|
|
27
|
+
display: 'flex',
|
|
28
|
+
gap: '10px'
|
|
29
|
+
},
|
|
30
|
+
children: [
|
|
31
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
32
|
+
style: {
|
|
33
|
+
background: 'var(--theme-elevation-100)',
|
|
34
|
+
borderRadius: '4px',
|
|
35
|
+
flexGrow: 1,
|
|
36
|
+
fontFamily: 'monospace',
|
|
37
|
+
padding: '8px 12px'
|
|
38
|
+
},
|
|
39
|
+
children: [
|
|
40
|
+
value,
|
|
41
|
+
/*#__PURE__*/ _jsx("span", {
|
|
42
|
+
style: {
|
|
43
|
+
color: 'var(--theme-success-500)',
|
|
44
|
+
fontSize: '0.8em',
|
|
45
|
+
marginLeft: '10px'
|
|
46
|
+
},
|
|
47
|
+
children: "✓ Configured"
|
|
48
|
+
})
|
|
49
|
+
]
|
|
50
|
+
}),
|
|
51
|
+
/*#__PURE__*/ _jsx("button", {
|
|
52
|
+
className: "btn btn--style-secondary btn--size-small",
|
|
53
|
+
onClick: ()=>{
|
|
54
|
+
setValue('');
|
|
55
|
+
setIsEditing(true);
|
|
56
|
+
},
|
|
57
|
+
type: "button",
|
|
58
|
+
children: "Change"
|
|
59
|
+
})
|
|
60
|
+
]
|
|
61
|
+
}) : /*#__PURE__*/ _jsx("input", {
|
|
62
|
+
onChange: (e)=>setValue(e.target.value),
|
|
63
|
+
placeholder: "sk-...",
|
|
64
|
+
style: {
|
|
65
|
+
width: '100%'
|
|
66
|
+
},
|
|
67
|
+
type: "password",
|
|
68
|
+
value: value || ''
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/EncryptedTextField/index.tsx"],"sourcesContent":["'use client'\n\nimport { useField } from '@payloadcms/ui'\nimport React, { useState } from 'react'\n\ntype Props = {\n label?: string\n path: string\n required?: boolean\n}\n\nexport const EncryptedTextField: React.FC<Props> = ({ label, path, required }) => {\n const { setValue, value } = useField<string>({ path })\n const [isEditing, setIsEditing] = useState(!value)\n\n const isMasked = typeof value === 'string' && value.startsWith('sk-') && value.includes('****')\n\n return (\n <div className=\"field-type text\">\n <label className=\"field-label\">\n {label || 'API Key'}\n {required && <span className=\"required\">*</span>}\n </label>\n\n {!isEditing && isMasked ? (\n <div style={{ alignItems: 'center', display: 'flex', gap: '10px' }}>\n <div\n style={{\n background: 'var(--theme-elevation-100)',\n borderRadius: '4px',\n flexGrow: 1,\n fontFamily: 'monospace',\n padding: '8px 12px',\n }}\n >\n {value}\n <span\n style={{ color: 'var(--theme-success-500)', fontSize: '0.8em', marginLeft: '10px' }}\n >\n ✓ Configured\n </span>\n </div>\n <button\n className=\"btn btn--style-secondary btn--size-small\"\n onClick={() => {\n setValue('')\n setIsEditing(true)\n }}\n type=\"button\"\n >\n Change\n </button>\n </div>\n ) : (\n <input\n onChange={(e) => setValue(e.target.value)}\n placeholder=\"sk-...\"\n style={{ width: '100%' }}\n type=\"password\"\n value={value || ''}\n />\n )}\n </div>\n )\n}\n"],"names":["useField","React","useState","EncryptedTextField","label","path","required","setValue","value","isEditing","setIsEditing","isMasked","startsWith","includes","div","className","span","style","alignItems","display","gap","background","borderRadius","flexGrow","fontFamily","padding","color","fontSize","marginLeft","button","onClick","type","input","onChange","e","target","placeholder","width"],"mappings":"AAAA;;AAEA,SAASA,QAAQ,QAAQ,iBAAgB;AACzC,OAAOC,SAASC,QAAQ,QAAQ,QAAO;AAQvC,OAAO,MAAMC,qBAAsC,CAAC,EAAEC,KAAK,EAAEC,IAAI,EAAEC,QAAQ,EAAE;IAC3E,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAE,GAAGR,SAAiB;QAAEK;IAAK;IACpD,MAAM,CAACI,WAAWC,aAAa,GAAGR,SAAS,CAACM;IAE5C,MAAMG,WAAW,OAAOH,UAAU,YAAYA,MAAMI,UAAU,CAAC,UAAUJ,MAAMK,QAAQ,CAAC;IAExF,qBACE,MAACC;QAAIC,WAAU;;0BACb,MAACX;gBAAMW,WAAU;;oBACdX,SAAS;oBACTE,0BAAY,KAACU;wBAAKD,WAAU;kCAAW;;;;YAGzC,CAACN,aAAaE,yBACb,MAACG;gBAAIG,OAAO;oBAAEC,YAAY;oBAAUC,SAAS;oBAAQC,KAAK;gBAAO;;kCAC/D,MAACN;wBACCG,OAAO;4BACLI,YAAY;4BACZC,cAAc;4BACdC,UAAU;4BACVC,YAAY;4BACZC,SAAS;wBACX;;4BAECjB;0CACD,KAACQ;gCACCC,OAAO;oCAAES,OAAO;oCAA4BC,UAAU;oCAASC,YAAY;gCAAO;0CACnF;;;;kCAIH,KAACC;wBACCd,WAAU;wBACVe,SAAS;4BACPvB,SAAS;4BACTG,aAAa;wBACf;wBACAqB,MAAK;kCACN;;;+BAKH,KAACC;gBACCC,UAAU,CAACC,IAAM3B,SAAS2B,EAAEC,MAAM,CAAC3B,KAAK;gBACxC4B,aAAY;gBACZnB,OAAO;oBAAEoB,OAAO;gBAAO;gBACvBN,MAAK;gBACLvB,OAAOA,SAAS;;;;AAK1B,EAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useField } from '@payloadcms/ui';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
export const EncryptedTextField = ({ label, path, required }) => {
|
|
5
|
+
const { setValue, value } = useField({ path });
|
|
6
|
+
const [isEditing, setIsEditing] = useState(!value);
|
|
7
|
+
const isMasked = typeof value === 'string' && value.startsWith('sk-') && value.includes('****');
|
|
8
|
+
return (<div className="field-type text">
|
|
9
|
+
<label className="field-label">
|
|
10
|
+
{label || 'API Key'}
|
|
11
|
+
{required && <span className="required">*</span>}
|
|
12
|
+
</label>
|
|
13
|
+
|
|
14
|
+
{!isEditing && isMasked ? (<div style={{ alignItems: 'center', display: 'flex', gap: '10px' }}>
|
|
15
|
+
<div style={{
|
|
16
|
+
background: 'var(--theme-elevation-100)',
|
|
17
|
+
borderRadius: '4px',
|
|
18
|
+
flexGrow: 1,
|
|
19
|
+
fontFamily: 'monospace',
|
|
20
|
+
padding: '8px 12px',
|
|
21
|
+
}}>
|
|
22
|
+
{value}
|
|
23
|
+
<span style={{ color: 'var(--theme-success-500)', fontSize: '0.8em', marginLeft: '10px' }}>
|
|
24
|
+
✓ Configured
|
|
25
|
+
</span>
|
|
26
|
+
</div>
|
|
27
|
+
<button className="btn btn--style-secondary btn--size-small" onClick={() => {
|
|
28
|
+
setValue('');
|
|
29
|
+
setIsEditing(true);
|
|
30
|
+
}} type="button">
|
|
31
|
+
Change
|
|
32
|
+
</button>
|
|
33
|
+
</div>) : (<input onChange={(e) => setValue(e.target.value)} placeholder="sk-..." style={{ width: '100%' }} type="password" value={value || ''}/>)}
|
|
34
|
+
</div>);
|
|
35
|
+
};
|
|
@@ -7,7 +7,9 @@ const LottieAnimation = ({ isLoading = false })=>{
|
|
|
7
7
|
const [animations, setAnimations] = useState([]);
|
|
8
8
|
useEffect(()=>{
|
|
9
9
|
const svg = svgRef.current;
|
|
10
|
-
if (!svg)
|
|
10
|
+
if (!svg) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
11
13
|
const animateTransform = (element, keyframes)=>{
|
|
12
14
|
const animation = element.animate(keyframes, {
|
|
13
15
|
direction: 'alternate',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/ui/Icons/LottieAnimation.tsx"],"sourcesContent":["// @ts-nocheck\n\nimport React, { useEffect, useRef, useState } from 'react'\n\nimport styles from './icons.module.css'\n\nconst LottieAnimation = ({ isLoading = false }) => {\n const svgRef = useRef(null)\n const [animations, setAnimations] = useState([])\n\n useEffect(() => {\n const svg = svgRef.current\n if (!svg) return\n\n const animateTransform = (element, keyframes) => {\n const animation = element.animate(keyframes, {\n direction: 'alternate',\n duration: 1000,\n easing: 'ease-in-out',\n iterations: Infinity,\n })\n return animation\n }\n\n // Animate Group 2 (Rectangle)\n const rectangle = svg.querySelector('#group2')\n const rectangleAnimation = animateTransform(rectangle, [\n { transform: 'translate(0, 0) scale(1)' },\n { transform: 'translate(0, 0) scale(2.54)' },\n { transform: 'translate(0, 0) scale(1)' },\n ])\n\n // Animate Group 3 (Triangle)\n const triangle = svg.querySelector('#group3')\n const triangleAnimation = animateTransform(triangle, [\n { transform: 'translate(-69.5px, 77.5px) scale(1)' },\n { transform: 'translate(-70px, 73px) scale(0.36)' },\n { transform: 'translate(-69.5px, 77.5px) scale(1)' },\n ])\n\n setAnimations([rectangleAnimation, triangleAnimation])\n\n // Clean up animations on unmount\n return () => {\n rectangleAnimation.cancel()\n triangleAnimation.cancel()\n }\n }, [])\n\n useEffect(() => {\n if (isLoading) {\n animations.forEach((animation) => animation.play())\n } else {\n animations.forEach((animation) => animation.pause())\n }\n }, [isLoading, animations])\n\n return (\n <span\n style={{\n left: '3px',\n position: 'relative',\n top: '-6px',\n }}\n >\n <svg height=\"41\" ref={svgRef} viewBox=\"-250 -250 500 500\" width=\"41\">\n <g id=\"group2\">\n <rect className={styles.color_fill} height=\"41\" width=\"41\" x=\"-20.5\" y=\"-20.5\" />\n </g>\n <g id=\"group3\">\n <path className={styles.color_fill} d=\"M48.5 57.5L48.5 -57.5L-49.5 -1.093L48.5 57.5Z\" />\n </g>\n </svg>\n </span>\n )\n}\n\nexport default LottieAnimation\n"],"names":["React","useEffect","useRef","useState","styles","LottieAnimation","isLoading","svgRef","animations","setAnimations","svg","current","animateTransform","element","keyframes","animation","animate","direction","duration","easing","iterations","Infinity","rectangle","querySelector","rectangleAnimation","transform","triangle","triangleAnimation","cancel","forEach","play","pause","span","style","left","position","top","height","ref","viewBox","width","g","id","rect","className","color_fill","x","y","path","d"],"mappings":"AAAA,cAAc;;AAEd,OAAOA,SAASC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAO;AAE1D,OAAOC,YAAY,qBAAoB;AAEvC,MAAMC,kBAAkB,CAAC,EAAEC,YAAY,KAAK,EAAE;IAC5C,MAAMC,SAASL,OAAO;IACtB,MAAM,CAACM,YAAYC,cAAc,GAAGN,SAAS,EAAE;IAE/CF,UAAU;QACR,MAAMS,MAAMH,OAAOI,OAAO;QAC1B,IAAI,CAACD,KAAK;
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/Icons/LottieAnimation.tsx"],"sourcesContent":["// @ts-nocheck\n\nimport React, { useEffect, useRef, useState } from 'react'\n\nimport styles from './icons.module.css'\n\nconst LottieAnimation = ({ isLoading = false }) => {\n const svgRef = useRef(null)\n const [animations, setAnimations] = useState([])\n\n useEffect(() => {\n const svg = svgRef.current\n if (!svg) {return}\n\n const animateTransform = (element, keyframes) => {\n const animation = element.animate(keyframes, {\n direction: 'alternate',\n duration: 1000,\n easing: 'ease-in-out',\n iterations: Infinity,\n })\n return animation\n }\n\n // Animate Group 2 (Rectangle)\n const rectangle = svg.querySelector('#group2')\n const rectangleAnimation = animateTransform(rectangle, [\n { transform: 'translate(0, 0) scale(1)' },\n { transform: 'translate(0, 0) scale(2.54)' },\n { transform: 'translate(0, 0) scale(1)' },\n ])\n\n // Animate Group 3 (Triangle)\n const triangle = svg.querySelector('#group3')\n const triangleAnimation = animateTransform(triangle, [\n { transform: 'translate(-69.5px, 77.5px) scale(1)' },\n { transform: 'translate(-70px, 73px) scale(0.36)' },\n { transform: 'translate(-69.5px, 77.5px) scale(1)' },\n ])\n\n setAnimations([rectangleAnimation, triangleAnimation])\n\n // Clean up animations on unmount\n return () => {\n rectangleAnimation.cancel()\n triangleAnimation.cancel()\n }\n }, [])\n\n useEffect(() => {\n if (isLoading) {\n animations.forEach((animation) => animation.play())\n } else {\n animations.forEach((animation) => animation.pause())\n }\n }, [isLoading, animations])\n\n return (\n <span\n style={{\n left: '3px',\n position: 'relative',\n top: '-6px',\n }}\n >\n <svg height=\"41\" ref={svgRef} viewBox=\"-250 -250 500 500\" width=\"41\">\n <g id=\"group2\">\n <rect className={styles.color_fill} height=\"41\" width=\"41\" x=\"-20.5\" y=\"-20.5\" />\n </g>\n <g id=\"group3\">\n <path className={styles.color_fill} d=\"M48.5 57.5L48.5 -57.5L-49.5 -1.093L48.5 57.5Z\" />\n </g>\n </svg>\n </span>\n )\n}\n\nexport default LottieAnimation\n"],"names":["React","useEffect","useRef","useState","styles","LottieAnimation","isLoading","svgRef","animations","setAnimations","svg","current","animateTransform","element","keyframes","animation","animate","direction","duration","easing","iterations","Infinity","rectangle","querySelector","rectangleAnimation","transform","triangle","triangleAnimation","cancel","forEach","play","pause","span","style","left","position","top","height","ref","viewBox","width","g","id","rect","className","color_fill","x","y","path","d"],"mappings":"AAAA,cAAc;;AAEd,OAAOA,SAASC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAO;AAE1D,OAAOC,YAAY,qBAAoB;AAEvC,MAAMC,kBAAkB,CAAC,EAAEC,YAAY,KAAK,EAAE;IAC5C,MAAMC,SAASL,OAAO;IACtB,MAAM,CAACM,YAAYC,cAAc,GAAGN,SAAS,EAAE;IAE/CF,UAAU;QACR,MAAMS,MAAMH,OAAOI,OAAO;QAC1B,IAAI,CAACD,KAAK;YAAC;QAAM;QAEjB,MAAME,mBAAmB,CAACC,SAASC;YACjC,MAAMC,YAAYF,QAAQG,OAAO,CAACF,WAAW;gBAC3CG,WAAW;gBACXC,UAAU;gBACVC,QAAQ;gBACRC,YAAYC;YACd;YACA,OAAON;QACT;QAEA,8BAA8B;QAC9B,MAAMO,YAAYZ,IAAIa,aAAa,CAAC;QACpC,MAAMC,qBAAqBZ,iBAAiBU,WAAW;YACrD;gBAAEG,WAAW;YAA2B;YACxC;gBAAEA,WAAW;YAA8B;YAC3C;gBAAEA,WAAW;YAA2B;SACzC;QAED,6BAA6B;QAC7B,MAAMC,WAAWhB,IAAIa,aAAa,CAAC;QACnC,MAAMI,oBAAoBf,iBAAiBc,UAAU;YACnD;gBAAED,WAAW;YAAsC;YACnD;gBAAEA,WAAW;YAAqC;YAClD;gBAAEA,WAAW;YAAsC;SACpD;QAEDhB,cAAc;YAACe;YAAoBG;SAAkB;QAErD,iCAAiC;QACjC,OAAO;YACLH,mBAAmBI,MAAM;YACzBD,kBAAkBC,MAAM;QAC1B;IACF,GAAG,EAAE;IAEL3B,UAAU;QACR,IAAIK,WAAW;YACbE,WAAWqB,OAAO,CAAC,CAACd,YAAcA,UAAUe,IAAI;QAClD,OAAO;YACLtB,WAAWqB,OAAO,CAAC,CAACd,YAAcA,UAAUgB,KAAK;QACnD;IACF,GAAG;QAACzB;QAAWE;KAAW;IAE1B,qBACE,KAACwB;QACCC,OAAO;YACLC,MAAM;YACNC,UAAU;YACVC,KAAK;QACP;kBAEA,cAAA,MAAC1B;YAAI2B,QAAO;YAAKC,KAAK/B;YAAQgC,SAAQ;YAAoBC,OAAM;;8BAC9D,KAACC;oBAAEC,IAAG;8BACJ,cAAA,KAACC;wBAAKC,WAAWxC,OAAOyC,UAAU;wBAAER,QAAO;wBAAKG,OAAM;wBAAKM,GAAE;wBAAQC,GAAE;;;8BAEzE,KAACN;oBAAEC,IAAG;8BACJ,cAAA,KAACM;wBAAKJ,WAAWxC,OAAOyC,UAAU;wBAAEI,GAAE;;;;;;AAKhD;AAEA,eAAe5C,gBAAe"}
|
|
@@ -6,8 +6,9 @@ const LottieAnimation = ({ isLoading = false }) => {
|
|
|
6
6
|
const [animations, setAnimations] = useState([]);
|
|
7
7
|
useEffect(() => {
|
|
8
8
|
const svg = svgRef.current;
|
|
9
|
-
if (!svg)
|
|
9
|
+
if (!svg) {
|
|
10
10
|
return;
|
|
11
|
+
}
|
|
11
12
|
const animateTransform = (element, keyframes) => {
|
|
12
13
|
const animation = element.animate(keyframes, {
|
|
13
14
|
direction: 'alternate',
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useRowLabel } from '@payloadcms/ui';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
/**
|
|
6
|
+
* Generic Model Row Label component for provider blocks
|
|
7
|
+
* Displays model name with enabled status badge
|
|
8
|
+
*/ export const ModelRowLabel = ()=>{
|
|
9
|
+
const { data, rowNumber } = useRowLabel();
|
|
10
|
+
const displayName = data?.name || data?.id || `Model ${rowNumber}`;
|
|
11
|
+
const isEnabled = data?.enabled !== false;
|
|
12
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
13
|
+
style: {
|
|
14
|
+
alignItems: 'center',
|
|
15
|
+
display: 'flex',
|
|
16
|
+
gap: '10px'
|
|
17
|
+
},
|
|
18
|
+
children: [
|
|
19
|
+
/*#__PURE__*/ _jsx("span", {
|
|
20
|
+
style: {
|
|
21
|
+
fontWeight: '500'
|
|
22
|
+
},
|
|
23
|
+
children: displayName
|
|
24
|
+
}),
|
|
25
|
+
/*#__PURE__*/ _jsx("span", {
|
|
26
|
+
style: {
|
|
27
|
+
backgroundColor: isEnabled ? 'var(--theme-success-100)' : 'var(--theme-elevation-200)',
|
|
28
|
+
borderRadius: '4px',
|
|
29
|
+
color: isEnabled ? 'var(--theme-success-700)' : 'var(--theme-elevation-600)',
|
|
30
|
+
fontSize: '11px',
|
|
31
|
+
fontWeight: '600',
|
|
32
|
+
padding: '2px 8px',
|
|
33
|
+
textTransform: 'uppercase'
|
|
34
|
+
},
|
|
35
|
+
children: isEnabled ? '●Enabled' : 'Disabled'
|
|
36
|
+
})
|
|
37
|
+
]
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/ModelRowLabel/index.tsx"],"sourcesContent":["'use client'\n\nimport type { ArrayFieldLabelClientComponent } from 'payload'\n\nimport { useRowLabel } from '@payloadcms/ui'\nimport React from 'react'\n\n/**\n * Generic Model Row Label component for provider blocks\n * Displays model name with enabled status badge\n */\nexport const ModelRowLabel: ArrayFieldLabelClientComponent = () => {\n const { data, rowNumber } = useRowLabel<{\n enabled?: boolean\n id?: string\n name?: string\n }>()\n\n const displayName = data?.name || data?.id || `Model ${rowNumber}`\n const isEnabled = data?.enabled !== false\n\n return (\n <div style={{ alignItems: 'center', display: 'flex', gap: '10px' }}>\n <span style={{ fontWeight: '500' }}>{displayName}</span>\n <span\n style={{\n backgroundColor: isEnabled ? 'var(--theme-success-100)' : 'var(--theme-elevation-200)',\n borderRadius: '4px',\n color: isEnabled ? 'var(--theme-success-700)' : 'var(--theme-elevation-600)',\n fontSize: '11px',\n fontWeight: '600',\n padding: '2px 8px',\n textTransform: 'uppercase',\n }}\n >\n {isEnabled ? '●Enabled' : 'Disabled'}\n </span>\n </div>\n )\n}\n"],"names":["useRowLabel","React","ModelRowLabel","data","rowNumber","displayName","name","id","isEnabled","enabled","div","style","alignItems","display","gap","span","fontWeight","backgroundColor","borderRadius","color","fontSize","padding","textTransform"],"mappings":"AAAA;;AAIA,SAASA,WAAW,QAAQ,iBAAgB;AAC5C,OAAOC,WAAW,QAAO;AAEzB;;;CAGC,GACD,OAAO,MAAMC,gBAAgD;IAC3D,MAAM,EAAEC,IAAI,EAAEC,SAAS,EAAE,GAAGJ;IAM5B,MAAMK,cAAcF,MAAMG,QAAQH,MAAMI,MAAM,CAAC,MAAM,EAAEH,UAAU,CAAC;IAClE,MAAMI,YAAYL,MAAMM,YAAY;IAEpC,qBACE,MAACC;QAAIC,OAAO;YAAEC,YAAY;YAAUC,SAAS;YAAQC,KAAK;QAAO;;0BAC/D,KAACC;gBAAKJ,OAAO;oBAAEK,YAAY;gBAAM;0BAAIX;;0BACrC,KAACU;gBACCJ,OAAO;oBACLM,iBAAiBT,YAAY,6BAA6B;oBAC1DU,cAAc;oBACdC,OAAOX,YAAY,6BAA6B;oBAChDY,UAAU;oBACVJ,YAAY;oBACZK,SAAS;oBACTC,eAAe;gBACjB;0BAECd,YAAY,aAAa;;;;AAIlC,EAAC"}
|