jqh пре 6 година
родитељ
комит
52204b67e5

+ 12 - 0
config/admin.php

@@ -1,5 +1,7 @@
 <?php
 
+use Dcat\Admin\Grid\Displayers\DropdownActions;
+
 return [
 
     /*
@@ -146,6 +148,16 @@ return [
 
     ],
 
+    'grid' => [
+
+        /*
+        |--------------------------------------------------------------------------
+        | The global Grid action display class.
+        |--------------------------------------------------------------------------
+        */
+        'grid_action_class' => Dcat\Admin\Grid\Displayers\DropdownActions::class,
+    ],
+
     /*
     |--------------------------------------------------------------------------
     | dcat-admin permission setting

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

@@ -58,6 +58,7 @@ return [
     'delete'                => 'Delete',
     'remove'                => 'Remove',
     'edit'                  => 'Edit',
+    'quick_edit'            => 'Quick Edit',
     'view'                  => 'View',
     'continue_editing'      => 'Continue editing',
     'continue_creating'     => 'Continue creating',

+ 1 - 0
resources/lang/zh-CN/admin.php

@@ -56,6 +56,7 @@ return [
     'delete'                => '删除',
     'remove'                => '移除',
     'edit'                  => '编辑',
+    'quick_edit'            => '快捷编辑',
     'continue_editing'      => '继续编辑',
     'continue_creating'     => '继续创建',
     'view'                  => '查看',

+ 18 - 0
resources/views/grid/dropdown-actions.blade.php

@@ -0,0 +1,18 @@
+<div class="grid-dropdown-actions dropdown">
+    <a href="#" style="padding:0 10px;" class="dropdown-toggle " data-toggle="dropdown">
+        <i class="fa fa-ellipsis-v"></i>
+    </a>
+    <ul class="dropdown-menu" style="min-width: 50px !important;box-shadow: 0 2px 3px 0 rgba(0,0,0,.2);border-radius:0;left: -65px;top: 5px;">
+
+        @foreach($default as $action)
+            <li>{!! \Dcat\Admin\Support\Helper::render($action) !!}</li>
+        @endforeach
+
+        @if(!empty($custom))
+            <li class="divider"></li>
+            @foreach($custom as $action)
+                <li>{!! $action !!}</li>
+            @endforeach
+        @endif
+    </ul>
+</div>

+ 3 - 0
src/Controllers/UserController.php

@@ -130,6 +130,9 @@ class UserController extends Controller
         return $grid;
     }
 
+    /**
+     * @return MiniGrid
+     */
     protected function miniGrid()
     {
         $grid = new MiniGrid(new Administrator());

+ 1 - 36
src/Grid.php

@@ -31,6 +31,7 @@ class Grid
 {
     use BuilderEvents,
         Concerns\HasElementNames,
+        Concerns\Actions,
         Concerns\Options,
         Concerns\MultipleHeader,
         Concerns\QuickSearch,
@@ -150,13 +151,6 @@ class Grid
      */
     protected $tools;
 
-    /**
-     * Callback for grid actions.
-     *
-     * @var Closure[]
-     */
-    protected $actionsCallback = [];
-
     /**
      * @var Closure
      */
@@ -547,35 +541,6 @@ class Grid
         return $this->perPages;
     }
 
-    /**
-     * Set grid action callback.
-     *
-     * @param Closure $callback
-     *
-     * @return $this
-     */
-    public function actions(Closure $callback)
-    {
-        $this->actionsCallback[] = $callback;
-
-        return $this;
-    }
-
-    /**
-     * Add `actions` column for grid.
-     *
-     * @return void
-     */
-    protected function appendActionsColumn()
-    {
-        if (!$this->options['show_actions']) {
-            return;
-        }
-
-        $this->addColumn('__actions__', trans('admin.action'))
-            ->displayUsing(Displayers\Actions::class, [$this->actionsCallback]);
-    }
-
     /**
      * @param array $options
      * @return $this

+ 27 - 0
src/Grid/Actions/Delete.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace Dcat\Admin\Grid\Actions;
+
+use Dcat\Admin\Grid\RowAction;
+
+class Delete extends RowAction
+{
+    /**
+     * @return array|null|string
+     */
+    public function name()
+    {
+        return __('admin.delete');
+    }
+
+    public function render()
+    {
+        $this->setHtmlAttribute([
+            'data-url' => "{$this->getResource()}/{$this->getKey()}",
+            'data-action' => 'delete',
+
+        ]);
+
+        return parent::render(); // TODO: Change the autogenerated stub
+    }
+}

+ 24 - 0
src/Grid/Actions/Edit.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace Dcat\Admin\Grid\Actions;
+
+use Dcat\Admin\Grid\RowAction;
+
+class Edit extends RowAction
+{
+    /**
+     * @return array|null|string
+     */
+    public function name()
+    {
+        return __('admin.edit');
+    }
+
+    /**
+     * @return string
+     */
+    public function href()
+    {
+        return "{$this->getResource()}/{$this->getKey()}/edit";
+    }
+}

+ 40 - 0
src/Grid/Actions/QuickEdit.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace Dcat\Admin\Grid\Actions;
+
+use Dcat\Admin\Form;
+use Dcat\Admin\Grid\RowAction;
+
+class QuickEdit extends RowAction
+{
+    protected static $resolvedWindow;
+
+    /**
+     * @return array|null|string
+     */
+    public function name()
+    {
+        return __('admin.quick_edit');
+    }
+
+    public function render()
+    {
+        if (!static::$resolvedWindow) {
+            static::$resolvedWindow = true;
+
+            list($width, $height) = $this->parent->option('dialog_form_area');
+
+            Form::popup(trans('admin.edit'))
+                ->click(".{$this->getElementClass()}")
+                ->dimensions($width, $height)
+                ->success('LA.reload()')
+                ->render();
+        }
+
+        $this->setHtmlAttribute([
+            'data-url' => "{$this->getResource()}/{$this->getKey()}/edit",
+        ]);
+
+        return parent::render(); // TODO: Change the autogenerated stub
+    }
+}

+ 24 - 0
src/Grid/Actions/Show.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace Dcat\Admin\Grid\Actions;
+
+use Dcat\Admin\Grid\RowAction;
+
+class Show extends RowAction
+{
+    /**
+     * @return array|null|string
+     */
+    public function name()
+    {
+        return __('admin.show');
+    }
+
+    /**
+     * @return string
+     */
+    public function href()
+    {
+        return "{$this->getResource()}/{$this->getKey()}";
+    }
+}

+ 87 - 0
src/Grid/Concerns/Actions.php

@@ -0,0 +1,87 @@
+<?php
+
+namespace Dcat\Admin\Grid\Concerns;
+
+use Closure;
+use Dcat\Admin\Grid;
+use Dcat\Admin\Grid\Displayers;
+
+trait Actions
+{
+    /**
+     * Callback for grid actions.
+     *
+     * @var Closure[]
+     */
+    protected $actionsCallback = [];
+
+    /**
+     * Actions column display class.
+     *
+     * @var string
+     */
+    protected $actionsClass;
+
+    /**
+     * @param string $actionClass
+     *
+     * @return $this
+     */
+    public function setActionClass(string $actionClass)
+    {
+        if (is_subclass_of($actionClass, Grid\Displayers\Actions::class)) {
+            $this->actionsClass = $actionClass;
+        }
+
+        return $this;
+    }
+
+
+    /**
+     * Get action display class.
+     *
+     * @return \Illuminate\Config\Repository|mixed|string
+     */
+    public function getActionClass()
+    {
+        if ($this->actionsClass) {
+            return $this->actionsClass;
+        }
+
+        if ($class = config('admin.grid.grid_action_class')) {
+            return $class;
+        }
+
+        return Grid\Displayers\Actions::class;
+    }
+
+
+    /**
+     * Set grid action callback.
+     *
+     * @param Closure $callback
+     *
+     * @return $this
+     */
+    public function actions(Closure $callback)
+    {
+        $this->actionsCallback[] = $callback;
+
+        return $this;
+    }
+
+    /**
+     * Add `actions` column for grid.
+     *
+     * @return void
+     */
+    protected function appendActionsColumn()
+    {
+        if (!$this->options['show_actions']) {
+            return;
+        }
+
+        $this->addColumn('__actions__', trans('admin.action'))
+            ->displayUsing($this->getActionClass(), [$this->actionsCallback]);
+    }
+}

+ 214 - 0
src/Grid/Displayers/DropdownActions.php

@@ -0,0 +1,214 @@
+<?php
+
+namespace Dcat\Admin\Grid\Displayers;
+
+use Dcat\Admin\Grid\Actions\QuickEdit;
+use Dcat\Admin\Grid\RowAction;
+use Dcat\Admin\Admin;
+use Dcat\Admin\Grid\Actions\Delete;
+use Dcat\Admin\Grid\Actions\Edit;
+use Dcat\Admin\Grid\Actions\Show;
+use Dcat\Admin\Support\Helper;
+use Illuminate\Contracts\Support\Renderable;
+
+class DropdownActions extends Actions
+{
+    /**
+     * @var array
+     */
+    protected $custom = [];
+
+    /**
+     * @var array
+     */
+    protected $default = [];
+
+    /**
+     * @var array
+     */
+    protected $defaultClass = [Edit::class, QuickEdit::class, Show::class, Delete::class];
+
+    /**
+     * Add JS script into pages.
+     *
+     * @return void.
+     */
+    protected function addScript()
+    {
+        $script = <<<'SCRIPT'
+(function ($) {
+    $('.table-responsive').on('show.bs.dropdown', function () {
+         $('.table-responsive').css("overflow", "inherit" );
+    });
+    
+    $('.table-responsive').on('hide.bs.dropdown', function () {
+         $('.table-responsive').css("overflow", "auto");
+    })
+})(jQuery);
+SCRIPT;
+
+        Admin::script($script);
+    }
+
+    /**
+     * @param RowAction|string|Renderable $action
+     *
+     * @return $this
+     */
+    public function append($action)
+    {
+        if ($action instanceof RowAction) {
+            $this->prepareAction($action);
+        }
+
+        array_push($this->custom, $this->wrapCustomAction($action));
+
+        return $this;
+    }
+
+    public function prepend($action)
+    {
+        return $this->append($action);
+    }
+
+    /**
+     * @param $action
+     *
+     * @return mixed
+     */
+    protected function wrapCustomAction($action)
+    {
+        $action = Helper::render($action);
+
+        if (strpos($action, '</a>') === false) {
+            return "<a>$action</a>";
+        }
+
+        return $action;
+    }
+
+    /**
+     * Prepend default `edit` `view` `delete` actions.
+     */
+    protected function prependDefaultActions()
+    {
+        foreach ($this->defaultClass as $class) {
+            /** @var RowAction $action */
+            $action = new $class();
+
+            $this->prepareAction($action);
+
+            array_push($this->default, $action);
+        }
+    }
+
+    /**
+     * @param RowAction $action
+     */
+    protected function prepareAction(RowAction $action)
+    {
+        $action->setGrid($this->grid)
+            ->setColumn($this->column)
+            ->setRow($this->row);
+    }
+
+    /**
+     * Disable view action.
+     *
+     * @param bool $disable
+     *
+     * @return $this
+     */
+    public function disableView(bool $disable = true)
+    {
+        if ($disable) {
+            array_delete($this->defaultClass, Show::class);
+        } elseif (!in_array(Show::class, $this->defaultClass)) {
+            array_push($this->defaultClass, Show::class);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Disable delete.
+     *
+     * @param bool $disable
+     *
+     * @return $this.
+     */
+    public function disableDelete(bool $disable = true)
+    {
+        if ($disable) {
+            array_delete($this->defaultClass, Delete::class);
+        } elseif (!in_array(Delete::class, $this->defaultClass)) {
+            array_push($this->defaultClass, Delete::class);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Disable edit.
+     *
+     * @param bool $disable
+     *
+     * @return $this
+     */
+    public function disableEdit(bool $disable = true)
+    {
+        if ($disable) {
+            array_delete($this->defaultClass, Edit::class);
+        } elseif (!in_array(Edit::class, $this->defaultClass)) {
+            array_push($this->defaultClass, Edit::class);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Disable quick edit.
+     *
+     * @return $this.
+     */
+    public function disableQuickEdit(bool $disable = true)
+    {
+        if ($disable) {
+            array_delete($this->defaultClass, QuickEdit::class);
+        } elseif (!in_array(Show::class, $this->defaultClass)) {
+            array_push($this->defaultClass, QuickEdit::class);
+        }
+
+        return $this;
+    }
+
+    /**
+     * @param \Closure[] $callback
+     *
+     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+     */
+    public function display($callbacks = [])
+    {
+        $this->disableView(!$this->grid->option('show_view_button'));
+        $this->disableEdit(!$this->grid->option('show_edit_button'));
+        $this->disableQuickEdit(!$this->grid->option('show_quick_edit_button'));
+        $this->disableDelete(!$this->grid->option('show_delete_button'));
+
+        $this->addScript();
+
+        foreach ($callbacks as $callback) {
+            if ($callback instanceof \Closure) {
+                $callback->call($this->row, $this);
+            }
+        }
+
+        $this->prependDefaultActions();
+
+        $actions = [
+            'default' => $this->default,
+            'custom'  => $this->custom,
+        ];
+
+        return view('admin::grid.dropdown-actions', $actions);
+    }
+}

+ 117 - 0
src/Grid/GridAction.php

@@ -0,0 +1,117 @@
+<?php
+
+namespace Dcat\Admin\Grid;
+
+use Dcat\Admin\Grid;
+use Dcat\Admin\Traits\HasHtmlAttributes;
+use Illuminate\Contracts\Support\Renderable;
+use Illuminate\Http\Request;
+
+/**
+ * Class GridAction.
+ *
+ */
+abstract class GridAction implements Renderable
+{
+    use HasHtmlAttributes;
+
+    /**
+     * @var array
+     */
+    protected static $selectors = [];
+
+    /**
+     * @var string
+     */
+    protected $name;
+
+    /**
+     * @var string
+     */
+    protected $selector;
+
+    /**
+     * @var Grid
+     */
+    protected $parent;
+
+    /**
+     * @var string
+     */
+    public $selectorPrefix = '.grid-action-';
+
+    /**
+     * @param Grid $grid
+     *
+     * @return $this
+     */
+    public function setGrid(Grid $grid)
+    {
+        $this->parent = $grid;
+
+        return $this;
+    }
+
+    /**
+     * Get url path of current resource.
+     *
+     * @return string
+     */
+    public function getResource()
+    {
+        return $this->parent->getResource();
+    }
+
+    /**
+     * @return string
+     */
+    protected function getElementClass()
+    {
+        return ltrim($this->selector($this->selectorPrefix), '.');
+    }
+
+    /**
+     * Get batch action title.
+     *
+     * @return string
+     */
+    public function name()
+    {
+        return $this->name;
+    }
+
+    /**
+     * @param string $prefix
+     *
+     * @return mixed|string
+     */
+    public function selector($prefix)
+    {
+        if (is_null($this->selector)) {
+            return static::makeSelector(get_called_class(), $prefix);
+        }
+
+        return $this->selector;
+    }
+
+    /**
+     * @param string $class
+     * @param string $prefix
+     *
+     * @return string
+     */
+    public static function makeSelector($class, $prefix)
+    {
+        if (!isset(static::$selectors[$class])) {
+            static::$selectors[$class] = uniqid($prefix);
+        }
+
+        return static::$selectors[$class];
+    }
+
+    protected function addScript()
+    {
+
+    }
+
+}

+ 111 - 0
src/Grid/RowAction.php

@@ -0,0 +1,111 @@
+<?php
+
+namespace Dcat\Admin\Grid;
+
+use Illuminate\Support\Fluent;
+
+abstract class RowAction extends GridAction
+{
+    /**
+     * @var Fluent
+     */
+    protected $row;
+
+    /**
+     * @var Column
+     */
+    protected $column;
+
+    /**
+     * @var string
+     */
+    public $selectorPrefix = '.grid-row-action-';
+
+    /**
+     * Get primary key value of current row.
+     *
+     * @return mixed
+     */
+    protected function getKey()
+    {
+        return $this->row->get($this->parent->getKeyName());
+    }
+
+    /**
+     * Set row model.
+     *
+     * @param mixed $key
+     *
+     * @return \Illuminate\Database\Eloquent\Model|mixed
+     */
+    public function row($key = null)
+    {
+        if (func_num_args() == 0) {
+            return $this->row;
+        }
+
+        return $this->row->{$key};
+    }
+
+    /**
+     * Set row model.
+     *
+     * @param Fluent $row
+     *
+     * @return $this
+     */
+    public function setRow($row)
+    {
+        $this->row = $row;
+
+        return $this;
+    }
+
+    public function getRow()
+    {
+        return $this->row;
+    }
+
+    /**
+     * @param Column $column
+     *
+     * @return $this
+     */
+    public function setColumn(Column $column)
+    {
+        $this->column = $column;
+
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function href()
+    {
+    }
+
+    /**
+     * Render row action.
+     *
+     * @return string
+     */
+    public function render()
+    {
+        $this->addScript();
+
+        if (!$href = $this->href()) {
+            $href = 'javascript:void(0);';
+        }
+
+        $attributes = $this->formatHtmlAttribute();
+
+        return sprintf(
+            "<a data-_key='%s' href='%s' class='%s' {$attributes}>%s</a>",
+            $this->getKey(),
+            $href,
+            $this->getElementClass(),
+            $this->name()
+        );
+    }
+}

+ 50 - 0
src/Traits/HasHtmlAttributes.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace Dcat\Admin\Traits;
+
+use Dcat\Admin\Support\Helper;
+
+trait HasHtmlAttributes
+{
+    /**
+     * @var array
+     */
+    protected $htmlAttributes = [];
+
+    /**
+     * @param string|array $key
+     * @param mixed $value
+     * @return $this
+     */
+    public function setHtmlAttribute($key, $value = null)
+    {
+        if (is_array($key)) {
+            $this->htmlAttributes = array_merge($this->htmlAttributes, $key);
+
+            return $this;
+        }
+        $this->htmlAttributes[$key] = $value;
+
+        return $this;
+    }
+
+    /**
+     * @param $key
+     * @param null $default
+     * @return |null
+     */
+    public function getHtmlAttribute($key, $default = null)
+    {
+        return $this->htmlAttributes[$key] ?? $default;
+    }
+
+    /**
+     * @return string
+     */
+    public function formatHtmlAttribute()
+    {
+        return Helper::buildHtmlAttributes($this->htmlAttributes);
+    }
+
+}
+