Projekt

Obecné

Profil

Stáhnout (6.45 KB) Statistiky
| Větev: | Tag: | Revize:
1 de12c6be Vaclav Honzik
import { Fragment, FunctionComponent, useEffect, useState } from "react"
2
import { useDispatch, useSelector } from "react-redux"
3
import { RootState } from "../redux/store"
4
import { PathVariant, MapPoint } from "./buildPathVariants"
5
import TextPath from "react-leaflet-textpath"
6
import { setPrimaryIdx, updateMapMarkerPosition } from "./trackingToolSlice"
7
import MapMarker from "./MapMarker"
8
import { LatLngTuple } from "leaflet"
9
import { Popup } from "react-leaflet"
10
import { Checkbox, FormControlLabel, Stack, Typography } from "@mui/material"
11
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 de12c6be Vaclav Honzik
export const primaryPathColor = "#346eeb"
22 b70813cb Vaclav Honzik
23
// Grey
24 de12c6be 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
    }, [paths])
39
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
        setDisplayableMapPoints(path.filter((vertex) => vertex.displayable))
52
    }, [path])
53 b70813cb Vaclav Honzik
54 de12c6be Vaclav Honzik
    // List of all edges in the path
55
    const [edges, setEdges] = useState<EdgeElement[]>([])
56 dd270a41 Vaclav Honzik
    useEffect(() => {
57 de12c6be Vaclav Honzik
        // Get all active map points
58
        const activeMapPoints = displayableMapPoints.filter(
59
            (item) => item.active
60 dd270a41 Vaclav Honzik
        )
61 b70813cb Vaclav Honzik
        if (activeMapPoints.length < 2) {
62 de12c6be Vaclav Honzik
            return
63 b70813cb Vaclav Honzik
        }
64
65 de12c6be Vaclav Honzik
        // Build edges
66
        const edges = []
67 b70813cb Vaclav Honzik
        for (let i = 0; i < activeMapPoints.length - 1; i += 1) {
68 de12c6be Vaclav Honzik
            const [start, end] = [
69
                activeMapPoints[i].catalogItem,
70
                activeMapPoints[i + 1].catalogItem,
71
            ]
72 b70813cb Vaclav Honzik
            edges.push(
73
                <TextPath
74 de12c6be Vaclav Honzik
                    // Somehow this refuses to work so let it rerender everything ...
75
                    // key={`${start.latitude},${start.longitude}-${end.latitude},${end.longitude}`}
76
                    // key={`${start.id}-${end.id}`}
77 b70813cb Vaclav Honzik
                    positions={[
78 de12c6be Vaclav Honzik
                        [start.latitude, start.longitude],
79
                        [end.latitude, end.longitude],
80 b70813cb Vaclav Honzik
                    ]}
81
                    text="►"
82 04fdedc6 Vaclav Honzik
                    // text=" > > > > "
83 b70813cb Vaclav Honzik
                    attributes={{
84 de12c6be Vaclav Honzik
                        "font-size": 19,
85 b70813cb Vaclav Honzik
                        // Set to primaryPathColor if primary index in the tracking tool is equal to this index
86 8c57f958 Vaclav Honzik
                        fill:
87
                            primaryPathIdx === idx
88
                                ? primaryPathColor
89
                                : secondaryPathColor,
90 b70813cb Vaclav Honzik
                    }}
91 de12c6be Vaclav Honzik
                    onClick={() => dispatch(setPrimaryIdx(idx))}
92 b70813cb Vaclav Honzik
                    repeat
93
                    center
94 04fdedc6 Vaclav Honzik
                    weight={0}
95 b70813cb Vaclav Honzik
                />
96
            )
97
        }
98 de12c6be Vaclav Honzik
        setEdges(edges)
99
    }, [dispatch, displayableMapPoints, idx, primaryPathIdx])
100 b70813cb Vaclav Honzik
101 de12c6be Vaclav Honzik
    // List of vertices to display
102
    const [vertices, setVertices] = useState<JSX.Element[]>([])
103
    useEffect(() => {
104
        // Iterate over all displayable map points and map them to MapMarker
105
        setVertices(
106
            displayableMapPoints.map((item) => (
107
                <MapMarker
108
                    key={`${item.catalogItem.latitude}${item.catalogItem.latitude}`}
109
                    position={[
110
                        item.catalogItem.latitude as number,
111
                        item.catalogItem.longitude as number,
112
                    ]}
113
                    updatePositionCallbackFn={(position: LatLngTuple) => {
114
                        // Update the position of the map point
115
                        dispatch(
116
                            updateMapMarkerPosition({
117
                                idx,
118
                                mapPointIdx: item.idx,
119
                                position,
120
                            })
121
                        )
122
                    }}
123
                >
124
                    <Popup>
125
                        <Fragment>
126
                            <Stack direction="column" sx={{ m: 0 }}>
127
                                <Typography
128
                                    variant="h6"
129
                                    fontWeight="bold"
130
                                    fontSize={16}
131
                                >
132
                                    {formatHtmlStringToReactDom(
133
                                        item.catalogItem.name as string
134
                                    )}
135
                                </Typography>
136
                                <FormControlLabel
137
                                    control={
138
                                        <Checkbox
139
                                            checked={item.active}
140
                                            onChange={() => {
141
                                                item.active = !item.active
142
                                                setDisplayableMapPoints([
143
                                                    ...displayableMapPoints,
144
                                                ])
145
                                            }}
146
                                        />
147
                                    }
148
                                    labelPlacement="end"
149
                                    label="Active"
150
                                />
151
                                <CatalogItemDetailDialog
152
                                    itemId={item.catalogItem.id ?? ""}
153
                                />
154
                            </Stack>
155
                        </Fragment>
156
                    </Popup>
157
                </MapMarker>
158
            ))
159
        )
160
    }, [dispatch, displayableMapPoints, idx])
161 b70813cb Vaclav Honzik
162
    return (
163
        <Fragment>
164 de12c6be Vaclav Honzik
            {vertices}
165
            {edges}
166 b70813cb Vaclav Honzik
        </Fragment>
167
    )
168
}
169
170
export default MapPath