Skip to content

Instantly share code, notes, and snippets.

@Platekun
Created November 20, 2019 18:02
Show Gist options
  • Save Platekun/78a7e44d961dcd1e2bfd115240b09c67 to your computer and use it in GitHub Desktop.
Save Platekun/78a7e44d961dcd1e2bfd115240b09c67 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
function cuid() {}
function sweetAlert() {}
const REDIRECT_LOCATION = 'https://www.getluna.com/';
/** ***************************************************************************
* Form Machine *
*************************************************************************** */
const InitialState = '@Initial';
const LoadingFormRequiredDataState = '@LoadingRequiredData';
const LoadingDraftState = '@LoadingDraft';
const IdleState = '@Idle';
const FirstPageState = '@FirstPageState';
const SecondPageState = '@SecondPageState';
const LoadingFailureState = '@LoadingFailure';
const LoadingResultsRequiredDataState = '@LoadingResultsRequiredData';
const ResultsState = '@ResultsPage';
const NotFoundState = '@NotFound';
const ExpiredFormState = '@ExpiredForm';
const SubmittingState = '@Submitting';
/**
* General
*/
const FormPageAccessedEvent = 'FORM_PAGE_ACCESSED';
const ResultsPageAccessedEvent = 'RESULTS_PAGE_ACCESSED';
const NotFoundPageAccessedEvent = 'NOT_FOUND_PAGE_ACCESSED';
const DraftSavedEvent = 'DRAFT_SAVED';
const SubmitEvent = 'SUBMIT';
const NextEvent = 'NEXT';
const PreviousEvent = 'PREVIOUS';
const updateFormWithDraftDataAction = 'updateFormWithDraftData';
const saveRequiredDataAction = 'savedRequiredData';
const hydrateFormAction = 'hydrateForm';
const saveDraftAction = 'saveDraftAction';
const showSubmitSuccessAction = 'showSubmitSuccess';
const showSubmitFailureAction = 'showSubmitFailure';
const redirectAfterSubmitAction = 'redirectAfterSubmit';
const saveResultsRequiredDataAction = 'saveResultsRequiredData';
/**
* Current Medical History
*/
const SetPrimaryCarePhysicianNameEvent = 'PRIMARY_CARE_PHYSICIAN_NAME_SET';
const SetDateOfLastExamEvent = 'DATE_OF_LAST_EXAM_SET';
const SetHasInfectionsOrPrecautionsEvent = 'HAS_INFECTIONS_OR_PRECAUTIONS_SET';
const SetPleaseExplainEvent = 'PLEASE_EXPLAIN_SET';
const SetPleaseExplainAnotherPhysician = 'PLEASE_EXPLAIN_ANOTHER_PHYSICIAN';
const SetReferralSourceEvent = 'REFERRAL_SOURCE_SET';
const SetInfectionsOrPrecautionsEvent =
'INFECTIONS_OR_PRECAUTIONS_QUESTION_SET';
const SetAllergicToLatexEvent = 'ALLERGIES_TO_LATEX_SET';
const setPrimaryCarePhysicianNameAction = 'setPrimaryCarePhysicianName';
const setDateOfLastExamAction = 'setDateOfLastExam';
const setHasInfectionsOrPrecautionsAction = 'setHasInfectionsOrPrecautions';
const setInfectionsOrPrecautionsEventAction = 'setInfectionsOrPrecautionsEvent';
const setReferralSourceAction = 'setReferralSource';
const setPleaseExplainAction = 'setPleaseExplain';
const setPleaseExplainAnotherPhysicianAction =
'setPleaseExplainAnotherPhysician';
const setAllergicToLatexAction = 'setAllergicToLatex';
/**
* Current Medication List
*/
const SetCurrentMedicationNameEvent = 'CURRENT_MEDICATION_NAME_SET';
const SetCurrentMedicationDosageEvent = 'CURRENT_MEDICATION_NAME_SET';
const AddMedicationEvent = 'MEDICATION_ADDED';
const RemoveMedicationEvent = 'MEDICATION_REMOVED';
/**
* Past Medical History
*/
const AddDiseaseEvent = 'DISEASE_ADDED';
const RemoveDiseaseEvent = 'DISEASE_ADDED';
/**
* Surgical History
*/
const SetSurgeryNameEvent = 'SURGERY_NAME_SET';
const SetSurgeryDateEvent = 'SURGERY_DATE_SET';
const AddSurgeryEvent = 'SURGERY_ADDED';
const RemoveSurgeryEvent = 'SURGERY_REMOVED';
/**
* Overall Quality of Life
*/
const SetOverallQualityOfLifeEvent = 'OVERALL_LIFE_QUALITY_SET';
/**
* Body Chart
*/
const AddPainPointEvent = 'PAIN_POINT_ADDED';
const RemovePainPointEvent = 'PAIN_POINT_REMOVED';
/**
* Pain Scale
*/
const SetPainScaleEvent = 'PAIN_SCALE_VALUE_SET';
/**
* Aggravating Activities
*/
const SetAggravatingActivityName = 'AGGRAVATING_ACTIVITY_NAME_SET';
const SetAggravatingActivityScore = 'AGGRAVATING_ACTIVITY_SCORE_SET';
/**
* Functional Limitations
*/
const SetFunctionalLimitationsQuestion = 'FUNCTIONAL_LIMITATIONS_QUESTION_SET';
/** ***************************************************************************
* Draft Machine *
*************************************************************************** */
const SavingDraftState = '@SaveDraft/Request';
const DraftSavedState = '@SaveDraft/Successful';
const DraftFailedToSaveState = '@SaveDraft/Failure';
const sendDraftToFormAction = 'sendDraftToFormAction';
const draftMachine = Machine(
{
id: 'Draft Saver Machine',
initial: SavingDraftState,
states: {
[SavingDraftState]: {
invoke: {
id: 'saveDraft',
src: () => Promise.resolve(),
onDone: {
target: DraftSavedState,
actions: [sendDraftToFormAction]
},
onError: {
target: DraftFailedToSaveState
}
}
},
[DraftSavedState]: {
type: 'final'
},
[DraftFailedToSaveState]: {
type: 'final'
}
}
},
{
actions: {
[sendDraftToFormAction]: sendParent({ type: DraftSavedEvent })
}
}
);
const formStates = {
states: {
[FirstPageState]: {
on: {
[NextEvent]: SecondPageState,
[DraftSavedEvent]: {
actions: [updateFormWithDraftDataAction]
},
[SetPrimaryCarePhysicianNameEvent]: {
actions: [setPrimaryCarePhysicianNameAction, saveDraftAction]
},
[SetDateOfLastExamEvent]: {
actions: [setDateOfLastExamAction, saveDraftAction]
},
[SetInfectionsOrPrecautionsEvent]: {
actions: [setInfectionsOrPrecautionsEventAction]
},
[SetHasInfectionsOrPrecautionsEvent]: {
actions: [setHasInfectionsOrPrecautionsAction, saveDraftAction]
},
[SetPleaseExplainEvent]: {
actions: [setPleaseExplainAction, saveDraftAction]
},
[SetPleaseExplainAnotherPhysician]: {
actions: [setPleaseExplainAnotherPhysicianAction, saveDraftAction]
},
[SetAllergicToLatexEvent]: {
actions: [setAllergicToLatexAction, saveDraftAction]
},
[SetReferralSourceEvent]: {
actions: [setReferralSourceAction, saveDraftAction]
},
[SetCurrentMedicationNameEvent]: {
actions: [saveDraftAction]
},
[SetCurrentMedicationDosageEvent]: {
actions: [saveDraftAction]
},
[AddMedicationEvent]: {
actions: [saveDraftAction]
},
[RemoveMedicationEvent]: {
actions: [saveDraftAction]
},
[AddDiseaseEvent]: {
actions: [saveDraftAction]
},
[RemoveDiseaseEvent]: {
actions: [saveDraftAction]
},
[SetSurgeryNameEvent]: {
actions: [saveDraftAction]
},
[SetSurgeryDateEvent]: {
actions: [saveDraftAction]
},
[AddSurgeryEvent]: {
actions: [saveDraftAction]
},
[RemoveSurgeryEvent]: {
actions: [saveDraftAction]
},
[SetOverallQualityOfLifeEvent]: {
actions: [saveDraftAction]
},
[AddPainPointEvent]: {
actions: [saveDraftAction]
},
[RemovePainPointEvent]: {
actions: [saveDraftAction]
},
[SetPainScaleEvent]: {
actions: [saveDraftAction]
},
[SetAggravatingActivityName]: {
actions: [saveDraftAction]
},
[SetAggravatingActivityScore]: {
actions: [saveDraftAction]
},
[SetFunctionalLimitationsQuestion]: {
actions: [saveDraftAction]
}
}
},
[SecondPageState]: {
on: {
[PreviousEvent]: FirstPageState,
[DraftSavedEvent]: {
actions: [updateFormWithDraftDataAction]
}
}
},
hist: {
type: 'history'
}
}
};
const formMachine = Machine(
{
id: 'Luna Form Machine',
initial: InitialState,
context: {
draft: null,
primaryCarePhysician: {
id: cuid(),
label: 'Primary care physician',
value: '',
dirty: false,
valid: false,
validable: true,
validationRules: {
isRequired: true
}
},
dateOfLastExam: {
id: cuid(),
label: 'Date of last exam',
value: '',
dirty: false,
valid: false,
validable: true,
validationRules: {
isRequired: true,
validDate: true
}
},
referralSource: {
id: cuid(),
value: 'doNotHaveAReferral',
dirty: false,
validable: false
},
pleaseExplainAnotherPhysician: {
id: cuid(),
label: 'Referred physician name',
value: '',
dirty: false,
valid: false,
validable: true,
validationRules: {
requiredIf: {
name: 'referralSource',
value: 'referralSourceAnotherPhysician'
}
}
},
hasInfectionsOrPrecautions: {
id: cuid(),
value: false,
dirty: false,
validable: false
},
pleaseExplain: {
id: cuid(),
label: 'Please explain',
value: '',
dirty: false,
valid: false,
validable: true,
validationRules: {
requiredIf: {
name: 'hasInfectionsOrPrecautions',
value: true
}
}
},
allergicToLatex: {
id: cuid(),
value: false,
dirty: false,
validable: false
},
currentMedicationList: {
id: cuid(),
valid: true,
validable: false,
validableChildren: true,
entries: [
{
id: cuid(),
valid: true,
controls: {
name: {
id: cuid(),
value: '',
dirty: false,
label: 'Medication List Name (1)',
valid: true
},
dosage: {
id: cuid(),
value: '',
dirty: false,
label: 'Medication List Dosage (1)',
valid: true
}
}
},
{
id: cuid(),
valid: true,
controls: {
name: {
id: cuid(),
value: '',
dirty: false,
label: 'Medication List Name (2)',
valid: true
},
dosage: {
id: cuid(),
value: '',
dirty: false,
label: 'Medication List Dosage (2)',
valid: true
}
}
},
{
id: cuid(),
valid: true,
controls: {
name: {
id: cuid(),
value: '',
dirty: false,
label: 'Medication List Name (3)',
valid: true
},
dosage: {
id: cuid(),
value: '',
dirty: false,
label: 'Medication List Dosage (3)',
valid: true
}
}
}
]
},
pastMedicalHistory: {
validable: false,
entries: []
},
surgicalHistory: {
id: cuid(),
valid: true,
validable: false,
validableChildren: true,
entries: [
{
id: cuid(),
valid: true,
controls: {
name: {
id: cuid(),
value: '',
dirty: false,
label: 'Surgical History Name (1)',
valid: true
},
date: {
id: cuid(),
value: '',
dirty: false,
label: 'Surgical History Date (1)',
valid: true
}
}
},
{
id: cuid(),
valid: true,
controls: {
name: {
id: cuid(),
value: '',
dirty: false,
label: 'Surgical History Name (2)',
valid: true
},
date: {
id: cuid(),
value: '',
dirty: false,
label: 'Surgical History Date (2)',
valid: true
}
}
},
{
id: cuid(),
valid: true,
controls: {
name: {
id: cuid(),
value: '',
dirty: false,
label: 'Surgical History Name (3)',
valid: true
},
date: {
id: cuid(),
value: '',
dirty: false,
valid: true,
label: 'Surgical History Date (3)'
}
}
}
]
},
overallQualityOfLife: {
id: cuid(),
label: 'Overall quality of life',
value: '',
dirty: false,
valid: false,
validable: true,
validationRules: {
isRequired: true
}
},
bodyChartPoints: {
id: cuid(),
label: 'Body chart points',
front: [],
back: [],
valid: false,
validable: true,
validationRules: {
selectedAtLeast: 1
}
},
painValueInLastSevenDays: {
id: cuid(),
dirty: false,
value: 5,
validable: false
},
aggravatingActivities: {
id: cuid(),
valid: false,
validable: false,
validableChildren: true,
entries: [
{
id: cuid(),
valid: false,
label: 'Aggravating Activities (1)',
controls: {
activity: {
id: cuid(),
value: '',
dirty: false
},
ability: {
id: cuid(),
value: 0,
dirty: false
}
}
},
{
id: cuid(),
valid: false,
label: 'Aggravating Activities (2)',
controls: {
activity: {
id: cuid(),
value: '',
dirty: false
},
ability: {
id: cuid(),
value: 0,
dirty: false
}
}
},
{
id: cuid(),
valid: false,
label: 'Aggravating Activities (3)',
controls: {
activity: {
id: cuid(),
value: '',
dirty: false
},
ability: {
id: cuid(),
value: 0,
dirty: false
}
}
}
]
},
painValueInLastWeeks: undefined,
invalidControls: []
},
states: {
[InitialState]: {
on: {
[FormPageAccessedEvent]: LoadingFormRequiredDataState,
[ResultsPageAccessedEvent]: ResultsState,
[NotFoundPageAccessedEvent]: NotFoundState
}
},
[LoadingFormRequiredDataState]: {
invoke: {
id: 'loadRequiredData',
src: () => Promise.resolve(),
onDone: {
target: LoadingDraftState,
actions: [saveRequiredDataAction]
},
onError: {
target: LoadingFailureState
}
}
},
[LoadingDraftState]: {
invoke: {
id: 'loadDraft',
src: () => Promise.resolve(),
onDone: {
target: IdleState,
actions: [hydrateFormAction]
},
onError: {
target: LoadingFailureState
}
}
},
[NotFoundState]: { type: 'final' },
[LoadingFailureState]: {
// Verificar que no expiró
type: 'final'
},
[ExpiredFormState]: { type: 'final' },
[IdleState]: {
initial: FirstPageState,
on: {
[SubmitEvent]: SubmittingState
},
...formStates
},
[SubmittingState]: {
invoke: {
id: 'Submit Form',
src: () => Promise.resolve(),
onDone: [
{
target: `${IdleState}.hist`,
actions: [showSubmitSuccessAction, redirectAfterSubmitAction],
cond: true
}
],
onError: {
target: `${IdleState}.hist`,
actions: [showSubmitFailureAction]
}
}
},
[LoadingResultsRequiredDataState]: {
invoke: {
id: 'Load Results Required Data',
src: () => Promise.resolve(),
onDone: {
target: ResultsState,
actions: [saveResultsRequiredDataAction]
},
onError: {
target: LoadingFailureState
}
}
},
[ResultsState]: {
on: {}
}
}
},
{
actions: {
/**
* General Actions
*/
[saveRequiredDataAction]: assign({}),
[saveDraftAction]: assign({
draft: () => spawn(draftMachine, 'draftMachine')
}),
[hydrateFormAction]: assign({}),
[updateFormWithDraftDataAction]: assign({}),
[showSubmitSuccessAction]: () => {
sweetAlert({
title: 'Success',
text: 'Your response was submitted',
icon: 'success',
buttons: false,
closeOnClickOutside: false,
closeOnEsc: false,
closeModal: false
});
},
[showSubmitFailureAction]: () => {
sweetAlert({
title: 'Error',
text: 'The form submission could not be completed',
icon: 'error',
buttons: false
});
},
[redirectAfterSubmitAction]: () => {
setTimeout(() => window.location.replace(REDIRECT_LOCATION), 4000);
},
[saveResultsRequiredDataAction]: assign({}),
/**
* Current Medication List Actions
*/
[setPrimaryCarePhysicianNameAction]: assign({
primaryCarePhysician: (ctx, e) => ({
...ctx.primaryCarePhysician,
value: e.value,
valid: true
})
}),
[setInfectionsOrPrecautionsEventAction]: assign({
hasInfectionsOrPrecautions: (ctx, e) => ({
...ctx.hasInfectionsOrPrecautions,
value: e.value
})
}),
[setDateOfLastExamAction]: assign({
dateOfLastExam: (ctx, e) => ({
...ctx.primaryCarePhysician,
value: e.value,
valid: true
})
}),
[setHasInfectionsOrPrecautionsAction]: assign({
hasInfectionsOrPrecautions: (ctx, e) => ({
...ctx.hasInfectionsOrPrecautions,
value: e.value
})
}),
[setPleaseExplainAction]: assign({
pleaseExplain: (ctx, e) => ({
...ctx.pleaseExplain,
value: e.value
})
}),
[setPleaseExplainAnotherPhysicianAction]: assign({
pleaseExplainAnotherPhysician: (ctx, e) => ({
...ctx.pleaseExplainAnotherPhysician,
value: e.value
})
}),
[setAllergicToLatexAction]: assign({
setAllergicToLatexAction: (ctx, e) => ({
...ctx.allergicToLatexAction,
value: e.value,
valid: true
})
}),
[setReferralSourceAction]: assign({
referralSource: (ctx, e) => ({
...ctx.referralSource,
value: e.value
})
})
}
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment