added vuex compatible to SearchableSelect

added meta input
pull/44/head
A1Gard 6 months ago
parent 5d2c2bd5eb
commit 740aca9349

@ -95,6 +95,11 @@ class ProductController extends XController
} }
} }
if ($request->has('meta')) {
// dd($request->input('meta'));
$product->syncMeta(json_decode($request->get('meta','[]'),true));
}
return $product; return $product;
} }

@ -66,7 +66,8 @@ class CategoryController extends Controller
// //
} }
public function props(Category $category){ public function props( $id){
$category = Category::whereId($id)->firstOrFail();
return PropCollection::collection($category->props); return PropCollection::collection($category->props);
} }
} }

@ -19,6 +19,7 @@ class PropCollection extends JsonResource
'id' => $this->id, 'id' => $this->id,
'name' => $this->name, 'name' => $this->name,
'label' => $this->label, 'label' => $this->label,
'type' => $this->type,
'searchable' => (bool) $this->searchable, 'searchable' => (bool) $this->searchable,
'priceable'=> (bool) $this->priceable, 'priceable'=> (bool) $this->priceable,
'unit' => $this->unit, 'unit' => $this->unit,

@ -16,6 +16,7 @@ import './bootstrap';
import { createApp } from 'vue'; import { createApp } from 'vue';
import ToastPlugin from 'vue-toast-notification'; import ToastPlugin from 'vue-toast-notification';
import {useToast} from 'vue-toast-notification'; import {useToast} from 'vue-toast-notification';
import store from "./components/libs/store.js";
import './panel/raw.js'; import './panel/raw.js';
import './panel/navbar.js'; import './panel/navbar.js';
import './panel/list-checkboxs.js'; import './panel/list-checkboxs.js';
@ -76,6 +77,10 @@ app.component('address-input', AddressInput);
import PropTypeInput from "./components/PropTypeInput.vue"; import PropTypeInput from "./components/PropTypeInput.vue";
app.component('props-type-input', PropTypeInput); app.component('props-type-input', PropTypeInput);
import MetaInput from "./components/MetaInput.vue";
app.component('meta-input', MetaInput);
/** /**
* The following block of code may be used to automatically register your * The following block of code may be used to automatically register your
* Vue components. It will recursively scan this directory for the Vue * Vue components. It will recursively scan this directory for the Vue
@ -94,6 +99,7 @@ app.component('props-type-input', PropTypeInput);
* scaffolding. Otherwise, you will need to add an element yourself. * scaffolding. Otherwise, you will need to add an element yourself.
*/ */
app.use(ToastPlugin); app.use(ToastPlugin);
app.use(store);
app.mount('#app'); app.mount('#app');
window.app = app; window.app = app;

@ -0,0 +1,126 @@
<template>
<div id="meta-input">
<div class="row">
<div v-for="prop in properties" :class="prop.width">
<label for="prop.name" v-if="prop.type != 'checkbox'">
{{prop.label}}
<!-- [{{prop.type}}]-->
</label>
<div v-else class="mt-2">
<br>
</div>
<template v-if="meta[prop.name] != undefined">
<template v-if="prop.type == 'text'">
<input type="text" :id="prop.name" v-model="meta[prop.name]" class="form-control">
</template>
<template v-if="prop.type == 'number'">
<input type="number" :id="prop.name" v-model="meta[prop.name]" class="form-control">
</template>
<template v-if="prop.type == 'checkbox'">
<div class="form-check form-switch">
<input class="form-check-input" v-model="meta[prop.name]" type="checkbox" role="switch" :id="prop.name">
<label class="form-check-label" for="flexSwitchCheckDefault">{{prop.label}}</label>
</div>
</template>
<template v-if="prop.type == 'color'">
<select :id="prop.name" class="form-control color" v-model="meta[prop.name]">
<option v-for="op in prop.optionList" :style="`background: ${op.value} ;`" :value="op.value"> {{op.title}} </option>
</select>
</template>
<template v-if="prop.type == 'select' || prop.type == 'singemulti'">
<select :id="prop.name" class="form-control color" v-model="meta[prop.name]">
<option v-for="op in prop.optionList" :value="op.value"> {{op.title}} </option>
</select>
</template>
<template v-if="prop.type == 'multi'">
<searchable-multi-select :items="prop.optionList" value-field="value" v-model="meta[prop.name]"></searchable-multi-select>
</template>
</template>
</div>
</div>
<input type="hidden" name="meta" :value="JSON.stringify(meta)">
</div>
</template>
<script>
import {mapState} from "vuex";
import searchableMultiSelect from "./SearchableMultiSelect.vue";
export default {
name: "meta-input",
components: {
searchableMultiSelect
},
data: () => {
return {
properties: [],
meta:{}
}
},
props: {
propsApiLink:{
required: true,
},
metaz:{
default: [],
}
} ,
mounted() {
},
computed: {
category_id: {
get() {
return this.$store.state.category;
},
set(value) {
this.$store.commit('UPDATE_CATEGORY', value)
}
},
},
methods: {
async updateProps(){
try {
const url = this.propsApiLink + this.category_id;
let resp = await axios.get(url);
this.properties = resp.data.data;
// added don't have
for( const prop of this.properties) {
if (this.meta[prop.name] == undefined){
if (prop.type == 'multi'){
this.meta[prop.name] = [];
}else{
this.meta[prop.name] = '';
}
}
}
// update by old meta data
for( const meta in this.metaz) {
this.meta[meta] = this.metaz[meta];
}
} catch(e) {
window.$toast.error(e.message);
}
},
},
watch: {
category_id: function() {
this.updateProps();
}
}
}
</script>
<style scoped>
#meta-input {
}
.color option{
}
</style>

@ -61,6 +61,9 @@ export default {
}, },
emits: ['update:modelValue'], emits: ['update:modelValue'],
props: { props: {
vuexDispatch:{
default: null,
},
xlang: { xlang: {
default: null default: null
}, },
@ -177,6 +180,9 @@ export default {
if (!isNaN(this.modelValue)) { if (!isNaN(this.modelValue)) {
this.$emit('update:modelValue', newValue); this.$emit('update:modelValue', newValue);
} }
if (this.vuexDispatch != null){
this.$store.dispatch(this.vuexDispatch, newValue);
}
} }
} }
} }

@ -2,7 +2,7 @@
@section('title') @section('title')
@if(isset($item)) @if(isset($item))
{{__("Edit product")}} [{{$item->id}}] {{__("Edit product")}} [{{$item->name}}]
@else @else
{{__("Add new product")}} {{__("Add new product")}}
@endif - @endif -

@ -53,6 +53,7 @@
{{-- data-url="{{route('props.list','')}}/"--}} {{-- data-url="{{route('props.list','')}}/"--}}
<searchable-select <searchable-select
vuex-dispatch="updateCategory"
@error('category_id') :err="true" @enderror @error('category_id') :err="true" @enderror
:items='@json($cats)' :items='@json($cats)'
title-field="name" title-field="name"

@ -1,3 +1,6 @@
<h1> <meta-input
step4 props-api-link="{{route('v1.category.prop','')}}/"
</h1> @if(isset($item))
:metaz='@json($item->getAllMeta())'
@endif
></meta-input>

Loading…
Cancel
Save