Browse Source

重写AbstractTool

jqh 5 years ago
parent
commit
a481936e30

+ 80 - 2
src/Actions/Action.php

@@ -2,6 +2,7 @@
 
 namespace Dcat\Admin\Actions;
 
+use Dcat\Admin\Support\Helper;
 use Dcat\Admin\Traits\HasHtmlAttributes;
 use Illuminate\Contracts\Support\Renderable;
 
@@ -44,6 +45,53 @@ abstract class Action implements Renderable
      */
     protected $event = 'click';
 
+    /**
+     * @var bool
+     */
+    protected $disabled = false;
+
+    /**
+     * @var bool
+     */
+    protected $disabledHandler = false;
+
+    /**
+     * Action constructor.
+     *
+     * @param mixed  $key
+     * @param string $title
+     */
+    public function __construct($key = null, $title = null)
+    {
+        $this->setKey($key);
+
+        $this->title = $title;
+    }
+
+    /**
+     * Toggle this button.
+     *
+     * @param bool $disable
+     *
+     * @return $this
+     */
+    public function disable(bool $disable = true)
+    {
+        $this->disabled = $disable;
+
+        return $this;
+    }
+
+    /**
+     * If the action is allowed.
+     *
+     * @return bool
+     */
+    public function allowed()
+    {
+        return ! $this->disabled;
+    }
+
     /**
      * Get primary key value of action.
      *
@@ -127,9 +175,15 @@ abstract class Action implements Renderable
     {
     }
 
+    /**
+     * @return void
+     */
     protected function prepareHandle()
     {
-        if (! method_exists($this, 'handle')) {
+        if (
+            $this->disabledHandler
+            || ! method_exists($this, 'handle')
+        ) {
             return;
         }
 
@@ -137,13 +191,37 @@ abstract class Action implements Renderable
     }
 
     /**
-     * @return mixed
+     * @return string
      */
     public function render()
     {
+        if (! $this->allowed()) {
+            return '';
+        }
+
         $this->prepareHandle();
         $this->addScript();
 
         return $this->html();
     }
+
+    /**
+     * @return string
+     */
+    public function __toString()
+    {
+        return Helper::render($this->render());
+    }
+
+    /**
+     * Create a action instance.
+     *
+     * @param mixed ...$params
+     *
+     * @return $this
+     */
+    public static function make(...$params)
+    {
+        return new static(...$params);
+    }
 }

+ 7 - 5
src/Grid/BatchAction.php

@@ -15,6 +15,7 @@ abstract class BatchAction extends GridAction
     public function actionScript()
     {
         $warning = __('No data selected!');
+
         return <<<JS
     var key = LA.grid.selected('{$this->parent->getName()}');
     
@@ -28,10 +29,11 @@ JS;
 
     protected function html()
     {
-        return sprintf(
-            "<li><a href='javascript:void(0);' class='%s'>%s</a></li>",
-            $this->elementClass(),
-            $this->title()
-        );
+        $this->setHtmlAttribute([
+            'href'  => 'javascript:void(0);',
+            'class' => $this->elementClass(),
+        ]);
+
+        return "<li><a {$this->formatHtmlAttributes()}>{$this->title()}</a></li>";
     }
 }

+ 19 - 4
src/Grid/Concerns/HasTools.php

@@ -3,8 +3,11 @@
 namespace Dcat\Admin\Grid\Concerns;
 
 use Closure;
+use Dcat\Admin\Actions\Action;
 use Dcat\Admin\Grid\BatchAction;
 use Dcat\Admin\Grid\Tools;
+use Illuminate\Contracts\Support\Htmlable;
+use Illuminate\Contracts\Support\Renderable;
 
 trait HasTools
 {
@@ -26,17 +29,29 @@ trait HasTools
     /**
      * Get or setup grid tools.
      *
-     * @param Closure $callback
+     * @param Closure|array|Action|Tools\AbstractTool|Renderable|Htmlable|string $value
      *
      * @return $this|Tools
      */
-    public function tools(Closure $callback = null)
+    public function tools($value = null)
     {
-        if ($callback === null) {
+        if ($value === null) {
             return $this->tools;
         }
 
-        call_user_func($callback, $this->tools);
+        if ($value instanceof Closure) {
+            $value($this->tools);
+
+            return $this;
+        }
+
+        if (! is_array($value)) {
+            $value = [$value];
+        }
+
+        foreach ($value as $tool) {
+            $this->tools->append($tool);
+        }
 
         return $this;
     }

+ 8 - 10
src/Grid/RowAction.php

@@ -96,18 +96,16 @@ abstract class RowAction extends GridAction
      */
     public function html()
     {
-        if (! $href = $this->href()) {
-            $href = 'javascript:void(0);';
+        if ($href = $this->href()) {
+            $this->disabledHandler = true;
         }
 
-        $attributes = $this->formatHtmlAttributes();
+        $this->setHtmlAttribute([
+            'data-_key' => $this->key(),
+            'href'      => $this->href() ?: 'javascript:void(0);',
+            'class'     => $this->elementClass(),
+        ]);
 
-        return sprintf(
-            "<a data-_key='%s' href='%s' class='%s' {$attributes}>%s</a>",
-            $this->key(),
-            $href,
-            $this->elementClass(),
-            $this->title()
-        );
+        return "<a {$this->formatHtmlAttributes()}>{$this->title()}</a>";
     }
 }

+ 20 - 11
src/Grid/Tools.php

@@ -61,6 +61,8 @@ class Tools implements Renderable
      */
     public function append($tool)
     {
+        $this->prepareAction($tool);
+
         $this->tools->push($tool);
 
         return $this;
@@ -75,11 +77,28 @@ class Tools implements Renderable
      */
     public function prepend($tool)
     {
+        $this->prepareAction($tool);
+
         $this->tools->prepend($tool);
 
         return $this;
     }
 
+    /**
+     * @param mixed $tool
+     *
+     * @return void
+     */
+    protected function prepareAction($tool)
+    {
+        if ($tool instanceof GridAction) {
+            $tool->setGrid($this->grid);
+        }
+    }
+
+    /**
+     * @return bool
+     */
     public function has()
     {
         return ! $this->tools->isEmpty();
@@ -165,16 +184,6 @@ class Tools implements Renderable
      */
     public function render()
     {
-        return $this->tools->map(function ($tool) {
-            if ($tool instanceof AbstractTool) {
-                if (! $tool->allowed()) {
-                    return '';
-                }
-
-                return $tool->setGrid($this->grid)->render();
-            }
-
-            return Helper::render($tool);
-        })->implode(' ');
+        return $this->tools->map([Helper::class, 'render'])->implode(' ');
     }
 }

+ 18 - 43
src/Grid/Tools/AbstractTool.php

@@ -3,66 +3,41 @@
 namespace Dcat\Admin\Grid\Tools;
 
 use Dcat\Admin\Grid;
-use Illuminate\Contracts\Support\Renderable;
 
-abstract class AbstractTool implements Renderable
+abstract class AbstractTool extends Grid\GridAction
 {
     /**
-     * @var Grid
+     * @var string
      */
-    protected $grid;
+    public $selectorPrefix = '.tool-action-';
 
     /**
-     * @var bool
+     * @var string
      */
-    protected $disabled = false;
+    protected $style = 'btn btn-sm btn-primary';
 
     /**
-     * Toggle this button.
-     *
-     * @param bool $disable
-     *
-     * @return $this
+     * @return string|void
      */
-    public function disable(bool $disable = true)
+    protected function href()
     {
-        $this->disabled = $disable;
-
-        return $this;
     }
 
     /**
-     * If the tool is allowed.
+     * @return string|void
      */
-    public function allowed()
+    public function html()
     {
-        return ! $this->disabled;
-    }
+        if ($href = $this->href()) {
+            $this->disabledHandler = true;
+        }
 
-    /**
-     * Set parent grid.
-     *
-     * @param Grid $grid
-     *
-     * @return $this
-     */
-    public function setGrid(Grid $grid)
-    {
-        $this->grid = $grid;
-
-        return $this;
-    }
+        $this->setHtmlAttribute([
+            'data-_key' => $this->key(),
+            'href'      => $href ?: 'javascript:void(0);',
+            'class'     => $this->style.' '.$this->elementClass(),
+        ]);
 
-    /**
-     * {@inheritdoc}
-     */
-    abstract public function render();
-
-    /**
-     * @return string
-     */
-    public function __toString()
-    {
-        return $this->render();
+        return "<a {$this->formatHtmlAttributes()}>{$this->title()}</a>";
     }
 }

+ 1 - 1
src/Grid/Tools/BatchActions.php

@@ -73,7 +73,7 @@ class BatchActions extends AbstractTool
     protected function prepareActions()
     {
         foreach ($this->actions as $action) {
-            $action->setGrid($this->grid);
+            $action->setGrid($this->parent);
         }
     }
 

+ 2 - 1
src/Grid/Tools/CreateButton.php

@@ -4,8 +4,9 @@ namespace Dcat\Admin\Grid\Tools;
 
 use Dcat\Admin\Form;
 use Dcat\Admin\Grid;
+use Illuminate\Contracts\Support\Renderable;
 
-class CreateButton
+class CreateButton implements Renderable
 {
     /**
      * @var Grid

+ 2 - 1
src/Grid/Tools/ExportButton.php

@@ -4,8 +4,9 @@ namespace Dcat\Admin\Grid\Tools;
 
 use Dcat\Admin\Admin;
 use Dcat\Admin\Grid;
+use Illuminate\Contracts\Support\Renderable;
 
-class ExportButton extends AbstractTool
+class ExportButton implements Renderable
 {
     /**
      * @var Grid

+ 2 - 2
src/Grid/Tools/FilterButton.php

@@ -22,7 +22,7 @@ class FilterButton extends AbstractTool
      */
     protected function filter()
     {
-        return $this->grid->filter();
+        return $this->parent->filter();
     }
 
     /**
@@ -93,7 +93,7 @@ JS
 
         $this->setupScripts();
 
-        $onlyScopes = ((! $filters || $this->grid->option('show_filter') === false) && ! $scopres->isEmpty()) ? true : false;
+        $onlyScopes = ((! $filters || $this->parent->option('show_filter') === false) && ! $scopres->isEmpty()) ? true : false;
 
         $variables = [
             'scopes'           => $scopres,

+ 14 - 2
src/Grid/Tools/Paginator.php

@@ -3,11 +3,18 @@
 namespace Dcat\Admin\Grid\Tools;
 
 use Dcat\Admin\Grid;
+use Dcat\Admin\Support\Helper;
 use Dcat\Admin\Widgets\Color;
+use Illuminate\Contracts\Support\Renderable;
 use Illuminate\Pagination\LengthAwarePaginator;
 
-class Paginator extends AbstractTool
+class Paginator implements Renderable
 {
+    /**
+     * @var Grid
+     */
+    protected $grid;
+
     /**
      * @var \Illuminate\Pagination\LengthAwarePaginator
      */
@@ -60,7 +67,7 @@ class Paginator extends AbstractTool
             return;
         }
 
-        return new PerPageSelector($this->grid);
+        return (new PerPageSelector($this->grid))->render();
     }
 
     /**
@@ -96,4 +103,9 @@ class Paginator extends AbstractTool
             $this->paginationLinks().
             $this->perPageSelector();
     }
+
+    public function __toString()
+    {
+        return Helper::render($this->render());
+    }
 }

+ 16 - 10
src/Grid/Tools/PerPageSelector.php

@@ -4,9 +4,15 @@ namespace Dcat\Admin\Grid\Tools;
 
 use Dcat\Admin\Admin;
 use Dcat\Admin\Grid;
+use Illuminate\Contracts\Support\Renderable;
 
-class PerPageSelector extends AbstractTool
+class PerPageSelector implements Renderable
 {
+    /**
+     * @var Grid
+     */
+    protected $parent;
+
     /**
      * @var string
      */
@@ -24,7 +30,7 @@ class PerPageSelector extends AbstractTool
      */
     public function __construct(Grid $grid)
     {
-        $this->grid = $grid;
+        $this->parent = $grid;
 
         $this->initialize();
     }
@@ -36,11 +42,11 @@ class PerPageSelector extends AbstractTool
      */
     protected function initialize()
     {
-        $this->perPageName = $this->grid->model()->getPerPageName();
+        $this->perPageName = $this->parent->model()->getPerPageName();
 
         $this->perPage = (int) app('request')->input(
             $this->perPageName,
-            $this->grid->getPerPage()
+            $this->parent->getPerPage()
         );
     }
 
@@ -51,8 +57,8 @@ class PerPageSelector extends AbstractTool
      */
     public function getOptions()
     {
-        return collect($this->grid->getPerPages())
-            ->push($this->grid->getPerPage())
+        return collect($this->parent->getPerPages())
+            ->push($this->parent->getPerPage())
             ->push($this->perPage)
             ->unique()
             ->sort();
@@ -81,7 +87,7 @@ class PerPageSelector extends AbstractTool
 
 <label class="control-label pull-right hidden-xs" style="margin-right: 10px; font-weight: 100;">
         <small>$show</small>&nbsp;
-        <select class="input-sm form-shadow {$this->grid->getPerPageName()}" name="per-page">
+        <select class="input-sm form-shadow {$this->parent->getPerPageName()}" name="per-page">
             $options
         </select>
         &nbsp;<small>$entries</small>
@@ -96,10 +102,10 @@ EOT;
      */
     protected function script()
     {
-        return <<<EOT
-$('.{$this->grid->getPerPageName()}').change(function() {
+        return <<<JS
+$('.{$this->parent->getPerPageName()}').change(function() {
     LA.reload(this.value);
 });
-EOT;
+JS;
     }
 }

+ 1 - 1
src/Grid/Tools/QuickSearch.php

@@ -93,7 +93,7 @@ class QuickSearch extends AbstractTool
 
         Arr::forget($query, [
             $this->queryName,
-            $this->grid->model()->getPageName(),
+            $this->parent->model()->getPageName(),
             '_pjax',
         ]);
 

+ 3 - 1
src/Grid/Tools/RefreshButton.php

@@ -2,7 +2,9 @@
 
 namespace Dcat\Admin\Grid\Tools;
 
-class RefreshButton extends AbstractTool
+use Illuminate\Contracts\Support\Renderable;
+
+class RefreshButton implements Renderable
 {
     /**
      * Render refresh button of grid.