Skip to content

Commit

Permalink
PSP-8320 Update Lease button location (#4338)
Browse files Browse the repository at this point in the history
* Add common component for custom section headers

* PSP-8320 Update Lease Button Location

* Test updates
  • Loading branch information
asanchezr authored Sep 17, 2024
1 parent 1900888 commit f7e8aa7
Show file tree
Hide file tree
Showing 13 changed files with 845 additions and 182 deletions.
56 changes: 56 additions & 0 deletions source/frontend/src/components/common/SimpleSectionHeader.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';

import { render, RenderOptions, screen } from '@/utils/test-utils';

import { ISimpleSectionHeaderProps, SimpleSectionHeader } from './SimpleSectionHeader';
import { StyledAddButton } from './styles';
import { FaMoneyCheck } from 'react-icons/fa';

describe('SimpleSectionHeader component', () => {
// render component under test
const setup = (
renderOptions: RenderOptions & {
props?: Partial<React.PropsWithChildren<ISimpleSectionHeaderProps>>;
} = {},
) => {
const utils = render(
<SimpleSectionHeader
title={renderOptions?.props?.title ?? 'TEST TITLE'}
className={renderOptions?.props?.className ?? ''}
>
{renderOptions?.props?.children ?? null}
</SimpleSectionHeader>,
{
...renderOptions,
},
);

return { ...utils };
};

it('renders as expected', () => {
const { asFragment } = setup();
expect(asFragment()).toMatchSnapshot();
});

it('displays the header title', () => {
setup({ props: { title: 'LOREM IPSUM' } });
expect(screen.getByText('LOREM IPSUM')).toBeVisible();
});

it('renders children sub-components on the right end of the header', () => {
setup({
props: {
title: 'LOREM IPSUM',
children: (
<StyledAddButton>
<FaMoneyCheck className="mr-2" />
Generate
</StyledAddButton>
),
},
});

expect(screen.getByText('Generate')).toBeVisible();
});
});
43 changes: 43 additions & 0 deletions source/frontend/src/components/common/SimpleSectionHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import clsx from 'classnames';
import React from 'react';
import { Col, Row } from 'react-bootstrap';
import styled from 'styled-components';

import { exists } from '@/utils';

export interface ISimpleSectionHeaderProps {
title: string;
className?: string;
}

/**
* Simple section header that takes a section title and optional children components.
* If children components are supplied, they will be rendered on the right end of the header.
* @param props customize the component by passing a title and optional class-name to modify the default component styling.
* @returns The header component
*/
export const SimpleSectionHeader: React.FunctionComponent<
React.PropsWithChildren<ISimpleSectionHeaderProps>
> = ({ title, className, children }) => {
return (
<StyledRow className={clsx('no-gutters', className)}>
<Col xs="auto" className="d-flex justify-content-start px-2 my-1">
{title ?? ''}
</Col>
{exists(children) && (
<Col xs="auto" className="d-flex justify-content-end my-1">
{children}
</Col>
)}
</StyledRow>
);
};

const StyledRow = styled(Row)`
justify-content: space-between;
align-items: end;
min-height: 4.5rem;
.btn {
margin: 0;
}
`;
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { screen } from '@testing-library/react';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { createMemoryHistory } from 'history';

import { mockLookups } from '@/mocks/lookups.mock';
import { lookupCodesSlice } from '@/store/slices/lookupCodes';
import { render, RenderOptions, waitFor } from '@/utils/test-utils';
import { render, RenderOptions, waitFor, screen } from '@/utils/test-utils';

import { IUserNameTooltipProps, UserNameTooltip } from './UserNameTooltip';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`SimpleSectionHeader component > renders as expected 1`] = `
<DocumentFragment>
<div
class="Toastify"
/>
<div />
.c0 {
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-align-items: end;
-webkit-box-align: end;
-ms-flex-align: end;
align-items: end;
min-height: 4.5rem;
}
.c0 .btn {
margin: 0;
}
<div
class="c0 no-gutters row"
>
<div
class="d-flex justify-content-start px-2 my-1 col-auto"
>
TEST TITLE
</div>
</div>
</DocumentFragment>
`;
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { FormikProps } from 'formik/dist/types';
import React, { useCallback, useContext } from 'react';

import { ProtectedComponent } from '@/components/common/ProtectedComponent';
import { Claims } from '@/constants/claims';
import { LeaseStateContext } from '@/features/leases/context/LeaseContext';
import { UpdateLeaseContainer } from '@/features/leases/detail/LeasePages/details/UpdateLeaseContainer';
import { LeaseFormModel } from '@/features/leases/models';
import { useGenerateLicenceOfOccupation } from '@/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateLicenceOfOccupation';
import { LeasePageProps } from '@/features/mapSideBar/lease/LeaseContainer';
import { ApiGen_Concepts_Lease } from '@/models/api/generated/ApiGen_Concepts_Lease';
import { exists } from '@/utils';

import LeaseDetailsForm from './LeaseDetailsForm';
import UpdateLeaseForm from './UpdateLeaseForm';
Expand All @@ -14,6 +19,18 @@ const DetailContainer: React.FunctionComponent<React.PropsWithChildren<LeasePage
onEdit,
formikRef,
}) => {
const { lease } = useContext(LeaseStateContext);
const generateLicenceOfOccupation = useGenerateLicenceOfOccupation();

const onGenerate = useCallback(
(lease?: ApiGen_Concepts_Lease) => {
if (exists(lease)) {
generateLicenceOfOccupation(lease);
}
},
[generateLicenceOfOccupation],
);

return !!isEditing && !!onEdit ? (
<ProtectedComponent claims={[Claims.LEASE_EDIT]}>
<UpdateLeaseContainer
Expand All @@ -23,7 +40,7 @@ const DetailContainer: React.FunctionComponent<React.PropsWithChildren<LeasePage
/>
</ProtectedComponent>
) : (
<LeaseDetailsForm />
<LeaseDetailsForm lease={lease} onGenerate={onGenerate} />
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,76 @@
import { Col, Row } from 'react-bootstrap';
import { FaFileContract } from 'react-icons/fa';

import { Section } from '@/components/common/Section/Section';
import { SectionField } from '@/components/common/Section/SectionField';
import { SimpleSectionHeader } from '@/components/common/SimpleSectionHeader';
import { StyledAddButton } from '@/components/common/styles';
import TooltipIcon from '@/components/common/TooltipIcon';
import { Claims } from '@/constants';
import { useKeycloakWrapper } from '@/hooks/useKeycloakWrapper';
import { ApiGen_CodeTypes_LeaseLicenceTypes } from '@/models/api/generated/ApiGen_CodeTypes_LeaseLicenceTypes';
import { ApiGen_CodeTypes_LeaseStatusTypes } from '@/models/api/generated/ApiGen_CodeTypes_LeaseStatusTypes';
import { ApiGen_Concepts_Lease } from '@/models/api/generated/ApiGen_Concepts_Lease';
import { exists, prettyFormatDate } from '@/utils';

export interface ILeaseDetailView {
export interface ILeaseDetailViewProps {
lease: ApiGen_Concepts_Lease;
onGenerate: (lease?: ApiGen_Concepts_Lease) => void;
}

/**
* Sub-form displaying the original and renewal period information presented in styled boxes.
* @param {ILeaseDetailView} param0
* @param {ILeaseDetailViewProps} param0
*/
export const LeaseDetailView: React.FunctionComponent<
React.PropsWithChildren<ILeaseDetailView>
> = ({ lease }) => {
const projectName = lease.project ? `${lease.project.code} - ${lease.project.description}` : '';
React.PropsWithChildren<ILeaseDetailViewProps>
> = ({ lease, onGenerate }) => {
const { hasClaim } = useKeycloakWrapper();

const projectName = exists(lease?.project)
? `${lease?.project?.code} - ${lease?.project?.description}`
: '';

const productName = exists(lease?.product)
? lease?.product?.code + ' ' + lease?.product?.description
: '';

const leaseTypeCode = exists(lease?.type?.id) ? lease?.type?.id : null;

return (
<Section header="Details">
<Section
header={
<SimpleSectionHeader title="Details">
{hasClaim(Claims.LEASE_VIEW) &&
exists(leaseTypeCode) &&
leaseTypeCode === ApiGen_CodeTypes_LeaseLicenceTypes.LOOBCTFA && (
<StyledAddButton onClick={() => onGenerate(lease)}>
<FaFileContract
size={24}
id={`generate-h1005-a`}
title="Generate H1005(a)"
className="mr-2"
/>
Generate H1005(a)
</StyledAddButton>
)}

{hasClaim(Claims.LEASE_VIEW) &&
exists(leaseTypeCode) &&
leaseTypeCode === ApiGen_CodeTypes_LeaseLicenceTypes.LIPPUBHWY && (
<StyledAddButton onClick={() => onGenerate(lease)}>
<FaFileContract
size={24}
id={`generate-h1005`}
title="Generate H1005"
className="mr-2"
/>
Generate H1005
</StyledAddButton>
)}
</SimpleSectionHeader>
}
>
<SectionField label="Ministry project" labelWidth="3">
{projectName}
</SectionField>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import noop from 'lodash/noop';
import React from 'react';
import styled from 'styled-components';

import { LeaseStateContext } from '@/features/leases/context/LeaseContext';
import { ApiGen_Concepts_Lease } from '@/models/api/generated/ApiGen_Concepts_Lease';
import { defaultApiLease } from '@/models/defaultInitializers';
import { exists } from '@/utils';

Expand All @@ -13,8 +13,15 @@ import LeaseDetailView from './LeaseDetailView';
import { LeaseRenewalsView } from './LeaseRenewalsView';
import PropertiesInformation from './PropertiesInformation';

export const LeaseDetailsForm: React.FunctionComponent<React.PropsWithChildren<unknown>> = () => {
const { lease } = React.useContext(LeaseStateContext);
export interface ILeaseDetailsFormProps {
lease?: ApiGen_Concepts_Lease;
onGenerate: (lease?: ApiGen_Concepts_Lease) => void;
}

export const LeaseDetailsForm: React.FunctionComponent<ILeaseDetailsFormProps> = ({
lease,
onGenerate,
}) => {
if (!exists(lease)) {
return <></>;
}
Expand All @@ -26,7 +33,7 @@ export const LeaseDetailsForm: React.FunctionComponent<React.PropsWithChildren<u
onSubmit={noop}
>
<StyledDetails>
<LeaseDetailView lease={lease} />
<LeaseDetailView lease={lease} onGenerate={onGenerate} />
<LeaseRenewalsView renewals={lease.renewals} />
<PropertiesInformation disabled={true} />
<DetailAdministration disabled={true} />
Expand Down
Loading

0 comments on commit f7e8aa7

Please sign in to comment.