app/addons/documents/changes/reducers.js (94 lines of code) (raw):

// Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. import ActionTypes from './actiontypes'; import Helpers from '../helpers'; const initialState = { isLoaded: false, filters: [], changes: [], filteredChanges: [], maxChangesListed: 100, showingSubset: false, lastSequenceNum: null }; function updateChanges(state, seqNum, changes, reset) { // reset to the initial state when switching between databases so changes aren't carried over const newState = (reset) ? { ...initialState, // make a note of the most recent sequence number. This is used for a point of reference for polling for new changes lastSequenceNum: seqNum, isLoaded: true } : { ...state, lastSequenceNum: seqNum, isLoaded: true }; // mark any additional changes that come after first page load as "new" so we can add a nice highlight effect // when the new row is rendered const firstBatch = newState.changes.length === 0; newState.changes.forEach((change) => { change.isNew = false; }); const newChanges = changes.map((change) => { const seq = Helpers.getSeqNum(change.seq); return { id: change.id, seq: seq, deleted: _.has(change, 'deleted') ? change.deleted : false, changes: change.changes, doc: change.doc, // only populated with ?include_docs=true isNew: !firstBatch }; }); // add the new changes to the start of the list newState.changes = newChanges.concat(newState.changes); updateFilteredChanges(newState); return newState; } function addFilter(state, filter) { const newFilters = state.filters.slice(); newFilters.push(filter); const newState = { ...state, filters: newFilters }; updateFilteredChanges(newState); return newState; } function removeFilter(state, filter) { const newFilters = state.filters.slice(); const idx = newFilters.indexOf(filter); if (idx >= 0) { newFilters.splice(idx, 1); } const newState = { ...state, filters: newFilters }; updateFilteredChanges(newState); return newState; } function updateFilteredChanges(state) { state.showingSubset = false; let numMatches = 0; state.filteredChanges = state.changes.filter((change) => { if (numMatches >= state.maxChangesListed) { state.showingSubset = true; return false; } let changeStr = JSON.stringify(change); let match = state.filters.every((filter) => { return new RegExp(filter, 'i').test(changeStr); }); if (match) { numMatches++; } return match; }); } export default function changes (state = initialState, action) { switch (action.type) { case ActionTypes.UPDATE_CHANGES: return updateChanges(state, action.seqNum, action.changes, action.resetChanges); case ActionTypes.ADD_CHANGES_FILTER_ITEM: return addFilter(state, action.filter); case ActionTypes.REMOVE_CHANGES_FILTER_ITEM: return removeFilter(state, action.filter); default: return state; } }