Projekt

Obecné

Profil

Stáhnout (7.35 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 './pathUtils'
5
import TextPath from 'react-leaflet-textpath'
6
import { setPrimaryIdx, updateMapMarker, updateMapMarkerWithId } 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(
52
            path.filter((mapPoint) => isMapPointDisplayable(mapPoint))
53
        )
54
    }, [path])
55

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

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

    
103
    // 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
                    key={`${item.catalogItem.id}`}
111
                    position={[
112
                        item.catalogItem.latitude as number,
113
                        item.catalogItem.longitude as number,
114
                    ]}
115
                    updatePositionCallbackFn={(position: LatLngTuple) => {
116
                        dispatch(
117
                            updateMapMarkerWithId({
118
                                item: {
119
                                    ...item,
120
                                    catalogItem: {
121
                                        ...item.catalogItem,
122
                                        latitude: position[0],
123
                                        longitude: position[1],
124
                                    },
125
                                },
126
                                id: item.id,
127
                            })
128
                        )
129
                    }}
130
                >
131
                    <Fragment>
132
                        <Tooltip>
133
                            {/* <Typography> */}
134
                            {item.catalogItem.name ?? ''}
135
                            {/* </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
                                                            item: {
157
                                                                ...item,
158
                                                                active: !item.active,
159
                                                            },
160
                                                        })
161
                                                    )
162
                                                }}
163
                                            />
164
                                        }
165
                                        labelPlacement="end"
166
                                        label="Active"
167
                                    />
168
                                    <CatalogItemDetailDialog
169
                                        itemId={item.catalogItem.id ?? ''}
170
                                    />
171
                                </Stack>
172
                            </Fragment>
173
                        </Popup>
174
                    </Fragment>
175
                </MapMarker>
176
            ))
177
        )
178
    }, [dispatch, displayableMapPoints, idx])
179

    
180
    return (
181
        <Fragment>
182
            {vertices}
183
            {edges}
184
        </Fragment>
185
    )
186
}
187

    
188
export default MapPath
(2-2/4)