Przeglądaj źródła

Merge branch 'dev'

jqh 5 lat temu
rodzic
commit
1c5ee4c8da

+ 86 - 0
resources/views/grid/selector.blade.php

@@ -0,0 +1,86 @@
+<style>
+    .grid-selector {
+        margin: -10px;
+    }
+    .grid-selector .wrap {
+        position: relative;
+        line-height: 40px;
+        border-bottom: 1px dashed #eee;
+        padding: 0 30px;
+        font-size: 13px;
+        overflow:auto;
+    }
+    .grid-selector .wrap:last-child {
+        border-bottom: none;
+    }
+    .grid-selector .select-label {
+        float: left;
+        width: 100px;
+        padding-left: 10px;
+        color: #999;
+    }
+    .grid-selector .select-options {
+        margin-left: 100px;
+    }
+    .grid-selector ul {
+        height: 25px;
+        list-style: none;
+    }
+    .grid-selector ul > li {
+        margin-right: 30px;
+        float: left;
+    }
+    .grid-selector ul > li a {
+        color: #666;
+        text-decoration: none;
+    }
+    .grid-selector .select-options a.active {
+        color: var(--primary-dark);
+        font-weight: bold;
+    }
+    .grid-selector li .add {
+        visibility: hidden;
+    }
+    .grid-selector li:hover .add {
+        visibility: visible;
+    }
+    .grid-selector ul .clear {
+        visibility: hidden;
+    }
+    .grid-selector ul:hover .clear {
+        color: var(--danger);
+        visibility: visible;
+    }
+</style>
+
+<div class="grid-selector">
+    @foreach($selectors as $column => $selector)
+        <div class="wrap">
+            <div class="select-label">{{ $selector['label'] }}</div>
+            <div class="select-options">
+                <ul>
+                    @foreach($selector['options'] as $value => $option)
+                        @php
+                            $active = in_array($value, \Illuminate\Support\Arr::get($selected, $column, []));
+                        @endphp
+                        <li>
+                            <a href="{{ \Dcat\Admin\Grid\Tools\Selector::url($column, $value, true) }}"
+                               class="{{$active ? 'active' : ''}}">{{ $option }}</a>
+                            @if(!$active && $selector['type'] == 'many')
+                                &nbsp;
+                                <a href="{{ \Dcat\Admin\Grid\Tools\Selector::url($column, $value) }}" class="add"><i
+                                            class="fa fa-plus-square-o"></i></a>
+                            @else
+                                <a style="visibility: hidden;"><i class="fa fa-plus-square-o"></i></a>
+                            @endif
+                        </li>
+                    @endforeach
+                    <li>
+                        <a href="{{ \Dcat\Admin\Grid\Tools\Selector::url($column) }}" class="clear"><i
+                                    class="fa fa-trash"></i></a>
+                    </li>
+                </ul>
+            </div>
+        </div>
+    @endforeach
+</div>

+ 1 - 0
src/Grid.php

@@ -30,6 +30,7 @@ class Grid
         Concerns\HasExporter,
         Concerns\HasMultipleHeader,
         Concerns\HasQuickSearch,
+        Concerns\HasSelector,
         Macroable {
             __call as macroCall;
         }

+ 1 - 0
src/Grid/Concerns/HasFilter.php

@@ -50,6 +50,7 @@ trait HasFilter
 
         $this->applyQuickSearch();
         $this->applyColumnFilter();
+        $this->applySelectorQuery();
 
         return $this->filter->execute($toArray);
     }

+ 78 - 0
src/Grid/Concerns/HasSelector.php

@@ -0,0 +1,78 @@
+<?php
+
+namespace Dcat\Admin\Grid\Concerns;
+
+use Dcat\Admin\Grid;
+use Dcat\Admin\Grid\Tools\Selector;
+
+/**
+ * @mixin Grid
+ */
+trait HasSelector
+{
+    /**
+     * @var Selector
+     */
+    protected $_selector;
+
+    /**
+     * @param \Closure $closure
+     *
+     * @return $this
+     */
+    public function selector(\Closure $closure)
+    {
+        $this->_selector = new Selector();
+
+        call_user_func($closure, $this->_selector);
+
+        $this->header(function () {
+            return $this->renderSelector();
+        });
+
+        return $this;
+    }
+
+    /**
+     * Apply selector query to grid model query.
+     *
+     * @return $this
+     */
+    protected function applySelectorQuery()
+    {
+        if (is_null($this->_selector)) {
+            return $this;
+        }
+
+        $active = Selector::parseSelected();
+
+        $this->_selector->getSelectors()->each(function ($selector, $column) use ($active) {
+            if (!array_key_exists($column, $active)) {
+                return;
+            }
+
+            $values = $active[$column];
+            if ($selector['type'] == 'one') {
+                $values = current($values);
+            }
+
+            if (is_null($selector['query'])) {
+                $this->model()->whereIn($column, $values);
+            } else {
+                call_user_func($selector['query'], $this->model(), $values);
+            }
+        });
+
+        return $this;
+    }
+
+    /**
+     * Render grid selector.
+     *
+     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|string
+     */
+    public function renderSelector()
+    {
+        return $this->_selector->render();
+    }
+}

+ 167 - 0
src/Grid/Tools/Selector.php

@@ -0,0 +1,167 @@
+<?php
+
+namespace Dcat\Admin\Grid\Tools;
+
+use Illuminate\Contracts\Support\Renderable;
+use Illuminate\Support\Arr;
+use Illuminate\Support\Collection;
+
+class Selector implements Renderable
+{
+    /**
+     * @var array|Collection
+     */
+    protected $selectors = [];
+
+    /**
+     * @var array
+     */
+    protected static $selected;
+
+    /**
+     * Selector constructor.
+     */
+    public function __construct()
+    {
+        $this->selectors = new Collection();
+    }
+
+    /**
+     * @param string $column
+     * @param string|array $label
+     * @param array|\Closure $options
+     * @param null|\Closure $query
+     *
+     * @return $this
+     */
+    public function select($column, $label, $options = [], $query = null)
+    {
+        return $this->addSelector($column, $label, $options, $query);
+    }
+
+    /**
+     * @param string $column
+     * @param string $label
+     * @param array $options
+     * @param null|\Closure $query
+     *
+     * @return $this
+     */
+    public function selectOne($column, $label, $options = [], $query = null)
+    {
+        return $this->addSelector($column, $label, $options, $query, 'one');
+    }
+
+    /**
+     * @param string $column
+     * @param string $label
+     * @param array $options
+     * @param null $query
+     * @param string $type
+     *
+     * @return $this
+     */
+    protected function addSelector($column, $label, $options = [], $query = null, $type = 'many')
+    {
+        if (is_array($label)) {
+            if ($options instanceof \Closure) {
+                $query = $options;
+            }
+
+            $options = $label;
+            $label   = admin_trans_field($column);
+        }
+
+        $this->selectors[$column] = compact(
+            'label', 'options', 'type', 'query'
+        );
+
+        return $this;
+    }
+
+    /**
+     * Get all selectors.
+     *
+     * @return array|Collection
+     */
+    public function getSelectors()
+    {
+        return $this->selectors;
+    }
+
+    /**
+     * @return array
+     */
+    public static function parseSelected()
+    {
+        if (! is_null(static::$selected)) {
+            return static::$selected;
+        }
+
+        $selected = request('_selector', []);
+        if (! is_array($selected)) {
+            return [];
+        }
+
+        $selected = array_filter($selected, function ($value) {
+            return !is_null($value);
+        });
+
+        foreach ($selected as &$value) {
+            $value = explode(',', $value);
+        }
+
+        return static::$selected = $selected;
+    }
+
+    /**
+     * @param string $column
+     * @param mixed $value
+     * @param bool $add
+     *
+     * @return string
+     */
+    public static function url($column, $value = null, $add = false)
+    {
+        $query = request()->query();
+
+        $selected = static::parseSelected();
+
+        $options = Arr::get($selected, $column, []);
+
+        if (is_null($value)) {
+            Arr::forget($query, "_selector.{$column}");
+
+            return request()->fullUrlWithQuery($query);
+        }
+
+        if (in_array($value, $options)) {
+            array_delete($options, $value);
+        } else {
+            if ($add) {
+                $options = [];
+            }
+            array_push($options, $value);
+        }
+
+        if (! empty($options)) {
+            Arr::set($query, "_selector.{$column}", implode(',', $options));
+        } else {
+            Arr::forget($query, "_selector.{$column}");
+        }
+
+        return request()->fullUrlWithQuery($query);
+    }
+
+    /**
+     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+     */
+    public function render()
+    {
+        return view('admin::grid.selector', [
+            'selectors' => $this->selectors,
+            'selected'  => static::parseSelected(),
+        ]);
+    }
+
+}

+ 1 - 1
src/Layout/Menu.php

@@ -122,7 +122,7 @@ class Menu
             return trim($this->getPath($item['uri']), '/') == $path;
         }
 
-        foreach($item['children'] as $v) {
+        foreach ($item['children'] as $v) {
             if ($path == trim($this->getPath($v['uri']), '/')) {
                 return true;
             }