Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nowo-tech/DashboardMenuBundle/llms.txt

Use this file to discover all available pages before exploring further.

All notable changes are documented here. The format follows Keep a Changelog and this project adheres to Semantic Versioning.

Fixed

  • Dashboard import modal: AJAX import submit now follows redirects reliably and navigates back to the dashboard index after successful imports, avoiding a stuck modal state on 302 responses.
  • Dashboard item list: item rows are rendered in deterministic tree order (parent/children traversal with sibling sort by position, then id) so visual ordering matches stored positions.
  • Dashboard table UX: item position is displayed under the parent label to make ordering and debugging easier.
  • Tests: migration command integration assertion for --dump output is now robust to Symfony console note line-wrapping.

Changed

  • Performance (N+1 reduction):
    • Menu copy now clones items from a preloaded flat list in two passes (no recursive getChildren() lazy traversal)
    • Descendant id resolution for item edit uses preloaded menu items + in-memory BFS
    • Import post-processing clears link fields for parents with children using an in-memory hasChildren map (no per-item lazy children->count())
    • Export-all loads items for all menus in a single repository query and groups in memory

Fixed

  • Dashboard UI: menu item labels are rendered using locale-resolved MenuItem::getLabelForLocale() (avoids empty base label when text is stored in per-locale translations).
  • Dashboard item forms: “Add child” modal hides type, icon and position inputs and shows only label + per-locale translations (item type is fixed to Link).
  • Dashboard item forms: the icon section is rendered with a normal Symfony form (not LiveComponent) so the icon-selector widget refreshes reliably when the modal content changes.
  • Dashboard item forms: label validation accepts either a non-empty base label or at least one non-empty translation; empty position values are normalized to 0 to prevent null mapping issues.

Changed

  • Docs/UX: item form rendering and documentation were aligned for section-based partial submissions (section/_section, section_focus).

Fixed

  • LiveComponent: prevent Symfony “submitted form data” exceptions when saving items, and stabilize hydration of per-locale label_{locale} fields in the item modal.
  • Dashboard UI: item modal icon field prefill is normalized; when the optional icon-selector bundle is installed it uses IconSelectorType, otherwise it falls back to a plain text input.

Changed

  • Demos: dashboard asset builds (make assets / make ts-assets) run inside the demo Docker container to avoid host pnpm/permission issues.

Added

  • Config: dashboard.icon_size — CSS size used to render menu item icons (SVG width/height and legacy icon font-size).

Fixed

  • Twig/UI: menu item labels are rendered using the locale-resolved MenuItem.label (already resolved by MenuTreeLoader), avoiding an extra translation pass in Twig.

Added

  • Config/UI: wrapper <span> for non-section menu items controlled by dashboard.item_span_active, with wrapper class configurable via dashboard.css_class_options.span.

Added

  • Config: dashboard.id_options — list of HTML id values for the root <ul> of each rendered menu. Drives the dashboard field ulId (dropdown vs plain text).
  • Menu entity: new nullable property Menu.ulId (DB column ul_id).
  • Dashboard UI: menu configuration includes ulId; the frontend template sets id="..." on the root <ul> when configured.
  • Import/export: menu export/import now includes ulId.
  • Migration generator: nowo_dashboard_menu:generate-migration --update can add the missing ul_id column.

Added

  • UX Autocomplete detection: new Twig global nowo_dashboard_ux_autocomplete_available computed from the presence of Symfony\UX\Autocomplete\AutocompleteBundle. Dashboard item form templates apply the autocomplete form theme only when available.
  • CSRF consistency: dashboard menu item forms set csrf_token_id to submit (controller + LiveComponent) to keep CSRF behaviour aligned across Symfony versions.

Changed

  • MenuDashboardController: when creating a child item, uses _query to include parent id in the generated URL.
  • Templates: wraps {% form_theme '@SymfonyUXAutocomplete/autocomplete_form_theme.html.twig' %} in the new availability guard.

Fixed

  • Avoid warnings/errors when Symfony UX Autocomplete is not installed.
  • Demo Symfony 7: enable sessions, CSRF support, and framework.property_info for older Symfony configs.

Added

  • Config: dashboard.permission_key_choices — optional list of permission keys for the menu item form. When set, the field becomes a select with autocomplete.
  • Dashboard item form: route name selector and (when configured) permission key selector use Symfony UX Autocomplete.
  • Dashboard: “Add child” passes parent ID in the form action URL; “Add child” button disabled for section and divider items.
  • Permission checkers: AllowAllMenuPermissionChecker and PermissionKeyAwareMenuPermissionChecker are explicitly tagged with nowo_dashboard_menu.permission_checker.
  • MenuItem: itemType is now nullable (DB column nullable).

Added

  • Dashboard menu form: split into definition (code, base, name, context, icon) and configuration (permission checker, depth, collapsible, CSS classes).
  • Dashboard item form: same definition/configuration split; partial and LiveComponent support section_focus.
  • Redirect to referer: after any successful form submission the controller redirects to the same-origin referer URL; otherwise to the usual route.
  • Import in modal: import form is loaded and submitted via AJAX; on success redirects to referer or index.
  • Translations: dashboard.edit_identity, dashboard.edit_config (en, es, fr).
  • Dockerfile: added Node.js, npm, and pnpm for building dashboard assets inside the container.

Changed

  • MenuItem: label property is now nullable (for divider items); getter returns '' when null.
  • Twig: _menu_form_partial and _item_form_partial no longer use field.vars.rendered (removed in Symfony 6.3+).

Added

  • Menu option: nestedCollapsibleSections — when disabled, section-type items do not show a collapse toggle.
  • Dependency: symfony/mime required for the File validator used in the import form.

Changed

  • Export/import: now includes classSectionLabel and nestedCollapsibleSections.
  • ImportMenuType: constraints use named arguments for Symfony 7/8 compatibility.

Deprecated

  • Config: dashboard.path_prefix is deprecated. Set the dashboard URL prefix in your app routing when importing @NowoDashboardMenuBundle/Resources/config/routes_dashboard.yaml.

Added

  • Security: CSRF validation in deleteMenu() and deleteItem(); invalid or missing token returns 403.
  • Security: move up/down actions now use POST with CSRF tokens.
  • Security: import size limit via dashboard.import_max_bytes (default 2 MiB).
  • Security: optional dashboard.required_role (e.g. ROLE_ADMIN) and dashboard.import_export_rate_limit (returns 429 when exceeded).

Added

  • Translation domain: bundle uses domain NowoDashboardMenuBundle for all UI strings. Constant NowoDashboardMenuBundle::TRANSLATION_DOMAIN available in code.

Changed

  • Translations (breaking for overrides): bundle translation files are now NowoDashboardMenuBundle.{locale}.yaml (replacing messages.* and validators.*). To override strings in your app, create translations/NowoDashboardMenuBundle.{locale}.yaml with the same keys.

Added

  • Dashboard export/import: export one or all menus as JSON (config + item tree, no internal IDs). Import from JSON with strategy Skip existing or Replace.
  • Config: dashboard.layout_template — Twig template that dashboard views extend.
  • MenuUrlResolver: fills missing path parameters from the current request’s route params.

Added

  • Symfony 6.4 LTS: bundle now supports Symfony ^6.4 || ^7.0 || ^8.0; CI tests PHP 8.2–8.5 × Symfony 6.4, 7.0 and 8.0.

Changed

  • nowo-tech/icon-selector-bundle is now optional (moved from require to suggest). The dashboard item form uses IconSelectorType when installed; otherwise the icon field is a plain text input.
This release raised the minimum PHP version to 8.4 and dropped Symfony 7 and Doctrine 2.x support.

Changed (breaking)

  • PHP: minimum version raised to 8.4 (8.2 and 8.3 no longer supported).
  • Symfony: bundle requires Symfony ^8.0 only; Symfony 7 support dropped.
  • Doctrine: requires doctrine/doctrine-bundle ^3.0 and doctrine/orm ^3.0 (2.x no longer supported).

Fixed

  • Doctrine config: removed deprecated auto_generate_proxy_classes from test and demo configs.

Added

  • Cache: configurable tree cache (cache.ttl min 60 s, cache.pool) to avoid N+1 and repeated DB hits.
  • Icon prefix map: icon_library_prefix_map (e.g. bootstrap-icons: bi) so icon identifiers are converted before rendering.
  • Menu loading: two-query SQL path in MenuRepository::findMenuAndItemsRaw(); optional PSR-6 cache.
  • Web Profiler: “Dashboard menus” panel with Menus tab (query count, item tree) and Configuration tab.
  • Doctrine: table name quoting via Platform::quoteSingleIdentifier().

Added

  • Entities: Menu and MenuItem with Doctrine ORM (no Gedmo/Stof). Tree via parent + position; labels with optional JSON translations per locale.
  • Config: project, locales, default_locale, defaults, menus.{code} overrides, api (enabled, path_prefix), dashboard options.
  • MenuTreeLoader: single-query load; labels resolved by request locale; optional permission filter via MenuPermissionCheckerInterface.
  • Twig: dashboard_menu_tree(), dashboard_menu_href(), dashboard_menu_config() functions; @NowoDashboardMenuBundle/menu.html.twig (Bootstrap 5, collapsible).
  • JSON API: GET /api/menu/{code} with optional _locale and _context_sets.
  • Dashboard: CRUD at configurable path (default /admin/menus).
  • Context resolution: menus with same code can have different JSON context; resolved by ordered context sets.
  • Translations: dashboard and form messages in English, Spanish and French.
  • Demos: Symfony 7 and Symfony 8 with FrankenPHP + Caddy, MySQL, fixtures.
  • CI: GitHub Actions (PHP 8.2–8.5 × Symfony 7.0/8.0, code style, coverage, release workflow).
  • Recipe: Symfony Flex recipe for config and routes.

For the complete history including all patch releases, see the GitHub releases page or the full CHANGELOG in the repository.

Build docs developers (and LLMs) love