Skip to content

Commit

Permalink
feat: Add DashboardAction
Browse files Browse the repository at this point in the history
Closes #185
  • Loading branch information
josegonzalez committed May 12, 2018
1 parent 213cab4 commit 4c68ff7
Show file tree
Hide file tree
Showing 19 changed files with 726 additions and 12 deletions.
16 changes: 16 additions & 0 deletions docs/_partials/pages/dashboard/elements.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Available Elements
------------------

All the *CrudView* templates are built from several elements that can be
overridden by creating them in your own ``src/Template/Element`` folder. The
following sections will list all the elements that can be overridden for each
type of action.

In general, if you want to override a template, it is a good idea to copy the
original implementation from
``vendor/friendsofcake/crud-view/src/Template/Element``

action-header
Create ``src/Template/Element/action-header.ctp`` to have full control over
what is displayed at the top of the page. This is shared across all page
types.
7 changes: 7 additions & 0 deletions docs/_partials/pages/dashboard/viewblocks.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Available Viewblocks
--------------------

The following custom view blocks are available for use within forms:

- ``dashboard.before``: Rendered before the entire dashboard is rendered.
- ``dashboard.after``: Rendered after the entire dashboard is rendered.
8 changes: 8 additions & 0 deletions docs/contents.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ Contents
Sidebar Navigation <general-configuration/sidebar-navigation>
Utility Navigation <general-configuration/utility-navigation>

.. _dashboard-pages-docs:

.. toctree::
:maxdepth: 3
:caption: Dashboard Pages

Customizing the Dashboard <dashboard-pages/customizing-the-dashboard-page>

.. _index-pages-docs:

.. toctree::
Expand Down
136 changes: 136 additions & 0 deletions docs/dashboard-pages/customizing-the-dashboard-page.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
Customizing the Dashboard Page
==============================

The "dashboard" can be used to display a default landing page for CrudView-powered
admin sites. It is made of several ``\Cake\View\Cell``
instances, and can be extended to display items other than what is shipped with CrudView.

To use the "Dashboard", the custom ``DashboardAction`` needs to be mapped:

.. code-block:: php
public function initialize()
{
parent::initialize();
$this->Crud->mapAction('dashboard', 'CrudView.Dashboard');
}
Browsing to this mapped action will result in a blank page. To customize it, a
``\CrudView\Dashboard\Dashboard`` can be configured on the ``scaffold.dashboard`` key:

.. code-block:: php
public function dashboard()
{
$dashboard = new \CrudView\Dashboard\Dashboard();
$this->Crud->action()->setConfig('scaffold.dashboard', $dashboard);
return $this->Crud->execute();
}
The ``\CrudView\Dashboard\Dashboard`` instance takes two arguments:

- ``title``: The title for the dashboard view. Defaults to ``Dashboard``.
- ``columns`` A number of columns to display on the view. Defaults to ``1``.

.. code-block:: php
public function dashboard()
{
// setting both the title and the number of columns
$dashboard = new \CrudView\Dashboard\Dashboard(__('Site Administration'), 12);
$this->Crud->action()->setConfig('scaffold.dashboard', $dashboard);
return $this->Crud->execute();
}
Adding Cells to the Dashboard
-------------------------------

Any number of cells may be added to the Dashboard. All cells *must* extend the
``\Cake\View\Cell`` class.

Cells can be added via the ``Dashboard::addToColumn()`` method. It takes a cell
instance and a column number as arguments.

.. code-block:: php
// assuming the `CellTrait` is in use, we can generate a cell via `$this->cell()`
$someCell = $this->cell('SomeCell');
$dashboard = new \CrudView\Dashboard\Dashboard(__('Site Administration'), 2);
// add to the first column
$dashboard->addToColumn($someCell);
// configure the column to add to
$dashboard->addToColumn($someCell, 2);
CrudView ships with the ``DashboardTable`` cell by default.

CrudView.DashboardTable
~~~~~~~~~~~~~~~~~~~~~~~

This can be used to display links to items in your application or offiste.

.. code-block:: php
public function dashboard()
{
// setting both the title and the number of columns
$dashboard = new \CrudView\Dashboard\Dashboard(__('Site Administration'), 1);
$dashboard->addToColumn($this->cell('CrudView.DashboardTable', [
'title' => 'Important Links'
]));
$this->Crud->action()->setConfig('scaffold.dashboard', $dashboard);
return $this->Crud->execute();
}
In the above example, only a title to the ``DashboardTable``, which will
show a single subheading for your Dashboard.

In addition to showing a title, it is also possible to show a list of links. This can
be done by adding a ``links`` key with an array of ``LinkItem`` objects as the value.
Links containing urls for external websites will open in a new window by default.

.. code-block:: php
public function dashboard()
{
// setting both the title and the number of columns
$dashboard = new \CrudView\Dashboard\Dashboard(__('Site Administration'), 1);
$dashboard->addToColumn($this->cell('CrudView.DashboardTable', [
'title' => 'Important Links',
'links' => [
new LinkItem('Example', 'https://example.com', ['target' => '_blank']),
],
]));
$this->Crud->action()->setConfig('scaffold.dashboard', $dashboard);
return $this->Crud->execute();
}
There is also a special kind of ``LinkItem`` called an ``ActionLinkItem``. This
has a fourth argument is an array of ``LinkItem`` objects. It can be used to show
embedded action links on the same row.

.. code-block:: php
public function dashboard()
{
$dashboard = new \CrudView\Dashboard\Dashboard(__('Site Administration'), 1);
$dashboard->addToColumn($this->cell('CrudView.DashboardTable', [
'title' => 'Important Links',
'links' => [
new ActionLinkItem('Posts', ['controller' => 'Posts'], [], [
new LinkItem('Add', ['controller' => 'Posts', 'action' => 'add']),
]),
],
]));
$this->Crud->action()->setConfig('scaffold.dashboard', $dashboard);
return $this->Crud->execute();
}
.. include:: /_partials/pages/dashboard/viewblocks.rst
.. include:: /_partials/pages/dashboard/elements.rst
43 changes: 43 additions & 0 deletions src/Action/DashboardAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
namespace CrudView\Action;

use CrudView\Dashboard\Dashboard;
use Crud\Action\BaseAction;
use Crud\Traits\ViewTrait;

class DashboardAction extends BaseAction
{
use ViewTrait;

protected $_defaultConfig = [
'enabled' => true,
'view' => null,
];

/**
* HTTP GET handler
*
* @return void|\Cake\Network\Response
*/
protected function _get()
{
$pageTitle = $this->getConfig('scaffold.page_title', __d('CrudView', 'Dashboard'));
$this->setConfig('scaffold.page_title', $pageTitle);
$this->setConfig('scaffold.autoFields', false);
$this->setConfig('scaffold.fields', ['dashboard']);
$this->setConfig('scaffold.actions', []);

$dashboard = $this->getConfig('scaffold.dashboard', new Dashboard($pageTitle));
$subject = $this->_subject([
'success' => true,
'dashboard' => $dashboard,
]);

$this->_trigger('beforeRender', $subject);

$controller = $this->_controller();
$controller->set('dashboard', $subject->dashboard);
$controller->set('viewVar', 'dashboard');
$controller->set('title', $subject->dashboard->get('title'));
}
}
86 changes: 86 additions & 0 deletions src/Dashboard/Dashboard.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php
namespace CrudView\Dashboard;

use Cake\Datasource\EntityTrait;
use Cake\View\Cell;
use InvalidArgumentException;

class Dashboard
{
use EntityTrait;

/**
* Constructor
*
* @param string $title The name of the group
* @param int $columns Number of columns
*/
public function __construct($title = null, $columns = 1)
{
if ($title === null) {
$title = __d('CrudView', 'Dashboard');
}

$this->set('title', $title);
$this->set('children', []);
$this->set('columns', $columns);
}

/**
* Returns the children from a given column
*
* @param int $column a column number
* @return array
*/
public function getColumnChildren($column)
{
$children = $this->get('children');
if (isset($children[$column])) {
return $children[$column];
}

return [];
}

/**
* Adds a Cell to a given column
*
* @param Cell $module instance of Cell
* @param int $column a column number
* @return $this
*/
public function addToColumn(Cell $module, $column = 1)
{
$children = $this->get('children');
$children[$column][] = $module;
$this->set('children', $children);

return $this;
}

/**
* columns property setter
*
* @param int $value A column count
* @return int
* @throws \InvalidArgumentException the column count is invalid
*/
protected function _setColumns($value)
{
$columnMap = [
1 => 12,
2 => 6,
3 => 4,
4 => 3,
6 => 2,
12 => 1,
];
if (!in_array($value, [1, 2, 3, 4, 6, 12])) {
throw new InvalidArgumentException('Valid columns value must be one of [1, 2, 3, 4, 6, 12]');
}

$this->set('columnClass', sprintf('col-md-%d', $columnMap[$value]));

return $value;
}
}
48 changes: 48 additions & 0 deletions src/Dashboard/Module/ActionLinkItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
namespace CrudView\Dashboard\Module;

use Cake\Collection\Collection;
use Cake\Utility\Hash;
use InvalidArgumentException;

class ActionLinkItem extends LinkItem
{
/**
* Array of LinkItems.
*
* @var array
**/
protected $actions = [];

/**
* Constructor
*
* @param string|array $title The content to be wrapped by `<a>` tags.
* Can be an array if $url is null. If $url is null, $title will be used as both the URL and title.
* @param string|array|null $url Cake-relative URL or array of URL parameters, or
* external URL (starts with http://)
* @param array $options Array of options and HTML attributes.
* @param array $actions Array of ActionItems
*/
public function __construct($title, $url, $options = [], array $actions = [])
{
parent::__construct($title, $url, $options);
$this->set('actions', $actions);
}

/**
* options property setter
*
* @param array $actions Array of options and HTML attributes.
* @return array
*/
protected function _setActions($actions)
{
return (new Collection($actions))->map(function ($value) {
$options = (array)$value->get('options') + ['class' => ['btn btn-default']];
$value->set('options', $options);

return $value;
})->toArray();
}
}
Loading

0 comments on commit 4c68ff7

Please sign in to comment.