Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .changeset/prune-report-column-grouping-schemas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
"@objectstack/spec": minor
---

feat(spec)!: prune the dead `ReportColumnSchema`/`ReportGroupingSchema` exports + the unread report chart `groupBy` (#3463, #1878/#1890)

Deep-cleanup close-out of the report-chart disposition (follow-up to #3441).
After the ADR-0021 single-form cutover a dataset-bound report expresses its
columns/grouping as dataset **measure/dimension name arrays** — `values`,
`rows` and `columns` are `z.array(z.string())`, not object literals — so
`ReportColumnSchema` / `ReportGroupingSchema` were referenced by **no schema
body**. They survived only as public type exports and were marked
`@deprecated` in #3441; this removes them.

- Deleted `ReportColumnSchema` / `ReportGroupingSchema` and their type
exports `ReportColumn` / `ReportGrouping` / `ReportColumnInput` /
`ReportGroupingInput` from `@objectstack/spec/ui`. The manifest ratchet
keys `ui/ReportColumn` / `ui/ReportGrouping` are dropped in the same PR.
- Deleted `ReportChart.groupBy` — the `[EXPERIMENTAL — not enforced]`
series-split field flagged in #3441. The dataset-bound `DatasetReportRenderer`
plots a single `xAxis`×`yAxis` series and never read it; only the retired
legacy `ReportViewer` fallback ever consumed a top-level `groupBy`.
`ReportChartSchema` is non-strict, so any residual `chart.groupBy` in stored
metadata is silently stripped on parse — no tombstone needed.
- Regenerated `content/docs/references/ui/report.mdx` and the spec API-surface
snapshot.

**Migration**: nothing an author writes changes.
- No first-party or example report authored `ReportColumn` / `ReportGrouping`
objects or `chart.groupBy` — a dataset-bound report already expresses
columns as `values` (measure names) and grouping as `rows` / `columns`
(dimension names).
- TypeScript consumers importing `ReportColumn` / `ReportGrouping` /
`ReportColumnInput` / `ReportGroupingInput` (or the `*Schema` values) from
`@objectstack/spec/ui` have no replacement type — model report columns as
the dataset's measure names and grouping as its dimension names. objectui's
`SpecReportColumn*` / `SpecReportGrouping*` re-exports are removed in the
companion objectui change.
32 changes: 2 additions & 30 deletions content/docs/references/ui/report.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ Report Type Enum
## TypeScript Usage

```typescript
import { JoinedReportBlock, Report, ReportChart, ReportColumn, ReportGrouping, ReportType } from '@objectstack/spec/ui';
import type { JoinedReportBlock, Report, ReportChart, ReportColumn, ReportGrouping, ReportType } from '@objectstack/spec/ui';
import { JoinedReportBlock, Report, ReportChart, ReportType } from '@objectstack/spec/ui';
import type { JoinedReportBlock, Report, ReportChart, ReportType } from '@objectstack/spec/ui';

// Validate data
const result = JoinedReportBlock.parse(data);
Expand Down Expand Up @@ -95,34 +95,6 @@ const result = JoinedReportBlock.parse(data);
| **annotations** | `{ type: Enum<'line' \| 'region'>; axis: Enum<'x' \| 'y'>; value: number \| string; endValue?: number \| string; … }[]` | optional | |
| **interaction** | `{ tooltips: boolean; zoom: boolean; brush: boolean; clickAction?: string }` | optional | |
| **aria** | `{ ariaLabel?: string; ariaDescribedBy?: string; role?: string }` | optional | ARIA accessibility attributes |
| **groupBy** | `string` | optional | [EXPERIMENTAL — not enforced] Additional series-split grouping; not read by the dataset-bound report renderer (liveness #1878/#1890) |


---

## ReportColumn

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **field** | `string` | ✅ | Field name |
| **label** | `string` | optional | Override label |
| **aggregate** | `Enum<'sum' \| 'avg' \| 'max' \| 'min' \| 'count' \| 'unique'>` | optional | Aggregation function |
| **responsive** | `{ breakpoint?: Enum<'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'>; hiddenOn?: Enum<'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'>[]; columns?: object; order?: object }` | optional | Responsive visibility for this column |


---

## ReportGrouping

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **field** | `string` | ✅ | Field to group by |
| **sortOrder** | `Enum<'asc' \| 'desc'>` | ✅ | |
| **dateGranularity** | `Enum<'day' \| 'week' \| 'month' \| 'quarter' \| 'year'>` | optional | For date fields |


---
Expand Down
6 changes: 0 additions & 6 deletions packages/spec/api-surface.json
Original file line number Diff line number Diff line change
Expand Up @@ -3371,12 +3371,6 @@
"ReportChart (type)",
"ReportChartInput (type)",
"ReportChartSchema (const)",
"ReportColumn (type)",
"ReportColumnInput (type)",
"ReportColumnSchema (const)",
"ReportGrouping (type)",
"ReportGroupingInput (type)",
"ReportGroupingSchema (const)",
"ReportInput (type)",
"ReportNavItem (type)",
"ReportNavItemSchema (const)",
Expand Down
2 changes: 0 additions & 2 deletions packages/spec/json-schema.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1751,8 +1751,6 @@
"ui/RecordRelatedListProps",
"ui/Report",
"ui/ReportChart",
"ui/ReportColumn",
"ui/ReportGrouping",
"ui/ReportNavItem",
"ui/ReportType",
"ui/ResponsiveConfig",
Expand Down
44 changes: 1 addition & 43 deletions packages/spec/src/ui/report.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { FilterConditionSchema } from '../data/filter.zod';
import { ChartConfigSchema } from './chart.zod';
import { SnakeCaseIdentifierSchema } from '../shared/identifiers.zod';
import { I18nLabelSchema, AriaPropsSchema } from './i18n.zod';
import { ResponsiveConfigSchema, PerformanceConfigSchema } from './responsive.zod';
import { PerformanceConfigSchema } from './responsive.zod';

/**
* Report Type Enum
Expand All @@ -20,37 +20,6 @@ export const ReportType = z.enum([
'joined' // Joined multiple blocks
]);

/**
* Report Column Schema
*
* @deprecated Unreferenced by the single-form (ADR-0021) report shape — a
* dataset-bound report selects `values` (measure names) and `rows`/`columns`
* (dimension names) as `z.array(z.string())`, not `ReportColumn` objects. Kept
* only as a public type export (objectui re-exports it as `SpecReportColumn`);
* slated for removal in a future governed prune (liveness #1878/#1890).
*/
export const ReportColumnSchema = lazySchema(() => z.object({
field: z.string().describe('Field name'),
label: I18nLabelSchema.optional().describe('Override label'),
aggregate: z.enum(['sum', 'avg', 'max', 'min', 'count', 'unique']).optional().describe('Aggregation function'),
/** Responsive visibility/priority per breakpoint */
responsive: ResponsiveConfigSchema.optional().describe('Responsive visibility for this column'),
}));

/**
* Report Grouping Schema
*
* @deprecated Unreferenced by the single-form (ADR-0021) report shape —
* grouping is expressed by dataset dimension names in `rows`/`columns`. Kept
* only as a public type export (objectui re-exports it as `SpecReportGrouping`);
* slated for removal in a future governed prune (liveness #1878/#1890).
*/
export const ReportGroupingSchema = lazySchema(() => z.object({
field: z.string().describe('Field to group by'),
sortOrder: z.enum(['asc', 'desc']).default('asc'),
dateGranularity: z.enum(['day', 'week', 'month', 'quarter', 'year']).optional().describe('For date fields'),
}));

/**
* Report Chart Schema
*
Expand All @@ -64,13 +33,6 @@ export const ReportChartSchema = lazySchema(() => ChartConfigSchema.extend({
xAxis: z.string().describe('Dataset dimension name for the X-axis (bound-dataset dimension, not a raw field)'),
/** Dataset **measure** name for the Y-axis (from the report's bound dataset). */
yAxis: z.string().describe('Dataset measure name for the Y-axis (bound-dataset measure, not a raw field)'),
/**
* ⚠️ EXPERIMENTAL — NOT ENFORCED (liveness #1878/#1890). An additional
* series-split grouping. The dataset-bound `DatasetReportRenderer` plots a
* single `xAxis`×`yAxis` series and does not read this; only the legacy
* `ReportViewer` fallback consumed a top-level `groupBy`.
*/
groupBy: z.string().optional().describe('[EXPERIMENTAL — not enforced] Additional series-split grouping; not read by the dataset-bound report renderer (liveness #1878/#1890)'),
}));

/**
Expand Down Expand Up @@ -223,17 +185,13 @@ export type JoinedReportBlockInput = z.input<typeof JoinedReportBlockSchema>;
* which allow optional fields with defaults to be omitted.
*/
export type Report = z.infer<typeof ReportSchema>;
export type ReportColumn = z.infer<typeof ReportColumnSchema>;
export type ReportGrouping = z.infer<typeof ReportGroupingSchema>;
export type ReportChart = z.infer<typeof ReportChartSchema>;

/**
* Input Types for Report Configuration
* Use these when defining reports in configuration files.
*/
export type ReportInput = z.input<typeof ReportSchema>;
export type ReportColumnInput = z.input<typeof ReportColumnSchema>;
export type ReportGroupingInput = z.input<typeof ReportGroupingSchema>;
export type ReportChartInput = z.input<typeof ReportChartSchema>;

/**
Expand Down