Attribute Family Feature Added
This commit is contained in:
parent
89a0a8a8d2
commit
c87f71427a
|
|
@ -1,7 +1,7 @@
|
||||||
php artisan make:controller UserController && mv app/Http/Controllers/UserController.php packages/Webkul/User/src/Ht
|
php artisan make:controller UserController && mv app/Http/Controllers/UserController.php packages/Webkul/User/src/Ht
|
||||||
tp/Controllers
|
tp/Controllers
|
||||||
|
|
||||||
php artisan make:migration foo --path=packages/Webkul/User/src/Database/migrations
|
php artisan make:migration foo --path=packages/Webkul/User/src/Database/Migrations
|
||||||
|
|
||||||
php artisan db:seed --class=Webkul\\User\\Database\\Seeders\\DatabaseSeeder
|
php artisan db:seed --class=Webkul\\User\\Database\\Seeders\\DatabaseSeeder
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ Route::group(['middleware' => ['web']], function () {
|
||||||
|
|
||||||
// Catalog Routes
|
// Catalog Routes
|
||||||
Route::prefix('catalog')->group(function () {
|
Route::prefix('catalog')->group(function () {
|
||||||
|
|
||||||
|
// Catalog Attribute Routes
|
||||||
Route::get('/attributes', 'Webkul\Attribute\Http\Controllers\AttributeController@index')->defaults('_config', [
|
Route::get('/attributes', 'Webkul\Attribute\Http\Controllers\AttributeController@index')->defaults('_config', [
|
||||||
'view' => 'admin::catalog.attributes.index'
|
'view' => 'admin::catalog.attributes.index'
|
||||||
])->name('admin.catalog.attributes.index');
|
])->name('admin.catalog.attributes.index');
|
||||||
|
|
@ -55,6 +57,35 @@ Route::group(['middleware' => ['web']], function () {
|
||||||
Route::post('/attributes/create', 'Webkul\Attribute\Http\Controllers\AttributeController@store')->defaults('_config', [
|
Route::post('/attributes/create', 'Webkul\Attribute\Http\Controllers\AttributeController@store')->defaults('_config', [
|
||||||
'redirect' => 'admin.catalog.attributes.index'
|
'redirect' => 'admin.catalog.attributes.index'
|
||||||
])->name('admin.catalog.attributes.store');
|
])->name('admin.catalog.attributes.store');
|
||||||
|
|
||||||
|
Route::get('/attributes/edit/{id}', 'Webkul\Attribute\Http\Controllers\AttributeController@edit')->defaults('_config', [
|
||||||
|
'view' => 'admin::catalog.attributes.edit'
|
||||||
|
])->name('admin.catalog.attributes.edit');
|
||||||
|
|
||||||
|
Route::put('/attributes/edit/{id}', 'Webkul\Attribute\Http\Controllers\AttributeController@update')->defaults('_config', [
|
||||||
|
'redirect' => 'admin.catalog.attributes.index'
|
||||||
|
])->name('admin.catalog.attributes.update');
|
||||||
|
|
||||||
|
// Catalog Family Routes
|
||||||
|
Route::get('/families', 'Webkul\Attribute\Http\Controllers\AttributeFamilyController@index')->defaults('_config', [
|
||||||
|
'view' => 'admin::catalog.families.index'
|
||||||
|
])->name('admin.catalog.families.index');
|
||||||
|
|
||||||
|
Route::get('/families/create', 'Webkul\Attribute\Http\Controllers\AttributeFamilyController@create')->defaults('_config', [
|
||||||
|
'view' => 'admin::catalog.families.create'
|
||||||
|
])->name('admin.catalog.families.create');
|
||||||
|
|
||||||
|
Route::post('/families/create', 'Webkul\Attribute\Http\Controllers\AttributeFamilyController@store')->defaults('_config', [
|
||||||
|
'redirect' => 'admin.catalog.families.index'
|
||||||
|
])->name('admin.catalog.families.store');
|
||||||
|
|
||||||
|
Route::get('/families/edit/{id}', 'Webkul\Attribute\Http\Controllers\AttributeFamilyController@edit')->defaults('_config', [
|
||||||
|
'view' => 'admin::catalog.families.edit'
|
||||||
|
])->name('admin.catalog.families.edit');
|
||||||
|
|
||||||
|
Route::put('/families/edit/{id}', 'Webkul\Attribute\Http\Controllers\AttributeFamilyController@update')->defaults('_config', [
|
||||||
|
'redirect' => 'admin.catalog.families.index'
|
||||||
|
])->name('admin.catalog.families.update');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Datagrid Routes
|
// Datagrid Routes
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,6 @@ class AdminServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
$this->composeView();
|
$this->composeView();
|
||||||
|
|
||||||
Blade::directive('continue', function() { return "<?php continue; ?>"; });
|
|
||||||
|
|
||||||
$this->app->register(EventServiceProvider::class);
|
$this->app->register(EventServiceProvider::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,8 @@ class EventServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
$menu->add('catalog.attributes', 'Attributes', 'admin.catalog.attributes.index', 3);
|
$menu->add('catalog.attributes', 'Attributes', 'admin.catalog.attributes.index', 3);
|
||||||
|
|
||||||
|
$menu->add('catalog.families', 'Families', 'admin.catalog.families.index', 4);
|
||||||
|
|
||||||
$menu->add('configuration', 'Configure', 'admin.account.edit', 6, 'configuration-icon');
|
$menu->add('configuration', 'Configure', 'admin.account.edit', 6, 'configuration-icon');
|
||||||
|
|
||||||
$menu->add('configuration.account', 'My Account', 'admin.account.edit', 1);
|
$menu->add('configuration.account', 'My Account', 'admin.account.edit', 1);
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,26 @@ window.VeeValidate = require('vee-validate');
|
||||||
Vue.use(VeeValidate);
|
Vue.use(VeeValidate);
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
const app = new Vue({
|
Vue.config.ignoredElements = [
|
||||||
|
'option-wrapper',
|
||||||
|
'group-form',
|
||||||
|
'group-list'
|
||||||
|
];
|
||||||
|
|
||||||
|
var app = new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
|
|
||||||
mounted: function() {
|
data: {
|
||||||
|
modalIds: {}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted () {
|
||||||
this.addServerErrors()
|
this.addServerErrors()
|
||||||
this.addFlashMessages()
|
this.addFlashMessages()
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
onSubmit: function(e) {
|
onSubmit (e) {
|
||||||
this.$validator.validateAll().then((result) => {
|
this.$validator.validateAll().then((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
e.target.submit()
|
e.target.submit()
|
||||||
|
|
@ -22,7 +32,7 @@ $(document).ready(function () {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
addServerErrors: function() {
|
addServerErrors () {
|
||||||
var scope = null;
|
var scope = null;
|
||||||
for (var key in serverErrors) {
|
for (var key in serverErrors) {
|
||||||
const field = this.$validator.fields.find({ name: key, scope: scope });
|
const field = this.$validator.fields.find({ name: key, scope: scope });
|
||||||
|
|
@ -37,12 +47,16 @@ $(document).ready(function () {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
addFlashMessages: function() {
|
addFlashMessages () {
|
||||||
const flashes = this.$refs.flashes
|
const flashes = this.$refs.flashes
|
||||||
|
|
||||||
flashMessages.forEach(function(flash) {
|
flashMessages.forEach(function(flash) {
|
||||||
flashes.addFlash(flash)
|
flashes.addFlash(flash)
|
||||||
}, this);
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
showModal (id) {
|
||||||
|
this.$set(this.modalIds, id, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,6 @@ body {
|
||||||
right: 0;
|
right: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
z-index: 1;
|
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
|
@ -155,7 +154,7 @@ body {
|
||||||
|
|
||||||
.content-wrapper {
|
.content-wrapper {
|
||||||
padding: 25px 25px 25px 305px;
|
padding: 25px 25px 25px 305px;
|
||||||
overflow-y: auto;
|
// overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'catalog' => [
|
||||||
|
'attributes' => [
|
||||||
|
'add-title' => 'Add Attribute',
|
||||||
|
'edit-title' => 'Edit Attribute',
|
||||||
|
'save-btn-title' => 'Save Attribute',
|
||||||
|
'general' => 'General',
|
||||||
|
'code' => 'Attribute Code',
|
||||||
|
'type' => 'Attribute Type',
|
||||||
|
'text' => 'Text',
|
||||||
|
'textarea' => 'Textarea',
|
||||||
|
'select' => 'Select',
|
||||||
|
'multiselect' => 'Multiselect',
|
||||||
|
'checkbox' => 'Checkbox',
|
||||||
|
'datetime' => 'Datetime',
|
||||||
|
'date' => 'Date',
|
||||||
|
'label' => 'label',
|
||||||
|
'admin' => 'Admin',
|
||||||
|
'options' => 'Options',
|
||||||
|
'position' => 'Position',
|
||||||
|
'add-option-btn-title' => 'Add Option',
|
||||||
|
'validations' => 'Validations',
|
||||||
|
'input_validation' => 'Input Validation',
|
||||||
|
'is_required' => 'Is Required',
|
||||||
|
'is_unique' => 'Is Unique',
|
||||||
|
'number' => 'Number',
|
||||||
|
'decimal' => 'Decimal',
|
||||||
|
'email' => 'Email',
|
||||||
|
'url' => 'URL',
|
||||||
|
'configuration' => 'Configuration',
|
||||||
|
'status' => 'Status',
|
||||||
|
'yes' => 'Yes',
|
||||||
|
'no' => 'No',
|
||||||
|
'value_per_locale' => 'Value Per Locale',
|
||||||
|
'value_per_channel' => 'Value Per Channel',
|
||||||
|
'value_per_channel' => 'Value Per Channel',
|
||||||
|
'is_filterable' => 'Use in Layered Navigation',
|
||||||
|
'is_configurable' => 'Use To Create Configurable Product'
|
||||||
|
],
|
||||||
|
'families' => [
|
||||||
|
'families' => 'Families',
|
||||||
|
'add-family-btn-title' => 'Add Family',
|
||||||
|
'add-title' => 'Add Family',
|
||||||
|
'save-btn-title' => 'Save Family',
|
||||||
|
'general' => 'General',
|
||||||
|
'code' => 'Family Code',
|
||||||
|
'name' => 'Name',
|
||||||
|
'groups' => 'Groups',
|
||||||
|
'add-group-title' => 'Add Group',
|
||||||
|
'position' => 'Position',
|
||||||
|
'attribute-code' => 'Code',
|
||||||
|
'type' => 'Type',
|
||||||
|
'add-attribute-title' => 'Add Attribute',
|
||||||
|
'search' => 'Search'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
<input name="_method" type="hidden" value="PUT">
|
<input name="_method" type="hidden" value="PUT">
|
||||||
|
|
||||||
<accordian :title="'{{ __('General') }}'" :active="true">
|
<accordian :title="'{{ __('General') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
||||||
<label for="name">{{ __('Name') }}</label>
|
<label for="name">{{ __('Name') }}</label>
|
||||||
<input type="text" v-validate="'required'" class="control" id="name" name="name" value="{{ $user->name }}"/>
|
<input type="text" v-validate="'required'" class="control" id="name" name="name" value="{{ $user->name }}"/>
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
</accordian>
|
</accordian>
|
||||||
|
|
||||||
<accordian :title="'{{ __('Password') }}'" :active="true">
|
<accordian :title="'{{ __('Password') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
|
||||||
<label for="password">{{ __('Password') }}</label>
|
<label for="password">{{ __('Password') }}</label>
|
||||||
<input type="password" v-validate="'min:6'" class="control" id="password" name="password"/>
|
<input type="password" v-validate="'min:6'" class="control" id="password" name="password"/>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,22 @@
|
||||||
@extends('admin::layouts.content')
|
@extends('admin::layouts.content')
|
||||||
|
|
||||||
|
@section('page_title')
|
||||||
|
{{ __('admin::app.catalog.attributes.add-title') }}
|
||||||
|
@stop
|
||||||
|
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<form method="POST" action="{{ route('admin.catalog.attributes.store') }}">
|
<form method="POST" action="{{ route('admin.catalog.attributes.store') }}">
|
||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<div class="page-title">
|
<div class="page-title">
|
||||||
<h1>{{ __('Add Attribute') }}</h1>
|
<h1>{{ __('admin::app.catalog.attributes.add-title') }}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page-action">
|
<div class="page-action">
|
||||||
<button type="submit" class="btn btn-lg btn-primary">
|
<button type="submit" class="btn btn-lg btn-primary">
|
||||||
{{ __('Save Attribute') }}
|
{{ __('admin::app.catalog.attributes.save-btn-title') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -20,44 +25,43 @@
|
||||||
<div class="form-container">
|
<div class="form-container">
|
||||||
@csrf()
|
@csrf()
|
||||||
|
|
||||||
<accordian :title="'{{ __('General') }}'" :active="true">
|
<accordian :title="'{{ __('admin::app.catalog.attributes.general') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
|
||||||
<label for="code">{{ __('Attribute Code') }}</label>
|
<label for="code">{{ __('admin::app.catalog.attributes.code') }}</label>
|
||||||
<input type="text" v-validate="'required'" class="control" id="code" name="code" value="{{ old('code') }}"/>
|
<input type="text" v-validate="'required'" class="control" id="code" name="code" value="{{ old('code') }}"/>
|
||||||
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
|
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label for="type">{{ __('Attribute Type') }}</label>
|
<label for="type">{{ __('admin::app.catalog.attributes.type') }}</label>
|
||||||
<select class="control" id="type" name="type">
|
<select class="control" id="type" name="type">
|
||||||
<option value="text">{{ __('Text') }}</option>
|
<option value="text">{{ __('admin::app.catalog.attributes.text') }}</option>
|
||||||
<option value="textarea">{{ __('Textarea') }}</option>
|
<option value="textarea">{{ __('admin::app.catalog.attributes.textarea') }}</option>
|
||||||
<option value="integer">{{ __('Integer') }}</option>
|
<option value="select">{{ __('admin::app.catalog.attributes.select') }}</option>
|
||||||
<option value="select">{{ __('Select') }}</option>
|
<option value="multiselect">{{ __('admin::app.catalog.attributes.multiselect') }}</option>
|
||||||
<option value="multiselect">{{ __('Multiselect') }}</option>
|
<option value="checkbox">{{ __('admin::app.catalog.attributes.checkbox') }}</option>
|
||||||
<option value="checkbox">{{ __('Multiselect') }}</option>
|
<option value="datetime">{{ __('admin::app.catalog.attributes.datetime') }}</option>
|
||||||
<option value="datetime">{{ __('Datetime') }}</option>
|
<option value="date">{{ __('admin::app.catalog.attributes.date') }}</option>
|
||||||
<option value="date">{{ __('Date') }}</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</accordian>
|
</accordian>
|
||||||
|
|
||||||
<accordian :title="'{{ __('Label') }}'" :active="true">
|
<accordian :title="'{{ __('admin::app.catalog.attributes.label') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
|
|
||||||
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('admin_name') ? 'has-error' : '']">
|
||||||
<label for="name">{{ __('Admin') }}</label>
|
<label for="admin_name">{{ __('admin::app.catalog.attributes.admin') }}</label>
|
||||||
<input type="text" v-validate="'required'" class="control" id="name" name="name"/>
|
<input type="text" v-validate="'required'" class="control" id="admin_name" name="admin_name" value="{{ old('admin_name') }}"/>
|
||||||
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
|
<span class="control-error" v-if="errors.has('admin_name')">@{{ errors.first('admin_name') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@foreach(Webkul\Core\Models\Locale::all() as $locale)
|
@foreach(Webkul\Core\Models\Locale::all() as $locale)
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label for="locale-{{ $locale->code }}">{{ $locale->name . ' (' . $locale->code . ')' }}</label>
|
<label for="locale-{{ $locale->code }}">{{ $locale->name . ' (' . $locale->code . ')' }}</label>
|
||||||
<input type="text" class="control" id="locale-{{ $locale->code }}" name="<?php echo $locale->code; ?>[name]"/>
|
<input type="text" class="control" id="locale-{{ $locale->code }}" name="<?php echo $locale->code; ?>[name]" value="{{ old($locale->code)['name'] }}"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
@ -65,13 +69,93 @@
|
||||||
</div>
|
</div>
|
||||||
</accordian>
|
</accordian>
|
||||||
|
|
||||||
<accordian :title="'{{ __('Options') }}'" :active="true" :class-name="'hide'" :id="'options'">
|
<div class="hide">
|
||||||
|
<accordian :title="'{{ __('admin::app.catalog.attributes.options') }}'" :active="true" :id="'options'">
|
||||||
|
<div slot="body">
|
||||||
|
|
||||||
|
<option-wrapper></option-wrapper>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<accordian :title="'{{ __('admin::app.catalog.attributes.validations') }}'" :active="true">
|
||||||
|
<div slot="body">
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="is_required">{{ __('admin::app.catalog.attributes.is_required') }}</label>
|
||||||
|
<select class="control" id="is_required" name="is_required">
|
||||||
|
<option value="1">{{ __('admin::app.catalog.attributes.yes') }}</option>
|
||||||
|
<option value="0">{{ __('admin::app.catalog.attributes.no') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="is_unique">{{ __('admin::app.catalog.attributes.is_unique') }}</label>
|
||||||
|
<select class="control" id="is_unique" name="is_unique">
|
||||||
|
<option value="1">{{ __('admin::app.catalog.attributes.yes') }}</option>
|
||||||
|
<option value="0">{{ __('admin::app.catalog.attributes.no') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="validation">{{ __('admin::app.catalog.attributes.input_validation') }}</label>
|
||||||
|
<select class="control" id="validation" name="validation">
|
||||||
|
<option value=""></option>
|
||||||
|
<option value="number">{{ __('admin::app.catalog.attributes.number') }}</option>
|
||||||
|
<option value="decimal">{{ __('admin::app.catalog.attributes.decimal') }}</option>
|
||||||
|
<option value="email">{{ __('admin::app.catalog.attributes.email') }}</option>
|
||||||
|
<option value="url">{{ __('admin::app.catalog.attributes.url') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</accordian>
|
</accordian>
|
||||||
|
|
||||||
<accordian :title="'{{ __('Validations') }}'" :active="true">
|
<accordian :title="'{{ __('admin::app.catalog.attributes.configuration') }}'" :active="true">
|
||||||
</accordian>
|
<div slot="body">
|
||||||
|
|
||||||
<accordian :title="'{{ __('Configuration') }}'" :active="true">
|
<div class="control-group">
|
||||||
|
<label for="status">{{ __('admin::app.catalog.attributes.status') }}</label>
|
||||||
|
<select class="control" id="status" name="status">
|
||||||
|
<option value="1">{{ __('admin::app.catalog.attributes.yes') }}</option>
|
||||||
|
<option value="0">{{ __('admin::app.catalog.attributes.no') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="value_per_locale">{{ __('admin::app.catalog.attributes.value_per_locale') }}</label>
|
||||||
|
<select class="control" id="value_per_locale" name="value_per_locale">
|
||||||
|
<option value="1">{{ __('admin::app.catalog.attributes.yes') }}</option>
|
||||||
|
<option value="0">{{ __('admin::app.catalog.attributes.no') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="value_per_channel">{{ __('admin::app.catalog.attributes.value_per_channel') }}</label>
|
||||||
|
<select class="control" id="value_per_channel" name="value_per_channel">
|
||||||
|
<option value="1">{{ __('admin::app.catalog.attributes.yes') }}</option>
|
||||||
|
<option value="0">{{ __('admin::app.catalog.attributes.no') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="is_filterable">{{ __('admin::app.catalog.attributes.is_filterable') }}</label>
|
||||||
|
<select class="control" id="is_filterable" name="is_filterable">
|
||||||
|
<option value="1">{{ __('admin::app.catalog.attributes.yes') }}</option>
|
||||||
|
<option value="0">{{ __('admin::app.catalog.attributes.no') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="is_configurable">{{ __('admin::app.catalog.attributes.is_configurable') }}</label>
|
||||||
|
<select class="control" id="is_configurable" name="is_configurable">
|
||||||
|
<option value="1">{{ __('admin::app.catalog.attributes.yes') }}</option>
|
||||||
|
<option value="0">{{ __('admin::app.catalog.attributes.no') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</accordian>
|
</accordian>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -81,5 +165,109 @@
|
||||||
@stop
|
@stop
|
||||||
|
|
||||||
@section('javascript')
|
@section('javascript')
|
||||||
|
<script type="text/x-template" id="options-template">
|
||||||
|
<div>
|
||||||
|
<div class="table">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
@foreach(Webkul\Core\Models\Locale::all() as $locale)
|
||||||
|
|
||||||
|
<th>{{ $locale->name . ' (' . $locale->code . ')' }}</th>
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<th>{{ __('admin::app.catalog.attributes.position') }}</th>
|
||||||
|
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="row in optionRows">
|
||||||
|
@foreach(Webkul\Core\Models\Locale::all() as $locale)
|
||||||
|
<td>
|
||||||
|
<div class="control-group" :class="[errors.has(localeInputName(row, '{{ $locale->code }}')) ? 'has-error' : '']">
|
||||||
|
<input type="text" v-validate="'required'" v-model="row['{{ $locale->code }}']" :name="localeInputName(row, '{{ $locale->code }}')" class="control"/>
|
||||||
|
<span class="control-error" v-if="errors.has(localeInputName(row, '{{ $locale->code }}'))">@{{ errors.first(localeInputName(row, '{!! $locale->code !!}')) }}</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div class="control-group" :class="[errors.has(sortOrderName(row)) ? 'has-error' : '']">
|
||||||
|
<input type="text" v-validate="'required'" :name="sortOrderName(row)" class="control"/>
|
||||||
|
<span class="control-error" v-if="errors.has(sortOrderName(row))">@{{ errors.first(sortOrderName(row)) }}</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="actions">
|
||||||
|
<i class="icon trash-icon" @click="removeRow(row)"></i>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-lg btn-primary" id="add-option-btn" style="margin-top: 20px" @click="addOptionRow()">
|
||||||
|
{{ __('admin::app.catalog.attributes.add-option-btn-title') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('#type').on('change', function (e) {
|
||||||
|
if(['select', 'multiselect', 'checkbox'].indexOf($(e.target).val()) === -1) {
|
||||||
|
$('#options').parent().addClass('hide')
|
||||||
|
} else {
|
||||||
|
$('#options').parent().removeClass('hide')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var optionWrapper = Vue.component('option-wrapper', {
|
||||||
|
|
||||||
|
template: '#options-template',
|
||||||
|
|
||||||
|
data: () => ({
|
||||||
|
optionRowCount: 0,
|
||||||
|
optionRows: []
|
||||||
|
}),
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
addOptionRow () {
|
||||||
|
var rowCount = this.optionRowCount++;
|
||||||
|
var row = {'id': 'option_' + rowCount};
|
||||||
|
|
||||||
|
@foreach(Webkul\Core\Models\Locale::all() as $locale)
|
||||||
|
row['{{ $locale->code }}'] = '';
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
this.optionRows.push(row);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeRow (row) {
|
||||||
|
var index = this.optionRows.indexOf(row)
|
||||||
|
Vue.delete(this.optionRows, index);
|
||||||
|
},
|
||||||
|
|
||||||
|
localeInputName (row, locale) {
|
||||||
|
return 'options[' + row.id + '][' + locale + '][label]';
|
||||||
|
},
|
||||||
|
|
||||||
|
sortOrderName (row) {
|
||||||
|
return 'options[' + row.id + '][sort_order]';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
el: '#options',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
optionWrapper: optionWrapper
|
||||||
|
},
|
||||||
|
})
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@stop
|
@stop
|
||||||
|
|
@ -0,0 +1,333 @@
|
||||||
|
@extends('admin::layouts.content')
|
||||||
|
|
||||||
|
@section('page_title')
|
||||||
|
{{ __('admin::app.catalog.attributes.edit-title') }}
|
||||||
|
@stop
|
||||||
|
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="content">
|
||||||
|
<form method="POST" action="{{ route('admin.catalog.attributes.update', $attribute->id) }}">
|
||||||
|
|
||||||
|
<div class="page-header">
|
||||||
|
<div class="page-title">
|
||||||
|
<h1>{{ __('admin::app.catalog.attributes.edit-title') }}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-action">
|
||||||
|
<button type="submit" class="btn btn-lg btn-primary">
|
||||||
|
{{ __('admin::app.catalog.attributes.save-btn-title') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="form-container">
|
||||||
|
@csrf()
|
||||||
|
<input name="_method" type="hidden" value="PUT">
|
||||||
|
|
||||||
|
<accordian :title="'{{ __('admin::app.catalog.attributes.general') }}'" :active="true">
|
||||||
|
<div slot="body">
|
||||||
|
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
|
||||||
|
<label for="code">{{ __('admin::app.catalog.attributes.code') }}</label>
|
||||||
|
<input type="hidden" name="code" value="{{ old('code') ?: $attribute->code }}"/>
|
||||||
|
<input type="text" v-validate="'required'" class="control" id="code" name="code" value="{{ old('code') ?: $attribute->code }}" disabled="disabled"/>
|
||||||
|
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<?php $selectedOption = old('type') ?: $attribute->type ?>
|
||||||
|
<label for="type">{{ __('admin::app.catalog.attributes.type') }}</label>
|
||||||
|
<input type="hidden" name="type" value="{{ old('type') ?: $attribute->type }}"/>
|
||||||
|
<select class="control" id="type" name="type" disabled="disabled">
|
||||||
|
<option value="text" {{ $selectedOption == 'text' ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.text') }}
|
||||||
|
</option>
|
||||||
|
<option value="textarea" {{ $selectedOption == 'textarea' ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.textarea') }}
|
||||||
|
</option>
|
||||||
|
<option value="select" {{ $selectedOption == 'select' ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.select') }}
|
||||||
|
</option>
|
||||||
|
<option value="multiselect" {{ $selectedOption == 'multiselect' ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.multiselect') }}
|
||||||
|
</option>
|
||||||
|
<option value="checkbox" {{ $selectedOption == 'checkbox' ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.checkbox') }}
|
||||||
|
</option>
|
||||||
|
<option value="datetime" {{ $selectedOption == 'datetime' ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.datetime') }}
|
||||||
|
</option>
|
||||||
|
<option value="date" {{ $selectedOption == 'date' ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.date') }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
|
||||||
|
<accordian :title="'{{ __('admin::app.catalog.attributes.label') }}'" :active="true">
|
||||||
|
<div slot="body">
|
||||||
|
|
||||||
|
<div class="control-group" :class="[errors.has('admin_name') ? 'has-error' : '']">
|
||||||
|
<label for="admin_name">{{ __('admin::app.catalog.attributes.admin') }}</label>
|
||||||
|
<input type="text" v-validate="'required'" class="control" id="admin_name" name="admin_name" value="{{ old('admin_name') ?: $attribute->admin_name }}"/>
|
||||||
|
<span class="control-error" v-if="errors.has('admin_name')">@{{ errors.first('admin_name') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@foreach(Webkul\Core\Models\Locale::all() as $locale)
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="locale-{{ $locale->code }}">{{ $locale->name . ' (' . $locale->code . ')' }}</label>
|
||||||
|
<input type="text" class="control" id="locale-{{ $locale->code }}" name="<?php echo $locale->code; ?>[name]" value="{{ old($locale->code)['name'] ?: $attribute->translate($locale->code)->name }}"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
|
||||||
|
<div class="<?php in_array($attribute->type, ['select', 'multiselect', 'checkbox']) ?: 'hide' ?>">
|
||||||
|
<accordian :title="'{{ __('admin::app.catalog.attributes.options') }}'" :active="true" :id="'options'">
|
||||||
|
<div slot="body">
|
||||||
|
|
||||||
|
<option-wrapper></option-wrapper>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<accordian :title="'{{ __('admin::app.catalog.attributes.validations') }}'" :active="true">
|
||||||
|
<div slot="body">
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="is_required">{{ __('admin::app.catalog.attributes.is_required') }}</label>
|
||||||
|
<select class="control" id="is_required" name="is_required">
|
||||||
|
<option value="1" {{ $attribute->is_required ? 'selected' : '' }}>{{ __('admin::app.catalog.attributes.yes') }}</option>
|
||||||
|
<option value="0" {{ $attribute->is_required ? '' : 'selected' }}>{{ __('admin::app.catalog.attributes.no') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="is_unique">{{ __('admin::app.catalog.attributes.is_unique') }}</label>
|
||||||
|
<select class="control" id="is_unique" name="is_unique">
|
||||||
|
<option value="1" {{ $attribute->is_unique ? 'selected' : '' }}>{{ __('admin::app.catalog.attributes.yes') }}</option>
|
||||||
|
<option value="0" {{ $attribute->is_unique ? '' : 'selected' }}>{{ __('admin::app.catalog.attributes.no') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<?php $selectedValidation = old('input_validation') ?: $attribute->input_validation ?>
|
||||||
|
<label for="validation">{{ __('admin::app.catalog.attributes.input_validation') }}</label>
|
||||||
|
<select class="control" id="validation" name="validation">
|
||||||
|
<option value=""></option>
|
||||||
|
<option value="number" {{ $selectedValidation == 'number' ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.number') }}
|
||||||
|
</option>
|
||||||
|
<option value="decimal" {{ $selectedValidation == 'decimal' ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.decimal') }}
|
||||||
|
</option>
|
||||||
|
<option value="email" {{ $selectedValidation == 'email' ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.email') }}
|
||||||
|
</option>
|
||||||
|
<option value="url" {{ $selectedValidation == 'url' ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.url') }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
|
||||||
|
<accordian :title="'{{ __('admin::app.catalog.attributes.configuration') }}'" :active="true">
|
||||||
|
<div slot="body">
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="status">{{ __('admin::app.catalog.attributes.status') }}</label>
|
||||||
|
<select class="control" id="status" name="status">
|
||||||
|
<option value="1" {{ $attribute->status ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.yes') }}
|
||||||
|
</option>
|
||||||
|
<option value="0" {{ $attribute->status ? '' : 'selected' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.no') }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="value_per_locale">{{ __('admin::app.catalog.attributes.value_per_locale') }}</label>
|
||||||
|
<select class="control" id="value_per_locale" name="value_per_locale">
|
||||||
|
<option value="1" {{ $attribute->value_per_locale ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.yes') }}
|
||||||
|
</option>
|
||||||
|
<option value="0" {{ $attribute->value_per_locale ? '' : 'selected' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.no') }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="value_per_channel">{{ __('admin::app.catalog.attributes.value_per_channel') }}</label>
|
||||||
|
<select class="control" id="value_per_channel" name="value_per_channel">
|
||||||
|
<option value="1" {{ $attribute->value_per_channel ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.yes') }}
|
||||||
|
</option>
|
||||||
|
<option value="0" {{ $attribute->value_per_channel ? '' : 'selected' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.no') }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="is_filterable">{{ __('admin::app.catalog.attributes.is_filterable') }}</label>
|
||||||
|
<select class="control" id="is_filterable" name="is_filterable">
|
||||||
|
<option value="1" {{ $attribute->is_filterable ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.yes') }}
|
||||||
|
</option>
|
||||||
|
<option value="0" {{ $attribute->is_filterable ? '' : 'selected' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.no') }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="is_configurable">{{ __('admin::app.catalog.attributes.is_configurable') }}</label>
|
||||||
|
<select class="control" id="is_configurable" name="is_configurable">
|
||||||
|
<option value="1" {{ $attribute->is_configurable ? 'selected' : '' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.yes') }}
|
||||||
|
</option>
|
||||||
|
<option value="0" {{ $attribute->is_configurable ? '' : 'selected' }}>
|
||||||
|
{{ __('admin::app.catalog.attributes.no') }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('javascript')
|
||||||
|
<script type="text/x-template" id="options-template">
|
||||||
|
<div>
|
||||||
|
<div class="table">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
@foreach(Webkul\Core\Models\Locale::all() as $locale)
|
||||||
|
|
||||||
|
<th>{{ $locale->name . ' (' . $locale->code . ')' }}</th>
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<th>{{ __('admin::app.catalog.attributes.position') }}</th>
|
||||||
|
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="row in optionRows">
|
||||||
|
@foreach(Webkul\Core\Models\Locale::all() as $locale)
|
||||||
|
<td>
|
||||||
|
<div class="control-group" :class="[errors.has(localeInputName(row, '{{ $locale->code }}')) ? 'has-error' : '']">
|
||||||
|
<input type="text" v-validate="'required'" v-model="row['{{ $locale->code }}']" :name="localeInputName(row, '{{ $locale->code }}')" class="control"/>
|
||||||
|
<span class="control-error" v-if="errors.has(localeInputName(row, '{{ $locale->code }}'))">@{{ errors.first(localeInputName(row, '{!! $locale->code !!}')) }}</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div class="control-group" :class="[errors.has(sortOrderName(row)) ? 'has-error' : '']">
|
||||||
|
<input type="text" v-validate="'required'" v-model="row['sort_order']" :name="sortOrderName(row)" class="control"/>
|
||||||
|
<span class="control-error" v-if="errors.has(sortOrderName(row))">@{{ errors.first(sortOrderName(row)) }}</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="actions">
|
||||||
|
<i class="icon trash-icon" @click="removeRow(row)"></i>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-lg btn-primary" id="add-option-btn" style="margin-top: 20px" @click="addOptionRow()">
|
||||||
|
{{ __('admin::app.catalog.attributes.add-option-btn-title') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('#type').on('change', function (e) {
|
||||||
|
if(['select', 'multiselect', 'checkbox'].indexOf($(e.target).val()) === -1) {
|
||||||
|
$('#options').parent().addClass('hide')
|
||||||
|
} else {
|
||||||
|
$('#options').parent().removeClass('hide')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var optionWrapper = Vue.component('option-wrapper', {
|
||||||
|
|
||||||
|
template: '#options-template',
|
||||||
|
|
||||||
|
created () {
|
||||||
|
@foreach($attribute->options as $option)
|
||||||
|
this.optionRowCount++;
|
||||||
|
var row = {'id': '{{ $option->id }}', 'sort_order': '{{ $option->sort_order }}'};
|
||||||
|
|
||||||
|
@foreach(Webkul\Core\Models\Locale::all() as $locale)
|
||||||
|
row['{{ $locale->code }}'] = '{{ $option->translate($locale->code)->label }}';
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
this.optionRows.push(row);
|
||||||
|
@endforeach
|
||||||
|
},
|
||||||
|
|
||||||
|
data: () => ({
|
||||||
|
optionRowCount: 0,
|
||||||
|
optionRows: []
|
||||||
|
}),
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
addOptionRow () {
|
||||||
|
var rowCount = this.optionRowCount++;
|
||||||
|
var row = {'id': 'option_' + rowCount};
|
||||||
|
|
||||||
|
@foreach(Webkul\Core\Models\Locale::all() as $locale)
|
||||||
|
row['{{ $locale->code }}'] = '';
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
this.optionRows.push(row);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeRow (row) {
|
||||||
|
var index = this.optionRows.indexOf(row)
|
||||||
|
Vue.delete(this.optionRows, index);
|
||||||
|
},
|
||||||
|
|
||||||
|
localeInputName (row, locale) {
|
||||||
|
return 'options[' + row.id + '][' + locale + '][label]';
|
||||||
|
},
|
||||||
|
|
||||||
|
sortOrderName (row) {
|
||||||
|
return 'options[' + row.id + '][sort_order]';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
el: '#options',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
optionWrapper: optionWrapper
|
||||||
|
},
|
||||||
|
})
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@stop
|
||||||
|
|
@ -0,0 +1,279 @@
|
||||||
|
@extends('admin::layouts.content')
|
||||||
|
|
||||||
|
@section('page_title')
|
||||||
|
{{ __('admin::app.catalog.families.add-title') }}
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="content">
|
||||||
|
<form method="POST" action="{{ route('admin.catalog.families.store') }}">
|
||||||
|
|
||||||
|
<div class="page-header">
|
||||||
|
<div class="page-title">
|
||||||
|
<h1>{{ __('admin::app.catalog.families.add-title') }}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-action">
|
||||||
|
<button type="submit" class="btn btn-lg btn-primary">
|
||||||
|
{{ __('admin::app.catalog.families.save-btn-title') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
|
||||||
|
<div class="form-container">
|
||||||
|
@csrf()
|
||||||
|
|
||||||
|
<accordian :title="'{{ __('admin::app.catalog.families.general') }}'" :active="true">
|
||||||
|
<div slot="body">
|
||||||
|
|
||||||
|
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
|
||||||
|
<label for="code">{{ __('admin::app.catalog.families.code') }}</label>
|
||||||
|
<input type="text" v-validate="'required'" class="control" id="code" name="code" value="{{ old('code') }}"/>
|
||||||
|
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
||||||
|
<label for="name">{{ __('admin::app.catalog.families.name') }}</label>
|
||||||
|
<input type="text" v-validate="'required'" class="control" id="name" name="name" value="{{ old('name') }}"/>
|
||||||
|
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
|
||||||
|
<accordian :title="'{{ __('admin::app.catalog.families.groups') }}'" :active="true">
|
||||||
|
<div slot="body">
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-md btn-primary" @click="showModal('addGroup')">
|
||||||
|
{{ __('admin::app.catalog.families.add-group-title') }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<group-list></group-list>
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<modal id="addGroup" :is-open="modalIds.addGroup">
|
||||||
|
<h3 slot="header">{{ __('admin::app.catalog.families.add-group-title') }}</h3>
|
||||||
|
|
||||||
|
<div slot="body">
|
||||||
|
<group-form></group-form>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('javascript')
|
||||||
|
|
||||||
|
<script type="text/x-template" id="group-form-template">
|
||||||
|
<form method="POST" action="{{ route('admin.catalog.families.store') }}" data-vv-scope="add-group-form" @submit.prevent="addGroup('add-group-form')">
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="form-container">
|
||||||
|
@csrf()
|
||||||
|
|
||||||
|
<div class="control-group" :class="[errors.has('add-group-form.groupName') ? 'has-error' : '']">
|
||||||
|
<label for="groupName">{{ __('admin::app.catalog.families.name') }}</label>
|
||||||
|
<input type="text" v-validate="'required'" v-model="group.groupName" class="control" id="groupName" name="groupName"/>
|
||||||
|
<span class="control-error" v-if="errors.has('add-group-form.groupName')">@{{ errors.first('add-group-form.groupName') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" :class="[errors.has('add-group-form.position') ? 'has-error' : '']">
|
||||||
|
<label for="position">{{ __('admin::app.catalog.families.position') }}</label>
|
||||||
|
<input type="text" v-validate="'required'" v-model="group.position" class="control" id="position" name="position"/>
|
||||||
|
<span class="control-error" v-if="errors.has('add-group-form.position')">@{{ errors.first('add-group-form.position') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-lg btn-primary">
|
||||||
|
{{ __('admin::app.catalog.families.add-group-title') }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/x-template" id="group-list-template">
|
||||||
|
<div>
|
||||||
|
<group-item v-for='(group, index) in groups' :group="group" :attributes="attributes" :key="index" @onRemoveGroup="removeGroup($event)" @onAttributeAdd="addAttributes(index, $event)" @onAttributeRemove="removeAttribute(index, $event)"></group-item>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/x-template" id="group-item-template">
|
||||||
|
<accordian :title="group.groupName" :active="true">
|
||||||
|
<div slot="header">
|
||||||
|
<i class="icon expand-icon left"></i>
|
||||||
|
<h1>@{{ group.groupName }}</h1>
|
||||||
|
<i class="icon trash-icon" @click="removeGroup()"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div slot="body">
|
||||||
|
<div class="table" v-if="group.attributes.length" style="margin-bottom: 20px;">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{ __('admin::app.catalog.families.attribute-code') }}</th>
|
||||||
|
<th>{{ __('admin::app.catalog.families.name') }}</th>
|
||||||
|
<th>{{ __('admin::app.catalog.families.type') }}</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<tr v-for='(attribute, index) in group.attributes'>
|
||||||
|
<td>@{{ attribute.code }}</td>
|
||||||
|
<td>@{{ attribute.name }}</td>
|
||||||
|
<td>@{{ attribute.type }}</td>
|
||||||
|
<td class="actions">
|
||||||
|
<i class="icon trash-icon" @click="removeAttribute(attribute)"></i>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-md btn-primary dropdown-toggle">
|
||||||
|
{{ __('admin::app.catalog.families.add-attribute-title') }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="dropdown-list" style="width: 240px">
|
||||||
|
<div class="search-box">
|
||||||
|
<input type="text" class="control" placeholder="{{ __('admin::app.catalog.families.search') }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dropdown-container">
|
||||||
|
<ul>
|
||||||
|
<li v-for='(attribute, index) in attributes' :data-id="attribute.id">
|
||||||
|
<span class="checkbox">
|
||||||
|
<input type="checkbox" :id="attribute.id" :value="attribute.id"/>
|
||||||
|
<label class="checkbox-view" :for="attribute.id"></label>
|
||||||
|
@{{ attribute.admin_name }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-lg btn-primary" @click="addAttributes($event)">
|
||||||
|
{{ __('admin::app.catalog.families.add-attribute-title') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</accordian>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// $(document).ready(function () {
|
||||||
|
var groups = [];
|
||||||
|
var attributes = @json($attributes);
|
||||||
|
|
||||||
|
Vue.component('group-form', {
|
||||||
|
|
||||||
|
data: () => ({
|
||||||
|
group: {
|
||||||
|
'groupName': '',
|
||||||
|
'position': '',
|
||||||
|
'attributes': []
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
template: '#group-form-template',
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
addGroup (formScope) {
|
||||||
|
this.$validator.validateAll(formScope).then((result) => {
|
||||||
|
if (result) {
|
||||||
|
groups.push(this.group);
|
||||||
|
|
||||||
|
groups = this.sortGroups();
|
||||||
|
|
||||||
|
this.group = {'groupName': '', 'position': '', 'attributes': []};
|
||||||
|
|
||||||
|
this.$parent.closeModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
sortGroups () {
|
||||||
|
return groups.sort(function(a, b) {
|
||||||
|
return a.position - b.position;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Vue.component('group-list', {
|
||||||
|
|
||||||
|
template: '#group-list-template',
|
||||||
|
|
||||||
|
data: () => ({
|
||||||
|
groups: groups,
|
||||||
|
attributes: attributes
|
||||||
|
}),
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
removeGroup (group) {
|
||||||
|
let index = groups.indexOf(group)
|
||||||
|
|
||||||
|
groups.splice(index, 1)
|
||||||
|
},
|
||||||
|
|
||||||
|
addAttributes (groupIndex, attributeIds) {
|
||||||
|
var this_this = this;
|
||||||
|
attributeIds.forEach(function(attributeId) {
|
||||||
|
var attribute = this_this.attributes.filter(attribute => attribute.id == attributeId)
|
||||||
|
|
||||||
|
this_this.groups[groupIndex].attributes.push(attribute[0]);
|
||||||
|
|
||||||
|
let index = this_this.attributes.indexOf(attribute)
|
||||||
|
|
||||||
|
this_this.attributes.splice(index, 1)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
removeAttribute (groupIndex, attribute) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Vue.component('group-item', {
|
||||||
|
props: ['group', 'attributes'],
|
||||||
|
|
||||||
|
template: "#group-item-template",
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
removeGroup () {
|
||||||
|
this.$emit('onRemoveGroup', this.group)
|
||||||
|
},
|
||||||
|
|
||||||
|
addAttributes (e) {
|
||||||
|
var attributeIds = [];
|
||||||
|
|
||||||
|
$(e.target).prev().find('li input').each(function() {
|
||||||
|
var attributeId = $(this).val();
|
||||||
|
if($(this).is(':checked')) {
|
||||||
|
attributeIds.push(attributeId);
|
||||||
|
|
||||||
|
$(this).prop('checked', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('body').trigger('click')
|
||||||
|
|
||||||
|
this.$emit('onAttributeAdd', attributeIds)
|
||||||
|
},
|
||||||
|
|
||||||
|
removeAttribute (attribute) {
|
||||||
|
this.$emit('onAttributeRemove', attributeIds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// });
|
||||||
|
</script>
|
||||||
|
@stop
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
@extends('admin::layouts.content')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="content">
|
||||||
|
<div class="page-header">
|
||||||
|
<div class="page-title">
|
||||||
|
{{ __('admin::app.catalog.families.families') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-action">
|
||||||
|
<a href="{{ route('admin.catalog.families.create') }}" class="btn btn-lg btn-primary">
|
||||||
|
{{ __('admin::app.catalog.families.add-family-btn-title') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@stop
|
||||||
|
|
@ -54,5 +54,6 @@
|
||||||
|
|
||||||
@yield('javascript')
|
@yield('javascript')
|
||||||
|
|
||||||
|
<div class="modal-overlay"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
@csrf()
|
@csrf()
|
||||||
|
|
||||||
<accordian :title="'{{ __('General') }}'" :active="true">
|
<accordian :title="'{{ __('General') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
|
||||||
<label for="code">{{ __('Code') }}</label>
|
<label for="code">{{ __('Code') }}</label>
|
||||||
<input v-validate="'required'" class="control" id="code" name="code"/>
|
<input v-validate="'required'" class="control" id="code" name="code"/>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
@csrf()
|
@csrf()
|
||||||
|
|
||||||
<accordian :title="'{{ __('General') }}'" :active="true">
|
<accordian :title="'{{ __('General') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
||||||
<label for="name">{{ __('Name') }}</label>
|
<label for="name">{{ __('Name') }}</label>
|
||||||
<input type="text" v-validate="'required'" class="control" id="email" name="name"/>
|
<input type="text" v-validate="'required'" class="control" id="email" name="name"/>
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
</accordian>
|
</accordian>
|
||||||
|
|
||||||
<accordian :title="'{{ __('Access Control') }}'" :active="true">
|
<accordian :title="'{{ __('Access Control') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label for="permission_type">{{ __('Permissions') }}</label>
|
<label for="permission_type">{{ __('Permissions') }}</label>
|
||||||
<select class="control" name="permission_type" id="permission_type">
|
<select class="control" name="permission_type" id="permission_type">
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
<input name="_method" type="hidden" value="PUT">
|
<input name="_method" type="hidden" value="PUT">
|
||||||
|
|
||||||
<accordian :title="'{{ __('General') }}'" :active="true">
|
<accordian :title="'{{ __('General') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
||||||
<label for="name">{{ __('Name') }}</label>
|
<label for="name">{{ __('Name') }}</label>
|
||||||
<input type="text" v-validate="'required'" class="control" id="email" name="name" value="{{ $role->name }}"/>
|
<input type="text" v-validate="'required'" class="control" id="email" name="name" value="{{ $role->name }}"/>
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
</accordian>
|
</accordian>
|
||||||
|
|
||||||
<accordian :title="'{{ __('Access Control') }}'" :active="true">
|
<accordian :title="'{{ __('Access Control') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label for="permission_type">{{ __('Permissions') }}</label>
|
<label for="permission_type">{{ __('Permissions') }}</label>
|
||||||
<select class="control" name="permission_type" id="permission_type">
|
<select class="control" name="permission_type" id="permission_type">
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
@csrf()
|
@csrf()
|
||||||
|
|
||||||
<accordian :title="'{{ __('General') }}'" :active="true">
|
<accordian :title="'{{ __('General') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
||||||
<label for="name">{{ __('Name') }}</label>
|
<label for="name">{{ __('Name') }}</label>
|
||||||
<input type="text" v-validate="'required'" class="control" id="email" name="name"/>
|
<input type="text" v-validate="'required'" class="control" id="email" name="name"/>
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
</accordian>
|
</accordian>
|
||||||
|
|
||||||
<accordian :title="'{{ __('Password') }}'" :active="true">
|
<accordian :title="'{{ __('Password') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
|
||||||
<label for="password">{{ __('Password') }}</label>
|
<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|max:18'" class="control" id="password" name="password"/>
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
</accordian>
|
</accordian>
|
||||||
|
|
||||||
<accordian :title="'{{ __('Status and Role') }}'" :active="true">
|
<accordian :title="'{{ __('Status and Role') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('role_id') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('role_id') ? 'has-error' : '']">
|
||||||
<label for="role">{{ __('Role') }}</label>
|
<label for="role">{{ __('Role') }}</label>
|
||||||
<select v-validate="'required'" class="control" name="role_id">
|
<select v-validate="'required'" class="control" name="role_id">
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
<input name="_method" type="hidden" value="PUT">
|
<input name="_method" type="hidden" value="PUT">
|
||||||
|
|
||||||
<accordian :title="'{{ __('General') }}'" :active="true">
|
<accordian :title="'{{ __('General') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
||||||
<label for="name">{{ __('Name') }}</label>
|
<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="email" name="name" value="{{ $user->name }}"/>
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
</accordian>
|
</accordian>
|
||||||
|
|
||||||
<accordian :title="'{{ __('Password') }}'" :active="true">
|
<accordian :title="'{{ __('Password') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
|
||||||
<label for="password">{{ __('Password') }}</label>
|
<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|max:18'" class="control" id="password" name="password"/>
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
</accordian>
|
</accordian>
|
||||||
|
|
||||||
<accordian :title="'{{ __('Status and Role') }}'" :active="true">
|
<accordian :title="'{{ __('Status and Role') }}'" :active="true">
|
||||||
<div class="accordian-content">
|
<div slot="body">
|
||||||
<div class="control-group" :class="[errors.has('role_id') ? 'has-error' : '']">
|
<div class="control-group" :class="[errors.has('role_id') ? 'has-error' : '']">
|
||||||
<label for="role">{{ __('Role') }}</label>
|
<label for="role">{{ __('Role') }}</label>
|
||||||
<select v-validate="'required'" class="control" name="role_id">
|
<select v-validate="'required'" class="control" name="role_id">
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"nwidart/laravel-modules": "^3.2"
|
"nwidart/laravel-modules": "^3.2",
|
||||||
|
"webkul/laravel-core": "dev-master"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,16 @@ class CreateAttributesTable extends Migration
|
||||||
Schema::create('attributes', function (Blueprint $table) {
|
Schema::create('attributes', function (Blueprint $table) {
|
||||||
$table->increments('id');
|
$table->increments('id');
|
||||||
$table->string('code')->unique();
|
$table->string('code')->unique();
|
||||||
$table->string('name');
|
$table->string('admin_name');
|
||||||
$table->string('type');
|
$table->string('type');
|
||||||
$table->string('validation')->nullable();
|
$table->string('validation')->nullable();
|
||||||
$table->integer('position')->nullable();
|
$table->integer('position')->nullable();
|
||||||
$table->boolean('is_required');
|
$table->boolean('is_required')->default(1);
|
||||||
$table->boolean('is_unique');
|
$table->boolean('is_unique')->default(0);
|
||||||
$table->boolean('value_per_locale');
|
$table->boolean('value_per_locale')->default(0);
|
||||||
$table->boolean('value_per_channel');
|
$table->boolean('value_per_channel')->default(0);
|
||||||
$table->boolean('is_filterable');
|
$table->boolean('is_filterable')->default(0);
|
||||||
$table->boolean('is_configurable');
|
$table->boolean('is_configurable')->default(0);
|
||||||
$table->boolean('is_user_defined')->default(1);
|
$table->boolean('is_user_defined')->default(1);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,18 @@ class CreateAttributeGroupsTable extends Migration
|
||||||
$table->increments('id');
|
$table->increments('id');
|
||||||
$table->string('name');
|
$table->string('name');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
$table->integer('sort_order');
|
$table->integer('position');
|
||||||
$table->integer('attribute_family_id')->unsigned();
|
$table->integer('attribute_family_id')->unsigned();
|
||||||
$table->unique(['attribute_family_id', 'name']);
|
$table->unique(['attribute_family_id', 'name']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Schema::create('attribute_group_mappings', function (Blueprint $table) {
|
||||||
|
$table->integer('attribute_id')->unsigned();
|
||||||
|
$table->integer('attribute_group_id')->unsigned();
|
||||||
|
$table->primary(['attribute_id', 'attribute_group_id']);
|
||||||
|
$table->foreign('attribute_id')->references('id')->on('attributes')->onDelete('cascade');
|
||||||
|
$table->foreign('attribute_group_id')->references('id')->on('attribute_groups')->onDelete('cascade');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -31,5 +39,7 @@ class CreateAttributeGroupsTable extends Migration
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('attribute_groups');
|
Schema::dropIfExists('attribute_groups');
|
||||||
|
|
||||||
|
Schema::dropIfExists('attribute_group_mappings');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,8 @@ class CreateAttributeOptionsTable extends Migration
|
||||||
{
|
{
|
||||||
Schema::create('attribute_options', function (Blueprint $table) {
|
Schema::create('attribute_options', function (Blueprint $table) {
|
||||||
$table->increments('id');
|
$table->increments('id');
|
||||||
$table->string('code');
|
|
||||||
$table->integer('sort_order');
|
$table->integer('sort_order');
|
||||||
$table->integer('attribute_id')->unsigned();
|
$table->integer('attribute_id')->unsigned();
|
||||||
$table->unique(['attribute_id', 'code']);
|
|
||||||
$table->foreign('attribute_id')->references('id')->on('attributes')->onDelete('cascade');
|
$table->foreign('attribute_id')->references('id')->on('attributes')->onDelete('cascade');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ namespace Webkul\Attribute\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Webkul\Attribute\Models\Attribute;
|
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Catalog attribute controller
|
* Catalog attribute controller
|
||||||
*
|
*
|
||||||
|
|
@ -19,14 +21,24 @@ class AttributeController extends Controller
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $_config;
|
protected $_config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeRepository object
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $attribute;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new controller instance.
|
* Create a new controller instance.
|
||||||
*
|
*
|
||||||
|
* @param Webkul\Attribute\Repositories\AttributeRepository $attribute
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct(Attribute $attribute)
|
||||||
{
|
{
|
||||||
|
$this->attribute = $attribute;
|
||||||
|
|
||||||
$this->_config = request('_config');
|
$this->_config = request('_config');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,7 +59,7 @@ class AttributeController extends Controller
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
return view($this->_config['view'], compact('roleItems'));
|
return view($this->_config['view']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,11 +71,11 @@ class AttributeController extends Controller
|
||||||
{
|
{
|
||||||
$this->validate(request(), [
|
$this->validate(request(), [
|
||||||
'code' => ['required', 'unique:attributes,code', new \Webkul\Core\Contracts\Validations\Slug],
|
'code' => ['required', 'unique:attributes,code', new \Webkul\Core\Contracts\Validations\Slug],
|
||||||
'name' => 'required',
|
'admin_name' => 'required',
|
||||||
'type' => 'required'
|
'type' => 'required'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Attribute::create(request()->all());
|
$this->attribute->create(request()->all());
|
||||||
|
|
||||||
session()->flash('success', 'Attribute created successfully.');
|
session()->flash('success', 'Attribute created successfully.');
|
||||||
|
|
||||||
|
|
@ -78,9 +90,9 @@ class AttributeController extends Controller
|
||||||
*/
|
*/
|
||||||
public function edit($id)
|
public function edit($id)
|
||||||
{
|
{
|
||||||
$role = Role::findOrFail($id);
|
$attribute = $this->attribute->findOrFail($id);
|
||||||
|
|
||||||
return view($this->_config['view'], compact('role'));
|
return view($this->_config['view'], compact('attribute'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -93,15 +105,14 @@ class AttributeController extends Controller
|
||||||
public function update(Request $request, $id)
|
public function update(Request $request, $id)
|
||||||
{
|
{
|
||||||
$this->validate(request(), [
|
$this->validate(request(), [
|
||||||
'name' => 'required',
|
'code' => ['required', 'unique:attributes,code,' . $id, new \Webkul\Core\Contracts\Validations\Slug],
|
||||||
'permission_type' => 'required',
|
'admin_name' => 'required',
|
||||||
|
'type' => 'required'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$role = Role::findOrFail($id);
|
$this->attribute->update(request()->all(), $id);
|
||||||
|
|
||||||
$role->update(request()->all());
|
session()->flash('success', 'Attribute updated successfully.');
|
||||||
|
|
||||||
session()->flash('success', 'Role updated successfully.');
|
|
||||||
|
|
||||||
return redirect()->route($this->_config['redirect']);
|
return redirect()->route($this->_config['redirect']);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Attribute\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeFamilyRepository as AttributeFamily;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Catalog family controller
|
||||||
|
*
|
||||||
|
* @author Jitendra Singh <jitendra@webkul.com>
|
||||||
|
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||||
|
*/
|
||||||
|
class AttributeFamilyController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Contains route related configuration
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $_config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttributeFamilyRepository object
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $attributeFamily;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @param Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamily
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(AttributeFamily $attributeFamily)
|
||||||
|
{
|
||||||
|
$this->attributeFamily = $attributeFamily;
|
||||||
|
|
||||||
|
$this->_config = request('_config');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view($this->_config['view']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*
|
||||||
|
* @param Webkul\Attribute\Repositories\AttributeRepository $attribute
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function create(Attribute $attribute)
|
||||||
|
{
|
||||||
|
$attributes = $attribute->all(['id', 'code', 'admin_name', 'type']);
|
||||||
|
|
||||||
|
return view($this->_config['view'], compact('attributes'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store()
|
||||||
|
{
|
||||||
|
$this->validate(request(), [
|
||||||
|
'code' => ['required', 'unique:families,code', new \Webkul\Core\Contracts\Validations\Slug],
|
||||||
|
'name' => 'required'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->attributeFamily->create(request()->all());
|
||||||
|
|
||||||
|
session()->flash('success', 'Family created successfully.');
|
||||||
|
|
||||||
|
return redirect()->route($this->_config['redirect']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*
|
||||||
|
* @param Webkul\Attribute\Repositories\AttributeRepository $attribute
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function edit(Attribute $attribute, $id)
|
||||||
|
{
|
||||||
|
$attributeFamily = $this->attributeFamily->findOrFail($id);
|
||||||
|
|
||||||
|
$attributes = $attribute->all(['id', 'code', 'admin_name', 'type']);
|
||||||
|
|
||||||
|
return view($this->_config['view'], compact('attributes', 'family'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function update(Request $request, $id)
|
||||||
|
{
|
||||||
|
$this->validate(request(), [
|
||||||
|
'code' => ['required', 'unique:families,code,' . $id, new \Webkul\Core\Contracts\Validations\Slug],
|
||||||
|
'name' => 'required'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->attributeFamily->update(request()->all(), $id);
|
||||||
|
|
||||||
|
session()->flash('success', 'Family updated successfully.');
|
||||||
|
|
||||||
|
return redirect()->route($this->_config['redirect']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,10 +4,21 @@ namespace Webkul\Attribute\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Dimsav\Translatable\Translatable;
|
use Dimsav\Translatable\Translatable;
|
||||||
|
use Webkul\Attribute\Models\AttributeOption;
|
||||||
|
|
||||||
class Attribute extends Model
|
class Attribute extends Model
|
||||||
{
|
{
|
||||||
use Translatable;
|
use Translatable;
|
||||||
|
|
||||||
public $translatedAttributes = ['name'];
|
public $translatedAttributes = ['name'];
|
||||||
|
|
||||||
|
protected $fillable = ['code', 'admin_name', 'type', 'is_required', 'is_unique', 'value_per_locale', 'value_per_channel', 'is_filterable', 'is_configurable'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the options.
|
||||||
|
*/
|
||||||
|
public function options()
|
||||||
|
{
|
||||||
|
return $this->hasMany(AttributeOption::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,16 @@
|
||||||
namespace Webkul\Attribute\Models;
|
namespace Webkul\Attribute\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Webkul\Attribute\Models\Attribute;
|
||||||
|
use Webkul\Attribute\Models\AttributeGroup;
|
||||||
|
|
||||||
class AttributeFamily extends Model
|
class AttributeFamily extends Model
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Get all of the attributes for the attribute groups.
|
||||||
|
*/
|
||||||
|
public function attributes()
|
||||||
|
{
|
||||||
|
return $this->hasManyThrough(Attribute::class, AttributeGroup::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,15 @@
|
||||||
namespace Webkul\Attribute\Models;
|
namespace Webkul\Attribute\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Webkul\Attribute\Models\Attribute;
|
||||||
|
|
||||||
class AttributeGroup extends Model
|
class AttributeGroup extends Model
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Get the attributes that owns the attribute group.
|
||||||
|
*/
|
||||||
|
public function attributes()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(Attribute::class, 'attribute_group_mappings');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,10 +4,23 @@ namespace Webkul\Attribute\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Dimsav\Translatable\Translatable;
|
use Dimsav\Translatable\Translatable;
|
||||||
|
use Webkul\Attribute\Models\Attribute;
|
||||||
|
|
||||||
class AttributeOption extends Model
|
class AttributeOption extends Model
|
||||||
{
|
{
|
||||||
|
public $timestamps = false;
|
||||||
|
|
||||||
use Translatable;
|
use Translatable;
|
||||||
|
|
||||||
public $translatedAttributes = ['label'];
|
public $translatedAttributes = ['label'];
|
||||||
|
|
||||||
|
protected $fillable = ['sort_order'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the attribute that owns the attribute option.
|
||||||
|
*/
|
||||||
|
public function attribute()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Attribute::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Attribute\Repositories;
|
||||||
|
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeGroupRepository;
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute Reposotory
|
||||||
|
*
|
||||||
|
* @author Jitendra Singh <jitendra@webkul.com>
|
||||||
|
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||||
|
*/
|
||||||
|
class AttributeFamilyRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* AttributeGroupRepository object
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $attributeGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @param Webkul\Attribute\Repositories\AttributeGroupRepository $attributeGroup
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(AttributeGroupRepository $attributeGroup, App $app)
|
||||||
|
{
|
||||||
|
$this->attributeGroup = $attributeGroup;
|
||||||
|
|
||||||
|
parent::__construct($app);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Attribute\Models\AttributeFamily';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function create(array $data)
|
||||||
|
{
|
||||||
|
$family = $this->model->create($data);
|
||||||
|
|
||||||
|
return $attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @param $id
|
||||||
|
* @param string $attribute
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function update(array $data, $id, $attribute = "id")
|
||||||
|
{
|
||||||
|
$family = $this->findOrFail($id);
|
||||||
|
|
||||||
|
$family->update($data);
|
||||||
|
|
||||||
|
return $family;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Attribute\Repositories;
|
||||||
|
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute Group Reposotory
|
||||||
|
*
|
||||||
|
* @author Jitendra Singh <jitendra@webkul.com>
|
||||||
|
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||||
|
*/
|
||||||
|
class AttributeGroupRepository extends Repository
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Attribute\Models\AttributeGroup';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Attribute\Repositories;
|
||||||
|
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute Option Reposotory
|
||||||
|
*
|
||||||
|
* @author Jitendra Singh <jitendra@webkul.com>
|
||||||
|
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||||
|
*/
|
||||||
|
class AttributeOptionRepository extends Repository
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Attribute\Models\AttributeOption';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Attribute\Repositories;
|
||||||
|
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
use Webkul\Attribute\Repositories\AttributeOptionRepository;
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute Reposotory
|
||||||
|
*
|
||||||
|
* @author Jitendra Singh <jitendra@webkul.com>
|
||||||
|
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||||
|
*/
|
||||||
|
class AttributeRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* AttributeOptionRepository object
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $attributeOption;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @param Webkul\Attribute\Repositories\AttributeOptionRepository $attributeOption
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(AttributeOptionRepository $attributeOption, App $app)
|
||||||
|
{
|
||||||
|
$this->attributeOption = $attributeOption;
|
||||||
|
|
||||||
|
parent::__construct($app);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Attribute\Models\Attribute';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function create(array $data)
|
||||||
|
{
|
||||||
|
$attribute = $this->model->create($data);
|
||||||
|
|
||||||
|
if(in_array($attribute->code, ['select', 'multiselect', 'checkbox']) && isset($data['options'])) {
|
||||||
|
foreach ($data['options'] as $key => $option) {
|
||||||
|
$attribute->options()->create($option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @param $id
|
||||||
|
* @param string $attribute
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function update(array $data, $id, $attribute = "id")
|
||||||
|
{
|
||||||
|
$attribute = $this->findOrFail($id);
|
||||||
|
|
||||||
|
$attribute->update($data);
|
||||||
|
|
||||||
|
$previousOptionIds = $attribute->options()->pluck('id');
|
||||||
|
|
||||||
|
if(in_array($attribute->code, ['select', 'multiselect', 'checkbox'])) {
|
||||||
|
if(isset($data['options'])) {
|
||||||
|
foreach ($data['options'] as $optionId => $optionInputs) {
|
||||||
|
if (str_contains($optionId, 'option_')) {
|
||||||
|
$attribute->options()->create($optionInputs);
|
||||||
|
} else {
|
||||||
|
if(($index = $previousOptionIds->search($optionId)) >= 0) {
|
||||||
|
$previousOptionIds->forget($index);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->attributeOption->update($optionInputs, $optionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($previousOptionIds as $optionId) {
|
||||||
|
$this->attributeOption->delete($optionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $attribute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,8 @@ interface RepositoryInterface {
|
||||||
public function delete($id);
|
public function delete($id);
|
||||||
|
|
||||||
public function find($id, $columns = ['*']);
|
public function find($id, $columns = ['*']);
|
||||||
|
|
||||||
|
public function findOrFail($id, $columns = ['*']);
|
||||||
|
|
||||||
public function findBy($field, $value, $columns = ['*']);
|
public function findBy($field, $value, $columns = ['*']);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ abstract class Repository implements RepositoryInterface {
|
||||||
* @param App $app
|
* @param App $app
|
||||||
* @throws \Webkul\Core\Exceptions\RepositoryException
|
* @throws \Webkul\Core\Exceptions\RepositoryException
|
||||||
*/
|
*/
|
||||||
public function __construct(App $app) {
|
public function __construct(App $app)
|
||||||
|
{
|
||||||
$this->app = $app;
|
$this->app = $app;
|
||||||
|
|
||||||
$this->makeModel();
|
$this->makeModel();
|
||||||
|
|
@ -47,25 +48,28 @@ abstract class Repository implements RepositoryInterface {
|
||||||
* @param array $columns
|
* @param array $columns
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function all($columns = ['*']) {
|
public function all($columns = ['*'])
|
||||||
return $this->model->get($columns);
|
{
|
||||||
|
return $this->resetScope()->model->get($columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $perPage
|
* @param int $perPage
|
||||||
* @param array $columns
|
* @param array $columns
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function paginate($perPage = 1, $columns = ['*']) {
|
public function paginate($perPage = 1, $columns = ['*'])
|
||||||
return $this->model->paginate($perPage, $columns);
|
{
|
||||||
|
return $this->resetScope()->model->paginate($perPage, $columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function create(array $data) {
|
public function create(array $data)
|
||||||
return $this->model->create($data);
|
{
|
||||||
|
return $this->resetScope()->model->create($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -74,16 +78,18 @@ abstract class Repository implements RepositoryInterface {
|
||||||
* @param string $attribute
|
* @param string $attribute
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function update(array $data, $id, $attribute="id") {
|
public function update(array $data, $id, $attribute = "id")
|
||||||
return $this->model->where($attribute, '=', $id)->update($data);
|
{
|
||||||
|
return $this->resetScope()->model->where($attribute, '=', $id)->first()->update($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $id
|
* @param $id
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function delete($id) {
|
public function delete($id)
|
||||||
return $this->model->destroy($id);
|
{
|
||||||
|
return $this->resetScope()->find($id)->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -91,8 +97,19 @@ abstract class Repository implements RepositoryInterface {
|
||||||
* @param array $columns
|
* @param array $columns
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function find($id, $columns = ['*']) {
|
public function find($id, $columns = ['*'])
|
||||||
return $this->model->find($id, $columns);
|
{
|
||||||
|
return $this->resetScope()->model->find($id, $columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $id
|
||||||
|
* @param array $columns
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function findOrFail($id, $columns = ['*'])
|
||||||
|
{
|
||||||
|
return $this->resetScope()->model->findOrFail($id, $columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -101,15 +118,17 @@ abstract class Repository implements RepositoryInterface {
|
||||||
* @param array $columns
|
* @param array $columns
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function findBy($attribute, $value, $columns = ['*']) {
|
public function findBy($attribute, $value, $columns = ['*'])
|
||||||
return $this->model->where($attribute, '=', $value)->first($columns);
|
{
|
||||||
|
return $this->resetScope()->model->where($attribute, '=', $value)->first($columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Illuminate\Database\Eloquent\Builder
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
* @throws RepositoryException
|
* @throws RepositoryException
|
||||||
*/
|
*/
|
||||||
public function makeModel() {
|
public function makeModel()
|
||||||
|
{
|
||||||
$model = $this->app->make($this->model());
|
$model = $this->app->make($this->model());
|
||||||
|
|
||||||
if (!$model instanceof Model)
|
if (!$model instanceof Model)
|
||||||
|
|
@ -117,4 +136,13 @@ abstract class Repository implements RepositoryInterface {
|
||||||
|
|
||||||
return $this->model = $model->newQuery();
|
return $this->model = $model->newQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function resetScope() {
|
||||||
|
$this->makeModel();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,4 +3,5 @@ Vue.component('flash', require('./components/flash'))
|
||||||
Vue.component('accordian', require('./components/accordian'))
|
Vue.component('accordian', require('./components/accordian'))
|
||||||
Vue.component('tree-view', require('./components/tree-view/tree-view'))
|
Vue.component('tree-view', require('./components/tree-view/tree-view'))
|
||||||
Vue.component('tree-item', require('./components/tree-view/tree-item'))
|
Vue.component('tree-item', require('./components/tree-view/tree-item'))
|
||||||
Vue.component('tree-checkbox', require('./components/tree-view/tree-checkbox'))
|
Vue.component('tree-checkbox', require('./components/tree-view/tree-checkbox'))
|
||||||
|
Vue.component('modal', require('./components/modal'))
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="accordian" :class="[isActive ? 'active' : '', className]" :id="id">
|
<div class="accordian" :class="[isActive ? 'active' : '', className]" :id="id">
|
||||||
<div class="accordian-header" @click="toggleAccordion()">
|
<div class="accordian-header" @click="toggleAccordion()">
|
||||||
{{ title }}
|
<slot name="header">
|
||||||
<i class="icon" :class="iconClass"></i>
|
{{ title }}
|
||||||
|
<i class="icon" :class="iconClass"></i>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="accordian-content">
|
||||||
|
<slot name="body">
|
||||||
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<slot></slot>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
<template>
|
||||||
|
<div class="modal-container" v-if="isModalOpen">
|
||||||
|
<div class="modal-header">
|
||||||
|
<slot name="header">
|
||||||
|
Default header
|
||||||
|
</slot>
|
||||||
|
<i class="icon remove-icon" @click="closeModal"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<slot name="body">
|
||||||
|
Default body
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ['id', 'isOpen'],
|
||||||
|
|
||||||
|
created () {
|
||||||
|
this.closeModal();
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
isModalOpen () {
|
||||||
|
this.addClassToBody();
|
||||||
|
|
||||||
|
return this.isOpen;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
closeModal () {
|
||||||
|
this.$root.$set(this.$root.modalIds, this.id, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
addClassToBody () {
|
||||||
|
var body = document.querySelector("body");
|
||||||
|
if(this.isOpen) {
|
||||||
|
body.classList.add("modal-open");
|
||||||
|
} else {
|
||||||
|
body.classList.remove("modal-open");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
window.jQuery = window.$ = $ = require('jquery');
|
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
$(document).click(function(e) {
|
$(document).click(function(e) {
|
||||||
var target = e.target;
|
var target = e.target;
|
||||||
|
|
@ -29,6 +27,31 @@ $(function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('.dropdown-list .search-box .control').on('input', function() {
|
||||||
|
var currentElement = $(this);
|
||||||
|
currentElement.parents(".dropdown-list").find('li').each(function() {
|
||||||
|
var text = $(this).text().trim().toLowerCase();
|
||||||
|
var value = $(this).attr('data-id');
|
||||||
|
if(value) {
|
||||||
|
var isTextContained = text.search(currentElement.val().toLowerCase());
|
||||||
|
var isValueContained = value.search(currentElement.val());
|
||||||
|
if(isTextContained < 0 && isValueContained < 0) {
|
||||||
|
$(this).hide();
|
||||||
|
} else {
|
||||||
|
$(this).show();
|
||||||
|
flag = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var isTextContained = text.search(currentElement.val().toLowerCase());
|
||||||
|
if(isTextContained < 0) {
|
||||||
|
$(this).hide();
|
||||||
|
} else {
|
||||||
|
$(this).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function autoDropupDropdown() {
|
function autoDropupDropdown() {
|
||||||
dropdown = $(".dropdown-open");
|
dropdown = $(".dropdown-open");
|
||||||
if(!dropdown.find('.dropdown-list').hasClass('top-left') && !dropdown.find('.dropdown-list').hasClass('top-right') && dropdown.length) {
|
if(!dropdown.find('.dropdown-list').hasClass('top-left') && !dropdown.find('.dropdown-list').hasClass('top-right') && dropdown.length) {
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ h2 {
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
@include box-shadow(0 1px 4px 0 rgba(0, 0, 0, 0.20), 0 0 8px 0 rgba(0, 0, 0, 0.10));
|
@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;
|
@include border-radius(3px);
|
||||||
border: none;
|
border: none;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
@ -93,8 +93,9 @@ h2 {
|
||||||
}
|
}
|
||||||
.dropdown-list {
|
.dropdown-list {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
|
margin-bottom: 20px;
|
||||||
@include box-shadow(0 2px 4px 0 rgba(0,0,0,0.16), 0 0 9px 0 rgba(0,0,0,0.16));
|
@include box-shadow(0 2px 4px 0 rgba(0,0,0,0.16), 0 0 9px 0 rgba(0,0,0,0.16));
|
||||||
border-radius: 3px;
|
@include border-radius(3px);
|
||||||
background-color: #FFFFFF;
|
background-color: #FFFFFF;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: none;
|
display: none;
|
||||||
|
|
@ -118,6 +119,28 @@ h2 {
|
||||||
right: 0px;
|
right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
padding: 20px;
|
||||||
|
border-bottom: 1px solid $border-color;
|
||||||
|
|
||||||
|
.control {
|
||||||
|
background: #fff;
|
||||||
|
border: 2px solid $control-border-color;
|
||||||
|
@include border-radius(3px);
|
||||||
|
width: 100%;
|
||||||
|
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;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: $brand-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown-container {
|
.dropdown-container {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
@ -140,10 +163,9 @@ h2 {
|
||||||
li {
|
li {
|
||||||
padding: 5px 0px;
|
padding: 5px 0px;
|
||||||
|
|
||||||
&:hover {
|
// &:hover {
|
||||||
color: $brand-color;
|
// color: $brand-color;
|
||||||
cursor: pointer;
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
a:link, a:active, a:visited, a:focus {
|
a:link, a:active, a:visited, a:focus {
|
||||||
color: #333333;
|
color: #333333;
|
||||||
|
|
@ -152,8 +174,17 @@ h2 {
|
||||||
a:hover {
|
a:hover {
|
||||||
color: $brand-color;
|
color: $brand-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,6 +208,25 @@ h2 {
|
||||||
padding: 12px 10px;
|
padding: 12px 10px;
|
||||||
border-bottom: solid 1px #D3D3D3;
|
border-bottom: solid 1px #D3D3D3;
|
||||||
color: #3A3A3A;
|
color: #3A3A3A;
|
||||||
|
vertical-align: top;
|
||||||
|
|
||||||
|
&.actions {
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-group {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
.control {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -186,7 +236,7 @@ h2 {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
border: 2px solid $control-border-color;
|
border: 2px solid $control-border-color;
|
||||||
border-radius: 3px;
|
@include border-radius(3px);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #8E8E8E;
|
color: #8E8E8E;
|
||||||
padding: 8px 35px 8px 10px;
|
padding: 8px 35px 8px 10px;
|
||||||
|
|
@ -210,7 +260,7 @@ h2 {
|
||||||
.page-item {
|
.page-item {
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
border: 2px solid $control-border-color;
|
border: 2px solid $control-border-color;
|
||||||
border-radius: 3px;
|
@include border-radius(3px);
|
||||||
padding: 7px 14px;
|
padding: 7px 14px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
@ -325,7 +375,7 @@ h2 {
|
||||||
.control {
|
.control {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 2px solid $control-border-color;
|
border: 2px solid $control-border-color;
|
||||||
border-radius: 3px;
|
@include border-radius(3px);
|
||||||
width: 70%;
|
width: 70%;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
@ -379,9 +429,9 @@ h2 {
|
||||||
.alert {
|
.alert {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
border-radius: 3px;
|
@include border-radius(3px);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
box-shadow: 0px 4px 15.36px 0.64px rgba(0, 0, 0, 0.1), 0px 2px 6px 0px rgba(0, 0, 0, 0.12);
|
@include box-shadow(0px 4px 15.36px 0.64px rgba(0, 0, 0, 0.1), 0px 2px 6px 0px rgba(0, 0, 0, 0.12));
|
||||||
position: relative;
|
position: relative;
|
||||||
animation: jelly 0.5s ease-in-out;
|
animation: jelly 0.5s ease-in-out;
|
||||||
transform-origin: center top;
|
transform-origin: center top;
|
||||||
|
|
@ -448,20 +498,41 @@ h2 {
|
||||||
padding: 20px 15px;
|
padding: 20px 15px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
.expand-icon {
|
||||||
|
background-image: url('../images/Expand-Light.svg');
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
float: right;
|
float: right;
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordian-content {
|
.accordian-content {
|
||||||
|
width: 100%;
|
||||||
padding: 20px 15px;
|
padding: 20px 15px;
|
||||||
display: none;
|
display: none;
|
||||||
transition: 0.3s ease all;
|
transition: 0.3s ease all;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active .accordian-content {
|
&.active > .accordian-content {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.active > .accordian-header .expand-icon {
|
||||||
|
background-image: url('../images/Expand-Light-On.svg');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-container {
|
.tree-container {
|
||||||
|
|
@ -508,11 +579,71 @@ h2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel {
|
.panel {
|
||||||
box-shadow: 0 2px 25px 0 rgba(0,0,0,0.15);
|
@include box-shadow(0 2px 25px 0 rgba(0,0,0,0.15));
|
||||||
border-radius: 5px;
|
@include border-radius(5px);
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|
||||||
.panel-content {
|
.panel-content {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-open {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-overlay {
|
||||||
|
display: none;
|
||||||
|
overflow-y: auto;
|
||||||
|
z-index: 10;
|
||||||
|
top: 0px;
|
||||||
|
right: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0px;
|
||||||
|
position: fixed;
|
||||||
|
background: #000;
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
.modal-open .modal-overlay {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container {
|
||||||
|
animation: fade-in-white 0.3s ease-in-out;
|
||||||
|
z-index: 11;
|
||||||
|
margin-left: -350px;
|
||||||
|
width: 600px;
|
||||||
|
max-width: 80%;
|
||||||
|
background: #FFFFFF;
|
||||||
|
position: fixed;
|
||||||
|
left: 50%;
|
||||||
|
top: 100px;
|
||||||
|
margin-bottom: 100px;
|
||||||
|
@include box-shadow(0px 15px 25px 0px rgba(0, 0, 0, 0.03), 0px 20px 45px 5px rgba(0, 0, 0, 0.2));
|
||||||
|
animation: jelly 0.5s ease-in-out;
|
||||||
|
@include border-radius(5px);
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #3A3A3A;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
.control-group .control {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -110,6 +110,12 @@
|
||||||
height: 24px;
|
height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.expand-icon {
|
||||||
|
background-image: url('../images/Expand-Light.svg');
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
.dashboard-icon {
|
.dashboard-icon {
|
||||||
background-image: url('../images/Icon-Dashboard-Active.svg');
|
background-image: url('../images/Icon-Dashboard-Active.svg');
|
||||||
|
|
@ -133,6 +139,10 @@
|
||||||
height: 8px;
|
height: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.expand-icon {
|
||||||
|
background-image: url('../images/Expand-Light-On.svg');
|
||||||
|
}
|
||||||
|
|
||||||
&.dashboard-icon {
|
&.dashboard-icon {
|
||||||
background-image: url('../images/Icon-Dashboard-Active.svg');
|
background-image: url('../images/Icon-Dashboard-Active.svg');
|
||||||
}
|
}
|
||||||
|
|
@ -151,4 +161,8 @@
|
||||||
width: 14px;
|
width: 14px;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.expand-icon {
|
||||||
|
background-image: url('../images/Expand-Light-On.svg');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -311,22 +311,22 @@
|
||||||
<label class="styleguide-label">Icons</label>
|
<label class="styleguide-label">Icons</label>
|
||||||
<div class="styleguide-wrapper">
|
<div class="styleguide-wrapper">
|
||||||
<span class="icon-wrapper">
|
<span class="icon-wrapper">
|
||||||
<i class="icon icon-dashboard"></i>
|
<i class="icon dashboard-icon"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="icon-wrapper">
|
<span class="icon-wrapper">
|
||||||
<i class="icon icon-dashboard active"></i>
|
<i class="icon dashboard-icon active"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="icon-wrapper">
|
<span class="icon-wrapper">
|
||||||
<i class="icon icon-configuration"></i>
|
<i class="icon configuration-icon"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="icon-wrapper">
|
<span class="icon-wrapper">
|
||||||
<i class="icon icon-configuration active"></i>
|
<i class="icon configuration-icon active"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="icon-wrapper">
|
<span class="icon-wrapper">
|
||||||
<i class="icon icon-settings"></i>
|
<i class="icon settings-icon"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="icon-wrapper">
|
<span class="icon-wrapper">
|
||||||
<i class="icon icon-settings active"></i>
|
<i class="icon settings-icon active"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="icon-wrapper">
|
<span class="icon-wrapper">
|
||||||
<i class="icon angle-right-icon"></i>
|
<i class="icon angle-right-icon"></i>
|
||||||
|
|
|
||||||
|
|
@ -28,5 +28,4 @@ class Role extends Model
|
||||||
{
|
{
|
||||||
return $this->hasMany(Admin::class);
|
return $this->hasMany(Admin::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,6 @@
|
||||||
right: 0;
|
right: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
z-index: 1;
|
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
@ -144,7 +143,6 @@
|
||||||
|
|
||||||
.content-container .content-wrapper {
|
.content-container .content-wrapper {
|
||||||
padding: 25px 25px 25px 305px;
|
padding: 25px 25px 25px 305px;
|
||||||
overflow-y: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-container .content {
|
.content-container .content {
|
||||||
|
|
|
||||||
|
|
@ -109,14 +109,21 @@ window.VeeValidate = __webpack_require__(8);
|
||||||
Vue.use(VeeValidate);
|
Vue.use(VeeValidate);
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
Vue.config.ignoredElements = ['option-wrapper', 'group-form', 'group-list'];
|
||||||
|
|
||||||
var app = new Vue({
|
var app = new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
|
|
||||||
|
data: {
|
||||||
|
modalIds: {}
|
||||||
|
},
|
||||||
|
|
||||||
mounted: function mounted() {
|
mounted: function mounted() {
|
||||||
this.addServerErrors();
|
this.addServerErrors();
|
||||||
this.addFlashMessages();
|
this.addFlashMessages();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
onSubmit: function onSubmit(e) {
|
onSubmit: function onSubmit(e) {
|
||||||
this.$validator.validateAll().then(function (result) {
|
this.$validator.validateAll().then(function (result) {
|
||||||
|
|
@ -125,7 +132,6 @@ $(document).ready(function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
addServerErrors: function addServerErrors() {
|
addServerErrors: function addServerErrors() {
|
||||||
var scope = null;
|
var scope = null;
|
||||||
for (var key in serverErrors) {
|
for (var key in serverErrors) {
|
||||||
|
|
@ -140,13 +146,15 @@ $(document).ready(function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
addFlashMessages: function addFlashMessages() {
|
addFlashMessages: function addFlashMessages() {
|
||||||
var flashes = this.$refs.flashes;
|
var flashes = this.$refs.flashes;
|
||||||
|
|
||||||
flashMessages.forEach(function (flash) {
|
flashMessages.forEach(function (flash) {
|
||||||
flashes.addFlash(flash);
|
flashes.addFlash(flash);
|
||||||
}, this);
|
}, this);
|
||||||
|
},
|
||||||
|
showModal: function showModal(id) {
|
||||||
|
this.$set(this.modalIds, id, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,12 @@
|
||||||
height: 24px;
|
height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.expand-icon {
|
||||||
|
background-image: url("../images/Expand-Light.svg");
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
.active .dashboard-icon {
|
.active .dashboard-icon {
|
||||||
background-image: url("../images/Icon-Dashboard-Active.svg");
|
background-image: url("../images/Icon-Dashboard-Active.svg");
|
||||||
}
|
}
|
||||||
|
|
@ -133,6 +139,10 @@
|
||||||
height: 8px;
|
height: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.active .expand-icon {
|
||||||
|
background-image: url("../images/Expand-Light-On.svg");
|
||||||
|
}
|
||||||
|
|
||||||
.active.dashboard-icon {
|
.active.dashboard-icon {
|
||||||
background-image: url("../images/Icon-Dashboard-Active.svg");
|
background-image: url("../images/Icon-Dashboard-Active.svg");
|
||||||
}
|
}
|
||||||
|
|
@ -151,6 +161,10 @@
|
||||||
height: 8px;
|
height: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.active.expand-icon {
|
||||||
|
background-image: url("../images/Expand-Light-On.svg");
|
||||||
|
}
|
||||||
|
|
||||||
@-webkit-keyframes jelly {
|
@-webkit-keyframes jelly {
|
||||||
0% {
|
0% {
|
||||||
-webkit-transform: translateY(0px) scale(0.7);
|
-webkit-transform: translateY(0px) scale(0.7);
|
||||||
|
|
@ -318,6 +332,7 @@ h2 {
|
||||||
|
|
||||||
.dropdown-list {
|
.dropdown-list {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
|
margin-bottom: 20px;
|
||||||
-webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16), 0 0 9px 0 rgba(0, 0, 0, 0.16);
|
-webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16), 0 0 9px 0 rgba(0, 0, 0, 0.16);
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16), 0 0 9px 0 rgba(0, 0, 0, 0.16);
|
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16), 0 0 9px 0 rgba(0, 0, 0, 0.16);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
@ -348,6 +363,29 @@ h2 {
|
||||||
right: 0px;
|
right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown-list .search-box {
|
||||||
|
padding: 20px;
|
||||||
|
border-bottom: 1px solid rgba(162, 162, 162, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-list .search-box .control {
|
||||||
|
background: #fff;
|
||||||
|
border: 2px solid #C7C7C7;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%;
|
||||||
|
height: 36px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
-webkit-transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
padding: 0px 10px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-list .search-box .control:focus {
|
||||||
|
border-color: #0041FF;
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown-list .dropdown-container {
|
.dropdown-list .dropdown-container {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
@ -373,11 +411,6 @@ h2 {
|
||||||
padding: 5px 0px;
|
padding: 5px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-list .dropdown-container ul li:hover {
|
|
||||||
color: #0041FF;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-list .dropdown-container ul li a:link, .dropdown-list .dropdown-container ul li a:active, .dropdown-list .dropdown-container ul li a:visited, .dropdown-list .dropdown-container ul li a:focus {
|
.dropdown-list .dropdown-container ul li a:link, .dropdown-list .dropdown-container ul li a:active, .dropdown-list .dropdown-container ul li a:visited, .dropdown-list .dropdown-container ul li a:focus {
|
||||||
color: #333333;
|
color: #333333;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
@ -387,6 +420,15 @@ h2 {
|
||||||
color: #0041FF;
|
color: #0041FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown-list .dropdown-container ul li .checkbox {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-list .dropdown-container .btn {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.table {
|
.table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|
@ -409,6 +451,25 @@ h2 {
|
||||||
padding: 12px 10px;
|
padding: 12px 10px;
|
||||||
border-bottom: solid 1px #D3D3D3;
|
border-bottom: solid 1px #D3D3D3;
|
||||||
color: #3A3A3A;
|
color: #3A3A3A;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table table tbody td.actions {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table table tbody td.actions .icon {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table .control-group {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table .control-group .control {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-btn {
|
.dropdown-btn {
|
||||||
|
|
@ -612,7 +673,7 @@ h2 {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
-webkit-box-shadow: 0px 4px 15.36px 0.64px rgba(0, 0, 0, 0.1), 0px 2px 6px 0px rgba(0, 0, 0, 0.12);
|
-webkit-box-shadow: 0px 4px 15.36px 0.64px rgba(0, 0, 0, 0.1), 0px 2px 6px 0px rgba(0, 0, 0, 0.12);
|
||||||
box-shadow: 0px 4px 15.36px 0.64px rgba(0, 0, 0, 0.1), 0px 2px 6px 0px rgba(0, 0, 0, 0.12);
|
box-shadow: 0px 4px 15.36px 0.64px rgba(0, 0, 0, 0.1), 0px 2px 6px 0px rgba(0, 0, 0, 0.12);
|
||||||
position: relative;
|
position: relative;
|
||||||
-webkit-animation: jelly 0.5s ease-in-out;
|
-webkit-animation: jelly 0.5s ease-in-out;
|
||||||
animation: jelly 0.5s ease-in-out;
|
animation: jelly 0.5s ease-in-out;
|
||||||
|
|
@ -677,21 +738,42 @@ h2 {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.accordian .accordian-header .expand-icon {
|
||||||
|
background-image: url("../images/Expand-Light.svg");
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordian .accordian-header h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.accordian .accordian-header .icon {
|
.accordian .accordian-header .icon {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.accordian .accordian-header .icon.left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
.accordian .accordian-content {
|
.accordian .accordian-content {
|
||||||
|
width: 100%;
|
||||||
padding: 20px 15px;
|
padding: 20px 15px;
|
||||||
display: none;
|
display: none;
|
||||||
-webkit-transition: 0.3s ease all;
|
-webkit-transition: 0.3s ease all;
|
||||||
transition: 0.3s ease all;
|
transition: 0.3s ease all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordian.active .accordian-content {
|
.accordian.active > .accordian-content {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.accordian.active > .accordian-header .expand-icon {
|
||||||
|
background-image: url("../images/Expand-Light-On.svg");
|
||||||
|
}
|
||||||
|
|
||||||
.tree-container .tree-item {
|
.tree-container .tree-item {
|
||||||
padding-left: 30px;
|
padding-left: 30px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
@ -732,7 +814,7 @@ h2 {
|
||||||
|
|
||||||
.panel {
|
.panel {
|
||||||
-webkit-box-shadow: 0 2px 25px 0 rgba(0, 0, 0, 0.15);
|
-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);
|
box-shadow: 0 2px 25px 0 rgba(0, 0, 0, 0.15);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
@ -740,3 +822,67 @@ h2 {
|
||||||
.panel .panel-content {
|
.panel .panel-content {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-open {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-overlay {
|
||||||
|
display: none;
|
||||||
|
overflow-y: auto;
|
||||||
|
z-index: 10;
|
||||||
|
top: 0px;
|
||||||
|
right: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0px;
|
||||||
|
position: fixed;
|
||||||
|
background: #000;
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-open .modal-overlay {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container {
|
||||||
|
-webkit-animation: fade-in-white 0.3s ease-in-out;
|
||||||
|
animation: fade-in-white 0.3s ease-in-out;
|
||||||
|
z-index: 11;
|
||||||
|
margin-left: -350px;
|
||||||
|
width: 600px;
|
||||||
|
max-width: 80%;
|
||||||
|
background: #FFFFFF;
|
||||||
|
position: fixed;
|
||||||
|
left: 50%;
|
||||||
|
top: 100px;
|
||||||
|
margin-bottom: 100px;
|
||||||
|
-webkit-box-shadow: 0px 15px 25px 0px rgba(0, 0, 0, 0.03), 0px 20px 45px 5px rgba(0, 0, 0, 0.2);
|
||||||
|
box-shadow: 0px 15px 25px 0px rgba(0, 0, 0, 0.03), 0px 20px 45px 5px rgba(0, 0, 0, 0.2);
|
||||||
|
-webkit-animation: jelly 0.5s ease-in-out;
|
||||||
|
animation: jelly 0.5s ease-in-out;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container .modal-header {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container .modal-header h3 {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #3A3A3A;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container .modal-header .icon {
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container .modal-body {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container .modal-body .control-group .control {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue