From 15a4e28fddaa88e7dc203f4a7a0995202c539812 Mon Sep 17 00:00:00 2001 From: R Ranathunga Date: Fri, 15 Nov 2024 09:11:16 -0800 Subject: [PATCH] feat: enable detail panel with communities in all dashboard --- .../AnalystDashboard/AllDashboard.tsx | 64 ++++++++++++++- .../AllDashboardDetailPanel.tsx | 45 +++++++++++ app/tests/pages/analyst/dashboard.test.tsx | 81 +++++++++++++++++++ 3 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 app/components/AnalystDashboard/AllDashboardDetailPanel.tsx diff --git a/app/components/AnalystDashboard/AllDashboard.tsx b/app/components/AnalystDashboard/AllDashboard.tsx index 74b33ee8d..ce73e2998 100644 --- a/app/components/AnalystDashboard/AllDashboard.tsx +++ b/app/components/AnalystDashboard/AllDashboard.tsx @@ -40,6 +40,7 @@ import { import AdditionalFilters, { additionalFilterColumns, } from './AdditionalFilters'; +import AllDashboardDetailPanel from './AllDashboardDetailPanel'; type Application = { ccbcNumber: string; @@ -51,6 +52,7 @@ type Application = { externalStatus: string; analystLead?: string; zones: readonly number[]; + communities: any[]; }; export const filterNumber = (row, id, filterValue) => { @@ -95,11 +97,12 @@ const StyledTableHeader = styled.div` `; const muiTableBodyCellProps = (props): TableCellProps => { - const centeredCols = ['Package', 'zones']; + const centeredCols = ['Package', 'zones', 'intakeNumber']; + const isExpandColumn = props.column.id === 'mrt-row-expand'; return { align: centeredCols.includes(props.column.id) ? 'center' : 'left', sx: { - padding: '8px 0px', + padding: isExpandColumn ? '0 8px' : '8px 0px', }, }; }; @@ -201,6 +204,7 @@ const AllDashboardTable: React.FC = ({ query }) => { intakeNumber program zones + status applicationSowDataByApplicationId( condition: { isAmendment: false } last: 1 @@ -210,6 +214,18 @@ const AllDashboardTable: React.FC = ({ query }) => { id jsonData rowId + sowTab8SBySowId { + nodes { + rowId + jsonData + sowId + } + } + } + } + applicationFormTemplate9DataByApplicationId { + nodes { + jsonData } } } @@ -224,6 +240,14 @@ const AllDashboardTable: React.FC = ({ query }) => { jsonData projectNumber cbcId + cbcByCbcId { + communitiesSourceDataByCbcProjectCommunityCbcIdAndCommunitiesSourceDataId { + nodes { + bcGeographicName + mapLink + } + } + } } } } @@ -280,12 +304,13 @@ const AllDashboardTable: React.FC = ({ query }) => { const [sorting, setSorting] = useState([]); const [columnSizing, setColumnSizing] = useState({ + 'mrt-row-expand': 40, Lead: 114, Package: 104, analystStatus: 152, - ccbcNumber: 108, + projectId: 108, externalStatus: 150, - intakeNumber: 85, + intakeNumber: 90, organizationName: 141, projectTitle: 150, zones: 91, @@ -427,6 +452,29 @@ const AllDashboardTable: React.FC = ({ query }) => { columnSizing, }; + const getCommunities = (application) => { + const communityDataSource = + application.status === 'applicant_approved' || + application.status === 'approved' + ? application.applicationSowDataByApplicationId.nodes[0] + ?.sowTab8SBySowId + : application.applicationFormTemplate9DataByApplicationId; + return communityDataSource.nodes[0]?.jsonData?.geoNames?.map((item) => ({ + geoName: item.bcGeoName || item.geoName, + mapLink: item.mapLink, + })); + }; + + const getCbcCommunities = (project) => { + const communityDataSource = + project.node.cbcByCbcId + ?.communitiesSourceDataByCbcProjectCommunityCbcIdAndCommunitiesSourceDataId; + return communityDataSource?.nodes?.map((item) => ({ + geoName: item.bcGeographicName, + mapLink: item.mapLink, + })); + }; + const tableData = useMemo(() => { return [ ...allApplications.edges.map((application) => ({ @@ -442,6 +490,7 @@ const AllDashboardTable: React.FC = ({ query }) => { showLink: true, externalStatusOrder: statusOrderMap[application.node.externalStatus], internalStatusOrder: statusOrderMap[application.node.analystStatus], + communities: getCommunities(application.node), })), ...(showCbcProjects ? allCbcData.edges.map((project) => ({ @@ -465,6 +514,7 @@ const AllDashboardTable: React.FC = ({ query }) => { lead: null, isCbcProject: true, showLink: showCbcProjectsLink, + communities: getCbcCommunities(project), })) ?? [] : []), ]; @@ -612,6 +662,11 @@ const AllDashboardTable: React.FC = ({ query }) => { maxHeight: freezeHeader ? `calc(100vh - ${tableHeightOffset})` : '100%', }, }, + muiTableBodyRowProps: { + sx: { + boxShadow: '0 3px 3px -2px #c4c4c4', + }, + }, layoutMode: isLargeUp ? 'grid' : 'semantic', muiTableBodyCellProps, muiTableHeadCellProps, @@ -630,6 +685,7 @@ const AllDashboardTable: React.FC = ({ query }) => { filterNumber, statusFilter, }, + renderDetailPanel: ({ row }) => , renderToolbarInternalActions: ({ table }) => ( diff --git a/app/components/AnalystDashboard/AllDashboardDetailPanel.tsx b/app/components/AnalystDashboard/AllDashboardDetailPanel.tsx new file mode 100644 index 000000000..5c4eeb4ed --- /dev/null +++ b/app/components/AnalystDashboard/AllDashboardDetailPanel.tsx @@ -0,0 +1,45 @@ +import styled from 'styled-components'; + +interface Props { + row: any; +} + +const StyledMapLink = styled.a` + color: ${(props) => props.theme.color.links}; + text-decoration-line: underline; + :hover { + cursor: pointer; + } +`; + +const StyledSpan = styled.span` + color: ${(props) => props.theme.color.darkGrey}; + display: block; +`; + +const AllDashboardDetailPanel: React.FC = ({ row }) => { + const communities = (row.original.communities as any[]) || []; + return ( + <> + Communities + {communities.length > 0 ? ( + communities.map((item, index) => ( + <> + + {item.geoName} + + {index < communities.length - 1 && ', '} + + )) + ) : ( + N/A + )} + + ); +}; + +export default AllDashboardDetailPanel; diff --git a/app/tests/pages/analyst/dashboard.test.tsx b/app/tests/pages/analyst/dashboard.test.tsx index 350fc3842..9819f37a8 100644 --- a/app/tests/pages/analyst/dashboard.test.tsx +++ b/app/tests/pages/analyst/dashboard.test.tsx @@ -33,6 +33,21 @@ const mockQueryPayload = { zone: 1, zones: [1, 2], program: 'CCBC', + status: 'received', + applicationFormTemplate9DataByApplicationId: { + nodes: [ + { + jsonData: { + geoNames: [ + { + mapLink: 'https://www.google.com/maps', + geoName: 'Test Geo Name', + }, + ], + }, + }, + ], + }, }, }, { @@ -48,6 +63,41 @@ const mockQueryPayload = { zone: null, zones: [], program: 'CCBC', + status: 'approved', + applicationFormTemplate9DataByApplicationId: { + nodes: [ + { + jsonData: { + geoNames: [ + { + mapLink: 'https://www.google.com/maps', + geoName: 'Old Fort', + }, + ], + }, + }, + ], + }, + applicationSowDataByApplicationId: { + nodes: [ + { + sowTab8SBySowId: { + nodes: [ + { + jsonData: { + geoNames: [ + { + bcGeoName: 'Bear Lake', + mapLink: 'https://www.google.com/maps', + }, + ], + }, + }, + ], + }, + }, + ], + }, }, }, { @@ -261,6 +311,18 @@ const mockQueryPayload = { agreementSigned: 'YES', }, projectNumber: 3333, + cbcByCbcId: { + communitiesSourceDataByCbcProjectCommunityCbcIdAndCommunitiesSourceDataId: + { + nodes: [ + { + bcGeographicName: 'Old Silver Valley', + mapLink: + 'https://apps.gov.bc.ca/pub/bcgnws/names/24757.html', + }, + ], + }, + }, }, }, ], @@ -403,6 +465,25 @@ describe('The index page', () => { expect(screen.getByText('Package')).toBeInTheDocument(); }); + it('renders expand all and expand buttons and opens detail panel with communities data', async () => { + jest + .spyOn(moduleApi, 'useFeature') + .mockReturnValue(mockShowCbcProjects(true)); + + pageTestingHelper.loadQuery(); + pageTestingHelper.renderPage(); + + const expandAllButton = document.querySelector('[aria-label="Expand all"]'); + expect(expandAllButton).toBeInTheDocument(); + + fireEvent.click(screen.getByTestId('KeyboardDoubleArrowDownIcon')); + + expect(screen.getByText(/Test Geo Name/)).toBeInTheDocument(); + expect(screen.getByText(/Bear Lake/)).toBeInTheDocument(); + expect(screen.queryByText(/Old Fort/)).not.toBeInTheDocument(); + expect(screen.getByText(/Old Silver Valley/)).toBeInTheDocument(); + }); + it('analyst table lead only visible when feature enabled', async () => { jest .spyOn(moduleApi, 'useFeature')