Projekt

Obecné

Profil

Stáhnout (7.37 KB) Statistiky
| Větev: | Tag: | Revize:
1
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, updateMapMarker } from "./trackingToolSlice"
7
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
import { formatHtmlStringToReactDom } from "../../utils/formatting/HtmlUtils"
12
import { DialogCatalogItemDetail as CatalogItemDetailDialog } from "../Catalog/CatalogItemDetail"
13

    
14
export interface MapPathProps {
15
    idx: number // index of the path in the list
16
}
17

    
18
type EdgeElement = any
19

    
20
// Blue
21
export const primaryPathColor = "#346eeb"
22

    
23
// Grey
24
export const secondaryPathColor = "#878e9c"
25

    
26
const MapPath: FunctionComponent<MapPathProps> = ({ idx }) => {
27
    const dispatch = useDispatch()
28

    
29
    // 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
    )
34
    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
    }, [idx, paths])
39

    
40
    // Primary path index to set the correct color
41
    const primaryPathIdx = useSelector(
42
        (state: RootState) => state.trackingTool.primaryPathIdx
43
    )
44

    
45
    // List of all active map points
46
    const [displayableMapPoints, setDisplayableMapPoints] = useState<
47
        MapPoint[]
48
    >([])
49
    useEffect(() => {
50
        // Set all displayable vertices
51
        setDisplayableMapPoints(path.filter((vertex) => vertex.displayable))
52
    }, [path])
53

    
54
    // List of all edges in the path
55
    const [edges, setEdges] = useState<EdgeElement[]>([])
56
    useEffect(() => {
57
        // Get all active map points
58
        const activeMapPoints = displayableMapPoints.filter(
59
            (item) => item.active
60
        )
61
        if (activeMapPoints.length < 2) {
62
            setEdges([])
63
            return
64
        }
65

    
66
        // Build edges
67
        const edges = []
68
        for (let i = 0; i < activeMapPoints.length - 1; i += 1) {
69
            const [start, end] = [
70
                activeMapPoints[i].catalogItem,
71
                activeMapPoints[i + 1].catalogItem,
72
            ]
73
            edges.push(
74
                <TextPath
75
                    // Somehow this refuses to work so let it rerender everything ...
76
                    key={`${start.id}-${end.id}:${start.latitude},${start.longitude}-${end.latitude},${end.longitude}`}
77
                    positions={[
78
                        [start.latitude, start.longitude],
79
                        [end.latitude, end.longitude],
80
                    ]}
81
                    text="►"
82
                    // text=" > > > > "
83
                    attributes={{
84
                        "font-size": 19,
85
                        // Set to primaryPathColor if primary index in the tracking tool is equal to this index
86
                        fill:
87
                            primaryPathIdx === idx
88
                                ? primaryPathColor
89
                                : secondaryPathColor,
90
                    }}
91
                    onClick={() => dispatch(setPrimaryIdx(idx))}
92
                    repeat
93
                    center
94
                    weight={0}
95
                />
96
            )
97
        }
98
        setEdges(edges)
99
    }, [dispatch, displayableMapPoints, idx, primaryPathIdx])
100

    
101
    // 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.longitude}`}
109
                    position={[
110
                        item.catalogItem.latitude as number,
111
                        item.catalogItem.longitude as number,
112
                    ]}
113
                    updatePositionCallbackFn={(position: LatLngTuple) => {
114
                        dispatch(
115
                            updateMapMarker({
116
                                idx,
117
                                item: new MapPoint(item.idx, item.active, {
118
                                    ...item.catalogItem,
119
                                    latitude: position[0],
120
                                    longitude: position[1],
121
                                }),
122
                            })
123
                        )
124
                    }}
125
                >
126
                    <Fragment>
127
                        <Tooltip>
128
                            {/* <Typography> */}
129
                                {item.catalogItem.name ?? ""}
130
                            {/* </Typography> */}
131
                        </Tooltip>
132
                        <Popup>
133
                            <Fragment>
134
                                <Stack direction="column" sx={{ m: 0 }}>
135
                                    <Typography
136
                                        variant="h6"
137
                                        fontWeight="bold"
138
                                        fontSize={16}
139
                                    >
140
                                        {formatHtmlStringToReactDom(
141
                                            item.catalogItem.name as string
142
                                        )}
143
                                    </Typography>
144
                                    <FormControlLabel
145
                                        control={
146
                                            <Checkbox
147
                                                checked={item.active}
148
                                                onChange={() => {
149
                                                    dispatch(
150
                                                        updateMapMarker({
151
                                                            idx,
152
                                                            item: new MapPoint(
153
                                                                item.idx,
154
                                                                !item.active,
155
                                                                item.catalogItem
156
                                                            ),
157
                                                        })
158
                                                    )
159
                                                }}
160
                                            />
161
                                        }
162
                                        labelPlacement="end"
163
                                        label="Active"
164
                                    />
165
                                    <CatalogItemDetailDialog
166
                                        itemId={item.catalogItem.id ?? ""}
167
                                    />
168
                                </Stack>
169
                            </Fragment>
170
                        </Popup>
171
                    </Fragment>
172
                </MapMarker>
173
            ))
174
        )
175
    }, [dispatch, displayableMapPoints, idx])
176

    
177
    return (
178
        <Fragment>
179
            {vertices}
180
            {edges}
181
        </Fragment>
182
    )
183
}
184

    
185
export default MapPath
(3-3/9)