Created
January 15, 2019 19:58
-
-
Save beaucollins/bf12010d72252bee6573f66e1ff259d4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * @flow | |
| * @format | |
| */ | |
| /** | |
| * External dependencies | |
| */ | |
| import { reduce, isEmpty } from 'lodash'; | |
| /** | |
| * Internal dependencies | |
| */ | |
| import { | |
| hasMyScheduleModifications, | |
| getMyScheduleModifications, | |
| } from 'state/ui/selectors'; | |
| import { | |
| setMyScheduleModifications, | |
| } from 'state/ui/actions'; | |
| import { | |
| saveDaySettings, | |
| } from 'state/entities/day-settings/actions'; | |
| import { | |
| updateAvailabilityBlocks, | |
| } from 'state/entities/availability-blocks/actions'; | |
| /** | |
| * Flow | |
| */ | |
| import type { AppMiddleware, ActionTypes } from 'state'; | |
| import type { DaySettings } from 'state/entities/day-settings/reducer'; | |
| import type { ScheduleModifications } from 'state/ui/reducers'; | |
| /** | |
| * The Schedule Modifications (dirty blocks cache) can have deletion entries for | |
| * blocks that only existed temporarily client-side. These entries end up generating | |
| * events on save that are invalid as the blocks were never persisted before the delete. | |
| * | |
| * This function prevents save output from leaking ephemeral delete data to the | |
| * backend interactions by checking the modifications against previously persisted | |
| * block entities (props.existingAvailabilityBlocksInTimespan) before making the save attempt. | |
| */ | |
| const removeTemporaryBlocksFromSaveOutput = ( | |
| modifications: ScheduleModifications, | |
| ): ScheduleModifications => { | |
| return { | |
| ...modifications, | |
| deleted: modifications.deleted.filter( | |
| // TODO, filter out task blocks | |
| block => block, | |
| ), | |
| }; | |
| }; | |
| /** | |
| * Performs all of the required tasks to save a schedule's set of data | |
| * that currently includes 0-7 day settings and all of the block modifications | |
| */ | |
| const middleware: AppMiddleware = store => next => (action: ActionTypes) => { | |
| switch (action.type) { | |
| case 'UI_MY_SCHEDULE_SAVE': { | |
| // are we going to save the schedule? | |
| return new Promise(resolve => { | |
| const state = store.getState(); | |
| const hasModifications = hasMyScheduleModifications(state); | |
| if (!hasModifications) { | |
| resolve(); | |
| } | |
| const modifications = getMyScheduleModifications(state); | |
| /** | |
| * Save all daySettings that need to be saved | |
| */ | |
| const pending: Array<Promise<*>> = reduce( | |
| modifications.daySettings, | |
| (tasks, daySettings: DaySettings) => { | |
| // Don't save default day settings. | |
| if (!daySettings.daySettingsId) { | |
| return tasks; | |
| } | |
| return [...tasks, Promise.resolve(store.dispatch(saveDaySettings(daySettings)))]; | |
| }, | |
| [] | |
| ); | |
| /** | |
| * If there are modifications also save them | |
| */ | |
| if (!isEmpty(modifications.updated) || !isEmpty(modifications.deleted)) { | |
| // TODO: de we dispatch or de we use the event store api ourselves somehow? | |
| // this.props.updateAvailabilityBlocks(this.removeTemporaryBlocksFromSaveOutput(modifications)); | |
| pending.push(Promise.resolve(store.dispatch(updateAvailabilityBlocks(removeTemporaryBlocksFromSaveOutput(modifications))))); | |
| } | |
| /** | |
| * Wait for all tasks to resolve | |
| */ | |
| Promise.all(pending).then( | |
| () => console.log('hooray'), | |
| error => console.log('oops') | |
| ); | |
| /** | |
| * Clear out the modifications | |
| */ | |
| // @todo: switch to this.resetMyScheduleModifications, | |
| // but we have to re-work the way day settings save first | |
| store.dispatch(setMyScheduleModifications({ | |
| ...modifications, | |
| updated: [], | |
| deleted: [], | |
| })); | |
| }); | |
| } | |
| } | |
| return next(action); | |
| }; | |
| export default middleware; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment