diff --git a/public/print.css b/public/print.css index 37f08c59..3abe9eb1 100644 --- a/public/print.css +++ b/public/print.css @@ -1,443 +1,464 @@ +.test-label-section { + background-color: pink; + margin: 10px; + padding: 20px; +} + +.test-label-section > h1, +.test-label-section > h2 { + text-align: left; + justify-self: unset; +} + +.test-label-section .label-value-container { + border: 1px solid black; + padding: 10px; +} .App { - text-align: center; + text-align: center; } .App-logo { - height: 40vmin; - pointer-events: none; + height: 40vmin; + pointer-events: none; } @media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } + .App-logo { + animation: App-logo-spin infinite 20s linear; + } } -.align-right{ - text-align: right; +.align-right { + text-align: right; } .App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; } .App-link { - color: #61dafb; + color: #61dafb; } @keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } /* Code below are added by PNNL */ /*Headings*/ h1 { - font-size: 1.5rem; - text-align: center; - break-after: avoid-page; - justify-self: center; + font-size: 1.5rem; + text-align: center; + break-after: avoid-page; + justify-self: center; } h2 { - break-after: avoid-page; - font-size: 1.25rem; + break-after: avoid-page; + font-size: 1.25rem; } -h2:not(.accordion-header, h1+h2) { - margin-top: 30px; +h2:not(.accordion-header, h1 + h2) { + margin-top: 30px; } h3 { - font-size: 1rem; - break-after: avoid-page; + font-size: 1rem; + break-after: avoid-page; } /* used in all templates - for report title */ h1 + h2 { - text-align: center; + text-align: center; } /* used in mdx_project_details_view.tsx */ h1 + h3 { - text-align: center; + text-align: center; } /* used in workflows_view.tsx, mdx_template_view.tsx, job_view.tsx */ -.address -{ - text-align: center; +.address { + text-align: center; } /* used in home.tsx */ .flex-container { - display: flex; - flex-direction: row; - gap: 10px; - align-items: flex-start; - align-content: center; - justify-content: space-around; + display: flex; + flex-direction: row; + gap: 10px; + align-items: flex-start; + align-content: center; + justify-content: space-around; } .flex-child { - flex: 1; - align-self: top; + flex: 1; + align-self: top; } /* used in jobs_view.tsx */ .icon-container { - float: right; - vertical-align: top; + float: right; + vertical-align: top; } .button-container-right { - padding-left: 0.75rem; - padding-right: 0.75rem; - float: right; + padding-left: 0.75rem; + padding-right: 0.75rem; + float: right; } .button-container-center { - float: center; - padding-left: 0.75rem; - padding-right: 0.75rem; + float: center; + padding-left: 0.75rem; + padding-right: 0.75rem; } - - .menu-container { - float: right; - vertical-align: top; + float: right; + vertical-align: top; } - .img-thumbnail { - object-fit: contain; - max-height: 500px; + object-fit: contain; + max-height: 500px; } /* jobs_view.tsx & collapsible.tsx */ .bottom-margin { - margin-bottom: 10px; + margin-bottom: 10px; } +.string-input-modal { + .error { + color: red; + font-style: italic; + } +} -.string-input-modal{ - .error{ +.error { color: red; font-style: italic; - } } -.error{ - color: red; - font-style: italic; -} - - /* root_layout.tsx */ #root-flex-layout { - display: flex; - align-items: center; - justify-content: center; + display: flex; + align-items: center; + justify-content: center; } #root-background { - margin-left: auto; - margin-right: auto; - max-width: 800px; - background-color: rgba(231, 231, 231); - min-height: 100vh; + margin-left: auto; + margin-right: auto; + max-width: 800px; + background-color: rgba(231, 231, 231); + min-height: 100vh; } #root-banner { - background-color: #006100; + background-color: #006100; } #root-title { - color: gold; - font-size: 2rem; + color: gold; + font-size: 2rem; } #root-body { - padding-top: 1rem; - padding-bottom: 1rem; + padding-top: 1rem; + padding-bottom: 1rem; } #back-button-logo { - color: white; - height: 100%; + color: white; + height: 100%; } #back-button { - padding: 1rem; - background-color: #006100; + padding: 1rem; + background-color: #006100; } #back-button-link { - text-decoration: none; + text-decoration: none; } #back-button-container { - margin-left: 0.5rem; - margin-right: 0.5rem; + margin-left: 0.5rem; + margin-right: 0.5rem; } /* editor-flexbox.tsx */ -.editor-textarea{ - height: auto; - min-height: 700px; - resize: none; +.editor-textarea { + height: auto; + min-height: 700px; + resize: none; } /* photo_input.tsx */ .input-card { - page-break-before: always; - margin-bottom: 1rem; + page-break-before: always; + margin-bottom: 1rem; } /*also in radio.tsx*/ /* stylizes the hidden input for photo upload*/ .photo-upload-input { - display: none; + display: none; } /* photo.tsx */ .photo-card { - break-inside: avoid; - margin-bottom: 1rem; - margin-top: 1rem; + break-inside: avoid; + margin-bottom: 1rem; + margin-top: 1rem; +} + +.photo-card > .card-body > div { + margin-bottom: 1rem; } .photo-row { - display: grid; - grid-template-columns: 1fr 1fr; /* Forces two columns */ - gap: 1rem; + display: grid; + grid-template-columns: 1fr 1fr; /* Forces two columns */ + gap: 1rem; +} + +.photo-notes h3 { + font-weight: bold; +} + +.photo-notes .photo-note-string { + margin-bottom: unset; } /* stylizes tab component here to avoid putting styles in editor*/ .tab-content { - margin-top: 1rem; + margin-top: 1rem; } /* styling for PDFRenderer component */ -.react-pdf__Page__textContent{ +.react-pdf__Page__textContent { display: none; - } +} /* 'hint' styling - the input components */ -.form-text{ - margin-left:.50rem; - margin-top:.25rem; - font-size:.875rem; - color:var(--bs-secondary-color); - font-style: italic; +.form-text { + margin-left: 0.5rem; + margin-top: 0.25rem; + font-size: 0.875rem; + color: var(--bs-secondary-color); + font-style: italic; } /* label styling for the Radio component */ .custom-label { - color: gray; - font-size: .9rem; + color: gray; + font-size: 0.9rem; } - /* BETA version text - styling for new templates - temperary */ .beta-text { - color: red; - padding-left: .75rem; - font-size: 0.9rem; + color: red; + padding-left: 0.75rem; + font-size: 0.9rem; } /* used in home.tsx */ .padding { - padding: 5px 10px 5px 10px; /* top right bottom left*/ + padding: 5px 10px 5px 10px; /* top right bottom left*/ } -.top-bottom-padding -{ - padding: 5px 0 5px 0; +.top-bottom-padding { + padding: 5px 0 5px 0; } /* disclaimer text */ .disclaimer-text { - padding-left: .75rem; - padding-right: .75rem; - font-size: 0.9rem; - font-weight: bold; + padding-left: 0.75rem; + padding-right: 0.75rem; + font-size: 0.9rem; + font-weight: bold; } .combustion_tests { - padding: 5px 10px 5px 10px; - background-color: white; + padding: 5px 10px 5px 10px; + background-color: white; } .align_justify { - justify-content: center; - text-align: justify; + justify-content: center; + text-align: justify; } .margin-left { - margin-left: 2em + margin-left: 2em; } - /* Primary Button - with background color */ .btn-primary { - color: #fff; /* Text color */ - background-color: #006100; /* Base background color */ - border: 2px solid #006100; - cursor: pointer; - text-align: center; - text-decoration: none; - display: inline-block; - transition: background-color 0.3s ease, border-color 0.3s ease; - outline: none; -} - -.btn-primary:hover, -.btn-primary:active, -.btn-primary:focus, -.btn-primary:focus-visible, + color: #fff; /* Text color */ + background-color: #006100; /* Base background color */ + border: 2px solid #006100; + cursor: pointer; + text-align: center; + text-decoration: none; + display: inline-block; + transition: + background-color 0.3s ease, + border-color 0.3s ease; + outline: none; +} + +.btn-primary:hover, +.btn-primary:active, +.btn-primary:focus, +.btn-primary:focus-visible, .btn-primary:focus-within { - background-color: #004d00; - border-color: #004d00; + background-color: #004d00; + border-color: #004d00; } .btn-primary:disabled { - background-color: #4caf50; - border-color: #4caf50; - cursor: not-allowed; /* Not-allowed cursor on disabled */ - opacity: 0.6; + background-color: #4caf50; + border-color: #4caf50; + cursor: not-allowed; /* Not-allowed cursor on disabled */ + opacity: 0.6; } /* Outline Primary Button - only outline */ .btn-outline-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active, .show > .btn-primary.dropdown-toggle { - color: #fff; - background-color: #005f00; - border-color: #005f00; + color: #fff; + background-color: #005f00; + border-color: #005f00; } .btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus, .show > .btn-primary.dropdown-toggle:focus { - box-shadow: none + box-shadow: none; } -.btn-outline-primary{ - background-color: transparent; - cursor: pointer; - border: 2px solid #006100; - color: #006100; - +.btn-outline-primary { + background-color: transparent; + cursor: pointer; + border: 2px solid #006100; + color: #006100; } -.btn-outline-primary:hover{ - background-color: transparent; - color: #006100; - border-color: #006100; +.btn-outline-primary:hover { + background-color: transparent; + color: #006100; + border-color: #006100; } - /* Light Button - for Icons */ .btn-light { - background-color: transparent; - border-color: transparent; - color: #000000; + background-color: transparent; + border-color: transparent; + color: #000000; } btn-light:active, btn-light:hover { - box-shadow: none; + box-shadow: none; } .welcome-header { - padding-left: 1rem; - padding-right: 1rem; - color: #006100; - font-size: 28px; - font-weight: bold; + padding-left: 1rem; + padding-right: 1rem; + color: #006100; + font-size: 28px; + font-weight: bold; } .welcome-content { - padding-left: 1.5rem; - padding-right: 1.5rem; - color: #000000; - font-size: 14px; - font-weight: bold; -} - -@media (max-width: 480px) { - .welcome-content { padding-left: 1.5rem; padding-right: 1.5rem; color: #000000; - font-size: 12px; + font-size: 14px; font-weight: bold; - } } +@media (max-width: 480px) { + .welcome-content { + padding-left: 1.5rem; + padding-right: 1.5rem; + color: #000000; + font-size: 12px; + font-weight: bold; + } +} .loader { - border: 8px solid #f3f3f3; /* Light gray */ - border-top: 8px solid #3498db; /* Blue */ - border-radius: 50%; - width: 30px; /* Size of the loader */ - height: 30px; /* Size of the loader */ - animation: spin 1s linear infinite; /* Animation */ - background-color: white; + border: 8px solid #f3f3f3; /* Light gray */ + border-top: 8px solid #3498db; /* Blue */ + border-radius: 50%; + width: 30px; /* Size of the loader */ + height: 30px; /* Size of the loader */ + animation: spin 1s linear infinite; /* Animation */ + background-color: white; } @keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } } - /* used in photo-input and photo component */ .photo-container { - width: auto; /* Allow width to adjust based on content */ - max-width: 500px; /* Maximum width */ - overflow: visible; /* Hide overflow */ - height: auto; /* Allow height to adjust based on content */ - max-height: 600px; /* Maximum height */ - margin-bottom: 5px; /* Margin at the bottom */ - position: relative; /* Relative positioning for overlay elements */ - display: inline-block; /* Display inline-block to shrink to content size */ + width: auto; /* Allow width to adjust based on content */ + max-width: 500px; /* Maximum width */ + overflow: visible; /* Hide overflow */ + height: auto; /* Allow height to adjust based on content */ + max-height: 600px; /* Maximum height */ + margin-bottom: 5px; /* Margin at the bottom */ + position: relative; /* Relative positioning for overlay elements */ + display: inline-block; /* Display inline-block to shrink to content size */ } .photo-report-container { - width: auto; /* Allow width to adjust based on content */ - max-width: 500px; /* Maximum width */ - overflow: hidden; /* Hide overflow */ - height: auto; /* Allow height to adjust based on content */ - max-height: 600px; /* Maximum height */ - position: relative; /* Relative positioning for overlay elements */ - display: inline-block; /* Display inline-block to shrink to content size */ + width: auto; /* Allow width to adjust based on content */ + max-width: 500px; /* Maximum width */ + overflow: hidden; /* Hide overflow */ + height: auto; /* Allow height to adjust based on content */ + max-height: 600px; /* Maximum height */ + position: relative; /* Relative positioning for overlay elements */ + display: inline-block; /* Display inline-block to shrink to content size */ } /* used in photo-input component */ .photo-delete-button { - position: absolute; - top: 15px; - right: 15px; - border-radius: 50%; - padding: 5px; - z-index: 5; /* Ensures the button stays on top */ - cursor: pointer; - transform: scale(1.2); /* Increase icon size */ - stroke-width: 2; + position: absolute; + top: 15px; + right: 15px; + border-radius: 50%; + padding: 5px; + z-index: 5; /* Ensures the button stays on top */ + cursor: pointer; + transform: scale(1.2); /* Increase icon size */ + stroke-width: 2; } /* used in photo-input component */ -.image-tag { - width: '400px'; /* Fixed width */ - height: '400px'; /* Fixed height */ - object-fit: 'cover'; /* Ensure the image covers the area (cropped if necessary) */ - border-radius: '8px'; /*Optional: adds rounded corners to the image */ +.image-tag { + width: '400px'; /* Fixed width */ + height: '400px'; /* Fixed height */ + object-fit: 'cover'; /* Ensure the image covers the area (cropped if necessary) */ + border-radius: '8px'; /*Optional: adds rounded corners to the image */ } /* used in photo-input component */ @@ -451,41 +472,53 @@ btn-light:hover { /* used in photo-input component */ .custom-modal { - max-width: 300px; - margin: auto; + max-width: 300px; + margin: auto; +} + +/* Used in text_input component */ +.label-hidden.form-floating > label { + visibility: hidden; +} + +.label-hidden.form-floating > textarea { + padding: 1rem 0.75rem !important; +} + +.text-area-expanded.form-floating > textarea { + height: 100px; } /* Default font size */ .modal-body-text { - font-size: 18px; /* Adjust the default font size */ + font-size: 18px; /* Adjust the default font size */ } /* Common font size for medium, small, and extra small devices */ @media (max-width: 991.98px) { - .modal-body-text { - font-size: 14px; /* Adjust font size for all specified devices */ - } + .modal-body-text { + font-size: 14px; /* Adjust font size for all specified devices */ + } } .safari-print-header { -visibility: hidden;} + visibility: hidden; +} @media print { - /* Adjusts the margin for printing */ - @page { - margin-top: 4rem; - margin-bottom: 4rem; - } - - - .safari-print-header { - text-align: center; - font-size: 10px; - font-weight: bold; - visibility: visible; - margin-bottom: 10px; - display: block; - page-break-before: always; - } - + /* Adjusts the margin for printing */ + @page { + margin-top: 4rem; + margin-bottom: 4rem; + } + + .safari-print-header { + text-align: center; + font-size: 10px; + font-weight: bold; + visibility: visible; + margin-bottom: 10px; + display: block; + page-break-before: always; + } } diff --git a/src/App.css b/src/App.css index eb08d787..87bfdef5 100644 --- a/src/App.css +++ b/src/App.css @@ -1,3 +1,19 @@ +.playground-section { + background-color: lightgrey; + margin: 10px; + padding: 20px; +} + +.playground-section > h1, +.playground-section > h2 { + text-align: left; + justify-self: unset; +} + +.playground-section .label-value-container { + border: 1px solid black; + padding: 10px; +} .App { text-align: center; } diff --git a/src/__tests__/labelValue.test.tsx b/src/__tests__/labelValue.test.tsx new file mode 100644 index 00000000..d8a65937 --- /dev/null +++ b/src/__tests__/labelValue.test.tsx @@ -0,0 +1,116 @@ +//to run this test: npm test -- src/__tests__/labelValue.test.tsx + +import { render, screen } from '@testing-library/react' +import { StoreContext } from '../components/store' +import LabelValue, { LabelValueProps } from '../components/label_value' + +// Mock StoreContext data +const mockStoreContext = { + docId: 'TestDocID123', + attachments: {}, + data: { location: { state: 'WA', zip_code: '99354' } }, + metadata: {}, +} + +describe('LabelValue Component', () => { + // Helper function to render the component with StoreContext provider + const renderWithContext = ({ + label, + value, + required = false, + prefix = '', + suffix = '', + decimalPlaces = 1, + type = 'string', + }: LabelValueProps) => { + return render( + + + , + ) + } + + test('Label is rendered when label param is present', () => { + renderWithContext({ + label: 'Label Text', + type: 'string', + value: 'test this value', + }) + expect(screen.getByText(/label text/i)).toBeInTheDocument() + }) + + test('Value is rendered when value param is present', () => { + renderWithContext({ + label: 'Label Text', + type: 'string', + value: 'test this value', + }) + expect(screen.getByText(/test this value/i)).toBeInTheDocument() + }) + + test('Number value is rendered correctly with decimal places', () => { + renderWithContext({ + label: 'Label Numeric', + type: 'number', + value: 123.456, + decimalPlaces: 2, + }) + expect(screen.getByText(/123.46/i)).toBeInTheDocument() + }) + + test('Value with prefix and suffix is rendered correctly', () => { + renderWithContext({ + label: 'Label with Prefix and Suffix', + type: 'string', + value: '50', + prefix: '$', + suffix: ' USD', + }) + expect(screen.getByText(/\$50 USD/i)).toBeInTheDocument() + }) + + test('Should render date value correctly', () => { + renderWithContext({ + label: 'Label Date', + type: 'date', + value: '2025-02-14', + }) + expect(screen.getByText(/february 14, 2025/i)).toBeInTheDocument() + }) + + test('Should not render when required is false and value is empty', () => { + const { container } = renderWithContext({ + label: 'Label Text', + type: 'string', + value: '', + required: false, + }) + expect(container.firstChild).toBeNull() + }) + + test('Should not render when value is empty', () => { + const { container } = renderWithContext({ + label: 'Label Text', + type: 'string', + }) + expect(container.firstChild).toBeNull() + }) + + test('Should render when required is true and value is empty', () => { + renderWithContext({ + label: 'Label Text', + type: 'string', + value: '', + required: true, + }) + expect(screen.getByText(/label text/i)).toBeInTheDocument() + }) +}) diff --git a/src/components/label_value.tsx b/src/components/label_value.tsx index bf9d868c..21a94428 100644 --- a/src/components/label_value.tsx +++ b/src/components/label_value.tsx @@ -1,19 +1,28 @@ import React from 'react' +import DateStr from './date_str' /** * LabelValueProps defines the props for the LabelValue component. * * @interface LabelValueProps - * @property {string} label - The label to display next to the value. - * @property {string} value - The value to display. + * @property {string} [label] - The label to display next to the value. + * @property {string} [value] - The value to display. * @property {boolean} [required=false] - A flag to determine if the label-value pair should be rendered. + * @property {string} [prefix] - A prefix to display before the value. + * @property {string} [suffix] - A suffix to display after the value. + * @property {'string' | 'number' | 'date'} type - The type of value to display. + * @property {number} [decimalPlaces] - Number of decimal places to round the value if type is 'number'. + * @property {Intl.DateTimeFormatOptions} [dateOptions] - Options for date formatting if type is 'date'. */ -interface LabelValueProps { +export interface LabelValueProps { label?: string - value: string + value?: string | number | boolean required?: boolean prefix?: string suffix?: string + type: 'string' | 'number' | 'date' + decimalPlaces?: number + dateOptions?: Intl.DateTimeFormatOptions } /** @@ -36,17 +45,55 @@ const LabelValue: React.FC = ({ required = false, prefix = '', suffix = '', + decimalPlaces = 1, + type = 'string', + dateOptions, }: LabelValueProps): JSX.Element | null => { + //If type is "number" and decimalPlaces, round the value + if (type === 'number' && typeof value === 'number') { + //check that value is actually a number + //Need to do this because TS not currently configured for MDX files and there's a chance that + //someone could try to .toFixed("some string") and cause an error + if ( + typeof value === 'number' && + !isNaN(value) && + typeof decimalPlaces === 'number' && + !isNaN(decimalPlaces) + ) { + value = value.toFixed(decimalPlaces) + } else { + console.log( + 'Make sure that your value and decimalPlaces params are actually numbers.', + ) + } + } else if (type === 'number' && typeof value !== 'number') { + console.log( + `You are trying to set the type of a non-number value to 'number'. Value is : ${value} and typeof value is: ${typeof value}`, + ) + } + return required || value ? ( label ? (
- {label}: - {value} + + {label}: + + {prefix} + {type === 'date' && typeof value === 'string' ? ( + + ) : ( + value + )} + {suffix}
) : ( <> {prefix} - {value} + {type === 'date' && typeof value === 'string' ? ( + + ) : ( + value + )} {suffix} ) diff --git a/src/components/label_value_wrapper.tsx b/src/components/label_value_wrapper.tsx index df888697..1c24ec86 100644 --- a/src/components/label_value_wrapper.tsx +++ b/src/components/label_value_wrapper.tsx @@ -4,12 +4,16 @@ import { get } from 'lodash' import LabelValue from './label_value' interface LabelValueWrapperProps { - label: string - path: string + label?: string + path?: string prefix?: string suffix?: string required?: boolean parent?: any + value?: string | number | boolean + type?: 'string' | 'number' | 'date' + decimalPlaces?: number + dateOptions?: Intl.DateTimeFormatOptions } /** @@ -18,10 +22,16 @@ interface LabelValueWrapperProps { * The component conditionally renders the label-value pair based on the `required` prop. * * @param {LabelValueWrapperProps} props - The props for the `LabelValueWrapper` component. - * @param {string} props.label - The label to display next to the value. - * @param {string} props.path - The path in the data where the value can be found. + * @param {string} [props.label] - The label to display next to the value. + * @param {string} [props.path] - The path in the data where the value can be found. + * @param {string} [props.prefix] - A prefix to display before the value. + * @param {string} [props.suffix] - A suffix to display after the value. * @param {boolean} [props.required=false] - A flag to determine if the label-value pair should be rendered. * @param {any} [props.parent=null] - Optional. A custom parent object to retrieve the data from, instead of the global store context. + * @param {string | number | boolean} [props.value] - The value to display. + * @param {'string' | 'number' | 'date'} [props.type='string'] - The type of value to display. + * @param {number} [props.decimalPlaces] - Number of decimal places to round the value if type is 'number'. + * @param {Intl.DateTimeFormatOptions} [props.dateOptions] - Options for date formatting if type is 'date'. * * @returns {JSX.Element | null} - A JSX element containing the label and value if `required` is true, or null if `required` is false. * @@ -40,14 +50,20 @@ const LabelValueWrapper: React.FC = ({ suffix, parent = null, required = false, + decimalPlaces, + type = 'string', + dateOptions, + value, }: LabelValueWrapperProps): JSX.Element | null => { const [parentData, _] = useState(parent?.data_) return ( {({ data }) => { const data_object = parent ? parentData : data - const key = path == null ? '' : path - const value = get(data_object, key) + if (!value) { + const key = path == null ? '' : path + value = get(data_object, key) + } return ( = ({ required={required} prefix={prefix} suffix={suffix} + decimalPlaces={decimalPlaces} + type={type} + dateOptions={dateOptions} /> ) }} diff --git a/src/templates/LabelValueExamples/DateLabelValues.mdx b/src/templates/LabelValueExamples/DateLabelValues.mdx new file mode 100644 index 00000000..841d2a27 --- /dev/null +++ b/src/templates/LabelValueExamples/DateLabelValues.mdx @@ -0,0 +1,29 @@ +import DateInput from '../../components/date_input_wrapper' +import LabelValue from '../../components/label_value_wrapper' + +
+

Date Value Examples

+

Enter a date value to be retrieved by the LabelValues below

+ + + +

Date LabelValue with date type prop:

+ + `` + +
+ +
+ +

Date LabelValue without date type:

+ + `` + +
+ +
+
+ diff --git a/src/templates/LabelValueExamples/LabelValueExamplesStyles.css b/src/templates/LabelValueExamples/LabelValueExamplesStyles.css new file mode 100644 index 00000000..79d6dc81 --- /dev/null +++ b/src/templates/LabelValueExamples/LabelValueExamplesStyles.css @@ -0,0 +1,16 @@ +.label-value-section { + position: relative; +} + +.label-value-section nav { + position: sticky; + top: 0; + background-color: rgba(231, 231, 231); + z-index: 1; + padding: 10px 0px; +} + +.label-value-section ul { + display: flex; + flex-direction: column; +} diff --git a/src/templates/LabelValueExamples/NumberLabelValues.mdx b/src/templates/LabelValueExamples/NumberLabelValues.mdx new file mode 100644 index 00000000..0b165586 --- /dev/null +++ b/src/templates/LabelValueExamples/NumberLabelValues.mdx @@ -0,0 +1,32 @@ +import NumberInput from '../../components/number_input_wrapper'; +import LabelValue from '../../components/label_value_wrapper'; + +
+

Number Value Examples

+

Enter a number value to be retrieved by the LabelValues below

+ + +

LabelValue with number type prop:

+

Default is to round to 1 decimal place.

+ + `` + +
+ +
+ +

LabelValue with number type prop + decimal places + prefix + suffix:

+ + `` + +
+ +
+
diff --git a/src/templates/LabelValueExamples/OtherExamples.mdx b/src/templates/LabelValueExamples/OtherExamples.mdx new file mode 100644 index 00000000..3bae88df --- /dev/null +++ b/src/templates/LabelValueExamples/OtherExamples.mdx @@ -0,0 +1,56 @@ +import LabelValue from '../../components/label_value_wrapper'; +import NumberInput from '../../components/number_input_wrapper'; +import TextInput from '../../components/text_input_wrapper'; + +
+

Other Examples

+ +

Enter a text value to be retrieved by the LabelValue components below

+ + + +

LabelValue with no props:

+ + `` + +
+ +
+ +

+ LabelValue with number type prop and string value (Will console.log an error + message) +

+ + `` + +
+ +
+ +

+ Enter a number value to be retrieved by the LabelValues below +

+ + + +

+ LabelValue with string type prop and number value (Will show the string value of number with no rounding) +

+ + `` + +
+ +
+
diff --git a/src/templates/LabelValueExamples/TextLabelValues.mdx b/src/templates/LabelValueExamples/TextLabelValues.mdx new file mode 100644 index 00000000..21f18c99 --- /dev/null +++ b/src/templates/LabelValueExamples/TextLabelValues.mdx @@ -0,0 +1,16 @@ +import LabelValue from '../../components/label_value_wrapper' +import TextInput from '../../components/text_input_wrapper' + +
+

Text Value Examples

+

Enter a text value to be retrieved by the LabelValue components below:

+ +

Text LabelValue:

+

The default type is "string" so it does not need to be provided.

+ + `` + +
+ +
+
\ No newline at end of file diff --git a/src/templates/doe_workflow_combustion_appliance_safety_tests.mdx b/src/templates/doe_workflow_combustion_appliance_safety_tests.mdx index 4a88e165..f63ad462 100644 --- a/src/templates/doe_workflow_combustion_appliance_safety_tests.mdx +++ b/src/templates/doe_workflow_combustion_appliance_safety_tests.mdx @@ -201,7 +201,7 @@ --- # Combustion Appliance Safety Testing ## Photo Report - **Assessment Date:**  + diff --git a/src/templates/doe_workflow_heat_pump_ducted.mdx b/src/templates/doe_workflow_heat_pump_ducted.mdx index 8906dc62..98fe89d6 100644 --- a/src/templates/doe_workflow_heat_pump_ducted.mdx +++ b/src/templates/doe_workflow_heat_pump_ducted.mdx @@ -357,7 +357,7 @@ ## Pre-Upgrade Tests -

This heat pump will: {props.data?.heat_pump_purpose}

+ Photo of existing heating appliance’s nameplate -

Cooling appliance exists: {props.data?.no_cooling_appliance?.length === 0 ? "Yes" : "No"}

+ { props.data.comment_ductwork - ?

Ductwork Comments: {props.data.comment_ductwork}

+ ? : null } @@ -410,7 +410,7 @@
{ props.data.comment_pre_upgrade_static_pressure_test - ?

Pre-Upgrade Static Pressure Test Notes: {props.data.comment_pre_upgrade_static_pressure_test}

+ ? : null } @@ -426,11 +426,11 @@ { props.data.comment_pre_upgrade_air_flow_test - ?

Pre-Upgrade Airflow Test Notes: {props.data.comment_pre_upgrade_air_flow_test}

+ ? : null } - ## Duck Leakage Test Results + ## Duct Leakage Test Results Leaky ducts mean the conditioned air doesn't make it to the rooms where the conditioned air is needed. The worse kind of duct leakage is leakage to outside because that means the air you paid to conditioned is leaking outside the house. The duct leakage test measures how leaky @@ -438,7 +438,7 @@ In existing construction it is highly recommended that action be taken to reduce duct leakage if the duct leakage test finds the leakage rate to be greater than 12 CFM25 per 100 ft2 of conditioned floor area. -

Test method used: {props.data?.duct_leakage_test_method}

+ Photo of duct test setup showing ring size and how it is attached to the duct system @@ -449,13 +449,18 @@ { props.data.type_of_duct_leakage_radio - ?

Type Of Duct Leakage Test Performed: {props.data.type_of_duct_leakage_radio}

+ ? + : null } -

CFM25 ={props.data.cfm25_calculator?.cfm25 ? props.data.cfm25_calculator.cfm25 : null}

-

Conditioned Floor Area (ft2) = {props.data.cfm25_calculator?.conditioned_floor_area ? props.data.cfm25_calculator.conditioned_floor_area : null}

-

Duct CFM25 per 100 per ft2 = { props.data.cfm25_calculator?.cfm25 && props.data.cfm25_calculator?.conditioned_floor_area ? ((props.data.cfm25_calculator.cfm25 / props.data.cfm25_calculator.conditioned_floor_area) * 100).toFixed(2) : null }

+ + Conditioned Floor Area (ft2)} + value={props.data.cfm25_calculator?.conditioned_floor_area ? props.data.cfm25_calculator.conditioned_floor_area : null}/> + Duct CFM25 per 100 per ft2} + type={props.data.cfm25_calculator?.cfm25 && props.data.cfm25_calculator?.conditioned_floor_area ? "number" : "string"} + decimalPlaces={2} + value={ props.data.cfm25_calculator?.cfm25 && props.data.cfm25_calculator?.conditioned_floor_area ? ((props.data.cfm25_calculator.cfm25 / props.data.cfm25_calculator.conditioned_floor_area) * 100) : null }/>
@@ -482,17 +487,17 @@ { props.data?.outdoor_unit?.odu_mounting_style - ?

ODU Mounting Style: {props.data.outdoor_unit.odu_mounting_style}

+ ? : null } { props.data.outdoor_unit?.odu_inches_above_ground - ?

ODU Inches Above The Ground (elevated above the snow): {props.data.outdoor_unit.odu_inches_above_ground}

- : null + ? + : null } { props.data.outdoor_unit?.snow_ice_protection - ?

Overhead Snow & Ice Protection: {props.data.outdoor_unit.snow_ice_protection}

+ ? : null } @@ -506,11 +511,8 @@ } - - { props.data.comment_manual_j - && (

Manual J Notes or Comments: {props.data.comment_manual_j}

- ) + && } ## Equipment Selection The selected heat pump's extended heating and cooling performance tables are shown below. These tables were used in concert with the ASHRAE heating @@ -521,17 +523,17 @@ { props.data.aux_heat_lockout_temperature - ?

Aux Heat Lockout Above This Temperature (°F): {props.data.aux_heat_lockout_temperature}

+ ? Aux Heat Lockout Above This Temperature (°F)} value={props.data.aux_heat_lockout_temperature}/> : null } { props.data.compresser_lockout_temperature - ?

Compresser Lockout Below This Temperature (°F): {props.data.compresser_lockout_temperature}

+ ? Compresser Lockout Below This Temperature (°F)} value={props.data.compresser_lockout_temperature}/> : null } { props.data.dual_fuel_switch_over_temperature - ?

Dual Fuel Switch Over Temperature (°F): {props.data.dual_fuel_switch_over_temperature}

+ ? Dual Fuel Switch Over Temperature (°F)} value={props.data.dual_fuel_switch_over_temperature}/> : null } @@ -541,7 +543,7 @@ { props.data.comment_ductwork_concluding_summary - ?

Pre-Installation Comments: {props.data.comment_ductwork_concluding_summary}

+ ? : null } @@ -569,7 +571,7 @@ { props.data.comment_circuit_breaker_notes - ?

Circuit Breaker Notes: {props.data.comment_circuit_breaker_notes}

+ ? : null } @@ -600,8 +602,9 @@ | Ounces of additional refrigerant = {(props.data?.refrigerant_calculator?.ft_line_set_beyond_factory_charge && props.data?.refrigerant_calculator?.oz_per_ft_refrigerant) ? props.data.refrigerant_calculator.ft_line_set_beyond_factory_charge * props.data.refrigerant_calculator.oz_per_ft_refrigerant : null} { props.data.comment_refrigerant_quantity_adjustments_or_weigh_in - ?

Notes About Refrigerant Quantity Adjustments Or Weigh In: {props.data.comment_refrigerant_quantity_adjustments_or_weigh_in}

- : null + ? + : null } @@ -642,7 +645,8 @@ { props.data.comment_about_thermostat_settings - ?

Post-Installation Notes About Thermostat Settings: {props.data.comment_about_thermostat_settings}

+ ? : null } diff --git a/src/templates/doe_workflow_heat_pump_ductless.mdx b/src/templates/doe_workflow_heat_pump_ductless.mdx index e931e318..adcb75f6 100644 --- a/src/templates/doe_workflow_heat_pump_ductless.mdx +++ b/src/templates/doe_workflow_heat_pump_ductless.mdx @@ -284,14 +284,14 @@ ## Pre-Installation -

This heat pump will: {props.data?.heat_pump_purpose}

+ Photo of the proposed heat pump outdoor unit (ODU) installation location { props.data.comment_odu_install_location - ?

Notes: {props.data.comment_odu_install_location}

+ ? : null } @@ -305,7 +305,7 @@ { props.data.comment_idu_install_location - ?

Notes: {props.data.comment_idu_install_location}

+ ? : null } @@ -416,7 +416,7 @@ { props.data.comment_refridgerant_adjustment - ?

Notes About Refridgerant Adjustment: {props.data.comment_refridgerant_adjustment}

+ ? : null } diff --git a/src/templates/doe_workflow_heat_pump_water_heater.mdx b/src/templates/doe_workflow_heat_pump_water_heater.mdx index cc84e8d9..3b74d453 100644 --- a/src/templates/doe_workflow_heat_pump_water_heater.mdx +++ b/src/templates/doe_workflow_heat_pump_water_heater.mdx @@ -251,7 +251,7 @@ { props.data.space_air_volume - ?

Air Volume of the Space: {props.data.space_air_volume} ft3

+ ? {props.data.space_air_volume}3}/> : null } diff --git a/src/templates/ira_doe_workflow_attic_air_sealing_and_insulation.mdx b/src/templates/ira_doe_workflow_attic_air_sealing_and_insulation.mdx index 813781cf..159fe4bc 100644 --- a/src/templates/ira_doe_workflow_attic_air_sealing_and_insulation.mdx +++ b/src/templates/ira_doe_workflow_attic_air_sealing_and_insulation.mdx @@ -27,7 +27,7 @@ | ---------------------------- | | - |

ACH50: {!isNaN(props?.data?.air_leakage_cfm50) && !isNaN(props?.data?.conditioned_volume_ft3) ? ((props?.data?.air_leakage_cfm50 * 60) / props?.data?.conditioned_volume_ft3).toFixed(1): 'N/A'}

+ | Take a photo of the manometer showing CFM50 of air leakage before air sealing and insulation work was performed. @@ -188,8 +188,8 @@ | | | ---------------------------- | - |

Conditioned Volume (ft3): {props?.data?.conditioned_volume_ft3}

- |

ACH50: {!isNaN(props?.data?.postinstall_air_leakage_cfm50) && !isNaN(props?.data?.conditioned_volume_ft3) ? ((props?.data?.postinstall_air_leakage_cfm50 * 60) / props?.data?.conditioned_volume_ft3).toFixed(1): 'N/A'}

+ | + | Take a photo of the manometer showing CFM50 of air leakage before air sealing and insulation work was performed. diff --git a/src/templates/ira_doe_workflow_duct_air_sealing_and_insulation.mdx b/src/templates/ira_doe_workflow_duct_air_sealing_and_insulation.mdx index f930734c..48ae2069 100644 --- a/src/templates/ira_doe_workflow_duct_air_sealing_and_insulation.mdx +++ b/src/templates/ira_doe_workflow_duct_air_sealing_and_insulation.mdx @@ -26,7 +26,7 @@ | ---------------------------- | | - |

Cubic feet per minute (CFM) per 100 sq. ft. of conditioned floor area when the air handler is present: {!isNaN(props.data?.duct_leakage_cfm25) && !isNaN(props.data?.conditioned_floor_area_ft2) ? (props.data.duct_leakage_cfm25 / props.data.conditioned_floor_area_ft2 * 100).toFixed(1) : 'N/A'}

+ |
@@ -98,8 +98,11 @@ -

Conditioned Floor Area (ft2): {props.data?.conditioned_floor_area_ft2}

-

Cubic feet per minute (CFM) per 100 sq. ft. of conditioned floor area when the air handler is present: {!isNaN(props.data?.post_install_duct_leakage_cfm25) && !isNaN(props.data?.conditioned_floor_area_ft2) ? (props.data.post_install_duct_leakage_cfm25 / props.data.conditioned_floor_area_ft2 * 100).toFixed(1) : 'N/A'}

+ +
diff --git a/src/templates/ira_doe_workflow_electric_cooking_appliance.mdx b/src/templates/ira_doe_workflow_electric_cooking_appliance.mdx index b60ecdf0..6fdba8a6 100644 --- a/src/templates/ira_doe_workflow_electric_cooking_appliance.mdx +++ b/src/templates/ira_doe_workflow_electric_cooking_appliance.mdx @@ -1,3 +1,4 @@ + ## Existing Conditions @@ -7,7 +8,7 @@ - Please take a photo of the nameplate of the electric cooking appliance showing the model number and serial number. + Please take a photo of the nameplate of the electric cooking appliance showing the model number and serial number. Please take a picture of the circuit breaker that powers the electric cooling appliance. @@ -37,12 +38,12 @@ ## Installation - Photo of the nameplate of the electric cooking appliance showing the model number and serial number + Photo of the nameplate of the electric cooking appliance showing the model number and serial number Photo of the circuit breaker that powers the electric cooling appliance - + Photo of the gas pipe showing it is off and capped @@ -54,5 +55,6 @@

What is the fuel type of the new stovetop/oven/range?

+
-
\ No newline at end of file + diff --git a/src/templates/ira_doe_workflow_floor_air_sealing_and_insulation.mdx b/src/templates/ira_doe_workflow_floor_air_sealing_and_insulation.mdx index 10cfa512..6a0bfc44 100644 --- a/src/templates/ira_doe_workflow_floor_air_sealing_and_insulation.mdx +++ b/src/templates/ira_doe_workflow_floor_air_sealing_and_insulation.mdx @@ -29,7 +29,7 @@ | ---------------------------- | | - |

ACH50: {!isNaN(props?.data?.air_leakage_cfm50) && !isNaN(props?.data?.conditioned_volume_ft3) ? ((props?.data?.air_leakage_cfm50 * 60) / props?.data?.conditioned_volume_ft3).toFixed(1): 'N/A'}

+ | @@ -164,7 +164,11 @@

Conditioned Volume (ft3): {props.data?.conditioned_volume_ft3}

-

ACH50: {!isNaN(props?.data?.air_leakage_cfm50) && !isNaN(props?.data?.conditioned_volume_ft3) ? ((props?.data?.air_leakage_cfm50 * 60) / props?.data?.conditioned_volume_ft3).toFixed(1) : 'N/A'}

+ Photo of the manometer showing CFM50 of air leakage before air sealing and insulation work was performed diff --git a/src/templates/ira_doe_workflow_foundation_wall_air_sealing_and_insulation.mdx b/src/templates/ira_doe_workflow_foundation_wall_air_sealing_and_insulation.mdx index 512bacdc..215ec4ed 100644 --- a/src/templates/ira_doe_workflow_foundation_wall_air_sealing_and_insulation.mdx +++ b/src/templates/ira_doe_workflow_foundation_wall_air_sealing_and_insulation.mdx @@ -24,8 +24,7 @@ | ---------------------------- | | - |

ACH50: {!isNaN(props?.data?.air_leakage_cfm50) && !isNaN(props?.data?.conditioned_volume_ft3) ? ((props?.data?.air_leakage_cfm50 * 60) / props?.data?.conditioned_volume_ft3).toFixed(1): 'N/A'}

- + | Take a photo of the manometer showing CFM50 of air leakage before air sealing and insulation work was performed. @@ -175,8 +174,11 @@ -

Conditioned Volume (ft3): {props.data?.conditioned_volume_ft3}

-

ACH50: {!isNaN(props?.data?.air_leakage_cfm50) && !isNaN(props?.data?.conditioned_volume_ft3) ? ((props?.data?.air_leakage_cfm50 * 60) / props?.data?.conditioned_volume_ft3).toFixed(1): 'N/A'}

+

Conditioned Volume (ft3): {props.data?.conditioned_volume_ft3}

+ Photo of the manometer showing CFM50 of air leakage before air sealing and insulation work was performed diff --git a/src/templates/ira_doe_workflow_limited_assessment.mdx b/src/templates/ira_doe_workflow_limited_assessment.mdx index 889d38bd..217dc277 100644 --- a/src/templates/ira_doe_workflow_limited_assessment.mdx +++ b/src/templates/ira_doe_workflow_limited_assessment.mdx @@ -195,14 +195,14 @@ {props.project.data_.installer?.name ?     {props.project.data_.installer?.name} : null} {props.project.data_.installer?.name ?
: null} {props.project.data_.installer?.company_name ?     {props.project.data_.installer?.company_name} : null}{props.project.data_.installer?.company_name ?
: null} - **Assessment Date:** + **Assessment For:** {props.data.assessment_for}

{props.data.assessment_for === 'Whole multifamily building' - ? Multifamily Building Conditioned Area (ft2): {props.data.mf_conditioned_floor_area_sq_ft} - : Single-family/unit Conditioned Area (ft2): {props.data.sf_conditioned_floor_area_sq_ft} + ? Multifamily Building Conditioned Area (ft2)} value={props.data.mf_conditioned_floor_area_sq_ft}/> + : Single-family/unit Conditioned Area (ft2)} value={props.data.sf_conditioned_floor_area_sq_ft}/> }

@@ -236,42 +236,41 @@ <>

Heating System 1

-

Fuel and System Type: {props.data.heating_systems[0].fuel_and_system_type}

+ + {props.data.heating_systems[0].fuel_and_system_type === 'ELECTRIC_HEAT_PUMP' - ?

Heating Efficiency (HSPF): {props.data.heating_systems[0].is_efficiency_known === 'YES' ? props.data.heating_systems[0].efficiency_hspf : "NOT_KNOWN"}

- :

Heating Efficiency (AFUE): {props.data.heating_systems[0].is_efficiency_known === 'YES' ? props.data.heating_systems[0].efficiency_afue : "NOT_KNOWN"}

+ ? + : } - -

Percent Conditioned Area Served: {props.data.heating_systems[0].is_percent_conditioned_floor_area_served_known === 'YES' ? props.data.heating_systems[0].percent_conditioned_floor_area_served : "NOT_KNOWN"}

+ } {Number(props.data.num_heating_systems) > 1 && props.data.heating_systems[1] && <>

Heating System 2

- -

Fuel and System Type: {props.data.heating_systems[1].fuel_and_system_type}

+ {props.data.heating_systems[1].fuel_and_system_type === 'ELECTRIC_HEAT_PUMP' - ?

Heating Efficiency (HSPF): {props.data.heating_systems[1].is_efficiency_known === 'YES' ? props.data.heating_systems[1].efficiency_hspf : "NOT_KNOWN"}

- :

Heating Efficiency (AFUE): {props.data.heating_systems[1].is_efficiency_known === 'YES' ? props.data.heating_systems[1].efficiency_afue : "NOT_KNOWN"}

+ ? + : } -

Percent Conditioned Area Served: {props.data.heating_systems[1].is_percent_conditioned_floor_area_served_known === 'YES' ? props.data.heating_systems[1].percent_conditioned_floor_area_served : "NOT_KNOWN"}

+ } {Number(props.data.num_heating_systems) > 2 && props.data.heating_systems[2] && <>

Heating System 3

-

Fuel and System Type: {props.data.heating_systems[2].fuel_and_system_type}

+ {props.data.heating_systems[2].fuel_and_system_type === 'ELECTRIC_HEAT_PUMP' - ?

Heating Efficiency (HSPF): {props.data.heating_systems[2].is_efficiency_known === 'YES' ? props.data.heating_systems[2].efficiency_hspf : "NOT_KNOWN"}

- :

Heating Efficiency (AFUE): {props.data.heating_systems[2].is_efficiency_known === 'YES' ? props.data.heating_systems[2].efficiency_afue : "NOT_KNOWN"}

+ ? + : } -

Percent Conditioned Area Served: {props.data.heating_systems[2].is_percent_conditioned_floor_area_served_known === 'YES' ? props.data.heating_systems[2].percent_conditioned_floor_area_served : "NOT_KNOWN"}

+ } @@ -282,28 +281,22 @@ {Number(props.data.num_cooling_systems) > 0 && props.data.cooling_systems[0] && <>

Cooling System 1

- -

Cooling Efficiency (SEER): {props.data.cooling_systems[0].is_efficiency_known === 'YES' ? props.data.cooling_systems[0].efficiency_seer : "NOT_KNOWN"}

- -

Percent Conditioned Area Served: {props.data.cooling_systems[0].is_percent_conditioned_floor_area_served_known === 'YES' ? props.data.cooling_systems[0].percent_conditioned_floor_area_served : "NOT_KNOWN"}

+ + } {Number(props.data.num_cooling_systems) > 1 && props.data.cooling_systems[1] && <>

Cooling System 2

- -

Cooling Efficiency (SEER): {props.data.cooling_systems[1].is_efficiency_known === 'YES' ? props.data.cooling_systems[1].efficiency_seer : "NOT_KNOWN"}

- -

Percent Conditioned Area Served: {props.data.cooling_systems[1].is_percent_conditioned_floor_area_served_known === 'YES' ? props.data.cooling_systems[1].percent_conditioned_floor_area_served : "NOT_KNOWN"}

+ + } {Number(props.data.num_cooling_systems) > 2 && props.data.cooling_systems[2] && <>

Cooling System 3

- -

Cooling Efficiency (SEER): {props.data.cooling_systems[2].is_efficiency_known === 'YES' ? props.data.cooling_systems[2].efficiency_seer : "NOT_KNOWN"}

- -

Percent Conditioned Area Served: {props.data.cooling_systems[2].is_percent_conditioned_floor_area_served_known === 'YES' ? props.data.cooling_systems[2].percent_conditioned_floor_area_served : "NOT_KNOWN"}

+ + } diff --git a/src/templates/ira_doe_workflow_slap_foundation_exterior_sealing_and_insulation.mdx b/src/templates/ira_doe_workflow_slap_foundation_exterior_sealing_and_insulation.mdx index a7cedd0c..55a68836 100644 --- a/src/templates/ira_doe_workflow_slap_foundation_exterior_sealing_and_insulation.mdx +++ b/src/templates/ira_doe_workflow_slap_foundation_exterior_sealing_and_insulation.mdx @@ -19,7 +19,7 @@ | ---------------------------- | | - |

ACH50: {!isNaN(props?.data?.air_leakage_cfm50) && !isNaN(props?.data?.conditioned_volume_ft3) ? ((props?.data?.air_leakage_cfm50 * 60) / props?.data?.conditioned_volume_ft3).toFixed(1): 'N/A'}

+ | Take a photo of the manometer showing CFM50 of air leakage before air sealing and insulation work was performed. @@ -160,7 +160,7 @@

What is the starting air leakage rate for the home before modification? { props.data?.air_leakage_rate == 'CFM at 50Pa' ? ":" + props.data?.air_leakage_cfm50+ " " : null }{ props.data?.air_leakage_rate}

Conditioned Volume (ft3): {props.data?.conditioned_volume_ft3}

-

ACH50: {!isNaN(props?.data?.air_leakage_cfm50) && !isNaN(props?.data?.conditioned_volume_ft3) ? ((props?.data?.air_leakage_cfm50 * 60) / props?.data?.conditioned_volume_ft3).toFixed(1): 'N/A'}

+ Photo of the manometer showing CFM50 of air leakage before air sealing and insulation work was performed diff --git a/src/templates/ira_doe_workflow_wall_air_sealing_and_insulation_dry_fill.mdx b/src/templates/ira_doe_workflow_wall_air_sealing_and_insulation_dry_fill.mdx index 9305e100..875533ee 100644 --- a/src/templates/ira_doe_workflow_wall_air_sealing_and_insulation_dry_fill.mdx +++ b/src/templates/ira_doe_workflow_wall_air_sealing_and_insulation_dry_fill.mdx @@ -25,7 +25,7 @@ | ---------------------------- | | - |

ACH50: {!isNaN(props?.data?.air_leakage_cfm50) && !isNaN(props?.data?.conditioned_volume_ft3) ? ((props?.data?.air_leakage_cfm50 * 60) / props?.data?.conditioned_volume_ft3).toFixed(1): 'N/A'}

+ | Take a photo of the manometer showing CFM50 of air leakage before air sealing and insulation work was performed. @@ -222,7 +222,7 @@

What is the starting air leakage rate for the home before modification? { props.data?.wall_air_leakage_rate == 'CFM at 50Pa' ? props.data?.air_leakage_cfm50 +" " : null } { props.data?.wall_air_leakage_rate}

Conditioned Volume (ft3): {props.data?.conditioned_volume_ft3}

-

ACH50: {!isNaN(props?.data?.air_leakage_cfm50) && !isNaN(props?.data?.conditioned_volume_ft3) ? ((props?.data?.air_leakage_cfm50 * 60) / props?.data?.conditioned_volume_ft3).toFixed(1): 'N/A'}

+ Photo of the manometer showing CFM50 of air leakage before air sealing and insulation work was performed diff --git a/src/templates/playground.mdx b/src/templates/playground.mdx index 575a6908..5bb2178f 100644 --- a/src/templates/playground.mdx +++ b/src/templates/playground.mdx @@ -1,6 +1,35 @@ +import TextLabelValues from './LabelValueExamples/TextLabelValues.mdx' +import NumberLabelValues from './LabelValueExamples/NumberLabelValues.mdx' +import OtherExamples from './LabelValueExamples/OtherExamples.mdx' +import DateLabelValues from './LabelValueExamples/DateLabelValues.mdx' +import LabelValueExamplesStyles from './LabelValueExamples/LabelValueExamplesStyles.css' -# Playground + + + + - + -Grade: {props.doc.student.grade} diff --git a/src/templates/reusable/project_info_report.mdx b/src/templates/reusable/project_info_report.mdx index 87894d12..defc0694 100644 --- a/src/templates/reusable/project_info_report.mdx +++ b/src/templates/reusable/project_info_report.mdx @@ -17,7 +17,9 @@

<> - Installation Date:  + { /* This will be removed in ticket #249 */} + diff --git a/src/templates/templates_config.ts b/src/templates/templates_config.ts index 334003e9..40501e31 100644 --- a/src/templates/templates_config.ts +++ b/src/templates/templates_config.ts @@ -19,7 +19,7 @@ import DOEWorkflowWallAirSealingAndInsulation from './ira_doe_workflow_wall_air_ import DOEWorkflowAtticAirSealingAndInsulation from './ira_doe_workflow_attic_air_sealing_and_insulation.mdx' import IRADOEWorkflowLimitedAssessment from './ira_doe_workflow_limited_assessment.mdx' import DOECombustionApplianceSafetyTests from './doe_workflow_combustion_appliance_safety_tests.mdx' - +import Playground from './playground.mdx' import { MDXProps } from 'mdx/types' interface TemplatesConfig { @@ -117,6 +117,10 @@ const templatesConfig: TemplatesConfig = { title: 'IRA Limited Assessment', template: IRADOEWorkflowLimitedAssessment, }, + playground: { + title: 'Playground', + template: Playground, + }, } // Assuming TemplatesConfig is defined somewhere as a type or interface