Skip to content

[8549] Quick create enhancements#4803

Open
jvega190 wants to merge 5 commits intocraftercms:developfrom
jvega190:enhancement/8549
Open

[8549] Quick create enhancements#4803
jvega190 wants to merge 5 commits intocraftercms:developfrom
jvega190:enhancement/8549

Conversation

@jvega190
Copy link
Member

@jvega190 jvega190 commented Feb 16, 2026

craftercms/craftercms#8549

  • Update without need of a full-page refresh (after updating content types)
  • Update to have good defaults
  • Group by archetypes

Summary by CodeRabbit

  • New Features

    • Path selection dialog with search for choosing target paths.
    • Quick Create menu now shows content items grouped by archetype.
  • Improvements

    • Smarter default path suggestions based on content type.
    • Streamlined controls: separate buttons for path selection and adding macros.
    • Quick Create list refreshes after content-type updates.

@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

No actionable comments were generated in the recent review. 🎉


Walkthrough

Adds a path-selection workflow to PathWithMacroCreator, makes Quick Create archetype-aware with grouped items and content-type-derived default paths, and updates the configuration epic to refresh the quick-create list when content-type form-definition XML changes.

Changes

Cohort / File(s) Summary
Content Type-Aware Path Selection
ui/app/src/components/ContentTypeManagement/controls/PathWithMacroCreator.tsx
Adds dialog-based path selection (pushDialog/popDialog) with onOk handling, computes defaultPath from originalValues.type, populates placeholder/default on focus when empty, and replaces the single add-macro adornment with a two-button cluster. Uses useStableFormContext and useDispatch.
Quick Create Grouping & Archetype Organization
ui/app/src/components/QuickCreate/QuickCreate.tsx
Adds useContentTypes/useArchetypes imports and a memoized getGroupedQuickCreateItems helper; transforms flat quick-create list into archetype-grouped sections (renders with Box) and derives defaultPath from item.contentType.type when item.path is absent. Adjusts menu rendering and removes prior static section header.
Configuration Epic: Quick-Create Refresh Trigger
ui/app/src/state/epics/configuration.ts
Imports fetchQuickCreateList and includes it in actions returned by handleSystemEvent for content-type form-definition XML path updates, causing quick-create list refresh on those changes.

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant PWMC as PathWithMacroCreator
  participant Store as Redux Store
  participant Dialog as PathSelectionDialog

  User->>PWMC: click "open path selector" (search icon)
  PWMC->>Store: dispatch pushDialog(PathSelectionDialog)
  Store-->>Dialog: show PathSelectionDialog
  User->>Dialog: select path + click OK
  Dialog->>Store: onOk(selectedPath)
  Store->>PWMC: popDialog + deliver selectedPath
  PWMC->>PWMC: set form value to selectedPath
Loading
sequenceDiagram
  participant User as User
  participant QC as QuickCreate
  participant Store as Redux Store
  participant Epic as Configuration Epic
  participant Form as NewContentFormDialog

  User->>QC: open quick create, choose grouped item
  QC->>QC: compute defaultPath from contentType.type
  QC->>Store: open NewContentFormDialog (with defaultPath)
  User->>Form: save content-type/form-definition
  Form->>Store: emit system event / contentTypeUpdated
  Store->>Epic: handleSystemEvent -> returns fetchQuickCreateList()
  Epic->>Store: dispatch fetchQuickCreateList
  Store->>QC: update quickCreateItems
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • rart
🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title '[8549] Quick create enhancements' directly corresponds to the main changes in the PR, which focus on improving the quick-create functionality with grouping by archetypes, default values, and real-time updates.
Description check ✅ Passed The PR description addresses the required template with a ticket reference and bullet points covering all major enhancements (refresh-free updates, good defaults, grouping by archetypes).

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

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@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: 1

🤖 Fix all issues with AI agents
In
`@ui/app/src/components/ContentTypeManagement/controls/PathWithMacroCreator.tsx`:
- Around line 157-162: The IconButton in PathWithMacroCreator.tsx uses an
incorrect aria-label ("Maximize"); update its aria-label to match the
tooltip/FormattedMessage (e.g., "Select path") to improve accessibility and
consistency—locate the IconButton that calls onOpenPathSelectionDialog() within
the PathWithMacroCreator component and replace aria-label="Maximize" with
aria-label matching the tooltip text.
🧹 Nitpick comments (5)
ui/app/src/components/QuickCreate/QuickCreate.tsx (3)

178-201: Prefer stable keys over index-based keys for the grouped items.

Line 179 uses index as the key for archetype groups, and Line 193 uses index for items within each group. Since archetype (the group label) is unique per group and each item likely has a unique contentTypeId, these are better candidates for keys. Index-based keys can cause subtle rendering issues if the list order or composition changes.

♻️ Suggested key improvements
-			{Object.keys(groupedItems).map((archetype, index) => (
-				<Box key={index}>
+			{Object.keys(groupedItems).map((archetype) => (
+				<Box key={archetype}>
 					<Typography
 						...
 					</Typography>
-					{groupedItems[archetype].map((item, index) => (
+					{groupedItems[archetype].map((item) => (
 						<MenuItem
-							key={index}
+							key={item.contentTypeId}
 							onClick={() => onItemSelected(item)}

364-372: Missing message id for the "Other" fallback label.

Line 367 uses formatMessage({ defaultMessage: 'Other' }) without a message id. While this works at runtime with react-intl v8, it won't be picked up by message extraction tools and is inconsistent with the rest of the codebase which uses defineMessages/defineMessage with explicit ids. Consider defining this message alongside the other translations at the top of the file.

♻️ Suggested approach

Add to the translations object at the top of the file:

otherArchetype: {
  id: 'quickCreate.otherArchetype',
  defaultMessage: 'Other'
}

Then reference it:

-			const archetypeLabel = archetype?.name || formatMessage({ defaultMessage: 'Other' });
+			const archetypeLabel = archetype?.name || formatMessage(translations.otherArchetype);

111-123: Duplicated default path logic with PathWithMacroCreator.

The type === 'page' ? '/site/website/' : '/site/components/' pattern on lines 114–115 is repeated in PathWithMacroCreator.tsx (line 74). Consider extracting this into a shared utility to keep the path defaults in one place.

ui/app/src/components/ContentTypeManagement/controls/PathWithMacroCreator.tsx (2)

148-153: Auto-populating on focus may cause unintended form dirty state.

When the user focuses the empty input (e.g., tabbing through the form), setValue(defaultPath) fires, which likely marks the form as dirty/changed without explicit user intent. The placeholder already communicates the default. Consider deferring the auto-population to a later user action (e.g., on blur if still empty, or only when the form is submitted) to avoid accidental state changes.


107-125: Consider initializing the path selection dialog at the current value or default path.

initialPath is hardcoded to '/site'. If the input already has a value (or has the defaultPath), it would be more ergonomic to open the dialog at that location so the user doesn't need to navigate from the root every time.

♻️ Suggested improvement
 	const onOpenPathSelectionDialog = () => {
 		const id = nanoid();
 		dispatch(
 			pushDialog({
 				id,
 				component: 'craftercms.components.PathSelectionDialog',
 				props: {
 					rootPath: '/site',
 					allowSwitchingRootPath: false,
-					initialPath: '/site',
+					initialPath: value || defaultPath,
 					onClose: () => dispatch(popDialog({ id })),
 					onOk: ({ path }) => {
 						setValue(path);
 						dispatch(popDialog({ id }));
 					}
 				}
 			})
 		);
 	};

Copy link

@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: 2

🤖 Fix all issues with AI agents
In
`@ui/app/src/components/ContentTypeManagement/controls/PathWithMacroCreator.tsx`:
- Around line 149-153: The current onFocus handler in PathWithMacroCreator calls
setValue(defaultPath) which marks the form dirty when the user simply focuses
the field; change this so focus does not commit a value: remove the
setValue(defaultPath) from the onFocus, use the defaultPath as the input's
placeholder prop instead, and only programmatically set the value either when
the user begins typing (e.g., in the input's onChange/onKeyDown if the current
value is empty) or during form submission if the field is still empty; update
references in PathWithMacroCreator (remove setValue usage in the onFocus
handler, add placeholder={defaultPath} and add logic in the input change/submit
handlers to apply defaultPath when appropriate).
- Around line 72-74: The code reads originalValues.type without a type guard;
update the access used in PathWithMacroCreator to match the project's pattern by
either casting originalValues.type as string or guarding it (e.g.,
originalValues?.type) before comparing; specifically modify the
useStableFormContext()/originalValues usage that sets defaultPath so the
expression becomes type-safe (e.g., treat originalValues.type as string or check
for undefined) and avoid silently falling back without an explicit cast/check.
🧹 Nitpick comments (3)
ui/app/src/components/ContentTypeManagement/controls/PathWithMacroCreator.tsx (3)

107-125: Path selection replaces the entire input value — verify this is intentional.

When the user picks a path from PathSelectionDialog, onOk calls setValue(path), which overwrites whatever was previously in the input (including any macros the user may have already appended). If the intent is to use this as a base path before adding macros, this is fine, but it could surprise users who added macros first and then decide to change the base path.

Also, minor: the onClose callback doesn't call dialogState.onClose — it only pops the dialog stack. This seems correct since this dialog is managed via the Redux dialog stack (not dialogState), just noting for clarity.


157-165: Aria-label fix looks good; simplify the onClick handler.

The aria-label now correctly matches the tooltip — nice fix. Minor nit: the wrapping arrow function is unnecessary since onOpenPathSelectionDialog takes no arguments.

Suggested simplification
-								<IconButton
-									aria-label={formatMessage({ defaultMessage: 'Select path' })}
-									onClick={() => onOpenPathSelectionDialog()}
-								>
+								<IconButton
+									aria-label={formatMessage({ defaultMessage: 'Select path' })}
+									onClick={onOpenPathSelectionDialog}
+								>

197-205: Unused Popover — appears to be dead code.

anchorEl is initialized to undefined and setAnchorEl is never called in this component, so this Popover can never open. If this is leftover from a previous implementation, consider removing it along with the anchorEl state on Line 77.

#!/bin/bash
# Verify setAnchorEl is never called with a truthy value
rg -n "setAnchorEl" --type=ts -g '*PathWithMacroCreator*'

@jvega190 jvega190 marked this pull request as ready for review February 16, 2026 22:44
@jvega190 jvega190 requested a review from rart as a code owner February 16, 2026 22:44
@jvega190 jvega190 requested a review from rart February 19, 2026 19:54
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.

2 participants

Comments