Website: Update /start questionnaire steps and add images (#21452)

Closes: #21417 
Closes: #21413
Closes: #21378 


Changes:
- Updated save-questionnaire-progress to return the user's current
psychological stage when a user submits a step of the /start
questionnaire
- Updated the /start questionnaire to display an image that changes as
the user's psychological stage progresses.
- Updated the first step of the /start questionnaire and gave users the
ability to go back to the first step.
- Added an option for Linux to the "what do you manage" question that is
asked to MDM-focused users
- Added a step for MDM-focused users filling out the /start
questionnaire
- Updated the /start CTA to show different images based on psychological
stage and to be visible to users who have not purchased a self-service
license
This commit is contained in:
Eric 2024-08-21 11:54:06 -06:00 committed by GitHub
parent cd14831e44
commit 637e5e1216
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 857 additions and 776 deletions

View file

@ -21,6 +21,7 @@ module.exports = {
'what-does-your-team-manage-eo-it',
'what-does-your-team-manage-vm',
'what-do-you-manage-mdm',
'cross-platform-mdm',
'is-it-any-good',
'what-did-you-think',
'deploy-fleet-in-your-environment',
@ -86,28 +87,25 @@ module.exports = {
// 'how-many-hosts': Stage 4/5/6
// 'will-you-be-self-hosting': Stage 5/6
// 'what-are-you-working-on-eo-security'
// - no-use-case-yet: » Stage 2/3 (depends on answer from 'have-you-ever-used-fleet' step)
// - All other options » Stage 4
// 'what-does-your-team-manage-eo-it'
// - no-use-case-yet: » Stage 2/3 (depends on answer from 'have-you-ever-used-fleet' step)
// - All other options » Stage 4
// 'what-does-your-team-manage-vm'
// - no-use-case-yet: » Stage 2/3 (depends on answer from 'have-you-ever-used-fleet' step)
// - All other options » Stage 4
// 'what-do-you-manage-mdm'
// - no-use-case-yet: » Stage 2/3 (depends on answer from 'have-you-ever-used-fleet' step)
// - no-use-case-yet: » Stage 3
// - All other options » Stage 4
// 'is-it-any-good': Stage 2/3/4 (depends on answer from 'have-you-ever-used-fleet' & the buying situation specific step)
// 'is-it-any-good': Stage 3/4 (depends on answer from 'have-you-ever-used-fleet' & the buying situation specific step)
// 'what-did-you-think'
// - host-fleet-for-me » Stage 4
// - deploy-fleet-in-environment » Stage 4
// - host-fleet-for-me » Stage 5
// - deploy-fleet-in-environment » Stage 5
// - let-me-think-about-it » Stage 2
// FUTURE: Should the step about deploying fleet in your env be here? (For same reason is-it-any-good is here: when navigating back then forwards?)
// 'how-was-your-deployment'
// - up-and-running » Stage 5
// - kinda-stuck » Stage 4 (...at best! Still got the use case.)
// - havent-gotten-to-it » Stage 4 (same as above)
// - changed-mind-want-managed-deployment » Stage 4 (same as above)
// - kinda-stuck » Stage 5
// - havent-gotten-to-it » Stage 5
// - changed-mind-want-managed-deployment » Stage 5
// - decided-to-not-use-fleet » Stage 2
// 'whats-left-to-get-you-set-up'
// - need-premium-license-key » No change (Stage ??)
@ -124,17 +122,13 @@ module.exports = {
} else if(currentStep === 'what-are-you-using-fleet-for') {
psychologicalStage = '2 - Aware';
} else if(currentStep === 'have-you-ever-used-fleet') {
if(['yes-deployed'].includes(valueFromFormData)) {
if(valueFromFormData === 'yes-deployed') {
// If the user has Fleet deployed, set their stage to 6.
psychologicalStage = '6 - Has team buy-in';
} else if(valueFromFormData === 'yes-recently-deployed'){
} else if(valueFromFormData === 'yes-recently-deployed') {
psychologicalStage = '5 - Personally confident';
} else if(valueFromFormData === 'yes-deployed-local'){
// If they've tried Fleet locally, set their stage to 3.
psychologicalStage = '3 - Intrigued';
} else {
// Otherwise, we'll just assume liu're only aware. Maybe liu don't fully grasp what Fleet can do.
psychologicalStage = '2 - Aware';
psychologicalStage = '3 - Intrigued';
}
} else {
// If the user submitted any other step, we'll set variables using the answers to the previous questions.
@ -144,13 +138,7 @@ module.exports = {
let hasUsedFleetAnswer = questionnaireProgress['have-you-ever-used-fleet'].fleetUseStatus;
if(['what-are-you-working-on-eo-security','what-does-your-team-manage-eo-it','what-does-your-team-manage-vm','what-do-you-manage-mdm'].includes(currentStep)){
if(valueFromFormData === 'no-use-case-yet') {
// Check the user's answer to the previous question
if(hasUsedFleetAnswer === 'yes-deployed-local'){
// If they've tried Fleet locally, set their stage to 3.
psychologicalStage = '3 - Intrigued';
} else {
psychologicalStage = '2 - Aware';
}
psychologicalStage = '3 - Intrigued';
} else {// Otherwise, they have a use case and will be set to stage 4.
psychologicalStage = '4 - Has use case';
}
@ -160,12 +148,7 @@ module.exports = {
// be selected, we'll check the user's previous answers before changing their psyStage
if(questionnaireProgress['what-do-you-manage-mdm'].mdmUseCase === 'no-use-case-yet'){
// Check the user's answer to the have-you-ever-used-fleet question.
if(hasUsedFleetAnswer === 'yes-deployed-local') {
// If they've tried Fleet locally, set their stage to 3.
psychologicalStage = '3 - Intrigued';
} else {
psychologicalStage = '2 - Aware';
}
psychologicalStage = '3 - Intrigued';
} else {
psychologicalStage = '4 - Has use case';
}
@ -177,27 +160,22 @@ module.exports = {
// If the user selects "Let me think about it", set their psyStage to 2.
if(valueFromFormData === 'let-me-think-about-it') {
psychologicalStage = '2 - Aware';
} else if (['deploy-fleet-in-environment','host-fleet-for-me'].includes(valueFromFormData)) {
psychologicalStage = '4 - Has use case';
} else if (['host-fleet-for-me', 'deploy-fleet-in-environment'].includes(valueFromFormData)) {
psychologicalStage = '5 - Personally confident';
} else { require('assert')(false,'This should never happen.'); }
} else if(currentStep === 'how-was-your-deployment') {
if(valueFromFormData === 'decided-to-not-use-fleet') {
psychologicalStage = '2 - Aware';
} else if(valueFromFormData === 'up-and-running'){
} else if(['up-and-running', 'changed-mind-want-managed-deployment', 'kinda-stuck', 'havent-gotten-to-it'].includes(valueFromFormData)){
psychologicalStage = '5 - Personally confident';
} else if(['kinda-stuck', 'havent-gotten-to-it', 'changed-mind-want-managed-deployment'].includes(valueFromFormData)){
psychologicalStage = '4 - Has use case';
} else { require('assert')(false,'This should never happen.'); }
} else if (currentStep === 'whats-left-to-get-you-set-up') {
// FUTURE: do more stuff (for now this always acts like 'no change')
} else if(currentStep === 'how-many-hosts') {
if(['yes-deployed'].includes(hasUsedFleetAnswer)) {
psychologicalStage = '6 - Has team buy-in';
} else if(['yes-recently-deployed'].includes(hasUsedFleetAnswer)){
psychologicalStage = '5 - Personally confident';
} else {
// IWMIH then we want Fleet to host for us (either because we wanted that from the get-go, or we backtracked because deploying looked too time-consuming)
psychologicalStage = '4 - Has use case';
psychologicalStage = '5 - Personally confident';
}
} else if(currentStep === 'will-you-be-self-hosting') {
if(['yes-deployed'].includes(hasUsedFleetAnswer)) {
@ -243,7 +221,7 @@ module.exports = {
psychologicalStageLastChangedAt,
});
// Return the JSON dictionary of form data submitted by this user.
return getStartedProgress;
return {getStartedProgress, psychologicalStage};
}

View file

@ -289,8 +289,8 @@ will be disabled and/or hidden in the UI.
// FUTURE: Only show this CTA to users who are below psyStage 6.
// > The code below is so we don't bother users who have completed the questionnaire
// Determine if this user should see the CTA to bring them to the /start questionnaire using the user's last submitted questionnaire answer.
res.locals.showStartCta = !['how-many-hosts','will-you-be-self-hosting','managed-cloud-for-growing-deployments','self-hosted-deploy', 'whats-left-to-get-you-set-up'].includes(req.me.lastSubmittedGetStartedQuestionnaireStep);
// Show this logged-in user a CTA to bring them to the /start questionnaire if they do not have billing information saved.
res.locals.showStartCta = !req.me.hasBillingCard;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// If an expandCtaAt timestamp is set in the user's sesssion, check the value to see if we should expand the CTA.

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View file

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 KiB

View file

@ -18,6 +18,7 @@ parasails.registerPage('start', {
'what-does-your-team-manage-eo-it': {},
'what-does-your-team-manage-vm': {},
'what-do-you-manage-mdm': {},
'cross-platform-mdm': {stepCompleted: true},
'is-it-any-good': {stepCompleted: true},
'what-did-you-think': {},
'deploy-fleet-in-your-environment': {stepCompleted: true},
@ -25,6 +26,8 @@ parasails.registerPage('start', {
'how-was-your-deployment': {},
'whats-left-to-get-you-set-up': {},
},
psychologicalStage: '2 - Aware',
// For tracking client-side validation errors in our form.
// > Has property set to `true` for each invalid property in `formData`.
formErrors: { /* … */ },
@ -89,6 +92,9 @@ parasails.registerPage('start', {
this.formData['what-are-you-using-fleet-for'] = {primaryBuyingSituation: this.primaryBuyingSituation};
}
}
if(this.me.psychologicalStage){
this.psychologicalStage = this.me.psychologicalStage;
}
if(window.location.hash) {
if(typeof analytics !== 'undefined') {
if(window.location.hash === '#signup') {
@ -126,11 +132,13 @@ parasails.registerPage('start', {
handleSubmittingForm: async function(argins) {
let formDataForThisStep = _.clone(argins);
let nextStep = this.getNextStep();
let getStartedProgress = await Cloud.saveQuestionnaireProgress.with({
let questionanireProgress = await Cloud.saveQuestionnaireProgress.with({
currentStep: this.currentStep,
formData: formDataForThisStep,
});
this.previouslyAnsweredQuestions[this.currentStep] = getStartedProgress[this.currentStep];
this.previouslyAnsweredQuestions[this.currentStep] = questionanireProgress.getStartedProgress[this.currentStep];
this.psychologicalStage = questionanireProgress.psychologicalStage;
if(_.startsWith(nextStep, '/')){
this.goto(nextStep);
} else {
@ -140,6 +148,9 @@ parasails.registerPage('start', {
},
clickGoToPreviousStep: async function() {
switch(this.currentStep) {
case 'what-are-you-using-fleet-for':
this.currentStep = 'start';
break;
case 'have-you-ever-used-fleet':
this.currentStep = 'what-are-you-using-fleet-for';
break;
@ -175,9 +186,12 @@ parasails.registerPage('start', {
} else if(primaryBuyingSituation === 'vm') {
this.currentStep = 'what-does-your-team-manage-vm';
} else if(primaryBuyingSituation === 'mdm') {
this.currentStep = 'what-do-you-manage-mdm';
this.currentStep = 'cross-platform-mdm';
}
break;
case 'cross-platform-mdm':
this.currentStep = 'what-do-you-manage-mdm';
break;
case 'lets-talk-to-your-team':
this.currentStep = 'how-many-hosts';
break;
@ -274,6 +288,9 @@ parasails.registerPage('start', {
nextStepInForm = 'is-it-any-good';
break;
case 'what-do-you-manage-mdm':
nextStepInForm = 'cross-platform-mdm';
break;
case 'cross-platform-mdm':
nextStepInForm = 'is-it-any-good';
break;
case 'is-it-any-good':
@ -300,7 +317,7 @@ parasails.registerPage('start', {
} else if(this.formData['how-was-your-deployment'].howWasYourDeployment === 'kinda-stuck'){
nextStepInForm = '/contact';
} else if(this.formData['how-was-your-deployment'].howWasYourDeployment === 'havent-gotten-to-it') {
nextStepInForm = 'deploy-fleet-in-your-environment';
nextStepInForm = '/contact';
} else if(this.formData['how-was-your-deployment'].howWasYourDeployment === 'changed-mind-want-managed-deployment'){
nextStepInForm = 'how-many-hosts';
} else if(this.formData['how-was-your-deployment'].howWasYourDeployment === 'decided-to-not-use-fleet'){

View file

@ -144,8 +144,27 @@ html, body {
[purpose='banner-image'] {
height: 80px;
min-width: 80px;
background-image: url('/images/continue-thumbnail.png');
background-size: cover;
background-position: center;
border-radius: 12px;
&.stage-one {
background-image: url('/images/psystage-1-unaware-558x680@2x.png');
}
&.stage-two {
background-image: url('/images/cta-thumbnail-psystage-2-aware-128x128@2x.png');
}
&.stage-three {
background-image: url('/images/cta-thumbnail-psystage-3-intrigued-128x128@2x.png');
}
&.stage-four {
background-image: url('/images/cta-thumbnail-psystage-4-has-use-case-128x128@2x.png');
}
&.stage-five {
background-image: url('/images/cta-thumbnail-psystage-5-100x100@2x.png');
}
&.stage-six {
background-image: url('/images/psystage-6-has-team-buy-in-504x784@2x.png');
}
}
}
[purpose='banner-body'].collapsed {
@ -656,7 +675,6 @@ body.detected-mobile {
[purpose='banner-image'] {
height: 54px;
min-width: 54px;
background-image: url('/images/continue-thumbnail.png');
background-size: cover;
}
}
@ -667,7 +685,6 @@ body.detected-mobile {
[purpose='banner-image'] {
height: 54px;
min-width: 54px;
background-image: url('/images/continue-thumbnail.png');
background-size: cover;
}
transform: none;

View file

@ -2,6 +2,7 @@
background: linear-gradient(180deg, #E8F1F6 0%, #FFF 16.49%);
a {
color: @core-fleet-black-75;
text-decoration: underline;
}
h1 {
font-size: 32px;
@ -14,6 +15,13 @@
font-weight: 800;
line-height: 120%;
}
ul {
margin-top: 32px;
padding-inline-start: 16px;
li {
margin-bottom: 24px;
}
}
[purpose='logo-container'] {
max-width: 524px;
margin-left: auto;
@ -29,15 +37,66 @@
}
}
[purpose='form-container'] {
width: 528px;
margin-left: auto;
margin-right: auto;
}
[purpose='page-container'] {
padding-top: 64px;
min-width: 632px;
max-width: 632px;
padding-left: 64px;
padding-right: 64px;
padding-bottom: 64px;
padding-top: 32px;
margin-right: 20px;
}
[purpose='form-tip'] {
margin-top: 32px;
padding: 16px;
border-radius: 8px;
border: 1px solid #E6E3D0;
background: #FFFEF9;
p {
margin-bottom: 0px;
font-size: 14px;
line-height: 150%;
}
img {
height: 32px;
width: 32px;
margin-right: 12px;
}
}
[purpose='form-image'] {
width: 100%;
height: 680px;
max-width: 568px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
border: 1px solid @core-vibrant-blue-15;
border-radius: 16px;
&.stage-one {
background-image: url('/images/psystage-1-unaware-558x680@2x.png');
}
&.stage-two {
background-image: url('/images/psystage-2-aware-508x784@2x.png');
}
&.stage-three {
background-image: url('/images/psystage-3-intrigued-558x680@2x.png');
}
&.stage-four {
background-image: url('/images/psystage-4-has-use-case-508x784@2x.png');
}
&.stage-five {
background-image: url('/images/cropped-fleet-cloud-city-504x784@2x.png');
}
&.stage-six {
background-image: url('/images/psystage-6-has-team-buy-in-504x784@2x.png');
}
&.cloud-city {
background-image: url('/images/cropped-fleet-cloud-city-504x784@2x.png');
}
}
[purpose='page-container'] {
padding-top: 20px;
padding-left: 20px;
padding-right: 24px;
padding-bottom: 24px;
max-width: unset;
display: flex;
flex-direction: column;
@ -140,6 +199,9 @@
align-items: center;
justify-content: start;
user-select: none;
a {
text-decoration: none;
}
}
[purpose='submit-button'] {
padding: 12px;
@ -208,6 +270,9 @@
}
}
[parasails-component='logo-carousel'] {
margin-bottom: 0px;
}
[purpose='quote'] {
display: flex;
padding: 32px;
@ -259,6 +324,16 @@
padding-right: 40px;
max-width: 600px;
}
[purpose='form-container'] {
padding: 0;
min-width: unset;
max-width: 504px;
margin-left: auto;
margin-right: auto;
}
[purpose='form-image'] {
display: none;
}
}
@media (max-width: 768px) {
@ -267,7 +342,6 @@
padding-left: 24px;
padding-right: 24px;
}
}
@media (max-width: 575px) {
[purpose='logo-container'] {

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
<div purpose="continue-banner" id="start-cta" class="d-flex justify-content-end">
<div purpose="banner-body" class="d-flex flex-row align-items-center invisible <%- collapseStartCta ? 'collapsed' : ''%>">
<div purpose="banner-image-background">
<div purpose="banner-image">
<div purpose="banner-image" class="<%=['2 - Aware'].includes(me.psychologicalStage) ? 'stage-two' : ['3 - Intrigued'].includes(me.psychologicalStage) ? 'stage-three' : ['4 - Has use case'].includes(me.psychologicalStage) ? 'stage-four' : ['5 - Personally confident'].includes(me.psychologicalStage) ? 'stage-five' : ['6 - Has team buy-in'].includes(me.psychologicalStage) ? 'stage-six' : ''%>">
</div>
</div>
<div purpose="banner-text" class="d-flex flex-column justify-content-center">