Projekt

Obecné

Profil

Stáhnout (6.36 KB) Statistiky
| Větev: | Tag: | Revize:
1 de12c6be Vaclav Honzik
import { createSlice } from "@reduxjs/toolkit"
2
import { LatLngTuple } from "leaflet"
3
import mapConfig from "../../config/mapConfig"
4
import { PathDto } from "../../swagger/data-contracts"
5 a7ae217f Vaclav Honzik
import buildPathVariants, { isMapPointDisplayable, MapPoint, PathVariant } from "./pathUtils"
6 de12c6be Vaclav Honzik
import { sendTextForProcessing } from "./trackingToolThunks"
7
import storage from "redux-persist/lib/storage"
8 a7ae217f Vaclav Honzik
import TrackingToolState from './TrackingToolState'
9 8c57f958 Vaclav Honzik
10
11 81698b9a Vaclav Honzik
const defaultPathsPerPage = 5
12
13 8c57f958 Vaclav Honzik
const initialState: TrackingToolState = {
14
    isLoading: false,
15 de12c6be Vaclav Honzik
    mapCenter: [mapConfig.defaultCoordinates[0], mapConfig.defaultCoordinates[1]],
16 8c57f958 Vaclav Honzik
    primaryPathIdx: 0,
17
    dialogApiCallSuccess: true,
18 81698b9a Vaclav Honzik
    pathsPerPage: defaultPathsPerPage,
19
    currentPage: 0,
20 8c57f958 Vaclav Honzik
}
21
22 11fca75a Vaclav Honzik
const calculateMapCenter = (pathVariant: PathVariant): LatLngTuple | undefined => {
23 a7ae217f Vaclav Honzik
    const displayableItems = pathVariant.filter((item) => isMapPointDisplayable(item))
24 11fca75a Vaclav Honzik
    if (displayableItems.length === 0) {
25
        return undefined
26
    }
27
28
    return [
29
        displayableItems
30
            .map((item) => item.catalogItem.latitude ?? 0)
31
            .reduce((a, b) => a + b, 0) / displayableItems.length,
32
        displayableItems
33
            .map((item) => item.catalogItem.longitude ?? 0)
34
            .reduce((a, b) => a + b, 0) / displayableItems.length,
35
    ]
36
}
37 8c57f958 Vaclav Honzik
38 04fdedc6 Vaclav Honzik
const persistConfig = {
39 de12c6be Vaclav Honzik
    key: "auth",
40 04fdedc6 Vaclav Honzik
    storage, // localStorage for browsers
41
}
42
43 8c57f958 Vaclav Honzik
export const trackingToolSlice = createSlice({
44 de12c6be Vaclav Honzik
    name: "trackingTool",
45 8c57f958 Vaclav Honzik
    initialState,
46
    reducers: {
47 de12c6be Vaclav Honzik
        consumeErr: (state: TrackingToolState) => ({
48
            ...state,
49
            lastErr: undefined,
50
        }),
51 c0cf1dbc Vaclav Honzik
        setPrimaryIdx: (state: TrackingToolState, action: any) => ({
52 8c57f958 Vaclav Honzik
            ...state,
53
            primaryPathIdx: action.payload,
54
        }),
55 c0cf1dbc Vaclav Honzik
        resetDialogApiCallSuccess: (state: TrackingToolState) => ({
56 8c57f958 Vaclav Honzik
            ...state,
57
            dialogApiCallSuccess: false,
58
        }),
59 de12c6be Vaclav Honzik
        setPage: (state: TrackingToolState, action: { payload: number }) => ({
60 81698b9a Vaclav Honzik
            ...state,
61
            currentPage: action.payload,
62
        }),
63 7b864a5c Vaclav Honzik
        updateMapMarker: (state: TrackingToolState, action: { payload: { idx: number, item: MapPoint } }) => {
64
            const { idx, item } = action.payload
65 de12c6be Vaclav Honzik
            if (!state.pathVariants || state.pathVariants.length <= idx) {
66
                return state
67
            }
68
69
            return {
70
                ...state,
71
                pathVariants: state.pathVariants.map((pathVariant, i) => {
72
                    if (i !== idx) {
73
                        return [...pathVariant]
74
                    }
75
76
                    return [
77 7b864a5c Vaclav Honzik
                        ...pathVariant.slice(0, item.idx),
78
                        item,
79
                        ...pathVariant.slice(item.idx + 1),
80 de12c6be Vaclav Honzik
                    ]
81
                })
82
            }
83
        },
84
        clear: () => ({ ...initialState }),
85 a7ae217f Vaclav Honzik
        mergeWithCurrentPath: (state: TrackingToolState, action: { payload: PathVariant }) => {
86
            const { payload: jsonPath } = action
87
            if (!jsonPath) {
88
                return { ...state }
89
            }
90
91
            const pathVariants = [...state.pathVariants ?? []]
92
            let primaryPathIdx = state.primaryPathIdx
93
            let currentPage = state.currentPage
94
95
            // If there are no path append a new array to the pathVariants array and set primaryIdx to 0
96
            if (pathVariants.length === 0) {
97
                primaryPathIdx = 0
98
                currentPage = 0
99
                pathVariants.push([])
100
            }
101
102
            // Get the path and create a map to check whether some point with the same id already exists
103
            const path = pathVariants[primaryPathIdx]
104
            const pathMap = new Map(path.map((item) => [item.catalogItem.id as string, item]))
105
106
            // Create an array of items to be replaced and items to be added to the end
107
            const itemsToReplace: MapPoint[] = []
108
            const itemsToAdd: MapPoint[] = []
109
            jsonPath.forEach((item) => {
110
                if (!pathMap.has(item.catalogItem.id as string)) {
111
                    itemsToAdd.push(item)
112
                    return
113
                }
114
                
115
                const idx = pathMap.get(item.catalogItem.id as string)!.idx
116
                item.idx = idx
117
                itemsToReplace.push(item)
118
            })
119
120
            // Iterate over items to replace and replace them
121
            const newPath = [...path]
122
            itemsToReplace.forEach((item) => {
123
                newPath[item.idx] = item
124
            })
125
126
            // Add items to the end
127
            itemsToAdd.forEach((item) => {
128
                item.active = false
129
                item.idx = newPath.length
130
                newPath.push(item)
131
            })
132
133
            // Return the new path
134
            return {
135
                ...state,
136
                pathVariants: [
137
                    ...pathVariants.slice(0, primaryPathIdx),
138
                    newPath,
139
                    ...pathVariants.slice(primaryPathIdx + 1),
140
                ],
141
                primaryPathIdx, // in case the list is empty
142
                currentPage, // in case the list is empty
143
            }
144
        }
145 8c57f958 Vaclav Honzik
    },
146
    extraReducers: (builder) => {
147
        builder.addCase(sendTextForProcessing.fulfilled, (state, action) => {
148 04fdedc6 Vaclav Honzik
            const pathDto: PathDto = action.payload
149
            const pathVariants = buildPathVariants(pathDto)
150 11fca75a Vaclav Honzik
151
            const mapCenter = calculateMapCenter(pathVariants[state.primaryPathIdx])
152 8c57f958 Vaclav Honzik
            return {
153
                ...state,
154
                pathVariants,
155 04fdedc6 Vaclav Honzik
                pathDto,
156 11fca75a Vaclav Honzik
                mapCenter: mapCenter ?? state.mapCenter,
157 8c57f958 Vaclav Honzik
                isLoading: false,
158
                dialogApiCallSuccess: true,
159 81698b9a Vaclav Honzik
                currentPage: 0,
160 8c57f958 Vaclav Honzik
            }
161
        })
162 b45d0300 Vaclav Honzik
        builder.addCase(sendTextForProcessing.rejected, (_, action) => ({
163 8c57f958 Vaclav Honzik
            ...initialState,
164 dd270a41 Vaclav Honzik
            lastError: action.error.message,
165 8c57f958 Vaclav Honzik
            isLoading: false,
166
            dialogApiCallSuccess: false,
167 81698b9a Vaclav Honzik
            currentPage: 0,
168 8c57f958 Vaclav Honzik
        }))
169
        builder.addCase(sendTextForProcessing.pending, (state) => {
170
            return {
171
                ...state,
172
                isLoading: true,
173
                dialogApiCallSuccess: false,
174
            }
175
        })
176
    },
177
})
178
179 a7ae217f Vaclav Honzik
export const { consumeErr, setPrimaryIdx, resetDialogApiCallSuccess, clear, updateMapMarker, mergeWithCurrentPath } =
180 de12c6be Vaclav Honzik
    trackingToolSlice.actions
181 8c57f958 Vaclav Honzik
const trackingToolReducer = trackingToolSlice.reducer
182
export default trackingToolReducer