{{- /* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial */ -}} {{- /* SPDX-FileCopyrightText: 2025-2026 Christian Galo */ -}} {{/* operator_plan_topology.html The cross-ladder topology overview, included by operator_plan_ladders.html under its "Plan topology" section header: the ladders-by-rank grid, then the off-ladder / shared / org-type subsections, each titled by sectionHeader. Read-only; every drill-in links into existing CRUD (cross-refs link identifiers, never buttons). The inline structural-validation health strip this once carried was retired in acceptance-fixes round 2 (design D8, operator-topology- overview "Overview surfaces structural-validation health inline"): the one check it ran is impossible under the database's exclusion constraint. */}}

The whole plan catalog at a glance. Ladders are columns in member-facing order; ranks are rows. Drag a ladder column by its handle (⣿) to reorder.

Open a ladder to reorder its tiers.

{{ if .Error }} {{ else }} {{/* The cross-ladder grid. */}} {{ if eq (len .Ladders) 0 }}

No plan ladders configured yet.

{{ else }}
{{ range .Ladders }} {{ end }} {{ if eq (len .Rows) 0 }} {{/* Empty-state row spans the Rank column (a leading {{ else }} {{ range .Rows }} {{ range .Cells }} {{ end }} {{ end }} {{ end }}
Rank {{/* operator-topology-overview "One ladder has no handle": a handle to reorder among siblings means nothing when there is only one column. */}} {{ if gt (len $.Ladders) 1 }} {{ end }} {{ .Name }}
{{ .AttachmentCountLabel }}
, matching the populated rows) plus one cell per ladder column, so the placeholder covers the whole grid width (audit finding #13). Split into two cells because the template FuncMap has no arithmetic helper for len(.Ladders)+1. */}} No tiers configured on any ladder.
{{ .Rank }} {{ if .Present }} {{ .ProductName }} {{ if .Shared }} {{ template "statusBadge" .SharedBadge }}{{ end }} {{ if ne .LifecycleStatus "published" }} {{ template "statusBadge" .LifecycleBadge }}{{ end }} {{ else }} {{ end }}
{{ end }} {{/* Off-ladder products, bucketed by display_category (presentation only). */}} {{ template "sectionHeader" .OffLadderHeader }} {{ if eq (len .Addons) 0 }}

No off-ladder products.

{{ else }} {{ end }} {{/* Shared-product reverse index (the M:N made explicit). */}} {{ template "sectionHeader" .SharedHeader }} {{ if eq (len .SharedProducts) 0 }}

No products are shared across ladders.

{{ else }} {{ end }} {{/* Per-org-type provisioning summary (auto-provisioning config as outcome). */}} {{ template "sectionHeader" .OrgTypesHeader }} {{ if eq (len .OrgTypes) 0 }}

No org types configured.

{{ else }}
{{ range .OrgTypes }} {{ end }}
Org type New organizations are provisioned
{{ .DisplayName }} {{ if .HasDefault }} {{ .LadderName }} @ rank 0 {{ .RankZeroProduct }} {{ else }} No default (off-ladder) {{ end }}
{{ end }} {{ end }}