User Flows
Malleable User Flow allows you to define generic user flows in your system that a user interface can pickup and drive through a process, this includes the capability for the controls to call API's to validate what has been entered, or to lookup information.
These can be defined in kubernetes:
---
apiVersion: kadense.io/v1
kind: MalleableUserFlow
metadata:
name: test-userflow
namespace: test-namespace
spec:
steps:
Vaccinator:
Title: Who is the vaccinator?
selectChoicesFrom: Api
selectChoicesFromApi: "/api/v1/Organisations/{User.Organisation}/Vaccinators"
nextStep: Vaccine
renderAs: Choice
Vaccine:
Title: Which vaccine are you giving?
selectChoicesFrom: Api
selectChoicesFromApi: "/api/v1/Organisations/{User.Organisation}/Vaccines"
nextStep: Product
renderAs: Choice
Product:
Title: Which product are you giving?
selectChoicesFrom: Api
selectChoicesFromApi: "/api/v1/Organisations/{User.Organisation}/Vaccines/{Vaccine}/Products"
nextStep: Batch
renderAs: Choice
Batch:
Title: Which batch are you using?
selectChoicesFrom: Api
selectChoicesFromApi: "/api/v1/Organisations/{User.Organisation}/Vaccines/{Vaccine}/Products/{Product}/Batches"
nextStep: Why
renderAs: Choice
Why:
Title: Why are you giving them the vaccine?
selectChoicesFrom: ValuesList
selectChoicesFromValuesList:
- Residents in care homoes
- Social Care Workers
- Age-based eligibility
- Pregnancy
- People with immunosuppression
- People in other clinical risk groups
- People who are homeless or live in closed settlings like supported living
accommodation
- Household contacts of people with immunosuppression
- Carer
- People that have had CAR-T therapy or stem cell transplantation since receiving
their last Vaccination
nextStep: Where
renderAs: Choice
Where:
Title: Where is the vaccination taking place?
Description: This is needed for payment and reporting
selectChoicesFrom: ValuesList
selectChoicesFromValuesList:
- Hospital Hub
- Vaccination Centre
- Primary Care Network (PCN)
- Pharmacy
- Care Home
- Home of Housebound Patient
- Off-site Outreach Event
nextStep: CareHome
renderAs: Choice
CareHome:
Title: Please supply the Care Home Details
Description: Search by name or ODS Code
nextStep: CareHomeVerify
skipIfCondition: "'{Where}' != 'Care Home'"
lookupFromApi: "/api/v1/Organisations/Search"
lookupFromApiWhen: ButtonPress
CareHomeVerify:
Title: Please verify the care home details
nextStep: Patient
skipIfCondition: "'{Where}' != 'Care Home'"
Patient:
Title: What is the patient's NHS Number?
Description: For example, 485 777 3456
nextStep: PatientVerify
lookupFromApi: "/api/v1/Organisations/Search"
lookupFromApiWhen: ButtonPress
PatientVerify:
Title: Check {Patient.ResultSet.Name}'s details
nextStep: PatientHistory
PatientHistory:
Title: Review {Patient.ResultSet.Name}'s Vaccination History
nextStep: Warnings
Warnings:
Title: "{Vaccination} may not be recommended"
nextStep: Consent
skipIfCondition: "'{Patient.ResultSet.HasWarnings}' == false"
Consent:
Title: Who is giving consent?
selectChoicesFrom: ValuesList
selectChoicesFromValuesList:
- "{Patient.ResultSet.Name}"
- Clinician acting in the patient's best interests
- Person with lasting power of attorney for health and welfare
- Parent or guardian
- Independent mental capacity advocate
- Court appointed deputy
nextStep: ConsentGiver
renderAs: Choice
ConsentGiver:
Title: Please enter the name of the {Consent}
nextStep: ConsentGiverRelationship
skipIfCondition: "'{ConsentGiver}' != '{Patient.ResultSet.Name}'"
ConsentGiverRelationship:
Title: What is {ConsentGiver}'s relationship with the patient?
nextStep: InjectionSite
skipIfCondition: "'{ConsentGiver}' != 'Person with lasting power of attorney
for health and welfare' && '{Consent}' != 'Court appointed deputy'"
InjectionSite:
Title: Where did you give the injection?
selectChoicesFrom: ValuesList
selectChoicesFromValuesList:
- Left upper arm
- Right upper arm
- Somewhere else
nextStep: OtherInjectionSite
renderAs: Choice
OtherInjectionSite:
Title: Where did you give the injection?
selectChoicesFrom: ValuesList
selectChoicesFromValuesList:
- Left buttock
- Right buttock
- Left thigh
- Right thigh
- Nasal
- Oral
nextStep: Confirmation
skipIfCondition: "'{InjectionSite}' != 'Somewhere else'"
renderAs: Choice
Confirmation:
Title: Check and Confirm
nextStep: Comments
renderAs: Custom
customRenderer: vaccination_confirmation
Comments:
Title: Add an optional note
Description: This comment will not be sent to the GP and is only visible to
your organisation
nextStep: Submit
Submit:
Title: Vaccination {Submit.Result}
lookupFromApi: "/api/v1/Vaccination"
lookupFromApiWhen: OnStepLoad
renderAs: Custom
customRenderer: vaccination-submission
or via helper classes in C#
return new MalleableUserFlowFactory("test-namespace", "test-userflow")
.AddStep("Vaccinator")
.WithTitle("Who is the vaccinator?")
.SelectChoicesFromApi("/api/v1/Organisations/{User.Organisation}/Vaccinators")
.AddNextStep("Vaccine")
.WithTitle("Which vaccine are you giving?")
.SelectChoicesFromApi("/api/v1/Organisations/{User.Organisation}/Vaccines")
.AddNextStep("Product")
.WithTitle("Which product are you giving?")
.SelectChoicesFromApi("/api/v1/Organisations/{User.Organisation}/Vaccines/{Vaccine}/Products")
.AddNextStep("Batch")
.WithTitle("Which batch are you using?")
.SelectChoicesFromApi("/api/v1/Organisations/{User.Organisation}/Vaccines/{Vaccine}/Products/{Product}/Batches")
.AddNextStep("Why")
.WithTitle("Why are you giving them the vaccine?")
.WithChoice("Residents in care homoes")
.WithChoice("Social Care Workers")
.WithChoice("Age-based eligibility")
.WithChoice("Pregnancy")
.WithChoice("People with immunosuppression")
.WithChoice("People in other clinical risk groups")
.WithChoice("People who are homeless or live in closed settlings like supported living accommodation")
.WithChoice("Household contacts of people with immunosuppression")
.WithChoice("Carer")
.WithChoice("People that have had CAR-T therapy or stem cell transplantation since receiving their last Vaccination")
.AddNextStep("Where")
.WithTitle("Where is the vaccination taking place?")
.WithDescription("This is needed for payment and reporting")
.WithChoice("Hospital Hub")
.WithChoice("Vaccination Centre")
.WithChoice("Primary Care Network (PCN)")
.WithChoice("Pharmacy")
.WithChoice("Care Home")
.WithChoice("Home of Housebound Patient")
.WithChoice("Off-site Outreach Event")
.AddNextStep("CareHome")
.WithTitle("Please supply the Care Home Details")
.WithDescription("Search by name or ODS Code")
.LookupFromApi("/api/v1/Organisations/Search")
.SkipIf("'{Where}' != 'Care Home'")
.AddNextStep("CareHomeVerify")
.WithTitle("Please verify the care home details")
.SkipIf("'{Where}' != 'Care Home'")
.AddNextStep("Patient")
.WithTitle("What is the patient's NHS Number?")
.WithDescription("For example, 485 777 3456")
.LookupFromApi("/api/v1/Organisations/Search")
.AddNextStep("PatientVerify")
.WithTitle("Check {Patient.ResultSet.Name}'s details")
.AddNextStep("PatientHistory")
.WithTitle("Review {Patient.ResultSet.Name}'s Vaccination History")
.AddNextStep("Warnings")
.SkipIf("'{Patient.ResultSet.HasWarnings}' == false")
.WithTitle("{Vaccination} may not be recommended")
.AddNextStep("Consent")
.WithTitle("Who is giving consent?")
.WithChoice("{Patient.ResultSet.Name}")
.WithChoice("Clinician acting in the patient's best interests")
.WithChoice("Person with lasting power of attorney for health and welfare")
.WithChoice("Parent or guardian")
.WithChoice("Independent mental capacity advocate")
.WithChoice("Court appointed deputy")
.AddNextStep("ConsentGiver")
.SkipIf("'{ConsentGiver}' != '{Patient.ResultSet.Name}'")
.WithTitle("Please enter the name of the {Consent}")
.AddNextStep("ConsentGiverRelationship")
.SkipIf("'{ConsentGiver}' != 'Person with lasting power of attorney for health and welfare' && '{Consent}' != 'Court appointed deputy'")
.WithTitle("What is {ConsentGiver}'s relationship with the patient?")
.AddNextStep("InjectionSite")
.WithTitle("Where did you give the injection?")
.WithChoice("Left upper arm")
.WithChoice("Right upper arm")
.WithChoice("Somewhere else")
.AddNextStep("OtherInjectionSite")
.SkipIf("'{InjectionSite}' != 'Somewhere else'")
.WithTitle("Where did you give the injection?")
.WithChoice("Left buttock")
.WithChoice("Right buttock")
.WithChoice("Left thigh")
.WithChoice("Right thigh")
.WithChoice("Nasal")
.WithChoice("Oral")
.AddNextStep("Confirmation")
.WithCustomRenderer("vaccination_confirmation")
.WithTitle("Check and Confirm")
.AddNextStep("Comments")
.WithTitle("Add an optional note")
.WithDescription("This comment will not be sent to the GP and is only visible to your organisation")
.AddNextStep("Submit")
.WithTitle("Vaccination {Submit.Result}")
.LookupFromApi("/api/v1/Vaccination", MalleableUserFlowStep.LookupFromApiWhenOptions.OnStepLoad)
.WithCustomRenderer("vaccination-submission")
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndStep()
.EndWorkflow();
These user flows can be fetched by any service that you want to act as your user interface, whether this be a single page application, a traditional server-side application, a win32 application or a mobile application so long as the read API is exposed (we recommend fronting this with a proxy API that has list/read permissions for the service in question to avoid security issues).