menu brand links test ready

This commit is contained in:
merdan 2022-09-23 16:00:12 +05:00
parent a7ad32190d
commit aaff314fb3
9 changed files with 204 additions and 186 deletions

View File

@ -39,12 +39,7 @@ class SearchController extends V1Controller
}
private function searchBrands($key){
$brands = $this->brandRepository->getModel()::search(implode(' OR ', $key))
// ->where('status',1)
// ->orderBy('name','asc')
->take(10)
->query(fn ($query) => $query->select('id','name')->orderBy('name'))
->get();
$brands = $this->brandRepository->search($key);
if($brands->count()){
$brands->flatMap(fn ($val) => $val['suggestion_type']='brand');

View File

@ -5,6 +5,7 @@ use Sarga\Admin\DataGrids\MenuDataGrid;
use Sarga\Admin\Http\Requests\MenuRequest;
use Sarga\Shop\Repositories\CategoryRepository;
use Sarga\Shop\Repositories\MenuRepository;
use Sarga\Brand\Repositories\BrandRepository;
use Webkul\Admin\Http\Controllers\Controller;
class Menus extends Controller
@ -53,10 +54,27 @@ class Menus extends Controller
}
public function update(MenuRequest $request,$id){
$menu = $this->categoryRepository->update($request->all(), $id);
$menu = $this->mRepository->update($request->all(), $id);
session()->flash('success', trans('admin::app.response.update-success', ['name' => 'Menu']));
return redirect()->route($this->_config['redirect']);
}
public function brands(BrandRepository $repository){
if (request()->ajax()) {
$results = [];
foreach ($repository->search(request()->input('query')) as $row) {
$results[] = [
'id' => $row->id,
'name' => $row->name,
];
}
return response()->json($results);
} else {
return view($this->_config['view']);
}
}
}

View File

@ -184,18 +184,22 @@ return [
],
'catalog' => [
'menus' => [
'title' => 'Menus',
'add-title' => 'Add Menu',
'edit-title' => 'Edit Menu',
'save-btn-title' => 'Save Menu',
'general' => 'General',
'name' => 'Name',
'visible-in-menu' => 'Visible In Menu',
'yes' => 'Yes',
'no' => 'No',
'position' => 'Position',
'description' => 'Description',
'categories' => 'Categories'
'title' => 'Menus',
'add-title' => 'Add Menu',
'edit-title' => 'Edit Menu',
'save-btn-title' => 'Save Menu',
'general' => 'General',
'name' => 'Name',
'visible-in-menu' => 'Visible In Menu',
'yes' => 'Yes',
'no' => 'No',
'position' => 'Position',
'description' => 'Description',
'categories' => 'Categories',
'brands' => 'Brands',
'brand-search-hint' => 'Brand search hint',
'no-result-found' => 'No result found',
'searching' => 'Searching',
],
]
];

View File

@ -29,38 +29,38 @@
<input type="hidden" name="locale" value="all"/>
<accordian title="{{ __('sarga::app.catalog.categories.general') }}" :active="true">
<accordian title="{{ __('sarga::app.catalog.menus.general') }}" :active="true">
<div slot="body">
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="name" class="required">{{ __('sarga::app.catalog.categories.name') }}</label>
<input type="text" v-validate="'required'" class="control" id="name" name="name" value="{{ old('name') }}" data-vv-as="&quot;{{ __('sarga::app.catalog.categories.name') }}&quot;" v-slugify-target="'slug'"/>
<label for="name" class="required">{{ __('sarga::app.catalog.menus.name') }}</label>
<input type="text" v-validate="'required'" class="control" id="name" name="name" value="{{ old('name') }}" data-vv-as="&quot;{{ __('sarga::app.catalog.menus.name') }}&quot;" v-slugify-target="'slug'"/>
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
<div class="control-group" :class="[errors.has('status') ? 'has-error' : '']">
<label for="status" class="required">{{ __('sarga::app.catalog.categories.visible-in-menu') }}</label>
<select class="control" v-validate="'required'" id="status" name="status" data-vv-as="&quot;{{ __('sarga::app.catalog.categories.visible-in-menu') }}&quot;">
<label for="status" class="required">{{ __('sarga::app.catalog.menus.visible-in-menu') }}</label>
<select class="control" v-validate="'required'" id="status" name="status" data-vv-as="&quot;{{ __('sarga::app.catalog.menus.visible-in-menu') }}&quot;">
<option value="1">
{{ __('sarga::app.catalog.categories.yes') }}
{{ __('sarga::app.catalog.menus.yes') }}
</option>
<option value="0">
{{ __('sarga::app.catalog.categories.no') }}
{{ __('sarga::app.catalog.menus.no') }}
</option>
</select>
<span class="control-error" v-if="errors.has('status')">@{{ errors.first('status') }}</span>
</div>
<div class="control-group" :class="[errors.has('position') ? 'has-error' : '']">
<label for="position" class="required">{{ __('sarga::app.catalog.categories.position') }}</label>
<input type="text" v-validate="'required|numeric'" class="control" id="position" name="position" value="{{ old('position') }}" data-vv-as="&quot;{{ __('sarga::app.catalog.categories.position') }}&quot;"/>
<label for="position" class="required">{{ __('sarga::app.catalog.menus.position') }}</label>
<input type="text" v-validate="'required|numeric'" class="control" id="position" name="position" value="{{ old('position') }}" data-vv-as="&quot;{{ __('sarga::app.catalog.menus.position') }}&quot;"/>
<span class="control-error" v-if="errors.has('position')">@{{ errors.first('position') }}</span>
</div>
</div>
</accordian>
<accordian title="{{ __('sarga::app.catalog.categories.description-and-images') }}" :active="true">
<accordian title="{{ __('sarga::app.catalog.menus.description') }}" :active="true">
<div slot="body">
<description></description>

View File

@ -56,7 +56,7 @@
<input name="_method" type="hidden" value="PUT">
<accordian title="{{ __('sarga::app.catalog.categories.general') }}" :active="true">
<accordian title="{{ __('sarga::app.catalog.menus.general') }}" :active="true">
<div slot="body">
<div class="control-group" :class="[errors.has('{{$locale}}[name]') ? 'has-error' : '']">
<label for="name" class="required">{{ __('sarga::app.catalog.menus.name') }}
@ -90,15 +90,16 @@
</div>
</accordian>
<accordian title="{{ __('sarga::app.catalog.menus.description-and-images') }}" :active="true">
<accordian title="{{ __('sarga::app.catalog.menus.description') }}" :active="true">
<div slot="body">
<description></description>
</div>
</accordian>
@include('sarga::catalog.menus.menu-brand-links')
@if ($categories->count())
<accordian title="{{ __('sarga::app.catalog.menus.parent-category') }}" :active="true">
<accordian title="{{ __('sarga::app.catalog.menus.categories') }}" :active="true">
<div slot="body">
<tree-view behavior="normal" value-field="id" name-field="categories" input-type="checkbox" value='@json($menu->categories->pluck("id"))'
items='@json($categories)' fallback-locale="{{ config('app.fallback_locale') }}"></tree-view>

View File

@ -0,0 +1,140 @@
<accordian title="{{ __('sarga::app.catalog.menus.brands') }}" :active="false">
<div slot="body">
<linked-brands></linked-brands>
</div>
</accordian>
@push('scripts')
<script type="text/x-template" id="linked-brands-template">
<div>
<div class="control-group" >
<input type="text" class="control" autocomplete="off" v-model="search_term" placeholder="{{ __('sarga::app.catalog.menus.brand-search-hint') }}" v-on:keyup="search()">
<div class="linked-product-search-result">
<ul>
<li v-for='(brand, index) in brands' v-if=brands.length' @click="addBrand(brand, key)">
@{{ brand.name }}
</li>
<li v-if='! brands.length && search_term.length && ! is_searching'>
{{ __('sarga::app.catalog.menus.no-result-found') }}
</li>
<li v-if="is_searching && search_term.length">
{{ __('sarga::app.catalog.menus.searching') }}
</li>
</ul>
</div>
<input type="hidden" name="brands[]" v-for='(brand, index) in addedBrands' v-if="addedBrands.length" :value="brand.id"/>
<span class="filter-tag linked-product-filter-tag" v-if="addedBrands.length">
<span class="wrapper linked-product-wrapper " v-for='(brand, index) in addedBrands'>
<span class="do-not-cross-linked-product-arrow">
@{{ brand.name }}
</span>
<span class="icon cross-icon" @click="removeBrand(brand)"></span>
</span>
</span>
</div>
</div>
</script>
<script>
Vue.component('linked-brands', {
template: '#linked-brands-template',
data: function() {
return {
brands: [],
search_term: '',
addedBrands: [],
is_searching: false,
menuId: {{ $menu->id }},
menuBrands: @json($menu->brands()->get()),
}
},
created: function () {
if (this.menuBrands.length > 0) {
for (var index in this.menuBrands) {
this.addedBrands.push(this.menuBrands[index]);
}
}
},
methods: {
addBrand: function (brand ) {
this.addedBrands.push(brand);
this.search_term = '';
this.brands = []
},
removeBrand: function (brand) {
for (var index in this.addedBrands) {
if (this.addedBrands[index].id == brand.id ) {
this.addedBrands.splice(index, 1);
}
}
},
search: function () {
this_this = this;
this.is_searching = true;
if (this.search_term.length >= 1) {
this.$http.get ("{{ route('admin.catalog.menus.brandsearch') }}", {params: {query: this.search_term}})
.then (function(response) {
for (var index in response.data) {
if (response.data[index].id == this_this.productId) {
response.data.splice(index, 1);
}
}
if (this_this.addedBrands.length ) {
for (var brand in this_this.addedBrands) {
for (var productId in response.data) {
if (response.data[productId].id == this_this.addedBrands[brand].id) {
response.data.splice(productId, 1);
}
}
}
}
this_this.brands = response.data;
this_this.is_searching = false;
})
.catch (function (error) {
this_this.is_searching = false;
})
} else {
this_this.brands = [];
this_this.is_searching = false;
}
}
}
});
</script>
@endpush

View File

@ -1,153 +0,0 @@
<accordian title="{{ __('admin::app.catalog.products.product-link') }}" :active="false">
<div slot="body">
<linked-products></linked-products>
</div>
</accordian>
@push('scripts')
<script type="text/x-template" id="linked-products-template">
<div>
<div class="control-group" v-for='(key) in linkedProducts'>
<label for="up-selling" v-if="(key == 'up_sells')">
{{ __('admin::app.catalog.products.up-selling') }}
</label>
<input type="text" class="control" autocomplete="off" v-model="search_term[key]" placeholder="{{ __('admin::app.catalog.products.product-search-hint') }}" v-on:keyup="search(key)">
<div class="linked-product-search-result">
<ul>
<li v-for='(product, index) in products[key]' v-if='products[key].length' @click="addProduct(product, key)">
@{{ product.name }}
</li>
<li v-if='! products[key].length && search_term[key].length && ! is_searching[key]'>
{{ __('admin::app.catalog.products.no-result-found') }}
</li>
<li v-if="is_searching[key] && search_term[key].length">
{{ __('admin::app.catalog.products.searching') }}
</li>
</ul>
</div>
<input type="hidden" name="up_sell[]" v-for='(product, index) in addedProducts.up_sells' v-if="(key == 'up_sells') && addedProducts.up_sells.length" :value="product.id"/>
<span class="filter-tag linked-product-filter-tag" v-if="addedProducts[key].length">
<span class="wrapper linked-product-wrapper " v-for='(product, index) in addedProducts[key]'>
<span class="do-not-cross-linked-product-arrow">
@{{ product.name }}
</span>
<span class="icon cross-icon" @click="removeProduct(product, key)"></span>
</span>
</span>
</div>
</div>
</script>
<script>
Vue.component('linked-products', {
template: '#linked-products-template',
data: function() {
return {
products: {
'up_sells': [],
},
search_term: {
'up_sells': '',
},
addedProducts: {
'up_sells': [],
},
is_searching: {
'up_sells': false,
},
productId: {{ $product->id }},
linkedProducts: ['up_sells'],
upSellingProducts: @json($product->up_sells()->get()),
}
},
created: function () {
if (this.upSellingProducts.length >= 1) {
for (var index in this.upSellingProducts) {
this.addedProducts.up_sells.push(this.upSellingProducts[index]);
}
}
},
methods: {
addProduct: function (product, key) {
this.addedProducts[key].push(product);
this.search_term[key] = '';
this.products[key] = []
},
removeProduct: function (product, key) {
for (var index in this.addedProducts[key]) {
if (this.addedProducts[key][index].id == product.id ) {
this.addedProducts[key].splice(index, 1);
}
}
},
search: function (key) {
this_this = this;
this.is_searching[key] = true;
if (this.search_term[key].length >= 1) {
this.$http.get ("{{ route('admin.catalog.products.productlinksearch') }}", {params: {query: this.search_term[key]}})
.then (function(response) {
for (var index in response.data) {
if (response.data[index].id == this_this.productId) {
response.data.splice(index, 1);
}
}
if (this_this.addedProducts[key].length) {
for (var product in this_this.addedProducts[key]) {
for (var productId in response.data) {
if (response.data[productId].id == this_this.addedProducts[key][product].id) {
response.data.splice(productId, 1);
}
}
}
}
this_this.products[key] = response.data;
this_this.is_searching[key] = false;
})
.catch (function (error) {
this_this.is_searching[key] = false;
})
} else {
this_this.products[key] = [];
this_this.is_searching[key] = false;
}
}
}
});
</script>
@endpush

View File

@ -8,7 +8,7 @@ use Sarga\Admin\Http\Controllers\Menus;
Route::group(['middleware' => ['web', 'admin'], 'prefix' => config('app.admin_url')], function () {
Route::prefix('catalog')->group(function () {
/**
* Categories routes.
* Menu routes.
*/
Route::get('/menus', [Menus::class, 'index'])->defaults('_config', [
'view' => 'sarga_admin::catalog.menus.index',
@ -35,5 +35,7 @@ Route::group(['middleware' => ['web', 'admin'], 'prefix' => config('app.admin_ur
Route::post('menus/massdelete', [Menus::class, 'massDestroy'])->defaults('_config', [
'redirect' => 'admin.catalog.menus.index',
])->name('admin.catalog.menus.massdelete');
Route::get('menus/brands',[Menus::class, 'brands'])->name('admin.catalog.menus.brandsearch')
});
});

View File

@ -97,4 +97,15 @@ class BrandRepository extends Repository
->groupBy('brands.id')
->get();
}
public function search($key){
$brands = $this->getModel()::search(implode(' OR ', $key))
// ->where('status',1)
// ->orderBy('name','asc')
->take(10)
->query(fn ($query) => $query->select('id','name')->orderBy('name'))
->get();
return $brands;
}
}