Projekt

Obecné

Profil

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

    
25
// Page with tracking tool
26
const TrackingTool = () => {
27
    const dispatch = useDispatch()
28

    
29
    // Path response from the API
30
    const pathDto = useSelector(
31
        (state: RootState) => state.trackingTool.pathDto
32
    )
33
    const pathVariants = useSelector(
34
        (state: RootState) => state.trackingTool.pathVariants
35
    )
36
    const mapCenter = useSelector(
37
        (state: RootState) => state.trackingTool.mapCenter
38
    )
39

    
40
    // Consume any error
41
    const err = useSelector((state: RootState) => state.trackingTool.lastError)
42
    useEffect(() => {
43
        if (!err) {
44
            return
45
        }
46
        const error = `${err}`
47
        dispatch(consumeError())
48
        dispatch(
49
            showNotification({
50
                message: error,
51
                severity: 'error',
52
            })
53
        )
54
    }, [err, dispatch])
55

    
56
    const mapRef = useRef<Map | undefined>(undefined)
57
    useEffect(() => {
58
        if (!mapRef || !mapRef.current) {
59
            console.log('No map ref')
60
            return
61
        }
62

    
63
        const map = mapRef.current
64
        map.setView(mapCenter, mapConfig.defaultZoom, {
65
            animate: true,
66
        })
67
    }, [mapCenter, mapRef])
68

    
69
    return (
70
        <Fragment>
71
            <Typography variant="h3" sx={{ mb: 2 }} fontWeight="bold">
72
                Tracking Tool
73
            </Typography>
74

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

    
113
                    {pathDto && (
114
                        <Stack alignItems="flex-end">
115
                            <Button
116
                                startIcon={<ClearIcon />}
117
                                sx={{ mb: 1 }}
118
                                variant="contained"
119
                                onClick={() => dispatch(clear())}
120
                            >
121
                                Clear Map
122
                            </Button>
123
                        </Stack>
124
                    )}
125
                </Grid>
126

    
127
                <Grid
128
                    item
129
                    xs={12}
130
                    md={12}
131
                    style={{
132
                        minHeight: '60vh',
133
                        maxHeight: '100vh',
134
                        width: '100%',
135
                    }}
136
                >
137
                    <MapContainer
138
                        center={[mapCenter[0], mapCenter[1]]}
139
                        zoom={mapConfig.defaultZoom}
140
                        style={{ height: '100%', minHeight: '100%' }}
141
                        whenCreated={(map) => {
142
                            mapRef.current = map
143
                        }}
144
                    >
145
                        <TileLayer
146
                            attribution={mapConfig.attribution}
147
                            url={mapConfig.url}
148
                        />
149
                        {pathVariants?.map((pathVariant, idx) => (
150
                            <MapPath idx={idx} />
151
                        ))}
152
                    </MapContainer>
153
                    {pathDto && (
154
                        <Fragment>
155
                            <Card variant="outlined" sx={{ mt: 2 }}>
156
                                <CardContent>
157
                                    <Stack direction="column">
158
                                        <Typography
159
                                            variant="h5"
160
                                            sx={{ mb: 1 }}
161
                                            fontWeight="600"
162
                                        >
163
                                            Processed Text
164
                                        </Typography>
165
                                        <Typography variant="body2">
166
                                            {formatHtmlStringToReactDom(
167
                                                pathDto.text ?? ''
168
                                            )}
169
                                        </Typography>
170
                                    </Stack>
171
                                </CardContent>
172
                            </Card>
173
                        </Fragment>
174
                    )}
175
                </Grid>
176
            </Grid>
177
        </Fragment>
178
    )
179
}
180

    
181
export default TrackingTool
(4-4/8)