Procházet zdrojové kódy

Merge remote-tracking branch 'upstream/2.0' into 2.0

Joker před 5 roky
rodič
revize
78f4a1e789

+ 2 - 1
.travis.yml

@@ -25,6 +25,7 @@ install:
 #  - sudo apt upgrade dpkg
   - sudo dpkg -i /tmp/google-chrome-stable_current_amd64.deb
   - mysql -e 'create database if not exists laravel;'
+  - composer self-update --2
   - travis_retry composer create-project --prefer-dist laravel/laravel laravel-tests
   - cp -f ./tests/resources/stubs/artisan ./laravel-tests/
   - cp -f ./tests/resources/stubs/ComposerConfigCommand.php ./laravel-tests/app/
@@ -47,7 +48,7 @@ install:
   - php artisan admin:publish --force
   - php artisan admin:install
   - php artisan migrate:rollback
-  - php artisan dusk:chrome-driver 85
+  - php artisan dusk:chrome-driver 87
 #  - php artisan dusk:update 79
   - cp -f ./tests/routes.php ./app/Admin/
   - cp -rf ./tests/resources/config ./config/

+ 2 - 2
resources/views/tree/container.blade.php

@@ -49,11 +49,11 @@
     </div>
 </div>
 
-<script>
+<script require="@jquery.nestable">
     var id = '{{ $id }}';
     var tree = $('#'+id);
 
-    tree.nestable({!! json_encode($nestableOptions) !!});
+    tree.nestable({!! admin_javascript_json($nestableOptions) !!});
 
     $('.'+id+'-save').on('click', function () {
         var serialize = tree.nestable('serialize'), _this = $(this);

+ 19 - 6
src/Console/ExportSeedCommand.php

@@ -41,24 +41,32 @@ class ExportSeedCommand extends Command
             'DummyNamespace' => ucwords($namespace),
             'DummyClass' => $name,
 
-            'ClassMenu'       => config('admin.database.menu_model'),
-            'ClassPermission' => config('admin.database.permissions_model'),
-            'ClassRole'       => config('admin.database.roles_model'),
+            'ClassMenu'             => $this->getTableName('admin.database.menu_model'),
+            'ClassPermission'       => $this->getTableName('admin.database.permissions_model'),
+            'ClassRole'             => $this->getTableName('admin.database.roles_model'),
+            'ClassSetting'          => 'Models\Setting',
+            'ClassExtension'        => 'Models\Extension',
+            'ClassExtensionHistory' => 'Models\ExtensionHistory',
 
-            'TableRoleMenu'        => config('admin.database.role_menu_table'),
-            'TableRolePermissions' => config('admin.database.role_permissions_table'),
+            'TablePermissionMenu'  => $this->getTableName('admin.database.permission_menu_table'),
+            'TableRoleMenu'        => $this->getTableName('admin.database.role_menu_table'),
+            'TableRolePermissions' => $this->getTableName('admin.database.role_permissions_table'),
 
             'ArrayMenu'       => $this->getTableDataArrayAsString(config('admin.database.menu_table'), $exceptFields),
             'ArrayPermission' => $this->getTableDataArrayAsString(config('admin.database.permissions_table'), $exceptFields),
             'ArrayRole'       => $this->getTableDataArrayAsString(config('admin.database.roles_table'), $exceptFields),
+            'ArraySetting'    => $this->getTableDataArrayAsString(config('admin.database.settings_table') ?: 'admin_settings', $exceptFields),
+            'ArrayExtension'  => $this->getTableDataArrayAsString(config('admin.database.extensions_table') ?: 'admin_extensions', $exceptFields),
+            'ArrayExtHistory' => $this->getTableDataArrayAsString(config('admin.database.extension_histories_table') ?: 'admin_extension_histories', $exceptFields),
 
+            'ArrayPivotPermissionMenu'  => $this->getTableDataArrayAsString(config('admin.database.permission_menu_table'), $exceptFields),
             'ArrayPivotRoleMenu'        => $this->getTableDataArrayAsString(config('admin.database.role_menu_table'), $exceptFields),
             'ArrayPivotRolePermissions' => $this->getTableDataArrayAsString(config('admin.database.role_permissions_table'), $exceptFields),
         ];
 
         if ($exportUsers) {
             $replaces = array_merge($replaces, [
-                'ClassUsers'            => config('admin.database.users_model'),
+                'ClassUsers'            => $this->getTableName('admin.database.users_model'),
                 'TableRoleUsers'        => config('admin.database.role_users_table'),
                 'ArrayUsers'            => $this->getTableDataArrayAsString(config('admin.database.users_table'), $exceptFields),
                 'ArrayPivotRoleUsers'   => $this->getTableDataArrayAsString(config('admin.database.role_users_table'), $exceptFields),
@@ -75,6 +83,11 @@ class ExportSeedCommand extends Command
         $this->line("Use: <info>php artisan db:seed --class={$name}</info>");
     }
 
+    protected function getTableName($config)
+    {
+        return trim(str_replace('Dcat\\Admin\\', '', config($config)), '\\');
+    }
+
     /**
      * Get data array from table as string result var_export.
      *

+ 21 - 0
src/Console/stubs/AdminTablesSeeder.stub

@@ -2,6 +2,7 @@
 
 namespace Database\DummyNamespace;
 
+use Dcat\Admin\Models;
 use Illuminate\Database\Seeder;
 use DB;
 
@@ -30,7 +31,27 @@ class DummyClass extends Seeder
             ArrayRole
         );
 
+        ClassSetting::truncate();
+		ClassSetting::insert(
+			ArraySetting
+		);
+
+		ClassExtension::truncate();
+		ClassExtension::insert(
+			ArrayExtension
+		);
+
+		ClassExtensionHistory::truncate();
+		ClassExtensionHistory::insert(
+			ArrayExtHistory
+		);
+
         // pivot tables
+        DB::table('TablePermissionMenu')->truncate();
+		DB::table('TablePermissionMenu')->insert(
+			ArrayPivotPermissionMenu
+		);
+
         DB::table('TableRoleMenu')->truncate();
         DB::table('TableRoleMenu')->insert(
             ArrayPivotRoleMenu

+ 3 - 0
src/Console/stubs/config.stub

@@ -264,6 +264,9 @@ return [
         'role_permissions_table' => 'admin_role_permissions',
         'role_menu_table'        => 'admin_role_menu',
         'permission_menu_table'  => 'admin_permission_menu',
+        'settings_table'         => 'admin_settings',
+		'extensions_table'       => 'admin_extensions',
+		'extension_histories_table' => 'admin_extension_histories',
     ],
 
     /*

+ 1 - 1
src/Form.php

@@ -571,7 +571,7 @@ class Form implements Renderable
                 ->alert()
                 ->status($status)
                 ->message($message)
-                ->refreshIf($status)
+                ->redirectIf($status, $this->resource(-1))
         );
     }
 

+ 0 - 1
src/Form/NestedForm.php

@@ -283,7 +283,6 @@ class NestedForm extends WidgetForm
 
         if (method_exists($this->form, 'builder')) {
             $this->form->builder()->fields()->push($field);
-            $this->form->ignore($field->column());
             $field->attribute(Field::BUILD_IGNORE, true);
         }
 

+ 1 - 0
src/Http/Controllers/MenuController.php

@@ -68,6 +68,7 @@ class MenuController extends AdminController
             $tree->disableCreateButton();
             $tree->disableQuickCreateButton();
             $tree->disableEditButton();
+            $tree->maxDepth(3);
 
             $tree->actions(function (Tree\Actions $actions) {
                 if ($actions->getRow()->extension) {

+ 0 - 1
src/Support/Helper.php

@@ -12,7 +12,6 @@ use Illuminate\Contracts\Support\Renderable;
 use Illuminate\Http\Request;
 use Illuminate\Support\Arr;
 use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Artisan;
 use Illuminate\Support\Facades\File;
 use Illuminate\Support\Str;
 use Symfony\Component\Process\Process;

+ 21 - 11
src/Tree.php

@@ -19,6 +19,11 @@ use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Str;
 use Illuminate\Support\Traits\Macroable;
 
+/**
+ * Class Tree.
+ *
+ * @see https://github.com/dbushell/Nestable
+ */
 class Tree implements Renderable
 {
     use HasBuilderEvents;
@@ -144,8 +149,7 @@ class Tree implements Renderable
 
         $this->elementId .= Str::random(8);
 
-        $this->setupTools();
-        $this->requireAssets();
+        $this->setUpTools();
 
         if ($callback instanceof \Closure) {
             call_user_func($callback, $this);
@@ -157,7 +161,7 @@ class Tree implements Renderable
     /**
      * Setup tree tools.
      */
-    public function setupTools()
+    public function setUpTools()
     {
         $this->tools = new Tools($this);
     }
@@ -186,14 +190,6 @@ class Tree implements Renderable
         return $repository;
     }
 
-    /**
-     * Collect assets.
-     */
-    protected function requireAssets()
-    {
-        Admin::requireAssets('jquery.nestable');
-    }
-
     /**
      * Initialize branch callback.
      *
@@ -237,6 +233,20 @@ class Tree implements Renderable
         return $this;
     }
 
+    /**
+     * number of levels an item can be nested (default 5).
+     *
+     * @see https://github.com/dbushell/Nestable
+     *
+     * @param int $max
+     *
+     * @return $this
+     */
+    public function maxDepth(int $max)
+    {
+        return $this->nestable(['maxDepth' => $max]);
+    }
+
     /**
      * Set nestable options.
      *

+ 39 - 5
tests/Browser/Components/Form/Field/HasMany.php

@@ -2,7 +2,7 @@
 
 namespace Tests\Browser\Components\Form\Field;
 
-use Dcat\Admin\Form\Field;
+use Dcat\Admin\Form\NestedForm;
 use Laravel\Dusk\Browser;
 use Tests\Browser\Components\Component;
 use Tests\PHPUnit;
@@ -51,7 +51,7 @@ class HasMany extends Component
             '@add' => '.add',
             '@remove' => '.remove',
             '@forms' => ".has-many-{$this->relation}-forms",
-            '@group' => ".has-many-{$this->relation}-forms .fields-group",
+            '@group' => ".has-many-{$this->relation}-forms .has-many-{$this->relation}-form",
         ];
     }
 
@@ -97,7 +97,7 @@ return $('{$this->formatSelector($browser, '@group')}').length;
 JS
         );
 
-        return $length[0] ?? null;
+        return $length[0] ?? 0;
     }
 
     /**
@@ -183,14 +183,48 @@ JS
      *
      * @return string|null
      */
-    public function assertFormGroupInputValue(Browser $browser, $field, $value)
+    public function assertFormGroupInputValue(Browser $browser, $field, $value, $id = null)
     {
         $input = $browser->script(
                 <<<JS
-return $('{$browser->resolver->format('.'.Field::FIELD_CLASS_PREFIX.$field)}').val();
+return $('{$this->getFieldSelector($browser, $field, $id)}').val();
 JS
         )[0] ?? null;
 
         PHPUnit::assertEquals($input, $value);
     }
+
+    /**
+     * 填充字段数据.
+     *
+     * @param \Laravel\Dusk\Browser $browser
+     * @param $field
+     * @param $value
+     * @param null $id
+     */
+    public function fillFieldValue(Browser $browser, $field, $value, $id = null)
+    {
+        $browser->script(
+            <<<JS
+$('{$this->getFieldSelector($browser, $field, $id)}').val('$value');
+JS
+        );
+    }
+
+    /**
+     * 获取元素选择器.
+     *
+     * @param $field
+     * @param null $id
+     *
+     * @return array|string
+     */
+    public function getFieldSelector(Browser $browser, $field, $id = null)
+    {
+        return $browser->resolver->format(
+            (new NestedForm($this->relation, $id))
+                ->text($field)
+                ->getElementClassSelector()
+        );
+    }
 }

+ 1 - 3
tests/Browser/Components/Form/Field/Tree.php

@@ -45,10 +45,8 @@ class Tree extends Component
      */
     public function elements()
     {
-        $prefix = Field::FIELD_CLASS_PREFIX;
-
         return [
-            '@container' => ".{$prefix}{$this->name}-tree-wrapper",
+            '@container' => (new Field($this->name))->getElementClassSelector(),
             '@tree'      => '.da-tree',
             '@input'     => sprintf('input[name="%s"][type="hidden"]', $this->name),
         ];

+ 1 - 2
tests/Browser/Pages/MenuPage.php

@@ -36,8 +36,7 @@ class MenuPage extends Page
                     ->assertSeeText('Users')
                     ->assertSeeText('Roles')
                     ->assertSeeText('Permission')
-                    ->assertSeeText('Menu')
-                    ->assertSeeText('Operation log');
+                    ->assertSeeText('Menu');
             }, 1)
             ->within('@form', function (Browser $browser) {
                 $browser->assertSeeText(__('admin.parent_id'))

+ 1 - 6
tests/Browser/Pages/PainterCreatePage.php

@@ -2,7 +2,6 @@
 
 namespace Tests\Browser\Pages;
 
-use Dcat\Admin\Form\Field;
 use Laravel\Dusk\Browser;
 use Tests\Browser\Components\Form\Field\HasMany;
 
@@ -81,11 +80,7 @@ class PainterCreatePage extends Page
 
                             $browser->withLastFormGroup(function (Browser $browser) use ($input) {
                                 foreach ($input as $k => $v) {
-                                    $browser->script(
-                                        <<<JS
-                                    $('{$browser->resolver->format('.'.Field::FIELD_CLASS_PREFIX.$k)}').val('$v');
-JS
-                                    );
+                                    $browser->fillFieldValue($k, $v);
                                 }
                             });
                         }

+ 3 - 3
tests/Browser/Pages/PainterEditPage.php

@@ -44,9 +44,9 @@ class PainterEditPage extends PainterCreatePage
             $browser->within(new HasMany('paintings'), function (Browser $browser) {
                 $this->painter->paintings->each(function (Painting $painting, $key) use ($browser) {
                     $browser->withFormGroup($key + 1, function (Browser $browser) use ($painting) {
-                        $browser->assertFormGroupInputValue('title', $painting->title);
-                        $browser->assertFormGroupInputValue('body', $painting->body);
-                        $browser->assertFormGroupInputValue('completed_at', $painting->completed_at);
+                        $browser->assertFormGroupInputValue('title', $painting->title, $painting->getKey());
+                        $browser->assertFormGroupInputValue('body', $painting->body, $painting->getKey());
+                        $browser->assertFormGroupInputValue('completed_at', $painting->completed_at, $painting->getKey());
                     });
                 });
             });

+ 9 - 3
tests/CreatesApplication.php

@@ -53,11 +53,17 @@ trait CreatesApplication
 
     protected function destory()
     {
-        (new \CreateAdminTables())->down();
-
+        //(new \CreateAdminTables())->down();
+        //(new \CreateAdminSettingsTable())->down();
+        //(new \CreateAdminExtensionsTable())->down();
+        //(new \UpdateAdminMenuTable())->down();
+        //
         (new \CreateTestTables())->down();
 
-        DB::select("delete from `migrations` where `migration` = '2016_01_04_173148_create_admin_tables'");
+        //DB::select("delete from `migrations` where `migration` = '2016_01_04_173148_create_admin_tables'");
+        //DB::select("delete from `migrations` where `migration` = '2020_09_07_090635_create_admin_settings_table'");
+        //DB::select("delete from `migrations` where `migration` = '2020_09_22_015815_create_admin_extensions_table'");
+        //DB::select("delete from `migrations` where `migration` = '2020_11_01_083237_update_admin_menu_table'");
         DB::select("delete from `migrations` where `migration` = '2016_11_22_093148_create_test_tables'");
 
         Artisan::call('migrate:rollback');

+ 2 - 2
tests/Feature/InstallTest.php

@@ -32,7 +32,7 @@ class InstallTest extends TestCase
         $this->assertFileExists(public_path(Admin::asset()->getRealPath('@admin')));
         $this->assertFileExists(database_path('migrations/2016_01_04_173148_create_admin_tables.php'));
         $this->assertFileExists(resource_path('lang/en/admin.php'));
-        $this->assertFileExists(resource_path('lang/zh-CN/admin.php'));
-        $this->assertFileExists(resource_path('lang/zh-CN/global.php'));
+        $this->assertFileExists(resource_path('lang/zh_CN/admin.php'));
+        $this->assertFileExists(resource_path('lang/zh_CN/global.php'));
     }
 }

+ 29 - 89
tests/resources/config/admin.php

@@ -22,7 +22,7 @@ return [
     | `img` tag, eg '<img src="http://logo-url" alt="Admin logo">'.
     |
     */
-    'logo' => '<span>Dcat</span> Admin',
+    'logo' => '<img src="/vendor/dcat-admin/images/logo.png" width="35"> &nbsp;Dcat Admin',
 
     /*
     |--------------------------------------------------------------------------
@@ -34,7 +34,17 @@ return [
     | '<img src="http://logo-url" alt="Admin logo">'.
     |
     */
-    'logo-mini' => 'Da',
+    'logo-mini' => '<img src="/vendor/dcat-admin/images/logo.png">',
+
+    /*
+     |--------------------------------------------------------------------------
+     | User default avatar
+     |--------------------------------------------------------------------------
+     |
+     | Set a default avatar for newly created users.
+     |
+     */
+    'default_avatar' => '@admin/images/default-avatar.jpg',
 
     /*
     |--------------------------------------------------------------------------
@@ -85,14 +95,6 @@ return [
    */
     'assets_server' => env('ADMIN_ASSETS_SERVER'),
 
-    /*
-    |--------------------------------------------------------------------------
-    | Cdn setting
-    |--------------------------------------------------------------------------
-    |
-   */
-    'cdn' => env('ADMIN_CDN', false),
-
     /*
     |--------------------------------------------------------------------------
     | Access via `https`
@@ -117,7 +119,7 @@ return [
     'auth' => [
         'enable' => true,
 
-        'controller' => Dcat\Admin\Controllers\AuthController::class,
+        'controller' => App\Admin\Controllers\AuthController::class,
 
         'guard' => 'admin',
 
@@ -219,7 +221,7 @@ return [
     'upload' => [
 
         // Disk in `config/filesystem.php`.
-        'disk' => 'admin',
+        'disk' => 'public',
 
         // Image and file upload path under the disk above.
         'directory' => [
@@ -258,52 +260,15 @@ return [
         'menu_model' => Dcat\Admin\Models\Menu::class,
 
         // Pivot table for table above.
-        'operation_log_table'    => 'admin_operation_log',
-        'user_permissions_table' => 'admin_user_permissions',
         'role_users_table'       => 'admin_role_users',
         'role_permissions_table' => 'admin_role_permissions',
         'role_menu_table'        => 'admin_role_menu',
         'permission_menu_table'  => 'admin_permission_menu',
+        'settings_table'         => 'admin_settings',
+        'extensions_table'       => 'admin_extensions',
+        'extension_histories_table' => 'admin_extension_histories',
     ],
 
-    /*
-    |--------------------------------------------------------------------------
-    | User operation log setting
-    |--------------------------------------------------------------------------
-    |
-    | By setting this option to open or close operation log in dcat-admin.
-    |
-    */
-    'operation_log' => [
-
-        'enable' => true,
-
-        // Only logging allowed methods in the list
-        'allowed_methods' => ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'],
-
-        'secret_fields' => [
-            'password',
-            'password_confirmation',
-        ],
-
-        // Routes that will not log to database.
-        // All method to path like: auth/logs/*/edit
-        // or specific method to path like: get:auth/logs.
-        'except' => [
-            'auth/logs*',
-        ],
-    ],
-
-    /*
-    |--------------------------------------------------------------------------
-    | Admin map field provider
-    |--------------------------------------------------------------------------
-    |
-    | Supported: "tencent", "google", "yandex".
-    |
-    */
-    'map_provider' => 'google',
-
     /*
     |--------------------------------------------------------------------------
     | Application layout
@@ -312,42 +277,29 @@ return [
     | This value is the layout of admin pages.
     */
     'layout' => [
-        // vertical, horizontal
-        'mainLayout_type' => 'vertical',
+        // default, blue, blue-light, green
+        'color' => 'default',
 
         'body_class' => '',
 
         'sidebar_collapsed' => false,
 
-        'blank_page' => false,
+        // light, primary, dark
+        'sidebar_style' => 'light',
+
+        'dark_mode_switch' => false,
 
         // bg-primary, bg-info, bg-warning, bg-success, bg-danger, bg-dark
         'navbar_color' => '',
-
-        // floating, static, sticky, hidden
-        'vertical_menu_navbar_type' => 'floating',
-
-        // static, sticky, hidden
-        'footer_type' => 'static',
     ],
 
-    /*
-    |--------------------------------------------------------------------------
-    | Login page background image
-    |--------------------------------------------------------------------------
-    |
-    | This value is used to set the background image of login page.
-    |
-    */
-    'login_background_image' => '',
-
     /*
     |--------------------------------------------------------------------------
     | The exception handler class
     |--------------------------------------------------------------------------
     |
     */
-    'exception_handler' => \Dcat\Admin\Exception\Handler::class,
+    'exception_handler' => Dcat\Admin\Exception\Handler::class,
 
     /*
     |--------------------------------------------------------------------------
@@ -360,24 +312,12 @@ return [
 
     /*
     |--------------------------------------------------------------------------
-    | Extension Directory
-    |--------------------------------------------------------------------------
-    |
-    | When you use command `php artisan admin:extend` to generate extensions,
-    | the extension files will be generated in this directory.
-    */
-    'extension_dir' => app_path('Admin/Extensions'),
-
-    /*
-    |--------------------------------------------------------------------------
-    | Settings for extensions.
+    | Extension
     |--------------------------------------------------------------------------
-    |
-    | You can find all available extensions here
-    | https://github.com/dcat-admin-extensions.
-    |
     */
-    'extensions' => [
-
+    'extension' => [
+        // When you use command `php artisan admin:ext-make` to generate extensions,
+        // the extension files will be generated in this directory.
+        'dir' => base_path('dcat-admin-extensions'),
     ],
 ];