Variant Images Handled

This commit is contained in:
Devansh 2022-02-03 17:44:45 +05:30
parent 757dc9a8ed
commit 6d8ef13120
2 changed files with 166 additions and 76 deletions

View File

@ -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="'&quot;' + attribute.admin_name + '&quot;'"
>
<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="&quot;{{ __('admin::app.catalog.products.sku') }}&quot;"
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="&quot;{{ __('admin::app.catalog.products.name') }}&quot;"/>
<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="'&quot;' + inventorySource.name + '&quot;'"/>
<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="'&quot;' + inventorySource.name + '&quot;'"
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="&quot;{{ __('admin::app.catalog.products.price') }}&quot;"
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="&quot;{{ __('admin::app.catalog.products.weight') }}&quot;"
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>

View File

@ -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);