Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…e-review into mcr-4014-submission-summary-tests
  • Loading branch information
pearl-truss committed Apr 23, 2024
2 parents f9ec4de + a5ff84a commit c229c28
Show file tree
Hide file tree
Showing 22 changed files with 442 additions and 188 deletions.
2 changes: 1 addition & 1 deletion services/app-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@aws-sdk/client-ses": "^3.529.1",
"@aws-sdk/client-ssm": "^3.529.1",
"@aws-sdk/lib-storage": "^3.529.1",
"@launchdarkly/node-server-sdk": "8.1.1",
"@launchdarkly/node-server-sdk": "9.4.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.45.1",
"apollo-server-core": "^3.11.1",
"apollo-server-lambda": "^3.5.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ export const ContractDetailsSummarySection = ({
? new Date(
documentDateLookupTable.previousSubmissionDate
)
: undefined
: null
}
caption="Contract"
documentCategory="Contract"
Expand All @@ -325,7 +325,7 @@ export const ContractDetailsSummarySection = ({
? new Date(
documentDateLookupTable.previousSubmissionDate
)
: undefined
: null
}
caption="Contract supporting documents"
documentCategory="Contract-supporting"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ export const RateDetailsSummarySection = ({
? new Date(
documentDateLookupTable.previousSubmissionDate
)
: undefined
: null
}
multipleDocumentsAllowed={false}
caption="Rate certification"
Expand All @@ -388,7 +388,7 @@ export const RateDetailsSummarySection = ({
? new Date(
documentDateLookupTable.previousSubmissionDate
)
: undefined
: null
}
caption="Rate supporting documents"
isSupportingDocuments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export const SingleRateSummarySection = ({
const navigate = useNavigate()
const rateRevision = rate.revisions[0]
const formData: RateFormData = rateRevision?.formData
const lastSubmittedDate = rate.revisions[0]?.submitInfo?.updatedAt
const lastSubmittedDate = rate.revisions[0]?.submitInfo?.updatedAt ?? null
const isRateAmendment = formData.rateType === 'AMENDMENT'
const isUnlocked = rate.status === 'UNLOCKED'
const explainMissingData =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ describe('UploadedDocumentsTable', () => {

renderWithProviders(
<UploadedDocumentsTable
previousSubmissionDate={null}
documents={testDocuments}
caption="Contract supporting"
documentCategory="Contract-supporting"
Expand Down Expand Up @@ -217,6 +218,7 @@ describe('UploadedDocumentsTable', () => {
renderWithProviders(
<UploadedDocumentsTable
documents={testDocuments}
previousSubmissionDate={null}
caption="Contract supporting"
documentCategory="Contract-supporting"
isSupportingDocuments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export const convertFromSubmissionDocumentsToGenericDocuments = (
export type UploadedDocumentsTableProps = {
documents: GenericDocument[]
caption: string | null
previousSubmissionDate: Date | null // used to calculate NEW tag based on doc dateAdded
packagesWithSharedRateCerts?: SharedRateCertDisplay[] // deprecated - could be deleted after we resolve all historical data linked rates
previousSubmissionDate?: Date // used to calculate NEW tag based on doc dateAdded
isSupportingDocuments?: boolean // used to calculate empty state and styles around the secondary supporting docs tables - would be nice to remove this in favor of more domain agnostic prop such as 'emptyStateText'
multipleDocumentsAllowed?: boolean // used to determined if we display validations based on doc list length
documentCategory?: string // used to determine if we display document category column
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@ function makeDocumentDateTable(
revisionsLookup: RevisionsLookupType
): DocumentDateLookupTableType {
const lookupTable: DocumentDateLookupTableType = {
previousSubmissionDate: null,
previousSubmissionDate: null, // the last time there was a submission on this package
}
Object.keys(revisionsLookup).forEach(
(revisionId: string, index: number) => {
const listOfRevisionLookups = Object.keys(revisionsLookup)
listOfRevisionLookups.forEach(
(revisionId: string, index) => {
const revision = revisionsLookup[revisionId]
if (index === 1) {
// second most recent revision
const previousSubmission = getDateAdded(revision) // used in UploadedDocumentsTable to determine if we should show NEW tag
if (previousSubmission)
lookupTable['previousSubmissionDate'] = previousSubmission
}

const submitDate = revision.submitInfo?.updatedAt
if (submitDate && (listOfRevisionLookups.length === 1 || index === 1)) { // if we have a package with only one submitted revision, use that - otherwise use whatever in is the 1 index because thats the last submitted
lookupTable['previousSubmissionDate'] = submitDate
}

const allDocuments = getAllDocuments(revision.formData)
allDocuments.forEach((doc) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import {
Column,
createColumnHelper,
getCoreRowModel,
getFacetedUniqueValues,
getFilteredRowModel,
getSortedRowModel,
useReactTable,
} from '@tanstack/react-table'
import { StateAnalystsConfiguration } from '../../../gen/gqlClient'
import { useMemo, useRef } from 'react'
import {
FilterSelect,
FilterSelectedOptionsType,
} from '../../../components/FilterAccordion'
import { DoubleColumnGrid } from '../../../components'
import { formatEmails } from './EmailSettingsTables'
import { Table } from '@trussworks/react-uswds'

import styles from '../Settings.module.scss'
import { pluralize } from '../../../common-code/formatters'

const columnHelper = createColumnHelper<StateAnalystsConfiguration>()

const EmailAnalystsTable = ({
analysts,
}: {
analysts: StateAnalystsConfiguration[]
}) => {
const lastClickedElement = useRef<string | null>(null)
const tableColumns = useMemo(
() => [
columnHelper.accessor('stateCode', {
id: 'stateCode',
header: 'State',
cell: (info) => <span>{info.getValue()}</span>,
filterFn: `arrIncludesSome`,
}),
columnHelper.accessor('emails', {
id: 'emails',
header: 'Emails',
cell: (info) => <span>{info.getValue()}</span>,
filterFn: `arrIncludesSome`,
}),
],
[]
)

const reactTable = useReactTable({
data: analysts.sort((a, b) =>
a['stateCode'] > b['stateCode'] ? -1 : 1
),
filterFns: {
dateRangeFilter: () => true,
},
getCoreRowModel: getCoreRowModel(),
columns: tableColumns,
getFacetedUniqueValues: getFacetedUniqueValues(),
getFilteredRowModel: getFilteredRowModel(),
getSortedRowModel: getSortedRowModel(),
})

const filteredRows = reactTable.getRowModel().rows

const stateColumn = reactTable.getColumn(
'stateCode'
) as Column<StateAnalystsConfiguration>
const emailsColumn = reactTable.getColumn(
'emails'
) as Column<StateAnalystsConfiguration>
const rowCount = `Displaying ${filteredRows.length} of ${analysts.length} ${pluralize(
'analyst',
analysts.length
)}`
const updateFilters = (
column: Column<StateAnalystsConfiguration>,
selectedOptions: FilterSelectedOptionsType,
filterName: string
) => {
lastClickedElement.current = filterName
column.setFilterValue(
selectedOptions.map((selection) => selection.value)
)
}

return (
<>
<h2>State Analyst emails</h2>
<p>
State analysts email settings. Currently a standalone
configuration based on the state programs spreadsheet.
</p>

<DoubleColumnGrid>
<FilterSelect
name="state"
label="State"
filterOptions={Array.from(
stateColumn.getFacetedUniqueValues().keys()
)
.sort()
.map((state) => ({
value: state,
label: state,
}))}
onChange={(selectedOptions) =>
updateFilters(stateColumn, selectedOptions, 'state')
}
/>
<FilterSelect
name="emails"
label="Emails"
filterOptions={Array.from(
emailsColumn.getFacetedUniqueValues().keys()
)
.sort()
.map((state) => ({
value: state,
label: state,
}))}
onChange={(selectedOptions) =>
updateFilters(emailsColumn, selectedOptions, 'emails')
}
/>
</DoubleColumnGrid>
<div className={styles.filterCount}>{rowCount}</div>
<hr />

<Table bordered>
<caption className="srOnly">Analyst emails</caption>
<thead>
<tr>
<th>State</th>
<th>Inbox</th>
</tr>
</thead>
<tbody>
{filteredRows.map((row) => {
return (
<tr key={row.id}>
<td>{row.getValue('stateCode')}</td>
<td>
{formatEmails(row.getValue('emails') || [])}
</td>
</tr>
)
})}
</tbody>
</Table>
</>
)
}
export { EmailAnalystsTable }
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import React from 'react'
import { Loading } from '../../../components'
import {
EmailConfiguration,
StateAnalystsConfiguration,
useFetchEmailSettingsQuery,
} from '../../../gen/gqlClient'
import { SettingsErrorAlert } from '../SettingsErrorAlert'
import styles from '../Settings.module.scss'
import { EmailAnalystsTable } from './EmailAnalystsTable'

const formatEmails = (arr?: string[]) => (arr ? arr.join(',') : 'NOT DEFINED')

export const EmailSettingsTable = ({
const EmailSettingsTable = ({
type,
}: {
type: 'GENERAL' | 'ANALYSTS' | 'SUPPORT'
Expand All @@ -26,20 +26,20 @@ export const EmailSettingsTable = ({
{loading && <Loading />}

{data && config && type === 'GENERAL' && (
<EmailsGeneralTable config={config} />
<EmailGeneralTable config={config} />
)}

{data && analysts && type === 'ANALYSTS' && (
<EmailsAnalystsTable analysts={analysts} />
<EmailAnalystsTable analysts={analysts} />
)}
{data && config && type === 'SUPPORT' && (
<EmailsSupportTable config={config} />
<EmailSupportTable config={config} />
)}
</div>
)
}

const EmailsGeneralTable = ({ config }: { config: EmailConfiguration }) => {
const EmailGeneralTable = ({ config }: { config: EmailConfiguration }) => {
console.info('ALL CONFIG', JSON.stringify(config))
return (
<>
Expand Down Expand Up @@ -98,45 +98,7 @@ const EmailsGeneralTable = ({ config }: { config: EmailConfiguration }) => {
)
}

const EmailsAnalystsTable = ({
analysts,
}: {
analysts: StateAnalystsConfiguration[]
}) => {
return (
<>
<h2>State Analyst emails</h2>
<p>
State analysts email settings. Currently a standalone
configuration based on the state programs spreadsheet.
</p>
<Table bordered>
<caption className="srOnly">Analyst emails</caption>
<thead>
<tr>
<th>Inbox</th>
<th>State</th>
</tr>
</thead>
<tbody>
{analysts &&
analysts.map((analyst, index) => {
return (
<tr key={index}>
<td>
{formatEmails(analyst.emails || [])}
</td>
<td>{analyst.stateCode}</td>
</tr>
)
})}
</tbody>
</Table>
</>
)
}

const EmailsSupportTable = ({ config }: { config: EmailConfiguration }) => {
const EmailSupportTable = ({ config }: { config: EmailConfiguration }) => {
return (
<>
<h2>Support emails</h2>
Expand Down Expand Up @@ -176,3 +138,5 @@ const EmailsSupportTable = ({ config }: { config: EmailConfiguration }) => {
</>
)
}

export { EmailSettingsTable, formatEmails }
4 changes: 4 additions & 0 deletions services/app-web/src/pages/Settings/Settings.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
border-left: 0;
border-right: 0;
}
td {
word-wrap: break-word;
overflow-wrap: break-word;
}
}

table {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const LinkedRateSummary = ({
caption="Rate certification"
documentCategory="Rate certification"
isEditing={false}
previousSubmissionDate={null}
/>
</SectionCard>
)
Expand Down
Loading

0 comments on commit c229c28

Please sign in to comment.