Created
November 29, 2019 21:01
-
-
Save martypenner/9499edea003c0e4a07cab79457236c0e to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
This file contains 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
const processItem = ({ subEvents: appliesToSubEvents, fromDate, toDate, ...item }) => ({ | |
...item, | |
appliesToSubEvents: appliesToSubEvents || [], | |
fromDate: fromDate == null || (typeof fromDate === 'string' && fromDate.trim() === '') ? null : moment(fromDate), | |
toDate: toDate == null || (typeof toDate === 'string' && toDate.trim() === '') ? null : moment(toDate), | |
}); | |
const lineItemsMachine = Machine( | |
{ | |
strict: true, | |
id: 'lineItems', | |
context: { | |
items: [], | |
itemIdsOnBackEnd: [], | |
removedItemsThatExistOnBackEnd: [], | |
itemToRemove: null, | |
maxId: 0, | |
snacks: [], | |
}, | |
type: 'parallel', | |
states: { | |
items: { | |
id: 'items', | |
initial: 'initializing', | |
states: { | |
initializing: { | |
entry: assign({ | |
items: (ctx) => | |
ctx.items.map((item, index) => { | |
const newItem = processItem({ | |
...lineItemMachine.context, | |
...item, | |
existsOnBackEnd: true, | |
}); | |
return { | |
...newItem, | |
// Reset display order to match array order. This is | |
// defensive. | |
displayOrder: index, | |
ref: spawn(lineItemMachine.withContext(newItem), `line-item-${item.id}`), | |
}; | |
}), | |
}), | |
on: { | |
// Transition immediately after settings things up | |
'': 'unknown', | |
}, | |
}, | |
// Unknown has been modeled as a separate state so we can transition | |
// directly to it instead of revisiting initializing when an item is | |
// removed | |
unknown: { | |
on: { | |
'': [ | |
{ | |
target: 'hasItems', | |
cond: 'hasItems', | |
}, | |
{ target: 'empty' }, | |
], | |
}, | |
}, | |
hasItems: {}, | |
empty: {}, | |
}, | |
}, | |
confirmation: { | |
initial: 'hidden', | |
states: { | |
hidden: {}, | |
visible: { | |
on: { | |
CONFIRMED: { | |
target: ['hidden', '#items.unknown'], | |
actions: 'deleteItem', | |
}, | |
CANCELLED: { | |
target: ['hidden', '#items.unknown'], | |
}, | |
}, | |
}, | |
}, | |
}, | |
saving: { | |
initial: 'idle', | |
states: { | |
idle: { | |
on: { | |
SAVED_ITEMS: 'saving.inPage', | |
SAVED_ITEMS_AND_EXITED: 'saving.withExit', | |
}, | |
}, | |
saving: { | |
initial: 'inPage', | |
states: { | |
inPage: { | |
invoke: { | |
src: 'saveItems', | |
onError: { | |
target: '#failure', | |
actions: 'makeSnacks', | |
}, | |
}, | |
}, | |
withExit: { | |
invoke: { | |
src: 'saveItemsWithExit', | |
onError: { | |
target: '#failure', | |
actions: 'makeSnacks', | |
}, | |
}, | |
}, | |
}, | |
}, | |
failure: { | |
id: 'failure', | |
on: { | |
SAVED_ITEMS: 'saving.inPage', | |
SAVED_ITEMS_AND_EXITED: 'saving.withExit', | |
}, | |
}, | |
}, | |
}, | |
}, | |
// In each of these events, we have to ensure that we transition to | |
// `items.unknown` explicitly. Otherwise, for SOME reason, that state thinks | |
// it needs to re-enter `initializing`, spawning new actors for each item. | |
// Clustering all unrelated states under a `ready` state and moving the | |
// `initializing` state up a level doesn't resolve the problem. | |
on: { | |
ADDED_ITEM: { | |
target: 'items.unknown', | |
actions: 'createItem', | |
}, | |
CHANGED_ITEM: { | |
target: 'items.unknown', | |
actions: 'updateItem', | |
}, | |
REMOVED_ITEM: { | |
target: ['confirmation.visible', 'items.unknown'], | |
actions: 'storeItemToRemove', | |
}, | |
EXPANDED_ALL: { | |
target: 'items.unknown', | |
actions: 'expandAll', | |
}, | |
COLLAPSED_ALL: { | |
target: 'items.unknown', | |
actions: 'collapseAll', | |
}, | |
DROPPED_ITEM: { | |
target: 'items.unknown', | |
actions: 'updateDisplayOrder', | |
}, | |
SNACK_DISMISSED: { | |
target: 'items.unknown', | |
actions: 'dismissSnack', | |
}, | |
}, | |
}, | |
{ | |
guards: { | |
hasItems: (ctx) => ctx.items.length > 0, | |
}, | |
}, | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment