Skip to content

chore: adding grid component and helpers#237

Open
santipalenque wants to merge 10 commits intomainfrom
feature/add-sponsor-order-grid
Open

chore: adding grid component and helpers#237
santipalenque wants to merge 10 commits intomainfrom
feature/add-sponsor-order-grid

Conversation

@santipalenque
Copy link
Copy Markdown
Contributor

@santipalenque santipalenque commented May 8, 2026

https://app.clickup.com/t/86b66n5p9

Summary by CodeRabbit

  • New Features

    • Added a SponsorOrderGrid table and a compact InfoNote display component.
    • Improved money parsing/formatting and added a discount formatter (amount or rate).
  • Localization

    • Added sponsor_order_grid translation keys.
  • Tests

    • Added test coverage for sponsor order grid behavior.
  • Chores

    • Added build entry for the new component and bumped package version.
  • Misc

    • Added constants for basis points and sponsor form metafield classes.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8b031d58-88a4-45cd-80fa-0decd74e3641

📥 Commits

Reviewing files that changed from the base of the PR and between ae40efa and 8e346ab.

📒 Files selected for processing (1)
  • src/components/mui/FormItemTable/index.js

📝 Walkthrough

Walkthrough

Adds a new SponsorOrderGrid MUI component and InfoNote, tightens money utilities and constants (BPS, metafield class), includes Jest/RTL tests, adds i18n keys, and wires the component into exports and webpack with a package version bump.

Changes

SponsorOrderGrid Component & Utilities

Layer / File(s) Summary
Constants & Money Utilities
src/utils/constants.js, src/utils/money.js
Adds BPS = 100 and SPONSOR_FORMS_METAFIELD_CLASS; tightens amountToCents, amountFromCents, currencyAmountFromCents, parsePrice; adds formatDiscount(amount,type).
InfoNote Component
src/components/mui/InfoNote/index.jsx
Adds InfoNote React component rendering an info icon and message, accepts sx prop.
Component Implementation
src/components/mui/SponsorOrderGrid/index.js
Adds SponsorOrderGrid with mapOrderData to filter/transform lines, format amounts/rates, compose item details, optional action column (cancel/undo), extra rows (discounts, fees, refunds, payments, notes), total computation, and empty-state rendering.
FormItemTable Adjustments
src/components/mui/FormItemTable/index.js
Updates itemFieldsIncomplete to use c-Item-f-... keys and adds completeness checks for CheckBoxList and CheckBox.
Tests
src/components/mui/SponsorOrderGrid/__tests__/SponsorOrderGrid.test.js
New Jest/RTL suite with mocks; verifies headers, sponsor code/name, formatting, empty/zero-quantity handling, action column visibility, cancel/undo interactions, amountDue label, and metafield rendering.
Build Configuration & Exports
src/components/index.js, webpack.common.js, package.json, src/i18n/en.json
Adds MuiSponsorOrderGrid and MuiInfoNote exports to component barrel, registers webpack entry components/mui/sponsor-order-grid, bumps package version, and adds sponsor_order_grid i18n keys.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • smarcet

Poem

🐰 A grid of sponsors, neatly aligned,
Cents counted carefully, no cents left behind,
Buttons to cancel, and undo when you need,
Metafields shown and totals agreed,
Hoppity-hop — the components succeed!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: adding grid component and helpers' accurately summarizes the main changes: a new SponsorOrderGrid component, an InfoNote component, and utility helpers (money formatting, constants). It is clear, concise, and directly related to the primary additions in the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/add-sponsor-order-grid

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/mui/SponsorOrderGrid/index.js`:
- Around line 152-154: The icon-only cancel button using IconButton with
onClick={() => onCancelForm(row)} and the DeleteIcon lacks an accessible name;
add an explicit accessible label (e.g., aria-label="Cancel" or
aria-label={`Cancel ${row.name || 'sponsor'}`}) to the IconButton or wrap it
with a Tooltip providing the same text so screen readers can announce the
action, ensuring the label uniquely identifies the row when appropriate; update
the IconButton element where onCancelForm(row) is used to include this
aria-label/Tooltip.
- Around line 43-47: The code assumes form.items and each it.meta_fields are
always arrays which can crash when payloads are partial; update the mapping that
builds items (the expression using form.items.filter(...).map(...)) to guard
both arrays by replacing form.items with a null-safe fallback (e.g., form.items
|| []) and use a null-safe fallback for meta fields inside the map (e.g.,
(it.meta_fields || []) before calling .filter) so the filter/map on items and
the filter on meta_fields (used with SPONSOR_FORMS_METAFIELD_CLASS.FORM) never
run on undefined/null values.
- Around line 250-254: The current truthy checks treat 0 as absent; update the
props in SponsorOrderGrid (the total prop and the label decision) to use nullish
checks so legitimate zero values are preserved — e.g. replace the truthy checks
around total and amountDue with null/undefined-safe checks (use the nullish
coalescing pattern for total and an explicit amountDue != null check for the
label) so 0 is accepted as a valid value.
- Around line 219-222: FeeRow instances in the fee map are hardcoded with
trailing={1}, which breaks alignment when the action column is hidden; update
the mapped FeeRow to use the component's trailingCols variable instead (replace
trailing={1} with trailing={trailingCols}) so FeeRow rows align with the table
layout dynamically; locate the FeeRow in the fees.map block and pass
trailing={trailingCols}.

In `@src/utils/money.js`:
- Around line 66-70: The current comma-only normalization always treats every
comma as a decimal separator (variable s), which turns "1,234" into "1.234"
incorrectly; change the logic in the block that handles s.includes(",") &&
!s.includes(".") to first detect whether the commas are thousand separators by
testing s against the regex /^-?\d{1,3}(?:,\d{3})+$/ (if it matches, remove all
commas), otherwise treat the last comma as the decimal separator by replacing
only the final comma with a dot (e.g., use s = s.replace(/,([^,]*)$/, '.$1'));
apply these checks where s is manipulated so cent conversion later produces
correct results.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a7a56cf4-f4be-40fc-93fa-5e25129ff63c

📥 Commits

Reviewing files that changed from the base of the PR and between 6939989 and 462ea29.

📒 Files selected for processing (6)
  • src/components/index.js
  • src/components/mui/SponsorOrderGrid/__tests__/SponsorOrderGrid.test.js
  • src/components/mui/SponsorOrderGrid/index.js
  • src/utils/constants.js
  • src/utils/money.js
  • webpack.common.js

Comment on lines +43 to +47
items: form.items
.filter((it) => it.quantity)
.map((it) => {
const formMetaFields = it.meta_fields.filter(
(mf) => mf.class_field === SPONSOR_FORMS_METAFIELD_CLASS.FORM
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard nullable API arrays before filter to prevent runtime crashes.

form.items and it.meta_fields are used as always-defined arrays. A partial payload will throw and break rendering.

💡 Suggested patch
-    items: form.items
+    items: (form.items ?? [])
       .filter((it) => it.quantity)
       .map((it) => {
-        const formMetaFields = it.meta_fields.filter(
+        const formMetaFields = (it.meta_fields ?? []).filter(
           (mf) => mf.class_field === SPONSOR_FORMS_METAFIELD_CLASS.FORM
         );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
items: form.items
.filter((it) => it.quantity)
.map((it) => {
const formMetaFields = it.meta_fields.filter(
(mf) => mf.class_field === SPONSOR_FORMS_METAFIELD_CLASS.FORM
items: (form.items ?? [])
.filter((it) => it.quantity)
.map((it) => {
const formMetaFields = (it.meta_fields ?? []).filter(
(mf) => mf.class_field === SPONSOR_FORMS_METAFIELD_CLASS.FORM
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/mui/SponsorOrderGrid/index.js` around lines 43 - 47, The code
assumes form.items and each it.meta_fields are always arrays which can crash
when payloads are partial; update the mapping that builds items (the expression
using form.items.filter(...).map(...)) to guard both arrays by replacing
form.items with a null-safe fallback (e.g., form.items || []) and use a
null-safe fallback for meta fields inside the map (e.g., (it.meta_fields || [])
before calling .filter) so the filter/map on items and the filter on meta_fields
(used with SPONSOR_FORMS_METAFIELD_CLASS.FORM) never run on undefined/null
values.

Comment on lines +152 to +154
<IconButton size="large" onClick={() => onCancelForm(row)}>
<DeleteIcon fontSize="large" />
</IconButton>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add an accessible label to the icon-only cancel button.

The delete action is icon-only and currently has no explicit accessible name.

💡 Suggested patch
-          <IconButton size="large" onClick={() => onCancelForm(row)}>
+          <IconButton
+            size="large"
+            aria-label={T.translate("order_details_grid.action")}
+            onClick={() => onCancelForm(row)}
+          >
             <DeleteIcon fontSize="large" />
           </IconButton>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<IconButton size="large" onClick={() => onCancelForm(row)}>
<DeleteIcon fontSize="large" />
</IconButton>
<IconButton
size="large"
aria-label={T.translate("order_details_grid.action")}
onClick={() => onCancelForm(row)}
>
<DeleteIcon fontSize="large" />
</IconButton>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/mui/SponsorOrderGrid/index.js` around lines 152 - 154, The
icon-only cancel button using IconButton with onClick={() => onCancelForm(row)}
and the DeleteIcon lacks an accessible name; add an explicit accessible label
(e.g., aria-label="Cancel" or aria-label={`Cancel ${row.name || 'sponsor'}`}) to
the IconButton or wrap it with a Tooltip providing the same text so screen
readers can announce the action, ensuring the label uniquely identifies the row
when appropriate; update the IconButton element where onCancelForm(row) is used
to include this aria-label/Tooltip.

Comment on lines +219 to +222
{fees &&
fees.map((fee) => (
<FeeRow fee={fee} key={`fee-row-${fee.id}`} trailing={1} />
))}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use trailingCols for fee rows to keep table alignment consistent.

FeeRow is hardcoded to trailing={1}, which misaligns columns when the action column is not shown.

💡 Suggested patch
-                  <FeeRow fee={fee} key={`fee-row-${fee.id}`} trailing={1} />
+                  <FeeRow
+                    fee={fee}
+                    key={`fee-row-${fee.id}`}
+                    trailing={trailingCols}
+                  />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{fees &&
fees.map((fee) => (
<FeeRow fee={fee} key={`fee-row-${fee.id}`} trailing={1} />
))}
{fees &&
fees.map((fee) => (
<FeeRow
fee={fee}
key={`fee-row-${fee.id}`}
trailing={trailingCols}
/>
))}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/mui/SponsorOrderGrid/index.js` around lines 219 - 222, FeeRow
instances in the fee map are hardcoded with trailing={1}, which breaks alignment
when the action column is hidden; update the mapped FeeRow to use the
component's trailingCols variable instead (replace trailing={1} with
trailing={trailingCols}) so FeeRow rows align with the table layout dynamically;
locate the FeeRow in the fees.map block and pass trailing={trailingCols}.

Comment on lines +250 to +254
total={total || amountDue}
label={
amountDue
? T.translate("order_details_grid.amount_due")
: null
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Handle zero values correctly for total/amountDue.

Truthy checks here treat 0 as absent. That can produce wrong totals/labels when amountDue or total is legitimately zero.

💡 Suggested patch
-                total={total || amountDue}
+                total={total ?? amountDue}
                 label={
-                  amountDue
+                  amountDue != null
                     ? T.translate("order_details_grid.amount_due")
                     : null
                 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
total={total || amountDue}
label={
amountDue
? T.translate("order_details_grid.amount_due")
: null
total={total ?? amountDue}
label={
amountDue != null
? T.translate("order_details_grid.amount_due")
: null
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/mui/SponsorOrderGrid/index.js` around lines 250 - 254, The
current truthy checks treat 0 as absent; update the props in SponsorOrderGrid
(the total prop and the label decision) to use nullish checks so legitimate zero
values are preserved — e.g. replace the truthy checks around total and amountDue
with null/undefined-safe checks (use the nullish coalescing pattern for total
and an explicit amountDue != null check for the label) so 0 is accepted as a
valid value.

Comment thread src/utils/money.js
Comment on lines +66 to +70
if (s.includes(",") && s.includes(".")) {
s = s.replace(/,/g, "");
} else if (s.includes(",") && !s.includes(".")) {
s = s.replace(",", ".");
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix comma-only number normalization to avoid wrong cent conversion.

For comma-only inputs, this always treats , as decimal separator. 1,234 becomes 1.234 (123 cents) instead of 123400 cents.

💡 Suggested patch
-  } else if (s.includes(",") && !s.includes(".")) {
-    s = s.replace(",", ".");
+  } else if (s.includes(",") && !s.includes(".")) {
+    // thousands grouping (e.g. 1,234 or 1,234,567)
+    if (/^\d{1,3}(,\d{3})+$/.test(s)) {
+      s = s.replace(/,/g, "");
+    } else {
+      // decimal comma locale (e.g. 1234,56)
+      s = s.replace(",", ".");
+    }
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/money.js` around lines 66 - 70, The current comma-only
normalization always treats every comma as a decimal separator (variable s),
which turns "1,234" into "1.234" incorrectly; change the logic in the block that
handles s.includes(",") && !s.includes(".") to first detect whether the commas
are thousand separators by testing s against the regex /^-?\d{1,3}(?:,\d{3})+$/
(if it matches, remove all commas), otherwise treat the last comma as the
decimal separator by replacing only the final comma with a dot (e.g., use s =
s.replace(/,([^,]*)$/, '.$1')); apply these checks where s is manipulated so
cent conversion later produces correct results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant