Row count badge for related entity sections
Just the names, for the field-panel slot. Same lifetime as ClaimableFields.
The fields this panel draws, for the contributions that stand in for one and for the composition snapshot the placement dialog reads.
Held as fields rather than derived in getters: the field-panel slot treats a new array as a structural change, and a getter would hand it one on every change-detection pass. Recomputed only when the projected fields change.
Default expanded state when no persisted state exists
Reference to the parent form component for state delegation. Expected to have IsSectionExpanded, SetSectionExpanded, getSectionDisplayOrder methods.
OptionalFormForm-level context (search filter, showEmptyFields)
Font Awesome icon class for the panel header
OptionalIndicatorsIndicator counts a custom section supplies for content that is NOT rendered by
mj-form-field — a designer, an inline grid, a hand-built editor. Added to the
counts this panel derives from its own fields, so a section that mixes both
reports the union. Omit for ordinary field panels: their state is derived.
<mj-collapsible-panel SectionKey="lines" [Indicators]="{ DirtyCount: LineEditor.EditedRows, ErrorCount: LineEditor.InvalidRows }">
For 'inherited' variant: the parent entity name this section's fields come from. Displayed as "Inherited from X" badge and used for navigation.
OptionalInheritedFor 'inherited' variant: the primary key to navigate to when clicking the badge. (Shared PK in IS-A relationships.)
Flex order, for a panel the form's section order does not know about.
getSectionDisplayOrder answers with the section count for an unknown key, which is
the highest order on the form — so a contribution panel rendered anywhere lands last
regardless of the slot it mounted in. A slot-derived order is passed here instead.
Unique key for state persistence
Display name shown in the panel header
OptionalValidationGraph-path collection names whose validation failures belong to THIS panel —
ValidationSources="Modifications" claims Modifications[2].ProvisionID.
Only needed when a panel hosts a child collection whose path name differs from
its SectionKey: plain field failures are joined automatically from the panel's
mj-form-field children, and a graph path whose leading segment already matches
the SectionKey is claimed without any declaration. Declared HERE, on the panel
that owns the collection, rather than in an app-side fieldName -> sectionKey
map that duplicates a fact the panel owns and drifts silently when a
SectionKey is renamed. Accepts a single name or a list.
Panel visual variant
Whether this panel's header may collapse/expand. Driven by
FormContext.collapsibleSections; when false the panel renders
always-expanded with no toggle chevron (used by dialog/slide-in surfaces
that lock sections open). Undefined / true means collapsible.
Flex order, in precedence: where the user put this panel, then where its host said to put it, then the form's section order.
The user's placement comes first so a dragged panel draws where it was dropped. Order
is a fixed number a host supplies (a contribution panel derives one from its slot); it
applies only while the user has not placed the panel.
Whether the panel is expanded (delegates to form state; always true when not collapsible)
The entity this panel's fields belong to, or '' outside a form.
The host form, when this panel sits in one.
Form stays unknown because the panel is reused outside a form host; this narrows
it for the one place that needs the record and the provider. The import is type-only,
so nothing about the runtime dependency direction changes.
Container-driven hard hide. When true the panel is removed from view
regardless of search state — used by the record-form container to honor
EntityFormConfig.showRelatedEntities / hiddenSectionKeys /
visibleSectionKeys. Composes with (overrides) search visibility so all
existing IsVisible-based section counts stay correct.
Indicator counts mirrored onto the host element, so CSS and any DOM sweep can read a section's state without a component reference.
True when a contribution could claim one of this panel's fields.
Persisted accordion resize height for related-entity panels. Related grids size themselves from row count (accordion and left-nav), so a pinned pixel height — especially 0 / toolbar-only measured while collapsed — would clip the grid. Only honor a user drag that is at least the CSS min-height.
Whether drag-to-reorder is allowed (from FormContext)
Live state of this section: fields edited since the last save, fields that are
invalid or required-and-empty, and fields carrying warnings. Derived from the
projected mj-form-fields on every read — the same state those fields use for
their own amber dot and red underline, so the section can never disagree with
its fields — plus graph-path validation failures this section claims, plus
whatever a custom section supplies through [Indicators].
Read during change detection (host bindings, the header template, the rail via the coordinator). Pure and cheap: one pass over the field list.
Normalized ValidationSources.
FormSectionIndicatorSource — the rail reads this through the coordinator.
Whether this panel matches a section-search term by title or field name. Ignores chrome hide/show — the rail uses this to decide if the group matches, even when another section is currently selected.
A callback method that is invoked immediately after Angular has completed initialization of all of the directive's content. It is invoked only once when the directive is instantiated.
A callback method that is invoked immediately after Angular has completed initialization of a component's view. It is invoked only once when the view is instantiated.
A callback method that is invoked immediately after the default change detector has checked data-bound properties if at least one has changed, and before the view and content children are checked.
The changed properties.
A callback method that performs custom clean-up, invoked immediately before a directive, pipe, or service instance is destroyed.
A callback method that is invoked immediately after the default change detector has checked the directive's data-bound properties for the first time, and before any of the view or content children have been checked. It is invoked only once when the directive is instantiated.
Navigate to the parent entity when clicking the "Inherited from X" badge. Derives the PrimaryKey from the Form's record when InheritedRecordPrimaryKey is not explicitly provided (which is the common case in generated templates).
FormSectionIndicatorSource — whether a form-level error belongs to this section.
FormSectionFieldHost — a field rendered inside this section, at any view depth.
Reusable collapsible panel for form sections.
Supports three visual variants:
Features:
mj-form-fields (plus anything a custom section supplies through[Indicators]), published to the form's chrome rail through FormSectionIndicatorCoordinatorWhich fields belong to the section. Two sources, unioned: the
@ContentChildrenquery over projected content, and fields that registered themselves through FORM_SECTION_FIELD_HOST, which this panel provides. The content query cannot see a field declared inside a child component's own template (a widget projected into the panel), and a section that saw none of its fields reported no required-and-empty count, claimed none of the failed save's field errors, and so never badged on the rail. The injector follows the element tree across view boundaries, so the registered set covers exactly those fields. A registered field counts only while its element is physically inside this panel, which keeps a field created in an overlay that happened to inherit this injector from being counted.Example