EntityConfiguration
The central configuration class that brings together all aspects of an entity type: metadata, API, layouts, editor, actions, and routing.
Class Signature
Constructor Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
metadata | EntityMetadata | Yes | Display name, icon, identifier, visibility |
api | EntityApi<T> | Yes | CRUD API implementation |
layouts | EntityLayouts<T> | Yes | List, detail, summary, dashboard, item, comparison, analytics |
actions | EntityActions<T> | Yes | Inline, menu, collection, header actions |
routing | EntityRouting<T> | Yes | Path patterns, route builder, selection mode, route permissions |
editor | EntityEditor<T>? | No | Form/editor configuration |
fields | List<FieldDefinition<T>>? | No | Declarative field definitions for columns/filters |
filterPresets | List<FilterPreset>? | No | System-defined filter presets (from cdx_query) |
referenceFields | Map<String, String>? | No | FK column → target entity identifier for generated reference metadata. New picker fields declare ReferenceFieldType; read-side projections use FieldCompanion.lookup. |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
route | NavigationPathBuilder | -- | Convenience getter for routing.path |
Methods
buildRoutesList<RouteBase> buildRoutes()Generates GoRouter routes via routing.builder.
registervoid register(EntitySystemPlugin plugin)Internal — registers this config with the entity system.
copyWithEntityConfiguration<T> copyWith({...})Returns a copy with overrides — useful for feature packages extending a shared config.
clearAllPermissionCachesstatic void clearAllPermissionCaches()Clears all entity permission caches (call on logout). Delegates to EntityPermissionCache.clearAll().
Behavioural policies are resolved at runtime
EntityConfiguration declares no verification or signature policy. Plain entities use StandardEntityEditor (no verification). Regulated entities use SignatureDrivenEditor which resolves its LifecycleRequirements via a callback during init() — keeping app-specific compliance config out of entity declarations.
Usage Example
final config = EntityConfiguration<Equipment>(
metadata: EntityMetadata(
identifier: 'equipment',
name: 'Equipment',
pluralName: 'Equipment',
icon: Icons.precision_manufacturing,
visibility: UIVisibility.all(menuCategory: operationsCategory),
),
api: EquipmentApi(),
routing: EntityRouting<Equipment>(
path: NavigationPathBuilder.collection(prefix: '/entities/equipment'),
builder: StandardRouteBuilder<Equipment>(),
mode: EntitySelectionMode.navigate,
permissions: EntityRoutePermissions(
list: ['equipment.view'],
create: ['equipment.create'],
),
),
layouts: EntityLayouts<Equipment>(
list: [equipmentTableLayout, equipmentGridLayout],
details: [equipmentDetailLayout],
dashboard: equipmentDashboardLayout,
),
editor: StandardEntityEditor<Equipment>(
transformer: DefaultEntityTransformer<Equipment>(
fromJson: Equipment.fromJson,
),
parts: () => [
FormEditorPart<Equipment>(
title: 'Details',
icon: FluentIcons.edit_24_regular,
identifier: 'details',
getForm: _getEquipmentForm,
),
],
),
actions: EntityActions<Equipment>(
inline: StandardEntityActions.inline<Equipment>(),
header: StandardEntityActions.header<Equipment>(),
),
fields: EquipmentFields.instance.all,
);EntityMetadata
Descriptive information about an entity type, including display names, visibility, categorization, and localization support.
EntityMetadata
Class Signature
Properties
| Property | Type | Default | Description |
|---|---|---|---|
identifier | String | -- | Unique identifier for permission checks and lookups |
name | String | -- | Singular display name (resolves via nameResolver if set) |
pluralName | String | -- | Plural display name (resolves via pluralNameResolver if set) |
category | EntityCategory | EntityCategory.general | Top-level category grouping |
visibility | Set<UIVisibility> | const {} | Surfaces this entity appears on (see UIVisibility) |
icon | IconData? | null | Icon for this entity type |
description | String? | null | Entity-type description (uses resolver if set) |
schemaType | String? | null | Schema-qualified type name (e.g., 'lms.area') |
priority | int | 999 | Sort priority in menus (lower = first) |
isSingleton | bool | false | Single-instance entity (no create operation) |
getHelp | Future<EntityHelpModel?> Function()? | null | Contextual help provider |
nameResolver | String Function()? | null | Localized singular name resolver |
pluralNameResolver | String Function()? | null | Localized plural name resolver |
descriptionResolver | String Function()? | null | Localized description resolver |
alternateIdentifiers | List<String> | [] | Alternate identifiers for flexible lookup |
subtitleBuilder | String? Function(EntityBase)? | null | One-line subtitle for picker / reference contexts |
Computed visibility getters
Class Signature
Properties
| Property | Type | Default | Description |
|---|---|---|---|
hasRoutes | bool | -- | True if visibility contains a route or menu visibility |
isVisibleInMenu | bool | -- | True if visibility contains MenuVisibility |
isSearchable | bool | -- | True if visibility contains SearchVisibility |
isVisibleInDashboard | bool | -- | True if visibility contains DashboardVisibility |
menuVisibility | MenuVisibility? | -- | The MenuVisibility entry, if any |
searchVisibility | SearchVisibility? | -- | The SearchVisibility entry, if any |
menuCategory | MenuCategory? | -- | Shorthand for menuVisibility?.menuCategory |
Localization Example
EntityMetadata(
identifier: 'areas',
name: 'Area',
nameResolver: () => t.strings.lms.entities.area.singular,
pluralName: 'Areas',
pluralNameResolver: () => t.strings.lms.entities.area.plural,
alternateIdentifiers: ['area'],
)UIVisibility
A sealed class declaring where an entity is exposed in the application. Pass a Set<UIVisibility> to EntityMetadata.visibility. Each surface type can appear at most once.
sealed class UIVisibility {
const UIVisibility();
const factory UIVisibility.route() = RouteVisibility;
const factory UIVisibility.menu({MenuCategory? menuCategory, int sortOrder}) = MenuVisibility;
const factory UIVisibility.search({List<String> additionalSearchTerms}) = SearchVisibility;
const factory UIVisibility.dashboard() = DashboardVisibility;
static Set<UIVisibility> all({MenuCategory? menuCategory, int sortOrder = 0});
}| Variant | Effect |
|---|---|
RouteVisibility | Generates GoRouter routes (list, detail, create, edit). |
MenuVisibility({menuCategory, sortOrder}) | Shows in navigation menu. Implies routes. |
SearchVisibility({additionalSearchTerms}) | Discoverable via command palette / global search. |
DashboardVisibility | Appears in dashboard widgets. |
// All standard surfaces (route + menu + search + dashboard)
visibility: UIVisibility.all(menuCategory: masterData),
// Routes + searchable, but not in menu
visibility: {const UIVisibility.route(), const UIVisibility.search()},
// Invisible (junction tables, embedded entities — no routes, no UI)
visibility: const {},EntityActions
Groups all action configurations for an entity. The class lives in vyuh_entity_system and the constructor is plain — most apps build it with the standard helpers from vyuh_entity_system_ui.
EntityActions
Class Signature
Properties
| Property | Type | Default | Description |
|---|---|---|---|
inline | List<EntityAction<T>> | -- | Inline actions in detail view (edit, delete) |
menu | List<ActionGroup<T>> | [] | Dropdown menu action groups |
collection | List<CollectionAction<T>> | [] | Bulk actions for multiple selected entities |
header | List<CollectionAction<T>> | [] | Header actions between layout controls and filter (typically Create) |
Methods
EntityActions.functionfactory EntityActions.function(EntityActions<T> Function() factory)Build via a factory function — useful for moving complex wiring out of const annotations. Evaluated eagerly.
copyWithEntityActions<T> copyWith({inline?, menu?, collection?, header?})Returns a copy with updates.
For the full action surface — EntityAction<T>, CollectionAction<T>, ActionGroup<T>, EditorAction<T>, StandardEntityActions, VersionableActions — see Actions.
actions: EntityActions<Equipment>(
inline: StandardEntityActions.inline<Equipment>(
editAuthorize: Authorize.permission('equipment.edit'),
deleteAuthorize: Authorize.permission('equipment.delete'),
),
header: StandardEntityActions.header<Equipment>(),
),EntityRouting
EntityRouting
Class Signature
Properties
| Property | Type | Default | Description |
|---|---|---|---|
path | NavigationPathBuilder | -- | URL pattern builder (collection or singleton) |
builder | NavigationRouteBuilder<T> | -- | GoRouter route generator (typically StandardRouteBuilder) |
mode | EntitySelectionMode | EntitySelectionMode.navigate | How a row tap in the list view is handled |
permissions | EntityRoutePermissions? | null | Route-level access control |
Consolidated routing configuration. The <T> type parameter is required because builder is a generic NavigationRouteBuilder<T>.
EntityRouting.function(factory) builds via a factory; the factory is called eagerly because routing is resolved at app startup.
NavigationPathBuilder
final class NavigationPathBuilder — generates URL paths for all entity routes.
Factory Constructors
| Constructor | Description |
|---|---|
NavigationPathBuilder.collection({prefix}) | Multi-instance entity routes |
NavigationPathBuilder.singleton({prefix}) | Single-instance entity routes |
prefix is the full route prefix (e.g., /entities/equipment, /sso/roles). Defaults to /entities if omitted.
Path Methods
All methods return String and accept an optional NavSlice.
| Method | Returns | Example Output |
|---|---|---|
list([slice]) | List route | /entities/equipment |
create([slice]) | Create route | /entities/equipment/new |
view(id, [slice]) | View route | /entities/equipment/abc |
edit(id, [slice]) | Edit route | /entities/equipment/abc/edit |
dashboard([slice]) | Dashboard route | /entities/equipment/dashboard |
custom(id, subPath, [slice]) | Custom subpage | /entities/equipment/abc/report |
slice is a NavSlice. NavSlice(tab: 'drafts') opens the draft partition by emitting ?tab=drafts; NavSlice(section: 'history') opens a detail subsection by emitting ?section=history. Additional query parameters are carried on NavSlice.queryParameters. The default approved partition is omitted from the URL, so canonical approved routes stay clean. Singleton paths ignore id for view, edit, and create (which collapses to the edit URL).
EntitySelectionMode
enum EntitySelectionMode { none, navigate, responsive }Controls how EntityListView handles a row click/tap.
| Value | Description |
|---|---|
none | Fire onSelectionChanged only — no navigation. Used for selection-only lists. |
navigate | Navigate to the entity's detail route. Default. |
responsive | Adapt by viewport: navigate on desktop, embed inline (master-detail) on mobile. |
Extension EntitySelectionModeExtension provides a description getter for human-readable labels.
EntityRoutePermissions
const EntityRoutePermissions({
this.list,
this.create,
this.view,
this.edit,
this.dashboard,
});| Property | Type | Description |
|---|---|---|
list | List<String>? | Permissions for the list route |
create | List<String>? | Permissions for the create route |
view | List<String>? | Permissions for the view route |
edit | List<String>? | Permissions for the edit route |
dashboard | List<String>? | Permissions for the dashboard route |
Routes with null permissions are accessible to all authenticated users. At runtime these strings are evaluated through the AuthorizationProvider (Authorize.anyPermission(perms)).
FieldDefinition
abstract class FieldDefinition<T extends EntityBase> — declarative field definitions used for type-safe columns and filters.
Base Class
abstract class FieldDefinition<T extends EntityBase> {
final String field;
String get label;
final bool required;
final bool filterable;
final bool sortable;
final bool primary;
final bool secondary;
final bool showInCard;
final IconData? icon;
final String? placeholder;
final String? helperText;
final int priority; // ColumnPriority constant
final String? sortField;
final String? filterField;
String get fieldType;
String get effectiveSortField;
String get effectiveFilterField;
dynamic getValue(T entity);
}Concrete Subclasses
| Subclass | Field Type | Extra Properties |
|---|---|---|
TextFieldDef<T> | 'text' | maxLines, maxLength |
NumberFieldDef<T> | 'number' | prefix, suffix, allowDecimal, min, max |
EnumFieldDef<T> | 'enum' | options, colorMap, iconMap, displayAs |
BooleanFieldDef<T> | 'boolean' | trueLabel, falseLabel, displayAs |
DateFieldDef<T> | 'date' | format, minDate, maxDate |
DateTimeFieldDef<T> | 'datetime' | format, minDateTime, maxDateTime |
ReferenceFieldDef<T> | 'reference' | foreignKeyField, targetField, targetEntityType, maxLength |
ReferenceFieldDef also exposes a ReferenceFieldDef.auto({...}) factory that auto-derives field as '$foreignKeyField.$targetField'.
ColumnPriority
abstract final class ColumnPriority {
static const int essential = 0;
static const int high = 1;
static const int normal = 2;
static const int low = 3;
}Lower values = higher priority (last to be hidden when space is limited).
See Also
- EntityBase — Base class and mixins that configurations manage
- EntityApi — API contract required by configuration
- Layouts — Layout types used in
EntityLayouts - Editors — Editor used in the
editorparameter - Actions —
EntityAction,CollectionAction, action helpers - Permissions —
AuthorizeDSL, route permissions, guards