Hyvä Admin for Magento 2

repository·main·Indexed 41 days ago

https://github.com/hyva-themes/magento2-hyva-admin

A Magento 2 module designed to replace the complex UI Component system for creating admin grids and forms. It leverages Tailwind CSS and Alpine.js to provide a faster developer experience, featuring XML-based grid configuration, programmatic column customization via events, and flexible grid source prefetching.

Tokens
38K
Snippets
127
Records
167
Agent score
46%

What's inside Hyvä Admin

  1. Overview of Hyvä Admin

    main

    Hyvä Admin is a Magento 2 module designed to provide a modern way to create admin grids. Its primary goal is to improve the developer experience when building new administrative interfaces in Magento.

    Key characteristics:

    • Non-destructive: Installing the module does not affect existing grids or forms; they remain unchanged.
    • Focus: Currently focused on admin grids, with future support planned for admin forms.
  2. Filter extension attribute columns using prefetch events

    main

    Because extension attributes are often loaded after the main record data, standard grid filtering may not work for them. To implement custom filtering for columns containing extension attributes, you can intercept the data loading process using the hyva_grid_source_prefetch_ event.

    When the RepositoryGridSourceType is about to load grid data, it dispatches an event named hyva_grid_source_prefetch_ followed by a sanitized version of the grid name (where non-alphanumeric characters like - are replaced with underscores).

    How to use this event:

    1. Identify the event name: If your grid name is customer-grid, the event name is hyva_grid_source_prefetch_customer_grid.
    2. Create an Observer: Listen for this event in your events.xml.
    3. Modify Search Criteria: The event provides a search_criteria_container (which wraps the SearchCriteriaInterface), the grid_name, and the record_type.
    4. Apply Logic: You can use the observer to:
      • Modify or replace the SearchCriteria to include filters for extension attributes.
      • Map attribute codes to internal column names.
      • Store filter values to apply them manually when extension attributes are loaded later in the lifecycle.
    // Example of the event dispatch logic in RepositoryGridSourceType
    private function dispatchEvent(
        string $gridName,
        string $recordType,
        SearchCriteriaInterface $searchCriteria
    ): SearchCriteriaInterface {
        $eventName = 'hyva_grid_source_prefetch_' . $this->getGridNameEventSuffix($gridName);
        $container = new SearchCriteriaEventContainer($searchCriteria);
        $this->eventManager->dispatch($eventName, [
            'search_criteria_container' => $container,
            'grid_name'                 => $gridName,
            'record_type'               => $recordType
        ]);
    
        return $container->getSearchCriteria();
    }
  3. Customize grid search criteria using Prefetch Events

    main

    Before grid data is loaded from a grid source object, Hyvä Admin dispatches two events that allow you to intercept and modify the SearchCriteria instance. This is useful for applying global filters or custom search logic to specific grids.

    There are two types of events available:

    1. Specific Grid Event: 'hyva_grid_source_prefetch_' . $suffix. The suffix is the grid name in lowercase with underscores replacing non-alphanumeric characters (e.g., a grid named product-grid dispatches hyva_grid_source_prefetch_product_grid).
    2. Generic Event: 'hyva_grid_source_prefetch', which triggers for all grids.

    Both events provide access to a SearchCriteriaEventContainer which you can use to replace the existing search criteria with your own.

    // Example of how to update search criteria in an observer
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $event = $observer->getEvent();
        /** @var \Hyva\Admin\Model\GridSourceType\RepositorySourceType\SearchCriteriaEventContainer $searchCriteriaContainer */
        $searchCriteriaContainer = $event->getData('search_criteria_container');
        $type = $event->getData('record_type');
    
        // Logic to generate your custom criteria
        $updatedSearchCriteria = $this->changeCriteria($type, $searchCriteriaContainer->getSearchCriteria());
    
        // Apply the new criteria to the container
        $searchCriteriaContainer->replaceSearchCriteria($updatedSearchCriteria);
    }
  4. Choosing the right Grid Source type

    main

    When multiple sources are available for the same data (e.g., Repository vs. Collection vs. Grid Collection), consider the following:

    1. Repository: Best when you need extension attributes that might not be loaded on standard models.
    2. Collection: Standard approach for most DB-backed data.
    3. Grid Collection: Use this if you need aggregate fields or indexed data (e.g., Magento\Sales\Model\ResourceModel\OrderGridCollection provides a full customer name field that is not present in the standard Order model).

    If performance or specific data availability isn't a concern, use whichever is most readily available in your implementation.

  5. Configure default search criteria bindings for grids

    main

    In Hyvä Admin grid XML configuration, the <field> element within <defaultSearchCriteriaBindings> allows you to automatically apply filters to a grid based on the current Magento state (e.g., filtering orders by the current customer ID or store ID). This is particularly useful for grids embedded within other entity pages.

    Each <field> declaration maps a grid field name to a value retrieved from a request parameter, a service method, or a session object.

    <source>
      ...
      <defaultSearchCriteriaBindings>
        <field name="entity_id" requestParam="id"/>
        <field name="store_id" method="Magento\Store\Model\StoreManagerInterface::getStore" property="id"/>
        <field name="customer_ids" condition="finset" method="Magento\Customer\Model\Session::getCustomerId"/>
      </defaultSearchCriteriaBindings>
    </source>
  6. Configure entityConfig labels in grids

    main
    In Hyvä Admin grid XML configurations, the entityConfig element serves strictly as a structural parent. It is used to group the label children elements, which define the singular and plural labels for an entity. You cannot apply configuration directly to entityConfig itself; instead, you must define the labels within its child elements.
  7. Understand $source and $rawResult types by Grid Source type

    main

    The types of the $source and $rawResult arguments in processor methods depend on the specific type of Grid Source being used:

    Grid Source Type$source Argument$rawResult Argument
    RepositoryInstance of the class on which getList is calledMagentoFrameworkApiSearchResultsInterface instance
    CollectionCollection instance before search criteria are appliedCollection instance after search criteria are applied (may be loaded)
    ArrayArray provider instanceArray result after filtering, but before pagination or sorting
    QueryMagentoFrameworkDBSelect instance after search criteria appliedQuery result array: ['data' => $rows, 'count' => $count]
  8. Configure unionSelect in grid queries

    main

    In Hyvä Admin grid configurations, a <query> element can include zero or more <unionSelect> children. Each <unionSelect> allows you to combine a secondary select configuration with the primary select configuration of the query.

    Note that <unionSelect> elements do not have their own attributes; instead, they inherit the same configuration structure as a standard <select> element. For more details on the allowed children within a select, refer to the grid > source > query > select documentation.

  9. How to construct Hyvä Grid action event names

    main

    When an action event is triggered, a JavaScript event is dispatched to the window object. The event name follows a specific pattern based on the grid name, the action ID, and the event trigger type:

    hyva-grid-{gridName}-action-{actionId}-{trigger}

    Where {gridName} and {actionId} are processed via an eventify function (typically converting names to kebab-case).

    Example: For a grid named products-query-grid and an action with the ID delete triggered on click, the event name is: hyva-grid-products-query-grid-action-delete-click

  10. Programmatically customize grid columns using the build after event

    main

    While grid columns are typically configured via XML, you can use the hyva_grid_column_definition_build_after event to apply conditional logic to column definitions. This event is dispatched after the column definitions are built, allowing you to modify them based on the grid type or configuration.

    Event Naming Convention

    The event name is dynamic and follows this pattern: hyva_grid_column_definition_build_after_{grid_name_suffix}

    Where {grid_name_suffix} is the grid name in lowercase, with non-alphanumeric characters replaced by underscores. For example, a grid named product-grid dispatches hyva_grid_column_definition_build_after_product_grid.

    // Example event name for a 'product-grid'
    'hyva_grid_column_definition_build_after_product_grid'
  11. Core design principles of Hyva_Admin

    main

    Hyva_Admin is designed to maximize developer efficiency and enjoyment by adhering to several core architectural principles:

    • Minimalism by Default: Defaults are configured to handle approximately 80% of use cases with minimal code.
    • IDE-Friendly: The system is built to leverage modern IDE and editor support (e.g., autocomplete, type hinting).
    • Standard Magento Technologies: It utilizes well-understood, existing technologies such as Layout XML, Blocks, XML merging, and .phtml templates.
    • Balanced Extensibility: Extensibility is provided for common advanced use cases without increasing complexity for simple ones.
    • Long-Term Backward Compatibility: Once an API is marked as stable, it is never changed. New features are added in a backward-compatible manner to ensure stability.