Projekt

Obecné

Profil

Stáhnout (6.37 KB) Statistiky
| Větev: | Tag: | Revize:
1
import {
2
    Button,
3
    Card,
4
    CardContent,
5
    Grid,
6
    Stack,
7
    ThemeProvider,
8
    Typography,
9
} from '@mui/material'
10
import { Fragment, useEffect, useRef } from 'react'
11
import { MapContainer, TileLayer } from 'react-leaflet'
12
import mapConfig from '../../config/mapConfig'
13
import PlaintextUpload from './Upload/PlaintextUpload'
14
import FileUpload from './Upload/FileUpload'
15
import { Map } from 'leaflet'
16
import { formatHtmlStringToReactDom } from '../../utils/formatting/HtmlUtils'
17
import MapPath from './Map/MapPath'
18
import { useDispatch, useSelector } from 'react-redux'
19
import { RootState } from '../redux/store'
20
import { clear, consumeErr as consumeError } from './trackingToolSlice'
21
import { showNotification } from '../Notification/notificationSlice'
22
import ClearIcon from '@mui/icons-material/Clear'
23
import GeoJsonExportButton from './Upload/GeoJsonExportButton'
24
import GeoJsonImportDialog from './Upload/GeoJsonImportDialog'
25
import ProcessedTextDisplay from './ProcessedText/ProcessedTextDisplay'
26
import MapPointDraggableList from './MapPointDraggableList/MapPointDraggableList'
27
import RightClickPopupMenu from './Import/ImportContextMenu'
28
import { buildTheme, getPalette } from '../Theme/ThemeWrapper'
29
import AttachFileIcon from '@mui/icons-material/AttachFile'
30

    
31
const mapTheme = buildTheme('light')
32

    
33
// Page with tracking tool
34
const TrackingTool = () => {
35
    const dispatch = useDispatch()
36

    
37
    // Path response from the API
38
    const pathDto = useSelector(
39
        (state: RootState) => state.trackingTool.pathDto
40
    )
41
    const pathVariants = useSelector(
42
        (state: RootState) => state.trackingTool.pathVariants
43
    )
44
    const mapCenter = useSelector(
45
        (state: RootState) => state.trackingTool.mapCenter
46
    )
47

    
48
    // Consume any error
49
    const err = useSelector((state: RootState) => state.trackingTool.lastError)
50
    useEffect(() => {
51
        if (!err) {
52
            return
53
        }
54
        const error = `${err}`
55
        dispatch(consumeError())
56
        dispatch(
57
            showNotification({
58
                message: error,
59
                severity: 'error',
60
            })
61
        )
62
    }, [err, dispatch])
63

    
64
    const mapRef = useRef<Map | undefined>(undefined)
65
    useEffect(() => {
66
        if (!mapRef || !mapRef.current) {
67
            console.log('No map ref')
68
            return
69
        }
70

    
71
        const map = mapRef.current
72
        map.setView(mapCenter, mapConfig.defaultZoom, {
73
            animate: true,
74
        })
75
    }, [mapCenter, mapRef])
76

    
77
    return (
78
        <Fragment>
79
            <Typography variant="h3" sx={{ mb: 2 }} fontWeight="bold">
80
                Tracking Tool
81
            </Typography>
82

    
83
            <Grid container>
84
                <Grid item xs={12}>
85
                    {pathDto && pathDto?.foundCatalogItems?.length === 0 && (
86
                        <Typography
87
                            variant="body1"
88
                            sx={{ mb: 2 }}
89
                            fontWeight="500"
90
                            align="center"
91
                            color="error.main"
92
                        >
93
                            Looks like no path / catalog items match this query.
94
                        </Typography>
95
                    )}
96
                    <Stack
97
                        direction="row"
98
                        alignItems="flex-start"
99
                        spacing={2}
100
                        sx={{ mt: 1 }}
101
                    >
102
                        {!pathDto && (
103
                            <Fragment>
104
                                <Typography
105
                                    variant="h5"
106
                                    sx={{ mb: 2 }}
107
                                    fontWeight="500"
108
                                >
109
                                    Upload:
110
                                </Typography>
111
                                <PlaintextUpload />
112
                                <FileUpload />
113
                            </Fragment>
114
                        )}
115
                        {pathVariants && pathVariants.length > 0 && (
116
                            <Fragment>
117
                                <GeoJsonImportDialog />
118
                                <GeoJsonExportButton />
119
                            </Fragment>
120
                        )}
121
                    </Stack>
122

    
123
                    {pathDto && (
124
                        <Stack alignItems="flex-end">
125
                            <Button
126
                                startIcon={<ClearIcon />}
127
                                sx={{ mb: 1 }}
128
                                variant="contained"
129
                                onClick={() => dispatch(clear())}
130
                            >
131
                                Clear Map
132
                            </Button>
133
                        </Stack>
134
                    )}
135
                </Grid>
136

    
137
                <Grid
138
                    item
139
                    xs={12}
140
                    md={12}
141
                    style={{
142
                        minHeight: '60vh',
143
                        maxHeight: '100vh',
144
                        width: '100%',
145
                    }}
146
                >
147
                    <ThemeProvider theme={mapTheme}>
148
                        <MapContainer
149
                            center={[mapCenter[0], mapCenter[1]]}
150
                            zoom={mapConfig.defaultZoom}
151
                            style={{ height: '100%', minHeight: '100%' }}
152
                            whenCreated={(map) => {
153
                                mapRef.current = map
154
                            }}
155
                        >
156
                            <TileLayer
157
                                attribution={mapConfig.attribution}
158
                                url={mapConfig.url}
159
                            />
160
                            {pathVariants?.map((pathVariant, idx) => (
161
                                <MapPath idx={idx} />
162
                            ))}
163
                            <RightClickPopupMenu />
164
                        </MapContainer>
165
                    </ThemeProvider>
166
                </Grid>
167
                <Grid container sx={{ mt: 1, mb: 20 }} spacing={1}>
168
                    <Grid item xs={12} md={6}>
169
                        <MapPointDraggableList />
170
                    </Grid>
171
                    <Grid item xs={12} md={6}>
172
                        <ProcessedTextDisplay />
173
                    </Grid>
174
                </Grid>
175
            </Grid>
176
        </Fragment>
177
    )
178
}
179

    
180
export default TrackingTool
(2-2/6)