@strapi/content-type-builder 5.29.0 → 5.30.1
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/dist/admin/components/AIChat/Chat.js +1 -0
- package/dist/admin/components/AIChat/Chat.js.map +1 -1
- package/dist/admin/components/AIChat/Chat.mjs +1 -0
- package/dist/admin/components/AIChat/Chat.mjs.map +1 -1
- package/dist/admin/components/AIChat/FeedbackModal.js.map +1 -1
- package/dist/admin/components/AIChat/FeedbackModal.mjs.map +1 -1
- package/dist/admin/components/AIChat/UploadFigmaModal.js +2 -1
- package/dist/admin/components/AIChat/UploadFigmaModal.js.map +1 -1
- package/dist/admin/components/AIChat/UploadFigmaModal.mjs +2 -1
- package/dist/admin/components/AIChat/UploadFigmaModal.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/Base64Image.js.map +1 -1
- package/dist/admin/components/AIChat/components/Base64Image.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/Collapsible.js.map +1 -1
- package/dist/admin/components/AIChat/components/Collapsible.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/FullScreenImage.js.map +1 -1
- package/dist/admin/components/AIChat/components/FullScreenImage.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/Messages/Message.js.map +1 -1
- package/dist/admin/components/AIChat/components/Messages/Message.mjs.map +1 -1
- package/dist/admin/components/AIChat/hooks/useAIFetch.js.map +1 -1
- package/dist/admin/components/AIChat/hooks/useAIFetch.mjs.map +1 -1
- package/dist/admin/components/AIChat/hooks/useCodeUpload.js.map +1 -1
- package/dist/admin/components/AIChat/hooks/useCodeUpload.mjs.map +1 -1
- package/dist/admin/components/AIChat/hooks/useFigmaUpload.js.map +1 -1
- package/dist/admin/components/AIChat/hooks/useFigmaUpload.mjs.map +1 -1
- package/dist/admin/components/AIChat/lib/aiClient.js.map +1 -1
- package/dist/admin/components/AIChat/lib/aiClient.mjs.map +1 -1
- package/dist/admin/components/AIChat/lib/constants.js.map +1 -1
- package/dist/admin/components/AIChat/lib/constants.mjs.map +1 -1
- package/dist/admin/components/AIChat/providers/SchemaProvider.js.map +1 -1
- package/dist/admin/components/AIChat/providers/SchemaProvider.mjs.map +1 -1
- package/dist/admin/components/AttributeOptions/AttributeOption.js.map +1 -1
- package/dist/admin/components/AttributeOptions/AttributeOption.mjs.map +1 -1
- package/dist/admin/components/AttributeOptions/AttributeOptions.js.map +1 -1
- package/dist/admin/components/AttributeOptions/AttributeOptions.mjs.map +1 -1
- package/dist/admin/components/AttributeOptions/EmptyAttributes.js.map +1 -1
- package/dist/admin/components/AttributeOptions/EmptyAttributes.mjs.map +1 -1
- package/dist/admin/components/AttributeRow.js.map +1 -1
- package/dist/admin/components/AttributeRow.mjs.map +1 -1
- package/dist/admin/components/CheckboxWithNumberField.js +2 -1
- package/dist/admin/components/CheckboxWithNumberField.js.map +1 -1
- package/dist/admin/components/CheckboxWithNumberField.mjs +2 -1
- package/dist/admin/components/CheckboxWithNumberField.mjs.map +1 -1
- package/dist/admin/components/ComponentCard/ComponentCard.js.map +1 -1
- package/dist/admin/components/ComponentCard/ComponentCard.mjs.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.js.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.mjs.map +1 -1
- package/dist/admin/components/DataManager/utils/cleanData.js.map +1 -1
- package/dist/admin/components/DataManager/utils/cleanData.mjs.map +1 -1
- package/dist/admin/components/DisplayedType.js.map +1 -1
- package/dist/admin/components/DisplayedType.mjs.map +1 -1
- package/dist/admin/components/DynamicZoneList.js.map +1 -1
- package/dist/admin/components/DynamicZoneList.mjs.map +1 -1
- package/dist/admin/components/Footers.js.map +1 -1
- package/dist/admin/components/Footers.mjs.map +1 -1
- package/dist/admin/components/FormModal/FormModal.js.map +1 -1
- package/dist/admin/components/FormModal/FormModal.mjs.map +1 -1
- package/dist/admin/components/FormModal/attributes/ConditionForm.js.map +1 -1
- package/dist/admin/components/FormModal/attributes/ConditionForm.mjs.map +1 -1
- package/dist/admin/components/FormModal/attributes/advancedForm.js.map +1 -1
- package/dist/admin/components/FormModal/attributes/advancedForm.mjs.map +1 -1
- package/dist/admin/components/FormModal/attributes/baseForm.js.map +1 -1
- package/dist/admin/components/FormModal/attributes/baseForm.mjs.map +1 -1
- package/dist/admin/components/FormModal/component/componentForm.js.map +1 -1
- package/dist/admin/components/FormModal/component/componentForm.mjs.map +1 -1
- package/dist/admin/components/FormModal/forms/utils/createCollectionName.js.map +1 -1
- package/dist/admin/components/FormModal/forms/utils/createCollectionName.mjs.map +1 -1
- package/dist/admin/components/FormModal/utils/createUid.js.map +1 -1
- package/dist/admin/components/FormModal/utils/createUid.mjs.map +1 -1
- package/dist/admin/components/FormModalHeader.js.map +1 -1
- package/dist/admin/components/FormModalHeader.mjs.map +1 -1
- package/dist/admin/components/FormModalSubHeader.js.map +1 -1
- package/dist/admin/components/FormModalSubHeader.mjs.map +1 -1
- package/dist/admin/components/IconPicker/constants.js +3 -0
- package/dist/admin/components/IconPicker/constants.js.map +1 -1
- package/dist/admin/components/IconPicker/constants.mjs +3 -0
- package/dist/admin/components/IconPicker/constants.mjs.map +1 -1
- package/dist/admin/components/List.js.map +1 -1
- package/dist/admin/components/List.mjs.map +1 -1
- package/dist/admin/components/PluralName.js +2 -1
- package/dist/admin/components/PluralName.js.map +1 -1
- package/dist/admin/components/PluralName.mjs +2 -1
- package/dist/admin/components/PluralName.mjs.map +1 -1
- package/dist/admin/components/Relation/RelationField/RelationTargetPicker/RelationTargetPicker.js.map +1 -1
- package/dist/admin/components/Relation/RelationField/RelationTargetPicker/RelationTargetPicker.mjs.map +1 -1
- package/dist/admin/components/Relation/RelationNaturePicker/RelationNaturePicker.js.map +1 -1
- package/dist/admin/components/Relation/RelationNaturePicker/RelationNaturePicker.mjs.map +1 -1
- package/dist/admin/components/SelectComponent.js.map +1 -1
- package/dist/admin/components/SelectComponent.mjs.map +1 -1
- package/dist/admin/components/SingularName.js +2 -1
- package/dist/admin/components/SingularName.js.map +1 -1
- package/dist/admin/components/SingularName.mjs +2 -1
- package/dist/admin/components/SingularName.mjs.map +1 -1
- package/dist/admin/components/TabForm.js.map +1 -1
- package/dist/admin/components/TabForm.mjs.map +1 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/pages/App/index.js.map +1 -1
- package/dist/admin/pages/App/index.mjs.map +1 -1
- package/dist/admin/pages/ListView/ListView.js.map +1 -1
- package/dist/admin/pages/ListView/ListView.mjs.map +1 -1
- package/dist/admin/utils/conditions.js.map +1 -1
- package/dist/admin/utils/conditions.mjs.map +1 -1
- package/dist/admin/utils/getTrad.js.map +1 -1
- package/dist/admin/utils/getTrad.mjs.map +1 -1
- package/dist/admin/utils/prefixPluginTranslations.js.map +1 -1
- package/dist/admin/utils/prefixPluginTranslations.mjs.map +1 -1
- package/dist/admin/utils/timeFormat.js.map +1 -1
- package/dist/admin/utils/timeFormat.mjs.map +1 -1
- package/dist/server/controllers/validation/common.js.map +1 -1
- package/dist/server/controllers/validation/common.mjs.map +1 -1
- package/dist/server/controllers/validation/content-type.js.map +1 -1
- package/dist/server/controllers/validation/content-type.mjs.map +1 -1
- package/dist/server/controllers/validation/model-schema.js.map +1 -1
- package/dist/server/controllers/validation/model-schema.mjs.map +1 -1
- package/dist/server/controllers/validation/relations.js.map +1 -1
- package/dist/server/controllers/validation/relations.mjs.map +1 -1
- package/dist/server/register.js +30 -89
- package/dist/server/register.js.map +1 -1
- package/dist/server/register.mjs +30 -89
- package/dist/server/register.mjs.map +1 -1
- package/dist/server/services/api-handler.js.map +1 -1
- package/dist/server/services/api-handler.mjs.map +1 -1
- package/dist/server/services/component-categories.js.map +1 -1
- package/dist/server/services/component-categories.mjs.map +1 -1
- package/dist/server/services/schema-builder/component-builder.js.map +1 -1
- package/dist/server/services/schema-builder/component-builder.mjs.map +1 -1
- package/dist/server/services/schema-builder/content-type-builder.js.map +1 -1
- package/dist/server/services/schema-builder/content-type-builder.mjs.map +1 -1
- package/dist/server/src/index.d.ts +3 -1
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/register.d.ts +4 -9
- package/dist/server/src/register.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadFigmaModal.js","sources":["../../../../admin/src/components/AIChat/UploadFigmaModal.tsx"],"sourcesContent":["import { createContext, useContext, useState } from 'react';\n\nimport { Flex, Typography, Box, TextInput, Grid, Button, Link } from '@strapi/design-system'; // Added Link\n\nimport { ImagePreview } from './components/ImagePreview';\nimport { StepModal, useStepModal } from './components/StepModal';\nimport { useAttachments } from './hooks/useAttachments';\nimport {\n FigmaImage,\n useFigmaUpload,\n getFigmaToken,\n saveFigmaToken,\n hasFigmaToken,\n} from './hooks/useFigmaUpload';\nimport { useTranslations } from './hooks/useTranslations';\nimport { useStrapiChat } from './providers/ChatProvider';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface UploadFigmaContextType {\n isFigmaUploadOpen: boolean;\n submitOnFinish: boolean;\n openFigmaUpload: (submitOnFinish?: boolean) => void;\n closeFigmaUpload: () => void;\n}\n\nconst UploadFigmaContext = createContext<UploadFigmaContextType>({\n isFigmaUploadOpen: false,\n submitOnFinish: false,\n openFigmaUpload: () => {},\n closeFigmaUpload: () => {},\n});\n\nexport const useUploadFigmaToChat = () => {\n const context = useContext(UploadFigmaContext);\n if (!context) {\n throw new Error('useUploadFigmaToChat must be used within an UploadFigmaToChatProvider');\n }\n return context;\n};\n\nexport const UploadFigmaToChatProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFigmaUploadOpen, setIsFigmaUploadOpen] = useState(false); // Default to false\n const [submitOnFinish, setSubmitOnFinish] = useState(false);\n\n const openFigmaUpload = (submitOnFinishParam?: boolean) => {\n setIsFigmaUploadOpen(true);\n setSubmitOnFinish(submitOnFinishParam ?? false);\n };\n\n const closeFigmaUpload = () => setIsFigmaUploadOpen(false);\n\n return (\n <UploadFigmaContext.Provider\n value={{ isFigmaUploadOpen, submitOnFinish, openFigmaUpload, closeFigmaUpload }}\n >\n {isFigmaUploadOpen && <UploadFigmaModal />}\n {children}\n </UploadFigmaContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 1 - Input Figma URL\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaUrlInputStepProps {\n figmaUrl: string;\n setFigmaUrl: (url: string) => void;\n error: string | null; // Error state from useFigmaUpload\n}\n\nconst FigmaUrlInputStep = ({ figmaUrl, setFigmaUrl }: FigmaUrlInputStepProps) => {\n const { t } = useTranslations();\n const { isLoading } = useStepModal();\n const [showingTokenInput, setShowingTokenInput] = useState(!hasFigmaToken());\n const [figmaToken, setFigmaToken] = useState<string>(getFigmaToken);\n\n // Handle saving token and returning to URL input\n const handleSaveToken = () => {\n if (figmaToken.trim()) {\n saveFigmaToken(figmaToken);\n setShowingTokenInput(false);\n }\n };\n\n // If we need to show token step, render the token input\n if (showingTokenInput) {\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.token-title', 'Enter Figma API Token')}\n </Typography>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.token-description',\n 'To access your Figma designs, you need to provide a personal access token. This will be stored securely in your browser.'\n )}\n </Typography>\n <Link\n href=\"https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens\"\n isExternal\n >\n {t('chat.figma-upload.token-help', 'How to get a Figma API token')}\n </Link>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-token\"\n placeholder={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n aria-label={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n value={figmaToken}\n onChange={(e) => setFigmaToken(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"password\"\n />\n </Box>\n\n <Flex gap={2}>\n <Button onClick={handleSaveToken} disabled={!figmaToken.trim()} variant=\"secondary\">\n {t('chat.figma-upload.save-token', 'Save token')}\n </Button>\n <Button\n onClick={() => setShowingTokenInput(false)}\n variant=\"tertiary\"\n disabled={!hasFigmaToken()}\n >\n {t('chat.figma-upload.cancel', 'Cancel')}\n </Button>\n </Flex>\n </Flex>\n );\n }\n\n // Otherwise render the URL input\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\" width=\"100%\">\n <Flex justifyContent=\"space-between\" alignItems=\"center\" width=\"100%\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.title', 'Import Figma Design')}\n </Typography>\n <Button onClick={() => setShowingTokenInput(true)} variant=\"tertiary\" size=\"S\">\n {t('chat.figma-upload.edit-token', 'Edit API token')}\n </Button>\n </Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.description',\n 'Ask to turn your designs into schemas by attaching a link to one or multiple frames in your Figma files. (Max 15 frames)'\n )}\n </Typography>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-url\"\n placeholder={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n aria-label={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n value={figmaUrl}\n onChange={(e) => setFigmaUrl(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n />\n </Box>\n\n {/* {error && (\n <Box padding={3} background=\"danger100\" color=\"danger600\" borderRadius=\"4px\" width=\"100%\">\n <Typography variant=\"pi\">{error}</Typography>\n </Box>\n )} */}\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 2 - Display Figma Images\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaImageDisplayStepProps {\n images: FigmaImage[];\n selectedImages: string[];\n setSelectedImages: (images: string[]) => void;\n}\n\nconst FigmaImageDisplayStep = ({\n images,\n selectedImages,\n setSelectedImages,\n}: FigmaImageDisplayStepProps) => {\n const { t } = useTranslations();\n\n // Handle select/deselect all\n const toggleSelectAll = () => {\n if (selectedImages.length === images.length) {\n // Deselect all if all or max allowed are selected\n setSelectedImages([]);\n } else {\n // Select all images up to the max limit\n const allImageIds = images.map((img) => img.id);\n setSelectedImages(allImageIds);\n }\n };\n\n if (images.length === 0) {\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"center\" padding={4}>\n <Typography variant=\"omega\">\n {t('chat.figma-upload.no-images', 'No frames found in the Figma file.')}\n </Typography>\n </Flex>\n );\n }\n\n // Handle individual frame selection\n const handleFrameSelection = (frameId: string) => {\n const newSelection = selectedImages.includes(frameId)\n ? selectedImages.filter((id) => id !== frameId)\n : [...selectedImages, frameId];\n\n setSelectedImages(newSelection);\n };\n\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"start\" width=\"100%\" height=\"min(45vh, 400px)\">\n <Flex justifyContent=\"space-between\" width=\"100%\" alignItems=\"center\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.select-images', 'Select Frames to Import')}\n </Typography>\n <Flex gap={3} alignItems=\"center\">\n <Typography>\n {selectedImages.length} of {images.length} selected\n </Typography>\n <Button onClick={toggleSelectAll} type=\"button\" variant=\"secondary\">\n {/* Determine if select all button should show \"Select All\" or \"Deselect All\" */}\n {selectedImages.length === images.length\n ? t('chat.figma-upload.deselect-all', 'Deselect All')\n : t('chat.figma-upload.select-all', 'Select All')}\n </Button>\n </Flex>\n </Flex>\n\n <Box paddingRight={4} width=\"100%\" style={{ overflowY: 'auto' }}>\n <Grid.Root gap={4}>\n {images.map((frame, index) => {\n const isSelected = selectedImages.includes(frame.id);\n return (\n <Grid.Item key={frame.id} col={6} padding={'1px'}>\n <ImagePreview\n imageUrl={frame.url}\n imageName={frame.filename || `Frame ${index + 1}`}\n selected={isSelected}\n onSelect={() => handleFrameSelection(frame.id)}\n />\n </Grid.Item>\n );\n })}\n </Grid.Root>\n </Box>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\nexport const UploadFigmaModal = () => {\n const [figmaUrl, setFigmaUrl] = useState<string>('');\n const [figmaImages, setFigmaImages] = useState<FigmaImage[]>([]);\n const [selectedImages, setSelectedImages] = useState<string[]>([]);\n const { t } = useTranslations();\n\n const { addAttachments } = useAttachments();\n const { isFigmaUploadOpen, closeFigmaUpload, submitOnFinish } = useUploadFigmaToChat();\n const { input, setInput, setMessages, sendMessage, openChat } = useStrapiChat();\n const { processFigmaUrl, isLoading, error } = useFigmaUpload({\n onSuccess: (images) => {\n setFigmaImages(images);\n // Initialize with first 15 images selected\n const initialSelection = images.slice(0, 15).map((img) => img.id);\n setSelectedImages(initialSelection);\n },\n });\n\n const handleImportStep = async () => {\n await processFigmaUrl(figmaUrl);\n return true;\n };\n\n // Validate if the URL is a valid Figma URL\n const isValidFigmaUrl = (url: string) => {\n if (!url) return false;\n try {\n const urlObj = new URL(url);\n return urlObj.hostname === 'www.figma.com' || urlObj.hostname === 'figma.com';\n } catch (e) {\n return false;\n }\n };\n\n const handleCancel = () => {\n // Reset all state on cancel\n setFigmaUrl('');\n setFigmaImages([]);\n setSelectedImages([]);\n closeFigmaUpload();\n };\n\n const handleComplete = () => {\n // Only attach the selected images\n const selectedFigmaImages = figmaImages.filter((img) => selectedImages.includes(img.id));\n if (selectedFigmaImages.length === 0) {\n closeFigmaUpload();\n return;\n }\n\n // Ensure chat is opened\n openChat();\n\n if (submitOnFinish) {\n // Auto-submit a message to chat with attachments\n sendMessage({\n role: 'user',\n parts: [\n { type: 'text', text: 'Create schemas from the attached images' },\n ...selectedFigmaImages,\n ],\n });\n\n closeFigmaUpload();\n } else {\n // If input is empty, set a predefined message\n if (!input) {\n setInput('Create schemas from the attached images');\n }\n addAttachments(selectedFigmaImages);\n closeFigmaUpload();\n }\n };\n\n return (\n <StepModal\n open={isFigmaUploadOpen}\n onOpenChange={(isOpen) => {\n if (!isOpen) handleCancel();\n }}\n title={t('chat.figma-upload.header', 'Import from Figma')}\n onCancel={handleCancel}\n onComplete={handleComplete}\n >\n <StepModal.Step\n title={t('chat.figma-upload.step1-title', 'Enter Figma URL')}\n nextLabel={t('chat.figma-upload.import-button', 'Import')}\n cancelLabel={t('form.button.cancel', 'Cancel')}\n disableNext={!figmaUrl || isLoading || !isValidFigmaUrl(figmaUrl)}\n onNext={handleImportStep}\n >\n <FigmaUrlInputStep figmaUrl={figmaUrl} setFigmaUrl={setFigmaUrl} error={error} />\n </StepModal.Step>\n\n <StepModal.Step\n title={t('chat.figma-upload.step2-title', 'Preview Images')}\n nextLabel={t('form.button.finish', 'Finish')}\n backLabel={t('form.button.back', 'Back')}\n disableNext={selectedImages.length === 0}\n >\n <FigmaImageDisplayStep\n images={figmaImages}\n selectedImages={selectedImages}\n setSelectedImages={setSelectedImages}\n />\n </StepModal.Step>\n </StepModal>\n );\n};\n"],"names":["UploadFigmaContext","createContext","isFigmaUploadOpen","submitOnFinish","openFigmaUpload","closeFigmaUpload","useUploadFigmaToChat","context","useContext","Error","UploadFigmaToChatProvider","children","setIsFigmaUploadOpen","useState","setSubmitOnFinish","submitOnFinishParam","_jsxs","Provider","value","_jsx","UploadFigmaModal","FigmaUrlInputStep","figmaUrl","setFigmaUrl","t","useTranslations","isLoading","useStepModal","showingTokenInput","setShowingTokenInput","hasFigmaToken","figmaToken","setFigmaToken","getFigmaToken","handleSaveToken","trim","saveFigmaToken","Flex","direction","gap","alignItems","Typography","variant","textColor","Link","href","isExternal","Box","width","TextInput","name","placeholder","aria-label","onChange","e","target","disabled","type","Button","onClick","justifyContent","size","FigmaImageDisplayStep","images","selectedImages","setSelectedImages","toggleSelectAll","length","allImageIds","map","img","id","padding","handleFrameSelection","frameId","newSelection","includes","filter","height","paddingRight","style","overflowY","Grid","Root","frame","index","isSelected","Item","col","ImagePreview","imageUrl","url","imageName","filename","selected","onSelect","figmaImages","setFigmaImages","addAttachments","useAttachments","input","setInput","setMessages","sendMessage","openChat","useStrapiChat","processFigmaUrl","error","useFigmaUpload","onSuccess","initialSelection","slice","handleImportStep","isValidFigmaUrl","urlObj","URL","hostname","handleCancel","handleComplete","selectedFigmaImages","role","parts","text","StepModal","open","onOpenChange","isOpen","title","onCancel","onComplete","Step","nextLabel","cancelLabel","disableNext","onNext","backLabel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UploadFigmaModal.js","sources":["../../../../admin/src/components/AIChat/UploadFigmaModal.tsx"],"sourcesContent":["import { createContext, useContext, useState } from 'react';\n\nimport { Flex, Typography, Box, TextInput, Grid, Button, Link } from '@strapi/design-system'; // Added Link\n\nimport { ImagePreview } from './components/ImagePreview';\nimport { StepModal, useStepModal } from './components/StepModal';\nimport { useAttachments } from './hooks/useAttachments';\nimport {\n FigmaImage,\n useFigmaUpload,\n getFigmaToken,\n saveFigmaToken,\n hasFigmaToken,\n} from './hooks/useFigmaUpload';\nimport { useTranslations } from './hooks/useTranslations';\nimport { useStrapiChat } from './providers/ChatProvider';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface UploadFigmaContextType {\n isFigmaUploadOpen: boolean;\n submitOnFinish: boolean;\n openFigmaUpload: (submitOnFinish?: boolean) => void;\n closeFigmaUpload: () => void;\n}\n\nconst UploadFigmaContext = createContext<UploadFigmaContextType>({\n isFigmaUploadOpen: false,\n submitOnFinish: false,\n openFigmaUpload: () => {},\n closeFigmaUpload: () => {},\n});\n\nexport const useUploadFigmaToChat = () => {\n const context = useContext(UploadFigmaContext);\n if (!context) {\n throw new Error('useUploadFigmaToChat must be used within an UploadFigmaToChatProvider');\n }\n return context;\n};\n\nexport const UploadFigmaToChatProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFigmaUploadOpen, setIsFigmaUploadOpen] = useState(false); // Default to false\n const [submitOnFinish, setSubmitOnFinish] = useState(false);\n\n const openFigmaUpload = (submitOnFinishParam?: boolean) => {\n setIsFigmaUploadOpen(true);\n setSubmitOnFinish(submitOnFinishParam ?? false);\n };\n\n const closeFigmaUpload = () => setIsFigmaUploadOpen(false);\n\n return (\n <UploadFigmaContext.Provider\n value={{ isFigmaUploadOpen, submitOnFinish, openFigmaUpload, closeFigmaUpload }}\n >\n {isFigmaUploadOpen && <UploadFigmaModal />}\n {children}\n </UploadFigmaContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 1 - Input Figma URL\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaUrlInputStepProps {\n figmaUrl: string;\n setFigmaUrl: (url: string) => void;\n error: string | null; // Error state from useFigmaUpload\n}\n\nconst FigmaUrlInputStep = ({ figmaUrl, setFigmaUrl }: FigmaUrlInputStepProps) => {\n const { t } = useTranslations();\n const { isLoading } = useStepModal();\n const [showingTokenInput, setShowingTokenInput] = useState(!hasFigmaToken());\n const [figmaToken, setFigmaToken] = useState<string>(getFigmaToken);\n\n // Handle saving token and returning to URL input\n const handleSaveToken = () => {\n if (figmaToken.trim()) {\n saveFigmaToken(figmaToken);\n setShowingTokenInput(false);\n }\n };\n\n // If we need to show token step, render the token input\n if (showingTokenInput) {\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.token-title', 'Enter Figma API Token')}\n </Typography>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.token-description',\n 'To access your Figma designs, you need to provide a personal access token. This will be stored securely in your browser.'\n )}\n </Typography>\n <Link\n href=\"https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens\"\n isExternal\n >\n {t('chat.figma-upload.token-help', 'How to get a Figma API token')}\n </Link>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-token\"\n placeholder={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n aria-label={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n value={figmaToken}\n onChange={(e) => setFigmaToken(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"password\"\n />\n </Box>\n\n <Flex gap={2}>\n <Button onClick={handleSaveToken} disabled={!figmaToken.trim()} variant=\"secondary\">\n {t('chat.figma-upload.save-token', 'Save token')}\n </Button>\n <Button\n onClick={() => setShowingTokenInput(false)}\n variant=\"tertiary\"\n disabled={!hasFigmaToken()}\n >\n {t('chat.figma-upload.cancel', 'Cancel')}\n </Button>\n </Flex>\n </Flex>\n );\n }\n\n // Otherwise render the URL input\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\" width=\"100%\">\n <Flex justifyContent=\"space-between\" alignItems=\"center\" width=\"100%\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.title', 'Import Figma Design')}\n </Typography>\n <Button onClick={() => setShowingTokenInput(true)} variant=\"tertiary\" size=\"S\">\n {t('chat.figma-upload.edit-token', 'Edit API token')}\n </Button>\n </Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.description',\n 'Ask to turn your designs into schemas by attaching a link to one or multiple frames in your Figma files. (Max 15 frames)'\n )}\n </Typography>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-url\"\n placeholder={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n aria-label={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n value={figmaUrl}\n onChange={(e) => setFigmaUrl(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"url\"\n />\n </Box>\n\n {/* {error && (\n <Box padding={3} background=\"danger100\" color=\"danger600\" borderRadius=\"4px\" width=\"100%\">\n <Typography variant=\"pi\">{error}</Typography>\n </Box>\n )} */}\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 2 - Display Figma Images\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaImageDisplayStepProps {\n images: FigmaImage[];\n selectedImages: string[];\n setSelectedImages: (images: string[]) => void;\n}\n\nconst FigmaImageDisplayStep = ({\n images,\n selectedImages,\n setSelectedImages,\n}: FigmaImageDisplayStepProps) => {\n const { t } = useTranslations();\n\n // Handle select/deselect all\n const toggleSelectAll = () => {\n if (selectedImages.length === images.length) {\n // Deselect all if all or max allowed are selected\n setSelectedImages([]);\n } else {\n // Select all images up to the max limit\n const allImageIds = images.map((img) => img.id);\n setSelectedImages(allImageIds);\n }\n };\n\n if (images.length === 0) {\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"center\" padding={4}>\n <Typography variant=\"omega\">\n {t('chat.figma-upload.no-images', 'No frames found in the Figma file.')}\n </Typography>\n </Flex>\n );\n }\n\n // Handle individual frame selection\n const handleFrameSelection = (frameId: string) => {\n const newSelection = selectedImages.includes(frameId)\n ? selectedImages.filter((id) => id !== frameId)\n : [...selectedImages, frameId];\n\n setSelectedImages(newSelection);\n };\n\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"start\" width=\"100%\" height=\"min(45vh, 400px)\">\n <Flex justifyContent=\"space-between\" width=\"100%\" alignItems=\"center\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.select-images', 'Select Frames to Import')}\n </Typography>\n <Flex gap={3} alignItems=\"center\">\n <Typography>\n {selectedImages.length} of {images.length} selected\n </Typography>\n <Button onClick={toggleSelectAll} type=\"button\" variant=\"secondary\">\n {/* Determine if select all button should show \"Select All\" or \"Deselect All\" */}\n {selectedImages.length === images.length\n ? t('chat.figma-upload.deselect-all', 'Deselect All')\n : t('chat.figma-upload.select-all', 'Select All')}\n </Button>\n </Flex>\n </Flex>\n\n <Box paddingRight={4} width=\"100%\" style={{ overflowY: 'auto' }}>\n <Grid.Root gap={4}>\n {images.map((frame, index) => {\n const isSelected = selectedImages.includes(frame.id);\n return (\n <Grid.Item key={frame.id} col={6} padding={'1px'}>\n <ImagePreview\n imageUrl={frame.url}\n imageName={frame.filename || `Frame ${index + 1}`}\n selected={isSelected}\n onSelect={() => handleFrameSelection(frame.id)}\n />\n </Grid.Item>\n );\n })}\n </Grid.Root>\n </Box>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\nexport const UploadFigmaModal = () => {\n const [figmaUrl, setFigmaUrl] = useState<string>('');\n const [figmaImages, setFigmaImages] = useState<FigmaImage[]>([]);\n const [selectedImages, setSelectedImages] = useState<string[]>([]);\n const { t } = useTranslations();\n\n const { addAttachments } = useAttachments();\n const { isFigmaUploadOpen, closeFigmaUpload, submitOnFinish } = useUploadFigmaToChat();\n const { input, setInput, setMessages, sendMessage, openChat } = useStrapiChat();\n const { processFigmaUrl, isLoading, error } = useFigmaUpload({\n onSuccess: (images) => {\n setFigmaImages(images);\n // Initialize with first 15 images selected\n const initialSelection = images.slice(0, 15).map((img) => img.id);\n setSelectedImages(initialSelection);\n },\n });\n\n const handleImportStep = async () => {\n await processFigmaUrl(figmaUrl);\n return true;\n };\n\n // Validate if the URL is a valid Figma URL\n const isValidFigmaUrl = (url: string) => {\n if (!url) return false;\n try {\n const urlObj = new URL(url);\n return urlObj.hostname === 'www.figma.com' || urlObj.hostname === 'figma.com';\n } catch (e) {\n return false;\n }\n };\n\n const handleCancel = () => {\n // Reset all state on cancel\n setFigmaUrl('');\n setFigmaImages([]);\n setSelectedImages([]);\n closeFigmaUpload();\n };\n\n const handleComplete = () => {\n // Only attach the selected images\n const selectedFigmaImages = figmaImages.filter((img) => selectedImages.includes(img.id));\n if (selectedFigmaImages.length === 0) {\n closeFigmaUpload();\n return;\n }\n\n // Ensure chat is opened\n openChat();\n\n if (submitOnFinish) {\n // Auto-submit a message to chat with attachments\n sendMessage({\n role: 'user',\n parts: [\n { type: 'text', text: 'Create schemas from the attached images' },\n ...selectedFigmaImages,\n ],\n });\n\n closeFigmaUpload();\n } else {\n // If input is empty, set a predefined message\n if (!input) {\n setInput('Create schemas from the attached images');\n }\n addAttachments(selectedFigmaImages);\n closeFigmaUpload();\n }\n };\n\n return (\n <StepModal\n open={isFigmaUploadOpen}\n onOpenChange={(isOpen) => {\n if (!isOpen) handleCancel();\n }}\n title={t('chat.figma-upload.header', 'Import from Figma')}\n onCancel={handleCancel}\n onComplete={handleComplete}\n >\n <StepModal.Step\n title={t('chat.figma-upload.step1-title', 'Enter Figma URL')}\n nextLabel={t('chat.figma-upload.import-button', 'Import')}\n cancelLabel={t('form.button.cancel', 'Cancel')}\n disableNext={!figmaUrl || isLoading || !isValidFigmaUrl(figmaUrl)}\n onNext={handleImportStep}\n >\n <FigmaUrlInputStep figmaUrl={figmaUrl} setFigmaUrl={setFigmaUrl} error={error} />\n </StepModal.Step>\n\n <StepModal.Step\n title={t('chat.figma-upload.step2-title', 'Preview Images')}\n nextLabel={t('form.button.finish', 'Finish')}\n backLabel={t('form.button.back', 'Back')}\n disableNext={selectedImages.length === 0}\n >\n <FigmaImageDisplayStep\n images={figmaImages}\n selectedImages={selectedImages}\n setSelectedImages={setSelectedImages}\n />\n </StepModal.Step>\n </StepModal>\n );\n};\n"],"names":["UploadFigmaContext","createContext","isFigmaUploadOpen","submitOnFinish","openFigmaUpload","closeFigmaUpload","useUploadFigmaToChat","context","useContext","Error","UploadFigmaToChatProvider","children","setIsFigmaUploadOpen","useState","setSubmitOnFinish","submitOnFinishParam","_jsxs","Provider","value","_jsx","UploadFigmaModal","FigmaUrlInputStep","figmaUrl","setFigmaUrl","t","useTranslations","isLoading","useStepModal","showingTokenInput","setShowingTokenInput","hasFigmaToken","figmaToken","setFigmaToken","getFigmaToken","handleSaveToken","trim","saveFigmaToken","Flex","direction","gap","alignItems","Typography","variant","textColor","Link","href","isExternal","Box","width","TextInput","name","placeholder","aria-label","onChange","e","target","disabled","type","Button","onClick","justifyContent","size","FigmaImageDisplayStep","images","selectedImages","setSelectedImages","toggleSelectAll","length","allImageIds","map","img","id","padding","handleFrameSelection","frameId","newSelection","includes","filter","height","paddingRight","style","overflowY","Grid","Root","frame","index","isSelected","Item","col","ImagePreview","imageUrl","url","imageName","filename","selected","onSelect","figmaImages","setFigmaImages","addAttachments","useAttachments","input","setInput","setMessages","sendMessage","openChat","useStrapiChat","processFigmaUrl","error","useFigmaUpload","onSuccess","initialSelection","slice","handleImportStep","isValidFigmaUrl","urlObj","URL","hostname","handleCancel","handleComplete","selectedFigmaImages","role","parts","text","StepModal","open","onOpenChange","isOpen","title","onCancel","onComplete","Step","nextLabel","cancelLabel","disableNext","onNext","backLabel"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadFigmaModal.mjs","sources":["../../../../admin/src/components/AIChat/UploadFigmaModal.tsx"],"sourcesContent":["import { createContext, useContext, useState } from 'react';\n\nimport { Flex, Typography, Box, TextInput, Grid, Button, Link } from '@strapi/design-system'; // Added Link\n\nimport { ImagePreview } from './components/ImagePreview';\nimport { StepModal, useStepModal } from './components/StepModal';\nimport { useAttachments } from './hooks/useAttachments';\nimport {\n FigmaImage,\n useFigmaUpload,\n getFigmaToken,\n saveFigmaToken,\n hasFigmaToken,\n} from './hooks/useFigmaUpload';\nimport { useTranslations } from './hooks/useTranslations';\nimport { useStrapiChat } from './providers/ChatProvider';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface UploadFigmaContextType {\n isFigmaUploadOpen: boolean;\n submitOnFinish: boolean;\n openFigmaUpload: (submitOnFinish?: boolean) => void;\n closeFigmaUpload: () => void;\n}\n\nconst UploadFigmaContext = createContext<UploadFigmaContextType>({\n isFigmaUploadOpen: false,\n submitOnFinish: false,\n openFigmaUpload: () => {},\n closeFigmaUpload: () => {},\n});\n\nexport const useUploadFigmaToChat = () => {\n const context = useContext(UploadFigmaContext);\n if (!context) {\n throw new Error('useUploadFigmaToChat must be used within an UploadFigmaToChatProvider');\n }\n return context;\n};\n\nexport const UploadFigmaToChatProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFigmaUploadOpen, setIsFigmaUploadOpen] = useState(false); // Default to false\n const [submitOnFinish, setSubmitOnFinish] = useState(false);\n\n const openFigmaUpload = (submitOnFinishParam?: boolean) => {\n setIsFigmaUploadOpen(true);\n setSubmitOnFinish(submitOnFinishParam ?? false);\n };\n\n const closeFigmaUpload = () => setIsFigmaUploadOpen(false);\n\n return (\n <UploadFigmaContext.Provider\n value={{ isFigmaUploadOpen, submitOnFinish, openFigmaUpload, closeFigmaUpload }}\n >\n {isFigmaUploadOpen && <UploadFigmaModal />}\n {children}\n </UploadFigmaContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 1 - Input Figma URL\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaUrlInputStepProps {\n figmaUrl: string;\n setFigmaUrl: (url: string) => void;\n error: string | null; // Error state from useFigmaUpload\n}\n\nconst FigmaUrlInputStep = ({ figmaUrl, setFigmaUrl }: FigmaUrlInputStepProps) => {\n const { t } = useTranslations();\n const { isLoading } = useStepModal();\n const [showingTokenInput, setShowingTokenInput] = useState(!hasFigmaToken());\n const [figmaToken, setFigmaToken] = useState<string>(getFigmaToken);\n\n // Handle saving token and returning to URL input\n const handleSaveToken = () => {\n if (figmaToken.trim()) {\n saveFigmaToken(figmaToken);\n setShowingTokenInput(false);\n }\n };\n\n // If we need to show token step, render the token input\n if (showingTokenInput) {\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.token-title', 'Enter Figma API Token')}\n </Typography>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.token-description',\n 'To access your Figma designs, you need to provide a personal access token. This will be stored securely in your browser.'\n )}\n </Typography>\n <Link\n href=\"https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens\"\n isExternal\n >\n {t('chat.figma-upload.token-help', 'How to get a Figma API token')}\n </Link>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-token\"\n placeholder={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n aria-label={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n value={figmaToken}\n onChange={(e) => setFigmaToken(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"password\"\n />\n </Box>\n\n <Flex gap={2}>\n <Button onClick={handleSaveToken} disabled={!figmaToken.trim()} variant=\"secondary\">\n {t('chat.figma-upload.save-token', 'Save token')}\n </Button>\n <Button\n onClick={() => setShowingTokenInput(false)}\n variant=\"tertiary\"\n disabled={!hasFigmaToken()}\n >\n {t('chat.figma-upload.cancel', 'Cancel')}\n </Button>\n </Flex>\n </Flex>\n );\n }\n\n // Otherwise render the URL input\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\" width=\"100%\">\n <Flex justifyContent=\"space-between\" alignItems=\"center\" width=\"100%\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.title', 'Import Figma Design')}\n </Typography>\n <Button onClick={() => setShowingTokenInput(true)} variant=\"tertiary\" size=\"S\">\n {t('chat.figma-upload.edit-token', 'Edit API token')}\n </Button>\n </Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.description',\n 'Ask to turn your designs into schemas by attaching a link to one or multiple frames in your Figma files. (Max 15 frames)'\n )}\n </Typography>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-url\"\n placeholder={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n aria-label={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n value={figmaUrl}\n onChange={(e) => setFigmaUrl(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n />\n </Box>\n\n {/* {error && (\n <Box padding={3} background=\"danger100\" color=\"danger600\" borderRadius=\"4px\" width=\"100%\">\n <Typography variant=\"pi\">{error}</Typography>\n </Box>\n )} */}\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 2 - Display Figma Images\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaImageDisplayStepProps {\n images: FigmaImage[];\n selectedImages: string[];\n setSelectedImages: (images: string[]) => void;\n}\n\nconst FigmaImageDisplayStep = ({\n images,\n selectedImages,\n setSelectedImages,\n}: FigmaImageDisplayStepProps) => {\n const { t } = useTranslations();\n\n // Handle select/deselect all\n const toggleSelectAll = () => {\n if (selectedImages.length === images.length) {\n // Deselect all if all or max allowed are selected\n setSelectedImages([]);\n } else {\n // Select all images up to the max limit\n const allImageIds = images.map((img) => img.id);\n setSelectedImages(allImageIds);\n }\n };\n\n if (images.length === 0) {\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"center\" padding={4}>\n <Typography variant=\"omega\">\n {t('chat.figma-upload.no-images', 'No frames found in the Figma file.')}\n </Typography>\n </Flex>\n );\n }\n\n // Handle individual frame selection\n const handleFrameSelection = (frameId: string) => {\n const newSelection = selectedImages.includes(frameId)\n ? selectedImages.filter((id) => id !== frameId)\n : [...selectedImages, frameId];\n\n setSelectedImages(newSelection);\n };\n\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"start\" width=\"100%\" height=\"min(45vh, 400px)\">\n <Flex justifyContent=\"space-between\" width=\"100%\" alignItems=\"center\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.select-images', 'Select Frames to Import')}\n </Typography>\n <Flex gap={3} alignItems=\"center\">\n <Typography>\n {selectedImages.length} of {images.length} selected\n </Typography>\n <Button onClick={toggleSelectAll} type=\"button\" variant=\"secondary\">\n {/* Determine if select all button should show \"Select All\" or \"Deselect All\" */}\n {selectedImages.length === images.length\n ? t('chat.figma-upload.deselect-all', 'Deselect All')\n : t('chat.figma-upload.select-all', 'Select All')}\n </Button>\n </Flex>\n </Flex>\n\n <Box paddingRight={4} width=\"100%\" style={{ overflowY: 'auto' }}>\n <Grid.Root gap={4}>\n {images.map((frame, index) => {\n const isSelected = selectedImages.includes(frame.id);\n return (\n <Grid.Item key={frame.id} col={6} padding={'1px'}>\n <ImagePreview\n imageUrl={frame.url}\n imageName={frame.filename || `Frame ${index + 1}`}\n selected={isSelected}\n onSelect={() => handleFrameSelection(frame.id)}\n />\n </Grid.Item>\n );\n })}\n </Grid.Root>\n </Box>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\nexport const UploadFigmaModal = () => {\n const [figmaUrl, setFigmaUrl] = useState<string>('');\n const [figmaImages, setFigmaImages] = useState<FigmaImage[]>([]);\n const [selectedImages, setSelectedImages] = useState<string[]>([]);\n const { t } = useTranslations();\n\n const { addAttachments } = useAttachments();\n const { isFigmaUploadOpen, closeFigmaUpload, submitOnFinish } = useUploadFigmaToChat();\n const { input, setInput, setMessages, sendMessage, openChat } = useStrapiChat();\n const { processFigmaUrl, isLoading, error } = useFigmaUpload({\n onSuccess: (images) => {\n setFigmaImages(images);\n // Initialize with first 15 images selected\n const initialSelection = images.slice(0, 15).map((img) => img.id);\n setSelectedImages(initialSelection);\n },\n });\n\n const handleImportStep = async () => {\n await processFigmaUrl(figmaUrl);\n return true;\n };\n\n // Validate if the URL is a valid Figma URL\n const isValidFigmaUrl = (url: string) => {\n if (!url) return false;\n try {\n const urlObj = new URL(url);\n return urlObj.hostname === 'www.figma.com' || urlObj.hostname === 'figma.com';\n } catch (e) {\n return false;\n }\n };\n\n const handleCancel = () => {\n // Reset all state on cancel\n setFigmaUrl('');\n setFigmaImages([]);\n setSelectedImages([]);\n closeFigmaUpload();\n };\n\n const handleComplete = () => {\n // Only attach the selected images\n const selectedFigmaImages = figmaImages.filter((img) => selectedImages.includes(img.id));\n if (selectedFigmaImages.length === 0) {\n closeFigmaUpload();\n return;\n }\n\n // Ensure chat is opened\n openChat();\n\n if (submitOnFinish) {\n // Auto-submit a message to chat with attachments\n sendMessage({\n role: 'user',\n parts: [\n { type: 'text', text: 'Create schemas from the attached images' },\n ...selectedFigmaImages,\n ],\n });\n\n closeFigmaUpload();\n } else {\n // If input is empty, set a predefined message\n if (!input) {\n setInput('Create schemas from the attached images');\n }\n addAttachments(selectedFigmaImages);\n closeFigmaUpload();\n }\n };\n\n return (\n <StepModal\n open={isFigmaUploadOpen}\n onOpenChange={(isOpen) => {\n if (!isOpen) handleCancel();\n }}\n title={t('chat.figma-upload.header', 'Import from Figma')}\n onCancel={handleCancel}\n onComplete={handleComplete}\n >\n <StepModal.Step\n title={t('chat.figma-upload.step1-title', 'Enter Figma URL')}\n nextLabel={t('chat.figma-upload.import-button', 'Import')}\n cancelLabel={t('form.button.cancel', 'Cancel')}\n disableNext={!figmaUrl || isLoading || !isValidFigmaUrl(figmaUrl)}\n onNext={handleImportStep}\n >\n <FigmaUrlInputStep figmaUrl={figmaUrl} setFigmaUrl={setFigmaUrl} error={error} />\n </StepModal.Step>\n\n <StepModal.Step\n title={t('chat.figma-upload.step2-title', 'Preview Images')}\n nextLabel={t('form.button.finish', 'Finish')}\n backLabel={t('form.button.back', 'Back')}\n disableNext={selectedImages.length === 0}\n >\n <FigmaImageDisplayStep\n images={figmaImages}\n selectedImages={selectedImages}\n setSelectedImages={setSelectedImages}\n />\n </StepModal.Step>\n </StepModal>\n );\n};\n"],"names":["UploadFigmaContext","createContext","isFigmaUploadOpen","submitOnFinish","openFigmaUpload","closeFigmaUpload","useUploadFigmaToChat","context","useContext","Error","UploadFigmaToChatProvider","children","setIsFigmaUploadOpen","useState","setSubmitOnFinish","submitOnFinishParam","_jsxs","Provider","value","_jsx","UploadFigmaModal","FigmaUrlInputStep","figmaUrl","setFigmaUrl","t","useTranslations","isLoading","useStepModal","showingTokenInput","setShowingTokenInput","hasFigmaToken","figmaToken","setFigmaToken","getFigmaToken","handleSaveToken","trim","saveFigmaToken","Flex","direction","gap","alignItems","Typography","variant","textColor","Link","href","isExternal","Box","width","TextInput","name","placeholder","aria-label","onChange","e","target","disabled","type","Button","onClick","justifyContent","size","FigmaImageDisplayStep","images","selectedImages","setSelectedImages","toggleSelectAll","length","allImageIds","map","img","id","padding","handleFrameSelection","frameId","newSelection","includes","filter","height","paddingRight","style","overflowY","Grid","Root","frame","index","isSelected","Item","col","ImagePreview","imageUrl","url","imageName","filename","selected","onSelect","figmaImages","setFigmaImages","addAttachments","useAttachments","input","setInput","setMessages","sendMessage","openChat","useStrapiChat","processFigmaUrl","error","useFigmaUpload","onSuccess","initialSelection","slice","handleImportStep","isValidFigmaUrl","urlObj","URL","hostname","handleCancel","handleComplete","selectedFigmaImages","role","parts","text","StepModal","open","onOpenChange","isOpen","title","onCancel","onComplete","Step","nextLabel","cancelLabel","disableNext","onNext","backLabel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UploadFigmaModal.mjs","sources":["../../../../admin/src/components/AIChat/UploadFigmaModal.tsx"],"sourcesContent":["import { createContext, useContext, useState } from 'react';\n\nimport { Flex, Typography, Box, TextInput, Grid, Button, Link } from '@strapi/design-system'; // Added Link\n\nimport { ImagePreview } from './components/ImagePreview';\nimport { StepModal, useStepModal } from './components/StepModal';\nimport { useAttachments } from './hooks/useAttachments';\nimport {\n FigmaImage,\n useFigmaUpload,\n getFigmaToken,\n saveFigmaToken,\n hasFigmaToken,\n} from './hooks/useFigmaUpload';\nimport { useTranslations } from './hooks/useTranslations';\nimport { useStrapiChat } from './providers/ChatProvider';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface UploadFigmaContextType {\n isFigmaUploadOpen: boolean;\n submitOnFinish: boolean;\n openFigmaUpload: (submitOnFinish?: boolean) => void;\n closeFigmaUpload: () => void;\n}\n\nconst UploadFigmaContext = createContext<UploadFigmaContextType>({\n isFigmaUploadOpen: false,\n submitOnFinish: false,\n openFigmaUpload: () => {},\n closeFigmaUpload: () => {},\n});\n\nexport const useUploadFigmaToChat = () => {\n const context = useContext(UploadFigmaContext);\n if (!context) {\n throw new Error('useUploadFigmaToChat must be used within an UploadFigmaToChatProvider');\n }\n return context;\n};\n\nexport const UploadFigmaToChatProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFigmaUploadOpen, setIsFigmaUploadOpen] = useState(false); // Default to false\n const [submitOnFinish, setSubmitOnFinish] = useState(false);\n\n const openFigmaUpload = (submitOnFinishParam?: boolean) => {\n setIsFigmaUploadOpen(true);\n setSubmitOnFinish(submitOnFinishParam ?? false);\n };\n\n const closeFigmaUpload = () => setIsFigmaUploadOpen(false);\n\n return (\n <UploadFigmaContext.Provider\n value={{ isFigmaUploadOpen, submitOnFinish, openFigmaUpload, closeFigmaUpload }}\n >\n {isFigmaUploadOpen && <UploadFigmaModal />}\n {children}\n </UploadFigmaContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 1 - Input Figma URL\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaUrlInputStepProps {\n figmaUrl: string;\n setFigmaUrl: (url: string) => void;\n error: string | null; // Error state from useFigmaUpload\n}\n\nconst FigmaUrlInputStep = ({ figmaUrl, setFigmaUrl }: FigmaUrlInputStepProps) => {\n const { t } = useTranslations();\n const { isLoading } = useStepModal();\n const [showingTokenInput, setShowingTokenInput] = useState(!hasFigmaToken());\n const [figmaToken, setFigmaToken] = useState<string>(getFigmaToken);\n\n // Handle saving token and returning to URL input\n const handleSaveToken = () => {\n if (figmaToken.trim()) {\n saveFigmaToken(figmaToken);\n setShowingTokenInput(false);\n }\n };\n\n // If we need to show token step, render the token input\n if (showingTokenInput) {\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.token-title', 'Enter Figma API Token')}\n </Typography>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.token-description',\n 'To access your Figma designs, you need to provide a personal access token. This will be stored securely in your browser.'\n )}\n </Typography>\n <Link\n href=\"https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens\"\n isExternal\n >\n {t('chat.figma-upload.token-help', 'How to get a Figma API token')}\n </Link>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-token\"\n placeholder={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n aria-label={t('chat.figma-upload.token-placeholder', 'Enter Figma API token')}\n value={figmaToken}\n onChange={(e) => setFigmaToken(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"password\"\n />\n </Box>\n\n <Flex gap={2}>\n <Button onClick={handleSaveToken} disabled={!figmaToken.trim()} variant=\"secondary\">\n {t('chat.figma-upload.save-token', 'Save token')}\n </Button>\n <Button\n onClick={() => setShowingTokenInput(false)}\n variant=\"tertiary\"\n disabled={!hasFigmaToken()}\n >\n {t('chat.figma-upload.cancel', 'Cancel')}\n </Button>\n </Flex>\n </Flex>\n );\n }\n\n // Otherwise render the URL input\n return (\n <Flex direction=\"column\" gap={6} alignItems=\"start\">\n <Flex direction=\"column\" gap={2} alignItems=\"start\" width=\"100%\">\n <Flex justifyContent=\"space-between\" alignItems=\"center\" width=\"100%\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.title', 'Import Figma Design')}\n </Typography>\n <Button onClick={() => setShowingTokenInput(true)} variant=\"tertiary\" size=\"S\">\n {t('chat.figma-upload.edit-token', 'Edit API token')}\n </Button>\n </Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\">\n {t(\n 'chat.figma-upload.description',\n 'Ask to turn your designs into schemas by attaching a link to one or multiple frames in your Figma files. (Max 15 frames)'\n )}\n </Typography>\n </Flex>\n\n <Box width=\"100%\">\n <TextInput\n name=\"figma-url\"\n placeholder={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n aria-label={t('chat.figma-upload.url-placeholder', 'Enter Figma URL')}\n value={figmaUrl}\n onChange={(e) => setFigmaUrl(e.target.value)}\n width=\"100%\"\n disabled={isLoading}\n type=\"url\"\n />\n </Box>\n\n {/* {error && (\n <Box padding={3} background=\"danger100\" color=\"danger600\" borderRadius=\"4px\" width=\"100%\">\n <Typography variant=\"pi\">{error}</Typography>\n </Box>\n )} */}\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step 2 - Display Figma Images\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FigmaImageDisplayStepProps {\n images: FigmaImage[];\n selectedImages: string[];\n setSelectedImages: (images: string[]) => void;\n}\n\nconst FigmaImageDisplayStep = ({\n images,\n selectedImages,\n setSelectedImages,\n}: FigmaImageDisplayStepProps) => {\n const { t } = useTranslations();\n\n // Handle select/deselect all\n const toggleSelectAll = () => {\n if (selectedImages.length === images.length) {\n // Deselect all if all or max allowed are selected\n setSelectedImages([]);\n } else {\n // Select all images up to the max limit\n const allImageIds = images.map((img) => img.id);\n setSelectedImages(allImageIds);\n }\n };\n\n if (images.length === 0) {\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"center\" padding={4}>\n <Typography variant=\"omega\">\n {t('chat.figma-upload.no-images', 'No frames found in the Figma file.')}\n </Typography>\n </Flex>\n );\n }\n\n // Handle individual frame selection\n const handleFrameSelection = (frameId: string) => {\n const newSelection = selectedImages.includes(frameId)\n ? selectedImages.filter((id) => id !== frameId)\n : [...selectedImages, frameId];\n\n setSelectedImages(newSelection);\n };\n\n return (\n <Flex direction=\"column\" gap={4} alignItems=\"start\" width=\"100%\" height=\"min(45vh, 400px)\">\n <Flex justifyContent=\"space-between\" width=\"100%\" alignItems=\"center\">\n <Typography variant=\"beta\">\n {t('chat.figma-upload.select-images', 'Select Frames to Import')}\n </Typography>\n <Flex gap={3} alignItems=\"center\">\n <Typography>\n {selectedImages.length} of {images.length} selected\n </Typography>\n <Button onClick={toggleSelectAll} type=\"button\" variant=\"secondary\">\n {/* Determine if select all button should show \"Select All\" or \"Deselect All\" */}\n {selectedImages.length === images.length\n ? t('chat.figma-upload.deselect-all', 'Deselect All')\n : t('chat.figma-upload.select-all', 'Select All')}\n </Button>\n </Flex>\n </Flex>\n\n <Box paddingRight={4} width=\"100%\" style={{ overflowY: 'auto' }}>\n <Grid.Root gap={4}>\n {images.map((frame, index) => {\n const isSelected = selectedImages.includes(frame.id);\n return (\n <Grid.Item key={frame.id} col={6} padding={'1px'}>\n <ImagePreview\n imageUrl={frame.url}\n imageName={frame.filename || `Frame ${index + 1}`}\n selected={isSelected}\n onSelect={() => handleFrameSelection(frame.id)}\n />\n </Grid.Item>\n );\n })}\n </Grid.Root>\n </Box>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\nexport const UploadFigmaModal = () => {\n const [figmaUrl, setFigmaUrl] = useState<string>('');\n const [figmaImages, setFigmaImages] = useState<FigmaImage[]>([]);\n const [selectedImages, setSelectedImages] = useState<string[]>([]);\n const { t } = useTranslations();\n\n const { addAttachments } = useAttachments();\n const { isFigmaUploadOpen, closeFigmaUpload, submitOnFinish } = useUploadFigmaToChat();\n const { input, setInput, setMessages, sendMessage, openChat } = useStrapiChat();\n const { processFigmaUrl, isLoading, error } = useFigmaUpload({\n onSuccess: (images) => {\n setFigmaImages(images);\n // Initialize with first 15 images selected\n const initialSelection = images.slice(0, 15).map((img) => img.id);\n setSelectedImages(initialSelection);\n },\n });\n\n const handleImportStep = async () => {\n await processFigmaUrl(figmaUrl);\n return true;\n };\n\n // Validate if the URL is a valid Figma URL\n const isValidFigmaUrl = (url: string) => {\n if (!url) return false;\n try {\n const urlObj = new URL(url);\n return urlObj.hostname === 'www.figma.com' || urlObj.hostname === 'figma.com';\n } catch (e) {\n return false;\n }\n };\n\n const handleCancel = () => {\n // Reset all state on cancel\n setFigmaUrl('');\n setFigmaImages([]);\n setSelectedImages([]);\n closeFigmaUpload();\n };\n\n const handleComplete = () => {\n // Only attach the selected images\n const selectedFigmaImages = figmaImages.filter((img) => selectedImages.includes(img.id));\n if (selectedFigmaImages.length === 0) {\n closeFigmaUpload();\n return;\n }\n\n // Ensure chat is opened\n openChat();\n\n if (submitOnFinish) {\n // Auto-submit a message to chat with attachments\n sendMessage({\n role: 'user',\n parts: [\n { type: 'text', text: 'Create schemas from the attached images' },\n ...selectedFigmaImages,\n ],\n });\n\n closeFigmaUpload();\n } else {\n // If input is empty, set a predefined message\n if (!input) {\n setInput('Create schemas from the attached images');\n }\n addAttachments(selectedFigmaImages);\n closeFigmaUpload();\n }\n };\n\n return (\n <StepModal\n open={isFigmaUploadOpen}\n onOpenChange={(isOpen) => {\n if (!isOpen) handleCancel();\n }}\n title={t('chat.figma-upload.header', 'Import from Figma')}\n onCancel={handleCancel}\n onComplete={handleComplete}\n >\n <StepModal.Step\n title={t('chat.figma-upload.step1-title', 'Enter Figma URL')}\n nextLabel={t('chat.figma-upload.import-button', 'Import')}\n cancelLabel={t('form.button.cancel', 'Cancel')}\n disableNext={!figmaUrl || isLoading || !isValidFigmaUrl(figmaUrl)}\n onNext={handleImportStep}\n >\n <FigmaUrlInputStep figmaUrl={figmaUrl} setFigmaUrl={setFigmaUrl} error={error} />\n </StepModal.Step>\n\n <StepModal.Step\n title={t('chat.figma-upload.step2-title', 'Preview Images')}\n nextLabel={t('form.button.finish', 'Finish')}\n backLabel={t('form.button.back', 'Back')}\n disableNext={selectedImages.length === 0}\n >\n <FigmaImageDisplayStep\n images={figmaImages}\n selectedImages={selectedImages}\n setSelectedImages={setSelectedImages}\n />\n </StepModal.Step>\n </StepModal>\n );\n};\n"],"names":["UploadFigmaContext","createContext","isFigmaUploadOpen","submitOnFinish","openFigmaUpload","closeFigmaUpload","useUploadFigmaToChat","context","useContext","Error","UploadFigmaToChatProvider","children","setIsFigmaUploadOpen","useState","setSubmitOnFinish","submitOnFinishParam","_jsxs","Provider","value","_jsx","UploadFigmaModal","FigmaUrlInputStep","figmaUrl","setFigmaUrl","t","useTranslations","isLoading","useStepModal","showingTokenInput","setShowingTokenInput","hasFigmaToken","figmaToken","setFigmaToken","getFigmaToken","handleSaveToken","trim","saveFigmaToken","Flex","direction","gap","alignItems","Typography","variant","textColor","Link","href","isExternal","Box","width","TextInput","name","placeholder","aria-label","onChange","e","target","disabled","type","Button","onClick","justifyContent","size","FigmaImageDisplayStep","images","selectedImages","setSelectedImages","toggleSelectAll","length","allImageIds","map","img","id","padding","handleFrameSelection","frameId","newSelection","includes","filter","height","paddingRight","style","overflowY","Grid","Root","frame","index","isSelected","Item","col","ImagePreview","imageUrl","url","imageName","filename","selected","onSelect","figmaImages","setFigmaImages","addAttachments","useAttachments","input","setInput","setMessages","sendMessage","openChat","useStrapiChat","processFigmaUrl","error","useFigmaUpload","onSuccess","initialSelection","slice","handleImportStep","isValidFigmaUrl","urlObj","URL","hostname","handleCancel","handleComplete","selectedFigmaImages","role","parts","text","StepModal","open","onOpenChange","isOpen","title","onCancel","onComplete","Step","nextLabel","cancelLabel","disableNext","onNext","backLabel"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Base64Image.js","sources":["../../../../../admin/src/components/AIChat/components/Base64Image.tsx"],"sourcesContent":["import { useState, useEffect, ImgHTMLAttributes } from 'react';\n\nimport { Flex, Loader } from '@strapi/design-system';\nimport { CrossCircle } from '@strapi/icons';\n\nconst blobToBase64 = (blob: Blob): Promise<string | ArrayBuffer | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n};\n\n// Check if a string is already a data URL (base64 image)\nconst isBase64Image = (src: string): boolean => {\n return src.startsWith('data:image/');\n};\n\ninterface Base64ImgProps extends ImgHTMLAttributes<HTMLImageElement> {\n src: string;\n inferSize?: boolean;\n onLoad?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n onError?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n}\n\nexport const Base64Img: React.FC<Base64ImgProps> = ({\n src,\n alt,\n inferSize = false,\n onLoad: externalOnLoad,\n onError: externalOnError,\n ...rest\n}) => {\n const [base64Src, setBase64Src] = useState<string | null>(null);\n const [dimensions, setDimensions] = useState<{ width?: number; height?: number }>({});\n const [isLoading, setIsLoading] = useState(true);\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n const fetchAndConvert = async () => {\n setIsLoading(true);\n setHasError(false);\n\n // If src is already a base64 string, use it directly\n if (isBase64Image(src)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n\n try {\n // TODO: Find a better way of doing this\n // If url is from strapi-ai-staging.s3.us-east-1.amazonaws.com or strapi-ai-production.s3.us-east-1.amazonaws.com, use it directly\n const url = new URL(src);\n const allowedDomains = [\n 'strapi-ai-staging.s3.us-east-1.amazonaws.com',\n 'strapi-ai-production.s3.us-east-1.amazonaws.com',\n ];\n\n if (allowedDomains.includes(url.hostname)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n } catch (e) {\n // If URL parsing fails, continue with the fetch attempt\n }\n\n try {\n // Only fetch if it's a URL and not already a base64 string\n const response = await fetch(src);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const blob = await response.blob();\n const dataUrl = await blobToBase64(blob);\n setBase64Src(dataUrl as string);\n setIsLoading(false);\n } catch (error) {\n console.error('Error converting image to base64:', error);\n setHasError(true);\n setIsLoading(false);\n }\n };\n\n fetchAndConvert();\n }, [src, externalOnError]);\n\n const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {\n if (inferSize) {\n const { naturalWidth, naturalHeight } = e.currentTarget;\n setDimensions({ width: naturalWidth, height: naturalHeight });\n }\n\n if (externalOnLoad) {\n externalOnLoad(e);\n }\n };\n\n if (isLoading) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <Loader small />\n </Flex>\n );\n }\n\n if (hasError) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <CrossCircle width={24} height={24} fill=\"danger600\" />\n </Flex>\n );\n }\n\n // Build props for the img element\n const imgProps: ImgHTMLAttributes<HTMLImageElement> = {\n src: base64Src || '',\n alt,\n onLoad: handleImageLoad,\n ...rest,\n };\n\n // If inferSize is enabled and width/height weren't explicitly provided,\n // merge the inferred dimensions into the props once available.\n if (inferSize && !rest.width && !rest.height && dimensions.width && dimensions.height) {\n imgProps.width = dimensions.width;\n imgProps.height = dimensions.height;\n }\n\n return base64Src ? <img {...imgProps} /> : null;\n};\n"],"names":["blobToBase64","blob","Promise","resolve","reject","reader","FileReader","onloadend","result","onerror","readAsDataURL","isBase64Image","src","startsWith","Base64Img","alt","inferSize","onLoad","externalOnLoad","onError","externalOnError","rest","base64Src","setBase64Src","useState","dimensions","setDimensions","isLoading","setIsLoading","hasError","setHasError","useEffect","fetchAndConvert","url","URL","allowedDomains","includes","hostname","e","response","fetch","ok","Error","status","dataUrl","error","console","handleImageLoad","naturalWidth","naturalHeight","currentTarget","width","height","_jsx","Flex","direction","gap","alignItems","Loader","small","CrossCircle","fill","imgProps","img"],"mappings":";;;;;;;AAKA,MAAMA,eAAe,CAACC,IAAAA,GAAAA;IACpB,OAAO,IAAIC,OAAQ,CAAA,CAACC,OAASC,EAAAA,MAAAA,GAAAA;AAC3B,QAAA,MAAMC,SAAS,IAAIC,UAAAA,EAAAA;AACnBD,QAAAA,MAAAA,CAAOE,SAAS,GAAG,IAAMJ,OAAAA,CAAQE,OAAOG,MAAM,CAAA;AAC9CH,QAAAA,MAAAA,CAAOI,OAAO,GAAGL,MAAAA;AACjBC,QAAAA,MAAAA,CAAOK,aAAa,CAACT,IAAAA,CAAAA;AACvB,KAAA,CAAA;AACF,CAAA;AAEA;AACA,MAAMU,gBAAgB,CAACC,GAAAA,GAAAA;IACrB,OAAOA,GAAAA,CAAIC,UAAU,CAAC,aAAA,CAAA;AACxB,CAAA;MASaC,SAAsC,GAAA,CAAC,EAClDF,GAAG,EACHG,GAAG,EACHC,SAAAA,GAAY,KAAK,EACjBC,QAAQC,cAAc,EACtBC,SAASC,eAAe,EACxB,GAAGC,IACJ,EAAA,GAAA;AACC,IAAA,MAAM,CAACC,SAAAA,EAAWC,YAAa,CAAA,GAAGC,cAAwB,CAAA,IAAA,CAAA;AAC1D,IAAA,MAAM,CAACC,UAAAA,EAAYC,aAAc,CAAA,GAAGF,eAA8C,EAAC,CAAA;AACnF,IAAA,MAAM,CAACG,SAAAA,EAAWC,YAAa,CAAA,GAAGJ,cAAS,CAAA,IAAA,CAAA;AAC3C,IAAA,MAAM,CAACK,QAAAA,EAAUC,WAAY,CAAA,GAAGN,cAAS,CAAA,KAAA,CAAA;IAEzCO,eAAU,CAAA,IAAA;AACR,QAAA,MAAMC,eAAkB,GAAA,UAAA;YACtBJ,YAAa,CAAA,IAAA,CAAA;YACbE,WAAY,CAAA,KAAA,CAAA;;AAGZ,YAAA,IAAInB,cAAcC,GAAM,CAAA,EAAA;gBACtBW,YAAaX,CAAAA,GAAAA,CAAAA;gBACbgB,YAAa,CAAA,KAAA,CAAA;AACb,gBAAA;AACF;YAEA,IAAI;;;gBAGF,MAAMK,GAAAA,GAAM,IAAIC,GAAItB,CAAAA,GAAAA,CAAAA;AACpB,gBAAA,MAAMuB,cAAiB,GAAA;AACrB,oBAAA,8CAAA;AACA,oBAAA;AACD,iBAAA;AAED,gBAAA,IAAIA,cAAeC,CAAAA,QAAQ,CAACH,GAAAA,CAAII,QAAQ,CAAG,EAAA;oBACzCd,YAAaX,CAAAA,GAAAA,CAAAA;oBACbgB,YAAa,CAAA,KAAA,CAAA;AACb,oBAAA;AACF;AACF,aAAA,CAAE,OAAOU,CAAG,EAAA;;AAEZ;YAEA,IAAI;;gBAEF,MAAMC,QAAAA,GAAW,MAAMC,KAAM5B,CAAAA,GAAAA,CAAAA;gBAC7B,IAAI,CAAC2B,QAASE,CAAAA,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"Base64Image.js","sources":["../../../../../admin/src/components/AIChat/components/Base64Image.tsx"],"sourcesContent":["import { useState, useEffect, ImgHTMLAttributes } from 'react';\n\nimport { Flex, Loader } from '@strapi/design-system';\nimport { CrossCircle } from '@strapi/icons';\n\nconst blobToBase64 = (blob: Blob): Promise<string | ArrayBuffer | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n};\n\n// Check if a string is already a data URL (base64 image)\nconst isBase64Image = (src: string): boolean => {\n return src.startsWith('data:image/');\n};\n\ninterface Base64ImgProps extends ImgHTMLAttributes<HTMLImageElement> {\n src: string;\n inferSize?: boolean;\n onLoad?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n onError?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n}\n\nexport const Base64Img: React.FC<Base64ImgProps> = ({\n src,\n alt,\n inferSize = false,\n onLoad: externalOnLoad,\n onError: externalOnError,\n ...rest\n}) => {\n const [base64Src, setBase64Src] = useState<string | null>(null);\n const [dimensions, setDimensions] = useState<{ width?: number; height?: number }>({});\n const [isLoading, setIsLoading] = useState(true);\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n const fetchAndConvert = async () => {\n setIsLoading(true);\n setHasError(false);\n\n // If src is already a base64 string, use it directly\n if (isBase64Image(src)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n\n try {\n // TODO: Find a better way of doing this\n // If url is from strapi-ai-staging.s3.us-east-1.amazonaws.com or strapi-ai-production.s3.us-east-1.amazonaws.com, use it directly\n const url = new URL(src);\n const allowedDomains = [\n 'strapi-ai-staging.s3.us-east-1.amazonaws.com',\n 'strapi-ai-production.s3.us-east-1.amazonaws.com',\n ];\n\n if (allowedDomains.includes(url.hostname)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n } catch (e) {\n // If URL parsing fails, continue with the fetch attempt\n }\n\n try {\n // Only fetch if it's a URL and not already a base64 string\n const response = await fetch(src);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const blob = await response.blob();\n const dataUrl = await blobToBase64(blob);\n setBase64Src(dataUrl as string);\n setIsLoading(false);\n } catch (error) {\n console.error('Error converting image to base64:', error);\n setHasError(true);\n setIsLoading(false);\n }\n };\n\n fetchAndConvert();\n }, [src, externalOnError]);\n\n const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {\n if (inferSize) {\n const { naturalWidth, naturalHeight } = e.currentTarget;\n setDimensions({ width: naturalWidth, height: naturalHeight });\n }\n\n if (externalOnLoad) {\n externalOnLoad(e);\n }\n };\n\n if (isLoading) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <Loader small />\n </Flex>\n );\n }\n\n if (hasError) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <CrossCircle width={24} height={24} fill=\"danger600\" />\n </Flex>\n );\n }\n\n // Build props for the img element\n const imgProps: ImgHTMLAttributes<HTMLImageElement> = {\n src: base64Src || '',\n alt,\n onLoad: handleImageLoad,\n ...rest,\n };\n\n // If inferSize is enabled and width/height weren't explicitly provided,\n // merge the inferred dimensions into the props once available.\n if (inferSize && !rest.width && !rest.height && dimensions.width && dimensions.height) {\n imgProps.width = dimensions.width;\n imgProps.height = dimensions.height;\n }\n\n return base64Src ? <img {...imgProps} /> : null;\n};\n"],"names":["blobToBase64","blob","Promise","resolve","reject","reader","FileReader","onloadend","result","onerror","readAsDataURL","isBase64Image","src","startsWith","Base64Img","alt","inferSize","onLoad","externalOnLoad","onError","externalOnError","rest","base64Src","setBase64Src","useState","dimensions","setDimensions","isLoading","setIsLoading","hasError","setHasError","useEffect","fetchAndConvert","url","URL","allowedDomains","includes","hostname","e","response","fetch","ok","Error","status","dataUrl","error","console","handleImageLoad","naturalWidth","naturalHeight","currentTarget","width","height","_jsx","Flex","direction","gap","alignItems","Loader","small","CrossCircle","fill","imgProps","img"],"mappings":";;;;;;;AAKA,MAAMA,eAAe,CAACC,IAAAA,GAAAA;IACpB,OAAO,IAAIC,OAAQ,CAAA,CAACC,OAASC,EAAAA,MAAAA,GAAAA;AAC3B,QAAA,MAAMC,SAAS,IAAIC,UAAAA,EAAAA;AACnBD,QAAAA,MAAAA,CAAOE,SAAS,GAAG,IAAMJ,OAAAA,CAAQE,OAAOG,MAAM,CAAA;AAC9CH,QAAAA,MAAAA,CAAOI,OAAO,GAAGL,MAAAA;AACjBC,QAAAA,MAAAA,CAAOK,aAAa,CAACT,IAAAA,CAAAA;AACvB,KAAA,CAAA;AACF,CAAA;AAEA;AACA,MAAMU,gBAAgB,CAACC,GAAAA,GAAAA;IACrB,OAAOA,GAAAA,CAAIC,UAAU,CAAC,aAAA,CAAA;AACxB,CAAA;MASaC,SAAsC,GAAA,CAAC,EAClDF,GAAG,EACHG,GAAG,EACHC,SAAAA,GAAY,KAAK,EACjBC,QAAQC,cAAc,EACtBC,SAASC,eAAe,EACxB,GAAGC,IACJ,EAAA,GAAA;AACC,IAAA,MAAM,CAACC,SAAAA,EAAWC,YAAa,CAAA,GAAGC,cAAwB,CAAA,IAAA,CAAA;AAC1D,IAAA,MAAM,CAACC,UAAAA,EAAYC,aAAc,CAAA,GAAGF,eAA8C,EAAC,CAAA;AACnF,IAAA,MAAM,CAACG,SAAAA,EAAWC,YAAa,CAAA,GAAGJ,cAAS,CAAA,IAAA,CAAA;AAC3C,IAAA,MAAM,CAACK,QAAAA,EAAUC,WAAY,CAAA,GAAGN,cAAS,CAAA,KAAA,CAAA;IAEzCO,eAAU,CAAA,IAAA;AACR,QAAA,MAAMC,eAAkB,GAAA,UAAA;YACtBJ,YAAa,CAAA,IAAA,CAAA;YACbE,WAAY,CAAA,KAAA,CAAA;;AAGZ,YAAA,IAAInB,cAAcC,GAAM,CAAA,EAAA;gBACtBW,YAAaX,CAAAA,GAAAA,CAAAA;gBACbgB,YAAa,CAAA,KAAA,CAAA;AACb,gBAAA;AACF;YAEA,IAAI;;;gBAGF,MAAMK,GAAAA,GAAM,IAAIC,GAAItB,CAAAA,GAAAA,CAAAA;AACpB,gBAAA,MAAMuB,cAAiB,GAAA;AACrB,oBAAA,8CAAA;AACA,oBAAA;AACD,iBAAA;AAED,gBAAA,IAAIA,cAAeC,CAAAA,QAAQ,CAACH,GAAAA,CAAII,QAAQ,CAAG,EAAA;oBACzCd,YAAaX,CAAAA,GAAAA,CAAAA;oBACbgB,YAAa,CAAA,KAAA,CAAA;AACb,oBAAA;AACF;AACF,aAAA,CAAE,OAAOU,CAAG,EAAA;;AAEZ;YAEA,IAAI;;gBAEF,MAAMC,QAAAA,GAAW,MAAMC,KAAM5B,CAAAA,GAAAA,CAAAA;gBAC7B,IAAI,CAAC2B,QAASE,CAAAA,EAAE,EAAE;AAChB,oBAAA,MAAM,IAAIC,KAAM,CAAA,CAAC,oBAAoB,EAAEH,QAAAA,CAASI,MAAM,CAAE,CAAA,CAAA;AAC1D;gBAEA,MAAM1C,IAAAA,GAAO,MAAMsC,QAAAA,CAAStC,IAAI,EAAA;gBAChC,MAAM2C,OAAAA,GAAU,MAAM5C,YAAaC,CAAAA,IAAAA,CAAAA;gBACnCsB,YAAaqB,CAAAA,OAAAA,CAAAA;gBACbhB,YAAa,CAAA,KAAA,CAAA;AACf,aAAA,CAAE,OAAOiB,KAAO,EAAA;gBACdC,OAAQD,CAAAA,KAAK,CAAC,mCAAqCA,EAAAA,KAAAA,CAAAA;gBACnDf,WAAY,CAAA,IAAA,CAAA;gBACZF,YAAa,CAAA,KAAA,CAAA;AACf;AACF,SAAA;AAEAI,QAAAA,eAAAA,EAAAA;KACC,EAAA;AAACpB,QAAAA,GAAAA;AAAKQ,QAAAA;AAAgB,KAAA,CAAA;AAEzB,IAAA,MAAM2B,kBAAkB,CAACT,CAAAA,GAAAA;AACvB,QAAA,IAAItB,SAAW,EAAA;AACb,YAAA,MAAM,EAAEgC,YAAY,EAAEC,aAAa,EAAE,GAAGX,EAAEY,aAAa;YACvDxB,aAAc,CAAA;gBAAEyB,KAAOH,EAAAA,YAAAA;gBAAcI,MAAQH,EAAAA;AAAc,aAAA,CAAA;AAC7D;AAEA,QAAA,IAAI/B,cAAgB,EAAA;YAClBA,cAAeoB,CAAAA,CAAAA,CAAAA;AACjB;AACF,KAAA;AAEA,IAAA,IAAIX,SAAW,EAAA;AACb,QAAA,qBACE0B,cAACC,CAAAA,iBAAAA,EAAAA;YAAKC,SAAU,EAAA,QAAA;YAASC,GAAK,EAAA,CAAA;YAAGC,UAAW,EAAA,QAAA;YAASN,KAAM,EAAA,MAAA;AACzD,YAAA,QAAA,gBAAAE,cAACK,CAAAA,mBAAAA,EAAAA;gBAAOC,KAAK,EAAA;;;AAGnB;AAEA,IAAA,IAAI9B,QAAU,EAAA;AACZ,QAAA,qBACEwB,cAACC,CAAAA,iBAAAA,EAAAA;YAAKC,SAAU,EAAA,QAAA;YAASC,GAAK,EAAA,CAAA;YAAGC,UAAW,EAAA,QAAA;YAASN,KAAM,EAAA,MAAA;AACzD,YAAA,QAAA,gBAAAE,cAACO,CAAAA,iBAAAA,EAAAA;gBAAYT,KAAO,EAAA,EAAA;gBAAIC,MAAQ,EAAA,EAAA;gBAAIS,IAAK,EAAA;;;AAG/C;;AAGA,IAAA,MAAMC,QAAgD,GAAA;AACpDlD,QAAAA,GAAAA,EAAKU,SAAa,IAAA,EAAA;AAClBP,QAAAA,GAAAA;QACAE,MAAQ8B,EAAAA,eAAAA;AACR,QAAA,GAAG1B;AACL,KAAA;;;AAIA,IAAA,IAAIL,SAAa,IAAA,CAACK,IAAK8B,CAAAA,KAAK,IAAI,CAAC9B,IAAAA,CAAK+B,MAAM,IAAI3B,UAAW0B,CAAAA,KAAK,IAAI1B,UAAAA,CAAW2B,MAAM,EAAE;QACrFU,QAASX,CAAAA,KAAK,GAAG1B,UAAAA,CAAW0B,KAAK;QACjCW,QAASV,CAAAA,MAAM,GAAG3B,UAAAA,CAAW2B,MAAM;AACrC;AAEA,IAAA,OAAO9B,0BAAY+B,cAACU,CAAAA,KAAAA,EAAAA;AAAK,QAAA,GAAGD;AAAe,KAAA,CAAA,GAAA,IAAA;AAC7C;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Base64Image.mjs","sources":["../../../../../admin/src/components/AIChat/components/Base64Image.tsx"],"sourcesContent":["import { useState, useEffect, ImgHTMLAttributes } from 'react';\n\nimport { Flex, Loader } from '@strapi/design-system';\nimport { CrossCircle } from '@strapi/icons';\n\nconst blobToBase64 = (blob: Blob): Promise<string | ArrayBuffer | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n};\n\n// Check if a string is already a data URL (base64 image)\nconst isBase64Image = (src: string): boolean => {\n return src.startsWith('data:image/');\n};\n\ninterface Base64ImgProps extends ImgHTMLAttributes<HTMLImageElement> {\n src: string;\n inferSize?: boolean;\n onLoad?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n onError?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n}\n\nexport const Base64Img: React.FC<Base64ImgProps> = ({\n src,\n alt,\n inferSize = false,\n onLoad: externalOnLoad,\n onError: externalOnError,\n ...rest\n}) => {\n const [base64Src, setBase64Src] = useState<string | null>(null);\n const [dimensions, setDimensions] = useState<{ width?: number; height?: number }>({});\n const [isLoading, setIsLoading] = useState(true);\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n const fetchAndConvert = async () => {\n setIsLoading(true);\n setHasError(false);\n\n // If src is already a base64 string, use it directly\n if (isBase64Image(src)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n\n try {\n // TODO: Find a better way of doing this\n // If url is from strapi-ai-staging.s3.us-east-1.amazonaws.com or strapi-ai-production.s3.us-east-1.amazonaws.com, use it directly\n const url = new URL(src);\n const allowedDomains = [\n 'strapi-ai-staging.s3.us-east-1.amazonaws.com',\n 'strapi-ai-production.s3.us-east-1.amazonaws.com',\n ];\n\n if (allowedDomains.includes(url.hostname)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n } catch (e) {\n // If URL parsing fails, continue with the fetch attempt\n }\n\n try {\n // Only fetch if it's a URL and not already a base64 string\n const response = await fetch(src);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const blob = await response.blob();\n const dataUrl = await blobToBase64(blob);\n setBase64Src(dataUrl as string);\n setIsLoading(false);\n } catch (error) {\n console.error('Error converting image to base64:', error);\n setHasError(true);\n setIsLoading(false);\n }\n };\n\n fetchAndConvert();\n }, [src, externalOnError]);\n\n const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {\n if (inferSize) {\n const { naturalWidth, naturalHeight } = e.currentTarget;\n setDimensions({ width: naturalWidth, height: naturalHeight });\n }\n\n if (externalOnLoad) {\n externalOnLoad(e);\n }\n };\n\n if (isLoading) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <Loader small />\n </Flex>\n );\n }\n\n if (hasError) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <CrossCircle width={24} height={24} fill=\"danger600\" />\n </Flex>\n );\n }\n\n // Build props for the img element\n const imgProps: ImgHTMLAttributes<HTMLImageElement> = {\n src: base64Src || '',\n alt,\n onLoad: handleImageLoad,\n ...rest,\n };\n\n // If inferSize is enabled and width/height weren't explicitly provided,\n // merge the inferred dimensions into the props once available.\n if (inferSize && !rest.width && !rest.height && dimensions.width && dimensions.height) {\n imgProps.width = dimensions.width;\n imgProps.height = dimensions.height;\n }\n\n return base64Src ? <img {...imgProps} /> : null;\n};\n"],"names":["blobToBase64","blob","Promise","resolve","reject","reader","FileReader","onloadend","result","onerror","readAsDataURL","isBase64Image","src","startsWith","Base64Img","alt","inferSize","onLoad","externalOnLoad","onError","externalOnError","rest","base64Src","setBase64Src","useState","dimensions","setDimensions","isLoading","setIsLoading","hasError","setHasError","useEffect","fetchAndConvert","url","URL","allowedDomains","includes","hostname","e","response","fetch","ok","Error","status","dataUrl","error","console","handleImageLoad","naturalWidth","naturalHeight","currentTarget","width","height","_jsx","Flex","direction","gap","alignItems","Loader","small","CrossCircle","fill","imgProps","img"],"mappings":";;;;;AAKA,MAAMA,eAAe,CAACC,IAAAA,GAAAA;IACpB,OAAO,IAAIC,OAAQ,CAAA,CAACC,OAASC,EAAAA,MAAAA,GAAAA;AAC3B,QAAA,MAAMC,SAAS,IAAIC,UAAAA,EAAAA;AACnBD,QAAAA,MAAAA,CAAOE,SAAS,GAAG,IAAMJ,OAAAA,CAAQE,OAAOG,MAAM,CAAA;AAC9CH,QAAAA,MAAAA,CAAOI,OAAO,GAAGL,MAAAA;AACjBC,QAAAA,MAAAA,CAAOK,aAAa,CAACT,IAAAA,CAAAA;AACvB,KAAA,CAAA;AACF,CAAA;AAEA;AACA,MAAMU,gBAAgB,CAACC,GAAAA,GAAAA;IACrB,OAAOA,GAAAA,CAAIC,UAAU,CAAC,aAAA,CAAA;AACxB,CAAA;MASaC,SAAsC,GAAA,CAAC,EAClDF,GAAG,EACHG,GAAG,EACHC,SAAAA,GAAY,KAAK,EACjBC,QAAQC,cAAc,EACtBC,SAASC,eAAe,EACxB,GAAGC,IACJ,EAAA,GAAA;AACC,IAAA,MAAM,CAACC,SAAAA,EAAWC,YAAa,CAAA,GAAGC,QAAwB,CAAA,IAAA,CAAA;AAC1D,IAAA,MAAM,CAACC,UAAAA,EAAYC,aAAc,CAAA,GAAGF,SAA8C,EAAC,CAAA;AACnF,IAAA,MAAM,CAACG,SAAAA,EAAWC,YAAa,CAAA,GAAGJ,QAAS,CAAA,IAAA,CAAA;AAC3C,IAAA,MAAM,CAACK,QAAAA,EAAUC,WAAY,CAAA,GAAGN,QAAS,CAAA,KAAA,CAAA;IAEzCO,SAAU,CAAA,IAAA;AACR,QAAA,MAAMC,eAAkB,GAAA,UAAA;YACtBJ,YAAa,CAAA,IAAA,CAAA;YACbE,WAAY,CAAA,KAAA,CAAA;;AAGZ,YAAA,IAAInB,cAAcC,GAAM,CAAA,EAAA;gBACtBW,YAAaX,CAAAA,GAAAA,CAAAA;gBACbgB,YAAa,CAAA,KAAA,CAAA;AACb,gBAAA;AACF;YAEA,IAAI;;;gBAGF,MAAMK,GAAAA,GAAM,IAAIC,GAAItB,CAAAA,GAAAA,CAAAA;AACpB,gBAAA,MAAMuB,cAAiB,GAAA;AACrB,oBAAA,8CAAA;AACA,oBAAA;AACD,iBAAA;AAED,gBAAA,IAAIA,cAAeC,CAAAA,QAAQ,CAACH,GAAAA,CAAII,QAAQ,CAAG,EAAA;oBACzCd,YAAaX,CAAAA,GAAAA,CAAAA;oBACbgB,YAAa,CAAA,KAAA,CAAA;AACb,oBAAA;AACF;AACF,aAAA,CAAE,OAAOU,CAAG,EAAA;;AAEZ;YAEA,IAAI;;gBAEF,MAAMC,QAAAA,GAAW,MAAMC,KAAM5B,CAAAA,GAAAA,CAAAA;gBAC7B,IAAI,CAAC2B,QAASE,CAAAA,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"Base64Image.mjs","sources":["../../../../../admin/src/components/AIChat/components/Base64Image.tsx"],"sourcesContent":["import { useState, useEffect, ImgHTMLAttributes } from 'react';\n\nimport { Flex, Loader } from '@strapi/design-system';\nimport { CrossCircle } from '@strapi/icons';\n\nconst blobToBase64 = (blob: Blob): Promise<string | ArrayBuffer | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n};\n\n// Check if a string is already a data URL (base64 image)\nconst isBase64Image = (src: string): boolean => {\n return src.startsWith('data:image/');\n};\n\ninterface Base64ImgProps extends ImgHTMLAttributes<HTMLImageElement> {\n src: string;\n inferSize?: boolean;\n onLoad?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n onError?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;\n}\n\nexport const Base64Img: React.FC<Base64ImgProps> = ({\n src,\n alt,\n inferSize = false,\n onLoad: externalOnLoad,\n onError: externalOnError,\n ...rest\n}) => {\n const [base64Src, setBase64Src] = useState<string | null>(null);\n const [dimensions, setDimensions] = useState<{ width?: number; height?: number }>({});\n const [isLoading, setIsLoading] = useState(true);\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n const fetchAndConvert = async () => {\n setIsLoading(true);\n setHasError(false);\n\n // If src is already a base64 string, use it directly\n if (isBase64Image(src)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n\n try {\n // TODO: Find a better way of doing this\n // If url is from strapi-ai-staging.s3.us-east-1.amazonaws.com or strapi-ai-production.s3.us-east-1.amazonaws.com, use it directly\n const url = new URL(src);\n const allowedDomains = [\n 'strapi-ai-staging.s3.us-east-1.amazonaws.com',\n 'strapi-ai-production.s3.us-east-1.amazonaws.com',\n ];\n\n if (allowedDomains.includes(url.hostname)) {\n setBase64Src(src);\n setIsLoading(false);\n return;\n }\n } catch (e) {\n // If URL parsing fails, continue with the fetch attempt\n }\n\n try {\n // Only fetch if it's a URL and not already a base64 string\n const response = await fetch(src);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const blob = await response.blob();\n const dataUrl = await blobToBase64(blob);\n setBase64Src(dataUrl as string);\n setIsLoading(false);\n } catch (error) {\n console.error('Error converting image to base64:', error);\n setHasError(true);\n setIsLoading(false);\n }\n };\n\n fetchAndConvert();\n }, [src, externalOnError]);\n\n const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {\n if (inferSize) {\n const { naturalWidth, naturalHeight } = e.currentTarget;\n setDimensions({ width: naturalWidth, height: naturalHeight });\n }\n\n if (externalOnLoad) {\n externalOnLoad(e);\n }\n };\n\n if (isLoading) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <Loader small />\n </Flex>\n );\n }\n\n if (hasError) {\n return (\n <Flex direction=\"column\" gap={2} alignItems=\"center\" width=\"100%\">\n <CrossCircle width={24} height={24} fill=\"danger600\" />\n </Flex>\n );\n }\n\n // Build props for the img element\n const imgProps: ImgHTMLAttributes<HTMLImageElement> = {\n src: base64Src || '',\n alt,\n onLoad: handleImageLoad,\n ...rest,\n };\n\n // If inferSize is enabled and width/height weren't explicitly provided,\n // merge the inferred dimensions into the props once available.\n if (inferSize && !rest.width && !rest.height && dimensions.width && dimensions.height) {\n imgProps.width = dimensions.width;\n imgProps.height = dimensions.height;\n }\n\n return base64Src ? <img {...imgProps} /> : null;\n};\n"],"names":["blobToBase64","blob","Promise","resolve","reject","reader","FileReader","onloadend","result","onerror","readAsDataURL","isBase64Image","src","startsWith","Base64Img","alt","inferSize","onLoad","externalOnLoad","onError","externalOnError","rest","base64Src","setBase64Src","useState","dimensions","setDimensions","isLoading","setIsLoading","hasError","setHasError","useEffect","fetchAndConvert","url","URL","allowedDomains","includes","hostname","e","response","fetch","ok","Error","status","dataUrl","error","console","handleImageLoad","naturalWidth","naturalHeight","currentTarget","width","height","_jsx","Flex","direction","gap","alignItems","Loader","small","CrossCircle","fill","imgProps","img"],"mappings":";;;;;AAKA,MAAMA,eAAe,CAACC,IAAAA,GAAAA;IACpB,OAAO,IAAIC,OAAQ,CAAA,CAACC,OAASC,EAAAA,MAAAA,GAAAA;AAC3B,QAAA,MAAMC,SAAS,IAAIC,UAAAA,EAAAA;AACnBD,QAAAA,MAAAA,CAAOE,SAAS,GAAG,IAAMJ,OAAAA,CAAQE,OAAOG,MAAM,CAAA;AAC9CH,QAAAA,MAAAA,CAAOI,OAAO,GAAGL,MAAAA;AACjBC,QAAAA,MAAAA,CAAOK,aAAa,CAACT,IAAAA,CAAAA;AACvB,KAAA,CAAA;AACF,CAAA;AAEA;AACA,MAAMU,gBAAgB,CAACC,GAAAA,GAAAA;IACrB,OAAOA,GAAAA,CAAIC,UAAU,CAAC,aAAA,CAAA;AACxB,CAAA;MASaC,SAAsC,GAAA,CAAC,EAClDF,GAAG,EACHG,GAAG,EACHC,SAAAA,GAAY,KAAK,EACjBC,QAAQC,cAAc,EACtBC,SAASC,eAAe,EACxB,GAAGC,IACJ,EAAA,GAAA;AACC,IAAA,MAAM,CAACC,SAAAA,EAAWC,YAAa,CAAA,GAAGC,QAAwB,CAAA,IAAA,CAAA;AAC1D,IAAA,MAAM,CAACC,UAAAA,EAAYC,aAAc,CAAA,GAAGF,SAA8C,EAAC,CAAA;AACnF,IAAA,MAAM,CAACG,SAAAA,EAAWC,YAAa,CAAA,GAAGJ,QAAS,CAAA,IAAA,CAAA;AAC3C,IAAA,MAAM,CAACK,QAAAA,EAAUC,WAAY,CAAA,GAAGN,QAAS,CAAA,KAAA,CAAA;IAEzCO,SAAU,CAAA,IAAA;AACR,QAAA,MAAMC,eAAkB,GAAA,UAAA;YACtBJ,YAAa,CAAA,IAAA,CAAA;YACbE,WAAY,CAAA,KAAA,CAAA;;AAGZ,YAAA,IAAInB,cAAcC,GAAM,CAAA,EAAA;gBACtBW,YAAaX,CAAAA,GAAAA,CAAAA;gBACbgB,YAAa,CAAA,KAAA,CAAA;AACb,gBAAA;AACF;YAEA,IAAI;;;gBAGF,MAAMK,GAAAA,GAAM,IAAIC,GAAItB,CAAAA,GAAAA,CAAAA;AACpB,gBAAA,MAAMuB,cAAiB,GAAA;AACrB,oBAAA,8CAAA;AACA,oBAAA;AACD,iBAAA;AAED,gBAAA,IAAIA,cAAeC,CAAAA,QAAQ,CAACH,GAAAA,CAAII,QAAQ,CAAG,EAAA;oBACzCd,YAAaX,CAAAA,GAAAA,CAAAA;oBACbgB,YAAa,CAAA,KAAA,CAAA;AACb,oBAAA;AACF;AACF,aAAA,CAAE,OAAOU,CAAG,EAAA;;AAEZ;YAEA,IAAI;;gBAEF,MAAMC,QAAAA,GAAW,MAAMC,KAAM5B,CAAAA,GAAAA,CAAAA;gBAC7B,IAAI,CAAC2B,QAASE,CAAAA,EAAE,EAAE;AAChB,oBAAA,MAAM,IAAIC,KAAM,CAAA,CAAC,oBAAoB,EAAEH,QAAAA,CAASI,MAAM,CAAE,CAAA,CAAA;AAC1D;gBAEA,MAAM1C,IAAAA,GAAO,MAAMsC,QAAAA,CAAStC,IAAI,EAAA;gBAChC,MAAM2C,OAAAA,GAAU,MAAM5C,YAAaC,CAAAA,IAAAA,CAAAA;gBACnCsB,YAAaqB,CAAAA,OAAAA,CAAAA;gBACbhB,YAAa,CAAA,KAAA,CAAA;AACf,aAAA,CAAE,OAAOiB,KAAO,EAAA;gBACdC,OAAQD,CAAAA,KAAK,CAAC,mCAAqCA,EAAAA,KAAAA,CAAAA;gBACnDf,WAAY,CAAA,IAAA,CAAA;gBACZF,YAAa,CAAA,KAAA,CAAA;AACf;AACF,SAAA;AAEAI,QAAAA,eAAAA,EAAAA;KACC,EAAA;AAACpB,QAAAA,GAAAA;AAAKQ,QAAAA;AAAgB,KAAA,CAAA;AAEzB,IAAA,MAAM2B,kBAAkB,CAACT,CAAAA,GAAAA;AACvB,QAAA,IAAItB,SAAW,EAAA;AACb,YAAA,MAAM,EAAEgC,YAAY,EAAEC,aAAa,EAAE,GAAGX,EAAEY,aAAa;YACvDxB,aAAc,CAAA;gBAAEyB,KAAOH,EAAAA,YAAAA;gBAAcI,MAAQH,EAAAA;AAAc,aAAA,CAAA;AAC7D;AAEA,QAAA,IAAI/B,cAAgB,EAAA;YAClBA,cAAeoB,CAAAA,CAAAA,CAAAA;AACjB;AACF,KAAA;AAEA,IAAA,IAAIX,SAAW,EAAA;AACb,QAAA,qBACE0B,GAACC,CAAAA,IAAAA,EAAAA;YAAKC,SAAU,EAAA,QAAA;YAASC,GAAK,EAAA,CAAA;YAAGC,UAAW,EAAA,QAAA;YAASN,KAAM,EAAA,MAAA;AACzD,YAAA,QAAA,gBAAAE,GAACK,CAAAA,MAAAA,EAAAA;gBAAOC,KAAK,EAAA;;;AAGnB;AAEA,IAAA,IAAI9B,QAAU,EAAA;AACZ,QAAA,qBACEwB,GAACC,CAAAA,IAAAA,EAAAA;YAAKC,SAAU,EAAA,QAAA;YAASC,GAAK,EAAA,CAAA;YAAGC,UAAW,EAAA,QAAA;YAASN,KAAM,EAAA,MAAA;AACzD,YAAA,QAAA,gBAAAE,GAACO,CAAAA,WAAAA,EAAAA;gBAAYT,KAAO,EAAA,EAAA;gBAAIC,MAAQ,EAAA,EAAA;gBAAIS,IAAK,EAAA;;;AAG/C;;AAGA,IAAA,MAAMC,QAAgD,GAAA;AACpDlD,QAAAA,GAAAA,EAAKU,SAAa,IAAA,EAAA;AAClBP,QAAAA,GAAAA;QACAE,MAAQ8B,EAAAA,eAAAA;AACR,QAAA,GAAG1B;AACL,KAAA;;;AAIA,IAAA,IAAIL,SAAa,IAAA,CAACK,IAAK8B,CAAAA,KAAK,IAAI,CAAC9B,IAAAA,CAAK+B,MAAM,IAAI3B,UAAW0B,CAAAA,KAAK,IAAI1B,UAAAA,CAAW2B,MAAM,EAAE;QACrFU,QAASX,CAAAA,KAAK,GAAG1B,UAAAA,CAAW0B,KAAK;QACjCW,QAASV,CAAAA,MAAM,GAAG3B,UAAAA,CAAW2B,MAAM;AACrC;AAEA,IAAA,OAAO9B,0BAAY+B,GAACU,CAAAA,KAAAA,EAAAA;AAAK,QAAA,GAAGD;AAAe,KAAA,CAAA,GAAA,IAAA;AAC7C;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Collapsible.js","sources":["../../../../../admin/src/components/AIChat/components/Collapsible.tsx"],"sourcesContent":["import { useState, createContext, useContext, useRef, useLayoutEffect } from 'react';\n\nimport { Box } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\ninterface CollapsibleContextValue {\n open: boolean;\n toggle: () => void;\n}\n\nconst CollapsibleContext = createContext<CollapsibleContextValue | undefined>(undefined);\n\nexport const useCollapsible = () => {\n const context = useContext(CollapsibleContext);\n if (!context) {\n throw new Error('Collapsible components must be wrapped in <Collapsible />');\n }\n return context;\n};\n\nconst AnimatedContent = styled(Box)`\n overflow: hidden;\n transition: height ${({ theme }) => theme.motion.timings['200']}\n ${({ theme }) => theme.motion.easings.easeOutQuad};\n`;\n\nexport const Collapsible = ({\n children,\n defaultOpen = false,\n}: {\n children: React.ReactNode;\n defaultOpen?: boolean;\n}) => {\n const [open, setOpen] = useState(defaultOpen);\n return (\n <CollapsibleContext.Provider value={{ open, toggle: () => setOpen((prev) => !prev) }}>\n {children}\n </CollapsibleContext.Provider>\n );\n};\n\nexport const CollapsibleTrigger = ({\n children,\n}: {\n children: React.ReactNode | ((props: { open: boolean }) => React.ReactNode);\n}) => {\n const { toggle, open } = useCollapsible();\n return (\n <Box onClick={toggle} style={{ cursor: 'pointer' }}>\n {typeof children === 'function' ? children({ open }) : children}\n </Box>\n );\n};\n\nexport const CollapsibleContent = ({ children }: { children: React.ReactNode }) => {\n const { open } = useCollapsible();\n const contentRef = useRef<HTMLDivElement>(null);\n const [height, setHeight] = useState<number>(0);\n\n useLayoutEffect(() => {\n if (contentRef.current) {\n const contentHeight = contentRef.current.scrollHeight;\n setHeight(contentHeight);\n }\n }, [children]);\n\n return (\n <AnimatedContent\n ref={contentRef}\n role=\"region\"\n aria-hidden={!open}\n style={{\n height: open ? `${height}px` : 0,\n visibility: height === 0 ? 'hidden' : 'visible',\n }}\n >\n {children}\n </AnimatedContent>\n );\n};\n"],"names":["CollapsibleContext","createContext","undefined","useCollapsible","context","useContext","Error","AnimatedContent","styled","Box","theme","motion","timings","easings","easeOutQuad","Collapsible","children","defaultOpen","open","setOpen","useState","_jsx","Provider","value","toggle","prev","CollapsibleTrigger","onClick","style","cursor","CollapsibleContent","contentRef","useRef","height","setHeight","useLayoutEffect","current","contentHeight","scrollHeight","ref","role","aria-hidden","visibility"],"mappings":";;;;;;;AAUA,MAAMA,mCAAqBC,mBAAmDC,CAAAA,SAAAA,CAAAA;MAEjEC,cAAiB,GAAA,IAAA;AAC5B,IAAA,MAAMC,UAAUC,gBAAWL,CAAAA,kBAAAA,CAAAA;AAC3B,IAAA,IAAI,CAACI,OAAS,EAAA;AACZ,QAAA,MAAM,IAAIE,KAAM,CAAA,2DAAA,CAAA;AAClB;IACA,OAAOF,OAAAA;AACT;AAEA,MAAMG,eAAAA,GAAkBC,uBAAOC,CAAAA,gBAAAA,CAAI;;qBAEd,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAACC,OAAO,CAAC,KAAA,CAAM;IAC7D,EAAE,CAAC,EAAEF,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAACE,OAAO,CAACC,WAAW,CAAC;AACtD,CAAC;AAEM,MAAMC,cAAc,CAAC,EAC1BC,QAAQ,EACRC,WAAAA,GAAc,KAAK,EAIpB,GAAA;AACC,IAAA,MAAM,CAACC,IAAAA,EAAMC,OAAQ,CAAA,GAAGC,cAASH,CAAAA,WAAAA,CAAAA;IACjC,qBACEI,cAAA,CAACrB,mBAAmBsB,QAAQ,EAAA;QAACC,KAAO,EAAA;AAAEL,YAAAA,IAAAA;AAAMM,YAAAA,MAAAA,EAAQ,IAAML,OAAAA,CAAQ,CAACM,IAAAA,GAAS,CAACA,IAAAA;AAAM,SAAA;AAChFT,QAAAA,QAAAA,EAAAA;;AAGP;AAEaU,MAAAA,kBAAAA,GAAqB,CAAC,EACjCV,QAAQ,EAGT,GAAA;AACC,IAAA,MAAM,EAAEQ,MAAM,EAAEN,IAAI,EAAE,GAAGf,cAAAA,EAAAA;AACzB,IAAA,qBACEkB,cAACZ,CAAAA,gBAAAA,EAAAA;QAAIkB,OAASH,EAAAA,MAAAA;QAAQI,KAAO,EAAA;YAAEC,MAAQ,EAAA;AAAU,SAAA;kBAC9C,OAAOb,QAAAA,KAAa,aAAaA,QAAS,CAAA;AAAEE,YAAAA;SAAUF,CAAAA,GAAAA;;AAG7D;AAEac,MAAAA,kBAAAA,GAAqB,CAAC,EAAEd,QAAQ,EAAiC,GAAA;IAC5E,MAAM,EAAEE,IAAI,EAAE,GAAGf,cAAAA,EAAAA;AACjB,IAAA,MAAM4B,aAAaC,YAAuB,CAAA,IAAA,CAAA;AAC1C,IAAA,MAAM,CAACC,MAAAA,EAAQC,SAAU,CAAA,GAAGd,cAAiB,CAAA,CAAA,CAAA;IAE7Ce,qBAAgB,CAAA,IAAA;QACd,IAAIJ,UAAAA,CAAWK,OAAO,EAAE;AACtB,YAAA,MAAMC,aAAgBN,GAAAA,UAAAA,CAAWK,OAAO,CAACE,YAAY;YACrDJ,SAAUG,CAAAA,aAAAA,CAAAA;AACZ;KACC,EAAA;AAACrB,QAAAA;AAAS,KAAA,CAAA;AAEb,IAAA,qBACEK,cAACd,CAAAA,eAAAA,EAAAA;QACCgC,GAAKR,EAAAA,UAAAA;QACLS,IAAK,EAAA,QAAA;AACLC,QAAAA,aAAAA,EAAa,CAACvB,IAAAA;QACdU,KAAO,EAAA;AACLK,YAAAA,MAAAA,EAAQf,
|
|
1
|
+
{"version":3,"file":"Collapsible.js","sources":["../../../../../admin/src/components/AIChat/components/Collapsible.tsx"],"sourcesContent":["import { useState, createContext, useContext, useRef, useLayoutEffect } from 'react';\n\nimport { Box } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\ninterface CollapsibleContextValue {\n open: boolean;\n toggle: () => void;\n}\n\nconst CollapsibleContext = createContext<CollapsibleContextValue | undefined>(undefined);\n\nexport const useCollapsible = () => {\n const context = useContext(CollapsibleContext);\n if (!context) {\n throw new Error('Collapsible components must be wrapped in <Collapsible />');\n }\n return context;\n};\n\nconst AnimatedContent = styled(Box)`\n overflow: hidden;\n transition: height ${({ theme }) => theme.motion.timings['200']}\n ${({ theme }) => theme.motion.easings.easeOutQuad};\n`;\n\nexport const Collapsible = ({\n children,\n defaultOpen = false,\n}: {\n children: React.ReactNode;\n defaultOpen?: boolean;\n}) => {\n const [open, setOpen] = useState(defaultOpen);\n return (\n <CollapsibleContext.Provider value={{ open, toggle: () => setOpen((prev) => !prev) }}>\n {children}\n </CollapsibleContext.Provider>\n );\n};\n\nexport const CollapsibleTrigger = ({\n children,\n}: {\n children: React.ReactNode | ((props: { open: boolean }) => React.ReactNode);\n}) => {\n const { toggle, open } = useCollapsible();\n return (\n <Box onClick={toggle} style={{ cursor: 'pointer' }}>\n {typeof children === 'function' ? children({ open }) : children}\n </Box>\n );\n};\n\nexport const CollapsibleContent = ({ children }: { children: React.ReactNode }) => {\n const { open } = useCollapsible();\n const contentRef = useRef<HTMLDivElement>(null);\n const [height, setHeight] = useState<number>(0);\n\n useLayoutEffect(() => {\n if (contentRef.current) {\n const contentHeight = contentRef.current.scrollHeight;\n setHeight(contentHeight);\n }\n }, [children]);\n\n return (\n <AnimatedContent\n ref={contentRef}\n role=\"region\"\n aria-hidden={!open}\n style={{\n height: open ? `${height}px` : 0,\n visibility: height === 0 ? 'hidden' : 'visible',\n }}\n >\n {children}\n </AnimatedContent>\n );\n};\n"],"names":["CollapsibleContext","createContext","undefined","useCollapsible","context","useContext","Error","AnimatedContent","styled","Box","theme","motion","timings","easings","easeOutQuad","Collapsible","children","defaultOpen","open","setOpen","useState","_jsx","Provider","value","toggle","prev","CollapsibleTrigger","onClick","style","cursor","CollapsibleContent","contentRef","useRef","height","setHeight","useLayoutEffect","current","contentHeight","scrollHeight","ref","role","aria-hidden","visibility"],"mappings":";;;;;;;AAUA,MAAMA,mCAAqBC,mBAAmDC,CAAAA,SAAAA,CAAAA;MAEjEC,cAAiB,GAAA,IAAA;AAC5B,IAAA,MAAMC,UAAUC,gBAAWL,CAAAA,kBAAAA,CAAAA;AAC3B,IAAA,IAAI,CAACI,OAAS,EAAA;AACZ,QAAA,MAAM,IAAIE,KAAM,CAAA,2DAAA,CAAA;AAClB;IACA,OAAOF,OAAAA;AACT;AAEA,MAAMG,eAAAA,GAAkBC,uBAAOC,CAAAA,gBAAAA,CAAI;;qBAEd,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAACC,OAAO,CAAC,KAAA,CAAM;IAC7D,EAAE,CAAC,EAAEF,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAACE,OAAO,CAACC,WAAW,CAAC;AACtD,CAAC;AAEM,MAAMC,cAAc,CAAC,EAC1BC,QAAQ,EACRC,WAAAA,GAAc,KAAK,EAIpB,GAAA;AACC,IAAA,MAAM,CAACC,IAAAA,EAAMC,OAAQ,CAAA,GAAGC,cAASH,CAAAA,WAAAA,CAAAA;IACjC,qBACEI,cAAA,CAACrB,mBAAmBsB,QAAQ,EAAA;QAACC,KAAO,EAAA;AAAEL,YAAAA,IAAAA;AAAMM,YAAAA,MAAAA,EAAQ,IAAML,OAAAA,CAAQ,CAACM,IAAAA,GAAS,CAACA,IAAAA;AAAM,SAAA;AAChFT,QAAAA,QAAAA,EAAAA;;AAGP;AAEaU,MAAAA,kBAAAA,GAAqB,CAAC,EACjCV,QAAQ,EAGT,GAAA;AACC,IAAA,MAAM,EAAEQ,MAAM,EAAEN,IAAI,EAAE,GAAGf,cAAAA,EAAAA;AACzB,IAAA,qBACEkB,cAACZ,CAAAA,gBAAAA,EAAAA;QAAIkB,OAASH,EAAAA,MAAAA;QAAQI,KAAO,EAAA;YAAEC,MAAQ,EAAA;AAAU,SAAA;kBAC9C,OAAOb,QAAAA,KAAa,aAAaA,QAAS,CAAA;AAAEE,YAAAA;SAAUF,CAAAA,GAAAA;;AAG7D;AAEac,MAAAA,kBAAAA,GAAqB,CAAC,EAAEd,QAAQ,EAAiC,GAAA;IAC5E,MAAM,EAAEE,IAAI,EAAE,GAAGf,cAAAA,EAAAA;AACjB,IAAA,MAAM4B,aAAaC,YAAuB,CAAA,IAAA,CAAA;AAC1C,IAAA,MAAM,CAACC,MAAAA,EAAQC,SAAU,CAAA,GAAGd,cAAiB,CAAA,CAAA,CAAA;IAE7Ce,qBAAgB,CAAA,IAAA;QACd,IAAIJ,UAAAA,CAAWK,OAAO,EAAE;AACtB,YAAA,MAAMC,aAAgBN,GAAAA,UAAAA,CAAWK,OAAO,CAACE,YAAY;YACrDJ,SAAUG,CAAAA,aAAAA,CAAAA;AACZ;KACC,EAAA;AAACrB,QAAAA;AAAS,KAAA,CAAA;AAEb,IAAA,qBACEK,cAACd,CAAAA,eAAAA,EAAAA;QACCgC,GAAKR,EAAAA,UAAAA;QACLS,IAAK,EAAA,QAAA;AACLC,QAAAA,aAAAA,EAAa,CAACvB,IAAAA;QACdU,KAAO,EAAA;AACLK,YAAAA,MAAAA,EAAQf,IAAO,GAAA,CAAA,EAAGe,MAAO,CAAA,EAAE,CAAC,GAAG,CAAA;YAC/BS,UAAYT,EAAAA,MAAAA,KAAW,IAAI,QAAW,GAAA;AACxC,SAAA;AAECjB,QAAAA,QAAAA,EAAAA;;AAGP;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Collapsible.mjs","sources":["../../../../../admin/src/components/AIChat/components/Collapsible.tsx"],"sourcesContent":["import { useState, createContext, useContext, useRef, useLayoutEffect } from 'react';\n\nimport { Box } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\ninterface CollapsibleContextValue {\n open: boolean;\n toggle: () => void;\n}\n\nconst CollapsibleContext = createContext<CollapsibleContextValue | undefined>(undefined);\n\nexport const useCollapsible = () => {\n const context = useContext(CollapsibleContext);\n if (!context) {\n throw new Error('Collapsible components must be wrapped in <Collapsible />');\n }\n return context;\n};\n\nconst AnimatedContent = styled(Box)`\n overflow: hidden;\n transition: height ${({ theme }) => theme.motion.timings['200']}\n ${({ theme }) => theme.motion.easings.easeOutQuad};\n`;\n\nexport const Collapsible = ({\n children,\n defaultOpen = false,\n}: {\n children: React.ReactNode;\n defaultOpen?: boolean;\n}) => {\n const [open, setOpen] = useState(defaultOpen);\n return (\n <CollapsibleContext.Provider value={{ open, toggle: () => setOpen((prev) => !prev) }}>\n {children}\n </CollapsibleContext.Provider>\n );\n};\n\nexport const CollapsibleTrigger = ({\n children,\n}: {\n children: React.ReactNode | ((props: { open: boolean }) => React.ReactNode);\n}) => {\n const { toggle, open } = useCollapsible();\n return (\n <Box onClick={toggle} style={{ cursor: 'pointer' }}>\n {typeof children === 'function' ? children({ open }) : children}\n </Box>\n );\n};\n\nexport const CollapsibleContent = ({ children }: { children: React.ReactNode }) => {\n const { open } = useCollapsible();\n const contentRef = useRef<HTMLDivElement>(null);\n const [height, setHeight] = useState<number>(0);\n\n useLayoutEffect(() => {\n if (contentRef.current) {\n const contentHeight = contentRef.current.scrollHeight;\n setHeight(contentHeight);\n }\n }, [children]);\n\n return (\n <AnimatedContent\n ref={contentRef}\n role=\"region\"\n aria-hidden={!open}\n style={{\n height: open ? `${height}px` : 0,\n visibility: height === 0 ? 'hidden' : 'visible',\n }}\n >\n {children}\n </AnimatedContent>\n );\n};\n"],"names":["CollapsibleContext","createContext","undefined","useCollapsible","context","useContext","Error","AnimatedContent","styled","Box","theme","motion","timings","easings","easeOutQuad","Collapsible","children","defaultOpen","open","setOpen","useState","_jsx","Provider","value","toggle","prev","CollapsibleTrigger","onClick","style","cursor","CollapsibleContent","contentRef","useRef","height","setHeight","useLayoutEffect","current","contentHeight","scrollHeight","ref","role","aria-hidden","visibility"],"mappings":";;;;;AAUA,MAAMA,mCAAqBC,aAAmDC,CAAAA,SAAAA,CAAAA;MAEjEC,cAAiB,GAAA,IAAA;AAC5B,IAAA,MAAMC,UAAUC,UAAWL,CAAAA,kBAAAA,CAAAA;AAC3B,IAAA,IAAI,CAACI,OAAS,EAAA;AACZ,QAAA,MAAM,IAAIE,KAAM,CAAA,2DAAA,CAAA;AAClB;IACA,OAAOF,OAAAA;AACT;AAEA,MAAMG,eAAAA,GAAkBC,MAAOC,CAAAA,GAAAA,CAAI;;qBAEd,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAACC,OAAO,CAAC,KAAA,CAAM;IAC7D,EAAE,CAAC,EAAEF,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAACE,OAAO,CAACC,WAAW,CAAC;AACtD,CAAC;AAEM,MAAMC,cAAc,CAAC,EAC1BC,QAAQ,EACRC,WAAAA,GAAc,KAAK,EAIpB,GAAA;AACC,IAAA,MAAM,CAACC,IAAAA,EAAMC,OAAQ,CAAA,GAAGC,QAASH,CAAAA,WAAAA,CAAAA;IACjC,qBACEI,GAAA,CAACrB,mBAAmBsB,QAAQ,EAAA;QAACC,KAAO,EAAA;AAAEL,YAAAA,IAAAA;AAAMM,YAAAA,MAAAA,EAAQ,IAAML,OAAAA,CAAQ,CAACM,IAAAA,GAAS,CAACA,IAAAA;AAAM,SAAA;AAChFT,QAAAA,QAAAA,EAAAA;;AAGP;AAEaU,MAAAA,kBAAAA,GAAqB,CAAC,EACjCV,QAAQ,EAGT,GAAA;AACC,IAAA,MAAM,EAAEQ,MAAM,EAAEN,IAAI,EAAE,GAAGf,cAAAA,EAAAA;AACzB,IAAA,qBACEkB,GAACZ,CAAAA,GAAAA,EAAAA;QAAIkB,OAASH,EAAAA,MAAAA;QAAQI,KAAO,EAAA;YAAEC,MAAQ,EAAA;AAAU,SAAA;kBAC9C,OAAOb,QAAAA,KAAa,aAAaA,QAAS,CAAA;AAAEE,YAAAA;SAAUF,CAAAA,GAAAA;;AAG7D;AAEac,MAAAA,kBAAAA,GAAqB,CAAC,EAAEd,QAAQ,EAAiC,GAAA;IAC5E,MAAM,EAAEE,IAAI,EAAE,GAAGf,cAAAA,EAAAA;AACjB,IAAA,MAAM4B,aAAaC,MAAuB,CAAA,IAAA,CAAA;AAC1C,IAAA,MAAM,CAACC,MAAAA,EAAQC,SAAU,CAAA,GAAGd,QAAiB,CAAA,CAAA,CAAA;IAE7Ce,eAAgB,CAAA,IAAA;QACd,IAAIJ,UAAAA,CAAWK,OAAO,EAAE;AACtB,YAAA,MAAMC,aAAgBN,GAAAA,UAAAA,CAAWK,OAAO,CAACE,YAAY;YACrDJ,SAAUG,CAAAA,aAAAA,CAAAA;AACZ;KACC,EAAA;AAACrB,QAAAA;AAAS,KAAA,CAAA;AAEb,IAAA,qBACEK,GAACd,CAAAA,eAAAA,EAAAA;QACCgC,GAAKR,EAAAA,UAAAA;QACLS,IAAK,EAAA,QAAA;AACLC,QAAAA,aAAAA,EAAa,CAACvB,IAAAA;QACdU,KAAO,EAAA;AACLK,YAAAA,MAAAA,EAAQf,
|
|
1
|
+
{"version":3,"file":"Collapsible.mjs","sources":["../../../../../admin/src/components/AIChat/components/Collapsible.tsx"],"sourcesContent":["import { useState, createContext, useContext, useRef, useLayoutEffect } from 'react';\n\nimport { Box } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\ninterface CollapsibleContextValue {\n open: boolean;\n toggle: () => void;\n}\n\nconst CollapsibleContext = createContext<CollapsibleContextValue | undefined>(undefined);\n\nexport const useCollapsible = () => {\n const context = useContext(CollapsibleContext);\n if (!context) {\n throw new Error('Collapsible components must be wrapped in <Collapsible />');\n }\n return context;\n};\n\nconst AnimatedContent = styled(Box)`\n overflow: hidden;\n transition: height ${({ theme }) => theme.motion.timings['200']}\n ${({ theme }) => theme.motion.easings.easeOutQuad};\n`;\n\nexport const Collapsible = ({\n children,\n defaultOpen = false,\n}: {\n children: React.ReactNode;\n defaultOpen?: boolean;\n}) => {\n const [open, setOpen] = useState(defaultOpen);\n return (\n <CollapsibleContext.Provider value={{ open, toggle: () => setOpen((prev) => !prev) }}>\n {children}\n </CollapsibleContext.Provider>\n );\n};\n\nexport const CollapsibleTrigger = ({\n children,\n}: {\n children: React.ReactNode | ((props: { open: boolean }) => React.ReactNode);\n}) => {\n const { toggle, open } = useCollapsible();\n return (\n <Box onClick={toggle} style={{ cursor: 'pointer' }}>\n {typeof children === 'function' ? children({ open }) : children}\n </Box>\n );\n};\n\nexport const CollapsibleContent = ({ children }: { children: React.ReactNode }) => {\n const { open } = useCollapsible();\n const contentRef = useRef<HTMLDivElement>(null);\n const [height, setHeight] = useState<number>(0);\n\n useLayoutEffect(() => {\n if (contentRef.current) {\n const contentHeight = contentRef.current.scrollHeight;\n setHeight(contentHeight);\n }\n }, [children]);\n\n return (\n <AnimatedContent\n ref={contentRef}\n role=\"region\"\n aria-hidden={!open}\n style={{\n height: open ? `${height}px` : 0,\n visibility: height === 0 ? 'hidden' : 'visible',\n }}\n >\n {children}\n </AnimatedContent>\n );\n};\n"],"names":["CollapsibleContext","createContext","undefined","useCollapsible","context","useContext","Error","AnimatedContent","styled","Box","theme","motion","timings","easings","easeOutQuad","Collapsible","children","defaultOpen","open","setOpen","useState","_jsx","Provider","value","toggle","prev","CollapsibleTrigger","onClick","style","cursor","CollapsibleContent","contentRef","useRef","height","setHeight","useLayoutEffect","current","contentHeight","scrollHeight","ref","role","aria-hidden","visibility"],"mappings":";;;;;AAUA,MAAMA,mCAAqBC,aAAmDC,CAAAA,SAAAA,CAAAA;MAEjEC,cAAiB,GAAA,IAAA;AAC5B,IAAA,MAAMC,UAAUC,UAAWL,CAAAA,kBAAAA,CAAAA;AAC3B,IAAA,IAAI,CAACI,OAAS,EAAA;AACZ,QAAA,MAAM,IAAIE,KAAM,CAAA,2DAAA,CAAA;AAClB;IACA,OAAOF,OAAAA;AACT;AAEA,MAAMG,eAAAA,GAAkBC,MAAOC,CAAAA,GAAAA,CAAI;;qBAEd,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAACC,OAAO,CAAC,KAAA,CAAM;IAC7D,EAAE,CAAC,EAAEF,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAACE,OAAO,CAACC,WAAW,CAAC;AACtD,CAAC;AAEM,MAAMC,cAAc,CAAC,EAC1BC,QAAQ,EACRC,WAAAA,GAAc,KAAK,EAIpB,GAAA;AACC,IAAA,MAAM,CAACC,IAAAA,EAAMC,OAAQ,CAAA,GAAGC,QAASH,CAAAA,WAAAA,CAAAA;IACjC,qBACEI,GAAA,CAACrB,mBAAmBsB,QAAQ,EAAA;QAACC,KAAO,EAAA;AAAEL,YAAAA,IAAAA;AAAMM,YAAAA,MAAAA,EAAQ,IAAML,OAAAA,CAAQ,CAACM,IAAAA,GAAS,CAACA,IAAAA;AAAM,SAAA;AAChFT,QAAAA,QAAAA,EAAAA;;AAGP;AAEaU,MAAAA,kBAAAA,GAAqB,CAAC,EACjCV,QAAQ,EAGT,GAAA;AACC,IAAA,MAAM,EAAEQ,MAAM,EAAEN,IAAI,EAAE,GAAGf,cAAAA,EAAAA;AACzB,IAAA,qBACEkB,GAACZ,CAAAA,GAAAA,EAAAA;QAAIkB,OAASH,EAAAA,MAAAA;QAAQI,KAAO,EAAA;YAAEC,MAAQ,EAAA;AAAU,SAAA;kBAC9C,OAAOb,QAAAA,KAAa,aAAaA,QAAS,CAAA;AAAEE,YAAAA;SAAUF,CAAAA,GAAAA;;AAG7D;AAEac,MAAAA,kBAAAA,GAAqB,CAAC,EAAEd,QAAQ,EAAiC,GAAA;IAC5E,MAAM,EAAEE,IAAI,EAAE,GAAGf,cAAAA,EAAAA;AACjB,IAAA,MAAM4B,aAAaC,MAAuB,CAAA,IAAA,CAAA;AAC1C,IAAA,MAAM,CAACC,MAAAA,EAAQC,SAAU,CAAA,GAAGd,QAAiB,CAAA,CAAA,CAAA;IAE7Ce,eAAgB,CAAA,IAAA;QACd,IAAIJ,UAAAA,CAAWK,OAAO,EAAE;AACtB,YAAA,MAAMC,aAAgBN,GAAAA,UAAAA,CAAWK,OAAO,CAACE,YAAY;YACrDJ,SAAUG,CAAAA,aAAAA,CAAAA;AACZ;KACC,EAAA;AAACrB,QAAAA;AAAS,KAAA,CAAA;AAEb,IAAA,qBACEK,GAACd,CAAAA,eAAAA,EAAAA;QACCgC,GAAKR,EAAAA,UAAAA;QACLS,IAAK,EAAA,QAAA;AACLC,QAAAA,aAAAA,EAAa,CAACvB,IAAAA;QACdU,KAAO,EAAA;AACLK,YAAAA,MAAAA,EAAQf,IAAO,GAAA,CAAA,EAAGe,MAAO,CAAA,EAAE,CAAC,GAAG,CAAA;YAC/BS,UAAYT,EAAAA,MAAAA,KAAW,IAAI,QAAW,GAAA;AACxC,SAAA;AAECjB,QAAAA,QAAAA,EAAAA;;AAGP;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FullScreenImage.js","sources":["../../../../../admin/src/components/AIChat/components/FullScreenImage.tsx"],"sourcesContent":["import { useEffect, useRef, createContext, useContext, useState, ReactNode } from 'react';\n\nimport { createPortal } from 'react-dom';\nimport { styled } from 'styled-components';\n\nimport { ANIMATIONS } from './animations';\nimport { Base64Img } from './Base64Image';\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FullScreenImageContextType {\n isOpen: boolean;\n open: () => void;\n close: () => void;\n src: string;\n alt: string;\n}\n\nconst FullScreenImageContext = createContext<FullScreenImageContextType | undefined>(undefined);\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FullScreenImageProps {\n src: string;\n alt: string;\n onClose?: () => void;\n}\n\ninterface FullScreenImageRootProps extends FullScreenImageProps {\n children: ReactNode;\n defaultOpen?: boolean;\n}\n\ninterface FullScreenImageTriggerProps {\n children: ReactNode;\n asChild?: boolean;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nexport const setOpacity = (hex: string, alpha: number) =>\n `${hex}${Math.floor(alpha * 255)\n .toString(16)\n .padStart(2, '0')}`;\n\nconst Overlay = styled.div`\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 500;\n pointer-events: auto; /* Explicitly enable pointer events */\n background: ${(props) => setOpacity(props.theme.colors.neutral800, 0.2)};\n`;\n\nconst ImageWrapper = styled.div`\n max-width: 80vw;\n max-height: 90vh;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: auto; /* Explicitly enable pointer events */\n position: relative;\n animation: ${ANIMATIONS.scaleIn} 0.3s ease;\n`;\n\nconst StyledImg = styled(Base64Img)`\n max-width: 100%;\n max-height: 90vh;\n object-fit: contain;\n pointer-events: auto; /* Explicitly enable pointer events */\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\n\n// Use the existing FullScreenImage as our modal component\nconst ImageModal = ({ src, alt, onClose }: FullScreenImageProps) => {\n const overlayRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n // Close on ESC key press\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n // Stop propagation to prevent closing parent modals\n e.preventDefault();\n e.stopPropagation();\n onClose?.();\n\n // The next 3 lines are critical: they completely stop the event\n e.stopImmediatePropagation();\n e.cancelBubble = true; // For older browsers\n return false;\n }\n };\n\n // Use capture phase to intercept event before it reaches other components\n window.addEventListener('keydown', handleKeyDown, true);\n return () => window.removeEventListener('keydown', handleKeyDown, true);\n }, [onClose]);\n\n // Setup click handlers\n useEffect(() => {\n const handleOverlayClick = (e: MouseEvent) => {\n // Only close if clicking directly on the overlay (not its children)\n if (e.target === overlayRef.current) {\n e.preventDefault();\n e.stopPropagation();\n onClose?.();\n }\n };\n\n const handleWrapperClick = (e: MouseEvent) => {\n // Stop propagation for clicks on the image wrapper\n e.stopPropagation();\n };\n\n const overlay = overlayRef.current;\n const wrapper = wrapperRef.current;\n\n if (overlay) {\n overlay.addEventListener('click', handleOverlayClick);\n }\n\n if (wrapper) {\n wrapper.addEventListener('click', handleWrapperClick);\n }\n\n return () => {\n if (overlay) {\n overlay.removeEventListener('click', handleOverlayClick);\n }\n\n if (wrapper) {\n wrapper.removeEventListener('click', handleWrapperClick);\n }\n };\n }, [onClose]);\n\n // Using createPortal to render directly at document body level\n return createPortal(\n <Overlay ref={overlayRef}>\n <ImageWrapper ref={wrapperRef}>\n <StyledImg src={src} alt={alt} />\n </ImageWrapper>\n </Overlay>,\n document.body\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\n// Root component that provides context\nconst Root = ({ children, src, alt, onClose, defaultOpen = false }: FullScreenImageRootProps) => {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n\n const open = () => setIsOpen(true);\n const close = () => {\n setIsOpen(false);\n onClose?.();\n };\n\n return (\n <FullScreenImageContext.Provider value={{ isOpen, open, close, src, alt }}>\n {children}\n {isOpen && <ImageModal src={src} alt={alt} onClose={close} />}\n </FullScreenImageContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\n// Hook to use the context\nconst useFullScreenImage = () => {\n const context = useContext(FullScreenImageContext);\n if (!context) {\n throw new Error('useFullScreenImage must be used within a FullScreenImage.Root');\n }\n return context;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Trigger\n * -----------------------------------------------------------------------------------------------*/\n\n// Trigger component that opens the full screen image\nconst Trigger = ({ children, asChild = false }: FullScreenImageTriggerProps) => {\n const { open } = useFullScreenImage();\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n open();\n };\n\n if (asChild) {\n return (\n <div onClick={handleClick} style={{ cursor: 'pointer', display: 'contents' }}>\n {children}\n </div>\n );\n }\n\n return (\n <div onClick={handleClick} style={{ cursor: 'pointer' }}>\n {children}\n </div>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Export\n * -----------------------------------------------------------------------------------------------*/\n\nexport const FullScreenImage = {\n Root,\n Trigger,\n};\n"],"names":["FullScreenImageContext","createContext","undefined","setOpacity","hex","alpha","Math","floor","toString","padStart","Overlay","styled","div","props","theme","colors","neutral800","ImageWrapper","ANIMATIONS","scaleIn","StyledImg","Base64Img","ImageModal","src","alt","onClose","overlayRef","useRef","wrapperRef","useEffect","handleKeyDown","e","key","preventDefault","stopPropagation","stopImmediatePropagation","cancelBubble","window","addEventListener","removeEventListener","handleOverlayClick","target","current","handleWrapperClick","overlay","wrapper","createPortal","_jsx","ref","document","body","Root","children","defaultOpen","isOpen","setIsOpen","useState","open","close","_jsxs","Provider","value","useFullScreenImage","context","useContext","Error","Trigger","asChild","handleClick","onClick","style","cursor","display","FullScreenImage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FullScreenImage.js","sources":["../../../../../admin/src/components/AIChat/components/FullScreenImage.tsx"],"sourcesContent":["import { useEffect, useRef, createContext, useContext, useState, ReactNode } from 'react';\n\nimport { createPortal } from 'react-dom';\nimport { styled } from 'styled-components';\n\nimport { ANIMATIONS } from './animations';\nimport { Base64Img } from './Base64Image';\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FullScreenImageContextType {\n isOpen: boolean;\n open: () => void;\n close: () => void;\n src: string;\n alt: string;\n}\n\nconst FullScreenImageContext = createContext<FullScreenImageContextType | undefined>(undefined);\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FullScreenImageProps {\n src: string;\n alt: string;\n onClose?: () => void;\n}\n\ninterface FullScreenImageRootProps extends FullScreenImageProps {\n children: ReactNode;\n defaultOpen?: boolean;\n}\n\ninterface FullScreenImageTriggerProps {\n children: ReactNode;\n asChild?: boolean;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nexport const setOpacity = (hex: string, alpha: number) =>\n `${hex}${Math.floor(alpha * 255)\n .toString(16)\n .padStart(2, '0')}`;\n\nconst Overlay = styled.div`\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 500;\n pointer-events: auto; /* Explicitly enable pointer events */\n background: ${(props) => setOpacity(props.theme.colors.neutral800, 0.2)};\n`;\n\nconst ImageWrapper = styled.div`\n max-width: 80vw;\n max-height: 90vh;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: auto; /* Explicitly enable pointer events */\n position: relative;\n animation: ${ANIMATIONS.scaleIn} 0.3s ease;\n`;\n\nconst StyledImg = styled(Base64Img)`\n max-width: 100%;\n max-height: 90vh;\n object-fit: contain;\n pointer-events: auto; /* Explicitly enable pointer events */\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\n\n// Use the existing FullScreenImage as our modal component\nconst ImageModal = ({ src, alt, onClose }: FullScreenImageProps) => {\n const overlayRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n // Close on ESC key press\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n // Stop propagation to prevent closing parent modals\n e.preventDefault();\n e.stopPropagation();\n onClose?.();\n\n // The next 3 lines are critical: they completely stop the event\n e.stopImmediatePropagation();\n e.cancelBubble = true; // For older browsers\n return false;\n }\n };\n\n // Use capture phase to intercept event before it reaches other components\n window.addEventListener('keydown', handleKeyDown, true);\n return () => window.removeEventListener('keydown', handleKeyDown, true);\n }, [onClose]);\n\n // Setup click handlers\n useEffect(() => {\n const handleOverlayClick = (e: MouseEvent) => {\n // Only close if clicking directly on the overlay (not its children)\n if (e.target === overlayRef.current) {\n e.preventDefault();\n e.stopPropagation();\n onClose?.();\n }\n };\n\n const handleWrapperClick = (e: MouseEvent) => {\n // Stop propagation for clicks on the image wrapper\n e.stopPropagation();\n };\n\n const overlay = overlayRef.current;\n const wrapper = wrapperRef.current;\n\n if (overlay) {\n overlay.addEventListener('click', handleOverlayClick);\n }\n\n if (wrapper) {\n wrapper.addEventListener('click', handleWrapperClick);\n }\n\n return () => {\n if (overlay) {\n overlay.removeEventListener('click', handleOverlayClick);\n }\n\n if (wrapper) {\n wrapper.removeEventListener('click', handleWrapperClick);\n }\n };\n }, [onClose]);\n\n // Using createPortal to render directly at document body level\n return createPortal(\n <Overlay ref={overlayRef}>\n <ImageWrapper ref={wrapperRef}>\n <StyledImg src={src} alt={alt} />\n </ImageWrapper>\n </Overlay>,\n document.body\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\n// Root component that provides context\nconst Root = ({ children, src, alt, onClose, defaultOpen = false }: FullScreenImageRootProps) => {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n\n const open = () => setIsOpen(true);\n const close = () => {\n setIsOpen(false);\n onClose?.();\n };\n\n return (\n <FullScreenImageContext.Provider value={{ isOpen, open, close, src, alt }}>\n {children}\n {isOpen && <ImageModal src={src} alt={alt} onClose={close} />}\n </FullScreenImageContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\n// Hook to use the context\nconst useFullScreenImage = () => {\n const context = useContext(FullScreenImageContext);\n if (!context) {\n throw new Error('useFullScreenImage must be used within a FullScreenImage.Root');\n }\n return context;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Trigger\n * -----------------------------------------------------------------------------------------------*/\n\n// Trigger component that opens the full screen image\nconst Trigger = ({ children, asChild = false }: FullScreenImageTriggerProps) => {\n const { open } = useFullScreenImage();\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n open();\n };\n\n if (asChild) {\n return (\n <div onClick={handleClick} style={{ cursor: 'pointer', display: 'contents' }}>\n {children}\n </div>\n );\n }\n\n return (\n <div onClick={handleClick} style={{ cursor: 'pointer' }}>\n {children}\n </div>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Export\n * -----------------------------------------------------------------------------------------------*/\n\nexport const FullScreenImage = {\n Root,\n Trigger,\n};\n"],"names":["FullScreenImageContext","createContext","undefined","setOpacity","hex","alpha","Math","floor","toString","padStart","Overlay","styled","div","props","theme","colors","neutral800","ImageWrapper","ANIMATIONS","scaleIn","StyledImg","Base64Img","ImageModal","src","alt","onClose","overlayRef","useRef","wrapperRef","useEffect","handleKeyDown","e","key","preventDefault","stopPropagation","stopImmediatePropagation","cancelBubble","window","addEventListener","removeEventListener","handleOverlayClick","target","current","handleWrapperClick","overlay","wrapper","createPortal","_jsx","ref","document","body","Root","children","defaultOpen","isOpen","setIsOpen","useState","open","close","_jsxs","Provider","value","useFullScreenImage","context","useContext","Error","Trigger","asChild","handleClick","onClick","style","cursor","display","FullScreenImage"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FullScreenImage.mjs","sources":["../../../../../admin/src/components/AIChat/components/FullScreenImage.tsx"],"sourcesContent":["import { useEffect, useRef, createContext, useContext, useState, ReactNode } from 'react';\n\nimport { createPortal } from 'react-dom';\nimport { styled } from 'styled-components';\n\nimport { ANIMATIONS } from './animations';\nimport { Base64Img } from './Base64Image';\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FullScreenImageContextType {\n isOpen: boolean;\n open: () => void;\n close: () => void;\n src: string;\n alt: string;\n}\n\nconst FullScreenImageContext = createContext<FullScreenImageContextType | undefined>(undefined);\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FullScreenImageProps {\n src: string;\n alt: string;\n onClose?: () => void;\n}\n\ninterface FullScreenImageRootProps extends FullScreenImageProps {\n children: ReactNode;\n defaultOpen?: boolean;\n}\n\ninterface FullScreenImageTriggerProps {\n children: ReactNode;\n asChild?: boolean;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nexport const setOpacity = (hex: string, alpha: number) =>\n `${hex}${Math.floor(alpha * 255)\n .toString(16)\n .padStart(2, '0')}`;\n\nconst Overlay = styled.div`\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 500;\n pointer-events: auto; /* Explicitly enable pointer events */\n background: ${(props) => setOpacity(props.theme.colors.neutral800, 0.2)};\n`;\n\nconst ImageWrapper = styled.div`\n max-width: 80vw;\n max-height: 90vh;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: auto; /* Explicitly enable pointer events */\n position: relative;\n animation: ${ANIMATIONS.scaleIn} 0.3s ease;\n`;\n\nconst StyledImg = styled(Base64Img)`\n max-width: 100%;\n max-height: 90vh;\n object-fit: contain;\n pointer-events: auto; /* Explicitly enable pointer events */\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\n\n// Use the existing FullScreenImage as our modal component\nconst ImageModal = ({ src, alt, onClose }: FullScreenImageProps) => {\n const overlayRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n // Close on ESC key press\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n // Stop propagation to prevent closing parent modals\n e.preventDefault();\n e.stopPropagation();\n onClose?.();\n\n // The next 3 lines are critical: they completely stop the event\n e.stopImmediatePropagation();\n e.cancelBubble = true; // For older browsers\n return false;\n }\n };\n\n // Use capture phase to intercept event before it reaches other components\n window.addEventListener('keydown', handleKeyDown, true);\n return () => window.removeEventListener('keydown', handleKeyDown, true);\n }, [onClose]);\n\n // Setup click handlers\n useEffect(() => {\n const handleOverlayClick = (e: MouseEvent) => {\n // Only close if clicking directly on the overlay (not its children)\n if (e.target === overlayRef.current) {\n e.preventDefault();\n e.stopPropagation();\n onClose?.();\n }\n };\n\n const handleWrapperClick = (e: MouseEvent) => {\n // Stop propagation for clicks on the image wrapper\n e.stopPropagation();\n };\n\n const overlay = overlayRef.current;\n const wrapper = wrapperRef.current;\n\n if (overlay) {\n overlay.addEventListener('click', handleOverlayClick);\n }\n\n if (wrapper) {\n wrapper.addEventListener('click', handleWrapperClick);\n }\n\n return () => {\n if (overlay) {\n overlay.removeEventListener('click', handleOverlayClick);\n }\n\n if (wrapper) {\n wrapper.removeEventListener('click', handleWrapperClick);\n }\n };\n }, [onClose]);\n\n // Using createPortal to render directly at document body level\n return createPortal(\n <Overlay ref={overlayRef}>\n <ImageWrapper ref={wrapperRef}>\n <StyledImg src={src} alt={alt} />\n </ImageWrapper>\n </Overlay>,\n document.body\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\n// Root component that provides context\nconst Root = ({ children, src, alt, onClose, defaultOpen = false }: FullScreenImageRootProps) => {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n\n const open = () => setIsOpen(true);\n const close = () => {\n setIsOpen(false);\n onClose?.();\n };\n\n return (\n <FullScreenImageContext.Provider value={{ isOpen, open, close, src, alt }}>\n {children}\n {isOpen && <ImageModal src={src} alt={alt} onClose={close} />}\n </FullScreenImageContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\n// Hook to use the context\nconst useFullScreenImage = () => {\n const context = useContext(FullScreenImageContext);\n if (!context) {\n throw new Error('useFullScreenImage must be used within a FullScreenImage.Root');\n }\n return context;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Trigger\n * -----------------------------------------------------------------------------------------------*/\n\n// Trigger component that opens the full screen image\nconst Trigger = ({ children, asChild = false }: FullScreenImageTriggerProps) => {\n const { open } = useFullScreenImage();\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n open();\n };\n\n if (asChild) {\n return (\n <div onClick={handleClick} style={{ cursor: 'pointer', display: 'contents' }}>\n {children}\n </div>\n );\n }\n\n return (\n <div onClick={handleClick} style={{ cursor: 'pointer' }}>\n {children}\n </div>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Export\n * -----------------------------------------------------------------------------------------------*/\n\nexport const FullScreenImage = {\n Root,\n Trigger,\n};\n"],"names":["FullScreenImageContext","createContext","undefined","setOpacity","hex","alpha","Math","floor","toString","padStart","Overlay","styled","div","props","theme","colors","neutral800","ImageWrapper","ANIMATIONS","scaleIn","StyledImg","Base64Img","ImageModal","src","alt","onClose","overlayRef","useRef","wrapperRef","useEffect","handleKeyDown","e","key","preventDefault","stopPropagation","stopImmediatePropagation","cancelBubble","window","addEventListener","removeEventListener","handleOverlayClick","target","current","handleWrapperClick","overlay","wrapper","createPortal","_jsx","ref","document","body","Root","children","defaultOpen","isOpen","setIsOpen","useState","open","close","_jsxs","Provider","value","useFullScreenImage","context","useContext","Error","Trigger","asChild","handleClick","onClick","style","cursor","display","FullScreenImage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FullScreenImage.mjs","sources":["../../../../../admin/src/components/AIChat/components/FullScreenImage.tsx"],"sourcesContent":["import { useEffect, useRef, createContext, useContext, useState, ReactNode } from 'react';\n\nimport { createPortal } from 'react-dom';\nimport { styled } from 'styled-components';\n\nimport { ANIMATIONS } from './animations';\nimport { Base64Img } from './Base64Image';\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FullScreenImageContextType {\n isOpen: boolean;\n open: () => void;\n close: () => void;\n src: string;\n alt: string;\n}\n\nconst FullScreenImageContext = createContext<FullScreenImageContextType | undefined>(undefined);\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FullScreenImageProps {\n src: string;\n alt: string;\n onClose?: () => void;\n}\n\ninterface FullScreenImageRootProps extends FullScreenImageProps {\n children: ReactNode;\n defaultOpen?: boolean;\n}\n\ninterface FullScreenImageTriggerProps {\n children: ReactNode;\n asChild?: boolean;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Styles\n * -----------------------------------------------------------------------------------------------*/\nexport const setOpacity = (hex: string, alpha: number) =>\n `${hex}${Math.floor(alpha * 255)\n .toString(16)\n .padStart(2, '0')}`;\n\nconst Overlay = styled.div`\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 500;\n pointer-events: auto; /* Explicitly enable pointer events */\n background: ${(props) => setOpacity(props.theme.colors.neutral800, 0.2)};\n`;\n\nconst ImageWrapper = styled.div`\n max-width: 80vw;\n max-height: 90vh;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: auto; /* Explicitly enable pointer events */\n position: relative;\n animation: ${ANIMATIONS.scaleIn} 0.3s ease;\n`;\n\nconst StyledImg = styled(Base64Img)`\n max-width: 100%;\n max-height: 90vh;\n object-fit: contain;\n pointer-events: auto; /* Explicitly enable pointer events */\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\n\n// Use the existing FullScreenImage as our modal component\nconst ImageModal = ({ src, alt, onClose }: FullScreenImageProps) => {\n const overlayRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n // Close on ESC key press\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n // Stop propagation to prevent closing parent modals\n e.preventDefault();\n e.stopPropagation();\n onClose?.();\n\n // The next 3 lines are critical: they completely stop the event\n e.stopImmediatePropagation();\n e.cancelBubble = true; // For older browsers\n return false;\n }\n };\n\n // Use capture phase to intercept event before it reaches other components\n window.addEventListener('keydown', handleKeyDown, true);\n return () => window.removeEventListener('keydown', handleKeyDown, true);\n }, [onClose]);\n\n // Setup click handlers\n useEffect(() => {\n const handleOverlayClick = (e: MouseEvent) => {\n // Only close if clicking directly on the overlay (not its children)\n if (e.target === overlayRef.current) {\n e.preventDefault();\n e.stopPropagation();\n onClose?.();\n }\n };\n\n const handleWrapperClick = (e: MouseEvent) => {\n // Stop propagation for clicks on the image wrapper\n e.stopPropagation();\n };\n\n const overlay = overlayRef.current;\n const wrapper = wrapperRef.current;\n\n if (overlay) {\n overlay.addEventListener('click', handleOverlayClick);\n }\n\n if (wrapper) {\n wrapper.addEventListener('click', handleWrapperClick);\n }\n\n return () => {\n if (overlay) {\n overlay.removeEventListener('click', handleOverlayClick);\n }\n\n if (wrapper) {\n wrapper.removeEventListener('click', handleWrapperClick);\n }\n };\n }, [onClose]);\n\n // Using createPortal to render directly at document body level\n return createPortal(\n <Overlay ref={overlayRef}>\n <ImageWrapper ref={wrapperRef}>\n <StyledImg src={src} alt={alt} />\n </ImageWrapper>\n </Overlay>,\n document.body\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\n// Root component that provides context\nconst Root = ({ children, src, alt, onClose, defaultOpen = false }: FullScreenImageRootProps) => {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n\n const open = () => setIsOpen(true);\n const close = () => {\n setIsOpen(false);\n onClose?.();\n };\n\n return (\n <FullScreenImageContext.Provider value={{ isOpen, open, close, src, alt }}>\n {children}\n {isOpen && <ImageModal src={src} alt={alt} onClose={close} />}\n </FullScreenImageContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\n// Hook to use the context\nconst useFullScreenImage = () => {\n const context = useContext(FullScreenImageContext);\n if (!context) {\n throw new Error('useFullScreenImage must be used within a FullScreenImage.Root');\n }\n return context;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Trigger\n * -----------------------------------------------------------------------------------------------*/\n\n// Trigger component that opens the full screen image\nconst Trigger = ({ children, asChild = false }: FullScreenImageTriggerProps) => {\n const { open } = useFullScreenImage();\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n open();\n };\n\n if (asChild) {\n return (\n <div onClick={handleClick} style={{ cursor: 'pointer', display: 'contents' }}>\n {children}\n </div>\n );\n }\n\n return (\n <div onClick={handleClick} style={{ cursor: 'pointer' }}>\n {children}\n </div>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Export\n * -----------------------------------------------------------------------------------------------*/\n\nexport const FullScreenImage = {\n Root,\n Trigger,\n};\n"],"names":["FullScreenImageContext","createContext","undefined","setOpacity","hex","alpha","Math","floor","toString","padStart","Overlay","styled","div","props","theme","colors","neutral800","ImageWrapper","ANIMATIONS","scaleIn","StyledImg","Base64Img","ImageModal","src","alt","onClose","overlayRef","useRef","wrapperRef","useEffect","handleKeyDown","e","key","preventDefault","stopPropagation","stopImmediatePropagation","cancelBubble","window","addEventListener","removeEventListener","handleOverlayClick","target","current","handleWrapperClick","overlay","wrapper","createPortal","_jsx","ref","document","body","Root","children","defaultOpen","isOpen","setIsOpen","useState","open","close","_jsxs","Provider","value","useFullScreenImage","context","useContext","Error","Trigger","asChild","handleClick","onClick","style","cursor","display","FullScreenImage"],"mappings":"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"}
|