瀏覽代碼

增加"Grid\Column::if"方法

jqh 5 年之前
父節點
當前提交
91d5434ce9

+ 16 - 6
src/Controllers/ExtensionController.php

@@ -106,13 +106,18 @@ class ExtensionController extends Controller
         $grid->name;
         $grid->version;
         $grid->alias;
-        $grid->description->expand(function ($expand) {
-            if (!$this->description) return;
 
-            $expand->button(trans('admin.view'));
+        $grid->description
+            ->if(function () {
+                return mb_strlen($this->description) > 14;
+            })
+            ->limit(14)
+            ->expand(function ($expand) {
+                if (!$this->description) return;
+
+                return "<div style='padding:10px 20px'>{$this->description}</div>";
+            });
 
-            return "<div style='padding:10px 20px'>{$this->description}</div>";
-        });
         $grid->authors;
 
         $grid->enable->switch();
@@ -122,8 +127,13 @@ class ExtensionController extends Controller
         $view = ucfirst(trans('admin.view'));
 
         $grid->config
+            ->if(function () {
+                return $this->config ? true : false;
+            })
             ->display($view)
-            ->expand($this->getExpandHandler('config'));
+            ->expand($this->getExpandHandler('config'))
+            ->else()
+            ->showEmpty();
 
         $grid->require
             ->display($view)

+ 4 - 4
src/Form.php

@@ -1108,17 +1108,17 @@ class Form implements Renderable
 
     /**
      * @example
-     *     $form->if(true)->next(function (Form $form) {
+     *     $form->if(true)->then(function (Form $form) {
      *          $form->text('name');
      *     });
      *
      *     $form->if(function (Form $form) {
      *         return $form->model()->id > 5;
-     *     })->next(function (Form $form) {
+     *     })->then(function (Form $form) {
      *         $form->text('name');
      *     });
      *
-     *     $form->if(true)->then(function (Form $form) {
+     *     $form->if(true)->now(function (Form $form) {
      *         $form->text('name');
      *     });
      *
@@ -1163,7 +1163,7 @@ class Form implements Renderable
         }
 
         foreach ($this->conditions as $condition) {
-            $condition->then();
+            $condition->process();
         }
     }
 

+ 9 - 4
src/Form/Condition.php

@@ -26,14 +26,19 @@ class Condition
         $this->form = $form;
     }
 
-    public function next(\Closure $closure)
+    public function then(\Closure $closure)
     {
         $this->next[] = $closure;
 
         return $this;
     }
 
-    public function then(\Closure $next = null)
+    public function now(\Closure $next = null)
+    {
+        $this->process($next);
+    }
+
+    public function process(\Closure $next = null)
     {
         if ($this->done) {
             return;
@@ -45,7 +50,7 @@ class Condition
         }
 
         if ($next) {
-            $this->next($next);
+            $this->then($next);
         }
 
         foreach ($this->next as $callback) {
@@ -73,7 +78,7 @@ class Condition
             return $this;
         }
 
-        return $this->next(function (Form $form) use ($name, &$arguments) {
+        return $this->then(function (Form $form) use ($name, &$arguments) {
             return $form->$name(...$arguments);
         });
     }

+ 109 - 20
src/Grid/Column.php

@@ -36,7 +36,6 @@ use Illuminate\Support\Str;
  * @method $this copyable()
  * @method $this orderable()
  *
- * @method $this limit($limit = 100, $end = '...')
  * @method $this ascii()
  * @method $this camel()
  * @method $this finish($cap)
@@ -118,6 +117,11 @@ class Column
      */
     protected $label;
 
+    /**
+     * @var Fluent
+     */
+    protected $originalModel;
+
     /**
      * Original value of column.
      *
@@ -164,6 +168,11 @@ class Column
      */
     protected static $model;
 
+    /**
+     * @var Grid\Column\Condition
+     */
+    protected $conditions = [];
+
     /**
      * @param string $name
      * @param string $label
@@ -236,6 +245,37 @@ class Column
         return $this;
     }
 
+    /**
+     *
+     * @example
+     *     $grid->config
+     *         ->if(function () {
+     *             return $this->config ? true : false;
+     *         })
+     *         ->display($view)
+     *         ->expand(...)
+     *         ->else()
+     *         ->showEmpty()
+     *
+     *    $grid->config
+     *         ->if(function () {
+     *             return $this->config ? true : false;
+     *         })
+     *         ->then(function (Column $column) {
+     *             $column ->display($view)->expand(...);
+     *         })
+     *         ->else(function (Column $column) {
+     *             $column->showEmpty();
+     *         })
+     *
+     * @param \Closure $condition
+     * @return Column\Condition|$this
+     */
+    public function if(\Closure $condition)
+    {
+        return $this->conditions[] = new Grid\Column\Condition($condition, $this);
+    }
+
     /**
      * Set column attributes.
      *
@@ -321,6 +361,26 @@ class Column
         return $this->name;
     }
 
+    /**
+     * @param array|Model $model
+     */
+    public function setOriginalModel($model)
+    {
+        if (is_array($model)) {
+            $model = new Fluent($model);
+        }
+
+        $this->originalModel = $model;
+    }
+
+    /**
+     * @return Fluent|Model
+     */
+    public function getOriginalModel()
+    {
+        return $this->originalModel;
+    }
+
     /**
      * @return mixed
      */
@@ -435,20 +495,37 @@ class Column
      *
      * @return bool
      */
-    protected function hasDisplayCallbacks()
+    public function hasDisplayCallbacks()
+    {
+        return ! empty($this->displayCallbacks);
+    }
+
+    /**
+     * @param array $callbacks
+     *
+     * @return void
+     */
+    public function setDisplayCallbacks(array $callbacks)
     {
-        return !empty($this->displayCallbacks);
+        $this->displayCallbacks = $callbacks;
+    }
+
+    /**
+     * @return \Closure[]
+     */
+    public function getDisplayCallbacks()
+    {
+        return $this->displayCallbacks;
     }
 
     /**
      * Call all of the "display" callbacks column.
      *
      * @param mixed $value
-     * @param int   $key
      *
      * @return mixed
      */
-    protected function callDisplayCallbacks($value, $key)
+    protected function callDisplayCallbacks($value)
     {
         foreach ($this->displayCallbacks as $callback) {
             list($callback, $params) = $callback;
@@ -460,14 +537,15 @@ class Column
 
             $previous = $value;
 
-            $callback = $this->bindOriginalRowModel($callback, $key);
+            $callback = $this->bindOriginalRowModel($callback);
             $value = $callback($value, $this, ...$params);
 
-            if (($value instanceof static) &&
-                ($last = array_pop($this->displayCallbacks))
+            if (
+                $value instanceof static
+                && ($last = array_pop($this->displayCallbacks))
             ) {
                 list($last, $params) = $last;
-                $last = $this->bindOriginalRowModel($last, $key);
+                $last = $this->bindOriginalRowModel($last);
                 $value = call_user_func($last, $previous, $this, ...$params);
             }
         }
@@ -479,19 +557,12 @@ class Column
      * Set original grid data to column.
      *
      * @param Closure $callback
-     * @param int     $key
      *
      * @return Closure
      */
-    protected function bindOriginalRowModel(Closure $callback, $key)
+    protected function bindOriginalRowModel(Closure $callback)
     {
-        $rowModel = static::$originalGridModels[$key];
-
-        if (is_array($rowModel)) {
-            $rowModel = new Fluent($rowModel);
-        }
-
-        return $callback->bindTo($rowModel);
+        return $callback->bindTo($this->getOriginalModel());
     }
 
     /**
@@ -508,7 +579,7 @@ class Column
         $i = 0;
         foreach ($data as $key => &$row) {
             $i++;
-            if (!isset($row['#'])) {
+            if (! isset($row['#'])) {
                 $row['#'] = $i;
             }
 
@@ -516,10 +587,14 @@ class Column
 
             $this->value = $value = $this->htmlEntityEncode($value);
 
+            $this->setOriginalModel(static::$originalGridModels[$key]);
+
+            $this->processConditions();
+
             Arr::set($row, $this->name, $value);
 
             if ($this->hasDisplayCallbacks()) {
-                $value = $this->callDisplayCallbacks($this->original, $key);
+                $value = $this->callDisplayCallbacks($this->original);
                 Arr::set($row, $this->name, $value);
             }
         }
@@ -527,6 +602,20 @@ class Column
         $this->value = $value ?? null;
     }
 
+    /**
+     * @return void
+     */
+    protected function processConditions()
+    {
+        foreach ($this->conditions as $condition) {
+            $condition->reset();
+        }
+
+        foreach ($this->conditions as $condition) {
+            $condition->process();
+        }
+    }
+
     /**
      * Use a defined column.
      *

+ 120 - 0
src/Grid/Column/Condition.php

@@ -0,0 +1,120 @@
+<?php
+
+namespace Dcat\Admin\Grid\Column;
+
+use Dcat\Admin\Grid\Column;
+
+class Condition
+{
+    /**
+     * @var Column
+     */
+    protected $original;
+
+    /**
+     * @var Column
+     */
+    protected $column;
+
+    /**
+     * @var mixed
+     */
+    protected $condition;
+
+    /**
+     * @var \Closure[]
+     */
+    protected $next = [];
+
+    public function __construct($condition, Column $column)
+    {
+        $this->condition = $condition;
+        $this->original = clone $column;
+        $this->column = $column;
+    }
+
+    public function then(\Closure $closure)
+    {
+        $this->next[] = $closure;
+
+        return $this;
+    }
+
+    public function else(\Closure $next = null)
+    {
+        $self = $this;
+
+        $condition = $this->column->if(function () use ($self) {
+            return ! $self->is();
+        });
+
+        if ($next) {
+            $condition->then($next);
+        }
+
+        return $condition;
+    }
+
+    public function process()
+    {
+        if ($this->is()) {
+            $this->callCallbacks($this->next);
+        }
+    }
+
+    protected function callCallbacks(array $callbacks)
+    {
+        if (! $callbacks) {
+            return;
+        }
+
+        $column = $this->copy();
+
+        foreach ($callbacks as $callback) {
+            $this->call($callback, $column);
+        }
+
+        $this->setColumnDisplayers($column->getDisplayCallbacks());
+    }
+
+    public function reset()
+    {
+        $this->setColumnDisplayers($this->original->getDisplayCallbacks());
+    }
+
+    public function setColumnDisplayers(array $callbacks)
+    {
+        $this->column->setDisplayCallbacks($callbacks);
+    }
+
+    protected function copy()
+    {
+        return clone $this->original;
+    }
+
+    public function is()
+    {
+        $condition = $this->condition;
+
+        if ($condition instanceof \Closure) {
+            $condition = $this->call($condition);
+        }
+
+        return $condition ? true : false;
+    }
+
+    protected function call(\Closure $callback, $column = null)
+    {
+        $column = $column ?: $this->column;
+
+        return $callback->call($this->column->getOriginalModel(), $column);
+    }
+
+    public function __call($name, $arguments)
+    {
+        return $this->then(function ($column) use ($name, &$arguments) {
+            return $column->$name(...$arguments);
+        });
+    }
+
+}

+ 26 - 0
src/Grid/Column/HasDisplayers.php

@@ -172,4 +172,30 @@ trait HasDisplayers
         });
     }
 
+    /**
+     * Limit the number of characters in a string.
+     *
+     * @param  int     $limit
+     * @param  string  $end
+     * @return $this
+     */
+    public function limit($limit = 100, $end = '...')
+    {
+        return $this->display(function ($value) use ($limit, $end) {
+            if (mb_strlen($value, 'UTF-8') <= $limit) {
+                return $value;
+            }
+
+            return mb_substr($value, 0, $limit).$end;
+        });
+    }
+
+    /**
+     * @return $this
+     */
+    public function showEmpty()
+    {
+        return $this->display('');
+    }
+
 }

+ 1 - 1
src/Grid/Displayers/Expand.php

@@ -37,7 +37,7 @@ class Expand extends AbstractDisplayer
 
         $key = $this->getDataKey();
 
-        $button = $this->button ?? $this->value;
+        $button = is_null($this->button) ? $this->value : $this->button;
 
         return <<<EOT
 <span class="grid-expand" data-inserted="0" data-key="{$key}" data-toggle="collapse" data-target="#grid-collapse-{$key}">

+ 3 - 3
src/Models/Role.php

@@ -65,7 +65,7 @@ class Role extends Model
      *
      * @return bool
      */
-    public function can(string $permission) : bool
+    public function can(?string $permission) : bool
     {
         return $this->permissions()->where('slug', $permission)->exists();
     }
@@ -77,7 +77,7 @@ class Role extends Model
      *
      * @return bool
      */
-    public function cannot(string $permission) : bool
+    public function cannot(?string $permission) : bool
     {
         return !$this->can($permission);
     }
@@ -115,7 +115,7 @@ class Role extends Model
      * @param string $slug
      * @return bool
      */
-    public static function isAdministrator(string $slug)
+    public static function isAdministrator(?string $slug)
     {
         return $slug === static::ADMINISTRATOR;
     }