Skip to content

Commit

Permalink
feature EasyCorp#1345 Allow actions to define their "target" HTML att…
Browse files Browse the repository at this point in the history
…ribute (javiereguiluz)

This PR was squashed before being merged into the master branch (closes EasyCorp#1345).

Discussion
----------

Allow actions to define their "target" HTML attribute

This fixes EasyCorp#1121.

Commits
-------

fcf17de Allow actions to define their "target" HTML attribute
  • Loading branch information
javiereguiluz committed Oct 23, 2016
2 parents 33c0759 + fcf17de commit 2000913
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 4 deletions.
2 changes: 2 additions & 0 deletions Configuration/ActionConfigPass.php
Expand Up @@ -31,6 +31,8 @@ class ActionConfigPass implements ConfigPassInterface
'css_class' => null,
// the name of the FontAwesome icon to display next to the 'label' (doesn't include the 'fa-' prefix)
'icon' => null,
// the value of the HTML 'target' attribute add to the links of the actions (e.g. '_blank')
'target' => '_self',
);

public function process(array $backendConfig)
Expand Down
3 changes: 3 additions & 0 deletions Resources/doc/book/5-actions-configuration.md
Expand Up @@ -220,6 +220,9 @@ Then, define any of the following options to customize the action:
inside the button used to render the action. You don't have to include the
`fa-` prefix of the icon name (e.g. to display the icon of a user, don't
use `fa fa-user` or `fa-user`; just use `user`).
* `target`, is the value of the `target` HTML attribute applied to the button
or link associated with the action (e.g. `_blank` to open the action in a
new browser tab/window).

-------------------------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion Resources/views/default/includes/_actions.html.twig
Expand Up @@ -7,7 +7,7 @@
{% set action_href = path(action.name, request_parameters|merge({ action: action.name, id: item_id })) %}
{% endif %}

<a class="{{ action.css_class|default('') }}" href="{{ action_href }}">
<a class="{{ action.css_class|default('') }}" href="{{ action_href }}" target="{{ action.target }}">
{%- if action.icon %}<i class="fa fa-{{ action.icon }}"></i> {% endif -%}
{%- if action.label is defined and not action.label is empty -%}
{{ action.label|trans(trans_parameters|merge({ '%entity_id%': item_id }), 'messages') }}
Expand Down
2 changes: 1 addition & 1 deletion Resources/views/default/includes/_delete_form.html.twig
Expand Up @@ -20,7 +20,7 @@

{% if easyadmin_action_is_enabled(view, 'delete', _entity_config.name) %}
{% set _delete_action = easyadmin_get_action(view, 'delete', _entity_config.name) %}
<button type="button" data-dismiss="modal" class="btn btn-danger" id="modal-delete-button">
<button type="button" data-dismiss="modal" class="btn btn-danger" id="modal-delete-button" formtarget="{{ _delete_action.target }}">
{% if _delete_action.icon %}<i class="fa fa-{{ _delete_action.icon }}"></i>{% endif %}
{{ 'delete_modal.action'|trans(_trans_parameters, 'EasyAdminBundle') }}
</button>
Expand Down
4 changes: 2 additions & 2 deletions Resources/views/default/list.html.twig
Expand Up @@ -62,7 +62,7 @@
<div class="input-group">
<input class="form-control" type="search" name="query" value="{{ app.request.get('query')|default('') }}">
<span class="input-group-btn">
<button class="btn" type="submit">
<button class="btn" type="submit" formtarget="{{ _action.target }}">
<i class="fa fa-search"></i>
<span class="hidden-xs hidden-sm">{{ _action.label|default('action.search')|trans(_trans_parameters) }}</span>
</button>
Expand All @@ -78,7 +78,7 @@
{% set _action = easyadmin_get_action_for_list_view('new', _entity_config.name) %}
{% block new_action %}
<div class="button-action">
<a class="{{ _action.css_class|default('') }}" href="{{ path('easyadmin', _request_parameters|merge({ action: _action.name })) }}">
<a class="{{ _action.css_class|default('') }}" href="{{ path('easyadmin', _request_parameters|merge({ action: _action.name })) }}" target="{{ _action.target }}">
{% if _action.icon %}<i class="fa fa-{{ _action.icon }}"></i>{% endif %}
{{ _action.label is defined and not _action.label is empty ? _action.label|trans(_trans_parameters) }}
</a>
Expand Down
24 changes: 24 additions & 0 deletions Tests/Configuration/fixtures/configurations/input/admin_140.yml
@@ -0,0 +1,24 @@
# TEST
# actions can define their 'target' HTML attribute

# CONFIGURATION
easy_admin:
entities:
Category:
class: AppTestBundle\Entity\UnitTests\Category
list:
actions:
- { name: 'edit', target: '_blank' }
- { name: 'custom_action', target: '_parent' }
- { name: 'another_custom_action' }
edit:
actions:
- { name: 'list', target: '_parent' }
show:
actions:
- { name: 'edit', target: '_self' }
- { name: 'list' }
- { name: 'custom_action', target: 'custom_target' }
new:
actions:
- { name: 'list', target: '_top' }
25 changes: 25 additions & 0 deletions Tests/Configuration/fixtures/configurations/output/config_140.yml
@@ -0,0 +1,25 @@
easy_admin:
entities:
Category:
class: AppTestBundle\Entity\UnitTests\Category
list:
actions:
edit: { target: '_blank' }
custom_action: { target: '_parent' }
another_custom_action: { target: '_self' }
delete: { target: '_self' }
new: { target: '_self' }
search: { target: '_self' }
edit:
actions:
list: { target: '_parent' }
delete: { target: '_self' }
new:
actions:
list: { target: '_top' }
show:
actions:
edit: { target: '_self' }
list: { target: '_self' }
custom_action: { target: 'custom_target' }
delete: { target: '_self' }
67 changes: 67 additions & 0 deletions Tests/Controller/ActionTargetTest.php
@@ -0,0 +1,67 @@
<?php

/*
* This file is part of the EasyAdminBundle.
*
* (c) Javier Eguiluz <javier.eguiluz@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace JavierEguiluz\Bundle\EasyAdminBundle\Tests\Controller;

use JavierEguiluz\Bundle\EasyAdminBundle\Tests\Fixtures\AbstractTestCase;

class ActionTargetTest extends AbstractTestCase
{
public function setUp()
{
parent::setUp();

$this->initClient(array('environment' => 'action_target'));
}

public function testListViewActions()
{
$crawler = $this->requestListView();

$this->assertEquals('_top', $crawler->filter('.global-actions form button[type="submit"]')->attr('formtarget'));
$this->assertEquals('custom_target', $crawler->filter('.button-action a:contains("Add Category")')->attr('target'));

$this->assertEquals('_blank', $crawler->filter('table a:contains("Edit")')->attr('target'));
$this->assertEquals('_parent', $crawler->filter('table a:contains("Custom action")')->attr('target'));
$this->assertEquals('_self', $crawler->filter('table a:contains("Another custom action")')->attr('target'));
$this->assertEquals('_self', $crawler->filter('table a:contains("Delete")')->attr('target'));
$this->assertEquals('_self', $crawler->filter('#modal-delete-button')->attr('formtarget'));
}

public function testEditViewActions()
{
$crawler = $this->requestEditView();

$this->assertEquals('_parent', $crawler->filter('.form-actions a:contains("Back to listing")')->attr('target'));
$this->assertEquals('_blank', $crawler->filter('.form-actions a:contains("Custom action")')->attr('target'));
$this->assertEquals('_blank', $crawler->filter('.form-actions a:contains("Delete")')->attr('target'));
$this->assertEquals('_blank', $crawler->filter('#modal-delete-button')->attr('formtarget'));
}

public function testShowViewActions()
{
$crawler = $this->requestShowView();

$this->assertEquals('_self', $crawler->filter('.form-actions a:contains("Edit")')->attr('target'));
$this->assertEquals('_self', $crawler->filter('.form-actions a:contains("Back to listing")')->attr('target'));
$this->assertEquals('custom_target', $crawler->filter('.form-actions a:contains("Custom action")')->attr('target'));
$this->assertEquals('_self', $crawler->filter('.form-actions a:contains("Delete")')->attr('target'));
$this->assertEquals('_self', $crawler->filter('#modal-delete-button')->attr('formtarget'));
}

public function testNewViewActions()
{
$crawler = $this->requestNewView();

$this->assertEquals('_top', $crawler->filter('.form-actions a:contains("Back to listing")')->attr('target'));
$this->assertEquals('_parent', $crawler->filter('.form-actions a:contains("Custom action")')->attr('target'));
}
}
8 changes: 8 additions & 0 deletions Tests/Controller/DefaultBackendTest.php
Expand Up @@ -130,6 +130,7 @@ public function testListViewSearchAction()
);

$this->assertEquals('Search', trim($crawler->filter('.action-search button[type=submit]')->text()));
$this->assertEquals('_self', $crawler->filter('.action-search button')->attr('formtarget'));

$i = 0;
foreach ($hiddenParameters as $name => $value) {
Expand All @@ -145,6 +146,7 @@ public function testListViewNewAction()
$crawler = $this->requestListView();

$this->assertEquals('Add Category', trim($crawler->filter('.global-actions a.btn')->text()));
$this->assertEquals('_self', $crawler->filter('.global-actions a.btn')->attr('target'));
$this->assertCount(0, $crawler->filter('.global-actions a.btn i'), 'The default "new" button shows no icon.');
$this->assertStringStartsWith('/admin/?action=new&entity=Category&sortField=id&sortDirection=DESC&page=1', $crawler->filter('.global-actions a.btn')->attr('href'));
}
Expand All @@ -154,6 +156,7 @@ public function testListViewItemActions()
$crawler = $this->requestListView();

$this->assertEquals('Edit', trim($crawler->filter('#main .table td.actions a')->eq(0)->text()));
$this->assertEquals('_self', $crawler->filter('#main .table td.actions a')->eq(0)->attr('target'));
$this->assertEquals('Delete', trim($crawler->filter('#main .table td.actions a')->eq(1)->text()));
}

Expand Down Expand Up @@ -259,12 +262,14 @@ public function testShowViewActions()

// edit action
$this->assertContains('fa-edit', trim($crawler->filter('.form-actions a:contains("Edit") i')->attr('class')));
$this->assertEquals('_self', $crawler->filter('.form-actions a:contains("Edit")')->attr('target'));

// delete action
$this->assertContains('fa-trash', trim($crawler->filter('.form-actions a:contains("Delete") i')->attr('class')));

// list action
$this->assertEquals('btn btn-secondary action-list', trim($crawler->filter('.form-actions a:contains("Back to listing")')->attr('class')));
$this->assertEquals('_self', $crawler->filter('.form-actions a:contains("Back to listing")')->attr('target'));
}

public function testShowViewReferer()
Expand Down Expand Up @@ -342,6 +347,7 @@ public function testEditViewActions()

// list action
$this->assertEquals('btn btn-secondary action-list', trim($crawler->filter('#form-actions-row a:contains("Back to listing")')->attr('class')));
$this->assertEquals('_self', $crawler->filter('#form-actions-row a:contains("Back to listing")')->attr('target'));
}

public function testEditViewReferer()
Expand Down Expand Up @@ -457,6 +463,7 @@ public function testNewViewActions()

// list action
$this->assertEquals('btn btn-secondary action-list', trim($crawler->filter('#form-actions-row a:contains("Back to listing")')->attr('class')));
$this->assertEquals('_self', $crawler->filter('#form-actions-row a:contains("Back to listing")')->attr('target'));
}

public function testNewViewReferer()
Expand Down Expand Up @@ -601,6 +608,7 @@ public function testSearchViewItemActions()
$crawler = $this->requestSearchView();

$this->assertEquals('Edit', trim($crawler->filter('#main .table td.actions a')->eq(0)->text()));
$this->assertEquals('_self', $crawler->filter('#main .table td.actions a')->eq(0)->attr('target'));
$this->assertEquals('Delete', trim($crawler->filter('#main .table td.actions a')->eq(1)->text()));
}

Expand Down
28 changes: 28 additions & 0 deletions Tests/Fixtures/App/config/config_action_target.yml
@@ -0,0 +1,28 @@
imports:
- { resource: config.yml }

easy_admin:
entities:
Category:
class: AppTestBundle\Entity\FunctionalTests\Category
list:
actions:
- { name: 'edit', target: '_blank' }
- { name: 'search', target: '_top' }
- { name: 'new', target: 'custom_target' }
- { name: 'custom_action', target: '_parent' }
- { name: 'another_custom_action' }
edit:
actions:
- { name: 'list', target: '_parent' }
- { name: 'delete', target: '_blank' }
- { name: 'custom_action', target: '_blank' }
show:
actions:
- { name: 'edit', target: '_self' }
- { name: 'list' }
- { name: 'custom_action', target: 'custom_target' }
new:
actions:
- { name: 'list', target: '_top' }
- { name: 'custom_action', target: '_parent' }

0 comments on commit 2000913

Please sign in to comment.