Projekt

Obecné

Profil

Stáhnout (7.33 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, isMapPointDisplayable } from '../trackingToolUtils'
5
import TextPath from 'react-leaflet-textpath'
6
import {
7
    setPrimaryIdx,
8
    updateMapMarker,
9
    updateMapMarkerWithId,
10
} from '../trackingToolSlice'
11
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
import { formatHtmlStringToReactDom } from '../../../utils/formatting/HtmlUtils'
16
import { DialogCatalogItemDetail as CatalogItemDetailDialog } from '../../Catalog/CatalogItemDetail'
17

    
18
export interface MapPathProps {
19
    idx: number // index of the path in the list
20
}
21

    
22
type EdgeElement = any
23

    
24
// Blue
25
export const primaryPathColor = '#346eeb'
26

    
27
// Grey
28
export const secondaryPathColor = '#878e9c'
29

    
30
const MapPath: FunctionComponent<MapPathProps> = ({ idx }) => {
31
    const dispatch = useDispatch()
32

    
33
    // 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
    )
38
    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
    }, [idx, paths])
43

    
44
    // Primary path index to set the correct color
45
    const primaryPathIdx = useSelector(
46
        (state: RootState) => state.trackingTool.primaryPathIdx
47
    )
48

    
49
    // List of all active map points
50
    const [displayableMapPoints, setDisplayableMapPoints] = useState<
51
        MapPoint[]
52
    >([])
53
    useEffect(() => {
54
        // Set all displayable vertices
55
        setDisplayableMapPoints(
56
            path.filter((mapPoint) => isMapPointDisplayable(mapPoint))
57
        )
58
    }, [path])
59

    
60
    // List of all edges in the path
61
    const [edges, setEdges] = useState<EdgeElement[]>([])
62
    useEffect(() => {
63
        // Get all active map points
64
        const activeMapPoints = displayableMapPoints.filter(
65
            (item) => item.addToPath && !item.hidden
66
        )
67
        if (activeMapPoints.length < 2) {
68
            setEdges([])
69
            return
70
        }
71

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

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

    
185
    return (
186
        <Fragment>
187
            {vertices}
188
            {edges}
189
        </Fragment>
190
    )
191
}
192

    
193
export default MapPath
(2-2/3)