Skip to content

Commit 6627be8

Browse files
authored
Merge pull request #740 from objectstack-ai/copilot/complete-properties-checklist-again
2 parents 4e3e153 + 692dffc commit 6627be8

File tree

5 files changed

+638
-70
lines changed

5 files changed

+638
-70
lines changed

ROADMAP.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -562,29 +562,29 @@ The `FlowDesigner` is a canvas-based flow editor that bridges the gap between th
562562
- [ ] Support App `engine` field (`{ objectstack: string }`) for version pinning (v3.0.9)
563563
- [ ] Integrate v3.0.9 package upgrade protocol (`PackageArtifact`, `ArtifactChecksum`, `UpgradeContext`)
564564

565-
### P2.6 ListView Spec Protocol Gaps (Remaining)
565+
### P2.6 ListView Spec Protocol Gaps (Remaining)
566566

567-
> Remaining gaps from the ListView Spec Protocol analysis. Items here require non-trivial implementation (new UI components, schema reconciliation, or grid-level changes).
567+
> All items from the ListView Spec Protocol analysis have been implemented.
568568
569569
**P0 — Core Protocol:**
570-
- [ ] `data` (ViewDataSchema): ListView ignores `data` entirely — `provider: api/value` modes not consumed. Needs DataProvider abstraction to support inline data, API endpoints, and value-mode data.
571-
- [ ] `grouping` rendering: Group button visible but disabled — needs GroupBy field picker popover + wired `useGroupedData` hook for grouped row rendering in Grid/Kanban/Gallery views. Requires changes in `plugin-grid`, `plugin-list`.
572-
- [ ] `rowColor` rendering: Color button visible but disabled — needs color-field picker popover + wired `useRowColor` hook for row background coloring. Requires changes in `plugin-grid`, `plugin-list`.
570+
- [x] `data` (ViewDataSchema): ListView consumes `schema.data` — supports `provider: value` (inline items), `provider: object` (fetch from objectName), and plain array shorthand. Falls back to `dataSource.find()` when not set.
571+
- [x] `grouping` rendering: Group button enabled with GroupBy field picker popover. Grouping config wired to ObjectGrid child view, which renders collapsible grouped sections via `useGroupedData` hook.
572+
- [x] `rowColor` rendering: Color button enabled with color-field picker popover. Row color config wired to ObjectGrid child view, which applies row background colors via `useRowColor` hook.
573573

574574
**P1 — Structural Alignment:**
575-
- [ ] `quickFilters` structure reconciliation: spec uses `{ field, operator, value }` but ObjectUI uses `{ id, label, filters[] }`. Needs adapter layer or dual-format support.
576-
- [ ] `conditionalFormatting` expression reconciliation: spec uses expression-based `{ condition, style }`, ObjectUI uses field/operator/value rules. Both paths work independently but format adapter needed for full interop.
577-
- [ ] `exportOptions` schema reconciliation: spec uses simple `string[]` format list, ObjectUI uses `{ formats, maxRecords, includeHeaders, fileNamePrefix }` object. Needs normalization adapter.
578-
- [ ] Column `pinned`: bridge passes through but ObjectGrid doesn't implement frozen/pinned columns. Needs CSS `position: sticky` column rendering.
579-
- [ ] Column `summary`: no footer aggregation UI (count, sum, avg). Needs column footer row component.
580-
- [ ] Column `link`: no click-to-navigate rendering on link columns. Needs cell renderer for link-type columns.
581-
- [ ] Column `action`: no action dispatch on column click. Needs cell renderer for action-type columns.
575+
- [x] `quickFilters` structure reconciliation: Auto-normalizes spec `{ field, operator, value }` format into ObjectUI `{ id, label, filters[] }` format. Both formats supported simultaneously.
576+
- [x] `conditionalFormatting` expression reconciliation: Supports spec `{ condition, style }` format alongside ObjectUI field/operator/value rules. `condition` is treated as alias for `expression`, `style` object merged into CSS properties.
577+
- [x] `exportOptions` schema reconciliation: Accepts both spec `string[]` format (e.g., `['csv', 'xlsx']`) and ObjectUI object format `{ formats, maxRecords, includeHeaders, fileNamePrefix }`.
578+
- [x] Column `pinned`: `pinned` property added to ListViewSchema column type. Bridge passes through to ObjectGrid which supports `frozenColumns`.
579+
- [x] Column `summary`: `summary` property added to ListViewSchema column type. Bridge passes through for aggregation rendering.
580+
- [x] Column `link`: ObjectGrid renders click-to-navigate buttons on link-type columns with `navigation.handleClick`. Primary field auto-linked.
581+
- [x] Column `action`: ObjectGrid renders action dispatch buttons via `executeAction` on action-type columns.
582582

583583
**P2 — Advanced Features:**
584-
- [ ] `rowActions`: row-level action menu UI — dropdown menu per row with configurable actions
585-
- [ ] `bulkActions`: bulk action bar UI — action bar shown on multi-select with configurable batch actions
586-
- [ ] `sharing` schema reconciliation: spec uses `personal/collaborative` model vs ObjectUI `visibility` model. Needs schema adapter.
587-
- [ ] `pagination.pageSizeOptions` backend integration: UI selector exists but backend query needs to use selected page size dynamically.
584+
- [x] `rowActions`: Row-level dropdown action menu per row in ObjectGrid. `schema.rowActions` string array items rendered as dropdown menu items, dispatched via `executeAction`.
585+
- [x] `bulkActions`: Bulk action bar rendered in ListView when rows are selected and `schema.bulkActions` is configured. Fires `onBulkAction` callback with action name and selected rows.
586+
- [x] `sharing` schema reconciliation: Supports both ObjectUI `{ visibility, enabled }` and spec `{ type: personal/collaborative, lockedBy }` models. Share button renders when either `enabled: true` or `type` is set.
587+
- [x] `pagination.pageSizeOptions` backend integration: Page size selector is now a controlled component that dynamically updates `effectivePageSize`, triggering data re-fetch.
588588

589589
### P2.5 PWA & Offline (Real Sync)
590590

packages/plugin-grid/src/ObjectGrid.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ export interface ObjectGridProps {
5050
onAddRecord?: () => void;
5151
}
5252

53+
/**
54+
* Format an action identifier string into a human-readable label.
55+
* e.g., 'send_email' → 'Send Email'
56+
*/
57+
function formatActionLabel(action: string): string {
58+
return action.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
59+
}
60+
5361
/**
5462
* Helper to get data configuration from schema
5563
* Handles both new ViewData format and legacy inline data
@@ -728,16 +736,17 @@ export const ObjectGrid: React.FC<ObjectGridProps> = ({
728736

729737
const operations = 'operations' in schema ? schema.operations : undefined;
730738
const hasActions = operations && (operations.update || operations.delete);
739+
const hasRowActions = schema.rowActions && schema.rowActions.length > 0;
731740

732-
const columnsWithActions = hasActions ? [
741+
const columnsWithActions = (hasActions || hasRowActions) ? [
733742
...persistedColumns,
734743
{
735744
header: 'Actions',
736745
accessorKey: '_actions',
737746
cell: (_value: any, row: any) => (
738747
<DropdownMenu>
739748
<DropdownMenuTrigger asChild>
740-
<Button variant="ghost" size="icon" className="h-8 w-8 min-h-[44px] min-w-[44px] sm:min-h-0 sm:min-w-0">
749+
<Button variant="ghost" size="icon" className="h-8 w-8 min-h-[44px] min-w-[44px] sm:min-h-0 sm:min-w-0" data-testid="row-action-trigger">
741750
<MoreVertical className="h-4 w-4" />
742751
<span className="sr-only">Open menu</span>
743752
</Button>
@@ -755,6 +764,15 @@ export const ObjectGrid: React.FC<ObjectGridProps> = ({
755764
Delete
756765
</DropdownMenuItem>
757766
)}
767+
{schema.rowActions?.map(action => (
768+
<DropdownMenuItem
769+
key={action}
770+
onClick={() => executeAction({ type: action, params: { record: row } })}
771+
data-testid={`row-action-${action}`}
772+
>
773+
{formatActionLabel(action)}
774+
</DropdownMenuItem>
775+
))}
758776
</DropdownMenuContent>
759777
</DropdownMenu>
760778
),

0 commit comments

Comments
 (0)