Projekt

Obecné

Profil

Stáhnout (3.5 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, { 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
    activePaths: Set<number> // indices of the active paths
18
    // trigger to close the dialog when API call is finished
19
    dialogApiCallSuccess: boolean
20
}
21

    
22
const initialState: TrackingToolState = {
23
    isLoading: false,
24
    mapCenter: [
25
        mapConfig.defaultCoordinates[0],
26
        mapConfig.defaultCoordinates[1],
27
    ],
28
    primaryPathIdx: 0,
29
    activePaths: new Set(),
30
    dialogApiCallSuccess: true,
31
}
32

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

    
41
const persistConfig = {
42
    key: 'auth',
43
    storage, // localStorage for browsers
44
}
45

    
46
export const trackingToolSlice = createSlice({
47
    name: 'trackingTool',
48
    initialState,
49
    reducers: {
50
        consumeErr: (state) => ({ ...state, lastErr: undefined }),
51
        setPrimaryIdx: (state, action) => ({
52
            ...state,
53
            primaryPathIdx: action.payload,
54
        }),
55
        resetDialogApiCallSuccess: (state) => ({
56
            ...state,
57
            dialogApiCallSuccess: false,
58
        }),
59
        clear: (state) => ({...initialState})
60
    },
61
    extraReducers: (builder) => {
62
        builder.addCase(sendTextForProcessing.fulfilled, (state, action) => {
63
            const pathDto: PathDto = action.payload
64
            const pathVariants = buildPathVariants(pathDto)
65
            return {
66
                ...state,
67
                pathVariants,
68
                pathDto,
69
                // TODO map this correctly
70
                activePaths: new Set(pathVariants.map((_, idx) => idx)),
71
                // TODO calculate correctly
72
                mapCenter:
73
                    pathVariants.length > 0
74
                        ? calculateMapCenter(pathVariants[0])
75
                        : (state.mapCenter as LatLngTuple),
76
                isLoading: false,
77
                dialogApiCallSuccess: true,
78
            }
79
        })
80
        builder.addCase(sendTextForProcessing.rejected, (state, action) => ({
81
            ...initialState,
82
            lastError: action.error.message,
83
            isLoading: false,
84
            dialogApiCallSuccess: false,
85
        }))
86
        builder.addCase(sendTextForProcessing.pending, (state) => {
87
            return {
88
                ...state,
89
                isLoading: true,
90
                dialogApiCallSuccess: false,
91
            }
92
        })
93
    },
94
})
95

    
96
export const { consumeErr, setPrimaryIdx, resetDialogApiCallSuccess, clear } = trackingToolSlice.actions
97
const trackingToolReducer = trackingToolSlice.reducer
98
export default trackingToolReducer
(7-7/8)