Projekt

Obecné

Profil

Stáhnout (6.21 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 DraggableMarkerList from './DraggableList/DraggableMarkerList'
27
import RightClickPopupMenu from './Import/ImportContextMenu'
28
import { buildTheme, getPalette } from '../Theme/ThemeWrapper'
29

    
30
const mapTheme = buildTheme('light')
31

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

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

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

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

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

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

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

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

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

    
177
export default TrackingTool
(2-2/5)