Skip to content

[8419] Improve Change Type dialog/flow#4902

Open
jvega190 wants to merge 5 commits into
craftercms:developfrom
jvega190:enhancement/8419
Open

[8419] Improve Change Type dialog/flow#4902
jvega190 wants to merge 5 commits into
craftercms:developfrom
jvega190:enhancement/8419

Conversation

@jvega190

@jvega190 jvega190 commented Jun 25, 2026

Copy link
Copy Markdown
Member

craftercms/craftercms#8419

Summary by CodeRabbit

  • New Features

    • The change-content-type dialog now retrieves and displays only compatible content types for the selected item path.
    • The dialog layout adapts dynamically while loading and based on whether compatible types are available (including responsive sizing and conditional subtitles).
  • Bug Fixes

    • Improved empty-state behavior when no compatible types exist, with clearer messaging and updated primary action labeling (Cancel vs Close).

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@jvega190, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 23 minutes and 12 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d4331228-f8bf-4c06-aaf6-0659923390b6

📥 Commits

Reviewing files that changed from the base of the PR and between a16bbae and e291a4c.

📒 Files selected for processing (3)
  • ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx
  • ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx
  • ui/app/src/components/ChangeContentTypeDialog/utils.ts

Walkthrough

The dialog now fetches allowed content types for the current item path, passes them into the container, and changes sizing, loading behavior, empty-state text, and footer actions based on whether compatible types are available.

Changes

ChangeContentTypeDialog allowed-types flow

Layer / File(s) Summary
Props contract and fetch wiring
ui/app/src/components/ChangeContentTypeDialog/utils.ts, ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx
ChangeContentTypeDialogBaseProps now includes contentTypes and isFetching, and the wrapper fetches allowed types for the normalized folder path before choosing dialog sizing and subtitle content.
Container loading and empty states
ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx
The container consumes contentTypes and isFetching, updates body layout/loading behavior, and switches empty-state copy and the footer button label based on whether compatible types exist.

Sequence Diagram(s)

sequenceDiagram
  participant ChangeContentTypeDialog
  participant useFetchAllowedTypesForPath
  participant ChangeContentTypeDialogContainer

  ChangeContentTypeDialog->>useFetchAllowedTypesForPath: fetch allowed types for normalized path
  useFetchAllowedTypesForPath-->>ChangeContentTypeDialog: contentTypes and isFetching
  ChangeContentTypeDialog->>ChangeContentTypeDialogContainer: render with contentTypes and isFetching
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • craftercms/studio-ui#4834: This PR continues the same ChangeContentTypeDialog/container flow around allowed content types, filtering, and conditional UI.
  • craftercms/studio-ui#4849: Both PRs use useFetchAllowedTypesForPath to drive the allowed content types flow for the dialog.

Suggested reviewers

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

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 is concise and relates to the dialog/flow changes, though it is broader than the specific implementation.
Description check ✅ Passed The description includes the required ticket reference link, which satisfies the repository 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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx (1)

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

Typo: showSelectTpeViewshowSelectTypeView.

Minor naming nit for readability; update the declaration and its uses on lines 72 and 74.

🤖 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/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx`
at line 67, Rename the misspelled boolean `showSelectTpeView` to
`showSelectTypeView` in `ChangeContentTypeDialogContainer`, and update every
reference to it in the same component so the naming is consistent and readable.
🤖 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 `@ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx`:
- Around line 35-41: The loading state in ChangeContentTypeDialog is using the
compact xs width because maxWidth only checks contentTypes?.length, which makes
the SelectTypeView skeleton render cramped and then jump to lg after data loads.
Update the dialog sizing logic in ChangeContentTypeDialog to treat isFetching as
a full-layout state as well, so maxWidth and the subtitle follow isFetching ||
contentTypes?.length and the skeleton gets the larger layout from the start.

In `@ui/app/src/components/ChangeContentTypeDialog/utils.ts`:
- Line 27: Make the ChangeContentTypeDialog props match the hook state by making
contentTypes optional instead of required. Update the type in the utils.ts
definition used by ChangeContentTypeDialog so it accepts ContentType[] |
undefined, since useFetchAllowedTypesForPath returns undefined until data loads.
Keep the existing consumer behavior that already guards with optional chaining,
and ensure any references to contentTypes in ChangeContentTypeDialog or related
props handle the optional value safely.

---

Nitpick comments:
In
`@ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx`:
- Line 67: Rename the misspelled boolean `showSelectTpeView` to
`showSelectTypeView` in `ChangeContentTypeDialogContainer`, and update every
reference to it in the same component so the naming is consistent and readable.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 25c50981-ce50-4e59-9735-09004b97a596

📥 Commits

Reviewing files that changed from the base of the PR and between 9990ce9 and 72af2b5.

📒 Files selected for processing (3)
  • ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx
  • ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx
  • ui/app/src/components/ChangeContentTypeDialog/utils.ts

Comment thread ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx Outdated
Comment thread ui/app/src/components/ChangeContentTypeDialog/utils.ts Outdated
@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 25, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Changed files vs develop:"
git diff --name-only origin/develop...HEAD

echo
echo "==== Outline: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx ===="
ast-grep outline ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx --view expanded || true

echo
echo "==== Diff: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx ===="
git diff --unified=80 origin/develop...HEAD -- ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx

echo
echo "==== File: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx ===="
sed -n '1,260p' ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx

echo
echo "==== Outline: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx ===="
ast-grep outline ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx --view expanded || true

echo
echo "==== Diff: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx ===="
git diff --unified=100 origin/develop...HEAD -- ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx

echo
echo "==== File: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx ===="
sed -n '1,320p' ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx

echo
echo "==== File: ui/app/src/components/ChangeContentTypeDialog/utils.ts ===="
sed -n '1,220p' ui/app/src/components/ChangeContentTypeDialog/utils.ts

echo
echo "==== Search: ChangeContentTypeDialogContainer usages ===="
rg -n -C3 'ChangeContentTypeDialogContainer' ui/app/src/components/ChangeContentTypeDialog

echo
echo "==== Search: useFetchAllowedTypesForPath usages ===="
rg -n -C3 'useFetchAllowedTypesForPath' ui/app/src

Length of output: 30361



@jvega190 I did a final pass, and this is very close, but I wouldn’t hand it over just yet.

Blocking issue:

  • ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx: Line 49 passes isFetching={true} to ChangeContentTypeDialogContainer. That means the container will stay in loading mode forever, so the new empty-state path won’t behave correctly. This should pass the hook value instead:
isFetching={isFetching}

Cleanup / likely lint issue:

  • ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx still has unused imports after the refactor:
    • Line 22: getNormalizedFolderPathForApi1GetTypes
    • Line 27: useFetchAllowedTypesForPath
    • Line 36: Alert

Once those are fixed, the rest of the refactor looks consistent to me: fetching is centralized in the parent, the dialog sizing/header behavior matches the fetched-state intent, and the empty-state copy/button behavior makes sense.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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 25, 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

echo "== Changed files vs develop =="
git diff --name-only origin/develop...HEAD

echo
echo "== Outline: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx =="
ast-grep outline ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx --view expanded || true

echo
echo "== Diff: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx =="
git diff --unified=80 origin/develop...HEAD -- ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx

echo
echo "== Current file: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx =="
sed -n '1,260p' ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx

echo
echo "== Outline: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx =="
ast-grep outline ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx --view expanded || true

echo
echo "== Diff: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx =="
git diff --unified=120 origin/develop...HEAD -- ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx

echo
echo "== Current file: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx =="
sed -n '1,340p' ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx

echo
echo "== Current file: ui/app/src/components/ChangeContentTypeDialog/utils.ts =="
sed -n '1,220p' ui/app/src/components/ChangeContentTypeDialog/utils.ts

echo
echo "== Search: ChangeContentTypeDialogBaseProps usage =="
rg -n -C3 'ChangeContentTypeDialogBaseProps|isFetching|contentTypes' ui/app/src/components/ChangeContentTypeDialog

echo
echo "== Search: useFetchAllowedTypesForPath in ChangeContentTypeDialog subtree =="
rg -n -C3 'useFetchAllowedTypesForPath|getNormalizedFolderPathForApi1GetTypes' ui/app/src/components/ChangeContentTypeDialog

Length of output: 32154


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search: ChangeContentTypeDialog usages across repo =="
rg -n -C3 'ChangeContentTypeDialog' ui/app/src

echo
echo "== Search: ChangeContentTypeDialogProps and ChangeContentTypeDialogStateProps usages across repo =="
rg -n -C3 'ChangeContentTypeDialogProps|ChangeContentTypeDialogStateProps' ui/app/src

echo
echo "== Search: dialog registration for ChangeContentTypeDialog =="
rg -n -C4 'Change Content Type|ChangeContentTypeDialog' ui/app/src/state ui/app/src/components ui/app/src/utils ui/app/src/models

echo
echo "== Candidate file names related to ChangeContentTypeDialog =="
fd -i 'ChangeContentTypeDialog' ui/app/src

echo
echo "== If present, inspect any matching state/connected files =="
for f in $(fd -i 'ChangeContentTypeDialog' ui/app/src); do
  echo
  echo "---- FILE: $f ----"
  sed -n '1,260p' "$f"
done

Length of output: 42076



@jvega190 I did one more pass.

Good news first: the two issues I flagged before are fixed:

  • ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx: Line 49 now passes the real isFetching value.
  • ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx: the stale imports are gone.

I do still see one remaining issue before I’d call this ready:

  • ui/app/src/components/ChangeContentTypeDialog/utils.ts: Lines 24-28 moved contentTypes and isFetching into ChangeContentTypeDialogBaseProps.
  • ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx: Line 25 uses ChangeContentTypeDialogProps, so the top-level dialog now advertises those props as required input even though it derives them internally.

That makes the public prop contract inconsistent with the implementation. In other words, ChangeContentTypeDialog should own fetching state, but its exported props now imply callers must provide it.

I’d recommend splitting the props so only the container/resolved state includes:

contentTypes?: ContentType[];
isFetching: boolean;

and keeping ChangeContentTypeDialogProps limited to the external inputs the caller actually provides.

So: runtime behavior looks good now, but I’d still hold this for that one typing cleanup before handing it to human review.

@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 25, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Changed files vs origin/develop =="
git diff --name-only origin/develop...HEAD

echo
echo "== Outline: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx =="
ast-grep outline ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx --view expanded || true

echo
echo "== Diff: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx =="
git diff --unified=120 origin/develop...HEAD -- ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx

echo
echo "== Current file: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx =="
sed -n '1,260p' ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialog.tsx

echo
echo "== Outline: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx =="
ast-grep outline ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx --view expanded || true

echo
echo "== Diff: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx =="
git diff --unified=160 origin/develop...HEAD -- ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx

echo
echo "== Current file: ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx =="
sed -n '1,340p' ui/app/src/components/ChangeContentTypeDialog/ChangeContentTypeDialogContainer.tsx

echo
echo "== Current file: ui/app/src/components/ChangeContentTypeDialog/utils.ts =="
sed -n '1,260p' ui/app/src/components/ChangeContentTypeDialog/utils.ts

echo
echo "== Search: props types and usages in ChangeContentTypeDialog subtree =="
rg -n -C3 'ChangeContentTypeDialogProps|ChangeContentTypeDialogBaseProps|ChangeContentTypeDialogStateProps|contentTypes\??:|isFetching:' ui/app/src/components/ChangeContentTypeDialog

echo
echo "== Search: ChangeContentTypeDialog public usages across repo =="
rg -n -C3 '\bChangeContentTypeDialog\b' ui/app/src

echo
echo "== Search: direct imports from utils.ts across repo =="
rg -n -C3 "from './utils'|from \"./utils\"|from '.*/ChangeContentTypeDialog/utils'|from \".*/ChangeContentTypeDialog/utils\"" ui/app/src

Length of output: 122348



@jvega190 I did a final pass, and this looks good to hand over for human review.

What I checked:

  • ChangeContentTypeDialog now owns the fetch state and passes the real contentTypes / isFetching values down to the container.
  • ChangeContentTypeDialogContainer no longer fetches internally and its empty/loading states are consistent with the new flow.
  • utils.ts now has the prop split in the right place:
    • public dialog props stay limited to caller-provided inputs
    • container props carry the internally-derived contentTypes and isFetching
  • repo usage still matches that public contract

I didn’t find any remaining issues in the files changed by this PR. From my side, this is ready for human review.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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