Skip to content

Commit

Permalink
Added ability to add custom dashboard actions
Browse files Browse the repository at this point in the history
  • Loading branch information
mweimerskirch committed Apr 30, 2016
1 parent 88e9451 commit b712dd9
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 28 deletions.
31 changes: 31 additions & 0 deletions Admin/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -3026,4 +3026,35 @@ public function getActionButtons($action, $object = null)

return $list;
}

/**
* Get the list of actions that can be accessed directly from the dashboard.
*
* @return array
*/
public function getDashboardActions()
{
$actions = array();

if ($this->hasRoute('create') && $this->isGranted('CREATE')) {
$actions['create'] = array(
'label' => 'link_add',
'translation_domain' => 'SonataAdminBundle',
'template' => 'SonataAdminBundle:CRUD:dashboard__action_create.html.twig',
'url' => $this->generateUrl('create'),
'icon' => 'plus-circle',
);
}

if ($this->hasRoute('list') && $this->isGranted('LIST')) {
$actions['list'] = array(
'label' => 'link_list',
'translation_domain' => 'SonataAdminBundle',
'url' => $this->generateUrl('list'),
'icon' => 'list',
);
}

return $actions;
}
}
60 changes: 60 additions & 0 deletions Resources/doc/reference/dashboard.rst
Original file line number Diff line number Diff line change
Expand Up @@ -356,3 +356,63 @@ On ``top`` and ``bottom`` positions, you can also specify an optional ``class``
position: top
class: col-md-6
type: sonata.admin.block.admin_list
Configuring what actions are available for each item on the dashboard
---------------------------------------------------------------------

By default. A "list" and a "create" option are available for each item on the
dashboard. If you created a custom action and want to display it along the
other two on the dashboard, you can do so by overriding the
``getDashboardActions()`` method of your admin class:

.. code-block:: php
<?php
// src/AppBundle/Admin/PostAdmin.php
class PostAdmin extends Admin
{
// ...
public function getDashboardActions()
{
$actions = parent::getDashboardActions();
$actions['import'] = array(
'label' => 'Import',
'url' => $this->generateUrl('import'),
'icon' => 'import',
'translation_domain' => 'SonataAdminBundle', // optional
'template' => 'SonataAdminBundle:CRUD:dashboard__action.html.twig', // optional
);
return $actions;
}
}
You can also hide an action from the dashboard by unsetting it:

.. code-block:: php
<?php
// src/AppBundle/Admin/PostAdmin.php
class PostAdmin extends Admin
{
// ...
public function getDashboardActions()
{
$actions = parent::getDashboardActions();
unset($actions['list']);
return $actions;
}
}
If you do this, you need to be aware that the action is only hidden. it will
still be available by directly calling its URL, unless you prevent that using
proper security measures (e.g. ACL or role based).
32 changes: 4 additions & 28 deletions Resources/views/Block/block_admin_list.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -27,40 +27,16 @@ file that was distributed with this source code.
<table class="table table-hover">
<tbody>
{% for admin in group.items %}
{% if admin.hasRoute('create') and admin.isGranted('CREATE') or admin.hasroute('list') and admin.isGranted('LIST') %}
{% if admin.dashboardActions|length > 0 %}
<tr>
<td class="sonata-ba-list-label" width="40%">
{{ admin.label|trans({}, admin.translationdomain) }}
</td>
<td>
<div class="btn-group">
{% if admin.hasroute('create') and admin.isGranted('CREATE') %}
{% if admin.subClasses is empty %}
<a class="btn btn-link btn-flat" href="{{ admin.generateUrl('create')}}">
<i class="fa fa-plus-circle"></i>
{% trans from 'SonataAdminBundle' %}link_add{% endtrans %}
</a>
{% else %}
<a class="btn btn-link btn-flat dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-plus-circle"></i>
{% trans from 'SonataAdminBundle' %}link_add{% endtrans %}
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
{% for subclass in admin.subclasses|keys %}
<li>
<a href="{{ admin.generateUrl('create', {'subclass': subclass}) }}">{{ subclass|trans({}, admin.translationdomain) }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
{% endif %}
{% if admin.hasroute('list') and admin.isGranted('LIST') %}
<a class="btn btn-link btn-flat" href="{{ admin.generateUrl('list')}}">
<i class="fa fa-list"></i>
{% trans from 'SonataAdminBundle' %}link_list{% endtrans -%}
</a>
{% endif %}
{% for action in admin.dashboardActions %}
{% include action.template|default('SonataAdminBundle:CRUD:dashboard__action.html.twig') with {'action': action} %}
{% endfor %}
</div>
</td>
</tr>
Expand Down
4 changes: 4 additions & 0 deletions Resources/views/CRUD/dashboard__action.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<a class="btn btn-link btn-flat" href="{{ action.url }}">
<i class="fa fa-{{ action.icon }}"></i>
{{ action.label|trans({}, action.translation_domain|default('SonataAdminBundle')) }}
</a>
19 changes: 19 additions & 0 deletions Resources/views/CRUD/dashboard__action_create.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% if admin.subClasses is empty %}
<a class="btn btn-link btn-flat" href="{{ action.url }}">
<i class="fa fa-{{ action.icon }}"></i>
{{ action.label|trans({}, action.translation_domain|default('SonataAdminBundle')) }}
</a>
{% else %}
<a class="btn btn-link btn-flat dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-{{ action.icon }}"></i>
{{ action.label|trans({}, action.translation_domain|default('SonataAdminBundle')) }}
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
{% for subclass in admin.subclasses|keys %}
<li>
<a href="{{ admin.generateUrl('create', {'subclass': subclass}) }}">{{ subclass|trans({}, action.translation_domain|default('SonataAdminBundle')) }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
35 changes: 35 additions & 0 deletions Tests/Admin/AdminTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1671,6 +1671,41 @@ public function testGetActionButtonsList()

$this->assertSame($expected, $admin->getActionButtons('list', null));
}

/**
* @covers Sonata\AdminBundle\Admin\Admin::getDashboardActions
* @dataProvider provideGetBaseRouteName
*/
public function testDefaultDashboardActionsArePresent($objFqn, $expected)
{
$pathInfo = new \Sonata\AdminBundle\Route\PathInfoBuilder($this->getMock('Sonata\AdminBundle\Model\AuditManagerInterface'));

$routeGenerator = new DefaultRouteGenerator(
$this->getMock('Symfony\Component\Routing\RouterInterface'),
new RoutesCache($this->cacheTempFolder, true)
);

$admin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
$admin->setRouteBuilder($pathInfo);
$admin->setRouteGenerator($routeGenerator);
$admin->initialize();

$securityHandler = $this->getMock('Sonata\AdminBundle\Security\Handler\SecurityHandlerInterface');
$securityHandler->expects($this->any())
->method('isGranted')
->will($this->returnCallback(function (AdminInterface $adminIn, $attributes, $object = null) use ($admin) {
if ($admin == $adminIn && ($attributes == 'CREATE' || $attributes == 'LIST')) {
return true;
}

return false;
}));

$admin->setSecurityHandler($securityHandler);

$this->assertArrayHasKey('list', $admin->getDashboardActions());
$this->assertArrayHasKey('create', $admin->getDashboardActions());
}
}

class DummySubject
Expand Down

0 comments on commit b712dd9

Please sign in to comment.