Projekt

Obecné

Profil

Stáhnout (6.02 KB) Statistiky
| Větev: | Tag: | Revize:
1 8c57f958 Vaclav Honzik
import { Fragment, FunctionComponent, useEffect, useState } from 'react'
2 b70813cb Vaclav Honzik
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 dd270a41 Vaclav Honzik
import {
7
    Checkbox,
8
    FormControlLabel,
9
    Paper,
10
    Stack,
11
    Typography,
12
} from '@mui/material'
13 b70813cb Vaclav Honzik
import { formatHtmlStringToReactDom } from '../../utils/formatting/HtmlUtils'
14
import { DialogCatalogItemDetail as CatalogItemDetailDialog } from '../Catalog/CatalogItemDetail'
15 8c57f958 Vaclav Honzik
import { useDispatch, useSelector } from 'react-redux'
16
import { RootState } from '../redux/store'
17 b70813cb Vaclav Honzik
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 8c57f958 Vaclav Honzik
// Map path component
38
const MapPath: FunctionComponent<MapPathProps> = ({ idx, pathVariant }) => {
39 b70813cb Vaclav Honzik
    // List of all map points that belong to the path
40 dd270a41 Vaclav Honzik
    const pathVariants = useSelector(
41
        (state: RootState) => state.trackingTool.pathVariants
42 b70813cb Vaclav Honzik
    )
43 dd270a41 Vaclav Honzik
    const [mapPoints, setMapPoints] = useState<DisplayableMapPoint[]>([])
44
    const dispatch = useDispatch()
45 8c57f958 Vaclav Honzik
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 b70813cb Vaclav Honzik
61
    const getActiveMapPoints = () => mapPoints.filter((item) => item.active)
62
63 dd270a41 Vaclav Honzik
    // 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 8c57f958 Vaclav Honzik
75 b70813cb Vaclav Honzik
    // 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
                    attributes={{
99
                        'font-size': 25,
100
                        // Set to primaryPathColor if primary index in the tracking tool is equal to this index
101 8c57f958 Vaclav Honzik
                        fill:
102
                            primaryPathIdx === idx
103
                                ? primaryPathColor
104
                                : secondaryPathColor,
105 b70813cb Vaclav Honzik
                    }}
106
                    onClick={() => {
107 8c57f958 Vaclav Honzik
                        dispatch(setPrimaryIdx(idx))
108
                    }}
109 b70813cb Vaclav Honzik
                    repeat
110
                    center
111
                    weight={9}
112
                />
113
            )
114
        }
115
116
        // Return the path
117
        return edges
118
    }
119
120
    /**
121
     * Creates a list of all vertices in the path
122
     */
123
    const buildVertices = () => {
124
        return mapPoints.map((mapPoint, idx) => (
125
            <Marker
126
                key={idx}
127
                position={[
128
                    mapPoint.catalogItem.latitude as number,
129
                    mapPoint.catalogItem.longitude as number,
130
                ]}
131
            >
132
                <Popup>
133
                    <Fragment>
134
                        <Stack direction="column" sx={{ m: 0 }}>
135
                            <Typography
136
                                variant="h6"
137
                                fontWeight="bold"
138
                                fontSize={16}
139
                            >
140 8c57f958 Vaclav Honzik
                                {formatHtmlStringToReactDom(
141
                                    mapPoint.catalogItem.name as string
142
                                )}
143 b70813cb Vaclav Honzik
                            </Typography>
144
                            <FormControlLabel
145
                                control={
146
                                    <Checkbox
147
                                        checked={mapPoint.active}
148
                                        onChange={() => {
149
                                            mapPoint.active = !mapPoint.active
150
                                            setMapPoints([...mapPoints])
151
                                        }}
152
                                    />
153
                                }
154
                                labelPlacement="end"
155
                                label="Active"
156
                            />
157 8c57f958 Vaclav Honzik
                            <CatalogItemDetailDialog
158
                                itemId={mapPoint.catalogItem.id ?? ''}
159
                            />
160 b70813cb Vaclav Honzik
                        </Stack>
161
                    </Fragment>
162
                </Popup>
163
            </Marker>
164
        ))
165
    }
166
167
    return (
168
        <Fragment>
169 8c57f958 Vaclav Honzik
            {active && (
170
                <Fragment>
171
                    {buildVertices()}
172
                    {buildEdges()}
173
                </Fragment>
174
            )}
175 b70813cb Vaclav Honzik
        </Fragment>
176
    )
177
}
178
179
export default MapPath
180 8c57f958 Vaclav Honzik
function setPrimaryIdx(idx: number): any {
181
    throw new Error('Function not implemented.')
182
}