Projekt

Obecné

Profil

Stáhnout (4.61 KB) Statistiky
| Větev: | Tag: | Revize:
1
import { createSlice } from "@reduxjs/toolkit"
2
import { LatLngTuple } from "leaflet"
3
import { persistReducer } from "redux-persist"
4
import mapConfig from "../../config/mapConfig"
5
import { PathDto } from "../../swagger/data-contracts"
6
import buildPathVariants, { MapPoint, PathVariant } from "./buildPathVariants"
7
import { sendTextForProcessing } from "./trackingToolThunks"
8
import storage from "redux-persist/lib/storage"
9

    
10
export interface TrackingToolState {
11
    isLoading: boolean // whether the data is being loaded
12
    pathDto?: PathDto // the data
13
    pathVariants?: PathVariant[] // undefined signals that no path variants were yet fetched from the API
14
    lastError?: string // consumable for errors during thunks
15
    mapCenter: LatLngTuple // pair of latitude and longitude
16
    primaryPathIdx: number // index of the primary path
17
    // trigger to close the dialog when API call is finished
18
    dialogApiCallSuccess: boolean
19
    pathsPerPage: number // max number of paths to show on the map at once
20
    currentPage: number // current page of paths - starts from 0
21
}
22

    
23
const defaultPathsPerPage = 5
24

    
25
const initialState: TrackingToolState = {
26
    isLoading: false,
27
    mapCenter: [mapConfig.defaultCoordinates[0], mapConfig.defaultCoordinates[1]],
28
    primaryPathIdx: 0,
29
    dialogApiCallSuccess: true,
30
    pathsPerPage: defaultPathsPerPage,
31
    currentPage: 0,
32
}
33

    
34
// Returns tuple of average latitude and longitude
35
const calculateMapCenter = (pathVariant: PathVariant): LatLngTuple => [
36
    pathVariant
37
        .map((item) => item.catalogItem.latitude ?? 0)
38
        .reduce((a, b) => a + b, 0) / pathVariant.length,
39
    pathVariant
40
        .map((item) => item.catalogItem.longitude ?? 0)
41
        .reduce((a, b) => a + b, 0) / pathVariant.length,
42
]
43

    
44
const persistConfig = {
45
    key: "auth",
46
    storage, // localStorage for browsers
47
}
48

    
49
export const trackingToolSlice = createSlice({
50
    name: "trackingTool",
51
    initialState,
52
    reducers: {
53
        consumeErr: (state: TrackingToolState) => ({
54
            ...state,
55
            lastErr: undefined,
56
        }),
57
        setPrimaryIdx: (state: TrackingToolState, action: any) => ({
58
            ...state,
59
            primaryPathIdx: action.payload,
60
        }),
61
        resetDialogApiCallSuccess: (state: TrackingToolState) => ({
62
            ...state,
63
            dialogApiCallSuccess: false,
64
        }),
65
        setPage: (state: TrackingToolState, action: { payload: number }) => ({
66
            ...state,
67
            currentPage: action.payload,
68
        }),
69
        updateMapMarker: (state: TrackingToolState, action: { payload: { idx: number, item: MapPoint } }) => {
70
            const { idx, item } = action.payload
71
            if (!state.pathVariants || state.pathVariants.length <= idx) {
72
                return state
73
            }
74

    
75
            return {
76
                ...state,
77
                pathVariants: state.pathVariants.map((pathVariant, i) => {
78
                    if (i !== idx) {
79
                        return [...pathVariant]
80
                    }
81

    
82
                    return [
83
                        ...pathVariant.slice(0, item.idx),
84
                        item,
85
                        ...pathVariant.slice(item.idx + 1),
86
                    ]
87
                })
88
            }
89
        },
90
        clear: () => ({ ...initialState }),
91
    },
92
    extraReducers: (builder) => {
93
        builder.addCase(sendTextForProcessing.fulfilled, (state, action) => {
94
            const pathDto: PathDto = action.payload
95
            const pathVariants = buildPathVariants(pathDto)
96
            return {
97
                ...state,
98
                pathVariants,
99
                pathDto,
100
                // TODO calculate correctly
101
                mapCenter:
102
                    pathVariants.length > 0
103
                        ? calculateMapCenter(pathVariants[0])
104
                        : (state.mapCenter as LatLngTuple),
105
                isLoading: false,
106
                dialogApiCallSuccess: true,
107
                currentPage: 0,
108
            }
109
        })
110
        builder.addCase(sendTextForProcessing.rejected, (_, action) => ({
111
            ...initialState,
112
            lastError: action.error.message,
113
            isLoading: false,
114
            dialogApiCallSuccess: false,
115
            currentPage: 0,
116
        }))
117
        builder.addCase(sendTextForProcessing.pending, (state) => {
118
            return {
119
                ...state,
120
                isLoading: true,
121
                dialogApiCallSuccess: false,
122
            }
123
        })
124
    },
125
})
126

    
127
export const { consumeErr, setPrimaryIdx, resetDialogApiCallSuccess, clear, updateMapMarker } =
128
    trackingToolSlice.actions
129
const trackingToolReducer = trackingToolSlice.reducer
130
export default trackingToolReducer
(8-8/9)