Projekt

Obecné

Profil

Stáhnout (7.35 KB) Statistiky
| Větev: | Tag: | Revize:
1 a7ae217f Vaclav Honzik
import { Fragment, FunctionComponent, useEffect, useState } from 'react'
2
import { useDispatch, useSelector } from 'react-redux'
3 812b9f90 Vaclav Honzik
import { RootState } from '../../redux/store'
4 a7ae217f Vaclav Honzik
import { PathVariant, MapPoint, isMapPointDisplayable } from './pathUtils'
5
import TextPath from 'react-leaflet-textpath'
6 1e2f25c9 Vaclav Honzik
import { setPrimaryIdx, updateMapMarker, updateMapMarkerWithId } from '../trackingToolSlice'
7 a7ae217f Vaclav Honzik
import MapMarker from './MapMarker'
8
import { LatLngTuple } from 'leaflet'
9
import { Popup, Tooltip } from 'react-leaflet'
10
import { Checkbox, FormControlLabel, Stack, Typography } from '@mui/material'
11 812b9f90 Vaclav Honzik
import { formatHtmlStringToReactDom } from '../../../utils/formatting/HtmlUtils'
12
import { DialogCatalogItemDetail as CatalogItemDetailDialog } from '../../Catalog/CatalogItemDetail'
13 b70813cb Vaclav Honzik
14
export interface MapPathProps {
15 de12c6be Vaclav Honzik
    idx: number // index of the path in the list
16 b70813cb Vaclav Honzik
}
17
18 de12c6be Vaclav Honzik
type EdgeElement = any
19
20 b70813cb Vaclav Honzik
// Blue
21 a7ae217f Vaclav Honzik
export const primaryPathColor = '#346eeb'
22 b70813cb Vaclav Honzik
23
// Grey
24 a7ae217f Vaclav Honzik
export const secondaryPathColor = '#878e9c'
25 b70813cb Vaclav Honzik
26 de12c6be Vaclav Honzik
const MapPath: FunctionComponent<MapPathProps> = ({ idx }) => {
27 dd270a41 Vaclav Honzik
    const dispatch = useDispatch()
28 8c57f958 Vaclav Honzik
29 de12c6be Vaclav Honzik
    // Get list of all paths from the store
30
    // And extract path from them
31
    const paths = useSelector(
32
        (state: RootState) => state.trackingTool.pathVariants
33 8c57f958 Vaclav Honzik
    )
34 de12c6be Vaclav Honzik
    const [path, setPath] = useState<PathVariant>([])
35
    useEffect(() => {
36
        // Either set the path if it exists or set it to an empty array
37
        setPath(paths && paths.length > idx ? paths[idx] : [])
38 7b864a5c Vaclav Honzik
    }, [idx, paths])
39 de12c6be Vaclav Honzik
40
    // Primary path index to set the correct color
41 8c57f958 Vaclav Honzik
    const primaryPathIdx = useSelector(
42
        (state: RootState) => state.trackingTool.primaryPathIdx
43
    )
44
45 de12c6be Vaclav Honzik
    // List of all active map points
46
    const [displayableMapPoints, setDisplayableMapPoints] = useState<
47
        MapPoint[]
48
    >([])
49 8c57f958 Vaclav Honzik
    useEffect(() => {
50 de12c6be Vaclav Honzik
        // Set all displayable vertices
51 a7ae217f Vaclav Honzik
        setDisplayableMapPoints(
52
            path.filter((mapPoint) => isMapPointDisplayable(mapPoint))
53
        )
54 de12c6be Vaclav Honzik
    }, [path])
55 b70813cb Vaclav Honzik
56 de12c6be Vaclav Honzik
    // List of all edges in the path
57
    const [edges, setEdges] = useState<EdgeElement[]>([])
58 dd270a41 Vaclav Honzik
    useEffect(() => {
59 de12c6be Vaclav Honzik
        // Get all active map points
60
        const activeMapPoints = displayableMapPoints.filter(
61
            (item) => item.active
62 dd270a41 Vaclav Honzik
        )
63 b70813cb Vaclav Honzik
        if (activeMapPoints.length < 2) {
64 7b864a5c Vaclav Honzik
            setEdges([])
65 de12c6be Vaclav Honzik
            return
66 b70813cb Vaclav Honzik
        }
67
68 de12c6be Vaclav Honzik
        // Build edges
69
        const edges = []
70 b70813cb Vaclav Honzik
        for (let i = 0; i < activeMapPoints.length - 1; i += 1) {
71 de12c6be Vaclav Honzik
            const [start, end] = [
72
                activeMapPoints[i].catalogItem,
73
                activeMapPoints[i + 1].catalogItem,
74
            ]
75 b70813cb Vaclav Honzik
            edges.push(
76
                <TextPath
77 de12c6be Vaclav Honzik
                    // Somehow this refuses to work so let it rerender everything ...
78 1e2f25c9 Vaclav Honzik
                    key={`${activeMapPoints[i].id}-${activeMapPoints[i + 1].id}`}
79 b70813cb Vaclav Honzik
                    positions={[
80 de12c6be Vaclav Honzik
                        [start.latitude, start.longitude],
81
                        [end.latitude, end.longitude],
82 b70813cb Vaclav Honzik
                    ]}
83
                    text="►"
84 04fdedc6 Vaclav Honzik
                    // text=" > > > > "
85 b70813cb Vaclav Honzik
                    attributes={{
86 a7ae217f Vaclav Honzik
                        'font-size': 19,
87 b70813cb Vaclav Honzik
                        // Set to primaryPathColor if primary index in the tracking tool is equal to this index
88 8c57f958 Vaclav Honzik
                        fill:
89
                            primaryPathIdx === idx
90
                                ? primaryPathColor
91
                                : secondaryPathColor,
92 b70813cb Vaclav Honzik
                    }}
93 de12c6be Vaclav Honzik
                    onClick={() => dispatch(setPrimaryIdx(idx))}
94 b70813cb Vaclav Honzik
                    repeat
95
                    center
96 04fdedc6 Vaclav Honzik
                    weight={0}
97 b70813cb Vaclav Honzik
                />
98
            )
99
        }
100 de12c6be Vaclav Honzik
        setEdges(edges)
101
    }, [dispatch, displayableMapPoints, idx, primaryPathIdx])
102 b70813cb Vaclav Honzik
103 de12c6be Vaclav Honzik
    // List of vertices to display
104
    const [vertices, setVertices] = useState<JSX.Element[]>([])
105
    useEffect(() => {
106
        // Iterate over all displayable map points and map them to MapMarker
107
        setVertices(
108
            displayableMapPoints.map((item) => (
109
                <MapMarker
110 1e2f25c9 Vaclav Honzik
                    key={`${item.catalogItem.id}`}
111 de12c6be Vaclav Honzik
                    position={[
112
                        item.catalogItem.latitude as number,
113
                        item.catalogItem.longitude as number,
114
                    ]}
115
                    updatePositionCallbackFn={(position: LatLngTuple) => {
116
                        dispatch(
117 1e2f25c9 Vaclav Honzik
                            updateMapMarkerWithId({
118 a7ae217f Vaclav Honzik
                                item: {
119 812b9f90 Vaclav Honzik
                                    ...item,
120 a7ae217f Vaclav Honzik
                                    catalogItem: {
121
                                        ...item.catalogItem,
122
                                        latitude: position[0],
123
                                        longitude: position[1],
124
                                    },
125
                                },
126 1e2f25c9 Vaclav Honzik
                                id: item.id,
127 de12c6be Vaclav Honzik
                            })
128
                        )
129
                    }}
130
                >
131 11fca75a Vaclav Honzik
                    <Fragment>
132
                        <Tooltip>
133
                            {/* <Typography> */}
134 a7ae217f Vaclav Honzik
                            {item.catalogItem.name ?? ''}
135 11fca75a Vaclav Honzik
                            {/* </Typography> */}
136
                        </Tooltip>
137
                        <Popup>
138
                            <Fragment>
139
                                <Stack direction="column" sx={{ m: 0 }}>
140
                                    <Typography
141
                                        variant="h6"
142
                                        fontWeight="bold"
143
                                        fontSize={16}
144
                                    >
145
                                        {formatHtmlStringToReactDom(
146
                                            item.catalogItem.name as string
147
                                        )}
148
                                    </Typography>
149
                                    <FormControlLabel
150
                                        control={
151
                                            <Checkbox
152
                                                checked={item.active}
153
                                                onChange={() => {
154
                                                    dispatch(
155
                                                        updateMapMarker({
156 a7ae217f Vaclav Honzik
                                                            item: {
157
                                                                ...item,
158
                                                                active: !item.active,
159
                                                            },
160 11fca75a Vaclav Honzik
                                                        })
161
                                                    )
162
                                                }}
163
                                            />
164
                                        }
165
                                        labelPlacement="end"
166
                                        label="Active"
167
                                    />
168
                                    <CatalogItemDetailDialog
169 a7ae217f Vaclav Honzik
                                        itemId={item.catalogItem.id ?? ''}
170 11fca75a Vaclav Honzik
                                    />
171
                                </Stack>
172
                            </Fragment>
173
                        </Popup>
174
                    </Fragment>
175 de12c6be Vaclav Honzik
                </MapMarker>
176
            ))
177
        )
178
    }, [dispatch, displayableMapPoints, idx])
179 b70813cb Vaclav Honzik
180
    return (
181
        <Fragment>
182 de12c6be Vaclav Honzik
            {vertices}
183
            {edges}
184 b70813cb Vaclav Honzik
        </Fragment>
185
    )
186
}
187
188
export default MapPath