Skip to content

Commit

Permalink
Merge branch 'main' into NDT-606-Refine-Global-Search-for-the-Interna…
Browse files Browse the repository at this point in the history
…l-and-External-Status
  • Loading branch information
rafasdc authored Dec 4, 2024
2 parents 3ff9226 + 8950e15 commit 5313a0e
Show file tree
Hide file tree
Showing 28 changed files with 1,264 additions and 566 deletions.
5 changes: 5 additions & 0 deletions .github/actions/app/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ inputs:
coverages_file:
description: 'Coverages file'
required: true
session_secret:
description: 'Session secret'
required: true

runs:
using: composite
Expand All @@ -143,6 +146,7 @@ runs:
cert_key: ${{ inputs.cert_key }}
cert_ca: ${{ inputs.cert_ca }}
pgbackrest_s3_bucket: ${{ inputs.pgbackrest_s3_bucket }}
session_secret: ${{ inputs.session_secret }}
insecure_skip_tls_verify: true
- run: |
SHA_ONLY=$(echo ${{ inputs.tag }} | cut -c 5-)
Expand Down Expand Up @@ -191,6 +195,7 @@ runs:
--set cronshp.erFile="${{ inputs.er_file }}" \
--set cronshp.rdFile="${{ inputs.rd_file }}" \
--set cronshp.coveragesFile="${{ inputs.coverages_file }}" \
--set app.sessionSecret="${{ inputs.session_secret }}" \
--values values-${{ inputs.environment }}.yaml
shell: bash
4 changes: 4 additions & 0 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ on:
ER_FILE: { required: true }
RD_FILE: { required: true }
COVERAGES_FILE: { required: true }
SESSION_SECRET: { required: true }

env:
TAG: sha-${{ github.sha }}
Expand Down Expand Up @@ -120,6 +121,7 @@ jobs:
er_file: ${{ secrets.ER_FILE }}
rd_file: ${{ secrets.RD_FILE }}
coverages_file: ${{ secrets.COVERAGES_FILE }}
session_secret: ${{ secrets.SESSION_SECRET }}
environment: dev

ensure-sqitch-plan-ends-with-tag:
Expand Down Expand Up @@ -188,6 +190,7 @@ jobs:
er_file: ${{ secrets.ER_FILE }}
rd_file: ${{ secrets.RD_FILE }}
coverages_file: ${{ secrets.COVERAGES_FILE }}
session_secret: ${{ secrets.SESSION_SECRET }}
environment: test

deploy-to-openshift-production:
Expand Down Expand Up @@ -247,6 +250,7 @@ jobs:
er_file: ${{ secrets.ER_FILE }}
rd_file: ${{ secrets.RD_FILE }}
coverages_file: ${{ secrets.COVERAGES_FILE }}
session_secret: ${{ secrets.SESSION_SECRET }}
environment: prod

backup-secrets-dev:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ jobs:
ER_FILE: ${{ secrets.ER_FILE }}
RD_FILE: ${{ secrets.RD_FILE }}
COVERAGES_FILE: ${{ secrets.COVERAGES_FILE }}
SESSION_SECRET: ${{ secrets.SESSION_SECRET }}

deploy-feature:
if: github.event_name == 'pull_request' && github.event.pull_request.draft == false
Expand Down
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,40 @@
## [1.214.3](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.214.2...v1.214.3) (2024-12-04)

## [1.214.2](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.214.1...v1.214.2) (2024-12-04)

### Bug Fixes

- browser compatibility on toSorted ([a4d2384](https://github.com/bcgov/CONN-CCBC-portal/commit/a4d2384a33f39c7097042ae4da8cb2165ada8b12))
- remove unwanted unsaved changes modal from RFI ([db5ae03](https://github.com/bcgov/CONN-CCBC-portal/commit/db5ae03e00167fb1aad4d2fa7d2fa6b1e44bb0b2))

## [1.214.1](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.214.0...v1.214.1) (2024-12-04)

### Bug Fixes

- scroll preservation when sticky header on in all dashboard ([ee4e6b9](https://github.com/bcgov/CONN-CCBC-portal/commit/ee4e6b92ae0f8d045bea69a9b824eca5bec00849))

# [1.214.0](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.213.4...v1.214.0) (2024-12-04)

### Features

- enable global filter to filter communities ([ef8f11d](https://github.com/bcgov/CONN-CCBC-portal/commit/ef8f11ddb95b1c74ca396bff181577d30732b93e))

## [1.213.4](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.213.3...v1.213.4) (2024-12-03)

## [1.213.3](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.213.2...v1.213.3) (2024-11-29)

### Bug Fixes

- deterministic session secret ([d7d29a0](https://github.com/bcgov/CONN-CCBC-portal/commit/d7d29a0c72331dc2ebcea90528a3ebb55af733a6))

## [1.213.2](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.213.1...v1.213.2) (2024-11-29)

## [1.213.1](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.213.0...v1.213.1) (2024-11-29)

### Bug Fixes

- browser compatibility on toSorted ([b1f6e37](https://github.com/bcgov/CONN-CCBC-portal/commit/b1f6e37a76672d9a07ecc39b0dbb7dfd6c9f01cc))

# [1.213.0](https://github.com/bcgov/CONN-CCBC-portal/compare/v1.212.2...v1.213.0) (2024-11-27)

### Features
Expand Down
2 changes: 1 addition & 1 deletion app/components/Analyst/RFI/RFI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ const RFI: React.FC<Props> = ({ rfiDataByRfiDataId, id }) => {
formData={jsonData}
noValidate
tagName="div"
formContext={{ applicationId, rfiId: rowId }}
formContext={{ applicationId, rfiId: rowId, skipUnsavedWarning: true }}
// Pass children to hide submit button
// eslint-disable-next-line react/no-children-prop
children
Expand Down
65 changes: 58 additions & 7 deletions app/components/AnalystDashboard/AllDashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-shadow */
/* eslint-disable react/jsx-pascal-case */
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { graphql, useFragment } from 'react-relay';
import styled from 'styled-components';
import cookie from 'js-cookie';
Expand All @@ -18,6 +18,7 @@ import {
MRT_ToggleDensePaddingButton,
MRT_ToggleFullScreenButton,
MRT_ShowHideColumnsButton,
MRT_FilterFns,
} from 'material-react-table';

import RowCount from 'components/Table/RowCount';
Expand Down Expand Up @@ -156,6 +157,9 @@ const ApplicantStatusCell = ({ cell }) => {

const filterOutNullishs = (val) => val !== undefined && val !== null;

const toLabelValuePair = (value) =>
value ? { label: value, value } : { label: 'Unassigned', value: ' ' };

const accessorFunctionGeneratorInjectsEmptyString = (accessorKey) => {
return (row) => row[accessorKey] ?? '';
};
Expand Down Expand Up @@ -302,6 +306,10 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
const [showColumnFilters, setShowColumnFilters] = useState(false);

const [sorting, setSorting] = useState<MRT_SortingState>([]);
const [expanded, setExpanded] = useState({});
const [globalFilter, setGlobalFilter] = useState(null);

const expandedRowsRef = useRef({});

const [columnSizing, setColumnSizing] = useState<MRT_ColumnSizingState>({
'mrt-row-expand': 40,
Expand All @@ -315,6 +323,7 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
projectTitle: 150,
zones: 91,
});
const tableContainerRef = useRef(null);

const statusOrderMap = useMemo(() => {
return allApplicationStatusTypes?.nodes?.reduce((acc, status) => {
Expand Down Expand Up @@ -361,6 +370,11 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
}

setIsFirstRender(false);

const savedScrollTop = sessionStorage.getItem('dashboard_scroll_position');
if (savedScrollTop && tableContainerRef.current) {
tableContainerRef.current.scrollTop = parseInt(savedScrollTop, 10);
}
}, []);

useEffect(() => {
Expand Down Expand Up @@ -442,6 +456,11 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
}
}, [visibilityPreference]);

useEffect(() => {
setExpanded(globalFilter ? expandedRowsRef.current : {});
expandedRowsRef.current = {};
}, [globalFilter]);

const state = {
showGlobalFilter: true,
columnFilters,
Expand All @@ -450,6 +469,20 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
showColumnFilters,
sorting,
columnSizing,
expanded,
globalFilter,
};

const customGlobalFilter = (row, id, filterValue, filterMeta) => {
const defaultMatch = MRT_FilterFns.fuzzy(row, id, filterValue, filterMeta);
const communitiesString = row.original.communities
?.map((item) => item.geoName)
.join(',')
?.toLowerCase();
const detailsMatch = communitiesString?.includes(filterValue.toLowerCase());
expandedRowsRef.current[row.id] = detailsMatch;

return defaultMatch || detailsMatch;
};

const getCommunities = (application) => {
Expand Down Expand Up @@ -536,7 +569,7 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
allApplications.edges.map((edge) => edge.node?.intakeNumber?.toString())
),
'N/A',
].toSorted((a, b) => {
].sort((a, b) => {
if (a === 'N/A') return -1;
if (b === 'N/A') return 1;
return Number(a) - Number(b);
Expand All @@ -559,7 +592,7 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
),
...allCbcStatuses,
]),
].toSorted((a, b) => statusOrderMap[a] - statusOrderMap[b]);
].sort((a, b) => statusOrderMap[a] - statusOrderMap[b]);

const externalStatuses = [
...new Set([
Expand All @@ -568,7 +601,7 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
),
...allCbcStatuses,
]),
].toSorted((a, b) => statusOrderMap[a] - statusOrderMap[b]);
].sort((a, b) => statusOrderMap[a] - statusOrderMap[b]);

const uniqueLeads = [
...new Set(allApplications.edges.map((edge) => edge.node.analystLead)),
Expand All @@ -579,8 +612,8 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
allApplications.edges.map((edge) => edge.node.package?.toString())
),
]
.filter(filterOutNullishs)
.toSorted((a, b) => Number(a) - Number(b));
.map(toLabelValuePair)
.toSorted((a, b) => Number(a.value) - Number(b.value));

return [
{
Expand Down Expand Up @@ -655,6 +688,14 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
setSorting(sort);
}
};

const handleTableScroll = () => {
sessionStorage.setItem(
'dashboard_scroll_position',
tableContainerRef?.current?.scrollTop
);
};

const tableHeightOffset = enableTimeMachine ? '460px' : '360px';

const table = useMaterialReactTable({
Expand All @@ -664,6 +705,8 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
columnResizeMode: 'onChange',
state,
muiTableContainerProps: {
ref: tableContainerRef,
onScroll: handleTableScroll,
sx: {
padding: '0 8px 8px 8px',
maxHeight: freezeHeader ? `calc(100vh - ${tableHeightOffset})` : '100%',
Expand Down Expand Up @@ -691,8 +734,16 @@ const AllDashboardTable: React.FC<Props> = ({ query }) => {
filterFns: {
filterNumber,
statusFilter,
customGlobalFilter,
},
renderDetailPanel: ({ row }) => (
<AllDashboardDetailPanel row={row} filterValue={globalFilter} />
),
globalFilterFn: 'customGlobalFilter',
onGlobalFilterChange: setGlobalFilter,
onExpandedChange: (expanded) => {
setExpanded(expanded);
},
renderDetailPanel: ({ row }) => <AllDashboardDetailPanel row={row} />,
renderToolbarInternalActions: ({ table }) => (
<Box>
<IconButton size="small">
Expand Down
37 changes: 35 additions & 2 deletions app/components/AnalystDashboard/AllDashboardDetailPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import styled from 'styled-components';

interface Props {
row: any;
filterValue: string;
}

const StyledMapLink = styled.a`
Expand All @@ -17,7 +18,36 @@ const StyledSpan = styled.span`
display: block;
`;

const AllDashboardDetailPanel: React.FC<Props> = ({ row }) => {
const StyledHighlightSpan = styled.span`
background-color: ${(props) => props.theme.color.primaryYellow};
`;

const HighlightFilterMatch = ({ text, filterValue }) => {
if (!filterValue) return text;

const normalizedFilterValue = filterValue.replace(/\s+/g, '').toLowerCase();
const normalizedText = text.replace(/\s+/g, '').toLowerCase();

const matchIndex = normalizedText.indexOf(normalizedFilterValue);

if (matchIndex === -1) {
return text;
}

const beforeMatch = text.slice(0, matchIndex);
const match = text.slice(matchIndex, matchIndex + filterValue.length);
const afterMatch = text.slice(matchIndex + filterValue.length);

return (
<>
{beforeMatch}
<StyledHighlightSpan>{match}</StyledHighlightSpan>
{afterMatch}
</>
);
};

const AllDashboardDetailPanel: React.FC<Props> = ({ row, filterValue }) => {
const communities = (row.original.communities as any[]) || [];
return (
<>
Expand All @@ -30,7 +60,10 @@ const AllDashboardDetailPanel: React.FC<Props> = ({ row }) => {
target="_blank"
rel="noopener noreferrer"
>
{item.geoName}
<HighlightFilterMatch
text={item.geoName}
filterValue={filterValue}
/>
</StyledMapLink>
{index < communities.length - 1 && ', '}
</>
Expand Down
9 changes: 8 additions & 1 deletion app/components/Table/ClearFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const ClearFilters: React.FC<Props> = ({
const clearFilters = () => {
table.resetColumnFilters();
table.setColumnFilters(defaultFilters);
table.setGlobalFilter('');
};

const isTableFiltersPresent =
Expand All @@ -29,9 +30,15 @@ const ClearFilters: React.FC<Props> = ({
filters.filter((f) => f.id === 'program' && (f.value as any[]).length < 3)
.length > 0;

const isGlobalFilterPresent = table.getState().globalFilter !== '';

return (
<Button
disabled={!isTableFiltersPresent && !isExternalFiltersPresent}
disabled={
!isTableFiltersPresent &&
!isExternalFiltersPresent &&
!isGlobalFilterPresent
}
variant="text"
onClick={clearFilters}
data-testid="clear-filter-button"
Expand Down
Loading

0 comments on commit 5313a0e

Please sign in to comment.