Search by

uhifadhi / widget-module

Widget: the dashboard machinery every module with a surface would otherwise reinvent — a surface registry modules declare into, one person's adopted preset and layout per surface, and the library component that arranges them.

Maintainers

Package info

github.com/uhifadhilabs/widget-module

Type:symfony-bundle

pkg:composer/uhifadhi/widget-module

Transparency log

Statistics

Installs: 104

Dependents: 5

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.4 2026-09-04 20:22 UTC

This package is auto-updated.

Last update: 2026-09-04 20:51:17 UTC


README

Widget: the dashboard machinery every module with a surface would otherwise reinvent — a surface registry modules declare into, one person's adopted preset and layout per surface, and the library component that arranges them. A uhifadhi platform bundle.

What it is

It provides two tables (widget_preference, widget_custom_preset), a surface registry modules tag into, the resolver that turns a catalogue plus a stored row into a layout, the six write endpoints a library page posts to, the library's own templates and stylesheet, and widget:prune.

It ships zero widgets, the way the seam ships zero modules. What a widget shows belongs to the module that declared it; what arranges it belongs here.

Installation

This module stores preferences per person, so it needs an account class answering the user contract before its tables can exist. uhifadhi/team-module is that provider; install them together:

composer require uhifadhi/team-module uhifadhi/widget-module

Flex registers the bundle and writes config/packages/widget.yaml. An installation that brings its own account class may skip team-module and name its own class in the resolution step below instead.

Resolve the user contract

If uhifadhi/team-module is installed, it is already answered and you write nothing — team provides the account class, so team states the resolution itself.

Without team, or with an account class of your own, it is yours to write — and it is one line, merged into the doctrine: block already in the file:

# config/packages/doctrine.yaml
doctrine:
    orm:
        resolve_target_entities:
            Uhifadhi\ModuleContracts\Entity\UserInterface: App\Entity\Person

docs/user-contract.md has the seven questions your class must answer, why naming your own wins over team's, and what fails if the line is missing.

Create the tables

bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate

Declare a surface

A module that wants a dashboard writes a class implementing Uhifadhi\Widget\Registry\WidgetSurfaceInterface and tags the service, then includes @UhifadhiWidget/widgets/_library.html.twig on its own page. docs/declaring-a-surface.md is the worked example.

Learn more

  • docs/architecture.md — how a module, this module and the shared library socket divide a dashboard between them; why widgets are module-specific and machinery is not; who has to depend on this bundle; what happens to stored layouts when a module is removed; and everything this module owns.
  • docs/declaring-a-surface.md — the catalogue vocabulary and the service tag, the one-active-preset model a dashboard obeys, and how a page renders the library.
  • docs/user-contract.mdresolve_target_entities in full: what team answers for you, what you write otherwise, and why there is no configuration tree.
  • docs/schema.md — the two tables, why the area is a uuid and the person a relation, the uniqueness the database guarantees, and widget:prune.
  • docs/development.md — running the suite, including the Postgres database the integration tests need.

License

AGPL-3.0-or-later. See LICENSE.