Merge pull request #3 from jitendra-webkul/jitendra

Jitendra
This commit is contained in:
JItendra Singh 2018-07-11 11:19:50 +05:30 committed by GitHub
commit a20c5daaab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
125 changed files with 5446 additions and 2937 deletions

8
Laracel Command Normal file
View File

@ -0,0 +1,8 @@
php artisan make:controller UserController && mv app/Http/Controllers/UserController.php packages/Webkul/User/src/Ht
tp/Controllers
php artisan make:migration foo --path=packages/Webkul/User/src/Database/migrations
php artisan db:seed --class=Webkul\\User\\Database\\Seeders\\DatabaseSeeder
php artisan route:cache

View File

@ -6,10 +6,12 @@
"type": "project",
"require": {
"php": "^7.1.3",
"dimsav/laravel-translatable": "^9.0",
"fideloper/proxy": "^4.0",
"laravel/framework": "5.6.*",
"laravel/tinker": "^1.0",
"nwidart/laravel-modules": "^3.2"
"nwidart/laravel-modules": "^3.2",
"propaganistas/laravel-intl": "^2.0"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.1",
@ -22,7 +24,9 @@
"replace": {
"webkul/laravel-user": "self.version",
"webkul/laravel-admin": "self.version",
"webkul/laravel-ui": "self.version"
"webkul/laravel-ui": "self.version",
"webkul/laravel-core": "self.version",
"webkul/laravel-attribute": "self.version"
},
"autoload": {
"classmap": [
@ -33,7 +37,9 @@
"App\\": "app/",
"Webkul\\User\\": "packages/Webkul/User/src",
"Webkul\\Admin\\": "packages/Webkul/Admin/src",
"Webkul\\Ui\\": "packages/Webkul/Ui/src"
"Webkul\\Ui\\": "packages/Webkul/Ui/src",
"Webkul\\Attribute\\": "packages/Webkul/Attribute/src",
"Webkul\\Core\\": "packages/Webkul/Core/src"
}
},
"autoload-dev": {

375
composer.lock generated
View File

@ -4,8 +4,107 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5d86c298bb279ec35bcbbd1dfb204831",
"content-hash": "1cfe5a0cb070df958cccb486627d42f2",
"packages": [
{
"name": "commerceguys/intl",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/commerceguys/intl.git",
"reference": "22156e447530d6ebd387bfee51ef1ae2c70a5ff0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/commerceguys/intl/zipball/22156e447530d6ebd387bfee51ef1ae2c70a5ff0",
"reference": "22156e447530d6ebd387bfee51ef1ae2c70a5ff0",
"shasum": ""
},
"require": {
"php": ">=5.5.0"
},
"require-dev": {
"mikey179/vfsstream": "1.*",
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"CommerceGuys\\Intl\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Bojan Zivanovic"
}
],
"description": "Internationalization library powered by CLDR data.",
"time": "2018-06-21T14:03:04+00:00"
},
{
"name": "dimsav/laravel-translatable",
"version": "v9.0",
"source": {
"type": "git",
"url": "https://github.com/dimsav/laravel-translatable.git",
"reference": "a174b327342e882df7df9d971cf36ae678c16088"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dimsav/laravel-translatable/zipball/a174b327342e882df7df9d971cf36ae678c16088",
"reference": "a174b327342e882df7df9d971cf36ae678c16088",
"shasum": ""
},
"require": {
"illuminate/support": "5.6.*",
"php": ">=5.4.0"
},
"require-dev": {
"orchestra/testbench": "3.6.*",
"phpunit/phpunit": "~7.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Dimsav\\Translatable\\TranslatableServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Dimsav\\Translatable\\": "src/Translatable/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dimitrios Savvopoulos",
"email": "ds@dimsav.com",
"homepage": "http://dimsav.com"
}
],
"description": "A Laravel package for multilingual models",
"keywords": [
"database",
"language",
"laravel",
"translation"
],
"time": "2018-02-10T14:10:41+00:00"
},
{
"name": "dnoegel/php-xdg-base-dir",
"version": "0.1",
@ -453,6 +552,71 @@
],
"time": "2015-04-20T18:58:01+00:00"
},
{
"name": "jenssegers/date",
"version": "v3.4.0",
"source": {
"type": "git",
"url": "https://github.com/jenssegers/date.git",
"reference": "3f5f94f28bd5108fab011869434209101d4189ae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jenssegers/date/zipball/3f5f94f28bd5108fab011869434209101d4189ae",
"reference": "3f5f94f28bd5108fab011869434209101d4189ae",
"shasum": ""
},
"require": {
"nesbot/carbon": "^1.0",
"php": ">=5.6",
"symfony/translation": "^2.7|^3.0|^4.0"
},
"require-dev": {
"phpunit/phpunit": "^5.0|^6.0|^7.0",
"satooshi/php-coveralls": "^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
},
"laravel": {
"providers": [
"Jenssegers\\Date\\DateServiceProvider"
],
"aliases": {
"Date": "Jenssegers\\Date\\Date"
}
}
},
"autoload": {
"psr-4": {
"Jenssegers\\Date\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jens Segers",
"homepage": "https://jenssegers.com"
}
],
"description": "A date library to help you work with dates in different languages",
"homepage": "https://github.com/jenssegers/date",
"keywords": [
"carbon",
"date",
"datetime",
"i18n",
"laravel",
"time",
"translation"
],
"time": "2018-05-16T11:53:55+00:00"
},
{
"name": "laravel/framework",
"version": "v5.6.24",
@ -1040,6 +1204,69 @@
],
"time": "2018-06-08T15:26:40+00:00"
},
{
"name": "propaganistas/laravel-intl",
"version": "2.0.3",
"source": {
"type": "git",
"url": "https://github.com/Propaganistas/Laravel-Intl.git",
"reference": "645a34430ae92d287e97a06815d613be1f3002b5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Propaganistas/Laravel-Intl/zipball/645a34430ae92d287e97a06815d613be1f3002b5",
"reference": "645a34430ae92d287e97a06815d613be1f3002b5",
"shasum": ""
},
"require": {
"commerceguys/intl": "^1.0.1",
"illuminate/support": ">=5.1,<5.7",
"jenssegers/date": "^3.2.3",
"php": ">=7.0",
"punic/punic": "^3.1",
"umpirsky/country-list": "^2.0",
"umpirsky/locale-list": "^1.0"
},
"require-dev": {
"orchestra/testbench": ">=3.1",
"phpunit/phpunit": "^5.0|^6.0|^7.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Propaganistas\\LaravelIntl\\IntlServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Propaganistas\\LaravelIntl\\": "src/"
},
"files": [
"src/helpers.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Propaganistas",
"email": "Propaganistas@users.noreply.github.com"
}
],
"description": "Easy to use internationalization functions for Laravel",
"keywords": [
"i18n",
"internationalization",
"intl",
"l10n",
"laravel"
],
"time": "2018-07-03T07:55:17+00:00"
},
{
"name": "psr/container",
"version": "1.0.0",
@ -1256,6 +1483,75 @@
],
"time": "2018-06-10T17:57:20+00:00"
},
{
"name": "punic/punic",
"version": "3.1.0",
"source": {
"type": "git",
"url": "https://github.com/punic/punic.git",
"reference": "bd49ff54ea6ee8a902a567905664ecc7840037d6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/punic/punic/zipball/bd49ff54ea6ee8a902a567905664ecc7840037d6",
"reference": "bd49ff54ea6ee8a902a567905664ecc7840037d6",
"shasum": ""
},
"require": {
"php": ">=5.3"
},
"replace": {
"punic/calendar": "*",
"punic/common": "*"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "2.2.*",
"phpunit/phpunit": "^4"
},
"bin": [
"bin/punic-data"
],
"type": "library",
"autoload": {
"psr-4": {
"Punic\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michele Locati",
"email": "mlocati@gmail.com",
"role": "Developer"
},
{
"name": "Remo Laubacher",
"email": "remo.laubacher@gmail.com",
"role": "Collaborator, motivator and perfectionist supporter"
}
],
"description": "PHP-Unicode CLDR",
"homepage": "https://github.com/punic/punic",
"keywords": [
"calendar",
"cldr",
"date",
"date-time",
"i18n",
"internationalization",
"l10n",
"localization",
"php",
"time",
"translate",
"translations",
"unicode"
],
"time": "2018-02-09T15:54:34+00:00"
},
{
"name": "ramsey/uuid",
"version": "3.7.3",
@ -2308,6 +2604,83 @@
"homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
"time": "2017-11-27T11:13:29+00:00"
},
{
"name": "umpirsky/country-list",
"version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/umpirsky/country-list.git",
"reference": "ddabf3a8ef2956fc0fbd22da9bec642ab6cfdede"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/umpirsky/country-list/zipball/ddabf3a8ef2956fc0fbd22da9bec642ab6cfdede",
"reference": "ddabf3a8ef2956fc0fbd22da9bec642ab6cfdede",
"shasum": ""
},
"require": {
"php": "^7.0"
},
"require-dev": {
"slowprog/composer-copy-file": "^0.2",
"symfony/locale": "^2.7|^3.0",
"umpirsky/list-generator": "^1.2"
},
"type": "library",
"extra": {
"copy-file": {
"vendor/umpirsky/list-generator/Dockerfile": "./",
"vendor/umpirsky/list-generator/docker-compose.yml": "./"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Saša Stamenković",
"email": "umpirsky@gmail.com"
}
],
"description": "List of all countries with names and ISO 3166-1 codes in all languages and data formats.",
"time": "2018-02-27T18:55:19+00:00"
},
{
"name": "umpirsky/locale-list",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/umpirsky/locale-list.git",
"reference": "8141f749e16e568a5a9f7e813c50f72efa794c2e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/umpirsky/locale-list/zipball/8141f749e16e568a5a9f7e813c50f72efa794c2e",
"reference": "8141f749e16e568a5a9f7e813c50f72efa794c2e",
"shasum": ""
},
"require": {
"php": ">=5.4"
},
"require-dev": {
"symfony/locale": "^2.7|^3.0",
"umpirsky/list-generator": "^1.1"
},
"type": "library",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Saša Stamenković",
"email": "umpirsky@gmail.com"
}
],
"description": "List of all locales with names and codes in all languages and all data formats.",
"time": "2018-06-01T17:50:07+00:00"
},
{
"name": "vlucas/phpdotenv",
"version": "v2.4.0",

View File

@ -13,7 +13,7 @@ return [
|
*/
'name' => env('APP_NAME', 'Laravel'),
'name' => env('APP_NAME', 'Bagisto'),
/*
|--------------------------------------------------------------------------
@ -151,6 +151,9 @@ return [
* Package Service Providers...
*/
Dimsav\Translatable\TranslatableServiceProvider::class,
Propaganistas\LaravelIntl\IntlServiceProvider::class,
/*
* Application Service Providers...
*/
@ -163,7 +166,9 @@ return [
Webkul\User\Providers\UserServiceProvider::class,
Webkul\Admin\Providers\AdminServiceProvider::class,
Webkul\Ui\Providers\UiServiceProvider::class
Webkul\Ui\Providers\UiServiceProvider::class,
Webkul\Attribute\Providers\AttributeServiceProvider::class,
Webkul\Core\Providers\CoreServiceProvider::class
],
/*

View File

@ -9,7 +9,8 @@
],
"require": {
"webkul/laravel-user": "dev-master",
"webkul/laravel-ui": "dev-master"
"webkul/laravel-ui": "dev-master",
"webkul/laravel-core": "dev-master"
},
"autoload": {
"psr-4": {

View File

@ -18,6 +18,6 @@
"vue": "^2.1.10"
},
"dependencies": {
"vee-validate": "^2.1.0-beta.3"
"vee-validate": "2.0.0-rc.26"
}
}

View File

@ -33,5 +33,13 @@ return [
'driver' => 'eloquent',
'model' => Webkul\User\Models\Admin::class,
]
]
],
'passwords' => [
'admins' => [
'provider' => 'admins',
'table' => 'admin_password_resets',
'expire' => 60,
],
],
];

View File

@ -3,30 +3,70 @@
Route::group(['middleware' => ['web']], function () {
Route::prefix('admin')->group(function () {
Route::get('/login', 'Webkul\User\Http\Controllers\SeesionController@create')->defaults('_config', [
'view' => 'admin::sessions.create'
// Login Routes
Route::get('/login', 'Webkul\User\Http\Controllers\SessionController@create')->defaults('_config', [
'view' => 'admin::users.sessions.create'
])->name('admin.session.create');
Route::post('/login', 'Webkul\User\Http\Controllers\SeesionController@store')->defaults('_config', [
'redirect' => 'admin/dashboard'
])->name('admin.session.store');
Route::post('/login', 'Webkul\User\Http\Controllers\SessionController@store')->defaults('_config', [
'redirect' => 'admin.dashboard.index'
])->name('admin.forget-password.store');
// Forget Password Routes
Route::get('/forget-password', 'Webkul\User\Http\Controllers\ForgetPasswordController@create')->defaults('_config', [
'view' => 'admin::users.forget-password.create'
])->name('admin.forget-password.create');
Route::post('/forget-password', 'Webkul\User\Http\Controllers\ForgetPasswordController@store')->name('admin.forget-password.store');
// Reset Password Routes
Route::get('/reset-password/{token}', 'Webkul\User\Http\Controllers\ResetPasswordController@create')->defaults('_config', [
'view' => 'admin::users.reset-password.create'
])->name('admin.reset-password.create');
Route::post('/reset-password', 'Webkul\User\Http\Controllers\ResetPasswordController@store')->defaults('_config', [
'redirect' => 'admin.dashboard.index'
])->name('admin.reset-password.store');
// Admin Routes
Route::group(['middleware' => ['admin']], function () {
Route::get('/logout', 'Webkul\User\Http\Controllers\SeesionController@destroy')->defaults('_config', [
'redirect' => 'admin/login'
Route::get('/logout', 'Webkul\User\Http\Controllers\SessionController@destroy')->defaults('_config', [
'redirect' => 'admin.session.create'
])->name('admin.session.destroy');
// Dashboard Route
Route::get('/dashboard', 'Webkul\Admin\Http\Controllers\DashboardController@index')->name('admin.dashboard.index');
// Catalog Routes
Route::prefix('catalog')->group(function () {
Route::get('/attributes', 'Webkul\Attribute\Http\Controllers\AttributeController@index')->defaults('_config', [
'view' => 'admin::catalog.attributes.index'
])->name('admin.catalog.attributes.index');
Route::get('/attributes/create', 'Webkul\Attribute\Http\Controllers\AttributeController@create')->defaults('_config', [
'view' => 'admin::catalog.attributes.create'
])->name('admin.catalog.attributes.create');
Route::post('/attributes/create', 'Webkul\Attribute\Http\Controllers\AttributeController@store')->defaults('_config', [
'redirect' => 'admin.catalog.attributes.index'
])->name('admin.catalog.attributes.store');
});
// Datagrid Routes
Route::get('/datagrid', 'Webkul\Admin\Http\Controllers\DataGridController@index')->name('admin.datagrid.index');
// User Routes
Route::get('/users', 'Webkul\User\Http\Controllers\UserController@index')->defaults('_config', [
'view' => 'admin::users.index'
'view' => 'admin::users.users.index'
])->name('admin.users.index');
Route::get('/users/create', 'Webkul\User\Http\Controllers\UserController@create')->defaults('_config', [
'view' => 'admin::users.create'
'view' => 'admin::users.users.create'
])->name('admin.users.create');
Route::post('/users/create', 'Webkul\User\Http\Controllers\UserController@store')->defaults('_config', [
@ -34,20 +74,21 @@ Route::group(['middleware' => ['web']], function () {
])->name('admin.users.store');
Route::get('/users/edit/{id}', 'Webkul\User\Http\Controllers\UserController@edit')->defaults('_config', [
'view' => 'admin::users.edit'
'view' => 'admin::users.users.edit'
])->name('admin.users.edit');
Route::put('/users/edit/{id}', 'Webkul\User\Http\Controllers\UserController@update')->defaults('_config', [
'redirect' => 'admin.users.index'
])->name('admin.users.update');
// User Role Routes
Route::get('/roles', 'Webkul\User\Http\Controllers\RoleController@index')->defaults('_config', [
'view' => 'admin::roles.index'
'view' => 'admin::users.roles.index'
])->name('admin.roles.index');
Route::get('/roles/create', 'Webkul\User\Http\Controllers\RoleController@create')->defaults('_config', [
'view' => 'admin::roles.create'
'view' => 'admin::users.roles.create'
])->name('admin.roles.create');
Route::post('/roles/create', 'Webkul\User\Http\Controllers\RoleController@store')->defaults('_config', [
@ -55,7 +96,7 @@ Route::group(['middleware' => ['web']], function () {
])->name('admin.roles.store');
Route::get('/roles/edit/{id}', 'Webkul\User\Http\Controllers\RoleController@edit')->defaults('_config', [
'view' => 'admin::roles.edit'
'view' => 'admin::users.roles.edit'
])->name('admin.roles.edit');
Route::put('/roles/edit/{id}', 'Webkul\User\Http\Controllers\RoleController@update')->defaults('_config', [
@ -63,6 +104,20 @@ Route::group(['middleware' => ['web']], function () {
])->name('admin.roles.update');
// Locale Routes
Route::get('/locales', 'Webkul\Core\Http\Controllers\LocaleController@index')->defaults('_config', [
'view' => 'admin::locales.index'
])->name('admin.locales.index');
Route::get('/locales/create', 'Webkul\Core\Http\Controllers\LocaleController@create')->defaults('_config', [
'view' => 'admin::locales.create'
])->name('admin.locales.create');
Route::post('/locales/create', 'Webkul\Core\Http\Controllers\LocaleController@store')->defaults('_config', [
'redirect' => 'admin.locales.index'
])->name('admin.locales.store');
// Admin Profile route
Route::get('/account', 'Webkul\User\Http\Controllers\AccountController@edit')->defaults('_config', [
'view' => 'admin::account.edit'

View File

@ -5,7 +5,7 @@ namespace Webkul\Admin\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Blade;
use Webkul\Ui\Menu;
use Webkul\Admin\Providers\EventServiceProvider;
class AdminServiceProvider extends ServiceProvider
{
@ -18,50 +18,19 @@ class AdminServiceProvider extends ServiceProvider
{
include __DIR__ . '/../Http/routes.php';
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'admin');
$this->publishes([
__DIR__ . '/../../publishable/assets' => public_path('vendor/webkul/admin/assets'),
], 'public');
$this->loadMigrationsFrom(__DIR__ . '/../Database/migrations');
$this->loadViewsFrom(__DIR__ . '/../Resources/views', 'admin');
$this->createAdminMenu();
$this->composeView();
Blade::directive('continue', function() { return "<?php continue; ?>"; });
}
/**
* This method fires an event for menu creation, any package can add their menu item by listening to the admin.menu.build event
*
* @return void
*/
public function createAdminMenu()
{
Event::listen('admin.menu.create', function() {
return Menu::create(function($menu) {
Event::fire('admin.menu.build', $menu);
});
});
Event::listen('admin.menu.build', function($menu) {
$menu->add('dashboard', 'Dashboard', route('admin.dashboard.index'), 1, 'icon-dashboard');
$menu->add('configuration', 'Configure', route('admin.account.edit'), 6, 'icon-configuration');
$menu->add('configuration.account', 'My Account', route('admin.account.edit'), 1, '');
$menu->add('settings', 'Settings', route('admin.users.index'), 6, 'icon-settings');
$menu->add('settings.users', 'Users', route('admin.users.index'), 1, '');
$menu->add('settings.users.users', 'Users', route('admin.users.index'), 1, '');
$menu->add('settings.users.roles', 'Roles', route('admin.roles.index'), 1, '');
});
$this->app->register(EventServiceProvider::class);
}
/**
@ -91,7 +60,7 @@ class AdminServiceProvider extends ServiceProvider
];
}
}
$view->with('menu', $menu)->with('subMenus', $subMenus)->with('tabs', $tabs);
});
}

View File

@ -0,0 +1,97 @@
<?php
namespace Webkul\Admin\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\View;
use Webkul\Ui\Menu;
class EventServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
$this->createAdminMenu();
$this->buildACL();
$this->registerACL();
}
/**
* This method fires an event for menu creation, any package can add their menu item by listening to the admin.menu.build event
*
* @return void
*/
public function createAdminMenu()
{
Event::listen('admin.menu.create', function() {
return Menu::create(function($menu) {
Event::fire('admin.menu.build', $menu);
});
});
Event::listen('admin.menu.build', function($menu) {
$menu->add('dashboard', 'Dashboard', 'admin.dashboard.index', 1, 'dashboard-icon');
$menu->add('catalog', 'Catalog', 'admin.catalog.attributes.index', 3, 'catalog-icon');
$menu->add('catalog.attributes', 'Attributes', 'admin.catalog.attributes.index', 3);
$menu->add('configuration', 'Configure', 'admin.account.edit', 6, 'configuration-icon');
$menu->add('configuration.account', 'My Account', 'admin.account.edit', 1);
$menu->add('settings', 'Settings', 'admin.users.index', 6, 'settings-icon');
$menu->add('settings.users', 'Users', 'admin.users.index', 1, '');
$menu->add('settings.users.users', 'Users', 'admin.users.index', 1, '');
$menu->add('settings.users.roles', 'Roles', 'admin.roles.index', 2, '');
$menu->add('settings.locales', 'Locales', 'admin.locales.index', 2, '');
});
}
/**
* Build route based ACL
*
* @return voidbuildACL
*/
public function buildACL()
{
Event::listen('admin.acl.build', function($acl) {
$acl->add('dashboard', 'Dashboard', 'admin.dashboard.index', 1);
$acl->add('configuration', 'Configure', 'admin.account.edit', 5);
$acl->add('settings', 'Settings', 'admin.users.index', 6);
$acl->add('settings.users', 'Users', 'admin.users.index', 1);
$acl->add('settings.users.users', 'Users', 'admin.users.index', 1);
$acl->add('settings.users.roles', 'Roles', 'admin.roles.index', 2);
});
}
/**
* Registers acl to entire application
*
* @return void
*/
public function registerACL()
{
$this->app->singleton('acl', function() {
return current(Event::fire('admin.acl.create'));
});
View::share('acl', app('acl'));
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -28,7 +28,7 @@
<div class="accordian-content">
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="name">{{ __('Name') }}</label>
<input type="text" v-validate="'required'" class="control" id="email" name="name" value="{{ $user->name }}"/>
<input type="text" v-validate="'required'" class="control" id="name" name="name" value="{{ $user->name }}"/>
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
@ -44,13 +44,13 @@
<div class="accordian-content">
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
<label for="password">{{ __('Password') }}</label>
<input type="password" v-validate="'min:6|max:18'" class="control" id="password" name="password"/>
<input type="password" v-validate="'min:6'" class="control" id="password" name="password"/>
<span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span>
</div>
<div class="control-group" :class="[errors.has('password_confirmation') ? 'has-error' : '']">
<label for="password_confirmation">{{ __('Confirm Password') }}</label>
<input type="password" v-validate="'min:6|max:18|confirmed:password'" class="control" id="password_confirmation" name="password_confirmation"/>
<input type="password" v-validate="'min:6|confirmed:password'" class="control" id="password_confirmation" name="password_confirmation"/>
<span class="control-error" v-if="errors.has('password_confirmation')">@{{ errors.first('password_confirmation') }}</span>
</div>
</div>

View File

@ -0,0 +1,85 @@
@extends('admin::layouts.content')
@section('content')
<div class="content">
<form method="POST" action="{{ route('admin.catalog.attributes.store') }}">
<div class="page-header">
<div class="page-title">
<h1>{{ __('Add Attribute') }}</h1>
</div>
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('Save Attribute') }}
</button>
</div>
</div>
<div class="page-content">
<div class="form-container">
@csrf()
<accordian :title="'{{ __('General') }}'" :active="true">
<div class="accordian-content">
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
<label for="code">{{ __('Attribute Code') }}</label>
<input type="text" v-validate="'required'" class="control" id="code" name="code" value="{{ old('code') }}"/>
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
</div>
<div class="control-group">
<label for="type">{{ __('Attribute Type') }}</label>
<select class="control" id="type" name="type">
<option value="text">{{ __('Text') }}</option>
<option value="textarea">{{ __('Textarea') }}</option>
<option value="integer">{{ __('Integer') }}</option>
<option value="select">{{ __('Select') }}</option>
<option value="multiselect">{{ __('Multiselect') }}</option>
<option value="checkbox">{{ __('Multiselect') }}</option>
<option value="datetime">{{ __('Datetime') }}</option>
<option value="date">{{ __('Date') }}</option>
</select>
</div>
</div>
</accordian>
<accordian :title="'{{ __('Label') }}'" :active="true">
<div class="accordian-content">
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="name">{{ __('Admin') }}</label>
<input type="text" v-validate="'required'" class="control" id="name" name="name"/>
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
@foreach(Webkul\Core\Models\Locale::all() as $locale)
<div class="control-group">
<label for="locale-{{ $locale->code }}">{{ $locale->name . ' (' . $locale->code . ')' }}</label>
<input type="text" class="control" id="locale-{{ $locale->code }}" name="<?php echo $locale->code; ?>[name]"/>
</div>
@endforeach
</div>
</accordian>
<accordian :title="'{{ __('Options') }}'" :active="true" :class-name="'hide'" :id="'options'">
</accordian>
<accordian :title="'{{ __('Validations') }}'" :active="true">
</accordian>
<accordian :title="'{{ __('Configuration') }}'" :active="true">
</accordian>
</div>
</div>
</form>
</div>
@stop
@section('javascript')
@stop

View File

@ -0,0 +1,21 @@
@extends('admin::layouts.content')
@section('content')
<div class="content">
<div class="page-header">
<div class="page-title">
Attributes
</div>
<div class="page-action">
<a href="{{ route('admin.catalog.attributes.create') }}" class="btn btn-lg btn-primary">
{{ __('Add Attribute') }}
</a>
</div>
</div>
<div class="page-content">
</div>
</div>
@stop

View File

@ -0,0 +1,115 @@
<!DOCTYPE html>
<html lang="{{ config('app.locale') }}">
<head>
<title>@yield('page_title')</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="stylesheet" href="{{ asset('vendor/webkul/admin/assets/css/admin.css') }}">
<link rel="stylesheet" href="{{ asset('vendor/webkul/ui/assets/css/ui.css') }}">
<style>
.container {
text-align: center;
position: absolute;
width: 100%;
height: 100%;
display: table;
z-index: 1;
background: #F8F9FA;
}
.center-box {
display: table-cell;
vertical-align: middle;
}
.adjacent-center {
width: 365px;
display: inline-block;
text-align: left;
}
.form-container .control-group .control {
width: 100%;
}
h1 {
font-size: 24px;
font-weight: 600;
margin-bottom: 30px;
}
.brand-logo {
margin-bottom: 30px;
text-align: center;
}
.footer {
margin-top: 40px;
padding: 0 20px;
}
.footer p {
font-size: 14px;
color: #8E8E8E;
text-align: center;
}
.btn.btn-primary {
width: 100%;
}
</style>
@yield('css')
</head>
<body>
<div id="app" class="container">
<flash-wrapper ref='flashes'></flash-wrapper>
<div class="center-box">
<div class="adjacent-center">
<div class="brand-logo">
<img src="{{ asset('vendor/webkul/admin/assets/images/logo.png') }}" alt="Bagisto"/>
</div>
@yield('content')
<div class="footer">
<p>
© Copyright 2018 Webkul Software, All rights reserved.
</p>
</div>
</div>
</div>
</div>
<script type="text/javascript">
window.flashMessages = [];
@if($success = session('success'))
window.flashMessages = [{'type': 'alert-success', 'message': "{{ $success }}" }];
@elseif($warning = session('warning'))
window.flashMessages = [{'type': 'alert-warning', 'message': "{{ $warning }}" }];
@elseif($error = session('error'))
window.flashMessages = [{'type': 'alert-error', 'message': "{{ $error }}" }];
@endif
window.serverErrors = [];
@if (count($errors))
window.serverErrors = @json($errors->getMessages());
@endif
</script>
<script type="text/javascript" src="{{ asset('vendor/webkul/admin/assets/js/admin.js') }}"></script>
<script type="text/javascript" src="{{ asset('vendor/webkul/ui/assets/js/ui.js') }}"></script>
@yield('javascript')
</body>
</html>

View File

@ -0,0 +1,43 @@
@extends('admin::layouts.content')
@section('content')
<div class="content">
<form method="POST" action="{{ route('admin.locales.store') }}" @submit.prevent="onSubmit">
<div class="page-header">
<div class="page-title">
<h1>{{ __('Add Locale') }}</h1>
</div>
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('Save Locale') }}
</button>
</div>
</div>
<div class="page-content">
<div class="form-container">
@csrf()
<accordian :title="'{{ __('General') }}'" :active="true">
<div class="accordian-content">
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
<label for="code">{{ __('Code') }}</label>
<input v-validate="'required'" class="control" id="code" name="code"/>
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
</div>
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="name">{{ __('Name') }}</label>
<input v-validate="'required'" class="control" id="name" name="name"/>
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
</div>
</accordian>
</div>
</div>
</form>
</div>
@stop

View File

@ -0,0 +1,21 @@
@extends('admin::layouts.content')
@section('content')
<div class="content">
<div class="page-header">
<div class="page-title">
</div>
<div class="page-action">
<a href="{{ route('admin.locales.create') }}" class="btn btn-lg btn-primary">
{{ __('Add Locale') }}
</a>
</div>
</div>
<div class="page-content">
</div>
</div>
@stop

View File

@ -1,47 +0,0 @@
<!DOCTYPE html>
<html lang="{{ config('app.locale') }}">
<head>
<title>@yield('page_title')</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="stylesheet" href="{{ asset('vendor/webkul/admin/assets/css/admin.css') }}">
</head>
<body>
<div class="container">
<form method="POST" action="login">
@csrf
<div class="element-block">
<label for="email" class="field-label"></label>
<div class="field-block">
<input type="text" class="field" id="email" name="email"/>
</div>
</div>
<div class="element-block">
<label for="password" class="field-label"></label>
<div class="field-block">
<input type="password" class="field" id="password" name="password"/>
</div>
</div>
@if (count($errors))
@foreach ($errors->all() as $error)
{{ $error }}
@endforeach
@endif
<div class="button-block">
<button type="submit" class="button">Login</button>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,55 @@
@extends('admin::layouts.anonymous-master')
@section('page_title')
{{ __('Forget Password') }}
@stop
@section('css')
<style>
.button-group {
margin-bottom: 25px;
}
.primary-back-icon {
vertical-align: middle;
}
</style>
@stop
@section('content')
<div class="panel">
<div class="panel-content">
<div class="form-container" style="text-align: left">
<h1>{{ __('Recover Password') }}</h1>
<form method="POST" action="{{ route('admin.forget-password.store') }}" @submit.prevent="onSubmit">
@csrf
<div class="control-group" :class="[errors.has('email') ? 'has-error' : '']">
<label for="email">{{ __('Registered Email') }}</label>
<input type="text" v-validate="'required'" class="control" id="email" name="email" value="{{ old('email') }}"/>
<span class="control-error" v-if="errors.has('email')">@{{ errors.first('email') }}</span>
</div>
<div class="button-group">
<button class="btn btn-xl btn-primary">{{ __('Email Password Reset Link') }}</button>
</div>
<div class="control-group" style="margin-bottom: 0">
<a href="{{ route('admin.session.create') }}">
<i class="icon primary-back-icon"></i>
{{ __('Back to Sign In') }}
</a>
</div>
</form>
</div>
</div>
</div>
@stop

View File

@ -0,0 +1,69 @@
@extends('admin::layouts.anonymous-master')
@section('page_title')
{{ __('Reset Password') }}
@stop
@section('css')
<style>
.button-group {
margin-bottom: 25px;
}
.primary-back-icon {
vertical-align: middle;
}
</style>
@stop
@section('content')
<div class="panel">
<div class="panel-content">
<div class="form-container" style="text-align: left">
<h1>{{ __('Reset Password') }}</h1>
<form method="POST" action="{{ route('admin.reset-password.store') }}" @submit.prevent="onSubmit">
@csrf
<input type="hidden" name="token" value="{{ $token }}">
<div class="control-group" :class="[errors.has('email') ? 'has-error' : '']">
<label for="email">{{ __('Email') }}</label>
<input type="text" v-validate="'required|email'" class="control" id="email" name="email" value="{{ old('email') }}"/>
<span class="control-error" v-if="errors.has('email')">@{{ errors.first('email') }}</span>
</div>
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
<label for="password">{{ __('Password') }}</label>
<input type="password" v-validate="'required|min:6'" class="control" id="password" name="password"/>
<span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span>
</div>
<div class="control-group" :class="[errors.has('password_confirmation') ? 'has-error' : '']">
<label for="password_confirmation">{{ __('Confirm Password') }}</label>
<input type="password" v-validate="'required|min:6|confirmed:password'" class="control" id="password_confirmation" name="password_confirmation" data-vv-as="password"/>
<span class="control-error" v-if="errors.has('password_confirmation')">@{{ errors.first('password_confirmation') }}</span>
</div>
<div class="button-group">
<button type="submit" class="btn btn-xl btn-primary">{{ __('Reset Password') }}</button>
</div>
<div class="control-group" style="margin-bottom: 0">
<a href="{{ route('admin.session.create') }}">
<i class="icon primary-back-icon"></i>
{{ __('Back to Sign In') }}
</a>
</div>
</form>
</div>
</div>
</div>
@stop

View File

@ -2,6 +2,7 @@
@section('content')
<div class="content">
<form method="POST" action="{{ route('admin.roles.store') }}" @submit.prevent="onSubmit">
<div class="page-header">
<div class="page-title">
@ -45,12 +46,27 @@
</div>
<div class="control-group">
<tree-view/>
</div>
<tree-view value-field="key" id-field="key" items='@json($acl->items)'></tree-view>
</div>
</div>
</accordian>
</div>
</div>
</form>
</div>
@stop
@section('javascript')
<script>
$(document).ready(function () {
$('#permission_type').on('change', function(e) {
if($(e.target).val() == 'custom') {
$('.tree-container').removeClass('hide')
} else {
$('.tree-container').addClass('hide')
}
})
});
</script>
@stop

View File

@ -0,0 +1,74 @@
@extends('admin::layouts.content')
@section('content')
<div class="content">
<form method="POST" action="{{ route('admin.roles.update', $role->id) }}" @submit.prevent="onSubmit">
<div class="page-header">
<div class="page-title">
<h1>{{ __('Edit Role') }}</h1>
</div>
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('Save Role') }}
</button>
</div>
</div>
<div class="page-content">
<div class="form-container">
@csrf()
<input name="_method" type="hidden" value="PUT">
<accordian :title="'{{ __('General') }}'" :active="true">
<div class="accordian-content">
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="name">{{ __('Name') }}</label>
<input type="text" v-validate="'required'" class="control" id="email" name="name" value="{{ $role->name }}"/>
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
<div class="control-group">
<label for="description">{{ __('Description') }}</label>
<textarea class="control" id="description" name="description">{{ $role->description }}</textarea>
</div>
</div>
</accordian>
<accordian :title="'{{ __('Access Control') }}'" :active="true">
<div class="accordian-content">
<div class="control-group">
<label for="permission_type">{{ __('Permissions') }}</label>
<select class="control" name="permission_type" id="permission_type">
<option value="custom" {{ $role->permission_type == 'custom' ? 'selected' : '' }}>{{ __('Custom') }}</option>
<option value="all" {{ $role->permission_type == 'all' ? 'selected' : '' }}>{{ __('All') }}</option>
</select>
</div>
<div class="control-group tree-wrapper {{ $role->permission_type == 'all' ? 'hide' : '' }}">
<tree-view value-field="key" id-field="key" items='@json($acl->items)' value='@json($role->permissions)'></tree-view>
</div>
</div>
</accordian>
</div>
</div>
</form>
</div>
@stop
@section('javascript')
<script>
$(document).ready(function () {
$('#permission_type').on('change', function(e) {
if($(e.target).val() == 'custom') {
$('.tree-wrapper').removeClass('hide')
} else {
$('.tree-wrapper').addClass('hide')
}
})
});
</script>
@stop

View File

@ -0,0 +1,55 @@
@extends('admin::layouts.anonymous-master')
@section('page_title')
{{ __('Sign In') }}
@stop
@section('content')
<div class="panel">
<div class="panel-content">
<div class="form-container" style="text-align: left">
<h1>{{ __('Sign In') }}</h1>
<form method="POST" action="login" @submit.prevent="onSubmit">
@csrf
<div class="control-group" :class="[errors.has('email') ? 'has-error' : '']">
<label for="email">{{ __('Email') }}</label>
<input type="text" v-validate="'required'" class="control" id="email" name="email"/>
<span class="control-error" v-if="errors.has('email')">@{{ errors.first('email') }}</span>
</div>
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
<label for="password">{{ __('Password') }}</label>
<input type="password" v-validate="'required|min:6'" class="control" id="password" name="password"/>
<span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span>
</div>
<div class="control-group">
<a href="{{ route('admin.forget-password.create') }}">{{ __('Forget Password ?') }}</a>
</div>
<div class="control-group">
<span class="checkbox">
<input type="checkbox" id="remember" name="remember" value="1">
<label class="checkbox-view" for="remember"></label>
{{ __('Remember me') }}
</span>
</div>
<div class="button-group">
<button class="btn btn-xl btn-primary">{{ __('Sign In') }}</button>
</div>
</form>
</div>
</div>
</div>
@stop

View File

@ -5,6 +5,7 @@ require('laravel-mix-merge-manifest');
var publicPath = '../../../public/vendor/webkul/admin/assets';
mix.setPublicPath(publicPath).mergeManifest();
mix.disableNotifications();
mix.js(__dirname + '/src/Resources/assets/js/app.js', 'js/admin.js')
.copyDirectory( __dirname + '/src/Resources/assets/images', publicPath + '/images')

1
packages/Webkul/Attribute/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/node_modules

View File

@ -0,0 +1,27 @@
{
"name": "webkul/laravel-attribute",
"license": "MIT",
"authors": [
{
"name": "Jitendra Singh",
"email": "jitendra@webkul.com"
}
],
"require": {
"nwidart/laravel-modules": "^3.2"
},
"autoload": {
"psr-4": {
"Webkul\\Attribute\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Webkul\\Attribute\\Providers\\AttributeServiceProvider"
],
"aliases": { }
}
},
"minimum-stability": "dev"
}

View File

@ -0,0 +1,43 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAttributesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('attributes', function (Blueprint $table) {
$table->increments('id');
$table->string('code')->unique();
$table->string('name');
$table->string('type');
$table->string('validation')->nullable();
$table->integer('position')->nullable();
$table->boolean('is_required');
$table->boolean('is_unique');
$table->boolean('value_per_locale');
$table->boolean('value_per_channel');
$table->boolean('is_filterable');
$table->boolean('is_configurable');
$table->boolean('is_user_defined')->default(1);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('attributes');
}
}

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAttributeTranslationsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('attribute_translations', function (Blueprint $table) {
$table->increments('id');
$table->string('locale');
$table->text('name')->nullable();
$table->integer('attribute_id')->unsigned();
$table->unique(['attribute_id', 'locale']);
$table->foreign('attribute_id')->references('id')->on('attributes')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('attribute_translations');
}
}

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAttributeGroupsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('attribute_groups', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
$table->integer('sort_order');
$table->integer('attribute_family_id')->unsigned();
$table->unique(['attribute_family_id', 'name']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('attribute_groups');
}
}

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAttributeFamiliesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('attribute_families', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->boolean('status')->default(0);
});
Schema::table('attribute_groups', function($table) {
$table->foreign('attribute_family_id')->references('id')->on('attribute_families')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('attribute_families');
}
}

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAttributeOptionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('attribute_options', function (Blueprint $table) {
$table->increments('id');
$table->string('code');
$table->integer('sort_order');
$table->integer('attribute_id')->unsigned();
$table->unique(['attribute_id', 'code']);
$table->foreign('attribute_id')->references('id')->on('attributes')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('attribute_options');
}
}

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAttributeOptionTranslationsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('attribute_option_translations', function (Blueprint $table) {
$table->increments('id');
$table->string('locale');
$table->text('label')->nullable();
$table->integer('attribute_option_id')->unsigned();
$table->unique(['attribute_option_id', 'locale']);
$table->foreign('attribute_option_id')->references('id')->on('attribute_options')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('attribute_option_translations');
}
}

View File

@ -0,0 +1,119 @@
<?php
namespace Webkul\Attribute\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Webkul\Attribute\Models\Attribute;
/**
* Catalog attribute controller
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class AttributeController extends Controller
{
/**
* Contains route related configuration
*
* @var array
*/
protected $_config;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->_config = request('_config');
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return view($this->_config['view']);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view($this->_config['view'], compact('roleItems'));
}
/**
* Store a newly created resource in storage.
*
* @return \Illuminate\Http\Response
*/
public function store()
{
$this->validate(request(), [
'code' => ['required', 'unique:attributes,code', new \Webkul\Core\Contracts\Validations\Slug],
'name' => 'required',
'type' => 'required'
]);
Attribute::create(request()->all());
session()->flash('success', 'Attribute created successfully.');
return redirect()->route($this->_config['redirect']);
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$role = Role::findOrFail($id);
return view($this->_config['view'], compact('role'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$this->validate(request(), [
'name' => 'required',
'permission_type' => 'required',
]);
$role = Role::findOrFail($id);
$role->update(request()->all());
session()->flash('success', 'Role updated successfully.');
return redirect()->route($this->_config['redirect']);
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Webkul\Attribute\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

View File

@ -0,0 +1,13 @@
<?php
namespace Webkul\Attribute\Models;
use Illuminate\Database\Eloquent\Model;
use Dimsav\Translatable\Translatable;
class Attribute extends Model
{
use Translatable;
public $translatedAttributes = ['name'];
}

View File

@ -0,0 +1,9 @@
<?php
namespace Webkul\Attribute\Models;
use Illuminate\Database\Eloquent\Model;
class AttributeFamily extends Model
{
}

View File

@ -0,0 +1,9 @@
<?php
namespace Webkul\Attribute\Models;
use Illuminate\Database\Eloquent\Model;
class AttributeGroup extends Model
{
}

View File

@ -0,0 +1,13 @@
<?php
namespace Webkul\Attribute\Models;
use Illuminate\Database\Eloquent\Model;
use Dimsav\Translatable\Translatable;
class AttributeOption extends Model
{
use Translatable;
public $translatedAttributes = ['label'];
}

View File

@ -0,0 +1,12 @@
<?php
namespace Webkul\Attribute\Models;
use Illuminate\Database\Eloquent\Model;
class AttributeOptionTranslation extends Model
{
public $timestamps = false;
protected $fillable = ['label'];
}

View File

@ -0,0 +1,12 @@
<?php
namespace Webkul\Attribute\Models;
use Illuminate\Database\Eloquent\Model;
class AttributeTranslation extends Model
{
public $timestamps = false;
protected $fillable = ['name'];
}

View File

@ -0,0 +1,30 @@
<?php
namespace Webkul\Attribute\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Routing\Router;
class AttributeServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot(Router $router)
{
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
}
/**
* Register services.
*
* @return void
*/
public function register()
{
}
}

1
packages/Webkul/Category/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/node_modules

View File

@ -0,0 +1,25 @@
{
"name": "webkul/laravel-category",
"license": "MIT",
"authors": [
{
"name": "Jitendra Singh",
"email": "jitendra@webkul.com"
}
],
"require": {},
"autoload": {
"psr-4": {
"Webkul\\Attribute\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Webkul\\Attribute\\Providers\\AttributeServiceProvider"
],
"aliases": { }
}
},
"minimum-stability": "dev"
}

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCategoriesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('code')->unique();
$table->integer('position');
$table->integer('parent_id')->unsigned()->nullable();
$table->foreign('parent_id')->references('id')->on('categories')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('categories');
}
}

View File

@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class Foo extends Migration
class CreateCategoryNameTranslationTable extends Migration
{
/**
* Run the migrations.
@ -13,7 +13,10 @@ class Foo extends Migration
*/
public function up()
{
//
Schema::create('category_name_translation', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
/**
@ -23,6 +26,6 @@ class Foo extends Migration
*/
public function down()
{
//
Schema::dropIfExists('category_name_translation');
}
}

View File

@ -0,0 +1,31 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCategoryDescriptionTranslationsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('category_description_translations', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('category_description_translations');
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace Webkul\Category\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Routing\Router;
class CategoryServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot(Router $router)
{
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
}
/**
* Register services.
*
* @return void
*/
public function register()
{
}
}

1
packages/Webkul/Core/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/node_modules

View File

@ -0,0 +1,27 @@
{
"name": "webkul/laravel-core",
"license": "MIT",
"authors": [
{
"name": "Jitendra Singh",
"email": "jitendra@webkul.com"
}
],
"require": {
"propaganistas/laravel-intl": "^2.0"
},
"autoload": {
"psr-4": {
"Webkul\\Core\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Webkul\\Core\\Providers\\CoreServiceProvider"
],
"aliases": { }
}
},
"minimum-stability": "dev"
}

View File

@ -0,0 +1,27 @@
<?php
namespace Webkul\Core\Contracts;
/**
* Reposotory Interface
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
interface RepositoryInterface {
public function all($columns = ['*']);
public function paginate($perPage = 15, $columns = ['*']);
public function create(array $data);
public function update(array $data, $id);
public function delete($id);
public function find($id, $columns = ['*']);
public function findBy($field, $value, $columns = ['*']);
}

View File

@ -0,0 +1,30 @@
<?php
namespace Webkul\Core\Contracts\Validations;
use Illuminate\Contracts\Validation\Rule;
class Slug implements Rule
{
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return preg_match('/^[a-z0-9]+(?:-[a-z0-9]+)*$/', $value);
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return trans('core::validation.slug');
}
}

View File

@ -0,0 +1,33 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateLocalesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('locales', function (Blueprint $table) {
$table->increments('id');
$table->string('code')->unique();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('locales');
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace Webkul\Core\Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(LocalesTableSeeder::class);
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace Webkul\Core\Database\Seeders;
use Illuminate\Database\Seeder;
use Webkul\Core\Models\Locale;
class LocalesTableSeeder extends Seeder
{
public function run()
{
$locale = new Locale();
$locale->code = 'en';
$locale->name = 'English';
$locale->save();
}
}

View File

@ -0,0 +1,120 @@
<?php
namespace Webkul\Core\Eloquent;
use Webkul\Core\Contracts\RepositoryInterface;
use Webkul\Core\Exceptions\RepositoryException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Container\Container as App;
/**
* Reposotory
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
abstract class Repository implements RepositoryInterface {
/**
* @var App
*/
private $app;
/**
* @var \Illuminate\Database\Eloquent\Model
*/
protected $model;
/**
* @param App $app
* @throws \Webkul\Core\Exceptions\RepositoryException
*/
public function __construct(App $app) {
$this->app = $app;
$this->makeModel();
}
/**
* Specify Model class name
*
* @return mixed
*/
public abstract function model();
/**
* @param array $columns
* @return mixed
*/
public function all($columns = ['*']) {
return $this->model->get($columns);
}
/**
* @param int $perPage
* @param array $columns
* @return mixed
*/
public function paginate($perPage = 1, $columns = ['*']) {
return $this->model->paginate($perPage, $columns);
}
/**
* @param array $data
* @return mixed
*/
public function create(array $data) {
return $this->model->create($data);
}
/**
* @param array $data
* @param $id
* @param string $attribute
* @return mixed
*/
public function update(array $data, $id, $attribute="id") {
return $this->model->where($attribute, '=', $id)->update($data);
}
/**
* @param $id
* @return mixed
*/
public function delete($id) {
return $this->model->destroy($id);
}
/**
* @param $id
* @param array $columns
* @return mixed
*/
public function find($id, $columns = ['*']) {
return $this->model->find($id, $columns);
}
/**
* @param $attribute
* @param $value
* @param array $columns
* @return mixed
*/
public function findBy($attribute, $value, $columns = ['*']) {
return $this->model->where($attribute, '=', $value)->first($columns);
}
/**
* @return \Illuminate\Database\Eloquent\Builder
* @throws RepositoryException
*/
public function makeModel() {
$model = $this->app->make($this->model());
if (!$model instanceof Model)
throw new RepositoryException("Class {$this->model()} must be an instance of Illuminate\\Database\\Eloquent\\Model");
return $this->model = $model->newQuery();
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace Webkul\Core\Exceptions;
/**
* Reposotory Exception
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class RepositoryException extends \Exception
{
}

View File

@ -0,0 +1,13 @@
<?php
namespace Webkul\Core\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

View File

@ -0,0 +1,84 @@
<?php
namespace Webkul\Core\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Webkul\Core\Models\Locale;
/**
* Locale controller
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class LocaleController extends Controller
{
/**
* Contains route related configuration
*
* @var array
*/
protected $_config;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->_config = request('_config');
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return view($this->_config['view']);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view($this->_config['view']);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->validate(request(), [
'code' => 'required|unique:locales,code',
'name' => 'required'
]);
Locale::create(request(['code','name']));
session()->flash('success', 'Locale created successfully.');
return redirect()->route($this->_config['redirect']);
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace Webkul\Core\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\User\Models\Admin;
class Locale extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'code', 'name'
];
}

View File

@ -0,0 +1,38 @@
<?php
namespace Webkul\Core\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;
use Illuminate\Routing\Router;
use Illuminate\Foundation\AliasLoader;
class CoreServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot(Router $router)
{
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'core');
$this->publishes([
__DIR__ . '/../../publishable/lang' => public_path('vendor/webkul/core/lang'),
], 'public');
Validator::extend('slug', 'Webkul\Core\Contracts\Validations\Slug@passes');
}
/**
* Register services.
*
* @return void
*/
public function register()
{
}
}

View File

@ -0,0 +1,5 @@
<?php
return [
'slug' => 'The :attribute must be valid slug.'
];

View File

@ -36,16 +36,18 @@ class Menu {
*
* @param string $key Dot seperated heirarchy
* @param string $name Text for the anchor
* @param string $url URL for the anchor
* @param string $route Route for the menu
* @param integer $sort Sorting index for the items
* @param string $iconClass Icon Class name
*/
public function add($key, $name, $url, $sort = 0, $iconClass = null)
public function add($key, $name, $route, $sort = 0, $iconClass = null)
{
$url = route($route);
$item = [
'key' => $key,
'name' => $name,
'url' => $url,
'route' => $route,
'sort' => $sort,
'icon-class' => $iconClass,
'children' => []
@ -65,6 +67,9 @@ class Menu {
* @return void
*/
public function sortItems($items) {
if(!$items) {
return;
}
usort($items, function($a, $b) {
if ($a['sort'] == $b['sort']) {
return 0;

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Expand-Light-On</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Expand-Light-On" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(2.000000, 6.000000)" fill="#8E8E8E" id="Path-2">
<polygon points="0 0 13.3424655 0 6.67123275 7.3125"></polygon>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 635 B

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Angle-Right</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Angle-Right" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<polyline id="Path-3" stroke="#A2A2A2" stroke-width="3" points="7 3 14 10.058476 7.11598308 17"></polyline>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Expand-Light</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Expand-Light" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(9.000000, 9.000000) rotate(-90.000000) translate(-9.000000, -9.000000) translate(2.000000, 5.000000)" fill="#3A3A3A" id="Path-2">
<polygon points="0 0 13.3424655 0 6.67123275 7.3125"></polygon>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 710 B

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Checkbox-Checked</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Checkbox-Checked" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="Base" stroke="#0041FF" stroke-width="2" fill="#0041FF" x="1" y="1" width="22" height="22" rx="2"></rect>
<g id="Check-Accent" transform="translate(6.000000, 7.000000)" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-width="3">
<polyline id="Path-2" points="0 5 4 9 13 0"></polyline>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 824 B

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Checkbox</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Checkbox" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="Base" stroke="#C7C7C7" stroke-width="2" fill="#FFFFFF" x="1" y="1" width="22" height="22" rx="2"></rect>
</g>
</svg>

After

Width:  |  Height:  |  Size: 574 B

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Expand-Light-On</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Expand-Light-On" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(2.000000, 6.000000)" fill="#8E8E8E" id="Path-2">
<polygon points="0 0 13.3424655 0 6.67123275 7.3125"></polygon>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 635 B

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Expand-Light</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Expand-Light" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(9.000000, 9.000000) rotate(-90.000000) translate(-9.000000, -9.000000) translate(2.000000, 5.000000)" fill="#3A3A3A" id="Path-2">
<polygon points="0 0 13.3424655 0 6.67123275 7.3125"></polygon>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 710 B

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Icon-Back-Primary</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Icon-Back-Primary" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="Icon-Sort-Down" transform="translate(12.000000, 12.000000) scale(-1, 1) translate(-12.000000, -12.000000) translate(3.000000, 6.000000)" stroke="#0041FF" stroke-width="2">
<path d="M1,6 L16.068125,6" id="Path-3"></path>
<polyline id="Path-4" points="12 0 18 6.08548298 12 12"></polyline>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 856 B

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Icon-Catalog-Active</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Icon-Catalog-Active" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g transform="translate(9.000000, 7.000000)" stroke="#0041FF" stroke-width="2">
<rect id="Rectangle-2" x="0" y="0" width="30" height="34"></rect>
<path d="M6,6 L24,6" id="Path-6"></path>
<path d="M6,13 L24,13" id="Path-6"></path>
<path d="M6,20 L24,20" id="Path-6"></path>
<path d="M6,27 L24,27" id="Path-6"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 917 B

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Icon-Catalog</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Icon-Catalog" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g transform="translate(9.000000, 7.000000)" stroke-width="2">
<rect id="Rectangle-2" stroke="#8E8E8E" x="0" y="0" width="30" height="34"></rect>
<path d="M6,6 L24,6" id="Path-6" stroke="#979797"></path>
<path d="M6,13 L24,13" id="Path-6" stroke="#979797"></path>
<path d="M6,20 L24,20" id="Path-6" stroke="#979797"></path>
<path d="M6,27 L24,27" id="Path-6" stroke="#979797"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 971 B

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="41px" height="41px" viewBox="0 0 41 41" style="enable-background:new 0 0 41 41;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:#333333;}
.st2{fill:#B1B1AE;}
</style>
<path class="st0" d="M31,21.5L31,21.5c5.2,0,9.5,4.3,9.5,9.5l0,0c0,5.2-4.3,9.5-9.5,9.5l0,0c-5.2,0-9.5-4.3-9.5-9.5l0,0
C21.5,25.8,25.8,21.5,31,21.5z"/>
<circle class="st1" cx="31" cy="31" r="5"/>
<g id="checkbox">
<path class="st0" d="M3.5,0.5h13c1.7,0,3,1.3,3,3v13c0,1.7-1.3,3-3,3h-13c-1.7,0-3-1.3-3-3v-13C0.5,1.8,1.8,0.5,3.5,0.5z"/>
<path class="st2" d="M16.5,20h-13C1.6,20,0,18.4,0,16.5v-13C0,1.6,1.6,0,3.5,0h13C18.4,0,20,1.6,20,3.5v13C20,18.4,18.4,20,16.5,20
z M3.5,1C2.1,1,1,2.1,1,3.5v13C1,17.9,2.1,19,3.5,19h13c1.4,0,2.5-1.1,2.5-2.5v-13C19,2.1,17.9,1,16.5,1H3.5z"/>
</g>
<path id="checkbox-checked" class="st1" d="M17,41H3c-1.7,0-3-1.3-3-3V24c0-1.7,1.3-3,3-3h14c1.7,0,3,1.3,3,3v14
C20,39.7,18.7,41,17,41z M13.3,26l-5.9,5.7l-1.7-1.6L4,31.7L7.4,35l7.6-7.4L13.3,26z"/>
<g id="checkbox_1_">
<path class="st0" d="M31,0.5L31,0.5c5.2,0,9.5,4.3,9.5,9.5l0,0c0,5.2-4.3,9.5-9.5,9.5l0,0c-5.2,0-9.5-4.3-9.5-9.5l0,0
C21.5,4.8,25.8,0.5,31,0.5z"/>
<path class="st2" d="M31,20c-5.5,0-10-4.5-10-10c0-5.5,4.5-10,10-10c5.5,0,10,4.5,10,10C41,15.5,36.5,20,31,20z M31,1c-5,0-9,4-9,9
c0,5,4,9,9,9c5,0,9-4,9-9C40,5,36,1,31,1z"/>
</g>
<path id="radio-checked" class="st1" d="M31,41c-5.5,0-10-4.5-10-10s4.5-10,10-10s10,4.5,10,10S36.5,41,31,41z M31,22c-5,0-9,4-9,9
s4,9,9,9s9-4,9-9S36,22,31,22z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -2,4 +2,5 @@ Vue.component('flash-wrapper', require('./components/flash-wrapper'))
Vue.component('flash', require('./components/flash'))
Vue.component('accordian', require('./components/accordian'))
Vue.component('tree-view', require('./components/tree-view/tree-view'))
Vue.component('tree-item', require('./components/tree-view/tree-item'))
Vue.component('tree-checkbox', require('./components/tree-view/tree-checkbox'))

View File

@ -1,5 +1,5 @@
<template>
<div class="accordian" :class="{ 'active': isActive }">
<div class="accordian" :class="[isActive ? 'active' : '', className]" :id="id">
<div class="accordian-header" @click="toggleAccordion()">
{{ title }}
<i class="icon" :class="iconClass"></i>
@ -11,6 +11,8 @@
export default {
props: {
title: String,
id: String,
className: String,
active: Boolean
},

View File

@ -13,7 +13,7 @@
var this_this = this;
setTimeout(function() {
this_this.$emit('onRemoveFlash', this_this.flash)
}, 1000)
}, 5000)
},
methods: {

View File

@ -1 +0,0 @@
export { default as Treeview } from './tree-view';

View File

@ -1,21 +0,0 @@
<template>
<span class="checkbox">
<input type="checkbox" name="permissions[]" :id="inputValue" v-model="inputValue" @change="inputChanged($event)" :checked="isChecked">
<label class="checkbox-view" :for="inputValue"></label>
{{ label }}
</span>
</template>
<script>
export default {
name: 'tree-checkbox',
props: ['label', 'inputValue', 'isChecked'],
methods: {
inputChanged (e) {
this.$emit('change', this.inputValue)
}
}
}
</script>

View File

@ -1,147 +0,0 @@
<script>
export default {
name: 'tree-view',
inheritAttrs: false,
props: {
items: {
type: Object,
required: false,
default: () => ({
"name": "Root",
"value": "1",
"children": [{
"name": "First Child",
"value": "2",
}, {
"name": "Second Child",
"value": "3",
"children": [{
"name": "GrandChild 1",
"value": "4",
}, {
"name": "GrandChild 2",
"value": "5",
}, {
"name":"GrandChild 3",
"value": "6",
}]
}]
})
},
value: {
type: Array,
required: false,
default: () => ([])
}
},
computed: {
allChildren () {
let leafs = [];
let searchTree = items => {
if(!! items['children'] && items['children'].length > 0) {
items['children'].forEach(child => searchTree(child))
} else {
leafs.push(items)
}
}
searchTree(this.items)
return leafs;
},
hasChildren () {
return !! this.items['children'] && this.items['children'].length > 0;
},
hasSelection () {
return !! this.value && this.value.length > 0;
},
isAllChildrenSelected () {
return this.hasChildren && this.hasSelection && this.allChildren.every(leaf => this.value.some(sel => sel === leaf.value))
},
isSomeChildrenSelected () {
return this.hasSelection && this.allChildren.some(leaf => this.value.some(sel => sel === leaf.value))
},
isChecked () {
return this.hasChildren ? this.isSomeChildrenSelected : (this.value.indexOf(this.items['value']) === -1 ? false : true);
}
},
methods: {
generateRoot () {
return this.$createElement('tree-checkbox', {
props: {
label: this.items['name'],
inputValue: this.items['value'],
isChecked: this.isChecked
},
on: {
change: selection => {
if(this.hasChildren) {
if(this.isAllChildrenSelected) {
this.allChildren.forEach(leaf => {
let index = this.value.indexOf(leaf.value)
this.value.splice(index, 1)
})
} else {
this.allChildren.forEach(leaf => {
let index = this.value.indexOf(leaf.value)
if(index === -1) {
this.value.push(leaf.value);
}
})
}
this.$emit('input', this.value)
} else {
this.$emit('input', selection);
}
}
}
})
},
generateChildren () {
let childElements = [];
if(this.items['children']) {
this.items['children'].forEach(child => {
childElements.push(this.generateChild(child));
})
}
return childElements;
},
generateChild (child) {
return this.$createElement('tree-view', {
class: 'tree-item',
on: {
input: selection => {
// Main Turning Point
console.log(this.items)
this.$emit('input', selection)
}
},
props: {
items: child,
value: this.value
}
})
}
},
render (createElement) {
return createElement('div', {}, [this.generateRoot(), ... this.generateChildren()])
}
}
</script>

View File

@ -1,8 +1,8 @@
<template>
<span class="checkbox">
<input type="checkbox" name="permissions[]" :id="inputValue" :value="inputValue.value" @change="inputChanged($event)" :checked="isActive">
<label class="checkbox-view" :for="inputValue"></label>
{{ inputValue }} ======== {{ value }}
<input type="checkbox" :id="id" name="permissions[]" :value="modelValue" @change="inputChanged()" :checked="isActive">
<label class="checkbox-view" :for="id"></label>
<span class="" :for="id">{{ label }}</span>
</span>
</template>
@ -10,11 +10,63 @@
export default {
name: 'tree-checkbox',
props: ['label', 'inputValue', 'value'],
props: ['id', 'label', 'modelValue', 'inputValue', 'value'],
computed: {
isMultiple () {
return Array.isArray(this.internalValue)
},
isActive () {
const value = this.value
const input = this.internalValue
if (this.isMultiple) {
return input.some(item => this.valueComparator(item, value))
}
return value ? this.valueComparator(value, input) : Boolean(input)
},
internalValue: {
get () {
return this.lazyValue
},
set (val) {
this.lazyValue = val
this.$emit('input', val)
}
}
},
data: vm => ({
lazyValue: vm.inputValue
}),
watch: {
inputValue (val) {
this.internalValue = val
}
},
methods: {
inputChanged (e) {
this.$emit('change', this.inputValue)
inputChanged () {
const value = this.value
let input = this.internalValue
if (this.isMultiple) {
const length = input.length
input = input.filter(item => !this.valueComparator(item, value))
if (input.length === length) {
input.push(value)
}
} else {
input = !input
}
this.$emit('change', input)
},
valueComparator (a, b) {
@ -33,28 +85,6 @@
return props.every(p => this.valueComparator(a[p], b[p]))
}
},
computed: {
isMultiple () {
return Array.isArray(this.inputValue)
},
isActive () {
const value = this.value
const input = this.inputValue
if (this.isMultiple) {
if (!Array.isArray(input))
return false
return input.some(item => this.valueComparator(item, value))
}
var isChecked = value ? this.valueComparator(value, input) : Boolean(input)
return isChecked;
},
}
}
</script>

View File

@ -0,0 +1,203 @@
<script>
export default {
name: 'tree-view',
inheritAttrs: false,
props: {
idField: String,
captionField: String,
childrenField: String,
valueField: String,
items: {
type: [Array, String, Object],
required: false,
default: null
},
value: {
type: Array,
required: false,
default: null
},
savedValues: {
type: Array,
required: false,
default: null
}
},
created () {
let index = this.savedValues.indexOf(this.items[this.valueField])
if(index !== -1) {
this.value.push(this.items);
}
},
computed: {
caption () {
return this.items[this.captionField]
},
allChildren () {
let leafs = [];
let searchTree = items => {
if(!! items[this.childrenField] && this.getLength(items[this.childrenField]) > 0) {
if(typeof items[this.childrenField] == 'object') {
for(let key in items[this.childrenField]) {
searchTree(items[this.childrenField][key])
}
} else {
items[this.childrenField].forEach(child => searchTree(child))
}
} else {
leafs.push(items)
}
}
searchTree(this.items)
return leafs;
},
hasChildren () {
return !! this.items[this.childrenField] && this.getLength(this.items[this.childrenField]) > 0;
},
hasSelection () {
return !! this.value && this.value.length > 0;
},
isAllChildrenSelected () {
return this.hasChildren && this.hasSelection && this.allChildren.every(leaf => this.value.some(sel => sel[this.idField] === leaf[this.idField]))
},
isSomeChildrenSelected () {
return this.hasChildren && this.hasSelection && this.allChildren.some(leaf => this.value.some(sel => sel[this.idField] === leaf[this.idField]))
}
},
methods: {
getLength (items) {
if(typeof items == 'object') {
let length = 0;
for(let item in items) {
length++;
}
return length;
}
return items.length;
},
generateRoot () {
return this.$createElement('tree-checkbox', {
props: {
id: this.items[this.idField],
label: this.caption,
modelValue: this.items[this.valueField],
inputValue: this.hasChildren ? this.isSomeChildrenSelected : this.value,
value: this.hasChildren ? this.isAllChildrenSelected : this.items
},
on: {
change: selection => {
if(this.hasChildren) {
if(this.isAllChildrenSelected) {
this.allChildren.forEach(leaf => {
let index = this.value.indexOf(leaf)
this.value.splice(index, 1)
})
} else {
this.allChildren.forEach(leaf => {
let exists = false;
this.value.forEach(item => {
if(item['key'] == leaf['key']) {
exists = true;
}
})
if(!exists) {
this.value.push(leaf);
}
})
}
this.$emit('input', this.value)
} else {
this.$emit('input', selection);
}
}
}
})
},
generateChild (child) {
return this.$createElement('tree-item', {
on: {
input: selection => {
this.$emit('input', selection)
}
},
props: {
items: child,
value: this.value,
savedValues: this.savedValues,
captionField: this.captionField,
childrenField: this.childrenField,
valueField: this.valueField,
idField: this.idField,
}
})
},
generateChildren () {
let childElements = [];
if(this.items[this.childrenField]) {
if(typeof this.items[this.childrenField] == 'object') {
for(let key in this.items[this.childrenField]) {
childElements.push(this.generateChild(this.items[this.childrenField][key]));
}
} else {
this.items[this.childrenField].forEach(child => {
childElements.push(this.generateChild(child));
})
}
}
return childElements;
},
generateIcon () {
return this.$createElement('i', {
class: ['expand-icon'],
on: {
click: selection => {
this.$el.classList.toggle("active")
}
}
})
}
},
render (createElement) {
return createElement('div', {
class: [
'tree-item',
'active',
this.hasChildren ? 'has-children' : ''
]
}, [
this.generateIcon(), this.generateRoot(), ... this.generateChildren()
]
)
}
}
</script>

View File

@ -6,135 +6,97 @@
inheritAttrs: false,
props: {
items: {
type: Object,
idField: {
type: String,
required: false,
default: () => ({
"name": "Root",
"value": "1",
"children": [{
"name": "First Child",
"value": "2",
}, {
"name": "Second Child",
"value": "3",
"children": [{
"name": "GrandChild 1",
"value": "4",
}, {
"name": "GrandChild 2",
"value": "5",
}, {
"name":"GrandChild 3",
"value": "6",
}]
}]
})
default: 'id'
},
captionField: {
type: String,
required: false,
default: 'name'
},
childrenField: {
type: String,
required: false,
default: 'children'
},
valueField: {
type: String,
required: false,
default: 'value'
},
items: {
type: [Array, String, Object],
required: false,
default: () => ([])
},
value: {
type: Array,
type: [Array, String, Object],
required: false,
default: () => ([])
}
},
data: () => ({
finalValues: []
}),
computed: {
allChildren () {
let leafs = [];
let searchTree = items => {
if(!! items['children'] && items['children'].length > 0) {
items['children'].forEach(child => searchTree(child))
} else {
leafs.push(items)
}
}
savedValues () {
if(!this.value)
return [];
searchTree(this.items)
return leafs;
},
hasChildren () {
return !! this.items['children'] && this.items['children'].length > 0;
},
hasSelection () {
return !! this.value && this.value.length > 0;
},
isAllChildrenSelected () {
return this.hasChildren && this.hasSelection && this.allChildren.every(leaf => this.value.some(sel => sel === leaf))
},
isSomeChildrenSelected () {
return this.hasSelection && this.allChildren.some(leaf => this.value.some(sel => sel === leaf))
return (typeof this.value == 'string') ? JSON.parse(this.value) : this.value;
}
},
methods: {
generateRoot () {
return this.$createElement('tree-checkbox', {
props: {
label: this.items['name'],
inputValue: this.hasChildren ? this.isAllChildrenSelected : this.value,
value: this.hasChildren ? this.isAllChildrenSelected : this.items
},
on: {
change: selection => {
if(this.hasChildren) {
if(this.isAllChildrenSelected) {
this.allChildren.forEach(leaf => {
let index = this.value.indexOf(leaf)
this.value.splice(index, 1)
})
} else {
this.allChildren.forEach(leaf => {
let index = this.value.indexOf(leaf)
if(index === -1) {
this.value.push(leaf);
}
})
}
this.$emit('input', this.value)
} else {
this.$emit('input', selection);
}
}
}
})
},
generateChild (child) {
return this.$createElement('tree-view', {
class: 'tree-item',
on: {
input: selection => {
this.$emit('input', selection)
}
},
props: {
items: child,
value: this.value
}
})
},
generateChildren () {
let childElements = [];
if(this.items['children']) {
this.items['children'].forEach(child => {
childElements.push(this.generateChild(child));
})
let items = (typeof this.items == 'string') ? JSON.parse(this.items) : this.items;
for(let key in items) {
childElements.push(this.generateTreeItem(items[key]));
}
return childElements;
},
generateTreeItem(item) {
return this.$createElement('tree-item', {
props: {
items: item,
value: this.finalValues,
savedValues: this.savedValues,
captionField: this.captionField,
childrenField: this.childrenField,
valueField: this.valueField,
idField: this.idField
},
on: {
input: selection => {
this.finalValues = selection;
}
},
})
}
},
render (createElement) {
return createElement('div', {}, [this.generateRoot(), ... this.generateChildren()])
return createElement('div', {
class: [
'tree-container',
]
}, [this.generateChildren()]
)
}
}
</script>

View File

@ -21,6 +21,7 @@ a:visited,
a:focus,
a:active {
text-decoration: none;
color: $brand-color;
}
ul {
@ -40,6 +41,10 @@ h2 {
color: #3A3A3A;
}
.hide {
display: none !important;
}
.btn {
@include box-shadow(0 1px 4px 0 rgba(0, 0, 0, 0.20), 0 0 8px 0 rgba(0, 0, 0, 0.10));
border-radius: 3px;
@ -65,10 +70,12 @@ h2 {
}
&.btn-xl {
padding: 12px 24px;
font-size: 16px;
}
&.btn-primary {
background: $brand-color;
color: #ffffff;
}
&[disabled="disabled"],
@ -244,10 +251,9 @@ h2 {
}
.checkbox-view {
background-image: url('../images/controls.svg');
background-position: 0px 0px;
height: 20px;
width: 20px;
background-image: url('../images/Checkbox.svg');
height: 24px;
width: 24px;
margin: 0;
display: inline-block !important;
vertical-align: middle;
@ -255,7 +261,7 @@ h2 {
}
input:checked + .checkbox-view {
background-position: 0px -21px;
background-image: url('../images/Checkbox-Checked.svg');
}
input:disabled + .checkbox-view {
@ -298,68 +304,67 @@ h2 {
}
}
.form-container {
.control-group {
.control-group {
display: block;
margin-bottom: 25px;
font-size: 15px;
color: #333333;
width: 750px;
max-width: 100%;
label {
display: block;
margin-bottom: 25px;
color: #3A3A3A;
}
textarea.control {
height: 100px;
padding: 10px;
}
.control {
background: #fff;
border: 2px solid $control-border-color;
border-radius: 3px;
width: 70%;
height: 36px;
display: inline-block;
vertical-align: middle;
transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
padding: 0px 10px;
font-size: 15px;
color: #333333;
width: 750px;
max-width: 100%;
margin-top: 10px;
margin-bottom: 5px;
label {
display: block;
color: #3A3A3A;
&:focus {
border-color: $brand-color;
}
textarea.control {
height: 100px;
&[disabled="disabled"] {
border-color: #D3D3D3;
background-color: #D3D3D3;
cursor: not-allowed;
}
}
.control {
background: #fff;
border: 2px solid $control-border-color;
border-radius: 3px;
width: 70%;
height: 36px;
display: inline-block;
vertical-align: middle;
transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
padding: 0px 10px;
font-size: 15px;
margin-top: 10px;
margin-bottom: 5px;
.control-info {
display: block;
font-style: italic;
color: #6F6F6F;
}
&:focus {
border-color: $brand-color;
}
.control-error {
display: none;
color: #FF5656;
margin-top: 5px;
}
&[disabled="disabled"] {
border-color: #D3D3D3;
background-color: #D3D3D3;
cursor: not-allowed;
}
}
&.has-error .control {
border-color: $danger-color;
}
.control-info {
display: block;
font-style: italic;
color: #6F6F6F;
}
.control-error {
display: none;
color: #FF5656;
margin-top: 5px;
}
&.has-error .control {
border-color: $danger-color;
}
&.has-error .control-error {
display: block;
}
&.has-error .control-error {
display: block;
}
}
@ -369,6 +374,7 @@ h2 {
right: 10px;
position: fixed;
z-index: 6;
text-align: left;
.alert {
width: 300px;
@ -458,13 +464,55 @@ h2 {
}
}
.tree-item {
padding-left: 30px;
display: inline-block;
width: 100%;
.tree-container {
.tree-item {
padding-left: 30px;
display: inline-block;
margin-top: 10px;
width: 100%;
.checkbox {
margin: 0;
margin-bottom: 5px;
> .tree-item {
display: none;
}
&.active > .tree-item {
display: inline-block;
}
.checkbox {
margin: 0;
display: inline-block;
}
.expand-icon {
display: inline-block;
margin-right: 10px;
cursor: pointer;
background-image: url('../images/Expand-Light.svg');
width: 18px;
height: 18px;
vertical-align: middle;
}
&.active {
> .expand-icon {
background-image: url('../images/Expand-Light-On.svg');
}
}
}
> .tree-item {
padding-left: 0;
}
}
.panel {
box-shadow: 0 2px 25px 0 rgba(0,0,0,0.15);
border-radius: 5px;
background: #fff;
.panel-content {
padding: 20px;
}
}

View File

@ -10,15 +10,19 @@
display: inline-block;
background-size: cover;
}
.icon-dashboard {
.dashboard-icon {
@extend %menu-properties;
background-image: url('../images/Icon-Dashboard.svg');
}
.icon-configuration {
.catalog-icon {
@extend %menu-properties;
background-image: url('../images/Icon-Catalog.svg');
}
.configuration-icon {
@extend %menu-properties;
background-image: url('../images/Icon-Configure.svg');
}
.icon-settings {
.settings-icon {
@extend %menu-properties;
background-image: url('../images/Icon-Settings.svg');
}
@ -41,6 +45,12 @@
height: 8px;
}
.arrow-right-icon {
background-image: url('../images/Arrow-Right.svg');
width: 18px;
height: 18px;
}
.white-cross-sm-icon {
background-image: url('../images/Icon-Sm-Cross-White.svg');
width: 18px;
@ -94,17 +104,26 @@
height: 18px;
}
.primary-back-icon {
background-image: url('../images/Icon-Back-Primary.svg');
width: 24px;
height: 24px;
}
.active {
.icon-dashboard {
.dashboard-icon {
background-image: url('../images/Icon-Dashboard-Active.svg');
}
.icon-settings {
.catalog-icon {
background-image: url('../images/Icon-Catalog-Active.svg');
}
.settings-icon {
background-image: url('../images/Icon-Settings-Active.svg');
}
.icon-configuration {
@extend %menu-properties;
.configuration-icon {
background-image: url('../images/Icon-Configure-Active.svg');
}
@ -114,15 +133,15 @@
height: 8px;
}
&.icon-dashboard {
&.dashboard-icon {
background-image: url('../images/Icon-Dashboard-Active.svg');
}
&.icon-settings {
&.settings-icon {
background-image: url('../images/Icon-Settings-Active.svg');
}
&.icon-configuration {
&.configuration-icon {
@extend %menu-properties;
background-image: url('../images/Icon-Configure-Active.svg');
}

View File

@ -343,6 +343,10 @@
<i class="icon arrow-down-icon active"></i>
</span>
<span class="icon-wrapper">
<i class="icon arrow-right-icon"></i>
</span>
<span class="icon-wrapper">
<i class="icon white-cross-sm-icon"></i>
</span>

View File

@ -1,10 +1,12 @@
const { mix } = require('laravel-mix');
require('laravel-mix-merge-manifest');
// var publicPath = 'publishable/assets';
var publicPath = '../../../public/vendor/webkul/ui/assets';
mix.setPublicPath(publicPath).mergeManifest();
mix.disableNotifications();
mix.js([
__dirname + '/src/Resources/assets/js/app.js',

View File

@ -0,0 +1,111 @@
<?php
namespace Webkul\User;
class ACLCreator {
public $items = [];
/**
* Shortcut method for create a acl with a callback.
* This will allow you to do things like fire an event on creation.
*
* @param callable $callback Callback to use after the acl creation
* @return object
*/
public static function create($callback) {
$acl = new ACLCreator();
$callback($acl);
$acl->items = $acl->sortItems($acl->items);
return $acl;
}
/**
* Add a acl item to the item stack
*
* @param string $key Dot seperated heirarchy
* @param string $name Text for the anchor
* @param string $route Route for the acl
* @param integer $sort Sorting index for the items
*/
public function add($key, $name, $route, $sort = 0)
{
$item = [
'key' => $key,
'name' => $name,
'route' => $route,
'sort' => $sort,
'children' => []
];
$children = str_replace('.', '.children.', $key);
$this->array_set($this->items, $children, $item);
}
/**
* Method to sort through the acl items and put them in order
*
* @return void
*/
public function sortItems($items) {
foreach ($items as &$item) {
if(count($item['children'])) {
$item['children'] = $this->sortItems($item['children']);
}
}
usort($items, function($a, $b) {
if ($a['sort'] == $b['sort']) {
return 0;
}
return ($a['sort'] < $b['sort']) ? -1 : 1;
});
return $items;
}
public function array_set(&$array, $key, $value)
{
if (is_null($key)) {
return $array = $value;
}
$keys = explode('.', $key);
$count = count($keys);
while (count($keys) > 1) {
$key = array_shift($keys);
if (! isset($array[$key]) || ! is_array($array[$key])) {
$array[$key] = [];
}
$array = &$array[$key];
}
$finalKey = array_shift($keys);
if(isset($array[$finalKey])) {
$array[$finalKey] = $this->arrayMerge($array[$finalKey], $value);
} else {
$array[$finalKey] = $value;
}
return $array;
}
protected function arrayMerge(array &$array1, array &$array2)
{
$merged = $array1;
foreach ($array2 as $key => &$value) {
if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
$merged[$key] = $this->arrayMerge($merged[$key], $value);
} else {
$merged[$key] = $value;
}
}
return $merged;
}
}

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAdminPasswordResetsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('admin_password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('admin_password_resets');
}
}

View File

@ -16,7 +16,8 @@ class CreateRolesTable extends Migration
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('description');
$table->string('description')->nullable();
$table->string('permission_type');
$table->json('permissions')->nullable();
$table->timestamps();
});

View File

@ -12,7 +12,7 @@ class RolesTableSeeder extends Seeder
$Role = new Role();
$Role->name = 'Administrator';
$Role->description = 'Administrator role';
$Role->status = true;
$Role->permission_type = 'all';
$Role->permissions = [];
$Role->save();
}

View File

@ -10,8 +10,18 @@ namespace Webkul\User\Http\Controllers;
*/
class AccountController extends Controller
{
/**
* Contains route related configuration
*
* @var array
*/
protected $_config;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->_config = request('_config');

View File

@ -0,0 +1,85 @@
<?php
namespace Webkul\User\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Support\Facades\Password;
/**
* Admin forget password controller
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class ForgetPasswordController extends Controller
{
use SendsPasswordResetEmails;
/**
* Contains route related configuration
*
* @var array
*/
protected $_config;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->_config = request('_config');
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view($this->_config['view']);
}
/**
* Store a newly created resource in storage.
*
* @return \Illuminate\Http\Response
*/
public function store()
{
$this->validate(request(), [
'email' => 'required|email'
]);
$response = $this->broker()->sendResetLink(
request(['email'])
);
if($response == Password::RESET_LINK_SENT) {
session()->flash('success', trans($response));
return back();
}
return back()
->withInput(request(['email']))
->withErrors(
['email' => trans($response)]
);
}
/**
* Get the broker to be used during password reset.
*
* @return \Illuminate\Contracts\Auth\PasswordBroker
*/
public function broker()
{
return Password::broker('admins');
}
}

Some files were not shown because too many files have changed in this diff Show More