openreplay/frontend/app/duck/customMetrics.js
2022-12-30 17:59:56 +01:00

203 lines
No EOL
6.2 KiB
JavaScript

import { List, Map } from 'immutable';
import CustomMetric, { FilterSeries } from 'Types/customMetric'
import { fetchListType, fetchType, saveType, removeType, editType, createRemove, createEdit } from './funcTools/crud';
import { createRequestReducer, ROOT_KEY } from './funcTools/request';
import { array, success, createListUpdater, mergeReducers } from './funcTools/tools';
import Filter from 'Types/filter';
import Session from 'Types/session';
const name = "custom_metric";
const idKey = "metricId";
const FETCH_LIST = fetchListType(name);
const FETCH_SESSION_LIST = fetchListType(`${name}/FETCH_SESSION_LIST`);
const FETCH = fetchType(name);
const SAVE = saveType(name);
const ADD_SERIES = `${name}/ADD_SERIES`;
const REMOVE_SERIES = `${name}/REMOVE_SERIES`;
const ADD_SERIES_FILTER_FILTER = `${name}/ADD_SERIES_FILTER_FILTER`;
const REMOVE_SERIES_FILTER_FILTER = `${name}/REMOVE_SERIES_FILTER_FILTER`;
const EDIT_SERIES_FILTER = `${name}/EDIT_SERIES_FILTER`;
const EDIT_SERIES_FILTER_FILTER = `${name}/EDIT_SERIES_FILTER_FILTER`;
const UPDATE_ACTIVE_STATE = saveType(`${name}/UPDATE_ACTIVE_STATE`);
const EDIT = editType(name);
const INIT = `${name}/INIT`;
const SET_ACTIVE_WIDGET = `${name}/SET_ACTIVE_WIDGET`;
const REMOVE = removeType(name);
const UPDATE_SERIES = `${name}/UPDATE_SERIES`;
const updateItemInList = createListUpdater(idKey);
const updateInstance = (state, instance) => state.getIn([ "instance", idKey ]) === instance[ idKey ]
? state.mergeIn([ "instance" ], instance)
: state;
const defaultInstance = CustomMetric({
name: 'New',
series: List([
{
name: 'Series 1',
filter: new Filter({ filters: List(), eventsOrder: 'then' }),
},
])
})
const initialState = Map({
list: List(),
sessionList: List(),
alertMetricId: null,
instance: null,
activeWidget: null,
});
// Metric - Series - [] - filters
function reducer(state = initialState, action = {}) {
switch (action.type) {
// Custom Metric
case INIT:
return state.set('instance', action.instance);
case EDIT:
return state.mergeIn([ 'instance' ], action.instance);
case ADD_SERIES:
const series = new FilterSeries(action.series);
return state.updateIn([ 'instance', 'series' ], list => list.push(series));
case REMOVE_SERIES:
return state.updateIn([ 'instance', 'series' ], list => list.delete(action.index));
case UPDATE_SERIES:
return state.mergeIn(['instance', 'series', action.index], action.series);
// Custom Metric - Series - Filters
case EDIT_SERIES_FILTER:
return state.mergeIn(['instance', 'series', action.seriesIndex, 'filter'], action.filter);
// Custom Metric - Series - Filter - Filters
case EDIT_SERIES_FILTER_FILTER:
return state.updateIn([ 'instance', 'series', action.seriesIndex, 'filter', 'filters' ], filters => filters.set(action.filterIndex, action.filter));
case ADD_SERIES_FILTER_FILTER:
return state.updateIn([ 'instance', 'series', action.seriesIndex, 'filter', 'filters' ], filters => filters.push(action.filter));
case REMOVE_SERIES_FILTER_FILTER:
return state.updateIn([ 'instance', 'series', action.seriesIndex, 'filter', 'filters' ], filters => filters.delete(action.index));
case success(SAVE):
return updateItemInList(updateInstance(state, action.data), action.data);
case success(REMOVE):
return state.update('list', list => list.filter(item => item.metricId !== action.id));
case success(FETCH):
return state.set("instance", CustomMetric(action.data));
case success(FETCH_LIST):
const { data } = action;
return state.set("list", List(data.map(CustomMetric)));
case success(FETCH_SESSION_LIST):
return state.set("sessionList", List(action.data.map(item => ({ ...item, sessions: item.sessions.map(s => new Session(s)) }))));
case SET_ACTIVE_WIDGET:
return state.set("activeWidget", action.widget).set('sessionList', List());
}
return state;
}
export default mergeReducers(
reducer,
createRequestReducer({
[ ROOT_KEY ]: FETCH_LIST,
fetch: FETCH,
save: SAVE,
fetchSessionList: FETCH_SESSION_LIST,
}),
);
export const edit = createEdit(name);
export const remove = createRemove(name);
export function fetch(id) {
return {
id,
types: array(FETCH),
call: c => c.get(`/errors/${id}`),
}
}
export const save = (instance) => (dispatch, getState) => {
return dispatch({
types: SAVE.array,
call: client => client.post( `/${ instance.exists() ? name + 's/' + instance[idKey] : name + 's'}`, instance.toSaveData()),
}).then(() => {
dispatch(fetchList());
});
};
export function fetchList() {
return {
types: array(FETCH_LIST),
call: client => client.get(`/${name}s`),
};
}
export const init = (instance = null, forceNull = false) => (dispatch, getState) => {
dispatch({
type: INIT,
instance: forceNull ? null : (instance || defaultInstance),
});
}
export const fetchSessionList = (params) => (dispatch, getState) => {
dispatch({
types: array(FETCH_SESSION_LIST),
call: client => client.post(`/custom_metrics/${params.metricId}/sessions`, { ...params }),
});
}
export const setActiveWidget = (widget) => (dispatch, getState) => {
return dispatch({
type: SET_ACTIVE_WIDGET,
widget,
});
}
export const updateActiveState = (metricId, state) => (dispatch, getState) => {
return dispatch({
types: UPDATE_ACTIVE_STATE.array,
call: client => client.post(`/custom_metrics/${metricId}/status`, { active: state }),
metricId
}).then(() => {
dispatch(fetchList());
});
}
export const editSeriesFilter = (seriesIndex, filter) => (dispatch, getState) => {
return dispatch({
type: EDIT_SERIES_FILTER,
seriesIndex,
filter,
});
}
export const addSeriesFilterFilter = (seriesIndex, filter) => (dispatch, getState) => {
return dispatch({
type: ADD_SERIES_FILTER_FILTER,
seriesIndex,
filter,
});
}
export const removeSeriesFilterFilter = (seriesIndex, filterIndex) => (dispatch, getState) => {
return dispatch({
type: REMOVE_SERIES_FILTER_FILTER,
seriesIndex,
index: filterIndex,
});
}
export const editSeriesFilterFilter = (seriesIndex, filterIndex, filter) => (dispatch, getState) => {
return dispatch({
type: EDIT_SERIES_FILTER_FILTER,
seriesIndex,
filterIndex,
filter,
});
}