NestJS backend rewrite; migrate client to FluentUI V9
This commit is contained in:
@ -1,5 +1,4 @@
|
||||
import { ActionIcon, Button, Checkbox, Flex, Modal, Radio, ScrollAreaAutosize, Select, Stack, Text } from '@mantine/core'
|
||||
import { IconHelp, IconWindowMaximize, IconWindowMinimize } from '@tabler/icons-react'
|
||||
import { IconHelp, IconWindowMaximize, IconWindowMinimize, IconX } from '@tabler/icons-react'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { clearPrintArea, PrintScale, setPreviousView, setPrintScale, setPrintScaleLine, useMapStore } from '../../../store/map'
|
||||
import { PrintFormat, PrintOrientation, printResolutions, setPrintOrientation, setPrintResolution, usePrintStore } from '../../../store/print'
|
||||
@ -9,6 +8,7 @@ import { useObjectsStore } from '../../../store/objects'
|
||||
import jsPDF from 'jspdf'
|
||||
import { getCenter } from 'ol/extent'
|
||||
import ScaleLine from 'ol/control/ScaleLine'
|
||||
import { Button, Checkbox, Dropdown, Field, Option, Radio, RadioGroup, Text } from '@fluentui/react-components'
|
||||
|
||||
const MapPrint = ({
|
||||
id,
|
||||
@ -140,94 +140,128 @@ const MapPrint = ({
|
||||
}
|
||||
}, [printScaleLine, printArea])
|
||||
|
||||
const [opened, setOpened] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!!printArea) {
|
||||
setOpened(true)
|
||||
}
|
||||
}, [printArea])
|
||||
|
||||
useEffect(() => {
|
||||
if (!opened) {
|
||||
clearPrintArea(id)
|
||||
map?.setTarget(mapElement.current as HTMLDivElement)
|
||||
map?.addInteraction(printAreaDraw)
|
||||
}
|
||||
}, [opened])
|
||||
|
||||
return (
|
||||
<Modal.Root
|
||||
scrollAreaComponent={ScrollAreaAutosize}
|
||||
keepMounted size='auto'
|
||||
opened={!!printArea}
|
||||
onClose={() => {
|
||||
clearPrintArea(id)
|
||||
map?.setTarget(mapElement.current as HTMLDivElement)
|
||||
map?.addInteraction(printAreaDraw)
|
||||
}} fullScreen={fullscreen}>
|
||||
<Modal.Overlay />
|
||||
<Modal.Content style={{ transition: 'all .3s ease' }}>
|
||||
<Modal.Header>
|
||||
<Modal.Title>
|
||||
<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>
|
||||
Предпросмотр области печати
|
||||
</Modal.Title>
|
||||
</Text>
|
||||
|
||||
<Flex ml='auto' gap='md'>
|
||||
<ActionIcon title='Помощь' ml='auto' variant='transparent'>
|
||||
<IconHelp color='gray' />
|
||||
</ActionIcon>
|
||||
<ActionIcon title={fullscreen ? 'Свернуть' : 'Развернуть'} variant='transparent' onClick={() => setFullscreen(!fullscreen)}>
|
||||
{fullscreen ? <IconWindowMinimize color='gray' /> : <IconWindowMaximize color='gray' />}
|
||||
</ActionIcon>
|
||||
<Modal.CloseButton title='Закрыть' />
|
||||
</Flex>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<Stack align='center'>
|
||||
<Text w='100%'>Область печати можно передвигать.</Text>
|
||||
<div style={{ display: 'flex', marginLeft: 'auto', gap: '1.5rem' }}>
|
||||
<Button appearance='subtle' title='Помощь' style={{ marginLeft: 'auto' }} icon={<IconHelp color='gray' />} />
|
||||
|
||||
<div id='print-portal' style={{
|
||||
width: printOrientation === 'horizontal' ? '594px' : '420px',
|
||||
height: printOrientation === 'horizontal' ? '420px' : '594px'
|
||||
}}>
|
||||
<Button appearance='subtle' title={fullscreen ? 'Свернуть' : 'Развернуть'} style={{ marginLeft: 'auto' }} icon={fullscreen ? <IconWindowMinimize color='gray' /> : <IconWindowMaximize color='gray' />} onClick={() => setFullscreen(!fullscreen)} />
|
||||
|
||||
</div>
|
||||
<Button appearance='subtle' title='Закрыть' icon={<IconX />} onClick={() => setOpened(false)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Flex w='100%' wrap='wrap' gap='lg' justify='space-between'>
|
||||
<Radio.Group
|
||||
label='Ориентация'
|
||||
value={printOrientation}
|
||||
onChange={(value) => setPrintOrientation(value as PrintOrientation)}
|
||||
>
|
||||
<Stack>
|
||||
<Radio value='horizontal' label='Горизонтальная' />
|
||||
<Radio value='vertical' label='Вертикальная' />
|
||||
</Stack>
|
||||
</Radio.Group>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', height: 'fit-content', overflow: 'auto' }}>
|
||||
<Text>Область печати можно передвигать.</Text>
|
||||
|
||||
<Select
|
||||
allowDeselect={false}
|
||||
label="Разрешение"
|
||||
placeholder="Выберите разрешение"
|
||||
data={printResolutions}
|
||||
<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()}
|
||||
onChange={(value) => setPrintResolution(Number(value))}
|
||||
/>
|
||||
selectedOptions={[printResolution.toString()]}
|
||||
onOptionSelect={(_, data) => setPrintResolution(Number(data.optionValue))}
|
||||
>
|
||||
{printResolutions.map((res) => (
|
||||
<Option key={res} text={res} value={res}>
|
||||
{res}
|
||||
</Option>
|
||||
))}
|
||||
</Dropdown>
|
||||
</Field>
|
||||
|
||||
<Select
|
||||
allowDeselect={false}
|
||||
label="Масштаб"
|
||||
placeholder="Выберите масштаб"
|
||||
data={scaleOptions}
|
||||
value={printScale}
|
||||
onChange={(value) => setPrintScale(id, value as PrintScale)}
|
||||
/>
|
||||
|
||||
<Checkbox
|
||||
checked={printScaleLine}
|
||||
label="Масштабная линия"
|
||||
onChange={(event) => setPrintScaleLine(id, event.currentTarget.checked)}
|
||||
/>
|
||||
</Flex>
|
||||
<Field label="Масштаб">
|
||||
<Dropdown
|
||||
defaultValue={printScale.toString()}
|
||||
value={printScale.toString()}
|
||||
defaultSelectedOptions={[printScale]}
|
||||
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>
|
||||
|
||||
<Flex w='100%' gap='sm' align='center'>
|
||||
<Button ml='auto' onClick={() => {
|
||||
if (previousView) {
|
||||
exportToPDF(printFormat, printResolution, printOrientation)
|
||||
}
|
||||
}}>
|
||||
Печать
|
||||
</Button>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</Modal.Body>
|
||||
</Modal.Content>
|
||||
</Modal.Root>
|
||||
<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>
|
||||
)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user