Skip to content

Instantly share code, notes, and snippets.

@derek-duncan
Last active August 21, 2019 20:14
Show Gist options
  • Save derek-duncan/763d66489b057738c2c0d83cddfa7b7d to your computer and use it in GitHub Desktop.
Save derek-duncan/763d66489b057738c2c0d83cddfa7b7d to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
Machine({
context: {
entryType: null,
isPending: false,
isDropping: false,
dropStatus: 'idle',
formError: null,
locationId: null,
practiceId: null,
practices: [],
},
id: 'practice',
type: 'parallel',
states: {
upload: {
initial: 'dropIdle',
states: {
dropIdle: {
onEntry: 'resetDrop',
on: {
DROP_START: 'dropActive',
},
},
dropActive: {
onEntry: 'startDrop',
on: {
DROP_CANCEL: 'dropIdle',
DROP_REJECT: 'dropRejected',
DROP_ACCEPT: 'dropAccepted',
},
},
dropRejected: {
onEntry: 'rejectDrop',
after: { dropReset: 'dropIdle' },
},
dropAccepted: {
// TODO: Maybe this should be accepted onDone
onEntry: 'acceptDrop',
invoke: {
id: 'processTokens',
src: 'processTokens',
onDone: {
target: 'dropIdle',
actions: ['assignProcessedTokens', 'notifyPracticeChange'],
},
onError: 'dropRejected',
},
},
},
},
tokenLookup: {
initial: 'tokenLookupIdle',
states: {
tokenLookupIdle: {
after: {
tokenLookup: [
{ cond: 'isAutoAuthAvailable', target: 'tokenLookupPending' },
{ target: 'tokenLookupIdle' },
],
},
on: {
TOKEN_LOOKUP_START: [
{ cond: 'isAutoAuthAvailable', target: 'tokenLookupPending' },
{ target: 'tokenLookupIdle' },
],
},
},
tokenLookupPending: {
onEntry: 'startPending',
onExit: 'stopPending',
on: {
TOKEN_LOOKUP_CANCEL: 'tokenLookupIdle',
},
initial: 'tokenLookupPendingSearching',
states: {
tokenLookupPendingSearching: {
invoke: {
id: 'searchForPracticeToken',
src: 'searchForPracticeToken',
onDone: 'tokenLookupPendingProcessing',
onError: '#practice.tokenLookup.tokenLookupIdle',
},
},
tokenLookupPendingProcessing: {
invoke: {
src: 'processTokens',
onDone: {
target: '#practice.tokenLookup.tokenLookupIdle',
actions: ['assignProcessedTokens', 'notifyPracticeChange'],
},
onError: '#practice.tokenLookup.tokenLookupIdle',
},
},
},
},
},
},
authStatus: {
initial: 'authStatusBoot',
on: {
REBOOT: '.authStatusBoot',
},
states: {
authStatusBoot: {
on: {
'': [
{ cond: 'hasValidToken', target: 'authenticated' },
{ target: 'unauthenticated' },
],
},
},
unauthenticated: {
onEntry: 'setPracticeTitle',
initial: 'unauthenticatedBoot',
states: {
unauthenticatedBoot: {
on: {
'': [
{ cond: 'isAutoAuthAvailable', target: 'autoInput' },
{ target: 'manualInput' },
],
},
},
autoInput: {
onEntry: ['setAuto'],
on: {
USE_MANUAL: {
target: 'manualInput',
actions: ['showManualCancel'],
},
},
},
manualInput: {
onEntry: 'setManual',
on: {
CANCEL_MANUAL: 'unauthenticatedBoot',
},
initial: 'manualIdle',
states: {
manualIdle: {
on: {
MANUAL_AUTH_SUBMIT: 'manualPending',
},
},
manualPending: {
onEntry: 'startPending',
onExit: 'stopPending',
invoke: {
src: 'processTokens',
onDone: {
target: '#practice.authStatus.authenticated',
actions: [
'assignProcessedTokens',
'notifyPracticeChange',
],
},
onError: 'manualIdle',
},
},
},
},
},
},
authenticated: {
onEntry: 'setPracticeTitle',
on: {
CHANGE_PRACTICE: {
actions: ['changePractice', 'setPracticeTitle'],
},
PRACTICE_LOGOUT: {
target: 'unauthenticated',
actions: ['clearPractices', 'notifyPracticeChange'],
},
},
initial: 'refreshPractices',
states: {
refreshPractices: {
initial: 'refreshPracticesIdle',
states: {
refreshPracticesIdle: {
after: { refreshPractices: 'refreshPracticesPending' },
},
refreshPracticesPending: {
invoke: {
src: 'refreshPractices',
onDone: {
target: 'refreshPracticesIdle',
actions: ['setPracticeTitle', 'notifyPracticeChange'],
},
onError: 'refreshPracticesIdle',
},
},
},
},
},
},
},
},
},
}, {
actions: {
setAuto: assign({
entryType: 'auto',
}),
setManual: assign({
entryType: 'manual',
}),
startPending: assign({
isPending: true,
}),
stopPending: assign({
isPending: false,
}),
startDrop: assign({
isDropping: true,
}),
resetDrop: assign({
isDropping: false,
dropStatus: 'idle',
}),
acceptDrop: assign({
dropStatus: 'accepted',
}),
rejectDrop: assign({
dropStatus: 'rejected',
}),
clearPractices: assign({
practiceId: null,
practices: [],
}),
assignProcessedTokens: assign((ctx, e) => {
if (e.type !== 'done.invoke.processTokens')
throw new Error('Event must be CHANGE_PRACTICE to call this action');
let practice = e.data.practices.find(p => p.instinctId === e.data.selectedPracticeId);
if (!practice)
practice = ctx.practices[0];
return {
practices: e.data.practices,
practiceId: practice.instinctId,
};
}),
changePractice: assign((ctx, e) => {
if (e.type !== 'CHANGE_PRACTICE')
throw new Error('Event must be CHANGE_PRACTICE to call this action');
let practice = ctx.practices.find(p => p.instinctId === e.practiceId);
if (!practice)
practice = ctx.practices[0];
return {
practiceId: practice.instinctId,
};
}),
setPracticeTitle(ctx) {
let practice = ctx.practices.find(p => p.instinctId === ctx.practiceId);
if (!practice) {
document.title = 'Instinct Treatment Plan';
return;
}
document.title = `Instinct Treatment Plan | ${practice.settings.location_name}`;
},
notifyPracticeChange() {
return;
},
},
services: {
async processTokens() {
return {};
},
async searchForPracticeToken() {
return;
},
async refreshPractices() {
return;
},
},
guards: {
hasValidToken(ctx) {
return Boolean(ctx.practiceId);
},
isAutoAuthAvailable() {
return true;
},
},
delays: {
refreshPractices: 5 * 3600,
tokenLookup: 5 * 3600,
dropReset: 3 * 1000,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment