Skip to content

Commit

Permalink
Update Medallia logic to what is in production (#860)
Browse files Browse the repository at this point in the history
  • Loading branch information
randimays authored Jan 8, 2025
1 parent 62b1541 commit 3fdc28c
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 91 deletions.
8 changes: 8 additions & 0 deletions src/lib/utils/medallia.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ describe('medallis.ts', () => {
expect(getSurveyNumber('/search', true)).toBe(21)
expect(getSurveyNumber('/unknown-path', false)).toBe(11)
expect(getSurveyNumber('/unknown-path', true)).toBe(17)
expect(getSurveyNumber('/resources', true)).toBe(17)
expect(getSurveyNumber('/contact-us/virtual-agent', false)).toBe(26)
expect(
getSurveyNumber(
'/my-health/medical-records/summaries-and-notes/visit-summary',
true
)
).toBe(17)
})

test('loadForm calls KAMPYLE_ONSITE_SDK.loadForm with correct form number', () => {
Expand Down
87 changes: 71 additions & 16 deletions src/lib/utils/medallia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,101 @@ type KampyleOnsiteSdk = Window &
vaSurvey: string
}

const vagovstagingsurveys = {
'/search': 20,
'/contact-us/virtual-agent': 26,
const SURVEY_NUMBERS = {
DEFAULT_STAGING_SURVEY: 11,
DEFAULT_PROD_SURVEY: 17,
SEARCH_PROD: 21,
SEARCH_STAGING: 20,
CONTACT_US_VIRTUAL_AGENT_PROD: 25,
CONTACT_US_VIRTUAL_AGENT_STAGING: 26,
SCHOOL_ADMINISTRATORS_PROD: 17,
SCHOOL_ADMINISTRATORS_STAGING: 37,
HEALTH_CARE_PROD: 17,
HEALTH_CARE_STAGING: 41,
VISIT_SUMMARY_PROD: 17,
VISIT_SUMMARY_STAGING: 41,
}

const vagovprodsurveys = {
'/search': 21,
'/contact-us/virtual-agent': 25,
}

function trimSlash(url: string): string {
if (url.length === 0) return
return url.charAt(url.length - 1) === '/' ? url.slice(0, url.length - 1) : url
const medalliaSurveys = {
urls: {
'/search': {
production: SURVEY_NUMBERS.SEARCH_PROD,
staging: SURVEY_NUMBERS.SEARCH_STAGING,
},
'/contact-us/virtual-agent': {
production: SURVEY_NUMBERS.CONTACT_US_VIRTUAL_AGENT_PROD,
staging: SURVEY_NUMBERS.CONTACT_US_VIRTUAL_AGENT_STAGING,
},
'/school-administrators': {
production: SURVEY_NUMBERS.SCHOOL_ADMINISTRATORS_PROD,
staging: SURVEY_NUMBERS.SCHOOL_ADMINISTRATORS_STAGING,
},
},
urlsWithSubPaths: {
'/health-care': {
production: SURVEY_NUMBERS.HEALTH_CARE_PROD,
staging: SURVEY_NUMBERS.HEALTH_CARE_STAGING,
},
'/my-health/medical-records/summaries-and-notes/visit-summary': {
production: SURVEY_NUMBERS.VISIT_SUMMARY_PROD,
staging: SURVEY_NUMBERS.VISIT_SUMMARY_STAGING,
},
'/resources': {
production: SURVEY_NUMBERS.DEFAULT_PROD_SURVEY,
staging: SURVEY_NUMBERS.DEFAULT_STAGING_SURVEY,
},
},
}

export function getSurveyNumber(url: string, isProduction = false): number {
const pathUrl = trimSlash(url.toString())
if (isProduction) {
return vagovprodsurveys[pathUrl] ? vagovprodsurveys[pathUrl] : 17
} else {
return vagovstagingsurveys[pathUrl] ? vagovstagingsurveys[pathUrl] : 11
const defaultSurvey = isProduction
? SURVEY_NUMBERS.DEFAULT_PROD_SURVEY
: SURVEY_NUMBERS.DEFAULT_STAGING_SURVEY

const buildEnv = isProduction ? 'production' : 'staging'

if (typeof url !== 'string' || url === null) {
return defaultSurvey
}

// Check for exact path match
if (url in medalliaSurveys.urls) {
const surveyInfo = medalliaSurveys.urls[url]

return surveyInfo[buildEnv] || defaultSurvey
}

// Check for subpath match
for (const [subpath, surveyInfo] of Object.entries(
medalliaSurveys.urlsWithSubPaths
)) {
if (url.startsWith(subpath)) {
return surveyInfo[buildEnv] || defaultSurvey
}
}

return defaultSurvey
}

export function loadForm(formNumber: number): boolean {
const KAMPYLE_ONSITE_SDK = (window as KampyleOnsiteSdk).KAMPYLE_ONSITE_SDK

if (KAMPYLE_ONSITE_SDK) {
return KAMPYLE_ONSITE_SDK.loadForm(formNumber)
}
}

export function showForm(formNumber: number): boolean {
const KAMPYLE_ONSITE_SDK = (window as KampyleOnsiteSdk).KAMPYLE_ONSITE_SDK

if (KAMPYLE_ONSITE_SDK) {
return KAMPYLE_ONSITE_SDK.showForm(formNumber)
}
}

export function onMedalliaLoaded(callback: () => void): void {
const KAMPYLE_ONSITE_SDK = (window as KampyleOnsiteSdk).KAMPYLE_ONSITE_SDK

if (KAMPYLE_ONSITE_SDK) {
callback()
} else {
Expand Down
122 changes: 47 additions & 75 deletions src/templates/common/contentFooter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ import { MedalliaAssets } from '@/templates/common/medallia'
import { getSurveyNumber, showForm } from '@/lib/utils/medallia'
import { BUILD_TYPES } from '@/lib/constants/environment'

// "Back to top", "Last updated" date and Medallia feedback button

type ContentFooterProps = {
lastUpdated?: string | number
// responsiveLayout should be passed by the "landing_page" content type only
responsiveLayout?: string
}

function formatDate(date: Date, format: 'display' | 'machine'): string {
const dateParts = getDateParts(date)

if (format === 'display') {
const month = dateParts.month?.name
const day = dateParts.day?.numeric
Expand All @@ -33,91 +38,58 @@ function formatDate(date: Date, format: 'display' | 'machine'): string {
}
}

function FeedbackButton() {
useEffect(() => {
const vaButton = document.getElementById('mdFormButton') as HTMLElement & {
shadowRoot?: ShadowRoot
}
if (vaButton && vaButton.shadowRoot) {
const shadowRoot = vaButton.shadowRoot

// Create a new observer
const observer = new MutationObserver(() => {
const button = shadowRoot.querySelector(
'.usa-button'
) as HTMLButtonElement
if (button) {
button.classList.add('feedback-button')
observer.disconnect() // Stop observing once we've found the button and added the class
}
})

// Start observing the shadow root with the configured parameters
observer.observe(shadowRoot, { childList: true, subtree: true })
}
}, [])
return (
<>
<MedalliaAssets />
<button
className="feedback-button usa-button"
id="mdFormButton"
onClick={() => {
const isProduction =
process.env.NEXT_PUBLIC_BUILD_TYPE === BUILD_TYPES.PROD
const surveyNumber = getSurveyNumber(
window.location.pathname,
isProduction
)
showForm(surveyNumber)
}}
>
Feedback
</button>
</>
)
}

export function ContentFooter({ lastUpdated }: ContentFooterProps) {
export function ContentFooter({
lastUpdated,
responsiveLayout,
}: ContentFooterProps) {
let displayDate, machineDate
let wrapperClasses = ''
const date = parseDate(lastUpdated)

if (date) {
displayDate = formatDate(date, 'display')
machineDate = formatDate(date, 'machine')
}

if (responsiveLayout === 'desktop') {
wrapperClasses = ' vads-u-display--none medium-screen:vads-u-display--block'
} else if (responsiveLayout === 'mobile') {
wrapperClasses = ' medium-screen:vads-u-display--none'
}

return (
<>
<div className="last-updated vads-u-padding-x--1 desktop-lg:vads-u-padding-x--0">
{displayDate && (
<div className="mobile-lg:vads-u-display--flex above-footer-elements-container">
<div className="vads-u-flex--auto">
<span className="vads-u-text-align--justify">
<p>
<>
Last updated:{' '}
<time dateTime={machineDate}>{displayDate}</time>
</>
</p>
</span>
</div>
<div className="vads-u-flex--1 vads-u-text-align--right">
<span className="vads-u-text-align--right">
<FeedbackButton />
</span>
</div>
</div>
)}
{!displayDate && (
<div className="vads-u-display--flex above-footer-elements-container">
<div className="vads-u-flex--1 vads-u-text-align--right">
<span className="vads-u-text-align--right">
<FeedbackButton />
</span>
</div>
<div
className={`last-updated usa-content vads-u-padding-x--1 desktop-lg:vads-u-padding-x--0${wrapperClasses}`}
>
<div className="mobile-lg:vads-u-display--flex above-footer-elements-container">
{displayDate && machineDate && (
<div className="vads-u-flex--auto">
<span className="vads-u-text-align--justify">
<p>
Last updated:&nbsp;
<time dateTime={machineDate}>{displayDate}</time>
</p>
</span>
</div>
)}
<div className="vads-u-flex--1 vads-u-text-align--right">
<MedalliaAssets />
<va-button
label="Give feedback"
id="mdFormButton"
onClick={() => {
const isProduction =
process.env.NEXT_PUBLIC_BUILD_TYPE === BUILD_TYPES.PROD
const surveyNumber = getSurveyNumber(
window.location.pathname,
isProduction
)
showForm(surveyNumber)
}}
text="Feedback"
/>
</div>
</div>
</>
</div>
)
}

0 comments on commit 3fdc28c

Please sign in to comment.