Skip to content

Commit

Permalink
Site 3912 (#120)
Browse files Browse the repository at this point in the history
* Changes from SITE-3986

* Update B1Tab.tsx

* Create SMTPTestCases.tsx

* Remove duplicate files

* Add env variables and move API calls to ServerActions

* Improve environment variable name

* Remove env variables

* Add Loading Button, Remove Default Profile Values

* add IMAP/POP3 manual validation, attachment type field

* Fix tab data carryover, fix include filter

* Add XDR endpoint fields

* Add XDR DocumentSelector handling

* Fix incorrect emails

* Fix missing doc select on XDR 3

* Add logs formatting

* Fix reversed IMAP and POP3 icons

* Add tooltip

* Fix XDR logs and missing manual validations

* Add attachment type tooltip

* Remove Tooltips add XDR API call

* Add error condition, add clear button

* Fix more info sections, censor profile password

* Add clear selected document

* Remove accept/reject on API error

* Fix XDR more info page

* add tooltip and pop over for endpoint copy

* Fix incorrect xdr email addresses

* Replace popover system and fix error handling

* Language improvements and fix clear button visibility trigger

* Fix language errors

* Add clear button to XDR send

* Basic xdr functionality

* Add manual validation, request/response, remining request fields,

* add xdr document selector

* Add XDR Document Select test functionality, add colorized XML display

* Correct document selection per sub criteria

* Fix failure detection on empty responses

* Banish type errors

* Less restrictive clear button

* Fix CORS issue with document select

* Update DocumentSelector.tsx

* add prettier ignore to bugged line

* Add improved warning triggers

* Add backup content, fix criteriaMet icon on non manual tests
  • Loading branch information
ebrockainq authored Sep 6, 2024
1 parent c3fc404 commit 0d685d9
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"experimentalTernaries": false,
"singleQuote": true,
"jsxSingleQuote": false,
"quoteProps": "consistent",
"quoteProps": "as-needed",
"trailingComma": "es5",
"singleAttributePerLine": false,
"htmlWhitespaceSensitivity": "css",
Expand Down
49 changes: 41 additions & 8 deletions src/components/direct/hisp/TestCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import DynamicTable from './DynamicTable'
import InfoIcon from '@mui/icons-material/Info'
import _ from 'lodash'
import React, { useState } from 'react'
import DocumentSelector from './DocumentSelector'
Expand All @@ -23,6 +22,7 @@ import {
Checkbox,
TextField,
SelectChangeEvent,
Popover,
} from '@mui/material'

export type TestCaseFields = {
Expand Down Expand Up @@ -100,6 +100,10 @@ const TestCard = ({
tlsRequired = false,
receive,
}: TestCardProps) => {
const [popoverAnchorEl, setPopoverAnchorEl] = useState<HTMLButtonElement | null>(null)
const popoverOpen = Boolean(popoverAnchorEl)
const popoverId = popoverOpen ? 'ccda-file-required-popover' : undefined
const [autoCloseTimer, setAutoCloseTimer] = useState<NodeJS.Timeout | null>(null)
const attachmentTypeTestIDs = [231, 331]
const manualValidationCriteria = [
"['b1-5']",
Expand All @@ -118,7 +122,6 @@ const TestCard = ({
const [isFinished, setIsFinished] = useState(false)
const [apiError, setApiError] = useState(false)
const [attachmentType, setAttachmentType] = useState('')
const apiUrl = process.env.CCDA_DOCUMENTS || 'https://ett.healthit.gov/ett/api/ccdadocuments'

const handleDocumentConfirm = (selectedData: SelectedDocument) => {
console.log('Confirmed Document', selectedData)
Expand Down Expand Up @@ -194,9 +197,21 @@ const TestCard = ({
setFormData((prev) => ({ ...prev, [name]: value }))
}

const handleClosePopover = () => {
if (autoCloseTimer) {
clearTimeout(autoCloseTimer)
setAutoCloseTimer(null)
}
setPopoverAnchorEl(null)
}

const handleRunTest = async () => {
if (test.ccdaFileRequired && !documentDetails) {
alert('This test requires a CCDA document to be selected. Please select a document before running the test.')
setPopoverAnchorEl(document.activeElement as HTMLButtonElement)
const timer = setTimeout(() => {
handleClosePopover()
}, 2500)
setAutoCloseTimer(timer)
} else {
try {
setIsLoading(true)
Expand Down Expand Up @@ -294,7 +309,25 @@ const TestCard = ({
<Card>
<CardHeader title={test.name} />
<Divider />

{}
<Popover
id={popoverId}
open={popoverOpen}
anchorEl={popoverAnchorEl}
onClose={handleClosePopover}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
<Typography sx={{ p: 2 }}>
This test requires a CCDA document to be selected. Please select a document before running the test.
</Typography>
</Popover>
{showDetail ? (
<>
<CardContent>
Expand Down Expand Up @@ -353,10 +386,10 @@ const TestCard = ({
<Button
variant="outlined"
sx={{
'color': 'black',
'backgroundColor': '#E8E8E8',
'borderColor': 'transparent',
'boxShadow': '0px 3px 1px -2px rgba(0, 0, 0, 0.20)',
color: 'black',
backgroundColor: '#E8E8E8',
borderColor: 'transparent',
boxShadow: '0px 3px 1px -2px rgba(0, 0, 0, 0.20)',
'&:hover': {
backgroundColor: '#E8E8E8',
boxShadow: '0px 4px 2px -1px rgba(0, 0, 0, 0.22)',
Expand Down
130 changes: 91 additions & 39 deletions src/components/direct/hisp/XDRTestCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,37 @@ import {
CardContent,
CardHeader,
Divider,
Snackbar,
TextField,
Tooltip,
Typography,
FormControl,
Popover,
} from '@mui/material'
import InfoIcon from '@mui/icons-material/Info'
import ContentPasteGoIcon from '@mui/icons-material/ContentPasteGo'
import _ from 'lodash'
import React, { useState } from 'react'
import React, { useState, useEffect, useRef } from 'react'
import DynamicTable from './DynamicTable'
import { handleXDRAPICall } from '../test-by-criteria/ServerActions'
import CheckCircleIcon from '@mui/icons-material/CheckCircle'
import CancelIcon from '@mui/icons-material/Cancel'
import LoadingButton from '../shared/LoadingButton'
import DocumentSelector from './DocumentSelector'
import { getSession } from 'next-auth/react'
import { useSession } from 'next-auth/react'
import XMLDisplay from '../shared/colorizeXML'

export type TestCaseFields = {
'name'?: string
'id': string | number
'protocol'?: string
'desc'?: string
'sutEdge'?: boolean
'sutHisp'?: boolean
'sutRole'?: string
'criteria'?: string
'status'?: string
'ccdaFileRequired'?: boolean
'inputs'?: InputFields[]
'moreInfo'?: {
name?: string
id: string | number
protocol?: string
desc?: string
sutEdge?: boolean
sutHisp?: boolean
sutRole?: string
criteria?: string
status?: string
ccdaFileRequired?: boolean
inputs?: InputFields[]
moreInfo?: {
subHeader?: string
subDesc?: string
subDesc2?: string
Expand Down Expand Up @@ -152,8 +149,14 @@ const TestCard = ({ test, receive }: TestCardProps) => {
const [isLoading, setIsLoading] = useState(false)
const [apiError, setApiError] = useState(false)
const [isFinished, setIsFinished] = useState(false)

const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null)
const [popoverMessage, setPopoverMessage] = useState('')
const [autoCloseTimer, setAutoCloseTimer] = useState<NodeJS.Timeout | null>(null)
const open = Boolean(anchorEl)
const id = open ? 'simple-popover' : undefined
const hiddenAnchorRef = useRef(null)

const [logType, setLogType] = useState<'request' | 'response'>('request')
const manualValidationCriteria = ["['b1-3']", "['b1-3','su1-3']"]
const { data: session } = useSession()
Expand All @@ -162,7 +165,6 @@ const TestCard = ({ test, receive }: TestCardProps) => {
const subDesc = test['Purpose/Description']
const expTestHeader = 'Expected Test Results'
const expTestResults = test['Expected Test Results']
const apiUrl = process.env.CCDA_DOCUMENTS_XDR || 'https://ett.healthit.gov/ett/api/ccdadocuments'

const requiresCCDADocument = () => {
return test.inputs?.some((input) => input.key === 'payload' && input.type?.includes('CCDAWidget'))
Expand All @@ -174,21 +176,38 @@ const TestCard = ({ test, receive }: TestCardProps) => {

const handleClick = (event: React.MouseEvent<HTMLButtonElement>, link: string) => {
navigator.clipboard.writeText(link)
setAnchorEl(event.currentTarget)
setPopoverMessage('Copied to clipboard!')
showPopover('Copied to clipboard!', event.currentTarget)
}

const handleClose = () => {
const showPopover = (message: string, anchor: HTMLButtonElement | null) => {
setPopoverMessage(message)
setAnchorEl(anchor || hiddenAnchorRef.current)

if (autoCloseTimer) clearTimeout(autoCloseTimer)
const timer = setTimeout(() => {
handleClosePopover()
}, 3000)
setAutoCloseTimer(timer)
}

useEffect(() => {
return () => {
if (autoCloseTimer) clearTimeout(autoCloseTimer)
}
}, [autoCloseTimer, anchorEl])

const handleClosePopover = () => {
if (autoCloseTimer) {
clearTimeout(autoCloseTimer)
setAutoCloseTimer(null)
}
setAnchorEl(null)
}

const toggleLogType = (type: 'request' | 'response') => {
setLogType(type)
}

const open = Boolean(anchorEl)
const id = open ? 'simple-popover' : undefined

const endpointTestIds = [
'10',
'11',
Expand All @@ -206,6 +225,9 @@ const TestCard = ({ test, receive }: TestCardProps) => {
'44mu2',
]

const ccdaRequiredTestIds = ['1', '2', '3add']
const isCCDADocumentRequired = ccdaRequiredTestIds.includes(test.id.toString())

const [formData] = useState<{ [key: string]: FieldValue }>(() => {
const initialData: { [key: string]: FieldValue } = {}
test.moreInfo?.fields?.forEach((field) => {
Expand All @@ -225,11 +247,17 @@ const TestCard = ({ test, receive }: TestCardProps) => {

const handleRunTest = async () => {
if (!session) {
alert('You must be logged in and have a valid session to perform this action.')
showPopover('You must be logged in and have a valid session to perform this action.', null)
return
}
if (test.ccdaFileRequired && !documentDetails) {
alert('This test requires a CCDA document to be selected. Please select a document before running the test.')
console.log('ccda required' + test.ccdaFileRequired)
console.log('doc details ' + documentDetails)
if (isCCDADocumentRequired && !documentDetails) {
showPopover(
'This test requires a CCDA document to be selected. Please select a document before running the test.',
null
)
return
} else {
const ip_address = fieldValues['ip_address'] || ''
const port = fieldValues['port'] || ''
Expand Down Expand Up @@ -261,18 +289,22 @@ const TestCard = ({ test, receive }: TestCardProps) => {
uscdiv3: false,
})
setIsFinished(true)
setCriteriaMet(response.criteriaMet)
if (test.criteria && !manualValidationCriteria.includes(test.criteria)) {
setCriteriaMet(response.criteriaMet)
}
setTestRequestRequest(response.testRequest)
setTestRequestResponse(response.testResponse)
if (!testRequest && !testResponse) {
if (!testRequest && !testResponse && test.criteria && !manualValidationCriteria.includes(test.criteria)) {
setCriteriaMet('FALSE')
}
console.log('Criteria met: ', response.criteriaMet)
console.log('Test Request Responses:', response.testResponse)
} catch (error) {
console.error('Failed to run test:', error)
setApiError(true)
setCriteriaMet('FALSE')
if (test.criteria && !manualValidationCriteria.includes(test.criteria)) {
setCriteriaMet('FALSE')
}
} finally {
setIsLoading(false)
if (test.criteria && !manualValidationCriteria.includes(test.criteria)) {
Expand Down Expand Up @@ -381,10 +413,10 @@ const TestCard = ({ test, receive }: TestCardProps) => {
<Button
variant="outlined"
sx={{
'color': 'black',
'backgroundColor': '#E8E8E8',
'borderColor': 'transparent',
'boxShadow': '0px 3px 1px -2px rgba(0, 0, 0, 0.20)',
color: 'black',
backgroundColor: '#E8E8E8',
borderColor: 'transparent',
boxShadow: '0px 3px 1px -2px rgba(0, 0, 0, 0.20)',
'&:hover': {
backgroundColor: '#E8E8E8',
boxShadow: '0px 4px 2px -1px rgba(0, 0, 0, 0.22)',
Expand All @@ -404,11 +436,27 @@ const TestCard = ({ test, receive }: TestCardProps) => {
<CardHeader title={test.name}></CardHeader>
<Divider />
<CardContent>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClosePopover}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
>
<Typography sx={{ p: 2 }}>{popoverMessage}</Typography>
</Popover>
{showDetail ? (
renderMoreInfo()
) : showLogs ? (
<CardContent>
<Typography variant="h3">Log for XDR Test ${test.name}</Typography>
<Typography variant="h3">Log for XDR Test {test.name}</Typography>

<Box sx={{ display: 'flex', gap: 1, justifyContent: 'flex-start', mt: 2, mb: 2 }}>
<Button
Expand Down Expand Up @@ -436,8 +484,7 @@ const TestCard = ({ test, receive }: TestCardProps) => {
{test.criteria &&
manualValidationCriteria.includes(test.criteria) &&
testRequest &&
testRequest.length > 0 &&
criteriaMet.includes('SUCCESS') && (
testRequest.length > 0 && (
<Box sx={{ display: 'flex', gap: 1 }}>
<Button variant="contained" color="primary" onClick={handleAcceptTest}>
Accept
Expand Down Expand Up @@ -466,7 +513,7 @@ const TestCard = ({ test, receive }: TestCardProps) => {
)}
{_.has(test, 'inputs') &&
test.inputs &&
test.inputs.filter(shouldDisplayInput).map((input, index) => (
test.inputs.filter(shouldDisplayInput).map((input) => (
<Box sx={{ pt: 2 }} key={input.key || 'default-key'}>
<FormControl fullWidth>
<TextField
Expand Down Expand Up @@ -519,10 +566,14 @@ const TestCard = ({ test, receive }: TestCardProps) => {
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
onClose={handleClosePopover}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
horizontal: 'center',
}}
>
<Typography sx={{ p: 2 }}>{popoverMessage}</Typography>
Expand Down Expand Up @@ -568,6 +619,7 @@ const TestCard = ({ test, receive }: TestCardProps) => {
>
RUN
</LoadingButton>
<div ref={hiddenAnchorRef} style={{ visibility: 'hidden', top: '50px' }}></div>
<Button variant="contained" onClick={handleToggleDetail}>
MORE INFO
</Button>
Expand Down
8 changes: 6 additions & 2 deletions src/components/direct/test-by-criteria/ServerActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export async function handleXDRAPICall(data: XDRAPICallData): Promise<XDRAPIResp
url: apiUrl,
headers: {
'Content-Type': 'application/json',
// prettier-ignore
'Cookie': `JSESSIONID=${data.jsession}`,
},
data: JSON.stringify(formattedData),
Expand All @@ -144,10 +145,13 @@ export async function handleXDRAPICall(data: XDRAPICallData): Promise<XDRAPIResp
console.log('Raw content:', response.data)
const content = response.data

const testRequest = content.content.value.request || content.message
const testResponse = content.content.value.response

return {
criteriaMet: content.status,
testRequest: content.content.value.request,
testResponse: content.content.value.response,
testRequest: testRequest,
testResponse: testResponse,
}
} catch (error) {
if (axios.isAxiosError(error) && error.response) {
Expand Down

0 comments on commit 0d685d9

Please sign in to comment.