diff --git a/src/components/containers/EventsBrowser.tsx b/src/components/containers/EventsBrowser.tsx index c0602818..30314eeb 100644 --- a/src/components/containers/EventsBrowser.tsx +++ b/src/components/containers/EventsBrowser.tsx @@ -52,6 +52,8 @@ export type EventBrowserProps = { fields?: boolean; metadata?: boolean; }; + cursor?: string; + searchText?: string; }; interface EventBrowserState { @@ -155,41 +157,34 @@ class EventsBrowser extends React.Component) { + if (this.props.session.token !== prevProps.session.token) { + this.submitQuery(this.props.searchText ?? "crud:c,u,d", this.props.cursor ?? ""); + } + + if (this.props.auditLogToken !== prevProps.auditLogToken) { + this.props.createSession(this.props.auditLogToken, this.props.host); + } + } + handleRefreshToken() { if (typeof this.props.refreshToken === "function") { this.props.refreshToken(); } } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { if (this.props.currentResults !== nextProps.currentResults) { this.onEventsChange(this.props.currentResults, nextProps.currentResults); } } - componentWillUpdate(nextProps) { - // If we have a new token, we need to create a new session - - if (this.props.auditLogToken !== nextProps.auditLogToken) { - this.props.createSession(nextProps.auditLogToken, this.props.host); - } - // If we have a new session, we need to request a new event search - - if (this.props.session.token !== nextProps.session.token) { - // use same initial query that the search button would use - this.submitQuery("crud:c,u,d", ""); - } - } - componentWillUnmount() { // Clearing the store - this.props.clearSession(); } @@ -203,6 +198,7 @@ class EventsBrowser extends React.Component ({ requestEventSearch(query, handleRefreshToken) { diff --git a/src/components/modals/AccessTokensModal.jsx b/src/components/modals/AccessTokensModal.jsx index 2fdaa3fe..ca561ee9 100644 --- a/src/components/modals/AccessTokensModal.jsx +++ b/src/components/modals/AccessTokensModal.jsx @@ -27,7 +27,7 @@ class AccessTokensModal extends React.Component { }; } - componentWillMount() { + UNSAFE_componentWillMount() { this.props.fetchEitapiTokensList(); } diff --git a/src/components/modals/ExportEventsModal.jsx b/src/components/modals/ExportEventsModal.jsx index b5cafdcc..81465d36 100644 --- a/src/components/modals/ExportEventsModal.jsx +++ b/src/components/modals/ExportEventsModal.jsx @@ -26,7 +26,7 @@ class ExportEventsModal extends React.Component { } } - componentWillMount() { + UNSAFE_componentWillMount() { this.props.fetchSavedExports(); } diff --git a/src/components/views/SearchForm.jsx b/src/components/views/SearchForm.jsx index be9a620e..6f45a9f6 100644 --- a/src/components/views/SearchForm.jsx +++ b/src/components/views/SearchForm.jsx @@ -24,11 +24,31 @@ function getDateFormatString(lang = "default") { .join(""); } +const initialState = { + query: "", + receivedStartDate: null, + receivedEndDate: null, + searchQuery: "", + crudFiltersArray: ["c", "u", "d"], + crudFilters: { + cChecked: true, + rChecked: false, + uChecked: true, + dChecked: true, + }, + isDefault: true, +}; + export default class SearchForm extends React.Component { constructor(props) { super(props); autoBind(this); this.dateFormatString = getDateFormatString(); + this.state = initialState; + } + + setInitialState() { + this.setState(initialState); } onChange = (e) => { @@ -39,7 +59,7 @@ export default class SearchForm extends React.Component { }; handleCrudFilterChange(field, e) { - let newCrudFilters = this.state.crudFiltersArray; + let newCrudFilters = [...this.state.crudFiltersArray]; if (!newCrudFilters.includes(field)) { newCrudFilters.push(field); } else { @@ -72,25 +92,7 @@ export default class SearchForm extends React.Component { }); } - setInitialState() { - this.setState({ - query: "", - receivedStartDate: null, - receivedEndDate: null, - searchQuery: "", - crudFiltersArray: ["c", "u", "d"], - crudFilters: { - cChecked: true, - rChecked: false, - uChecked: true, - dChecked: true, - }, - isDefault: true, - }); - } - componentDidMount() { - this.setInitialState(); this.props.hasFilters(this.state); } @@ -144,7 +146,7 @@ export default class SearchForm extends React.Component { ({ ...acc, [cur.key]: cur.value }), {}); @@ -113,7 +114,10 @@ export function requestEventSearch(query, refreshToken, toggleDisplay) { dispatch(receiveEventList(query, data.data.search.totalCount, events, cursor)); dispatch(loadingData("eventFetch", false)); } else { + // token expired store cursor and query,then refresh token dispatch(loadingData("eventFetch", false)); + dispatch(storeCursor(query.cursor)); + dispatch(storeSearchText(query.search_text)); if (refreshToken && typeof refreshToken === "function") { refreshToken(); } diff --git a/src/redux/index.js b/src/redux/index.js index 6f4ac1ec..fe537909 100644 --- a/src/redux/index.js +++ b/src/redux/index.js @@ -19,10 +19,13 @@ const rootReducer = (state, action) => { // Global store instance export function configStore() { - const hasExtension = window.devToolsExtension; + const middleware = [thunk]; + let enhancers = [applyMiddleware(...middleware)]; - return createStore( - rootReducer, - compose(applyMiddleware(thunk), hasExtension ? window.devToolsExtension() : (f) => f) - ); + // Add Redux DevTools extension only if running in a browser environment + if (typeof window !== "undefined" && window.__REDUX_DEVTOOLS_EXTENSION__) { + enhancers.push(window.__REDUX_DEVTOOLS_EXTENSION__()); + } + + return createStore(rootReducer, compose(...enhancers)); } diff --git a/src/redux/ui/actions.js b/src/redux/ui/actions.js index b28fb230..1d9a8644 100644 --- a/src/redux/ui/actions.js +++ b/src/redux/ui/actions.js @@ -1,20 +1,7 @@ export const constants = { - DISPLAY_MODAL: "DISPLAY_MODAL", LOADING_DATA: "LOADING_DATA", - TIME_FILTER: "TIME_FILTER", - CRUD_FILTER: "CRUD_FILTER", }; -export function displayModal(key, display) { - return { - type: constants.DISPLAY_MODAL, - payload: { - key, - display, - }, - }; -} - export function loadingData(key, isLoading) { return { type: constants.LOADING_DATA, @@ -24,21 +11,3 @@ export function loadingData(key, isLoading) { }, }; } - -export function timeFilter(timerange) { - return { - type: constants.TIME_FILTER, - payload: { - timerange, - }, - }; -} - -export function crudFilter(crud) { - return { - type: constants.CRUD_FILTER, - payload: { - crud, - }, - }; -} diff --git a/src/redux/ui/events/actions.js b/src/redux/ui/events/actions.js new file mode 100644 index 00000000..bb8117ca --- /dev/null +++ b/src/redux/ui/events/actions.js @@ -0,0 +1,22 @@ +export const constants = { + STORE_CURSOR: "STORE_CURSOR", + STORE_SEARCH_TEXT: "STORE_SEARCH_TEXT", +}; + +export function storeCursor(cursor) { + return { + type: constants.STORE_CURSOR, + payload: { + cursor, + }, + }; +} + +export function storeSearchText(searchText) { + return { + type: constants.STORE_SEARCH_TEXT, + payload: { + searchText, + }, + }; +} diff --git a/src/redux/ui/events/reducer.js b/src/redux/ui/events/reducer.js index efb3f218..2ea25ef6 100644 --- a/src/redux/ui/events/reducer.js +++ b/src/redux/ui/events/reducer.js @@ -1,3 +1,5 @@ +import { constants } from "./actions"; + const initialState = { eventTableHeaderItems: [ { @@ -14,10 +16,17 @@ const initialState = { field: "source_ip", }, ], + // keep cursor in state to refetch the just requested page that failed due to token expiry + cursor: "", + searchText: "crud:c,u,d", }; export default (state = initialState, action) => { switch (action.type) { + case constants.STORE_CURSOR: + return { ...state, cursor: action.payload.cursor }; + case constants.STORE_SEARCH_TEXT: + return { ...state, searchText: action.payload.searchText }; default: return state; } diff --git a/src/redux/ui/index.js b/src/redux/ui/index.js index 000e2003..1881a314 100644 --- a/src/redux/ui/index.js +++ b/src/redux/ui/index.js @@ -1,10 +1,8 @@ import { combineReducers } from "redux"; -import { modalData, loadingData, filterData } from "./reducer"; +import { loadingData } from "./reducer"; import eventsUiData from "./events/reducer"; export default combineReducers({ - modalData, loadingData, - filterData, eventsUiData, }); diff --git a/src/redux/ui/reducer.js b/src/redux/ui/reducer.js index 7fb6853c..c062ffda 100644 --- a/src/redux/ui/reducer.js +++ b/src/redux/ui/reducer.js @@ -1,15 +1,5 @@ -import dayjs from "dayjs"; import { constants } from "./actions"; -const modalState = {}; - -export function modalData(state = modalState, action = {}) { - switch (action.type) { - default: - return state; - } -} - const loadingState = { eventFetchLoading: false, exportCSVLoading: false, @@ -27,26 +17,3 @@ export function loadingData(state = loadingState, action = {}) { return state; } } - -const filterState = { - timerange: { - start: dayjs().startOf("day").valueOf(), - end: dayjs().endOf("day").valueOf(), - }, - crud: "cud", -}; - -export function filterData(state = filterState, action = {}) { - switch (action.type) { - case constants.TIME_FILTER: - return Object.assign({}, state, { - timerange: action.payload.timerange, - }); - case constants.CRUD_FILTER: - return Object.assign({}, state, { - crud: action.payload.crud, - }); - default: - return state; - } -}