Projekt

Obecné

Profil

Stáhnout (6.1 KB) Statistiky
| Větev: | Tag: | Revize:
1
import { Fragment, FunctionComponent, useEffect, useState } from 'react'
2
import { CatalogItemDto } from '../../swagger/data-contracts'
3
import { PathVariant } from './buildPathVariants'
4
import TextPath from 'react-leaflet-textpath'
5
import { Marker, Popup } from 'react-leaflet'
6
import {
7
    Checkbox,
8
    FormControlLabel,
9
    Paper,
10
    Stack,
11
    Typography,
12
} from '@mui/material'
13
import { formatHtmlStringToReactDom } from '../../utils/formatting/HtmlUtils'
14
import { DialogCatalogItemDetail as CatalogItemDetailDialog } from '../Catalog/CatalogItemDetail'
15
import { useDispatch, useSelector } from 'react-redux'
16
import { RootState } from '../redux/store'
17
import MapMarker from './MapMarker'
18

    
19
// CatalogItemDto wrapper to keep track whether the item is active or not
20
class DisplayableMapPoint {
21
    constructor(
22
        public readonly catalogItem: CatalogItemDto,
23
        public active: boolean = true
24
    ) {}
25
}
26

    
27
export interface MapPathProps {
28
    pathVariant: PathVariant // aka CatalogItemDto[]
29
    idx: number // index of path in the list
30
}
31

    
32
// Blue
33
export const primaryPathColor = '#346eeb'
34

    
35
// Grey
36
export const secondaryPathColor = '#878e9c'
37

    
38
// Map path component
39
const MapPath: FunctionComponent<MapPathProps> = ({ idx, pathVariant }) => {
40
    // List of all map points that belong to the path
41
    const pathVariants = useSelector(
42
        (state: RootState) => state.trackingTool.pathVariants
43
    )
44
    const [mapPoints, setMapPoints] = useState<DisplayableMapPoint[]>([])
45
    const dispatch = useDispatch()
46

    
47
    // Set of all active paths
48
    const activePaths = useSelector(
49
        (state: RootState) => state.trackingTool.activePaths
50
    )
51
    // Index of the primary path
52
    const primaryPathIdx = useSelector(
53
        (state: RootState) => state.trackingTool.primaryPathIdx
54
    )
55

    
56
    // Whether the path is active or not
57
    const [active, setActive] = useState(false)
58
    useEffect(() => {
59
        setActive(activePaths.has(idx))
60
    }, [activePaths, idx])
61

    
62
    const getActiveMapPoints = () => mapPoints.filter((item) => item.active)
63

    
64
    // Refresh the list of map points if it has changed
65
    useEffect(() => {
66
        if (!pathVariants || pathVariants.length <= idx) {
67
            return
68
        }
69
        setMapPoints(
70
            [...pathVariants[idx]]
71
                .filter((item) => item.latitude && item.longitude)
72
                .map((item) => new DisplayableMapPoint(item))
73
        )
74
    }, [pathVariants, idx])
75

    
76
    // Builds all edges of the path
77
    const buildEdges = () => {
78
        const activeMapPoints = getActiveMapPoints()
79
        if (activeMapPoints.length < 2) {
80
            return null
81
        }
82

    
83
        // Create path edges
84
        const edges: any[] = []
85
        for (let i = 0; i < activeMapPoints.length - 1; i += 1) {
86
            edges.push(
87
                <TextPath
88
                    positions={[
89
                        [
90
                            activeMapPoints[i].catalogItem.latitude,
91
                            activeMapPoints[i].catalogItem.longitude,
92
                        ],
93
                        [
94
                            activeMapPoints[i + 1].catalogItem.latitude,
95
                            activeMapPoints[i + 1].catalogItem.longitude,
96
                        ],
97
                    ]}
98
                    text="►"
99
                    // text=" > > > > "
100
                    attributes={{
101
                        'font-size': 19,
102
                        // Set to primaryPathColor if primary index in the tracking tool is equal to this index
103
                        fill:
104
                            primaryPathIdx === idx
105
                                ? primaryPathColor
106
                                : secondaryPathColor,
107
                    }}
108
                    onClick={() => {
109
                        dispatch(setPrimaryIdx(idx))
110
                    }}
111
                    repeat
112
                    center
113
                    weight={0}
114
                />
115
            )
116
        }
117

    
118
        // Return the path
119
        return edges
120
    }
121

    
122
    /**
123
     * Creates a list of all vertices in the path
124
     */
125
    const buildVertices = () => {
126
        return mapPoints.map((mapPoint, idx) => (
127
            <MapMarker
128
                key={idx}
129
                position={[
130
                    mapPoint.catalogItem.latitude as number,
131
                    mapPoint.catalogItem.longitude as number,
132
                ]}
133
            >
134
                <Popup>
135
                    <Fragment>
136
                        <Stack direction="column" sx={{ m: 0 }}>
137
                            <Typography
138
                                variant="h6"
139
                                fontWeight="bold"
140
                                fontSize={16}
141
                            >
142
                                {formatHtmlStringToReactDom(
143
                                    mapPoint.catalogItem.name as string
144
                                )}
145
                            </Typography>
146
                            <FormControlLabel
147
                                control={
148
                                    <Checkbox
149
                                        checked={mapPoint.active}
150
                                        onChange={() => {
151
                                            mapPoint.active = !mapPoint.active
152
                                            setMapPoints([...mapPoints])
153
                                        }}
154
                                    />
155
                                }
156
                                labelPlacement="end"
157
                                label="Active"
158
                            />
159
                            <CatalogItemDetailDialog
160
                                itemId={mapPoint.catalogItem.id ?? ''}
161
                            />
162
                        </Stack>
163
                    </Fragment>
164
                </Popup>
165
            </MapMarker>
166
        ))
167
    }
168

    
169
    return (
170
        <Fragment>
171
            {active && (
172
                <Fragment>
173
                    {buildVertices()}
174
                    {buildEdges()}
175
                </Fragment>
176
            )}
177
        </Fragment>
178
    )
179
}
180

    
181
export default MapPath
182
function setPrimaryIdx(idx: number): any {
183
    throw new Error('Function not implemented.')
184
}
(3-3/9)