diff --git a/assets/icons/magicwandicon.svg b/assets/icons/magicwandicon.svg new file mode 100644 index 00000000..e50833c2 --- /dev/null +++ b/assets/icons/magicwandicon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/components/Dashboard/Management/DocumentTemplates/DocumentTemplateDesign.jsx b/src/components/Dashboard/Management/DocumentTemplates/DocumentTemplateDesign.jsx index 38ddce3d..87568335 100644 --- a/src/components/Dashboard/Management/DocumentTemplates/DocumentTemplateDesign.jsx +++ b/src/components/Dashboard/Management/DocumentTemplates/DocumentTemplateDesign.jsx @@ -135,7 +135,7 @@ const DocumentTemplateDesign = () => { setEditFormState((prev) => ({ ...prev, ...state })) }} > - {({ loading, isEditing, objectData }) => { + {({ loading, isEditing, objectData, form, setObjectData }) => { return ( { style={{ height: '72vh' }} collapseState={collapseState} isEditing={isEditing} + form={form} + setObjectData={setObjectData} /> ) }} diff --git a/src/components/Dashboard/common/CodeBlockEditor.jsx b/src/components/Dashboard/common/CodeBlockEditor.jsx index 01706fbb..d618e551 100644 --- a/src/components/Dashboard/common/CodeBlockEditor.jsx +++ b/src/components/Dashboard/common/CodeBlockEditor.jsx @@ -82,6 +82,7 @@ export function getCodeLanguageExtension( export default function CodeBlockEditor({ code = '', + value, language = 'javascript', style = {}, className = '', @@ -95,7 +96,8 @@ export default function CodeBlockEditor({ }) { const { isDarkMode } = useThemeContext() const [codeMirrorOpen, setCodeMirrorOpen] = useState(false) - const editorCode = toEditorCode(code, language) + const sourceCode = value !== undefined ? value : code + const editorCode = toEditorCode(sourceCode, language) const languageExtension = useMemo( () => getCodeLanguageExtension(language, autoCompleteObject), @@ -192,7 +194,8 @@ export default function CodeBlockEditor({ } CodeBlockEditor.propTypes = { - code: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, + code: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), + value: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), language: PropTypes.oneOfType([ PropTypes.string, PropTypes.arrayOf(PropTypes.string) diff --git a/src/components/Dashboard/common/TemplateEditor.jsx b/src/components/Dashboard/common/TemplateEditor.jsx index 1381b495..93bafb06 100644 --- a/src/components/Dashboard/common/TemplateEditor.jsx +++ b/src/components/Dashboard/common/TemplateEditor.jsx @@ -1,4 +1,4 @@ -import { useState, useCallback } from 'react' +import { useState, useCallback, useContext } from 'react' import PropTypes from 'prop-types' import { Flex, @@ -14,9 +14,11 @@ import { import { LoadingOutlined, CaretDownOutlined } from '@ant-design/icons' import ExclamationOctagonIcon from '../../Icons/ExclamationOctagonIcon.jsx' import CheckCircleIcon from '../../Icons/CheckCircleIcon.jsx' +import MagicWandIcon from '../../Icons/MagicWandIcon.jsx' import ObjectProperty from '../common/ObjectProperty.jsx' import TemplatePreview from './TemplatePreview.jsx' import DataTree from './DataTree.jsx' +import { ApiServerContext } from '../context/ApiServerContext.jsx' //import { useMediaQuery } from 'react-responsive' const TemplateEditor = ({ @@ -24,12 +26,16 @@ const TemplateEditor = ({ loading, collapseState, isEditing, - style + style, + form, + setObjectData }) => { + const { fetchTemplateFormat } = useContext(ApiServerContext) const [testObjectOpen, setTestObjectOpen] = useState(false) const [testObjectViewMode, setTestObjectViewMode] = useState('Tree') const [previewMessage, setPreviewMessage] = useState('No issues found.') const [previewError, setPreviewError] = useState(false) + const [formatLoading, setFormatLoading] = useState(false) //const isMobile = useMediaQuery({ maxWidth: 768 }) const handlePreviewMessage = useCallback((message, isError) => { @@ -67,6 +73,40 @@ const TemplateEditor = ({ setPreviewError(isError) }, []) + const handleFormatCode = useCallback(async () => { + const content = form?.getFieldValue?.('content') ?? objectData?.content + if (content == null || typeof content !== 'string') { + return + } + + setFormatLoading(true) + try { + const result = await fetchTemplateFormat(content) + if (result?.error) { + handlePreviewMessage(result.error, true) + return + } + + if (result?.content == null) { + return + } + + form?.setFieldValue?.('content', result.content) + setObjectData?.((prev) => ({ + ...prev, + content: result.content + })) + } finally { + setFormatLoading(false) + } + }, [ + form, + objectData?.content, + fetchTemplateFormat, + handlePreviewMessage, + setObjectData + ]) + return ( <> @@ -95,19 +135,33 @@ const TemplateEditor = ({ }> - - ) : ( - - ) - } - type={previewError ? 'error' : 'success'} - /> + + + ) : ( + + ) + } + type={previewError ? 'error' : 'success'} + /> + {isEditing && ( +