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
31 changes: 31 additions & 0 deletions .changeset/retire-dashboard-legacy-analytics-3320.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
"@object-ui/types": minor
"@object-ui/plugin-dashboard": minor
"@object-ui/plugin-designer": minor
---

feat(dashboard): retire the pre-ADR-0021 inline-analytics renderer branches (framework#3320)

Follow-up to the dashboard analytics migration (framework#3251 / objectui#2703).
Authoring already emits only the semantic-layer shape (`dataset` + `dimensions` +
`values`); this removes the renderer's now-unauthored legacy read-branches.

- **types**: drop the `@deprecated` inline-analytics keys (`object`,
`categoryField`, `categoryGranularity`, `valueField`, `aggregate`, `measures`)
from `DashboardWidgetSchema`. They were retained in #2703 only so the renderer
could read legacy/static metadata during the transition.
- **plugin-dashboard**: `DashboardRenderer` no longer emits the object-bound
metric / chart / pivot / table / list branches from the top-level `object` +
analytics keys. It keeps the renderer-internal static paths (`options.data` /
`widget.data` array and the `provider: 'object'` async config) and
`widget.component`. The dashboard renderer no longer emits `object-pivot` /
`pivot` at all — dataset pivots render through `DatasetWidget` (grouped table /
cross-tab); the `ObjectPivotTable` / `PivotTable` components stay as public
SDUI blocks for other surfaces. `DashboardGridLayout` gets the same treatment.
- **graceful fallback**: a widget that still carries the retired inline shape in
stored metadata (top-level `object`, no `dataset`, no inline `options.data`)
now renders a visible error placeholder prompting a rebind to a dataset, rather
than a blank chart/grid.
- **plugin-designer**: `DashboardEditor` drops its inline object / value-field /
aggregate fields (analytics binding is authored via the dataset picker in
app-shell's `DashboardWidgetInspector` / plugin-dashboard's `WidgetConfigPanel`).
59 changes: 12 additions & 47 deletions packages/plugin-dashboard/src/DashboardGridLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,26 +172,24 @@ export const DashboardGridLayout: React.FC<DashboardGridLayoutProps> = ({
const options = (widget.options || {}) as Record<string, any>;
if (widgetType === 'bar' || widgetType === 'horizontal-bar' || widgetType === 'line' || widgetType === 'area' || widgetType === 'pie' || widgetType === 'donut' || widgetType === 'scatter' || widgetType === 'funnel') {
const widgetData = (widget as any).data || options.data;
// Widget-level fields (from config panel) override options-level fields
const xAxisKey = widget.categoryField || options.xField || 'name';
const yField = widget.valueField || options.yField || 'value';
const xAxisKey = options.xField || 'name';
const yField = options.yField || 'value';

// provider: 'object' — delegate to ObjectChart for async data loading
// provider: 'object' — delegate to ObjectChart for async data loading.
// Field/aggregate config comes from the nested data provider (the
// pre-ADR-0021 top-level analytics keys were retired in framework#3320).
if (isObjectProvider(widgetData)) {
// Merge widget-level fields with data provider config.
// Widget-level fields take precedence so that config panel
// edits are immediately reflected in the live preview.
const providerAgg = widgetData.aggregate;
const effectiveAggregate = providerAgg ? {
field: widget.valueField || providerAgg.field,
function: widget.aggregate || providerAgg.function,
groupBy: widget.categoryField || providerAgg.groupBy,
field: providerAgg.field,
function: providerAgg.function,
groupBy: providerAgg.groupBy,
} : undefined;
const effectiveYField = effectiveAggregate?.field || yField;
return {
type: 'object-chart',
chartType: widgetType,
objectName: widget.object || widgetData.object,
objectName: widgetData.object,
aggregate: effectiveAggregate,
xAxisKey: xAxisKey,
series: [{ dataKey: effectiveYField }],
Expand All @@ -200,28 +198,8 @@ export const DashboardGridLayout: React.FC<DashboardGridLayoutProps> = ({
};
}

// No explicit data provider but widget has object binding
// (e.g. newly created widget via config panel) — build object-chart
if (!widgetData && widget.object) {
const aggregate = widget.aggregate ? {
field: widget.valueField || 'value',
function: widget.aggregate,
groupBy: widget.categoryField || 'name',
} : undefined;
return {
type: 'object-chart',
chartType: widgetType,
objectName: widget.object,
aggregate,
xAxisKey: xAxisKey,
series: [{ dataKey: widget.valueField || 'value' }],
colors: CHART_COLORS,
className: "h-full"
};
}

const dataItems = Array.isArray(widgetData) ? widgetData : widgetData?.items || [];

return {
type: 'chart',
chartType: widgetType,
Expand All @@ -242,7 +220,7 @@ export const DashboardGridLayout: React.FC<DashboardGridLayoutProps> = ({
return {
type: 'data-table',
...restOptions,
objectName: widget.object || widgetData.object,
objectName: widgetData.object,
dataProvider: widgetData,
data: [],
searchable: false,
Expand All @@ -251,19 +229,6 @@ export const DashboardGridLayout: React.FC<DashboardGridLayoutProps> = ({
};
}

// No explicit data provider but widget has object binding
if (!widgetData && widget.object) {
return {
type: 'data-table',
...options,
objectName: widget.object,
data: [],
searchable: false,
pagination: false,
className: "border-0"
};
}

return {
type: 'data-table',
...options,
Expand All @@ -283,7 +248,7 @@ export const DashboardGridLayout: React.FC<DashboardGridLayoutProps> = ({
return {
type: 'pivot',
...restOptions,
objectName: widget.object || widgetData.object,
objectName: widgetData.object,
dataProvider: widgetData,
data: [],
};
Expand Down
Loading
Loading