Projekt

Obecné

Profil

Stáhnout (3.97 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
    pathsPerPage: number // max number of paths to show on the map at once
21
    currentPage: number // current page of paths - starts from 0
22
}
23

    
24
const defaultPathsPerPage = 5
25

    
26
const initialState: TrackingToolState = {
27
    isLoading: false,
28
    mapCenter: [
29
        mapConfig.defaultCoordinates[0],
30
        mapConfig.defaultCoordinates[1],
31
    ],
32
    primaryPathIdx: 0,
33
    activePaths: new Set(),
34
    dialogApiCallSuccess: true,
35
    pathsPerPage: defaultPathsPerPage,
36
    currentPage: 0,
37
}
38

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

    
47
const persistConfig = {
48
    key: 'auth',
49
    storage, // localStorage for browsers
50
}
51

    
52
export const trackingToolSlice = createSlice({
53
    name: 'trackingTool',
54
    initialState,
55
    reducers: {
56
        consumeErr: (state: TrackingToolState) => ({ ...state, lastErr: undefined }),
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: any) => ({
66
            ...state,
67
            currentPage: action.payload,
68
        }),
69
        clear: () => ({...initialState})
70
    },
71
    extraReducers: (builder) => {
72
        builder.addCase(sendTextForProcessing.fulfilled, (state, action) => {
73
            const pathDto: PathDto = action.payload
74
            const pathVariants = buildPathVariants(pathDto)
75
            return {
76
                ...state,
77
                pathVariants,
78
                pathDto,
79
                // TODO map this correctly
80
                activePaths: new Set(pathVariants.map((_, idx) => idx)),
81
                // TODO calculate correctly
82
                mapCenter:
83
                    pathVariants.length > 0
84
                        ? calculateMapCenter(pathVariants[0])
85
                        : (state.mapCenter as LatLngTuple),
86
                isLoading: false,
87
                dialogApiCallSuccess: true,
88
                currentPage: 0,
89
            }
90
        })
91
        builder.addCase(sendTextForProcessing.rejected, (_, action) => ({
92
            ...initialState,
93
            lastError: action.error.message,
94
            isLoading: false,
95
            dialogApiCallSuccess: false,
96
            currentPage: 0,
97
        }))
98
        builder.addCase(sendTextForProcessing.pending, (state) => {
99
            return {
100
                ...state,
101
                isLoading: true,
102
                dialogApiCallSuccess: false,
103
            }
104
        })
105
    },
106
})
107

    
108
export const { consumeErr, setPrimaryIdx, resetDialogApiCallSuccess, clear } = trackingToolSlice.actions
109
const trackingToolReducer = trackingToolSlice.reducer
110
export default trackingToolReducer
(8-8/9)