diff --git a/backend/lcfs/web/api/compliance_report/schema.py b/backend/lcfs/web/api/compliance_report/schema.py
index 34696dee2..e839bee11 100644
--- a/backend/lcfs/web/api/compliance_report/schema.py
+++ b/backend/lcfs/web/api/compliance_report/schema.py
@@ -40,7 +40,6 @@ class CompliancePeriodSchema(BaseSchema):
display_order: Optional[int] = None
-
class SummarySchema(BaseSchema):
summary_id: int
is_locked: bool
@@ -154,6 +153,7 @@ class ComplianceReportBaseSchema(BaseSchema):
update_date: Optional[datetime] = None
history: Optional[List[ComplianceReportHistorySchema]] = None
has_supplemental: bool
+ legacy_id: Optional[int] = None
class ChainedComplianceReportSchema(BaseSchema):
diff --git a/frontend/public/config/config.js b/frontend/public/config/config.js
index a53256ce3..c3885613c 100644
--- a/frontend/public/config/config.js
+++ b/frontend/public/config/config.js
@@ -1,5 +1,6 @@
export const config = {
api_base: 'http://localhost:8000/api',
+ tfrs_base: 'http://localhost:3001',
keycloak: {
REALM: 'standard',
CLIENT_ID: 'low-carbon-fuel-standard-5147',
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 2e6c33946..907ce057a 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -35,6 +35,8 @@ import { AddEditFuelExports } from './views/FuelExports/AddEditFuelExports'
import { AddEditAllocationAgreements } from './views/AllocationAgreements/AddEditAllocationAgreements'
import { logout } from '@/utils/keycloak.js'
import { CompareReports } from '@/views/CompareReports/CompareReports'
+import { ViewLegacyComplianceReport } from '@/views/ComplianceReports/ViewLegacyComplianceReport.jsx'
+import { ViewComplianceReportBrancher } from '@/views/ComplianceReports/ViewComplianceReportBrancher.jsx'
const router = createBrowserRouter([
{
@@ -196,7 +198,7 @@ const router = createBrowserRouter([
},
{
path: ROUTES.REPORTS_VIEW,
- element: ,
+ element: ,
handle: { title: '' }
},
{
diff --git a/frontend/src/assets/locales/en/reports.json b/frontend/src/assets/locales/en/reports.json
index 597eab678..91ced911b 100644
--- a/frontend/src/assets/locales/en/reports.json
+++ b/frontend/src/assets/locales/en/reports.json
@@ -158,5 +158,6 @@
"totalValue": "Total Value"
},
"summaryLoadingMsg": "Loading compliance report summary...",
- "noSigningAuthorityTooltip": "Signing authority role required."
+ "noSigningAuthorityTooltip": "Signing authority role required.",
+ "viewLegacyBtn": "View Full Historical Report in TFRS"
}
diff --git a/frontend/src/constants/config.js b/frontend/src/constants/config.js
index 8dfec5e6c..3fc0c851f 100644
--- a/frontend/src/constants/config.js
+++ b/frontend/src/constants/config.js
@@ -39,6 +39,7 @@ export const FEATURE_FLAGS = {
export const CONFIG = {
API_BASE: getApiBaseUrl(),
+ TFRS_BASE: window.lcfs_config.tfrs_base,
KEYCLOAK: {
REALM: window.lcfs_config.keycloak.REALM ?? 'standard',
CLIENT_ID:
diff --git a/frontend/src/constants/routes/routes.js b/frontend/src/constants/routes/routes.js
index 78c3978a8..040be0f9b 100644
--- a/frontend/src/constants/routes/routes.js
+++ b/frontend/src/constants/routes/routes.js
@@ -36,13 +36,13 @@ export const ORGANIZATIONS_EDITUSER = `${ORGANIZATIONS_VIEWUSER}/edit-user`
export const REPORTS = '/compliance-reporting'
export const REPORTS_VIEW = `${REPORTS}/:compliancePeriod/:complianceReportId`
-export const REPORTS_COMPARE = `/compare-reporting`
export const REPORTS_ADD_SUPPLY_OF_FUEL = `${REPORTS_VIEW}/supply-of-fuel`
export const REPORTS_ADD_FINAL_SUPPLY_EQUIPMENTS = `${REPORTS_VIEW}/final-supply-equipments`
export const REPORTS_ADD_ALLOCATION_AGREEMENTS = `${REPORTS_VIEW}/allocation-agreements`
export const REPORTS_ADD_NOTIONAL_TRANSFERS = `${REPORTS_VIEW}/notional-transfers`
export const REPORTS_ADD_OTHER_USE_FUELS = `${REPORTS_VIEW}/fuels-other-use`
export const REPORTS_ADD_FUEL_EXPORTS = `${REPORTS_VIEW}/fuel-exports`
+export const REPORTS_COMPARE = '/compare-reporting'
export const NOTIFICATIONS = '/notifications'
export const NOTIFICATIONS_SETTINGS = `${NOTIFICATIONS}/configure`
diff --git a/frontend/src/views/ComplianceReports/ComplianceReports.jsx b/frontend/src/views/ComplianceReports/ComplianceReports.jsx
index 973b6f46b..504d42990 100644
--- a/frontend/src/views/ComplianceReports/ComplianceReports.jsx
+++ b/frontend/src/views/ComplianceReports/ComplianceReports.jsx
@@ -4,20 +4,20 @@ import BCBox from '@/components/BCBox'
import BCAlert from '@/components/BCAlert'
import BCDataGridServer from '@/components/BCDataGrid/BCDataGridServer'
// react components
-import { useEffect, useMemo, useRef, useState, useCallback } from 'react'
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useLocation, useNavigate } from 'react-router-dom'
// Services
import { Role } from '@/components/Role'
// constants
import { roles } from '@/constants/roles'
-import { ROUTES, apiRoutes } from '@/constants/routes'
+import { apiRoutes, ROUTES } from '@/constants/routes'
import { COMPLIANCE_REPORT_STATUSES } from '@/constants/statuses'
// hooks
import { useCurrentUser } from '@/hooks/useCurrentUser'
import { useCreateComplianceReport } from '@/hooks/useComplianceReports'
// internal components
-import { reportsColDefs, defaultSortModel } from './components/_schema'
+import { defaultSortModel, reportsColDefs } from './components/_schema'
import { NewComplianceReportButton } from './components/NewComplianceReportButton'
import BCTypography from '@/components/BCTypography'
@@ -44,15 +44,13 @@ export const ComplianceReports = () => {
(params) => params.data.complianceReportId.toString(),
[]
)
- // eslint-disable-next-line react-hooks/exhaustive-deps
const handleRowClicked = useCallback(
({ data }) => {
- navigate(
- ROUTES.REPORTS_VIEW.replace(
- ':compliancePeriod',
- data.compliancePeriod.description
- ).replace(':complianceReportId', data.complianceReportId)
- )
+ const mappedRoute = ROUTES.REPORTS_VIEW.replace(
+ ':compliancePeriod',
+ data.compliancePeriod.description
+ ).replace(':complianceReportId', data.complianceReportId)
+ navigate(mappedRoute)
},
[navigate]
)
diff --git a/frontend/src/views/ComplianceReports/EditViewComplianceReport.jsx b/frontend/src/views/ComplianceReports/EditViewComplianceReport.jsx
index 30b2925f0..dc6b075b1 100644
--- a/frontend/src/views/ComplianceReports/EditViewComplianceReport.jsx
+++ b/frontend/src/views/ComplianceReports/EditViewComplianceReport.jsx
@@ -18,10 +18,7 @@ import { useTranslation } from 'react-i18next'
import { useCurrentUser } from '@/hooks/useCurrentUser'
import { useOrganization } from '@/hooks/useOrganization'
import { Introduction } from './components/Introduction'
-import {
- useGetComplianceReport,
- useUpdateComplianceReport
-} from '@/hooks/useComplianceReports'
+import { useUpdateComplianceReport } from '@/hooks/useComplianceReports'
import ComplianceReportSummary from './components/ComplianceReportSummary'
import ReportDetails from './components/ReportDetails'
import { buttonClusterConfigFn } from './buttonConfigs'
@@ -35,7 +32,7 @@ const iconStyle = {
height: '2rem',
color: colors.white.main
}
-export const EditViewComplianceReport = () => {
+export const EditViewComplianceReport = ({ reportData, isError, error }) => {
const { t } = useTranslation(['common', 'report'])
const location = useLocation()
const [modalData, setModalData] = useState(null)
@@ -83,15 +80,6 @@ export const EditViewComplianceReport = () => {
hasRoles
} = useCurrentUser()
const isGovernmentUser = currentUser?.isGovernmentUser
- const {
- data: reportData,
- isLoading: isReportLoading,
- isError,
- error
- } = useGetComplianceReport(
- currentUser?.organization?.organizationId,
- complianceReportId
- )
const currentStatus = reportData?.report.currentStatus?.status
const { data: orgData, isLoading } = useOrganization(
@@ -158,7 +146,7 @@ export const EditViewComplianceReport = () => {
}
}, [location.state, isError, error])
- if (isLoading || isReportLoading || isCurrentUserLoading) {
+ if (isLoading || isCurrentUserLoading) {
return
}
diff --git a/frontend/src/views/ComplianceReports/ViewComplianceReportBrancher.jsx b/frontend/src/views/ComplianceReports/ViewComplianceReportBrancher.jsx
new file mode 100644
index 000000000..de4b97f75
--- /dev/null
+++ b/frontend/src/views/ComplianceReports/ViewComplianceReportBrancher.jsx
@@ -0,0 +1,40 @@
+import { useGetComplianceReport } from '@/hooks/useComplianceReports.js'
+import { useCurrentUser } from '@/hooks/useCurrentUser.js'
+import Loading from '@/components/Loading.jsx'
+import { ViewLegacyComplianceReport } from '@/views/ComplianceReports/ViewLegacyComplianceReport.jsx'
+import { useParams } from 'react-router-dom'
+import { EditViewComplianceReport } from '@/views/ComplianceReports/EditViewComplianceReport.jsx'
+
+export const ViewComplianceReportBrancher = () => {
+ const { complianceReportId } = useParams()
+ const { data: currentUser, isLoading: isCurrentUserLoading } =
+ useCurrentUser()
+
+ const {
+ data: reportData,
+ isLoading: isReportLoading,
+ isError,
+ error
+ } = useGetComplianceReport(
+ currentUser?.organization?.organizationId,
+ complianceReportId
+ )
+
+ if (isReportLoading || isCurrentUserLoading) {
+ return
+ }
+
+ return reportData.report.legacyId ? (
+
+ ) : (
+
+ )
+}
diff --git a/frontend/src/views/ComplianceReports/ViewLegacyComplianceReport.jsx b/frontend/src/views/ComplianceReports/ViewLegacyComplianceReport.jsx
new file mode 100644
index 000000000..163591800
--- /dev/null
+++ b/frontend/src/views/ComplianceReports/ViewLegacyComplianceReport.jsx
@@ -0,0 +1,143 @@
+import { useCallback, useEffect, useRef, useState } from 'react'
+import { FloatingAlert } from '@/components/BCAlert'
+import BCBox from '@/components/BCBox'
+import BCModal from '@/components/BCModal'
+import Loading from '@/components/Loading'
+import { Fab, Stack, Tooltip } from '@mui/material'
+import BCTypography from '@/components/BCTypography'
+import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'
+import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
+import colors from '@/themes/base/colors.js'
+import { useTranslation } from 'react-i18next'
+import { useCurrentUser } from '@/hooks/useCurrentUser'
+import { useOrganization } from '@/hooks/useOrganization'
+import { LegacyAssessmentCard } from '@/views/ComplianceReports/components/LegacyAssessmentCard.jsx'
+
+const iconStyle = {
+ width: '2rem',
+ height: '2rem',
+ color: colors.white.main
+}
+export const ViewLegacyComplianceReport = ({ reportData, error, isError }) => {
+ const { t } = useTranslation(['common', 'report'])
+ const [modalData, setModalData] = useState(null)
+ const alertRef = useRef()
+
+ const [isScrollingUp, setIsScrollingUp] = useState(false)
+ const [lastScrollTop, setLastScrollTop] = useState(0)
+
+ const scrollToTopOrBottom = () => {
+ if (isScrollingUp) {
+ window.scrollTo({
+ top: 0,
+ behavior: 'smooth'
+ })
+ } else {
+ window.scrollTo({
+ top: document.documentElement.scrollHeight,
+ behavior: 'smooth'
+ })
+ }
+ }
+
+ const handleScroll = useCallback(() => {
+ const scrollTop = window.pageYOffset || document.documentElement.scrollTop
+ setIsScrollingUp(scrollTop < lastScrollTop || scrollTop === 0)
+ setLastScrollTop(scrollTop)
+ }, [lastScrollTop])
+
+ useEffect(() => {
+ window.addEventListener('scroll', handleScroll)
+ return () => window.removeEventListener('scroll', handleScroll)
+ }, [handleScroll])
+
+ const { data: currentUser, isLoading: isCurrentUserLoading } =
+ useCurrentUser()
+ const isGovernmentUser = currentUser?.isGovernmentUser
+
+ const currentStatus = reportData.report.currentStatus?.status
+ const { data: orgData, isLoading } = useOrganization(
+ reportData.report.organizationId
+ )
+
+ if (isLoading || isCurrentUserLoading) {
+ return
+ }
+
+ if (isError) {
+ return (
+ <>
+
+ {t('report:errorRetrieving')}
+ >
+ )
+ }
+
+ return (
+ <>
+
+
+ setModalData(null)}
+ data={modalData}
+ />
+
+
+ {reportData?.report.compliancePeriod.description}
+ {t('report:complianceReport')} -
+ {reportData?.report.nickname}
+
+
+ Status: {currentStatus}
+
+
+
+
+
+
+
+ {isScrollingUp ? (
+
+ ) : (
+
+ )}
+
+
+
+ >
+ )
+}
diff --git a/frontend/src/views/ComplianceReports/__tests__/EditViewComplianceReports.test.jsx b/frontend/src/views/ComplianceReports/__tests__/EditViewComplianceReports.test.jsx
index cb50dbee6..a3e38b0df 100644
--- a/frontend/src/views/ComplianceReports/__tests__/EditViewComplianceReports.test.jsx
+++ b/frontend/src/views/ComplianceReports/__tests__/EditViewComplianceReports.test.jsx
@@ -2,9 +2,9 @@ import React from 'react'
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { EditViewComplianceReport } from '../EditViewComplianceReport'
-import * as useComplianceReportsHook from '@/hooks/useComplianceReports'
import * as useCurrentUserHook from '@/hooks/useCurrentUser'
import * as useOrganizationHook from '@/hooks/useOrganization'
+import * as useComplianceReportsHook from '@/hooks/useComplianceReports'
import { COMPLIANCE_REPORT_STATUSES } from '@/constants/statuses'
import { wrapper } from '@/tests/utils/wrapper'
@@ -89,17 +89,17 @@ describe('EditViewComplianceReport', () => {
isLoading: false,
hasRoles: mockHasRoles
},
- complianceReport: {
- data: {
- report: {
- organizationId: '123',
- currentStatus: { status: COMPLIANCE_REPORT_STATUSES.DRAFT }
- },
- chain: []
+ reportData: {
+ report: {
+ organizationId: '123',
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.DRAFT },
+ history: [],
+ nickname: 'Test Report'
},
- isLoading: false,
- isError: false
+ chain: []
},
+ isError: false,
+ error: null,
organization: {
data: {
name: 'Test Org',
@@ -117,10 +117,6 @@ describe('EditViewComplianceReport', () => {
}
},
isLoading: false
- },
- createSupplementalReport: {
- mutate: vi.fn(),
- isLoading: false
}
}
@@ -131,9 +127,6 @@ describe('EditViewComplianceReport', () => {
vi.mocked(useCurrentUserHook.useCurrentUser).mockReturnValue(
mocks.currentUser
)
- vi.mocked(useComplianceReportsHook.useGetComplianceReport).mockReturnValue(
- mocks.complianceReport
- )
vi.mocked(useOrganizationHook.useOrganization).mockReturnValue(
mocks.organization
)
@@ -142,23 +135,43 @@ describe('EditViewComplianceReport', () => {
).mockReturnValue({ mutate: vi.fn() })
vi.mocked(
useComplianceReportsHook.useCreateSupplementalReport
- ).mockReturnValue(mocks.createSupplementalReport)
+ ).mockReturnValue({
+ mutate: vi.fn(),
+ isLoading: false
+ })
+
+ return mocks
}
beforeEach(() => {
vi.resetAllMocks()
- setupMocks()
})
it('renders the component', async () => {
- render(, { wrapper })
+ const mocks = setupMocks()
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(screen.getByText(/2023.*complianceReport/i)).toBeInTheDocument()
})
})
it('renders report components', async () => {
- render(, { wrapper })
+ const mocks = setupMocks()
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(screen.getByText('Report Details')).toBeInTheDocument()
expect(screen.getByText('Compliance Report Summary')).toBeInTheDocument()
@@ -167,44 +180,61 @@ describe('EditViewComplianceReport', () => {
})
it('displays an alert message when location state has a message', async () => {
- setupMocks({
+ const mocks = setupMocks({
useLocation: { state: { message: 'Test alert', severity: 'success' } }
})
- render(, { wrapper })
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(screen.getByText('Test alert')).toBeInTheDocument()
})
})
it('displays an error message when there is an error fetching the report', async () => {
- setupMocks({
- complianceReport: {
- isError: true,
- error: { message: 'Error fetching report' }
- }
+ const mocks = setupMocks({
+ isError: true,
+ error: { message: 'Error fetching report' }
})
- render(, { wrapper })
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(screen.getByText('Error fetching report')).toBeInTheDocument()
})
})
it('displays the correct buttons for Submitted status with Analyst role', async () => {
- setupMocks({
- complianceReport: {
- data: {
- report: {
- currentStatus: { status: COMPLIANCE_REPORT_STATUSES.SUBMITTED }
- },
- chain: []
- }
+ const mocks = setupMocks({
+ reportData: {
+ report: {
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.SUBMITTED }
+ },
+ chain: []
},
currentUser: {
data: { isGovernmentUser: true },
hasRoles: (role) => role === 'Analyst'
}
})
- render(, { wrapper })
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(
screen.getByText('report:actionBtns.recommendReportAnalystBtn')
@@ -213,23 +243,28 @@ describe('EditViewComplianceReport', () => {
})
it('displays the correct buttons for Recommended by Analyst status with Compliance Manager role', async () => {
- setupMocks({
- complianceReport: {
- data: {
- report: {
- currentStatus: {
- status: COMPLIANCE_REPORT_STATUSES.RECOMMENDED_BY_ANALYST
- }
- },
- chain: []
- }
+ const mocks = setupMocks({
+ reportData: {
+ report: {
+ currentStatus: {
+ status: COMPLIANCE_REPORT_STATUSES.RECOMMENDED_BY_ANALYST
+ }
+ },
+ chain: []
},
currentUser: {
data: { isGovernmentUser: true },
hasRoles: (role) => role === 'Compliance Manager'
}
})
- render(, { wrapper })
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(
screen.getByText('report:actionBtns.recommendReportManagerBtn')
@@ -241,23 +276,28 @@ describe('EditViewComplianceReport', () => {
})
it('displays the correct buttons for Recommended by Manager status with Director role', async () => {
- setupMocks({
- complianceReport: {
- data: {
- report: {
- currentStatus: {
- status: COMPLIANCE_REPORT_STATUSES.RECOMMENDED_BY_MANAGER
- }
- },
- chain: []
- }
+ const mocks = setupMocks({
+ reportData: {
+ report: {
+ currentStatus: {
+ status: COMPLIANCE_REPORT_STATUSES.RECOMMENDED_BY_MANAGER
+ }
+ },
+ chain: []
},
currentUser: {
data: { isGovernmentUser: true },
hasRoles: (role) => role === 'Director'
}
})
- render(, { wrapper })
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(
screen.getByText('report:actionBtns.assessReportBtn')
@@ -269,21 +309,26 @@ describe('EditViewComplianceReport', () => {
})
it('displays the correct buttons for Assessed status with Analyst role', async () => {
- setupMocks({
- complianceReport: {
- data: {
- report: {
- currentStatus: { status: COMPLIANCE_REPORT_STATUSES.ASSESSED }
- },
- chain: []
- }
+ const mocks = setupMocks({
+ reportData: {
+ report: {
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.ASSESSED }
+ },
+ chain: []
},
currentUser: {
data: { isGovernmentUser: true },
hasRoles: (role) => role === 'Analyst'
}
})
- render(, { wrapper })
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(
screen.getByText('report:actionBtns.reAssessReportBtn')
@@ -292,18 +337,23 @@ describe('EditViewComplianceReport', () => {
})
it('does not display action buttons for non-government users on submitted reports', async () => {
- setupMocks({
- complianceReport: {
- data: {
- report: {
- currentStatus: { status: COMPLIANCE_REPORT_STATUSES.SUBMITTED }
- },
- chain: []
- }
+ const mocks = setupMocks({
+ reportData: {
+ report: {
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.SUBMITTED }
+ },
+ chain: []
},
currentUser: { data: { isGovernmentUser: false }, hasRoles: () => false }
})
- render(, { wrapper })
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(
screen.queryByText('report:actionBtns.recommendReportAnalystBtn')
@@ -321,20 +371,34 @@ describe('EditViewComplianceReport', () => {
})
it('displays internal comments section for government users', async () => {
- setupMocks({
+ const mocks = setupMocks({
currentUser: { data: { isGovernmentUser: true }, hasRoles: () => true }
})
- render(, { wrapper })
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(screen.getByText('report:internalComments')).toBeInTheDocument()
})
})
it('does not display internal comments section for non-government users', async () => {
- setupMocks({
+ const mocks = setupMocks({
currentUser: { data: { isGovernmentUser: false }, hasRoles: () => false }
})
- render(, { wrapper })
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(
screen.queryByText('report:internalComments')
@@ -343,17 +407,22 @@ describe('EditViewComplianceReport', () => {
})
it('displays ActivityListCard for Draft status', async () => {
- setupMocks({
- complianceReport: {
- data: {
- report: {
- currentStatus: { status: COMPLIANCE_REPORT_STATUSES.DRAFT }
- },
- chain: []
- }
+ const mocks = setupMocks({
+ reportData: {
+ report: {
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.DRAFT }
+ },
+ chain: []
}
})
- render(, { wrapper })
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(screen.getByText('Activity Links List')).toBeInTheDocument()
})
@@ -373,8 +442,8 @@ describe('EditViewComplianceReport', () => {
}
]
- vi.mocked(useComplianceReportsHook.useGetComplianceReport).mockReturnValue({
- data: {
+ const mocks = setupMocks({
+ reportData: {
report: {
currentStatus: { status: COMPLIANCE_REPORT_STATUSES.ASSESSED },
history: historyMock
@@ -389,12 +458,17 @@ describe('EditViewComplianceReport', () => {
currentStatus: { status: COMPLIANCE_REPORT_STATUSES.SUBMITTED }
}
]
- },
- isLoading: false,
- isError: false
+ }
})
- render(, { wrapper })
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
expect(screen.getByText('report:assessment')).toBeInTheDocument()
expect(screen.getByText('report:reportHistory')).toBeInTheDocument()
@@ -405,7 +479,15 @@ describe('EditViewComplianceReport', () => {
})
it('displays scroll-to-top button when scrolling down', async () => {
- render(, { wrapper })
+ const mocks = setupMocks()
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
fireEvent.scroll(window, { target: { pageYOffset: 100 } })
expect(screen.getByLabelText('scroll to bottom')).toBeInTheDocument()
@@ -413,7 +495,15 @@ describe('EditViewComplianceReport', () => {
})
it('displays scroll-to-bottom button when at the top of the page', async () => {
- render(, { wrapper })
+ const mocks = setupMocks()
+ render(
+ ,
+ { wrapper }
+ )
await waitFor(() => {
fireEvent.scroll(window, { target: { pageYOffset: 0 } })
expect(screen.getByLabelText('scroll to top')).toBeInTheDocument()
diff --git a/frontend/src/views/ComplianceReports/__tests__/HistoryCard.test.jsx b/frontend/src/views/ComplianceReports/__tests__/HistoryCard.test.jsx
new file mode 100644
index 000000000..defa965c7
--- /dev/null
+++ b/frontend/src/views/ComplianceReports/__tests__/HistoryCard.test.jsx
@@ -0,0 +1,171 @@
+import React from 'react'
+import { render, screen, waitFor } from '@testing-library/react'
+import { describe, it, expect, vi, beforeEach } from 'vitest'
+import { COMPLIANCE_REPORT_STATUSES } from '@/constants/statuses'
+import { HistoryCard } from '@/views/ComplianceReports/components/HistoryCard.jsx'
+import { wrapper } from '@/tests/utils/wrapper.jsx'
+
+import * as useCurrentUserHook from '@/hooks/useCurrentUser'
+
+// Mock useCurrentUser
+vi.mock('@/hooks/useCurrentUser', () => ({
+ useCurrentUser: vi.fn(() => ({
+ data: { isGovernmentUser: false },
+ isLoading: false
+ }))
+}))
+
+// Mock translation
+vi.mock('react-i18next', () => ({
+ useTranslation: () => ({
+ t: (key, opts) => {
+ if (opts && opts.createDate && opts.firstName && opts.lastName) {
+ return `${key}: ${opts.firstName} ${opts.lastName} - ${opts.createDate}`
+ }
+ return key
+ }
+ })
+}))
+
+// Mock timezoneFormatter
+vi.mock('@/utils/formatters', () => ({
+ timezoneFormatter: vi.fn(({ value }) => `formatted-${value}`)
+}))
+
+describe('HistoryCard', () => {
+ const defaultReport = {
+ version: 0,
+ compliancePeriod: { description: '2024' },
+ nickname: 'My Nickname',
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.DRAFT },
+ history: []
+ }
+
+ const renderComponent = (overrides = {}) => {
+ return render(, {
+ wrapper
+ })
+ }
+
+ beforeEach(() => {
+ vi.clearAllMocks()
+ })
+
+ it('renders without history', async () => {
+ renderComponent()
+ // Only the accordion header should be present
+ await waitFor(() => {
+ expect(screen.queryByRole('listitem')).not.toBeInTheDocument()
+ })
+ })
+
+ it('displays compliancePeriod.description and current status if version=0', async () => {
+ renderComponent({
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.SUBMITTED }
+ })
+ await waitFor(() => {
+ expect(
+ screen.getByText(/2024 Compliance Report: SUBMITTED/i)
+ ).toBeInTheDocument()
+ })
+ })
+
+ it('displays nickname and current status if version > 0', async () => {
+ renderComponent({
+ version: 1,
+ nickname: 'My Cool Nickname',
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.SUBMITTED }
+ })
+ await waitFor(() => {
+ expect(
+ screen.getByText(/My Cool Nickname: SUBMITTED/i)
+ ).toBeInTheDocument()
+ })
+ })
+
+ it('sorts history in descending order by createDate and filters out DRAFT', async () => {
+ const history = [
+ {
+ status: { status: COMPLIANCE_REPORT_STATUSES.DRAFT },
+ createDate: '2024-10-02',
+ userProfile: { firstName: 'Draft', lastName: 'User' }
+ },
+ {
+ status: { status: COMPLIANCE_REPORT_STATUSES.SUBMITTED },
+ createDate: '2024-10-01T10:00:00Z',
+ userProfile: { firstName: 'John', lastName: 'Doe' }
+ },
+ {
+ status: { status: COMPLIANCE_REPORT_STATUSES.RECOMMENDED_BY_ANALYST },
+ createDate: '2024-10-03T15:00:00Z',
+ userProfile: { firstName: 'Jane', lastName: 'Smith' }
+ }
+ ]
+ renderComponent({
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.SUBMITTED },
+ history
+ })
+
+ // SUBMITTED first because 2024-10-03 is later than 2024-10-01
+ await waitFor(() => {
+ const items = screen.getAllByTestId('list-item')
+ expect(items.length).toBe(2) // DRAFT is filtered out
+ // The first item should be RECOMMENDED_BY_ANALYST (2024-10-03)
+ expect(items[0].textContent).toContain(
+ 'report:complianceReportHistory.Recommended by analyst: Jane Smith'
+ )
+ // The second item should be SUBMITTED (2024-10-01)
+ expect(items[1].textContent).toContain(
+ 'report:complianceReportHistory.Submitted: John Doe'
+ )
+ })
+ })
+
+ it('replaces ASSESSED with AssessedBy if user is not government', async () => {
+ const history = [
+ {
+ status: { status: COMPLIANCE_REPORT_STATUSES.ASSESSED },
+ createDate: '2024-10-01T10:00:00Z',
+ userProfile: { firstName: 'John', lastName: 'Doe' }
+ }
+ ]
+ renderComponent({
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.ASSESSED },
+ history
+ })
+
+ await waitFor(() => {
+ const item = screen.getByTestId('list-item')
+ // Should have replaced ASSESSED with AssessedBy
+ expect(item.textContent).toContain(
+ 'report:complianceReportHistory.AssessedBy: John Doe - formatted-2024-10-01T10:00:00Z'
+ )
+ })
+ })
+
+ it('does not replace ASSESSED with AssessedBy if user is government', async () => {
+ useCurrentUserHook.useCurrentUser.mockReturnValueOnce({
+ data: { isGovernmentUser: true },
+ isLoading: false
+ })
+ const history = [
+ {
+ status: { status: COMPLIANCE_REPORT_STATUSES.ASSESSED },
+ createDate: '2024-10-01T10:00:00Z',
+ userProfile: { firstName: 'John', lastName: 'Doe' }
+ }
+ ]
+ renderComponent({
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.ASSESSED },
+ history
+ })
+
+ await waitFor(() => {
+ const item = screen.getByTestId('list-item')
+ // Should NOT have replaced ASSESSED with AssessedBy
+ expect(item.textContent).toContain(
+ 'report:complianceReportHistory.Assessed: John Doe - formatted-2024-10-01T10:00:00Z'
+ )
+ })
+ })
+})
diff --git a/frontend/src/views/ComplianceReports/__tests__/ViewComplianceReportBrancher.test.jsx b/frontend/src/views/ComplianceReports/__tests__/ViewComplianceReportBrancher.test.jsx
new file mode 100644
index 000000000..0b3127534
--- /dev/null
+++ b/frontend/src/views/ComplianceReports/__tests__/ViewComplianceReportBrancher.test.jsx
@@ -0,0 +1,146 @@
+import React from 'react'
+import { render, screen, waitFor } from '@testing-library/react'
+import { describe, it, expect, beforeEach, vi } from 'vitest'
+import { ViewComplianceReportBrancher } from '../ViewComplianceReportBrancher'
+import * as useComplianceReportsHook from '@/hooks/useComplianceReports'
+import * as useCurrentUserHook from '@/hooks/useCurrentUser'
+import { wrapper } from '@/tests/utils/wrapper'
+
+vi.mock('react-router-dom', async () => {
+ const actual = await vi.importActual('react-router-dom')
+ return {
+ ...actual,
+ useParams: vi.fn()
+ }
+})
+
+vi.mock('@/hooks/useComplianceReports')
+vi.mock('@/hooks/useCurrentUser')
+
+vi.mock('@/components/Loading', () => ({
+ default: () =>
Loading...
+}))
+
+vi.mock('@/views/ComplianceReports/ViewLegacyComplianceReport', () => ({
+ ViewLegacyComplianceReport: () => Legacy Report View
+}))
+
+vi.mock('@/views/ComplianceReports/EditViewComplianceReport', () => ({
+ EditViewComplianceReport: () => Edit Compliance Report
+}))
+
+// Import useParams after mocking so it's already a mock
+import { useParams } from 'react-router-dom'
+
+describe('ViewComplianceReportBrancher', () => {
+ const setupMocks = ({
+ currentUser = { organization: { organizationId: '123' } },
+ isCurrentUserLoading = false,
+ reportData = {
+ report: {
+ legacyId: null,
+ currentStatus: { status: 'DRAFT' }
+ }
+ },
+ isReportLoading = false,
+ isError = false,
+ error = null,
+ complianceReportId = '123'
+ } = {}) => {
+ // Set the return value for useParams
+ useParams.mockReturnValue({ complianceReportId })
+
+ // Mock useCurrentUser
+ useCurrentUserHook.useCurrentUser.mockReturnValue({
+ data: currentUser,
+ isLoading: isCurrentUserLoading
+ })
+
+ // Mock useGetComplianceReport
+ useComplianceReportsHook.useGetComplianceReport.mockReturnValue({
+ data: reportData,
+ isLoading: isReportLoading,
+ isError,
+ error
+ })
+ }
+
+ beforeEach(() => {
+ vi.resetAllMocks()
+ })
+
+ it('renders loading when user is loading', async () => {
+ setupMocks({ isCurrentUserLoading: true })
+ render(, { wrapper })
+
+ await waitFor(() => {
+ expect(screen.getByText('Loading...')).toBeInTheDocument()
+ })
+ })
+
+ it('renders loading when report is loading', async () => {
+ setupMocks({ isReportLoading: true })
+ render(, { wrapper })
+
+ await waitFor(() => {
+ expect(screen.getByText('Loading...')).toBeInTheDocument()
+ })
+ })
+
+ it('renders ViewLegacyComplianceReport when legacyId is present', async () => {
+ setupMocks({
+ reportData: {
+ report: {
+ legacyId: 999,
+ currentStatus: { status: 'DRAFT' }
+ }
+ }
+ })
+
+ render(, { wrapper })
+
+ await waitFor(() => {
+ expect(screen.getByText('Legacy Report View')).toBeInTheDocument()
+ expect(
+ screen.queryByText('Edit Compliance Report')
+ ).not.toBeInTheDocument()
+ })
+ })
+
+ it('renders EditViewComplianceReport when legacyId is null/undefined', async () => {
+ setupMocks({
+ reportData: {
+ report: {
+ currentStatus: { status: 'DRAFT' }
+ // No legacyId means it should render the EditViewComplianceReport
+ }
+ }
+ })
+
+ render(, { wrapper })
+
+ await waitFor(() => {
+ expect(screen.getByText('Edit Compliance Report')).toBeInTheDocument()
+ expect(screen.queryByText('Legacy Report View')).not.toBeInTheDocument()
+ })
+ })
+
+ it('passes error and isError props to the rendered component', async () => {
+ const testError = { message: 'Test error' }
+ setupMocks({
+ isError: true,
+ error: testError,
+ reportData: {
+ report: {
+ currentStatus: { status: 'DRAFT' }
+ }
+ }
+ })
+
+ render(, { wrapper })
+
+ await waitFor(() => {
+ expect(screen.getByText('Edit Compliance Report')).toBeInTheDocument()
+ })
+ })
+})
diff --git a/frontend/src/views/ComplianceReports/__tests__/ViewLegacyComplianceReport.test.jsx b/frontend/src/views/ComplianceReports/__tests__/ViewLegacyComplianceReport.test.jsx
new file mode 100644
index 000000000..4394e044d
--- /dev/null
+++ b/frontend/src/views/ComplianceReports/__tests__/ViewLegacyComplianceReport.test.jsx
@@ -0,0 +1,149 @@
+import React from 'react'
+import { render, screen, fireEvent, waitFor } from '@testing-library/react'
+import { describe, it, expect, beforeEach, vi } from 'vitest'
+import { COMPLIANCE_REPORT_STATUSES } from '@/constants/statuses'
+import { CONFIG } from '@/constants/config'
+import { LegacyAssessmentCard } from '@/views/ComplianceReports/components/LegacyAssessmentCard.jsx'
+import { wrapper } from '@/tests/utils/wrapper.jsx'
+
+// Mock useTranslation
+vi.mock('react-i18next', () => ({
+ useTranslation: () => ({
+ t: (key) => key
+ })
+}))
+
+// Mock HistoryCard
+vi.mock('@/views/ComplianceReports/components/HistoryCard.jsx', () => ({
+ HistoryCard: ({ report }) => HistoryCard - Version {report.version}
+}))
+
+// Mock window.open
+global.open = vi.fn()
+
+describe('LegacyAssessmentCard', () => {
+ const setup = (overrides = {}) => {
+ const defaultProps = {
+ orgData: {
+ name: 'Test Org',
+ orgAddress: {
+ addressLine1: '123 Test St',
+ city: 'Test City',
+ state: 'TS',
+ postalCode: '12345'
+ },
+ orgAttorneyAddress: {
+ addressLine1: '456 Law St',
+ city: 'Law City',
+ state: 'LS',
+ postalCode: '67890'
+ }
+ },
+ hasSupplemental: false,
+ isGovernmentUser: false,
+ currentStatus: COMPLIANCE_REPORT_STATUSES.DRAFT,
+ legacyReportId: '999',
+ chain: []
+ }
+
+ const props = { ...defaultProps, ...overrides }
+
+ return render(, { wrapper })
+ }
+
+ beforeEach(() => {
+ vi.resetAllMocks()
+ })
+
+ it('renders the organization details and addresses', () => {
+ setup()
+ expect(screen.getByText('report:orgDetails')).toBeInTheDocument()
+ expect(screen.getByText('Test Org')).toBeInTheDocument()
+ expect(screen.getByText(/report:serviceAddrLabel/)).toBeInTheDocument()
+ expect(screen.getByText(/report:bcAddrLabel/)).toBeInTheDocument()
+ })
+
+ it('displays contact instructions for non-government users', () => {
+ setup({ isGovernmentUser: false })
+ expect(
+ screen.getByText('report:contactForAddrChange', { exact: false })
+ ).toBeInTheDocument()
+ })
+
+ it('does not display contact instructions for government users', () => {
+ setup({ isGovernmentUser: true })
+ expect(
+ screen.queryByText('report:contactForAddrChange', { exact: false })
+ ).not.toBeInTheDocument()
+ })
+
+ it('displays the supplemental warning text', () => {
+ setup()
+ expect(screen.getByText('report:supplementalWarning')).toBeInTheDocument()
+ })
+
+ it('displays "View Legacy" button which opens the legacy report link on click', async () => {
+ setup({ legacyReportId: '999' })
+ const viewBtn = screen.getByText('report:viewLegacyBtn')
+ expect(viewBtn).toBeInTheDocument()
+ fireEvent.click(viewBtn)
+ await waitFor(() => {
+ expect(global.open).toHaveBeenCalledWith(
+ `${CONFIG.TFRS_BASE}/compliance_reporting/edit/999/intro`,
+ '_blank'
+ )
+ })
+ })
+
+ it('displays history when chain is not empty', () => {
+ setup({
+ chain: [
+ {
+ version: 0,
+ report: {
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.SUBMITTED }
+ }
+ },
+ {
+ version: 1,
+ report: {
+ currentStatus: { status: COMPLIANCE_REPORT_STATUSES.ASSESSED }
+ }
+ }
+ ]
+ })
+ expect(screen.getByText('report:reportHistory')).toBeInTheDocument()
+ expect(screen.getByText('HistoryCard - Version 0')).toBeInTheDocument()
+ expect(screen.getByText('HistoryCard - Version 1')).toBeInTheDocument()
+ })
+
+ it('shows "report:assessment" title when currentStatus is ASSESSED', () => {
+ setup({ currentStatus: COMPLIANCE_REPORT_STATUSES.ASSESSED })
+ expect(screen.getByText('report:assessment')).toBeInTheDocument()
+ })
+
+ it('shows "report:assessment" title for government users even if not assessed', () => {
+ setup({
+ isGovernmentUser: true,
+ currentStatus: COMPLIANCE_REPORT_STATUSES.DRAFT
+ })
+ expect(screen.getByText('report:assessment')).toBeInTheDocument()
+ })
+
+ it('shows "report:assessment" title if supplemental is true', () => {
+ setup({
+ hasSupplemental: true,
+ currentStatus: COMPLIANCE_REPORT_STATUSES.DRAFT
+ })
+ expect(screen.getByText('report:assessment')).toBeInTheDocument()
+ })
+
+ it('shows "report:orgDetails" title if not assessed, not government user, and no supplemental', () => {
+ setup({
+ isGovernmentUser: false,
+ hasSupplemental: false,
+ currentStatus: COMPLIANCE_REPORT_STATUSES.DRAFT
+ })
+ expect(screen.getByText('report:orgDetails')).toBeInTheDocument()
+ })
+})
diff --git a/frontend/src/views/ComplianceReports/components/AssessmentCard.jsx b/frontend/src/views/ComplianceReports/components/AssessmentCard.jsx
index 1b69bcd17..9c55d4117 100644
--- a/frontend/src/views/ComplianceReports/components/AssessmentCard.jsx
+++ b/frontend/src/views/ComplianceReports/components/AssessmentCard.jsx
@@ -6,119 +6,14 @@ import { StyledListItem } from '@/components/StyledListItem'
import { roles } from '@/constants/roles'
import { COMPLIANCE_REPORT_STATUSES } from '@/constants/statuses'
import { useCreateSupplementalReport } from '@/hooks/useComplianceReports'
-import { useCurrentUser } from '@/hooks/useCurrentUser'
import { constructAddress } from '@/utils/constructAddress'
-import { timezoneFormatter } from '@/utils/formatters'
import AssignmentIcon from '@mui/icons-material/Assignment'
-import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
-import { List, ListItemText, Stack, styled } from '@mui/material'
-import MuiAccordion from '@mui/material/Accordion'
-import MuiAccordionDetails from '@mui/material/AccordionDetails'
-import MuiAccordionSummary, {
- accordionSummaryClasses
-} from '@mui/material/AccordionSummary'
+import { List, ListItemText, Stack } from '@mui/material'
import Box from '@mui/material/Box'
-import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router-dom'
import { FEATURE_FLAGS, isFeatureEnabled } from '@/constants/config.js'
-
-const Accordion = styled((props) => (
-
-))(() => ({
- border: `none`,
- '&::before': {
- display: 'none'
- }
-}))
-
-const AccordionSummary = styled((props) => (
- }
- {...props}
- />
-))(() => ({
- minHeight: 'unset',
- padding: 0,
- flexDirection: 'row-reverse',
- [`& .${accordionSummaryClasses.content}`]: {
- margin: 0
- },
- [`& .${accordionSummaryClasses.expanded}`]: {
- margin: 0
- }
-}))
-
-const AccordionDetails = styled(MuiAccordionDetails)(() => ({
- paddingLeft: '1rem',
- paddingTop: 0,
- paddingBottom: 0
-}))
-
-const HistoryCard = ({ report }) => {
- const { data: currentUser } = useCurrentUser()
- const isGovernmentUser = currentUser?.isGovernmentUser
- const { t } = useTranslation(['report'])
- const filteredHistory = useMemo(() => {
- if (!report.history || report.history.length === 0) {
- return []
- }
- // Sort the history array by date in descending order
- return [...report.history]
- .sort((a, b) => {
- return new Date(b.createDate) - new Date(a.createDate)
- })
- .map((item) => {
- if (
- item.status.status === COMPLIANCE_REPORT_STATUSES.ASSESSED &&
- !isGovernmentUser
- ) {
- item.status.status = 'AssessedBy'
- }
- return item
- })
- .filter((item) => item.status.status !== COMPLIANCE_REPORT_STATUSES.DRAFT)
- }, [isGovernmentUser, report.history])
- return (
-
- }
- aria-controls="panel1-content"
- >
-
- {report.version === 0
- ? `${report.compliancePeriod.description} Compliance Report`
- : report.nickname}
- : {report.currentStatus.status}
-
-
-
-
- {filteredHistory.map((item, index) => (
-
-
-
-
-
- ))}
-
-
-
- )
-}
+import { HistoryCard } from '@/views/ComplianceReports/components/HistoryCard.jsx'
export const AssessmentCard = ({
orgData,
diff --git a/frontend/src/views/ComplianceReports/components/HistoryCard.jsx b/frontend/src/views/ComplianceReports/components/HistoryCard.jsx
new file mode 100644
index 000000000..fb8a755a8
--- /dev/null
+++ b/frontend/src/views/ComplianceReports/components/HistoryCard.jsx
@@ -0,0 +1,114 @@
+import React, { useMemo } from 'react'
+import { List, ListItemText, styled } from '@mui/material'
+import MuiAccordion from '@mui/material/Accordion'
+import MuiAccordionSummary, {
+ accordionSummaryClasses
+} from '@mui/material/AccordionSummary'
+import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
+import MuiAccordionDetails from '@mui/material/AccordionDetails'
+import { useCurrentUser } from '@/hooks/useCurrentUser.js'
+import { useTranslation } from 'react-i18next'
+import { COMPLIANCE_REPORT_STATUSES } from '@/constants/statuses.js'
+import BCTypography from '@/components/BCTypography/index.jsx'
+import { StyledListItem } from '@/components/StyledListItem.jsx'
+import { timezoneFormatter } from '@/utils/formatters.js'
+
+const Accordion = styled((props) => (
+
+))(() => ({
+ border: `none`,
+ '&::before': {
+ display: 'none'
+ }
+}))
+
+const AccordionSummary = styled((props) => (
+ }
+ {...props}
+ />
+))(() => ({
+ minHeight: 'unset',
+ padding: 0,
+ flexDirection: 'row-reverse',
+ [`& .${accordionSummaryClasses.content}`]: {
+ margin: 0
+ },
+ [`& .${accordionSummaryClasses.expanded}`]: {
+ margin: 0
+ }
+}))
+
+const AccordionDetails = styled(MuiAccordionDetails)(() => ({
+ paddingLeft: '1rem',
+ paddingTop: 0,
+ paddingBottom: 0
+}))
+
+export const HistoryCard = ({ report }) => {
+ const { data: currentUser } = useCurrentUser()
+ const isGovernmentUser = currentUser?.isGovernmentUser
+ const { t } = useTranslation(['report'])
+ const filteredHistory = useMemo(() => {
+ if (!report.history || report.history.length === 0) {
+ return []
+ }
+ // Sort the history array by date in descending order
+ return [...report.history]
+ .sort((a, b) => {
+ return new Date(b.createDate) - new Date(a.createDate)
+ })
+ .map((item) => {
+ if (
+ item.status.status === COMPLIANCE_REPORT_STATUSES.ASSESSED &&
+ !isGovernmentUser
+ ) {
+ item.status.status = 'AssessedBy'
+ }
+ return item
+ })
+ .filter((item) => item.status.status !== COMPLIANCE_REPORT_STATUSES.DRAFT)
+ }, [isGovernmentUser, report.history])
+ return (
+
+ }
+ aria-controls="panel1-content"
+ >
+
+ {report.version === 0
+ ? `${report.compliancePeriod.description} Compliance Report`
+ : report.nickname}
+ : {report.currentStatus.status}
+
+
+
+
+ {filteredHistory.map((item, index) => (
+
+
+
+
+
+ ))}
+
+
+
+ )
+}
diff --git a/frontend/src/views/ComplianceReports/components/LegacyAssessmentCard.jsx b/frontend/src/views/ComplianceReports/components/LegacyAssessmentCard.jsx
new file mode 100644
index 000000000..697a17b4f
--- /dev/null
+++ b/frontend/src/views/ComplianceReports/components/LegacyAssessmentCard.jsx
@@ -0,0 +1,128 @@
+import BCButton from '@/components/BCButton'
+import BCTypography from '@/components/BCTypography'
+import BCWidgetCard from '@/components/BCWidgetCard/BCWidgetCard'
+import { StyledListItem } from '@/components/StyledListItem'
+import { COMPLIANCE_REPORT_STATUSES } from '@/constants/statuses'
+import { constructAddress } from '@/utils/constructAddress'
+import AssignmentIcon from '@mui/icons-material/Assignment'
+import { List, ListItemText, Stack } from '@mui/material'
+import Box from '@mui/material/Box'
+import { useTranslation } from 'react-i18next'
+import { CONFIG } from '@/constants/config'
+import { HistoryCard } from '@/views/ComplianceReports/components/HistoryCard.jsx'
+
+export const LegacyAssessmentCard = ({
+ orgData,
+ hasSupplemental,
+ isGovernmentUser,
+ currentStatus,
+ legacyReportId,
+ chain
+}) => {
+ const { t } = useTranslation(['report'])
+
+ const viewLegacyReport = () => {
+ window.open(
+ `${CONFIG.TFRS_BASE}/compliance_reporting/edit/${legacyReportId}/intro`,
+ '_blank'
+ )
+ }
+ return (
+ <>
+
+
+
+ {orgData?.name}
+
+
+
+
+ {t('report:serviceAddrLabel')}:
+ {orgData && constructAddress(orgData.orgAddress)}
+
+
+
+
+ {t('report:bcAddrLabel')}:{' '}
+ {orgData && constructAddress(orgData.orgAttorneyAddress)}
+
+
+
+
+ {!isGovernmentUser && (
+
+ )}
+ {!!chain.length && (
+ <>
+
+ {t('report:reportHistory')}
+
+ {chain.map((report) => (
+
+ ))}
+ >
+ )}
+
+
+ {t('report:supplementalWarning')}
+
+
+ }
+ sx={{ mt: 2 }}
+ onClick={viewLegacyReport}
+ >
+ {t('report:viewLegacyBtn')}
+
+
+
+ >
+ }
+ />
+
+ {t('report:questions')}
+
+
+ >
+ )
+}
diff --git a/frontend/src/views/ComplianceReports/components/_schema.jsx b/frontend/src/views/ComplianceReports/components/_schema.jsx
index e83fcdc19..e7f1546fb 100644
--- a/frontend/src/views/ComplianceReports/components/_schema.jsx
+++ b/frontend/src/views/ComplianceReports/components/_schema.jsx
@@ -1,6 +1,6 @@
import { BCColumnSetFilter } from '@/components/BCDataGrid/components'
import { SUMMARY } from '@/constants/common'
-import { ReportsStatusRenderer, LinkRenderer } from '@/utils/grid/cellRenderers'
+import { ReportsStatusRenderer } from '@/utils/grid/cellRenderers'
import { timezoneFormatter } from '@/utils/formatters'
export const reportsColDefs = (t, bceidRole) => [
@@ -8,11 +8,6 @@ export const reportsColDefs = (t, bceidRole) => [
field: 'compliancePeriod',
headerName: t('report:reportColLabels.compliancePeriod'),
width: 210,
- cellRenderer: LinkRenderer,
- cellRendererParams: {
- url: ({ data }) =>
- `${data.compliancePeriod?.description}/${data.complianceReportId}`
- },
valueGetter: ({ data }) => data.compliancePeriod?.description || '',
filterParams: {
buttons: ['clear']
@@ -23,11 +18,6 @@ export const reportsColDefs = (t, bceidRole) => [
headerName: t('report:reportColLabels.organization'),
flex: 2,
hide: bceidRole,
- cellRenderer: LinkRenderer,
- cellRendererParams: {
- url: ({ data }) =>
- `${data.compliancePeriod?.description}/${data.complianceReportId}`
- },
valueGetter: ({ data }) => data.organization?.name || ''
},
{