EasyCorp / EasyAdminBundle

EasyAdmin is a fast, beautiful and modern admin generator for Symfony applications.
MIT License
3.99k stars 1.01k forks source link

Collection::allowDelete should still allow deletion of unsaved items #6257

Open Geolim4 opened 1 month ago

Geolim4 commented 1 month ago

Describe the bug When you're editing an entity containing a collection of items that you want prohibit deletion, IMHO, the deletion should still be allowed while the item are added but not yet saved (only client-side).

dwd-akira commented 1 month ago

For me it's logical. The entity is not yet saved, the user can always cancel the added item (entry error for example)

Geolim4 commented 3 weeks ago

@dwd-akira

Simple solution: Override vendor/easycorp/easyadmin-bundle/src/Resources/views/crud/form_theme.html.twig:

Look for {% set allows_deleting_items = form_parent(form).vars.allow_delete|default(false) %}

and replace it by:

{% set allows_deleting_items = form_parent(form).vars.allow_delete|default(false) or value is null %}

See:

{% extends '@!EasyAdmin/crud/form_theme.html.twig' %}

{% block collection_entry_row %}
    {% set is_array_field = 'EasyCorp\\Bundle\\EasyAdminBundle\\Field\\ArrayField' == form_parent(form).vars.ea_vars.field.fieldFqcn ?? false %}
    {% set is_complex = form_parent(form).vars.ea_vars.field.customOptions.get('entryIsComplex') ?? false %}
    {% set allows_deleting_items = form_parent(form).vars.allow_delete|default(false) or value is null %}
    {% set render_expanded = form_parent(form).vars.ea_vars.field.customOptions.get('renderExpanded') ?? false %}
    {% set delete_item_button %}
        <button type="button" class="btn btn-link btn-link-danger field-collection-delete-button"
                title="{{ 'action.remove_item'|trans({}, 'EasyAdminBundle') }}">
            <i class="far fa-trash-alt"></i>
        </button>
    {% endset %}

    <div class="field-collection-item {{ is_complex ? 'field-collection-item-complex' }} {{ not form.vars.valid ? 'is-invalid' }}">
        {% if is_array_field|default(false) %}
            {{ form_label(form) }}
            {{ form_widget(form) }}
            {% if allows_deleting_items and not disabled %}
                {{ delete_item_button }}
            {% endif %}
        {% else %}
            <div class="accordion-item">
                <h2 class="accordion-header">
                    <button class="accordion-button {{ render_expanded ? '' : 'collapsed' }}" type="button" data-bs-toggle="collapse" data-bs-target="#{{ id }}-contents">
                        <i class="fas fw fa-chevron-right form-collection-item-collapse-marker"></i>
                        {{ value|ea_as_string_translatable }}
                    </button>

                    {% if allows_deleting_items and not disabled %}
                        {{ delete_item_button }}
                    {% endif %}
                </h2>
                <div id="{{ id }}-contents" class="accordion-collapse collapse {{ render_expanded ? 'show' }}">
                    <div class="accordion-body">
                        <div class="row">
                            {{ form_widget(form) }}
                        </div>
                    </div>
                </div>
            </div>
        {% endif %}
    </div>
{% endblock collection_entry_row %}

This trick would allow to delete only unsaved item 😇

dwd-akira commented 3 weeks ago

Maybe @javiereguiluz can add this change without form theme override ?

Geolim4 commented 3 weeks ago

Unfortunately @javiereguiluz looks very busy atm, I'm afraid he's not concerned for minor issues right now and focusing only on blocking issue of EA :(