Role Creation and Tree Vue Component Comnpleted
|
|
@ -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
|
||||
|
|
@ -13,7 +13,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'name' => env('APP_NAME', 'Laravel'),
|
||||
'name' => env('APP_NAME', 'Bagisto'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -18,6 +18,6 @@
|
|||
"vue": "^2.1.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"vee-validate": "^2.1.0-beta.3"
|
||||
"vee-validate": "2.0.0-rc.26"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,5 +33,13 @@ return [
|
|||
'driver' => 'eloquent',
|
||||
'model' => Webkul\User\Models\Admin::class,
|
||||
]
|
||||
]
|
||||
],
|
||||
|
||||
'passwords' => [
|
||||
'admins' => [
|
||||
'provider' => 'admins',
|
||||
'table' => 'admin_password_resets',
|
||||
'expire' => 60,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
|
@ -3,28 +3,49 @@
|
|||
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');
|
||||
|
||||
Route::get('/dashboard', 'Webkul\Admin\Http\Controllers\DashboardController@index')->name('admin.dashboard.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', [
|
||||
|
|
@ -32,7 +53,7 @@ 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', [
|
||||
|
|
@ -41,11 +62,11 @@ Route::group(['middleware' => ['web']], function () {
|
|||
|
||||
// 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', [
|
||||
|
|
@ -53,7 +74,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', [
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
@ -26,42 +26,11 @@ class AdminServiceProvider extends ServiceProvider
|
|||
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
<?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
|
||||
{
|
||||
/**
|
||||
* Register services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$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('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, '');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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');
|
||||
|
||||
$acl->add('settings.users.users', 'Users', 'admin.users.index');
|
||||
|
||||
$acl->add('settings.users.roles', 'Roles', 'admin.roles.index');
|
||||
|
||||
$acl->add('settings.users.roles1', 'Roles 1', 'admin.roles.index');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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'));
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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="route" id-field="key" value-field="route" 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
|
||||
|
|
@ -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
|
||||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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' => []
|
||||
|
|
|
|||
|
|
@ -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 |
|
|
@ -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 |
|
Before Width: | Height: | Size: 264 B |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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'))
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
var this_this = this;
|
||||
setTimeout(function() {
|
||||
this_this.$emit('onRemoveFlash', this_this.flash)
|
||||
}, 1000)
|
||||
}, 5000)
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
export { default as Treeview } from './tree-view';
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
<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
|
||||
}
|
||||
},
|
||||
|
||||
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,
|
||||
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>
|
||||
|
|
@ -6,30 +6,57 @@
|
|||
inheritAttrs: false,
|
||||
|
||||
props: {
|
||||
items: {
|
||||
type: Object,
|
||||
idField: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: () => ({
|
||||
"name": "Root",
|
||||
"value": "1",
|
||||
"children": [{
|
||||
"name": "First Child",
|
||||
"value": "2",
|
||||
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: () => ([{
|
||||
"name": "Dashboard",
|
||||
"value": "1",
|
||||
}, {
|
||||
"name": "Second Child",
|
||||
"value": "3",
|
||||
"name": "Root",
|
||||
"value": "2",
|
||||
"children": [{
|
||||
"name": "GrandChild 1",
|
||||
"value": "4",
|
||||
}, {
|
||||
"name": "GrandChild 2",
|
||||
"value": "5",
|
||||
}, {
|
||||
"name":"GrandChild 3",
|
||||
"value": "6",
|
||||
}]
|
||||
}]
|
||||
})
|
||||
"name": "First Child",
|
||||
"value": "3",
|
||||
}, {
|
||||
"name": "Second Child",
|
||||
"value": "4",
|
||||
"children": [{
|
||||
"name": "GrandChild 1",
|
||||
"value": "5",
|
||||
}, {
|
||||
"name": "GrandChild 2",
|
||||
"value": "6",
|
||||
}, {
|
||||
"name":"GrandChild 3",
|
||||
"value": "7",
|
||||
}]
|
||||
}]
|
||||
}])
|
||||
},
|
||||
|
||||
value: {
|
||||
|
|
@ -39,102 +66,54 @@
|
|||
}
|
||||
},
|
||||
|
||||
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))
|
||||
},
|
||||
|
||||
isSomeChildrenSelected () {
|
||||
return this.hasSelection && this.allChildren.some(leaf => this.value.some(sel => sel === leaf))
|
||||
}
|
||||
created() {
|
||||
this.finalValues = this.value;
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
finalValues: []
|
||||
}),
|
||||
|
||||
|
||||
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,
|
||||
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>
|
||||
|
|
@ -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,66 @@ 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;
|
||||
}
|
||||
|
||||
.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 +373,7 @@ h2 {
|
|||
right: 10px;
|
||||
position: fixed;
|
||||
z-index: 6;
|
||||
text-align: left;
|
||||
|
||||
.alert {
|
||||
width: 300px;
|
||||
|
|
@ -458,13 +463,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,15 +10,15 @@
|
|||
display: inline-block;
|
||||
background-size: cover;
|
||||
}
|
||||
.icon-dashboard {
|
||||
.dashboard-icon {
|
||||
@extend %menu-properties;
|
||||
background-image: url('../images/Icon-Dashboard.svg');
|
||||
}
|
||||
.icon-configuration {
|
||||
.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 +41,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,6 +100,12 @@
|
|||
height: 18px;
|
||||
}
|
||||
|
||||
.primary-back-icon {
|
||||
background-image: url('../images/Icon-Back-Primary.svg');
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.active {
|
||||
.icon-dashboard {
|
||||
background-image: url('../images/Icon-Dashboard-Active.svg');
|
||||
|
|
@ -114,15 +126,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');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
<?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->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);
|
||||
array_set($this->items, $children, $item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to sort through the acl items and put them in order
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sortItems($items) {
|
||||
usort($items, function($a, $b) {
|
||||
if ($a['sort'] == $b['sort']) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ($a['sort'] < $b['sort']) ? -1 : 1;
|
||||
});
|
||||
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Schema;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class Foo extends Migration
|
||||
class CreateAdminPasswordResetsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -13,7 +13,11 @@ class Foo extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
//
|
||||
Schema::create('admin_password_resets', function (Blueprint $table) {
|
||||
$table->string('email')->index();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -23,6 +27,6 @@ class Foo extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
Schema::dropIfExists('admin_password_resets');
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\User\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Admin reset password controller
|
||||
*
|
||||
* @author Jitendra Singh <jitendra@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Contains route related configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_config = request('_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the password reset view for the given token.
|
||||
*
|
||||
* If no token is present, display the link request form.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string|null $token
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function create(Request $request, $token = null)
|
||||
{
|
||||
return view($this->_config['view'])->with(
|
||||
['token' => $token, 'email' => $request->email]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store()
|
||||
{
|
||||
$this->validate(request(), [
|
||||
'token' => 'required',
|
||||
'email' => 'required|email',
|
||||
'password' => 'required|confirmed|min:6',
|
||||
]);
|
||||
|
||||
$response = $this->broker()->reset(
|
||||
request(['email', 'password', 'password_confirmation', 'token']), function ($admin, $password) {
|
||||
$this->resetPassword($admin, $password);
|
||||
}
|
||||
);
|
||||
|
||||
if($response == Password::PASSWORD_RESET) {
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
}
|
||||
|
||||
return back()
|
||||
->withInput(request(['email']))
|
||||
->withErrors([
|
||||
'email' => trans($response)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the given admin's password.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\CanResetPassword $admin
|
||||
* @param string $password
|
||||
* @return void
|
||||
*/
|
||||
protected function resetPassword($admin, $password)
|
||||
{
|
||||
$admin->password = Hash::make($password);
|
||||
|
||||
$admin->setRememberToken(Str::random(60));
|
||||
|
||||
$admin->save();
|
||||
|
||||
event(new PasswordReset($admin));
|
||||
|
||||
auth()->guard('admin')->login($admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the broker to be used during password reset.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\PasswordBroker
|
||||
*/
|
||||
public function broker()
|
||||
{
|
||||
return Password::broker('admins');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ namespace Webkul\User\Http\Controllers;
|
|||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Webkul\User\Models\Role;
|
||||
|
||||
/**
|
||||
|
|
@ -15,8 +14,18 @@ use Webkul\User\Models\Role;
|
|||
*/
|
||||
class RoleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Contains route related configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_config = request('_config');
|
||||
|
|
@ -50,6 +59,12 @@ class RoleController extends Controller
|
|||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->validate(request(), [
|
||||
'name' => 'required',
|
||||
'permission_type' => 'required',
|
||||
]);
|
||||
|
||||
|
||||
Role::create(request()->all());
|
||||
|
||||
session()->flash('success', 'Role created successfully.');
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ namespace Webkul\User\Http\Controllers;
|
|||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Routing\Controller;
|
||||
|
||||
/**
|
||||
* Admin user session controller
|
||||
|
|
@ -12,10 +11,20 @@ use Illuminate\Routing\Controller;
|
|||
* @author Jitendra Singh <jitendra@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class SeesionController extends Controller
|
||||
class SessionController extends Controller
|
||||
{
|
||||
/**
|
||||
* Contains route related configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_config = request('_config');
|
||||
|
|
@ -40,13 +49,19 @@ class SeesionController extends Controller
|
|||
*/
|
||||
public function store()
|
||||
{
|
||||
if(! auth()->guard('admin')->attempt(request(['email', 'password']))) {
|
||||
return back()->withErrors([
|
||||
'message' => 'Please check your credentials and try again.'
|
||||
]);
|
||||
$this->validate(request(), [
|
||||
'email' => 'required|email',
|
||||
'password' => 'required'
|
||||
]);
|
||||
|
||||
$remember = request('remember');
|
||||
if(! auth()->guard('admin')->attempt(request(['email', 'password']), $remember)) {
|
||||
session()->flash('error', 'Please check your credentials and try again.');
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
return redirect($this->_config['redirect']);
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -59,6 +74,6 @@ class SeesionController extends Controller
|
|||
{
|
||||
auth()->guard('admin')->logout();
|
||||
|
||||
return redirect($this->_config['redirect']);
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ namespace Webkul\User\Http\Controllers;
|
|||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Webkul\User\Models\Admin;
|
||||
use Webkul\User\Models\Role;
|
||||
use Webkul\User\Http\Requests\UserForm;
|
||||
|
|
@ -17,8 +16,18 @@ use Webkul\User\Http\Requests\UserForm;
|
|||
*/
|
||||
class UserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Contains route related configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_config = request('_config');
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ namespace Webkul\User\Models;
|
|||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Webkul\User\Models\Role;
|
||||
use Webkul\User\Notifications\AdminResetPassword;
|
||||
|
||||
|
||||
class Admin extends Authenticatable
|
||||
{
|
||||
|
|
@ -36,6 +38,17 @@ class Admin extends Authenticatable
|
|||
return $this->belongsTo(Role::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the password reset notification.
|
||||
*
|
||||
* @param string $token
|
||||
* @return void
|
||||
*/
|
||||
public function sendPasswordResetNotification($token)
|
||||
{
|
||||
$this->notify(new AdminResetPassword($token));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if admin has permission to perform certain action.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -7,6 +7,16 @@ use Webkul\User\Models\Admin;
|
|||
|
||||
class Role extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name', 'description', 'permission_type', 'permissions',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'permissions' => 'array'
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\User\Notifications;
|
||||
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Auth\Notifications\ResetPassword;
|
||||
|
||||
class AdminResetPassword extends ResetPassword
|
||||
{
|
||||
|
||||
/**
|
||||
* Build the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
if (static::$toMailCallback) {
|
||||
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
|
||||
}
|
||||
|
||||
return (new MailMessage)
|
||||
->line('You are receiving this email because we received a password reset request for your account.')
|
||||
->action('Reset Password', route('admin.reset-password.create', $this->token))
|
||||
->line('If you did not request a password reset, no further action is required.');
|
||||
}
|
||||
}
|
||||
|
|
@ -5,9 +5,11 @@ namespace Webkul\User\Providers;
|
|||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Foundation\AliasLoader;
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Webkul\User\Bouncer;
|
||||
use Webkul\User\Facades\Bouncer as BouncerFacade;
|
||||
use Webkul\User\Http\Middleware\RedirectIfNotAdmin;
|
||||
use Webkul\User\ACLCreator;
|
||||
|
||||
class UserServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
@ -21,6 +23,22 @@ class UserServiceProvider extends ServiceProvider
|
|||
$router->aliasMiddleware('admin', RedirectIfNotAdmin::class);
|
||||
|
||||
$this->loadMigrationsFrom(__DIR__ . '/../Database/migrations');
|
||||
|
||||
$this->createACL();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method fires an event for acl creation, any package can add their acl item by listening to the admin.acl.build event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function createACL()
|
||||
{
|
||||
Event::listen('admin.acl.create', function() {
|
||||
return ACLCreator::create(function($acl) {
|
||||
Event::fire('admin.acl.build', $acl);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="147px" height="60px" viewBox="0 0 147 60" 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>Logo+Text</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Sign-In" transform="translate(-726.000000, -100.000000)">
|
||||
<g id="Paper" transform="translate(618.000000, 100.000000)">
|
||||
<g id="Logo+Text-LG" transform="translate(108.000000, 0.000000)">
|
||||
<g id="Logo+Text">
|
||||
<g id="Logo">
|
||||
<rect id="Rectangle" fill="#0041FF" x="0" y="16" width="44" height="44"></rect>
|
||||
<rect id="Rectangle" fill="#000311" x="0" y="54" width="44" height="6"></rect>
|
||||
<path d="M36,15.2214765 L36,25.557047 C36,26.9062527 34.9580948,28 33.6728395,28 C32.3875843,28 31.345679,26.9062527 31.345679,25.557047 L31.345679,15.2214765 C31.345679,9.51329856 26.9376184,4.88590604 21.5,4.88590604 C16.0623816,4.88590604 11.654321,9.51329856 11.654321,15.2214765 L11.654321,25.557047 C11.654321,26.9062527 10.6124157,28 9.32716049,28 C8.04190524,28 7,26.9062527 7,25.557047 L7,15.2214765 C7,6.81488716 13.4918711,0 21.5,0 C29.5081289,0 36,6.81488716 36,15.2214765 Z" id="Combined-Shape" fill="#000311"></path>
|
||||
</g>
|
||||
<text id="bagisto" font-family="Montserrat-SemiBold, Montserrat" font-size="24" font-weight="500" letter-spacing="-0.3839998" fill="#0041FF">
|
||||
<tspan x="59" y="45">bagisto</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="147px" height="60px" viewBox="0 0 147 60" 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>Logo+Text</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Sign-In" transform="translate(-726.000000, -100.000000)">
|
||||
<g id="Paper" transform="translate(618.000000, 100.000000)">
|
||||
<g id="Logo+Text-LG" transform="translate(108.000000, 0.000000)">
|
||||
<g id="Logo+Text">
|
||||
<g id="Logo">
|
||||
<rect id="Rectangle" fill="#0041FF" x="0" y="16" width="44" height="44"></rect>
|
||||
<rect id="Rectangle" fill="#000311" x="0" y="54" width="44" height="6"></rect>
|
||||
<path d="M36,15.2214765 L36,25.557047 C36,26.9062527 34.9580948,28 33.6728395,28 C32.3875843,28 31.345679,26.9062527 31.345679,25.557047 L31.345679,15.2214765 C31.345679,9.51329856 26.9376184,4.88590604 21.5,4.88590604 C16.0623816,4.88590604 11.654321,9.51329856 11.654321,15.2214765 L11.654321,25.557047 C11.654321,26.9062527 10.6124157,28 9.32716049,28 C8.04190524,28 7,26.9062527 7,25.557047 L7,15.2214765 C7,6.81488716 13.4918711,0 21.5,0 C29.5081289,0 36,6.81488716 36,15.2214765 Z" id="Combined-Shape" fill="#000311"></path>
|
||||
</g>
|
||||
<text id="bagisto" font-family="Montserrat-SemiBold, Montserrat" font-size="24" font-weight="500" letter-spacing="-0.3839998" fill="#0041FF">
|
||||
<tspan x="59" y="45">bagisto</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
|
|
@ -1,4 +1,4 @@
|
|||
.icon-dashboard, .icon-configuration, .icon-settings, .active .icon-configuration, .active.icon-configuration {
|
||||
.dashboard-icon, .configuration-icon, .settings-icon, .active .icon-configuration, .active.configuration-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-bottom: 10px;
|
||||
|
|
@ -11,15 +11,15 @@
|
|||
background-size: cover;
|
||||
}
|
||||
|
||||
.icon-dashboard {
|
||||
.dashboard-icon {
|
||||
background-image: url("../images/Icon-Dashboard.svg");
|
||||
}
|
||||
|
||||
.icon-configuration {
|
||||
.configuration-icon {
|
||||
background-image: url("../images/Icon-Configure.svg");
|
||||
}
|
||||
|
||||
.icon-settings {
|
||||
.settings-icon {
|
||||
background-image: url("../images/Icon-Settings.svg");
|
||||
}
|
||||
|
||||
|
|
@ -41,6 +41,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;
|
||||
|
|
@ -95,6 +101,12 @@
|
|||
height: 18px;
|
||||
}
|
||||
|
||||
.primary-back-icon {
|
||||
background-image: url("../images/Icon-Back-Primary.svg");
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.active .icon-dashboard {
|
||||
background-image: url("../images/Icon-Dashboard-Active.svg");
|
||||
}
|
||||
|
|
@ -113,15 +125,15 @@
|
|||
height: 8px;
|
||||
}
|
||||
|
||||
.active.icon-dashboard {
|
||||
.active.dashboard-icon {
|
||||
background-image: url("../images/Icon-Dashboard-Active.svg");
|
||||
}
|
||||
|
||||
.active.icon-settings {
|
||||
.active.settings-icon {
|
||||
background-image: url("../images/Icon-Settings-Active.svg");
|
||||
}
|
||||
|
||||
.active.icon-configuration {
|
||||
.active.configuration-icon {
|
||||
background-image: url("../images/Icon-Configure-Active.svg");
|
||||
}
|
||||
|
||||
|
|
@ -221,6 +233,7 @@ a:visited,
|
|||
a:focus,
|
||||
a:active {
|
||||
text-decoration: none;
|
||||
color: #0041FF;
|
||||
}
|
||||
|
||||
ul {
|
||||
|
|
@ -240,6 +253,10 @@ h2 {
|
|||
color: #3A3A3A;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.btn {
|
||||
-webkit-box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.2), 0 0 8px 0 rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.2), 0 0 8px 0 rgba(0, 0, 0, 0.1);
|
||||
|
|
@ -271,10 +288,12 @@ h2 {
|
|||
|
||||
.btn.btn-xl {
|
||||
padding: 12px 24px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.btn.btn-primary {
|
||||
background: #0041FF;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.btn[disabled="disabled"], .btn[disabled="disabled"]:hover, .btn[disabled="disabled"]:active {
|
||||
|
|
@ -453,10 +472,9 @@ h2 {
|
|||
}
|
||||
|
||||
.checkbox .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;
|
||||
|
|
@ -464,7 +482,7 @@ h2 {
|
|||
}
|
||||
|
||||
.checkbox input:checked + .checkbox-view {
|
||||
background-position: 0px -21px;
|
||||
background-image: url("../images/Checkbox-Checked.svg");
|
||||
}
|
||||
|
||||
.checkbox input:disabled + .checkbox-view {
|
||||
|
|
@ -506,7 +524,7 @@ h2 {
|
|||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.form-container .control-group {
|
||||
.control-group {
|
||||
display: block;
|
||||
margin-bottom: 25px;
|
||||
font-size: 15px;
|
||||
|
|
@ -515,16 +533,16 @@ h2 {
|
|||
max-width: 100%;
|
||||
}
|
||||
|
||||
.form-container .control-group label {
|
||||
.control-group label {
|
||||
display: block;
|
||||
color: #3A3A3A;
|
||||
}
|
||||
|
||||
.form-container .control-group textarea.control {
|
||||
.control-group textarea.control {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.form-container .control-group .control {
|
||||
.control-group .control {
|
||||
background: #fff;
|
||||
border: 2px solid #C7C7C7;
|
||||
border-radius: 3px;
|
||||
|
|
@ -540,33 +558,33 @@ h2 {
|
|||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.form-container .control-group .control:focus {
|
||||
.control-group .control:focus {
|
||||
border-color: #0041FF;
|
||||
}
|
||||
|
||||
.form-container .control-group .control[disabled="disabled"] {
|
||||
.control-group .control[disabled="disabled"] {
|
||||
border-color: #D3D3D3;
|
||||
background-color: #D3D3D3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.form-container .control-group .control-info {
|
||||
.control-group .control-info {
|
||||
display: block;
|
||||
font-style: italic;
|
||||
color: #6F6F6F;
|
||||
}
|
||||
|
||||
.form-container .control-group .control-error {
|
||||
.control-group .control-error {
|
||||
display: none;
|
||||
color: #FF5656;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.form-container .control-group.has-error .control {
|
||||
.control-group.has-error .control {
|
||||
border-color: #FC6868;
|
||||
}
|
||||
|
||||
.form-container .control-group.has-error .control-error {
|
||||
.control-group.has-error .control-error {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
|
@ -576,6 +594,7 @@ h2 {
|
|||
right: 10px;
|
||||
position: fixed;
|
||||
z-index: 6;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.alert-wrapper .alert {
|
||||
|
|
@ -664,13 +683,51 @@ h2 {
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
.tree-item {
|
||||
.tree-container .tree-item {
|
||||
padding-left: 30px;
|
||||
display: inline-block;
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tree-item .checkbox {
|
||||
margin: 0;
|
||||
margin-bottom: 5px;
|
||||
.tree-container .tree-item > .tree-item {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tree-container .tree-item.active > .tree-item {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tree-container .tree-item .checkbox {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tree-container .tree-item .expand-icon {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
background-image: url("../images/Expand-Light.svg");
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.tree-container .tree-item.active > .expand-icon {
|
||||
background-image: url("../images/Expand-Light-On.svg");
|
||||
}
|
||||
|
||||
.tree-container > .tree-item {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.panel {
|
||||
-webkit-box-shadow: 0 2px 25px 0 rgba(0, 0, 0, 0.15);
|
||||
box-shadow: 0 2px 25px 0 rgba(0, 0, 0, 0.15);
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.panel .panel-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -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 |
|
|
@ -177,8 +177,8 @@ module.exports = function normalizeComponent (
|
|||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
__webpack_require__(2);
|
||||
__webpack_require__(17);
|
||||
module.exports = __webpack_require__(19);
|
||||
__webpack_require__(19);
|
||||
module.exports = __webpack_require__(21);
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
|
@ -189,7 +189,8 @@ Vue.component('flash-wrapper', __webpack_require__(3));
|
|||
Vue.component('flash', __webpack_require__(6));
|
||||
Vue.component('accordian', __webpack_require__(9));
|
||||
Vue.component('tree-view', __webpack_require__(12));
|
||||
Vue.component('tree-checkbox', __webpack_require__(14));
|
||||
Vue.component('tree-item', __webpack_require__(14));
|
||||
Vue.component('tree-checkbox', __webpack_require__(16));
|
||||
|
||||
/***/ }),
|
||||
/* 3 */
|
||||
|
|
@ -388,7 +389,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
|||
var this_this = this;
|
||||
setTimeout(function () {
|
||||
this_this.$emit('onRemoveFlash', this_this.flash);
|
||||
}, 1000);
|
||||
}, 5000);
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
@ -616,7 +617,7 @@ module.exports = Component.exports
|
|||
|
||||
"use strict";
|
||||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
|
||||
/* harmony default export */ __webpack_exports__["default"] = ({
|
||||
name: 'tree-view',
|
||||
|
|
@ -624,31 +625,58 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
|
|||
inheritAttrs: false,
|
||||
|
||||
props: {
|
||||
idField: {
|
||||
type: String,
|
||||
required: false,
|
||||
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: Object,
|
||||
type: [Array, String, Object],
|
||||
required: false,
|
||||
default: function _default() {
|
||||
return {
|
||||
return [{
|
||||
"name": "Dashboard",
|
||||
"value": "1"
|
||||
}, {
|
||||
"name": "Root",
|
||||
"value": "1",
|
||||
"value": "2",
|
||||
"children": [{
|
||||
"name": "First Child",
|
||||
"value": "2"
|
||||
"value": "3"
|
||||
}, {
|
||||
"name": "Second Child",
|
||||
"value": "3",
|
||||
"value": "4",
|
||||
"children": [{
|
||||
"name": "GrandChild 1",
|
||||
"value": "4"
|
||||
}, {
|
||||
"name": "GrandChild 2",
|
||||
"value": "5"
|
||||
}, {
|
||||
"name": "GrandChild 3",
|
||||
"name": "GrandChild 2",
|
||||
"value": "6"
|
||||
}, {
|
||||
"name": "GrandChild 3",
|
||||
"value": "7"
|
||||
}]
|
||||
}]
|
||||
};
|
||||
}];
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -661,116 +689,54 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
|
|||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
allChildren: function allChildren() {
|
||||
var leafs = [];
|
||||
var searchTree = function searchTree(items) {
|
||||
if (!!items['children'] && items['children'].length > 0) {
|
||||
items['children'].forEach(function (child) {
|
||||
return searchTree(child);
|
||||
});
|
||||
} else {
|
||||
leafs.push(items);
|
||||
}
|
||||
};
|
||||
created: function created() {
|
||||
this.finalValues = this.value;
|
||||
},
|
||||
|
||||
searchTree(this.items);
|
||||
|
||||
return leafs;
|
||||
},
|
||||
hasChildren: function hasChildren() {
|
||||
return !!this.items['children'] && this.items['children'].length > 0;
|
||||
},
|
||||
hasSelection: function hasSelection() {
|
||||
return !!this.value && this.value.length > 0;
|
||||
},
|
||||
isAllChildrenSelected: function isAllChildrenSelected() {
|
||||
var _this = this;
|
||||
|
||||
return this.hasChildren && this.hasSelection && this.allChildren.every(function (leaf) {
|
||||
return _this.value.some(function (sel) {
|
||||
return sel === leaf;
|
||||
});
|
||||
});
|
||||
},
|
||||
isSomeChildrenSelected: function isSomeChildrenSelected() {
|
||||
var _this2 = this;
|
||||
|
||||
return this.hasSelection && this.allChildren.some(function (leaf) {
|
||||
return _this2.value.some(function (sel) {
|
||||
return sel === leaf;
|
||||
});
|
||||
});
|
||||
}
|
||||
data: function data() {
|
||||
return {
|
||||
finalValues: []
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
generateRoot: function generateRoot() {
|
||||
var _this3 = this;
|
||||
|
||||
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: function change(selection) {
|
||||
if (_this3.hasChildren) {
|
||||
if (_this3.isAllChildrenSelected) {
|
||||
_this3.allChildren.forEach(function (leaf) {
|
||||
var index = _this3.value.indexOf(leaf);
|
||||
_this3.value.splice(index, 1);
|
||||
});
|
||||
} else {
|
||||
_this3.allChildren.forEach(function (leaf) {
|
||||
var index = _this3.value.indexOf(leaf);
|
||||
if (index === -1) {
|
||||
_this3.value.push(leaf);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_this3.$emit('input', _this3.value);
|
||||
} else {
|
||||
_this3.$emit('input', selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
generateChild: function generateChild(child) {
|
||||
var _this4 = this;
|
||||
|
||||
return this.$createElement('tree-view', {
|
||||
class: 'tree-item',
|
||||
on: {
|
||||
input: function input(selection) {
|
||||
_this4.$emit('input', selection);
|
||||
}
|
||||
},
|
||||
props: {
|
||||
items: child,
|
||||
value: this.value
|
||||
}
|
||||
});
|
||||
},
|
||||
generateChildren: function generateChildren() {
|
||||
var _this5 = this;
|
||||
|
||||
var childElements = [];
|
||||
if (this.items['children']) {
|
||||
this.items['children'].forEach(function (child) {
|
||||
childElements.push(_this5.generateChild(child));
|
||||
});
|
||||
|
||||
var items = typeof this.items == 'string' ? JSON.parse(this.items) : this.items;
|
||||
|
||||
for (var key in items) {
|
||||
childElements.push(this.generateTreeItem(items[key]));
|
||||
}
|
||||
|
||||
return childElements;
|
||||
},
|
||||
generateTreeItem: function generateTreeItem(item) {
|
||||
var _this = this;
|
||||
|
||||
return this.$createElement('tree-item', {
|
||||
props: {
|
||||
items: item,
|
||||
value: this.finalValues,
|
||||
captionField: this.captionField,
|
||||
childrenField: this.childrenField,
|
||||
valueField: this.valueField,
|
||||
idField: this.idField
|
||||
},
|
||||
on: {
|
||||
input: function input(selection) {
|
||||
_this.finalValues = selection;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
render: function render(createElement) {
|
||||
return createElement('div', {}, [this.generateRoot()].concat(_toConsumableArray(this.generateChildren())));
|
||||
return createElement('div', {
|
||||
class: ['tree-container']
|
||||
}, [this.generateChildren()]);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -783,7 +749,259 @@ var normalizeComponent = __webpack_require__(0)
|
|||
/* script */
|
||||
var __vue_script__ = __webpack_require__(15)
|
||||
/* template */
|
||||
var __vue_template__ = __webpack_require__(16)
|
||||
var __vue_template__ = null
|
||||
/* template functional */
|
||||
var __vue_template_functional__ = false
|
||||
/* styles */
|
||||
var __vue_styles__ = null
|
||||
/* scopeId */
|
||||
var __vue_scopeId__ = null
|
||||
/* moduleIdentifier (server only) */
|
||||
var __vue_module_identifier__ = null
|
||||
var Component = normalizeComponent(
|
||||
__vue_script__,
|
||||
__vue_template__,
|
||||
__vue_template_functional__,
|
||||
__vue_styles__,
|
||||
__vue_scopeId__,
|
||||
__vue_module_identifier__
|
||||
)
|
||||
Component.options.__file = "src/Resources/assets/js/components/tree-view/tree-item.vue"
|
||||
|
||||
/* hot reload */
|
||||
if (false) {(function () {
|
||||
var hotAPI = require("vue-hot-reload-api")
|
||||
hotAPI.install(require("vue"), false)
|
||||
if (!hotAPI.compatible) return
|
||||
module.hot.accept()
|
||||
if (!module.hot.data) {
|
||||
hotAPI.createRecord("data-v-2af003eb", Component.options)
|
||||
} else {
|
||||
hotAPI.reload("data-v-2af003eb", Component.options)
|
||||
}
|
||||
module.hot.dispose(function (data) {
|
||||
disposed = true
|
||||
})
|
||||
})()}
|
||||
|
||||
module.exports = Component.exports
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 15 */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
/* harmony default export */ __webpack_exports__["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
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
caption: function caption() {
|
||||
return this.items[this.captionField];
|
||||
},
|
||||
allChildren: function allChildren() {
|
||||
var _this = this;
|
||||
|
||||
var leafs = [];
|
||||
var searchTree = function searchTree(items) {
|
||||
if (!!items[_this.childrenField] && _this.getLength(items[_this.childrenField]) > 0) {
|
||||
if (_typeof(items[_this.childrenField]) == 'object') {
|
||||
for (var key in items[_this.childrenField]) {
|
||||
searchTree(items[_this.childrenField][key]);
|
||||
}
|
||||
} else {
|
||||
items[_this.childrenField].forEach(function (child) {
|
||||
return searchTree(child);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
leafs.push(items);
|
||||
}
|
||||
};
|
||||
|
||||
searchTree(this.items);
|
||||
|
||||
return leafs;
|
||||
},
|
||||
hasChildren: function hasChildren() {
|
||||
return !!this.items[this.childrenField] && this.getLength(this.items[this.childrenField]) > 0;
|
||||
},
|
||||
hasSelection: function hasSelection() {
|
||||
return !!this.value && this.value.length > 0;
|
||||
},
|
||||
isAllChildrenSelected: function isAllChildrenSelected() {
|
||||
var _this2 = this;
|
||||
|
||||
return this.hasChildren && this.hasSelection && this.allChildren.every(function (leaf) {
|
||||
return _this2.value.some(function (sel) {
|
||||
return sel[_this2.idField] === leaf[_this2.idField];
|
||||
});
|
||||
});
|
||||
},
|
||||
isSomeChildrenSelected: function isSomeChildrenSelected() {
|
||||
var _this3 = this;
|
||||
|
||||
return this.hasChildren && this.hasSelection && this.allChildren.some(function (leaf) {
|
||||
return _this3.value.some(function (sel) {
|
||||
return sel[_this3.idField] === leaf[_this3.idField];
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getLength: function getLength(items) {
|
||||
if ((typeof items === 'undefined' ? 'undefined' : _typeof(items)) == 'object') {
|
||||
var length = 0;
|
||||
|
||||
for (var item in items) {
|
||||
length++;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
return items.length;
|
||||
},
|
||||
generateRoot: function generateRoot() {
|
||||
var _this4 = this;
|
||||
|
||||
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: function change(selection) {
|
||||
if (_this4.hasChildren) {
|
||||
if (_this4.isAllChildrenSelected) {
|
||||
_this4.allChildren.forEach(function (leaf) {
|
||||
var index = _this4.value.indexOf(leaf);
|
||||
_this4.value.splice(index, 1);
|
||||
});
|
||||
} else {
|
||||
_this4.allChildren.forEach(function (leaf) {
|
||||
var exists = false;
|
||||
_this4.value.forEach(function (item) {
|
||||
if (item['key'] == leaf['key']) {
|
||||
exists = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!exists) {
|
||||
_this4.value.push(leaf);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_this4.$emit('input', _this4.value);
|
||||
} else {
|
||||
_this4.$emit('input', selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
generateChild: function generateChild(child) {
|
||||
var _this5 = this;
|
||||
|
||||
return this.$createElement('tree-item', {
|
||||
on: {
|
||||
input: function input(selection) {
|
||||
_this5.$emit('input', selection);
|
||||
}
|
||||
},
|
||||
props: {
|
||||
items: child,
|
||||
value: this.value,
|
||||
captionField: this.captionField,
|
||||
childrenField: this.childrenField,
|
||||
valueField: this.valueField,
|
||||
idField: this.idField
|
||||
}
|
||||
});
|
||||
},
|
||||
generateChildren: function generateChildren() {
|
||||
var _this6 = this;
|
||||
|
||||
var childElements = [];
|
||||
if (this.items[this.childrenField]) {
|
||||
if (_typeof(this.items[this.childrenField]) == 'object') {
|
||||
for (var key in this.items[this.childrenField]) {
|
||||
childElements.push(this.generateChild(this.items[this.childrenField][key]));
|
||||
}
|
||||
} else {
|
||||
this.items[this.childrenField].forEach(function (child) {
|
||||
childElements.push(_this6.generateChild(child));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return childElements;
|
||||
},
|
||||
generateIcon: function generateIcon() {
|
||||
var _this7 = this;
|
||||
|
||||
return this.$createElement('i', {
|
||||
class: ['expand-icon'],
|
||||
on: {
|
||||
click: function click(selection) {
|
||||
_this7.$el.classList.toggle("active");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
render: function render(createElement) {
|
||||
return createElement('div', {
|
||||
class: ['tree-item', 'active', this.hasChildren ? 'has-children' : '']
|
||||
}, [this.generateIcon(), this.generateRoot()].concat(_toConsumableArray(this.generateChildren())));
|
||||
}
|
||||
});
|
||||
|
||||
/***/ }),
|
||||
/* 16 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var disposed = false
|
||||
var normalizeComponent = __webpack_require__(0)
|
||||
/* script */
|
||||
var __vue_script__ = __webpack_require__(17)
|
||||
/* template */
|
||||
var __vue_template__ = __webpack_require__(18)
|
||||
/* template functional */
|
||||
var __vue_template_functional__ = false
|
||||
/* styles */
|
||||
|
|
@ -822,7 +1040,7 @@ module.exports = Component.exports
|
|||
|
||||
|
||||
/***/ }),
|
||||
/* 15 */
|
||||
/* 17 */
|
||||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
|
@ -839,14 +1057,76 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
|||
/* harmony default export */ __webpack_exports__["default"] = ({
|
||||
name: 'tree-checkbox',
|
||||
|
||||
props: ['label', 'inputValue', 'value'],
|
||||
props: ['id', 'label', 'modelValue', 'inputValue', 'value'],
|
||||
|
||||
computed: {
|
||||
isMultiple: function isMultiple() {
|
||||
return Array.isArray(this.internalValue);
|
||||
},
|
||||
isActive: function isActive() {
|
||||
var _this = this;
|
||||
|
||||
var value = this.value;
|
||||
var input = this.internalValue;
|
||||
|
||||
if (this.isMultiple) {
|
||||
return input.some(function (item) {
|
||||
return _this.valueComparator(item, value);
|
||||
});
|
||||
}
|
||||
|
||||
return value ? this.valueComparator(value, input) : Boolean(input);
|
||||
},
|
||||
|
||||
|
||||
internalValue: {
|
||||
get: function get() {
|
||||
return this.lazyValue;
|
||||
},
|
||||
set: function set(val) {
|
||||
this.lazyValue = val;
|
||||
this.$emit('input', val);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
data: function data(vm) {
|
||||
return {
|
||||
lazyValue: vm.inputValue
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
inputValue: function inputValue(val) {
|
||||
this.internalValue = val;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
inputChanged: function inputChanged(e) {
|
||||
this.$emit('change', this.inputValue);
|
||||
inputChanged: function inputChanged() {
|
||||
var _this2 = this;
|
||||
|
||||
var value = this.value;
|
||||
var input = this.internalValue;
|
||||
|
||||
if (this.isMultiple) {
|
||||
var length = input.length;
|
||||
|
||||
input = input.filter(function (item) {
|
||||
return !_this2.valueComparator(item, value);
|
||||
});
|
||||
|
||||
if (input.length === length) {
|
||||
input.push(value);
|
||||
}
|
||||
} else {
|
||||
input = !input;
|
||||
}
|
||||
|
||||
this.$emit('change', input);
|
||||
},
|
||||
valueComparator: function valueComparator(a, b) {
|
||||
var _this = this;
|
||||
var _this3 = this;
|
||||
|
||||
if (a === b) return true;
|
||||
|
||||
|
|
@ -861,38 +1141,14 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
|||
}
|
||||
|
||||
return props.every(function (p) {
|
||||
return _this.valueComparator(a[p], b[p]);
|
||||
return _this3.valueComparator(a[p], b[p]);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isMultiple: function isMultiple() {
|
||||
return Array.isArray(this.inputValue);
|
||||
},
|
||||
isActive: function isActive() {
|
||||
var _this2 = this;
|
||||
|
||||
var value = this.value;
|
||||
var input = this.inputValue;
|
||||
|
||||
if (this.isMultiple) {
|
||||
if (!Array.isArray(input)) return false;
|
||||
|
||||
return input.some(function (item) {
|
||||
return _this2.valueComparator(item, value);
|
||||
});
|
||||
}
|
||||
|
||||
var isChecked = value ? this.valueComparator(value, input) : Boolean(input);
|
||||
|
||||
return isChecked;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/***/ }),
|
||||
/* 16 */
|
||||
/* 18 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var render = function() {
|
||||
|
|
@ -901,26 +1157,18 @@ var render = function() {
|
|||
var _c = _vm._self._c || _h
|
||||
return _c("span", { staticClass: "checkbox" }, [
|
||||
_c("input", {
|
||||
attrs: { type: "checkbox", name: "permissions[]", id: _vm.inputValue },
|
||||
domProps: { value: _vm.inputValue.value, checked: _vm.isActive },
|
||||
attrs: { type: "checkbox", id: _vm.id, name: "permissions[]" },
|
||||
domProps: { value: _vm.modelValue, checked: _vm.isActive },
|
||||
on: {
|
||||
change: function($event) {
|
||||
_vm.inputChanged($event)
|
||||
_vm.inputChanged()
|
||||
}
|
||||
}
|
||||
}),
|
||||
_vm._v(" "),
|
||||
_c("label", {
|
||||
staticClass: "checkbox-view",
|
||||
attrs: { for: _vm.inputValue }
|
||||
}),
|
||||
_vm._v(
|
||||
"\n " +
|
||||
_vm._s(_vm.inputValue) +
|
||||
" ======== " +
|
||||
_vm._s(_vm.value) +
|
||||
"\n"
|
||||
)
|
||||
_c("label", { staticClass: "checkbox-view", attrs: { for: _vm.id } }),
|
||||
_vm._v(" "),
|
||||
_c("span", { attrs: { for: _vm.id } }, [_vm._v(_vm._s(_vm.label))])
|
||||
])
|
||||
}
|
||||
var staticRenderFns = []
|
||||
|
|
@ -934,10 +1182,10 @@ if (false) {
|
|||
}
|
||||
|
||||
/***/ }),
|
||||
/* 17 */
|
||||
/* 19 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
window.jQuery = window.$ = $ = __webpack_require__(18);
|
||||
window.jQuery = window.$ = $ = __webpack_require__(20);
|
||||
|
||||
$(function () {
|
||||
$(document).click(function (e) {
|
||||
|
|
@ -1002,7 +1250,7 @@ $(function () {
|
|||
});
|
||||
|
||||
/***/ }),
|
||||
/* 18 */
|
||||
/* 20 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
|
||||
|
|
@ -11373,7 +11621,7 @@ return jQuery;
|
|||
|
||||
|
||||
/***/ }),
|
||||
/* 19 */
|
||||
/* 21 */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
// removed by extract-text-webpack-plugin
|
||||
|
|
|
|||