Skip to content

Commit

Permalink
introduce record specific enabling/disabling of actions in Grid/CRUD
Browse files Browse the repository at this point in the history
  • Loading branch information
georgehristov committed Jan 5, 2020
1 parent 4fad5d4 commit 938d230
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 85 deletions.
2 changes: 1 addition & 1 deletion src/CRUD.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function setModel(\atk4\data\Model $m, $fields = null)
if ($this->useMenuActions) {
$this->addActionMenuItem($single_record_action);
} else {
$this->addAction($single_record_action);
$this->addActionButton($single_record_action);
}
}

Expand Down
30 changes: 15 additions & 15 deletions src/Grid.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ class Grid extends View
public $ipp = 50;

/**
* Calling addAction will add a new column inside $table, and will be re-used
* for next addAction().
* Calling addActionButton will add a new column inside $table, and will be re-used
* for next addActionButton().
*
* @var TableColumn\Actions
* @var TableColumn\ActionButtons
*/
public $actions = null;
public $actionButtons = null;

/**
* Calling addAction will add a new column inside $table with dropdown menu,
Expand Down Expand Up @@ -106,12 +106,12 @@ class Grid extends View
public $defaultTemplate = 'grid.html';

/**
* TableColumn\Action seed.
* Defines which Table Decorator to use for Actions.
* TableColumn\ActionButtons seed.
* Defines which Table Decorator to use for ActionButtons.
*
* @var string
*/
protected $actionDecorator = 'Actions';
protected $actionButtonsDecorator = 'ActionButtons';

/**
* TableColumn\ActionMenu seed.
Expand Down Expand Up @@ -153,7 +153,7 @@ public function init()
*/
public function setActionDecorator($seed)
{
$this->actionDecorator = $seed;
$this->actionButtonsDecorator = $seed;
}

/**
Expand Down Expand Up @@ -395,13 +395,13 @@ public function jsReload($args = [], $afterSuccess = null, $apiConfig = [])
*
* @return object
*/
public function addAction($button, $action = null, $confirm = false, $isDisabeld = false)
public function addActionButton($button, $action = null, $confirm = false, $isDisabeld = false)
{
if (!$this->actions) {
$this->actions = $this->table->addColumn(null, $this->actionDecorator);
if (!$this->actionButtons) {
$this->actionButtons = $this->table->addColumn(null, $this->actionButtonsDecorator);
}

return $this->actions->addAction($button, $action, $confirm, $isDisabeld);
return $this->actionButtons->addButton($button, $action, $confirm, $isDisabeld);
}

/**
Expand Down Expand Up @@ -545,11 +545,11 @@ public function addPopup($columnName, $popup = null, $icon = 'caret square down'
*/
public function addModalAction($button, $title, $callback, $args = [])
{
if (!$this->actions) {
$this->actions = $this->table->addColumn(null, 'Actions');
if (!$this->actionButtons) {
$this->actionButtons = $this->table->addColumn(null, 'Actions');
}

return $this->actions->addModal($button, $title, $callback, $this, $args);
return $this->actionButtons->addModal($button, $title, $callback, $this, $args);
}

/**
Expand Down
101 changes: 57 additions & 44 deletions src/TableColumn/Actions.php → src/TableColumn/ActionButtons.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@
namespace atk4\ui\TableColumn;

use atk4\core\FactoryTrait;
use atk4\ui\Button;

/**
* Formatting action buttons column.
*/
class Actions extends Generic
class ActionButtons extends Generic
{
use FactoryTrait;

public $actions = [];
public $buttons = [];

/**
* Callbacks as defined in $action->enabled for evaluating row-specific if an action is enabled
*
* @var array
*/
protected $callbacks = [];

public function init()
{
Expand All @@ -35,37 +41,33 @@ public function init()
*
* @return object
*/
public function addAction($button, $callback = null, $confirm = false, $isDisabled = false)
public function addButton($button, $action = null, $confirm = false, $isDisabled = false)
{
// If action is not specified, perhaps it is defined in the model
if (!$callback && is_string($button)) {
$model_action = $this->table->model->getAction($button);
if ($model_action) {
$isDisabled = !$model_action->enabled;
$callback = $model_action;
$button = $callback->caption;
if ($model_action->ui['confirm'] ?? null) {
$confirm = $model_action->ui['confirm'];
}
if (! $action) {
if (is_string($button)) {
$action = $this->table->model->getAction($button);
}
} elseif (!$callback && $button instanceof \atk4\data\UserAction\Generic) {
$isDisabled = !$button->enabled;
if ($button->ui['confirm'] ?? null) {
$confirm = $button->ui['confirm'];
elseif ($button instanceof \atk4\data\UserAction\Generic){
$action = $button;
}
$callback = $button;
$button = $button->caption;
}

$name = $this->name.'_action_'.(count($this->actions) + 1);

if ($callback instanceof \atk4\data\UserAction\Generic) {
if (isset($callback->ui['button'])) {
$button = $callback->ui['button'];

if ($action) {
$button = $action->caption;
}

if (isset($callback->ui['confirm'])) {
$confirm = $callback->ui['confirm'];
}

$name = $this->name.'_button_'.(count($this->buttons) + 1);

if ($action instanceof \atk4\data\UserAction\Generic) {
$button = $action->ui['button'] ?? $button;

$confirm = $action->ui['confirm'] ?? $confirm;

$isDisabled = ! $action->enabled;

if (is_callable($action->enabled)) {
$this->callbacks[$name] = $action->enabled;
}
}

Expand All @@ -78,14 +80,13 @@ public function addAction($button, $callback = null, $confirm = false, $isDisabl
}

$button->app = $this->table->app;

$this->actions[$name] = $button;
$button->addClass('b_'.$name);
$button->addClass('compact');

$this->buttons[$name] = $button->addClass('{$_'.$name.'_disabled} compact b_'.$name);

if ($isDisabled) {
$button->addClass('disabled');
}
$this->table->on('click', '.b_'.$name, $callback, [$this->table->jsRow()->data('id'), 'confirm' => $confirm]);
$this->table->on('click', '.b_'.$name, $action, [$this->table->jsRow()->data('id'), 'confirm' => $confirm]);

return $button;
}
Expand All @@ -96,18 +97,17 @@ public function addAction($button, $callback = null, $confirm = false, $isDisabl
*/
public function addModal($button, $title, $callback, $owner = null, $args = [])
{
if (!$owner) {
$modal = $this->owner->owner->add(['Modal', 'title'=>$title]);
} else {
$modal = $owner->add(['Modal', 'title'=>$title]);
}
$owner = $owner?: $this->owner->owner;

$modal = $owner->add(['Modal', compact('title')]);

$modal->observeChanges(); // adds scrollbar if needed

$modal->set(function ($t) use ($callback) {
call_user_func($callback, $t, $this->app->stickyGet($this->name));
});

return $this->addAction($button, $modal->show(array_merge([$this->name=>$this->owner->jsRow()->data('id')], $args)));
return $this->addButton($button, $modal->show(array_merge([$this->name=>$this->owner->jsRow()->data('id')], $args)));
}

/**
Expand All @@ -124,18 +124,31 @@ public function getTag($position, $value, $attr = [])

public function getDataCellTemplate(\atk4\data\Field $f = null)
{
if (!$this->actions) {
if (!$this->buttons) {
return '';
}

// render our actions
// render our buttons
$output = '';
foreach ($this->actions as $action) {
$output .= $action->getHTML();
foreach ($this->buttons as $button) {
$output .= $button->getHTML();
}

return '<div class="ui buttons">'.$output.'</div>';
}

public function getHTMLTags($row, $field)
{
$tags = [];
foreach ($this->callbacks as $name => $callback) {
// if action is enabled then do not set disabled class
if ($callback($row)) continue;

$tags['_'.$name.'_disabled'] = 'disabled';
}

return $tags;
}

// rest will be implemented for crud
}
76 changes: 51 additions & 25 deletions src/TableColumn/ActionMenu.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ class ActionMenu extends Generic
*
* @var array
*/
protected $actions = [];
protected $items = [];

/**
* Callbacks as defined in $action->enabled for evaluating row-specific if an action is enabled
*
* @var array
*/
protected $callbacks = [];

/**
* Dropdown label.
Expand Down Expand Up @@ -78,44 +85,50 @@ public function getTag($position, $value, $attr = [])
*
* @return object|string
*/
public function addActionMenuItem($item, $callback = null, $confirm = null, $isDisabled = false)
public function addActionMenuItem($item, $action = null, $confirm = null, $isDisabled = false)
{
// If action is not specified, perhaps it is defined in the model
if (!$callback && is_string($item)) {
$model_action = $this->table->model->getAction($item);
if ($model_action) {
$isDisabled = !$model_action->enabled;
$callback = $model_action;
$item = $callback->caption;
if ($model_action->ui['confirm'] ?? null) {
$confirm = $model_action->ui['confirm'];
}
if (! $action) {
if (is_string($item)) {
$action = $this->table->model->getAction($item);
}
} elseif (!$callback && $item instanceof \atk4\data\UserAction\Generic) {
$isDisabled = !$item->enabled;
if ($item->ui['confirm'] ?? null) {
$confirm = $item->ui['confirm'];
elseif ($item instanceof \atk4\data\UserAction\Generic){
$action = $item;
}

if ($action) {
$item = $action->caption;
}
$callback = $item;
$item = $item->caption;
}

$name = $this->name.'_action_'.(count($this->actions) + 1);


$name = $this->name.'_action_'.(count($this->items) + 1);

if ($action instanceof \atk4\data\UserAction\Generic) {
$confirm = $action->ui['confirm'] ?? $confirm;

$isDisabled = ! $action->enabled;

if (is_callable($action->enabled)) {
$this->callbacks[$name] = $action->enabled;
}
}

if (!is_object($item)) {
$item = $this->factory('View', ['id' => false, 'ui' => 'item', 'content' => $item], 'atk4\ui');
}

$this->actions[] = $item;
$item->addClass('i_'.$name);
$this->items[] = $item;

$item->addClass('{$_'.$name.'_disabled} i_'.$name);

if ($isDisabled) {
$item->addClass('disabled');
}

// set executor context.
$context = (new jQuery())->closest('.ui.button');

$this->table->on('click', '.i_'.$name, $callback, [$this->table->jsRow()->data('id'), 'confirm' => $confirm, 'apiConfig' => ['stateContext' => $context]]);
$this->table->on('click', '.i_'.$name, $action, [$this->table->jsRow()->data('id'), 'confirm' => $confirm, 'apiConfig' => ['stateContext' => $context]]);

return $item;
}
Expand Down Expand Up @@ -145,13 +158,13 @@ public function getHeaderCellHTML(\atk4\data\Field $f = null, $value = null)
*/
public function getDataCellTemplate(\atk4\data\Field $f = null)
{
if (!$this->actions) {
if (!$this->items) {
return '';
}

// render our menus
$output = '';
foreach ($this->actions as $item) {
foreach ($this->items as $item) {
$output .= $item->getHTML();
}

Expand All @@ -164,4 +177,17 @@ public function getDataCellTemplate(\atk4\data\Field $f = null)

return $s;
}

public function getHTMLTags($row, $field)
{
$tags = [];
foreach ($this->callbacks as $name => $callback) {
// if action is enabled then do not set disabled class
if ($callback($row)) continue;

$tags['_'.$name.'_disabled'] = 'disabled';
}

return $tags;
}
}

0 comments on commit 938d230

Please sign in to comment.