Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/components/CommonLinks.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { Link } from 'components/Link';
import { Button } from 'design-system-react';
import type { ReactElement } from 'react';
import type { ComponentProps, ReactElement } from 'react';
import { useNavigate, useParams } from 'react-router-dom';

function GLIEF(): ReactElement {
return <Link href='https://www.gleif.org/'>GLEIF</Link>;
function GLIEF(arguments_: ComponentProps<typeof Link>): ReactElement {
return (
<Link href='https://www.gleif.org/' {...arguments_}>
GLEIF
</Link>
);
}

function GetAnLEI(): ReactElement {
Expand Down
19 changes: 15 additions & 4 deletions src/components/InputEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { Element } from 'react-scroll';

import InputErrorMessage from 'components/InputErrorMessage';
import LabelOptional from 'components/LabelOptional';
import { Heading } from 'design-system-react';
import { TextInput } from 'components/TextInput';
import { DisplayField } from 'pages/Filing/ViewInstitutionProfile/DisplayField';
import { Heading } from 'design-system-react';
import type { InputType } from 'design-system-react/dist/components/TextInput/TextInput';
import type { DisplayFieldProperties } from 'pages/Filing/ViewInstitutionProfile/DisplayField';
import { DisplayField } from 'pages/Filing/ViewInstitutionProfile/DisplayField';

interface InputEntryProperties extends ComponentPropsWithoutRef<'input'> {
id: string;
Expand All @@ -24,7 +25,10 @@ interface InputEntryProperties extends ComponentPropsWithoutRef<'input'> {
helperText?: string;
}

const InputEntry = forwardRef<HTMLInputElement, InputEntryProperties>(
const InputEntry = forwardRef<
HTMLInputElement,
DisplayFieldProperties & InputEntryProperties
>(
(
{
className = '',
Expand All @@ -40,6 +44,7 @@ const InputEntry = forwardRef<HTMLInputElement, InputEntryProperties>(
isOptional = false,
type = 'text',
helperText,
fallbackValue,
...properties
},
reference,
Expand Down Expand Up @@ -78,7 +83,13 @@ const InputEntry = forwardRef<HTMLInputElement, InputEntryProperties>(
/>
</>
)}
{hideInput ? <DisplayField label={label} value={children} /> : null}
{hideInput ? (
<DisplayField
label={label}
value={children}
fallbackValue={fallbackValue}
/>
) : null}
{handleError ? (
<div>
<InputErrorMessage>{errorMessage}</InputErrorMessage>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { ReactNode } from 'react';
import type { InstitutionDetailsApiType } from 'types/formTypes';
import InstitutionDataLabels from '../formHelpers';
import './AffiliateInformation.less';
import { DisplayField } from './DisplayField';
import { DisplayField, NOT_APPLICABLE } from './DisplayField';

const defaultDescription = (
<>
Expand Down Expand Up @@ -41,7 +41,8 @@ export function AffiliateInformation({
/>
<DisplayField
label={InstitutionDataLabels.lei}
value={data.parent_lei}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
value={data.parent_lei || NOT_APPLICABLE}
/>
<DisplayField
label={InstitutionDataLabels.rssd}
Expand All @@ -58,7 +59,8 @@ export function AffiliateInformation({
/>
<DisplayField
label={InstitutionDataLabels.lei}
value={data.top_holder_lei}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
value={data.top_holder_lei || NOT_APPLICABLE}
/>
<DisplayField
label={InstitutionDataLabels.rssd}
Expand Down
54 changes: 51 additions & 3 deletions src/pages/Filing/ViewInstitutionProfile/DisplayField.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,49 @@
import classNames from 'classnames';
import { Heading } from 'design-system-react';
import CommonLinks from 'components/CommonLinks';
import { AlertFieldLevel, Heading, Link } from 'design-system-react';
import type { ReactNode } from 'react';
import { useParams } from 'react-router-dom';
import InstitutionDataLabels from '../formHelpers';
import './DisplayField.less';

export const NOT_AVAILABLE = 'Not available';
export const NOT_APPLICABLE = 'Not applicable';
export const NOT_PROVIDED = 'Not provided';
export const LAPSED = 'Lapsed';

function LinkUpdateInstitutionProfile(): JSX.Element {
const { lei } = useParams();

return (
<Link href={`/institution/${lei}/update`}>
update your financial institution profile
</Link>
);
}

const NotProvidedAlertMessage = {
[InstitutionDataLabels.leiStatus]: (
<p>
Your financial institution must have an active LEI to file. Visit{' '}
<CommonLinks.GLIEF isExternalLink={false} /> for instructions on how to
reactivate your LEI or{' '}
<CommonLinks.EmailSupportStaff subject='Reactivating an LEI' /> for
assistance.
</p>
),
[InstitutionDataLabels.tin]: (
<p>
You must provide your TIN to file. Visit <LinkUpdateInstitutionProfile />{' '}
for instructions on how to update this information.
</p>
),
[InstitutionDataLabels.fiType]: (
<p>
You must provide your type of financial institution to file. Visit{' '}
<LinkUpdateInstitutionProfile /> to provide this information.
</p>
),
};

export interface DisplayFieldProperties {
label?: ReactNode;
Expand All @@ -18,21 +58,29 @@ export function DisplayField({
className,
fallbackValue,
}: DisplayFieldProperties): JSX.Element {
const resultingValue = value ?? fallbackValue;
const showAlert = [LAPSED, NOT_PROVIDED].includes(resultingValue as string);

return (
<div className={classNames('display-field', className)}>
{label ? (
<Heading className='h4 break-all' type='3'>
{label}
</Heading>
) : undefined}
<p className='u-mt10 break-all'>{value ?? fallbackValue}</p>
<p className='u-mt10 break-all'>{resultingValue}</p>
<AlertFieldLevel
status='warning'
isVisible={showAlert}
message={NotProvidedAlertMessage[label as string]}
/>
</div>
);
}

DisplayField.defaultProps = {
className: undefined,
fallbackValue: NOT_AVAILABLE,
fallbackValue: NOT_APPLICABLE,
label: undefined,
value: undefined,
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { valueOrNotavailable } from 'utils/formatting';
import { FormSectionWrapper } from '../../../components/FormSectionWrapper';
import InstitutionDataLabels from '../formHelpers';
import AddressStreetOptional from './AddressStreetOptional';
import { DisplayField, NOT_AVAILABLE } from './DisplayField';
import { DisplayField, LAPSED, NOT_AVAILABLE } from './DisplayField';

export const formatDomains = (domains?: Domain[]): string => {
if (!domains || domains.length === 0) return NOT_AVAILABLE;
Expand Down Expand Up @@ -76,11 +76,7 @@ export function FinancialInstitutionDetails({
<DisplayField label={InstitutionDataLabels.lei} value={data.lei} />
<DisplayField
label={InstitutionDataLabels.leiStatus}
value={
<span className='capitalize'>
{data.is_active ? 'Active' : 'Inactive'}
</span>
}
value={data.is_active ? 'Issued' : LAPSED}
/>
{isDomainsVisible ? (
<DisplayField
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import SectionIntro from 'components/SectionIntro';
import { WellContainer } from 'design-system-react';
import type { ReactNode } from 'react';
import type { InstitutionDetailsApiType } from 'types/formTypes';
import { formatFederalRegulator, valueOrNotavailable } from 'utils/formatting';
import { formatFederalRegulator } from 'utils/formatting';
import InstitutionDataLabels from '../formHelpers';
import { DisplayField } from './DisplayField';
import { DisplayField, NOT_PROVIDED } from './DisplayField';

const defaultDescription = (
<>
Expand All @@ -29,7 +29,7 @@ export function IdentifyingInformation({
}): JSX.Element {
// TODO: Asking Le about 'Other' institution type/detail in mock data and the ending period
// https://github.com/cfpb/sbl-frontend/issues/137
const institutionTypeNamesArray = data.sbl_institution_types.map(
const institutionTypeNamesArray = data.sbl_institution_types?.map(
institutionType => {
let name = '';
if (typeof institutionType === 'string') name = institutionType;
Expand All @@ -45,16 +45,18 @@ export function IdentifyingInformation({
},
);

const institutionTypeNamesString = valueOrNotavailable(
institutionTypeNamesArray.join(', '),
);
const institutionTypeNamesString = institutionTypeNamesArray?.join(', ');

return (
<FormSectionWrapper>
<SectionIntro heading={heading}>{description}</SectionIntro>

<WellContainer className='u-mt30'>
<DisplayField label={InstitutionDataLabels.tin} value={data.tax_id} />
<DisplayField
label={InstitutionDataLabels.tin}
value={data.tax_id}
fallbackValue={NOT_PROVIDED}
/>
<DisplayField label={InstitutionDataLabels.rssd} value={data.rssd_id} />
<DisplayField
label={InstitutionDataLabels.regName}
Expand All @@ -70,6 +72,7 @@ export function IdentifyingInformation({
<DisplayField
label={InstitutionDataLabels.fiType}
value={institutionTypeNamesString}
fallbackValue={NOT_PROVIDED}
/>
</WellContainer>
</FormSectionWrapper>
Expand Down
7 changes: 5 additions & 2 deletions src/utils/formatting.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { NOT_AVAILABLE } from 'pages/Filing/ViewInstitutionProfile/DisplayField';
import {
NOT_APPLICABLE,
NOT_AVAILABLE,
} from 'pages/Filing/ViewInstitutionProfile/DisplayField';
import type { DomainType, InstitutionDetailsApiType } from 'types/formTypes';

export const buildEmailDomainString = (
Expand All @@ -19,4 +22,4 @@ export const formatFederalRegulator = (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
data.primary_federal_regulator
? `${data.primary_federal_regulator.name} (${data.primary_federal_regulator.id})`
: NOT_AVAILABLE;
: NOT_APPLICABLE;
2 changes: 1 addition & 1 deletion src/utils/useHeaderAuthLinks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const useHeaderAuthLinks = (): ReactElement[] => {
'User profile'}
</span>
</NavLink>,
<Button label='LOG OUT' asLink onClick={onLogout} />,
<Button key='logout' label='LOG OUT' asLink onClick={onLogout} />,
);
}

Expand Down