Jelajahi Sumber

:hammer: 模型树actions重构,支持闭包操作

jqh 5 tahun lalu
induk
melakukan
a655c9e117

+ 1 - 0
resources/lang/en/admin.php

@@ -101,6 +101,7 @@ return [
     'update_succeeded'      => 'Update succeeded !',
     'update_failed'         => 'Update failed !',
     'save_succeeded'        => 'Save succeeded !',
+    'save_failed'           => 'Save failed !',
     'refresh_succeeded'     => 'Refresh succeeded !',
     'login_successful'      => 'Login successful',
     'choose'                => 'Choose',

+ 1 - 11
resources/views/tree/branch.blade.php

@@ -2,17 +2,7 @@
     <div class="dd-handle">
         {!! $branchCallback($branch) !!}
         <span class="pull-right dd-nodrag">
-            @if($useEdit)
-            <a href="{{ $currentUrl }}/{{ $branch[$keyName] }}/edit"><i class="feather icon-edit-1"></i>&nbsp;</a>
-            @endif
-
-            @if($useQuickEdit)
-                <a href="javascript:void(0);" data-url="{{ $currentUrl }}/{{ $branch[$keyName] }}/edit" class="tree-quick-edit"><i class="feather icon-edit"></i></a>
-            @endif
-
-            @if($useDelete)
-            <a href="javascript:void(0);" data-message="ID - {{ $branch[$keyName] }}" data-url="{{ $currentUrl }}/{{ $branch[$keyName] }}" data-action="delete"><i class="feather icon-trash"></i></a>
-            @endif
+            {!! $resolveAction($branch) !!}
         </span>
     </div>
     @if(isset($branch['children']))

+ 33 - 0
resources/views/tree/container.blade.php

@@ -48,3 +48,36 @@
         </ol>
     </div>
 </div>
+
+<script>
+    var id = '{{ $id }}';
+    var tree = $('#'+id);
+
+    tree.nestable({!! json_encode($nestableOptions) !!});
+
+    $('.'+id+'-save').on('click', function () {
+        var serialize = tree.nestable('serialize'), _this = $(this);
+        _this.buttonLoading();
+        $.post({
+            url: '{{ $url }}',
+            data: {
+                '{{ \Dcat\Admin\Tree::SAVE_ORDER_NAME }}': JSON.stringify(serialize)
+            },
+            success: function (data) {
+                _this.buttonLoading(false);
+
+                Dcat.handleJsonResponse(data)
+            }
+        });
+    });
+
+    $('.'+id+'-tree-tools').on('click', function(e){
+        var action = $(this).data('action');
+        if (action === 'expand') {
+            tree.nestable('expandAll');
+        }
+        if (action === 'collapse') {
+            tree.nestable('collapseAll');
+        }
+    });
+</script>

+ 2 - 0
src/Console/ActionCommand.php

@@ -42,6 +42,7 @@ class ActionCommand extends GeneratorCommand
         'grid-tool'  => 'Grid',
         'form-tool'  => 'Form',
         'show-tool'  => 'Show',
+        'tree-row'   => 'Tree',
         'tree-tool'  => 'Tree',
     ];
 
@@ -79,6 +80,7 @@ class ActionCommand extends GeneratorCommand
             'grid-tool',
             'form-tool',
             'show-tool',
+            'tree-row',
             'tree-tool',
         ];
     }

+ 61 - 0
src/Console/stubs/actions/tree-row.stub

@@ -0,0 +1,61 @@
+<?php
+
+namespace DummyNamespace;
+
+use Dcat\Admin\Tree\RowAction;
+use Dcat\Admin\Actions\Response;
+use Dcat\Admin\Traits\HasPermissions;
+use Illuminate\Contracts\Auth\Authenticatable;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Http\Request;
+
+class DummyClass extends RowAction
+{
+    /**
+     * @return string
+     */
+	protected $title = 'Title';
+
+    /**
+     * Handle the action request.
+     *
+     * @param Request $request
+     *
+     * @return Response
+     */
+    public function handle(Request $request)
+    {
+    	//
+    	$key = $this->getKey();
+
+        return $this->response()
+            ->success('Processed successfully.')
+            ->redirect('/');
+    }
+
+    /**
+     * @return string|void
+     */
+    protected function href()
+    {
+        // return admin_url('auth/users');
+    }
+
+    /**
+	 * @return string|array|void
+	 */
+	public function confirm()
+	{
+		// return ['Confirm?', 'contents'];
+	}
+
+    /**
+     * @param Model|Authenticatable|HasPermissions|null $user
+     *
+     * @return bool
+     */
+    protected function authorize($user): bool
+    {
+        return true;
+    }
+}

+ 0 - 29
src/Grid/Column.php

@@ -3,12 +3,10 @@
 namespace Dcat\Admin\Grid;
 
 use Closure;
-use Dcat\Admin\Exception\RuntimeException;
 use Dcat\Admin\Grid;
 use Dcat\Admin\Grid\Displayers\AbstractDisplayer;
 use Dcat\Admin\Support\Helper;
 use Dcat\Admin\Traits\HasBuilderEvents;
-use Dcat\Admin\Traits\HasDefinitions;
 use Illuminate\Contracts\Support\Arrayable;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Arr;
@@ -57,7 +55,6 @@ use Illuminate\Support\Traits\Macroable;
 class Column
 {
     use HasBuilderEvents;
-    use HasDefinitions;
     use Grid\Column\HasHeader;
     use Grid\Column\HasDisplayers;
     use Macroable {
@@ -537,10 +534,6 @@ class Column
      */
     public function fill(array &$data)
     {
-        if (static::hasDefinition($this->name)) {
-            $this->useDefinedColumn();
-        }
-
         $i = 0;
         foreach ($data as $key => &$row) {
             $i++;
@@ -581,28 +574,6 @@ class Column
         }
     }
 
-    /**
-     * Use a defined column.
-     *
-     * @throws \Exception
-     */
-    protected function useDefinedColumn()
-    {
-        $class = static::$definitions[$this->name];
-
-        if ($class instanceof Closure) {
-            $this->display($class);
-
-            return;
-        }
-
-        if (! class_exists($class) || ! is_subclass_of($class, AbstractDisplayer::class)) {
-            throw new RuntimeException("Invalid column definition [$class]");
-        }
-
-        $this->displayUsing($class);
-    }
-
     /**
      * Convert characters to HTML entities recursively.
      *

+ 2 - 2
src/Grid/Displayers/DropdownActions.php

@@ -24,7 +24,7 @@ class DropdownActions extends Actions
     /**
      * @var array
      */
-    protected $defaultClass = [
+    protected $defaultActions = [
         'view'      => Show::class,
         'edit'      => Edit::class,
         'quickEdit' => QuickEdit::class,
@@ -74,7 +74,7 @@ class DropdownActions extends Actions
                 continue;
             }
 
-            $action = new $this->defaultClass[$action]();
+            $action = new $this->defaultActions[$action]();
 
             $this->prepareAction($action);
 

+ 2 - 3
src/Http/Controllers/UserController.php

@@ -22,9 +22,7 @@ class UserController extends AdminController
     {
         return Grid::make(Administrator::with(['roles']), function (Grid $grid) {
             $grid->column('id', 'ID')->sortable();
-            $grid->column('username')->prepend(function () {
-                return "<img src='{$this->getAvatar()}' data-action='preview-img' width='40' class='avatar img-circle' /> &nbsp; ";
-            });
+            $grid->column('username');
             $grid->column('name');
 
             if (config('admin.permission.enable')) {
@@ -58,6 +56,7 @@ class UserController extends AdminController
             $grid->showQuickEditButton();
             $grid->disableFilterButton();
             $grid->enableDialogCreate();
+            $grid->showColumnSelector();
 
             $grid->actions(function (Grid\Displayers\Actions $actions) {
                 if ($actions->getKey() == AdministratorModel::DEFAULT_ID) {

+ 0 - 22
src/Show/Field.php

@@ -7,7 +7,6 @@ use Dcat\Admin\Exception\RuntimeException;
 use Dcat\Admin\Show;
 use Dcat\Admin\Support\Helper;
 use Dcat\Admin\Traits\HasBuilderEvents;
-use Dcat\Admin\Traits\HasDefinitions;
 use Dcat\Admin\Traits\HasVariables;
 use Dcat\Admin\Widgets\Dump;
 use Illuminate\Contracts\Support\Arrayable;
@@ -23,7 +22,6 @@ class Field implements Renderable
 {
     use HasBuilderEvents;
     use HasVariables;
-    use HasDefinitions;
     use Macroable {
             __call as macroCall;
         }
@@ -679,10 +677,6 @@ HTML;
      */
     public function render()
     {
-        if (static::hasDefinition($this->name)) {
-            $this->useDefinedColumn();
-        }
-
         if ($this->showAs->isNotEmpty()) {
             $this->showAs->each(function ($callable) {
                 [$callable, $params] = $callable;
@@ -704,22 +698,6 @@ HTML;
         return view($this->view, $this->variables());
     }
 
-    /**
-     * Use a defined column.
-     *
-     * @throws \Exception
-     */
-    protected function useDefinedColumn()
-    {
-        $class = static::$definitions[$this->name];
-
-        if (! $class instanceof \Closure) {
-            throw new RuntimeException("Invalid column definition [$class]");
-        }
-
-        $this->as($class);
-    }
-
     /**
      * Register custom field.
      *

+ 0 - 34
src/Traits/HasDefinitions.php

@@ -1,34 +0,0 @@
-<?php
-
-namespace Dcat\Admin\Traits;
-
-trait HasDefinitions
-{
-    /**
-     * Defined columns.
-     *
-     * @var array
-     */
-    protected static $definitions = [];
-
-    /**
-     * @param string $name
-     * @param mixed  $definition
-     */
-    public static function define(string $name, $definition)
-    {
-        if ($name && $definition) {
-            static::$definitions[$name] = $definition;
-        }
-    }
-
-    /**
-     * @param string $name
-     *
-     * @return bool
-     */
-    public static function hasDefinition(string $name)
-    {
-        return isset(static::$definitions[$name]);
-    }
-}

+ 5 - 3
src/Traits/ModelTree.php

@@ -344,13 +344,15 @@ trait ModelTree
                 throw new AdminException(trans('admin.parent_select_error'));
             }
 
-            if (Request::has('_order')) {
-                $order = Request::input('_order');
+            if (Request::has(Tree::SAVE_ORDER_NAME)) {
+                $order = Request::input(Tree::SAVE_ORDER_NAME);
 
-                Request::offsetUnset('_order');
+                Request::offsetUnset(Tree::SAVE_ORDER_NAME);
 
                 Tree::make(new static())->saveOrder($order);
 
+                $branch->{$branch->getKeyName()} = true;
+
                 return false;
             }
 

+ 137 - 115
src/Tree.php

@@ -6,8 +6,10 @@ use Closure;
 use Dcat\Admin\Contracts\TreeRepository;
 use Dcat\Admin\Exception\InvalidArgumentException;
 use Dcat\Admin\Repositories\EloquentRepository;
+use Dcat\Admin\Support\Helper;
 use Dcat\Admin\Traits\HasBuilderEvents;
 use Dcat\Admin\Traits\HasVariables;
+use Dcat\Admin\Tree\Actions;
 use Dcat\Admin\Tree\AbstractTool;
 use Dcat\Admin\Tree\Tools;
 use Illuminate\Contracts\Support\Htmlable;
@@ -23,6 +25,8 @@ class Tree implements Renderable
     use HasVariables;
     use Macroable;
 
+    const SAVE_ORDER_NAME = '_order';
+
     /**
      * @var array
      */
@@ -88,7 +92,7 @@ class Tree implements Renderable
     /**
      * @var array
      */
-    public $dialogFormDimensions = ['700px', '620px'];
+    public $dialogFormDimensions = ['700px', '670px'];
 
     /**
      * @var bool
@@ -100,21 +104,6 @@ class Tree implements Renderable
      */
     public $useRefresh = true;
 
-    /**
-     * @var bool
-     */
-    public $useEdit = true;
-
-    /**
-     * @var bool
-     */
-    public $useQuickEdit = true;
-
-    /**
-     * @var bool
-     */
-    public $useDelete = true;
-
     /**
      * @var array
      */
@@ -127,6 +116,16 @@ class Tree implements Renderable
      */
     public $tools;
 
+    /**
+     * @var string
+     */
+    protected $actionsClass;
+
+    /**
+     * @var \Closure[]
+     */
+    protected $actionCallbacks = [];
+
     /**
      * @var Closure
      */
@@ -255,16 +254,18 @@ class Tree implements Renderable
     /**
      * Disable create.
      *
+     * @param bool $value
+     *
      * @return void
      */
-    public function disableCreateButton()
+    public function disableCreateButton(bool $value = true)
     {
-        $this->useCreate = false;
+        $this->useCreate = ! $value;
     }
 
-    public function disableQuickCreateButton()
+    public function disableQuickCreateButton(bool $value = true)
     {
-        $this->useQuickCreate = false;
+        $this->useQuickCreate = ! $value;
     }
 
     /**
@@ -283,36 +284,46 @@ class Tree implements Renderable
     /**
      * Disable save.
      *
+     * @param bool $value
+     *
      * @return void
      */
-    public function disableSaveButton()
+    public function disableSaveButton(bool $value = true)
     {
-        $this->useSave = false;
+        $this->useSave = ! $value;
     }
 
     /**
      * Disable refresh.
      *
+     * @param bool $value
+     *
      * @return void
      */
-    public function disableRefreshButton()
+    public function disableRefreshButton(bool $value = true)
     {
-        $this->useRefresh = false;
+        $this->useRefresh = ! $value;
     }
 
-    public function disableQuickEditButton()
+    public function disableQuickEditButton(bool $value = true)
     {
-        $this->useQuickEdit = false;
+        $this->actions(function (Actions $actions) use ($value) {
+            $actions->disableQuickEdit($value);
+        });
     }
 
-    public function disableEditButton()
+    public function disableEditButton(bool $value = true)
     {
-        $this->useEdit = false;
+        $this->actions(function (Actions $actions) use ($value) {
+            $actions->disableEdit($value);
+        });
     }
 
-    public function disableDeleteButton()
+    public function disableDeleteButton(bool $value = true)
     {
-        $this->useDelete = false;
+        $this->actions(function (Actions $actions) use ($value) {
+            $actions->disableDelete($value);
+        });
     }
 
     /**
@@ -355,59 +366,6 @@ class Tree implements Renderable
         return true;
     }
 
-    /**
-     * Build tree grid scripts.
-     *
-     * @return string
-     */
-    protected function script()
-    {
-        $saveSucceeded = trans('admin.save_succeeded');
-        $nestableOptions = json_encode($this->nestableOptions);
-
-        return <<<JS
-(function () {
-    var tree = $('#{$this->elementId}');
-    
-    tree.nestable($nestableOptions);
-
-    $('.{$this->elementId}-save').on('click', function () {
-        var serialize = tree.nestable('serialize'), _this = $(this);
-        _this.buttonLoading();
-        $.post('{$this->url}', {
-            _order: JSON.stringify(serialize)
-        },
-        function (data) {
-            _this.buttonLoading(false);
-            Dcat.success('{$saveSucceeded}');
-            
-            if (typeof data.location !== "undefined") {
-                return setTimeout(function () {
-                    if (data.location) {
-                        location.href = data.location;
-                    } else {
-                        location.reload();
-                    }
-                }, 1500)
-            }
-            
-            Dcat.reload();
-        });
-    });
-    
-    $('.{$this->elementId}-tree-tools').on('click', function(e){
-        var action = $(this).data('action');
-        if (action === 'expand') {
-            tree.nestable('expandAll');
-        }
-        if (action === 'collapse') {
-            tree.nestable('collapseAll');
-        }
-    });
-})()
-JS;
-    }
-
     /**
      * Set view of tree.
      *
@@ -434,6 +392,60 @@ JS;
         return $this;
     }
 
+    /**
+     * @return \Closure
+     */
+    public function resolveAction()
+    {
+        return function ($branch) {
+            $class = $this->actionsClass ?: Actions::class;
+
+            $action = new $class();
+
+            $action->setParent($this);
+            $action->setRow($branch);
+
+            $this->callActionCallbacks($action);
+
+            return $action->render();
+        };
+    }
+
+    protected function callActionCallbacks(Actions $actions)
+    {
+        foreach ($this->actionCallbacks as $callback) {
+            $callback->call($actions->row, $actions);
+        }
+    }
+
+    /**
+     * 自定义行操作类.
+     *
+     * @param string $actionClass
+     *
+     * @return $this
+     */
+    public function setActionClass(string $actionClass)
+    {
+        $this->actionsClass = $actionClass;
+
+        return $this;
+    }
+
+    /**
+     * 设置行操作回调.
+     *
+     * @param \Closure $callback
+     *
+     * @return $this
+     */
+    public function actions(\Closure $callback)
+    {
+        $this->actionCallbacks[] = $callback;
+
+        return $this;
+    }
+
     /**
      * Return all items of the tree.
      *
@@ -452,20 +464,46 @@ JS;
     public function defaultVariables()
     {
         return [
-            'id'             => $this->elementId,
-            'tools'          => $this->tools->render(),
-            'items'          => $this->getItems(),
-            'useCreate'      => $this->useCreate,
-            'useQuickCreate' => $this->useQuickCreate,
-            'useSave'        => $this->useSave,
-            'useRefresh'     => $this->useRefresh,
-            'useEdit'        => $this->useEdit,
-            'useQuickEdit'   => $this->useQuickEdit,
-            'useDelete'      => $this->useDelete,
-            'createButton'   => $this->renderCreateButton(),
+            'id'              => $this->elementId,
+            'tools'           => $this->tools->render(),
+            'items'           => $this->getItems(),
+            'useCreate'       => $this->useCreate,
+            'useQuickCreate'  => $this->useQuickCreate,
+            'useSave'         => $this->useSave,
+            'useRefresh'      => $this->useRefresh,
+            'createButton'    => $this->renderCreateButton(),
+            'nestableOptions' => $this->nestableOptions,
+            'url'             => $this->url,
+            'resolveAction'   => $this->resolveAction(),
         ];
     }
 
+    /**
+     * @return mixed
+     */
+    public function getKeyName()
+    {
+        return $this->repository->getKeyName();
+    }
+
+    /**
+     * @param string $path
+     *
+     * @return $this|string
+     */
+    public function resource(string $path = null)
+    {
+        if ($path === null) {
+            return $this->url;
+        }
+
+        if (! empty($path)) {
+            $this->url = admin_url($path);
+        }
+
+        return $this;
+    }
+
     /**
      * Setup tools.
      *
@@ -521,21 +559,6 @@ JS;
         return "&nbsp;<div class='btn-group pull-right' style='margin-right:3px'>{$btn}{$quickBtn}</div>";
     }
 
-    /**
-     * @return void
-     */
-    protected function renderQuickEditButton()
-    {
-        if ($this->useQuickEdit) {
-            [$width, $height] = $this->dialogFormDimensions;
-
-            Form::dialog(trans('admin.edit'))
-                ->click('.tree-quick-edit')
-                ->success('Dcat.reload()')
-                ->dimensions($width, $height);
-        }
-    }
-
     /**
      * @return void
      */
@@ -563,14 +586,11 @@ JS;
 
             $this->setDefaultBranchCallback();
 
-            $this->renderQuickEditButton();
             $this->renderQuickCreateButton();
 
-            Admin::script($this->script());
-
             view()->share([
                 'currentUrl'     => $this->url,
-                'keyName'        => $this->repository->getKeyName(),
+                'keyName'        => $this->getKeyName(),
                 'branchView'     => $this->branchView,
                 'branchCallback' => $this->branchCallback,
             ]);
@@ -589,10 +609,12 @@ JS;
         $view = view($this->view, $this->variables());
 
         if (! $wrapper = $this->wrapper) {
-            return "<div class='card'>{$view->render()}</div>";
+            $html = Admin::resolveHtml($view->render())['html'];
+
+            return "<div class='card'>{$html}</div>";
         }
 
-        return $wrapper($view);
+        return Admin::resolveHtml(Helper::render($wrapper($view)))['html'];
     }
 
     protected function handleException(\Throwable $e)

+ 149 - 2
src/Tree/Actions.php

@@ -2,9 +2,156 @@
 
 namespace Dcat\Admin\Tree;
 
-use Dcat\Admin\Actions\Action;
+use Dcat\Admin\Support\Helper;
+use Dcat\Admin\Tree;
+use Illuminate\Contracts\Support\Renderable;
 
-class Actions extends Action
+class Actions implements Renderable
 {
+    /**
+     * @var Tree
+     */
+    protected $parent;
 
+    /**
+     * @var \Illuminate\Database\Eloquent\Model
+     */
+    public $row;
+
+    /**
+     * @var array
+     */
+    protected $appends = [];
+
+    /**
+     * @var array
+     */
+    protected $prepends = [];
+
+    /**
+     * @var array
+     */
+    protected $actions = [
+        'delete'    => true,
+        'quickEdit' => true,
+        'edit'      => false,
+    ];
+
+    /**
+     * @var array
+     */
+    protected $defaultActions = [
+        'edit'      => Tree\Actions\Edit::class,
+        'quickEdit' => Tree\Actions\QuickEdit::class,
+        'delete'    => Tree\Actions\Delete::class,
+    ];
+
+    /**
+     * @param string|Renderable|\Dcat\Admin\Actions\Action|\Illuminate\Contracts\Support\Htmlable $action
+     *
+     * @return $this
+     */
+    public function append($action)
+    {
+        $this->prepareAction($action);
+
+        array_push($this->appends, $action);
+
+        return $this;
+    }
+
+    /**
+     * @param string|Renderable|\Dcat\Admin\Actions\Action|\Illuminate\Contracts\Support\Htmlable $action
+     *
+     * @return $this
+     */
+    public function prepend($action)
+    {
+        $this->prepareAction($action);
+
+        array_unshift($this->prepends, $action);
+
+        return $this;
+    }
+
+    public function getKey()
+    {
+        return $this->row->{$this->getParent()->getKeyName()};
+    }
+
+    public function disableQuickEdit(bool $value = true)
+    {
+        $this->actions['quickEdit'] = ! $value;
+
+        return $this;
+    }
+
+    public function disableEdit(bool $value = true)
+    {
+        $this->actions['edit'] = ! $value;
+
+        return $this;
+    }
+
+    public function disableDelete(bool $value = true)
+    {
+        $this->actions['delete'] = ! $value;
+
+        return $this;
+    }
+
+    public function render()
+    {
+        $this->prependDefaultActions();
+
+        $toString = [Helper::class, 'render'];
+
+        $prepends = array_map($toString, $this->prepends);
+        $appends = array_map($toString, $this->appends);
+
+        return implode('', array_merge($prepends, $appends));
+    }
+
+    protected function prepareAction($action)
+    {
+        if ($action instanceof RowAction) {
+            $action->setParent($this);
+            $action->setRow($this->row);
+        }
+    }
+
+    protected function prependDefaultActions()
+    {
+        foreach ($this->actions as $action => $enable) {
+            if (! $enable) {
+                continue;
+            }
+
+            $action = new $this->defaultActions[$action]();
+
+            $this->prepareAction($action);
+
+            $this->prepend($action);
+        }
+    }
+
+    public function getParent()
+    {
+        return $this->parent;
+    }
+
+    public function setParent(Tree $tree)
+    {
+        $this->parent = $tree;
+    }
+
+    public function getRow()
+    {
+        return $this->row;
+    }
+
+    public function setRow($row)
+    {
+        $this->row = $row;
+    }
 }

+ 4 - 18
src/Tree/Actions/Delete.php

@@ -6,24 +6,10 @@ use Dcat\Admin\Tree\RowAction;
 
 class Delete extends RowAction
 {
-    public function title()
+    public function html()
     {
-        return '<i class="feather icon-trash"></i> '.__('admin.delete');
-    }
-
-    public function render()
-    {
-        $this->setHtmlAttribute([
-            'data-url'     => $this->url(),
-            'data-message' => "ID - {$this->getKey()}",
-            'data-action'  => 'delete',
-        ]);
-
-        return parent::render(); // TODO: Change the autogenerated stub
-    }
-
-    public function url()
-    {
-        return "{$this->resource()}/{$this->getKey()}";
+        return <<<HTML
+<a href="javascript:void(0);" data-message="ID - {$this->getKey()}" data-url="{$this->resource()}/{$this->getKey()}" data-action="delete"><i class="feather icon-trash"></i>&nbsp;</a>
+HTML;
     }
 }

+ 6 - 1
src/Tree/Actions/Edit.php

@@ -6,5 +6,10 @@ use Dcat\Admin\Tree\RowAction;
 
 class Edit extends RowAction
 {
-
+    public function html()
+    {
+        return <<<HTML
+<a href="{$this->resource()}/{$this->getKey()}/edit"><i class="feather icon-edit-1"></i>&nbsp;</a>
+HTML;
+    }
 }

+ 15 - 0
src/Tree/Actions/QuickEdit.php

@@ -2,9 +2,24 @@
 
 namespace Dcat\Admin\Tree\Actions;
 
+use Dcat\Admin\Form;
 use Dcat\Admin\Tree\RowAction;
 
 class QuickEdit extends RowAction
 {
+    protected $dialogFormDimensions = ['700px', '670px'];
 
+    public function html()
+    {
+        [$width, $height] = $this->dialogFormDimensions;
+
+        Form::dialog(trans('admin.edit'))
+            ->click('.tree-quick-edit')
+            ->success('Dcat.reload()')
+            ->dimensions($width, $height);
+
+        return <<<HTML
+<a href="javascript:void(0);" data-url="{$this->resource()}/{$this->getKey()}/edit" class="tree-quick-edit"><i class="feather icon-edit"></i>&nbsp;</a>
+HTML;
+    }
 }

+ 0 - 10
src/Tree/Actions/Show.php

@@ -1,10 +0,0 @@
-<?php
-
-namespace Dcat\Admin\Tree\Actions;
-
-use Dcat\Admin\Tree\RowAction;
-
-class Show extends RowAction
-{
-
-}

+ 55 - 0
src/Tree/RowAction.php

@@ -6,5 +6,60 @@ use Dcat\Admin\Actions\Action;
 
 class RowAction extends Action
 {
+    /**
+     * @var \Dcat\Admin\Tree\Actions;
+     */
+    protected $actions;
 
+    /**
+     * @var \Illuminate\Database\Eloquent\Model
+     */
+    protected $row;
+
+    public $selectorPrefix = '.tree-row-action-';
+
+    /**
+     * 获取主键值.
+     *
+     * @return array|mixed|string
+     */
+    public function getKey()
+    {
+        return $this->row->{$this->actions->getParent()->getKeyName()};
+    }
+
+    /**
+     * 获取行数据.
+     *
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function getRow()
+    {
+        return $this->row;
+    }
+
+    /**
+     * 获取资源路径.
+     *
+     * @return string
+     */
+    public function resource()
+    {
+        return $this->actions->getParent()->resource();
+    }
+
+    public function getActions()
+    {
+        return $this->actions;
+    }
+
+    public function setParent(Actions $actions)
+    {
+        $this->actions = $actions;
+    }
+
+    public function setRow($row)
+    {
+        $this->row = $row;
+    }
 }