[6.x] Inertia section edit#18491
Conversation
There was a problem hiding this comment.
Pull request overview
This PR migrates the Settings → Sections index/create/edit flows to Inertia pages, modernizes shared table/UI infrastructure, and aligns frontend imports with the packaged @craftcms/cp dist/type entrypoints.
Changes:
- Convert Sections settings pages to Inertia (
SettingsSectionsIndexPage,SettingsSectionsEditPage) and update controller/tests accordingly. - Enhance
CpScreenResponseto support rendering Inertia screens, and expandAdminTablefor pagination/sorting/metadata. - Add shared Vue composables/components (editable table, reorderable rows, input generator) and update CP package exports + generated Vue wrapper tooling.
Reviewed changes
Copilot reviewed 81 out of 85 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Feature/Integration/PagesTest.php | Moves Sections page coverage to a dedicated Inertia page assertion. |
| tests/Feature/Http/Controllers/Settings/SectionsControllerTest.php | Updates expectations for Inertia + adds sorting and delete assertions. |
| src/Section/Sections.php | Clears query ordering before applying table sorting. |
| src/Http/Responses/CpScreenResponse.php | Adds inertiaPage() and Inertia rendering path in toResponse(). |
| src/Http/Controllers/Settings/SectionsController.php | Implements Inertia-based Sections index/create/edit; adjusts flash responses. |
| resources/js/pages/SettingsSectionsIndexPage.vue | New Inertia index page using TanStack table + server-side sorting/pagination. |
| resources/js/pages/SettingsSectionsEditPage.vue | New Inertia edit page with form + per-site settings and preview targets. |
| resources/js/components/AdminTable/AdminTable.vue | Adds pagination footer, sorting UI, meta-driven classes/tags, and search slot. |
| resources/js/composables/useEditableTable.ts | New helper for inline-editable TanStack tables. |
| resources/js/components/ActionMenu.vue | New action menu wrapper for craft-action-menu/craft-action-item. |
| resources/js/components/sites/SiteFields.vue | Switches to useInputGenerator for handle/baseUrl generation. |
| packages/craftcms-cp/src/components/input/* | Updates craft-input sizing/attrs handling. |
| packages/craftcms-cp/scripts/* + package.json | Adds Vue wrapper generation script + export map changes. |
Comments suppressed due to low confidence (1)
packages/craftcms-cp/src/components/input/input.ts:25
craft-input’ssizeattribute appears to have been repurposed from an HTML-style character width (used throughout the app assize="3",size="7", etc.) to a'small' | 'medium' | 'large'enum. This is likely a breaking change: existing templates that pass numericsizewill no longer size the underlying<input>as intended. Consider keeping a numericsizeAPI (and using a different prop name for visual sizing, e.g.uiSize/variant), or updating all call sites and docs consistently.
@property({type: Number, reflect: true}) maxlength?: string;
@property({type: String, reflect: true}) size?: 'small' | 'medium' | 'large' =
'medium';
@property({reflect: true, type: Boolean}) small = false;
@property({reflect: true, type: Boolean}) center = false;
override connectedCallback() {
super.connectedCallback();
if (this._inputNode && this.maxlength) {
const sizeInt = parseInt(this.maxlength, 10);
if (sizeInt > 0) {
this._inputNode.size = sizeInt;
}
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This seemed to work beforehand but this _feels_ better
Creates a `CanSelect` trait for enums that are selectable from the CP.
|
@riasvdv I made a I also added a |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 95 out of 98 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (10)
src/Cp/SelectOptions.php:1
$suggestionsitems are built withlabel/valuekeys (notname), so sorting by'name'is incorrect and may result in unsorted output or runtime issues depending onArr::sortimplementation. Sort by'label'(or'value') instead, or change the suggestion items to include a'name'key consistently.
src/Http/Responses/CpScreenResponse.php:1$this->crumbscan benullor acallable(per thecrumbs()setter). In that case,$crumbs[] = ...will throw. Initialize$crumbsto an array (e.g.,is_array($this->crumbs) ? $this->crumbs : []) before appending the title crumb.
src/Entry/Validation/EntryTypeRules.php:1- This replaces the prior allowlist that explicitly included
'__blank__'. If the UI still submits'__blank__'to represent “no color”,Rule::enum(Color::class)will now reject it and cause validation failures. Either continue allowing'__blank__'in the rule, or normalize'__blank__'tonullbefore validation.
src/Section/Resources/SectionResource.php:1 - The null-coalescing operator won’t prevent a fatal error if
$this->typeisnullbecause$this->type->valueis evaluated first. If these fields can be unset (which the default fortypesuggests), use the nullsafe operator (?->value) (and/or defaults) to avoid dereferencing null.
src/Section/Resources/SectionResource.php:1 - The null-coalescing operator won’t prevent a fatal error if
$this->typeisnullbecause$this->type->valueis evaluated first. If these fields can be unset (which the default fortypesuggests), use the nullsafe operator (?->value) (and/or defaults) to avoid dereferencing null.
resources/js/composables/useEditableTable.ts:1 - A
<textarea>does not support thetypeattribute, soinputType(email/url/number) won’t behave as intended and native browser validation/keyboards won’t apply. Either render an<input>element wheninputTypeis not multiline, or droptypeand set an appropriateinputmode/validation strategy for textarea.
src/Http/RespondsWithFlash.php:1 ->with($data)can overwrite the explicitly set'error'key (and the success variant below can overwrite'success') if$datacontains those keys. To make the flash message deterministic, merge$datawith the intended flash key in a single array (or ensure ordering can’t clobber it).
yii2-adapter/legacy/web/twig/variables/Cp.php:1- Fix typo in annotation:
@dprecated→@deprecated.
yii2-adapter/legacy/web/twig/variables/Cp.php:1 - Fix typo in docblock:
shoudl→should.
packages/craftcms-cp/scripts/generate-vue-wrappers.js:1 - The comment says checked-based components emit a
checked-changedevent, but the generated wrapper listens tomodel-value-changed. Either update the documentation to match the actual event used, or change the wrapper event listener so it matches the intended event contract.
/**
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Long live PHPStan
The main focus here is porting the sections edit page over to Inertia but maybe the real code was all the things we had to change along the way.
Editable Tables
The biggest of those is figuring out how to manage editable tables. In the end, I ended up creating our own version of TanStack Table's
columnHelperwhich will eventually have dedicated methods for each of the input types the currenteditableTable.twigsupports. At the moment we only have the ones that were needed for this port (text,lightswitchandcheckbox).Vue Wrappers
Another fairly large shift in this PR is that we've added a script that will generate Vue components from the lit web components. I wanted to avoid this, but annoyingly Vue and Lion don't agree on some prop values. The Vue wrappers smooth this out so you can just
v-modelthe inputs as you would expect. These components are only to handle thev-modelbinding which is why we still have aSelectcomponent in the mainresources/js/componentsfolder. TheSelectcomponent takes in anoptionsprop and handles normalizing those before rendering the appropriate markup.Not ideal, but at least these layers keep things flexible.
It may end up that using Lion's form components isn't really worth it if we're living in a purely Vue world but for now, I still like the flexibility it allows us. That way if we have some views that we can't fully convert to Vue for some reason, we can ensure some visual consistency by using the
@craftcms/cpcomponents.Copilot's summary
Including this because it did a pretty good job of summing things up.
Component Enhancements and Features:
craft-action-itemnow supports checkable items with newchecked,active, andtypeproperties, updated rendering logic, and corresponding style adjustments to allow for checkbox-like menu items. [1] [2] [3] [4]craft-chipgains aniconproperty for easy prefix icon rendering, improved slot handling, and minor style adjustments for layout consistency. [1] [2] [3] [4] [5]craft-buttonintroduces a newdashedappearance, with corresponding styles and property updates for more visual variety. [1] [2]craft-inputandcraft-selectcomponents now support additional sizing and alignment options, includingsmall,medium, andlargesizes, acenterproperty, and a corrected use ofmaxlengthinstead ofsizefor input length. [1] [2] [3] [4]craft-switch-buttonandcraft-switchhave updated sizing logic for better consistency across controls, and a new Storybook story is added forcraft-switchwith various usage examples. [1] [2] [3]Build Process and Exports:
generate:vue-wrappers), and updates topackage.jsonexports to better support consumption from different environments and frameworks. [1] [2] [3] [4] [5]Storybook and Documentation:
craft-action-itemandcraft-switchcomponents, demonstrating new features and usage patterns. [1] [2] [3]