Skip to content

Commit

Permalink
[Page] Resolve Errors & Warnings (#423)
Browse files Browse the repository at this point in the history
closes #333 
closes #401 

## Note (05/02/24)
The `sbl-filing` branch used is `main` -- latest working commit
`0ddf51bd4bd0ab7aefac8cbb02c7797077885620`

branched off
[331-filing-routing_phase2-live-data](#406)

## Changes
- feat(Resolve Errors): Single-Field Errors
- feat(Resolve Errors): Multi-Field Errors
- feat(Resolve Errors): Register-Level Errors
- feat(Resolve Errors): Alerts present depending on errors or no errors
- feat(Resolve Errors): Swappable between Step 1 (Syntax Errors) and
Step 2 (Logical Errors/Register Errors); navigates to `warnings` on Step
2 (no errors)
- enhancement(Upload): added an `enableLongPolling` boolean to
`useGetSubmissionLatest`; default false
- enhancement(Resolve Errors): Implemented 'react-markdown' --
Validation Description
- chore(Resolve Errors): TypeScript handling in
`FilingErrors.helpers.ts`
- [chore(Upload): Hide FilingNavButtons if still
loading](d380708)
- feat(Resolve Errors): if a get submission latest fails, there is an
Alert that pops up


## Next PRs
- Pagination
- Accessibility pass
- Table styling size adjustments
- Download linking the validation report

## How to Test

1. `yarn install` to install `react-markdown`
2. Select an institution and upload with the csv files provided (Syntax
Errors and then Logical/Register Errors)
3. Ensure the right Alert occurs based on the error (or no errors) per
segment
4. Verify all proper data is present per field-level section

#### Test CSV's to use

[all-errors-warnings-no-syntax-errors.csv](https://github.com/cfpb/sbl-frontend/files/15182232/all-errors-warnings-no-syntax-errors.csv)

[sblar_syntax_errors_large.csv](https://github.com/cfpb/sbl-frontend/files/15182233/sblar_syntax_errors_large.csv)

[sblar_syntax_errors.csv](https://github.com/cfpb/sbl-frontend/files/15182234/sblar_syntax_errors.csv)

Note: If Syntax Errors are present, then validation for the logical
errors/warnings do not occur. Hence, why the test CSV's has either
syntax errors or logical errors; not both.

## Screenshots
|Markdown|
|--|
|<img width="602" alt="Screenshot 2024-05-02 at 2 40 05 AM"
src="https://github.com/cfpb/sbl-frontend/assets/13324863/c277389e-46c3-4374-8195-740e3b04b193">|

| SingleFieldErrors | Success | Register-Level |
|--|--|--|
|<img width="411" alt="Screenshot 2024-05-01 at 4 44 52 PM"
src="https://github.com/cfpb/sbl-frontend/assets/13324863/776da07d-7c9a-4dca-9fe9-24e106ac00e2">|<img
width="400" alt="Screenshot 2024-05-01 at 4 45 10 PM"
src="https://github.com/cfpb/sbl-frontend/assets/13324863/4682d70c-52dc-40fb-9f8b-a3e0c72d8247">|<img
width="403" alt="Screenshot 2024-05-01 at 4 45 45 PM"
src="https://github.com/cfpb/sbl-frontend/assets/13324863/c1b6e28e-c6e1-4b1a-902b-b7803aa91f77">|

---------

Co-authored-by: Meis <meissadia@gmail.com>
  • Loading branch information
shindigira and meissadia committed May 6, 2024
1 parent b4e9735 commit 4429fa1
Show file tree
Hide file tree
Showing 23 changed files with 1,074 additions and 352 deletions.
31 changes: 22 additions & 9 deletions src/api/requests/fetchFilingSubmissionLatest.ts
Expand Up @@ -112,7 +112,7 @@ const interceptor = apiClient.interceptors.response.use(
apiClient.defaults.handleStartInterceptorCallback(response);
}
// Retry if validation still in-progress
if (shouldRetry(response)) {
if (apiClient.defaults.enableLongPolling && shouldRetry(response)) {
return retryRequestWithDelay(apiClient, response);
}
apiClient.defaults.retryCount = Zero;
Expand All @@ -124,16 +124,29 @@ const interceptor = apiClient.interceptors.response.use(
},
);

export const fetchFilingSubmissionLatest = async (
auth: SblAuthProperties,
lei: InstitutionDetailsApiType['lei'],
filingPeriod: FilingPeriodType,
interface FetchFilingSubmissionLatestProperties {
auth: SblAuthProperties;
lei: InstitutionDetailsApiType['lei'];
filingPeriod: FilingPeriodType;
handleStartInterceptorCallback?: (
response: AxiosResponse<SubmissionResponse>,
) => void,
signal?: AbortSignal,
// eslint-disable-next-line @typescript-eslint/max-params
): Promise<SubmissionResponse> => {
) => void;
signal?: AbortSignal;
enableLongPolling?: boolean;
}

export const fetchFilingSubmissionLatest = async ({
auth,
lei,
filingPeriod,
handleStartInterceptorCallback,
signal,
enableLongPolling,
}: FetchFilingSubmissionLatestProperties): Promise<SubmissionResponse> => {
if (enableLongPolling) {
apiClient.defaults.enableLongPolling = enableLongPolling;
}

if (handleStartInterceptorCallback) {
apiClient.defaults.handleStartInterceptorCallback =
handleStartInterceptorCallback;
Expand Down
17 changes: 15 additions & 2 deletions src/components/FormButtonGroup.tsx
Expand Up @@ -2,10 +2,23 @@ import type { ReactNode } from 'react';

interface Properties {
children: ReactNode;
isFilingStep?: boolean;
}

function FormButtonGroup({ children }: Properties): JSX.Element {
return <div className='mt-[1.875rem] flex gap-[0.625rem]'>{children}</div>;
function FormButtonGroup({ isFilingStep, children }: Properties): JSX.Element {
return (
<div
className={`mt-[1.875rem] flex ${
isFilingStep ? 'gap-[1.125rem]' : 'gap-[0.625rem]'
}`}
>
{children}
</div>
);
}

FormButtonGroup.defaultProps = {
isFilingStep: false,
};

export default FormButtonGroup;
7 changes: 6 additions & 1 deletion src/components/FormMain.tsx
@@ -1,3 +1,4 @@
import classnames from 'classnames';
import type { ReactNode } from 'react';

interface FormProperties {
Expand All @@ -12,7 +13,11 @@ function FormMain({
children,
className = '',
}: FormProperties & React.ComponentPropsWithoutRef<'form'>): JSX.Element {
return <form className={`mb-[3.75rem] w-full ${className}`}>{children}</form>;
return (
<form className={classnames('w-full', 'mb-[3.75rem]', className)}>
{children}
</form>
);
}

export default FormMain;
9 changes: 7 additions & 2 deletions src/components/SectionIntro.tsx
Expand Up @@ -13,9 +13,14 @@ export interface SectionIntroProperties {
function SectionIntro({
heading = null,
children = '',
}: SectionIntroProperties): JSX.Element {
className,
...other
}: JSX.IntrinsicElements['div'] & SectionIntroProperties): JSX.Element {
return (
<div className='mb-[1.875rem] box-border max-w-[41.875rem]'>
<div
className={`mb-[1.875rem] box-border max-w-[41.875rem] ${className}`}
{...other}
>
{heading ? <Heading type='2'>{heading}</Heading> : null}
<FormParagraph>{children}</FormParagraph>
</div>
Expand Down
27 changes: 26 additions & 1 deletion src/index.css
Expand Up @@ -26,4 +26,29 @@ https://v1.tailwindcss.com/docs/adding-base-styles#using-css */
/* Fixes the issue where too much white space below the footer while zoomed out or when swiping on mobile */
body {
background-color: #f7f8f9;
}
}

/* Uncomment to use ellipsis trick on Review Errors and Warnings tables */

/* td
{
max-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} */


/* Uncomment to make cells width the smallest possible */

/* td:not(:last-child){
white-space: nowrap;
}
td:last-child{
width: 100%;
} */

/* td {
word-break: break-all;
} */
4 changes: 2 additions & 2 deletions src/main.tsx
Expand Up @@ -20,9 +20,9 @@ const MAX_RETRIES = 1;
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: Number.POSITIVE_INFINITY,
// staleTime: Number.POSITIVE_INFINITY,
retry: MAX_RETRIES,
refetchOnWindowFocus: false,
refetchOnWindowFocus: false, // default: true
},
},
});
Expand Down
74 changes: 74 additions & 0 deletions src/pages/Filing/FilingApp/FieldEntry.tsx
@@ -0,0 +1,74 @@
import { Link } from 'components/Link';
import { Heading, Table } from 'design-system-react';
import Markdown from 'react-markdown';
import type { Detail, Field } from 'types/filingTypes';

interface FieldEntryProperties {
fieldObject: Detail;
}

function FieldEntry({ fieldObject }: FieldEntryProperties): JSX.Element {
const validationId = fieldObject.validation.id;
const validationLink = fieldObject.validation.fig_link;
const validationName = fieldObject.validation.name;
const validationDescription = fieldObject.validation.description;
// eslint-disable-next-line unicorn/no-array-reduce
const additionalColumnHeaders = fieldObject.records[0].fields.reduce(
(accumulator: Field['name'][], fieldsObject) => [
...accumulator,
fieldsObject.name,
],
[],
);
const columns = [
'Row',
'Unique identifier (uid)',
...additionalColumnHeaders,
];
const rows = fieldObject.records.map(object => {
// eslint-disable-next-line unicorn/no-array-reduce
const fieldValues = object.fields.reduce(
(accumulator: Field['name'][], fieldsObject) => [
...accumulator,
fieldsObject.value,
],
[],
);
return [object.record_no, object.uid, ...fieldValues];
});

return (
<div className='mb-[2.8125rem]'>
<div className='validation-info-section mb-[1.875rem] max-w-[41.875rem]'>
<Link target='_blank' href={validationLink}>
<Heading type='3'>{validationId}</Heading>
</Link>
<Heading type='4'>{validationName}</Heading>
<Markdown>{validationDescription}</Markdown>
</div>
<Table
className='w-full max-w-full table-auto'
columns={columns}
// rows={[...Array.from({ length: 100 }).keys()].map((item, index) => [
// index + 10_000,
// '4234000O91BZ2SUPERCALIFRAGILISTICEXPIALI45CHARS',
// '4234000O91BZ2SUPERCALIFRAGILISTICEXPIALI45CHARS',
// ])}
// rows={[
// [
// 'Row 1, Column 1',
// 'Row 1, Column 123456789TESTBANK123C2 123456789TESTBANK123C2 123456789TESTBANK123C2 123456789TESTBANK123C2 123456789TESTBANK123C2 123456789TESTBANK123C2',
// 'Row 1, Column 3 123456789TESTBANK123C2123456789TESTBANK123C2123456789TESTBANK123C2123456789TESTBANK123C2',
// ],
// ['Row 2, Column 1', 'Row 2, Column 2', 'Row 2, Column 3'],
// ['Row 3, Column 1', 'Row 3, Column 2', 'Row 3, Column 3'],
// ]}
// @ts-expect-error TypeScript error needs to be resolved within DSR
rows={rows}
isScrollableHorizontal
/>
</div>
);
}

export default FieldEntry;
35 changes: 35 additions & 0 deletions src/pages/Filing/FilingApp/FieldSummary.tsx
@@ -0,0 +1,35 @@
import SectionIntro from 'components/SectionIntro';
import FieldEntry from 'pages/Filing/FilingApp/FieldEntry';
import type { ReactNode } from 'react';
import type { Detail } from 'types/filingTypes';

interface FieldProperties {
fieldArray: Detail[];
heading: string;
bottomMargin?: boolean;
children: ReactNode;
id: string;
}

function FieldSummary({
heading,
fieldArray,
bottomMargin,
children,
id,
}: FieldProperties): JSX.Element {
return (
<div id={id} className={bottomMargin ? 'mb-[3.75rem]' : ''}>
<SectionIntro heading={heading}>{children}</SectionIntro>
{fieldArray.map(fieldObject => (
<FieldEntry key={fieldObject.validation.id} fieldObject={fieldObject} />
))}
</div>
);
}

FieldSummary.defaultProps = {
bottomMargin: false,
};

export default FieldSummary;
2 changes: 2 additions & 0 deletions src/pages/Filing/FilingApp/FileSubmission.data.tsx
Expand Up @@ -83,6 +83,7 @@ export function IncorrectFileTypeAlert(): JSX.Element {
export const fileSubmissionStateAlert: Record<
Exclude<
FileSubmissionState,
| FileSubmissionState.SUBMISSION_STARTED
| FileSubmissionState.SUBMISSION_UPLOADED
| FileSubmissionState.VALIDATION_IN_PROGRESS
>,
Expand Down Expand Up @@ -122,6 +123,7 @@ export const fileSubmissionStateAlert: Record<
export const fileSubmissionValidationStatus: Record<
Exclude<
FileSubmissionState,
| FileSubmissionState.SUBMISSION_STARTED
| FileSubmissionState.SUBMISSION_UPLOADED
| FileSubmissionState.UPLOAD_FAILED
| FileSubmissionState.VALIDATION_IN_PROGRESS
Expand Down

0 comments on commit 4429fa1

Please sign in to comment.