Skip to content

[8685] Fix issues when saving, and repeat group validator#4905

Open
jvega190 wants to merge 3 commits into
craftercms:developfrom
jvega190:bugfix/8685
Open

[8685] Fix issues when saving, and repeat group validator#4905
jvega190 wants to merge 3 commits into
craftercms:developfrom
jvega190:bugfix/8685

Conversation

@jvega190

@jvega190 jvega190 commented Jun 30, 2026

Copy link
Copy Markdown
Member

craftercms/craftercms#8685

Summary by CodeRabbit

  • Bug Fixes
    • Improved form creation so saved paths follow the site-specific path format, ensuring new items open and save in the correct location.
    • Fixed repeat-group validation to honor the configured min/max constraints, making entry limit checks more consistent and reliable.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1db31798-e93f-40ca-8ccd-80afefec9b73

📥 Commits

Reviewing files that changed from the base of the PR and between 2679891 and 405ed93.

📒 Files selected for processing (1)
  • ui/app/src/components/FormsEngine/FormsEngine.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • ui/app/src/components/FormsEngine/FormsEngine.tsx

Walkthrough

FormsEngine now uses pathInSite from ItemMetaContext for create-mode save and header path handling, and repeatGroupValidator now reads minOccurs/maxOccurs from field.validations instead of field.properties.

Changes

FormsEngine save path and validator fixes

Layer / File(s) Summary
Create-mode path uses pathInSite
ui/app/src/components/FormsEngine/FormsEngine.tsx
FormOrchestrator destructures pathInSite from ItemMetaContext and uses it for useSaveForm’s createPath and CreateModeHeader’s path when create.path is present.
Repeat-group limits read from validations
ui/app/src/components/FormsEngine/lib/validators.ts
repeatGroupValidator now derives minOccurs and maxOccurs from field.validations via getValidationValue instead of from field.properties via getPropertyValue.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • craftercms/studio-ui#4804: It also changes repeatGroupValidator occurrence-limit handling in ui/app/src/components/FormsEngine/lib/validators.ts.
  • craftercms/studio-ui#4871: It also touches FormsEngine.tsx create-mode pathInSite handling and path derivation logic.

Suggested reviewers

  • rart
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the PR's main changes: saving fixes and repeat group validator updates.
Description check ✅ Passed The PR description includes the required ticket reference link, which satisfies the template.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ui/app/src/components/FormsEngine/FormsEngine.tsx (1)

908-914: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Header still displays the raw, unresolved create?.path.

The save flow now derives createPath from pathInSite (the macro-resolved path), per the comment on Line 816, but CreateModeHeader at Line 911 still receives the raw create?.path. If the configured create path contains macros, the header will show the unresolved macro string while the form actually saves to the resolved pathInSite, creating a discrepancy between what's displayed and where the content lands.

💡 Suggested fix
-						<CreateModeHeader path={create?.path} collapse={collapseHeader} />
+						<CreateModeHeader path={pathInSite} collapse={collapseHeader} />
🤖 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 `@ui/app/src/components/FormsEngine/FormsEngine.tsx` around lines 908 - 914,
The CreateModeHeader is still rendering the unresolved create path, causing a
mismatch with the macro-resolved save target. Update the create-mode branch in
FormsEngine so it passes the resolved create path derived from pathInSite
instead of create?.path, keeping the displayed header aligned with the actual
destination used by the save flow. Use the existing createPath/pathInSite logic
in FormsEngine and ensure CreateModeHeader receives the resolved value.
🧹 Nitpick comments (1)
ui/app/src/components/FormsEngine/FormsEngine.tsx (1)

811-819: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Reuse isCreateMode instead of recomputing the same condition.

isCreateMode (Line 634) is already Boolean(create?.path). Recomputing it inline here is redundant.

♻️ Proposed simplification
-		createPath: Boolean(create?.path) ? pathInSite : undefined, // pathInSite is the result of processing the create path with macros.
+		createPath: isCreateMode ? pathInSite : undefined, // pathInSite is the result of processing the create path with macros.
🤖 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 `@ui/app/src/components/FormsEngine/FormsEngine.tsx` around lines 811 - 819,
`FormsEngine` is recomputing the create-mode check inline when building
`saveFn`, even though `isCreateMode` already captures `Boolean(create?.path)`.
Update the `useSaveForm` call to pass `isCreateMode` for `createPath` instead of
repeating the condition, keeping the logic centralized and consistent with the
existing `isCreateMode` value.
🤖 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.

Outside diff comments:
In `@ui/app/src/components/FormsEngine/FormsEngine.tsx`:
- Around line 908-914: The CreateModeHeader is still rendering the unresolved
create path, causing a mismatch with the macro-resolved save target. Update the
create-mode branch in FormsEngine so it passes the resolved create path derived
from pathInSite instead of create?.path, keeping the displayed header aligned
with the actual destination used by the save flow. Use the existing
createPath/pathInSite logic in FormsEngine and ensure CreateModeHeader receives
the resolved value.

---

Nitpick comments:
In `@ui/app/src/components/FormsEngine/FormsEngine.tsx`:
- Around line 811-819: `FormsEngine` is recomputing the create-mode check inline
when building `saveFn`, even though `isCreateMode` already captures
`Boolean(create?.path)`. Update the `useSaveForm` call to pass `isCreateMode`
for `createPath` instead of repeating the condition, keeping the logic
centralized and consistent with the existing `isCreateMode` value.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1b1be6a4-ef45-4b4c-9da0-3c5673e9ddf2

📥 Commits

Reviewing files that changed from the base of the PR and between 7d8ec52 and 2679891.

📒 Files selected for processing (2)
  • ui/app/src/components/FormsEngine/FormsEngine.tsx
  • ui/app/src/components/FormsEngine/lib/validators.ts

@jvega190

Copy link
Copy Markdown
Member Author

Outside diff range comment addressed

@jvega190

Copy link
Copy Markdown
Member Author

@coderabbitai can you check if everything looks good? Please give it a final review before I hand over for human review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
gh pr view 4905 --repo craftercms/studio-ui --json title,body,commits,files,additions,deletions,changedFiles
echo "----DIFF----"
gh pr diff 4905 --repo craftercms/studio-ui

Length of output: 4869


🏁 Script executed:

#!/bin/bash
set -euo pipefail
cd $(git rev-parse --show-toplevel 2>/dev/null || pwd) || true

echo "---- getValidationValue / getPropertyValue defs ----"
rg -n "export function getValidationValue|export function getPropertyValue" ui/app/src/components/FormsEngine/lib/validators.ts -A 8

echo "---- pathInSite in ItemMetaContext ----"
rg -n "pathInSite" ui/app/src/components/FormsEngine/FormsEngine.tsx -B3 -A3

echo "---- ItemMetaContext type def ----"
rg -n "ItemMetaContext" ui/app/src/components/FormsEngine -l

echo "---- usage of minOccurs/maxOccurs elsewhere ----"
rg -n "minOccurs|maxOccurs" ui/app/src/components/FormsEngine -g '*.ts*'

Length of output: 1006


🏁 Script executed:

#!/bin/bash
set -e
pwd
find / -maxdepth 3 -iname "studio-ui*" 2>/dev/null
ls

Length of output: 439


🏁 Script executed:

#!/bin/bash
set -e
cd /home/jailuser/git

echo "---- getValidationValue / getPropertyValue defs ----"
rg -n "export function getValidationValue|export function getPropertyValue|function getValidationValue|function getPropertyValue" ui/app/src/components/FormsEngine -A 10

echo "---- pathInSite in FormsEngine.tsx ----"
rg -n "pathInSite" ui/app/src/components/FormsEngine/FormsEngine.tsx -B5 -A5

echo "---- ItemMetaContext def ----"
rg -n "ItemMetaContext" ui/app/src/components/FormsEngine -l

echo "---- minOccurs/maxOccurs usage ----"
rg -n "minOccurs|maxOccurs" ui/app/src/components/FormsEngine

Length of output: 8046


🏁 Script executed:

#!/bin/bash
set -e
cd /home/jailuser/git

echo "---- imports in validators.ts ----"
rg -n "^import|getPropertyValue|getValidationValue" ui/app/src/components/FormsEngine/lib/validators.ts

echo "---- check other usages of getPropertyValue in validators.ts file (ensure still used elsewhere or remove unused import) ----"
rg -n "getPropertyValue" ui/app/src/components/FormsEngine/lib/validators.ts

Length of output: 3246


Both changes look clean and consistent with how validations are used elsewhere in the file (e.g., maxLength, pattern, maxValue, minValue already use getValidationValue), and getPropertyValue is still used for other properties (allowPastDate, minSize, maxSize), so no unused imports. The pathInSite change in FormsEngine.tsx correctly sources the macro-processed value from ItemMetaContext and is consistently applied to both useSaveForm's createPath and CreateModeHeader's path prop, guarded by Boolean(create?.path).

@jvega190 I reviewed the latest changes — everything looks good to me:

  1. ui/app/src/components/FormsEngine/lib/validators.tsrepeatGroupValidator now reads minOccurs/maxOccurs via getValidationValue(field.validations, ...) instead of getPropertyValue(field.properties, ...). This is consistent with how other occurrence-related constraints (maxLength, pattern, minValue, maxValue) are already read from validations elsewhere in this file, and getPropertyValue remains correctly used for genuine properties (allowPastDate, minSize, maxSize). No unused imports left behind.

  2. ui/app/src/components/FormsEngine/FormsEngine.tsxpathInSite (the macro-processed path) is now pulled from ItemMetaContext and used for both useSaveForm's createPath and CreateModeHeader's path prop, gated by Boolean(create?.path) so it's undefined when no create path is set. This is consistent with how pathInSite is computed/passed elsewhere (e.g., via processPathMacros in the create.path initialization block around Line 462).

One minor, non-blocking note: the inline comment // pathInSite is the result of processing the create path with macros. is placed only on the createPath line — worth double-checking it reads naturally given it also implicitly explains the CreateModeHeader line below, but this is purely cosmetic.

I don't see any functional issues — this looks ready for human review.

[approve]

ᕦ(ᐛ)ᕤ

@jvega190 jvega190 marked this pull request as ready for review June 30, 2026 21:28
@jvega190 jvega190 requested a review from rart as a code owner June 30, 2026 21:28
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