github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/redux/reducers/serviceDiscovery.ts (about) 1 import { Target } from '@webapp/models/targets'; 2 import { fetchTargets } from '@webapp/services/serviceDiscovery'; 3 import { createSlice } from '@reduxjs/toolkit'; 4 import { addNotification } from './notifications'; 5 import type { RootState } from '../store'; 6 import { createAsyncThunk } from '../async-thunk'; 7 8 export const loadTargets = createAsyncThunk( 9 'serviceDiscovery/loadTargets', 10 async (_, thunkAPI) => { 11 const res = await fetchTargets(); 12 13 if (res.isOk) { 14 return Promise.resolve(res.value); 15 } 16 17 thunkAPI.dispatch( 18 addNotification({ 19 type: 'danger', 20 title: 'Failed to load targets', 21 message: res.error.message, 22 }) 23 ); 24 25 return Promise.reject(res.error); 26 } 27 ); 28 29 interface State { 30 type: 'pristine' | 'loading' | 'failed' | 'loaded'; 31 data: Target[]; 32 } 33 const initialState: State = { type: 'loaded', data: [] }; 34 35 export const serviceDiscoverySlice = createSlice({ 36 name: 'serviceDiscovery', 37 initialState, 38 reducers: {}, 39 extraReducers: (builder) => { 40 builder.addCase(loadTargets.fulfilled, (state, action) => { 41 state.data = action.payload; 42 state.type = 'loaded'; 43 }); 44 45 builder.addCase(loadTargets.pending, (state) => { 46 state.type = 'loading'; 47 }); 48 builder.addCase(loadTargets.rejected, (state) => { 49 state.type = 'failed'; 50 }); 51 }, 52 }); 53 54 export default serviceDiscoverySlice.reducer; 55 56 export function selectTargetsData(s: RootState) { 57 return s.serviceDiscovery.data; 58 }