Projekt

Obecné

Profil

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