-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: ✨adds CAN Spending page BLI Table (#3029)
* refactor: simplify CAN Detail prefer parent to do the hard work * style: update breadcrumb for CANs * refactor: add BLIs for table * feat: adds CanBudgetLines Table and Row * feat: filter CAN BLIs by fiscal year * feat: adds Expandable Row * feat: adds messages to in_review BLI * feat: adds notes
- Loading branch information
Showing
12 changed files
with
483 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
frontend/src/components/CANs/CANBudgetLineTable/CABBudgetLineTable.constants.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const TABLE_HEADERS = ["BL ID #", "Agreement", "Obligate By", "FY", "Total", "% of CAN", "Status"]; |
50 changes: 50 additions & 0 deletions
50
frontend/src/components/CANs/CANBudgetLineTable/CANBudgetLineTable.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { formatDateNeeded } from "../../../helpers/utils"; | ||
import Table from "../../UI/Table"; | ||
import { TABLE_HEADERS } from "./CABBudgetLineTable.constants"; | ||
import CANBudgetLineTableRow from "./CANBudgetLineTableRow"; | ||
/** | ||
* @typedef {import("../../../components/BudgetLineItems/BudgetLineTypes").BudgetLine} BudgetLine | ||
*/ | ||
|
||
/** | ||
* @typedef {Object} CANBudgetLineTableProps | ||
* @property {BudgetLine[]} budgetLines | ||
*/ | ||
|
||
/** | ||
* @component - The CAN Budget Line Table. | ||
* @param {CANBudgetLineTableProps} props | ||
* @returns {JSX.Element} - The component JSX. | ||
*/ | ||
const CANBudgetLineTable = ({ budgetLines }) => { | ||
if (budgetLines.length === 0) { | ||
return <p className="text-center">No budget lines have been added to this CAN.</p>; | ||
} | ||
|
||
return ( | ||
<Table tableHeadings={TABLE_HEADERS}> | ||
{budgetLines.map((budgetLine) => ( | ||
<CANBudgetLineTableRow | ||
key={budgetLine.id} | ||
budgetLine={budgetLine} | ||
blId={budgetLine.id} | ||
agreementName="TBD" | ||
obligateDate={formatDateNeeded(budgetLine.date_needed || "")} | ||
fiscalYear={budgetLine.fiscal_year || "TBD"} | ||
amount={budgetLine.amount || 0} | ||
fee={budgetLine.proc_shop_fee_percentage} | ||
percentOfCAN={3} | ||
status={budgetLine.status} | ||
inReview={budgetLine.in_review} | ||
creatorId={budgetLine.created_by} | ||
creationDate={budgetLine.created_on} | ||
procShopCode="TBD" | ||
procShopFeePercentage={budgetLine.proc_shop_fee_percentage} | ||
notes={budgetLine.comments || "No Notes added"} | ||
/> | ||
))} | ||
</Table> | ||
); | ||
}; | ||
|
||
export default CANBudgetLineTable; |
33 changes: 33 additions & 0 deletions
33
frontend/src/components/CANs/CANBudgetLineTable/CANBudgetLineTable.test.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { render, screen } from "@testing-library/react"; | ||
import { Provider } from "react-redux"; | ||
import CANBudgetLineTable from "./CANBudgetLineTable"; | ||
import store from "../../../store"; | ||
import { budgetLine } from "../../../tests/data"; | ||
|
||
describe("CANBudgetLineTable", () => { | ||
const mockBudgetLines = [ | ||
{ ...budgetLine, status: "Approved", amount: 1000 }, | ||
{ ...budgetLine, status: "Pending", amount: 2000 } | ||
]; | ||
|
||
it("renders 'No budget lines have been added to this CAN.' when there are no budget lines", () => { | ||
render( | ||
<Provider store={store}> | ||
<CANBudgetLineTable budgetLines={[]} /> | ||
</Provider> | ||
); | ||
expect(screen.getByText("No budget lines have been added to this CAN.")).toBeInTheDocument(); | ||
}); | ||
|
||
it("renders table with budget lines", () => { | ||
render( | ||
<Provider store={store}> | ||
<CANBudgetLineTable budgetLines={mockBudgetLines} /> | ||
</Provider> | ||
); | ||
expect(screen.getByText("Approved")).toBeInTheDocument(); | ||
expect(screen.getByText("Pending")).toBeInTheDocument(); | ||
expect(screen.getByText("$1,000.00")).toBeInTheDocument(); | ||
expect(screen.getByText("$2,000.00")).toBeInTheDocument(); | ||
}); | ||
}); |
225 changes: 225 additions & 0 deletions
225
frontend/src/components/CANs/CANBudgetLineTable/CANBudgetLineTableRow.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
import { faClock } from "@fortawesome/free-regular-svg-icons"; | ||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||
import CurrencyFormat from "react-currency-format"; | ||
import { | ||
formatDateToMonthDayYear, | ||
totalBudgetLineAmountPlusFees, | ||
totalBudgetLineFeeAmount | ||
} from "../../../helpers/utils"; | ||
import useGetUserFullNameFromId from "../../../hooks/user.hooks"; | ||
import TableRowExpandable from "../../UI/TableRowExpandable"; | ||
import { | ||
changeBgColorIfExpanded, | ||
expandedRowBGColor, | ||
removeBorderBottomIfExpanded | ||
} from "../../UI/TableRowExpandable/TableRowExpandable.helpers"; | ||
import { useTableRow } from "../../UI/TableRowExpandable/TableRowExpandable.hooks"; | ||
import TableTag from "../../UI/TableTag"; | ||
import { useChangeRequestsForTooltip } from "../../../hooks/useChangeRequests.hooks"; | ||
|
||
/** | ||
* @typedef {import("../../../components/BudgetLineItems/BudgetLineTypes").BudgetLine} BudgetLine | ||
*/ | ||
|
||
/** | ||
* @typedef {Object} CANBudgetLineTableRowProps | ||
* @property {BudgetLine} budgetLine | ||
* @property {number} blId | ||
* @property {string} agreementName - TODO | ||
* @property {string} obligateDate | ||
* @property {number | string } fiscalYear | ||
* @property {number} amount | ||
* @property {number} fee | ||
* @property {number} percentOfCAN - TODO | ||
* @property {string} status | ||
* @property {boolean} inReview | ||
* @property {number} creatorId | ||
* @property {string} creationDate | ||
* @property {string} procShopCode - TODO | ||
* @property {number} procShopFeePercentage | ||
* @property {string} notes | ||
*/ | ||
|
||
/** | ||
* @component - The CAN Budget Line Table. | ||
* @param {CANBudgetLineTableRowProps} props | ||
* @returns {JSX.Element} - The component JSX. | ||
*/ | ||
const CANBudgetLineTableRow = ({ | ||
budgetLine, | ||
blId, | ||
agreementName, | ||
obligateDate, | ||
fiscalYear, | ||
amount, | ||
fee, | ||
percentOfCAN, | ||
status, | ||
inReview, | ||
creatorId, | ||
creationDate, | ||
procShopCode, | ||
procShopFeePercentage, | ||
notes | ||
}) => { | ||
const lockedMessage = useChangeRequestsForTooltip(budgetLine); | ||
const { isExpanded, setIsRowActive, setIsExpanded } = useTableRow(); | ||
const borderExpandedStyles = removeBorderBottomIfExpanded(isExpanded); | ||
const bgExpandedStyles = changeBgColorIfExpanded(isExpanded); | ||
const budgetLineCreatorName = useGetUserFullNameFromId(creatorId); | ||
const feeTotal = totalBudgetLineFeeAmount(amount, fee); | ||
const budgetLineTotalPlusFees = totalBudgetLineAmountPlusFees(amount, feeTotal); | ||
const displayCreatedDate = formatDateToMonthDayYear(creationDate); | ||
|
||
const TableRowData = ( | ||
<> | ||
<th | ||
scope="row" | ||
className={borderExpandedStyles} | ||
style={bgExpandedStyles} | ||
> | ||
{blId} | ||
</th> | ||
<td | ||
className={borderExpandedStyles} | ||
style={bgExpandedStyles} | ||
> | ||
{agreementName} | ||
</td> | ||
<td | ||
className={borderExpandedStyles} | ||
style={bgExpandedStyles} | ||
> | ||
{obligateDate} | ||
</td> | ||
<td | ||
className={borderExpandedStyles} | ||
style={bgExpandedStyles} | ||
> | ||
{fiscalYear} | ||
</td> | ||
<td | ||
className={borderExpandedStyles} | ||
style={bgExpandedStyles} | ||
> | ||
<CurrencyFormat | ||
value={budgetLineTotalPlusFees} | ||
displayType={"text"} | ||
thousandSeparator={true} | ||
prefix={"$"} | ||
decimalScale={2} | ||
fixedDecimalScale={true} | ||
/> | ||
</td> | ||
<td | ||
className={borderExpandedStyles} | ||
style={bgExpandedStyles} | ||
> | ||
{percentOfCAN}% | ||
</td> | ||
<td | ||
className={borderExpandedStyles} | ||
style={bgExpandedStyles} | ||
> | ||
<TableTag | ||
status={status} | ||
inReview={inReview} | ||
lockedMessage={lockedMessage} | ||
/> | ||
</td> | ||
</> | ||
); | ||
|
||
const ExpandedData = ( | ||
<td | ||
colSpan={9} | ||
className="border-top-none" | ||
style={expandedRowBGColor} | ||
> | ||
<div className="display-flex padding-right-9"> | ||
<dl className="font-12px"> | ||
<dt className="margin-0 text-base-dark">Created By</dt> | ||
<dd | ||
id={`created-by-name-${blId}`} | ||
className="margin-0" | ||
> | ||
{budgetLineCreatorName} | ||
</dd> | ||
<dt className="margin-0 text-base-dark display-flex flex-align-center margin-top-2"> | ||
<FontAwesomeIcon | ||
icon={faClock} | ||
className="height-2 width-2 margin-right-1" | ||
/> | ||
{displayCreatedDate} | ||
</dt> | ||
</dl> | ||
<dl | ||
className="font-12px" | ||
style={{ marginLeft: "9.0625rem" }} | ||
> | ||
<dt className="margin-0 text-base-dark">Notes</dt> | ||
<dd | ||
className="margin-0" | ||
style={{ maxWidth: "25rem" }} | ||
> | ||
{notes} | ||
</dd> | ||
</dl> | ||
<div | ||
className="font-12px" | ||
style={{ marginLeft: "15rem" }} | ||
> | ||
<dl className="margin-bottom-0"> | ||
<dt className="margin-0 text-base-dark">Procurement Shop</dt> | ||
<dd | ||
className="margin-0" | ||
style={{ maxWidth: "25rem" }} | ||
> | ||
{`${procShopCode}-Fee Rate: ${procShopFeePercentage * 100}%`} | ||
</dd> | ||
</dl> | ||
<div className="font-12px display-flex margin-top-1"> | ||
<dl className="margin-0"> | ||
<dt className="margin-0 text-base-dark">SubTotal</dt> | ||
<dd className="margin-0"> | ||
<CurrencyFormat | ||
value={amount} | ||
displayType={"text"} | ||
thousandSeparator={true} | ||
prefix={"$"} | ||
decimalScale={2} | ||
fixedDecimalScale={true} | ||
/> | ||
</dd> | ||
</dl> | ||
<dl className=" margin-0 margin-left-2"> | ||
<dt className="margin-0 text-base-dark">Fees</dt> | ||
<dd className="margin-0"> | ||
<CurrencyFormat | ||
value={feeTotal} | ||
displayType={"text"} | ||
thousandSeparator={true} | ||
prefix={"$"} | ||
decimalScale={2} | ||
fixedDecimalScale={true} | ||
/> | ||
</dd> | ||
</dl> | ||
</div> | ||
</div> | ||
</div> | ||
</td> | ||
); | ||
|
||
return ( | ||
<TableRowExpandable | ||
tableRowData={TableRowData} | ||
expandedData={ExpandedData} | ||
isExpanded={isExpanded} | ||
setIsExpanded={setIsExpanded} | ||
setIsRowActive={setIsRowActive} | ||
/> | ||
); | ||
}; | ||
|
||
export default CANBudgetLineTableRow; |
Oops, something went wrong.