Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: displays CAN obligate_by as MM/DD/YY #2873

Merged
merged 4 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
64 changes: 33 additions & 31 deletions backend/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -291,11 +291,11 @@ paths:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateUpdateCANRequestSchema"
examples:
"0":
$ref: "#/components/examples/CreateUpdateCANRequestSchema"
schema:
$ref: "#/components/schemas/CreateUpdateCANRequestSchema"
examples:
"0":
$ref: "#/components/examples/CreateUpdateCANRequestSchema"
responses:
"200":
description: CAN Updated
Expand Down Expand Up @@ -329,11 +329,11 @@ paths:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateUpdateCANRequestSchema"
examples:
"0":
$ref: "#/components/examples/CreateUpdateCANRequestSchema"
schema:
$ref: "#/components/schemas/CreateUpdateCANRequestSchema"
examples:
"0":
$ref: "#/components/examples/CreateUpdateCANRequestSchema"
responses:
"200":
description: CAN Updated
Expand Down Expand Up @@ -391,11 +391,11 @@ paths:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateUpdateCANFundingBudgetRequest"
examples:
"0":
$ref: "#/components/examples/CreateUpdateCANFundingBudgetRequest"
schema:
$ref: "#/components/schemas/CreateUpdateCANFundingBudgetRequest"
examples:
"0":
$ref: "#/components/examples/CreateUpdateCANFundingBudgetRequest"
responses:
"201":
description: Created
Expand Down Expand Up @@ -457,11 +457,11 @@ paths:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateUpdateCANFundingBudgetRequest"
examples:
"0":
$ref: "#/components/examples/CreateUpdateCANFundingBudgetRequest"
schema:
$ref: "#/components/schemas/CreateUpdateCANFundingBudgetRequest"
examples:
"0":
$ref: "#/components/examples/CreateUpdateCANFundingBudgetRequest"
responses:
"200":
description: CANFundingBudget Updated
Expand Down Expand Up @@ -495,11 +495,11 @@ paths:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateUpdateCANFundingBudgetRequest"
examples:
"0":
$ref: "#/components/examples/CreateUpdateCANFundingBudgetRequest"
schema:
$ref: "#/components/schemas/CreateUpdateCANFundingBudgetRequest"
examples:
"0":
$ref: "#/components/examples/CreateUpdateCANFundingBudgetRequest"
responses:
"200":
description: CAN Updated
Expand Down Expand Up @@ -2355,6 +2355,8 @@ components:
type: array
items:
$ref: "#/components/schemas/BudgetLineItem"
description:
type: string
display_name:
type: string
funding_budgets:
Expand All @@ -2371,8 +2373,14 @@ components:
type: array
items:
$ref: "#/components/schemas/FundingReceived"
id:
type: integer
nick_name:
type: string
number:
type: string
obligate_by:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added obligate_by and sorted alphebetically

type: integer
portfolio:
type: integer
portfolio_id:
Expand All @@ -2381,12 +2389,6 @@ components:
type: array
items:
$ref: "#/components/schemas/Project"
nick_name:
type: string
description:
type: string
id:
type: integer
created_on:
$ref: "#/components/parameters/created_on"
updated_on:
Expand Down
27 changes: 27 additions & 0 deletions frontend/src/components/CANs/CANTable/CANTable.helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Gets the last day of the fiscal year for a given year.
* @param {number} fiscalYear - The fiscal year
* @returns {Date} The last day of the fiscal year
*/
const getLastDayOfFiscalYear = (fiscalYear) => {
// Fiscal year ends on September 30
return new Date(fiscalYear, 8, 30); // Month is 0-indexed, so 8 is September
};
/**
* Formats the obligate by date to the last day of the fiscal year.
* @param {number | undefined} obligateBy - The obligate by value
* @returns {string} Formatted date string or "TBD"
*/
export const formatObligateBy = (obligateBy) => {
if (!obligateBy) return "TBD"; // Default value
if (typeof obligateBy !== "number" || isNaN(obligateBy)) return "TBD"; // Default if parsing fails

const lastDay = getLastDayOfFiscalYear(obligateBy);

// Format as MM/DD/YY
return lastDay.toLocaleDateString("en-US", {
month: "2-digit",
day: "2-digit",
year: "2-digit"
});
};
24 changes: 24 additions & 0 deletions frontend/src/components/CANs/CANTable/CANTable.helpers.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { formatObligateBy } from "./CANTable.helpers";

describe("formatObligateBy", () => {
test('returns "TBD" for undefined input', () => {
expect(formatObligateBy(undefined)).toBe("TBD");
});

test('returns "TBD" for non-numeric input', () => {
expect(formatObligateBy("not a number")).toBe("TBD");
});

test('returns "TBD" for NaN input', () => {
expect(formatObligateBy(NaN)).toBe("TBD");
});

test("formats valid fiscal year correctly", () => {
expect(formatObligateBy(2023)).toBe("09/30/23");
});

test("handles different fiscal years", () => {
expect(formatObligateBy(2024)).toBe("09/30/24");
expect(formatObligateBy(2025)).toBe("09/30/25");
});
});
78 changes: 9 additions & 69 deletions frontend/src/components/CANs/CANTable/CANTable.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import _ from "lodash";
import PropTypes from "prop-types";
import React from "react";
import PaginationNav from "../../UI/PaginationNav";
import Tooltip from "../../UI/USWDS/Tooltip";
import CANTableHead from "./CANTableHead";
import CANTableRow from "./CANTableRow";
import styles from "./style.module.css";
import { formatObligateBy } from "./CANTable.helpers";

/**
* CANTable component of CanList
* @component
Expand All @@ -16,7 +17,7 @@ import styles from "./style.module.css";
const CANTable = ({ cans }) => {
const CANS_PER_PAGE = 10;
const [currentPage, setCurrentPage] = React.useState(1);
let cansPerPage = _.cloneDeep(cans);
let cansPerPage = [...cans];
cansPerPage = cansPerPage.slice((currentPage - 1) * CANS_PER_PAGE, currentPage * CANS_PER_PAGE);

if (cans.length === 0) {
Expand All @@ -26,18 +27,18 @@ const CANTable = ({ cans }) => {
return (
<>
<table className={`usa-table usa-table--borderless width-full ${styles.tableHover}`}>
<TableHead />
<CANTableHead />
<tbody>
{cansPerPage.map((can) => (
<CANTableRow
key={can.id}
canId={can.id}
name={can.display_name}
nickname={can.nick_name}
name={can.display_name ?? ""}
nickname={can.nick_name ?? ""}
portfolio={can.portfolio.abbreviation}
fiscalYear={can.funding_budgets[0]?.fiscal_year ?? "TBD"}
activePeriod={can.active_period ?? "TBD"}
obligateBy={can.obligate_by ?? "09/30/25"}
activePeriod={can.active_period?.toString() ?? "TBD"}
obligateBy={formatObligateBy(can.obligate_by)}
transfer={can.funding_details.method_of_transfer ?? "TBD"}
fyBudget={can.funding_budgets[0]?.budget ?? 0}
/>
Expand All @@ -56,67 +57,6 @@ const CANTable = ({ cans }) => {
);
};

const TableHead = () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to its own component

const availbleTooltip =
"$ Available is the remaining amount of the total budget that is available to plan from (Total FY Budget minus budget lines in Planned, Executing or Obligated Status)";
return (
<thead>
<tr>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
CAN
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
Portfolio
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
FY
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
Active Period
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
Obligate By
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
Transfer
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
FY Budget
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
<Tooltip label={availbleTooltip}>
<span>$ Available</span>
</Tooltip>
</th>
</tr>
</thead>
);
};

CANTable.propTypes = {
cans: PropTypes.array.isRequired
};
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/CANs/CANTable/CANTable.test.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { render, screen } from "@testing-library/react";
import { describe, it, expect, vi } from "vitest";
import CANTable from "./CANTable";
import { cans } from "../../../tests/data";
import { useGetCansQuery, useGetCanFundingSummaryQuery } from "../../../api/opsAPI";
import { MemoryRouter } from "react-router-dom";
import { describe, expect, it, vi } from "vitest";
import { useGetCanFundingSummaryQuery, useGetCansQuery } from "../../../api/opsAPI";
import { cans } from "../../../tests/data";
import CANTable from "./CANTable";

// Mock the PaginationNav component
vi.mock("../../UI/PaginationNav", () => ({
Expand Down
65 changes: 65 additions & 0 deletions frontend/src/components/CANs/CANTable/CANTableHead.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import Tooltip from "../../UI/USWDS/Tooltip";

const CANTableHead = () => {
const availbleTooltip =
"$ Available is the remaining amount of the total budget that is available to plan from (Total FY Budget minus budget lines in Planned, Executing or Obligated Status)";

return (
<thead>
<tr>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
CAN
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
Portfolio
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
FY
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
Active Period
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
Obligate By
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
Transfer
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
FY Budget
</th>
<th
scope="col"
style={{ whiteSpace: "nowrap" }}
>
<Tooltip label={availbleTooltip}>
<span>$ Available</span>
</Tooltip>
</th>
</tr>
</thead>
);
};

export default CANTableHead;
Loading