Example: Grid Widget

Source project: octopus-widgets/ska-octopus-grid-widget

Why This Example Matters

It demonstrates:

  • Formatted input templates for labels and click values

  • Tango source normalization and hover row normalization

  • Workspace and variable updates as user interactions

  • Endpoint aware source grouping for polling/streaming

Definition Pattern

In src/index.ts, the widget schema uses:

  • INPUT_TANGO_ATTRIBUTES for grid source attributes

  • INPUT_MULTIPLE_TANGO_ATTRIBUTES for hover targets

  • VARIABLES and WORKSPACES selectors

  • INPUT_FORMATED_SCHEMA_TYPE for title and format strings

Snippet adapted from src/index.ts:

const schema = {
  type: "object",
  properties: {
    title: { type: INPUT_FORMATED_SCHEMA_TYPE, title: "Title", default: "" },
    attributes: {
      type: INPUT_TANGO_ATTRIBUTES,
      title: "Tango attributes",
      minItems: 1,
      default: defaultAttributes,
    },
    hoverAttributes: {
      type: INPUT_MULTIPLE_TANGO_ATTRIBUTES,
      title: "Hover attributes",
      default: defaultHoverAttributes,
    },
    selectedVariableKey: { type: "VARIABLES", title: "Selected variable key", default: "" },
    workspace: { type: "WORKSPACES", title: "Workspace", default: "" },
  },
} as const;

Runtime Pattern

In src/GridWidget.tsx, the widget:

  • Resolves attributes using normalizeTangoAttributeInputs

  • Resolves hover rows using normalizeTangoAttributeRows

  • Formats titles/cell labels using formatInputFormattedTemplate

  • Reads and writes host state via useVariables and useWorkspace

Snippet adapted from src/GridWidget.tsx:

const { vars, setVariable } = useVariables();
const { setWorkspace } = useWorkspace();

const resolvedFullNames = normalizeTangoAttributeInputs({
  attributes,
  fallbackAttributes: fullNames,
  fallbackEndpoint: endpoint,
  variables: vars,
});

const resolvedHoverAttributes = normalizeTangoAttributeRows({
  rows: hoverAttributes,
  fallbackEndpoint: endpoint,
  variables: vars,
});

Data Pipeline Pattern

In src/useGridWidgetData.ts, the widget:

  • Groups routed sources by endpoint

  • Supports stream and polling flows

  • Resolves selector style source definitions

  • Produces render ready grid rows with optional hover metadata

What To Reuse In New Widgets

  • Input template workflow from src/index.ts + src/GridWidget.tsx

  • Dynamic workspace/variable integration

  • Endpoint grouping pattern for mixed routed sources

Related docs: