Skip to content

Ui5Tile

Introduction

The Ui5Tile is a UI5 artifact that renders a single visual primitive — a sap.m.GenericTile / ActionTile / SlideTileinside a dashboard group. A tile is a compact status, KPI, or entry point.

Unlike most artifacts, a tile is not routable: it has no URL, no manifest, and no standalone endpoint. It exists only as part of a Ui5Dashboard, and its whole control (shell and content) is computed by its provider at the moment the dashboard is emitted.

Conceptual Overview

Two seats, two jobs

  • The tile class (Ui5TileInterface) is pure metadata: identity, the slots it depends on, and a handle to its provider. It is deliberately not a template factory — a tile's shell (subheader, value color, …) is frequently data-driven, so only the executor, which has the data, can build it.

  • The tile provider (TileProviderInterface) is the executor. It computes the entire typed tile from the bound slot values and the request context:

    php
    public function getTile(array $boundParams, Ui5ContextInterface $context): Tile;

Lifecycle

  1. The tile is declared in a module and referenced from a dashboard group.
  2. When the dashboard is emitted, the framework resolves the tile's required slots and calls getTileProvider()->getTile($boundParams, $context).
  3. The provider returns a GenericTile (or ActionTile / SlideTile), built from the data; the framework places it verbatim into the dashboard tree.

The provider reads the actor from $context, never from a slot — slots carry wire-shaped values, identity comes from the context.

How to Generate

bash
php artisan ui5:tile Offers/ProjectKpi \
  --title="Project KPI" \
  --description="Displays aggregated project health indicators"

Options

OptionDefaultDescription
name (argument)(required)Format: {AppName}/{TileName}
--titleThe tile nameTile title
--descriptionTile generated via ui5:tileTile description
--seed[=<name>](bare)Scaffold the provider from a named seed (see Seeding)

The PHP and JS namespaces are derived from the target app's module — there are no namespace-prefix options.

Output

Given php artisan ui5:tile Offers/ProjectKpi:

ui5/
└── Offers/
    └── src/
        └── Tiles/
            ├── ProjectKpiTile.php
            └── Provider/
                └── ProjectKpiTileProvider.php

On success the command prints the exact registration directives — the module method to edit (getTiles()) and the owning Dashboard Group's getChildNamespaces(), each with the literal line to add. Composition is explicit by design; the command tells you precisely what to wire.

Seeding

By default the TileProvider is a bare shell — a valid tile that boots but shows a placeholder value (NumericContent with 0). Sample data never lives in the default stub.

To scaffold a populated starting point instead, pass --seed:

bash
php artisan ui5:tile Offers/Revenue --seed=revenue   # a named seed
php artisan ui5:tile Offers/Revenue --seed           # pick from the catalog

--seed swaps exactly one file — the TileProvider — for the seed's version; the tile POPO and everything else are emitted exactly as they would be bare. An unknown seed name fails with the list of available seeds. The tile seed catalog ships revenue, new-customers, and open-deals; it is open content — adding a seed is a stub plus a seeds.json row, no command change.

Artifact Roles

ProjectKpiTile.php

Implements Ui5TileInterface. Identity is declared as class constants (the getters are inherited from AbstractUi5Tile); the only behaviour is the handle to its provider:

plannedThe generators still slug the URL segment with `Str::snake` for tiles, charts, actions, reports and resources — so a freshly scaffolded one reads `project_kpi`. Moving them all to `kebab` is queued; it changes new scaffolds only, never an existing artifact.
php
class ProjectKpiTile extends AbstractUi5Tile
{
    public const string NAMESPACE   = 'com.acme.offers.tiles.project-kpi';
    public const string VERSION     = '1.0.0';
    public const string TITLE       = 'Project KPI';
    public const string DESCRIPTION = 'Displays aggregated project health indicators';

    public function getTileProvider(): string
    {
        return ProjectKpiTileProvider::class;
    }
}

getTileProvider() declares the provider by class-string; the framework resolves it through the container, so the provider's constructor dependencies are autowired. Never write return app(...) or return new ... here — a declaration method declares, it does not build.

If the tile depends on slot values, declare them with getRequiredSlots(); the resolved values arrive in $boundParams. (See Slots.)

ProjectKpiTileProvider.php

Builds the whole tile. Follow the injection recipe: services go in the constructor (autowired, since the framework resolves the declared class-string through the container); the per-request inputs — $boundParams and $context — arrive as the typed getTile() arguments.

php
class ProjectKpiTileProvider implements TileProviderInterface
{
    public function __construct(private readonly ProjectMetrics $metrics) {}

    public function getTile(array $boundParams, Ui5ContextInterface $context): Tile
    {
        return new GenericTile(
            header: 'Project KPI',
            tileContent: [
                new TileContent(
                    content: new NumericContent(
                        value:     (string) $this->metrics->health(),
                        scale:     '%',
                        indicator: DeviationIndicator::Up,
                    ),
                ),
            ],
        );
    }
}

Module Integration

Register tiles in their module's getTiles(), passing the module instance:

php
public function getTiles(): array
{
    return [
        new Tiles\ProjectKpiTile($this),
    ];
}

A tile is rendered by referencing its ::NAMESPACE from a dashboard group's getChildNamespaces() — see Ui5Dashboard. There is no route to configure: tiles are composed, not addressed.

Best Practices

  • Keep the tile class metadata-only; build the visual in the provider.
  • Inject services via the provider's constructor; take per-request values from $boundParams / $context.
  • One tile, one purpose; use value color / indicator to communicate urgency.
  • For a tile that presses through to a destination, emit an ActionTile and let the dashboard's action event carry the intent (see Ui5Dashboard).