Skip to content

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

ParameterTypeRequiredDescription
metadataEntityMetadataYesDisplay name, icon, identifier, visibility
apiEntityApi<T>YesCRUD API implementation
layoutsEntityLayouts<T>YesList, detail, summary, dashboard, item, comparison, analytics
actionsEntityActions<T>YesInline, menu, collection, header actions
routingEntityRouting<T>YesPath patterns, route builder, selection mode, route permissions
editorEntityEditor<T>?NoForm/editor configuration
fieldsList<FieldDefinition<T>>?NoDeclarative field definitions for columns/filters
filterPresetsList<FilterPreset>?NoSystem-defined filter presets (from cdx_query)
referenceFieldsMap<String, String>?NoFK column → target entity identifier for generated reference metadata. New picker fields declare ReferenceFieldType; read-side projections use FieldCompanion.lookup.

Properties

PropertyTypeDefaultDescription
routeNavigationPathBuilder--Convenience getter for routing.path

Methods

  • buildRoutes
    List<RouteBase> buildRoutes()

    Generates GoRouter routes via routing.builder.

  • register
    void register(EntitySystemPlugin plugin)

    Internal — registers this config with the entity system.

  • copyWith
    EntityConfiguration<T> copyWith({...})

    Returns a copy with overrides — useful for feature packages extending a shared config.

  • clearAllPermissionCaches
    static 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

dart
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

PropertyTypeDefaultDescription
identifierString--Unique identifier for permission checks and lookups
nameString--Singular display name (resolves via nameResolver if set)
pluralNameString--Plural display name (resolves via pluralNameResolver if set)
categoryEntityCategoryEntityCategory.generalTop-level category grouping
visibilitySet<UIVisibility>const {}Surfaces this entity appears on (see UIVisibility)
iconIconData?nullIcon for this entity type
descriptionString?nullEntity-type description (uses resolver if set)
schemaTypeString?nullSchema-qualified type name (e.g., 'lms.area')
priorityint999Sort priority in menus (lower = first)
isSingletonboolfalseSingle-instance entity (no create operation)
getHelpFuture<EntityHelpModel?> Function()?nullContextual help provider
nameResolverString Function()?nullLocalized singular name resolver
pluralNameResolverString Function()?nullLocalized plural name resolver
descriptionResolverString Function()?nullLocalized description resolver
alternateIdentifiersList<String>[]Alternate identifiers for flexible lookup
subtitleBuilderString? Function(EntityBase)?nullOne-line subtitle for picker / reference contexts

Computed visibility getters

Class Signature

Properties

PropertyTypeDefaultDescription
hasRoutesbool--True if visibility contains a route or menu visibility
isVisibleInMenubool--True if visibility contains MenuVisibility
isSearchablebool--True if visibility contains SearchVisibility
isVisibleInDashboardbool--True if visibility contains DashboardVisibility
menuVisibilityMenuVisibility?--The MenuVisibility entry, if any
searchVisibilitySearchVisibility?--The SearchVisibility entry, if any
menuCategoryMenuCategory?--Shorthand for menuVisibility?.menuCategory

Localization Example

dart
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.

dart
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});
}
VariantEffect
RouteVisibilityGenerates GoRouter routes (list, detail, create, edit).
MenuVisibility({menuCategory, sortOrder})Shows in navigation menu. Implies routes.
SearchVisibility({additionalSearchTerms})Discoverable via command palette / global search.
DashboardVisibilityAppears in dashboard widgets.
dart
// 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

PropertyTypeDefaultDescription
inlineList<EntityAction<T>>--Inline actions in detail view (edit, delete)
menuList<ActionGroup<T>>[]Dropdown menu action groups
collectionList<CollectionAction<T>>[]Bulk actions for multiple selected entities
headerList<CollectionAction<T>>[]Header actions between layout controls and filter (typically Create)

Methods

  • EntityActions.function
    factory EntityActions.function(EntityActions<T> Function() factory)

    Build via a factory function — useful for moving complex wiring out of const annotations. Evaluated eagerly.

  • copyWith
    EntityActions<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.

dart
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

PropertyTypeDefaultDescription
pathNavigationPathBuilder--URL pattern builder (collection or singleton)
builderNavigationRouteBuilder<T>--GoRouter route generator (typically StandardRouteBuilder)
modeEntitySelectionModeEntitySelectionMode.navigateHow a row tap in the list view is handled
permissionsEntityRoutePermissions?nullRoute-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.


final class NavigationPathBuilder — generates URL paths for all entity routes.

Factory Constructors

ConstructorDescription
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.

MethodReturnsExample 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

dart
enum EntitySelectionMode { none, navigate, responsive }

Controls how EntityListView handles a row click/tap.

ValueDescription
noneFire onSelectionChanged only — no navigation. Used for selection-only lists.
navigateNavigate to the entity's detail route. Default.
responsiveAdapt by viewport: navigate on desktop, embed inline (master-detail) on mobile.

Extension EntitySelectionModeExtension provides a description getter for human-readable labels.


EntityRoutePermissions

dart
const EntityRoutePermissions({
  this.list,
  this.create,
  this.view,
  this.edit,
  this.dashboard,
});
PropertyTypeDescription
listList<String>?Permissions for the list route
createList<String>?Permissions for the create route
viewList<String>?Permissions for the view route
editList<String>?Permissions for the edit route
dashboardList<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

dart
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

SubclassField TypeExtra 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

dart
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 editor parameter
  • ActionsEntityAction, CollectionAction, action helpers
  • PermissionsAuthorize DSL, route permissions, guards