Variant Images Handled
This commit is contained in:
parent
757dc9a8ed
commit
6d8ef13120
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
<accordian :title="'{{ __('admin::app.catalog.products.variations') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.variations.controls.before', ['product' => $product]) !!}
|
||||
|
||||
<button type="button" class="btn btn-md btn-primary" @click="showModal('addVariant')">
|
||||
|
|
@ -42,7 +41,6 @@
|
|||
<variant-list></variant-list>
|
||||
|
||||
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.variations.controls.after', ['product' => $product]) !!}
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
|
|
@ -58,17 +56,21 @@
|
|||
|
||||
@push('scripts')
|
||||
<script type="text/x-template" id="variant-form-template">
|
||||
<form method="POST" action="{{ route('admin.catalog.products.store') }}"
|
||||
data-vv-scope="add-variant-form" @submit.prevent="addVariant('add-variant-form')">
|
||||
|
||||
<form
|
||||
method="POST"
|
||||
action="{{ route('admin.catalog.products.store') }}"
|
||||
data-vv-scope="add-variant-form" @submit.prevent="addVariant('add-variant-form')">
|
||||
<div class="page-content">
|
||||
<div class="form-container">
|
||||
<div
|
||||
v-for='(attribute, index) in super_attributes'
|
||||
:class="['control-group', errors.has('add-variant-form.' + attribute.code) ? 'has-error' : '']">
|
||||
<label
|
||||
class="required"
|
||||
:for="attribute.code"
|
||||
v-text="attribute.admin_name">
|
||||
</label>
|
||||
|
||||
<div v-for='(attribute, index) in super_attributes' class="control-group"
|
||||
:class="[errors.has('add-variant-form.' + attribute.code) ? 'has-error' : '']"
|
||||
>
|
||||
<label :for="attribute.code" class="required">@{{ attribute.admin_name
|
||||
}}</label>
|
||||
<select
|
||||
v-validate="'required'"
|
||||
v-model="variant[attribute.code]"
|
||||
|
|
@ -77,21 +79,25 @@
|
|||
:name="attribute.code"
|
||||
:data-vv-as="'"' + attribute.admin_name + '"'"
|
||||
>
|
||||
<option v-for='(option, index) in attribute.options' :value="option.id">
|
||||
@{{ option.admin_name }}
|
||||
<option
|
||||
v-for='(option, index) in attribute.options'
|
||||
:value="option.id"
|
||||
v-text="option.admin_name">
|
||||
</option>
|
||||
</select>
|
||||
<span class="control-error"
|
||||
v-if="errors.has('add-variant-form.' + attribute.code)">@{{ errors.first('add-variant-form.' + attribute.code) }}</span>
|
||||
|
||||
<span
|
||||
class="control-error"
|
||||
v-text="errors.first('add-variant-form.' + attribute.code)"
|
||||
v-if="errors.has('add-variant-form.' + attribute.code)">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.catalog.products.add-variant-title') }}
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</script>
|
||||
|
||||
|
|
@ -106,8 +112,11 @@
|
|||
<th>{{ __('admin::app.catalog.products.images') }}</th>
|
||||
|
||||
@foreach ($product->super_attributes as $attribute)
|
||||
<th class="{{ $attribute->code }}"
|
||||
style="width: 150px">{{ $attribute->admin_name }}</th>
|
||||
<th
|
||||
class="{{ $attribute->code }}"
|
||||
style="width: 150px">
|
||||
{{ $attribute->admin_name }}
|
||||
</th>
|
||||
@endforeach
|
||||
|
||||
<th class="qty">{{ __('admin::app.catalog.products.qty') }}</th>
|
||||
|
|
@ -119,7 +128,10 @@
|
|||
</thead>
|
||||
|
||||
<tbody>
|
||||
<variant-item v-for='(variant, index) in variants' :key="index" :index="index"
|
||||
<variant-item
|
||||
v-for='(variant, index) in variants'
|
||||
:key="index"
|
||||
:index="index"
|
||||
:variant="variant" @onRemoveVariant="removeVariant($event)">
|
||||
</variant-item>
|
||||
</tbody>
|
||||
|
|
@ -132,9 +144,13 @@
|
|||
<td>
|
||||
<div class="control-group">
|
||||
<span class="radio">
|
||||
<input type="radio" id="default_variant_id"
|
||||
name="default_variant_id" :value="variant.id"
|
||||
v-on:change="checkDefaultVariant(variant.id)" :checked="variant.id == default_variant_id">
|
||||
<input
|
||||
id="default_variant_id"
|
||||
type="radio"
|
||||
name="default_variant_id"
|
||||
:value="variant.id"
|
||||
v-on:change="checkDefaultVariant(variant.id)"
|
||||
:checked="variant.id == default_variant_id">
|
||||
<label class="radio-view" :for="[variantInputName + '[default_variant_id]']"></label>
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -142,33 +158,65 @@
|
|||
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has(variantInputName + '[sku]') ? 'has-error' : '']">
|
||||
<input type="text" v-validate="'required'" v-model="variant.sku"
|
||||
:name="[variantInputName + '[sku]']" class="control"
|
||||
<input
|
||||
class="control"
|
||||
type="text"
|
||||
:name="[variantInputName + '[sku]']"
|
||||
v-model="variant.sku"
|
||||
v-validate="'required'"
|
||||
data-vv-as=""{{ __('admin::app.catalog.products.sku') }}""
|
||||
v-slugify/>
|
||||
<span class="control-error" v-if="errors.has(variantInputName + '[sku]')">@{{ errors.first(variantInputName + '[sku]') }}</span>
|
||||
|
||||
<span
|
||||
class="control-error"
|
||||
v-text="errors.first(variantInputName + '[sku]')"
|
||||
v-if="errors.has(variantInputName + '[sku]')">
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group"
|
||||
:class="[errors.has(variantInputName + '[name]') ? 'has-error' : '']">
|
||||
<input type="text" v-validate="'required'" v-model="variant.name"
|
||||
:name="[variantInputName + '[name]']" class="control"
|
||||
<div
|
||||
:class="['control-group', errors.has(variantInputName + '[name]') ? 'has-error' : '']">
|
||||
<input
|
||||
class="control"
|
||||
type="text"
|
||||
:name="[variantInputName + '[name]']"
|
||||
v-model="variant.name"
|
||||
v-validate="'required'"
|
||||
data-vv-as=""{{ __('admin::app.catalog.products.name') }}""/>
|
||||
<span class="control-error" v-if="errors.has(variantInputName + '[name]')">@{{ errors.first(variantInputName + '[name]') }}</span>
|
||||
|
||||
<span
|
||||
class="control-error"
|
||||
v-text="errors.first(variantInputName + '[name]')"
|
||||
v-if="errors.has(variantInputName + '[name]')">
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has(variantInputName + '[images][' + index + ']') ? 'has-error' : '']">
|
||||
<div :class="['control-group', errors.has(variantInputName + '[images][files][' + index + ']') ? 'has-error' : '']">
|
||||
<div v-for='(image, index) in items' class="image-wrapper variant-image">
|
||||
<label class="image-item" v-bind:class="{ 'has-image': imageData[index] }">
|
||||
<input type="hidden" :name="[variantInputName + '[images][' + image.id + ']']" v-if="! new_image[index]"/>
|
||||
<input
|
||||
type="hidden"
|
||||
:name="[variantInputName + '[images][files][' + image.id + ']']"
|
||||
v-if="! new_image[index]"/>
|
||||
|
||||
<input type="file" v-validate="'mimes:image/*'" :name="[variantInputName + '[images][' + index + ']']" accept="image/*" :ref="'imageInput' + index" multiple="multiple" @change="addImageView($event, index)" :id="image.id"/>
|
||||
<input
|
||||
:ref="'imageInput' + index"
|
||||
:id="image.id"
|
||||
type="file"
|
||||
:name="[variantInputName + '[images][files][' + index + ']']"
|
||||
accept="image/*"
|
||||
multiple="multiple"
|
||||
v-validate="'mimes:image/*'"
|
||||
@change="addImageView($event, index)"/>
|
||||
|
||||
<img class="preview" :src="imageData[index]" v-if="imageData[index]">
|
||||
<img
|
||||
class="preview"
|
||||
:src="imageData[index]"
|
||||
v-if="imageData[index]">
|
||||
</label>
|
||||
|
||||
<span class="icon trash-icon" @click="removeImage(image)"></span>
|
||||
|
|
@ -182,9 +230,15 @@
|
|||
|
||||
<td v-for='(attribute, index) in superAttributes'>
|
||||
<div class="control-group">
|
||||
<input type="hidden" :name="[variantInputName + '[' + attribute.code + ']']"
|
||||
<input
|
||||
type="hidden"
|
||||
:name="[variantInputName + '[' + attribute.code + ']']"
|
||||
:value="variant[attribute.code]"/>
|
||||
<input type="text" class="control" :value="optionName(variant[attribute.code])"
|
||||
|
||||
<input
|
||||
type="text"
|
||||
class="control"
|
||||
:value="optionName(variant[attribute.code])"
|
||||
readonly/>
|
||||
</div>
|
||||
</td>
|
||||
|
|
@ -192,6 +246,7 @@
|
|||
<td>
|
||||
<button style="width: 100%;" type="button" class="dropdown-btn dropdown-toggle">
|
||||
@{{ totalQty }}
|
||||
|
||||
<i class="icon arrow-down-icon"></i>
|
||||
</button>
|
||||
|
||||
|
|
@ -201,14 +256,21 @@
|
|||
<li v-for='(inventorySource, index) in inventorySources'>
|
||||
<div class="control-group"
|
||||
:class="[errors.has(variantInputName + '[inventories][' + inventorySource.id + ']') ? 'has-error' : '']">
|
||||
<label>@{{ inventorySource.name }}</label>
|
||||
<input type="text" v-validate="'numeric|min:0'"
|
||||
<label v-text="inventorySource.name"></label>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
:name="[variantInputName + '[inventories][' + inventorySource.id + ']']"
|
||||
v-model="inventories[inventorySource.id]" class="control"
|
||||
v-on:keyup="updateTotalQty()"
|
||||
:data-vv-as="'"' + inventorySource.name + '"'"/>
|
||||
<span class="control-error"
|
||||
v-if="errors.has(variantInputName + '[inventories][' + inventorySource.id + ']')">@{{ errors.first(variantInputName + '[inventories][' + inventorySource.id + ']') }}</span>
|
||||
v-validate="'numeric|min:0'"
|
||||
:data-vv-as="'"' + inventorySource.name + '"'"
|
||||
v-on:keyup="updateTotalQty()"/>
|
||||
|
||||
<span
|
||||
class="control-error"
|
||||
v-text="errors.first(variantInputName + '[inventories][' + inventorySource.id + ']')"
|
||||
v-if="errors.has(variantInputName + '[inventories][' + inventorySource.id + ']')">
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -217,42 +279,70 @@
|
|||
</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group"
|
||||
:class="[errors.has(variantInputName + '[price]') ? 'has-error' : '']">
|
||||
<input type="number" v-validate="'required'" v-model="variant.price"
|
||||
:name="[variantInputName + '[price]']" class="control"
|
||||
<div :class="['control-group', errors.has(variantInputName + '[price]') ? 'has-error' : '']">
|
||||
<input
|
||||
class="control"
|
||||
type="number"
|
||||
:name="[variantInputName + '[price]']"
|
||||
v-model="variant.price"
|
||||
v-validate="'required'"
|
||||
data-vv-as=""{{ __('admin::app.catalog.products.price') }}""
|
||||
step="any"/>
|
||||
<span class="control-error" v-if="errors.has(variantInputName + '[price]')">@{{ errors.first(variantInputName + '[price]') }}</span>
|
||||
|
||||
<span
|
||||
class="control-error"
|
||||
v-text="errors.first(variantInputName + '[price]')"
|
||||
v-if="errors.has(variantInputName + '[price]')">
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group"
|
||||
:class="[errors.has(variantInputName + '[weight]') ? 'has-error' : '']">
|
||||
<input type="number" v-validate="'required'" v-model="variant.weight"
|
||||
<div :class="['control-group', errors.has(variantInputName + '[weight]') ? 'has-error' : '']">
|
||||
<input
|
||||
type="number"
|
||||
:name="[variantInputName + '[weight]']" class="control"
|
||||
v-model="variant.weight"
|
||||
v-validate="'required'"
|
||||
data-vv-as=""{{ __('admin::app.catalog.products.weight') }}""
|
||||
step="any"/>
|
||||
<span class="control-error" v-if="errors.has(variantInputName + '[weight]')">@{{ errors.first(variantInputName + '[weight]') }}</span>
|
||||
|
||||
<span
|
||||
class="control-error"
|
||||
v-text="errors.first(variantInputName + '[weight]')"
|
||||
v-if="errors.has(variantInputName + '[weight]')">
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group">
|
||||
<select type="text" v-model="variant.status"
|
||||
:name="[variantInputName + '[status]']" class="control">
|
||||
<option value="1"
|
||||
:selected="variant.status">{{ __('admin::app.catalog.products.enabled') }}</option>
|
||||
<option value="0"
|
||||
:selected="!variant.status">{{ __('admin::app.catalog.products.disabled') }}</option>
|
||||
<select
|
||||
class="control"
|
||||
type="text"
|
||||
v-model="variant.status"
|
||||
:name="[variantInputName + '[status]']">
|
||||
|
||||
<option
|
||||
value="1"
|
||||
:selected="variant.status">
|
||||
{{ __('admin::app.catalog.products.enabled') }}
|
||||
</option>
|
||||
|
||||
<option
|
||||
value="0"
|
||||
:selected="!variant.status">
|
||||
{{ __('admin::app.catalog.products.disabled') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td class="actions">
|
||||
<a :href="['{{ route('admin.catalog.products.index') }}/edit/' + variant.id]"><i
|
||||
class="icon pencil-lg-icon"></i></a>
|
||||
<a :href="['{{ route('admin.catalog.products.index') }}/edit/' + variant.id]">
|
||||
<i class="icon pencil-lg-icon"></i>
|
||||
</a>
|
||||
|
||||
<i class="icon remove-icon" @click="removeVariant()"></i>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -38,28 +38,19 @@ class ProductMediaRepository extends Repository
|
|||
/**
|
||||
* Upload.
|
||||
*
|
||||
* @param \Webkul\Product\Contracts\Product $product
|
||||
* @param array
|
||||
* @param array $data
|
||||
* @param \Webkul\Product\Contracts\Product $product
|
||||
* @param string $uploadFileType
|
||||
* @return void
|
||||
*/
|
||||
public function upload($data, $product, $uploadFileType): void
|
||||
public function upload($data, $product, string $uploadFileType): void
|
||||
{
|
||||
/**
|
||||
* Previous model ids for filtering.
|
||||
*/
|
||||
$previousIds = $this->resolveFileTypeQueryBuilder($product, $uploadFileType)->pluck('id');
|
||||
|
||||
if (
|
||||
isset($data[$uploadFileType]['files']) && $data[$uploadFileType]['files']
|
||||
&& isset($data[$uploadFileType]['positions']) && $data[$uploadFileType]['positions']
|
||||
) {
|
||||
/**
|
||||
* Filter out existing models because new model positions are already setuped by index.
|
||||
*/
|
||||
$positions = collect($data[$uploadFileType]['positions'])->keys()->filter(function ($position) {
|
||||
return is_numeric($position);
|
||||
});
|
||||
|
||||
if (isset($data[$uploadFileType]['files']) && $data[$uploadFileType]['files']) {
|
||||
foreach ($data[$uploadFileType]['files'] as $indexOrModelId => $file) {
|
||||
if ($file instanceof UploadedFile) {
|
||||
$this->create([
|
||||
|
|
@ -69,9 +60,18 @@ class ProductMediaRepository extends Repository
|
|||
'position' => $indexOrModelId,
|
||||
]);
|
||||
} else {
|
||||
$this->update([
|
||||
'position' => $positions->search($indexOrModelId),
|
||||
], $indexOrModelId);
|
||||
/**
|
||||
* Filter out existing models because new model positions are already setuped by index.
|
||||
*/
|
||||
if (isset($data[$uploadFileType]['positions']) && $data[$uploadFileType]['positions']) {
|
||||
$positions = collect($data[$uploadFileType]['positions'])->keys()->filter(function ($position) {
|
||||
return is_numeric($position);
|
||||
});
|
||||
|
||||
$this->update([
|
||||
'position' => $positions->search($indexOrModelId),
|
||||
], $indexOrModelId);
|
||||
}
|
||||
|
||||
if (is_numeric($index = $previousIds->search($indexOrModelId))) {
|
||||
$previousIds->forget($index);
|
||||
|
|
|
|||
Loading…
Reference in New Issue