@strapi/content-type-builder 5.30.0 → 5.31.0
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/FeedbackModal.js.map +1 -1
- package/dist/admin/components/AIChat/FeedbackModal.mjs.map +1 -1
- package/dist/admin/components/AIChat/UploadFigmaModal.js.map +1 -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/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/GenericInputs.js +7 -4
- package/dist/admin/components/GenericInputs.js.map +1 -1
- package/dist/admin/components/GenericInputs.mjs +7 -4
- package/dist/admin/components/GenericInputs.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/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/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/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/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeedbackModal.js","sources":["../../../../admin/src/components/AIChat/FeedbackModal.tsx"],"sourcesContent":["import * as React from 'react';\nimport { createContext, useContext, useState } from 'react';\n\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Flex,\n Typography,\n Textarea,\n Button,\n Grid,\n Checkbox,\n Modal,\n} from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\nimport { useFeedback } from './hooks/useFeedback';\nimport { useTranslations } from './hooks/useTranslations';\n\nimport type { FeedbackReasonIds } from './lib/types/feedback';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface FeedbackModalContextType {\n isFeedbackModalOpen: boolean;\n currentMessageId: string | null;\n openFeedbackModal: (messageId: string) => void;\n closeFeedbackModal: () => void;\n}\n\nconst FeedbackModalContext = createContext<FeedbackModalContextType>({\n isFeedbackModalOpen: false,\n currentMessageId: null,\n openFeedbackModal: () => {},\n closeFeedbackModal: () => {},\n});\n\nexport const useFeedbackModal = () => useContext(FeedbackModalContext);\n\nexport const FeedbackProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFeedbackModalOpen, setIsFeedbackModalOpen] = useState(false);\n const [currentMessageId, setCurrentMessageId] = useState<string | null>(null);\n\n const openFeedbackModal = (messageId: string) => {\n setCurrentMessageId(messageId);\n setIsFeedbackModalOpen(true);\n };\n\n const closeFeedbackModal = () => {\n setIsFeedbackModalOpen(false);\n setCurrentMessageId(null);\n };\n\n return (\n <FeedbackModalContext.Provider\n value={{ isFeedbackModalOpen, currentMessageId, openFeedbackModal, closeFeedbackModal }}\n >\n {isFeedbackModalOpen && currentMessageId && <FeedbackModal />}\n {children}\n </FeedbackModalContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Feedback Option\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FeedbackOptionProps {\n id: FeedbackReasonIds;\n label: string;\n selected: boolean;\n onClick: (id: FeedbackReasonIds) => void;\n}\n\nconst FeedbackOptionWrapper = styled(Flex)`\n &:hover {\n background-color: ${({ theme }) => theme.colors.neutral100};\n }\n\n &.selected {\n background-color: ${({ theme }) => theme.colors.primary100};\n border-color: ${({ theme }) => theme.colors.primary200};\n }\n`;\n\nconst FeedbackOption: React.FC<FeedbackOptionProps> = ({ id, label, selected, onClick }) => {\n return (\n <FeedbackOptionWrapper\n className={selected ? 'selected' : ''}\n justifyContent=\"space-between\"\n hasRadius\n width=\"100%\"\n cursor=\"pointer\"\n borderColor=\"neutral200\"\n padding={3}\n gap={3}\n onClick={() => onClick(id)}\n >\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {label}\n </Typography>\n <Checkbox\n name={`feedback-${id}`}\n value={id}\n checked={selected}\n onChange={() => onClick(id)}\n />\n </FeedbackOptionWrapper>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\n\nexport const FeedbackModal: React.FC = () => {\n const [feedbackText, setFeedbackText] = useState('');\n const [selectedReasons, setSelectedReasons] = useState<FeedbackReasonIds[]>([]);\n\n const { t } = useTranslations();\n const { toggleNotification } = useNotification();\n const { closeFeedbackModal, currentMessageId } = useFeedbackModal();\n const { downvoteMessage, isPending } = useFeedback();\n\n const feedbackReasons = [\n {\n id: 'invalid_schema',\n label: t('chat.feedback.reason.invalid_schema', 'Invalid schema'),\n },\n {\n id: 'bad_recommendation',\n label: t('chat.feedback.reason.bad_recommendation', 'Bad recommendation'),\n },\n {\n id: 'slow',\n label: t('chat.feedback.reason.slow', 'Slow'),\n },\n {\n id: 'instructions_ignored',\n label: t('chat.feedback.reason.instructions_ignored', 'Instructions ignored'),\n },\n {\n id: 'being_lazy',\n label: t('chat.feedback.reason.being_lazy', 'Being lazy'),\n },\n {\n id: 'other',\n label: t('chat.feedback.reason.other', 'Other'),\n },\n ] satisfies { id: FeedbackReasonIds; label: string }[];\n\n const handleReasonSelect = (id: FeedbackReasonIds) => {\n setSelectedReasons((prevSelected) => {\n // If already selected, remove it\n if (prevSelected.includes(id)) {\n return prevSelected.filter((reasonId) => reasonId !== id);\n }\n // Otherwise add it\n return [...prevSelected, id];\n });\n };\n\n const handleSubmitFeedback = async () => {\n if (selectedReasons.length === 0) return;\n\n try {\n await downvoteMessage(currentMessageId as string, feedbackText, selectedReasons);\n\n setFeedbackText('');\n setSelectedReasons([]);\n closeFeedbackModal();\n } catch (error) {\n toggleNotification({\n type: 'danger',\n message: t('chat.feedback.error', 'An error occurred while submitting your feedback'),\n });\n }\n };\n\n return (\n <Modal.Root open onOpenChange={closeFeedbackModal}>\n <Modal.Content>\n <Modal.Header>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {t('chat.feedback.title', 'Give feedback')}\n </Typography>\n </Modal.Header>\n <Modal.Body>\n <Flex direction=\"column\" alignItems=\"start\" gap={6} width=\"100%\">\n <Flex direction=\"column\" alignItems=\"start\" gap={2}>\n <Typography variant=\"beta\" fontWeight=\"bold\">\n {t('chat.feedback.title', 'Give feedback')}\n </Typography>\n <Typography variant=\"omega\">\n {t(\n 'chat.feedback.subtitle',\n 'Provide additional feedback on this message. Select all that apply.'\n )}\n </Typography>\n </Flex>\n <Grid.Root width=\"100%\" gap={2}>\n {feedbackReasons.map((reason) => (\n <Grid.Item key={reason.id} col={6}>\n <FeedbackOption\n key={reason.id}\n id={reason.id}\n label={reason.label}\n selected={selectedReasons.includes(reason.id)}\n onClick={handleReasonSelect}\n />\n </Grid.Item>\n ))}\n </Grid.Root>\n <Flex direction=\"column\" gap={2} width=\"100%\" alignItems=\"start\">\n <Typography variant=\"omega\">\n {t('chat.feedback.comment.label', 'How can we improve? (optional)')}\n </Typography>\n <Box width=\"100%\">\n <Textarea\n name=\"feedback\"\n placeholder={t('chat.feedback.placeholder', 'Your feedback...')}\n onChange={(e) => setFeedbackText(e.target.value)}\n value={feedbackText}\n />\n </Box>\n </Flex>\n </Flex>\n </Modal.Body>\n <Modal.Footer>\n <Modal.Close>\n <Button variant=\"tertiary\" onClick={closeFeedbackModal}>\n {t('form.button.cancel', 'Cancel')}\n </Button>\n </Modal.Close>\n <Button\n onClick={handleSubmitFeedback}\n loading={isPending}\n disabled={selectedReasons.length === 0}\n >\n {t('form.button.submit', 'Submit')}\n </Button>\n </Modal.Footer>\n </Modal.Content>\n </Modal.Root>\n );\n};\n"],"names":["FeedbackModalContext","createContext","isFeedbackModalOpen","currentMessageId","openFeedbackModal","closeFeedbackModal","useFeedbackModal","useContext","FeedbackProvider","children","setIsFeedbackModalOpen","useState","setCurrentMessageId","messageId","_jsxs","Provider","value","_jsx","FeedbackModal","FeedbackOptionWrapper","styled","Flex","theme","colors","neutral100","primary100","primary200","FeedbackOption","id","label","selected","onClick","className","justifyContent","hasRadius","width","cursor","borderColor","padding","gap","Typography","variant","fontWeight","Checkbox","name","checked","onChange","feedbackText","setFeedbackText","selectedReasons","setSelectedReasons","t","useTranslations","toggleNotification","useNotification","downvoteMessage","isPending","useFeedback","feedbackReasons","handleReasonSelect","prevSelected","includes","filter","reasonId","handleSubmitFeedback","length","error","type","message","Modal","Root","open","onOpenChange","Content","Header","Body","direction","alignItems","Grid","map","reason","Item","col","Box","Textarea","placeholder","e","target","Footer","Close","Button","loading","disabled"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FeedbackModal.js","sources":["../../../../admin/src/components/AIChat/FeedbackModal.tsx"],"sourcesContent":["import * as React from 'react';\nimport { createContext, useContext, useState } from 'react';\n\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Flex,\n Typography,\n Textarea,\n Button,\n Grid,\n Checkbox,\n Modal,\n} from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\nimport { useFeedback } from './hooks/useFeedback';\nimport { useTranslations } from './hooks/useTranslations';\n\nimport type { FeedbackReasonIds } from './lib/types/feedback';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface FeedbackModalContextType {\n isFeedbackModalOpen: boolean;\n currentMessageId: string | null;\n openFeedbackModal: (messageId: string) => void;\n closeFeedbackModal: () => void;\n}\n\nconst FeedbackModalContext = createContext<FeedbackModalContextType>({\n isFeedbackModalOpen: false,\n currentMessageId: null,\n openFeedbackModal: () => {},\n closeFeedbackModal: () => {},\n});\n\nexport const useFeedbackModal = () => useContext(FeedbackModalContext);\n\nexport const FeedbackProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFeedbackModalOpen, setIsFeedbackModalOpen] = useState(false);\n const [currentMessageId, setCurrentMessageId] = useState<string | null>(null);\n\n const openFeedbackModal = (messageId: string) => {\n setCurrentMessageId(messageId);\n setIsFeedbackModalOpen(true);\n };\n\n const closeFeedbackModal = () => {\n setIsFeedbackModalOpen(false);\n setCurrentMessageId(null);\n };\n\n return (\n <FeedbackModalContext.Provider\n value={{ isFeedbackModalOpen, currentMessageId, openFeedbackModal, closeFeedbackModal }}\n >\n {isFeedbackModalOpen && currentMessageId && <FeedbackModal />}\n {children}\n </FeedbackModalContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Feedback Option\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FeedbackOptionProps {\n id: FeedbackReasonIds;\n label: string;\n selected: boolean;\n onClick: (id: FeedbackReasonIds) => void;\n}\n\nconst FeedbackOptionWrapper = styled(Flex)`\n &:hover {\n background-color: ${({ theme }) => theme.colors.neutral100};\n }\n\n &.selected {\n background-color: ${({ theme }) => theme.colors.primary100};\n border-color: ${({ theme }) => theme.colors.primary200};\n }\n`;\n\nconst FeedbackOption: React.FC<FeedbackOptionProps> = ({ id, label, selected, onClick }) => {\n return (\n <FeedbackOptionWrapper\n className={selected ? 'selected' : ''}\n justifyContent=\"space-between\"\n hasRadius\n width=\"100%\"\n cursor=\"pointer\"\n borderColor=\"neutral200\"\n padding={3}\n gap={3}\n onClick={() => onClick(id)}\n >\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {label}\n </Typography>\n <Checkbox\n name={`feedback-${id}`}\n value={id}\n checked={selected}\n onChange={() => onClick(id)}\n />\n </FeedbackOptionWrapper>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\n\nexport const FeedbackModal: React.FC = () => {\n const [feedbackText, setFeedbackText] = useState('');\n const [selectedReasons, setSelectedReasons] = useState<FeedbackReasonIds[]>([]);\n\n const { t } = useTranslations();\n const { toggleNotification } = useNotification();\n const { closeFeedbackModal, currentMessageId } = useFeedbackModal();\n const { downvoteMessage, isPending } = useFeedback();\n\n const feedbackReasons = [\n {\n id: 'invalid_schema',\n label: t('chat.feedback.reason.invalid_schema', 'Invalid schema'),\n },\n {\n id: 'bad_recommendation',\n label: t('chat.feedback.reason.bad_recommendation', 'Bad recommendation'),\n },\n {\n id: 'slow',\n label: t('chat.feedback.reason.slow', 'Slow'),\n },\n {\n id: 'instructions_ignored',\n label: t('chat.feedback.reason.instructions_ignored', 'Instructions ignored'),\n },\n {\n id: 'being_lazy',\n label: t('chat.feedback.reason.being_lazy', 'Being lazy'),\n },\n {\n id: 'other',\n label: t('chat.feedback.reason.other', 'Other'),\n },\n ] satisfies { id: FeedbackReasonIds; label: string }[];\n\n const handleReasonSelect = (id: FeedbackReasonIds) => {\n setSelectedReasons((prevSelected) => {\n // If already selected, remove it\n if (prevSelected.includes(id)) {\n return prevSelected.filter((reasonId) => reasonId !== id);\n }\n // Otherwise add it\n return [...prevSelected, id];\n });\n };\n\n const handleSubmitFeedback = async () => {\n if (selectedReasons.length === 0) return;\n\n try {\n await downvoteMessage(currentMessageId as string, feedbackText, selectedReasons);\n\n setFeedbackText('');\n setSelectedReasons([]);\n closeFeedbackModal();\n } catch (error) {\n toggleNotification({\n type: 'danger',\n message: t('chat.feedback.error', 'An error occurred while submitting your feedback'),\n });\n }\n };\n\n return (\n <Modal.Root open onOpenChange={closeFeedbackModal}>\n <Modal.Content>\n <Modal.Header>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {t('chat.feedback.title', 'Give feedback')}\n </Typography>\n </Modal.Header>\n <Modal.Body>\n <Flex direction=\"column\" alignItems=\"start\" gap={6} width=\"100%\">\n <Flex direction=\"column\" alignItems=\"start\" gap={2}>\n <Typography variant=\"beta\" fontWeight=\"bold\">\n {t('chat.feedback.title', 'Give feedback')}\n </Typography>\n <Typography variant=\"omega\">\n {t(\n 'chat.feedback.subtitle',\n 'Provide additional feedback on this message. Select all that apply.'\n )}\n </Typography>\n </Flex>\n <Grid.Root width=\"100%\" gap={2}>\n {feedbackReasons.map((reason) => (\n <Grid.Item key={reason.id} col={6}>\n <FeedbackOption\n key={reason.id}\n id={reason.id}\n label={reason.label}\n selected={selectedReasons.includes(reason.id)}\n onClick={handleReasonSelect}\n />\n </Grid.Item>\n ))}\n </Grid.Root>\n <Flex direction=\"column\" gap={2} width=\"100%\" alignItems=\"start\">\n <Typography variant=\"omega\">\n {t('chat.feedback.comment.label', 'How can we improve? (optional)')}\n </Typography>\n <Box width=\"100%\">\n <Textarea\n name=\"feedback\"\n placeholder={t('chat.feedback.placeholder', 'Your feedback...')}\n onChange={(e) => setFeedbackText(e.target.value)}\n value={feedbackText}\n />\n </Box>\n </Flex>\n </Flex>\n </Modal.Body>\n <Modal.Footer>\n <Modal.Close>\n <Button variant=\"tertiary\" onClick={closeFeedbackModal}>\n {t('form.button.cancel', 'Cancel')}\n </Button>\n </Modal.Close>\n <Button\n onClick={handleSubmitFeedback}\n loading={isPending}\n disabled={selectedReasons.length === 0}\n >\n {t('form.button.submit', 'Submit')}\n </Button>\n </Modal.Footer>\n </Modal.Content>\n </Modal.Root>\n );\n};\n"],"names":["FeedbackModalContext","createContext","isFeedbackModalOpen","currentMessageId","openFeedbackModal","closeFeedbackModal","useFeedbackModal","useContext","FeedbackProvider","children","setIsFeedbackModalOpen","useState","setCurrentMessageId","messageId","_jsxs","Provider","value","_jsx","FeedbackModal","FeedbackOptionWrapper","styled","Flex","theme","colors","neutral100","primary100","primary200","FeedbackOption","id","label","selected","onClick","className","justifyContent","hasRadius","width","cursor","borderColor","padding","gap","Typography","variant","fontWeight","Checkbox","name","checked","onChange","feedbackText","setFeedbackText","selectedReasons","setSelectedReasons","t","useTranslations","toggleNotification","useNotification","downvoteMessage","isPending","useFeedback","feedbackReasons","handleReasonSelect","prevSelected","includes","filter","reasonId","handleSubmitFeedback","length","error","type","message","Modal","Root","open","onOpenChange","Content","Header","Body","direction","alignItems","Grid","map","reason","Item","col","Box","Textarea","placeholder","e","target","Footer","Close","Button","loading","disabled"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeedbackModal.mjs","sources":["../../../../admin/src/components/AIChat/FeedbackModal.tsx"],"sourcesContent":["import * as React from 'react';\nimport { createContext, useContext, useState } from 'react';\n\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Flex,\n Typography,\n Textarea,\n Button,\n Grid,\n Checkbox,\n Modal,\n} from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\nimport { useFeedback } from './hooks/useFeedback';\nimport { useTranslations } from './hooks/useTranslations';\n\nimport type { FeedbackReasonIds } from './lib/types/feedback';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface FeedbackModalContextType {\n isFeedbackModalOpen: boolean;\n currentMessageId: string | null;\n openFeedbackModal: (messageId: string) => void;\n closeFeedbackModal: () => void;\n}\n\nconst FeedbackModalContext = createContext<FeedbackModalContextType>({\n isFeedbackModalOpen: false,\n currentMessageId: null,\n openFeedbackModal: () => {},\n closeFeedbackModal: () => {},\n});\n\nexport const useFeedbackModal = () => useContext(FeedbackModalContext);\n\nexport const FeedbackProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFeedbackModalOpen, setIsFeedbackModalOpen] = useState(false);\n const [currentMessageId, setCurrentMessageId] = useState<string | null>(null);\n\n const openFeedbackModal = (messageId: string) => {\n setCurrentMessageId(messageId);\n setIsFeedbackModalOpen(true);\n };\n\n const closeFeedbackModal = () => {\n setIsFeedbackModalOpen(false);\n setCurrentMessageId(null);\n };\n\n return (\n <FeedbackModalContext.Provider\n value={{ isFeedbackModalOpen, currentMessageId, openFeedbackModal, closeFeedbackModal }}\n >\n {isFeedbackModalOpen && currentMessageId && <FeedbackModal />}\n {children}\n </FeedbackModalContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Feedback Option\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FeedbackOptionProps {\n id: FeedbackReasonIds;\n label: string;\n selected: boolean;\n onClick: (id: FeedbackReasonIds) => void;\n}\n\nconst FeedbackOptionWrapper = styled(Flex)`\n &:hover {\n background-color: ${({ theme }) => theme.colors.neutral100};\n }\n\n &.selected {\n background-color: ${({ theme }) => theme.colors.primary100};\n border-color: ${({ theme }) => theme.colors.primary200};\n }\n`;\n\nconst FeedbackOption: React.FC<FeedbackOptionProps> = ({ id, label, selected, onClick }) => {\n return (\n <FeedbackOptionWrapper\n className={selected ? 'selected' : ''}\n justifyContent=\"space-between\"\n hasRadius\n width=\"100%\"\n cursor=\"pointer\"\n borderColor=\"neutral200\"\n padding={3}\n gap={3}\n onClick={() => onClick(id)}\n >\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {label}\n </Typography>\n <Checkbox\n name={`feedback-${id}`}\n value={id}\n checked={selected}\n onChange={() => onClick(id)}\n />\n </FeedbackOptionWrapper>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\n\nexport const FeedbackModal: React.FC = () => {\n const [feedbackText, setFeedbackText] = useState('');\n const [selectedReasons, setSelectedReasons] = useState<FeedbackReasonIds[]>([]);\n\n const { t } = useTranslations();\n const { toggleNotification } = useNotification();\n const { closeFeedbackModal, currentMessageId } = useFeedbackModal();\n const { downvoteMessage, isPending } = useFeedback();\n\n const feedbackReasons = [\n {\n id: 'invalid_schema',\n label: t('chat.feedback.reason.invalid_schema', 'Invalid schema'),\n },\n {\n id: 'bad_recommendation',\n label: t('chat.feedback.reason.bad_recommendation', 'Bad recommendation'),\n },\n {\n id: 'slow',\n label: t('chat.feedback.reason.slow', 'Slow'),\n },\n {\n id: 'instructions_ignored',\n label: t('chat.feedback.reason.instructions_ignored', 'Instructions ignored'),\n },\n {\n id: 'being_lazy',\n label: t('chat.feedback.reason.being_lazy', 'Being lazy'),\n },\n {\n id: 'other',\n label: t('chat.feedback.reason.other', 'Other'),\n },\n ] satisfies { id: FeedbackReasonIds; label: string }[];\n\n const handleReasonSelect = (id: FeedbackReasonIds) => {\n setSelectedReasons((prevSelected) => {\n // If already selected, remove it\n if (prevSelected.includes(id)) {\n return prevSelected.filter((reasonId) => reasonId !== id);\n }\n // Otherwise add it\n return [...prevSelected, id];\n });\n };\n\n const handleSubmitFeedback = async () => {\n if (selectedReasons.length === 0) return;\n\n try {\n await downvoteMessage(currentMessageId as string, feedbackText, selectedReasons);\n\n setFeedbackText('');\n setSelectedReasons([]);\n closeFeedbackModal();\n } catch (error) {\n toggleNotification({\n type: 'danger',\n message: t('chat.feedback.error', 'An error occurred while submitting your feedback'),\n });\n }\n };\n\n return (\n <Modal.Root open onOpenChange={closeFeedbackModal}>\n <Modal.Content>\n <Modal.Header>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {t('chat.feedback.title', 'Give feedback')}\n </Typography>\n </Modal.Header>\n <Modal.Body>\n <Flex direction=\"column\" alignItems=\"start\" gap={6} width=\"100%\">\n <Flex direction=\"column\" alignItems=\"start\" gap={2}>\n <Typography variant=\"beta\" fontWeight=\"bold\">\n {t('chat.feedback.title', 'Give feedback')}\n </Typography>\n <Typography variant=\"omega\">\n {t(\n 'chat.feedback.subtitle',\n 'Provide additional feedback on this message. Select all that apply.'\n )}\n </Typography>\n </Flex>\n <Grid.Root width=\"100%\" gap={2}>\n {feedbackReasons.map((reason) => (\n <Grid.Item key={reason.id} col={6}>\n <FeedbackOption\n key={reason.id}\n id={reason.id}\n label={reason.label}\n selected={selectedReasons.includes(reason.id)}\n onClick={handleReasonSelect}\n />\n </Grid.Item>\n ))}\n </Grid.Root>\n <Flex direction=\"column\" gap={2} width=\"100%\" alignItems=\"start\">\n <Typography variant=\"omega\">\n {t('chat.feedback.comment.label', 'How can we improve? (optional)')}\n </Typography>\n <Box width=\"100%\">\n <Textarea\n name=\"feedback\"\n placeholder={t('chat.feedback.placeholder', 'Your feedback...')}\n onChange={(e) => setFeedbackText(e.target.value)}\n value={feedbackText}\n />\n </Box>\n </Flex>\n </Flex>\n </Modal.Body>\n <Modal.Footer>\n <Modal.Close>\n <Button variant=\"tertiary\" onClick={closeFeedbackModal}>\n {t('form.button.cancel', 'Cancel')}\n </Button>\n </Modal.Close>\n <Button\n onClick={handleSubmitFeedback}\n loading={isPending}\n disabled={selectedReasons.length === 0}\n >\n {t('form.button.submit', 'Submit')}\n </Button>\n </Modal.Footer>\n </Modal.Content>\n </Modal.Root>\n );\n};\n"],"names":["FeedbackModalContext","createContext","isFeedbackModalOpen","currentMessageId","openFeedbackModal","closeFeedbackModal","useFeedbackModal","useContext","FeedbackProvider","children","setIsFeedbackModalOpen","useState","setCurrentMessageId","messageId","_jsxs","Provider","value","_jsx","FeedbackModal","FeedbackOptionWrapper","styled","Flex","theme","colors","neutral100","primary100","primary200","FeedbackOption","id","label","selected","onClick","className","justifyContent","hasRadius","width","cursor","borderColor","padding","gap","Typography","variant","fontWeight","Checkbox","name","checked","onChange","feedbackText","setFeedbackText","selectedReasons","setSelectedReasons","t","useTranslations","toggleNotification","useNotification","downvoteMessage","isPending","useFeedback","feedbackReasons","handleReasonSelect","prevSelected","includes","filter","reasonId","handleSubmitFeedback","length","error","type","message","Modal","Root","open","onOpenChange","Content","Header","Body","direction","alignItems","Grid","map","reason","Item","col","Box","Textarea","placeholder","e","target","Footer","Close","Button","loading","disabled"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FeedbackModal.mjs","sources":["../../../../admin/src/components/AIChat/FeedbackModal.tsx"],"sourcesContent":["import * as React from 'react';\nimport { createContext, useContext, useState } from 'react';\n\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Flex,\n Typography,\n Textarea,\n Button,\n Grid,\n Checkbox,\n Modal,\n} from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\nimport { useFeedback } from './hooks/useFeedback';\nimport { useTranslations } from './hooks/useTranslations';\n\nimport type { FeedbackReasonIds } from './lib/types/feedback';\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\ninterface FeedbackModalContextType {\n isFeedbackModalOpen: boolean;\n currentMessageId: string | null;\n openFeedbackModal: (messageId: string) => void;\n closeFeedbackModal: () => void;\n}\n\nconst FeedbackModalContext = createContext<FeedbackModalContextType>({\n isFeedbackModalOpen: false,\n currentMessageId: null,\n openFeedbackModal: () => {},\n closeFeedbackModal: () => {},\n});\n\nexport const useFeedbackModal = () => useContext(FeedbackModalContext);\n\nexport const FeedbackProvider = ({ children }: { children: React.ReactNode }) => {\n const [isFeedbackModalOpen, setIsFeedbackModalOpen] = useState(false);\n const [currentMessageId, setCurrentMessageId] = useState<string | null>(null);\n\n const openFeedbackModal = (messageId: string) => {\n setCurrentMessageId(messageId);\n setIsFeedbackModalOpen(true);\n };\n\n const closeFeedbackModal = () => {\n setIsFeedbackModalOpen(false);\n setCurrentMessageId(null);\n };\n\n return (\n <FeedbackModalContext.Provider\n value={{ isFeedbackModalOpen, currentMessageId, openFeedbackModal, closeFeedbackModal }}\n >\n {isFeedbackModalOpen && currentMessageId && <FeedbackModal />}\n {children}\n </FeedbackModalContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Feedback Option\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FeedbackOptionProps {\n id: FeedbackReasonIds;\n label: string;\n selected: boolean;\n onClick: (id: FeedbackReasonIds) => void;\n}\n\nconst FeedbackOptionWrapper = styled(Flex)`\n &:hover {\n background-color: ${({ theme }) => theme.colors.neutral100};\n }\n\n &.selected {\n background-color: ${({ theme }) => theme.colors.primary100};\n border-color: ${({ theme }) => theme.colors.primary200};\n }\n`;\n\nconst FeedbackOption: React.FC<FeedbackOptionProps> = ({ id, label, selected, onClick }) => {\n return (\n <FeedbackOptionWrapper\n className={selected ? 'selected' : ''}\n justifyContent=\"space-between\"\n hasRadius\n width=\"100%\"\n cursor=\"pointer\"\n borderColor=\"neutral200\"\n padding={3}\n gap={3}\n onClick={() => onClick(id)}\n >\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {label}\n </Typography>\n <Checkbox\n name={`feedback-${id}`}\n value={id}\n checked={selected}\n onChange={() => onClick(id)}\n />\n </FeedbackOptionWrapper>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Modal\n * -----------------------------------------------------------------------------------------------*/\n\nexport const FeedbackModal: React.FC = () => {\n const [feedbackText, setFeedbackText] = useState('');\n const [selectedReasons, setSelectedReasons] = useState<FeedbackReasonIds[]>([]);\n\n const { t } = useTranslations();\n const { toggleNotification } = useNotification();\n const { closeFeedbackModal, currentMessageId } = useFeedbackModal();\n const { downvoteMessage, isPending } = useFeedback();\n\n const feedbackReasons = [\n {\n id: 'invalid_schema',\n label: t('chat.feedback.reason.invalid_schema', 'Invalid schema'),\n },\n {\n id: 'bad_recommendation',\n label: t('chat.feedback.reason.bad_recommendation', 'Bad recommendation'),\n },\n {\n id: 'slow',\n label: t('chat.feedback.reason.slow', 'Slow'),\n },\n {\n id: 'instructions_ignored',\n label: t('chat.feedback.reason.instructions_ignored', 'Instructions ignored'),\n },\n {\n id: 'being_lazy',\n label: t('chat.feedback.reason.being_lazy', 'Being lazy'),\n },\n {\n id: 'other',\n label: t('chat.feedback.reason.other', 'Other'),\n },\n ] satisfies { id: FeedbackReasonIds; label: string }[];\n\n const handleReasonSelect = (id: FeedbackReasonIds) => {\n setSelectedReasons((prevSelected) => {\n // If already selected, remove it\n if (prevSelected.includes(id)) {\n return prevSelected.filter((reasonId) => reasonId !== id);\n }\n // Otherwise add it\n return [...prevSelected, id];\n });\n };\n\n const handleSubmitFeedback = async () => {\n if (selectedReasons.length === 0) return;\n\n try {\n await downvoteMessage(currentMessageId as string, feedbackText, selectedReasons);\n\n setFeedbackText('');\n setSelectedReasons([]);\n closeFeedbackModal();\n } catch (error) {\n toggleNotification({\n type: 'danger',\n message: t('chat.feedback.error', 'An error occurred while submitting your feedback'),\n });\n }\n };\n\n return (\n <Modal.Root open onOpenChange={closeFeedbackModal}>\n <Modal.Content>\n <Modal.Header>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {t('chat.feedback.title', 'Give feedback')}\n </Typography>\n </Modal.Header>\n <Modal.Body>\n <Flex direction=\"column\" alignItems=\"start\" gap={6} width=\"100%\">\n <Flex direction=\"column\" alignItems=\"start\" gap={2}>\n <Typography variant=\"beta\" fontWeight=\"bold\">\n {t('chat.feedback.title', 'Give feedback')}\n </Typography>\n <Typography variant=\"omega\">\n {t(\n 'chat.feedback.subtitle',\n 'Provide additional feedback on this message. Select all that apply.'\n )}\n </Typography>\n </Flex>\n <Grid.Root width=\"100%\" gap={2}>\n {feedbackReasons.map((reason) => (\n <Grid.Item key={reason.id} col={6}>\n <FeedbackOption\n key={reason.id}\n id={reason.id}\n label={reason.label}\n selected={selectedReasons.includes(reason.id)}\n onClick={handleReasonSelect}\n />\n </Grid.Item>\n ))}\n </Grid.Root>\n <Flex direction=\"column\" gap={2} width=\"100%\" alignItems=\"start\">\n <Typography variant=\"omega\">\n {t('chat.feedback.comment.label', 'How can we improve? (optional)')}\n </Typography>\n <Box width=\"100%\">\n <Textarea\n name=\"feedback\"\n placeholder={t('chat.feedback.placeholder', 'Your feedback...')}\n onChange={(e) => setFeedbackText(e.target.value)}\n value={feedbackText}\n />\n </Box>\n </Flex>\n </Flex>\n </Modal.Body>\n <Modal.Footer>\n <Modal.Close>\n <Button variant=\"tertiary\" onClick={closeFeedbackModal}>\n {t('form.button.cancel', 'Cancel')}\n </Button>\n </Modal.Close>\n <Button\n onClick={handleSubmitFeedback}\n loading={isPending}\n disabled={selectedReasons.length === 0}\n >\n {t('form.button.submit', 'Submit')}\n </Button>\n </Modal.Footer>\n </Modal.Content>\n </Modal.Root>\n );\n};\n"],"names":["FeedbackModalContext","createContext","isFeedbackModalOpen","currentMessageId","openFeedbackModal","closeFeedbackModal","useFeedbackModal","useContext","FeedbackProvider","children","setIsFeedbackModalOpen","useState","setCurrentMessageId","messageId","_jsxs","Provider","value","_jsx","FeedbackModal","FeedbackOptionWrapper","styled","Flex","theme","colors","neutral100","primary100","primary200","FeedbackOption","id","label","selected","onClick","className","justifyContent","hasRadius","width","cursor","borderColor","padding","gap","Typography","variant","fontWeight","Checkbox","name","checked","onChange","feedbackText","setFeedbackText","selectedReasons","setSelectedReasons","t","useTranslations","toggleNotification","useNotification","downvoteMessage","isPending","useFeedback","feedbackReasons","handleReasonSelect","prevSelected","includes","filter","reasonId","handleSubmitFeedback","length","error","type","message","Modal","Root","open","onOpenChange","Content","Header","Body","direction","alignItems","Grid","map","reason","Item","col","Box","Textarea","placeholder","e","target","Footer","Close","Button","loading","disabled"],"mappings":"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"}
|
|
@@ -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 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
|
+
{"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 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":";;;;;;;;;;AA2BA,MAAMA,mCAAqBC,aAAsC,CAAA;IAC/DC,iBAAmB,EAAA,KAAA;IACnBC,cAAgB,EAAA,KAAA;AAChBC,IAAAA,eAAAA,EAAiB,IAAO,EAAA;AACxBC,IAAAA,gBAAAA,EAAkB,IAAO;AAC3B,CAAA,CAAA;MAEaC,oBAAuB,GAAA,IAAA;AAClC,IAAA,MAAMC,UAAUC,UAAWR,CAAAA,kBAAAA,CAAAA;AAC3B,IAAA,IAAI,CAACO,OAAS,EAAA;AACZ,QAAA,MAAM,IAAIE,KAAM,CAAA,uEAAA,CAAA;AAClB;IACA,OAAOF,OAAAA;AACT;AAEaG,MAAAA,yBAAAA,GAA4B,CAAC,EAAEC,QAAQ,EAAiC,GAAA;AACnF,IAAA,MAAM,CAACT,iBAAmBU,EAAAA,oBAAAA,CAAqB,GAAGC,QAAAA,CAAS;AAC3D,IAAA,MAAM,CAACV,cAAAA,EAAgBW,iBAAkB,CAAA,GAAGD,QAAS,CAAA,KAAA,CAAA;AAErD,IAAA,MAAMT,kBAAkB,CAACW,mBAAAA,GAAAA;QACvBH,oBAAqB,CAAA,IAAA,CAAA;AACrBE,QAAAA,iBAAAA,CAAkBC,mBAAuB,IAAA,KAAA,CAAA;AAC3C,KAAA;IAEA,MAAMV,gBAAAA,GAAmB,IAAMO,oBAAqB,CAAA,KAAA,CAAA;IAEpD,qBACEI,IAAA,CAAChB,mBAAmBiB,QAAQ,EAAA;QAC1BC,KAAO,EAAA;AAAEhB,YAAAA,iBAAAA;AAAmBC,YAAAA,cAAAA;AAAgBC,YAAAA,eAAAA;AAAiBC,YAAAA;AAAiB,SAAA;;AAE7EH,YAAAA,iBAAAA,kBAAqBiB,GAACC,CAAAA,gBAAAA,EAAAA,EAAAA,CAAAA;AACtBT,YAAAA;;;AAGP;AAYA,MAAMU,oBAAoB,CAAC,EAAEC,QAAQ,EAAEC,WAAW,EAA0B,GAAA;IAC1E,MAAM,EAAEC,CAAC,EAAE,GAAGC,eAAAA,EAAAA;IACd,MAAM,EAAEC,SAAS,EAAE,GAAGC,YAAAA,EAAAA;AACtB,IAAA,MAAM,CAACC,iBAAAA,EAAmBC,oBAAqB,CAAA,GAAGhB,SAAS,CAACiB,aAAAA,EAAAA,CAAAA;AAC5D,IAAA,MAAM,CAACC,UAAAA,EAAYC,aAAc,CAAA,GAAGnB,QAAiBoB,CAAAA,aAAAA,CAAAA;;AAGrD,IAAA,MAAMC,eAAkB,GAAA,IAAA;QACtB,IAAIH,UAAAA,CAAWI,IAAI,EAAI,EAAA;YACrBC,cAAeL,CAAAA,UAAAA,CAAAA;YACfF,oBAAqB,CAAA,KAAA,CAAA;AACvB;AACF,KAAA;;AAGA,IAAA,IAAID,iBAAmB,EAAA;AACrB,QAAA,qBACEZ,IAACqB,CAAAA,IAAAA,EAAAA;YAAKC,SAAU,EAAA,QAAA;YAASC,GAAK,EAAA,CAAA;YAAGC,UAAW,EAAA,OAAA;;8BAC1CxB,IAACqB,CAAAA,IAAAA,EAAAA;oBAAKC,SAAU,EAAA,QAAA;oBAASC,GAAK,EAAA,CAAA;oBAAGC,UAAW,EAAA,OAAA;;sCAC1CrB,GAACsB,CAAAA,UAAAA,EAAAA;4BAAWC,OAAQ,EAAA,MAAA;AACjBlB,4BAAAA,QAAAA,EAAAA,CAAAA,CAAE,+BAAiC,EAAA,uBAAA;;sCAEtCL,GAACsB,CAAAA,UAAAA,EAAAA;4BAAWC,OAAQ,EAAA,OAAA;4BAAQC,SAAU,EAAA,YAAA;AACnCnB,4BAAAA,QAAAA,EAAAA,CAAAA,CACC,qCACA,EAAA,0HAAA;;sCAGJL,GAACyB,CAAAA,IAAAA,EAAAA;4BACCC,IAAK,EAAA,sFAAA;4BACLC,UAAU,EAAA,IAAA;AAETtB,4BAAAA,QAAAA,EAAAA,CAAAA,CAAE,8BAAgC,EAAA,8BAAA;;;;8BAIvCL,GAAC4B,CAAAA,GAAAA,EAAAA;oBAAIC,KAAM,EAAA,MAAA;AACT,oBAAA,QAAA,gBAAA7B,GAAC8B,CAAAA,SAAAA,EAAAA;wBACCC,IAAK,EAAA,aAAA;AACLC,wBAAAA,WAAAA,EAAa3B,EAAE,qCAAuC,EAAA,uBAAA,CAAA;AACtD4B,wBAAAA,YAAAA,EAAY5B,EAAE,qCAAuC,EAAA,uBAAA,CAAA;wBACrDN,KAAOa,EAAAA,UAAAA;AACPsB,wBAAAA,QAAAA,EAAU,CAACC,CAAMtB,GAAAA,aAAAA,CAAcsB,CAAEC,CAAAA,MAAM,CAACrC,KAAK,CAAA;wBAC7C8B,KAAM,EAAA,MAAA;wBACNQ,QAAU9B,EAAAA,SAAAA;wBACV+B,IAAK,EAAA;;;8BAITzC,IAACqB,CAAAA,IAAAA,EAAAA;oBAAKE,GAAK,EAAA,CAAA;;sCACTpB,GAACuC,CAAAA,MAAAA,EAAAA;4BAAOC,OAASzB,EAAAA,eAAAA;4BAAiBsB,QAAU,EAAA,CAACzB,WAAWI,IAAI,EAAA;4BAAIO,OAAQ,EAAA,WAAA;AACrElB,4BAAAA,QAAAA,EAAAA,CAAAA,CAAE,8BAAgC,EAAA,YAAA;;sCAErCL,GAACuC,CAAAA,MAAAA,EAAAA;AACCC,4BAAAA,OAAAA,EAAS,IAAM9B,oBAAqB,CAAA,KAAA,CAAA;4BACpCa,OAAQ,EAAA,UAAA;AACRc,4BAAAA,QAAAA,EAAU,CAAC1B,aAAAA,EAAAA;AAEVN,4BAAAA,QAAAA,EAAAA,CAAAA,CAAE,0BAA4B,EAAA,QAAA;;;;;;AAKzC;;AAGA,IAAA,qBACER,IAACqB,CAAAA,IAAAA,EAAAA;QAAKC,SAAU,EAAA,QAAA;QAASC,GAAK,EAAA,CAAA;QAAGC,UAAW,EAAA,OAAA;;0BAC1CxB,IAACqB,CAAAA,IAAAA,EAAAA;gBAAKC,SAAU,EAAA,QAAA;gBAASC,GAAK,EAAA,CAAA;gBAAGC,UAAW,EAAA,OAAA;gBAAQQ,KAAM,EAAA,MAAA;;kCACxDhC,IAACqB,CAAAA,IAAAA,EAAAA;wBAAKuB,cAAe,EAAA,eAAA;wBAAgBpB,UAAW,EAAA,QAAA;wBAASQ,KAAM,EAAA,MAAA;;0CAC7D7B,GAACsB,CAAAA,UAAAA,EAAAA;gCAAWC,OAAQ,EAAA,MAAA;AACjBlB,gCAAAA,QAAAA,EAAAA,CAAAA,CAAE,yBAA2B,EAAA,qBAAA;;0CAEhCL,GAACuC,CAAAA,MAAAA,EAAAA;AAAOC,gCAAAA,OAAAA,EAAS,IAAM9B,oBAAqB,CAAA,IAAA,CAAA;gCAAOa,OAAQ,EAAA,UAAA;gCAAWmB,IAAK,EAAA,GAAA;AACxErC,gCAAAA,QAAAA,EAAAA,CAAAA,CAAE,8BAAgC,EAAA,gBAAA;;;;kCAGvCL,GAACsB,CAAAA,UAAAA,EAAAA;wBAAWC,OAAQ,EAAA,OAAA;wBAAQC,SAAU,EAAA,YAAA;AACnCnB,wBAAAA,QAAAA,EAAAA,CAAAA,CACC,+BACA,EAAA,0HAAA;;;;0BAKNL,GAAC4B,CAAAA,GAAAA,EAAAA;gBAAIC,KAAM,EAAA,MAAA;AACT,gBAAA,QAAA,gBAAA7B,GAAC8B,CAAAA,SAAAA,EAAAA;oBACCC,IAAK,EAAA,WAAA;AACLC,oBAAAA,WAAAA,EAAa3B,EAAE,mCAAqC,EAAA,iBAAA,CAAA;AACpD4B,oBAAAA,YAAAA,EAAY5B,EAAE,mCAAqC,EAAA,iBAAA,CAAA;oBACnDN,KAAOI,EAAAA,QAAAA;AACP+B,oBAAAA,QAAAA,EAAU,CAACC,CAAM/B,GAAAA,WAAAA,CAAY+B,CAAEC,CAAAA,MAAM,CAACrC,KAAK,CAAA;oBAC3C8B,KAAM,EAAA,MAAA;oBACNQ,QAAU9B,EAAAA,SAAAA;oBACV+B,IAAK,EAAA;;;;;AAWf,CAAA;AAYA,MAAMK,qBAAAA,GAAwB,CAAC,EAC7BC,MAAM,EACNC,cAAc,EACdC,iBAAiB,EACU,GAAA;IAC3B,MAAM,EAAEzC,CAAC,EAAE,GAAGC,eAAAA,EAAAA;;AAGd,IAAA,MAAMyC,eAAkB,GAAA,IAAA;AACtB,QAAA,IAAIF,cAAeG,CAAAA,MAAM,KAAKJ,MAAAA,CAAOI,MAAM,EAAE;;AAE3CF,YAAAA,iBAAAA,CAAkB,EAAE,CAAA;SACf,MAAA;;AAEL,YAAA,MAAMG,cAAcL,MAAOM,CAAAA,GAAG,CAAC,CAACC,GAAAA,GAAQA,IAAIC,EAAE,CAAA;YAC9CN,iBAAkBG,CAAAA,WAAAA,CAAAA;AACpB;AACF,KAAA;IAEA,IAAIL,MAAAA,CAAOI,MAAM,KAAK,CAAG,EAAA;AACvB,QAAA,qBACEhD,GAACkB,CAAAA,IAAAA,EAAAA;YAAKC,SAAU,EAAA,QAAA;YAASC,GAAK,EAAA,CAAA;YAAGC,UAAW,EAAA,QAAA;YAASgC,OAAS,EAAA,CAAA;AAC5D,YAAA,QAAA,gBAAArD,GAACsB,CAAAA,UAAAA,EAAAA;gBAAWC,OAAQ,EAAA,OAAA;AACjBlB,gBAAAA,QAAAA,EAAAA,CAAAA,CAAE,6BAA+B,EAAA,oCAAA;;;AAI1C;;AAGA,IAAA,MAAMiD,uBAAuB,CAACC,OAAAA,GAAAA;QAC5B,MAAMC,YAAAA,GAAeX,cAAeY,CAAAA,QAAQ,CAACF,OAAAA,CAAAA,GACzCV,cAAea,CAAAA,MAAM,CAAC,CAACN,EAAOA,GAAAA,EAAAA,KAAOG,OACrC,CAAA,GAAA;AAAIV,YAAAA,GAAAA,cAAAA;AAAgBU,YAAAA;AAAQ,SAAA;QAEhCT,iBAAkBU,CAAAA,YAAAA,CAAAA;AACpB,KAAA;AAEA,IAAA,qBACE3D,IAACqB,CAAAA,IAAAA,EAAAA;QAAKC,SAAU,EAAA,QAAA;QAASC,GAAK,EAAA,CAAA;QAAGC,UAAW,EAAA,OAAA;QAAQQ,KAAM,EAAA,MAAA;QAAO8B,MAAO,EAAA,kBAAA;;0BACtE9D,IAACqB,CAAAA,IAAAA,EAAAA;gBAAKuB,cAAe,EAAA,eAAA;gBAAgBZ,KAAM,EAAA,MAAA;gBAAOR,UAAW,EAAA,QAAA;;kCAC3DrB,GAACsB,CAAAA,UAAAA,EAAAA;wBAAWC,OAAQ,EAAA,MAAA;AACjBlB,wBAAAA,QAAAA,EAAAA,CAAAA,CAAE,iCAAmC,EAAA,yBAAA;;kCAExCR,IAACqB,CAAAA,IAAAA,EAAAA;wBAAKE,GAAK,EAAA,CAAA;wBAAGC,UAAW,EAAA,QAAA;;0CACvBxB,IAACyB,CAAAA,UAAAA,EAAAA;;AACEuB,oCAAAA,cAAAA,CAAeG,MAAM;AAAC,oCAAA,MAAA;AAAKJ,oCAAAA,MAAAA,CAAOI,MAAM;AAAC,oCAAA;;;0CAE5ChD,GAACuC,CAAAA,MAAAA,EAAAA;gCAAOC,OAASO,EAAAA,eAAAA;gCAAiBT,IAAK,EAAA,QAAA;gCAASf,OAAQ,EAAA,WAAA;0CAErDsB,cAAeG,CAAAA,MAAM,KAAKJ,MAAOI,CAAAA,MAAM,GACpC3C,CAAE,CAAA,gCAAA,EAAkC,cACpCA,CAAAA,GAAAA,CAAAA,CAAE,8BAAgC,EAAA,YAAA;;;;;;0BAK5CL,GAAC4B,CAAAA,GAAAA,EAAAA;gBAAIgC,YAAc,EAAA,CAAA;gBAAG/B,KAAM,EAAA,MAAA;gBAAOgC,KAAO,EAAA;oBAAEC,SAAW,EAAA;AAAO,iBAAA;wCAC5D9D,GAAA,CAAC+D,KAAKC,IAAI,EAAA;oBAAC5C,GAAK,EAAA,CAAA;8BACbwB,MAAOM,CAAAA,GAAG,CAAC,CAACe,KAAOC,EAAAA,KAAAA,GAAAA;AAClB,wBAAA,MAAMC,UAAatB,GAAAA,cAAAA,CAAeY,QAAQ,CAACQ,MAAMb,EAAE,CAAA;wBACnD,qBACEpD,GAAA,CAAC+D,KAAKK,IAAI,EAAA;4BAAgBC,GAAK,EAAA,CAAA;4BAAGhB,OAAS,EAAA,KAAA;AACzC,4BAAA,QAAA,gBAAArD,GAACsE,CAAAA,YAAAA,EAAAA;AACCC,gCAAAA,QAAAA,EAAUN,MAAMO,GAAG;gCACnBC,SAAWR,EAAAA,KAAAA,CAAMS,QAAQ,IAAI,CAAC,MAAM,EAAER,KAAAA,GAAQ,EAAE,CAAC;gCACjDS,QAAUR,EAAAA,UAAAA;gCACVS,QAAU,EAAA,IAAMtB,oBAAqBW,CAAAA,KAAAA,CAAMb,EAAE;;AALjCa,yBAAAA,EAAAA,KAAAA,CAAMb,EAAE,CAAA;AAS5B,qBAAA;;;;;AAKV,CAAA;AAEA;;2GAGanD,gBAAmB,GAAA,IAAA;AAC9B,IAAA,MAAM,CAACE,QAAAA,EAAUC,WAAY,CAAA,GAAGV,QAAiB,CAAA,EAAA,CAAA;AACjD,IAAA,MAAM,CAACmF,WAAAA,EAAaC,cAAe,CAAA,GAAGpF,SAAuB,EAAE,CAAA;AAC/D,IAAA,MAAM,CAACmD,cAAAA,EAAgBC,iBAAkB,CAAA,GAAGpD,SAAmB,EAAE,CAAA;IACjE,MAAM,EAAEW,CAAC,EAAE,GAAGC,eAAAA,EAAAA;IAEd,MAAM,EAAEyE,cAAc,EAAE,GAAGC,cAAAA,EAAAA;AAC3B,IAAA,MAAM,EAAEjG,iBAAiB,EAAEG,gBAAgB,EAAEF,cAAc,EAAE,GAAGG,oBAAAA,EAAAA;IAChE,MAAM,EAAE8F,KAAK,EAAEC,QAAQ,EAAEC,WAAW,EAAEC,WAAW,EAAEC,QAAQ,EAAE,GAAGC,aAAAA,EAAAA;IAChE,MAAM,EAAEC,eAAe,EAAEhF,SAAS,EAAEiF,KAAK,EAAE,GAAGC,cAAe,CAAA;AAC3DC,QAAAA,SAAAA,EAAW,CAAC9C,MAAAA,GAAAA;YACVkC,cAAelC,CAAAA,MAAAA,CAAAA;;YAEf,MAAM+C,gBAAAA,GAAmB/C,MAAOgD,CAAAA,KAAK,CAAC,CAAA,EAAG,EAAI1C,CAAAA,CAAAA,GAAG,CAAC,CAACC,GAAQA,GAAAA,GAAAA,CAAIC,EAAE,CAAA;YAChEN,iBAAkB6C,CAAAA,gBAAAA,CAAAA;AACpB;AACF,KAAA,CAAA;AAEA,IAAA,MAAME,gBAAmB,GAAA,UAAA;AACvB,QAAA,MAAMN,eAAgBpF,CAAAA,QAAAA,CAAAA;QACtB,OAAO,IAAA;AACT,KAAA;;AAGA,IAAA,MAAM2F,kBAAkB,CAACtB,GAAAA,GAAAA;QACvB,IAAI,CAACA,KAAK,OAAO,KAAA;QACjB,IAAI;YACF,MAAMuB,MAAAA,GAAS,IAAIC,GAAIxB,CAAAA,GAAAA,CAAAA;AACvB,YAAA,OAAOuB,OAAOE,QAAQ,KAAK,eAAmBF,IAAAA,MAAAA,CAAOE,QAAQ,KAAK,WAAA;AACpE,SAAA,CAAE,OAAO9D,CAAG,EAAA;YACV,OAAO,KAAA;AACT;AACF,KAAA;AAEA,IAAA,MAAM+D,YAAe,GAAA,IAAA;;QAEnB9F,WAAY,CAAA,EAAA,CAAA;AACZ0E,QAAAA,cAAAA,CAAe,EAAE,CAAA;AACjBhC,QAAAA,iBAAAA,CAAkB,EAAE,CAAA;AACpB5D,QAAAA,gBAAAA,EAAAA;AACF,KAAA;AAEA,IAAA,MAAMiH,cAAiB,GAAA,IAAA;;QAErB,MAAMC,mBAAAA,GAAsBvB,WAAYnB,CAAAA,MAAM,CAAC,CAACP,MAAQN,cAAeY,CAAAA,QAAQ,CAACN,GAAAA,CAAIC,EAAE,CAAA,CAAA;QACtF,IAAIgD,mBAAAA,CAAoBpD,MAAM,KAAK,CAAG,EAAA;AACpC9D,YAAAA,gBAAAA,EAAAA;AACA,YAAA;AACF;;AAGAmG,QAAAA,QAAAA,EAAAA;AAEA,QAAA,IAAIrG,cAAgB,EAAA;;YAElBoG,WAAY,CAAA;gBACViB,IAAM,EAAA,MAAA;gBACNC,KAAO,EAAA;AACL,oBAAA;wBAAEhE,IAAM,EAAA,MAAA;wBAAQiE,IAAM,EAAA;AAA0C,qBAAA;AAC7DH,oBAAAA,GAAAA;AACJ;AACH,aAAA,CAAA;AAEAlH,YAAAA,gBAAAA,EAAAA;SACK,MAAA;;AAEL,YAAA,IAAI,CAAC+F,KAAO,EAAA;gBACVC,QAAS,CAAA,yCAAA,CAAA;AACX;YACAH,cAAeqB,CAAAA,mBAAAA,CAAAA;AACflH,YAAAA,gBAAAA,EAAAA;AACF;AACF,KAAA;AAEA,IAAA,qBACEW,IAAC2G,CAAAA,SAAAA,EAAAA;QACCC,IAAM1H,EAAAA,iBAAAA;AACN2H,QAAAA,YAAAA,EAAc,CAACC,MAAAA,GAAAA;AACb,YAAA,IAAI,CAACA,MAAQT,EAAAA,YAAAA,EAAAA;AACf,SAAA;AACAU,QAAAA,KAAAA,EAAOvG,EAAE,0BAA4B,EAAA,mBAAA,CAAA;QACrCwG,QAAUX,EAAAA,YAAAA;QACVY,UAAYX,EAAAA,cAAAA;;AAEZ,0BAAAnG,GAAA,CAACwG,UAAUO,IAAI,EAAA;AACbH,gBAAAA,KAAAA,EAAOvG,EAAE,+BAAiC,EAAA,iBAAA,CAAA;AAC1C2G,gBAAAA,SAAAA,EAAW3G,EAAE,iCAAmC,EAAA,QAAA,CAAA;AAChD4G,gBAAAA,WAAAA,EAAa5G,EAAE,oBAAsB,EAAA,QAAA,CAAA;AACrC6G,gBAAAA,WAAAA,EAAa,CAAC/G,QAAAA,IAAYI,SAAa,IAAA,CAACuF,eAAgB3F,CAAAA,QAAAA,CAAAA;gBACxDgH,MAAQtB,EAAAA,gBAAAA;AAER,gBAAA,QAAA,gBAAA7F,GAACE,CAAAA,iBAAAA,EAAAA;oBAAkBC,QAAUA,EAAAA,QAAAA;oBAAUC,WAAaA,EAAAA,WAAAA;oBAAaoF,KAAOA,EAAAA;;;AAG1E,0BAAAxF,GAAA,CAACwG,UAAUO,IAAI,EAAA;AACbH,gBAAAA,KAAAA,EAAOvG,EAAE,+BAAiC,EAAA,gBAAA,CAAA;AAC1C2G,gBAAAA,SAAAA,EAAW3G,EAAE,oBAAsB,EAAA,QAAA,CAAA;AACnC+G,gBAAAA,SAAAA,EAAW/G,EAAE,kBAAoB,EAAA,MAAA,CAAA;gBACjC6G,WAAarE,EAAAA,cAAAA,CAAeG,MAAM,KAAK,CAAA;AAEvC,gBAAA,QAAA,gBAAAhD,GAAC2C,CAAAA,qBAAAA,EAAAA;oBACCC,MAAQiC,EAAAA,WAAAA;oBACRhC,cAAgBA,EAAAA,cAAAA;oBAChBC,iBAAmBA,EAAAA;;;;;AAK7B;;;;"}
|
|
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":"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"}
|
|
@@ -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":"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"}
|
|
@@ -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;;;;"}
|