ObjectUIObjectUI
Fields

Summary Field

Read-only aggregation field for rollup calculations

The Summary Field component displays aggregated values from related records. This is a read-only field where the value is automatically calculated by the backend through rollup aggregations.

Count Summary

Count Of Related Records

42

Sum Summary

Sum Of Field Values

15,750.5

Average Summary

Average Of Field Values

4.52

Field Schema

A summary field is authored as SummaryFieldMetadata (@object-ui/types), which is the source of truth for the key set: it extends BaseFieldMetadata with the roll-up definition summaryOperations. summaryOperations is @objectstack/spec's own FieldSchema.summaryOperations, typed by reference: the child object, the child field to aggregate, the aggregation function — a closed union of 'count' | 'sum' | 'min' | 'max' | 'avg' — and optionally the child's relationshipField and a filter restricting which child rows are aggregated.

import type { SummaryFieldMetadata } from '@object-ui/types';

const totalRevenue: SummaryFieldMetadata = {
  type: 'summary',
  name: 'total_revenue',
  label: 'Total Revenue',
  readonly: true,
  summaryOperations: {
    object: 'opportunities',
    field: 'amount',
    function: 'sum',
    filter: { stage: 'closed_won' },
  },
};

The computed value, and the className a host supplies, are not metadata keys — they are runtime widget props. See Field Widget Props.

Aggregation Functions

The function decides what the backend computes, not how the value is drawn. The form and the table cell read the same rule for every function, so one stored value reads the same in both:

  • a number: Formatted as a number field formats it, in the viewer's display locale (15750.5 reads 15,750.5 in en-US). With no scale on the field it keeps its own precision, so a count reads as a whole number (12000 reads 12,000); a scale on the field sets a fixed width in both places (scale: 2 reads 15,750.50)
  • anything else: The value as text; an empty value reads as empty

The five functions:

  • count: Count of related records
  • sum: Sum of numeric field values
  • avg: Average of numeric field values
  • min: Minimum value in the field
  • max: Maximum value in the field

Examples

{
  type: 'summary',
  name: 'task_count',
  label: 'Open Tasks',
  summaryOperations: {
    object: 'tasks',
    field: 'id',
    function: 'count'
  }
}

Sum Amounts

{
  type: 'summary',
  name: 'total_sales',
  label: 'Total Sales',
  summaryOperations: {
    object: 'invoices',
    field: 'amount',
    function: 'sum'
  }
}

Average Value

{
  type: 'summary',
  name: 'avg_response_time',
  label: 'Avg Response Time',
  summaryOperations: {
    object: 'support_tickets',
    field: 'response_time_hours',
    function: 'avg'
  }
}

Min/Max Values

{
  type: 'summary',
  name: 'highest_bid',
  label: 'Highest Bid',
  summaryOperations: {
    object: 'bids',
    field: 'amount',
    function: 'max'
  }
}

Cell Renderer

In tables/grids, a summary value is rendered by the formula cell renderer — getCellRenderer('summary') resolves to this same component:

import { FormulaCellRenderer } from '@object-ui/fields';

// <FormulaCellRenderer value={15750.5} field={field} /> renders the computed
// value as a number, through the number cell: 15,750.5 (en-US), not monospace
// A null or empty value renders an em-dash instead.

Backend Implementation

Summary fields are calculated through database aggregations:

// Example backend aggregation
const calculateSummary = async (summaryOperations: SummaryOperations, parentId: string) => {
  const { object, field, function: fn } = summaryOperations;
  
  switch (fn) {
    case 'count':
      return db.count(object, { parent_id: parentId });
    
    case 'sum':
      return db.sum(object, field, { parent_id: parentId });
    
    case 'avg':
      return db.avg(object, field, { parent_id: parentId });
    
    case 'min':
      return db.min(object, field, { parent_id: parentId });
    
    case 'max':
      return db.max(object, field, { parent_id: parentId });
  }
};

Use Cases

  • Order Management: Total order value, order count
  • CRM: Number of contacts, total deal value
  • Project Management: Task count, total hours
  • Analytics: Average ratings, min/max values
  • Financial: Sum of expenses, average transaction size

On this page