Files
trunk-server/frontend/src/features/calls/callsSlice.js
2023-01-14 22:43:10 -05:00

274 lines
8.6 KiB
JavaScript

import {
createSlice,
createEntityAdapter,
createSelector,
createAsyncThunk
} from '@reduxjs/toolkit'
/*
import { apiSlice } from '../api/apiSlice'
// in order for the initial fetch to happen this call needs to be made in index.js
// store.dispatch(extendedApiSlice.endpoints.getCalls.initiate())
export const callsAdapter = createEntityAdapter({
selectId: (call) => call._id,
sortComparer: (a, b) => a.time.localeCompare(b.time),
})
const initialState = callsAdapter.getInitialState()
export const extendedApiSlice = apiSlice.injectEndpoints({
endpoints: builder => ({
getCalls: builder.query({
query: ({shortName,filterType=0,filterCode=0}) => ({
url: `/${shortName}/calls`,
method: "GET",
params: { filterType, filterCode },
}),
transformResponse: responseData => {
responseData = responseData.calls;
return callsAdapter.setAll(initialState, responseData)
}
})
})
})
// from tutorials: https://redux.js.org/tutorials/essentials/part-8-rtk-query-advanced#transforming-responses
export const { useGetCallsQuery } = extendedApiSlice
// Calling `someEndpoint.select(someArg)` generates a new selector that will return
// the query result object for a query with those parameters.
// To generate a selector for a specific query argument, call `select(theQueryArg)`.
// In this case, the users query has no params, so we don't pass anything to select()
export const selectCallsResult = extendedApiSlice.endpoints.getCalls.select({"shortName":"test"})
const selectCallsData = createSelector(
selectCallsResult,
(callsResult) => {
return callsResult.data
}
)
export const { selectAll: selectAllCalls, selectById: selectCallById } = callsAdapter.getSelectors(state => {
return selectCallsData(state) ?? initialState
})
*/
const now = new Date();
export const callsAdapter = createEntityAdapter({
selectId: (call) => call._id,
sortComparer: (a, b) => b.time.localeCompare(a.time),
})
const initialState = {
loading: false,
data: callsAdapter.getInitialState(),
oldestCallTime: now,
newestCallTime: now,
}
function buildUrlParams(a) {
return Object.keys(a).map(function(k) {
return encodeURIComponent(k) + '=' + encodeURIComponent(a[k])
}).join('&')
}
function buildCallUrl(getState, direction=false, date=false) {
var params = {};
var url = "";
const {shortName,filterType,filterGroupId, filterTalkgroups, filterStarred, filterDate} = getState().callPlayer;
if ((typeof direction === 'string') && (typeof date === 'number')) {
url = url + '/' + direction;
params["time"] = date;
} else {
if (filterDate){
url = url + '/older'
params["time"] = filterDate;
}
}
if (filterStarred) {
params["filter-starred"] = true;
}
switch(filterType) {
case 1:
params["filter-type"] = "group";
params["filter-code"] = filterGroupId;
break;
case 2:
params["filter-type"] = "talkgroup";
params["filter-code"] = filterTalkgroups;
break;
default:
case 0:
}
/*
if (this.filterCode != "") {
params["filter-code"] = this.filterCode;
}
if (this.filterType == this.FilterType.Group) {
params["filter-type"] = "group";
params["filter-name"] = this.filterName;
}
if (this.filterType == this.FilterType.Talkgroup) {
params["filter-type"] = "talkgroup";
}
if (this.filterType == this.FilterType.Unit) {
params["filter-type"] = "unit";
}
*/
// url = startUp.backend_server + "/" + startUp.shortName.toLowerCase() + "/calls" + url + '?' + buildUrlParams(params);
url = process.env.REACT_APP_BACKEND_SERVER + "/" + shortName + "/calls" + url + '?' + buildUrlParams(params);
console.log("Trying to fetch data from this url: " + url);
return url;
}
export const addStar = createAsyncThunk(
'calls/addStar',
async(callId,{getState, requestIdleCallback}) => {
const {shortName} = getState().callPlayer;
const url = process.env.REACT_APP_BACKEND_SERVER + "/" + shortName.toLowerCase() + "/star/" + callId
const res = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: "{}"
}).then(
(data) => data.json()
)
return res;
}
)
export const removeStar = createAsyncThunk(
'calls/removeStar',
async(callId,{getState, requestIdleCallback}) => {
const {shortName} = getState().callPlayer;
const url = process.env.REACT_APP_BACKEND_SERVER + "/" + shortName.toLowerCase() + "/removeStar/" + callId
const res = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: "{}"
}).then(
(data) => data.json()
)
return res;
}
)
export const getCalls = createAsyncThunk(
'calls/getCalls',
async({},{getState, requestId}) => {
const state = getState()
const {loading,oldestCallTime, newestCallTime} = getState().calls;
const url = buildCallUrl(getState);
const res = await fetch(url).then(
(data) => data.json()
)
return res;
})
export const getOlderCalls = createAsyncThunk(
'calls/getOlderCalls',
async({},{getState, requestId} ) => {
const {loading,oldestCallTime, newestCallTime} = getState().calls;
const url = buildCallUrl(getState,"older",oldestCallTime.getTime());
const res = await fetch(url).then(
(data) => data.json()
)
return res;
})
export const getNewerCalls = createAsyncThunk(
'calls/getNewerCalls',
async({},{getState, requestId} ) => {
const {loading,oldestCallTime, newestCallTime} = getState().calls;
const url = buildCallUrl(getState,"newer",newestCallTime.getTime());
const res = await fetch(url).then(
(data) => data.json()
)
return res;
})
export const callsSlice = createSlice({
name: 'calls',
initialState,
reducers: {
addCall: (call) => {
state.data = callsAdapter.addOne(state.data, call)
},
},
extraReducers: {
[getCalls.pending]: (state) => {
state.loading = true;
},
[getCalls.rejected]: (state) => {
state.loading = false;
},
[getCalls.fulfilled]: (state, {payload}) => {
state.loading = false;
state.data = callsAdapter.setAll(state.data, payload.calls)
if (state.data && (state.data.ids.length > 0)) {
const first = state.data.ids[0]
const firstTime = state.data.entities[first].time;
const last = state.data.ids[state.data.ids[0].length-1];
const lastTime = state.data.entities[last].time;
state.newestCallTime = new Date(firstTime)
state.oldestCallTime = new Date(lastTime)
}
},
[getOlderCalls.pending]: (state) => {
state.loading = true;
},
[getOlderCalls.rejected]: (state) => {
state.loading = false;
},
[getOlderCalls.fulfilled]: (state, {payload}) => {
state.loading = false;
state.data = callsAdapter.addMany(state.data, payload.calls)
if (state.data && (state.data.ids.length > 0)) {
const first = state.data.ids[0]
const firstTime = state.data.entities[first].time;
const last = state.data.ids[state.data.ids[0].length-1];
const lastTime = state.data.entities[last].time;
state.newestCallTime = new Date(firstTime)
state.oldestCallTime = new Date(lastTime)
}
},
[getNewerCalls.pending]: (state) => {
state.loading = true;
},
[getNewerCalls.rejected]: (state) => {
state.loading = false;
},
[getNewerCalls.fulfilled]: (state, {payload}) => {
state.loading = false;
state.data = callsAdapter.addMany(state.data, payload.calls)
if (state.data && (state.data.ids.length > 0)) {
const first = state.data.ids[0]
const firstTime = state.data.entities[first].time;
const last = state.data.ids[state.data.ids[0].length-1];
const lastTime = state.data.entities[last].time;
state.newestCallTime = new Date(firstTime)
state.oldestCallTime = new Date(lastTime)
}
},
[addStar.fulfilled]: (state, {payload}) => {
state.data.entities[payload.call._id] = payload.call;
},
[removeStar.fulfilled]: (state, {payload}) => {
state.data.entities[payload.call._id] = payload.call;
}
}
})
export const callsReducer = callsSlice.reducer;