Enhance TemplateEditor and TemplatePreview Components with Layout Improvements
- Added minWidth property to the TemplateEditor component for better layout control. - Introduced a responsive toolbar in the TemplatePreview component, utilizing Popover for improved UI on smaller screens. - Implemented a ResizeObserver to dynamically adjust toolbar settings based on available width, enhancing user experience. - Refactored toolbar content handling to streamline button interactions and improve accessibility.
This commit is contained in:
parent
ae1194efb9
commit
7df004ac47
@ -110,6 +110,7 @@ const TemplateEditor = ({
|
||||
const [previewError, setPreviewError] = useState(false)
|
||||
const [errorLines, setErrorLines] = useState([])
|
||||
const [formatLoading, setFormatLoading] = useState(false)
|
||||
|
||||
//const isMobile = useMediaQuery({ maxWidth: 768 })
|
||||
|
||||
const handlePreviewMessage = useCallback((message, isError) => {
|
||||
@ -256,7 +257,8 @@ const TemplateEditor = ({
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
flex: '1 1 auto',
|
||||
minHeight: 0
|
||||
minHeight: 0,
|
||||
minWidth: 0
|
||||
}}
|
||||
useFormItem={false}
|
||||
name={'content'}
|
||||
|
||||
@ -7,7 +7,7 @@ import {
|
||||
useCallback
|
||||
} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Flex, Button, Input, Select, Card } from 'antd'
|
||||
import { Flex, Button, Input, Select, Card, Popover } from 'antd'
|
||||
import PlusIcon from '../../Icons/PlusIcon.jsx'
|
||||
import MinusIcon from '../../Icons/MinusIcon.jsx'
|
||||
import InfoCircleIcon from '../../Icons/InfoCircleIcon.jsx'
|
||||
@ -18,7 +18,7 @@ import PDFViewer from './PDFViewer.jsx'
|
||||
import ScrollBox from './ScrollBox.jsx'
|
||||
import { ApiServerContext } from '../context/ApiServerContext.jsx'
|
||||
import ProgressDisplay from './ProgressDisplay.jsx'
|
||||
|
||||
import { CaretDownFilled } from '@ant-design/icons'
|
||||
const noop = () => {}
|
||||
|
||||
const TemplatePreview = ({
|
||||
@ -56,6 +56,27 @@ const TemplatePreview = ({
|
||||
height: 'auto'
|
||||
})
|
||||
|
||||
const toolbarRef = useRef(null)
|
||||
const [usePopoverSettings, setUsePopoverSettings] = useState(false)
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const toolbar = toolbarRef.current
|
||||
if (!toolbar) return undefined
|
||||
|
||||
const updateLayout = () => {
|
||||
const { width, height } = toolbar.getBoundingClientRect()
|
||||
console.log('Preview card size', { width, height })
|
||||
setUsePopoverSettings(width < 620)
|
||||
}
|
||||
|
||||
updateLayout()
|
||||
|
||||
const observer = new ResizeObserver(updateLayout)
|
||||
observer.observe(toolbar)
|
||||
|
||||
return () => observer.disconnect()
|
||||
}, [])
|
||||
|
||||
const applyIframeContentSize = useCallback(() => {
|
||||
const iframe = iframeRef.current
|
||||
const doc = iframe?.contentDocument
|
||||
@ -474,9 +495,70 @@ const TemplatePreview = ({
|
||||
|
||||
const showProgressOverlay = previewType != 'HTML' && downloadProgress != null
|
||||
|
||||
const toolbarContent = (
|
||||
<>
|
||||
<Button
|
||||
icon={
|
||||
panMode ? (
|
||||
<PanFilledIcon style={{ color: 'var(--color-primary)' }} />
|
||||
) : (
|
||||
<PanIcon />
|
||||
)
|
||||
}
|
||||
disabled={loading || reloadLoading}
|
||||
onClick={() => {
|
||||
setPanMode((prev) => !prev)
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
icon={<PlusIcon />}
|
||||
onClick={() => {
|
||||
setPreviewScale((prev) => prev + 0.05)
|
||||
}}
|
||||
disabled={loading || reloadLoading}
|
||||
/>
|
||||
<Button
|
||||
readOnly={true}
|
||||
style={{ width: '65px' }}
|
||||
disabled={loading || reloadLoading}
|
||||
onClick={() => {
|
||||
setPreviewScale(1)
|
||||
}}
|
||||
>
|
||||
{previewScale.toFixed(2)}x
|
||||
</Button>
|
||||
<Button
|
||||
icon={<MinusIcon />}
|
||||
onClick={() => {
|
||||
setPreviewScale((prev) => Math.max(0.1, prev - 0.05))
|
||||
}}
|
||||
disabled={loading || reloadLoading}
|
||||
/>
|
||||
{showPreviewSwitch == true ? (
|
||||
<Select
|
||||
options={[
|
||||
{ value: 'HTML', label: 'HTML' },
|
||||
{ value: 'PDF', label: 'PDF' }
|
||||
]}
|
||||
style
|
||||
loading={(loading || reloadLoading) && !usePopoverSettings}
|
||||
disabled={loading || reloadLoading}
|
||||
value={previewType}
|
||||
onChange={(value) => {
|
||||
if (value == 'PDF') {
|
||||
clearIframeContents()
|
||||
setPDFBlob(null)
|
||||
}
|
||||
setPreviewType(value)
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
|
||||
return (
|
||||
<Flex vertical gap={'middle'} style={{ height: '100%' }}>
|
||||
<Flex gap={'small'}>
|
||||
<Flex gap={'small'} ref={toolbarRef}>
|
||||
{showTestObject == true ? (
|
||||
<>
|
||||
{documentTemplate?.objectType ? (
|
||||
@ -503,63 +585,21 @@ const TemplatePreview = ({
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
<Button
|
||||
icon={
|
||||
panMode ? (
|
||||
<PanFilledIcon style={{ color: 'var(--color-primary)' }} />
|
||||
) : (
|
||||
<PanIcon />
|
||||
)
|
||||
}
|
||||
disabled={loading || reloadLoading}
|
||||
onClick={() => {
|
||||
setPanMode((prev) => !prev)
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
icon={<PlusIcon />}
|
||||
onClick={() => {
|
||||
setPreviewScale((prev) => prev + 0.05)
|
||||
}}
|
||||
disabled={loading || reloadLoading}
|
||||
/>
|
||||
<Button
|
||||
icon={<MinusIcon />}
|
||||
onClick={() => {
|
||||
setPreviewScale((prev) => Math.max(0.1, prev - 0.05))
|
||||
}}
|
||||
disabled={loading || reloadLoading}
|
||||
/>
|
||||
<Button
|
||||
readOnly={true}
|
||||
style={{ width: '65px' }}
|
||||
disabled={loading || reloadLoading}
|
||||
onClick={() => {
|
||||
setPreviewScale(1)
|
||||
}}
|
||||
>
|
||||
{previewScale.toFixed(2)}x
|
||||
</Button>
|
||||
{showPreviewSwitch == true ? (
|
||||
<Select
|
||||
options={[
|
||||
{ value: 'HTML', label: 'HTML' },
|
||||
{ value: 'PDF', label: 'PDF' }
|
||||
]}
|
||||
style
|
||||
loading={loading || reloadLoading}
|
||||
disabled={loading || reloadLoading}
|
||||
value={previewType}
|
||||
onChange={(value) => {
|
||||
if (value == 'PDF') {
|
||||
clearIframeContents()
|
||||
setPDFBlob(null)
|
||||
}
|
||||
setPreviewType(value)
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
{!usePopoverSettings ? (
|
||||
toolbarContent
|
||||
) : (
|
||||
<Popover
|
||||
content={<Flex gap={'small'}>{toolbarContent}</Flex>}
|
||||
trigger={['hover', 'click']}
|
||||
placement='bottomRight'
|
||||
arrow={false}
|
||||
>
|
||||
<Button
|
||||
icon={<CaretDownFilled />}
|
||||
loading={loading || reloadLoading}
|
||||
/>
|
||||
</Popover>
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
<div
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user