Skip to content

Instantly share code, notes, and snippets.

@martypenner
Last active November 28, 2019 16:18
Show Gist options
  • Save martypenner/69ae8c97762f252de4d30b0d50d9acae to your computer and use it in GitHub Desktop.
Save martypenner/69ae8c97762f252de4d30b0d50d9acae to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const dashboardMachine = Machine(
{
id: 'dashboard',
context: {
organizations: [],
currentOrganization: null,
currentPeriod: null,
reservations: []
},
states: {
Initializing: {
initial: 'Authenticating',
states: {
Authenticating: {
on: {
authenticated: 'Authorizing',
'not authenticated': '#Not authenticated'
}
},
Authorizing: {
on: {
authorized: 'Fetching organizations',
'not authorized': '#Not authorized'
}
},
'Fetching organizations': {
invoke: {
src: 'fetchOrganizations',
onDone: [
{
target: 'Fetching initial data',
cond: 'hasOrganizations',
actions: 'setOrganizations'
},
{ target: '#User has no organizations' }
],
onError: '#Failure fetching organizations'
}
},
'Fetching initial data': {
invoke: {
src: 'fetchData',
onDone: {
target: '#Ready',
actions: 'storeData'
},
onError: '#Fetch error'
}
}
}
},
Ready: {
id: 'Ready',
states: {
Calendar: {
states: {
'Grid view': {
id: 'Grid view',
states: {
// Only allowing month to start. Week and day may be added later
Month: { id: 'Month', states: {} }
// Week: { id: "Week", states: {} },
// Day: { id: "Day", states: {} }
},
initial: 'Month',
on: {
// "view month": ".Month",
// "view week": ".Week",
// "view day": ".Day",
}
},
Cells: {
// These should be placed in a separate machine that is spawned from this one for each cell
states: {
Today: {
initial: 'Unknown',
states: {
Unknown: {},
Yes: {},
No: {}
}
},
'In current period': {
initial: 'Unknown',
states: {
Unknown: {},
Yes: {},
No: {}
}
}
},
initial: 'Unknown',
type: 'parallel'
}
},
initial: 'Grid view',
type: 'parallel',
on: {
'view previous period': {
actions: 'viewPreviousPeriod'
},
'view next period': {
actions: 'viewNextPeriod'
}
}
},
'List view': {
states: {
Active: {
id: 'Active',
states: {
Unknown: {
on: {
'': [
{
target: 'Has reservations',
cond: 'hasActiveOrOverdueReservations'
},
{ target: 'Empty' }
]
}
},
'Has reservations': {},
Empty: {}
},
initial: 'Unknown'
},
Upcoming: {
id: 'Upcoming',
states: {
Unknown: {
on: {
'': [
{
target: 'Has reservations',
cond: 'hasUpcomingReservations'
},
{ target: 'Empty' }
]
}
},
'Has reservations': {},
Empty: {}
},
initial: 'Unknown'
}
},
type: 'parallel'
}
},
type: 'parallel'
},
'Not authenticated': {
id: 'Not authenticated'
},
'Not authorized': {
id: 'Not authorized'
},
'User has no organizations': {
id: 'User has no organizations'
},
'Failure fetching organizations': {
id: 'Failure fetching organizations'
},
'Fetch error': {
id: 'Fetch error'
}
},
initial: 'Initializing'
},
{
guards: {
hasOrganizations: (_, event) =>
console.info('a', event) ||
(Array.isArray(event.data) && event.data.length > 0),
hasActiveOrOverdueReservations: ctx => ctx.reservations.length > 0,
hasUpcomingReservations: ctx => ctx.reservations.length > 0
},
actions: {
setOrganizations: assign({
organizations: (ctx, event) => event.data,
currentOrganization: (ctx, event) => {
// todo: check if an association ID exists in the URL search params, and grab the organization with that ID if it does. If the search param doesn't exist, or the organization doesn't exist, fall back to the first organization in the list.
return event.data[0];
}
}),
viewPreviousPeriod: ctx => null, // todo: something useful here
viewNextPeriod: ctx => null // todo: something useful here
}
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment