diff --git a/lib/ops/report-store-ops.js b/lib/ops/report-store-ops.js index 80d3725f3..2bb2d0ea8 100644 --- a/lib/ops/report-store-ops.js +++ b/lib/ops/report-store-ops.js @@ -1,49 +1,71 @@ // @flow import type { ClientReportCreationRequest } from '../types/report-types.js'; export type ReplaceQueuedReportOperation = { +type: 'replace_report', +payload: { +report: ClientReportCreationRequest }, }; export type RemoveQueuedReportsOperation = { +type: 'remove_reports', +payload: { +ids: $ReadOnlyArray }, }; export type RemoveAllQueuedReportsOperation = { +type: 'remove_all_reports', }; export type ReportStoreOperation = | ReplaceQueuedReportOperation | RemoveQueuedReportsOperation | RemoveAllQueuedReportsOperation; function processReportStoreOperations( queuedReports: $ReadOnlyArray, reportStoreOps: $ReadOnlyArray, ): $ReadOnlyArray { if (reportStoreOps.length === 0) { return queuedReports; } let processedReports = [...queuedReports]; for (const operation of reportStoreOps) { if (operation.type === 'replace_report') { const filteredReports = processedReports.filter( report => report.id !== operation.payload.report.id, ); processedReports = [...filteredReports, { ...operation.payload.report }]; } else if (operation.type === 'remove_reports') { processedReports = processedReports.filter( report => !operation.payload.ids.includes(report.id), ); } else if (operation.type === 'remove_all_reports') { processedReports = []; } } return processedReports; } -export { processReportStoreOperations }; +function convertReportsToReplaceReportOps( + reports: $ReadOnlyArray, +): $ReadOnlyArray { + return reports.map(report => ({ + type: 'replace_report', + payload: { report }, + })); +} + +function convertReportsToRemoveReportsOperation( + reports: $ReadOnlyArray, +): RemoveQueuedReportsOperation { + return { + type: 'remove_reports', + payload: { ids: reports.map(report => report.id) }, + }; +} + +export { + processReportStoreOperations, + convertReportsToReplaceReportOps, + convertReportsToRemoveReportsOperation, +}; diff --git a/lib/reducers/report-store-reducer.js b/lib/reducers/report-store-reducer.js index 336c07ea5..e0d64ef78 100644 --- a/lib/reducers/report-store-reducer.js +++ b/lib/reducers/report-store-reducer.js @@ -1,120 +1,143 @@ // @flow import { sendReportActionTypes, sendReportsActionTypes, queueReportsActionType, } from '../actions/report-actions.js'; import { siweAuthActionTypes } from '../actions/siwe-actions.js'; import { logOutActionTypes, deleteAccountActionTypes, logInActionTypes, } from '../actions/user-actions.js'; import type { ReportStoreOperation } from '../ops/report-store-ops.js'; +import { + convertReportsToRemoveReportsOperation, + convertReportsToReplaceReportOps, + processReportStoreOperations, +} from '../ops/report-store-ops.js'; import { isStaff } from '../shared/staff-utils.js'; import type { BaseAction } from '../types/redux-types.js'; import { type ReportStore, defaultEnabledReports, defaultDevEnabledReports, type ClientReportCreationRequest, } from '../types/report-types.js'; import { setNewSessionActionType } from '../utils/action-utils.js'; import { isDev } from '../utils/dev-utils.js'; import { isReportEnabled } from '../utils/report-utils.js'; export const updateReportsEnabledActionType = 'UPDATE_REPORTS_ENABLED'; export default function reduceReportStore( state: ReportStore, action: BaseAction, newInconsistencies: $ReadOnlyArray, ): { reportStore: ReportStore, reportStoreOperations: $ReadOnlyArray, } { + const newReports = newInconsistencies.filter(report => + isReportEnabled(report, state.enabledReports), + ); + const updatedReports = newInconsistencies.length > 0 ? [...state.queuedReports, ...newInconsistencies].filter(report => isReportEnabled(report, state.enabledReports), ) : state.queuedReports; if (action.type === updateReportsEnabledActionType) { const newEnabledReports = { ...state.enabledReports, ...action.payload }; - const filteredReports = updatedReports.filter(report => + const newFilteredReports = newReports.filter(report => isReportEnabled(report, newEnabledReports), ); + const reportsToRemove = state.queuedReports.filter( + report => !isReportEnabled(report, newEnabledReports), + ); + + const reportStoreOperations: $ReadOnlyArray = [ + convertReportsToRemoveReportsOperation(reportsToRemove), + ...convertReportsToReplaceReportOps(newFilteredReports), + ]; + + const queuedReports = processReportStoreOperations( + state.queuedReports, + reportStoreOperations, + ); + return { reportStore: { - queuedReports: filteredReports, + queuedReports, enabledReports: newEnabledReports, }, - reportStoreOperations: [], + reportStoreOperations, }; } else if ( action.type === logOutActionTypes.success || action.type === deleteAccountActionTypes.success || (action.type === setNewSessionActionType && action.payload.sessionChange.cookieInvalidated) ) { return { reportStore: { queuedReports: [], enabledReports: isDev ? defaultDevEnabledReports : defaultEnabledReports, }, reportStoreOperations: [{ type: 'remove_all_reports' }], }; } else if ( action.type === logInActionTypes.success || action.type === siweAuthActionTypes.success ) { return { reportStore: { queuedReports: [], enabledReports: isStaff(action.payload.currentUserInfo.id) || isDev ? defaultDevEnabledReports : defaultEnabledReports, }, reportStoreOperations: [{ type: 'remove_all_reports' }], }; } else if ( (action.type === sendReportActionTypes.success || action.type === sendReportsActionTypes.success) && action.payload ) { const { payload } = action; const unsentReports = updatedReports.filter( response => !payload.reports.includes(response), ); if (unsentReports.length === updatedReports.length) { return { reportStore: state, reportStoreOperations: [] }; } return { reportStore: { ...state, queuedReports: unsentReports }, reportStoreOperations: [], }; } else if (action.type === queueReportsActionType) { const { reports } = action.payload; const filteredReports = [...updatedReports, ...reports].filter(report => isReportEnabled(report, state.enabledReports), ); return { reportStore: { ...state, queuedReports: filteredReports, }, reportStoreOperations: [], }; } const reportStore = updatedReports !== state.queuedReports ? { ...state, queuedReports: updatedReports } : state; return { reportStore, reportStoreOperations: [] }; }