use Dialog for MapPrint

This commit is contained in:
2025-09-25 17:12:10 +09:00
parent 2ffd94bd5b
commit bdab63f1bb

View File

@ -1,4 +1,4 @@
import { IconHelp, IconWindowMaximize, IconWindowMinimize, IconX } from '@tabler/icons-react' import { IconHelp, IconWindowMaximize, IconWindowMinimize } from '@tabler/icons-react'
import React, { useEffect, useRef, useState } from 'react' import React, { useEffect, useRef, useState } from 'react'
import { clearPrintArea, PrintScale, setPreviousView, setPrintScale, setPrintScaleLine, useMapStore } from '../../../store/map' import { clearPrintArea, PrintScale, setPreviousView, setPrintScale, setPrintScaleLine, useMapStore } from '../../../store/map'
import { PrintFormat, PrintOrientation, printResolutions, setPrintOrientation, setPrintResolution, usePrintStore } from '../../../store/print' import { PrintFormat, PrintOrientation, printResolutions, setPrintOrientation, setPrintResolution, usePrintStore } from '../../../store/print'
@ -8,7 +8,8 @@ import { useObjectsStore } from '../../../store/objects'
import jsPDF from 'jspdf' import jsPDF from 'jspdf'
import { getCenter } from 'ol/extent' import { getCenter } from 'ol/extent'
import ScaleLine from 'ol/control/ScaleLine' import ScaleLine from 'ol/control/ScaleLine'
import { Button, Checkbox, Dropdown, Field, Option, Radio, RadioGroup, Text } from '@fluentui/react-components' import { Button, Checkbox, Dialog, DialogActions, DialogBody, DialogContent, DialogSurface, DialogTitle, Dropdown, Field, Option, Radio, RadioGroup, Text } from '@fluentui/react-components'
import { Dismiss24Regular } from '@fluentui/react-icons'
const MapPrint = ({ const MapPrint = ({
id, id,
@ -116,8 +117,11 @@ const MapPrint = ({
minWidth: 125 minWidth: 125
})) }))
const [opened, setOpened] = useState(false)
useEffect(() => { useEffect(() => {
if (printArea) { if (printArea && opened) {
// backup view before entering print mode // backup view before entering print mode
setPreviousView(id, map?.getView()) setPreviousView(id, map?.getView())
@ -130,7 +134,7 @@ const MapPrint = ({
}) })
map?.removeInteraction(printAreaDraw) map?.removeInteraction(printAreaDraw)
} }
}, [printArea, map]) }, [printArea, map, opened])
useEffect(() => { useEffect(() => {
if (printScaleLine && printArea) { if (printScaleLine && printArea) {
@ -140,8 +144,6 @@ const MapPrint = ({
} }
}, [printScaleLine, printArea]) }, [printScaleLine, printArea])
const [opened, setOpened] = useState(false)
useEffect(() => { useEffect(() => {
if (!!printArea) { if (!!printArea) {
setOpened(true) setOpened(true)
@ -157,98 +159,78 @@ const MapPrint = ({
}, [opened]) }, [opened])
return ( return (
<div <Dialog open={opened} defaultOpen={true}>
style={{ <DialogSurface style={{ maxWidth: fullscreen ? '100%' : 'fit-content', maxHeight: fullscreen ? '100%' : 'fit-content' }}>
display: opened ? 'flex' : 'none', <DialogBody>
position: fullscreen ? 'fixed' : 'fixed', <DialogTitle action={
zIndex: '9999', <div style={{ display: 'flex', marginLeft: 'auto', gap: '1.5rem' }}>
width: '100%', <Button appearance='subtle' title='Помощь' style={{ marginLeft: 'auto' }} icon={<IconHelp color='gray' />} />
height: '100%',
inset: 0,
justifyContent: 'center',
alignItems: 'center',
}}
>
<div style={{
display: 'flex',
flexDirection: 'column',
transition: 'all .3s ease',
width: fullscreen ? '100%' : 'auto',
height: fullscreen ? '100%' : 'fit-content',
background: 'var(--colorNeutralBackground1)',
border: '1px solid var(--colorNeutralShadowKey)',
}}>
<div style={{ display: 'flex', padding: '1rem', alignItems: 'center' }}>
<Text>
Предпросмотр области печати
</Text>
<div style={{ display: 'flex', marginLeft: 'auto', gap: '1.5rem' }}> <Button appearance='subtle' title={fullscreen ? 'Свернуть' : 'Развернуть'} style={{ marginLeft: 'auto' }} icon={fullscreen ? <IconWindowMinimize color='gray' /> : <IconWindowMaximize color='gray' />} onClick={() => setFullscreen(!fullscreen)} />
<Button appearance='subtle' title='Помощь' style={{ marginLeft: 'auto' }} icon={<IconHelp color='gray' />} />
<Button appearance='subtle' title={fullscreen ? 'Свернуть' : 'Развернуть'} style={{ marginLeft: 'auto' }} icon={fullscreen ? <IconWindowMinimize color='gray' /> : <IconWindowMaximize color='gray' />} onClick={() => setFullscreen(!fullscreen)} /> <Button appearance='subtle' title='Закрыть' icon={<Dismiss24Regular />} onClick={() => setOpened(false)} />
</div>
}>Предпросмотр области печати</DialogTitle>
<Button appearance='subtle' title='Закрыть' icon={<IconX />} onClick={() => setOpened(false)} /> <DialogContent>
</div> <div style={{ display: 'flex', width: 'fit-content', flexDirection: 'column', alignItems: 'center', height: 'fit-content', overflowY: 'auto' }}>
</div> <Text>Область печати можно передвигать.</Text>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', height: 'fit-content', overflow: 'auto' }}> <div id='print-portal' style={{
<Text>Область печати можно передвигать.</Text> width: printOrientation === 'horizontal' ? '594px' : '420px',
height: printOrientation === 'horizontal' ? '420px' : '594px',
flexShrink: '0'
}}>
<div id='print-portal' style={{ </div>
width: printOrientation === 'horizontal' ? '594px' : '420px',
height: printOrientation === 'horizontal' ? '420px' : '594px',
flexShrink: '0'
}}>
</div> <div style={{ display: 'flex', width: '100%', flexWrap: 'wrap', gap: '1rem', padding: '1rem', justifyContent: 'space-between', alignItems: 'flex-start' }}>
<Field label={'Ориентация'}>
<RadioGroup value={printOrientation} onChange={(_, data) => setPrintOrientation(data.value as PrintOrientation)}>
<Radio value='horizontal' label='Горизонтальная' />
<Radio value='vertical' label='Вертикальная' />
</RadioGroup>
</Field>
<div style={{ display: 'flex', width: '100%', flexWrap: 'wrap', gap: '1rem', padding: '1rem', justifyContent: 'space-between', alignItems: 'flex-start' }}> <Field label="Разрешение">
<Field label={'Ориентация'}> <Dropdown
<RadioGroup value={printOrientation} onChange={(_, data) => setPrintOrientation(data.value as PrintOrientation)}> defaultValue={printResolution.toString()}
<Radio value='horizontal' label='Горизонтальная' /> value={printResolution.toString()}
<Radio value='vertical' label='Вертикальная' /> selectedOptions={[printResolution.toString()]}
</RadioGroup> onOptionSelect={(_, data) => setPrintResolution(Number(data.optionValue))}
</Field> >
{printResolutions.map((res) => (
<Field label="Разрешение"> <Option key={res} text={res} value={res}>
<Dropdown {res}
defaultValue={printResolution.toString()} </Option>
value={printResolution.toString()} ))}
selectedOptions={[printResolution.toString()]} </Dropdown>
onOptionSelect={(_, data) => setPrintResolution(Number(data.optionValue))} </Field>
>
{printResolutions.map((res) => (
<Option key={res} text={res} value={res}>
{res}
</Option>
))}
</Dropdown>
</Field>
<Field label="Масштаб"> <Field label="Масштаб">
<Dropdown <Dropdown
value={printScale.toString()} value={printScale.toString()}
selectedOptions={[printScale]} selectedOptions={[printScale]}
onOptionSelect={(_, data) => setPrintScale(id, data.optionValue as PrintScale)} onOptionSelect={(_, data) => setPrintScale(id, data.optionValue as PrintScale)}
> >
{scaleOptions.map((opt) => ( {scaleOptions.map((opt) => (
<Option key={opt.value} text={opt.label} value={opt.value}> <Option key={opt.value} text={opt.label} value={opt.value}>
{opt.label} {opt.label}
</Option> </Option>
))} ))}
</Dropdown> </Dropdown>
</Field> </Field>
</div>
</div>
</DialogContent>
<DialogActions>
<Checkbox <Checkbox
checked={printScaleLine} checked={printScaleLine}
label="Масштабная линия" label="Масштабная линия"
onChange={(event) => setPrintScaleLine(id, event.currentTarget.checked)} onChange={(event) => setPrintScaleLine(id, event.currentTarget.checked)}
/> />
</div>
<div style={{ display: 'flex', width: '100%', gap: '1rem', padding: '1rem', alignItems: 'center' }}>
<Button style={{ marginLeft: 'auto' }} onClick={() => { <Button style={{ marginLeft: 'auto' }} onClick={() => {
if (previousView) { if (previousView) {
exportToPDF(printFormat, printResolution, printOrientation) exportToPDF(printFormat, printResolution, printOrientation)
@ -256,11 +238,117 @@ const MapPrint = ({
}}> }}>
Печать Печать
</Button> </Button>
</div> </DialogActions>
</div> </DialogBody>
</div> </DialogSurface>
</div> </Dialog>
) )
// return (
// <div
// style={{
// display: opened ? 'flex' : 'none',
// position: fullscreen ? 'fixed' : 'fixed',
// zIndex: '9999',
// width: '100%',
// height: '100%',
// inset: 0,
// justifyContent: 'center',
// alignItems: 'center',
// }}
// >
// <div style={{
// display: 'flex',
// flexDirection: 'column',
// transition: 'all .3s ease',
// width: fullscreen ? '100%' : 'auto',
// height: fullscreen ? '100%' : 'fit-content',
// background: 'var(--colorNeutralBackground1)',
// border: '1px solid var(--colorNeutralShadowKey)',
// }}>
// <div style={{ display: 'flex', padding: '1rem', alignItems: 'center' }}>
// <Text>
// Предпросмотр области печати
// </Text>
// <div style={{ display: 'flex', marginLeft: 'auto', gap: '1.5rem' }}>
// <Button appearance='subtle' title='Помощь' style={{ marginLeft: 'auto' }} icon={<IconHelp color='gray' />} />
// <Button appearance='subtle' title={fullscreen ? 'Свернуть' : 'Развернуть'} style={{ marginLeft: 'auto' }} icon={fullscreen ? <IconWindowMinimize color='gray' /> : <IconWindowMaximize color='gray' />} onClick={() => setFullscreen(!fullscreen)} />
// <Button appearance='subtle' title='Закрыть' icon={<IconX />} onClick={() => setOpened(false)} />
// </div>
// </div>
// <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', height: 'fit-content', overflow: 'auto' }}>
// <Text>Область печати можно передвигать.</Text>
// <div id='print-portal' style={{
// width: printOrientation === 'horizontal' ? '594px' : '420px',
// height: printOrientation === 'horizontal' ? '420px' : '594px',
// flexShrink: '0'
// }}>
// </div>
// <div style={{ display: 'flex', width: '100%', flexWrap: 'wrap', gap: '1rem', padding: '1rem', justifyContent: 'space-between', alignItems: 'flex-start' }}>
// <Field label={'Ориентация'}>
// <RadioGroup value={printOrientation} onChange={(_, data) => setPrintOrientation(data.value as PrintOrientation)}>
// <Radio value='horizontal' label='Горизонтальная' />
// <Radio value='vertical' label='Вертикальная' />
// </RadioGroup>
// </Field>
// <Field label="Разрешение">
// <Dropdown
// defaultValue={printResolution.toString()}
// value={printResolution.toString()}
// selectedOptions={[printResolution.toString()]}
// onOptionSelect={(_, data) => setPrintResolution(Number(data.optionValue))}
// >
// {printResolutions.map((res) => (
// <Option key={res} text={res} value={res}>
// {res}
// </Option>
// ))}
// </Dropdown>
// </Field>
// <Field label="Масштаб">
// <Dropdown
// value={printScale.toString()}
// selectedOptions={[printScale]}
// onOptionSelect={(_, data) => setPrintScale(id, data.optionValue as PrintScale)}
// >
// {scaleOptions.map((opt) => (
// <Option key={opt.value} text={opt.label} value={opt.value}>
// {opt.label}
// </Option>
// ))}
// </Dropdown>
// </Field>
// <Checkbox
// checked={printScaleLine}
// label="Масштабная линия"
// onChange={(event) => setPrintScaleLine(id, event.currentTarget.checked)}
// />
// </div>
// <div style={{ display: 'flex', width: '100%', gap: '1rem', padding: '1rem', alignItems: 'center' }}>
// <Button style={{ marginLeft: 'auto' }} onClick={() => {
// if (previousView) {
// exportToPDF(printFormat, printResolution, printOrientation)
// }
// }}>
// Печать
// </Button>
// </div>
// </div>
// </div>
// </div>
// )
} }
export default MapPrint export default MapPrint