Last active
November 19, 2019 03:35
-
-
Save airandopal/bc0abefb5a7fa7e0ab5e2d991d6b2633 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
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
| // todo: move these to guards object in machine | |
| const isError = (context, event) => { | |
| return context.isError; | |
| }; | |
| const isNoError = (context, event) => { | |
| return context.noError; | |
| }; | |
| const isComplete = (context, event) => { | |
| return context.isComplete; | |
| }; | |
| const stripeElement = { | |
| id: "stripeElement", | |
| initial: "empty", | |
| states: { | |
| empty: { | |
| on: { | |
| // this might need conditions | |
| SE_CHANGE: "noError" | |
| } | |
| }, | |
| noError: { | |
| on: { | |
| // didnt know how else to change context in the visualizer... | |
| HELPER: { | |
| actions: assign({ isComplete: true }) | |
| }, | |
| SE_CHANGE: [ | |
| { target: "error", cond: isError }, | |
| { target: "noError", cond: isNoError }, | |
| { target: "complete", cond: isComplete }, | |
| { target: "noError" } | |
| ] | |
| } | |
| }, | |
| error: { | |
| on: { | |
| // conditions... | |
| // CHANGE: [], | |
| SE_ERROR: "error", | |
| SE_NO_ERROR: "noError" | |
| } | |
| }, | |
| complete: { type: "final" } | |
| } | |
| }; | |
| const cardholderName = { | |
| id: "cardholderName", | |
| initial: "empty", | |
| states: { | |
| // from empty it can only go to noError becaue once one letter is typed it would be an error | |
| empty: { | |
| on: { | |
| // this might need conditions | |
| CN_CHANGE: "error" | |
| } | |
| }, | |
| noError: { | |
| on: { | |
| CN_ERROR: "error", | |
| CN_NO_ERROR: "noError", | |
| CN_VALID: "valid" | |
| } | |
| }, | |
| error: { | |
| on: { | |
| // conditions... | |
| // CHANGE: [], | |
| CN_ERROR: "error", | |
| CN_NO_ERROR: "noError" | |
| } | |
| }, | |
| valid: { type: "final" } | |
| } | |
| }; | |
| // todo: use only elementStates, not isComplete [currently used with assign helper in testing] | |
| const context = { | |
| mountedElement: null, | |
| elementStates: { | |
| error: null, | |
| complete: null, | |
| empty: null | |
| }, | |
| cardholderName: '', | |
| setupIntent: null, | |
| isComplete: false, | |
| retries: 0, | |
| stripeElementLoadAttempts: 0, | |
| } | |
| const fetchMachine = Machine({ | |
| id: 'fetch', | |
| initial: 'closed', | |
| context, | |
| states: { | |
| closed: { | |
| on: { | |
| // user clicks button to reveal the form | |
| OPEN: 'loading' | |
| } | |
| }, | |
| // this is where things are being created, call to get a setup intent, etc. loading / creating the form | |
| // seems like this needs to invoke and then onDone or onError move along accordingly | |
| loading: { | |
| on: { | |
| SUCCESS: 'editPhase', | |
| FAIL: 'failedUI' | |
| } | |
| }, | |
| editPhase: { | |
| id: "fields", | |
| type: "parallel", | |
| onDone: "readyToSubmit", | |
| states: { | |
| stripeElement, | |
| cardholderName | |
| } | |
| }, | |
| readyToSubmit: { | |
| on: { | |
| SUBMIT: 'submitting' | |
| } | |
| }, | |
| // on, success, move to submitted good submission | |
| submitting: { | |
| on: { | |
| GOOD_RESPONSE: 'submitted.goodSubmission', | |
| BAD_RESPONSE: 'submitted.failedSubmit' | |
| } | |
| }, | |
| failedUI: { | |
| on: { | |
| // todo: retry a few times and if failed all those times then reportbug and exit and do not allow to return for x amount of time? | |
| RETRY: 'loading', // or should be editing | |
| EXIT: '#fetch.closed', // this actually needs to exit the whole component | |
| // maybe | |
| SEND_FEEDBACK: '#reportBug' | |
| } | |
| }, | |
| // did have it in submitted, but from failed ui might need to report bug. [is report bug a parallel state, would anythinge else be open when its showing?] | |
| reportBug: { | |
| // onEntry show reportBug modal... | |
| id: 'reportBug' | |
| }, | |
| submitted: { | |
| id: 'submitted', | |
| states: { | |
| failedSubmit: { | |
| on: { | |
| // requires guards | |
| RETRY: {}, | |
| // this might be wehre i invoke another machine - the report bug form machine | |
| SEND_FEEDBACK: '#reportBug', | |
| EXIT: '#fetch.closed' | |
| } | |
| }, | |
| // is this really final tho? wouldnt closed be a final? answer: thats what exit action can do. | |
| goodSubmission: { | |
| type: 'final', | |
| // use a timeout for effect? | |
| exit: 'closeForm' | |
| } | |
| }, | |
| }, | |
| }, | |
| on: { | |
| // aka cancel, clear / need onExit here to perform clearing of the form - do i need a new setup intent in some cases? is that a case / guard to handle | |
| // reset will reset form but does not exit | |
| // cancel/exit will kill form, unmount stripe elements etc, and close the component back to the button. should also do entry and exit analytics like mark cancelled setup intent etc. | |
| RESET: 'editPhase', | |
| CANCEL: 'closed', | |
| } | |
| }); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment