File: D:/HostingSpaces/SBogers10/shop.komma.nl/resources/js/components/vue/discounts/Editor.vue
<template>
<form ref="form">
<h2>{{ editorTitle }}</h2>
<tabs :fixed-tabs="[trans('KMS::discounts').general ]" :has-language-tabs="true" @languageTabsLoaded="languageTabs = $event">
<!--General tab-->
<template v-slot:[generalTabName]>
<div>
<label>
<span>{{ trans('KMS::discounts').active }}</span>
<input type="checkbox" v-model="currentDiscount.active" @change="changed">
</label><br>
<label>
<span>{{ trans('KMS::discounts').stop_processing }}</span>
<input type="checkbox" v-model="currentDiscount.stop_processing" @change="changed">
</label>
<!--Conditions-->
<p>{{ trans('KMS::discounts').apply_when }}</p>
<div class="conditions" v-if="currentDiscount">
<discountable-condition-or-action
v-for="condition in currentDiscount.conditions"
v-if="condition.state !== 4"
:id="condition.id"
:type="condition.type"
:operator="condition.operator"
:params="condition.params"
:dataByType="conditionDataByType"
@change="updateCondition($event, condition)"
@add="addAfterCondition(condition)"
@delete="deleteCondition(condition)"
:key="condition.id"
/>
<button v-if="!discountConditionsVisible" type="button" @click="appendCondition">{{ trans('KMS::discounts').add_condition }}</button>
</div>
<!--Actions-->
<p>{{ trans('KMS::discounts').and_act_as_follows }}</p>
<div class="actions">
<discountable-condition-or-action
v-for="action in currentDiscount.actions"
v-if="action.state !== 4"
:id="action.id"
:type="action.type"
:params="action.params"
:dataByType="actionDataByType"
@change="updateAction($event, action)"
@add="addAfterActionExpression(action)"
@delete="deleteAction(action)"
:key="action.id"
/>
<button v-if="!discountActionsVisible" type="button" @click="appendActionExpression">{{ trans('KMS::discounts').add_action }}</button>
</div>
</div>
<br>
<button type="button" @click="save">{{ trans('KMS::discounts').save }}</button>
<button type="button" @click="$emit('cancel')">{{ trans('KMS::discounts').cancel }}</button>
</template>
<!--Language tabs-->
<template v-slot:[languageTab] v-for="languageTab in languageTabs">
<div>
<label>
<span>{{ trans('KMS::discounts').name }}</span>
<input type="text" :name="'name_' + languageTab" v-model="translation(languageTab).title" @change="translationChanged(languageTab)">
</label>
<br>
<label>
<span>{{ trans('KMS::discounts').description }}</span>
<textarea type="text" :name="'description_' + languageTab" v-model="translation(languageTab).description" @change="translationChanged(languageTab)"></textarea>
</label>
</div>
<button type="button" @click="save">{{ trans('KMS::discounts').save }}</button>
<button type="button" @click="$emit('cancel')">{{ trans('KMS::discounts').cancel }}</button>
</template>
</tabs>
</form>
</template>
<script>
import {mapGetters} from "vuex";
import {States} from "../../../global/models/Model";
import Vue from 'vue';
import Tabs from "../Tabs";
import Action from "./models/Action";
import Discount from "./models/Discount";
import Condition from "./models/Condition";
import DiscountTranslation from "./models/DiscountTranslation";
import {DiscountService} from "../../../services/discountService";
import DiscountableConditionOrAction from "./DiscountableConditionOrAction";
let discountService = new DiscountService();
export default {
name: "Editor",
components: {
DiscountableConditionOrAction,
Tabs
},
props: {
discount: {
type: Object,
required: true
}
},
data: function () {
return {
conditionDataByType: {},
actionDataByType: {},
currentDiscount: null,
languageTabs: []
}
},
computed: {
...mapGetters({
trans: "g11n/translation/translation",
languagesHavingSites: "sites/languagesHavingSites",
}),
editorTitle: function () {
let title = this.currentDiscount && this.currentDiscount.id ? this.trans('KMS::discounts').edit : this.trans('KMS::discounts').new
if(this.currentDiscount && this.currentDiscount.names !== '') title += ' (' + this.currentDiscount.names + ')'
return title
},
generalTabName: function() {
return this.trans('KMS::discounts').general
},
discountConditionsVisible: function() {
return this.currentDiscount.conditions.filter((condition) => {
return condition.state !== States.DELETED;
}).length > 0;
},
discountActionsVisible: function() {
return this.currentDiscount.actions.filter((condition) => {
return condition.state !== States.DELETED;
}).length > 0;
}
},
methods: {
loadConditionDataByType: function () {
discountService.conditionDataByType().then(function (response) {
if (typeof response.data === 'object' && !Array.isArray(response.data)) {
this.conditionDataByType = response.data;
}
}.bind(this));
},
loadActionDataByType: function () {
discountService.actionDataByType().then(function (response) {
if (typeof response.data === 'object' && !Array.isArray(response.data)) {
this.actionDataByType = response.data;
}
}.bind(this));
},
updateCondition: function(updatedData, condition) {
Vue.set(condition, 'type', parseInt(updatedData.type));
Vue.set(condition, 'operator', updatedData.operator);
Vue.set(condition, 'params', updatedData.params);
// console.log('Updated ', condition, 'with condition data: ', updatedData)
if(condition.state !== States.NEW && condition.state !== States.DELETED) condition.state = States.DIRTY
},
appendCondition: function () {
this.currentDiscount.conditions.push(new Condition());
},
addAfterCondition: function (condition) {
this.currentDiscount.conditions.splice(this.currentDiscount.conditions.indexOf(condition) + 1, 0, new Condition())
},
deleteCondition: function (condition) {
switch (condition.state) {
case States.NEW:
//Just delete the condition since it does not exists in the database
this.currentDiscount.conditions.splice(this.currentDiscount.conditions.indexOf(condition), 1)
break;
case States.PRISTINE:
case States.DIRTY:
//Mark it as deleted. The backend will delete it upon save.
this.currentDiscount.conditions[this.currentDiscount.conditions.indexOf(condition)].state = States.DELETED
break;
case States.DELETED:
default:
break;
}
},
updateAction: function(updatedData, action) {
Vue.set(action, 'type', parseInt(updatedData.type));
Vue.set(action, 'params', updatedData.params);
if(action.state !== States.NEW && action.state !== States.DELETED) action.state = States.DIRTY
},
appendActionExpression: function () {
this.currentDiscount.actions.push(new Action())
},
addAfterActionExpression: function (actionExpression) {
this.currentDiscount.actions.splice(this.currentDiscount.actions.indexOf(actionExpression) + 1, 0, new Action())
},
deleteAction: function (action) {
switch (action.state) {
case States.NEW:
//Just delete the condition since it does not exists in the database
this.currentDiscount.actions.splice(this.currentDiscount.actions.indexOf(action), 1)
break;
case States.PRISTINE:
case States.DIRTY:
//Mark it as deleted. The backend will delete it upon save.
this.currentDiscount.actions[this.currentDiscount.actions.indexOf(action)].state = States.DELETED
break;
case States.DELETED:
default:
break;
}
},
translation(iso_2) {
let translation = this.currentDiscount.translations.find((translation) => translation.language.iso_2 === iso_2)
if(!translation) {
translation = new DiscountTranslation();
translation.language.iso_2 = iso_2
translation.language.state = States.NEW
translation.state = States.NEW
this.currentDiscount.translations.push(translation);
}
return translation;
},
changed() {
if(this.currentDiscount && this.currentDiscount.state !== States.NEW && this.currentDiscount.state !== States.DELETED) {
this.currentDiscount.state = States.DIRTY;
}
},
translationChanged(iso_2) {
let translation = this.currentDiscount.translations.find((translation) => {
return translation.language.iso_2 === iso_2
})
if(translation && translation.state !== States.NEW && translation.state !== States.DELETED) translation.state = States.DIRTY
},
save() {
discountService.update(this.currentDiscount).then(function (response) {
this.$emit('saved', this.currentDiscount)
}.bind(this)).catch((errorResponse) => {
console.error(errorResponse)
})
},
},
created() {
//Copy the input discount so that we dont edit it directly
const inputDiscount = JSON.stringify(this.$props.discount)
this.currentDiscount = new Discount(JSON.parse(inputDiscount))
this.loadConditionDataByType();
this.loadActionDataByType();
}
}
</script>
<style scoped>
</style>