Skip to content

Instantly share code, notes, and snippets.

@devstojko
Last active March 22, 2020 22:55
Show Gist options
  • Save devstojko/4ec50c776c535bf5cf3b33213051a939 to your computer and use it in GitHub Desktop.
Save devstojko/4ec50c776c535bf5cf3b33213051a939 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
// Available variables:
// - Machine
// - interpret
// - assign
// - send
// - sendParent
// - spawn
// - raise
// - actions
// - XState (all XState exports)
const basketItem = {
companyName: '',
accommodations: {
passengers: [],
vehicles: [],
extraServices: []
}
}
const onFetchTripsSuccess = assign({
basket: (ctx, e) => ({
...ctx.basket,
selectedCompanies: Array(e.data && e.data.tripsWithDictionary.length).fill(basketItem)
}),
trips: (_, e) => e.data && e.data.tripsWithDictionary
});
const steps = {
one: {
valid: false,
completed: false,
companies: []
},
two: {
valid: false,
completed: false
},
three: {
valid: false,
completed: false
}
}
const WITHOUT_FIRST_TRIP = "https://api.myjson.com/bins/yacvc";
const fetchTrips = (ctx, e) => {
console.log('CTX', {ctx, e})
return fetch(WITHOUT_FIRST_TRIP).then(response => response.json());
}
const stepMachine = Machine({
id: 'stepMachine',
initial: 'stepOne',
context: {
locations: [],
trips: [],
basket: {
allowedCompany: null,
validSelectSeats: false,
selectedCompanies: [],
selectedAccommodations: []
},
tripQuery: {
type: "SINGLE",
passengers: 1,
vehicles: 0,
},
steps,
},
states: {
stepOne: {
initial: 'idle',
states: {
idle: {
on: {
SEARCH: {
target: 'searching'
}
},
},
searching: {
invoke: {
id: 'getTrips',
src: 'fetchTrips',
onDone: {
target: 'success',
actions: 'onFetchTripsSuccess'
},
onError: {
target: 'error',
actions: assign({ error: (ctx, e) => event.data })
}
}
},
success: {
on: {
NEXT: {
target: '#stepMachine.stepTwo',
actions: 'submitOne',
cond: 'isSeatSelectionValid',
},
SEARCH: {
target: 'searching'
},
SELECT_COMPANY: {
actions: 'selectCompany'
},
}
},
error: {
},
},
on: {
TO_STEP_2: {
target: 'stepTwo',
cond: 'isOneCompleted'
},
TO_STEP_3: {
target: 'stepThree',
cond: 'isTwoCompleted'
},
SET_TRIP_QUERY: {
actions: 'setTripQuery',
cond: 'isValidTripQueryData'
}
}
},
stepTwo: {
initial: 'idle',
on: {
NEXT: {
target: 'stepThree',
actions: 'submitTwo',
},
TO_STEP_1: {
target: '#stepMachine.stepOne.success',
cond: 'isOneCompleted'
},
TO_STEP_3: {
target: 'stepThree',
cond: 'isTwoCompleted'
}
},
states: {
idle: {
on: {
SELECT_ACCOMMODATION: {
actions: 'selectAccommodation'
}
}
},
priceCalculation: {
}
}
},
stepThree: {
on: {
TO_STEP_2: {
target: 'stepTwo',
cond: 'isTwoCompleted'
},
TO_STEP_1: {
target: '#stepMachine.stepOne.success',
cond: 'isOneCompleted'
}
}
}
}
}, {
actions: {
onFetchTripsSuccess,
selectAccommodation: assign({
basket: (ctx, e) => {
const selectedCompanies = ctx.basket.selectedCompanies.map((company, idx) => {
if (idx === e.idx) {
return { ...company, accommodations: e.value }
}
return company;
});
return ({
...ctx.basket,
selectedCompanies
})
}
}),
selectCompany: assign({
basket: (ctx, e) => {
const selectedCompanies = ctx.basket.selectedCompanies.map((company, idx) => {
if (idx === e.idx) {
console.log('IDX', idx, e.idx)
return { ...company, companyName: e.value }
}
return company;
});
console.log('selectedCompanies', selectedCompanies)
const validSelectSeats = ctx.basket.allowedCompany && selectedCompanies.every(company => company.companyName === ctx.basket.allowedCompany)
const allowedCompany = e.idx === 0 ? e.value : ctx.basket.allowedCompany;
return ({
...ctx.basket,
validSelectSeats,
allowedCompany,
selectedCompanies
})
}
}),
submitOne: assign({
steps: ctx => ({
...ctx.steps,
one: {
completed: true
}
})
}),
submitTwo: assign({
steps: ctx => ({
...ctx.steps,
two: {
completed: true
}
})
}),
setTripQuery: assign({
tripQuery: (ctx, e) => ({
...ctx.tripQuery,
[e.name]: e.payload
})
}),
goBack: () => console.log('go back'),
submit: () => console.log('submit')
},
guards: {
isOneCompleted: ctx => ctx.steps.one.valid,
isOneCompleted: ctx => ctx.steps.one.completed,
isTwoCompleted: ctx => ctx.steps.two.completed,
isThreeCompleted: ctx => ctx.steps.three.completed,
isValidTripQueryData: (_, e) => e.name === "type" || e.name === "passengers" || e.name === "vehicles",
isSeatSelectionValid: ctx => ctx.basket.validSelectSeats
},
services: {
fetchTrips
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment