Changelog (1.1.0)
June 29, 2026 · 5 min read
#v1.1.0 - Provider refactor, Chart Types, Widgets & Private Views
#Chart Types
| Type | What you get |
|---|---|
| 2D Chart | Typical 2D charts, uses Rechart |
| Aggregate | KPI summary cards showing the aggregated value for each stat |
| List | Paginated data tables with aggregate rows (sum, average, min, max, count) |
#Widget for Dashboard Embedding
You can now embed charts as a standalone widget anywhere in the Medusa admin dashboard. The widget handles its own data fetching and renders independently.
#Revamped UIs
All user interfaces were revamped to improve the visual attractiveness and UX.
#Internationalization
All UI text is now translatable. English translations are built-in under the stats namespace.
Providers now also provide their own translation files for their metrics and parameters.
#Private Views
You can mark a view as private so only you see it.
#Providers
#Provider API Rewrite
The providers were rewritten to use a decorator-based API to allow for better DX and less redundancy.
class MyProvider extends AbstractStatisticsProvider {
static identifier = "my-provider"
@StatFn("total_orders", {
schema: z.object({ status: z.enum(["completed", "pending"]).default("completed") }),
dimension: "time",
})
async totalOrders({ parameters, ...input }: StatCalculationInput): Promise<StatisticResult> {
const timeSeries = await createQueryTimeSeries(this.query, input, {
entity: "order",
fields: ["id", "created_at"],
filters: { status: parameters.status },
}, count())
return { value: timeSeries }
}
}
StatBuilder- removed, use@StatFninstead.getAvailableStatistics()andcalculateStatistic()- removed.displayName- removed, use i18n translation files instead.
#New Shared Utilities
These are exported from medusa-stats and available in your custom providers:
| Export | What it does |
|---|---|
createTimeSeries(data, start, end, interval, accumulator) | Bucket pre-fetched data into time intervals |
createQueryTimeSeries(query, input, config, accumulator) | Query an entity and bucket results in one call |
count() | Accumulator: number of items per bucket |
sum("field") | Accumulator: sum of a numeric field per bucket |
average("field") | Accumulator: average of a numeric field per bucket |
groupBy(data, keySelector, aggregator?) | Group data by a key with optional aggregation |
generateIntervals(start, end, interval) | Generate interval timestamps for a period |
getIntervalBucket(date, periodStart, interval) | Get the interval bucket for a given date |
extractFieldsFromZodSchema(schema) | Derive parameter metadata from a Zod schema |
You can also pass a custom accumulator function to createTimeSeries or createQueryTimeSeries for arbitrary per-bucket logic.
#New API Routes
| Route | Method | Purpose |
|---|---|---|
/admin/statistics/calculate | POST | Ad-hoc calculation without a view — used by the widget |
/admin/statistics/chart-types | GET | Returns available chart types (2d, aggregate, list) |