-
Notifications
You must be signed in to change notification settings - Fork 21
feat: add tableRowReplace injection for custom row rendering in list … #419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds a new tableRowReplace injection point that allows users to customize how each row in the list view table is rendered. This extends AdminForth's page injection system to support full row-level customization beyond the existing column-level components.
Key Changes
- Added
tableRowReplaceto the list of allowed page injections in the config validator - Implemented custom row rendering in
ResourceListTableVirtual.vueusing Vue's dynamic component system - Added comprehensive documentation with usage examples and component contract specifications
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| adminforth/spa/src/views/ListView.vue | Passes tableRowReplaceInjection prop to both table components with array handling logic |
| adminforth/spa/src/components/ResourceListTableVirtual.vue | Implements custom row component rendering using dynamic <component> element |
| adminforth/modules/configValidator.ts | Adds tableRowReplace to the allowed injection keys for list pages |
| adminforth/documentation/docs/tutorial/03-Customization/08-pageInjections.md | Adds complete documentation section explaining the feature, configuration, and usage patterns |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| :tableRowReplaceInjection="Array.isArray(coreStore.resourceOptions?.pageInjections?.list?.tableRowReplace) | ||
| ? coreStore.resourceOptions.pageInjections.list.tableRowReplace[0] | ||
| : coreStore.resourceOptions?.pageInjections?.list?.tableRowReplace || null" |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tableRowReplaceInjection prop is passed to ResourceListTable but this component doesn't appear to use it. Unlike ResourceListTableVirtual which has custom row rendering logic, ResourceListTable still uses a standard <tr> element (line 86-87 in the base file). Either implement the tableRowReplace functionality in this component to match ResourceListTableVirtual, or remove this prop binding if the feature is only intended for virtual scrolling.
| :tableRowReplaceInjection="Array.isArray(coreStore.resourceOptions?.pageInjections?.list?.tableRowReplace) | |
| ? coreStore.resourceOptions.pageInjections.list.tableRowReplace[0] | |
| : coreStore.resourceOptions?.pageInjections?.list?.tableRowReplace || null" |
| Notes and tips: | ||
| - Requirements: | ||
| - Required <tr></tr> structure around </slot> |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation mentions "Required structure around " but uses incorrect syntax with </slot>. The correct syntax should be <slot /> as shown in the template example above. Update to: "Required <tr></tr> structure around <slot />"
| - Required <tr></tr> structure around </slot> | |
| - Required `<tr></tr>` structure around `<slot />` |
…g in ResourceListTable components
ivictbor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets make scalar type for this injection for now since there is no roadmap to make recursive wrap. For actions injection same.
| - Slots | ||
| - Default slot: the table’s standard row content (cells) will be projected here. Your component can wrap or style it. | ||
| - Output | ||
| - Render a full `<tr>…</tr>` fragment. For simple decoration, render a single `<td :colspan="columnsCount">` and wrap `<slot />` inside your layout. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For simple decoration
->
For example to replace a set of cells with sincle full-width cell, render
<tr>
<td :colspan="columnsCount">
<slot />
| ? [coreStore.resourceOptions.pageInjections.list.tableBodyStart] | ||
| : [] | ||
| " | ||
| :tableRowReplaceInjection="Array.isArray(coreStore.resourceOptions?.pageInjections?.list?.tableRowReplace) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NoOne7135 Since we don't support array, the type of coreStore.resourceOptions?.pageInjections?.list?.tableRowReplace should not be array. Probably in future you plan to add recursive wrapping, but anyway now in config validation step if there is mroe then one element lets throw clear error that tableRowReplace has multiple components but supports only one
… ResourceListTable components
…lidate element count
…view