Projekt

Obecné

Profil

Stáhnout (6.06 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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